diff --git a/src/engine.cc b/src/engine.c similarity index 85% rename from src/engine.cc rename to src/engine.c index f982b7d..f524f90 100644 --- a/src/engine.cc +++ b/src/engine.c @@ -1,7 +1,7 @@ -#include "engine.hpp" +#include "engine.h" #include "corelib/assets.h" #include "corelib/render.h" -#include "SDL2/SDL_image.h" +#include "corelib/input.h" int engine_start() { init_context(); @@ -9,6 +9,7 @@ int engine_start() { } int engine_shutdown() { + game_exit(); clean_assets(); close_context(); exit(0); @@ -16,23 +17,27 @@ int engine_shutdown() { void handle_events() { while(SDL_PollEvent(&g_context.event)) { + input_event(g_context.event); switch(g_context.event.type) { - case SDL_QUIT: - g_context.running = 0; - break; + case SDL_QUIT: + g_context.running = 0; + break; } } } int engine_run() { SDL_Window* window = SDL_CreateWindow("Tabletop", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 420, SDL_WINDOW_FULLSCREEN_DESKTOP); + g_context = (context_t){ .window = window, .renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED), .running = 1, }; + load_game(); start_game(); + while(g_context.running) { handle_events(); _render_mode = 1; @@ -41,7 +46,6 @@ int engine_run() { update_game(); swap_buffer(); } - engine_shutdown(); return 0; } diff --git a/src/engine.hpp b/src/engine.h similarity index 78% rename from src/engine.hpp rename to src/engine.h index 2369646..fa546de 100644 --- a/src/engine.hpp +++ b/src/engine.h @@ -1,12 +1,10 @@ #ifndef _engine_h #define _engine_h -#include "SDL2/SDL.h" -#include "corelib/context.h" - /* TO BE DEFINED IN GAME */ extern void load_game(); +extern void game_exit(); extern void start_game(); extern void update_game(); extern void update_ui(); diff --git a/src/game.c b/src/game.c new file mode 100644 index 0000000..0e61f9f --- /dev/null +++ b/src/game.c @@ -0,0 +1,234 @@ +#include "engine.h" +#include "tilemap.h" +#include "corelib/input.h" +#include "corelib/render.h" +#include "corelib/assets.h" +#include "corelib/layers.h" +#include "SDL2/SDL_mouse.h" +#include "SDL2/SDL_scancode.h" +#include "ui.h" + +int cursor_tile = 1; +int dragging = 0; +int drawing = 0; +sprite_t cursor; +spritesheet_t world_sheet; +tileset_t tileset; +tilemap_t tilemap = { + .width = 0,.height = 0, + .x=0,.y=0 +}; + +void on_save_key(int down) { + if(down) save_tilemap(&tilemap, "tilemap.csv"); +} + +void on_load_key(int down) { + if(down) load_tilemap(&tilemap, "tilemap.csv"); +} + +void on_clear_key(int down) { + if(down) { + for(int i = 0; i < tilemap.height * tilemap.width; ++i) { + tilemap.tiles[i] = 0; + } + } +} + +void on_cycle_tile(int axis) { + cursor_tile += axis; + if(cursor_tile <= 0) { + cursor_tile = 1; + } + int size = tileset.size; + if(cursor_tile >= size) { + cursor_tile = size-1; + } + if(tileset.size >= cursor_tile && 0 < cursor_tile) { + cursor = tileset.set[cursor_tile-1].sprite; + } +} + +void on_quit_key(int down) { + if(down) { + g_context.running = 0; + } +} + +void on_click(int down) { + drawing = down; +} + +void on_erase(int down) { + drawing = -down; +} + +void on_drag_world(float dx, float dy) { + if(dragging) { + g_active_view.x -= dx * g_active_view.width; + g_active_view.y -= dy * g_active_view.width; + } +} + +void on_middle_mouse(int down) { + dragging = down; +} + +void on_debug_frame(int down) { + if(down) { + d_debug_next_frame = 1; + } +} + + +void on_button_zoom(int axis) { + if(axis != 0) { + g_active_view.width += axis; + } +} + +void on_scroll_zoom(float delta) { + g_active_view.width -= delta * 0.5f; +} + +void load_game() { + style.button.button = style.button.active = make_nineslice("button.png", 126, 0.01); + world_sheet = make_spritesheet("tileset.png", 189, 189); + + tileset.set = (tile_t*)calloc(21, sizeof(tile_t)); + tileset.size = 21; + tileset.set[0] = (tile_t){.sprite=sprite_from_spritesheet(&world_sheet, 0),.walkable=0}; + tileset.set[1] = (tile_t){.sprite=sprite_from_spritesheet(&world_sheet, 1),.walkable=0}; + tileset.set[2] = (tile_t){.sprite=sprite_from_spritesheet(&world_sheet, 2),.walkable=0}; + + tileset.set[3] = (tile_t){.sprite=sprite_from_spritesheet(&world_sheet, 10),.walkable=0}; + tileset.set[4] = (tile_t){.sprite=sprite_from_spritesheet(&world_sheet, 11),.walkable=0}; + tileset.set[5] = (tile_t){.sprite=sprite_from_spritesheet(&world_sheet, 12),.walkable=0}; + + tileset.set[6] = (tile_t){.sprite=sprite_from_spritesheet(&world_sheet, 20),.walkable=0}; + tileset.set[7] = (tile_t){.sprite=sprite_from_spritesheet(&world_sheet, 21),.walkable=0}; + tileset.set[8] = (tile_t){.sprite=sprite_from_spritesheet(&world_sheet, 22),.walkable=0}; + + tileset.set[9] = (tile_t){.sprite=sprite_from_spritesheet(&world_sheet, 30),.walkable=1}; + tileset.set[10]= (tile_t){.sprite=sprite_from_spritesheet(&world_sheet, 31),.walkable=1}; + tileset.set[11]= (tile_t){.sprite=sprite_from_spritesheet(&world_sheet, 32),.walkable=1}; + + tileset.set[12]= (tile_t){.sprite=sprite_from_spritesheet(&world_sheet, 3),.walkable=1}; + tileset.set[13]= (tile_t){.sprite=sprite_from_spritesheet(&world_sheet, 4),.walkable=1}; + tileset.set[14]= (tile_t){.sprite=sprite_from_spritesheet(&world_sheet, 5),.walkable=1}; + + tileset.set[15]= (tile_t){.sprite=sprite_from_spritesheet(&world_sheet, 13),.walkable=1}; + tileset.set[16]= (tile_t){.sprite=sprite_from_spritesheet(&world_sheet, 14),.walkable=1}; + tileset.set[17]= (tile_t){.sprite=sprite_from_spritesheet(&world_sheet, 15),.walkable=1}; + + tileset.set[18]= (tile_t){.sprite=sprite_from_spritesheet(&world_sheet, 23),.walkable=1}; + tileset.set[19]= (tile_t){.sprite=sprite_from_spritesheet(&world_sheet, 24),.walkable=1}; + tileset.set[20]= (tile_t){.sprite=sprite_from_spritesheet(&world_sheet, 25),.walkable=1}; + + // register calloc'd array to be deleted with free(...) + add_arbitrary_asset(tileset.set, &free); + + tilemap.width = tilemap.height = 128; + on_cycle_tile(0); + + input_init(); + add_key_listener(SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_W, &on_save_key); + add_key_listener(SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_R, &on_load_key); + add_key_listener(SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_C, &on_clear_key); + add_key_listener(SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_Q, &on_quit_key); + add_key_listener(SDL_SCANCODE_A, SDL_SCANCODE_D, &on_cycle_tile); + add_key_listener(SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_TAB, &on_debug_frame); + add_key_listener(SDL_SCANCODE_MINUS, SDL_SCANCODE_EQUALS, &on_button_zoom); + add_mouse_button_listener(SDL_BUTTON_LMASK, &on_click); + add_mouse_button_listener(SDL_BUTTON_RMASK, &on_erase); + add_mouse_button_listener(SDL_BUTTON_MMASK, &on_middle_mouse); + add_mouse_listener(&on_drag_world); + add_scroll_listener(&on_scroll_zoom); +} + +void start_game() { + g_active_view.width = 21; + on_clear_key(1); +} + +void update_game() { + if(drawing == 1) { + drawing = 2; + } + + float fx, fy; + mouse_world_position(&fx, &fy); + cursor.x = floor(fx); cursor.y = floor(fy); + if(drawing) { + int x, y; + x = floorf(fx); + y = floorf(fy); + if(x >= 0 && y >= 0 && x < tilemap.width && y < tilemap.height) { + if(drawing > 0) { + set_tile(&tilemap, x, y, cursor_tile); + } else { + set_tile(&tilemap, x, y, 0); + } + } + } + + rectshape_t world_outline = { + tilemap.x, tilemap.y, (float)tilemap.width, (float)tilemap.height, + 0.01f, RLAYER_TILEMAP-1, {0,0,0,0}, {255, 255, 255, 255} + }; + rectshape_t cursor_outline = { + cursor.x, cursor.y, 1.0f, 1.0f, 0.01f, RLAYER_SPRITES-1, + {0, 0, 0, 0}, {255, 255, 255, 255} + }; + + draw_rect(&world_outline); + draw_rect(&cursor_outline); + draw_sprite(&cursor); + draw_tilemap(&tilemap, &tileset); +} + +void update_ui() { + update_input(); + + nineslice_t sliced = style.button.active; + sliced.rect = (SDL_FRect){0, 0, 0.1, 0.1}; + sliced.depth = RLAYER_UI - 20; + draw_sliced(&sliced); + + const int offset_selected = cursor_tile - 1; + + rectshape_t selected_tile_rect = (rectshape_t) { + offset_selected * 0.015f, 0.f, 0.015f, 0.015f, 0.001f, RLAYER_UI-10, + {0,0,0,0}, {255, 255, 255, 255} + }; + draw_rect(&selected_tile_rect); + + rectshape_t shape = (rectshape_t) { + 0.0f, 0.0f, 1.f, 0.015f, 0, RLAYER_UI, + {100,100,100,255}, {0,0,0,0} + }; + draw_rect(&shape); + + float mx, my; + mouse_screen_position(&mx, &my); + for(int i = 0; i < tileset.size; ++i) { + // make a copy of the reference sprite and adjust it to fit the ui + sprite_t sprite = tileset.set[i].sprite; + sprite.depth = RLAYER_UI-5; + sprite.x = i * 0.015f; sprite.y = 0; + sprite.sx = 0.015f; sprite.sy = 0.015f; + float amx=mx-sprite.x, amy=my-sprite.y; + draw_sprite(&sprite); + + // allow user to select tiles with mouse + if(amx >= 0 && amy >= 0 && amx < sprite.sx && amy < sprite.sy) { + if(drawing == 1) { + drawing = 0; + cursor_tile = i+1; + on_cycle_tile(0); + } + } + } +} + +void game_exit() {} diff --git a/src/game.cc b/src/game.cc deleted file mode 100644 index 5c6de38..0000000 --- a/src/game.cc +++ /dev/null @@ -1,214 +0,0 @@ -#include "engine.hpp" -#include "tilemap.hpp" -#include "corelib/input.h" -#include "corelib/render.h" -#include "corelib/assets.h" -#include "corelib/layers.h" -#include "SDL2/SDL_mouse.h" -#include - -int cursor_tile = 1; -int dragging = 0; -int drawing = 0; -sprite_t cursor; -sprite_t current_tile_display; -spritesheet_t world_sheet; - -void on_save_key(int down) { - if(down) - save_tilemap("tilemap.csv"); -} - -void on_load_key(int down) { - if(down) - load_tilemap("tilemap.csv"); -} - -void on_clear_key(int down) { - if(down) { - for(int i = 0; i < g_tilemap.height * g_tilemap.width; ++i) { - g_tilemap.tiles[i].value = 0; - } - } -} - -void on_cycle_tile(int axis) { - cursor_tile += axis; - if(cursor_tile <= 0) { - cursor_tile = 1; - } - if(cursor_tile > g_tilemap.tileset.set.size()) { - cursor_tile = g_tilemap.tileset.set.size(); - } - if(g_tilemap.tileset.set.size() >= cursor_tile && 0 < cursor_tile) { - cursor = g_tilemap.tileset.set.at(cursor_tile-1); - } -} - -void on_quit_key(int down) { - if(down) { - g_context.running = 0; - } -} - -void on_click(int down) { - drawing = down; -} - -void on_erase(int down) { - drawing = -down; -} - -void on_drag_world(float dx, float dy) { - if(dragging) { - g_active_view.x -= dx * g_active_view.width; - g_active_view.y -= dy * g_active_view.width; - } -} - -void on_middle_mouse(int down) { - dragging = down; -} - -void on_debug_frame(int down) { - if(down) { - d_debug_next_frame = 1; - } -} - -void load_game() { - g_tilemap.width = g_tilemap.height = 128; - - cursor = make_sprite("tilemap.png", 0, 0); - - current_tile_display = make_sprite("tilemap.png", 0, 0); - current_tile_display.depth = 0; - current_tile_display.sx = 0.15f; - current_tile_display.sy = 0.15f; - - world_sheet = make_spritesheet("tilemap.png", 189, 189); - - g_tilemap.tileset.set = { - sprite_from_spritesheet(&world_sheet, 0), - sprite_from_spritesheet(&world_sheet, 1), - sprite_from_spritesheet(&world_sheet, 2), - - sprite_from_spritesheet(&world_sheet, 10), - sprite_from_spritesheet(&world_sheet, 11), - sprite_from_spritesheet(&world_sheet, 12), - - sprite_from_spritesheet(&world_sheet, 20), - sprite_from_spritesheet(&world_sheet, 21), - sprite_from_spritesheet(&world_sheet, 22), - - sprite_from_spritesheet(&world_sheet, 30), - sprite_from_spritesheet(&world_sheet, 31), - sprite_from_spritesheet(&world_sheet, 32), - - sprite_from_spritesheet(&world_sheet, 3), - sprite_from_spritesheet(&world_sheet, 4), - sprite_from_spritesheet(&world_sheet, 5), - - sprite_from_spritesheet(&world_sheet, 13), - sprite_from_spritesheet(&world_sheet, 14), - sprite_from_spritesheet(&world_sheet, 15), - - sprite_from_spritesheet(&world_sheet, 23), - sprite_from_spritesheet(&world_sheet, 24), - sprite_from_spritesheet(&world_sheet, 25), - }; - - on_cycle_tile(0); - - input_init(); - add_listener_for(SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_W, &on_save_key); - add_listener_for(SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_R, &on_load_key); - add_listener_for(SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_C, &on_clear_key); - add_listener_for(SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_Q, &on_quit_key); - add_listener_for(SDL_SCANCODE_A, SDL_SCANCODE_D, &on_cycle_tile); - add_listener_for(SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_TAB, &on_debug_frame); - add_mouse_button_listener(SDL_BUTTON_LMASK, &on_click); - add_mouse_button_listener(SDL_BUTTON_RMASK, &on_erase); - add_mouse_button_listener(SDL_BUTTON_MMASK, &on_middle_mouse); - add_mouse_listener(0, &on_drag_world); -} - -void start_game() { - g_active_view.width = 21; - on_clear_key(1); -} - -void update_game() { - if(drawing == 1) drawing = 2; - mouse_world_position(&cursor.x, &cursor.y); - cursor.x += 0.1f; cursor.y += 0.1f; - - if(drawing) { - int x, y; - float fx, fy; - mouse_world_position(&fx, &fy); - x = floorf(fx); - y = floorf(fy); - if(x >= 0 && y >= 0 && x < g_tilemap.width && y < g_tilemap.height) { - if(drawing > 0) { - get_tilemap_tile(x, y)->value = cursor_tile; - } else { - get_tilemap_tile(x, y)->value = 0; - } - } - } - - rectshape_t world_outline = { - g_tilemap.x, g_tilemap.y, float(g_tilemap.width), float(g_tilemap.height), - 0.01f, RLAYER_TILEMAP-1, {0,0,0,0}, {255, 255, 255, 255} - }; - rectshape_t cursor_outline = { - cursor.x, cursor.y, 1.0f, 1.0f, 0.01f, RLAYER_SPRITES-1, - {0, 0, 0, 0}, {255, 255, 255, 255} - }; - - draw_rect(&world_outline); - draw_rect(&cursor_outline); - draw_sprite(&cursor); - draw_tilemap(); -} - -void update_ui() { - update_input(); - - const int offset_selected = cursor_tile - 1; - - rectshape_t selected_tile_rect = (rectshape_t) { - offset_selected * 0.015f, 0.f, 0.015f, 0.015f, 0.001f, RLAYER_UI-10, - {0,0,0,0}, {255, 255, 255, 255} - }; - draw_rect(&selected_tile_rect); - - rectshape_t shape = (rectshape_t) { - 0.0f, 0.0f, 1.f, 0.015f, 0, RLAYER_UI, - {100,100,100,255}, {0,0,0,0} - }; - draw_rect(&shape); - - float mx, my; - mouse_screen_position(&mx, &my); - for(int i=0;i= 0 && amy >= 0 && amx < sprite.sx && amy < sprite.sy) { - if(drawing == 1) { - drawing = 0; - cursor_tile = i+1; - on_cycle_tile(0); - } - } - - } -} diff --git a/src/tilemap.cc b/src/tilemap.c similarity index 60% rename from src/tilemap.cc rename to src/tilemap.c index e51857d..ef9ce4d 100644 --- a/src/tilemap.cc +++ b/src/tilemap.c @@ -1,22 +1,18 @@ -#include "tilemap.hpp" +#include "tilemap.h" #include "corelib/layers.h" #include "stdio.h" #include "string.h" #include "signal.h" #include "stdio.h" -tilemap_t g_tilemap = { - .width = 0,.height = 0, - .x=0,.y=0 -}; - -void draw_tilemap() { +void draw_tilemap(const tilemap_t* tilemap, const tileset_t* tileset) { sprite_t sprite; - for(int y=0;yvalue <= 0) continue; - sprite = g_tilemap.tileset.set[tile->value-1]; + for(int y=0;yheight;++y) { + for(int x=0;xwidth;++x) { + size_t index = get_tile(tilemap, x, y); + if(index == 0) continue; + const tile_t tile = tileset->set[index-1]; + sprite = tile.sprite; sprite.depth = RLAYER_TILEMAP; sprite.x = x; sprite.y = y; draw_sprite(&sprite); @@ -24,20 +20,20 @@ void draw_tilemap() { } } -int save_tilemap(const char* file) { +int save_tilemap(const tilemap_t* map, const char* file) { FILE* fs = fopen(file, "w"); if(fs == NULL) { fprintf(stderr, "ERROR: Failed to open file %s\n", file); return 1; } - fprintf(fs, "%d,%d,", g_tilemap.width, g_tilemap.height); - for(int i = 0; i < g_tilemap.width * g_tilemap.height; ++i) - fprintf(fs,"%d,", g_tilemap.tiles[i].value); + fprintf(fs, "%d,%d,", map->width, map->height); + for(int i = 0; i < map->width * map->height; ++i) + fprintf(fs,"%zu,", map->tiles[i]); fclose(fs); return 0; } -int load_tilemap(const char* file) { +int load_tilemap(tilemap_t* map, const char* file) { FILE* fs = fopen(file, "r"); if(fs == NULL) { fprintf(stderr, "ERROR: Failed to open file %s\n", file); @@ -46,7 +42,7 @@ int load_tilemap(const char* file) { char buf[99]; char* writer = buf; int n = 0; - tile_t* tile = g_tilemap.tiles; + size_t* tile = map->tiles; int entries=0; while(1) { n = fgetc(fs); @@ -60,12 +56,12 @@ int load_tilemap(const char* file) { case ',': *writer = '\0'; if(entries == 0) { - g_tilemap.width = atoi(buf); + map->width = atoi(buf); } else if(entries == 1) { - g_tilemap.height = atoi(buf); + map->height = atoi(buf); } else { if(entries-2 >= TILEMAP_MAX_SIZE) goto end_while; - tile->value = (short)atoi(buf); + *tile = (size_t)atoi(buf); ++tile; } writer = buf; diff --git a/src/tilemap.h b/src/tilemap.h new file mode 100644 index 0000000..478bebd --- /dev/null +++ b/src/tilemap.h @@ -0,0 +1,41 @@ +#ifndef _tilemap_h +#define _tilemap_h + +#include "corelib/render.h" + +#define TILEMAP_MAX_SIZE 16384 +#define TILESET_MAX_SIZE 255 + +typedef struct tile_t { + sprite_t sprite; + short walkable; +} tile_t; + +typedef struct tileset_t { + tile_t* set; + size_t size; +} tileset_t; + +typedef struct tilemap_t { + size_t tiles[TILEMAP_MAX_SIZE]; + int width, height; + float x, y; +} tilemap_t; + +static inline int get_tilemap_index(const tilemap_t* tilemap, int x, int y) { + return x + y * tilemap->width; +} +static inline size_t get_tile(const tilemap_t* tilemap, int x, int y) { + return *(tilemap->tiles + get_tilemap_index(tilemap, x, y)); +} +static inline void set_tile(tilemap_t* tilemap, int x, int y, size_t value) { + *(tilemap->tiles + get_tilemap_index(tilemap, x, y)) = value; +} + +extern void draw_tilemap(const tilemap_t* tilemap, const tileset_t* tileset); +/*load csv tilemap from file*/ +extern int load_tilemap(tilemap_t* tilemap, const char* file); +/*write csv tilemap to file*/ +extern int save_tilemap(const tilemap_t* tilemap, const char* file); + +#endif /* _tilemap_h */ diff --git a/src/tilemap.hpp b/src/tilemap.hpp deleted file mode 100644 index f361fd0..0000000 --- a/src/tilemap.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _tilemap_h -#define _tilemap_h - -#include "vector" -#include "corelib/render.h" - -#define TILEMAP_MAX_SIZE 16384 - -typedef struct tile_t { - short value; -} tile_t; - -typedef struct tileset_t { - std::vector set; -} tileset_t; - -typedef struct tilemap_t { - tile_t tiles[TILEMAP_MAX_SIZE]; - tileset_t tileset; - int width, height; - float x, y; -} tilemap_t; - -extern tilemap_t g_tilemap; - -static inline int get_tilemap_index(int x, int y) { - return x + y * g_tilemap.width; -} -static inline tile_t* get_tilemap_tile(int x, int y) { - return g_tilemap.tiles + get_tilemap_index(x, y); -} - -extern void draw_tilemap(); -/*load csv tilemap from file*/ -extern int load_tilemap(const char* file); -/*write csv tilemap to file*/ -extern int save_tilemap(const char* file); - -#endif /* _tilemap_h */