Added in_mouse_x and in_mouse_y, which contain the rel. coords of the mouse.
authorblack <black@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 21 Oct 2003 12:08:29 +0000 (12:08 +0000)
committerblack <black@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 21 Oct 2003 12:08:29 +0000 (12:08 +0000)
Fixed a bug where PRVM_Stacktrace/PR_Stacktrace were involved.
Added some vm builtin functions to the new vm and changed PRVM_ED_LoadFromFile, so it can load multiple files.

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

18 files changed:
cl_main.c
cl_screen.c
cl_screen.h
client.h
gl_backend.c
gl_backend.h
gl_draw.c
host.c
input.h
menu.c
pr_exec.c
progsvm.h
prvm_cmds.c
prvm_edict.c
prvm_exec.c
prvm_execprogram.h
vid_shared.c
vid_wgl.c

index f010403..1807fff 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -1107,27 +1107,10 @@ int CL_ReadFromServer(void)
 CL_SendCmd
 =================
 */
-void CL_SendCmd(void)
+void CL_SendCmd(usercmd_t *cmd)
 {
-       usercmd_t cmd;
-
        if (cls.signon == SIGNONS)
-       {
-               // get basic movement from keyboard
-               CL_BaseMove(&cmd);
-               
-               // OS independent code
-               IN_PreMove();
-                       
-               // allow mice or other external controllers to add to the move
-               IN_Move(&cmd);
-                       
-               // OS independent code
-               IN_PostMove();
-                       
-               // send the unreliable message
-               CL_SendMove(&cmd);
-       }
+               CL_SendMove(cmd);
 
        if (cls.demoplayback)
        {
index d6f522c..b9bf5ab 100644 (file)
@@ -618,6 +618,48 @@ void DrawQ_Mesh (drawqueuemesh_t *mesh, int flags)
        r_refdef.drawqueuesize += dq->size;
 }
 
+void DrawQ_SetClipArea(float x, float y, float width, float height)
+{
+       drawqueue_t * dq;
+       if(r_refdef.drawqueuesize + sizeof(*dq) > r_refdef.maxdrawqueuesize)
+       {
+               Con_DPrintf("DrawQueue full !\n");
+               return;
+       }
+       dq = (void*) (r_refdef.drawqueue + r_refdef.drawqueuesize);
+       dq->size = sizeof(*dq);
+       dq->command = DRAWQUEUE_SETCLIP;
+       dq->x = x;
+       dq->y = y;
+       dq->scalex = width;
+       dq->scaley = height;
+       dq->flags = 0;
+       dq->color = 0;
+       
+       r_refdef.drawqueuesize += dq->size;
+}
+
+void DrawQ_ResetClipArea(void)
+{
+       drawqueue_t *dq;
+       if(r_refdef.drawqueuesize + sizeof(*dq) > r_refdef.maxdrawqueuesize)
+       {
+               Con_DPrintf("DrawQueue full !\n");
+               return;
+       }
+       dq = (void*) (r_refdef.drawqueue + r_refdef.drawqueuesize);
+       dq->size = sizeof(*dq);
+       dq->command = DRAWQUEUE_RESETCLIP;
+       dq->x = 0;
+       dq->y = 0;
+       dq->scalex = 0;
+       dq->scaley = 0;
+       dq->flags = 0;
+       dq->color = 0;
+       
+       r_refdef.drawqueuesize += dq->size;
+}
+
 /*
 ====================
 CalcFov
index 4e08a3a..53156a9 100644 (file)
@@ -5,6 +5,8 @@
 // drawqueue stuff for use by client to feed 2D art to renderer
 #define DRAWQUEUE_STRING 0
 #define DRAWQUEUE_MESH 1
+#define DRAWQUEUE_SETCLIP 2
+#define DRAWQUEUE_RESETCLIP 3
 
 typedef struct drawqueue_s
 {
@@ -51,6 +53,10 @@ void DrawQ_Fill(float x, float y, float w, float h, float red, float green, floa
 void DrawQ_SuperPic(float x, float y, char *picname, float width, float height, float s1, float t1, float r1, float g1, float b1, float a1, float s2, float t2, float r2, float g2, float b2, float a2, float s3, float t3, float r3, float g3, float b3, float a3, float s4, float t4, float r4, float g4, float b4, float a4, int flags);
 // draw a triangle mesh
 void DrawQ_Mesh(drawqueuemesh_t *mesh, int flags);
+// set the clipping area
+void DrawQ_SetClipArea(float x, float y, float width, float height);
+// reset the clipping area
+void DrawQ_ResetClipArea(void);
 
 void SHOWLMP_decodehide(void);
 void SHOWLMP_decodeshow(void);
index 43aa005..4183a3f 100644 (file)
--- a/client.h
+++ b/client.h
@@ -535,7 +535,7 @@ extern      kbutton_t       in_strafe;
 extern         kbutton_t       in_speed;
 
 void CL_InitInput (void);
-void CL_SendCmd (void);
+void CL_SendCmd (usercmd_t *cmd);
 void CL_SendMove (usercmd_t *cmd);
 
 void CL_LerpUpdate(entity_t *e);
index c3eef34..70810fc 100644 (file)
@@ -344,6 +344,7 @@ static struct
        int blend;
        GLboolean depthmask;
        int depthtest;
+       int scissortest;
        int unit;
        int clientunit;
        gltextureunit_t units[MAX_TEXTUREUNITS];
@@ -605,6 +606,26 @@ void GL_LockArrays(int first, int count)
        }
 }
 
+void GL_Scissor (int x, int y, int width, int height)
+{
+       CHECKGLERROR
+       qglScissor(x, vid.realheight - (y + height),width,height);      
+       CHECKGLERROR
+}
+
+void GL_ScissorTest(qboolean state)
+{
+       if(gl_state.scissortest == state)
+               return;
+       
+       CHECKGLERROR
+       if((gl_state.scissortest = state))
+               qglEnable(GL_SCISSOR_TEST);
+       else
+               qglDisable(GL_SCISSOR_TEST);
+       CHECKGLERROR
+}
+
 void GL_TransformToScreen(const vec4_t in, vec4_t out)
 {
        vec4_t temp;
index 584332c..199e064 100644 (file)
@@ -23,6 +23,9 @@ void GL_TransformToScreen(const vec4_t in, vec4_t out);
 void GL_LockArrays(int first, int count);
 void GL_ActiveTexture(int num);
 void GL_ClientActiveTexture(int num);
+void GL_Scissor(int x, int y, int width, int height); // AK for DRAWQUEUE_SETCLIP
+void GL_ScissorTest(qboolean state);   // AK for DRAWQUEUE_(RE)SETCLIP
 
 extern cvar_t gl_lockarrays;
 extern cvar_t gl_mesh_copyarrays;
index 775a150..f0905e9 100644 (file)
--- a/gl_draw.c
+++ b/gl_draw.c
@@ -328,7 +328,7 @@ void Draw_FreePic(char *picname)
        hashkey = ((crc >> 8) ^ crc) % CACHEPICHASHSIZE;
        for (pic = cachepichash[hashkey];pic;pic = pic->chain)
        {
-               if (!strcmp (picname, pic->name))
+               if (!strcmp (picname, pic->name) && pic->tex)
                {
                        R_FreeTexture(pic->tex);
                        pic->width = 0;
@@ -507,6 +507,24 @@ void R_DrawQueue(void)
                        R_Mesh_Draw(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i);
                        currentpic = "\0";
                        break;
+               case DRAWQUEUE_SETCLIP:
+                       {
+                               // We have to convert the con coords into real coords
+                               int x , y, width, height;
+                               x = dq->x * (vid.realwidth / vid.conwidth) + vid.realx;
+                               // OGL uses top to bottom 
+                               y = (dq->y + dq->scaley) * (vid.realheight / vid.conheight) + vid.realy;
+                               width = dq->scalex * (vid.realwidth / vid.conwidth);
+                               height = dq->scaley * (vid.realheight / vid.conheight);
+
+                               GL_Scissor(x, y, width, height);
+
+                               GL_ScissorTest(true);
+                       }
+                       break;
+               case DRAWQUEUE_RESETCLIP:
+                       GL_ScissorTest(false);
+                       break;                          
                }
        }
 
diff --git a/host.c b/host.c
index 6618d32..75ee9b3 100644 (file)
--- a/host.c
+++ b/host.c
@@ -687,7 +687,8 @@ void _Host_Frame (float time)
        static double time2 = 0;
        static double time3 = 0;
        int pass1, pass2, pass3;
-
+       usercmd_t cmd; // Used for receiving input
+       
        if (setjmp(host_abortserver))
                return;                 // something bad happened, or the server disconnected
 
@@ -706,6 +707,9 @@ void _Host_Frame (float time)
        // allow mice or other external controllers to add commands
        IN_Commands();
 
+       // Collect input into cmd
+       IN_ProcessMove(&cmd);
+       
        // process console commands
        Cbuf_Execute();
 
@@ -714,7 +718,7 @@ void _Host_Frame (float time)
 
        // if running the server locally, make intentions now
        if (cls.state == ca_connected && sv.active)
-               CL_SendCmd();
+               CL_SendCmd(&cmd);
 
 //-------------------
 //
@@ -744,7 +748,7 @@ void _Host_Frame (float time)
                // if running the server remotely, send intentions now after
                // the incoming messages have been read
                if (!sv.active)
-                       CL_SendCmd();
+                       CL_SendCmd(&cmd);
                CL_ReadFromServer();
        }
 
diff --git a/input.h b/input.h
index 31a2318..f48aa9c 100644 (file)
--- a/input.h
+++ b/input.h
@@ -33,6 +33,9 @@ extern float in_mouse_x, in_mouse_y;
 void IN_Commands (void);
 // oportunity for devices to stick commands on the script buffer
 
+// AK added to allow mouse movement for the menu
+void IN_ProcessMove(usercmd_t *cmd);
+
 void IN_Move (usercmd_t *cmd);
 // add additional movement on top of the keyboard move cmd
 
diff --git a/menu.c b/menu.c
index 3f37a71..5978e5b 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -3776,6 +3776,9 @@ void MP_Keydown (int key, char ascii)
        PRVM_Begin;
        PRVM_SetProg(PRVM_MENUPROG);
 
+       // set time
+       *prog->time = realtime;
+
        // pass key
        prog->globals[OFS_PARM0] = (float) key;
        prog->globals[OFS_PARM1] = (float) ascii;
@@ -3789,6 +3792,9 @@ void MP_Draw (void)
        PRVM_Begin;
        PRVM_SetProg(PRVM_MENUPROG);
 
+       // set time
+       *prog->time = realtime;
+
        PRVM_ExecuteProgram(m_draw,"");
 
        PRVM_End;
@@ -3799,6 +3805,9 @@ void MP_ToggleMenu_f (void)
        PRVM_Begin;
        PRVM_SetProg(PRVM_MENUPROG);
 
+       // set time
+       *prog->time = realtime;
+
        PRVM_ExecuteProgram((func_t) (PRVM_ED_FindFunction(M_F_TOGGLE) - prog->functions),"");
 
        PRVM_End;
@@ -3809,6 +3818,9 @@ void MP_Shutdown (void)
        PRVM_Begin;
        PRVM_SetProg(PRVM_MENUPROG);
 
+       // set time
+       *prog->time = realtime;
+
        PRVM_ExecuteProgram((func_t) (PRVM_ED_FindFunction(M_F_SHUTDOWN) - prog->functions),"");
 
        // reset key_dest
@@ -3851,6 +3863,9 @@ void MP_Init (void)
        m_draw = (func_t) (PRVM_ED_FindFunction(M_F_DRAW) - prog->functions);
        m_keydown = (func_t) (PRVM_ED_FindFunction(M_F_KEYDOWN) - prog->functions);
 
+       // set time
+       *prog->time = realtime;
+       
        // call the prog init
        PRVM_ExecuteProgram((func_t) (PRVM_ED_FindFunction(M_F_INIT) - prog->functions),"");
        
@@ -3917,13 +3932,17 @@ void MR_Init()
 {
        // set router console commands
        Cvar_RegisterVariable (&forceqmenu);
+       Cmd_AddCommand ("menu_restart",MR_Restart);
 
+       // use -forceqmenu to use always the normal quake menu (it sets forceqmenu to 1)
        if(COM_CheckParm("-forceqmenu"))
                Cvar_SetValueQuick(&forceqmenu,1);
-
-       Cmd_AddCommand ("menu_restart",MR_Restart);
-       
-       MR_SetRouting (FALSE);
+       // use -useqmenu for debugging proposes, cause it starts 
+       // the normal quake menu only the first time
+       else if(COM_CheckParm("-useqmenu"))
+               MR_SetRouting (TRUE);
+       else
+               MR_SetRouting (FALSE);  
 }
 
 
index d9e81cd..ad83e34 100644 (file)
--- a/pr_exec.c
+++ b/pr_exec.c
@@ -28,7 +28,9 @@ typedef struct
 } prstack_t;
 
 #define        MAX_STACK_DEPTH         256
-prstack_t      pr_stack[MAX_STACK_DEPTH];
+// stacktrace writes into pr_stack[MAX_STACK_DEPTH]
+// thus increase the array, so depth wont be overwritten
+prstack_t      pr_stack[MAX_STACK_DEPTH+1];
 int                    pr_depth = 0;
 
 #define        LOCALSTACK_SIZE         2048
index e2af343..eb2215b 100644 (file)
--- a/progsvm.h
+++ b/progsvm.h
@@ -209,7 +209,6 @@ typedef struct prvm_builtin_mem_s
 */
 #define PRVM_FE_CLASSNAME   8
 #define PRVM_FE_CHAIN          4
-#define PRVM_GE_TIME           2
 #define PRVM_OP_STATE          1
 
 #define        PRVM_MAX_STACK_DEPTH            256
@@ -243,7 +242,9 @@ typedef struct vm_prog_s
        mfunction_t                     *xfunction;
        int                                     xstatement;
 
-       prvm_stack_t            stack[PRVM_MAX_STACK_DEPTH];
+       // stacktrace writes into stack[MAX_STACK_DEPTH]
+       // thus increase the array, so depth wont be overwritten
+       prvm_stack_t            stack[PRVM_MAX_STACK_DEPTH+1];
        int                                     depth;
        
        int                                     localstack[PRVM_LOCALSTACK_SIZE];
@@ -269,7 +270,10 @@ typedef struct vm_prog_s
        mempool_t                       *edicts_mempool;
        
        // has to be updated every frame - so the vm time is up-to-date
-       double                          time;
+       // AK changed so time will point to the time field (if there is one) else it points to _time
+       // actually should be double, but qc doesnt support it
+       float                           *time;
+       float                           _time;
 
        // name of the prog, e.g. "Server", "Client" or "Menu" (used in for text output)
        char                            *name;
@@ -423,10 +427,10 @@ void PRVM_ED_PrintNum (int ent);
 //============================================================================
 
 // used as replacement for a prog stack
-#define PRVM_DEBUGPRSTACK
+//#define PRVM_DEBUGPRSTACK
 
 #ifdef PRVM_DEBUGPRSTACK
-#define PRVM_Begin  if(prog != 0) Con_Printf("prog not 0(prog = %i)!\n", PRVM_GetProgNr())
+#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  
@@ -444,11 +448,6 @@ void PRVM_ED_PrintNum (int ent);
 // helper macro to make function pointer calls easier
 #define PRVM_GCALL(func)       if(prog->func) prog->func
 
-/*#define PRVM_ERROR   if(!prog->error_cmd)  \
-                                               Sys_Error("PRVM: No error_cmd specified !\n");   \
-                                       else \
-                                               prog->error_cmd*/
-
 #define PRVM_ERROR             Host_Error
 
 // other prog handling functions
index 4b0afb0..bf26c4b 100644 (file)
@@ -82,6 +82,10 @@ float        clientstate()
                changelevel(string map)
                localsound(string sample)
 vector getmousepos()
+float  gettime()
+               loadfromdata(string data)
+               loadfromfile(string file)
+float  mod(float val, float m)
                
 perhaps only : Menu : WriteMsg 
 ===============================
@@ -105,7 +109,10 @@ float      drawcharacter(vector position, float character, vector scale, vector rgb,
 float  drawstring(vector position, string text, vector scale, vector rgb, float alpha, float flag)
 float  drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag)
 float  drawfill(vector position, vector size, vector rgb, float alpha, float flag)
-
+               drawsetcliparea(float x, float y, float width, float height)
+               drawresetcliparea()
+vector getimagesize(string pic)
+               
 
 ==============================================================================
 menu cmd list:
@@ -859,7 +866,7 @@ void VM_find (void)
                }
        }
 
