void aa_editkey(struct aa_edit *e, int c) { if (c < 127 && (isgraph(c) || c == ' ')) { if (e->clearafterpress) e->data[0] = 0, e->cursor = 0; e->clearafterpress = 0; aa_insert(e, c); aa_editdisplay(e); } else if (c == AA_BACKSPACE) { e->clearafterpress = 0; aa_delete(e); aa_editdisplay(e); } else if (c == AA_LEFT) { e->cursor--; e->clearafterpress = 0; if (e->cursor < 0) e->cursor = 0; aa_editdisplay(e); } else if (c == AA_RIGHT) { e->cursor++; e->clearafterpress = 0; if (e->cursor > strlen(e->data)) e->cursor = strlen(e->data); aa_editdisplay(e); } aa_flush(e->c); }
static AATREE *get_properties (xmlNode *node, TILED_MAP *map) { assert (node); xmlNode *props_node = get_first_child_for_name (node, "properties"); if (!props_node) return NULL; LIST *property_nodes = get_children_for_name (props_node, 1, "property"); if (_al_list_is_empty (property_nodes)) return NULL; AATREE *props = NULL; LIST_ITEM *property_item = _al_list_front (property_nodes); while (property_item) { xmlNode *prop_node = (xmlNode*)_al_list_item_data (property_item); char *name = get_str (prop_node, "name"); char *value = get_str (prop_node, "value"); props = aa_insert (props, (void *)name, (void *)value, charcmp); _al_list_push_back_ex (map->strings, name, dtor_string); _al_list_push_back_ex (map->strings, value, dtor_string); property_item = _al_list_next (property_nodes, property_item); } _al_list_destroy (property_nodes); return props; }
static void load_prototypes(const char *filename) { dstr line; const char *name; const char *newtext; const char *file_name; const char *line_number; dstr text; d_open_input(filename); while (d_getline(line)) { if (d_match(line, "([^:]*): ([^:]*):([^:]*):([^:]*)")) { name = d_submatch(1); newtext = d_submatch(2); file_name = d_submatch(3); line_number = d_submatch(4); d_assign(text, lookup_prototype(name)); strcat(text, "\n"); strcat(text, newtext); protos = aa_insert(protos, name, text); d_assign(text, lookup_source(name)); if (strlen(text) == 0) { strcat(text, "https://github.com/liballeg/allegro5/blob/5.1/"); strcat(text, file_name); strcat(text, "#L"); strcat(text, line_number); sources = aa_insert(sources, name, text); } } } d_close_input(); }
int main(int argc, char *argv[]) { dstr line; Aatree * root = &aa_nil; d_init(argc, argv); d_printf("# Index\n"); while ((d_getline(line))) { if (d_match(line, "^\\[([^\\]]*)")) { const char *ref = d_submatch(1); char *s = xstrdup(ref); root = aa_insert(root, s, s); } } pre_order_traversal(root, print_link); aa_destroy(root); return 0; }
TILED_MAP* tiled_load_tmx_file (const char *filename) { TILED_MAP *map; xmlDoc *doc; xmlNode *root; char *str; if (!filename) return NULL; LIBXML_TEST_VERSION doc = xmlReadFile (filename, NULL, 0); if (!doc) return NULL; ALLEGRO_PATH *mapdir = al_create_path (filename); al_set_path_filename (mapdir, NULL); if (!al_change_directory (al_path_cstr (mapdir, ALLEGRO_NATIVE_PATH_SEP))) { printf ("Failed to change directory."); } al_destroy_path (mapdir); root = xmlDocGetRootElement (doc); map = al_malloc (sizeof (TILED_MAP)); map->width = get_int (root, "width", 0); map->height = get_int (root, "height", 0); map->tile_width = get_int (root, "tilewidth", 0); map->tile_height = get_int (root, "tileheight", 0); map->strings = _al_list_create (); map->properties = get_properties (root, map); map->tiles = NULL; str = get_xml_attribute (root, "orientation"); if (!strcmp (str, "orthogonal")) map->orientation = ORIENTATION_ORTHOGONAL; else if (!strcmp (str, "isometric")) map->orientation = ORIENTATION_ISOMETRIC; else if (!strcmp (str, "staggered")) map->orientation = ORIENTATION_STAGGERED; else map->orientation = ORIENTATION_UNKNOWN; // Tilesets LIST *tileset_nodes = get_children_for_name (root, 1, "tileset"); map->tilesets = create_list (_al_list_size (tileset_nodes)); LIST_ITEM *tileset_item = _al_list_front (tileset_nodes); while (tileset_item) { xmlNode *tileset_node = _al_list_item_data (tileset_item); TILED_TILESET *tileset = al_malloc (sizeof (TILED_TILESET)); tileset->first_gid = get_int (tileset_node, "firstgid", 1); tileset->tile_width = get_int (tileset_node, "tilewidth", 0); tileset->tile_height = get_int (tileset_node, "tileheight", 0); tileset->name = get_str (tileset_node, "name"); tileset->properties = get_properties (tileset_node, map); xmlNode *image_node = get_first_child_for_name (tileset_node, "image"); tileset->image_width = get_int (image_node, "width", 0); tileset->image_height = get_int (image_node, "height", 0); tileset->image_source = get_str (image_node, "source"); tileset->bitmap = al_load_bitmap (tileset->image_source); LIST *tile_nodes = get_children_for_name (tileset_node, 1, "tile"); int tiles_per_row = tileset->image_width / tileset->tile_width; tileset->num_tiles = (tileset->image_width * tileset->image_height) / (tileset->tile_width * tileset->tile_height); TILED_TILE *tile; tileset->tiles = al_malloc (tileset->num_tiles * sizeof (TILED_TILE)); for (int i = 0; i < tileset->num_tiles; i++) { tile = &tileset->tiles[i]; tile->id = i; tile->gid = i + tileset->first_gid; tile->tileset = tileset; tile->properties = NULL; int x = (i % tiles_per_row) * tileset->tile_width; int y = (i / tiles_per_row) * tileset->tile_height; tile->bitmap = al_create_sub_bitmap(tileset->bitmap, x, y, tileset->tile_width, tileset->tile_height); map->tiles = aa_insert (map->tiles, &tile->gid, tile, intcmp); } LIST_ITEM *tile_item = _al_list_front (tile_nodes); while (tile_item) { xmlNode *tile_node = (xmlNode*)_al_list_item_data (tile_item); int id = get_int (tile_node, "id", 0); tile = &tileset->tiles[id]; tile->properties = get_properties (tile_node, map); tile_item = _al_list_next (tile_nodes, tile_item); } _al_list_destroy (tile_nodes); _al_list_push_back_ex (map->tilesets, tileset, dtor_tileset); tileset_item = _al_list_next (tileset_nodes, tileset_item); } _al_list_destroy (tileset_nodes); // Layers LIST *layer_nodes = get_children_for_name (root, 2, "layer", "objectgroup"); map->layers = create_list (_al_list_size (layer_nodes)); map->layers_fore = _al_list_create (); map->layers_back = _al_list_create (); LIST_ITEM *layer_item = _al_list_front (layer_nodes); while (layer_item) { xmlNode *layer_node = _al_list_item_data (layer_item); TILED_LAYER *layer = NULL; const char* type_str = (const char *)layer_node->name; if (!strcmp (type_str, "layer")) { layer = al_malloc (sizeof (TILED_LAYER_TILE)); layer->type = LAYER_TYPE_TILE; } else if (!strcmp (type_str, "objectgroup")) { layer = al_malloc (sizeof (TILED_LAYER_OBJECT)); layer->type = LAYER_TYPE_OBJECT; } layer->name = get_str (layer_node, "name"); layer->width = get_int (layer_node, "width", 0); layer->height = get_int (layer_node, "height", 0); layer->opacity = get_float (layer_node, "opacity", 1.0); layer->map = map; layer->properties = get_properties (layer_node, map); char *order = aa_search (layer->properties, "order", charcmp); if (layer->type == LAYER_TYPE_TILE) { TILED_LAYER_TILE *tile_layer = (TILED_LAYER_TILE *)layer; tile_layer->tiles = al_malloc (layer->height * sizeof (TILED_TILE*)); xmlNode *data_node = get_first_child_for_name (layer_node, "data"); LIST *tile_nodes = get_children_for_name (data_node, 1, "tile"); LIST_ITEM *tile_item = _al_list_front (tile_nodes); for (int j = 0; j < layer->height; j++) { tile_layer->tiles[j] = al_malloc (layer->width * sizeof (TILED_TILE*)); for (int k = 0; k < layer->width; k++) { xmlNode *tile_node = (xmlNode*)_al_list_item_data (tile_item); int id = get_int (tile_node, "gid", 0); if (id == 0) { tile_layer->tiles[j][k] = NULL; } else { TILED_TILE *tile = aa_search (map->tiles, &id, intcmp); tile_layer->tiles[j][k] = tile; } tile_item = _al_list_next (tile_nodes, tile_item); } } _al_list_destroy (tile_nodes); } else if (layer->type == LAYER_TYPE_OBJECT) { TILED_LAYER_OBJECT *object_layer = (TILED_LAYER_OBJECT *)layer; object_layer->objects = _al_list_create (); LIST *object_nodes = get_children_for_name (layer_node, 1, "object"); LIST_ITEM *object_item = _al_list_front (object_nodes); while (object_item) { xmlNode *object_node = (xmlNode*)_al_list_item_data (object_item); TILED_OBJECT *cobj = NULL; int width = get_int (object_node, "width", 0); int gid = get_int (object_node, "gid", 0); int px = get_int (object_node, "x", 0); int py = get_int (object_node, "y", 0); if (width > 0) { TILED_OBJECT_RECT *obj = al_malloc (sizeof (TILED_OBJECT_RECT)); obj->object.type = OBJECT_TYPE_RECT; obj->width = width; obj->height = get_int (object_node, "height", 0); cobj = (TILED_OBJECT *) obj; } else if (gid > 0) { TILED_OBJECT_TILE *obj = al_malloc (sizeof (TILED_OBJECT_TILE)); obj->object.type = OBJECT_TYPE_TILE; obj->tile = aa_search (map->tiles, &gid, intcmp); cobj = (TILED_OBJECT *) obj; } else { TILED_OBJECT_GEOM *obj = al_malloc (sizeof (TILED_OBJECT_GEOM)); obj->object.type = OBJECT_TYPE_GEOM; xmlNode *poly_node = get_first_child_for_name (object_node, "polyline"); if (poly_node) { obj->points = get_float_points (poly_node, "points", &obj->num_points); offset_points (px, py, obj->points, obj->num_points); } else { poly_node = get_first_child_for_name (object_node, "polygon"); if (poly_node) obj->points = get_float_points (poly_node, "points", &obj->num_points); offset_points (px, py, obj->points, obj->num_points); } cobj = (TILED_OBJECT *) obj; } cobj->x = px; cobj->y = py; cobj->name = get_str (object_node, "name"); cobj->type_str = get_str (object_node, "type"); cobj->properties = get_properties (object_node, map); _al_list_push_back_ex (object_layer->objects, cobj, dtor_object); object_item = _al_list_next (object_nodes, object_item); } _al_list_destroy (object_nodes); } layer_item = _al_list_next (layer_nodes, layer_item); _al_list_push_back_ex (map->layers, layer, dtor_layer); if (order && !strcmp (order, "fore")) _al_list_push_back (map->layers_fore, layer); else _al_list_push_back (map->layers_back, layer); } _al_list_destroy (layer_nodes); xmlFreeDoc (doc); xmlCleanupParser (); ALLEGRO_PATH *respath = al_get_standard_path (ALLEGRO_RESOURCES_PATH); al_change_directory (al_path_cstr (respath, ALLEGRO_NATIVE_PATH_SEP)); al_destroy_path (respath); return map; }