72 lines
2.1 KiB
C
72 lines
2.1 KiB
C
#include "spritesheet.h"
|
|
#include "assets.h"
|
|
#include "render.h"
|
|
#include <SDL2/SDL_render.h>
|
|
#include <SDL2/SDL_image.h>
|
|
|
|
struct Spritesheet {
|
|
// The texture to sample.
|
|
SDL_Texture* texture;
|
|
// The resolution of the texture.
|
|
IVector resolution;
|
|
// The number of frames in the sheet.
|
|
size_t frame_count;
|
|
// The number of frames contained in the width of the texture.
|
|
size_t frame_shear;
|
|
// Rules for how to play the sheet's animation.
|
|
AnimationType animation_type;
|
|
// The resolution of a single frame of the sheet.
|
|
IVector frame_size;
|
|
// The time to wait before switching frames.
|
|
float frame_interval;
|
|
};
|
|
|
|
static
|
|
void _spritesheet_destroy_asset(void* self_void) {
|
|
Spritesheet* self = self_void;
|
|
SDL_DestroyTexture(self->texture);
|
|
free(self_void);
|
|
}
|
|
|
|
Spritesheet* spritesheet_from_texture(const char* texture_name, IVector frame_resolution) {
|
|
Spritesheet* self = malloc(sizeof(Spritesheet));
|
|
|
|
if(self == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
store_asset(self, _spritesheet_destroy_asset);
|
|
|
|
// Load the texture image and query it's size
|
|
self->texture = IMG_LoadTexture(g_renderer, texture_name);
|
|
SDL_QueryTexture(self->texture, NULL, NULL, &self->resolution.x, &self->resolution.y);
|
|
|
|
self->animation_type = ANIMTYPE_ONCE;
|
|
self->frame_size = frame_resolution;
|
|
self->frame_shear = self->resolution.x / self->frame_size.x;
|
|
self->frame_count = self->resolution.x / self->frame_size.x + self->resolution.y / self->frame_size.y;
|
|
self->frame_interval = 0.016f;
|
|
|
|
return self;
|
|
}
|
|
|
|
void spritesheet_destroy(Spritesheet* self) {
|
|
asset_id id = get_asset_id(self);
|
|
if(id != 0) {
|
|
free_asset(id);
|
|
}
|
|
}
|
|
|
|
SDL_Texture* spritesheet_get_texture(const Spritesheet* self) {
|
|
return self->texture;
|
|
}
|
|
|
|
SDL_Rect spritesheet_get_frame_rect(const Spritesheet* self, size_t index) {
|
|
IVector tile_coord = {index % self->frame_shear, index / self->frame_shear};
|
|
tile_coord = vmuli(tile_coord, self->frame_size);
|
|
|
|
return (SDL_Rect) {
|
|
tile_coord.x, tile_coord.y,
|
|
self->frame_size.x, self->frame_size.y
|
|
};
|
|
} |