liblashgame

Pathfinder and path decision making library for 2D tile game
git clone git://holbrook.no/liblashgame.git
Info | Log | Files | Refs

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 }