#include #include #include #include "Map.h" #include "report.h" #include "fifo.h" #include "string.h" int initMapCells(struct MapData *map, int width, int height) { if (map == NULL) return 1; map->width = width; map->height = height; map->cells = malloc(map->width * sizeof(struct MapCell)); if (map->cells == NULL) { report(ERROR, "initMapData", "could not allocate memory for cells"); return 1; } int i, j; for (i = 0; i < map->width; i++) { map->cells[i] = malloc(sizeof *map->cells[i] * map->height); if (map->cells[i] == NULL) { report(ERROR, "initMapData", "could not allocate memory for cells[%d]", i); for(j = 0; j < i; j++) { free(map->cells[j]); } free(map->cells); return 2; } // assign Floor pointers to NULL for(j = 0;j < map->height;j++) { map->cells[i][j].flags = 0; map->cells[i][j].decor_count = 0; map->cells[i][j].decor = NULL; } } return 0; } int freeMapCells(struct MapData *map) { if (map == NULL) return 1; int x; for(x = 0; x < map->width; x++) { int y; for (y = 0; y < map->height; y++) { if (map->cells[x][y].decor != NULL) { int i; for (i = 0; i < map->cells[x][y].decor_count; i++) { freeDecorMapData(map->cells[x][y].decor[i]); } free(map->cells[x][y].decor); map->cells[x][y].decor_count = 0; } } free(map->cells[x]); } if (map->cells != NULL) { free(map->cells); } return 0; } struct MapData *newMapData() { struct MapData *map = malloc(sizeof(struct MapData)); if (map == NULL) return NULL; map->filename = malloc(6); memcpy(map->filename, "undef", 6); map->name = malloc(6); memcpy(map->name, "undef", 6); map->session = malloc(6); memcpy(map->session, "undef", 6); map->location = CYBERSPACE; map->cells = NULL; map->entity_count = 0; map->entities = newVoidMan(8); map->trigger_count = 0; map->triggers = newVoidMan(8); map->event_count = 0; map->events = newVoidMan(8); map->path_count = 0; map->paths = NULL; map->height = 0; map->width = 0; initPlayer(map); return map; } int freeMapData(struct MapData *map) { if (map == NULL) return 1; if (map->filename != NULL) free(map->filename); if (map->name != NULL) free(map->name); if (map->session != NULL) free(map->session); if (map->cells != NULL) freeMapCells(map); freePlayer(map); if (map->entities != NULL) freeMapEntities(map); if (map->triggers != NULL) freeMapTriggers(map); if (map->events != NULL) freeMapEvents(map); if (map->paths != NULL) freeMapPaths(map); free(map); return 0; } int freeMapEntities(struct MapData *map) { if (map == NULL) return 1; if (map->entities == NULL) return 2; struct EntityMapData *entity; while ((entity = iterObject(map->entities)) != NULL) { free(entity->name); free(entity->set); free(entity->face); } freeVoidMan(map->entities); map->entity_count = 0; return 0; } int freeMapTriggers(struct MapData *map) { if (map == NULL) return 1; if (map->triggers == NULL) return 2; struct TriggerMapData *trigger; while ((trigger = iterObject(map->triggers)) != NULL) { int i; for (i = 0; i < trigger->event_count; i++) { free(trigger->events[i]); } free(trigger->events); } freeVoidMan(map->triggers); map->trigger_count = 0; return 0; } int freeMapPaths(struct MapData *map) { if (map == NULL) return 1; if (map->paths == NULL) return 2; int i; for (i = 0; i < map->path_count; i++) { // freepaths } map->path_count = 0; return 0; } int freeMapEvents(struct MapData *map) { if (map == NULL) return 1; if (map->events == NULL) return 2; struct EventMapData *event; while ((event = iterObject(map->events)) != NULL) { int i; for (i = 0; i < event->param_count; i++) { free(event->params[i]); } free(event->params); free(event->param_type); if (event->name != NULL) free(event->name); } freeVoidMan(map->events); map->event_count = 0; return 0; } int saveMapData(struct MapData *map) { if (map == NULL) return 1; if (map->filename == NULL) return 2; if (map->cells == NULL) return 3; if (map->name == NULL) return 4; if (map->session == NULL) return 4; FILE *output = fopen(map->filename, "wb"); if (output == NULL) { report(ERROR, "saveMapData", "cannot open \"%s\" for writing", map->filename); return 5; } // write magic number char magic[4]; magic[0] = 'N'; magic[1] = 'b'; magic[2] = 'M'; magic[3] = 1; writeData(output, T_MAGIC, (void*)&magic); // write map information writeData(output, T_STRING, (void*)&map->name); writeData(output, T_STRING, (void*)&map->session); writeData(output, T_INT, (void*)&map->location); writeData(output, T_INT, (void*)&map->width); writeData(output, T_INT, (void*)&map->height); // write cell data int x, y, i; for (x = 0; x < map->width; x++) { for(y = 0; y < map->height;y++) { writeData(output, T_INT, (void*)&map->cells[x][y].flags); // give th' D writeData(output, T_INT, (void*)&map->cells[x][y].decor_count); if (map->cells[x][y].decor_count > 0) { for (i = 0; i < map->cells[x][y].decor_count; i++) { // write x writeData(output, T_INT, (void*)&map->cells[x][y].decor[i]->x); // write y writeData(output, T_INT, (void*)&map->cells[x][y].decor[i]->y); // write animated boolean writeData(output, T_INT, (void*)&map->cells[x][y].decor[i]->animated); // write frame index writeData(output, T_INT, (void*)&map->cells[x][y].decor[i]->frame); // write animation name writeData(output, T_STRING, (void*)&map->cells[x][y].decor[i]->anim); // write set name writeData(output, T_STRING, (void*)&map->cells[x][y].decor[i]->set); // write face name writeData(output, T_STRING, (void*)&map->cells[x][y].decor[i]->face); } } } } // write player data writeData(output, T_INT, (void*)&map->player_data.x); writeData(output, T_INT, (void*)&map->player_data.y); writeData(output, T_INT, (void*)&map->player_data.frame); writeData(output, T_STRING, (void*)&map->player_data.anim); writeData(output, T_STRING, (void*)&map->player_data.set); writeData(output, T_STRING, (void*)&map->player_data.face); // write entities writeData(output, T_INT, (void*)&map->entities->count); struct EntityMapData *entity; while ((entity = iterObject(map->entities)) != NULL) { writeData(output, T_STRING, (void*)&entity->name); writeData(output, T_INT, (void*)&entity->x); writeData(output, T_INT, (void*)&entity->y); writeData(output, T_STRING, (void*)&entity->set); writeData(output, T_STRING, (void*)&entity->face); writeData(output, T_INT, (void*)&entity->frame); } // write triggers writeData(output, T_INT, (void*)&map->triggers->count); struct TriggerMapData *trigger; i = 0; while ((trigger = iterObject(map->triggers)) != NULL) { writeData(output, T_INT, (void*)&trigger->x); writeData(output, T_INT, (void*)&trigger->y); writeData(output, T_INT, (void*)&trigger->w); writeData(output, T_INT, (void*)&trigger->h); writeData(output, T_INT, (void*)&trigger->type); writeData(output, T_INT, (void*)&trigger->activator); writeData(output, T_INT, (void*)&trigger->behavior); writeData(output, T_INT, (void*)&trigger->iter); writeData(output, T_INT, (void*)&trigger->time); writeData(output, T_INT, (void*)&trigger->event_count); int j; for (j = 0; j < trigger->event_count; j++) { writeData(output, T_STRING, (void*)&trigger->events[j]); } } // write events writeData(output, T_INT, (void*)&map->events->count); struct EventMapData *event; while ((event = iterObject(map->events)) != NULL) { writeData(output, T_STRING, (void*)&event->name); writeData(output, T_INT, (void*)&event->x); writeData(output, T_INT, (void*)&event->y); writeData(output, T_INT, (void*)&event->w); writeData(output, T_INT, (void*)&event->h); writeData(output, T_INT, (void*)&event->type); writeData(output, T_INT, (void*)&event->param_count); int j; for (j = 0; j < event->param_count; j++) { writeData(output, T_INT, (void*)&event->param_type[j]); // FIXME char ch; int in; float fl; char *string; switch(event->param_type[j]) { case T_CHAR: ch = *(char*)event->params[j]; writeData(output, T_CHAR, (void*)&ch); break; case T_INT: in = *(int*)event->params[j]; writeData(output, T_INT, (void*)&in); break; case T_FLOAT: fl = *(float*)event->params[j]; writeData(output, T_FLOAT, (void*)&fl); break; case T_STRING: string = (char*)event->params[j]; writeData(output, T_STRING, (void*)&string); break; default: // unknown, just write our param # writeData(output, T_INT, (void*)&j); break; } } } // write nodes writeData(output, T_INT, (void*)&map->path_count); if (map->path_count > 0) { } fclose(output); return 0; } int loadMapData(struct MapData *map, const char *filename) { if (map == NULL) return 1; if (filename == NULL) return 2; map->filename = copyString(map->filename, filename); // free cells if they exist if (map->cells != NULL) freeMapCells(map); if (map->entities != NULL) freeMapEntities(map); if (map->triggers != NULL) freeMapTriggers(map); if (map->paths != NULL) freeMapPaths(map); if (map->events != NULL) freeMapEvents(map); FILE *input = fopen(filename, "rb"); if (input == NULL) { report(ERROR, "loadMapData", "cannot open \"%s\" for reading", filename); return 3; } void *val = malloc(4); // read in magic number readData(input, T_MAGIC, val); // check magic number if (((char *)val)[0] != 'N' || ((char *)val)[1] != 'b' || ((char *)val)[2] != 'M' || ((char *)val)[3] != 1) { report(ERROR, "loadMapData", "Magic number mismatch, expected %d, got %d\n", ((char *)val)[3], 1); return 4; } // read in map name map->name = readData(input, T_STRING, map->name); map->session = readData(input, T_STRING, map->session); // get width x height readData(input, T_INT, &map->location); readData(input, T_INT, &map->width); readData(input, T_INT, &map->height); // initialize cells initMapCells(map, map->width, map->height); // get cell data int x, y, d, i; for(x = 0; x < map->width; x++) { for(y = 0; y < map->height; y++) { readData(input, T_INT, val); map->cells[x][y].flags = *(int*)val; // get th' D readData(input, T_INT, val); d = *(int*)val; map->cells[x][y].decor_count = d; if (d > 0) { map->cells[x][y].decor = malloc(sizeof(struct DecorMapData*)*d); for (i = 0; i < d; i++) { map->cells[x][y].decor[i] = newDecorMapData(); // read in x readData(input, T_INT, &map->cells[x][y].decor[i]->x); // read in y readData(input, T_INT, &map->cells[x][y].decor[i]->y); // read in animated boolean readData(input, T_INT, &map->cells[x][y].decor[i]->animated); // read in frame index readData(input, T_INT, &map->cells[x][y].decor[i]->frame); // read in animation name map->cells[x][y].decor[i]->anim = readData(input, T_STRING, map->cells[x][y].decor[i]->anim); // read in set name map->cells[x][y].decor[i]->set = readData(input, T_STRING, map->cells[x][y].decor[i]->set); // read in face name map->cells[x][y].decor[i]->face = readData(input, T_STRING, map->cells[x][y].decor[i]->face); } } } } // read player data readData(input, T_INT, &map->player_data.x); readData(input, T_INT, &map->player_data.y); readData(input, T_INT, &map->player_data.frame); map->player_data.anim = readData(input, T_STRING, map->player_data.anim); map->player_data.set = readData(input, T_STRING, map->player_data.set); map->player_data.face = readData(input, T_STRING, map->player_data.face); // read entities readData(input, T_INT, &map->entity_count); map->entities = newVoidMan(8); for (i = 0; i < map->entity_count; i++) { struct EntityMapData *entity = newEntityMapData(); entity->name = malloc(1); entity->name = readData(input, T_STRING, entity->name); readData(input, T_INT, &entity->x); entity->w = 32; readData(input, T_INT, &entity->y); entity->h = 32; entity->set = malloc(1); entity->set = readData(input, T_STRING, entity->set); entity->face = malloc(1); entity->face = readData(input, T_STRING, entity->face); readData(input, T_INT, &entity->frame); addObject(map->entities, entity); } // read triggers readData(input, T_INT, &map->trigger_count); map->triggers = newVoidMan(8); for (i = 0; i < map->trigger_count; i++) { struct TriggerMapData *trigger = newTriggerMapData(); readData(input, T_INT, &(trigger->x)); readData(input, T_INT, &(trigger->y)); readData(input, T_INT, &(trigger->w)); if (trigger->w < 32) trigger->w = 32; readData(input, T_INT, &(trigger->h)); if (trigger->h < 32) trigger->h = 32; readData(input, T_INT, &(trigger->type)); readData(input, T_INT, &(trigger->activator)); readData(input, T_INT, &(trigger->behavior)); readData(input, T_INT, &(trigger->iter)); readData(input, T_INT, &(trigger->time)); readData(input, T_INT, &(trigger->event_count)); int j; trigger->events = malloc(trigger->event_count*sizeof(char*)); for (j = 0; j < trigger->event_count; j++) { trigger->events[j] = malloc(1); trigger->events[j] = readData(input, T_STRING, trigger->events[j]); } addObject(map->triggers, trigger); } // read events readData(input, T_INT, &map->event_count); map->events = newVoidMan(8); for (i = 0; i < map->event_count; i++) { struct EventMapData *event = newEventMapData(); event->name = readData(input, T_STRING, event->name); readData(input, T_INT, &(event->x)); readData(input, T_INT, &(event->y)); readData(input, T_INT, &(event->w)); if (event->w < 32) event->w = 32; readData(input, T_INT, &(event->h)); if (event->h < 32) event->h = 32; readData(input, T_INT, &(event->type)); int j; readData(input, T_INT, &(event->param_count)); event->param_type = malloc(event->param_count*sizeof(int)); event->params = malloc(event->param_count*sizeof(void*)); //printf("reading in %d\n", event->param_count); for (j = 0; j < event->param_count; j++) { readData(input, T_INT, &(event->param_type[j])); // we're assuming saveMapData wrote data properly here switch(event->param_type[j]) { case T_CHAR: event->params[j] = malloc(sizeof(char)); readData(input, T_CHAR, val); *(char*)event->params[j] = ((char*)val)[0]; break; case T_INT: event->params[j] = (int*)malloc(sizeof(int)); readData(input, T_INT, val); *(int*)event->params[j] = *(int*)val; break; case T_FLOAT: event->params[j] = (float*)malloc(sizeof(float)); readData(input, T_FLOAT, val); *(float*)event->params[j] = *(float*)val; break; case T_STRING: event->params[j] = (char*)malloc(1); event->params[j] = (char*)readData(input, T_STRING, event->params[j]); break; default: event->params[j] = (int*)malloc(sizeof(int)); readData(input, T_INT, val); *(int*)event->params[j] = *(int*)val; break; } } addObject(map->events, event); } // read nodes readData(input, T_INT, &map->path_count); free(val); fclose(input); return 0; } int pushDecorMapData(struct MapCell *cell, struct DecorMapData *decor) { if (cell == NULL) return 1; if (decor == NULL) return 2; cell->decor_count++; cell->decor = realloc(cell->decor, cell->decor_count*sizeof(struct DecorMapData*)); cell->decor[cell->decor_count-1] = decor; return 0; } int popDecorMapData(struct MapCell *cell) { if (cell == NULL) return 1; if (cell->decor_count > 0) { cell->decor_count--; freeDecorMapData(cell->decor[cell->decor_count]); cell->decor = realloc(cell->decor, cell->decor_count*sizeof(struct DecorMapData*)); return 0; } else { return 2; } } struct EntityMapData *newEntityMapData() { struct EntityMapData *entity = malloc(sizeof(struct EntityMapData)); entity->x = 0; entity->y = 0; entity->w = 32; entity->h = 32; entity->radius = 10.0f; entity->frame = 0; entity->name = NULL; entity->set = NULL; entity->face = NULL; entity->sprite = NULL; return entity; } int freeEntityMapData(struct EntityMapData *entity) { if (entity == NULL) return 1; if (entity->name != NULL) free(entity->name); if (entity->set != NULL) free(entity->set); if (entity->face != NULL) free(entity->face); entity->sprite = NULL; //free(entity); freed by vman //entity = NULL; return 0; } int pushEntityMapData(struct MapData *map, struct EntityMapData *entity) { addObject(map->entities, entity); return 0; } int delEntityMapData(struct MapData *map, int id) { struct EntityMapData *entity = map->entities->object[id]; if (entity == NULL) return 1; freeEntityMapData(entity); delObject(map->entities, id); return 0; } struct DecorMapData *newDecorMapData() { struct DecorMapData *decor = malloc(sizeof(struct DecorMapData)); decor->x = 0; decor->y = 0; decor->animated = 0; decor->frame = 0; decor->anim = NULL; decor->set = NULL; decor->face = NULL; decor->sprite = NULL; return decor; } //int initDecorMapData(int x, int y, int animated, int frame, const char *anim, const char *set, const char *face, int freeDecorMapData(struct DecorMapData *decor) { if (decor == NULL) return 1; if (decor->anim != NULL) free(decor->anim); if (decor->set != NULL) free(decor->set); if (decor->face != NULL) free(decor->face); decor->sprite = NULL; free(decor); decor = NULL; return 0; } struct TriggerMapData *newTriggerMapData() { struct TriggerMapData *trigger = malloc(sizeof(struct TriggerMapData)); trigger->x = 0; trigger->y = 0; trigger->w = 0; trigger->h = 0; trigger->time = 0; trigger->iter = 0; trigger->activator = 0; trigger->behavior = 0; trigger->type = 0; trigger->event_count = 0; trigger->events = NULL; return trigger; } struct TriggerMapData *freeTriggerMapData(struct TriggerMapData *trigger) { int i; for (i = 0; i < trigger->event_count; i++) { free(trigger->events[i]); } free(trigger->events); free(trigger); return NULL; } int pushTriggerMapData(struct MapData *map, struct TriggerMapData *trigger) { addObject(map->triggers, trigger); return 0; } int delTriggerMapData(struct MapData *map, int id) { struct TriggerMapData *trigger = map->triggers->object[id]; if (trigger == NULL) return 1; int i; for (i = 0; i < trigger->event_count; i++) { free(trigger->events[i]); } free(trigger->events); delObject(map->triggers, id); return 0; } struct EventMapData *newEventMapData() { struct EventMapData *event = malloc(sizeof(struct EventMapData)); event->x = 0; event->y = 0; event->w = 0; event->h = 0; event->name = NULL; event->type = 0; event->param_count = 0; event->params = NULL; event->param_type = NULL; return event; } struct EventMapData *freeEventMapData(struct EventMapData *event) { int i; for (i = 0; i < event->param_count; i++) { free(event->params[i]); } free(event->params); free(event->param_type); free(event); return NULL; } int pushEventMapData(struct MapData *map, struct EventMapData *event) { addObject(map->events, event); return 0; } int delEventMapData(struct MapData *map, int id) { struct EventMapData *event = map->events->object[id]; if (event == NULL) return 1; int i; for (i = 0; i < event->param_count; i++) { free(event->params[i]); } free(event->params); free(event->param_type); delObject(map->events, id); return 0; } int setCellFlags(struct MapData *map, int x, int y, int flags) { if (x >= 0 && x < map->width && y >= 0 && y < map->height) { map->cells[x][y].flags = flags; return 0; } return 1; } int setPlayer(struct MapData *map, int x, int y, const char *anim, const char *set, const char *face, int frame) { if (map == NULL) return 1; map->player_data.x = x; map->player_data.y = y; map->player_data.anim = copyString(map->player_data.anim, anim); map->player_data.set = copyString(map->player_data.set, set); map->player_data.face = copyString(map->player_data.face, face); map->player_data.frame = frame; return 0; } int initPlayer(struct MapData *map) { map->player_data.anim = malloc(1); map->player_data.anim[0] = '\0'; map->player_data.set = malloc(1); map->player_data.set[0] = '\0'; map->player_data.face = malloc(1); map->player_data.face[0] = '\0'; map->player_data.x = 0; map->player_data.y = 0; map->player_data.frame = 0; return 0; } int freePlayer(struct MapData *map) { if (map == NULL) return 1; if (map->player_data.anim != NULL) free(map->player_data.anim); if (map->player_data.face != NULL) free(map->player_data.face); if (map->player_data.set != NULL) free(map->player_data.set); return 0; }