]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
major overhaul for thread-safety - many global variables and static
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 22 Oct 2011 23:52:58 +0000 (23:52 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 22 Oct 2011 23:52:58 +0000 (23:52 +0000)
buffers eliminated, this causes MANY changes, such as va() taking a
buffer, prog variable has to be passed as parameter to every PRVM
function, and many other edits of that nature.
realtime is now the only linearly increasing time stamp in the engine,
Sys_DoubleTime replaced by Sys_DirtyTime which requires sanity checks in
every use, but ensures thread-safe behavior
added -Wmissing-prototypes to makefile so that no one will ever put an
extern function prototype in a .c file again, this was necessary to
clean up crashes where prototype parameters differed.

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11463 d7cf8633-e32d-0410-b094-e92efae38249

101 files changed:
cap_avi.c
cap_ogg.c
cd_shared.c
cdaudio.h
cl_collision.c
cl_demo.c
cl_input.c
cl_main.c
cl_parse.c
cl_particles.c
cl_screen.c
cl_video.c
cl_video_jamdecode.c
client.h
clvm_cmds.c
clvm_cmds.h
cmd.c
cmd.h
collision.c
common.c
common.h
console.c
console.h
crypto.c
csprogs.c
csprogs.h
curves.c
cvar.c
dpsoftrast.c
dpvsimpledecode.c
fs.c
fs.h
ft2.c
gl_backend.c
gl_draw.c
gl_rmain.c
gl_rsurf.c
gl_textures.c
host.c
host_cmd.c
image.c
image_png.c
jpeg.c
keys.c
keys.h
lhnet.c
lhnet.h
libcurl.c
libcurl.h
makefile
mathlib.h
menu.c
menu.h
model_alias.c
model_brush.c
model_shared.c
model_sprite.c
mvm_cmds.c
netconn.c
netconn.h
palette.c
portals.c
progsvm.h
protocol.c
prvm_cmds.c
prvm_cmds.h
prvm_edict.c
prvm_exec.c
prvm_execprogram.h
quakedef.h
r_lightning.c
r_shadow.c
r_sky.c
r_sprites.c
r_textures.h
render.h
sbar.c
sbar.h
server.h
snd_main.c
snd_mix.c
sound.h
sv_demo.c
sv_main.c
sv_move.c
sv_phys.c
sv_user.c
svvm_cmds.c
sys.h
sys_shared.c
timing.h
utf8lib.c
utf8lib.h
vid.h
vid_glx.c
vid_sdl.c
vid_shared.c
view.c
world.c
world.h
zone.c

index 486243645860d80488191e9d9249d26f05999648..9a238e80ff4d335994191019f6237e92acc3bf77 100644 (file)
--- a/cap_avi.c
+++ b/cap_avi.c
@@ -188,7 +188,7 @@ static void SCR_CaptureVideo_RIFF_IndexEntry(const char *chunkfourcc, int chunks
 {
        LOAD_FORMATSPECIFIC_AVI();
        if(!format->canseek)
-               Host_Error("SCR_CaptureVideo_RIFF_IndexEntry called on non-seekable AVI");
+               Sys_Error("SCR_CaptureVideo_RIFF_IndexEntry called on non-seekable AVI");
 
        if (format->riffstacklevel != 2)
                Sys_Error("SCR_Capturevideo_RIFF_IndexEntry: RIFF stack level is %i (should be 2)\n", format->riffstacklevel);
@@ -209,7 +209,7 @@ static void SCR_CaptureVideo_RIFF_MakeIxChunk(const char *fcc, const char *dwChu
        fs_offset_t pos, sz;
        
        if(!format->canseek)
-               Host_Error("SCR_CaptureVideo_RIFF_MakeIxChunk called on non-seekable AVI");
+               Sys_Error("SCR_CaptureVideo_RIFF_MakeIxChunk called on non-seekable AVI");
 
        if(*masteridx_count >= AVI_MASTER_INDEX_SIZE)
                return;
@@ -404,7 +404,7 @@ static void SCR_CaptureVideo_Avi_VideoFrames(int num)
        }
 }
 
-void SCR_CaptureVideo_Avi_EndVideo(void)
+static void SCR_CaptureVideo_Avi_EndVideo(void)
 {
        LOAD_FORMATSPECIFIC_AVI();
 
@@ -449,7 +449,7 @@ void SCR_CaptureVideo_Avi_EndVideo(void)
        Mem_Free(format);
 }
 
-void SCR_CaptureVideo_Avi_SoundFrame(const portable_sampleframe_t *paintbuffer, size_t length)
+static void SCR_CaptureVideo_Avi_SoundFrame(const portable_sampleframe_t *paintbuffer, size_t length)
 {
        LOAD_FORMATSPECIFIC_AVI();
        int x;
@@ -502,12 +502,13 @@ void SCR_CaptureVideo_Avi_BeginVideo(void)
        int n, d;
        unsigned int i;
        double aspect;
+       char vabuf[1024];
 
        aspect = vid.width / (vid.height * vid_pixelheight.value);
 
        cls.capturevideo.format = CAPTUREVIDEOFORMAT_AVI_I420;
        cls.capturevideo.formatextension = "avi";
-       cls.capturevideo.videofile = FS_OpenRealFile(va("%s.%s", cls.capturevideo.basename, cls.capturevideo.formatextension), "wb", false);
+       cls.capturevideo.videofile = FS_OpenRealFile(va(vabuf, sizeof(vabuf), "%s.%s", cls.capturevideo.basename, cls.capturevideo.formatextension), "wb", false);
        cls.capturevideo.endvideo = SCR_CaptureVideo_Avi_EndVideo;
        cls.capturevideo.videoframes = SCR_CaptureVideo_Avi_VideoFrames;
        cls.capturevideo.soundframe = SCR_CaptureVideo_Avi_SoundFrame;
index 166ead0138cc2b82ef4043d1eb9ec14d12f806ca..de3132d14552b539c692260fe7dc7862a98f2eb9 100644 (file)
--- a/cap_ogg.c
+++ b/cap_ogg.c
@@ -523,7 +523,7 @@ static dllfunction_t theorafuncs[] =
 
 static dllhandle_t og_dll = NULL, vo_dll = NULL, ve_dll = NULL, th_dll = NULL;
 
-qboolean SCR_CaptureVideo_Ogg_OpenLibrary(void)
+static qboolean SCR_CaptureVideo_Ogg_OpenLibrary(void)
 {
        const char* dllnames_og [] =
        {
@@ -677,7 +677,7 @@ static void SCR_CaptureVideo_Ogg_Interleave(void)
                                format->videopage.len = pg.header_len + pg.body_len;
                                format->videopage.time = qtheora_granule_time(&format->ts, qogg_page_granulepos(&pg));
                                if(format->videopage.len > sizeof(format->videopage.data))
-                                       Host_Error("video page too long");
+                                       Sys_Error("video page too long");
                                memcpy(format->videopage.data, pg.header, pg.header_len);
                                memcpy(format->videopage.data + pg.header_len, pg.body, pg.body_len);
                        }
@@ -687,7 +687,7 @@ static void SCR_CaptureVideo_Ogg_Interleave(void)
                                format->audiopage.len = pg.header_len + pg.body_len;
                                format->audiopage.time = qvorbis_granule_time(&format->vd, qogg_page_granulepos(&pg));
                                if(format->audiopage.len > sizeof(format->audiopage.data))
-                                       Host_Error("audio page too long");
+                                       Sys_Error("audio page too long");
                                memcpy(format->audiopage.data, pg.header, pg.header_len);
                                memcpy(format->audiopage.data + pg.header_len, pg.body, pg.body_len);
                        }
@@ -782,7 +782,7 @@ static void SCR_CaptureVideo_Ogg_EndVideo(void)
        while (1) {
                int result = qogg_stream_flush (&format->to, &pg);
                if (result < 0)
-                       fprintf (stderr, "Internal Ogg library error.\n"); // TODO Host_Error
+                       fprintf (stderr, "Internal Ogg library error.\n"); // TODO Sys_Error
                if (result <= 0)
                        break;
                FS_Write(cls.capturevideo.videofile, pg.header, pg.header_len);
@@ -794,7 +794,7 @@ static void SCR_CaptureVideo_Ogg_EndVideo(void)
                while (1) {
                        int result = qogg_stream_flush (&format->vo, &pg);
                        if (result < 0)
-                               fprintf (stderr, "Internal Ogg library error.\n"); // TODO Host_Error
+                               fprintf (stderr, "Internal Ogg library error.\n"); // TODO Sys_Error
                        if (result <= 0)
                                break;
                        FS_Write(cls.capturevideo.videofile, pg.header, pg.header_len);
@@ -937,9 +937,10 @@ static void SCR_CaptureVideo_Ogg_SoundFrame(const portable_sampleframe_t *paintb
 
 void SCR_CaptureVideo_Ogg_BeginVideo(void)
 {
+       char vabuf[1024];
        cls.capturevideo.format = CAPTUREVIDEOFORMAT_OGG_VORBIS_THEORA;
        cls.capturevideo.formatextension = "ogv";
-       cls.capturevideo.videofile = FS_OpenRealFile(va("%s.%s", cls.capturevideo.basename, cls.capturevideo.formatextension), "wb", false);
+       cls.capturevideo.videofile = FS_OpenRealFile(va(vabuf, sizeof(vabuf), "%s.%s", cls.capturevideo.basename, cls.capturevideo.formatextension), "wb", false);
        cls.capturevideo.endvideo = SCR_CaptureVideo_Ogg_EndVideo;
        cls.capturevideo.videoframes = SCR_CaptureVideo_Ogg_VideoFrames;
        cls.capturevideo.soundframe = SCR_CaptureVideo_Ogg_SoundFrame;
@@ -1098,7 +1099,7 @@ void SCR_CaptureVideo_Ogg_BeginVideo(void)
                {
                        int result = qogg_stream_flush (&format->to, &pg);
                        if (result < 0)
-                               fprintf (stderr, "Internal Ogg library error.\n"); // TODO Host_Error
+                               fprintf (stderr, "Internal Ogg library error.\n"); // TODO Sys_Error
                        if (result <= 0)
                                break;
                        FS_Write(cls.capturevideo.videofile, pg.header, pg.header_len);
@@ -1110,7 +1111,7 @@ void SCR_CaptureVideo_Ogg_BeginVideo(void)
                {
                        int result = qogg_stream_flush (&format->vo, &pg);
                        if (result < 0)
-                               fprintf (stderr, "Internal Ogg library error.\n"); // TODO Host_Error
+                               fprintf (stderr, "Internal Ogg library error.\n"); // TODO Sys_Error
                        if (result <= 0)
                                break;
                        FS_Write(cls.capturevideo.videofile, pg.header, pg.header_len);
index cd12235ca3c30bc3bb0db0d438d7226618db712f..43b4a7f43338cadf08df419faf21c4da21ac66d2 100644 (file)
@@ -24,21 +24,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "cdaudio.h"
 #include "sound.h"
 
-// Prototypes of the system dependent functions
-extern void CDAudio_SysEject (void);
-extern void CDAudio_SysCloseDoor (void);
-extern int CDAudio_SysGetAudioDiskInfo (void);
-extern float CDAudio_SysGetVolume (void);
-extern void CDAudio_SysSetVolume (float volume);
-extern int CDAudio_SysPlay (int track);
-extern int CDAudio_SysStop (void);
-extern int CDAudio_SysPause (void);
-extern int CDAudio_SysResume (void);
-extern int CDAudio_SysUpdate (void);
-extern void CDAudio_SysInit (void);
-extern int CDAudio_SysStartup (void);
-extern void CDAudio_SysShutdown (void);
-
 // used by menu to ghost CD audio slider
 cvar_t cdaudioinitialized = {CVAR_READONLY,"cdaudioinitialized","0","indicates if CD Audio system is active"};
 cvar_t cdaudio = {CVAR_SAVE,"cdaudio","1","CD playing mode (0 = never access CD drive, 1 = play CD tracks if no replacement available, 2 = play fake tracks if no CD track available, 3 = play only real CD tracks, 4 = play real CD tracks even instead of named fake tracks)"};
@@ -164,7 +149,7 @@ static int CDAudio_GetAudioDiskInfo (void)
        return 0;
 }
 
-qboolean CDAudio_Play_real (int track, qboolean looping, qboolean complain)
+static qboolean CDAudio_Play_real (int track, qboolean looping, qboolean complain)
 {
        if(track < 1)
        {
@@ -583,7 +568,7 @@ static void CD_f (void)
        Con_Printf("cd info - prints basic disc information (number of tracks, currently playing track, volume level)\n");
 }
 
-void CDAudio_SetVolume (float newvol)
+static void CDAudio_SetVolume (float newvol)
 {
        // If the volume hasn't changed
        if (newvol == cdvolume)
index 3fed67fa5132167238aa84ebb5ba05f5ced6a691..5eac430a89a940b9ad97b0e6d85d3486a20e6e8a 100644 (file)
--- a/cdaudio.h
+++ b/cdaudio.h
@@ -49,3 +49,18 @@ void CDAudio_Shutdown(void);
 void CDAudio_Update(void);
 float CDAudio_GetPosition(void);
 void CDAudio_StartPlaylist(qboolean resume);
+
+// Prototypes of the system dependent functions
+void CDAudio_SysEject (void);
+void CDAudio_SysCloseDoor (void);
+int CDAudio_SysGetAudioDiskInfo (void);
+float CDAudio_SysGetVolume (void);
+void CDAudio_SysSetVolume (float volume);
+int CDAudio_SysPlay (int track);
+int CDAudio_SysStop (void);
+int CDAudio_SysPause (void);
+int CDAudio_SysResume (void);
+int CDAudio_SysUpdate (void);
+void CDAudio_SysInit (void);
+int CDAudio_SysStartup (void);
+void CDAudio_SysShutdown (void);
index 6829863048decabbc2bb1045d0eb7d74aac0460b..1fc448da57d7300560b7c512c8ecce4c5c000554 100644 (file)
@@ -128,6 +128,7 @@ dp_model_t *CL_GetModelByIndex(int modelindex)
 
 dp_model_t *CL_GetModelFromEdict(prvm_edict_t *ed)
 {
+       prvm_prog_t *prog = CLVM_prog;
        if (!ed || ed->priv.server->free)
                return NULL;
        return CL_GetModelByIndex((int)PRVM_clientedictfloat(ed, modelindex));
@@ -135,6 +136,7 @@ dp_model_t *CL_GetModelFromEdict(prvm_edict_t *ed)
 
 void CL_LinkEdict(prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = CLVM_prog;
        vec3_t mins, maxs;
 
        if (ent == prog->edicts)
@@ -197,6 +199,7 @@ void CL_LinkEdict(prvm_edict_t *ent)
 
 int CL_GenericHitSuperContentsMask(const prvm_edict_t *passedict)
 {
+       prvm_prog_t *prog = CLVM_prog;
        if (passedict)
        {
                int dphitcontentsmask = (int)PRVM_clientedictfloat(passedict, dphitcontentsmask);
@@ -227,6 +230,7 @@ CL_Move
 */
 trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities)
 {
+       prvm_prog_t *prog = CLVM_prog;
        int i, bodysupercontents;
        int passedictprog;
        prvm_edict_t *traceowner, *touch;
@@ -439,6 +443,7 @@ trace_t CL_TraceLine(const vec3_t start, const vec3_t pEnd, int type, prvm_edict
 trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities, qboolean hitsurfaces)
 #endif
 {
+       prvm_prog_t *prog = CLVM_prog;
        int i, bodysupercontents;
        int passedictprog;
        prvm_edict_t *traceowner, *touch;
@@ -676,6 +681,7 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
 trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities)
 #endif
 {
+       prvm_prog_t *prog = CLVM_prog;
        vec3_t hullmins, hullmaxs;
        int i, bodysupercontents;
        int passedictprog;
@@ -950,6 +956,7 @@ trace_t CL_Cache_TraceLineSurfaces(const vec3_t start, const vec3_t pEnd, int ty
 trace_t CL_Cache_TraceLineSurfaces(const vec3_t start, const vec3_t end, int type, int hitsupercontentsmask)
 #endif
 {
+       prvm_prog_t *prog = CLVM_prog;
        int i;
        prvm_edict_t *touch;
        trace_t trace;
index 6778917737b4d710d7193f3033e14f4261d5eeda..6c2b36d4ea1ae2e38adde76499576a925cbf36d3 100644 (file)
--- a/cl_demo.c
+++ b/cl_demo.c
@@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 extern cvar_t cl_capturevideo;
 int old_vsync = 0;
 
-void CL_FinishTimeDemo (void);
+static void CL_FinishTimeDemo (void);
 
 /*
 ==============================================================================
@@ -138,7 +138,7 @@ void CL_CutDemo (unsigned char **buf, fs_offset_t *filesize)
        // restart the demo recording
        cls.demofile = FS_OpenRealFile(cls.demoname, "wb", false);
        if(!cls.demofile)
-               Host_Error("failed to reopen the demo file");
+               Sys_Error("failed to reopen the demo file");
        FS_Printf(cls.demofile, "%i\n", cls.forcetrack);
 }
 
@@ -238,16 +238,21 @@ void CL_ReadDemoMessage(void)
                }
 
                // get the next message
-               FS_Read(cls.demofile, &net_message.cursize, 4);
-               net_message.cursize = LittleLong(net_message.cursize);
-               if(net_message.cursize & DEMOMSG_CLIENT_TO_SERVER) // This is a client->server message! Ignore for now!
+               FS_Read(cls.demofile, &cl_message.cursize, 4);
+               cl_message.cursize = LittleLong(cl_message.cursize);
+               if(cl_message.cursize & DEMOMSG_CLIENT_TO_SERVER) // This is a client->server message! Ignore for now!
                {
                        // skip over demo packet
-                       FS_Seek(cls.demofile, 12 + (net_message.cursize & (~DEMOMSG_CLIENT_TO_SERVER)), SEEK_CUR);
+                       FS_Seek(cls.demofile, 12 + (cl_message.cursize & (~DEMOMSG_CLIENT_TO_SERVER)), SEEK_CUR);
                        continue;
                }
-               if (net_message.cursize > net_message.maxsize)
-                       Host_Error("Demo message (%i) > net_message.maxsize (%i)", net_message.cursize, net_message.maxsize);
+               if (cl_message.cursize > cl_message.maxsize)
+               {
+                       Con_Printf("Demo message (%i) > cl_message.maxsize (%i)", cl_message.cursize, cl_message.maxsize);
+                       cl_message.cursize = 0;
+                       CL_Disconnect();
+                       return;
+               }
                VectorCopy(cl.mviewangles[0], cl.mviewangles[1]);
                for (i = 0;i < 3;i++)
                {
@@ -255,9 +260,9 @@ void CL_ReadDemoMessage(void)
                        cl.mviewangles[0][i] = LittleFloat(f);
                }
 
-               if (FS_Read(cls.demofile, net_message.data, net_message.cursize) == net_message.cursize)
+               if (FS_Read(cls.demofile, cl_message.data, cl_message.cursize) == cl_message.cursize)
                {
-                       MSG_BeginReading();
+                       MSG_BeginReading(&cl_message);
                        CL_ParseServerMessage();
 
                        if (cls.signon != SIGNONS)
@@ -298,7 +303,7 @@ void CL_Stop_f (void)
        }
 
 // write a disconnect message to the demo file
-       // LordHavoc: don't replace the net_message when doing this
+       // LordHavoc: don't replace the cl_message when doing this
        buf.data = bufdata;
        buf.maxsize = sizeof(bufdata);
        SZ_Clear(&buf);
@@ -329,6 +334,7 @@ void CL_Record_f (void)
 {
        int c, track;
        char name[MAX_OSPATH];
+       char vabuf[1024];
 
        c = Cmd_Argc();
        if (c != 2 && c != 3 && c != 4)
@@ -367,7 +373,7 @@ void CL_Record_f (void)
 
        // start the map up
        if (c > 2)
-               Cmd_ExecuteString ( va("map %s", Cmd_Argv(2)), src_command, false);
+               Cmd_ExecuteString ( va(vabuf, sizeof(vabuf), "map %s", Cmd_Argv(2)), src_command, false);
 
        // open the demo file
        Con_Printf("recording to %s.\n", name);
@@ -449,13 +455,14 @@ CL_FinishTimeDemo
 
 ====================
 */
-void CL_FinishTimeDemo (void)
+static void CL_FinishTimeDemo (void)
 {
        int frames;
        int i;
        double time, totalfpsavg;
        double fpsmin, fpsavg, fpsmax; // report min/avg/max fps
        static int benchmark_runs = 0;
+       char vabuf[1024];
 
        cls.timedemo = false;
 
@@ -477,7 +484,7 @@ void CL_FinishTimeDemo (void)
                        if(atoi(com_argv[i + 1]) > benchmark_runs)
                        {
                                // restart the benchmark
-                               Cbuf_AddText(va("timedemo %s\n", cls.demoname));
+                               Cbuf_AddText(va(vabuf, sizeof(vabuf), "timedemo %s\n", cls.demoname));
                                // cannot execute here
                        }
                        else
index a0a29575608beb057fcaae2be3fa336540d328cb..6959b14f44394df66d11d557359012b13cd037b6 100644 (file)
@@ -61,7 +61,7 @@ int                   in_impulse;
 
 
 
-void KeyDown (kbutton_t *b)
+static void KeyDown (kbutton_t *b)
 {
        int k;
        const char *c;
@@ -90,7 +90,7 @@ void KeyDown (kbutton_t *b)
        b->state |= 1 + 2;      // down + impulse down
 }
 
-void KeyUp (kbutton_t *b)
+static void KeyUp (kbutton_t *b)
 {
        int k;
        const char *c;
@@ -120,86 +120,86 @@ void KeyUp (kbutton_t *b)
        b->state |= 4;          // impulse up
 }
 
-void IN_KLookDown (void) {KeyDown(&in_klook);}
-void IN_KLookUp (void) {KeyUp(&in_klook);}
-void IN_MLookDown (void) {KeyDown(&in_mlook);}
-void IN_MLookUp (void)
+static void IN_KLookDown (void) {KeyDown(&in_klook);}
+static void IN_KLookUp (void) {KeyUp(&in_klook);}
+static void IN_MLookDown (void) {KeyDown(&in_mlook);}
+static void IN_MLookUp (void)
 {
        KeyUp(&in_mlook);
        if ( !(in_mlook.state&1) && lookspring.value)
                V_StartPitchDrift();
 }
-void IN_UpDown(void) {KeyDown(&in_up);}
-void IN_UpUp(void) {KeyUp(&in_up);}
-void IN_DownDown(void) {KeyDown(&in_down);}
-void IN_DownUp(void) {KeyUp(&in_down);}
-void IN_LeftDown(void) {KeyDown(&in_left);}
-void IN_LeftUp(void) {KeyUp(&in_left);}
-void IN_RightDown(void) {KeyDown(&in_right);}
-void IN_RightUp(void) {KeyUp(&in_right);}
-void IN_ForwardDown(void) {KeyDown(&in_forward);}
-void IN_ForwardUp(void) {KeyUp(&in_forward);}
-void IN_BackDown(void) {KeyDown(&in_back);}
-void IN_BackUp(void) {KeyUp(&in_back);}
-void IN_LookupDown(void) {KeyDown(&in_lookup);}
-void IN_LookupUp(void) {KeyUp(&in_lookup);}
-void IN_LookdownDown(void) {KeyDown(&in_lookdown);}
-void IN_LookdownUp(void) {KeyUp(&in_lookdown);}
-void IN_MoveleftDown(void) {KeyDown(&in_moveleft);}
-void IN_MoveleftUp(void) {KeyUp(&in_moveleft);}
-void IN_MoverightDown(void) {KeyDown(&in_moveright);}
-void IN_MoverightUp(void) {KeyUp(&in_moveright);}
-
-void IN_SpeedDown(void) {KeyDown(&in_speed);}
-void IN_SpeedUp(void) {KeyUp(&in_speed);}
-void IN_StrafeDown(void) {KeyDown(&in_strafe);}
-void IN_StrafeUp(void) {KeyUp(&in_strafe);}
-
-void IN_AttackDown(void) {KeyDown(&in_attack);}
-void IN_AttackUp(void) {KeyUp(&in_attack);}
-
-void IN_UseDown(void) {KeyDown(&in_use);}
-void IN_UseUp(void) {KeyUp(&in_use);}
+static void IN_UpDown(void) {KeyDown(&in_up);}
+static void IN_UpUp(void) {KeyUp(&in_up);}
+static void IN_DownDown(void) {KeyDown(&in_down);}
+static void IN_DownUp(void) {KeyUp(&in_down);}
+static void IN_LeftDown(void) {KeyDown(&in_left);}
+static void IN_LeftUp(void) {KeyUp(&in_left);}
+static void IN_RightDown(void) {KeyDown(&in_right);}
+static void IN_RightUp(void) {KeyUp(&in_right);}
+static void IN_ForwardDown(void) {KeyDown(&in_forward);}
+static void IN_ForwardUp(void) {KeyUp(&in_forward);}
+static void IN_BackDown(void) {KeyDown(&in_back);}
+static void IN_BackUp(void) {KeyUp(&in_back);}
+static void IN_LookupDown(void) {KeyDown(&in_lookup);}
+static void IN_LookupUp(void) {KeyUp(&in_lookup);}
+static void IN_LookdownDown(void) {KeyDown(&in_lookdown);}
+static void IN_LookdownUp(void) {KeyUp(&in_lookdown);}
+static void IN_MoveleftDown(void) {KeyDown(&in_moveleft);}
+static void IN_MoveleftUp(void) {KeyUp(&in_moveleft);}
+static void IN_MoverightDown(void) {KeyDown(&in_moveright);}
+static void IN_MoverightUp(void) {KeyUp(&in_moveright);}
+
+static void IN_SpeedDown(void) {KeyDown(&in_speed);}
+static void IN_SpeedUp(void) {KeyUp(&in_speed);}
+static void IN_StrafeDown(void) {KeyDown(&in_strafe);}
+static void IN_StrafeUp(void) {KeyUp(&in_strafe);}
+
+static void IN_AttackDown(void) {KeyDown(&in_attack);}
+static void IN_AttackUp(void) {KeyUp(&in_attack);}
+
+static void IN_UseDown(void) {KeyDown(&in_use);}
+static void IN_UseUp(void) {KeyUp(&in_use);}
 
 // LordHavoc: added 6 new buttons
-void IN_Button3Down(void) {KeyDown(&in_button3);}
-void IN_Button3Up(void) {KeyUp(&in_button3);}
-void IN_Button4Down(void) {KeyDown(&in_button4);}
-void IN_Button4Up(void) {KeyUp(&in_button4);}
-void IN_Button5Down(void) {KeyDown(&in_button5);}
-void IN_Button5Up(void) {KeyUp(&in_button5);}
-void IN_Button6Down(void) {KeyDown(&in_button6);}
-void IN_Button6Up(void) {KeyUp(&in_button6);}
-void IN_Button7Down(void) {KeyDown(&in_button7);}
-void IN_Button7Up(void) {KeyUp(&in_button7);}
-void IN_Button8Down(void) {KeyDown(&in_button8);}
-void IN_Button8Up(void) {KeyUp(&in_button8);}
-
-void IN_Button9Down(void) {KeyDown(&in_button9);}
-void IN_Button9Up(void) {KeyUp(&in_button9);}
-void IN_Button10Down(void) {KeyDown(&in_button10);}
-void IN_Button10Up(void) {KeyUp(&in_button10);}
-void IN_Button11Down(void) {KeyDown(&in_button11);}
-void IN_Button11Up(void) {KeyUp(&in_button11);}
-void IN_Button12Down(void) {KeyDown(&in_button12);}
-void IN_Button12Up(void) {KeyUp(&in_button12);}
-void IN_Button13Down(void) {KeyDown(&in_button13);}
-void IN_Button13Up(void) {KeyUp(&in_button13);}
-void IN_Button14Down(void) {KeyDown(&in_button14);}
-void IN_Button14Up(void) {KeyUp(&in_button14);}
-void IN_Button15Down(void) {KeyDown(&in_button15);}
-void IN_Button15Up(void) {KeyUp(&in_button15);}
-void IN_Button16Down(void) {KeyDown(&in_button16);}
-void IN_Button16Up(void) {KeyUp(&in_button16);}
-
-void IN_JumpDown (void) {KeyDown(&in_jump);}
-void IN_JumpUp (void) {KeyUp(&in_jump);}
-
-void IN_Impulse (void) {in_impulse=atoi(Cmd_Argv(1));}
+static void IN_Button3Down(void) {KeyDown(&in_button3);}
+static void IN_Button3Up(void) {KeyUp(&in_button3);}
+static void IN_Button4Down(void) {KeyDown(&in_button4);}
+static void IN_Button4Up(void) {KeyUp(&in_button4);}
+static void IN_Button5Down(void) {KeyDown(&in_button5);}
+static void IN_Button5Up(void) {KeyUp(&in_button5);}
+static void IN_Button6Down(void) {KeyDown(&in_button6);}
+static void IN_Button6Up(void) {KeyUp(&in_button6);}
+static void IN_Button7Down(void) {KeyDown(&in_button7);}
+static void IN_Button7Up(void) {KeyUp(&in_button7);}
+static void IN_Button8Down(void) {KeyDown(&in_button8);}
+static void IN_Button8Up(void) {KeyUp(&in_button8);}
+
+static void IN_Button9Down(void) {KeyDown(&in_button9);}
+static void IN_Button9Up(void) {KeyUp(&in_button9);}
+static void IN_Button10Down(void) {KeyDown(&in_button10);}
+static void IN_Button10Up(void) {KeyUp(&in_button10);}
+static void IN_Button11Down(void) {KeyDown(&in_button11);}
+static void IN_Button11Up(void) {KeyUp(&in_button11);}
+static void IN_Button12Down(void) {KeyDown(&in_button12);}
+static void IN_Button12Up(void) {KeyUp(&in_button12);}
+static void IN_Button13Down(void) {KeyDown(&in_button13);}
+static void IN_Button13Up(void) {KeyUp(&in_button13);}
+static void IN_Button14Down(void) {KeyDown(&in_button14);}
+static void IN_Button14Up(void) {KeyUp(&in_button14);}
+static void IN_Button15Down(void) {KeyDown(&in_button15);}
+static void IN_Button15Up(void) {KeyUp(&in_button15);}
+static void IN_Button16Down(void) {KeyDown(&in_button16);}
+static void IN_Button16Up(void) {KeyUp(&in_button16);}
+
+static void IN_JumpDown (void) {KeyDown(&in_jump);}
+static void IN_JumpUp (void) {KeyUp(&in_jump);}
+
+static void IN_Impulse (void) {in_impulse=atoi(Cmd_Argv(1));}
 
 in_bestweapon_info_t in_bestweapon_info[IN_BESTWEAPON_MAX];
 
-void IN_BestWeapon_Register(const char *name, int impulse, int weaponbit, int activeweaponcode, int ammostat, int ammomin)
+static void IN_BestWeapon_Register(const char *name, int impulse, int weaponbit, int activeweaponcode, int ammostat, int ammomin)
 {
        int i;
        for(i = 0; i < IN_BESTWEAPON_MAX && in_bestweapon_info[i].impulse; ++i)
@@ -240,7 +240,7 @@ void IN_BestWeapon_ResetData (void)
        IN_BestWeapon_Register("h", 226, HIT_MJOLNIR, HIT_MJOLNIR, STAT_CELLS, 0); // hipnotic mjolnir hammer
 }
 
-void IN_BestWeapon_Register_f (void)
+static void IN_BestWeapon_Register_f (void)
 {
        if(Cmd_Argc() == 7)
        {
@@ -267,7 +267,7 @@ void IN_BestWeapon_Register_f (void)
        }
 }
 
-void IN_BestWeapon (void)
+static void IN_BestWeapon (void)
 {
        int i, n;
        const char *t;
@@ -468,7 +468,7 @@ CL_AdjustAngles
 Moves the local angle positions
 ================
 */
-void CL_AdjustAngles (void)
+static void CL_AdjustAngles (void)
 {
        float   speed;
        float   up, down;
@@ -518,7 +518,6 @@ CL_Input
 Send the intended movement message to the server
 ================
 */
-extern qboolean CL_VM_InputEvent (int eventtype, int x, int y);
 void CL_Input (void)
 {
        float mx, my;
@@ -756,7 +755,7 @@ void CL_Input (void)
 
 #include "cl_collision.h"
 
-void CL_UpdatePrydonCursor(void)
+static void CL_UpdatePrydonCursor(void)
 {
        vec3_t temp;
 
@@ -864,7 +863,7 @@ static vec3_t offsets[NUMOFFSETS] =
        {-0.125,  0.125, -0.125}, { 0.125,  0.125, -0.125},
 };
 
-qboolean CL_ClientMovement_Unstick(cl_clientmovement_state_t *s)
+static qboolean CL_ClientMovement_Unstick(cl_clientmovement_state_t *s)
 {
        int i;
        vec3_t neworigin;
@@ -881,7 +880,7 @@ qboolean CL_ClientMovement_Unstick(cl_clientmovement_state_t *s)
        return false;
 }
 
-void CL_ClientMovement_UpdateStatus(cl_clientmovement_state_t *s)
+static void CL_ClientMovement_UpdateStatus(cl_clientmovement_state_t *s)
 {
        vec_t f;
        vec3_t origin1, origin2;
@@ -957,7 +956,7 @@ void CL_ClientMovement_UpdateStatus(cl_clientmovement_state_t *s)
                s->waterjumptime = 0;
 }
 
-void CL_ClientMovement_Move(cl_clientmovement_state_t *s)
+static void CL_ClientMovement_Move(cl_clientmovement_state_t *s)
 {
        int bump;
        double t;
@@ -1019,7 +1018,7 @@ void CL_ClientMovement_Move(cl_clientmovement_state_t *s)
 }
 
 
-void CL_ClientMovement_Physics_Swim(cl_clientmovement_state_t *s)
+static void CL_ClientMovement_Physics_Swim(cl_clientmovement_state_t *s)
 {
        vec_t wishspeed;
        vec_t f;
@@ -1146,7 +1145,7 @@ static vec_t CL_GeomLerp(vec_t a, vec_t lerp, vec_t b)
        return a * pow(fabs(b / a), lerp);
 }
 
-void CL_ClientMovement_Physics_CPM_PM_Aircontrol(cl_clientmovement_state_t *s, vec3_t wishdir, vec_t wishspeed)
+static void CL_ClientMovement_Physics_CPM_PM_Aircontrol(cl_clientmovement_state_t *s, vec3_t wishdir, vec_t wishspeed)
 {
        vec_t zspeed, speed, dot, k;
 
@@ -1181,7 +1180,7 @@ void CL_ClientMovement_Physics_CPM_PM_Aircontrol(cl_clientmovement_state_t *s, v
        s->velocity[2] = zspeed;
 }
 
-float CL_ClientMovement_Physics_AdjustAirAccelQW(float accelqw, float factor)
+static float CL_ClientMovement_Physics_AdjustAirAccelQW(float accelqw, float factor)
 {
        return
                (accelqw < 0 ? -1 : +1)
@@ -1189,7 +1188,7 @@ float CL_ClientMovement_Physics_AdjustAirAccelQW(float accelqw, float factor)
                bound(0.000001, 1 - (1 - fabs(accelqw)) * factor, 1);
 }
 
-void CL_ClientMovement_Physics_PM_Accelerate(cl_clientmovement_state_t *s, vec3_t wishdir, vec_t wishspeed, vec_t wishspeed0, vec_t accel, vec_t accelqw, vec_t stretchfactor, vec_t sidefric, vec_t speedlimit)
+static void CL_ClientMovement_Physics_PM_Accelerate(cl_clientmovement_state_t *s, vec3_t wishdir, vec_t wishspeed, vec_t wishspeed0, vec_t accel, vec_t accelqw, vec_t stretchfactor, vec_t sidefric, vec_t speedlimit)
 {
        vec_t vel_straight;
        vec_t vel_z;
@@ -1269,7 +1268,7 @@ void CL_ClientMovement_Physics_PM_Accelerate(cl_clientmovement_state_t *s, vec3_
        s->velocity[2] += vel_z;
 }
 
-void CL_ClientMovement_Physics_PM_AirAccelerate(cl_clientmovement_state_t *s, vec3_t wishdir, vec_t wishspeed)
+static void CL_ClientMovement_Physics_PM_AirAccelerate(cl_clientmovement_state_t *s, vec3_t wishdir, vec_t wishspeed)
 {
     vec3_t curvel, wishvel, acceldir, curdir;
     float addspeed, accelspeed, curspeed;
@@ -1320,7 +1319,7 @@ void CL_ClientMovement_Physics_PM_AirAccelerate(cl_clientmovement_state_t *s, ve
     VectorMA( s->velocity, accelspeed, acceldir, s->velocity );
 }
 
-void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s)
+static void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s)
 {
        vec_t friction;
        vec_t wishspeed;
@@ -1474,7 +1473,7 @@ void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s)
        }
 }
 
-void CL_ClientMovement_PlayerMove(cl_clientmovement_state_t *s)
+static void CL_ClientMovement_PlayerMove(cl_clientmovement_state_t *s)
 {
        //Con_Printf(" %f", frametime);
        if (!s->cmd.jump)
@@ -1691,7 +1690,7 @@ void CL_ClientMovement_Replay(void)
        cl.oldonground = cl.onground;
 }
 
-void QW_MSG_WriteDeltaUsercmd(sizebuf_t *buf, usercmd_t *from, usercmd_t *to)
+static void QW_MSG_WriteDeltaUsercmd(sizebuf_t *buf, usercmd_t *from, usercmd_t *to)
 {
        int bits;
 
@@ -2156,7 +2155,9 @@ void CL_SendMove(void)
        {
                Con_Print("CL_SendMove: lost server connection\n");
                CL_Disconnect();
+               SV_LockThreadMutex();
                Host_ShutdownServer();
+               SV_UnlockThreadMutex();
        }
 }
 
index d0d9fa90cbad026fb2f0c5fdf83ca6b903667c24..9071b890de7fc6ce4cf0384be7067a22763f60a9 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -104,7 +104,6 @@ CL_ClearState
 
 =====================
 */
-void CL_VM_ShutDown (void);
 void CL_ClearState(void)
 {
        int i;
@@ -216,6 +215,7 @@ void CL_SetInfo(const char *key, const char *value, qboolean send, qboolean allo
 {
        int i;
        qboolean fail = false;
+       char vabuf[1024];
        if (!allowstarkey && key[0] == '*')
                fail = true;
        if (!allowmodel && (!strcasecmp(key, "pmodel") || !strcasecmp(key, "emodel")))
@@ -238,22 +238,22 @@ void CL_SetInfo(const char *key, const char *value, qboolean send, qboolean allo
                if (cls.protocol == PROTOCOL_QUAKEWORLD)
                {
                        MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
-                       MSG_WriteString(&cls.netcon->message, va("setinfo \"%s\" \"%s\"", key, value));
+                       MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "setinfo \"%s\" \"%s\"", key, value));
                }
                else if (!strcasecmp(key, "name"))
                {
                        MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
-                       MSG_WriteString(&cls.netcon->message, va("name \"%s\"", value));
+                       MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "name \"%s\"", value));
                }
                else if (!strcasecmp(key, "playermodel"))
                {
                        MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
-                       MSG_WriteString(&cls.netcon->message, va("playermodel \"%s\"", value));
+                       MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "playermodel \"%s\"", value));
                }
                else if (!strcasecmp(key, "playerskin"))
                {
                        MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
-                       MSG_WriteString(&cls.netcon->message, va("playerskin \"%s\"", value));
+                       MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "playerskin \"%s\"", value));
                }
                else if (!strcasecmp(key, "topcolor"))
                {
@@ -266,7 +266,7 @@ void CL_SetInfo(const char *key, const char *value, qboolean send, qboolean allo
                else if (!strcasecmp(key, "rate"))
                {
                        MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
-                       MSG_WriteString(&cls.netcon->message, va("rate \"%s\"", value));
+                       MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "rate \"%s\"", value));
                }
        }
 }
@@ -390,6 +390,7 @@ void CL_Disconnect(void)
                cls.netcon = NULL;
        }
        cls.state = ca_disconnected;
+       cl.islocalgame = false;
 
        cls.demoplayback = cls.timedemo = false;
        cls.signon = 0;
@@ -435,9 +436,6 @@ void CL_EstablishConnection(const char *host, int firstarg)
        // make sure the client ports are open before attempting to connect
        NetConn_UpdateSockets();
 
-       // run a network frame
-       //NetConn_ClientFrame();SV_VM_Begin();NetConn_ServerFrame();SV_VM_End();
-
        if (LHNETADDRESS_FromString(&cls.connect_address, host, 26000) && (cls.connect_mysocket = NetConn_ChooseClientSocketForAddress(&cls.connect_address)))
        {
                cls.connect_trying = true;
@@ -460,15 +458,6 @@ void CL_EstablishConnection(const char *host, int firstarg)
                }
 
                M_Update_Return_Reason("Trying to connect...");
-
-               // run several network frames to jump into the game quickly
-               //if (sv.active)
-               //{
-               //      NetConn_ClientFrame();SV_VM_Begin();NetConn_ServerFrame();SV_VM_End();
-               //      NetConn_ClientFrame();SV_VM_Begin();NetConn_ServerFrame();SV_VM_End();
-               //      NetConn_ClientFrame();SV_VM_Begin();NetConn_ServerFrame();SV_VM_End();
-               //      NetConn_ClientFrame();SV_VM_Begin();NetConn_ServerFrame();SV_VM_End();
-               //}
        }
        else
        {
@@ -754,7 +743,7 @@ void CL_AllocLightFlash(entity_render_t *ent, matrix4x4_t *matrix, float radius,
        dl->specularscale = specularscale;
 }
 
-void CL_DecayLightFlashes(void)
+static void CL_DecayLightFlashes(void)
 {
        int i, oldmax;
        dlight_t *dl;
@@ -854,7 +843,7 @@ void CL_RelinkLightFlashes(void)
        }
 }
 
-void CL_AddQWCTFFlagModel(entity_t *player, int skin)
+static void CL_AddQWCTFFlagModel(entity_t *player, int skin)
 {
        int frame = player->render.framegroupblend[0].frame;
        float f;
@@ -913,11 +902,6 @@ matrix4x4_t viewmodelmatrix_nobob;
 
 static const vec3_t muzzleflashorigin = {18, 0, 0};
 
-extern void V_DriftPitch(void);
-extern void V_FadeViewFlashs(void);
-extern void V_CalcViewBlend(void);
-extern void V_CalcRefdef(void);
-
 void CL_SetEntityColormapColors(entity_render_t *ent, int colormap)
 {
        const unsigned char *cbcolor;
@@ -936,7 +920,7 @@ void CL_SetEntityColormapColors(entity_render_t *ent, int colormap)
 }
 
 // note this is a recursive function, recursionlimit should be 32 or so on the initial call
-void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolate)
+static void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolate)
 {
        const matrix4x4_t *matrix;
        matrix4x4_t blendmatrix, tempmatrix, matrix2;
@@ -1195,7 +1179,7 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat
 }
 
 // creates light and trails from an entity
-void CL_UpdateNetworkEntityTrail(entity_t *e)
+static void CL_UpdateNetworkEntityTrail(entity_t *e)
 {
        effectnameindex_t trailtype;
        vec3_t origin;
@@ -1309,7 +1293,7 @@ void CL_UpdateViewEntities(void)
 CL_UpdateNetworkCollisionEntities
 ===============
 */
-void CL_UpdateNetworkCollisionEntities(void)
+static void CL_UpdateNetworkCollisionEntities(void)
 {
        entity_t *ent;
        int i;
@@ -1331,14 +1315,12 @@ void CL_UpdateNetworkCollisionEntities(void)
        }
 }
 
-extern void R_DecalSystem_Reset(decalsystem_t *decalsystem);
-
 /*
 ===============
 CL_UpdateNetworkEntities
 ===============
 */
-void CL_UpdateNetworkEntities(void)
+static void CL_UpdateNetworkEntities(void)
 {
        entity_t *ent;
        int i;
@@ -1365,7 +1347,7 @@ void CL_UpdateNetworkEntities(void)
        }
 }
 
-void CL_UpdateViewModel(void)
+static void CL_UpdateViewModel(void)
 {
        entity_t *ent;
        ent = &cl.viewent;
@@ -1400,12 +1382,13 @@ void CL_UpdateViewModel(void)
 }
 
 // note this is a recursive function, but it can never get in a runaway loop (because of the delayedlink flags)
-void CL_LinkNetworkEntity(entity_t *e)
+static void CL_LinkNetworkEntity(entity_t *e)
 {
        effectnameindex_t trailtype;
        vec3_t origin;
        vec3_t dlightcolor;
        vec_t dlightradius;
+       char vabuf[1024];
 
        // skip inactive entities and world
        if (!e->state_current.active || e == cl.entities)
@@ -1542,7 +1525,7 @@ void CL_LinkNetworkEntity(entity_t *e)
                // FIXME: add ambient/diffuse/specular scales as an extension ontop of TENEBRAE_GFX_DLIGHTS?
                Matrix4x4_Normalize(&dlightmatrix, &e->render.matrix);
                Matrix4x4_Scale(&dlightmatrix, light[3], 1);
-               R_RTLight_Update(&r_refdef.scene.templights[r_refdef.scene.numlights], false, &dlightmatrix, light, e->state_current.lightstyle, e->state_current.skin > 0 ? va("cubemaps/%i", e->state_current.skin) : NULL, !(e->state_current.lightpflags & PFLAGS_NOSHADOW), (e->state_current.lightpflags & PFLAGS_CORONA) != 0, 0.25, 0, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
+               R_RTLight_Update(&r_refdef.scene.templights[r_refdef.scene.numlights], false, &dlightmatrix, light, e->state_current.lightstyle, e->state_current.skin > 0 ? va(vabuf, sizeof(vabuf), "cubemaps/%i", e->state_current.skin) : NULL, !(e->state_current.lightpflags & PFLAGS_NOSHADOW), (e->state_current.lightpflags & PFLAGS_CORONA) != 0, 0.25, 0, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
                r_refdef.scene.lights[r_refdef.scene.numlights] = &r_refdef.scene.templights[r_refdef.scene.numlights];r_refdef.scene.numlights++;
        }
        // make the glow dlight
@@ -1573,7 +1556,7 @@ void CL_LinkNetworkEntity(entity_t *e)
        //      Matrix4x4_Print(&e->render.matrix);
 }
 
-void CL_RelinkWorld(void)
+static void CL_RelinkWorld(void)
 {
        entity_t *ent = &cl.entities[0];
        // FIXME: this should be done at load
@@ -1850,7 +1833,7 @@ static void CL_RelinkQWNails(void)
        }
 }
 
-void CL_LerpPlayer(float frac)
+static void CL_LerpPlayer(float frac)
 {
        int i;
 
@@ -2036,19 +2019,19 @@ static void CL_TimeRefresh_f (void)
 
        r_refdef.scene.extraupdate = false;
 
-       timestart = Sys_DoubleTime();
+       timestart = Sys_DirtyTime();
        for (i = 0;i < 128;i++)
        {
                Matrix4x4_CreateFromQuakeEntity(&r_refdef.view.matrix, r_refdef.view.origin[0], r_refdef.view.origin[1], r_refdef.view.origin[2], 0, i / 128.0 * 360.0, 0, 1);
                r_refdef.view.quality = 1;
                CL_UpdateScreen();
        }
-       timedelta = Sys_DoubleTime() - timestart;
+       timedelta = Sys_DirtyTime() - timestart;
 
        Con_Printf("%f seconds (%f fps)\n", timedelta, 128/timedelta);
 }
 
-void CL_AreaStats_f(void)
+static void CL_AreaStats_f(void)
 {
        World_PrintAreaStats(&cl.world, "client");
 }
@@ -2088,7 +2071,7 @@ void CL_Locs_FindLocationName(char *buffer, size_t buffersize, vec3_t point)
                dpsnprintf(buffer, buffersize, "LOC=%.0f:%.0f:%.0f", point[0], point[1], point[2]);
 }
 
-void CL_Locs_FreeNode(cl_locnode_t *node)
+static void CL_Locs_FreeNode(cl_locnode_t *node)
 {
        cl_locnode_t **pointer, **next;
        for (pointer = &cl.locnodes;*pointer;pointer = next)
@@ -2104,7 +2087,7 @@ void CL_Locs_FreeNode(cl_locnode_t *node)
        Con_Printf("CL_Locs_FreeNode: no such node! (%p)\n", (void *)node);
 }
 
-void CL_Locs_AddNode(vec3_t mins, vec3_t maxs, const char *name)
+static void CL_Locs_AddNode(vec3_t mins, vec3_t maxs, const char *name)
 {
        cl_locnode_t *node, **pointer;
        int namelen;
@@ -2123,7 +2106,7 @@ void CL_Locs_AddNode(vec3_t mins, vec3_t maxs, const char *name)
        *pointer = node;
 }
 
-void CL_Locs_Add_f(void)
+static void CL_Locs_Add_f(void)
 {
        vec3_t mins, maxs;
        if (Cmd_Argc() != 5 && Cmd_Argc() != 8)
@@ -2145,7 +2128,7 @@ void CL_Locs_Add_f(void)
                CL_Locs_AddNode(mins, mins, Cmd_Argv(4));
 }
 
-void CL_Locs_RemoveNearest_f(void)
+static void CL_Locs_RemoveNearest_f(void)
 {
        cl_locnode_t *loc;
        loc = CL_Locs_FindNearest(r_refdef.view.origin);
@@ -2155,13 +2138,13 @@ void CL_Locs_RemoveNearest_f(void)
                Con_Printf("no loc point or box found for your location\n");
 }
 
-void CL_Locs_Clear_f(void)
+static void CL_Locs_Clear_f(void)
 {
        while (cl.locnodes)
                CL_Locs_FreeNode(cl.locnodes);
 }
 
-void CL_Locs_Save_f(void)
+static void CL_Locs_Save_f(void)
 {
        cl_locnode_t *loc;
        qfile_t *outfile;
index dcde8eb1607e060f1bd748eb06eb6076f8c71152..7ff8ead9a80783cf07ace98d9bf8c73f7e6df53f 100644 (file)
@@ -191,18 +191,15 @@ cvar_t cl_iplog_name = {CVAR_SAVE, "cl_iplog_name", "darkplaces_iplog.txt", "nam
 static qboolean QW_CL_CheckOrDownloadFile(const char *filename);
 static void QW_CL_RequestNextDownload(void);
 static void QW_CL_NextUpload(void);
-void QW_CL_StartUpload(unsigned char *data, int size);
 //static qboolean QW_CL_IsUploading(void);
 static void QW_CL_StopUpload(void);
-extern void CL_VM_UpdateIntermissionState(int intermission);
-extern qboolean CL_VM_Event_Sound(int sound_num, float volume, int channel, float attenuation, int ent, vec3_t pos, int flags, float speed);
 
 /*
 ==================
 CL_ParseStartSoundPacket
 ==================
 */
-void CL_ParseStartSoundPacket(int largesoundindex)
+static void CL_ParseStartSoundPacket(int largesoundindex)
 {
        vec3_t  pos;
        int     channel, ent;
@@ -215,15 +212,15 @@ void CL_ParseStartSoundPacket(int largesoundindex)
 
        if (cls.protocol == PROTOCOL_QUAKEWORLD)
        {
-               channel = MSG_ReadShort();
+               channel = MSG_ReadShort(&cl_message);
 
                if (channel & (1<<15))
-                       volume = MSG_ReadByte ();
+                       volume = MSG_ReadByte(&cl_message);
                else
                        volume = DEFAULT_SOUND_PACKET_VOLUME;
 
                if (channel & (1<<14))
-                       attenuation = MSG_ReadByte () / 64.0;
+                       attenuation = MSG_ReadByte(&cl_message) / 64.0;
                else
                        attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
        
@@ -232,48 +229,48 @@ void CL_ParseStartSoundPacket(int largesoundindex)
                ent = (channel>>3)&1023;
                channel &= 7;
 
-               sound_num = MSG_ReadByte ();
+               sound_num = MSG_ReadByte(&cl_message);
        }
        else
        {
-               field_mask = MSG_ReadByte();
+               field_mask = MSG_ReadByte(&cl_message);
 
                if (field_mask & SND_VOLUME)
-                       volume = MSG_ReadByte ();
+                       volume = MSG_ReadByte(&cl_message);
                else
                        volume = DEFAULT_SOUND_PACKET_VOLUME;
 
                if (field_mask & SND_ATTENUATION)
-                       attenuation = MSG_ReadByte () / 64.0;
+                       attenuation = MSG_ReadByte(&cl_message) / 64.0;
                else
                        attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
 
                if (field_mask & SND_SPEEDUSHORT4000)
-                       speed = ((unsigned short)MSG_ReadShort ()) / 4000.0f;
+                       speed = ((unsigned short)MSG_ReadShort(&cl_message)) / 4000.0f;
                else
                        speed = 1.0f;
 
                if (field_mask & SND_LARGEENTITY)
                {
-                       ent = (unsigned short) MSG_ReadShort ();
-                       channel = MSG_ReadChar ();
+                       ent = (unsigned short) MSG_ReadShort(&cl_message);
+                       channel = MSG_ReadChar(&cl_message);
                }
                else
                {
-                       channel = (unsigned short) MSG_ReadShort ();
+                       channel = (unsigned short) MSG_ReadShort(&cl_message);
                        ent = channel >> 3;
                        channel &= 7;
                }
 
                if (largesoundindex || (field_mask & SND_LARGESOUND) || cls.protocol == PROTOCOL_NEHAHRABJP2 || cls.protocol == PROTOCOL_NEHAHRABJP3)
-                       sound_num = (unsigned short) MSG_ReadShort ();
+                       sound_num = (unsigned short) MSG_ReadShort(&cl_message);
                else
-                       sound_num = MSG_ReadByte ();
+                       sound_num = MSG_ReadByte(&cl_message);
        }
 
        channel = CHAN_NET2ENGINE(channel);
 
-       MSG_ReadVector(pos, cls.protocol);
+       MSG_ReadVector(&cl_message, pos, cls.protocol);
 
        if (sound_num >= MAX_SOUNDS)
        {
@@ -307,14 +304,12 @@ static unsigned char olddata[NET_MAXMESSAGE];
 void CL_KeepaliveMessage (qboolean readmessages)
 {
        static qboolean recursive = false;
-       float time;
+       double time;
        static double nextmsg = -1;
        static double nextupdate = -1;
 #if 0
        static double lasttime = -1;
 #endif
-       int oldreadcount;
-       qboolean oldbadread;
        sizebuf_t old;
 
        qboolean thisrecursive;
@@ -322,11 +317,12 @@ void CL_KeepaliveMessage (qboolean readmessages)
        thisrecursive = recursive;
        recursive = true;
 
+       time = Sys_DirtyTime();
        if(!thisrecursive)
        {
                if(cls.state != ca_dedicated)
                {
-                       if((time = Sys_DoubleTime()) >= nextupdate)
+                       if(time >= nextupdate || time < nextupdate) // check if time stepped backwards
                        {
                                SCR_UpdateLoadingScreenIfShown();
                                nextupdate = time + 2;
@@ -344,28 +340,16 @@ void CL_KeepaliveMessage (qboolean readmessages)
        if (readmessages)
        {
                // read messages from server, should just be nops
-               oldreadcount = msg_readcount;
-               oldbadread = msg_badread;
-               old = net_message;
-               memcpy(olddata, net_message.data, net_message.cursize);
+               old = cl_message;
+               memcpy(olddata, cl_message.data, cl_message.cursize);
 
                NetConn_ClientFrame();
 
-               msg_readcount = oldreadcount;
-               msg_badread = oldbadread;
-               net_message = old;
-               memcpy(net_message.data, olddata, net_message.cursize);
+               cl_message = old;
+               memcpy(cl_message.data, olddata, cl_message.cursize);
        }
 
-#if 0
-       if((time = Sys_DoubleTime()) >= lasttime + 1)
-       {
-               Con_Printf("long delta: %f\n", time - lasttime);
-       }
-       lasttime = Sys_DoubleTime();
-#endif
-
-       if (cls.netcon && (time = Sys_DoubleTime()) >= nextmsg)
+       if (cls.netcon && (time >= nextmsg || time < nextmsg)) // check if time stepped backwards
        {
                sizebuf_t       msg;
                unsigned char           buf[4];
@@ -462,12 +446,11 @@ void CL_ParseEntityLump(char *entdata)
        }
 }
 
-extern void CL_Locs_Reload_f(void);
-extern void CL_VM_Init (void);
 static const vec3_t defaultmins = {-4096, -4096, -4096};
 static const vec3_t defaultmaxs = {4096, 4096, 4096};
 static void CL_SetupWorldModel(void)
 {
+       prvm_prog_t *prog = CLVM_prog;
        // update the world model
        cl.entities[0].render.model = cl.worldmodel = CL_GetModelByIndex(1);
        CL_UpdateRenderEntity(&cl.entities[0].render);
@@ -483,14 +466,14 @@ static void CL_SetupWorldModel(void)
                Cvar_SetQuick(&cl_worldname, cl.worldname);
                Cvar_SetQuick(&cl_worldnamenoextension, cl.worldnamenoextension);
                Cvar_SetQuick(&cl_worldbasename, cl.worldbasename);
-               World_SetSize(&cl.world, cl.worldname, cl.worldmodel->normalmins, cl.worldmodel->normalmaxs);
+               World_SetSize(&cl.world, cl.worldname, cl.worldmodel->normalmins, cl.worldmodel->normalmaxs, prog);
        }
        else
        {
                Cvar_SetQuick(&cl_worldmessage, cl.worldmessage);
                Cvar_SetQuick(&cl_worldnamenoextension, "");
                Cvar_SetQuick(&cl_worldbasename, "");
-               World_SetSize(&cl.world, "", defaultmins, defaultmaxs);
+               World_SetSize(&cl.world, "", defaultmins, defaultmaxs, prog);
        }
        World_Start(&cl.world);
 
@@ -527,6 +510,7 @@ static void CL_SetupWorldModel(void)
 static qboolean QW_CL_CheckOrDownloadFile(const char *filename)
 {
        qfile_t *file;
+       char vabuf[1024];
 
        // see if the file already exists
        file = FS_OpenVirtualFile(filename, true);
@@ -558,7 +542,7 @@ static qboolean QW_CL_CheckOrDownloadFile(const char *filename)
        }
 
        MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
-       MSG_WriteString(&cls.netcon->message, va("download %s", filename));
+       MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "download %s", filename));
 
        cls.qw_downloadnumber++;
        cls.qw_downloadpercent = 0;
@@ -571,6 +555,7 @@ static void QW_CL_ProcessUserInfo(int slot);
 static void QW_CL_RequestNextDownload(void)
 {
        int i;
+       char vabuf[1024];
 
        // clear name of file that just finished
        cls.qw_downloadname[0] = 0;
@@ -587,7 +572,7 @@ static void QW_CL_RequestNextDownload(void)
                        if (!cl.scores[cls.qw_downloadnumber].name[0])
                                continue;
                        // check if we need to download the file, and return if so
-                       if (!QW_CL_CheckOrDownloadFile(va("skins/%s.pcx", cl.scores[cls.qw_downloadnumber].qw_skin)))
+                       if (!QW_CL_CheckOrDownloadFile(va(vabuf, sizeof(vabuf), "skins/%s.pcx", cl.scores[cls.qw_downloadnumber].qw_skin)))
                                return;
                }
 
@@ -603,7 +588,7 @@ static void QW_CL_RequestNextDownload(void)
                        cls.signon = SIGNONS-1;
                        // we'll go to SIGNONS when the first entity update is received
                        MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
-                       MSG_WriteString(&cls.netcon->message, va("begin %i", cl.qw_servercount));
+                       MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "begin %i", cl.qw_servercount));
                }
                break;
        case dl_model:
@@ -668,12 +653,12 @@ static void QW_CL_RequestNextDownload(void)
                CL_SetupWorldModel();
 
                // add pmodel/emodel CRCs to userinfo
-               CL_SetInfo("pmodel", va("%i", FS_CRCFile("progs/player.mdl", NULL)), true, true, true, true);
-               CL_SetInfo("emodel", va("%i", FS_CRCFile("progs/eyes.mdl", NULL)), true, true, true, true);
+               CL_SetInfo("pmodel", va(vabuf, sizeof(vabuf), "%i", FS_CRCFile("progs/player.mdl", NULL)), true, true, true, true);
+               CL_SetInfo("emodel", va(vabuf, sizeof(vabuf), "%i", FS_CRCFile("progs/eyes.mdl", NULL)), true, true, true, true);
 
                // done checking sounds and models, send a prespawn command now
                MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
-               MSG_WriteString(&cls.netcon->message, va("prespawn %i 0 %i", cl.qw_servercount, cl.model_precache[1]->brush.qw_md4sum2));
+               MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "prespawn %i 0 %i", cl.qw_servercount, cl.model_precache[1]->brush.qw_md4sum2));
 
                if (cls.qw_downloadmemory)
                {
@@ -694,7 +679,7 @@ static void QW_CL_RequestNextDownload(void)
                for (;cl.sound_name[cls.qw_downloadnumber][0];cls.qw_downloadnumber++)
                {
                        // check if we need to download the file, and return if so
-                       if (!QW_CL_CheckOrDownloadFile(va("sound/%s", cl.sound_name[cls.qw_downloadnumber])))
+                       if (!QW_CL_CheckOrDownloadFile(va(vabuf, sizeof(vabuf), "sound/%s", cl.sound_name[cls.qw_downloadnumber])))
                                return;
                }
 
@@ -724,7 +709,7 @@ static void QW_CL_RequestNextDownload(void)
 
                // done with sound downloads, next we check models
                MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
-               MSG_WriteString(&cls.netcon->message, va("modellist %i %i", cl.qw_servercount, 0));
+               MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "modellist %i %i", cl.qw_servercount, 0));
                break;
        case dl_none:
        default:
@@ -734,8 +719,8 @@ static void QW_CL_RequestNextDownload(void)
 
 static void QW_CL_ParseDownload(void)
 {
-       int size = (signed short)MSG_ReadShort();
-       int percent = MSG_ReadByte();
+       int size = (signed short)MSG_ReadShort(&cl_message);
+       int percent = MSG_ReadByte(&cl_message);
 
        //Con_Printf("download %i %i%% (%i/%i)\n", size, percent, cls.qw_downloadmemorycursize, cls.qw_downloadmemorymaxsize);
 
@@ -743,7 +728,7 @@ static void QW_CL_ParseDownload(void)
        if (!cls.netcon)
        {
                if (size > 0)
-                       msg_readcount += size;
+                       cl_message.readcount += size;
                return;
        }
 
@@ -754,7 +739,7 @@ static void QW_CL_ParseDownload(void)
                return;
        }
 
-       if (msg_readcount + (unsigned short)size > net_message.cursize)
+       if (cl_message.readcount + (unsigned short)size > cl_message.cursize)
                Host_Error("corrupt download message\n");
 
        // make sure the buffer is big enough to include this new fragment
@@ -773,7 +758,7 @@ static void QW_CL_ParseDownload(void)
        }
 
        // read the fragment out of the packet
-       MSG_ReadBytes(size, cls.qw_downloadmemory + cls.qw_downloadmemorycursize);
+       MSG_ReadBytes(&cl_message, size, cls.qw_downloadmemory + cls.qw_downloadmemorycursize);
        cls.qw_downloadmemorycursize += size;
        cls.qw_downloadspeedcount += size;
 
@@ -802,13 +787,14 @@ static void QW_CL_ParseDownload(void)
 static void QW_CL_ParseModelList(void)
 {
        int n;
-       int nummodels = MSG_ReadByte();
+       int nummodels = MSG_ReadByte(&cl_message);
        char *str;
+       char vabuf[1024];
 
        // parse model precache list
        for (;;)
        {
-               str = MSG_ReadString();
+               str = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
                if (!str[0])
                        break;
                nummodels++;
@@ -819,11 +805,11 @@ static void QW_CL_ParseModelList(void)
                strlcpy(cl.model_name[nummodels], str, sizeof (cl.model_name[nummodels]));
        }
 
-       n = MSG_ReadByte();
+       n = MSG_ReadByte(&cl_message);
        if (n)
        {
                MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
-               MSG_WriteString(&cls.netcon->message, va("modellist %i %i", cl.qw_servercount, n));
+               MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "modellist %i %i", cl.qw_servercount, n));
                return;
        }
 
@@ -836,13 +822,14 @@ static void QW_CL_ParseModelList(void)
 static void QW_CL_ParseSoundList(void)
 {
        int n;
-       int numsounds = MSG_ReadByte();
+       int numsounds = MSG_ReadByte(&cl_message);
        char *str;
+       char vabuf[1024];
 
        // parse sound precache list
        for (;;)
        {
-               str = MSG_ReadString();
+               str = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
                if (!str[0])
                        break;
                numsounds++;
@@ -853,12 +840,12 @@ static void QW_CL_ParseSoundList(void)
                strlcpy(cl.sound_name[numsounds], str, sizeof (cl.sound_name[numsounds]));
        }
 
-       n = MSG_ReadByte();
+       n = MSG_ReadByte(&cl_message);
 
        if (n)
        {
                MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
-               MSG_WriteString(&cls.netcon->message, va("soundlist %i %i", cl.qw_servercount, n));
+               MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "soundlist %i %i", cl.qw_servercount, n));
                return;
        }
 
@@ -971,16 +958,16 @@ static void QW_CL_ProcessUserInfo(int slot)
 static void QW_CL_UpdateUserInfo(void)
 {
        int slot;
-       slot = MSG_ReadByte();
+       slot = MSG_ReadByte(&cl_message);
        if (slot >= cl.maxclients)
        {
                Con_Printf("svc_updateuserinfo >= cl.maxclients\n");
-               MSG_ReadLong();
-               MSG_ReadString();
+               MSG_ReadLong(&cl_message);
+               MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
                return;
        }
-       cl.scores[slot].qw_userid = MSG_ReadLong();
-       strlcpy(cl.scores[slot].qw_userinfo, MSG_ReadString(), sizeof(cl.scores[slot].qw_userinfo));
+       cl.scores[slot].qw_userid = MSG_ReadLong(&cl_message);
+       strlcpy(cl.scores[slot].qw_userinfo, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof(cl.scores[slot].qw_userinfo));
 
        QW_CL_ProcessUserInfo(slot);
 }
@@ -990,9 +977,9 @@ static void QW_CL_SetInfo(void)
        int slot;
        char key[2048];
        char value[2048];
-       slot = MSG_ReadByte();
-       strlcpy(key, MSG_ReadString(), sizeof(key));
-       strlcpy(value, MSG_ReadString(), sizeof(value));
+       slot = MSG_ReadByte(&cl_message);
+       strlcpy(key, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof(key));
+       strlcpy(value, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof(value));
        if (slot >= cl.maxclients)
        {
                Con_Printf("svc_setinfo >= cl.maxclients\n");
@@ -1008,8 +995,8 @@ static void QW_CL_ServerInfo(void)
        char key[2048];
        char value[2048];
        char temp[32];
-       strlcpy(key, MSG_ReadString(), sizeof(key));
-       strlcpy(value, MSG_ReadString(), sizeof(value));
+       strlcpy(key, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof(key));
+       strlcpy(value, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof(value));
        Con_DPrintf("SERVERINFO: %s=%s\n", key, value);
        InfoString_SetValue(cl.qw_serverinfo, sizeof(cl.qw_serverinfo), key, value);
        InfoString_GetValue(cl.qw_serverinfo, "teamplay", temp, sizeof(temp));
@@ -1019,13 +1006,13 @@ static void QW_CL_ServerInfo(void)
 static void QW_CL_ParseNails(void)
 {
        int i, j;
-       int numnails = MSG_ReadByte();
+       int numnails = MSG_ReadByte(&cl_message);
        vec_t *v;
        unsigned char bits[6];
        for (i = 0;i < numnails;i++)
        {
                for (j = 0;j < 6;j++)
-                       bits[j] = MSG_ReadByte();
+                       bits[j] = MSG_ReadByte(&cl_message);
                if (cl.qw_num_nails > 255)
                        continue;
                v = cl.qw_nails[cl.qw_num_nails++];
@@ -1061,8 +1048,9 @@ static void CL_UpdateItemsAndWeapon(void)
 #define LOADPROGRESSWEIGHT_WORLDMODEL      30.0
 #define LOADPROGRESSWEIGHT_WORLDMODEL_INIT  2.0
 
-void CL_BeginDownloads(qboolean aborteddownload)
+static void CL_BeginDownloads(qboolean aborteddownload)
 {
+       char vabuf[1024];
        // quakeworld works differently
        if (cls.protocol == PROTOCOL_QUAKEWORLD)
                return;
@@ -1095,13 +1083,13 @@ void CL_BeginDownloads(qboolean aborteddownload)
                 && csqc_progcrc.integer >= 0
                 && cl_serverextension_download.integer
                 && (FS_CRCFile(csqc_progname.string, &progsize) != csqc_progcrc.integer || ((int)progsize != csqc_progsize.integer && csqc_progsize.integer != -1))
-                && !FS_FileExists(va("dlcache/%s.%i.%i", csqc_progname.string, csqc_progsize.integer, csqc_progcrc.integer)))
+                && !FS_FileExists(va(vabuf, sizeof(vabuf), "dlcache/%s.%i.%i", csqc_progname.string, csqc_progsize.integer, csqc_progcrc.integer)))
                {
                        Con_Printf("Downloading new CSQC code to dlcache/%s.%i.%i\n", csqc_progname.string, csqc_progsize.integer, csqc_progcrc.integer);
                        if(cl_serverextension_download.integer == 2 && FS_HasZlib())
-                               Cmd_ForwardStringToServer(va("download %s deflate", csqc_progname.string));
+                               Cmd_ForwardStringToServer(va(vabuf, sizeof(vabuf), "download %s deflate", csqc_progname.string));
                        else
-                               Cmd_ForwardStringToServer(va("download %s", csqc_progname.string));
+                               Cmd_ForwardStringToServer(va(vabuf, sizeof(vabuf), "download %s", csqc_progname.string));
                        return;
                }
        }
@@ -1269,7 +1257,7 @@ void CL_BeginDownloads(qboolean aborteddownload)
                                // regarding the * check: don't try to download submodels
                                if (cl_serverextension_download.integer && cls.netcon && cl.model_name[cl.downloadmodel_current][0] != '*' && !sv.active)
                                {
-                                       Cmd_ForwardStringToServer(va("download %s", cl.model_name[cl.downloadmodel_current]));
+                                       Cmd_ForwardStringToServer(va(vabuf, sizeof(vabuf), "download %s", cl.model_name[cl.downloadmodel_current]));
                                        // we'll try loading again when the download finishes
                                        return;
                                }
@@ -1322,7 +1310,7 @@ void CL_BeginDownloads(qboolean aborteddownload)
                                Con_Printf("Sound %s not found\n", soundname);
                                if (cl_serverextension_download.integer && cls.netcon && !sv.active)
                                {
-                                       Cmd_ForwardStringToServer(va("download %s", soundname));
+                                       Cmd_ForwardStringToServer(va(vabuf, sizeof(vabuf), "download %s", soundname));
                                        // we'll try loading again when the download finishes
                                        return;
                                }
@@ -1348,7 +1336,7 @@ void CL_BeginDownloads(qboolean aborteddownload)
        }
 }
 
-void CL_BeginDownloads_f(void)
+static void CL_BeginDownloads_f(void)
 {
        // prevent cl_begindownloads from being issued multiple times in one match
        // to prevent accidentally cancelled downloads
@@ -1358,7 +1346,7 @@ void CL_BeginDownloads_f(void)
                CL_BeginDownloads(false);
 }
 
-void CL_StopDownload(int size, int crc)
+static void CL_StopDownload(int size, int crc)
 {
        if (cls.qw_downloadmemory && cls.qw_downloadmemorycursize == size && CRC_Block(cls.qw_downloadmemory, cls.qw_downloadmemorycursize) == crc)
        {
@@ -1443,12 +1431,12 @@ void CL_StopDownload(int size, int crc)
        cls.qw_downloadpercent = 0;
 }
 
-void CL_ParseDownload(void)
+static void CL_ParseDownload(void)
 {
        int i, start, size;
        static unsigned char data[NET_MAXMESSAGE];
-       start = MSG_ReadLong();
-       size = (unsigned short)MSG_ReadShort();
+       start = MSG_ReadLong(&cl_message);
+       size = (unsigned short)MSG_ReadShort(&cl_message);
 
        // record the start/size information to ack in the next input packet
        for (i = 0;i < CL_MAX_DOWNLOADACKS;i++)
@@ -1461,7 +1449,7 @@ void CL_ParseDownload(void)
                }
        }
 
-       MSG_ReadBytes(size, data);
+       MSG_ReadBytes(&cl_message, size, data);
 
        if (!cls.qw_downloadname[0])
        {
@@ -1482,7 +1470,7 @@ void CL_ParseDownload(void)
        cls.qw_downloadspeedcount += size;
 }
 
-void CL_DownloadBegin_f(void)
+static void CL_DownloadBegin_f(void)
 {
        int size = atoi(Cmd_Argv(1));
 
@@ -1515,7 +1503,7 @@ void CL_DownloadBegin_f(void)
        Cmd_ForwardStringToServer("sv_startdownload");
 }
 
-void CL_StopDownload_f(void)
+static void CL_StopDownload_f(void)
 {
        Curl_CancelAll();
        if (cls.qw_downloadname[0])
@@ -1526,7 +1514,7 @@ void CL_StopDownload_f(void)
        CL_BeginDownloads(true);
 }
 
-void CL_DownloadFinished_f(void)
+static void CL_DownloadFinished_f(void)
 {
        if (Cmd_Argc() < 3)
        {
@@ -1539,29 +1527,30 @@ void CL_DownloadFinished_f(void)
 
 static void CL_SendPlayerInfo(void)
 {
+       char vabuf[1024];
        MSG_WriteByte (&cls.netcon->message, clc_stringcmd);
-       MSG_WriteString (&cls.netcon->message, va("name \"%s\"", cl_name.string));
+       MSG_WriteString (&cls.netcon->message, va(vabuf, sizeof(vabuf), "name \"%s\"", cl_name.string));
 
        MSG_WriteByte (&cls.netcon->message, clc_stringcmd);
-       MSG_WriteString (&cls.netcon->message, va("color %i %i", cl_color.integer >> 4, cl_color.integer & 15));
+       MSG_WriteString (&cls.netcon->message, va(vabuf, sizeof(vabuf), "color %i %i", cl_color.integer >> 4, cl_color.integer & 15));
 
        MSG_WriteByte (&cls.netcon->message, clc_stringcmd);
-       MSG_WriteString (&cls.netcon->message, va("rate %i", cl_rate.integer));
+       MSG_WriteString (&cls.netcon->message, va(vabuf, sizeof(vabuf), "rate %i", cl_rate.integer));
 
        if (cl_pmodel.integer)
        {
                MSG_WriteByte (&cls.netcon->message, clc_stringcmd);
-               MSG_WriteString (&cls.netcon->message, va("pmodel %i", cl_pmodel.integer));
+               MSG_WriteString (&cls.netcon->message, va(vabuf, sizeof(vabuf), "pmodel %i", cl_pmodel.integer));
        }
        if (*cl_playermodel.string)
        {
                MSG_WriteByte (&cls.netcon->message, clc_stringcmd);
-               MSG_WriteString (&cls.netcon->message, va("playermodel %s", cl_playermodel.string));
+               MSG_WriteString (&cls.netcon->message, va(vabuf, sizeof(vabuf), "playermodel %s", cl_playermodel.string));
        }
        if (*cl_playerskin.string)
        {
                MSG_WriteByte (&cls.netcon->message, clc_stringcmd);
-               MSG_WriteString (&cls.netcon->message, va("playerskin %s", cl_playerskin.string));
+               MSG_WriteString (&cls.netcon->message, va(vabuf, sizeof(vabuf), "playerskin %s", cl_playerskin.string));
        }
 }
 
@@ -1638,12 +1627,13 @@ static void CL_SignonReply (void)
 CL_ParseServerInfo
 ==================
 */
-void CL_ParseServerInfo (void)
+static void CL_ParseServerInfo (void)
 {
        char *str;
        int i;
        protocolversion_t protocol;
        int nummodels, numsounds;
+       char vabuf[1024];
 
        // if we start loading a level and a video is still playing, stop it
        CL_VideoStop();
@@ -1672,7 +1662,7 @@ void CL_ParseServerInfo (void)
        CL_ClearState ();
 
 // parse protocol version number
-       i = MSG_ReadLong ();
+       i = MSG_ReadLong(&cl_message);
        protocol = Protocol_EnumForNumber(i);
        if (protocol == PROTOCOL_UNKNOWN)
        {
@@ -1691,9 +1681,9 @@ void CL_ParseServerInfo (void)
        {
                char gamedir[1][MAX_QPATH];
 
-               cl.qw_servercount = MSG_ReadLong();
+               cl.qw_servercount = MSG_ReadLong(&cl_message);
 
-               str = MSG_ReadString();
+               str = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
                Con_Printf("server gamedir is %s\n", str);
                strlcpy(gamedir[0], str, sizeof(gamedir[0]));
 
@@ -1705,27 +1695,27 @@ void CL_ParseServerInfo (void)
                cl.maxclients = 32;
 
                // parse player number
-               i = MSG_ReadByte();
+               i = MSG_ReadByte(&cl_message);
                // cl.qw_spectator is an unneeded flag, cl.scores[cl.playerentity].qw_spectator works better (it can be updated by the server during the game)
                //cl.qw_spectator = (i & 128) != 0;
                cl.realplayerentity = cl.playerentity = cl.viewentity = (i & 127) + 1;
                cl.scores = (scoreboard_t *)Mem_Alloc(cls.levelmempool, cl.maxclients*sizeof(*cl.scores));
 
                // get the full level name
-               str = MSG_ReadString ();
+               str = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
                strlcpy (cl.worldmessage, str, sizeof(cl.worldmessage));
 
                // get the movevars that are defined in the qw protocol
-               cl.movevars_gravity            = MSG_ReadFloat();
-               cl.movevars_stopspeed          = MSG_ReadFloat();
-               cl.movevars_maxspeed           = MSG_ReadFloat();
-               cl.movevars_spectatormaxspeed  = MSG_ReadFloat();
-               cl.movevars_accelerate         = MSG_ReadFloat();
-               cl.movevars_airaccelerate      = MSG_ReadFloat();
-               cl.movevars_wateraccelerate    = MSG_ReadFloat();
-               cl.movevars_friction           = MSG_ReadFloat();
-               cl.movevars_waterfriction      = MSG_ReadFloat();
-               cl.movevars_entgravity         = MSG_ReadFloat();
+               cl.movevars_gravity            = MSG_ReadFloat(&cl_message);
+               cl.movevars_stopspeed          = MSG_ReadFloat(&cl_message);
+               cl.movevars_maxspeed           = MSG_ReadFloat(&cl_message);
+               cl.movevars_spectatormaxspeed  = MSG_ReadFloat(&cl_message);
+               cl.movevars_accelerate         = MSG_ReadFloat(&cl_message);
+               cl.movevars_airaccelerate      = MSG_ReadFloat(&cl_message);
+               cl.movevars_wateraccelerate    = MSG_ReadFloat(&cl_message);
+               cl.movevars_friction           = MSG_ReadFloat(&cl_message);
+               cl.movevars_waterfriction      = MSG_ReadFloat(&cl_message);
+               cl.movevars_entgravity         = MSG_ReadFloat(&cl_message);
 
                // other movevars not in the protocol...
                cl.movevars_wallfriction = 0;
@@ -1746,7 +1736,7 @@ void CL_ParseServerInfo (void)
                if (cls.netcon)
                {
                        MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
-                       MSG_WriteString(&cls.netcon->message, va("soundlist %i %i", cl.qw_servercount, 0));
+                       MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "soundlist %i %i", cl.qw_servercount, 0));
                }
 
                cl.loadbegun = false;
@@ -1773,7 +1763,7 @@ void CL_ParseServerInfo (void)
        else
        {
        // parse maxclients
-               cl.maxclients = MSG_ReadByte ();
+               cl.maxclients = MSG_ReadByte(&cl_message);
                if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
                {
                        Host_Error("Bad maxclients (%u) from server", cl.maxclients);
@@ -1782,14 +1772,14 @@ void CL_ParseServerInfo (void)
                cl.scores = (scoreboard_t *)Mem_Alloc(cls.levelmempool, cl.maxclients*sizeof(*cl.scores));
 
        // parse gametype
-               cl.gametype = MSG_ReadByte ();
+               cl.gametype = MSG_ReadByte(&cl_message);
                // the original id singleplayer demos are bugged and contain
                // GAME_DEATHMATCH even for singleplayer
                if (cl.maxclients == 1 && cls.protocol == PROTOCOL_QUAKE)
                        cl.gametype = GAME_COOP;
 
        // parse signon message
-               str = MSG_ReadString ();
+               str = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
                strlcpy (cl.worldmessage, str, sizeof(cl.worldmessage));
 
        // seperate the printfs so the server message can have a color
@@ -1802,7 +1792,7 @@ void CL_ParseServerInfo (void)
                // parse model precache list
                for (nummodels=1 ; ; nummodels++)
                {
-                       str = MSG_ReadString();
+                       str = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
                        if (!str[0])
                                break;
                        if (nummodels==MAX_MODELS)
@@ -1814,7 +1804,7 @@ void CL_ParseServerInfo (void)
                // parse sound precache list
                for (numsounds=1 ; ; numsounds++)
                {
-                       str = MSG_ReadString();
+                       str = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
                        if (!str[0])
                                break;
                        if (numsounds==MAX_SOUNDS)
@@ -1917,6 +1907,7 @@ void CL_ParseServerInfo (void)
                                Con_Print ("ERROR: couldn't open.\n");
                }
        }
+       cl.islocalgame = NetConn_IsLocalGame();
 }
 
 void CL_ValidateState(entity_state_t *s)
@@ -2065,7 +2056,7 @@ void CL_MoveLerpEntityStates(entity_t *ent)
 CL_ParseBaseline
 ==================
 */
-void CL_ParseBaseline (entity_t *ent, int large)
+static void CL_ParseBaseline (entity_t *ent, int large)
 {
        int i;
 
@@ -2074,25 +2065,25 @@ void CL_ParseBaseline (entity_t *ent, int large)
        ent->state_baseline.active = true;
        if (large)
        {
-               ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort ();
-               ent->state_baseline.frame = (unsigned short) MSG_ReadShort ();
+               ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort(&cl_message);
+               ent->state_baseline.frame = (unsigned short) MSG_ReadShort(&cl_message);
        }
        else if (cls.protocol == PROTOCOL_NEHAHRABJP || cls.protocol == PROTOCOL_NEHAHRABJP2 || cls.protocol == PROTOCOL_NEHAHRABJP3)
        {
-               ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort ();
-               ent->state_baseline.frame = MSG_ReadByte ();
+               ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort(&cl_message);
+               ent->state_baseline.frame = MSG_ReadByte(&cl_message);
        }
        else
        {
-               ent->state_baseline.modelindex = MSG_ReadByte ();
-               ent->state_baseline.frame = MSG_ReadByte ();
+               ent->state_baseline.modelindex = MSG_ReadByte(&cl_message);
+               ent->state_baseline.frame = MSG_ReadByte(&cl_message);
        }
-       ent->state_baseline.colormap = MSG_ReadByte();
-       ent->state_baseline.skin = MSG_ReadByte();
+       ent->state_baseline.colormap = MSG_ReadByte(&cl_message);
+       ent->state_baseline.skin = MSG_ReadByte(&cl_message);
        for (i = 0;i < 3;i++)
        {
-               ent->state_baseline.origin[i] = MSG_ReadCoord(cls.protocol);
-               ent->state_baseline.angles[i] = MSG_ReadAngle(cls.protocol);
+               ent->state_baseline.origin[i] = MSG_ReadCoord(&cl_message, cls.protocol);
+               ent->state_baseline.angles[i] = MSG_ReadAngle(&cl_message, cls.protocol);
        }
        ent->state_previous = ent->state_current = ent->state_baseline;
 }
@@ -2105,7 +2096,7 @@ CL_ParseClientdata
 Server information pertaining to this client only
 ==================
 */
-void CL_ParseClientdata (void)
+static void CL_ParseClientdata (void)
 {
        int i, bits;
 
@@ -2132,89 +2123,89 @@ void CL_ParseClientdata (void)
        cl.mvelocity[0][2] = 0;
        cl.mviewzoom[0] = 1;
 
-       bits = (unsigned short) MSG_ReadShort ();
+       bits = (unsigned short) MSG_ReadShort(&cl_message);
        if (bits & SU_EXTEND1)
-               bits |= (MSG_ReadByte() << 16);
+               bits |= (MSG_ReadByte(&cl_message) << 16);
        if (bits & SU_EXTEND2)
-               bits |= (MSG_ReadByte() << 24);
+               bits |= (MSG_ReadByte(&cl_message) << 24);
 
        if (bits & SU_VIEWHEIGHT)
-               cl.stats[STAT_VIEWHEIGHT] = MSG_ReadChar ();
+               cl.stats[STAT_VIEWHEIGHT] = MSG_ReadChar(&cl_message);
 
        if (bits & SU_IDEALPITCH)
-               cl.idealpitch = MSG_ReadChar ();
+               cl.idealpitch = MSG_ReadChar(&cl_message);
 
        for (i = 0;i < 3;i++)
        {
                if (bits & (SU_PUNCH1<<i) )
                {
                        if (cls.protocol == PROTOCOL_QUAKE || cls.protocol == PROTOCOL_QUAKEDP || cls.protocol == PROTOCOL_NEHAHRAMOVIE || cls.protocol == PROTOCOL_NEHAHRABJP || cls.protocol == PROTOCOL_NEHAHRABJP2 || cls.protocol == PROTOCOL_NEHAHRABJP3)
-                               cl.mpunchangle[0][i] = MSG_ReadChar();
+                               cl.mpunchangle[0][i] = MSG_ReadChar(&cl_message);
                        else
-                               cl.mpunchangle[0][i] = MSG_ReadAngle16i();
+                               cl.mpunchangle[0][i] = MSG_ReadAngle16i(&cl_message);
                }
                if (bits & (SU_PUNCHVEC1<<i))
                {
                        if (cls.protocol == PROTOCOL_DARKPLACES1 || cls.protocol == PROTOCOL_DARKPLACES2 || cls.protocol == PROTOCOL_DARKPLACES3 || cls.protocol == PROTOCOL_DARKPLACES4)
-                               cl.mpunchvector[0][i] = MSG_ReadCoord16i();
+                               cl.mpunchvector[0][i] = MSG_ReadCoord16i(&cl_message);
                        else
-                               cl.mpunchvector[0][i] = MSG_ReadCoord32f();
+                               cl.mpunchvector[0][i] = MSG_ReadCoord32f(&cl_message);
                }
                if (bits & (SU_VELOCITY1<<i) )
                {
                        if (cls.protocol == PROTOCOL_QUAKE || cls.protocol == PROTOCOL_QUAKEDP || cls.protocol == PROTOCOL_NEHAHRAMOVIE || cls.protocol == PROTOCOL_NEHAHRABJP || cls.protocol == PROTOCOL_NEHAHRABJP2 || cls.protocol == PROTOCOL_NEHAHRABJP3 || cls.protocol == PROTOCOL_DARKPLACES1 || cls.protocol == PROTOCOL_DARKPLACES2 || cls.protocol == PROTOCOL_DARKPLACES3 || cls.protocol == PROTOCOL_DARKPLACES4)
-                               cl.mvelocity[0][i] = MSG_ReadChar()*16;
+                               cl.mvelocity[0][i] = MSG_ReadChar(&cl_message)*16;
                        else
-                               cl.mvelocity[0][i] = MSG_ReadCoord32f();
+                               cl.mvelocity[0][i] = MSG_ReadCoord32f(&cl_message);
                }
        }
 
        // LordHavoc: hipnotic demos don't have this bit set but should
        if (bits & SU_ITEMS || cls.protocol == PROTOCOL_QUAKE || cls.protocol == PROTOCOL_QUAKEDP || cls.protocol == PROTOCOL_NEHAHRAMOVIE || cls.protocol == PROTOCOL_NEHAHRABJP || cls.protocol == PROTOCOL_NEHAHRABJP2 || cls.protocol == PROTOCOL_NEHAHRABJP3 || cls.protocol == PROTOCOL_DARKPLACES1 || cls.protocol == PROTOCOL_DARKPLACES2 || cls.protocol == PROTOCOL_DARKPLACES3 || cls.protocol == PROTOCOL_DARKPLACES4 || cls.protocol == PROTOCOL_DARKPLACES5)
-               cl.stats[STAT_ITEMS] = MSG_ReadLong ();
+               cl.stats[STAT_ITEMS] = MSG_ReadLong(&cl_message);
 
        cl.onground = (bits & SU_ONGROUND) != 0;
        cl.inwater = (bits & SU_INWATER) != 0;
 
        if (cls.protocol == PROTOCOL_DARKPLACES5)
        {
-               cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadShort() : 0;
-               cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadShort() : 0;
-               cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadShort() : 0;
-               cl.stats[STAT_HEALTH] = MSG_ReadShort();
-               cl.stats[STAT_AMMO] = MSG_ReadShort();
-               cl.stats[STAT_SHELLS] = MSG_ReadShort();
-               cl.stats[STAT_NAILS] = MSG_ReadShort();
-               cl.stats[STAT_ROCKETS] = MSG_ReadShort();
-               cl.stats[STAT_CELLS] = MSG_ReadShort();
-               cl.stats[STAT_ACTIVEWEAPON] = (unsigned short) MSG_ReadShort ();
+               cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadShort(&cl_message) : 0;
+               cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadShort(&cl_message) : 0;
+               cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadShort(&cl_message) : 0;
+               cl.stats[STAT_HEALTH] = MSG_ReadShort(&cl_message);
+               cl.stats[STAT_AMMO] = MSG_ReadShort(&cl_message);
+               cl.stats[STAT_SHELLS] = MSG_ReadShort(&cl_message);
+               cl.stats[STAT_NAILS] = MSG_ReadShort(&cl_message);
+               cl.stats[STAT_ROCKETS] = MSG_ReadShort(&cl_message);
+               cl.stats[STAT_CELLS] = MSG_ReadShort(&cl_message);
+               cl.stats[STAT_ACTIVEWEAPON] = (unsigned short) MSG_ReadShort(&cl_message);
        }
        else if (cls.protocol == PROTOCOL_QUAKE || cls.protocol == PROTOCOL_QUAKEDP || cls.protocol == PROTOCOL_NEHAHRAMOVIE || cls.protocol == PROTOCOL_NEHAHRABJP || cls.protocol == PROTOCOL_NEHAHRABJP2 || cls.protocol == PROTOCOL_NEHAHRABJP3 || cls.protocol == PROTOCOL_NEHAHRABJP || cls.protocol == PROTOCOL_NEHAHRABJP2 || cls.protocol == PROTOCOL_NEHAHRABJP3 || cls.protocol == PROTOCOL_DARKPLACES1 || cls.protocol == PROTOCOL_DARKPLACES2 || cls.protocol == PROTOCOL_DARKPLACES3 || cls.protocol == PROTOCOL_DARKPLACES4)
        {
-               cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadByte() : 0;
-               cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadByte() : 0;
+               cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadByte(&cl_message) : 0;
+               cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadByte(&cl_message) : 0;
                if (cls.protocol == PROTOCOL_NEHAHRABJP || cls.protocol == PROTOCOL_NEHAHRABJP2 || cls.protocol == PROTOCOL_NEHAHRABJP3)
-                       cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? (unsigned short)MSG_ReadShort() : 0;
+                       cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? (unsigned short)MSG_ReadShort(&cl_message) : 0;
                else
-                       cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadByte() : 0;
-               cl.stats[STAT_HEALTH] = MSG_ReadShort();
-               cl.stats[STAT_AMMO] = MSG_ReadByte();
-               cl.stats[STAT_SHELLS] = MSG_ReadByte();
-               cl.stats[STAT_NAILS] = MSG_ReadByte();
-               cl.stats[STAT_ROCKETS] = MSG_ReadByte();
-               cl.stats[STAT_CELLS] = MSG_ReadByte();
+                       cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadByte(&cl_message) : 0;
+               cl.stats[STAT_HEALTH] = MSG_ReadShort(&cl_message);
+               cl.stats[STAT_AMMO] = MSG_ReadByte(&cl_message);
+               cl.stats[STAT_SHELLS] = MSG_ReadByte(&cl_message);
+               cl.stats[STAT_NAILS] = MSG_ReadByte(&cl_message);
+               cl.stats[STAT_ROCKETS] = MSG_ReadByte(&cl_message);
+               cl.stats[STAT_CELLS] = MSG_ReadByte(&cl_message);
                if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE || gamemode == GAME_NEXUIZ)
-                       cl.stats[STAT_ACTIVEWEAPON] = (1<<MSG_ReadByte ());
+                       cl.stats[STAT_ACTIVEWEAPON] = (1<<MSG_ReadByte(&cl_message));
                else
-                       cl.stats[STAT_ACTIVEWEAPON] = MSG_ReadByte ();
+                       cl.stats[STAT_ACTIVEWEAPON] = MSG_ReadByte(&cl_message);
        }
 
        if (bits & SU_VIEWZOOM)
        {
                if (cls.protocol == PROTOCOL_DARKPLACES2 || cls.protocol == PROTOCOL_DARKPLACES3 || cls.protocol == PROTOCOL_DARKPLACES4)
-                       cl.stats[STAT_VIEWZOOM] = MSG_ReadByte();
+                       cl.stats[STAT_VIEWZOOM] = MSG_ReadByte(&cl_message);
                else
-                       cl.stats[STAT_VIEWZOOM] = (unsigned short) MSG_ReadShort();
+                       cl.stats[STAT_VIEWZOOM] = (unsigned short) MSG_ReadShort(&cl_message);
        }
 
        // viewzoom interpolation
@@ -2226,7 +2217,7 @@ void CL_ParseClientdata (void)
 CL_ParseStatic
 =====================
 */
-void CL_ParseStatic (int large)
+static void CL_ParseStatic (int large)
 {
        entity_t *ent;
 
@@ -2266,46 +2257,46 @@ void CL_ParseStatic (int large)
 CL_ParseStaticSound
 ===================
 */
-void CL_ParseStaticSound (int large)
+static void CL_ParseStaticSound (int large)
 {
        vec3_t          org;
        int                     sound_num, vol, atten;
 
-       MSG_ReadVector(org, cls.protocol);
+       MSG_ReadVector(&cl_message, org, cls.protocol);
        if (large || cls.protocol == PROTOCOL_NEHAHRABJP2)
-               sound_num = (unsigned short) MSG_ReadShort ();
+               sound_num = (unsigned short) MSG_ReadShort(&cl_message);
        else
-               sound_num = MSG_ReadByte ();
-       vol = MSG_ReadByte ();
-       atten = MSG_ReadByte ();
+               sound_num = MSG_ReadByte(&cl_message);
+       vol = MSG_ReadByte(&cl_message);
+       atten = MSG_ReadByte(&cl_message);
 
        S_StaticSound (cl.sound_precache[sound_num], org, vol/255.0f, atten);
 }
 
-void CL_ParseEffect (void)
+static void CL_ParseEffect (void)
 {
        vec3_t          org;
        int                     modelindex, startframe, framecount, framerate;
 
-       MSG_ReadVector(org, cls.protocol);
-       modelindex = MSG_ReadByte ();
-       startframe = MSG_ReadByte ();
-       framecount = MSG_ReadByte ();
-       framerate = MSG_ReadByte ();
+       MSG_ReadVector(&cl_message, org, cls.protocol);
+       modelindex = MSG_ReadByte(&cl_message);
+       startframe = MSG_ReadByte(&cl_message);
+       framecount = MSG_ReadByte(&cl_message);
+       framerate = MSG_ReadByte(&cl_message);
 
        CL_Effect(org, modelindex, startframe, framecount, framerate);
 }
 
-void CL_ParseEffect2 (void)
+static void CL_ParseEffect2 (void)
 {
        vec3_t          org;
        int                     modelindex, startframe, framecount, framerate;
 
-       MSG_ReadVector(org, cls.protocol);
-       modelindex = (unsigned short) MSG_ReadShort ();
-       startframe = (unsigned short) MSG_ReadShort ();
-       framecount = MSG_ReadByte ();
-       framerate = MSG_ReadByte ();
+       MSG_ReadVector(&cl_message, org, cls.protocol);
+       modelindex = (unsigned short) MSG_ReadShort(&cl_message);
+       startframe = (unsigned short) MSG_ReadShort(&cl_message);
+       framecount = MSG_ReadByte(&cl_message);
+       framerate = MSG_ReadByte(&cl_message);
 
        CL_Effect(org, modelindex, startframe, framecount, framerate);
 }
@@ -2349,14 +2340,14 @@ void CL_NewBeam (int ent, vec3_t start, vec3_t end, dp_model_t *m, int lightning
                Con_Print("beam list overflow!\n");
 }
 
-void CL_ParseBeam (dp_model_t *m, int lightning)
+static void CL_ParseBeam (dp_model_t *m, int lightning)
 {
        int ent;
        vec3_t start, end;
 
-       ent = (unsigned short) MSG_ReadShort ();
-       MSG_ReadVector(start, cls.protocol);
-       MSG_ReadVector(end, cls.protocol);
+       ent = (unsigned short) MSG_ReadShort(&cl_message);
+       MSG_ReadVector(&cl_message, start, cls.protocol);
+       MSG_ReadVector(&cl_message, end, cls.protocol);
 
        if (ent >= MAX_EDICTS)
        {
@@ -2367,7 +2358,7 @@ void CL_ParseBeam (dp_model_t *m, int lightning)
        CL_NewBeam(ent, start, end, m, lightning);
 }
 
-void CL_ParseTempEntity(void)
+static void CL_ParseTempEntity(void)
 {
        int type;
        vec3_t pos, pos2;
@@ -2382,12 +2373,12 @@ void CL_ParseTempEntity(void)
 
        if (cls.protocol == PROTOCOL_QUAKEWORLD)
        {
-               type = MSG_ReadByte();
+               type = MSG_ReadByte(&cl_message);
                switch (type)
                {
                case QW_TE_WIZSPIKE:
                        // spike hitting wall
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 4);
                        CL_ParticleEffect(EFFECT_TE_WIZSPIKE, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        S_StartSound(-1, 0, cl.sfx_wizhit, pos, 1, 1);
@@ -2395,7 +2386,7 @@ void CL_ParseTempEntity(void)
 
                case QW_TE_KNIGHTSPIKE:
                        // spike hitting wall
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 4);
                        CL_ParticleEffect(EFFECT_TE_KNIGHTSPIKE, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        S_StartSound(-1, 0, cl.sfx_knighthit, pos, 1, 1);
@@ -2403,7 +2394,7 @@ void CL_ParseTempEntity(void)
 
                case QW_TE_SPIKE:
                        // spike hitting wall
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 4);
                        CL_ParticleEffect(EFFECT_TE_SPIKE, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        if (rand() % 5)
@@ -2421,7 +2412,7 @@ void CL_ParseTempEntity(void)
                        break;
                case QW_TE_SUPERSPIKE:
                        // super spike hitting wall
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 4);
                        CL_ParticleEffect(EFFECT_TE_SUPERSPIKE, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        if (rand() % 5)
@@ -2440,7 +2431,7 @@ void CL_ParseTempEntity(void)
 
                case QW_TE_EXPLOSION:
                        // rocket explosion
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 10);
                        CL_ParticleEffect(EFFECT_TE_EXPLOSION, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        S_StartSound(-1, 0, cl.sfx_r_exp3, pos, 1, 1);
@@ -2449,7 +2440,7 @@ void CL_ParseTempEntity(void)
 
                case QW_TE_TAREXPLOSION:
                        // tarbaby explosion
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 10);
                        CL_ParticleEffect(EFFECT_TE_TAREXPLOSION, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        S_StartSound(-1, 0, cl.sfx_r_exp3, pos, 1, 1);
@@ -2471,19 +2462,19 @@ void CL_ParseTempEntity(void)
                        break;
 
                case QW_TE_LAVASPLASH:
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_ParticleEffect(EFFECT_TE_LAVASPLASH, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        break;
 
                case QW_TE_TELEPORT:
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_ParticleEffect(EFFECT_TE_TELEPORT, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        break;
 
                case QW_TE_GUNSHOT:
                        // bullet hitting wall
-                       radius = MSG_ReadByte();
-                       MSG_ReadVector(pos, cls.protocol);
+                       radius = MSG_ReadByte(&cl_message);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 4);
                        VectorSet(pos2, pos[0] + radius, pos[1] + radius, pos[2] + radius);
                        VectorSet(pos, pos[0] - radius, pos[1] - radius, pos[2] - radius);
@@ -2506,14 +2497,14 @@ void CL_ParseTempEntity(void)
                        break;
 
                case QW_TE_BLOOD:
-                       count = MSG_ReadByte();
-                       MSG_ReadVector(pos, cls.protocol);
+                       count = MSG_ReadByte(&cl_message);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 4);
                        CL_ParticleEffect(EFFECT_TE_BLOOD, count, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        break;
 
                case QW_TE_LIGHTNINGBLOOD:
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 4);
                        CL_ParticleEffect(EFFECT_TE_BLOOD, 2.5, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        break;
@@ -2524,12 +2515,12 @@ void CL_ParseTempEntity(void)
        }
        else
        {
-               type = MSG_ReadByte();
+               type = MSG_ReadByte(&cl_message);
                switch (type)
                {
                case TE_WIZSPIKE:
                        // spike hitting wall
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 4);
                        CL_ParticleEffect(EFFECT_TE_WIZSPIKE, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        S_StartSound(-1, 0, cl.sfx_wizhit, pos, 1, 1);
@@ -2537,7 +2528,7 @@ void CL_ParseTempEntity(void)
 
                case TE_KNIGHTSPIKE:
                        // spike hitting wall
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 4);
                        CL_ParticleEffect(EFFECT_TE_KNIGHTSPIKE, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        S_StartSound(-1, 0, cl.sfx_knighthit, pos, 1, 1);
@@ -2545,7 +2536,7 @@ void CL_ParseTempEntity(void)
 
                case TE_SPIKE:
                        // spike hitting wall
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 4);
                        CL_ParticleEffect(EFFECT_TE_SPIKE, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        if (rand() % 5)
@@ -2563,7 +2554,7 @@ void CL_ParseTempEntity(void)
                        break;
                case TE_SPIKEQUAD:
                        // quad spike hitting wall
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 4);
                        CL_ParticleEffect(EFFECT_TE_SPIKEQUAD, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        if (rand() % 5)
@@ -2581,7 +2572,7 @@ void CL_ParseTempEntity(void)
                        break;
                case TE_SUPERSPIKE:
                        // super spike hitting wall
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 4);
                        CL_ParticleEffect(EFFECT_TE_SUPERSPIKE, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        if (rand() % 5)
@@ -2599,7 +2590,7 @@ void CL_ParseTempEntity(void)
                        break;
                case TE_SUPERSPIKEQUAD:
                        // quad super spike hitting wall
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 4);
                        CL_ParticleEffect(EFFECT_TE_SUPERSPIKEQUAD, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        if (rand() % 5)
@@ -2618,36 +2609,36 @@ void CL_ParseTempEntity(void)
                        // LordHavoc: added for improved blood splatters
                case TE_BLOOD:
                        // blood puff
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 4);
-                       dir[0] = MSG_ReadChar();
-                       dir[1] = MSG_ReadChar();
-                       dir[2] = MSG_ReadChar();
-                       count = MSG_ReadByte();
+                       dir[0] = MSG_ReadChar(&cl_message);
+                       dir[1] = MSG_ReadChar(&cl_message);
+                       dir[2] = MSG_ReadChar(&cl_message);
+                       count = MSG_ReadByte(&cl_message);
                        CL_ParticleEffect(EFFECT_TE_BLOOD, count, pos, pos, dir, dir, NULL, 0);
                        break;
                case TE_SPARK:
                        // spark shower
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 4);
-                       dir[0] = MSG_ReadChar();
-                       dir[1] = MSG_ReadChar();
-                       dir[2] = MSG_ReadChar();
-                       count = MSG_ReadByte();
+                       dir[0] = MSG_ReadChar(&cl_message);
+                       dir[1] = MSG_ReadChar(&cl_message);
+                       dir[2] = MSG_ReadChar(&cl_message);
+                       count = MSG_ReadByte(&cl_message);
                        CL_ParticleEffect(EFFECT_TE_SPARK, count, pos, pos, dir, dir, NULL, 0);
                        break;
                case TE_PLASMABURN:
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 4);
                        CL_ParticleEffect(EFFECT_TE_PLASMABURN, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        break;
                        // LordHavoc: added for improved gore
                case TE_BLOODSHOWER:
                        // vaporized body
-                       MSG_ReadVector(pos, cls.protocol); // mins
-                       MSG_ReadVector(pos2, cls.protocol); // maxs
-                       velspeed = MSG_ReadCoord(cls.protocol); // speed
-                       count = (unsigned short) MSG_ReadShort(); // number of particles
+                       MSG_ReadVector(&cl_message, pos, cls.protocol); // mins
+                       MSG_ReadVector(&cl_message, pos2, cls.protocol); // maxs
+                       velspeed = MSG_ReadCoord(&cl_message, cls.protocol); // speed
+                       count = (unsigned short) MSG_ReadShort(&cl_message); // number of particles
                        vel1[0] = -velspeed;
                        vel1[1] = -velspeed;
                        vel1[2] = -velspeed;
@@ -2659,39 +2650,39 @@ void CL_ParseTempEntity(void)
 
                case TE_PARTICLECUBE:
                        // general purpose particle effect
-                       MSG_ReadVector(pos, cls.protocol); // mins
-                       MSG_ReadVector(pos2, cls.protocol); // maxs
-                       MSG_ReadVector(dir, cls.protocol); // dir
-                       count = (unsigned short) MSG_ReadShort(); // number of particles
-                       colorStart = MSG_ReadByte(); // color
-                       colorLength = MSG_ReadByte(); // gravity (1 or 0)
-                       velspeed = MSG_ReadCoord(cls.protocol); // randomvel
+                       MSG_ReadVector(&cl_message, pos, cls.protocol); // mins
+                       MSG_ReadVector(&cl_message, pos2, cls.protocol); // maxs
+                       MSG_ReadVector(&cl_message, dir, cls.protocol); // dir
+                       count = (unsigned short) MSG_ReadShort(&cl_message); // number of particles
+                       colorStart = MSG_ReadByte(&cl_message); // color
+                       colorLength = MSG_ReadByte(&cl_message); // gravity (1 or 0)
+                       velspeed = MSG_ReadCoord(&cl_message, cls.protocol); // randomvel
                        CL_ParticleCube(pos, pos2, dir, count, colorStart, colorLength != 0, velspeed);
                        break;
 
                case TE_PARTICLERAIN:
                        // general purpose particle effect
-                       MSG_ReadVector(pos, cls.protocol); // mins
-                       MSG_ReadVector(pos2, cls.protocol); // maxs
-                       MSG_ReadVector(dir, cls.protocol); // dir
-                       count = (unsigned short) MSG_ReadShort(); // number of particles
-                       colorStart = MSG_ReadByte(); // color
+                       MSG_ReadVector(&cl_message, pos, cls.protocol); // mins
+                       MSG_ReadVector(&cl_message, pos2, cls.protocol); // maxs
+                       MSG_ReadVector(&cl_message, dir, cls.protocol); // dir
+                       count = (unsigned short) MSG_ReadShort(&cl_message); // number of particles
+                       colorStart = MSG_ReadByte(&cl_message); // color
                        CL_ParticleRain(pos, pos2, dir, count, colorStart, 0);
                        break;
 
                case TE_PARTICLESNOW:
                        // general purpose particle effect
-                       MSG_ReadVector(pos, cls.protocol); // mins
-                       MSG_ReadVector(pos2, cls.protocol); // maxs
-                       MSG_ReadVector(dir, cls.protocol); // dir
-                       count = (unsigned short) MSG_ReadShort(); // number of particles
-                       colorStart = MSG_ReadByte(); // color
+                       MSG_ReadVector(&cl_message, pos, cls.protocol); // mins
+                       MSG_ReadVector(&cl_message, pos2, cls.protocol); // maxs
+                       MSG_ReadVector(&cl_message, dir, cls.protocol); // dir
+                       count = (unsigned short) MSG_ReadShort(&cl_message); // number of particles
+                       colorStart = MSG_ReadByte(&cl_message); // color
                        CL_ParticleRain(pos, pos2, dir, count, colorStart, 1);
                        break;
 
                case TE_GUNSHOT:
                        // bullet hitting wall
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 4);
                        CL_ParticleEffect(EFFECT_TE_GUNSHOT, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        if(cl_sound_ric_gunshot.integer & RIC_GUNSHOT)
@@ -2713,7 +2704,7 @@ void CL_ParseTempEntity(void)
 
                case TE_GUNSHOTQUAD:
                        // quad bullet hitting wall
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 4);
                        CL_ParticleEffect(EFFECT_TE_GUNSHOTQUAD, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        if(cl_sound_ric_gunshot.integer & RIC_GUNSHOTQUAD)
@@ -2735,7 +2726,7 @@ void CL_ParseTempEntity(void)
 
                case TE_EXPLOSION:
                        // rocket explosion
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 10);
                        CL_ParticleEffect(EFFECT_TE_EXPLOSION, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        S_StartSound(-1, 0, cl.sfx_r_exp3, pos, 1, 1);
@@ -2743,7 +2734,7 @@ void CL_ParseTempEntity(void)
 
                case TE_EXPLOSIONQUAD:
                        // quad rocket explosion
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 10);
                        CL_ParticleEffect(EFFECT_TE_EXPLOSIONQUAD, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        S_StartSound(-1, 0, cl.sfx_r_exp3, pos, 1, 1);
@@ -2751,11 +2742,11 @@ void CL_ParseTempEntity(void)
 
                case TE_EXPLOSION3:
                        // Nehahra movie colored lighting explosion
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 10);
-                       color[0] = MSG_ReadCoord(cls.protocol) * (2.0f / 1.0f);
-                       color[1] = MSG_ReadCoord(cls.protocol) * (2.0f / 1.0f);
-                       color[2] = MSG_ReadCoord(cls.protocol) * (2.0f / 1.0f);
+                       color[0] = MSG_ReadCoord(&cl_message, cls.protocol) * (2.0f / 1.0f);
+                       color[1] = MSG_ReadCoord(&cl_message, cls.protocol) * (2.0f / 1.0f);
+                       color[2] = MSG_ReadCoord(&cl_message, cls.protocol) * (2.0f / 1.0f);
                        CL_ParticleExplosion(pos);
                        Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
                        CL_AllocLightFlash(NULL, &tempmatrix, 350, color[0], color[1], color[2], 700, 0.5, 0, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
@@ -2764,12 +2755,12 @@ void CL_ParseTempEntity(void)
 
                case TE_EXPLOSIONRGB:
                        // colored lighting explosion
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 10);
                        CL_ParticleExplosion(pos);
-                       color[0] = MSG_ReadByte() * (2.0f / 255.0f);
-                       color[1] = MSG_ReadByte() * (2.0f / 255.0f);
-                       color[2] = MSG_ReadByte() * (2.0f / 255.0f);
+                       color[0] = MSG_ReadByte(&cl_message) * (2.0f / 255.0f);
+                       color[1] = MSG_ReadByte(&cl_message) * (2.0f / 255.0f);
+                       color[2] = MSG_ReadByte(&cl_message) * (2.0f / 255.0f);
                        Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
                        CL_AllocLightFlash(NULL, &tempmatrix, 350, color[0], color[1], color[2], 700, 0.5, 0, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
                        S_StartSound(-1, 0, cl.sfx_r_exp3, pos, 1, 1);
@@ -2777,34 +2768,34 @@ void CL_ParseTempEntity(void)
 
                case TE_TAREXPLOSION:
                        // tarbaby explosion
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 10);
                        CL_ParticleEffect(EFFECT_TE_TAREXPLOSION, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        S_StartSound(-1, 0, cl.sfx_r_exp3, pos, 1, 1);
                        break;
 
                case TE_SMALLFLASH:
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 10);
                        CL_ParticleEffect(EFFECT_TE_SMALLFLASH, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        break;
 
                case TE_CUSTOMFLASH:
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 4);
-                       radius = (MSG_ReadByte() + 1) * 8;
-                       velspeed = (MSG_ReadByte() + 1) * (1.0 / 256.0);
-                       color[0] = MSG_ReadByte() * (2.0f / 255.0f);
-                       color[1] = MSG_ReadByte() * (2.0f / 255.0f);
-                       color[2] = MSG_ReadByte() * (2.0f / 255.0f);
+                       radius = (MSG_ReadByte(&cl_message) + 1) * 8;
+                       velspeed = (MSG_ReadByte(&cl_message) + 1) * (1.0 / 256.0);
+                       color[0] = MSG_ReadByte(&cl_message) * (2.0f / 255.0f);
+                       color[1] = MSG_ReadByte(&cl_message) * (2.0f / 255.0f);
+                       color[2] = MSG_ReadByte(&cl_message) * (2.0f / 255.0f);
                        Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
                        CL_AllocLightFlash(NULL, &tempmatrix, radius, color[0], color[1], color[2], radius / velspeed, velspeed, 0, -1, true, 1, 0.25, 1, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
                        break;
 
                case TE_FLAMEJET:
-                       MSG_ReadVector(pos, cls.protocol);
-                       MSG_ReadVector(dir, cls.protocol);
-                       count = MSG_ReadByte();
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, dir, cls.protocol);
+                       count = MSG_ReadByte(&cl_message);
                        CL_ParticleEffect(EFFECT_TE_FLAMEJET, count, pos, pos, dir, dir, NULL, 0);
                        break;
 
@@ -2832,25 +2823,25 @@ void CL_ParseTempEntity(void)
 
        // LordHavoc: for compatibility with the Nehahra movie...
                case TE_LIGHTNING4NEH:
-                       CL_ParseBeam(Mod_ForName(MSG_ReadString(), true, false, NULL), false);
+                       CL_ParseBeam(Mod_ForName(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), true, false, NULL), false);
                        break;
 
                case TE_LAVASPLASH:
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_ParticleEffect(EFFECT_TE_LAVASPLASH, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        break;
 
                case TE_TELEPORT:
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_ParticleEffect(EFFECT_TE_TELEPORT, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        break;
 
                case TE_EXPLOSION2:
                        // color mapped explosion
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 10);
-                       colorStart = MSG_ReadByte();
-                       colorLength = MSG_ReadByte();
+                       colorStart = MSG_ReadByte(&cl_message);
+                       colorLength = MSG_ReadByte(&cl_message);
                        CL_ParticleExplosion2(pos, colorStart, colorLength);
                        tempcolor = palette_rgb[(rand()%colorLength) + colorStart];
                        color[0] = tempcolor[0] * (2.0f / 255.0f);
@@ -2862,31 +2853,31 @@ void CL_ParseTempEntity(void)
                        break;
 
                case TE_TEI_G3:
-                       MSG_ReadVector(pos, cls.protocol);
-                       MSG_ReadVector(pos2, cls.protocol);
-                       MSG_ReadVector(dir, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos2, cls.protocol);
+                       MSG_ReadVector(&cl_message, dir, cls.protocol);
                        CL_ParticleEffect(EFFECT_TE_TEI_G3, 1, pos, pos2, dir, dir, NULL, 0);
                        break;
 
                case TE_TEI_SMOKE:
-                       MSG_ReadVector(pos, cls.protocol);
-                       MSG_ReadVector(dir, cls.protocol);
-                       count = MSG_ReadByte();
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, dir, cls.protocol);
+                       count = MSG_ReadByte(&cl_message);
                        CL_FindNonSolidLocation(pos, pos, 4);
                        CL_ParticleEffect(EFFECT_TE_TEI_SMOKE, count, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        break;
 
                case TE_TEI_BIGEXPLOSION:
-                       MSG_ReadVector(pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
                        CL_FindNonSolidLocation(pos, pos, 10);
                        CL_ParticleEffect(EFFECT_TE_TEI_BIGEXPLOSION, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        S_StartSound(-1, 0, cl.sfx_r_exp3, pos, 1, 1);
                        break;
 
                case TE_TEI_PLASMAHIT:
-                       MSG_ReadVector(pos, cls.protocol);
-                       MSG_ReadVector(dir, cls.protocol);
-                       count = MSG_ReadByte();
+                       MSG_ReadVector(&cl_message, pos, cls.protocol);
+                       MSG_ReadVector(&cl_message, dir, cls.protocol);
+                       count = MSG_ReadByte(&cl_message);
                        CL_FindNonSolidLocation(pos, pos, 5);
                        CL_ParticleEffect(EFFECT_TE_TEI_PLASMAHIT, count, pos, pos, vec3_origin, vec3_origin, NULL, 0);
                        break;
@@ -2897,39 +2888,39 @@ void CL_ParseTempEntity(void)
        }
 }
 
-void CL_ParseTrailParticles(void)
+static void CL_ParseTrailParticles(void)
 {
        int entityindex;
        int effectindex;
        vec3_t start, end;
-       entityindex = (unsigned short)MSG_ReadShort();
+       entityindex = (unsigned short)MSG_ReadShort(&cl_message);
        if (entityindex >= MAX_EDICTS)
                entityindex = 0;
        if (entityindex >= cl.max_entities)
                CL_ExpandEntities(entityindex);
-       effectindex = (unsigned short)MSG_ReadShort();
-       MSG_ReadVector(start, cls.protocol);
-       MSG_ReadVector(end, cls.protocol);
+       effectindex = (unsigned short)MSG_ReadShort(&cl_message);
+       MSG_ReadVector(&cl_message, start, cls.protocol);
+       MSG_ReadVector(&cl_message, end, cls.protocol);
        CL_ParticleEffect(effectindex, 1, start, end, vec3_origin, vec3_origin, entityindex > 0 ? cl.entities + entityindex : NULL, 0);
 }
 
-void CL_ParsePointParticles(void)
+static void CL_ParsePointParticles(void)
 {
        int effectindex, count;
        vec3_t origin, velocity;
-       effectindex = (unsigned short)MSG_ReadShort();
-       MSG_ReadVector(origin, cls.protocol);
-       MSG_ReadVector(velocity, cls.protocol);
-       count = (unsigned short)MSG_ReadShort();
+       effectindex = (unsigned short)MSG_ReadShort(&cl_message);
+       MSG_ReadVector(&cl_message, origin, cls.protocol);
+       MSG_ReadVector(&cl_message, velocity, cls.protocol);
+       count = (unsigned short)MSG_ReadShort(&cl_message);
        CL_ParticleEffect(effectindex, count, origin, origin, velocity, velocity, NULL, 0);
 }
 
-void CL_ParsePointParticles1(void)
+static void CL_ParsePointParticles1(void)
 {
        int effectindex;
        vec3_t origin;
-       effectindex = (unsigned short)MSG_ReadShort();
-       MSG_ReadVector(origin, cls.protocol);
+       effectindex = (unsigned short)MSG_ReadShort(&cl_message);
+       MSG_ReadVector(&cl_message, origin, cls.protocol);
        CL_ParticleEffect(effectindex, 1, origin, origin, vec3_origin, vec3_origin, NULL, 0);
 }
 
@@ -3083,7 +3074,7 @@ static void CL_IPLog_List_f(void)
 }
 
 // look for anything interesting like player IP addresses or ping reports
-qboolean CL_ExaminePrintString(const char *text)
+static qboolean CL_ExaminePrintString(const char *text)
 {
        int len;
        const char *t;
@@ -3228,7 +3219,6 @@ qboolean CL_ExaminePrintString(const char *text)
 
 extern cvar_t slowmo;
 extern cvar_t cl_lerpexcess;
-extern void CSQC_UpdateNetworkTimes(double newtime, double oldtime);
 static void CL_NetworkTimeReceived(double newtime)
 {
        double timehigh;
@@ -3327,14 +3317,7 @@ static void CL_NetworkTimeReceived(double newtime)
        }
 }
 
-#define SHOWNET(x) if(cl_shownet.integer==2)Con_Printf("%3i:%s(%i)\n", msg_readcount-1, x, cmd);
-
-//[515]: csqc
-qboolean CL_VM_Parse_TempEntity (void);
-void CL_VM_Parse_StuffCmd (const char *msg);
-void CL_VM_Parse_CenterPrint (const char *msg);
-void CSQC_AddPrintText (const char *msg);
-void CSQC_ReadEntities (void);
+#define SHOWNET(x) if(cl_shownet.integer==2)Con_Printf("%3i:%s(%i)\n", cl_message.readcount-1, x, cmd);
 
 /*
 =====================
@@ -3342,7 +3325,6 @@ CL_ParseServerMessage
 =====================
 */
 int parsingerror = false;
-extern void CL_UpdateMoveVars(void);
 void CL_ParseServerMessage(void)
 {
        int                     cmd;
@@ -3353,12 +3335,13 @@ void CL_ParseServerMessage(void)
        int                     cmdindex, cmdcount = 0;
        qboolean        qwplayerupdatereceived;
        qboolean        strip_pqc;
+       char vabuf[1024];
 
        // LordHavoc: moved demo message writing from before the packet parse to
        // after the packet parse so that CL_Stop_f can be called by cl_autodemo
        // code in CL_ParseServerinfo
        //if (cls.demorecording)
-       //      CL_WriteDemoMessage (&net_message);
+       //      CL_WriteDemoMessage (&cl_message);
 
        cl.last_received_message = realtime;
 
@@ -3368,7 +3351,7 @@ void CL_ParseServerMessage(void)
 // if recording demos, copy the message out
 //
        if (cl_shownet.integer == 1)
-               Con_Printf("%f %i\n", realtime, net_message.cursize);
+               Con_Printf("%f %i\n", realtime, cl_message.cursize);
        else if (cl_shownet.integer == 2)
                Con_Print("------------------\n");
 
@@ -3395,10 +3378,10 @@ void CL_ParseServerMessage(void)
 
                while (1)
                {
-                       if (msg_badread)
+                       if (cl_message.badread)
                                Host_Error ("CL_ParseServerMessage: Bad QW server message");
 
-                       cmd = MSG_ReadByte ();
+                       cmd = MSG_ReadByte(&cl_message);
 
                        if (cmd == -1)
                        {
@@ -3459,23 +3442,23 @@ void CL_ParseServerMessage(void)
                                return;
 
                        case qw_svc_print:
-                               i = MSG_ReadByte();
-                               temp = MSG_ReadString();
+                               i = MSG_ReadByte(&cl_message);
+                               temp = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
                                if (CL_ExaminePrintString(temp)) // look for anything interesting like player IP addresses or ping reports
                                {
                                        if (i == 3) // chat
-                                               CSQC_AddPrintText(va("\1%s", temp));    //[515]: csqc
+                                               CSQC_AddPrintText(va(vabuf, sizeof(vabuf), "\1%s", temp));      //[515]: csqc
                                        else
                                                CSQC_AddPrintText(temp);
                                }
                                break;
 
                        case qw_svc_centerprint:
-                               CL_VM_Parse_CenterPrint(MSG_ReadString ());     //[515]: csqc
+                               CL_VM_Parse_CenterPrint(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)));     //[515]: csqc
                                break;
 
                        case qw_svc_stufftext:
-                               CL_VM_Parse_StuffCmd(MSG_ReadString ());        //[515]: csqc
+                               CL_VM_Parse_StuffCmd(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)));        //[515]: csqc
                                break;
 
                        case qw_svc_damage:
@@ -3490,7 +3473,7 @@ void CL_ParseServerMessage(void)
 
                        case qw_svc_setangle:
                                for (i=0 ; i<3 ; i++)
-                                       cl.viewangles[i] = MSG_ReadAngle (cls.protocol);
+                                       cl.viewangles[i] = MSG_ReadAngle(&cl_message, cls.protocol);
                                if (!cls.demoplayback)
                                {
                                        cl.fixangle[0] = true;
@@ -3502,13 +3485,13 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case qw_svc_lightstyle:
-                               i = MSG_ReadByte ();
+                               i = MSG_ReadByte(&cl_message);
                                if (i >= cl.max_lightstyle)
                                {
                                        Con_Printf ("svc_lightstyle >= MAX_LIGHTSTYLES");
                                        break;
                                }
-                               strlcpy (cl.lightstyle[i].map,  MSG_ReadString(), sizeof (cl.lightstyle[i].map));
+                               strlcpy (cl.lightstyle[i].map,  MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof (cl.lightstyle[i].map));
                                cl.lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
                                cl.lightstyle[i].length = (int)strlen(cl.lightstyle[i].map);
                                break;
@@ -3518,41 +3501,41 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case qw_svc_stopsound:
-                               i = (unsigned short) MSG_ReadShort();
+                               i = (unsigned short) MSG_ReadShort(&cl_message);
                                S_StopSound(i>>3, i&7);
                                break;
 
                        case qw_svc_updatefrags:
-                               i = MSG_ReadByte();
+                               i = MSG_ReadByte(&cl_message);
                                if (i >= cl.maxclients)
                                        Host_Error("CL_ParseServerMessage: svc_updatefrags >= cl.maxclients");
-                               cl.scores[i].frags = (signed short) MSG_ReadShort();
+                               cl.scores[i].frags = (signed short) MSG_ReadShort(&cl_message);
                                break;
 
                        case qw_svc_updateping:
-                               i = MSG_ReadByte();
+                               i = MSG_ReadByte(&cl_message);
                                if (i >= cl.maxclients)
                                        Host_Error("CL_ParseServerMessage: svc_updateping >= cl.maxclients");
-                               cl.scores[i].qw_ping = MSG_ReadShort();
+                               cl.scores[i].qw_ping = MSG_ReadShort(&cl_message);
                                break;
 
                        case qw_svc_updatepl:
-                               i = MSG_ReadByte();
+                               i = MSG_ReadByte(&cl_message);
                                if (i >= cl.maxclients)
                                        Host_Error("CL_ParseServerMessage: svc_updatepl >= cl.maxclients");
-                               cl.scores[i].qw_packetloss = MSG_ReadByte();
+                               cl.scores[i].qw_packetloss = MSG_ReadByte(&cl_message);
                                break;
 
                        case qw_svc_updateentertime:
-                               i = MSG_ReadByte();
+                               i = MSG_ReadByte(&cl_message);
                                if (i >= cl.maxclients)
                                        Host_Error("CL_ParseServerMessage: svc_updateentertime >= cl.maxclients");
                                // seconds ago
-                               cl.scores[i].qw_entertime = cl.time - MSG_ReadFloat();
+                               cl.scores[i].qw_entertime = cl.time - MSG_ReadFloat(&cl_message);
                                break;
 
                        case qw_svc_spawnbaseline:
-                               i = (unsigned short) MSG_ReadShort();
+                               i = (unsigned short) MSG_ReadShort(&cl_message);
                                if (i < 0 || i >= MAX_EDICTS)
                                        Host_Error ("CL_ParseServerMessage: svc_spawnbaseline: invalid entity number %i", i);
                                if (i >= cl.max_entities)
@@ -3576,17 +3559,17 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case qw_svc_updatestat:
-                               i = MSG_ReadByte ();
+                               i = MSG_ReadByte(&cl_message);
                                if (i < 0 || i >= MAX_CL_STATS)
                                        Host_Error ("svc_updatestat: %i is invalid", i);
-                               cl.stats[i] = MSG_ReadByte ();
+                               cl.stats[i] = MSG_ReadByte(&cl_message);
                                break;
 
                        case qw_svc_updatestatlong:
-                               i = MSG_ReadByte ();
+                               i = MSG_ReadByte(&cl_message);
                                if (i < 0 || i >= MAX_CL_STATS)
                                        Host_Error ("svc_updatestatlong: %i is invalid", i);
-                               cl.stats[i] = MSG_ReadLong ();
+                               cl.stats[i] = MSG_ReadLong(&cl_message);
                                break;
 
                        case qw_svc_spawnstaticsound:
@@ -3594,7 +3577,7 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case qw_svc_cdtrack:
-                               cl.cdtrack = cl.looptrack = MSG_ReadByte ();
+                               cl.cdtrack = cl.looptrack = MSG_ReadByte(&cl_message);
                                if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
                                        CDAudio_Play ((unsigned char)cls.forcetrack, true);
                                else
@@ -3605,16 +3588,16 @@ void CL_ParseServerMessage(void)
                                if(!cl.intermission)
                                        cl.completed_time = cl.time;
                                cl.intermission = 1;
-                               MSG_ReadVector(cl.qw_intermission_origin, cls.protocol);
+                               MSG_ReadVector(&cl_message, cl.qw_intermission_origin, cls.protocol);
                                for (i = 0;i < 3;i++)
-                                       cl.qw_intermission_angles[i] = MSG_ReadAngle(cls.protocol);
+                                       cl.qw_intermission_angles[i] = MSG_ReadAngle(&cl_message, cls.protocol);
                                break;
 
                        case qw_svc_finale:
                                if(!cl.intermission)
                                        cl.completed_time = cl.time;
                                cl.intermission = 2;
-                               SCR_CenterPrint(MSG_ReadString ());
+                               SCR_CenterPrint(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)));
                                break;
 
                        case qw_svc_sellscreen:
@@ -3629,7 +3612,7 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case qw_svc_muzzleflash:
-                               i = (unsigned short) MSG_ReadShort();
+                               i = (unsigned short) MSG_ReadShort(&cl_message);
                                // NOTE: in QW this only worked on clients
                                if (i < 0 || i >= MAX_EDICTS)
                                        Host_Error("CL_ParseServerMessage: svc_spawnbaseline: invalid entity number %i", i);
@@ -3671,7 +3654,7 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case qw_svc_chokecount:
-                               i = MSG_ReadByte();
+                               i = MSG_ReadByte(&cl_message);
                                // FIXME: apply to netgraph
                                //for (j = 0;j < i;j++)
                                //      cl.frames[(cls.netcon->qw.incoming_acknowledged-1-j)&QW_UPDATE_MASK].receivedtime = -2;
@@ -3706,17 +3689,17 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case qw_svc_maxspeed:
-                               cl.movevars_maxspeed = MSG_ReadFloat();
+                               cl.movevars_maxspeed = MSG_ReadFloat(&cl_message);
                                break;
 
                        case qw_svc_entgravity:
-                               cl.movevars_entgravity = MSG_ReadFloat();
+                               cl.movevars_entgravity = MSG_ReadFloat(&cl_message);
                                if (!cl.movevars_entgravity)
                                        cl.movevars_entgravity = 1.0f;
                                break;
 
                        case qw_svc_setpause:
-                               cl.paused = MSG_ReadByte () != 0;
+                               cl.paused = MSG_ReadByte(&cl_message) != 0;
                                if (cl.paused)
                                        CDAudio_Pause ();
                                else
@@ -3738,10 +3721,10 @@ void CL_ParseServerMessage(void)
        {
                while (1)
                {
-                       if (msg_badread)
+                       if (cl_message.badread)
                                Host_Error ("CL_ParseServerMessage: Bad server message");
 
-                       cmd = MSG_ReadByte ();
+                       cmd = MSG_ReadByte(&cl_message);
 
                        if (cmd == -1)
                        {
@@ -3813,7 +3796,7 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case svc_time:
-                               CL_NetworkTimeReceived(MSG_ReadFloat());
+                               CL_NetworkTimeReceived(MSG_ReadFloat(&cl_message));
                                break;
 
                        case svc_clientdata:
@@ -3821,7 +3804,7 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case svc_version:
-                               i = MSG_ReadLong ();
+                               i = MSG_ReadLong(&cl_message);
                                protocol = Protocol_EnumForNumber(i);
                                if (protocol == PROTOCOL_UNKNOWN)
                                        Host_Error("CL_ParseServerMessage: Server is unrecognized protocol number (%i)", i);
@@ -3840,17 +3823,17 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case svc_print:
-                               temp = MSG_ReadString();
+                               temp = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
                                if (CL_ExaminePrintString(temp)) // look for anything interesting like player IP addresses or ping reports
                                        CSQC_AddPrintText(temp);        //[515]: csqc
                                break;
 
                        case svc_centerprint:
-                               CL_VM_Parse_CenterPrint(MSG_ReadString ());     //[515]: csqc
+                               CL_VM_Parse_CenterPrint(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)));     //[515]: csqc
                                break;
 
                        case svc_stufftext:
-                               temp = MSG_ReadString();
+                               temp = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
                                /* if(utf8_enable.integer)
                                {
                                        strip_pqc = true;
@@ -3898,7 +3881,7 @@ void CL_ParseServerMessage(void)
 
                        case svc_setangle:
                                for (i=0 ; i<3 ; i++)
-                                       cl.viewangles[i] = MSG_ReadAngle (cls.protocol);
+                                       cl.viewangles[i] = MSG_ReadAngle(&cl_message, cls.protocol);
                                if (!cls.demoplayback)
                                {
                                        cl.fixangle[0] = true;
@@ -3910,7 +3893,7 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case svc_setview:
-                               cl.viewentity = (unsigned short)MSG_ReadShort ();
+                               cl.viewentity = (unsigned short)MSG_ReadShort(&cl_message);
                                if (cl.viewentity >= MAX_EDICTS)
                                        Host_Error("svc_setview >= MAX_EDICTS");
                                if (cl.viewentity >= cl.max_entities)
@@ -3924,13 +3907,13 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case svc_lightstyle:
-                               i = MSG_ReadByte ();
+                               i = MSG_ReadByte(&cl_message);
                                if (i >= cl.max_lightstyle)
                                {
                                        Con_Printf ("svc_lightstyle >= MAX_LIGHTSTYLES");
                                        break;
                                }
-                               strlcpy (cl.lightstyle[i].map,  MSG_ReadString(), sizeof (cl.lightstyle[i].map));
+                               strlcpy (cl.lightstyle[i].map,  MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof (cl.lightstyle[i].map));
                                cl.lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
                                cl.lightstyle[i].length = (int)strlen(cl.lightstyle[i].map);
                                break;
@@ -3947,8 +3930,8 @@ void CL_ParseServerMessage(void)
                                }
                                else
                                {
-                                       int i = (unsigned short)MSG_ReadShort();
-                                       char *s = MSG_ReadString();
+                                       int i = (unsigned short)MSG_ReadShort(&cl_message);
+                                       char *s = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
                                        if (i < 32768)
                                        {
                                                if (i >= 1 && i < MAX_MODELS)
@@ -3978,29 +3961,29 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case svc_stopsound:
-                               i = (unsigned short) MSG_ReadShort();
+                               i = (unsigned short) MSG_ReadShort(&cl_message);
                                S_StopSound(i>>3, i&7);
                                break;
 
                        case svc_updatename:
-                               i = MSG_ReadByte ();
+                               i = MSG_ReadByte(&cl_message);
                                if (i >= cl.maxclients)
                                        Host_Error ("CL_ParseServerMessage: svc_updatename >= cl.maxclients");
-                               strlcpy (cl.scores[i].name, MSG_ReadString (), sizeof (cl.scores[i].name));
+                               strlcpy (cl.scores[i].name, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof (cl.scores[i].name));
                                break;
 
                        case svc_updatefrags:
-                               i = MSG_ReadByte ();
+                               i = MSG_ReadByte(&cl_message);
                                if (i >= cl.maxclients)
                                        Host_Error ("CL_ParseServerMessage: svc_updatefrags >= cl.maxclients");
-                               cl.scores[i].frags = (signed short) MSG_ReadShort ();
+                               cl.scores[i].frags = (signed short) MSG_ReadShort(&cl_message);
                                break;
 
                        case svc_updatecolors:
-                               i = MSG_ReadByte ();
+                               i = MSG_ReadByte(&cl_message);
                                if (i >= cl.maxclients)
                                        Host_Error ("CL_ParseServerMessage: svc_updatecolors >= cl.maxclients");
-                               cl.scores[i].colors = MSG_ReadByte ();
+                               cl.scores[i].colors = MSG_ReadByte(&cl_message);
                                break;
 
                        case svc_particle:
@@ -4016,7 +3999,7 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case svc_spawnbaseline:
-                               i = (unsigned short) MSG_ReadShort ();
+                               i = (unsigned short) MSG_ReadShort(&cl_message);
                                if (i < 0 || i >= MAX_EDICTS)
                                        Host_Error ("CL_ParseServerMessage: svc_spawnbaseline: invalid entity number %i", i);
                                if (i >= cl.max_entities)
@@ -4024,7 +4007,7 @@ void CL_ParseServerMessage(void)
                                CL_ParseBaseline (cl.entities + i, false);
                                break;
                        case svc_spawnbaseline2:
-                               i = (unsigned short) MSG_ReadShort ();
+                               i = (unsigned short) MSG_ReadShort(&cl_message);
                                if (i < 0 || i >= MAX_EDICTS)
                                        Host_Error ("CL_ParseServerMessage: svc_spawnbaseline2: invalid entity number %i", i);
                                if (i >= cl.max_entities)
@@ -4043,7 +4026,7 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case svc_setpause:
-                               cl.paused = MSG_ReadByte () != 0;
+                               cl.paused = MSG_ReadByte(&cl_message) != 0;
                                if (cl.paused)
                                        CDAudio_Pause ();
                                else
@@ -4052,7 +4035,7 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case svc_signonnum:
-                               i = MSG_ReadByte ();
+                               i = MSG_ReadByte(&cl_message);
                                // LordHavoc: it's rude to kick off the client if they missed the
                                // reconnect somehow, so allow signon 1 even if at signon 1
                                if (i <= cls.signon && i != 1)
@@ -4070,17 +4053,17 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case svc_updatestat:
-                               i = MSG_ReadByte ();
+                               i = MSG_ReadByte(&cl_message);
                                if (i < 0 || i >= MAX_CL_STATS)
                                        Host_Error ("svc_updatestat: %i is invalid", i);
-                               cl.stats[i] = MSG_ReadLong ();
+                               cl.stats[i] = MSG_ReadLong(&cl_message);
                                break;
 
                        case svc_updatestatubyte:
-                               i = MSG_ReadByte ();
+                               i = MSG_ReadByte(&cl_message);
                                if (i < 0 || i >= MAX_CL_STATS)
                                        Host_Error ("svc_updatestat: %i is invalid", i);
-                               cl.stats[i] = MSG_ReadByte ();
+                               cl.stats[i] = MSG_ReadByte(&cl_message);
                                break;
 
                        case svc_spawnstaticsound:
@@ -4092,8 +4075,8 @@ void CL_ParseServerMessage(void)
                                break;
 
                        case svc_cdtrack:
-                               cl.cdtrack = MSG_ReadByte ();
-                               cl.looptrack = MSG_ReadByte ();
+                               cl.cdtrack = MSG_ReadByte(&cl_message);
+                               cl.looptrack = MSG_ReadByte(&cl_message);
                                if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
                                        CDAudio_Play ((unsigned char)cls.forcetrack, true);
                                else
@@ -4112,7 +4095,7 @@ void CL_ParseServerMessage(void)
                                        cl.completed_time = cl.time;
                                cl.intermission = 2;
                                CL_VM_UpdateIntermissionState(cl.intermission);
-                               SCR_CenterPrint(MSG_ReadString ());
+                               SCR_CenterPrint(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)));
                                break;
 
                        case svc_cutscene:
@@ -4120,7 +4103,7 @@ void CL_ParseServerMessage(void)
                                        cl.completed_time = cl.time;
                                cl.intermission = 3;
                                CL_VM_UpdateIntermissionState(cl.intermission);
-                               SCR_CenterPrint(MSG_ReadString ());
+                               SCR_CenterPrint(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)));
                                break;
 
                        case svc_sellscreen:
@@ -4130,16 +4113,16 @@ void CL_ParseServerMessage(void)
                                if (gamemode == GAME_TENEBRAE)
                                {
                                        // repeating particle effect
-                                       MSG_ReadCoord(cls.protocol);
-                                       MSG_ReadCoord(cls.protocol);
-                                       MSG_ReadCoord(cls.protocol);
-                                       MSG_ReadCoord(cls.protocol);
-                                       MSG_ReadCoord(cls.protocol);
-                                       MSG_ReadCoord(cls.protocol);
-                                       (void) MSG_ReadByte();
-                                       MSG_ReadLong();
-                                       MSG_ReadLong();
-                                       MSG_ReadString();
+                                       MSG_ReadCoord(&cl_message, cls.protocol);
+                                       MSG_ReadCoord(&cl_message, cls.protocol);
+                                       MSG_ReadCoord(&cl_message, cls.protocol);
+                                       MSG_ReadCoord(&cl_message, cls.protocol);
+                                       MSG_ReadCoord(&cl_message, cls.protocol);
+                                       MSG_ReadCoord(&cl_message, cls.protocol);
+                                       (void) MSG_ReadByte(&cl_message);
+                                       MSG_ReadLong(&cl_message);
+                                       MSG_ReadLong(&cl_message);
+                                       MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
                                }
                                else
                                        SHOWLMP_decodehide();
@@ -4148,17 +4131,17 @@ void CL_ParseServerMessage(void)
                                if (gamemode == GAME_TENEBRAE)
                                {
                                        // particle effect
-                                       MSG_ReadCoord(cls.protocol);
-                                       MSG_ReadCoord(cls.protocol);
-                                       MSG_ReadCoord(cls.protocol);
-                                       (void) MSG_ReadByte();
-                                       MSG_ReadString();
+                                       MSG_ReadCoord(&cl_message, cls.protocol);
+                                       MSG_ReadCoord(&cl_message, cls.protocol);
+                                       MSG_ReadCoord(&cl_message, cls.protocol);
+                                       (void) MSG_ReadByte(&cl_message);
+                                       MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
                                }
                                else
                                        SHOWLMP_decodeshow();
                                break;
                        case svc_skybox:
-                               R_SetSkyBox(MSG_ReadString());
+                               R_SetSkyBox(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)));
                                break;
                        case svc_entities:
                                if (cls.signon == SIGNONS - 1)
@@ -4210,7 +4193,7 @@ void CL_ParseServerMessage(void)
        // implemented
        if (cls.demorecording)
        {
-               CL_WriteDemoMessage (&net_message);
+               CL_WriteDemoMessage (&cl_message);
 //             R_TimeReport("WriteDemo");
        }
 }
@@ -4220,7 +4203,7 @@ void CL_Parse_DumpPacket(void)
        if (!parsingerror)
                return;
        Con_Print("Packet dump:\n");
-       SZ_HexDumpToConsole(&net_message);
+       SZ_HexDumpToConsole(&cl_message);
        parsingerror = false;
 }
 
index 3bf86bd2ead0d335965ccab46eb04b384ded04f9..70e1b2924a90a0201f9329efaa7b2606e2be3f42 100644 (file)
@@ -302,7 +302,7 @@ cvar_t cl_decals_bias = {CVAR_SAVE, "cl_decals_bias", "0.125", "distance to bias
 cvar_t cl_decals_max = {CVAR_SAVE, "cl_decals_max", "4096", "maximum number of decals allowed to exist in the world at once"};
 
 
-void CL_Particles_ParseEffectInfo(const char *textstart, const char *textend, const char *filename)
+static void CL_Particles_ParseEffectInfo(const char *textstart, const char *textend, const char *filename)
 {
        int arrayindex;
        int argc;
@@ -509,7 +509,7 @@ static const char *standardeffectnames[EFFECT_TOTAL] =
        "SVC_PARTICLE"
 };
 
-void CL_Particles_LoadEffectInfo(void)
+static void CL_Particles_LoadEffectInfo(void)
 {
        int i;
        int filepass;
@@ -891,7 +891,7 @@ void CL_SpawnDecalParticleForPoint(const vec3_t org, float maxdist, float size,
 
 static void CL_Sparks(const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, float sparkcount);
 static void CL_Smoke(const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, float smokecount);
-void CL_ParticleEffect_Fallback(int effectnameindex, float count, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qboolean spawndlight, qboolean spawnparticles)
+static void CL_ParticleEffect_Fallback(int effectnameindex, float count, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qboolean spawndlight, qboolean spawnparticles)
 {
        vec3_t center;
        matrix4x4_t tempmatrix;
@@ -1417,6 +1417,7 @@ void CL_ParticleEffect_Fallback(int effectnameindex, float count, const vec3_t o
 void CL_ParticleTrail(int effectnameindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qboolean spawndlight, qboolean spawnparticles, float tintmins[4], float tintmaxs[4])
 {
        qboolean found = false;
+       char vabuf[1024];
        if (effectnameindex < 1 || effectnameindex >= MAX_PARTICLEEFFECTNAME || !particleeffectname[effectnameindex][0])
        {
                Con_DPrintf("Unknown effect number %i received from server\n", effectnameindex);
@@ -1485,7 +1486,7 @@ void CL_ParticleTrail(int effectnameindex, float pcount, const vec3_t originmins
                                                rvec[0] = info->lightcolor[0]*avgtint[0]*avgtint[3];
                                                rvec[1] = info->lightcolor[1]*avgtint[1]*avgtint[3];
                                                rvec[2] = info->lightcolor[2]*avgtint[2]*avgtint[3];
-                                               R_RTLight_Update(&r_refdef.scene.templights[r_refdef.scene.numlights], false, &tempmatrix, rvec, -1, info->lightcubemapnum > 0 ? va("cubemaps/%i", info->lightcubemapnum) : NULL, info->lightshadow, 1, 0.25, 0, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
+                                               R_RTLight_Update(&r_refdef.scene.templights[r_refdef.scene.numlights], false, &tempmatrix, rvec, -1, info->lightcubemapnum > 0 ? va(vabuf, sizeof(vabuf), "cubemaps/%i", info->lightcubemapnum) : NULL, info->lightshadow, 1, 0.25, 0, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
                                                r_refdef.scene.lights[r_refdef.scene.numlights] = &r_refdef.scene.templights[r_refdef.scene.numlights];r_refdef.scene.numlights++;
                                        }
                                }
@@ -1687,11 +1688,11 @@ void CL_ParseParticleEffect (void)
        vec3_t org, dir;
        int i, count, msgcount, color;
 
-       MSG_ReadVector(org, cls.protocol);
+       MSG_ReadVector(&cl_message, org, cls.protocol);
        for (i=0 ; i<3 ; i++)
-               dir[i] = MSG_ReadChar () * (1.0 / 16.0);
-       msgcount = MSG_ReadByte ();
-       color = MSG_ReadByte ();
+               dir[i] = MSG_ReadChar(&cl_message) * (1.0 / 16.0);
+       msgcount = MSG_ReadByte(&cl_message);
+       color = MSG_ReadByte(&cl_message);
 
        if (msgcount == 255)
                count = 1024;
@@ -1930,7 +1931,7 @@ static unsigned char shadebubble(float dx, float dy, vec3_t light)
 }
 
 int particlefontwidth, particlefontheight, particlefontcellwidth, particlefontcellheight, particlefontrows, particlefontcols;
-void CL_Particle_PixelCoordsForTexnum(int texnum, int *basex, int *basey, int *width, int *height)
+static void CL_Particle_PixelCoordsForTexnum(int texnum, int *basex, int *basey, int *width, int *height)
 {
        *basex = (texnum % particlefontcols) * particlefontcellwidth;
        *basey = ((texnum / particlefontcols) % particlefontrows) * particlefontcellheight;
@@ -1948,7 +1949,7 @@ static void setuptex(int texnum, unsigned char *data, unsigned char *particletex
                memcpy(particletexturedata + ((basey + y) * PARTICLEFONTSIZE + basex) * 4, data + y * PARTICLETEXTURESIZE * 4, PARTICLETEXTURESIZE * 4);
 }
 
-void particletextureblotch(unsigned char *data, float radius, float red, float green, float blue, float alpha)
+static void particletextureblotch(unsigned char *data, float radius, float red, float green, float blue, float alpha)
 {
        int x, y;
        float cx, cy, dx, dy, f, iradius;
@@ -1977,7 +1978,8 @@ void particletextureblotch(unsigned char *data, float radius, float red, float g
        }
 }
 
-void particletextureclamp(unsigned char *data, int minr, int ming, int minb, int maxr, int maxg, int maxb)
+#if 0
+static void particletextureclamp(unsigned char *data, int minr, int ming, int minb, int maxr, int maxg, int maxb)
 {
        int i;
        for (i = 0;i < PARTICLETEXTURESIZE*PARTICLETEXTURESIZE;i++, data += 4)
@@ -1987,8 +1989,9 @@ void particletextureclamp(unsigned char *data, int minr, int ming, int minb, int
                data[2] = bound(minr, data[2], maxr);
        }
 }
+#endif
 
-void particletextureinvert(unsigned char *data)
+static void particletextureinvert(unsigned char *data)
 {
        int i;
        for (i = 0;i < PARTICLETEXTURESIZE*PARTICLETEXTURESIZE;i++, data += 4)
@@ -2368,7 +2371,7 @@ void R_Particles_Init (void)
        R_RegisterModule("R_Particles", r_part_start, r_part_shutdown, r_part_newmap, NULL, NULL);
 }
 
-void R_DrawDecal_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
+static void R_DrawDecal_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
 {
        int surfacelistindex;
        const decal_t *d;
@@ -2519,7 +2522,7 @@ killdecal:
        r_refdef.stats.totaldecals = cl.num_decals;
 }
 
-void R_DrawParticle_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
+static void R_DrawParticle_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
 {
        int surfacelistindex;
        int batchstart, batchcount;
index bf3749ae2494c1c05d6abec7d2df709e98dfa521..2c62af0ca892da53bf88da37c0802da433b678d3 100644 (file)
@@ -143,7 +143,7 @@ void SCR_CenterPrint(const char *str)
 }
 
 
-void SCR_DrawCenterString (void)
+static void SCR_DrawCenterString (void)
 {
        char    *start;
        int             x, y;
@@ -200,7 +200,7 @@ void SCR_DrawCenterString (void)
        } while (1);
 }
 
-void SCR_CheckDrawCenterString (void)
+static void SCR_CheckDrawCenterString (void)
 {
        if (scr_center_lines > scr_erase_lines)
                scr_erase_lines = scr_center_lines;
@@ -220,7 +220,7 @@ void SCR_CheckDrawCenterString (void)
        SCR_DrawCenterString ();
 }
 
-void SCR_DrawNetGraph_DrawGraph (int graphx, int graphy, int graphwidth, int graphheight, float graphscale, const char *label, float textsize, int packetcounter, netgraphitem_t *netgraph)
+static void SCR_DrawNetGraph_DrawGraph (int graphx, int graphy, int graphwidth, int graphheight, float graphscale, const char *label, float textsize, int packetcounter, netgraphitem_t *netgraph)
 {
        netgraphitem_t *graph;
        int j, x, y, numlines;
@@ -308,11 +308,12 @@ void SCR_DrawNetGraph_DrawGraph (int graphx, int graphy, int graphwidth, int gra
 SCR_DrawNetGraph
 ==============
 */
-void SCR_DrawNetGraph (void)
+static void SCR_DrawNetGraph (void)
 {
        int i, separator1, separator2, graphwidth, graphheight, netgraph_x, netgraph_y, textsize, index, netgraphsperrow;
        float graphscale;
        netconn_t *c;
+       char vabuf[1024];
 
        if (cls.state != ca_connected)
                return;
@@ -348,7 +349,7 @@ void SCR_DrawNetGraph (void)
                                continue;
                        netgraph_x = (vid_conwidth.integer + separator2) - (1 + (index % netgraphsperrow)) * (graphwidth * 2 + separator1 + separator2);
                        netgraph_y = (vid_conheight.integer - 48 + separator2) - (1 + (index / netgraphsperrow)) * (graphheight + textsize + separator2);
-                       SCR_DrawNetGraph_DrawGraph(netgraph_x                          , netgraph_y, graphwidth, graphheight, graphscale, va("%s", svs.clients[i].name), textsize, c->outgoing_packetcounter, c->outgoing_netgraph);
+                       SCR_DrawNetGraph_DrawGraph(netgraph_x                          , netgraph_y, graphwidth, graphheight, graphscale, va(vabuf, sizeof(vabuf), "%s", svs.clients[i].name), textsize, c->outgoing_packetcounter, c->outgoing_netgraph);
                        SCR_DrawNetGraph_DrawGraph(netgraph_x + graphwidth + separator1, netgraph_y, graphwidth, graphheight, graphscale, ""                           , textsize, c->incoming_packetcounter, c->incoming_netgraph);
                        index++;
                }
@@ -360,7 +361,7 @@ void SCR_DrawNetGraph (void)
 SCR_DrawTurtle
 ==============
 */
-void SCR_DrawTurtle (void)
+static void SCR_DrawTurtle (void)
 {
        static int      count;
 
@@ -388,7 +389,7 @@ void SCR_DrawTurtle (void)
 SCR_DrawNet
 ==============
 */
-void SCR_DrawNet (void)
+static void SCR_DrawNet (void)
 {
        if (cls.state != ca_connected)
                return;
@@ -405,7 +406,7 @@ void SCR_DrawNet (void)
 DrawPause
 ==============
 */
-void SCR_DrawPause (void)
+static void SCR_DrawPause (void)
 {
        cachepic_t      *pic;
 
@@ -427,7 +428,7 @@ void SCR_DrawPause (void)
 SCR_DrawBrand
 ==============
 */
-void SCR_DrawBrand (void)
+static void SCR_DrawBrand (void)
 {
        cachepic_t      *pic;
        float           x, y;
@@ -549,9 +550,10 @@ static int SCR_DrawCurlDownload(int offset)
        float size = scr_infobar_height.value;
        Curl_downloadinfo_t *downinfo;
        char temp[256];
+       char addinfobuf[128];
        const char *addinfo;
 
-       downinfo = Curl_GetDownloadInfo(&nDownloads, &addinfo);
+       downinfo = Curl_GetDownloadInfo(&nDownloads, &addinfo, addinfobuf, sizeof(addinfobuf));
        if(!downinfo)
                return 0;
 
@@ -606,6 +608,7 @@ static int SCR_InfobarHeight(void)
        Curl_downloadinfo_t *downinfo;
        const char *addinfo;
        int nDownloads;
+       char addinfobuf[128];
 
        if (cl.time > cl.oldtime)
                scr_infobartime_off -= cl.time - cl.oldtime;
@@ -614,7 +617,7 @@ static int SCR_InfobarHeight(void)
        if(cls.qw_downloadname[0])
                offset += 1;
 
-       downinfo = Curl_GetDownloadInfo(&nDownloads, &addinfo);
+       downinfo = Curl_GetDownloadInfo(&nDownloads, &addinfo, addinfobuf, sizeof(addinfobuf));
        if(downinfo)
        {
                offset += (nDownloads + (addinfo ? 1 : 0));
@@ -630,7 +633,7 @@ static int SCR_InfobarHeight(void)
 SCR_InfoBar_f
 ==============
 */
-void SCR_InfoBar_f(void)
+static void SCR_InfoBar_f(void)
 {
        if(Cmd_Argc() == 3)
        {
@@ -649,7 +652,7 @@ void SCR_InfoBar_f(void)
 SCR_SetUpToDrawConsole
 ==================
 */
-void SCR_SetUpToDrawConsole (void)
+static void SCR_SetUpToDrawConsole (void)
 {
        // lines of console to display
        float conlines;
@@ -736,7 +739,7 @@ void R_TimeReport(const char *desc)
                GL_Finish();
        CHECKGLERROR
        r_timereport_temp = r_timereport_current;
-       r_timereport_current = Sys_DoubleTime();
+       r_timereport_current = Sys_DirtyTime();
        t = (int) ((r_timereport_current - r_timereport_temp) * 1000000.0 + 0.5);
 
        length = dpsnprintf(tempbuf, sizeof(tempbuf), "%8i %s", t, desc);
@@ -756,7 +759,7 @@ void R_TimeReport(const char *desc)
        speedstringcount += length;
 }
 
-void R_TimeReport_BeginFrame(void)
+static void R_TimeReport_BeginFrame(void)
 {
        speedstringcount = 0;
        r_speeds_timestring[0] = 0;
@@ -766,7 +769,7 @@ void R_TimeReport_BeginFrame(void)
        if (r_speeds.integer >= 2)
        {
                r_timereport_active = true;
-               r_timereport_start = r_timereport_current = Sys_DoubleTime();
+               r_timereport_start = r_timereport_current = Sys_DirtyTime();
        }
 }
 
@@ -780,7 +783,7 @@ static int R_CountLeafTriangles(const dp_model_t *model, const mleaf_t *leaf)
 
 extern cvar_t r_viewscale;
 extern float viewscalefpsadjusted;
-void R_TimeReport_EndFrame(void)
+static void R_TimeReport_EndFrame(void)
 {
        int i, j, lines, y;
        cl_locnode_t *loc;
@@ -829,7 +832,7 @@ void R_TimeReport_EndFrame(void)
                if (r_speeds.integer >= 2)
                {
                        r_timereport_active = true;
-                       r_timereport_start = r_timereport_current = Sys_DoubleTime();
+                       r_timereport_start = r_timereport_current = Sys_DirtyTime();
                }
        }
 
@@ -867,7 +870,7 @@ SCR_SizeUp_f
 Keybinding command
 =================
 */
-void SCR_SizeUp_f (void)
+static void SCR_SizeUp_f (void)
 {
        Cvar_SetValue ("viewsize",scr_viewsize.value+10);
 }
@@ -880,7 +883,7 @@ SCR_SizeDown_f
 Keybinding command
 =================
 */
-void SCR_SizeDown_f (void)
+static void SCR_SizeDown_f (void)
 {
        Cvar_SetValue ("viewsize",scr_viewsize.value-10);
 }
@@ -990,6 +993,7 @@ void SCR_ScreenShot_f (void)
        unsigned char *buffer2;
        qboolean jpeg = (scr_screenshot_jpeg.integer != 0);
        qboolean png = (scr_screenshot_png.integer != 0) && !jpeg;
+       char vabuf[1024];
 
        if (Cmd_Argc() == 2)
        {
@@ -1029,9 +1033,9 @@ void SCR_ScreenShot_f (void)
 
                // find a file name to save it to
                for (shotnumber100 = 0;shotnumber100 < 100;shotnumber100++)
-                       if (!FS_SysFileExists(va("%s/screenshots/%s-%02d.tga", fs_gamedir, prefix_name, shotnumber100))
-                        && !FS_SysFileExists(va("%s/screenshots/%s-%02d.jpg", fs_gamedir, prefix_name, shotnumber100))
-                        && !FS_SysFileExists(va("%s/screenshots/%s-%02d.png", fs_gamedir, prefix_name, shotnumber100)))
+                       if (!FS_SysFileExists(va(vabuf, sizeof(vabuf), "%s/screenshots/%s-%02d.tga", fs_gamedir, prefix_name, shotnumber100))
+                        && !FS_SysFileExists(va(vabuf, sizeof(vabuf), "%s/screenshots/%s-%02d.jpg", fs_gamedir, prefix_name, shotnumber100))
+                        && !FS_SysFileExists(va(vabuf, sizeof(vabuf), "%s/screenshots/%s-%02d.png", fs_gamedir, prefix_name, shotnumber100)))
                                break;
                if (shotnumber100 >= 100)
                {
@@ -1060,9 +1064,9 @@ void SCR_ScreenShot_f (void)
 
                // find a file name to save it to
                for (;shotnumber < 1000000;shotnumber++)
-                       if (!FS_SysFileExists(va("%s/screenshots/%s%06d.tga", fs_gamedir, prefix_name, shotnumber))
-                        && !FS_SysFileExists(va("%s/screenshots/%s%06d.jpg", fs_gamedir, prefix_name, shotnumber))
-                        && !FS_SysFileExists(va("%s/screenshots/%s%06d.png", fs_gamedir, prefix_name, shotnumber)))
+                       if (!FS_SysFileExists(va(vabuf, sizeof(vabuf), "%s/screenshots/%s%06d.tga", fs_gamedir, prefix_name, shotnumber))
+                        && !FS_SysFileExists(va(vabuf, sizeof(vabuf), "%s/screenshots/%s%06d.jpg", fs_gamedir, prefix_name, shotnumber))
+                        && !FS_SysFileExists(va(vabuf, sizeof(vabuf), "%s/screenshots/%s%06d.png", fs_gamedir, prefix_name, shotnumber)))
                                break;
                if (shotnumber >= 1000000)
                {
@@ -1097,7 +1101,7 @@ void SCR_ScreenShot_f (void)
        Mem_Free (buffer2);
 }
 
-void SCR_CaptureVideo_BeginVideo(void)
+static void SCR_CaptureVideo_BeginVideo(void)
 {
        double r, g, b;
        unsigned int i;
@@ -1132,7 +1136,7 @@ void SCR_CaptureVideo_BeginVideo(void)
        cls.capturevideo.soundchannels = S_GetSoundChannels();
        cls.capturevideo.startrealtime = realtime;
        cls.capturevideo.frame = cls.capturevideo.lastfpsframe = 0;
-       cls.capturevideo.starttime = cls.capturevideo.lastfpstime = Sys_DoubleTime();
+       cls.capturevideo.starttime = cls.capturevideo.lastfpstime = realtime;
        cls.capturevideo.soundsampleframe = 0;
        cls.capturevideo.realtime = cl_capturevideo_realtime.integer != 0;
        cls.capturevideo.screenbuffer = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * 4);
@@ -1290,7 +1294,7 @@ static void SCR_ScaleDownBGRA(unsigned char *in, int inw, int inh, unsigned char
        }
 }
 
-void SCR_CaptureVideo_VideoFrame(int newframestepframenum)
+static void SCR_CaptureVideo_VideoFrame(int newframestepframenum)
 {
        int x = 0, y = 0;
        int width = cls.capturevideo.width, height = cls.capturevideo.height;
@@ -1311,7 +1315,7 @@ void SCR_CaptureVideo_VideoFrame(int newframestepframenum)
        if(cl_capturevideo_printfps.integer)
        {
                char buf[80];
-               double t = Sys_DoubleTime();
+               double t = realtime;
                if(t > cls.capturevideo.lastfpstime + 1)
                {
                        double fps1 = (cls.capturevideo.frame - cls.capturevideo.lastfpsframe) / (t - cls.capturevideo.lastfpstime + 0.0000001);
@@ -1330,7 +1334,7 @@ void SCR_CaptureVideo_SoundFrame(const portable_sampleframe_t *paintbuffer, size
        cls.capturevideo.soundframe(paintbuffer, length);
 }
 
-void SCR_CaptureVideo(void)
+static void SCR_CaptureVideo(void)
 {
        int newframenum;
        if (cl_capturevideo.integer)
@@ -1475,7 +1479,7 @@ void SHOWLMP_decodehide(void)
 {
        int i;
        char *lmplabel;
-       lmplabel = MSG_ReadString();
+       lmplabel = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
        for (i = 0;i < cl.num_showlmps;i++)
                if (cl.showlmps[i].isactive && strcmp(cl.showlmps[i].label, lmplabel) == 0)
                {
@@ -1489,17 +1493,17 @@ void SHOWLMP_decodeshow(void)
        int k;
        char lmplabel[256], picname[256];
        float x, y;
-       strlcpy (lmplabel,MSG_ReadString(), sizeof (lmplabel));
-       strlcpy (picname, MSG_ReadString(), sizeof (picname));
+       strlcpy (lmplabel,MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof (lmplabel));
+       strlcpy (picname, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof (picname));
        if (gamemode == GAME_NEHAHRA) // LordHavoc: nasty old legacy junk
        {
-               x = MSG_ReadByte();
-               y = MSG_ReadByte();
+               x = MSG_ReadByte(&cl_message);
+               y = MSG_ReadByte(&cl_message);
        }
        else
        {
-               x = MSG_ReadShort();
-               y = MSG_ReadShort();
+               x = MSG_ReadShort(&cl_message);
+               y = MSG_ReadShort(&cl_message);
        }
        if (!cl.showlmps || cl.num_showlmps >= cl.max_showlmps)
        {
@@ -1637,7 +1641,6 @@ static void SCR_DrawTouchscreenOverlay(void)
        }
 }
 
-extern void R_UpdateFog(void);
 void R_ClearScreen(qboolean fogcolor)
 {
        float clearcolor[4];
@@ -1656,14 +1659,9 @@ void R_ClearScreen(qboolean fogcolor)
        GL_Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | (vid.stencil ? GL_STENCIL_BUFFER_BIT : 0), clearcolor, 1.0f, 128);
 }
 
-qboolean CL_VM_UpdateView (void);
-void SCR_DrawConsole (void);
-void R_Shadow_EditLights_DrawSelectedLightProperties(void);
-
 int r_stereo_side;
 
-extern void Sbar_ShowFPS(void);
-void SCR_DrawScreen (void)
+static void SCR_DrawScreen (void)
 {
        Draw_Frame();
 
@@ -2031,6 +2029,7 @@ static void SCR_DrawLoadingScreen_SharedSetup (qboolean clear)
 {
        r_viewport_t viewport;
        float x, y, w, h, sw, sh, f;
+       char vabuf[1024];
        // release mouse grab while loading
        if (!vid.fullscreen)
                VID_SetMouse(false, false, false);
@@ -2047,7 +2046,7 @@ static void SCR_DrawLoadingScreen_SharedSetup (qboolean clear)
        R_Mesh_Start();
        R_EntityMatrix(&identitymatrix);
        // draw the loading plaque
-       loadingscreenpic = Draw_CachePic_Flags (loadingscreenpic_number ? va("gfx/loading%d", loadingscreenpic_number+1) : "gfx/loading", loadingscreenpic_number ? CACHEPICFLAG_NOTPERSISTENT : 0);
+       loadingscreenpic = Draw_CachePic_Flags (loadingscreenpic_number ? va(vabuf, sizeof(vabuf), "gfx/loading%d", loadingscreenpic_number+1) : "gfx/loading", loadingscreenpic_number ? CACHEPICFLAG_NOTPERSISTENT : 0);
 
        w = loadingscreenpic->width;
        h = loadingscreenpic->height;
@@ -2211,7 +2210,6 @@ extern cvar_t cl_minfps_qualityscale;
 extern cvar_t r_viewscale_fpsscaling;
 static double cl_updatescreen_rendertime = 0;
 static double cl_updatescreen_quality = 1;
-extern void Sbar_ShowFPS_Update(void);
 void CL_UpdateScreen(void)
 {
        vec3_t vieworigin;
@@ -2247,7 +2245,7 @@ void CL_UpdateScreen(void)
                return;
        }
 
-       rendertime1 = Sys_DoubleTime();
+       rendertime1 = Sys_DirtyTime();
 
        conwidth = bound(160, vid_conwidth.value, 32768);
        conheight = bound(90, vid_conheight.value, 24576);
@@ -2351,7 +2349,7 @@ void CL_UpdateScreen(void)
 
        if (r_viewscale_fpsscaling.integer)
                GL_Finish();
-       drawscreenstart = Sys_DoubleTime();
+       drawscreenstart = Sys_DirtyTime();
 #ifndef USE_GLES2
        if (R_Stereo_Active())
        {
@@ -2388,7 +2386,7 @@ void CL_UpdateScreen(void)
                SCR_DrawScreen();
        if (r_viewscale_fpsscaling.integer)
                GL_Finish();
-       r_refdef.lastdrawscreentime = Sys_DoubleTime() - drawscreenstart;
+       r_refdef.lastdrawscreentime = Sys_DirtyTime() - drawscreenstart;
 
        SCR_CaptureVideo();
 
@@ -2396,7 +2394,7 @@ void CL_UpdateScreen(void)
                qglFlush(); // FIXME: should we really be using qglFlush here?
 
        // quality adjustment according to render time
-       cl_updatescreen_rendertime += ((Sys_DoubleTime() - rendertime1) - cl_updatescreen_rendertime) * bound(0, cl_minfps_fade.value, 1);
+       cl_updatescreen_rendertime += ((Sys_DirtyTime() - rendertime1) - cl_updatescreen_rendertime) * bound(0, cl_minfps_fade.value, 1);
        if (cl_minfps.value > 0 && cl_updatescreen_rendertime > 0 && !cls.timedemo && (!cls.capturevideo.active || !cls.capturevideo.realtime))
                cl_updatescreen_quality = 1 / (cl_updatescreen_rendertime * cl_minfps.value);
        else
index 7c4b2a5ebda32f919e79f0174902a421445c7a85..08db0588845caa8a6cea0d8e7ef9a9d367a14129 100644 (file)
@@ -418,7 +418,7 @@ typedef struct
 }
 cl_video_subtitle_info_t;
 
-float CL_DrawVideo_WordWidthFunc(void *passthrough, const char *w, size_t *length, float maxWidth)
+static float CL_DrawVideo_WordWidthFunc(void *passthrough, const char *w, size_t *length, float maxWidth)
 {
        cl_video_subtitle_info_t *si = (cl_video_subtitle_info_t *) passthrough;
 
@@ -432,7 +432,7 @@ float CL_DrawVideo_WordWidthFunc(void *passthrough, const char *w, size_t *lengt
                return 0;
 }
 
-int CL_DrawVideo_DisplaySubtitleLine(void *passthrough, const char *line, size_t length, float width, qboolean isContinuation)
+static int CL_DrawVideo_DisplaySubtitleLine(void *passthrough, const char *line, size_t length, float width, qboolean isContinuation)
 {
        cl_video_subtitle_info_t *si = (cl_video_subtitle_info_t *) passthrough;
 
@@ -577,12 +577,13 @@ void CL_DrawVideo(void)
 
 void CL_VideoStart(char *filename, const char *subtitlesfile)
 {
+       char vabuf[1024];
        Host_StartVideo();
 
        if( cl_videos->state != CLVIDEO_UNUSED )
                CL_CloseVideo( cl_videos );
        // already contains video/
-       if( !OpenVideo( cl_videos, filename, va( CLDYNTEXTUREPREFIX "%s", filename ), 0, subtitlesfile ) )
+       if( !OpenVideo( cl_videos, filename, va(vabuf, sizeof(vabuf),  CLDYNTEXTUREPREFIX "%s", filename ), 0, subtitlesfile ) )
                return;
        // expand the active range to include the new entry
        cl_num_videos = max(cl_num_videos, 1);
index a652dbc221734955ef5480e630fb9ecd1f5da783..da65ef298e96bbb42da1da2f99c20571cb149532 100644 (file)
@@ -41,7 +41,7 @@ unsigned int jam_getwidth(void *stream);
 unsigned int jam_getheight(void *stream);
 double jam_getframerate(void *stream);
 int jam_video(void *stream, void *imagedata, unsigned int Rmask, unsigned int Gmask, unsigned int Bmask, unsigned int bytesperpixel, int imagebytesperrow);
-void *jam_open(clvideo_t *video, char *filename, const char **errorstring)
+static void *jam_open(clvideo_t *video, char *filename, const char **errorstring)
 {
        unsigned char jamHead[16];
        char *wavename;
@@ -176,7 +176,7 @@ double jam_getframerate(void *stream)
 
 
 // decode JAM frame
-void jam_decodeframe(unsigned char *inbuf, unsigned char *outbuf, unsigned char *prevbuf, int outsize, int frametype)
+static void jam_decodeframe(unsigned char *inbuf, unsigned char *outbuf, unsigned char *prevbuf, int outsize, int frametype)
 {
        unsigned char *srcptr, *destptr, *prevptr;
        int bytesleft;
index f8acbcdd7c8b97151cf42c52cd2e866219d099dc..cd780e62e9b70d15db82f685c358c21488850eb2 100644 (file)
--- a/client.h
+++ b/client.h
@@ -580,7 +580,7 @@ typedef struct capturevideostate_s
        const char *formatextension;
        qfile_t *videofile;
                // always use this:
-               //   cls.capturevideo.videofile = FS_OpenRealFile(va("%s.%s", cls.capturevideo.basename, cls.capturevideo.formatextension), "wb", false);
+               //   cls.capturevideo.videofile = FS_OpenRealFile(va(vabuf, sizeof(vabuf), "%s.%s", cls.capturevideo.basename, cls.capturevideo.formatextension), "wb", false);
        void (*endvideo) (void);
        void (*videoframes) (int num);
        void (*soundframe) (const portable_sampleframe_t *paintbuffer, size_t length);
@@ -1409,7 +1409,7 @@ extern int cl_ignoremousemoves;
 
 
 float CL_KeyState (kbutton_t *key);
-const char *Key_KeynumToString (int keynum);
+const char *Key_KeynumToString (int keynum, char *buf, size_t buflength);
 int Key_StringToKeynum (const char *str);
 
 //
@@ -1838,5 +1838,21 @@ extern r_refdef_t r_refdef;
 // warpzone prediction hack (CSQC builtin)
 void CL_RotateMoves(const matrix4x4_t *m);
 
+void CL_NewFrameReceived(int num);
+void CL_ParseEntityLump(char *entitystring);
+void CL_FindNonSolidLocation(const vec3_t in, vec3_t out, vec_t radius);
+void CL_RelinkLightFlashes(void);
+void Sbar_ShowFPS(void);
+void Sbar_ShowFPS_Update(void);
+void Host_SaveConfig(void);
+void Host_LoadConfig_f(void);
+void CL_UpdateMoveVars(void);
+void SCR_CaptureVideo_SoundFrame(const portable_sampleframe_t *paintbuffer, size_t length);
+void V_DriftPitch(void);
+void V_FadeViewFlashs(void);
+void V_CalcViewBlend(void);
+void V_CalcRefdef(void);
+void CL_Locs_Reload_f(void);
+
 #endif
 
index a9c30b4297d49526ab10f6461e475270912a6d4e..62b84db36843aee60a0fcab2e8c69059bb8caa75 100644 (file)
@@ -25,22 +25,15 @@ extern cvar_t r_equalize_entities_fullbright;
 
 r_refdef_view_t csqc_original_r_refdef_view;
 
-sfx_t *S_FindName(const char *name);
-int Sbar_GetSortedPlayerIndex (int index);
-void Sbar_SortFrags (void);
-void CL_FindNonSolidLocation(const vec3_t in, vec3_t out, vec_t radius);
-void CSQC_RelinkAllEntities (int drawmask);
-void CSQC_RelinkCSQCEntities (void);
-
 // #1 void(vector ang) makevectors
-static void VM_CL_makevectors (void)
+static void VM_CL_makevectors (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_CL_makevectors);
        AngleVectors (PRVM_G_VECTOR(OFS_PARM0), PRVM_clientglobalvector(v_forward), PRVM_clientglobalvector(v_right), PRVM_clientglobalvector(v_up));
 }
 
 // #2 void(entity e, vector o) setorigin
-void VM_CL_setorigin (void)
+static void VM_CL_setorigin (prvm_prog_t *prog)
 {
        prvm_edict_t    *e;
        float   *org;
@@ -49,12 +42,12 @@ void VM_CL_setorigin (void)
        e = PRVM_G_EDICT(OFS_PARM0);
        if (e == prog->edicts)
        {
-               VM_Warning("setorigin: can not modify world entity\n");
+               VM_Warning(prog, "setorigin: can not modify world entity\n");
                return;
        }
        if (e->priv.required->free)
        {
-               VM_Warning("setorigin: can not modify free entity\n");
+               VM_Warning(prog, "setorigin: can not modify free entity\n");
                return;
        }
        org = PRVM_G_VECTOR(OFS_PARM1);
@@ -62,13 +55,13 @@ void VM_CL_setorigin (void)
        CL_LinkEdict(e);
 }
 
-static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max)
+static void SetMinMaxSize (prvm_prog_t *prog, prvm_edict_t *e, float *min, float *max)
 {
        int             i;
 
        for (i=0 ; i<3 ; i++)
                if (min[i] > max[i])
-                       PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
+                       prog->error_cmd("SetMinMaxSize: backwards mins/maxs");
 
        // set derived values
        VectorCopy (min, PRVM_clientedictvector(e, mins));
@@ -79,7 +72,7 @@ static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max)
 }
 
 // #3 void(entity e, string m) setmodel
-void VM_CL_setmodel (void)
+static void VM_CL_setmodel (prvm_prog_t *prog)
 {
        prvm_edict_t    *e;
        const char              *m;
@@ -99,7 +92,7 @@ void VM_CL_setmodel (void)
                if (!strcmp(cl.csqc_model_precache[i]->name, m))
                {
                        mod = cl.csqc_model_precache[i];
-                       PRVM_clientedictstring(e, model) = PRVM_SetEngineString(mod->name);
+                       PRVM_clientedictstring(e, model) = PRVM_SetEngineString(prog, mod->name);
                        PRVM_clientedictfloat(e, modelindex) = -(i+1);
                        break;
                }
@@ -111,7 +104,7 @@ void VM_CL_setmodel (void)
                        mod = cl.model_precache[i];
                        if (mod && !strcmp(mod->name, m))
                        {
-                               PRVM_clientedictstring(e, model) = PRVM_SetEngineString(mod->name);
+                               PRVM_clientedictstring(e, model) = PRVM_SetEngineString(prog, mod->name);
                                PRVM_clientedictfloat(e, modelindex) = i;
                                break;
                        }
@@ -124,13 +117,13 @@ void VM_CL_setmodel (void)
        }
        else
        {
-               SetMinMaxSize (e, vec3_origin, vec3_origin);
-               VM_Warning ("setmodel: model '%s' not precached\n", m);
+               SetMinMaxSize (prog, e, vec3_origin, vec3_origin);
+               VM_Warning(prog, "setmodel: model '%s' not precached\n", m);
        }
 }
 
 // #4 void(entity e, vector min, vector max) setsize
-static void VM_CL_setsize (void)
+static void VM_CL_setsize (prvm_prog_t *prog)
 {
        prvm_edict_t    *e;
        float                   *min, *max;
@@ -139,24 +132,24 @@ static void VM_CL_setsize (void)
        e = PRVM_G_EDICT(OFS_PARM0);
        if (e == prog->edicts)
        {
-               VM_Warning("setsize: can not modify world entity\n");
+               VM_Warning(prog, "setsize: can not modify world entity\n");
                return;
        }
        if (e->priv.server->free)
        {
-               VM_Warning("setsize: can not modify free entity\n");
+               VM_Warning(prog, "setsize: can not modify free entity\n");
                return;
        }
        min = PRVM_G_VECTOR(OFS_PARM1);
        max = PRVM_G_VECTOR(OFS_PARM2);
 
-       SetMinMaxSize( e, min, max );
+       SetMinMaxSize( prog, e, min, max );
 
        CL_LinkEdict(e);
 }
 
 // #8 void(entity e, float chan, string samp, float volume, float atten) sound
-static void VM_CL_sound (void)
+static void VM_CL_sound (prvm_prog_t *prog)
 {
        const char                      *sample;
        int                                     channel;
@@ -177,13 +170,13 @@ static void VM_CL_sound (void)
 
        if (volume < 0 || volume > 1)
        {
-               VM_Warning("VM_CL_sound: volume must be in range 0-1\n");
+               VM_Warning(prog, "VM_CL_sound: volume must be in range 0-1\n");
                return;
        }
 
        if (attenuation < 0 || attenuation > 4)
        {
-               VM_Warning("VM_CL_sound: attenuation must be in range 0-4\n");
+               VM_Warning(prog, "VM_CL_sound: attenuation must be in range 0-4\n");
                return;
        }
 
@@ -202,7 +195,7 @@ static void VM_CL_sound (void)
 
        if (!IS_CHAN(channel))
        {
-               VM_Warning("VM_CL_sound: channel must be in range 0-127\n");
+               VM_Warning(prog, "VM_CL_sound: channel must be in range 0-127\n");
                return;
        }
 
@@ -211,7 +204,7 @@ static void VM_CL_sound (void)
 }
 
 // #483 void(vector origin, string sample, float volume, float attenuation) pointsound
-static void VM_CL_pointsound(void)
+static void VM_CL_pointsound(prvm_prog_t *prog)
 {
        const char                      *sample;
        float                           volume;
@@ -227,13 +220,13 @@ static void VM_CL_pointsound(void)
 
        if (volume < 0 || volume > 1)
        {
-               VM_Warning("VM_CL_pointsound: volume must be in range 0-1\n");
+               VM_Warning(prog, "VM_CL_pointsound: volume must be in range 0-1\n");
                return;
        }
 
        if (attenuation < 0 || attenuation > 4)
        {
-               VM_Warning("VM_CL_pointsound: attenuation must be in range 0-4\n");
+               VM_Warning(prog, "VM_CL_pointsound: attenuation must be in range 0-4\n");
                return;
        }
 
@@ -242,16 +235,16 @@ static void VM_CL_pointsound(void)
 }
 
 // #14 entity() spawn
-static void VM_CL_spawn (void)
+static void VM_CL_spawn (prvm_prog_t *prog)
 {
        prvm_edict_t *ed;
-       ed = PRVM_ED_Alloc();
+       ed = PRVM_ED_Alloc(prog);
        VM_RETURN_EDICT(ed);
 }
 
-void CL_VM_SetTraceGlobals(const trace_t *trace, int svent)
+static void CL_VM_SetTraceGlobals(prvm_prog_t *prog, const trace_t *trace, int svent)
 {
-       VM_SetTraceGlobals(trace);
+       VM_SetTraceGlobals(prog, trace);
        PRVM_clientglobalfloat(trace_networkentity) = svent;
 }
 
@@ -259,7 +252,7 @@ void CL_VM_SetTraceGlobals(const trace_t *trace, int svent)
 #define CL_HitNetworkPlayers(move)     !((move) == MOVE_WORLDONLY || (move) == MOVE_NOMONSTERS)
 
 // #16 void(vector v1, vector v2, float movetype, entity ignore) traceline
-static void VM_CL_traceline (void)
+static void VM_CL_traceline (prvm_prog_t *prog)
 {
        float   *v1, *v2;
        trace_t trace;
@@ -278,11 +271,11 @@ static void VM_CL_traceline (void)
        ent = PRVM_G_EDICT(OFS_PARM3);
 
        if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v2[1]) || IS_NAN(v2[2]))
-               PRVM_ERROR("%s: NAN errors detected in traceline('%f %f %f', '%f %f %f', %i, entity %i)\n", PRVM_NAME, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
+               prog->error_cmd("%s: NAN errors detected in traceline('%f %f %f', '%f %f %f', %i, entity %i)\n", prog->name, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
 
        trace = CL_TraceLine(v1, v2, move, ent, CL_GenericHitSuperContentsMask(ent), CL_HitNetworkBrushModels(move), CL_HitNetworkPlayers(move), &svent, true, false);
 
-       CL_VM_SetTraceGlobals(&trace, svent);
+       CL_VM_SetTraceGlobals(prog, &trace, svent);
 //     R_TimeReport("traceline");
 }
 
@@ -298,7 +291,7 @@ tracebox (vector1, vector mins, vector maxs, vector2, tryents)
 =================
 */
 // LordHavoc: added this for my own use, VERY useful, similar to traceline
-static void VM_CL_tracebox (void)
+static void VM_CL_tracebox (prvm_prog_t *prog)
 {
        float   *v1, *v2, *m1, *m2;
        trace_t trace;
@@ -318,15 +311,15 @@ static void VM_CL_tracebox (void)
        ent = PRVM_G_EDICT(OFS_PARM5);
 
        if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v2[1]) || IS_NAN(v2[2]))
-               PRVM_ERROR("%s: NAN errors detected in tracebox('%f %f %f', '%f %f %f', '%f %f %f', '%f %f %f', %i, entity %i)\n", PRVM_NAME, v1[0], v1[1], v1[2], m1[0], m1[1], m1[2], m2[0], m2[1], m2[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
+               prog->error_cmd("%s: NAN errors detected in tracebox('%f %f %f', '%f %f %f', '%f %f %f', '%f %f %f', %i, entity %i)\n", prog->name, v1[0], v1[1], v1[2], m1[0], m1[1], m1[2], m2[0], m2[1], m2[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
 
        trace = CL_TraceBox(v1, m1, m2, v2, move, ent, CL_GenericHitSuperContentsMask(ent), CL_HitNetworkBrushModels(move), CL_HitNetworkPlayers(move), &svent, true);
 
-       CL_VM_SetTraceGlobals(&trace, svent);
+       CL_VM_SetTraceGlobals(prog, &trace, svent);
 //     R_TimeReport("tracebox");
 }
 
-trace_t CL_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore, int *svent)
+static trace_t CL_Trace_Toss (prvm_prog_t *prog, prvm_edict_t *tossent, prvm_edict_t *ignore, int *svent)
 {
        int i;
        float gravity;
@@ -368,7 +361,7 @@ trace_t CL_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore, int *svent)
        return trace;
 }
 
-static void VM_CL_tracetoss (void)
+static void VM_CL_tracetoss (prvm_prog_t *prog)
 {
        trace_t trace;
        prvm_edict_t    *ent;
@@ -382,19 +375,19 @@ static void VM_CL_tracetoss (void)
        ent = PRVM_G_EDICT(OFS_PARM0);
        if (ent == prog->edicts)
        {
-               VM_Warning("tracetoss: can not use world entity\n");
+               VM_Warning(prog, "tracetoss: can not use world entity\n");
                return;
        }
        ignore = PRVM_G_EDICT(OFS_PARM1);
 
-       trace = CL_Trace_Toss (ent, ignore, &svent);
+       trace = CL_Trace_Toss (prog, ent, ignore, &svent);
 
-       CL_VM_SetTraceGlobals(&trace, svent);
+       CL_VM_SetTraceGlobals(prog, &trace, svent);
 }
 
 
 // #20 void(string s) precache_model
-void VM_CL_precache_model (void)
+static void VM_CL_precache_model (prvm_prog_t *prog)
 {
        const char      *name;
        int                     i;
@@ -424,13 +417,13 @@ void VM_CL_precache_model (void)
                                return;
                        }
                }
-               VM_Warning("VM_CL_precache_model: no free models\n");
+               VM_Warning(prog, "VM_CL_precache_model: no free models\n");
                return;
        }
-       VM_Warning("VM_CL_precache_model: model \"%s\" not found\n", name);
+       VM_Warning(prog, "VM_CL_precache_model: model \"%s\" not found\n", name);
 }
 
-int CSQC_EntitiesInBox (vec3_t mins, vec3_t maxs, int maxlist, prvm_edict_t **list)
+static int CSQC_EntitiesInBox (prvm_prog_t *prog, vec3_t mins, vec3_t maxs, int maxlist, prvm_edict_t **list)
 {
        prvm_edict_t    *ent;
        int                             i, k;
@@ -447,7 +440,7 @@ int CSQC_EntitiesInBox (vec3_t mins, vec3_t maxs, int maxlist, prvm_edict_t **li
 }
 
 // #22 entity(vector org, float rad) findradius
-static void VM_CL_findradius (void)
+static void VM_CL_findradius (prvm_prog_t *prog)
 {
        prvm_edict_t    *ent, *chain;
        vec_t                   radius, radius2;
@@ -463,7 +456,7 @@ static void VM_CL_findradius (void)
        else
                chainfield = prog->fieldoffsets.chain;
        if(chainfield < 0)
-               PRVM_ERROR("VM_findchain: %s doesnt have the specified chain field !", PRVM_NAME);
+               prog->error_cmd("VM_findchain: %s doesnt have the specified chain field !", prog->name);
 
        chain = (prvm_edict_t *)prog->edicts;
 
@@ -477,7 +470,7 @@ static void VM_CL_findradius (void)
        maxs[0] = org[0] + (radius + 1);
        maxs[1] = org[1] + (radius + 1);
        maxs[2] = org[2] + (radius + 1);
-       numtouchedicts = CSQC_EntitiesInBox(mins, maxs, MAX_EDICTS, touchedicts);
+       numtouchedicts = CSQC_EntitiesInBox(prog, mins, maxs, MAX_EDICTS, touchedicts);
        if (numtouchedicts > MAX_EDICTS)
        {
                // this never happens   //[515]: for what then ?
@@ -514,7 +507,7 @@ static void VM_CL_findradius (void)
 }
 
 // #34 float() droptofloor
-static void VM_CL_droptofloor (void)
+static void VM_CL_droptofloor (prvm_prog_t *prog)
 {
        prvm_edict_t            *ent;
        vec3_t                          end;
@@ -528,12 +521,12 @@ static void VM_CL_droptofloor (void)
        ent = PRVM_PROG_TO_EDICT(PRVM_clientglobaledict(self));
        if (ent == prog->edicts)
        {
-               VM_Warning("droptofloor: can not modify world entity\n");
+               VM_Warning(prog, "droptofloor: can not modify world entity\n");
                return;
        }
        if (ent->priv.server->free)
        {
-               VM_Warning("droptofloor: can not modify free entity\n");
+               VM_Warning(prog, "droptofloor: can not modify free entity\n");
                return;
        }
 
@@ -554,7 +547,7 @@ static void VM_CL_droptofloor (void)
 }
 
 // #35 void(float style, string value) lightstyle
-static void VM_CL_lightstyle (void)
+static void VM_CL_lightstyle (prvm_prog_t *prog)
 {
        int                     i;
        const char      *c;
@@ -565,7 +558,7 @@ static void VM_CL_lightstyle (void)
        c = PRVM_G_STRING(OFS_PARM1);
        if (i >= cl.max_lightstyle)
        {
-               VM_Warning("VM_CL_lightstyle >= MAX_LIGHTSTYLES\n");
+               VM_Warning(prog, "VM_CL_lightstyle >= MAX_LIGHTSTYLES\n");
                return;
        }
        strlcpy (cl.lightstyle[i].map, c, sizeof (cl.lightstyle[i].map));
@@ -574,7 +567,7 @@ static void VM_CL_lightstyle (void)
 }
 
 // #40 float(entity e) checkbottom
-static void VM_CL_checkbottom (void)
+static void VM_CL_checkbottom (prvm_prog_t *prog)
 {
        static int              cs_yes, cs_no;
        prvm_edict_t    *ent;
@@ -645,14 +638,14 @@ realcheck:
 }
 
 // #41 float(vector v) pointcontents
-static void VM_CL_pointcontents (void)
+static void VM_CL_pointcontents (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_CL_pointcontents);
        PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, CL_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
 }
 
 // #48 void(vector o, vector d, float color, float count) particle
-static void VM_CL_particle (void)
+static void VM_CL_particle (prvm_prog_t *prog)
 {
        float   *org, *dir;
        int             count;
@@ -667,7 +660,7 @@ static void VM_CL_particle (void)
 }
 
 // #74 void(vector pos, string samp, float vol, float atten) ambientsound
-static void VM_CL_ambientsound (void)
+static void VM_CL_ambientsound (prvm_prog_t *prog)
 {
        float   *f;
        sfx_t   *s;
@@ -678,7 +671,7 @@ static void VM_CL_ambientsound (void)
 }
 
 // #92 vector(vector org[, float lpflag]) getlight (DP_QC_GETLIGHT)
-static void VM_CL_getlight (void)
+static void VM_CL_getlight (prvm_prog_t *prog)
 {
        vec3_t ambientcolor, diffusecolor, diffusenormal;
        vec_t *p;
@@ -704,7 +697,6 @@ static void VM_CL_getlight (void)
 
 //============================================================================
 //[515]: SCENE MANAGER builtins
-extern qboolean CSQC_AddRenderEdict (prvm_edict_t *ed, int edictnum);//csprogs.c
 
 void CSQC_R_RecalcView (void)
 {
@@ -716,9 +708,8 @@ void CSQC_R_RecalcView (void)
        Matrix4x4_Concat(&viewmodelmatrix_withbob, &r_refdef.view.matrix, &cl.csqc_viewmodelmatrixfromengine);
 }
 
-void CL_RelinkLightFlashes(void);
 //#300 void() clearscene (EXT_CSQC)
-void VM_CL_R_ClearScene (void)
+static void VM_CL_R_ClearScene (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0, VM_CL_R_ClearScene);
        // clear renderable entity and light lists
@@ -735,11 +726,9 @@ void VM_CL_R_ClearScene (void)
 }
 
 //#301 void(float mask) addentities (EXT_CSQC)
-extern void CSQC_Predraw (prvm_edict_t *ed);//csprogs.c
-extern void CSQC_Think (prvm_edict_t *ed);//csprogs.c
-void VM_CL_R_AddEntities (void)
+static void VM_CL_R_AddEntities (prvm_prog_t *prog)
 {
-       double t = Sys_DoubleTime();
+       double t = Sys_DirtyTime();
        int                     i, drawmask;
        prvm_edict_t *ed;
        VM_SAFEPARMCOUNT(1, VM_CL_R_AddEntities);
@@ -768,16 +757,18 @@ void VM_CL_R_AddEntities (void)
        }
 
        // callprofile fixing hack: do not include this time in what is counted for CSQC_UpdateView
-       prog->functions[PRVM_clientfunction(CSQC_UpdateView)].totaltime -= Sys_DoubleTime() - t;
+       t = Sys_DirtyTime() - t;if (t < 0 || t >= 1800) t = 0;
+       prog->functions[PRVM_clientfunction(CSQC_UpdateView)].totaltime -= t;
 }
 
 //#302 void(entity ent) addentity (EXT_CSQC)
-void VM_CL_R_AddEntity (void)
+static void VM_CL_R_AddEntity (prvm_prog_t *prog)
 {
-       double t = Sys_DoubleTime();
+       double t = Sys_DirtyTime();
        VM_SAFEPARMCOUNT(1, VM_CL_R_AddEntity);
        CSQC_AddRenderEdict(PRVM_G_EDICT(OFS_PARM0), 0);
-       prog->functions[PRVM_clientfunction(CSQC_UpdateView)].totaltime -= Sys_DoubleTime() - t;
+       t = Sys_DirtyTime() - t;if (t < 0 || t >= 1800) t = 0;
+       prog->functions[PRVM_clientfunction(CSQC_UpdateView)].totaltime -= t;
 }
 
 //#303 float(float property, ...) setproperty (EXT_CSQC)
@@ -786,7 +777,7 @@ void VM_CL_R_AddEntity (void)
 //#309 float(float property) getproperty
 //#309 vector(float property) getpropertyvec
 // VorteX: make this function be able to return previously set property if new value is not given
-void VM_CL_R_SetView (void)
+static void VM_CL_R_SetView (prvm_prog_t *prog)
 {
        int             c;
        float   *f;
@@ -820,7 +811,7 @@ void VM_CL_R_SetView (void)
                        PRVM_G_FLOAT(OFS_RETURN) = r_refdef.view.height;
                        break;
                case VF_VIEWPORT:
-                       VM_Warning("VM_CL_R_GetView : VF_VIEWPORT can't be retrieved, use VF_MIN/VF_SIZE instead\n");
+                       VM_Warning(prog, "VM_CL_R_GetView : VF_VIEWPORT can't be retrieved, use VF_MIN/VF_SIZE instead\n");
                        break;
                case VF_FOV:
                        VectorSet(PRVM_G_VECTOR(OFS_RETURN), r_refdef.view.ortho_x, r_refdef.view.ortho_y, 0);
@@ -916,7 +907,7 @@ void VM_CL_R_SetView (void)
                        break;
                default:
                        PRVM_G_FLOAT(OFS_RETURN) = 0;
-                       VM_Warning("VM_CL_R_GetView : unknown parm %i\n", c);
+                       VM_Warning(prog, "VM_CL_R_GetView : unknown parm %i\n", c);
                        return;
                }
                return;
@@ -1063,16 +1054,16 @@ void VM_CL_R_SetView (void)
                break;
        default:
                PRVM_G_FLOAT(OFS_RETURN) = 0;
-               VM_Warning("VM_CL_R_SetView : unknown parm %i\n", c);
+               VM_Warning(prog, "VM_CL_R_SetView : unknown parm %i\n", c);
                return;
        }
        PRVM_G_FLOAT(OFS_RETURN) = 1;
 }
 
 //#305 void(vector org, float radius, vector lightcolours[, float style, string cubemapname, float pflags]) adddynamiclight (EXT_CSQC)
-void VM_CL_R_AddDynamicLight (void)
+static void VM_CL_R_AddDynamicLight (prvm_prog_t *prog)
 {
-       double t = Sys_DoubleTime();
+       double t = Sys_DirtyTime();
        vec_t *org;
        float radius = 300;
        vec_t *col;
@@ -1119,13 +1110,14 @@ void VM_CL_R_AddDynamicLight (void)
 
        R_RTLight_Update(&r_refdef.scene.templights[r_refdef.scene.numlights], false, &matrix, col, style, cubemapname, castshadow, coronaintensity, coronasizescale, ambientscale, diffusescale, specularscale, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
        r_refdef.scene.lights[r_refdef.scene.numlights] = &r_refdef.scene.templights[r_refdef.scene.numlights];r_refdef.scene.numlights++;
-       prog->functions[PRVM_clientfunction(CSQC_UpdateView)].totaltime -= Sys_DoubleTime() - t;
+       t = Sys_DirtyTime() - t;if (t < 0 || t >= 1800) t = 0;
+       prog->functions[PRVM_clientfunction(CSQC_UpdateView)].totaltime -= t;
 }
 
 //============================================================================
 
 //#310 vector (vector v) cs_unproject (EXT_CSQC)
-static void VM_CL_unproject (void)
+static void VM_CL_unproject (prvm_prog_t *prog)
 {
        float   *f;
        vec3_t  temp;
@@ -1142,7 +1134,7 @@ static void VM_CL_unproject (void)
 }
 
 //#311 vector (vector v) cs_project (EXT_CSQC)
-static void VM_CL_project (void)
+static void VM_CL_project (prvm_prog_t *prog)
 {
        float   *f;
        vec3_t  v;
@@ -1164,7 +1156,7 @@ static void VM_CL_project (void)
 }
 
 //#330 float(float stnum) getstatf (EXT_CSQC)
-static void VM_CL_getstatf (void)
+static void VM_CL_getstatf (prvm_prog_t *prog)
 {
        int i;
        union
@@ -1176,7 +1168,7 @@ static void VM_CL_getstatf (void)
        i = (int)PRVM_G_FLOAT(OFS_PARM0);
        if(i < 0 || i >= MAX_CL_STATS)
        {
-               VM_Warning("VM_CL_getstatf: index>=MAX_CL_STATS or index<0\n");
+               VM_Warning(prog, "VM_CL_getstatf: index>=MAX_CL_STATS or index<0\n");
                return;
        }
        dat.l = cl.stats[i];
@@ -1184,7 +1176,7 @@ static void VM_CL_getstatf (void)
 }
 
 //#331 float(float stnum) getstati (EXT_CSQC)
-static void VM_CL_getstati (void)
+static void VM_CL_getstati (prvm_prog_t *prog)
 {
        int i, index;
        int firstbit, bitcount;
@@ -1208,7 +1200,7 @@ static void VM_CL_getstati (void)
 
        if(index < 0 || index >= MAX_CL_STATS)
        {
-               VM_Warning("VM_CL_getstati: index>=MAX_CL_STATS or index<0\n");
+               VM_Warning(prog, "VM_CL_getstati: index>=MAX_CL_STATS or index<0\n");
                return;
        }
        i = cl.stats[index];
@@ -1218,7 +1210,7 @@ static void VM_CL_getstati (void)
 }
 
 //#332 string(float firststnum) getstats (EXT_CSQC)
-static void VM_CL_getstats (void)
+static void VM_CL_getstats (prvm_prog_t *prog)
 {
        int i;
        char t[17];
@@ -1227,15 +1219,15 @@ static void VM_CL_getstats (void)
        if(i < 0 || i > MAX_CL_STATS-4)
        {
                PRVM_G_INT(OFS_RETURN) = OFS_NULL;
-               VM_Warning("VM_CL_getstats: index>MAX_CL_STATS-4 or index<0\n");
+               VM_Warning(prog, "VM_CL_getstats: index>MAX_CL_STATS-4 or index<0\n");
                return;
        }
        strlcpy(t, (char*)&cl.stats[i], sizeof(t));
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(t);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, t);
 }
 
 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
-static void VM_CL_setmodelindex (void)
+static void VM_CL_setmodelindex (prvm_prog_t *prog)
 {
        int                             i;
        prvm_edict_t    *t;
@@ -1256,23 +1248,23 @@ static void VM_CL_setmodelindex (void)
        model = CL_GetModelByIndex(i);
        if (!model)
        {
-               VM_Warning("VM_CL_setmodelindex: null model\n");
+               VM_Warning(prog, "VM_CL_setmodelindex: null model\n");
                return;
        }
-       PRVM_clientedictstring(t, model) = PRVM_SetEngineString(model->name);
+       PRVM_clientedictstring(t, model) = PRVM_SetEngineString(prog, model->name);
        PRVM_clientedictfloat(t, modelindex) = i;
 
        // TODO: check if this breaks needed consistency and maybe add a cvar for it too?? [1/10/2008 Black]
        if (model)
        {
-               SetMinMaxSize (t, model->normalmins, model->normalmaxs);
+               SetMinMaxSize (prog, t, model->normalmins, model->normalmaxs);
        }
        else
-               SetMinMaxSize (t, vec3_origin, vec3_origin);
+               SetMinMaxSize (prog, t, vec3_origin, vec3_origin);
 }
 
 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
-static void VM_CL_modelnameforindex (void)
+static void VM_CL_modelnameforindex (prvm_prog_t *prog)
 {
        dp_model_t *model;
 
@@ -1280,11 +1272,11 @@ static void VM_CL_modelnameforindex (void)
 
        PRVM_G_INT(OFS_RETURN) = OFS_NULL;
        model = CL_GetModelByIndex((int)PRVM_G_FLOAT(OFS_PARM0));
-       PRVM_G_INT(OFS_RETURN) = model ? PRVM_SetEngineString(model->name) : 0;
+       PRVM_G_INT(OFS_RETURN) = model ? PRVM_SetEngineString(prog, model->name) : 0;
 }
 
 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
-static void VM_CL_particleeffectnum (void)
+static void VM_CL_particleeffectnum (prvm_prog_t *prog)
 {
        int                     i;
        VM_SAFEPARMCOUNT(1, VM_CL_particleeffectnum);
@@ -1295,7 +1287,7 @@ static void VM_CL_particleeffectnum (void)
 }
 
 // #336 void(entity ent, float effectnum, vector start, vector end[, float color]) trailparticles (EXT_CSQC)
-static void VM_CL_trailparticles (void)
+static void VM_CL_trailparticles (prvm_prog_t *prog)
 {
        int                             i;
        float                   *start, *end;
@@ -1313,7 +1305,7 @@ static void VM_CL_trailparticles (void)
 }
 
 //#337 void(float effectnum, vector origin, vector dir, float count[, float color]) pointparticles (EXT_CSQC)
-static void VM_CL_pointparticles (void)
+static void VM_CL_pointparticles (prvm_prog_t *prog)
 {
        int                     i;
        float n;
@@ -1329,7 +1321,7 @@ static void VM_CL_pointparticles (void)
 }
 
 //#502 void(float effectnum, entity own, vector origin_from, vector origin_to, vector dir_from, vector dir_to, float count, float extflags) boxparticles (DP_CSQC_BOXPARTICLES)
-static void VM_CL_boxparticles (void)
+static void VM_CL_boxparticles (prvm_prog_t *prog)
 {
        int effectnum;
        // prvm_edict_t *own;
@@ -1368,7 +1360,7 @@ static void VM_CL_boxparticles (void)
 }
 
 //#531 void(float pause) setpause
-static void VM_CL_setpause(void) 
+static void VM_CL_setpause(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_CL_setpause);
        if ((int)PRVM_G_FLOAT(OFS_PARM0) != 0)
@@ -1378,7 +1370,7 @@ static void VM_CL_setpause(void)
 }
 
 //#343 void(float usecursor) setcursormode (DP_CSQC)
-static void VM_CL_setcursormode (void)
+static void VM_CL_setcursormode (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_CL_setcursormode);
        cl.csqc_wantsmousemove = PRVM_G_FLOAT(OFS_PARM0) != 0;
@@ -1386,7 +1378,7 @@ static void VM_CL_setcursormode (void)
 }
 
 //#344 vector() getmousepos (DP_CSQC)
-static void VM_CL_getmousepos(void)
+static void VM_CL_getmousepos(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0,VM_CL_getmousepos);
 
@@ -1399,7 +1391,7 @@ static void VM_CL_getmousepos(void)
 }
 
 //#345 float(float framenum) getinputstate (EXT_CSQC)
-static void VM_CL_getinputstate (void)
+static void VM_CL_getinputstate (prvm_prog_t *prog)
 {
        int i, frame;
        VM_SAFEPARMCOUNT(1, VM_CL_getinputstate);
@@ -1431,19 +1423,19 @@ static void VM_CL_getinputstate (void)
 }
 
 //#346 void(float sens) setsensitivityscaler (EXT_CSQC)
-static void VM_CL_setsensitivityscale (void)
+static void VM_CL_setsensitivityscale (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_CL_setsensitivityscale);
        cl.sensitivityscale = PRVM_G_FLOAT(OFS_PARM0);
 }
 
 //#347 void() runstandardplayerphysics (EXT_CSQC)
-static void VM_CL_runplayerphysics (void)
+static void VM_CL_runplayerphysics (prvm_prog_t *prog)
 {
 }
 
 //#348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
-static void VM_CL_getplayerkey (void)
+static void VM_CL_getplayerkey (prvm_prog_t *prog)
 {
        int                     i;
        char            t[128];
@@ -1508,11 +1500,11 @@ static void VM_CL_getplayerkey (void)
                }
        if(!t[0])
                return;
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(t);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, t);
 }
 
 //#351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
-static void VM_CL_setlistener (void)
+static void VM_CL_setlistener (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(4, VM_CL_setlistener);
        Matrix4x4_FromVectors(&cl.csqc_listenermatrix, PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), PRVM_G_VECTOR(OFS_PARM3), PRVM_G_VECTOR(OFS_PARM0));
@@ -1520,7 +1512,7 @@ static void VM_CL_setlistener (void)
 }
 
 //#352 void(string cmdname) registercommand (EXT_CSQC)
-static void VM_CL_registercmd (void)
+static void VM_CL_registercmd (prvm_prog_t *prog)
 {
        char *t;
        VM_SAFEPARMCOUNT(1, VM_CL_registercmd);
@@ -1539,64 +1531,64 @@ static void VM_CL_registercmd (void)
 }
 
 //#360 float() readbyte (EXT_CSQC)
-static void VM_CL_ReadByte (void)
+static void VM_CL_ReadByte (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0, VM_CL_ReadByte);
-       PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadByte();
+       PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadByte(&cl_message);
 }
 
 //#361 float() readchar (EXT_CSQC)
-static void VM_CL_ReadChar (void)
+static void VM_CL_ReadChar (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0, VM_CL_ReadChar);
-       PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadChar();
+       PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadChar(&cl_message);
 }
 
 //#362 float() readshort (EXT_CSQC)
-static void VM_CL_ReadShort (void)
+static void VM_CL_ReadShort (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0, VM_CL_ReadShort);
-       PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadShort();
+       PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadShort(&cl_message);
 }
 
 //#363 float() readlong (EXT_CSQC)
-static void VM_CL_ReadLong (void)
+static void VM_CL_ReadLong (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0, VM_CL_ReadLong);
-       PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadLong();
+       PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadLong(&cl_message);
 }
 
 //#364 float() readcoord (EXT_CSQC)
-static void VM_CL_ReadCoord (void)
+static void VM_CL_ReadCoord (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0, VM_CL_ReadCoord);
-       PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadCoord(cls.protocol);
+       PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadCoord(&cl_message, cls.protocol);
 }
 
 //#365 float() readangle (EXT_CSQC)
-static void VM_CL_ReadAngle (void)
+static void VM_CL_ReadAngle (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0, VM_CL_ReadAngle);
-       PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadAngle(cls.protocol);
+       PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadAngle(&cl_message, cls.protocol);
 }
 
 //#366 string() readstring (EXT_CSQC)
-static void VM_CL_ReadString (void)
+static void VM_CL_ReadString (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0, VM_CL_ReadString);
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(MSG_ReadString());
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)));
 }
 
 //#367 float() readfloat (EXT_CSQC)
-static void VM_CL_ReadFloat (void)
+static void VM_CL_ReadFloat (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0, VM_CL_ReadFloat);
-       PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadFloat();
+       PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadFloat(&cl_message);
 }
 
 //#501 string() readpicture (DP_CSQC_READWRITEPICTURE)
 extern cvar_t cl_readpicture_force;
-static void VM_CL_ReadPicture (void)
+static void VM_CL_ReadPicture (prvm_prog_t *prog)
 {
        const char *name;
        unsigned char *data;
@@ -1607,8 +1599,8 @@ static void VM_CL_ReadPicture (void)
 
        VM_SAFEPARMCOUNT(0, VM_CL_ReadPicture);
 
-       name = MSG_ReadString();
-       size = MSG_ReadShort();
+       name = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
+       size = MSG_ReadShort(&cl_message);
 
        // check if a texture of that name exists
        // if yes, it is used and the data is discarded
@@ -1625,14 +1617,14 @@ static void VM_CL_ReadPicture (void)
                        // texture found and loaded
                        // skip over the jpeg as we don't need it
                        for(i = 0; i < size; ++i)
-                               (void) MSG_ReadByte();
+                               (void) MSG_ReadByte(&cl_message);
                }
                else
                {
                        // texture not found
                        // use the attached jpeg as texture
                        buf = (unsigned char *) Mem_Alloc(tempmempool, size);
-                       MSG_ReadBytes(size, buf);
+                       MSG_ReadBytes(&cl_message, size, buf);
                        data = JPEG_LoadImage_BGRA(buf, size, NULL);
                        Mem_Free(buf);
                        Draw_NewPic(name, image_width, image_height, false, data);
@@ -1640,12 +1632,12 @@ static void VM_CL_ReadPicture (void)
                }
        }
 
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(name);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, name);
 }
 
 //////////////////////////////////////////////////////////
 
-static void VM_CL_makestatic (void)
+static void VM_CL_makestatic (prvm_prog_t *prog)
 {
        prvm_edict_t *ent;
 
@@ -1654,12 +1646,12 @@ static void VM_CL_makestatic (void)
        ent = PRVM_G_EDICT(OFS_PARM0);
        if (ent == prog->edicts)
        {
-               VM_Warning("makestatic: can not modify world entity\n");
+               VM_Warning(prog, "makestatic: can not modify world entity\n");
                return;
        }
        if (ent->priv.server->free)
        {
-               VM_Warning("makestatic: can not modify free entity\n");
+               VM_Warning(prog, "makestatic: can not modify free entity\n");
                return;
        }
 
@@ -1728,7 +1720,7 @@ static void VM_CL_makestatic (void)
                Con_Printf("Too many static entities");
 
 // throw the entity away now
-       PRVM_ED_Free (ent);
+       PRVM_ED_Free(prog, ent);
 }
 
 //=================================================================//
@@ -1742,30 +1734,30 @@ copies data from one entity to another
 copyentity(src, dst)
 =================
 */
-static void VM_CL_copyentity (void)
+static void VM_CL_copyentity (prvm_prog_t *prog)
 {
        prvm_edict_t *in, *out;
        VM_SAFEPARMCOUNT(2, VM_CL_copyentity);
        in = PRVM_G_EDICT(OFS_PARM0);
        if (in == prog->edicts)
        {
-               VM_Warning("copyentity: can not read world entity\n");
+               VM_Warning(prog, "copyentity: can not read world entity\n");
                return;
        }
        if (in->priv.server->free)
        {
-               VM_Warning("copyentity: can not read free entity\n");
+               VM_Warning(prog, "copyentity: can not read free entity\n");
                return;
        }
        out = PRVM_G_EDICT(OFS_PARM1);
        if (out == prog->edicts)
        {
-               VM_Warning("copyentity: can not modify world entity\n");
+               VM_Warning(prog, "copyentity: can not modify world entity\n");
                return;
        }
        if (out->priv.server->free)
        {
-               VM_Warning("copyentity: can not modify free entity\n");
+               VM_Warning(prog, "copyentity: can not modify free entity\n");
                return;
        }
        memcpy(out->fields.vp, in->fields.vp, prog->entityfields * 4);
@@ -1775,14 +1767,14 @@ static void VM_CL_copyentity (void)
 //=================================================================//
 
 // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
-static void VM_CL_effect (void)
+static void VM_CL_effect (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(5, VM_CL_effect);
        CL_Effect(PRVM_G_VECTOR(OFS_PARM0), (int)PRVM_G_FLOAT(OFS_PARM1), (int)PRVM_G_FLOAT(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), PRVM_G_FLOAT(OFS_PARM4));
 }
 
 // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
-static void VM_CL_te_blood (void)
+static void VM_CL_te_blood (prvm_prog_t *prog)
 {
        float   *pos;
        vec3_t  pos2;
@@ -1795,7 +1787,7 @@ static void VM_CL_te_blood (void)
 }
 
 // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
-static void VM_CL_te_bloodshower (void)
+static void VM_CL_te_bloodshower (prvm_prog_t *prog)
 {
        vec_t speed;
        vec3_t vel1, vel2;
@@ -1813,7 +1805,7 @@ static void VM_CL_te_bloodshower (void)
 }
 
 // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
-static void VM_CL_te_explosionrgb (void)
+static void VM_CL_te_explosionrgb (prvm_prog_t *prog)
 {
        float           *pos;
        vec3_t          pos2;
@@ -1827,28 +1819,28 @@ static void VM_CL_te_explosionrgb (void)
 }
 
 // #408 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube (DP_TE_PARTICLECUBE)
-static void VM_CL_te_particlecube (void)
+static void VM_CL_te_particlecube (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(7, VM_CL_te_particlecube);
        CL_ParticleCube(PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4), PRVM_G_FLOAT(OFS_PARM5), PRVM_G_FLOAT(OFS_PARM6));
 }
 
 // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
-static void VM_CL_te_particlerain (void)
+static void VM_CL_te_particlerain (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(5, VM_CL_te_particlerain);
        CL_ParticleRain(PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4), 0);
 }
 
 // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
-static void VM_CL_te_particlesnow (void)
+static void VM_CL_te_particlesnow (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(5, VM_CL_te_particlesnow);
        CL_ParticleRain(PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4), 1);
 }
 
 // #411 void(vector org, vector vel, float howmany) te_spark
-static void VM_CL_te_spark (void)
+static void VM_CL_te_spark (prvm_prog_t *prog)
 {
        float           *pos;
        vec3_t          pos2;
@@ -1861,7 +1853,7 @@ static void VM_CL_te_spark (void)
 
 extern cvar_t cl_sound_ric_gunshot;
 // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
-static void VM_CL_te_gunshotquad (void)
+static void VM_CL_te_gunshotquad (prvm_prog_t *prog)
 {
        float           *pos;
        vec3_t          pos2;
@@ -1885,7 +1877,7 @@ static void VM_CL_te_gunshotquad (void)
 }
 
 // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
-static void VM_CL_te_spikequad (void)
+static void VM_CL_te_spikequad (prvm_prog_t *prog)
 {
        float           *pos;
        vec3_t          pos2;
@@ -1906,7 +1898,7 @@ static void VM_CL_te_spikequad (void)
 }
 
 // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
-static void VM_CL_te_superspikequad (void)
+static void VM_CL_te_superspikequad (prvm_prog_t *prog)
 {
        float           *pos;
        vec3_t          pos2;
@@ -1927,7 +1919,7 @@ static void VM_CL_te_superspikequad (void)
 }
 
 // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
-static void VM_CL_te_explosionquad (void)
+static void VM_CL_te_explosionquad (prvm_prog_t *prog)
 {
        float           *pos;
        vec3_t          pos2;
@@ -1940,7 +1932,7 @@ static void VM_CL_te_explosionquad (void)
 }
 
 // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
-static void VM_CL_te_smallflash (void)
+static void VM_CL_te_smallflash (prvm_prog_t *prog)
 {
        float           *pos;
        vec3_t          pos2;
@@ -1952,7 +1944,7 @@ static void VM_CL_te_smallflash (void)
 }
 
 // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
-static void VM_CL_te_customflash (void)
+static void VM_CL_te_customflash (prvm_prog_t *prog)
 {
        float           *pos;
        vec3_t          pos2;
@@ -1966,7 +1958,7 @@ static void VM_CL_te_customflash (void)
 }
 
 // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
-static void VM_CL_te_gunshot (void)
+static void VM_CL_te_gunshot (prvm_prog_t *prog)
 {
        float           *pos;
        vec3_t          pos2;
@@ -1990,7 +1982,7 @@ static void VM_CL_te_gunshot (void)
 }
 
 // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
-static void VM_CL_te_spike (void)
+static void VM_CL_te_spike (prvm_prog_t *prog)
 {
        float           *pos;
        vec3_t          pos2;
@@ -2011,7 +2003,7 @@ static void VM_CL_te_spike (void)
 }
 
 // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
-static void VM_CL_te_superspike (void)
+static void VM_CL_te_superspike (prvm_prog_t *prog)
 {
        float           *pos;
        vec3_t          pos2;
@@ -2032,7 +2024,7 @@ static void VM_CL_te_superspike (void)
 }
 
 // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
-static void VM_CL_te_explosion (void)
+static void VM_CL_te_explosion (prvm_prog_t *prog)
 {
        float           *pos;
        vec3_t          pos2;
@@ -2045,7 +2037,7 @@ static void VM_CL_te_explosion (void)
 }
 
 // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
-static void VM_CL_te_tarexplosion (void)
+static void VM_CL_te_tarexplosion (prvm_prog_t *prog)
 {
        float           *pos;
        vec3_t          pos2;
@@ -2058,7 +2050,7 @@ static void VM_CL_te_tarexplosion (void)
 }
 
 // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
-static void VM_CL_te_wizspike (void)
+static void VM_CL_te_wizspike (prvm_prog_t *prog)
 {
        float           *pos;
        vec3_t          pos2;
@@ -2071,7 +2063,7 @@ static void VM_CL_te_wizspike (void)
 }
 
 // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
-static void VM_CL_te_knightspike (void)
+static void VM_CL_te_knightspike (prvm_prog_t *prog)
 {
        float           *pos;
        vec3_t          pos2;
@@ -2084,21 +2076,21 @@ static void VM_CL_te_knightspike (void)
 }
 
 // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
-static void VM_CL_te_lavasplash (void)
+static void VM_CL_te_lavasplash (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_CL_te_lavasplash);
        CL_ParticleEffect(EFFECT_TE_LAVASPLASH, 1, PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM0), vec3_origin, vec3_origin, NULL, 0);
 }
 
 // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
-static void VM_CL_te_teleport (void)
+static void VM_CL_te_teleport (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_CL_te_teleport);
        CL_ParticleEffect(EFFECT_TE_TELEPORT, 1, PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM0), vec3_origin, vec3_origin, NULL, 0);
 }
 
 // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
-static void VM_CL_te_explosion2 (void)
+static void VM_CL_te_explosion2 (prvm_prog_t *prog)
 {
        float           *pos;
        vec3_t          pos2, color;
@@ -2123,35 +2115,35 @@ static void VM_CL_te_explosion2 (void)
 
 
 // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
-static void VM_CL_te_lightning1 (void)
+static void VM_CL_te_lightning1 (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(3, VM_CL_te_lightning1);
        CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_bolt, true);
 }
 
 // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
-static void VM_CL_te_lightning2 (void)
+static void VM_CL_te_lightning2 (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(3, VM_CL_te_lightning2);
        CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_bolt2, true);
 }
 
 // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
-static void VM_CL_te_lightning3 (void)
+static void VM_CL_te_lightning3 (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(3, VM_CL_te_lightning3);
        CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_bolt3, false);
 }
 
 // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
-static void VM_CL_te_beam (void)
+static void VM_CL_te_beam (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(3, VM_CL_te_beam);
        CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_beam, false);
 }
 
 // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
-static void VM_CL_te_plasmaburn (void)
+static void VM_CL_te_plasmaburn (prvm_prog_t *prog)
 {
        float           *pos;
        vec3_t          pos2;
@@ -2163,7 +2155,7 @@ static void VM_CL_te_plasmaburn (void)
 }
 
 // #457 void(vector org, vector velocity, float howmany) te_flamejet (DP_TE_FLAMEJET)
-static void VM_CL_te_flamejet (void)
+static void VM_CL_te_flamejet (prvm_prog_t *prog)
 {
        float *pos;
        vec3_t pos2;
@@ -2177,7 +2169,7 @@ static void VM_CL_te_flamejet (void)
 
 
 // #443 void(entity e, entity tagentity, string tagname) setattachment
-void VM_CL_setattachment (void)
+static void VM_CL_setattachment (prvm_prog_t *prog)
 {
        prvm_edict_t *e;
        prvm_edict_t *tagentity;
@@ -2193,12 +2185,12 @@ void VM_CL_setattachment (void)
 
        if (e == prog->edicts)
        {
-               VM_Warning("setattachment: can not modify world entity\n");
+               VM_Warning(prog, "setattachment: can not modify world entity\n");
                return;
        }
        if (e->priv.server->free)
        {
-               VM_Warning("setattachment: can not modify free entity\n");
+               VM_Warning(prog, "setattachment: can not modify free entity\n");
                return;
        }
 
@@ -2227,7 +2219,7 @@ void VM_CL_setattachment (void)
 /////////////////////////////////////////
 // DP_MD3_TAGINFO extension coded by VorteX
 
-int CL_GetTagIndex (prvm_edict_t *e, const char *tagname)
+static int CL_GetTagIndex (prvm_prog_t *prog, prvm_edict_t *e, const char *tagname)
 {
        dp_model_t *model = CL_GetModelFromEdict(e);
        if (model)
@@ -2236,7 +2228,7 @@ int CL_GetTagIndex (prvm_edict_t *e, const char *tagname)
                return -1;
 }
 
-int CL_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
+static int CL_GetExtendedTagInfo (prvm_prog_t *prog, prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
 {
        int r;
        dp_model_t *model;
@@ -2260,7 +2252,7 @@ int CL_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, cons
        return 1;
 }
 
-int CL_GetPitchSign(prvm_edict_t *ent)
+int CL_GetPitchSign(prvm_prog_t *prog, prvm_edict_t *ent)
 {
        dp_model_t *model;
        if ((model = CL_GetModelFromEdict(ent)) && model->type == mod_alias)
@@ -2268,7 +2260,7 @@ int CL_GetPitchSign(prvm_edict_t *ent)
        return 1;
 }
 
-void CL_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
+void CL_GetEntityMatrix (prvm_prog_t *prog, prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
 {
        float scale;
        float pitchsign = 1;
@@ -2293,21 +2285,21 @@ void CL_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatri
        }
        else
        {
-               pitchsign = CL_GetPitchSign(ent);
+               pitchsign = CL_GetPitchSign(prog, ent);
                Matrix4x4_CreateFromQuakeEntity(out, PRVM_clientedictvector(ent, origin)[0], PRVM_clientedictvector(ent, origin)[1], PRVM_clientedictvector(ent, origin)[2], pitchsign * PRVM_clientedictvector(ent, angles)[0], PRVM_clientedictvector(ent, angles)[1], PRVM_clientedictvector(ent, angles)[2], scale);
        }
 }
 
-int CL_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
+static int CL_GetEntityLocalTagMatrix(prvm_prog_t *prog, prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
 {
        dp_model_t *model;
        if (tagindex >= 0
         && (model = CL_GetModelFromEdict(ent))
         && model->animscenes)
        {
-               VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
+               VM_GenerateFrameGroupBlend(prog, ent->priv.server->framegroupblend, ent);
                VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
-               VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
+               VM_UpdateEdictSkeleton(prog, ent, model, ent->priv.server->frameblend);
                return Mod_Alias_GetTagMatrix(model, ent->priv.server->frameblend, &ent->priv.server->skeleton, tagindex, out);
        }
        *out = identitymatrix;
@@ -2324,7 +2316,7 @@ int CL_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out
 extern cvar_t cl_bob;
 extern cvar_t cl_bobcycle;
 extern cvar_t cl_bobup;
-int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
+int CL_GetTagMatrix (prvm_prog_t *prog, matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
 {
        int ret;
        int attachloop;
@@ -2350,10 +2342,10 @@ int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
                        return 5;
                // apply transformation by child's tagindex on parent entity and then
                // by parent entity itself
-               ret = CL_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
+               ret = CL_GetEntityLocalTagMatrix(prog, ent, tagindex - 1, &attachmatrix);
                if(ret && attachloop == 0)
                        return ret;
-               CL_GetEntityMatrix(ent, &entitymatrix, false);
+               CL_GetEntityMatrix(prog, ent, &entitymatrix, false);
                Matrix4x4_Concat(&tagmatrix, &attachmatrix, out);
                Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
                // next iteration we process the parent entity
@@ -2372,7 +2364,7 @@ int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
        {
                Matrix4x4_Copy(&tagmatrix, out);
 
-               CL_GetEntityMatrix(prog->edicts, &entitymatrix, true);
+               CL_GetEntityMatrix(prog, prog->edicts, &entitymatrix, true);
                Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
 
                /*
@@ -2402,7 +2394,7 @@ int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
 }
 
 // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
-void VM_CL_gettagindex (void)
+static void VM_CL_gettagindex (prvm_prog_t *prog)
 {
        prvm_edict_t *ent;
        const char *tag_name;
@@ -2414,12 +2406,12 @@ void VM_CL_gettagindex (void)
        tag_name = PRVM_G_STRING(OFS_PARM1);
        if (ent == prog->edicts)
        {
-               VM_Warning("VM_CL_gettagindex(entity #%i): can't affect world entity\n", PRVM_NUM_FOR_EDICT(ent));
+               VM_Warning(prog, "VM_CL_gettagindex(entity #%i): can't affect world entity\n", PRVM_NUM_FOR_EDICT(ent));
                return;
        }
        if (ent->priv.server->free)
        {
-               VM_Warning("VM_CL_gettagindex(entity #%i): can't affect free entity\n", PRVM_NUM_FOR_EDICT(ent));
+               VM_Warning(prog, "VM_CL_gettagindex(entity #%i): can't affect free entity\n", PRVM_NUM_FOR_EDICT(ent));
                return;
        }
 
@@ -2428,7 +2420,7 @@ void VM_CL_gettagindex (void)
                Con_DPrintf("VM_CL_gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
        else
        {
-               tag_index = CL_GetTagIndex(ent, tag_name);
+               tag_index = CL_GetTagIndex(prog, ent, tag_name);
                if (tag_index == 0)
                        Con_DPrintf("VM_CL_gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
        }
@@ -2436,7 +2428,7 @@ void VM_CL_gettagindex (void)
 }
 
 // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
-void VM_CL_gettaginfo (void)
+static void VM_CL_gettaginfo (prvm_prog_t *prog)
 {
        prvm_edict_t *e;
        int tagindex;
@@ -2452,18 +2444,18 @@ void VM_CL_gettaginfo (void)
 
        e = PRVM_G_EDICT(OFS_PARM0);
        tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
-       returncode = CL_GetTagMatrix(&tag_matrix, e, tagindex);
+       returncode = CL_GetTagMatrix(prog, &tag_matrix, e, tagindex);
        Matrix4x4_ToVectors(&tag_matrix, PRVM_clientglobalvector(v_forward), le, PRVM_clientglobalvector(v_up), PRVM_G_VECTOR(OFS_RETURN));
        VectorScale(le, -1, PRVM_clientglobalvector(v_right));
        model = CL_GetModelFromEdict(e);
-       VM_GenerateFrameGroupBlend(e->priv.server->framegroupblend, e);
+       VM_GenerateFrameGroupBlend(prog, e->priv.server->framegroupblend, e);
        VM_FrameBlendFromFrameGroupBlend(e->priv.server->frameblend, e->priv.server->framegroupblend, model);
-       VM_UpdateEdictSkeleton(e, model, e->priv.server->frameblend);
-       CL_GetExtendedTagInfo(e, tagindex, &parentindex, &tagname, &tag_localmatrix);
+       VM_UpdateEdictSkeleton(prog, e, model, e->priv.server->frameblend);
+       CL_GetExtendedTagInfo(prog, e, tagindex, &parentindex, &tagname, &tag_localmatrix);
        Matrix4x4_ToVectors(&tag_localmatrix, fo, le, up, trans);
 
        PRVM_clientglobalfloat(gettaginfo_parent) = parentindex;
-       PRVM_clientglobalstring(gettaginfo_name) = tagname ? PRVM_SetTempString(tagname) : 0;
+       PRVM_clientglobalstring(gettaginfo_name) = tagname ? PRVM_SetTempString(prog, tagname) : 0;
        VectorCopy(trans, PRVM_clientglobalvector(gettaginfo_offset));
        VectorCopy(fo, PRVM_clientglobalvector(gettaginfo_forward));
        VectorScale(le, -1, PRVM_clientglobalvector(gettaginfo_right));
@@ -2472,10 +2464,10 @@ void VM_CL_gettaginfo (void)
        switch(returncode)
        {
                case 1:
-                       VM_Warning("gettagindex: can't affect world entity\n");
+                       VM_Warning(prog, "gettagindex: can't affect world entity\n");
                        break;
                case 2:
-                       VM_Warning("gettagindex: can't affect free entity\n");
+                       VM_Warning(prog, "gettagindex: can't affect free entity\n");
                        break;
                case 3:
                        Con_DPrintf("CL_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
@@ -2572,7 +2564,7 @@ typedef struct vmparticlespawner_s
 vmparticlespawner_t vmpartspawner;
 
 // TODO: automatic max_themes grow
-static void VM_InitParticleSpawner (int maxthemes)
+static void VM_InitParticleSpawner (prvm_prog_t *prog, int maxthemes)
 {
        // bound max themes to not be an insane value
        if (maxthemes < 4)
@@ -2657,7 +2649,7 @@ static void VM_ResetParticleTheme (vmparticletheme_t *theme)
 }
 
 // particle theme -> QC globals
-void VM_CL_ParticleThemeToGlobals(vmparticletheme_t *theme)
+static void VM_CL_ParticleThemeToGlobals(vmparticletheme_t *theme)
 {
        *vmpartspawner.particle_type = theme->typeindex;
        *vmpartspawner.particle_blendmode = theme->blendmode;
@@ -2698,7 +2690,7 @@ void VM_CL_ParticleThemeToGlobals(vmparticletheme_t *theme)
 }
 
 // QC globals ->  particle theme
-void VM_CL_ParticleThemeFromGlobals(vmparticletheme_t *theme)
+static void VM_CL_ParticleThemeFromGlobals(vmparticletheme_t *theme)
 {
        theme->typeindex = (unsigned short)*vmpartspawner.particle_type;
        theme->blendmode = (pblend_t)(int)*vmpartspawner.particle_blendmode;
@@ -2732,48 +2724,48 @@ void VM_CL_ParticleThemeFromGlobals(vmparticletheme_t *theme)
 
 // init particle spawner interface
 // # float(float max_themes) initparticlespawner
-void VM_CL_InitParticleSpawner (void)
+static void VM_CL_InitParticleSpawner (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNTRANGE(0, 1, VM_CL_InitParticleSpawner);
-       VM_InitParticleSpawner((int)PRVM_G_FLOAT(OFS_PARM0));
+       VM_InitParticleSpawner(prog, (int)PRVM_G_FLOAT(OFS_PARM0));
        vmpartspawner.themes[0].initialized = true;
        VM_ResetParticleTheme(&vmpartspawner.themes[0]);
        PRVM_G_FLOAT(OFS_RETURN) = (vmpartspawner.verified == true) ? 1 : 0;
 }
 
 // void() resetparticle
-void VM_CL_ResetParticle (void)
+static void VM_CL_ResetParticle (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0, VM_CL_ResetParticle);
        if (vmpartspawner.verified == false)
        {
-               VM_Warning("VM_CL_ResetParticle: particle spawner not initialized\n");
+               VM_Warning(prog, "VM_CL_ResetParticle: particle spawner not initialized\n");
                return;
        }
        VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[0]);
 }
 
 // void(float themenum) particletheme
-void VM_CL_ParticleTheme (void)
+static void VM_CL_ParticleTheme (prvm_prog_t *prog)
 {
        int themenum;
 
        VM_SAFEPARMCOUNT(1, VM_CL_ParticleTheme);
        if (vmpartspawner.verified == false)
        {
-               VM_Warning("VM_CL_ParticleTheme: particle spawner not initialized\n");
+               VM_Warning(prog, "VM_CL_ParticleTheme: particle spawner not initialized\n");
                return;
        }
        themenum = (int)PRVM_G_FLOAT(OFS_PARM0);
        if (themenum < 0 || themenum >= vmpartspawner.max_themes)
        {
-               VM_Warning("VM_CL_ParticleTheme: bad theme number %i\n", themenum);
+               VM_Warning(prog, "VM_CL_ParticleTheme: bad theme number %i\n", themenum);
                VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[0]);
                return;
        }
        if (vmpartspawner.themes[themenum].initialized == false)
        {
-               VM_Warning("VM_CL_ParticleTheme: theme #%i not exists\n", themenum);
+               VM_Warning(prog, "VM_CL_ParticleTheme: theme #%i not exists\n", themenum);
                VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[0]);
                return;
        }
@@ -2783,14 +2775,14 @@ void VM_CL_ParticleTheme (void)
 
 // float() saveparticletheme
 // void(float themenum) updateparticletheme
-void VM_CL_ParticleThemeSave (void)
+static void VM_CL_ParticleThemeSave (prvm_prog_t *prog)
 {
        int themenum;
 
        VM_SAFEPARMCOUNTRANGE(0, 1, VM_CL_ParticleThemeSave);
        if (vmpartspawner.verified == false)
        {
-               VM_Warning("VM_CL_ParticleThemeSave: particle spawner not initialized\n");
+               VM_Warning(prog, "VM_CL_ParticleThemeSave: particle spawner not initialized\n");
                return;
        }
        // allocate new theme, save it and return
@@ -2802,9 +2794,9 @@ void VM_CL_ParticleThemeSave (void)
                if (themenum >= vmpartspawner.max_themes)
                {
                        if (vmpartspawner.max_themes == 2048)
-                               VM_Warning("VM_CL_ParticleThemeSave: no free theme slots\n");
+                               VM_Warning(prog, "VM_CL_ParticleThemeSave: no free theme slots\n");
                        else
-                               VM_Warning("VM_CL_ParticleThemeSave: no free theme slots, try initparticlespawner() with highter max_themes\n");
+                               VM_Warning(prog, "VM_CL_ParticleThemeSave: no free theme slots, try initparticlespawner() with highter max_themes\n");
                        PRVM_G_FLOAT(OFS_RETURN) = -1;
                        return;
                }
@@ -2817,7 +2809,7 @@ void VM_CL_ParticleThemeSave (void)
        themenum = (int)PRVM_G_FLOAT(OFS_PARM0);
        if (themenum < 0 || themenum >= vmpartspawner.max_themes)
        {
-               VM_Warning("VM_CL_ParticleThemeSave: bad theme number %i\n", themenum);
+               VM_Warning(prog, "VM_CL_ParticleThemeSave: bad theme number %i\n", themenum);
                return;
        }
        vmpartspawner.themes[themenum].initialized = true;
@@ -2825,26 +2817,26 @@ void VM_CL_ParticleThemeSave (void)
 }
 
 // void(float themenum) freeparticletheme
-void VM_CL_ParticleThemeFree (void)
+static void VM_CL_ParticleThemeFree (prvm_prog_t *prog)
 {
        int themenum;
 
        VM_SAFEPARMCOUNT(1, VM_CL_ParticleThemeFree);
        if (vmpartspawner.verified == false)
        {
-               VM_Warning("VM_CL_ParticleThemeFree: particle spawner not initialized\n");
+               VM_Warning(prog, "VM_CL_ParticleThemeFree: particle spawner not initialized\n");
                return;
        }
        themenum = (int)PRVM_G_FLOAT(OFS_PARM0);
        // check parms
        if (themenum <= 0 || themenum >= vmpartspawner.max_themes)
        {
-               VM_Warning("VM_CL_ParticleThemeFree: bad theme number %i\n", themenum);
+               VM_Warning(prog, "VM_CL_ParticleThemeFree: bad theme number %i\n", themenum);
                return;
        }
        if (vmpartspawner.themes[themenum].initialized == false)
        {
-               VM_Warning("VM_CL_ParticleThemeFree: theme #%i already freed\n", themenum);
+               VM_Warning(prog, "VM_CL_ParticleThemeFree: theme #%i already freed\n", themenum);
                VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[0]);
                return;
        }
@@ -2855,7 +2847,7 @@ void VM_CL_ParticleThemeFree (void)
 
 // float(vector org, vector dir, [float theme]) particle
 // returns 0 if failed, 1 if succesful
-void VM_CL_SpawnParticle (void)
+static void VM_CL_SpawnParticle (prvm_prog_t *prog)
 {
        float *org, *dir;
        vmparticletheme_t *theme;
@@ -2865,7 +2857,7 @@ void VM_CL_SpawnParticle (void)
        VM_SAFEPARMCOUNTRANGE(2, 3, VM_CL_SpawnParticle2);
        if (vmpartspawner.verified == false)
        {
-               VM_Warning("VM_CL_SpawnParticle: particle spawner not initialized\n");
+               VM_Warning(prog, "VM_CL_SpawnParticle: particle spawner not initialized\n");
                PRVM_G_FLOAT(OFS_RETURN) = 0; 
                return;
        }
@@ -2890,7 +2882,7 @@ void VM_CL_SpawnParticle (void)
                themenum = (int)PRVM_G_FLOAT(OFS_PARM2);
                if (themenum <= 0 || themenum >= vmpartspawner.max_themes)
                {
-                       VM_Warning("VM_CL_SpawnParticle: bad theme number %i\n", themenum);
+                       VM_Warning(prog, "VM_CL_SpawnParticle: bad theme number %i\n", themenum);
                        PRVM_G_FLOAT(OFS_RETURN) = 0; 
                        return;
                }
@@ -2911,7 +2903,7 @@ void VM_CL_SpawnParticle (void)
 
 // float(vector org, vector dir, float spawndelay, float collisiondelay, [float theme]) delayedparticle
 // returns 0 if failed, 1 if success
-void VM_CL_SpawnParticleDelayed (void)
+static void VM_CL_SpawnParticleDelayed (prvm_prog_t *prog)
 {
        float *org, *dir;
        vmparticletheme_t *theme;
@@ -2921,7 +2913,7 @@ void VM_CL_SpawnParticleDelayed (void)
        VM_SAFEPARMCOUNTRANGE(4, 5, VM_CL_SpawnParticle2);
        if (vmpartspawner.verified == false)
        {
-               VM_Warning("VM_CL_SpawnParticle: particle spawner not initialized\n");
+               VM_Warning(prog, "VM_CL_SpawnParticle: particle spawner not initialized\n");
                PRVM_G_FLOAT(OFS_RETURN) = 0; 
                return;
        }
@@ -2934,7 +2926,7 @@ void VM_CL_SpawnParticleDelayed (void)
                themenum = (int)PRVM_G_FLOAT(OFS_PARM4);
                if (themenum <= 0 || themenum >= vmpartspawner.max_themes)
                {
-                       VM_Warning("VM_CL_SpawnParticle: bad theme number %i\n", themenum);
+                       VM_Warning(prog, "VM_CL_SpawnParticle: bad theme number %i\n", themenum);
                        PRVM_G_FLOAT(OFS_RETURN) = 0;  
                        return;
                }
@@ -2959,7 +2951,7 @@ void VM_CL_SpawnParticleDelayed (void)
 // vector(float entitynum, float whatfld) getentityvec;
 // querying engine-drawn entity
 // VorteX: currently it's only tested with whatfld = 1..7
-void VM_CL_GetEntity (void)
+static void VM_CL_GetEntity (prvm_prog_t *prog)
 {
        int entnum, fieldnum;
        float org[3], v1[3], v2[3];
@@ -3037,55 +3029,14 @@ void VM_CL_GetEntity (void)
 //QC POLYGON functions
 //====================
 
-#define VMPOLYGONS_MAXPOINTS 64
-
-typedef struct vmpolygons_triangle_s
-{
-       rtexture_t              *texture;
-       int                             drawflag;
-       qboolean hasalpha;
-       unsigned short  elements[3];
-}vmpolygons_triangle_t;
-
-typedef struct vmpolygons_s
-{
-       mempool_t               *pool;
-       qboolean                initialized;
-       double          progstarttime;
-
-       int                             max_vertices;
-       int                             num_vertices;
-       float                   *data_vertex3f;
-       float                   *data_color4f;
-       float                   *data_texcoord2f;
-
-       int                             max_triangles;
-       int                             num_triangles;
-       vmpolygons_triangle_t *data_triangles;
-       unsigned short  *data_sortedelement3s;
-
-       qboolean                begin_active;
-       int     begin_draw2d;
-       rtexture_t              *begin_texture;
-       int                             begin_drawflag;
-       int                             begin_vertices;
-       float                   begin_vertex[VMPOLYGONS_MAXPOINTS][3];
-       float                   begin_color[VMPOLYGONS_MAXPOINTS][4];
-       float                   begin_texcoord[VMPOLYGONS_MAXPOINTS][2];
-       qboolean                begin_texture_hasalpha;
-} vmpolygons_t;
-
-// FIXME: make VM_CL_R_Polygon functions use Debug_Polygon functions?
-vmpolygons_t vmpolygons[PRVM_MAXPROGS];
-
 //#304 void() renderscene (EXT_CSQC)
 // moved that here to reset the polygons,
 // resetting them earlier causes R_Mesh_Draw to be called with numvertices = 0
 // --blub
-void VM_CL_R_RenderScene (void)
+static void VM_CL_R_RenderScene (prvm_prog_t *prog)
 {
-       double t = Sys_DoubleTime();
-       vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
+       double t = Sys_DirtyTime();
+       vmpolygons_t *polys = &prog->vmpolygons;
        VM_SAFEPARMCOUNT(0, VM_CL_R_RenderScene);
 
        // we need to update any RENDER_VIEWMODEL entities at this point because
@@ -3096,10 +3047,10 @@ void VM_CL_R_RenderScene (void)
        R_RenderView();
 
        polys->num_vertices = polys->num_triangles = 0;
-       polys->progstarttime = prog->starttime;
 
        // callprofile fixing hack: do not include this time in what is counted for CSQC_UpdateView
-       prog->functions[PRVM_clientfunction(CSQC_UpdateView)].totaltime -= Sys_DoubleTime() - t;
+       t = Sys_DirtyTime() - t;if (t < 0 || t >= 1800) t = 0;
+       prog->functions[PRVM_clientfunction(CSQC_UpdateView)].totaltime -= t;
 }
 
 static void VM_ResizePolygons(vmpolygons_t *polys)
@@ -3150,9 +3101,7 @@ static void VM_InitPolygons (vmpolygons_t* polys)
 static void VM_DrawPolygonCallback (const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
 {
        int surfacelistindex;
-       vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
-       if(polys->progstarttime != prog->starttime) // from other progs? won't draw these (this can cause crashes!)
-               return;
+       vmpolygons_t *polys = (vmpolygons_t *)ent;
 //     R_Mesh_ResetTextureState();
        R_EntityMatrix(&identitymatrix);
        GL_CullFace(GL_NONE);
@@ -3179,7 +3128,7 @@ static void VM_DrawPolygonCallback (const entity_render_t *ent, const rtlight_t
        }
 }
 
-void VMPolygons_Store(vmpolygons_t *polys)
+static void VMPolygons_Store(vmpolygons_t *polys)
 {
        qboolean hasalpha;
        int i;
@@ -3241,10 +3190,10 @@ void VMPolygons_Store(vmpolygons_t *polys)
 
 // TODO: move this into the client code and clean-up everything else, too! [1/6/2008 Black]
 // LordHavoc: agreed, this is a mess
-void VM_CL_AddPolygonsToMeshQueue (void)
+void VM_CL_AddPolygonsToMeshQueue (prvm_prog_t *prog)
 {
        int i;
-       vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
+       vmpolygons_t *polys = &prog->vmpolygons;
        vec3_t center;
 
        // only add polygons of the currently active prog to the queue - if there is none, we're done
@@ -3257,7 +3206,7 @@ void VM_CL_AddPolygonsToMeshQueue (void)
        for (i = 0;i < polys->num_triangles;i++)
        {
                VectorMAMAM(1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].elements[0], 1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].elements[1], 1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].elements[2], center);
-               R_MeshQueue_AddTransparent(center, VM_DrawPolygonCallback, NULL, i, NULL);
+               R_MeshQueue_AddTransparent(center, VM_DrawPolygonCallback, (entity_render_t *)polys, i, NULL);
        }
 
        /*polys->num_triangles = 0; // now done after rendering the scene,
@@ -3265,11 +3214,11 @@ void VM_CL_AddPolygonsToMeshQueue (void)
 }
 
 //void(string texturename, float flag[, float is2d]) R_BeginPolygon
-void VM_CL_R_PolygonBegin (void)
+static void VM_CL_R_PolygonBegin (prvm_prog_t *prog)
 {
        const char              *picname;
        skinframe_t     *sf;
-       vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
+       vmpolygons_t *polys = &prog->vmpolygons;
        int tf;
 
        // TODO instead of using skinframes here (which provides the benefit of
@@ -3280,15 +3229,9 @@ void VM_CL_R_PolygonBegin (void)
 
        if (!polys->initialized)
                VM_InitPolygons(polys);
-       if(polys->progstarttime != prog->starttime)
-       {
-               // from another progs? then reset the polys first (fixes crashes on map change, because that can make skinframe textures invalid)
-               polys->num_vertices = polys->num_triangles = 0;
-               polys->progstarttime = prog->starttime;
-       }
        if (polys->begin_active)
        {
-               VM_Warning("VM_CL_R_PolygonBegin: called twice without VM_CL_R_PolygonBegin after first\n");
+               VM_Warning(prog, "VM_CL_R_PolygonBegin: called twice without VM_CL_R_PolygonBegin after first\n");
                return;
        }
        picname = PRVM_G_STRING(OFS_PARM0);
@@ -3322,21 +3265,21 @@ void VM_CL_R_PolygonBegin (void)
 }
 
 //void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
-void VM_CL_R_PolygonVertex (void)
+static void VM_CL_R_PolygonVertex (prvm_prog_t *prog)
 {
-       vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
+       vmpolygons_t *polys = &prog->vmpolygons;
 
        VM_SAFEPARMCOUNT(4, VM_CL_R_PolygonVertex);
 
        if (!polys->begin_active)
        {
-               VM_Warning("VM_CL_R_PolygonVertex: VM_CL_R_PolygonBegin wasn't called\n");
+               VM_Warning(prog, "VM_CL_R_PolygonVertex: VM_CL_R_PolygonBegin wasn't called\n");
                return;
        }
 
        if (polys->begin_vertices >= VMPOLYGONS_MAXPOINTS)
        {
-               VM_Warning("VM_CL_R_PolygonVertex: may have %i vertices max\n", VMPOLYGONS_MAXPOINTS);
+               VM_Warning(prog, "VM_CL_R_PolygonVertex: may have %i vertices max\n", VMPOLYGONS_MAXPOINTS);
                return;
        }
 
@@ -3353,21 +3296,21 @@ void VM_CL_R_PolygonVertex (void)
 }
 
 //void() R_EndPolygon
-void VM_CL_R_PolygonEnd (void)
+static void VM_CL_R_PolygonEnd (prvm_prog_t *prog)
 {
-       vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
+       vmpolygons_t *polys = &prog->vmpolygons;
 
        VM_SAFEPARMCOUNT(0, VM_CL_R_PolygonEnd);
        if (!polys->begin_active)
        {
-               VM_Warning("VM_CL_R_PolygonEnd: VM_CL_R_PolygonBegin wasn't called\n");
+               VM_Warning(prog, "VM_CL_R_PolygonEnd: VM_CL_R_PolygonBegin wasn't called\n");
                return;
        }
        polys->begin_active = false;
        if (polys->begin_vertices >= 3)
                VMPolygons_Store(polys);
        else
-               VM_Warning("VM_CL_R_PolygonEnd: %i vertices isn't a good choice\n", polys->begin_vertices);
+               VM_Warning(prog, "VM_CL_R_PolygonEnd: %i vertices isn't a good choice\n", polys->begin_vertices);
 }
 
 static vmpolygons_t debugPolys;
@@ -3436,8 +3379,9 @@ is not a staircase.
 
 =============
 */
-qboolean CL_CheckBottom (prvm_edict_t *ent)
+static qboolean CL_CheckBottom (prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = CLVM_prog;
        vec3_t  mins, maxs, start, stop;
        trace_t trace;
        int             x, y;
@@ -3504,8 +3448,9 @@ The move will be adjusted for slopes and stairs, but if the move isn't
 possible, no move is done and false is returned
 =============
 */
-qboolean CL_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qboolean noenemy, qboolean settrace)
+static qboolean CL_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qboolean noenemy, qboolean settrace)
 {
+       prvm_prog_t *prog = CLVM_prog;
        float           dz;
        vec3_t          oldorg, neworg, end, traceendpos;
        trace_t         trace;
@@ -3534,7 +3479,7 @@ qboolean CL_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qboolean
                        }
                        trace = CL_TraceBox(PRVM_clientedictvector(ent, origin), PRVM_clientedictvector(ent, mins), PRVM_clientedictvector(ent, maxs), neworg, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, &svent, true);
                        if (settrace)
-                               CL_VM_SetTraceGlobals(&trace, svent);
+                               CL_VM_SetTraceGlobals(prog, &trace, svent);
 
                        if (trace.fraction == 1)
                        {
@@ -3562,14 +3507,14 @@ qboolean CL_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qboolean
 
        trace = CL_TraceBox(neworg, PRVM_clientedictvector(ent, mins), PRVM_clientedictvector(ent, maxs), end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, &svent, true);
        if (settrace)
-               CL_VM_SetTraceGlobals(&trace, svent);
+               CL_VM_SetTraceGlobals(prog, &trace, svent);
 
        if (trace.startsolid)
        {
                neworg[2] -= sv_stepheight.value;
                trace = CL_TraceBox(neworg, PRVM_clientedictvector(ent, mins), PRVM_clientedictvector(ent, maxs), end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, &svent, true);
                if (settrace)
-                       CL_VM_SetTraceGlobals(&trace, svent);
+                       CL_VM_SetTraceGlobals(prog, &trace, svent);
                if (trace.startsolid)
                        return false;
        }
@@ -3622,7 +3567,7 @@ VM_CL_walkmove
 float(float yaw, float dist[, settrace]) walkmove
 ===============
 */
-static void VM_CL_walkmove (void)
+static void VM_CL_walkmove (prvm_prog_t *prog)
 {
        prvm_edict_t    *ent;
        float   yaw, dist;
@@ -3639,12 +3584,12 @@ static void VM_CL_walkmove (void)
        ent = PRVM_PROG_TO_EDICT(PRVM_clientglobaledict(self));
        if (ent == prog->edicts)
        {
-               VM_Warning("walkmove: can not modify world entity\n");
+               VM_Warning(prog, "walkmove: can not modify world entity\n");
                return;
        }
        if (ent->priv.server->free)
        {
-               VM_Warning("walkmove: can not modify free entity\n");
+               VM_Warning(prog, "walkmove: can not modify free entity\n");
                return;
        }
        yaw = PRVM_G_FLOAT(OFS_PARM0);
@@ -3679,12 +3624,12 @@ VM_CL_serverkey
 string(string key) serverkey
 ===============
 */
-void VM_CL_serverkey(void)
+static void VM_CL_serverkey(prvm_prog_t *prog)
 {
        char string[VM_STRINGTEMP_LENGTH];
        VM_SAFEPARMCOUNT(1, VM_CL_serverkey);
        InfoString_GetValue(cl.qw_serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, string);
 }
 
 /*
@@ -3697,7 +3642,7 @@ Should be fast but can be inexact.
 float checkpvs(vector viewpos, entity viewee) = #240;
 =================
 */
-static void VM_CL_checkpvs (void)
+static void VM_CL_checkpvs (prvm_prog_t *prog)
 {
        vec3_t viewpos;
        prvm_edict_t *viewee;
@@ -3715,7 +3660,7 @@ static void VM_CL_checkpvs (void)
 
        if(viewee->priv.required->free)
        {
-               VM_Warning("checkpvs: can not check free entity\n");
+               VM_Warning(prog, "checkpvs: can not check free entity\n");
                PRVM_G_FLOAT(OFS_RETURN) = 4;
                return;
        }
@@ -3758,7 +3703,7 @@ static void VM_CL_checkpvs (void)
 }
 
 // #263 float(float modlindex) skel_create = #263; // (FTE_CSQC_SKELETONOBJECTS) create a skeleton (be sure to assign this value into .skeletonindex for use), returns skeleton index (1 or higher) on success, returns 0 on failure  (for example if the modelindex is not skeletal), it is recommended that you create a new skeleton if you change modelindex.
-static void VM_CL_skel_create(void)
+static void VM_CL_skel_create(prvm_prog_t *prog)
 {
        int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
        dp_model_t *model = CL_GetModelByIndex(modelindex);
@@ -3782,7 +3727,7 @@ static void VM_CL_skel_create(void)
 }
 
 // #264 float(float skel, entity ent, float modlindex, float retainfrac, float firstbone, float lastbone) skel_build = #264; // (FTE_CSQC_SKELETONOBJECTS) blend in a percentage of standard animation, 0 replaces entirely, 1 does nothing, 0.5 blends half, etc, and this only alters the bones in the specified range for which out of bounds values like 0,100000 are safe (uses .frame, .frame2, .frame3, .frame4, .lerpfrac, .lerpfrac3, .lerpfrac4, .frame1time, .frame2time, .frame3time, .frame4time), returns skel on success, 0 on failure
-static void VM_CL_skel_build(void)
+static void VM_CL_skel_build(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        skeleton_t *skeleton;
@@ -3806,7 +3751,7 @@ static void VM_CL_skel_build(void)
        firstbone = max(0, firstbone);
        lastbone = min(lastbone, model->num_bones - 1);
        lastbone = min(lastbone, skeleton->model->num_bones - 1);
-       VM_GenerateFrameGroupBlend(framegroupblend, ed);
+       VM_GenerateFrameGroupBlend(prog, framegroupblend, ed);
        VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model);
        blendfrac = 1.0f - retainfrac;
        for (numblends = 0;numblends < MAX_FRAMEBLENDS && frameblend[numblends].lerp;numblends++)
@@ -3826,7 +3771,7 @@ static void VM_CL_skel_build(void)
 }
 
 // #265 float(float skel) skel_get_numbones = #265; // (FTE_CSQC_SKELETONOBJECTS) returns how many bones exist in the created skeleton
-static void VM_CL_skel_get_numbones(void)
+static void VM_CL_skel_get_numbones(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        skeleton_t *skeleton;
@@ -3837,7 +3782,7 @@ static void VM_CL_skel_get_numbones(void)
 }
 
 // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (FTE_CSQC_SKELETONOBJECTS) returns name of bone (as a tempstring)
-static void VM_CL_skel_get_bonename(void)
+static void VM_CL_skel_get_bonename(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
@@ -3847,11 +3792,11 @@ static void VM_CL_skel_get_bonename(void)
                return;
        if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
                return;
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(skeleton->model->data_bones[bonenum].name);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, skeleton->model->data_bones[bonenum].name);
 }
 
 // #267 float(float skel, float bonenum) skel_get_boneparent = #267; // (FTE_CSQC_SKELETONOBJECTS) returns parent num for supplied bonenum, 0 if bonenum has no parent or bone does not exist (returned value is always less than bonenum, you can loop on this)
-static void VM_CL_skel_get_boneparent(void)
+static void VM_CL_skel_get_boneparent(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
@@ -3865,7 +3810,7 @@ static void VM_CL_skel_get_boneparent(void)
 }
 
 // #268 float(float skel, string tagname) skel_find_bone = #268; // (FTE_CSQC_SKELETONOBJECTS) get number of bone with specified name, 0 on failure, tagindex (bonenum+1) on success, same as using gettagindex on the modelindex
-static void VM_CL_skel_find_bone(void)
+static void VM_CL_skel_find_bone(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        const char *tagname = PRVM_G_STRING(OFS_PARM1);
@@ -3877,7 +3822,7 @@ static void VM_CL_skel_find_bone(void)
 }
 
 // #269 vector(float skel, float bonenum) skel_get_bonerel = #269; // (FTE_CSQC_SKELETONOBJECTS) get matrix of bone in skeleton relative to its parent - sets v_forward, v_right, v_up, returns origin (relative to parent bone)
-static void VM_CL_skel_get_bonerel(void)
+static void VM_CL_skel_get_bonerel(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
@@ -3901,7 +3846,7 @@ static void VM_CL_skel_get_bonerel(void)
 }
 
 // #270 vector(float skel, float bonenum) skel_get_boneabs = #270; // (FTE_CSQC_SKELETONOBJECTS) get matrix of bone in skeleton in model space - sets v_forward, v_right, v_up, returns origin (relative to entity)
-static void VM_CL_skel_get_boneabs(void)
+static void VM_CL_skel_get_boneabs(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
@@ -3932,7 +3877,7 @@ static void VM_CL_skel_get_boneabs(void)
 }
 
 // #271 void(float skel, float bonenum, vector org) skel_set_bone = #271; // (FTE_CSQC_SKELETONOBJECTS) set matrix of bone relative to its parent, reads v_forward, v_right, v_up, takes origin as parameter (relative to parent bone)
-static void VM_CL_skel_set_bone(void)
+static void VM_CL_skel_set_bone(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
@@ -3952,7 +3897,7 @@ static void VM_CL_skel_set_bone(void)
 }
 
 // #272 void(float skel, float bonenum, vector org) skel_mul_bone = #272; // (FTE_CSQC_SKELETONOBJECTS) transform bone matrix (relative to its parent) by the supplied matrix in v_forward, v_right, v_up, takes origin as parameter (relative to parent bone)
-static void VM_CL_skel_mul_bone(void)
+static void VM_CL_skel_mul_bone(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
@@ -3974,7 +3919,7 @@ static void VM_CL_skel_mul_bone(void)
 }
 
 // #273 void(float skel, float startbone, float endbone, vector org) skel_mul_bones = #273; // (FTE_CSQC_SKELETONOBJECTS) transform bone matrices (relative to their parents) by the supplied matrix in v_forward, v_right, v_up, takes origin as parameter (relative to parent bones)
-static void VM_CL_skel_mul_bones(void)
+static void VM_CL_skel_mul_bones(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        int firstbone = PRVM_G_FLOAT(OFS_PARM1) - 1;
@@ -4001,7 +3946,7 @@ static void VM_CL_skel_mul_bones(void)
 }
 
 // #274 void(float skeldst, float skelsrc, float startbone, float endbone) skel_copybones = #274; // (FTE_CSQC_SKELETONOBJECTS) copy bone matrices (relative to their parents) from one skeleton to another, useful for copying a skeleton to a corpse
-static void VM_CL_skel_copybones(void)
+static void VM_CL_skel_copybones(prvm_prog_t *prog)
 {
        int skeletonindexdst = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        int skeletonindexsrc = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
@@ -4022,7 +3967,7 @@ static void VM_CL_skel_copybones(void)
 }
 
 // #275 void(float skel) skel_delete = #275; // (FTE_CSQC_SKELETONOBJECTS) deletes skeleton at the beginning of the next frame (you can add the entity, delete the skeleton, renderscene, and it will still work)
-static void VM_CL_skel_delete(void)
+static void VM_CL_skel_delete(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        skeleton_t *skeleton;
@@ -4033,7 +3978,7 @@ static void VM_CL_skel_delete(void)
 }
 
 // #276 float(float modlindex, string framename) frameforname = #276; // (FTE_CSQC_SKELETONOBJECTS) finds number of a specified frame in the animation, returns -1 if no match found
-static void VM_CL_frameforname(void)
+static void VM_CL_frameforname(prvm_prog_t *prog)
 {
        int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
        dp_model_t *model = CL_GetModelByIndex(modelindex);
@@ -4053,7 +3998,7 @@ static void VM_CL_frameforname(void)
 }
 
 // #277 float(float modlindex, float framenum) frameduration = #277; // (FTE_CSQC_SKELETONOBJECTS) returns the intended play time (in seconds) of the specified framegroup, if it does not exist the result is 0, if it is a single frame it may be a small value around 0.1 or 0.
-static void VM_CL_frameduration(void)
+static void VM_CL_frameduration(prvm_prog_t *prog)
 {
        int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
        dp_model_t *model = CL_GetModelByIndex(modelindex);
@@ -4065,7 +4010,7 @@ static void VM_CL_frameduration(void)
                PRVM_G_FLOAT(OFS_RETURN) = model->animscenes[framenum].framecount / model->animscenes[framenum].framerate;
 }
 
-void VM_CL_RotateMoves(void)
+static void VM_CL_RotateMoves(prvm_prog_t *prog)
 {
        /*
         * Obscure builtin used by GAME_XONOTIC.
@@ -4104,7 +4049,7 @@ void VM_CL_RotateMoves(void)
 }
 
 // #358 void(string cubemapname) loadcubemap
-static void VM_CL_loadcubemap(void)
+static void VM_CL_loadcubemap(prvm_prog_t *prog)
 {
        const char *name;
 
@@ -4772,9 +4717,9 @@ NULL,                                                     // #640
 
 const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t);
 
-void VM_Polygons_Reset(void)
+void VM_Polygons_Reset(prvm_prog_t *prog)
 {
-       vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
+       vmpolygons_t *polys = &prog->vmpolygons;
 
        // TODO: replace vm_polygons stuff with a more general debugging polygon system, and make vm_polygons functions use that system
        if(polys->initialized)
@@ -4784,17 +4729,15 @@ void VM_Polygons_Reset(void)
        }
 }
 
-void VM_CL_Cmd_Init(void)
+void CLVM_init_cmd(prvm_prog_t *prog)
 {
-       VM_Cmd_Init();
-       VM_Polygons_Reset();
+       VM_Cmd_Init(prog);
+       VM_Polygons_Reset(prog);
 }
 
-void VM_CL_Cmd_Reset(void)
+void CLVM_reset_cmd(prvm_prog_t *prog)
 {
        World_End(&cl.world);
-       VM_Cmd_Reset();
-       VM_Polygons_Reset();
+       VM_Cmd_Reset(prog);
+       VM_Polygons_Reset(prog);
 }
-
-
index 8835dae65d4c0accc6ee6c7c93343d96150caa0d..259991ff3f0ebf2416a1e2c0458f6ce0d09e45a0 100644 (file)
@@ -1,10 +1,6 @@
 #ifndef __CLVM_CMDS_H__
 #define __CLVM_CMDS_H__
 
-int CL_GetPitchSign(prvm_edict_t *ent);
-int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex);
-void CL_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix);
-
 /* These are VM built-ins that originate in the client-side programs support
    but are reused by the other programs (usually the menu). */
 
@@ -23,8 +19,6 @@ void VM_CL_R_LoadWorldModel (void);
 void VM_CL_R_PolygonBegin (void);
 void VM_CL_R_PolygonVertex (void);
 void VM_CL_R_PolygonEnd (void);
-/* VMs exposing the polygon calls must call this on Init/Reset */
-void VM_Polygons_Reset(void);
 
 void VM_CL_setattachment(void);
 void VM_CL_gettagindex(void);
diff --git a/cmd.c b/cmd.c
index 1ce6be78541463928712b1d9d331871323ca991d..d2d688f8c16a571320fa9b544ee6dd5180f17056 100644 (file)
--- a/cmd.c
+++ b/cmd.c
@@ -60,7 +60,7 @@ typedef struct cmddeferred_s
 {
        struct cmddeferred_s *next;
        char *value;
-       double time;
+       double delay;
 } cmddeferred_t;
 
 static cmddeferred_t *cmd_deferred_list = NULL;
@@ -76,13 +76,12 @@ static void Cmd_Defer_f (void)
 {
        if(Cmd_Argc() == 1)
        {
-               double time = Sys_DoubleTime();
                cmddeferred_t *next = cmd_deferred_list;
                if(!next)
                        Con_Printf("No commands are pending.\n");
                while(next)
                {
-                       Con_Printf("-> In %9.2f: %s\n", next->time-time, next->value);
+                       Con_Printf("-> In %9.2f: %s\n", next->delay, next->value);
                        next = next->next;
                }
        } else if(Cmd_Argc() == 2 && !strcasecmp("clear", Cmd_Argv(1)))
@@ -100,7 +99,7 @@ static void Cmd_Defer_f (void)
                cmddeferred_t *defcmd = (cmddeferred_t*)Mem_Alloc(tempmempool, sizeof(*defcmd));
                size_t len = strlen(value);
 
-               defcmd->time = Sys_DoubleTime() + atof(Cmd_Argv(1));
+               defcmd->delay = atof(Cmd_Argv(1));
                defcmd->value = (char*)Mem_Alloc(tempmempool, len+1);
                memcpy(defcmd->value, value, len+1);
                defcmd->next = NULL;
@@ -177,17 +176,24 @@ static void Cmd_Centerprint_f (void)
 static sizebuf_t       cmd_text;
 static unsigned char           cmd_text_buf[CMDBUFSIZE];
 void *cmd_text_mutex = NULL;
+qboolean cmd_text_mutex_locked = false;
 
 static void Cbuf_LockThreadMutex(void)
 {
        if (cmd_text_mutex)
+       {
                Thread_LockMutex(cmd_text_mutex);
+               cmd_text_mutex_locked = true;
+       }
 }
 
 static void Cbuf_UnlockThreadMutex(void)
 {
        if (cmd_text_mutex)
+       {
+               cmd_text_mutex_locked = false;
                Thread_UnlockMutex(cmd_text_mutex);
+       }
 }
 
 /*
@@ -257,15 +263,22 @@ void Cbuf_InsertText (const char *text)
 Cbuf_Execute_Deferred --blub
 ============
 */
-void Cbuf_Execute_Deferred (void)
+static void Cbuf_Execute_Deferred (void)
 {
+       static double oldrealtime = 0;
        cmddeferred_t *cmd, *prev;
-       double time = Sys_DoubleTime();
+       double eat;
+       if (realtime - oldrealtime < 0 || realtime - oldrealtime > 1800) oldrealtime = realtime;
+       eat = realtime - oldrealtime;
+       if (eat < (1.0 / 120.0))
+               return;
+       oldrealtime = realtime;
        prev = NULL;
        cmd = cmd_deferred_list;
        while(cmd)
        {
-               if(cmd->time <= time)
+               cmd->delay -= eat;
+               if(cmd->delay <= 0)
                {
                        Cbuf_AddText(cmd->value);
                        Cbuf_AddText(";\n");
@@ -303,8 +316,8 @@ void Cbuf_Execute (void)
        qboolean quotes;
        char *comment;
 
-       Cbuf_LockThreadMutex();
        SV_LockThreadMutex();
+       Cbuf_LockThreadMutex();
 
        // LordHavoc: making sure the tokenizebuffer doesn't get filled up by repeated crashes
        cmd_tokenizebufferpos = 0;
@@ -420,7 +433,7 @@ quake -nosound +cmd amlev1
 ===============
 */
 qboolean host_stuffcmdsrun = false;
-void Cmd_StuffCmds_f (void)
+static void Cmd_StuffCmds_f (void)
 {
        int             i, j, l;
        // this is for all commandline options combined (and is bounds checked)
@@ -808,6 +821,7 @@ static const char *Cmd_GetDirectCvarValue(const char *varname, cmdalias_t *alias
        cvar_t *cvar;
        long argno;
        char *endptr;
+       char vabuf[1024];
 
        if(is_multiple)
                *is_multiple = false;
@@ -825,7 +839,7 @@ static const char *Cmd_GetDirectCvarValue(const char *varname, cmdalias_t *alias
                }
                else if(!strcmp(varname, "#"))
                {
-                       return va("%d", Cmd_Argc());
+                       return va(vabuf, sizeof(vabuf), "%d", Cmd_Argc());
                }
                else if(varname[strlen(varname) - 1] == '-')
                {
@@ -930,8 +944,8 @@ fail:
 
 static const char *Cmd_GetCvarValue(const char *var, size_t varlen, cmdalias_t *alias)
 {
-       static char varname[MAX_INPUTLINE];
-       static char varval[MAX_INPUTLINE];
+       static char varname[MAX_INPUTLINE]; // cmd_mutex
+       static char varval[MAX_INPUTLINE]; // cmd_mutex
        const char *varstr;
        char *varfunc;
 static char asis[] = "asis"; // just to suppress const char warnings
@@ -1120,8 +1134,8 @@ Called for aliases and fills in the alias into the cbuffer
 */
 static void Cmd_ExecuteAlias (cmdalias_t *alias)
 {
-       static char buffer[ MAX_INPUTLINE ];
-       static char buffer2[ MAX_INPUTLINE ];
+       static char buffer[ MAX_INPUTLINE ]; // cmd_mutex
+       static char buffer2[ MAX_INPUTLINE ]; // cmd_mutex
        Cmd_PreprocessString( alias->value, buffer, sizeof(buffer) - 2, alias );
        // insert at start of command buffer, so that aliases execute in order
        // (fixes bug introduced by Black on 20050705)
@@ -1191,6 +1205,7 @@ static void Cmd_Apropos_f(void)
        const char *partial;
        int count;
        qboolean ispattern;
+       char vabuf[1024];
 
        if (Cmd_Argc() > 1)
                partial = Cmd_Args();
@@ -1202,7 +1217,7 @@ static void Cmd_Apropos_f(void)
 
        ispattern = partial && (strchr(partial, '*') || strchr(partial, '?'));
        if(!ispattern)
-               partial = va("*%s*", partial);
+               partial = va(vabuf, sizeof(vabuf), "*%s*", partial);
 
        count = 0;
        for (cvar = cvar_vars; cvar; cvar = cvar->next)
@@ -1296,7 +1311,11 @@ Cmd_Shutdown
 void Cmd_Shutdown(void)
 {
        if (cmd_text_mutex)
+       {
+               // we usually have this locked when we get here from Host_Quit_f
+               Cbuf_UnlockThreadMutex();
                Thread_DestroyMutex(cmd_text_mutex);
+       }
        cmd_text_mutex = NULL;
 
        Mem_FreePool(&cmd_mempool);
@@ -1667,7 +1686,6 @@ void Cmd_ClearCsqcFuncs (void)
                cmd->csqcfunc = false;
 }
 
-qboolean CL_VM_ConsoleCommand (const char *cmd);
 /*
 ============
 Cmd_ExecuteString
@@ -1902,6 +1920,7 @@ Sends the entire command line over to the server
 void Cmd_ForwardToServer (void)
 {
        const char *s;
+       char vabuf[1024];
        if (!strcasecmp(Cmd_Argv(0), "cmd"))
        {
                // we want to strip off "cmd", so just send the args
@@ -1910,7 +1929,7 @@ void Cmd_ForwardToServer (void)
        else
        {
                // we need to keep the command name, so send Cmd_Argv(0), a space and then Cmd_Args()
-               s = va("%s %s", Cmd_Argv(0), Cmd_Argc() > 1 ? Cmd_Args() : "");
+               s = va(vabuf, sizeof(vabuf), "%s %s", Cmd_Argv(0), Cmd_Argc() > 1 ? Cmd_Args() : "");
        }
        // don't send an empty forward message if the user tries "cmd" by itself
        if (!s || !*s)
diff --git a/cmd.h b/cmd.h
index 722fea6543815e3037fdc22ebe87de8ba29269fb..826581d177259195a523f58bf842749bda98aec1 100644 (file)
--- a/cmd.h
+++ b/cmd.h
@@ -165,5 +165,7 @@ void Cmd_Print(const char *text);
 /// enclosing quote marks are also put.
 qboolean Cmd_QuoteString(char *out, size_t outlen, const char *in, const char *quoteset, qboolean putquotes);
 
+void Cmd_ClearCsqcFuncs (void);
+
 #endif
 
index e0cc37dd817c1644a0dbac94750ed75ab328fcf2..ed1fac4e586e1ef07f995eb6e7bb4c1c88c53d6d 100644 (file)
@@ -53,7 +53,7 @@ void Collision_Init (void)
 
 
 
-void Collision_PrintBrushAsQHull(colbrushf_t *brush, const char *name)
+static void Collision_PrintBrushAsQHull(colbrushf_t *brush, const char *name)
 {
        int i;
        Con_Printf("3 %s\n%i\n", name, brush->numpoints);
@@ -65,7 +65,7 @@ void Collision_PrintBrushAsQHull(colbrushf_t *brush, const char *name)
                Con_Printf("%f %f %f %f\n", brush->planes[i].normal[0], brush->planes[i].normal[1], brush->planes[i].normal[2], brush->planes[i].dist);
 }
 
-void Collision_ValidateBrush(colbrushf_t *brush)
+static void Collision_ValidateBrush(colbrushf_t *brush)
 {
        int j, k, pointsoffplanes, pointonplanes, pointswithinsufficientplanes, printbrush;
        float d;
@@ -124,7 +124,7 @@ void Collision_ValidateBrush(colbrushf_t *brush)
                Collision_PrintBrushAsQHull(brush, "unnamed");
 }
 
-float nearestplanedist_float(const float *normal, const colpointf_t *points, int numpoints)
+static float nearestplanedist_float(const float *normal, const colpointf_t *points, int numpoints)
 {
        float dist, bestdist;
        if (!numpoints)
@@ -140,7 +140,7 @@ float nearestplanedist_float(const float *normal, const colpointf_t *points, int
        return bestdist;
 }
 
-float furthestplanedist_float(const float *normal, const colpointf_t *points, int numpoints)
+static float furthestplanedist_float(const float *normal, const colpointf_t *points, int numpoints)
 {
        float dist, bestdist;
        if (!numpoints)
@@ -156,7 +156,7 @@ float furthestplanedist_float(const float *normal, const colpointf_t *points, in
        return bestdist;
 }
 
-void Collision_CalcEdgeDirsForPolygonBrushFloat(colbrushf_t *brush)
+static void Collision_CalcEdgeDirsForPolygonBrushFloat(colbrushf_t *brush)
 {
        int i, j;
        for (i = 0, j = brush->numpoints - 1;i < brush->numpoints;j = i, i++)
@@ -1032,7 +1032,7 @@ void Collision_TracePointBrushFloat(trace_t *trace, const vec3_t point, const co
        }
 }
 
-void Collision_SnapCopyPoints(int numpoints, const colpointf_t *in, colpointf_t *out, float fractionprecision, float invfractionprecision)
+static void Collision_SnapCopyPoints(int numpoints, const colpointf_t *in, colpointf_t *out, float fractionprecision, float invfractionprecision)
 {
        int i;
        for (i = 0;i < numpoints;i++)
@@ -1247,28 +1247,6 @@ void Collision_BrushForBox(colboxbrushf_t *boxbrush, const vec3_t mins, const ve
        //Collision_ValidateBrush(&boxbrush->brush);
 }
 
-void Collision_ClipTrace_BrushBox(trace_t *trace, const vec3_t cmins, const vec3_t cmaxs, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontentsmask, int supercontents, int q3surfaceflags, texture_t *texture)
-{
-       colboxbrushf_t boxbrush, thisbrush_start, thisbrush_end;
-       vec3_t startmins, startmaxs, endmins, endmaxs;
-
-       // create brushes for the collision
-       VectorAdd(start, mins, startmins);
-       VectorAdd(start, maxs, startmaxs);
-       VectorAdd(end, mins, endmins);
-       VectorAdd(end, maxs, endmaxs);
-       Collision_BrushForBox(&boxbrush, cmins, cmaxs, supercontents, q3surfaceflags, texture);
-       Collision_BrushForBox(&thisbrush_start, startmins, startmaxs, 0, 0, NULL);
-       Collision_BrushForBox(&thisbrush_end, endmins, endmaxs, 0, 0, NULL);
-
-       memset(trace, 0, sizeof(trace_t));
-       trace->hitsupercontentsmask = hitsupercontentsmask;
-       trace->fraction = 1;
-       trace->realfraction = 1;
-       trace->allsolid = true;
-       Collision_TraceBrushBrushFloat(trace, &thisbrush_start.brush, &thisbrush_end.brush, &boxbrush.brush, &boxbrush.brush);
-}
-
 //pseudocode for detecting line/sphere overlap without calculating an impact point
 //linesphereorigin = sphereorigin - linestart;linediff = lineend - linestart;linespherefrac = DotProduct(linesphereorigin, linediff) / DotProduct(linediff, linediff);return VectorLength2(linesphereorigin - bound(0, linespherefrac, 1) * linediff) >= sphereradius*sphereradius;
 
@@ -1538,55 +1516,6 @@ void Collision_TraceLineTriangleFloat(trace_t *trace, const vec3_t linestart, co
 #endif
 }
 
-typedef struct colbspnode_s
-{
-       mplane_t plane;
-       struct colbspnode_s *children[2];
-       // the node is reallocated or split if max is reached
-       int numcolbrushf;
-       int maxcolbrushf;
-       colbrushf_t **colbrushflist;
-       //int numcolbrushd;
-       //int maxcolbrushd;
-       //colbrushd_t **colbrushdlist;
-}
-colbspnode_t;
-
-typedef struct colbsp_s
-{
-       mempool_t *mempool;
-       colbspnode_t *nodes;
-}
-colbsp_t;
-
-colbsp_t *Collision_CreateCollisionBSP(mempool_t *mempool)
-{
-       colbsp_t *bsp;
-       bsp = (colbsp_t *)Mem_Alloc(mempool, sizeof(colbsp_t));
-       bsp->mempool = mempool;
-       bsp->nodes = (colbspnode_t *)Mem_Alloc(bsp->mempool, sizeof(colbspnode_t));
-       return bsp;
-}
-
-void Collision_FreeCollisionBSPNode(colbspnode_t *node)
-{
-       if (node->children[0])
-               Collision_FreeCollisionBSPNode(node->children[0]);
-       if (node->children[1])
-               Collision_FreeCollisionBSPNode(node->children[1]);
-       while (--node->numcolbrushf)
-               Mem_Free(node->colbrushflist[node->numcolbrushf]);
-       //while (--node->numcolbrushd)
-       //      Mem_Free(node->colbrushdlist[node->numcolbrushd]);
-       Mem_Free(node);
-}
-
-void Collision_FreeCollisionBSP(colbsp_t *bsp)
-{
-       Collision_FreeCollisionBSPNode(bsp->nodes);
-       Mem_Free(bsp);
-}
-
 void Collision_BoundingBoxOfBrushTraceSegment(const colbrushf_t *start, const colbrushf_t *end, vec3_t mins, vec3_t maxs, float startfrac, float endfrac)
 {
        int i;
@@ -1615,7 +1544,7 @@ void Collision_BoundingBoxOfBrushTraceSegment(const colbrushf_t *start, const co
 
 //===========================================
 
-void Collision_TranslateBrush(const vec3_t shift, colbrushf_t *brush)
+static void Collision_TranslateBrush(const vec3_t shift, colbrushf_t *brush)
 {
        int i;
        // now we can transform the data
@@ -1631,7 +1560,7 @@ void Collision_TranslateBrush(const vec3_t shift, colbrushf_t *brush)
        VectorAdd(brush->maxs, shift, brush->maxs);
 }
 
-void Collision_TransformBrush(const matrix4x4_t *matrix, colbrushf_t *brush)
+static void Collision_TransformBrush(const matrix4x4_t *matrix, colbrushf_t *brush)
 {
        int i;
        vec3_t v;
@@ -1733,7 +1662,7 @@ void Collision_Cache_Init(mempool_t *mempool)
        Collision_Cache_Reset(true);
 }
 
-void Collision_Cache_RebuildHash(void)
+static void Collision_Cache_RebuildHash(void)
 {
        int index;
        int range = collision_cachedtrace_lastused + 1;
index 206cc05794200b93a0d2aa7f2a0c920342967d44..a0d291e2cc14e99d79a45c269c6a60867b765ae5 100644 (file)
--- a/common.c
+++ b/common.c
@@ -404,170 +404,167 @@ void MSG_WriteAngle (sizebuf_t *sb, float f, protocolversion_t protocol)
 //
 // reading functions
 //
-int msg_readcount;
-qboolean msg_badread;
 
-void MSG_BeginReading (void)
+void MSG_BeginReading(sizebuf_t *sb)
 {
-       msg_readcount = 0;
-       msg_badread = false;
+       sb->readcount = 0;
+       sb->badread = false;
 }
 
-int MSG_ReadLittleShort (void)
+int MSG_ReadLittleShort(sizebuf_t *sb)
 {
-       if (msg_readcount+2 > net_message.cursize)
+       if (sb->readcount+2 > sb->cursize)
        {
-               msg_badread = true;
+               sb->badread = true;
                return -1;
        }
-       msg_readcount += 2;
-       return (short)(net_message.data[msg_readcount-2] | (net_message.data[msg_readcount-1]<<8));
+       sb->readcount += 2;
+       return (short)(sb->data[sb->readcount-2] | (sb->data[sb->readcount-1]<<8));
 }
 
-int MSG_ReadBigShort (void)
+int MSG_ReadBigShort (sizebuf_t *sb)
 {
-       if (msg_readcount+2 > net_message.cursize)
+       if (sb->readcount+2 > sb->cursize)
        {
-               msg_badread = true;
+               sb->badread = true;
                return -1;
        }
-       msg_readcount += 2;
-       return (short)((net_message.data[msg_readcount-2]<<8) + net_message.data[msg_readcount-1]);
+       sb->readcount += 2;
+       return (short)((sb->data[sb->readcount-2]<<8) + sb->data[sb->readcount-1]);
 }
 
-int MSG_ReadLittleLong (void)
+int MSG_ReadLittleLong (sizebuf_t *sb)
 {
-       if (msg_readcount+4 > net_message.cursize)
+       if (sb->readcount+4 > sb->cursize)
        {
-               msg_badread = true;
+               sb->badread = true;
                return -1;
        }
-       msg_readcount += 4;
-       return net_message.data[msg_readcount-4] | (net_message.data[msg_readcount-3]<<8) | (net_message.data[msg_readcount-2]<<16) | (net_message.data[msg_readcount-1]<<24);
+       sb->readcount += 4;
+       return sb->data[sb->readcount-4] | (sb->data[sb->readcount-3]<<8) | (sb->data[sb->readcount-2]<<16) | (sb->data[sb->readcount-1]<<24);
 }
 
-int MSG_ReadBigLong (void)
+int MSG_ReadBigLong (sizebuf_t *sb)
 {
-       if (msg_readcount+4 > net_message.cursize)
+       if (sb->readcount+4 > sb->cursize)
        {
-               msg_badread = true;
+               sb->badread = true;
                return -1;
        }
-       msg_readcount += 4;
-       return (net_message.data[msg_readcount-4]<<24) + (net_message.data[msg_readcount-3]<<16) + (net_message.data[msg_readcount-2]<<8) + net_message.data[msg_readcount-1];
+       sb->readcount += 4;
+       return (sb->data[sb->readcount-4]<<24) + (sb->data[sb->readcount-3]<<16) + (sb->data[sb->readcount-2]<<8) + sb->data[sb->readcount-1];
 }
 
-float MSG_ReadLittleFloat (void)
+float MSG_ReadLittleFloat (sizebuf_t *sb)
 {
        union
        {
                float f;
                int l;
        } dat;
-       if (msg_readcount+4 > net_message.cursize)
+       if (sb->readcount+4 > sb->cursize)
        {
-               msg_badread = true;
+               sb->badread = true;
                return -1;
        }
-       msg_readcount += 4;
-       dat.l = net_message.data[msg_readcount-4] | (net_message.data[msg_readcount-3]<<8) | (net_message.data[msg_readcount-2]<<16) | (net_message.data[msg_readcount-1]<<24);
+       sb->readcount += 4;
+       dat.l = sb->data[sb->readcount-4] | (sb->data[sb->readcount-3]<<8) | (sb->data[sb->readcount-2]<<16) | (sb->data[sb->readcount-1]<<24);
        return dat.f;
 }
 
-float MSG_ReadBigFloat (void)
+float MSG_ReadBigFloat (sizebuf_t *sb)
 {
        union
        {
                float f;
                int l;
        } dat;
-       if (msg_readcount+4 > net_message.cursize)
+       if (sb->readcount+4 > sb->cursize)
        {
-               msg_badread = true;
+               sb->badread = true;
                return -1;
        }
-       msg_readcount += 4;
-       dat.l = (net_message.data[msg_readcount-4]<<24) | (net_message.data[msg_readcount-3]<<16) | (net_message.data[msg_readcount-2]<<8) | net_message.data[msg_readcount-1];
+       sb->readcount += 4;
+       dat.l = (sb->data[sb->readcount-4]<<24) | (sb->data[sb->readcount-3]<<16) | (sb->data[sb->readcount-2]<<8) | sb->data[sb->readcount-1];
        return dat.f;
 }
 
-char *MSG_ReadString (void)
+char *MSG_ReadString (sizebuf_t *sb, char *string, size_t maxstring)
 {
-       static char string[MAX_INPUTLINE];
-       const int maxstring = sizeof(string);
-       int l = 0,c;
-       // read string into buffer, but only store as many characters as will fit
-       while ((c = MSG_ReadByte()) > 0)
+       int c;
+       size_t l = 0;
+       // read string into sbfer, but only store as many characters as will fit
+       while ((c = MSG_ReadByte(sb)) > 0)
                if (l < maxstring - 1)
                        string[l++] = c;
        string[l] = 0;
        return string;
 }
 
-int MSG_ReadBytes (int numbytes, unsigned char *out)
+int MSG_ReadBytes (sizebuf_t *sb, int numbytes, unsigned char *out)
 {
        int l, c;
-       for (l = 0;l < numbytes && (c = MSG_ReadByte()) != -1;l++)
+       for (l = 0;l < numbytes && (c = MSG_ReadByte(sb)) != -1;l++)
                out[l] = c;
        return l;
 }
 
-float MSG_ReadCoord13i (void)
+float MSG_ReadCoord13i (sizebuf_t *sb)
 {
-       return MSG_ReadLittleShort() * (1.0/8.0);
+       return MSG_ReadLittleShort(sb) * (1.0/8.0);
 }
 
-float MSG_ReadCoord16i (void)
+float MSG_ReadCoord16i (sizebuf_t *sb)
 {
-       return (signed short) MSG_ReadLittleShort();
+       return (signed short) MSG_ReadLittleShort(sb);
 }
 
-float MSG_ReadCoord32f (void)
+float MSG_ReadCoord32f (sizebuf_t *sb)
 {
-       return MSG_ReadLittleFloat();
+       return MSG_ReadLittleFloat(sb);
 }
 
-float MSG_ReadCoord (protocolversion_t protocol)
+float MSG_ReadCoord (sizebuf_t *sb, protocolversion_t protocol)
 {
        if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_NEHAHRABJP || protocol == PROTOCOL_NEHAHRABJP2 || protocol == PROTOCOL_NEHAHRABJP3 || protocol == PROTOCOL_QUAKEWORLD)
-               return MSG_ReadCoord13i();
+               return MSG_ReadCoord13i(sb);
        else if (protocol == PROTOCOL_DARKPLACES1)
-               return MSG_ReadCoord32f();
+               return MSG_ReadCoord32f(sb);
        else if (protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4)
-               return MSG_ReadCoord16i();
+               return MSG_ReadCoord16i(sb);
        else
-               return MSG_ReadCoord32f();
+               return MSG_ReadCoord32f(sb);
 }
 
-void MSG_ReadVector (float *v, protocolversion_t protocol)
+void MSG_ReadVector (sizebuf_t *sb, float *v, protocolversion_t protocol)
 {
-       v[0] = MSG_ReadCoord(protocol);
-       v[1] = MSG_ReadCoord(protocol);
-       v[2] = MSG_ReadCoord(protocol);
+       v[0] = MSG_ReadCoord(sb, protocol);
+       v[1] = MSG_ReadCoord(sb, protocol);
+       v[2] = MSG_ReadCoord(sb, protocol);
 }
 
 // LordHavoc: round to nearest value, rather than rounding toward zero, fixes crosshair problem
-float MSG_ReadAngle8i (void)
+float MSG_ReadAngle8i (sizebuf_t *sb)
 {
-       return (signed char) MSG_ReadByte () * (360.0/256.0);
+       return (signed char) MSG_ReadByte (sb) * (360.0/256.0);
 }
 
-float MSG_ReadAngle16i (void)
+float MSG_ReadAngle16i (sizebuf_t *sb)
 {
-       return (signed short)MSG_ReadShort () * (360.0/65536.0);
+       return (signed short)MSG_ReadShort (sb) * (360.0/65536.0);
 }
 
-float MSG_ReadAngle32f (void)
+float MSG_ReadAngle32f (sizebuf_t *sb)
 {
-       return MSG_ReadFloat ();
+       return MSG_ReadFloat (sb);
 }
 
-float MSG_ReadAngle (protocolversion_t protocol)
+float MSG_ReadAngle (sizebuf_t *sb, protocolversion_t protocol)
 {
        if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_NEHAHRABJP || protocol == PROTOCOL_NEHAHRABJP2 || protocol == PROTOCOL_NEHAHRABJP3 || protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4 || protocol == PROTOCOL_QUAKEWORLD)
-               return MSG_ReadAngle8i ();
+               return MSG_ReadAngle8i (sb);
        else
-               return MSG_ReadAngle16i ();
+               return MSG_ReadAngle16i (sb);
 }
 
 
@@ -1616,25 +1613,18 @@ void COM_Init_Commands (void)
 ============
 va
 
-does a varargs printf into a temp buffer, so I don't need to have
-varargs versions of all text functions.
-FIXME: make this buffer size safe someday
+varargs print into provided buffer, returns buffer (so that it can be called in-line, unlike dpsnprintf)
 ============
 */
-char *va(const char *format, ...)
+char *va(char *buf, size_t buflen, const char *format, ...)
 {
        va_list argptr;
-       // LordHavoc: now cycles through 8 buffers to avoid problems in most cases
-       static char string[8][1024], *s;
-       static int stringindex = 0;
 
-       s = string[stringindex];
-       stringindex = (stringindex + 1) & 7;
        va_start (argptr, format);
-       dpvsnprintf (s, sizeof (string[0]), format,argptr);
+       dpvsnprintf (buf, buflen, format,argptr);
        va_end (argptr);
 
-       return s;
+       return buf;
 }
 
 
@@ -1976,69 +1966,7 @@ COM_StringDecolorize(const char *in, size_t size_in, char *out, size_t size_out,
 #undef APPEND
 }
 
-// written by Elric, thanks Elric!
-char *SearchInfostring(const char *infostring, const char *key)
-{
-       static char value [MAX_INPUTLINE];
-       char crt_key [MAX_INPUTLINE];
-       size_t value_ind, key_ind;
-       char c;
-
-       if (*infostring++ != '\\')
-               return NULL;
-
-       value_ind = 0;
-       for (;;)
-       {
-               key_ind = 0;
-
-               // Get the key name
-               for (;;)
-               {
-                       c = *infostring++;
-
-                       if (c == '\0')
-                               return NULL;
-                       if (c == '\\' || key_ind == sizeof (crt_key) - 1)
-                       {
-                               crt_key[key_ind] = '\0';
-                               break;
-                       }
-
-                       crt_key[key_ind++] = c;
-               }
-
-               // If it's the key we are looking for, save it in "value"
-               if (!strcmp(crt_key, key))
-               {
-                       for (;;)
-                       {
-                               c = *infostring++;
-
-                               if (c == '\0' || c == '\\' || value_ind == sizeof (value) - 1)
-                               {
-                                       value[value_ind] = '\0';
-                                       return value;
-                               }
-
-                               value[value_ind++] = c;
-                       }
-               }
-
-               // Else, skip the value
-               for (;;)
-               {
-                       c = *infostring++;
-
-                       if (c == '\0')
-                               return NULL;
-                       if (c == '\\')
-                               break;
-               }
-       }
-}
-
-void InfoString_GetValue(const char *buffer, const char *key, char *value, size_t valuelength)
+char *InfoString_GetValue(const char *buffer, const char *key, char *value, size_t valuelength)
 {
        int pos = 0, j;
        size_t keylength;
@@ -2048,23 +1976,23 @@ void InfoString_GetValue(const char *buffer, const char *key, char *value, size_
        if (valuelength < 1 || !value)
        {
                Con_Printf("InfoString_GetValue: no room in value\n");
-               return;
+               return NULL;
        }
        value[0] = 0;
        if (strchr(key, '\\'))
        {
                Con_Printf("InfoString_GetValue: key name \"%s\" contains \\ which is not possible in an infostring\n", key);
-               return;
+               return NULL;
        }
        if (strchr(key, '\"'))
        {
                Con_Printf("InfoString_SetValue: key name \"%s\" contains \" which is not allowed in an infostring\n", key);
-               return;
+               return NULL;
        }
        if (!key[0])
        {
                Con_Printf("InfoString_GetValue: can not look up a key with no name\n");
-               return;
+               return NULL;
        }
        while (buffer[pos] == '\\')
        {
@@ -2075,12 +2003,13 @@ void InfoString_GetValue(const char *buffer, const char *key, char *value, size_
                        for (j = 0;buffer[pos+j] && buffer[pos+j] != '\\' && j < (int)valuelength - 1;j++)
                                value[j] = buffer[pos+j];
                        value[j] = 0;
-                       return;
+                       return value;
                }
                for (pos++;buffer[pos] && buffer[pos] != '\\';pos++);
                for (pos++;buffer[pos] && buffer[pos] != '\\';pos++);
        }
        // if we reach this point the key was not found
+       return NULL;
 }
 
 void InfoString_SetValue(char *buffer, size_t bufferlength, const char *key, const char *value)
@@ -2129,7 +2058,7 @@ void InfoString_SetValue(char *buffer, size_t bufferlength, const char *key, con
        if (value && value[0])
        {
                // set the key/value and append the remaining text
-               char tempbuffer[4096];
+               char tempbuffer[MAX_INPUTLINE];
                strlcpy(tempbuffer, buffer + pos2, sizeof(tempbuffer));
                dpsnprintf(buffer + pos, bufferlength - pos, "\\%s\\%s%s", key, value, tempbuffer);
        }
@@ -2143,8 +2072,8 @@ void InfoString_SetValue(char *buffer, size_t bufferlength, const char *key, con
 void InfoString_Print(char *buffer)
 {
        int i;
-       char key[2048];
-       char value[2048];
+       char key[MAX_INPUTLINE];
+       char value[MAX_INPUTLINE];
        while (*buffer)
        {
                if (*buffer != '\\')
index bd715ed65eeb2cc9259b33bfabb116c5db959b6a..ed21376f7102e7f01f0a69f122373e973509f31c 100644 (file)
--- a/common.h
+++ b/common.h
@@ -46,6 +46,8 @@ typedef struct sizebuf_s
        unsigned char           *data;
        int                     maxsize;
        int                     cursize;
+       int                     readcount;
+       qboolean        badread;                // set if a read goes beyond end of message
 } sizebuf_t;
 
 void SZ_Clear (sizebuf_t *buf);
@@ -64,6 +66,8 @@ unsigned char COM_BlockSequenceCRCByteQW(unsigned char *base, int length, int se
 unsigned Com_BlockChecksum (void *buffer, int length);
 void Com_BlockFullChecksum (void *buffer, int len, unsigned char *outbuf);
 
+void COM_Init_Commands(void);
+
 
 //============================================================================
 //                                                     Endianess handling
@@ -160,34 +164,31 @@ void MSG_WriteCoord (sizebuf_t *sb, float f, protocolversion_t protocol);
 void MSG_WriteVector (sizebuf_t *sb, float *v, protocolversion_t protocol);
 void MSG_WriteAngle (sizebuf_t *sb, float f, protocolversion_t protocol);
 
-extern int                     msg_readcount;
-extern qboolean        msg_badread;            // set if a read goes beyond end of message
-
-void MSG_BeginReading (void);
-int MSG_ReadLittleShort (void);
-int MSG_ReadBigShort (void);
-int MSG_ReadLittleLong (void);
-int MSG_ReadBigLong (void);
-float MSG_ReadLittleFloat (void);
-float MSG_ReadBigFloat (void);
-char *MSG_ReadString (void);
-int MSG_ReadBytes (int numbytes, unsigned char *out);
-
-#define MSG_ReadChar() (msg_readcount >= net_message.cursize ? (msg_badread = true, -1) : (signed char)net_message.data[msg_readcount++])
-#define MSG_ReadByte() (msg_readcount >= net_message.cursize ? (msg_badread = true, -1) : (unsigned char)net_message.data[msg_readcount++])
+void MSG_BeginReading (sizebuf_t *sb);
+int MSG_ReadLittleShort (sizebuf_t *sb);
+int MSG_ReadBigShort (sizebuf_t *sb);
+int MSG_ReadLittleLong (sizebuf_t *sb);
+int MSG_ReadBigLong (sizebuf_t *sb);
+float MSG_ReadLittleFloat (sizebuf_t *sb);
+float MSG_ReadBigFloat (sizebuf_t *sb);
+char *MSG_ReadString (sizebuf_t *sb, char *string, size_t maxstring);
+int MSG_ReadBytes (sizebuf_t *sb, int numbytes, unsigned char *out);
+
+#define MSG_ReadChar(sb) ((sb)->readcount >= (sb)->cursize ? ((sb)->badread = true, -1) : (signed char)(sb)->data[(sb)->readcount++])
+#define MSG_ReadByte(sb) ((sb)->readcount >= (sb)->cursize ? ((sb)->badread = true, -1) : (unsigned char)(sb)->data[(sb)->readcount++])
 #define MSG_ReadShort MSG_ReadLittleShort
 #define MSG_ReadLong MSG_ReadLittleLong
 #define MSG_ReadFloat MSG_ReadLittleFloat
 
-float MSG_ReadAngle8i (void);
-float MSG_ReadAngle16i (void);
-float MSG_ReadAngle32f (void);
-float MSG_ReadCoord13i (void);
-float MSG_ReadCoord16i (void);
-float MSG_ReadCoord32f (void);
-float MSG_ReadCoord (protocolversion_t protocol);
-void MSG_ReadVector (float *v, protocolversion_t protocol);
-float MSG_ReadAngle (protocolversion_t protocol);
+float MSG_ReadAngle8i (sizebuf_t *sb);
+float MSG_ReadAngle16i (sizebuf_t *sb);
+float MSG_ReadAngle32f (sizebuf_t *sb);
+float MSG_ReadCoord13i (sizebuf_t *sb);
+float MSG_ReadCoord16i (sizebuf_t *sb);
+float MSG_ReadCoord32f (sizebuf_t *sb);
+float MSG_ReadCoord (sizebuf_t *sb, protocolversion_t protocol);
+void MSG_ReadVector (sizebuf_t *sb, float *v, protocolversion_t protocol);
+float MSG_ReadAngle (sizebuf_t *sb, protocolversion_t protocol);
 //@}
 //============================================================================
 
@@ -211,8 +212,8 @@ void COM_Init (void);
 void COM_Shutdown (void);
 void COM_InitGameType (void);
 
-char   *va(const char *format, ...) DP_FUNC_PRINTF(1);
-// does a varargs printf into a temp buffer
+char *va(char *buf, size_t buflen, const char *format, ...) DP_FUNC_PRINTF(3);
+// does a varargs printf into provided buffer, returns buffer (so it can be called in-line unlike dpsnprintf)
 
 
 // snprintf and vsnprintf are NOT portable. Use their DP counterparts instead
@@ -332,9 +333,7 @@ void stringlistappend(stringlist_t *list, const char *text);
 void stringlistsort(stringlist_t *list, qboolean uniq);
 void listdirectory(stringlist_t *list, const char *basepath, const char *path);
 
-char *SearchInfostring(const char *infostring, const char *key);
-
-void InfoString_GetValue(const char *buffer, const char *key, char *value, size_t valuelength);
+char *InfoString_GetValue(const char *buffer, const char *key, char *value, size_t valuelength);
 void InfoString_SetValue(char *buffer, size_t bufferlength, const char *key, const char *value);
 void InfoString_Print(char *buffer);
 
index 2f7e99b72f96d41a0d22c861a256247d1385a858..537cdc72019ced668af841aa9e8fbed16c153b2b 100644 (file)
--- a/console.c
+++ b/console.c
@@ -289,27 +289,9 @@ int ConBuffer_FindPrevLine(conbuffer_t *buf, int mask_must, int mask_mustnot, in
        return -1;
 }
 
-int Con_FindNextLine(conbuffer_t *buf, int mask_must, int mask_mustnot, int start)
-{
-       int i;
-       for(i = start + 1; i < buf->lines_count; ++i)
-       {
-               con_lineinfo_t *l = &CONBUFFER_LINES(buf, i);
-
-               if((l->mask & mask_must) != mask_must)
-                       continue;
-               if(l->mask & mask_mustnot)
-                       continue;
-
-               return i;
-       }
-
-       return -1;
-}
-
 const char *ConBuffer_GetLine(conbuffer_t *buf, int i)
 {
-       static char copybuf[MAX_INPUTLINE];
+       static char copybuf[MAX_INPUTLINE]; // client only
        con_lineinfo_t *l = &CONBUFFER_LINES(buf, i);
        size_t sz = l->len+1 > sizeof(copybuf) ? sizeof(copybuf) : l->len+1;
        strlcpy(copybuf, l->start, sz);
@@ -340,23 +322,13 @@ size_t logq_size = 0;
 
 void Log_ConPrint (const char *msg);
 //@}
-/*
-====================
-Log_DestBuffer_Init
-====================
-*/
 static void Log_DestBuffer_Init(void)
 {
        memcpy(log_dest_buffer, "\377\377\377\377n", 5); // QW rcon print
        log_dest_buffer_pos = 5;
 }
 
-/*
-====================
-Log_DestBuffer_Flush
-====================
-*/
-void Log_DestBuffer_Flush(void)
+static void Log_DestBuffer_Flush_NoLock(void)
 {
        lhnetaddress_t log_dest_addr;
        lhnetsocket_t *log_dest_socket;
@@ -392,12 +364,21 @@ void Log_DestBuffer_Flush(void)
 
 /*
 ====================
-Log_Timestamp
+Log_DestBuffer_Flush
 ====================
 */
-const char* Log_Timestamp (const char *desc)
+void Log_DestBuffer_Flush(void)
+{
+       if (con_mutex)
+               Thread_LockMutex(con_mutex);
+       Log_DestBuffer_Flush_NoLock();
+       if (con_mutex)
+               Thread_UnlockMutex(con_mutex);
+}
+
+static const char* Log_Timestamp (const char *desc)
 {
-       static char timestamp [128];
+       static char timestamp [128]; // init/shutdown only
        time_t crt_time;
 #if _MSC_VER >= 1400
        struct tm crt_tm;
@@ -424,13 +405,7 @@ const char* Log_Timestamp (const char *desc)
        return timestamp;
 }
 
-
-/*
-====================
-Log_Open
-====================
-*/
-void Log_Open (void)
+static void Log_Open (void)
 {
        if (logfile != NULL || log_file.string[0] == '\0')
                return;
@@ -443,7 +418,6 @@ void Log_Open (void)
        }
 }
 
-
 /*
 ====================
 Log_Close
@@ -492,7 +466,7 @@ void Log_Start (void)
                                        n = min(sizeof(log_dest_buffer) - log_dest_buffer_pos - 1, logq_ind - pos);
                                        memcpy(log_dest_buffer + log_dest_buffer_pos, temp + pos, n);
                                        log_dest_buffer_pos += n;
-                                       Log_DestBuffer_Flush();
+                                       Log_DestBuffer_Flush_NoLock();
                                        pos += n;
                                }
                        }
@@ -625,7 +599,7 @@ void Con_ClearNotify (void)
 Con_MessageMode_f
 ================
 */
-void Con_MessageMode_f (void)
+static void Con_MessageMode_f (void)
 {
        key_dest = key_message;
        chat_mode = 0; // "say"
@@ -642,7 +616,7 @@ void Con_MessageMode_f (void)
 Con_MessageMode2_f
 ================
 */
-void Con_MessageMode2_f (void)
+static void Con_MessageMode2_f (void)
 {
        key_dest = key_message;
        chat_mode = 1; // "say_team"
@@ -658,7 +632,7 @@ void Con_MessageMode2_f (void)
 Con_CommandMode_f
 ================
 */
-void Con_CommandMode_f (void)
+static void Con_CommandMode_f (void)
 {
        key_dest = key_message;
        if(Cmd_Argc() > 1)
@@ -713,7 +687,7 @@ static void Con_Maps_f (void)
                GetMapList("", NULL, 0);
 }
 
-void Con_ConDump_f (void)
+static void Con_ConDump_f (void)
 {
        int i;
        qfile_t *file;
@@ -827,14 +801,14 @@ All console printing must go through this in order to be displayed
 If no console is visible, the notify window will pop up.
 ================
 */
-void Con_PrintToHistory(const char *txt, int mask)
+static void Con_PrintToHistory(const char *txt, int mask)
 {
        // process:
        //   \n goes to next line
        //   \r deletes current line and makes a new one
 
        static int cr_pending = 0;
-       static char buf[CON_TEXTSIZE];
+       static char buf[CON_TEXTSIZE]; // con_mutex
        static int bufpos = 0;
 
        if(!con.text) // FIXME uses a non-abstracted property of con
@@ -931,7 +905,7 @@ void Con_Rcon_Redirect_Init(lhnetsocket_t *sock, lhnetaddress_t *dest, qboolean
        rcon_redirect_bufferpos = 5;
 }
 
-void Con_Rcon_Redirect_Flush(void)
+static void Con_Rcon_Redirect_Flush(void)
 {
        rcon_redirect_buffer[rcon_redirect_bufferpos] = 0;
        if (rcon_redirect_proquakeprotocol)
@@ -964,7 +938,7 @@ Con_Rcon_AddChar
 ================
 */
 /// Adds a character to the rcon buffer.
-void Con_Rcon_AddChar(int c)
+static void Con_Rcon_AddChar(int c)
 {
        if(log_dest_buffer_appending)
                return;
@@ -985,7 +959,7 @@ void Con_Rcon_AddChar(int c)
                        Log_DestBuffer_Init();
                log_dest_buffer[log_dest_buffer_pos++] = c;
                if(log_dest_buffer_pos >= sizeof(log_dest_buffer) - 1) // minus one, to allow for terminating zero
-                       Log_DestBuffer_Flush();
+                       Log_DestBuffer_Flush_NoLock();
        }
        else
                log_dest_buffer_pos = 0;
@@ -1440,7 +1414,7 @@ Modified by EvilTypeGuy eviltypeguy@qeradiant.com
 ================
 */
 extern cvar_t r_font_disable_freetype;
-void Con_DrawInput (void)
+static void Con_DrawInput (void)
 {
        int             y;
        int             i;
@@ -1479,7 +1453,8 @@ void Con_DrawInput (void)
                                int ofs = u8_bytelen(text + key_linepos, 1);
                                size_t len;
                                const char *curbuf;
-                               curbuf = u8_encodech(0xE000 + 11 + 130 * key_insert, &len);
+                               char charbuf16[16];
+                               curbuf = u8_encodech(0xE000 + 11 + 130 * key_insert, &len, charbuf16);
 
                                if (curbuf)
                                {
@@ -1517,7 +1492,8 @@ void Con_DrawInput (void)
                        {
                                size_t len;
                                const char *curbuf;
-                               curbuf = u8_encodech(0xE000 + 11 + 130 * key_insert, &len);
+                               char charbuf16[16];
+                               curbuf = u8_encodech(0xE000 + 11 + 130 * key_insert, &len, charbuf16);
                                memcpy(text, curbuf, len);
                                text[len] = 0;
                        }
@@ -1545,7 +1521,7 @@ typedef struct
 }
 con_text_info_t;
 
-float Con_WordWidthFunc(void *passthrough, const char *w, size_t *length, float maxWidth)
+static float Con_WordWidthFunc(void *passthrough, const char *w, size_t *length, float maxWidth)
 {
        con_text_info_t *ti = (con_text_info_t *) passthrough;
        if(w == NULL)
@@ -1565,7 +1541,7 @@ float Con_WordWidthFunc(void *passthrough, const char *w, size_t *length, float
        }
 }
 
-int Con_CountLineFunc(void *passthrough, const char *line, size_t length, float width, qboolean isContinuation)
+static int Con_CountLineFunc(void *passthrough, const char *line, size_t length, float width, qboolean isContinuation)
 {
        (void) passthrough;
        (void) line;
@@ -1575,7 +1551,7 @@ int Con_CountLineFunc(void *passthrough, const char *line, size_t length, float
        return 1;
 }
 
-int Con_DisplayLineFunc(void *passthrough, const char *line, size_t length, float width, qboolean isContinuation)
+static int Con_DisplayLineFunc(void *passthrough, const char *line, size_t length, float width, qboolean isContinuation)
 {
        con_text_info_t *ti = (con_text_info_t *) passthrough;
 
@@ -1596,7 +1572,7 @@ int Con_DisplayLineFunc(void *passthrough, const char *line, size_t length, floa
        return 1;
 }
 
-int Con_DrawNotifyRect(int mask_must, int mask_mustnot, float maxage, float x, float y, float width, float height, float fontsize, float alignment_x, float alignment_y, const char *continuationString)
+static int Con_DrawNotifyRect(int mask_must, int mask_mustnot, float maxage, float x, float y, float width, float height, float fontsize, float alignment_x, float alignment_y, const char *continuationString)
 {
        int i;
        int lines = 0;
@@ -1762,7 +1738,8 @@ void Con_DrawNotify (void)
                //static char *cursor[2] = { "\xee\x80\x8a", "\xee\x80\x8b" }; // { off, on }
                int colorindex = -1;
                const char *cursor;
-               cursor = u8_encodech(0xE00A + ((int)(realtime * con_cursorspeed)&1), NULL);
+               char charbuf16[16];
+               cursor = u8_encodech(0xE00A + ((int)(realtime * con_cursorspeed)&1), NULL, charbuf16);
 
                // LordHavoc: speedup, and other improvements
                if (chat_mode < 0)
@@ -1788,7 +1765,7 @@ Con_LineHeight
 Returns the height of a given console line; calculates it if necessary.
 ================
 */
-int Con_LineHeight(int lineno)
+static int Con_LineHeight(int lineno)
 {
        con_lineinfo_t *li = &CON_LINES(lineno);
        if(li->height == -1)
@@ -1812,7 +1789,7 @@ If alpha is 0, the line is not drawn, but still wrapped and its height
 returned.
 ================
 */
-int Con_DrawConsoleLine(int mask_must, int mask_mustnot, float y, int lineno, float ymin, float ymax)
+static int Con_DrawConsoleLine(int mask_must, int mask_mustnot, float y, int lineno, float ymin, float ymax)
 {
        float width = vid_conwidth.value;
        con_text_info_t ti;
@@ -2208,7 +2185,7 @@ void Con_DisplayList(const char **list)
        SanitizeString strips color tags from the string in
        and writes the result on string out
 */
-void SanitizeString(char *in, char *out)
+static void SanitizeString(char *in, char *out)
 {
        while(*in)
        {
@@ -2263,7 +2240,7 @@ static int Nicks_offset[MAX_SCOREBOARD]; // when nicks use a space, we need this
 static int Nicks_matchpos;
 
 // co against <<:BLASTER:>> is true!?
-int Nicks_strncasecmp_nospaces(char *a, char *b, unsigned int a_len)
+static int Nicks_strncasecmp_nospaces(char *a, char *b, unsigned int a_len)
 {
        while(a_len)
        {
@@ -2289,7 +2266,7 @@ int Nicks_strncasecmp_nospaces(char *a, char *b, unsigned int a_len)
        }
        return 0;
 }
-int Nicks_strncasecmp(char *a, char *b, unsigned int a_len)
+static int Nicks_strncasecmp(char *a, char *b, unsigned int a_len)
 {
        char space_char;
        if(!(con_nickcompletion_flags.integer & NICKS_ALPHANUMERICS_ONLY))
@@ -2340,7 +2317,7 @@ int Nicks_strncasecmp(char *a, char *b, unsigned int a_len)
 
    Count the number of possible nicks to complete
  */
-int Nicks_CompleteCountPossible(char *line, int pos, char *s, qboolean isCon)
+static int Nicks_CompleteCountPossible(char *line, int pos, char *s, qboolean isCon)
 {
        char name[128];
        int i, p;
@@ -2407,14 +2384,14 @@ int Nicks_CompleteCountPossible(char *line, int pos, char *s, qboolean isCon)
        return count;
 }
 
-void Cmd_CompleteNicksPrint(int count)
+static void Cmd_CompleteNicksPrint(int count)
 {
        int i;
        for(i = 0; i < count; ++i)
                Con_Printf("%s\n", Nicks_list[i]);
 }
 
-void Nicks_CutMatchesNormal(int count)
+static void Nicks_CutMatchesNormal(int count)
 {
        // cut match 0 down to the longest possible completion
        int i;
@@ -2437,7 +2414,7 @@ void Nicks_CutMatchesNormal(int count)
        //Con_Printf("List0: %s\n", Nicks_sanlist[0]);
 }
 
-unsigned int Nicks_strcleanlen(const char *s)
+static unsigned int Nicks_strcleanlen(const char *s)
 {
        unsigned int l = 0;
        while(*s)
@@ -2452,7 +2429,7 @@ unsigned int Nicks_strcleanlen(const char *s)
        return l;
 }
 
-void Nicks_CutMatchesAlphaNumeric(int count)
+static void Nicks_CutMatchesAlphaNumeric(int count)
 {
        // cut match 0 down to the longest possible completion
        int i;
@@ -2511,7 +2488,7 @@ void Nicks_CutMatchesAlphaNumeric(int count)
        }
 }
 
-void Nicks_CutMatchesNoSpaces(int count)
+static void Nicks_CutMatchesNoSpaces(int count)
 {
        // cut match 0 down to the longest possible completion
        int i;
@@ -2567,7 +2544,7 @@ void Nicks_CutMatchesNoSpaces(int count)
        }
 }
 
-void Nicks_CutMatches(int count)
+static void Nicks_CutMatches(int count)
 {
        if(con_nickcompletion_flags.integer & NICKS_ALPHANUMERICS_ONLY)
                Nicks_CutMatchesAlphaNumeric(count);
@@ -2577,7 +2554,7 @@ void Nicks_CutMatches(int count)
                Nicks_CutMatchesNormal(count);
 }
 
-const char **Nicks_CompleteBuildList(int count)
+static const char **Nicks_CompleteBuildList(int count)
 {
        const char **buf;
        int bpos = 0;
@@ -2597,7 +2574,7 @@ const char **Nicks_CompleteBuildList(int count)
        Nicks_AddLastColor
        Restores the previous used color, after the autocompleted name.
 */
-int Nicks_AddLastColor(char *buffer, int pos)
+static int Nicks_AddLastColor(char *buffer, int pos)
 {
        qboolean quote_added = false;
        int match;
@@ -2718,6 +2695,7 @@ void Con_CompleteCommandLine (void)
        int c, v, a, i, cmd_len, pos, k;
        int n; // nicks --blub
        const char *space, *patterns;
+       char vabuf[1024];
 
        //find what we want to complete
        pos = key_linepos;
@@ -2738,7 +2716,7 @@ void Con_CompleteCommandLine (void)
        {
                strlcpy(command, key_line + 1, min(sizeof(command), (unsigned int)(space - key_line)));
 
-               patterns = Cvar_VariableString(va("con_completion_%s", command)); // TODO maybe use a better place for this?
+               patterns = Cvar_VariableString(va(vabuf, sizeof(vabuf), "con_completion_%s", command)); // TODO maybe use a better place for this?
                if(patterns && !*patterns)
                        patterns = NULL; // get rid of the empty string
 
index 8b2d7680579a2d26b982bd96a43a08e68fb763dc..860c501eebfe3b89a0901842426e89ef72326915 100644 (file)
--- a/console.h
+++ b/console.h
@@ -63,6 +63,8 @@ void Con_DrawNotify (void);
 void Con_ClearNotify (void);
 void Con_ToggleConsole_f (void);
 
+int Nicks_CompleteChatLine(char *buffer, size_t size, unsigned int pos);
+
 qboolean GetMapList (const char *s, char *completedname, int completednamebufferlength);
 
 /// wrapper function to attempt to either complete the command line
index 7bd36d12b2704c093602c0c2a795ad5a8f0c17d2..8b9bd2d5c7cf1fb147f8d4a15a5da61c02c178e3 100644 (file)
--- a/crypto.c
+++ b/crypto.c
@@ -2,10 +2,13 @@
 #include "quakedef.h"
 #include "crypto.h"
 #include "common.h"
+#include "thread.h"
 
 #include "hmac.h"
 #include "libcurl.h"
 
+void *crypto_mutex = NULL;
+
 cvar_t crypto_developer = {CVAR_SAVE, "crypto_developer", "0", "print extra info about crypto handshake"};
 cvar_t crypto_servercpupercent = {CVAR_SAVE, "crypto_servercpupercent", "10", "allowed crypto CPU load in percent for server operation (0 = no limit, faster)"};
 cvar_t crypto_servercpumaxtime = {CVAR_SAVE, "crypto_servercpumaxtime", "0.01", "maximum allowed crypto CPU time per frame (0 = no limit)"};
@@ -342,12 +345,13 @@ void sha256(unsigned char *out, const unsigned char *in, int n)
 
 static size_t Crypto_LoadFile(const char *path, char *buf, size_t nmax)
 {
+       char vabuf[1024];
        qfile_t *f = NULL;
        fs_offset_t n;
        if(*fs_userdir)
-               f = FS_SysOpen(va("%s%s", fs_userdir, path), "rb", false);
+               f = FS_SysOpen(va(vabuf, sizeof(vabuf), "%s%s", fs_userdir, path), "rb", false);
        if(!f)
-               f = FS_SysOpen(va("%s%s", fs_basedir, path), "rb", false);
+               f = FS_SysOpen(va(vabuf, sizeof(vabuf), "%s%s", fs_basedir, path), "rb", false);
        if(!f)
                return 0;
        n = FS_Read(f, buf, nmax);
@@ -753,6 +757,7 @@ static void Crypto_LoadKeys(void)
        char buf[8192];
        size_t len, len2;
        int i;
+       char vabuf[1024];
 
        // load keys
        // note: we are just a CLIENT
@@ -767,14 +772,14 @@ static void Crypto_LoadKeys(void)
                memset(pubkeys_fp64[i], 0, sizeof(pubkeys_fp64[i]));
                memset(pubkeys_priv_fp64[i], 0, sizeof(pubkeys_fp64[i]));
                pubkeys_havepriv[i] = false;
-               len = Crypto_LoadFile(va("key_%d.d0pk", i), buf, sizeof(buf));
+               len = Crypto_LoadFile(va(vabuf, sizeof(vabuf), "key_%d.d0pk", i), buf, sizeof(buf));
                if((pubkeys[i] = Crypto_ReadPublicKey(buf, len)))
                {
                        len2 = FP64_SIZE;
                        if(qd0_blind_id_fingerprint64_public_key(pubkeys[i], pubkeys_fp64[i], &len2)) // keeps final NUL
                        {
                                Con_Printf("Loaded public key key_%d.d0pk (fingerprint: %s)\n", i, pubkeys_fp64[i]);
-                               len = Crypto_LoadFile(va("key_%d.d0si", i), buf, sizeof(buf));
+                               len = Crypto_LoadFile(va(vabuf, sizeof(vabuf), "key_%d.d0si", i), buf, sizeof(buf));
                                if(len)
                                {
                                        if(Crypto_AddPrivateKey(pubkeys[i], buf, len))
@@ -784,7 +789,7 @@ static void Crypto_LoadKeys(void)
                                                {
                                                        Con_Printf("Loaded private ID key_%d.d0si for key_%d.d0pk (public key fingerprint: %s)\n", i, i, pubkeys_priv_fp64[i]);
                                                        pubkeys_havepriv[i] = true;
-                                                       strlcat(crypto_idstring_buf, va(" %s@%s", pubkeys_priv_fp64[i], pubkeys_fp64[i]), sizeof(crypto_idstring_buf));
+                                                       strlcat(crypto_idstring_buf, va(vabuf, sizeof(vabuf), " %s@%s", pubkeys_priv_fp64[i], pubkeys_fp64[i]), sizeof(crypto_idstring_buf));
                                                }
                                                else
                                                {
@@ -872,6 +877,10 @@ void Crypto_Shutdown(void)
        crypto_t *crypto;
        int i;
 
+       if (crypto_mutex)
+               Thread_DestroyMutex(crypto_mutex);
+       crypto_mutex = NULL;
+
        Crypto_Rijndael_CloseLibrary();
 
        if(d0_blind_id_dll)
@@ -899,6 +908,9 @@ void Crypto_Init(void)
        if(!Crypto_OpenLibrary())
                return;
 
+       if (Thread_HasThreads())
+               crypto_mutex = Thread_CreateMutex();
+
        if(!qd0_blind_id_INITIALIZE())
        {
                Crypto_Rijndael_CloseLibrary();
@@ -933,11 +945,15 @@ static void Crypto_KeyGen_Finished(int code, size_t length_received, unsigned ch
        d0_blind_id_t *ctx, *ctx2;
        D0_BOOL status;
        size_t len2;
+       char vabuf[1024];
+
+       if (crypto_mutex) Thread_LockMutex(crypto_mutex);
 
        if(!d0_blind_id_dll)
        {
                Con_Print("libd0_blind_id DLL not found, this command is inactive.\n");
                keygen_i = -1;
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
 
@@ -945,12 +961,14 @@ static void Crypto_KeyGen_Finished(int code, size_t length_received, unsigned ch
        {
                Con_Printf("overflow of keygen_i\n");
                keygen_i = -1;
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
        if(keygen_i < 0)
        {
                Con_Printf("Unexpected response from keygen server:\n");
                Com_HexDumpToConsole(buffer, length_received);
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
        if(!Crypto_ParsePack((const char *) buffer, length_received, FOURCC_D0IR, p, l, 1))
@@ -965,12 +983,14 @@ static void Crypto_KeyGen_Finished(int code, size_t length_received, unsigned ch
                        Com_HexDumpToConsole(buffer, length_received);
                }
                keygen_i = -1;
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
        if(!qd0_blind_id_finish_private_id_request(pubkeys[keygen_i], p[0], l[0]))
        {
                Con_Printf("d0_blind_id_finish_private_id_request failed\n");
                keygen_i = -1;
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
 
@@ -980,6 +1000,7 @@ static void Crypto_KeyGen_Finished(int code, size_t length_received, unsigned ch
        {
                Con_Printf("d0_blind_id_new failed\n");
                keygen_i = -1;
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
        ctx2 = qd0_blind_id_new();
@@ -988,6 +1009,7 @@ static void Crypto_KeyGen_Finished(int code, size_t length_received, unsigned ch
                Con_Printf("d0_blind_id_new failed\n");
                qd0_blind_id_free(ctx);
                keygen_i = -1;
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
        if(!qd0_blind_id_copy(ctx, pubkeys[keygen_i]))
@@ -996,6 +1018,7 @@ static void Crypto_KeyGen_Finished(int code, size_t length_received, unsigned ch
                qd0_blind_id_free(ctx);
                qd0_blind_id_free(ctx2);
                keygen_i = -1;
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
        if(!qd0_blind_id_copy(ctx2, pubkeys[keygen_i]))
@@ -1004,6 +1027,7 @@ static void Crypto_KeyGen_Finished(int code, size_t length_received, unsigned ch
                qd0_blind_id_free(ctx);
                qd0_blind_id_free(ctx2);
                keygen_i = -1;
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
        bufsize = sizeof(buf);
@@ -1013,6 +1037,7 @@ static void Crypto_KeyGen_Finished(int code, size_t length_received, unsigned ch
                qd0_blind_id_free(ctx);
                qd0_blind_id_free(ctx2);
                keygen_i = -1;
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
        buf2size = sizeof(buf2);
@@ -1022,6 +1047,7 @@ static void Crypto_KeyGen_Finished(int code, size_t length_received, unsigned ch
                qd0_blind_id_free(ctx);
                qd0_blind_id_free(ctx2);
                keygen_i = -1;
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
        bufsize = sizeof(buf);
@@ -1031,6 +1057,7 @@ static void Crypto_KeyGen_Finished(int code, size_t length_received, unsigned ch
                qd0_blind_id_free(ctx);
                qd0_blind_id_free(ctx2);
                keygen_i = -1;
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
        buf2size = sizeof(buf2);
@@ -1040,6 +1067,7 @@ static void Crypto_KeyGen_Finished(int code, size_t length_received, unsigned ch
                qd0_blind_id_free(ctx);
                qd0_blind_id_free(ctx2);
                keygen_i = -1;
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
        qd0_blind_id_free(ctx);
@@ -1052,7 +1080,7 @@ static void Crypto_KeyGen_Finished(int code, size_t length_received, unsigned ch
        {
                Con_Printf("Received private ID key_%d.d0pk (public key fingerprint: %s)\n", keygen_i, pubkeys_priv_fp64[keygen_i]);
                pubkeys_havepriv[keygen_i] = true;
-               strlcat(crypto_idstring_buf, va(" %s@%s", pubkeys_priv_fp64[keygen_i], pubkeys_fp64[keygen_i]), sizeof(crypto_idstring_buf));
+               strlcat(crypto_idstring_buf, va(vabuf, sizeof(vabuf), " %s@%s", pubkeys_priv_fp64[keygen_i], pubkeys_fp64[keygen_i]), sizeof(crypto_idstring_buf));
                crypto_idstring = crypto_idstring_buf;
                Crypto_BuildChallengeAppend();
        }
@@ -1063,29 +1091,32 @@ static void Crypto_KeyGen_Finished(int code, size_t length_received, unsigned ch
        {
                Con_Printf("d0_blind_id_write_private_id failed\n");
                keygen_i = -1;
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
        if(!(buf2size = Crypto_UnParsePack(buf2, sizeof(buf2), FOURCC_D0SI, p, l, 1)))
        {
                Con_Printf("Crypto_UnParsePack failed\n");
                keygen_i = -1;
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
 
        if(*fs_userdir)
        {
-               FS_CreatePath(va("%skey_%d.d0si", fs_userdir, keygen_i));
-               f = FS_SysOpen(va("%skey_%d.d0si", fs_userdir, keygen_i), "wb", false);
+               FS_CreatePath(va(vabuf, sizeof(vabuf), "%skey_%d.d0si", fs_userdir, keygen_i));
+               f = FS_SysOpen(va(vabuf, sizeof(vabuf), "%skey_%d.d0si", fs_userdir, keygen_i), "wb", false);
        }
        if(!f)
        {
-               FS_CreatePath(va("%skey_%d.d0si", fs_basedir, keygen_i));
-               f = FS_SysOpen(va("%skey_%d.d0si", fs_basedir, keygen_i), "wb", false);
+               FS_CreatePath(va(vabuf, sizeof(vabuf), "%skey_%d.d0si", fs_basedir, keygen_i));
+               f = FS_SysOpen(va(vabuf, sizeof(vabuf), "%skey_%d.d0si", fs_basedir, keygen_i), "wb", false);
        }
        if(!f)
        {
                Con_Printf("Cannot open key_%d.d0si\n", keygen_i);
                keygen_i = -1;
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
        FS_Write(f, buf2, buf2size);
@@ -1093,6 +1124,7 @@ static void Crypto_KeyGen_Finished(int code, size_t length_received, unsigned ch
 
        Con_Printf("Saved to key_%d.d0si\n", keygen_i);
        keygen_i = -1;
+       if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
 }
 
 static void Crypto_KeyGen_f(void)
@@ -1113,20 +1145,24 @@ static void Crypto_KeyGen_f(void)
                Con_Printf("usage:\n%s id url\n", Cmd_Argv(0));
                return;
        }
+       if (crypto_mutex) Thread_LockMutex(crypto_mutex);
        i = atoi(Cmd_Argv(1));
        if(!pubkeys[i])
        {
                Con_Printf("there is no public key %d\n", i);
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
        if(pubkeys_havepriv[i])
        {
                Con_Printf("there is already a private key for %d\n", i);
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
        if(keygen_i >= 0)
        {
                Con_Printf("there is already a keygen run on the way\n");
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
        keygen_i = i;
@@ -1134,6 +1170,7 @@ static void Crypto_KeyGen_f(void)
        {
                Con_Printf("d0_blind_id_start failed\n");
                keygen_i = -1;
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
        p[0] = buf;
@@ -1142,6 +1179,7 @@ static void Crypto_KeyGen_f(void)
        {
                Con_Printf("d0_blind_id_generate_private_id_request failed\n");
                keygen_i = -1;
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
        buf2pos = strlen(Cmd_Argv(2));
@@ -1150,12 +1188,14 @@ static void Crypto_KeyGen_f(void)
        {
                Con_Printf("Crypto_UnParsePack failed\n");
                keygen_i = -1;
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
        if(!(buf2l = base64_encode((unsigned char *) (buf2 + buf2pos), buf2l, sizeof(buf2) - buf2pos - 1)))
        {
                Con_Printf("base64_encode failed\n");
                keygen_i = -1;
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
        buf2l += buf2pos;
@@ -1164,9 +1204,11 @@ static void Crypto_KeyGen_f(void)
        {
                Con_Printf("curl failed\n");
                keygen_i = -1;
+               if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
                return;
        }
        Con_Printf("key generation in progress\n");
+       if (crypto_mutex) Thread_UnlockMutex(crypto_mutex);
 }
 // end
 
@@ -1529,6 +1571,8 @@ static int Crypto_ServerParsePacket_Internal(const char *data_in, size_t len_in,
        int aeslevel;
        D0_BOOL aes;
        D0_BOOL status;
+       char infostringvalue[MAX_INPUTLINE];
+       char vabuf[1024];
 
        if(!d0_blind_id_dll)
                return CRYPTO_NOMATCH; // no support
@@ -1539,7 +1583,7 @@ static int Crypto_ServerParsePacket_Internal(const char *data_in, size_t len_in,
                int i;
                // sorry, we have to verify the challenge here to not reflect network spam
 
-               if (!(s = SearchInfostring(string + 4, "challenge")))
+               if (!(s = InfoString_GetValue(string + 4, "challenge", infostringvalue, sizeof(infostringvalue))))
                        return CRYPTO_NOMATCH; // will be later accepted if encryption was set up
                // validate the challenge
                for (i = 0;i < MAX_CHALLENGES;i++)
@@ -1559,9 +1603,9 @@ static int Crypto_ServerParsePacket_Internal(const char *data_in, size_t len_in,
                const char *cnt, *s, *p;
                int id;
                int clientid = -1, serverid = -1;
-               cnt = SearchInfostring(string + 4, "id");
+               cnt = InfoString_GetValue(string + 4, "id", infostringvalue, sizeof(infostringvalue));
                id = (cnt ? atoi(cnt) : -1);
-               cnt = SearchInfostring(string + 4, "cnt");
+               cnt = InfoString_GetValue(string + 4, "cnt", infostringvalue, sizeof(infostringvalue));
                if(!cnt)
                        return CRYPTO_DISCARD; // pre-challenge: rather be silent
                GetUntilNul(&data_in, &len_in);
@@ -1570,7 +1614,7 @@ static int Crypto_ServerParsePacket_Internal(const char *data_in, size_t len_in,
                if(!strcmp(cnt, "0"))
                {
                        int i;
-                       if (!(s = SearchInfostring(string + 4, "challenge")))
+                       if (!(s = InfoString_GetValue(string + 4, "challenge", infostringvalue, sizeof(infostringvalue))))
                                return CRYPTO_DISCARD; // pre-challenge: rather be silent
                        // validate the challenge
                        for (i = 0;i < MAX_CHALLENGES;i++)
@@ -1581,7 +1625,7 @@ static int Crypto_ServerParsePacket_Internal(const char *data_in, size_t len_in,
                        if (i == MAX_CHALLENGES) // challenge mismatch is silent
                                return CRYPTO_DISCARD; // pre-challenge: rather be silent
 
-                       if (!(s = SearchInfostring(string + 4, "aeslevel")))
+                       if (!(s = InfoString_GetValue(string + 4, "aeslevel", infostringvalue, sizeof(infostringvalue))))
                                aeslevel = 0; // not supported
                        else
                                aeslevel = bound(0, atoi(s), 3);
@@ -1667,7 +1711,7 @@ static int Crypto_ServerParsePacket_Internal(const char *data_in, size_t len_in,
                                        CLEAR_CDATA;
                                        return Crypto_ServerError(data_out, len_out, "d0_blind_id_copy failed", "Internal error");
                                }
-                               PutWithNul(&data_out_p, len_out, va("d0pk\\cnt\\1\\id\\%d\\aes\\%d", CDATA->cdata_id, crypto->use_aes));
+                               PutWithNul(&data_out_p, len_out, va(vabuf, sizeof(vabuf), "d0pk\\cnt\\1\\id\\%d\\aes\\%d", CDATA->cdata_id, crypto->use_aes));
                                if(!qd0_blind_id_authenticate_with_private_id_start(CDATA->id, true, false, "XONOTIC", 8, data_out_p, len_out)) // len_out receives used size by this op
                                {
                                        CLEAR_CDATA;
@@ -1692,7 +1736,7 @@ static int Crypto_ServerParsePacket_Internal(const char *data_in, size_t len_in,
                                        CLEAR_CDATA;
                                        return Crypto_ServerError(data_out, len_out, "d0_blind_id_copy failed", "Internal error");
                                }
-                               PutWithNul(&data_out_p, len_out, va("d0pk\\cnt\\5\\id\\%d\\aes\\%d", CDATA->cdata_id, crypto->use_aes));
+                               PutWithNul(&data_out_p, len_out, va(vabuf, sizeof(vabuf), "d0pk\\cnt\\5\\id\\%d\\aes\\%d", CDATA->cdata_id, crypto->use_aes));
                                if(!qd0_blind_id_authenticate_with_private_id_challenge(CDATA->id, true, false, data_in, len_in, data_out_p, len_out, &status))
                                {
                                        CLEAR_CDATA;
@@ -1717,11 +1761,11 @@ static int Crypto_ServerParsePacket_Internal(const char *data_in, size_t len_in,
                                return CRYPTO_NOMATCH; // pre-challenge, rather be silent
                        if(id >= 0)
                                if(CDATA->cdata_id != id)
-                                       return Crypto_SoftServerError(data_out, len_out, va("Got d0pk\\id\\%d when expecting %d", id, CDATA->cdata_id));
+                                       return Crypto_SoftServerError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\id\\%d when expecting %d", id, CDATA->cdata_id));
                        if(CDATA->next_step != 2)
-                               return Crypto_SoftServerError(data_out, len_out, va("Got d0pk\\cnt\\%s when expecting %d", cnt, CDATA->next_step));
+                               return Crypto_SoftServerError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\cnt\\%s when expecting %d", cnt, CDATA->next_step));
 
-                       PutWithNul(&data_out_p, len_out, va("d0pk\\cnt\\3\\id\\%d", CDATA->cdata_id));
+                       PutWithNul(&data_out_p, len_out, va(vabuf, sizeof(vabuf), "d0pk\\cnt\\3\\id\\%d", CDATA->cdata_id));
                        if(!qd0_blind_id_authenticate_with_private_id_response(CDATA->id, data_in, len_in, data_out_p, len_out))
                        {
                                CLEAR_CDATA;
@@ -1759,10 +1803,10 @@ static int Crypto_ServerParsePacket_Internal(const char *data_in, size_t len_in,
                                return CRYPTO_NOMATCH; // pre-challenge, rather be silent
                        if(id >= 0)
                                if(CDATA->cdata_id != id)
-                                       return Crypto_SoftServerError(data_out, len_out, va("Got d0pk\\id\\%d when expecting %d", id, CDATA->cdata_id));
+                                       return Crypto_SoftServerError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\id\\%d when expecting %d", id, CDATA->cdata_id));
                        if(CDATA->next_step != 4)
-                               return Crypto_SoftServerError(data_out, len_out, va("Got d0pk\\cnt\\%s when expecting %d", cnt, CDATA->next_step));
-                       PutWithNul(&data_out_p, len_out, va("d0pk\\cnt\\5\\id\\%d", CDATA->cdata_id));
+                               return Crypto_SoftServerError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\cnt\\%s when expecting %d", cnt, CDATA->next_step));
+                       PutWithNul(&data_out_p, len_out, va(vabuf, sizeof(vabuf), "d0pk\\cnt\\5\\id\\%d", CDATA->cdata_id));
                        if(!qd0_blind_id_authenticate_with_private_id_challenge(CDATA->id, true, false, data_in, len_in, data_out_p, len_out, &status))
                        {
                                CLEAR_CDATA;
@@ -1785,9 +1829,9 @@ static int Crypto_ServerParsePacket_Internal(const char *data_in, size_t len_in,
                                return CRYPTO_NOMATCH; // pre-challenge, rather be silent
                        if(id >= 0)
                                if(CDATA->cdata_id != id)
-                                       return Crypto_SoftServerError(data_out, len_out, va("Got d0pk\\id\\%d when expecting %d", id, CDATA->cdata_id));
+                                       return Crypto_SoftServerError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\id\\%d when expecting %d", id, CDATA->cdata_id));
                        if(CDATA->next_step != 6)
-                               return Crypto_SoftServerError(data_out, len_out, va("Got d0pk\\cnt\\%s when expecting %d", cnt, CDATA->next_step));
+                               return Crypto_SoftServerError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\cnt\\%s when expecting %d", cnt, CDATA->next_step));
 
                        if(!qd0_blind_id_authenticate_with_private_id_verify(CDATA->id, data_in, len_in, msgbuf, &msgbuflen, &status))
                        {
@@ -1837,11 +1881,12 @@ int Crypto_ServerParsePacket(const char *data_in, size_t len_in, char *data_out,
        const char *cnt;
        qboolean do_time = false;
        qboolean do_reject = false;
+       char infostringvalue[MAX_INPUTLINE];
        if(crypto_servercpupercent.value > 0 || crypto_servercpumaxtime.value > 0)
                if(len_in > 5 && !memcmp(data_in, "d0pk\\", 5))
                {
                        do_time = true;
-                       cnt = SearchInfostring(data_in + 4, "cnt");
+                       cnt = InfoString_GetValue(data_in + 4, "cnt", infostringvalue, sizeof(infostringvalue));
                        if(cnt)
                                if(!strcmp(cnt, "0"))
                                        do_reject = true;
@@ -1870,12 +1915,12 @@ int Crypto_ServerParsePacket(const char *data_in, size_t len_in, char *data_out,
                        *len_out = 0;
                        return CRYPTO_DISCARD;
                }
-               t = Sys_DoubleTime();
+               t = Sys_DirtyTime();
        }
        ret = Crypto_ServerParsePacket_Internal(data_in, len_in, data_out, len_out, peeraddress);
        if(do_time)
        {
-               t = Sys_DoubleTime() - t;
+               t = Sys_DirtyTime() - t;if (t < 0.0) t = 0.0; // dirtytime can step backwards
                if(crypto_servercpudebug.integer)
                        Con_Printf("crypto: accumulator was %.1f ms, used %.1f ms for crypto, ", crypto_servercpu_accumulator * 1000, t * 1000);
                crypto_servercpu_accumulator -= t;
@@ -1907,6 +1952,8 @@ int Crypto_ClientParsePacket(const char *data_in, size_t len_in, char *data_out,
        D0_BOOL aes;
        char *data_out_p = data_out;
        D0_BOOL status;
+       char infostringvalue[MAX_INPUTLINE];
+       char vabuf[1024];
 
        if(!d0_blind_id_dll)
                return CRYPTO_NOMATCH; // no support
@@ -1942,7 +1989,7 @@ int Crypto_ClientParsePacket(const char *data_in, size_t len_in, char *data_out,
        }
        else if (len_in >= 13 && !memcmp(string, "infoResponse\x0A", 13))
        {
-               s = SearchInfostring(string + 13, "d0_blind_id");
+               s = InfoString_GetValue(string + 13, "d0_blind_id", infostringvalue, sizeof(infostringvalue));
                if(s)
                        Crypto_StoreHostKey(peeraddress, s, true);
                return CRYPTO_NOMATCH;
@@ -1957,7 +2004,7 @@ int Crypto_ClientParsePacket(const char *data_in, size_t len_in, char *data_out,
                        save = *p;
                        * (char *) p = 0; // cut off the string there
                }
-               s = SearchInfostring(string + 15, "d0_blind_id");
+               s = InfoString_GetValue(string + 15, "d0_blind_id", infostringvalue, sizeof(infostringvalue));
                if(s)
                        Crypto_StoreHostKey(peeraddress, s, true);
                if(p)
@@ -2117,7 +2164,7 @@ int Crypto_ClientParsePacket(const char *data_in, size_t len_in, char *data_out,
 
                        // build outgoing message
                        // append regular stuff
-                       PutWithNul(&data_out_p, len_out, va("d0pk\\cnt\\0\\id\\%d\\aeslevel\\%d\\challenge\\%s", CDATA->cdata_id, d0_rijndael_dll ? crypto_aeslevel.integer : 0, challenge));
+                       PutWithNul(&data_out_p, len_out, va(vabuf, sizeof(vabuf), "d0pk\\cnt\\0\\id\\%d\\aeslevel\\%d\\challenge\\%s", CDATA->cdata_id, d0_rijndael_dll ? crypto_aeslevel.integer : 0, challenge));
                        PutWithNul(&data_out_p, len_out, serverid >= 0 ? pubkeys_fp64[serverid] : "");
                        PutWithNul(&data_out_p, len_out, clientid >= 0 ? pubkeys_fp64[clientid] : "");
 
@@ -2187,9 +2234,9 @@ int Crypto_ClientParsePacket(const char *data_in, size_t len_in, char *data_out,
        {
                const char *cnt;
                int id;
-               cnt = SearchInfostring(string + 4, "id");
+               cnt = InfoString_GetValue(string + 4, "id", infostringvalue, sizeof(infostringvalue));
                id = (cnt ? atoi(cnt) : -1);
-               cnt = SearchInfostring(string + 4, "cnt");
+               cnt = InfoString_GetValue(string + 4, "cnt", infostringvalue, sizeof(infostringvalue));
                if(!cnt)
                        return Crypto_ClientError(data_out, len_out, "d0pk\\ message without cnt");
                GetUntilNul(&data_in, &len_in);
@@ -2200,13 +2247,13 @@ int Crypto_ClientParsePacket(const char *data_in, size_t len_in, char *data_out,
                {
                        if(id >= 0)
                                if(CDATA->cdata_id != id)
-                                       return Crypto_SoftServerError(data_out, len_out, va("Got d0pk\\id\\%d when expecting %d", id, CDATA->cdata_id));
+                                       return Crypto_SoftServerError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\id\\%d when expecting %d", id, CDATA->cdata_id));
                        if(CDATA->next_step != 1)
-                               return Crypto_SoftClientError(data_out, len_out, va("Got d0pk\\cnt\\%s when expecting %d", cnt, CDATA->next_step));
+                               return Crypto_SoftClientError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\cnt\\%s when expecting %d", cnt, CDATA->next_step));
 
                        cls.connect_nextsendtime = max(cls.connect_nextsendtime, realtime + 1); // prevent "hammering"
 
-                       if((s = SearchInfostring(string + 4, "aes")))
+                       if((s = InfoString_GetValue(string + 4, "aes", infostringvalue, sizeof(infostringvalue))))
                                aes = atoi(s);
                        else
                                aes = false;
@@ -2230,7 +2277,7 @@ int Crypto_ClientParsePacket(const char *data_in, size_t len_in, char *data_out,
                        }
                        crypto->use_aes = aes != 0;
 
-                       PutWithNul(&data_out_p, len_out, va("d0pk\\cnt\\2\\id\\%d", CDATA->cdata_id));
+                       PutWithNul(&data_out_p, len_out, va(vabuf, sizeof(vabuf), "d0pk\\cnt\\2\\id\\%d", CDATA->cdata_id));
                        if(!qd0_blind_id_authenticate_with_private_id_challenge(CDATA->id, true, false, data_in, len_in, data_out_p, len_out, &status))
                        {
                                CLEAR_CDATA;
@@ -2249,9 +2296,9 @@ int Crypto_ClientParsePacket(const char *data_in, size_t len_in, char *data_out,
 
                        if(id >= 0)
                                if(CDATA->cdata_id != id)
-                                       return Crypto_SoftServerError(data_out, len_out, va("Got d0pk\\id\\%d when expecting %d", id, CDATA->cdata_id));
+                                       return Crypto_SoftServerError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\id\\%d when expecting %d", id, CDATA->cdata_id));
                        if(CDATA->next_step != 3)
-                               return Crypto_SoftClientError(data_out, len_out, va("Got d0pk\\cnt\\%s when expecting %d", cnt, CDATA->next_step));
+                               return Crypto_SoftClientError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\cnt\\%s when expecting %d", cnt, CDATA->next_step));
 
                        cls.connect_nextsendtime = max(cls.connect_nextsendtime, realtime + 1); // prevent "hammering"
 
@@ -2285,12 +2332,12 @@ int Crypto_ClientParsePacket(const char *data_in, size_t len_in, char *data_out,
                        }
 
                        // cache the server key
-                       Crypto_StoreHostKey(&cls.connect_address, va("%d %s@%s", crypto->use_aes ? 1 : 0, crypto->server_idfp, pubkeys_fp64[CDATA->s]), false);
+                       Crypto_StoreHostKey(&cls.connect_address, va(vabuf, sizeof(vabuf), "%d %s@%s", crypto->use_aes ? 1 : 0, crypto->server_idfp, pubkeys_fp64[CDATA->s]), false);
 
                        if(CDATA->c >= 0)
                        {
                                // client will auth next
-                               PutWithNul(&data_out_p, len_out, va("d0pk\\cnt\\4\\id\\%d", CDATA->cdata_id));
+                               PutWithNul(&data_out_p, len_out, va(vabuf, sizeof(vabuf), "d0pk\\cnt\\4\\id\\%d", CDATA->cdata_id));
                                if(!qd0_blind_id_copy(CDATA->id, pubkeys[CDATA->c]))
                                {
                                        CLEAR_CDATA;
@@ -2326,15 +2373,15 @@ int Crypto_ClientParsePacket(const char *data_in, size_t len_in, char *data_out,
 
                        if(id >= 0)
                                if(CDATA->cdata_id != id)
-                                       return Crypto_SoftServerError(data_out, len_out, va("Got d0pk\\id\\%d when expecting %d", id, CDATA->cdata_id));
+                                       return Crypto_SoftServerError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\id\\%d when expecting %d", id, CDATA->cdata_id));
                        if(CDATA->next_step != 5)
-                               return Crypto_SoftClientError(data_out, len_out, va("Got d0pk\\cnt\\%s when expecting %d", cnt, CDATA->next_step));
+                               return Crypto_SoftClientError(data_out, len_out, va(vabuf, sizeof(vabuf), "Got d0pk\\cnt\\%s when expecting %d", cnt, CDATA->next_step));
 
                        cls.connect_nextsendtime = max(cls.connect_nextsendtime, realtime + 1); // prevent "hammering"
 
                        if(CDATA->s < 0) // only if server didn't auth
                        {
-                               if((s = SearchInfostring(string + 4, "aes")))
+                               if((s = InfoString_GetValue(string + 4, "aes", infostringvalue, sizeof(infostringvalue))))
                                        aes = atoi(s);
                                else
                                        aes = false;
@@ -2357,7 +2404,7 @@ int Crypto_ClientParsePacket(const char *data_in, size_t len_in, char *data_out,
                                crypto->use_aes = aes != 0;
                        }
 
-                       PutWithNul(&data_out_p, len_out, va("d0pk\\cnt\\6\\id\\%d", CDATA->cdata_id));
+                       PutWithNul(&data_out_p, len_out, va(vabuf, sizeof(vabuf), "d0pk\\cnt\\6\\id\\%d", CDATA->cdata_id));
                        if(!qd0_blind_id_authenticate_with_private_id_response(CDATA->id, data_in, len_in, data_out_p, len_out))
                        {
                                CLEAR_CDATA;
index 77e3a16bdca3d599a65422d2a3f08a717c81c561..79af0570f09565a1f0f247f9d648e60766db6a2a 100644 (file)
--- a/csprogs.c
+++ b/csprogs.c
 //[515]: omg !!! optimize it ! a lot of hacks here and there also :P
 
 #define CSQC_RETURNVAL prog->globals.generic[OFS_RETURN]
-#define CSQC_BEGIN             csqc_tmpprog=prog;prog=0;PRVM_SetProg(PRVM_CLIENTPROG);
-#define CSQC_END               prog=csqc_tmpprog;
-
-static prvm_prog_t *csqc_tmpprog;
+#define CSQC_BEGIN
+#define CSQC_END
 
 void CL_VM_PreventInformationLeaks(void)
 {
+       prvm_prog_t *prog = CLVM_prog;
        if(!cl.csqc_loaded)
                return;
        CSQC_BEGIN
-               VM_ClearTraceGlobals();
+               VM_ClearTraceGlobals(prog);
                PRVM_clientglobalfloat(trace_networkentity) = 0;
        CSQC_END
 }
@@ -196,28 +195,9 @@ prvm_required_field_t cl_reqglobals[] =
 #undef PRVM_DECLARE_function
 };
 
-void CL_VM_Error (const char *format, ...) DP_FUNC_PRINTF(1);
-void CL_VM_Error (const char *format, ...)     //[515]: hope it will be never executed =)
-{
-       char errorstring[4096];
-       va_list argptr;
-
-       va_start (argptr, format);
-       dpvsnprintf (errorstring, sizeof(errorstring), format, argptr);
-       va_end (argptr);
-//     Con_Printf( "CL_VM_Error: %s\n", errorstring );
-
-       PRVM_Crash();
-       cl.csqc_loaded = false;
-
-       Cvar_SetValueQuick(&csqc_progcrc, -1);
-       Cvar_SetValueQuick(&csqc_progsize, -1);
-
-//     Host_AbortCurrentFrame();       //[515]: hmmm... if server says it needs csqc then client MUST disconnect
-       Host_Error("CL_VM_Error: %s", errorstring);
-}
 void CL_VM_UpdateDmgGlobals (int dmg_take, int dmg_save, vec3_t dmg_origin)
 {
+       prvm_prog_t *prog = CLVM_prog;
        if(cl.csqc_loaded)
        {
                CSQC_BEGIN
@@ -230,6 +210,7 @@ void CL_VM_UpdateDmgGlobals (int dmg_take, int dmg_save, vec3_t dmg_origin)
 
 void CSQC_UpdateNetworkTimes(double newtime, double oldtime)
 {
+       prvm_prog_t *prog = CLVM_prog;
        if(!cl.csqc_loaded)
                return;
        CSQC_BEGIN
@@ -240,9 +221,9 @@ void CSQC_UpdateNetworkTimes(double newtime, double oldtime)
 }
 
 //[515]: set globals before calling R_UpdateView, WEIRD CRAP
-void CSQC_R_RecalcView (void);
 static void CSQC_SetGlobals (void)
 {
+       prvm_prog_t *prog = CLVM_prog;
        CSQC_BEGIN
                PRVM_clientglobalfloat(time) = cl.time;
                PRVM_clientglobalfloat(frametime) = max(0, cl.time - cl.oldtime);
@@ -274,17 +255,19 @@ static void CSQC_SetGlobals (void)
 
 void CSQC_Predraw (prvm_edict_t *ed)
 {
+       prvm_prog_t *prog = CLVM_prog;
        int b;
        if(!PRVM_clientedictfunction(ed, predraw))
                return;
        b = PRVM_clientglobaledict(self);
        PRVM_clientglobaledict(self) = PRVM_EDICT_TO_PROG(ed);
-       PRVM_ExecuteProgram(PRVM_clientedictfunction(ed, predraw), "CSQC_Predraw: NULL function\n");
+       prog->ExecuteProgram(prog, PRVM_clientedictfunction(ed, predraw), "CSQC_Predraw: NULL function\n");
        PRVM_clientglobaledict(self) = b;
 }
 
 void CSQC_Think (prvm_edict_t *ed)
 {
+       prvm_prog_t *prog = CLVM_prog;
        int b;
        if(PRVM_clientedictfunction(ed, think))
        if(PRVM_clientedictfloat(ed, nextthink) && PRVM_clientedictfloat(ed, nextthink) <= PRVM_clientglobalfloat(time))
@@ -292,7 +275,7 @@ void CSQC_Think (prvm_edict_t *ed)
                PRVM_clientedictfloat(ed, nextthink) = 0;
                b = PRVM_clientglobaledict(self);
                PRVM_clientglobaledict(self) = PRVM_EDICT_TO_PROG(ed);
-               PRVM_ExecuteProgram(PRVM_clientedictfunction(ed, think), "CSQC_Think: NULL function\n");
+               prog->ExecuteProgram(prog, PRVM_clientedictfunction(ed, think), "CSQC_Think: NULL function\n");
                PRVM_clientglobaledict(self) = b;
        }
 }
@@ -301,6 +284,7 @@ extern cvar_t cl_noplayershadow;
 extern cvar_t r_equalize_entities_fullbright;
 qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum)
 {
+       prvm_prog_t *prog = CLVM_prog;
        int renderflags;
        int c;
        float scale;
@@ -357,12 +341,12 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum)
                VectorSet(entrender->glowmod, 1, 1, 1);
 
        // LordHavoc: use the CL_GetTagMatrix function on self to ensure consistent behavior (duplicate code would be bad)
-       CL_GetTagMatrix(&entrender->matrix, ed, 0);
+       CL_GetTagMatrix(prog, &entrender->matrix, ed, 0);
 
        // set up the animation data
-       VM_GenerateFrameGroupBlend(ed->priv.server->framegroupblend, ed);
+       VM_GenerateFrameGroupBlend(prog, ed->priv.server->framegroupblend, ed);
        VM_FrameBlendFromFrameGroupBlend(ed->priv.server->frameblend, ed->priv.server->framegroupblend, model);
-       VM_UpdateEdictSkeleton(ed, model, ed->priv.server->frameblend);
+       VM_UpdateEdictSkeleton(prog, ed, model, ed->priv.server->frameblend);
        if (PRVM_clientedictfloat(ed, shadertime)) // hack for csprogs.dat files that do not set shadertime, leaves the value at entity spawn time
                entrender->shadertime = PRVM_clientedictfloat(ed, shadertime);
 
@@ -442,6 +426,7 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum)
 // 3 = mousemove absolute, x, y (DP_CSQC)
 qboolean CL_VM_InputEvent (int eventtype, int x, int y)
 {
+       prvm_prog_t *prog = CLVM_prog;
        qboolean r;
 
        if(!cl.csqc_loaded)
@@ -457,7 +442,7 @@ qboolean CL_VM_InputEvent (int eventtype, int x, int y)
                        PRVM_G_FLOAT(OFS_PARM0) = eventtype;
                        PRVM_G_FLOAT(OFS_PARM1) = x; // key or x
                        PRVM_G_FLOAT(OFS_PARM2) = y; // ascii or y
-                       PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_InputEvent), "QC function CSQC_InputEvent is missing");
+                       prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_InputEvent), "QC function CSQC_InputEvent is missing");
                        r = CSQC_RETURNVAL != 0;
                }
        CSQC_END
@@ -467,6 +452,7 @@ qboolean CL_VM_InputEvent (int eventtype, int x, int y)
 extern r_refdef_view_t csqc_original_r_refdef_view;
 qboolean CL_VM_UpdateView (void)
 {
+       prvm_prog_t *prog = CLVM_prog;
        vec3_t emptyvector;
        emptyvector[0] = 0;
        emptyvector[1] = 0;
@@ -488,7 +474,7 @@ qboolean CL_VM_UpdateView (void)
                // pass in width and height as parameters (EXT_CSQC_1)
                PRVM_G_FLOAT(OFS_PARM0) = vid.width;
                PRVM_G_FLOAT(OFS_PARM1) = vid.height;
-               PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_UpdateView), "QC function CSQC_UpdateView is missing");
+               prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_UpdateView), "QC function CSQC_UpdateView is missing");
                //VectorCopy(oldangles, cl.viewangles);
                // Dresk : Reset Dmg Globals Here
                CL_VM_UpdateDmgGlobals(0, 0, emptyvector);
@@ -498,9 +484,9 @@ qboolean CL_VM_UpdateView (void)
        return true;
 }
 
-extern sizebuf_t vm_tempstringsbuf;
 qboolean CL_VM_ConsoleCommand (const char *cmd)
 {
+       prvm_prog_t *prog = CLVM_prog;
        int restorevm_tempstringsbuf_cursize;
        qboolean r = false;
        if(!cl.csqc_loaded)
@@ -510,10 +496,10 @@ qboolean CL_VM_ConsoleCommand (const char *cmd)
        {
                PRVM_clientglobalfloat(time) = cl.time;
                PRVM_clientglobaledict(self) = cl.csqc_server2csqcentitynumber[cl.playerentity];
-               restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize;
-               PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(cmd);
-               PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_ConsoleCommand), "QC function CSQC_ConsoleCommand is missing");
-               vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
+               restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize;
+               PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, cmd);
+               prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_ConsoleCommand), "QC function CSQC_ConsoleCommand is missing");
+               prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
                r = CSQC_RETURNVAL != 0;
        }
        CSQC_END
@@ -522,6 +508,7 @@ qboolean CL_VM_ConsoleCommand (const char *cmd)
 
 qboolean CL_VM_Parse_TempEntity (void)
 {
+       prvm_prog_t *prog = CLVM_prog;
        int                     t;
        qboolean        r = false;
        if(!cl.csqc_loaded)
@@ -529,15 +516,15 @@ qboolean CL_VM_Parse_TempEntity (void)
        CSQC_BEGIN
        if(PRVM_clientfunction(CSQC_Parse_TempEntity))
        {
-               t = msg_readcount;
+               t = cl_message.readcount;
                PRVM_clientglobalfloat(time) = cl.time;
                PRVM_clientglobaledict(self) = cl.csqc_server2csqcentitynumber[cl.playerentity];
-               PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Parse_TempEntity), "QC function CSQC_Parse_TempEntity is missing");
+               prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_Parse_TempEntity), "QC function CSQC_Parse_TempEntity is missing");
                r = CSQC_RETURNVAL != 0;
                if(!r)
                {
-                       msg_readcount = t;
-                       msg_badread = false;
+                       cl_message.readcount = t;
+                       cl_message.badread = false;
                }
        }
        CSQC_END
@@ -546,6 +533,7 @@ qboolean CL_VM_Parse_TempEntity (void)
 
 void CL_VM_Parse_StuffCmd (const char *msg)
 {
+       prvm_prog_t *prog = CLVM_prog;
        int restorevm_tempstringsbuf_cursize;
        if(msg[0] == 'c')
        if(msg[1] == 's')
@@ -614,10 +602,10 @@ void CL_VM_Parse_StuffCmd (const char *msg)
        {
                PRVM_clientglobalfloat(time) = cl.time;
                PRVM_clientglobaledict(self) = cl.csqc_server2csqcentitynumber[cl.playerentity];
-               restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize;
-               PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(msg);
-               PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Parse_StuffCmd), "QC function CSQC_Parse_StuffCmd is missing");
-               vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
+               restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize;
+               PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, msg);
+               prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_Parse_StuffCmd), "QC function CSQC_Parse_StuffCmd is missing");
+               prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
        }
        else
                Cbuf_AddText(msg);
@@ -626,17 +614,19 @@ void CL_VM_Parse_StuffCmd (const char *msg)
 
 static void CL_VM_Parse_Print (const char *msg)
 {
+       prvm_prog_t *prog = CLVM_prog;
        int restorevm_tempstringsbuf_cursize;
        PRVM_clientglobalfloat(time) = cl.time;
        PRVM_clientglobaledict(self) = cl.csqc_server2csqcentitynumber[cl.playerentity];
-       restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize;
-       PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(msg);
-       PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Parse_Print), "QC function CSQC_Parse_Print is missing");
-       vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
+       restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize;
+       PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, msg);
+       prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_Parse_Print), "QC function CSQC_Parse_Print is missing");
+       prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
 }
 
 void CSQC_AddPrintText (const char *msg)
 {
+       prvm_prog_t *prog = CLVM_prog;
        size_t i;
        if(!cl.csqc_loaded)
        {
@@ -670,6 +660,7 @@ void CSQC_AddPrintText (const char *msg)
 
 void CL_VM_Parse_CenterPrint (const char *msg)
 {
+       prvm_prog_t *prog = CLVM_prog;
        int restorevm_tempstringsbuf_cursize;
        if(!cl.csqc_loaded)
        {
@@ -681,10 +672,10 @@ void CL_VM_Parse_CenterPrint (const char *msg)
        {
                PRVM_clientglobalfloat(time) = cl.time;
                PRVM_clientglobaledict(self) = cl.csqc_server2csqcentitynumber[cl.playerentity];
-               restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize;
-               PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(msg);
-               PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Parse_CenterPrint), "QC function CSQC_Parse_CenterPrint is missing");
-               vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
+               restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize;
+               PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, msg);
+               prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_Parse_CenterPrint), "QC function CSQC_Parse_CenterPrint is missing");
+               prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
        }
        else
                SCR_CenterPrint(msg);
@@ -693,6 +684,7 @@ void CL_VM_Parse_CenterPrint (const char *msg)
 
 void CL_VM_UpdateIntermissionState (int intermission)
 {
+       prvm_prog_t *prog = CLVM_prog;
        if(cl.csqc_loaded)
        {
                CSQC_BEGIN
@@ -702,6 +694,7 @@ void CL_VM_UpdateIntermissionState (int intermission)
 }
 void CL_VM_UpdateShowingScoresState (int showingscores)
 {
+       prvm_prog_t *prog = CLVM_prog;
        if(cl.csqc_loaded)
        {
                CSQC_BEGIN
@@ -711,6 +704,7 @@ void CL_VM_UpdateShowingScoresState (int showingscores)
 }
 qboolean CL_VM_Event_Sound(int sound_num, float volume, int channel, float attenuation, int ent, vec3_t pos, int flags, float speed)
 {
+       prvm_prog_t *prog = CLVM_prog;
        qboolean r = false;
        if(cl.csqc_loaded)
        {
@@ -721,13 +715,13 @@ qboolean CL_VM_Event_Sound(int sound_num, float volume, int channel, float atten
                        PRVM_clientglobaledict(self) = cl.csqc_server2csqcentitynumber[cl.playerentity];
                        PRVM_G_FLOAT(OFS_PARM0) = ent;
                        PRVM_G_FLOAT(OFS_PARM1) = CHAN_ENGINE2USER(channel);
-                       PRVM_G_INT(OFS_PARM2) = PRVM_SetTempString(cl.sound_name[sound_num] );
+                       PRVM_G_INT(OFS_PARM2) = PRVM_SetTempString(prog, cl.sound_name[sound_num] );
                        PRVM_G_FLOAT(OFS_PARM3) = volume;
                        PRVM_G_FLOAT(OFS_PARM4) = attenuation;
                        VectorCopy(pos, PRVM_G_VECTOR(OFS_PARM5) );
                        PRVM_G_FLOAT(OFS_PARM6) = speed * 100.0f;
                        PRVM_G_FLOAT(OFS_PARM7) = flags; // flags
-                       PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Event_Sound), "QC function CSQC_Event_Sound is missing");
+                       prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_Event_Sound), "QC function CSQC_Event_Sound is missing");
                        r = CSQC_RETURNVAL != 0;
                }
                CSQC_END
@@ -735,8 +729,9 @@ qboolean CL_VM_Event_Sound(int sound_num, float volume, int channel, float atten
 
        return r;
 }
-void CL_VM_UpdateCoopDeathmatchGlobals (int gametype)
+static void CL_VM_UpdateCoopDeathmatchGlobals (int gametype)
 {
+       prvm_prog_t *prog = CLVM_prog;
        // Avoid global names for clean(er) coding
        int localcoop;
        int localdeathmatch;
@@ -767,8 +762,10 @@ void CL_VM_UpdateCoopDeathmatchGlobals (int gametype)
                CSQC_END
        }
 }
-float CL_VM_Event (float event)                //[515]: needed ? I'd say "YES", but don't know for what :D
+#if 0
+static float CL_VM_Event (float event)         //[515]: needed ? I'd say "YES", but don't know for what :D
 {
+       prvm_prog_t *prog = CLVM_prog;
        float r = 0;
        if(!cl.csqc_loaded)
                return 0;
@@ -778,15 +775,17 @@ float CL_VM_Event (float event)           //[515]: needed ? I'd say "YES", but don't know
                PRVM_clientglobalfloat(time) = cl.time;
                PRVM_clientglobaledict(self) = cl.csqc_server2csqcentitynumber[cl.playerentity];
                PRVM_G_FLOAT(OFS_PARM0) = event;
-               PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Event), "QC function CSQC_Event is missing");
+               prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_Event), "QC function CSQC_Event is missing");
                r = CSQC_RETURNVAL;
        }
        CSQC_END
        return r;
 }
+#endif
 
 void CSQC_ReadEntities (void)
 {
+       prvm_prog_t *prog = CLVM_prog;
        unsigned short entnum, oldself, realentnum;
        if(!cl.csqc_loaded)
        {
@@ -799,8 +798,8 @@ void CSQC_ReadEntities (void)
                oldself = PRVM_clientglobaledict(self);
                while(1)
                {
-                       entnum = MSG_ReadShort();
-                       if(!entnum || msg_badread)
+                       entnum = MSG_ReadShort(&cl_message);
+                       if(!entnum || cl_message.badread)
                                break;
                        realentnum = entnum & 0x7FFF;
                        PRVM_clientglobaledict(self) = cl.csqc_server2csqcentitynumber[realentnum];
@@ -808,7 +807,7 @@ void CSQC_ReadEntities (void)
                        {
                                if(PRVM_clientglobaledict(self))
                                {
-                                       PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Ent_Remove), "QC function CSQC_Ent_Remove is missing");
+                                       prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_Ent_Remove), "QC function CSQC_Ent_Remove is missing");
                                        cl.csqc_server2csqcentitynumber[realentnum] = 0;
                                }
                                else
@@ -827,7 +826,7 @@ void CSQC_ReadEntities (void)
                                        if(!PRVM_clientfunction(CSQC_Ent_Spawn))
                                        {
                                                prvm_edict_t    *ed;
-                                               ed = PRVM_ED_Alloc();
+                                               ed = PRVM_ED_Alloc(prog);
                                                PRVM_clientedictfloat(ed, entnum) = realentnum;
                                                PRVM_clientglobaledict(self) = cl.csqc_server2csqcentitynumber[realentnum] = PRVM_EDICT_TO_PROG(ed);
                                        }
@@ -838,15 +837,15 @@ void CSQC_ReadEntities (void)
                                                PRVM_G_FLOAT(OFS_PARM0) = (float) realentnum;
                                                // make sure no one gets wrong ideas
                                                PRVM_clientglobaledict(self) = 0;
-                                               PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Ent_Spawn), "QC function CSQC_Ent_Spawn is missing");
+                                               prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_Ent_Spawn), "QC function CSQC_Ent_Spawn is missing");
                                                PRVM_clientglobaledict(self) = cl.csqc_server2csqcentitynumber[realentnum] = PRVM_EDICT( PRVM_G_INT( OFS_RETURN ) );
                                        }
                                        PRVM_G_FLOAT(OFS_PARM0) = 1;
-                                       PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Ent_Update), "QC function CSQC_Ent_Update is missing");
+                                       prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_Ent_Update), "QC function CSQC_Ent_Update is missing");
                                }
                                else {
                                        PRVM_G_FLOAT(OFS_PARM0) = 0;
-                                       PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Ent_Update), "QC function CSQC_Ent_Update is missing");
+                                       prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_Ent_Update), "QC function CSQC_Ent_Update is missing");
                                }
                        }
                }
@@ -854,13 +853,13 @@ void CSQC_ReadEntities (void)
        CSQC_END
 }
 
-void CL_VM_CB_BeginIncreaseEdicts(void)
+static void CLVM_begin_increase_edicts(prvm_prog_t *prog)
 {
        // links don't survive the transition, so unlink everything
        World_UnlinkAll(&cl.world);
 }
 
-void CL_VM_CB_EndIncreaseEdicts(void)
+static void CLVM_end_increase_edicts(prvm_prog_t *prog)
 {
        int i;
        prvm_edict_t *ent;
@@ -871,7 +870,7 @@ void CL_VM_CB_EndIncreaseEdicts(void)
                        CL_LinkEdict(ent);
 }
 
-void CL_VM_CB_InitEdict(prvm_edict_t *e)
+static void CLVM_init_edict(prvm_prog_t *prog, prvm_edict_t *e)
 {
        int edictnum = PRVM_NUM_FOR_EDICT(e);
        entity_render_t *entrender;
@@ -882,21 +881,19 @@ void CL_VM_CB_InitEdict(prvm_edict_t *e)
        entrender->shadertime = cl.time;
 }
 
-extern void R_DecalSystem_Reset(decalsystem_t *decalsystem);
-
-void CL_VM_CB_FreeEdict(prvm_edict_t *ed)
+static void CLVM_free_edict(prvm_prog_t *prog, prvm_edict_t *ed)
 {
        entity_render_t *entrender = cl.csqcrenderentities + PRVM_NUM_FOR_EDICT(ed);
        R_DecalSystem_Reset(&entrender->decalsystem);
        memset(entrender, 0, sizeof(*entrender));
        World_UnlinkEdict(ed);
        memset(ed->fields.vp, 0, prog->entityfields * 4);
-       VM_RemoveEdictSkeleton(ed);
+       VM_RemoveEdictSkeleton(prog, ed);
        World_Physics_RemoveFromEntity(&cl.world, ed);
        World_Physics_RemoveJointFromEntity(&cl.world, ed);
 }
 
-void CL_VM_CB_CountEdicts(void)
+static void CLVM_count_edicts(prvm_prog_t *prog)
 {
        int             i;
        prvm_edict_t    *ent;
@@ -920,19 +917,18 @@ void CL_VM_CB_CountEdicts(void)
        Con_Printf("touch     :%3i\n", solid);
 }
 
-qboolean CL_VM_CB_LoadEdict(prvm_edict_t *ent)
+static qboolean CLVM_load_edict(prvm_prog_t *prog, prvm_edict_t *ent)
 {
        return true;
 }
 
-void Cmd_ClearCsqcFuncs (void);
-
 // returns true if the packet is valid, false if end of file is reached
 // used for dumping the CSQC download into demo files
 qboolean MakeDownloadPacket(const char *filename, unsigned char *data, size_t len, int crc, int cnt, sizebuf_t *buf, int protocol)
 {
        int packetsize = buf->maxsize - 7; // byte short long
        int npackets = (len + packetsize - 1) / (packetsize);
+       char vabuf[1024];
 
        if(protocol == PROTOCOL_QUAKEWORLD)
                return false; // CSQC can't run in QW anyway
@@ -941,7 +937,7 @@ qboolean MakeDownloadPacket(const char *filename, unsigned char *data, size_t le
        if(cnt == 0)
        {
                MSG_WriteByte(buf, svc_stufftext);
-               MSG_WriteString(buf, va("\ncl_downloadbegin %lu %s\n", (unsigned long)len, filename));
+               MSG_WriteString(buf, va(vabuf, sizeof(vabuf), "\ncl_downloadbegin %lu %s\n", (unsigned long)len, filename));
                return true;
        }
        else if(cnt >= 1 && cnt <= npackets)
@@ -961,7 +957,7 @@ qboolean MakeDownloadPacket(const char *filename, unsigned char *data, size_t le
        else if(cnt == npackets + 1)
        {
                MSG_WriteByte(buf, svc_stufftext);
-               MSG_WriteString(buf, va("\ncl_downloadfinished %lu %d\n", (unsigned long)len, crc));
+               MSG_WriteString(buf, va(vabuf, sizeof(vabuf), "\ncl_downloadfinished %lu %d\n", (unsigned long)len, crc));
                return true;
        }
        return false;
@@ -970,11 +966,13 @@ qboolean MakeDownloadPacket(const char *filename, unsigned char *data, size_t le
 extern cvar_t csqc_usedemoprogs;
 void CL_VM_Init (void)
 {
+       prvm_prog_t *prog = CLVM_prog;
        const char* csprogsfn;
        unsigned char *csprogsdata = NULL;
        fs_offset_t csprogsdatasize;
        int csprogsdatacrc, requiredcrc;
        int requiredsize;
+       char vabuf[1024];
 
        // reset csqc_progcrc after reading it, so that changing servers doesn't
        // expect csqc on the next server
@@ -991,7 +989,7 @@ void CL_VM_Init (void)
        csprogsdatacrc = -1;
        if (!cls.demoplayback || csqc_usedemoprogs.integer)
        {
-               csprogsfn = va("dlcache/%s.%i.%i", csqc_progname.string, requiredsize, requiredcrc);
+               csprogsfn = va(vabuf, sizeof(vabuf), "dlcache/%s.%i.%i", csqc_progname.string, requiredsize, requiredcrc);
                csprogsdata = FS_LoadFile(csprogsfn, tempmempool, true, &csprogsdatasize);
        }
        if (!csprogsdata)
@@ -1034,13 +1032,12 @@ void CL_VM_Init (void)
                return;
        }
 
-       PRVM_Begin;
-       PRVM_InitProg(PRVM_CLIENTPROG);
+       PRVM_Prog_Init(prog);
 
        // allocate the mempools
        prog->progs_mempool = Mem_AllocPool(csqc_progname.string, 0, NULL);
        prog->edictprivate_size = 0; // no private struct used
-       prog->name = CL_NAME;
+       prog->name = "client";
        prog->num_edicts = 1;
        prog->max_edicts = 512;
        prog->limit_edicts = CL_MAX_EDICTS;
@@ -1050,22 +1047,24 @@ void CL_VM_Init (void)
        prog->extensionstring = vm_sv_extensions;
        prog->builtins = vm_cl_builtins;
        prog->numbuiltins = vm_cl_numbuiltins;
-       prog->begin_increase_edicts = CL_VM_CB_BeginIncreaseEdicts;
-       prog->end_increase_edicts = CL_VM_CB_EndIncreaseEdicts;
-       prog->init_edict = CL_VM_CB_InitEdict;
-       prog->free_edict = CL_VM_CB_FreeEdict;
-       prog->count_edicts = CL_VM_CB_CountEdicts;
-       prog->load_edict = CL_VM_CB_LoadEdict;
-       prog->init_cmd = VM_CL_Cmd_Init;
-       prog->reset_cmd = VM_CL_Cmd_Reset;
-       prog->error_cmd = CL_VM_Error;
-       prog->ExecuteProgram = CLVM_ExecuteProgram;
-
-       PRVM_LoadProgs(csprogsfn, cl_numrequiredfunc, cl_required_func, CL_REQFIELDS, cl_reqfields, CL_REQGLOBALS, cl_reqglobals);
+
+       // all callbacks must be defined (pointers are not checked before calling)
+       prog->begin_increase_edicts = CLVM_begin_increase_edicts;
+       prog->end_increase_edicts   = CLVM_end_increase_edicts;
+       prog->init_edict            = CLVM_init_edict;
+       prog->free_edict            = CLVM_free_edict;
+       prog->count_edicts          = CLVM_count_edicts;
+       prog->load_edict            = CLVM_load_edict;
+       prog->init_cmd              = CLVM_init_cmd;
+       prog->reset_cmd             = CLVM_reset_cmd;
+       prog->error_cmd             = Host_Error;
+       prog->ExecuteProgram        = CLVM_ExecuteProgram;
+
+       PRVM_Prog_Load(prog, csprogsfn, cl_numrequiredfunc, cl_required_func, CL_REQFIELDS, cl_reqfields, CL_REQGLOBALS, cl_reqglobals);
 
        if (!prog->loaded)
        {
-               CL_VM_Error("CSQC %s ^2failed to load\n", csprogsfn);
+               Host_Error("CSQC %s ^2failed to load\n", csprogsfn);
                if(!sv.active)
                        CL_Disconnect();
                Mem_Free(csprogsdata);
@@ -1106,18 +1105,17 @@ void CL_VM_Init (void)
        PRVM_clientglobalfloat(time) = cl.time;
        PRVM_clientglobaledict(self) = 0;
 
-       PRVM_clientglobalstring(mapname) = PRVM_SetEngineString(cl.worldname);
+       PRVM_clientglobalstring(mapname) = PRVM_SetEngineString(prog, cl.worldname);
        PRVM_clientglobalfloat(player_localentnum) = cl.playerentity;
 
        // set map description (use world entity 0)
-       PRVM_clientedictstring(prog->edicts, message) = PRVM_SetEngineString(cl.worldmessage);
+       PRVM_clientedictstring(prog->edicts, message) = PRVM_SetEngineString(prog, cl.worldmessage);
        VectorCopy(cl.world.mins, PRVM_clientedictvector(prog->edicts, mins));
        VectorCopy(cl.world.maxs, PRVM_clientedictvector(prog->edicts, maxs));
 
        // call the prog init
-       PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Init), "QC function CSQC_Init is missing");
+       prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_Init), "QC function CSQC_Init is missing");
 
-       PRVM_End;
        cl.csqc_loaded = true;
 
        cl.csqc_vidvars.drawcrosshair = false;
@@ -1129,6 +1127,7 @@ void CL_VM_Init (void)
 
 void CL_VM_ShutDown (void)
 {
+       prvm_prog_t *prog = CLVM_prog;
        Cmd_ClearCsqcFuncs();
        //Cvar_SetValueQuick(&csqc_progcrc, -1);
        //Cvar_SetValueQuick(&csqc_progsize, -1);
@@ -1138,8 +1137,8 @@ void CL_VM_ShutDown (void)
                PRVM_clientglobalfloat(time) = cl.time;
                PRVM_clientglobaledict(self) = 0;
                if (PRVM_clientfunction(CSQC_Shutdown))
-                       PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Shutdown), "QC function CSQC_Shutdown is missing");
-               PRVM_ResetProg();
+                       prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_Shutdown), "QC function CSQC_Shutdown is missing");
+               PRVM_Prog_Reset(prog);
        CSQC_END
        Con_DPrint("CSQC ^1unloaded\n");
        cl.csqc_loaded = false;
@@ -1147,6 +1146,7 @@ void CL_VM_ShutDown (void)
 
 qboolean CL_VM_GetEntitySoundOrigin(int entnum, vec3_t out)
 {
+       prvm_prog_t *prog = CLVM_prog;
        prvm_edict_t *ed;
        dp_model_t *mod;
        matrix4x4_t matrix;
@@ -1162,7 +1162,7 @@ qboolean CL_VM_GetEntitySoundOrigin(int entnum, vec3_t out)
        {
                mod = CL_GetModelFromEdict(ed);
                VectorCopy(PRVM_clientedictvector(ed, origin), out);
-               if(CL_GetTagMatrix (&matrix, ed, 0) == 0)
+               if(CL_GetTagMatrix(prog, &matrix, ed, 0) == 0)
                        Matrix4x4_OriginFromMatrix(&matrix, out);
                if (mod && mod->soundfromcenter)
                        VectorMAMAM(1.0f, out, 0.5f, mod->normalmins, 0.5f, mod->normalmaxs, out);
@@ -1176,6 +1176,7 @@ qboolean CL_VM_GetEntitySoundOrigin(int entnum, vec3_t out)
 
 qboolean CL_VM_TransformView(int entnum, matrix4x4_t *viewmatrix, mplane_t *clipplane, vec3_t visorigin)
 {
+       prvm_prog_t *prog = CLVM_prog;
        qboolean ret = false;
        prvm_edict_t *ed;
        vec3_t forward, left, up, origin, ang;
@@ -1200,7 +1201,7 @@ qboolean CL_VM_TransformView(int entnum, matrix4x4_t *viewmatrix, mplane_t *clip
                                VectorScale(left, -1, PRVM_clientglobalvector(v_right));
                                VectorCopy(up, PRVM_clientglobalvector(v_up));
                                VectorCopy(origin, PRVM_clientglobalvector(trace_endpos));
-                               PRVM_ExecuteProgram(PRVM_clientedictfunction(ed, camera_transform), "QC function e.camera_transform is missing");
+                               prog->ExecuteProgram(prog, PRVM_clientedictfunction(ed, camera_transform), "QC function e.camera_transform is missing");
                                VectorCopy(PRVM_G_VECTOR(OFS_RETURN), origin);
                                VectorCopy(PRVM_clientglobalvector(v_forward), forward);
                                VectorScale(PRVM_clientglobalvector(v_right), -1, left);
index a5f478c161ca308b77271219aa132b0f91a8a511..95e1c48d29e83d68c8f85d1157025034b2250d95 100644 (file)
--- a/csprogs.h
+++ b/csprogs.h
@@ -1,8 +1,6 @@
 #ifndef CSPROGS_H
 #define CSPROGS_H
 
-#define CL_NAME "client"
-
 // LordHavoc: changed to match MAX_EDICTS
 #define CL_MAX_EDICTS MAX_EDICTS
 
@@ -78,4 +76,35 @@ qboolean CL_VM_GetEntitySoundOrigin(int entnum, vec3_t out);
 
 qboolean CL_VM_TransformView(int entnum, matrix4x4_t *viewmatrix, mplane_t *clipplane, vec3_t visorigin);
 
+void CL_VM_Init(void);
+void CL_VM_ShutDown(void);
+void CL_VM_UpdateIntermissionState(int intermission);
+void CL_VM_UpdateShowingScoresState(int showingscores);
+qboolean CL_VM_InputEvent(int eventtype, int x, int y);
+qboolean CL_VM_ConsoleCommand(const char *cmd);
+void CL_VM_UpdateDmgGlobals(int dmg_take, int dmg_save, vec3_t dmg_origin);
+void CL_VM_UpdateIntermissionState(int intermission);
+qboolean CL_VM_Event_Sound(int sound_num, float volume, int channel, float attenuation, int ent, vec3_t pos, int flags, float speed);
+qboolean CL_VM_Parse_TempEntity(void);
+void CL_VM_Parse_StuffCmd(const char *msg);
+void CL_VM_Parse_CenterPrint(const char *msg);
+int CL_GetPitchSign(prvm_prog_t *prog, prvm_edict_t *ent);
+int CL_GetTagMatrix(prvm_prog_t *prog, matrix4x4_t *out, prvm_edict_t *ent, int tagindex);
+void CL_GetEntityMatrix(prvm_prog_t *prog, prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix);
+/* VMs exposing the polygon calls must call this on Init/Reset */
+void VM_Polygons_Reset(prvm_prog_t *prog);
+void QW_CL_StartUpload(unsigned char *data, int size);
+
+void CSQC_UpdateNetworkTimes(double newtime, double oldtime);
+void CSQC_AddPrintText(const char *msg);
+void CSQC_ReadEntities(void);
+void CSQC_RelinkAllEntities(int drawmask);
+void CSQC_RelinkCSQCEntities(void);
+void CSQC_Predraw(prvm_edict_t *ed);
+void CSQC_Think(prvm_edict_t *ed);
+qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum);//csprogs.c
+void CSQC_R_RecalcView(void);
+
+dp_model_t *CL_GetModelByIndex(int modelindex);
+
 #endif
index 17d1b9424d0c24c97f2610f180190875d9e2b3f2..cf7569dba482a202a641553ed5a31fa59dc220c0 100644 (file)
--- a/curves.c
+++ b/curves.c
@@ -156,7 +156,7 @@ static int Q3PatchTesselation(float largestsquared3xcurvearea, float tolerance)
                // maps [4..8[ to 4
 }
 
-float Squared3xCurveArea(const float *a, const float *control, const float *b, int components)
+static float Squared3xCurveArea(const float *a, const float *control, const float *b, int components)
 {
 #if 0
        // mimicing the old behaviour with the new code...
diff --git a/cvar.c b/cvar.c
index 8cc14f0964396c91b48e1f5c8d707cc081d07108..4e9e20dab8a2cee0e256e820fe6d784c2680d450 100644 (file)
--- a/cvar.c
+++ b/cvar.c
@@ -70,7 +70,7 @@ cvar_t *Cvar_FindVarAfter (const char *prev_var_name, int neededflags)
        return var;
 }
 
-cvar_t *Cvar_FindVarLink (const char *var_name, cvar_t **parent, cvar_t ***link, cvar_t **prev_alpha)
+static cvar_t *Cvar_FindVarLink (const char *var_name, cvar_t **parent, cvar_t ***link, cvar_t **prev_alpha)
 {
        int hashindex;
        cvar_t *var;
@@ -266,17 +266,18 @@ void Cvar_CompleteCvarPrint (const char *partial)
 static void Cvar_UpdateAutoCvar(cvar_t *var)
 {
        int i;
-       if(!prog)
-               Host_Error("Cvar_UpdateAutoCvar: no prog set");
-       i = PRVM_GetProgNr();
-       if(var->globaldefindex_progid[i] == prog->id)
+       int j;
+       const char *s;
+       vec3_t v;
+       prvm_prog_t *prog;
+       for (i = 0;i < PRVM_PROG_MAX;i++)
        {
-               // MUST BE SYNCED WITH prvm_edict.c PRVM_LoadProgs
-               int j;
-               const char *s;
-               vec3_t v;
-               switch(prog->globaldefs[var->globaldefindex[i]].type & ~DEF_SAVEGLOBAL)
+               prog = &prvm_prog_list[i];
+               if (prog->loaded && var->globaldefindex_progid[i] == prog->id)
                {
+                       // MUST BE SYNCED WITH prvm_edict.c PRVM_LoadProgs
+                       switch(prog->globaldefs[var->globaldefindex[i]].type & ~DEF_SAVEGLOBAL)
+                       {
                        case ev_float:
                                PRVM_GLOBALFIELDFLOAT(prog->globaldefs[var->globaldefindex[i]].ofs) = var->value;
                                break;
@@ -298,9 +299,10 @@ static void Cvar_UpdateAutoCvar(cvar_t *var)
                                VectorCopy(v, PRVM_GLOBALFIELDVECTOR(prog->globaldefs[var->globaldefindex[i]].ofs));
                                break;
                        case ev_string:
-                               PRVM_ChangeEngineString(var->globaldefindex_stringno[i], var->string);
+                               PRVM_ChangeEngineString(prog, var->globaldefindex_stringno[i], var->string);
                                PRVM_GLOBALFIELDSTRING(prog->globaldefs[var->globaldefindex[i]].ofs) = var->globaldefindex_stringno[i];
                                break;
+                       }
                }
        }
 }
@@ -319,12 +321,11 @@ Cvar_Set
 ============
 */
 extern cvar_t sv_disablenotify;
-void Cvar_SetQuick_Internal (cvar_t *var, const char *value)
+static void Cvar_SetQuick_Internal (cvar_t *var, const char *value)
 {
        qboolean changed;
        size_t valuelen;
-       prvm_prog_t *tmpprog;
-       int i;
+       char vabuf[1024];
 
        changed = strcmp(var->string, value) != 0;
        // LordHavoc: don't reallocate when there is no change
@@ -370,16 +371,16 @@ void Cvar_SetQuick_Internal (cvar_t *var, const char *value)
                if (!strcmp(var->name, "_cl_color"))
                {
                        int top = (var->integer >> 4) & 15, bottom = var->integer & 15;
-                       CL_SetInfo("topcolor", va("%i", top), true, false, false, false);
-                       CL_SetInfo("bottomcolor", va("%i", bottom), true, false, false, false);
+                       CL_SetInfo("topcolor", va(vabuf, sizeof(vabuf), "%i", top), true, false, false, false);
+                       CL_SetInfo("bottomcolor", va(vabuf, sizeof(vabuf), "%i", bottom), true, false, false, false);
                        if (cls.protocol != PROTOCOL_QUAKEWORLD && cls.netcon)
                        {
                                MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
-                               MSG_WriteString(&cls.netcon->message, va("color %i %i", top, bottom));
+                               MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "color %i %i", top, bottom));
                        }
                }
                else if (!strcmp(var->name, "_cl_rate"))
-                       CL_SetInfo("rate", va("%i", var->integer), true, false, false, false);
+                       CL_SetInfo("rate", va(vabuf, sizeof(vabuf), "%i", var->integer), true, false, false, false);
                else if (!strcmp(var->name, "_cl_playerskin"))
                        CL_SetInfo("playerskin", var->string, true, false, false, false);
                else if (!strcmp(var->name, "_cl_playermodel"))
@@ -398,16 +399,7 @@ void Cvar_SetQuick_Internal (cvar_t *var, const char *value)
                        NetConn_UpdateFavorites();
        }
 
-       tmpprog = prog;
-       for(i = 0; i < PRVM_MAXPROGS; ++i)
-       {
-               if(PRVM_ProgLoaded(i))
-               {
-                       PRVM_SetProg(i);
-                       Cvar_UpdateAutoCvar(var);
-               }
-       }
-       prog = tmpprog;
+       Cvar_UpdateAutoCvar(var);
 }
 
 void Cvar_SetQuick (cvar_t *var, const char *value)
index b3a00ae417f34004967976d6c7278332b0daa0bf..a79a9d363aee62cc8b45416277d572eca511b601 100644 (file)
@@ -492,7 +492,7 @@ static void DPSOFTRAST_Validate(DPSOFTRAST_State_Thread *thread, int mask)
        }
 }
 
-DPSOFTRAST_Texture *DPSOFTRAST_Texture_GetByIndex(int index)
+static DPSOFTRAST_Texture *DPSOFTRAST_Texture_GetByIndex(int index)
 {
        if (index >= 1 && index < dpsoftrast.texture_end && dpsoftrast.texture[index].bytes)
                return &dpsoftrast.texture[index];
@@ -660,7 +660,7 @@ void DPSOFTRAST_Texture_Free(int index)
        while (dpsoftrast.texture_end > 0 && dpsoftrast.texture[dpsoftrast.texture_end-1].bytes == NULL)
                dpsoftrast.texture_end--;
 }
-void DPSOFTRAST_Texture_CalculateMipmaps(int index)
+static void DPSOFTRAST_Texture_CalculateMipmaps(int index)
 {
        int i, x, y, z, w, layer0, layer1, row0, row1;
        unsigned char *o, *i0, *i1, *i2, *i3;
@@ -1653,7 +1653,7 @@ static void DPSOFTRAST_Fill4f(float *dst, const float *src, int size)
 }
 #endif
 
-void DPSOFTRAST_Vertex_Transform(float *out4f, const float *in4f, int numitems, const float *inmatrix16f)
+static void DPSOFTRAST_Vertex_Transform(float *out4f, const float *in4f, int numitems, const float *inmatrix16f)
 {
 #ifdef SSE_POSSIBLE
        static const float identitymatrix[4][4] = {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}};
@@ -1701,10 +1701,12 @@ void DPSOFTRAST_Vertex_Transform(float *out4f, const float *in4f, int numitems,
 #endif
 }
 
-void DPSOFTRAST_Vertex_Copy(float *out4f, const float *in4f, int numitems)
+#if 0
+static void DPSOFTRAST_Vertex_Copy(float *out4f, const float *in4f, int numitems)
 {
        memcpy(out4f, in4f, numitems * sizeof(float[4]));
 }
+#endif
 
 #ifdef SSE_POSSIBLE
 #define DPSOFTRAST_PROJECTVERTEX(out, in, viewportcenter, viewportscale) \
@@ -2005,7 +2007,7 @@ static float *DPSOFTRAST_Array_TransformProject(int outarray, int inarray, const
 #endif
 }
 
-void DPSOFTRAST_Draw_Span_Begin(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, float *zf)
+static void DPSOFTRAST_Draw_Span_Begin(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, float *zf)
 {
        int x;
        int startx = span->startx;
@@ -2032,7 +2034,7 @@ void DPSOFTRAST_Draw_Span_Begin(DPSOFTRAST_State_Thread *thread, const DPSOFTRAS
        }
 }
 
-void DPSOFTRAST_Draw_Span_FinishBGRA8(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, const unsigned char* RESTRICT in4ub)
+static void DPSOFTRAST_Draw_Span_FinishBGRA8(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, const unsigned char* RESTRICT in4ub)
 {
 #ifdef SSE_POSSIBLE
        int x;
@@ -2344,7 +2346,8 @@ static void DPSOFTRAST_Texture2DBGRA8(DPSOFTRAST_Texture *texture, int mip, floa
        }
 }
 
-void DPSOFTRAST_Draw_Span_Texture2DVarying(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, float * RESTRICT out4f, int texunitindex, int arrayindex, const float * RESTRICT zf)
+#if 0
+static void DPSOFTRAST_Draw_Span_Texture2DVarying(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, float * RESTRICT out4f, int texunitindex, int arrayindex, const float * RESTRICT zf)
 {
        int x;
        int startx = span->startx;
@@ -2540,8 +2543,9 @@ void DPSOFTRAST_Draw_Span_Texture2DVarying(DPSOFTRAST_State_Thread *thread, cons
                }
        }
 }
+#endif
 
-void DPSOFTRAST_Draw_Span_Texture2DVaryingBGRA8(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, unsigned char * RESTRICT out4ub, int texunitindex, int arrayindex, const float * RESTRICT zf)
+static void DPSOFTRAST_Draw_Span_Texture2DVaryingBGRA8(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, unsigned char * RESTRICT out4ub, int texunitindex, int arrayindex, const float * RESTRICT zf)
 {
 #ifdef SSE_POSSIBLE
        int x;
@@ -2822,19 +2826,20 @@ void DPSOFTRAST_Draw_Span_Texture2DVaryingBGRA8(DPSOFTRAST_State_Thread *thread,
 #endif
 }
 
-void DPSOFTRAST_Draw_Span_TextureCubeVaryingBGRA8(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, unsigned char * RESTRICT out4ub, int texunitindex, int arrayindex, const float * RESTRICT zf)
+static void DPSOFTRAST_Draw_Span_TextureCubeVaryingBGRA8(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, unsigned char * RESTRICT out4ub, int texunitindex, int arrayindex, const float * RESTRICT zf)
 {
        // TODO: IMPLEMENT
        memset(out4ub + span->startx*4, 255, (span->startx - span->endx)*4);
 }
 
-float DPSOFTRAST_SampleShadowmap(const float *vector)
+static float DPSOFTRAST_SampleShadowmap(const float *vector)
 {
        // TODO: IMPLEMENT
        return 1.0f;
 }
 
-void DPSOFTRAST_Draw_Span_MultiplyVarying(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, float *out4f, const float *in4f, int arrayindex, const float *zf)
+#if 0
+static void DPSOFTRAST_Draw_Span_MultiplyVarying(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, float *out4f, const float *in4f, int arrayindex, const float *zf)
 {
        int x;
        int startx = span->startx;
@@ -2857,8 +2862,10 @@ void DPSOFTRAST_Draw_Span_MultiplyVarying(const DPSOFTRAST_State_Triangle * REST
                out4f[x*4+3] = in4f[x*4+3] * c[3];
        }
 }
+#endif
 
-void DPSOFTRAST_Draw_Span_Varying(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, float *out4f, int arrayindex, const float *zf)
+#if 0
+static void DPSOFTRAST_Draw_Span_Varying(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, float *out4f, int arrayindex, const float *zf)
 {
        int x;
        int startx = span->startx;
@@ -2881,8 +2888,10 @@ void DPSOFTRAST_Draw_Span_Varying(const DPSOFTRAST_State_Triangle * RESTRICT tri
                out4f[x*4+3] = c[3];
        }
 }
+#endif
 
-void DPSOFTRAST_Draw_Span_AddBloom(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, float *out4f, const float *ina4f, const float *inb4f, const float *subcolor)
+#if 0
+static void DPSOFTRAST_Draw_Span_AddBloom(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, float *out4f, const float *ina4f, const float *inb4f, const float *subcolor)
 {
        int x, startx = span->startx, endx = span->endx;
        float c[4], localcolor[4];
@@ -2902,8 +2911,10 @@ void DPSOFTRAST_Draw_Span_AddBloom(const DPSOFTRAST_State_Triangle * RESTRICT tr
                out4f[x*4+3] = ina4f[x*4+3] + c[3];
        }
 }
+#endif
 
-void DPSOFTRAST_Draw_Span_MultiplyBuffers(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, float *out4f, const float *ina4f, const float *inb4f)
+#if 0
+static void DPSOFTRAST_Draw_Span_MultiplyBuffers(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, float *out4f, const float *ina4f, const float *inb4f)
 {
        int x, startx = span->startx, endx = span->endx;
        for (x = startx;x < endx;x++)
@@ -2914,8 +2925,10 @@ void DPSOFTRAST_Draw_Span_MultiplyBuffers(const DPSOFTRAST_State_Triangle * REST
                out4f[x*4+3] = ina4f[x*4+3] * inb4f[x*4+3];
        }
 }
+#endif
 
-void DPSOFTRAST_Draw_Span_AddBuffers(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, float *out4f, const float *ina4f, const float *inb4f)
+#if 0
+static void DPSOFTRAST_Draw_Span_AddBuffers(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, float *out4f, const float *ina4f, const float *inb4f)
 {
        int x, startx = span->startx, endx = span->endx;
        for (x = startx;x < endx;x++)
@@ -2926,8 +2939,10 @@ void DPSOFTRAST_Draw_Span_AddBuffers(const DPSOFTRAST_State_Triangle * RESTRICT
                out4f[x*4+3] = ina4f[x*4+3] + inb4f[x*4+3];
        }
 }
+#endif
 
-void DPSOFTRAST_Draw_Span_MixBuffers(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, float *out4f, const float *ina4f, const float *inb4f)
+#if 0
+static void DPSOFTRAST_Draw_Span_MixBuffers(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, float *out4f, const float *ina4f, const float *inb4f)
 {
        int x, startx = span->startx, endx = span->endx;
        float a, b;
@@ -2941,8 +2956,10 @@ void DPSOFTRAST_Draw_Span_MixBuffers(const DPSOFTRAST_State_Triangle * RESTRICT
                out4f[x*4+3] = ina4f[x*4+3] * a + inb4f[x*4+3] * b;
        }
 }
+#endif
 
-void DPSOFTRAST_Draw_Span_MixUniformColor(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, float *out4f, const float *in4f, const float *color)
+#if 0
+static void DPSOFTRAST_Draw_Span_MixUniformColor(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, float *out4f, const float *in4f, const float *color)
 {
        int x, startx = span->startx, endx = span->endx;
        float localcolor[4], ilerp, lerp;
@@ -2960,10 +2977,11 @@ void DPSOFTRAST_Draw_Span_MixUniformColor(const DPSOFTRAST_State_Triangle * REST
                out4f[x*4+3] = in4f[x*4+3] * ilerp + localcolor[3] * lerp;
        }
 }
+#endif
 
 
 
-void DPSOFTRAST_Draw_Span_MultiplyVaryingBGRA8(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, unsigned char *out4ub, const unsigned char *in4ub, int arrayindex, const float *zf)
+static void DPSOFTRAST_Draw_Span_MultiplyVaryingBGRA8(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, unsigned char *out4ub, const unsigned char *in4ub, int arrayindex, const float *zf)
 {
 #ifdef SSE_POSSIBLE
        int x;
@@ -3010,7 +3028,7 @@ void DPSOFTRAST_Draw_Span_MultiplyVaryingBGRA8(const DPSOFTRAST_State_Triangle *
 #endif
 }
 
-void DPSOFTRAST_Draw_Span_VaryingBGRA8(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, unsigned char *out4ub, int arrayindex, const float *zf)
+static void DPSOFTRAST_Draw_Span_VaryingBGRA8(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, unsigned char *out4ub, int arrayindex, const float *zf)
 {
 #ifdef SSE_POSSIBLE
        int x;
@@ -3055,7 +3073,7 @@ void DPSOFTRAST_Draw_Span_VaryingBGRA8(const DPSOFTRAST_State_Triangle * RESTRIC
 #endif
 }
 
-void DPSOFTRAST_Draw_Span_AddBloomBGRA8(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, unsigned char *out4ub, const unsigned char *ina4ub, const unsigned char *inb4ub, const float *subcolor)
+static void DPSOFTRAST_Draw_Span_AddBloomBGRA8(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, unsigned char *out4ub, const unsigned char *ina4ub, const unsigned char *inb4ub, const float *subcolor)
 {
 #ifdef SSE_POSSIBLE
        int x, startx = span->startx, endx = span->endx;
@@ -3078,7 +3096,7 @@ void DPSOFTRAST_Draw_Span_AddBloomBGRA8(const DPSOFTRAST_State_Triangle * RESTRI
 #endif
 }
 
-void DPSOFTRAST_Draw_Span_MultiplyBuffersBGRA8(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, unsigned char *out4ub, const unsigned char *ina4ub, const unsigned char *inb4ub)
+static void DPSOFTRAST_Draw_Span_MultiplyBuffersBGRA8(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, unsigned char *out4ub, const unsigned char *ina4ub, const unsigned char *inb4ub)
 {
 #ifdef SSE_POSSIBLE
        int x, startx = span->startx, endx = span->endx;
@@ -3099,7 +3117,7 @@ void DPSOFTRAST_Draw_Span_MultiplyBuffersBGRA8(const DPSOFTRAST_State_Triangle *
 #endif
 }
 
-void DPSOFTRAST_Draw_Span_AddBuffersBGRA8(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, unsigned char *out4ub, const unsigned char *ina4ub, const unsigned char *inb4ub)
+static void DPSOFTRAST_Draw_Span_AddBuffersBGRA8(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, unsigned char *out4ub, const unsigned char *ina4ub, const unsigned char *inb4ub)
 {
 #ifdef SSE_POSSIBLE
        int x, startx = span->startx, endx = span->endx;
@@ -3120,7 +3138,8 @@ void DPSOFTRAST_Draw_Span_AddBuffersBGRA8(const DPSOFTRAST_State_Triangle * REST
 #endif
 }
 
-void DPSOFTRAST_Draw_Span_TintedAddBuffersBGRA8(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, unsigned char *out4ub, const unsigned char *ina4ub, const unsigned char *inb4ub, const float *inbtintbgra)
+#if 0
+static void DPSOFTRAST_Draw_Span_TintedAddBuffersBGRA8(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, unsigned char *out4ub, const unsigned char *ina4ub, const unsigned char *inb4ub, const float *inbtintbgra)
 {
 #ifdef SSE_POSSIBLE
        int x, startx = span->startx, endx = span->endx;
@@ -3142,8 +3161,9 @@ void DPSOFTRAST_Draw_Span_TintedAddBuffersBGRA8(const DPSOFTRAST_State_Triangle
        }
 #endif
 }
+#endif
 
-void DPSOFTRAST_Draw_Span_MixBuffersBGRA8(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, unsigned char *out4ub, const unsigned char *ina4ub, const unsigned char *inb4ub)
+static void DPSOFTRAST_Draw_Span_MixBuffersBGRA8(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, unsigned char *out4ub, const unsigned char *ina4ub, const unsigned char *inb4ub)
 {
 #ifdef SSE_POSSIBLE
        int x, startx = span->startx, endx = span->endx;
@@ -3166,7 +3186,7 @@ void DPSOFTRAST_Draw_Span_MixBuffersBGRA8(const DPSOFTRAST_State_Triangle * REST
 #endif
 }
 
-void DPSOFTRAST_Draw_Span_MixUniformColorBGRA8(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, unsigned char *out4ub, const unsigned char *in4ub, const float *color)
+static void DPSOFTRAST_Draw_Span_MixUniformColorBGRA8(const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, unsigned char *out4ub, const unsigned char *in4ub, const float *color)
 {
 #ifdef SSE_POSSIBLE
        int x, startx = span->startx, endx = span->endx;
@@ -3190,7 +3210,7 @@ void DPSOFTRAST_Draw_Span_MixUniformColorBGRA8(const DPSOFTRAST_State_Triangle *
 
 
 
-void DPSOFTRAST_VertexShader_Generic(void)
+static void DPSOFTRAST_VertexShader_Generic(void)
 {
        DPSOFTRAST_Array_TransformProject(DPSOFTRAST_ARRAY_POSITION, DPSOFTRAST_ARRAY_POSITION, dpsoftrast.uniform4f + 4*DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1);
        DPSOFTRAST_Array_Load(DPSOFTRAST_ARRAY_COLOR, DPSOFTRAST_ARRAY_COLOR);
@@ -3199,7 +3219,7 @@ void DPSOFTRAST_VertexShader_Generic(void)
                DPSOFTRAST_Array_Load(DPSOFTRAST_ARRAY_TEXCOORD1, DPSOFTRAST_ARRAY_TEXCOORD1);
 }
 
-void DPSOFTRAST_PixelShader_Generic(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
+static void DPSOFTRAST_PixelShader_Generic(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
 {
        float buffer_z[DPSOFTRAST_DRAW_MAXSPANLENGTH];
        unsigned char buffer_texture_colorbgra8[DPSOFTRAST_DRAW_MAXSPANLENGTH*4];
@@ -3237,14 +3257,14 @@ void DPSOFTRAST_PixelShader_Generic(DPSOFTRAST_State_Thread *thread, const DPSOF
 
 
 
-void DPSOFTRAST_VertexShader_PostProcess(void)
+static void DPSOFTRAST_VertexShader_PostProcess(void)
 {
        DPSOFTRAST_Array_TransformProject(DPSOFTRAST_ARRAY_POSITION, DPSOFTRAST_ARRAY_POSITION, dpsoftrast.uniform4f + 4*DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1);
        DPSOFTRAST_Array_Load(DPSOFTRAST_ARRAY_TEXCOORD0, DPSOFTRAST_ARRAY_TEXCOORD0);
        DPSOFTRAST_Array_Load(DPSOFTRAST_ARRAY_TEXCOORD1, DPSOFTRAST_ARRAY_TEXCOORD4);
 }
 
-void DPSOFTRAST_PixelShader_PostProcess(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
+static void DPSOFTRAST_PixelShader_PostProcess(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
 {
        // TODO: optimize!!  at the very least there is no reason to use texture sampling on the frame texture
        float buffer_z[DPSOFTRAST_DRAW_MAXSPANLENGTH];
@@ -3271,12 +3291,12 @@ void DPSOFTRAST_PixelShader_PostProcess(DPSOFTRAST_State_Thread *thread, const D
 
 
 
-void DPSOFTRAST_VertexShader_Depth_Or_Shadow(void)
+static void DPSOFTRAST_VertexShader_Depth_Or_Shadow(void)
 {
        DPSOFTRAST_Array_TransformProject(DPSOFTRAST_ARRAY_POSITION, DPSOFTRAST_ARRAY_POSITION, dpsoftrast.uniform4f + 4*DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1);
 }
 
-void DPSOFTRAST_PixelShader_Depth_Or_Shadow(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
+static void DPSOFTRAST_PixelShader_Depth_Or_Shadow(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
 {
        // this is never called (because colormask is off when this shader is used)
        float buffer_z[DPSOFTRAST_DRAW_MAXSPANLENGTH];
@@ -3288,13 +3308,13 @@ void DPSOFTRAST_PixelShader_Depth_Or_Shadow(DPSOFTRAST_State_Thread *thread, con
 
 
 
-void DPSOFTRAST_VertexShader_FlatColor(void)
+static void DPSOFTRAST_VertexShader_FlatColor(void)
 {
        DPSOFTRAST_Array_TransformProject(DPSOFTRAST_ARRAY_POSITION, DPSOFTRAST_ARRAY_POSITION, dpsoftrast.uniform4f + 4*DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1);
        DPSOFTRAST_Array_Transform(DPSOFTRAST_ARRAY_TEXCOORD0, DPSOFTRAST_ARRAY_TEXCOORD0, dpsoftrast.uniform4f + 4*DPSOFTRAST_UNIFORM_TexMatrixM1);
 }
 
-void DPSOFTRAST_PixelShader_FlatColor(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
+static void DPSOFTRAST_PixelShader_FlatColor(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
 {
 #ifdef SSE_POSSIBLE
        unsigned char * RESTRICT pixelmask = span->pixelmask;
@@ -3338,14 +3358,14 @@ void DPSOFTRAST_PixelShader_FlatColor(DPSOFTRAST_State_Thread *thread, const DPS
 
 
 
-void DPSOFTRAST_VertexShader_VertexColor(void)
+static void DPSOFTRAST_VertexShader_VertexColor(void)
 {
        DPSOFTRAST_Array_TransformProject(DPSOFTRAST_ARRAY_POSITION, DPSOFTRAST_ARRAY_POSITION, dpsoftrast.uniform4f + 4*DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1);
        DPSOFTRAST_Array_Load(DPSOFTRAST_ARRAY_COLOR, DPSOFTRAST_ARRAY_COLOR);
        DPSOFTRAST_Array_Transform(DPSOFTRAST_ARRAY_TEXCOORD0, DPSOFTRAST_ARRAY_TEXCOORD0, dpsoftrast.uniform4f + 4*DPSOFTRAST_UNIFORM_TexMatrixM1);
 }
 
-void DPSOFTRAST_PixelShader_VertexColor(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
+static void DPSOFTRAST_PixelShader_VertexColor(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
 {
 #ifdef SSE_POSSIBLE
        unsigned char * RESTRICT pixelmask = span->pixelmask;
@@ -3412,14 +3432,14 @@ void DPSOFTRAST_PixelShader_VertexColor(DPSOFTRAST_State_Thread *thread, const D
 
 
 
-void DPSOFTRAST_VertexShader_Lightmap(void)
+static void DPSOFTRAST_VertexShader_Lightmap(void)
 {
        DPSOFTRAST_Array_TransformProject(DPSOFTRAST_ARRAY_POSITION, DPSOFTRAST_ARRAY_POSITION, dpsoftrast.uniform4f + 4*DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1);
        DPSOFTRAST_Array_Transform(DPSOFTRAST_ARRAY_TEXCOORD0, DPSOFTRAST_ARRAY_TEXCOORD0, dpsoftrast.uniform4f + 4*DPSOFTRAST_UNIFORM_TexMatrixM1);
        DPSOFTRAST_Array_Load(DPSOFTRAST_ARRAY_TEXCOORD4, DPSOFTRAST_ARRAY_TEXCOORD4);
 }
 
-void DPSOFTRAST_PixelShader_Lightmap(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
+static void DPSOFTRAST_PixelShader_Lightmap(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
 {
 #ifdef SSE_POSSIBLE
        unsigned char * RESTRICT pixelmask = span->pixelmask;
@@ -3514,38 +3534,38 @@ void DPSOFTRAST_PixelShader_Lightmap(DPSOFTRAST_State_Thread *thread, const DPSO
 void DPSOFTRAST_VertexShader_LightDirection(void);
 void DPSOFTRAST_PixelShader_LightDirection(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span);
 
-void DPSOFTRAST_VertexShader_FakeLight(void)
+static void DPSOFTRAST_VertexShader_FakeLight(void)
 {
        DPSOFTRAST_VertexShader_LightDirection();
 }
 
-void DPSOFTRAST_PixelShader_FakeLight(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
+static void DPSOFTRAST_PixelShader_FakeLight(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
 {
        DPSOFTRAST_PixelShader_LightDirection(thread, triangle, span);
 }
 
 
 
-void DPSOFTRAST_VertexShader_LightDirectionMap_ModelSpace(void)
+static void DPSOFTRAST_VertexShader_LightDirectionMap_ModelSpace(void)
 {
        DPSOFTRAST_VertexShader_LightDirection();
        DPSOFTRAST_Array_Load(DPSOFTRAST_ARRAY_TEXCOORD4, DPSOFTRAST_ARRAY_TEXCOORD4);
 }
 
-void DPSOFTRAST_PixelShader_LightDirectionMap_ModelSpace(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
+static void DPSOFTRAST_PixelShader_LightDirectionMap_ModelSpace(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
 {
        DPSOFTRAST_PixelShader_LightDirection(thread, triangle, span);
 }
 
 
 
-void DPSOFTRAST_VertexShader_LightDirectionMap_TangentSpace(void)
+static void DPSOFTRAST_VertexShader_LightDirectionMap_TangentSpace(void)
 {
        DPSOFTRAST_VertexShader_LightDirection();
        DPSOFTRAST_Array_Load(DPSOFTRAST_ARRAY_TEXCOORD4, DPSOFTRAST_ARRAY_TEXCOORD4);
 }
 
-void DPSOFTRAST_PixelShader_LightDirectionMap_TangentSpace(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
+static void DPSOFTRAST_PixelShader_LightDirectionMap_TangentSpace(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
 {
        DPSOFTRAST_PixelShader_LightDirection(thread, triangle, span);
 }
@@ -4046,7 +4066,7 @@ void DPSOFTRAST_PixelShader_LightDirection(DPSOFTRAST_State_Thread *thread, cons
 
 
 
-void DPSOFTRAST_VertexShader_LightSource(void)
+static void DPSOFTRAST_VertexShader_LightSource(void)
 {
        int i;
        int numvertices = dpsoftrast.numvertices;
@@ -4113,7 +4133,7 @@ void DPSOFTRAST_VertexShader_LightSource(void)
        DPSOFTRAST_Array_Transform(DPSOFTRAST_ARRAY_TEXCOORD3, DPSOFTRAST_ARRAY_POSITION, dpsoftrast.uniform4f + 4*DPSOFTRAST_UNIFORM_ModelToLightM1);
 }
 
-void DPSOFTRAST_PixelShader_LightSource(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
+static void DPSOFTRAST_PixelShader_LightSource(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
 {
 #ifdef SSE_POSSIBLE
        float buffer_z[DPSOFTRAST_DRAW_MAXSPANLENGTH];
@@ -4410,14 +4430,14 @@ void DPSOFTRAST_PixelShader_LightSource(DPSOFTRAST_State_Thread *thread, const D
 
 
 
-void DPSOFTRAST_VertexShader_Refraction(void)
+static void DPSOFTRAST_VertexShader_Refraction(void)
 {
        DPSOFTRAST_Array_Transform(DPSOFTRAST_ARRAY_TEXCOORD4, DPSOFTRAST_ARRAY_POSITION, dpsoftrast.uniform4f + 4*DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1);
        DPSOFTRAST_Array_Transform(DPSOFTRAST_ARRAY_TEXCOORD0, DPSOFTRAST_ARRAY_TEXCOORD0, dpsoftrast.uniform4f + 4*DPSOFTRAST_UNIFORM_TexMatrixM1);
        DPSOFTRAST_Array_TransformProject(DPSOFTRAST_ARRAY_POSITION, DPSOFTRAST_ARRAY_POSITION, dpsoftrast.uniform4f + 4*DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1);
 }
 
-void DPSOFTRAST_PixelShader_Refraction(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
+static void DPSOFTRAST_PixelShader_Refraction(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
 {
        float buffer_z[DPSOFTRAST_DRAW_MAXSPANLENGTH];
        float z;
@@ -4499,7 +4519,7 @@ void DPSOFTRAST_PixelShader_Refraction(DPSOFTRAST_State_Thread *thread, const DP
 
 
 
-void DPSOFTRAST_VertexShader_Water(void)
+static void DPSOFTRAST_VertexShader_Water(void)
 {
        int i;
        int numvertices = dpsoftrast.numvertices;
@@ -4549,7 +4569,7 @@ void DPSOFTRAST_VertexShader_Water(void)
 }
 
 
-void DPSOFTRAST_PixelShader_Water(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
+static void DPSOFTRAST_PixelShader_Water(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
 {
        float buffer_z[DPSOFTRAST_DRAW_MAXSPANLENGTH];
        float z;
@@ -4667,12 +4687,12 @@ void DPSOFTRAST_PixelShader_Water(DPSOFTRAST_State_Thread *thread, const DPSOFTR
 
 
 
-void DPSOFTRAST_VertexShader_ShowDepth(void)
+static void DPSOFTRAST_VertexShader_ShowDepth(void)
 {
        DPSOFTRAST_Array_TransformProject(DPSOFTRAST_ARRAY_POSITION, DPSOFTRAST_ARRAY_POSITION, dpsoftrast.uniform4f + 4*DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1);
 }
 
-void DPSOFTRAST_PixelShader_ShowDepth(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
+static void DPSOFTRAST_PixelShader_ShowDepth(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
 {
        // TODO: IMPLEMENT
        float buffer_z[DPSOFTRAST_DRAW_MAXSPANLENGTH];
@@ -4684,12 +4704,12 @@ void DPSOFTRAST_PixelShader_ShowDepth(DPSOFTRAST_State_Thread *thread, const DPS
 
 
 
-void DPSOFTRAST_VertexShader_DeferredGeometry(void)
+static void DPSOFTRAST_VertexShader_DeferredGeometry(void)
 {
        DPSOFTRAST_Array_TransformProject(DPSOFTRAST_ARRAY_POSITION, DPSOFTRAST_ARRAY_POSITION, dpsoftrast.uniform4f + 4*DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1);
 }
 
-void DPSOFTRAST_PixelShader_DeferredGeometry(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
+static void DPSOFTRAST_PixelShader_DeferredGeometry(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
 {
        // TODO: IMPLEMENT
        float buffer_z[DPSOFTRAST_DRAW_MAXSPANLENGTH];
@@ -4701,12 +4721,12 @@ void DPSOFTRAST_PixelShader_DeferredGeometry(DPSOFTRAST_State_Thread *thread, co
 
 
 
-void DPSOFTRAST_VertexShader_DeferredLightSource(void)
+static void DPSOFTRAST_VertexShader_DeferredLightSource(void)
 {
        DPSOFTRAST_Array_TransformProject(DPSOFTRAST_ARRAY_POSITION, DPSOFTRAST_ARRAY_POSITION, dpsoftrast.uniform4f + 4*DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1);
 }
 
-void DPSOFTRAST_PixelShader_DeferredLightSource(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
+static void DPSOFTRAST_PixelShader_DeferredLightSource(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
 {
        // TODO: IMPLEMENT
        float buffer_z[DPSOFTRAST_DRAW_MAXSPANLENGTH];
@@ -4815,7 +4835,7 @@ static void DPSOFTRAST_Draw_DepthWrite(const DPSOFTRAST_State_Thread *thread, co
        }
 }
 
-void DPSOFTRAST_Draw_ProcessSpans(DPSOFTRAST_State_Thread *thread)
+static void DPSOFTRAST_Draw_ProcessSpans(DPSOFTRAST_State_Thread *thread)
 {
        int i;
        DPSOFTRAST_State_Triangle *triangle;
@@ -4837,7 +4857,7 @@ void DPSOFTRAST_Draw_ProcessSpans(DPSOFTRAST_State_Thread *thread)
        thread->numspans = 0;
 }
 
-DEFCOMMAND(22, Draw, int datasize; int starty; int endy; ATOMIC_COUNTER refcount; int clipped; int firstvertex; int numvertices; int numtriangles; float *arrays; int *element3i; unsigned short *element3s;);
+DEFCOMMAND(22, Draw, int datasize; int starty; int endy; ATOMIC_COUNTER refcount; int clipped; int firstvertex; int numvertices; int numtriangles; float *arrays; int *element3i; unsigned short *element3s;)
 
 static void DPSOFTRAST_Interpret_Draw(DPSOFTRAST_State_Thread *thread, DPSOFTRAST_Command_Draw *command)
 {
@@ -5407,7 +5427,7 @@ void DPSOFTRAST_DrawTriangles(int firstvertex, int numvertices, int numtriangles
        }
 }
 
-DEFCOMMAND(23, SetRenderTargets, int width; int height;);
+DEFCOMMAND(23, SetRenderTargets, int width; int height;)
 static void DPSOFTRAST_Interpret_SetRenderTargets(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_Command_SetRenderTargets *command)
 {
        thread->validate |= DPSOFTRAST_VALIDATE_FB;
index 2cf5e82f6aa45a0d3c0576aed4a87e9677b94c78..a72bf3645f86b40fea31ae22e021bd3fc67e5833 100644 (file)
@@ -33,7 +33,7 @@ typedef struct hz_bitstream_readblocks_s
 }
 hz_bitstream_readblocks_t;
 
-hz_bitstream_read_t *hz_bitstream_read_open(char *filename)
+static hz_bitstream_read_t *hz_bitstream_read_open(char *filename)
 {
        qfile_t *file;
        hz_bitstream_read_t *stream;
@@ -48,7 +48,7 @@ hz_bitstream_read_t *hz_bitstream_read_open(char *filename)
                return NULL;
 }
 
-void hz_bitstream_read_close(hz_bitstream_read_t *stream)
+static void hz_bitstream_read_close(hz_bitstream_read_t *stream)
 {
        if (stream)
        {
@@ -57,7 +57,7 @@ void hz_bitstream_read_close(hz_bitstream_read_t *stream)
        }
 }
 
-hz_bitstream_readblocks_t *hz_bitstream_read_blocks_new(void)
+static hz_bitstream_readblocks_t *hz_bitstream_read_blocks_new(void)
 {
        hz_bitstream_readblocks_t *blocks;
        blocks = (hz_bitstream_readblocks_t *)Z_Malloc(sizeof(hz_bitstream_readblocks_t));
@@ -67,7 +67,7 @@ hz_bitstream_readblocks_t *hz_bitstream_read_blocks_new(void)
        return blocks;
 }
 
-void hz_bitstream_read_blocks_free(hz_bitstream_readblocks_t *blocks)
+static void hz_bitstream_read_blocks_free(hz_bitstream_readblocks_t *blocks)
 {
        hz_bitstream_readblock_t *b, *n;
        if (blocks == NULL)
@@ -80,13 +80,13 @@ void hz_bitstream_read_blocks_free(hz_bitstream_readblocks_t *blocks)
        Z_Free(blocks);
 }
 
-void hz_bitstream_read_flushbits(hz_bitstream_readblocks_t *blocks)
+static void hz_bitstream_read_flushbits(hz_bitstream_readblocks_t *blocks)
 {
        blocks->store = 0;
        blocks->count = 0;
 }
 
-int hz_bitstream_read_blocks_read(hz_bitstream_readblocks_t *blocks, hz_bitstream_read_t *stream, unsigned int size)
+static int hz_bitstream_read_blocks_read(hz_bitstream_readblocks_t *blocks, hz_bitstream_read_t *stream, unsigned int size)
 {
        int s;
        hz_bitstream_readblock_t *b, *p;
@@ -133,7 +133,7 @@ int hz_bitstream_read_blocks_read(hz_bitstream_readblocks_t *blocks, hz_bitstrea
        return HZREADERROR_OK;
 }
 
-unsigned int hz_bitstream_read_blocks_getbyte(hz_bitstream_readblocks_t *blocks)
+static unsigned int hz_bitstream_read_blocks_getbyte(hz_bitstream_readblocks_t *blocks)
 {
        while (blocks->current != NULL && blocks->position >= blocks->current->size)
        {
@@ -145,7 +145,7 @@ unsigned int hz_bitstream_read_blocks_getbyte(hz_bitstream_readblocks_t *blocks)
        return blocks->current->data[blocks->position++];
 }
 
-int hz_bitstream_read_bit(hz_bitstream_readblocks_t *blocks)
+static int hz_bitstream_read_bit(hz_bitstream_readblocks_t *blocks)
 {
        if (!blocks->count)
        {
@@ -157,7 +157,7 @@ int hz_bitstream_read_bit(hz_bitstream_readblocks_t *blocks)
        return (blocks->store >> blocks->count) & 1;
 }
 
-unsigned int hz_bitstream_read_bits(hz_bitstream_readblocks_t *blocks, int size)
+static unsigned int hz_bitstream_read_bits(hz_bitstream_readblocks_t *blocks, int size)
 {
        unsigned int num = 0;
        // we can only handle about 24 bits at a time safely
@@ -178,18 +178,18 @@ unsigned int hz_bitstream_read_bits(hz_bitstream_readblocks_t *blocks, int size)
        return num;
 }
 
-unsigned int hz_bitstream_read_byte(hz_bitstream_readblocks_t *blocks)
+static unsigned int hz_bitstream_read_byte(hz_bitstream_readblocks_t *blocks)
 {
        return hz_bitstream_read_blocks_getbyte(blocks);
 }
 
-unsigned int hz_bitstream_read_short(hz_bitstream_readblocks_t *blocks)
+static unsigned int hz_bitstream_read_short(hz_bitstream_readblocks_t *blocks)
 {
        return (hz_bitstream_read_byte(blocks) << 8)
             | (hz_bitstream_read_byte(blocks));
 }
 
-unsigned int hz_bitstream_read_int(hz_bitstream_readblocks_t *blocks)
+static unsigned int hz_bitstream_read_int(hz_bitstream_readblocks_t *blocks)
 {
        return (hz_bitstream_read_byte(blocks) << 24)
             | (hz_bitstream_read_byte(blocks) << 16)
@@ -197,7 +197,7 @@ unsigned int hz_bitstream_read_int(hz_bitstream_readblocks_t *blocks)
             | (hz_bitstream_read_byte(blocks));
 }
 
-void hz_bitstream_read_bytes(hz_bitstream_readblocks_t *blocks, void *outdata, unsigned int size)
+static void hz_bitstream_read_bytes(hz_bitstream_readblocks_t *blocks, void *outdata, unsigned int size)
 {
        unsigned char *out;
        out = (unsigned char *)outdata;
diff --git a/fs.c b/fs.c
index f0fbc4e1179e8c3afe348ef0bef2686dbb08e740..775b97f4d975ac4848fbc5408d278272493866fb 100644 (file)
--- a/fs.c
+++ b/fs.c
@@ -463,7 +463,7 @@ PK3_CloseLibrary
 Unload the Zlib DLL
 ====================
 */
-void PK3_CloseLibrary (void)
+static void PK3_CloseLibrary (void)
 {
 #ifndef LINK_TO_ZLIB
        Sys_UnloadLibrary (&zlib_dll);
@@ -478,7 +478,7 @@ PK3_OpenLibrary
 Try to load the Zlib DLL
 ====================
 */
-qboolean PK3_OpenLibrary (void)
+static qboolean PK3_OpenLibrary (void)
 {
 #ifdef LINK_TO_ZLIB
        return true;
@@ -534,7 +534,7 @@ PK3_GetEndOfCentralDir
 Extract the end of the central directory from a PK3 package
 ====================
 */
-qboolean PK3_GetEndOfCentralDir (const char *packfile, int packhandle, pk3_endOfCentralDir_t *eocd)
+static qboolean PK3_GetEndOfCentralDir (const char *packfile, int packhandle, pk3_endOfCentralDir_t *eocd)
 {
        fs_offset_t filesize, maxsize;
        unsigned char *buffer, *ptr;
@@ -599,7 +599,7 @@ PK3_BuildFileList
 Extract the file list from a PK3 file
 ====================
 */
-int PK3_BuildFileList (pack_t *pack, const pk3_endOfCentralDir_t *eocd)
+static int PK3_BuildFileList (pack_t *pack, const pk3_endOfCentralDir_t *eocd)
 {
        unsigned char *central_dir, *ptr;
        unsigned int ind;
@@ -719,7 +719,7 @@ FS_LoadPackPK3
 Create a package entry associated with a PK3 file
 ====================
 */
-pack_t *FS_LoadPackPK3FromFD (const char *packfile, int packhandle, qboolean silent)
+static pack_t *FS_LoadPackPK3FromFD (const char *packfile, int packhandle, qboolean silent)
 {
        pk3_endOfCentralDir_t eocd;
        pack_t *pack;
@@ -772,7 +772,7 @@ pack_t *FS_LoadPackPK3FromFD (const char *packfile, int packhandle, qboolean sil
        Con_DPrintf("Added packfile %s (%i files)\n", packfile, real_nb_files);
        return pack;
 }
-pack_t *FS_LoadPackPK3 (const char *packfile)
+static pack_t *FS_LoadPackPK3 (const char *packfile)
 {
        int packhandle;
 #if _MSC_VER >= 1400
@@ -793,7 +793,7 @@ PK3_GetTrueFileOffset
 Find where the true file data offset is
 ====================
 */
-qboolean PK3_GetTrueFileOffset (packfile_t *pfile, pack_t *pack)
+static qboolean PK3_GetTrueFileOffset (packfile_t *pfile, pack_t *pack)
 {
        unsigned char buffer [ZIP_LOCAL_CHUNK_BASE_SIZE];
        fs_offset_t count;
@@ -912,7 +912,7 @@ FS_Path_f
 
 ============
 */
-void FS_Path_f (void)
+static void FS_Path_f (void)
 {
        searchpath_t *s;
 
@@ -941,7 +941,7 @@ FS_LoadPackPAK
  *Loads the header and directory, adding the files at the beginning
  *of the list so they override previous pack files.
  */
-pack_t *FS_LoadPackPAK (const char *packfile)
+static pack_t *FS_LoadPackPAK (const char *packfile)
 {
        dpackheader_t header;
        int i, numpackfiles;
@@ -1026,7 +1026,7 @@ FS_LoadPackVirtual
 Create a package entry associated with a directory file
 ====================
 */
-pack_t *FS_LoadPackVirtual (const char *dirname)
+static pack_t *FS_LoadPackVirtual (const char *dirname)
 {
        pack_t *pack;
        pack = (pack_t *)Mem_Alloc(fs_mempool, sizeof (pack_t));
@@ -1198,7 +1198,7 @@ Sets fs_gamedir, adds the directory to the head of the path,
 then loads and adds pak1.pak pak2.pak ...
 ================
 */
-void FS_AddGameDirectory (const char *dir)
+static void FS_AddGameDirectory (const char *dir)
 {
        int i;
        stringlist_t list;
@@ -1244,13 +1244,14 @@ void FS_AddGameDirectory (const char *dir)
 FS_AddGameHierarchy
 ================
 */
-void FS_AddGameHierarchy (const char *dir)
+static void FS_AddGameHierarchy (const char *dir)
 {
+       char vabuf[1024];
        // Add the common game directory
-       FS_AddGameDirectory (va("%s%s/", fs_basedir, dir));
+       FS_AddGameDirectory (va(vabuf, sizeof(vabuf), "%s%s/", fs_basedir, dir));
 
        if (*fs_userdir)
-               FS_AddGameDirectory(va("%s%s/", fs_userdir, dir));
+               FS_AddGameDirectory(va(vabuf, sizeof(vabuf), "%s%s/", fs_userdir, dir));
 }
 
 
@@ -1304,7 +1305,7 @@ const char *FS_FileWithoutPath (const char *in)
 FS_ClearSearchPath
 ================
 */
-void FS_ClearSearchPath (void)
+static void FS_ClearSearchPath (void)
 {
        // unload all packs and directory information, close all pack files
        // (if a qfile is still reading a pack it won't be harmed because it used
@@ -1353,6 +1354,7 @@ void FS_Rescan (void)
        qboolean fs_modified = false;
        qboolean reset = false;
        char gamedirbuf[MAX_INPUTLINE];
+       char vabuf[1024];
 
        if (fs_searchpaths)
                reset = true;
@@ -1391,7 +1393,7 @@ void FS_Rescan (void)
                // update the com_modname (used server info)
                strlcpy (com_modname, fs_gamedirs[i], sizeof (com_modname));
                if(i)
-                       strlcat(gamedirbuf, va(" %s", fs_gamedirs[i]), sizeof(gamedirbuf));
+                       strlcat(gamedirbuf, va(vabuf, sizeof(vabuf), " %s", fs_gamedirs[i]), sizeof(gamedirbuf));
                else
                        strlcpy(gamedirbuf, fs_gamedirs[i], sizeof(gamedirbuf));
        }
@@ -1412,7 +1414,7 @@ void FS_Rescan (void)
 
        // If "-condebug" is in the command line, remove the previous log file
        if (COM_CheckParm ("-condebug") != 0)
-               unlink (va("%s/qconsole.log", fs_gamedir));
+               unlink (va(vabuf, sizeof(vabuf), "%s/qconsole.log", fs_gamedir));
 
        // look for the pop.lmp file and set registered to true if it is found
        if (FS_FileExists("gfx/pop.lmp"))
@@ -1446,7 +1448,7 @@ void FS_Rescan (void)
        W_UnloadAll();
 }
 
-void FS_Rescan_f(void)
+static void FS_Rescan_f(void)
 {
        FS_Rescan();
 }
@@ -1456,10 +1458,7 @@ void FS_Rescan_f(void)
 FS_ChangeGameDirs
 ================
 */
-extern void Host_SaveConfig (void);
-extern void Host_LoadConfig_f (void);
 extern qboolean vid_opened;
-extern void VID_Stop(void);
 qboolean FS_ChangeGameDirs(int numgamedirs, char gamedirs[][MAX_QPATH], qboolean complain, qboolean failmissing)
 {
        int i;
@@ -1532,7 +1531,7 @@ qboolean FS_ChangeGameDirs(int numgamedirs, char gamedirs[][MAX_QPATH], qboolean
 FS_GameDir_f
 ================
 */
-void FS_GameDir_f (void)
+static void FS_GameDir_f (void)
 {
        int i;
        int numgamedirs;
@@ -1570,13 +1569,13 @@ void FS_GameDir_f (void)
        FS_ChangeGameDirs(numgamedirs, gamedirs, true, true);
 }
 
-static const char *FS_SysCheckGameDir(const char *gamedir)
+static const char *FS_SysCheckGameDir(const char *gamedir, char *buf, size_t buflength)
 {
-       static char buf[8192];
        qboolean success;
        qfile_t *f;
        stringlist_t list;
        fs_offset_t n;
+       char vabuf[1024];
 
        stringlistinit(&list);
        listdirectory(&list, gamedir, "");
@@ -1585,10 +1584,10 @@ static const char *FS_SysCheckGameDir(const char *gamedir)
 
        if(success)
        {
-               f = FS_SysOpen(va("%smodinfo.txt", gamedir), "r", false);
+               f = FS_SysOpen(va(vabuf, sizeof(vabuf), "%smodinfo.txt", gamedir), "r", false);
                if(f)
                {
-                       n = FS_Read (f, buf, sizeof(buf) - 1);
+                       n = FS_Read (f, buf, buflength - 1);
                        if(n >= 0)
                                buf[n] = 0;
                        else
@@ -1611,17 +1610,19 @@ FS_CheckGameDir
 const char *FS_CheckGameDir(const char *gamedir)
 {
        const char *ret;
+       char buf[8192];
+       char vabuf[1024];
 
        if (FS_CheckNastyPath(gamedir, true))
                return NULL;
 
-       ret = FS_SysCheckGameDir(va("%s%s/", fs_userdir, gamedir));
+       ret = FS_SysCheckGameDir(va(vabuf, sizeof(vabuf), "%s%s/", fs_userdir, gamedir), buf, sizeof(buf));
        if(ret)
        {
                if(!*ret)
                {
                        // get description from basedir
-                       ret = FS_SysCheckGameDir(va("%s%s/", fs_basedir, gamedir));
+                       ret = FS_SysCheckGameDir(va(vabuf, sizeof(vabuf), "%s%s/", fs_basedir, gamedir), buf, sizeof(buf));
                        if(ret)
                                return ret;
                        return "";
@@ -1629,7 +1630,7 @@ const char *FS_CheckGameDir(const char *gamedir)
                return ret;
        }
 
-       ret = FS_SysCheckGameDir(va("%s%s/", fs_basedir, gamedir));
+       ret = FS_SysCheckGameDir(va(vabuf, sizeof(vabuf), "%s%s/", fs_basedir, gamedir), buf, sizeof(buf));
        if(ret)
                return ret;
        
@@ -1641,14 +1642,15 @@ static void FS_ListGameDirs(void)
        stringlist_t list, list2;
        int i, j;
        const char *info;
+       char vabuf[1024];
 
        fs_all_gamedirs_count = 0;
        if(fs_all_gamedirs)
                Mem_Free(fs_all_gamedirs);
 
        stringlistinit(&list);
-       listdirectory(&list, va("%s/", fs_basedir), "");
-       listdirectory(&list, va("%s/", fs_userdir), "");
+       listdirectory(&list, va(vabuf, sizeof(vabuf), "%s/", fs_basedir), "");
+       listdirectory(&list, va(vabuf, sizeof(vabuf), "%s/", fs_userdir), "");
        stringlistsort(&list, false);
 
        stringlistinit(&list2);
@@ -1744,7 +1746,7 @@ void FS_Init_SelfPack (void)
        }
 }
 
-int FS_ChooseUserDir(userdirmode_t userdirmode, char *userdir, size_t userdirsize)
+static int FS_ChooseUserDir(userdirmode_t userdirmode, char *userdir, size_t userdirsize)
 {
 #if defined(__IPHONEOS__)
        if (userdirmode == USERDIRMODE_HOME)
@@ -1765,7 +1767,8 @@ int FS_ChooseUserDir(userdirmode_t userdirmode, char *userdir, size_t userdirsiz
        wchar_t *savedgamesdirw;
        char savedgamesdir[MAX_OSPATH];
        int fd;
-       
+       char vabuf[1024];
+
        userdir[0] = 0;
        switch(userdirmode)
        {
@@ -1838,6 +1841,7 @@ int FS_ChooseUserDir(userdirmode_t userdirmode, char *userdir, size_t userdirsiz
 #else
        int fd;
        char *homedir;
+       char vabuf[1024];
        userdir[0] = 0;
        switch(userdirmode)
        {
@@ -1887,15 +1891,15 @@ int FS_ChooseUserDir(userdirmode_t userdirmode, char *userdir, size_t userdirsiz
        // see if we can write to this path (note: won't create path)
 #ifdef WIN32
 # if _MSC_VER >= 1400
-       _sopen_s(&fd, va("%s%s/config.cfg", userdir, gamedirname1), O_WRONLY | O_CREAT, _SH_DENYNO, _S_IREAD | _S_IWRITE); // note: no O_TRUNC here!
+       _sopen_s(&fd, va(vabuf, sizeof(vabuf), "%s%s/config.cfg", userdir, gamedirname1), O_WRONLY | O_CREAT, _SH_DENYNO, _S_IREAD | _S_IWRITE); // note: no O_TRUNC here!
 # else
-       fd = open (va("%s%s/config.cfg", userdir, gamedirname1), O_WRONLY | O_CREAT, 0666); // note: no O_TRUNC here!
+       fd = open (va(vabuf, sizeof(vabuf), "%s%s/config.cfg", userdir, gamedirname1), O_WRONLY | O_CREAT, 0666); // note: no O_TRUNC here!
 # endif
        if(fd >= 0)
                close(fd);
 #else
        // on Unix, we don't need to ACTUALLY attempt to open the file
-       if(access(va("%s%s/", userdir, gamedirname1), W_OK | X_OK) >= 0)
+       if(access(va(vabuf, sizeof(vabuf), "%s%s/", userdir, gamedirname1), W_OK | X_OK) >= 0)
                fd = 1;
        else
                fd = 0;
@@ -1956,7 +1960,7 @@ void FS_Init (void)
                                // truncate to just after the .app/
                                split[5] = 0;
                                // see if gamedir exists in Resources
-                               if (stat(va("%s/Contents/Resources/%s", fs_basedir, gamedirname1), &statresult) == 0)
+                               if (stat(va(vabuf, sizeof(vabuf), "%s/Contents/Resources/%s", fs_basedir, gamedirname1), &statresult) == 0)
                                {
                                        // found gamedir inside Resources, use it
                                        strlcat(fs_basedir, "Contents/Resources/", sizeof(fs_basedir));
@@ -2100,6 +2104,7 @@ void FS_Shutdown (void)
        //  by the OS anyway)
        FS_ClearSearchPath();
        Mem_FreePool (&fs_mempool);
+       PK3_CloseLibrary ();
 
 #ifdef WIN32
        Sys_UnloadLibrary (&shfolder_dll);
@@ -2204,7 +2209,7 @@ FS_OpenPackedFile
 Open a packed file using its package file descriptor
 ===========
 */
-qfile_t *FS_OpenPackedFile (pack_t* pack, int pack_ind)
+static qfile_t *FS_OpenPackedFile (pack_t* pack, int pack_ind)
 {
        packfile_t *pfile;
        int dup_handle;
@@ -2459,7 +2464,7 @@ FS_OpenReadFile
 Look for a file in the search paths and open it in read-only mode
 ===========
 */
-qfile_t *FS_OpenReadFile (const char *filename, qboolean quiet, qboolean nonblocking, int symlinkLevels)
+static qfile_t *FS_OpenReadFile (const char *filename, qboolean quiet, qboolean nonblocking, int symlinkLevels)
 {
        searchpath_t *search;
        int pack_ind;
@@ -3572,7 +3577,7 @@ void FS_FreeSearch(fssearch_t *search)
 }
 
 extern int con_linewidth;
-int FS_ListDirectory(const char *pattern, int oneperline)
+static int FS_ListDirectory(const char *pattern, int oneperline)
 {
        int numfiles;
        int numcolumns;
diff --git a/fs.h b/fs.h
index 7ffba78eab5c028eaa756bec7be349dcdeb4fdcd..cd1979a2939bb424550931e285cc1d1c8ed69200 100644 (file)
--- a/fs.h
+++ b/fs.h
@@ -136,4 +136,9 @@ unsigned char *FS_Inflate(const unsigned char *data, size_t size, size_t *inflat
 
 qboolean FS_HasZlib(void);
 
+void FS_Init_SelfPack(void);
+void FS_Init(void);
+void FS_Shutdown(void);
+void FS_Init_Commands(void);
+
 #endif
diff --git a/ft2.c b/ft2.c
index 269cb11780c5e94930ad91f23e455675d63810df..12e889057c8c821b09c75f4e96de6f032eec761e 100644 (file)
--- a/ft2.c
+++ b/ft2.c
@@ -363,7 +363,7 @@ ft2_font_t *Font_Alloc(void)
        return (ft2_font_t *)Mem_Alloc(font_mempool, sizeof(ft2_font_t));
 }
 
-qboolean Font_Attach(ft2_font_t *font, ft2_attachment_t *attachment)
+static qboolean Font_Attach(ft2_font_t *font, ft2_attachment_t *attachment)
 {
        ft2_attachment_t *na;
 
@@ -410,6 +410,7 @@ qboolean Font_LoadFont(const char *name, dp_font_t *dpfnt)
 {
        int s, count, i;
        ft2_font_t *ft2, *fbfont, *fb;
+       char vabuf[1024];
 
        ft2 = Font_Alloc();
        if (!ft2)
@@ -457,10 +458,10 @@ qboolean Font_LoadFont(const char *name, dp_font_t *dpfnt)
 
                if (!Font_LoadFile(dpfnt->fallbacks[i], dpfnt->fallback_faces[i], &dpfnt->settings, fb))
                {
-                       if(!FS_FileExists(va("%s.tga", dpfnt->fallbacks[i])))
-                       if(!FS_FileExists(va("%s.png", dpfnt->fallbacks[i])))
-                       if(!FS_FileExists(va("%s.jpg", dpfnt->fallbacks[i])))
-                       if(!FS_FileExists(va("%s.pcx", dpfnt->fallbacks[i])))
+                       if(!FS_FileExists(va(vabuf, sizeof(vabuf), "%s.tga", dpfnt->fallbacks[i])))
+                       if(!FS_FileExists(va(vabuf, sizeof(vabuf), "%s.png", dpfnt->fallbacks[i])))
+                       if(!FS_FileExists(va(vabuf, sizeof(vabuf), "%s.jpg", dpfnt->fallbacks[i])))
+                       if(!FS_FileExists(va(vabuf, sizeof(vabuf), "%s.pcx", dpfnt->fallbacks[i])))
                                Con_Printf("Failed to load font %s for fallback %i of font %s\n", dpfnt->fallbacks[i], i, name);
                        Mem_Free(fb);
                        continue;
@@ -612,7 +613,7 @@ static qboolean Font_LoadFile(const char *name, int _face, ft2_settings_t *setti
        return true;
 }
 
-void Font_Postprocess_Update(ft2_font_t *fnt, int bpp, int w, int h)
+static void Font_Postprocess_Update(ft2_font_t *fnt, int bpp, int w, int h)
 {
        int needed, x, y;
        float gausstable[2*POSTPROCESS_MAXRADIUS+1];
@@ -666,7 +667,7 @@ void Font_Postprocess_Update(ft2_font_t *fnt, int bpp, int w, int h)
        }
 }
 
-void Font_Postprocess(ft2_font_t *fnt, unsigned char *imagedata, int pitch, int bpp, int w, int h, int *pad_l, int *pad_r, int *pad_t, int *pad_b)
+static void Font_Postprocess(ft2_font_t *fnt, unsigned char *imagedata, int pitch, int bpp, int w, int h, int *pad_l, int *pad_r, int *pad_t, int *pad_b)
 {
        int x, y;
 
@@ -1109,6 +1110,7 @@ static qboolean Font_LoadMap(ft2_font_t *font, ft2_font_map_t *mapstart, Uchar _
        int tp;
        FT_Int32 load_flags;
        int gpad_l, gpad_r, gpad_t, gpad_b;
+       char vabuf[1024];
 
        int pitch;
        int gR, gC; // glyph position: row and column
@@ -1545,10 +1547,10 @@ static qboolean Font_LoadMap(ft2_font_t *font, ft2_font_map_t *mapstart, Uchar _
                                data[x*4+0] = data[x*4+2];
                                data[x*4+2] = b;
                        }
-                       Image_WriteTGABGRA(va("%s.tga", map_identifier), w, h, data);
+                       Image_WriteTGABGRA(va(vabuf, sizeof(vabuf), "%s.tga", map_identifier), w, h, data);
 #ifndef USE_GLES2
                        if (r_font_compress.integer && qglGetCompressedTexImageARB && tex)
-                               R_SaveTextureDDSFile(tex, va("dds/%s.dds", map_identifier), r_texture_dds_save.integer < 2, true);
+                               R_SaveTextureDDSFile(tex, va(vabuf, sizeof(vabuf), "dds/%s.dds", map_identifier), r_texture_dds_save.integer < 2, true);
 #endif
                }
        }
index 9a5b6028211aeda6be1285444cbfc98cccfa4ec0..06e5d2fdb4a2fe9a28d957b93a38ffb48d6fc5b4 100644 (file)
@@ -347,7 +347,7 @@ unsigned short polygonelement3s[(POLYGONELEMENTS_MAXPOINTS-2)*3];
 int quadelement3i[QUADELEMENTS_MAXQUADS*6];
 unsigned short quadelement3s[QUADELEMENTS_MAXQUADS*6];
 
-void GL_VBOStats_f(void)
+static void GL_VBOStats_f(void)
 {
        GL_Mesh_ListVBOs(true);
 }
@@ -2523,7 +2523,7 @@ void R_Mesh_Start(void)
        }
 }
 
-qboolean GL_Backend_CompileShader(int programobject, GLenum shadertypeenum, const char *shadertype, int numstrings, const char **strings)
+static qboolean GL_Backend_CompileShader(int programobject, GLenum shadertypeenum, const char *shadertype, int numstrings, const char **strings)
 {
        int shaderobject;
        int shadercompiled;
@@ -2622,18 +2622,6 @@ void GL_Backend_FreeProgram(unsigned int prog)
        CHECKGLERROR
 }
 
-void GL_Backend_RenumberElements(int *out, int count, const int *in, int offset)
-{
-       int i;
-       if (offset)
-       {
-               for (i = 0;i < count;i++)
-                       *out++ = *in++ + offset;
-       }
-       else
-               memcpy(out, in, sizeof(*out) * count);
-}
-
 // renders triangles using vertices from the active arrays
 int paranoidblah = 0;
 void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const r_meshbuffer_t *element3i_indexbuffer, size_t element3i_bufferoffset, const unsigned short *element3s, const r_meshbuffer_t *element3s_indexbuffer, size_t element3s_bufferoffset)
index 44a83a94380a267d9431d7b6c610b540d0daeab5..a23c98c48188d9ca054c3c4e21ea34025dedc59b 100644 (file)
--- a/gl_draw.c
+++ b/gl_draw.c
@@ -323,6 +323,7 @@ cachepic_t *Draw_CachePic_Flags(const char *path, unsigned int cachepicflags)
        qboolean ddshasalpha;
        float ddsavgcolor[4];
        qboolean loaded = false;
+       char vabuf[1024];
 
        texflags = TEXF_ALPHA;
        if (!(cachepicflags & CACHEPICFLAG_NOCLAMP))
@@ -392,7 +393,7 @@ reload:
        pic->lastusedframe = draw_frame;
 
        // load a high quality image from disk if possible
-       if (!loaded && r_texture_dds_load.integer != 0 && (pic->tex = R_LoadTextureDDSFile(drawtexturepool, va("dds/%s.dds", pic->name), vid.sRGB2D, pic->texflags, &ddshasalpha, ddsavgcolor, 0)))
+       if (!loaded && r_texture_dds_load.integer != 0 && (pic->tex = R_LoadTextureDDSFile(drawtexturepool, va(vabuf, sizeof(vabuf), "dds/%s.dds", pic->name), vid.sRGB2D, pic->texflags, &ddshasalpha, ddsavgcolor, 0)))
        {
                // note this loads even if autoload is true, otherwise we can't get the width/height
                loaded = true;
@@ -423,7 +424,7 @@ reload:
                        pic->tex = R_LoadTexture2D(drawtexturepool, pic->name, image_width, image_height, pixels, vid.sRGB2D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, pic->texflags & (pic->hasalpha ? ~0 : ~TEXF_ALPHA), -1, NULL);
 #ifndef USE_GLES2
                        if (r_texture_dds_save.integer && qglGetCompressedTexImageARB && pic->tex)
-                               R_SaveTextureDDSFile(pic->tex, va("dds/%s.dds", pic->name), r_texture_dds_save.integer < 2, pic->hasalpha);
+                               R_SaveTextureDDSFile(pic->tex, va(vabuf, sizeof(vabuf), "dds/%s.dds", pic->name), r_texture_dds_save.integer < 2, pic->hasalpha);
 #endif
                }
        }
@@ -511,20 +512,21 @@ cachepic_t *Draw_CachePic (const char *path)
 
 rtexture_t *Draw_GetPicTexture(cachepic_t *pic)
 {
+       char vabuf[1024];
        if (pic->autoload && !pic->tex)
        {
                if (pic->tex == NULL && r_texture_dds_load.integer != 0)
                {
                        qboolean ddshasalpha;
                        float ddsavgcolor[4];
-                       pic->tex = R_LoadTextureDDSFile(drawtexturepool, va("dds/%s.dds", pic->name), vid.sRGB2D, pic->texflags, &ddshasalpha, ddsavgcolor, 0);
+                       pic->tex = R_LoadTextureDDSFile(drawtexturepool, va(vabuf, sizeof(vabuf), "dds/%s.dds", pic->name), vid.sRGB2D, pic->texflags, &ddshasalpha, ddsavgcolor, 0);
                }
                if (pic->tex == NULL)
                {
                        pic->tex = loadtextureimage(drawtexturepool, pic->name, false, pic->texflags, true, vid.sRGB2D);
 #ifndef USE_GLES2
                        if (r_texture_dds_save.integer && qglGetCompressedTexImageARB && pic->tex)
-                               R_SaveTextureDDSFile(pic->tex, va("dds/%s.dds", pic->name), r_texture_dds_save.integer < 2, pic->hasalpha);
+                               R_SaveTextureDDSFile(pic->tex, va(vabuf, sizeof(vabuf), "dds/%s.dds", pic->name), r_texture_dds_save.integer < 2, pic->hasalpha);
 #endif
                }
                if (pic->tex == NULL && !strncmp(pic->name, "gfx/", 4))
@@ -532,7 +534,7 @@ rtexture_t *Draw_GetPicTexture(cachepic_t *pic)
                        pic->tex = loadtextureimage(drawtexturepool, pic->name+4, false, pic->texflags, true, vid.sRGB2D);
 #ifndef USE_GLES2
                        if (r_texture_dds_save.integer && qglGetCompressedTexImageARB && pic->tex)
-                               R_SaveTextureDDSFile(pic->tex, va("dds/%s.dds", pic->name), r_texture_dds_save.integer < 2, pic->hasalpha);
+                               R_SaveTextureDDSFile(pic->tex, va(vabuf, sizeof(vabuf), "dds/%s.dds", pic->name), r_texture_dds_save.integer < 2, pic->hasalpha);
 #endif
                }
                if (pic->tex == NULL)
@@ -996,6 +998,7 @@ Draw_Init
 static void gl_draw_start(void)
 {
        int i;
+       char vabuf[1024];
        drawtexturepool = R_AllocTexturePool();
 
        numcachepics = 0;
@@ -1006,7 +1009,7 @@ static void gl_draw_start(void)
        // load default font textures
        for(i = 0; i < dp_fonts.maxsize; ++i)
                if (dp_fonts.f[i].title[0])
-                       LoadFont(false, va("gfx/font_%s", dp_fonts.f[i].title), &dp_fonts.f[i], 1, 0);
+                       LoadFont(false, va(vabuf, sizeof(vabuf), "gfx/font_%s", dp_fonts.f[i].title), &dp_fonts.f[i], 1, 0);
 
        // draw the loading screen so people have something to see in the newly opened window
        SCR_UpdateLoadingScreen(true);
@@ -1089,7 +1092,7 @@ static void _DrawQ_Setup(void)
 }
 
 qboolean r_draw2d_force = false;
-void _DrawQ_SetupAndProcessDrawFlag(int flags, cachepic_t *pic, float alpha)
+static void _DrawQ_SetupAndProcessDrawFlag(int flags, cachepic_t *pic, float alpha)
 {
        _DrawQ_Setup();
        CHECKGLERROR
index 20aff5a24551d832f97d6047d46740904cbeb10e..d907ef3eb84befb9b2f723a182685ab0b41280cc 100644 (file)
@@ -858,7 +858,7 @@ static int shaderstaticparms_count = 0;
 
 static unsigned int r_compileshader_staticparms[(SHADERSTATICPARMS_COUNT + 0x1F) >> 5] = {0};
 #define R_COMPILESHADER_STATICPARM_ENABLE(p) r_compileshader_staticparms[(p) >> 5] |= (1 << ((p) & 0x1F))
-qboolean R_CompileShader_CheckStaticParms(void)
+static qboolean R_CompileShader_CheckStaticParms(void)
 {
        static int r_compileshader_staticparms_save[1];
        memcpy(r_compileshader_staticparms_save, r_compileshader_staticparms, sizeof(r_compileshader_staticparms));
@@ -892,7 +892,7 @@ qboolean R_CompileShader_CheckStaticParms(void)
                shaderstaticparmstrings_list[shaderstaticparms_count++] = "#define " n "\n"; \
        else \
                shaderstaticparmstrings_list[shaderstaticparms_count++] = "\n"
-void R_CompileShader_AddStaticParms(unsigned int mode, unsigned int permutation)
+static void R_CompileShader_AddStaticParms(unsigned int mode, unsigned int permutation)
 {
        shaderstaticparms_count = 0;
 
@@ -1232,7 +1232,7 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode
                Mem_Free(fragmentstring);
 }
 
-void R_SetupShader_SetPermutationGLSL(unsigned int mode, unsigned int permutation)
+static void R_SetupShader_SetPermutationGLSL(unsigned int mode, unsigned int permutation)
 {
        r_glsl_permutation_t *perm = R_GLSL_FindPermutation(mode, permutation);
        if (r_glsl_permutation != perm)
@@ -1458,8 +1458,8 @@ static void R_HLSL_CacheShader(r_hlsl_permutation_t *p, const char *cachename, c
        if (p->permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) {vsversion = "vs_3_0";psversion = "ps_3_0";}
        if (!debugshader)
        {
-               vsbin = (DWORD *)FS_LoadFile(va("%s.vsbin", cachename), r_main_mempool, true, &vsbinsize);
-               psbin = (DWORD *)FS_LoadFile(va("%s.psbin", cachename), r_main_mempool, true, &psbinsize);
+               vsbin = (DWORD *)FS_LoadFile(va(vabuf, sizeof(vabuf), "%s.vsbin", cachename), r_main_mempool, true, &vsbinsize);
+               psbin = (DWORD *)FS_LoadFile(va(vabuf, sizeof(vabuf), "%s.psbin", cachename), r_main_mempool, true, &psbinsize);
        }
        if ((!vsbin && vertstring) || (!psbin && fragstring))
        {
@@ -1510,9 +1510,9 @@ static void R_HLSL_CacheShader(r_hlsl_permutation_t *p, const char *cachename, c
                                if (debugshader)
                                {
 //                                     vsresult = qD3DXPreprocessShader(vertstring, strlen(vertstring), NULL, NULL, &vsbuffer, &vslog);
-//                                     FS_WriteFile(va("%s_vs.fx", cachename), vsbuffer->GetBufferPointer(), vsbuffer->GetBufferSize());
-                                       FS_WriteFile(va("%s_vs.fx", cachename), vertstring, strlen(vertstring));
-                                       vsresult = qD3DXCompileShaderFromFileA(va("%s/%s_vs.fx", fs_gamedir, cachename), NULL, NULL, "main", vsversion, shaderflags, &vsbuffer, &vslog, &vsconstanttable);
+//                                     FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_vs.fx", cachename), vsbuffer->GetBufferPointer(), vsbuffer->GetBufferSize());
+                                       FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_vs.fx", cachename), vertstring, strlen(vertstring));
+                                       vsresult = qD3DXCompileShaderFromFileA(va(vabuf, sizeof(vabuf), "%s/%s_vs.fx", fs_gamedir, cachename), NULL, NULL, "main", vsversion, shaderflags, &vsbuffer, &vslog, &vsconstanttable);
                                }
                                else
                                        vsresult = qD3DXCompileShader(vertstring, strlen(vertstring), NULL, NULL, "main", vsversion, shaderflags, &vsbuffer, &vslog, &vsconstanttable);
@@ -1535,9 +1535,9 @@ static void R_HLSL_CacheShader(r_hlsl_permutation_t *p, const char *cachename, c
                                if (debugshader)
                                {
 //                                     psresult = qD3DXPreprocessShader(fragstring, strlen(fragstring), NULL, NULL, &psbuffer, &pslog);
-//                                     FS_WriteFile(va("%s_ps.fx", cachename), psbuffer->GetBufferPointer(), psbuffer->GetBufferSize());
-                                       FS_WriteFile(va("%s_ps.fx", cachename), fragstring, strlen(fragstring));
-                                       psresult = qD3DXCompileShaderFromFileA(va("%s/%s_ps.fx", fs_gamedir, cachename), NULL, NULL, "main", psversion, shaderflags, &psbuffer, &pslog, &psconstanttable);
+//                                     FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_ps.fx", cachename), psbuffer->GetBufferPointer(), psbuffer->GetBufferSize());
+                                       FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_ps.fx", cachename), fragstring, strlen(fragstring));
+                                       psresult = qD3DXCompileShaderFromFileA(va(vabuf, sizeof(vabuf), "%s/%s_ps.fx", fs_gamedir, cachename), NULL, NULL, "main", psversion, shaderflags, &psbuffer, &pslog, &psconstanttable);
                                }
                                else
                                        psresult = qD3DXCompileShader(fragstring, strlen(fragstring), NULL, NULL, "main", psversion, shaderflags, &psbuffer, &pslog, &psconstanttable);
@@ -1778,7 +1778,7 @@ void R_SetupShader_SetPermutationHLSL(unsigned int mode, unsigned int permutatio
 }
 #endif
 
-void R_SetupShader_SetPermutationSoft(unsigned int mode, unsigned int permutation)
+static void R_SetupShader_SetPermutationSoft(unsigned int mode, unsigned int permutation)
 {
        DPSOFTRAST_SetShader(mode, permutation, r_shadow_glossexact.integer);
        DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1, 1, false, gl_modelviewprojection16f);
@@ -1786,7 +1786,7 @@ void R_SetupShader_SetPermutationSoft(unsigned int mode, unsigned int permutatio
        DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ClientTime, cl.time);
 }
 
-void R_GLSL_Restart_f(void)
+static void R_GLSL_Restart_f(void)
 {
        unsigned int i, limit;
        if (glslshaderstring && glslshaderstring != builtinshaderstring)
@@ -1850,7 +1850,7 @@ void R_GLSL_Restart_f(void)
        }
 }
 
-void R_GLSL_DumpShader_f(void)
+static void R_GLSL_DumpShader_f(void)
 {
        int i;
        qfile_t *file;
@@ -3289,6 +3289,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
        int miplevel = R_PicmipForFlags(textureflags);
        int savemiplevel = miplevel;
        int mymiplevel;
+       char vabuf[1024];
 
        if (cls.state == ca_dedicated)
                return NULL;
@@ -3303,7 +3304,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
        Image_StripImageExtension(name, basename, sizeof(basename));
 
        // check for DDS texture file first
-       if (!r_loaddds || !(ddsbase = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s.dds", basename), vid.sRGB3D, textureflags, &ddshasalpha, ddsavgcolor, miplevel)))
+       if (!r_loaddds || !(ddsbase = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s.dds", basename), vid.sRGB3D, textureflags, &ddshasalpha, ddsavgcolor, miplevel)))
        {
                basepixels = loadimagepixelsbgra(name, complain, true, false, &miplevel);
                if (basepixels == NULL)
@@ -3337,7 +3338,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
                skinframe->hasalpha = ddshasalpha;
                VectorCopy(ddsavgcolor, skinframe->avgcolor);
                if (r_loadfog && skinframe->hasalpha)
-                       skinframe->fog = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_mask.dds", skinframe->basename), false, textureflags | TEXF_ALPHA, NULL, NULL, miplevel);
+                       skinframe->fog = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_mask.dds", skinframe->basename), false, textureflags | TEXF_ALPHA, NULL, NULL, miplevel);
                //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]);
        }
        else
@@ -3366,7 +3367,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
                                        pixels[j+2] = 255;
                                        pixels[j+3] = basepixels[j+3];
                                }
-                               skinframe->fog = R_LoadTexture2D (r_main_texturepool, va("%s_mask", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), miplevel, NULL);
+                               skinframe->fog = R_LoadTexture2D (r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_mask", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), miplevel, NULL);
                                Mem_Free(pixels);
                        }
                }
@@ -3374,9 +3375,9 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
 #ifndef USE_GLES2
                //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]);
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->base)
-                       R_SaveTextureDDSFile(skinframe->base, va("dds/%s.dds", skinframe->basename), r_texture_dds_save.integer < 2, skinframe->hasalpha);
+                       R_SaveTextureDDSFile(skinframe->base, va(vabuf, sizeof(vabuf), "dds/%s.dds", skinframe->basename), r_texture_dds_save.integer < 2, skinframe->hasalpha);
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->fog)
-                       R_SaveTextureDDSFile(skinframe->fog, va("dds/%s_mask.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
+                       R_SaveTextureDDSFile(skinframe->fog, va(vabuf, sizeof(vabuf), "dds/%s_mask.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
 #endif
        }
 
@@ -3384,30 +3385,30 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
        {
                mymiplevel = savemiplevel;
                if (r_loadnormalmap)
-                       skinframe->nmap = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_norm.dds", skinframe->basename), false, (TEXF_ALPHA | textureflags) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), NULL, NULL, mymiplevel);
-               skinframe->glow = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_glow.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel);
+                       skinframe->nmap = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_norm.dds", skinframe->basename), false, (TEXF_ALPHA | textureflags) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), NULL, NULL, mymiplevel);
+               skinframe->glow = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_glow.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel);
                if (r_loadgloss)
-                       skinframe->gloss = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_gloss.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel);
-               skinframe->pants = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_pants.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel);
-               skinframe->shirt = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_shirt.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel);
-               skinframe->reflect = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_reflect.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel);
+                       skinframe->gloss = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_gloss.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel);
+               skinframe->pants = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_pants.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel);
+               skinframe->shirt = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_shirt.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel);
+               skinframe->reflect = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_reflect.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel);
        }
 
        // _norm is the name used by tenebrae and has been adopted as standard
        if (r_loadnormalmap && skinframe->nmap == NULL)
        {
                mymiplevel = savemiplevel;
-               if ((pixels = loadimagepixelsbgra(va("%s_norm", skinframe->basename), false, false, false, &mymiplevel)) != NULL)
+               if ((pixels = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "%s_norm", skinframe->basename), false, false, false, &mymiplevel)) != NULL)
                {
-                       skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | textureflags) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP) & (gl_texturecompression_normal.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+                       skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | textureflags) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP) & (gl_texturecompression_normal.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
                        Mem_Free(pixels);
                        pixels = NULL;
                }
-               else if (r_shadow_bumpscale_bumpmap.value > 0 && (bumppixels = loadimagepixelsbgra(va("%s_bump", skinframe->basename), false, false, false, &mymiplevel)) != NULL)
+               else if (r_shadow_bumpscale_bumpmap.value > 0 && (bumppixels = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "%s_bump", skinframe->basename), false, false, false, &mymiplevel)) != NULL)
                {
                        pixels = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4);
                        Image_HeightmapToNormalmap_BGRA(bumppixels, pixels, image_width, image_height, false, r_shadow_bumpscale_bumpmap.value);
-                       skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | textureflags) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP) & (gl_texturecompression_normal.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+                       skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | textureflags) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP) & (gl_texturecompression_normal.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
                        Mem_Free(pixels);
                        Mem_Free(bumppixels);
                }
@@ -3415,71 +3416,71 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
                {
                        pixels = (unsigned char *)Mem_Alloc(tempmempool, basepixels_width * basepixels_height * 4);
                        Image_HeightmapToNormalmap_BGRA(basepixels, pixels, basepixels_width, basepixels_height, false, r_shadow_bumpscale_basetexture.value);
-                       skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), basepixels_width, basepixels_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | textureflags) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP) & (gl_texturecompression_normal.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+                       skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_nmap", skinframe->basename), basepixels_width, basepixels_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | textureflags) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP) & (gl_texturecompression_normal.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
                        Mem_Free(pixels);
                }
 #ifndef USE_GLES2
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->nmap)
-                       R_SaveTextureDDSFile(skinframe->nmap, va("dds/%s_norm.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
+                       R_SaveTextureDDSFile(skinframe->nmap, va(vabuf, sizeof(vabuf), "dds/%s_norm.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
 #endif
        }
 
        // _luma is supported only for tenebrae compatibility
        // _glow is the preferred name
        mymiplevel = savemiplevel;
-       if (skinframe->glow == NULL && ((pixels = loadimagepixelsbgra(va("%s_glow",  skinframe->basename), false, false, false, &mymiplevel)) || (pixels = loadimagepixelsbgra(va("%s_luma", skinframe->basename), false, false, false, &mymiplevel))))
+       if (skinframe->glow == NULL && ((pixels = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "%s_glow",  skinframe->basename), false, false, false, &mymiplevel)) || (pixels = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "%s_luma", skinframe->basename), false, false, false, &mymiplevel))))
        {
-               skinframe->glow = R_LoadTexture2D (r_main_texturepool, va("%s_glow", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_glow.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+               skinframe->glow = R_LoadTexture2D (r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_glow", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_glow.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
 #ifndef USE_GLES2
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->glow)
-                       R_SaveTextureDDSFile(skinframe->glow, va("dds/%s_glow.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
+                       R_SaveTextureDDSFile(skinframe->glow, va(vabuf, sizeof(vabuf), "dds/%s_glow.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
 #endif
                Mem_Free(pixels);pixels = NULL;
        }
 
        mymiplevel = savemiplevel;
-       if (skinframe->gloss == NULL && r_loadgloss && (pixels = loadimagepixelsbgra(va("%s_gloss", skinframe->basename), false, false, false, &mymiplevel)))
+       if (skinframe->gloss == NULL && r_loadgloss && (pixels = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "%s_gloss", skinframe->basename), false, false, false, &mymiplevel)))
        {
-               skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va("%s_gloss", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, (TEXF_ALPHA | textureflags) & (gl_texturecompression_gloss.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+               skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_gloss", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, (TEXF_ALPHA | textureflags) & (gl_texturecompression_gloss.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
 #ifndef USE_GLES2
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->gloss)
-                       R_SaveTextureDDSFile(skinframe->gloss, va("dds/%s_gloss.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
+                       R_SaveTextureDDSFile(skinframe->gloss, va(vabuf, sizeof(vabuf), "dds/%s_gloss.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
 #endif
                Mem_Free(pixels);
                pixels = NULL;
        }
 
        mymiplevel = savemiplevel;
-       if (skinframe->pants == NULL && (pixels = loadimagepixelsbgra(va("%s_pants", skinframe->basename), false, false, false, &mymiplevel)))
+       if (skinframe->pants == NULL && (pixels = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "%s_pants", skinframe->basename), false, false, false, &mymiplevel)))
        {
-               skinframe->pants = R_LoadTexture2D (r_main_texturepool, va("%s_pants", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+               skinframe->pants = R_LoadTexture2D (r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_pants", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
 #ifndef USE_GLES2
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->pants)
-                       R_SaveTextureDDSFile(skinframe->pants, va("dds/%s_pants.dds", skinframe->basename), r_texture_dds_save.integer < 2, false);
+                       R_SaveTextureDDSFile(skinframe->pants, va(vabuf, sizeof(vabuf), "dds/%s_pants.dds", skinframe->basename), r_texture_dds_save.integer < 2, false);
 #endif
                Mem_Free(pixels);
                pixels = NULL;
        }
 
        mymiplevel = savemiplevel;
-       if (skinframe->shirt == NULL && (pixels = loadimagepixelsbgra(va("%s_shirt", skinframe->basename), false, false, false, &mymiplevel)))
+       if (skinframe->shirt == NULL && (pixels = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "%s_shirt", skinframe->basename), false, false, false, &mymiplevel)))
        {
-               skinframe->shirt = R_LoadTexture2D (r_main_texturepool, va("%s_shirt", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+               skinframe->shirt = R_LoadTexture2D (r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_shirt", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
 #ifndef USE_GLES2
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->shirt)
-                       R_SaveTextureDDSFile(skinframe->shirt, va("dds/%s_shirt.dds", skinframe->basename), r_texture_dds_save.integer < 2, false);
+                       R_SaveTextureDDSFile(skinframe->shirt, va(vabuf, sizeof(vabuf), "dds/%s_shirt.dds", skinframe->basename), r_texture_dds_save.integer < 2, false);
 #endif
                Mem_Free(pixels);
                pixels = NULL;
        }
 
        mymiplevel = savemiplevel;
-       if (skinframe->reflect == NULL && (pixels = loadimagepixelsbgra(va("%s_reflect", skinframe->basename), false, false, false, &mymiplevel)))
+       if (skinframe->reflect == NULL && (pixels = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "%s_reflect", skinframe->basename), false, false, false, &mymiplevel)))
        {
-               skinframe->reflect = R_LoadTexture2D (r_main_texturepool, va("%s_reflect", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_reflectmask.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+               skinframe->reflect = R_LoadTexture2D (r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_reflect", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_reflectmask.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
 #ifndef USE_GLES2
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->reflect)
-                       R_SaveTextureDDSFile(skinframe->reflect, va("dds/%s_reflect.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
+                       R_SaveTextureDDSFile(skinframe->reflect, va(vabuf, sizeof(vabuf), "dds/%s_reflect.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
 #endif
                Mem_Free(pixels);
                pixels = NULL;
@@ -3497,6 +3498,7 @@ skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, co
        int i;
        unsigned char *temp1, *temp2;
        skinframe_t *skinframe;
+       char vabuf[1024];
 
        if (cls.state == ca_dedicated)
                return NULL;
@@ -3531,7 +3533,7 @@ skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, co
                temp1 = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8);
                temp2 = temp1 + width * height * 4;
                Image_HeightmapToNormalmap_BGRA(skindata, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
-               skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va("%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, (textureflags | TEXF_ALPHA) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), -1, NULL);
+               skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, (textureflags | TEXF_ALPHA) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), -1, NULL);
                Mem_Free(temp1);
        }
        skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, sRGB ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags, -1, NULL);
@@ -3551,7 +3553,7 @@ skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, co
                        memcpy(fogpixels, skindata, width * height * 4);
                        for (i = 0;i < width * height * 4;i += 4)
                                fogpixels[i] = fogpixels[i+1] = fogpixels[i+2] = 255;
-                       skinframe->fog = R_LoadTexture2D(r_main_texturepool, va("%s_fog", skinframe->basename), width, height, fogpixels, TEXTYPE_BGRA, textureflags, -1, NULL);
+                       skinframe->fog = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_fog", skinframe->basename), width, height, fogpixels, TEXTYPE_BGRA, textureflags, -1, NULL);
                        Mem_Free(fogpixels);
                }
        }
@@ -3624,6 +3626,7 @@ static void R_SkinFrame_GenerateTexturesFromQPixels(skinframe_t *skinframe, qboo
        int width;
        int height;
        unsigned char *skindata;
+       char vabuf[1024];
 
        if (!skinframe->qpixels)
                return;
@@ -3655,22 +3658,22 @@ static void R_SkinFrame_GenerateTexturesFromQPixels(skinframe_t *skinframe, qboo
                // use either a custom palette or the quake palette
                Image_Copy8bitBGRA(skindata, temp1, width * height, palette_bgra_complete);
                Image_HeightmapToNormalmap_BGRA(temp1, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
-               skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va("%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, (skinframe->textureflags | TEXF_ALPHA) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), -1, NULL);
+               skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, (skinframe->textureflags | TEXF_ALPHA) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), -1, NULL);
                Mem_Free(temp1);
        }
 
        if (skinframe->qgenerateglow)
        {
                skinframe->qgenerateglow = false;
-               skinframe->glow = R_LoadTexture2D(r_main_texturepool, va("%s_glow", skinframe->basename), width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags, -1, palette_bgra_onlyfullbrights); // glow
+               skinframe->glow = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_glow", skinframe->basename), width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags, -1, palette_bgra_onlyfullbrights); // glow
        }
 
        if (colormapped)
        {
                skinframe->qgeneratebase = false;
-               skinframe->base  = R_LoadTexture2D(r_main_texturepool, va("%s_nospecial", skinframe->basename), width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags, -1, skinframe->glow ? palette_bgra_nocolormapnofullbrights : palette_bgra_nocolormap);
-               skinframe->pants = R_LoadTexture2D(r_main_texturepool, va("%s_pants", skinframe->basename), width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags, -1, palette_bgra_pantsaswhite);
-               skinframe->shirt = R_LoadTexture2D(r_main_texturepool, va("%s_shirt", skinframe->basename), width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags, -1, palette_bgra_shirtaswhite);
+               skinframe->base  = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_nospecial", skinframe->basename), width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags, -1, skinframe->glow ? palette_bgra_nocolormapnofullbrights : palette_bgra_nocolormap);
+               skinframe->pants = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_pants", skinframe->basename), width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags, -1, palette_bgra_pantsaswhite);
+               skinframe->shirt = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_shirt", skinframe->basename), width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags, -1, palette_bgra_shirtaswhite);
        }
        else
        {
@@ -3689,6 +3692,7 @@ skinframe_t *R_SkinFrame_LoadInternal8bit(const char *name, int textureflags, co
 {
        int i;
        skinframe_t *skinframe;
+       char vabuf[1024];
 
        if (cls.state == ca_dedicated)
                return NULL;
@@ -3730,7 +3734,7 @@ skinframe_t *R_SkinFrame_LoadInternal8bit(const char *name, int textureflags, co
                        }
                }
                if (r_loadfog && skinframe->hasalpha)
-                       skinframe->fog = R_LoadTexture2D(r_main_texturepool, va("%s_fog", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, textureflags, -1, alphapalette);
+                       skinframe->fog = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_fog", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, textureflags, -1, alphapalette);
        }
 
        R_SKINFRAME_LOAD_AVERAGE_COLORS(width * height, ((unsigned char *)palette)[skindata[pix]*4 + comp]);
@@ -3804,7 +3808,7 @@ static suffixinfo_t suffix[3][6] =
 
 static int componentorder[4] = {0, 1, 2, 3};
 
-rtexture_t *R_LoadCubemap(const char *basename)
+static rtexture_t *R_LoadCubemap(const char *basename)
 {
        int i, j, cubemapsize;
        unsigned char *cubemappixels, *image_buffer;
@@ -3886,44 +3890,7 @@ rtexture_t *R_GetCubemap(const char *basename)
        return r_texture_cubemaps[i]->texture;
 }
 
-void R_FreeCubemap(const char *basename)
-{
-       int i;
-
-       for (i = 0;i < r_texture_numcubemaps;i++)
-       {
-               if (r_texture_cubemaps[i] != NULL)
-               {
-                       if (r_texture_cubemaps[i]->texture)
-                       {
-                               if (developer_loading.integer)
-                                       Con_DPrintf("unloading cubemap \"%s\"\n", r_texture_cubemaps[i]->basename);
-                               R_FreeTexture(r_texture_cubemaps[i]->texture);
-                               Mem_Free(r_texture_cubemaps[i]);
-                               r_texture_cubemaps[i] = NULL;
-                       }
-               }
-       }
-}
-
-void R_FreeCubemaps(void)
-{
-       int i;
-       for (i = 0;i < r_texture_numcubemaps;i++)
-       {
-               if (developer_loading.integer)
-                       Con_DPrintf("unloading cubemap \"%s\"\n", r_texture_cubemaps[i]->basename);
-               if (r_texture_cubemaps[i] != NULL)
-               {
-                       if (r_texture_cubemaps[i]->texture)
-                               R_FreeTexture(r_texture_cubemaps[i]->texture);
-                       Mem_Free(r_texture_cubemaps[i]);
-               }
-       }
-       r_texture_numcubemaps = 0;
-}
-
-void R_Main_FreeViewCache(void)
+static void R_Main_FreeViewCache(void)
 {
        if (r_refdef.viewcache.entityvisible)
                Mem_Free(r_refdef.viewcache.entityvisible);
@@ -3936,7 +3903,7 @@ void R_Main_FreeViewCache(void)
        memset(&r_refdef.viewcache, 0, sizeof(r_refdef.viewcache));
 }
 
-void R_Main_ResizeViewCache(void)
+static void R_Main_ResizeViewCache(void)
 {
        int numentities = r_refdef.scene.numentities;
        int numclusters = r_refdef.scene.worldmodel ? r_refdef.scene.worldmodel->brush.num_pvsclusters : 1;
@@ -3975,7 +3942,7 @@ void R_Main_ResizeViewCache(void)
 }
 
 extern rtexture_t *loadingscreentexture;
-void gl_main_start(void)
+static void gl_main_start(void)
 {
        loadingscreentexture = NULL;
        r_texture_blanknormalmap = NULL;
@@ -4075,7 +4042,7 @@ void gl_main_start(void)
        r_refdef.fogmasktable_density = 0;
 }
 
-void gl_main_shutdown(void)
+static void gl_main_shutdown(void)
 {
        R_AnimCache_Free();
        R_FrameData_Reset();
@@ -4149,8 +4116,7 @@ void gl_main_shutdown(void)
        hlslshaderstring = NULL;
 }
 
-extern void CL_ParseEntityLump(char *entitystring);
-void gl_main_newmap(void)
+static void gl_main_newmap(void)
 {
        // FIXME: move this code to client
        char *entities, entname[MAX_QPATH];
@@ -4343,20 +4309,6 @@ void GL_Main_Init(void)
        R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap, NULL, NULL);
 }
 
-extern void R_Textures_Init(void);
-extern void GL_Draw_Init(void);
-extern void GL_Main_Init(void);
-extern void R_Shadow_Init(void);
-extern void R_Sky_Init(void);
-extern void GL_Surf_Init(void);
-extern void R_Particles_Init(void);
-extern void R_Explosion_Init(void);
-extern void gl_backend_init(void);
-extern void Sbar_Init(void);
-extern void R_LightningBeams_Init(void);
-extern void Mod_RenderInit(void);
-extern void Font_Init(void);
-
 void Render_Init(void)
 {
        gl_backend_init();
@@ -4537,7 +4489,7 @@ void R_FrameData_Reset(void)
        }
 }
 
-void R_FrameData_Resize(void)
+static void R_FrameData_Resize(void)
 {
        size_t wantedsize;
        wantedsize = (size_t)(r_framedatasize.value * 1024*1024);
@@ -4651,7 +4603,7 @@ void R_AnimCache_ClearCache(void)
        }
 }
 
-void R_AnimCache_UpdateEntityMeshBuffers(entity_render_t *ent, int numvertices)
+static void R_AnimCache_UpdateEntityMeshBuffers(entity_render_t *ent, int numvertices)
 {
        int i;
 
@@ -4973,7 +4925,7 @@ static void R_View_UpdateEntityVisible (void)
 }
 
 /// only used if skyrendermasked, and normally returns false
-int R_DrawBrushModelsSky (void)
+static int R_DrawBrushModelsSky (void)
 {
        int i, sky;
        entity_render_t *ent;
@@ -5314,7 +5266,7 @@ static void R_View_SetFrustum(const int *scissor)
        //PlaneClassify(&frustum[4]);
 }
 
-void R_View_UpdateWithScissor(const int *myscissor)
+static void R_View_UpdateWithScissor(const int *myscissor)
 {
        R_Main_ResizeViewCache();
        R_View_SetFrustum(myscissor);
@@ -5324,7 +5276,7 @@ void R_View_UpdateWithScissor(const int *myscissor)
        R_AnimCache_CacheVisibleEntities();
 }
 
-void R_View_Update(void)
+static void R_View_Update(void)
 {
        R_Main_ResizeViewCache();
        R_View_SetFrustum(NULL);
@@ -5336,7 +5288,7 @@ void R_View_Update(void)
 
 float viewscalefpsadjusted = 1.0f;
 
-void R_GetScaledViewSize(int width, int height, int *outwidth, int *outheight)
+static void R_GetScaledViewSize(int width, int height, int *outwidth, int *outheight)
 {
        float scale = r_viewscale.value * sqrt(viewscalefpsadjusted);
        scale = bound(0.03125f, scale, 1.0f);
@@ -5745,6 +5697,7 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t
        r_waterstate_waterplane_t *p;
        vec3_t visorigin;
        qboolean usewaterfbo = (r_viewfbo.integer >= 1 || r_water_fbo.integer >= 1) && vid.support.ext_framebuffer_object && vid.samples < 2;
+       char vabuf[1024];
 
        originalview = r_refdef.view;
 
@@ -5778,7 +5731,7 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t
                if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
                {
                        if (!p->texture_refraction)
-                               p->texture_refraction = R_LoadTexture2D(r_main_texturepool, va("waterplane%i_refraction", planeindex), r_fb.water.texturewidth, r_fb.water.textureheight, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
+                               p->texture_refraction = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "waterplane%i_refraction", planeindex), r_fb.water.texturewidth, r_fb.water.textureheight, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
                        if (!p->texture_refraction)
                                goto error;
                        if (usewaterfbo)
@@ -5792,7 +5745,7 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t
                else if (p->materialflags & MATERIALFLAG_CAMERA)
                {
                        if (!p->texture_camera)
-                               p->texture_camera = R_LoadTexture2D(r_main_texturepool, va("waterplane%i_camera", planeindex), r_fb.water.camerawidth, r_fb.water.cameraheight, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_FORCELINEAR, -1, NULL);
+                               p->texture_camera = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "waterplane%i_camera", planeindex), r_fb.water.camerawidth, r_fb.water.cameraheight, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_FORCELINEAR, -1, NULL);
                        if (!p->texture_camera)
                                goto error;
                        if (usewaterfbo)
@@ -5807,7 +5760,7 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t
                if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION))
                {
                        if (!p->texture_reflection)
-                               p->texture_reflection = R_LoadTexture2D(r_main_texturepool, va("waterplane%i_reflection", planeindex), r_fb.water.texturewidth, r_fb.water.textureheight, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
+                               p->texture_reflection = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "waterplane%i_reflection", planeindex), r_fb.water.texturewidth, r_fb.water.textureheight, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
                        if (!p->texture_reflection)
                                goto error;
                        if (usewaterfbo)
@@ -6006,7 +5959,7 @@ finish:
        }
 }
 
-void R_Bloom_StartFrame(void)
+static void R_Bloom_StartFrame(void)
 {
        int i;
        int bloomtexturewidth, bloomtextureheight, screentexturewidth, screentextureheight;
@@ -6248,7 +6201,7 @@ void R_Bloom_StartFrame(void)
                r_refdef.view.clear = true;
 }
 
-void R_Bloom_MakeTexture(void)
+static void R_Bloom_MakeTexture(void)
 {
        int x, range, dir;
        float xoffset, yoffset, r, brighten;
@@ -6811,7 +6764,7 @@ r_refdef_scene_t * R_GetScenePointer( r_refdef_scene_type_t scenetype )
        }
 }
 
-int R_SortEntities_Compare(const void *ap, const void *bp)
+static int R_SortEntities_Compare(const void *ap, const void *bp)
 {
        const entity_render_t *a = *(const entity_render_t **)ap;
        const entity_render_t *b = *(const entity_render_t **)bp;
@@ -6833,7 +6786,7 @@ int R_SortEntities_Compare(const void *ap, const void *bp)
        // everything we compared is equal
        return 0;
 }
-void R_SortEntities(void)
+static void R_SortEntities(void)
 {
        // below or equal 2 ents, sorting never gains anything
        if(r_refdef.scene.numentities <= 2)
@@ -6848,7 +6801,6 @@ R_RenderView
 ================
 */
 int dpsoftrast_test;
-extern void R_Shadow_UpdateBounceGridTexture(void);
 extern cvar_t r_shadow_bouncegrid;
 void R_RenderView(void)
 {
@@ -6905,7 +6857,7 @@ void R_RenderView(void)
        if (!r_refdef.scene.entities || r_refdef.view.width * r_refdef.view.height == 0 || !r_renderview.integer || cl_videoplaying/* || !r_refdef.scene.worldmodel*/)
        {
                r_refdef.view.matrix = originalmatrix;
-               return; //Host_Error ("R_RenderView: NULL worldmodel");
+               return;
        }
 
        r_refdef.view.colorscale = r_hdr_scenebrightness.value * r_hdr_irisadaptation_value.value;
@@ -6990,9 +6942,6 @@ void R_RenderWaterPlanes(int fbo, rtexture_t *depthtexture, rtexture_t *colortex
        }
 }
 
-extern void R_DrawLightningBeams (void);
-extern void VM_CL_AddPolygonsToMeshQueue (void);
-extern void R_DrawPortals (void);
 extern cvar_t cl_locs_show;
 static void R_DrawLocs(void);
 static void R_DrawEntityBBoxes(void);
@@ -7163,7 +7112,8 @@ void R_RenderScene(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture)
                        R_TimeReport("lightning");
        }
 
-       VM_CL_AddPolygonsToMeshQueue();
+       if (cl.csqc_loaded)
+               VM_CL_AddPolygonsToMeshQueue(CLVM_prog);
 
        if (r_refdef.view.showdebug)
        {
@@ -7249,7 +7199,7 @@ static const unsigned short bboxelements[36] =
        1, 0, 2, 1, 2, 3,
 };
 
-void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca)
+static void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca)
 {
        int i;
        float *v, *c, f1, f2, vertex3f[8*3], color4f[8*4];
@@ -7290,10 +7240,10 @@ void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, floa
 
 static void R_DrawEntityBBoxes_Callback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i;
        float color[4];
        prvm_edict_t *edict;
-       prvm_prog_t *prog_save = prog;
 
        // this function draws bounding boxes of server entities
        if (!sv.active)
@@ -7302,8 +7252,6 @@ static void R_DrawEntityBBoxes_Callback(const entity_render_t *ent, const rtligh
        GL_CullFace(GL_NONE);
        R_SetupShader_Generic_NoTexture(false, false);
 
-       prog = 0;
-       SV_VM_Begin();
        for (i = 0;i < numsurfaces;i++)
        {
                edict = PRVM_EDICT_NUM(surfacelist[i]);
@@ -7322,8 +7270,6 @@ static void R_DrawEntityBBoxes_Callback(const entity_render_t *ent, const rtligh
                GL_CullFace(r_refdef.view.cullface_front);
                R_DrawBBoxMesh(edict->priv.server->areamins, edict->priv.server->areamaxs, color[0], color[1], color[2], color[3]);
        }
-       SV_VM_End();
-       prog = prog_save;
 }
 
 static void R_DrawEntityBBoxes(void)
@@ -7331,14 +7277,12 @@ static void R_DrawEntityBBoxes(void)
        int i;
        prvm_edict_t *edict;
        vec3_t center;
-       prvm_prog_t *prog_save = prog;
+       prvm_prog_t *prog = SVVM_prog;
 
        // this function draws bounding boxes of server entities
        if (!sv.active)
                return;
 
-       prog = 0;
-       SV_VM_Begin();
        for (i = 0;i < prog->num_edicts;i++)
        {
                edict = PRVM_EDICT_NUM(i);
@@ -7352,8 +7296,6 @@ static void R_DrawEntityBBoxes(void)
                VectorLerp(edict->priv.server->areamins, 0.5f, edict->priv.server->areamaxs, center);
                R_MeshQueue_AddTransparent(center, R_DrawEntityBBoxes_Callback, (entity_render_t *)NULL, i, (rtlight_t *)NULL);
        }
-       SV_VM_End();
-       prog = prog_save;
 }
 
 static const int nomodelelement3i[24] =
@@ -7400,7 +7342,7 @@ static const float nomodelcolor4f[6*4] =
        0.5f, 0.0f, 0.0f, 1.0f
 };
 
-void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
+static void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
 {
        int i;
        float f1, f2, *c;
@@ -7511,7 +7453,7 @@ void R_CalcSprite_Vertex3f(float *vertex3f, const vec3_t origin, const vec3_t le
        vertex3f[11] = origin[2] + left[2] * scalex1 + up[2] * scaley1;
 }
 
-int R_Mesh_AddVertex(rmesh_t *mesh, float x, float y, float z)
+static int R_Mesh_AddVertex(rmesh_t *mesh, float x, float y, float z)
 {
        int i;
        float *vertex3f;
@@ -7554,7 +7496,7 @@ void R_Mesh_AddPolygon3f(rmesh_t *mesh, int numvertices, float *vertex3f)
        }
 }
 
-void R_Mesh_AddPolygon3d(rmesh_t *mesh, int numvertices, double *vertex3d)
+static void R_Mesh_AddPolygon3d(rmesh_t *mesh, int numvertices, double *vertex3d)
 {
        int i;
        int *e, element[3];
@@ -7673,7 +7615,7 @@ static float R_EvaluateQ3WaveFunc(q3wavefunc_t func, const float *parms)
        return (float) f;
 }
 
-void R_tcMod_ApplyToMatrix(matrix4x4_t *texmatrix, q3shaderinfo_layer_tcmod_t *tcmod, int currentmaterialflags)
+static void R_tcMod_ApplyToMatrix(matrix4x4_t *texmatrix, q3shaderinfo_layer_tcmod_t *tcmod, int currentmaterialflags)
 {
        int w, h, idx;
        double f;
@@ -7737,7 +7679,7 @@ void R_tcMod_ApplyToMatrix(matrix4x4_t *texmatrix, q3shaderinfo_layer_tcmod_t *t
        Matrix4x4_Concat(texmatrix, &matrix, &temp);
 }
 
-void R_LoadQWSkin(r_qwskincache_t *cache, const char *skinname)
+static void R_LoadQWSkin(r_qwskincache_t *cache, const char *skinname)
 {
        int textureflags = (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_PICMIP;
        char name[MAX_QPATH];
@@ -8526,7 +8468,7 @@ float RSurf_FogVertex(const float *v)
        return r_refdef.fogmasktable[min(fogmasktableindex, FOGMASKTABLEWIDTH - 1)];
 }
 
-void RSurf_RenumberElements(const int *inelement3i, int *outelement3i, int numelements, int adjust)
+static void RSurf_RenumberElements(const int *inelement3i, int *outelement3i, int numelements, int adjust)
 {
        int i;
        for (i = 0;i < numelements;i++)
@@ -10528,7 +10470,7 @@ static void R_ProcessWorldTextureSurfaceList(int texturenumsurfaces, const msurf
        CHECKGLERROR
 }
 
-void R_QueueWorldSurfaceList(int numsurfaces, const msurface_t **surfacelist, int flagsmask, qboolean writedepth, qboolean depthonly, qboolean prepass)
+static void R_QueueWorldSurfaceList(int numsurfaces, const msurface_t **surfacelist, int flagsmask, qboolean writedepth, qboolean depthonly, qboolean prepass)
 {
        int i, j;
        texture_t *texture;
@@ -10606,7 +10548,7 @@ static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurf
        CHECKGLERROR
 }
 
-void R_QueueModelSurfaceList(entity_render_t *ent, int numsurfaces, const msurface_t **surfacelist, int flagsmask, qboolean writedepth, qboolean depthonly, qboolean prepass)
+static void R_QueueModelSurfaceList(entity_render_t *ent, int numsurfaces, const msurface_t **surfacelist, int flagsmask, qboolean writedepth, qboolean depthonly, qboolean prepass)
 {
        int i, j;
        texture_t *texture;
@@ -10672,7 +10614,7 @@ unsigned short locboxelements[6*2*3] =
        20,21,22, 20,22,23
 };
 
-void R_DrawLoc_Callback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
+static void R_DrawLoc_Callback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
 {
        int i, j;
        cl_locnode_t *loc = (cl_locnode_t *)ent;
@@ -11380,7 +11322,7 @@ static void R_DrawModelDecals(void)
 }
 
 extern cvar_t mod_collision_bih;
-void R_DrawDebugModel(void)
+static void R_DrawDebugModel(void)
 {
        entity_render_t *ent = rsurface.entity;
        int i, j, k, l, flagsmask;
@@ -11595,7 +11537,6 @@ void R_DrawDebugModel(void)
 #endif
 }
 
-extern void R_BuildLightMap(const entity_render_t *ent, msurface_t *surface);
 int r_maxsurfacelist = 0;
 const msurface_t **r_surfacelist = NULL;
 void R_DrawWorldSurfaces(qboolean skysurfaces, qboolean writedepth, qboolean depthonly, qboolean debug, qboolean prepass)
index 0331e2be08d6fec75a0dc1925950e52cfec33afc..8e1c0bce26bccd9830ebc397e02e806c69c6811d 100644 (file)
@@ -167,7 +167,7 @@ void R_BuildLightMap (const entity_render_t *ent, msurface_t *surface)
        }
 }
 
-void R_StainNode (mnode_t *node, dp_model_t *model, const vec3_t origin, float radius, const float fcolor[8])
+static void R_StainNode (mnode_t *node, dp_model_t *model, const vec3_t origin, float radius, const float fcolor[8])
 {
        float ndist, a, ratio, maxdist, maxdist2, maxdist3, invradius, sdtable[256], td, dist2;
        msurface_t *surface, *endsurface;
@@ -582,7 +582,6 @@ void R_Q1BSP_DrawSky(entity_render_t *ent)
                R_DrawModelSurfaces(ent, true, true, false, false, false);
 }
 
-extern void R_Water_AddWaterPlane(msurface_t *surface, int entno);
 void R_Q1BSP_DrawAddWaterPlanes(entity_render_t *ent)
 {
        int i, j, n, flagsmask;
@@ -1185,7 +1184,7 @@ static void R_Q1BSP_CallRecursiveGetLightInfo(r_q1bsp_getlightinfo_t *info, qboo
 
 static msurface_t *r_q1bsp_getlightinfo_surfaces;
 
-int R_Q1BSP_GetLightInfo_comparefunc(const void *ap, const void *bp)
+static int R_Q1BSP_GetLightInfo_comparefunc(const void *ap, const void *bp)
 {
        int a = *(int*)ap;
        int b = *(int*)bp;
@@ -1538,7 +1537,7 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surface
 }
 
 //Made by [515]
-void R_ReplaceWorldTexture (void)
+static void R_ReplaceWorldTexture (void)
 {
        dp_model_t              *m;
        texture_t       *t;
@@ -1588,7 +1587,7 @@ void R_ReplaceWorldTexture (void)
 }
 
 //Made by [515]
-void R_ListWorldTextures (void)
+static void R_ListWorldTextures (void)
 {
        dp_model_t              *m;
        texture_t       *t;
index 2fbc559974ea2245026c178c1fd2b013cfea57af..f1b6e09547ebe3442b534abc503b3b11f8d78626 100644 (file)
@@ -1012,7 +1012,7 @@ void R_Textures_Frame (void)
        }
 }
 
-void R_MakeResizeBufferBigger(int size)
+static void R_MakeResizeBufferBigger(int size)
 {
        if (resizebuffersize < size)
        {
diff --git a/host.c b/host.c
index cedb41b4a34c5a4b845f336153f4b06e06dc72df..88eed4bde5161cff7c3be4c527c15d4ad895397a 100644 (file)
--- a/host.c
+++ b/host.c
@@ -30,6 +30,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "sv_demo.h"
 #include "snd_main.h"
 #include "thread.h"
+#include "utf8lib.h"
 
 /*
 
@@ -48,14 +49,15 @@ int host_framecount = 0;
 // LordHavoc: set when quit is executed
 qboolean host_shuttingdown = false;
 
-// the real time since application started, without any slowmo or clamping
+// the accumulated mainloop time since application started (with filtering), without any slowmo or clamping
 double realtime;
+// the main loop wall time for this frame
+double host_dirtytime;
 
 // current client
 client_t *host_client;
 
 jmp_buf host_abortframe;
-double host_starttime = 0;
 
 // pretend frames take this amount of time (in seconds), 0 = realtime
 cvar_t host_framerate = {0, "host_framerate","0", "locks frame timing to this value in seconds, 0.05 is 20fps for example, note that this can easily run too fast, use cl_maxfps if you want to limit your framerate instead, or sys_ticrate to limit server speed"};
@@ -104,8 +106,8 @@ This shuts down both the client and server
 */
 void Host_Error (const char *error, ...)
 {
-       static char hosterrorstring1[MAX_INPUTLINE];
-       static char hosterrorstring2[MAX_INPUTLINE];
+       static char hosterrorstring1[MAX_INPUTLINE]; // THREAD UNSAFE
+       static char hosterrorstring2[MAX_INPUTLINE]; // THREAD UNSAFE
        static qboolean hosterror = false;
        va_list argptr;
 
@@ -137,10 +139,17 @@ void Host_Error (const char *error, ...)
        //PR_Crash();
 
        // print out where the crash happened, if it was caused by QC (and do a cleanup)
-       PRVM_Crash();
+       PRVM_Crash(SVVM_prog);
+       PRVM_Crash(CLVM_prog);
+       PRVM_Crash(MVM_prog);
 
+       cl.csqc_loaded = false;
+       Cvar_SetValueQuick(&csqc_progcrc, -1);
+       Cvar_SetValueQuick(&csqc_progsize, -1);
 
+       SV_LockThreadMutex();
        Host_ShutdownServer ();
+       SV_UnlockThreadMutex();
 
        if (cls.state == ca_dedicated)
                Sys_Error ("Host_Error: %s",hosterrorstring2);  // dedicated servers exit
@@ -153,7 +162,7 @@ void Host_Error (const char *error, ...)
        Host_AbortCurrentFrame();
 }
 
-void Host_ServerOptions (void)
+static void Host_ServerOptions (void)
 {
        int i;
 
@@ -253,7 +262,7 @@ Host_SaveConfig_f
 Writes key bindings and archived cvars to config.cfg
 ===============
 */
-void Host_SaveConfig_to(const char *file)
+static void Host_SaveConfig_to(const char *file)
 {
        qfile_t *f;
 
@@ -291,7 +300,7 @@ void Host_SaveConfig_f(void)
        Host_SaveConfig_to(file);
 }
 
-void Host_AddConfigText(void)
+static void Host_AddConfigText(void)
 {
        // set up the default startmap_sp and startmap_dm aliases (mods can
        // override these) and then execute the quake.rc startup script
@@ -436,6 +445,7 @@ if (crash = true), don't bother sending signofs
 */
 void SV_DropClient(qboolean crash)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i;
        Con_Printf("Client \"%s\" dropped\n", host_client->name);
 
@@ -471,8 +481,9 @@ void SV_DropClient(qboolean crash)
                // this will set the body to a dead frame, among other things
                int saveSelf = PRVM_serverglobaledict(self);
                host_client->clientconnectcalled = false;
+               PRVM_serverglobalfloat(time) = sv.time;
                PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict);
-               PRVM_ExecuteProgram(PRVM_serverfunction(ClientDisconnect), "QC function ClientDisconnect is missing");
+               prog->ExecuteProgram(prog, PRVM_serverfunction(ClientDisconnect), "QC function ClientDisconnect is missing");
                PRVM_serverglobaledict(self) = saveSelf;
        }
 
@@ -522,7 +533,7 @@ void SV_DropClient(qboolean crash)
        if (sv.active)
        {
                // clear a fields that matter to DP_SV_CLIENTNAME and DP_SV_CLIENTCOLORS, and also frags
-               PRVM_ED_ClearEdict(host_client->edict);
+               PRVM_ED_ClearEdict(prog, host_client->edict);
        }
 
        // clear the client struct (this sets active to false)
@@ -554,6 +565,7 @@ This only happens at the end of a game, not between levels
 */
 void Host_ShutdownServer(void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i;
 
        Con_DPrintf("Host_ShutdownServer\n");
@@ -565,19 +577,20 @@ void Host_ShutdownServer(void)
        NetConn_Heartbeat(2);
 
 // make sure all the clients know we're disconnecting
-       SV_VM_Begin();
        World_End(&sv.world);
        if(prog->loaded)
+       {
                if(PRVM_serverfunction(SV_Shutdown))
                {
                        func_t s = PRVM_serverfunction(SV_Shutdown);
+                       PRVM_serverglobalfloat(time) = sv.time;
                        PRVM_serverfunction(SV_Shutdown) = 0; // prevent it from getting called again
-                       PRVM_ExecuteProgram(s,"SV_Shutdown() required");
+                       prog->ExecuteProgram(prog, s,"SV_Shutdown() required");
                }
+       }
        for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
                if (host_client->active)
                        SV_DropClient(false); // server shutdown
-       SV_VM_End();
 
        NetConn_CloseServerPorts();
 
@@ -587,6 +600,8 @@ void Host_ShutdownServer(void)
 //
        memset(&sv, 0, sizeof(sv));
        memset(svs.clients, 0, svs.maxclients*sizeof(client_t));
+
+       cl.islocalgame = false;
 }
 
 
@@ -599,7 +614,7 @@ Host_GetConsoleCommands
 Add them exactly as if they had been typed at the console
 ===================
 */
-void Host_GetConsoleCommands (void)
+static void Host_GetConsoleCommands (void)
 {
        char *cmd;
 
@@ -619,21 +634,34 @@ Host_TimeReport
 Returns a time report string, for example for
 ==================
 */
-const char *Host_TimingReport(void)
+const char *Host_TimingReport(char *buf, size_t buflen)
 {
-       return va("%.1f%% CPU, %.2f%% lost, offset avg %.1fms, max %.1fms, sdev %.1fms", svs.perf_cpuload * 100, svs.perf_lost * 100, svs.perf_offset_avg * 1000, svs.perf_offset_max * 1000, svs.perf_offset_sdev * 1000);
+       return va(buf, buflen, "%.1f%% CPU, %.2f%% lost, offset avg %.1fms, max %.1fms, sdev %.1fms", svs.perf_cpuload * 100, svs.perf_lost * 100, svs.perf_offset_avg * 1000, svs.perf_offset_max * 1000, svs.perf_offset_sdev * 1000);
 }
 
-void Host_Mingled(void)
+/*
+==================
+Host_Frame
+
+Runs all active servers
+==================
+*/
+static void Host_Init(void);
+void Host_Main(void)
 {
        double time1 = 0;
        double time2 = 0;
        double time3 = 0;
        double cl_timer = 0, sv_timer = 0;
-       double clframetime, deltarealtime, oldrealtime;
+       double clframetime, deltacleantime, olddirtytime, dirtytime;
        double wait;
        int pass1, pass2, pass3, i;
+       char vabuf[1024];
 
+       Host_Init();
+
+       realtime = 0;
+       dirtytime = Sys_DirtyTime();
        for (;;)
        {
                if (setjmp(host_abortframe))
@@ -642,39 +670,56 @@ void Host_Mingled(void)
                        continue;                       // something bad happened, or the server disconnected
                }
 
-               oldrealtime = realtime;
-               realtime = Sys_DoubleTime();
-
-               deltarealtime = realtime - oldrealtime;
-               cl_timer += deltarealtime;
-               sv_timer += deltarealtime;
-
-               svs.perf_acc_realtime += deltarealtime;
-
-               // Look for clients who have spawned
-               for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
-                       if(host_client->spawned)
-                               if(host_client->netconnection)
-                                       break;
-               if(i == svs.maxclients)
+               olddirtytime = host_dirtytime;
+               dirtytime = Sys_DirtyTime();
+               deltacleantime = dirtytime - olddirtytime;
+               if (deltacleantime < 0)
+               {
+                       // warn if it's significant
+                       if (deltacleantime < -0.01)
+                               Con_Printf("Host_Mingled: time stepped backwards (went from %f to %f, difference %f)\n", olddirtytime, dirtytime, deltacleantime);
+                       deltacleantime = 0;
+               }
+               else if (deltacleantime >= 1800)
                {
-                       // Nobody is looking? Then we won't do timing...
-                       // Instead, reset it to zero
-                       svs.perf_acc_realtime = svs.perf_acc_sleeptime = svs.perf_acc_lost = svs.perf_acc_offset = svs.perf_acc_offset_squared = svs.perf_acc_offset_max = svs.perf_acc_offset_samples = 0;
+                       Con_Printf("Host_Mingled: time stepped forward (went from %f to %f, difference %f)\n", olddirtytime, dirtytime, deltacleantime);
+                       deltacleantime = 0;
                }
-               else if(svs.perf_acc_realtime > 5)
+               realtime += deltacleantime;
+               host_dirtytime = dirtytime;
+
+               cl_timer += deltacleantime;
+               sv_timer += deltacleantime;
+
+               if (!svs.threaded)
                {
-                       svs.perf_cpuload = 1 - svs.perf_acc_sleeptime / svs.perf_acc_realtime;
-                       svs.perf_lost = svs.perf_acc_lost / svs.perf_acc_realtime;
-                       if(svs.perf_acc_offset_samples > 0)
+                       svs.perf_acc_realtime += deltacleantime;
+
+                       // Look for clients who have spawned
+                       for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
+                               if(host_client->spawned)
+                                       if(host_client->netconnection)
+                                               break;
+                       if(i == svs.maxclients)
+                       {
+                               // Nobody is looking? Then we won't do timing...
+                               // Instead, reset it to zero
+                               svs.perf_acc_realtime = svs.perf_acc_sleeptime = svs.perf_acc_lost = svs.perf_acc_offset = svs.perf_acc_offset_squared = svs.perf_acc_offset_max = svs.perf_acc_offset_samples = 0;
+                       }
+                       else if(svs.perf_acc_realtime > 5)
                        {
-                               svs.perf_offset_max = svs.perf_acc_offset_max;
-                               svs.perf_offset_avg = svs.perf_acc_offset / svs.perf_acc_offset_samples;
-                               svs.perf_offset_sdev = sqrt(svs.perf_acc_offset_squared / svs.perf_acc_offset_samples - svs.perf_offset_avg * svs.perf_offset_avg);
+                               svs.perf_cpuload = 1 - svs.perf_acc_sleeptime / svs.perf_acc_realtime;
+                               svs.perf_lost = svs.perf_acc_lost / svs.perf_acc_realtime;
+                               if(svs.perf_acc_offset_samples > 0)
+                               {
+                                       svs.perf_offset_max = svs.perf_acc_offset_max;
+                                       svs.perf_offset_avg = svs.perf_acc_offset / svs.perf_acc_offset_samples;
+                                       svs.perf_offset_sdev = sqrt(svs.perf_acc_offset_squared / svs.perf_acc_offset_samples - svs.perf_offset_avg * svs.perf_offset_avg);
+                               }
+                               if(svs.perf_lost > 0 && developer_extra.integer)
+                                       Con_DPrintf("Server can't keep up: %s\n", Host_TimingReport(vabuf, sizeof(vabuf)));
+                               svs.perf_acc_realtime = svs.perf_acc_sleeptime = svs.perf_acc_lost = svs.perf_acc_offset = svs.perf_acc_offset_squared = svs.perf_acc_offset_max = svs.perf_acc_offset_samples = 0;
                        }
-                       if(svs.perf_lost > 0 && developer_extra.integer)
-                               Con_DPrintf("Server can't keep up: %s\n", Host_TimingReport());
-                       svs.perf_acc_realtime = svs.perf_acc_sleeptime = svs.perf_acc_lost = svs.perf_acc_offset = svs.perf_acc_offset_squared = svs.perf_acc_offset_max = svs.perf_acc_offset_samples = 0;
                }
 
                if (slowmo.value < 0.00001 && slowmo.value != 0)
@@ -686,8 +731,6 @@ void Host_Mingled(void)
                if(!*sv_random_seed.string && !cls.demoplayback)
                        rand();
 
-               cl.islocalgame = NetConn_IsLocalGame();
-
                // get new key events
                Key_EventQueue_Unblock();
                SndSys_SendKeyEvents();
@@ -699,7 +742,7 @@ void Host_Mingled(void)
 
                // receive packets on each main loop iteration, as the main loop may
                // be undersleeping due to select() detecting a new packet
-               if (sv.active)
+               if (sv.active && !svs.threaded)
                        NetConn_ServerFrame();
 
                Curl_Run();
@@ -724,14 +767,14 @@ void Host_Mingled(void)
                // if the accumulators haven't become positive yet, wait a while
                if (cls.state == ca_dedicated)
                        wait = sv_timer * -1000000.0;
-               else if (!sv.active)
+               else if (!sv.active || svs.threaded)
                        wait = cl_timer * -1000000.0;
                else
                        wait = max(cl_timer, sv_timer) * -1000000.0;
 
                if (!cls.timedemo && wait >= 1)
                {
-                       double time0;
+                       double time0, delta;
 
                        if(host_maxwait.value <= 0)
                                wait = min(wait, 1000000.0);
@@ -740,12 +783,15 @@ void Host_Mingled(void)
                        if(wait < 1)
                                wait = 1; // because we cast to int
 
-                       time0 = Sys_DoubleTime();
-                       if (sv_checkforpacketsduringsleep.integer && !sys_usenoclockbutbenchmark.integer)
+                       time0 = Sys_DirtyTime();
+                       if (sv_checkforpacketsduringsleep.integer && !sys_usenoclockbutbenchmark.integer && !svs.threaded)
                                NetConn_SleepMicroseconds((int)wait);
                        else
                                Sys_Sleep((int)wait);
-                       svs.perf_acc_sleeptime += Sys_DoubleTime() - time0;
+                       delta = Sys_DirtyTime() - time0;
+                       if (delta < 0 || delta >= 1800) delta = 0;
+                       if (!svs.threaded)
+                               svs.perf_acc_sleeptime += delta;
 //                     R_TimeReport("sleep");
                        continue;
                }
@@ -753,6 +799,12 @@ void Host_Mingled(void)
                // limit the frametime steps to no more than 100ms each
                if (cl_timer > 0.1)
                        cl_timer = 0.1;
+               if (sv_timer > 0.1)
+               {
+                       if (!svs.threaded)
+                               svs.perf_acc_lost += (sv_timer - 0.1);
+                       sv_timer = 0.1;
+               }
 
                R_TimeReport("---");
 
@@ -763,13 +815,7 @@ void Host_Mingled(void)
        //-------------------
 
                // limit the frametime steps to no more than 100ms each
-               if (sv_timer > 0.1)
-               {
-                       svs.perf_acc_lost += (sv_timer - 0.1);
-                       sv_timer = 0.1;
-               }
-
-               if (sv.active && sv_timer > 0)
+               if (sv.active && sv_timer > 0 && !svs.threaded)
                {
                        // execute one or more server frames, with an upper limit on how much
                        // execution time to spend on server frames to avoid freezing the game if
@@ -778,9 +824,7 @@ void Host_Mingled(void)
                        int framecount, framelimit = 1;
                        double advancetime, aborttime = 0;
                        float offset;
-
-                       if (cls.state == ca_dedicated)
-                               Collision_Cache_NewFrame();
+                       prvm_prog_t *prog = SVVM_prog;
 
                        // run the world state
                        // don't allow simulation to run too fast or too slow or logic glitches can occur
@@ -812,7 +856,8 @@ void Host_Mingled(void)
 
                        if(advancetime > 0)
                        {
-                               offset = sv_timer + (Sys_DoubleTime() - realtime);
+                               offset = Sys_DirtyTime() - realtime;if (offset < 0 || offset >= 1800) offset = 0;
+                               offset += sv_timer;
                                ++svs.perf_acc_offset_samples;
                                svs.perf_acc_offset += offset;
                                svs.perf_acc_offset_squared += offset * offset;
@@ -828,9 +873,6 @@ void Host_Mingled(void)
                        if (sv.paused || (cl.islocalgame && (key_dest != key_game || key_consoleactive || cl.csqc_paused)))
                                sv.frametime = 0;
 
-                       // setup the VM frame
-                       SV_VM_Begin();
-
                        for (framecount = 0;framecount < framelimit && sv_timer > 0;framecount++)
                        {
                                sv_timer -= advancetime;
@@ -840,27 +882,25 @@ void Host_Mingled(void)
                                        SV_Physics();
 
                                // if this server frame took too long, break out of the loop
-                               if (framelimit > 1 && Sys_DoubleTime() >= aborttime)
+                               if (framelimit > 1 && Sys_DirtyTime() >= aborttime)
                                        break;
                        }
                        R_TimeReport("serverphysics");
 
                        // send all messages to the clients
                        SV_SendClientMessages();
-                       
+
                        if (sv.paused == 1 && realtime > sv.pausedstart && sv.pausedstart > 0) {
                                prog->globals.generic[OFS_PARM0] = realtime - sv.pausedstart;
-                               PRVM_ExecuteProgram(PRVM_serverfunction(SV_PausedTic), "QC function SV_PausedTic is missing");
+                               PRVM_serverglobalfloat(time) = sv.time;
+                               prog->ExecuteProgram(prog, PRVM_serverfunction(SV_PausedTic), "QC function SV_PausedTic is missing");
                        }
 
-                       // end the server VM frame
-                       SV_VM_End();
-
                        // send an heartbeat if enough time has passed since the last one
                        NetConn_Heartbeat(0);
                        R_TimeReport("servernetwork");
                }
-               else
+               else if (!svs.threaded)
                {
                        // don't let r_speeds display jump around
                        R_TimeReport("serverphysics");
@@ -932,7 +972,7 @@ void Host_Mingled(void)
 
                        // update video
                        if (host_speeds.integer)
-                               time1 = Sys_DoubleTime();
+                               time1 = Sys_DirtyTime();
                        R_TimeReport("pre-input");
 
                        // Collect input into cmd
@@ -963,7 +1003,7 @@ void Host_Mingled(void)
                        R_TimeReport("render");
 
                        if (host_speeds.integer)
-                               time2 = Sys_DoubleTime();
+                               time2 = Sys_DirtyTime();
 
                        // update audio
                        if(cl.csqc_usecsqclistener)
@@ -983,7 +1023,7 @@ void Host_Mingled(void)
                        if (host_speeds.integer)
                        {
                                pass1 = (int)((time1 - time3)*1000000);
-                               time3 = Sys_DoubleTime();
+                               time3 = Sys_DirtyTime();
                                pass2 = (int)((time2 - time1)*1000000);
                                pass3 = (int)((time3 - time2)*1000000);
                                Con_Printf("%6ius total %6ius server %6ius gfx %6ius snd\n",
@@ -1003,7 +1043,8 @@ void Host_Mingled(void)
                        cl_timer = 0;
                if (sv_timer >= 0)
                {
-                       svs.perf_acc_lost += sv_timer;
+                       if (!svs.threaded)
+                               svs.perf_acc_lost += sv_timer;
                        sv_timer = 0;
                }
 
@@ -1011,242 +1052,6 @@ void Host_Mingled(void)
        }
 }
 
-void Host_Threaded(void)
-{
-       double time1 = 0;
-       double time2 = 0;
-       double time3 = 0;
-       double cl_timer = 0;
-       double clframetime, deltarealtime, oldrealtime;
-       double wait;
-       int pass1, pass2, pass3;
-
-       for (;;)
-       {
-               if (setjmp(host_abortframe))
-               {
-                       SCR_ClearLoadingScreen(false);
-                       continue;                       // something bad happened, or the server disconnected
-               }
-
-               oldrealtime = realtime;
-               realtime = Sys_DoubleTime();
-
-               deltarealtime = realtime - oldrealtime;
-               cl_timer += deltarealtime;
-
-               if (slowmo.value < 0.00001 && slowmo.value != 0)
-                       Cvar_SetValue("slowmo", 0);
-               if (host_framerate.value < 0.00001 && host_framerate.value != 0)
-                       Cvar_SetValue("host_framerate", 0);
-
-               // keep the random time dependent, but not when playing demos/benchmarking
-               if(!*sv_random_seed.string && !cls.demoplayback)
-                       rand();
-
-               cl.islocalgame = NetConn_IsLocalGame();
-
-               // get new key events
-               Key_EventQueue_Unblock();
-               SndSys_SendKeyEvents();
-               Sys_SendKeyEvents();
-
-               NetConn_UpdateSockets();
-
-               Log_DestBuffer_Flush();
-
-               Curl_Run();
-
-               // check for commands typed to the host
-               Host_GetConsoleCommands();
-
-               // process console commands
-//             R_TimeReport("preconsole");
-               CL_VM_PreventInformationLeaks();
-               Cbuf_Execute();
-//             R_TimeReport("console");
-
-               //Con_Printf("%6.0f %6.0f\n", cl_timer * 1000000.0, sv_timer * 1000000.0);
-
-               // if the accumulators haven't become positive yet, wait a while
-               wait = cl_timer * -1000000.0;
-
-               if (!cls.timedemo && wait >= 1)
-               {
-                       double time0;
-
-                       if(host_maxwait.value <= 0)
-                               wait = min(wait, 1000000.0);
-                       else
-                               wait = min(wait, host_maxwait.value * 1000.0);
-                       if(wait < 1)
-                               wait = 1; // because we cast to int
-
-                       time0 = Sys_DoubleTime();
-                       Sys_Sleep((int)wait);
-//                     R_TimeReport("sleep");
-                       continue;
-               }
-
-               // limit the frametime steps to no more than 100ms each
-               if (cl_timer > 0.1)
-                       cl_timer = 0.1;
-
-               R_TimeReport("---");
-
-               if (cl_timer > 0 || cls.timedemo || ((vid_activewindow ? cl_maxfps : cl_maxidlefps).value < 1))
-               {
-                       R_TimeReport("---");
-                       Collision_Cache_NewFrame();
-                       R_TimeReport("collisioncache");
-                       // decide the simulation time
-                       if (cls.capturevideo.active)
-                       {
-                               //***
-                               if (cls.capturevideo.realtime)
-                                       clframetime = cl.realframetime = max(cl_timer, 1.0 / cls.capturevideo.framerate);
-                               else
-                               {
-                                       clframetime = 1.0 / cls.capturevideo.framerate;
-                                       cl.realframetime = max(cl_timer, clframetime);
-                               }
-                       }
-                       else if (vid_activewindow && cl_maxfps.value >= 1 && !cls.timedemo)
-                       {
-                               clframetime = cl.realframetime = max(cl_timer, 1.0 / cl_maxfps.value);
-                               // when running slow, we need to sleep to keep input responsive
-                               wait = bound(0, cl_maxfps_alwayssleep.value * 1000, 100000);
-                               if (wait > 0)
-                                       Sys_Sleep((int)wait);
-                       }
-                       else if (!vid_activewindow && cl_maxidlefps.value >= 1 && !cls.timedemo)
-                               clframetime = cl.realframetime = max(cl_timer, 1.0 / cl_maxidlefps.value);
-                       else
-                               clframetime = cl.realframetime = cl_timer;
-
-                       // apply slowmo scaling
-                       clframetime *= cl.movevars_timescale;
-                       // scale playback speed of demos by slowmo cvar
-                       if (cls.demoplayback)
-                       {
-                               clframetime *= slowmo.value;
-                               // if demo playback is paused, don't advance time at all
-                               if (cls.demopaused)
-                                       clframetime = 0;
-                       }
-
-                       // host_framerate overrides all else
-                       if (host_framerate.value)
-                               clframetime = host_framerate.value;
-
-                       if (cl.paused || (cl.islocalgame && (key_dest != key_game || key_consoleactive || cl.csqc_paused)))
-                               clframetime = 0;
-
-                       if (cls.timedemo)
-                               clframetime = cl.realframetime = cl_timer;
-
-                       // deduct the frame time from the accumulator
-                       cl_timer -= cl.realframetime;
-
-                       cl.oldtime = cl.time;
-                       cl.time += clframetime;
-
-                       // update video
-                       if (host_speeds.integer)
-                               time1 = Sys_DoubleTime();
-                       R_TimeReport("pre-input");
-
-                       // Collect input into cmd
-                       CL_Input();
-
-                       R_TimeReport("input");
-
-                       // check for new packets
-                       NetConn_ClientFrame();
-
-                       // read a new frame from a demo if needed
-                       CL_ReadDemoMessage();
-                       R_TimeReport("clientnetwork");
-
-                       // now that packets have been read, send input to server
-                       CL_SendMove();
-                       R_TimeReport("sendmove");
-
-                       // update client world (interpolate entities, create trails, etc)
-                       CL_UpdateWorld();
-                       R_TimeReport("lerpworld");
-
-                       CL_Video_Frame();
-
-                       R_TimeReport("client");
-
-                       CL_UpdateScreen();
-                       R_TimeReport("render");
-
-                       if (host_speeds.integer)
-                               time2 = Sys_DoubleTime();
-
-                       // update audio
-                       if(cl.csqc_usecsqclistener)
-                       {
-                               S_Update(&cl.csqc_listenermatrix);
-                               cl.csqc_usecsqclistener = false;
-                       }
-                       else
-                               S_Update(&r_refdef.view.matrix);
-
-                       CDAudio_Update();
-                       R_TimeReport("audio");
-
-                       // reset gathering of mouse input
-                       in_mouse_x = in_mouse_y = 0;
-
-                       if (host_speeds.integer)
-                       {
-                               pass1 = (int)((time1 - time3)*1000000);
-                               time3 = Sys_DoubleTime();
-                               pass2 = (int)((time2 - time1)*1000000);
-                               pass3 = (int)((time3 - time2)*1000000);
-                               Con_Printf("%6ius total %6ius other %6ius gfx %6ius snd\n",
-                                                       pass1+pass2+pass3, pass1, pass2, pass3);
-                       }
-               }
-
-#if MEMPARANOIA
-               Mem_CheckSentinelsGlobal();
-#else
-               if (developer_memorydebug.integer)
-                       Mem_CheckSentinelsGlobal();
-#endif
-
-               // if there is some time remaining from this frame, reset the timers
-               if (cl_timer >= 0)
-                       cl_timer = 0;
-
-               host_framecount++;
-       }
-}
-
-/*
-==================
-Host_Frame
-
-Runs all active servers
-==================
-*/
-static void Host_Init(void);
-void Host_Main(void)
-{
-       Host_Init();
-
-       realtime = host_starttime = Sys_DoubleTime();
-
-       if (svs.threaded)
-               Host_Threaded();
-       else
-               Host_Mingled();
-}
-
 //============================================================================
 
 qboolean vid_opened = false;
@@ -1266,15 +1071,6 @@ char engineversion[128];
 
 qboolean sys_nostdout = false;
 
-extern void u8_Init(void);
-extern void Render_Init(void);
-extern void Mathlib_Init(void);
-extern void FS_Init_SelfPack(void);
-extern void FS_Init(void);
-extern void FS_Shutdown(void);
-extern void PR_Cmd_Init(void);
-extern void COM_Init_Commands(void);
-extern void FS_Init_Commands(void);
 extern qboolean host_stuffcmdsrun;
 
 /*
@@ -1286,6 +1082,7 @@ static void Host_Init (void)
 {
        int i;
        const char* os;
+       char vabuf[1024];
 
        if (COM_CheckParm("-profilegameonly"))
                Sys_AllowProfiling(false);
@@ -1443,7 +1240,7 @@ static void Host_Init (void)
        if (i && i + 1 < com_argc)
        if (!sv.active && !cls.demoplayback && !cls.connect_trying)
        {
-               Cbuf_AddText(va("timedemo %s\n", com_argv[i + 1]));
+               Cbuf_AddText(va(vabuf, sizeof(vabuf), "timedemo %s\n", com_argv[i + 1]));
                Cbuf_Execute();
        }
 
@@ -1453,7 +1250,7 @@ static void Host_Init (void)
        if (i && i + 1 < com_argc)
        if (!sv.active && !cls.demoplayback && !cls.connect_trying)
        {
-               Cbuf_AddText(va("playdemo %s\n", com_argv[i + 1]));
+               Cbuf_AddText(va(vabuf, sizeof(vabuf), "playdemo %s\n", com_argv[i + 1]));
                Cbuf_Execute();
        }
 
@@ -1462,7 +1259,7 @@ static void Host_Init (void)
        if (i && i + 1 < com_argc)
        if (!sv.active && !cls.demoplayback && !cls.connect_trying)
        {
-               Cbuf_AddText(va("playdemo %s\ncl_capturevideo 1\n", com_argv[i + 1]));
+               Cbuf_AddText(va(vabuf, sizeof(vabuf), "playdemo %s\ncl_capturevideo 1\n", com_argv[i + 1]));
                Cbuf_Execute();
        }
 
@@ -1519,7 +1316,13 @@ void Host_Shutdown(void)
        CL_Disconnect();
 
        // shut down local server if active
+       SV_LockThreadMutex();
        Host_ShutdownServer ();
+       SV_UnlockThreadMutex();
+
+       // end the server thread
+       if (svs.threaded)
+               SV_StopThread();
 
        // Shutdown menu
        if(MR_Shutdown)
index 764787051f97e637c372a9eebee17889e6e07476..0224ec4e362e7ffb933548a4246d043827a1bfbf 100644 (file)
@@ -67,14 +67,16 @@ void Host_Quit_f (void)
 Host_Status_f
 ==================
 */
-void Host_Status_f (void)
+static void Host_Status_f (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        char qcstatus[256];
        client_t *client;
        int seconds = 0, minutes = 0, hours = 0, i, j, k, in, players, ping = 0, packetloss = 0;
        void (*print) (const char *fmt, ...);
        char ip[48]; // can contain a full length v6 address with [] and a port
        int frags;
+       char vabuf[1024];
 
        if (cmd_source == src_command)
        {
@@ -91,10 +93,7 @@ void Host_Status_f (void)
 
        if (!sv.active)
                return;
-       
-       if(cmd_source == src_command)
-               SV_VM_Begin();
-       
+
        in = 0;
        if (Cmd_Argc() == 2)
        {
@@ -111,7 +110,7 @@ void Host_Status_f (void)
        print ("version:  %s build %s\n", gamename, buildstring);
        print ("protocol: %i (%s)\n", Protocol_NumberForEnum(sv.protocol), Protocol_NameForEnum(sv.protocol));
        print ("map:      %s\n", sv.name);
-       print ("timing:   %s\n", Host_TimingReport());
+       print ("timing:   %s\n", Host_TimingReport(vabuf, sizeof(vabuf)));
        print ("players:  %i active (%i max)\n\n", players, svs.maxclients);
 
        if (in == 1)
@@ -159,7 +158,7 @@ void Host_Status_f (void)
                if(sv_status_show_qcstatus.integer)
                {
                        prvm_edict_t *ed = PRVM_EDICT_NUM(i + 1);
-                       const char *str = PRVM_GetString(PRVM_serveredictstring(ed, clientstatus));
+                       const char *str = PRVM_GetString(prog, PRVM_serveredictstring(ed, clientstatus));
                        if(str && *str)
                        {
                                char *p;
@@ -198,9 +197,6 @@ void Host_Status_f (void)
                        print ("%s%-47s #%-3u ^7%s\n", k%2 ? "^3" : "^7", ip, i+1, client->name);
                }
        }
-
-       if(cmd_source == src_command)
-               SV_VM_End();
 }
 
 
@@ -211,8 +207,9 @@ Host_God_f
 Sets client to godmode
 ==================
 */
-void Host_God_f (void)
+static void Host_God_f (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        if (!allowcheats)
        {
                SV_ClientPrint("No cheats allowed, use sv_cheats 1 and restart level to enable.\n");
@@ -226,8 +223,9 @@ void Host_God_f (void)
                SV_ClientPrint("godmode ON\n");
 }
 
-void Host_Notarget_f (void)
+static void Host_Notarget_f (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        if (!allowcheats)
        {
                SV_ClientPrint("No cheats allowed, use sv_cheats 1 and restart level to enable.\n");
@@ -243,8 +241,9 @@ void Host_Notarget_f (void)
 
 qboolean noclip_anglehack;
 
-void Host_Noclip_f (void)
+static void Host_Noclip_f (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        if (!allowcheats)
        {
                SV_ClientPrint("No cheats allowed, use sv_cheats 1 and restart level to enable.\n");
@@ -272,8 +271,9 @@ Host_Fly_f
 Sets client to flymode
 ==================
 */
-void Host_Fly_f (void)
+static void Host_Fly_f (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        if (!allowcheats)
        {
                SV_ClientPrint("No cheats allowed, use sv_cheats 1 and restart level to enable.\n");
@@ -300,7 +300,7 @@ Host_Ping_f
 ==================
 */
 void Host_Pings_f (void); // called by Host_Ping_f
-void Host_Ping_f (void)
+static void Host_Ping_f (void)
 {
        int i;
        client_t *client;
@@ -352,7 +352,7 @@ map <servername>
 command from the console.  Active clients are kicked off.
 ======================
 */
-void Host_Map_f (void)
+static void Host_Map_f (void)
 {
        char level[MAX_QPATH];
 
@@ -399,7 +399,7 @@ Host_Changelevel_f
 Goes to a new map, taking all clients along
 ==================
 */
-void Host_Changelevel_f (void)
+static void Host_Changelevel_f (void)
 {
        char level[MAX_QPATH];
 
@@ -419,9 +419,7 @@ void Host_Changelevel_f (void)
                MR_ToggleMenu(0);
        key_dest = key_game;
 
-       SV_VM_Begin();
        SV_SaveSpawnparms ();
-       SV_VM_End();
        allowcheats = sv_cheats.integer != 0;
        strlcpy(level, Cmd_Argv(1), sizeof(level));
        SV_SpawnServer(level);
@@ -436,7 +434,7 @@ Host_Restart_f
 Restarts the current server for a dead player
 ==================
 */
-void Host_Restart_f (void)
+static void Host_Restart_f (void)
 {
        char mapname[MAX_QPATH];
 
@@ -526,7 +524,7 @@ Host_Connect_f
 User command to connect to server
 =====================
 */
-void Host_Connect_f (void)
+static void Host_Connect_f (void)
 {
        if (Cmd_Argc() < 2)
        {
@@ -550,7 +548,7 @@ LOAD / SAVE GAME
 
 #define        SAVEGAME_VERSION        5
 
-void Host_Savegame_to (const char *name)
+void Host_Savegame_to(prvm_prog_t *prog, const char *name)
 {
        qfile_t *f;
        int             i, k, l, lightstyles = 64;
@@ -565,7 +563,7 @@ void Host_Savegame_to (const char *name)
                if (sv.lightstyles[i][0])
                        lightstyles = i+1;
 
-       isserver = !strcmp(PRVM_NAME, "server");
+       isserver = prog == SVVM_prog;
 
        Con_Printf("Saving game to %s...\n", name);
        f = FS_OpenRealFile(name, "wb", false);
@@ -579,9 +577,9 @@ void Host_Savegame_to (const char *name)
 
        memset(comment, 0, sizeof(comment));
        if(isserver)
-               dpsnprintf(comment, sizeof(comment), "%-21.21s kills:%3i/%3i", PRVM_GetString(PRVM_serveredictstring(prog->edicts, message)), (int)PRVM_serverglobalfloat(killed_monsters), (int)PRVM_serverglobalfloat(total_monsters));
+               dpsnprintf(comment, sizeof(comment), "%-21.21s kills:%3i/%3i", PRVM_GetString(prog, PRVM_serveredictstring(prog->edicts, message)), (int)PRVM_serverglobalfloat(killed_monsters), (int)PRVM_serverglobalfloat(total_monsters));
        else
-               dpsnprintf(comment, sizeof(comment), "(crash dump of %s progs)", PRVM_NAME);
+               dpsnprintf(comment, sizeof(comment), "(crash dump of %s progs)", prog->name);
        // convert space to _ to make stdio happy
        // LordHavoc: convert control characters to _ as well
        for (i=0 ; i<SAVEGAME_COMMENT_LENGTH ; i++)
@@ -616,12 +614,12 @@ void Host_Savegame_to (const char *name)
                        FS_Print(f,"m\n");
        }
 
-       PRVM_ED_WriteGlobals (f);
+       PRVM_ED_WriteGlobals (prog, f);
        for (i=0 ; i<prog->num_edicts ; i++)
        {
                FS_Printf(f,"// edict %d\n", i);
                //Con_Printf("edict %d...\n", i);
-               PRVM_ED_Write (f, PRVM_EDICT_NUM(i));
+               PRVM_ED_Write (prog, f, PRVM_EDICT_NUM(i));
        }
 
 #if 1
@@ -698,8 +696,9 @@ void Host_Savegame_to (const char *name)
 Host_Savegame_f
 ===============
 */
-void Host_Savegame_f (void)
+static void Host_Savegame_f (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        char    name[MAX_QPATH];
        qboolean deadflag = false;
 
@@ -709,9 +708,7 @@ void Host_Savegame_f (void)
                return;
        }
 
-       SV_VM_Begin();
        deadflag = cl.islocalgame && svs.clients[0].active && PRVM_serveredictfloat(svs.clients[0].edict, deadflag);
-       SV_VM_End();
 
        if (cl.islocalgame)
        {
@@ -746,9 +743,7 @@ void Host_Savegame_f (void)
        strlcpy (name, Cmd_Argv(1), sizeof (name));
        FS_DefaultExtension (name, ".sav", sizeof (name));
 
-       SV_VM_Begin();
-       Host_Savegame_to(name);
-       SV_VM_End();
+       Host_Savegame_to(prog, name);
 }
 
 
@@ -758,8 +753,9 @@ Host_Loadgame_f
 ===============
 */
 
-void Host_Loadgame_f (void)
+static void Host_Loadgame_f (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        char filename[MAX_QPATH];
        char mapname[MAX_QPATH];
        float time;
@@ -868,7 +864,6 @@ void Host_Loadgame_f (void)
 
 // load the light styles
 
-       SV_VM_Begin();
        // -1 is the globals
        entnum = -1;
 
@@ -934,7 +929,7 @@ void Host_Loadgame_f (void)
                                Con_Printf("Host_Loadgame_f: loading globals\n");
 
                        // parse the global vars
-                       PRVM_ED_ParseGlobals (start);
+                       PRVM_ED_ParseGlobals (prog, start);
 
                        // restore the autocvar globals
                        Cvar_UpdateAllAutoCvars();
@@ -948,7 +943,7 @@ void Host_Loadgame_f (void)
                                Host_Error("Host_PerformLoadGame: too many edicts in save file (reached MAX_EDICTS %i)", MAX_EDICTS);
                        }
                        while (entnum >= prog->max_edicts)
-                               PRVM_MEM_IncreaseEdicts();
+                               PRVM_MEM_IncreaseEdicts(prog);
                        ent = PRVM_EDICT_NUM(entnum);
                        memset(ent->fields.vp, 0, prog->entityfields * 4);
                        ent->priv.server->free = false;
@@ -956,7 +951,7 @@ void Host_Loadgame_f (void)
                        if(developer_entityparsing.integer)
                                Con_Printf("Host_Loadgame_f: loading edict %d\n", entnum);
 
-                       PRVM_ED_ParseEdict (start, ent);
+                       PRVM_ED_ParseEdict (prog, start, ent);
 
                        // link it into the bsp tree
                        if (!ent->priv.server->free)
@@ -1079,8 +1074,6 @@ void Host_Loadgame_f (void)
        if(developer_entityparsing.integer)
                Con_Printf("Host_Loadgame_f: finished\n");
 
-       SV_VM_End();
-
        // make sure we're connected to loopback
        if (sv.active && cls.state == ca_disconnected)
                CL_EstablishConnection("local:1", -2);
@@ -1094,8 +1087,9 @@ Host_Name_f
 ======================
 */
 cvar_t cl_name = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_name", "player", "internal storage cvar for current player name (changed by name command)"};
-void Host_Name_f (void)
+static void Host_Name_f (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i, j;
        qboolean valid_colors;
        const char *newNameSource;
@@ -1201,7 +1195,7 @@ void Host_Name_f (void)
        if (j >= 0 && strlen(host_client->name) < sizeof(host_client->name) - 2)
                memcpy(host_client->name + strlen(host_client->name), STRING_COLOR_DEFAULT_STR, strlen(STRING_COLOR_DEFAULT_STR) + 1);
 
-       PRVM_serveredictstring(host_client->edict, netname) = PRVM_SetEngineString(host_client->name);
+       PRVM_serveredictstring(host_client->edict, netname) = PRVM_SetEngineString(prog, host_client->name);
        if (strcmp(host_client->old_name, host_client->name))
        {
                if (host_client->spawned)
@@ -1222,8 +1216,9 @@ Host_Playermodel_f
 */
 cvar_t cl_playermodel = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_playermodel", "", "internal storage cvar for current player model in Nexuiz/Xonotic (changed by playermodel command)"};
 // the old cl_playermodel in cl_main has been renamed to __cl_playermodel
-void Host_Playermodel_f (void)
+static void Host_Playermodel_f (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i, j;
        char newPath[sizeof(host_client->playermodel)];
 
@@ -1261,7 +1256,7 @@ void Host_Playermodel_f (void)
 
        // point the string back at updateclient->name to keep it safe
        strlcpy (host_client->playermodel, newPath, sizeof (host_client->playermodel));
-       PRVM_serveredictstring(host_client->edict, playermodel) = PRVM_SetEngineString(host_client->playermodel);
+       PRVM_serveredictstring(host_client->edict, playermodel) = PRVM_SetEngineString(prog, host_client->playermodel);
        if (strcmp(host_client->old_model, host_client->playermodel))
        {
                strlcpy(host_client->old_model, host_client->playermodel, sizeof(host_client->old_model));
@@ -1278,8 +1273,9 @@ Host_Playerskin_f
 ======================
 */
 cvar_t cl_playerskin = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_playerskin", "", "internal storage cvar for current player skin in Nexuiz/Xonotic (changed by playerskin command)"};
-void Host_Playerskin_f (void)
+static void Host_Playerskin_f (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i, j;
        char newPath[sizeof(host_client->playerskin)];
 
@@ -1317,7 +1313,7 @@ void Host_Playerskin_f (void)
 
        // point the string back at updateclient->name to keep it safe
        strlcpy (host_client->playerskin, newPath, sizeof (host_client->playerskin));
-       PRVM_serveredictstring(host_client->edict, playerskin) = PRVM_SetEngineString(host_client->playerskin);
+       PRVM_serveredictstring(host_client->edict, playerskin) = PRVM_SetEngineString(prog, host_client->playerskin);
        if (strcmp(host_client->old_skin, host_client->playerskin))
        {
                //if (host_client->spawned)
@@ -1330,13 +1326,14 @@ void Host_Playerskin_f (void)
        }
 }
 
-void Host_Version_f (void)
+static void Host_Version_f (void)
 {
        Con_Printf("Version: %s build %s\n", gamename, buildstring);
 }
 
-void Host_Say(qboolean teamonly)
+static void Host_Say(qboolean teamonly)
 {
+       prvm_prog_t *prog = SVVM_prog;
        client_t *save;
        int j, quoted;
        const char *p1;
@@ -1403,19 +1400,19 @@ void Host_Say(qboolean teamonly)
 }
 
 
-void Host_Say_f(void)
+static void Host_Say_f(void)
 {
        Host_Say(false);
 }
 
 
-void Host_Say_Team_f(void)
+static void Host_Say_Team_f(void)
 {
        Host_Say(true);
 }
 
 
-void Host_Tell_f(void)
+static void Host_Tell_f(void)
 {
        const char *playername_start = NULL;
        size_t playername_length = 0;
@@ -1550,8 +1547,9 @@ Host_Color_f
 ==================
 */
 cvar_t cl_color = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_color", "0", "internal storage cvar for current player colors (changed by color command)"};
-void Host_Color(int changetop, int changebottom)
+static void Host_Color(int changetop, int changebottom)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int top, bottom, playercolor;
 
        // get top and bottom either from the provided values or the current values
@@ -1581,10 +1579,10 @@ void Host_Color(int changetop, int changebottom)
        if (host_client->edict && PRVM_serverfunction(SV_ChangeTeam))
        {
                Con_DPrint("Calling SV_ChangeTeam\n");
-               PRVM_serverglobalfloat(time) = sv.time;
                prog->globals.generic[OFS_PARM0] = playercolor;
+               PRVM_serverglobalfloat(time) = sv.time;
                PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict);
-               PRVM_ExecuteProgram(PRVM_serverfunction(SV_ChangeTeam), "QC function SV_ChangeTeam is missing");
+               prog->ExecuteProgram(prog, PRVM_serverfunction(SV_ChangeTeam), "QC function SV_ChangeTeam is missing");
        }
        else
        {
@@ -1605,7 +1603,7 @@ void Host_Color(int changetop, int changebottom)
        }
 }
 
-void Host_Color_f(void)
+static void Host_Color_f(void)
 {
        int             top, bottom;
 
@@ -1626,7 +1624,7 @@ void Host_Color_f(void)
        Host_Color(top, bottom);
 }
 
-void Host_TopColor_f(void)
+static void Host_TopColor_f(void)
 {
        if (Cmd_Argc() == 1)
        {
@@ -1638,7 +1636,7 @@ void Host_TopColor_f(void)
        Host_Color(atoi(Cmd_Argv(1)), -1);
 }
 
-void Host_BottomColor_f(void)
+static void Host_BottomColor_f(void)
 {
        if (Cmd_Argc() == 1)
        {
@@ -1651,7 +1649,7 @@ void Host_BottomColor_f(void)
 }
 
 cvar_t cl_rate = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_rate", "20000", "internal storage cvar for current rate (changed by rate command)"};
-void Host_Rate_f(void)
+static void Host_Rate_f(void)
 {
        int rate;
 
@@ -1678,8 +1676,9 @@ void Host_Rate_f(void)
 Host_Kill_f
 ==================
 */
-void Host_Kill_f (void)
+static void Host_Kill_f (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        if (PRVM_serveredictfloat(host_client->edict, health) <= 0)
        {
                SV_ClientPrint("Can't suicide -- already dead!\n");
@@ -1688,7 +1687,7 @@ void Host_Kill_f (void)
 
        PRVM_serverglobalfloat(time) = sv.time;
        PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict);
-       PRVM_ExecuteProgram (PRVM_serverfunction(ClientKill), "QC function ClientKill is missing");
+       prog->ExecuteProgram(prog, PRVM_serverfunction(ClientKill), "QC function ClientKill is missing");
 }
 
 
@@ -1697,7 +1696,7 @@ void Host_Kill_f (void)
 Host_Pause_f
 ==================
 */
-void Host_Pause_f (void)
+static void Host_Pause_f (void)
 {
        if (!pausable.integer)
                SV_ClientPrint("Pause not allowed.\n");
@@ -1721,6 +1720,7 @@ LordHavoc: correction, Mindcrime will be removing pmodel in the future, but it's
 cvar_t cl_pmodel = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_pmodel", "0", "internal storage cvar for current player model number in nehahra (changed by pmodel command)"};
 static void Host_PModel_f (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i;
 
        if (Cmd_Argc () == 1)
@@ -1751,7 +1751,7 @@ static void Host_PModel_f (void)
 Host_PreSpawn_f
 ==================
 */
-void Host_PreSpawn_f (void)
+static void Host_PreSpawn_f (void)
 {
        if (host_client->spawned)
        {
@@ -1776,8 +1776,9 @@ void Host_PreSpawn_f (void)
 Host_Spawn_f
 ==================
 */
-void Host_Spawn_f (void)
+static void Host_Spawn_f (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i;
        client_t *client;
        int stats[MAX_CL_STATS];
@@ -1806,7 +1807,7 @@ void Host_Spawn_f (void)
                        Con_DPrint("Calling RestoreGame\n");
                        PRVM_serverglobalfloat(time) = sv.time;
                        PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict);
-                       PRVM_ExecuteProgram(PRVM_serverfunction(RestoreGame), "QC function RestoreGame is missing");
+                       prog->ExecuteProgram(prog, PRVM_serverfunction(RestoreGame), "QC function RestoreGame is missing");
                }
        }
        else
@@ -1821,12 +1822,13 @@ void Host_Spawn_f (void)
                host_client->clientconnectcalled = true;
                PRVM_serverglobalfloat(time) = sv.time;
                PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict);
-               PRVM_ExecuteProgram (PRVM_serverfunction(ClientConnect), "QC function ClientConnect is missing");
+               prog->ExecuteProgram(prog, PRVM_serverfunction(ClientConnect), "QC function ClientConnect is missing");
 
                if (cls.state == ca_dedicated)
                        Con_Printf("%s connected\n", host_client->name);
 
-               PRVM_ExecuteProgram (PRVM_serverfunction(PutClientInServer), "QC function PutClientInServer is missing");
+               PRVM_serverglobalfloat(time) = sv.time;
+               prog->ExecuteProgram(prog, PRVM_serverfunction(PutClientInServer), "QC function PutClientInServer is missing");
        }
 
        if (!host_client->netconnection)
@@ -1911,7 +1913,7 @@ void Host_Spawn_f (void)
 Host_Begin_f
 ==================
 */
-void Host_Begin_f (void)
+static void Host_Begin_f (void)
 {
        host_client->spawned = true;
 
@@ -1940,7 +1942,7 @@ Host_Kick_f
 Kicks a user off of the server
 ==================
 */
-void Host_Kick_f (void)
+static void Host_Kick_f (void)
 {
        const char *who;
        const char *message = NULL;
@@ -1951,7 +1953,6 @@ void Host_Kick_f (void)
        if (!sv.active)
                return;
 
-       SV_VM_Begin();
        save = host_client;
 
        if (Cmd_Argc() > 2 && strcmp(Cmd_Argv(1), "#") == 0)
@@ -2010,7 +2011,6 @@ void Host_Kick_f (void)
        }
 
        host_client = save;
-       SV_VM_End();
 }
 
 /*
@@ -2026,8 +2026,9 @@ DEBUGGING TOOLS
 Host_Give_f
 ==================
 */
-void Host_Give_f (void)
+static void Host_Give_f (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        const char *t;
        int v;
 
@@ -2148,7 +2149,7 @@ void Host_Give_f (void)
        }
 }
 
-prvm_edict_t   *FindViewthing (void)
+static prvm_edict_t    *FindViewthing(prvm_prog_t *prog)
 {
        int             i;
        prvm_edict_t    *e;
@@ -2156,7 +2157,7 @@ prvm_edict_t      *FindViewthing (void)
        for (i=0 ; i<prog->num_edicts ; i++)
        {
                e = PRVM_EDICT_NUM(i);
-               if (!strcmp (PRVM_GetString(PRVM_serveredictstring(e, classname)), "viewthing"))
+               if (!strcmp (PRVM_GetString(prog, PRVM_serveredictstring(e, classname)), "viewthing"))
                        return e;
        }
        Con_Print("No viewthing on map\n");
@@ -2168,16 +2169,16 @@ prvm_edict_t    *FindViewthing (void)
 Host_Viewmodel_f
 ==================
 */
-void Host_Viewmodel_f (void)
+static void Host_Viewmodel_f (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        prvm_edict_t    *e;
        dp_model_t      *m;
 
        if (!sv.active)
                return;
 
-       SV_VM_Begin();
-       e = FindViewthing ();
+       e = FindViewthing(prog);
        if (e)
        {
                m = Mod_ForName (Cmd_Argv(1), false, true, NULL);
@@ -2188,9 +2189,7 @@ void Host_Viewmodel_f (void)
                }
                else
                        Con_Printf("viewmodel: can't load %s\n", Cmd_Argv(1));
-       
        }
-       SV_VM_End();
 }
 
 /*
@@ -2198,8 +2197,9 @@ void Host_Viewmodel_f (void)
 Host_Viewframe_f
 ==================
 */
-void Host_Viewframe_f (void)
+static void Host_Viewframe_f (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        prvm_edict_t    *e;
        int             f;
        dp_model_t      *m;
@@ -2207,8 +2207,7 @@ void Host_Viewframe_f (void)
        if (!sv.active)
                return;
 
-       SV_VM_Begin();
-       e = FindViewthing ();
+       e = FindViewthing(prog);
        if (e)
        {
                m = cl.model_precache[(int)PRVM_serveredictfloat(e, modelindex)];
@@ -2219,11 +2218,10 @@ void Host_Viewframe_f (void)
 
                PRVM_serveredictfloat(e, frame) = f;
        }
-       SV_VM_End();
 }
 
 
-void PrintFrameName (dp_model_t *m, int frame)
+static void PrintFrameName (dp_model_t *m, int frame)
 {
        if (m->animscenes)
                Con_Printf("frame %i: %s\n", frame, m->animscenes[frame].name);
@@ -2236,17 +2234,16 @@ void PrintFrameName (dp_model_t *m, int frame)
 Host_Viewnext_f
 ==================
 */
-void Host_Viewnext_f (void)
+static void Host_Viewnext_f (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        prvm_edict_t    *e;
        dp_model_t      *m;
 
        if (!sv.active)
                return;
 
-       SV_VM_Begin();
-       e = FindViewthing ();
-       SV_VM_End();
+       e = FindViewthing(prog);
        if (e)
        {
                m = cl.model_precache[(int)PRVM_serveredictfloat(e, modelindex)];
@@ -2264,16 +2261,16 @@ void Host_Viewnext_f (void)
 Host_Viewprev_f
 ==================
 */
-void Host_Viewprev_f (void)
+static void Host_Viewprev_f (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        prvm_edict_t    *e;
        dp_model_t      *m;
 
        if (!sv.active)
                return;
 
-       SV_VM_Begin();
-       e = FindViewthing ();
+       e = FindViewthing(prog);
        if (e)
        {
                m = cl.model_precache[(int)PRVM_serveredictfloat(e, modelindex)];
@@ -2284,7 +2281,6 @@ void Host_Viewprev_f (void)
 
                PrintFrameName (m, (int)PRVM_serveredictfloat(e, frame));
        }
-       SV_VM_End();
 }
 
 /*
@@ -2301,7 +2297,7 @@ DEMO LOOP CONTROL
 Host_Startdemos_f
 ==================
 */
-void Host_Startdemos_f (void)
+static void Host_Startdemos_f (void)
 {
        int             i, c;
 
@@ -2340,7 +2336,7 @@ Host_Demos_f
 Return to looping demos
 ==================
 */
-void Host_Demos_f (void)
+static void Host_Demos_f (void)
 {
        if (cls.state == ca_dedicated)
                return;
@@ -2357,7 +2353,7 @@ Host_Stopdemo_f
 Return to looping demos
 ==================
 */
-void Host_Stopdemo_f (void)
+static void Host_Stopdemo_f (void)
 {
        if (!cls.demoplayback)
                return;
@@ -2365,12 +2361,13 @@ void Host_Stopdemo_f (void)
        Host_ShutdownServer ();
 }
 
-void Host_SendCvar_f (void)
+static void Host_SendCvar_f (void)
 {
        int             i;
        cvar_t  *c;
        const char *cvarname;
        client_t *old;
+       char vabuf[1024];
 
        if(Cmd_Argc() != 2)
                return;
@@ -2381,9 +2378,9 @@ void Host_SendCvar_f (void)
                // LordHavoc: if there is no such cvar or if it is private, send a
                // reply indicating that it has no value
                if(!c || (c->flags & CVAR_PRIVATE))
-                       Cmd_ForwardStringToServer(va("sentcvar %s", cvarname));
+                       Cmd_ForwardStringToServer(va(vabuf, sizeof(vabuf), "sentcvar %s", cvarname));
                else
-                       Cmd_ForwardStringToServer(va("sentcvar %s \"%s\"", c->name, c->string));
+                       Cmd_ForwardStringToServer(va(vabuf, sizeof(vabuf), "sentcvar %s \"%s\"", c->name, c->string));
                return;
        }
        if(!sv.active)// || !PRVM_serverfunction(SV_ParseClientCommand))
@@ -2437,7 +2434,7 @@ Host_PQRcon_f
 ProQuake rcon support
 =====================
 */
-void Host_PQRcon_f (void)
+static void Host_PQRcon_f (void)
 {
        int n;
        const char *e;
@@ -2471,15 +2468,18 @@ void Host_PQRcon_f (void)
        mysocket = NetConn_ChooseClientSocketForAddress(&to);
        if (mysocket)
        {
-               SZ_Clear(&net_message);
-               MSG_WriteLong (&net_message, 0);
-               MSG_WriteByte (&net_message, CCREQ_RCON);
-               SZ_Write(&net_message, (const unsigned char*)rcon_password.string, n);
-               MSG_WriteByte (&net_message, 0); // terminate the (possibly partial) string
-               MSG_WriteString (&net_message, Cmd_Args());
-               StoreBigLong(net_message.data, NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
-               NetConn_Write(mysocket, net_message.data, net_message.cursize, &to);
-               SZ_Clear (&net_message);
+               sizebuf_t buf;
+               unsigned char bufdata[64];
+               buf.data = bufdata;
+               SZ_Clear(&buf);
+               MSG_WriteLong(&buf, 0);
+               MSG_WriteByte(&buf, CCREQ_RCON);
+               SZ_Write(&buf, (const unsigned char*)rcon_password.string, n);
+               MSG_WriteByte(&buf, 0); // terminate the (possibly partial) string
+               MSG_WriteString(&buf, Cmd_Args());
+               StoreBigLong(buf.data, NETFLAG_CTL | (buf.cursize & NETFLAG_LENGTH_MASK));
+               NetConn_Write(mysocket, buf.data, buf.cursize, &to);
+               SZ_Clear(&buf);
        }
 }
 
@@ -2495,12 +2495,13 @@ Host_Rcon_f
   an unconnected command.
 =====================
 */
-void Host_Rcon_f (void) // credit: taken from QuakeWorld
+static void Host_Rcon_f (void) // credit: taken from QuakeWorld
 {
        int i, n;
        const char *e;
        lhnetaddress_t to;
        lhnetsocket_t *mysocket;
+       char vabuf[1024];
 
        if (!rcon_password.string || !rcon_password.string[0])
        {
@@ -2563,7 +2564,7 @@ void Host_Rcon_f (void) // credit: taken from QuakeWorld
                }
                else
                {
-                       NetConn_WriteString(mysocket, va("\377\377\377\377rcon %.*s %s", n, rcon_password.string, Cmd_Args()), &to);
+                       NetConn_WriteString(mysocket, va(vabuf, sizeof(vabuf), "\377\377\377\377rcon %.*s %s", n, rcon_password.string, Cmd_Args()), &to);
                }
        }
 }
@@ -2577,7 +2578,7 @@ user <name or userid>
 Dump userdata / masterdata for a user
 ====================
 */
-void Host_User_f (void) // credit: taken from QuakeWorld
+static void Host_User_f (void) // credit: taken from QuakeWorld
 {
        int             uid;
        int             i;
@@ -2610,7 +2611,7 @@ Host_Users_f
 Dump userids for all current players
 ====================
 */
-void Host_Users_f (void) // credit: taken from QuakeWorld
+static void Host_Users_f (void) // credit: taken from QuakeWorld
 {
        int             i;
        int             c;
@@ -2638,7 +2639,7 @@ Sent by server when serverinfo changes
 ==================
 */
 // TODO: shouldn't this be a cvar instead?
-void Host_FullServerinfo_f (void) // credit: taken from QuakeWorld
+static void Host_FullServerinfo_f (void) // credit: taken from QuakeWorld
 {
        char temp[512];
        if (Cmd_Argc() != 2)
@@ -2660,7 +2661,7 @@ Allow clients to change userinfo
 ==================
 Casey was here :)
 */
-void Host_FullInfo_f (void) // credit: taken from QuakeWorld
+static void Host_FullInfo_f (void) // credit: taken from QuakeWorld
 {
        char key[512];
        char value[512];
@@ -2709,7 +2710,7 @@ CL_SetInfo_f
 Allow clients to change userinfo
 ==================
 */
-void Host_SetInfo_f (void) // credit: taken from QuakeWorld
+static void Host_SetInfo_f (void) // credit: taken from QuakeWorld
 {
        if (Cmd_Argc() == 1)
        {
@@ -2733,7 +2734,7 @@ packet <destination> <contents>
 Contents allows \n escape character
 ====================
 */
-void Host_Packet_f (void) // credit: taken from QuakeWorld
+static void Host_Packet_f (void) // credit: taken from QuakeWorld
 {
        char send[2048];
        int i, l;
@@ -2858,7 +2859,7 @@ void Host_Pings_f (void)
                MSG_WriteString(&host_client->netconnection->message, "\n");
 }
 
-void Host_PingPLReport_f(void)
+static void Host_PingPLReport_f(void)
 {
        char *errbyte;
        int i;
diff --git a/image.c b/image.c
index f9f5e7505c04af8aad3ceb3426e581ecce58b3a3..988fbef8e7f27b4a8abcfaf89edb8e92cecea14e 100644 (file)
--- a/image.c
+++ b/image.c
@@ -8,7 +8,7 @@
 int            image_width;
 int            image_height;
 
-void Image_CopyAlphaFromBlueBGRA(unsigned char *outpixels, const unsigned char *inpixels, int w, int h)
+static void Image_CopyAlphaFromBlueBGRA(unsigned char *outpixels, const unsigned char *inpixels, int w, int h)
 {
        int i, n;
        n = w * h;
@@ -189,7 +189,7 @@ typedef struct pcx_s
 LoadPCX
 ============
 */
-unsigned char* LoadPCX_BGRA (const unsigned char *f, int filesize, int *miplevel)
+static unsigned char* LoadPCX_BGRA (const unsigned char *f, int filesize, int *miplevel)
 {
        pcx_t pcx;
        unsigned char *a, *b, *image_buffer, *pbuf;
@@ -372,7 +372,7 @@ typedef struct _TargaHeader
 }
 TargaHeader;
 
-void PrintTargaHeader(TargaHeader *t)
+static void PrintTargaHeader(TargaHeader *t)
 {
        Con_Printf("TargaHeader:\nuint8 id_length = %i;\nuint8 colormap_type = %i;\nuint8 image_type = %i;\nuint16 colormap_index = %i;\nuint16 colormap_length = %i;\nuint8 colormap_size = %i;\nuint16 x_origin = %i;\nuint16 y_origin = %i;\nuint16 width = %i;\nuint16 height = %i;\nuint8 pixel_size = %i;\nuint8 attributes = %i;\n", t->id_length, t->colormap_type, t->image_type, t->colormap_index, t->colormap_length, t->colormap_size, t->x_origin, t->y_origin, t->width, t->height, t->pixel_size, t->attributes);
 }
@@ -746,7 +746,7 @@ typedef struct q2wal_s
        int                     value;
 } q2wal_t;
 
-unsigned char *LoadWAL_BGRA (const unsigned char *f, int filesize, int *miplevel)
+static unsigned char *LoadWAL_BGRA (const unsigned char *f, int filesize, int *miplevel)
 {
        unsigned char *image_buffer;
        const q2wal_t *inwal = (const q2wal_t *)f;
@@ -916,6 +916,7 @@ unsigned char *loadimagepixelsbgra (const char *filename, qboolean complain, qbo
        imageformat_t *firstformat, *format;
        unsigned char *f, *data = NULL, *data2 = NULL;
        char basename[MAX_QPATH], name[MAX_QPATH], name2[MAX_QPATH], *c;
+       char vabuf[1024];
        //if (developer_memorydebug.integer)
        //      Mem_CheckSentinelsGlobal();
        if (developer_texturelogging.integer)
@@ -959,7 +960,7 @@ unsigned char *loadimagepixelsbgra (const char *filename, qboolean complain, qbo
                        {
                                if(format->loadfunc == JPEG_LoadImage_BGRA) // jpeg can't do alpha, so let's simulate it by loading another jpeg
                                {
-                                       dpsnprintf (name2, sizeof(name2), format->formatstring, va("%s_alpha", basename));
+                                       dpsnprintf (name2, sizeof(name2), format->formatstring, va(vabuf, sizeof(vabuf), "%s_alpha", basename));
                                        f = FS_LoadFile(name2, tempmempool, true, &filesize);
                                        if(f)
                                        {
@@ -1305,7 +1306,7 @@ static void Image_Resample32LerpLine (const unsigned char *in, unsigned char *ou
 }
 
 #define LERPBYTE(i) r = resamplerow1[i];out[i] = (unsigned char) ((((resamplerow2[i] - r) * lerp) >> 16) + r)
-void Image_Resample32Lerp(const void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight)
+static void Image_Resample32Lerp(const void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight)
 {
        int i, j, r, yi, oldy, f, fstep, lerp, endy = (inheight-1), inwidth4 = inwidth*4, outwidth4 = outwidth*4;
        unsigned char *out;
@@ -1409,7 +1410,7 @@ void Image_Resample32Lerp(const void *indata, int inwidth, int inheight, void *o
        resamplerow2 = NULL;
 }
 
-void Image_Resample32Nolerp(const void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight)
+static void Image_Resample32Nolerp(const void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight)
 {
        int i, j;
        unsigned frac, fracstep;
index 4267331be738462ceaacfd07541f5bedab60861a..9c03f8f3c05be418a2cd97c36a243281e06d6a2e 100644 (file)
@@ -217,7 +217,7 @@ static struct
 } my_png;
 
 //LordHavoc: removed __cdecl prefix, added overrun protection, and rewrote this to be more efficient
-void PNG_fReadData(void *png, unsigned char *data, size_t length)
+static void PNG_fReadData(void *png, unsigned char *data, size_t length)
 {
        size_t l;
        l = my_png.tmpBuflength - my_png.tmpi;
@@ -234,21 +234,21 @@ void PNG_fReadData(void *png, unsigned char *data, size_t length)
        //Com_HexDumpToConsole(data, (int)length);
 }
 
-void PNG_fWriteData(void *png, unsigned char *data, size_t length)
+static void PNG_fWriteData(void *png, unsigned char *data, size_t length)
 {
        FS_Write(my_png.outfile, data, length);
 }
 
-void PNG_fFlushData(void *png)
+static void PNG_fFlushData(void *png)
 {
 }
 
-void PNG_error_fn(void *png, const char *message)
+static void PNG_error_fn(void *png, const char *message)
 {
        Con_Printf("PNG_LoadImage: error: %s\n", message);
 }
 
-void PNG_warning_fn(void *png, const char *message)
+static void PNG_warning_fn(void *png, const char *message)
 {
        Con_Printf("PNG_LoadImage: warning: %s\n", message);
 }
diff --git a/jpeg.c b/jpeg.c
index 8df1b484083a2c9bf0951ee91ec12492ea5aa240..4b276d2e1549c5fd5c2ca175a16c5e8e25c5a703 100644 (file)
--- a/jpeg.c
+++ b/jpeg.c
@@ -1003,7 +1003,8 @@ static CompressedImageCacheItem *CompressedImageCache[COMPRESSEDIMAGECACHE_SIZE]
 
 static void CompressedImageCache_Add(const char *imagename, size_t maxsize, void *compressed, size_t compressed_size)
 {
-       const char *hashkey = va("%s:%d", imagename, (int) maxsize);
+       char vabuf[1024];
+       const char *hashkey = va(vabuf, sizeof(vabuf), "%s:%d", imagename, (int) maxsize);
        int hashindex = CRC_Block((unsigned char *) hashkey, strlen(hashkey)) % COMPRESSEDIMAGECACHE_SIZE;
        CompressedImageCacheItem *i;
 
@@ -1021,7 +1022,8 @@ static void CompressedImageCache_Add(const char *imagename, size_t maxsize, void
 
 static CompressedImageCacheItem *CompressedImageCache_Find(const char *imagename, size_t maxsize)
 {
-       const char *hashkey = va("%s:%d", imagename, (int) maxsize);
+       char vabuf[1024];
+       const char *hashkey = va(vabuf, sizeof(vabuf), "%s:%d", imagename, (int) maxsize);
        int hashindex = CRC_Block((unsigned char *) hashkey, strlen(hashkey)) % COMPRESSEDIMAGECACHE_SIZE;
        CompressedImageCacheItem *i = CompressedImageCache[hashindex];
 
diff --git a/keys.c b/keys.c
index 28f74a42b0dfcbb343ba094af647fdf1c2d89761..18b7a8446ed91e485485dce36603236ef4da46a0 100644 (file)
--- a/keys.c
+++ b/keys.c
@@ -23,6 +23,7 @@
 #include "quakedef.h"
 #include "cl_video.h"
 #include "utf8lib.h"
+#include "csprogs.h"
 
 cvar_t con_closeontoggleconsole = {CVAR_SAVE, "con_closeontoggleconsole","1", "allows toggleconsole binds to close the console as well; when set to 2, this even works when not at the start of the line in console input; when set to 3, this works even if the toggleconsole key is the color tag"};
 
@@ -114,7 +115,7 @@ static void Key_History_Push(void)
                history_matchfound = false;
 }
 
-qboolean Key_History_Get_foundCommand(void)
+static qboolean Key_History_Get_foundCommand(void)
 {
        if (!history_matchfound)
                return false;
@@ -201,7 +202,8 @@ static void Key_History_Find_Backwards(void)
 {
        int i;
        const char *partial = key_line + 1;
-       size_t digits = strlen(va("%i", HIST_MAXLINES));
+       char vabuf[1024];
+       size_t digits = strlen(va(vabuf, sizeof(vabuf), "%i", HIST_MAXLINES));
 
        if (history_line == -1) // editing the "new" line
                strlcpy(history_savedline, key_line + 1, sizeof(history_savedline));
@@ -219,7 +221,7 @@ static void Key_History_Find_Backwards(void)
        if (!*partial)
                partial = "*";
        else if (!( strchr(partial, '*') || strchr(partial, '?') )) // no pattern?
-               partial = va("*%s*", partial);
+               partial = va(vabuf, sizeof(vabuf), "*%s*", partial);
 
        for ( ; i >= 0; i--)
                if (matchpattern_with_separator(ConBuffer_GetLine(&history, i), partial, true, "", false))
@@ -235,7 +237,8 @@ static void Key_History_Find_Forwards(void)
 {
        int i;
        const char *partial = key_line + 1;
-       size_t digits = strlen(va("%i", HIST_MAXLINES));
+       char vabuf[1024];
+       size_t digits = strlen(va(vabuf, sizeof(vabuf), "%i", HIST_MAXLINES));
 
        if (history_line == -1) // editing the "new" line
                return;
@@ -250,7 +253,7 @@ static void Key_History_Find_Forwards(void)
        if (!*partial)
                partial = "*";
        else if (!( strchr(partial, '*') || strchr(partial, '?') )) // no pattern?
-               partial = va("*%s*", partial);
+               partial = va(vabuf, sizeof(vabuf), "*%s*", partial);
 
        for ( ; i < CONBUFFER_LINES_COUNT(&history); i++)
                if (matchpattern_with_separator(ConBuffer_GetLine(&history, i), partial, true, "", false))
@@ -266,13 +269,14 @@ static void Key_History_Find_All(void)
 {
        const char *partial = key_line + 1;
        int i, count = 0;
-       size_t digits = strlen(va("%i", HIST_MAXLINES));
+       char vabuf[1024];
+       size_t digits = strlen(va(vabuf, sizeof(vabuf), "%i", HIST_MAXLINES));
        Con_Printf("History commands containing \"%s\":\n", key_line + 1);
 
        if (!*partial)
                partial = "*";
        else if (!( strchr(partial, '*') || strchr(partial, '?') )) // no pattern?
-               partial = va("*%s*", partial);
+               partial = va(vabuf, sizeof(vabuf), "*%s*", partial);
 
        for (i=0; i<CONBUFFER_LINES_COUNT(&history); i++)
                if (matchpattern_with_separator(ConBuffer_GetLine(&history, i), partial, true, "", false))
@@ -287,7 +291,8 @@ static void Key_History_f(void)
 {
        char *errchar = NULL;
        int i = 0;
-       size_t digits = strlen(va("%i", HIST_MAXLINES));
+       char vabuf[1024];
+       size_t digits = strlen(va(vabuf, sizeof(vabuf), "%i", HIST_MAXLINES));
 
        if (Cmd_Argc () > 1)
        {
@@ -1192,17 +1197,16 @@ int chat_mode;
 char           chat_buffer[MAX_INPUTLINE];
 unsigned int   chat_bufferlen = 0;
 
-extern int Nicks_CompleteChatLine(char *buffer, size_t size, unsigned int pos);
-
 static void
 Key_Message (int key, int ascii)
 {
+       char vabuf[1024];
        if (key == K_ENTER || ascii == 10 || ascii == 13)
        {
                if(chat_mode < 0)
                        Cmd_ExecuteString(chat_buffer, src_command, true); // not Cbuf_AddText to allow semiclons in args; however, this allows no variables then. Use aliases!
                else
-                       Cmd_ForwardStringToServer(va("%s %s", chat_mode ? "say_team" : "say ", chat_buffer));
+                       Cmd_ForwardStringToServer(va(vabuf, sizeof(vabuf), "%s %s", chat_mode ? "say_team" : "say ", chat_buffer));
 
                key_dest = key_game;
                chat_bufferlen = 0;
@@ -1283,10 +1287,9 @@ FIXME: handle quote special (general escape sequence?)
 ===================
 */
 const char *
-Key_KeynumToString (int keynum)
+Key_KeynumToString (int keynum, char *tinystr, size_t tinystrlength)
 {
        const keyname_t  *kn;
-       static char tinystr[2];
 
        // -1 is an invalid code
        if (keynum < 0)
@@ -1300,8 +1303,11 @@ Key_KeynumToString (int keynum)
        // if it is printable, output it as a single character
        if (keynum > 32 && keynum < 256)
        {
-               tinystr[0] = keynum;
-               tinystr[1] = 0;
+               if (tinystrlength >= 2)
+               {
+                       tinystr[0] = keynum;
+                       tinystr[1] = 0;
+               }
                return tinystr;
        }
 
@@ -1494,6 +1500,7 @@ static void
 Key_PrintBindList(int j)
 {
        char bindbuf[MAX_INPUTLINE];
+       char tinystr[2];
        const char *p;
        int i;
 
@@ -1504,9 +1511,9 @@ Key_PrintBindList(int j)
                {
                        Cmd_QuoteString(bindbuf, sizeof(bindbuf), p, "\"\\", false);
                        if (j == 0)
-                               Con_Printf("^2%s ^7= \"%s\"\n", Key_KeynumToString (i), bindbuf);
+                               Con_Printf("^2%s ^7= \"%s\"\n", Key_KeynumToString (i, tinystr, sizeof(tinystr)), bindbuf);
                        else
-                               Con_Printf("^3bindmap %d: ^2%s ^7= \"%s\"\n", j, Key_KeynumToString (i), bindbuf);
+                               Con_Printf("^3bindmap %d: ^2%s ^7= \"%s\"\n", j, Key_KeynumToString (i, tinystr, sizeof(tinystr)), bindbuf);
                }
        }
 }
@@ -1586,6 +1593,7 @@ Key_WriteBindings (qfile_t *f)
 {
        int         i, j;
        char bindbuf[MAX_INPUTLINE];
+       char tinystr[2];
        const char *p;
 
        for (j = 0; j < MAX_BINDMAPS; j++)
@@ -1597,9 +1605,9 @@ Key_WriteBindings (qfile_t *f)
                        {
                                Cmd_QuoteString(bindbuf, sizeof(bindbuf), p, "\"\\", false); // don't need to escape $ because cvars are not expanded inside bind
                                if (j == 0)
-                                       FS_Printf(f, "bind %s \"%s\"\n", Key_KeynumToString (i), bindbuf);
+                                       FS_Printf(f, "bind %s \"%s\"\n", Key_KeynumToString (i, tinystr, sizeof(tinystr)), bindbuf);
                                else
-                                       FS_Printf(f, "in_bind %d %s \"%s\"\n", j, Key_KeynumToString (i), bindbuf);
+                                       FS_Printf(f, "in_bind %d %s \"%s\"\n", j, Key_KeynumToString (i, tinystr, sizeof(tinystr)), bindbuf);
                        }
                }
        }
@@ -1686,8 +1694,6 @@ void Key_FindKeysForCommand (const char *command, int *keys, int numkeys, int bi
        }
 }
 
-extern qboolean CL_VM_InputEvent (int eventtype, int x, int y);
-
 /*
 ===================
 Called by the system between frames for both key up and key down events
@@ -1741,6 +1747,7 @@ Key_Event (int key, int ascii, qboolean down)
        const char *bind;
        qboolean q;
        keydest_t keydest = key_dest;
+       char vabuf[1024];
 
        if (key < 0 || key >= MAX_KEYS)
                return;
@@ -1874,14 +1881,14 @@ Key_Event (int key, int ascii, qboolean down)
                        {
                                // button commands add keynum as a parm
                                if (bind[0] == '+')
-                                       Cbuf_AddText (va("%s %i\n", bind, key));
+                                       Cbuf_AddText (va(vabuf, sizeof(vabuf), "%s %i\n", bind, key));
                                else
                                {
                                        Cbuf_AddText (bind);
                                        Cbuf_AddText ("\n");
                                }
                        } else if(bind[0] == '+' && !down && keydown[key] == 0)
-                               Cbuf_AddText(va("-%s %i\n", bind + 1, key));
+                               Cbuf_AddText(va(vabuf, sizeof(vabuf), "-%s %i\n", bind + 1, key));
                }
                return;
        }
@@ -1948,14 +1955,14 @@ Key_Event (int key, int ascii, qboolean down)
                                {
                                        // button commands add keynum as a parm
                                        if (bind[0] == '+')
-                                               Cbuf_AddText (va("%s %i\n", bind, key));
+                                               Cbuf_AddText (va(vabuf, sizeof(vabuf), "%s %i\n", bind, key));
                                        else
                                        {
                                                Cbuf_AddText (bind);
                                                Cbuf_AddText ("\n");
                                        }
                                } else if(bind[0] == '+' && !down && keydown[key] == 0)
-                                       Cbuf_AddText(va("-%s %i\n", bind + 1, key));
+                                       Cbuf_AddText(va(vabuf, sizeof(vabuf), "-%s %i\n", bind + 1, key));
                        }
                        break;
                default:
diff --git a/keys.h b/keys.h
index e471a235a74ceb3255e0ed5732e76f79d8d29ac8..a84eb4c6f7cced9246b4faaf430ffb851467ed28 100644 (file)
--- a/keys.h
+++ b/keys.h
@@ -367,11 +367,11 @@ extern    keydest_t       key_dest;
 extern int                     key_consoleactive;
 extern char            *keybindings[MAX_BINDMAPS][MAX_KEYS];
 
-extern void Key_ClearEditLine(int edit_line);
 extern int chat_mode; // 0 for say, 1 for say_team, -1 for command
 extern char chat_buffer[MAX_INPUTLINE];
 extern unsigned int chat_bufferlen;
 
+void Key_ClearEditLine(int edit_line);
 void Key_WriteBindings(qfile_t *f);
 void Key_Init(void);
 void Key_Shutdown(void);
diff --git a/lhnet.c b/lhnet.c
index 7f9664c05da90dc410509fd7b983224af87579a7..cb87b6d319e2ae866f94ca9bf11d1856120aa9cd 100644 (file)
--- a/lhnet.c
+++ b/lhnet.c
@@ -612,7 +612,7 @@ int LHNETADDRESS_GetAddressType(const lhnetaddress_t *address)
                return LHNETADDRESSTYPE_NONE;
 }
 
-const char *LHNETADDRESS_GetInterfaceName(const lhnetaddress_t *vaddress)
+const char *LHNETADDRESS_GetInterfaceName(const lhnetaddress_t *vaddress, char *ifname, size_t ifnamelength)
 {
 #ifdef SUPPORTIPV6
        lhnetaddressnative_t *address = (lhnetaddressnative_t *)vaddress;
@@ -621,8 +621,6 @@ const char *LHNETADDRESS_GetInterfaceName(const lhnetaddress_t *vaddress)
        {
 #ifndef _WIN32
 
-               static char ifname [IF_NAMESIZE];
-               
                if (if_indextoname(address->addr.in6.sin6_scope_id, ifname) == ifname)
                        return ifname;
 
@@ -631,9 +629,7 @@ const char *LHNETADDRESS_GetInterfaceName(const lhnetaddress_t *vaddress)
                // The Win32 API doesn't have if_indextoname() until Windows Vista,
                // but luckily it just uses the interface ID as the interface name
 
-               static char ifname [16];
-
-               if (dpsnprintf(ifname, sizeof(ifname), "%lu", address->addr.in6.sin6_scope_id) > 0)
+               if (dpsnprintf(ifname, ifnamelength, "%lu", address->addr.in6.sin6_scope_id) > 0)
                        return ifname;
 
 #endif
diff --git a/lhnet.h b/lhnet.h
index d46dbe99a859cfb6db3a2ad8ed095febcd79073c..518ccdf91566a5bda09fa5fe27776b7ed7d5a40f 100644 (file)
--- a/lhnet.h
+++ b/lhnet.h
@@ -25,7 +25,7 @@ int LHNETADDRESS_FromPort(lhnetaddress_t *address, lhnetaddresstype_t addresstyp
 int LHNETADDRESS_FromString(lhnetaddress_t *address, const char *string, int defaultport);
 int LHNETADDRESS_ToString(const lhnetaddress_t *address, char *string, int stringbuffersize, int includeport);
 int LHNETADDRESS_GetAddressType(const lhnetaddress_t *address);
-const char *LHNETADDRESS_GetInterfaceName(const lhnetaddress_t *address);
+const char *LHNETADDRESS_GetInterfaceName(const lhnetaddress_t *address, char *ifname, size_t ifnamelength);
 int LHNETADDRESS_GetPort(const lhnetaddress_t *address);
 int LHNETADDRESS_SetPort(lhnetaddress_t *address, int port);
 int LHNETADDRESS_Compare(const lhnetaddress_t *address1, const lhnetaddress_t *address2);
index 7f1760595d87330d168b9daed21f727622be4e4a..38278606d0cd0f5fea86c27c30f8ebbd09665f85 100644 (file)
--- a/libcurl.c
+++ b/libcurl.c
@@ -1,6 +1,7 @@
 #include "quakedef.h"
 #include "fs.h"
 #include "libcurl.h"
+#include "thread.h"
 
 static cvar_t cl_curl_maxdownloads = {CVAR_SAVE, "cl_curl_maxdownloads","1", "maximum number of concurrent HTTP/FTP downloads"};
 static cvar_t cl_curl_maxspeed = {CVAR_SAVE, "cl_curl_maxspeed","300", "maximum download speed (KiB/s)"};
@@ -182,6 +183,8 @@ static dllfunction_t curlfuncs[] =
 static dllhandle_t curl_dll = NULL;
 // will be checked at many places to find out if qcurl calls are allowed
 
+void *curl_mutex = NULL;
+
 typedef struct downloadinfo_s
 {
        char filename[MAX_OSPATH];
@@ -231,7 +234,7 @@ all downloads since last server connect ended with a successful status.
 Setting the command to NULL clears it.
 ====================
 */
-void Curl_CommandWhenDone(const char *cmd)
+static void Curl_CommandWhenDone(const char *cmd)
 {
        if(!curl_dll)
                return;
@@ -247,7 +250,7 @@ Do not use yet. Not complete.
 Problem: what counts as an error?
 */
 
-void Curl_CommandWhenError(const char *cmd)
+static void Curl_CommandWhenError(const char *cmd)
 {
        if(!curl_dll)
                return;
@@ -269,6 +272,7 @@ void Curl_Clear_forthismap(void)
        downloadinfo *di;
        if(noclear)
                return;
+       if (curl_mutex) Thread_LockMutex(curl_mutex);
        for(di = downloads; di; di = di->next)
                di->forthismap = false;
        Curl_CommandWhenError(NULL);
@@ -276,6 +280,7 @@ void Curl_Clear_forthismap(void)
        numdownloads_fail = 0;
        numdownloads_success = 0;
        numdownloads_added = 0;
+       if (curl_mutex) Thread_UnlockMutex(curl_mutex);
 }
 
 /*
@@ -292,8 +297,10 @@ qboolean Curl_Have_forthismap(void)
 
 void Curl_Register_predownload(void)
 {
+       if (curl_mutex) Thread_LockMutex(curl_mutex);
        Curl_CommandWhenDone("cl_begindownloads");
        Curl_CommandWhenError("cl_begindownloads");
+       if (curl_mutex) Thread_UnlockMutex(curl_mutex);
 }
 
 /*
@@ -450,11 +457,6 @@ static void curl_default_callback(int status, size_t length_received, unsigned c
        }
 }
 
-static void curl_quiet_callback(int status, size_t length_received, unsigned char *buffer, void *cbdata)
-{
-       curl_default_callback(status, length_received, buffer, cbdata);
-}
-
 /*
 ====================
 Curl_EndDownload
@@ -562,9 +564,8 @@ CleanURL
 Returns a "cleaned up" URL for display (to strip login data)
 ====================
 */
-static const char *CleanURL(const char *url)
+static const char *CleanURL(const char *url, char *urlbuf, size_t urlbuflength)
 {
-       static char urlbuf[1024];
        const char *p, *q, *r;
 
        // if URL is of form anything://foo-without-slash@rest, replace by anything://rest
@@ -577,7 +578,7 @@ static const char *CleanURL(const char *url)
                        r = strchr(p + 3, '/');
                        if(!r || q < r)
                        {
-                               dpsnprintf(urlbuf, sizeof(urlbuf), "%.*s%s", (int)(p - url + 3), url, q + 1);
+                               dpsnprintf(urlbuf, urlbuflength, "%.*s%s", (int)(p - url + 3), url, q + 1);
                                return urlbuf;
                        }
                }
@@ -598,6 +599,8 @@ up to a maximum number of cl_curl_maxdownloads are running.
 static void CheckPendingDownloads(void)
 {
        const char *h;
+       char urlbuf[1024];
+       char vabuf[1024];
        if(!curl_dll)
                return;
        if(numdownloads < cl_curl_maxdownloads.integer)
@@ -609,7 +612,7 @@ static void CheckPendingDownloads(void)
                        {
                                if(!di->buffer)
                                {
-                                       Con_Printf("Downloading %s -> %s", CleanURL(di->url), di->filename);
+                                       Con_Printf("Downloading %s -> %s", CleanURL(di->url, urlbuf, sizeof(urlbuf)), di->filename);
 
                                        di->stream = FS_OpenRealFile(di->filename, "ab", false);
                                        if(!di->stream)
@@ -627,7 +630,7 @@ static void CheckPendingDownloads(void)
                                }
                                else
                                {
-                                       Con_DPrintf("Downloading %s -> memory\n", CleanURL(di->url));
+                                       Con_DPrintf("Downloading %s -> memory\n", CleanURL(di->url, urlbuf, sizeof(urlbuf)));
                                        di->startpos = 0;
                                }
 
@@ -654,7 +657,7 @@ static void CheckPendingDownloads(void)
                                        qcurl_easy_setopt(di->curle, CURLOPT_POST, 1);
                                        qcurl_easy_setopt(di->curle, CURLOPT_POSTFIELDS, di->postbuf);
                                        qcurl_easy_setopt(di->curle, CURLOPT_POSTFIELDSIZE, di->postbufsize);
-                                       di->slist = qcurl_slist_append(di->slist, va("Content-Type: %s", di->post_content_type));
+                                       di->slist = qcurl_slist_append(di->slist, va(vabuf, sizeof(vabuf), "Content-Type: %s", di->post_content_type));
                                }
 
                                // parse extra headers into slist
@@ -703,6 +706,7 @@ void Curl_Init(void)
        CURL_OpenLibrary();
        if(!curl_dll)
                return;
+       if (Thread_HasThreads()) curl_mutex = Thread_CreateMutex();
        qcurl_global_init(CURL_GLOBAL_NOTHING);
        curlm = qcurl_multi_init();
 }
@@ -721,6 +725,7 @@ void Curl_Shutdown(void)
                return;
        Curl_ClearRequirements();
        Curl_CancelAll();
+       if (curl_mutex) Thread_DestroyMutex(curl_mutex);
        CURL_CloseLibrary();
        curl_dll = NULL;
 }
@@ -743,24 +748,6 @@ static downloadinfo *Curl_Find(const char *filename)
        return NULL;
 }
 
-void Curl_Cancel_ToMemory(curl_callback_t callback, void *cbdata)
-{
-       downloadinfo *di;
-       if(!curl_dll)
-               return;
-       for(di = downloads; di; )
-       {
-               if(di->callback == callback && di->callback_data == cbdata)
-               {
-                       di->callback = curl_quiet_callback; // do NOT call the callback
-                       Curl_EndDownload(di, CURL_DOWNLOAD_ABORTED, CURLE_OK);
-                       di = downloads;
-               }
-               else
-                       di = di->next;
-       }
-}
-
 /*
 ====================
 Curl_Begin
@@ -830,7 +817,9 @@ static qboolean Curl_Begin(const char *URL, const char *extraheaders, double max
                //   141.2.16.3 - - [17/Mar/2006:22:32:43 +0100] "GET /maps/tznex07.pk3 HTTP/1.1" 200 1077455 "dp://141.2.16.7:26000/" "Nexuiz Linux 22:07:43 Mar 17 2006"
 
                if(!name)
-                       name = CleanURL(URL);
+                       name = CleanURL(URL, urlbuf, sizeof(urlbuf));
+
+               if (curl_mutex) Thread_LockMutex(curl_mutex);
 
                if(!buf)
                {
@@ -847,7 +836,7 @@ static qboolean Curl_Begin(const char *URL, const char *extraheaders, double max
                                downloadinfo *di = Curl_Find(fn);
                                if(di)
                                {
-                                       Con_Printf("Can't download %s, already getting it from %s!\n", fn, CleanURL(di->url));
+                                       Con_Printf("Can't download %s, already getting it from %s!\n", fn, CleanURL(di->url, urlbuf, sizeof(urlbuf)));
 
                                        // however, if it was not for this map yet...
                                        if(forthismap && !di->forthismap)
@@ -912,6 +901,7 @@ static qboolean Curl_Begin(const char *URL, const char *extraheaders, double max
                if(strncmp(URL, "http://", 7) && strncmp(URL, "ftp://", 6) && strncmp(URL, "https://", 8))
                {
                        Con_Printf("Curl_Begin(\"%s\"): nasty URL scheme rejected\n", URL);
+                       if (curl_mutex) Thread_UnlockMutex(curl_mutex);
                        return false;
                }
 
@@ -964,6 +954,7 @@ static qboolean Curl_Begin(const char *URL, const char *extraheaders, double max
                }
 
                downloads = di;
+               if (curl_mutex) Thread_UnlockMutex(curl_mutex);
                return true;
        }
 }
@@ -1002,13 +993,21 @@ void Curl_Run(void)
        if(!curl_dll)
                return;
 
+       if (curl_mutex) Thread_LockMutex(curl_mutex);
+
        Curl_CheckCommandWhenDone();
 
        if(!downloads)
+       {
+               if (curl_mutex) Thread_UnlockMutex(curl_mutex);
                return;
+       }
 
        if(realtime < curltime) // throttle
+       {
+               if (curl_mutex) Thread_UnlockMutex(curl_mutex);
                return;
+       }
 
        {
                int remaining;
@@ -1091,6 +1090,8 @@ void Curl_Run(void)
        }
        else
                curltime = realtime;
+
+       if (curl_mutex) Thread_UnlockMutex(curl_mutex);
 }
 
 /*
@@ -1105,11 +1106,15 @@ void Curl_CancelAll(void)
        if(!curl_dll)
                return;
 
+       if (curl_mutex) Thread_LockMutex(curl_mutex);
+
        while(downloads)
        {
                Curl_EndDownload(downloads, CURL_DOWNLOAD_ABORTED, CURLE_OK);
                // INVARIANT: downloads will point to the next download after that!
        }
+
+       if (curl_mutex) Thread_UnlockMutex(curl_mutex);
 }
 
 /*
@@ -1184,15 +1189,17 @@ prints the download list
 static void Curl_Info_f(void)
 {
        downloadinfo *di;
+       char urlbuf[1024];
        if(!curl_dll)
                return;
        if(Curl_Running())
        {
+               if (curl_mutex) Thread_LockMutex(curl_mutex);
                Con_Print("Currently running downloads:\n");
                for(di = downloads; di; di = di->next)
                {
                        double speed, percent;
-                       Con_Printf("  %s -> %s ",  CleanURL(di->url), di->filename);
+                       Con_Printf("  %s -> %s ",  CleanURL(di->url, urlbuf, sizeof(urlbuf)), di->filename);
                        percent = 100.0 * Curl_GetDownloadAmount(di);
                        speed = Curl_GetDownloadSpeed(di);
                        if(percent >= 0)
@@ -1200,6 +1207,7 @@ static void Curl_Info_f(void)
                        else
                                Con_Print("(queued)\n");
                }
+               if (curl_mutex) Thread_UnlockMutex(curl_mutex);
        }
        else
        {
@@ -1233,7 +1241,7 @@ curl --finish_autodownload
        once the last download completes successfully, reconnect to the current server
 ====================
 */
-void Curl_Curl_f(void)
+static void Curl_Curl_f(void)
 {
        double maxspeed = 0;
        int i;
@@ -1402,12 +1410,11 @@ information, or to NULL if no such display shall occur. The returned
 array must be freed later using Z_Free.
 ====================
 */
-Curl_downloadinfo_t *Curl_GetDownloadInfo(int *nDownloads, const char **additional_info)
+Curl_downloadinfo_t *Curl_GetDownloadInfo(int *nDownloads, const char **additional_info, char *addinfo, size_t addinfolength)
 {
        int i;
        downloadinfo *di;
        Curl_downloadinfo_t *downinfo;
-       static char addinfo[128];
 
        if(!curl_dll)
        {
@@ -1417,6 +1424,8 @@ Curl_downloadinfo_t *Curl_GetDownloadInfo(int *nDownloads, const char **addition
                return NULL;
        }
 
+       if (curl_mutex) Thread_LockMutex(curl_mutex);
+
        i = 0;
        for(di = downloads; di; di = di->next)
                ++i;
@@ -1449,11 +1458,11 @@ Curl_downloadinfo_t *Curl_GetDownloadInfo(int *nDownloads, const char **addition
                if(*command_when_done && !numdownloads_fail && numdownloads_added)
                {
                        if(!strncmp(command_when_done, "connect ", 8))
-                               dpsnprintf(addinfo, sizeof(addinfo), "(will join %s when done)", command_when_done + 8);
+                               dpsnprintf(addinfo, addinfolength, "(will join %s when done)", command_when_done + 8);
                        else if(!strcmp(command_when_done, "cl_begindownloads"))
-                               dpsnprintf(addinfo, sizeof(addinfo), "(will enter the game when done)");
+                               dpsnprintf(addinfo, addinfolength, "(will enter the game when done)");
                        else
-                               dpsnprintf(addinfo, sizeof(addinfo), "(will do '%s' when done)", command_when_done);
+                               dpsnprintf(addinfo, addinfolength, "(will do '%s' when done)", command_when_done);
                        *additional_info = addinfo;
                }
                else
@@ -1461,6 +1470,7 @@ Curl_downloadinfo_t *Curl_GetDownloadInfo(int *nDownloads, const char **addition
        }
 
        *nDownloads = i;
+       if (curl_mutex) Thread_UnlockMutex(curl_mutex);
        return downinfo;
 }
 
@@ -1491,7 +1501,7 @@ this file for obvious reasons.
 */
 static const char *Curl_FindPackURL(const char *filename)
 {
-       static char foundurl[1024];
+       static char foundurl[1024]; // invoked only by server
        fs_offset_t filesize;
        char *buf = (char *) FS_LoadFile("curl_urls.txt", tempmempool, true, &filesize);
        if(buf && filesize)
index ed05551c10bf27d31043951425b9a584bc7787cc..c5e55dd3707d4d17c008ee5e32a48e1d6dcc6604 100644 (file)
--- a/libcurl.h
+++ b/libcurl.h
@@ -15,9 +15,6 @@ qboolean Curl_Begin_ToFile(const char *URL, double maxspeed, const char *name, q
 
 qboolean Curl_Begin_ToMemory(const char *URL, double maxspeed, unsigned char *buf, size_t bufsize, curl_callback_t callback, void *cbdata);
 qboolean Curl_Begin_ToMemory_POST(const char *URL, const char *extraheaders, double maxspeed, const char *post_content_type, const unsigned char *postbuf, size_t postbufsize, unsigned char *buf, size_t bufsize, curl_callback_t callback, void *cbdata);
-       // NOTE: if these return false, the callback will NOT get called, so free your buffer then!
-void Curl_Cancel_ToMemory(curl_callback_t callback, void *cbdata);
-       // removes all downloads with the given callback and cbdata (this does NOT call the callbacks!)
 
 void Curl_Init(void);
 void Curl_Init_Commands(void);
@@ -39,7 +36,7 @@ typedef struct Curl_downloadinfo_s
        qboolean queued;
 }
 Curl_downloadinfo_t;
-Curl_downloadinfo_t *Curl_GetDownloadInfo(int *nDownloads, const char **additional_info);
+Curl_downloadinfo_t *Curl_GetDownloadInfo(int *nDownloads, const char **additional_info, char *addinfo, size_t addinfolength);
        // this may and should be Z_Free()ed
        // the result is actually an array
        // an additional info string may be returned in additional_info as a
index 84db7512929f70e67687b17d5bb9840f6fe0247b..7a8a4cfb9ca05a986c69e8c5ac4eb15dab907519 100644 (file)
--- a/makefile
+++ b/makefile
@@ -213,7 +213,7 @@ ifeq ($(D3D), 1)
        LDFLAGS_D3D=-ld3d9
 else
        CFLAGS_D3D=
-       CFLAGS_WARNINGS=-Wall -Wold-style-definition -Wstrict-prototypes -Wsign-compare -Wdeclaration-after-statement
+       CFLAGS_WARNINGS=-Wall -Wold-style-definition -Wstrict-prototypes -Wsign-compare -Wdeclaration-after-statement -Wmissing-prototypes
        LDFLAGS_D3D=
 endif
 
index e1c7f647d8eb17f90d1fd9065fc9c48dd432071e..06a5ba9274c6970c87d2c5fd9aa25166aef22676 100644 (file)
--- a/mathlib.h
+++ b/mathlib.h
@@ -293,5 +293,7 @@ void BoxFromPoints(vec3_t mins, vec3_t maxs, int numpoints, vec_t *point3f);
 
 int LoopingFrameNumberFromDouble(double t, int loopframes);
 
+void Mathlib_Init(void);
+
 #endif
 
diff --git a/menu.c b/menu.c
index f61dc5e8b4b7862d3a31986ba0646e71e6957bfe..ba50efde0619441e97ff764ea86fd5f450a7824b 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -273,7 +273,7 @@ static void M_DrawTextBox(float x, float y, float width, float height)
 M_ToggleMenu
 ================
 */
-void M_ToggleMenu(int mode)
+static void M_ToggleMenu(int mode)
 {
        m_entersound = true;
 
@@ -308,7 +308,7 @@ static void M_Demo_Draw (void)
 }
 
 
-void M_Menu_Demos_f (void)
+static void M_Menu_Demos_f (void)
 {
        key_dest = key_menu;
        m_state = m_demo;
@@ -318,6 +318,7 @@ void M_Menu_Demos_f (void)
 
 static void M_Demo_Key (int k, int ascii)
 {
+       char vabuf[1024];
        switch (k)
        {
        case K_ESCAPE:
@@ -328,7 +329,7 @@ static void M_Demo_Key (int k, int ascii)
                S_LocalSound ("sound/misc/menu2.wav");
                m_state = m_none;
                key_dest = key_game;
-               Cbuf_AddText (va ("playdemo %s\n", NehahraDemos[demo_cursor].name));
+               Cbuf_AddText (va(vabuf, sizeof(vabuf), "playdemo %s\n", NehahraDemos[demo_cursor].name));
                return;
 
        case K_UPARROW:
@@ -431,6 +432,7 @@ static void M_Main_Draw (void)
 {
        int             f;
        cachepic_t      *p;
+       char vabuf[1024];
 
        if (m_missingdata)
        {
@@ -460,14 +462,14 @@ static void M_Main_Draw (void)
                {
                        if (MAIN_ITEMS == 7 && y1 == 4)
                                y1++;
-                       M_DrawPic (0, y2, va("gfx/menu/mainmenu%i", y1));
+                       M_DrawPic (0, y2, va(vabuf, sizeof(vabuf), "gfx/menu/mainmenu%i", y1));
                        y2 += 40;
                }
                if (MAIN_ITEMS == 7 && m_main_cursor > 2)
                        y3 = m_main_cursor + 2;
                else
                        y3 = m_main_cursor + 1;
-               M_DrawPic (0, 120 + m_main_cursor * 40, va("gfx/menu/mainmenu%iselected", y3));
+               M_DrawPic (0, 120 + m_main_cursor * 40, va(vabuf, sizeof(vabuf), "gfx/menu/mainmenu%iselected", y3));
                return;
        }
 
@@ -490,7 +492,7 @@ static void M_Main_Draw (void)
 
        f = (int)(realtime * 10)%6;
 
-       M_DrawPic (54, 32 + m_main_cursor * 20, va("gfx/menudot%i", f+1));
+       M_DrawPic (54, 32 + m_main_cursor * 20, va(vabuf, sizeof(vabuf), "gfx/menudot%i", f+1));
 }
 
 
@@ -743,6 +745,7 @@ void M_Menu_SinglePlayer_f (void)
 static void M_SinglePlayer_Draw (void)
 {
        cachepic_t      *p;
+       char vabuf[1024];
 
        M_Background(320, 200);
 
@@ -770,7 +773,7 @@ static void M_SinglePlayer_Draw (void)
 
                f = (int)(realtime * 10)%6;
 
-               M_DrawPic (54, 32 + m_singleplayer_cursor * 20, va("gfx/menudot%i", f+1));
+               M_DrawPic (54, 32 + m_singleplayer_cursor * 20, va(vabuf, sizeof(vabuf), "gfx/menudot%i", f+1));
        }
 }
 
@@ -949,6 +952,7 @@ static void M_Save_Draw (void)
 
 static void M_Load_Key (int k, int ascii)
 {
+       char vabuf[1024];
        switch (k)
        {
        case K_ESCAPE:
@@ -966,7 +970,7 @@ static void M_Load_Key (int k, int ascii)
                key_dest = key_game;
 
                // issue the load command
-               Cbuf_AddText (va ("load s%i\n", load_cursor) );
+               Cbuf_AddText (va(vabuf, sizeof(vabuf), "load s%i\n", load_cursor) );
                return;
 
        case K_UPARROW:
@@ -990,6 +994,7 @@ static void M_Load_Key (int k, int ascii)
 
 static void M_Save_Key (int k, int ascii)
 {
+       char vabuf[1024];
        switch (k)
        {
        case K_ESCAPE:
@@ -1002,7 +1007,7 @@ static void M_Save_Key (int k, int ascii)
        case K_ENTER:
                m_state = m_none;
                key_dest = key_game;
-               Cbuf_AddText (va("save s%i\n", load_cursor));
+               Cbuf_AddText (va(vabuf, sizeof(vabuf), "save s%i\n", load_cursor));
                return;
 
        case K_UPARROW:
@@ -1040,15 +1045,16 @@ static void M_Transfusion_Episode_Draw (void)
 {
        int y;
        cachepic_t *p;
+       char vabuf[1024];
        M_Background(640, 480);
 
        p = Draw_CachePic ("gfx/menu/tb-episodes");
        M_DrawPic (640/2 - p->width/2, 40, "gfx/menu/tb-episodes");
        for (y = 0; y < EPISODE_ITEMS; y++){
-               M_DrawPic (0, 160 + y * 40, va("gfx/menu/episode%i", y+1));
+               M_DrawPic (0, 160 + y * 40, va(vabuf, sizeof(vabuf), "gfx/menu/episode%i", y+1));
        }
 
-       M_DrawPic (0, 120 + (m_episode_cursor + 1) * 40, va("gfx/menu/episode%iselected", m_episode_cursor + 1));
+       M_DrawPic (0, 120 + (m_episode_cursor + 1) * 40, va(vabuf, sizeof(vabuf), "gfx/menu/episode%iselected", m_episode_cursor + 1));
 }
 
 static void M_Transfusion_Episode_Key (int key, int ascii)
@@ -1097,6 +1103,7 @@ static void M_Transfusion_Skill_Draw (void)
 {
        int y;
        cachepic_t      *p;
+       char vabuf[1024];
        M_Background(640, 480);
 
        p = Draw_CachePic ("gfx/menu/tb-difficulty");
@@ -1104,9 +1111,9 @@ static void M_Transfusion_Skill_Draw (void)
 
        for (y = 0; y < SKILL_ITEMS; y++)
        {
-               M_DrawPic (0, 180 + y * 40, va("gfx/menu/difficulty%i", y+1));
+               M_DrawPic (0, 180 + y * 40, va(vabuf, sizeof(vabuf), "gfx/menu/difficulty%i", y+1));
        }
-       M_DrawPic (0, 140 + (m_skill_cursor + 1) *40, va("gfx/menu/difficulty%iselected", m_skill_cursor + 1));
+       M_DrawPic (0, 140 + (m_skill_cursor + 1) *40, va(vabuf, sizeof(vabuf), "gfx/menu/difficulty%iselected", m_skill_cursor + 1));
 }
 
 static void M_Transfusion_Skill_Key (int key, int ascii)
@@ -1199,6 +1206,7 @@ static void M_MultiPlayer_Draw (void)
 {
        int             f;
        cachepic_t      *p;
+       char vabuf[1024];
 
        if (gamemode == GAME_TRANSFUSION)
        {
@@ -1206,8 +1214,8 @@ static void M_MultiPlayer_Draw (void)
                p = Draw_CachePic ("gfx/menu/tb-online");
                M_DrawPic (640/2 - p->width/2, 140, "gfx/menu/tb-online");
                for (f = 1; f <= MULTIPLAYER_ITEMS; f++)
-                       M_DrawPic (0, 180 + f*40, va("gfx/menu/online%i", f));
-               M_DrawPic (0, 220 + m_multiplayer_cursor * 40, va("gfx/menu/online%iselected", m_multiplayer_cursor + 1));
+                       M_DrawPic (0, 180 + f*40, va(vabuf, sizeof(vabuf), "gfx/menu/online%i", f));
+               M_DrawPic (0, 220 + m_multiplayer_cursor * 40, va(vabuf, sizeof(vabuf), "gfx/menu/online%iselected", m_multiplayer_cursor + 1));
                return;
        }
        M_Background(320, 200);
@@ -1219,7 +1227,7 @@ static void M_MultiPlayer_Draw (void)
 
        f = (int)(realtime * 10)%6;
 
-       M_DrawPic (54, 32 + m_multiplayer_cursor * 20, va("gfx/menudot%i", f+1));
+       M_DrawPic (54, 32 + m_multiplayer_cursor * 20, va(vabuf, sizeof(vabuf), "gfx/menudot%i", f+1));
 }
 
 
@@ -1327,6 +1335,7 @@ static void M_Setup_Draw (void)
 {
        int i, j;
        cachepic_t      *p;
+       char vabuf[1024];
 
        M_Background(320, 200);
 
@@ -1345,7 +1354,7 @@ static void M_Setup_Draw (void)
        }
 
        M_Print(64, 124-8, "Network speed limit");
-       M_Print(168, 124, va("%i (%s)", setup_rate, setup_ratetable[setup_rateindex(setup_rate)].name));
+       M_Print(168, 124, va(vabuf, sizeof(vabuf), "%i (%s)", setup_rate, setup_ratetable[setup_rateindex(setup_rate)].name));
 
        M_DrawTextBox (64, 140-8, 14, 1);
        M_Print(72, 140, "Accept Changes");
@@ -1419,6 +1428,7 @@ static void M_Setup_Draw (void)
 static void M_Setup_Key (int k, int ascii)
 {
        int                     l;
+       char vabuf[1024];
 
        switch (k)
        {
@@ -1483,11 +1493,11 @@ forward:
 
                // setup_cursor == 4 (Accept changes)
                if (strcmp(cl_name.string, setup_myname) != 0)
-                       Cbuf_AddText ( va ("name \"%s\"\n", setup_myname) );
+                       Cbuf_AddText(va(vabuf, sizeof(vabuf), "name \"%s\"\n", setup_myname) );
                if (setup_top != setup_oldtop || setup_bottom != setup_oldbottom)
-                       Cbuf_AddText( va ("color %i %i\n", setup_top, setup_bottom) );
+                       Cbuf_AddText(va(vabuf, sizeof(vabuf), "color %i %i\n", setup_top, setup_bottom) );
                if (setup_rate != setup_oldrate)
-                       Cbuf_AddText(va("rate %i\n", setup_rate));
+                       Cbuf_AddText(va(vabuf, sizeof(vabuf), "rate %i\n", setup_rate));
 
                m_entersound = true;
                M_Menu_MultiPlayer_f ();
@@ -2629,6 +2639,7 @@ static void M_Keys_Draw (void)
                        strlcpy(keystring, "???", sizeof(keystring));
                else
                {
+                       char tinystr[2];
                        keystring[0] = 0;
                        for (j = 0;j < NUMKEYS;j++)
                        {
@@ -2636,7 +2647,7 @@ static void M_Keys_Draw (void)
                                {
                                        if (j > 0)
                                                strlcat(keystring, " or ", sizeof(keystring));
-                                       strlcat(keystring, Key_KeynumToString (keys[j]), sizeof(keystring));
+                                       strlcat(keystring, Key_KeynumToString (keys[j], tinystr, sizeof(tinystr)), sizeof(keystring));
                                }
                        }
                }
@@ -2654,6 +2665,7 @@ static void M_Keys_Key (int k, int ascii)
 {
        char    cmd[80];
        int             keys[NUMKEYS];
+       char    tinystr[2];
 
        if (bind_grab)
        {       // defining a key
@@ -2664,7 +2676,7 @@ static void M_Keys_Key (int k, int ascii)
                }
                else //if (k != '`')
                {
-                       dpsnprintf (cmd, sizeof(cmd), "bind \"%s\" \"%s\"\n", Key_KeynumToString (k), bindnames[keys_cursor][0]);
+                       dpsnprintf (cmd, sizeof(cmd), "bind \"%s\" \"%s\"\n", Key_KeynumToString (k, tinystr, sizeof(tinystr)), bindnames[keys_cursor][0]);
                        Cbuf_InsertText (cmd);
                }
 
@@ -2896,6 +2908,7 @@ static void M_Video_Draw (void)
 {
        int t;
        cachepic_t      *p;
+       char vabuf[1024];
 
        if(!!vid_fullscreen.integer != menu_video_resolutions_forfullscreen)
        {
@@ -2915,12 +2928,12 @@ static void M_Video_Draw (void)
        // Current and Proposed Resolution
        M_Print(16, video_cursor_table[t] - 12, "    Current Resolution");
        if (vid_supportrefreshrate && vid.userefreshrate && vid.fullscreen)
-               M_Print(220, video_cursor_table[t] - 12, va("%dx%d %.2fhz", vid.width, vid.height, vid.refreshrate));
+               M_Print(220, video_cursor_table[t] - 12, va(vabuf, sizeof(vabuf), "%dx%d %.2fhz", vid.width, vid.height, vid.refreshrate));
        else
-               M_Print(220, video_cursor_table[t] - 12, va("%dx%d", vid.width, vid.height));
+               M_Print(220, video_cursor_table[t] - 12, va(vabuf, sizeof(vabuf), "%dx%d", vid.width, vid.height));
        M_Print(16, video_cursor_table[t], "        New Resolution");
-       M_Print(220, video_cursor_table[t], va("%dx%d", menu_video_resolutions[menu_video_resolution].width, menu_video_resolutions[menu_video_resolution].height));
-       M_Print(96, video_cursor_table[t] + 8, va("Type: %s", menu_video_resolutions[menu_video_resolution].type));
+       M_Print(220, video_cursor_table[t], va(vabuf, sizeof(vabuf), "%dx%d", menu_video_resolutions[menu_video_resolution].width, menu_video_resolutions[menu_video_resolution].height));
+       M_Print(96, video_cursor_table[t] + 8, va(vabuf, sizeof(vabuf), "Type: %s", menu_video_resolutions[menu_video_resolution].type));
        t++;
 
        // Bits per pixel
@@ -3095,8 +3108,9 @@ void M_Menu_Help_f (void)
 
 static void M_Help_Draw (void)
 {
+       char vabuf[1024];
        M_Background(320, 200);
-       M_DrawPic (0, 0, va("gfx/help%i", help_page));
+       M_DrawPic (0, 0, va(vabuf, sizeof(vabuf), "gfx/help%i", help_page));
 }
 
 
@@ -3342,6 +3356,7 @@ static void M_LanConfig_Draw (void)
        int             basex;
        const char      *startJoin;
        const char      *protocol;
+       char vabuf[1024];
 
        M_Background(320, 200);
 
@@ -3355,7 +3370,7 @@ static void M_LanConfig_Draw (void)
        else
                startJoin = "Join Game";
        protocol = "TCP/IP";
-       M_Print(basex, 32, va ("%s - %s", startJoin, protocol));
+       M_Print(basex, 32, va(vabuf, sizeof(vabuf), "%s - %s", startJoin, protocol));
        basex += 8;
 
        M_Print(basex, lanConfig_cursor_table[0], "Port");
@@ -3392,6 +3407,7 @@ static void M_LanConfig_Draw (void)
 static void M_LanConfig_Key (int key, int ascii)
 {
        int             l;
+       char vabuf[1024];
 
        switch (key)
        {
@@ -3441,7 +3457,7 @@ static void M_LanConfig_Key (int key, int ascii)
                }
 
                if (lanConfig_cursor == 3)
-                       Cbuf_AddText ( va ("connect \"%s\"\n", lanConfig_joinname) );
+                       Cbuf_AddText(va(vabuf, sizeof(vabuf), "connect \"%s\"\n", lanConfig_joinname) );
                break;
 
        case K_BACKSPACE:
@@ -3963,6 +3979,7 @@ void M_GameOptions_Draw (void)
 {
        cachepic_t      *p;
        int             x;
+       char vabuf[1024];
 
        M_Background(320, 200);
 
@@ -3974,7 +3991,7 @@ void M_GameOptions_Draw (void)
        M_Print(160, 40, "begin game");
 
        M_Print(0, 56, "      Max players");
-       M_Print(160, 56, va("%i", maxplayers) );
+       M_Print(160, 56, va(vabuf, sizeof(vabuf), "%i", maxplayers) );
 
        if (gamemode != GAME_GOODVSBAD2)
        {
@@ -4067,20 +4084,20 @@ void M_GameOptions_Draw (void)
                if (fraglimit.integer == 0)
                        M_Print(160, 88, "none");
                else
-                       M_Print(160, 88, va("%i frags", fraglimit.integer));
+                       M_Print(160, 88, va(vabuf, sizeof(vabuf), "%i frags", fraglimit.integer));
 
                M_Print(0, 96, "       Time Limit");
                if (timelimit.integer == 0)
                        M_Print(160, 96, "none");
                else
-                       M_Print(160, 96, va("%i minutes", timelimit.integer));
+                       M_Print(160, 96, va(vabuf, sizeof(vabuf), "%i minutes", timelimit.integer));
        }
 
        M_Print(0, 104, "    Public server");
        M_Print(160, 104, (sv_public.integer == 0) ? "no" : "yes");
 
        M_Print(0, 112, "   Server maxrate");
-       M_Print(160, 112, va("%i", sv_maxrate.integer));
+       M_Print(160, 112, va(vabuf, sizeof(vabuf), "%i", sv_maxrate.integer));
 
        M_Print(0, 128, "      Server name");
        M_DrawTextBox (0, 132, 38, 1);
@@ -4284,6 +4301,7 @@ static void M_GameOptions_Key (int key, int ascii)
 {
        int l;
        char hostnamebuf[128];
+       char vabuf[1024];
 
        switch (key)
        {
@@ -4324,10 +4342,10 @@ static void M_GameOptions_Key (int key, int ascii)
                if (gameoptions_cursor == 0)
                {
                        if (sv.active)
-                               Cbuf_AddText ("disconnect\n");
-                       Cbuf_AddText ( va ("maxplayers %u\n", maxplayers) );
+                               Cbuf_AddText("disconnect\n");
+                       Cbuf_AddText(va(vabuf, sizeof(vabuf), "maxplayers %u\n", maxplayers) );
 
-                       Cbuf_AddText ( va ("map %s\n", gameoptions_levels->levels[gameoptions_levels->episodes[startepisode].firstLevel + startlevel].name) );
+                       Cbuf_AddText(va(vabuf, sizeof(vabuf), "map %s\n", gameoptions_levels->levels[gameoptions_levels->episodes[startepisode].firstLevel + startlevel].name) );
                        return;
                }
 
@@ -4389,6 +4407,7 @@ static void M_ServerList_Draw (void)
        int n, y, visible, start, end, numplayers, maxplayers;
        cachepic_t *p;
        const char *s;
+       char vabuf[1024];
 
        // use as much vertical space as available
        if (gamemode == GAME_TRANSFUSION)
@@ -4397,7 +4416,7 @@ static void M_ServerList_Draw (void)
                M_Background(640, vid_conheight.integer);
        // scroll the list as the cursor moves
        ServerList_GetPlayerStatistics(&numplayers, &maxplayers);
-       s = va("%i/%i masters %i/%i servers %i/%i players", masterreplycount, masterquerycount, serverreplycount, serverquerycount, numplayers, maxplayers);
+       s = va(vabuf, sizeof(vabuf), "%i/%i masters %i/%i servers %i/%i players", masterreplycount, masterquerycount, serverreplycount, serverquerycount, numplayers, maxplayers);
        M_PrintRed((640 - strlen(s) * 8) / 2, 32, s);
        if (*m_return_reason)
                M_Print(16, menu_height - 8, m_return_reason);
@@ -4437,6 +4456,7 @@ static void M_ServerList_Draw (void)
 
 static void M_ServerList_Key(int k, int ascii)
 {
+       char vabuf[1024];
        switch (k)
        {
        case K_ESCAPE:
@@ -4469,7 +4489,7 @@ static void M_ServerList_Key(int k, int ascii)
        case K_ENTER:
                S_LocalSound ("sound/misc/menu2.wav");
                if (serverlist_viewcount)
-                       Cbuf_AddText(va("connect \"%s\"\n", ServerList_GetViewEntry(slist_cursor)->info.cname));
+                       Cbuf_AddText(va(vabuf, sizeof(vabuf), "connect \"%s\"\n", ServerList_GetViewEntry(slist_cursor)->info.cname));
                break;
 
        default:
@@ -4502,7 +4522,7 @@ static int modlist_cursor;
 static int modlist_count = 0;
 static modlist_entry_t modlist[MODLIST_TOTALSIZE];
 
-void ModList_RebuildList(void)
+static void ModList_RebuildList(void)
 {
        int i,j;
        stringlist_t list;
@@ -4539,7 +4559,7 @@ void ModList_RebuildList(void)
        stringlistfreecontents(&list);
 }
 
-void ModList_Enable (void)
+static void ModList_Enable (void)
 {
        int i;
        int numgamedirs;
@@ -4708,7 +4728,7 @@ static void M_Draw(void);
 void M_ToggleMenu(int mode);
 static void M_Shutdown(void);
 
-void M_Init (void)
+static void M_Init (void)
 {
        menuplyr_load = true;
        menuplyr_pixels = NULL;
@@ -4736,6 +4756,7 @@ void M_Init (void)
 
 void M_Draw (void)
 {
+       char vabuf[1024];
        if (key_dest != key_menu && key_dest != key_menu_grabbed)
                m_state = m_none;
 
@@ -4849,7 +4870,7 @@ void M_Draw (void)
                        g = (int)(realtime * 64)%96;
                        scale_y_rate = (float)(g+1) / 96;
                        top_offset = (g+12)/12;
-                       p = Draw_CachePic (va("gfx/menu/blooddrip%i", top_offset));
+                       p = Draw_CachePic (va(vabuf, sizeof(vabuf), "gfx/menu/blooddrip%i", top_offset));
                        drop1 = Draw_CachePic ("gfx/menu/blooddrop1");
                        drop2 = Draw_CachePic ("gfx/menu/blooddrop2");
                        drop3 = Draw_CachePic ("gfx/menu/blooddrop3");
@@ -4867,7 +4888,7 @@ void M_Draw (void)
                                        DrawQ_Pic (scale_x + 557, scale_y_repeat * .9425 + scale_y + scale_y_rate * scale_y_repeat, drop1, 0, 0, 1, 1, 1, 1, 0);
                                        DrawQ_Pic (scale_x + 606, scale_y_repeat * .5 + scale_y + scale_y_rate * scale_y_repeat, drop2, 0, 0, 1, 1, 1, 1, 0);
                                }
-                               DrawQ_Pic (scale_x, -1, Draw_CachePic (va("gfx/menu/blooddrip%i", top_offset)), 0, 0, 1, 1, 1, 1, 0);
+                               DrawQ_Pic (scale_x, -1, Draw_CachePic (va(vabuf, sizeof(vabuf), "gfx/menu/blooddrip%i", top_offset)), 0, 0, 1, 1, 1, 1, 0);
                        }
                }
        }
@@ -4986,7 +5007,7 @@ void M_KeyEvent (int key, int ascii, qboolean downevent)
 
 }
 
-void M_NewMap(void)
+static void M_NewMap(void)
 {
 }
 
@@ -5169,9 +5190,10 @@ static int m_numrequiredglobals = sizeof(m_required_globals) / sizeof(m_required
 
 void MR_SetRouting (qboolean forceold);
 
-void MP_Error(const char *format, ...) DP_FUNC_PRINTF(1);
-void MP_Error(const char *format, ...)
+void MVM_error_cmd(const char *format, ...) DP_FUNC_PRINTF(1);
+void MVM_error_cmd(const char *format, ...)
 {
+       prvm_prog_t *prog = MVM_prog;
        static qboolean processingError = false;
        char errorstring[MAX_INPUTLINE];
        va_list argptr;
@@ -5183,10 +5205,10 @@ void MP_Error(const char *format, ...)
 
        if( !processingError ) {
                processingError = true;
-               PRVM_Crash();
+               PRVM_Crash(prog);
                processingError = false;
        } else {
-               Con_Printf( "Menu_Error: Recursive call to MP_Error (from PRVM_Crash)!\n" );
+               Con_Printf( "Menu_Error: Recursive call to MVM_error_cmd (from PRVM_Crash)!\n" );
        }
 
        // fall back to the normal menu
@@ -5205,24 +5227,62 @@ void MP_Error(const char *format, ...)
        Host_AbortCurrentFrame();
 }
 
-void MP_KeyEvent (int key, int ascii, qboolean downevent)
+static void MVM_begin_increase_edicts(prvm_prog_t *prog)
+{
+}
+
+static void MVM_end_increase_edicts(prvm_prog_t *prog)
+{
+}
+
+static void MVM_init_edict(prvm_prog_t *prog, prvm_edict_t *edict)
+{
+}
+
+static void MVM_free_edict(prvm_prog_t *prog, prvm_edict_t *ed)
+{
+}
+
+static void MVM_count_edicts(prvm_prog_t *prog)
+{
+       int i;
+       prvm_edict_t *ent;
+       int active;
+
+       active = 0;
+       for (i=0 ; i<prog->num_edicts ; i++)
+       {
+               ent = PRVM_EDICT_NUM(i);
+               if (ent->priv.required->free)
+                       continue;
+               active++;
+       }
+
+       Con_Printf("num_edicts:%3i\n", prog->num_edicts);
+       Con_Printf("active    :%3i\n", active);
+}
+
+static qboolean MVM_load_edict(prvm_prog_t *prog, prvm_edict_t *ent)
+{
+       return true;
+}
+
+static void MP_KeyEvent (int key, int ascii, qboolean downevent)
 {
-       PRVM_Begin;
-       PRVM_SetProg(PRVM_MENUPROG);
+       prvm_prog_t *prog = MVM_prog;
 
        // pass key
        prog->globals.generic[OFS_PARM0] = (float) key;
        prog->globals.generic[OFS_PARM1] = (float) ascii;
        if (downevent)
-               PRVM_ExecuteProgram(PRVM_menufunction(m_keydown),"m_keydown(float key, float ascii) required");
+               prog->ExecuteProgram(prog, PRVM_menufunction(m_keydown),"m_keydown(float key, float ascii) required");
        else if (PRVM_menufunction(m_keyup))
-               PRVM_ExecuteProgram(PRVM_menufunction(m_keyup),"m_keyup(float key, float ascii) required");
-
-       PRVM_End;
+               prog->ExecuteProgram(prog, PRVM_menufunction(m_keyup),"m_keyup(float key, float ascii) required");
 }
 
-void MP_Draw (void)
+static void MP_Draw (void)
 {
+       prvm_prog_t *prog = MVM_prog;
        // declarations that are needed right now
 
        float oldquality;
@@ -5238,14 +5298,9 @@ void MP_Draw (void)
        // TODO: this needs to be exposed to R_SetView (or something similar) ASAP [2/5/2008 Andreas]
        r_refdef.scene.time = realtime;
 
-       PRVM_Begin;
-       PRVM_SetProg(PRVM_MENUPROG);
-
        // FIXME: this really shouldnt error out lest we have a very broken refdef state...?
        // or does it kill the server too?
-       PRVM_ExecuteProgram(PRVM_menufunction(m_draw),"m_draw() required");
-
-       PRVM_End;
+       prog->ExecuteProgram(prog, PRVM_menufunction(m_draw),"m_draw() required");
 
        // TODO: imo this should be moved into scene, too [1/27/2008 Andreas]
        r_refdef.view.quality = oldquality;
@@ -5253,63 +5308,63 @@ void MP_Draw (void)
        R_SelectScene( RST_CLIENT );
 }
 
-void MP_ToggleMenu(int mode)
+static void MP_ToggleMenu(int mode)
 {
-       PRVM_Begin;
-       PRVM_SetProg(PRVM_MENUPROG);
+       prvm_prog_t *prog = MVM_prog;
 
        prog->globals.generic[OFS_PARM0] = (float) mode;
-       PRVM_ExecuteProgram(PRVM_menufunction(m_toggle),"m_toggle() required");
-
-       PRVM_End;
+       prog->ExecuteProgram(prog, PRVM_menufunction(m_toggle),"m_toggle() required");
 }
 
-void MP_NewMap(void)
+static void MP_NewMap(void)
 {
-       PRVM_Begin;
-       PRVM_SetProg(PRVM_MENUPROG);
+       prvm_prog_t *prog = MVM_prog;
        if (PRVM_menufunction(m_newmap))
-               PRVM_ExecuteProgram(PRVM_menufunction(m_newmap),"m_newmap() required");
-       PRVM_End;
+               prog->ExecuteProgram(prog, PRVM_menufunction(m_newmap),"m_newmap() required");
 }
 
-void MP_Shutdown (void)
+static void MP_Shutdown (void)
 {
-       PRVM_Begin;
-       PRVM_SetProg(PRVM_MENUPROG);
+       prvm_prog_t *prog = MVM_prog;
 
-       PRVM_ExecuteProgram(PRVM_menufunction(m_shutdown),"m_shutdown() required");
+       prog->ExecuteProgram(prog, PRVM_menufunction(m_shutdown),"m_shutdown() required");
 
        // reset key_dest
        key_dest = key_game;
 
        // AK not using this cause Im not sure whether this is useful at all instead :
-       PRVM_ResetProg();
-
-       PRVM_End;
+       PRVM_Prog_Reset(prog);
 }
 
-void MP_Init (void)
+static void MP_Init (void)
 {
-       PRVM_Begin;
-       PRVM_InitProg(PRVM_MENUPROG);
+       prvm_prog_t *prog = MVM_prog;
+       PRVM_Prog_Init(prog);
 
        prog->edictprivate_size = 0; // no private struct used
-       prog->name = M_NAME;
+       prog->name = "menu";
        prog->num_edicts = 1;
        prog->limit_edicts = M_MAX_EDICTS;
        prog->extensionstring = vm_m_extensions;
        prog->builtins = vm_m_builtins;
        prog->numbuiltins = vm_m_numbuiltins;
-       prog->init_cmd = VM_M_Cmd_Init;
-       prog->reset_cmd = VM_M_Cmd_Reset;
-       prog->error_cmd = MP_Error;
-       prog->ExecuteProgram = MVM_ExecuteProgram;
+
+       // all callbacks must be defined (pointers are not checked before calling)
+       prog->begin_increase_edicts = MVM_begin_increase_edicts;
+       prog->end_increase_edicts   = MVM_end_increase_edicts;
+       prog->init_edict            = MVM_init_edict;
+       prog->free_edict            = MVM_free_edict;
+       prog->count_edicts          = MVM_count_edicts;
+       prog->load_edict            = MVM_load_edict;
+       prog->init_cmd              = MVM_init_cmd;
+       prog->reset_cmd             = MVM_reset_cmd;
+       prog->error_cmd             = MVM_error_cmd;
+       prog->ExecuteProgram        = MVM_ExecuteProgram;
 
        // allocate the mempools
        prog->progs_mempool = Mem_AllocPool(M_PROG_FILENAME, 0, NULL);
 
-       PRVM_LoadProgs(M_PROG_FILENAME, m_numrequiredfunc, m_required_func, m_numrequiredfields, m_required_fields, m_numrequiredglobals, m_required_globals);
+       PRVM_Prog_Load(prog, M_PROG_FILENAME, m_numrequiredfunc, m_required_func, m_numrequiredfields, m_required_fields, m_numrequiredglobals, m_required_globals);
 
        // note: OP_STATE is not supported by menu qc, we don't even try to detect
        // it here
@@ -5317,9 +5372,7 @@ void MP_Init (void)
        in_client_mouse = true;
 
        // call the prog init
-       PRVM_ExecuteProgram(PRVM_menufunction(m_init),"m_init() required");
-
-       PRVM_End;
+       prog->ExecuteProgram(prog, PRVM_menufunction(m_init),"m_init() required");
 }
 
 //============================================================================
@@ -5363,7 +5416,7 @@ void MR_Restart(void)
        MR_SetRouting (FALSE);
 }
 
-void Call_MR_ToggleMenu_f(void)
+static void Call_MR_ToggleMenu_f(void)
 {
        int m;
        m = ((Cmd_Argc() < 2) ? -1 : atoi(Cmd_Argv(1)));
diff --git a/menu.h b/menu.h
index 1ca8799b6bb185ff189f24b5b956822ecef414c6..aac8a4bc52dbdc48cb3e0904c69fbbbdc3b6f120 100644 (file)
--- a/menu.h
+++ b/menu.h
@@ -22,7 +22,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #define MENU_H
 
 #define M_PROG_FILENAME "menu.dat"
-#define M_NAME "menu"
 
 enum m_state_e {
        m_none,
index 81ffff781080c3606ce5515e615353f0f8820257..bf8af921909aacc87df24043bdbd66472cd1b168 100644 (file)
@@ -61,7 +61,7 @@ void *Mod_Skeletal_AnimateVertices_AllocBuffers(size_t nbytes)
        return Mod_Skeletal_AnimateVertices_bonepose;
 }
 
-void Mod_Skeletal_AnimateVertices(const dp_model_t * RESTRICT model, const frameblend_t * RESTRICT frameblend, const skeleton_t *skeleton, float * RESTRICT vertex3f, float * RESTRICT normal3f, float * RESTRICT svector3f, float * RESTRICT tvector3f)
+static void Mod_Skeletal_AnimateVertices(const dp_model_t * RESTRICT model, const frameblend_t * RESTRICT frameblend, const skeleton_t *skeleton, float * RESTRICT vertex3f, float * RESTRICT normal3f, float * RESTRICT svector3f, float * RESTRICT tvector3f)
 {
 
        if (!model->surfmesh.num_vertices)
@@ -113,7 +113,7 @@ void Mod_AliasInit (void)
 #endif
 }
 
-int Mod_Skeletal_AddBlend(dp_model_t *model, const blendweights_t *newweights)
+static int Mod_Skeletal_AddBlend(dp_model_t *model, const blendweights_t *newweights)
 {
        int i;
        blendweights_t *weights;
@@ -130,7 +130,7 @@ int Mod_Skeletal_AddBlend(dp_model_t *model, const blendweights_t *newweights)
        return model->num_bones + i;
 }
 
-int Mod_Skeletal_CompressBlend(dp_model_t *model, const int *newindex, const float *newinfluence)
+static int Mod_Skeletal_CompressBlend(dp_model_t *model, const int *newindex, const float *newinfluence)
 {
        int i, total;
        float scale;
@@ -173,7 +173,7 @@ int Mod_Skeletal_CompressBlend(dp_model_t *model, const int *newindex, const flo
        return Mod_Skeletal_AddBlend(model, &newweights);
 }
 
-void Mod_MD3_AnimateVertices(const dp_model_t * RESTRICT model, const frameblend_t * RESTRICT frameblend, const skeleton_t *skeleton, float * RESTRICT vertex3f, float * RESTRICT normal3f, float * RESTRICT svector3f, float * RESTRICT tvector3f)
+static void Mod_MD3_AnimateVertices(const dp_model_t * RESTRICT model, const frameblend_t * RESTRICT frameblend, const skeleton_t *skeleton, float * RESTRICT vertex3f, float * RESTRICT normal3f, float * RESTRICT svector3f, float * RESTRICT tvector3f)
 {
        // vertex morph
        int i, numblends, blendnum;
@@ -261,7 +261,7 @@ void Mod_MD3_AnimateVertices(const dp_model_t * RESTRICT model, const frameblend
                }
        }
 }
-void Mod_MDL_AnimateVertices(const dp_model_t * RESTRICT model, const frameblend_t * RESTRICT frameblend, const skeleton_t *skeleton, float * RESTRICT vertex3f, float * RESTRICT normal3f, float * RESTRICT svector3f, float * RESTRICT tvector3f)
+static void Mod_MDL_AnimateVertices(const dp_model_t * RESTRICT model, const frameblend_t * RESTRICT frameblend, const skeleton_t *skeleton, float * RESTRICT vertex3f, float * RESTRICT normal3f, float * RESTRICT svector3f, float * RESTRICT tvector3f)
 {
        // vertex morph
        int i, numblends, blendnum;
@@ -643,19 +643,14 @@ static void Mod_MDLMD2MD3_TraceLine(dp_model_t *model, const frameblend_t *frame
        int i;
        float segmentmins[3], segmentmaxs[3];
        msurface_t *surface;
-       static int maxvertices = 0;
-       static float *vertex3f = NULL;
+       float vertex3fbuf[1024*3];
+       float *vertex3f = vertex3fbuf;
        memset(trace, 0, sizeof(*trace));
        trace->fraction = 1;
        trace->realfraction = 1;
        trace->hitsupercontentsmask = hitsupercontentsmask;
-       if (maxvertices < model->surfmesh.num_vertices)
-       {
-               if (vertex3f)
-                       Z_Free(vertex3f);
-               maxvertices = (model->surfmesh.num_vertices + 255) & ~255;
-               vertex3f = (float *)Z_Malloc(maxvertices * sizeof(float[3]));
-       }
+       if (model->surfmesh.num_vertices > 1024)
+               vertex3f = Mem_Alloc(tempmempool, model->surfmesh.num_vertices * sizeof(float[3]));
        segmentmins[0] = min(start[0], end[0]) - 1;
        segmentmins[1] = min(start[1], end[1]) - 1;
        segmentmins[2] = min(start[2], end[2]) - 1;
@@ -665,17 +660,18 @@ static void Mod_MDLMD2MD3_TraceLine(dp_model_t *model, const frameblend_t *frame
        model->AnimateVertices(model, frameblend, skeleton, vertex3f, NULL, NULL, NULL);
        for (i = 0, surface = model->data_surfaces;i < model->num_surfaces;i++, surface++)
                Collision_TraceLineTriangleMeshFloat(trace, start, end, model->surfmesh.num_triangles, model->surfmesh.data_element3i, vertex3f, 0, NULL, SUPERCONTENTS_SOLID | (surface->texture->basematerialflags & MATERIALFLAGMASK_TRANSLUCENT ? 0 : SUPERCONTENTS_OPAQUE), 0, surface->texture, segmentmins, segmentmaxs);
+       if (vertex3f != vertex3fbuf)
+               Mem_Free(vertex3f);
 }
 
-static int maxvertices = 0;
-static float *vertex3f = NULL;
-
 static void Mod_MDLMD2MD3_TraceBox(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask)
 {
        int i;
        vec3_t shiftstart, shiftend;
        float segmentmins[3], segmentmaxs[3];
        msurface_t *surface;
+       float vertex3fbuf[1024*3];
+       float *vertex3f = vertex3fbuf;
        colboxbrushf_t thisbrush_start, thisbrush_end;
        vec3_t boxstartmins, boxstartmaxs, boxendmins, boxendmaxs;
 
@@ -693,13 +689,8 @@ static void Mod_MDLMD2MD3_TraceBox(dp_model_t *model, const frameblend_t *frameb
        trace->fraction = 1;
        trace->realfraction = 1;
        trace->hitsupercontentsmask = hitsupercontentsmask;
-       if (maxvertices < model->surfmesh.num_vertices)
-       {
-               if (vertex3f)
-                       Z_Free(vertex3f);
-               maxvertices = (model->surfmesh.num_vertices + 255) & ~255;
-               vertex3f = (float *)Z_Malloc(maxvertices * sizeof(float[3]));
-       }
+       if (model->surfmesh.num_vertices > 1024)
+               vertex3f = Mem_Alloc(tempmempool, model->surfmesh.num_vertices * sizeof(float[3]));
        segmentmins[0] = min(start[0], end[0]) + boxmins[0] - 1;
        segmentmins[1] = min(start[1], end[1]) + boxmins[1] - 1;
        segmentmins[2] = min(start[2], end[2]) + boxmins[2] - 1;
@@ -712,16 +703,11 @@ static void Mod_MDLMD2MD3_TraceBox(dp_model_t *model, const frameblend_t *frameb
        VectorAdd(end, boxmaxs, boxendmaxs);
        Collision_BrushForBox(&thisbrush_start, boxstartmins, boxstartmaxs, 0, 0, NULL);
        Collision_BrushForBox(&thisbrush_end, boxendmins, boxendmaxs, 0, 0, NULL);
-       if (maxvertices < model->surfmesh.num_vertices)
-       {
-               if (vertex3f)
-                       Z_Free(vertex3f);
-               maxvertices = (model->surfmesh.num_vertices + 255) & ~255;
-               vertex3f = (float *)Z_Malloc(maxvertices * sizeof(float[3]));
-       }
        model->AnimateVertices(model, frameblend, skeleton, vertex3f, NULL, NULL, NULL);
        for (i = 0, surface = model->data_surfaces;i < model->num_surfaces;i++, surface++)
                Collision_TraceBrushTriangleMeshFloat(trace, &thisbrush_start.brush, &thisbrush_end.brush, model->surfmesh.num_triangles, model->surfmesh.data_element3i, vertex3f, 0, NULL, SUPERCONTENTS_SOLID | (surface->texture->basematerialflags & MATERIALFLAGMASK_TRANSLUCENT ? 0 : SUPERCONTENTS_OPAQUE), 0, surface->texture, segmentmins, segmentmaxs);
+       if (vertex3f != vertex3fbuf)
+               Mem_Free(vertex3f);
 }
 
 static void Mod_ConvertAliasVerts (int inverts, trivertx_t *v, trivertx_t *out, int *vertremap)
@@ -842,7 +828,7 @@ static void Mod_BuildAliasSkinFromSkinFrame(texture_t *texture, skinframe_t *ski
 void Mod_BuildAliasSkinsFromSkinFiles(texture_t *skin, skinfile_t *skinfile, const char *meshname, const char *shadername)
 {
        int i;
-       static char stripbuf[MAX_QPATH];
+       char stripbuf[MAX_QPATH];
        skinfileitem_t *skinfileitem;
        if(developer_extra.integer)
                Con_DPrintf("Looking up texture for %s (default: %s)\n", meshname, shadername);
@@ -908,6 +894,7 @@ void Mod_IDP0_Load(dp_model_t *mod, void *buffer, void *bufferend)
        float *vertst;
        int *vertonseam, *vertremap;
        skinfile_t *skinfiles;
+       char vabuf[1024];
 
        datapointer = (unsigned char *)buffer;
        pinmodel = (mdl_t *)datapointer;
@@ -1186,7 +1173,7 @@ void Mod_IDP0_Load(dp_model_t *mod, void *buffer, void *bufferend)
                // check for skins that don't exist in the model, but do exist as external images
                // (this was added because yummyluv kept pestering me about support for it)
                // TODO: support shaders here?
-               while ((tempskinframe = R_SkinFrame_LoadExternal(va("%s_%i", loadmodel->name, loadmodel->numskins), (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS, false)))
+               while ((tempskinframe = R_SkinFrame_LoadExternal(va(vabuf, sizeof(vabuf), "%s_%i", loadmodel->name, loadmodel->numskins), (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS, false)))
                {
                        // expand the arrays to make room
                        tempskinscenes = loadmodel->skinscenes;
index 3bec9cdcfff9dcd3b2410e15a6f0daace6a034a0..6941af6bbe5335c6edd36a1d749960060b834d02 100644 (file)
@@ -1296,7 +1296,7 @@ loc0:
        }
 }
 
-void Mod_Q1BSP_LightPoint(dp_model_t *model, const vec3_t p, vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal)
+static void Mod_Q1BSP_LightPoint(dp_model_t *model, const vec3_t p, vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal)
 {
        // pretend lighting is coming down from above (due to lack of a lightgrid to know primary lighting direction)
        VectorSet(diffusenormal, 0, 0, 1);
@@ -1534,7 +1534,7 @@ R_Q1BSP_LoadSplitSky
 A sky texture is 256*128, with the right side being a masked overlay
 ==============
 */
-void R_Q1BSP_LoadSplitSky (unsigned char *src, int width, int height, int bytesperpixel)
+static void R_Q1BSP_LoadSplitSky (unsigned char *src, int width, int height, int bytesperpixel)
 {
        int x, y;
        int w = width/2;
@@ -1612,6 +1612,7 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
        const char *s;
        char mapname[MAX_QPATH], name[MAX_QPATH];
        unsigned char zeroopaque[4], zerotrans[4];
+       char vabuf[1024];
        Vector4Set(zeroopaque, 0, 0, 0, 255);
        Vector4Set(zerotrans, 0, 0, 0, 128);
 
@@ -1787,9 +1788,9 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
                        // LordHavoc: HL sky textures are entirely different than quake
                        if (!loadmodel->brush.ishlbsp && !strncmp(tx->name, "sky", 3) && mtwidth == mtheight * 2)
                        {
-                               data = loadimagepixelsbgra(gamemode == GAME_TENEBRAE ? tx->name : va("textures/%s/%s", mapname, tx->name), false, false, false, NULL);
+                               data = loadimagepixelsbgra(gamemode == GAME_TENEBRAE ? tx->name : va(vabuf, sizeof(vabuf), "textures/%s/%s", mapname, tx->name), false, false, false, NULL);
                                if (!data)
-                                       data = loadimagepixelsbgra(gamemode == GAME_TENEBRAE ? tx->name : va("textures/%s", tx->name), false, false, false, NULL);
+                                       data = loadimagepixelsbgra(gamemode == GAME_TENEBRAE ? tx->name : va(vabuf, sizeof(vabuf), "textures/%s", tx->name), false, false, false, NULL);
                                if (data && image_width == image_height * 2)
                                {
                                        R_Q1BSP_LoadSplitSky(data, image_width, image_height, 4);
@@ -1800,9 +1801,9 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
                        }
                        else
                        {
-                               skinframe = R_SkinFrame_LoadExternal(gamemode == GAME_TENEBRAE ? tx->name : va("textures/%s/%s", mapname, tx->name), TEXF_ALPHA | TEXF_MIPMAP | TEXF_ISWORLD | TEXF_PICMIP | TEXF_COMPRESS, false);
+                               skinframe = R_SkinFrame_LoadExternal(gamemode == GAME_TENEBRAE ? tx->name : va(vabuf, sizeof(vabuf), "textures/%s/%s", mapname, tx->name), TEXF_ALPHA | TEXF_MIPMAP | TEXF_ISWORLD | TEXF_PICMIP | TEXF_COMPRESS, false);
                                if (!skinframe)
-                                       skinframe = R_SkinFrame_LoadExternal(gamemode == GAME_TENEBRAE ? tx->name : va("textures/%s", tx->name), TEXF_ALPHA | TEXF_MIPMAP | TEXF_ISWORLD | TEXF_PICMIP | TEXF_COMPRESS, false);
+                                       skinframe = R_SkinFrame_LoadExternal(gamemode == GAME_TENEBRAE ? tx->name : va(vabuf, sizeof(vabuf), "textures/%s", tx->name), TEXF_ALPHA | TEXF_MIPMAP | TEXF_ISWORLD | TEXF_PICMIP | TEXF_COMPRESS, false);
                                if (skinframe)
                                        tx->offsetmapping = OFFSETMAPPING_DEFAULT; // allow offsetmapping on external textures without a q3 shader
                                if (!skinframe)
@@ -2166,7 +2167,7 @@ static void Mod_Q1BSP_LoadVertexes(lump_t *l)
 // The following two functions should be removed and MSG_* or SZ_* function sets adjusted so they
 // can be used for this
 // REMOVEME
-int SB_ReadInt (unsigned char **buffer)
+static int SB_ReadInt (unsigned char **buffer)
 {
        int     i;
        i = ((*buffer)[0]) + 256*((*buffer)[1]) + 65536*((*buffer)[2]) + 16777216*((*buffer)[3]);
@@ -2175,7 +2176,7 @@ int SB_ReadInt (unsigned char **buffer)
 }
 
 // REMOVEME
-float SB_ReadFloat (unsigned char **buffer)
+static float SB_ReadFloat (unsigned char **buffer)
 {
        union
        {
@@ -2462,6 +2463,7 @@ static void Mod_Q1BSP_LoadFaces(lump_t *l)
        int i, j, count, surfacenum, planenum, smax, tmax, ssize, tsize, firstedge, numedges, totalverts, totaltris, lightmapnumber, lightmapsize, totallightmapsamples;
        float texmins[2], texmaxs[2], val;
        rtexture_t *lightmaptexture, *deluxemaptexture;
+       char vabuf[1024];
 
        in = (dface_t *)(mod_base + l->fileofs);
        if (l->filelen % sizeof(*in))
@@ -2670,9 +2672,9 @@ static void Mod_Q1BSP_LoadFaces(lump_t *l)
                                loadmodel->brushq3.num_mergedlightmaps = lightmapnumber + 1;
                                loadmodel->brushq3.data_lightmaps = (rtexture_t **)Mem_Realloc(loadmodel->mempool, loadmodel->brushq3.data_lightmaps, loadmodel->brushq3.num_mergedlightmaps * sizeof(loadmodel->brushq3.data_lightmaps[0]));
                                loadmodel->brushq3.data_deluxemaps = (rtexture_t **)Mem_Realloc(loadmodel->mempool, loadmodel->brushq3.data_deluxemaps, loadmodel->brushq3.num_mergedlightmaps * sizeof(loadmodel->brushq3.data_deluxemaps[0]));
-                               loadmodel->brushq3.data_lightmaps[lightmapnumber] = lightmaptexture = R_LoadTexture2D(loadmodel->texturepool, va("lightmap%i", lightmapnumber), lightmapsize, lightmapsize, NULL, TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_ALLOWUPDATES, -1, NULL);
+                               loadmodel->brushq3.data_lightmaps[lightmapnumber] = lightmaptexture = R_LoadTexture2D(loadmodel->texturepool, va(vabuf, sizeof(vabuf), "lightmap%i", lightmapnumber), lightmapsize, lightmapsize, NULL, TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_ALLOWUPDATES, -1, NULL);
                                if (loadmodel->brushq1.nmaplightdata)
-                                       loadmodel->brushq3.data_deluxemaps[lightmapnumber] = deluxemaptexture = R_LoadTexture2D(loadmodel->texturepool, va("deluxemap%i", lightmapnumber), lightmapsize, lightmapsize, NULL, TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_ALLOWUPDATES, -1, NULL);
+                                       loadmodel->brushq3.data_deluxemaps[lightmapnumber] = deluxemaptexture = R_LoadTexture2D(loadmodel->texturepool, va(vabuf, sizeof(vabuf), "deluxemap%i", lightmapnumber), lightmapsize, lightmapsize, NULL, TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_ALLOWUPDATES, -1, NULL);
                                lightmapnumber++;
                                Mod_AllocLightmap_Reset(&allocState);
                                Mod_AllocLightmap_Block(&allocState, ssize, tsize, &lightmapx, &lightmapy);
@@ -2892,7 +2894,7 @@ static void Mod_Q1BSP_LoadLeafs(lump_t *l)
        }
 }
 
-qboolean Mod_Q1BSP_CheckWaterAlphaSupport(void)
+static qboolean Mod_Q1BSP_CheckWaterAlphaSupport(void)
 {
        int i, j;
        mleaf_t *leaf;
@@ -4376,7 +4378,7 @@ static void Mod_Q2BSP_LoadModels(lump_t *l)
 */
 }
 
-void static Mod_Q2BSP_Load(dp_model_t *mod, void *buffer, void *bufferend)
+static void Mod_Q2BSP_Load(dp_model_t *mod, void *buffer, void *bufferend)
 {
        int i;
        q2dheader_t *header;
@@ -4835,6 +4837,7 @@ static void Mod_Q3BSP_LoadLightmaps(lump_t *l, lump_t *faceslump)
        char mapname[MAX_QPATH];
        qboolean external;
        unsigned char *inpixels[10000]; // max count q3map2 can output (it uses 4 digits)
+       char vabuf[1024];
 
        // defaults for q3bsp
        size = 128;
@@ -4871,7 +4874,7 @@ static void Mod_Q3BSP_LoadLightmaps(lump_t *l, lump_t *faceslump)
                if (developer_loading.integer)
                        Con_Printf("Using external lightmaps\n");
                FS_StripExtension(loadmodel->name, mapname, sizeof(mapname));
-               inpixels[0] = loadimagepixelsbgra(va("%s/lm_%04d", mapname, 0), false, false, false, NULL);
+               inpixels[0] = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "%s/lm_%04d", mapname, 0), false, false, false, NULL);
                if(!inpixels[0])
                        return;
 
@@ -4891,7 +4894,7 @@ static void Mod_Q3BSP_LoadLightmaps(lump_t *l, lump_t *faceslump)
 
                for(count = 1; ; ++count)
                {
-                       inpixels[count] = loadimagepixelsbgra(va("%s/lm_%04d", mapname, count), false, false, false, NULL);
+                       inpixels[count] = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "%s/lm_%04d", mapname, count), false, false, false, NULL);
                        if(!inpixels[count])
                                break; // we got all of them
                        if(image_width != size || image_height != size)
@@ -5045,7 +5048,7 @@ static void Mod_Q3BSP_LoadLightmaps(lump_t *l, lump_t *faceslump)
                if (((realindex + 1) & (mergedrowsxcolumns - 1)) == 0 || (realindex + 1) == realcount)
                {
                        if (loadmodel->brushq3.deluxemapping && (i & 1))
-                               loadmodel->brushq3.data_deluxemaps[lightmapindex] = R_LoadTexture2D(loadmodel->texturepool, va("deluxemap%04i", lightmapindex), mergedwidth, mergedheight, mergeddeluxepixels, TEXTYPE_BGRA, TEXF_FORCELINEAR | (gl_texturecompression_q3bspdeluxemaps.integer ? TEXF_COMPRESS : 0), -1, NULL);
+                               loadmodel->brushq3.data_deluxemaps[lightmapindex] = R_LoadTexture2D(loadmodel->texturepool, va(vabuf, sizeof(vabuf), "deluxemap%04i", lightmapindex), mergedwidth, mergedheight, mergeddeluxepixels, TEXTYPE_BGRA, TEXF_FORCELINEAR | (gl_texturecompression_q3bspdeluxemaps.integer ? TEXF_COMPRESS : 0), -1, NULL);
                        else
                        {
                                if(mod_q3bsp_sRGBlightmaps.integer)
@@ -5070,13 +5073,13 @@ static void Mod_Q3BSP_LoadLightmaps(lump_t *l, lump_t *faceslump)
                                        }
                                        else
                                                t = TEXTYPE_SRGB_BGRA; // normally, we upload lightmaps in sRGB form (possibly downconverted to linear)
-                                       loadmodel->brushq3.data_lightmaps [lightmapindex] = R_LoadTexture2D(loadmodel->texturepool, va("lightmap%04i", lightmapindex), mergedwidth, mergedheight, mergedpixels, t, TEXF_FORCELINEAR | (gl_texturecompression_q3bsplightmaps.integer ? TEXF_COMPRESS : 0), -1, NULL);
+                                       loadmodel->brushq3.data_lightmaps [lightmapindex] = R_LoadTexture2D(loadmodel->texturepool, va(vabuf, sizeof(vabuf), "lightmap%04i", lightmapindex), mergedwidth, mergedheight, mergedpixels, t, TEXF_FORCELINEAR | (gl_texturecompression_q3bsplightmaps.integer ? TEXF_COMPRESS : 0), -1, NULL);
                                }
                                else
                                {
                                        if(vid_sRGB.integer && vid_sRGB_fallback.integer && !vid.sRGB3D)
                                                Image_MakesRGBColorsFromLinear_Lightmap(mergedpixels, mergedpixels, mergedwidth * mergedheight);
-                                       loadmodel->brushq3.data_lightmaps [lightmapindex] = R_LoadTexture2D(loadmodel->texturepool, va("lightmap%04i", lightmapindex), mergedwidth, mergedheight, mergedpixels, TEXTYPE_BGRA, TEXF_FORCELINEAR | (gl_texturecompression_q3bsplightmaps.integer ? TEXF_COMPRESS : 0), -1, NULL);
+                                       loadmodel->brushq3.data_lightmaps [lightmapindex] = R_LoadTexture2D(loadmodel->texturepool, va(vabuf, sizeof(vabuf), "lightmap%04i", lightmapindex), mergedwidth, mergedheight, mergedpixels, TEXTYPE_BGRA, TEXF_FORCELINEAR | (gl_texturecompression_q3bsplightmaps.integer ? TEXF_COMPRESS : 0), -1, NULL);
                                }
                        }
                }
@@ -6181,7 +6184,7 @@ void Mod_CollisionBIH_TracePoint(dp_model_t *model, const frameblend_t *frameble
        }
 }
 
-void Mod_CollisionBIH_TraceLineShared(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, const bih_t *bih)
+static void Mod_CollisionBIH_TraceLineShared(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, const bih_t *bih)
 {
        const bih_leaf_t *leaf;
        const bih_node_t *node;
@@ -6455,7 +6458,7 @@ void Mod_CollisionBIH_TraceBox(dp_model_t *model, const frameblend_t *frameblend
 }
 
 
-int Mod_CollisionBIH_PointSuperContents(struct model_s *model, int frame, const vec3_t point)
+static int Mod_CollisionBIH_PointSuperContents(struct model_s *model, int frame, const vec3_t point)
 {
        trace_t trace;
        Mod_CollisionBIH_TracePoint(model, NULL, NULL, &trace, point, 0);
@@ -6777,7 +6780,7 @@ static void Mod_Q3BSP_TraceLine(dp_model_t *model, const frameblend_t *frameblen
                Mod_Q3BSP_TraceLine_RecursiveBSPNode(trace, model, model->brush.data_nodes, start, end, 0, 1, start, end, ++markframe, segmentmins, segmentmaxs);
 }
 
-void Mod_Q3BSP_TraceBrush(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, colbrushf_t *start, colbrushf_t *end, int hitsupercontentsmask)
+static void Mod_Q3BSP_TraceBrush(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, colbrushf_t *start, colbrushf_t *end, int hitsupercontentsmask)
 {
        float segmentmins[3], segmentmaxs[3];
        int i;
@@ -6842,9 +6845,7 @@ static int Mod_Q3BSP_PointSuperContents(struct model_s *model, int frame, const
        q3mbrush_t *brush;
        if (mod_collision_bih.integer)
        {
-               trace_t trace;
-               Mod_Q3BSP_TracePoint(model, NULL, NULL, &trace, point, 0);
-               supercontents = trace.startsupercontents;
+               supercontents = Mod_CollisionBIH_PointSuperContents(model, frame, point);
        }
        // test if the point is inside each brush
        else if (model->brush.submodel)
@@ -7074,7 +7075,7 @@ static int Mod_Q3BSP_NativeContentsFromSuperContents(dp_model_t *model, int supe
        return nativecontents;
 }
 
-void Mod_Q3BSP_RecursiveFindNumLeafs(mnode_t *node)
+static void Mod_Q3BSP_RecursiveFindNumLeafs(mnode_t *node)
 {
        int numleafs;
        while (node->plane)
@@ -7087,7 +7088,7 @@ void Mod_Q3BSP_RecursiveFindNumLeafs(mnode_t *node)
                loadmodel->brush.num_leafs = numleafs;
 }
 
-void Mod_Q3BSP_Load(dp_model_t *mod, void *buffer, void *bufferend)
+static void Mod_Q3BSP_Load(dp_model_t *mod, void *buffer, void *bufferend)
 {
        int i, j, lumps;
        q3dheader_t *header;
@@ -7931,40 +7932,3 @@ void Mod_OBJ_Load(dp_model_t *mod, void *buffer, void *bufferend)
 
        Con_DPrintf("Stats for obj model \"%s\": %i faces, %i nodes, %i leafs, %i clusters, %i clusterportals, mesh: %i vertices, %i triangles, %i surfaces\n", loadmodel->name, loadmodel->num_surfaces, loadmodel->brush.num_nodes, loadmodel->brush.num_leafs, mod->brush.num_pvsclusters, loadmodel->brush.num_portals, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->num_surfaces);
 }
-
-qboolean Mod_CanSeeBox_Trace(int numsamples, float t, dp_model_t *model, vec3_t eye, vec3_t minsX, vec3_t maxsX)
-{
-       // we already have done PVS culling at this point...
-       // so we don't need to do it again.
-
-       int i;
-       vec3_t testorigin, mins, maxs;
-
-       testorigin[0] = (minsX[0] + maxsX[0]) * 0.5;
-       testorigin[1] = (minsX[1] + maxsX[1]) * 0.5;
-       testorigin[2] = (minsX[2] + maxsX[2]) * 0.5;
-
-       if(model->brush.TraceLineOfSight(model, eye, testorigin))
-               return 1;
-
-       // expand the box a little
-       mins[0] = (t+1) * minsX[0] - t * maxsX[0];
-       maxs[0] = (t+1) * maxsX[0] - t * minsX[0];
-       mins[1] = (t+1) * minsX[1] - t * maxsX[1];
-       maxs[1] = (t+1) * maxsX[1] - t * minsX[1];
-       mins[2] = (t+1) * minsX[2] - t * maxsX[2];
-       maxs[2] = (t+1) * maxsX[2] - t * minsX[2];
-
-       for(i = 0; i != numsamples; ++i)
-       {
-               testorigin[0] = lhrandom(mins[0], maxs[0]);
-               testorigin[1] = lhrandom(mins[1], maxs[1]);
-               testorigin[2] = lhrandom(mins[2], maxs[2]);
-
-               if(model->brush.TraceLineOfSight(model, eye, testorigin))
-                       return 1;
-       }
-
-       return 0;
-}
-
index 47b4c58fabedfde42ed40f62707e0f17c9a13598..04f2c9cbc208848e5b1103230959cdbba4701486 100644 (file)
@@ -228,7 +228,7 @@ void Mod_UnloadModel (dp_model_t *mod)
        mod->loaded = false;
 }
 
-void R_Model_Null_Draw(entity_render_t *ent)
+static void R_Model_Null_Draw(entity_render_t *ent)
 {
        return;
 }
@@ -236,7 +236,7 @@ void R_Model_Null_Draw(entity_render_t *ent)
 
 typedef void (*mod_framegroupify_parsegroups_t) (unsigned int i, int start, int len, float fps, qboolean loop, void *pass);
 
-int Mod_FrameGroupify_ParseGroups(const char *buf, mod_framegroupify_parsegroups_t cb, void *pass)
+static int Mod_FrameGroupify_ParseGroups(const char *buf, mod_framegroupify_parsegroups_t cb, void *pass)
 {
        const char *bufptr;
        int start, len;
@@ -289,13 +289,7 @@ int Mod_FrameGroupify_ParseGroups(const char *buf, mod_framegroupify_parsegroups
        return i;
 }
 
-void Mod_FrameGroupify_ParseGroups_Count (unsigned int i, int start, int len, float fps, qboolean loop, void *pass)
-{
-       unsigned int *cnt = (unsigned int *) pass;
-       ++*cnt;
-}
-
-void Mod_FrameGroupify_ParseGroups_Store (unsigned int i, int start, int len, float fps, qboolean loop, void *pass)
+static void Mod_FrameGroupify_ParseGroups_Store (unsigned int i, int start, int len, float fps, qboolean loop, void *pass)
 {
        dp_model_t *mod = (dp_model_t *) pass;
        animscene_t *anim = &mod->animscenes[i];
@@ -307,7 +301,7 @@ void Mod_FrameGroupify_ParseGroups_Store (unsigned int i, int start, int len, fl
        //Con_Printf("frame group %d is %d %d %f %d\n", i, start, len, fps, loop);
 }
 
-void Mod_FrameGroupify(dp_model_t *mod, const char *buf)
+static void Mod_FrameGroupify(dp_model_t *mod, const char *buf)
 {
        unsigned int cnt;
 
@@ -328,7 +322,7 @@ void Mod_FrameGroupify(dp_model_t *mod, const char *buf)
        Mod_FrameGroupify_ParseGroups(buf, Mod_FrameGroupify_ParseGroups_Store, mod);
 }
 
-void Mod_FindPotentialDeforms(dp_model_t *mod)
+static void Mod_FindPotentialDeforms(dp_model_t *mod)
 {
        int i, j;
        texture_t *texture;
@@ -366,6 +360,7 @@ dp_model_t *Mod_LoadModel(dp_model_t *mod, qboolean crash, qboolean checkdisk)
        unsigned int crc;
        void *buf;
        fs_offset_t filesize = 0;
+       char vabuf[1024];
 
        mod->used = true;
 
@@ -491,8 +486,8 @@ dp_model_t *Mod_LoadModel(dp_model_t *mod, qboolean crash, qboolean checkdisk)
                Mem_Free(buf);
 
                Mod_FindPotentialDeforms(mod);
-                                       
-               buf = FS_LoadFile (va("%s.framegroups", mod->name), tempmempool, false, &filesize);
+
+               buf = FS_LoadFile(va(vabuf, sizeof(vabuf), "%s.framegroups", mod->name), tempmempool, false, &filesize);
                if(buf)
                {
                        Mod_FrameGroupify(mod, (const char *)buf);
@@ -856,7 +851,8 @@ void Mod_BuildNormals(int firstvertex, int numvertices, int numtriangles, const
                VectorNormalize(vectorNormal);
 }
 
-void Mod_BuildBumpVectors(const float *v0, const float *v1, const float *v2, const float *tc0, const float *tc1, const float *tc2, float *svector3f, float *tvector3f, float *normal3f)
+#if 0
+static void Mod_BuildBumpVectors(const float *v0, const float *v1, const float *v2, const float *tc0, const float *tc1, const float *tc2, float *svector3f, float *tvector3f, float *normal3f)
 {
        float f, tangentcross[3], v10[3], v20[3], tc10[2], tc20[2];
        // 79 add/sub/negate/multiply (1 cycle), 1 compare (3 cycle?), total cycles not counting load/store/exchange roughly 82 cycles
@@ -899,6 +895,7 @@ void Mod_BuildBumpVectors(const float *v0, const float *v1, const float *v2, con
                VectorNegate(tvector3f, tvector3f);
        }
 }
+#endif
 
 // warning: this is a very expensive function!
 void Mod_BuildTextureVectorsFromNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const float *texcoord2f, const float *normal3f, const int *elements, float *svector3f, float *tvector3f, qboolean areaweighting)
@@ -1394,7 +1391,8 @@ void Mod_CreateCollisionMesh(dp_model_t *mod)
        mod->brush.collisionmesh = Mod_ShadowMesh_Finish(mempool, mod->brush.collisionmesh, false, false, false);
 }
 
-void Mod_GetTerrainVertex3fTexCoord2fFromBGRA(const unsigned char *imagepixels, int imagewidth, int imageheight, int ix, int iy, float *vertex3f, float *texcoord2f, matrix4x4_t *pixelstepmatrix, matrix4x4_t *pixeltexturestepmatrix)
+#if 0
+static void Mod_GetTerrainVertex3fTexCoord2fFromBGRA(const unsigned char *imagepixels, int imagewidth, int imageheight, int ix, int iy, float *vertex3f, float *texcoord2f, matrix4x4_t *pixelstepmatrix, matrix4x4_t *pixeltexturestepmatrix)
 {
        float v[3], tc[3];
        v[0] = ix;
@@ -1409,7 +1407,7 @@ void Mod_GetTerrainVertex3fTexCoord2fFromBGRA(const unsigned char *imagepixels,
        texcoord2f[1] = tc[1];
 }
 
-void Mod_GetTerrainVertexFromBGRA(const unsigned char *imagepixels, int imagewidth, int imageheight, int ix, int iy, float *vertex3f, float *svector3f, float *tvector3f, float *normal3f, float *texcoord2f, matrix4x4_t *pixelstepmatrix, matrix4x4_t *pixeltexturestepmatrix)
+static void Mod_GetTerrainVertexFromBGRA(const unsigned char *imagepixels, int imagewidth, int imageheight, int ix, int iy, float *vertex3f, float *svector3f, float *tvector3f, float *normal3f, float *texcoord2f, matrix4x4_t *pixelstepmatrix, matrix4x4_t *pixeltexturestepmatrix)
 {
        float vup[3], vdown[3], vleft[3], vright[3];
        float tcup[3], tcdown[3], tcleft[3], tcright[3];
@@ -1434,7 +1432,7 @@ void Mod_GetTerrainVertexFromBGRA(const unsigned char *imagepixels, int imagewid
        VectorAdd(normal3f, nl, normal3f);
 }
 
-void Mod_ConstructTerrainPatchFromBGRA(const unsigned char *imagepixels, int imagewidth, int imageheight, int x1, int y1, int width, int height, int *element3i, int *neighbor3i, float *vertex3f, float *svector3f, float *tvector3f, float *normal3f, float *texcoord2f, matrix4x4_t *pixelstepmatrix, matrix4x4_t *pixeltexturestepmatrix)
+static void Mod_ConstructTerrainPatchFromBGRA(const unsigned char *imagepixels, int imagewidth, int imageheight, int x1, int y1, int width, int height, int *element3i, int *neighbor3i, float *vertex3f, float *svector3f, float *tvector3f, float *normal3f, float *texcoord2f, matrix4x4_t *pixelstepmatrix, matrix4x4_t *pixeltexturestepmatrix)
 {
        int x, y, ix, iy, *e;
        e = element3i;
@@ -1456,6 +1454,7 @@ void Mod_ConstructTerrainPatchFromBGRA(const unsigned char *imagepixels, int ima
                for (x = 0, ix = x1;x < width + 1;x++, ix++, vertex3f += 3, texcoord2f += 2, svector3f += 3, tvector3f += 3, normal3f += 3)
                        Mod_GetTerrainVertexFromBGRA(imagepixels, imagewidth, imageheight, ix, iy, vertex3f, texcoord2f, svector3f, tvector3f, normal3f, pixelstepmatrix, pixeltexturestepmatrix);
 }
+#endif
 
 #if 0
 void Mod_Terrain_SurfaceRecurseChunk(dp_model_t *model, int stepsize, int x, int y)
@@ -1537,7 +1536,7 @@ void Mod_Terrain_UpdateSurfacesForViewOrigin(dp_model_t *model)
 }
 #endif
 
-int Mod_LoadQ3Shaders_EnumerateWaveFunc(const char *s)
+static int Mod_LoadQ3Shaders_EnumerateWaveFunc(const char *s)
 {
        int offset = 0;
        if (!strncasecmp(s, "user", 4)) // parse stuff like "user1sin", always user<n>func
@@ -2692,6 +2691,7 @@ skinfile_t *Mod_LoadSkinFiles(void)
        skinfile_t *skinfile = NULL, *first = NULL;
        skinfileitem_t *skinfileitem;
        char word[10][MAX_QPATH];
+       char vabuf[1024];
 
 /*
 sample file:
@@ -2709,7 +2709,7 @@ tag_weapon,
 tag_torso,
 */
        memset(word, 0, sizeof(word));
-       for (i = 0;i < 256 && (data = text = (char *)FS_LoadFile(va("%s_%i.skin", loadmodel->name, i), tempmempool, true, NULL));i++)
+       for (i = 0;i < 256 && (data = text = (char *)FS_LoadFile(va(vabuf, sizeof(vabuf), "%s_%i.skin", loadmodel->name, i), tempmempool, true, NULL));i++)
        {
                // If it's the first file we parse
                if (skinfile == NULL)
@@ -3280,6 +3280,7 @@ static void Mod_Decompile_f(void)
        int zymtextsize = 0;
        int dpmtextsize = 0;
        int framegroupstextsize = 0;
+       char vabuf[1024];
 
        if (Cmd_Argc() != 2)
        {
@@ -3386,11 +3387,11 @@ static void Mod_Decompile_f(void)
                        }
                }
                if (zymtextsize)
-                       FS_WriteFile(va("%s_decompiled/out_zym.txt", basename), zymtextbuffer, (fs_offset_t)zymtextsize);
+                       FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_decompiled/out_zym.txt", basename), zymtextbuffer, (fs_offset_t)zymtextsize);
                if (dpmtextsize)
-                       FS_WriteFile(va("%s_decompiled/out_dpm.txt", basename), dpmtextbuffer, (fs_offset_t)dpmtextsize);
+                       FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_decompiled/out_dpm.txt", basename), dpmtextbuffer, (fs_offset_t)dpmtextsize);
                if (framegroupstextsize)
-                       FS_WriteFile(va("%s_decompiled.framegroups", basename), framegroupstextbuffer, (fs_offset_t)framegroupstextsize);
+                       FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_decompiled.framegroups", basename), framegroupstextbuffer, (fs_offset_t)framegroupstextsize);
        }
 }
 
@@ -3524,7 +3525,6 @@ static float mod_generatelightmaps_offsets[3][MAX_LIGHTMAPSAMPLES][3];
 static int mod_generatelightmaps_numlights;
 static lightmaplight_t *mod_generatelightmaps_lightinfo;
 
-extern int R_Shadow_GetRTLightInfo(unsigned int lightindex, float *origin, float *radius, float *color);
 extern cvar_t r_shadow_lightattenuationdividebias;
 extern cvar_t r_shadow_lightattenuationlinearscale;
 
@@ -4105,6 +4105,7 @@ static void Mod_GenerateLightmaps_CreateLightmaps(dp_model_t *model)
        unsigned char *lightmappixels;
        unsigned char *deluxemappixels;
        mod_alloclightmap_state_t lmstate;
+       char vabuf[1024];
 
        // generate lightmap projection information for all triangles
        if (model->texturepool == NULL)
@@ -4287,8 +4288,8 @@ static void Mod_GenerateLightmaps_CreateLightmaps(dp_model_t *model)
 
        for (lightmapindex = 0;lightmapindex < model->brushq3.num_mergedlightmaps;lightmapindex++)
        {
-               model->brushq3.data_lightmaps[lightmapindex] = R_LoadTexture2D(model->texturepool, va("lightmap%i", lightmapindex), lm_texturesize, lm_texturesize, lightmappixels + lightmapindex * lm_texturesize * lm_texturesize * 4, TEXTYPE_BGRA, TEXF_FORCELINEAR, -1, NULL);
-               model->brushq3.data_deluxemaps[lightmapindex] = R_LoadTexture2D(model->texturepool, va("deluxemap%i", lightmapindex), lm_texturesize, lm_texturesize, deluxemappixels + lightmapindex * lm_texturesize * lm_texturesize * 4, TEXTYPE_BGRA, TEXF_FORCELINEAR, -1, NULL);
+               model->brushq3.data_lightmaps[lightmapindex] = R_LoadTexture2D(model->texturepool, va(vabuf, sizeof(vabuf), "lightmap%i", lightmapindex), lm_texturesize, lm_texturesize, lightmappixels + lightmapindex * lm_texturesize * lm_texturesize * 4, TEXTYPE_BGRA, TEXF_FORCELINEAR, -1, NULL);
+               model->brushq3.data_deluxemaps[lightmapindex] = R_LoadTexture2D(model->texturepool, va(vabuf, sizeof(vabuf), "deluxemap%i", lightmapindex), lm_texturesize, lm_texturesize, deluxemappixels + lightmapindex * lm_texturesize * lm_texturesize * 4, TEXTYPE_BGRA, TEXF_FORCELINEAR, -1, NULL);
        }
 
        if (lightmappixels)
index 1515092064a554ab6e81d7154b37fd76e9150148..c4d2b088234a61962243ae9ef565a32efe442581 100644 (file)
@@ -259,7 +259,6 @@ static void Mod_Sprite_SharedSetup(const unsigned char *datapointer, int version
        loadmodel->radius2 = modelradius * modelradius;
 }
 
-extern void R_Model_Sprite_Draw(entity_render_t *ent);
 void Mod_IDSP_Load(dp_model_t *mod, void *buffer, void *bufferend)
 {
        int version;
index ee28b45f677e9f1c7d1828ac21f8b59e79f698e6..e90dcdec6e5e38921925775aebc845f4851b39fa 100644 (file)
@@ -3,6 +3,7 @@
 #include "prvm_cmds.h"
 #include "clvm_cmds.h"
 #include "menu.h"
+#include "csprogs.h"
 
 // TODO check which strings really should be engine strings
 
@@ -55,7 +56,7 @@ VM_M_setmousetarget
 setmousetarget(float target)
 =========
 */
-void VM_M_setmousetarget(void)
+static void VM_M_setmousetarget(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_M_setmousetarget);
 
@@ -68,7 +69,7 @@ void VM_M_setmousetarget(void)
                in_client_mouse = true;
                break;
        default:
-               PRVM_ERROR("VM_M_setmousetarget: wrong destination %f !",PRVM_G_FLOAT(OFS_PARM0));
+               prog->error_cmd("VM_M_setmousetarget: wrong destination %f !",PRVM_G_FLOAT(OFS_PARM0));
        }
 }
 
@@ -79,7 +80,7 @@ VM_M_getmousetarget
 float  getmousetarget
 =========
 */
-void VM_M_getmousetarget(void)
+static void VM_M_getmousetarget(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0,VM_M_getmousetarget);
 
@@ -98,7 +99,7 @@ VM_M_setkeydest
 setkeydest(float dest)
 =========
 */
-void VM_M_setkeydest(void)
+static void VM_M_setkeydest(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1,VM_M_setkeydest);
 
@@ -121,7 +122,7 @@ void VM_M_setkeydest(void)
                // key_dest = key_message
                // break;
        default:
-               PRVM_ERROR("VM_M_setkeydest: wrong destination %f !", PRVM_G_FLOAT(OFS_PARM0));
+               prog->error_cmd("VM_M_setkeydest: wrong destination %f !", PRVM_G_FLOAT(OFS_PARM0));
        }
 }
 
@@ -132,7 +133,7 @@ VM_M_getkeydest
 float  getkeydest
 =========
 */
-void VM_M_getkeydest(void)
+static void VM_M_getkeydest(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0,VM_M_getkeydest);
 
@@ -165,7 +166,7 @@ VM_M_getresolution
 vector getresolution(float number)
 =========
 */
-void VM_M_getresolution(void)
+static void VM_M_getresolution(prvm_prog_t *prog)
 {
        int nr, fs;
        VM_SAFEPARMCOUNTRANGE(1, 2, VM_getresolution);
@@ -189,7 +190,7 @@ void VM_M_getresolution(void)
        }
 }
 
-void VM_M_getgamedirinfo(void)
+static void VM_M_getgamedirinfo(prvm_prog_t *prog)
 {
        int nr, item;
        VM_SAFEPARMCOUNT(2, VM_getgamedirinfo);
@@ -202,9 +203,9 @@ void VM_M_getgamedirinfo(void)
        if(nr >= 0 && nr < fs_all_gamedirs_count)
        {
                if(item == 0)
-                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( fs_all_gamedirs[nr].name );
+                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, fs_all_gamedirs[nr].name );
                else if(item == 1)
-                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( fs_all_gamedirs[nr].description );
+                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, fs_all_gamedirs[nr].description );
        }
 }
 
@@ -226,7 +227,7 @@ float       getserverliststat(float type)
 6      sortfield
 7      sortflags
 */
-void VM_M_getserverliststat( void )
+static void VM_M_getserverliststat(prvm_prog_t *prog)
 {
        int type;
        VM_SAFEPARMCOUNT ( 1, VM_M_getserverliststat );
@@ -261,7 +262,7 @@ void VM_M_getserverliststat( void )
                PRVM_G_FLOAT ( OFS_RETURN ) = serverlist_sortflags;
                return;
        default:
-               VM_Warning( "VM_M_getserverliststat: bad type %i!\n", type );
+               VM_Warning(prog, "VM_M_getserverliststat: bad type %i!\n", type );
        }
 }
 
@@ -272,7 +273,7 @@ VM_M_resetserverlistmasks
 resetserverlistmasks()
 ========================
 */
-void VM_M_resetserverlistmasks( void )
+static void VM_M_resetserverlistmasks(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0, VM_M_resetserverlistmasks);
        ServerList_ResetMasks();
@@ -288,7 +289,7 @@ setserverlistmaskstring(float mask, float fld, string str, float op)
 512 - 1024     or
 ========================
 */
-void VM_M_setserverlistmaskstring( void )
+static void VM_M_setserverlistmaskstring(prvm_prog_t *prog)
 {
        const char *str;
        int masknr;
@@ -305,7 +306,7 @@ void VM_M_setserverlistmaskstring( void )
                mask = &serverlist_ormasks[masknr - 512 ];
        else
        {
-               VM_Warning( "VM_M_setserverlistmaskstring: invalid mask number %i\n", masknr );
+               VM_Warning(prog, "VM_M_setserverlistmaskstring: invalid mask number %i\n", masknr );
                return;
        }
 
@@ -334,7 +335,7 @@ void VM_M_setserverlistmaskstring( void )
                        strlcpy( mask->info.game, str, sizeof(mask->info.game)  );
                        break;
                default:
-                       VM_Warning( "VM_M_setserverlistmaskstring: Bad field number %i passed!\n", field );
+                       VM_Warning(prog, "VM_M_setserverlistmaskstring: Bad field number %i passed!\n", field );
                        return;
        }
 
@@ -352,7 +353,7 @@ setserverlistmasknumber(float mask, float fld, float num, float op)
 512 - 1024     or
 ========================
 */
-void VM_M_setserverlistmasknumber( void )
+static void VM_M_setserverlistmasknumber(prvm_prog_t *prog)
 {
        int number;
        serverlist_mask_t *mask;
@@ -367,7 +368,7 @@ void VM_M_setserverlistmasknumber( void )
                mask = &serverlist_ormasks[masknr - 512 ];
        else
        {
-               VM_Warning( "VM_M_setserverlistmasknumber: invalid mask number %i\n", masknr );
+               VM_Warning(prog, "VM_M_setserverlistmasknumber: invalid mask number %i\n", masknr );
                return;
        }
 
@@ -400,7 +401,7 @@ void VM_M_setserverlistmasknumber( void )
                        mask->info.isfavorite = number != 0;
                        break;
                default:
-                       VM_Warning( "VM_M_setserverlistmasknumber: Bad field number %i passed!\n", field );
+                       VM_Warning(prog, "VM_M_setserverlistmasknumber: Bad field number %i passed!\n", field );
                        return;
        }
 
@@ -416,7 +417,7 @@ VM_M_resortserverlist
 resortserverlist
 ========================
 */
-void VM_M_resortserverlist( void )
+static void VM_M_resortserverlist(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0, VM_M_resortserverlist);
        ServerList_RebuildViewList();
@@ -429,7 +430,7 @@ VM_M_getserverliststring
 string getserverliststring(float field, float hostnr)
 =========
 */
-void VM_M_getserverliststring(void)
+static void VM_M_getserverliststring(prvm_prog_t *prog)
 {
        serverlist_entry_t *cache;
        int hostnr;
@@ -448,32 +449,32 @@ void VM_M_getserverliststring(void)
        cache = ServerList_GetViewEntry(hostnr);
        switch( (int) PRVM_G_FLOAT(OFS_PARM0) ) {
                case SLIF_CNAME:
-                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( cache->info.cname );
+                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, cache->info.cname );
                        break;
                case SLIF_NAME:
-                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( cache->info.name );
+                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, cache->info.name );
                        break;
                case SLIF_QCSTATUS:
-                       PRVM_G_INT (OFS_RETURN ) = PRVM_SetTempString (cache->info.qcstatus );
+                       PRVM_G_INT (OFS_RETURN ) = PRVM_SetTempString( prog, cache->info.qcstatus );
                        break;
                case SLIF_PLAYERS:
-                       PRVM_G_INT (OFS_RETURN ) = PRVM_SetTempString (cache->info.players );
+                       PRVM_G_INT (OFS_RETURN ) = PRVM_SetTempString( prog, cache->info.players );
                        break;
                case SLIF_GAME:
-                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( cache->info.game );
+                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, cache->info.game );
                        break;
                case SLIF_MOD:
-                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( cache->info.mod );
+                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, cache->info.mod );
                        break;
                case SLIF_MAP:
-                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( cache->info.map );
+                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, cache->info.map );
                        break;
                // TODO remove this again
                case 1024:
-                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( cache->line1 );
+                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, cache->line1 );
                        break;
                case 1025:
-                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( cache->line2 );
+                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, cache->line2 );
                        break;
                default:
                        Con_Print("VM_M_getserverliststring: bad field number passed!\n");
@@ -487,7 +488,7 @@ VM_M_getserverlistnumber
 float  getserverlistnumber(float field, float hostnr)
 =========
 */
-void VM_M_getserverlistnumber(void)
+static void VM_M_getserverlistnumber(prvm_prog_t *prog)
 {
        serverlist_entry_t *cache;
        int hostnr;
@@ -541,7 +542,7 @@ VM_M_setserverlistsort
 setserverlistsort(float field, float flags)
 ========================
 */
-void VM_M_setserverlistsort( void )
+static void VM_M_setserverlistsort(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT( 2, VM_M_setserverlistsort );
 
@@ -556,7 +557,7 @@ VM_M_refreshserverlist
 refreshserverlist()
 ========================
 */
-void VM_M_refreshserverlist( void )
+static void VM_M_refreshserverlist(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT( 0, VM_M_refreshserverlist );
        ServerList_QueryList(false, true, false, false);
@@ -569,13 +570,13 @@ VM_M_getserverlistindexforkey
 float getserverlistindexforkey(string key)
 ========================
 */
-void VM_M_getserverlistindexforkey( void )
+static void VM_M_getserverlistindexforkey(prvm_prog_t *prog)
 {
        const char *key;
        VM_SAFEPARMCOUNT( 1, VM_M_getserverlistindexforkey );
 
        key = PRVM_G_STRING( OFS_PARM0 );
-       VM_CheckEmptyString( key );
+       VM_CheckEmptyString( prog, key );
 
        if( !strcmp( key, "cname" ) )
                PRVM_G_FLOAT( OFS_RETURN ) = SLIF_CNAME;
@@ -618,7 +619,7 @@ VM_M_addwantedserverlistkey
 addwantedserverlistkey(string key)
 ========================
 */
-void VM_M_addwantedserverlistkey( void )
+static void VM_M_addwantedserverlistkey(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT( 1, VM_M_addwantedserverlistkey );
 }
@@ -640,13 +641,13 @@ Write*(* data, float type, float to)
 #define        MSG_ALL                 2               // reliable to all
 #define        MSG_INIT                3               // write to the init string
 
-sizebuf_t *VM_M_WriteDest (void)
+static sizebuf_t *VM_M_WriteDest (prvm_prog_t *prog)
 {
        int             dest;
        int             destclient;
 
        if(!sv.active)
-               PRVM_ERROR("VM_M_WriteDest: game is not server (%s)", PRVM_NAME);
+               prog->error_cmd("VM_M_WriteDest: game is not server (%s)", prog->name);
 
        dest = (int)PRVM_G_FLOAT(OFS_PARM1);
        switch (dest)
@@ -657,7 +658,7 @@ sizebuf_t *VM_M_WriteDest (void)
        case MSG_ONE:
                destclient = (int) PRVM_G_FLOAT(OFS_PARM2);
                if (destclient < 0 || destclient >= svs.maxclients || !svs.clients[destclient].active || !svs.clients[destclient].netconnection)
-                       PRVM_ERROR("VM_clientcommand: %s: invalid client !", PRVM_NAME);
+                       prog->error_cmd("VM_clientcommand: %s: invalid client !", prog->name);
 
                return &svs.clients[destclient].netconnection->message;
 
@@ -668,59 +669,59 @@ sizebuf_t *VM_M_WriteDest (void)
                return &sv.signon;
 
        default:
-               PRVM_ERROR ("WriteDest: bad destination");
+               prog->error_cmd("WriteDest: bad destination");
                break;
        }
 
        return NULL;
 }
 
-void VM_M_WriteByte (void)
+static void VM_M_WriteByte (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_M_WriteByte);
-       MSG_WriteByte (VM_M_WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM0));
+       MSG_WriteByte (VM_M_WriteDest(prog), (int)PRVM_G_FLOAT(OFS_PARM0));
 }
 
-void VM_M_WriteChar (void)
+static void VM_M_WriteChar (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_M_WriteChar);
-       MSG_WriteChar (VM_M_WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM0));
+       MSG_WriteChar (VM_M_WriteDest(prog), (int)PRVM_G_FLOAT(OFS_PARM0));
 }
 
-void VM_M_WriteShort (void)
+static void VM_M_WriteShort (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_M_WriteShort);
-       MSG_WriteShort (VM_M_WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM0));
+       MSG_WriteShort (VM_M_WriteDest(prog), (int)PRVM_G_FLOAT(OFS_PARM0));
 }
 
-void VM_M_WriteLong (void)
+static void VM_M_WriteLong (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_M_WriteLong);
-       MSG_WriteLong (VM_M_WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM0));
+       MSG_WriteLong (VM_M_WriteDest(prog), (int)PRVM_G_FLOAT(OFS_PARM0));
 }
 
-void VM_M_WriteAngle (void)
+static void VM_M_WriteAngle (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_M_WriteAngle);
-       MSG_WriteAngle (VM_M_WriteDest(), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
+       MSG_WriteAngle (VM_M_WriteDest(prog), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
 }
 
-void VM_M_WriteCoord (void)
+static void VM_M_WriteCoord (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_M_WriteCoord);
-       MSG_WriteCoord (VM_M_WriteDest(), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
+       MSG_WriteCoord (VM_M_WriteDest(prog), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
 }
 
-void VM_M_WriteString (void)
+static void VM_M_WriteString (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_M_WriteString);
-       MSG_WriteString (VM_M_WriteDest(), PRVM_G_STRING(OFS_PARM0));
+       MSG_WriteString (VM_M_WriteDest(prog), PRVM_G_STRING(OFS_PARM0));
 }
 
-void VM_M_WriteEntity (void)
+static void VM_M_WriteEntity (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_M_WriteEntity);
-       MSG_WriteShort (VM_M_WriteDest(), PRVM_G_EDICTNUM(OFS_PARM0));
+       MSG_WriteShort (VM_M_WriteDest(prog), PRVM_G_EDICTNUM(OFS_PARM0));
 }
 
 /*
@@ -732,7 +733,7 @@ copies data from one entity to another
 copyentity(entity src, entity dst)
 =================
 */
-static void VM_M_copyentity (void)
+static void VM_M_copyentity (prvm_prog_t *prog)
 {
        prvm_edict_t *in, *out;
        VM_SAFEPARMCOUNT(2,VM_M_copyentity);
@@ -742,7 +743,7 @@ static void VM_M_copyentity (void)
 }
 
 //#66 vector() getmousepos (EXT_CSQC)
-static void VM_M_getmousepos(void)
+static void VM_M_getmousepos(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0,VM_M_getmousepos);
 
@@ -754,7 +755,7 @@ static void VM_M_getmousepos(void)
                VectorSet(PRVM_G_VECTOR(OFS_RETURN), in_mouse_x * vid_conwidth.integer / vid.width, in_mouse_y * vid_conheight.integer / vid.height, 0);
 }
 
-void VM_M_crypto_getkeyfp(void)
+static void VM_M_crypto_getkeyfp(prvm_prog_t *prog)
 {
        lhnetaddress_t addr;
        const char *s;
@@ -763,14 +764,14 @@ void VM_M_crypto_getkeyfp(void)
        VM_SAFEPARMCOUNT(1,VM_M_crypto_getkeyfp);
 
        s = PRVM_G_STRING( OFS_PARM0 );
-       VM_CheckEmptyString( s );
+       VM_CheckEmptyString( prog, s );
 
        if(LHNETADDRESS_FromString(&addr, s, 26000) && Crypto_RetrieveHostKey(&addr, NULL, keyfp, sizeof(keyfp), NULL, 0, NULL))
-               PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( keyfp );
+               PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, keyfp );
        else
                PRVM_G_INT( OFS_RETURN ) = OFS_NULL;
 }
-void VM_M_crypto_getidfp(void)
+static void VM_M_crypto_getidfp(prvm_prog_t *prog)
 {
        lhnetaddress_t addr;
        const char *s;
@@ -779,30 +780,31 @@ void VM_M_crypto_getidfp(void)
        VM_SAFEPARMCOUNT(1,VM_M_crypto_getidfp);
 
        s = PRVM_G_STRING( OFS_PARM0 );
-       VM_CheckEmptyString( s );
+       VM_CheckEmptyString( prog, s );
 
        if(LHNETADDRESS_FromString(&addr, s, 26000) && Crypto_RetrieveHostKey(&addr, NULL, NULL, 0, idfp, sizeof(idfp), NULL))
-               PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( idfp );
+               PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( prog, idfp );
        else
                PRVM_G_INT( OFS_RETURN ) = OFS_NULL;
 }
-void VM_M_crypto_getencryptlevel(void)
+static void VM_M_crypto_getencryptlevel(prvm_prog_t *prog)
 {
        lhnetaddress_t addr;
        const char *s;
        int aeslevel;
+       char vabuf[1024];
 
        VM_SAFEPARMCOUNT(1,VM_M_crypto_getencryptlevel);
 
        s = PRVM_G_STRING( OFS_PARM0 );
-       VM_CheckEmptyString( s );
+       VM_CheckEmptyString( prog, s );
 
        if(LHNETADDRESS_FromString(&addr, s, 26000) && Crypto_RetrieveHostKey(&addr, NULL, NULL, 0, NULL, 0, &aeslevel))
-               PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(aeslevel ? va("%d AES128", aeslevel) : "0");
+               PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog, aeslevel ? va(vabuf, sizeof(vabuf), "%d AES128", aeslevel) : "0");
        else
                PRVM_G_INT( OFS_RETURN ) = OFS_NULL;
 }
-void VM_M_crypto_getmykeyfp(void)
+static void VM_M_crypto_getmykeyfp(prvm_prog_t *prog)
 {
        int i;
        char keyfp[FP64_SIZE + 1];
@@ -813,18 +815,18 @@ void VM_M_crypto_getmykeyfp(void)
        switch(Crypto_RetrieveLocalKey(i, keyfp, sizeof(keyfp), NULL, 0))
        {
                case -1:
-                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString("");
+                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog, "");
                        break;
                case 0:
                        PRVM_G_INT( OFS_RETURN ) = OFS_NULL;
                        break;
                default:
                case 1:
-                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(keyfp);
+                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog, keyfp);
                        break;
        }
 }
-void VM_M_crypto_getmyidfp(void)
+static void VM_M_crypto_getmyidfp(prvm_prog_t *prog)
 {
        int i;
        char idfp[FP64_SIZE + 1];
@@ -835,14 +837,14 @@ void VM_M_crypto_getmyidfp(void)
        switch(Crypto_RetrieveLocalKey(i, NULL, 0, idfp, sizeof(idfp)))
        {
                case -1:
-                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString("");
+                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog, "");
                        break;
                case 0:
                        PRVM_G_INT( OFS_RETURN ) = OFS_NULL;
                        break;
                default:
                case 1:
-                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(idfp);
+                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog, idfp);
                        break;
        }
 }
@@ -1520,12 +1522,12 @@ NULL
 
 const int vm_m_numbuiltins = sizeof(vm_m_builtins) / sizeof(prvm_builtin_t);
 
-void VM_M_Cmd_Init(void)
+void MVM_init_cmd(prvm_prog_t *prog)
 {
        r_refdef_scene_t *scene;
 
-       VM_Cmd_Init();
-       VM_Polygons_Reset();
+       VM_Cmd_Init(prog);
+       VM_Polygons_Reset(prog);
 
        scene = R_GetScenePointer( RST_MENU );
 
@@ -1540,11 +1542,11 @@ void VM_M_Cmd_Init(void)
        scene->ambient = 32.0f;
 }
 
-void VM_M_Cmd_Reset(void)
+void MVM_reset_cmd(prvm_prog_t *prog)
 {
        // note: the menu's render entities are automatically freed when the prog's pool is freed
 
        //VM_Cmd_Init();
-       VM_Cmd_Reset();
-       VM_Polygons_Reset();
+       VM_Cmd_Reset(prog);
+       VM_Polygons_Reset(prog);
 }
index 160803f824939d8ced6191ce721627f3fa52fa5c..aa839eefc39c06681d49cfb753c52d09a9a010f1 100755 (executable)
--- a/netconn.c
+++ b/netconn.c
@@ -69,8 +69,12 @@ static cvar_t sv_qwmasters [] =
 
 static double nextheartbeattime = 0;
 
-sizebuf_t net_message;
-static unsigned char net_message_buf[NET_MAXMESSAGE];
+sizebuf_t cl_message;
+sizebuf_t sv_message;
+static unsigned char cl_message_buf[NET_MAXMESSAGE];
+static unsigned char sv_message_buf[NET_MAXMESSAGE];
+char cl_readstring[MAX_INPUTLINE];
+char sv_readstring[MAX_INPUTLINE];
 
 cvar_t net_messagetimeout = {0, "net_messagetimeout","300", "drops players who have not sent any packets for this many seconds"};
 cvar_t net_connecttimeout = {0, "net_connecttimeout","15", "after requesting a connection, the client must reply within this many seconds or be dropped (cuts down on connect floods). Must be above 10 seconds."};
@@ -96,18 +100,6 @@ static cvar_t rcon_secure_maxdiff = {0, "rcon_secure_maxdiff", "5", "maximum tim
 extern cvar_t rcon_secure;
 extern cvar_t rcon_secure_challengetimeout;
 
-/* statistic counters */
-static int packetsSent = 0;
-static int packetsReSent = 0;
-static int packetsReceived = 0;
-static int receivedDuplicateCount = 0;
-static int droppedDatagrams = 0;
-
-static int unreliableMessagesSent = 0;
-static int unreliableMessagesReceived = 0;
-static int reliableMessagesSent = 0;
-static int reliableMessagesReceived = 0;
-
 double masterquerytime = -1000;
 int masterquerycount = 0;
 int masterreplycount = 0;
@@ -124,11 +116,6 @@ static qboolean serverlist_paused = false;
 /// flooding in (which would make a mess of the ping times)
 static double serverlist_querywaittime = 0;
 
-static unsigned char sendbuffer[NET_HEADERSIZE+NET_MAXMESSAGE];
-static unsigned char readbuffer[NET_HEADERSIZE+NET_MAXMESSAGE];
-static unsigned char cryptosendbuffer[NET_HEADERSIZE+NET_MAXMESSAGE+CRYPTO_HEADERSIZE];
-static unsigned char cryptoreadbuffer[NET_HEADERSIZE+NET_MAXMESSAGE+CRYPTO_HEADERSIZE];
-
 static int cl_numsockets;
 static lhnetsocket_t *cl_sockets[16];
 static int sv_numsockets;
@@ -677,6 +664,8 @@ qboolean NetConn_CanSend(netconn_t *conn)
 int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data, protocolversion_t protocol, int rate, qboolean quakesignon_suppressreliables)
 {
        int totallen = 0;
+       unsigned char sendbuffer[NET_HEADERSIZE+NET_MAXMESSAGE];
+       unsigned char cryptosendbuffer[NET_HEADERSIZE+NET_MAXMESSAGE+CRYPTO_HEADERSIZE];
 
        // if this packet was supposedly choked, but we find ourselves sending one
        // anyway, make sure the size counting starts at zero
@@ -746,8 +735,8 @@ int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data, protocolvers
 
                NetConn_Write(conn->mysocket, (void *)&sendbuffer, packetLen, &conn->peeraddress);
 
-               packetsSent++;
-               unreliableMessagesSent++;
+               conn->packetsSent++;
+               conn->unreliableMessagesSent++;
 
                totallen += packetLen + 28;
        }
@@ -785,7 +774,7 @@ int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data, protocolvers
                        if (sendme && NetConn_Write(conn->mysocket, sendme, sendmelen, &conn->peeraddress) == (int)sendmelen)
                        {
                                conn->lastSendTime = realtime;
-                               packetsReSent++;
+                               conn->packetsReSent++;
                        }
 
                        totallen += sendmelen + 28;
@@ -837,8 +826,8 @@ int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data, protocolvers
                                NetConn_Write(conn->mysocket, sendme, sendmelen, &conn->peeraddress);
 
                        conn->lastSendTime = realtime;
-                       packetsSent++;
-                       reliableMessagesSent++;
+                       conn->packetsSent++;
+                       conn->reliableMessagesSent++;
 
                        totallen += sendmelen + 28;
                }
@@ -866,8 +855,8 @@ int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data, protocolvers
                        if(sendme)
                                NetConn_Write(conn->mysocket, sendme, sendmelen, &conn->peeraddress);
 
-                       packetsSent++;
-                       unreliableMessagesSent++;
+                       conn->packetsSent++;
+                       conn->unreliableMessagesSent++;
 
                        totallen += sendmelen + 28;
                }
@@ -900,7 +889,7 @@ void NetConn_CloseClientPorts(void)
                        LHNET_CloseSocket(cl_sockets[cl_numsockets - 1]);
 }
 
-void NetConn_OpenClientPort(const char *addressstring, lhnetaddresstype_t addresstype, int defaultport)
+static void NetConn_OpenClientPort(const char *addressstring, lhnetaddresstype_t addresstype, int defaultport)
 {
        lhnetaddress_t address;
        lhnetsocket_t *s;
@@ -954,7 +943,7 @@ void NetConn_CloseServerPorts(void)
                        LHNET_CloseSocket(sv_sockets[sv_numsockets - 1]);
 }
 
-qboolean NetConn_OpenServerPort(const char *addressstring, lhnetaddresstype_t addresstype, int defaultport, int range)
+static qboolean NetConn_OpenServerPort(const char *addressstring, lhnetaddresstype_t addresstype, int defaultport, int range)
 {
        lhnetaddress_t address;
        lhnetsocket_t *s;
@@ -1138,6 +1127,9 @@ void NetConn_UpdateSockets(void)
 static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, size_t length, protocolversion_t protocol, double newtimeout)
 {
        int originallength = length;
+       unsigned char sendbuffer[NET_HEADERSIZE+NET_MAXMESSAGE];
+       unsigned char cryptosendbuffer[NET_HEADERSIZE+NET_MAXMESSAGE+CRYPTO_HEADERSIZE];
+       unsigned char cryptoreadbuffer[NET_HEADERSIZE+NET_MAXMESSAGE+CRYPTO_HEADERSIZE];
        if (length < 8)
                return 0;
 
@@ -1164,7 +1156,7 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s
                        length -= 2;
                }
 
-               packetsReceived++;
+               conn->packetsReceived++;
                reliable_message = (sequence >> 31) & 1;
                reliable_ack = (sequence_ack >> 31) & 1;
                sequence &= ~(1<<31);
@@ -1177,7 +1169,7 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s
                count = sequence - (conn->qw.incoming_sequence + 1);
                if (count > 0)
                {
-                       droppedDatagrams += count;
+                       conn->droppedDatagrams += count;
                        //Con_DPrintf("Dropped %u datagram(s)\n", count);
                        while (count--)
                        {
@@ -1197,7 +1189,7 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s
                {
                        // received, now we will be able to send another reliable message
                        conn->sendMessageLength = 0;
-                       reliableMessagesReceived++;
+                       conn->reliableMessagesReceived++;
                }
                conn->qw.incoming_sequence = sequence;
                if (conn == cls.netcon)
@@ -1208,10 +1200,19 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s
                        conn->qw.incoming_reliable_sequence ^= 1;
                conn->lastMessageTime = realtime;
                conn->timeout = realtime + newtimeout;
-               unreliableMessagesReceived++;
-               SZ_Clear(&net_message);
-               SZ_Write(&net_message, data, length);
-               MSG_BeginReading();
+               conn->unreliableMessagesReceived++;
+               if (conn == cls.netcon)
+               {
+                       SZ_Clear(&cl_message);
+                       SZ_Write(&cl_message, data, length);
+                       MSG_BeginReading(&cl_message);
+               }
+               else
+               {
+                       SZ_Clear(&sv_message);
+                       SZ_Write(&sv_message, data, length);
+                       MSG_BeginReading(&sv_message);
+               }
                return 2;
        }
        else
@@ -1237,7 +1238,7 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s
                if (!(flags & NETFLAG_CTL) && qlength == length)
                {
                        sequence = BuffBigLong(data + 4);
-                       packetsReceived++;
+                       conn->packetsReceived++;
                        data += 8;
                        length -= 8;
                        if (flags & NETFLAG_UNRELIABLE)
@@ -1247,7 +1248,7 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s
                                        if (sequence > conn->nq.unreliableReceiveSequence)
                                        {
                                                count = sequence - conn->nq.unreliableReceiveSequence;
-                                               droppedDatagrams += count;
+                                               conn->droppedDatagrams += count;
                                                //Con_DPrintf("Dropped %u datagram(s)\n", count);
                                                while (count--)
                                                {
@@ -1266,12 +1267,21 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s
                                        conn->nq.unreliableReceiveSequence = sequence + 1;
                                        conn->lastMessageTime = realtime;
                                        conn->timeout = realtime + newtimeout;
-                                       unreliableMessagesReceived++;
+                                       conn->unreliableMessagesReceived++;
                                        if (length > 0)
                                        {
-                                               SZ_Clear(&net_message);
-                                               SZ_Write(&net_message, data, length);
-                                               MSG_BeginReading();
+                                               if (conn == cls.netcon)
+                                               {
+                                                       SZ_Clear(&cl_message);
+                                                       SZ_Write(&cl_message, data, length);
+                                                       MSG_BeginReading(&cl_message);
+                                               }
+                                               else
+                                               {
+                                                       SZ_Clear(&sv_message);
+                                                       SZ_Write(&sv_message, data, length);
+                                                       MSG_BeginReading(&sv_message);
+                                               }
                                                return 2;
                                        }
                                }
@@ -1323,7 +1333,7 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s
                                                        if (sendme && NetConn_Write(conn->mysocket, sendme, sendmelen, &conn->peeraddress) == (int)sendmelen)
                                                        {
                                                                conn->lastSendTime = realtime;
-                                                               packetsSent++;
+                                                               conn->packetsSent++;
                                                        }
                                                }
                                                else
@@ -1362,20 +1372,29 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s
                                        }
                                        if (flags & NETFLAG_EOM)
                                        {
-                                               reliableMessagesReceived++;
+                                               conn->reliableMessagesReceived++;
                                                length = conn->receiveMessageLength;
                                                conn->receiveMessageLength = 0;
                                                if (length > 0)
                                                {
-                                                       SZ_Clear(&net_message);
-                                                       SZ_Write(&net_message, conn->receiveMessage, length);
-                                                       MSG_BeginReading();
+                                                       if (conn == cls.netcon)
+                                                       {
+                                                               SZ_Clear(&cl_message);
+                                                               SZ_Write(&cl_message, conn->receiveMessage, length);
+                                                               MSG_BeginReading(&cl_message);
+                                                       }
+                                                       else
+                                                       {
+                                                               SZ_Clear(&sv_message);
+                                                               SZ_Write(&sv_message, conn->receiveMessage, length);
+                                                               MSG_BeginReading(&sv_message);
+                                                       }
                                                        return 2;
                                                }
                                        }
                                }
                                else
-                                       receivedDuplicateCount++;
+                                       conn->receivedDuplicateCount++;
                                return 1;
                        }
                }
@@ -1383,7 +1402,7 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s
        return 0;
 }
 
-void NetConn_ConnectionEstablished(lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress, protocolversion_t initialprotocol)
+static void NetConn_ConnectionEstablished(lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress, protocolversion_t initialprotocol)
 {
        crypto_t *crypto;
        cls.connect_trying = false;
@@ -1392,7 +1411,11 @@ void NetConn_ConnectionEstablished(lhnetsocket_t *mysocket, lhnetaddress_t *peer
        CL_Disconnect();
        // if we're connecting to a remote server, shut down any local server
        if (LHNETADDRESS_GetAddressType(peeraddress) != LHNETADDRESSTYPE_LOOP && sv.active)
+       {
+               SV_LockThreadMutex();
                Host_ShutdownServer ();
+               SV_UnlockThreadMutex();
+       }
        // allocate a net connection to keep track of things
        cls.netcon = NetConn_Open(mysocket, peeraddress);
        crypto = &cls.crypto;
@@ -1603,10 +1626,11 @@ static void NetConn_ClientParsePacket_ServerList_ParseDPList(lhnetaddress_t *sen
                        {
 #ifdef WHY_JUST_WHY
                                const char *ifname;
+                               char ifnamebuf[16];
 
                                /// \TODO: make some basic checks of the IP address (broadcast, ...)
 
-                               ifname = LHNETADDRESS_GetInterfaceName(senderaddress);
+                               ifname = LHNETADDRESS_GetInterfaceName(senderaddress, ifnamebuf, sizeof(ifnamebuf));
                                if (ifname != NULL)
                                {
                                        dpsnprintf (ipstring, sizeof (ipstring), "[%x:%x:%x:%x:%x:%x:%x:%x%%%s]:%hu",
@@ -1657,6 +1681,8 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
        char stringbuf[16384];
        char senddata[NET_HEADERSIZE+NET_MAXMESSAGE+CRYPTO_HEADERSIZE];
        size_t sendlength;
+       char infostringvalue[MAX_INPUTLINE];
+       char vabuf[1024];
 
        // quakeworld ingame packet
        fromserver = cls.netcon && mysocket == cls.netcon->mysocket && !LHNETADDRESS_Compare(&cls.netcon->peeraddress, peeraddress);
@@ -1769,7 +1795,7 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                        // update the server IP in the userinfo (QW servers expect this, and it is used by the reconnect command)
                        InfoString_SetValue(cls.userinfo, sizeof(cls.userinfo), "*ip", addressstring2);
                        // TODO: add userinfo stuff here instead of using NQ commands?
-                       NetConn_WriteString(mysocket, va("\377\377\377\377connect\\protocol\\darkplaces 3\\protocols\\%s%s\\challenge\\%s", protocolnames, cls.connect_userinfo, string + 10), peeraddress);
+                       NetConn_WriteString(mysocket, va(vabuf, sizeof(vabuf), "\377\377\377\377connect\\protocol\\darkplaces 3\\protocols\\%s%s\\challenge\\%s", protocolnames, cls.connect_userinfo, string + 10), peeraddress);
                        return true;
                }
                if (length == 6 && !memcmp(string, "accept", 6) && cls.connect_trying)
@@ -1824,17 +1850,17 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                        else
                                Con_Printf("statusResponse without players block?\n");
 
-                       if ((s = SearchInfostring(string, "gamename"     )) != NULL) strlcpy(info->game, s, sizeof (info->game));
-                       if ((s = SearchInfostring(string, "modname"      )) != NULL) strlcpy(info->mod , s, sizeof (info->mod ));
-                       if ((s = SearchInfostring(string, "mapname"      )) != NULL) strlcpy(info->map , s, sizeof (info->map ));
-                       if ((s = SearchInfostring(string, "hostname"     )) != NULL) strlcpy(info->name, s, sizeof (info->name));
-                       if ((s = SearchInfostring(string, "protocol"     )) != NULL) info->protocol = atoi(s);
-                       if ((s = SearchInfostring(string, "clients"      )) != NULL) info->numplayers = atoi(s);
-                       if ((s = SearchInfostring(string, "bots"         )) != NULL) info->numbots = atoi(s);
-                       if ((s = SearchInfostring(string, "sv_maxclients")) != NULL) info->maxplayers = atoi(s);
-                       if ((s = SearchInfostring(string, "gameversion"  )) != NULL) info->gameversion = atoi(s);
-                       if ((s = SearchInfostring(string, "qcstatus"     )) != NULL) strlcpy(info->qcstatus, s, sizeof(info->qcstatus));
-                       if (p                                               != NULL) strlcpy(info->players, p, sizeof(info->players));
+                       if ((s = InfoString_GetValue(string, "gamename"     , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->game, s, sizeof (info->game));
+                       if ((s = InfoString_GetValue(string, "modname"      , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->mod , s, sizeof (info->mod ));
+                       if ((s = InfoString_GetValue(string, "mapname"      , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->map , s, sizeof (info->map ));
+                       if ((s = InfoString_GetValue(string, "hostname"     , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->name, s, sizeof (info->name));
+                       if ((s = InfoString_GetValue(string, "protocol"     , infostringvalue, sizeof(infostringvalue))) != NULL) info->protocol = atoi(s);
+                       if ((s = InfoString_GetValue(string, "clients"      , infostringvalue, sizeof(infostringvalue))) != NULL) info->numplayers = atoi(s);
+                       if ((s = InfoString_GetValue(string, "bots"         , infostringvalue, sizeof(infostringvalue))) != NULL) info->numbots = atoi(s);
+                       if ((s = InfoString_GetValue(string, "sv_maxclients", infostringvalue, sizeof(infostringvalue))) != NULL) info->maxplayers = atoi(s);
+                       if ((s = InfoString_GetValue(string, "gameversion"  , infostringvalue, sizeof(infostringvalue))) != NULL) info->gameversion = atoi(s);
+                       if ((s = InfoString_GetValue(string, "qcstatus"     , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->qcstatus, s, sizeof(info->qcstatus));
+                       if (p                                                                                         != NULL) strlcpy(info->players, p, sizeof(info->players));
                        info->numhumans = info->numplayers - max(0, info->numbots);
                        info->freeslots = info->maxplayers - info->numplayers;
 
@@ -1866,16 +1892,16 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                        info->maxplayers  = 0;
                        info->gameversion = 0;
 
-                       if ((s = SearchInfostring(string, "gamename"     )) != NULL) strlcpy(info->game, s, sizeof (info->game));
-                       if ((s = SearchInfostring(string, "modname"      )) != NULL) strlcpy(info->mod , s, sizeof (info->mod ));
-                       if ((s = SearchInfostring(string, "mapname"      )) != NULL) strlcpy(info->map , s, sizeof (info->map ));
-                       if ((s = SearchInfostring(string, "hostname"     )) != NULL) strlcpy(info->name, s, sizeof (info->name));
-                       if ((s = SearchInfostring(string, "protocol"     )) != NULL) info->protocol = atoi(s);
-                       if ((s = SearchInfostring(string, "clients"      )) != NULL) info->numplayers = atoi(s);
-                       if ((s = SearchInfostring(string, "bots"         )) != NULL) info->numbots = atoi(s);
-                       if ((s = SearchInfostring(string, "sv_maxclients")) != NULL) info->maxplayers = atoi(s);
-                       if ((s = SearchInfostring(string, "gameversion"  )) != NULL) info->gameversion = atoi(s);
-                       if ((s = SearchInfostring(string, "qcstatus"     )) != NULL) strlcpy(info->qcstatus, s, sizeof(info->qcstatus));
+                       if ((s = InfoString_GetValue(string, "gamename"     , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->game, s, sizeof (info->game));
+                       if ((s = InfoString_GetValue(string, "modname"      , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->mod , s, sizeof (info->mod ));
+                       if ((s = InfoString_GetValue(string, "mapname"      , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->map , s, sizeof (info->map ));
+                       if ((s = InfoString_GetValue(string, "hostname"     , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->name, s, sizeof (info->name));
+                       if ((s = InfoString_GetValue(string, "protocol"     , infostringvalue, sizeof(infostringvalue))) != NULL) info->protocol = atoi(s);
+                       if ((s = InfoString_GetValue(string, "clients"      , infostringvalue, sizeof(infostringvalue))) != NULL) info->numplayers = atoi(s);
+                       if ((s = InfoString_GetValue(string, "bots"         , infostringvalue, sizeof(infostringvalue))) != NULL) info->numbots = atoi(s);
+                       if ((s = InfoString_GetValue(string, "sv_maxclients", infostringvalue, sizeof(infostringvalue))) != NULL) info->maxplayers = atoi(s);
+                       if ((s = InfoString_GetValue(string, "gameversion"  , infostringvalue, sizeof(infostringvalue))) != NULL) info->gameversion = atoi(s);
+                       if ((s = InfoString_GetValue(string, "qcstatus"     , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->qcstatus, s, sizeof(info->qcstatus));
                        info->numhumans = info->numplayers - max(0, info->numbots);
                        info->freeslots = info->maxplayers - info->numplayers;
 
@@ -1953,7 +1979,7 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                        cls.qw_qport = qport.integer;
                        // update the server IP in the userinfo (QW servers expect this, and it is used by the reconnect command)
                        InfoString_SetValue(cls.userinfo, sizeof(cls.userinfo), "*ip", addressstring2);
-                       NetConn_WriteString(mysocket, va("\377\377\377\377connect %i %i %i \"%s%s\"\n", 28, cls.qw_qport, atoi(string + 1), cls.userinfo, cls.connect_userinfo), peeraddress);
+                       NetConn_WriteString(mysocket, va(vabuf, sizeof(vabuf), "\377\377\377\377connect %i %i %i \"%s%s\"\n", 28, cls.qw_qport, atoi(string + 1), cls.userinfo, cls.connect_userinfo), peeraddress);
                        return true;
                }
                if (length >= 1 && string[0] == 'j' && cls.connect_trying)
@@ -1980,14 +2006,14 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
 
                        info = &serverlist_cache[n].info;
                        strlcpy(info->game, "QuakeWorld", sizeof(info->game));
-                       if ((s = SearchInfostring(string, "*gamedir"     )) != NULL) strlcpy(info->mod , s, sizeof (info->mod ));else info->mod[0]  = 0;
-                       if ((s = SearchInfostring(string, "map"          )) != NULL) strlcpy(info->map , s, sizeof (info->map ));else info->map[0]  = 0;
-                       if ((s = SearchInfostring(string, "hostname"     )) != NULL) strlcpy(info->name, s, sizeof (info->name));else info->name[0] = 0;
+                       if ((s = InfoString_GetValue(string, "*gamedir"     , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->mod , s, sizeof (info->mod ));else info->mod[0]  = 0;
+                       if ((s = InfoString_GetValue(string, "map"          , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->map , s, sizeof (info->map ));else info->map[0]  = 0;
+                       if ((s = InfoString_GetValue(string, "hostname"     , infostringvalue, sizeof(infostringvalue))) != NULL) strlcpy(info->name, s, sizeof (info->name));else info->name[0] = 0;
                        info->protocol = 0;
                        info->numplayers = 0; // updated below
                        info->numhumans = 0; // updated below
-                       if ((s = SearchInfostring(string, "maxclients"   )) != NULL) info->maxplayers = atoi(s);else info->maxplayers  = 0;
-                       if ((s = SearchInfostring(string, "gameversion"  )) != NULL) info->gameversion = atoi(s);else info->gameversion = 0;
+                       if ((s = InfoString_GetValue(string, "maxclients"   , infostringvalue, sizeof(infostringvalue))) != NULL) info->maxplayers = atoi(s);else info->maxplayers  = 0;
+                       if ((s = InfoString_GetValue(string, "gameversion"  , infostringvalue, sizeof(infostringvalue))) != NULL) info->gameversion = atoi(s);else info->gameversion = 0;
 
                        // count active players on server
                        // (we could gather more info, but we're just after the number)
@@ -2035,10 +2061,10 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
 
                data += 4;
                length -= 4;
-               SZ_Clear(&net_message);
-               SZ_Write(&net_message, data, length);
-               MSG_BeginReading();
-               c = MSG_ReadByte();
+               SZ_Clear(&cl_message);
+               SZ_Write(&cl_message, data, length);
+               MSG_BeginReading(&cl_message);
+               c = MSG_ReadByte(&cl_message);
                switch (c)
                {
                case CCREP_ACCEPT:
@@ -2048,18 +2074,18 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                        {
                                lhnetaddress_t clientportaddress;
                                clientportaddress = *peeraddress;
-                               LHNETADDRESS_SetPort(&clientportaddress, MSG_ReadLong());
+                               LHNETADDRESS_SetPort(&clientportaddress, MSG_ReadLong(&cl_message));
                                // extra ProQuake stuff
                                if (length >= 6)
-                                       cls.proquake_servermod = MSG_ReadByte(); // MOD_PROQUAKE
+                                       cls.proquake_servermod = MSG_ReadByte(&cl_message); // MOD_PROQUAKE
                                else
                                        cls.proquake_servermod = 0;
                                if (length >= 7)
-                                       cls.proquake_serverversion = MSG_ReadByte(); // version * 10
+                                       cls.proquake_serverversion = MSG_ReadByte(&cl_message); // version * 10
                                else
                                        cls.proquake_serverversion = 0;
                                if (length >= 8)
-                                       cls.proquake_serverflags = MSG_ReadByte(); // flags (mainly PQF_CHEATFREE)
+                                       cls.proquake_serverflags = MSG_ReadByte(&cl_message); // flags (mainly PQF_CHEATFREE)
                                else
                                        cls.proquake_serverflags = 0;
                                if (cls.proquake_servermod == 1)
@@ -2074,14 +2100,14 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                        if (developer_extra.integer)
                                Con_DPrintf("Datagram_ParseConnectionless: received CCREP_REJECT from %s.\n", addressstring2);
                        cls.connect_trying = false;
-                       M_Update_Return_Reason((char *)MSG_ReadString());
+                       M_Update_Return_Reason((char *)MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)));
                        break;
                case CCREP_SERVER_INFO:
                        if (developer_extra.integer)
                                Con_DPrintf("Datagram_ParseConnectionless: received CCREP_SERVER_INFO from %s.\n", addressstring2);
                        // LordHavoc: because the quake server may report weird addresses
                        // we just ignore it and keep the real address
-                       MSG_ReadString();
+                       MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
                        // search the cache for this server and update it
                        n = NetConn_ClientParsePacket_ServerList_ProcessReply(addressstring2);
                        if (n < 0)
@@ -2090,11 +2116,11 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                        info = &serverlist_cache[n].info;
                        strlcpy(info->game, "Quake", sizeof(info->game));
                        strlcpy(info->mod , "", sizeof(info->mod)); // mod name is not specified
-                       strlcpy(info->name, MSG_ReadString(), sizeof(info->name));
-                       strlcpy(info->map , MSG_ReadString(), sizeof(info->map));
-                       info->numplayers = MSG_ReadByte();
-                       info->maxplayers = MSG_ReadByte();
-                       info->protocol = MSG_ReadByte();
+                       strlcpy(info->name, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof(info->name));
+                       strlcpy(info->map , MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof(info->map));
+                       info->numplayers = MSG_ReadByte(&cl_message);
+                       info->maxplayers = MSG_ReadByte(&cl_message);
+                       info->protocol = MSG_ReadByte(&cl_message);
 
                        NetConn_ClientParsePacket_ServerList_UpdateCache(n);
 
@@ -2103,7 +2129,7 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                        if (developer_extra.integer)
                                Con_DPrintf("Datagram_ParseConnectionless: received CCREP_RCON from %s.\n", addressstring2);
 
-                       Con_Printf("%s\n", MSG_ReadString());
+                       Con_Printf("%s\n", MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)));
                        break;
                case CCREP_PLAYER_INFO:
                        // we got a CCREP_PLAYER_INFO??
@@ -2118,7 +2144,7 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                default:
                        break;
                }
-               SZ_Clear(&net_message);
+               SZ_Clear(&cl_message);
                // we may not have liked the packet, but it was a valid control
                // packet, so we're done processing this packet now
                return true;
@@ -2222,6 +2248,7 @@ void NetConn_ClientFrame(void)
 {
        int i, length;
        lhnetaddress_t peeraddress;
+       unsigned char readbuffer[NET_HEADERSIZE+NET_MAXMESSAGE];
        NetConn_UpdateSockets();
        if (cls.connect_trying && cls.connect_nextsendtime < realtime)
        {
@@ -2238,24 +2265,24 @@ void NetConn_ClientFrame(void)
                // try challenge first (newer DP server or QW)
                NetConn_WriteString(cls.connect_mysocket, "\377\377\377\377getchallenge", &cls.connect_address);
                // then try netquake as a fallback (old server, or netquake)
-               SZ_Clear(&net_message);
+               SZ_Clear(&cl_message);
                // save space for the header, filled in later
-               MSG_WriteLong(&net_message, 0);
-               MSG_WriteByte(&net_message, CCREQ_CONNECT);
-               MSG_WriteString(&net_message, "QUAKE");
-               MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
+               MSG_WriteLong(&cl_message, 0);
+               MSG_WriteByte(&cl_message, CCREQ_CONNECT);
+               MSG_WriteString(&cl_message, "QUAKE");
+               MSG_WriteByte(&cl_message, NET_PROTOCOL_VERSION);
                // extended proquake stuff
-               MSG_WriteByte(&net_message, 1); // mod = MOD_PROQUAKE
+               MSG_WriteByte(&cl_message, 1); // mod = MOD_PROQUAKE
                // this version matches ProQuake 3.40, the first version to support
                // the NAT fix, and it only supports the NAT fix for ProQuake 3.40 or
                // higher clients, so we pretend we are that version...
-               MSG_WriteByte(&net_message, 34); // version * 10
-               MSG_WriteByte(&net_message, 0); // flags
-               MSG_WriteLong(&net_message, 0); // password
+               MSG_WriteByte(&cl_message, 34); // version * 10
+               MSG_WriteByte(&cl_message, 0); // flags
+               MSG_WriteLong(&cl_message, 0); // password
                // write the packetsize now...
-               StoreBigLong(net_message.data, NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
-               NetConn_Write(cls.connect_mysocket, net_message.data, net_message.cursize, &cls.connect_address);
-               SZ_Clear(&net_message);
+               StoreBigLong(cl_message.data, NETFLAG_CTL | (cl_message.cursize & NETFLAG_LENGTH_MASK));
+               NetConn_Write(cls.connect_mysocket, cl_message.data, cl_message.cursize, &cls.connect_address);
+               SZ_Clear(&cl_message);
        }
        for (i = 0;i < cl_numsockets;i++)
        {
@@ -2271,7 +2298,9 @@ void NetConn_ClientFrame(void)
        {
                Con_Print("Connection timed out\n");
                CL_Disconnect();
+               SV_LockThreadMutex();
                Host_ShutdownServer ();
+               SV_UnlockThreadMutex();
        }
 }
 
@@ -2293,6 +2322,7 @@ static void NetConn_BuildChallengeString(char *buffer, int bufferlength)
 /// (div0) build the full response only if possible; better a getinfo response than no response at all if getstatus won't fit
 static qboolean NetConn_BuildStatusResponse(const char* challenge, char* out_msg, size_t out_size, qboolean fullstatus)
 {
+       prvm_prog_t *prog = SVVM_prog;
        char qcstatus[256];
        unsigned int nb_clients = 0, nb_bots = 0, i;
        int length;
@@ -2300,8 +2330,6 @@ static qboolean NetConn_BuildStatusResponse(const char* challenge, char* out_msg
        const char *crypto_idstring;
        const char *str;
 
-       SV_VM_Begin();
-
        // How many clients are there?
        for (i = 0;i < (unsigned int)svs.maxclients;i++)
        {
@@ -2314,7 +2342,7 @@ static qboolean NetConn_BuildStatusResponse(const char* challenge, char* out_msg
        }
 
        *qcstatus = 0;
-       str = PRVM_GetString(PRVM_serverglobalstring(worldstatus));
+       str = PRVM_GetString(prog, PRVM_serverglobalstring(worldstatus));
        if(str && *str)
        {
                char *p;
@@ -2393,7 +2421,7 @@ static qboolean NetConn_BuildStatusResponse(const char* challenge, char* out_msg
 
                                *qcstatus = 0;
                                ed = PRVM_EDICT_NUM(i + 1);
-                               str = PRVM_GetString(PRVM_serveredictstring(ed, clientstatus));
+                               str = PRVM_GetString(prog, PRVM_serveredictstring(ed, clientstatus));
                                if(str && *str)
                                {
                                        char *p;
@@ -2452,11 +2480,9 @@ static qboolean NetConn_BuildStatusResponse(const char* challenge, char* out_msg
                }
        }
 
-       SV_VM_End();
        return true;
 
 bad:
-       SV_VM_End();
        return false;
 }
 
@@ -2522,7 +2548,7 @@ void NetConn_ClearConnectFlood(lhnetaddress_t *peeraddress)
 
 typedef qboolean (*rcon_matchfunc_t) (lhnetaddress_t *peeraddress, const char *password, const char *hash, const char *s, int slen);
 
-qboolean hmac_mdfour_time_matching(lhnetaddress_t *peeraddress, const char *password, const char *hash, const char *s, int slen)
+static qboolean hmac_mdfour_time_matching(lhnetaddress_t *peeraddress, const char *password, const char *hash, const char *s, int slen)
 {
        char mdfourbuf[16];
        long t1, t2;
@@ -2538,7 +2564,7 @@ qboolean hmac_mdfour_time_matching(lhnetaddress_t *peeraddress, const char *pass
        return !memcmp(mdfourbuf, hash, 16);
 }
 
-qboolean hmac_mdfour_challenge_matching(lhnetaddress_t *peeraddress, const char *password, const char *hash, const char *s, int slen)
+static qboolean hmac_mdfour_challenge_matching(lhnetaddress_t *peeraddress, const char *password, const char *hash, const char *s, int slen)
 {
        char mdfourbuf[16];
        int i;
@@ -2567,19 +2593,20 @@ qboolean hmac_mdfour_challenge_matching(lhnetaddress_t *peeraddress, const char
        return true;
 }
 
-qboolean plaintext_matching(lhnetaddress_t *peeraddress, const char *password, const char *hash, const char *s, int slen)
+static qboolean plaintext_matching(lhnetaddress_t *peeraddress, const char *password, const char *hash, const char *s, int slen)
 {
        return !strcmp(password, hash);
 }
 
 /// returns a string describing the user level, or NULL for auth failure
-const char *RCon_Authenticate(lhnetaddress_t *peeraddress, const char *password, const char *s, const char *endpos, rcon_matchfunc_t comparator, const char *cs, int cslen)
+static const char *RCon_Authenticate(lhnetaddress_t *peeraddress, const char *password, const char *s, const char *endpos, rcon_matchfunc_t comparator, const char *cs, int cslen)
 {
        const char *text, *userpass_start, *userpass_end, *userpass_startpass;
        static char buf[MAX_INPUTLINE];
        qboolean hasquotes;
        qboolean restricted = false;
        qboolean have_usernames = false;
+       char vabuf[1024];
 
        userpass_start = rcon_password.string;
        while((userpass_end = strchr(userpass_start, ' ')))
@@ -2651,7 +2678,7 @@ check:
                                {
                                        if(!strcmp(com_token, s))
                                                goto match;
-                                       if(!memcmp(va("%s ", com_token), s, strlen(com_token) + 1))
+                                       if(!memcmp(va(vabuf, sizeof(vabuf), "%s ", com_token), s, strlen(com_token) + 1))
                                                goto match;
                                }
                        }
@@ -2665,12 +2692,12 @@ match:
 allow:
        userpass_startpass = strchr(userpass_start, ':');
        if(have_usernames && userpass_startpass && userpass_startpass < userpass_end)
-               return va("%srcon (username %.*s)", restricted ? "restricted " : "", (int)(userpass_startpass-userpass_start), userpass_start);
+               return va(vabuf, sizeof(vabuf), "%srcon (username %.*s)", restricted ? "restricted " : "", (int)(userpass_startpass-userpass_start), userpass_start);
 
-       return va("%srcon", restricted ? "restricted " : "");
+       return va(vabuf, sizeof(vabuf), "%srcon", restricted ? "restricted " : "");
 }
 
-void RCon_Execute(lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress, const char *addressstring2, const char *userlevel, const char *s, const char *endpos, qboolean proquakeprotocol)
+static void RCon_Execute(lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress, const char *addressstring2, const char *userlevel, const char *s, const char *endpos, qboolean proquakeprotocol)
 {
        if(userlevel)
        {
@@ -2708,17 +2735,18 @@ void RCon_Execute(lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress, const ch
        }
 }
 
-extern void SV_SendServerinfo (client_t *client);
 static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *data, int length, lhnetaddress_t *peeraddress)
 {
        int i, ret, clientnum, best;
        double besttime;
        client_t *client;
        char *s, *string, response[1400], addressstring2[128];
-       static char stringbuf[16384];
+       static char stringbuf[16384]; // server only
        qboolean islocal = (LHNETADDRESS_GetAddressType(peeraddress) == LHNETADDRESSTYPE_LOOP);
        char senddata[NET_HEADERSIZE+NET_MAXMESSAGE+CRYPTO_HEADERSIZE];
        size_t sendlength, response_len;
+       char infostringvalue[MAX_INPUTLINE];
+       char vabuf[1024];
 
        if (!sv.active)
                return false;
@@ -2828,7 +2856,7 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                        }
                        else
                        {
-                               if ((s = SearchInfostring(string, "challenge")))
+                               if ((s = InfoString_GetValue(string, "challenge", infostringvalue, sizeof(infostringvalue))))
                                {
                                        // validate the challenge
                                        for (i = 0;i < MAX_CHALLENGES;i++)
@@ -2841,19 +2869,19 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                                }
                        }
 
-                       if((s = SearchInfostring(string, "message")))
+                       if((s = InfoString_GetValue(string, "message", infostringvalue, sizeof(infostringvalue))))
                                Con_DPrintf("Connecting client %s sent us the message: %s\n", addressstring2, s);
 
                        if(!(islocal || sv_public.integer > -2))
                        {
                                if (developer_extra.integer)
                                        Con_Printf("Datagram_ParseConnectionless: sending \"reject %s\" to %s.\n", sv_public_rejectreason.string, addressstring2);
-                               NetConn_WriteString(mysocket, va("\377\377\377\377reject %s", sv_public_rejectreason.string), peeraddress);
+                               NetConn_WriteString(mysocket, va(vabuf, sizeof(vabuf), "\377\377\377\377reject %s", sv_public_rejectreason.string), peeraddress);
                                return true;
                        }
 
                        // check engine protocol
-                       if(!(s = SearchInfostring(string, "protocol")) || strcmp(s, "darkplaces 3"))
+                       if(!(s = InfoString_GetValue(string, "protocol", infostringvalue, sizeof(infostringvalue))) || strcmp(s, "darkplaces 3"))
                        {
                                if (developer_extra.integer)
                                        Con_Printf("Datagram_ParseConnectionless: sending \"reject Wrong game protocol.\" to %s.\n", addressstring2);
@@ -2910,9 +2938,7 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                                                NetConn_WriteString(mysocket, "\377\377\377\377accept", peeraddress);
                                                if(crypto && crypto->authenticated)
                                                        Crypto_ServerFinishInstance(&client->netconnection->crypto, crypto);
-                                               SV_VM_Begin();
                                                SV_SendServerinfo(client);
-                                               SV_VM_End();
                                        }
                                        else
                                        {
@@ -2944,9 +2970,7 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                                        // now set up the client
                                        if(crypto && crypto->authenticated)
                                                Crypto_ServerFinishInstance(&conn->crypto, crypto);
-                                       SV_VM_Begin();
                                        SV_ConnectClient(clientnum, conn);
-                                       SV_VM_End();
                                        NetConn_Heartbeat(1);
                                        return true;
                                }
@@ -3082,10 +3106,10 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                const char *protocolname;
                data += 4;
                length -= 4;
-               SZ_Clear(&net_message);
-               SZ_Write(&net_message, data, length);
-               MSG_BeginReading();
-               c = MSG_ReadByte();
+               SZ_Clear(&sv_message);
+               SZ_Write(&sv_message, data, length);
+               MSG_BeginReading(&sv_message);
+               c = MSG_ReadByte(&sv_message);
                switch (c)
                {
                case CCREQ_CONNECT:
@@ -3095,31 +3119,31 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                        {
                                if (developer_extra.integer)
                                        Con_DPrintf("Datagram_ParseConnectionless: sending CCREP_REJECT \"%s\" to %s.\n", sv_public_rejectreason.string, addressstring2);
-                               SZ_Clear(&net_message);
+                               SZ_Clear(&sv_message);
                                // save space for the header, filled in later
-                               MSG_WriteLong(&net_message, 0);
-                               MSG_WriteByte(&net_message, CCREP_REJECT);
-                               MSG_WriteString(&net_message, va("%s\n", sv_public_rejectreason.string));
-                               StoreBigLong(net_message.data, NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
-                               NetConn_Write(mysocket, net_message.data, net_message.cursize, peeraddress);
-                               SZ_Clear(&net_message);
+                               MSG_WriteLong(&sv_message, 0);
+                               MSG_WriteByte(&sv_message, CCREP_REJECT);
+                               MSG_WriteString(&sv_message, va(vabuf, sizeof(vabuf), "%s\n", sv_public_rejectreason.string));
+                               StoreBigLong(sv_message.data, NETFLAG_CTL | (sv_message.cursize & NETFLAG_LENGTH_MASK));
+                               NetConn_Write(mysocket, sv_message.data, sv_message.cursize, peeraddress);
+                               SZ_Clear(&sv_message);
                                break;
                        }
 
-                       protocolname = MSG_ReadString();
-                       protocolnumber = MSG_ReadByte();
+                       protocolname = MSG_ReadString(&sv_message, sv_readstring, sizeof(sv_readstring));
+                       protocolnumber = MSG_ReadByte(&sv_message);
                        if (strcmp(protocolname, "QUAKE") || protocolnumber != NET_PROTOCOL_VERSION)
                        {
                                if (developer_extra.integer)
                                        Con_DPrintf("Datagram_ParseConnectionless: sending CCREP_REJECT \"Incompatible version.\" to %s.\n", addressstring2);
-                               SZ_Clear(&net_message);
+                               SZ_Clear(&sv_message);
                                // save space for the header, filled in later
-                               MSG_WriteLong(&net_message, 0);
-                               MSG_WriteByte(&net_message, CCREP_REJECT);
-                               MSG_WriteString(&net_message, "Incompatible version.\n");
-                               StoreBigLong(net_message.data, NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
-                               NetConn_Write(mysocket, net_message.data, net_message.cursize, peeraddress);
-                               SZ_Clear(&net_message);
+                               MSG_WriteLong(&sv_message, 0);
+                               MSG_WriteByte(&sv_message, CCREP_REJECT);
+                               MSG_WriteString(&sv_message, "Incompatible version.\n");
+                               StoreBigLong(sv_message.data, NETFLAG_CTL | (sv_message.cursize & NETFLAG_LENGTH_MASK));
+                               NetConn_Write(mysocket, sv_message.data, sv_message.cursize, peeraddress);
+                               SZ_Clear(&sv_message);
                                break;
                        }
 
@@ -3135,23 +3159,19 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                                        // send a reply
                                        if (developer_extra.integer)
                                                Con_DPrintf("Datagram_ParseConnectionless: sending duplicate CCREP_ACCEPT to %s.\n", addressstring2);
-                                       SZ_Clear(&net_message);
+                                       SZ_Clear(&sv_message);
                                        // save space for the header, filled in later
-                                       MSG_WriteLong(&net_message, 0);
-                                       MSG_WriteByte(&net_message, CCREP_ACCEPT);
-                                       MSG_WriteLong(&net_message, LHNETADDRESS_GetPort(LHNET_AddressFromSocket(client->netconnection->mysocket)));
-                                       StoreBigLong(net_message.data, NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
-                                       NetConn_Write(mysocket, net_message.data, net_message.cursize, peeraddress);
-                                       SZ_Clear(&net_message);
+                                       MSG_WriteLong(&sv_message, 0);
+                                       MSG_WriteByte(&sv_message, CCREP_ACCEPT);
+                                       MSG_WriteLong(&sv_message, LHNETADDRESS_GetPort(LHNET_AddressFromSocket(client->netconnection->mysocket)));
+                                       StoreBigLong(sv_message.data, NETFLAG_CTL | (sv_message.cursize & NETFLAG_LENGTH_MASK));
+                                       NetConn_Write(mysocket, sv_message.data, sv_message.cursize, peeraddress);
+                                       SZ_Clear(&sv_message);
 
                                        // if client is already spawned, re-send the
                                        // serverinfo message as they'll need it to play
                                        if (client->spawned)
-                                       {
-                                               SV_VM_Begin();
                                                SV_SendServerinfo(client);
-                                               SV_VM_End();
-                                       }
                                        return true;
                                }
                        }
@@ -3172,18 +3192,16 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                                        if (developer_extra.integer)
                                                Con_DPrintf("Datagram_ParseConnectionless: sending CCREP_ACCEPT to %s.\n", addressstring2);
                                        // send back the info about the server connection
-                                       SZ_Clear(&net_message);
+                                       SZ_Clear(&sv_message);
                                        // save space for the header, filled in later
-                                       MSG_WriteLong(&net_message, 0);
-                                       MSG_WriteByte(&net_message, CCREP_ACCEPT);
-                                       MSG_WriteLong(&net_message, LHNETADDRESS_GetPort(LHNET_AddressFromSocket(conn->mysocket)));
-                                       StoreBigLong(net_message.data, NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
-                                       NetConn_Write(mysocket, net_message.data, net_message.cursize, peeraddress);
-                                       SZ_Clear(&net_message);
+                                       MSG_WriteLong(&sv_message, 0);
+                                       MSG_WriteByte(&sv_message, CCREP_ACCEPT);
+                                       MSG_WriteLong(&sv_message, LHNETADDRESS_GetPort(LHNET_AddressFromSocket(conn->mysocket)));
+                                       StoreBigLong(sv_message.data, NETFLAG_CTL | (sv_message.cursize & NETFLAG_LENGTH_MASK));
+                                       NetConn_Write(mysocket, sv_message.data, sv_message.cursize, peeraddress);
+                                       SZ_Clear(&sv_message);
                                        // now set up the client struct
-                                       SV_VM_Begin();
                                        SV_ConnectClient(clientnum, conn);
-                                       SV_VM_End();
                                        NetConn_Heartbeat(1);
                                        return true;
                                }
@@ -3192,44 +3210,44 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                        if (developer_extra.integer)
                                Con_DPrintf("Datagram_ParseConnectionless: sending CCREP_REJECT \"Server is full.\" to %s.\n", addressstring2);
                        // no room; try to let player know
-                       SZ_Clear(&net_message);
+                       SZ_Clear(&sv_message);
                        // save space for the header, filled in later
-                       MSG_WriteLong(&net_message, 0);
-                       MSG_WriteByte(&net_message, CCREP_REJECT);
-                       MSG_WriteString(&net_message, "Server is full.\n");
-                       StoreBigLong(net_message.data, NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
-                       NetConn_Write(mysocket, net_message.data, net_message.cursize, peeraddress);
-                       SZ_Clear(&net_message);
+                       MSG_WriteLong(&sv_message, 0);
+                       MSG_WriteByte(&sv_message, CCREP_REJECT);
+                       MSG_WriteString(&sv_message, "Server is full.\n");
+                       StoreBigLong(sv_message.data, NETFLAG_CTL | (sv_message.cursize & NETFLAG_LENGTH_MASK));
+                       NetConn_Write(mysocket, sv_message.data, sv_message.cursize, peeraddress);
+                       SZ_Clear(&sv_message);
                        break;
                case CCREQ_SERVER_INFO:
                        if (developer_extra.integer)
                                Con_DPrintf("Datagram_ParseConnectionless: received CCREQ_SERVER_INFO from %s.\n", addressstring2);
                        if(!(islocal || sv_public.integer > -1))
                                break;
-                       if (sv.active && !strcmp(MSG_ReadString(), "QUAKE"))
+                       if (sv.active && !strcmp(MSG_ReadString(&sv_message, sv_readstring, sizeof(sv_readstring)), "QUAKE"))
                        {
                                int numclients;
                                char myaddressstring[128];
                                if (developer_extra.integer)
                                        Con_DPrintf("Datagram_ParseConnectionless: sending CCREP_SERVER_INFO to %s.\n", addressstring2);
-                               SZ_Clear(&net_message);
+                               SZ_Clear(&sv_message);
                                // save space for the header, filled in later
-                               MSG_WriteLong(&net_message, 0);
-                               MSG_WriteByte(&net_message, CCREP_SERVER_INFO);
+                               MSG_WriteLong(&sv_message, 0);
+                               MSG_WriteByte(&sv_message, CCREP_SERVER_INFO);
                                LHNETADDRESS_ToString(LHNET_AddressFromSocket(mysocket), myaddressstring, sizeof(myaddressstring), true);
-                               MSG_WriteString(&net_message, myaddressstring);
-                               MSG_WriteString(&net_message, hostname.string);
-                               MSG_WriteString(&net_message, sv.name);
+                               MSG_WriteString(&sv_message, myaddressstring);
+                               MSG_WriteString(&sv_message, hostname.string);
+                               MSG_WriteString(&sv_message, sv.name);
                                // How many clients are there?
                                for (i = 0, numclients = 0;i < svs.maxclients;i++)
                                        if (svs.clients[i].active)
                                                numclients++;
-                               MSG_WriteByte(&net_message, numclients);
-                               MSG_WriteByte(&net_message, svs.maxclients);
-                               MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
-                               StoreBigLong(net_message.data, NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
-                               NetConn_Write(mysocket, net_message.data, net_message.cursize, peeraddress);
-                               SZ_Clear(&net_message);
+                               MSG_WriteByte(&sv_message, numclients);
+                               MSG_WriteByte(&sv_message, svs.maxclients);
+                               MSG_WriteByte(&sv_message, NET_PROTOCOL_VERSION);
+                               StoreBigLong(sv_message.data, NETFLAG_CTL | (sv_message.cursize & NETFLAG_LENGTH_MASK));
+                               NetConn_Write(mysocket, sv_message.data, sv_message.cursize, peeraddress);
+                               SZ_Clear(&sv_message);
                        }
                        break;
                case CCREQ_PLAYER_INFO:
@@ -3242,29 +3260,29 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                                int playerNumber, activeNumber, clientNumber;
                                client_t *client;
 
-                               playerNumber = MSG_ReadByte();
+                               playerNumber = MSG_ReadByte(&sv_message);
                                activeNumber = -1;
                                for (clientNumber = 0, client = svs.clients; clientNumber < svs.maxclients; clientNumber++, client++)
                                        if (client->active && ++activeNumber == playerNumber)
                                                break;
                                if (clientNumber != svs.maxclients)
                                {
-                                       SZ_Clear(&net_message);
+                                       SZ_Clear(&sv_message);
                                        // save space for the header, filled in later
-                                       MSG_WriteLong(&net_message, 0);
-                                       MSG_WriteByte(&net_message, CCREP_PLAYER_INFO);
-                                       MSG_WriteByte(&net_message, playerNumber);
-                                       MSG_WriteString(&net_message, client->name);
-                                       MSG_WriteLong(&net_message, client->colors);
-                                       MSG_WriteLong(&net_message, client->frags);
-                                       MSG_WriteLong(&net_message, (int)(realtime - client->connecttime));
+                                       MSG_WriteLong(&sv_message, 0);
+                                       MSG_WriteByte(&sv_message, CCREP_PLAYER_INFO);
+                                       MSG_WriteByte(&sv_message, playerNumber);
+                                       MSG_WriteString(&sv_message, client->name);
+                                       MSG_WriteLong(&sv_message, client->colors);
+                                       MSG_WriteLong(&sv_message, client->frags);
+                                       MSG_WriteLong(&sv_message, (int)(realtime - client->connecttime));
                                        if(sv_status_privacy.integer)
-                                               MSG_WriteString(&net_message, client->netconnection ? "hidden" : "botclient");
+                                               MSG_WriteString(&sv_message, client->netconnection ? "hidden" : "botclient");
                                        else
-                                               MSG_WriteString(&net_message, client->netconnection ? client->netconnection->address : "botclient");
-                                       StoreBigLong(net_message.data, NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
-                                       NetConn_Write(mysocket, net_message.data, net_message.cursize, peeraddress);
-                                       SZ_Clear(&net_message);
+                                               MSG_WriteString(&sv_message, client->netconnection ? client->netconnection->address : "botclient");
+                                       StoreBigLong(sv_message.data, NETFLAG_CTL | (sv_message.cursize & NETFLAG_LENGTH_MASK));
+                                       NetConn_Write(mysocket, sv_message.data, sv_message.cursize, peeraddress);
+                                       SZ_Clear(&sv_message);
                                }
                        }
                        break;
@@ -3279,22 +3297,22 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                                cvar_t *var;
 
                                // find the search start location
-                               prevCvarName = MSG_ReadString();
+                               prevCvarName = MSG_ReadString(&sv_message, sv_readstring, sizeof(sv_readstring));
                                var = Cvar_FindVarAfter(prevCvarName, CVAR_NOTIFY);
 
                                // send the response
-                               SZ_Clear(&net_message);
+                               SZ_Clear(&sv_message);
                                // save space for the header, filled in later
-                               MSG_WriteLong(&net_message, 0);
-                               MSG_WriteByte(&net_message, CCREP_RULE_INFO);
+                               MSG_WriteLong(&sv_message, 0);
+                               MSG_WriteByte(&sv_message, CCREP_RULE_INFO);
                                if (var)
                                {
-                                       MSG_WriteString(&net_message, var->name);
-                                       MSG_WriteString(&net_message, var->string);
+                                       MSG_WriteString(&sv_message, var->name);
+                                       MSG_WriteString(&sv_message, var->string);
                                }
-                               StoreBigLong(net_message.data, NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
-                               NetConn_Write(mysocket, net_message.data, net_message.cursize, peeraddress);
-                               SZ_Clear(&net_message);
+                               StoreBigLong(sv_message.data, NETFLAG_CTL | (sv_message.cursize & NETFLAG_LENGTH_MASK));
+                               NetConn_Write(mysocket, sv_message.data, sv_message.cursize, peeraddress);
+                               SZ_Clear(&sv_message);
                        }
                        break;
                case CCREQ_RCON:
@@ -3307,8 +3325,8 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                                char *s;
                                char *endpos;
                                const char *userlevel;
-                               strlcpy(password, MSG_ReadString(), sizeof(password));
-                               strlcpy(cmd, MSG_ReadString(), sizeof(cmd));
+                               strlcpy(password, MSG_ReadString(&sv_message, sv_readstring, sizeof(sv_readstring)), sizeof(password));
+                               strlcpy(cmd, MSG_ReadString(&sv_message, sv_readstring, sizeof(sv_readstring)), sizeof(cmd));
                                s = cmd;
                                endpos = cmd + strlen(cmd) + 1; // one behind the NUL, so adding strlen+1 will eventually reach it
                                userlevel = RCon_Authenticate(peeraddress, password, s, endpos, plaintext_matching, NULL, 0);
@@ -3319,7 +3337,7 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                default:
                        break;
                }
-               SZ_Clear(&net_message);
+               SZ_Clear(&sv_message);
                // we may not have liked the packet, but it was a valid control
                // packet, so we're done processing this packet now
                return true;
@@ -3328,9 +3346,7 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
        {
                if ((ret = NetConn_ReceivedMessage(host_client->netconnection, data, length, sv.protocol, host_client->spawned ? net_messagetimeout.value : net_connecttimeout.value)) == 2)
                {
-                       SV_VM_Begin();
                        SV_ReadClientMessage();
-                       SV_VM_End();
                        return ret;
                }
        }
@@ -3341,6 +3357,7 @@ void NetConn_ServerFrame(void)
 {
        int i, length;
        lhnetaddress_t peeraddress;
+       unsigned char readbuffer[NET_HEADERSIZE+NET_MAXMESSAGE];
        for (i = 0;i < sv_numsockets;i++)
                while (sv_sockets[i] && (length = NetConn_Read(sv_sockets[i], readbuffer, sizeof(readbuffer), &peeraddress)) > 0)
                        NetConn_ServerParsePacket(sv_sockets[i], readbuffer, length, &peeraddress);
@@ -3350,9 +3367,7 @@ void NetConn_ServerFrame(void)
                if (host_client->netconnection && realtime > host_client->netconnection->timeout && LHNETADDRESS_GetAddressType(&host_client->netconnection->peeraddress) != LHNETADDRESSTYPE_LOOP)
                {
                        Con_Printf("Client \"%s\" connection timed out\n", host_client->name);
-                       SV_VM_Begin();
                        SV_DropClient(false);
-                       SV_VM_End();
                }
        }
 }
@@ -3390,15 +3405,15 @@ void NetConn_QueryMasters(qboolean querydp, qboolean queryqw)
                                if(LHNETADDRESS_GetAddressType(&broadcastaddress) == af)
                                {
                                        // search LAN for Quake servers
-                                       SZ_Clear(&net_message);
+                                       SZ_Clear(&cl_message);
                                        // save space for the header, filled in later
-                                       MSG_WriteLong(&net_message, 0);
-                                       MSG_WriteByte(&net_message, CCREQ_SERVER_INFO);
-                                       MSG_WriteString(&net_message, "QUAKE");
-                                       MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
-                                       StoreBigLong(net_message.data, NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
-                                       NetConn_Write(cl_sockets[i], net_message.data, net_message.cursize, &broadcastaddress);
-                                       SZ_Clear(&net_message);
+                                       MSG_WriteLong(&cl_message, 0);
+                                       MSG_WriteByte(&cl_message, CCREQ_SERVER_INFO);
+                                       MSG_WriteString(&cl_message, "QUAKE");
+                                       MSG_WriteByte(&cl_message, NET_PROTOCOL_VERSION);
+                                       StoreBigLong(cl_message.data, NETFLAG_CTL | (cl_message.cursize & NETFLAG_LENGTH_MASK));
+                                       NetConn_Write(cl_sockets[i], cl_message.data, cl_message.cursize, &broadcastaddress);
+                                       SZ_Clear(&cl_message);
 
                                        // search LAN for DarkPlaces servers
                                        NetConn_WriteString(cl_sockets[i], "\377\377\377\377getstatus", &broadcastaddress);
@@ -3536,26 +3551,26 @@ static void Net_Heartbeat_f(void)
                Con_Print("No server running, can not heartbeat to master server.\n");
 }
 
-void PrintStats(netconn_t *conn)
+static void PrintStats(netconn_t *conn)
 {
        if ((cls.state == ca_connected && cls.protocol == PROTOCOL_QUAKEWORLD) || (sv.active && sv.protocol == PROTOCOL_QUAKEWORLD))
                Con_Printf("address=%21s canSend=%u sendSeq=%6u recvSeq=%6u\n", conn->address, !conn->sendMessageLength, conn->outgoing_unreliable_sequence, conn->qw.incoming_sequence);
        else
                Con_Printf("address=%21s canSend=%u sendSeq=%6u recvSeq=%6u\n", conn->address, !conn->sendMessageLength, conn->nq.sendSequence, conn->nq.receiveSequence);
+       Con_Printf("unreliable messages sent   = %i\n", conn->unreliableMessagesSent);
+       Con_Printf("unreliable messages recv   = %i\n", conn->unreliableMessagesReceived);
+       Con_Printf("reliable messages sent     = %i\n", conn->reliableMessagesSent);
+       Con_Printf("reliable messages received = %i\n", conn->reliableMessagesReceived);
+       Con_Printf("packetsSent                = %i\n", conn->packetsSent);
+       Con_Printf("packetsReSent              = %i\n", conn->packetsReSent);
+       Con_Printf("packetsReceived            = %i\n", conn->packetsReceived);
+       Con_Printf("receivedDuplicateCount     = %i\n", conn->receivedDuplicateCount);
+       Con_Printf("droppedDatagrams           = %i\n", conn->droppedDatagrams);
 }
 
 void Net_Stats_f(void)
 {
        netconn_t *conn;
-       Con_Printf("unreliable messages sent   = %i\n", unreliableMessagesSent);
-       Con_Printf("unreliable messages recv   = %i\n", unreliableMessagesReceived);
-       Con_Printf("reliable messages sent     = %i\n", reliableMessagesSent);
-       Con_Printf("reliable messages received = %i\n", reliableMessagesReceived);
-       Con_Printf("packetsSent                = %i\n", packetsSent);
-       Con_Printf("packetsReSent              = %i\n", packetsReSent);
-       Con_Printf("packetsReceived            = %i\n", packetsReceived);
-       Con_Printf("receivedDuplicateCount     = %i\n", receivedDuplicateCount);
-       Con_Printf("droppedDatagrams           = %i\n", droppedDatagrams);
        Con_Print("connections                =\n");
        for (conn = netconn_list;conn;conn = conn->next)
                PrintStats(conn);
@@ -3662,9 +3677,12 @@ void NetConn_Init(void)
        }
        cl_numsockets = 0;
        sv_numsockets = 0;
-       net_message.data = net_message_buf;
-       net_message.maxsize = sizeof(net_message_buf);
-       net_message.cursize = 0;
+       cl_message.data = cl_message_buf;
+       cl_message.maxsize = sizeof(cl_message_buf);
+       cl_message.cursize = 0;
+       sv_message.data = sv_message_buf;
+       sv_message.maxsize = sizeof(sv_message_buf);
+       sv_message.cursize = 0;
        LHNET_Init();
        if (Thread_HasThreads())
                netconn_mutex = Thread_CreateMutex();
index ed2fc08dd2c7ec51d1b9f497d6629f4665d22a5a..69b0de518946ea361668d41b48234a536ff8e726 100755 (executable)
--- a/netconn.h
+++ b/netconn.h
@@ -221,6 +221,17 @@ typedef struct netconn_s
 
        char address[128];
        crypto_t crypto;
+
+       // statistic counters
+       int packetsSent;
+       int packetsReSent;
+       int packetsReceived;
+       int receivedDuplicateCount;
+       int droppedDatagrams;
+       int unreliableMessagesSent;
+       int unreliableMessagesReceived;
+       int reliableMessagesSent;
+       int reliableMessagesReceived;
 } netconn_t;
 
 extern netconn_t *netconn_list;
@@ -389,7 +400,10 @@ extern int masterreplycount;
 extern int serverquerycount;
 extern int serverreplycount;
 
-extern sizebuf_t net_message;
+extern sizebuf_t cl_message;
+extern sizebuf_t sv_message;
+extern char cl_readstring[MAX_INPUTLINE];
+extern char sv_readstring[MAX_INPUTLINE];
 
 extern cvar_t sv_public;
 
index af4131469d45cacdfb616ca9c5849e06db1f085f..9fb36de352170e0f6d18481baea4dd000aa5e840 100644 (file)
--- a/palette.c
+++ b/palette.c
@@ -76,7 +76,7 @@ unsigned char host_quakepal[768] =
        139,0,0,      179,0,0,      215,0,0,      255,0,0,      255,243,147,  255,247,199,  255,255,255,  159,91,83
 }; //                                                    15 ^
 
-void Palette_SetupSpecialPalettes(void)
+static void Palette_SetupSpecialPalettes(void)
 {
        int i;
        int fullbright_start, fullbright_end;
@@ -221,15 +221,15 @@ void BuildGammaTable16(float prescale, float gamma, float scale, float base, flo
        }
 }
 
-void Palette_Shutdown(void)
+static void Palette_Shutdown(void)
 {
 }
 
-void Palette_NewMap(void)
+static void Palette_NewMap(void)
 {
 }
 
-void Palette_Load(void)
+static void Palette_Load(void)
 {
        int i;
        unsigned char *out;
index 3b770f9ea40c79cbf4b55bf8d77bcee9e16e0d5e..0900a34f8f6c9c6fb41dc12b53c77baaa03a8398 100644 (file)
--- a/portals.c
+++ b/portals.c
@@ -1,6 +1,7 @@
 
 #include "quakedef.h"
 #include "polygon.h"
+#include "portals.h"
 
 #define MAXRECURSIVEPORTALPLANES 1024
 #define MAXRECURSIVEPORTALS 256
index ffcf3a16bf6c03f9ebdbcd196c1074a7972ecade..02f7228741a583b9a7987462230a80d613b5c83f 100644 (file)
--- a/progsvm.h
+++ b/progsvm.h
@@ -112,6 +112,43 @@ typedef struct prvm_edict_s
        } fields;
 } prvm_edict_t;
 
+#define VMPOLYGONS_MAXPOINTS 64
+
+typedef struct vmpolygons_triangle_s
+{
+       rtexture_t              *texture;
+       int                             drawflag;
+       qboolean hasalpha;
+       unsigned short  elements[3];
+} vmpolygons_triangle_t;
+
+typedef struct vmpolygons_s
+{
+       mempool_t               *pool;
+       qboolean                initialized;
+
+       int                             max_vertices;
+       int                             num_vertices;
+       float                   *data_vertex3f;
+       float                   *data_color4f;
+       float                   *data_texcoord2f;
+
+       int                             max_triangles;
+       int                             num_triangles;
+       vmpolygons_triangle_t *data_triangles;
+       unsigned short  *data_sortedelement3s;
+
+       qboolean                begin_active;
+       int     begin_draw2d;
+       rtexture_t              *begin_texture;
+       int                             begin_drawflag;
+       int                             begin_vertices;
+       float                   begin_vertex[VMPOLYGONS_MAXPOINTS][3];
+       float                   begin_color[VMPOLYGONS_MAXPOINTS][4];
+       float                   begin_texcoord[VMPOLYGONS_MAXPOINTS][2];
+       qboolean                begin_texture_hasalpha;
+} vmpolygons_t;
+
 extern prvm_eval_t prvm_badvalue;
 
 #define PRVM_alledictfloat(ed, fieldname)    (PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.fieldname))
@@ -231,7 +268,8 @@ extern prvm_eval_t prvm_badvalue;
 #define PRVM_MAX_OPENSEARCHES 128
 #endif
 
-typedef void (*prvm_builtin_t) (void);
+struct prvm_prog_s;
+typedef void (*prvm_builtin_t) (struct prvm_prog_s *prog);
 
 // NOTE: field offsets use -1 for NULL
 typedef struct prvm_prog_fieldoffsets_s
@@ -487,7 +525,8 @@ prvm_stringbuffer_t;
 // NOTE: external code has to create and free the mempools but everything else is done by prvm !
 typedef struct prvm_prog_s
 {
-       double              starttime;
+       double                          starttime; // system time when PRVM_Prog_Load was called
+       double                          profiletime; // system time when last PRVM_CallProfile was called (or PRVM_Prog_Load initially)
        unsigned int            id; // increasing unique id of progs instance
        mfunction_t                     *functions;
        char                            *strings;
@@ -570,6 +609,13 @@ typedef struct prvm_prog_s
        const char *         opensearches_origin[PRVM_MAX_OPENSEARCHES];
        skeleton_t                      *skeletons[MAX_EDICTS];
 
+       // buffer for storing all tempstrings created during one invocation of ExecuteProgram
+       sizebuf_t                       tempstringsbuf;
+
+       // LordHavoc: moved this here to clean up things that relied on prvm_prog_list too much
+       // FIXME: make VM_CL_R_Polygon functions use Debug_Polygon functions?
+       vmpolygons_t            vmpolygons;
+
        // copies of some vars that were former read from sv
        int                                     num_edicts;
        // number of edicts for which space has been (should be) allocated
@@ -628,32 +674,41 @@ typedef struct prvm_prog_s
        //============================================================================
        // function pointers
 
-       void                            (*begin_increase_edicts)(void); // [INIT] used by PRVM_MEM_Increase_Edicts
-       void                            (*end_increase_edicts)(void); // [INIT]
+       void                            (*begin_increase_edicts)(struct prvm_prog_s *prog); // [INIT] used by PRVM_MEM_Increase_Edicts
+       void                            (*end_increase_edicts)(struct prvm_prog_s *prog); // [INIT]
 
-       void                            (*init_edict)(prvm_edict_t *edict); // [INIT] used by PRVM_ED_ClearEdict
-       void                            (*free_edict)(prvm_edict_t *ed); // [INIT] used by PRVM_ED_Free
+       void                            (*init_edict)(struct prvm_prog_s *prog, prvm_edict_t *edict); // [INIT] used by PRVM_ED_ClearEdict
+       void                            (*free_edict)(struct prvm_prog_s *prog, prvm_edict_t *ed); // [INIT] used by PRVM_ED_Free
 
-       void                            (*count_edicts)(void); // [INIT] used by PRVM_ED_Count_f
+       void                            (*count_edicts)(struct prvm_prog_s *prog); // [INIT] used by PRVM_ED_Count_f
 
-       qboolean                        (*load_edict)(prvm_edict_t *ent); // [INIT] used by PRVM_ED_LoadFromFile
+       qboolean                        (*load_edict)(struct prvm_prog_s *prog, prvm_edict_t *ent); // [INIT] used by PRVM_ED_LoadFromFile
 
-       void                            (*init_cmd)(void); // [INIT] used by PRVM_InitProg
-       void                            (*reset_cmd)(void); // [INIT] used by PRVM_ResetProg
+       void                            (*init_cmd)(struct prvm_prog_s *prog); // [INIT] used by PRVM_InitProg
+       void                            (*reset_cmd)(struct prvm_prog_s *prog); // [INIT] used by PRVM_ResetProg
 
        void                            (*error_cmd)(const char *format, ...) DP_FUNC_PRINTF(1); // [INIT]
 
-       void                            (*ExecuteProgram)(func_t fnum, const char *errormessage); // pointer to one of the *VM_ExecuteProgram functions
+       void                            (*ExecuteProgram)(struct prvm_prog_s *prog, func_t fnum, const char *errormessage); // pointer to one of the *VM_ExecuteProgram functions
 } prvm_prog_t;
 
-extern prvm_prog_t * prog;
-
-#define PRVM_MAXPROGS 3
-#define PRVM_SERVERPROG 0 // actually not used at the moment
-#define PRVM_CLIENTPROG 1
-#define PRVM_MENUPROG  2
+typedef enum prvm_progindex_e
+{
+       PRVM_PROG_SERVER,
+       PRVM_PROG_CLIENT,
+       PRVM_PROG_MENU,
+       PRVM_PROG_MAX
+}
+prvm_progindex_t;
 
-extern prvm_prog_t prvm_prog_list[PRVM_MAXPROGS];
+extern prvm_prog_t prvm_prog_list[PRVM_PROG_MAX];
+prvm_prog_t *PRVM_ProgFromString(const char *str);
+prvm_prog_t *PRVM_FriendlyProgFromString(const char *str); // for console commands (prints error if name unknown and returns NULL, prints error if prog not loaded and returns NULL)
+#define PRVM_GetProg(n) (&prvm_prog_list[(n)])
+#define PRVM_ProgLoaded(n) (PRVM_GetProg(n)->loaded)
+#define SVVM_prog (&prvm_prog_list[PRVM_PROG_SERVER])
+#define CLVM_prog (&prvm_prog_list[PRVM_PROG_CLIENT])
+#define MVM_prog (&prvm_prog_list[PRVM_PROG_MENU])
 
 //============================================================================
 // prvm_cmds part
@@ -669,80 +724,75 @@ extern const int vm_m_numbuiltins;
 extern const char * vm_sv_extensions; // client also uses this
 extern const char * vm_m_extensions;
 
-void VM_SV_Cmd_Init(void);
-void VM_SV_Cmd_Reset(void);
+void SVVM_init_cmd(prvm_prog_t *prog);
+void SVVM_reset_cmd(prvm_prog_t *prog);
 
-void VM_CL_Cmd_Init(void);
-void VM_CL_Cmd_Reset(void);
+void CLVM_init_cmd(prvm_prog_t *prog);
+void CLVM_reset_cmd(prvm_prog_t *prog);
 
-void VM_M_Cmd_Init(void);
-void VM_M_Cmd_Reset(void);
+void MVM_init_cmd(prvm_prog_t *prog);
+void MVM_reset_cmd(prvm_prog_t *prog);
 
-void VM_Cmd_Init(void);
-void VM_Cmd_Reset(void);
+void VM_Cmd_Init(prvm_prog_t *prog);
+void VM_Cmd_Reset(prvm_prog_t *prog);
 //============================================================================
 
 void PRVM_Init (void);
 
 #ifdef PROFILING
-void MVM_ExecuteProgram (func_t fnum, const char *errormessage);
-void CLVM_ExecuteProgram (func_t fnum, const char *errormessage);
-void SVVM_ExecuteProgram (func_t fnum, const char *errormessage);
+void SVVM_ExecuteProgram (prvm_prog_t *prog, func_t fnum, const char *errormessage);
+void CLVM_ExecuteProgram (prvm_prog_t *prog, func_t fnum, const char *errormessage);
+void MVM_ExecuteProgram (prvm_prog_t *prog, func_t fnum, const char *errormessage);
 #else
-#define MVM_ExecuteProgram SVVM_ExecuteProgram
-#define CLVM_ExecuteProgram SVVM_ExecuteProgram
-void SVVM_ExecuteProgram (func_t fnum, const char *errormessage);
+#define SVVM_ExecuteProgram PRVM_ExecuteProgram
+#define CLVM_ExecuteProgram PRVM_ExecuteProgram
+#define MVM_ExecuteProgram PRVM_ExecuteProgram
+void PRVM_ExecuteProgram (prvm_prog_t *prog, func_t fnum, const char *errormessage);
 #endif
-#define PRVM_ExecuteProgram prog->ExecuteProgram
 
-#define PRVM_Alloc(buffersize) _PRVM_Alloc(buffersize, __FILE__, __LINE__)
-#define PRVM_Free(buffer) _PRVM_Free(buffer, __FILE__, __LINE__)
-#define PRVM_FreeAll() _PRVM_FreeAll(__FILE__, __LINE__)
-void *_PRVM_Alloc (size_t buffersize, const char *filename, int fileline);
-void _PRVM_Free (void *buffer, const char *filename, int fileline);
-void _PRVM_FreeAll (const char *filename, int fileline);
+#define PRVM_Alloc(buffersize) Mem_Alloc(prog->progs_mempool, buffersize)
+#define PRVM_Free(buffer) Mem_Free(buffer)
 
-void PRVM_Profile (int maxfunctions, double mintime, int sortby);
+void PRVM_Profile (prvm_prog_t *prog, int maxfunctions, double mintime, int sortby);
 void PRVM_Profile_f (void);
 void PRVM_ChildProfile_f (void);
 void PRVM_CallProfile_f (void);
 void PRVM_PrintFunction_f (void);
 
-void PRVM_PrintState(void);
-void PRVM_CrashAll (void);
-void PRVM_Crash (void);
-void PRVM_ShortStackTrace(char *buf, size_t bufsize);
-const char *PRVM_AllocationOrigin(void);
+void PRVM_PrintState(prvm_prog_t *prog);
+void PRVM_Crash(prvm_prog_t *prog);
+void PRVM_ShortStackTrace(prvm_prog_t *prog, char *buf, size_t bufsize);
+const char *PRVM_AllocationOrigin(prvm_prog_t *prog);
 
-ddef_t *PRVM_ED_FindField(const char *name);
-ddef_t *PRVM_ED_FindGlobal(const char *name);
-mfunction_t *PRVM_ED_FindFunction(const char *name);
+ddef_t *PRVM_ED_FindField(prvm_prog_t *prog, const char *name);
+ddef_t *PRVM_ED_FindGlobal(prvm_prog_t *prog, const char *name);
+mfunction_t *PRVM_ED_FindFunction(prvm_prog_t *prog, const char *name);
 
-int PRVM_ED_FindFieldOffset(const char *name);
-int PRVM_ED_FindGlobalOffset(const char *name);
-func_t PRVM_ED_FindFunctionOffset(const char *name);
+int PRVM_ED_FindFieldOffset(prvm_prog_t *prog, const char *name);
+int PRVM_ED_FindGlobalOffset(prvm_prog_t *prog, const char *name);
+func_t PRVM_ED_FindFunctionOffset(prvm_prog_t *prog, const char *name);
 #define PRVM_ED_FindFieldOffset_FromStruct(st, field) prog->fieldoffsets . field = ((int *)(&((st *)NULL)-> field ) - ((int *)NULL))
 #define PRVM_ED_FindGlobalOffset_FromStruct(st, field) prog->globaloffsets . field = ((int *)(&((st *)NULL)-> field ) - ((int *)NULL))
 
-void PRVM_MEM_IncreaseEdicts(void);
+void PRVM_MEM_IncreaseEdicts(prvm_prog_t *prog);
 
-qboolean PRVM_ED_CanAlloc(prvm_edict_t *e);
-prvm_edict_t *PRVM_ED_Alloc (void);
-void PRVM_ED_Free (prvm_edict_t *ed);
-void PRVM_ED_ClearEdict (prvm_edict_t *e);
+qboolean PRVM_ED_CanAlloc(prvm_prog_t *prog, prvm_edict_t *e);
+prvm_edict_t *PRVM_ED_Alloc(prvm_prog_t *prog);
+void PRVM_ED_Free(prvm_prog_t *prog, prvm_edict_t *ed);
+void PRVM_ED_ClearEdict(prvm_prog_t *prog, prvm_edict_t *e);
 
-void PRVM_PrintFunctionStatements (const char *name);
-void PRVM_ED_Print(prvm_edict_t *ed, const char *wildcard_fieldname);
-void PRVM_ED_Write (qfile_t *f, prvm_edict_t *ed);
-const char *PRVM_ED_ParseEdict (const char *data, prvm_edict_t *ent);
+void PRVM_PrintFunctionStatements(prvm_prog_t *prog, const char *name);
+void PRVM_ED_Print(prvm_prog_t *prog, prvm_edict_t *ed, const char *wildcard_fieldname);
+void PRVM_ED_Write(prvm_prog_t *prog, qfile_t *f, prvm_edict_t *ed);
+const char *PRVM_ED_ParseEdict(prvm_prog_t *prog, const char *data, prvm_edict_t *ent);
 
-void PRVM_ED_WriteGlobals (qfile_t *f);
-void PRVM_ED_ParseGlobals (const char *data);
+void PRVM_ED_WriteGlobals(prvm_prog_t *prog, qfile_t *f);
+void PRVM_ED_ParseGlobals(prvm_prog_t *prog, const char *data);
 
-void PRVM_ED_LoadFromFile (const char *data);
+void PRVM_ED_LoadFromFile(prvm_prog_t *prog, const char *data);
 
-unsigned int PRVM_EDICT_NUM_ERROR(unsigned int n, const char *filename, int fileline);
-#define        PRVM_EDICT(n) (((unsigned)(n) < (unsigned int)prog->max_edicts) ? (unsigned int)(n) : PRVM_EDICT_NUM_ERROR((unsigned int)(n), __FILE__, __LINE__))
+unsigned int PRVM_EDICT_NUM_ERROR(prvm_prog_t *prog, unsigned int n, const char *filename, int fileline);
+#define        PRVM_EDICT(n) (((unsigned)(n) < (unsigned int)prog->max_edicts) ? (unsigned int)(n) : PRVM_EDICT_NUM_ERROR(prog, (unsigned int)(n), __FILE__, __LINE__))
 #define        PRVM_EDICT_NUM(n) (prog->edicts + PRVM_EDICT(n))
 
 //int NUM_FOR_EDICT_ERROR(prvm_edict_t *e);
@@ -763,58 +813,37 @@ unsigned int PRVM_EDICT_NUM_ERROR(unsigned int n, const char *filename, int file
 #define        PRVM_G_EDICT(o) (PRVM_PROG_TO_EDICT(*(int *)&prog->globals.generic[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_STRING(o) (PRVM_GetString(prog, *(string_t *)&prog->globals.generic[o]))
+//#define      PRVM_G_FUNCTION(prog, o) (*(func_t *)&prog->globals.generic[o])
 
 // FIXME: make these go away?
 #define        PRVM_E_FLOAT(e,o) (((float*)e->fields.vp)[o])
 #define        PRVM_E_INT(e,o) (((int*)e->fields.vp)[o])
 //#define      PRVM_E_VECTOR(e,o) (&((float*)e->fields.vp)[o])
-#define        PRVM_E_STRING(e,o) (PRVM_GetString(*(string_t *)&((float*)e->fields.vp)[o]))
+#define        PRVM_E_STRING(e,o) (PRVM_GetString(prog, *(string_t *)&((float*)e->fields.vp)[o]))
 
 extern int             prvm_type_size[8]; // for consistency : I think a goal of this sub-project is to
 // make the new vm mostly independent from the old one, thus if it's necessary, I copy everything
 
-void PRVM_Init_Exec(void);
+void PRVM_Init_Exec(prvm_prog_t *prog);
 
 void PRVM_ED_PrintEdicts_f (void);
-void PRVM_ED_PrintNum (int ent, const char *wildcard_fieldname);
-
-const char *PRVM_GetString(int num);
-int PRVM_SetEngineString(const char *s);
-const char *PRVM_ChangeEngineString(int i, const char *s);
-int PRVM_SetTempString(const char *s);
-int PRVM_AllocString(size_t bufferlength, char **pointer);
-void PRVM_FreeString(int num);
+void PRVM_ED_PrintNum (prvm_prog_t *prog, int ent, const char *wildcard_fieldname);
 
-//============================================================================
+const char *PRVM_GetString(prvm_prog_t *prog, int num);
+int PRVM_SetEngineString(prvm_prog_t *prog, const char *s);
+const char *PRVM_ChangeEngineString(prvm_prog_t *prog, int i, const char *s);
+int PRVM_SetTempString(prvm_prog_t *prog, const char *s);
+int PRVM_AllocString(prvm_prog_t *prog, size_t bufferlength, char **pointer);
+void PRVM_FreeString(prvm_prog_t *prog, int num);
 
-// used as replacement for a prog stack
-//#define PRVM_DEBUGPRSTACK
+ddef_t *PRVM_ED_FieldAtOfs(prvm_prog_t *prog, int ofs);
+qboolean PRVM_ED_ParseEpair(prvm_prog_t *prog, prvm_edict_t *ent, ddef_t *key, const char *s, qboolean parsebackslash);
+char *PRVM_UglyValueString(prvm_prog_t *prog, etype_t type, prvm_eval_t *val, char *line, size_t linelength);
+char *PRVM_GlobalString(prvm_prog_t *prog, int ofs, char *line, size_t linelength);
+char *PRVM_GlobalStringNoContents(prvm_prog_t *prog, int ofs, char *line, size_t linelength);
 
-#ifdef PRVM_DEBUGPRSTACK
-#define PRVM_Begin  if(prog != 0) Con_Printf("prog not 0(prog = %i) in file: %s line: %i!\n", PRVM_GetProgNr(), __FILE__, __LINE__)
-#define PRVM_End       prog = 0
-#else
-#define PRVM_Begin
-#define PRVM_End       prog = 0
-#endif
-
-//#define PRVM_SAFENAME
-#ifndef PRVM_SAFENAME
-#      define PRVM_NAME        (prog->name)
-#else
-#      define PRVM_NAME        (prog->name ? prog->name : "Unknown prog name")
-#endif
-
-// helper macro to make function pointer calls easier
-#define PRVM_GCALL(func)       if(prog->func) prog->func
-
-#define PRVM_ERROR             prog->error_cmd
-
-// other prog handling functions
-qboolean PRVM_SetProgFromString(const char *str);
-void PRVM_SetProg(int prognr);
+//============================================================================
 
 /*
 Initializing a vm:
@@ -822,23 +851,18 @@ Call InitProg with the num
 Set up the fields marked with [INIT] in the prog struct
 Load a program with LoadProgs
 */
-void PRVM_InitProg(int prognr);
-// LoadProgs expects to be called right after InitProg
-void PRVM_LoadProgs (const char *filename, int numrequiredfunc, const char **required_func, int numrequiredfields, prvm_required_field_t *required_field, int numrequiredglobals, prvm_required_field_t *required_global);
-void PRVM_ResetProg(void);
-
-qboolean PRVM_ProgLoaded(int prognr);
-
-int    PRVM_GetProgNr(void);
+// Load expects to be called right after Init
+void PRVM_Prog_Init(prvm_prog_t *prog);
+void PRVM_Prog_Load(prvm_prog_t *prog, const char *filename, int numrequiredfunc, const char **required_func, int numrequiredfields, prvm_required_field_t *required_field, int numrequiredglobals, prvm_required_field_t *required_global);
+void PRVM_Prog_Reset(prvm_prog_t *prog);
 
-void VM_Warning(const char *fmt, ...) DP_FUNC_PRINTF(1);
+void PRVM_StackTrace(prvm_prog_t *prog);
 
-// TODO: fill in the params
-//void PRVM_Create();
+void VM_Warning(prvm_prog_t *prog, const char *fmt, ...) DP_FUNC_PRINTF(2);
 
-void VM_GenerateFrameGroupBlend(framegroupblend_t *framegroupblend, const prvm_edict_t *ed);
+void VM_GenerateFrameGroupBlend(prvm_prog_t *prog, framegroupblend_t *framegroupblend, const prvm_edict_t *ed);
 void VM_FrameBlendFromFrameGroupBlend(frameblend_t *frameblend, const framegroupblend_t *framegroupblend, const dp_model_t *model);
-void VM_UpdateEdictSkeleton(prvm_edict_t *ed, const dp_model_t *edmodel, const frameblend_t *frameblend);
-void VM_RemoveEdictSkeleton(prvm_edict_t *ed);
+void VM_UpdateEdictSkeleton(prvm_prog_t *prog, prvm_edict_t *ed, const dp_model_t *edmodel, const frameblend_t *frameblend);
+void VM_RemoveEdictSkeleton(prvm_prog_t *prog, prvm_edict_t *ed);
 
 #endif
index 3e384e16fccb0face48c7b49f3087702575e1439..4f0139b502453f07d3407d205059e4ed8d531d3d 100644 (file)
@@ -7,7 +7,7 @@
        if(developer_networkentities.integer >= 2) \
        { \
                prvm_edict_t *ed = prog->edicts + num; \
-               Con_Printf("sent entity update of size %d for a %s\n", (msg->cursize - entityprofiling_startsize), PRVM_serveredictstring(ed, classname) ? PRVM_GetString(PRVM_serveredictstring(ed, classname)) : "(no classname)"); \
+               Con_Printf("sent entity update of size %d for a %s\n", (msg->cursize - entityprofiling_startsize), PRVM_serveredictstring(ed, classname) ? PRVM_GetString(prog, PRVM_serveredictstring(ed, classname)) : "(no classname)"); \
        }
 
 // this is 88 bytes (must match entity_state_t in protocol.h)
@@ -131,18 +131,18 @@ void EntityFrameQuake_ReadEntity(int bits)
        entity_state_t s;
 
        if (bits & U_MOREBITS)
-               bits |= (MSG_ReadByte()<<8);
+               bits |= (MSG_ReadByte(&cl_message)<<8);
        if ((bits & U_EXTEND1) && cls.protocol != PROTOCOL_NEHAHRAMOVIE)
        {
-               bits |= MSG_ReadByte() << 16;
+               bits |= MSG_ReadByte(&cl_message) << 16;
                if (bits & U_EXTEND2)
-                       bits |= MSG_ReadByte() << 24;
+                       bits |= MSG_ReadByte(&cl_message) << 24;
        }
 
        if (bits & U_LONGENTITY)
-               num = (unsigned short) MSG_ReadShort ();
+               num = (unsigned short) MSG_ReadShort(&cl_message);
        else
-               num = MSG_ReadByte ();
+               num = MSG_ReadByte(&cl_message);
 
        if (num >= MAX_EDICTS)
                Host_Error("EntityFrameQuake_ReadEntity: entity number (%i) >= MAX_EDICTS (%i)", num, MAX_EDICTS);
@@ -178,30 +178,30 @@ void EntityFrameQuake_ReadEntity(int bits)
        if (bits & U_MODEL)
        {
                if (cls.protocol == PROTOCOL_NEHAHRABJP || cls.protocol == PROTOCOL_NEHAHRABJP2 || cls.protocol == PROTOCOL_NEHAHRABJP3)
-                                                       s.modelindex = (unsigned short) MSG_ReadShort();
+                                                       s.modelindex = (unsigned short) MSG_ReadShort(&cl_message);
                else
-                                                       s.modelindex = (s.modelindex & 0xFF00) | MSG_ReadByte();
-       }
-       if (bits & U_FRAME)             s.frame = (s.frame & 0xFF00) | MSG_ReadByte();
-       if (bits & U_COLORMAP)  s.colormap = MSG_ReadByte();
-       if (bits & U_SKIN)              s.skin = MSG_ReadByte();
-       if (bits & U_EFFECTS)   s.effects = (s.effects & 0xFF00) | MSG_ReadByte();
-       if (bits & U_ORIGIN1)   s.origin[0] = MSG_ReadCoord(cls.protocol);
-       if (bits & U_ANGLE1)    s.angles[0] = MSG_ReadAngle(cls.protocol);
-       if (bits & U_ORIGIN2)   s.origin[1] = MSG_ReadCoord(cls.protocol);
-       if (bits & U_ANGLE2)    s.angles[1] = MSG_ReadAngle(cls.protocol);
-       if (bits & U_ORIGIN3)   s.origin[2] = MSG_ReadCoord(cls.protocol);
-       if (bits & U_ANGLE3)    s.angles[2] = MSG_ReadAngle(cls.protocol);
+                                                       s.modelindex = (s.modelindex & 0xFF00) | MSG_ReadByte(&cl_message);
+       }
+       if (bits & U_FRAME)             s.frame = (s.frame & 0xFF00) | MSG_ReadByte(&cl_message);
+       if (bits & U_COLORMAP)  s.colormap = MSG_ReadByte(&cl_message);
+       if (bits & U_SKIN)              s.skin = MSG_ReadByte(&cl_message);
+       if (bits & U_EFFECTS)   s.effects = (s.effects & 0xFF00) | MSG_ReadByte(&cl_message);
+       if (bits & U_ORIGIN1)   s.origin[0] = MSG_ReadCoord(&cl_message, cls.protocol);
+       if (bits & U_ANGLE1)    s.angles[0] = MSG_ReadAngle(&cl_message, cls.protocol);
+       if (bits & U_ORIGIN2)   s.origin[1] = MSG_ReadCoord(&cl_message, cls.protocol);
+       if (bits & U_ANGLE2)    s.angles[1] = MSG_ReadAngle(&cl_message, cls.protocol);
+       if (bits & U_ORIGIN3)   s.origin[2] = MSG_ReadCoord(&cl_message, cls.protocol);
+       if (bits & U_ANGLE3)    s.angles[2] = MSG_ReadAngle(&cl_message, cls.protocol);
        if (bits & U_STEP)              s.flags |= RENDER_STEP;
-       if (bits & U_ALPHA)             s.alpha = MSG_ReadByte();
-       if (bits & U_SCALE)             s.scale = MSG_ReadByte();
-       if (bits & U_EFFECTS2)  s.effects = (s.effects & 0x00FF) | (MSG_ReadByte() << 8);
-       if (bits & U_GLOWSIZE)  s.glowsize = MSG_ReadByte();
-       if (bits & U_GLOWCOLOR) s.glowcolor = MSG_ReadByte();
-       if (bits & U_COLORMOD)  {int c = MSG_ReadByte();s.colormod[0] = (unsigned char)(((c >> 5) & 7) * (32.0f / 7.0f));s.colormod[1] = (unsigned char)(((c >> 2) & 7) * (32.0f / 7.0f));s.colormod[2] = (unsigned char)((c & 3) * (32.0f / 3.0f));}
+       if (bits & U_ALPHA)             s.alpha = MSG_ReadByte(&cl_message);
+       if (bits & U_SCALE)             s.scale = MSG_ReadByte(&cl_message);
+       if (bits & U_EFFECTS2)  s.effects = (s.effects & 0x00FF) | (MSG_ReadByte(&cl_message) << 8);
+       if (bits & U_GLOWSIZE)  s.glowsize = MSG_ReadByte(&cl_message);
+       if (bits & U_GLOWCOLOR) s.glowcolor = MSG_ReadByte(&cl_message);
+       if (bits & U_COLORMOD)  {int c = MSG_ReadByte(&cl_message);s.colormod[0] = (unsigned char)(((c >> 5) & 7) * (32.0f / 7.0f));s.colormod[1] = (unsigned char)(((c >> 2) & 7) * (32.0f / 7.0f));s.colormod[2] = (unsigned char)((c & 3) * (32.0f / 3.0f));}
        if (bits & U_GLOWTRAIL) s.flags |= RENDER_GLOWTRAIL;
-       if (bits & U_FRAME2)    s.frame = (s.frame & 0x00FF) | (MSG_ReadByte() << 8);
-       if (bits & U_MODEL2)    s.modelindex = (s.modelindex & 0x00FF) | (MSG_ReadByte() << 8);
+       if (bits & U_FRAME2)    s.frame = (s.frame & 0x00FF) | (MSG_ReadByte(&cl_message) << 8);
+       if (bits & U_MODEL2)    s.modelindex = (s.modelindex & 0x00FF) | (MSG_ReadByte(&cl_message) << 8);
        if (bits & U_VIEWMODEL) s.flags |= RENDER_VIEWMODEL;
        if (bits & U_EXTERIORMODEL)     s.flags |= RENDER_EXTERIORMODEL;
 
@@ -209,11 +209,11 @@ void EntityFrameQuake_ReadEntity(int bits)
        if (cls.protocol == PROTOCOL_NEHAHRAMOVIE && (bits & U_EXTEND1))
        {
                // LordHavoc: evil format
-               int i = (int)MSG_ReadFloat();
-               int j = (int)(MSG_ReadFloat() * 255.0f);
+               int i = (int)MSG_ReadFloat(&cl_message);
+               int j = (int)(MSG_ReadFloat(&cl_message) * 255.0f);
                if (i == 2)
                {
-                       i = (int)MSG_ReadFloat();
+                       i = (int)MSG_ReadFloat(&cl_message);
                        if (i)
                                s.effects |= EF_FULLBRIGHT;
                }
@@ -233,7 +233,7 @@ void EntityFrameQuake_ReadEntity(int bits)
                cl.entities_active[ent->state_current.number] = true;
        }
 
-       if (msg_badread)
+       if (cl_message.badread)
                Host_Error("EntityFrameQuake_ReadEntity: read error");
 }
 
@@ -270,6 +270,7 @@ void EntityFrameQuake_ISeeDeadEntities(void)
 // Always use the DP5 protocol, or a higher one, when using CSQC entities.
 static void EntityFrameCSQC_LostAllFrames(client_t *client)
 {
+       prvm_prog_t *prog = SVVM_prog;
        // mark ALL csqc entities as requiring a FULL resend!
        // I know this is a bad workaround, but better than nothing.
        int i, n;
@@ -297,7 +298,7 @@ void EntityFrameCSQC_LostFrame(client_t *client, int framenum)
        int i, j;
        qboolean valid;
        int ringfirst, ringlast;
-       static int recoversendflags[MAX_EDICTS];
+       static int recoversendflags[MAX_EDICTS]; // client only
        csqcentityframedb_t *d;
 
        if(client->csqcentityframe_lastreset < 0)
@@ -432,6 +433,7 @@ static void EntityFrameCSQC_DeallocFrame(client_t *client, int framenum)
 // amounts of csqc networked entities
 qboolean EntityFrameCSQC_WriteFrame (sizebuf_t *msg, int maxsize, int numnumbers, const unsigned short *numbers, int framenum)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int num, number, end, sendflags;
        qboolean sectionstarted = false;
        const unsigned short *n;
@@ -555,7 +557,7 @@ qboolean EntityFrameCSQC_WriteFrame (sizebuf_t *msg, int maxsize, int numnumbers
                                        PRVM_G_INT(OFS_PARM0) = sv.writeentitiestoclient_cliententitynumber;
                                        PRVM_G_FLOAT(OFS_PARM1) = sendflags;
                                        PRVM_serverglobaledict(self) = number;
-                                       PRVM_ExecuteProgram(PRVM_serveredictfunction(ed, SendEntity), "Null SendEntity\n");
+                                       prog->ExecuteProgram(prog, PRVM_serveredictfunction(ed, SendEntity), "Null SendEntity\n");
                                        msg->allowoverflow = false;
                                        if(PRVM_G_FLOAT(OFS_RETURN) && msg->cursize + 2 <= maxsize)
                                        {
@@ -677,6 +679,7 @@ void Protocol_WriteStatsReliable(void)
 
 qboolean EntityFrameQuake_WriteFrame(sizebuf_t *msg, int maxsize, int numstates, const entity_state_t **states)
 {
+       prvm_prog_t *prog = SVVM_prog;
        const entity_state_t *s;
        entity_state_t baseline;
        int i, bits;
@@ -1022,6 +1025,7 @@ void EntityState_WriteFields(const entity_state_t *ent, sizebuf_t *msg, unsigned
 
 void EntityState_WriteUpdate(const entity_state_t *ent, sizebuf_t *msg, const entity_state_t *delta)
 {
+       prvm_prog_t *prog = SVVM_prog;
        unsigned int bits;
        ENTITYSIZEPROFILING_START(msg, ent->number);
        if (ent->active == ACTIVE_NETWORK)
@@ -1050,15 +1054,15 @@ void EntityState_WriteUpdate(const entity_state_t *ent, sizebuf_t *msg, const en
 int EntityState_ReadExtendBits(void)
 {
        unsigned int bits;
-       bits = MSG_ReadByte();
+       bits = MSG_ReadByte(&cl_message);
        if (bits & 0x00000080)
        {
-               bits |= MSG_ReadByte() << 8;
+               bits |= MSG_ReadByte(&cl_message) << 8;
                if (bits & 0x00008000)
                {
-                       bits |= MSG_ReadByte() << 16;
+                       bits |= MSG_ReadByte(&cl_message) << 16;
                        if (bits & 0x00800000)
-                               bits |= MSG_ReadByte() << 24;
+                               bits |= MSG_ReadByte(&cl_message) << 24;
                }
        }
        return bits;
@@ -1069,96 +1073,96 @@ void EntityState_ReadFields(entity_state_t *e, unsigned int bits)
        if (cls.protocol == PROTOCOL_DARKPLACES2)
        {
                if (bits & E_ORIGIN1)
-                       e->origin[0] = MSG_ReadCoord16i();
+                       e->origin[0] = MSG_ReadCoord16i(&cl_message);
                if (bits & E_ORIGIN2)
-                       e->origin[1] = MSG_ReadCoord16i();
+                       e->origin[1] = MSG_ReadCoord16i(&cl_message);
                if (bits & E_ORIGIN3)
-                       e->origin[2] = MSG_ReadCoord16i();
+                       e->origin[2] = MSG_ReadCoord16i(&cl_message);
        }
        else
        {
                if (bits & E_FLAGS)
-                       e->flags = MSG_ReadByte();
+                       e->flags = MSG_ReadByte(&cl_message);
                if (e->flags & RENDER_LOWPRECISION)
                {
                        if (bits & E_ORIGIN1)
-                               e->origin[0] = MSG_ReadCoord16i();
+                               e->origin[0] = MSG_ReadCoord16i(&cl_message);
                        if (bits & E_ORIGIN2)
-                               e->origin[1] = MSG_ReadCoord16i();
+                               e->origin[1] = MSG_ReadCoord16i(&cl_message);
                        if (bits & E_ORIGIN3)
-                               e->origin[2] = MSG_ReadCoord16i();
+                               e->origin[2] = MSG_ReadCoord16i(&cl_message);
                }
                else
                {
                        if (bits & E_ORIGIN1)
-                               e->origin[0] = MSG_ReadCoord32f();
+                               e->origin[0] = MSG_ReadCoord32f(&cl_message);
                        if (bits & E_ORIGIN2)
-                               e->origin[1] = MSG_ReadCoord32f();
+                               e->origin[1] = MSG_ReadCoord32f(&cl_message);
                        if (bits & E_ORIGIN3)
-                               e->origin[2] = MSG_ReadCoord32f();
+                               e->origin[2] = MSG_ReadCoord32f(&cl_message);
                }
        }
        if ((cls.protocol == PROTOCOL_DARKPLACES5 || cls.protocol == PROTOCOL_DARKPLACES6) && !(e->flags & RENDER_LOWPRECISION))
        {
                if (bits & E_ANGLE1)
-                       e->angles[0] = MSG_ReadAngle16i();
+                       e->angles[0] = MSG_ReadAngle16i(&cl_message);
                if (bits & E_ANGLE2)
-                       e->angles[1] = MSG_ReadAngle16i();
+                       e->angles[1] = MSG_ReadAngle16i(&cl_message);
                if (bits & E_ANGLE3)
-                       e->angles[2] = MSG_ReadAngle16i();
+                       e->angles[2] = MSG_ReadAngle16i(&cl_message);
        }
        else
        {
                if (bits & E_ANGLE1)
-                       e->angles[0] = MSG_ReadAngle8i();
+                       e->angles[0] = MSG_ReadAngle8i(&cl_message);
                if (bits & E_ANGLE2)
-                       e->angles[1] = MSG_ReadAngle8i();
+                       e->angles[1] = MSG_ReadAngle8i(&cl_message);
                if (bits & E_ANGLE3)
-                       e->angles[2] = MSG_ReadAngle8i();
+                       e->angles[2] = MSG_ReadAngle8i(&cl_message);
        }
        if (bits & E_MODEL1)
-               e->modelindex = (e->modelindex & 0xFF00) | (unsigned int) MSG_ReadByte();
+               e->modelindex = (e->modelindex & 0xFF00) | (unsigned int) MSG_ReadByte(&cl_message);
        if (bits & E_MODEL2)
-               e->modelindex = (e->modelindex & 0x00FF) | ((unsigned int) MSG_ReadByte() << 8);
+               e->modelindex = (e->modelindex & 0x00FF) | ((unsigned int) MSG_ReadByte(&cl_message) << 8);
        if (bits & E_FRAME1)
-               e->frame = (e->frame & 0xFF00) | (unsigned int) MSG_ReadByte();
+               e->frame = (e->frame & 0xFF00) | (unsigned int) MSG_ReadByte(&cl_message);
        if (bits & E_FRAME2)
-               e->frame = (e->frame & 0x00FF) | ((unsigned int) MSG_ReadByte() << 8);
+               e->frame = (e->frame & 0x00FF) | ((unsigned int) MSG_ReadByte(&cl_message) << 8);
        if (bits & E_EFFECTS1)
-               e->effects = (e->effects & 0xFF00) | (unsigned int) MSG_ReadByte();
+               e->effects = (e->effects & 0xFF00) | (unsigned int) MSG_ReadByte(&cl_message);
        if (bits & E_EFFECTS2)
-               e->effects = (e->effects & 0x00FF) | ((unsigned int) MSG_ReadByte() << 8);
+               e->effects = (e->effects & 0x00FF) | ((unsigned int) MSG_ReadByte(&cl_message) << 8);
        if (bits & E_COLORMAP)
-               e->colormap = MSG_ReadByte();
+               e->colormap = MSG_ReadByte(&cl_message);
        if (bits & E_SKIN)
-               e->skin = MSG_ReadByte();
+               e->skin = MSG_ReadByte(&cl_message);
        if (bits & E_ALPHA)
-               e->alpha = MSG_ReadByte();
+               e->alpha = MSG_ReadByte(&cl_message);
        if (bits & E_SCALE)
-               e->scale = MSG_ReadByte();
+               e->scale = MSG_ReadByte(&cl_message);
        if (bits & E_GLOWSIZE)
-               e->glowsize = MSG_ReadByte();
+               e->glowsize = MSG_ReadByte(&cl_message);
        if (bits & E_GLOWCOLOR)
-               e->glowcolor = MSG_ReadByte();
+               e->glowcolor = MSG_ReadByte(&cl_message);
        if (cls.protocol == PROTOCOL_DARKPLACES2)
                if (bits & E_FLAGS)
-                       e->flags = MSG_ReadByte();
+                       e->flags = MSG_ReadByte(&cl_message);
        if (bits & E_TAGATTACHMENT)
        {
-               e->tagentity = (unsigned short) MSG_ReadShort();
-               e->tagindex = MSG_ReadByte();
+               e->tagentity = (unsigned short) MSG_ReadShort(&cl_message);
+               e->tagindex = MSG_ReadByte(&cl_message);
        }
        if (bits & E_LIGHT)
        {
-               e->light[0] = (unsigned short) MSG_ReadShort();
-               e->light[1] = (unsigned short) MSG_ReadShort();
-               e->light[2] = (unsigned short) MSG_ReadShort();
-               e->light[3] = (unsigned short) MSG_ReadShort();
+               e->light[0] = (unsigned short) MSG_ReadShort(&cl_message);
+               e->light[1] = (unsigned short) MSG_ReadShort(&cl_message);
+               e->light[2] = (unsigned short) MSG_ReadShort(&cl_message);
+               e->light[3] = (unsigned short) MSG_ReadShort(&cl_message);
        }
        if (bits & E_LIGHTSTYLE)
-               e->lightstyle = MSG_ReadByte();
+               e->lightstyle = MSG_ReadByte(&cl_message);
        if (bits & E_LIGHTPFLAGS)
-               e->lightpflags = MSG_ReadByte();
+               e->lightpflags = MSG_ReadByte(&cl_message);
 
        if (developer_networkentities.integer >= 2)
        {
@@ -1210,8 +1214,6 @@ void EntityState_ReadFields(entity_state_t *e, unsigned int bits)
        }
 }
 
-extern void CL_NewFrameReceived(int num);
-
 // (client and server) allocates a new empty database
 entityframe_database_t *EntityFrame_AllocDatabase(mempool_t *mempool)
 {
@@ -1384,6 +1386,7 @@ void EntityFrame_AddFrame_Server(entityframe_database_t *d, vec3_t eye, int fram
 // (server) writes a frame to network stream
 qboolean EntityFrame_WriteFrame(sizebuf_t *msg, int maxsize, entityframe_database_t *d, int numstates, const entity_state_t **states, int viewentnum)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i, onum, number;
        entity_frame_t *o = &d->deltaframe;
        const entity_state_t *ent, *delta;
@@ -1468,20 +1471,20 @@ void EntityFrame_CL_ReadFrame(void)
 
        // read the frame header info
        f->time = cl.mtime[0];
-       number = MSG_ReadLong();
-       f->framenum = MSG_ReadLong();
+       number = MSG_ReadLong(&cl_message);
+       f->framenum = MSG_ReadLong(&cl_message);
        CL_NewFrameReceived(f->framenum);
-       f->eye[0] = MSG_ReadFloat();
-       f->eye[1] = MSG_ReadFloat();
-       f->eye[2] = MSG_ReadFloat();
+       f->eye[0] = MSG_ReadFloat(&cl_message);
+       f->eye[1] = MSG_ReadFloat(&cl_message);
+       f->eye[2] = MSG_ReadFloat(&cl_message);
        EntityFrame_AckFrame(d, number);
        EntityFrame_FetchFrame(d, number, delta);
        old = delta->entitydata;
        oldend = old + delta->numentities;
        // read entities until we hit the magic 0xFFFF end tag
-       while ((number = (unsigned short) MSG_ReadShort()) != 0xFFFF && !msg_badread)
+       while ((number = (unsigned short) MSG_ReadShort(&cl_message)) != 0xFFFF && !cl_message.badread)
        {
-               if (msg_badread)
+               if (cl_message.badread)
                        Host_Error("EntityFrame_Read: read error");
                removed = number & 0x8000;
                number &= 0x7FFF;
@@ -1733,12 +1736,12 @@ void EntityFrame4_CL_ReadFrame(void)
                cl.entitydatabase4 = EntityFrame4_AllocDatabase(cls.levelmempool);
        d = cl.entitydatabase4;
        // read the number of the frame this refers to
-       referenceframenum = MSG_ReadLong();
+       referenceframenum = MSG_ReadLong(&cl_message);
        // read the number of this frame
-       framenum = MSG_ReadLong();
+       framenum = MSG_ReadLong(&cl_message);
        CL_NewFrameReceived(framenum);
        // read the start number
-       enumber = (unsigned short) MSG_ReadShort();
+       enumber = (unsigned short) MSG_ReadShort(&cl_message);
        if (developer_networkentities.integer >= 10)
        {
                Con_Printf("recv svc_entities num:%i ref:%i database: ref:%i commits:", framenum, referenceframenum, d->referenceframenum);
@@ -1768,18 +1771,18 @@ void EntityFrame4_CL_ReadFrame(void)
                skip = true;
        }
        done = false;
-       while (!done && !msg_badread)
+       while (!done && !cl_message.badread)
        {
                // read the number of the modified entity
                // (gaps will be copied unmodified)
-               n = (unsigned short)MSG_ReadShort();
+               n = (unsigned short)MSG_ReadShort(&cl_message);
                if (n == 0x8000)
                {
                        // no more entities in this update, but we still need to copy the
                        // rest of the reference entities (final gap)
                        done = true;
                        // read end of range number, then process normally
-                       n = (unsigned short)MSG_ReadShort();
+                       n = (unsigned short)MSG_ReadShort(&cl_message);
                }
                // high bit means it's a remove message
                cnumber = n & 0x7FFF;
@@ -1859,6 +1862,7 @@ void EntityFrame4_CL_ReadFrame(void)
 
 qboolean EntityFrame4_WriteFrame(sizebuf_t *msg, int maxsize, entityframe4_database_t *d, int numstates, const entity_state_t **states)
 {
+       prvm_prog_t *prog = SVVM_prog;
        const entity_state_t *e, *s;
        entity_state_t inactiveentitystate;
        int i, n, startnumber;
@@ -2060,6 +2064,7 @@ static int EntityState5_Priority(entityframe5_database_t *d, int stateindex)
 
 void EntityState5_WriteUpdate(int number, const entity_state_t *s, int changedbits, sizebuf_t *msg)
 {
+       prvm_prog_t *prog = SVVM_prog;
        unsigned int bits = 0;
        //dp_model_t *model;
        ENTITYSIZEPROFILING_START(msg, s->number);
@@ -2279,20 +2284,18 @@ void EntityState5_WriteUpdate(int number, const entity_state_t *s, int changedbi
        ENTITYSIZEPROFILING_END(msg, s->number);
 }
 
-extern dp_model_t *CL_GetModelByIndex(int modelindex);
-
 static void EntityState5_ReadUpdate(entity_state_t *s, int number)
 {
        int bits;
-       bits = MSG_ReadByte();
+       bits = MSG_ReadByte(&cl_message);
        if (bits & E5_EXTEND1)
        {
-               bits |= MSG_ReadByte() << 8;
+               bits |= MSG_ReadByte(&cl_message) << 8;
                if (bits & E5_EXTEND2)
                {
-                       bits |= MSG_ReadByte() << 16;
+                       bits |= MSG_ReadByte(&cl_message) << 16;
                        if (bits & E5_EXTEND3)
-                               bits |= MSG_ReadByte() << 24;
+                               bits |= MSG_ReadByte(&cl_message) << 24;
                }
        }
        if (bits & E5_FULLUPDATE)
@@ -2301,98 +2304,98 @@ static void EntityState5_ReadUpdate(entity_state_t *s, int number)
                s->active = ACTIVE_NETWORK;
        }
        if (bits & E5_FLAGS)
-               s->flags = MSG_ReadByte();
+               s->flags = MSG_ReadByte(&cl_message);
        if (bits & E5_ORIGIN)
        {
                if (bits & E5_ORIGIN32)
                {
-                       s->origin[0] = MSG_ReadCoord32f();
-                       s->origin[1] = MSG_ReadCoord32f();
-                       s->origin[2] = MSG_ReadCoord32f();
+                       s->origin[0] = MSG_ReadCoord32f(&cl_message);
+                       s->origin[1] = MSG_ReadCoord32f(&cl_message);
+                       s->origin[2] = MSG_ReadCoord32f(&cl_message);
                }
                else
                {
-                       s->origin[0] = MSG_ReadCoord13i();
-                       s->origin[1] = MSG_ReadCoord13i();
-                       s->origin[2] = MSG_ReadCoord13i();
+                       s->origin[0] = MSG_ReadCoord13i(&cl_message);
+                       s->origin[1] = MSG_ReadCoord13i(&cl_message);
+                       s->origin[2] = MSG_ReadCoord13i(&cl_message);
                }
        }
        if (bits & E5_ANGLES)
        {
                if (bits & E5_ANGLES16)
                {
-                       s->angles[0] = MSG_ReadAngle16i();
-                       s->angles[1] = MSG_ReadAngle16i();
-                       s->angles[2] = MSG_ReadAngle16i();
+                       s->angles[0] = MSG_ReadAngle16i(&cl_message);
+                       s->angles[1] = MSG_ReadAngle16i(&cl_message);
+                       s->angles[2] = MSG_ReadAngle16i(&cl_message);
                }
                else
                {
-                       s->angles[0] = MSG_ReadAngle8i();
-                       s->angles[1] = MSG_ReadAngle8i();
-                       s->angles[2] = MSG_ReadAngle8i();
+                       s->angles[0] = MSG_ReadAngle8i(&cl_message);
+                       s->angles[1] = MSG_ReadAngle8i(&cl_message);
+                       s->angles[2] = MSG_ReadAngle8i(&cl_message);
                }
        }
        if (bits & E5_MODEL)
        {
                if (bits & E5_MODEL16)
-                       s->modelindex = (unsigned short) MSG_ReadShort();
+                       s->modelindex = (unsigned short) MSG_ReadShort(&cl_message);
                else
-                       s->modelindex = MSG_ReadByte();
+                       s->modelindex = MSG_ReadByte(&cl_message);
        }
        if (bits & E5_FRAME)
        {
                if (bits & E5_FRAME16)
-                       s->frame = (unsigned short) MSG_ReadShort();
+                       s->frame = (unsigned short) MSG_ReadShort(&cl_message);
                else
-                       s->frame = MSG_ReadByte();
+                       s->frame = MSG_ReadByte(&cl_message);
        }
        if (bits & E5_SKIN)
-               s->skin = MSG_ReadByte();
+               s->skin = MSG_ReadByte(&cl_message);
        if (bits & E5_EFFECTS)
        {
                if (bits & E5_EFFECTS32)
-                       s->effects = (unsigned int) MSG_ReadLong();
+                       s->effects = (unsigned int) MSG_ReadLong(&cl_message);
                else if (bits & E5_EFFECTS16)
-                       s->effects = (unsigned short) MSG_ReadShort();
+                       s->effects = (unsigned short) MSG_ReadShort(&cl_message);
                else
-                       s->effects = MSG_ReadByte();
+                       s->effects = MSG_ReadByte(&cl_message);
        }
        if (bits & E5_ALPHA)
-               s->alpha = MSG_ReadByte();
+               s->alpha = MSG_ReadByte(&cl_message);
        if (bits & E5_SCALE)
-               s->scale = MSG_ReadByte();
+               s->scale = MSG_ReadByte(&cl_message);
        if (bits & E5_COLORMAP)
-               s->colormap = MSG_ReadByte();
+               s->colormap = MSG_ReadByte(&cl_message);
        if (bits & E5_ATTACHMENT)
        {
-               s->tagentity = (unsigned short) MSG_ReadShort();
-               s->tagindex = MSG_ReadByte();
+               s->tagentity = (unsigned short) MSG_ReadShort(&cl_message);
+               s->tagindex = MSG_ReadByte(&cl_message);
        }
        if (bits & E5_LIGHT)
        {
-               s->light[0] = (unsigned short) MSG_ReadShort();
-               s->light[1] = (unsigned short) MSG_ReadShort();
-               s->light[2] = (unsigned short) MSG_ReadShort();
-               s->light[3] = (unsigned short) MSG_ReadShort();
-               s->lightstyle = MSG_ReadByte();
-               s->lightpflags = MSG_ReadByte();
+               s->light[0] = (unsigned short) MSG_ReadShort(&cl_message);
+               s->light[1] = (unsigned short) MSG_ReadShort(&cl_message);
+               s->light[2] = (unsigned short) MSG_ReadShort(&cl_message);
+               s->light[3] = (unsigned short) MSG_ReadShort(&cl_message);
+               s->lightstyle = MSG_ReadByte(&cl_message);
+               s->lightpflags = MSG_ReadByte(&cl_message);
        }
        if (bits & E5_GLOW)
        {
-               s->glowsize = MSG_ReadByte();
-               s->glowcolor = MSG_ReadByte();
+               s->glowsize = MSG_ReadByte(&cl_message);
+               s->glowcolor = MSG_ReadByte(&cl_message);
        }
        if (bits & E5_COLORMOD)
        {
-               s->colormod[0] = MSG_ReadByte();
-               s->colormod[1] = MSG_ReadByte();
-               s->colormod[2] = MSG_ReadByte();
+               s->colormod[0] = MSG_ReadByte(&cl_message);
+               s->colormod[1] = MSG_ReadByte(&cl_message);
+               s->colormod[2] = MSG_ReadByte(&cl_message);
        }
        if (bits & E5_GLOWMOD)
        {
-               s->glowmod[0] = MSG_ReadByte();
-               s->glowmod[1] = MSG_ReadByte();
-               s->glowmod[2] = MSG_ReadByte();
+               s->glowmod[0] = MSG_ReadByte(&cl_message);
+               s->glowmod[1] = MSG_ReadByte(&cl_message);
+               s->glowmod[2] = MSG_ReadByte(&cl_message);
        }
        if (bits & E5_COMPLEXANIMATION)
        {
@@ -2403,15 +2406,15 @@ static void EntityState5_ReadUpdate(entity_state_t *s, int number)
                int bonenum;
                int numbones;
                short pose6s[6];
-               type = MSG_ReadByte();
+               type = MSG_ReadByte(&cl_message);
                switch(type)
                {
                case 0:
-                       s->framegroupblend[0].frame = MSG_ReadShort();
+                       s->framegroupblend[0].frame = MSG_ReadShort(&cl_message);
                        s->framegroupblend[1].frame = 0;
                        s->framegroupblend[2].frame = 0;
                        s->framegroupblend[3].frame = 0;
-                       s->framegroupblend[0].start = cl.time - (short)MSG_ReadShort() * (1.0f / 1000.0f);
+                       s->framegroupblend[0].start = cl.time - (short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
                        s->framegroupblend[1].start = 0;
                        s->framegroupblend[2].start = 0;
                        s->framegroupblend[3].start = 0;
@@ -2421,54 +2424,54 @@ static void EntityState5_ReadUpdate(entity_state_t *s, int number)
                        s->framegroupblend[3].lerp = 0;
                        break;
                case 1:
-                       s->framegroupblend[0].frame = MSG_ReadShort();
-                       s->framegroupblend[1].frame = MSG_ReadShort();
+                       s->framegroupblend[0].frame = MSG_ReadShort(&cl_message);
+                       s->framegroupblend[1].frame = MSG_ReadShort(&cl_message);
                        s->framegroupblend[2].frame = 0;
                        s->framegroupblend[3].frame = 0;
-                       s->framegroupblend[0].start = cl.time - (short)MSG_ReadShort() * (1.0f / 1000.0f);
-                       s->framegroupblend[1].start = cl.time - (short)MSG_ReadShort() * (1.0f / 1000.0f);
+                       s->framegroupblend[0].start = cl.time - (short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
+                       s->framegroupblend[1].start = cl.time - (short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
                        s->framegroupblend[2].start = 0;
                        s->framegroupblend[3].start = 0;
-                       s->framegroupblend[0].lerp = MSG_ReadByte() * (1.0f / 255.0f);
-                       s->framegroupblend[1].lerp = MSG_ReadByte() * (1.0f / 255.0f);
+                       s->framegroupblend[0].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
+                       s->framegroupblend[1].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
                        s->framegroupblend[2].lerp = 0;
                        s->framegroupblend[3].lerp = 0;
                        break;
                case 2:
-                       s->framegroupblend[0].frame = MSG_ReadShort();
-                       s->framegroupblend[1].frame = MSG_ReadShort();
-                       s->framegroupblend[2].frame = MSG_ReadShort();
+                       s->framegroupblend[0].frame = MSG_ReadShort(&cl_message);
+                       s->framegroupblend[1].frame = MSG_ReadShort(&cl_message);
+                       s->framegroupblend[2].frame = MSG_ReadShort(&cl_message);
                        s->framegroupblend[3].frame = 0;
-                       s->framegroupblend[0].start = cl.time - (short)MSG_ReadShort() * (1.0f / 1000.0f);
-                       s->framegroupblend[1].start = cl.time - (short)MSG_ReadShort() * (1.0f / 1000.0f);
-                       s->framegroupblend[2].start = cl.time - (short)MSG_ReadShort() * (1.0f / 1000.0f);
+                       s->framegroupblend[0].start = cl.time - (short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
+                       s->framegroupblend[1].start = cl.time - (short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
+                       s->framegroupblend[2].start = cl.time - (short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
                        s->framegroupblend[3].start = 0;
-                       s->framegroupblend[0].lerp = MSG_ReadByte() * (1.0f / 255.0f);
-                       s->framegroupblend[1].lerp = MSG_ReadByte() * (1.0f / 255.0f);
-                       s->framegroupblend[2].lerp = MSG_ReadByte() * (1.0f / 255.0f);
+                       s->framegroupblend[0].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
+                       s->framegroupblend[1].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
+                       s->framegroupblend[2].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
                        s->framegroupblend[3].lerp = 0;
                        break;
                case 3:
-                       s->framegroupblend[0].frame = MSG_ReadShort();
-                       s->framegroupblend[1].frame = MSG_ReadShort();
-                       s->framegroupblend[2].frame = MSG_ReadShort();
-                       s->framegroupblend[3].frame = MSG_ReadShort();
-                       s->framegroupblend[0].start = cl.time - (short)MSG_ReadShort() * (1.0f / 1000.0f);
-                       s->framegroupblend[1].start = cl.time - (short)MSG_ReadShort() * (1.0f / 1000.0f);
-                       s->framegroupblend[2].start = cl.time - (short)MSG_ReadShort() * (1.0f / 1000.0f);
-                       s->framegroupblend[3].start = cl.time - (short)MSG_ReadShort() * (1.0f / 1000.0f);
-                       s->framegroupblend[0].lerp = MSG_ReadByte() * (1.0f / 255.0f);
-                       s->framegroupblend[1].lerp = MSG_ReadByte() * (1.0f / 255.0f);
-                       s->framegroupblend[2].lerp = MSG_ReadByte() * (1.0f / 255.0f);
-                       s->framegroupblend[3].lerp = MSG_ReadByte() * (1.0f / 255.0f);
+                       s->framegroupblend[0].frame = MSG_ReadShort(&cl_message);
+                       s->framegroupblend[1].frame = MSG_ReadShort(&cl_message);
+                       s->framegroupblend[2].frame = MSG_ReadShort(&cl_message);
+                       s->framegroupblend[3].frame = MSG_ReadShort(&cl_message);
+                       s->framegroupblend[0].start = cl.time - (short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
+                       s->framegroupblend[1].start = cl.time - (short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
+                       s->framegroupblend[2].start = cl.time - (short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
+                       s->framegroupblend[3].start = cl.time - (short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
+                       s->framegroupblend[0].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
+                       s->framegroupblend[1].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
+                       s->framegroupblend[2].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
+                       s->framegroupblend[3].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
                        break;
                case 4:
                        if (!cl.engineskeletonobjects)
                                cl.engineskeletonobjects = (skeleton_t *) Mem_Alloc(cls.levelmempool, sizeof(*cl.engineskeletonobjects) * MAX_EDICTS);
                        skeleton = &cl.engineskeletonobjects[number];
-                       modelindex = MSG_ReadShort();
+                       modelindex = MSG_ReadShort(&cl_message);
                        model = CL_GetModelByIndex(modelindex);
-                       numbones = MSG_ReadByte();
+                       numbones = MSG_ReadByte(&cl_message);
                        if (model && numbones != model->num_bones)
                                Host_Error("E5_COMPLEXANIMATION: model has different number of bones than network packet describes\n");
                        if (!skeleton->relativetransforms || skeleton->model != model)
@@ -2480,12 +2483,12 @@ static void EntityState5_ReadUpdate(entity_state_t *s, int number)
                        }
                        for (bonenum = 0;bonenum < numbones;bonenum++)
                        {
-                               pose6s[0] = (short)MSG_ReadShort();
-                               pose6s[1] = (short)MSG_ReadShort();
-                               pose6s[2] = (short)MSG_ReadShort();
-                               pose6s[3] = (short)MSG_ReadShort();
-                               pose6s[4] = (short)MSG_ReadShort();
-                               pose6s[5] = (short)MSG_ReadShort();
+                               pose6s[0] = (short)MSG_ReadShort(&cl_message);
+                               pose6s[1] = (short)MSG_ReadShort(&cl_message);
+                               pose6s[2] = (short)MSG_ReadShort(&cl_message);
+                               pose6s[3] = (short)MSG_ReadShort(&cl_message);
+                               pose6s[4] = (short)MSG_ReadShort(&cl_message);
+                               pose6s[5] = (short)MSG_ReadShort(&cl_message);
                                Matrix4x4_FromBonePose6s(skeleton->relativetransforms + bonenum, 1.0f / 64.0f, pose6s);
                        }
                        s->skeletonobject = *skeleton;
@@ -2496,7 +2499,7 @@ static void EntityState5_ReadUpdate(entity_state_t *s, int number)
                }
        }
        if (bits & E5_TRAILEFFECTNUM)
-               s->traileffectnum = (unsigned short) MSG_ReadShort();
+               s->traileffectnum = (unsigned short) MSG_ReadShort(&cl_message);
 
 
        if (developer_networkentities.integer >= 2)
@@ -2612,13 +2615,13 @@ void EntityFrame5_CL_ReadFrame(void)
        entity_t *ent;
        entity_state_t *s;
        // read the number of this frame to echo back in next input packet
-       framenum = MSG_ReadLong();
+       framenum = MSG_ReadLong(&cl_message);
        CL_NewFrameReceived(framenum);
        if (cls.protocol != PROTOCOL_QUAKE && cls.protocol != PROTOCOL_QUAKEDP && cls.protocol != PROTOCOL_NEHAHRAMOVIE && cls.protocol != PROTOCOL_DARKPLACES1 && cls.protocol != PROTOCOL_DARKPLACES2 && cls.protocol != PROTOCOL_DARKPLACES3 && cls.protocol != PROTOCOL_DARKPLACES4 && cls.protocol != PROTOCOL_DARKPLACES5 && cls.protocol != PROTOCOL_DARKPLACES6)
-               cls.servermovesequence = MSG_ReadLong();
+               cls.servermovesequence = MSG_ReadLong(&cl_message);
        // read entity numbers until we find a 0x8000
        // (which would be remove world entity, but is actually a terminator)
-       while ((n = (unsigned short)MSG_ReadShort()) != 0x8000 && !msg_badread)
+       while ((n = (unsigned short)MSG_ReadShort(&cl_message)) != 0x8000 && !cl_message.badread)
        {
                // get the entity number
                enumber = n & 0x7FFF;
@@ -2744,6 +2747,7 @@ void EntityFrame5_AckFrame(entityframe5_database_t *d, int framenum)
 
 qboolean EntityFrame5_WriteFrame(sizebuf_t *msg, int maxsize, entityframe5_database_t *d, int numstates, const entity_state_t **states, int viewentnum, int movesequence, qboolean need_empty)
 {
+       prvm_prog_t *prog = SVVM_prog;
        const entity_state_t *n;
        int i, num, l, framenum, packetlognumber, priority;
        sizebuf_t buf;
@@ -2978,7 +2982,7 @@ static void QW_TranslateEffects(entity_state_t *s, int qweffects)
 
 void EntityStateQW_ReadPlayerUpdate(void)
 {
-       int slot = MSG_ReadByte();
+       int slot = MSG_ReadByte(&cl_message);
        int enumber = slot + 1;
        int weaponframe;
        int msec;
@@ -2999,9 +3003,9 @@ void EntityStateQW_ReadPlayerUpdate(void)
        s->active = ACTIVE_NETWORK;
        s->number = enumber;
        s->colormap = enumber;
-       playerflags = MSG_ReadShort();
-       MSG_ReadVector(s->origin, cls.protocol);
-       s->frame = MSG_ReadByte();
+       playerflags = MSG_ReadShort(&cl_message);
+       MSG_ReadVector(&cl_message, s->origin, cls.protocol);
+       s->frame = MSG_ReadByte(&cl_message);
 
        VectorClear(viewangles);
        VectorClear(velocity);
@@ -3012,47 +3016,47 @@ void EntityStateQW_ReadPlayerUpdate(void)
                // and last input we sent to the server (this packet is in response to
                // our input, so msec is how long ago the last update of this player
                // entity occurred, compared to our input being received)
-               msec = MSG_ReadByte();
+               msec = MSG_ReadByte(&cl_message);
        }
        else
                msec = 0;
        if (playerflags & QW_PF_COMMAND)
        {
-               bits = MSG_ReadByte();
+               bits = MSG_ReadByte(&cl_message);
                if (bits & QW_CM_ANGLE1)
-                       viewangles[0] = MSG_ReadAngle16i(); // cmd->angles[0]
+                       viewangles[0] = MSG_ReadAngle16i(&cl_message); // cmd->angles[0]
                if (bits & QW_CM_ANGLE2)
-                       viewangles[1] = MSG_ReadAngle16i(); // cmd->angles[1]
+                       viewangles[1] = MSG_ReadAngle16i(&cl_message); // cmd->angles[1]
                if (bits & QW_CM_ANGLE3)
-                       viewangles[2] = MSG_ReadAngle16i(); // cmd->angles[2]
+                       viewangles[2] = MSG_ReadAngle16i(&cl_message); // cmd->angles[2]
                if (bits & QW_CM_FORWARD)
-                       MSG_ReadShort(); // cmd->forwardmove
+                       MSG_ReadShort(&cl_message); // cmd->forwardmove
                if (bits & QW_CM_SIDE)
-                       MSG_ReadShort(); // cmd->sidemove
+                       MSG_ReadShort(&cl_message); // cmd->sidemove
                if (bits & QW_CM_UP)
-                       MSG_ReadShort(); // cmd->upmove
+                       MSG_ReadShort(&cl_message); // cmd->upmove
                if (bits & QW_CM_BUTTONS)
-                       (void) MSG_ReadByte(); // cmd->buttons
+                       (void) MSG_ReadByte(&cl_message); // cmd->buttons
                if (bits & QW_CM_IMPULSE)
-                       (void) MSG_ReadByte(); // cmd->impulse
-               (void) MSG_ReadByte(); // cmd->msec
+                       (void) MSG_ReadByte(&cl_message); // cmd->impulse
+               (void) MSG_ReadByte(&cl_message); // cmd->msec
        }
        if (playerflags & QW_PF_VELOCITY1)
-               velocity[0] = MSG_ReadShort();
+               velocity[0] = MSG_ReadShort(&cl_message);
        if (playerflags & QW_PF_VELOCITY2)
-               velocity[1] = MSG_ReadShort();
+               velocity[1] = MSG_ReadShort(&cl_message);
        if (playerflags & QW_PF_VELOCITY3)
-               velocity[2] = MSG_ReadShort();
+               velocity[2] = MSG_ReadShort(&cl_message);
        if (playerflags & QW_PF_MODEL)
-               s->modelindex = MSG_ReadByte();
+               s->modelindex = MSG_ReadByte(&cl_message);
        else
                s->modelindex = cl.qw_modelindex_player;
        if (playerflags & QW_PF_SKINNUM)
-               s->skin = MSG_ReadByte();
+               s->skin = MSG_ReadByte(&cl_message);
        if (playerflags & QW_PF_EFFECTS)
-               QW_TranslateEffects(s, MSG_ReadByte());
+               QW_TranslateEffects(s, MSG_ReadByte(&cl_message));
        if (playerflags & QW_PF_WEAPONFRAME)
-               weaponframe = MSG_ReadByte();
+               weaponframe = MSG_ReadByte(&cl_message);
        else
                weaponframe = 0;
 
@@ -3114,32 +3118,32 @@ static void EntityStateQW_ReadEntityUpdate(entity_state_t *s, int bits)
        s->number = bits & 511;
        bits &= ~511;
        if (bits & QW_U_MOREBITS)
-               bits |= MSG_ReadByte();
+               bits |= MSG_ReadByte(&cl_message);
 
        // store the QW_U_SOLID bit here?
 
        if (bits & QW_U_MODEL)
-               s->modelindex = MSG_ReadByte();
+               s->modelindex = MSG_ReadByte(&cl_message);
        if (bits & QW_U_FRAME)
-               s->frame = MSG_ReadByte();
+               s->frame = MSG_ReadByte(&cl_message);
        if (bits & QW_U_COLORMAP)
-               s->colormap = MSG_ReadByte();
+               s->colormap = MSG_ReadByte(&cl_message);
        if (bits & QW_U_SKIN)
-               s->skin = MSG_ReadByte();
+               s->skin = MSG_ReadByte(&cl_message);
        if (bits & QW_U_EFFECTS)
-               QW_TranslateEffects(s, qweffects = MSG_ReadByte());
+               QW_TranslateEffects(s, qweffects = MSG_ReadByte(&cl_message));
        if (bits & QW_U_ORIGIN1)
-               s->origin[0] = MSG_ReadCoord13i();
+               s->origin[0] = MSG_ReadCoord13i(&cl_message);
        if (bits & QW_U_ANGLE1)
-               s->angles[0] = MSG_ReadAngle8i();
+               s->angles[0] = MSG_ReadAngle8i(&cl_message);
        if (bits & QW_U_ORIGIN2)
-               s->origin[1] = MSG_ReadCoord13i();
+               s->origin[1] = MSG_ReadCoord13i(&cl_message);
        if (bits & QW_U_ANGLE2)
-               s->angles[1] = MSG_ReadAngle8i();
+               s->angles[1] = MSG_ReadAngle8i(&cl_message);
        if (bits & QW_U_ORIGIN3)
-               s->origin[2] = MSG_ReadCoord13i();
+               s->origin[2] = MSG_ReadCoord13i(&cl_message);
        if (bits & QW_U_ANGLE3)
-               s->angles[2] = MSG_ReadAngle8i();
+               s->angles[2] = MSG_ReadAngle8i(&cl_message);
 
        if (developer_networkentities.integer >= 2)
        {
@@ -3209,7 +3213,7 @@ void EntityFrameQW_CL_ReadFrame(qboolean delta)
        oldsnap = NULL;
        if (delta)
        {
-               number = MSG_ReadByte();
+               number = MSG_ReadByte(&cl_message);
                oldsnapindex = cl.qw_deltasequence[newsnapindex];
                if ((number & QW_UPDATE_MASK) != (oldsnapindex & QW_UPDATE_MASK))
                        Con_DPrintf("WARNING: from mismatch\n");
@@ -3237,8 +3241,8 @@ void EntityFrameQW_CL_ReadFrame(qboolean delta)
        oldindex = 0;
        for (;;)
        {
-               int word = (unsigned short)MSG_ReadShort();
-               if (msg_badread)
+               int word = (unsigned short)MSG_ReadShort(&cl_message);
+               if (cl_message.badread)
                        return; // just return, the main parser will print an error
                newnum = word == 0 ? 512 : (word & 511);
                oldnum = delta ? (oldindex >= oldsnap->num_entities ? 9999 : oldsnap->entities[oldindex].number) : 9999;
index 1837090decc99fbc3b0acdddde7ff0cdd75fc281..b172ea6f75b8370afa3f5e541f1c3fda80a47968 100644 (file)
 
 #include "cl_collision.h"
 #include "clvm_cmds.h"
+#include "csprogs.h"
 #include "ft2.h"
 #include "mdfour.h"
 
 extern cvar_t prvm_backtraceforwarnings;
 
 // LordHavoc: changed this to NOT use a return statement, so that it can be used in functions that must return a value
-void VM_Warning(const char *fmt, ...)
+void VM_Warning(prvm_prog_t *prog, const char *fmt, ...)
 {
        va_list argptr;
        char msg[MAX_INPUTLINE];
@@ -34,7 +35,7 @@ void VM_Warning(const char *fmt, ...)
        if(prvm_backtraceforwarnings.integer && recursive != realtime) // NOTE: this compares to the time, just in case if PRVM_PrintState causes a Host_Error and keeps recursive set
        {
                recursive = realtime;
-               PRVM_PrintState();
+               PRVM_PrintState(prog);
                recursive = -1;
        }
 }
@@ -48,13 +49,13 @@ void VM_Warning(const char *fmt, ...)
 // TODO: (move vm_files and vm_fssearchlist to prvm_prog_t struct again) [2007-01-23 LordHavoc]
 // TODO: will this war ever end? [2007-01-23 LordHavoc]
 
-void VM_CheckEmptyString (const char *s)
+void VM_CheckEmptyString(prvm_prog_t *prog, const char *s)
 {
        if (ISWHITESPACE(s[0]))
-               PRVM_ERROR ("%s: Bad string", PRVM_NAME);
+               prog->error_cmd("%s: Bad string", prog->name);
 }
 
-void VM_GenerateFrameGroupBlend(framegroupblend_t *framegroupblend, const prvm_edict_t *ed)
+void VM_GenerateFrameGroupBlend(prvm_prog_t *prog, framegroupblend_t *framegroupblend, const prvm_edict_t *ed)
 {
        // self.frame is the interpolation target (new frame)
        // self.frame1time is the animation base time for the interpolation target
@@ -180,11 +181,11 @@ void VM_FrameBlendFromFrameGroupBlend(frameblend_t *frameblend, const framegroup
        }
 }
 
-void VM_UpdateEdictSkeleton(prvm_edict_t *ed, const dp_model_t *edmodel, const frameblend_t *frameblend)
+void VM_UpdateEdictSkeleton(prvm_prog_t *prog, prvm_edict_t *ed, const dp_model_t *edmodel, const frameblend_t *frameblend)
 {
        if (ed->priv.server->skeleton.model != edmodel)
        {
-               VM_RemoveEdictSkeleton(ed);
+               VM_RemoveEdictSkeleton(prog, ed);
                ed->priv.server->skeleton.model = edmodel;
        }
        if (!ed->priv.server->skeleton.model || !ed->priv.server->skeleton.model->num_bones)
@@ -215,7 +216,7 @@ void VM_UpdateEdictSkeleton(prvm_edict_t *ed, const dp_model_t *edmodel, const f
        }
 }
 
-void VM_RemoveEdictSkeleton(prvm_edict_t *ed)
+void VM_RemoveEdictSkeleton(prvm_prog_t *prog, prvm_edict_t *ed)
 {
        if (ed->priv.server->skeleton.relativetransforms)
                Mem_Free(ed->priv.server->skeleton.relativetransforms);
@@ -228,7 +229,7 @@ void VM_RemoveEdictSkeleton(prvm_edict_t *ed)
 //============================================================================
 //BUILT-IN FUNCTIONS
 
-void VM_VarString(int first, char *out, int outlength)
+void VM_VarString(prvm_prog_t *prog, int first, char *out, int outlength)
 {
        int i;
        const char *s;
@@ -255,7 +256,7 @@ checkextension(extensionname)
 */
 
 // kind of helper function
-static qboolean checkextension(const char *name)
+static qboolean checkextension(prvm_prog_t *prog, const char *name)
 {
        int len;
        const char *e, *start;
@@ -294,11 +295,11 @@ static qboolean checkextension(const char *name)
        return false;
 }
 
-void VM_checkextension (void)
+void VM_checkextension(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1,VM_checkextension);
 
-       PRVM_G_FLOAT(OFS_RETURN) = checkextension(PRVM_G_STRING(OFS_PARM0));
+       PRVM_G_FLOAT(OFS_RETURN) = checkextension(prog, PRVM_G_STRING(OFS_PARM0));
 }
 
 /*
@@ -311,17 +312,17 @@ Dumps self.
 error(value)
 =================
 */
-void VM_error (void)
+void VM_error(prvm_prog_t *prog)
 {
        prvm_edict_t    *ed;
        char string[VM_STRINGTEMP_LENGTH];
 
-       VM_VarString(0, string, sizeof(string));
-       Con_Printf("======%s ERROR in %s:\n%s\n", PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string);
+       VM_VarString(prog, 0, string, sizeof(string));
+       Con_Printf("======%s ERROR in %s:\n%s\n", prog->name, PRVM_GetString(prog, prog->xfunction->s_name), string);
        ed = PRVM_PROG_TO_EDICT(PRVM_allglobaledict(self));
-       PRVM_ED_Print(ed, NULL);
+       PRVM_ED_Print(prog, ed, NULL);
 
-       PRVM_ERROR ("%s: Program error in function %s:\n%s\nTip: read above for entity information\n", PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string);
+       prog->error_cmd("%s: Program error in function %s:\n%s\nTip: read above for entity information\n", prog->name, PRVM_GetString(prog, prog->xfunction->s_name), string);
 }
 
 /*
@@ -334,17 +335,17 @@ removed, but the level can continue.
 objerror(value)
 =================
 */
-void VM_objerror (void)
+void VM_objerror(prvm_prog_t *prog)
 {
        prvm_edict_t    *ed;
        char string[VM_STRINGTEMP_LENGTH];
 
-       VM_VarString(0, string, sizeof(string));
-       Con_Printf("======OBJECT ERROR======\n"); // , PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string); // or include them? FIXME
+       VM_VarString(prog, 0, string, sizeof(string));
+       Con_Printf("======OBJECT ERROR======\n"); // , prog->name, PRVM_GetString(prog->xfunction->s_name), string); // or include them? FIXME
        ed = PRVM_PROG_TO_EDICT(PRVM_allglobaledict(self));
-       PRVM_ED_Print(ed, NULL);
-       PRVM_ED_Free (ed);
-       Con_Printf("%s OBJECT ERROR in %s:\n%s\nTip: read above for entity information\n", PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string);
+       PRVM_ED_Print(prog, ed, NULL);
+       PRVM_ED_Free (prog, ed);
+       Con_Printf("%s OBJECT ERROR in %s:\n%s\nTip: read above for entity information\n", prog->name, PRVM_GetString(prog, prog->xfunction->s_name), string);
 }
 
 /*
@@ -356,11 +357,11 @@ print to console
 print(...[string])
 =================
 */
-void VM_print (void)
+void VM_print(prvm_prog_t *prog)
 {
        char string[VM_STRINGTEMP_LENGTH];
 
-       VM_VarString(0, string, sizeof(string));
+       VM_VarString(prog, 0, string, sizeof(string));
        Con_Print(string);
 }
 
@@ -373,17 +374,17 @@ broadcast print to everyone on server
 bprint(...[string])
 =================
 */
-void VM_bprint (void)
+void VM_bprint(prvm_prog_t *prog)
 {
        char string[VM_STRINGTEMP_LENGTH];
 
        if(!sv.active)
        {
-               VM_Warning("VM_bprint: game is not server(%s) !\n", PRVM_NAME);
+               VM_Warning(prog, "VM_bprint: game is not server(%s) !\n", prog->name);
                return;
        }
 
-       VM_VarString(0, string, sizeof(string));
+       VM_VarString(prog, 0, string, sizeof(string));
        SV_BroadcastPrint(string);
 }
 
@@ -396,7 +397,7 @@ single print to a specific client
 sprint(float clientnum,...[string])
 =================
 */
-void VM_sprint (void)
+void VM_sprint(prvm_prog_t *prog)
 {
        client_t        *client;
        int                     clientnum;
@@ -408,7 +409,7 @@ void VM_sprint (void)
        clientnum = (int)PRVM_G_FLOAT(OFS_PARM0);
        if (!sv.active  || clientnum < 0 || clientnum >= svs.maxclients || !svs.clients[clientnum].active)
        {
-               VM_Warning("VM_sprint: %s: invalid client or server is not active !\n", PRVM_NAME);
+               VM_Warning(prog, "VM_sprint: %s: invalid client or server is not active !\n", prog->name);
                return;
        }
 
@@ -416,7 +417,7 @@ void VM_sprint (void)
        if (!client->netconnection)
                return;
 
-       VM_VarString(1, string, sizeof(string));
+       VM_VarString(prog, 1, string, sizeof(string));
        MSG_WriteChar(&client->netconnection->message,svc_print);
        MSG_WriteString(&client->netconnection->message, string);
 }
@@ -430,12 +431,12 @@ single print to the screen
 centerprint(value)
 =================
 */
-void VM_centerprint (void)
+void VM_centerprint(prvm_prog_t *prog)
 {
        char string[VM_STRINGTEMP_LENGTH];
 
        VM_SAFEPARMCOUNTRANGE(1, 8, VM_centerprint);
-       VM_VarString(0, string, sizeof(string));
+       VM_VarString(prog, 0, string, sizeof(string));
        SCR_CenterPrint(string);
 }
 
@@ -446,7 +447,7 @@ VM_normalize
 vector normalize(vector)
 =================
 */
-void VM_normalize (void)
+void VM_normalize(prvm_prog_t *prog)
 {
        float   *value1;
        vec3_t  newvalue;
@@ -475,7 +476,7 @@ VM_vlen
 scalar vlen(vector)
 =================
 */
-void VM_vlen (void)
+void VM_vlen(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1,VM_vlen);
        PRVM_G_FLOAT(OFS_RETURN) = VectorLength(PRVM_G_VECTOR(OFS_PARM0));
@@ -488,7 +489,7 @@ VM_vectoyaw
 float vectoyaw(vector)
 =================
 */
-void VM_vectoyaw (void)
+void VM_vectoyaw(prvm_prog_t *prog)
 {
        float   *value1;
        float   yaw;
@@ -517,7 +518,7 @@ VM_vectoangles
 vector vectoangles(vector[, vector])
 =================
 */
-void VM_vectoangles (void)
+void VM_vectoangles(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNTRANGE(1, 2,VM_vectoangles);
 
@@ -533,7 +534,7 @@ Returns a number from 0<= num < 1
 float random()
 =================
 */
-void VM_random (void)
+void VM_random(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0,VM_random);
 
@@ -547,7 +548,7 @@ VM_localsound
 localsound(string sample)
 =========
 */
-void VM_localsound(void)
+void VM_localsound(prvm_prog_t *prog)
 {
        const char *s;
 
@@ -558,7 +559,7 @@ void VM_localsound(void)
        if(!S_LocalSound (s))
        {
                PRVM_G_FLOAT(OFS_RETURN) = -4;
-               VM_Warning("VM_localsound: Failed to play %s for %s !\n", s, PRVM_NAME);
+               VM_Warning(prog, "VM_localsound: Failed to play %s for %s !\n", s, prog->name);
                return;
        }
 
@@ -572,9 +573,9 @@ VM_break
 break()
 =================
 */
-void VM_break (void)
+void VM_break(prvm_prog_t *prog)
 {
-       PRVM_ERROR ("%s: break statement", PRVM_NAME);
+       prog->error_cmd("%s: break statement", prog->name);
 }
 
 //============================================================================
@@ -589,11 +590,11 @@ Sends text over to the client's execution buffer
 cmd (string, ...)
 =================
 */
-void VM_localcmd (void)
+void VM_localcmd(prvm_prog_t *prog)
 {
        char string[VM_STRINGTEMP_LENGTH];
        VM_SAFEPARMCOUNTRANGE(1, 8, VM_localcmd);
-       VM_VarString(0, string, sizeof(string));
+       VM_VarString(prog, 0, string, sizeof(string));
        Cbuf_AddText(string);
 }
 
@@ -611,12 +612,12 @@ VM_cvar
 float cvar (string)
 =================
 */
-void VM_cvar (void)
+void VM_cvar(prvm_prog_t *prog)
 {
        char string[VM_STRINGTEMP_LENGTH];
        VM_SAFEPARMCOUNTRANGE(1,8,VM_cvar);
-       VM_VarString(0, string, sizeof(string));
-       VM_CheckEmptyString(string);
+       VM_VarString(prog, 0, string, sizeof(string));
+       VM_CheckEmptyString(prog, string);
        PRVM_G_FLOAT(OFS_RETURN) = PRVM_Cvar_ReadOk(string) ? Cvar_VariableValue(string) : 0;
 }
 
@@ -633,15 +634,15 @@ float CVAR_TYPEFLAG_HASDESCRIPTION = 16;
 float CVAR_TYPEFLAG_READONLY = 32;
 =================
 */
-void VM_cvar_type (void)
+void VM_cvar_type(prvm_prog_t *prog)
 {
        char string[VM_STRINGTEMP_LENGTH];
        cvar_t *cvar;
        int ret;
 
        VM_SAFEPARMCOUNTRANGE(1,8,VM_cvar);
-       VM_VarString(0, string, sizeof(string));
-       VM_CheckEmptyString(string);
+       VM_VarString(prog, 0, string, sizeof(string));
+       VM_CheckEmptyString(prog, string);
        cvar = Cvar_FindVar(string);
 
 
@@ -673,13 +674,13 @@ VM_cvar_string
 const string   VM_cvar_string (string, ...)
 =================
 */
-void VM_cvar_string(void)
+void VM_cvar_string(prvm_prog_t *prog)
 {
        char string[VM_STRINGTEMP_LENGTH];
        VM_SAFEPARMCOUNTRANGE(1,8,VM_cvar_string);
-       VM_VarString(0, string, sizeof(string));
-       VM_CheckEmptyString(string);
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(PRVM_Cvar_ReadOk(string) ? Cvar_VariableString(string) : "");
+       VM_VarString(prog, 0, string, sizeof(string));
+       VM_CheckEmptyString(prog, string);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, PRVM_Cvar_ReadOk(string) ? Cvar_VariableString(string) : "");
 }
 
 
@@ -690,13 +691,13 @@ VM_cvar_defstring
 const string   VM_cvar_defstring (string, ...)
 ========================
 */
-void VM_cvar_defstring (void)
+void VM_cvar_defstring(prvm_prog_t *prog)
 {
        char string[VM_STRINGTEMP_LENGTH];
        VM_SAFEPARMCOUNTRANGE(1,8,VM_cvar_defstring);
-       VM_VarString(0, string, sizeof(string));
-       VM_CheckEmptyString(string);
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(Cvar_VariableDefString(string));
+       VM_VarString(prog, 0, string, sizeof(string));
+       VM_CheckEmptyString(prog, string);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, Cvar_VariableDefString(string));
 }
 
 /*
@@ -706,13 +707,13 @@ VM_cvar_defstring
 const string   VM_cvar_description (string, ...)
 ========================
 */
-void VM_cvar_description (void)
+void VM_cvar_description(prvm_prog_t *prog)
 {
        char string[VM_STRINGTEMP_LENGTH];
        VM_SAFEPARMCOUNTRANGE(1,8,VM_cvar_description);
-       VM_VarString(0, string, sizeof(string));
-       VM_CheckEmptyString(string);
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(Cvar_VariableDescription(string));
+       VM_VarString(prog, 0, string, sizeof(string));
+       VM_CheckEmptyString(prog, string);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, Cvar_VariableDescription(string));
 }
 /*
 =================
@@ -721,14 +722,14 @@ VM_cvar_set
 void cvar_set (string,string, ...)
 =================
 */
-void VM_cvar_set (void)
+void VM_cvar_set(prvm_prog_t *prog)
 {
        const char *name;
        char string[VM_STRINGTEMP_LENGTH];
        VM_SAFEPARMCOUNTRANGE(2,8,VM_cvar_set);
-       VM_VarString(1, string, sizeof(string));
+       VM_VarString(prog, 1, string, sizeof(string));
        name = PRVM_G_STRING(OFS_PARM0);
-       VM_CheckEmptyString(name);
+       VM_CheckEmptyString(prog, name);
        Cvar_Set(name, string);
 }
 
@@ -739,15 +740,15 @@ VM_dprint
 dprint(...[string])
 =========
 */
-void VM_dprint (void)
+void VM_dprint(prvm_prog_t *prog)
 {
        char string[VM_STRINGTEMP_LENGTH];
        VM_SAFEPARMCOUNTRANGE(1, 8, VM_dprint);
-       VM_VarString(0, string, sizeof(string));
+       VM_VarString(prog, 0, string, sizeof(string));
 #if 1
        Con_DPrintf("%s", string);
 #else
-       Con_DPrintf("%s: %s", PRVM_NAME, string);
+       Con_DPrintf("%s: %s", prog->name, string);
 #endif
 }
 
@@ -759,7 +760,7 @@ string      ftos(float)
 =========
 */
 
-void VM_ftos (void)
+void VM_ftos(prvm_prog_t *prog)
 {
        float v;
        char s[128];
@@ -772,7 +773,7 @@ void VM_ftos (void)
                dpsnprintf(s, sizeof(s), "%i", (int)v);
        else
                dpsnprintf(s, sizeof(s), "%f", v);
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(s);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, s);
 }
 
 /*
@@ -783,7 +784,7 @@ float       fabs(float)
 =========
 */
 
-void VM_fabs (void)
+void VM_fabs(prvm_prog_t *prog)
 {
        float   v;
 
@@ -801,14 +802,14 @@ string    vtos(vector)
 =========
 */
 
-void VM_vtos (void)
+void VM_vtos(prvm_prog_t *prog)
 {
        char s[512];
 
        VM_SAFEPARMCOUNT(1,VM_vtos);
 
        dpsnprintf (s, sizeof(s), "'%5.1f %5.1f %5.1f'", PRVM_G_VECTOR(OFS_PARM0)[0], PRVM_G_VECTOR(OFS_PARM0)[1], PRVM_G_VECTOR(OFS_PARM0)[2]);
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(s);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, s);
 }
 
 /*
@@ -819,14 +820,14 @@ string    etos(entity)
 =========
 */
 
-void VM_etos (void)
+void VM_etos(prvm_prog_t *prog)
 {
        char s[128];
 
        VM_SAFEPARMCOUNT(1, VM_etos);
 
        dpsnprintf (s, sizeof(s), "entity %i", PRVM_G_EDICTNUM(OFS_PARM0));
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(s);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, s);
 }
 
 /*
@@ -836,11 +837,11 @@ VM_stof
 float stof(...[string])
 =========
 */
-void VM_stof(void)
+void VM_stof(prvm_prog_t *prog)
 {
        char string[VM_STRINGTEMP_LENGTH];
        VM_SAFEPARMCOUNTRANGE(1, 8, VM_stof);
-       VM_VarString(0, string, sizeof(string));
+       VM_VarString(prog, 0, string, sizeof(string));
        PRVM_G_FLOAT(OFS_RETURN) = atof(string);
 }
 
@@ -851,7 +852,7 @@ VM_itof
 float itof(intt ent)
 ========================
 */
-void VM_itof(void)
+void VM_itof(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_itof);
        PRVM_G_FLOAT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
@@ -864,7 +865,7 @@ VM_ftoe
 entity ftoe(float num)
 ========================
 */
-void VM_ftoe(void)
+void VM_ftoe(prvm_prog_t *prog)
 {
        int ent;
        VM_SAFEPARMCOUNT(1, VM_ftoe);
@@ -883,7 +884,7 @@ VM_etof
 float etof(entity ent)
 ========================
 */
-void VM_etof(void)
+void VM_etof(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_etof);
        PRVM_G_FLOAT(OFS_RETURN) = PRVM_G_EDICTNUM(OFS_PARM0);
@@ -896,7 +897,7 @@ VM_strftime
 string strftime(float uselocaltime, string[, string ...])
 =========
 */
-void VM_strftime(void)
+void VM_strftime(prvm_prog_t *prog)
 {
        time_t t;
 #if _MSC_VER >= 1400
@@ -908,7 +909,7 @@ void VM_strftime(void)
        char fmt[VM_STRINGTEMP_LENGTH];
        char result[VM_STRINGTEMP_LENGTH];
        VM_SAFEPARMCOUNTRANGE(2, 8, VM_strftime);
-       VM_VarString(1, fmt, sizeof(fmt));
+       VM_VarString(prog, 1, fmt, sizeof(fmt));
        t = time(NULL);
 #if _MSC_VER >= 1400
        if (PRVM_G_FLOAT(OFS_PARM0))
@@ -932,7 +933,7 @@ void VM_strftime(void)
 #else
        strftime(result, sizeof(result), fmt, tm);
 #endif
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(result);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, result);
 }
 
 /*
@@ -943,12 +944,12 @@ entity spawn()
 =========
 */
 
-void VM_spawn (void)
+void VM_spawn(prvm_prog_t *prog)
 {
        prvm_edict_t    *ed;
        VM_SAFEPARMCOUNT(0, VM_spawn);
        prog->xfunction->builtinsprofile += 20;
-       ed = PRVM_ED_Alloc();
+       ed = PRVM_ED_Alloc(prog);
        VM_RETURN_EDICT(ed);
 }
 
@@ -960,7 +961,7 @@ remove(entity e)
 =========
 */
 
-void VM_remove (void)
+void VM_remove(prvm_prog_t *prog)
 {
        prvm_edict_t    *ed;
        prog->xfunction->builtinsprofile += 20;
@@ -971,15 +972,15 @@ void VM_remove (void)
        if( PRVM_NUM_FOR_EDICT(ed) <= prog->reserved_edicts )
        {
                if (developer.integer > 0)
-                       VM_Warning( "VM_remove: tried to remove the null entity or a reserved entity!\n" );
+                       VM_Warning(prog, "VM_remove: tried to remove the null entity or a reserved entity!\n" );
        }
        else if( ed->priv.required->free )
        {
                if (developer.integer > 0)
-                       VM_Warning( "VM_remove: tried to remove an already freed entity!\n" );
+                       VM_Warning(prog, "VM_remove: tried to remove an already freed entity!\n" );
        }
        else
-               PRVM_ED_Free (ed);
+               PRVM_ED_Free (prog, ed);
 }
 
 /*
@@ -990,7 +991,7 @@ entity      find(entity start, .string field, string match)
 =========
 */
 
-void VM_find (void)
+void VM_find(prvm_prog_t *prog)
 {
        int             e;
        int             f;
@@ -1035,7 +1036,7 @@ VM_findfloat
 =========
 */
 // LordHavoc: added this for searching float, int, and entity reference fields
-void VM_findfloat (void)
+void VM_findfloat(prvm_prog_t *prog)
 {
        int             e;
        int             f;
@@ -1073,7 +1074,7 @@ entity    findchain(.string field, string match)
 */
 // chained search for strings in entity fields
 // entity(.string field, string match) findchain = #402;
-void VM_findchain (void)
+void VM_findchain(prvm_prog_t *prog)
 {
        int             i;
        int             f;
@@ -1088,7 +1089,7 @@ void VM_findchain (void)
        else
                chainfield = prog->fieldoffsets.chain;
        if (chainfield < 0)
-               PRVM_ERROR("VM_findchain: %s doesnt have the specified chain field !", PRVM_NAME);
+               prog->error_cmd("VM_findchain: %s doesnt have the specified chain field !", prog->name);
 
        chain = prog->edicts;
 
@@ -1128,7 +1129,7 @@ entity    findchainentity(.string field, entity match)
 */
 // LordHavoc: chained search for float, int, and entity reference fields
 // entity(.string field, float match) findchainfloat = #403;
-void VM_findchainfloat (void)
+void VM_findchainfloat(prvm_prog_t *prog)
 {
        int             i;
        int             f;
@@ -1143,7 +1144,7 @@ void VM_findchainfloat (void)
        else
                chainfield = prog->fieldoffsets.chain;
        if (chainfield < 0)
-               PRVM_ERROR("VM_findchain: %s doesnt have the specified chain field !", PRVM_NAME);
+               prog->error_cmd("VM_findchain: %s doesnt have the specified chain field !", prog->name);
 
        chain = (prvm_edict_t *)prog->edicts;
 
@@ -1174,7 +1175,7 @@ entity    findflags(entity start, .float field, float match)
 ========================
 */
 // LordHavoc: search for flags in float fields
-void VM_findflags (void)
+void VM_findflags(prvm_prog_t *prog)
 {
        int             e;
        int             f;
@@ -1214,7 +1215,7 @@ entity    findchainflags(.float field, float match)
 ========================
 */
 // LordHavoc: chained search for flags in float fields
-void VM_findchainflags (void)
+void VM_findchainflags(prvm_prog_t *prog)
 {
        int             i;
        int             f;
@@ -1229,7 +1230,7 @@ void VM_findchainflags (void)
        else
                chainfield = prog->fieldoffsets.chain;
        if (chainfield < 0)
-               PRVM_ERROR("VM_findchain: %s doesnt have the specified chain field !", PRVM_NAME);
+               prog->error_cmd("VM_findchain: %s doesnt have the specified chain field !", prog->name);
 
        chain = (prvm_edict_t *)prog->edicts;
 
@@ -1261,7 +1262,7 @@ VM_precache_sound
 string precache_sound (string sample)
 =========
 */
-void VM_precache_sound (void)
+void VM_precache_sound(prvm_prog_t *prog)
 {
        const char *s;
 
@@ -1269,11 +1270,11 @@ void VM_precache_sound (void)
 
        s = PRVM_G_STRING(OFS_PARM0);
        PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
-       //VM_CheckEmptyString(s);
+       //VM_CheckEmptyString(prog, s);
 
        if(snd_initialized.integer && !S_PrecacheSound(s, true, true))
        {
-               VM_Warning("VM_precache_sound: Failed to load %s for %s\n", s, PRVM_NAME);
+               VM_Warning(prog, "VM_precache_sound: Failed to load %s for %s\n", s, prog->name);
                return;
        }
 }
@@ -1287,7 +1288,7 @@ returns the same string as output
 does nothing, only used by qcc to build .pak archives
 =================
 */
-void VM_precache_file (void)
+void VM_precache_file(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1,VM_precache_file);
        // precache_file is only used to copy files with qcc, it does nothing
@@ -1301,12 +1302,12 @@ VM_coredump
 coredump()
 =========
 */
-void VM_coredump (void)
+void VM_coredump(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0,VM_coredump);
 
        Cbuf_AddText("prvm_edicts ");
-       Cbuf_AddText(PRVM_NAME);
+       Cbuf_AddText(prog->name);
        Cbuf_AddText("\n");
 }
 
@@ -1317,12 +1318,11 @@ VM_stackdump
 stackdump()
 =========
 */
-void PRVM_StackTrace(void);
-void VM_stackdump (void)
+void VM_stackdump(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0, VM_stackdump);
 
-       PRVM_StackTrace();
+       PRVM_StackTrace(prog);
 }
 
 /*
@@ -1333,11 +1333,11 @@ crash()
 =========
 */
 
-void VM_crash(void)
+void VM_crash(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0, VM_crash);
 
-       PRVM_ERROR("Crash called by %s",PRVM_NAME);
+       prog->error_cmd("Crash called by %s",prog->name);
 }
 
 /*
@@ -1347,7 +1347,7 @@ VM_traceon
 traceon()
 =========
 */
-void VM_traceon (void)
+void VM_traceon(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0,VM_traceon);
 
@@ -1361,7 +1361,7 @@ VM_traceoff
 traceoff()
 =========
 */
-void VM_traceoff (void)
+void VM_traceoff(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0,VM_traceoff);
 
@@ -1375,11 +1375,11 @@ VM_eprint
 eprint(entity e)
 =========
 */
-void VM_eprint (void)
+void VM_eprint(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1,VM_eprint);
 
-       PRVM_ED_PrintNum (PRVM_G_EDICTNUM(OFS_PARM0), NULL);
+       PRVM_ED_PrintNum (prog, PRVM_G_EDICTNUM(OFS_PARM0), NULL);
 }
 
 /*
@@ -1389,7 +1389,7 @@ VM_rint
 float  rint(float)
 =========
 */
-void VM_rint (void)
+void VM_rint(prvm_prog_t *prog)
 {
        float f;
        VM_SAFEPARMCOUNT(1,VM_rint);
@@ -1408,7 +1408,7 @@ VM_floor
 float  floor(float)
 =========
 */
-void VM_floor (void)
+void VM_floor(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1,VM_floor);
 
@@ -1422,7 +1422,7 @@ VM_ceil
 float  ceil(float)
 =========
 */
-void VM_ceil (void)
+void VM_ceil(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1,VM_ceil);
 
@@ -1437,7 +1437,7 @@ VM_nextent
 entity nextent(entity)
 =============
 */
-void VM_nextent (void)
+void VM_nextent(prvm_prog_t *prog)
 {
        int             i;
        prvm_edict_t    *ent;
@@ -1473,13 +1473,14 @@ server and menu
 changelevel(string map)
 ==============
 */
-void VM_changelevel (void)
+void VM_changelevel(prvm_prog_t *prog)
 {
+       char vabuf[1024];
        VM_SAFEPARMCOUNT(1, VM_changelevel);
 
        if(!sv.active)
        {
-               VM_Warning("VM_changelevel: game is not server (%s)\n", PRVM_NAME);
+               VM_Warning(prog, "VM_changelevel: game is not server (%s)\n", prog->name);
                return;
        }
 
@@ -1488,7 +1489,7 @@ void VM_changelevel (void)
                return;
        svs.changelevel_issued = true;
 
-       Cbuf_AddText (va("changelevel %s\n",PRVM_G_STRING(OFS_PARM0)));
+       Cbuf_AddText(va(vabuf, sizeof(vabuf), "changelevel %s\n",PRVM_G_STRING(OFS_PARM0)));
 }
 
 /*
@@ -1498,7 +1499,7 @@ VM_sin
 float  sin(float)
 =========
 */
-void VM_sin (void)
+void VM_sin(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1,VM_sin);
        PRVM_G_FLOAT(OFS_RETURN) = sin(PRVM_G_FLOAT(OFS_PARM0));
@@ -1510,7 +1511,7 @@ VM_cos
 float  cos(float)
 =========
 */
-void VM_cos (void)
+void VM_cos(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1,VM_cos);
        PRVM_G_FLOAT(OFS_RETURN) = cos(PRVM_G_FLOAT(OFS_PARM0));
@@ -1523,7 +1524,7 @@ VM_sqrt
 float  sqrt(float)
 =========
 */
-void VM_sqrt (void)
+void VM_sqrt(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1,VM_sqrt);
        PRVM_G_FLOAT(OFS_RETURN) = sqrt(PRVM_G_FLOAT(OFS_PARM0));
@@ -1536,7 +1537,7 @@ VM_asin
 float  asin(float)
 =========
 */
-void VM_asin (void)
+void VM_asin(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1,VM_asin);
        PRVM_G_FLOAT(OFS_RETURN) = asin(PRVM_G_FLOAT(OFS_PARM0));
@@ -1548,7 +1549,7 @@ VM_acos
 float  acos(float)
 =========
 */
-void VM_acos (void)
+void VM_acos(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1,VM_acos);
        PRVM_G_FLOAT(OFS_RETURN) = acos(PRVM_G_FLOAT(OFS_PARM0));
@@ -1560,7 +1561,7 @@ VM_atan
 float  atan(float)
 =========
 */
-void VM_atan (void)
+void VM_atan(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1,VM_atan);
        PRVM_G_FLOAT(OFS_RETURN) = atan(PRVM_G_FLOAT(OFS_PARM0));
@@ -1572,7 +1573,7 @@ VM_atan2
 float  atan2(float,float)
 =========
 */
-void VM_atan2 (void)
+void VM_atan2(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(2,VM_atan2);
        PRVM_G_FLOAT(OFS_RETURN) = atan2(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
@@ -1584,7 +1585,7 @@ VM_tan
 float  tan(float)
 =========
 */
-void VM_tan (void)
+void VM_tan(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1,VM_tan);
        PRVM_G_FLOAT(OFS_RETURN) = tan(PRVM_G_FLOAT(OFS_PARM0));
@@ -1599,31 +1600,12 @@ Returns a vector of length < 1 and > 0
 vector randomvec()
 =================
 */
-void VM_randomvec (void)
+void VM_randomvec(prvm_prog_t *prog)
 {
-       vec3_t          temp;
-       //float         length;
-
+       vec3_t temp;
        VM_SAFEPARMCOUNT(0, VM_randomvec);
-
-       //// WTF ??
-       do
-       {
-               temp[0] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
-               temp[1] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
-               temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
-       }
-       while (DotProduct(temp, temp) >= 1);
-       VectorCopy (temp, PRVM_G_VECTOR(OFS_RETURN));
-
-       /*
-       temp[0] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
-       temp[1] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
-       temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
-       // length returned always > 0
-       length = (rand()&32766 + 1) * (1.0 / 32767.0) / VectorLength(temp);
-       VectorScale(temp,length, temp);*/
-       //VectorCopy(temp, PRVM_G_VECTOR(OFS_RETURN));
+       VectorRandom(temp);
+       VectorCopy(temp, PRVM_G_VECTOR(OFS_RETURN));
 }
 
 //=============================================================================
@@ -1635,7 +1617,7 @@ VM_registercvar
 float  registercvar (string name, string value[, float flags])
 =========
 */
-void VM_registercvar (void)
+void VM_registercvar(prvm_prog_t *prog)
 {
        const char *name, *value;
        int     flags;
@@ -1657,7 +1639,7 @@ void VM_registercvar (void)
 // check for overlap with a command
        if (Cmd_Exists (name))
        {
-               VM_Warning("VM_registercvar: %s is a command\n", name);
+               VM_Warning(prog, "VM_registercvar: %s is a command\n", name);
                return;
        }
 
@@ -1676,7 +1658,7 @@ returns the minimum of two supplied floats
 float min(float a, float b, ...[float])
 =================
 */
-void VM_min (void)
+void VM_min(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNTRANGE(2, 8, VM_min);
        // LordHavoc: 3+ argument enhancement suggested by FrikaC
@@ -1702,7 +1684,7 @@ returns the maximum of two supplied floats
 float  max(float a, float b, ...[float])
 =================
 */
-void VM_max (void)
+void VM_max(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNTRANGE(2, 8, VM_max);
        // LordHavoc: 3+ argument enhancement suggested by FrikaC
@@ -1728,7 +1710,7 @@ returns number bounded by supplied range
 float  bound(float min, float value, float max)
 =================
 */
-void VM_bound (void)
+void VM_bound(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(3,VM_bound);
        PRVM_G_FLOAT(OFS_RETURN) = bound(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1), PRVM_G_FLOAT(OFS_PARM2));
@@ -1743,26 +1725,26 @@ returns a raised to power b
 float  pow(float a, float b)
 =================
 */
-void VM_pow (void)
+void VM_pow(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(2,VM_pow);
        PRVM_G_FLOAT(OFS_RETURN) = pow(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
 }
 
-void VM_log (void)
+void VM_log(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1,VM_log);
        PRVM_G_FLOAT(OFS_RETURN) = log(PRVM_G_FLOAT(OFS_PARM0));
 }
 
-void VM_Files_Init(void)
+void VM_Files_Init(prvm_prog_t *prog)
 {
        int i;
        for (i = 0;i < PRVM_MAX_OPENFILES;i++)
                prog->openfiles[i] = NULL;
 }
 
-void VM_Files_CloseAll(void)
+void VM_Files_CloseAll(prvm_prog_t *prog)
 {
        int i;
        for (i = 0;i < PRVM_MAX_OPENFILES;i++)
@@ -1773,16 +1755,16 @@ void VM_Files_CloseAll(void)
        }
 }
 
-static qfile_t *VM_GetFileHandle( int index )
+static qfile_t *VM_GetFileHandle(prvm_prog_t *prog, int index)
 {
        if (index < 0 || index >= PRVM_MAX_OPENFILES)
        {
-               Con_Printf("VM_GetFileHandle: invalid file handle %i used in %s\n", index, PRVM_NAME);
+               Con_Printf("VM_GetFileHandle: invalid file handle %i used in %s\n", index, prog->name);
                return NULL;
        }
        if (prog->openfiles[index] == NULL)
        {
-               Con_Printf("VM_GetFileHandle: no such file handle %i (or file has been closed) in %s\n", index, PRVM_NAME);
+               Con_Printf("VM_GetFileHandle: no such file handle %i (or file has been closed) in %s\n", index, prog->name);
                return NULL;
        }
        return prog->openfiles[index];
@@ -1798,10 +1780,11 @@ float   fopen(string filename, float mode)
 // float(string filename, float mode) fopen = #110;
 // opens a file inside quake/gamedir/data/ (mode is FILE_READ, FILE_APPEND, or FILE_WRITE),
 // returns fhandle >= 0 if successful, or fhandle < 0 if unable to open file for any reason
-void VM_fopen(void)
+void VM_fopen(prvm_prog_t *prog)
 {
        int filenum, mode;
        const char *modestring, *filename;
+       char vabuf[1024];
 
        VM_SAFEPARMCOUNT(2,VM_fopen);
 
@@ -1811,7 +1794,7 @@ void VM_fopen(void)
        if (filenum >= PRVM_MAX_OPENFILES)
        {
                PRVM_G_FLOAT(OFS_RETURN) = -2;
-               VM_Warning("VM_fopen: %s ran out of file handles (%i)\n", PRVM_NAME, PRVM_MAX_OPENFILES);
+               VM_Warning(prog, "VM_fopen: %s ran out of file handles (%i)\n", prog->name, PRVM_MAX_OPENFILES);
                return;
        }
        filename = PRVM_G_STRING(OFS_PARM0);
@@ -1820,21 +1803,21 @@ void VM_fopen(void)
        {
        case 0: // FILE_READ
                modestring = "rb";
-               prog->openfiles[filenum] = FS_OpenVirtualFile(va("data/%s", filename), false);
+               prog->openfiles[filenum] = FS_OpenVirtualFile(va(vabuf, sizeof(vabuf), "data/%s", filename), false);
                if (prog->openfiles[filenum] == NULL)
-                       prog->openfiles[filenum] = FS_OpenVirtualFile(va("%s", filename), false);
+                       prog->openfiles[filenum] = FS_OpenVirtualFile(va(vabuf, sizeof(vabuf), "%s", filename), false);
                break;
        case 1: // FILE_APPEND
                modestring = "a";
-               prog->openfiles[filenum] = FS_OpenRealFile(va("data/%s", filename), modestring, false);
+               prog->openfiles[filenum] = FS_OpenRealFile(va(vabuf, sizeof(vabuf), "data/%s", filename), modestring, false);
                break;
        case 2: // FILE_WRITE
                modestring = "w";
-               prog->openfiles[filenum] = FS_OpenRealFile(va("data/%s", filename), modestring, false);
+               prog->openfiles[filenum] = FS_OpenRealFile(va(vabuf, sizeof(vabuf), "data/%s", filename), modestring, false);
                break;
        default:
                PRVM_G_FLOAT(OFS_RETURN) = -3;
-               VM_Warning("VM_fopen: %s: no such mode %i (valid: 0 = read, 1 = append, 2 = write)\n", PRVM_NAME, mode);
+               VM_Warning(prog, "VM_fopen: %s: no such mode %i (valid: 0 = read, 1 = append, 2 = write)\n", prog->name, mode);
                return;
        }
 
@@ -1842,14 +1825,14 @@ void VM_fopen(void)
        {
                PRVM_G_FLOAT(OFS_RETURN) = -1;
                if (developer_extra.integer)
-                       VM_Warning("VM_fopen: %s: %s mode %s failed\n", PRVM_NAME, filename, modestring);
+                       VM_Warning(prog, "VM_fopen: %s: %s mode %s failed\n", prog->name, filename, modestring);
        }
        else
        {
                PRVM_G_FLOAT(OFS_RETURN) = filenum;
                if (developer_extra.integer)
-                       Con_DPrintf("VM_fopen: %s: %s mode %s opened as #%i\n", PRVM_NAME, filename, modestring, filenum);
-               prog->openfiles_origin[filenum] = PRVM_AllocationOrigin();
+                       Con_DPrintf("VM_fopen: %s: %s mode %s opened as #%i\n", prog->name, filename, modestring, filenum);
+               prog->openfiles_origin[filenum] = PRVM_AllocationOrigin(prog);
        }
 }
 
@@ -1861,7 +1844,7 @@ fclose(float fhandle)
 =========
 */
 //void(float fhandle) fclose = #111; // closes a file
-void VM_fclose(void)
+void VM_fclose(prvm_prog_t *prog)
 {
        int filenum;
 
@@ -1870,12 +1853,12 @@ void VM_fclose(void)
        filenum = (int)PRVM_G_FLOAT(OFS_PARM0);
        if (filenum < 0 || filenum >= PRVM_MAX_OPENFILES)
        {
-               VM_Warning("VM_fclose: invalid file handle %i used in %s\n", filenum, PRVM_NAME);
+               VM_Warning(prog, "VM_fclose: invalid file handle %i used in %s\n", filenum, prog->name);
                return;
        }
        if (prog->openfiles[filenum] == NULL)
        {
-               VM_Warning("VM_fclose: no such file handle %i (or file has been closed) in %s\n", filenum, PRVM_NAME);
+               VM_Warning(prog, "VM_fclose: no such file handle %i (or file has been closed) in %s\n", filenum, prog->name);
                return;
        }
        FS_Close(prog->openfiles[filenum]);
@@ -1883,7 +1866,7 @@ void VM_fclose(void)
        if(prog->openfiles_origin[filenum])
                PRVM_Free((char *)prog->openfiles_origin[filenum]);
        if (developer_extra.integer)
-               Con_DPrintf("VM_fclose: %s: #%i closed\n", PRVM_NAME, filenum);
+               Con_DPrintf("VM_fclose: %s: #%i closed\n", prog->name, filenum);
 }
 
 /*
@@ -1894,7 +1877,7 @@ string    fgets(float fhandle)
 =========
 */
 //string(float fhandle) fgets = #112; // reads a line of text from the file and returns as a tempstring
-void VM_fgets(void)
+void VM_fgets(prvm_prog_t *prog)
 {
        int c, end;
        char string[VM_STRINGTEMP_LENGTH];
@@ -1908,12 +1891,12 @@ void VM_fgets(void)
        filenum = (int)PRVM_G_FLOAT(OFS_PARM0);
        if (filenum < 0 || filenum >= PRVM_MAX_OPENFILES)
        {
-               VM_Warning("VM_fgets: invalid file handle %i used in %s\n", filenum, PRVM_NAME);
+               VM_Warning(prog, "VM_fgets: invalid file handle %i used in %s\n", filenum, prog->name);
                return;
        }
        if (prog->openfiles[filenum] == NULL)
        {
-               VM_Warning("VM_fgets: no such file handle %i (or file has been closed) in %s\n", filenum, PRVM_NAME);
+               VM_Warning(prog, "VM_fgets: no such file handle %i (or file has been closed) in %s\n", filenum, prog->name);
                return;
        }
        end = 0;
@@ -1934,9 +1917,9 @@ void VM_fgets(void)
                        FS_UnGetc(prog->openfiles[filenum], (unsigned char)c);
        }
        if (developer_extra.integer)
-               Con_DPrintf("fgets: %s: %s\n", PRVM_NAME, string);
+               Con_DPrintf("fgets: %s: %s\n", prog->name, string);
        if (c >= 0 || end)
-               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
+               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, string);
 }
 
 /*
@@ -1947,7 +1930,7 @@ fputs(float fhandle, string s)
 =========
 */
 //void(float fhandle, string s) fputs = #113; // writes a line of text to the end of the file
-void VM_fputs(void)
+void VM_fputs(prvm_prog_t *prog)
 {
        int stringlength;
        char string[VM_STRINGTEMP_LENGTH];
@@ -1958,19 +1941,19 @@ void VM_fputs(void)
        filenum = (int)PRVM_G_FLOAT(OFS_PARM0);
        if (filenum < 0 || filenum >= PRVM_MAX_OPENFILES)
        {
-               VM_Warning("VM_fputs: invalid file handle %i used in %s\n", filenum, PRVM_NAME);
+               VM_Warning(prog, "VM_fputs: invalid file handle %i used in %s\n", filenum, prog->name);
                return;
        }
        if (prog->openfiles[filenum] == NULL)
        {
-               VM_Warning("VM_fputs: no such file handle %i (or file has been closed) in %s\n", filenum, PRVM_NAME);
+               VM_Warning(prog, "VM_fputs: no such file handle %i (or file has been closed) in %s\n", filenum, prog->name);
                return;
        }
-       VM_VarString(1, string, sizeof(string));
+       VM_VarString(prog, 1, string, sizeof(string));
        if ((stringlength = (int)strlen(string)))
                FS_Write(prog->openfiles[filenum], string, stringlength);
        if (developer_extra.integer)
-               Con_DPrintf("fputs: %s: %s\n", PRVM_NAME, string);
+               Con_DPrintf("fputs: %s: %s\n", prog->name, string);
 }
 
 /*
@@ -1980,28 +1963,28 @@ VM_writetofile
        writetofile(float fhandle, entity ent)
 =========
 */
-void VM_writetofile(void)
+void VM_writetofile(prvm_prog_t *prog)
 {
        prvm_edict_t * ent;
        qfile_t *file;
 
        VM_SAFEPARMCOUNT(2, VM_writetofile);
 
-       file = VM_GetFileHandle( (int)PRVM_G_FLOAT(OFS_PARM0) );
+       file = VM_GetFileHandle(prog, (int)PRVM_G_FLOAT(OFS_PARM0));
        if( !file )
        {
-               VM_Warning("VM_writetofile: invalid or closed file handle\n");
+               VM_Warning(prog, "VM_writetofile: invalid or closed file handle\n");
                return;
        }
 
        ent = PRVM_G_EDICT(OFS_PARM1);
        if(ent->priv.required->free)
        {
-               VM_Warning("VM_writetofile: %s: entity %i is free !\n", PRVM_NAME, PRVM_NUM_FOR_EDICT(ent));
+               VM_Warning(prog, "VM_writetofile: %s: entity %i is free !\n", prog->name, PRVM_NUM_FOR_EDICT(ent));
                return;
        }
 
-       PRVM_ED_Write (file, ent);
+       PRVM_ED_Write (prog, file, ent);
 }
 
 // KrimZon - DP_QC_ENTITYDATA
@@ -2013,7 +1996,7 @@ float() numentityfields
 Return the number of entity fields - NOT offsets
 =========
 */
-void VM_numentityfields(void)
+void VM_numentityfields(prvm_prog_t *prog)
 {
        PRVM_G_FLOAT(OFS_RETURN) = prog->numfielddefs;
 }
@@ -2027,15 +2010,15 @@ string(float fieldnum) entityfieldname
 Return name of the specified field as a string, or empty if the field is invalid (warning)
 =========
 */
-void VM_entityfieldname(void)
+void VM_entityfieldname(prvm_prog_t *prog)
 {
        ddef_t *d;
        int i = (int)PRVM_G_FLOAT(OFS_PARM0);
        
        if (i < 0 || i >= prog->numfielddefs)
        {
-        VM_Warning("VM_entityfieldname: %s: field index out of bounds\n", PRVM_NAME);
-        PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString("");
+        VM_Warning(prog, "VM_entityfieldname: %s: field index out of bounds\n", prog->name);
+        PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, "");
                return;
        }
        
@@ -2051,14 +2034,14 @@ VM_entityfieldtype
 float(float fieldnum) entityfieldtype
 =========
 */
-void VM_entityfieldtype(void)
+void VM_entityfieldtype(prvm_prog_t *prog)
 {
        ddef_t *d;
        int i = (int)PRVM_G_FLOAT(OFS_PARM0);
        
        if (i < 0 || i >= prog->numfielddefs)
        {
-               VM_Warning("VM_entityfieldtype: %s: field index out of bounds\n", PRVM_NAME);
+               VM_Warning(prog, "VM_entityfieldtype: %s: field index out of bounds\n", prog->name);
                PRVM_G_FLOAT(OFS_RETURN) = -1.0;
                return;
        }
@@ -2075,7 +2058,7 @@ VM_getentityfieldstring
 string(float fieldnum, entity ent) getentityfieldstring
 =========
 */
-void VM_getentityfieldstring(void)
+void VM_getentityfieldstring(prvm_prog_t *prog)
 {
        // put the data into a string
        ddef_t *d;
@@ -2083,11 +2066,12 @@ void VM_getentityfieldstring(void)
        int *v;
        prvm_edict_t * ent;
        int i = (int)PRVM_G_FLOAT(OFS_PARM0);
+       char valuebuf[MAX_INPUTLINE];
        
        if (i < 0 || i >= prog->numfielddefs)
        {
-        VM_Warning("VM_entityfielddata: %s: field index out of bounds\n", PRVM_NAME);
-               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString("");
+        VM_Warning(prog, "VM_entityfielddata: %s: field index out of bounds\n", prog->name);
+               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, "");
                return;
        }
        
@@ -2097,8 +2081,8 @@ void VM_getentityfieldstring(void)
        ent = PRVM_G_EDICT(OFS_PARM1);
        if(ent->priv.required->free)
        {
-               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString("");
-               VM_Warning("VM_entityfielddata: %s: entity %i is free !\n", PRVM_NAME, PRVM_NUM_FOR_EDICT(ent));
+               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, "");
+               VM_Warning(prog, "VM_entityfielddata: %s: entity %i is free !\n", prog->name, PRVM_NUM_FOR_EDICT(ent));
                return;
        }
        v = (int *)((char *)ent->fields.vp + d->ofs*4);
@@ -2110,11 +2094,11 @@ void VM_getentityfieldstring(void)
                        break;
        if (j == prvm_type_size[type])
        {
-               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString("");
+               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, "");
                return;
        }
                
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(PRVM_UglyValueString((etype_t)d->type, (prvm_eval_t *)v));
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, PRVM_UglyValueString(prog, (etype_t)d->type, (prvm_eval_t *)v, valuebuf, sizeof(valuebuf)));
 }
 
 // KrimZon - DP_QC_ENTITYDATA
@@ -2125,7 +2109,7 @@ VM_putentityfieldstring
 float(float fieldnum, entity ent, string s) putentityfieldstring
 =========
 */
-void VM_putentityfieldstring(void)
+void VM_putentityfieldstring(prvm_prog_t *prog)
 {
        ddef_t *d;
        prvm_edict_t * ent;
@@ -2133,7 +2117,7 @@ void VM_putentityfieldstring(void)
 
        if (i < 0 || i >= prog->numfielddefs)
        {
-        VM_Warning("VM_entityfielddata: %s: field index out of bounds\n", PRVM_NAME);
+        VM_Warning(prog, "VM_entityfielddata: %s: field index out of bounds\n", prog->name);
                PRVM_G_FLOAT(OFS_RETURN) = 0.0f;
                return;
        }
@@ -2144,13 +2128,13 @@ void VM_putentityfieldstring(void)
        ent = PRVM_G_EDICT(OFS_PARM1);
        if(ent->priv.required->free)
        {
-               VM_Warning("VM_entityfielddata: %s: entity %i is free !\n", PRVM_NAME, PRVM_NUM_FOR_EDICT(ent));
+               VM_Warning(prog, "VM_entityfielddata: %s: entity %i is free !\n", prog->name, PRVM_NUM_FOR_EDICT(ent));
                PRVM_G_FLOAT(OFS_RETURN) = 0.0f;
                return;
        }
 
        // parse the string into the value
-       PRVM_G_FLOAT(OFS_RETURN) = ( PRVM_ED_ParseEpair(ent, d, PRVM_G_STRING(OFS_PARM2), false) ) ? 1.0f : 0.0f;
+       PRVM_G_FLOAT(OFS_RETURN) = ( PRVM_ED_ParseEpair(prog, ent, d, PRVM_G_STRING(OFS_PARM2), false) ) ? 1.0f : 0.0f;
 }
 
 /*
@@ -2161,7 +2145,7 @@ float     strlen(string s)
 =========
 */
 //float(string s) strlen = #114; // returns how many characters are in a string
-void VM_strlen(void)
+void VM_strlen(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1,VM_strlen);
 
@@ -2178,7 +2162,7 @@ string    strdecolorize(string s)
 =========
 */
 // string (string s) strdecolorize = #472; // returns the passed in string with color codes stripped
-void VM_strdecolorize(void)
+void VM_strdecolorize(prvm_prog_t *prog)
 {
        char szNewString[VM_STRINGTEMP_LENGTH];
        const char *szString;
@@ -2187,7 +2171,7 @@ void VM_strdecolorize(void)
        VM_SAFEPARMCOUNT(1,VM_strdecolorize);
        szString = PRVM_G_STRING(OFS_PARM0);
        COM_StringDecolorize(szString, 0, szNewString, sizeof(szNewString), TRUE);
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(szNewString);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, szNewString);
 }
 
 // DRESK - String Length (not counting color codes)
@@ -2200,7 +2184,7 @@ float     strlennocol(string s)
 */
 // float(string s) strlennocol = #471; // returns how many characters are in a string not including color codes
 // For example, ^2Dresk returns a length of 5
-void VM_strlennocol(void)
+void VM_strlennocol(prvm_prog_t *prog)
 {
        const char *szString;
        int nCnt;
@@ -2224,7 +2208,7 @@ string    strtolower(string s)
 =========
 */
 // string (string s) strtolower = #480; // returns passed in string in lowercase form
-void VM_strtolower(void)
+void VM_strtolower(prvm_prog_t *prog)
 {
        char szNewString[VM_STRINGTEMP_LENGTH];
        const char *szString;
@@ -2235,7 +2219,7 @@ void VM_strtolower(void)
 
        COM_ToLowerString(szString, szNewString, sizeof(szNewString) );
 
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(szNewString);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, szNewString);
 }
 
 /*
@@ -2246,7 +2230,7 @@ string    strtoupper(string s)
 =========
 */
 // string (string s) strtoupper = #481; // returns passed in string in uppercase form
-void VM_strtoupper(void)
+void VM_strtoupper(prvm_prog_t *prog)
 {
        char szNewString[VM_STRINGTEMP_LENGTH];
        const char *szString;
@@ -2257,7 +2241,7 @@ void VM_strtoupper(void)
 
        COM_ToUpperString(szString, szNewString, sizeof(szNewString) );
 
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(szNewString);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, szNewString);
 }
 
 /*
@@ -2270,13 +2254,13 @@ string strcat(string,string,...[string])
 //string(string s1, string s2) strcat = #115;
 // concatenates two strings (for example "abc", "def" would return "abcdef")
 // and returns as a tempstring
-void VM_strcat(void)
+void VM_strcat(prvm_prog_t *prog)
 {
        char s[VM_STRINGTEMP_LENGTH];
        VM_SAFEPARMCOUNTRANGE(1, 8, VM_strcat);
 
-       VM_VarString(0, s, sizeof(s));
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(s);
+       VM_VarString(prog, 0, s, sizeof(s));
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, s);
 }
 
 /*
@@ -2288,7 +2272,7 @@ string    substring(string s, float start, float length)
 */
 // string(string s, float start, float length) substring = #116;
 // returns a section of a string as a tempstring
-void VM_substring(void)
+void VM_substring(prvm_prog_t *prog)
 {
        int start, length;
        int u_slength = 0, u_start;
@@ -2315,7 +2299,7 @@ void VM_substring(void)
 
        memcpy(string, s + start, length);
        string[length] = 0;
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, string);
        */
        
        s = PRVM_G_STRING(OFS_PARM0);
@@ -2340,7 +2324,7 @@ void VM_substring(void)
        u_start = u8_byteofs(s, start, NULL);
        if (u_start < 0)
        {
-               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString("");
+               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, "");
                return;
        }
        u_length = u8_bytelen(s + u_start, length);
@@ -2349,7 +2333,7 @@ void VM_substring(void)
        
        memcpy(string, s + u_start, u_length);
        string[u_length] = 0;
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, string);
 }
 
 /*
@@ -2360,7 +2344,7 @@ string(string search, string replace, string subject) strreplace = #484;
 =========
 */
 // replaces all occurrences of search with replace in the string subject, and returns the result
-void VM_strreplace(void)
+void VM_strreplace(prvm_prog_t *prog)
 {
        int i, j, si;
        const char *search, *replace, *subject;
@@ -2416,7 +2400,7 @@ void VM_strreplace(void)
                        string[si++] = subject[i];
        string[si] = '\0';
 
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, string);
 }
 
 /*
@@ -2427,7 +2411,7 @@ string(string search, string replace, string subject) strireplace = #485;
 =========
 */
 // case-insensitive version of strreplace
-void VM_strireplace(void)
+void VM_strireplace(prvm_prog_t *prog)
 {
        int i, j, si;
        const char *search, *replace, *subject;
@@ -2483,7 +2467,7 @@ void VM_strireplace(void)
                        string[si++] = subject[i];
        string[si] = '\0';
 
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, string);
 }
 
 /*
@@ -2494,13 +2478,13 @@ vector  stov(string s)
 =========
 */
 //vector(string s) stov = #117; // returns vector value from a string
-void VM_stov(void)
+void VM_stov(prvm_prog_t *prog)
 {
        char string[VM_STRINGTEMP_LENGTH];
 
        VM_SAFEPARMCOUNT(1,VM_stov);
 
-       VM_VarString(0, string, sizeof(string));
+       VM_VarString(prog, 0, string, sizeof(string));
        Math_atov(string, PRVM_G_VECTOR(OFS_RETURN));
 }
 
@@ -2512,7 +2496,7 @@ string    strzone(string s)
 =========
 */
 //string(string s, ...) strzone = #118; // makes a copy of a string into the string zone and returns it, this is often used to keep around a tempstring for longer periods of time (tempstrings are replaced often)
-void VM_strzone(void)
+void VM_strzone(prvm_prog_t *prog)
 {
        char *out;
        char string[VM_STRINGTEMP_LENGTH];
@@ -2520,9 +2504,9 @@ void VM_strzone(void)
 
        VM_SAFEPARMCOUNT(1,VM_strzone);
 
-       VM_VarString(0, string, sizeof(string));
+       VM_VarString(prog, 0, string, sizeof(string));
        alloclen = strlen(string) + 1;
-       PRVM_G_INT(OFS_RETURN) = PRVM_AllocString(alloclen, &out);
+       PRVM_G_INT(OFS_RETURN) = PRVM_AllocString(prog, alloclen, &out);
        memcpy(out, string, alloclen);
 }
 
@@ -2534,10 +2518,10 @@ strunzone(string s)
 =========
 */
 //void(string s) strunzone = #119; // removes a copy of a string from the string zone (you can not use that string again or it may crash!!!)
-void VM_strunzone(void)
+void VM_strunzone(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1,VM_strunzone);
-       PRVM_FreeString(PRVM_G_INT(OFS_PARM0));
+       PRVM_FreeString(prog, PRVM_G_INT(OFS_PARM0));
 }
 
 /*
@@ -2549,7 +2533,7 @@ clientcommand(float client, string s) (for client and menu)
 */
 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
 //this function originally written by KrimZon, made shorter by LordHavoc
-void VM_clcommand (void)
+void VM_clcommand (prvm_prog_t *prog)
 {
        client_t *temp_client;
        int i;
@@ -2559,7 +2543,7 @@ void VM_clcommand (void)
        i = (int)PRVM_G_FLOAT(OFS_PARM0);
        if (!sv.active  || i < 0 || i >= svs.maxclients || !svs.clients[i].active)
        {
-               VM_Warning("VM_clientcommand: %s: invalid client/server is not active !\n", PRVM_NAME);
+               VM_Warning(prog, "VM_clientcommand: %s: invalid client/server is not active !\n", prog->name);
                return;
        }
 
@@ -2585,7 +2569,7 @@ static int tokens[VM_STRINGTEMP_LENGTH / 2];
 static int tokens_startpos[VM_STRINGTEMP_LENGTH / 2];
 static int tokens_endpos[VM_STRINGTEMP_LENGTH / 2];
 static char tokenize_string[VM_STRINGTEMP_LENGTH];
-void VM_tokenize (void)
+void VM_tokenize (prvm_prog_t *prog)
 {
        const char *p;
 
@@ -2608,7 +2592,7 @@ void VM_tokenize (void)
                if(!COM_ParseToken_VM_Tokenize(&p, false))
                        break;
                tokens_endpos[num_tokens] = p - tokenize_string;
-               tokens[num_tokens] = PRVM_SetTempString(com_token);
+               tokens[num_tokens] = PRVM_SetTempString(prog, com_token);
                ++num_tokens;
        }
 
@@ -2616,7 +2600,7 @@ void VM_tokenize (void)
 }
 
 //float(string s) tokenize = #514; // takes apart a string into individal words (access them with argv), returns how many
-void VM_tokenize_console (void)
+void VM_tokenize_console (prvm_prog_t *prog)
 {
        const char *p;
 
@@ -2639,7 +2623,7 @@ void VM_tokenize_console (void)
                if(!COM_ParseToken_Console(&p))
                        break;
                tokens_endpos[num_tokens] = p - tokenize_string;
-               tokens[num_tokens] = PRVM_SetTempString(com_token);
+               tokens[num_tokens] = PRVM_SetTempString(prog, com_token);
                ++num_tokens;
        }
 
@@ -2660,7 +2644,7 @@ float tokenizebyseparator(string s, string separator1, ...)
 //example:
 //numnumbers = tokenizebyseparator("10.1.2.3", ".");
 //returns 4 and the tokens "10" "1" "2" "3".
-void VM_tokenizebyseparator (void)
+void VM_tokenizebyseparator (prvm_prog_t *prog)
 {
        int j, k;
        int numseparators;
@@ -2716,7 +2700,7 @@ void VM_tokenizebyseparator (void)
                if (j >= (int)sizeof(tokentext))
                        break;
                tokentext[j++] = 0;
-               tokens[num_tokens++] = PRVM_SetTempString(token);
+               tokens[num_tokens++] = PRVM_SetTempString(prog, token);
                if (!*p)
                        break;
        }
@@ -2726,7 +2710,7 @@ void VM_tokenizebyseparator (void)
 
 //string(float n) argv = #442; // returns a word from the tokenized string (returns nothing for an invalid index)
 //this function originally written by KrimZon, made shorter by LordHavoc
-void VM_argv (void)
+void VM_argv (prvm_prog_t *prog)
 {
        int token_num;
 
@@ -2744,7 +2728,7 @@ void VM_argv (void)
 }
 
 //float(float n) argv_start_index = #515; // returns the start index of a token
-void VM_argv_start_index (void)
+void VM_argv_start_index (prvm_prog_t *prog)
 {
        int token_num;
 
@@ -2762,7 +2746,7 @@ void VM_argv_start_index (void)
 }
 
 //float(float n) argv_end_index = #516; // returns the end index of a token
-void VM_argv_end_index (void)
+void VM_argv_end_index (prvm_prog_t *prog)
 {
        int token_num;
 
@@ -2786,7 +2770,7 @@ VM_isserver
 float  isserver()
 =========
 */
-void VM_isserver(void)
+void VM_isserver(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0,VM_serverstate);
 
@@ -2800,7 +2784,7 @@ VM_clientcount
 float  clientcount()
 =========
 */
-void VM_clientcount(void)
+void VM_clientcount(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0,VM_clientcount);
 
@@ -2814,7 +2798,7 @@ VM_clientstate
 float  clientstate()
 =========
 */
-void VM_clientstate(void)
+void VM_clientstate(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0,VM_clientstate);
 
@@ -2840,10 +2824,10 @@ void VM_clientstate(void)
 =========
 VM_getostype
 
-float  getostype(void)
+float  getostype(prvm_prog_t *prog)
 =========
 */ // not used at the moment -> not included in the common list
-void VM_getostype(void)
+void VM_getostype(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0,VM_getostype);
 
@@ -2866,12 +2850,11 @@ void VM_getostype(void)
 =========
 VM_gettime
 
-float  gettime(void)
+float  gettime(prvm_prog_t *prog)
 =========
 */
-extern double host_starttime;
 float CDAudio_GetPosition(void);
-void VM_gettime(void)
+void VM_gettime(prvm_prog_t *prog)
 {
        int timer_index;
 
@@ -2884,26 +2867,26 @@ void VM_gettime(void)
        else
        {
                timer_index = (int) PRVM_G_FLOAT(OFS_PARM0);
-        switch(timer_index)
-        {
-            case 0: // GETTIME_FRAMESTART
-                PRVM_G_FLOAT(OFS_RETURN) = (float) realtime;
-                break;
-            case 1: // GETTIME_REALTIME
-                PRVM_G_FLOAT(OFS_RETURN) = (float) Sys_DoubleTime();
-                break;
-            case 2: // GETTIME_HIRES
-                PRVM_G_FLOAT(OFS_RETURN) = (float) (Sys_DoubleTime() - realtime);
-                break;
-            case 3: // GETTIME_UPTIME
-                PRVM_G_FLOAT(OFS_RETURN) = (float) (Sys_DoubleTime() - host_starttime);
-                break;
-            case 4: // GETTIME_CDTRACK
-                PRVM_G_FLOAT(OFS_RETURN) = (float) CDAudio_GetPosition();
-                break;
+               switch(timer_index)
+               {
+                       case 0: // GETTIME_FRAMESTART
+                               PRVM_G_FLOAT(OFS_RETURN) = realtime;
+                               break;
+                       case 1: // GETTIME_REALTIME
+                               PRVM_G_FLOAT(OFS_RETURN) = Sys_DirtyTime();
+                               break;
+                       case 2: // GETTIME_HIRES
+                               PRVM_G_FLOAT(OFS_RETURN) = (Sys_DirtyTime() - host_dirtytime);
+                               break;
+                       case 3: // GETTIME_UPTIME
+                               PRVM_G_FLOAT(OFS_RETURN) = realtime;
+                               break;
+                       case 4: // GETTIME_CDTRACK
+                               PRVM_G_FLOAT(OFS_RETURN) = CDAudio_GetPosition();
+                               break;
                        default:
-                               VM_Warning("VM_gettime: %s: unsupported timer specified, returning realtime\n", PRVM_NAME);
-                               PRVM_G_FLOAT(OFS_RETURN) = (float) realtime;
+                               VM_Warning(prog, "VM_gettime: %s: unsupported timer specified, returning realtime\n", prog->name);
+                               PRVM_G_FLOAT(OFS_RETURN) = realtime;
                                break;
                }
        }
@@ -2913,27 +2896,29 @@ void VM_gettime(void)
 =========
 VM_getsoundtime
 
-float  getsoundtime(void)
+float  getsoundtime(prvm_prog_t *prog)
 =========
 */
 
-void VM_getsoundtime (void)
+void VM_getsoundtime (prvm_prog_t *prog)
 {
-       int entnum, entchannel, pnum;
+       int entnum, entchannel;
        VM_SAFEPARMCOUNT(2,VM_getsoundtime);
 
-       pnum = PRVM_GetProgNr();
-       if (pnum == PRVM_MENUPROG)
+       if (prog == SVVM_prog)
+               entnum = PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0));
+       else if (prog == CLVM_prog)
+               entnum = MAX_EDICTS + PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0));
+       else
        {
-               VM_Warning("VM_getsoundtime: %s: not supported on this progs\n", PRVM_NAME);
+               VM_Warning(prog, "VM_getsoundtime: %s: not supported on this progs\n", prog->name);
                PRVM_G_FLOAT(OFS_RETURN) = -1;
                return;
        }
-       entnum = ((pnum == PRVM_CLIENTPROG) ? MAX_EDICTS : 0) + PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0));
        entchannel = (int)PRVM_G_FLOAT(OFS_PARM1);
        entchannel = CHAN_USER2ENGINE(entchannel);
        if (!IS_CHAN(entchannel))
-               VM_Warning("VM_getsoundtime: %s: bad channel %i\n", PRVM_NAME, entchannel);
+               VM_Warning(prog, "VM_getsoundtime: %s: bad channel %i\n", prog->name, entchannel);
        PRVM_G_FLOAT(OFS_RETURN) = (float)S_GetEntChannelPosition(entnum, entchannel);
 }
 
@@ -2944,7 +2929,7 @@ VM_GetSoundLen
 string soundlength (string sample)
 =========
 */
-void VM_soundlength (void)
+void VM_soundlength (prvm_prog_t *prog)
 {
        const char *s;
 
@@ -2961,11 +2946,11 @@ VM_loadfromdata
 loadfromdata(string data)
 =========
 */
-void VM_loadfromdata(void)
+void VM_loadfromdata(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1,VM_loadentsfromfile);
 
-       PRVM_ED_LoadFromFile(PRVM_G_STRING(OFS_PARM0));
+       PRVM_ED_LoadFromFile(prog, PRVM_G_STRING(OFS_PARM0));
 }
 
 /*
@@ -2975,7 +2960,7 @@ VM_parseentitydata
 parseentitydata(entity ent, string data)
 ========================
 */
-void VM_parseentitydata(void)
+void VM_parseentitydata(prvm_prog_t *prog)
 {
        prvm_edict_t *ent;
        const char *data;
@@ -2985,15 +2970,15 @@ void VM_parseentitydata(void)
        // get edict and test it
        ent = PRVM_G_EDICT(OFS_PARM0);
        if (ent->priv.required->free)
-               PRVM_ERROR ("VM_parseentitydata: %s: Can only set already spawned entities (entity %i is free)!", PRVM_NAME, PRVM_NUM_FOR_EDICT(ent));
+               prog->error_cmd("VM_parseentitydata: %s: Can only set already spawned entities (entity %i is free)!", prog->name, PRVM_NUM_FOR_EDICT(ent));
 
        data = PRVM_G_STRING(OFS_PARM1);
 
        // parse the opening brace
        if (!COM_ParseToken_Simple(&data, false, false) || com_token[0] != '{' )
-               PRVM_ERROR ("VM_parseentitydata: %s: Couldn't parse entity data:\n%s", PRVM_NAME, data );
+               prog->error_cmd("VM_parseentitydata: %s: Couldn't parse entity data:\n%s", prog->name, data );
 
-       PRVM_ED_ParseEdict (data, ent);
+       PRVM_ED_ParseEdict (prog, data, ent);
 }
 
 /*
@@ -3003,7 +2988,7 @@ VM_loadfromfile
 loadfromfile(string file)
 =========
 */
-void VM_loadfromfile(void)
+void VM_loadfromfile(prvm_prog_t *prog)
 {
        const char *filename;
        char *data;
@@ -3014,7 +2999,7 @@ void VM_loadfromfile(void)
        if (FS_CheckNastyPath(filename, false))
        {
                PRVM_G_FLOAT(OFS_RETURN) = -4;
-               VM_Warning("VM_loadfromfile: %s dangerous or non-portable filename \"%s\" not allowed. (contains : or \\ or begins with .. or /)\n", PRVM_NAME, filename);
+               VM_Warning(prog, "VM_loadfromfile: %s dangerous or non-portable filename \"%s\" not allowed. (contains : or \\ or begins with .. or /)\n", prog->name, filename);
                return;
        }
 
@@ -3023,7 +3008,7 @@ void VM_loadfromfile(void)
        if (data == NULL)
                PRVM_G_FLOAT(OFS_RETURN) = -1;
 
-       PRVM_ED_LoadFromFile(data);
+       PRVM_ED_LoadFromFile(prog, data);
 
        if(data)
                Mem_Free(data);
@@ -3037,7 +3022,7 @@ VM_modulo
 float  mod(float val, float m)
 =========
 */
-void VM_modulo(void)
+void VM_modulo(prvm_prog_t *prog)
 {
        int val, m;
        VM_SAFEPARMCOUNT(2,VM_module);
@@ -3048,14 +3033,14 @@ void VM_modulo(void)
        PRVM_G_FLOAT(OFS_RETURN) = (float) (val % m);
 }
 
-void VM_Search_Init(void)
+static void VM_Search_Init(prvm_prog_t *prog)
 {
        int i;
        for (i = 0;i < PRVM_MAX_OPENSEARCHES;i++)
                prog->opensearches[i] = NULL;
 }
 
-void VM_Search_Reset(void)
+static void VM_Search_Reset(prvm_prog_t *prog)
 {
        int i;
        // reset the fssearch list
@@ -3074,7 +3059,7 @@ VM_search_begin
 float search_begin(string pattern, float caseinsensitive, float quiet)
 =========
 */
-void VM_search_begin(void)
+void VM_search_begin(prvm_prog_t *prog)
 {
        int handle;
        const char *pattern;
@@ -3084,7 +3069,7 @@ void VM_search_begin(void)
 
        pattern = PRVM_G_STRING(OFS_PARM0);
 
-       VM_CheckEmptyString(pattern);
+       VM_CheckEmptyString(prog, pattern);
 
        caseinsens = (int)PRVM_G_FLOAT(OFS_PARM1);
        quiet = (int)PRVM_G_FLOAT(OFS_PARM2);
@@ -3096,7 +3081,7 @@ void VM_search_begin(void)
        if(handle >= PRVM_MAX_OPENSEARCHES)
        {
                PRVM_G_FLOAT(OFS_RETURN) = -2;
-               VM_Warning("VM_search_begin: %s ran out of search handles (%i)\n", PRVM_NAME, PRVM_MAX_OPENSEARCHES);
+               VM_Warning(prog, "VM_search_begin: %s ran out of search handles (%i)\n", prog->name, PRVM_MAX_OPENSEARCHES);
                return;
        }
 
@@ -3104,7 +3089,7 @@ void VM_search_begin(void)
                PRVM_G_FLOAT(OFS_RETURN) = -1;
        else
        {
-               prog->opensearches_origin[handle] = PRVM_AllocationOrigin();
+               prog->opensearches_origin[handle] = PRVM_AllocationOrigin(prog);
                PRVM_G_FLOAT(OFS_RETURN) = handle;
        }
 }
@@ -3116,7 +3101,7 @@ VM_search_end
 void   search_end(float handle)
 =========
 */
-void VM_search_end(void)
+void VM_search_end(prvm_prog_t *prog)
 {
        int handle;
        VM_SAFEPARMCOUNT(1, VM_search_end);
@@ -3125,12 +3110,12 @@ void VM_search_end(void)
 
        if(handle < 0 || handle >= PRVM_MAX_OPENSEARCHES)
        {
-               VM_Warning("VM_search_end: invalid handle %i used in %s\n", handle, PRVM_NAME);
+               VM_Warning(prog, "VM_search_end: invalid handle %i used in %s\n", handle, prog->name);
                return;
        }
        if(prog->opensearches[handle] == NULL)
        {
-               VM_Warning("VM_search_end: no such handle %i in %s\n", handle, PRVM_NAME);
+               VM_Warning(prog, "VM_search_end: no such handle %i in %s\n", handle, prog->name);
                return;
        }
 
@@ -3147,7 +3132,7 @@ VM_search_getsize
 float  search_getsize(float handle)
 =========
 */
-void VM_search_getsize(void)
+void VM_search_getsize(prvm_prog_t *prog)
 {
        int handle;
        VM_SAFEPARMCOUNT(1, VM_M_search_getsize);
@@ -3156,12 +3141,12 @@ void VM_search_getsize(void)
 
        if(handle < 0 || handle >= PRVM_MAX_OPENSEARCHES)
        {
-               VM_Warning("VM_search_getsize: invalid handle %i used in %s\n", handle, PRVM_NAME);
+               VM_Warning(prog, "VM_search_getsize: invalid handle %i used in %s\n", handle, prog->name);
                return;
        }
        if(prog->opensearches[handle] == NULL)
        {
-               VM_Warning("VM_search_getsize: no such handle %i in %s\n", handle, PRVM_NAME);
+               VM_Warning(prog, "VM_search_getsize: no such handle %i in %s\n", handle, prog->name);
                return;
        }
 
@@ -3175,7 +3160,7 @@ VM_search_getfilename
 string search_getfilename(float handle, float num)
 =========
 */
-void VM_search_getfilename(void)
+void VM_search_getfilename(prvm_prog_t *prog)
 {
        int handle, filenum;
        VM_SAFEPARMCOUNT(2, VM_search_getfilename);
@@ -3185,21 +3170,21 @@ void VM_search_getfilename(void)
 
        if(handle < 0 || handle >= PRVM_MAX_OPENSEARCHES)
        {
-               VM_Warning("VM_search_getfilename: invalid handle %i used in %s\n", handle, PRVM_NAME);
+               VM_Warning(prog, "VM_search_getfilename: invalid handle %i used in %s\n", handle, prog->name);
                return;
        }
        if(prog->opensearches[handle] == NULL)
        {
-               VM_Warning("VM_search_getfilename: no such handle %i in %s\n", handle, PRVM_NAME);
+               VM_Warning(prog, "VM_search_getfilename: no such handle %i in %s\n", handle, prog->name);
                return;
        }
        if(filenum < 0 || filenum >= prog->opensearches[handle]->numfilenames)
        {
-               VM_Warning("VM_search_getfilename: invalid filenum %i in %s\n", filenum, PRVM_NAME);
+               VM_Warning(prog, "VM_search_getfilename: invalid filenum %i in %s\n", filenum, prog->name);
                return;
        }
 
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog->opensearches[handle]->filenames[filenum]);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, prog->opensearches[handle]->filenames[filenum]);
 }
 
 /*
@@ -3209,7 +3194,7 @@ VM_chr
 string chr(float ascii)
 =========
 */
-void VM_chr(void)
+void VM_chr(prvm_prog_t *prog)
 {
        /*
        char tmp[2];
@@ -3218,7 +3203,7 @@ void VM_chr(void)
        tmp[0] = (unsigned char) PRVM_G_FLOAT(OFS_PARM0);
        tmp[1] = 0;
 
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(tmp);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, tmp);
        */
        
        char tmp[8];
@@ -3227,7 +3212,7 @@ void VM_chr(void)
 
        len = u8_fromchar((Uchar)PRVM_G_FLOAT(OFS_PARM0), tmp, sizeof(tmp));
        tmp[len] = 0;
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(tmp);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, tmp);
 }
 
 //=============================================================================
@@ -3240,7 +3225,7 @@ VM_iscachedpic
 float  iscachedpic(string pic)
 =========
 */
-void VM_iscachedpic(void)
+void VM_iscachedpic(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1,VM_iscachedpic);
 
@@ -3255,7 +3240,7 @@ VM_precache_pic
 string precache_pic(string pic)
 =========
 */
-void VM_precache_pic(void)
+void VM_precache_pic(prvm_prog_t *prog)
 {
        const char      *s;
 
@@ -3263,7 +3248,7 @@ void VM_precache_pic(void)
 
        s = PRVM_G_STRING(OFS_PARM0);
        PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
-       VM_CheckEmptyString (s);
+       VM_CheckEmptyString(prog, s);
 
        // AK Draw_CachePic is supposed to always return a valid pointer
        if( Draw_CachePic_Flags(s, 0)->tex == r_texture_notexture )
@@ -3277,19 +3262,19 @@ VM_freepic
 freepic(string s)
 =========
 */
-void VM_freepic(void)
+void VM_freepic(prvm_prog_t *prog)
 {
        const char *s;
 
        VM_SAFEPARMCOUNT(1,VM_freepic);
 
        s = PRVM_G_STRING(OFS_PARM0);
-       VM_CheckEmptyString (s);
+       VM_CheckEmptyString(prog, s);
 
        Draw_FreePic(s);
 }
 
-void getdrawfontscale(float *sx, float *sy)
+static void getdrawfontscale(prvm_prog_t *prog, float *sx, float *sy)
 {
        vec3_t v;
        *sx = *sy = 1;
@@ -3301,7 +3286,7 @@ void getdrawfontscale(float *sx, float *sy)
        }
 }
 
-dp_font_t *getdrawfont(void)
+static dp_font_t *getdrawfont(prvm_prog_t *prog)
 {
        int f = (int) PRVM_drawglobalfloat(drawfont);
        if(f < 0 || f >= dp_fonts.maxsize)
@@ -3316,7 +3301,7 @@ VM_drawcharacter
 float  drawcharacter(vector position, float character, vector scale, vector rgb, float alpha, float flag)
 =========
 */
-void VM_drawcharacter(void)
+void VM_drawcharacter(prvm_prog_t *prog)
 {
        float *pos,*scale,*rgb;
        char   character;
@@ -3328,7 +3313,7 @@ void VM_drawcharacter(void)
        if(character == 0)
        {
                PRVM_G_FLOAT(OFS_RETURN) = -1;
-               VM_Warning("VM_drawcharacter: %s passed null character !\n",PRVM_NAME);
+               VM_Warning(prog, "VM_drawcharacter: %s passed null character !\n",prog->name);
                return;
        }
 
@@ -3340,7 +3325,7 @@ void VM_drawcharacter(void)
        if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
        {
                PRVM_G_FLOAT(OFS_RETURN) = -2;
-               VM_Warning("VM_drawcharacter: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
+               VM_Warning(prog, "VM_drawcharacter: %s: wrong DRAWFLAG %i !\n",prog->name,flag);
                return;
        }
 
@@ -3350,12 +3335,12 @@ void VM_drawcharacter(void)
        if(!scale[0] || !scale[1])
        {
                PRVM_G_FLOAT(OFS_RETURN) = -3;
-               VM_Warning("VM_drawcharacter: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y");
+               VM_Warning(prog, "VM_drawcharacter: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y");
                return;
        }
 
-       getdrawfontscale(&sx, &sy);
-       DrawQ_String_Scale(pos[0], pos[1], &character, 1, scale[0], scale[1], sx, sy, rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag, NULL, true, getdrawfont());
+       getdrawfontscale(prog, &sx, &sy);
+       DrawQ_String_Scale(pos[0], pos[1], &character, 1, scale[0], scale[1], sx, sy, rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag, NULL, true, getdrawfont(prog));
        PRVM_G_FLOAT(OFS_RETURN) = 1;
 }
 
@@ -3366,7 +3351,7 @@ VM_drawstring
 float  drawstring(vector position, string text, vector scale, vector rgb, float alpha[, float flag])
 =========
 */
-void VM_drawstring(void)
+void VM_drawstring(prvm_prog_t *prog)
 {
        float *pos,*scale,*rgb;
        const char  *string;
@@ -3384,22 +3369,22 @@ void VM_drawstring(void)
        if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
        {
                PRVM_G_FLOAT(OFS_RETURN) = -2;
-               VM_Warning("VM_drawstring: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
+               VM_Warning(prog, "VM_drawstring: %s: wrong DRAWFLAG %i !\n",prog->name,flag);
                return;
        }
 
        if(!scale[0] || !scale[1])
        {
                PRVM_G_FLOAT(OFS_RETURN) = -3;
-               VM_Warning("VM_drawstring: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y");
+               VM_Warning(prog, "VM_drawstring: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y");
                return;
        }
 
        if(pos[2] || scale[2])
                Con_Printf("VM_drawstring: z value%s from %s discarded\n",(pos[2] && scale[2]) ? "s" : " ",((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale")));
 
-       getdrawfontscale(&sx, &sy);
-       DrawQ_String_Scale(pos[0], pos[1], string, 0, scale[0], scale[1], sx, sy, rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag, NULL, true, getdrawfont());
+       getdrawfontscale(prog, &sx, &sy);
+       DrawQ_String_Scale(pos[0], pos[1], string, 0, scale[0], scale[1], sx, sy, rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag, NULL, true, getdrawfont(prog));
        //Font_DrawString(pos[0], pos[1], string, 0, scale[0], scale[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag, NULL, true);
        PRVM_G_FLOAT(OFS_RETURN) = 1;
 }
@@ -3413,7 +3398,7 @@ float     drawcolorcodedstring(vector position, string text, vector scale, float alp
 float  drawcolorcodedstring(vector position, string text, vector scale, vector rgb, float alpha, float flag)
 =========
 */
-void VM_drawcolorcodedstring(void)
+void VM_drawcolorcodedstring(prvm_prog_t *prog)
 {
        float *pos, *scale;
        const char  *string;
@@ -3447,22 +3432,22 @@ void VM_drawcolorcodedstring(void)
        if(flag < DRAWFLAG_NORMAL || flag >= DRAWFLAG_NUMFLAGS)
        {
                PRVM_G_FLOAT(OFS_RETURN) = -2;
-               VM_Warning("VM_drawcolorcodedstring: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
+               VM_Warning(prog, "VM_drawcolorcodedstring: %s: wrong DRAWFLAG %i !\n",prog->name,flag);
                return;
        }
 
        if(!scale[0] || !scale[1])
        {
                PRVM_G_FLOAT(OFS_RETURN) = -3;
-               VM_Warning("VM_drawcolorcodedstring: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y");
+               VM_Warning(prog, "VM_drawcolorcodedstring: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y");
                return;
        }
 
        if(pos[2] || scale[2])
                Con_Printf("VM_drawcolorcodedstring: z value%s from %s discarded\n",(pos[2] && scale[2]) ? "s" : " ",((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale")));
 
-       getdrawfontscale(&sx, &sy);
-       DrawQ_String_Scale(pos[0], pos[1], string, 0, scale[0], scale[1], sx, sy, rgb[0], rgb[1], rgb[2], alpha, flag, NULL, false, getdrawfont());
+       getdrawfontscale(prog, &sx, &sy);
+       DrawQ_String_Scale(pos[0], pos[1], string, 0, scale[0], scale[1], sx, sy, rgb[0], rgb[1], rgb[2], alpha, flag, NULL, false, getdrawfont(prog));
        if (prog->argc == 6) // also return vector of last color
                VectorCopy(DrawQ_Color, PRVM_G_VECTOR(OFS_RETURN));
        else
@@ -3475,7 +3460,7 @@ VM_stringwidth
 float  stringwidth(string text, float allowColorCodes, float size)
 =========
 */
-void VM_stringwidth(void)
+void VM_stringwidth(prvm_prog_t *prog)
 {
        const char  *string;
        float *szv;
@@ -3485,7 +3470,7 @@ void VM_stringwidth(void)
        size_t maxlen = 0;
        VM_SAFEPARMCOUNTRANGE(2,3,VM_drawstring);
 
-       getdrawfontscale(&sx, &sy);
+       getdrawfontscale(prog, &sx, &sy);
        if(prog->argc == 3)
        {
                szv = PRVM_G_VECTOR(OFS_PARM2);
@@ -3509,7 +3494,7 @@ void VM_stringwidth(void)
        string = PRVM_G_STRING(OFS_PARM0);
        colors = (int)PRVM_G_FLOAT(OFS_PARM1);
 
-       PRVM_G_FLOAT(OFS_RETURN) = DrawQ_TextWidth_UntilWidth_TrackColors_Scale(string, &maxlen, szv[0], szv[1], sx, sy, NULL, !colors, getdrawfont(), 1000000000) * mult;
+       PRVM_G_FLOAT(OFS_RETURN) = DrawQ_TextWidth_UntilWidth_TrackColors_Scale(string, &maxlen, szv[0], szv[1], sx, sy, NULL, !colors, getdrawfont(prog), 1000000000) * mult;
 /*
        if(prog->argc == 3)
        {
@@ -3536,7 +3521,7 @@ float findfont(string s)
 =========
 */
 
-float getdrawfontnum(const char *fontname)
+static float getdrawfontnum(const char *fontname)
 {
        int i;
 
@@ -3546,7 +3531,7 @@ float getdrawfontnum(const char *fontname)
        return -1;
 }
 
-void VM_findfont(void)
+void VM_findfont(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1,VM_findfont);
        PRVM_G_FLOAT(OFS_RETURN) = getdrawfontnum(PRVM_G_STRING(OFS_PARM0));
@@ -3560,9 +3545,7 @@ float loadfont(string fontname, string fontmaps, string sizes, float slot)
 =========
 */
 
-dp_font_t *FindFont(const char *title, qboolean allocate_new);
-void LoadFont(qboolean override, const char *name, dp_font_t *fnt, float scale, float voffset);
-void VM_loadfont(void)
+void VM_loadfont(prvm_prog_t *prog)
 {
        const char *fontname, *filelist, *sizes, *c, *cm;
        char mainfont[MAX_QPATH];
@@ -3664,13 +3647,13 @@ void VM_loadfont(void)
                // detect crap size
                if (sz < 0.001f || sz > 1000.0f)
                {
-                       VM_Warning("VM_loadfont: crap size %s", com_token);
+                       VM_Warning(prog, "VM_loadfont: crap size %s", com_token);
                        continue;
                }
                // check overflow
                if (numsizes == MAX_FONT_SIZES)
                {
-                       VM_Warning("VM_loadfont: MAX_FONT_SIZES = %i exceeded", MAX_FONT_SIZES);
+                       VM_Warning(prog, "VM_loadfont: MAX_FONT_SIZES = %i exceeded", MAX_FONT_SIZES);
                        break;
                }
                f->req_sizes[numsizes] = sz;
@@ -3703,7 +3686,7 @@ VM_drawpic
 float  drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag)
 =========
 */
-void VM_drawpic(void)
+void VM_drawpic(prvm_prog_t *prog)
 {
        const char *picname;
        float *size, *pos, *rgb;
@@ -3712,13 +3695,13 @@ void VM_drawpic(void)
        VM_SAFEPARMCOUNTRANGE(5,6,VM_drawpic);
 
        picname = PRVM_G_STRING(OFS_PARM1);
-       VM_CheckEmptyString (picname);
+       VM_CheckEmptyString(prog, picname);
 
        // is pic cached ? no function yet for that
        if(!1)
        {
                PRVM_G_FLOAT(OFS_RETURN) = -4;
-               VM_Warning("VM_drawpic: %s: %s not cached !\n", PRVM_NAME, picname);
+               VM_Warning(prog, "VM_drawpic: %s: %s not cached !\n", prog->name, picname);
                return;
        }
 
@@ -3731,7 +3714,7 @@ void VM_drawpic(void)
        if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
        {
                PRVM_G_FLOAT(OFS_RETURN) = -2;
-               VM_Warning("VM_drawpic: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
+               VM_Warning(prog, "VM_drawpic: %s: wrong DRAWFLAG %i !\n",prog->name,flag);
                return;
        }
 
@@ -3748,7 +3731,7 @@ VM_drawrotpic
 float  drawrotpic(vector position, string pic, vector size, vector org, float angle, vector rgb, float alpha, float flag)
 =========
 */
-void VM_drawrotpic(void)
+void VM_drawrotpic(prvm_prog_t *prog)
 {
        const char *picname;
        float *size, *pos, *org, *rgb;
@@ -3757,13 +3740,13 @@ void VM_drawrotpic(void)
        VM_SAFEPARMCOUNT(8,VM_drawrotpic);
 
        picname = PRVM_G_STRING(OFS_PARM1);
-       VM_CheckEmptyString (picname);
+       VM_CheckEmptyString(prog, picname);
 
        // is pic cached ? no function yet for that
        if(!1)
        {
                PRVM_G_FLOAT(OFS_RETURN) = -4;
-               VM_Warning("VM_drawrotpic: %s: %s not cached !\n", PRVM_NAME, picname);
+               VM_Warning(prog, "VM_drawrotpic: %s: %s not cached !\n", prog->name, picname);
                return;
        }
 
@@ -3776,7 +3759,7 @@ void VM_drawrotpic(void)
        if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
        {
                PRVM_G_FLOAT(OFS_RETURN) = -2;
-               VM_Warning("VM_drawrotpic: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
+               VM_Warning(prog, "VM_drawrotpic: %s: wrong DRAWFLAG %i !\n",prog->name,flag);
                return;
        }
 
@@ -3794,7 +3777,7 @@ float     drawsubpic(vector position, vector size, string pic, vector srcPos, vector
 
 =========
 */
-void VM_drawsubpic(void)
+void VM_drawsubpic(prvm_prog_t *prog)
 {
        const char *picname;
        float *size, *pos, *rgb, *srcPos, *srcSize, alpha;
@@ -3803,13 +3786,13 @@ void VM_drawsubpic(void)
        VM_SAFEPARMCOUNT(8,VM_drawsubpic);
 
        picname = PRVM_G_STRING(OFS_PARM2);
-       VM_CheckEmptyString (picname);
+       VM_CheckEmptyString(prog, picname);
 
        // is pic cached ? no function yet for that
        if(!1)
        {
                PRVM_G_FLOAT(OFS_RETURN) = -4;
-               VM_Warning("VM_drawsubpic: %s: %s not cached !\n", PRVM_NAME, picname);
+               VM_Warning(prog, "VM_drawsubpic: %s: %s not cached !\n", prog->name, picname);
                return;
        }
 
@@ -3824,7 +3807,7 @@ void VM_drawsubpic(void)
        if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
        {
                PRVM_G_FLOAT(OFS_RETURN) = -2;
-               VM_Warning("VM_drawsubpic: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
+               VM_Warning(prog, "VM_drawsubpic: %s: wrong DRAWFLAG %i !\n",prog->name,flag);
                return;
        }
 
@@ -3848,7 +3831,7 @@ VM_drawfill
 float drawfill(vector position, vector size, vector rgb, float alpha, float flag)
 =========
 */
-void VM_drawfill(void)
+void VM_drawfill(prvm_prog_t *prog)
 {
        float *size, *pos, *rgb;
        int flag;
@@ -3864,7 +3847,7 @@ void VM_drawfill(void)
        if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
        {
                PRVM_G_FLOAT(OFS_RETURN) = -2;
-               VM_Warning("VM_drawfill: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
+               VM_Warning(prog, "VM_drawfill: %s: wrong DRAWFLAG %i !\n",prog->name,flag);
                return;
        }
 
@@ -3882,7 +3865,7 @@ VM_drawsetcliparea
 drawsetcliparea(float x, float y, float width, float height)
 =========
 */
-void VM_drawsetcliparea(void)
+void VM_drawsetcliparea(prvm_prog_t *prog)
 {
        float x,y,w,h;
        VM_SAFEPARMCOUNT(4,VM_drawsetcliparea);
@@ -3902,7 +3885,7 @@ VM_drawresetcliparea
 drawresetcliparea()
 =========
 */
-void VM_drawresetcliparea(void)
+void VM_drawresetcliparea(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0,VM_drawresetcliparea);
 
@@ -3916,7 +3899,7 @@ VM_getimagesize
 vector getimagesize(string pic)
 =========
 */
-void VM_getimagesize(void)
+void VM_getimagesize(prvm_prog_t *prog)
 {
        const char *p;
        cachepic_t *pic;
@@ -3924,7 +3907,7 @@ void VM_getimagesize(void)
        VM_SAFEPARMCOUNT(1,VM_getimagesize);
 
        p = PRVM_G_STRING(OFS_PARM0);
-       VM_CheckEmptyString (p);
+       VM_CheckEmptyString(prog, p);
 
        pic = Draw_CachePic_Flags (p, CACHEPICFLAG_NOTPERSISTENT);
 
@@ -3940,11 +3923,12 @@ VM_keynumtostring
 string keynumtostring(float keynum)
 =========
 */
-void VM_keynumtostring (void)
+void VM_keynumtostring (prvm_prog_t *prog)
 {
+       char tinystr[2];
        VM_SAFEPARMCOUNT(1, VM_keynumtostring);
 
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(Key_KeynumToString((int)PRVM_G_FLOAT(OFS_PARM0)));
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, Key_KeynumToString((int)PRVM_G_FLOAT(OFS_PARM0), tinystr, sizeof(tinystr)));
 }
 
 /*
@@ -3958,13 +3942,14 @@ the returned string is an altstring
 */
 #define FKFC_NUMKEYS 5
 void M_FindKeysForCommand(const char *command, int *keys);
-void VM_findkeysforcommand(void)
+void VM_findkeysforcommand(prvm_prog_t *prog)
 {
        const char *cmd;
        char ret[VM_STRINGTEMP_LENGTH];
        int keys[FKFC_NUMKEYS];
        int i;
        int bindmap;
+       char vabuf[1024];
 
        VM_SAFEPARMCOUNTRANGE(1, 2, VM_findkeysforcommand);
 
@@ -3974,15 +3959,15 @@ void VM_findkeysforcommand(void)
        else
                bindmap = 0; // consistent to "bind"
 
-       VM_CheckEmptyString(cmd);
+       VM_CheckEmptyString(prog, cmd);
 
        Key_FindKeysForCommand(cmd, keys, FKFC_NUMKEYS, bindmap);
 
        ret[0] = 0;
        for(i = 0; i < FKFC_NUMKEYS; i++)
-               strlcat(ret, va(" \'%i\'", keys[i]), sizeof(ret));
+               strlcat(ret, va(vabuf, sizeof(vabuf), " \'%i\'", keys[i]), sizeof(ret));
 
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(ret);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, ret);
 }
 
 /*
@@ -3992,7 +3977,7 @@ VM_stringtokeynum
 float stringtokeynum(string key)
 =========
 */
-void VM_stringtokeynum (void)
+void VM_stringtokeynum (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT( 1, VM_keynumtostring );
 
@@ -4006,7 +3991,7 @@ VM_getkeybind
 string getkeybind(float key, float bindmap)
 =========
 */
-void VM_getkeybind (void)
+void VM_getkeybind (prvm_prog_t *prog)
 {
        int bindmap;
        VM_SAFEPARMCOUNTRANGE(1, 2, VM_CL_getkeybind);
@@ -4015,7 +4000,7 @@ void VM_getkeybind (void)
        else
                bindmap = 0; // consistent to "bind"
 
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(Key_GetBind((int)PRVM_G_FLOAT(OFS_PARM0), bindmap));
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, Key_GetBind((int)PRVM_G_FLOAT(OFS_PARM0), bindmap));
 }
 
 /*
@@ -4025,7 +4010,7 @@ VM_setkeybind
 float setkeybind(float key, string cmd, float bindmap)
 =========
 */
-void VM_setkeybind (void)
+void VM_setkeybind (prvm_prog_t *prog)
 {
        int bindmap;
        VM_SAFEPARMCOUNTRANGE(2, 3, VM_CL_setkeybind);
@@ -4046,7 +4031,7 @@ VM_getbindmap
 vector getbindmaps()
 =========
 */
-void VM_getbindmaps (void)
+void VM_getbindmaps (prvm_prog_t *prog)
 {
        int fg, bg;
        VM_SAFEPARMCOUNT(0, VM_CL_getbindmap);
@@ -4063,7 +4048,7 @@ VM_setbindmap
 float setbindmaps(vector bindmap)
 =========
 */
-void VM_setbindmaps (void)
+void VM_setbindmaps (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_CL_setbindmap);
        PRVM_G_FLOAT(OFS_RETURN) = 0;
@@ -4081,7 +4066,7 @@ VM_cin_open
 float cin_open(string file, string name)
 ========================
 */
-void VM_cin_open( void )
+void VM_cin_open(prvm_prog_t *prog)
 {
        const char *file;
        const char *name;
@@ -4091,8 +4076,8 @@ void VM_cin_open( void )
        file = PRVM_G_STRING( OFS_PARM0 );
        name = PRVM_G_STRING( OFS_PARM1 );
 
-       VM_CheckEmptyString( file );
-    VM_CheckEmptyString( name );
+       VM_CheckEmptyString(prog,  file );
+    VM_CheckEmptyString(prog,  name );
 
        if( CL_OpenVideo( file, name, MENUOWNER, "" ) )
                PRVM_G_FLOAT( OFS_RETURN ) = 1;
@@ -4107,14 +4092,14 @@ VM_cin_close
 void cin_close(string name)
 ========================
 */
-void VM_cin_close( void )
+void VM_cin_close(prvm_prog_t *prog)
 {
        const char *name;
 
        VM_SAFEPARMCOUNT( 1, VM_cin_close );
 
        name = PRVM_G_STRING( OFS_PARM0 );
-       VM_CheckEmptyString( name );
+       VM_CheckEmptyString(prog,  name );
 
        CL_CloseVideo( CL_GetVideoByName( name ) );
 }
@@ -4125,7 +4110,7 @@ VM_cin_setstate
 void cin_setstate(string name, float type)
 ========================
 */
-void VM_cin_setstate( void )
+void VM_cin_setstate(prvm_prog_t *prog)
 {
        const char *name;
        clvideostate_t  state;
@@ -4134,7 +4119,7 @@ void VM_cin_setstate( void )
        VM_SAFEPARMCOUNT( 2, VM_cin_netstate );
 
        name = PRVM_G_STRING( OFS_PARM0 );
-       VM_CheckEmptyString( name );
+       VM_CheckEmptyString(prog,  name );
 
        state = (clvideostate_t)((int)PRVM_G_FLOAT( OFS_PARM1 ));
 
@@ -4150,7 +4135,7 @@ VM_cin_getstate
 float cin_getstate(string name)
 ========================
 */
-void VM_cin_getstate( void )
+void VM_cin_getstate(prvm_prog_t *prog)
 {
        const char *name;
        clvideo_t               *video;
@@ -4158,7 +4143,7 @@ void VM_cin_getstate( void )
        VM_SAFEPARMCOUNT( 1, VM_cin_getstate );
 
        name = PRVM_G_STRING( OFS_PARM0 );
-       VM_CheckEmptyString( name );
+       VM_CheckEmptyString(prog,  name );
 
        video = CL_GetVideoByName( name );
        if( video )
@@ -4174,7 +4159,7 @@ VM_cin_restart
 void cin_restart(string name)
 ========================
 */
-void VM_cin_restart( void )
+void VM_cin_restart(prvm_prog_t *prog)
 {
        const char *name;
        clvideo_t               *video;
@@ -4182,31 +4167,13 @@ void VM_cin_restart( void )
        VM_SAFEPARMCOUNT( 1, VM_cin_restart );
 
        name = PRVM_G_STRING( OFS_PARM0 );
-       VM_CheckEmptyString( name );
+       VM_CheckEmptyString(prog,  name );
 
        video = CL_GetVideoByName( name );
        if( video )
                CL_RestartVideo( video );
 }
 
-/*
-========================
-VM_Gecko_Init
-========================
-*/
-void VM_Gecko_Init( void ) {
-       // REMOVED
-}
-
-/*
-========================
-VM_Gecko_Destroy
-========================
-*/
-void VM_Gecko_Destroy( void ) {
-       // REMOVED
-}
-
 /*
 ========================
 VM_gecko_create
@@ -4214,7 +4181,7 @@ VM_gecko_create
 float[bool] gecko_create( string name )
 ========================
 */
-void VM_gecko_create( void ) {
+void VM_gecko_create(prvm_prog_t *prog) {
        // REMOVED
        PRVM_G_FLOAT( OFS_RETURN ) = 0;
 }
@@ -4226,7 +4193,7 @@ VM_gecko_destroy
 void gecko_destroy( string name )
 ========================
 */
-void VM_gecko_destroy( void ) {
+void VM_gecko_destroy(prvm_prog_t *prog) {
        // REMOVED
 }
 
@@ -4237,7 +4204,7 @@ VM_gecko_navigate
 void gecko_navigate( string name, string URI )
 ========================
 */
-void VM_gecko_navigate( void ) {
+void VM_gecko_navigate(prvm_prog_t *prog) {
        // REMOVED
 }
 
@@ -4248,7 +4215,7 @@ VM_gecko_keyevent
 float[bool] gecko_keyevent( string name, float key, float eventtype ) 
 ========================
 */
-void VM_gecko_keyevent( void ) {
+void VM_gecko_keyevent(prvm_prog_t *prog) {
        // REMOVED
        PRVM_G_FLOAT( OFS_RETURN ) = 0;
 }
@@ -4260,7 +4227,7 @@ VM_gecko_movemouse
 void gecko_mousemove( string name, float x, float y )
 ========================
 */
-void VM_gecko_movemouse( void ) {
+void VM_gecko_movemouse(prvm_prog_t *prog) {
        // REMOVED
 }
 
@@ -4272,7 +4239,7 @@ VM_gecko_resize
 void gecko_resize( string name, float w, float h )
 ========================
 */
-void VM_gecko_resize( void ) {
+void VM_gecko_resize(prvm_prog_t *prog) {
        // REMOVED
 }
 
@@ -4284,7 +4251,7 @@ VM_gecko_get_texture_extent
 vector gecko_get_texture_extent( string name )
 ========================
 */
-void VM_gecko_get_texture_extent( void ) {
+void VM_gecko_get_texture_extent(prvm_prog_t *prog) {
        // REMOVED
        PRVM_G_VECTOR(OFS_RETURN)[0] = 0;
        PRVM_G_VECTOR(OFS_RETURN)[1] = 0;
@@ -4300,7 +4267,7 @@ Writes new values for v_forward, v_up, and v_right based on angles
 void makevectors(vector angle)
 ==============
 */
-void VM_makevectors (void)
+void VM_makevectors (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_makevectors);
        AngleVectors(PRVM_G_VECTOR(OFS_PARM0), PRVM_gameglobalvector(v_forward), PRVM_gameglobalvector(v_right), PRVM_gameglobalvector(v_up));
@@ -4314,7 +4281,7 @@ Writes new values for v_forward, v_up, and v_right based on the given forward ve
 vectorvectors(vector)
 ==============
 */
-void VM_vectorvectors (void)
+void VM_vectorvectors (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_vectorvectors);
        VectorNormalize2(PRVM_G_VECTOR(OFS_PARM0), PRVM_gameglobalvector(v_forward));
@@ -4328,7 +4295,7 @@ VM_drawline
 void drawline(float width, vector pos1, vector pos2, vector rgb, float alpha, float flags)
 ========================
 */
-void VM_drawline (void)
+void VM_drawline (prvm_prog_t *prog)
 {
        float   *c1, *c2, *rgb;
        float   alpha, width;
@@ -4345,7 +4312,7 @@ void VM_drawline (void)
 }
 
 // float(float number, float quantity) bitshift (EXT_BITSHIFT)
-void VM_bitshift (void)
+void VM_bitshift (prvm_prog_t *prog)
 {
        int n1, n2;
        VM_SAFEPARMCOUNT(2, VM_bitshift);
@@ -4372,7 +4339,7 @@ VM_altstr_count
 float altstr_count(string)
 ========================
 */
-void VM_altstr_count( void )
+void VM_altstr_count(prvm_prog_t *prog)
 {
        const char *altstr, *pos;
        int     count;
@@ -4380,7 +4347,7 @@ void VM_altstr_count( void )
        VM_SAFEPARMCOUNT( 1, VM_altstr_count );
 
        altstr = PRVM_G_STRING( OFS_PARM0 );
-       //VM_CheckEmptyString( altstr );
+       //VM_CheckEmptyString(prog,  altstr );
 
        for( count = 0, pos = altstr ; *pos ; pos++ ) {
                if( *pos == '\\' ) {
@@ -4402,7 +4369,7 @@ VM_altstr_prepare
 string altstr_prepare(string)
 ========================
 */
-void VM_altstr_prepare( void )
+void VM_altstr_prepare(prvm_prog_t *prog)
 {
        char *out;
        const char *instr, *in;
@@ -4422,7 +4389,7 @@ void VM_altstr_prepare( void )
                        *out = *in;
        *out = 0;
 
-       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( outstr );
+       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog,  outstr );
 }
 
 /*
@@ -4432,7 +4399,7 @@ VM_altstr_get
 string altstr_get(string, float)
 ========================
 */
-void VM_altstr_get( void )
+void VM_altstr_get(prvm_prog_t *prog)
 {
        const char *altstr, *pos;
        char *out;
@@ -4470,7 +4437,7 @@ void VM_altstr_get( void )
                        *out = *pos;
 
        *out = 0;
-       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( outstr );
+       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog,  outstr );
 }
 
 /*
@@ -4480,7 +4447,7 @@ VM_altstr_set
 string altstr_set(string altstr, float num, string set)
 ========================
 */
-void VM_altstr_set( void )
+void VM_altstr_set(prvm_prog_t *prog)
 {
     int num;
        const char *altstr, *str;
@@ -4514,7 +4481,7 @@ void VM_altstr_set( void )
                        break;
 
        strlcpy(out, in, outstr + sizeof(outstr) - out);
-       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( outstr );
+       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog,  outstr );
 }
 
 /*
@@ -4524,7 +4491,7 @@ insert after num
 string altstr_ins(string altstr, float num, string set)
 ========================
 */
-void VM_altstr_ins(void)
+void VM_altstr_ins(prvm_prog_t *prog)
 {
        int num;
        const char *set;
@@ -4553,7 +4520,7 @@ void VM_altstr_ins(void)
        *out++ = '\'';
 
        strlcpy(out, in, outstr + sizeof(outstr) - out);
-       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( outstr );
+       PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog,  outstr );
 }
 
 
@@ -4564,7 +4531,7 @@ void VM_altstr_ins(void)
 
 static size_t stringbuffers_sortlength;
 
-static void BufStr_Expand(prvm_stringbuffer_t *stringbuffer, int strindex)
+static void BufStr_Expand(prvm_prog_t *prog, prvm_stringbuffer_t *stringbuffer, int strindex)
 {
        if (stringbuffer->max_strings <= strindex)
        {
@@ -4580,7 +4547,7 @@ static void BufStr_Expand(prvm_stringbuffer_t *stringbuffer, int strindex)
        }
 }
 
-static void BufStr_Shrink(prvm_stringbuffer_t *stringbuffer)
+static void BufStr_Shrink(prvm_prog_t *prog, prvm_stringbuffer_t *stringbuffer)
 {
        // reduce num_strings if there are empty string slots at the end
        while (stringbuffer->num_strings > 0 && stringbuffer->strings[stringbuffer->num_strings - 1] == NULL)
@@ -4620,12 +4587,12 @@ static int BufStr_SortStringsDOWN (const void *in1, const void *in2)
 ========================
 VM_buf_create
 creates new buffer, and returns it's index, returns -1 if failed
-float buf_create(void) = #460;
+float buf_create(prvm_prog_t *prog) = #460;
 float newbuf(string format, float flags) = #460;
 ========================
 */
 
-void VM_buf_create (void)
+void VM_buf_create (prvm_prog_t *prog)
 {
        prvm_stringbuffer_t *stringbuffer;
        int i;
@@ -4640,7 +4607,7 @@ void VM_buf_create (void)
        }
        stringbuffer = (prvm_stringbuffer_t *) Mem_ExpandableArray_AllocRecord(&prog->stringbuffersarray);
        for (i = 0;stringbuffer != Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, i);i++);
-       stringbuffer->origin = PRVM_AllocationOrigin();
+       stringbuffer->origin = PRVM_AllocationOrigin(prog);
        // optional flags parm
        if (prog->argc >= 2)
                stringbuffer->flags = (int)PRVM_G_FLOAT(OFS_PARM1) & 0xFF;
@@ -4656,7 +4623,7 @@ deletes buffer and all strings in it
 void buf_del(float bufhandle) = #461;
 ========================
 */
-void VM_buf_del (void)
+void VM_buf_del (prvm_prog_t *prog)
 {
        prvm_stringbuffer_t *stringbuffer;
        VM_SAFEPARMCOUNT(1, VM_buf_del);
@@ -4675,7 +4642,7 @@ void VM_buf_del (void)
        }
        else
        {
-               VM_Warning("VM_buf_del: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+               VM_Warning(prog, "VM_buf_del: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), prog->name);
                return;
        }
 }
@@ -4687,7 +4654,7 @@ how many strings are stored in buffer
 float buf_getsize(float bufhandle) = #462;
 ========================
 */
-void VM_buf_getsize (void)
+void VM_buf_getsize (prvm_prog_t *prog)
 {
        prvm_stringbuffer_t *stringbuffer;
        VM_SAFEPARMCOUNT(1, VM_buf_getsize);
@@ -4696,7 +4663,7 @@ void VM_buf_getsize (void)
        if(!stringbuffer)
        {
                PRVM_G_FLOAT(OFS_RETURN) = -1;
-               VM_Warning("VM_buf_getsize: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+               VM_Warning(prog, "VM_buf_getsize: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), prog->name);
                return;
        }
        else
@@ -4710,7 +4677,7 @@ copy all content from one buffer to another, make sure it exists
 void buf_copy(float bufhandle_from, float bufhandle_to) = #463;
 ========================
 */
-void VM_buf_copy (void)
+void VM_buf_copy (prvm_prog_t *prog)
 {
        prvm_stringbuffer_t *srcstringbuffer, *dststringbuffer;
        int i;
@@ -4719,19 +4686,19 @@ void VM_buf_copy (void)
        srcstringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, (int)PRVM_G_FLOAT(OFS_PARM0));
        if(!srcstringbuffer)
        {
-               VM_Warning("VM_buf_copy: invalid source buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+               VM_Warning(prog, "VM_buf_copy: invalid source buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), prog->name);
                return;
        }
        i = (int)PRVM_G_FLOAT(OFS_PARM1);
        if(i == (int)PRVM_G_FLOAT(OFS_PARM0))
        {
-               VM_Warning("VM_buf_copy: source == destination (%i) in %s\n", i, PRVM_NAME);
+               VM_Warning(prog, "VM_buf_copy: source == destination (%i) in %s\n", i, prog->name);
                return;
        }
        dststringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, (int)PRVM_G_FLOAT(OFS_PARM0));
        if(!dststringbuffer)
        {
-               VM_Warning("VM_buf_copy: invalid destination buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM1), PRVM_NAME);
+               VM_Warning(prog, "VM_buf_copy: invalid destination buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM1), prog->name);
                return;
        }
 
@@ -4764,7 +4731,7 @@ sort buffer by beginnings of strings (cmplength defaults it's length)
 void buf_sort(float bufhandle, float cmplength, float backward) = #464;
 ========================
 */
-void VM_buf_sort (void)
+void VM_buf_sort (prvm_prog_t *prog)
 {
        prvm_stringbuffer_t *stringbuffer;
        VM_SAFEPARMCOUNT(3, VM_buf_sort);
@@ -4772,12 +4739,12 @@ void VM_buf_sort (void)
        stringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, (int)PRVM_G_FLOAT(OFS_PARM0));
        if(!stringbuffer)
        {
-               VM_Warning("VM_buf_sort: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+               VM_Warning(prog, "VM_buf_sort: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), prog->name);
                return;
        }
        if(stringbuffer->num_strings <= 0)
        {
-               VM_Warning("VM_buf_sort: tried to sort empty buffer %i in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+               VM_Warning(prog, "VM_buf_sort: tried to sort empty buffer %i in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), prog->name);
                return;
        }
        stringbuffers_sortlength = (int)PRVM_G_FLOAT(OFS_PARM1);
@@ -4789,7 +4756,7 @@ void VM_buf_sort (void)
        else
                qsort(stringbuffer->strings, stringbuffer->num_strings, sizeof(char*), BufStr_SortStringsDOWN);
 
-       BufStr_Shrink(stringbuffer);
+       BufStr_Shrink(prog, stringbuffer);
 }
 
 /*
@@ -4799,7 +4766,7 @@ concantenates all buffer string into one with "glue" separator and returns it as
 string buf_implode(float bufhandle, string glue) = #465;
 ========================
 */
-void VM_buf_implode (void)
+void VM_buf_implode (prvm_prog_t *prog)
 {
        prvm_stringbuffer_t *stringbuffer;
        char                    k[VM_STRINGTEMP_LENGTH];
@@ -4812,7 +4779,7 @@ void VM_buf_implode (void)
        PRVM_G_INT(OFS_RETURN) = OFS_NULL;
        if(!stringbuffer)
        {
-               VM_Warning("VM_buf_implode: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+               VM_Warning(prog, "VM_buf_implode: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), prog->name);
                return;
        }
        if(!stringbuffer->num_strings)
@@ -4830,7 +4797,7 @@ void VM_buf_implode (void)
                        strlcat(k, stringbuffer->strings[i], sizeof(k));
                }
        }
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(k);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, k);
 }
 
 /*
@@ -4840,7 +4807,7 @@ get a string from buffer, returns tempstring, dont str_unzone it!
 string bufstr_get(float bufhandle, float string_index) = #465;
 ========================
 */
-void VM_bufstr_get (void)
+void VM_bufstr_get (prvm_prog_t *prog)
 {
        prvm_stringbuffer_t *stringbuffer;
        int                             strindex;
@@ -4850,17 +4817,17 @@ void VM_bufstr_get (void)
        stringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, (int)PRVM_G_FLOAT(OFS_PARM0));
        if(!stringbuffer)
        {
-               VM_Warning("VM_bufstr_get: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+               VM_Warning(prog, "VM_bufstr_get: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), prog->name);
                return;
        }
        strindex = (int)PRVM_G_FLOAT(OFS_PARM1);
        if (strindex < 0)
        {
-               // VM_Warning("VM_bufstr_get: invalid string index %i used in %s\n", strindex, PRVM_NAME);
+               // VM_Warning(prog, "VM_bufstr_get: invalid string index %i used in %s\n", strindex, prog->name);
                return;
        }
        if (strindex < stringbuffer->num_strings && stringbuffer->strings[strindex])
-               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(stringbuffer->strings[strindex]);
+               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, stringbuffer->strings[strindex]);
 }
 
 /*
@@ -4870,7 +4837,7 @@ copies a string into selected slot of buffer
 void bufstr_set(float bufhandle, float string_index, string str) = #466;
 ========================
 */
-void VM_bufstr_set (void)
+void VM_bufstr_set (prvm_prog_t *prog)
 {
        size_t alloclen;
        int                             strindex;
@@ -4882,17 +4849,17 @@ void VM_bufstr_set (void)
        stringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, (int)PRVM_G_FLOAT(OFS_PARM0));
        if(!stringbuffer)
        {
-               VM_Warning("VM_bufstr_set: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+               VM_Warning(prog, "VM_bufstr_set: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), prog->name);
                return;
        }
        strindex = (int)PRVM_G_FLOAT(OFS_PARM1);
        if(strindex < 0 || strindex >= 1000000) // huge number of strings
        {
-               VM_Warning("VM_bufstr_set: invalid string index %i used in %s\n", strindex, PRVM_NAME);
+               VM_Warning(prog, "VM_bufstr_set: invalid string index %i used in %s\n", strindex, prog->name);
                return;
        }
 
-       BufStr_Expand(stringbuffer, strindex);
+       BufStr_Expand(prog, stringbuffer, strindex);
        stringbuffer->num_strings = max(stringbuffer->num_strings, strindex + 1);
 
        if(stringbuffer->strings[strindex])
@@ -4908,7 +4875,7 @@ void VM_bufstr_set (void)
                memcpy(stringbuffer->strings[strindex], news, alloclen);
        }
 
-       BufStr_Shrink(stringbuffer);
+       BufStr_Shrink(prog, stringbuffer);
 }
 
 /*
@@ -4919,7 +4886,7 @@ adds string to buffer in first free slot and returns its index
 float bufstr_add(float bufhandle, string str, float order) = #467;
 ========================
 */
-void VM_bufstr_add (void)
+void VM_bufstr_add (prvm_prog_t *prog)
 {
        int                             order, strindex;
        prvm_stringbuffer_t *stringbuffer;
@@ -4932,12 +4899,12 @@ void VM_bufstr_add (void)
        PRVM_G_FLOAT(OFS_RETURN) = -1;
        if(!stringbuffer)
        {
-               VM_Warning("VM_bufstr_add: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+               VM_Warning(prog, "VM_bufstr_add: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), prog->name);
                return;
        }
        if(!PRVM_G_INT(OFS_PARM1)) // NULL string
        {
-               VM_Warning("VM_bufstr_add: can not add an empty string to buffer %i in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+               VM_Warning(prog, "VM_bufstr_add: can not add an empty string to buffer %i in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), prog->name);
                return;
        }
        string = PRVM_G_STRING(OFS_PARM1);
@@ -4949,7 +4916,7 @@ void VM_bufstr_add (void)
                        if (stringbuffer->strings[strindex] == NULL)
                                break;
 
-       BufStr_Expand(stringbuffer, strindex);
+       BufStr_Expand(prog, stringbuffer, strindex);
 
        stringbuffer->num_strings = max(stringbuffer->num_strings, strindex + 1);
        alloclen = strlen(string) + 1;
@@ -4966,7 +4933,7 @@ delete string from buffer
 void bufstr_free(float bufhandle, float string_index) = #468;
 ========================
 */
-void VM_bufstr_free (void)
+void VM_bufstr_free (prvm_prog_t *prog)
 {
        int                             i;
        prvm_stringbuffer_t     *stringbuffer;
@@ -4975,13 +4942,13 @@ void VM_bufstr_free (void)
        stringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, (int)PRVM_G_FLOAT(OFS_PARM0));
        if(!stringbuffer)
        {
-               VM_Warning("VM_bufstr_free: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+               VM_Warning(prog, "VM_bufstr_free: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), prog->name);
                return;
        }
        i = (int)PRVM_G_FLOAT(OFS_PARM1);
        if(i < 0)
        {
-               VM_Warning("VM_bufstr_free: invalid string index %i used in %s\n", i, PRVM_NAME);
+               VM_Warning(prog, "VM_bufstr_free: invalid string index %i used in %s\n", i, prog->name);
                return;
        }
 
@@ -4992,7 +4959,7 @@ void VM_bufstr_free (void)
                stringbuffer->strings[i] = NULL;
        }
 
-       BufStr_Shrink(stringbuffer);
+       BufStr_Shrink(prog, stringbuffer);
 }
 
 
@@ -5001,7 +4968,7 @@ void VM_bufstr_free (void)
 
 
 
-void VM_buf_cvarlist(void)
+void VM_buf_cvarlist(prvm_prog_t *prog)
 {
        cvar_t *cvar;
        const char *partial, *antipartial;
@@ -5015,7 +4982,7 @@ void VM_buf_cvarlist(void)
        stringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, (int)PRVM_G_FLOAT(OFS_PARM0));
        if(!stringbuffer)
        {
-               VM_Warning("VM_bufstr_free: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+               VM_Warning(prog, "VM_bufstr_free: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), prog->name);
                return;
        }
 
@@ -5089,24 +5056,24 @@ VM_changeyaw
 This was a major timewaster in progs, so it was converted to C
 ==============
 */
-void VM_changeyaw (void)
+void VM_changeyaw (prvm_prog_t *prog)
 {
        prvm_edict_t            *ent;
        float           ideal, current, move, speed;
 
-       // this is called (VERY HACKISHLY) by SV_MoveToGoal, so it can not use any
-       // parameters because they are the parameters to SV_MoveToGoal, not this
+       // this is called (VERY HACKISHLY) by VM_SV_MoveToGoal, so it can not use any
+       // parameters because they are the parameters to VM_SV_MoveToGoal, not this
        //VM_SAFEPARMCOUNT(0, VM_changeyaw);
 
        ent = PRVM_PROG_TO_EDICT(PRVM_gameglobaledict(self));
        if (ent == prog->edicts)
        {
-               VM_Warning("changeyaw: can not modify world entity\n");
+               VM_Warning(prog, "changeyaw: can not modify world entity\n");
                return;
        }
        if (ent->priv.server->free)
        {
-               VM_Warning("changeyaw: can not modify free entity\n");
+               VM_Warning(prog, "changeyaw: can not modify free entity\n");
                return;
        }
        current = PRVM_gameedictvector(ent, angles)[1];
@@ -5147,7 +5114,7 @@ void VM_changeyaw (void)
 VM_changepitch
 ==============
 */
-void VM_changepitch (void)
+void VM_changepitch (prvm_prog_t *prog)
 {
        prvm_edict_t            *ent;
        float           ideal, current, move, speed;
@@ -5157,12 +5124,12 @@ void VM_changepitch (void)
        ent = PRVM_G_EDICT(OFS_PARM0);
        if (ent == prog->edicts)
        {
-               VM_Warning("changepitch: can not modify world entity\n");
+               VM_Warning(prog, "changepitch: can not modify world entity\n");
                return;
        }
        if (ent->priv.server->free)
        {
-               VM_Warning("changepitch: can not modify free entity\n");
+               VM_Warning(prog, "changepitch: can not modify free entity\n");
                return;
        }
        current = PRVM_gameedictvector(ent, angles)[0];
@@ -5199,7 +5166,7 @@ void VM_changepitch (void)
 }
 
 
-void VM_uncolorstring (void)
+void VM_uncolorstring (prvm_prog_t *prog)
 {
        char szNewString[VM_STRINGTEMP_LENGTH];
        const char *szString;
@@ -5208,13 +5175,13 @@ void VM_uncolorstring (void)
        VM_SAFEPARMCOUNT(1, VM_uncolorstring);
        szString = PRVM_G_STRING(OFS_PARM0);
        COM_StringDecolorize(szString, 0, szNewString, sizeof(szNewString), TRUE);
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(szNewString);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, szNewString);
        
 }
 
 // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
 //strstr, without generating a new string. Use in conjunction with FRIK_FILE's substring for more similar strstr.
-void VM_strstrofs (void)
+void VM_strstrofs (prvm_prog_t *prog)
 {
        const char *instr, *match;
        int firstofs;
@@ -5238,7 +5205,7 @@ void VM_strstrofs (void)
 }
 
 //#222 string(string s, float index) str2chr (FTE_STRINGS)
-void VM_str2chr (void)
+void VM_str2chr (prvm_prog_t *prog)
 {
        const char *s;
        Uchar ch;
@@ -5260,7 +5227,7 @@ void VM_str2chr (void)
 }
 
 //#223 string(float c, ...) chr2str (FTE_STRINGS)
-void VM_chr2str (void)
+void VM_chr2str (prvm_prog_t *prog)
 {
        /*
        char    t[9];
@@ -5269,7 +5236,7 @@ void VM_chr2str (void)
        for(i = 0;i < prog->argc && i < (int)sizeof(t) - 1;i++)
                t[i] = (unsigned char)PRVM_G_FLOAT(OFS_PARM0+i*3);
        t[i] = 0;
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(t);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, t);
        */
        char t[9 * 4 + 1];
        int i;
@@ -5278,7 +5245,7 @@ void VM_chr2str (void)
        for(i = 0; i < prog->argc && len < sizeof(t)-1; ++i)
                len += u8_fromchar((Uchar)PRVM_G_FLOAT(OFS_PARM0+i*3), t + len, sizeof(t)-1);
        t[len] = 0;
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(t);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, t);
 }
 
 static int chrconv_number(int i, int base, int conv)
@@ -5363,7 +5330,7 @@ static int chrchar_alpha(int i, int basec, int baset, int convc, int convt, int
 }
 // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
 //bulk convert a string. change case or colouring.
-void VM_strconv (void)
+void VM_strconv (prvm_prog_t *prog)
 {
        int ccase, redalpha, rednum, len, i;
        unsigned char resbuf[VM_STRINGTEMP_LENGTH];
@@ -5374,7 +5341,7 @@ void VM_strconv (void)
        ccase = (int) PRVM_G_FLOAT(OFS_PARM0);  //0 same, 1 lower, 2 upper
        redalpha = (int) PRVM_G_FLOAT(OFS_PARM1);       //0 same, 1 white, 2 red,  5 alternate, 6 alternate-alternate
        rednum = (int) PRVM_G_FLOAT(OFS_PARM2); //0 same, 1 white, 2 red, 3 redspecial, 4 whitespecial, 5 alternate, 6 alternate-alternate
-       VM_VarString(3, (char *) resbuf, sizeof(resbuf));
+       VM_VarString(prog, 3, (char *) resbuf, sizeof(resbuf));
        len = strlen((char *) resbuf);
 
        for (i = 0; i < len; i++, result++)     //should this be done backwards?
@@ -5406,29 +5373,29 @@ void VM_strconv (void)
        }
        *result = '\0';
 
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString((char *) resbuf);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, (char *) resbuf);
 }
 
 // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
-void VM_strpad (void)
+void VM_strpad (prvm_prog_t *prog)
 {
        char src[VM_STRINGTEMP_LENGTH];
        char destbuf[VM_STRINGTEMP_LENGTH];
        int pad;
        VM_SAFEPARMCOUNTRANGE(1, 8, VM_strpad);
        pad = (int) PRVM_G_FLOAT(OFS_PARM0);
-       VM_VarString(1, src, sizeof(src));
+       VM_VarString(prog, 1, src, sizeof(src));
 
        // note: < 0 = left padding, > 0 = right padding,
        // this is reverse logic of printf!
        dpsnprintf(destbuf, sizeof(destbuf), "%*s", -pad, src);
 
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(destbuf);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, destbuf);
 }
 
 // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
 //uses qw style \key\value strings
-void VM_infoadd (void)
+void VM_infoadd (prvm_prog_t *prog)
 {
        const char *info, *key;
        char value[VM_STRINGTEMP_LENGTH];
@@ -5437,18 +5404,18 @@ void VM_infoadd (void)
        VM_SAFEPARMCOUNTRANGE(2, 8, VM_infoadd);
        info = PRVM_G_STRING(OFS_PARM0);
        key = PRVM_G_STRING(OFS_PARM1);
-       VM_VarString(2, value, sizeof(value));
+       VM_VarString(prog, 2, value, sizeof(value));
 
        strlcpy(temp, info, VM_STRINGTEMP_LENGTH);
 
        InfoString_SetValue(temp, VM_STRINGTEMP_LENGTH, key, value);
 
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(temp);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, temp);
 }
 
 // #227 string(string info, string key) infoget (FTE_STRINGS)
 //uses qw style \key\value strings
-void VM_infoget (void)
+void VM_infoget (prvm_prog_t *prog)
 {
        const char *info;
        const char *key;
@@ -5460,12 +5427,12 @@ void VM_infoget (void)
 
        InfoString_GetValue(info, key, value, VM_STRINGTEMP_LENGTH);
 
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(value);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, value);
 }
 
 //#228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
 // also float(string s1, string s2) strcmp (FRIK_FILE)
-void VM_strncmp (void)
+void VM_strncmp (prvm_prog_t *prog)
 {
        const char *s1, *s2;
        VM_SAFEPARMCOUNTRANGE(2, 3, VM_strncmp);
@@ -5483,7 +5450,7 @@ void VM_strncmp (void)
 
 // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
 // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
-void VM_strncasecmp (void)
+void VM_strncasecmp (prvm_prog_t *prog)
 {
        const char *s1, *s2;
        VM_SAFEPARMCOUNTRANGE(2, 3, VM_strncasecmp);
@@ -5500,33 +5467,33 @@ void VM_strncasecmp (void)
 }
 
 // #494 float(float caseinsensitive, string s, ...) crc16
-void VM_crc16(void)
+void VM_crc16(prvm_prog_t *prog)
 {
        float insensitive;
-       static char s[VM_STRINGTEMP_LENGTH];
+       char s[VM_STRINGTEMP_LENGTH];
        VM_SAFEPARMCOUNTRANGE(2, 8, VM_crc16);
        insensitive = PRVM_G_FLOAT(OFS_PARM0);
-       VM_VarString(1, s, sizeof(s));
+       VM_VarString(prog, 1, s, sizeof(s));
        PRVM_G_FLOAT(OFS_RETURN) = (unsigned short) ((insensitive ? CRC_Block_CaseInsensitive : CRC_Block) ((unsigned char *) s, strlen(s)));
 }
 
 // #639 float(string digest, string data, ...) digest_hex
-void VM_digest_hex(void)
+void VM_digest_hex(prvm_prog_t *prog)
 {
        const char *digest;
 
-       static char out[32];
-       static char outhex[65];
+       char out[32];
+       char outhex[65];
        int outlen;
 
-       static char s[VM_STRINGTEMP_LENGTH];
+       char s[VM_STRINGTEMP_LENGTH];
        int len;
 
        VM_SAFEPARMCOUNTRANGE(2, 8, VM_digest_hex);
        digest = PRVM_G_STRING(OFS_PARM0);
        if(!digest)
                digest = "";
-       VM_VarString(1, s, sizeof(s));
+       VM_VarString(prog, 1, s, sizeof(s));
        len = strlen(s);
 
        outlen = 0;
@@ -5553,19 +5520,19 @@ void VM_digest_hex(void)
                        outhex[2*i+1] = hexmap[(out[i] >> 0) & 15];
                }
                outhex[2*i] = 0;
-               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(outhex);
+               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, outhex);
        }
        else
                PRVM_G_INT(OFS_RETURN) = 0;
 }
 
-void VM_wasfreed (void)
+void VM_wasfreed (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_wasfreed);
        PRVM_G_FLOAT(OFS_RETURN) = PRVM_G_EDICT(OFS_PARM0)->priv.required->free;
 }
 
-void VM_SetTraceGlobals(const trace_t *trace)
+void VM_SetTraceGlobals(prvm_prog_t *prog, const trace_t *trace)
 {
        PRVM_gameglobalfloat(trace_allsolid) = trace->allsolid;
        PRVM_gameglobalfloat(trace_startsolid) = trace->startsolid;
@@ -5579,10 +5546,10 @@ void VM_SetTraceGlobals(const trace_t *trace)
        PRVM_gameglobalfloat(trace_dpstartcontents) = trace->startsupercontents;
        PRVM_gameglobalfloat(trace_dphitcontents) = trace->hitsupercontents;
        PRVM_gameglobalfloat(trace_dphitq3surfaceflags) = trace->hitq3surfaceflags;
-       PRVM_gameglobalstring(trace_dphittexturename) = trace->hittexture ? PRVM_SetTempString(trace->hittexture->name) : 0;
+       PRVM_gameglobalstring(trace_dphittexturename) = trace->hittexture ? PRVM_SetTempString(prog, trace->hittexture->name) : 0;
 }
 
-void VM_ClearTraceGlobals(void)
+void VM_ClearTraceGlobals(prvm_prog_t *prog)
 {
        // clean up all trace globals when leaving the VM (anti-triggerbot safeguard)
        PRVM_gameglobalfloat(trace_allsolid) = 0;
@@ -5602,25 +5569,23 @@ void VM_ClearTraceGlobals(void)
 
 //=============
 
-void VM_Cmd_Init(void)
+void VM_Cmd_Init(prvm_prog_t *prog)
 {
        // only init the stuff for the current prog
-       VM_Files_Init();
-       VM_Search_Init();
-//     VM_BufStr_Init();
+       VM_Files_Init(prog);
+       VM_Search_Init(prog);
 }
 
-void VM_Cmd_Reset(void)
+void VM_Cmd_Reset(prvm_prog_t *prog)
 {
        CL_PurgeOwner( MENUOWNER );
-       VM_Search_Reset();
-       VM_Files_CloseAll();
-//     VM_BufStr_ShutDown();
+       VM_Search_Reset(prog);
+       VM_Files_CloseAll(prog);
 }
 
 // #510 string(string input, ...) uri_escape (DP_QC_URI_ESCAPE)
 // does URI escaping on a string (replace evil stuff by %AB escapes)
-void VM_uri_escape (void)
+void VM_uri_escape (prvm_prog_t *prog)
 {
        char src[VM_STRINGTEMP_LENGTH];
        char dest[VM_STRINGTEMP_LENGTH];
@@ -5628,7 +5593,7 @@ void VM_uri_escape (void)
        static const char *hex = "0123456789ABCDEF";
 
        VM_SAFEPARMCOUNTRANGE(1, 8, VM_uri_escape);
-       VM_VarString(0, src, sizeof(src));
+       VM_VarString(prog, 0, src, sizeof(src));
 
        for(p = src, q = dest; *p && q < dest + sizeof(dest) - 3; ++p)
        {
@@ -5648,12 +5613,12 @@ void VM_uri_escape (void)
        }
        *q++ = 0;
 
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(dest);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, dest);
 }
 
 // #510 string(string input, ...) uri_unescape (DP_QC_URI_ESCAPE)
 // does URI unescaping on a string (get back the evil stuff)
-void VM_uri_unescape (void)
+void VM_uri_unescape (prvm_prog_t *prog)
 {
        char src[VM_STRINGTEMP_LENGTH];
        char dest[VM_STRINGTEMP_LENGTH];
@@ -5661,7 +5626,7 @@ void VM_uri_unescape (void)
        int hi, lo;
 
        VM_SAFEPARMCOUNTRANGE(1, 8, VM_uri_unescape);
-       VM_VarString(0, src, sizeof(src));
+       VM_VarString(prog, 0, src, sizeof(src));
 
        for(p = src, q = dest; *p; ) // no need to check size, because unescape can't expand
        {
@@ -5695,12 +5660,12 @@ nohex:
        }
        *q++ = 0;
 
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(dest);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, dest);
 }
 
 // #502 string(string filename) whichpack (DP_QC_WHICHPACK)
 // returns the name of the pack containing a file, or "" if it is not in any pack (but local or non-existant)
-void VM_whichpack (void)
+void VM_whichpack (prvm_prog_t *prog)
 {
        const char *fn, *pack;
 
@@ -5708,12 +5673,12 @@ void VM_whichpack (void)
        fn = PRVM_G_STRING(OFS_PARM0);
        pack = FS_WhichPack(fn);
 
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(pack ? pack : "");
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, pack ? pack : "");
 }
 
 typedef struct
 {
-       int prognr;
+       prvm_prog_t *prog;
        double starttime;
        float id;
        char buffer[MAX_INPUTLINE];
@@ -5726,9 +5691,11 @@ uri_to_prog_t;
 
 static void uri_to_string_callback(int status, size_t length_received, unsigned char *buffer, void *cbdata)
 {
+       prvm_prog_t *prog;
        uri_to_prog_t *handle = (uri_to_prog_t *) cbdata;
 
-       if(!PRVM_ProgLoaded(handle->prognr))
+       prog = handle->prog;
+       if(!prog->loaded)
        {
                // curl reply came too late... so just drop it
                if(handle->postdata)
@@ -5738,22 +5705,19 @@ static void uri_to_string_callback(int status, size_t length_received, unsigned
                Z_Free(handle);
                return;
        }
-               
-       PRVM_SetProg(handle->prognr);
-       PRVM_Begin;
-               if((prog->starttime == handle->starttime) && (PRVM_allfunction(URI_Get_Callback)))
-               {
-                       if(length_received >= sizeof(handle->buffer))
-                               length_received = sizeof(handle->buffer) - 1;
-                       handle->buffer[length_received] = 0;
-               
-                       PRVM_G_FLOAT(OFS_PARM0) = handle->id;
-                       PRVM_G_FLOAT(OFS_PARM1) = status;
-                       PRVM_G_INT(OFS_PARM2) = PRVM_SetTempString(handle->buffer);
-                       PRVM_ExecuteProgram(PRVM_allfunction(URI_Get_Callback), "QC function URI_Get_Callback is missing");
-               }
-       PRVM_End;
-       
+
+       if((prog->starttime == handle->starttime) && (PRVM_allfunction(URI_Get_Callback)))
+       {
+               if(length_received >= sizeof(handle->buffer))
+                       length_received = sizeof(handle->buffer) - 1;
+               handle->buffer[length_received] = 0;
+
+               PRVM_G_FLOAT(OFS_PARM0) = handle->id;
+               PRVM_G_FLOAT(OFS_PARM1) = status;
+               PRVM_G_INT(OFS_PARM2) = PRVM_SetTempString(prog, handle->buffer);
+               prog->ExecuteProgram(prog, PRVM_allfunction(URI_Get_Callback), "QC function URI_Get_Callback is missing");
+       }
+
        if(handle->postdata)
                Z_Free(handle->postdata);
        if(handle->sigdata)
@@ -5763,7 +5727,7 @@ static void uri_to_string_callback(int status, size_t length_received, unsigned
 
 // uri_get() gets content from an URL and calls a callback "uri_get_callback" with it set as string; an unique ID of the transfer is returned
 // returns 1 on success, and then calls the callback with the ID, 0 or the HTTP status code, and the received data in a string
-void VM_uri_get (void)
+void VM_uri_get (prvm_prog_t *prog)
 {
        const char *url;
        float id;
@@ -5777,7 +5741,7 @@ void VM_uri_get (void)
        size_t lq;
 
        if(!PRVM_allfunction(URI_Get_Callback))
-               PRVM_ERROR("uri_get called by %s without URI_Get_Callback defined", PRVM_NAME);
+               prog->error_cmd("uri_get called by %s without URI_Get_Callback defined", prog->name);
 
        VM_SAFEPARMCOUNTRANGE(2, 6, VM_uri_get);
 
@@ -5798,7 +5762,7 @@ void VM_uri_get (void)
                ++query_string;
        lq = query_string ? strlen(query_string) : 0;
 
-       handle->prognr = PRVM_GetProgNr();
+       handle->prog = prog;
        handle->starttime = prog->starttime;
        handle->id = id;
        if(postseparator && posttype && *posttype)
@@ -5813,7 +5777,7 @@ void VM_uri_get (void)
                        stringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, poststringbuffer);
                        if(!stringbuffer)
                        {
-                               VM_Warning("uri_get: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+                               VM_Warning(prog, "uri_get: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), prog->name);
                                return;
                        }
                        ltotal = 0;
@@ -5841,7 +5805,7 @@ void VM_uri_get (void)
                                }
                        }
                        if(ltotal != handle->postlen)
-                               PRVM_ERROR ("%s: string buffer content size mismatch, possible overrun", PRVM_NAME);
+                               prog->error_cmd("%s: string buffer content size mismatch, possible overrun", prog->name);
                }
                else
                {
@@ -5925,7 +5889,7 @@ out2:
        }
 }
 
-void VM_netaddress_resolve (void)
+void VM_netaddress_resolve (prvm_prog_t *prog)
 {
        const char *ip;
        char normalized[128];
@@ -5940,13 +5904,13 @@ void VM_netaddress_resolve (void)
                port = (int) PRVM_G_FLOAT(OFS_PARM1);
 
        if(LHNETADDRESS_FromString(&addr, ip, port) && LHNETADDRESS_ToString(&addr, normalized, sizeof(normalized), prog->argc > 1))
-               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(normalized);
+               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, normalized);
        else
-               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString("");
+               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, "");
 }
 
-//string(void) getextresponse = #624; // returns the next extResponse packet that was sent to this client
-void VM_CL_getextresponse (void)
+//string(prvm_prog_t *prog) getextresponse = #624; // returns the next extResponse packet that was sent to this client
+void VM_CL_getextresponse (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0,VM_argv);
 
@@ -5957,11 +5921,11 @@ void VM_CL_getextresponse (void)
                int first;
                --cl_net_extresponse_count;
                first = (cl_net_extresponse_last + NET_EXTRESPONSE_MAX - cl_net_extresponse_count) % NET_EXTRESPONSE_MAX;
-               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(cl_net_extresponse[first]);
+               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, cl_net_extresponse[first]);
        }
 }
 
-void VM_SV_getextresponse (void)
+void VM_SV_getextresponse (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0,VM_argv);
 
@@ -5972,7 +5936,7 @@ void VM_SV_getextresponse (void)
                int first;
                --sv_net_extresponse_count;
                first = (sv_net_extresponse_last + NET_EXTRESPONSE_MAX - sv_net_extresponse_count) % NET_EXTRESPONSE_MAX;
-               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(sv_net_extresponse[first]);
+               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, sv_net_extresponse[first]);
        }
 }
 
@@ -5983,14 +5947,14 @@ Common functions between menu.dat and clsprogs
 */
 
 //#349 float() isdemo 
-void VM_CL_isdemo (void)
+void VM_CL_isdemo (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0, VM_CL_isdemo);
        PRVM_G_FLOAT(OFS_RETURN) = cls.demoplayback;
 }
 
 //#355 float() videoplaying 
-void VM_CL_videoplaying (void)
+void VM_CL_videoplaying (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0, VM_CL_videoplaying);
        PRVM_G_FLOAT(OFS_RETURN) = cl_videoplaying;
@@ -6004,8 +5968,7 @@ VM_M_callfunction
 Extension: pass
 =========
 */
-mfunction_t *PRVM_ED_FindFunction (const char *name);
-void VM_callfunction(void)
+void VM_callfunction(prvm_prog_t *prog)
 {
        mfunction_t *func;
        const char *s;
@@ -6014,26 +5977,26 @@ void VM_callfunction(void)
 
        s = PRVM_G_STRING(OFS_PARM0+(prog->argc - 1)*3);
 
-       VM_CheckEmptyString(s);
+       VM_CheckEmptyString(prog, s);
 
-       func = PRVM_ED_FindFunction(s);
+       func = PRVM_ED_FindFunction(prog, s);
 
        if(!func)
-               PRVM_ERROR("VM_callfunciton: function %s not found !", s);
+               prog->error_cmd("VM_callfunciton: function %s not found !", s);
        else if (func->first_statement < 0)
        {
                // negative statements are built in functions
                int builtinnumber = -func->first_statement;
                prog->xfunction->builtinsprofile++;
                if (builtinnumber < prog->numbuiltins && prog->builtins[builtinnumber])
-                       prog->builtins[builtinnumber]();
+                       prog->builtins[builtinnumber](prog);
                else
-                       PRVM_ERROR("No such builtin #%i in %s; most likely cause: outdated engine build. Try updating!", builtinnumber, PRVM_NAME);
+                       prog->error_cmd("No such builtin #%i in %s; most likely cause: outdated engine build. Try updating!", builtinnumber, prog->name);
        }
        else if(func - prog->functions > 0)
        {
                prog->argc--;
-               PRVM_ExecuteProgram(func - prog->functions,"");
+               prog->ExecuteProgram(prog, func - prog->functions,"");
                prog->argc++;
        }
 }
@@ -6045,8 +6008,7 @@ VM_isfunction
 float  isfunction(string function_name)
 =========
 */
-mfunction_t *PRVM_ED_FindFunction (const char *name);
-void VM_isfunction(void)
+void VM_isfunction(prvm_prog_t *prog)
 {
        mfunction_t *func;
        const char *s;
@@ -6055,9 +6017,9 @@ void VM_isfunction(void)
 
        s = PRVM_G_STRING(OFS_PARM0);
 
-       VM_CheckEmptyString(s);
+       VM_CheckEmptyString(prog, s);
 
-       func = PRVM_ED_FindFunction(s);
+       func = PRVM_ED_FindFunction(prog, s);
 
        if(!func)
                PRVM_G_FLOAT(OFS_RETURN) = false;
@@ -6073,7 +6035,7 @@ string sprintf(string format, ...)
 =========
 */
 
-void VM_sprintf(void)
+void VM_sprintf(prvm_prog_t *prog)
 {
        const char *s, *s0;
        char outbuf[MAX_INPUTLINE];
@@ -6085,6 +6047,7 @@ void VM_sprintf(void)
        int isfloat;
        static int dummyivec[3] = {0, 0, 0};
        static float dummyvec[3] = {0, 0, 0};
+       char vabuf[1024];
 
 #define PRINTF_ALTERNATE 1
 #define PRINTF_ZEROPAD 2
@@ -6130,7 +6093,7 @@ void VM_sprintf(void)
                                        width = strtol(s, &err, 10);
                                        if(!err)
                                        {
-                                               VM_Warning("VM_sprintf: invalid directive in %s: %s\n", PRVM_NAME, s0);
+                                               VM_Warning(prog, "VM_sprintf: invalid directive in %s: %s\n", prog->name, s0);
                                                goto finished;
                                        }
                                        if(*err == '$')
@@ -6176,7 +6139,7 @@ noflags:
                                                        width = strtol(s, &err, 10);
                                                        if(!err || *err != '$')
                                                        {
-                                                               VM_Warning("VM_sprintf: invalid directive in %s: %s\n", PRVM_NAME, s0);
+                                                               VM_Warning(prog, "VM_sprintf: invalid directive in %s: %s\n", prog->name, s0);
                                                                goto finished;
                                                        }
                                                        s = err + 1;
@@ -6195,7 +6158,7 @@ noflags:
                                                width = strtol(s, &err, 10);
                                                if(!err)
                                                {
-                                                       VM_Warning("VM_sprintf: invalid directive in %s: %s\n", PRVM_NAME, s0);
+                                                       VM_Warning(prog, "VM_sprintf: invalid directive in %s: %s\n", prog->name, s0);
                                                        goto finished;
                                                }
                                                s = err;
@@ -6219,7 +6182,7 @@ noflags:
                                                        precision = strtol(s, &err, 10);
                                                        if(!err || *err != '$')
                                                        {
-                                                               VM_Warning("VM_sprintf: invalid directive in %s: %s\n", PRVM_NAME, s0);
+                                                               VM_Warning(prog, "VM_sprintf: invalid directive in %s: %s\n", prog->name, s0);
                                                                goto finished;
                                                        }
                                                        s = err + 1;
@@ -6233,14 +6196,14 @@ noflags:
                                                precision = strtol(s, &err, 10);
                                                if(!err)
                                                {
-                                                       VM_Warning("VM_sprintf: invalid directive in %s: %s\n", PRVM_NAME, s0);
+                                                       VM_Warning(prog, "VM_sprintf: invalid directive in %s: %s\n", prog->name, s0);
                                                        goto finished;
                                                }
                                                s = err;
                                        }
                                        else
                                        {
-                                               VM_Warning("VM_sprintf: invalid directive in %s: %s\n", PRVM_NAME, s0);
+                                               VM_Warning(prog, "VM_sprintf: invalid directive in %s: %s\n", prog->name, s0);
                                                goto finished;
                                        }
                                }
@@ -6318,13 +6281,13 @@ nolength:
                                                case 'v': case 'V':
                                                        f[-2] += 'g' - 'v';
                                                        if(precision < 0) // not set
-                                                               o += dpsnprintf(o, end - o, va("%s %s %s", /* NESTED SPRINTF IS NESTED */ formatbuf, formatbuf, formatbuf),
+                                                               o += dpsnprintf(o, end - o, va(vabuf, sizeof(vabuf), "%s %s %s", /* NESTED SPRINTF IS NESTED */ formatbuf, formatbuf, formatbuf),
                                                                        width, (isfloat ? (double) GETARG_VECTOR(thisarg)[0] : (double) GETARG_INTVECTOR(thisarg)[0]),
                                                                        width, (isfloat ? (double) GETARG_VECTOR(thisarg)[1] : (double) GETARG_INTVECTOR(thisarg)[1]),
                                                                        width, (isfloat ? (double) GETARG_VECTOR(thisarg)[2] : (double) GETARG_INTVECTOR(thisarg)[2])
                                                                );
                                                        else
-                                                               o += dpsnprintf(o, end - o, va("%s %s %s", /* NESTED SPRINTF IS NESTED */ formatbuf, formatbuf, formatbuf),
+                                                               o += dpsnprintf(o, end - o, va(vabuf, sizeof(vabuf), "%s %s %s", /* NESTED SPRINTF IS NESTED */ formatbuf, formatbuf, formatbuf),
                                                                        width, precision, (isfloat ? (double) GETARG_VECTOR(thisarg)[0] : (double) GETARG_INTVECTOR(thisarg)[0]),
                                                                        width, precision, (isfloat ? (double) GETARG_VECTOR(thisarg)[1] : (double) GETARG_INTVECTOR(thisarg)[1]),
                                                                        width, precision, (isfloat ? (double) GETARG_VECTOR(thisarg)[2] : (double) GETARG_INTVECTOR(thisarg)[2])
@@ -6341,7 +6304,8 @@ nolength:
                                                        else
                                                        {
                                                                unsigned int c = (isfloat ? (unsigned int) GETARG_FLOAT(thisarg) : (unsigned int) GETARG_INT(thisarg));
-                                                               const char *buf = u8_encodech(c, NULL);
+                                                               char charbuf16[16];
+                                                               const char *buf = u8_encodech(c, NULL, charbuf16);
                                                                if(!buf)
                                                                        buf = "";
                                                                if(precision < 0) // not set
@@ -6365,7 +6329,7 @@ nolength:
                                                        }
                                                        break;
                                                default:
-                                                       VM_Warning("VM_sprintf: invalid directive in %s: %s\n", PRVM_NAME, s0);
+                                                       VM_Warning(prog, "VM_sprintf: invalid directive in %s: %s\n", prog->name, s0);
                                                        goto finished;
                                        }
                                }
@@ -6380,23 +6344,20 @@ verbatim:
        }
 finished:
        *o = 0;
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(outbuf);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, outbuf);
 }
 
 
 // surface querying
 
-static dp_model_t *getmodel(prvm_edict_t *ed)
+static dp_model_t *getmodel(prvm_prog_t *prog, prvm_edict_t *ed)
 {
-       switch(PRVM_GetProgNr())
-       {
-               case PRVM_SERVERPROG:
-                       return SV_GetModelFromEdict(ed);
-               case PRVM_CLIENTPROG:
-                       return CL_GetModelFromEdict(ed);
-               default:
-                       return NULL;
-       }
+       if (prog == SVVM_prog)
+               return SV_GetModelFromEdict(ed);
+       else if (prog == CLVM_prog)
+               return CL_GetModelFromEdict(ed);
+       else
+               return NULL;
 }
 
 typedef struct
@@ -6419,7 +6380,7 @@ typedef struct
 animatemodel_cache_t;
 static animatemodel_cache_t animatemodel_cache;
 
-void animatemodel(dp_model_t *model, prvm_edict_t *ed)
+static void animatemodel(prvm_prog_t *prog, dp_model_t *model, prvm_edict_t *ed)
 {
        skeleton_t *skeleton;
        int skeletonindex = -1;
@@ -6435,7 +6396,7 @@ void animatemodel(dp_model_t *model, prvm_edict_t *ed)
        if(animatemodel_cache.progid != prog->id)
                memset(&animatemodel_cache, 0, sizeof(animatemodel_cache));
        need |= (animatemodel_cache.model != model);
-       VM_GenerateFrameGroupBlend(ed->priv.server->framegroupblend, ed);
+       VM_GenerateFrameGroupBlend(prog, ed->priv.server->framegroupblend, ed);
        VM_FrameBlendFromFrameGroupBlend(ed->priv.server->frameblend, ed->priv.server->framegroupblend, model);
        need |= (memcmp(&animatemodel_cache.frameblend, &ed->priv.server->frameblend, sizeof(ed->priv.server->frameblend))) != 0;
        skeletonindex = (int)PRVM_gameedictfloat(ed, skeletonindex) - 1;
@@ -6462,7 +6423,7 @@ void animatemodel(dp_model_t *model, prvm_edict_t *ed)
        animatemodel_cache.data_svector3f = animatemodel_cache.buf_svector3f;
        animatemodel_cache.data_tvector3f = animatemodel_cache.buf_tvector3f;
        animatemodel_cache.data_normal3f = animatemodel_cache.buf_normal3f;
-       VM_UpdateEdictSkeleton(ed, model, ed->priv.server->frameblend);
+       VM_UpdateEdictSkeleton(prog, ed, model, ed->priv.server->frameblend);
        model->AnimateVertices(model, ed->priv.server->frameblend, &ed->priv.server->skeleton, animatemodel_cache.data_vertex3f, animatemodel_cache.data_normal3f, animatemodel_cache.data_svector3f, animatemodel_cache.data_tvector3f);
        animatemodel_cache.progid = prog->id;
        animatemodel_cache.model = model;
@@ -6472,59 +6433,53 @@ void animatemodel(dp_model_t *model, prvm_edict_t *ed)
                memcpy(&animatemodel_cache.skeleton, skeleton, sizeof(ed->priv.server->skeleton));
 }
 
-static void getmatrix(prvm_edict_t *ed, matrix4x4_t *out)
+static void getmatrix(prvm_prog_t *prog, prvm_edict_t *ed, matrix4x4_t *out)
 {
-       switch(PRVM_GetProgNr())
-       {
-               case PRVM_SERVERPROG:
-                       SV_GetEntityMatrix(ed, out, false);
-                       break;
-               case PRVM_CLIENTPROG:
-                       CL_GetEntityMatrix(ed, out, false);
-                       break;
-               default:
-                       *out = identitymatrix;
-                       break;
-       }
+       if (prog == SVVM_prog)
+               SV_GetEntityMatrix(prog, ed, out, false);
+       else if (prog == CLVM_prog)
+               CL_GetEntityMatrix(prog, ed, out, false);
+       else
+               *out = identitymatrix;
 }
 
-static void applytransform_forward(const vec3_t in, prvm_edict_t *ed, vec3_t out)
+static void applytransform_forward(prvm_prog_t *prog, const vec3_t in, prvm_edict_t *ed, vec3_t out)
 {
        matrix4x4_t m;
-       getmatrix(ed, &m);
+       getmatrix(prog, ed, &m);
        Matrix4x4_Transform(&m, in, out);
 }
 
-static void applytransform_forward_direction(const vec3_t in, prvm_edict_t *ed, vec3_t out)
+static void applytransform_forward_direction(prvm_prog_t *prog, const vec3_t in, prvm_edict_t *ed, vec3_t out)
 {
        matrix4x4_t m;
-       getmatrix(ed, &m);
+       getmatrix(prog, ed, &m);
        Matrix4x4_Transform3x3(&m, in, out);
 }
 
-static void applytransform_inverted(const vec3_t in, prvm_edict_t *ed, vec3_t out)
+static void applytransform_inverted(prvm_prog_t *prog, const vec3_t in, prvm_edict_t *ed, vec3_t out)
 {
        matrix4x4_t m, n;
-       getmatrix(ed, &m);
+       getmatrix(prog, ed, &m);
        Matrix4x4_Invert_Full(&n, &m);
        Matrix4x4_Transform3x3(&n, in, out);
 }
 
-static void applytransform_forward_normal(const vec3_t in, prvm_edict_t *ed, vec3_t out)
+static void applytransform_forward_normal(prvm_prog_t *prog, const vec3_t in, prvm_edict_t *ed, vec3_t out)
 {
        matrix4x4_t m;
        float p[4];
-       getmatrix(ed, &m);
+       getmatrix(prog, ed, &m);
        Matrix4x4_TransformPositivePlane(&m, in[0], in[1], in[2], 0, p);
        VectorCopy(p, out);
 }
 
-static void clippointtosurface(prvm_edict_t *ed, dp_model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
+static void clippointtosurface(prvm_prog_t *prog, prvm_edict_t *ed, dp_model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
 {
        int i, j, k;
        float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
        const int *e;
-       animatemodel(model, ed);
+       animatemodel(prog, model, ed);
        bestdist = 1000000000;
        VectorCopy(p, out);
        for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
@@ -6565,13 +6520,13 @@ static msurface_t *getsurface(dp_model_t *model, int surfacenum)
 
 
 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
-void VM_getsurfacenumpoints(void)
+void VM_getsurfacenumpoints(prvm_prog_t *prog)
 {
        dp_model_t *model;
        msurface_t *surface;
        VM_SAFEPARMCOUNT(2, VM_getsurfacenumpoints);
        // return 0 if no such surface
-       if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
+       if (!(model = getmodel(prog, PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
        {
                PRVM_G_FLOAT(OFS_RETURN) = 0;
                return;
@@ -6581,7 +6536,7 @@ void VM_getsurfacenumpoints(void)
        PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
 }
 //PF_getsurfacepoint,     // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
-void VM_getsurfacepoint(void)
+void VM_getsurfacepoint(prvm_prog_t *prog)
 {
        prvm_edict_t *ed;
        dp_model_t *model;
@@ -6590,14 +6545,14 @@ void VM_getsurfacepoint(void)
        VM_SAFEPARMCOUNT(3, VM_getsurfacepoint);
        VectorClear(PRVM_G_VECTOR(OFS_RETURN));
        ed = PRVM_G_EDICT(OFS_PARM0);
-       if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
+       if (!(model = getmodel(prog, ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
                return;
        // note: this (incorrectly) assumes it is a simple polygon
        pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
        if (pointnum < 0 || pointnum >= surface->num_vertices)
                return;
-       animatemodel(model, ed);
-       applytransform_forward(&(animatemodel_cache.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, PRVM_G_VECTOR(OFS_RETURN));
+       animatemodel(prog, model, ed);
+       applytransform_forward(prog, &(animatemodel_cache.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, PRVM_G_VECTOR(OFS_RETURN));
 }
 //PF_getsurfacepointattribute,     // #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
 // float SPA_POSITION = 0;
@@ -6607,7 +6562,7 @@ void VM_getsurfacepoint(void)
 // float SPA_TEXCOORDS0 = 4;
 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
 // float SPA_LIGHTMAP0_COLOR = 6;
-void VM_getsurfacepointattribute(void)
+void VM_getsurfacepointattribute(prvm_prog_t *prog)
 {
        prvm_edict_t *ed;
        dp_model_t *model;
@@ -6618,31 +6573,31 @@ void VM_getsurfacepointattribute(void)
        VM_SAFEPARMCOUNT(4, VM_getsurfacepoint);
        VectorClear(PRVM_G_VECTOR(OFS_RETURN));
        ed = PRVM_G_EDICT(OFS_PARM0);
-       if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
+       if (!(model = getmodel(prog, ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
                return;
        pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
        if (pointnum < 0 || pointnum >= surface->num_vertices)
                return;
        attributetype = (int) PRVM_G_FLOAT(OFS_PARM3);
 
-       animatemodel(model, ed);
+       animatemodel(prog, model, ed);
 
        switch( attributetype ) {
                // float SPA_POSITION = 0;
                case 0:
-                       applytransform_forward(&(animatemodel_cache.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, PRVM_G_VECTOR(OFS_RETURN));
+                       applytransform_forward(prog, &(animatemodel_cache.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, PRVM_G_VECTOR(OFS_RETURN));
                        break;
                // float SPA_S_AXIS = 1;
                case 1:
-                       applytransform_forward_direction(&(animatemodel_cache.data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, PRVM_G_VECTOR(OFS_RETURN));
+                       applytransform_forward_direction(prog, &(animatemodel_cache.data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, PRVM_G_VECTOR(OFS_RETURN));
                        break;
                // float SPA_T_AXIS = 2;
                case 2:
-                       applytransform_forward_direction(&(animatemodel_cache.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, PRVM_G_VECTOR(OFS_RETURN));
+                       applytransform_forward_direction(prog, &(animatemodel_cache.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, PRVM_G_VECTOR(OFS_RETURN));
                        break;
                // float SPA_R_AXIS = 3; // same as SPA_NORMAL
                case 3:
-                       applytransform_forward_direction(&(animatemodel_cache.data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, PRVM_G_VECTOR(OFS_RETURN));
+                       applytransform_forward_direction(prog, &(animatemodel_cache.data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, PRVM_G_VECTOR(OFS_RETURN));
                        break;
                // float SPA_TEXCOORDS0 = 4;
                case 4: {
@@ -6673,35 +6628,35 @@ void VM_getsurfacepointattribute(void)
        }
 }
 //PF_getsurfacenormal,    // #436 vector(entity e, float s) getsurfacenormal = #436;
-void VM_getsurfacenormal(void)
+void VM_getsurfacenormal(prvm_prog_t *prog)
 {
        dp_model_t *model;
        msurface_t *surface;
        vec3_t normal;
        VM_SAFEPARMCOUNT(2, VM_getsurfacenormal);
        VectorClear(PRVM_G_VECTOR(OFS_RETURN));
-       if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
+       if (!(model = getmodel(prog, PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
                return;
        // note: this only returns the first triangle, so it doesn't work very
        // well for curved surfaces or arbitrary meshes
-       animatemodel(model, PRVM_G_EDICT(OFS_PARM0));
+       animatemodel(prog, model, PRVM_G_EDICT(OFS_PARM0));
        TriangleNormal((animatemodel_cache.data_vertex3f + 3 * surface->num_firstvertex), (animatemodel_cache.data_vertex3f + 3 * surface->num_firstvertex) + 3, (animatemodel_cache.data_vertex3f + 3 * surface->num_firstvertex) + 6, normal);
-       applytransform_forward_normal(normal, PRVM_G_EDICT(OFS_PARM0), PRVM_G_VECTOR(OFS_RETURN));
+       applytransform_forward_normal(prog, normal, PRVM_G_EDICT(OFS_PARM0), PRVM_G_VECTOR(OFS_RETURN));
        VectorNormalize(PRVM_G_VECTOR(OFS_RETURN));
 }
 //PF_getsurfacetexture,   // #437 string(entity e, float s) getsurfacetexture = #437;
-void VM_getsurfacetexture(void)
+void VM_getsurfacetexture(prvm_prog_t *prog)
 {
        dp_model_t *model;
        msurface_t *surface;
        VM_SAFEPARMCOUNT(2, VM_getsurfacetexture);
        PRVM_G_INT(OFS_RETURN) = OFS_NULL;
-       if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
+       if (!(model = getmodel(prog, PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
                return;
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, surface->texture->name);
 }
 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
-void VM_getsurfacenearpoint(void)
+void VM_getsurfacenearpoint(prvm_prog_t *prog)
 {
        int surfacenum, best;
        vec3_t clipped, p;
@@ -6717,13 +6672,13 @@ void VM_getsurfacenearpoint(void)
 
        if (!ed || ed->priv.server->free)
                return;
-       model = getmodel(ed);
+       model = getmodel(prog, ed);
        if (!model || !model->num_surfaces)
                return;
 
-       animatemodel(model, ed);
+       animatemodel(prog, model, ed);
 
-       applytransform_inverted(point, ed, p);
+       applytransform_inverted(prog, point, ed, p);
        best = -1;
        bestdist = 1000000000;
        for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
@@ -6737,7 +6692,7 @@ void VM_getsurfacenearpoint(void)
                if (dist < bestdist)
                {
                        // it is, check the nearest point on the actual geometry
-                       clippointtosurface(ed, model, surface, p, clipped);
+                       clippointtosurface(prog, ed, model, surface, p, clipped);
                        VectorSubtract(clipped, p, clipped);
                        dist += VectorLength2(clipped);
                        if (dist < bestdist)
@@ -6751,7 +6706,7 @@ void VM_getsurfacenearpoint(void)
        PRVM_G_FLOAT(OFS_RETURN) = best;
 }
 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
-void VM_getsurfaceclippedpoint(void)
+void VM_getsurfaceclippedpoint(prvm_prog_t *prog)
 {
        prvm_edict_t *ed;
        dp_model_t *model;
@@ -6760,32 +6715,31 @@ void VM_getsurfaceclippedpoint(void)
        VM_SAFEPARMCOUNT(3, VM_te_getsurfaceclippedpoint);
        VectorClear(PRVM_G_VECTOR(OFS_RETURN));
        ed = PRVM_G_EDICT(OFS_PARM0);
-       if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
+       if (!(model = getmodel(prog, ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
                return;
-       animatemodel(model, ed);
-       applytransform_inverted(PRVM_G_VECTOR(OFS_PARM2), ed, p);
-       clippointtosurface(ed, model, surface, p, out);
+       animatemodel(prog, model, ed);
+       applytransform_inverted(prog, PRVM_G_VECTOR(OFS_PARM2), ed, p);
+       clippointtosurface(prog, ed, model, surface, p, out);
        VectorAdd(out, PRVM_serveredictvector(ed, origin), PRVM_G_VECTOR(OFS_RETURN));
 }
 
 //PF_getsurfacenumtriangles, // #??? float(entity e, float s) getsurfacenumtriangles = #???;
-void VM_getsurfacenumtriangles(void)
+void VM_getsurfacenumtriangles(prvm_prog_t *prog)
 {
        dp_model_t *model;
        msurface_t *surface;
        VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumtriangles);
        // return 0 if no such surface
-       if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
+       if (!(model = getmodel(prog, PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
        {
                PRVM_G_FLOAT(OFS_RETURN) = 0;
                return;
        }
 
-       // note: this (incorrectly) assumes it is a simple polygon
        PRVM_G_FLOAT(OFS_RETURN) = surface->num_triangles;
 }
 //PF_getsurfacetriangle,     // #??? vector(entity e, float s, float n) getsurfacetriangle = #???;
-void VM_getsurfacetriangle(void)
+void VM_getsurfacetriangle(prvm_prog_t *prog)
 {
        const vec3_t d = {-1, -1, -1};
        prvm_edict_t *ed;
@@ -6795,7 +6749,7 @@ void VM_getsurfacetriangle(void)
        VM_SAFEPARMCOUNT(3, VM_SV_getsurfacetriangle);
        VectorClear(PRVM_G_VECTOR(OFS_RETURN));
        ed = PRVM_G_EDICT(OFS_PARM0);
-       if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
+       if (!(model = getmodel(prog, ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
                return;
        trinum = (int)PRVM_G_FLOAT(OFS_PARM2);
        if (trinum < 0 || trinum >= surface->num_triangles)
@@ -6808,11 +6762,9 @@ void VM_getsurfacetriangle(void)
 // physics builtins
 //
 
-void World_Physics_ApplyCmd(prvm_edict_t *ed, edict_odefunc_t *f);
-
-#define VM_physics_ApplyCmd(ed,f) if (!ed->priv.server->ode_body) VM_physics_newstackfunction(ed, f); else World_Physics_ApplyCmd(ed, f)
+#define VM_physics_ApplyCmd(ed,f) if (!ed->priv.server->ode_body) VM_physics_newstackfunction(prog, ed, f); else World_Physics_ApplyCmd(ed, f)
 
-edict_odefunc_t *VM_physics_newstackfunction(prvm_edict_t *ed, edict_odefunc_t *f)
+static edict_odefunc_t *VM_physics_newstackfunction(prvm_prog_t *prog, prvm_edict_t *ed, edict_odefunc_t *f)
 {
        edict_odefunc_t *newfunc, *func;
 
@@ -6830,7 +6782,7 @@ edict_odefunc_t *VM_physics_newstackfunction(prvm_edict_t *ed, edict_odefunc_t *
 }
 
 // void(entity e, float physics_enabled) physics_enable = #;
-void VM_physics_enable(void)
+void VM_physics_enable(prvm_prog_t *prog)
 {
        prvm_edict_t *ed;
        edict_odefunc_t f;
@@ -6840,13 +6792,13 @@ void VM_physics_enable(void)
        if (!ed)
        {
                if (developer.integer > 0)
-                       VM_Warning("VM_physics_enable: null entity!\n");
+                       VM_Warning(prog, "VM_physics_enable: null entity!\n");
                return;
        }
        // entity should have MOVETYPE_PHYSICS already set, this can damage memory (making leaked allocation) so warn about this even if non-developer
        if (PRVM_serveredictfloat(ed, movetype) != MOVETYPE_PHYSICS)
        {
-               VM_Warning("VM_physics_enable: entity is not MOVETYPE_PHYSICS!\n");
+               VM_Warning(prog, "VM_physics_enable: entity is not MOVETYPE_PHYSICS!\n");
                return;
        }
        f.type = PRVM_G_FLOAT(OFS_PARM1) == 0 ? ODEFUNC_DISABLE : ODEFUNC_ENABLE;
@@ -6854,7 +6806,7 @@ void VM_physics_enable(void)
 }
 
 // void(entity e, vector force, vector relative_ofs) physics_addforce = #;
-void VM_physics_addforce(void)
+void VM_physics_addforce(prvm_prog_t *prog)
 {
        prvm_edict_t *ed;
        edict_odefunc_t f;
@@ -6864,13 +6816,13 @@ void VM_physics_addforce(void)
        if (!ed)
        {
                if (developer.integer > 0)
-                       VM_Warning("VM_physics_addforce: null entity!\n");
+                       VM_Warning(prog, "VM_physics_addforce: null entity!\n");
                return;
        }
        // entity should have MOVETYPE_PHYSICS already set, this can damage memory (making leaked allocation) so warn about this even if non-developer
        if (PRVM_serveredictfloat(ed, movetype) != MOVETYPE_PHYSICS)
        {
-               VM_Warning("VM_physics_addforce: entity is not MOVETYPE_PHYSICS!\n");
+               VM_Warning(prog, "VM_physics_addforce: entity is not MOVETYPE_PHYSICS!\n");
                return;
        }
        f.type = ODEFUNC_RELFORCEATPOS;
@@ -6880,7 +6832,7 @@ void VM_physics_addforce(void)
 }
 
 // void(entity e, vector torque) physics_addtorque = #;
-void VM_physics_addtorque(void)
+void VM_physics_addtorque(prvm_prog_t *prog)
 {
        prvm_edict_t *ed;
        edict_odefunc_t f;
@@ -6890,13 +6842,13 @@ void VM_physics_addtorque(void)
        if (!ed)
        {
                if (developer.integer > 0)
-                       VM_Warning("VM_physics_addtorque: null entity!\n");
+                       VM_Warning(prog, "VM_physics_addtorque: null entity!\n");
                return;
        }
        // entity should have MOVETYPE_PHYSICS already set, this can damage memory (making leaked allocation) so warn about this even if non-developer
        if (PRVM_serveredictfloat(ed, movetype) != MOVETYPE_PHYSICS)
        {
-               VM_Warning("VM_physics_addtorque: entity is not MOVETYPE_PHYSICS!\n");
+               VM_Warning(prog, "VM_physics_addtorque: entity is not MOVETYPE_PHYSICS!\n");
                return;
        }
        f.type = ODEFUNC_RELTORQUE;
index d4c1a19e58089812e7129a95e299cffe6659ff17..7679336738e70c1e039541e8700ad889b4a649a4 100644 (file)
@@ -1,3 +1,7 @@
+
+#ifndef PRVM_CMDS_H
+#define PRVM_CMDS_H
+
 // AK
 // Basically every vm builtin cmd should be in here.
 // All 3 builtin and extension lists can be found here
@@ -199,8 +203,8 @@ float       getserverlistindexforkey(string key)
 // nice helper macros
 
 #ifndef VM_NOPARMCHECK
-#define VM_SAFEPARMCOUNTRANGE(p1,p2,f) if(prog->argc < p1 || prog->argc > p2) PRVM_ERROR(#f " wrong parameter count %i (" #p1 " to " #p2 " expected ) !", prog->argc)
-#define VM_SAFEPARMCOUNT(p,f)  if(prog->argc != p) PRVM_ERROR(#f " wrong parameter count %i (" #p " expected ) !", prog->argc)
+#define VM_SAFEPARMCOUNTRANGE(p1,p2,f) if(prog->argc < p1 || prog->argc > p2) prog->error_cmd(#f " wrong parameter count %i (" #p1 " to " #p2 " expected ) !", prog->argc)
+#define VM_SAFEPARMCOUNT(p,f)  if(prog->argc != p) prog->error_cmd(#f " wrong parameter count %i (" #p " expected ) !", prog->argc)
 #else
 #define VM_SAFEPARMCOUNTRANGE(p1,p2,f)
 #define VM_SAFEPARMCOUNT(p,f)
@@ -210,271 +214,269 @@ float   getserverlistindexforkey(string key)
 
 #define VM_STRINGTEMP_LENGTH MAX_INPUTLINE
 
+// init code
+void PR_Cmd_Init(void);
+
 // builtins and other general functions
 
-void VM_CheckEmptyString (const char *s);
-void VM_VarString(int first, char *out, int outlength);
-
-void VM_checkextension (void);
-void VM_error (void);
-void VM_objerror (void);
-void VM_print (void);
-void VM_bprint (void);
-void VM_sprint (void);
-void VM_centerprint (void);
-void VM_normalize (void);
-void VM_vlen (void);
-void VM_vectoyaw (void);
-void VM_vectoangles (void);
-void VM_random (void);
-void VM_localsound(void);
-void VM_break (void);
-void VM_localcmd (void);
-void VM_cvar (void);
-void VM_cvar_string(void);
-void VM_cvar_type (void);
-void VM_cvar_defstring (void);
-void VM_cvar_set (void);
-void VM_dprint (void);
-void VM_ftos (void);
-void VM_fabs (void);
-void VM_vtos (void);
-void VM_etos (void);
-void VM_stof(void);
-void VM_itof(void);
-void VM_ftoe(void);
-void VM_strftime(void);
-void VM_spawn (void);
-void VM_remove (void);
-void VM_find (void);
-void VM_findfloat (void);
-void VM_findchain (void);
-void VM_findchainfloat (void);
-void VM_findflags (void);
-void VM_findchainflags (void);
-void VM_precache_file (void);
-void VM_precache_sound (void);
-void VM_coredump (void);
-
-void VM_stackdump (void);
-void VM_crash(void); // REMOVE IT
-void VM_traceon (void);
-void VM_traceoff (void);
-void VM_eprint (void);
-void VM_rint (void);
-void VM_floor (void);
-void VM_ceil (void);
-void VM_nextent (void);
-
-void VM_changelevel (void);
-void VM_sin (void);
-void VM_cos (void);
-void VM_sqrt (void);
-void VM_randomvec (void);
-void VM_registercvar (void);
-void VM_min (void);
-void VM_max (void);
-void VM_bound (void);
-void VM_pow (void);
-void VM_log (void);
-void VM_asin (void);
-void VM_acos (void);
-void VM_atan (void);
-void VM_atan2 (void);
-void VM_tan (void);
-
-void VM_Files_Init(void);
-void VM_Files_CloseAll(void);
-
-void VM_fopen(void);
-void VM_fclose(void);
-void VM_fgets(void);
-void VM_fputs(void);
-void VM_writetofile(void); // only used by menu
-
-void VM_strlen(void);
-void VM_strcat(void);
-void VM_substring(void);
-void VM_stov(void);
-void VM_strzone(void);
-void VM_strunzone(void);
+void VM_CheckEmptyString (prvm_prog_t *prog, const char *s);
+void VM_VarString(prvm_prog_t *prog, int first, char *out, int outlength);
+
+void VM_checkextension (prvm_prog_t *prog);
+void VM_error (prvm_prog_t *prog);
+void VM_objerror (prvm_prog_t *prog);
+void VM_print (prvm_prog_t *prog);
+void VM_bprint (prvm_prog_t *prog);
+void VM_sprint (prvm_prog_t *prog);
+void VM_centerprint (prvm_prog_t *prog);
+void VM_normalize (prvm_prog_t *prog);
+void VM_vlen (prvm_prog_t *prog);
+void VM_vectoyaw (prvm_prog_t *prog);
+void VM_vectoangles (prvm_prog_t *prog);
+void VM_random (prvm_prog_t *prog);
+void VM_localsound(prvm_prog_t *prog);
+void VM_break (prvm_prog_t *prog);
+void VM_localcmd (prvm_prog_t *prog);
+void VM_cvar (prvm_prog_t *prog);
+void VM_cvar_string(prvm_prog_t *prog);
+void VM_cvar_type (prvm_prog_t *prog);
+void VM_cvar_defstring (prvm_prog_t *prog);
+void VM_cvar_set (prvm_prog_t *prog);
+void VM_dprint (prvm_prog_t *prog);
+void VM_ftos (prvm_prog_t *prog);
+void VM_fabs (prvm_prog_t *prog);
+void VM_vtos (prvm_prog_t *prog);
+void VM_etos (prvm_prog_t *prog);
+void VM_stof(prvm_prog_t *prog);
+void VM_itof(prvm_prog_t *prog);
+void VM_ftoe(prvm_prog_t *prog);
+void VM_strftime(prvm_prog_t *prog);
+void VM_spawn (prvm_prog_t *prog);
+void VM_remove (prvm_prog_t *prog);
+void VM_find (prvm_prog_t *prog);
+void VM_findfloat (prvm_prog_t *prog);
+void VM_findchain (prvm_prog_t *prog);
+void VM_findchainfloat (prvm_prog_t *prog);
+void VM_findflags (prvm_prog_t *prog);
+void VM_findchainflags (prvm_prog_t *prog);
+void VM_precache_file (prvm_prog_t *prog);
+void VM_precache_sound (prvm_prog_t *prog);
+void VM_coredump (prvm_prog_t *prog);
+
+void VM_stackdump (prvm_prog_t *prog);
+void VM_crash(prvm_prog_t *prog); // REMOVE IT
+void VM_traceon (prvm_prog_t *prog);
+void VM_traceoff (prvm_prog_t *prog);
+void VM_eprint (prvm_prog_t *prog);
+void VM_rint (prvm_prog_t *prog);
+void VM_floor (prvm_prog_t *prog);
+void VM_ceil (prvm_prog_t *prog);
+void VM_nextent (prvm_prog_t *prog);
+
+void VM_changelevel (prvm_prog_t *prog);
+void VM_sin (prvm_prog_t *prog);
+void VM_cos (prvm_prog_t *prog);
+void VM_sqrt (prvm_prog_t *prog);
+void VM_randomvec (prvm_prog_t *prog);
+void VM_registercvar (prvm_prog_t *prog);
+void VM_min (prvm_prog_t *prog);
+void VM_max (prvm_prog_t *prog);
+void VM_bound (prvm_prog_t *prog);
+void VM_pow (prvm_prog_t *prog);
+void VM_log (prvm_prog_t *prog);
+void VM_asin (prvm_prog_t *prog);
+void VM_acos (prvm_prog_t *prog);
+void VM_atan (prvm_prog_t *prog);
+void VM_atan2 (prvm_prog_t *prog);
+void VM_tan (prvm_prog_t *prog);
+
+void VM_Files_Init(prvm_prog_t *prog);
+void VM_Files_CloseAll(prvm_prog_t *prog);
+
+void VM_fopen(prvm_prog_t *prog);
+void VM_fclose(prvm_prog_t *prog);
+void VM_fgets(prvm_prog_t *prog);
+void VM_fputs(prvm_prog_t *prog);
+void VM_writetofile(prvm_prog_t *prog); // only used by menu
+
+void VM_strlen(prvm_prog_t *prog);
+void VM_strcat(prvm_prog_t *prog);
+void VM_substring(prvm_prog_t *prog);
+void VM_stov(prvm_prog_t *prog);
+void VM_strzone(prvm_prog_t *prog);
+void VM_strunzone(prvm_prog_t *prog);
 
 // KrimZon - DP_QC_ENTITYDATA
-void VM_numentityfields(void);
-void VM_entityfieldname(void);
-void VM_entityfieldtype(void);
-void VM_getentityfieldstring(void);
-void VM_putentityfieldstring(void);
-// And declared these ones for VM_getentityfieldstring and VM_putentityfieldstring in prvm_cmds.c
-// the function is from prvm_edict.c
-char *PRVM_UglyValueString (etype_t type, prvm_eval_t *val);
-qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s, qboolean parsebackslash);
+void VM_numentityfields(prvm_prog_t *prog);
+void VM_entityfieldname(prvm_prog_t *prog);
+void VM_entityfieldtype(prvm_prog_t *prog);
+void VM_getentityfieldstring(prvm_prog_t *prog);
+void VM_putentityfieldstring(prvm_prog_t *prog);
 
 // DRESK - String Length (not counting color codes)
-void VM_strlennocol(void);
+void VM_strlennocol(prvm_prog_t *prog);
 // DRESK - Decolorized String
-void VM_strdecolorize(void);
+void VM_strdecolorize(prvm_prog_t *prog);
 // DRESK - String Uppercase and Lowercase Support
-void VM_strtolower(void);
-void VM_strtoupper(void);
+void VM_strtolower(prvm_prog_t *prog);
+void VM_strtoupper(prvm_prog_t *prog);
 
-void VM_clcommand (void);
+void VM_clcommand (prvm_prog_t *prog);
 
-void VM_tokenize (void);
-void VM_tokenizebyseparator (void);
-void VM_argv (void);
+void VM_tokenize (prvm_prog_t *prog);
+void VM_tokenizebyseparator (prvm_prog_t *prog);
+void VM_argv (prvm_prog_t *prog);
 
-void VM_isserver(void);
-void VM_clientcount(void);
-void VM_clientstate(void);
+void VM_isserver(prvm_prog_t *prog);
+void VM_clientcount(prvm_prog_t *prog);
+void VM_clientstate(prvm_prog_t *prog);
 // not used at the moment -> not included in the common list
-void VM_getostype(void);
-void VM_getmousepos(void);
-void VM_gettime(void);
-void VM_getsoundtime(void);
-void VM_soundlength(void);
-void VM_loadfromdata(void);
-void VM_parseentitydata(void);
-void VM_loadfromfile(void);
-void VM_modulo(void);
-
-void VM_search_begin(void);
-void VM_search_end(void);
-void VM_search_getsize(void);
-void VM_search_getfilename(void);
-void VM_chr(void);
-void VM_iscachedpic(void);
-void VM_precache_pic(void);
-void VM_freepic(void);
-void VM_drawcharacter(void);
-void VM_drawstring(void);
-void VM_drawcolorcodedstring(void);
-void VM_stringwidth(void);
-void VM_drawpic(void);
-void VM_drawrotpic(void);
-void VM_drawsubpic(void);
-void VM_drawfill(void);
-void VM_drawsetcliparea(void);
-void VM_drawresetcliparea(void);
-void VM_getimagesize(void);
-
-void VM_findfont(void);
-void VM_loadfont(void);
-
-void VM_makevectors (void);
-void VM_vectorvectors (void);
-
-void VM_keynumtostring (void);
-void VM_getkeybind (void);
-void VM_findkeysforcommand (void);
-void VM_stringtokeynum (void);
-void VM_setkeybind (void);
-void VM_getbindmaps (void);
-void VM_setbindmaps (void);
-
-void VM_cin_open( void );
-void VM_cin_close( void );
-void VM_cin_setstate( void );
-void VM_cin_getstate( void );
-void VM_cin_restart( void );
-
-void VM_gecko_create( void );
-void VM_gecko_destroy( void );
-void VM_gecko_navigate( void );
-void VM_gecko_keyevent( void );
-void VM_gecko_movemouse( void );
-void VM_gecko_resize( void );
-void VM_gecko_get_texture_extent( void );
-
-void VM_drawline (void);
-
-void VM_bitshift (void);
-
-void VM_altstr_count( void );
-void VM_altstr_prepare( void );
-void VM_altstr_get( void );
-void VM_altstr_set( void );
-void VM_altstr_ins(void);
-
-void VM_buf_create(void);
-void VM_buf_del (void);
-void VM_buf_getsize (void);
-void VM_buf_copy (void);
-void VM_buf_sort (void);
-void VM_buf_implode (void);
-void VM_bufstr_get (void);
-void VM_bufstr_set (void);
-void VM_bufstr_add (void);
-void VM_bufstr_free (void);
-
-void VM_changeyaw (void);
-void VM_changepitch (void);
-
-void VM_uncolorstring (void);
-
-void VM_strstrofs (void);
-void VM_str2chr (void);
-void VM_chr2str (void);
-void VM_strconv (void);
-void VM_strpad (void);
-void VM_infoadd (void);
-void VM_infoget (void);
-void VM_strncmp (void);
-void VM_strncmp (void);
-void VM_strncasecmp (void);
-void VM_registercvar (void);
-void VM_wasfreed (void);
-
-void VM_strreplace (void);
-void VM_strireplace (void);
-
-void VM_crc16(void);
-void VM_digest_hex(void);
-
-void VM_SetTraceGlobals(const trace_t *trace);
-void VM_ClearTraceGlobals(void);
-
-void VM_Cmd_Init(void);
-void VM_Cmd_Reset(void);
-
-void VM_uri_escape (void);
-void VM_uri_unescape (void);
-void VM_whichpack (void);
-
-void VM_etof (void);
-void VM_uri_get (void);
-void VM_netaddress_resolve (void);
-
-void VM_tokenize_console (void);
-void VM_argv_start_index (void);
-void VM_argv_end_index (void);
-
-void VM_buf_cvarlist(void);
-void VM_cvar_description(void);
-
-void VM_CL_getextresponse (void);
-void VM_SV_getextresponse (void);
+void VM_getostype(prvm_prog_t *prog);
+void VM_getmousepos(prvm_prog_t *prog);
+void VM_gettime(prvm_prog_t *prog);
+void VM_getsoundtime(prvm_prog_t *prog);
+void VM_soundlength(prvm_prog_t *prog);
+void VM_loadfromdata(prvm_prog_t *prog);
+void VM_parseentitydata(prvm_prog_t *prog);
+void VM_loadfromfile(prvm_prog_t *prog);
+void VM_modulo(prvm_prog_t *prog);
+
+void VM_search_begin(prvm_prog_t *prog);
+void VM_search_end(prvm_prog_t *prog);
+void VM_search_getsize(prvm_prog_t *prog);
+void VM_search_getfilename(prvm_prog_t *prog);
+void VM_chr(prvm_prog_t *prog);
+void VM_iscachedpic(prvm_prog_t *prog);
+void VM_precache_pic(prvm_prog_t *prog);
+void VM_freepic(prvm_prog_t *prog);
+void VM_drawcharacter(prvm_prog_t *prog);
+void VM_drawstring(prvm_prog_t *prog);
+void VM_drawcolorcodedstring(prvm_prog_t *prog);
+void VM_stringwidth(prvm_prog_t *prog);
+void VM_drawpic(prvm_prog_t *prog);
+void VM_drawrotpic(prvm_prog_t *prog);
+void VM_drawsubpic(prvm_prog_t *prog);
+void VM_drawfill(prvm_prog_t *prog);
+void VM_drawsetcliparea(prvm_prog_t *prog);
+void VM_drawresetcliparea(prvm_prog_t *prog);
+void VM_getimagesize(prvm_prog_t *prog);
+
+void VM_findfont(prvm_prog_t *prog);
+void VM_loadfont(prvm_prog_t *prog);
+
+void VM_makevectors (prvm_prog_t *prog);
+void VM_vectorvectors (prvm_prog_t *prog);
+
+void VM_keynumtostring (prvm_prog_t *prog);
+void VM_getkeybind (prvm_prog_t *prog);
+void VM_findkeysforcommand (prvm_prog_t *prog);
+void VM_stringtokeynum (prvm_prog_t *prog);
+void VM_setkeybind (prvm_prog_t *prog);
+void VM_getbindmaps (prvm_prog_t *prog);
+void VM_setbindmaps (prvm_prog_t *prog);
+
+void VM_cin_open(prvm_prog_t *prog);
+void VM_cin_close(prvm_prog_t *prog);
+void VM_cin_setstate(prvm_prog_t *prog);
+void VM_cin_getstate(prvm_prog_t *prog);
+void VM_cin_restart(prvm_prog_t *prog);
+
+void VM_gecko_create(prvm_prog_t *prog);
+void VM_gecko_destroy(prvm_prog_t *prog);
+void VM_gecko_navigate(prvm_prog_t *prog);
+void VM_gecko_keyevent(prvm_prog_t *prog);
+void VM_gecko_movemouse(prvm_prog_t *prog);
+void VM_gecko_resize(prvm_prog_t *prog);
+void VM_gecko_get_texture_extent(prvm_prog_t *prog);
+
+void VM_drawline (prvm_prog_t *prog);
+
+void VM_bitshift (prvm_prog_t *prog);
+
+void VM_altstr_count(prvm_prog_t *prog);
+void VM_altstr_prepare(prvm_prog_t *prog);
+void VM_altstr_get(prvm_prog_t *prog);
+void VM_altstr_set(prvm_prog_t *prog);
+void VM_altstr_ins(prvm_prog_t *prog);
+
+void VM_buf_create(prvm_prog_t *prog);
+void VM_buf_del (prvm_prog_t *prog);
+void VM_buf_getsize (prvm_prog_t *prog);
+void VM_buf_copy (prvm_prog_t *prog);
+void VM_buf_sort (prvm_prog_t *prog);
+void VM_buf_implode (prvm_prog_t *prog);
+void VM_bufstr_get (prvm_prog_t *prog);
+void VM_bufstr_set (prvm_prog_t *prog);
+void VM_bufstr_add (prvm_prog_t *prog);
+void VM_bufstr_free (prvm_prog_t *prog);
+
+void VM_changeyaw (prvm_prog_t *prog);
+void VM_changepitch (prvm_prog_t *prog);
+
+void VM_uncolorstring (prvm_prog_t *prog);
+
+void VM_strstrofs (prvm_prog_t *prog);
+void VM_str2chr (prvm_prog_t *prog);
+void VM_chr2str (prvm_prog_t *prog);
+void VM_strconv (prvm_prog_t *prog);
+void VM_strpad (prvm_prog_t *prog);
+void VM_infoadd (prvm_prog_t *prog);
+void VM_infoget (prvm_prog_t *prog);
+void VM_strncmp (prvm_prog_t *prog);
+void VM_strncmp (prvm_prog_t *prog);
+void VM_strncasecmp (prvm_prog_t *prog);
+void VM_registercvar (prvm_prog_t *prog);
+void VM_wasfreed (prvm_prog_t *prog);
+
+void VM_strreplace (prvm_prog_t *prog);
+void VM_strireplace (prvm_prog_t *prog);
+
+void VM_crc16(prvm_prog_t *prog);
+void VM_digest_hex(prvm_prog_t *prog);
+
+void VM_SetTraceGlobals(prvm_prog_t *prog, const trace_t *trace);
+void VM_ClearTraceGlobals(prvm_prog_t *prog);
+
+void VM_uri_escape (prvm_prog_t *prog);
+void VM_uri_unescape (prvm_prog_t *prog);
+void VM_whichpack (prvm_prog_t *prog);
+
+void VM_etof (prvm_prog_t *prog);
+void VM_uri_get (prvm_prog_t *prog);
+void VM_netaddress_resolve (prvm_prog_t *prog);
+
+void VM_tokenize_console (prvm_prog_t *prog);
+void VM_argv_start_index (prvm_prog_t *prog);
+void VM_argv_end_index (prvm_prog_t *prog);
+
+void VM_buf_cvarlist(prvm_prog_t *prog);
+void VM_cvar_description(prvm_prog_t *prog);
+
+void VM_CL_getextresponse (prvm_prog_t *prog);
+void VM_SV_getextresponse (prvm_prog_t *prog);
 
 // Common functions between menu.dat and clsprogs
-void VM_CL_isdemo (void);
-void VM_CL_videoplaying (void);
+void VM_CL_isdemo (prvm_prog_t *prog);
+void VM_CL_videoplaying (prvm_prog_t *prog);
 
-void VM_isfunction(void);
-void VM_callfunction(void);
+void VM_isfunction(prvm_prog_t *prog);
+void VM_callfunction(prvm_prog_t *prog);
 
-void VM_sprintf(void);
+void VM_sprintf(prvm_prog_t *prog);
 
-void VM_getsurfacenumpoints(void);
-void VM_getsurfacepoint(void);
-void VM_getsurfacepointattribute(void);
-void VM_getsurfacenormal(void);
-void VM_getsurfacetexture(void);
-void VM_getsurfacenearpoint(void);
-void VM_getsurfaceclippedpoint(void);
-void VM_getsurfacenumtriangles(void);
-void VM_getsurfacetriangle(void);
+void VM_getsurfacenumpoints(prvm_prog_t *prog);
+void VM_getsurfacepoint(prvm_prog_t *prog);
+void VM_getsurfacepointattribute(prvm_prog_t *prog);
+void VM_getsurfacenormal(prvm_prog_t *prog);
+void VM_getsurfacetexture(prvm_prog_t *prog);
+void VM_getsurfacenearpoint(prvm_prog_t *prog);
+void VM_getsurfaceclippedpoint(prvm_prog_t *prog);
+void VM_getsurfacenumtriangles(prvm_prog_t *prog);
+void VM_getsurfacetriangle(prvm_prog_t *prog);
 
 // physics builtins
-void VM_physics_enable(void);
-void VM_physics_addforce(void);
-void VM_physics_addtorque(void);
+void VM_physics_enable(prvm_prog_t *prog);
+void VM_physics_addforce(prvm_prog_t *prog);
+void VM_physics_addtorque(prvm_prog_t *prog);
+
+#endif
index ffe917a8060034737664e089d8cb042321b4740a..c236447ec09ddea055f52ba54262b9440f9ef88b 100644 (file)
@@ -23,17 +23,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "progsvm.h"
 #include "csprogs.h"
 
-prvm_prog_t *prog;
-
-static prvm_prog_t prog_list[PRVM_MAXPROGS];
+prvm_prog_t prvm_prog_list[PRVM_PROG_MAX];
 
 int            prvm_type_size[8] = {1,sizeof(string_t)/4,1,3,1,1,sizeof(func_t)/4,sizeof(void *)/4};
 
 prvm_eval_t prvm_badvalue; // used only for error returns
 
-ddef_t *PRVM_ED_FieldAtOfs(int ofs);
-qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s, qboolean parsebackslash);
-
 cvar_t prvm_language = {CVAR_SAVE, "prvm_language", "", "when set, loads progs.dat.LANGUAGENAME.po for string translations; when set to dump, progs.dat.pot is written from the strings in the progs"};
 // LordHavoc: prints every opcode as it executes - warning: this is significant spew
 cvar_t prvm_traceqc = {0, "prvm_traceqc", "0", "prints every QuakeC statement as it is executed (only for really thorough debugging!)"};
@@ -50,8 +45,6 @@ cvar_t prvm_reuseedicts_neverinsameframe = {0, "prvm_reuseedicts_neverinsamefram
 static double prvm_reuseedicts_always_allow = 0;
 qboolean prvm_runawaycheck = true;
 
-extern sizebuf_t vm_tempstringsbuf;
-
 //============================================================================
 // mempool handling
 
@@ -60,7 +53,7 @@ extern sizebuf_t vm_tempstringsbuf;
 PRVM_MEM_Alloc
 ===============
 */
-void PRVM_MEM_Alloc(void)
+static void PRVM_MEM_Alloc(prvm_prog_t *prog)
 {
        int i;
 
@@ -95,14 +88,14 @@ void PRVM_MEM_Alloc(void)
 PRVM_MEM_IncreaseEdicts
 ===============
 */
-void PRVM_MEM_IncreaseEdicts(void)
+void PRVM_MEM_IncreaseEdicts(prvm_prog_t *prog)
 {
        int             i;
 
        if(prog->max_edicts >= prog->limit_edicts)
                return;
 
-       PRVM_GCALL(begin_increase_edicts)();
+       prog->begin_increase_edicts(prog);
 
        // increase edicts
        prog->max_edicts = min(prog->max_edicts + 256, prog->limit_edicts);
@@ -118,91 +111,74 @@ void PRVM_MEM_IncreaseEdicts(void)
                prog->edicts[i].fields.vp = prog->edictsfields + i * prog->entityfields;
        }
 
-       PRVM_GCALL(end_increase_edicts)();
+       prog->end_increase_edicts(prog);
 }
 
 //============================================================================
 // normal prvm
 
-int PRVM_ED_FindFieldOffset(const char *field)
+int PRVM_ED_FindFieldOffset(prvm_prog_t *prog, const char *field)
 {
        ddef_t *d;
-       d = PRVM_ED_FindField(field);
+       d = PRVM_ED_FindField(prog, field);
        if (!d)
                return -1;
        return d->ofs;
 }
 
-int PRVM_ED_FindGlobalOffset(const char *global)
+int PRVM_ED_FindGlobalOffset(prvm_prog_t *prog, const char *global)
 {
        ddef_t *d;
-       d = PRVM_ED_FindGlobal(global);
+       d = PRVM_ED_FindGlobal(prog, global);
        if (!d)
                return -1;
        return d->ofs;
 }
 
-func_t PRVM_ED_FindFunctionOffset(const char *function)
+func_t PRVM_ED_FindFunctionOffset(prvm_prog_t *prog, const char *function)
 {
        mfunction_t *f;
-       f = PRVM_ED_FindFunction(function);
+       f = PRVM_ED_FindFunction(prog, function);
        if (!f)
                return 0;
        return (func_t)(f - prog->functions);
 }
 
-qboolean PRVM_ProgLoaded(int prognr)
-{
-       if(prognr < 0 || prognr >= PRVM_MAXPROGS)
-               return FALSE;
-
-       return (prog_list[prognr].loaded ? TRUE : FALSE);
-}
-
 /*
 =================
-PRVM_SetProgFromString
+PRVM_ProgFromString
 =================
 */
-// perhaps add a return value when the str doesnt exist
-qboolean PRVM_SetProgFromString(const char *str)
-{
-       int i = 0;
-       for(; i < PRVM_MAXPROGS ; i++)
-               if(prog_list[i].name && !strcmp(prog_list[i].name,str))
-               {
-                       if(prog_list[i].loaded)
-                       {
-                               prog = &prog_list[i];
-                               return TRUE;
-                       }
-                       else
-                       {
-                               Con_Printf("%s not loaded !\n",PRVM_NAME);
-                               return FALSE;
-                       }
-               }
-
-       Con_Printf("Invalid program name %s !\n", str);
-       return FALSE;
+prvm_prog_t *PRVM_ProgFromString(const char *str)
+{
+       if (!strcmp(str, "server"))
+               return SVVM_prog;
+       if (!strcmp(str, "client"))
+               return CLVM_prog;
+       if (!strcmp(str, "menu"))
+               return MVM_prog;
+       return NULL;
 }
 
 /*
 =================
-PRVM_SetProg
+PRVM_FriendlyProgFromString
 =================
 */
-void PRVM_SetProg(int prognr)
+prvm_prog_t *PRVM_FriendlyProgFromString(const char *str)
 {
-       if(0 <= prognr && prognr < PRVM_MAXPROGS)
+       prvm_prog_t *prog = PRVM_ProgFromString(str);
+       if (!prog)
        {
-               if(prog_list[prognr].loaded)
-                       prog = &prog_list[prognr];
-               else
-                       PRVM_ERROR("%i not loaded !", prognr);
-               return;
+               Con_Printf("%s: unknown program name\n", str);
+               return NULL;
        }
-       PRVM_ERROR("Invalid program number %i", prognr);
+       if (!prog->loaded)
+       {
+               Con_Printf("%s: program is not loaded\n", str);
+               return NULL;
+       }
+       return prog;
 }
 
 /*
@@ -212,23 +188,23 @@ PRVM_ED_ClearEdict
 Sets everything to NULL
 =================
 */
-void PRVM_ED_ClearEdict (prvm_edict_t *e)
+void PRVM_ED_ClearEdict(prvm_prog_t *prog, prvm_edict_t *e)
 {
-       memset (e->fields.vp, 0, prog->entityfields * 4);
+       memset(e->fields.vp, 0, prog->entityfields * 4);
        e->priv.required->free = false;
 
        // AK: Let the init_edict function determine if something needs to be initialized
-       PRVM_GCALL(init_edict)(e);
+       prog->init_edict(prog, e);
 }
 
-const char *PRVM_AllocationOrigin(void)
+const char *PRVM_AllocationOrigin(prvm_prog_t *prog)
 {
        char *buf = NULL;
        if(prog->leaktest_active)
        if(prog->depth > 0) // actually in QC code and not just parsing the entities block of a map/savegame
        {
                buf = (char *)PRVM_Alloc(128);
-               PRVM_ShortStackTrace(buf, 128);
+               PRVM_ShortStackTrace(prog, buf, 128);
        }
        return buf;
 }
@@ -240,7 +216,7 @@ PRVM_ED_CanAlloc
 Returns if this particular edict could get allocated by PRVM_ED_Alloc
 =================
 */
-qboolean PRVM_ED_CanAlloc(prvm_edict_t *e)
+qboolean PRVM_ED_CanAlloc(prvm_prog_t *prog, prvm_edict_t *e)
 {
        if(!e->priv.required->free)
                return false;
@@ -266,10 +242,10 @@ instead of being removed and recreated, which can cause interpolated
 angles and bad trails.
 =================
 */
-prvm_edict_t *PRVM_ED_Alloc (void)
+prvm_edict_t *PRVM_ED_Alloc(prvm_prog_t *prog)
 {
-       int                     i;
-       prvm_edict_t            *e;
+       int i;
+       prvm_edict_t *e;
 
        // the client qc dont need maxclients
        // thus it doesnt need to use svs.maxclients
@@ -279,25 +255,25 @@ prvm_edict_t *PRVM_ED_Alloc (void)
        for (i = prog->reserved_edicts + 1;i < prog->num_edicts;i++)
        {
                e = PRVM_EDICT_NUM(i);
-               if(PRVM_ED_CanAlloc(e))
+               if(PRVM_ED_CanAlloc(prog, e))
                {
-                       PRVM_ED_ClearEdict (e);
-                       e->priv.required->allocation_origin = PRVM_AllocationOrigin();
+                       PRVM_ED_ClearEdict (prog, e);
+                       e->priv.required->allocation_origin = PRVM_AllocationOrigin(prog);
                        return e;
                }
        }
 
        if (i == prog->limit_edicts)
-               PRVM_ERROR ("%s: PRVM_ED_Alloc: no free edicts",PRVM_NAME);
+               prog->error_cmd("%s: PRVM_ED_Alloc: no free edicts", prog->name);
 
        prog->num_edicts++;
        if (prog->num_edicts >= prog->max_edicts)
-               PRVM_MEM_IncreaseEdicts();
+               PRVM_MEM_IncreaseEdicts(prog);
 
        e = PRVM_EDICT_NUM(i);
-       PRVM_ED_ClearEdict (e);
+       PRVM_ED_ClearEdict(prog, e);
 
-       e->priv.required->allocation_origin = PRVM_AllocationOrigin();
+       e->priv.required->allocation_origin = PRVM_AllocationOrigin(prog);
 
        return e;
 }
@@ -310,19 +286,19 @@ Marks the edict as free
 FIXME: walk all entities and NULL out references to this entity
 =================
 */
-void PRVM_ED_Free (prvm_edict_t *ed)
+void PRVM_ED_Free(prvm_prog_t *prog, prvm_edict_t *ed)
 {
        // dont delete the null entity (world) or reserved edicts
-       if(PRVM_NUM_FOR_EDICT(ed) <= prog->reserved_edicts )
+       if (ed - prog->edicts <= prog->reserved_edicts)
                return;
 
-       PRVM_GCALL(free_edict)(ed);
+       prog->free_edict(prog, ed);
 
        ed->priv.required->free = true;
        ed->priv.required->freetime = realtime;
        if(ed->priv.required->allocation_origin)
        {
-               PRVM_Free((char *)ed->priv.required->allocation_origin);
+               Mem_Free((char *)ed->priv.required->allocation_origin);
                ed->priv.required->allocation_origin = NULL;
        }
 }
@@ -334,7 +310,7 @@ void PRVM_ED_Free (prvm_edict_t *ed)
 PRVM_ED_GlobalAtOfs
 ============
 */
-ddef_t *PRVM_ED_GlobalAtOfs (int ofs)
+static ddef_t *PRVM_ED_GlobalAtOfs (prvm_prog_t *prog, int ofs)
 {
        ddef_t          *def;
        int                     i;
@@ -353,7 +329,7 @@ ddef_t *PRVM_ED_GlobalAtOfs (int ofs)
 PRVM_ED_FieldAtOfs
 ============
 */
-ddef_t *PRVM_ED_FieldAtOfs (int ofs)
+ddef_t *PRVM_ED_FieldAtOfs (prvm_prog_t *prog, int ofs)
 {
        ddef_t          *def;
        int                     i;
@@ -372,7 +348,7 @@ ddef_t *PRVM_ED_FieldAtOfs (int ofs)
 PRVM_ED_FindField
 ============
 */
-ddef_t *PRVM_ED_FindField (const char *name)
+ddef_t *PRVM_ED_FindField (prvm_prog_t *prog, const char *name)
 {
        ddef_t *def;
        int i;
@@ -380,7 +356,7 @@ ddef_t *PRVM_ED_FindField (const char *name)
        for (i = 0;i < prog->numfielddefs;i++)
        {
                def = &prog->fielddefs[i];
-               if (!strcmp(PRVM_GetString(def->s_name), name))
+               if (!strcmp(PRVM_GetString(prog, def->s_name), name))
                        return def;
        }
        return NULL;
@@ -391,7 +367,7 @@ ddef_t *PRVM_ED_FindField (const char *name)
 PRVM_ED_FindGlobal
 ============
 */
-ddef_t *PRVM_ED_FindGlobal (const char *name)
+ddef_t *PRVM_ED_FindGlobal (prvm_prog_t *prog, const char *name)
 {
        ddef_t *def;
        int i;
@@ -399,7 +375,7 @@ ddef_t *PRVM_ED_FindGlobal (const char *name)
        for (i = 0;i < prog->numglobaldefs;i++)
        {
                def = &prog->globaldefs[i];
-               if (!strcmp(PRVM_GetString(def->s_name), name))
+               if (!strcmp(PRVM_GetString(prog, def->s_name), name))
                        return def;
        }
        return NULL;
@@ -411,7 +387,7 @@ ddef_t *PRVM_ED_FindGlobal (const char *name)
 PRVM_ED_FindFunction
 ============
 */
-mfunction_t *PRVM_ED_FindFunction (const char *name)
+mfunction_t *PRVM_ED_FindFunction (prvm_prog_t *prog, const char *name)
 {
        mfunction_t             *func;
        int                             i;
@@ -419,7 +395,7 @@ mfunction_t *PRVM_ED_FindFunction (const char *name)
        for (i = 0;i < prog->numfunctions;i++)
        {
                func = &prog->functions[i];
-               if (!strcmp(PRVM_GetString(func->s_name), name))
+               if (!strcmp(PRVM_GetString(prog, func->s_name), name))
                        return func;
        }
        return NULL;
@@ -433,9 +409,8 @@ PRVM_ValueString
 Returns a string describing *data in a type specific manner
 =============
 */
-char *PRVM_ValueString (etype_t type, prvm_eval_t *val)
+static char *PRVM_ValueString (prvm_prog_t *prog, etype_t type, prvm_eval_t *val, char *line, size_t linelength)
 {
-       static char line[MAX_INPUTLINE];
        ddef_t *def;
        mfunction_t *f;
        int n;
@@ -445,39 +420,39 @@ char *PRVM_ValueString (etype_t type, prvm_eval_t *val)
        switch (type)
        {
        case ev_string:
-               strlcpy (line, PRVM_GetString (val->string), sizeof (line));
+               strlcpy (line, PRVM_GetString (prog, val->string), linelength);
                break;
        case ev_entity:
                n = val->edict;
                if (n < 0 || n >= prog->max_edicts)
-                       dpsnprintf (line, sizeof(line), "entity %i (invalid!)", n);
+                       dpsnprintf (line, linelength, "entity %i (invalid!)", n);
                else
-                       dpsnprintf (line, sizeof(line), "entity %i", n);
+                       dpsnprintf (line, linelength, "entity %i", n);
                break;
        case ev_function:
                f = prog->functions + val->function;
-               dpsnprintf (line, sizeof(line), "%s()", PRVM_GetString(f->s_name));
+               dpsnprintf (line, linelength, "%s()", PRVM_GetString(prog, f->s_name));
                break;
        case ev_field:
-               def = PRVM_ED_FieldAtOfs ( val->_int );
-               dpsnprintf (line, sizeof(line), ".%s", PRVM_GetString(def->s_name));
+               def = PRVM_ED_FieldAtOfs ( prog, val->_int );
+               dpsnprintf (line, linelength, ".%s", PRVM_GetString(prog, def->s_name));
                break;
        case ev_void:
-               dpsnprintf (line, sizeof(line), "void");
+               dpsnprintf (line, linelength, "void");
                break;
        case ev_float:
                // LordHavoc: changed from %5.1f to %10.4f
-               dpsnprintf (line, sizeof(line), "%10.4f", val->_float);
+               dpsnprintf (line, linelength, "%10.4f", val->_float);
                break;
        case ev_vector:
                // LordHavoc: changed from %5.1f to %10.4f
-               dpsnprintf (line, sizeof(line), "'%10.4f %10.4f %10.4f'", val->vector[0], val->vector[1], val->vector[2]);
+               dpsnprintf (line, linelength, "'%10.4f %10.4f %10.4f'", val->vector[0], val->vector[1], val->vector[2]);
                break;
        case ev_pointer:
-               dpsnprintf (line, sizeof(line), "pointer");
+               dpsnprintf (line, linelength, "pointer");
                break;
        default:
-               dpsnprintf (line, sizeof(line), "bad type %i", (int) type);
+               dpsnprintf (line, linelength, "bad type %i", (int) type);
                break;
        }
 
@@ -492,9 +467,8 @@ Returns a string describing *data in a type specific manner
 Easier to parse than PR_ValueString
 =============
 */
-char *PRVM_UglyValueString (etype_t type, prvm_eval_t *val)
+char *PRVM_UglyValueString (prvm_prog_t *prog, etype_t type, prvm_eval_t *val, char *line, size_t linelength)
 {
-       static char line[MAX_INPUTLINE];
        int i;
        const char *s;
        ddef_t *def;
@@ -508,8 +482,8 @@ char *PRVM_UglyValueString (etype_t type, prvm_eval_t *val)
                // Parse the string a bit to turn special characters
                // (like newline, specifically) into escape codes,
                // this fixes saving games from various mods
-               s = PRVM_GetString (val->string);
-               for (i = 0;i < (int)sizeof(line) - 2 && *s;)
+               s = PRVM_GetString (prog, val->string);
+               for (i = 0;i < (int)linelength - 2 && *s;)
                {
                        if (*s == '\n')
                        {
@@ -538,27 +512,27 @@ char *PRVM_UglyValueString (etype_t type, prvm_eval_t *val)
                line[i] = '\0';
                break;
        case ev_entity:
-               dpsnprintf (line, sizeof (line), "%i", PRVM_NUM_FOR_EDICT(PRVM_PROG_TO_EDICT(val->edict)));
+               dpsnprintf (line, linelength, "%i", PRVM_NUM_FOR_EDICT(PRVM_PROG_TO_EDICT(val->edict)));
                break;
        case ev_function:
                f = prog->functions + val->function;
-               strlcpy (line, PRVM_GetString (f->s_name), sizeof (line));
+               strlcpy (line, PRVM_GetString (prog, f->s_name), linelength);
                break;
        case ev_field:
-               def = PRVM_ED_FieldAtOfs ( val->_int );
-               dpsnprintf (line, sizeof (line), ".%s", PRVM_GetString(def->s_name));
+               def = PRVM_ED_FieldAtOfs ( prog, val->_int );
+               dpsnprintf (line, linelength, ".%s", PRVM_GetString(prog, def->s_name));
                break;
        case ev_void:
-               dpsnprintf (line, sizeof (line), "void");
+               dpsnprintf (line, linelength, "void");
                break;
        case ev_float:
-               dpsnprintf (line, sizeof (line), "%.9g", val->_float);
+               dpsnprintf (line, linelength, "%.9g", val->_float);
                break;
        case ev_vector:
-               dpsnprintf (line, sizeof (line), "%.9g %.9g %.9g", val->vector[0], val->vector[1], val->vector[2]);
+               dpsnprintf (line, linelength, "%.9g %.9g %.9g", val->vector[0], val->vector[1], val->vector[2]);
                break;
        default:
-               dpsnprintf (line, sizeof (line), "bad type %i", type);
+               dpsnprintf (line, linelength, "bad type %i", type);
                break;
        }
 
@@ -573,22 +547,22 @@ Returns a string with a description and the contents of a global,
 padded to 20 field width
 ============
 */
-char *PRVM_GlobalString (int ofs)
+char *PRVM_GlobalString (prvm_prog_t *prog, int ofs, char *line, size_t linelength)
 {
        char    *s;
        //size_t        i;
        ddef_t  *def;
        void    *val;
-       static char     line[128];
+       char valuebuf[MAX_INPUTLINE];
 
        val = (void *)&prog->globals.generic[ofs];
-       def = PRVM_ED_GlobalAtOfs(ofs);
+       def = PRVM_ED_GlobalAtOfs(prog, ofs);
        if (!def)
-               dpsnprintf (line, sizeof(line), "GLOBAL%i", ofs);
+               dpsnprintf (line, linelength, "GLOBAL%i", ofs);
        else
        {
-               s = PRVM_ValueString ((etype_t)def->type, (prvm_eval_t *)val);
-               dpsnprintf (line, sizeof(line), "%s (=%s)", PRVM_GetString(def->s_name), s);
+               s = PRVM_ValueString (prog, (etype_t)def->type, (prvm_eval_t *)val, valuebuf, sizeof(valuebuf));
+               dpsnprintf (line, linelength, "%s (=%s)", PRVM_GetString(prog, def->s_name), s);
        }
 
        //i = strlen(line);
@@ -599,17 +573,16 @@ char *PRVM_GlobalString (int ofs)
        return line;
 }
 
-char *PRVM_GlobalStringNoContents (int ofs)
+char *PRVM_GlobalStringNoContents (prvm_prog_t *prog, int ofs, char *line, size_t linelength)
 {
        //size_t        i;
        ddef_t  *def;
-       static char     line[128];
 
-       def = PRVM_ED_GlobalAtOfs(ofs);
+       def = PRVM_ED_GlobalAtOfs(prog, ofs);
        if (!def)
-               dpsnprintf (line, sizeof(line), "GLOBAL%i", ofs);
+               dpsnprintf (line, linelength, "GLOBAL%i", ofs);
        else
-               dpsnprintf (line, sizeof(line), "%s", PRVM_GetString(def->s_name));
+               dpsnprintf (line, linelength, "%s", PRVM_GetString(prog, def->s_name));
 
        //i = strlen(line);
        //for ( ; i<20 ; i++)
@@ -629,7 +602,7 @@ For debugging
 */
 // LordHavoc: optimized this to print out much more quickly (tempstring)
 // LordHavoc: changed to print out every 4096 characters (incase there are a lot of fields to print)
-void PRVM_ED_Print(prvm_edict_t *ed, const char *wildcard_fieldname)
+void PRVM_ED_Print(prvm_prog_t *prog, prvm_edict_t *ed, const char *wildcard_fieldname)
 {
        size_t  l;
        ddef_t  *d;
@@ -638,19 +611,20 @@ void PRVM_ED_Print(prvm_edict_t *ed, const char *wildcard_fieldname)
        const char      *name;
        int             type;
        char    tempstring[MAX_INPUTLINE], tempstring2[260]; // temporary string buffers
+       char    valuebuf[MAX_INPUTLINE];
 
        if (ed->priv.required->free)
        {
-               Con_Printf("%s: FREE\n",PRVM_NAME);
+               Con_Printf("%s: FREE\n",prog->name);
                return;
        }
 
        tempstring[0] = 0;
-       dpsnprintf(tempstring, sizeof(tempstring), "\n%s EDICT %i:\n", PRVM_NAME, PRVM_NUM_FOR_EDICT(ed));
+       dpsnprintf(tempstring, sizeof(tempstring), "\n%s EDICT %i:\n", prog->name, PRVM_NUM_FOR_EDICT(ed));
        for (i = 1;i < prog->numfielddefs;i++)
        {
                d = &prog->fielddefs[i];
-               name = PRVM_GetString(d->s_name);
+               name = PRVM_GetString(prog, d->s_name);
                if(strlen(name) > 1 && name[strlen(name)-2] == '_' && (name[strlen(name)-1] == 'x' || name[strlen(name)-1] == 'y' || name[strlen(name)-1] == 'z'))
                        continue;       // skip _x, _y, _z vars
 
@@ -683,7 +657,7 @@ void PRVM_ED_Print(prvm_edict_t *ed, const char *wildcard_fieldname)
                        strlcat(tempstring, " ", sizeof(tempstring));
                strlcat(tempstring, " ", sizeof(tempstring));
 
-               name = PRVM_ValueString((etype_t)d->type, (prvm_eval_t *)v);
+               name = PRVM_ValueString(prog, (etype_t)d->type, (prvm_eval_t *)v, valuebuf, sizeof(valuebuf));
                if (strlen(name) > sizeof(tempstring2)-4)
                {
                        memcpy (tempstring2, name, sizeof(tempstring2)-4);
@@ -711,13 +685,15 @@ For savegames
 =============
 */
 extern cvar_t developer_entityparsing;
-void PRVM_ED_Write (qfile_t *f, prvm_edict_t *ed)
+void PRVM_ED_Write (prvm_prog_t *prog, qfile_t *f, prvm_edict_t *ed)
 {
        ddef_t  *d;
        int             *v;
        int             i, j;
        const char      *name;
        int             type;
+       char vabuf[1024];
+       char valuebuf[MAX_INPUTLINE];
 
        FS_Print(f, "{\n");
 
@@ -730,7 +706,7 @@ void PRVM_ED_Write (qfile_t *f, prvm_edict_t *ed)
        for (i = 1;i < prog->numfielddefs;i++)
        {
                d = &prog->fielddefs[i];
-               name = PRVM_GetString(d->s_name);
+               name = PRVM_GetString(prog, d->s_name);
 
                if(developer_entityparsing.integer)
                        Con_Printf("PRVM_ED_Write: at entity %d field %s\n", PRVM_NUM_FOR_EDICT(ed), name);
@@ -750,17 +726,17 @@ void PRVM_ED_Write (qfile_t *f, prvm_edict_t *ed)
                        continue;
 
                FS_Printf(f,"\"%s\" ",name);
-               prog->statestring = va("PRVM_ED_Write, ent=%d, name=%s", i, name);
-               FS_Printf(f,"\"%s\"\n", PRVM_UglyValueString((etype_t)d->type, (prvm_eval_t *)v));
+               prog->statestring = va(vabuf, sizeof(vabuf), "PRVM_ED_Write, ent=%d, name=%s", i, name);
+               FS_Printf(f,"\"%s\"\n", PRVM_UglyValueString(prog, (etype_t)d->type, (prvm_eval_t *)v, valuebuf, sizeof(valuebuf)));
                prog->statestring = NULL;
        }
 
        FS_Print(f, "}\n");
 }
 
-void PRVM_ED_PrintNum (int ent, const char *wildcard_fieldname)
+void PRVM_ED_PrintNum (prvm_prog_t *prog, int ent, const char *wildcard_fieldname)
 {
-       PRVM_ED_Print(PRVM_EDICT_NUM(ent), wildcard_fieldname);
+       PRVM_ED_Print(prog, PRVM_EDICT_NUM(ent), wildcard_fieldname);
 }
 
 /*
@@ -772,6 +748,7 @@ For debugging, prints all the entities in the current server
 */
 void PRVM_ED_PrintEdicts_f (void)
 {
+       prvm_prog_t *prog;
        int             i;
        const char *wildcard_fieldname;
 
@@ -781,8 +758,7 @@ void PRVM_ED_PrintEdicts_f (void)
                return;
        }
 
-       PRVM_Begin;
-       if(!PRVM_SetProgFromString(Cmd_Argv(1)))
+       if (!(prog = PRVM_FriendlyProgFromString(Cmd_Argv(1))))
                return;
 
        if( Cmd_Argc() == 3)
@@ -790,11 +766,9 @@ void PRVM_ED_PrintEdicts_f (void)
        else
                wildcard_fieldname = NULL;
 
-       Con_Printf("%s: %i entities\n", PRVM_NAME, prog->num_edicts);
+       Con_Printf("%s: %i entities\n", prog->name, prog->num_edicts);
        for (i=0 ; i<prog->num_edicts ; i++)
-               PRVM_ED_PrintNum (i, wildcard_fieldname);
-
-       PRVM_End;
+               PRVM_ED_PrintNum (prog, i, wildcard_fieldname);
 }
 
 /*
@@ -804,8 +778,9 @@ PRVM_ED_PrintEdict_f
 For debugging, prints a single edict
 =============
 */
-void PRVM_ED_PrintEdict_f (void)
+static void PRVM_ED_PrintEdict_f (void)
 {
+       prvm_prog_t *prog;
        int             i;
        const char      *wildcard_fieldname;
 
@@ -815,15 +790,13 @@ void PRVM_ED_PrintEdict_f (void)
                return;
        }
 
-       PRVM_Begin;
-       if(!PRVM_SetProgFromString(Cmd_Argv(1)))
+       if (!(prog = PRVM_FriendlyProgFromString(Cmd_Argv(1))))
                return;
 
        i = atoi (Cmd_Argv(2));
        if (i >= prog->num_edicts)
        {
                Con_Print("Bad edict number\n");
-               PRVM_End;
                return;
        }
        if( Cmd_Argc() == 4)
@@ -832,9 +805,7 @@ void PRVM_ED_PrintEdict_f (void)
        else
                // Use All
                wildcard_fieldname = NULL;
-       PRVM_ED_PrintNum (i, wildcard_fieldname);
-
-       PRVM_End;
+       PRVM_ED_PrintNum (prog, i, wildcard_fieldname);
 }
 
 /*
@@ -846,11 +817,9 @@ For debugging
 */
 // 2 possibilities : 1. just displaying the active edict count
 //                                      2. making a function pointer [x]
-void PRVM_ED_Count_f (void)
+static void PRVM_ED_Count_f (void)
 {
-       int             i;
-       prvm_edict_t    *ent;
-       int             active;
+       prvm_prog_t *prog;
 
        if(Cmd_Argc() != 2)
        {
@@ -858,28 +827,10 @@ void PRVM_ED_Count_f (void)
                return;
        }
 
-       PRVM_Begin;
-       if(!PRVM_SetProgFromString(Cmd_Argv(1)))
+       if (!(prog = PRVM_FriendlyProgFromString(Cmd_Argv(1))))
                return;
 
-       if(prog->count_edicts)
-               prog->count_edicts();
-       else
-       {
-               active = 0;
-               for (i=0 ; i<prog->num_edicts ; i++)
-               {
-                       ent = PRVM_EDICT_NUM(i);
-                       if (ent->priv.required->free)
-                               continue;
-                       active++;
-               }
-
-               Con_Printf("num_edicts:%3i\n", prog->num_edicts);
-               Con_Printf("active    :%3i\n", active);
-       }
-
-       PRVM_End;
+       prog->count_edicts(prog);
 }
 
 /*
@@ -896,12 +847,14 @@ FIXME: need to tag constants, doesn't really work
 PRVM_ED_WriteGlobals
 =============
 */
-void PRVM_ED_WriteGlobals (qfile_t *f)
+void PRVM_ED_WriteGlobals (prvm_prog_t *prog, qfile_t *f)
 {
        ddef_t          *def;
        int                     i;
        const char              *name;
        int                     type;
+       char vabuf[1024];
+       char valuebuf[MAX_INPUTLINE];
 
        FS_Print(f,"{\n");
        for (i = 0;i < prog->numglobaldefs;i++)
@@ -915,14 +868,14 @@ void PRVM_ED_WriteGlobals (qfile_t *f)
                if (type != ev_string && type != ev_float && type != ev_entity)
                        continue;
 
-               name = PRVM_GetString(def->s_name);
+               name = PRVM_GetString(prog, def->s_name);
 
                if(developer_entityparsing.integer)
                        Con_Printf("PRVM_ED_WriteGlobals: at global %s\n", name);
 
-               prog->statestring = va("PRVM_ED_WriteGlobals, name=%s", name);
+               prog->statestring = va(vabuf, sizeof(vabuf), "PRVM_ED_WriteGlobals, name=%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(prog, (etype_t)type, (prvm_eval_t *)&prog->globals.generic[def->ofs], valuebuf, sizeof(valuebuf)));
                prog->statestring = NULL;
        }
        FS_Print(f,"}\n");
@@ -933,7 +886,7 @@ void PRVM_ED_WriteGlobals (qfile_t *f)
 PRVM_ED_ParseGlobals
 =============
 */
-void PRVM_ED_ParseGlobals (const char *data)
+void PRVM_ED_ParseGlobals (prvm_prog_t *prog, const char *data)
 {
        char keyname[MAX_INPUTLINE];
        ddef_t *key;
@@ -942,7 +895,7 @@ void PRVM_ED_ParseGlobals (const char *data)
        {
                // parse key
                if (!COM_ParseToken_Simple(&data, false, false))
-                       PRVM_ERROR ("PRVM_ED_ParseGlobals: EOF without closing brace");
+                       prog->error_cmd("PRVM_ED_ParseGlobals: EOF without closing brace");
                if (com_token[0] == '}')
                        break;
 
@@ -953,23 +906,23 @@ void PRVM_ED_ParseGlobals (const char *data)
 
                // parse value
                if (!COM_ParseToken_Simple(&data, false, true))
-                       PRVM_ERROR ("PRVM_ED_ParseGlobals: EOF without closing brace");
+                       prog->error_cmd("PRVM_ED_ParseGlobals: EOF without closing brace");
 
                if (developer_entityparsing.integer)
                        Con_Printf(" \"%s\"\n", com_token);
 
                if (com_token[0] == '}')
-                       PRVM_ERROR ("PRVM_ED_ParseGlobals: closing brace without data");
+                       prog->error_cmd("PRVM_ED_ParseGlobals: closing brace without data");
 
-               key = PRVM_ED_FindGlobal (keyname);
+               key = PRVM_ED_FindGlobal (prog, keyname);
                if (!key)
                {
-                       Con_DPrintf("'%s' is not a global on %s\n", keyname, PRVM_NAME);
+                       Con_DPrintf("'%s' is not a global on %s\n", keyname, prog->name);
                        continue;
                }
 
-               if (!PRVM_ED_ParseEpair(NULL, key, com_token, true))
-                       PRVM_ERROR ("PRVM_ED_ParseGlobals: parse error");
+               if (!PRVM_ED_ParseEpair(prog, NULL, key, com_token, true))
+                       prog->error_cmd("PRVM_ED_ParseGlobals: parse error");
        }
 }
 
@@ -984,7 +937,7 @@ Can parse either fields or globals
 returns false if error
 =============
 */
-qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s, qboolean parsebackslash)
+qboolean PRVM_ED_ParseEpair(prvm_prog_t *prog, prvm_edict_t *ent, ddef_t *key, const char *s, qboolean parsebackslash)
 {
        int i, l;
        char *new_p;
@@ -1000,7 +953,7 @@ qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s, qbool
        {
        case ev_string:
                l = (int)strlen(s) + 1;
-               val->string = PRVM_AllocString(l, &new_p);
+               val->string = PRVM_AllocString(prog, l, &new_p);
                for (i = 0;i < l;i++)
                {
                        if (s[i] == '\\' && s[i+1] && parsebackslash)
@@ -1044,9 +997,9 @@ qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s, qbool
                        s++;
                i = atoi(s);
                if (i >= prog->limit_edicts)
-                       Con_Printf("PRVM_ED_ParseEpair: ev_entity reference too large (edict %u >= MAX_EDICTS %u) on %s\n", (unsigned int)i, prog->limit_edicts, PRVM_NAME);
+                       Con_Printf("PRVM_ED_ParseEpair: ev_entity reference too large (edict %u >= MAX_EDICTS %u) on %s\n", (unsigned int)i, prog->limit_edicts, prog->name);
                while (i >= prog->max_edicts)
-                       PRVM_MEM_IncreaseEdicts();
+                       PRVM_MEM_IncreaseEdicts(prog);
                // if IncreaseEdicts was called the base pointer needs to be updated
                if (ent)
                        val = (prvm_eval_t *)(ent->fields.vp + key->ofs);
@@ -1056,30 +1009,30 @@ qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s, qbool
        case ev_field:
                if (*s != '.')
                {
-                       Con_DPrintf("PRVM_ED_ParseEpair: Bogus field name %s in %s\n", s, PRVM_NAME);
+                       Con_DPrintf("PRVM_ED_ParseEpair: Bogus field name %s in %s\n", s, prog->name);
                        return false;
                }
-               def = PRVM_ED_FindField(s + 1);
+               def = PRVM_ED_FindField(prog, s + 1);
                if (!def)
                {
-                       Con_DPrintf("PRVM_ED_ParseEpair: Can't find field %s in %s\n", s, PRVM_NAME);
+                       Con_DPrintf("PRVM_ED_ParseEpair: Can't find field %s in %s\n", s, prog->name);
                        return false;
                }
                val->_int = def->ofs;
                break;
 
        case ev_function:
-               func = PRVM_ED_FindFunction(s);
+               func = PRVM_ED_FindFunction(prog, s);
                if (!func)
                {
-                       Con_Printf("PRVM_ED_ParseEpair: Can't find function %s in %s\n", s, PRVM_NAME);
+                       Con_Printf("PRVM_ED_ParseEpair: Can't find function %s in %s\n", s, prog->name);
                        return false;
                }
                val->function = func - prog->functions;
                break;
 
        default:
-               Con_Printf("PRVM_ED_ParseEpair: Unknown key->type %i for key \"%s\" on %s\n", key->type, PRVM_GetString(key->s_name), PRVM_NAME);
+               Con_Printf("PRVM_ED_ParseEpair: Unknown key->type %i for key \"%s\" on %s\n", key->type, PRVM_GetString(prog, key->s_name), prog->name);
                return false;
        }
        return true;
@@ -1101,22 +1054,17 @@ All progs can support this extension; sg calls it in server QC, cg in client
 QC, mg in menu QC.
 =============
 */
-void PRVM_GameCommand(const char *whichprogs, const char *whichcmd)
+static void PRVM_GameCommand(const char *whichprogs, const char *whichcmd)
 {
+       prvm_prog_t *prog;
        if(Cmd_Argc() < 1)
        {
                Con_Printf("%s text...\n", whichcmd);
                return;
        }
 
-       PRVM_Begin;
-       if(!PRVM_SetProgFromString(whichprogs))
-       // note: this is not PRVM_SetProg because that one aborts "hard" using PRVM_Error
-       // also, it makes printing error messages easier!
-       {
-               Con_Printf("%s program not loaded.\n", whichprogs);
+       if (!(prog = PRVM_FriendlyProgFromString(whichprogs)))
                return;
-       }
 
        if(!PRVM_allfunction(GameCommand))
        {
@@ -1129,23 +1077,21 @@ void PRVM_GameCommand(const char *whichprogs, const char *whichcmd)
 
                s = Cmd_Args();
 
-               restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize;
-               PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(s ? s : "");
-               PRVM_ExecuteProgram (PRVM_allfunction(GameCommand), "QC function GameCommand is missing");
-               vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
+               restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize;
+               PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, s ? s : "");
+               prog->ExecuteProgram(prog, PRVM_allfunction(GameCommand), "QC function GameCommand is missing");
+               prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
        }
-
-       PRVM_End;
 }
-void PRVM_GameCommand_Server_f(void)
+static void PRVM_GameCommand_Server_f(void)
 {
        PRVM_GameCommand("server", "sv_cmd");
 }
-void PRVM_GameCommand_Client_f(void)
+static void PRVM_GameCommand_Client_f(void)
 {
        PRVM_GameCommand("client", "cl_cmd");
 }
-void PRVM_GameCommand_Menu_f(void)
+static void PRVM_GameCommand_Menu_f(void)
 {
        PRVM_GameCommand("menu", "menu_cmd");
 }
@@ -1157,12 +1103,14 @@ PRVM_ED_EdictGet_f
 Console command to load a field of a specified edict
 =============
 */
-void PRVM_ED_EdictGet_f(void)
+static void PRVM_ED_EdictGet_f(void)
 {
+       prvm_prog_t *prog;
        prvm_edict_t *ed;
        ddef_t *key;
        const char *s;
        prvm_eval_t *v;
+       char valuebuf[MAX_INPUTLINE];
 
        if(Cmd_Argc() != 4 && Cmd_Argc() != 5)
        {
@@ -1170,23 +1118,19 @@ void PRVM_ED_EdictGet_f(void)
                return;
        }
 
-       PRVM_Begin;
-       if(!PRVM_SetProgFromString(Cmd_Argv(1)))
-       {
-               Con_Printf("Wrong program name %s !\n", Cmd_Argv(1));
+       if (!(prog = PRVM_FriendlyProgFromString(Cmd_Argv(1))))
                return;
-       }
 
        ed = PRVM_EDICT_NUM(atoi(Cmd_Argv(2)));
 
-       if((key = PRVM_ED_FindField(Cmd_Argv(3))) == 0)
+       if((key = PRVM_ED_FindField(prog, Cmd_Argv(3))) == 0)
        {
                Con_Printf("Key %s not found !\n", Cmd_Argv(3));
                goto fail;
        }
 
        v = (prvm_eval_t *)(ed->fields.vp + key->ofs);
-       s = PRVM_UglyValueString((etype_t)key->type, v);
+       s = PRVM_UglyValueString(prog, (etype_t)key->type, v, valuebuf, sizeof(valuebuf));
        if(Cmd_Argc() == 5)
        {
                cvar_t *cvar = Cvar_FindVar(Cmd_Argv(4));
@@ -1201,14 +1145,16 @@ void PRVM_ED_EdictGet_f(void)
                Con_Printf("%s\n", s);
 
 fail:
-       PRVM_End;
+       ;
 }
 
-void PRVM_ED_GlobalGet_f(void)
+static void PRVM_ED_GlobalGet_f(void)
 {
+       prvm_prog_t *prog;
        ddef_t *key;
        const char *s;
        prvm_eval_t *v;
+       char valuebuf[MAX_INPUTLINE];
 
        if(Cmd_Argc() != 3 && Cmd_Argc() != 4)
        {
@@ -1216,14 +1162,10 @@ void PRVM_ED_GlobalGet_f(void)
                return;
        }
 
-       PRVM_Begin;
-       if(!PRVM_SetProgFromString(Cmd_Argv(1)))
-       {
-               Con_Printf("Wrong program name %s !\n", Cmd_Argv(1));
+       if (!(prog = PRVM_FriendlyProgFromString(Cmd_Argv(1))))
                return;
-       }
 
-       key = PRVM_ED_FindGlobal(Cmd_Argv(2));
+       key = PRVM_ED_FindGlobal(prog, Cmd_Argv(2));
        if(!key)
        {
                Con_Printf( "No global '%s' in %s!\n", Cmd_Argv(2), Cmd_Argv(1) );
@@ -1231,7 +1173,7 @@ void PRVM_ED_GlobalGet_f(void)
        }
 
        v = (prvm_eval_t *) &prog->globals.generic[key->ofs];
-       s = PRVM_UglyValueString((etype_t)key->type, v);
+       s = PRVM_UglyValueString(prog, (etype_t)key->type, v, valuebuf, sizeof(valuebuf));
        if(Cmd_Argc() == 4)
        {
                cvar_t *cvar = Cvar_FindVar(Cmd_Argv(3));
@@ -1246,7 +1188,7 @@ void PRVM_ED_GlobalGet_f(void)
                Con_Printf("%s\n", s);
 
 fail:
-       PRVM_End;
+       ;
 }
 
 /*
@@ -1256,8 +1198,9 @@ PRVM_ED_EdictSet_f
 Console command to set a field of a specified edict
 =============
 */
-void PRVM_ED_EdictSet_f(void)
+static void PRVM_ED_EdictSet_f(void)
 {
+       prvm_prog_t *prog;
        prvm_edict_t *ed;
        ddef_t *key;
 
@@ -1267,21 +1210,15 @@ void PRVM_ED_EdictSet_f(void)
                return;
        }
 
-       PRVM_Begin;
-       if(!PRVM_SetProgFromString(Cmd_Argv(1)))
-       {
-               Con_Printf("Wrong program name %s !\n", Cmd_Argv(1));
+       if (!(prog = PRVM_FriendlyProgFromString(Cmd_Argv(1))))
                return;
-       }
 
        ed = PRVM_EDICT_NUM(atoi(Cmd_Argv(2)));
 
-       if((key = PRVM_ED_FindField(Cmd_Argv(3))) == 0)
+       if((key = PRVM_ED_FindField(prog, Cmd_Argv(3))) == 0)
                Con_Printf("Key %s not found !\n", Cmd_Argv(3));
        else
-               PRVM_ED_ParseEpair(ed, key, Cmd_Argv(4), true);
-
-       PRVM_End;
+               PRVM_ED_ParseEpair(prog, ed, key, Cmd_Argv(4), true);
 }
 
 /*
@@ -1293,7 +1230,7 @@ ed should be a properly initialized empty edict.
 Used for initial level load and for savegames.
 ====================
 */
-const char *PRVM_ED_ParseEdict (const char *data, prvm_edict_t *ent)
+const char *PRVM_ED_ParseEdict (prvm_prog_t *prog, const char *data, prvm_edict_t *ent)
 {
        ddef_t *key;
        qboolean anglehack;
@@ -1308,7 +1245,7 @@ const char *PRVM_ED_ParseEdict (const char *data, prvm_edict_t *ent)
        {
        // parse key
                if (!COM_ParseToken_Simple(&data, false, false))
-                       PRVM_ERROR ("PRVM_ED_ParseEdict: EOF without closing brace");
+                       prog->error_cmd("PRVM_ED_ParseEdict: EOF without closing brace");
                if (developer_entityparsing.integer)
                        Con_Printf("Key: \"%s\"", com_token);
                if (com_token[0] == '}')
@@ -1340,12 +1277,12 @@ const char *PRVM_ED_ParseEdict (const char *data, prvm_edict_t *ent)
 
        // parse value
                if (!COM_ParseToken_Simple(&data, false, false))
-                       PRVM_ERROR ("PRVM_ED_ParseEdict: EOF without closing brace");
+                       prog->error_cmd("PRVM_ED_ParseEdict: EOF without closing brace");
                if (developer_entityparsing.integer)
                        Con_Printf(" \"%s\"\n", com_token);
 
                if (com_token[0] == '}')
-                       PRVM_ERROR ("PRVM_ED_ParseEdict: closing brace without data");
+                       prog->error_cmd("PRVM_ED_ParseEdict: closing brace without data");
 
                init = true;
 
@@ -1358,10 +1295,10 @@ const char *PRVM_ED_ParseEdict (const char *data, prvm_edict_t *ent)
                if (keyname[0] == '_')
                        continue;
 
-               key = PRVM_ED_FindField (keyname);
+               key = PRVM_ED_FindField (prog, keyname);
                if (!key)
                {
-                       Con_DPrintf("%s: '%s' is not a field\n", PRVM_NAME, keyname);
+                       Con_DPrintf("%s: '%s' is not a field\n", prog->name, keyname);
                        continue;
                }
 
@@ -1372,8 +1309,8 @@ const char *PRVM_ED_ParseEdict (const char *data, prvm_edict_t *ent)
                        dpsnprintf (com_token, sizeof(com_token), "0 %s 0", temp);
                }
 
-               if (!PRVM_ED_ParseEpair(ent, key, com_token, strcmp(keyname, "wad") != 0))
-                       PRVM_ERROR ("PRVM_ED_ParseEdict: parse error");
+               if (!PRVM_ED_ParseEpair(prog, ent, key, com_token, strcmp(keyname, "wad") != 0))
+                       prog->error_cmd("PRVM_ED_ParseEdict: parse error");
        }
 
        if (!init)
@@ -1398,12 +1335,13 @@ Used for both fresh maps and savegame loads.  A fresh map would also need
 to call PRVM_ED_CallSpawnFunctions () to let the objects initialize themselves.
 ================
 */
-void PRVM_ED_LoadFromFile (const char *data)
+void PRVM_ED_LoadFromFile (prvm_prog_t *prog, const char *data)
 {
        prvm_edict_t *ent;
        int parsed, inhibited, spawned, died;
        const char *funcname;
        mfunction_t *func;
+       char vabuf[1024];
 
        parsed = 0;
        inhibited = 0;
@@ -1419,7 +1357,7 @@ void PRVM_ED_LoadFromFile (const char *data)
                if (!COM_ParseToken_Simple(&data, false, false))
                        break;
                if (com_token[0] != '{')
-                       PRVM_ERROR ("PRVM_ED_LoadFromFile: %s: found %s when expecting {", PRVM_NAME, com_token);
+                       prog->error_cmd("PRVM_ED_LoadFromFile: %s: found %s when expecting {", prog->name, com_token);
 
                // CHANGED: this is not conform to PR_LoadFromFile
                if(prog->loadintoworld)
@@ -1428,19 +1366,19 @@ void PRVM_ED_LoadFromFile (const char *data)
                        ent = PRVM_EDICT_NUM(0);
                }
                else
-                       ent = PRVM_ED_Alloc();
+                       ent = PRVM_ED_Alloc(prog);
 
                // clear it
                if (ent != prog->edicts)        // hack
                        memset (ent->fields.vp, 0, prog->entityfields * 4);
 
-               data = PRVM_ED_ParseEdict (data, ent);
+               data = PRVM_ED_ParseEdict (prog, data, ent);
                parsed++;
 
                // remove the entity ?
-               if(prog->load_edict && !prog->load_edict(ent))
+               if(!prog->load_edict(prog, ent))
                {
-                       PRVM_ED_Free(ent);
+                       PRVM_ED_Free(prog, ent);
                        inhibited++;
                        continue;
                }
@@ -1448,8 +1386,9 @@ void PRVM_ED_LoadFromFile (const char *data)
                if (PRVM_serverfunction(SV_OnEntityPreSpawnFunction))
                {
                        // self = ent
+                       PRVM_serverglobalfloat(time) = sv.time;
                        PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
-                       PRVM_ExecuteProgram (PRVM_serverfunction(SV_OnEntityPreSpawnFunction), "QC function SV_OnEntityPreSpawnFunction is missing");
+                       prog->ExecuteProgram(prog, PRVM_serverfunction(SV_OnEntityPreSpawnFunction), "QC function SV_OnEntityPreSpawnFunction is missing");
                }
 
                if(ent->priv.required->free)
@@ -1466,17 +1405,17 @@ void PRVM_ED_LoadFromFile (const char *data)
                        if (!PRVM_alledictstring(ent, classname))
                        {
                                Con_Print("No classname for:\n");
-                               PRVM_ED_Print(ent, NULL);
-                               PRVM_ED_Free (ent);
+                               PRVM_ED_Print(prog, ent, NULL);
+                               PRVM_ED_Free (prog, ent);
                                continue;
                        }
 
                        // look for the spawn function
-                       funcname = PRVM_GetString(PRVM_alledictstring(ent, classname));
-                       func = PRVM_ED_FindFunction (va("spawnfunc_%s", funcname));
+                       funcname = PRVM_GetString(prog, PRVM_alledictstring(ent, classname));
+                       func = PRVM_ED_FindFunction (prog, va(vabuf, sizeof(vabuf), "spawnfunc_%s", funcname));
                        if(!func)
                                if(!PRVM_allglobalfloat(require_spawnfunc_prefix))
-                                       func = PRVM_ED_FindFunction (funcname);
+                                       func = PRVM_ED_FindFunction (prog, funcname);
 
                        if (!func)
                        {
@@ -1484,25 +1423,27 @@ void PRVM_ED_LoadFromFile (const char *data)
                                if (PRVM_serverfunction(SV_OnEntityNoSpawnFunction))
                                {
                                        // self = ent
+                                       PRVM_serverglobalfloat(time) = sv.time;
                                        PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
-                                       PRVM_ExecuteProgram (PRVM_serverfunction(SV_OnEntityNoSpawnFunction), "QC function SV_OnEntityNoSpawnFunction is missing");
+                                       prog->ExecuteProgram(prog, PRVM_serverfunction(SV_OnEntityNoSpawnFunction), "QC function SV_OnEntityNoSpawnFunction is missing");
                                }
                                else
                                {
                                        if (developer.integer > 0) // don't confuse non-developers with errors
                                        {
                                                Con_Print("No spawn function for:\n");
-                                               PRVM_ED_Print(ent, NULL);
+                                               PRVM_ED_Print(prog, ent, NULL);
                                        }
-                                       PRVM_ED_Free (ent);
+                                       PRVM_ED_Free (prog, ent);
                                        continue; // not included in "inhibited" count
                                }
                        }
                        else
                        {
                                // self = ent
+                               PRVM_serverglobalfloat(time) = sv.time;
                                PRVM_allglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
-                               PRVM_ExecuteProgram (func - prog->functions, "");
+                               prog->ExecuteProgram(prog, func - prog->functions, "");
                        }
                }
 
@@ -1510,8 +1451,9 @@ void PRVM_ED_LoadFromFile (const char *data)
                if (PRVM_serverfunction(SV_OnEntityPostSpawnFunction))
                {
                        // self = ent
+                       PRVM_serverglobalfloat(time) = sv.time;
                        PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
-                       PRVM_ExecuteProgram (PRVM_serverfunction(SV_OnEntityPostSpawnFunction), "QC function SV_OnEntityPostSpawnFunction is missing");
+                       prog->ExecuteProgram(prog, PRVM_serverfunction(SV_OnEntityPostSpawnFunction), "QC function SV_OnEntityPostSpawnFunction is missing");
                }
 
                spawned++;
@@ -1519,12 +1461,12 @@ void PRVM_ED_LoadFromFile (const char *data)
                        died++;
        }
 
-       Con_DPrintf("%s: %i new entities parsed, %i new inhibited, %i (%i new) spawned (whereas %i removed self, %i stayed)\n", PRVM_NAME, parsed, inhibited, prog->num_edicts, spawned, died, spawned - died);
+       Con_DPrintf("%s: %i new entities parsed, %i new inhibited, %i (%i new) spawned (whereas %i removed self, %i stayed)\n", prog->name, parsed, inhibited, prog->num_edicts, spawned, died, spawned - died);
 
        prvm_reuseedicts_always_allow = 0;
 }
 
-void PRVM_FindOffsets(void)
+static void PRVM_FindOffsets(prvm_prog_t *prog)
 {
        // field and global searches use -1 for NULL
        memset(&prog->fieldoffsets, -1, sizeof(prog->fieldoffsets));
@@ -1564,9 +1506,9 @@ void PRVM_FindOffsets(void)
 #define PRVM_DECLARE_serverfunction(x)
 #define PRVM_DECLARE_clientfunction(x)
 #define PRVM_DECLARE_menufunction(x)
-#define PRVM_DECLARE_field(x) prog->fieldoffsets.x = PRVM_ED_FindFieldOffset(#x);
-#define PRVM_DECLARE_global(x) prog->globaloffsets.x = PRVM_ED_FindGlobalOffset(#x);
-#define PRVM_DECLARE_function(x) prog->funcoffsets.x = PRVM_ED_FindFunctionOffset(#x);
+#define PRVM_DECLARE_field(x) prog->fieldoffsets.x = PRVM_ED_FindFieldOffset(prog, #x);
+#define PRVM_DECLARE_global(x) prog->globaloffsets.x = PRVM_ED_FindGlobalOffset(prog, #x);
+#define PRVM_DECLARE_function(x) prog->funcoffsets.x = PRVM_ED_FindFunctionOffset(prog, #x);
 #include "prvm_offsets.h"
 #undef PRVM_DECLARE_serverglobalfloat
 #undef PRVM_DECLARE_serverglobalvector
@@ -1640,7 +1582,7 @@ typedef struct po_s
        po_string_t *hashtable[PO_HASHSIZE];
 }
 po_t;
-void PRVM_PO_UnparseString(char *out, const char *in, size_t outsize)
+static void PRVM_PO_UnparseString(char *out, const char *in, size_t outsize)
 {
        for(;;)
        {
@@ -1681,7 +1623,7 @@ void PRVM_PO_UnparseString(char *out, const char *in, size_t outsize)
                ++in;
        }
 }
-void PRVM_PO_ParseString(char *out, const char *in, size_t outsize)
+static void PRVM_PO_ParseString(char *out, const char *in, size_t outsize)
 {
        for(;;)
        {
@@ -1740,7 +1682,7 @@ void PRVM_PO_ParseString(char *out, const char *in, size_t outsize)
                ++in;
        }
 }
-po_t *PRVM_PO_Load(const char *filename, mempool_t *pool)
+static po_t *PRVM_PO_Load(const char *filename, mempool_t *pool)
 {
        po_t *po;
        const char *p, *q;
@@ -1839,7 +1781,7 @@ po_t *PRVM_PO_Load(const char *filename, mempool_t *pool)
        Mem_Free((char *) buf);
        return po;
 }
-const char *PRVM_PO_Lookup(po_t *po, const char *str)
+static const char *PRVM_PO_Lookup(po_t *po, const char *str)
 {
        int hashindex = CRC_Block((const unsigned char *) str, strlen(str)) % PO_HASHSIZE;
        po_string_t *p = po->hashtable[hashindex];
@@ -1851,7 +1793,7 @@ const char *PRVM_PO_Lookup(po_t *po, const char *str)
        }
        return NULL;
 }
-void PRVM_PO_Destroy(po_t *po)
+static void PRVM_PO_Destroy(po_t *po)
 {
        int i;
        for(i = 0; i < PO_HASHSIZE; ++i)
@@ -1869,16 +1811,15 @@ void PRVM_PO_Destroy(po_t *po)
        Mem_Free(po);
 }
 
-void PRVM_LeakTest(void);
-void PRVM_ResetProg(void)
+void PRVM_LeakTest(prvm_prog_t *prog);
+void PRVM_Prog_Reset(prvm_prog_t *prog)
 {
-       PRVM_LeakTest();
-       PRVM_GCALL(reset_cmd)();
+       PRVM_LeakTest(prog);
+       prog->reset_cmd(prog);
        Mem_FreePool(&prog->progs_mempool);
        if(prog->po)
                PRVM_PO_Destroy((po_t *) prog->po);
        memset(prog,0,sizeof(prvm_prog_t));
-       prog->starttime = Sys_DoubleTime();
 }
 
 /*
@@ -1886,7 +1827,7 @@ void PRVM_ResetProg(void)
 PRVM_LoadLNO
 ===============
 */
-void PRVM_LoadLNO( const char *progname ) {
+static void PRVM_LoadLNO( prvm_prog_t *prog, const char *progname ) {
        fs_offset_t filesize;
        unsigned char *lno;
        unsigned int *header;
@@ -1934,7 +1875,7 @@ void PRVM_LoadLNO( const char *progname ) {
 PRVM_LoadProgs
 ===============
 */
-void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **required_func, int numrequiredfields, prvm_required_field_t *required_field, int numrequiredglobals, prvm_required_field_t *required_global)
+void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, int numrequiredfunc, const char **required_func, int numrequiredfields, prvm_required_field_t *required_field, int numrequiredglobals, prvm_required_field_t *required_global)
 {
        int i;
        dprograms_t *dprograms;
@@ -1950,16 +1891,19 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
        int a;
        int b;
        int c;
+       char vabuf[1024];
 
        if (prog->loaded)
-               PRVM_ERROR ("PRVM_LoadProgs: there is already a %s program loaded!", PRVM_NAME );
+               prog->error_cmd("PRVM_LoadProgs: there is already a %s program loaded!", prog->name );
 
        dprograms = (dprograms_t *)FS_LoadFile (filename, prog->progs_mempool, false, &filesize);
        if (dprograms == NULL || filesize < (fs_offset_t)sizeof(dprograms_t))
-               PRVM_ERROR ("PRVM_LoadProgs: couldn't load %s for %s", filename, PRVM_NAME);
+               prog->error_cmd("PRVM_LoadProgs: couldn't load %s for %s", filename, prog->name);
        // TODO bounds check header fields (e.g. numstatements), they must never go behind end of file
 
-       Con_DPrintf("%s programs occupy %iK.\n", PRVM_NAME, (int)(filesize/1024));
+       prog->profiletime = prog->starttime = Sys_DirtyTime();
+
+       Con_DPrintf("%s programs occupy %iK.\n", prog->name, (int)(filesize/1024));
 
        requiredglobalspace = 0;
        for (i = 0;i < numrequiredglobals;i++)
@@ -1971,7 +1915,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
        prog->progs_version = LittleLong(dprograms->version);
        prog->progs_crc = LittleLong(dprograms->crc);
        if (prog->progs_version != PROG_VERSION)
-               PRVM_ERROR ("%s: %s has wrong version number (%i should be %i)", PRVM_NAME, filename, prog->progs_version, PROG_VERSION);
+               prog->error_cmd("%s: %s has wrong version number (%i should be %i)", prog->name, filename, prog->progs_version, PROG_VERSION);
        instatements = (dstatement_t *)((unsigned char *)dprograms + LittleLong(dprograms->ofs_statements));
        prog->progs_numstatements = LittleLong(dprograms->numstatements);
        inglobaldefs = (ddef_t *)((unsigned char *)dprograms + LittleLong(dprograms->ofs_globaldefs));
@@ -1995,7 +1939,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
        prog->entityfields = prog->progs_entityfields;
 
        if (LittleLong(dprograms->ofs_strings) + prog->progs_numstrings >= (int)filesize)
-               PRVM_ERROR ("%s: %s strings go past end of file", PRVM_NAME, filename);
+               prog->error_cmd("%s: %s strings go past end of file", prog->name, filename);
        prog->strings = (char *)Mem_Alloc(prog->progs_mempool, prog->progs_numstrings);
        memcpy(prog->strings, instrings, prog->progs_numstrings);
        prog->stringssize = prog->progs_numstrings;
@@ -2028,7 +1972,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                prog->functions[i].locals = LittleLong(infunctions[i].locals);
                memcpy(prog->functions[i].parm_size, infunctions[i].parm_size, sizeof(infunctions[i].parm_size));
                if(prog->functions[i].first_statement >= prog->numstatements)
-                       PRVM_ERROR("PRVM_LoadProgs: out of bounds function statement (function %d) in %s", i, PRVM_NAME);
+                       prog->error_cmd("PRVM_LoadProgs: out of bounds function statement (function %d) in %s", i, prog->name);
                // TODO bounds check parm_start, s_name, s_file, numparms, locals, parm_size
        }
 
@@ -2046,7 +1990,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
        {
                prog->globaldefs[prog->numglobaldefs].type = required_global[i].type;
                prog->globaldefs[prog->numglobaldefs].ofs = prog->numglobals;
-               prog->globaldefs[prog->numglobaldefs].s_name = PRVM_SetEngineString(required_global[i].name);
+               prog->globaldefs[prog->numglobaldefs].s_name = PRVM_SetEngineString(prog, required_global[i].name);
                if (prog->globaldefs[prog->numglobaldefs].type == ev_vector)
                        prog->numglobals += 3;
                else
@@ -2059,7 +2003,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
        {
                prog->fielddefs[i].type = LittleShort(infielddefs[i].type);
                if (prog->fielddefs[i].type & DEF_SAVEGLOBAL)
-                       PRVM_ERROR ("PRVM_LoadProgs: prog->fielddefs[i].type & DEF_SAVEGLOBAL in %s", PRVM_NAME);
+                       prog->error_cmd("PRVM_LoadProgs: prog->fielddefs[i].type & DEF_SAVEGLOBAL in %s", prog->name);
                prog->fielddefs[i].ofs = LittleShort(infielddefs[i].ofs);
                prog->fielddefs[i].s_name = LittleLong(infielddefs[i].s_name);
                // TODO bounds check ofs, s_name
@@ -2070,7 +2014,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
        {
                prog->fielddefs[prog->numfielddefs].type = required_field[i].type;
                prog->fielddefs[prog->numfielddefs].ofs = prog->entityfields;
-               prog->fielddefs[prog->numfielddefs].s_name = PRVM_SetEngineString(required_field[i].name);
+               prog->fielddefs[prog->numfielddefs].s_name = PRVM_SetEngineString(prog, required_field[i].name);
                if (prog->fielddefs[prog->numfielddefs].type == ev_vector)
                        prog->entityfields += 3;
                else
@@ -2101,7 +2045,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                case OP_IFNOT:
                        b = (short)b;
                        if (a >= prog->progs_numglobals || b + i < 0 || b + i >= prog->progs_numstatements)
-                               PRVM_ERROR("PRVM_LoadProgs: out of bounds IF/IFNOT (statement %d) in %s", i, PRVM_NAME);
+                               prog->error_cmd("PRVM_LoadProgs: out of bounds IF/IFNOT (statement %d) in %s", i, prog->name);
                        prog->statements[i].op = op;
                        prog->statements[i].operand[0] = remapglobal(a);
                        prog->statements[i].operand[1] = -1;
@@ -2111,7 +2055,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                case OP_GOTO:
                        a = (short)a;
                        if (a + i < 0 || a + i >= prog->progs_numstatements)
-                               PRVM_ERROR("PRVM_LoadProgs: out of bounds GOTO (statement %d) in %s", i, PRVM_NAME);
+                               prog->error_cmd("PRVM_LoadProgs: out of bounds GOTO (statement %d) in %s", i, prog->name);
                        prog->statements[i].op = op;
                        prog->statements[i].operand[0] = -1;
                        prog->statements[i].operand[1] = -1;
@@ -2119,7 +2063,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                        prog->statements[i].jumpabsolute = i + a;
                        break;
                default:
-                       Con_DPrintf("PRVM_LoadProgs: unknown opcode %d at statement %d in %s\n", (int)op, i, PRVM_NAME);
+                       Con_DPrintf("PRVM_LoadProgs: unknown opcode %d at statement %d in %s\n", (int)op, i, prog->name);
                // global global global
                case OP_ADD_F:
                case OP_ADD_V:
@@ -2156,7 +2100,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                case OP_LOAD_FNC:
                case OP_LOAD_V:
                        if (a >= prog->progs_numglobals || b >= prog->progs_numglobals || c >= prog->progs_numglobals)
-                               PRVM_ERROR("PRVM_LoadProgs: out of bounds global index (statement %d)", i);
+                               prog->error_cmd("PRVM_LoadProgs: out of bounds global index (statement %d)", i);
                        prog->statements[i].op = op;
                        prog->statements[i].operand[0] = remapglobal(a);
                        prog->statements[i].operand[1] = remapglobal(b);
@@ -2170,7 +2114,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                case OP_NOT_FNC:
                case OP_NOT_ENT:
                        if (a >= prog->progs_numglobals || c >= prog->progs_numglobals)
-                               PRVM_ERROR("PRVM_LoadProgs: out of bounds global index (statement %d) in %s", i, PRVM_NAME);
+                               prog->error_cmd("PRVM_LoadProgs: out of bounds global index (statement %d) in %s", i, prog->name);
                        prog->statements[i].op = op;
                        prog->statements[i].operand[0] = remapglobal(a);
                        prog->statements[i].operand[1] = -1;
@@ -2192,7 +2136,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                case OP_STOREP_V:
                case OP_STORE_V:
                        if (a >= prog->progs_numglobals || b >= prog->progs_numglobals)
-                               PRVM_ERROR("PRVM_LoadProgs: out of bounds global index (statement %d) in %s", i, PRVM_NAME);
+                               prog->error_cmd("PRVM_LoadProgs: out of bounds global index (statement %d) in %s", i, prog->name);
                        prog->statements[i].op = op;
                        prog->statements[i].operand[0] = remapglobal(a);
                        prog->statements[i].operand[1] = remapglobal(b);
@@ -2212,7 +2156,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                case OP_DONE:
                case OP_RETURN:
                        if ( a >= prog->progs_numglobals)
-                               PRVM_ERROR("PRVM_LoadProgs: out of bounds global index (statement %d) in %s", i, PRVM_NAME);
+                               prog->error_cmd("PRVM_LoadProgs: out of bounds global index (statement %d) in %s", i, prog->name);
                        prog->statements[i].op = op;
                        prog->statements[i].operand[0] = remapglobal(a);
                        prog->statements[i].operand[1] = -1;
@@ -2223,7 +2167,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
        }
        if(prog->numstatements < 1)
        {
-               PRVM_ERROR("PRVM_LoadProgs: empty program in %s", PRVM_NAME);
+               prog->error_cmd("PRVM_LoadProgs: empty program in %s", prog->name);
        }
        else switch(prog->statements[prog->numstatements - 1].op)
        {
@@ -2232,7 +2176,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                case OP_DONE:
                        break;
                default:
-                       PRVM_ERROR("PRVM_LoadProgs: program may fall off the edge (does not end with RETURN, GOTO or DONE) in %s", PRVM_NAME);
+                       prog->error_cmd("PRVM_LoadProgs: program may fall off the edge (does not end with RETURN, GOTO or DONE) in %s", prog->name);
                        break;
        }
 
@@ -2242,25 +2186,25 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
 
        // check required functions
        for(i=0 ; i < numrequiredfunc ; i++)
-               if(PRVM_ED_FindFunction(required_func[i]) == 0)
-                       PRVM_ERROR("%s: %s not found in %s",PRVM_NAME, required_func[i], filename);
+               if(PRVM_ED_FindFunction(prog, required_func[i]) == 0)
+                       prog->error_cmd("%s: %s not found in %s",prog->name, required_func[i], filename);
 
-       PRVM_LoadLNO(filename);
+       PRVM_LoadLNO(prog, filename);
 
-       PRVM_Init_Exec();
+       PRVM_Init_Exec(prog);
 
        if(*prvm_language.string)
        // in CSQC we really shouldn't be able to change how stuff works... sorry for now
        // later idea: include a list of authorized .po file checksums with the csprogs
        {
-               qboolean deftrans = !!strcmp(PRVM_NAME, "client");
-               const char *realfilename = (strcmp(PRVM_NAME, "client") ? filename : csqc_progname.string);
+               qboolean deftrans = prog == CLVM_prog;
+               const char *realfilename = (prog != CLVM_prog ? filename : csqc_progname.string);
                if(deftrans) // once we have dotranslate_ strings, ALWAYS use the opt-in method!
                {
                        for (i=0 ; i<prog->numglobaldefs ; i++)
                        {
                                const char *name;
-                               name = PRVM_GetString(prog->globaldefs[i].s_name);
+                               name = PRVM_GetString(prog, prog->globaldefs[i].s_name);
                                if((prog->globaldefs[i].type & ~DEF_SAVEGLOBAL) == ev_string)
                                if(name && !strncmp(name, "dotranslate_", 12))
                                {
@@ -2271,19 +2215,19 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                }
                if(!strcmp(prvm_language.string, "dump"))
                {
-                       qfile_t *f = FS_OpenRealFile(va("%s.pot", realfilename), "w", false);
+                       qfile_t *f = FS_OpenRealFile(va(vabuf, sizeof(vabuf), "%s.pot", realfilename), "w", false);
                        Con_Printf("Dumping to %s.pot\n", realfilename);
                        if(f)
                        {
                                for (i=0 ; i<prog->numglobaldefs ; i++)
                                {
                                        const char *name;
-                                       name = PRVM_GetString(prog->globaldefs[i].s_name);
+                                       name = PRVM_GetString(prog, prog->globaldefs[i].s_name);
                                        if(deftrans ? (!name || strncmp(name, "notranslate_", 12)) : (name && !strncmp(name, "dotranslate_", 12)))
                                        if((prog->globaldefs[i].type & ~DEF_SAVEGLOBAL) == ev_string)
                                        {
                                                prvm_eval_t *val = PRVM_GLOBALFIELDVALUE(prog->globaldefs[i].ofs);
-                                               const char *value = PRVM_GetString(val->string);
+                                               const char *value = PRVM_GetString(prog, val->string);
                                                if(*value)
                                                {
                                                        char buf[MAX_INPUTLINE];
@@ -2297,23 +2241,23 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                }
                else
                {
-                       po_t *po = PRVM_PO_Load(va("%s.%s.po", realfilename, prvm_language.string), prog->progs_mempool);
+                       po_t *po = PRVM_PO_Load(va(vabuf, sizeof(vabuf), "%s.%s.po", realfilename, prvm_language.string), prog->progs_mempool);
                        if(po)
                        {
                                for (i=0 ; i<prog->numglobaldefs ; i++)
                                {
                                        const char *name;
-                                       name = PRVM_GetString(prog->globaldefs[i].s_name);
+                                       name = PRVM_GetString(prog, prog->globaldefs[i].s_name);
                                        if(deftrans ? (!name || strncmp(name, "notranslate_", 12)) : (name && !strncmp(name, "dotranslate_", 12)))
                                        if((prog->globaldefs[i].type & ~DEF_SAVEGLOBAL) == ev_string)
                                        {
                                                prvm_eval_t *val = PRVM_GLOBALFIELDVALUE(prog->globaldefs[i].ofs);
-                                               const char *value = PRVM_GetString(val->string);
+                                               const char *value = PRVM_GetString(prog, val->string);
                                                if(*value)
                                                {
                                                        value = PRVM_PO_Lookup(po, value);
                                                        if(value)
-                                                               val->string = PRVM_SetEngineString(value);
+                                                               val->string = PRVM_SetEngineString(prog, value);
                                                }
                                        }
                                }
@@ -2324,7 +2268,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
        for (i=0 ; i<prog->numglobaldefs ; i++)
        {
                const char *name;
-               name = PRVM_GetString(prog->globaldefs[i].s_name);
+               name = PRVM_GetString(prog, prog->globaldefs[i].s_name);
                //Con_Printf("found var %s\n", name);
                if(name
                        && !strncmp(name, "autocvar_", 9)
@@ -2333,12 +2277,12 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                {
                        prvm_eval_t *val = PRVM_GLOBALFIELDVALUE(prog->globaldefs[i].ofs);
                        cvar_t *cvar = Cvar_FindVar(name + 9);
-                       //Con_Printf("PRVM_LoadProgs: autocvar global %s in %s, processing...\n", name, PRVM_NAME);
+                       //Con_Printf("PRVM_LoadProgs: autocvar global %s in %s, processing...\n", name, prog->name);
                        if(!cvar)
                        {
                                const char *value;
                                char buf[64];
-                               Con_DPrintf("PRVM_LoadProgs: no cvar for autocvar global %s in %s, creating...\n", name, PRVM_NAME);
+                               Con_DPrintf("PRVM_LoadProgs: no cvar for autocvar global %s in %s, creating...\n", name, prog->name);
                                switch(prog->globaldefs[i].type & ~DEF_SAVEGLOBAL)
                                {
                                        case ev_float:
@@ -2352,22 +2296,22 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                                                dpsnprintf(buf, sizeof(buf), "%.9g %.9g %.9g", val->vector[0], val->vector[1], val->vector[2]); value = buf;
                                                break;
                                        case ev_string:
-                                               value = PRVM_GetString(val->string);
+                                               value = PRVM_GetString(prog, val->string);
                                                break;
                                        default:
-                                               Con_Printf("PRVM_LoadProgs: invalid type of autocvar global %s in %s\n", name, PRVM_NAME);
+                                               Con_Printf("PRVM_LoadProgs: invalid type of autocvar global %s in %s\n", name, prog->name);
                                                goto fail;
                                }
                                cvar = Cvar_Get(name + 9, value, 0, NULL);
                                if((prog->globaldefs[i].type & ~DEF_SAVEGLOBAL) == ev_string)
                                {
-                                       val->string = PRVM_SetEngineString(cvar->string);
-                                       cvar->globaldefindex_stringno[prog - prog_list] = val->string;
+                                       val->string = PRVM_SetEngineString(prog, cvar->string);
+                                       cvar->globaldefindex_stringno[prog - prvm_prog_list] = val->string;
                                }
                                if(!cvar)
-                                       PRVM_ERROR("PRVM_LoadProgs: could not create cvar for autocvar global %s in %s", name, PRVM_NAME);
-                               cvar->globaldefindex_progid[prog - prog_list] = prog->id;
-                               cvar->globaldefindex[prog - prog_list] = i;
+                                       prog->error_cmd("PRVM_LoadProgs: could not create cvar for autocvar global %s in %s", name, prog->name);
+                               cvar->globaldefindex_progid[prog - prvm_prog_list] = prog->id;
+                               cvar->globaldefindex[prog - prvm_prog_list] = i;
                        }
                        else if((cvar->flags & CVAR_PRIVATE) == 0)
                        {
@@ -2396,18 +2340,18 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                                                }
                                                break;
                                        case ev_string:
-                                               val->string = PRVM_SetEngineString(cvar->string);
-                                               cvar->globaldefindex_stringno[prog - prog_list] = val->string;
+                                               val->string = PRVM_SetEngineString(prog, cvar->string);
+                                               cvar->globaldefindex_stringno[prog - prvm_prog_list] = val->string;
                                                break;
                                        default:
-                                               Con_Printf("PRVM_LoadProgs: invalid type of autocvar global %s in %s\n", name, PRVM_NAME);
+                                               Con_Printf("PRVM_LoadProgs: invalid type of autocvar global %s in %s\n", name, prog->name);
                                                goto fail;
                                }
-                               cvar->globaldefindex_progid[prog - prog_list] = prog->id;
-                               cvar->globaldefindex[prog - prog_list] = i;
+                               cvar->globaldefindex_progid[prog - prvm_prog_list] = prog->id;
+                               cvar->globaldefindex[prog - prvm_prog_list] = i;
                        }
                        else
-                               Con_Printf("PRVM_LoadProgs: private cvar for autocvar global %s in %s\n", name, PRVM_NAME);
+                               Con_Printf("PRVM_LoadProgs: private cvar for autocvar global %s in %s\n", name, prog->name);
                }
 fail:
                ;
@@ -2419,17 +2363,18 @@ fail:
 
        prog->flag = 0;
 
-       PRVM_FindOffsets();
+       PRVM_FindOffsets(prog);
 
-       PRVM_GCALL(init_cmd)();
+       prog->init_cmd(prog);
 
        // init mempools
-       PRVM_MEM_Alloc();
+       PRVM_MEM_Alloc(prog);
 }
 
 
-void PRVM_Fields_f (void)
+static void PRVM_Fields_f (void)
 {
+       prvm_prog_t *prog;
        int i, j, ednum, used, usedamount;
        int *counts;
        char tempstring[MAX_INPUTLINE], tempstring2[260];
@@ -2453,8 +2398,7 @@ void PRVM_Fields_f (void)
                return;
        }
 
-       PRVM_Begin;
-       if(!PRVM_SetProgFromString(Cmd_Argv(1)))
+       if (!(prog = PRVM_FriendlyProgFromString(Cmd_Argv(1))))
                return;
 
        counts = (int *)Mem_Alloc(tempmempool, prog->numfielddefs * sizeof(int));
@@ -2466,7 +2410,7 @@ void PRVM_Fields_f (void)
                for (i = 1;i < prog->numfielddefs;i++)
                {
                        d = &prog->fielddefs[i];
-                       name = PRVM_GetString(d->s_name);
+                       name = PRVM_GetString(prog, d->s_name);
                        if (name[strlen(name)-2] == '_')
                                continue;       // skip _x, _y, _z vars
                        v = (int *)(ed->fields.vp + d->ofs);
@@ -2487,7 +2431,7 @@ void PRVM_Fields_f (void)
        for (i = 0;i < prog->numfielddefs;i++)
        {
                d = &prog->fielddefs[i];
-               name = PRVM_GetString(d->s_name);
+               name = PRVM_GetString(prog, d->s_name);
                if (name[strlen(name)-2] == '_')
                        continue;       // skip _x, _y, _z vars
                switch(d->type & ~DEF_SAVEGLOBAL)
@@ -2546,13 +2490,12 @@ void PRVM_Fields_f (void)
                }
        }
        Mem_Free(counts);
-       Con_Printf("%s: %i entity fields (%i in use), totalling %i bytes per edict (%i in use), %i edicts allocated, %i bytes total spent on edict fields (%i needed)\n", PRVM_NAME, prog->entityfields, used, prog->entityfields * 4, usedamount * 4, prog->max_edicts, prog->entityfields * 4 * prog->max_edicts, usedamount * 4 * prog->max_edicts);
-
-       PRVM_End;
+       Con_Printf("%s: %i entity fields (%i in use), totalling %i bytes per edict (%i in use), %i edicts allocated, %i bytes total spent on edict fields (%i needed)\n", prog->name, prog->entityfields, used, prog->entityfields * 4, usedamount * 4, prog->max_edicts, prog->entityfields * 4 * prog->max_edicts, usedamount * 4 * prog->max_edicts);
 }
 
-void PRVM_Globals_f (void)
+static void PRVM_Globals_f (void)
 {
+       prvm_prog_t *prog;
        int i;
        const char *wildcard;
        int numculled;
@@ -2569,8 +2512,7 @@ void PRVM_Globals_f (void)
                return;
        }
 
-       PRVM_Begin;
-       if(!PRVM_SetProgFromString (Cmd_Argv (1)))
+       if (!(prog = PRVM_FriendlyProgFromString(Cmd_Argv(1))))
                return;
 
        if( Cmd_Argc() == 3)
@@ -2578,21 +2520,19 @@ void PRVM_Globals_f (void)
        else
                wildcard = NULL;
 
-       Con_Printf("%s :", PRVM_NAME);
+       Con_Printf("%s :", prog->name);
 
        for (i = 0;i < prog->numglobaldefs;i++)
        {
                if(wildcard)
-                       if( !matchpattern( PRVM_GetString(prog->globaldefs[i].s_name), wildcard, 1) )
+                       if( !matchpattern( PRVM_GetString(prog, prog->globaldefs[i].s_name), wildcard, 1) )
                        {
                                numculled++;
                                continue;
                        }
-               Con_Printf("%s\n", PRVM_GetString(prog->globaldefs[i].s_name));
+               Con_Printf("%s\n", PRVM_GetString(prog, prog->globaldefs[i].s_name));
        }
        Con_Printf("%i global variables, %i culled, totalling %i bytes\n", prog->numglobals, numculled, prog->numglobals * 4);
-
-       PRVM_End;
 }
 
 /*
@@ -2600,24 +2540,24 @@ void PRVM_Globals_f (void)
 PRVM_Global
 ===============
 */
-void PRVM_Global_f(void)
+static void PRVM_Global_f(void)
 {
+       prvm_prog_t *prog;
        ddef_t *global;
+       char valuebuf[MAX_INPUTLINE];
        if( Cmd_Argc() != 3 ) {
                Con_Printf( "prvm_global <program name> <global name>\n" );
                return;
        }
 
-       PRVM_Begin;
-       if( !PRVM_SetProgFromString( Cmd_Argv(1) ) )
+       if (!(prog = PRVM_FriendlyProgFromString(Cmd_Argv(1))))
                return;
 
-       global = PRVM_ED_FindGlobal( Cmd_Argv(2) );
+       global = PRVM_ED_FindGlobal( prog, Cmd_Argv(2) );
        if( !global )
                Con_Printf( "No global '%s' in %s!\n", Cmd_Argv(2), Cmd_Argv(1) );
        else
-               Con_Printf( "%s: %s\n", Cmd_Argv(2), PRVM_ValueString( (etype_t)global->type, PRVM_GLOBALFIELDVALUE(global->ofs) ) );
-       PRVM_End;
+               Con_Printf( "%s: %s\n", Cmd_Argv(2), PRVM_ValueString( prog, (etype_t)global->type, PRVM_GLOBALFIELDVALUE(global->ofs), valuebuf, sizeof(valuebuf) ) );
 }
 
 /*
@@ -2625,24 +2565,23 @@ void PRVM_Global_f(void)
 PRVM_GlobalSet
 ===============
 */
-void PRVM_GlobalSet_f(void)
+static void PRVM_GlobalSet_f(void)
 {
+       prvm_prog_t *prog;
        ddef_t *global;
        if( Cmd_Argc() != 4 ) {
                Con_Printf( "prvm_globalset <program name> <global name> <value>\n" );
                return;
        }
 
-       PRVM_Begin;
-       if( !PRVM_SetProgFromString( Cmd_Argv(1) ) )
+       if (!(prog = PRVM_FriendlyProgFromString(Cmd_Argv(1))))
                return;
 
-       global = PRVM_ED_FindGlobal( Cmd_Argv(2) );
+       global = PRVM_ED_FindGlobal( prog, Cmd_Argv(2) );
        if( !global )
                Con_Printf( "No global '%s' in %s!\n", Cmd_Argv(2), Cmd_Argv(1) );
        else
-               PRVM_ED_ParseEpair( NULL, global, Cmd_Argv(3), true );
-       PRVM_End;
+               PRVM_ED_ParseEpair( prog, NULL, global, Cmd_Argv(3), true );
 }
 
 /*
@@ -2692,68 +2631,30 @@ void PRVM_Init (void)
 PRVM_InitProg
 ===============
 */
-void PRVM_InitProg(int prognr)
+void PRVM_Prog_Init(prvm_prog_t *prog)
 {
-       static unsigned int progid = 0;
-
-       if(prognr < 0 || prognr >= PRVM_MAXPROGS)
-               Sys_Error("PRVM_InitProg: Invalid program number %i",prognr);
-
-       prog = &prog_list[prognr];
-
-       if(prog->loaded)
-               PRVM_ResetProg();
+       if (prog->loaded)
+               PRVM_Prog_Reset(prog);
 
        memset(prog, 0, sizeof(prvm_prog_t));
-       prog->starttime = Sys_DoubleTime();
-       prog->id = ++progid;
-
-       prog->error_cmd = Host_Error;
        prog->leaktest_active = prvm_leaktest.integer != 0;
 }
 
-int PRVM_GetProgNr(void)
-{
-       return prog - prog_list;
-}
-
-void *_PRVM_Alloc(size_t buffersize, const char *filename, int fileline)
-{
-       return _Mem_Alloc(prog->progs_mempool, NULL, buffersize, 16, filename, fileline);
-}
-
-void _PRVM_Free(void *buffer, const char *filename, int fileline)
-{
-       _Mem_Free(buffer, filename, fileline);
-}
-
-void _PRVM_FreeAll(const char *filename, int fileline)
-{
-       prog->functions = NULL;
-       prog->strings = NULL;
-       prog->fielddefs = NULL;
-       prog->globaldefs = NULL;
-       prog->statements = NULL;
-       // FIXME: what about knownstrings?
-       _Mem_EmptyPool(prog->progs_mempool, filename, fileline);
-}
-
 // LordHavoc: turned PRVM_EDICT_NUM into a #define for speed reasons
-unsigned int PRVM_EDICT_NUM_ERROR(unsigned int n, const char *filename, int fileline)
+unsigned int PRVM_EDICT_NUM_ERROR(prvm_prog_t *prog, unsigned int n, const char *filename, int fileline)
 {
-       PRVM_ERROR ("PRVM_EDICT_NUM: %s: bad number %i (called at %s:%i)", PRVM_NAME, n, filename, fileline);
+       prog->error_cmd("PRVM_EDICT_NUM: %s: bad number %i (called at %s:%i)", prog->name, n, filename, fileline);
        return 0;
 }
 
-sizebuf_t vm_tempstringsbuf;
 #define PRVM_KNOWNSTRINGBASE 0x40000000
 
-const char *PRVM_GetString(int num)
+const char *PRVM_GetString(prvm_prog_t *prog, int num)
 {
        if (num < 0)
        {
                // invalid
-               VM_Warning("PRVM_GetString: Invalid string offset (%i < 0)\n", num);
+               VM_Warning(prog, "PRVM_GetString: Invalid string offset (%i < 0)\n", num);
                return "";
        }
        else if (num < prog->stringssize)
@@ -2761,15 +2662,15 @@ const char *PRVM_GetString(int num)
                // constant string from progs.dat
                return prog->strings + num;
        }
-       else if (num <= prog->stringssize + vm_tempstringsbuf.maxsize)
+       else if (num <= prog->stringssize + prog->tempstringsbuf.maxsize)
        {
                // tempstring returned by engine to QC (becomes invalid after returning to engine)
                num -= prog->stringssize;
-               if (num < vm_tempstringsbuf.cursize)
-                       return (char *)vm_tempstringsbuf.data + num;
+               if (num < prog->tempstringsbuf.cursize)
+                       return (char *)prog->tempstringsbuf.data + num;
                else
                {
-                       VM_Warning("PRVM_GetString: Invalid temp-string offset (%i >= %i vm_tempstringsbuf.cursize)\n", num, vm_tempstringsbuf.cursize);
+                       VM_Warning(prog, "PRVM_GetString: Invalid temp-string offset (%i >= %i prog->tempstringsbuf.cursize)\n", num, prog->tempstringsbuf.cursize);
                        return "";
                }
        }
@@ -2781,48 +2682,48 @@ const char *PRVM_GetString(int num)
                {
                        if (!prog->knownstrings[num])
                        {
-                               VM_Warning("PRVM_GetString: Invalid zone-string offset (%i has been freed)\n", num);
+                               VM_Warning(prog, "PRVM_GetString: Invalid zone-string offset (%i has been freed)\n", num);
                                return "";
                        }
                        return prog->knownstrings[num];
                }
                else
                {
-                       VM_Warning("PRVM_GetString: Invalid zone-string offset (%i >= %i)\n", num, prog->numknownstrings);
+                       VM_Warning(prog, "PRVM_GetString: Invalid zone-string offset (%i >= %i)\n", num, prog->numknownstrings);
                        return "";
                }
        }
        else
        {
                // invalid string offset
-               VM_Warning("PRVM_GetString: Invalid constant-string offset (%i >= %i prog->stringssize)\n", num, prog->stringssize);
+               VM_Warning(prog, "PRVM_GetString: Invalid constant-string offset (%i >= %i prog->stringssize)\n", num, prog->stringssize);
                return "";
        }
 }
 
-const char *PRVM_ChangeEngineString(int i, const char *s)
+const char *PRVM_ChangeEngineString(prvm_prog_t *prog, int i, const char *s)
 {
        const char *old;
        i = i - PRVM_KNOWNSTRINGBASE;
        if(i < 0 || i >= prog->numknownstrings)
-               PRVM_ERROR("PRVM_ChangeEngineString: s is not an engine string");
+               prog->error_cmd("PRVM_ChangeEngineString: s is not an engine string");
        old = prog->knownstrings[i];
        prog->knownstrings[i] = s;
        return old;
 }
 
-int PRVM_SetEngineString(const char *s)
+int PRVM_SetEngineString(prvm_prog_t *prog, const char *s)
 {
        int i;
        if (!s)
                return 0;
        if (s >= prog->strings && s <= prog->strings + prog->stringssize)
-               PRVM_ERROR("PRVM_SetEngineString: s in prog->strings area");
+               prog->error_cmd("PRVM_SetEngineString: s in prog->strings area");
        // if it's in the tempstrings area, use a reserved range
        // (otherwise we'd get millions of useless string offsets cluttering the database)
-       if (s >= (char *)vm_tempstringsbuf.data && s < (char *)vm_tempstringsbuf.data + vm_tempstringsbuf.maxsize)
+       if (s >= (char *)prog->tempstringsbuf.data && s < (char *)prog->tempstringsbuf.data + prog->tempstringsbuf.maxsize)
 #if 1
-               return prog->stringssize + (s - (char *)vm_tempstringsbuf.data);
+               return prog->stringssize + (s - (char *)prog->tempstringsbuf.data);
 #endif
        // see if it's a known string address
        for (i = 0;i < prog->numknownstrings;i++)
@@ -2873,7 +2774,7 @@ int PRVM_SetEngineString(const char *s)
 //  buffer)
 // the buffer size is automatically grown as needed
 
-int PRVM_SetTempString(const char *s)
+int PRVM_SetTempString(prvm_prog_t *prog, const char *s)
 {
        int size;
        char *t;
@@ -2881,32 +2782,32 @@ int PRVM_SetTempString(const char *s)
                return 0;
        size = (int)strlen(s) + 1;
        if (developer_insane.integer)
-               Con_DPrintf("PRVM_SetTempString: cursize %i, size %i\n", vm_tempstringsbuf.cursize, size);
-       if (vm_tempstringsbuf.maxsize < vm_tempstringsbuf.cursize + size)
-       {
-               sizebuf_t old = vm_tempstringsbuf;
-               if (vm_tempstringsbuf.cursize + size >= 1<<28)
-                       PRVM_ERROR("PRVM_SetTempString: ran out of tempstring memory!  (refusing to grow tempstring buffer over 256MB, cursize %i, size %i)\n", vm_tempstringsbuf.cursize, size);
-               vm_tempstringsbuf.maxsize = max(vm_tempstringsbuf.maxsize, 65536);
-               while (vm_tempstringsbuf.maxsize < vm_tempstringsbuf.cursize + size)
-                       vm_tempstringsbuf.maxsize *= 2;
-               if (vm_tempstringsbuf.maxsize != old.maxsize || vm_tempstringsbuf.data == NULL)
+               Con_DPrintf("PRVM_SetTempString: cursize %i, size %i\n", prog->tempstringsbuf.cursize, size);
+       if (prog->tempstringsbuf.maxsize < prog->tempstringsbuf.cursize + size)
+       {
+               sizebuf_t old = prog->tempstringsbuf;
+               if (prog->tempstringsbuf.cursize + size >= 1<<28)
+                       prog->error_cmd("PRVM_SetTempString: ran out of tempstring memory!  (refusing to grow tempstring buffer over 256MB, cursize %i, size %i)\n", prog->tempstringsbuf.cursize, size);
+               prog->tempstringsbuf.maxsize = max(prog->tempstringsbuf.maxsize, 65536);
+               while (prog->tempstringsbuf.maxsize < prog->tempstringsbuf.cursize + size)
+                       prog->tempstringsbuf.maxsize *= 2;
+               if (prog->tempstringsbuf.maxsize != old.maxsize || prog->tempstringsbuf.data == NULL)
                {
-                       Con_DPrintf("PRVM_SetTempString: enlarging tempstrings buffer (%iKB -> %iKB)\n", old.maxsize/1024, vm_tempstringsbuf.maxsize/1024);
-                       vm_tempstringsbuf.data = (unsigned char *) Mem_Alloc(sv_mempool, vm_tempstringsbuf.maxsize);
+                       Con_DPrintf("PRVM_SetTempString: enlarging tempstrings buffer (%iKB -> %iKB)\n", old.maxsize/1024, prog->tempstringsbuf.maxsize/1024);
+                       prog->tempstringsbuf.data = (unsigned char *) Mem_Alloc(prog->progs_mempool, prog->tempstringsbuf.maxsize);
                        if (old.cursize)
-                               memcpy(vm_tempstringsbuf.data, old.data, old.cursize);
+                               memcpy(prog->tempstringsbuf.data, old.data, old.cursize);
                        if (old.data)
                                Mem_Free(old.data);
                }
        }
-       t = (char *)vm_tempstringsbuf.data + vm_tempstringsbuf.cursize;
+       t = (char *)prog->tempstringsbuf.data + prog->tempstringsbuf.cursize;
        memcpy(t, s, size);
-       vm_tempstringsbuf.cursize += size;
-       return PRVM_SetEngineString(t);
+       prog->tempstringsbuf.cursize += size;
+       return PRVM_SetEngineString(prog, t);
 }
 
-int PRVM_AllocString(size_t bufferlength, char **pointer)
+int PRVM_AllocString(prvm_prog_t *prog, size_t bufferlength, char **pointer)
 {
        int i;
        if (!bufferlength)
@@ -2946,25 +2847,25 @@ int PRVM_AllocString(size_t bufferlength, char **pointer)
        prog->knownstrings[i] = (char *)PRVM_Alloc(bufferlength);
        prog->knownstrings_freeable[i] = true;
        if(prog->leaktest_active)
-               prog->knownstrings_origin[i] = PRVM_AllocationOrigin();
+               prog->knownstrings_origin[i] = PRVM_AllocationOrigin(prog);
        if (pointer)
                *pointer = (char *)(prog->knownstrings[i]);
        return PRVM_KNOWNSTRINGBASE + i;
 }
 
-void PRVM_FreeString(int num)
+void PRVM_FreeString(prvm_prog_t *prog, int num)
 {
        if (num == 0)
-               PRVM_ERROR("PRVM_FreeString: attempt to free a NULL string");
+               prog->error_cmd("PRVM_FreeString: attempt to free a NULL string");
        else if (num >= 0 && num < prog->stringssize)
-               PRVM_ERROR("PRVM_FreeString: attempt to free a constant string");
+               prog->error_cmd("PRVM_FreeString: attempt to free a constant string");
        else if (num >= PRVM_KNOWNSTRINGBASE && num < PRVM_KNOWNSTRINGBASE + prog->numknownstrings)
        {
                num = num - PRVM_KNOWNSTRINGBASE;
                if (!prog->knownstrings[num])
-                       PRVM_ERROR("PRVM_FreeString: attempt to free a non-existent or already freed string");
+                       prog->error_cmd("PRVM_FreeString: attempt to free a non-existent or already freed string");
                if (!prog->knownstrings_freeable[num])
-                       PRVM_ERROR("PRVM_FreeString: attempt to free a string owned by the engine");
+                       prog->error_cmd("PRVM_FreeString: attempt to free a string owned by the engine");
                PRVM_Free((char *)prog->knownstrings[num]);
                if(prog->leaktest_active)
                        if(prog->knownstrings_origin[num])
@@ -2974,10 +2875,10 @@ void PRVM_FreeString(int num)
                prog->firstfreeknownstring = min(prog->firstfreeknownstring, num);
        }
        else
-               PRVM_ERROR("PRVM_FreeString: invalid string offset %i", num);
+               prog->error_cmd("PRVM_FreeString: invalid string offset %i", num);
 }
 
-static qboolean PRVM_IsStringReferenced(string_t string)
+static qboolean PRVM_IsStringReferenced(prvm_prog_t *prog, string_t string)
 {
        int i, j;
 
@@ -3008,70 +2909,64 @@ static qboolean PRVM_IsStringReferenced(string_t string)
        return false;
 }
 
-static qboolean PRVM_IsEdictRelevant(prvm_edict_t *edict)
+static qboolean PRVM_IsEdictRelevant(prvm_prog_t *prog, prvm_edict_t *edict)
 {
+       char vabuf[1024];
+       char vabuf2[1024];
        if(PRVM_NUM_FOR_EDICT(edict) <= prog->reserved_edicts)
                return true; // world or clients
-       switch(prog - prog_list)
+       if (prog == SVVM_prog)
        {
-               case PRVM_SERVERPROG:
-                       {
-                               if(PRVM_serveredictfloat(edict, solid)) // can block other stuff, or is a trigger?
-                                       return true;
-                               if(PRVM_serveredictfloat(edict, modelindex)) // visible ent?
-                                       return true;
-                               if(PRVM_serveredictfloat(edict, effects)) // particle effect?
-                                       return true;
-                               if(PRVM_serveredictfunction(edict, think)) // has a think function?
-                                       if(PRVM_serveredictfloat(edict, nextthink) > 0) // that actually will eventually run?
-                                               return true;
-                               if(PRVM_serveredictfloat(edict, takedamage))
-                                       return true;
-                               if(*prvm_leaktest_ignore_classnames.string)
-                               {
-                                       if(strstr(va(" %s ", prvm_leaktest_ignore_classnames.string), va(" %s ", PRVM_GetString(PRVM_serveredictstring(edict, classname)))))
-                                               return true;
-                               }
-                       }
-                       break;
-               case PRVM_CLIENTPROG:
-                       {
-                               // TODO someone add more stuff here
-                               if(PRVM_clientedictfloat(edict, entnum)) // csqc networked
-                                       return true;
-                               if(PRVM_clientedictfloat(edict, modelindex)) // visible ent?
-                                       return true;
-                               if(PRVM_clientedictfloat(edict, effects)) // particle effect?
-                                       return true;
-                               if(PRVM_clientedictfunction(edict, think)) // has a think function?
-                                       if(PRVM_clientedictfloat(edict, nextthink) > 0) // that actually will eventually run?
-                                               return true;
-                               if(*prvm_leaktest_ignore_classnames.string)
-                               {
-                                       if(strstr(va(" %s ", prvm_leaktest_ignore_classnames.string), va(" %s ", PRVM_GetString(PRVM_clientedictstring(edict, classname)))))
-                                               return true;
-                               }
-                       }
-                       break;
-               case PRVM_MENUPROG:
-                       // menu prog does not have classnames
-                       break;
+               if(PRVM_serveredictfloat(edict, solid)) // can block other stuff, or is a trigger?
+                       return true;
+               if(PRVM_serveredictfloat(edict, modelindex)) // visible ent?
+                       return true;
+               if(PRVM_serveredictfloat(edict, effects)) // particle effect?
+                       return true;
+               if(PRVM_serveredictfunction(edict, think)) // has a think function?
+                       if(PRVM_serveredictfloat(edict, nextthink) > 0) // that actually will eventually run?
+                               return true;
+               if(PRVM_serveredictfloat(edict, takedamage))
+                       return true;
+               if(*prvm_leaktest_ignore_classnames.string)
+               {
+                       if(strstr(va(vabuf, sizeof(vabuf), " %s ", prvm_leaktest_ignore_classnames.string), va(vabuf2, sizeof(vabuf2), " %s ", PRVM_GetString(prog, PRVM_serveredictstring(edict, classname)))))
+                               return true;
+               }
+       }
+       else if (prog == CLVM_prog)
+       {
+               // TODO someone add more stuff here
+               if(PRVM_clientedictfloat(edict, entnum)) // csqc networked
+                       return true;
+               if(PRVM_clientedictfloat(edict, modelindex)) // visible ent?
+                       return true;
+               if(PRVM_clientedictfloat(edict, effects)) // particle effect?
+                       return true;
+               if(PRVM_clientedictfunction(edict, think)) // has a think function?
+                       if(PRVM_clientedictfloat(edict, nextthink) > 0) // that actually will eventually run?
+                               return true;
+               if(*prvm_leaktest_ignore_classnames.string)
+               {
+                       if(strstr(va(vabuf, sizeof(vabuf), " %s ", prvm_leaktest_ignore_classnames.string), va(vabuf2, sizeof(vabuf2), " %s ", PRVM_GetString(prog, PRVM_clientedictstring(edict, classname)))))
+                               return true;
+               }
+       }
+       else
+       {
+               // menu prog does not have classnames
        }
        return false;
 }
 
-static qboolean PRVM_IsEdictReferenced(prvm_edict_t *edict, int mark)
+static qboolean PRVM_IsEdictReferenced(prvm_prog_t *prog, prvm_edict_t *edict, int mark)
 {
        int i, j;
        int edictnum = PRVM_NUM_FOR_EDICT(edict);
        const char *targetname = NULL;
 
-       switch(prog - prog_list)
-       {
-               case PRVM_SERVERPROG:
-                       targetname = PRVM_GetString(PRVM_serveredictstring(edict, targetname));
-                       break;
-       }
+       if (prog == SVVM_prog)
+               targetname = PRVM_GetString(prog, PRVM_serveredictstring(edict, targetname));
 
        if(targetname)
                if(!*targetname) // ""
@@ -3095,7 +2990,7 @@ static qboolean PRVM_IsEdictReferenced(prvm_edict_t *edict, int mark)
                        continue;
                if(targetname)
                {
-                       const char *target = PRVM_GetString(PRVM_serveredictstring(ed, target));
+                       const char *target = PRVM_GetString(prog, PRVM_serveredictstring(ed, target));
                        if(target)
                                if(!strcmp(target, targetname))
                                        return true;
@@ -3113,7 +3008,7 @@ static qboolean PRVM_IsEdictReferenced(prvm_edict_t *edict, int mark)
        return false;
 }
 
-static void PRVM_MarkReferencedEdicts(void)
+static void PRVM_MarkReferencedEdicts(prvm_prog_t *prog)
 {
        int j;
        qboolean found_new;
@@ -3124,7 +3019,7 @@ static void PRVM_MarkReferencedEdicts(void)
                prvm_edict_t *ed = PRVM_EDICT_NUM(j);
                if(ed->priv.required->free)
                        continue;
-               ed->priv.required->mark = PRVM_IsEdictRelevant(ed) ? 1 : 0;
+               ed->priv.required->mark = PRVM_IsEdictRelevant(prog, ed) ? 1 : 0;
        }
 
        stage = 1;
@@ -3138,7 +3033,7 @@ static void PRVM_MarkReferencedEdicts(void)
                                continue;
                        if(ed->priv.required->mark)
                                continue;
-                       if(PRVM_IsEdictReferenced(ed, stage))
+                       if(PRVM_IsEdictReferenced(prog, ed, stage))
                        {
                                ed->priv.required->mark = stage + 1;
                                found_new = true;
@@ -3150,7 +3045,7 @@ static void PRVM_MarkReferencedEdicts(void)
        Con_DPrintf("leak check used %d stages to find all references\n", stage);
 }
 
-void PRVM_LeakTest(void)
+void PRVM_LeakTest(prvm_prog_t *prog)
 {
        int i, j;
        qboolean leaked = false;
@@ -3164,7 +3059,7 @@ void PRVM_LeakTest(void)
                if(prog->knownstrings[i])
                if(prog->knownstrings_freeable[i])
                if(prog->knownstrings_origin[i])
-               if(!PRVM_IsStringReferenced(PRVM_KNOWNSTRINGBASE + i))
+               if(!PRVM_IsStringReferenced(prog, PRVM_KNOWNSTRINGBASE + i))
                {
                        Con_Printf("Unreferenced string found!\n  Value: %s\n  Origin: %s\n", prog->knownstrings[i], prog->knownstrings_origin[i]);
                        leaked = true;
@@ -3172,7 +3067,7 @@ void PRVM_LeakTest(void)
        }
 
        // 2. Edicts
-       PRVM_MarkReferencedEdicts();
+       PRVM_MarkReferencedEdicts(prog);
        for(j = 0; j < prog->num_edicts; ++j)
        {
                prvm_edict_t *ed = PRVM_EDICT_NUM(j);
@@ -3182,7 +3077,7 @@ void PRVM_LeakTest(void)
                if(ed->priv.required->allocation_origin)
                {
                        Con_Printf("Unreferenced edict found!\n  Allocated at: %s\n", ed->priv.required->allocation_origin);
-                       PRVM_ED_Print(ed, NULL);
+                       PRVM_ED_Print(prog, ed, NULL);
                        Con_Print("\n");
                        leaked = true;
                }
index 8fb0d69254722617045db75231ebb23c047bbf99..d1e37f76c70b914a33c53644be3eb022a6783385 100644 (file)
@@ -110,9 +110,6 @@ const char *prvm_opnames[] =
 "BITOR"
 };
 
-char *PRVM_GlobalString (int ofs);
-char *PRVM_GlobalStringNoContents (int ofs);
-extern ddef_t *PRVM_ED_FieldAtOfs(int ofs);
 
 
 //=============================================================================
@@ -124,14 +121,15 @@ PRVM_PrintStatement
 */
 extern cvar_t prvm_statementprofiling;
 extern cvar_t prvm_timeprofiling;
-void PRVM_PrintStatement(mstatement_t *s)
+static void PRVM_PrintStatement(prvm_prog_t *prog, mstatement_t *s)
 {
        size_t i;
        int opnum = (int)(s - prog->statements);
+       char valuebuf[MAX_INPUTLINE];
 
        Con_Printf("s%i: ", opnum);
        if( prog->statement_linenums )
-               Con_Printf( "%s:%i: ", PRVM_GetString( prog->xfunction->s_file ), prog->statement_linenums[ opnum ] );
+               Con_Printf( "%s:%i: ", PRVM_GetString( prog, prog->xfunction->s_file ), prog->statement_linenums[ opnum ] );
 
        if (prvm_statementprofiling.integer)
                Con_Printf("%7.0f ", prog->statement_profile[s - prog->statements]);
@@ -146,27 +144,27 @@ void PRVM_PrintStatement(mstatement_t *s)
                for ( ; i<10 ; i++)
                        Con_Print(" ");
        }
-       if (s->operand[0] >= 0) Con_Printf(  "%s", PRVM_GlobalString(s->operand[0]));
-       if (s->operand[1] >= 0) Con_Printf(", %s", PRVM_GlobalString(s->operand[1]));
-       if (s->operand[2] >= 0) Con_Printf(", %s", PRVM_GlobalString(s->operand[2]));
+       if (s->operand[0] >= 0) Con_Printf(  "%s", PRVM_GlobalString(prog, s->operand[0], valuebuf, sizeof(valuebuf)));
+       if (s->operand[1] >= 0) Con_Printf(", %s", PRVM_GlobalString(prog, s->operand[1], valuebuf, sizeof(valuebuf)));
+       if (s->operand[2] >= 0) Con_Printf(", %s", PRVM_GlobalString(prog, s->operand[2], valuebuf, sizeof(valuebuf)));
        if (s->jumpabsolute >= 0) Con_Printf(", statement %i", s->jumpabsolute);
        Con_Print("\n");
 }
 
-void PRVM_PrintFunctionStatements (const char *name)
+void PRVM_PrintFunctionStatements (prvm_prog_t *prog, const char *name)
 {
        int i, firststatement, endstatement;
        mfunction_t *func;
-       func = PRVM_ED_FindFunction (name);
+       func = PRVM_ED_FindFunction (prog, name);
        if (!func)
        {
-               Con_Printf("%s progs: no function named %s\n", PRVM_NAME, name);
+               Con_Printf("%s progs: no function named %s\n", prog->name, name);
                return;
        }
        firststatement = func->first_statement;
        if (firststatement < 0)
        {
-               Con_Printf("%s progs: function %s is builtin #%i\n", PRVM_NAME, name, -firststatement);
+               Con_Printf("%s progs: function %s is builtin #%i\n", prog->name, name, -firststatement);
                return;
        }
 
@@ -177,10 +175,10 @@ void PRVM_PrintFunctionStatements (const char *name)
                        endstatement = prog->functions[i].first_statement;
 
        // now print the range of statements
-       Con_Printf("%s progs: disassembly of function %s (statements %i-%i, locals %i-%i):\n", PRVM_NAME, name, firststatement, endstatement, func->parm_start, func->parm_start + func->locals - 1);
+       Con_Printf("%s progs: disassembly of function %s (statements %i-%i, locals %i-%i):\n", prog->name, name, firststatement, endstatement, func->parm_start, func->parm_start + func->locals - 1);
        for (i = firststatement;i < endstatement;i++)
        {
-               PRVM_PrintStatement(prog->statements + i);
+               PRVM_PrintStatement(prog, prog->statements + i);
                prog->statement_profile[i] = 0;
        }
 }
@@ -193,19 +191,17 @@ PRVM_PrintFunction_f
 */
 void PRVM_PrintFunction_f (void)
 {
+       prvm_prog_t *prog;
        if (Cmd_Argc() != 3)
        {
                Con_Printf("usage: prvm_printfunction <program name> <function name>\n");
                return;
        }
 
-       PRVM_Begin;
-       if(!PRVM_SetProgFromString(Cmd_Argv(1)))
+       if (!(prog = PRVM_FriendlyProgFromString(Cmd_Argv(1))))
                return;
 
-       PRVM_PrintFunctionStatements(Cmd_Argv(2));
-
-       PRVM_End;
+       PRVM_PrintFunctionStatements(prog, Cmd_Argv(2));
 }
 
 /*
@@ -213,7 +209,7 @@ void PRVM_PrintFunction_f (void)
 PRVM_StackTrace
 ============
 */
-void PRVM_StackTrace (void)
+void PRVM_StackTrace (prvm_prog_t *prog)
 {
        mfunction_t     *f;
        int                     i;
@@ -227,14 +223,15 @@ void PRVM_StackTrace (void)
                if (!f)
                        Con_Print("<NULL FUNCTION>\n");
                else
-                       Con_Printf("%12s : %s : statement %i\n", PRVM_GetString(f->s_file), PRVM_GetString(f->s_name), prog->stack[i].s - f->first_statement);
+                       Con_Printf("%12s : %s : statement %i\n", PRVM_GetString(prog, f->s_file), PRVM_GetString(prog, f->s_name), prog->stack[i].s - f->first_statement);
        }
 }
 
-void PRVM_ShortStackTrace(char *buf, size_t bufsize)
+void PRVM_ShortStackTrace(prvm_prog_t *prog, char *buf, size_t bufsize)
 {
        mfunction_t     *f;
        int                     i;
+       char vabuf[1024];
 
        if(prog)
        {
@@ -254,7 +251,7 @@ void PRVM_ShortStackTrace(char *buf, size_t bufsize)
 
                if(strlcat(buf,
                        f
-                               ? va("%s:%s(%i) ", PRVM_GetString(f->s_file), PRVM_GetString(f->s_name), prog->stack[i].s - f->first_statement)
+                               ? va(vabuf, sizeof(vabuf), "%s:%s(%i) ", PRVM_GetString(prog, f->s_file), PRVM_GetString(prog, f->s_name), prog->stack[i].s - f->first_statement)
                                : "<NULL> ",
                        bufsize
                ) >= bufsize)
@@ -263,14 +260,15 @@ void PRVM_ShortStackTrace(char *buf, size_t bufsize)
 }
 
 
-void PRVM_CallProfile (void)
+static void PRVM_CallProfile (prvm_prog_t *prog)
 {
        mfunction_t *f, *best;
        int i;
        double max;
        double sum;
+       double newprofiletime;
 
-       Con_Printf( "%s Call Profile:\n", PRVM_NAME );
+       Con_Printf( "%s Call Profile:\n", prog->name );
 
        sum = 0;
        do
@@ -289,18 +287,19 @@ void PRVM_CallProfile (void)
                if (best)
                {
                        sum += best->totaltime;
-                       Con_Printf("%9.4f %s\n", best->totaltime, PRVM_GetString(best->s_name));
+                       Con_Printf("%9.4f %s\n", best->totaltime, PRVM_GetString(prog, best->s_name));
                        best->totaltime = 0;
                }
        } while (best);
 
-       Con_Printf("Total time since last profile reset: %9.4f\n", Sys_DoubleTime() - prog->starttime);
+       newprofiletime = Sys_DirtyTime();
+       Con_Printf("Total time since last profile reset: %9.4f\n", newprofiletime - prog->profiletime);
        Con_Printf("       - used by QC code of this VM: %9.4f\n", sum);
 
-       prog->starttime = Sys_DoubleTime();
+       prog->profiletime = newprofiletime;
 }
 
-void PRVM_Profile (int maxfunctions, double mintime, int sortby)
+void PRVM_Profile (prvm_prog_t *prog, int maxfunctions, double mintime, int sortby)
 {
        mfunction_t *f, *best;
        int i, num;
@@ -310,10 +309,10 @@ void PRVM_Profile (int maxfunctions, double mintime, int sortby)
                mintime *= 10000000; // count each statement as about 0.1µs
 
        if(prvm_timeprofiling.integer)
-               Con_Printf( "%s Profile:\n[CallCount]      [Time] [BuiltinTm] [Statement] [BuiltinCt] [TimeTotal] [StmtTotal] [BltnTotal] [self]\n", PRVM_NAME );
+               Con_Printf( "%s Profile:\n[CallCount]      [Time] [BuiltinTm] [Statement] [BuiltinCt] [TimeTotal] [StmtTotal] [BltnTotal] [self]\n", prog->name );
                //                        12345678901 12345678901 12345678901 12345678901 12345678901 12345678901 12345678901 123.45%
        else
-               Con_Printf( "%s Profile:\n[CallCount] [Statement] [BuiltinCt] [StmtTotal] [BltnTotal] [self]\n", PRVM_NAME );
+               Con_Printf( "%s Profile:\n[CallCount] [Statement] [BuiltinCt] [StmtTotal] [BltnTotal] [self]\n", prog->name );
                //                        12345678901 12345678901 12345678901 12345678901 12345678901 123.45%
 
        num = 0;
@@ -381,18 +380,18 @@ void PRVM_Profile (int maxfunctions, double mintime, int sortby)
                                if(prvm_timeprofiling.integer)
                                {
                                        if (best->first_statement < 0)
-                                               Con_Printf("%11.0f %11.6f ------------- builtin ------------- %11.6f ----------- builtin ----------- %s\n", best->callcount, best->tprofile, best->tprofile, PRVM_GetString(best->s_name));
+                                               Con_Printf("%11.0f %11.6f ------------- builtin ------------- %11.6f ----------- builtin ----------- %s\n", best->callcount, best->tprofile, best->tprofile, PRVM_GetString(prog, best->s_name));
                                        //                 %11.6f 12345678901 12345678901 12345678901 %11.6f 12345678901 12345678901 123.45%
                                        else
-                                               Con_Printf("%11.0f %11.6f %11.6f %11.0f %11.0f %11.6f %11.0f %11.0f %6.2f%% %s\n", best->callcount, best->tprofile, best->tbprofile, best->profile, best->builtinsprofile, best->tprofile_total, best->profile_total, best->builtinsprofile_total, (best->tprofile_total > 0) ? ((best->tprofile) * 100.0 / (best->tprofile_total)) : -99.99, PRVM_GetString(best->s_name));
+                                               Con_Printf("%11.0f %11.6f %11.6f %11.0f %11.0f %11.6f %11.0f %11.0f %6.2f%% %s\n", best->callcount, best->tprofile, best->tbprofile, best->profile, best->builtinsprofile, best->tprofile_total, best->profile_total, best->builtinsprofile_total, (best->tprofile_total > 0) ? ((best->tprofile) * 100.0 / (best->tprofile_total)) : -99.99, PRVM_GetString(prog, best->s_name));
                                }
                                else
                                {
                                        if (best->first_statement < 0)
-                                               Con_Printf("%11.0f ----------------------- builtin ----------------------- %s\n", best->callcount, PRVM_GetString(best->s_name));
+                                               Con_Printf("%11.0f ----------------------- builtin ----------------------- %s\n", best->callcount, PRVM_GetString(prog, best->s_name));
                                        //                 12345678901 12345678901 12345678901 12345678901 123.45%
                                        else
-                                               Con_Printf("%11.0f %11.0f %11.0f %11.0f %11.0f %6.2f%% %s\n", best->callcount, best->profile, best->builtinsprofile, best->profile_total, best->builtinsprofile_total, (best->profile + best->builtinsprofile) * 100.0 / (best->profile_total + best->builtinsprofile_total), PRVM_GetString(best->s_name));
+                                               Con_Printf("%11.0f %11.0f %11.0f %11.0f %11.0f %6.2f%% %s\n", best->callcount, best->profile, best->builtinsprofile, best->profile_total, best->builtinsprofile_total, (best->profile + best->builtinsprofile) * 100.0 / (best->profile_total + best->builtinsprofile_total), PRVM_GetString(prog, best->s_name));
                                }
                        }
                        num++;
@@ -416,19 +415,17 @@ PRVM_CallProfile_f
 */
 void PRVM_CallProfile_f (void)
 {
+       prvm_prog_t *prog;
        if (Cmd_Argc() != 2)
        {
                Con_Print("prvm_callprofile <program name>\n");
                return;
        }
 
-       PRVM_Begin;
-       if(!PRVM_SetProgFromString(Cmd_Argv(1)))
+       if (!(prog = PRVM_FriendlyProgFromString(Cmd_Argv(1))))
                return;
 
-       PRVM_CallProfile();
-
-       PRVM_End;
+       PRVM_CallProfile(prog);
 }
 
 /*
@@ -439,6 +436,7 @@ PRVM_Profile_f
 */
 void PRVM_Profile_f (void)
 {
+       prvm_prog_t *prog;
        int howmany;
 
        howmany = 1<<30;
@@ -450,17 +448,15 @@ void PRVM_Profile_f (void)
                return;
        }
 
-       PRVM_Begin;
-       if(!PRVM_SetProgFromString(Cmd_Argv(1)))
+       if (!(prog = PRVM_FriendlyProgFromString(Cmd_Argv(1))))
                return;
 
-       PRVM_Profile(howmany, 0, 0);
-
-       PRVM_End;
+       PRVM_Profile(prog, howmany, 0, 0);
 }
 
 void PRVM_ChildProfile_f (void)
 {
+       prvm_prog_t *prog;
        int howmany;
 
        howmany = 1<<30;
@@ -472,35 +468,16 @@ void PRVM_ChildProfile_f (void)
                return;
        }
 
-       PRVM_Begin;
-       if(!PRVM_SetProgFromString(Cmd_Argv(1)))
+       if (!(prog = PRVM_FriendlyProgFromString(Cmd_Argv(1))))
                return;
 
-       PRVM_Profile(howmany, 0, 1);
-
-       PRVM_End;
+       PRVM_Profile(prog, howmany, 0, 1);
 }
 
-void PRVM_CrashAll(void)
+void PRVM_PrintState(prvm_prog_t *prog)
 {
        int i;
-       prvm_prog_t *oldprog = prog;
-
-       for(i = 0; i < PRVM_MAXPROGS; i++)
-       {
-               if(!PRVM_ProgLoaded(i))
-                       continue;
-               PRVM_SetProg(i);
-               PRVM_Crash();
-       }
-
-       prog = oldprog;
-}
-
-void PRVM_PrintState(void)
-{
-       int i;
-       if(prog->statestring)
+       if (prog->statestring)
        {
                Con_Printf("Caller-provided information: %s\n", prog->statestring);
        }
@@ -508,33 +485,34 @@ void PRVM_PrintState(void)
        {
                for (i = -7; i <= 0;i++)
                        if (prog->xstatement + i >= prog->xfunction->first_statement)
-                               PRVM_PrintStatement (prog->statements + prog->xstatement + i);
+                               PRVM_PrintStatement(prog, prog->statements + prog->xstatement + i);
        }
        else
                Con_Print("null function executing??\n");
-       PRVM_StackTrace ();
+       PRVM_StackTrace(prog);
 }
 
-extern sizebuf_t vm_tempstringsbuf;
 extern cvar_t prvm_errordump;
-void Host_Savegame_to (const char *name);
-void PRVM_Crash(void)
+void PRVM_Crash(prvm_prog_t *prog)
 {
+       char vabuf[1024];
        if (prog == NULL)
                return;
+       if (!prog->loaded)
+               return;
 
        PRVM_serverfunction(SV_Shutdown) = 0; // don't call SV_Shutdown on crash
 
        if( prog->depth > 0 )
        {
-               Con_Printf("QuakeC crash report for %s:\n", PRVM_NAME);
-               PRVM_PrintState();
+               Con_Printf("QuakeC crash report for %s:\n", prog->name);
+               PRVM_PrintState(prog);
        }
 
        if(prvm_errordump.integer)
        {
                // make a savegame
-               Host_Savegame_to(va("crash-%s.dmp", PRVM_NAME));
+               Host_Savegame_to(prog, va(vabuf, sizeof(vabuf), "crash-%s.dmp", prog->name));
        }
 
        // dump the stack so host_error can shutdown functions
@@ -542,7 +520,7 @@ void PRVM_Crash(void)
        prog->localstack_used = 0;
 
        // delete all tempstrings (FIXME: is this safe in VM->engine->VM recursion?)
-       vm_tempstringsbuf.cursize = 0;
+       prog->tempstringsbuf.cursize = 0;
 
        // reset the prog pointer
        prog = NULL;
@@ -563,12 +541,12 @@ PRVM_EnterFunction
 Returns the new program statement counter
 ====================
 */
-int PRVM_EnterFunction (mfunction_t *f)
+static int PRVM_EnterFunction (prvm_prog_t *prog, mfunction_t *f)
 {
        int             i, j, c, o;
 
        if (!f)
-               PRVM_ERROR ("PRVM_EnterFunction: NULL function in %s", PRVM_NAME);
+               prog->error_cmd("PRVM_EnterFunction: NULL function in %s", prog->name);
 
        prog->stack[prog->depth].s = prog->xstatement;
        prog->stack[prog->depth].f = prog->xfunction;
@@ -577,12 +555,12 @@ int PRVM_EnterFunction (mfunction_t *f)
        prog->stack[prog->depth].builtinsprofile_acc = -f->builtinsprofile;
        prog->depth++;
        if (prog->depth >=PRVM_MAX_STACK_DEPTH)
-               PRVM_ERROR ("stack overflow");
+               prog->error_cmd("stack overflow");
 
 // save off any locals that the new function steps on
        c = f->locals;
        if (prog->localstack_used + c > PRVM_LOCALSTACK_SIZE)
-               PRVM_ERROR ("PRVM_ExecuteProgram: locals stack overflow in %s", PRVM_NAME);
+               prog->error_cmd("PRVM_ExecuteProgram: locals stack overflow in %s", prog->name);
 
        for (i=0 ; i < c ; i++)
                prog->localstack[prog->localstack_used+i] = ((int *)prog->globals.generic)[f->parm_start + i];
@@ -609,21 +587,21 @@ int PRVM_EnterFunction (mfunction_t *f)
 PRVM_LeaveFunction
 ====================
 */
-int PRVM_LeaveFunction (void)
+static int PRVM_LeaveFunction (prvm_prog_t *prog)
 {
        int             i, c;
        mfunction_t *f;
 
        if (prog->depth <= 0)
-               PRVM_ERROR ("prog stack underflow in %s", PRVM_NAME);
+               prog->error_cmd("prog stack underflow in %s", prog->name);
 
        if (!prog->xfunction)
-               PRVM_ERROR ("PR_LeaveFunction: NULL function in %s", PRVM_NAME);
+               prog->error_cmd("PR_LeaveFunction: NULL function in %s", prog->name);
 // restore locals from the stack
        c = prog->xfunction->locals;
        prog->localstack_used -= c;
        if (prog->localstack_used < 0)
-               PRVM_ERROR ("PRVM_ExecuteProgram: locals stack underflow in %s", PRVM_NAME);
+               prog->error_cmd("PRVM_ExecuteProgram: locals stack underflow in %s", prog->name);
 
        for (i=0 ; i < c ; i++)
                ((int *)prog->globals.generic)[prog->xfunction->parm_start + i] = prog->localstack[prog->localstack_used+i];
@@ -656,7 +634,7 @@ int PRVM_LeaveFunction (void)
        return prog->stack[prog->depth].s;
 }
 
-void PRVM_Init_Exec(void)
+void PRVM_Init_Exec(prvm_prog_t *prog)
 {
        // dump the stack
        prog->depth = 0;
@@ -670,7 +648,6 @@ void PRVM_Init_Exec(void)
 #define OPC ((prvm_eval_t *)&prog->globals.generic[st->operand[2]])
 extern cvar_t prvm_traceqc;
 extern cvar_t prvm_statementprofiling;
-extern sizebuf_t vm_tempstringsbuf;
 extern qboolean prvm_runawaycheck;
 
 #ifdef PROFILING
@@ -679,7 +656,7 @@ extern qboolean prvm_runawaycheck;
 MVM_ExecuteProgram
 ====================
 */
-void MVM_ExecuteProgram (func_t fnum, const char *errormessage)
+void MVM_ExecuteProgram (prvm_prog_t *prog, func_t fnum, const char *errormessage)
 {
        mstatement_t    *st, *startst;
        mfunction_t     *f, *newf;
@@ -690,19 +667,19 @@ void MVM_ExecuteProgram (func_t fnum, const char *errormessage)
        double  calltime;
        double tm, starttm;
 
-       calltime = Sys_DoubleTime();
+       calltime = Sys_DirtyTime();
 
        if (!fnum || fnum >= (unsigned int)prog->numfunctions)
        {
                if (PRVM_allglobaledict(self))
-                       PRVM_ED_Print(PRVM_PROG_TO_EDICT(PRVM_allglobaledict(self)), NULL);
-               PRVM_ERROR ("MVM_ExecuteProgram: %s", errormessage);
+                       PRVM_ED_Print(prog, PRVM_PROG_TO_EDICT(PRVM_allglobaledict(self)), NULL);
+               prog->error_cmd("MVM_ExecuteProgram: %s", errormessage);
        }
 
        f = &prog->functions[fnum];
 
        // after executing this function, delete all tempstrings it created
-       restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize;
+       restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize;
 
        prog->trace = prvm_traceqc.integer;
 
@@ -710,7 +687,7 @@ void MVM_ExecuteProgram (func_t fnum, const char *errormessage)
        exitdepth = prog->depth;
 
 // make a stack frame
-       st = &prog->statements[PRVM_EnterFunction (f)];
+       st = &prog->statements[PRVM_EnterFunction(prog, f)];
        // save the starting statement pointer for profiling
        // (when the function exits or jumps, the (st - startst) integer value is
        // added to the function's profile counter)
@@ -753,14 +730,16 @@ chooseexecprogram:
        }
 
 cleanup:
-       if (developer_insane.integer && vm_tempstringsbuf.cursize > restorevm_tempstringsbuf_cursize)
-               Con_DPrintf("MVM_ExecuteProgram: %s used %i bytes of tempstrings\n", PRVM_GetString(prog->functions[fnum].s_name), vm_tempstringsbuf.cursize - restorevm_tempstringsbuf_cursize);
+       if (developer_insane.integer && prog->tempstringsbuf.cursize > restorevm_tempstringsbuf_cursize)
+               Con_DPrintf("MVM_ExecuteProgram: %s used %i bytes of tempstrings\n", PRVM_GetString(prog, prog->functions[fnum].s_name), prog->tempstringsbuf.cursize - restorevm_tempstringsbuf_cursize);
        // delete tempstrings created by this function
-       vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
+       prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
 
-       f->totaltime += (Sys_DoubleTime() - calltime);
+       tm = Sys_DirtyTime() - calltime;if (tm < 0 || tm >= 1800) tm = 0;
+       f->totaltime += tm;
 
-       SV_FlushBroadcastMessages();
+       if (prog == SVVM_prog)
+               SV_FlushBroadcastMessages();
 }
 
 /*
@@ -768,7 +747,7 @@ cleanup:
 CLVM_ExecuteProgram
 ====================
 */
-void CLVM_ExecuteProgram (func_t fnum, const char *errormessage)
+void CLVM_ExecuteProgram (prvm_prog_t *prog, func_t fnum, const char *errormessage)
 {
        mstatement_t    *st, *startst;
        mfunction_t     *f, *newf;
@@ -779,19 +758,19 @@ void CLVM_ExecuteProgram (func_t fnum, const char *errormessage)
        double  calltime;
        double tm, starttm;
 
-       calltime = Sys_DoubleTime();
+       calltime = Sys_DirtyTime();
 
        if (!fnum || fnum >= (unsigned int)prog->numfunctions)
        {
                if (PRVM_allglobaledict(self))
-                       PRVM_ED_Print(PRVM_PROG_TO_EDICT(PRVM_allglobaledict(self)), NULL);
-               PRVM_ERROR ("CLVM_ExecuteProgram: %s", errormessage);
+                       PRVM_ED_Print(prog, PRVM_PROG_TO_EDICT(PRVM_allglobaledict(self)), NULL);
+               prog->error_cmd("CLVM_ExecuteProgram: %s", errormessage);
        }
 
        f = &prog->functions[fnum];
 
        // after executing this function, delete all tempstrings it created
-       restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize;
+       restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize;
 
        prog->trace = prvm_traceqc.integer;
 
@@ -799,7 +778,7 @@ void CLVM_ExecuteProgram (func_t fnum, const char *errormessage)
        exitdepth = prog->depth;
 
 // make a stack frame
-       st = &prog->statements[PRVM_EnterFunction (f)];
+       st = &prog->statements[PRVM_EnterFunction(prog, f)];
        // save the starting statement pointer for profiling
        // (when the function exits or jumps, the (st - startst) integer value is
        // added to the function's profile counter)
@@ -842,14 +821,16 @@ chooseexecprogram:
        }
 
 cleanup:
-       if (developer_insane.integer && vm_tempstringsbuf.cursize > restorevm_tempstringsbuf_cursize)
-               Con_DPrintf("CLVM_ExecuteProgram: %s used %i bytes of tempstrings\n", PRVM_GetString(prog->functions[fnum].s_name), vm_tempstringsbuf.cursize - restorevm_tempstringsbuf_cursize);
+       if (developer_insane.integer && prog->tempstringsbuf.cursize > restorevm_tempstringsbuf_cursize)
+               Con_DPrintf("CLVM_ExecuteProgram: %s used %i bytes of tempstrings\n", PRVM_GetString(prog, prog->functions[fnum].s_name), prog->tempstringsbuf.cursize - restorevm_tempstringsbuf_cursize);
        // delete tempstrings created by this function
-       vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
+       prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
 
-       f->totaltime += (Sys_DoubleTime() - calltime);
+       tm = Sys_DirtyTime() - calltime;if (tm < 0 || tm >= 1800) tm = 0;
+       f->totaltime += tm;
 
-       SV_FlushBroadcastMessages();
+       if (prog == SVVM_prog)
+               SV_FlushBroadcastMessages();
 }
 #endif
 
@@ -858,7 +839,11 @@ cleanup:
 SVVM_ExecuteProgram
 ====================
 */
-void SVVM_ExecuteProgram (func_t fnum, const char *errormessage)
+#ifdef PROFILING
+void SVVM_ExecuteProgram (prvm_prog_t *prog, func_t fnum, const char *errormessage)
+#else
+void PRVM_ExecuteProgram (prvm_prog_t *prog, func_t fnum, const char *errormessage)
+#endif
 {
        mstatement_t    *st, *startst;
        mfunction_t     *f, *newf;
@@ -869,19 +854,19 @@ void SVVM_ExecuteProgram (func_t fnum, const char *errormessage)
        double  calltime;
        double tm, starttm;
 
-       calltime = Sys_DoubleTime();
+       calltime = Sys_DirtyTime();
 
        if (!fnum || fnum >= (unsigned int)prog->numfunctions)
        {
                if (PRVM_allglobaledict(self))
-                       PRVM_ED_Print(PRVM_PROG_TO_EDICT(PRVM_allglobaledict(self)), NULL);
-               PRVM_ERROR ("SVVM_ExecuteProgram: %s", errormessage);
+                       PRVM_ED_Print(prog, PRVM_PROG_TO_EDICT(PRVM_allglobaledict(self)), NULL);
+               prog->error_cmd("SVVM_ExecuteProgram: %s", errormessage);
        }
 
        f = &prog->functions[fnum];
 
        // after executing this function, delete all tempstrings it created
-       restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize;
+       restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize;
 
        prog->trace = prvm_traceqc.integer;
 
@@ -889,7 +874,7 @@ void SVVM_ExecuteProgram (func_t fnum, const char *errormessage)
        exitdepth = prog->depth;
 
 // make a stack frame
-       st = &prog->statements[PRVM_EnterFunction (f)];
+       st = &prog->statements[PRVM_EnterFunction(prog, f)];
        // save the starting statement pointer for profiling
        // (when the function exits or jumps, the (st - startst) integer value is
        // added to the function's profile counter)
@@ -932,12 +917,14 @@ chooseexecprogram:
        }
 
 cleanup:
-       if (developer_insane.integer && vm_tempstringsbuf.cursize > restorevm_tempstringsbuf_cursize)
-               Con_DPrintf("SVVM_ExecuteProgram: %s used %i bytes of tempstrings\n", PRVM_GetString(prog->functions[fnum].s_name), vm_tempstringsbuf.cursize - restorevm_tempstringsbuf_cursize);
+       if (developer_insane.integer && prog->tempstringsbuf.cursize > restorevm_tempstringsbuf_cursize)
+               Con_DPrintf("SVVM_ExecuteProgram: %s used %i bytes of tempstrings\n", PRVM_GetString(prog, prog->functions[fnum].s_name), prog->tempstringsbuf.cursize - restorevm_tempstringsbuf_cursize);
        // delete tempstrings created by this function
-       vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
+       prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
 
-       f->totaltime += (Sys_DoubleTime() - calltime);
+       tm = Sys_DirtyTime() - calltime;if (tm < 0 || tm >= 1800) tm = 0;
+       f->totaltime += tm;
 
-       SV_FlushBroadcastMessages();
+       if (prog == SVVM_prog)
+               SV_FlushBroadcastMessages();
 }
index 4d872f64bf4e72c09d0afba93c0910e6b24aa488..3ae82b335c3ba44dcc33575a6c45ff95b681e707 100644 (file)
@@ -1,9 +1,9 @@
 #ifdef PRVMTIMEPROFILING 
 #define PreError() \
        prog->xstatement = st - prog->statements; \
-       tm = Sys_DoubleTime(); \
+       tm = Sys_DirtyTime(); \
        prog->xfunction->profile += (st - startst); \
-       prog->xfunction->tprofile += (tm - starttm);
+       prog->xfunction->tprofile += (tm - starttm >= 0 && tm - starttm < 1800) ? (tm - starttm) : 0;
 #else
 #define PreError() \
        prog->xstatement = st - prog->statements; \
@@ -18,7 +18,7 @@
 
 #if PRVMSLOWINTERPRETER
                        if (prog->trace)
-                               PRVM_PrintStatement(st);
+                               PRVM_PrintStatement(prog, st);
                        prog->statement_profile[st - prog->statements]++;
 #endif
 
@@ -68,7 +68,7 @@
                                                prog->xfunction->profile += (st - startst);
                                                startst = st;
                                                prog->xstatement = st - prog->statements;
-                                               VM_Warning( "Attempted division by zero in %s\n", PRVM_NAME );
+                                               VM_Warning(prog, "Attempted division by zero in %s\n", prog->name );
                                        }
                                        OPC->_float = 0.0f;
                                }
                                OPC->_float = !OPA->vector[0] && !OPA->vector[1] && !OPA->vector[2];
                                break;
                        case OP_NOT_S:
-                               OPC->_float = !OPA->string || !*PRVM_GetString(OPA->string);
+                               OPC->_float = !OPA->string || !*PRVM_GetString(prog, OPA->string);
                                break;
                        case OP_NOT_FNC:
                                OPC->_float = !OPA->function;
                                OPC->_float = (OPA->vector[0] == OPB->vector[0]) && (OPA->vector[1] == OPB->vector[1]) && (OPA->vector[2] == OPB->vector[2]);
                                break;
                        case OP_EQ_S:
-                               OPC->_float = !strcmp(PRVM_GetString(OPA->string),PRVM_GetString(OPB->string));
+                               OPC->_float = !strcmp(PRVM_GetString(prog, OPA->string),PRVM_GetString(prog, OPB->string));
                                break;
                        case OP_EQ_E:
                                OPC->_float = OPA->_int == OPB->_int;
                                OPC->_float = (OPA->vector[0] != OPB->vector[0]) || (OPA->vector[1] != OPB->vector[1]) || (OPA->vector[2] != OPB->vector[2]);
                                break;
                        case OP_NE_S:
-                               OPC->_float = strcmp(PRVM_GetString(OPA->string),PRVM_GetString(OPB->string));
+                               OPC->_float = strcmp(PRVM_GetString(prog, OPA->string),PRVM_GetString(prog, OPB->string));
                                break;
                        case OP_NE_E:
                                OPC->_float = OPA->_int != OPB->_int;
                                if (OPB->_int < 0 || OPB->_int + 1 > prog->entityfieldsarea)
                                {
                                        PreError();
-                                       PRVM_ERROR("%s attempted to write to an out of bounds edict (%i)", PRVM_NAME, OPB->_int);
+                                       prog->error_cmd("%s attempted to write to an out of bounds edict (%i)", prog->name, OPB->_int);
                                        goto cleanup;
                                }
                                if (OPB->_int < prog->entityfields && !prog->allowworldwrites)
                                {
                                        prog->xstatement = st - prog->statements;
-                                       VM_Warning("assignment to world.%s (field %i) in %s\n", PRVM_GetString(PRVM_ED_FieldAtOfs(OPB->_int)->s_name), OPB->_int, PRVM_NAME);
+                                       VM_Warning(prog, "assignment to world.%s (field %i) in %s\n", PRVM_GetString(prog, PRVM_ED_FieldAtOfs(prog, OPB->_int)->s_name), OPB->_int, prog->name);
                                }
                                ptr = (prvm_eval_t *)(prog->edictsfields + OPB->_int);
                                ptr->_int = OPA->_int;
                                if (OPB->_int < 0 || OPB->_int + 3 > prog->entityfieldsarea)
                                {
                                        PreError();
-                                       PRVM_ERROR("%s attempted to write to an out of bounds edict (%i)", PRVM_NAME, OPB->_int);
+                                       prog->error_cmd("%s attempted to write to an out of bounds edict (%i)", prog->name, OPB->_int);
                                        goto cleanup;
                                }
                                if (OPB->_int < prog->entityfields && !prog->allowworldwrites)
                                {
                                        prog->xstatement = st - prog->statements;
-                                       VM_Warning("assignment to world.%s (field %i) in %s\n", PRVM_GetString(PRVM_ED_FieldAtOfs(OPB->_int)->s_name), OPB->_int, PRVM_NAME);
+                                       VM_Warning(prog, "assignment to world.%s (field %i) in %s\n", PRVM_GetString(prog, PRVM_ED_FieldAtOfs(prog, OPB->_int)->s_name), OPB->_int, prog->name);
                                }
                                ptr = (prvm_eval_t *)(prog->edictsfields + OPB->_int);
                                ptr->ivector[0] = OPA->ivector[0];
                                if (OPA->edict < 0 || OPA->edict >= prog->max_edicts)
                                {
                                        PreError();
-                                       PRVM_ERROR ("%s Progs attempted to address an out of bounds edict number", PRVM_NAME);
+                                       prog->error_cmd("%s Progs attempted to address an out of bounds edict number", prog->name);
                                        goto cleanup;
                                }
                                if ((unsigned int)(OPB->_int) >= (unsigned int)(prog->entityfields))
                                {
                                        PreError();
-                                       PRVM_ERROR("%s attempted to address an invalid field (%i) in an edict", PRVM_NAME, OPB->_int);
+                                       prog->error_cmd("%s attempted to address an invalid field (%i) in an edict", prog->name, OPB->_int);
                                        goto cleanup;
                                }
 #if 0
                                if (OPA->edict == 0 && !prog->allowworldwrites)
                                {
                                        PreError();
-                                       PRVM_ERROR("forbidden assignment to null/world entity in %s", PRVM_NAME);
+                                       prog->error_cmd("forbidden assignment to null/world entity in %s", prog->name);
                                        goto cleanup;
                                }
 #endif
                                if (OPA->edict < 0 || OPA->edict >= prog->max_edicts)
                                {
                                        PreError();
-                                       PRVM_ERROR ("%s Progs attempted to read an out of bounds edict number", PRVM_NAME);
+                                       prog->error_cmd("%s Progs attempted to read an out of bounds edict number", prog->name);
                                        goto cleanup;
                                }
                                if ((unsigned int)(OPB->_int) >= (unsigned int)(prog->entityfields))
                                {
                                        PreError();
-                                       PRVM_ERROR("%s attempted to read an invalid field in an edict (%i)", PRVM_NAME, OPB->_int);
+                                       prog->error_cmd("%s attempted to read an invalid field in an edict (%i)", prog->name, OPB->_int);
                                        goto cleanup;
                                }
                                ed = PRVM_PROG_TO_EDICT(OPA->edict);
                                if (OPA->edict < 0 || OPA->edict >= prog->max_edicts)
                                {
                                        PreError();
-                                       PRVM_ERROR ("%s Progs attempted to read an out of bounds edict number", PRVM_NAME);
+                                       prog->error_cmd("%s Progs attempted to read an out of bounds edict number", prog->name);
                                        goto cleanup;
                                }
                                if (OPB->_int < 0 || OPB->_int + 2 >= prog->entityfields)
                                {
                                        PreError();
-                                       PRVM_ERROR("%s attempted to read an invalid field in an edict (%i)", PRVM_NAME, OPB->_int);
+                                       prog->error_cmd("%s attempted to read an invalid field in an edict (%i)", prog->name, OPB->_int);
                                        goto cleanup;
                                }
                                ed = PRVM_PROG_TO_EDICT(OPA->edict);
                                        if (++jumpcount == 10000000 && prvm_runawaycheck)
                                        {
                                                prog->xstatement = st - prog->statements;
-                                               PRVM_Profile(1<<30, 1000000, 0);
-                                               PRVM_ERROR("%s runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", PRVM_NAME, jumpcount);
+                                               PRVM_Profile(prog, 1<<30, 1000000, 0);
+                                               prog->error_cmd("%s runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", prog->name, jumpcount);
                                        }
                                }
                                break;
                                        if (++jumpcount == 10000000 && prvm_runawaycheck)
                                        {
                                                prog->xstatement = st - prog->statements;
-                                               PRVM_Profile(1<<30, 0.01, 0);
-                                               PRVM_ERROR("%s runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", PRVM_NAME, jumpcount);
+                                               PRVM_Profile(prog, 1<<30, 0.01, 0);
+                                               prog->error_cmd("%s runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", prog->name, jumpcount);
                                        }
                                }
                                break;
                                if (++jumpcount == 10000000 && prvm_runawaycheck)
                                {
                                        prog->xstatement = st - prog->statements;
-                                       PRVM_Profile(1<<30, 0.01, 0);
-                                       PRVM_ERROR("%s runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", PRVM_NAME, jumpcount);
+                                       PRVM_Profile(prog, 1<<30, 0.01, 0);
+                                       prog->error_cmd("%s runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", prog->name, jumpcount);
                                }
                                break;
 
                        case OP_CALL7:
                        case OP_CALL8:
 #ifdef PRVMTIMEPROFILING 
-                               tm = Sys_DoubleTime();
-                               prog->xfunction->tprofile += (tm - starttm);
+                               tm = Sys_DirtyTime();
+                               prog->xfunction->tprofile += (tm - starttm >= 0 && tm - starttm < 1800) ? (tm - starttm) : 0;
                                starttm = tm;
 #endif
                                prog->xfunction->profile += (st - startst);
                                prog->xstatement = st - prog->statements;
                                prog->argc = st->op - OP_CALL0;
                                if (!OPA->function)
-                                       PRVM_ERROR("NULL function in %s", PRVM_NAME);
+                                       prog->error_cmd("NULL function in %s", prog->name);
 
                                if(!OPA->function || OPA->function >= (unsigned int)prog->numfunctions)
                                {
                                        PreError();
-                                       PRVM_ERROR("%s CALL outside the program", PRVM_NAME);
+                                       prog->error_cmd("%s CALL outside the program", prog->name);
                                        goto cleanup;
                                }
 
                                        prog->xfunction->builtinsprofile++;
                                        if (builtinnumber < prog->numbuiltins && prog->builtins[builtinnumber])
                                        {
-                                               prog->builtins[builtinnumber]();
+                                               prog->builtins[builtinnumber](prog);
 #ifdef PRVMTIMEPROFILING 
-                                               tm = Sys_DoubleTime();
-                                               newf->tprofile += (tm - starttm);
-                                               prog->xfunction->tbprofile += (tm - starttm);
+                                               tm = Sys_DirtyTime();
+                                               newf->tprofile += (tm - starttm >= 0 && tm - starttm < 1800) ? (tm - starttm) : 0;
+                                               prog->xfunction->tbprofile += (tm - starttm >= 0 && tm - starttm < 1800) ? (tm - starttm) : 0;
                                                starttm = tm;
 #endif
                                        }
                                        else
-                                               PRVM_ERROR("No such builtin #%i in %s; most likely cause: outdated engine build. Try updating!", builtinnumber, PRVM_NAME);
+                                               prog->error_cmd("No such builtin #%i in %s; most likely cause: outdated engine build. Try updating!", builtinnumber, prog->name);
                                }
                                else
-                                       st = prog->statements + PRVM_EnterFunction(newf);
+                                       st = prog->statements + PRVM_EnterFunction(prog, newf);
                                startst = st;
                                break;
 
                        case OP_DONE:
                        case OP_RETURN:
 #ifdef PRVMTIMEPROFILING 
-                               tm = Sys_DoubleTime();
-                               prog->xfunction->tprofile += (tm - starttm);
+                               tm = Sys_DirtyTime();
+                               prog->xfunction->tprofile += (tm - starttm >= 0 && tm - starttm < 1800) ? (tm - starttm) : 0;
                                starttm = tm;
 #endif
                                prog->xfunction->profile += (st - startst);
                                prog->globals.generic[OFS_RETURN+1] = prog->globals.generic[st->operand[0]+1];
                                prog->globals.generic[OFS_RETURN+2] = prog->globals.generic[st->operand[0]+2];
 
-                               st = prog->statements + PRVM_LeaveFunction();
+                               st = prog->statements + PRVM_LeaveFunction(prog);
                                startst = st;
                                if (prog->depth <= exitdepth)
                                        goto cleanup; // all done
                                {
                                        PreError();
                                        prog->xstatement = st - prog->statements;
-                                       PRVM_ERROR("OP_STATE not supported by %s", PRVM_NAME);
+                                       prog->error_cmd("OP_STATE not supported by %s", prog->name);
                                }
                                break;
 
                                if (OPB->_int < 0 || OPB->_int + 4 > pr_edictareasize)
                                {
                                        PreError();
-                                       PRVM_ERROR ("%s Progs attempted to write to an out of bounds edict", PRVM_NAME);
+                                       prog->error_cmd("%s Progs attempted to write to an out of bounds edict", prog->name);
                                        goto cleanup;
                                }
 #endif
                                if (OPA->edict < 0 || OPA->edict >= prog->max_edicts)
                                {
                                        PreError();
-                                       PRVM_ERROR ("%s Progs attempted to read an out of bounds edict number", PRVM_NAME);
+                                       prog->error_cmd("%s Progs attempted to read an out of bounds edict number", prog->name);
                                        goto cleanup;
                                }
                                if (OPB->_int < 0 || OPB->_int >= progs->entityfields)
                                {
                                        PreError();
-                                       PRVM_ERROR ("%s Progs attempted to read an invalid field in an edict", PRVM_NAME);
+                                       prog->error_cmd("%s Progs attempted to read an invalid field in an edict", prog->name);
                                        goto cleanup;
                                }
 #endif
                                if (OPB->_int < 0 || OPB->_int >= pr_globaldefs)
                                {
                                        PreError();
-                                       PRVM_ERROR ("%s Progs attempted to write to an invalid indexed global", PRVM_NAME);
+                                       prog->error_cmd("%s Progs attempted to write to an invalid indexed global", prog->name);
                                        goto cleanup;
                                }
 #endif
                                if (OPB->_int < 0 || OPB->_int + 2 >= pr_globaldefs)
                                {
                                        PreError();
-                                       PRVM_ERROR ("%s Progs attempted to write to an invalid indexed global", PRVM_NAME);
+                                       prog->error_cmd("%s Progs attempted to write to an invalid indexed global", prog->name);
                                        goto cleanup;
                                }
 #endif
                                if (i < 0 || i >= pr_globaldefs)
                                {
                                        PreError();
-                                       PRVM_ERROR ("%s Progs attempted to address an out of bounds global", PRVM_NAME);
+                                       prog->error_cmd("%s Progs attempted to address an out of bounds global", prog->name);
                                        goto cleanup;
                                }
 #endif
                                if (OPA->_int < 0 || OPA->_int >= pr_globaldefs)
                                {
                                        PreError();
-                                       PRVM_ERROR ("%s Progs attempted to read an invalid indexed global", PRVM_NAME);
+                                       prog->error_cmd("%s Progs attempted to read an invalid indexed global", prog->name);
                                        goto cleanup;
                                }
 #endif
                                if (OPA->_int < 0 || OPA->_int + 2 >= pr_globaldefs)
                                {
                                        PreError();
-                                       PRVM_ERROR ("%s Progs attempted to read an invalid indexed global", PRVM_NAME);
+                                       prog->error_cmd("%s Progs attempted to read an invalid indexed global", prog->name);
                                        goto cleanup;
                                }
 #endif
                                if (OPA->_int < 0 || OPA->_int >= st->b)
                                {
                                        PreError();
-                                       PRVM_ERROR ("%s Progs boundcheck failed at line number %d, value is < 0 or >= %d", PRVM_NAME, st->b, st->c);
+                                       prog->error_cmd("%s Progs boundcheck failed at line number %d, value is < 0 or >= %d", prog->name, st->b, st->c);
                                        goto cleanup;
                                }
                                break;
 
                        default:
                                PreError();
-                               PRVM_ERROR ("Bad opcode %i in %s", st->op, PRVM_NAME);
+                               prog->error_cmd("Bad opcode %i in %s", st->op, prog->name);
                                goto cleanup;
                        }
                }
index e90be22ecb4493a3f33b7c0a729fc60182ddd726..f656b26f4eb6521bdc2576161f4d81be66c213ca 100644 (file)
@@ -395,6 +395,7 @@ extern char engineversion[128];
 #include "keys.h"
 #include "console.h"
 #include "menu.h"
+#include "csprogs.h"
 
 extern qboolean noclip_anglehack;
 
@@ -501,6 +502,8 @@ qboolean Sys_HaveSSE2(void);
 extern int host_framecount;
 /// not bounded in any way, changed at start of every frame, never reset
 extern double realtime;
+/// equal to Sys_DirtyTime() at the start of this host frame
+extern double host_dirtytime;
 
 void Host_InitCommands(void);
 void Host_Main(void);
index 67d32ae80fbae5b79ed097b8ff88fcd91f5d00bb..b7975c6c01b4281eec6c5d529a418a66e40ebb06 100644 (file)
@@ -16,20 +16,20 @@ skinframe_t *r_lightningbeamqmbtexture;
 int r_lightningbeamelement3i[18] = {0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11};
 unsigned short r_lightningbeamelement3s[18] = {0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11};
 
-void r_lightningbeams_start(void)
+static void r_lightningbeams_start(void)
 {
        r_lightningbeamtexture = NULL;
        r_lightningbeamqmbtexture = NULL;
 }
 
-void r_lightningbeams_setupqmbtexture(void)
+static void r_lightningbeams_setupqmbtexture(void)
 {
        r_lightningbeamqmbtexture = R_SkinFrame_LoadExternal("textures/particles/lightning.pcx", TEXF_ALPHA | TEXF_FORCELINEAR, false);
        if (r_lightningbeamqmbtexture == NULL)
                Cvar_SetValueQuick(&r_lightningbeam_qmbtexture, false);
 }
 
-void r_lightningbeams_setuptexture(void)
+static void r_lightningbeams_setuptexture(void)
 {
 #if 0
 #define BEAMWIDTH 128
@@ -103,7 +103,7 @@ void r_lightningbeams_setuptexture(void)
                        }
                }
 
-               Image_WriteTGABGRA(va("lightningbeam%i.tga", imagenumber), BEAMWIDTH, BEAMHEIGHT, pixels);
+               Image_WriteTGABGRA(va(vabuf, sizeof(vabuf), "lightningbeam%i.tga", imagenumber), BEAMWIDTH, BEAMHEIGHT, pixels);
        }
 
        r_lightningbeamtexture = R_LoadTexture2D(r_lightningbeamtexturepool, "lightningbeam", BEAMWIDTH, BEAMHEIGHT, pixels, TEXTYPE_BGRA, TEXF_FORCELINEAR, NULL);
@@ -151,13 +151,13 @@ void r_lightningbeams_setuptexture(void)
 #endif
 }
 
-void r_lightningbeams_shutdown(void)
+static void r_lightningbeams_shutdown(void)
 {
        r_lightningbeamtexture = NULL;
        r_lightningbeamqmbtexture = NULL;
 }
 
-void r_lightningbeams_newmap(void)
+static void r_lightningbeams_newmap(void)
 {
        if (r_lightningbeamtexture)
                R_SkinFrame_MarkUsed(r_lightningbeamtexture);
@@ -177,7 +177,7 @@ void R_LightningBeams_Init(void)
        R_RegisterModule("R_LightningBeams", r_lightningbeams_start, r_lightningbeams_shutdown, r_lightningbeams_newmap, NULL, NULL);
 }
 
-void R_CalcLightningBeamPolygonVertex3f(float *v, const float *start, const float *end, const float *offset)
+static void R_CalcLightningBeamPolygonVertex3f(float *v, const float *start, const float *end, const float *offset)
 {
        // near right corner
        VectorAdd     (start, offset, (v + 0));
@@ -189,7 +189,7 @@ void R_CalcLightningBeamPolygonVertex3f(float *v, const float *start, const floa
        VectorAdd     (end  , offset, (v + 9));
 }
 
-void R_CalcLightningBeamPolygonTexCoord2f(float *tc, float t1, float t2)
+static void R_CalcLightningBeamPolygonTexCoord2f(float *tc, float t1, float t2)
 {
        if (r_lightningbeam_qmbtexture.integer)
        {
@@ -217,7 +217,7 @@ void R_CalcLightningBeamPolygonTexCoord2f(float *tc, float t1, float t2)
 
 float beamrepeatscale;
 
-void R_DrawLightningBeam_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
+static void R_DrawLightningBeam_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
 {
        int surfacelistindex;
        float vertex3f[12*3];
index 521f6984d4088b256227cbb59ce6d172c6390ad1..fc10e437ef81a64aa66a5fad4e45b59c20faa0a8 100644 (file)
@@ -146,7 +146,7 @@ demonstrated by the game Doom3.
 extern LPDIRECT3DDEVICE9 vid_d3d9dev;
 #endif
 
-extern void R_Shadow_EditLights_Init(void);
+static void R_Shadow_EditLights_Init(void);
 
 typedef enum r_shadow_rendermode_e
 {
@@ -429,7 +429,7 @@ skinframe_t *r_editlights_sprcubemaplight;
 skinframe_t *r_editlights_sprcubemapnoshadowlight;
 skinframe_t *r_editlights_sprselection;
 
-void R_Shadow_SetShadowMode(void)
+static void R_Shadow_SetShadowMode(void)
 {
        r_shadow_shadowmapmaxsize = bound(1, r_shadow_shadowmapping_maxsize.integer, (int)vid.maxtexturesize_2d / 4);
        r_shadow_shadowmapvsdct = r_shadow_shadowmapping_vsdct.integer != 0 && vid.renderpath == RENDERPATH_GL20;
@@ -509,7 +509,7 @@ qboolean R_Shadow_ShadowMappingEnabled(void)
        }
 }
 
-void R_Shadow_FreeShadowMaps(void)
+static void R_Shadow_FreeShadowMaps(void)
 {
        R_Shadow_SetShadowMode();
 
@@ -530,7 +530,7 @@ void R_Shadow_FreeShadowMaps(void)
        r_shadow_shadowmapvsdcttexture = NULL;
 }
 
-void r_shadow_start(void)
+static void r_shadow_start(void)
 {
        // allocate vertex processing arrays
        r_shadow_bouncegridpixels = NULL;
@@ -596,7 +596,7 @@ void r_shadow_start(void)
 }
 
 static void R_Shadow_FreeDeferred(void);
-void r_shadow_shutdown(void)
+static void r_shadow_shutdown(void)
 {
        CHECKGLERROR
        R_Shadow_UncompileWorldLights();
@@ -679,7 +679,7 @@ void r_shadow_shutdown(void)
                Mem_Free(r_shadow_buffer_lighttrispvs);
 }
 
-void r_shadow_newmap(void)
+static void r_shadow_newmap(void)
 {
        if (r_shadow_bouncegridtexture) R_FreeTexture(r_shadow_bouncegridtexture);r_shadow_bouncegridtexture = NULL;
        if (r_shadow_lightcorona)                 R_SkinFrame_MarkUsed(r_shadow_lightcorona);
@@ -826,7 +826,7 @@ matrix4x4_t matrix_attenuationz =
        }
 };
 
-void R_Shadow_ResizeShadowArrays(int numvertices, int numtriangles, int vertscale, int triscale)
+static void R_Shadow_ResizeShadowArrays(int numvertices, int numtriangles, int vertscale, int triscale)
 {
        numvertices = ((numvertices + 255) & ~255) * vertscale;
        numtriangles = ((numtriangles + 255) & ~255) * triscale;
@@ -1301,7 +1301,7 @@ void R_Shadow_MarkVolumeFromBox(int firsttriangle, int numtris, const float *inv
        }
 }
 
-qboolean R_Shadow_UseZPass(vec3_t mins, vec3_t maxs)
+static qboolean R_Shadow_UseZPass(vec3_t mins, vec3_t maxs)
 {
 #if 1
        return false;
@@ -1456,7 +1456,7 @@ int R_Shadow_CalcTriangleSideMask(const vec3_t p1, const vec3_t p2, const vec3_t
        return mask;
 }
 
-int R_Shadow_CalcBBoxSideMask(const vec3_t mins, const vec3_t maxs, const matrix4x4_t *worldtolight, const matrix4x4_t *radiustolight, float bias)
+static int R_Shadow_CalcBBoxSideMask(const vec3_t mins, const vec3_t maxs, const matrix4x4_t *worldtolight, const matrix4x4_t *radiustolight, float bias)
 {
        vec3_t center, radius, lightcenter, lightradius, pmin, pmax;
        float dp1, dn1, ap1, an1, dp2, dn2, ap2, an2;
@@ -1525,7 +1525,7 @@ int R_Shadow_CalcSphereSideMask(const vec3_t p, float radius, float bias)
     return mask;
 }
 
-int R_Shadow_CullFrustumSides(rtlight_t *rtlight, float size, float border)
+static int R_Shadow_CullFrustumSides(rtlight_t *rtlight, float size, float border)
 {
        int i;
        vec3_t p, n;
@@ -2138,7 +2138,7 @@ static void R_Shadow_MakeShadowMap(int side, int size)
 #endif
 }
 
-void R_Shadow_RenderMode_ShadowMap(int side, int clear, int size)
+static void R_Shadow_RenderMode_ShadowMap(int side, int clear, int size)
 {
        float nearclip, farclip, bias;
        r_viewport_t viewport;
@@ -3181,8 +3181,8 @@ static void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numve
        int *newe;
        const int *e;
        float *c;
-       int maxtriangles = 4096;
-       static int newelements[4096*3];
+       int maxtriangles = 1024;
+       int newelements[1024*3];
        R_Shadow_RenderLighting_Light_Vertex_Shading(firstvertex, numvertices, diffusecolor2, ambientcolor2);
        for (renders = 0;renders < 4;renders++)
        {
@@ -3570,7 +3570,7 @@ void R_Shadow_UncompileWorldLights(void)
        }
 }
 
-void R_Shadow_ComputeShadowCasterCullingPlanes(rtlight_t *rtlight)
+static void R_Shadow_ComputeShadowCasterCullingPlanes(rtlight_t *rtlight)
 {
        int i, j;
        mplane_t plane;
@@ -3739,7 +3739,7 @@ void R_Shadow_ComputeShadowCasterCullingPlanes(rtlight_t *rtlight)
 #endif
 }
 
-void R_Shadow_DrawWorldShadow_ShadowMap(int numsurfaces, int *surfacelist, const unsigned char *trispvs, const unsigned char *surfacesides)
+static void R_Shadow_DrawWorldShadow_ShadowMap(int numsurfaces, int *surfacelist, const unsigned char *trispvs, const unsigned char *surfacesides)
 {
        shadowmesh_t *mesh;
 
@@ -3769,7 +3769,7 @@ void R_Shadow_DrawWorldShadow_ShadowMap(int numsurfaces, int *surfacelist, const
        rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
 }
 
-void R_Shadow_DrawWorldShadow_ShadowVolume(int numsurfaces, int *surfacelist, const unsigned char *trispvs)
+static void R_Shadow_DrawWorldShadow_ShadowVolume(int numsurfaces, int *surfacelist, const unsigned char *trispvs)
 {
        qboolean zpass = false;
        shadowmesh_t *mesh;
@@ -3844,7 +3844,7 @@ void R_Shadow_DrawWorldShadow_ShadowVolume(int numsurfaces, int *surfacelist, co
        rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
 }
 
-void R_Shadow_DrawEntityShadow(entity_render_t *ent)
+static void R_Shadow_DrawEntityShadow(entity_render_t *ent)
 {
        vec3_t relativeshadoworigin, relativeshadowmins, relativeshadowmaxs;
        vec_t relativeshadowradius;
@@ -3880,7 +3880,7 @@ void R_Shadow_SetupEntityLight(const entity_render_t *ent)
        Matrix4x4_Transform(&ent->inversematrix, rsurface.rtlight->shadoworigin, rsurface.entitylightorigin);
 }
 
-void R_Shadow_DrawWorldLight(int numsurfaces, int *surfacelist, const unsigned char *lighttrispvs)
+static void R_Shadow_DrawWorldLight(int numsurfaces, int *surfacelist, const unsigned char *lighttrispvs)
 {
        if (!r_refdef.scene.worldmodel->DrawLight)
                return;
@@ -3897,7 +3897,7 @@ void R_Shadow_DrawWorldLight(int numsurfaces, int *surfacelist, const unsigned c
        rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
 }
 
-void R_Shadow_DrawEntityLight(entity_render_t *ent)
+static void R_Shadow_DrawEntityLight(entity_render_t *ent)
 {
        dp_model_t *model = ent->model;
        if (!model->DrawLight)
@@ -3910,7 +3910,7 @@ void R_Shadow_DrawEntityLight(entity_render_t *ent)
        rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
 }
 
-void R_Shadow_PrepareLight(rtlight_t *rtlight)
+static void R_Shadow_PrepareLight(rtlight_t *rtlight)
 {
        int i;
        float f;
@@ -4144,7 +4144,7 @@ void R_Shadow_PrepareLight(rtlight_t *rtlight)
        }
 }
 
-void R_Shadow_DrawLight(rtlight_t *rtlight)
+static void R_Shadow_DrawLight(rtlight_t *rtlight)
 {
        int i;
        int numsurfaces;
@@ -5097,7 +5097,7 @@ void R_DrawModelShadows(int fbo, rtexture_t *depthtexture, rtexture_t *colortext
        //R_Shadow_RenderMode_End();
 }
 
-void R_BeginCoronaQuery(rtlight_t *rtlight, float scale, qboolean usequery)
+static void R_BeginCoronaQuery(rtlight_t *rtlight, float scale, qboolean usequery)
 {
        float zdist;
        vec3_t centerorigin;
@@ -5159,7 +5159,7 @@ void R_BeginCoronaQuery(rtlight_t *rtlight, float scale, qboolean usequery)
 
 static float spritetexcoord2f[4*2] = {0, 1, 0, 0, 1, 0, 1, 1};
 
-void R_DrawCorona(rtlight_t *rtlight, float cscale, float scale)
+static void R_DrawCorona(rtlight_t *rtlight, float cscale, float scale)
 {
        vec3_t color;
        GLint allpixels = 0, visiblepixels = 0;
@@ -5350,12 +5350,12 @@ void R_Shadow_DrawCoronas(void)
 
 
 
-dlight_t *R_Shadow_NewWorldLight(void)
+static dlight_t *R_Shadow_NewWorldLight(void)
 {
        return (dlight_t *)Mem_ExpandableArray_AllocRecord(&r_shadow_worldlightsarray);
 }
 
-void R_Shadow_UpdateWorldLight(dlight_t *light, vec3_t origin, vec3_t angles, vec3_t color, vec_t radius, vec_t corona, int style, int shadowenable, const char *cubemapname, vec_t coronasizescale, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int flags)
+static void R_Shadow_UpdateWorldLight(dlight_t *light, vec3_t origin, vec3_t angles, vec3_t color, vec_t radius, vec_t corona, int style, int shadowenable, const char *cubemapname, vec_t coronasizescale, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int flags)
 {
        matrix4x4_t matrix;
        // validate parameters
@@ -5396,7 +5396,7 @@ void R_Shadow_UpdateWorldLight(dlight_t *light, vec3_t origin, vec3_t angles, ve
        R_RTLight_Update(&light->rtlight, true, &matrix, light->color, light->style, light->cubemapname[0] ? light->cubemapname : NULL, light->shadow, light->corona, light->coronasizescale, light->ambientscale, light->diffusescale, light->specularscale, light->flags);
 }
 
-void R_Shadow_FreeWorldLight(dlight_t *light)
+static void R_Shadow_FreeWorldLight(dlight_t *light)
 {
        if (r_shadow_selectedlight == light)
                r_shadow_selectedlight = NULL;
@@ -5418,7 +5418,7 @@ void R_Shadow_ClearWorldLights(void)
        r_shadow_selectedlight = NULL;
 }
 
-void R_Shadow_SelectLight(dlight_t *light)
+static void R_Shadow_SelectLight(dlight_t *light)
 {
        if (r_shadow_selectedlight)
                r_shadow_selectedlight->selected = false;
@@ -5427,7 +5427,7 @@ void R_Shadow_SelectLight(dlight_t *light)
                r_shadow_selectedlight->selected = true;
 }
 
-void R_Shadow_DrawCursor_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
+static void R_Shadow_DrawCursor_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
 {
        // this is never batched (there can be only one)
        float vertex3f[12];
@@ -5436,7 +5436,7 @@ void R_Shadow_DrawCursor_TransparentCallback(const entity_render_t *ent, const r
        R_DrawCustomSurface(r_editlights_sprcursor, &identitymatrix, MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_FULLBRIGHT | MATERIALFLAG_NOCULLFACE, 0, 4, 0, 2, false, false);
 }
 
-void R_Shadow_DrawLightSprite_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
+static void R_Shadow_DrawLightSprite_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
 {
        float intensity;
        float s;
@@ -5515,7 +5515,7 @@ int R_Shadow_GetRTLightInfo(unsigned int lightindex, float *origin, float *radiu
        return 1;
 }
 
-void R_Shadow_SelectLightInView(void)
+static void R_Shadow_SelectLightInView(void)
 {
        float bestrating, rating, temp[3];
        dlight_t *best;
@@ -5770,6 +5770,7 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void)
        const char *data;
        float origin[3], angles[3], radius, color[3], light[4], fadescale, lightscale, originhack[3], overridecolor[3], vec[4];
        char key[256], value[MAX_INPUTLINE];
+       char vabuf[1024];
 
        if (cl.worldmodel == NULL)
        {
@@ -5973,14 +5974,14 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void)
                }
                VectorAdd(origin, originhack, origin);
                if (radius >= 1)
-                       R_Shadow_UpdateWorldLight(R_Shadow_NewWorldLight(), origin, angles, color, radius, (pflags & PFLAGS_CORONA) != 0, style, (pflags & PFLAGS_NOSHADOW) == 0, skin >= 16 ? va("cubemaps/%i", skin) : NULL, 0.25, 0, 1, 1, LIGHTFLAG_REALTIMEMODE);
+                       R_Shadow_UpdateWorldLight(R_Shadow_NewWorldLight(), origin, angles, color, radius, (pflags & PFLAGS_CORONA) != 0, style, (pflags & PFLAGS_NOSHADOW) == 0, skin >= 16 ? va(vabuf, sizeof(vabuf), "cubemaps/%i", skin) : NULL, 0.25, 0, 1, 1, LIGHTFLAG_REALTIMEMODE);
        }
        if (entfiledata)
                Mem_Free(entfiledata);
 }
 
 
-void R_Shadow_SetCursorLocationForView(void)
+static void R_Shadow_SetCursorLocationForView(void)
 {
        vec_t dist, push;
        vec3_t dest, endpos;
@@ -6017,7 +6018,7 @@ void R_Shadow_UpdateWorldLightSelection(void)
                R_Shadow_SelectLight(NULL);
 }
 
-void R_Shadow_EditLights_Clear_f(void)
+static void R_Shadow_EditLights_Clear_f(void)
 {
        R_Shadow_ClearWorldLights();
 }
@@ -6037,26 +6038,26 @@ void R_Shadow_EditLights_Reload_f(void)
        }
 }
 
-void R_Shadow_EditLights_Save_f(void)
+static void R_Shadow_EditLights_Save_f(void)
 {
        if (!cl.worldmodel)
                return;
        R_Shadow_SaveWorldLights();
 }
 
-void R_Shadow_EditLights_ImportLightEntitiesFromMap_f(void)
+static void R_Shadow_EditLights_ImportLightEntitiesFromMap_f(void)
 {
        R_Shadow_ClearWorldLights();
        R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite();
 }
 
-void R_Shadow_EditLights_ImportLightsFile_f(void)
+static void R_Shadow_EditLights_ImportLightsFile_f(void)
 {
        R_Shadow_ClearWorldLights();
        R_Shadow_LoadLightsFile();
 }
 
-void R_Shadow_EditLights_Spawn_f(void)
+static void R_Shadow_EditLights_Spawn_f(void)
 {
        vec3_t color;
        if (!r_editlights.integer)
@@ -6073,7 +6074,7 @@ void R_Shadow_EditLights_Spawn_f(void)
        R_Shadow_UpdateWorldLight(R_Shadow_NewWorldLight(), r_editlights_cursorlocation, vec3_origin, color, 200, 0, 0, true, NULL, 0.25, 0, 1, 1, LIGHTFLAG_REALTIMEMODE);
 }
 
-void R_Shadow_EditLights_Edit_f(void)
+static void R_Shadow_EditLights_Edit_f(void)
 {
        vec3_t origin, angles, color;
        vec_t radius, corona, coronasizescale, ambientscale, diffusescale, specularscale;
@@ -6399,7 +6400,7 @@ void R_Shadow_EditLights_Edit_f(void)
        R_Shadow_UpdateWorldLight(r_shadow_selectedlight, origin, angles, color, radius, corona, style, shadows, cubemapname, coronasizescale, ambientscale, diffusescale, specularscale, flags);
 }
 
-void R_Shadow_EditLights_EditAll_f(void)
+static void R_Shadow_EditLights_EditAll_f(void)
 {
        size_t lightindex;
        dlight_t *light, *oldselected;
@@ -6472,7 +6473,7 @@ void R_Shadow_EditLights_DrawSelectedLightProperties(void)
        dpsnprintf(temp, sizeof(temp), "RealTimeMode : %s\n", (r_shadow_selectedlight->flags & LIGHTFLAG_REALTIMEMODE) ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT);y += 8;
 }
 
-void R_Shadow_EditLights_ToggleShadow_f(void)
+static void R_Shadow_EditLights_ToggleShadow_f(void)
 {
        if (!r_editlights.integer)
        {
@@ -6487,7 +6488,7 @@ void R_Shadow_EditLights_ToggleShadow_f(void)
        R_Shadow_UpdateWorldLight(r_shadow_selectedlight, r_shadow_selectedlight->origin, r_shadow_selectedlight->angles, r_shadow_selectedlight->color, r_shadow_selectedlight->radius, r_shadow_selectedlight->corona, r_shadow_selectedlight->style, !r_shadow_selectedlight->shadow, r_shadow_selectedlight->cubemapname, r_shadow_selectedlight->coronasizescale, r_shadow_selectedlight->ambientscale, r_shadow_selectedlight->diffusescale, r_shadow_selectedlight->specularscale, r_shadow_selectedlight->flags);
 }
 
-void R_Shadow_EditLights_ToggleCorona_f(void)
+static void R_Shadow_EditLights_ToggleCorona_f(void)
 {
        if (!r_editlights.integer)
        {
@@ -6502,7 +6503,7 @@ void R_Shadow_EditLights_ToggleCorona_f(void)
        R_Shadow_UpdateWorldLight(r_shadow_selectedlight, r_shadow_selectedlight->origin, r_shadow_selectedlight->angles, r_shadow_selectedlight->color, r_shadow_selectedlight->radius, !r_shadow_selectedlight->corona, r_shadow_selectedlight->style, r_shadow_selectedlight->shadow, r_shadow_selectedlight->cubemapname, r_shadow_selectedlight->coronasizescale, r_shadow_selectedlight->ambientscale, r_shadow_selectedlight->diffusescale, r_shadow_selectedlight->specularscale, r_shadow_selectedlight->flags);
 }
 
-void R_Shadow_EditLights_Remove_f(void)
+static void R_Shadow_EditLights_Remove_f(void)
 {
        if (!r_editlights.integer)
        {
@@ -6518,7 +6519,7 @@ void R_Shadow_EditLights_Remove_f(void)
        r_shadow_selectedlight = NULL;
 }
 
-void R_Shadow_EditLights_Help_f(void)
+static void R_Shadow_EditLights_Help_f(void)
 {
        Con_Print(
 "Documentation on r_editlights system:\n"
@@ -6575,7 +6576,7 @@ void R_Shadow_EditLights_Help_f(void)
        );
 }
 
-void R_Shadow_EditLights_CopyInfo_f(void)
+static void R_Shadow_EditLights_CopyInfo_f(void)
 {
        if (!r_editlights.integer)
        {
@@ -6604,7 +6605,7 @@ void R_Shadow_EditLights_CopyInfo_f(void)
        r_shadow_bufferlight.flags = r_shadow_selectedlight->flags;
 }
 
-void R_Shadow_EditLights_PasteInfo_f(void)
+static void R_Shadow_EditLights_PasteInfo_f(void)
 {
        if (!r_editlights.integer)
        {
@@ -6619,7 +6620,7 @@ void R_Shadow_EditLights_PasteInfo_f(void)
        R_Shadow_UpdateWorldLight(r_shadow_selectedlight, r_shadow_selectedlight->origin, r_shadow_bufferlight.angles, r_shadow_bufferlight.color, r_shadow_bufferlight.radius, r_shadow_bufferlight.corona, r_shadow_bufferlight.style, r_shadow_bufferlight.shadow, r_shadow_bufferlight.cubemapname, r_shadow_bufferlight.coronasizescale, r_shadow_bufferlight.ambientscale, r_shadow_bufferlight.diffusescale, r_shadow_bufferlight.specularscale, r_shadow_bufferlight.flags);
 }
 
-void R_Shadow_EditLights_Lock_f(void)
+static void R_Shadow_EditLights_Lock_f(void)
 {
        if (!r_editlights.integer)
        {
@@ -6639,7 +6640,7 @@ void R_Shadow_EditLights_Lock_f(void)
        r_editlights_lockcursor = true;
 }
 
-void R_Shadow_EditLights_Init(void)
+static void R_Shadow_EditLights_Init(void)
 {
        Cvar_RegisterVariable(&r_editlights);
        Cvar_RegisterVariable(&r_editlights_cursordistance);
diff --git a/r_sky.c b/r_sky.c
index 0f019bbb25b5ab2dfd26d40148b44daf84768eb7..97b2dafe6fae404f48df7744575ee01106a6632e 100644 (file)
--- a/r_sky.c
+++ b/r_sky.c
@@ -74,7 +74,7 @@ void R_SkyStartFrame(void)
 R_SetSkyBox
 ==================
 */
-void R_UnloadSkyBox(void)
+static void R_UnloadSkyBox(void)
 {
        int i;
        int c = 0;
@@ -91,13 +91,14 @@ void R_UnloadSkyBox(void)
                Con_Printf("unloading skybox\n");
 }
 
-int R_LoadSkyBox(void)
+static int R_LoadSkyBox(void)
 {
        int i, j, success;
        int indices[4] = {0,1,2,3};
        char name[MAX_INPUTLINE];
        unsigned char *image_buffer;
        unsigned char *temp;
+       char vabuf[1024];
 
        R_UnloadSkyBox();
 
@@ -122,7 +123,7 @@ int R_LoadSkyBox(void)
                        }
                        temp = (unsigned char *)Mem_Alloc(tempmempool, image_width*image_height*4);
                        Image_CopyMux (temp, image_buffer, image_width, image_height, suffix[j][i].flipx, suffix[j][i].flipy, suffix[j][i].flipdiagonal, 4, 4, indices);
-                       skyboxskinframe[i] = R_SkinFrame_LoadInternalBGRA(va("skyboxside%d", i), TEXF_CLAMP | (gl_texturecompression_sky.integer ? TEXF_COMPRESS : 0), temp, image_width, image_height, vid.sRGB3D);
+                       skyboxskinframe[i] = R_SkinFrame_LoadInternalBGRA(va(vabuf, sizeof(vabuf), "skyboxside%d", i), TEXF_CLAMP | (gl_texturecompression_sky.integer ? TEXF_COMPRESS : 0), temp, image_width, image_height, vid.sRGB3D);
                        Mem_Free(image_buffer);
                        Mem_Free(temp);
                        success++;
@@ -158,7 +159,7 @@ int R_SetSkyBox(const char *sky)
 }
 
 // LordHavoc: added LoadSky console command
-void LoadSky_f (void)
+static void LoadSky_f (void)
 {
        switch (Cmd_Argc())
        {
index 5e150dad634a310a7e387ef720ffce25ed0a32ac..27338621ad6199e25e48632356d28bf58745192e 100644 (file)
@@ -35,7 +35,7 @@ extern cvar_t r_overheadsprites_scaley;
 #define SIDE_BOTTOM 3
 #define SIDE_RIGHT 4
 
-void R_TrackSprite(const entity_render_t *ent, vec3_t origin, vec3_t left, vec3_t up, int *edge, float *dir_angle)
+static void R_TrackSprite(const entity_render_t *ent, vec3_t origin, vec3_t left, vec3_t up, int *edge, float *dir_angle)
 {
        float distance;
        vec3_t bCoord; // body coordinates of object
@@ -141,7 +141,7 @@ void R_TrackSprite(const entity_render_t *ent, vec3_t origin, vec3_t left, vec3_
        }
 }
 
-void R_RotateSprite(const mspriteframe_t *frame, vec3_t origin, vec3_t left, vec3_t up, int edge, float dir_angle)
+static void R_RotateSprite(const mspriteframe_t *frame, vec3_t origin, vec3_t left, vec3_t up, int edge, float dir_angle)
 {
        if(!(r_track_sprites_flags.integer & TSF_ROTATE))
        {
@@ -205,7 +205,7 @@ void R_RotateSprite(const mspriteframe_t *frame, vec3_t origin, vec3_t left, vec
 
 static float spritetexcoord2f[4*2] = {0, 1, 0, 0, 1, 0, 1, 1};
 
-void R_Model_Sprite_Draw_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
+static void R_Model_Sprite_Draw_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
 {
        int i;
        dp_model_t *model = ent->model;
index bc654a345791595dcbe54ca77dd445be30da550f..2c5b6ec025f9c8eea698acc0e93d678582c71721 100644 (file)
@@ -199,5 +199,7 @@ void R_ClearTexture (rtexture_t *rt);
 // returns the desired picmip level for given TEXF_ flags
 int R_PicmipForFlags(int flags);
 
+void R_TextureStats_Print(qboolean printeach, qboolean printpool, qboolean printtotal);
+
 #endif
 
index 46c0c658ee502e556aa92453e858dbc0c2d4cfc4..70d5515df0b7abbd8d3169f7417dd639c23d91f7 100644 (file)
--- a/render.h
+++ b/render.h
@@ -27,22 +27,22 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 extern float ixtable[4096];
 
 // fog stuff
-extern void FOG_clear(void);
+void FOG_clear(void);
 
 // sky stuff
 extern cvar_t r_sky;
 extern cvar_t r_skyscroll1;
 extern cvar_t r_skyscroll2;
 extern int skyrenderlater, skyrendermasked;
-extern int R_SetSkyBox(const char *sky);
-extern void R_SkyStartFrame(void);
-extern void R_Sky(void);
-extern void R_ResetSkyBox(void);
+int R_SetSkyBox(const char *sky);
+void R_SkyStartFrame(void);
+void R_Sky(void);
+void R_ResetSkyBox(void);
 
 // SHOWLMP stuff (Nehahra)
-extern void SHOWLMP_decodehide(void);
-extern void SHOWLMP_decodeshow(void);
-extern void SHOWLMP_drawall(void);
+void SHOWLMP_decodehide(void);
+void SHOWLMP_decodeshow(void);
+void SHOWLMP_drawall(void);
 
 // render profiling stuff
 extern int r_timereport_active;
@@ -529,5 +529,42 @@ extern cvar_t r_shadows_throwdirection;
 extern cvar_t r_shadows_focus;
 extern cvar_t r_shadows_shadowmapscale;
 
+void R_Model_Sprite_Draw(entity_render_t *ent);
+
+struct prvm_prog_s;
+void R_UpdateFog(void);
+qboolean CL_VM_UpdateView(void);
+void SCR_DrawConsole(void);
+void R_Shadow_EditLights_DrawSelectedLightProperties(void);
+void R_DecalSystem_Reset(decalsystem_t *decalsystem);
+void R_Shadow_UpdateBounceGridTexture(void);
+void R_DrawLightningBeams(void);
+void VM_CL_AddPolygonsToMeshQueue(struct prvm_prog_s *prog);
+void R_DrawPortals(void);
+void R_DrawModelShadows(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture);
+void R_DrawModelShadowMaps(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture);
+void R_BuildLightMap(const entity_render_t *ent, msurface_t *surface);
+void R_Water_AddWaterPlane(msurface_t *surface, int entno);
+int R_Shadow_GetRTLightInfo(unsigned int lightindex, float *origin, float *radius, float *color);
+dp_font_t *FindFont(const char *title, qboolean allocate_new);
+void LoadFont(qboolean override, const char *name, dp_font_t *fnt, float scale, float voffset);
+
+void Render_Init(void);
+
+// these are called by Render_Init
+void R_Textures_Init(void);
+void GL_Draw_Init(void);
+void GL_Main_Init(void);
+void R_Shadow_Init(void);
+void R_Sky_Init(void);
+void GL_Surf_Init(void);
+void R_Particles_Init(void);
+void R_Explosion_Init(void);
+void gl_backend_init(void);
+void Sbar_Init(void);
+void R_LightningBeams_Init(void);
+void Mod_RenderInit(void);
+void Font_Init(void);
+
 #endif
 
diff --git a/sbar.c b/sbar.c
index 188c4e23a5f2263669a3663ef1dbbb3022e1af98..43a1b93d45e906c52813e924fb5a0252fb69116a 100644 (file)
--- a/sbar.c
+++ b/sbar.c
@@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "quakedef.h"
 #include "time.h"
 #include "cl_collision.h"
+#include "csprogs.h"
 
 cachepic_t *sb_disc;
 
@@ -117,12 +118,11 @@ cvar_t crosshair_color_blue = {CVAR_SAVE, "crosshair_color_blue", "0", "customiz
 cvar_t crosshair_color_alpha = {CVAR_SAVE, "crosshair_color_alpha", "1", "how opaque the crosshair should be"};
 cvar_t crosshair_size = {CVAR_SAVE, "crosshair_size", "1", "adjusts size of the crosshair on the screen"};
 
-void Sbar_MiniDeathmatchOverlay (int x, int y);
-void Sbar_DeathmatchOverlay (void);
-void Sbar_IntermissionOverlay (void);
-void Sbar_FinaleOverlay (void);
+static void Sbar_MiniDeathmatchOverlay (int x, int y);
+static void Sbar_DeathmatchOverlay (void);
+static void Sbar_IntermissionOverlay (void);
+static void Sbar_FinaleOverlay (void);
 
-void CL_VM_UpdateShowingScoresState (int showingscores);
 
 
 /*
@@ -132,7 +132,7 @@ Sbar_ShowScores
 Tab key down
 ===============
 */
-void Sbar_ShowScores (void)
+static void Sbar_ShowScores (void)
 {
        if (sb_showscores)
                return;
@@ -147,14 +147,15 @@ Sbar_DontShowScores
 Tab key up
 ===============
 */
-void Sbar_DontShowScores (void)
+static void Sbar_DontShowScores (void)
 {
        sb_showscores = false;
        CL_VM_UpdateShowingScoresState(sb_showscores);
 }
 
-void sbar_start(void)
+static void sbar_start(void)
 {
+       char vabuf[1024];
        int i;
 
        if (gamemode == GAME_DELUXEQUAKE || gamemode == GAME_BLOODOMNICIDE)
@@ -165,7 +166,7 @@ void sbar_start(void)
                sb_disc = Draw_CachePic_Flags ("gfx/disc", CACHEPICFLAG_QUIET);
 
                for (i = 0;i < 10;i++)
-                       sb_nums[0][i] = Draw_CachePic_Flags (va("gfx/num_%i",i), CACHEPICFLAG_QUIET);
+                       sb_nums[0][i] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/num_%i",i), CACHEPICFLAG_QUIET);
 
                somsb_health = Draw_CachePic_Flags ("gfx/hud_health", CACHEPICFLAG_QUIET);
                somsb_ammo[0] = Draw_CachePic_Flags ("gfx/sb_shells", CACHEPICFLAG_QUIET);
@@ -179,7 +180,7 @@ void sbar_start(void)
        else if (gamemode == GAME_NEXUIZ)
        {
                for (i = 0;i < 10;i++)
-                       sb_nums[0][i] = Draw_CachePic_Flags (va("gfx/num_%i",i), CACHEPICFLAG_QUIET);
+                       sb_nums[0][i] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/num_%i",i), CACHEPICFLAG_QUIET);
                sb_nums[0][10] = Draw_CachePic_Flags ("gfx/num_minus", CACHEPICFLAG_QUIET);
                sb_colon = Draw_CachePic_Flags ("gfx/num_colon", CACHEPICFLAG_QUIET);
 
@@ -212,7 +213,7 @@ void sbar_start(void)
                sb_sbar_overlay = Draw_CachePic_Flags ("gfx/sbar_overlay", CACHEPICFLAG_QUIET);
 
                for(i = 0; i < 9;i++)
-                       sb_weapons[0][i] = Draw_CachePic_Flags (va("gfx/inv_weapon%i",i), CACHEPICFLAG_QUIET);
+                       sb_weapons[0][i] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inv_weapon%i",i), CACHEPICFLAG_QUIET);
        }
        else if (gamemode == GAME_ZYMOTIC)
        {
@@ -232,8 +233,8 @@ void sbar_start(void)
 
                for (i = 0;i < 10;i++)
                {
-                       sb_nums[0][i] = Draw_CachePic_Flags (va("gfx/num_%i",i), CACHEPICFLAG_QUIET);
-                       sb_nums[1][i] = Draw_CachePic_Flags (va("gfx/anum_%i",i), CACHEPICFLAG_QUIET);
+                       sb_nums[0][i] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/num_%i",i), CACHEPICFLAG_QUIET);
+                       sb_nums[1][i] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/anum_%i",i), CACHEPICFLAG_QUIET);
                }
 
                sb_nums[0][10] = Draw_CachePic_Flags ("gfx/num_minus", CACHEPICFLAG_QUIET);
@@ -260,13 +261,13 @@ void sbar_start(void)
 
                for (i = 0;i < 5;i++)
                {
-                       sb_weapons[2+i][0] = Draw_CachePic_Flags (va("gfx/inva%i_shotgun",i+1), CACHEPICFLAG_QUIET);
-                       sb_weapons[2+i][1] = Draw_CachePic_Flags (va("gfx/inva%i_sshotgun",i+1), CACHEPICFLAG_QUIET);
-                       sb_weapons[2+i][2] = Draw_CachePic_Flags (va("gfx/inva%i_nailgun",i+1), CACHEPICFLAG_QUIET);
-                       sb_weapons[2+i][3] = Draw_CachePic_Flags (va("gfx/inva%i_snailgun",i+1), CACHEPICFLAG_QUIET);
-                       sb_weapons[2+i][4] = Draw_CachePic_Flags (va("gfx/inva%i_rlaunch",i+1), CACHEPICFLAG_QUIET);
-                       sb_weapons[2+i][5] = Draw_CachePic_Flags (va("gfx/inva%i_srlaunch",i+1), CACHEPICFLAG_QUIET);
-                       sb_weapons[2+i][6] = Draw_CachePic_Flags (va("gfx/inva%i_lightng",i+1), CACHEPICFLAG_QUIET);
+                       sb_weapons[2+i][0] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_shotgun",i+1), CACHEPICFLAG_QUIET);
+                       sb_weapons[2+i][1] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_sshotgun",i+1), CACHEPICFLAG_QUIET);
+                       sb_weapons[2+i][2] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_nailgun",i+1), CACHEPICFLAG_QUIET);
+                       sb_weapons[2+i][3] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_snailgun",i+1), CACHEPICFLAG_QUIET);
+                       sb_weapons[2+i][4] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_rlaunch",i+1), CACHEPICFLAG_QUIET);
+                       sb_weapons[2+i][5] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_srlaunch",i+1), CACHEPICFLAG_QUIET);
+                       sb_weapons[2+i][6] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_lightng",i+1), CACHEPICFLAG_QUIET);
                }
 
                sb_ammo[0] = Draw_CachePic_Flags ("gfx/sb_shells", CACHEPICFLAG_QUIET);
@@ -327,11 +328,11 @@ void sbar_start(void)
 
                        for (i = 0;i < 5;i++)
                        {
-                               hsb_weapons[2+i][0] = Draw_CachePic_Flags (va("gfx/inva%i_laser",i+1), CACHEPICFLAG_QUIET);
-                               hsb_weapons[2+i][1] = Draw_CachePic_Flags (va("gfx/inva%i_mjolnir",i+1), CACHEPICFLAG_QUIET);
-                               hsb_weapons[2+i][2] = Draw_CachePic_Flags (va("gfx/inva%i_gren_prox",i+1), CACHEPICFLAG_QUIET);
-                               hsb_weapons[2+i][3] = Draw_CachePic_Flags (va("gfx/inva%i_prox_gren",i+1), CACHEPICFLAG_QUIET);
-                               hsb_weapons[2+i][4] = Draw_CachePic_Flags (va("gfx/inva%i_prox",i+1), CACHEPICFLAG_QUIET);
+                               hsb_weapons[2+i][0] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_laser",i+1), CACHEPICFLAG_QUIET);
+                               hsb_weapons[2+i][1] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_mjolnir",i+1), CACHEPICFLAG_QUIET);
+                               hsb_weapons[2+i][2] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_gren_prox",i+1), CACHEPICFLAG_QUIET);
+                               hsb_weapons[2+i][3] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_prox_gren",i+1), CACHEPICFLAG_QUIET);
+                               hsb_weapons[2+i][4] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_prox",i+1), CACHEPICFLAG_QUIET);
                        }
 
                        hsb_items[0] = Draw_CachePic_Flags ("gfx/sb_wsuit", CACHEPICFLAG_QUIET);
@@ -367,11 +368,11 @@ void sbar_start(void)
        sb_finale = Draw_CachePic_Flags ("gfx/finale", CACHEPICFLAG_QUIET);
 }
 
-void sbar_shutdown(void)
+static void sbar_shutdown(void)
 {
 }
 
-void sbar_newmap(void)
+static void sbar_newmap(void)
 {
 }
 
@@ -422,17 +423,17 @@ int sbar_x, sbar_y;
 Sbar_DrawPic
 =============
 */
-void Sbar_DrawStretchPic (int x, int y, cachepic_t *pic, float alpha, float overridewidth, float overrideheight)
+static void Sbar_DrawStretchPic (int x, int y, cachepic_t *pic, float alpha, float overridewidth, float overrideheight)
 {
        DrawQ_Pic (sbar_x + x, sbar_y + y, pic, overridewidth, overrideheight, 1, 1, 1, alpha, 0);
 }
 
-void Sbar_DrawPic (int x, int y, cachepic_t *pic)
+static void Sbar_DrawPic (int x, int y, cachepic_t *pic)
 {
        DrawQ_Pic (sbar_x + x, sbar_y + y, pic, 0, 0, 1, 1, 1, sbar_alpha_fg.value, 0);
 }
 
-void Sbar_DrawAlphaPic (int x, int y, cachepic_t *pic, float alpha)
+static void Sbar_DrawAlphaPic (int x, int y, cachepic_t *pic, float alpha)
 {
        DrawQ_Pic (sbar_x + x, sbar_y + y, pic, 0, 0, 1, 1, 1, alpha, 0);
 }
@@ -444,9 +445,10 @@ Sbar_DrawCharacter
 Draws one solid graphics character
 ================
 */
-void Sbar_DrawCharacter (int x, int y, int num)
+static void Sbar_DrawCharacter (int x, int y, int num)
 {
-       DrawQ_String (sbar_x + x + 4 , sbar_y + y, va("%c", num), 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0, NULL, true, FONT_SBAR);
+       char vabuf[1024];
+       DrawQ_String (sbar_x + x + 4 , sbar_y + y, va(vabuf, sizeof(vabuf), "%c", num), 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0, NULL, true, FONT_SBAR);
 }
 
 /*
@@ -454,7 +456,7 @@ void Sbar_DrawCharacter (int x, int y, int num)
 Sbar_DrawString
 ================
 */
-void Sbar_DrawString (int x, int y, char *str)
+static void Sbar_DrawString (int x, int y, char *str)
 {
        DrawQ_String (sbar_x + x, sbar_y + y, str, 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR);
 }
@@ -464,7 +466,7 @@ void Sbar_DrawString (int x, int y, char *str)
 Sbar_DrawNum
 =============
 */
-void Sbar_DrawNum (int x, int y, int num, int digits, int color)
+static void Sbar_DrawNum (int x, int y, int num, int digits, int color)
 {
        char str[32], *ptr;
        int l, frame;
@@ -496,7 +498,7 @@ Sbar_DrawXNum
 =============
 */
 
-void Sbar_DrawXNum (int x, int y, int num, int digits, int lettersize, float r, float g, float b, float a, int flags)
+static void Sbar_DrawXNum (int x, int y, int num, int digits, int lettersize, float r, float g, float b, float a, int flags)
 {
        char str[32], *ptr;
        int l, frame;
@@ -531,7 +533,7 @@ void Sbar_DrawXNum (int x, int y, int num, int digits, int lettersize, float r,
 //=============================================================================
 
 
-int Sbar_IsTeammatch(void)
+static int Sbar_IsTeammatch(void)
 {
        // currently only nexuiz uses the team score board
        return ((gamemode == GAME_NEXUIZ)
@@ -661,13 +663,14 @@ void Sbar_SortFrags (void)
 Sbar_SoloScoreboard
 ===============
 */
-void Sbar_SoloScoreboard (void)
+static void Sbar_SoloScoreboard (void)
 {
 #if 1
        char    str[80], timestr[40];
        int             max, timelen;
        int             minutes, seconds;
        double  t;
+       char vabuf[1024];
 
        t = (cl.intermission ? cl.completed_time : cl.time);
        minutes = (int)(t / 60);
@@ -675,14 +678,14 @@ void Sbar_SoloScoreboard (void)
 
        // monsters and secrets are now both on the top row
        if (cl.stats[STAT_TOTALMONSTERS])
-               Sbar_DrawString(8, 4, va("Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]));
+               Sbar_DrawString(8, 4, va(vabuf, sizeof(vabuf), "Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]));
        else if (cl.stats[STAT_MONSTERS]) // LA: Display something if monsters_killed is non-zero, but total_monsters is zero
-               Sbar_DrawString(8, 4, va("Monsters:%3i", cl.stats[STAT_MONSTERS]));
+               Sbar_DrawString(8, 4, va(vabuf, sizeof(vabuf), "Monsters:%3i", cl.stats[STAT_MONSTERS]));
 
        if (cl.stats[STAT_TOTALSECRETS])
-               Sbar_DrawString(8+22*8, 4, va("Secrets:%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]));
+               Sbar_DrawString(8+22*8, 4, va(vabuf, sizeof(vabuf), "Secrets:%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]));
        else if (cl.stats[STAT_SECRETS]) // LA: And similarly for secrets
-               Sbar_DrawString(8+22*8, 4, va("Secrets:%3i", cl.stats[STAT_SECRETS]));
+               Sbar_DrawString(8+22*8, 4, va(vabuf, sizeof(vabuf), "Secrets:%3i", cl.stats[STAT_SECRETS]));
 
        // format is like this: e1m1:The Sligpate Complex
        dpsnprintf(str, sizeof(str), "%s:%s", cl.worldbasename, cl.worldmessage);
@@ -742,7 +745,7 @@ void Sbar_SoloScoreboard (void)
 Sbar_DrawScoreboard
 ===============
 */
-void Sbar_DrawScoreboard (void)
+static void Sbar_DrawScoreboard (void)
 {
        Sbar_SoloScoreboard ();
        // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
@@ -756,6 +759,7 @@ void Sbar_DrawScoreboard (void)
 // AK to make DrawInventory smaller
 static void Sbar_DrawWeapon(int nr, float fade, int active)
 {
+       char vabuf[1024];
        if (sbar_hudselector.integer == 1)
        {
                // width = 300, height = 100
@@ -763,7 +767,7 @@ static void Sbar_DrawWeapon(int nr, float fade, int active)
 
                DrawQ_Pic((vid_conwidth.integer - w_width * 9) * 0.5 + w_width * nr, vid_conheight.integer - w_height, sb_weapons[0][nr], w_width, w_height, (active) ? 1 : 0.6, active ? 1 : 0.6, active ? 1 : 0.6, (active ? 1 : 0.6) * fade * sbar_alpha_fg.value, DRAWFLAG_NORMAL);
                // FIXME ??
-               DrawQ_String((vid_conwidth.integer - w_width * 9) * 0.5 + w_width * nr + w_space, vid_conheight.integer - w_height + w_space, va("%i",nr+1), 0, font_size, font_size, 1, 1, 0, sbar_alpha_fg.value, 0, NULL, true, FONT_DEFAULT);
+               DrawQ_String((vid_conwidth.integer - w_width * 9) * 0.5 + w_width * nr + w_space, vid_conheight.integer - w_height + w_space, va(vabuf, sizeof(vabuf), "%i",nr+1), 0, font_size, font_size, 1, 1, 0, sbar_alpha_fg.value, 0, NULL, true, FONT_DEFAULT);
        }
        else
        {
@@ -772,7 +776,7 @@ static void Sbar_DrawWeapon(int nr, float fade, int active)
                const float w_scale = 0.4;
 
                DrawQ_Pic(vid_conwidth.integer - (w_width + w_space) * w_scale, (w_height + w_space) * w_scale * nr + w_space, sb_weapons[0][nr], w_width * w_scale, w_height * w_scale, (active) ? 1 : 0.6, active ? 1 : 0.6, active ? 1 : 1, fade * sbar_alpha_fg.value, DRAWFLAG_NORMAL);
-               //DrawQ_String(vid_conwidth.integer - (w_space + font_size ), (w_height + w_space) * w_scale * nr + w_space, va("%i",nr+1), 0, font_size, font_size, 1, 0, 0, fade, 0, NULL, true, FONT_DEFAULT);
+               //DrawQ_String(vid_conwidth.integer - (w_space + font_size ), (w_height + w_space) * w_scale * nr + w_space, va(vabuf, sizeof(vabuf), "%i",nr+1), 0, font_size, font_size, 1, 0, 0, fade, 0, NULL, true, FONT_DEFAULT);
        }
 }
 
@@ -781,7 +785,7 @@ static void Sbar_DrawWeapon(int nr, float fade, int active)
 Sbar_DrawInventory
 ===============
 */
-void Sbar_DrawInventory (void)
+static void Sbar_DrawInventory (void)
 {
        int i;
        char num[6];
@@ -932,7 +936,7 @@ void Sbar_DrawInventory (void)
 Sbar_DrawFrags
 ===============
 */
-void Sbar_DrawFrags (void)
+static void Sbar_DrawFrags (void)
 {
        int i, k, l, x, f;
        char num[12];
@@ -981,7 +985,7 @@ void Sbar_DrawFrags (void)
 Sbar_DrawFace
 ===============
 */
-void Sbar_DrawFace (void)
+static void Sbar_DrawFace (void)
 {
        int f;
 
@@ -1306,7 +1310,7 @@ void Sbar_ShowFPS(void)
        }
 }
 
-void Sbar_DrawGauge(float x, float y, cachepic_t *pic, float width, float height, float rangey, float rangeheight, float c1, float c2, float c1r, float c1g, float c1b, float c1a, float c2r, float c2g, float c2b, float c2a, float c3r, float c3g, float c3b, float c3a, int drawflags)
+static void Sbar_DrawGauge(float x, float y, cachepic_t *pic, float width, float height, float rangey, float rangeheight, float c1, float c2, float c1r, float c1g, float c1b, float c1a, float c2r, float c2g, float c2b, float c2a, float c3r, float c3g, float c3b, float c3a, int drawflags)
 {
        float r[5];
        c2 = bound(0, c2, 1);
@@ -1337,6 +1341,7 @@ void Sbar_Score (int margin);
 void Sbar_Draw (void)
 {
        cachepic_t *pic;
+       char vabuf[1024];
 
        if(cl.csqc_vidvars.drawenginesbar)      //[515]: csqc drawsbar
        {
@@ -1781,12 +1786,12 @@ void Sbar_Draw (void)
 
        if (cl.csqc_vidvars.drawcrosshair && crosshair.integer >= 1 && !cl.intermission && !r_letterbox.value)
        {
-               pic = Draw_CachePic (va("gfx/crosshair%i", crosshair.integer));
+               pic = Draw_CachePic (va(vabuf, sizeof(vabuf), "gfx/crosshair%i", crosshair.integer));
                DrawQ_Pic((vid_conwidth.integer - pic->width * crosshair_size.value) * 0.5f, (vid_conheight.integer - pic->height * crosshair_size.value) * 0.5f, pic, pic->width * crosshair_size.value, pic->height * crosshair_size.value, crosshair_color_red.value, crosshair_color_green.value, crosshair_color_blue.value, crosshair_color_alpha.value, 0);
        }
 
        if (cl_prydoncursor.integer > 0)
-               DrawQ_Pic((cl.cmd.cursor_screen[0] + 1) * 0.5 * vid_conwidth.integer, (cl.cmd.cursor_screen[1] + 1) * 0.5 * vid_conheight.integer, Draw_CachePic (va("gfx/prydoncursor%03i", cl_prydoncursor.integer)), 0, 0, 1, 1, 1, 1, 0);
+               DrawQ_Pic((cl.cmd.cursor_screen[0] + 1) * 0.5 * vid_conwidth.integer, (cl.cmd.cursor_screen[1] + 1) * 0.5 * vid_conheight.integer, Draw_CachePic (va(vabuf, sizeof(vabuf), "gfx/prydoncursor%03i", cl_prydoncursor.integer)), 0, 0, 1, 1, 1, 1, 0);
 }
 
 //=============================================================================
@@ -1797,11 +1802,12 @@ Sbar_DeathmatchOverlay
 
 ==================
 */
-float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
+static float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
 {
        int minutes;
        qboolean myself = false;
        unsigned char *c;
+       char vabuf[1024];
        minutes = (int)((cl.intermission ? cl.completed_time - s->qw_entertime : cl.time - s->qw_entertime) / 60.0);
 
        if((s - cl.scores) == cl.playerentity - 1)
@@ -1815,9 +1821,9 @@ float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
                if (s->qw_spectator)
                {
                        if (s->qw_ping || s->qw_packetloss)
-                               DrawQ_String(x, y, va("%4i %3i %4i spectator  %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), minutes, myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
+                               DrawQ_String(x, y, va(vabuf, sizeof(vabuf), "%4i %3i %4i spectator  %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), minutes, myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
                        else
-                               DrawQ_String(x, y, va("         %4i spectator  %c%s", minutes, myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
+                               DrawQ_String(x, y, va(vabuf, sizeof(vabuf), "         %4i spectator  %c%s", minutes, myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
                }
                else
                {
@@ -1832,11 +1838,11 @@ float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
                        c = palette_rgb_shirtscoreboard[s->colors & 0xf];
                        DrawQ_Fill(x + 14*8*FONT_SBAR->maxwidth, y+4, 40*FONT_SBAR->maxwidth, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), sbar_alpha_fg.value, 0);
                        // print the text
-                       //DrawQ_String(x, y, va("%c%4i %s", myself ? 13 : ' ', (int) s->frags, s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, true, FONT_DEFAULT);
+                       //DrawQ_String(x, y, va(vabuf, sizeof(vabuf), "%c%4i %s", myself ? 13 : ' ', (int) s->frags, s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, true, FONT_DEFAULT);
                        if (s->qw_ping || s->qw_packetloss)
-                               DrawQ_String(x, y, va("%4i %3i %4i %5i %-4s %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), minutes,(int) s->frags, cl.qw_teamplay ? s->qw_team : "", myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
+                               DrawQ_String(x, y, va(vabuf, sizeof(vabuf), "%4i %3i %4i %5i %-4s %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), minutes,(int) s->frags, cl.qw_teamplay ? s->qw_team : "", myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
                        else
-                               DrawQ_String(x, y, va("         %4i %5i %-4s %c%s", minutes,(int) s->frags, cl.qw_teamplay ? s->qw_team : "", myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
+                               DrawQ_String(x, y, va(vabuf, sizeof(vabuf), "         %4i %5i %-4s %c%s", minutes,(int) s->frags, cl.qw_teamplay ? s->qw_team : "", myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
                }
        }
        else
@@ -1844,9 +1850,9 @@ float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
                if (s->qw_spectator)
                {
                        if (s->qw_ping || s->qw_packetloss)
-                               DrawQ_String(x, y, va("%4i %3i spect %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
+                               DrawQ_String(x, y, va(vabuf, sizeof(vabuf), "%4i %3i spect %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
                        else
-                               DrawQ_String(x, y, va("         spect %c%s", myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
+                               DrawQ_String(x, y, va(vabuf, sizeof(vabuf), "         spect %c%s", myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
                }
                else
                {
@@ -1856,11 +1862,11 @@ float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
                        c = palette_rgb_shirtscoreboard[s->colors & 0xf];
                        DrawQ_Fill(x + 9*8*FONT_SBAR->maxwidth, y+4, 40*FONT_SBAR->maxwidth, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), sbar_alpha_fg.value, 0);
                        // print the text
-                       //DrawQ_String(x, y, va("%c%4i %s", myself ? 13 : ' ', (int) s->frags, s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, true, FONT_DEFAULT);
+                       //DrawQ_String(x, y, va(vabuf, sizeof(vabuf), "%c%4i %s", myself ? 13 : ' ', (int) s->frags, s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, true, FONT_DEFAULT);
                        if (s->qw_ping || s->qw_packetloss)
-                               DrawQ_String(x, y, va("%4i %3i %5i %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), (int) s->frags, myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
+                               DrawQ_String(x, y, va(vabuf, sizeof(vabuf), "%4i %3i %5i %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), (int) s->frags, myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
                        else
-                               DrawQ_String(x, y, va("         %5i %c%s", (int) s->frags, myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
+                               DrawQ_String(x, y, va(vabuf, sizeof(vabuf), "         %5i %c%s", (int) s->frags, myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
                }
        }
        return 8;
@@ -1869,6 +1875,7 @@ float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
 void Sbar_DeathmatchOverlay (void)
 {
        int i, y, xmin, xmax, ymin, ymax;
+       char vabuf[1024];
 
        // request new ping times every two second
        if (cl.last_ping_request < realtime - 2 && cls.netcon)
@@ -1926,11 +1933,11 @@ void Sbar_DeathmatchOverlay (void)
        y = 40;
        if (cls.protocol == PROTOCOL_QUAKEWORLD)
        {
-               DrawQ_String(xmin, y, va("ping pl%% time frags team  name"), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
+               DrawQ_String(xmin, y, va(vabuf, sizeof(vabuf), "ping pl%% time frags team  name"), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
        }
        else
        {
-               DrawQ_String(xmin, y, va("ping pl%% frags  name"), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
+               DrawQ_String(xmin, y, va(vabuf, sizeof(vabuf), "ping pl%% frags  name"), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
        }
        y += 8;
 
@@ -2030,7 +2037,7 @@ void Sbar_MiniDeathmatchOverlay (int x, int y)
        }
 }
 
-int Sbar_TeamColorCompare(const void *t1_, const void *t2_)
+static int Sbar_TeamColorCompare(const void *t1_, const void *t2_)
 {
        static int const sortorder[16] =
        {
diff --git a/sbar.h b/sbar.h
index 4b566b6df162ffd947a21657e04ed1e3af22a394..0739756abb16f3a528fe10226bba7bf3df49f9fc 100644 (file)
--- a/sbar.h
+++ b/sbar.h
@@ -32,5 +32,8 @@ void Sbar_Init (void);
 /// called every frame by screen
 void Sbar_Draw (void);
 
+int Sbar_GetSortedPlayerIndex (int index);
+void Sbar_SortFrags (void);
+
 #endif
 
index d62a736683683a5591059b0a0b72331d1812c1a2..64153e565c4adeba6e163acaa7d599a10bef0284 100644 (file)
--- a/server.h
+++ b/server.h
@@ -509,7 +509,7 @@ void SV_StartPointSound (vec3_t origin, const char *sample, int volume, float at
 void SV_ConnectClient (int clientnum, netconn_t *netconnection);
 void SV_DropClient (qboolean crash);
 
-void SV_SendClientMessages (void);
+void SV_SendClientMessages(void);
 
 void SV_ReadClientMessage(void);
 
@@ -572,7 +572,7 @@ int SV_PointSuperContents(const vec3_t point);
 void SV_FlushBroadcastMessages(void);
 void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats);
 
-void SV_MoveToGoal (void);
+void VM_SV_MoveToGoal(prvm_prog_t *prog);
 
 void SV_ApplyClientMove (void);
 void SV_SaveSpawnparms (void);
@@ -582,18 +582,20 @@ void SV_CheckVelocity (prvm_edict_t *ent);
 
 void SV_SetupVM(void);
 
-void SV_VM_Begin(void);
-void SV_VM_End(void);
+const char *Host_TimingReport(char *buf, size_t buflen); ///< for output in Host_Status_f
 
-const char *Host_TimingReport(void); ///< for output in Host_Status_f
-
-int SV_GetPitchSign(prvm_edict_t *ent);
-void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix);
+int SV_GetPitchSign(prvm_prog_t *prog, prvm_edict_t *ent);
+void SV_GetEntityMatrix(prvm_prog_t *prog, prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix);
 
 void SV_StartThread(void);
 void SV_StopThread(void);
 void SV_LockThreadMutex(void);
 void SV_UnlockThreadMutex(void);
 
+void VM_CustomStats_Clear(void);
+void VM_SV_UpdateCustomStats(client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats);
+void Host_Savegame_to(prvm_prog_t *prog, const char *name);
+void SV_SendServerinfo(client_t *client);
+
 #endif
 
index e76bc8047e78207f5d91e01c787b072fa23fc1a1..09a132926145c3e7734188b16be3b3ee710253aa 100644 (file)
@@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "snd_modplug.h"
 #include "csprogs.h"
 #include "cl_collision.h"
+#include "cdaudio.h"
 
 
 #define SND_MIN_SPEED 8000
@@ -344,7 +345,7 @@ static void S_SoundList_f (void)
 }
 
 
-void S_SoundInfo_f(void)
+static void S_SoundInfo_f(void)
 {
        if (snd_renderbuffer == NULL)
        {
@@ -776,7 +777,7 @@ void S_Shutdown(void)
        sound_spatialized = false;
 }
 
-void S_Restart_f(void)
+static void S_Restart_f(void)
 {
        // NOTE: we can't free all sounds if we are running a map (this frees sfx_t that are still referenced by precaches)
        // So, refuse to do this if we are connected.
@@ -1220,7 +1221,7 @@ SND_PickChannel
 Picks a channel based on priorities, empty slots, number of channels
 =================
 */
-channel_t *SND_PickChannel(int entnum, int entchannel)
+static channel_t *SND_PickChannel(int entnum, int entchannel)
 {
        int ch_idx;
        int first_to_die;
@@ -1293,13 +1294,14 @@ Spatializes a channel
 =================
 */
 extern cvar_t cl_gameplayfix_soundsmovewithentities;
-void SND_Spatialize_WithSfx(channel_t *ch, qboolean isstatic, sfx_t *sfx)
+static void SND_Spatialize_WithSfx(channel_t *ch, qboolean isstatic, sfx_t *sfx)
 {
        int i;
        double f;
        float angle_side, angle_front, angle_factor, mixspeed;
        vec_t dist, mastervol, intensity;
        vec3_t source_vec;
+       char vabuf[1024];
 
        // update sound origin if we know about the entity
        if (ch->entnum > 0 && cls.state == ca_connected && cl_gameplayfix_soundsmovewithentities.integer)
@@ -1406,7 +1408,7 @@ void SND_Spatialize_WithSfx(channel_t *ch, qboolean isstatic, sfx_t *sfx)
                        case 5:  mastervol *= snd_channel5volume.value; break;
                        case 6:  mastervol *= snd_channel6volume.value; break;
                        case 7:  mastervol *= snd_channel7volume.value; break;
-                       default: mastervol *= Cvar_VariableValueOr(va("snd_channel%dvolume", CHAN_ENGINE2CVAR(ch->entchannel)), 1.0); break;
+                       default: mastervol *= Cvar_VariableValueOr(va(vabuf, sizeof(vabuf), "snd_channel%dvolume", CHAN_ENGINE2CVAR(ch->entchannel)), 1.0); break;
                }
        }
 
@@ -1597,7 +1599,7 @@ void SND_Spatialize_WithSfx(channel_t *ch, qboolean isstatic, sfx_t *sfx)
                                ch->volume[i] = 0;
        }
 }
-void SND_Spatialize(channel_t *ch, qboolean isstatic)
+static void SND_Spatialize(channel_t *ch, qboolean isstatic)
 {
        sfx_t *sfx = ch->sfx;
        SND_Spatialize_WithSfx(ch, isstatic, sfx);
@@ -1608,7 +1610,7 @@ void SND_Spatialize(channel_t *ch, qboolean isstatic)
 // Start a sound effect
 // =======================================================================
 
-void S_PlaySfxOnChannel (sfx_t *sfx, channel_t *target_chan, unsigned int flags, vec3_t origin, float fvol, float attenuation, qboolean isstatic, int entnum, int entchannel, int startpos, float fspeed)
+static void S_PlaySfxOnChannel (sfx_t *sfx, channel_t *target_chan, unsigned int flags, vec3_t origin, float fvol, float attenuation, qboolean isstatic, int entnum, int entchannel, int startpos, float fspeed)
 {
        if (!sfx)
        {
@@ -1801,7 +1803,6 @@ void S_StopSound(int entnum, int entchannel)
                }
 }
 
-extern void CDAudio_Stop(void);
 void S_StopAllSounds (void)
 {
        unsigned int i;
@@ -1923,7 +1924,7 @@ void S_StaticSound (sfx_t *sfx, vec3_t origin, float fvol, float attenuation)
 S_UpdateAmbientSounds
 ===================
 */
-void S_UpdateAmbientSounds (void)
+static void S_UpdateAmbientSounds (void)
 {
        int                     i;
        float           vol;
index cf992904c96c672a997849601df81760ae7c00c4..4f3310bfcf1a83b3ef3eaad472b70fa7e850ceae 100644 (file)
--- a/snd_mix.c
+++ b/snd_mix.c
@@ -28,7 +28,6 @@ static portable_sampleframe_t paintbuffer_unswapped[PAINTBUFFER_SIZE];
 
 extern speakerlayout_t snd_speakerlayout; // for querying the listeners
 
-extern void SCR_CaptureVideo_SoundFrame(const portable_sampleframe_t *paintbuffer, size_t length);
 static void S_CaptureAVISound(const portable_sampleframe_t *paintbuffer, size_t length)
 {
        size_t i;
diff --git a/sound.h b/sound.h
index cacb23ae5e878818c03319727cbe6995e765cad9..0162c37c72923a83a3494774e7fae5d55b6f54b6 100644 (file)
--- a/sound.h
+++ b/sound.h
@@ -72,6 +72,7 @@ float S_SoundLength(const char *name);
 void S_ClearUsed (void);
 void S_PurgeUnused (void);
 qboolean S_IsSoundPrecached (const sfx_t *sfx);
+sfx_t *S_FindName(const char *name);
 
 // for sound() builtins
 #define CHANFLAG_RELIABLE 1
index f6f00d33102ec3c30968a30ff05e0c9a3e446b5a..cc94a2c05aa5d1e6d41b04031651060d41bdc77e 100644 (file)
--- a/sv_demo.c
+++ b/sv_demo.c
@@ -5,6 +5,7 @@ extern cvar_t sv_autodemo_perclient_discardable;
 
 void SV_StartDemoRecording(client_t *client, const char *filename, int forcetrack)
 {
+       prvm_prog_t *prog = SVVM_prog;
        char name[MAX_QPATH];
 
        if(client->sv_demo_file != NULL)
@@ -30,6 +31,7 @@ void SV_StartDemoRecording(client_t *client, const char *filename, int forcetrac
 
 void SV_WriteDemoMessage(client_t *client, sizebuf_t *sendbuffer, qboolean clienttoserver)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int len, i;
        float f;
        int temp;
@@ -52,6 +54,7 @@ void SV_WriteDemoMessage(client_t *client, sizebuf_t *sendbuffer, qboolean clien
 
 void SV_StopDemoRecording(client_t *client)
 {
+       prvm_prog_t *prog = SVVM_prog;
        sizebuf_t buf;
        unsigned char bufdata[64];
 
index 406bde3e024ac075698ea1a8464e8be91d29be2c..26d856950a1e7ac76e50fe26b4f69b3a5ebd3bd9 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -31,9 +31,6 @@ static void SV_Download_f(void);
 static void SV_VM_Setup(void);
 extern cvar_t net_connecttimeout;
 
-void VM_CustomStats_Clear (void);
-void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats);
-
 cvar_t sv_worldmessage = {CVAR_READONLY, "sv_worldmessage", "", "title of current level"};
 cvar_t sv_worldname = {CVAR_READONLY, "sv_worldname", "", "name of current worldmodel"};
 cvar_t sv_worldnamenoextension = {CVAR_READONLY, "sv_worldnamenoextension", "", "name of current worldmodel without extension"};
@@ -416,7 +413,7 @@ prvm_required_field_t sv_reqglobals[] =
 
 //============================================================================
 
-void SV_AreaStats_f(void)
+static void SV_AreaStats_f(void)
 {
        World_PrintAreaStats(&sv.world, "server");
 }
@@ -614,12 +611,13 @@ void SV_Init (void)
 
 static void SV_SaveEntFile_f(void)
 {
+       char vabuf[1024];
        if (!sv.active || !sv.worldmodel)
        {
                Con_Print("Not running a server\n");
                return;
        }
-       FS_WriteFile(va("%s.ent", sv.worldnamenoextension), sv.worldmodel->brush.entities, (fs_offset_t)strlen(sv.worldmodel->brush.entities));
+       FS_WriteFile(va(vabuf, sizeof(vabuf), "%s.ent", sv.worldnamenoextension), sv.worldmodel->brush.entities, (fs_offset_t)strlen(sv.worldmodel->brush.entities));
 }
 
 
@@ -710,6 +708,7 @@ Larger attenuations will drop off.  (max 4 attenuation)
 */
 void SV_StartSound (prvm_edict_t *entity, int channel, const char *sample, int volume, float attenuation, qboolean reliable, float speed)
 {
+       prvm_prog_t *prog = SVVM_prog;
        sizebuf_t *dest;
        int sound_num, field_mask, i, ent, speed4000;
 
@@ -872,8 +871,10 @@ This will be sent on the initial connection and upon each server load.
 */
 void SV_SendServerinfo (client_t *client)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i;
        char message[128];
+       char vabuf[1024];
 
        // we know that this client has a netconnection and thus is not a bot
 
@@ -952,11 +953,11 @@ void SV_SendServerinfo (client_t *client)
        {
                Con_DPrintf("sending csqc info to client (\"%s\" with size %i and crc %i)\n", sv.csqc_progname, sv.csqc_progsize, sv.csqc_progcrc);
                MSG_WriteByte (&client->netconnection->message, svc_stufftext);
-               MSG_WriteString (&client->netconnection->message, va("csqc_progname %s\n", sv.csqc_progname));
+               MSG_WriteString (&client->netconnection->message, va(vabuf, sizeof(vabuf), "csqc_progname %s\n", sv.csqc_progname));
                MSG_WriteByte (&client->netconnection->message, svc_stufftext);
-               MSG_WriteString (&client->netconnection->message, va("csqc_progsize %i\n", sv.csqc_progsize));
+               MSG_WriteString (&client->netconnection->message, va(vabuf, sizeof(vabuf), "csqc_progsize %i\n", sv.csqc_progsize));
                MSG_WriteByte (&client->netconnection->message, svc_stufftext);
-               MSG_WriteString (&client->netconnection->message, va("csqc_progcrc %i\n", sv.csqc_progcrc));
+               MSG_WriteString (&client->netconnection->message, va(vabuf, sizeof(vabuf), "csqc_progcrc %i\n", sv.csqc_progcrc));
 
                if(client->sv_demo_file != NULL)
                {
@@ -972,10 +973,10 @@ void SV_SendServerinfo (client_t *client)
                }
 
                //[515]: init stufftext string (it is sent before svc_serverinfo)
-               if (PRVM_GetString(PRVM_serverglobalstring(SV_InitCmd)))
+               if (PRVM_GetString(prog, PRVM_serverglobalstring(SV_InitCmd)))
                {
                        MSG_WriteByte (&client->netconnection->message, svc_stufftext);
-                       MSG_WriteString (&client->netconnection->message, va("%s\n", PRVM_GetString(PRVM_serverglobalstring(SV_InitCmd))));
+                       MSG_WriteString (&client->netconnection->message, va(vabuf, sizeof(vabuf), "%s\n", PRVM_GetString(prog, PRVM_serverglobalstring(SV_InitCmd))));
                }
        }
 
@@ -1005,7 +1006,7 @@ void SV_SendServerinfo (client_t *client)
        else
                MSG_WriteByte (&client->netconnection->message, GAME_COOP);
 
-       MSG_WriteString (&client->netconnection->message,PRVM_GetString(PRVM_serveredictstring(prog->edicts, message)));
+       MSG_WriteString (&client->netconnection->message,PRVM_GetString(prog, PRVM_serveredictstring(prog->edicts, message)));
 
        for (i = 1;i < MAX_MODELS && sv.model_precache[i][0];i++)
                MSG_WriteString (&client->netconnection->message, sv.model_precache[i]);
@@ -1058,6 +1059,7 @@ once for a player each game, not once for each level change.
 */
 void SV_ConnectClient (int clientnum, netconn_t *netconnection)
 {
+       prvm_prog_t *prog = SVVM_prog;
        client_t                *client;
        int                             i;
 
@@ -1110,13 +1112,14 @@ void SV_ConnectClient (int clientnum, netconn_t *netconnection)
        {
                // call the progs to get default spawn parms for the new client
                // set self to world to intentionally cause errors with broken SetNewParms code in some mods
+               PRVM_serverglobalfloat(time) = sv.time;
                PRVM_serverglobaledict(self) = 0;
-               PRVM_ExecuteProgram (PRVM_serverfunction(SetNewParms), "QC function SetNewParms is missing");
+               prog->ExecuteProgram(prog, PRVM_serverfunction(SetNewParms), "QC function SetNewParms is missing");
                for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
                        client->spawn_parms[i] = (&PRVM_serverglobalfloat(parm1))[i];
 
                // set up the entity for this client (including .colormap, .team, etc)
-               PRVM_ED_ClearEdict(client->edict);
+               PRVM_ED_ClearEdict(prog, client->edict);
        }
 
        // don't call SendServerinfo for a fresh botclient because its fields have
@@ -1149,6 +1152,7 @@ crosses a waterline.
 
 static qboolean SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *cs, int enumber)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i;
        unsigned int sendflags;
        unsigned int version;
@@ -1179,7 +1183,7 @@ static qboolean SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *c
        // LordHavoc: this could kill tags attached to an invisible entity, I
        // just hope we never have to support that case
        i = (int)PRVM_serveredictfloat(ent, modelindex);
-       modelindex = (i >= 1 && i < MAX_MODELS && PRVM_serveredictstring(ent, model) && *PRVM_GetString(PRVM_serveredictstring(ent, model)) && sv.models[i]) ? i : 0;
+       modelindex = (i >= 1 && i < MAX_MODELS && PRVM_serveredictstring(ent, model) && *PRVM_GetString(prog, PRVM_serveredictstring(ent, model)) && sv.models[i]) ? i : 0;
 
        flags = 0;
        i = (int)(PRVM_serveredictfloat(ent, glow_size) * 0.25f);
@@ -1453,8 +1457,9 @@ static qboolean SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *c
        return true;
 }
 
-void SV_PrepareEntitiesForSending(void)
+static void SV_PrepareEntitiesForSending(void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int e;
        prvm_edict_t *ent;
        // send all entities that touch the pvs
@@ -1475,6 +1480,7 @@ void SV_PrepareEntitiesForSending(void)
 
 qboolean SV_CanSeeBox(int numtraces, vec_t enlarge, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs)
 {
+       prvm_prog_t *prog = SVVM_prog;
        float pitchsign;
        float alpha;
        float starttransformed[3], endtransformed[3];
@@ -1564,7 +1570,7 @@ qboolean SV_CanSeeBox(int numtraces, vec_t enlarge, vec3_t eye, vec3_t entboxmin
                        if(model && model->brush.TraceLineOfSight)
                        {
                                // get the entity matrix
-                               pitchsign = SV_GetPitchSign(touch);
+                               pitchsign = SV_GetPitchSign(prog, touch);
                                Matrix4x4_CreateFromQuakeEntity(&matrix, PRVM_serveredictvector(touch, origin)[0], PRVM_serveredictvector(touch, origin)[1], PRVM_serveredictvector(touch, origin)[2], pitchsign * PRVM_serveredictvector(touch, angles)[0], PRVM_serveredictvector(touch, angles)[1], PRVM_serveredictvector(touch, angles)[2], 1);
                                Matrix4x4_Invert_Simple(&imatrix, &matrix);
                                // see if the ray hits this entity
@@ -1588,8 +1594,9 @@ qboolean SV_CanSeeBox(int numtraces, vec_t enlarge, vec3_t eye, vec3_t entboxmin
        return false;
 }
 
-void SV_MarkWriteEntityStateToClient(entity_state_t *s)
+static void SV_MarkWriteEntityStateToClient(entity_state_t *s)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int isbmodel;
        dp_model_t *model;
        prvm_edict_t *ed;
@@ -1600,9 +1607,10 @@ void SV_MarkWriteEntityStateToClient(entity_state_t *s)
 
        if (s->customizeentityforclient)
        {
+               PRVM_serverglobalfloat(time) = sv.time;
                PRVM_serverglobaledict(self) = s->number;
                PRVM_serverglobaledict(other) = sv.writeentitiestoclient_cliententitynumber;
-               PRVM_ExecuteProgram(s->customizeentityforclient, "customizeentityforclient: NULL function");
+               prog->ExecuteProgram(prog, s->customizeentityforclient, "customizeentityforclient: NULL function");
                if(!PRVM_G_FLOAT(OFS_RETURN) || !SV_PrepareEntityForSending(PRVM_EDICT_NUM(s->number), s, s->number))
                        return;
        }
@@ -1716,8 +1724,9 @@ void SV_MarkWriteEntityStateToClient(entity_state_t *s)
 
 #if MAX_LEVELNETWORKEYES > 0
 #define MAX_EYE_RECURSION 1 // increase if recursion gets supported by portals
-void SV_AddCameraEyes(void)
+static void SV_AddCameraEyes(void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int e, i, j, k;
        prvm_edict_t *ed;
        static int cameras[MAX_LEVELNETWORKEYES];
@@ -1736,12 +1745,13 @@ void SV_AddCameraEyes(void)
                {
                        if(PRVM_serveredictfunction(ed, camera_transform))
                        {
+                               PRVM_serverglobalfloat(time) = sv.time;
                                PRVM_serverglobaledict(self) = e;
                                PRVM_serverglobaledict(other) = sv.writeentitiestoclient_cliententitynumber;
                                VectorCopy(sv.writeentitiestoclient_eyes[0], PRVM_serverglobalvector(trace_endpos));
                                VectorCopy(sv.writeentitiestoclient_eyes[0], PRVM_G_VECTOR(OFS_PARM0));
                                VectorClear(PRVM_G_VECTOR(OFS_PARM1));
-                               PRVM_ExecuteProgram(PRVM_serveredictfunction(ed, camera_transform), "QC function e.camera_transform is missing");
+                               prog->ExecuteProgram(prog, PRVM_serveredictfunction(ed, camera_transform), "QC function e.camera_transform is missing");
                                if(!VectorCompare(PRVM_serverglobalvector(trace_endpos), sv.writeentitiestoclient_eyes[0]))
                                {
                                        VectorCopy(PRVM_serverglobalvector(trace_endpos), camera_origins[n_cameras]);
@@ -1788,8 +1798,9 @@ void SV_AddCameraEyes(void)
 }
 #endif
 
-void SV_WriteEntitiesToClient(client_t *client, prvm_edict_t *clent, sizebuf_t *msg, int maxsize)
+static void SV_WriteEntitiesToClient(client_t *client, prvm_edict_t *clent, sizebuf_t *msg, int maxsize)
 {
+       prvm_prog_t *prog = SVVM_prog;
        qboolean need_empty = false;
        int i, numsendstates, numcsqcsendstates;
        entity_state_t *s;
@@ -1918,6 +1929,7 @@ SV_CleanupEnts
 */
 static void SV_CleanupEnts (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int             e;
        prvm_edict_t    *ent;
 
@@ -1934,6 +1946,7 @@ SV_WriteClientdataToMessage
 */
 void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int             bits;
        int             i;
        prvm_edict_t    *other;
@@ -1999,7 +2012,7 @@ void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t
 
        // cache weapon model name and index in client struct to save time
        // (this search can be almost 1% of cpu time!)
-       s = PRVM_GetString(PRVM_serveredictstring(ent, weaponmodel));
+       s = PRVM_GetString(prog, PRVM_serveredictstring(ent, weaponmodel));
        if (strcmp(s, client->weaponmodel))
        {
                strlcpy(client->weaponmodel, s, sizeof(client->weaponmodel));
@@ -2356,7 +2369,7 @@ static void SV_SendClientDatagram (client_t *client)
                // add the client specific data to the datagram
                SV_WriteClientdataToMessage (client, client->edict, &msg, stats);
                // now update the stats[] array using any registered custom fields
-               VM_SV_UpdateCustomStats (client, client->edict, &msg, stats);
+               VM_SV_UpdateCustomStats(client, client->edict, &msg, stats);
                // set host_client->statsdeltabits
                Protocol_UpdateClientStats (stats);
 
@@ -2419,6 +2432,7 @@ SV_UpdateToReliableMessages
 */
 static void SV_UpdateToReliableMessages (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i, j;
        client_t *client;
        const char *name;
@@ -2433,12 +2447,12 @@ static void SV_UpdateToReliableMessages (void)
                host_client->edict = PRVM_EDICT_NUM(i+1);
 
                // DP_SV_CLIENTNAME
-               name = PRVM_GetString(PRVM_serveredictstring(host_client->edict, netname));
+               name = PRVM_GetString(prog, PRVM_serveredictstring(host_client->edict, netname));
                if (name == NULL)
                        name = "";
                // always point the string back at host_client->name to keep it safe
                strlcpy (host_client->name, name, sizeof (host_client->name));
-               PRVM_serveredictstring(host_client->edict, netname) = PRVM_SetEngineString(host_client->name);
+               PRVM_serveredictstring(host_client->edict, netname) = PRVM_SetEngineString(prog, host_client->name);
                if (strcmp(host_client->old_name, host_client->name))
                {
                        if (host_client->spawned)
@@ -2463,20 +2477,20 @@ static void SV_UpdateToReliableMessages (void)
                }
 
                // NEXUIZ_PLAYERMODEL
-               model = PRVM_GetString(PRVM_serveredictstring(host_client->edict, playermodel));
+               model = PRVM_GetString(prog, PRVM_serveredictstring(host_client->edict, playermodel));
                if (model == NULL)
                        model = "";
                // always point the string back at host_client->name to keep it safe
                strlcpy (host_client->playermodel, model, sizeof (host_client->playermodel));
-               PRVM_serveredictstring(host_client->edict, playermodel) = PRVM_SetEngineString(host_client->playermodel);
+               PRVM_serveredictstring(host_client->edict, playermodel) = PRVM_SetEngineString(prog, host_client->playermodel);
 
                // NEXUIZ_PLAYERSKIN
-               skin = PRVM_GetString(PRVM_serveredictstring(host_client->edict, playerskin));
+               skin = PRVM_GetString(prog, PRVM_serveredictstring(host_client->edict, playerskin));
                if (skin == NULL)
                        skin = "";
                // always point the string back at host_client->name to keep it safe
                strlcpy (host_client->playerskin, skin, sizeof (host_client->playerskin));
-               PRVM_serveredictstring(host_client->edict, playerskin) = PRVM_SetEngineString(host_client->playerskin);
+               PRVM_serveredictstring(host_client->edict, playerskin) = PRVM_SetEngineString(prog, host_client->playerskin);
 
                // TODO: add an extension name for this [1/17/2008 Black]
                clientcamera = PRVM_serveredictedict(host_client->edict, clientcamera);
@@ -2522,7 +2536,7 @@ static void SV_UpdateToReliableMessages (void)
 SV_SendClientMessages
 =======================
 */
-void SV_SendClientMessages (void)
+void SV_SendClientMessages(void)
 {
        int i, prepared = false;
 
@@ -2554,7 +2568,7 @@ void SV_SendClientMessages (void)
                        // only prepare entities once per frame
                        SV_PrepareEntitiesForSending();
                }
-               SV_SendClientDatagram (host_client);
+               SV_SendClientDatagram(host_client);
        }
 
 // clear muzzle flashes
@@ -3015,6 +3029,7 @@ dp_model_t *SV_GetModelByIndex(int modelindex)
 
 dp_model_t *SV_GetModelFromEdict(prvm_edict_t *ed)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int modelindex;
        if (!ed || ed->priv.server->free)
                return NULL;
@@ -3030,6 +3045,7 @@ SV_CreateBaseline
 */
 static void SV_CreateBaseline (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i, entnum, large;
        prvm_edict_t *svent;
 
@@ -3111,7 +3127,7 @@ Load csprogs.dat and comperss it so it doesn't need to be
 reloaded on request.
 ================
 */
-void SV_Prepare_CSQC(void)
+static void SV_Prepare_CSQC(void)
 {
        fs_offset_t progsize;
 
@@ -3162,6 +3178,7 @@ transition to another level
 */
 void SV_SaveSpawnparms (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int             i, j;
 
        svs.serverflags = (int)PRVM_serverglobalfloat(serverflags);
@@ -3172,8 +3189,9 @@ void SV_SaveSpawnparms (void)
                        continue;
 
        // call the progs to get default spawn parms for the new client
+               PRVM_serverglobalfloat(time) = sv.time;
                PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict);
-               PRVM_ExecuteProgram (PRVM_serverfunction(SetChangeParms), "QC function SetChangeParms is missing");
+               prog->ExecuteProgram(prog, PRVM_serverfunction(SetChangeParms), "QC function SetChangeParms is missing");
                for (j=0 ; j<NUM_SPAWN_PARMS ; j++)
                        host_client->spawn_parms[j] = (&PRVM_serverglobalfloat(parm1))[j];
        }
@@ -3189,11 +3207,13 @@ This is called at the start of each level
 
 void SV_SpawnServer (const char *server)
 {
+       prvm_prog_t *prog = SVVM_prog;
        prvm_edict_t *ent;
        int i;
        char *entities;
        dp_model_t *worldmodel;
        char modelname[sizeof(sv.worldname)];
+       char vabuf[1024];
 
        Con_DPrintf("SpawnServer: %s\n", server);
 
@@ -3219,15 +3239,14 @@ void SV_SpawnServer (const char *server)
 
        if(sv.active)
        {
-               SV_VM_Begin();
                World_End(&sv.world);
                if(PRVM_serverfunction(SV_Shutdown))
                {
                        func_t s = PRVM_serverfunction(SV_Shutdown);
+                       PRVM_serverglobalfloat(time) = sv.time;
                        PRVM_serverfunction(SV_Shutdown) = 0; // prevent it from getting called again
-                       PRVM_ExecuteProgram(s,"SV_Shutdown() required");
+                       prog->ExecuteProgram(prog, s,"SV_Shutdown() required");
                }
-               SV_VM_End();
        }
 
        // free q3 shaders so that any newly downloaded shaders will be active
@@ -3237,7 +3256,7 @@ void SV_SpawnServer (const char *server)
        if (!worldmodel || !worldmodel->TraceBox)
        {
                Con_Printf("Couldn't load map %s\n", modelname);
-               SV_UnlockThreadMutex();
+//             SV_UnlockThreadMutex();
                return;
        }
 
@@ -3324,8 +3343,6 @@ void SV_SpawnServer (const char *server)
                sv.protocol = PROTOCOL_QUAKE;
        }
 
-       SV_VM_Begin();
-
 // load progs to get entity field count
        //PR_LoadProgs ( sv_progs.string );
 
@@ -3348,7 +3365,7 @@ void SV_SpawnServer (const char *server)
        prog->allowworldwrites = true;
        sv.paused = false;
 
-       PRVM_serverglobalfloat(time) = sv.time = 1.0;
+       sv.time = 1.0;
 
        Mod_ClearUsed();
        worldmodel->used = true;
@@ -3359,7 +3376,7 @@ void SV_SpawnServer (const char *server)
 //
 // clear world interaction links
 //
-       World_SetSize(&sv.world, sv.worldname, sv.worldmodel->normalmins, sv.worldmodel->normalmaxs);
+       World_SetSize(&sv.world, sv.worldname, sv.worldmodel->normalmins, sv.worldmodel->normalmaxs, prog);
        World_Start(&sv.world);
 
        strlcpy(sv.sound_precache[0], "", sizeof(sv.sound_precache[0]));
@@ -3381,7 +3398,7 @@ void SV_SpawnServer (const char *server)
        ent = PRVM_EDICT_NUM(0);
        memset (ent->fields.vp, 0, prog->entityfields * 4);
        ent->priv.server->free = false;
-       PRVM_serveredictstring(ent, model) = PRVM_SetEngineString(sv.worldname);
+       PRVM_serveredictstring(ent, model) = PRVM_SetEngineString(prog, sv.worldname);
        PRVM_serveredictfloat(ent, modelindex) = 1;             // world model
        PRVM_serveredictfloat(ent, solid) = SOLID_BSP;
        PRVM_serveredictfloat(ent, movetype) = MOVETYPE_PUSH;
@@ -3395,7 +3412,7 @@ void SV_SpawnServer (const char *server)
        else
                PRVM_serverglobalfloat(deathmatch) = deathmatch.integer;
 
-       PRVM_serverglobalstring(mapname) = PRVM_SetEngineString(sv.name);
+       PRVM_serverglobalstring(mapname) = PRVM_SetEngineString(prog, sv.name);
 
 // serverflags are for cross level information (sigils)
        PRVM_serverglobalfloat(serverflags) = svs.serverflags;
@@ -3408,18 +3425,18 @@ void SV_SpawnServer (const char *server)
        {
                host_client->spawned = false;
                host_client->edict = PRVM_EDICT_NUM(i + 1);
-               PRVM_ED_ClearEdict(host_client->edict);
+               PRVM_ED_ClearEdict(prog, host_client->edict);
        }
 
        // load replacement entity file if found
-       if (sv_entpatch.integer && (entities = (char *)FS_LoadFile(va("%s.ent", sv.worldnamenoextension), tempmempool, true, NULL)))
+       if (sv_entpatch.integer && (entities = (char *)FS_LoadFile(va(vabuf, sizeof(vabuf), "%s.ent", sv.worldnamenoextension), tempmempool, true, NULL)))
        {
                Con_Printf("Loaded %s.ent\n", sv.worldnamenoextension);
-               PRVM_ED_LoadFromFile (entities);
+               PRVM_ED_LoadFromFile(prog, entities);
                Mem_Free(entities);
        }
        else
-               PRVM_ED_LoadFromFile (sv.worldmodel->brush.entities);
+               PRVM_ED_LoadFromFile(prog, sv.worldmodel->brush.entities);
 
 
        // LordHavoc: clear world angles (to fix e3m3.bsp)
@@ -3430,7 +3447,7 @@ void SV_SpawnServer (const char *server)
        prog->allowworldwrites = false;
 
 // run two frames to allow everything to settle
-       PRVM_serverglobalfloat(time) = sv.time = 1.0001;
+       sv.time = 1.0001;
        for (i = 0;i < 2;i++)
        {
                sv.frametime = 0.1;
@@ -3446,9 +3463,6 @@ void SV_SpawnServer (const char *server)
 
        sv.state = ss_active; // LordHavoc: workaround for svc_precache bug
 
-       // to prevent network timeouts
-       realtime = Sys_DoubleTime();
-       
 // send serverinfo to all connected clients, and set up botclients coming back from a level change
        for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
        {
@@ -3471,34 +3485,32 @@ void SV_SpawnServer (const char *server)
                        host_client->clientconnectcalled = true;
                        PRVM_serverglobalfloat(time) = sv.time;
                        PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict);
-                       PRVM_ExecuteProgram (PRVM_serverfunction(ClientConnect), "QC function ClientConnect is missing");
-                       PRVM_ExecuteProgram (PRVM_serverfunction(PutClientInServer), "QC function PutClientInServer is missing");
+                       prog->ExecuteProgram(prog, PRVM_serverfunction(ClientConnect), "QC function ClientConnect is missing");
+                       prog->ExecuteProgram(prog, PRVM_serverfunction(PutClientInServer), "QC function PutClientInServer is missing");
                        host_client->spawned = true;
                }
        }
 
        // update the map title cvar
-       strlcpy(sv.worldmessage, PRVM_GetString(PRVM_serveredictstring(prog->edicts, message)), sizeof(sv.worldmessage)); // map title (not related to filename)
+       strlcpy(sv.worldmessage, PRVM_GetString(prog, PRVM_serveredictstring(prog->edicts, message)), sizeof(sv.worldmessage)); // map title (not related to filename)
        Cvar_SetQuick(&sv_worldmessage, sv.worldmessage);
 
        Con_DPrint("Server spawned.\n");
        NetConn_Heartbeat (2);
 
-       SV_VM_End();
-
 //     SV_UnlockThreadMutex();
 }
 
 /////////////////////////////////////////////////////
 // SV VM stuff
 
-static void SV_VM_CB_BeginIncreaseEdicts(void)
+static void SVVM_begin_increase_edicts(prvm_prog_t *prog)
 {
        // links don't survive the transition, so unlink everything
        World_UnlinkAll(&sv.world);
 }
 
-static void SV_VM_CB_EndIncreaseEdicts(void)
+static void SVVM_end_increase_edicts(prvm_prog_t *prog)
 {
        int i;
        prvm_edict_t *ent;
@@ -3509,7 +3521,7 @@ static void SV_VM_CB_EndIncreaseEdicts(void)
                        SV_LinkEdict(ent);
 }
 
-static void SV_VM_CB_InitEdict(prvm_edict_t *e)
+static void SVVM_init_edict(prvm_prog_t *prog, prvm_edict_t *e)
 {
        // LordHavoc: for consistency set these here
        int num = PRVM_NUM_FOR_EDICT(e) - 1;
@@ -3524,44 +3536,44 @@ static void SV_VM_CB_InitEdict(prvm_edict_t *e)
                // set netname/clientcolors back to client values so that
                // DP_SV_CLIENTNAME and DP_SV_CLIENTCOLORS will not immediately
                // reset them
-               PRVM_serveredictstring(e, netname) = PRVM_SetEngineString(svs.clients[num].name);
+               PRVM_serveredictstring(e, netname) = PRVM_SetEngineString(prog, svs.clients[num].name);
                PRVM_serveredictfloat(e, clientcolors) = svs.clients[num].colors;
                // NEXUIZ_PLAYERMODEL and NEXUIZ_PLAYERSKIN
-               PRVM_serveredictstring(e, playermodel) = PRVM_SetEngineString(svs.clients[num].playermodel);
-               PRVM_serveredictstring(e, playerskin) = PRVM_SetEngineString(svs.clients[num].playerskin);
+               PRVM_serveredictstring(e, playermodel) = PRVM_SetEngineString(prog, svs.clients[num].playermodel);
+               PRVM_serveredictstring(e, playerskin) = PRVM_SetEngineString(prog, svs.clients[num].playerskin);
                // Assign netaddress (IP Address, etc)
                if(svs.clients[num].netconnection != NULL)
                {
                        // Acquire Readable Address
                        LHNETADDRESS_ToString(&svs.clients[num].netconnection->peeraddress, svs.clients[num].netaddress, sizeof(svs.clients[num].netaddress), false);
-                       PRVM_serveredictstring(e, netaddress) = PRVM_SetEngineString(svs.clients[num].netaddress);
+                       PRVM_serveredictstring(e, netaddress) = PRVM_SetEngineString(prog, svs.clients[num].netaddress);
                }
                else
-                       PRVM_serveredictstring(e, netaddress) = PRVM_SetEngineString("null/botclient");
+                       PRVM_serveredictstring(e, netaddress) = PRVM_SetEngineString(prog, "null/botclient");
                if(svs.clients[num].netconnection != NULL && svs.clients[num].netconnection->crypto.authenticated && svs.clients[num].netconnection->crypto.client_idfp[0])
-                       PRVM_serveredictstring(e, crypto_idfp) = PRVM_SetEngineString(svs.clients[num].netconnection->crypto.client_idfp);
+                       PRVM_serveredictstring(e, crypto_idfp) = PRVM_SetEngineString(prog, svs.clients[num].netconnection->crypto.client_idfp);
                else
                        PRVM_serveredictstring(e, crypto_idfp) = 0;
                if(svs.clients[num].netconnection != NULL && svs.clients[num].netconnection->crypto.authenticated && svs.clients[num].netconnection->crypto.client_keyfp[0])
-                       PRVM_serveredictstring(e, crypto_keyfp) = PRVM_SetEngineString(svs.clients[num].netconnection->crypto.client_keyfp);
+                       PRVM_serveredictstring(e, crypto_keyfp) = PRVM_SetEngineString(prog, svs.clients[num].netconnection->crypto.client_keyfp);
                else
                        PRVM_serveredictstring(e, crypto_keyfp) = 0;
                if(svs.clients[num].netconnection != NULL && svs.clients[num].netconnection->crypto.authenticated && svs.clients[num].netconnection->crypto.server_keyfp[0])
-                       PRVM_serveredictstring(e, crypto_mykeyfp) = PRVM_SetEngineString(svs.clients[num].netconnection->crypto.server_keyfp);
+                       PRVM_serveredictstring(e, crypto_mykeyfp) = PRVM_SetEngineString(prog, svs.clients[num].netconnection->crypto.server_keyfp);
                else
                        PRVM_serveredictstring(e, crypto_mykeyfp) = 0;
                if(svs.clients[num].netconnection != NULL && svs.clients[num].netconnection->crypto.authenticated && svs.clients[num].netconnection->crypto.use_aes)
-                       PRVM_serveredictstring(e, crypto_encryptmethod) = PRVM_SetEngineString("AES128");
+                       PRVM_serveredictstring(e, crypto_encryptmethod) = PRVM_SetEngineString(prog, "AES128");
                else
                        PRVM_serveredictstring(e, crypto_encryptmethod) = 0;
                if(svs.clients[num].netconnection != NULL && svs.clients[num].netconnection->crypto.authenticated)
-                       PRVM_serveredictstring(e, crypto_signmethod) = PRVM_SetEngineString("HMAC-SHA256");
+                       PRVM_serveredictstring(e, crypto_signmethod) = PRVM_SetEngineString(prog, "HMAC-SHA256");
                else
                        PRVM_serveredictstring(e, crypto_signmethod) = 0;
        }
 }
 
-static void SV_VM_CB_FreeEdict(prvm_edict_t *ed)
+static void SVVM_free_edict(prvm_prog_t *prog, prvm_edict_t *ed)
 {
        int i;
        int e;
@@ -3579,7 +3591,7 @@ static void SV_VM_CB_FreeEdict(prvm_edict_t *ed)
        PRVM_serveredictfloat(ed, nextthink) = -1;
        PRVM_serveredictfloat(ed, solid) = 0;
 
-       VM_RemoveEdictSkeleton(ed);
+       VM_RemoveEdictSkeleton(prog, ed);
        World_Physics_RemoveFromEntity(&sv.world, ed);
        World_Physics_RemoveJointFromEntity(&sv.world, ed);
 
@@ -3594,7 +3606,7 @@ static void SV_VM_CB_FreeEdict(prvm_edict_t *ed)
        }
 }
 
-static void SV_VM_CB_CountEdicts(void)
+static void SVVM_count_edicts(prvm_prog_t *prog)
 {
        int             i;
        prvm_edict_t    *ent;
@@ -3622,7 +3634,7 @@ static void SV_VM_CB_CountEdicts(void)
        Con_Printf("step      :%3i\n", step);
 }
 
-static qboolean SV_VM_CB_LoadEdict(prvm_edict_t *ent)
+static qboolean SVVM_load_edict(prvm_prog_t *prog, prvm_edict_t *ent)
 {
        // remove things from different skill levels or deathmatch
        if (gamemode != GAME_TRANSFUSION) //Transfusion does this in QC
@@ -3646,8 +3658,8 @@ static qboolean SV_VM_CB_LoadEdict(prvm_edict_t *ent)
 
 static void SV_VM_Setup(void)
 {
-       PRVM_Begin;
-       PRVM_InitProg( PRVM_SERVERPROG );
+       prvm_prog_t *prog = SVVM_prog;
+       PRVM_Prog_Init(prog);
 
        // allocate the mempools
        // TODO: move the magic numbers/constants into #defines [9/13/2006 Black]
@@ -3671,18 +3683,19 @@ static void SV_VM_Setup(void)
        prog->extensionstring = vm_sv_extensions;
        prog->loadintoworld = true;
 
-       prog->begin_increase_edicts = SV_VM_CB_BeginIncreaseEdicts;
-       prog->end_increase_edicts = SV_VM_CB_EndIncreaseEdicts;
-       prog->init_edict = SV_VM_CB_InitEdict;
-       prog->free_edict = SV_VM_CB_FreeEdict;
-       prog->count_edicts = SV_VM_CB_CountEdicts;
-       prog->load_edict = SV_VM_CB_LoadEdict;
-       prog->init_cmd = VM_SV_Cmd_Init;
-       prog->reset_cmd = VM_SV_Cmd_Reset;
-       prog->error_cmd = Host_Error;
-       prog->ExecuteProgram = SVVM_ExecuteProgram;
+       // all callbacks must be defined (pointers are not checked before calling)
+       prog->begin_increase_edicts = SVVM_begin_increase_edicts;
+       prog->end_increase_edicts   = SVVM_end_increase_edicts;
+       prog->init_edict            = SVVM_init_edict;
+       prog->free_edict            = SVVM_free_edict;
+       prog->count_edicts          = SVVM_count_edicts;
+       prog->load_edict            = SVVM_load_edict;
+       prog->init_cmd              = SVVM_init_cmd;
+       prog->reset_cmd             = SVVM_reset_cmd;
+       prog->error_cmd             = Host_Error;
+       prog->ExecuteProgram        = SVVM_ExecuteProgram;
 
-       PRVM_LoadProgs( sv_progs.string, SV_REQFUNCS, sv_reqfuncs, SV_REQFIELDS, sv_reqfields, SV_REQGLOBALS, sv_reqglobals);
+       PRVM_Prog_Load(prog, sv_progs.string, SV_REQFUNCS, sv_reqfuncs, SV_REQFIELDS, sv_reqfields, SV_REQGLOBALS, sv_reqglobals);
 
        // some mods compiled with scrambling compilers lack certain critical
        // global names and field names such as "self" and "time" and "nextthink"
@@ -3823,40 +3836,28 @@ static void SV_VM_Setup(void)
 //             PRVM_ED_FindGlobalOffset_FromStruct(globalvars_t, SetChangeParms);
        }
        else
-               Con_DPrintf("%s: %s system vars have been modified (CRC %i != engine %i), will not load in other engines", PRVM_NAME, sv_progs.string, prog->progs_crc, PROGHEADER_CRC);
+               Con_DPrintf("%s: %s system vars have been modified (CRC %i != engine %i), will not load in other engines", prog->name, sv_progs.string, prog->progs_crc, PROGHEADER_CRC);
 
        // OP_STATE is always supported on server because we add fields/globals for it
        prog->flag |= PRVM_OP_STATE;
 
        VM_CustomStats_Clear();//[515]: csqc
 
-       PRVM_End;
-
        SV_Prepare_CSQC();
 }
 
-void SV_VM_Begin(void)
-{
-       PRVM_Begin;
-       PRVM_SetProg( PRVM_SERVERPROG );
-
-       PRVM_serverglobalfloat(time) = (float) sv.time;
-}
-
-void SV_VM_End(void)
-{
-       PRVM_End;
-}
-
 extern cvar_t host_maxwait;
 extern cvar_t host_framerate;
-int SV_ThreadFunc(void *voiddata)
+static int SV_ThreadFunc(void *voiddata)
 {
+       prvm_prog_t *prog = SVVM_prog;
+       qboolean playing = false;
        double sv_timer = 0;
        double sv_deltarealtime, sv_oldrealtime, sv_realtime;
        double wait;
        int i;
-       sv_realtime = Sys_DoubleTime();
+       char vabuf[1024];
+       sv_realtime = Sys_DirtyTime();
        while (!svs.threadstop)
        {
                // FIXME: we need to handle Host_Error in the server thread somehow
@@ -3864,19 +3865,25 @@ int SV_ThreadFunc(void *voiddata)
 //                     continue;                       // something bad happened in the server game
 
                sv_oldrealtime = sv_realtime;
-               sv_realtime = Sys_DoubleTime();
-
+               sv_realtime = Sys_DirtyTime();
                sv_deltarealtime = sv_realtime - sv_oldrealtime;
+               if (sv_deltarealtime < 0 || sv_deltarealtime >= 1800) sv_deltarealtime = 0;
+
                sv_timer += sv_deltarealtime;
 
                svs.perf_acc_realtime += sv_deltarealtime;
 
+               // at this point we start doing real server work, and must block on any client activity pertaining to the server (such as executing SV_SpawnServer)
+               SV_LockThreadMutex();
+
                // Look for clients who have spawned
-               for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
-                       if(host_client->spawned)
-                               if(host_client->netconnection)
-                                       break;
-               if(i == svs.maxclients)
+               playing = false;
+               if (sv.active)
+                       for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
+                               if(host_client->spawned)
+                                       if(host_client->netconnection)
+                                               playing = true;
+               if(!playing)
                {
                        // Nobody is looking? Then we won't do timing...
                        // Instead, reset it to zero
@@ -3893,7 +3900,7 @@ int SV_ThreadFunc(void *voiddata)
                                svs.perf_offset_sdev = sqrt(svs.perf_acc_offset_squared / svs.perf_acc_offset_samples - svs.perf_offset_avg * svs.perf_offset_avg);
                        }
                        if(svs.perf_lost > 0 && developer_extra.integer)
-                               Con_DPrintf("Server can't keep up: %s\n", Host_TimingReport());
+                               Con_DPrintf("Server can't keep up: %s\n", Host_TimingReport(vabuf, sizeof(vabuf)));
                        svs.perf_acc_realtime = svs.perf_acc_sleeptime = svs.perf_acc_lost = svs.perf_acc_offset = svs.perf_acc_offset_squared = svs.perf_acc_offset_max = svs.perf_acc_offset_samples = 0;
                }
 
@@ -3905,16 +3912,18 @@ int SV_ThreadFunc(void *voiddata)
                wait = sv_timer * -1000000.0;
                if (wait >= 1)
                {
-                       double time0;
+                       double time0, delta;
+                       SV_UnlockThreadMutex(); // don't keep mutex locked while sleeping
                        if (host_maxwait.value <= 0)
                                wait = min(wait, 1000000.0);
                        else
                                wait = min(wait, host_maxwait.value * 1000.0);
                        if(wait < 1)
                                wait = 1; // because we cast to int
-                       time0 = Sys_DoubleTime();
+                       time0 = Sys_DirtyTime();
                        Sys_Sleep((int)wait);
-                       svs.perf_acc_sleeptime += Sys_DoubleTime() - time0;
+                       delta = Sys_DirtyTime() - time0;if (delta < 0 || delta >= 1800) delta = 0;
+                       svs.perf_acc_sleeptime += delta;
                        continue;
                }
 
@@ -3931,7 +3940,7 @@ int SV_ThreadFunc(void *voiddata)
 
                        if(advancetime > 0)
                        {
-                               offset = sv_timer + (Sys_DoubleTime() - sv_realtime); // LordHavoc: FIXME: I don't understand this line
+                               offset = sv_timer + (Sys_DirtyTime() - sv_realtime); // LordHavoc: FIXME: I don't understand this line
                                ++svs.perf_acc_offset_samples;
                                svs.perf_acc_offset += offset;
                                svs.perf_acc_offset_squared += offset * offset;
@@ -3939,9 +3948,6 @@ int SV_ThreadFunc(void *voiddata)
                                        svs.perf_acc_offset_max = offset;
                        }
 
-                       // at this point we start doing real server work, and must block on any client activity pertaining to the server (such as executing SV_SpawnServer)
-                       SV_LockThreadMutex();
-
                        // only advance time if not paused
                        // the game also pauses in singleplayer when menu or console is used
                        sv.frametime = advancetime * slowmo.value;
@@ -3952,9 +3958,6 @@ int SV_ThreadFunc(void *voiddata)
 
                        sv_timer -= advancetime;
 
-                       // setup the VM frame
-                       SV_VM_Begin();
-
                        // move things around and think unless paused
                        if (sv.frametime)
                                SV_Physics();
@@ -3964,20 +3967,19 @@ int SV_ThreadFunc(void *voiddata)
 
                        if (sv.paused == 1 && sv_realtime > sv.pausedstart && sv.pausedstart > 0)
                        {
+                               PRVM_serverglobalfloat(time) = sv.time;
                                prog->globals.generic[OFS_PARM0] = sv_realtime - sv.pausedstart;
-                               PRVM_ExecuteProgram(PRVM_serverfunction(SV_PausedTic), "QC function SV_PausedTic is missing");
+                               prog->ExecuteProgram(prog, PRVM_serverfunction(SV_PausedTic), "QC function SV_PausedTic is missing");
                        }
 
-                       // end the server VM frame
-                       SV_VM_End();
-
                        // send an heartbeat if enough time has passed since the last one
                        NetConn_Heartbeat(0);
 
-                       // at this point we start doing real server work, and must block on any client activity pertaining to the server (such as executing SV_SpawnServer)
-                       SV_UnlockThreadMutex();
                }
 
+               // we're back to safe code now
+               SV_UnlockThreadMutex();
+
                // if there is some time remaining from this frame, reset the timers
                if (sv_timer >= 0)
                {
index d93d1f8b2b6fbc948b30515f9776fac46e1fccc8..eb577c77721975b6e27e945fb8d73434ae50a662 100644 (file)
--- a/sv_move.c
+++ b/sv_move.c
@@ -35,6 +35,7 @@ int c_yes, c_no;
 
 qboolean SV_CheckBottom (prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        vec3_t  mins, maxs, start, stop;
        trace_t trace;
        int             x, y;
@@ -107,6 +108,7 @@ possible, no move is done and false is returned
 */
 qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qboolean noenemy, qboolean settrace)
 {
+       prvm_prog_t *prog = SVVM_prog;
        float           dz;
        vec3_t          oldorg, neworg, end, traceendpos;
        trace_t         trace;
@@ -249,14 +251,14 @@ facing it.
 
 ======================
 */
-void VM_changeyaw (void);
-qboolean SV_StepDirection (prvm_edict_t *ent, float yaw, float dist)
+static qboolean SV_StepDirection (prvm_edict_t *ent, float yaw, float dist)
 {
+       prvm_prog_t *prog = SVVM_prog;
        vec3_t          move, oldorigin;
        float           delta;
 
        PRVM_serveredictfloat(ent, ideal_yaw) = yaw;
-       VM_changeyaw();
+       VM_changeyaw(prog);
 
        yaw = yaw*M_PI*2 / 360;
        move[0] = cos(yaw)*dist;
@@ -287,8 +289,9 @@ SV_FixCheckBottom
 
 ======================
 */
-void SV_FixCheckBottom (prvm_edict_t *ent)
+static void SV_FixCheckBottom (prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) | FL_PARTIALGROUND;
 }
 
@@ -301,8 +304,9 @@ SV_NewChaseDir
 ================
 */
 #define        DI_NODIR        -1
-void SV_NewChaseDir (prvm_edict_t *actor, prvm_edict_t *enemy, float dist)
+static void SV_NewChaseDir (prvm_edict_t *actor, prvm_edict_t *enemy, float dist)
 {
+       prvm_prog_t *prog = SVVM_prog;
        float           deltax,deltay;
        float                   d[3];
        float           tdir, olddir, turnaround;
@@ -390,7 +394,7 @@ SV_CloseEnough
 
 ======================
 */
-qboolean SV_CloseEnough (prvm_edict_t *ent, prvm_edict_t *goal, float dist)
+static qboolean SV_CloseEnough (prvm_edict_t *ent, prvm_edict_t *goal, float dist)
 {
        int             i;
 
@@ -410,7 +414,7 @@ SV_MoveToGoal
 
 ======================
 */
-void SV_MoveToGoal (void)
+void VM_SV_MoveToGoal(prvm_prog_t *prog)
 {
        prvm_edict_t            *ent, *goal;
        float           dist;
index c0142c5940125072a1e0de64364b00f6c723d3dc..d1de5a39cd8ef0848e2f79d07526ba39cfad6987 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // sv_phys.c
 
 #include "quakedef.h"
+#include "prvm_cmds.h"
 
 /*
 
@@ -43,7 +44,7 @@ solid_edge items only clip against bsp models.
 
 void SV_Physics_Toss (prvm_edict_t *ent);
 
-int SV_GetPitchSign(prvm_edict_t *ent)
+int SV_GetPitchSign(prvm_prog_t *prog, prvm_edict_t *ent)
 {
        dp_model_t *model;
        if (
@@ -71,6 +72,7 @@ LINE TESTING IN HULLS
 
 int SV_GenericHitSuperContentsMask(const prvm_edict_t *passedict)
 {
+       prvm_prog_t *prog = SVVM_prog;
        if (passedict)
        {
                int dphitcontentsmask = (int)PRVM_serveredictfloat(passedict, dphitcontentsmask);
@@ -101,6 +103,7 @@ SV_TracePoint
 */
 trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i, bodysupercontents;
        int passedictprog;
        float pitchsign = 1;
@@ -213,16 +216,16 @@ trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int
                if ((int) PRVM_serveredictfloat(touch, solid) == SOLID_BSP || type == MOVE_HITMODEL)
                {
                        model = SV_GetModelFromEdict(touch);
-                       pitchsign = SV_GetPitchSign(touch);
+                       pitchsign = SV_GetPitchSign(prog, touch);
                }
                if (model)
                        Matrix4x4_CreateFromQuakeEntity(&matrix, PRVM_serveredictvector(touch, origin)[0], PRVM_serveredictvector(touch, origin)[1], PRVM_serveredictvector(touch, origin)[2], pitchsign * PRVM_serveredictvector(touch, angles)[0], PRVM_serveredictvector(touch, angles)[1], PRVM_serveredictvector(touch, angles)[2], 1);
                else
                        Matrix4x4_CreateTranslate(&matrix, PRVM_serveredictvector(touch, origin)[0], PRVM_serveredictvector(touch, origin)[1], PRVM_serveredictvector(touch, origin)[2]);
                Matrix4x4_Invert_Simple(&imatrix, &matrix);
-               VM_GenerateFrameGroupBlend(touch->priv.server->framegroupblend, touch);
+               VM_GenerateFrameGroupBlend(prog, touch->priv.server->framegroupblend, touch);
                VM_FrameBlendFromFrameGroupBlend(touch->priv.server->frameblend, touch->priv.server->framegroupblend, model);
-               VM_UpdateEdictSkeleton(touch, model, touch->priv.server->frameblend);
+               VM_UpdateEdictSkeleton(prog, touch, model, touch->priv.server->frameblend);
                if (type == MOVE_MISSILE && (int)PRVM_serveredictfloat(touch, flags) & FL_MONSTER)
                        Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, PRVM_serveredictvector(touch, mins), PRVM_serveredictvector(touch, maxs), bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipstart, hitsupercontentsmask);
                else
@@ -246,6 +249,7 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t pEnd, int type, prvm_edict
 trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask)
 #endif
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i, bodysupercontents;
        int passedictprog;
        float pitchsign = 1;
@@ -379,16 +383,16 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
                if ((int) PRVM_serveredictfloat(touch, solid) == SOLID_BSP || type == MOVE_HITMODEL)
                {
                        model = SV_GetModelFromEdict(touch);
-                       pitchsign = SV_GetPitchSign(touch);
+                       pitchsign = SV_GetPitchSign(prog, touch);
                }
                if (model)
                        Matrix4x4_CreateFromQuakeEntity(&matrix, PRVM_serveredictvector(touch, origin)[0], PRVM_serveredictvector(touch, origin)[1], PRVM_serveredictvector(touch, origin)[2], pitchsign * PRVM_serveredictvector(touch, angles)[0], PRVM_serveredictvector(touch, angles)[1], PRVM_serveredictvector(touch, angles)[2], 1);
                else
                        Matrix4x4_CreateTranslate(&matrix, PRVM_serveredictvector(touch, origin)[0], PRVM_serveredictvector(touch, origin)[1], PRVM_serveredictvector(touch, origin)[2]);
                Matrix4x4_Invert_Simple(&imatrix, &matrix);
-               VM_GenerateFrameGroupBlend(touch->priv.server->framegroupblend, touch);
+               VM_GenerateFrameGroupBlend(prog, touch->priv.server->framegroupblend, touch);
                VM_FrameBlendFromFrameGroupBlend(touch->priv.server->frameblend, touch->priv.server->framegroupblend, model);
-               VM_UpdateEdictSkeleton(touch, model, touch->priv.server->frameblend);
+               VM_UpdateEdictSkeleton(prog, touch, model, touch->priv.server->frameblend);
                if (type == MOVE_MISSILE && (int)PRVM_serveredictfloat(touch, flags) & FL_MONSTER)
                        Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, PRVM_serveredictvector(touch, mins), PRVM_serveredictvector(touch, maxs), bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask);
                else
@@ -424,6 +428,7 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
 #endif
 #endif
 {
+       prvm_prog_t *prog = SVVM_prog;
        vec3_t hullmins, hullmaxs;
        int i, bodysupercontents;
        int passedictprog;
@@ -592,16 +597,16 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
                if ((int) PRVM_serveredictfloat(touch, solid) == SOLID_BSP || type == MOVE_HITMODEL)
                {
                        model = SV_GetModelFromEdict(touch);
-                       pitchsign = SV_GetPitchSign(touch);
+                       pitchsign = SV_GetPitchSign(prog, touch);
                }
                if (model)
                        Matrix4x4_CreateFromQuakeEntity(&matrix, PRVM_serveredictvector(touch, origin)[0], PRVM_serveredictvector(touch, origin)[1], PRVM_serveredictvector(touch, origin)[2], pitchsign * PRVM_serveredictvector(touch, angles)[0], PRVM_serveredictvector(touch, angles)[1], PRVM_serveredictvector(touch, angles)[2], 1);
                else
                        Matrix4x4_CreateTranslate(&matrix, PRVM_serveredictvector(touch, origin)[0], PRVM_serveredictvector(touch, origin)[1], PRVM_serveredictvector(touch, origin)[2]);
                Matrix4x4_Invert_Simple(&imatrix, &matrix);
-               VM_GenerateFrameGroupBlend(touch->priv.server->framegroupblend, touch);
+               VM_GenerateFrameGroupBlend(prog, touch->priv.server->framegroupblend, touch);
                VM_FrameBlendFromFrameGroupBlend(touch->priv.server->frameblend, touch->priv.server->framegroupblend, model);
-               VM_UpdateEdictSkeleton(touch, model, touch->priv.server->frameblend);
+               VM_UpdateEdictSkeleton(prog, touch, model, touch->priv.server->frameblend);
                if (type == MOVE_MISSILE && (int)PRVM_serveredictfloat(touch, flags) & FL_MONSTER)
                        Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, PRVM_serveredictvector(touch, mins), PRVM_serveredictvector(touch, maxs), bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask);
                else
@@ -640,6 +645,7 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
 
 int SV_PointSuperContents(const vec3_t point)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int supercontents = 0;
        int i;
        prvm_edict_t *touch;
@@ -701,6 +707,7 @@ Linking entities into the world culling system
 
 int SV_EntitiesInBox(const vec3_t mins, const vec3_t maxs, int maxedicts, prvm_edict_t **resultedicts)
 {
+       prvm_prog_t *prog = SVVM_prog;
        vec3_t paddedmins, paddedmaxs;
        if (maxedicts < 1 || resultedicts == NULL)
                return 0;
@@ -729,6 +736,7 @@ int SV_EntitiesInBox(const vec3_t mins, const vec3_t maxs, int maxedicts, prvm_e
 
 void SV_LinkEdict_TouchAreaGrid_Call(prvm_edict_t *touch, prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(touch);
        PRVM_serverglobaledict(other) = PRVM_EDICT_TO_PROG(ent);
        PRVM_serverglobalfloat(time) = sv.time;
@@ -745,11 +753,12 @@ void SV_LinkEdict_TouchAreaGrid_Call(prvm_edict_t *touch, prvm_edict_t *ent)
        PRVM_serverglobalfloat(trace_dphitcontents) = 0;
        PRVM_serverglobalfloat(trace_dphitq3surfaceflags) = 0;
        PRVM_serverglobalstring(trace_dphittexturename) = 0;
-       PRVM_ExecuteProgram (PRVM_serveredictfunction(touch, touch), "QC function self.touch is missing");
+       prog->ExecuteProgram(prog, PRVM_serveredictfunction(touch, touch), "QC function self.touch is missing");
 }
 
 void SV_LinkEdict_TouchAreaGrid(prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i, numtouchedicts, old_self, old_other;
        prvm_edict_t *touch;
        static prvm_edict_t *touchedicts[MAX_EDICTS];
@@ -826,6 +835,7 @@ SV_LinkEdict
 */
 void SV_LinkEdict (prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        dp_model_t *model;
        vec3_t mins, maxs;
        int modelindex;
@@ -844,9 +854,9 @@ void SV_LinkEdict (prvm_edict_t *ent)
        }
        model = SV_GetModelByIndex(modelindex);
 
-       VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
+       VM_GenerateFrameGroupBlend(prog, ent->priv.server->framegroupblend, ent);
        VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
-       VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
+       VM_UpdateEdictSkeleton(prog, ent, model, ent->priv.server->frameblend);
 
 // set the abs box
 
@@ -942,6 +952,7 @@ returns true if the entity is in solid currently
 */
 static int SV_TestEntityPosition (prvm_edict_t *ent, vec3_t offset)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int contents;
        vec3_t org;
        trace_t trace;
@@ -996,34 +1007,6 @@ static int SV_TestEntityPosition (prvm_edict_t *ent, vec3_t offset)
        return false;
 }
 
-/*
-================
-SV_CheckAllEnts
-================
-*/
-void SV_CheckAllEnts (void)
-{
-       int e;
-       prvm_edict_t *check;
-
-       // see if any solid entities are inside the final position
-       check = PRVM_NEXT_EDICT(prog->edicts);
-       for (e = 1;e < prog->num_edicts;e++, check = PRVM_NEXT_EDICT(check))
-       {
-               if (check->priv.server->free)
-                       continue;
-               if (PRVM_serveredictfloat(check, movetype) == MOVETYPE_PUSH
-                || PRVM_serveredictfloat(check, movetype) == MOVETYPE_NONE
-                || PRVM_serveredictfloat(check, movetype) == MOVETYPE_FOLLOW
-                || PRVM_serveredictfloat(check, movetype) == MOVETYPE_NOCLIP
-                || PRVM_serveredictfloat(check, movetype) == MOVETYPE_FLY_WORLDONLY)
-                       continue;
-
-               if (SV_TestEntityPosition (check, vec3_origin))
-                       Con_Print("entity in invalid position\n");
-       }
-}
-
 // DRESK - Support for Entity Contents Transition Event
 /*
 ================
@@ -1032,8 +1015,9 @@ SV_CheckContentsTransition
 returns true if entity had a valid contentstransition function call
 ================
 */
-int SV_CheckContentsTransition(prvm_edict_t *ent, const int nContents)
+static int SV_CheckContentsTransition(prvm_edict_t *ent, const int nContents)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int bValidFunctionCall;
 
        // Default Valid Function Call to False
@@ -1047,14 +1031,16 @@ int SV_CheckContentsTransition(prvm_edict_t *ent, const int nContents)
                        // Assign Valid Function
                        bValidFunctionCall = true;
                        // Prepare Parameters (Original Contents, New Contents)
-                               // Original Contents
-                               PRVM_G_FLOAT(OFS_PARM0) = PRVM_serveredictfloat(ent, watertype);
-                               // New Contents
-                               PRVM_G_FLOAT(OFS_PARM1) = nContents;
-                               // Assign Self
-                               PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
+                       // Original Contents
+                       PRVM_G_FLOAT(OFS_PARM0) = PRVM_serveredictfloat(ent, watertype);
+                       // New Contents
+                       PRVM_G_FLOAT(OFS_PARM1) = nContents;
+                       // Assign Self
+                       PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
+                       // Set Time
+                       PRVM_serverglobalfloat(time) = sv.time;
                        // Execute VM Function
-                       PRVM_ExecuteProgram(PRVM_serveredictfunction(ent, contentstransition), "contentstransition: NULL function");
+                       prog->ExecuteProgram(prog, PRVM_serveredictfunction(ent, contentstransition), "contentstransition: NULL function");
                }
        }
 
@@ -1070,6 +1056,7 @@ SV_CheckVelocity
 */
 void SV_CheckVelocity (prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i;
        float wishspeed;
 
@@ -1080,12 +1067,12 @@ void SV_CheckVelocity (prvm_edict_t *ent)
        {
                if (IS_NAN(PRVM_serveredictvector(ent, velocity)[i]))
                {
-                       Con_Printf("Got a NaN velocity on entity #%i (%s)\n", PRVM_NUM_FOR_EDICT(ent), PRVM_GetString(PRVM_serveredictstring(ent, classname)));
+                       Con_Printf("Got a NaN velocity on entity #%i (%s)\n", PRVM_NUM_FOR_EDICT(ent), PRVM_GetString(prog, PRVM_serveredictstring(ent, classname)));
                        PRVM_serveredictvector(ent, velocity)[i] = 0;
                }
                if (IS_NAN(PRVM_serveredictvector(ent, origin)[i]))
                {
-                       Con_Printf("Got a NaN origin on entity #%i (%s)\n", PRVM_NUM_FOR_EDICT(ent), PRVM_GetString(PRVM_serveredictstring(ent, classname)));
+                       Con_Printf("Got a NaN origin on entity #%i (%s)\n", PRVM_NUM_FOR_EDICT(ent), PRVM_GetString(prog, PRVM_serveredictstring(ent, classname)));
                        PRVM_serveredictvector(ent, origin)[i] = 0;
                }
        }
@@ -1117,8 +1104,9 @@ in a frame.  Not used for pushmove objects, because they must be exact.
 Returns false if the entity removed itself.
 =============
 */
-qboolean SV_RunThink (prvm_edict_t *ent)
+static qboolean SV_RunThink (prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int iterations;
 
        // don't let things stay in the past.
@@ -1132,7 +1120,7 @@ qboolean SV_RunThink (prvm_edict_t *ent)
                PRVM_serveredictfloat(ent, nextthink) = 0;
                PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
                PRVM_serverglobaledict(other) = PRVM_EDICT_TO_PROG(prog->edicts);
-               PRVM_ExecuteProgram (PRVM_serveredictfunction(ent, think), "QC function self.think is missing");
+               prog->ExecuteProgram(prog, PRVM_serveredictfunction(ent, think), "QC function self.think is missing");
                // mods often set nextthink to time to cause a think every frame,
                // we don't want to loop in that case, so exit if the new nextthink is
                // <= the time the qc was told, also exit if it is past the end of the
@@ -1150,30 +1138,30 @@ SV_Impact
 Two entities have touched, so run their touch functions
 ==================
 */
-extern void VM_SetTraceGlobals(const trace_t *trace);
-extern sizebuf_t vm_tempstringsbuf;
-void SV_Impact (prvm_edict_t *e1, trace_t *trace)
+static void SV_Impact (prvm_edict_t *e1, trace_t *trace)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int restorevm_tempstringsbuf_cursize;
        int old_self, old_other;
        prvm_edict_t *e2 = (prvm_edict_t *)trace->ent;
 
        old_self = PRVM_serverglobaledict(self);
        old_other = PRVM_serverglobaledict(other);
-       restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize;
+       restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize;
 
-       VM_SetTraceGlobals(trace);
+       VM_SetTraceGlobals(prog, trace);
 
-       PRVM_serverglobalfloat(time) = sv.time;
        if (!e1->priv.server->free && !e2->priv.server->free && PRVM_serveredictfunction(e1, touch) && PRVM_serveredictfloat(e1, solid) != SOLID_NOT)
        {
+               PRVM_serverglobalfloat(time) = sv.time;
                PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(e1);
                PRVM_serverglobaledict(other) = PRVM_EDICT_TO_PROG(e2);
-               PRVM_ExecuteProgram (PRVM_serveredictfunction(e1, touch), "QC function self.touch is missing");
+               prog->ExecuteProgram(prog, PRVM_serveredictfunction(e1, touch), "QC function self.touch is missing");
        }
 
        if (!e1->priv.server->free && !e2->priv.server->free && PRVM_serveredictfunction(e2, touch) && PRVM_serveredictfloat(e2, solid) != SOLID_NOT)
        {
+               PRVM_serverglobalfloat(time) = sv.time;
                PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(e2);
                PRVM_serverglobaledict(other) = PRVM_EDICT_TO_PROG(e1);
                VectorCopy(PRVM_serveredictvector(e2, origin), PRVM_serverglobalvector(trace_endpos));
@@ -1184,12 +1172,12 @@ void SV_Impact (prvm_edict_t *e1, trace_t *trace)
                PRVM_serverglobalfloat(trace_dphitcontents) = 0;
                PRVM_serverglobalfloat(trace_dphitq3surfaceflags) = 0;
                PRVM_serverglobalstring(trace_dphittexturename) = 0;
-               PRVM_ExecuteProgram (PRVM_serveredictfunction(e2, touch), "QC function self.touch is missing");
+               prog->ExecuteProgram(prog, PRVM_serveredictfunction(e2, touch), "QC function self.touch is missing");
        }
 
        PRVM_serverglobaledict(self) = old_self;
        PRVM_serverglobaledict(other) = old_other;
-       vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
+       prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
 }
 
 
@@ -1202,7 +1190,7 @@ returns the blocked flags (1 = floor, 2 = step / wall)
 ==================
 */
 #define STOP_EPSILON 0.1
-void ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce)
+static void ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce)
 {
        int i;
        float backoff;
@@ -1234,6 +1222,7 @@ static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, q
 #define MAX_CLIP_PLANES 5
 static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, float *stepnormal, int hitsupercontentsmask, float stepheight)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int blocked, bumpcount;
        int i, j, numplanes;
        float d, time_left, gravity;
@@ -1461,6 +1450,7 @@ SV_Gravity
 */
 static float SV_Gravity (prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        float ent_gravity;
 
        ent_gravity = PRVM_serveredictfloat(ent, gravity);
@@ -1480,6 +1470,7 @@ PUSHMOVE
 
 static qboolean SV_NudgeOutOfSolid_PivotIsKnownGood(prvm_edict_t *ent, vec3_t pivot)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int bump;
        trace_t stucktrace;
        vec3_t stuckorigin;
@@ -1560,6 +1551,7 @@ static qboolean SV_NudgeOutOfSolid_PivotIsKnownGood(prvm_edict_t *ent, vec3_t pi
 
 static qboolean SV_NudgeOutOfSolid(prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int bump;
        trace_t stucktrace;
        vec3_t stuckorigin;
@@ -1603,6 +1595,7 @@ Returns true if the push did not result in the entity being teleported by QC cod
 */
 static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, qboolean failonbmodelstartsolid, qboolean dolink)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int solid;
        int movetype;
        int type;
@@ -1669,8 +1662,9 @@ SV_PushMove
 
 ============
 */
-void SV_PushMove (prvm_edict_t *pusher, float movetime)
+static void SV_PushMove (prvm_edict_t *pusher, float movetime)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i, e, index;
        int pusherowner, pusherprog;
        int checkcontents;
@@ -1949,9 +1943,10 @@ void SV_PushMove (prvm_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 (PRVM_serveredictfunction(pusher, blocked))
                        {
+                               PRVM_serverglobalfloat(time) = sv.time;
                                PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(pusher);
                                PRVM_serverglobaledict(other) = PRVM_EDICT_TO_PROG(check);
-                               PRVM_ExecuteProgram (PRVM_serveredictfunction(pusher, blocked), "QC function self.blocked is missing");
+                               prog->ExecuteProgram(prog, PRVM_serveredictfunction(pusher, blocked), "QC function self.blocked is missing");
                        }
                        break;
                }
@@ -1967,8 +1962,9 @@ SV_Physics_Pusher
 
 ================
 */
-void SV_Physics_Pusher (prvm_edict_t *ent)
+static void SV_Physics_Pusher (prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        float thinktime, oldltime, movetime;
 
        oldltime = PRVM_serveredictfloat(ent, ltime);
@@ -1993,7 +1989,7 @@ void SV_Physics_Pusher (prvm_edict_t *ent)
                PRVM_serverglobalfloat(time) = sv.time;
                PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
                PRVM_serverglobaledict(other) = PRVM_EDICT_TO_PROG(prog->edicts);
-               PRVM_ExecuteProgram (PRVM_serveredictfunction(ent, think), "QC function self.think is missing");
+               prog->ExecuteProgram(prog, PRVM_serveredictfunction(ent, think), "QC function self.think is missing");
        }
 }
 
@@ -2031,8 +2027,9 @@ typedef enum unstickresult_e
 }
 unstickresult_t;
 
-unstickresult_t SV_UnstickEntityReturnOffset (prvm_edict_t *ent, vec3_t offset)
+static unstickresult_t SV_UnstickEntityReturnOffset (prvm_edict_t *ent, vec3_t offset)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i, maxunstick;
 
        // if not stuck in a bmodel, just return
@@ -2077,17 +2074,18 @@ unstickresult_t SV_UnstickEntityReturnOffset (prvm_edict_t *ent, vec3_t offset)
 
 qboolean SV_UnstickEntity (prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        vec3_t offset;
        switch(SV_UnstickEntityReturnOffset(ent, offset))
        {
                case UNSTICK_GOOD:
                        return true;
                case UNSTICK_UNSTUCK:
-                       Con_DPrintf("Unstuck entity %i (classname \"%s\") with offset %f %f %f.\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(PRVM_serveredictstring(ent, classname)), offset[0], offset[1], offset[2]);
+                       Con_DPrintf("Unstuck entity %i (classname \"%s\") with offset %f %f %f.\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(prog, PRVM_serveredictstring(ent, classname)), offset[0], offset[1], offset[2]);
                        return true;
                case UNSTICK_STUCK:
                        if (developer_extra.integer)
-                               Con_DPrintf("Stuck entity %i (classname \"%s\").\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(PRVM_serveredictstring(ent, classname)));
+                               Con_DPrintf("Stuck entity %i (classname \"%s\").\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(prog, PRVM_serveredictstring(ent, classname)));
                        return false;
                default:
                        Con_Printf("SV_UnstickEntityReturnOffset returned a value outside its enum.\n");
@@ -2103,8 +2101,9 @@ This is a big hack to try and fix the rare case of getting stuck in the world
 clipping hull.
 =============
 */
-void SV_CheckStuck (prvm_edict_t *ent)
+static void SV_CheckStuck (prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        vec3_t offset;
 
        switch(SV_UnstickEntityReturnOffset(ent, offset))
@@ -2113,18 +2112,18 @@ void SV_CheckStuck (prvm_edict_t *ent)
                        VectorCopy (PRVM_serveredictvector(ent, origin), PRVM_serveredictvector(ent, oldorigin));
                        break;
                case UNSTICK_UNSTUCK:
-                       Con_DPrintf("Unstuck player entity %i (classname \"%s\") with offset %f %f %f.\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(PRVM_serveredictstring(ent, classname)), offset[0], offset[1], offset[2]);
+                       Con_DPrintf("Unstuck player entity %i (classname \"%s\") with offset %f %f %f.\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(prog, PRVM_serveredictstring(ent, classname)), offset[0], offset[1], offset[2]);
                        break;
                case UNSTICK_STUCK:
                        VectorSubtract(PRVM_serveredictvector(ent, oldorigin), PRVM_serveredictvector(ent, origin), offset);
                        if (!SV_TestEntityPosition(ent, offset))
                        {
-                               Con_DPrintf("Unstuck player entity %i (classname \"%s\") by restoring oldorigin.\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(PRVM_serveredictstring(ent, classname)));
+                               Con_DPrintf("Unstuck player entity %i (classname \"%s\") by restoring oldorigin.\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(prog, PRVM_serveredictstring(ent, classname)));
                                SV_LinkEdict(ent);
                                //SV_LinkEdict_TouchAreaGrid(ent);
                        }
                        else
-                               Con_DPrintf("Stuck player entity %i (classname \"%s\").\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(PRVM_serveredictstring(ent, classname)));
+                               Con_DPrintf("Stuck player entity %i (classname \"%s\").\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(prog, PRVM_serveredictstring(ent, classname)));
                        break;
                default:
                        Con_Printf("SV_UnstickEntityReturnOffset returned a value outside its enum.\n");
@@ -2137,8 +2136,9 @@ void SV_CheckStuck (prvm_edict_t *ent)
 SV_CheckWater
 =============
 */
-qboolean SV_CheckWater (prvm_edict_t *ent)
+static qboolean SV_CheckWater (prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int cont;
        int nNativeContents;
        vec3_t point;
@@ -2188,8 +2188,9 @@ SV_WallFriction
 
 ============
 */
-void SV_WallFriction (prvm_edict_t *ent, float *stepnormal)
+static void SV_WallFriction (prvm_edict_t *ent, float *stepnormal)
 {
+       prvm_prog_t *prog = SVVM_prog;
        float d, i;
        vec3_t forward, into, side;
 
@@ -2274,8 +2275,9 @@ SV_WalkMove
 Only used by players
 ======================
 */
-void SV_WalkMove (prvm_edict_t *ent)
+static void SV_WalkMove (prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int clip;
        int oldonground;
        //int originalmove_clip;
@@ -2479,8 +2481,9 @@ SV_Physics_Follow
 Entities that are "stuck" to another entity
 =============
 */
-void SV_Physics_Follow (prvm_edict_t *ent)
+static void SV_Physics_Follow (prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        vec3_t vf, vr, vu, angles, v;
        prvm_edict_t *e;
 
@@ -2531,8 +2534,9 @@ SV_CheckWaterTransition
 
 =============
 */
-void SV_CheckWaterTransition (prvm_edict_t *ent)
+static void SV_CheckWaterTransition (prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        // LordHavoc: bugfixes in this function are keyed to the sv_gameplayfix_bugfixedcheckwatertransition cvar - if this cvar is 0 then all the original bugs should be reenabled for compatibility
        int cont;
        cont = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_serveredictvector(ent, origin)));
@@ -2579,6 +2583,7 @@ Toss, bounce, and fly movement.  When onground, do nothing.
 
 void SV_Physics_Toss (prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        trace_t trace;
        vec3_t move;
        vec_t movetime;
@@ -2744,8 +2749,9 @@ This is also used for objects that have become still on the ground, but
 will fall if the floor is pulled out from under them.
 =============
 */
-void SV_Physics_Step (prvm_edict_t *ent)
+static void SV_Physics_Step (prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int flags = (int)PRVM_serveredictfloat(ent, flags);
 
        // DRESK
@@ -2787,14 +2793,16 @@ void SV_Physics_Step (prvm_edict_t *ent)
                                if(PRVM_serveredictfunction(ent, movetypesteplandevent))
                                { // Valid Function; Execute
                                        // Prepare Parameters
-                                               // Assign Velocity at Impact
-                                               PRVM_G_VECTOR(OFS_PARM0)[0] = backupVelocity[0];
-                                               PRVM_G_VECTOR(OFS_PARM0)[1] = backupVelocity[1];
-                                               PRVM_G_VECTOR(OFS_PARM0)[2] = backupVelocity[2];
-                                               // Assign Self
-                                               PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
+                                       // Assign Velocity at Impact
+                                       PRVM_G_VECTOR(OFS_PARM0)[0] = backupVelocity[0];
+                                       PRVM_G_VECTOR(OFS_PARM0)[1] = backupVelocity[1];
+                                       PRVM_G_VECTOR(OFS_PARM0)[2] = backupVelocity[2];
+                                       // Assign Self
+                                       PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
+                                       // Set Time
+                                       PRVM_serverglobalfloat(time) = sv.time;
                                        // Execute VM Function
-                                       PRVM_ExecuteProgram(PRVM_serveredictfunction(ent, movetypesteplandevent), "movetypesteplandevent: NULL function");
+                                       prog->ExecuteProgram(prog, PRVM_serveredictfunction(ent, movetypesteplandevent), "movetypesteplandevent: NULL function");
                                }
                                else
                                // Check for Engine Landing Sound
@@ -2821,6 +2829,7 @@ void SV_Physics_Step (prvm_edict_t *ent)
 
 static void SV_Physics_Entity (prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        // don't run think/move on newly spawned projectiles as it messes up
        // movement interpolation and rocket trails, and is inconsistent with
        // respect to entities spawned in the same frame
@@ -2886,6 +2895,7 @@ static void SV_Physics_Entity (prvm_edict_t *ent)
 
 void SV_Physics_ClientMove(void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        prvm_edict_t *ent;
        ent = host_client->edict;
 
@@ -2897,7 +2907,7 @@ void SV_Physics_ClientMove(void)
        PRVM_serverglobalfloat(time) = sv.time;
        PRVM_serverglobalfloat(frametime) = 0;
        PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
-       PRVM_ExecuteProgram (PRVM_serverfunction(PlayerPreThink), "QC function PlayerPreThink is missing");
+       prog->ExecuteProgram(prog, PRVM_serverfunction(PlayerPreThink), "QC function PlayerPreThink is missing");
        PRVM_serverglobalfloat(frametime) = sv.frametime;
 
        // make sure the velocity is sane (not a NaN)
@@ -2910,7 +2920,7 @@ void SV_Physics_ClientMove(void)
        PRVM_serverglobalfloat(time) = sv.time;
        PRVM_serverglobalfloat(frametime) = 0;
        PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
-       PRVM_ExecuteProgram (PRVM_serverfunction(PlayerPostThink), "QC function PlayerPostThink is missing");
+       prog->ExecuteProgram(prog, PRVM_serverfunction(PlayerPostThink), "QC function PlayerPostThink is missing");
        PRVM_serverglobalfloat(frametime) = sv.frametime;
 
        if(PRVM_serveredictfloat(ent, fixangle))
@@ -2927,6 +2937,7 @@ void SV_Physics_ClientMove(void)
 
 static void SV_Physics_ClientEntity_PreThink(prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        // don't do physics on disconnected clients, FrikBot relies on this
        if (!host_client->spawned)
                return;
@@ -2947,7 +2958,7 @@ static void SV_Physics_ClientEntity_PreThink(prvm_edict_t *ent)
        // call standard client pre-think
        PRVM_serverglobalfloat(time) = sv.time;
        PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
-       PRVM_ExecuteProgram(PRVM_serverfunction(PlayerPreThink), "QC function PlayerPreThink is missing");
+       prog->ExecuteProgram(prog, PRVM_serverfunction(PlayerPreThink), "QC function PlayerPreThink is missing");
 
        // make sure the velocity is still sane (not a NaN)
        SV_CheckVelocity(ent);
@@ -2955,6 +2966,7 @@ static void SV_Physics_ClientEntity_PreThink(prvm_edict_t *ent)
 
 static void SV_Physics_ClientEntity_PostThink(prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        // don't do physics on disconnected clients, FrikBot relies on this
        if (!host_client->spawned)
                return;
@@ -2965,7 +2977,7 @@ static void SV_Physics_ClientEntity_PostThink(prvm_edict_t *ent)
        // call standard player post-think
        PRVM_serverglobalfloat(time) = sv.time;
        PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
-       PRVM_ExecuteProgram(PRVM_serverfunction(PlayerPostThink), "QC function PlayerPostThink is missing");
+       prog->ExecuteProgram(prog, PRVM_serverfunction(PlayerPostThink), "QC function PlayerPostThink is missing");
 
        // make sure the velocity is still sane (not a NaN)
        SV_CheckVelocity(ent);
@@ -2991,6 +3003,7 @@ static void SV_Physics_ClientEntity_PostThink(prvm_edict_t *ent)
 
 static void SV_Physics_ClientEntity(prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = SVVM_prog;
        // don't do physics on disconnected clients, FrikBot relies on this
        if (!host_client->spawned)
        {
@@ -3067,6 +3080,7 @@ SV_Physics
 */
 void SV_Physics (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i;
        prvm_edict_t *ent;
 
@@ -3075,7 +3089,7 @@ void SV_Physics (void)
        PRVM_serverglobaledict(other) = PRVM_EDICT_TO_PROG(prog->edicts);
        PRVM_serverglobalfloat(time) = sv.time;
        PRVM_serverglobalfloat(frametime) = sv.frametime;
-       PRVM_ExecuteProgram (PRVM_serverfunction(StartFrame), "QC function StartFrame is missing");
+       prog->ExecuteProgram(prog, PRVM_serverfunction(StartFrame), "QC function StartFrame is missing");
 
        // run physics engine
        World_Physics_Frame(&sv.world, sv.frametime, sv_gravity.value);
@@ -3142,11 +3156,11 @@ void SV_Physics (void)
                PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(prog->edicts);
                PRVM_serverglobaledict(other) = PRVM_EDICT_TO_PROG(prog->edicts);
                PRVM_serverglobalfloat(time) = sv.time;
-               PRVM_ExecuteProgram (PRVM_serverfunction(EndFrame), "QC function EndFrame is missing");
+               prog->ExecuteProgram(prog, PRVM_serverfunction(EndFrame), "QC function EndFrame is missing");
        }
 
        // decrement prog->num_edicts if the highest number entities died
-       for (;PRVM_ED_CanAlloc(PRVM_EDICT_NUM(prog->num_edicts - 1));prog->num_edicts--);
+       for (;PRVM_ED_CanAlloc(prog, PRVM_EDICT_NUM(prog->num_edicts - 1));prog->num_edicts--);
 
        if (!sv_freezenonclients.integer)
                sv.time += sv.frametime;
index 431bdff0a67f68c1efe1693673adc66ec099906b..ce0b8e07d1b81c7d4c6045689ba7ce16088a8978 100644 (file)
--- a/sv_user.c
+++ b/sv_user.c
@@ -34,6 +34,7 @@ SV_SetIdealPitch
 #define        MAX_FORWARD     6
 void SV_SetIdealPitch (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        float   angleval, sinval, cosval, step, dir;
        trace_t tr;
        vec3_t  top, bottom;
@@ -108,8 +109,9 @@ SV_UserFriction
 
 ==================
 */
-void SV_UserFriction (void)
+static void SV_UserFriction (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        float speed, newspeed, control, friction;
        vec3_t start, stop;
        trace_t trace;
@@ -148,8 +150,9 @@ void SV_UserFriction (void)
 SV_Accelerate
 ==============
 */
-void SV_Accelerate (void)
+static void SV_Accelerate (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i;
        float addspeed, accelspeed, currentspeed;
 
@@ -166,8 +169,9 @@ void SV_Accelerate (void)
 }
 
 extern cvar_t sv_gameplayfix_q2airaccelerate;
-void SV_AirAccelerate (vec3_t wishveloc)
+static void SV_AirAccelerate (vec3_t wishveloc)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i;
        float addspeed, wishspd, accelspeed, currentspeed;
 
@@ -187,8 +191,9 @@ void SV_AirAccelerate (vec3_t wishveloc)
 }
 
 
-void DropPunchAngle (void)
+static void DropPunchAngle (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        float len;
        vec3_t v;
 
@@ -211,36 +216,15 @@ void DropPunchAngle (void)
        VectorCopy(v, PRVM_serveredictvector(host_client->edict, punchvector));
 }
 
-/*
-===================
-SV_FreeMove
-===================
-*/
-void SV_FreeMove (void)
-{
-       int i;
-       float wishspeed;
-
-       AngleVectors (PRVM_serveredictvector(host_client->edict, v_angle), forward, right, up);
-
-       for (i = 0; i < 3; i++)
-               PRVM_serveredictvector(host_client->edict, velocity)[i] = forward[i] * cmd.forwardmove + right[i] * cmd.sidemove;
-
-       PRVM_serveredictvector(host_client->edict, velocity)[2] += cmd.upmove;
-
-       wishspeed = VectorLength(PRVM_serveredictvector(host_client->edict, velocity));
-       if (wishspeed > sv_maxspeed.value)
-               VectorScale(PRVM_serveredictvector(host_client->edict, velocity), sv_maxspeed.value / wishspeed, PRVM_serveredictvector(host_client->edict, velocity));
-}
-
 /*
 ===================
 SV_WaterMove
 
 ===================
 */
-void SV_WaterMove (void)
+static void SV_WaterMove (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i;
        vec3_t wishvel;
        float speed, newspeed, wishspeed, addspeed, accelspeed, temp;
@@ -295,8 +279,9 @@ void SV_WaterMove (void)
                PRVM_serveredictvector(host_client->edict, velocity)[i] += accelspeed * wishvel[i];
 }
 
-void SV_WaterJump (void)
+static void SV_WaterJump (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        if (sv.time > PRVM_serveredictfloat(host_client->edict, teleport_time) || !PRVM_serveredictfloat(host_client->edict, waterlevel))
        {
                PRVM_serveredictfloat(host_client->edict, flags) = (int)PRVM_serveredictfloat(host_client->edict, flags) & ~FL_WATERJUMP;
@@ -313,8 +298,9 @@ SV_AirMove
 
 ===================
 */
-void SV_AirMove (void)
+static void SV_AirMove (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i;
        vec3_t wishvel;
        float fmove, smove, temp;
@@ -373,6 +359,7 @@ the angle fields specify an exact angular motion in degrees
 */
 void SV_ClientThink (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        vec3_t v_angle;
 
        //Con_Printf("clientthink for %ims\n", (int) (sv.frametime * 1000));
@@ -386,7 +373,7 @@ void SV_ClientThink (void)
        {
                PRVM_serverglobalfloat(time) = sv.time;
                PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict);
-               PRVM_ExecuteProgram (PRVM_serverfunction(SV_PlayerPhysics), "QC function SV_PlayerPhysics is missing");
+               prog->ExecuteProgram(prog, PRVM_serverfunction(SV_PlayerPhysics), "QC function SV_PlayerPhysics is missing");
                SV_CheckVelocity(host_client->edict);
                return;
        }
@@ -450,21 +437,22 @@ SV_ReadClientMove
 */
 int sv_numreadmoves = 0;
 usercmd_t sv_readmoves[CL_MAX_USERCMDS];
-void SV_ReadClientMove (void)
+static void SV_ReadClientMove (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int i;
        usercmd_t newmove;
        usercmd_t *move = &newmove;
 
        memset(move, 0, sizeof(*move));
 
-       if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
+       if (sv_message.badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
 
        // read ping time
        if (sv.protocol != PROTOCOL_QUAKE && sv.protocol != PROTOCOL_QUAKEDP && sv.protocol != PROTOCOL_NEHAHRAMOVIE && sv.protocol != PROTOCOL_NEHAHRABJP && sv.protocol != PROTOCOL_NEHAHRABJP2 && sv.protocol != PROTOCOL_NEHAHRABJP3 && sv.protocol != PROTOCOL_DARKPLACES1 && sv.protocol != PROTOCOL_DARKPLACES2 && sv.protocol != PROTOCOL_DARKPLACES3 && sv.protocol != PROTOCOL_DARKPLACES4 && sv.protocol != PROTOCOL_DARKPLACES5 && sv.protocol != PROTOCOL_DARKPLACES6)
-               move->sequence = MSG_ReadLong ();
-       move->time = move->clienttime = MSG_ReadFloat ();
-       if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
+               move->sequence = MSG_ReadLong(&sv_message);
+       move->time = move->clienttime = MSG_ReadFloat(&sv_message);
+       if (sv_message.badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
        move->receivetime = (float)sv.time;
 
 #if DEBUGMOVES
@@ -478,48 +466,48 @@ void SV_ReadClientMove (void)
        for (i = 0;i < 3;i++)
        {
                if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
-                       move->viewangles[i] = MSG_ReadAngle8i();
+                       move->viewangles[i] = MSG_ReadAngle8i(&sv_message);
                else if (sv.protocol == PROTOCOL_DARKPLACES1)
-                       move->viewangles[i] = MSG_ReadAngle16i();
+                       move->viewangles[i] = MSG_ReadAngle16i(&sv_message);
                else if (sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3)
-                       move->viewangles[i] = MSG_ReadAngle32f();
+                       move->viewangles[i] = MSG_ReadAngle32f(&sv_message);
                else
-                       move->viewangles[i] = MSG_ReadAngle16i();
+                       move->viewangles[i] = MSG_ReadAngle16i(&sv_message);
        }
-       if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
+       if (sv_message.badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
 
        // read movement
-       move->forwardmove = MSG_ReadCoord16i ();
-       move->sidemove = MSG_ReadCoord16i ();
-       move->upmove = MSG_ReadCoord16i ();
-       if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
+       move->forwardmove = MSG_ReadCoord16i(&sv_message);
+       move->sidemove = MSG_ReadCoord16i(&sv_message);
+       move->upmove = MSG_ReadCoord16i(&sv_message);
+       if (sv_message.badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
 
        // read buttons
        // be sure to bitwise OR them into the move->buttons because we want to
        // accumulate button presses from multiple packets per actual move
        if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3 || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
-               move->buttons = MSG_ReadByte ();
+               move->buttons = MSG_ReadByte(&sv_message);
        else
-               move->buttons = MSG_ReadLong ();
-       if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
+               move->buttons = MSG_ReadLong(&sv_message);
+       if (sv_message.badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
 
        // read impulse
-       move->impulse = MSG_ReadByte ();
-       if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
+       move->impulse = MSG_ReadByte(&sv_message);
+       if (sv_message.badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
 
        // PRYDON_CLIENTCURSOR
        if (sv.protocol != PROTOCOL_QUAKE && sv.protocol != PROTOCOL_QUAKEDP && sv.protocol != PROTOCOL_NEHAHRAMOVIE && sv.protocol != PROTOCOL_NEHAHRABJP && sv.protocol != PROTOCOL_NEHAHRABJP2 && sv.protocol != PROTOCOL_NEHAHRABJP3 && sv.protocol != PROTOCOL_DARKPLACES1 && sv.protocol != PROTOCOL_DARKPLACES2 && sv.protocol != PROTOCOL_DARKPLACES3 && sv.protocol != PROTOCOL_DARKPLACES4 && sv.protocol != PROTOCOL_DARKPLACES5)
        {
                // 30 bytes
-               move->cursor_screen[0] = MSG_ReadShort() * (1.0f / 32767.0f);
-               move->cursor_screen[1] = MSG_ReadShort() * (1.0f / 32767.0f);
-               move->cursor_start[0] = MSG_ReadFloat();
-               move->cursor_start[1] = MSG_ReadFloat();
-               move->cursor_start[2] = MSG_ReadFloat();
-               move->cursor_impact[0] = MSG_ReadFloat();
-               move->cursor_impact[1] = MSG_ReadFloat();
-               move->cursor_impact[2] = MSG_ReadFloat();
-               move->cursor_entitynumber = (unsigned short)MSG_ReadShort();
+               move->cursor_screen[0] = MSG_ReadShort(&sv_message) * (1.0f / 32767.0f);
+               move->cursor_screen[1] = MSG_ReadShort(&sv_message) * (1.0f / 32767.0f);
+               move->cursor_start[0] = MSG_ReadFloat(&sv_message);
+               move->cursor_start[1] = MSG_ReadFloat(&sv_message);
+               move->cursor_start[2] = MSG_ReadFloat(&sv_message);
+               move->cursor_impact[0] = MSG_ReadFloat(&sv_message);
+               move->cursor_impact[1] = MSG_ReadFloat(&sv_message);
+               move->cursor_impact[2] = MSG_ReadFloat(&sv_message);
+               move->cursor_entitynumber = (unsigned short)MSG_ReadShort(&sv_message);
                if (move->cursor_entitynumber >= prog->max_edicts)
                {
                        Con_DPrintf("SV_ReadClientMessage: client send bad cursor_entitynumber\n");
@@ -529,7 +517,7 @@ void SV_ReadClientMove (void)
                // entity is free at time of receipt
                if (PRVM_EDICT_NUM(move->cursor_entitynumber)->priv.server->free)
                        move->cursor_entitynumber = 0;
-               if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
+               if (sv_message.badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
        }
 
        // if the previous move has not been applied yet, we need to accumulate
@@ -576,8 +564,9 @@ void SV_ReadClientMove (void)
        }
 }
 
-void SV_ExecuteClientMoves(void)
+static void SV_ExecuteClientMoves(void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int moveindex;
        float moveframetime;
        double oldframetime;
@@ -705,6 +694,7 @@ void SV_ExecuteClientMoves(void)
 
 void SV_ApplyClientMove (void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        usercmd_t *move = &host_client->cmd;
        int j, movementloss, packetloss;
 
@@ -765,7 +755,7 @@ void SV_ApplyClientMove (void)
        PRVM_serveredictfloat(host_client->edict, ping_movementloss) = movementloss / (float) NETGRAPH_PACKETS;
 }
 
-void SV_FrameLost(int framenum)
+static void SV_FrameLost(int framenum)
 {
        if (host_client->entitydatabase5)
        {
@@ -774,7 +764,7 @@ void SV_FrameLost(int framenum)
        }
 }
 
-void SV_FrameAck(int framenum)
+static void SV_FrameAck(int framenum)
 {
        if (host_client->entitydatabase)
                EntityFrame_AckFrame(host_client->entitydatabase, framenum);
@@ -789,10 +779,9 @@ void SV_FrameAck(int framenum)
 SV_ReadClientMessage
 ===================
 */
-extern void SV_SendServerinfo(client_t *client);
-extern sizebuf_t vm_tempstringsbuf;
 void SV_ReadClientMessage(void)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int cmd, num, start;
        char *s, *p, *q;
 
@@ -811,14 +800,14 @@ void SV_ReadClientMessage(void)
                        return;
                }
 
-               if (msg_badread)
+               if (sv_message.badread)
                {
                        Con_Print("SV_ReadClientMessage: badread\n");
                        SV_DropClient (false);
                        return;
                }
 
-               cmd = MSG_ReadByte ();
+               cmd = MSG_ReadByte(&sv_message);
                if (cmd == -1)
                {
                        // end of message
@@ -830,9 +819,9 @@ void SV_ReadClientMessage(void)
                switch (cmd)
                {
                default:
-                       Con_Printf("SV_ReadClientMessage: unknown command char %i (at offset 0x%x)\n", cmd, msg_readcount);
+                       Con_Printf("SV_ReadClientMessage: unknown command char %i (at offset 0x%x)\n", cmd, sv_message.readcount);
                        if (developer_networking.integer)
-                               Com_HexDumpToConsole(net_message.data, net_message.cursize);
+                               Com_HexDumpToConsole(sv_message.data, sv_message.cursize);
                        SV_DropClient (false);
                        return;
 
@@ -843,7 +832,7 @@ void SV_ReadClientMessage(void)
                        // allow reliable messages now as the client is done with initial loading
                        if (host_client->sendsignon == 2)
                                host_client->sendsignon = 0;
-                       s = MSG_ReadString ();
+                       s = MSG_ReadString(&sv_message, sv_readstring, sizeof(sv_readstring));
                        q = NULL;
                        for(p = s; *p; ++p) switch(*p)
                        {
@@ -866,11 +855,12 @@ void SV_ReadClientMessage(void)
                        else if (PRVM_serverfunction(SV_ParseClientCommand))
                        {
                                int restorevm_tempstringsbuf_cursize;
-                               restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize;
-                               PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(s);
+                               restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize;
+                               PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, s);
+                               PRVM_serverglobalfloat(time) = sv.time;
                                PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict);
-                               PRVM_ExecuteProgram (PRVM_serverfunction(SV_ParseClientCommand), "QC function SV_ParseClientCommand is missing");
-                               vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
+                               prog->ExecuteProgram(prog, PRVM_serverfunction(SV_ParseClientCommand), "QC function SV_ParseClientCommand is missing");
+                               prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
                        }
                        else
                                Cmd_ExecuteString (s, src_client, true);
@@ -891,8 +881,8 @@ clc_stringcmd_invalid:
                        break;
 
                case clc_ackdownloaddata:
-                       start = MSG_ReadLong();
-                       num = MSG_ReadShort();
+                       start = MSG_ReadLong(&sv_message);
+                       num = MSG_ReadShort(&sv_message);
                        if (host_client->download_file && host_client->download_started)
                        {
                                if (host_client->download_expectedposition == start)
@@ -943,9 +933,9 @@ clc_stringcmd_invalid:
                        break;
 
                case clc_ackframe:
-                       if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
-                       num = MSG_ReadLong();
-                       if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
+                       if (sv_message.badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
+                       num = MSG_ReadLong(&sv_message);
+                       if (sv_message.badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
                        if (developer_networkentities.integer >= 10)
                                Con_Printf("recv clc_ackframe %i\n", num);
                        // if the client hasn't progressed through signons yet,
index acc1d184086680dbf371ad48f9262a26bae80342..39498eccf4940fda068e64aadd2f3c75fdc5135d 100644 (file)
@@ -230,7 +230,7 @@ This is the only valid way to move an object without using the physics of the wo
 setorigin (entity, origin)
 =================
 */
-static void VM_SV_setorigin (void)
+static void VM_SV_setorigin(prvm_prog_t *prog)
 {
        prvm_edict_t    *e;
        float   *org;
@@ -240,12 +240,12 @@ static void VM_SV_setorigin (void)
        e = PRVM_G_EDICT(OFS_PARM0);
        if (e == prog->edicts)
        {
-               VM_Warning("setorigin: can not modify world entity\n");
+               VM_Warning(prog, "setorigin: can not modify world entity\n");
                return;
        }
        if (e->priv.server->free)
        {
-               VM_Warning("setorigin: can not modify free entity\n");
+               VM_Warning(prog, "setorigin: can not modify free entity\n");
                return;
        }
        org = PRVM_G_VECTOR(OFS_PARM1);
@@ -254,13 +254,13 @@ static void VM_SV_setorigin (void)
 }
 
 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
-static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
+static void SetMinMaxSize (prvm_prog_t *prog, prvm_edict_t *e, float *min, float *max, qboolean rotate)
 {
        int             i;
 
        for (i=0 ; i<3 ; i++)
                if (min[i] > max[i])
-                       PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
+                       prog->error_cmd("SetMinMaxSize: backwards mins/maxs");
 
 // set derived values
        VectorCopy (min, PRVM_serveredictvector(e, mins));
@@ -280,7 +280,7 @@ LordHavoc: no it isn't...
 setsize (entity, minvector, maxvector)
 =================
 */
-static void VM_SV_setsize (void)
+static void VM_SV_setsize(prvm_prog_t *prog)
 {
        prvm_edict_t    *e;
        float   *min, *max;
@@ -290,17 +290,17 @@ static void VM_SV_setsize (void)
        e = PRVM_G_EDICT(OFS_PARM0);
        if (e == prog->edicts)
        {
-               VM_Warning("setsize: can not modify world entity\n");
+               VM_Warning(prog, "setsize: can not modify world entity\n");
                return;
        }
        if (e->priv.server->free)
        {
-               VM_Warning("setsize: can not modify free entity\n");
+               VM_Warning(prog, "setsize: can not modify free entity\n");
                return;
        }
        min = PRVM_G_VECTOR(OFS_PARM1);
        max = PRVM_G_VECTOR(OFS_PARM2);
-       SetMinMaxSize (e, min, max, false);
+       SetMinMaxSize(prog, e, min, max, false);
 }
 
 
@@ -312,7 +312,7 @@ setmodel(entity, model)
 =================
 */
 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
-static void VM_SV_setmodel (void)
+static void VM_SV_setmodel(prvm_prog_t *prog)
 {
        prvm_edict_t    *e;
        dp_model_t      *mod;
@@ -323,16 +323,16 @@ static void VM_SV_setmodel (void)
        e = PRVM_G_EDICT(OFS_PARM0);
        if (e == prog->edicts)
        {
-               VM_Warning("setmodel: can not modify world entity\n");
+               VM_Warning(prog, "setmodel: can not modify world entity\n");
                return;
        }
        if (e->priv.server->free)
        {
-               VM_Warning("setmodel: can not modify free entity\n");
+               VM_Warning(prog, "setmodel: can not modify free entity\n");
                return;
        }
        i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
-       PRVM_serveredictstring(e, model) = PRVM_SetEngineString(sv.model_precache[i]);
+       PRVM_serveredictstring(e, model) = PRVM_SetEngineString(prog, sv.model_precache[i]);
        PRVM_serveredictfloat(e, modelindex) = i;
 
        mod = SV_GetModelByIndex(i);
@@ -340,12 +340,12 @@ static void VM_SV_setmodel (void)
        if (mod)
        {
                if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
-                       SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
+                       SetMinMaxSize(prog, e, mod->normalmins, mod->normalmaxs, true);
                else
-                       SetMinMaxSize (e, quakemins, quakemaxs, true);
+                       SetMinMaxSize(prog, e, quakemins, quakemaxs, true);
        }
        else
-               SetMinMaxSize (e, vec3_origin, vec3_origin, true);
+               SetMinMaxSize(prog, e, vec3_origin, vec3_origin, true);
 }
 
 /*
@@ -357,16 +357,16 @@ single print to a specific client
 sprint(clientent, value)
 =================
 */
-static void VM_SV_sprint (void)
+static void VM_SV_sprint(prvm_prog_t *prog)
 {
        client_t        *client;
        int                     entnum;
        char string[VM_STRINGTEMP_LENGTH];
 
-       VM_VarString(1, string, sizeof(string));
-
        VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
 
+       VM_VarString(prog, 1, string, sizeof(string));
+
        entnum = PRVM_G_EDICTNUM(OFS_PARM0);
        // LordHavoc: div0 requested that sprintto world  operate like print
        if (entnum == 0)
@@ -377,7 +377,7 @@ static void VM_SV_sprint (void)
 
        if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
        {
-               VM_Warning("tried to centerprint to a non-client\n");
+               VM_Warning(prog, "tried to centerprint to a non-client\n");
                return;
        }
 
@@ -399,7 +399,7 @@ single print to a specific client
 centerprint(clientent, value)
 =================
 */
-static void VM_SV_centerprint (void)
+static void VM_SV_centerprint(prvm_prog_t *prog)
 {
        client_t        *client;
        int                     entnum;
@@ -411,7 +411,7 @@ static void VM_SV_centerprint (void)
 
        if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
        {
-               VM_Warning("tried to centerprint to a non-client\n");
+               VM_Warning(prog, "tried to centerprint to a non-client\n");
                return;
        }
 
@@ -419,7 +419,7 @@ static void VM_SV_centerprint (void)
        if (!client->netconnection)
                return;
 
-       VM_VarString(1, string, sizeof(string));
+       VM_VarString(prog, 1, string, sizeof(string));
        MSG_WriteChar(&client->netconnection->message,svc_centerprint);
        MSG_WriteString(&client->netconnection->message, string);
 }
@@ -431,7 +431,7 @@ VM_SV_particle
 particle(origin, color, count)
 =================
 */
-static void VM_SV_particle (void)
+static void VM_SV_particle(prvm_prog_t *prog)
 {
        float           *org, *dir;
        float           color;
@@ -453,7 +453,7 @@ VM_SV_ambientsound
 
 =================
 */
-static void VM_SV_ambientsound (void)
+static void VM_SV_ambientsound(prvm_prog_t *prog)
 {
        const char      *samp;
        float           *pos;
@@ -510,7 +510,7 @@ Larger attenuations will drop off.
 
 =================
 */
-static void VM_SV_sound (void)
+static void VM_SV_sound(prvm_prog_t *prog)
 {
        const char      *sample;
        int                     channel;
@@ -552,13 +552,13 @@ static void VM_SV_sound (void)
 
        if (volume < 0 || volume > 255)
        {
-               VM_Warning("SV_StartSound: volume must be in range 0-1\n");
+               VM_Warning(prog, "SV_StartSound: volume must be in range 0-1\n");
                return;
        }
 
        if (attenuation < 0 || attenuation > 4)
        {
-               VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
+               VM_Warning(prog, "SV_StartSound: attenuation must be in range 0-4\n");
                return;
        }
 
@@ -566,7 +566,7 @@ static void VM_SV_sound (void)
 
        if (!IS_CHAN(channel))
        {
-               VM_Warning("SV_StartSound: channel must be in range 0-127\n");
+               VM_Warning(prog, "SV_StartSound: channel must be in range 0-127\n");
                return;
        }
 
@@ -583,7 +583,7 @@ is omitted (since no entity is being tracked).
 
 =================
 */
-static void VM_SV_pointsound(void)
+static void VM_SV_pointsound(prvm_prog_t *prog)
 {
        const char      *sample;
        int             volume;
@@ -601,13 +601,13 @@ static void VM_SV_pointsound(void)
 
        if (volume < 0 || volume > 255)
        {
-               VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
+               VM_Warning(prog, "SV_StartPointSound: volume must be in range 0-1\n");
                return;
        }
 
        if (attenuation < 0 || attenuation > 4)
        {
-               VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
+               VM_Warning(prog, "SV_StartPointSound: attenuation must be in range 0-4\n");
                return;
        }
 
@@ -625,7 +625,7 @@ if the tryents flag is set.
 traceline (vector1, vector2, movetype, ignore)
 =================
 */
-static void VM_SV_traceline (void)
+static void VM_SV_traceline(prvm_prog_t *prog)
 {
        float   *v1, *v2;
        trace_t trace;
@@ -642,11 +642,11 @@ static void VM_SV_traceline (void)
        ent = PRVM_G_EDICT(OFS_PARM3);
 
        if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v2[1]) || IS_NAN(v2[2]))
-               PRVM_ERROR("%s: NAN errors detected in traceline('%f %f %f', '%f %f %f', %i, entity %i)\n", PRVM_NAME, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
+               prog->error_cmd("%s: NAN errors detected in traceline('%f %f %f', '%f %f %f', %i, entity %i)\n", prog->name, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
 
        trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
 
-       VM_SetTraceGlobals(&trace);
+       VM_SetTraceGlobals(prog, &trace);
 }
 
 
@@ -662,7 +662,7 @@ tracebox (vector1, vector mins, vector maxs, vector2, tryents)
 =================
 */
 // LordHavoc: added this for my own use, VERY useful, similar to traceline
-static void VM_SV_tracebox (void)
+static void VM_SV_tracebox(prvm_prog_t *prog)
 {
        float   *v1, *v2, *m1, *m2;
        trace_t trace;
@@ -681,14 +681,14 @@ static void VM_SV_tracebox (void)
        ent = PRVM_G_EDICT(OFS_PARM5);
 
        if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v2[1]) || IS_NAN(v2[2]))
-               PRVM_ERROR("%s: NAN errors detected in tracebox('%f %f %f', '%f %f %f', '%f %f %f', '%f %f %f', %i, entity %i)\n", PRVM_NAME, v1[0], v1[1], v1[2], m1[0], m1[1], m1[2], m2[0], m2[1], m2[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
+               prog->error_cmd("%s: NAN errors detected in tracebox('%f %f %f', '%f %f %f', '%f %f %f', '%f %f %f', %i, entity %i)\n", prog->name, v1[0], v1[1], v1[2], m1[0], m1[1], m1[2], m2[0], m2[1], m2[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
 
        trace = SV_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
 
-       VM_SetTraceGlobals(&trace);
+       VM_SetTraceGlobals(prog, &trace);
 }
 
-static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
+static trace_t SV_Trace_Toss(prvm_prog_t *prog, prvm_edict_t *tossent, prvm_edict_t *ignore)
 {
        int i;
        float gravity;
@@ -732,7 +732,7 @@ static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
        return trace;
 }
 
-static void VM_SV_tracetoss (void)
+static void VM_SV_tracetoss(prvm_prog_t *prog)
 {
        trace_t trace;
        prvm_edict_t    *ent;
@@ -745,14 +745,14 @@ static void VM_SV_tracetoss (void)
        ent = PRVM_G_EDICT(OFS_PARM0);
        if (ent == prog->edicts)
        {
-               VM_Warning("tracetoss: can not use world entity\n");
+               VM_Warning(prog, "tracetoss: can not use world entity\n");
                return;
        }
        ignore = PRVM_G_EDICT(OFS_PARM1);
 
-       trace = SV_Trace_Toss (ent, ignore);
+       trace = SV_Trace_Toss(prog, ent, ignore);
 
-       VM_SetTraceGlobals(&trace);
+       VM_SetTraceGlobals(prog, &trace);
 }
 
 //============================================================================
@@ -760,7 +760,7 @@ static void VM_SV_tracetoss (void)
 static int checkpvsbytes;
 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
 
-static int VM_SV_newcheckclient (int check)
+static int VM_SV_newcheckclient(prvm_prog_t *prog, int check)
 {
        int             i;
        prvm_edict_t    *ent;
@@ -815,7 +815,7 @@ name checkclient ()
 =================
 */
 int c_invis, c_notvis;
-static void VM_SV_checkclient (void)
+static void VM_SV_checkclient(prvm_prog_t *prog)
 {
        prvm_edict_t    *ent, *self;
        vec3_t  view;
@@ -825,7 +825,7 @@ static void VM_SV_checkclient (void)
        // find a new check if on a new frame
        if (sv.time - sv.lastchecktime >= 0.1)
        {
-               sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
+               sv.lastcheck = VM_SV_newcheckclient(prog, sv.lastcheck);
                sv.lastchecktime = sv.time;
        }
 
@@ -864,7 +864,7 @@ Should be fast but can be inexact.
 float checkpvs(vector viewpos, entity viewee) = #240;
 =================
 */
-static void VM_SV_checkpvs (void)
+static void VM_SV_checkpvs(prvm_prog_t *prog)
 {
        vec3_t viewpos;
        prvm_edict_t *viewee;
@@ -881,7 +881,7 @@ static void VM_SV_checkpvs (void)
 
        if(viewee->priv.server->free)
        {
-               VM_Warning("checkpvs: can not check free entity\n");
+               VM_Warning(prog, "checkpvs: can not check free entity\n");
                PRVM_G_FLOAT(OFS_RETURN) = 4;
                return;
        }
@@ -930,7 +930,7 @@ Sends text over to the client's execution buffer
 stuffcmd (clientent, value, ...)
 =================
 */
-static void VM_SV_stuffcmd (void)
+static void VM_SV_stuffcmd(prvm_prog_t *prog)
 {
        int             entnum;
        client_t        *old;
@@ -941,11 +941,11 @@ static void VM_SV_stuffcmd (void)
        entnum = PRVM_G_EDICTNUM(OFS_PARM0);
        if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
        {
-               VM_Warning("Can't stuffcmd to a non-client\n");
+               VM_Warning(prog, "Can't stuffcmd to a non-client\n");
                return;
        }
 
-       VM_VarString(1, string, sizeof(string));
+       VM_VarString(prog, 1, string, sizeof(string));
 
        old = host_client;
        host_client = svs.clients + entnum-1;
@@ -962,7 +962,7 @@ Returns a chain of entities that have origins within a spherical area
 findradius (origin, radius)
 =================
 */
-static void VM_SV_findradius (void)
+static void VM_SV_findradius(prvm_prog_t *prog)
 {
        prvm_edict_t *ent, *chain;
        vec_t radius, radius2;
@@ -979,7 +979,7 @@ static void VM_SV_findradius (void)
        else
                chainfield = prog->fieldoffsets.chain;
        if (chainfield < 0)
-               PRVM_ERROR("VM_findchain: %s doesnt have the specified chain field !", PRVM_NAME);
+               prog->error_cmd("VM_findchain: %s doesnt have the specified chain field !", prog->name);
 
        chain = (prvm_edict_t *)prog->edicts;
 
@@ -1030,13 +1030,13 @@ static void VM_SV_findradius (void)
        VM_RETURN_EDICT(chain);
 }
 
-static void VM_SV_precache_sound (void)
+static void VM_SV_precache_sound(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
        PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
 }
 
-static void VM_SV_precache_model (void)
+static void VM_SV_precache_model(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
        SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
@@ -1050,7 +1050,7 @@ VM_SV_walkmove
 float(float yaw, float dist[, settrace]) walkmove
 ===============
 */
-static void VM_SV_walkmove (void)
+static void VM_SV_walkmove(prvm_prog_t *prog)
 {
        prvm_edict_t    *ent;
        float   yaw, dist;
@@ -1067,12 +1067,12 @@ static void VM_SV_walkmove (void)
        ent = PRVM_PROG_TO_EDICT(PRVM_serverglobaledict(self));
        if (ent == prog->edicts)
        {
-               VM_Warning("walkmove: can not modify world entity\n");
+               VM_Warning(prog, "walkmove: can not modify world entity\n");
                return;
        }
        if (ent->priv.server->free)
        {
-               VM_Warning("walkmove: can not modify free entity\n");
+               VM_Warning(prog, "walkmove: can not modify free entity\n");
                return;
        }
        yaw = PRVM_G_FLOAT(OFS_PARM0);
@@ -1108,7 +1108,7 @@ void() droptofloor
 ===============
 */
 
-static void VM_SV_droptofloor (void)
+static void VM_SV_droptofloor(prvm_prog_t *prog)
 {
        prvm_edict_t            *ent;
        vec3_t          end;
@@ -1122,12 +1122,12 @@ static void VM_SV_droptofloor (void)
        ent = PRVM_PROG_TO_EDICT(PRVM_serverglobaledict(self));
        if (ent == prog->edicts)
        {
-               VM_Warning("droptofloor: can not modify world entity\n");
+               VM_Warning(prog, "droptofloor: can not modify world entity\n");
                return;
        }
        if (ent->priv.server->free)
        {
-               VM_Warning("droptofloor: can not modify free entity\n");
+               VM_Warning(prog, "droptofloor: can not modify free entity\n");
                return;
        }
 
@@ -1193,7 +1193,7 @@ VM_SV_lightstyle
 void(float style, string value) lightstyle
 ===============
 */
-static void VM_SV_lightstyle (void)
+static void VM_SV_lightstyle(prvm_prog_t *prog)
 {
        int             style;
        const char      *val;
@@ -1206,7 +1206,7 @@ static void VM_SV_lightstyle (void)
        val = PRVM_G_STRING(OFS_PARM1);
 
        if( (unsigned) style >= MAX_LIGHTSTYLES ) {
-               PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
+               prog->error_cmd( "PF_lightstyle: style: %i >= 64", style );
        }
 
 // change the string in sv
@@ -1232,7 +1232,7 @@ static void VM_SV_lightstyle (void)
 VM_SV_checkbottom
 =============
 */
-static void VM_SV_checkbottom (void)
+static void VM_SV_checkbottom(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
        PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
@@ -1243,7 +1243,7 @@ static void VM_SV_checkbottom (void)
 VM_SV_pointcontents
 =============
 */
-static void VM_SV_pointcontents (void)
+static void VM_SV_pointcontents(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
        PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
@@ -1257,7 +1257,7 @@ Pick a vector for the player to shoot along
 vector aim(entity, missilespeed)
 =============
 */
-static void VM_SV_aim (void)
+static void VM_SV_aim(prvm_prog_t *prog)
 {
        prvm_edict_t    *ent, *check, *bestent;
        vec3_t  start, dir, end, bestdir;
@@ -1277,12 +1277,12 @@ static void VM_SV_aim (void)
        ent = PRVM_G_EDICT(OFS_PARM0);
        if (ent == prog->edicts)
        {
-               VM_Warning("aim: can not use world entity\n");
+               VM_Warning(prog, "aim: can not use world entity\n");
                return;
        }
        if (ent->priv.server->free)
        {
-               VM_Warning("aim: can not use free entity\n");
+               VM_Warning(prog, "aim: can not use free entity\n");
                return;
        }
        //speed = PRVM_G_FLOAT(OFS_PARM1);
@@ -1362,7 +1362,7 @@ MESSAGE WRITING
 #define        MSG_INIT                3               // write to the init string
 #define        MSG_ENTITY              5
 
-sizebuf_t *WriteDest (void)
+static sizebuf_t *WriteDest(prvm_prog_t *prog)
 {
        int             entnum;
        int             dest;
@@ -1379,14 +1379,14 @@ sizebuf_t *WriteDest (void)
                entnum = PRVM_NUM_FOR_EDICT(ent);
                if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
                {
-                       VM_Warning ("WriteDest: tried to write to non-client\n");
+                       VM_Warning(prog, "WriteDest: tried to write to non-client\n");
                        return &sv.reliable_datagram;
                }
                else
                        return &svs.clients[entnum-1].netconnection->message;
 
        default:
-               VM_Warning ("WriteDest: bad destination\n");
+               VM_Warning(prog, "WriteDest: bad destination\n");
        case MSG_ALL:
                return &sv.reliable_datagram;
 
@@ -1400,59 +1400,59 @@ sizebuf_t *WriteDest (void)
        //return NULL;
 }
 
-static void VM_SV_WriteByte (void)
+static void VM_SV_WriteByte(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
-       MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
+       MSG_WriteByte (WriteDest(prog), (int)PRVM_G_FLOAT(OFS_PARM1));
 }
 
-static void VM_SV_WriteChar (void)
+static void VM_SV_WriteChar(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
-       MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
+       MSG_WriteChar (WriteDest(prog), (int)PRVM_G_FLOAT(OFS_PARM1));
 }
 
-static void VM_SV_WriteShort (void)
+static void VM_SV_WriteShort(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
-       MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
+       MSG_WriteShort (WriteDest(prog), (int)PRVM_G_FLOAT(OFS_PARM1));
 }
 
-static void VM_SV_WriteLong (void)
+static void VM_SV_WriteLong(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
-       MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
+       MSG_WriteLong (WriteDest(prog), (int)PRVM_G_FLOAT(OFS_PARM1));
 }
 
-static void VM_SV_WriteAngle (void)
+static void VM_SV_WriteAngle(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
-       MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
+       MSG_WriteAngle (WriteDest(prog), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
 }
 
-static void VM_SV_WriteCoord (void)
+static void VM_SV_WriteCoord(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
-       MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
+       MSG_WriteCoord (WriteDest(prog), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
 }
 
-static void VM_SV_WriteString (void)
+static void VM_SV_WriteString(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
-       MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
+       MSG_WriteString (WriteDest(prog), PRVM_G_STRING(OFS_PARM1));
 }
 
-static void VM_SV_WriteUnterminatedString (void)
+static void VM_SV_WriteUnterminatedString(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
-       MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
+       MSG_WriteUnterminatedString (WriteDest(prog), PRVM_G_STRING(OFS_PARM1));
 }
 
 
-static void VM_SV_WriteEntity (void)
+static void VM_SV_WriteEntity(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
-       MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
+       MSG_WriteShort (WriteDest(prog), PRVM_G_EDICTNUM(OFS_PARM1));
 }
 
 // writes a picture as at most size bytes of data
@@ -1461,7 +1461,7 @@ static void VM_SV_WriteEntity (void)
 // if failed to read/compress:
 //   IMGNAME \0 \0 \0
 //#501 void(float dest, string name, float maxsize) WritePicture (DP_SV_WRITEPICTURE))
-static void VM_SV_WritePicture (void)
+static void VM_SV_WritePicture(prvm_prog_t *prog)
 {
        const char *imgname;
        void *buf;
@@ -1474,23 +1474,23 @@ static void VM_SV_WritePicture (void)
        if(size > 65535)
                size = 65535;
 
-       MSG_WriteString(WriteDest(), imgname);
+       MSG_WriteString(WriteDest(prog), imgname);
        if(Image_Compress(imgname, size, &buf, &size))
        {
                // actual picture
-               MSG_WriteShort(WriteDest(), size);
-               SZ_Write(WriteDest(), (unsigned char *) buf, size);
+               MSG_WriteShort(WriteDest(prog), size);
+               SZ_Write(WriteDest(prog), (unsigned char *) buf, size);
        }
        else
        {
                // placeholder
-               MSG_WriteShort(WriteDest(), 0);
+               MSG_WriteShort(WriteDest(prog), 0);
        }
 }
 
 //////////////////////////////////////////////////////////
 
-static void VM_SV_makestatic (void)
+static void VM_SV_makestatic(prvm_prog_t *prog)
 {
        prvm_edict_t *ent;
        int i, large;
@@ -1505,12 +1505,12 @@ static void VM_SV_makestatic (void)
                ent = PRVM_PROG_TO_EDICT(PRVM_serverglobaledict(self));
        if (ent == prog->edicts)
        {
-               VM_Warning("makestatic: can not modify world entity\n");
+               VM_Warning(prog, "makestatic: can not modify world entity\n");
                return;
        }
        if (ent->priv.server->free)
        {
-               VM_Warning("makestatic: can not modify free entity\n");
+               VM_Warning(prog, "makestatic: can not modify free entity\n");
                return;
        }
 
@@ -1546,7 +1546,7 @@ static void VM_SV_makestatic (void)
        }
 
 // throw the entity away now
-       PRVM_ED_Free (ent);
+       PRVM_ED_Free(prog, ent);
 }
 
 //=============================================================================
@@ -1556,7 +1556,7 @@ static void VM_SV_makestatic (void)
 VM_SV_setspawnparms
 ==============
 */
-static void VM_SV_setspawnparms (void)
+static void VM_SV_setspawnparms(prvm_prog_t *prog)
 {
        prvm_edict_t    *ent;
        int             i;
@@ -1590,7 +1590,7 @@ Returns a color vector indicating the lighting at the requested point.
 getlight(vector)
 =================
 */
-static void VM_SV_getlight (void)
+static void VM_SV_getlight(prvm_prog_t *prog)
 {
        vec3_t ambientcolor, diffusecolor, diffusenormal;
        vec_t *p;
@@ -1625,6 +1625,7 @@ void VM_CustomStats_Clear (void)
 
 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
 {
+       prvm_prog_t *prog = SVVM_prog;
        int                     i;
        char            s[17];
 
@@ -1667,7 +1668,7 @@ void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *ms
 //          1: string (4 stats carrying a total of 16 charactures)
 //          2: float (one stat, float converted to an integer for transportation)
 //          8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
-static void VM_SV_AddStat (void)
+static void VM_SV_AddStat(prvm_prog_t *prog)
 {
        int             off, i;
        unsigned char   type;
@@ -1679,7 +1680,7 @@ static void VM_SV_AddStat (void)
                vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
                if(!vm_customstats)
                {
-                       VM_Warning("PF_SV_AddStat: not enough memory\n");
+                       VM_Warning(prog, "PF_SV_AddStat: not enough memory\n");
                        return;
                }
        }
@@ -1690,17 +1691,17 @@ static void VM_SV_AddStat (void)
 
        if(i < 0)
        {
-               VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
+               VM_Warning(prog, "PF_SV_AddStat: index may not be less than 32\n");
                return;
        }
        if(i >= (MAX_CL_STATS-32))
        {
-               VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
+               VM_Warning(prog, "PF_SV_AddStat: index >= MAX_CL_STATS\n");
                return;
        }
        if(i > (MAX_CL_STATS-32-4) && type == 1)
        {
-               VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
+               VM_Warning(prog, "PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
                return;
        }
        vm_customstats[i].type          = type;
@@ -1718,30 +1719,30 @@ copies data from one entity to another
 copyentity(src, dst)
 =================
 */
-static void VM_SV_copyentity (void)
+static void VM_SV_copyentity(prvm_prog_t *prog)
 {
        prvm_edict_t *in, *out;
        VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
        in = PRVM_G_EDICT(OFS_PARM0);
        if (in == prog->edicts)
        {
-               VM_Warning("copyentity: can not read world entity\n");
+               VM_Warning(prog, "copyentity: can not read world entity\n");
                return;
        }
        if (in->priv.server->free)
        {
-               VM_Warning("copyentity: can not read free entity\n");
+               VM_Warning(prog, "copyentity: can not read free entity\n");
                return;
        }
        out = PRVM_G_EDICT(OFS_PARM1);
        if (out == prog->edicts)
        {
-               VM_Warning("copyentity: can not modify world entity\n");
+               VM_Warning(prog, "copyentity: can not modify world entity\n");
                return;
        }
        if (out->priv.server->free)
        {
-               VM_Warning("copyentity: can not modify free entity\n");
+               VM_Warning(prog, "copyentity: can not modify free entity\n");
                return;
        }
        memcpy(out->fields.vp, in->fields.vp, prog->entityfields * 4);
@@ -1758,7 +1759,7 @@ sets the color of a client and broadcasts the update to all connected clients
 setcolor(clientent, value)
 =================
 */
-static void VM_SV_setcolor (void)
+static void VM_SV_setcolor(prvm_prog_t *prog)
 {
        client_t *client;
        int entnum, i;
@@ -1797,7 +1798,7 @@ VM_SV_effect
 effect(origin, modelname, startframe, framecount, framerate)
 =================
 */
-static void VM_SV_effect (void)
+static void VM_SV_effect(prvm_prog_t *prog)
 {
        int i;
        const char *s;
@@ -1805,33 +1806,33 @@ static void VM_SV_effect (void)
        s = PRVM_G_STRING(OFS_PARM1);
        if (!s[0])
        {
-               VM_Warning("effect: no model specified\n");
+               VM_Warning(prog, "effect: no model specified\n");
                return;
        }
 
        i = SV_ModelIndex(s, 1);
        if (!i)
        {
-               VM_Warning("effect: model not precached\n");
+               VM_Warning(prog, "effect: model not precached\n");
                return;
        }
 
        if (PRVM_G_FLOAT(OFS_PARM3) < 1)
        {
-               VM_Warning("effect: framecount < 1\n");
+               VM_Warning(prog, "effect: framecount < 1\n");
                return;
        }
 
        if (PRVM_G_FLOAT(OFS_PARM4) < 1)
        {
-               VM_Warning("effect: framerate < 1\n");
+               VM_Warning(prog, "effect: framerate < 1\n");
                return;
        }
 
        SV_StartEffect(PRVM_G_VECTOR(OFS_PARM0), i, (int)PRVM_G_FLOAT(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4));
 }
 
-static void VM_SV_te_blood (void)
+static void VM_SV_te_blood(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
        if (PRVM_G_FLOAT(OFS_PARM2) < 1)
@@ -1851,7 +1852,7 @@ static void VM_SV_te_blood (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_bloodshower (void)
+static void VM_SV_te_bloodshower(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
        if (PRVM_G_FLOAT(OFS_PARM3) < 1)
@@ -1873,7 +1874,7 @@ static void VM_SV_te_bloodshower (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_explosionrgb (void)
+static void VM_SV_te_explosionrgb(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -1889,7 +1890,7 @@ static void VM_SV_te_explosionrgb (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_particlecube (void)
+static void VM_SV_te_particlecube(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
        if (PRVM_G_FLOAT(OFS_PARM3) < 1)
@@ -1919,7 +1920,7 @@ static void VM_SV_te_particlecube (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_particlerain (void)
+static void VM_SV_te_particlerain(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
        if (PRVM_G_FLOAT(OFS_PARM3) < 1)
@@ -1945,7 +1946,7 @@ static void VM_SV_te_particlerain (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_particlesnow (void)
+static void VM_SV_te_particlesnow(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
        if (PRVM_G_FLOAT(OFS_PARM3) < 1)
@@ -1971,7 +1972,7 @@ static void VM_SV_te_particlesnow (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_spark (void)
+static void VM_SV_te_spark(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
        if (PRVM_G_FLOAT(OFS_PARM2) < 1)
@@ -1991,7 +1992,7 @@ static void VM_SV_te_spark (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_gunshotquad (void)
+static void VM_SV_te_gunshotquad(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -2003,7 +2004,7 @@ static void VM_SV_te_gunshotquad (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_spikequad (void)
+static void VM_SV_te_spikequad(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -2015,7 +2016,7 @@ static void VM_SV_te_spikequad (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_superspikequad (void)
+static void VM_SV_te_superspikequad(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -2027,7 +2028,7 @@ static void VM_SV_te_superspikequad (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_explosionquad (void)
+static void VM_SV_te_explosionquad(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -2039,7 +2040,7 @@ static void VM_SV_te_explosionquad (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_smallflash (void)
+static void VM_SV_te_smallflash(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -2051,7 +2052,7 @@ static void VM_SV_te_smallflash (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_customflash (void)
+static void VM_SV_te_customflash(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
        if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
@@ -2073,7 +2074,7 @@ static void VM_SV_te_customflash (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_gunshot (void)
+static void VM_SV_te_gunshot(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -2085,7 +2086,7 @@ static void VM_SV_te_gunshot (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_spike (void)
+static void VM_SV_te_spike(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -2097,7 +2098,7 @@ static void VM_SV_te_spike (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_superspike (void)
+static void VM_SV_te_superspike(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -2109,7 +2110,7 @@ static void VM_SV_te_superspike (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_explosion (void)
+static void VM_SV_te_explosion(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -2121,7 +2122,7 @@ static void VM_SV_te_explosion (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_tarexplosion (void)
+static void VM_SV_te_tarexplosion(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -2133,7 +2134,7 @@ static void VM_SV_te_tarexplosion (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_wizspike (void)
+static void VM_SV_te_wizspike(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -2145,7 +2146,7 @@ static void VM_SV_te_wizspike (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_knightspike (void)
+static void VM_SV_te_knightspike(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -2157,7 +2158,7 @@ static void VM_SV_te_knightspike (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_lavasplash (void)
+static void VM_SV_te_lavasplash(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -2169,7 +2170,7 @@ static void VM_SV_te_lavasplash (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_teleport (void)
+static void VM_SV_te_teleport(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -2181,7 +2182,7 @@ static void VM_SV_te_teleport (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_explosion2 (void)
+static void VM_SV_te_explosion2(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -2196,7 +2197,7 @@ static void VM_SV_te_explosion2 (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_lightning1 (void)
+static void VM_SV_te_lightning1(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -2214,7 +2215,7 @@ static void VM_SV_te_lightning1 (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_lightning2 (void)
+static void VM_SV_te_lightning2(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -2232,7 +2233,7 @@ static void VM_SV_te_lightning2 (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_lightning3 (void)
+static void VM_SV_te_lightning3(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -2250,7 +2251,7 @@ static void VM_SV_te_lightning3 (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_beam (void)
+static void VM_SV_te_beam(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -2268,7 +2269,7 @@ static void VM_SV_te_beam (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_plasmaburn (void)
+static void VM_SV_te_plasmaburn(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -2279,7 +2280,7 @@ static void VM_SV_te_plasmaburn (void)
        SV_FlushBroadcastMessages();
 }
 
-static void VM_SV_te_flamejet (void)
+static void VM_SV_te_flamejet(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
@@ -2299,7 +2300,7 @@ static void VM_SV_te_flamejet (void)
 
 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
 //this function originally written by KrimZon, made shorter by LordHavoc
-static void VM_SV_clientcommand (void)
+static void VM_SV_clientcommand(prvm_prog_t *prog)
 {
        client_t *temp_client;
        int i;
@@ -2320,7 +2321,7 @@ static void VM_SV_clientcommand (void)
 }
 
 //void(entity e, entity tagentity, string tagname) setattachment = #443; // attachs e to a tag on tagentity (note: use "" to attach to entity origin/angles instead of a tag)
-static void VM_SV_setattachment (void)
+static void VM_SV_setattachment(prvm_prog_t *prog)
 {
        prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
        prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
@@ -2331,12 +2332,12 @@ static void VM_SV_setattachment (void)
 
        if (e == prog->edicts)
        {
-               VM_Warning("setattachment: can not modify world entity\n");
+               VM_Warning(prog, "setattachment: can not modify world entity\n");
                return;
        }
        if (e->priv.server->free)
        {
-               VM_Warning("setattachment: can not modify free entity\n");
+               VM_Warning(prog, "setattachment: can not modify free entity\n");
                return;
        }
 
@@ -2365,7 +2366,7 @@ static void VM_SV_setattachment (void)
 /////////////////////////////////////////
 // DP_MD3_TAGINFO extension coded by VorteX
 
-int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
+static int SV_GetTagIndex (prvm_prog_t *prog, prvm_edict_t *e, const char *tagname)
 {
        int i;
 
@@ -2376,7 +2377,7 @@ int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
        return Mod_Alias_GetTagIndexForName(SV_GetModelByIndex(i), (int)PRVM_serveredictfloat(e, skin), tagname);
 }
 
-int SV_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
+static int SV_GetExtendedTagInfo (prvm_prog_t *prog, prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
 {
        int r;
        dp_model_t *model;
@@ -2398,7 +2399,7 @@ int SV_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, cons
        return 1;
 }
 
-void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
+void SV_GetEntityMatrix (prvm_prog_t *prog, prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
 {
        float scale;
        float pitchsign = 1;
@@ -2411,19 +2412,19 @@ void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatri
                Matrix4x4_CreateFromQuakeEntity(out, PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2] + PRVM_serveredictvector(ent, view_ofs)[2], PRVM_serveredictvector(ent, v_angle)[0], PRVM_serveredictvector(ent, v_angle)[1], PRVM_serveredictvector(ent, v_angle)[2], scale * cl_viewmodel_scale.value);
        else
        {
-               pitchsign = SV_GetPitchSign(ent);
+               pitchsign = SV_GetPitchSign(prog, ent);
                Matrix4x4_CreateFromQuakeEntity(out, PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2], pitchsign * PRVM_serveredictvector(ent, angles)[0], PRVM_serveredictvector(ent, angles)[1], PRVM_serveredictvector(ent, angles)[2], scale);
        }
 }
 
-int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
+static int SV_GetEntityLocalTagMatrix(prvm_prog_t *prog, prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
 {
        dp_model_t *model;
        if (tagindex >= 0 && (model = SV_GetModelFromEdict(ent)) && model->animscenes)
        {
-               VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
+               VM_GenerateFrameGroupBlend(prog, ent->priv.server->framegroupblend, ent);
                VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
-               VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
+               VM_UpdateEdictSkeleton(prog, ent, model, ent->priv.server->frameblend);
                return Mod_Alias_GetTagMatrix(model, ent->priv.server->frameblend, &ent->priv.server->skeleton, tagindex, out);
        }
        *out = identitymatrix;
@@ -2440,7 +2441,7 @@ int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out
 extern cvar_t cl_bob;
 extern cvar_t cl_bobcycle;
 extern cvar_t cl_bobup;
-int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
+static int SV_GetTagMatrix (prvm_prog_t *prog, matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
 {
        int ret;
        int modelindex, attachloop;
@@ -2460,9 +2461,9 @@ int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
 
        model = SV_GetModelByIndex(modelindex);
 
-       VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
+       VM_GenerateFrameGroupBlend(prog, ent->priv.server->framegroupblend, ent);
        VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
-       VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
+       VM_UpdateEdictSkeleton(prog, ent, model, ent->priv.server->frameblend);
 
        tagmatrix = identitymatrix;
        // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
@@ -2473,10 +2474,10 @@ int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
                        return 5;
                // apply transformation by child's tagindex on parent entity and then
                // by parent entity itself
-               ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
+               ret = SV_GetEntityLocalTagMatrix(prog, ent, tagindex - 1, &attachmatrix);
                if (ret && attachloop == 0)
                        return ret;
-               SV_GetEntityMatrix(ent, &entitymatrix, false);
+               SV_GetEntityMatrix(prog, ent, &entitymatrix, false);
                Matrix4x4_Concat(&tagmatrix, &attachmatrix, out);
                Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
                // next iteration we process the parent entity
@@ -2496,7 +2497,7 @@ int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
                Matrix4x4_Copy(&tagmatrix, out);
                ent = PRVM_EDICT_NUM(PRVM_serveredictedict(ent, viewmodelforclient));
 
-               SV_GetEntityMatrix(ent, &entitymatrix, true);
+               SV_GetEntityMatrix(prog, ent, &entitymatrix, true);
                Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
 
                /*
@@ -2527,7 +2528,7 @@ int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
 
 //float(entity ent, string tagname) gettagindex;
 
-static void VM_SV_gettagindex (void)
+static void VM_SV_gettagindex(prvm_prog_t *prog)
 {
        prvm_edict_t *ent;
        const char *tag_name;
@@ -2540,12 +2541,12 @@ static void VM_SV_gettagindex (void)
 
        if (ent == prog->edicts)
        {
-               VM_Warning("VM_SV_gettagindex(entity #%i): can't affect world entity\n", PRVM_NUM_FOR_EDICT(ent));
+               VM_Warning(prog, "VM_SV_gettagindex(entity #%i): can't affect world entity\n", PRVM_NUM_FOR_EDICT(ent));
                return;
        }
        if (ent->priv.server->free)
        {
-               VM_Warning("VM_SV_gettagindex(entity #%i): can't affect free entity\n", PRVM_NUM_FOR_EDICT(ent));
+               VM_Warning(prog, "VM_SV_gettagindex(entity #%i): can't affect free entity\n", PRVM_NUM_FOR_EDICT(ent));
                return;
        }
 
@@ -2554,7 +2555,7 @@ static void VM_SV_gettagindex (void)
                Con_DPrintf("VM_SV_gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
        else
        {
-               tag_index = SV_GetTagIndex(ent, tag_name);
+               tag_index = SV_GetTagIndex(prog, ent, tag_name);
                if (tag_index == 0)
                        if(developer_extra.integer)
                                Con_DPrintf("VM_SV_gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
@@ -2563,7 +2564,7 @@ static void VM_SV_gettagindex (void)
 }
 
 //vector(entity ent, float tagindex) gettaginfo;
-static void VM_SV_gettaginfo (void)
+static void VM_SV_gettaginfo(prvm_prog_t *prog)
 {
        prvm_edict_t *e;
        int tagindex;
@@ -2580,18 +2581,18 @@ static void VM_SV_gettaginfo (void)
        e = PRVM_G_EDICT(OFS_PARM0);
        tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
 
-       returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
+       returncode = SV_GetTagMatrix(prog, &tag_matrix, e, tagindex);
        Matrix4x4_ToVectors(&tag_matrix, PRVM_serverglobalvector(v_forward), le, PRVM_serverglobalvector(v_up), PRVM_G_VECTOR(OFS_RETURN));
        VectorScale(le, -1, PRVM_serverglobalvector(v_right));
        model = SV_GetModelFromEdict(e);
-       VM_GenerateFrameGroupBlend(e->priv.server->framegroupblend, e);
+       VM_GenerateFrameGroupBlend(prog, e->priv.server->framegroupblend, e);
        VM_FrameBlendFromFrameGroupBlend(e->priv.server->frameblend, e->priv.server->framegroupblend, model);
-       VM_UpdateEdictSkeleton(e, model, e->priv.server->frameblend);
-       SV_GetExtendedTagInfo(e, tagindex, &parentindex, &tagname, &tag_localmatrix);
+       VM_UpdateEdictSkeleton(prog, e, model, e->priv.server->frameblend);
+       SV_GetExtendedTagInfo(prog, e, tagindex, &parentindex, &tagname, &tag_localmatrix);
        Matrix4x4_ToVectors(&tag_localmatrix, fo, le, up, trans);
 
        PRVM_serverglobalfloat(gettaginfo_parent) = parentindex;
-       PRVM_serverglobalstring(gettaginfo_name) = tagname ? PRVM_SetTempString(tagname) : 0;
+       PRVM_serverglobalstring(gettaginfo_name) = tagname ? PRVM_SetTempString(prog, tagname) : 0;
        VectorCopy(trans, PRVM_serverglobalvector(gettaginfo_offset));
        VectorCopy(fo, PRVM_serverglobalvector(gettaginfo_forward));
        VectorScale(le, -1, PRVM_serverglobalvector(gettaginfo_right));
@@ -2600,10 +2601,10 @@ static void VM_SV_gettaginfo (void)
        switch(returncode)
        {
                case 1:
-                       VM_Warning("gettagindex: can't affect world entity\n");
+                       VM_Warning(prog, "gettagindex: can't affect world entity\n");
                        break;
                case 2:
-                       VM_Warning("gettagindex: can't affect free entity\n");
+                       VM_Warning(prog, "gettagindex: can't affect free entity\n");
                        break;
                case 3:
                        Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
@@ -2618,7 +2619,7 @@ static void VM_SV_gettaginfo (void)
 }
 
 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
-static void VM_SV_dropclient (void)
+static void VM_SV_dropclient(prvm_prog_t *prog)
 {
        int clientnum;
        client_t *oldhostclient;
@@ -2626,12 +2627,12 @@ static void VM_SV_dropclient (void)
        clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
        if (clientnum < 0 || clientnum >= svs.maxclients)
        {
-               VM_Warning("dropclient: not a client\n");
+               VM_Warning(prog, "dropclient: not a client\n");
                return;
        }
        if (!svs.clients[clientnum].active)
        {
-               VM_Warning("dropclient: that client slot is not connected\n");
+               VM_Warning(prog, "dropclient: that client slot is not connected\n");
                return;
        }
        oldhostclient = host_client;
@@ -2641,7 +2642,7 @@ static void VM_SV_dropclient (void)
 }
 
 //entity() spawnclient (DP_SV_BOTCLIENT)
-static void VM_SV_spawnclient (void)
+static void VM_SV_spawnclient(prvm_prog_t *prog)
 {
        int i;
        prvm_edict_t    *ed;
@@ -2665,7 +2666,7 @@ static void VM_SV_spawnclient (void)
 }
 
 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
-static void VM_SV_clienttype (void)
+static void VM_SV_clienttype(prvm_prog_t *prog)
 {
        int clientnum;
        VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
@@ -2687,16 +2688,16 @@ VM_SV_serverkey
 string(string key) serverkey
 ===============
 */
-void VM_SV_serverkey(void)
+static void VM_SV_serverkey(prvm_prog_t *prog)
 {
        char string[VM_STRINGTEMP_LENGTH];
        VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
        InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, string);
 }
 
 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
-static void VM_SV_setmodelindex (void)
+static void VM_SV_setmodelindex(prvm_prog_t *prog)
 {
        prvm_edict_t    *e;
        dp_model_t      *mod;
@@ -2706,27 +2707,27 @@ static void VM_SV_setmodelindex (void)
        e = PRVM_G_EDICT(OFS_PARM0);
        if (e == prog->edicts)
        {
-               VM_Warning("setmodelindex: can not modify world entity\n");
+               VM_Warning(prog, "setmodelindex: can not modify world entity\n");
                return;
        }
        if (e->priv.server->free)
        {
-               VM_Warning("setmodelindex: can not modify free entity\n");
+               VM_Warning(prog, "setmodelindex: can not modify free entity\n");
                return;
        }
        i = (int)PRVM_G_FLOAT(OFS_PARM1);
        if (i <= 0 || i >= MAX_MODELS)
        {
-               VM_Warning("setmodelindex: invalid modelindex\n");
+               VM_Warning(prog, "setmodelindex: invalid modelindex\n");
                return;
        }
        if (!sv.model_precache[i][0])
        {
-               VM_Warning("setmodelindex: model not precached\n");
+               VM_Warning(prog, "setmodelindex: model not precached\n");
                return;
        }
 
-       PRVM_serveredictstring(e, model) = PRVM_SetEngineString(sv.model_precache[i]);
+       PRVM_serveredictstring(e, model) = PRVM_SetEngineString(prog, sv.model_precache[i]);
        PRVM_serveredictfloat(e, modelindex) = i;
 
        mod = SV_GetModelByIndex(i);
@@ -2734,16 +2735,16 @@ static void VM_SV_setmodelindex (void)
        if (mod)
        {
                if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
-                       SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
+                       SetMinMaxSize(prog, e, mod->normalmins, mod->normalmaxs, true);
                else
-                       SetMinMaxSize (e, quakemins, quakemaxs, true);
+                       SetMinMaxSize(prog, e, quakemins, quakemaxs, true);
        }
        else
-               SetMinMaxSize (e, vec3_origin, vec3_origin, true);
+               SetMinMaxSize(prog, e, vec3_origin, vec3_origin, true);
 }
 
 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
-static void VM_SV_modelnameforindex (void)
+static void VM_SV_modelnameforindex(prvm_prog_t *prog)
 {
        int i;
        VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
@@ -2753,20 +2754,20 @@ static void VM_SV_modelnameforindex (void)
        i = (int)PRVM_G_FLOAT(OFS_PARM0);
        if (i <= 0 || i >= MAX_MODELS)
        {
-               VM_Warning("modelnameforindex: invalid modelindex\n");
+               VM_Warning(prog, "modelnameforindex: invalid modelindex\n");
                return;
        }
        if (!sv.model_precache[i][0])
        {
-               VM_Warning("modelnameforindex: model not precached\n");
+               VM_Warning(prog, "modelnameforindex: model not precached\n");
                return;
        }
 
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(prog, sv.model_precache[i]);
 }
 
 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
-static void VM_SV_particleeffectnum (void)
+static void VM_SV_particleeffectnum(prvm_prog_t *prog)
 {
        int                     i;
        VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
@@ -2777,7 +2778,7 @@ static void VM_SV_particleeffectnum (void)
 }
 
 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
-static void VM_SV_trailparticles (void)
+static void VM_SV_trailparticles(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
 
@@ -2793,7 +2794,7 @@ static void VM_SV_trailparticles (void)
 }
 
 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
-static void VM_SV_pointparticles (void)
+static void VM_SV_pointparticles(prvm_prog_t *prog)
 {
        int effectnum, count;
        vec3_t org, vel;
@@ -2827,12 +2828,12 @@ static void VM_SV_pointparticles (void)
 }
 
 //PF_setpause,    // void(float pause) setpause        = #531;
-static void VM_SV_setpause(void) {
+static void VM_SV_setpause(prvm_prog_t *prog) {
        int pauseValue;
        pauseValue = (int)PRVM_G_FLOAT(OFS_PARM0);
        if (pauseValue != 0) { //pause the game
                sv.paused = 1;
-               sv.pausedstart = Sys_DoubleTime();
+               sv.pausedstart = realtime;
        } else { //disable pause, in case it was enabled
                if (sv.paused != 0) {
                        sv.paused = 0;
@@ -2845,7 +2846,7 @@ static void VM_SV_setpause(void) {
 }
 
 // #263 float(float modlindex) skel_create = #263; // (FTE_CSQC_SKELETONOBJECTS) create a skeleton (be sure to assign this value into .skeletonindex for use), returns skeleton index (1 or higher) on success, returns 0 on failure  (for example if the modelindex is not skeletal), it is recommended that you create a new skeleton if you change modelindex.
-static void VM_SV_skel_create(void)
+static void VM_SV_skel_create(prvm_prog_t *prog)
 {
        int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
        dp_model_t *model = SV_GetModelByIndex(modelindex);
@@ -2869,7 +2870,7 @@ static void VM_SV_skel_create(void)
 }
 
 // #264 float(float skel, entity ent, float modlindex, float retainfrac, float firstbone, float lastbone) skel_build = #264; // (FTE_CSQC_SKELETONOBJECTS) blend in a percentage of standard animation, 0 replaces entirely, 1 does nothing, 0.5 blends half, etc, and this only alters the bones in the specified range for which out of bounds values like 0,100000 are safe (uses .frame, .frame2, .frame3, .frame4, .lerpfrac, .lerpfrac3, .lerpfrac4, .frame1time, .frame2time, .frame3time, .frame4time), returns skel on success, 0 on failure
-static void VM_SV_skel_build(void)
+static void VM_SV_skel_build(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        skeleton_t *skeleton;
@@ -2893,7 +2894,7 @@ static void VM_SV_skel_build(void)
        firstbone = max(0, firstbone);
        lastbone = min(lastbone, model->num_bones - 1);
        lastbone = min(lastbone, skeleton->model->num_bones - 1);
-       VM_GenerateFrameGroupBlend(framegroupblend, ed);
+       VM_GenerateFrameGroupBlend(prog, framegroupblend, ed);
        VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model);
        blendfrac = 1.0f - retainfrac;
        for (numblends = 0;numblends < MAX_FRAMEBLENDS && frameblend[numblends].lerp;numblends++)
@@ -2913,7 +2914,7 @@ static void VM_SV_skel_build(void)
 }
 
 // #265 float(float skel) skel_get_numbones = #265; // (FTE_CSQC_SKELETONOBJECTS) returns how many bones exist in the created skeleton
-static void VM_SV_skel_get_numbones(void)
+static void VM_SV_skel_get_numbones(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        skeleton_t *skeleton;
@@ -2924,7 +2925,7 @@ static void VM_SV_skel_get_numbones(void)
 }
 
 // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (FTE_CSQC_SKELETONOBJECTS) returns name of bone (as a tempstring)
-static void VM_SV_skel_get_bonename(void)
+static void VM_SV_skel_get_bonename(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
@@ -2934,11 +2935,11 @@ static void VM_SV_skel_get_bonename(void)
                return;
        if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
                return;
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(skeleton->model->data_bones[bonenum].name);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, skeleton->model->data_bones[bonenum].name);
 }
 
 // #267 float(float skel, float bonenum) skel_get_boneparent = #267; // (FTE_CSQC_SKELETONOBJECTS) returns parent num for supplied bonenum, 0 if bonenum has no parent or bone does not exist (returned value is always less than bonenum, you can loop on this)
-static void VM_SV_skel_get_boneparent(void)
+static void VM_SV_skel_get_boneparent(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
@@ -2952,7 +2953,7 @@ static void VM_SV_skel_get_boneparent(void)
 }
 
 // #268 float(float skel, string tagname) skel_find_bone = #268; // (FTE_CSQC_SKELETONOBJECTS) get number of bone with specified name, 0 on failure, tagindex (bonenum+1) on success, same as using gettagindex on the modelindex
-static void VM_SV_skel_find_bone(void)
+static void VM_SV_skel_find_bone(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        const char *tagname = PRVM_G_STRING(OFS_PARM1);
@@ -2964,7 +2965,7 @@ static void VM_SV_skel_find_bone(void)
 }
 
 // #269 vector(float skel, float bonenum) skel_get_bonerel = #269; // (FTE_CSQC_SKELETONOBJECTS) get matrix of bone in skeleton relative to its parent - sets v_forward, v_right, v_up, returns origin (relative to parent bone)
-static void VM_SV_skel_get_bonerel(void)
+static void VM_SV_skel_get_bonerel(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
@@ -2988,7 +2989,7 @@ static void VM_SV_skel_get_bonerel(void)
 }
 
 // #270 vector(float skel, float bonenum) skel_get_boneabs = #270; // (FTE_CSQC_SKELETONOBJECTS) get matrix of bone in skeleton in model space - sets v_forward, v_right, v_up, returns origin (relative to entity)
-static void VM_SV_skel_get_boneabs(void)
+static void VM_SV_skel_get_boneabs(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
@@ -3019,7 +3020,7 @@ static void VM_SV_skel_get_boneabs(void)
 }
 
 // #271 void(float skel, float bonenum, vector org) skel_set_bone = #271; // (FTE_CSQC_SKELETONOBJECTS) set matrix of bone relative to its parent, reads v_forward, v_right, v_up, takes origin as parameter (relative to parent bone)
-static void VM_SV_skel_set_bone(void)
+static void VM_SV_skel_set_bone(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
@@ -3039,7 +3040,7 @@ static void VM_SV_skel_set_bone(void)
 }
 
 // #272 void(float skel, float bonenum, vector org) skel_mul_bone = #272; // (FTE_CSQC_SKELETONOBJECTS) transform bone matrix (relative to its parent) by the supplied matrix in v_forward, v_right, v_up, takes origin as parameter (relative to parent bone)
-static void VM_SV_skel_mul_bone(void)
+static void VM_SV_skel_mul_bone(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
@@ -3061,7 +3062,7 @@ static void VM_SV_skel_mul_bone(void)
 }
 
 // #273 void(float skel, float startbone, float endbone, vector org) skel_mul_bones = #273; // (FTE_CSQC_SKELETONOBJECTS) transform bone matrices (relative to their parents) by the supplied matrix in v_forward, v_right, v_up, takes origin as parameter (relative to parent bones)
-static void VM_SV_skel_mul_bones(void)
+static void VM_SV_skel_mul_bones(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        int firstbone = PRVM_G_FLOAT(OFS_PARM1) - 1;
@@ -3088,7 +3089,7 @@ static void VM_SV_skel_mul_bones(void)
 }
 
 // #274 void(float skeldst, float skelsrc, float startbone, float endbone) skel_copybones = #274; // (FTE_CSQC_SKELETONOBJECTS) copy bone matrices (relative to their parents) from one skeleton to another, useful for copying a skeleton to a corpse
-static void VM_SV_skel_copybones(void)
+static void VM_SV_skel_copybones(prvm_prog_t *prog)
 {
        int skeletonindexdst = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        int skeletonindexsrc = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
@@ -3109,7 +3110,7 @@ static void VM_SV_skel_copybones(void)
 }
 
 // #275 void(float skel) skel_delete = #275; // (FTE_CSQC_SKELETONOBJECTS) deletes skeleton at the beginning of the next frame (you can add the entity, delete the skeleton, renderscene, and it will still work)
-static void VM_SV_skel_delete(void)
+static void VM_SV_skel_delete(prvm_prog_t *prog)
 {
        int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
        skeleton_t *skeleton;
@@ -3120,7 +3121,7 @@ static void VM_SV_skel_delete(void)
 }
 
 // #276 float(float modlindex, string framename) frameforname = #276; // (FTE_CSQC_SKELETONOBJECTS) finds number of a specified frame in the animation, returns -1 if no match found
-static void VM_SV_frameforname(void)
+static void VM_SV_frameforname(prvm_prog_t *prog)
 {
        int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
        dp_model_t *model = SV_GetModelByIndex(modelindex);
@@ -3140,7 +3141,7 @@ static void VM_SV_frameforname(void)
 }
 
 // #277 float(float modlindex, float framenum) frameduration = #277; // (FTE_CSQC_SKELETONOBJECTS) returns the intended play time (in seconds) of the specified framegroup, if it does not exist the result is 0, if it is a single frame it may be a small value around 0.1 or 0.
-static void VM_SV_frameduration(void)
+static void VM_SV_frameduration(prvm_prog_t *prog)
 {
        int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
        dp_model_t *model = SV_GetModelByIndex(modelindex);
@@ -3221,7 +3222,7 @@ VM_changepitch,                                   // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUA
 VM_SV_tracetoss,                               // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
 VM_etos,                                               // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
 NULL,                                                  // #66 (QUAKE)
-SV_MoveToGoal,                                 // #67 void(float step) movetogoal (QUAKE)
+VM_SV_MoveToGoal,                              // #67 void(float step) movetogoal (QUAKE)
 VM_precache_file,                              // #68 string(string s) precache_file (QUAKE)
 VM_SV_makestatic,                              // #69 void(entity e) makestatic (QUAKE)
 VM_changelevel,                                        // #70 void(string s) changelevel (QUAKE)
@@ -3803,21 +3804,21 @@ NULL,                                                   // #640
 
 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
 
-void VM_SV_Cmd_Init(void)
+void SVVM_init_cmd(prvm_prog_t *prog)
 {
-       VM_Cmd_Init();
+       VM_Cmd_Init(prog);
 }
 
-void VM_SV_Cmd_Reset(void)
+void SVVM_reset_cmd(prvm_prog_t *prog)
 {
        World_End(&sv.world);
        if(PRVM_serverfunction(SV_Shutdown))
        {
                func_t s = PRVM_serverfunction(SV_Shutdown);
+               PRVM_serverglobalfloat(time) = sv.time;
                PRVM_serverfunction(SV_Shutdown) = 0; // prevent it from getting called again
-               PRVM_ExecuteProgram(s,"SV_Shutdown() required");
+               prog->ExecuteProgram(prog, s,"SV_Shutdown() required");
        }
 
-       VM_Cmd_Reset();
+       VM_Cmd_Reset(prog);
 }
-
diff --git a/sys.h b/sys.h
index 37fcc8044fb87051d91eb7cfbd3e3715f7bfe2c1..908c9e5f2f5509d9f1a0a55dfb2ef7309ee7eac6 100644 (file)
--- a/sys.h
+++ b/sys.h
@@ -84,7 +84,14 @@ void Sys_Quit (int returnvalue);
  */
 void Sys_AllowProfiling (qboolean enable);
 
-double Sys_DoubleTime (void);
+typedef struct sys_cleantime_s
+{
+       double dirtytime; // last value gotten from Sys_DirtyTime()
+       double cleantime; // sanitized linearly increasing time since app start
+}
+sys_cleantime_t;
+
+double Sys_DirtyTime(void);
 
 void Sys_ProvideSelfFD (void);
 
index bb6ce36bff76923f8f86178285578a92cfbdf061..34fd2f7ae6098feaf904f51d573f46ee5be4259d 100644 (file)
@@ -284,11 +284,11 @@ void Sys_Init_Commands (void)
 #endif
 }
 
-double Sys_DoubleTime(void)
+double Sys_DirtyTime(void)
 {
-       static int first = true;
-       static double oldtime = 0.0, curtime = 0.0;
-       double newtime;
+       // first all the OPTIONAL timers
+
+       // benchmark timer (fake clock)
        if(sys_usenoclockbutbenchmark.integer)
        {
                double old_benchmark_time = benchmark_time;
@@ -297,11 +297,8 @@ double Sys_DoubleTime(void)
                        Sys_Error("sys_usenoclockbutbenchmark cannot run any longer, sorry");
                return benchmark_time * 0.000001;
        }
-
-       // first all the OPTIONAL timers
-
 #if HAVE_QUERYPERFORMANCECOUNTER
-       else if (sys_usequeryperformancecounter.integer)
+       if (sys_usequeryperformancecounter.integer)
        {
                // LordHavoc: note to people modifying this code, DWORD is specifically defined as an unsigned 32bit number, therefore the 65536.0 * 65536.0 is fine.
                // QueryPerformanceCounter
@@ -316,27 +313,29 @@ double Sys_DoubleTime(void)
                LARGE_INTEGER PerformanceFreq;
                LARGE_INTEGER PerformanceCount;
 
-               if (!QueryPerformanceFrequency (&PerformanceFreq))
+               if (QueryPerformanceFrequency (&PerformanceFreq))
                {
-                       Con_Printf ("No hardware timer available\n");
-                       // fall back to timeGetTime
+                       QueryPerformanceCounter (&PerformanceCount);
+       
+                       #ifdef __BORLANDC__
+                       timescale = 1.0 / ((double) PerformanceFreq.u.LowPart + (double) PerformanceFreq.u.HighPart * 65536.0 * 65536.0);
+                       return ((double) PerformanceCount.u.LowPart + (double) PerformanceCount.u.HighPart * 65536.0 * 65536.0) * timescale;
+                       #else
+                       timescale = 1.0 / ((double) PerformanceFreq.LowPart + (double) PerformanceFreq.HighPart * 65536.0 * 65536.0);
+                       return ((double) PerformanceCount.LowPart + (double) PerformanceCount.HighPart * 65536.0 * 65536.0) * timescale;
+                       #endif
+               }
+               else
+               {
+                       Con_Printf("No hardware timer available\n");
+                       // fall back to other clock sources
                        Cvar_SetValueQuick(&sys_usequeryperformancecounter, false);
-                       return Sys_DoubleTime();
                }
-               QueryPerformanceCounter (&PerformanceCount);
-
-               #ifdef __BORLANDC__
-               timescale = 1.0 / ((double) PerformanceFreq.u.LowPart + (double) PerformanceFreq.u.HighPart * 65536.0 * 65536.0);
-               newtime = ((double) PerformanceCount.u.LowPart + (double) PerformanceCount.u.HighPart * 65536.0 * 65536.0) * timescale;
-               #else
-               timescale = 1.0 / ((double) PerformanceFreq.LowPart + (double) PerformanceFreq.HighPart * 65536.0 * 65536.0);
-               newtime = ((double) PerformanceCount.LowPart + (double) PerformanceCount.HighPart * 65536.0 * 65536.0) * timescale;
-               #endif
        }
 #endif
 
 #if HAVE_CLOCKGETTIME
-       else if (sys_useclockgettime.integer)
+       if (sys_useclockgettime.integer)
        {
                struct timespec ts;
 #  ifdef CLOCK_MONOTONIC
@@ -346,24 +345,20 @@ double Sys_DoubleTime(void)
                // sunos
                clock_gettime(CLOCK_HIGHRES, &ts);
 #  endif
-               newtime = (double) ts.tv_sec + ts.tv_nsec / 1000000000.0;
+               return (double) ts.tv_sec + ts.tv_nsec / 1000000000.0;
        }
 #endif
 
        // now all the FALLBACK timers
-       else if(sys_supportsdlgetticks && sys_usesdlgetticks.integer)
-       {
-               newtime = (double) Sys_SDL_GetTicks() / 1000.0;
-       }
+       if(sys_supportsdlgetticks && sys_usesdlgetticks.integer)
+               return (double) Sys_SDL_GetTicks() / 1000.0;
 #if HAVE_GETTIMEOFDAY
-       else
        {
                struct timeval tp;
                gettimeofday(&tp, NULL);
-               newtime = (double) tp.tv_sec + tp.tv_usec / 1000000.0;
+               return (double) tp.tv_sec + tp.tv_usec / 1000000.0;
        }
 #elif HAVE_TIMEGETTIME
-       else
        {
                static int firsttimegettime = true;
                // timeGetTime
@@ -377,42 +372,17 @@ double Sys_DoubleTime(void)
                // make sure the timer is high precision, otherwise different versions of windows have varying accuracy
                if (firsttimegettime)
                {
-                       timeBeginPeriod (1);
+                       timeBeginPeriod(1);
                        firsttimegettime = false;
                }
 
-               newtime = (double) timeGetTime () / 1000.0;
+               return (double) timeGetTime() / 1000.0;
        }
 #else
        // fallback for using the SDL timer if no other timer is available
-       else
-       {
-               newtime = (double) Sys_SDL_GetTicks() / 1000.0;
-               // this calls Sys_Error() if not linking against SDL
-       }
+       // this calls Sys_Error() if not linking against SDL
+       return (double) Sys_SDL_GetTicks() / 1000.0;
 #endif
-
-       if (first)
-       {
-               first = false;
-               oldtime = newtime;
-       }
-
-       if (newtime < oldtime)
-       {
-               // warn if it's significant
-               if (newtime - oldtime < -0.01)
-                       Con_Printf("Sys_DoubleTime: time stepped backwards (went from %f to %f, difference %f)\n", oldtime, newtime, newtime - oldtime);
-       }
-       else if (newtime > oldtime + 1800)
-       {
-               Con_Printf("Sys_DoubleTime: time stepped forward (went from %f to %f, difference %f)\n", oldtime, newtime, newtime - oldtime);
-       }
-       else
-               curtime += newtime - oldtime;
-       oldtime = newtime;
-
-       return curtime;
 }
 
 void Sys_Sleep(int microseconds)
@@ -431,7 +401,7 @@ void Sys_Sleep(int microseconds)
        }
        if(sys_debugsleep.integer)
        {
-               t = Sys_DoubleTime();
+               t = Sys_DirtyTime();
        }
        if(sys_supportsdlgetticks && sys_usesdldelay.integer)
        {
@@ -463,12 +433,12 @@ void Sys_Sleep(int microseconds)
 #endif
        if(sys_debugsleep.integer)
        {
-               t = Sys_DoubleTime() - t;
+               t = Sys_DirtyTime() - t;
                printf("%d %d # debugsleep\n", microseconds, (unsigned int)(t * 1000000));
        }
 }
 
-const char *Sys_FindInPATH(const char *name, char namesep, const char *PATH, char pathsep, char *buf, size_t bufsize)
+static const char *Sys_FindInPATH(const char *name, char namesep, const char *PATH, char pathsep, char *buf, size_t bufsize)
 {
        const char *p = PATH;
        const char *q;
@@ -491,7 +461,7 @@ const char *Sys_FindInPATH(const char *name, char namesep, const char *PATH, cha
        return name;
 }
 
-const char *Sys_FindExecutableName(void)
+static const char *Sys_FindExecutableName(void)
 {
 #if defined(WIN32)
        return com_argv[0];
index 310f4e8f1164c7437598350206636b1a6c635e5f..33da8584e95f2817b84fcdfb08e53181d8d42f9c 100644 (file)
--- a/timing.h
+++ b/timing.h
@@ -25,15 +25,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #if defined(DO_TIMING)
 
-#define TIMING_BEGIN   double _timing_end_, _timing_start_ = Sys_DoubleTime();
+#define TIMING_BEGIN   double _timing_end_, _timing_start_ = Sys_DirtyTime();
 #define TIMING_END_STR(S)              \
-  _timing_end_ = Sys_DoubleTime();     \
+  _timing_end_ = Sys_DirtyTime();      \
   Con_Printf ("%s: %.3g s\n", S, _timing_end_ - _timing_start_);
 #define TIMING_END     TIMING_END_STR(__FUNCTION__)
 
 #define TIMING_INTERMEDIATE(S)                                         \
   {                                                                    \
-    double currentTime = Sys_DoubleTime();                             \
+    double currentTime = Sys_DirtyTime();                              \
     Con_Printf ("%s: %.3g s\n", S, currentTime - _timing_start_);      \
   }
   
index b726e220d9768ca01d82b973aba0d5d464fecdd2..8994bd7a00a697e124779b86318919aea0d5aaf9 100644 (file)
--- a/utf8lib.c
+++ b/utf8lib.c
@@ -596,15 +596,14 @@ int u8_fromchar(Uchar w, char *to, size_t maxlen)
  * @param l         The number of bytes without the terminating null.
  * @return          A statically allocated buffer containing the character's utf8 representation, or NULL if it fails.
  */
-char *u8_encodech(Uchar ch, size_t *l)
+char *u8_encodech(Uchar ch, size_t *l, char *buf16)
 {
-       static char buf[16];
        size_t len;
-       len = u8_fromchar(ch, buf, sizeof(buf));
+       len = u8_fromchar(ch, buf16, 16);
        if (len > 0)
        {
                if (l) *l = len;
-               return buf;
+               return buf16;
        }
        return NULL;
 }
index 9124c4e7905ea72ed0123aca9c20daf7a02e9f7e..36c16fe1444d967a255cbe11d87f2904929f6d8b 100644 (file)
--- a/utf8lib.h
+++ b/utf8lib.h
@@ -38,11 +38,12 @@ size_t u8_prevbyte(const char*, size_t);
 Uchar  u8_getchar_utf8_enabled(const char*, const char**);
 Uchar  u8_getnchar_utf8_enabled(const char*, const char**, size_t);
 int    u8_fromchar(Uchar, char*, size_t);
+size_t u8_mbstowcs(Uchar *, const char *, size_t);
 size_t u8_wcstombs(char*, const Uchar*, size_t);
 size_t u8_COM_StringLengthNoColors(const char *s, size_t size_s, qboolean *valid);
 
 // returns a static buffer, use this for inlining
-char  *u8_encodech(Uchar ch, size_t*);
+char  *u8_encodech(Uchar ch, size_t*, char*buf16);
 
 size_t u8_strpad(char *out, size_t outsize, const char *in, qboolean leftalign, size_t minwidth, size_t maxwidth);
 
diff --git a/vid.h b/vid.h
index 4840ae4a53451c476e45edaaa08e934e48df812d..3351abcf6d3429dc493e5e43a64a4aaa35a13da7 100644 (file)
--- a/vid.h
+++ b/vid.h
@@ -225,10 +225,6 @@ extern const char *gl_platformextensions;
 // name of driver library (opengl32.dll, libGL.so.1, or whatever)
 extern char gl_driver[256];
 
-// compatibility hacks
-extern qboolean isG200;
-extern qboolean isRagePro;
-
 void *GL_GetProcAddress(const char *name);
 qboolean GL_CheckExtension(const char *minglver_or_ext, const dllfunction_t *funcs, const char *disableparm, int silent);
 
@@ -274,6 +270,7 @@ void VID_Finish (void);
 void VID_Restart_f(void);
 
 void VID_Start(void);
+void VID_Stop(void);
 
 extern unsigned int vid_gammatables_serial; // so other subsystems can poll if gamma parameters have changed; this starts with 0 and gets increased by 1 each time the gamma parameters get changed and VID_BuildGammaTables should be called again
 extern qboolean vid_gammatables_trivial; // this is set to true if all color control values are at default setting, and it therefore would make no sense to use the gamma table
@@ -288,5 +285,6 @@ vid_mode_t;
 size_t VID_ListModes(vid_mode_t *modes, size_t maxcount);
 size_t VID_SortModes(vid_mode_t *modes, size_t count, qboolean usebpp, qboolean userefreshrate, qboolean useaspect);
 void VID_Soft_SharedSetup(void);
+
 #endif
 
index 9f142bb9a0caf34be92da7fe97f6611d3a111146..46e0280101e9a6071b37aeb930f3a9c83354c060 100644 (file)
--- a/vid_glx.c
+++ b/vid_glx.c
@@ -1190,7 +1190,7 @@ qboolean VID_InitModeSoft(viddef_mode_t *mode)
                        }
                        ++i;
                        Mem_Free(data);
-                       data = loadimagepixelsbgra(va("darkplaces-icon%d", i), false, false, false, NULL);
+                       data = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "darkplaces-icon%d", i), false, false, false, NULL);
                }
                XChangeProperty(vidx11_display, win, net_wm_icon, cardinal, 32, PropModeReplace, (const unsigned char *) netwm_icon, pos);
        }
@@ -1523,7 +1523,7 @@ qboolean VID_InitModeGL(viddef_mode_t *mode)
                        }
                        ++i;
                        Mem_Free(data);
-                       data = loadimagepixelsbgra(va("darkplaces-icon%d", i), false, false, false, NULL);
+                       data = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "darkplaces-icon%d", i), false, false, false, NULL);
                }
                XChangeProperty(vidx11_display, win, net_wm_icon, cardinal, 32, PropModeReplace, (const unsigned char *) netwm_icon, pos);
        }
index f72abea1021527172cc6898a02cff498bddd2f1b..2d48d39582e4836e0ea43ec9d9b7bc4496b3ab24 100644 (file)
--- a/vid_sdl.c
+++ b/vid_sdl.c
@@ -380,7 +380,7 @@ SDL_bool SDL_iPhoneKeyboardIsShown(SDL_Window * window);  // returns whether or
 int SDL_iPhoneKeyboardToggle(SDL_Window * window); // toggles the visibility of the onscreen keyboard.  Returns 0 on success and -1 on error.
 #endif
 
-void VID_ShowKeyboard(qboolean show)
+static void VID_ShowKeyboard(qboolean show)
 {
 #ifdef __IPHONEOS__
        if (show)
@@ -486,7 +486,7 @@ void VID_SetMouse(qboolean fullscreengrab, qboolean relative, qboolean hidecurso
 #define MAXFINGERS 11
 int multitouch[MAXFINGERS][3];
 
-qboolean VID_TouchscreenArea(int corner, float px, float py, float pwidth, float pheight, const char *icon, float *resultmove, qboolean *resultbutton, keynum_t key)
+static qboolean VID_TouchscreenArea(int corner, float px, float py, float pwidth, float pheight, const char *icon, float *resultmove, qboolean *resultbutton, keynum_t key)
 {
        int finger;
        float fx, fy, fwidth, fheight;
@@ -1964,6 +1964,7 @@ static SDL_Surface *VID_WrapSDL_SetVideoMode(int screenwidth, int screenheight,
                                static long netwm_icon[MAX_NETWM_ICON];
                                int pos = 0;
                                int i = 1;
+                               char vabuf[1024];
 
                                while(data)
                                {
@@ -1981,7 +1982,7 @@ static SDL_Surface *VID_WrapSDL_SetVideoMode(int screenwidth, int screenheight,
                                        }
                                        ++i;
                                        Mem_Free(data);
-                                       data = (char *) loadimagepixelsbgra(va("darkplaces-icon%d", i), false, false, false, NULL);
+                                       data = (char *) loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "darkplaces-icon%d", i), false, false, false, NULL);
                                }
 
                                info.info.x11.lock_func();
@@ -2011,7 +2012,7 @@ static void VID_OutputVersion(void)
                                        version->major, version->minor, version->patch );
 }
 
-qboolean VID_InitModeGL(viddef_mode_t *mode)
+static qboolean VID_InitModeGL(viddef_mode_t *mode)
 {
        int i;
 #if SETVIDEOMODE
@@ -2198,7 +2199,7 @@ extern cvar_t gl_info_version;
 extern cvar_t gl_info_platform;
 extern cvar_t gl_info_driver;
 
-qboolean VID_InitModeSoft(viddef_mode_t *mode)
+static qboolean VID_InitModeSoft(viddef_mode_t *mode)
 {
 #if SETVIDEOMODE
        int flags = SDL_HWSURFACE;
index 87a188effacfc94ef29ed2ab7ea7884c7accba68..411aceff1592b2e17fe2efae66307a130bb79148 100644 (file)
@@ -72,10 +72,6 @@ int vid_xinputindex = -1;
 // global video state
 viddef_t vid;
 
-// LordHavoc: these are only set in wgl
-qboolean isG200 = false; // LordHavoc: the Matrox G200 can't do per pixel alpha, and it uses a D3D driver for GL... ugh...
-qboolean isRagePro = false; // LordHavoc: the ATI Rage Pro has limitations with per pixel alpha (the color scaler does not apply to per pixel alpha images...), although not as bad as a G200.
-
 // AK FIXME -> input_dest
 qboolean in_client_mouse = true;
 
@@ -1241,7 +1237,7 @@ void VID_Shared_BuildJoyState_Finish(vid_joystate_t *joystate)
        joystate->button[35] = r < 0.0f;
 }
 
-void VID_KeyEventForButton(qboolean oldbutton, qboolean newbutton, int key, double *timer)
+static void VID_KeyEventForButton(qboolean oldbutton, qboolean newbutton, int key, double *timer)
 {
        if (oldbutton)
        {
@@ -1386,7 +1382,7 @@ int VID_Shared_SetJoystick(int index)
 }
 
 
-void Force_CenterView_f (void)
+static void Force_CenterView_f (void)
 {
        cl.viewangles[PITCH] = 0;
 }
@@ -1752,9 +1748,10 @@ void VID_Shared_Init(void)
        Cmd_AddCommand("vid_restart", VID_Restart_f, "restarts video system (closes and reopens the window, restarts renderer)");
 }
 
-int VID_Mode(int fullscreen, int width, int height, int bpp, float refreshrate, int stereobuffer, int samples)
+static int VID_Mode(int fullscreen, int width, int height, int bpp, float refreshrate, int stereobuffer, int samples)
 {
        viddef_mode_t mode;
+       char vabuf[1024];
 
        memset(&mode, 0, sizeof(mode));
        mode.fullscreen = fullscreen != 0;
@@ -1795,7 +1792,7 @@ int VID_Mode(int fullscreen, int width, int height, int bpp, float refreshrate,
                if(vid.samples != vid.mode.samples)
                        Con_Printf("NOTE: requested %dx AA, got %dx AA\n", vid.mode.samples, vid.samples);
 
-               Con_Printf("Video Mode: %s %dx%dx%dx%.2fhz%s%s\n", mode.fullscreen ? "fullscreen" : "window", mode.width, mode.height, mode.bitsperpixel, mode.refreshrate, mode.stereobuffer ? " stereo" : "", mode.samples > 1 ? va(" (%ix AA)", mode.samples) : "");
+               Con_Printf("Video Mode: %s %dx%dx%dx%.2fhz%s%s\n", mode.fullscreen ? "fullscreen" : "window", mode.width, mode.height, mode.bitsperpixel, mode.refreshrate, mode.stereobuffer ? " stereo" : "", mode.samples > 1 ? va(vabuf, sizeof(vabuf), " (%ix AA)", mode.samples) : "");
 
                Cvar_SetValueQuick(&vid_fullscreen, vid.mode.fullscreen);
                Cvar_SetValueQuick(&vid_width, vid.mode.width);
@@ -1829,6 +1826,8 @@ extern qboolean vid_opened;
 
 void VID_Restart_f(void)
 {
+       char vabuf[1024];
+       char vabuf2[1024];
        // don't crash if video hasn't started yet
        if (vid_commandlinecheck)
                return;
@@ -1840,8 +1839,8 @@ void VID_Restart_f(void)
        }
 
        Con_Printf("VID_Restart: changing from %s %dx%dx%dbpp%s%s, to %s %dx%dx%dbpp%s%s.\n",
-               vid.mode.fullscreen ? "fullscreen" : "window", vid.mode.width, vid.mode.height, vid.mode.bitsperpixel, vid.mode.fullscreen && vid.mode.userefreshrate ? va("x%.2fhz", vid.mode.refreshrate) : "", vid.mode.samples > 1 ? va(" (%ix AA)", vid.mode.samples) : "",
-               vid_fullscreen.integer ? "fullscreen" : "window", vid_width.integer, vid_height.integer, vid_bitsperpixel.integer, vid_fullscreen.integer && vid_userefreshrate.integer ? va("x%.2fhz", vid_refreshrate.value) : "", vid_samples.integer > 1 ? va(" (%ix AA)", vid_samples.integer) : "");
+               vid.mode.fullscreen ? "fullscreen" : "window", vid.mode.width, vid.mode.height, vid.mode.bitsperpixel, vid.mode.fullscreen && vid.mode.userefreshrate ? va(vabuf, sizeof(vabuf), "x%.2fhz", vid.mode.refreshrate) : "", vid.mode.samples > 1 ? va(vabuf2, sizeof(vabuf2), " (%ix AA)", vid.mode.samples) : "",
+               vid_fullscreen.integer ? "fullscreen" : "window", vid_width.integer, vid_height.integer, vid_bitsperpixel.integer, vid_fullscreen.integer && vid_userefreshrate.integer ? va(vabuf, sizeof(vabuf), "x%.2fhz", vid_refreshrate.value) : "", vid_samples.integer > 1 ? va(vabuf2, sizeof(vabuf2), " (%ix AA)", vid_samples.integer) : "");
        VID_CloseSystems();
        VID_Shutdown();
        if (!VID_Mode(vid_fullscreen.integer, vid_width.integer, vid_height.integer, vid_bitsperpixel.integer, vid_refreshrate.value, vid_stereobuffer.integer, vid_samples.integer))
@@ -1920,7 +1919,7 @@ void VID_Stop(void)
        VID_Shutdown();
 }
 
-int VID_SortModes_Compare(const void *a_, const void *b_)
+static int VID_SortModes_Compare(const void *a_, const void *b_)
 {
        vid_mode_t *a = (vid_mode_t *) a_;
        vid_mode_t *b = (vid_mode_t *) b_;
diff --git a/view.c b/view.c
index 3e0ccc57ebbf17154f9e4e8dd536fdc818222de5..8afabbee0365ae639b6d9de19eb2b97a19caf573 100644 (file)
--- a/view.c
+++ b/view.c
@@ -23,8 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "cl_collision.h"
 #include "image.h"
 
-void CL_VM_UpdateDmgGlobals (int dmg_take, int dmg_save, vec3_t dmg_origin);
-
 /*
 
 The view is allowed to move slightly from it's true position for bobbing,
@@ -260,9 +258,9 @@ void V_ParseDamage (void)
        //float side;
        float count;
 
-       armor = MSG_ReadByte ();
-       blood = MSG_ReadByte ();
-       MSG_ReadVector(from, cls.protocol);
+       armor = MSG_ReadByte(&cl_message);
+       blood = MSG_ReadByte(&cl_message);
+       MSG_ReadVector(&cl_message, from, cls.protocol);
 
        // Send the Dmg Globals to CSQC
        CL_VM_UpdateDmgGlobals(blood, armor, from);
diff --git a/world.c b/world.c
index ec767e0415335322b39ccf87da497a7f9c12f1e9..c56f405c5106799be81187db51b0fc3b40645306 100644 (file)
--- a/world.c
+++ b/world.c
@@ -102,13 +102,14 @@ World_SetSize
 
 ===============
 */
-void World_SetSize(world_t *world, const char *filename, const vec3_t mins, const vec3_t maxs)
+void World_SetSize(world_t *world, const char *filename, const vec3_t mins, const vec3_t maxs, prvm_prog_t *prog)
 {
        int i;
 
        strlcpy(world->filename, filename, sizeof(world->filename));
        VectorCopy(mins, world->mins);
        VectorCopy(maxs, world->maxs);
+       world->prog = prog;
 
        // the areagrid_marknumber is not allowed to be 0
        if (world->areagrid_marknumber < 1)
@@ -144,6 +145,7 @@ World_UnlinkAll
 */
 void World_UnlinkAll(world_t *world)
 {
+       prvm_prog_t *prog = world->prog;
        int i;
        link_t *grid;
        // unlink all entities one by one
@@ -175,6 +177,7 @@ void World_UnlinkEdict(prvm_edict_t *ent)
 
 int World_EntitiesInBox(world_t *world, const vec3_t requestmins, const vec3_t requestmaxs, int maxlist, prvm_edict_t **list)
 {
+       prvm_prog_t *prog = world->prog;
        int numlist;
        link_t *grid;
        link_t *l;
@@ -257,8 +260,9 @@ int World_EntitiesInBox(world_t *world, const vec3_t requestmins, const vec3_t r
        return numlist;
 }
 
-void World_LinkEdict_AreaGrid(world_t *world, prvm_edict_t *ent)
+static void World_LinkEdict_AreaGrid(world_t *world, prvm_edict_t *ent)
 {
+       prvm_prog_t *prog = world->prog;
        link_t *grid;
        int igrid[3], igridmins[3], igridmaxs[3], gridnum, entitynumber = PRVM_NUM_FOR_EDICT(ent);
 
@@ -298,6 +302,7 @@ World_LinkEdict
 */
 void World_LinkEdict(world_t *world, prvm_edict_t *ent, const vec3_t mins, const vec3_t maxs)
 {
+       prvm_prog_t *prog = world->prog;
        // unlink from old position first
        if (ent->priv.server->areagrid[0].prev)
                World_UnlinkEdict(ent);
@@ -1747,6 +1752,7 @@ void World_Physics_ApplyCmd(prvm_edict_t *ed, edict_odefunc_t *f)
 #ifdef USEODE
 static void World_Physics_Frame_BodyToEntity(world_t *world, prvm_edict_t *ed)
 {
+       prvm_prog_t *prog = world->prog;
        const dReal *avel;
        const dReal *o;
        const dReal *r; // for some reason dBodyGetRotation returns a [3][4] matrix
@@ -1812,13 +1818,13 @@ static void World_Physics_Frame_BodyToEntity(world_t *world, prvm_edict_t *ed)
 
        {
                float pitchsign = 1;
-               if(!strcmp(prog->name, "server")) // FIXME some better way?
+               if(prog == SVVM_prog) // FIXME some better way?
                {
-                       pitchsign = SV_GetPitchSign(ed);
+                       pitchsign = SV_GetPitchSign(prog, ed);
                }
-               else if(!strcmp(prog->name, "client"))
+               else if(prog == CLVM_prog)
                {
-                       pitchsign = CL_GetPitchSign(ed);
+                       pitchsign = CL_GetPitchSign(prog, ed);
                }
                angles[PITCH] *= pitchsign;
                avelocity[PITCH] *= pitchsign;
@@ -1840,7 +1846,7 @@ static void World_Physics_Frame_BodyToEntity(world_t *world, prvm_edict_t *ed)
        VectorCopy(avelocity, ed->priv.server->ode_avelocity);
        ed->priv.server->ode_gravity = dBodyGetGravityMode(body) != 0;
 
-       if(!strcmp(prog->name, "server")) // FIXME some better way?
+       if(prog == SVVM_prog) // FIXME some better way?
        {
                SV_LinkEdict(ed);
                SV_LinkEdict_TouchAreaGrid(ed);
@@ -1849,6 +1855,7 @@ static void World_Physics_Frame_BodyToEntity(world_t *world, prvm_edict_t *ed)
 
 static void World_Physics_Frame_JointFromEntity(world_t *world, prvm_edict_t *ed)
 {
+       prvm_prog_t *prog = world->prog;
        dJointID j = 0;
        dBodyID b1 = 0;
        dBodyID b2 = 0;
@@ -2030,6 +2037,7 @@ static void World_Physics_Frame_JointFromEntity(world_t *world, prvm_edict_t *ed
 
 static void World_Physics_Frame_BodyFromEntity(world_t *world, prvm_edict_t *ed)
 {
+       prvm_prog_t *prog = world->prog;
        const float *iv;
        const int *ie;
        dBodyID body = (dBodyID)ed->priv.server->ode_body;
@@ -2083,12 +2091,7 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, prvm_edict_t *ed)
        movetype = (int)PRVM_gameedictfloat(ed, movetype);
        scale = PRVM_gameedictfloat(ed, scale);if (!scale) scale = 1.0f;
        modelindex = 0;
-       if (world == &sv.world)
-               mempool = sv_mempool;
-       else if (world == &cl.world)
-               mempool = cls.levelmempool;
-       else
-               mempool = NULL;
+       mempool = prog->progs_mempool;
        model = NULL;
        switch(solid)
        {
@@ -2170,7 +2173,7 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, prvm_edict_t *ed)
                if (massval * geomsize[0] * geomsize[1] * geomsize[2] == 0)
                {
                        if (movetype == MOVETYPE_PHYSICS)
-                               Con_Printf("entity %i (classname %s) .mass * .size_x * .size_y * .size_z == 0\n", PRVM_NUM_FOR_EDICT(ed), PRVM_GetString(PRVM_gameedictstring(ed, classname)));
+                               Con_Printf("entity %i (classname %s) .mass * .size_x * .size_y * .size_z == 0\n", PRVM_NUM_FOR_EDICT(ed), PRVM_GetString(prog, PRVM_gameedictstring(ed, classname)));
                        massval = 1.0f;
                        VectorSet(geomsize, 1.0f, 1.0f, 1.0f);
                }
@@ -2182,7 +2185,7 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, prvm_edict_t *ed)
                        ed->priv.server->ode_offsetmatrix = identitymatrix;
                        if (!model)
                        {
-                               Con_Printf("entity %i (classname %s) has no model\n", PRVM_NUM_FOR_EDICT(ed), PRVM_GetString(PRVM_gameedictstring(ed, classname)));
+                               Con_Printf("entity %i (classname %s) has no model\n", PRVM_NUM_FOR_EDICT(ed), PRVM_GetString(prog, PRVM_gameedictstring(ed, classname)));
                                goto treatasbox;
                        }
                        // add an optimized mesh to the model containing only the SUPERCONTENTS_SOLID surfaces
@@ -2190,7 +2193,7 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, prvm_edict_t *ed)
                                Mod_CreateCollisionMesh(model);
                        if (!model->brush.collisionmesh || !model->brush.collisionmesh->numtriangles)
                        {
-                               Con_Printf("entity %i (classname %s) has no geometry\n", PRVM_NUM_FOR_EDICT(ed), PRVM_GetString(PRVM_gameedictstring(ed, classname)));
+                               Con_Printf("entity %i (classname %s) has no geometry\n", PRVM_NUM_FOR_EDICT(ed), PRVM_GetString(prog, PRVM_gameedictstring(ed, classname)));
                                goto treatasbox;
                        }
                        // ODE requires persistent mesh storage, so we need to copy out
@@ -2337,13 +2340,13 @@ treatasbox:
                VectorCopy(angles, qangles);
                VectorCopy(avelocity, qavelocity);
 
-               if(!strcmp(prog->name, "server")) // FIXME some better way?
+               if(prog == SVVM_prog) // FIXME some better way?
                {
-                       pitchsign = SV_GetPitchSign(ed);
+                       pitchsign = SV_GetPitchSign(prog, ed);
                }
-               else if(!strcmp(prog->name, "client"))
+               else if(prog == CLVM_prog)
                {
-                       pitchsign = CL_GetPitchSign(ed);
+                       pitchsign = CL_GetPitchSign(prog, ed);
                }
                qangles[PITCH] *= pitchsign;
                qavelocity[PITCH] *= pitchsign;
@@ -2377,7 +2380,7 @@ treatasbox:
                        modified = true;
                        //Con_Printf("Fixing NAN values on entity %i : .classname = \"%s\" .origin = '%f %f %f' .velocity = '%f %f %f' .axis_forward = '%f %f %f' .axis_left = '%f %f %f' .axis_up = %f %f %f' .spinvelocity = '%f %f %f'\n", PRVM_NUM_FOR_EDICT(ed), PRVM_GetString(PRVM_gameedictstring(ed, classname)), origin[0], origin[1], origin[2], velocity[0], velocity[1], velocity[2], forward[0], forward[1], forward[2], left[0], left[1], left[2], up[0], up[1], up[2], spinvelocity[0], spinvelocity[1], spinvelocity[2]);
                        if (physics_ode_trick_fixnan.integer >= 2)
-                               Con_Printf("Fixing NAN values on entity %i : .classname = \"%s\" .origin = '%f %f %f' .velocity = '%f %f %f' .angles = '%f %f %f' .avelocity = '%f %f %f'\n", PRVM_NUM_FOR_EDICT(ed), PRVM_GetString(PRVM_gameedictstring(ed, classname)), origin[0], origin[1], origin[2], velocity[0], velocity[1], velocity[2], angles[0], angles[1], angles[2], avelocity[0], avelocity[1], avelocity[2]);
+                               Con_Printf("Fixing NAN values on entity %i : .classname = \"%s\" .origin = '%f %f %f' .velocity = '%f %f %f' .angles = '%f %f %f' .avelocity = '%f %f %f'\n", PRVM_NUM_FOR_EDICT(ed), PRVM_GetString(prog, PRVM_gameedictstring(ed, classname)), origin[0], origin[1], origin[2], velocity[0], velocity[1], velocity[2], angles[0], angles[1], angles[2], avelocity[0], avelocity[1], avelocity[2]);
                        test = VectorLength2(origin);
                        if (IS_NAN(test))
                                VectorClear(origin);
@@ -2522,6 +2525,7 @@ treatasbox:
 static void nearCallback (void *data, dGeomID o1, dGeomID o2)
 {
        world_t *world = (world_t *)data;
+       prvm_prog_t *prog = world->prog;
        dContact contact[MAX_CONTACTS]; // max contacts per collision pair
        dBodyID b1;
        dBodyID b2;
@@ -2579,7 +2583,7 @@ static void nearCallback (void *data, dGeomID o1, dGeomID o2)
                        bouncestop2 = 60.0f / 800.0f;
        }
 
-       if(!strcmp(prog->name, "server"))
+       if(prog == SVVM_prog)
        {
                if(ed1 && PRVM_serveredictfunction(ed1, touch))
                {
@@ -2630,9 +2634,10 @@ static void nearCallback (void *data, dGeomID o1, dGeomID o2)
 
 void World_Physics_Frame(world_t *world, double frametime, double gravity)
 {
+       prvm_prog_t *prog = world->prog;
        double tdelta, tdelta2, tdelta3, simulationtime, collisiontime;
 
-       tdelta = Sys_DoubleTime();
+       tdelta = Sys_DirtyTime();
 #ifdef USEODE
        if (world->physics.ode && physics_ode.integer)
        {
@@ -2659,7 +2664,7 @@ void World_Physics_Frame(world_t *world, double frametime, double gravity)
                                        World_Physics_Frame_JointFromEntity(world, ed);
                }
 
-               tdelta2 = Sys_DoubleTime();
+               tdelta2 = Sys_DirtyTime();
                collisiontime = 0;
                for (i = 0;i < world->physics.ode_iterations;i++)
                {
@@ -2669,9 +2674,9 @@ void World_Physics_Frame(world_t *world, double frametime, double gravity)
                        dWorldSetContactSurfaceLayer((dWorldID)world->physics.ode_world, max(0, physics_ode_contactsurfacelayer.value));
 
                        // run collisions for the current world state, creating JointGroup
-                       tdelta3 = Sys_DoubleTime();
+                       tdelta3 = Sys_DirtyTime();
                        dSpaceCollide((dSpaceID)world->physics.ode_space, (void *)world, nearCallback);
-                       collisiontime += (Sys_DoubleTime() - tdelta3)*10000;
+                       collisiontime += (Sys_DirtyTime() - tdelta3)*10000;
 
                        // run physics (move objects, calculate new velocities)
                        if (physics_ode_worldstep.integer == 2)
@@ -2689,7 +2694,7 @@ void World_Physics_Frame(world_t *world, double frametime, double gravity)
                        // clear the JointGroup now that we're done with it
                        dJointGroupEmpty((dJointGroupID)world->physics.ode_contactgroup);
                }
-               simulationtime = (Sys_DoubleTime() - tdelta2)*10000;
+               simulationtime = (Sys_DirtyTime() - tdelta2)*10000;
 
                // copy physics properties from physics engine to entities and do some stats
                if (prog)
@@ -2716,7 +2721,7 @@ void World_Physics_Frame(world_t *world, double frametime, double gravity)
                                        if (dBodyIsEnabled(body))
                                                world->physics.ode_activeovjects++;
                                }
-                               Con_Printf("ODE Stats(%s): %3.01f (%3.01f collision) %3.01f total : %i objects %i active %i disabled\n", prog->name, simulationtime, collisiontime, (Sys_DoubleTime() - tdelta)*10000, world->physics.ode_numobjects, world->physics.ode_activeovjects, (world->physics.ode_numobjects - world->physics.ode_activeovjects));
+                               Con_Printf("ODE Stats(%s): %3.01f (%3.01f collision) %3.01f total : %i objects %i active %i disabled\n", prog->name, simulationtime, collisiontime, (Sys_DirtyTime() - tdelta)*10000, world->physics.ode_numobjects, world->physics.ode_activeovjects, (world->physics.ode_numobjects - world->physics.ode_activeovjects));
                        }
                }
        }
diff --git a/world.h b/world.h
index 334420fbff9599d29012044e417b139dadf4be51..90c70884060461343cf4932f5a858c2c0d5926d2 100644 (file)
--- a/world.h
+++ b/world.h
@@ -59,12 +59,15 @@ typedef struct world_physics_s
 }
 world_physics_t;
 
+struct prvm_prog_s;
+
 typedef struct world_s
 {
        // convenient fields
        char filename[MAX_QPATH];
        vec3_t mins;
        vec3_t maxs;
+       struct prvm_prog_s *prog;
 
        int areagrid_stats_calls;
        int areagrid_stats_nodechecks;
@@ -95,7 +98,7 @@ void World_Init(void);
 void World_Shutdown(void);
 
 /// called after the world model has been loaded, before linking any entities
-void World_SetSize(world_t *world, const char *filename, const vec3_t mins, const vec3_t maxs);
+void World_SetSize(world_t *world, const char *filename, const vec3_t mins, const vec3_t maxs, struct prvm_prog_s *prog);
 /// unlinks all entities (used before reallocation of edicts)
 void World_UnlinkAll(world_t *world);
 
@@ -121,7 +124,7 @@ void World_Physics_Frame(world_t *world, double frametime, double gravity);
 // change physics properties of entity
 struct prvm_edict_s;
 struct edict_odefunc_s;
-//void World_Physics_ApplyCmd(prvm_edict_s *ed, edict_odefunc_s *f);
+void World_Physics_ApplyCmd(struct prvm_edict_s *ed, struct edict_odefunc_s *f);
 
 // remove physics data from entity
 // this is called by entity removal
diff --git a/zone.c b/zone.c
index d14b0ec94ea2754231a893b7167d82e3538a4639..87e7121248bf6cd0043cdf69156dfffa75dd1a52 100644 (file)
--- a/zone.c
+++ b/zone.c
@@ -824,7 +824,7 @@ void Mem_PrintList(size_t minallocationsize)
        }
 }
 
-void MemList_f(void)
+static void MemList_f(void)
 {
        switch(Cmd_Argc())
        {
@@ -842,8 +842,7 @@ void MemList_f(void)
        }
 }
 
-extern void R_TextureStats_Print(qboolean printeach, qboolean printpool, qboolean printtotal);
-void MemStats_f(void)
+static void MemStats_f(void)
 {
        Mem_CheckSentinelsGlobal();
        R_TextureStats_Print(false, false, true);