-       VM_RETURN_EDICT(sv.edicts);
+       VM_RETURN_EDICT(prog->edicts);
 }
 
 /*
@@ -1066,7 +1073,9 @@ void VM_coredump (void)
 {
        VM_SAFEPARMCOUNT(0,VM_coredump);
 
-       PRVM_ED_PrintEdicts_f ();
+       Cbuf_AddText("prvm_edicts ");
+       Cbuf_AddText(PRVM_NAME);
+       Cbuf_AddText("\n");
 }
 
 /*
@@ -1224,8 +1233,8 @@ sizebuf_t *VM_WriteDest (void)
 
        case MSG_ONE:
                destclient = (int) PRVM_G_FLOAT(OFS_PARM2);
-               if (!sv.active  || destclient < 0 || destclient >= svs.maxclients || !svs.clients[destclient].active)
-                       PRVM_ERROR("VM_clientcommand: %s: invalid client/server is not active !", PRVM_NAME);
+               if (destclient < 0 || destclient >= svs.maxclients || !svs.clients[destclient].active)
+                       PRVM_ERROR("VM_clientcommand: %s: invalid client !\n", PRVM_NAME);
 
                return &svs.clients[destclient].message;
 
@@ -1638,7 +1647,7 @@ void VM_fopen(void)
        // \ is a windows-ism (so it's naughty to use it, / works on all platforms)
        if ((filename[0] == '.' && filename[1] == '.') || filename[0] == '/' || strrchr(filename, ':') || strrchr(filename, '\\'))
        {
-               Con_Printf("VM_fopen: dangerous or non-portable filename \"%s\" not allowed. (contains : or \\ or begins with .. or /)\n", filename);
+               Con_Printf("VM_fopen: %s dangerous or non-portable filename \"%s\" not allowed. (contains : or \\ or begins with .. or /)\n", PRVM_NAME, filename);
                PRVM_G_FLOAT(OFS_RETURN) = -4;
                return;
        }
@@ -2065,6 +2074,105 @@ void VM_clientstate(void)
        PRVM_G_FLOAT(OFS_RETURN) = cls.state;
 }
 
+/*
+=========
+VM_getmousepos
+
+vector getmousepos()
+=========
+*/
+void VM_getmousepos(void)
+{
+
+       VM_SAFEPARMCOUNT(0,VM_getmousepos);
+       
+       PRVM_G_VECTOR(OFS_RETURN)[0] = in_mouse_x;
+       PRVM_G_VECTOR(OFS_RETURN)[1] = in_mouse_y;
+       PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
+}
+
+/*
+=========
+VM_gettime
+
+float  gettime(void)
+=========
+*/
+void VM_gettime(void)
+{
+       VM_SAFEPARMCOUNT(0,VM_gettime);
+
+       PRVM_G_FLOAT(OFS_RETURN) = (float) *prog->time;
+}
+
+/*
+=========
+VM_loadfromdata
+
+loadfromdata(string data)
+=========
+*/
+void VM_loadfromdata(void)
+{
+       VM_SAFEPARMCOUNT(1,VM_loadentsfromfile);
+
+       PRVM_ED_LoadFromFile(PRVM_G_STRING(OFS_PARM0));
+}
+
+/*
+=========
+VM_loadfromfile
+
+loadfromfile(string file)
+=========
+*/
+void VM_loadfromfile(void)
+{
+       char *filename;
+       qbyte *data;
+       
+       VM_SAFEPARMCOUNT(1,VM_loadfromfile);
+       
+       filename = PRVM_G_STRING(OFS_PARM0);
+       // .. is parent directory on many platforms
+       // / is parent directory on Amiga
+       // : is root of drive on Amiga (also used as a directory separator on Mac, but / works there too, so that's a bad idea)
+       // \ is a windows-ism (so it's naughty to use it, / works on all platforms)
+       if ((filename[0] == '.' && filename[1] == '.') || filename[0] == '/' || strrchr(filename, ':') || strrchr(filename, '\\'))
+       {
+               Con_Printf("VM_loadfromfile: %s dangerous or non-portable filename \"%s\" not allowed. (contains : or \\ or begins with .. or /)\n", PRVM_NAME, filename);
+               PRVM_G_FLOAT(OFS_RETURN) = -4;
+               return;
+       }
+
+       data = FS_LoadFile(va("data/%s", filename), false);
+       if (data == NULL)
+               PRVM_G_FLOAT(OFS_RETURN) = -1;
+       
+       PRVM_ED_LoadFromFile(data);
+
+       Mem_Free(data);
+}
+
+
+/*
+=========
+VM_modulo
+
+float  mod(float val, float m)
+=========
+*/
+void VM_modulo(void)
+{
+       int val, m;
+       VM_SAFEPARMCOUNT(2,VM_module);
+
+       val = (int) PRVM_G_FLOAT(OFS_PARM0);
+       m       = (int) PRVM_G_FLOAT(OFS_PARM1);
+
+       PRVM_G_FLOAT(OFS_RETURN) = (float) (val % m);
+}
+
 //=============================================================================
 // Draw builtins (client & menu)
 
