prepare new commands
authorNiki <niki@nikiroo.be>
Tue, 15 Apr 2025 15:54:58 +0000 (17:54 +0200)
committerNiki <niki@nikiroo.be>
Tue, 15 Apr 2025 15:54:58 +0000 (17:54 +0200)
src/tdef/command.c
src/tdef/command.h
src/tdef/reader.c
src/tdef/tdef.c

index 2786311905a09eca52a4d3b4d2035cd93e1dd33b..4a249f80a3f74c832dd73db747873791448d8a4c 100644 (file)
@@ -23,7 +23,7 @@
 #include "cutils/cstring.h"
 #include "command.h"
 
-array_t *read_word(command_t *self, char *line, int pstart, int pstop);
+array_t *read_word(command_t *self,const char line[],int pstart,int pstop);
 
 command_t *new_command(command_type type) {
        command_t *self = malloc(sizeof(command_t));
@@ -66,7 +66,37 @@ void uninit_command(command_t *self) {
        }
 }
 
-int command_read_str(command_t *self, char *line, int pstart, int pstop) {
+int command_read_count(command_t *self, const char line[]) {   
+       int howmany_read = 0;
+       int in_params = 0;
+       int escaped = 0;
+       for (size_t i = 0 ; line[i] ; i++) {
+               if (!in_params) {
+                       if (line[i] == ':')
+                               in_params = 1;
+                       
+                       continue;
+               }
+               
+               if (line[i] == '"')
+                       escaped = !escaped;
+               if (escaped)
+                       continue;
+               
+               if (line[i] == ',') {
+                       // parameter found
+                       howmany_read++;
+               }
+       }
+       
+       // Final parameter
+       if (in_params)
+               howmany_read++;
+       
+       return howmany_read;
+}
+
+int command_read_str(command_t *self,const char line[],int pstart,int pstop) {
        if (!self->data)
                self->data = new_array(sizeof(char *), 1);
        
@@ -102,7 +132,7 @@ int command_read_str(command_t *self, char *line, int pstart, int pstop) {
        return ok;
 }
 
-int command_read_int(command_t *self, char *line, int pstart, int pstop) {
+int command_read_int(command_t *self,const char line[],int pstart,int pstop) {
        if (!self->data)
                self->data = new_array(sizeof(char *), 1);
        
@@ -136,7 +166,7 @@ int command_read_int(command_t *self, char *line, int pstart, int pstop) {
        return ok;
 }
 
-int command_read_file(command_t *self, char *line, int pstart, int pstop) {
+int command_read_file(command_t *self,const char line[],int pstart,int pstop) {
        if (!self->data)
                self->data = new_array(sizeof(char *), 1);
        
@@ -177,7 +207,7 @@ int command_read_file(command_t *self, char *line, int pstart, int pstop) {
        return ok;
 }
 
-array_t *read_word(command_t *self, char *line, int pstart, int pstop) {
+array_t *read_word(command_t *self,const char line[],int pstart,int pstop) {
        array_t *tmp = new_array(sizeof(char *), 1);
        
        int howmany_read = 0;
index 26bc08eb04158be3b3aee44912bf70bb09f8df6c..d29016240d54aaae5be1b5c7c18cdbc2bc8999a0 100644 (file)
  * blablabla
  */
 typedef enum {
-       TICK,
-       DISPLAY,
-       READFILE,
-       UNKNOWN,
-       INVALID,
-       FILE404,
-       QUIT
+       COMMAND_TICK,
+       COMMAND_DISPLAY,
+       COMMAND_READFILE,
+       COMMAND_MAP,
+       COMMAND_LIFE,
+       COMMAND_BITS,
+       COMMAND_PATH,
+       COMMAND_QUIT,
+       
+       // error management:
+       COMMAND_UNKNOWN,
+       COMMAND_INVALID,
+       COMMAND_FILE404
 } command_type;
 
 /**
@@ -88,11 +94,13 @@ void uninit_command(command_t *self);
 // COMMAND:param1,param2,...
 // pstop 0 -> continue until no more param
 // white space ignored (trimmed)
-int command_read_str(command_t *self, char *line, int pstart, int pstop);
+int command_read_count(command_t *self, const char line[]);
 
-int command_read_int(command_t *self, char *line, int pstart, int pstop);
+int command_read_str(command_t *self,const char line[],int pstart,int pstop);
 
-int command_read_file(command_t *self, char *line, int pstart, int pstop);
+int command_read_int(command_t *self,const char line[],int pstart,int pstop);
+
+int command_read_file(command_t *self,const char line[],int pstart,int pstop);
 
 #endif /* COMMAND_H */
 
index 4e6d9d99a41b1df5dd5de66c23f4315f358763e3..d3b2184517a2bc2c457ddd1e4291c2a30b936efc 100644 (file)
 #include "cutils/cstring.h"
 #include "reader.h"
 
+// Commands are given in the form of:
+//     KEYWORD
+// or:
+//     KEYWORD: [parameters]
+//
+// Parameters are given in the form of:
+//     int_parameter1, int_parameter2...
+// or:
+//     "string parameter", "file parameter"
+//
+// Note that white space around the separators (':' or ',') are allowed.
+//
+// Known commands:
+// > .                        = will process a tick in the game engine
+// > display                  = will toggle display (debug) mode
+// > readfile : "file1..."    = will read commands from the given file(s)
+// > map      : width, height = will setup the map (and reset the path)
+// > life     : lives         = will set the number of life points
+// > bits     : bit_amount    = will set the current bits (money) balance
+// > path     : x1,y1,x2,y2.. = will setup the enemies path (cumulative)
+// > quit                     = will immediately exit the game
 
 // TODO: configuration:
-// map size
-// path: 1,1;1,2;1,3;
-// basic: setMoney, setLife, start...
 // tower: configTower('1', ...)
 // enemy: configEnemy('a', ...)
 
+int is_cmd(cstring_t *line, const char cmd[]) {
+       if (cstring_starts_with(line->string, cmd, 0)) {
+               int first_non_space = strlen(cmd);
+               while (line->string[first_non_space] == ' ')
+                       first_non_space++;
+               
+               char car = line->string[first_non_space];
+               if ((car == ':') || (car == '\0'))
+                       return 1;
+       }
+       
+       return 0;
+}
+
 command_t *reader_readnext(FILE *file) {
        static cstring_t *line = NULL;
        if (!line)
@@ -39,21 +71,51 @@ command_t *reader_readnext(FILE *file) {
        command_t *cmd = NULL;
        
        if (cstring_readline(line, file)) {
-               cmd = new_command(UNKNOWN);
+               cmd = new_command(COMMAND_UNKNOWN);
                
-               if (!strcmp(".", line->string)) {
-                       cmd->type = TICK;
-               } else if (cstring_starts_with(line->string, "display", 0)) {
-                       cmd->type = DISPLAY;
-               } else if (cstring_starts_with(line->string, "readfile", 0)) {
-                       cmd->type = READFILE;
+               if (is_cmd(line, ".")) {
+                       cmd->type = COMMAND_TICK;
+                       if (command_read_count(cmd, line->string))
+                               cmd->type = COMMAND_INVALID;
+               } else if (is_cmd(line, "display")) {
+                       cmd->type = COMMAND_DISPLAY;
+                       if (command_read_count(cmd, line->string))
+                               cmd->type = COMMAND_INVALID;
+               } else if (is_cmd(line, "readfile")) {
+                       cmd->type = COMMAND_READFILE;
                        if (!command_read_file(cmd, line->string, 0, -1)) {
-                               cmd->type = INVALID;
+                               cmd->type = COMMAND_INVALID;
                                if (command_read_str(cmd, line->string, 0, -1))
-                                       cmd->type = FILE404;
+                                       cmd->type = COMMAND_FILE404;
                        }
-               } else if (cstring_starts_with("quit", line->string, 0)) {
-                       cmd->type = QUIT;
+               } else if (is_cmd(line, "map")) {
+                       cmd->type = COMMAND_MAP;
+                       if (!command_read_int(cmd, line->string, 0, 1))
+                               cmd->type = COMMAND_INVALID;
+                       if (command_read_count(cmd, line->string) > 2)
+                               cmd->type = COMMAND_INVALID;
+               } else if (is_cmd(line, "life")) {
+                       cmd->type = COMMAND_LIFE;
+                       if (!command_read_int(cmd, line->string, 0, 0))
+                               cmd->type = COMMAND_INVALID;
+                       if (command_read_count(cmd, line->string) > 2)
+                               cmd->type = COMMAND_INVALID;
+               } else if (is_cmd(line, "bits")) {
+                       cmd->type = COMMAND_BITS;
+                       if (!command_read_int(cmd, line->string, 0, 0))
+                               cmd->type = COMMAND_INVALID;
+                       if (command_read_count(cmd, line->string) > 2)
+                               cmd->type = COMMAND_INVALID;
+               } else if (is_cmd(line, "path")) {
+                       cmd->type = COMMAND_PATH;
+                       if (!command_read_int(cmd, line->string, 0, -1))
+                               cmd->type = COMMAND_INVALID;
+                       if ((command_read_count(cmd, line->string) % 2) == 1)
+                               cmd->type = COMMAND_INVALID;
+               } else if (is_cmd(line, "quit")) {
+                       cmd->type = COMMAND_QUIT;
+                       if (command_read_count(cmd, line->string))
+                               cmd->type = COMMAND_INVALID;
                }
        }
        
index 8d7cf14e3531cc5543d9f6d19a34b08a558dcd87..84c2e22a518d0f9cc782a8ea829ecf5225fe6f82 100644 (file)
@@ -79,13 +79,13 @@ int process_cmd(command_t *cmd, engine_t *engine) {
                out = new_cstring();
        
        switch(cmd->type) {
-       case TICK:
+       case COMMAND_TICK:
                engine_tick(engine);
                break;
-       case DISPLAY:
+       case COMMAND_DISPLAY:
                displayMode = !displayMode;
                break;
-       case READFILE:
+       case COMMAND_READFILE:
                array_loop (cmd->data, ptr, char*) {
                        char *subname = *ptr;
                        FILE *sub = fopen(subname, "r");
@@ -102,19 +102,19 @@ int process_cmd(command_t *cmd, engine_t *engine) {
                                fprintf(stdout, "Done reading: %s\n",subname);
                }
                break;
-       case FILE404:
+       case COMMAND_FILE404:
                fprintf(stderr, "Unknown file(s):\n");
                array_loop_i (cmd->data, ptr, char*, i) {
                        fprintf(stderr, "%zu. \"%s\"\n", (i+1), *ptr);
                }
                break;
-       case UNKNOWN:
+       case COMMAND_UNKNOWN:
                fprintf(stderr, "Unrecognized command\n");
                break;
-       case INVALID:
+       case COMMAND_INVALID:
                fprintf(stderr, "Invalid command\n");
                break;
-       case QUIT:
+       case COMMAND_QUIT:
                return 0;
        }
        
@@ -127,7 +127,8 @@ int process_cmd(command_t *cmd, engine_t *engine) {
        array_clear(engine->events);
        
        // display mode
-       if ((cmd->type == TICK || cmd->type == DISPLAY) && (displayMode)) {
+       if ((cmd->type == COMMAND_TICK || cmd->type == COMMAND_DISPLAY)
+                       && (displayMode)) {
                fprintf(stderr, 
                        "Tick is: %zu\n", engine->current_tick);
                display(engine->map);