From: Mario Date: Sun, 31 May 2020 20:48:15 +0000 (+1000) Subject: Merge branch 'master' into Mario/ext_entityparam X-Git-Url: http://git.xonotic.org/?a=commitdiff_plain;h=8fcbbb10d27dabefbd27a11c6784c783ca035e75;hp=4297a9d970e88dae61030269d113f25f3386897b;p=xonotic%2Fdarkplaces.git Merge branch 'master' into Mario/ext_entityparam --- diff --git a/cmd.c b/cmd.c index 352d8c5b..a06f39ce 100644 --- a/cmd.c +++ b/cmd.c @@ -2018,6 +2018,8 @@ A complete command line has been parsed, so try to execute it FIXME: lookupnoadd the token to speed search? ============ */ +extern hook_t *csqc_concmd; + void Cmd_ExecuteString (cmd_state_t *cmd, const char *text, cmd_source_t src, qboolean lockmutex) { int oldpos; @@ -2039,7 +2041,7 @@ void Cmd_ExecuteString (cmd_state_t *cmd, const char *text, cmd_source_t src, qb { if (!strcasecmp(cmd->argv[0], func->name)) { - if (func->csqcfunc && CL_VM_ConsoleCommand(text)) //[515]: csqc + if (func->csqcfunc && Hook_Call(csqc_concmd, text)->bval) //[515]: csqc goto done; break; } diff --git a/csprogs.c b/csprogs.c index 13c27ec3..6d83a784 100644 --- a/csprogs.c +++ b/csprogs.c @@ -509,7 +509,9 @@ qboolean CL_VM_UpdateView (double frametime) return true; } -qboolean CL_VM_ConsoleCommand (const char *cmd) +hook_t *csqc_concmd; + +qboolean CL_VM_ConsoleCommand (hook_val_t *arg) { prvm_prog_t *prog = CLVM_prog; int restorevm_tempstringsbuf_cursize; @@ -522,7 +524,7 @@ qboolean CL_VM_ConsoleCommand (const char *cmd) PRVM_clientglobalfloat(time) = cl.time; PRVM_clientglobaledict(self) = cl.csqc_server2csqcentitynumber[cl.playerentity]; restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize; - PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, cmd); + PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, arg->str); // optional entity parameter for self (EXT_ENTITYPARAM) PRVM_G_INT(OFS_PARM1) = cl.csqc_server2csqcentitynumber[cl.playerentity]; prog->ExecuteProgram(prog, PRVM_clientfunction(CSQC_ConsoleCommand), "QC function CSQC_ConsoleCommand is missing"); diff --git a/csprogs.h b/csprogs.h index dff44d74..46b71eba 100644 --- a/csprogs.h +++ b/csprogs.h @@ -91,7 +91,7 @@ void CL_VM_ShutDown(void); void CL_VM_UpdateIntermissionState(int intermission); void CL_VM_UpdateShowingScoresState(int showingscores); qboolean CL_VM_InputEvent(int eventtype, float x, float y); -qboolean CL_VM_ConsoleCommand(const char *cmd); +qboolean CL_VM_ConsoleCommand(hook_val_t *arg); void CL_VM_UpdateDmgGlobals(int dmg_take, int dmg_save, vec3_t dmg_origin); void CL_VM_UpdateIntermissionState(int intermission); qboolean CL_VM_Event_Sound(int sound_num, float volume, int channel, float attenuation, int ent, vec3_t pos, int flags, float speed); diff --git a/gl_rmain.c b/gl_rmain.c index 25b88923..6c6e2c1a 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -4695,7 +4695,7 @@ r_rendertarget_t *R_RenderTarget_Get(int texturewidth, int textureheight, textyp if (r->depthisrenderbuffer) r->depthtexture = R_LoadTextureRenderBuffer(r_main_texturepool, va(vabuf, sizeof(vabuf), "renderbuffer%i_depth_type%i", i, (int)r->depthtextype), r->texturewidth, r->textureheight, r->depthtextype); else - r->depthtexture = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "rendertarget%i_depth_type%i", i, j, (int)r->depthtextype), r->texturewidth, r->textureheight, NULL, r->depthtextype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL); + r->depthtexture = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "rendertarget%i_depth_type%i", i, (int)r->depthtextype), r->texturewidth, r->textureheight, NULL, r->depthtextype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL); } r->fbo = R_Mesh_CreateFramebufferObject(r->depthtexture, r->colortexture[0], r->colortexture[1], r->colortexture[2], r->colortexture[3]); } diff --git a/hook.c b/hook.c new file mode 100644 index 00000000..344f9e9b --- /dev/null +++ b/hook.c @@ -0,0 +1,92 @@ +/* +Copyright (C) 2020 Cloudwalk + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "quakedef.h" +#include "hook.h" + +mempool_t *hooks; + +hook_t *_Hook_Register(hook_t *hook, const char *name, void *func, unsigned int argc) +{ + if (hook) { + Con_Printf("Hook %s already registered\n",hook->name); + } else { + hook = (hook_t *)Mem_Alloc(hooks, sizeof(hook_t)); + hook->name = Mem_Alloc(hooks, strlen(name) + 1); + hook->arg = Mem_Alloc(hooks, sizeof(hook_val_t) * argc); + + memcpy(hook->name, name, strlen(name) + 1); + hook->func = func; + hook->argc = argc; + } + return hook; +} + +// Needs NULL pad to know when va_list ends. +hook_val_t *_Hook_Call(hook_t *hook, ... ) +{ + uintptr_t arg_ptr; // Align to platform size + va_list arg_list; + unsigned int i = 0; + + if(!hook) + return (hook_val_t *)NULL; + + va_start(arg_list, hook); + + arg_ptr = va_arg(arg_list,intptr_t); + + if((void *)arg_ptr && !hook->argc) + goto overflow; + + // Loop until we encounter that NULL pad, but stop if we overflow. + while ((void *)arg_ptr != NULL && i != hook->argc) + { + if (i > hook->argc) + goto overflow; + hook->arg[i].val = arg_ptr; + arg_ptr = va_arg(arg_list,intptr_t); + i++; + } + + va_end(arg_list); + + // Should be fairly obvious why it's bad if args don't match + if(i != hook->argc) + goto underflow; + // Call it + hook->ret.uval = (uintptr_t)hook->func(hook->arg); + + if (hook->ret.val) + return &hook->ret; + return (hook_val_t *)NULL; + +underflow: + Sys_Error("Hook_Call: Attempt to call hook '%s' with incorrect number of arguments. Got %i, expected %i\n", hook->name, i, hook->argc); +overflow: + Sys_Error("Hook_Call: Stack overflow calling hook '%s' (argc = %u)\n", hook->name, hook->argc); + +} + +void Hook_Init(void) +{ + hooks = Mem_AllocPool("hooks",0,NULL); + return; +} \ No newline at end of file diff --git a/hook.h b/hook.h new file mode 100644 index 00000000..d3a56fd8 --- /dev/null +++ b/hook.h @@ -0,0 +1,56 @@ +/* +Copyright (C) 2020 Cloudwalk + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +// hook.h + +#ifndef HOOK_H +#define HOOK_H + +typedef union hook_val_s +{ + intptr_t val; + uintptr_t uval; + void *ptr; + char *str; + int ival; + unsigned int uival; + double fval; + qboolean bval; +} hook_val_t; + +typedef struct hook_s +{ + char *name; + hook_val_t *(*func)(hook_val_t *hook); + hook_val_t *arg; + hook_val_t ret; + unsigned int argc; +} hook_t; + +hook_t *_Hook_Register(hook_t *hook, const char *name, void *func, unsigned int argc); +hook_val_t *_Hook_Call(hook_t *hook, ... ); +void Hook_Init(void); +void Hook_Shutdown(void); + +// For your convenience +#define Hook_Register(hook, func, argc) _Hook_Register(hook, #hook, func, argc) +#define Hook_Call(hook, ... ) _Hook_Call(hook, __VA_ARGS__, NULL) + +#endif \ No newline at end of file diff --git a/host.c b/host.c index 9404ac95..4930bf8b 100644 --- a/host.c +++ b/host.c @@ -1164,6 +1164,8 @@ void Host_UnlockSession(void) } } +extern hook_t *csqc_concmd; + /* ==================== Host_Init @@ -1231,6 +1233,8 @@ static void Host_Init (void) // initialize memory subsystem cvars/commands Memory_Init_Commands(); + Hook_Init(); + csqc_concmd = Hook_Register(csqc_concmd,CL_VM_ConsoleCommand,1); // initialize console and logging and its cvars/commands Con_Init(); diff --git a/makefile.inc b/makefile.inc index 39976e83..9bcac173 100644 --- a/makefile.inc +++ b/makefile.inc @@ -107,6 +107,7 @@ OBJ_COMMON= \ gl_rsurf.o \ gl_textures.o \ hmac.o \ + hook.o \ host.o \ host_cmd.o \ image.o \ diff --git a/model_alias.c b/model_alias.c index 22863519..be300a1b 100644 --- a/model_alias.c +++ b/model_alias.c @@ -786,7 +786,7 @@ static void Mod_MDLMD2MD3_TraceLine(dp_model_t *model, const frameblend_t *frame else vertex3f = model->surfmesh.data_vertex3f; for (i = 0, surface = model->data_surfaces;i < model->num_surfaces;i++, surface++) - Collision_TraceLineTriangleMeshFloat(trace, start, end, model->surfmesh.num_triangles, model->surfmesh.data_element3i, vertex3f, 0, NULL, SUPERCONTENTS_SOLID | (surface->texture->basematerialflags & MATERIALFLAGMASK_TRANSLUCENT ? 0 : SUPERCONTENTS_OPAQUE), 0, surface->texture, segmentmins, segmentmaxs); + Collision_TraceLineTriangleMeshFloat(trace, start, end, surface->num_triangles, model->surfmesh.data_element3i + 3 * surface->num_firsttriangle, vertex3f, 0, NULL, SUPERCONTENTS_SOLID | (surface->texture->basematerialflags & MATERIALFLAGMASK_TRANSLUCENT ? 0 : SUPERCONTENTS_OPAQUE), 0, surface->texture, segmentmins, segmentmaxs); if (freevertex3f) Mem_Free(freevertex3f); } @@ -840,7 +840,7 @@ static void Mod_MDLMD2MD3_TraceBox(dp_model_t *model, const frameblend_t *frameb Collision_BrushForBox(&thisbrush_end, boxendmins, boxendmaxs, 0, 0, NULL); model->AnimateVertices(model, frameblend, skeleton, vertex3f, NULL, NULL, NULL); for (i = 0, surface = model->data_surfaces;i < model->num_surfaces;i++, surface++) - Collision_TraceBrushTriangleMeshFloat(trace, &thisbrush_start.brush, &thisbrush_end.brush, model->surfmesh.num_triangles, model->surfmesh.data_element3i, vertex3f, 0, NULL, SUPERCONTENTS_SOLID | (surface->texture->basematerialflags & MATERIALFLAGMASK_TRANSLUCENT ? 0 : SUPERCONTENTS_OPAQUE), 0, surface->texture, segmentmins, segmentmaxs); + Collision_TraceBrushTriangleMeshFloat(trace, &thisbrush_start.brush, &thisbrush_end.brush, surface->num_triangles, model->surfmesh.data_element3i + 3 * surface->num_firsttriangle, vertex3f, 0, NULL, SUPERCONTENTS_SOLID | (surface->texture->basematerialflags & MATERIALFLAGMASK_TRANSLUCENT ? 0 : SUPERCONTENTS_OPAQUE), 0, surface->texture, segmentmins, segmentmaxs); if (vertex3f != vertex3fbuf) Mem_Free(vertex3f); } diff --git a/qtypes.h b/qtypes.h index d4fa148e..65218999 100644 --- a/qtypes.h +++ b/qtypes.h @@ -2,6 +2,8 @@ #ifndef QTYPES_H #define QTYPES_H +#include + #ifndef __cplusplus #ifdef _MSC_VER typedef enum {false, true} bool; diff --git a/quakedef.h b/quakedef.h index 8b9ea4d8..d07a93a5 100644 --- a/quakedef.h +++ b/quakedef.h @@ -376,6 +376,7 @@ extern char engineversion[128]; #include "sys.h" #include "vid.h" #include "mathlib.h" +#include "hook.h" #include "r_textures.h" diff --git a/taskqueue.c b/taskqueue.c index 0004e49e..06312cda 100644 --- a/taskqueue.c +++ b/taskqueue.c @@ -1,7 +1,7 @@ #include "quakedef.h" #include "taskqueue.h" -cvar_t taskqueue_minthreads = {CVAR_CLIENT | CVAR_SERVER | CVAR_SAVE, "taskqueue_minthreads", "4", "minimum number of threads to keep active for executing tasks"}; +cvar_t taskqueue_minthreads = {CVAR_CLIENT | CVAR_SERVER | CVAR_SAVE, "taskqueue_minthreads", "0", "minimum number of threads to keep active for executing tasks"}; cvar_t taskqueue_maxthreads = {CVAR_CLIENT | CVAR_SERVER | CVAR_SAVE, "taskqueue_maxthreads", "32", "maximum number of threads to start up as needed based on task count"}; cvar_t taskqueue_tasksperthread = {CVAR_CLIENT | CVAR_SERVER | CVAR_SAVE, "taskqueue_tasksperthread", "4000", "expected amount of work that a single thread can do in a frame - the number of threads being used depends on the average workload in recent frames"}; diff --git a/thread_sdl.c b/thread_sdl.c index f805e540..5c77bb3c 100644 --- a/thread_sdl.c +++ b/thread_sdl.c @@ -171,7 +171,7 @@ void _Thread_WaitBarrier(void *barrier, const char *filename, int fileline) int _Thread_AtomicGet(Thread_Atomic *a, const char *filename, int fileline) { #ifdef THREADDEBUG - Sys_PrintfToTerminal("%p atomic get at %s:%i\n", a, v, filename, fileline); + Sys_PrintfToTerminal("%p atomic get at %s:%i\n", a, filename, fileline); #endif return SDL_AtomicGet((SDL_atomic_t *)a); } @@ -195,7 +195,7 @@ int _Thread_AtomicAdd(Thread_Atomic *a, int v, const char *filename, int filelin void _Thread_AtomicIncRef(Thread_Atomic *a, const char *filename, int fileline) { #ifdef THREADDEBUG - Sys_PrintfToTerminal("%p atomic incref %s:%i\n", lock, filename, fileline); + Sys_PrintfToTerminal("%p atomic incref %s:%i\n", a, filename, fileline); #endif SDL_AtomicIncRef((SDL_atomic_t *)a); } @@ -203,7 +203,7 @@ void _Thread_AtomicIncRef(Thread_Atomic *a, const char *filename, int fileline) qboolean _Thread_AtomicDecRef(Thread_Atomic *a, const char *filename, int fileline) { #ifdef THREADDEBUG - Sys_PrintfToTerminal("%p atomic decref %s:%i\n", lock, filename, fileline); + Sys_PrintfToTerminal("%p atomic decref %s:%i\n", a, filename, fileline); #endif return SDL_AtomicDecRef((SDL_atomic_t *)a) != SDL_FALSE; }