mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 22:31:05 +00:00
Added threads and callbacks to GIB, as well as several QW callbacks dealing
with player status.
This commit is contained in:
parent
070aee9a0c
commit
98fc04e041
12 changed files with 299 additions and 35 deletions
|
@ -3,10 +3,10 @@ SUBDIRS = GL plugin
|
|||
includedir = $(prefix)/include/QF
|
||||
include_HEADERS = bspfile.h cbuf.h cdaudio.h checksum.h clip_hull.h cmd.h \
|
||||
console.h crc.h csqc.h cvar.h dstring.h draw.h gcc_attr.h gib_buffer.h \
|
||||
gib_builtin.h gib_function.h gib_parse.h gib_process.h gib_vars.h hash.h hl.h \
|
||||
idparse.h in_event.h info.h input.h joystick.h keys.h link.h locs.h \
|
||||
mathlib.h mdfour.h model.h modelgen.h msg.h pak.h pakfile.h pcx.h \
|
||||
plugin.h pr_comp.h pr_debug.h pr_obj.h progs.h qargs.h qdefs.h qendian.h \
|
||||
qfplist.h qtypes.h render.h screen.h sizebuf.h skin.h sound.h \
|
||||
spritegn.h sys.h teamplay.h texture.h tga.h uint32.h va.h ver_check.h \
|
||||
vfile.h vfs.h vid.h wad.h zone.h
|
||||
gib_builtin.h gib_function.h gib_parse.h gib_process.h gib_thread.h \
|
||||
gib_vars.h hash.h hl.h idparse.h in_event.h info.h input.h joystick.h \
|
||||
keys.h link.h locs.h mathlib.h mdfour.h model.h modelgen.h msg.h pak.h \
|
||||
pakfile.h pcx.h plugin.h pr_comp.h pr_debug.h pr_obj.h progs.h qargs.h \
|
||||
qdefs.h qendian.h qfplist.h qtypes.h render.h screen.h sizebuf.h skin.h \
|
||||
sound.h spritegn.h sys.h teamplay.h texture.h tga.h uint32.h va.h \
|
||||
ver_check.h vfile.h vfs.h vid.h wad.h zone.h
|
||||
|
|
|
@ -36,4 +36,4 @@ typedef struct gib_function_s {
|
|||
|
||||
void GIB_Function_Define (const char *name, const char *program);
|
||||
gib_function_t *GIB_Function_Find (const char *name);
|
||||
void GIB_Function_Execute (gib_function_t *func);
|
||||
void GIB_Function_Execute (cbuf_t *cbuf, gib_function_t *func, cbuf_args_t *args);
|
||||
|
|
43
include/QF/gib_thread.h
Normal file
43
include/QF/gib_thread.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
#FILENAME#
|
||||
|
||||
#DESCRIPTION#
|
||||
|
||||
Copyright (C) 2002 #AUTHOR#
|
||||
|
||||
Author: #AUTHOR#
|
||||
Date: #DATE#
|
||||
|
||||
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:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
typedef struct gib_thread_s {
|
||||
unsigned long int id;
|
||||
struct cbuf_s *cbuf;
|
||||
struct gib_thread_s *next,*prev;
|
||||
} gib_thread_t;
|
||||
|
||||
void GIB_Thread_Add (gib_thread_t *thread);
|
||||
void GIB_Thread_Remove (gib_thread_t *thread);
|
||||
gib_thread_t *GIB_Thread_Find (unsigned long int id);
|
||||
gib_thread_t *GIB_Thread_New (void);
|
||||
void GIB_Thread_Execute (void);
|
||||
void GIB_Thread_Callback (const char *func, unsigned int argc, ...);
|
|
@ -28,9 +28,9 @@ libQFutil_la_DEPENDENCIES= libasm.la
|
|||
libQFutil_la_SOURCES= \
|
||||
bspfile.c buildnum.c cbuf.c checksum.c cmd.c crc.c cvar.c dstring.c \
|
||||
exp.c fendian.c getopt.c getopt1.c gib_buffer.c gib_builtin.c \
|
||||
gib_function.c gib_parse.c gib_process.c gib_vars.c hash.c idparse.c \
|
||||
info.c link.c mathlib.c mdfour.c msg.c ops.c pakfile.c pcx.c plugin.c \
|
||||
qargs.c qendian.c qfplist.c quakefs.c quakeio.c sizebuf.c string.c \
|
||||
gib_function.c gib_parse.c gib_process.c gib_thread.c gib_vars.c hash.c \
|
||||
idparse.c info.c link.c mathlib.c mdfour.c msg.c ops.c pakfile.c pcx.c \
|
||||
plugin.c qargs.c qendian.c qfplist.c quakefs.c quakeio.c sizebuf.c string.c \
|
||||
sys.c tga.c va.c ver_check.c wad.c zone.c \
|
||||
$(fnmatch)
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ static const char rcsid[] =
|
|||
#include "QF/gib_buffer.h"
|
||||
#include "QF/gib_function.h"
|
||||
#include "QF/gib_vars.h"
|
||||
#include "QF/gib_thread.h"
|
||||
|
||||
hashtab_t *gib_builtins;
|
||||
|
||||
|
@ -334,8 +335,13 @@ GIB_Runexported_f (void)
|
|||
Sys_Printf ("Error: No function found for exported command \"%s\".\n"
|
||||
"This is most likely a bug, please report it to"
|
||||
"The QuakeForge developers.", Cmd_Argv(0));
|
||||
else
|
||||
GIB_Function_Execute (f);
|
||||
else {
|
||||
cbuf_t *sub = Cbuf_New (&gib_interp);
|
||||
GIB_Function_Execute (sub, f, cbuf_active->args);
|
||||
cbuf_active->down = sub;
|
||||
sub->up = cbuf_active;
|
||||
cbuf_active->state = CBUF_STATE_STACK;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -377,6 +383,45 @@ GIB_String_Equal_f (void)
|
|||
GIB_Return (va("%i", !strcmp(GIB_Argv(1), GIB_Argv(2))));
|
||||
}
|
||||
|
||||
void
|
||||
GIB_Thread_Create_f (void)
|
||||
{
|
||||
if (GIB_Argc() != 2)
|
||||
Cbuf_Error ("syntax",
|
||||
"thread.create: invalid syntax\n"
|
||||
"usage: thread.create program");
|
||||
else {
|
||||
gib_thread_t *thread = GIB_Thread_New ();
|
||||
Cbuf_AddText (thread->cbuf, GIB_Argv(1));
|
||||
GIB_Thread_Add (thread);
|
||||
GIB_Return (va("%lu", thread->id));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GIB_Thread_Kill_f (void)
|
||||
{
|
||||
if (GIB_Argc() != 2)
|
||||
Cbuf_Error ("syntax",
|
||||
"thread.kill: invalid syntax\n"
|
||||
"usage: thread.kill id");
|
||||
else {
|
||||
gib_thread_t *thread;
|
||||
cbuf_t *cur;
|
||||
unsigned long int id = strtoul (GIB_Argv(1), 0, 10);
|
||||
thread = GIB_Thread_Find (id);
|
||||
if (!thread) {
|
||||
Cbuf_Error ("thread", "thread.kill: thread %ul does not exist.", id);
|
||||
return;
|
||||
}
|
||||
for (cur = thread->cbuf; cur; cur = cur->down) {
|
||||
GIB_DATA(cur)->type = GIB_BUFFER_NORMAL;
|
||||
dstring_clearstr (cur->line);
|
||||
dstring_clearstr (cur->buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GIB_Builtin_Init (void)
|
||||
{
|
||||
|
@ -394,4 +439,6 @@ GIB_Builtin_Init (void)
|
|||
GIB_Builtin_Add ("break", GIB_Break_f, GIB_BUILTIN_NORMAL);
|
||||
GIB_Builtin_Add ("string.length", GIB_String_Length_f, GIB_BUILTIN_NORMAL);
|
||||
GIB_Builtin_Add ("string.equal", GIB_String_Equal_f, GIB_BUILTIN_NORMAL);
|
||||
GIB_Builtin_Add ("thread.create", GIB_Thread_Create_f, GIB_BUILTIN_NORMAL);
|
||||
GIB_Builtin_Add ("thread.kill", GIB_Thread_Kill_f, GIB_BUILTIN_NORMAL);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ static const char rcsid[] =
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "QF/sys.h"
|
||||
#include "QF/dstring.h"
|
||||
#include "QF/hash.h"
|
||||
#include "QF/cbuf.h"
|
||||
|
@ -123,26 +124,16 @@ GIB_Function_Find (const char *name)
|
|||
/*
|
||||
GIB_Function_Execute
|
||||
|
||||
Creates a new buffer on the current stack
|
||||
and copies the program text of a function
|
||||
into it. Also sets local variables on the
|
||||
buffer for all arguments passed to the
|
||||
function
|
||||
Prepares a buffer to execute
|
||||
a GIB function with certain arguments
|
||||
*/
|
||||
void
|
||||
GIB_Function_Execute (gib_function_t *func)
|
||||
GIB_Function_Execute (cbuf_t *cbuf, gib_function_t *func, cbuf_args_t *args)
|
||||
{
|
||||
cbuf_t *sub = Cbuf_New (&gib_interp);
|
||||
int i;
|
||||
|
||||
Cbuf_AddText (sub, func->program->str);
|
||||
if (cbuf_active->down)
|
||||
Cbuf_DeleteStack (cbuf_active->down);
|
||||
cbuf_active->down = sub;
|
||||
sub->up = cbuf_active;
|
||||
cbuf_active->state = CBUF_STATE_STACK;
|
||||
|
||||
for (i = 0; i < cbuf_active->args->argc; i++)
|
||||
GIB_Var_Set_Local (sub, va("%i", i), cbuf_active->args->argv[i]->str);
|
||||
GIB_Var_Set_Local (sub, "argc", va("%i", cbuf_active->args->argc));
|
||||
Cbuf_AddText (cbuf, func->program->str);
|
||||
for (i = 0; i < args->argc; i++)
|
||||
GIB_Var_Set_Local (cbuf, va("%i", i), args->argv[i]->str);
|
||||
GIB_Var_Set_Local (cbuf, "argc", va("%i", args->argc));
|
||||
}
|
||||
|
|
|
@ -466,9 +466,13 @@ void GIB_Parse_Execute_Line (cbuf_t *cbuf)
|
|||
|
||||
if ((b = GIB_Builtin_Find (args->argv[0]->str)))
|
||||
b->func ();
|
||||
else if ((f = GIB_Function_Find (args->argv[0]->str)))
|
||||
GIB_Function_Execute (f);
|
||||
else if (args->argc == 3 && !strcmp (args->argv[1]->str, "=")) {
|
||||
else if ((f = GIB_Function_Find (args->argv[0]->str))) {
|
||||
cbuf_t *sub = Cbuf_New (&gib_interp);
|
||||
GIB_Function_Execute (sub, f, cbuf_active->args);
|
||||
cbuf_active->down = sub;
|
||||
sub->up = cbuf_active;
|
||||
cbuf_active->state = CBUF_STATE_STACK;
|
||||
} else if (args->argc == 3 && !strcmp (args->argv[1]->str, "=")) {
|
||||
// First, determine global versus local
|
||||
int glob = 0;
|
||||
char *c = 0;
|
||||
|
|
143
libs/util/gib_thread.c
Normal file
143
libs/util/gib_thread.c
Normal file
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
#FILENAME#
|
||||
|
||||
#DESCRIPTION#
|
||||
|
||||
Copyright (C) 2002 #AUTHOR#
|
||||
|
||||
Author: #AUTHOR#
|
||||
Date: #DATE#
|
||||
|
||||
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:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
|
||||
static const char rcsid[] =
|
||||
"$Id$";
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "QF/sys.h"
|
||||
#include "QF/cbuf.h"
|
||||
#include "QF/gib_parse.h"
|
||||
#include "QF/gib_thread.h"
|
||||
#include "QF/gib_function.h"
|
||||
#include "QF/dstring.h"
|
||||
|
||||
gib_thread_t *gib_threads;
|
||||
static unsigned long int nextid = 0;
|
||||
|
||||
void
|
||||
GIB_Thread_Add (gib_thread_t *thread)
|
||||
{
|
||||
thread->prev = 0;
|
||||
thread->next = gib_threads;
|
||||
if (gib_threads)
|
||||
gib_threads->prev = thread;
|
||||
gib_threads = thread;
|
||||
}
|
||||
|
||||
void
|
||||
GIB_Thread_Remove (gib_thread_t *thread)
|
||||
{
|
||||
if (thread == gib_threads) {
|
||||
gib_threads = gib_threads->next;
|
||||
if (gib_threads)
|
||||
gib_threads->prev = 0;
|
||||
} else {
|
||||
thread->prev->next = thread->next;
|
||||
if (thread->next)
|
||||
thread->next->prev = thread->prev;
|
||||
}
|
||||
}
|
||||
|
||||
gib_thread_t *
|
||||
GIB_Thread_Find (unsigned long int id)
|
||||
{
|
||||
gib_thread_t *cur;
|
||||
|
||||
for (cur = gib_threads; cur; cur=cur->next)
|
||||
if (cur->id == id)
|
||||
return cur;
|
||||
return 0;
|
||||
}
|
||||
|
||||
gib_thread_t *
|
||||
GIB_Thread_New (void)
|
||||
{
|
||||
gib_thread_t *new = calloc (1, sizeof(gib_thread_t));
|
||||
new->cbuf = Cbuf_New (&gib_interp);
|
||||
new->id = nextid;
|
||||
nextid++;
|
||||
return new;
|
||||
}
|
||||
|
||||
void
|
||||
GIB_Thread_Delete (gib_thread_t *thread)
|
||||
{
|
||||
Cbuf_DeleteStack (thread->cbuf);
|
||||
free (thread);
|
||||
}
|
||||
|
||||
void
|
||||
GIB_Thread_Execute (void)
|
||||
{
|
||||
gib_thread_t *cur, *tmp;
|
||||
if (!gib_threads)
|
||||
return;
|
||||
|
||||
for (cur = gib_threads; cur->next; cur = cur->next);
|
||||
for (; cur; cur = tmp) {
|
||||
tmp = cur->prev;
|
||||
if (!cur->cbuf->buf->str[0] && !cur->cbuf->down) {
|
||||
GIB_Thread_Remove (cur);
|
||||
GIB_Thread_Delete (cur);
|
||||
} else
|
||||
Cbuf_Execute_Stack (cur->cbuf);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GIB_Thread_Callback (const char *func, unsigned int argc, ...)
|
||||
{
|
||||
gib_function_t *f = GIB_Function_Find (func);
|
||||
gib_thread_t *thread;
|
||||
cbuf_args_t *args;
|
||||
va_list ap;
|
||||
unsigned int i;
|
||||
|
||||
if (!f)
|
||||
return;
|
||||
|
||||
thread = GIB_Thread_New ();
|
||||
args = Cbuf_ArgsNew ();
|
||||
|
||||
va_start (ap, argc);
|
||||
|
||||
Cbuf_ArgsAdd (args, func);
|
||||
for (i = 0; i < argc; i++)
|
||||
Cbuf_ArgsAdd (args, va_arg (ap, const char *));
|
||||
|
||||
va_end (ap);
|
||||
|
||||
GIB_Function_Execute (thread->cbuf, f, args);
|
||||
GIB_Thread_Add (thread);
|
||||
Cbuf_ArgsDelete (args);
|
||||
}
|
|
@ -50,6 +50,7 @@ static const char rcsid[] =
|
|||
#include "QF/sys.h"
|
||||
#include "QF/va.h"
|
||||
#include "QF/vid.h"
|
||||
#include "QF/gib_thread.h"
|
||||
|
||||
#include "buildnum.h"
|
||||
#include "chase.h"
|
||||
|
@ -605,6 +606,10 @@ _Host_Frame (float time)
|
|||
IN_Commands ();
|
||||
}
|
||||
|
||||
// process gib threads
|
||||
|
||||
GIB_Thread_Execute ();
|
||||
|
||||
// process console commands
|
||||
cmd_source = src_command;
|
||||
Cbuf_Execute_Stack (host_cbuf);
|
||||
|
|
|
@ -79,6 +79,7 @@ static const char rcsid[] =
|
|||
#include "QF/va.h"
|
||||
#include "QF/vfs.h"
|
||||
#include "QF/vid.h"
|
||||
#include "QF/gib_thread.h"
|
||||
|
||||
#include "bothdefs.h"
|
||||
#include "buildnum.h"
|
||||
|
@ -1531,6 +1532,10 @@ Host_Frame (float time)
|
|||
// allow mouses or other external controllers to add commands
|
||||
IN_Commands ();
|
||||
|
||||
// process gib threads
|
||||
|
||||
GIB_Thread_Execute ();
|
||||
|
||||
// process console commands
|
||||
Cbuf_Execute_Stack (cl_cbuf);
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ static const char rcsid[] =
|
|||
#include "QF/vfile.h"
|
||||
#include "QF/dstring.h"
|
||||
#include "QF/gib_vars.h"
|
||||
#include "QF/gib_thread.h"
|
||||
|
||||
#include "bothdefs.h"
|
||||
#include "cl_ents.h"
|
||||
|
@ -1055,7 +1056,8 @@ void
|
|||
CL_SetStat (int stat, int value)
|
||||
{
|
||||
int j;
|
||||
const char *arm;
|
||||
unsigned int changed;
|
||||
const char *arm, *cb;
|
||||
|
||||
if (stat < 0 || stat >= MAX_CL_STATS)
|
||||
Host_Error ("CL_SetStat: %i is invalid", stat);
|
||||
|
@ -1064,7 +1066,11 @@ CL_SetStat (int stat, int value)
|
|||
|
||||
switch (stat) {
|
||||
case STAT_ITEMS:
|
||||
changed = cl.stats[STAT_ITEMS] ^ value;
|
||||
Sbar_Changed ();
|
||||
if ((changed & IT_KEY1 || changed & IT_KEY2) &&
|
||||
(cb = GIB_Var_Get_Global ("player.key.callback")))
|
||||
GIB_Thread_Callback (cb, 0);
|
||||
GIB_Var_Set_Global ("player.key.1", value & IT_KEY1 ? "1" : "0");
|
||||
GIB_Var_Set_Global ("player.key.2", value & IT_KEY2 ? "1" : "0");
|
||||
if (value & IT_ARMOR1)
|
||||
|
@ -1076,6 +1082,9 @@ CL_SetStat (int stat, int value)
|
|||
else
|
||||
arm = "none";
|
||||
GIB_Var_Set_Global ("player.armor.type", arm);
|
||||
if ((changed & 127 || changed & IT_AXE) &&
|
||||
(cb = GIB_Var_Get_Global ("player.weapon.callback")))
|
||||
GIB_Thread_Callback (cb, 0);
|
||||
GIB_Var_Set_Global ("player.weapon.1", value & IT_AXE ? "1" : "0");
|
||||
for (j = 0; j < 7; j++)
|
||||
GIB_Var_Set_Global (va("player.weapon.%i", j+2),
|
||||
|
@ -1085,23 +1094,35 @@ CL_SetStat (int stat, int value)
|
|||
cl.item_gettime[j] = cl.time;
|
||||
break;
|
||||
case STAT_HEALTH:
|
||||
if ((cb = GIB_Var_Get_Global ("player.health.callback")))
|
||||
GIB_Thread_Callback (cb, 1, va("%i", value));
|
||||
GIB_Var_Set_Global ("player.health", va("%i", value));
|
||||
if (value <= 0)
|
||||
Team_Dead ();
|
||||
break;
|
||||
case STAT_ARMOR:
|
||||
if ((cb = GIB_Var_Get_Global ("player.armor.callback")))
|
||||
GIB_Thread_Callback (cb, 1, va("%i", value));
|
||||
GIB_Var_Set_Global ("player.armor", va("%i", value));
|
||||
break;
|
||||
case STAT_SHELLS:
|
||||
if ((cb = GIB_Var_Get_Global ("player.ammo.shells.callback")))
|
||||
GIB_Thread_Callback (cb, 1, va("%i", value));
|
||||
GIB_Var_Set_Global ("player.ammo.shells", va("%i", value));
|
||||
break;
|
||||
case STAT_NAILS:
|
||||
if ((cb = GIB_Var_Get_Global ("player.ammo.nails.callback")))
|
||||
GIB_Thread_Callback (cb, 1, va("%i", value));
|
||||
GIB_Var_Set_Global ("player.ammo.nails", va("%i", value));
|
||||
break;
|
||||
case STAT_ROCKETS:
|
||||
if ((cb = GIB_Var_Get_Global ("player.ammo.rockets.callback")))
|
||||
GIB_Thread_Callback (cb, 1, va("%i", value));
|
||||
GIB_Var_Set_Global ("player.ammo.rockets", va("%i", value));
|
||||
break;
|
||||
case STAT_CELLS:
|
||||
if ((cb = GIB_Var_Get_Global ("player.ammo.cells.callback")))
|
||||
GIB_Thread_Callback (cb, 1, va("%i", value));
|
||||
GIB_Var_Set_Global ("player.ammo.cells", va("%i", value));
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@ static const char rcsid[] =
|
|||
#include "QF/idparse.h"
|
||||
#include "QF/gib_parse.h"
|
||||
#include "QF/gib_buffer.h"
|
||||
#include "QF/gib_thread.h"
|
||||
#include "QF/cmd.h"
|
||||
#include "QF/console.h"
|
||||
#include "QF/cvar.h"
|
||||
|
@ -1902,6 +1903,10 @@ SV_Frame (float time)
|
|||
// check for commands typed to the host
|
||||
SV_GetConsoleCommands ();
|
||||
|
||||
// process gib threads
|
||||
|
||||
GIB_Thread_Execute ();
|
||||
|
||||
// process console commands
|
||||
Cbuf_Execute_Stack (sv_cbuf);
|
||||
|
||||
|
|
Loading…
Reference in a new issue