kettek2/wiki/games/newsboy/Newsboy_0x00/engine/Map.c

675 lines
21 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#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;
}