@@ -2100,11 +2208,12 @@ void VM_precache_pic(void)
        PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
        
        if(!s)
-               PRVM_ERROR ("VM_precache_pic: %s: NULL\n");
+               PRVM_ERROR ("VM_precache_pic: %s: NULL\n", PRVM_NAME);
 
        VM_CheckEmptyString (s);
        
-       Draw_CachePic(s); 
+       if(!Draw_CachePic(s))
+               PRVM_G_INT(OFS_RETURN) = PRVM_SetString(""); 
 }
 
 /*
@@ -2253,7 +2362,7 @@ void VM_drawpic(void)
 
        VM_CheckEmptyString (pic);
 
-       // is pic cached ?
+       // is pic cached ? no function yet for that
        if(!1)
        {
                Con_Printf("VM_drawpic: %s: %s not cached !\n", PRVM_NAME, pic);
@@ -2316,19 +2425,64 @@ void VM_drawfill(void)
 
 /*
 =========
-VM_getmousepos
+VM_drawsetcliparea
 
-vector getmousepos()
+drawsetcliparea(float x, float y, float width, float height)
 =========
 */
-void VM_getmousepos(void)
+void VM_drawsetcliparea(void)
 {
+       float x,y,w,h;
+       VM_SAFEPARMCOUNT(4,VM_drawsetcliparea);
 
-       VM_SAFEPARMCOUNT(0,VM_getmousepos);
+       x = bound(0,PRVM_G_FLOAT(OFS_PARM0),vid.conwidth);
+       y = bound(0,PRVM_G_FLOAT(OFS_PARM1),vid.conheight);
+       w = bound(0,PRVM_G_FLOAT(OFS_PARM2),x);
+       h = bound(0,PRVM_G_FLOAT(OFS_PARM3),y); 
+
+       DrawQ_SetClipArea(x,y,w,h);
+}
+
+/*
+=========
+VM_drawresetcliparea
+
+drawresetcliparea()
+=========
+*/
+void VM_drawresetcliparea(void)
+{
+       VM_SAFEPARMCOUNT(0,VM_drawresetcliparea);
+
+       DrawQ_ResetClipArea();
+}
+
+/*
+=========
+VM_getimagesize
+
+vector getimagesize(string pic)
+=========
+*/
+void VM_getimagesize(void)
+{
+       char *p;
+       cachepic_t *pic;
+
+       VM_SAFEPARMCOUNT(1,VM_getimagesize);
        
-       PRVM_G_VECTOR(OFS_RETURN)[0] = in_mouse_x;
-       PRVM_G_VECTOR(OFS_RETURN)[1] = in_mouse_y;
-       PRVM_G_VECTOR(OFS_RETURN)[0] = 0;
+       p = PRVM_G_STRING(OFS_PARM0);
+
+       if(!p)
+               PRVM_ERROR("VM_getimagepos: %s passed null picture name !\n", PRVM_NAME);
+       
+       VM_CheckEmptyString (p);
+
+       pic = Draw_CachePic (p);
+
+       PRVM_G_VECTOR(OFS_RETURN)[0] = pic->width;
+       PRVM_G_VECTOR(OFS_RETURN)[1] = pic->height;
+       PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
 }
 
 void VM_Cmd_Init(void)
