]> de.git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
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 f01040391e931c570a04eaff68daf4be00b331f0..1807fff4f586909cc228751142c215397ecb9414 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 d6f522cb364b283cbeab56431dd4f934ab1b4b65..b9bf5ab3386e8192b655581ea333d919f32d4488 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 4e08a3ab2d7898d65bbf893aa8ff70562c8fa2c0..53156a92ca994440ffbc86ba361c3e016cc76855 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 43aa005bd0e9feab61cd2e1ac77eaa67e9a68d75..4183a3f1b90294dc0cf5b68d301d9deb1e6db452 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 c3eef34081e835296f1a08800b37a1663fa55521..70810fce77c665dbd7c83b2380e4845687bb4203 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 584332c3c80e64399e7c0c373b74f89c338fd090..199e064a5bb62c19136ed6571ddaedf9bab42d8b 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 775a150bd2e094a4d2d9f26f185eb707ca489f0f..f0905e98d787051e07beeef4f25cb349902b1a04 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 6618d329e4bb32fad5e73de05b8943f2ff62539a..75ee9b3dcb77656e73a60431df287bbfe47e671d 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 31a231805919af431cbeda69af848ed4ef80c1bc..f48aa9c4eec2ec13278d821b8f8d781d71b7c5b9 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 3f37a71c26fab0abc73b3dc8382b532c6befd687..5978e5b2977003691c7fd2d7faf02ed9b8a75ea2 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 d9e81cde60a670479b83d8f41fb7c2696ffb0e0d..ad83e34d0a61988b3cee2520533efbe9682dade6 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 e2af3432bacd586d8035d2b5ba14b34a43f79867..eb2215bbaeea2fc04ab1979f99bc44ce20e0a24d 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 4b0afb0d7efbc72015824ad4eab01dd345a162bb..bf26c4b4e3c5e86e9630b11863319d67ad3c854a 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 49fa7420320d8a2900bd159007e583640cdf5be3..064321296fd02ccbb42e992694e3d2e925748fe5 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 2ea778eba19475087a87bad70b89e305d47f2a02..adaf7967eb16f057997a96d779a225966580a3aa 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 3439affa82046866184eb6572cea685d464e70ad..51240d7258dee9a1f773cf0db93ec798fcb97922 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 1a8d0f170cc714bf19f5402779d1b91da93b5177..b77fe6b1ea2d2cb1f3a12ea964655208df4fd859 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 d54dfafd1a64e373855ea12352ec430b50711206..d7f8f946d57f35232dd0acf19e12dd4d847b4d32 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