fencer/src/tilemap.c

152 lines
4.3 KiB
C

#include "tilemap.h"
#include "debug.h"
#include "rigidbody.h"
#include "tileset.h"
#include "assets.h"
#include "camera.h"
#include "level.h"
#include "render.h"
#include "transform.h"
#include <SDL2/SDL_image.h>
#include <cjson/cJSON.h>
struct TileInstance {
Transform transform;
TileDef* tiledef;
Tilemap* parent_map;
};
struct Tilemap {
Transform transform;
Tileset* set;
TileInstance* map;
size_t map_num;
IVector map_size;
RigidBody* rigidbody;
};
Tilemap* tilemap_from_autolayer(cJSON* json) {
cJSON* const tileset = cJSON_GetObjectItem(json, "__tilesetDefUid");
ASSERT_RETURN(tileset != NULL && cJSON_IsNumber(tileset), NULL, "Could not find __tilesetDefUid while loading tilemap");
cJSON* const tiles = cJSON_GetObjectItem(json, "autoLayerTiles");
ASSERT_RETURN(tiles != NULL && cJSON_IsArray(tiles), NULL, "Could not find autoLayerTiles while loading tilemap");
cJSON* const wid = cJSON_GetObjectItem(json, "__cWid");
ASSERT_RETURN(wid != NULL && cJSON_IsNumber(wid), NULL, "Could not find __cWid while loading tilemap");
cJSON* const hei = cJSON_GetObjectItem(json, "__cHei");
ASSERT_RETURN(hei != NULL && cJSON_IsNumber(hei), NULL, "Could not find __cHei while loading tilemap");
cJSON* const grid = cJSON_GetObjectItem(json, "__gridSize");
ASSERT_RETURN(grid != NULL && cJSON_IsNumber(grid), NULL, "Could not find __gridSize while loading tilemap");
// the minimum requirements for a valid tilemap are met
// allocate a tilemap and load the tileset
Tilemap* self = malloc(sizeof(Tilemap));
self->transform = IdentityTransform;
self->set = tileset_load(tileset->valueint);
self->map_size = (IVector) {
.x = wid->valueint,
.y = hei->valueint
};
self->map_num = json_array_len(tiles);
self->map = malloc(self->map_num * sizeof(TileInstance));
if(self->map == NULL) {
tileset_destroy(self->set);
free(self);
RETURN_ERROR(NULL, "Failed to allocate map memory");
}
self->rigidbody = rigidbody_make(Tilemap_as_Transformable(self));
const double px_to_ws = 1.0 / grid->valuedouble;
cJSON* tile; TileInstance* writer = self->map;
cJSON_ArrayForEach(tile, tiles) {
cJSON* t = cJSON_GetObjectItem(tile, "t");
writer->tiledef = tileset_get_tiledef(self->set, t->valueint);
writer->transform = IdentityTransform;
cJSON* px = cJSON_GetObjectItem(tile, "px");
writer->transform.position = vmulff(json_array_to_vector(px), px_to_ws);
writer->parent_map = self;
++writer;
}
return self;
}
void tilemap_destroy(Tilemap* self) {
free(self->map);
rigidbody_destroy(self->rigidbody);
free(self);
}
void tilemap_draw(Tilemap* self, Transform transform) {
Transform tiletrans = transform_apply(transform, self->transform);
TileInstance* tile;
for(int i = 0; i < self->map_num; ++i) {
tile = self->map + i;
tiletrans = transform_apply(self->transform, tile->transform);
// shape_draw(tiledef_get_shape(tile->tiledef), tiletrans);
}
for(int i = 0; i < self->map_num; ++i) {
tile = self->map + i;
tiletrans = transform_apply(self->transform, tile->transform);
Sprite* sprite = tiledef_get_sprite(tile->tiledef);
if(sprite != NULL) {
sprite_draw(sprite, tiletrans);
}
}
}
size_t tilemap_get_tile_count(Tilemap* self) {
return self->map_num;
}
TileInstance* tilemap_get_tile(Tilemap* self, size_t at) {
return &self->map[at];
}
Transform* tilemap_get_transform(Tilemap* self ) {
return &self->transform;
}
RigidBody* tile_instance_get_rigidbody(TileInstance* self) {
return self->parent_map->rigidbody;
}
Transform* tile_instance_get_transform(TileInstance* self) {
return &self->transform;
}
Shape* tile_instance_get_shape(TileInstance* self) {
return tiledef_get_shape(self->tiledef);
}
void tile_instance_on_collision(TileInstance* self, Collision collision) {}
Vector* tile_instance_get_position(TileInstance* self) {
return &self->transform.position;
}
Vector* tile_instance_get_scale(TileInstance* self) {
return &self->transform.scale;
}
float* tile_instance_get_rotation(TileInstance* self) {
return &self->transform.rotation;
}
void tile_instance_solve_contacts(TileInstance* self, List* contacts) {}