Add tileset loading

This commit is contained in:
2026-06-05 12:02:40 +01:00
parent 419e95ac89
commit 821255a065
6 changed files with 118 additions and 6 deletions
+44 -1
View File
@@ -46,6 +46,48 @@ mrb_value image_load(mrb_state *mrb, mrb_value) {
return definitions::wrap(definitions::bindings.Image, id);
}
mrb_value image_load_set(mrb_state *mrb, mrb_value) {
char *path;
mrb_float tile_width, tile_height;
mrb_value kwargs;
mrb_get_args(mrb, "zff|H", &path, &tile_width, &tile_height, &kwargs);
bool pixel_art = false;
int padding_x = 0, padding_y = 0, offset_x = 0, offset_y = 0;
if (!mrb_nil_p(kwargs)) {
HASH_BOOL(kwargs, pixel_art, pixel_art);
mrb_value padding_hash = HASH_GET(kwargs, padding);
if (!mrb_nil_p(padding_hash)) {
HASH_FLOAT(padding_hash, x, padding_x);
HASH_FLOAT(padding_hash, y, padding_y);
}
mrb_value offset_hash = HASH_GET(kwargs, offset);
if (!mrb_nil_p(offset_hash)) {
HASH_FLOAT(offset_hash, x, offset_x);
HASH_FLOAT(offset_hash, y, offset_y);
}
}
std::vector<uint64_t> images = window.load_image_set(
path,
{(float)tile_width, (float)tile_height},
{(float)padding_x, (float)padding_y},
{(float)offset_x, (float)offset_y},
pixel_art
);
mrb_value image_array = mrb_ary_new_capa(mrb, images.size());
for (uint64_t image_id : images) {
image_pool.use(image_id);
mrb_value image_obj = definitions::wrap(definitions::bindings.Image, image_id);
mrb_ary_push(mrb, image_array, image_obj);
}
return image_array;
}
mrb_value image_equal(mrb_state *mrb, mrb_value self) {
mrb_value other;
mrb_get_args(mrb, "o", &other);
@@ -104,7 +146,8 @@ mrb_value image_update(mrb_state *mrb, mrb_value self) {
namespace definitions {
void register_image() {
DEF_CLASS(Image, MRB_ARGS_REQ(2) | MRB_ARGS_OPT(1));
ADD_CLASS_METHOD(Image, "load", image_load, MRB_ARGS_REQ(2) | MRB_ARGS_OPT(1));
ADD_CLASS_METHOD(Image, "load", image_load, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1));
ADD_CLASS_METHOD(Image, "load_set", image_load_set, MRB_ARGS_REQ(3) | MRB_ARGS_OPT(1));
ADD_METHOD(Image, "==", image_equal, MRB_ARGS_REQ(1));
ADD_METHOD(Image, "eql?", image_equal, MRB_ARGS_REQ(1));
ADD_METHOD(Image, "hash", image_hash, MRB_ARGS_NONE());
+63
View File
@@ -113,6 +113,69 @@ uint64_t Window::load_image(const char *path, bool pixel_art) {
return id;
}
std::vector<uint64_t> Window::load_image_set(const char *path, Vec2<float> tile_size, Vec2<float> padding, Vec2<float> offset, bool pixel_art) {
SDL_Surface *surface = IMG_Load(path);
if (!surface) {
fprintf(stderr, "Failed to load image set: %s\n", SDL_GetError());
return {};
}
std::vector<uint64_t> image_ids;
int columns = (int)((surface->w - offset.x + padding.x) / (tile_size.x + padding.x));
int rows = (int)((surface->h - offset.y + padding.y) / (tile_size.y + padding.y));
for (int y = 0; y < rows; y++) {
for (int x = 0; x < columns; x++) {
SDL_Rect src_rect = {
(int)(offset.x + x * (tile_size.x + padding.x)),
(int)(offset.y + y * (tile_size.y + padding.y)),
(int)tile_size.x,
(int)tile_size.y
};
SDL_Surface *tile_surface = SDL_CreateSurface(src_rect.w, src_rect.h, SDL_PIXELFORMAT_RGBA8888);
SDL_BlitSurface(surface, &src_rect, tile_surface, nullptr);
SDL_Texture *texture = SDL_CreateTexture(
renderer,
SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_STREAMING,
tile_surface->w,
tile_surface->h
);
if (!texture) {
fprintf(stderr, "Failed to create texture for tile: %s\n", SDL_GetError());
SDL_DestroySurface(tile_surface);
continue;
}
SDL_UpdateTexture(
texture,
nullptr,
tile_surface->pixels,
tile_surface->pitch
);
if (pixel_art) {
SDL_SetTextureScaleMode(texture, SDL_SCALEMODE_NEAREST);
}
Image *img = new Image{texture, {(float)tile_surface->w, (float)tile_surface->h}};
uint64_t id = image_pool.acquire(img);
image_pool.use(id);
image_ids.push_back(id);
SDL_DestroySurface(tile_surface);
}
}
SDL_DestroySurface(surface);
return image_ids;
}
uint64_t Window::create_image(Vec2<float> size, bool pixel_art) {
SDL_Texture *texture = SDL_CreateTexture(
renderer,