Memory usage improvements
Adds a texturecache to prevent multiple loads of the same texture. Texture dimension is now only intended for the actual texture dimension. Sprite should hold the "rendering dimension". Music songs now load and unload when switching songs. Standardized a lot of dimensions.
This commit is contained in:
parent
052b03189e
commit
131c0caa4e
|
@ -94,6 +94,7 @@ add_executable(breakhack
|
|||
src/io_util
|
||||
src/physfsrwops
|
||||
src/skillbar
|
||||
src/texturecache
|
||||
)
|
||||
|
||||
target_link_libraries(breakhack
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
73
src/gui.c
73
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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -20,10 +20,8 @@
|
|||
#define ITEMBUILDER_H_
|
||||
|
||||
#include "item.h"
|
||||
#include "hashtable.h"
|
||||
|
||||
typedef struct {
|
||||
Hashtable *textures;
|
||||
SDL_Renderer *renderer;
|
||||
} ItemBuilder;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
17
src/map.c
17
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);
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include <SDL.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#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*);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
36
src/mixer.c
36
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();
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -20,13 +20,11 @@
|
|||
#define SKILLBAR_H_
|
||||
|
||||
#include <SDL.h>
|
||||
#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;
|
||||
|
|
11
src/sprite.c
11
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* BreakHack - A dungeone crawler RPG
|
||||
* Copyright (C) 2018 Linus Probert <linus.probert@gmail.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* BreakHack - A dungeone crawler RPG
|
||||
* Copyright (C) 2018 Linus Probert <linus.probert@gmail.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TEXTURECACHE_H_
|
||||
#define TEXTURECACHE_H_
|
||||
|
||||
#include <SDL.h>
|
||||
#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_
|
Loading…
Reference in New Issue