improve command system and add some
authorNiki <niki@nikiroo.be>
Wed, 16 Apr 2025 06:35:54 +0000 (08:35 +0200)
committerNiki <niki@nikiroo.be>
Wed, 16 Apr 2025 06:35:54 +0000 (08:35 +0200)
src/tdef/command.c
src/tdef/command.h
src/tdef/engine.c
src/tdef/engine.h
src/tdef/event.c
src/tdef/event.h
src/tdef/reader.c
src/tdef/setup.c
src/tdef/tdef.c

index 4a249f80a3f74c832dd73db747873791448d8a4c..6280cf8ef976d95d169e4f723941ddcd91ecb069 100644 (file)
@@ -207,6 +207,16 @@ int command_read_file(command_t *self,const char line[],int pstart,int pstop) {
        return ok;
 }
 
+char *command_get(command_t *self, int i) {
+       char **p = array_get(self->data, i);
+       return *p;
+}
+
+int command_get_int(command_t *self, int i) {
+       char **p = array_get(self->data, i);
+       return atoi(*p);
+}
+
 array_t *read_word(command_t *self,const char line[],int pstart,int pstop) {
        array_t *tmp = new_array(sizeof(char *), 1);
        
@@ -265,7 +275,7 @@ array_t *read_word(command_t *self,const char line[],int pstart,int pstop) {
                howmany_read++;
        }
        
-       if ((pstop >= 0) && (tmp->count != (pstop - pstart))) {
+       if ((pstop >= 0) && (tmp->count != ((pstop - pstart) + 1))) {
                free_array(tmp);
                tmp = NULL;
        }
index d29016240d54aaae5be1b5c7c18cdbc2bc8999a0..84e2054997e3cdbd627f987d2dd8e16ef7d62bc2 100644 (file)
@@ -21,6 +21,7 @@
  * blablabla
  */
 typedef enum {
+       COMMAND_COMMENT,
        COMMAND_TICK,
        COMMAND_DISPLAY,
        COMMAND_READFILE,
@@ -102,5 +103,9 @@ 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);
 
+char *command_get(command_t *self, int i);
+
+int command_get_int(command_t *self, int i);
+
 #endif /* COMMAND_H */
 
index bee6dddcb2c9b75b91480ad1fa08fa2051361179..85ba3c92c66b9c1cd078157ef9ef62fac3f846d2 100644 (file)
@@ -25,9 +25,9 @@
 
 int tickit();
 
-engine_t *new_engine(map_t *map) {
+engine_t *new_engine() {
        engine_t *self = malloc(sizeof(engine_t));
-       if (!init_engine(self, map)) {
+       if (!init_engine(self)) {
                free(self);
                self = NULL;
        }
@@ -35,13 +35,13 @@ engine_t *new_engine(map_t *map) {
        return self;
 }
 
-int init_engine(engine_t *self, map_t *map) {
+int init_engine(engine_t *self) {
        size_t sz = sizeof(self->CNAME);
        strncpy(self->CNAME, "[engine          ", sz);
        self->CNAME[sz - 2] = ']';
        self->CNAME[sz - 1] = '\0';
        
-       self->map          = map;
+       self->map          = NULL;
        self->current_tick = 0;
        self->waves        = new_array(sizeof(wave_t) , 10);
        self->events       = new_array(sizeof(event_t), 20);
@@ -82,7 +82,27 @@ void uninit_engine(engine_t *self) {
        free_array(self->ebases) ; self->ebases = NULL;
 }
 
+int engine_reset_map(engine_t *self, int width, int height) {
+       if (self->map)
+               free_map(self->map);
+       self->current_tick = 0;
+       self->current_wave = 0;
+       self->last_enemy = NULL;
+       self->map = new_map(width, height);
+       
+       return !!self->map;
+}
+
 void engine_tick(engine_t *self) {
+       if (!self->map) {
+               event_t event;
+               init_event(&event, ERROR);
+               event.x = EEVENT_NOMAP;
+               array_push(self->events, &event);
+
+               return;
+       }
+       
        // Note that multiple ennemies per tick will trigger the backfill
        array_loop_i (self->waves, wave, wave_t, i) {
                if (wave->done)
index cd97f0249fc74278f39823773c422cf24818b247..15642f093c1d0dcccaa6561b56091d13c6626caa 100644 (file)
@@ -39,8 +39,6 @@ typedef struct {
 /**
  * Create a new engine.
  *
- * @param map the game map (will be owned by this engine)
- *
  * @note always identical to <tt>malloc</tt> + <tt>init_engine</tt>
  *
  * @see malloc()
@@ -48,14 +46,12 @@ typedef struct {
  *
  * @return a new engine (you must later call `free_engine()`)
  */
-engine_t *new_engine(map_t *map);
+engine_t *new_engine();
 
 /**
  * Initialise a new engine.
- *
- * @param map the game map (will be owned by this engine)
  */
-int init_engine(engine_t *self, map_t *map);
+int init_engine(engine_t *self);
 
 /** 
  * Free the resources held for the given engine: you must not use it any more.
@@ -80,6 +76,9 @@ void free_engine(engine_t *self);
  */
 void uninit_engine(engine_t *self);
 
+// @param map the game map (will be owned by this engine)
+int engine_reset_map(engine_t *self, int width, int height);
+
 // will clear events on start!
 void engine_tick(engine_t *self);
 
index c3d07c10729de313a4a1b0a1656ab3b9b9cbdfc9..150c2b23f6acc496acdd6c1ab835b37238ce9baa 100644 (file)
@@ -71,6 +71,7 @@ const char *event_name(event_t *self) {
        case WAVE    : return "WAVE"    ;
        case WIN     : return "WIN"     ;
        case LOOSE   : return "LOOSE"   ;
+       case ERROR   : return "ERROR"   ;
        }
        return "Unknown";
 }
@@ -100,6 +101,9 @@ void event_output(event_t *self, cstring_t *out) {
        case WIN: case LOOSE:
                cstring_addp(out, "EVENT:%s\n", name);
                break;
+       case ERROR:
+               cstring_addp(out, "ERROR: %d\n", self->x);
+               break;
        }
 }
 
index 48f37ca915a13baa30e9aa68dbdd51bf27bc265c..ff7c63f7ddd07b79565bc29a8f15b172a9a5ce47 100644 (file)
@@ -32,8 +32,13 @@ typedef enum {
        WAVE,
        WIN,
        LOOSE,
+       ERROR,
 } event_type;
 
+typedef enum {
+       EEVENT_NOMAP,
+} eevent_type;
+
 /**
  * @brief bla
  *
index d3b2184517a2bc2c457ddd1e4291c2a30b936efc..b9649a122b88e36b57a9da2b97a4e9443b11d6e8 100644 (file)
@@ -27,6 +27,8 @@
 //     KEYWORD
 // or:
 //     KEYWORD: [parameters]
+// or:
+//     # comment... (mostly used for data files)
 //
 // Parameters are given in the form of:
 //     int_parameter1, int_parameter2...
@@ -58,6 +60,9 @@ int is_cmd(cstring_t *line, const char cmd[]) {
                char car = line->string[first_non_space];
                if ((car == ':') || (car == '\0'))
                        return 1;
+               // Special empty line/comment check:
+               if (!cmd[0] && car == '#')
+                       return 1;
        }
        
        return 0;
@@ -73,7 +78,9 @@ command_t *reader_readnext(FILE *file) {
        if (cstring_readline(line, file)) {
                cmd = new_command(COMMAND_UNKNOWN);
                
-               if (is_cmd(line, ".")) {
+               if (is_cmd(line, "")) { // also checks for "#"
+                       cmd->type = COMMAND_COMMENT;
+               } else if (is_cmd(line, ".")) {
                        cmd->type = COMMAND_TICK;
                        if (command_read_count(cmd, line->string))
                                cmd->type = COMMAND_INVALID;
@@ -92,7 +99,7 @@ command_t *reader_readnext(FILE *file) {
                        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)
+                       if (command_read_count(cmd, line->string) != 2)
                                cmd->type = COMMAND_INVALID;
                } else if (is_cmd(line, "life")) {
                        cmd->type = COMMAND_LIFE;
index c75989af04b0e160ec7c34590712afc50b2fb88e..db0d6b7b2bb2bc866a355e7e24cedeecf5bb6c52 100644 (file)
@@ -21,6 +21,7 @@
 #include <stdlib.h>
 
 #include "setup.h"
+#include "event.h"
 
 tower_base_t *setup_tower_base(engine_t *self, int type, int cost) {
        tower_base_t *base = engine_get_tower_base(self, type);
@@ -57,6 +58,15 @@ enemy_t *setup_enemy(engine_t *self, int type, int id, size_t start_tick) {
 }
 
 int setup_path(engine_t *self, int x, int y) {
+       if (!self->map) {
+               event_t event;
+               init_event(&event, ERROR);
+               event.x = EEVENT_NOMAP;
+               array_push(self->events, &event);
+
+               return 0;
+       }
+       
        return map_add_path(self->map, x, y);
 }
 
index 84c2e22a518d0f9cc782a8ea829ecf5225fe6f82..110ca654bf2d6ddbb91a66c2dd8658a7abf664dd 100644 (file)
@@ -79,6 +79,8 @@ int process_cmd(command_t *cmd, engine_t *engine) {
                out = new_cstring();
        
        switch(cmd->type) {
+       case COMMAND_COMMENT:
+               break;
        case COMMAND_TICK:
                engine_tick(engine);
                break;
@@ -102,6 +104,30 @@ int process_cmd(command_t *cmd, engine_t *engine) {
                                fprintf(stdout, "Done reading: %s\n",subname);
                }
                break;
+       case COMMAND_MAP:
+               engine_reset_map(
+                               engine, 
+                               command_get_int(cmd, 0),
+                               command_get_int(cmd, 1)
+               );
+               break;
+       case COMMAND_LIFE:
+               engine->life = command_get_int(cmd, 0);
+               break;
+       case COMMAND_BITS:
+               engine->bits = command_get_int(cmd, 0);
+               break;
+       case COMMAND_PATH:
+               setup_path(
+                               engine,
+                               command_get_int(cmd, 0),
+                               command_get_int(cmd, 1)
+               );
+               break;
+       case COMMAND_QUIT:
+               return 0;
+       
+       // Error management:
        case COMMAND_FILE404:
                fprintf(stderr, "Unknown file(s):\n");
                array_loop_i (cmd->data, ptr, char*, i) {
@@ -114,8 +140,6 @@ int process_cmd(command_t *cmd, engine_t *engine) {
        case COMMAND_INVALID:
                fprintf(stderr, "Invalid command\n");
                break;
-       case COMMAND_QUIT:
-               return 0;
        }
        
        // Process all events
@@ -151,30 +175,20 @@ void read_commands(engine_t *engine, FILE *file) {
 }
 
 int main(int argc, char **argv) {
-       map_t *map = new_map(6, 4);
-       engine_t *engine = new_engine(map);
-       if (!map || !engine) {
+       engine_t *engine = new_engine();
+       if (!engine) {
                fprintf(stderr, "Allocation error");
                return 1;
        }
        
-       setup_path(engine, 0, 0);
-       setup_path(engine, 1, 0);
-       setup_path(engine, 2, 0);
-       setup_path(engine, 3, 0);
-       setup_path(engine, 3, 1);
-       setup_path(engine, 3, 2);
-       setup_path(engine, 4, 2);
-       setup_path(engine, 5, 2);
-       
-       setup_tower_base(engine, 0, 10);
-       
-       enemy_t *enemy = setup_enemy(engine, 0, 0, 0);
-       enemy->speed = 2;
-       enemy->bits = 5;
-       
-       engine->bits = 100;     
-       engine_add_tower(engine, 0, 2, 1);
+       /* DEBUG */
+       command_t debug;
+       init_command(&debug, COMMAND_READFILE);
+       debug.data = new_array(sizeof(char **), 1);
+       char **ptr = array_new(debug.data);
+       *ptr = cstring_convert(cstring_clone("setup.debug"));
+       process_cmd(&debug, engine);
+       /* */
        
        read_commands(engine, stdin);