diff --git a/CMakeLists.txt b/CMakeLists.txt index 91c4ad1..2106e3a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,7 @@ add_executable(breakhack src/util src/player src/map + src/map_lua src/camera ) @@ -28,6 +29,7 @@ target_link_libraries(breakhack -lSDL2_ttf -lX11 -lXrandr + -llua ) # TESTS: diff --git a/data/mapgen.lua b/data/mapgen.lua new file mode 100644 index 0000000..3a859ec --- /dev/null +++ b/data/mapgen.lua @@ -0,0 +1,37 @@ +function add_tiles_to_room (map, room_x, room_y, texture) + for i=0,11 do + for j=0,15 do + if (i == 0 and j == 0) then + add_tile(map, room_x, room_y, i, j, texture, 0, 48) + elseif (i == 11 and j == 0) then + add_tile(map, room_x, room_y, i, j, texture, 0, 80) + elseif (i == 0 and j == 15) then + add_tile(map, room_x, room_y, i, j, texture, 32, 48) + elseif (i == 11 and j == 15) then + add_tile(map, room_x, room_y, i, j, texture, 32, 80) + elseif (i == 0) then + add_tile(map, room_x, room_y, i, j, texture, 16, 48) + elseif (j == 0) then + add_tile(map, room_x, room_y, i, j, texture, 0, 64) + elseif (i == 11) then + add_tile(map, room_x, room_y, i, j, texture, 16, 80) + elseif (j == 15) then + add_tile(map, room_x, room_y, i, j, texture, 32, 64) + else + add_tile(map, room_x, room_y, i, j, texture, 16, 64) + end + end + end +end + +map = create_map() +-- add_texture(map, "path/to/a/fancy/texture") +-- add_tile(map, 1, 2, 3) + +local floorTexture = add_texture(map, "assets/Objects/Floor.png") + +for i=0,9 do + for j=0,9 do + add_tiles_to_room(map, i, j, floorTexture); + end +end diff --git a/src/main.c b/src/main.c index 17f8a06..7a5bf70 100644 --- a/src/main.c +++ b/src/main.c @@ -9,6 +9,7 @@ #include "dimension.h" #include "camera.h" #include "map.h" +#include "map_lua.h" #define SCREEN_WIDTH 1024 #define SCREEN_HEIGHT 768 @@ -25,7 +26,8 @@ static bool initSDL() { int imgFlags = IMG_INIT_PNG; - Dimension dim = getScreenDimensions(); + //Dimension dim = getScreenDimensions(); + Dimension dim = (Dimension) { 1920, 1080 }; double scale = 1.0; if (dim.height > 1080) { @@ -76,7 +78,7 @@ static bool initGame() { gSpriteList = linkedlist_create(); - gMap = map_create(gRenderer); + gMap = map_lua_generator_run(gRenderer); return gSpriteList == NULL; } diff --git a/src/map.c b/src/map.c index edbb8f6..db2cd7b 100644 --- a/src/map.c +++ b/src/map.c @@ -1,4 +1,5 @@ #include "map.h" +#include "map_lua.h" #include "util.h" static @@ -16,7 +17,7 @@ Room* create_room() return room; } -Map* map_create(SDL_Renderer *renderer) +Map* map_create() { int i, j; @@ -34,11 +35,45 @@ Map* map_create(SDL_Renderer *renderer) return map; } +void map_add_tile(Map *map, Position *room_pos, Position *tile_pos, MapTile *tile) +{ + MapTile **oldTile = &map->rooms[room_pos->x][room_pos->y]->tiles[tile_pos->x][tile_pos->y]; + 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)); + return linkedlist_size(map->textures) - 1; +} + static void map_tile_render(Map *map, MapTile *tile, Position *pos, Camera *cam) { if (tile == NULL) return; + + Position camPos = camera_to_camera_position(cam, pos); + SDL_Rect draw_box = (SDL_Rect) { + camPos.x, + camPos.y, + 64, + 64 + }; + + Texture *texture = linkedlist_get(&map->textures, tile->textureIndex); + + SDL_RenderCopy(cam->renderer, + texture->texture, + &tile->clip, + &draw_box + ); + } void map_render(Map *map, Camera *cam) @@ -54,7 +89,11 @@ void map_render(Map *map, Camera *cam) room = map->rooms[roomPos.x][roomPos.y]; for (i=0; i < MAP_ROOM_HEIGHT; ++i) { for (j=0; j < MAP_ROOM_WIDTH; ++j) { - map_tile_render(map, room->tiles[i][j], &roomCords, cam); + Position tilePos = (Position) { + roomCords.x + j*64, + roomCords.y + i*64 + }; + map_tile_render(map, room->tiles[i][j], &tilePos, cam); } } } diff --git a/src/map.h b/src/map.h index efbbb73..3f59117 100644 --- a/src/map.h +++ b/src/map.h @@ -15,7 +15,7 @@ typedef struct { unsigned int textureIndex; - Position clipPosition; + SDL_Rect clip; } MapTile; typedef struct { @@ -29,7 +29,11 @@ typedef struct { int level; } Map; -Map* map_create(SDL_Renderer *renderer); +Map* map_create(); + +int map_add_texture(Map*, const char *path, SDL_Renderer*); + +void map_add_tile(Map *map, Position *room_pos, Position *tile_pos, MapTile*); void map_render(Map*, Camera*); diff --git a/src/map_lua.c b/src/map_lua.c new file mode 100644 index 0000000..43b7b7a --- /dev/null +++ b/src/map_lua.c @@ -0,0 +1,142 @@ +#include + +#include +#include +#include + +#include "map_lua.h" +#include "util.h" + +static +lua_State* load_lua_state() +{ + lua_State *L = luaL_newstate(); + luaL_openlibs(L); + return L; +} + +static +int l_create_map(lua_State *L) +{ + Map *map = map_create(); + lua_pushlightuserdata(L, map); + return 1; +} + +static +Map* luaL_checkmap(lua_State *L, int index) +{ + Map *map; + + if (!lua_islightuserdata(L, index)) + fatal("in luaL_checkmap(), pointer lost in lua script"); + + map = lua_touserdata(L, index); + if (map == NULL) + fatal("in luaL_checkmap(), bad map pointer"); + + return map; +} + +static +SDL_Renderer* luaL_checksdlrenderer(lua_State *L) +{ + SDL_Renderer *renderer; + + lua_getglobal(L, "_sdl_renderer"); + if (!lua_islightuserdata(L, -1)) + fatal("in luaL_checksdlrenderer(), pointer lost in lua script"); + + renderer = lua_touserdata(L, -1); + if (renderer == NULL) + fatal("in luaL_checksdlrenderer(), bad SDL_Renderer pointer"); + + return renderer; +} + +static +int l_add_texture(lua_State *L) +{ + Map *map; + const char *path; + int index; + + map = luaL_checkmap(L, 1); + path = luaL_checkstring(L, 2); + SDL_Renderer *renderer = luaL_checksdlrenderer(L); + + index = map_add_texture(map, path, renderer); + lua_pushinteger(L, index); + return 1; +} + +static +int l_add_tile(lua_State *L) +{ + Map *map; + int room_x, room_y, tile_x, tile_y; + int texture_index, tile_clip_x, tile_clip_y; + + map = luaL_checkmap(L, 1); + room_x = luaL_checkinteger(L, 2); + room_y = luaL_checkinteger(L, 3); + tile_x = luaL_checkinteger(L, 4); + tile_y = luaL_checkinteger(L, 5); + texture_index = luaL_checkinteger(L, 6); + tile_clip_x = luaL_checkinteger(L, 7); + tile_clip_y = luaL_checkinteger(L, 8); + + Position roomPos = (Position) { room_x, room_y }; + Position tilePos = (Position) { tile_x, tile_y }; + SDL_Rect clip = (SDL_Rect) { tile_clip_x, tile_clip_y, 16, 16 }; + + MapTile *tile = malloc(sizeof(MapTile)); + *tile = (MapTile) { texture_index, clip }; + + map_add_tile(map, &roomPos, &tilePos, tile); + + return 0; +} + +Map* map_lua_generator_run(SDL_Renderer *renderer) +{ + int status, result; + char file[] = "data/mapgen.lua"; + + printf("[**] Running lua script: %s\n", file); + + lua_State *L = load_lua_state(); + status = luaL_loadfile(L, file); + if (status) { + fprintf(stderr, "[!!] Couldn't load file: %s\n", lua_tostring(L, -1)); + exit(-1); + } + + // Present stuff to lua + lua_pushlightuserdata(L, renderer); + lua_setglobal(L, "_sdl_renderer"); + + lua_pushcfunction(L, l_create_map); + lua_setglobal(L, "create_map"); + + lua_pushcfunction(L, l_add_tile); + lua_setglobal(L, "add_tile"); + + lua_pushcfunction(L, l_add_texture); + lua_setglobal(L, "add_texture"); + + result = lua_pcall(L, 0, LUA_MULTRET, 0); + if (result) { + fprintf(stderr, "[!!] Failed to run script: %s\n", lua_tostring(L, -1)); + exit(-1); + } + + lua_getglobal(L, "map"); + Map *map = lua_touserdata(L, 1); + + lua_close(L); + + printf("[**] Done\n"); + + return map; +} diff --git a/src/map_lua.h b/src/map_lua.h new file mode 100644 index 0000000..534a4b4 --- /dev/null +++ b/src/map_lua.h @@ -0,0 +1,8 @@ +#ifndef MAP_LUA_H_ +#define MAP_LUA_H_ + +#include "map.h" + +Map* map_lua_generator_run(); + +#endif // MAP_LUA_H_ diff --git a/src/texture.c b/src/texture.c index 7d45e2c..d4fd6c4 100644 --- a/src/texture.c +++ b/src/texture.c @@ -2,7 +2,7 @@ #include "texture.h" #include "util.h" -Texture* texture_create(char *path, SDL_Renderer *renderer) +Texture* texture_create(const char *path, SDL_Renderer *renderer) { Texture *newTexture = NULL; SDL_Surface *surface = IMG_Load(path); diff --git a/src/texture.h b/src/texture.h index 365adee..c0d1320 100644 --- a/src/texture.h +++ b/src/texture.h @@ -10,7 +10,7 @@ typedef struct { SDL_Rect clip; } Texture; -Texture* texture_create(char *path, SDL_Renderer *renderer); +Texture* texture_create(const char *path, SDL_Renderer *renderer); void texture_destroy(Texture *texture);