graphics updates
[voxelands-alt.git] / src / core / command.c
blob7ffda7d6a75e6d44cf1a05828a05bc972ae441d2
1 /************************************************************************
2 * command.c
3 * voxelands - 3d voxel world sandbox game
4 * Copyright (C) Lisa 'darkrose' Milne 2016 <lisa@ltmnet.com>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>
18 ************************************************************************/
20 #include "common.h"
21 #include "nvp.h"
22 #include "array.h"
23 #include "thread.h"
24 #include "file.h"
25 #include "wm.h"
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdarg.h>
31 typedef struct setter_s {
32 int (*func)(array_t *args);
33 int (*help)();
34 } setter_t;
36 static struct {
37 nvp_t *list;
38 mutex_t *mutex;
39 } command_data = {
40 NULL,
41 NULL
44 static int command_alias(array_t *args)
46 char* a;
47 char* c;
48 nvp_t *n;
50 if (!args) {
51 n = command_data.list;
52 while (n) {
53 if (n->value)
54 vlprintf(CN_INFO, "alias: %s %s",n->name,n->value);
55 n = n->next;
57 return 0;
60 a = array_get_string(args,0);
61 c = array_join(args," ",1);
63 n = nvp_get(&command_data.list,a);
64 if (!n) {
65 if (c)
66 nvp_set(&command_data.list,a,c,NULL);
67 return 0;
70 if (!n->value) {
71 vlprintf(CN_WARN, "alias: Cannot unias built-in command '%s'",a);
72 return 1;
75 nvp_set(&command_data.list,a,c,NULL);
78 return 0;
81 static int command_help(array_t *args)
83 nvp_t *n;
84 setter_t *s;
85 if (args) {
86 char* c = array_get_string(args,0);
87 if (!c)
88 return 1;
90 n = nvp_get(&command_data.list,c);
91 if (!n)
92 return 1;
94 s = n->data;
95 if (s && s->help) {
96 /* TODO: implement the help() functionality */
97 s->help();
98 return 0;
101 vlprintf(CN_INFO, "%s [arguments]",c);
102 return 0;
104 return 0;
107 static int control_forward(array_t *args)
109 vlprintf(CN_INFO, "forward");
110 return 0;
113 /* initialise commands */
114 int command_init()
116 command_data.mutex = mutex_create();
117 command_add("help",command_help);
118 command_add("set",config_set_command);
119 command_add("unset",config_set_command);
120 command_add("exec",config_load_command);
121 command_add("ignore",config_ignore_command);
122 command_add("alias",command_alias);
123 command_add("bind",event_bind);
124 command_add("forward",control_forward);
126 command_add("forward",control_forward);
127 command_add("backward",control_backward);
128 command_add("left",control_left);
129 command_add("right",control_right);
130 command_add("jump",control_jump);
131 command_add("sneak",control_sneak);
132 command_add("inventory",control_inventory);
133 command_add("examine",control_examine);
134 command_add("use",control_use);
135 command_add("chat",control_chat);
136 command_add("fly",control_fly);
137 command_add("up",control_up);
138 command_add("down",control_down);
139 command_add("run",control_run);
140 command_add("dig",control_dig);
141 command_add("place",control_place);
142 command_add("wield0",control_wield0);
143 command_add("wield1",control_wield1);
144 command_add("wield2",control_wield2);
145 command_add("wield3",control_wield3);
146 command_add("wield4",control_wield4);
147 command_add("wield5",control_wield5);
148 command_add("wield6",control_wield6);
149 command_add("wield7",control_wield7);
150 command_add("wieldnext",control_wieldnext);
151 command_add("wieldprev",control_wieldprev);
152 command_add("console",control_console);
153 command_add("capture",control_capture);
156 return 0;
159 /* register a new command function */
160 int command_add(char* name, int (*func)(array_t *args))
162 nvp_t *n;
163 setter_t *s;
165 n = nvp_get(&command_data.list,name);
166 if (n && n->data) {
167 s = n->data;
168 if (s->func)
169 return 1;
172 s = malloc(sizeof(setter_t));
173 if (!s)
174 return 1;
175 s->func = func;
176 s->help = NULL;
178 nvp_set(&command_data.list,name,NULL,s);
180 return 0;
183 /* apply a command */
184 int command_apply(char* name, char* value)
186 int r;
187 setter_t *s;
188 nvp_t *n;
189 array_t *args;
190 int (*func)(array_t *args);
192 mutex_lock(command_data.mutex);
194 n = nvp_get(&command_data.list,name);
195 if (!n) {
196 mutex_unlock(command_data.mutex);
197 vlprintf(CN_WARN, "Unknown command: '%s'",name);
198 return 1;
201 if (n->value) {
202 char buff[256];
203 strcpy(buff,n->value);
204 mutex_unlock(command_data.mutex);
205 if (value) {
206 return command_execf("%s %s",buff,value);
207 }else{
208 return command_exec(buff);
212 if (!n->data) {
213 mutex_unlock(command_data.mutex);
214 vlprintf(CN_WARN, "Invalid command: '%s'",name);
215 return 1;
218 s = n->data;
220 if (!s->func) {
221 mutex_unlock(command_data.mutex);
222 vlprintf(CN_WARN, "Invalid command: '%s'",name);
223 return 1;
226 func = s->func;
228 mutex_unlock(command_data.mutex);
230 args = array_split(value," ",1);
232 r = func(args);
234 array_free(args,1);
236 return r;
239 /* execute a command */
240 int command_exec(char* str)
242 int r;
243 char* cmd = str;
244 char* spc;
246 if (!cmd || !cmd[0])
247 return 1;
249 spc = strchr(cmd,' ');
251 if (cmd[0] == '/')
252 cmd++;
254 vlprintf(CN_INFO, "%s",cmd);
256 if (spc && spc[0]) {
257 char* args = spc+1;
258 *spc = 0;
260 r = command_apply(cmd,args);
262 *spc = ' ';
263 }else{
264 r = command_apply(cmd,NULL);
267 return r;
270 /* execute a command from a formatted string */
271 int command_execf(char* str, ...)
273 int l;
274 char buff[1024];
275 va_list ap;
276 va_start(ap, str);
277 l = vsnprintf(buff,1024,str,ap);
278 va_end(ap);
280 if (l >= 1024)
281 return 1;
283 return command_exec(buff);
286 /* save alias to file */
287 void command_save(file_t *f)
289 nvp_t *n = command_data.list;
290 while (n) {
291 if (!n->data)
292 file_writef(f,"alias %s %s\n",n->name,n->value);
293 n = n->next;