152 lines
4.3 KiB
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) {}
|