lash_game_map.c (3928B)
1 #include <stdlib.h> 2 #include <string.h> 3 #include <math.h> 4 5 #include "liblashgame/lash_game_map.h" 6 #include "liblashgame/lash_game_standard.h" 7 8 lash_map_simple_t * lash_mapSimpleInit(lash_map_simple_t *map, unsigned int *w, unsigned int *h) { 9 map->w = (unsigned int*)malloc(sizeof(unsigned int)); 10 map->h = (unsigned int*)malloc(sizeof(unsigned int)); 11 map->layer_count = 0; 12 *(map->w) = *w; 13 *(map->h) = *h; 14 map->layers = (lash_map_simple_layer_t**)malloc(sizeof(lash_map_simple_layer_t*) * LASH_GAME_MAP_SIMPLE_DEFAULT_LAYERS); 15 map->layer_path = lash_mapSimpleAddLayer(map); 16 return map; 17 } 18 19 void lash_mapSimpleFree(lash_map_simple_t *map) { 20 int i; 21 22 if (map->w != NULL) 23 free(map->w); 24 25 if (map->h != NULL) 26 free(map->h); 27 28 for (i = 0; i < map->layer_count; i++) { 29 if ((map->layers + i) != NULL) 30 free(map->layers + i); 31 } 32 33 } 34 35 int lash_mapSimpleGetSize(lash_map_simple_t *map) { 36 if (map == NULL) 37 return -1; 38 39 return *(map->w) * *(map->h); 40 } 41 42 lash_map_simple_layer_t * lash_mapSimpleAddLayer(lash_map_simple_t *map) { 43 lash_map_simple_layer_t *newlayer; 44 newlayer = (lash_map_simple_layer_t*)malloc(*(map->w) * *(map->h) * sizeof(lash_map_simple_layer_item_t)); 45 if (newlayer == NULL) 46 return NULL; 47 *(map->layers + map->layer_count) = newlayer; 48 map->layer_count ++; 49 return newlayer; 50 } 51 52 void lash_mapSimpleLayerPoke(lash_map_simple_layer_t *layer, const lash_game_map_index_t index, const lash_map_simple_layer_item_t value) { 53 if (layer == NULL) 54 return; 55 56 (layer+index)->val = value; 57 } 58 59 lash_map_simple_layer_item_t lash_mapSimpleLayerPeek(lash_map_simple_layer_t *layer, const lash_game_map_index_t index) { 60 if (layer == NULL) 61 return -1; 62 63 return (layer+index)->val; 64 } 65 66 lash_map_simple_t * lash_mapSimpleClip(lash_map_simple_t *clipmap, lash_map_simple_t *sourcemap, const unsigned int clip_x_radius, const unsigned int clip_y_radius, const lash_game_map_index_t clip_origin_index, enum lash_game_map_alignment clip_origin_alignment, int include_path_only) { 67 68 int i; 69 70 unsigned int delta_left; 71 unsigned int delta_right; 72 unsigned int delta_top; 73 unsigned int delta_bottom; 74 75 unsigned int clip_y_top; 76 unsigned int clip_y_bottom; 77 unsigned int clip_x_left; 78 unsigned int clip_x_right; 79 80 unsigned int clip_width; 81 unsigned int clip_height; 82 83 //lash_game_coords_cartesian_t map_coords_bounds; 84 lash_game_map_index_t map_index_last; 85 86 // if no valid source map 87 if (sourcemap == NULL) 88 return NULL; 89 else if (*sourcemap->w == 0 || *sourcemap->h == 0) 90 return NULL; 91 92 map_index_last = (*sourcemap->w * *sourcemap->h) - 1; 93 94 if (clip_origin_index > map_index_last) 95 return NULL; 96 97 // this will always clip from center 98 // also make possible clip from topleft 99 delta_top = (int)floor(clip_origin_index / *sourcemap->w); 100 delta_bottom = *sourcemap->h - delta_top - 1; 101 delta_left = clip_origin_index - delta_top * *sourcemap->w; 102 delta_right = ((delta_top + 1) * *sourcemap->w) - clip_origin_index - 1; 103 104 clip_y_top = clip_y_radius > delta_top ? delta_top : clip_y_radius; 105 clip_y_bottom = clip_y_radius > delta_bottom ? delta_bottom : clip_y_radius; 106 clip_x_left = clip_x_radius > delta_left ? delta_left : clip_x_radius; 107 clip_x_right = clip_x_radius > delta_right ? delta_right : clip_x_radius; 108 109 clip_width = (clip_x_right + clip_x_left + 1); 110 clip_height = (clip_y_bottom + clip_y_top + 1); 111 112 // we now have the size of the clip and the coords to cut 113 114 lash_mapSimpleInit(clipmap, &clip_width, &clip_height); 115 116 if (!include_path_only) { 117 for (i = 0; i < sourcemap->layer_count; i++) { 118 lash_mapSimpleAddLayer(clipmap); 119 } 120 } 121 122 // and fill in with values from the main map 123 124 for (i = clip_height - 1; i > -1; i--) { 125 int cpos = clip_origin_index - (*sourcemap->w * (i - delta_bottom)) - clip_x_left; 126 memcpy((*clipmap->layers + ((clip_height - 1 - i) * clip_width)), (*sourcemap->layers + cpos), clip_width * sizeof(lash_map_simple_layer_item_t)); 127 } 128 129 return clipmap; 130 }