diff --git a/include/QF/csqc.h b/include/QF/csqc.h index d098de476..0b0898707 100644 --- a/include/QF/csqc.h +++ b/include/QF/csqc.h @@ -49,6 +49,8 @@ void File_Progs_Init (struct progs_s *pr); void Hash_Progs_Init (struct progs_s *pr); +void GIB_Progs_Init (struct progs_s *pr); + void InputLine_Progs_Init (struct progs_s *pr); void InputLine_Progs_SetDraw (struct progs_s *pr, void (*draw)(struct inputline_s*)); diff --git a/include/QF/gib_builtin.h b/include/QF/gib_builtin.h index f1649776a..458d64eb2 100644 --- a/include/QF/gib_builtin.h +++ b/include/QF/gib_builtin.h @@ -34,7 +34,7 @@ #include "QF/dstring.h" // For ->str typedef struct gib_builtin_s { - struct dstring_s *name; + const char *name; void (*func) (void); } gib_builtin_t; @@ -53,6 +53,8 @@ extern char gib_null_string[]; void GIB_Arg_Strip_Delim (unsigned int arg); dstring_t *GIB_Return (const char *str); void GIB_Error (const char *type, const char *fmt, ...); -void GIB_Builtin_Add (const char *name, void (*func) (void)); +gib_builtin_t *GIB_Builtin_Add (const char *name, void (*func) (void)); +void GIB_Builtin_Remove (const char *name); +qboolean GIB_Builtin_Exists (const char *name); gib_builtin_t *GIB_Builtin_Find (const char *name); void GIB_Builtin_Init (qboolean sandbox); diff --git a/libs/console/menu.c b/libs/console/menu.c index c3c74ea45..bb664902a 100644 --- a/libs/console/menu.c +++ b/libs/console/menu.c @@ -444,6 +444,7 @@ Menu_Init (void) Cbuf_Progs_Init (&menu_pr_state); Cmd_Progs_Init (&menu_pr_state); + GIB_Progs_Init (&menu_pr_state); Cvar_Progs_Init (&menu_pr_state); File_Progs_Init (&menu_pr_state); InputLine_Progs_Init (&menu_pr_state); diff --git a/libs/gamecode/builtins/Makefile.am b/libs/gamecode/builtins/Makefile.am index 534f43b08..25f1fb807 100644 --- a/libs/gamecode/builtins/Makefile.am +++ b/libs/gamecode/builtins/Makefile.am @@ -10,6 +10,6 @@ libQFgamecode_builtins_la_SOURCES= pr_cmds.c libQFcsqc_la_LDFLAGS= -version-info 1:0:0 libQFcsqc_la_SOURCES=\ - bi_cbuf.c bi_cmd.c bi_cvar.c bi_file.c bi_hash.c bi_init.c \ + bi_cbuf.c bi_cmd.c bi_cvar.c bi_file.c bi_gib.c bi_hash.c bi_init.c \ bi_inputline.c bi_plist.c \ bi_qfile.c bi_qfs.c diff --git a/libs/gamecode/builtins/bi_gib.c b/libs/gamecode/builtins/bi_gib.c new file mode 100644 index 000000000..0e5a7e72f --- /dev/null +++ b/libs/gamecode/builtins/bi_gib.c @@ -0,0 +1,157 @@ +/* + bi_gib.c + + GIB <-> Ruamoko interface + + Copyright (C) 2003 Brian Koropoff + + 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 + +*/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +static __attribute__ ((unused)) const char rcsid[] = + "$Id$"; + +#include +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif + +#include "QF/cmd.h" +#include "QF/csqc.h" +#include "QF/hash.h" +#include "QF/progs.h" +#include "QF/sys.h" +#include "QF/gib_builtin.h" + +typedef struct bi_gib_builtin_s { + struct bi_gib_builtin_s *next; + gib_builtin_t *builtin; + progs_t *pr; + func_t func; +} bi_gib_builtin_t; + +typedef struct bi_gib_resources_s { + bi_gib_builtin_t *builtins; +} bi_gib_resources_t; + +static hashtab_t *bi_gib_builtins; + +static const char * +bi_gib_builtin_get_key (void *c, void *unused) +{ + return ((bi_gib_builtin_t *)c)->builtin->name; +} + +static void +bi_gib_builtin_free (void *_c, void *unused) +{ + bi_gib_builtin_t *c = (bi_gib_builtin_t *) _c; + + free (c); +} + +static void +bi_gib_builtin_f (void) +{ + bi_gib_builtin_t *builtin = Hash_Find (bi_gib_builtins, GIB_Argv(0)); + pr_type_t *pr_list; + unsigned int i; + + if (!builtin) + Sys_Error ("bi_gib_bultin_f: unexpected call %s", GIB_Argv (0)); + + pr_list = PR_Zone_Malloc (builtin->pr, GIB_Argc() * sizeof (pr_type_t)); + + for (i = 0; i < GIB_Argc(); i++) + pr_list[i].integer_var = PR_SetString (builtin->pr, GIB_Argv(i)); + + P_INT (builtin->pr, 0) = GIB_Argc(); + P_INT (builtin->pr, 1) = POINTER_TO_PROG (builtin->pr, pr_list); + PR_ExecuteProgram (builtin->pr, builtin->func); +} + +static void +bi_gib_builtin_clear (progs_t *progs, void *data) +{ + bi_gib_resources_t *res = (bi_gib_resources_t *) data; + bi_gib_builtin_t *cur; + + while ((cur = res->builtins)) { + void *del = Hash_Del (bi_gib_builtins, cur->builtin->name); + GIB_Builtin_Remove (cur->builtin->name); + res->builtins = cur->next; + Hash_Free (bi_gib_builtins, del); + } +} + +static void +bi_GIB_Builtin_Add (progs_t *pr) +{ + bi_gib_resources_t *res = PR_Resources_Find (pr, "GIB"); + bi_gib_builtin_t *builtin; + char *name = P_STRING (pr, 0); + func_t func = P_FUNCTION (pr, 1); + + if (GIB_Builtin_Exists (name)) { + R_INT (pr) = 0; + return; + } + + builtin = malloc (sizeof (bi_gib_builtin_t)); + + builtin->builtin = GIB_Builtin_Add (name, bi_gib_builtin_f); + builtin->pr = pr; + builtin->func = func; + builtin->next = res->builtins; + res->builtins = builtin; + Hash_Add (bi_gib_builtins, builtin); + R_INT (pr) = 1; +} + +static void +bi_GIB_Return (progs_t *pr) +{ + char *str = P_STRING(pr, 0); + + if (str) + GIB_Return (str); + R_INT (pr) = GIB_CanReturn () ? 1 : 0; +} + +void +GIB_Progs_Init (progs_t *pr) +{ + bi_gib_resources_t *res = malloc (sizeof (bi_gib_resources_t)); + res->builtins = 0; + + PR_Resources_Register (pr, "GIB", res, bi_gib_builtin_clear); + + bi_gib_builtins = Hash_NewTable (1021, bi_gib_builtin_get_key, bi_gib_builtin_free, 0); + + PR_AddBuiltin (pr, "GIB_Builtin_Add", bi_GIB_Builtin_Add, -1); + PR_AddBuiltin (pr, "GIB_Return", bi_GIB_Return, -1); +} diff --git a/libs/gamecode/builtins/bi_init.c b/libs/gamecode/builtins/bi_init.c index eecd43e24..3812ab643 100644 --- a/libs/gamecode/builtins/bi_init.c +++ b/libs/gamecode/builtins/bi_init.c @@ -36,6 +36,7 @@ static __attribute__ ((unused)) const char rcsid[] = static void (*const cbuf_progs_init)(progs_t *) = Cbuf_Progs_Init; static void (*const cmd_progs_init)(progs_t *) = Cmd_Progs_Init; +static void (*const gib_progs_init)(progs_t *) = GIB_Progs_Init; static void (*const cvar_progs_init)(progs_t *) = Cvar_Progs_Init; static void (*const file_progs_init)(progs_t *) = File_Progs_Init; static void (*const hash_progs_init)(progs_t *) = Hash_Progs_Init; diff --git a/libs/gib/gib_builtin.c b/libs/gib/gib_builtin.c index 689e3beb9..552698eaa 100644 --- a/libs/gib/gib_builtin.c +++ b/libs/gib/gib_builtin.c @@ -74,7 +74,7 @@ hashtab_t *gib_builtins; static const char * GIB_Builtin_Get_Key (void *ele, void *ptr) { - return ((gib_builtin_t *) ele)->name->str; + return ((gib_builtin_t *) ele)->name; } static void GIB_Builtin_Free (void *ele, void *ptr) @@ -82,7 +82,7 @@ GIB_Builtin_Free (void *ele, void *ptr) gib_builtin_t *b; b = (gib_builtin_t *) ele; - dstring_delete (b->name); + free ((void *)b->name); free (b); } @@ -91,7 +91,8 @@ GIB_Builtin_Free (void *ele, void *ptr) Registers a new builtin GIB command. */ -void + +gib_builtin_t * GIB_Builtin_Add (const char *name, void (*func) (void)) { gib_builtin_t *new; @@ -102,9 +103,25 @@ GIB_Builtin_Add (const char *name, void (*func) (void)) new = calloc (1, sizeof (gib_builtin_t)); new->func = func; - new->name = dstring_newstr (); - dstring_appendstr (new->name, name); + new->name = strdup (name); Hash_Add (gib_builtins, new); + + return new; +} + +void +GIB_Builtin_Remove (const char *name) +{ + gib_builtin_t *del; + + if ((del = Hash_Find (gib_builtins, name))) + Hash_Free (gib_builtins, Hash_DelElement (gib_builtins, del)); +} + +qboolean +GIB_Builtin_Exists (const char *name) +{ + return Hash_Find (gib_builtins, name) ? true : false; } /* diff --git a/ruamoko/cl_menu/client_menu.qc b/ruamoko/cl_menu/client_menu.qc index aef258082..4739761dd 100644 --- a/ruamoko/cl_menu/client_menu.qc +++ b/ruamoko/cl_menu/client_menu.qc @@ -1,6 +1,7 @@ #include "menu.h" #include "file.h" #include "cmd.h" +#include "gib.h" #include "draw.h" #include "key.h" #include "InputLine.h" @@ -11,6 +12,7 @@ #include "options.h" #include "servlist.h" #include "system.h" +#include "debug.h" #include "client_menu.h" //FIXME shouldn't need these @@ -476,6 +478,16 @@ void () main_menu = Menu_End (); }; +void (integer argc, string [] argv) gib_hello_world = +{ + GIB_Return ("Hello, world!"); +}; + +void () gib_menu = +{ + GIB_Builtin_Add ("Ruamoko::helloWorld", gib_hello_world); +}; + void () menu_init = { lanConfig_port_il = [[InputLine alloc] initWithBounds:[[Rect alloc] initWithComponents:126 :lanConfig_cursor_table[0] :8 :4] promptCharacter:' ']; @@ -496,6 +508,7 @@ void () menu_init = quit_menu (); load_menu (); save_menu (); + gib_menu (); Menu_TopMenu ("main"); Menu_SetQuit (quit); }; diff --git a/ruamoko/include/Makefile.am b/ruamoko/include/Makefile.am index 613cf9457..e419e7857 100644 --- a/ruamoko/include/Makefile.am +++ b/ruamoko/include/Makefile.am @@ -7,5 +7,5 @@ include_HEADERS= \ \ draw.h key.h \ \ - cbuf.h cmd.h cvar.h file.h hash.h plist.h \ + cbuf.h cmd.h cvar.h file.h gib.h hash.h plist.h \ Object.h Array.h Entity.h InputLine.h Point.h Rect.h Size.h diff --git a/ruamoko/include/gib.h b/ruamoko/include/gib.h new file mode 100644 index 000000000..67e13e929 --- /dev/null +++ b/ruamoko/include/gib.h @@ -0,0 +1,7 @@ +#ifndef __ruamoko_gib_h +#define __ruamoko_gib_h + +@extern void (string name, void (integer argc, string [] argv) func) GIB_Builtin_Add; +@extern integer (string value) GIB_Return; + +#endif//__ruamoko_gib_h diff --git a/ruamoko/lib/Makefile.am b/ruamoko/lib/Makefile.am index bb12fb3b0..e8a54dbf6 100644 --- a/ruamoko/lib/Makefile.am +++ b/ruamoko/lib/Makefile.am @@ -38,7 +38,7 @@ libgui_a_SOURCES=\ libgui_a_AR=$(PAK) -cf libcsqc_a_SOURCES= \ - cbuf.r cmd.r cvar.r file.r + cbuf.r cmd.r cvar.r file.r gib.r libcsqc_a_AR= $(PAK) -cf CLEANFILES= *.qfo *.o diff --git a/ruamoko/lib/gib.r b/ruamoko/lib/gib.r new file mode 100644 index 000000000..7dabb5975 --- /dev/null +++ b/ruamoko/lib/gib.r @@ -0,0 +1,4 @@ +#include "gib.h" + +void (string name, void (integer argc, string [] argv) func) GIB_Builtin_Add = #0; +integer (string value) GIB_Return = #0;