2017-12-01 16:03:19 +01:00
|
|
|
#include "map.h"
|
2017-12-02 23:32:40 +01:00
|
|
|
#include "map_lua.h"
|
2017-12-01 16:03:19 +01:00
|
|
|
#include "util.h"
|
|
|
|
|
|
|
|
static
|
|
|
|
Room* create_room()
|
|
|
|
{
|
|
|
|
int i, j;
|
|
|
|
Room *room;
|
|
|
|
|
|
|
|
room = ec_malloc(sizeof(Room));
|
2017-12-05 08:13:28 +01:00
|
|
|
for (i=0; i < MAP_ROOM_WIDTH; ++i) {
|
|
|
|
for (j=0; j < MAP_ROOM_HEIGHT; ++j) {
|
2017-12-01 16:03:19 +01:00
|
|
|
room->tiles[i][j] = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return room;
|
|
|
|
}
|
|
|
|
|
2017-12-02 23:32:40 +01:00
|
|
|
Map* map_create()
|
2017-12-01 16:03:19 +01:00
|
|
|
{
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
Map *map = ec_malloc(sizeof(Map));
|
2017-12-02 16:24:31 +01:00
|
|
|
map->textures = linkedlist_create();
|
2017-12-01 16:03:19 +01:00
|
|
|
map->currentRoom = (Position) { 0, 0 };
|
|
|
|
map->level = 1;
|
|
|
|
|
2017-12-05 08:13:28 +01:00
|
|
|
for (i=0; i < MAP_H_ROOM_COUNT; ++i) {
|
|
|
|
for (j=0; j < MAP_V_ROOM_COUNT; ++j) {
|
2017-12-01 16:03:19 +01:00
|
|
|
map->rooms[i][j] = create_room();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return map;
|
|
|
|
}
|
|
|
|
|
2017-12-05 08:13:28 +01:00
|
|
|
void map_add_tile(Map *map, Position *tile_pos, MapTile *tile)
|
2017-12-02 23:32:40 +01:00
|
|
|
{
|
2017-12-05 08:13:28 +01:00
|
|
|
const Position *cr = &map->currentRoom;
|
|
|
|
MapTile **oldTile = &map->rooms[cr->x][cr->y]->tiles[tile_pos->x][tile_pos->y];
|
2017-12-02 23:32:40 +01:00
|
|
|
if (*oldTile != NULL) {
|
|
|
|
free(*oldTile);
|
|
|
|
*oldTile = NULL;
|
|
|
|
}
|
|
|
|
*oldTile = tile;
|
|
|
|
}
|
|
|
|
|
|
|
|
int map_add_texture(Map *map, const char *path, SDL_Renderer *renderer)
|
|
|
|
{
|
|
|
|
Texture *t = texture_create(path, renderer);
|
|
|
|
linkedlist_append(&map->textures, t, sizeof(*t));
|
2017-12-07 23:58:29 +01:00
|
|
|
|
|
|
|
/* Freeing the texture preserves the underlying SDL_Texture* which
|
|
|
|
* isn't duplicated when it's being added to the list.
|
|
|
|
* texture_destroy() would destroy that too and break rendering.
|
|
|
|
* Unstable solution. Might cause problems if Texture is ever extended
|
|
|
|
* with more data.
|
|
|
|
*/
|
|
|
|
free(t);
|
2017-12-02 23:32:40 +01:00
|
|
|
return linkedlist_size(map->textures) - 1;
|
|
|
|
}
|
|
|
|
|
2017-12-02 16:24:31 +01:00
|
|
|
static
|
|
|
|
void map_tile_render(Map *map, MapTile *tile, Position *pos, Camera *cam)
|
|
|
|
{
|
|
|
|
if (tile == NULL)
|
|
|
|
return;
|
2017-12-02 23:32:40 +01:00
|
|
|
|
|
|
|
Position camPos = camera_to_camera_position(cam, pos);
|
|
|
|
SDL_Rect draw_box = (SDL_Rect) {
|
|
|
|
camPos.x,
|
|
|
|
camPos.y,
|
2017-12-03 11:09:57 +01:00
|
|
|
TILE_DIMENSION,
|
|
|
|
TILE_DIMENSION
|
2017-12-02 23:32:40 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
Texture *texture = linkedlist_get(&map->textures, tile->textureIndex);
|
|
|
|
|
|
|
|
SDL_RenderCopy(cam->renderer,
|
|
|
|
texture->texture,
|
|
|
|
&tile->clip,
|
|
|
|
&draw_box
|
|
|
|
);
|
|
|
|
|
2017-12-02 16:24:31 +01:00
|
|
|
}
|
|
|
|
|
2017-12-01 16:03:19 +01:00
|
|
|
void map_render(Map *map, Camera *cam)
|
|
|
|
{
|
|
|
|
int i, j;
|
|
|
|
Room *room;
|
|
|
|
Position roomPos = { map->currentRoom.x, map->currentRoom.y };
|
|
|
|
Position roomCords = {
|
2017-12-03 11:09:57 +01:00
|
|
|
roomPos.x * MAP_ROOM_WIDTH * TILE_DIMENSION,
|
|
|
|
roomPos.y * MAP_ROOM_HEIGHT * TILE_DIMENSION
|
2017-12-01 16:03:19 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
room = map->rooms[roomPos.x][roomPos.y];
|
2017-12-05 08:13:28 +01:00
|
|
|
for (i=0; i < MAP_ROOM_WIDTH; ++i) {
|
|
|
|
for (j=0; j < MAP_ROOM_HEIGHT; ++j) {
|
2017-12-02 23:32:40 +01:00
|
|
|
Position tilePos = (Position) {
|
2017-12-05 08:13:28 +01:00
|
|
|
roomCords.x + i*TILE_DIMENSION,
|
|
|
|
roomCords.y + j*TILE_DIMENSION
|
2017-12-02 23:32:40 +01:00
|
|
|
};
|
|
|
|
map_tile_render(map, room->tiles[i][j], &tilePos, cam);
|
2017-12-01 16:03:19 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-03 11:09:57 +01:00
|
|
|
void map_set_current_room(Map *map, Position *pos)
|
|
|
|
{
|
|
|
|
unsigned int room_width, room_height;
|
|
|
|
|
|
|
|
room_width = MAP_ROOM_WIDTH * TILE_DIMENSION;
|
|
|
|
room_height = MAP_ROOM_HEIGHT * TILE_DIMENSION;
|
|
|
|
|
|
|
|
if (pos->x <= 0) {
|
|
|
|
map->currentRoom.x = 0;
|
|
|
|
} else {
|
|
|
|
unsigned int room_cord_x = pos->x - (pos->x % room_width);
|
|
|
|
map->currentRoom.x = room_cord_x / room_width;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pos->y <= 0) {
|
|
|
|
map->currentRoom.y = 0;
|
|
|
|
} else {
|
|
|
|
unsigned int room_cord_y = pos->y - (pos->y % room_height);
|
|
|
|
map->currentRoom.y = room_cord_y / room_height;
|
|
|
|
}
|
2017-12-05 08:13:28 +01:00
|
|
|
|
|
|
|
if (map->currentRoom.x >= MAP_H_ROOM_COUNT)
|
|
|
|
map->currentRoom.x = MAP_H_ROOM_COUNT - 1;
|
|
|
|
if (map->currentRoom.y >= MAP_V_ROOM_COUNT)
|
|
|
|
map->currentRoom.y = MAP_V_ROOM_COUNT - 1;
|
2017-12-03 11:09:57 +01:00
|
|
|
}
|
|
|
|
|
2017-12-01 16:03:19 +01:00
|
|
|
static
|
|
|
|
void map_room_destroy(Room *room)
|
|
|
|
{
|
|
|
|
int i, j;
|
2017-12-05 08:13:28 +01:00
|
|
|
for (i=0; i < MAP_ROOM_WIDTH; ++i) {
|
|
|
|
for (j=0; j < MAP_ROOM_HEIGHT; ++j) {
|
2017-12-01 16:03:19 +01:00
|
|
|
if (room->tiles[i][j]) {
|
2017-12-02 16:24:31 +01:00
|
|
|
free(room->tiles[i][j]);
|
2017-12-01 16:03:19 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(room);
|
|
|
|
}
|
|
|
|
|
|
|
|
void map_destroy(Map *map)
|
|
|
|
{
|
|
|
|
int i, j;
|
2017-12-05 08:13:28 +01:00
|
|
|
for (i=0; i < MAP_H_ROOM_COUNT; ++i) {
|
|
|
|
for (j=0; j < MAP_V_ROOM_COUNT; ++j) {
|
2017-12-01 16:03:19 +01:00
|
|
|
map_room_destroy(map->rooms[i][j]);
|
|
|
|
}
|
|
|
|
}
|
2017-12-02 16:24:31 +01:00
|
|
|
while (map->textures != NULL) {
|
2017-12-07 23:58:29 +01:00
|
|
|
texture_destroy(linkedlist_poplast(&map->textures));
|
2017-12-02 16:24:31 +01:00
|
|
|
}
|
2017-12-01 16:03:19 +01:00
|
|
|
free(map);
|
|
|
|
}
|