diff --git a/src/main.cpp b/src/main.cpp index a559819..cec8de0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -122,6 +122,9 @@ V4 cpu_tile_infos_buffer[SDL_arraysize(tile_infos)]; Sint32 selected_tile = -1; Sint32 selected_rotation = 0; +bool dragging_tile_change = false; +Sint32 drag_start_pos[2]; + void save_map() { log("Save file is under construction."); FILE* file = fopen("../assets/map/map.sv", "wb"); @@ -1118,10 +1121,7 @@ int main(int argc, char **argv) { if (io.WantCaptureMouse) continue; - float mouse_x = event.button.x; - float mouse_y = event.button.y; - - V2 mouse = remap(V2{ 0, 0 }, V2{ (float)window_width, (float)window_height }, V2{ -1, 1 }, V2{ 1, -1 }, V2{ mouse_x, mouse_y }); + V2 mouse = remap(V2{ 0, 0 }, V2{ (float)window_width, (float)window_height }, V2{ -1, 1 }, V2{ 1, -1 }, V2{ event.button.x, event.button.y }); V3 camera_position = (inverse_view_matrix * V4_(0, 0, 0, 1)).xyz; V3 probe = Unproject(V3_(mouse, .5)); @@ -1133,20 +1133,13 @@ int main(int argc, char **argv) { Sint32 tile_x = roundf(floor_intersection.x); Sint32 tile_y = roundf(floor_intersection.y); - if (selected_tile != -1) { - if(0 <= tile_x && tile_x < map_width && - 0 <= tile_y && tile_y < map_height) { - if (selected_rotation == -1) { - Sint32 rotation = SDL_rand(4); - map_tiles[tile_x + map_width * tile_y] = ((rotation & 3) << 16) | selected_tile; - } else { - map_tiles[tile_x + map_width * tile_y] = ((selected_rotation & 3) << 16) | selected_tile; - } + if(0 <= tile_x && tile_x < map_width && 0 <= tile_y && tile_y < map_height) { + dragging_tile_change = true; - update_buffer(world_buffer, (tile_x + map_width * tile_y) * sizeof(Uint32), sizeof(Uint32), &map_tiles[tile_x + map_width * tile_y]); - } + drag_start_pos[0] = tile_x; + drag_start_pos[1] = tile_y; } - + SDL_Keymod modifiers = SDL_GetModState(); if (modifiers & SDL_KMOD_SHIFT && tile_x <= -1) { if(modifiers & SDL_KMOD_CTRL) @@ -1176,6 +1169,46 @@ int main(int argc, char **argv) { change_map_size('S', 1); } } break; + + case SDL_EVENT_MOUSE_BUTTON_UP: { + if (io.WantCaptureMouse) + continue; + + if (selected_tile != -1 && dragging_tile_change) { + V2 mouse = remap(V2{ 0, 0 }, V2{ (float)window_width, (float)window_height }, V2{ -1, 1 }, V2{ 1, -1 }, V2{ event.button.x, event.button.y }); + V3 camera_position = (inverse_view_matrix * V4_(0, 0, 0, 1)).xyz; + + V3 probe = Unproject(V3_(mouse, .5)); + V3 ray_dir = normalize(probe - camera_position); + + float t = -camera_position.z / ray_dir.z; + V3 floor_intersection = camera_position + (t * ray_dir); + + Sint32 tile_x = clamp(0, (Sint32)roundf(floor_intersection.x), map_width - 1); + Sint32 tile_y = clamp(0, (Sint32)roundf(floor_intersection.y), map_height - 1); + + Sint32 start_x = min(tile_x, drag_start_pos[0]); + Sint32 start_y = min(tile_y, drag_start_pos[1]); + + Sint32 end_x = max(tile_x, drag_start_pos[0]); + Sint32 end_y = max(tile_y, drag_start_pos[1]); + + for (Sint32 y = start_y; y <= end_y; y++) { + for (Sint32 x = start_x; x <= end_x; x++) { + if (selected_rotation == -1) { + Sint32 rotation = SDL_rand(4); + map_tiles[x + map_width * y] = ((rotation & 3) << 16) | selected_tile; + } else { + map_tiles[x + map_width * y] = ((selected_rotation & 3) << 16) | selected_tile; + } + } + } + + update_buffer(world_buffer, 0, map_width * map_height * sizeof(Uint32), map_tiles); + } + + dragging_tile_change = false; + } break;; } }