#include "map.h" #include "tile.h" #include #include #include // printf /* ================================ struct Map *newMap(int width, int height) This function allocates memory for a 2D array of Tile pointers. Calls nullMap before returning the newly allocated Map. Returns: NULL on malloc failure for: map, map->tiles, map->tiles[x] TODO: Map->tiles could be fragmented - figure out a way to use one malloc call for both x and y. ================================ */ struct Map *newMap(int width, int height, int depth) { struct Map *map = malloc(sizeof(struct Map)); if (map == NULL) { // TODO: ERROR: could not allocate memory for Map return NULL; } map->width = width; map->height = height; map->depth = depth; map->tiles = malloc(width * sizeof(struct Tile ***)); if (map->tiles == NULL) { free(map); printf("ERR: malloc width failed\n"); return NULL; } int i,j; // TODO: error check for(i=0;itiles[i] = malloc(height * sizeof(struct Tile **)); if (map->tiles[i] == NULL) { printf("ERR: malloc height failed\n"); return NULL; } for(j=0;jtiles[i][j] = malloc(depth * sizeof(struct Tile*)); if (map->tiles[i][j] == NULL) { printf("ERR: malloc depth failed\n"); return NULL; } } } nullMap(map); return map; } /* ================================ nullMap(struct Map *map) This function takes a fully allocated Map and sets all Tile pointers to NULL. ================================ */ int nullMap(struct Map *map) { if (map == NULL) { // TODO: ERROR: zeroMap passed NULL map return 1; } int i, j, k; for(i=0;i < map->width;i++) { for(j=0;j < map->height;j++) { for(k=0;k < map->depth;k++) { map->tiles[i][j][k] = NULL; } } } return 0; } /* ================================ freeMap(struct Map *map, int flags) This function frees the given map. If flags contains MAP_FREE_TILES, then the Tiles themselves are also freed. ================================ */ #define MAP_FREE_TILES 1 void freeMap(struct Map *map, int flags) { if (map == NULL) return; int i, j, k; for(i=0;i < map->width;i++) { for(j=0;j < map->height;j++) { for(k=0;k < map->depth;k++) { if (flags & MAP_FREE_TILES) { //freeTile(map->tiles[i][j][k]); } //free(map->tiles[i][j][k]); } free(map->tiles[i][j]); } free(map->tiles[i]); } free(map->tiles); free(map); } /* Tile -> Map interaction */ int moveTile(struct Map *map, struct Tile *tile, float x, float y, float z) { //printf("request to move %fx%fx%f distance from %fx%fx%f\n", x, y, z, tile->x, tile->y, tile->z); float target_x = tile->x + x; float target_y = tile->y + y; float target_z = tile->z + z; //printf("absolute new pos %fx%fx%f\n", target_x, target_y, target_z); int tile_x = (int)target_x; int tile_y = (int)target_y; int tile_z = (int)target_z; //float leftover_x = target_x - tile_x; //float leftover_y = target_y - tile_y; //float leftover_z = target_z - tile_z; //printf("move to %dx%dx%d with %fx%fx%f leftover\n", tile_x, tile_y, tile_z, leftover_x, leftover_y, leftover_z); //printf(" MAP: %dx%dx%d vs %fx%fx%f\n", map->width, map->height, map->depth, target_x, target_y, target_z); if (target_x < -0.5f || target_y < -0.5f || target_z < -0.5f || target_x >= map->width || target_y >= map->height || target_z >= map->depth) { return 1; } if (tile_x != (int)tile->x || tile_y != (int)tile->y || tile_z != (int)tile->z) { if (map->tiles[tile_x][tile_y][tile_z] == NULL) { map->tiles[tile_x][tile_y][tile_z] = tile; //return 2; } else { removeTile(tile); // remove from current position appendTile(map->tiles[tile_x][tile_y][tile_z], tile); } } tile->x = target_x; tile->y = target_y; tile->z = target_z; return 0; } int addTileToMap(struct Map *map, struct Tile *tile, float x, float y, float z) { if (map == NULL) return -1; if (tile == NULL) return -2; int tile_x = (int)x; int tile_y = (int)y; int tile_z = (int)z; // if out of bounds, add to nearest cell if (tile_x >= map->width) { tile_x = map->width-1; } else if (tile_x < 0) { tile_x = 0; } if (tile_y >= map->height) { tile_y = map->height-1; } else if (tile_y < 0) { tile_y = 0; } if (tile_z >= map->depth) { tile_z = map->depth-1; } else if (tile_z < 0) { tile_z = 0; } // set tile's x, y, and z params tile->x = tile_x; tile->y = tile_y; tile->z = tile_z; if (map->tiles[tile_x][tile_y][tile_z] == NULL) { map->tiles[tile_x][tile_y][tile_z] = tile; return 0; } // if existing, append to tile linked list there appendTile(map->tiles[tile_x][tile_y][tile_z], tile); return 0; }