diff --git a/CMakeLists.txt b/CMakeLists.txt index b9fd992..fa28d11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,6 +94,7 @@ add_executable(breakhack src/io_util src/physfsrwops src/skillbar + src/texturecache ) target_link_libraries(breakhack diff --git a/src/actiontext.c b/src/actiontext.c index dc79062..424593d 100644 --- a/src/actiontext.c +++ b/src/actiontext.c @@ -54,8 +54,9 @@ actiontext_render(ActionText *t, Camera *cam) timer_start(t->timer); Position cameraPos = camera_to_camera_position(cam, &t->pos); + SDL_Rect box = { cameraPos.x, cameraPos.y, t->texture->dim.width, t->texture->dim.height }; if (timer_get_ticks(t->timer) < 300) { - texture_render(t->texture, &cameraPos, cam); + texture_render(t->texture, &box, cam); } else { timer_stop(t->timer); t->active = false; diff --git a/src/defines.h b/src/defines.h index 3e71fae..4b20ec9 100644 --- a/src/defines.h +++ b/src/defines.h @@ -47,6 +47,9 @@ #define SCREEN_WIDTH (GAME_VIEW_WIDTH + RIGHT_GUI_WIDTH) #define SCREEN_HEIGHT (RIGHT_GUI_HEIGHT + BOTTOM_GUI_HEIGHT) +#define DEFAULT_DIMENSION (Dimension) { 16, 16 } +#define GAME_DIMENSION (Dimension) { TILE_DIMENSION, TILE_DIMENSION } + /* Windows and compile crap */ #ifdef _WIN32 #define strdup _strdup diff --git a/src/gui.c b/src/gui.c index 892792a..ab664b0 100644 --- a/src/gui.c +++ b/src/gui.c @@ -25,6 +25,7 @@ #include "gui.h" #include "util.h" #include "map.h" +#include "texturecache.h" #define DEFAULT_LOG { NULL, 50, 0, 200 } @@ -35,11 +36,11 @@ static SDL_Rect frame_top_left = { 16, 160, 16, 16 }; static SDL_Rect frame_top_right = { 48, 160, 16, 16 }; static SDL_Rect frame_bottom_left = { 16, 192, 16, 16 }; static SDL_Rect frame_bottom_right = { 48, 192, 16, 16 }; -static SDL_Rect frame_top = { 32, 160, 16, 16 }; +static SDL_Rect frame_top = { 32, 160, 16, 16 }; static SDL_Rect frame_bottom = { 32, 192, 16, 16 }; static SDL_Rect frame_center = { 32, 176, 16, 16 }; -static SDL_Rect frame_left = { 16, 176, 16, 16 }; -static SDL_Rect frame_right = { 48, 176, 16, 16 }; +static SDL_Rect frame_left = { 16, 176, 16, 16 }; +static SDL_Rect frame_right = { 48, 176, 16, 16 }; static struct LogData_t { char **log; @@ -48,19 +49,6 @@ static struct LogData_t { unsigned int strlen; } log_data = DEFAULT_LOG; -static Texture* -add_texture(Gui *gui, const char *path, SDL_Renderer *renderer) -{ - Texture *t = ht_get(gui->textures, path); - if (t == NULL) { - t = texture_create(); - texture_load_from_file(t, path, renderer); - t->dim = (Dimension) { 16, 16 }; - ht_set(gui->textures, path, t); - } - return t; -} - static void gui_malloc_log(void) { @@ -101,7 +89,7 @@ init_sprites(Gui *gui, SDL_Renderer *renderer) Texture *t; unsigned int i; - t = add_texture(gui, "GUI/GUI0.png", renderer); + t = texturecache_add("GUI/GUI0.png"); /* * Add XP bar decoration @@ -138,7 +126,7 @@ init_sprites(Gui *gui, SDL_Renderer *renderer) } Sprite *s; - t = add_texture(gui, "Items/Potion.png", renderer); + t = texturecache_add("Items/Potion.png"); s = sprite_create(); s->fixed = true; sprite_set_texture(s, t, 0); @@ -146,7 +134,7 @@ init_sprites(Gui *gui, SDL_Renderer *renderer) s->pos = (Position) { 16, POS_Y_COLLECTABLES }; linkedlist_append(&gui->sprites, s); - t = add_texture(gui, "Items/Money.png", renderer); + t = texturecache_add("Items/Money.png"); s = sprite_create(); s->fixed = true; sprite_set_texture(s, t, 0); @@ -165,7 +153,6 @@ gui_create(SDL_Renderer *renderer) gui->sprites = linkedlist_create(); gui->health = linkedlist_create(); gui->xp_bar = linkedlist_create(); - gui->textures = ht_create(5); for (i = 0; i < LOG_LINES_COUNT; ++i) { t = texture_create(); @@ -201,8 +188,8 @@ set_max_health(Gui *gui, int max, SDL_Renderer *renderer) while (gui->health != NULL) sprite_destroy(linkedlist_pop(&gui->health)); - texture0 = add_texture(gui, "GUI/GUI0.png", renderer); - texture1 = add_texture(gui, "GUI/GUI1.png", renderer); + texture0 = texturecache_add("GUI/GUI0.png"); + texture1 = texturecache_add("GUI/GUI1.png"); for (i = 0; i < max/3; ++i) { Sprite *sprite = sprite_create(); @@ -313,30 +300,35 @@ gui_update_player_stats(Gui *gui, Player *player, Map *map, SDL_Renderer *render if (dungeon_level != (unsigned int) map->level) { m_sprintf(buffer, 200, "Dungeon level: %d", map->level); texture_load_from_text(gui->labels[DUNGEON_LEVEL_LABEL]->textures[0], buffer, color, renderer); + gui->labels[DUNGEON_LEVEL_LABEL]->dim = gui->labels[DUNGEON_LEVEL_LABEL]->textures[0]->dim; dungeon_level = (unsigned int) map->level; } if (current_potion_sips != (int) player->potion_sips) { m_sprintf(buffer, 200, "x %u", (unsigned int) player->potion_sips); texture_load_from_text(gui->labels[HEALTH_POTION_LABEL]->textures[0], buffer, color, renderer); + gui->labels[HEALTH_POTION_LABEL]->dim = gui->labels[HEALTH_POTION_LABEL]->textures[0]->dim; current_potion_sips = player->potion_sips; } if (last_gold != player->gold) { m_sprintf(buffer, 200, "x %.2f", player->gold); texture_load_from_text(gui->labels[GOLD_LABEL]->textures[0], buffer, color, renderer); + gui->labels[GOLD_LABEL]->dim = gui->labels[GOLD_LABEL]->textures[0]->dim; last_gold = player->gold; } if (last_xp != (int) data.current) { m_sprintf(buffer, 200, "XP: %u / %u", data.current, data.nextLevel); texture_load_from_text(gui->labels[CURRENT_XP_LABEL]->textures[0], buffer, color, renderer); + gui->labels[CURRENT_XP_LABEL]->dim = gui->labels[CURRENT_XP_LABEL]->textures[0]->dim; last_xp = data.current; } if (last_level != data.level) { m_sprintf(buffer, 200, "Level: %u", data.level); texture_load_from_text(gui->labels[LEVEL_LABEL]->textures[0], buffer, color, renderer); + gui->labels[LEVEL_LABEL]->dim = gui->labels[LEVEL_LABEL]->textures[0]->dim; last_level = data.level; } } @@ -344,33 +336,34 @@ gui_update_player_stats(Gui *gui, Player *player, Map *map, SDL_Renderer *render static void gui_render_frame(Gui *gui, unsigned int width, unsigned int height, Camera *cam) { - Texture *texture = ht_get(gui->textures, "GUI/GUI0.png"); - Position pos = { 0, 0 }; + Texture *texture = texturecache_get("GUI/GUI0.png"); unsigned int i, j; + SDL_Rect box = { 0, 0, 16, 16 }; + for (i = 0; i < width; ++i) { for (j = 0; j < height; ++j) { - pos.x = i * 16; - pos.y = j * 16; + box.x = i * 16; + box.y = j * 16; if (i == 0 && j == 0) { - texture_render_clip(texture, &pos, &frame_top_left, cam); + texture_render_clip(texture, &box, &frame_top_left, cam); } else if (i == (width - 1) && j == 0) { - texture_render_clip(texture, &pos, &frame_top_right, cam); + texture_render_clip(texture, &box, &frame_top_right, cam); } else if (i == 0 && j == (height - 1)) { - texture_render_clip(texture, &pos, &frame_bottom_left, cam); + texture_render_clip(texture, &box, &frame_bottom_left, cam); } else if (i == (width - 1) && j == (height - 1)) { - texture_render_clip(texture, &pos, &frame_bottom_right, cam); + texture_render_clip(texture, &box, &frame_bottom_right, cam); } else if (i == 0) { - texture_render_clip(texture, &pos, &frame_left, cam); + texture_render_clip(texture, &box, &frame_left, cam); } else if (i == (width - 1)) { - texture_render_clip(texture, &pos, &frame_right, cam); + texture_render_clip(texture, &box, &frame_right, cam); } else if (j == 0) { - texture_render_clip(texture, &pos, &frame_top, cam); + texture_render_clip(texture, &box, &frame_top, cam); } else if (j == (height - 1)) { - texture_render_clip(texture, &pos, &frame_bottom, cam); + texture_render_clip(texture, &box, &frame_bottom, cam); } else { - texture_render_clip(texture, &pos, &frame_center, cam); + texture_render_clip(texture, &box, &frame_center, cam); } } } @@ -445,19 +438,20 @@ gui_render_log(Gui *gui, unsigned int width, unsigned int height, Camera *cam) unsigned int i; unsigned int render_count; - Position p; + SDL_Rect box = { 16, 0, 16, 16 }; render_count = LOG_LINES_COUNT > log_data.count ? log_data.count : LOG_LINES_COUNT; - p = (Position) { 16, 0 }; gui_render_frame(gui, width/16, height/16, cam); for (i = 0; i < render_count; ++i) { Texture *t; - p.y = 16 + ((LOG_FONT_SIZE+5) * i); + box.y = 16 + ((LOG_FONT_SIZE+5) * i); t = gui->log_lines[i]; texture_load_from_text(t, log_data.log[i], color, cam->renderer); - texture_render(t, &p, cam); + box.w = t->dim.width; + box.h = t->dim.height; + texture_render(t, &box, cam); } } @@ -493,6 +487,5 @@ gui_destroy(Gui *gui) for (int i = 0; i < LABEL_COUNT; ++i) sprite_destroy(gui->labels[i]); - ht_destroy_custom(gui->textures, (void (*)(void*)) &texture_destroy); free(gui); } diff --git a/src/gui.h b/src/gui.h index f6dee18..e514e21 100644 --- a/src/gui.h +++ b/src/gui.h @@ -24,7 +24,6 @@ #define LABEL_FONT_SIZE 8 #include "linkedlist.h" -#include "hashtable.h" #include "sprite.h" #include "camera.h" #include "player.h" @@ -42,7 +41,6 @@ typedef struct { LinkedList *sprites; LinkedList *health; LinkedList *xp_bar; - Hashtable *textures; Sprite *labels[LABEL_COUNT]; Texture *log_lines[LOG_LINES_COUNT]; } Gui; diff --git a/src/item_builder.c b/src/item_builder.c index f2aaac0..f22997c 100644 --- a/src/item_builder.c +++ b/src/item_builder.c @@ -25,6 +25,7 @@ #include "gui.h" #include "mixer.h" #include "random.h" +#include"texturecache.h" static ItemBuilder *builder = NULL; @@ -32,7 +33,6 @@ void item_builder_init(SDL_Renderer *renderer) { builder = ec_malloc(sizeof(ItemBuilder)); - builder->textures = ht_create(20); builder->renderer = renderer; } @@ -43,19 +43,6 @@ check_builder(void) fatal("item_builder_init() not run"); } -static Texture * -load_texture(const char *path) -{ - Texture *t = ht_get(builder->textures, path); - if (!t) { - t = texture_create(); - texture_load_from_file(t, path, builder->renderer); - t->dim = (Dimension) { 32, 32 }; - ht_set(builder->textures, path, t); - } - return t; -} - static void eat_flesh(Item *item, Player *player) { @@ -85,10 +72,11 @@ create_item(const char *path, SDL_Rect clip, void (*cb)(Item*, Player*)) Item *item; item = item_create(); - t = load_texture(path); + t = texturecache_add(path); item->sprite = sprite_create(); sprite_set_texture(item->sprite, t, 0); + item->sprite->dim = GAME_DIMENSION; item->sprite->clip = clip; item->effect = cb; @@ -203,6 +191,5 @@ item_builder_build_sack(void) void item_builder_close(void) { - ht_destroy_custom(builder->textures, (void (*)(void*)) texture_destroy); free(builder); } diff --git a/src/item_builder.h b/src/item_builder.h index c0a9e43..8c36bbf 100644 --- a/src/item_builder.h +++ b/src/item_builder.h @@ -20,10 +20,8 @@ #define ITEMBUILDER_H_ #include "item.h" -#include "hashtable.h" typedef struct { - Hashtable *textures; SDL_Renderer *renderer; } ItemBuilder; diff --git a/src/main.c b/src/main.c index a488662..d98a0f1 100644 --- a/src/main.c +++ b/src/main.c @@ -44,6 +44,7 @@ #include "mixer.h" #include "random.h" #include "skillbar.h" +#include "texturecache.h" typedef enum Turn_t { PLAYER, @@ -180,6 +181,7 @@ static bool initGame(void) { initViewports(); + texturecache_init(gRenderer); gCamera.renderer = gRenderer; gRoomMatrix = roommatrix_create(); gGui = gui_create(gRenderer); @@ -253,6 +255,7 @@ createMenu(Menu **menu, struct MENU_ITEM menu_items[], unsigned int size) hcenter = (SCREEN_WIDTH/2) - (s1->textures[0]->dim.width/2); s1->pos = (Position) { (int) hcenter, (int) 200 + (i*50) }; + s1->dim = s1->textures[0]->dim; s1->fixed = true; Sprite *s2 = sprite_create(); @@ -261,6 +264,7 @@ createMenu(Menu **menu, struct MENU_ITEM menu_items[], unsigned int size) C_MENU_HOVER, gRenderer); s2->pos = (Position) { (int) hcenter, (int) 200 + (i*50) }; + s2->dim = s2->textures[0]->dim; s2->fixed = true; menu_item_add(*menu, s1, s2, menu_items[i].callback); @@ -610,8 +614,9 @@ void close(void) item_builder_close(); particle_engine_close(); timer_destroy(menuTimer); - mixer_close(); + texturecache_close(); + SDL_DestroyRenderer(gRenderer); SDL_DestroyWindow(gWindow); gWindow = NULL; diff --git a/src/map.c b/src/map.c index e5f5f93..04f57ee 100644 --- a/src/map.c +++ b/src/map.c @@ -46,7 +46,6 @@ Map* map_create() Map *map = ec_malloc(sizeof(Map)); map->textures = linkedlist_create(); - map->monsterTextures = ht_create(30); map->monsters = linkedlist_create(); map->items = linkedlist_create(); map->currentRoom = (Position) { 0, 0 }; @@ -95,21 +94,6 @@ void map_add_decoration(Map *map, Position *tile_pos, MapTile *tile) *oldTile = tile; } -Texture* -map_add_monster_texture(Map *map, const char *path, SDL_Renderer *renderer) -{ - Texture *t; - - t = ht_get(map->monsterTextures, path); - if (!t) { - t = texture_create(); - texture_load_from_file(t, path, renderer); - ht_set(map->monsterTextures, path, t); - } - - return t; -} - void map_clear_dead_monsters(Map *map) { @@ -357,7 +341,6 @@ void map_destroy(Map *map) while (map->items != NULL) item_destroy(linkedlist_pop(&map->items)); - ht_destroy_custom(map->monsterTextures, (void (*)(void*)) texture_destroy); timer_destroy(map->renderTimer); free(map); } diff --git a/src/map.h b/src/map.h index 19576a0..8296e9b 100644 --- a/src/map.h +++ b/src/map.h @@ -22,7 +22,6 @@ #include #include -#include "hashtable.h" #include "linkedlist.h" #include "sprite.h" #include "camera.h" @@ -48,7 +47,6 @@ typedef struct Room_t { typedef struct Map_t { Room* rooms[MAP_H_ROOM_COUNT][MAP_V_ROOM_COUNT]; LinkedList *textures; - Hashtable *monsterTextures; LinkedList *monsters; LinkedList *items; Position currentRoom; @@ -69,9 +67,6 @@ map_add_tile(Map *map, Position *tile_pos, MapTile*); void map_add_decoration(Map *map, Position *tile_pos, MapTile*); -Texture* -map_add_monster_texture(Map*, const char *path, SDL_Renderer*); - void map_add_monster(Map*, Monster*); diff --git a/src/map_lua.c b/src/map_lua.c index 96b6cee..83a02ab 100644 --- a/src/map_lua.c +++ b/src/map_lua.c @@ -28,6 +28,8 @@ #include "map_lua.h" #include "util.h" #include "stats.h" +#include "io_util.h" +#include "texturecache.h" static lua_State* load_lua_state(void) @@ -278,13 +280,13 @@ l_add_monster(lua_State *L) nstate = (int) luaL_checkinteger(L, -2); cstate = (int) luaL_checkinteger(L, -1); - texture1 = map_add_monster_texture(map, texture_path_1, renderer); - texture2 = map_add_monster_texture(map, texture_path_2, renderer); + texture1 = texturecache_add(texture_path_1); + texture2 = texturecache_add(texture_path_2); label = strdup(tmp_label); - texture1->dim = (Dimension) { TILE_DIMENSION, TILE_DIMENSION }; - texture2->dim = (Dimension) { TILE_DIMENSION, TILE_DIMENSION }; + texture1->dim = GAME_DIMENSION; + texture2->dim = GAME_DIMENSION; lua_pop(L, 8); diff --git a/src/mixer.c b/src/mixer.c index e63edeb..bfa1c8b 100644 --- a/src/mixer.c +++ b/src/mixer.c @@ -21,8 +21,16 @@ #include "util.h" #include "io_util.h" -static Mix_Music *music[LAST_MUSIC]; static Mix_Chunk *effects[LAST_EFFECT]; +static Mix_Music *current_song = NULL; +static Music loaded_song = LAST_MUSIC; + +static char *music[LAST_MUSIC] = { + "Sounds/Music/fantasy-game-background-looping.ogg", // GAME_MUSIC0 + "Sounds/Music/bog-creatures-on-the-move-looping.ogg", // GAME_MUSIC1 + "Sounds/Music/fantascape-looping.ogg", // GAME_MUSIC2 + "Sounds/Music/fantasy-forest-battle.ogg" // MENU_MUSIC +}; static bool sound_enabled = true; static bool music_enabled = true; @@ -36,16 +44,6 @@ load_song(char *path) return m; } -static void -load_music(void) -{ - music[GAME_MUSIC0] = load_song("Sounds/Music/fantasy-game-background-looping.ogg"); - music[GAME_MUSIC1] = load_song("Sounds/Music/bog-creatures-on-the-move-looping.ogg"); - music[GAME_MUSIC2] = load_song("Sounds/Music/fantascape-looping.ogg"); - - music[MENU_MUSIC] = load_song("Sounds/Music/fantasy-forest-battle.ogg"); -} - static Mix_Chunk* load_effect(char *path) { @@ -85,8 +83,8 @@ mixer_init(void) if (Mix_OpenAudio( 44100, MIX_DEFAULT_FORMAT, 2, 2048 ) == -1) { fatal("Failed to load sound: %s", Mix_GetError()); } + load_effects(); - load_music(); } bool @@ -125,10 +123,17 @@ mixer_play_music(Music mus) if (!music_enabled) return; + if (mus != loaded_song) { + if (current_song) + Mix_FreeMusic(current_song); + current_song = load_song(music[mus]); + loaded_song = mus; + } + if (Mix_PlayingMusic()) mixer_stop_music(); - if (Mix_PlayMusic(music[mus], -1) == -1) + if (Mix_PlayMusic(current_song, -1) == -1) fatal("Failed to play music"); } @@ -144,7 +149,8 @@ mixer_close(void) { for (size_t i = 0; i < LAST_EFFECT; ++i) Mix_FreeChunk(effects[i]); - for (size_t i = 0; i < LAST_MUSIC; ++i) - Mix_FreeMusic(music[i]); + if (current_song) + Mix_FreeMusic(current_song); + Mix_CloseAudio(); } diff --git a/src/monster.c b/src/monster.c index 924ee40..31ec77e 100644 --- a/src/monster.c +++ b/src/monster.c @@ -53,6 +53,7 @@ monster_create(SDL_Renderer *renderer) { Monster *m = ec_malloc(sizeof(Monster)); m->sprite = sprite_create(); + m->sprite->dim = GAME_DIMENSION; m->sprite->clip = (SDL_Rect) { 0, 0, 16, 16 }; m->stats = (Stats) { diff --git a/src/player.c b/src/player.c index 3f43092..ca846fe 100644 --- a/src/player.c +++ b/src/player.c @@ -316,9 +316,8 @@ player_create(class_t class, SDL_Renderer *renderer) sprite_load_texture(player->sprite, asset, 0, renderer); player->sprite->pos = (Position) { TILE_DIMENSION, TILE_DIMENSION }; + player->sprite->dim = GAME_DIMENSION; player->sprite->clip = (SDL_Rect) { 0, 0, 16, 16 }; - player->sprite->textures[0]->dim = (Dimension) { - TILE_DIMENSION, TILE_DIMENSION }; player->handle_event = &handle_player_input; player_load_texts(player, renderer); diff --git a/src/pointer.c b/src/pointer.c index 1530fa1..4ce7443 100644 --- a/src/pointer.c +++ b/src/pointer.c @@ -32,8 +32,7 @@ pointer_create(SDL_Renderer *renderer) sprite_load_texture(p->sprite, "Items/MedWep.png", 0, renderer); p->sprite->fixed = true; p->sprite->clip = (SDL_Rect) { 0, 0, 16, 16 }; - p->sprite->textures[0]->dim = (Dimension) { - TILE_DIMENSION, TILE_DIMENSION }; + p->sprite->dim = GAME_DIMENSION; return p; } diff --git a/src/skillbar.c b/src/skillbar.c index 55cf24c..b887119 100644 --- a/src/skillbar.c +++ b/src/skillbar.c @@ -22,22 +22,22 @@ #include "util.h" #include "sprite.h" #include "keyboard.h" +#include "texturecache.h" static void load_texture(SkillBar *bar, const char *path, SDL_Renderer *renderer) { static SDL_Color c_yellow = { 255, 255, 0, 255 }; - Texture *t = texture_create(); - texture_load_from_file(t, path, renderer); + Texture *t = texturecache_add(path); t->dim.width = 16; t->dim.height = 16; - ht_set(bar->textures, path, t); for (unsigned int i = 0; i < 4; ++i) { char buffer[4]; Sprite *s = sprite_create(); s->pos = (Position) { i * 32 + 20, 20 }; + s->dim = (Dimension) { 8, 8 }; s->fixed = true; sprite_load_text_texture(s, "GUI/SDS_8x8.ttf", 0, 8); m_sprintf(buffer, 4, "%u", i+1); @@ -50,7 +50,6 @@ SkillBar * skillbar_create(SDL_Renderer *renderer) { SkillBar *bar = ec_malloc(sizeof(SkillBar)); - bar->textures = ht_create(10); bar->sprites = linkedlist_create(); bar->activationTimer = timer_create(); bar->lastActivation = 0; @@ -66,21 +65,21 @@ render_frame(SkillBar *bar, Camera *cam) static SDL_Rect c_bottom_left = { 1*16, 12*16, 16, 16 }; static SDL_Rect c_bottom_right = { 3*16, 12*16, 16, 16 }; - Texture *t = ht_get(bar->textures, "GUI/GUI0.png"); - Position p = { 0, 0 }; + Texture *t = texturecache_get("GUI/GUI0.png"); + SDL_Rect box = { 0, 0, 16, 16 }; for (unsigned int i = 0; i < MAP_ROOM_WIDTH; ++i) { - p.x = i*32; - p.y = 0; - texture_render_clip(t, &p, &c_top_left, cam); - p.y = 16; - texture_render_clip(t, &p, &c_bottom_left, cam); + box.x = i*32; + box.y = 0; + texture_render_clip(t, &box, &c_top_left, cam); + box.y = 16; + texture_render_clip(t, &box, &c_bottom_left, cam); - p.x = i*32 + 16; - p.y = 0; - texture_render_clip(t, &p, &c_top_right, cam); - p.y = 16; - texture_render_clip(t, &p, &c_bottom_right, cam); + box.x = i*32 + 16; + box.y = 0; + texture_render_clip(t, &box, &c_top_right, cam); + box.y = 16; + texture_render_clip(t, &box, &c_bottom_right, cam); } } @@ -146,7 +145,6 @@ skillbar_handle_event(SkillBar *bar, SDL_Event *event) void skillbar_destroy(SkillBar *bar) { - ht_destroy_custom(bar->textures, (void (*)(void *)) texture_destroy); while (bar->sprites) sprite_destroy(linkedlist_pop(&bar->sprites)); free(bar); diff --git a/src/skillbar.h b/src/skillbar.h index c08c5d3..6319d36 100644 --- a/src/skillbar.h +++ b/src/skillbar.h @@ -20,13 +20,11 @@ #define SKILLBAR_H_ #include -#include "hashtable.h" #include "linkedlist.h" #include "camera.h" #include "timer.h" typedef struct SkillBar_t { - Hashtable *textures; LinkedList *sprites; Timer *activationTimer; unsigned int lastActivation; diff --git a/src/sprite.c b/src/sprite.c index 711eedf..8a63a85 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -29,6 +29,7 @@ sprite_create_default(void) s->clip = (SDL_Rect) { 0, 0, 0, 0 }; s->destroyTextures = false; s->pos = (Position) { 0, 0 }; + s->dim = DEFAULT_DIMENSION; s->renderTimer = timer_create(); s->texture_index = 0; s->fixed = false; @@ -39,7 +40,7 @@ sprite_create_default(void) } Sprite* -sprite_create() +sprite_create(void) { return sprite_create_default(); } @@ -111,15 +112,19 @@ void sprite_render(Sprite *s, Camera *cam) else cameraPos = s->pos; + SDL_Rect box = { + cameraPos.x, cameraPos.y, s->dim.width, s->dim.height + }; + if (s->clip.w && s->clip.h) { texture_render_clip(s->textures[s->texture_index], - &cameraPos, + &box, &s->clip, cam); } else { texture_render(s->textures[s->texture_index], - &cameraPos, + &box, cam); } } diff --git a/src/sprite.h b/src/sprite.h index 2c95656..50c6eca 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -32,6 +32,7 @@ typedef struct Sprite_t { SDL_Rect clip; bool destroyTextures; Position pos; + Dimension dim; Timer *renderTimer; unsigned int texture_index; bool fixed; diff --git a/src/texture.c b/src/texture.c index 84161f4..8caa0fd 100644 --- a/src/texture.c +++ b/src/texture.c @@ -117,38 +117,24 @@ texture_load_from_text(Texture *t, } void -texture_render(Texture *texture, Position *p, Camera *cam) +texture_render(Texture *texture, SDL_Rect *box, Camera *cam) { if (!texture->texture) return; - SDL_Rect draw_box = (SDL_Rect) { - p->x, - p->y, - texture->dim.width, - texture->dim.height - }; - - SDL_RenderCopy(cam->renderer, - texture->texture, - NULL, - &draw_box); + texture_render_clip(texture, box, NULL, cam); } void -texture_render_clip(Texture *texture, Position *p, SDL_Rect *clip, Camera *cam) +texture_render_clip(Texture *texture, SDL_Rect *box, SDL_Rect *clip, Camera *cam) { - SDL_Rect draw_box = (SDL_Rect) { - p->x, - p->y, - texture->dim.width, - texture->dim.height - }; + if (!texture->texture) + return; SDL_RenderCopy(cam->renderer, texture->texture, clip, - &draw_box); + box); } void texture_destroy(Texture *texture) diff --git a/src/texture.h b/src/texture.h index f932b3a..0b431a8 100644 --- a/src/texture.h +++ b/src/texture.h @@ -31,21 +31,28 @@ typedef struct { Dimension dim; } Texture; -Texture* texture_create(void); +Texture* +texture_create(void); -void texture_load_from_file(Texture*, const char *path, SDL_Renderer*); +void +texture_load_from_file(Texture*, const char *path, SDL_Renderer*); -void texture_load_font(Texture*, const char *path, unsigned int size); +void +texture_load_font(Texture*, const char *path, unsigned int size); -void texture_load_from_text(Texture*, - const char *text, - SDL_Color, - SDL_Renderer*); +void +texture_load_from_text(Texture*, + const char *text, + SDL_Color, + SDL_Renderer*); -void texture_render(Texture*, Position*, Camera*); +void +texture_render(Texture*, SDL_Rect*, Camera*); -void texture_render_clip(Texture*, Position*, SDL_Rect*, Camera*); +void +texture_render_clip(Texture*, SDL_Rect*, SDL_Rect*, Camera*); -void texture_destroy(Texture *texture); +void +texture_destroy(Texture *texture); #endif // TEXTURE_H_ diff --git a/src/texturecache.c b/src/texturecache.c new file mode 100644 index 0000000..b37e362 --- /dev/null +++ b/src/texturecache.c @@ -0,0 +1,60 @@ +/* + * BreakHack - A dungeone crawler RPG + * Copyright (C) 2018 Linus Probert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "texturecache.h" +#include "hashtable.h" +#include "util.h" + +static Hashtable *textures = NULL; +static SDL_Renderer *renderer; + +void +texturecache_init(SDL_Renderer *rend) +{ + textures = ht_create(50); + renderer = rend; +} + +Texture* +texturecache_add(const char *path) +{ + Texture *t = ht_get(textures, path); + if (!t) { + t = texture_create(); + texture_load_from_file(t, path, renderer); + ht_set(textures, path, t); + debug("Cached texture: %s", path); + } + + return t; +} + +Texture* +texturecache_get(const char *path) +{ + Texture *t = ht_get(textures, path); + if (!t) + fatal("Texture not loaded: %s", path); + return t; +} + +void +texturecache_close(void) +{ + ht_destroy_custom(textures, (void(*)(void*)) texture_destroy); +} \ No newline at end of file diff --git a/src/texturecache.h b/src/texturecache.h new file mode 100644 index 0000000..d1dfcf3 --- /dev/null +++ b/src/texturecache.h @@ -0,0 +1,37 @@ +/* + * BreakHack - A dungeone crawler RPG + * Copyright (C) 2018 Linus Probert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef TEXTURECACHE_H_ +#define TEXTURECACHE_H_ + +#include +#include "texture.h" + +void +texturecache_init(SDL_Renderer*); + +Texture* +texturecache_add(const char *path); + +Texture* +texturecache_get(const char *path); + +void +texturecache_close(void); + +#endif // TEXTURECACHE_H_ \ No newline at end of file