23 cmd_handler_t function;
27 /* The list of cmds */
28 static cmd_t *cmd_list = NULL;
31 #define ALIAS_NAME_MAX 32
32 typedef struct cmd_alias_s
34 char name[ALIAS_NAME_MAX];
36 struct cmd_alias_s *next;
39 /* The list of aliases */
40 static cmd_alias_t *cmd_alias_list = NULL;
43 /* The list of keybindings */
44 static char *cmd_keybinding_list[256];
47 /* add a new console command */
48 void cmd_addcommand(char *cmd_name, cmd_handler_t cmd_func)
52 Assert(cmd_name != NULL);
54 for (cmd = cmd_list; cmd; cmd = cmd->next) {
55 if (!stricmp(cmd_name, cmd->name))
58 con_printf(CON_NORMAL, "command %s already exists, not adding\n", cmd_name);
63 /* create command, insert at front of list */
64 MALLOC(cmd, cmd_t, 1);
66 cmd->function = cmd_func;
68 con_printf(CON_DEBUG, "cmd_addcommand: added %s\n", cmd->name);
73 typedef struct cmd_queue_s
76 struct cmd_queue_s *next;
79 /* The list of commands to be executed */
80 static cmd_queue_t *cmd_queue_head = NULL;
81 static cmd_queue_t *cmd_queue_tail = NULL;
84 void cvar_cmd_set(int argc, char **argv);
87 /* execute a parsed command */
88 void cmd_execute(int argc, char **argv)
93 for (cmd = cmd_list; cmd; cmd = cmd->next) {
94 if (!stricmp(argv[0], cmd->name)) {
95 con_printf(CON_DEBUG, "cmd_execute: executing %s\n", argv[0]);
96 return cmd->function(argc, argv);
100 for (alias = cmd_alias_list; alias; alias = alias->next) {
101 if (!stricmp(argv[0], alias->name)) {
102 con_printf(CON_DEBUG, "cmd_execute: pushing alias \"%s\": %s\n", alias->name, alias->value);
103 cmd_insert(alias->value);
109 if (argc > 1) { // set value of cvar
110 char *new_argv[argc+1];
114 for (i = 0; i < argc; i++)
115 new_argv[i+1] = argv[i];
116 cvar_cmd_set(argc + 1, new_argv);
118 con_printf(CON_VERBOSE, "%s: %f\n", argv[0], cvar(argv[0]));
122 /* Parse an input string */
123 void cmd_parse(char *input)
125 char buffer[CMD_MAX_LENGTH];
126 char *tokens[CMD_MAX_TOKENS];
131 Assert(input != NULL);
133 /* Strip leading spaces */
134 for (i=0; isspace(input[i]); i++) ;
135 strncpy( buffer, &input[i], CMD_MAX_LENGTH );
137 //printf("lead strip \"%s\"\n",buffer);
139 /* If command is empty, give up */
142 /* Strip trailing spaces */
143 for (i=l-1; i>0 && isspace(buffer[i]); i--) ;
145 //printf("trail strip \"%s\"\n",buffer);
147 /* Split into tokens */
152 for (i=1; i<l; i++) {
153 if (buffer[i] == '"') {
157 if ((isspace(buffer[i]) || buffer[i] == '=') && !quoted) {
159 while (isspace(buffer[i+1]) && (i+1 < l)) i++;
160 tokens[num_tokens++] = &buffer[i+1];
164 /* Check for matching commands */
165 cmd_execute(num_tokens, tokens);
169 int cmd_queue_wait = 0;
171 void cmd_queue_process()
175 while (!cmd_queue_wait && cmd_queue_head) {
176 cmd = cmd_queue_head;
177 cmd_queue_head = cmd_queue_head->next;
179 cmd_queue_tail = NULL;
181 con_printf(CON_DEBUG, "cmd_queue_process: processing %s\n", cmd->command_line);
182 cmd_parse(cmd->command_line); // Note, this may change the queue
184 d_free(cmd->command_line);
188 if (cmd_queue_wait) {
189 con_printf(CON_DEBUG, "cmd_queue_process: waiting\n");
196 /* Add some commands to the queue to be executed */
197 void cmd_enqueue(int insert, char *input)
199 cmd_queue_t *new, *head, *tail;
202 Assert(input != NULL);
208 /* Strip leading spaces */
209 while(isspace(*input) || *input == ';')
212 /* If command is empty, give up */
216 /* Now at start of a command line */
219 /* Find the end of this line (\n, ;, or nul) */
226 } else if ( *input == '\n' || (!quoted && *input == ';') ) {
231 /* make a new queue item, add it to list */
232 MALLOC(new, cmd_queue_t, 1);
233 new->command_line = d_strdup(line);
242 con_printf(CON_DEBUG, "cmd_enqueue: adding %s\n", line);
246 /* add our list to the head of the main list */
248 tail->next = cmd_queue_head;
250 cmd_queue_tail = tail;
252 cmd_queue_head = head;
253 con_printf(CON_DEBUG, "cmd_enqueue: added to front of list\n");
255 /* add our list to the tail of the main list */
257 cmd_queue_head = head;
259 cmd_queue_tail->next = head;
261 cmd_queue_tail = tail;
262 con_printf(CON_DEBUG, "cmd_enqueue: added to back of list\n");
266 void cmd_enqueuef(int insert, char *fmt, ...)
269 char buf[CMD_MAX_LENGTH];
271 va_start (arglist, fmt);
272 vsnprintf (buf, CMD_MAX_LENGTH, fmt, arglist);
275 cmd_enqueue(insert, buf);
279 /* Attempt to autocomplete an input string */
280 char *cmd_complete(char *input)
285 int len = strlen(input);
290 for (ptr = cmd_list; ptr != NULL; ptr = ptr->next)
291 if (!strnicmp(input, ptr->name, len))
294 for (aptr = cmd_alias_list; aptr != NULL; aptr = aptr->next)
295 if (!strnicmp(input, aptr->name, len))
298 return cvar_complete(input);
302 int cmd_handle_keybinding(unsigned char key)
304 if (cmd_keybinding_list[key]) {
305 cmd_insert(cmd_keybinding_list[key]);
314 void cmd_alias(int argc, char **argv)
317 char buf[CMD_MAX_LENGTH] = "";
322 con_printf(CON_NORMAL, "aliases:\n");
323 for (alias = cmd_alias_list; alias; alias = alias->next)
324 con_printf(CON_NORMAL, "%s: %s\n", alias->name, alias->value);
328 for (i = 2; i < argc; i++) {
330 strncat(buf, " ", CMD_MAX_LENGTH);
331 strncat(buf, argv[i], CMD_MAX_LENGTH);
334 for (alias = cmd_alias_list; alias; alias = alias->next) {
335 if (!stricmp(argv[1], alias->name))
337 d_free(alias->value);
338 alias->value = d_strdup(buf);
343 MALLOC(alias, cmd_alias_t, 1);
344 strncpy(alias->name, argv[1], ALIAS_NAME_MAX);
345 alias->value = d_strdup(buf);
346 alias->next = cmd_alias_list;
347 cmd_alias_list = alias;
351 /* FIXME: key_text is not really adequate for this */
352 void cmd_bind(int argc, char **argv)
354 char buf[CMD_MAX_LENGTH] = "";
355 unsigned char key = 0;
360 con_printf(CON_NORMAL, "key bindings:\n");
361 for (i = 0; i < 256; i++) {
362 if (!cmd_keybinding_list[i])
364 con_printf(CON_NORMAL, "%s: %s\n", key_text[i], cmd_keybinding_list[i]);
369 for (i = 2; i < argc; i++) {
371 strncat(buf, " ", CMD_MAX_LENGTH);
372 strncat(buf, argv[i], CMD_MAX_LENGTH);
375 for (i = 0; i < 256; i++) {
376 if (!stricmp(argv[1], key_text[i])) {
383 con_printf(CON_CRITICAL, "bind: key %s not found\n", argv[1]);
387 if (cmd_keybinding_list[key])
388 d_free(cmd_keybinding_list[key]);
389 cmd_keybinding_list[key] = d_strdup(buf);
393 int Console_button_states[CMD_NUM_BUTTONS];
394 void cmd_attack_on(int argc, char **argv) { Console_button_states[CMD_ATTACK] = 1; }
395 void cmd_attack_off(int argc, char **argv) { Console_button_states[CMD_ATTACK] = 0; }
396 void cmd_attack2_on(int argc, char **argv) { Console_button_states[CMD_ATTACK2] = 1; }
397 void cmd_attack2_off(int argc, char **argv) { Console_button_states[CMD_ATTACK2] = 0; }
400 void cmd_impulse(int argc, char**argv)
404 int n = atoi(argv[1]);
405 if (n >= 1 && n <= 20) {
406 select_weapon((n-1) % 10, (n-1) / 10, 0, 1);
410 /* echo to console */
411 void cmd_echo(int argc, char **argv)
413 char buf[CMD_MAX_LENGTH] = "";
415 for (i = 1; i < argc; i++) {
417 strncat(buf, " ", CMD_MAX_LENGTH);
418 strncat(buf, argv[i], CMD_MAX_LENGTH);
420 con_printf(CON_NORMAL, "%s\n", buf);
424 void cmd_exec(int argc, char **argv) {
425 cmd_queue_t *new, *head, *tail;
427 char line[CMD_MAX_LENGTH] = "";
434 f = PHYSFSX_openReadBuffered(argv[1]);
436 con_printf(CON_CRITICAL, "exec: %s not found\n", argv[1]);
439 while (PHYSFSX_gets(f, line)) {
440 /* make a new queue item, add it to list */
441 MALLOC(new, cmd_queue_t, 1);
442 new->command_line = d_strdup(line);
451 con_printf(CON_DEBUG, "cmd_exec: adding %s\n", line);
455 /* add our list to the head of the main list */
457 tail->next = cmd_queue_head;
459 cmd_queue_tail = tail;
461 cmd_queue_head = head;
462 con_printf(CON_DEBUG, "cmd_exec: added to front of list\n");
467 void cmd_wait(int argc, char **argv)
472 cmd_queue_wait = atoi(argv[1]);
484 p = ((cmd_t *)p)->next;
490 d_free(((cmd_alias_t *)p)->value);
492 p = ((cmd_alias_t *)p)->next;
496 for (i = 0; i < 256; i++)
497 if (cmd_keybinding_list[i])
498 d_free(cmd_keybinding_list[i]);
504 memset(Console_button_states, 0, sizeof(int) * CMD_NUM_BUTTONS);
506 cmd_addcommand("alias", cmd_alias);
507 cmd_addcommand("bind", cmd_bind);
509 cmd_addcommand("+attack", cmd_attack_on);
510 cmd_addcommand("-attack", cmd_attack_off);
511 cmd_addcommand("+attack2", cmd_attack2_on);
512 cmd_addcommand("-attack2", cmd_attack2_off);
514 cmd_addcommand("impulse", cmd_impulse);
516 cmd_addcommand("echo", cmd_echo);
518 cmd_addcommand("exec", cmd_exec);
520 cmd_addcommand("wait", cmd_wait);