add tile selector

This commit is contained in:
Sven Balzer 2025-02-27 18:00:28 +01:00
parent 1c8a65e8ad
commit 08e3dfd9d3
2 changed files with 54 additions and 3 deletions

View File

@ -28,7 +28,7 @@
//#define IMGUI_API __attribute__((visibility("default"))) // GCC/Clang: override visibility when set is hidden
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names.
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
//---- Disable all of Dear ImGui or don't implement standard windows/tools.
// It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp.
@ -111,7 +111,7 @@
operator MyVec4() const { return MyVec4(x,y,z,w); }
*/
//---- ...Or use Dear ImGui's own very basic math operators.
//#define IMGUI_DEFINE_MATH_OPERATORS
#define IMGUI_DEFINE_MATH_OPERATORS
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).

View File

@ -102,13 +102,18 @@ TileInfo tile_infos[] = {
{ 0x0001, "../assets/tiles/error.png" },
{ 0x0000, "../assets/tiles/empty.png" },
{ 0x0100, "../assets/tiles/grass_1.png" },
{ 0x0101, "../assets/tiles/grass_2.png" },
{ 0x0102, "../assets/tiles/grass_3.png" },
{ 0x0200, "../assets/tiles/ground_1.png" },
{ 0x0300, "../assets/tiles/water_1.png" },
{ 0x0301, "../assets/tiles/water_2.png" },
};
int tile_atlas_size = 256;
smol_atlas_t *tile_atlas;
Sint32 selected_tile = -1;
void save_map() {
log("Save file is under construction.");
FILE* file = fopen("../assets/map/map.sv", "wb");
@ -528,6 +533,21 @@ void blit(char *dst, Sint32 dst_width, Sint32 dst_x, Sint32 dst_y, char *src, Si
memmove(&dst[((dst_y + y) * dst_width + dst_x) * components], &src[y * width * components], width * components);
}
bool SelectableImage(const char *label, bool selected, SDL_GPUTextureSamplerBinding *image, const ImVec2& image_size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1)) {
const ImGuiContext *context = ImGui::GetCurrentContext();
const ImVec2 padding = context->Style.FramePadding;
bool pressed = ImGui::Selectable(label, selected, 0, image_size + padding * 2.0f);
ImVec2 min = ImGui::GetItemRectMin();
ImVec2 max = ImGui::GetItemRectMax();
if (image)
context->CurrentWindow->DrawList->AddImage((ImTextureID)image, min + padding, max - padding, uv0, uv1);
return pressed;
}
int main(int argc, char **argv) {
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) {
log_error("Failed to initialize SDL (%s). Exiting.", SDL_GetError());
@ -783,6 +803,34 @@ int main(int argc, char **argv) {
ImGui_ImplSDL3_NewFrame();
ImGui::NewFrame();
ImGui::SetNextWindowPos(ImVec2(0, 0));
ImGui::SetNextWindowSizeConstraints(ImVec2(0, window_height), ImVec2(window_width, window_height));
ImGui::SetNextWindowSize(ImVec2(0.2 * window_width, window_height), ImGuiCond_FirstUseEver);
if (ImGui::Begin("Tile Picker", NULL, ImGuiWindowFlags_NoFocusOnAppearing)) {
if (SelectableImage("##tile", selected_tile == -1, NULL, ImVec2(32, 32))) {
selected_tile = -1;
}
for (int i = 0; i < SDL_arraysize(tile_infos); i++) {
ImGui::PushID(i);
SDL_GPUTextureSamplerBinding texture_binding = { .texture = tile_atlas_texture, .sampler = point_sampler };
ImVec2 uv0 = ImVec2(sma_item_x(tile_infos[i].atlas_item) / (float)tile_atlas_size, sma_item_y(tile_infos[i].atlas_item) / (float)tile_atlas_size);
ImVec2 uv1 = ImVec2(uv0.x + sma_item_width(tile_infos[i].atlas_item) / (float)tile_atlas_size, uv0.y + sma_item_height(tile_infos[i].atlas_item) / (float)tile_atlas_size);
float available = ImGui::GetContentRegionAvail().x - ImGui::GetItemRectMax().x;
if (available >= 32)
ImGui::SameLine();
if (SelectableImage("##tile", selected_tile == i, &texture_binding, ImVec2(32, 32), uv0, uv1)) {
selected_tile = i;
}
ImGui::PopID();
}
}
ImGui::End();
if (show_demo_window)
ImGui::ShowDemoWindow(&show_demo_window);
@ -852,6 +900,9 @@ int main(int argc, char **argv) {
if (io.WantCaptureMouse)
continue;
if (selected_tile == -1)
continue;
float mouse_x = event.button.x;
float mouse_y = event.button.y;
@ -883,7 +934,7 @@ int main(int argc, char **argv) {
if(0 <= tile_x && tile_x < map_width &&
0 <= tile_y && tile_y < map_height)
map_tiles[tile_x + map_width * tile_y] = (map_tiles[tile_x + map_width * tile_y] + 1) % 4;
map_tiles[tile_x + map_width * tile_y] = selected_tile;
SDL_Keymod modifiers = SDL_GetModState();
if (modifiers & SDL_KMOD_SHIFT && tile_x == -1) {