diff --git a/microfx_src/include/microfx/ext/gametools.h b/microfx_src/include/microfx/ext/gametools.h index 512f1b4..1e3db44 100644 --- a/microfx_src/include/microfx/ext/gametools.h +++ b/microfx_src/include/microfx/ext/gametools.h @@ -14,16 +14,44 @@ typedef struct { int tw, th; /* Tile width and height */ int px, py; /* Contains the position of the player on the screen, after drawing the map */ + int pw, ph; /* Player height and width. */ + int sx, sy; /* Where the map started to be drawn. */ + int padx, pady; /* Where the map was drawn on the screen. */ + int sw, sh; /* The size of the part that was drawn on screen. */ } MMap; /* Prototypes */ -/* void dmap(int sx, int sy, MMap *map); +/* void vmap(int padx, int pady, int w, int h, int sx, int sy, MMap *map); Draws a map contained in a MMap struct. -dmap draw the map from sx, sy. +dmap draw the map from sx, sy, at padx, pady on the screen with width w and +height h on screen. +The map should be the first thing to be drawn, because the map is not perfectly +drawn at (padx, pady), and vplayer and vitem use some variables that are updated +when calling vmap. */ -void vmap(int sx, int sy, MMap *map); +void vmap(int padx, int pady, int w, int h, int sx, int sy, MMap *map); + +/* void vplayer(MMap *map, unsigned char **player_sprites, int anim_frame); + +Draws the player on map map, from the sprite coder image in the image table at +anim frame. +*/ + +void vplayer(MMap *map, unsigned char **player_sprites, int anim_frame); + +/* void vitem(MMap *map, int x, int y, int w, int h, unsigned char **item, + int anim_frame); + +Draws an item at the position (x, y) on the map on the screen. +item is the sprite coder sprite table that contains the diffrent frames of the +animation of this item. +anim_frame is the frame of the animation of item that should be drawn. +*/ + +void vitem(MMap *map, int x, int y, int w, int h, unsigned char **item, + int anim_frame); #endif diff --git a/microfx_src/src/ext/gametools/map.c b/microfx_src/src/ext/gametools/map.c index 4b273d0..1f364bb 100644 --- a/microfx_src/src/ext/gametools/map.c +++ b/microfx_src/src/ext/gametools/map.c @@ -2,7 +2,7 @@ #include "../../../include/microfx/ext/img.h" #include "../../../include/microfx/microfx.h" -void vmap(int sx, int sy, MMap *map) { +void vmap(int padx, int pady, int w, int h, int sx, int sy, MMap *map) { /* Dessine la map à l'écran. */ /* x et y contiendront la position à laquelle je suis dans la boucle. */ int x, y; @@ -12,53 +12,76 @@ void vmap(int sx, int sy, MMap *map) { /* mx contient le nombre de pixels qui seront cachés sur x, pareil pour y. */ int mx = sx-tx*map->tw, my = sy-ty*map->th; + /* dw et dh contiennent le nombre de tuiles à dessiner sur x et y. */ + int dw = w/map->tw+1, dh = h/map->th+1; + /* mw et mh contiennent la largeur et la hauteur de la map. */ + int mw = map->w*map->tw, mh = map->h*map->th; /* tile contient la tuile à dessiner */ unsigned char tile; /* J'ajuste sx. */ - if(sx-SWIDTH/2<0){ + if(sxpx = sx; sx = 0; - }else if(sx+SWIDTH/2>map->w*map->tw){ + }else if(sx+w/2>mw){ /* Si je ne peux pas centrer le joueur car je suis trop proche du bord droit de la map. */ - map->px = sx-(map->w*map->tw-SWIDTH/2); - sx = map->w*map->tw-SWIDTH/2; + map->px = sx-(mw-w/2); + sx = mw-w/2; }else{ /* Sinon je peux centrer le joueur. */ - sx = sx-SWIDTH/2; - map->px = SWIDTH/2; + sx = sx-w/2; + map->px = w/2; } /* J'ajuste sy. */ - if(sy-SHEIGHT/2<0){ + if(sypy = sy; sy = 0; - }else if(sy+SHEIGHT/2>map->h*map->th){ + }else if(sy+h/2>mh){ /* Si je ne peux pas centrer le joueur car je suis trop proche du bas de la map. */ - map->py = sy-(map->h*map->th-SHEIGHT/2); - sy = map->h*map->th-SHEIGHT/2; + map->py = sy-(mh-h/2); + sy = mh-h/2; }else{ /* Sinon je peux centrer le joueur. */ - sy = sy-SHEIGHT/2; - map->py = SHEIGHT/2; + sy = sy-h/2; + map->py = h/2; } tx = sx/map->tw; ty = sy/map->th; - for(y=0;yh;y++){ - for(x=0;xw;x++){ + for(y=0;yw){ + if(tx+x>=0 && tx+x < map->w && ty+y>=0 && ty+y < map->h){ tile = map->map[(ty+y)*map->w+tx+x]; if(tile > 0){ - simage(x*map->tw-mx, y*map->th-my, map->tw, map->th, - map->tileset[(int)tile-1], SNORMAL); + simage(x*map->tw-mx+padx, y*map->th-my+pady, map->tw, + map->th, map->tileset[(int)tile-1], SNORMAL); } } } } + map->sx = sx; + map->sy = sy; + map->sw = w; + map->sh = h; + map->padx = padx; + map->pady = pady; +} + +void vplayer(MMap *map, unsigned char **player_sprites, int anim_frame) { + simage(map->px, map->py, map->pw, map->ph, player_sprites[anim_frame], + SNORMAL); +} + +void vitem(MMap *map, int x, int y, int w, int h, unsigned char **item, + int anim_frame) { + int dx = x-map->sx, dy = y-map->sy; + if(dx+w>=0 && dxsw && dy+h>=0 && dysh) { + simage(dx, dy, w, h, item[anim_frame], SNORMAL); + } } diff --git a/template/lib/libMicrofx.a b/template/lib/libMicrofx.a index 8542b38..52cfe57 100644 Binary files a/template/lib/libMicrofx.a and b/template/lib/libMicrofx.a differ diff --git a/tools/mapconv/Makefile b/tools/mapconv/Makefile index 47d4f99..864b7cb 100644 --- a/tools/mapconv/Makefile +++ b/tools/mapconv/Makefile @@ -1,15 +1,18 @@ NAME = mapconv -SRC = src/main.c +SRC = src/main.c \ + src/parse.c OBJ = $(SRC:src/%=build/%.o) BUILD = build +CFLAGS = -Wall -Wextra -Wpedantic + all: $(OBJ) $(CC) $(OBJ) -o $(NAME) -$(OBJ): $(SRC) | $(BUILD)/ - $(CC) -c $< -o $@ -Os -Iinc -std=c89 +$(BUILD)/%.o: src/% | $(BUILD)/ + $(CC) -c $< -o $@ -Os -Iinc -std=c89 $(CFLAGS) .PRECIOUS: %/ diff --git a/tools/mapconv/inc/help.h b/tools/mapconv/inc/help.h index 7a135c9..f001bbb 100644 --- a/tools/mapconv/inc/help.h +++ b/tools/mapconv/inc/help.h @@ -5,18 +5,6 @@ const char help[] = "mapconv - Microfx map creator\n\n" "This little tool makes it easier to create maps for the Microfx gametools ext." "\n" "Use :\n" -" mapconv map.txt conf.txt map.h\n" -"map.txt should contain a map made out of ASCII characters. Each line in the\n" -"map.txt file should represent one line in the map.\n" -"conf.txt should contain the map width, on the next line the height and then,\n" -"after, the number of the tile followed by a space and her ASCII character like" -"\n" -"this :\n" -" 1 #\n" -"The last argument is the header file that will be generated. You'll just need" -"\n" -"to modify it to add some informations into the MMap struct before using it in" -"\n" -"your game."; +" mapconv conf.txt\n"; #endif diff --git a/tools/mapconv/inc/parse.h b/tools/mapconv/inc/parse.h new file mode 100644 index 0000000..d7162b5 --- /dev/null +++ b/tools/mapconv/inc/parse.h @@ -0,0 +1,31 @@ +#ifndef PARSE_H +#define PARSE_H + +#define TOKEN_SZ 64 + +typedef enum { + T_GROUP, + T_NAME, + T_CHAR, + T_STRING, + T_INT +} Token; + +typedef struct { + Token token; + char content[TOKEN_SZ]; +} Tokendata; + +typedef enum { + FALSE, + TRUE +} bool; + +int parse(char *content, Tokendata **data); +int search_token(Token token, char *content, Tokendata *tokens, int token_d_sz); +int get_value_from_name(Token value_type, char *value, Tokendata *tokens, + int token_d_sz); +int get_value_from_name_noerror(Token value_type, char *value, + Tokendata *tokens, int token_d_sz); + +#endif diff --git a/tools/mapconv/src/main.c b/tools/mapconv/src/main.c index d2fecf6..eab4bde 100644 --- a/tools/mapconv/src/main.c +++ b/tools/mapconv/src/main.c @@ -2,65 +2,27 @@ #include #include #include +#include -void grabint(char *data, int size, int *start, char stop, int *out) { - int i; - *out=0; - for(i=0;*start int main(int argc, char **argv) { FILE *fp; FILE *fp_map; size_t size; - char tile[256]; - int i, n, oldn, a, len; - int w, h; - if(argc < 4){ + char tiles[256]; + int i, a, len, out; + int w, h, pw, ph, tw, th, padx, pady, dw, dh; + bool found; + Tokendata *tokens = NULL; + char buffer[TOKEN_SZ], c; + char *data = NULL; + int amount; + if(argc < 2){ puts(help); return 1; } - char *data = NULL; - fp = fopen(argv[2], "rb"); - if(fp == NULL){ - printf("[mapconv] Can't open \"%s\"\n", argv[2]); - return 2; - } - fseek(fp, 0L, SEEK_END); - size = ftell(fp); - rewind(fp); - data = malloc(sizeof(unsigned char) * size); - if(data == NULL){ - puts("[mapconv] More memory needed !"); - return 3; - } - if(!fread(data, 1, sizeof(unsigned char) * size, fp)){ - fclose(fp); - return; - } - fclose(fp); - /* Get the width and the height */ - n=0; - grabint(data, size, &n, '\n', &w); - grabint(data, size, &n, '\n', &h); - oldn = n; - len = 0; - for(i=0;i<256 && n\n\n" - "const unsigned char _map[] = {", fp_map); - for(i=0;i= 0x30 && c <= 0x39) || (c >= 0x41 && c <= 0x5A) || + (c >= 0x61 && c <= 0x7A)){ + buffer[i] = toupper(c); + }else{ + buffer[i] = '_'; + } + } + puts("[status] Generating header."); + i=get_value_from_name(T_STRING, "tileset_header", tokens, out); + fprintf(fp_map, "#ifndef %s_H\n#define %s_H\n\n#include <%s>\n" + "#include \n\nconst unsigned char _%s[] = {", + buffer, buffer, tokens[i].content, tokens[a].content); + amount = 0; + for(i=0;i<(int)size;i++){ if(data[i] != '\n'){ + found = FALSE; for(a=0;a + +#include +#include + +#include + +int parse(char *content, Tokendata **data) { + int i, current_token_pos = 0; + bool token_started = FALSE; + char c; + char current_token[TOKEN_SZ]; + Token current_token_type; + int token_num = 0; + for(i=0;i<(int)strlen(content);i++){ + c = content[i]; + if(!token_started && c != ' '){ + token_started = TRUE; + switch(c){ + case '\'': + current_token_type = T_CHAR; + break; + case '"': + current_token_type = T_STRING; + break; + case '-': + current_token_type = T_GROUP; + break; + default: + current_token_type = T_NAME; + } + if(c >= 0x30 && c <= 0x39){ + current_token_type = T_INT; + } + } + if(token_started){ + if(c != ' ' || (current_token_type == T_STRING || + current_token_type == T_CHAR)){ + /* TODO : the following condition should be changed, to allow + '"', '\'' and '-' in chars, strings, names, groups ... */ + if(current_token_pos < TOKEN_SZ && (c != '"' && c != '\'' && + c != '=' && c != '-' && c != '\n')){ + current_token[current_token_pos] = c; + current_token_pos++; + }else if(current_token_pos >= TOKEN_SZ){ + puts("[config] Too big token !"); + return -2; + } + } + if(((c == '=' && current_token_type == T_NAME) || + c == '\n') && strlen(current_token) > 0){ + (*data) = realloc((*data), (token_num+1)*sizeof(Tokendata)); + if(!(*data)){ + puts("[config] More memory needed !"); + return -1; + } + (*data)[token_num].token = current_token_type; + strcpy((*data)[token_num].content, current_token); + memset(current_token, '\0', TOKEN_SZ); + current_token_pos = 0; + token_started = FALSE; + token_num++; + } + } + } + if(current_token_pos > 0){ + (*data) = realloc((*data), (token_num+1)*sizeof(Tokendata)); + if(!(*data)){ + puts("[config] More memory needed !"); + return -1; + } + (*data)[token_num].token = current_token_type; + strcpy((*data)[token_num].content, current_token); + } + return token_num; +} + +int search_token(Token token, char *content, Tokendata *tokens, + int token_d_sz) { + int i; + for(i=0;i= token_d_sz){ + printf("[config] Can't get \"%s\" value, value not existing ! !\n", + value); + exit(-2); + } + if(tokens[i+1].token != value_type){ + printf("[config] Bad type for \"%s\" value !\n", value); + exit(-2); + } + return i+1; +} + +int get_value_from_name_noerror(Token value_type, char *value, + Tokendata *tokens, int token_d_sz) { + int i; + i=search_token(T_NAME, value, tokens, token_d_sz); + if(i<0 || i+1 >= token_d_sz){ + return -1; + } + if(tokens[i+1].token != value_type){ + return -1; + } + return i+1; +}