From 28620abb9561ae4dfd3626c69912af0aa2e941df Mon Sep 17 00:00:00 2001 From: black Date: Tue, 21 Oct 2003 12:08:29 +0000 Subject: [PATCH] Added in_mouse_x and in_mouse_y, which contain the rel. coords of the mouse. 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 --- cl_main.c | 21 +---- cl_screen.c | 42 ++++++++++ cl_screen.h | 6 ++ client.h | 2 +- gl_backend.c | 21 +++++ gl_backend.h | 3 + gl_draw.c | 20 ++++- host.c | 10 ++- input.h | 3 + menu.c | 27 +++++- pr_exec.c | 4 +- progsvm.h | 19 ++--- prvm_cmds.c | 204 +++++++++++++++++++++++++++++++++++++++------ prvm_edict.c | 43 +++++----- prvm_exec.c | 6 +- prvm_execprogram.h | 10 +-- vid_shared.c | 21 +++++ vid_wgl.c | 2 +- 18 files changed, 371 insertions(+), 93 deletions(-) diff --git a/cl_main.c b/cl_main.c index f0104039..1807fff4 100644 --- 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) { diff --git a/cl_screen.c b/cl_screen.c index d6f522cb..b9bf5ab3 100644 --- a/cl_screen.c +++ b/cl_screen.c @@ -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 diff --git a/cl_screen.h b/cl_screen.h index 4e08a3ab..53156a92 100644 --- a/cl_screen.h +++ b/cl_screen.h @@ -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); diff --git a/client.h b/client.h index 43aa005b..4183a3f1 100644 --- 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); diff --git a/gl_backend.c b/gl_backend.c index c3eef340..70810fce 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -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; diff --git a/gl_backend.h b/gl_backend.h index 584332c3..199e064a 100644 --- a/gl_backend.h +++ b/gl_backend.h @@ -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; diff --git a/gl_draw.c b/gl_draw.c index 775a150b..f0905e98 100644 --- 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 6618d329..75ee9b3d 100644 --- 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 31a23180..f48aa9c4 100644 --- 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 3f37a71c..5978e5b2 100644 --- 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); } diff --git a/pr_exec.c b/pr_exec.c index d9e81cde..ad83e34d 100644 --- 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 diff --git a/progsvm.h b/progsvm.h index e2af3432..eb2215bb 100644 --- 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 diff --git a/prvm_cmds.c b/prvm_cmds.c index 4b0afb0d..bf26c4b4 100644 --- a/prvm_cmds.c +++ b/prvm_cmds.c @@ -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 diff --git a/prvm_edict.c b/prvm_edict.c index 49fa7420..06432129 100644 --- a/prvm_edict.c +++ b/prvm_edict.c @@ -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)(); } diff --git a/prvm_exec.c b/prvm_exec.c index 2ea778eb..adaf7967 100644 --- a/prvm_exec.c +++ b/prvm_exec.c @@ -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); diff --git a/prvm_execprogram.h b/prvm_execprogram.h index 3439affa..51240d72 100644 --- a/prvm_execprogram.h +++ b/prvm_execprogram.h @@ -217,7 +217,7 @@ } #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: @@ -232,9 +232,9 @@ } #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; //================== @@ -309,7 +309,7 @@ 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; } diff --git a/vid_shared.c b/vid_shared.c index 1a8d0f17..b77fe6b1 100644 --- a/vid_shared.c +++ b/vid_shared.c @@ -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; diff --git a/vid_wgl.c b/vid_wgl.c index d54dfafd..d7f8f946 100644 --- a/vid_wgl.c +++ b/vid_wgl.c @@ -1324,6 +1324,7 @@ void IN_MouseMove (usercmd_t *cmd) { GetCursorPos (¤t_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 -- 2.39.2