]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
Merge branch 'master' into Mario/ext_entityparam
authorMario <mario@smbclan.net>
Sun, 31 May 2020 20:48:15 +0000 (06:48 +1000)
committerMario <mario@smbclan.net>
Sun, 31 May 2020 20:48:15 +0000 (06:48 +1000)
13 files changed:
cmd.c
csprogs.c
csprogs.h
gl_rmain.c
hook.c [new file with mode: 0644]
hook.h [new file with mode: 0644]
host.c
makefile.inc
model_alias.c
qtypes.h
quakedef.h
taskqueue.c
thread_sdl.c

diff --git a/cmd.c b/cmd.c
index 352d8c5be40491efe542a7d84a26b2411a41882f..a06f39ce889e5707b4f589446a5f1d1e66f7e571 100644 (file)
--- 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;
                }
index 13c27ec3992d9d3ebbadd531b8047b9daf77c7b2..6d83a7849d7951c27f00bc02804c3a63cb93acc2 100644 (file)
--- 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");
index dff44d74affd11bc282d707db759e6d1c4b9d761..46b71eba6ab7969758b281fe4a85a50fabf58849 100644 (file)
--- 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);
index 25b889239efaaaa370077db007b46baa674b334a..6c6e2c1abc480bf4c4ce2db17a7bbf965df0865b 100644 (file)
@@ -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 (file)
index 0000000..344f9e9
--- /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 (file)
index 0000000..d3a56fd
--- /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 9404ac952bc06c350d75499708d67af5236bbecf..4930bf8b50007455c404f1543e2a738cd6ebe13e 100644 (file)
--- 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();
 
index 39976e83981bf178da4fa5bc345c36d0e3897098..9bcac1732cb0b17ebc4a0ff6b8c8f462389e9020 100644 (file)
@@ -107,6 +107,7 @@ OBJ_COMMON= \
        gl_rsurf.o \
        gl_textures.o \
        hmac.o \
+       hook.o \
        host.o \
        host_cmd.o \
        image.o \
index 22863519406f3ccefb25c078597c72db9dd17e04..be300a1bb346a6bf6abca3c058a6863d9614262b 100644 (file)
@@ -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);
 }
index d4fa148e189051342d9be25038f0494da16f6090..6521899965ea6993427e3b0ec53424b9ee311044 100644 (file)
--- a/qtypes.h
+++ b/qtypes.h
@@ -2,6 +2,8 @@
 #ifndef QTYPES_H
 #define QTYPES_H
 
+#include <stdint.h>
+
 #ifndef __cplusplus
 #ifdef _MSC_VER
 typedef enum {false, true} bool;
index 8b9ea4d8aaf0242c64011bcf0fcbfdfa89541589..d07a93a5a38b9494c0848901866892247c3e5e2c 100644 (file)
@@ -376,6 +376,7 @@ extern char engineversion[128];
 #include "sys.h"
 #include "vid.h"
 #include "mathlib.h"
+#include "hook.h"
 
 #include "r_textures.h"
 
index 0004e49eb7ede11ca524b0708039ec902a7cf572..06312cda5095370fb524e8c037e7e90bceab5a76 100644 (file)
@@ -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"};
 
index f805e5403eae4f0ba27dd011d49d67231e5cc070..5c77bb3c976241b2bf4c95974a1b94219eb3147d 100644 (file)
@@ -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;
 }