@@ -2560,11 +2714,11 @@ prvm_builtin_t vm_m_builtins[] = {
        VM_clcommand,
        VM_changelevel,
        VM_localsound,  
-       VM_getmousepos, // 66
-       0,
-       0,
-       0,
-       0,                              // 70
+       VM_getmousepos,
+       VM_gettime,
+       VM_loadfromdata,
+       VM_loadfromfile,
+       VM_modulo,              // 70
        e10,                    // 80
        e10,                    // 90
        e10,                    // 100
@@ -2593,10 +2747,10 @@ prvm_builtin_t vm_m_builtins[] = {
        VM_drawcharacter,
        VM_drawstring,
        VM_drawpic,
-       VM_drawfill,    // 457
-       0,
-       0,
-       0,                              // 460
+       VM_drawfill,    
+       VM_drawsetcliparea,
+       VM_drawresetcliparea,
+       VM_getimagesize,// 460
        e10,                    // 470
        e10,                    // 480
        e10,                    // 490
index 49fa742..0643212 100644 (file)
@@ -50,8 +50,10 @@ void PRVM_MEM_Alloc()
 {
        int i;
 
+       // reserve space for the null entity aka world
        // check bound of max_edicts
-       prog->max_edicts = min(prog->max_edicts,prog->limit_edicts);
+       prog->max_edicts = bound(1, prog->max_edicts, prog->limit_edicts);
+       prog->num_edicts = bound(1, prog->num_edicts, prog->max_edicts);        
 
        // edictprivate_size has to be min as big prvm_edict_private_t
        prog->edictprivate_size = max(prog->edictprivate_size,(int)sizeof(prvm_edict_private_t)); 
@@ -216,14 +218,14 @@ prvm_edict_t *PRVM_ED_Alloc (void)
        // the client qc dont need maxclients
        // thus it doesnt need to use svs.maxclients
        // AK:  changed i=svs.maxclients+1
-       // AK:  changed so the edict 0 wont spawned -> used as reserved/world entity
+       // AK:  changed so the edict 0 wont spawn -> used as reserved/world entity
        //              although the menu/client has no world
        for (i = 1;i < prog->num_edicts;i++)
        {
                e = PRVM_EDICT_NUM(i);
                // the first couple seconds of server time can involve a lot of
                // freeing and allocating, so relax the replacement policy
-               if (e->e->free && ( e->e->freetime < 2 || prog->time - e->e->freetime > 0.5 ) )
+               if (e->e->free && ( e->e->freetime < 2 || *prog->time - e->e->freetime > 0.5 ) )
                {
                        PRVM_ED_ClearEdict (e);
                        return e;
@@ -256,7 +258,7 @@ void PRVM_ED_Free (prvm_edict_t *ed)
        PRVM_GCALL(free_edict)(ed);
 
        ed->e->free = true;
-       ed->e->freetime = prog->time;
+       ed->e->freetime = *prog->time;
 }
 
 //===========================================================================
@@ -770,7 +772,7 @@ void PRVM_ED_Count_f (void)
                        active++;
                }
                
-               Con_Printf ("num_edicts:%3i\n", sv.num_edicts);
+               Con_Printf ("num_edicts:%3i\n", prog->num_edicts);
                Con_Printf ("active    :%3i\n", active);
        }
 
@@ -913,7 +915,7 @@ qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s)
        switch (key->type & ~DEF_SAVEGLOBAL)
        {
        case ev_string:
-               val->string = PRVM_SetString(ED_NewString(s));
+               val->string = PRVM_SetString(PRVM_ED_NewString(s));
                break;
 
        case ev_float:
@@ -1027,7 +1029,7 @@ const char *PRVM_ED_ParseEdict (const char *data, prvm_edict_t *ent)
 
                strcpy (keyname, com_token);
 
-               // another hack to fix heynames with trailing spaces
+               // another hack to fix keynames with trailing spaces
                n = strlen(keyname);
                while (n && keyname[n-1] == ' ')
                {
@@ -1095,16 +1097,12 @@ void PRVM_ED_LoadFromFile (const char *data)
        int parsed, inhibited, spawned, died;
        mfunction_t *func;
 
-       ent = NULL;
        parsed = 0;
        inhibited = 0;
        spawned = 0;
        died = 0;
 
-       // time defined ?
-       if(prog->flag & PRVM_GE_TIME)
-               PRVM_G_FLOAT(PRVM_ED_FindFieldOffset("time")) = prog->time;
-       
+
 // parse ents
        while (1)
        {
@@ -1112,12 +1110,14 @@ void PRVM_ED_LoadFromFile (const char *data)
                if (!COM_ParseToken(&data, false))
                        break;
                if (com_token[0] != '{')
-                       PRVM_ERROR ("PRVM_ED_LoadFromFile: found %s when expecting (%s) {",com_token, PRVM_NAME);
+                       PRVM_ERROR ("PRVM_ED_LoadFromFile: %s: found %s when expecting {", PRVM_NAME, com_token);
 
-               if (!ent)
+               // CHANGED: this is not conform to ED_LoadFromFile
+               if(!prog->num_edicts) 
                        ent = PRVM_EDICT_NUM(0);
-               else
-                       ent = PRVM_ED_Alloc ();
+               else 
+                       ent = PRVM_ED_Alloc();
+
                data = PRVM_ED_ParseEdict (data, ent);
                parsed++;
 
@@ -1167,8 +1167,8 @@ void PRVM_ED_LoadFromFile (const char *data)
                        died++;
        }
 
-       Con_DPrintf ("%s: %i entities parsed, %i inhibited, %i spawned (%i removed self, %i stayed)\n", PRVM_NAME, parsed, inhibited, 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", PRVM_NAME, parsed, inhibited, prog->num_edicts, spawned, died, spawned - died);
+}      
 
 // not used
 /*
@@ -1206,6 +1206,7 @@ void PRVM_ResetProg()
        
        memset(prog,0,sizeof(prvm_prog_t));
        
+       prog->time = &prog->_time;
        
        prog->progs_mempool = t1;
        prog->edictstring_mempool = t2;
@@ -1444,7 +1445,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required
        prog->self = PRVM_ED_FindGlobal("self");
 
        if(PRVM_ED_FindGlobal("time"))
-               prog->flag |= PRVM_GE_TIME;
+               prog->time = &PRVM_G_FLOAT(PRVM_ED_FindGlobal("time")->ofs);
 
        if(PRVM_ED_FindField ("chain"))
                prog->flag |= PRVM_FE_CHAIN;
@@ -1453,7 +1454,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required
                prog->flag |= PRVM_FE_CLASSNAME; 
 
        if(PRVM_ED_FindField ("nextthink") && PRVM_ED_FindField ("frame") && PRVM_ED_FindField ("think") 
-               && prog->flag &  PRVM_GE_TIME && prog->self) 
+               && prog->flag && prog->self) 
                prog->flag |= PRVM_OP_STATE;
        
        PRVM_GCALL(reset_cmd)();
@@ -1647,6 +1648,8 @@ void PRVM_InitProg(int prognr)
 
        memset(prog, 0, sizeof(prvm_prog_t));
 
+       prog->time = &prog->_time;
+
        PRVM_GCALL(init_cmd)();
 }
 
index 2ea778e..adaf796 100644 (file)
@@ -369,9 +369,9 @@ PRVM_ExecuteProgram
 ====================
 */
 // LordHavoc: optimized
-#define OPA ((eval_t *)&prog->globals[(unsigned short) st->a])
-#define OPB ((eval_t *)&prog->globals[(unsigned short) st->b])
-#define OPC ((eval_t *)&prog->globals[(unsigned short) st->c])
+#define OPA ((prvm_eval_t *)&prog->globals[(unsigned short) st->a])
+#define OPB ((prvm_eval_t *)&prog->globals[(unsigned short) st->b])
+#define OPC ((prvm_eval_t *)&prog->globals[(unsigned short) st->c])
 extern cvar_t prvm_boundscheck;
 extern cvar_t prvm_traceqc;
 extern int             PRVM_ED_FindFieldOffset (const char *field);
index 3439aff..51240d7 100644 (file)
                                }
 #endif
                                ed = PRVM_PROG_TO_EDICT(OPA->edict);
-                               OPC->_int = ((eval_t *)((int *)ed->v + OPB->_int))->_int;
+                               OPC->_int = ((prvm_eval_t *)((int *)ed->v + OPB->_int))->_int;
                                break;
 
                        case OP_LOAD_V:
                                }
 #endif
                                ed = PRVM_PROG_TO_EDICT(OPA->edict);
-                               OPC->vector[0] = ((eval_t *)((int *)ed->v + OPB->_int))->vector[0];
-                               OPC->vector[1] = ((eval_t *)((int *)ed->v + OPB->_int))->vector[1];
-                               OPC->vector[2] = ((eval_t *)((int *)ed->v + OPB->_int))->vector[2];
+                               OPC->vector[0] = ((prvm_eval_t *)((int *)ed->v + OPB->_int))->vector[0];
+                               OPC->vector[1] = ((prvm_eval_t *)((int *)ed->v + OPB->_int))->vector[1];
+                               OPC->vector[2] = ((prvm_eval_t *)((int *)ed->v + OPB->_int))->vector[2];
                                break;
 
                //==================
                                        startprofile = profile;
                                        prog->xstatement = st - prog->statements;
                                        ed = PRVM_PROG_TO_EDICT(PRVM_G_INT(prog->self->ofs));
-                                       PRVM_E_FLOAT(ed,PRVM_ED_FindFieldOffset ("nextthink")) = PRVM_G_FLOAT(PRVM_ED_FindGlobal("time")->ofs*4) + 0.1;
+                                       PRVM_E_FLOAT(ed,PRVM_ED_FindFieldOffset ("nextthink")) = *prog->time + 0.1;
                                        PRVM_E_FLOAT(ed,PRVM_ED_FindFieldOffset ("frame")) = OPA->_float;
                                        *(func_t *)((qbyte*)ed->v + PRVM_ED_FindFieldOffset ("think")) = OPB->function;
                                }
