Пример #1
0
/* Test al_ustr_get on invalid sequences. */
static void t22(void)
{
   ALLEGRO_USTR_INFO info;
   const ALLEGRO_USTR *us;

   /* Empty string. */
   al_set_errno(0);
   CHECK(al_ustr_get(al_ustr_empty_string(), 0) < 0);
   CHECK(al_get_errno() == ERANGE);

   /* 5-byte sequence. */
   us = al_ref_cstr(&info, "\xf8\x88\x80\x80\x80");
   al_set_errno(0);
   CHECK(al_ustr_get(us, 0) < 0);
   CHECK(al_get_errno() == EILSEQ);

   /* Start in trail byte. */
   us = al_ref_cstr(&info, "ð");
   al_set_errno(0);
   CHECK(al_ustr_get(us, 1) < 0);
   CHECK(al_get_errno() == EILSEQ);

   /* Truncated 3-byte sequence. */
   us = al_ref_cstr(&info, "\xEF\xBF");
   al_set_errno(0);
   CHECK(al_ustr_get(us, 0) < 0);
   CHECK(al_get_errno() == EILSEQ);
}
Пример #2
0
	Font::Font(const string& filename, int size, bool antialiasing, bool hinting, bool kerning)
	: implementation(new Implementation)
	{
		checkInit();

		//I know, pretty odd...
		int flags = (antialiasing? 0 : ALLEGRO_TTF_MONOCHROME)	| (hinting? 0 : ALLEGRO_TTF_NO_AUTOHINT) | (kerning? 0 : ALLEGRO_TTF_NO_KERNING);
		this->implementation->allegroFont = al_load_ttf_font(filename.c_str(), size, flags);

		if(this->implementation->allegroFont == null)
			throw AdapterException("Font %s could not be loaded: Error %d", filename.c_str(), al_get_errno());
	}
Пример #3
0
/*
 * Parse a map file into an `ALLEGRO_MAP` struct. By default, relative values of `dir`
 * will be resolved relative to the path of the running executable. To change this,
 * call `al_find_resources_as(RELATIVE_TO_CWD);` first.
 */
ALLEGRO_MAP *al_open_map(const char *dir, const char *filename)
{
	char *cwd = al_get_current_directory();
	if (!cwd) {
		fprintf(stderr, "failed to get cwd; errno = %d", al_get_errno());
		return NULL;
	}

	// `resources` will point to either cwd or the location of the running executable,
	// depending on what was passed in for `rel`.
	ALLEGRO_PATH *resources;
	switch (resources_rel_to) {
		case RELATIVE_TO_EXE:
			resources = al_get_standard_path(ALLEGRO_RESOURCES_PATH);
			break;

		case RELATIVE_TO_CWD:
			resources = al_create_path_for_directory(cwd);
			break;

		default:
			fprintf(stderr, "unexpected value for `resources_rel_to` in al_open_map(): %d\n",
					resources_rel_to);
			al_free(cwd);
			return NULL;
	}

	ALLEGRO_PATH *map_dir = al_create_path_for_directory(dir);

	// Change directory to <cwd>/dir if dir is relative, otherwise dir.
	ALLEGRO_PATH *new_path = (al_join_paths(resources, map_dir) ? resources : map_dir);
	const char *new_path_cstr = al_path_cstr(new_path, ALLEGRO_NATIVE_PATH_SEP);
	if (!al_change_directory(new_path_cstr)) {
		fprintf(stderr, "Error: failed to cd into `%s` in al_open_map().\n",
				new_path_cstr);

		al_destroy_path(resources);
		al_destroy_path(map_dir);
		al_free(cwd);
		return NULL;
	}

	al_destroy_path(resources);
	al_destroy_path(map_dir);

	// Read in the data file
	xmlDoc *doc = xmlReadFile(filename, NULL, 0);
	if (!doc) {
		fprintf(stderr, "Error: failed to parse map data: %s\n", filename);
		al_free(cwd);
		return NULL;
	}

	// Get the root element, <map>
	xmlNode *root = xmlDocGetRootElement(doc);

	// Get some basic info
	ALLEGRO_MAP *map = MALLOC(ALLEGRO_MAP);
	map->width = atoi(get_xml_attribute(root, "width"));
	map->height = atoi(get_xml_attribute(root, "height"));
	map->tile_width = atoi(get_xml_attribute(root, "tilewidth"));
	map->tile_height = atoi(get_xml_attribute(root, "tileheight"));
	map->orientation = g_strdup(get_xml_attribute(root, "orientation"));
	map->tile_layer_count = 0;
	map->object_layer_count = 0;

	// Get the tilesets
	GSList *tilesets = get_children_for_name(root, "tileset");
	map->tilesets = NULL;

	GSList *tileset_item = tilesets;
	while (tileset_item) {
		xmlNode *tileset_node = (xmlNode*)tileset_item->data;
		tileset_item = g_slist_next(tileset_item);

		ALLEGRO_MAP_TILESET *tileset = MALLOC(ALLEGRO_MAP_TILESET);
		tileset->firstgid = atoi(get_xml_attribute(tileset_node, "firstgid"));
		tileset->tilewidth = atoi(get_xml_attribute(tileset_node, "tilewidth"));
		tileset->tileheight = atoi(get_xml_attribute(tileset_node, "tileheight"));
		tileset->name = g_strdup(get_xml_attribute(tileset_node, "name"));

		// Get this tileset's image
		xmlNode *image_node = get_first_child_for_name(tileset_node, "image");
		tileset->width = atoi(get_xml_attribute(image_node, "width"));
		tileset->height = atoi(get_xml_attribute(image_node, "height"));
		tileset->source = g_strdup(get_xml_attribute(image_node, "source"));
		tileset->bitmap = al_load_bitmap(tileset->source);
		if (!tileset->bitmap) {
			fprintf(stderr, "Error: no bitmap available; did you load the image addon?\n");
		}

		// Get this tileset's tiles
		GSList *tiles = get_children_for_name(tileset_node, "tile");
		tileset->tiles = NULL;

		GSList *tile_item = tiles;
		while (tile_item) {
			xmlNode *tile_node = (xmlNode*)tile_item->data;
			tile_item = g_slist_next(tile_item);

			ALLEGRO_MAP_TILE *tile = MALLOC(ALLEGRO_MAP_TILE);
			tile->id = tileset->firstgid + atoi(get_xml_attribute(tile_node, "id"));
			tile->tileset = tileset;
			tile->bitmap = NULL;

			// Get this tile's properties
			tile->properties = parse_properties(tile_node);

			// TODO: add a destructor
			tileset->tiles = g_slist_prepend(tileset->tiles, tile);
		}

		g_slist_free(tiles);
		//tileset->tiles = g_slist_reverse(tileset->tiles);

		// TODO: add a destructor
		map->tilesets = g_slist_prepend(map->tilesets, tileset);
	}

	g_slist_free(tilesets);
	//map->tilesets = g_slist_reverse(map->tilesets);

	// Create the map's master list of tiles
	cache_tile_list(map);

	// Get the layers
	GSList *layers = get_children_for_either_name(root, "layer", "objectgroup");
	map->layers = NULL;

	GSList *layer_item = layers;
	while (layer_item) {
		xmlNode *layer_node = (xmlNode*)layer_item->data;
		layer_item = g_slist_next(layer_item);

		ALLEGRO_MAP_LAYER *layer = MALLOC(ALLEGRO_MAP_LAYER);
		layer->name = g_strdup(get_xml_attribute(layer_node, "name"));
		layer->properties = parse_properties(layer_node);

		char *layer_visible = get_xml_attribute(layer_node, "visible");
		layer->visible = (layer_visible != NULL ? atoi(layer_visible) : 1);

		char *layer_opacity = get_xml_attribute(layer_node, "opacity");
		layer->opacity = (layer_opacity != NULL ? atof(layer_opacity) : 1.0);

		if (!strcmp((const char*)layer_node->name, "layer")) {
			layer->type = TILE_LAYER;
			layer->width = atoi(get_xml_attribute(layer_node, "width"));
			layer->height = atoi(get_xml_attribute(layer_node, "height"));
			decode_layer_data(get_first_child_for_name(layer_node, "data"), layer);

			// Create any missing tile objects
			unsigned i, j;
			for (i = 0; i < layer->height; i++) {
				for (j = 0; j < layer->width; j++) {
					char id = al_get_single_tile_id(layer, j, i);

					if (id == 0) {
						continue;
					}

					ALLEGRO_MAP_TILE *tile = al_get_tile_for_id(map, id);
					if (!tile) {
						// wasn't defined in the map file, presumably because it had no properties
						tile = MALLOC(ALLEGRO_MAP_TILE);
						tile->id = id;
						tile->properties = g_hash_table_new(NULL, NULL);
						tile->tileset = NULL;
						tile->bitmap = NULL;

						// locate its tilemap
						GSList *tilesets = map->tilesets;
						ALLEGRO_MAP_TILESET *tileset_ref;
						while (tilesets) {
							ALLEGRO_MAP_TILESET *tileset = (ALLEGRO_MAP_TILESET*)tilesets->data;
							tilesets = g_slist_next(tilesets);
							if (tileset->firstgid <= id) {
								if (!tile->tileset || tileset->firstgid > tile->tileset->firstgid) {
									tileset_ref = tileset;
								}
							}

						}

						tile->tileset = tileset_ref;
						tileset_ref->tiles = g_slist_prepend(tileset_ref->tiles, tile);
						g_hash_table_insert(map->tiles, GINT_TO_POINTER(tile->id), tile);
					}

					// create this tile's bitmap if it hasn't been yet
					if (!tile->bitmap) {
						ALLEGRO_MAP_TILESET *tileset = tile->tileset;
						int id = tile->id - tileset->firstgid;
						int width = tileset->width / tileset->tilewidth;
						int x = (id % width) * tileset->tilewidth;
						int y = (id / width) * tileset->tileheight;
						if (tileset->bitmap) {
							tile->bitmap = al_create_sub_bitmap(
									tileset->bitmap,
									x, y,
									tileset->tilewidth,
									tileset->tileheight);
						}
					}
				}
			}
			map->tile_layer_count++;
			map->tile_layers = g_slist_prepend(map->tile_layers, layer);
		} else if (!strcmp((const char*)layer_node->name, "objectgroup")) {
			layer->type = OBJECT_LAYER;
			layer->objects = NULL;
			layer->object_count = 0;
			// TODO: color?
			GSList *objects = get_children_for_name(layer_node, "object");
			GSList *object_item = objects;
			while (object_item) {
				xmlNode *object_node = (xmlNode*)object_item->data;
				object_item = g_slist_next(object_item);

				ALLEGRO_MAP_OBJECT *object = MALLOC(ALLEGRO_MAP_OBJECT);
				object->layer = layer;
				object->name = g_strdup(get_xml_attribute(object_node, "name"));
				object->type = g_strdup(get_xml_attribute(object_node, "type"));
				object->x = atoi(get_xml_attribute(object_node, "x"));
				object->y = atoi(get_xml_attribute(object_node, "y"));
				object->bitmap = NULL;

				char *object_width = get_xml_attribute(object_node, "width");
				object->width = (object_width ? atoi(object_width) : 0);

				char *object_height = get_xml_attribute(object_node, "height");
				object->height = (object_height ? atoi(object_height) : 0);

				char *gid = get_xml_attribute(object_node, "gid");
				object->gid = (gid ? atoi(gid) : 0);

				char *object_visible = get_xml_attribute(object_node, "visible");
				object->visible = (object_visible ? atoi(object_visible) : 1);

				// Get the object's properties
				object->properties = parse_properties(object_node);
				layer->objects = g_slist_prepend(layer->objects, object);
				layer->object_count++;
			}
			map->object_layer_count++;
			map->object_layers = g_slist_prepend(map->object_layers, layer);
		} else {
			fprintf(stderr, "Error: found invalid layer node \"%s\"\n", layer_node->name);
			continue;
		}

		map->layers = g_slist_prepend(map->layers, layer);
	}

	g_slist_free(layers);

	// If any objects have a tile gid, cache their image
	layer_item = map->layers;
	while (layer_item) {
		ALLEGRO_MAP_LAYER *layer = (ALLEGRO_MAP_LAYER*)layer_item->data;
		layer_item = g_slist_next(layer_item);
		if (layer->type != OBJECT_LAYER) {
			continue;
		}

		GSList *objects = layer->objects;
		while (objects) {
			ALLEGRO_MAP_OBJECT *object = (ALLEGRO_MAP_OBJECT*)objects->data;
			objects = g_slist_next(objects);
			if (!object->gid) {
				continue;
			}

			object->bitmap = al_get_tile_for_id(map, object->gid)->bitmap;
			object->width = map->tile_width;
			object->height = map->tile_height;
		}
	}

	xmlFreeDoc(doc);
	al_change_directory(cwd);
	al_free(cwd);

	return map;
}