index 1a8d0f1..b77fe6b 100644 (file)
@@ -519,6 +519,27 @@ void IN_PostMove(void)
        CL_AdjustAngles();
 }
 
+/*
+===========
+IN_DoMove
+===========
+*/
+void IN_ProcessMove(usercmd_t *cmd)
+{
+       // get basic movement from keyboard
+       CL_BaseMove(cmd);
+       
+       // OS independent code
+       IN_PreMove();
+       
+       // allow mice or other external controllers to add to the move
+       IN_Move(cmd);
+       
+       // OS independent code
+       IN_PostMove();
+}
+
+
 void IN_Mouse(usercmd_t *cmd, float mx, float my)
 {
        int mouselook = (in_mlook.state & 1) || freelook.integer;
index d54dfaf..d7f8f94 100644 (file)
--- a/vid_wgl.c
+++ b/vid_wgl.c
@@ -1324,6 +1324,7 @@ void IN_MouseMove (usercmd_t *cmd)
        {
                GetCursorPos (&current_pos);
                ui_mouseupdate(current_pos.x - window_x, current_pos.y - window_y);
+               in_mouse_x = in_mouse_y = 0;
                return;
        }
 
@@ -1641,7 +1642,6 @@ void Joy_AdvancedUpdate_f (void)
        }
 }
 
-
 /*
 ===========
 IN_Commands