make TileKind grid overlap the edge of the map to allow changing edge kinds
This commit is contained in:
+77
-57
@@ -35,7 +35,7 @@ static SDL_GPUGraphicsPipeline *grid_graphics_pipeline;
|
||||
static SDL_GPUGraphicsPipeline *gui_tile_graphics_pipeline;
|
||||
static SDL_GPUSampler *pixel_sampler;
|
||||
|
||||
SDL_GPUTexture *tile_textures_array;
|
||||
static SDL_GPUTexture *tile_textures_array;
|
||||
|
||||
static SDL_GPUBuffer *vertex_buffer;
|
||||
static SDL_GPUBuffer *index_buffer;
|
||||
@@ -63,7 +63,7 @@ static M4x4 inverse_view_matrix = inverse_view(V3_(0.0f, 0.0f, 0.0f), radians(ca
|
||||
static M4x4 projection_matrix = projection (radians(camera_fovy_degrees), 16.0f / 9.0f, NEAR_PLANE);
|
||||
static M4x4 inverse_projection_matrix = inverse_projection(radians(camera_fovy_degrees), 16.0f / 9.0f, NEAR_PLANE);
|
||||
|
||||
static SDL_Time time;
|
||||
static SDL_Time time;
|
||||
|
||||
static bool use_actual_time = true;
|
||||
static SDL_DateTime calendar_time;
|
||||
@@ -174,11 +174,17 @@ struct Player {
|
||||
|
||||
static Player player;
|
||||
|
||||
typedef struct Sint32x2 {
|
||||
Sint32 x;
|
||||
Sint32 y;
|
||||
} Sint32x2;
|
||||
|
||||
struct PerFrame {
|
||||
Sint32 drag_start[2];
|
||||
Sint32 mouse[2];
|
||||
Sint32 map_width;
|
||||
Uint32 flags;
|
||||
Sint32x2 drag_start;
|
||||
Sint32x2 mouse;
|
||||
V2 grid_offset;
|
||||
Sint32 grid_width;
|
||||
Sint32 map_width;
|
||||
};
|
||||
|
||||
static PerFrame per_frame = {};
|
||||
@@ -231,7 +237,7 @@ static Sint32 selected_tile = -1;
|
||||
static Sint32 selected_rotation = 0;
|
||||
|
||||
static bool dragging_tile_change = false;
|
||||
static Sint32 drag_start_pos[2];
|
||||
static V2 drag_start_pos;
|
||||
|
||||
static bool update_buffer(SDL_GPUBuffer *buffer, Uint32 offset, Uint32 num_bytes, void *data) {
|
||||
SDL_GPUTransferBufferCreateInfo transfer_buffer_info = {
|
||||
@@ -688,9 +694,6 @@ static V2 get_floor_intersection_of_mouse(V2 mouse_pos) {
|
||||
float t = -camera_position.z / ray_dir.z;
|
||||
V3 floor_intersection = camera_position + (t * ray_dir);
|
||||
|
||||
if (selected_tile != -1)
|
||||
floor_intersection.xy += V2_(0.5f, 0.5f);
|
||||
|
||||
return floor_intersection.xy;
|
||||
}
|
||||
|
||||
@@ -1167,7 +1170,7 @@ static bool recreate_graphics_pipelines() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool recreate_tile_textures() {
|
||||
static bool recreate_tile_textures() {
|
||||
SDL_PropertiesID tile_textures_array_properties = SDL_CreateProperties();
|
||||
defer(SDL_DestroyProperties(tile_textures_array_properties));
|
||||
|
||||
@@ -1273,12 +1276,12 @@ bool recreate_tile_textures() {
|
||||
return true;
|
||||
}
|
||||
|
||||
int real_mod(int a, int b) {
|
||||
static int real_mod(int a, int b) {
|
||||
int result = a % b;
|
||||
return result >= 0 ? result : result + b;
|
||||
}
|
||||
|
||||
bool imgui_time_picker(const char *label, int time[3]) {
|
||||
static bool imgui_time_picker(const char *label, int time[3]) {
|
||||
bool result = ImGui::DragScalarN(label, ImGuiDataType_S32, time, 3);
|
||||
|
||||
time[1] += time[2] >= 0 ? time[2] / 60 : -1;
|
||||
@@ -1292,6 +1295,9 @@ bool imgui_time_picker(const char *label, int time[3]) {
|
||||
}
|
||||
|
||||
static Uint32 get_corner_info(Sint32 tile_pos_x, Sint32 tile_pos_y) {
|
||||
if (tile_pos_x < 0 || tile_pos_x >= current_map.width || tile_pos_y < 0 || tile_pos_y >= current_map.height)
|
||||
return 0;
|
||||
|
||||
Uint32 tile = current_map.tiles[tile_pos_y * current_map.width + tile_pos_x];
|
||||
|
||||
Uint32 index = tile & 0xffff;
|
||||
@@ -1308,7 +1314,7 @@ static Uint32 get_corner_info(Sint32 tile_pos_x, Sint32 tile_pos_y) {
|
||||
}
|
||||
}
|
||||
|
||||
Uint32 find_matching_tile(Uint32 corner_info) {
|
||||
static Uint32 find_matching_tile(Uint32 corner_info) {
|
||||
Uint32 corner_info_1 = std::rotr(corner_info, 8);
|
||||
Uint32 corner_info_2 = std::rotr(corner_info, 16);
|
||||
Uint32 corner_info_3 = std::rotr(corner_info, 24);
|
||||
@@ -1330,13 +1336,7 @@ Uint32 find_matching_tile(Uint32 corner_info) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void change_map_tile(V2 pos, TileKind kind) {
|
||||
Sint32 pos_x = (Sint32)roundf(pos.x);
|
||||
Sint32 pos_y = (Sint32)roundf(pos.y);
|
||||
|
||||
if (pos_x < 0 || pos_y < 0 || pos_x > current_map.width - 1 || pos_y > current_map.height - 1)
|
||||
return;
|
||||
|
||||
static void change_map_tile(Sint32 pos_x, Sint32 pos_y, TileKind kind) {
|
||||
__m128i corner_infos = _mm_setr_epi32(get_corner_info(pos_x, pos_y + 1), get_corner_info(pos_x + 1, pos_y + 1), get_corner_info(pos_x + 1, pos_y), get_corner_info(pos_x, pos_y));
|
||||
__m128i none_mask = _mm_cmpeq_epi8(corner_infos, _mm_set1_epi8(TILEKIND_NONE));
|
||||
__m128i error_mask = _mm_cmpeq_epi8(corner_infos, _mm_set1_epi8(TILEKIND_ERROR));
|
||||
@@ -1348,10 +1348,17 @@ void change_map_tile(V2 pos, TileKind kind) {
|
||||
Uint32 corner_infos_u32[4];
|
||||
_mm_storeu_si128((__m128i *)&corner_infos_u32, corner_infos);
|
||||
|
||||
current_map.tiles[(pos_y + 1) * current_map.width + pos_x + 0] = find_matching_tile(corner_infos_u32[0]);
|
||||
current_map.tiles[(pos_y + 1) * current_map.width + pos_x + 1] = find_matching_tile(corner_infos_u32[1]);
|
||||
current_map.tiles[(pos_y + 0) * current_map.width + pos_x + 1] = find_matching_tile(corner_infos_u32[2]);
|
||||
current_map.tiles[(pos_y + 0) * current_map.width + pos_x + 0] = find_matching_tile(corner_infos_u32[3]);
|
||||
if (0 <= pos_x + 0 && pos_x + 0 < current_map.width && 0 <= pos_y + 1 && pos_y + 1 < current_map.height)
|
||||
current_map.tiles[(pos_y + 1) * current_map.width + pos_x + 0] = find_matching_tile(corner_infos_u32[0]);
|
||||
|
||||
if (0 <= pos_x + 1 && pos_x + 1 < current_map.width && 0 <= pos_y + 1 && pos_y + 1 < current_map.height)
|
||||
current_map.tiles[(pos_y + 1) * current_map.width + pos_x + 1] = find_matching_tile(corner_infos_u32[1]);
|
||||
|
||||
if (0 <= pos_x + 1 && pos_x + 1 < current_map.width && 0 <= pos_y + 0 && pos_y + 0 < current_map.height)
|
||||
current_map.tiles[(pos_y + 0) * current_map.width + pos_x + 1] = find_matching_tile(corner_infos_u32[2]);
|
||||
|
||||
if (0 <= pos_x + 0 && pos_x + 0 < current_map.width && 0 <= pos_y + 0 && pos_y + 0 < current_map.height)
|
||||
current_map.tiles[(pos_y + 0) * current_map.width + pos_x + 0] = find_matching_tile(corner_infos_u32[3]);
|
||||
|
||||
update_buffer(current_map.gpu_buffer, 0, current_map.width * current_map.height * sizeof(Uint32), current_map.tiles);
|
||||
}
|
||||
@@ -1363,6 +1370,13 @@ static void SameLineOrWrap(const ImVec2& size) {
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
||||
static Sint32x2 grid_tile_pos_from_floor_intersection(V2 floor_intersection) {
|
||||
return {
|
||||
(Sint32)SDL_floorf(floor_intersection.x + (selected_tile == -1 ? 0.5f : 1.0f)),
|
||||
(Sint32)SDL_floorf(floor_intersection.y + (selected_tile == -1 ? 0.5f : 1.0f)),
|
||||
};
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
setup_memory_functions();
|
||||
|
||||
@@ -1820,44 +1834,45 @@ int main(int argc, char **argv) {
|
||||
continue;
|
||||
|
||||
V2 floor_intersection = get_floor_intersection_of_mouse(V2_(event.button.x, event.button.y));
|
||||
Sint32x2 tile_pos = grid_tile_pos_from_floor_intersection(floor_intersection);
|
||||
|
||||
Sint32 tile_x = roundf(floor_intersection.x);
|
||||
Sint32 tile_y = roundf(floor_intersection.y);
|
||||
drag_start_pos = floor_intersection;
|
||||
|
||||
if(0 <= tile_x && tile_x < current_map.width && 0 <= tile_y && tile_y < current_map.height) {
|
||||
dragging_tile_change = true;
|
||||
if (selected_tile_kind != -1) {
|
||||
change_map_tile(tile_pos.x, tile_pos.y, (TileKind)selected_tile_kind);
|
||||
|
||||
drag_start_pos[0] = tile_x;
|
||||
drag_start_pos[1] = tile_y;
|
||||
|
||||
if (selected_tile_kind != -1) {
|
||||
change_map_tile(floor_intersection, (TileKind)selected_tile_kind);
|
||||
if (-1 <= tile_pos.x && tile_pos.x < current_map.width && -1 <= tile_pos.y && tile_pos.y < current_map.height) {
|
||||
dragging_tile_change = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 <= tile_pos.x && tile_pos.x < current_map.width && 0 <= tile_pos.y && tile_pos.y < current_map.height) {
|
||||
dragging_tile_change = true;
|
||||
}
|
||||
|
||||
SDL_Keymod modifiers = SDL_GetModState();
|
||||
if (modifiers & SDL_KMOD_SHIFT && tile_x <= -1) {
|
||||
if (modifiers & SDL_KMOD_SHIFT && tile_pos.x <= -1) {
|
||||
if(modifiers & SDL_KMOD_CTRL)
|
||||
change_map_size(¤t_map, 'W', -1);
|
||||
else
|
||||
change_map_size(¤t_map, 'W', 1);
|
||||
}
|
||||
|
||||
if (modifiers & SDL_KMOD_SHIFT && tile_x == current_map.width) {
|
||||
if (modifiers & SDL_KMOD_SHIFT && tile_pos.x == current_map.width) {
|
||||
if (modifiers & SDL_KMOD_CTRL)
|
||||
change_map_size(¤t_map, 'E', -1);
|
||||
else
|
||||
change_map_size(¤t_map, 'E', 1);
|
||||
}
|
||||
|
||||
if (modifiers & SDL_KMOD_SHIFT && tile_y <= -1) {
|
||||
if (modifiers & SDL_KMOD_SHIFT && tile_pos.y <= -1) {
|
||||
if (modifiers & SDL_KMOD_CTRL)
|
||||
change_map_size(¤t_map, 'N', -1);
|
||||
else
|
||||
change_map_size(¤t_map, 'N', 1);
|
||||
}
|
||||
|
||||
if (modifiers & SDL_KMOD_SHIFT && tile_y == current_map.height) {
|
||||
if (modifiers & SDL_KMOD_SHIFT && tile_pos.y == current_map.height) {
|
||||
if (modifiers & SDL_KMOD_CTRL)
|
||||
change_map_size(¤t_map, 'S', -1);
|
||||
else
|
||||
@@ -1871,15 +1886,18 @@ int main(int argc, char **argv) {
|
||||
|
||||
if (selected_tile != -1 && dragging_tile_change) {
|
||||
V2 floor_intersection = get_floor_intersection_of_mouse(V2_(event.button.x, event.button.y));
|
||||
Sint32x2 tile_pos = grid_tile_pos_from_floor_intersection(floor_intersection);
|
||||
|
||||
Sint32 tile_x = clamp(0, (Sint32)roundf(floor_intersection.x), current_map.width - 1);
|
||||
Sint32 tile_y = clamp(0, (Sint32)roundf(floor_intersection.y), current_map.height - 1);
|
||||
Sint32 tile_x = clamp(0, tile_pos.x, current_map.width - 1);
|
||||
Sint32 tile_y = clamp(0, tile_pos.y, current_map.height - 1);
|
||||
|
||||
Sint32 start_x = min(tile_x, drag_start_pos[0]);
|
||||
Sint32 start_y = min(tile_y, drag_start_pos[1]);
|
||||
Sint32x2 drag_start = grid_tile_pos_from_floor_intersection(drag_start_pos);
|
||||
|
||||
Sint32 end_x = max(tile_x, drag_start_pos[0]);
|
||||
Sint32 end_y = max(tile_y, drag_start_pos[1]);
|
||||
Sint32 start_x = min(tile_x, drag_start.x);
|
||||
Sint32 start_y = min(tile_y, drag_start.y);
|
||||
|
||||
Sint32 end_x = max(tile_x, drag_start.x);
|
||||
Sint32 end_y = max(tile_y, drag_start.y);
|
||||
|
||||
for (Sint32 y = start_y; y <= end_y; y++) {
|
||||
for (Sint32 x = start_x; x <= end_x; x++) {
|
||||
@@ -1900,11 +1918,11 @@ int main(int argc, char **argv) {
|
||||
|
||||
case SDL_EVENT_MOUSE_MOTION: {
|
||||
mouse_pos = V2_(event.motion.x, event.motion.y);
|
||||
V2 floor_intersection = get_floor_intersection_of_mouse(mouse_pos);
|
||||
|
||||
if (selected_tile_kind != -1 && dragging_tile_change) {
|
||||
V2 floor_intersection = get_floor_intersection_of_mouse(mouse_pos);
|
||||
change_map_tile(floor_intersection, (TileKind)selected_tile_kind);
|
||||
Sint32x2 tile_pos = grid_tile_pos_from_floor_intersection(floor_intersection);
|
||||
change_map_tile(tile_pos.x, tile_pos.y, (TileKind)selected_tile_kind);
|
||||
}
|
||||
} break;
|
||||
|
||||
@@ -1992,20 +2010,18 @@ int main(int argc, char **argv) {
|
||||
SDL_PushGPUVertexUniformData(command_buffer, 0, &view_projection_matrix, sizeof(view_projection_matrix));
|
||||
|
||||
V2 floor_intersection = get_floor_intersection_of_mouse(mouse_pos);
|
||||
Sint32 tile_x = roundf(floor_intersection.x);
|
||||
Sint32 tile_y = roundf(floor_intersection.y);
|
||||
Sint32x2 tile_pos = grid_tile_pos_from_floor_intersection(floor_intersection);
|
||||
|
||||
per_frame.map_width = current_map.width;
|
||||
per_frame.mouse[0] = tile_x;
|
||||
per_frame.mouse[1] = tile_y;
|
||||
per_frame.flags = selected_tile != -1;
|
||||
per_frame.map_width = current_map.width;
|
||||
per_frame.grid_width = selected_tile != -1 ? current_map.width : current_map.width + 1;
|
||||
per_frame.grid_offset = selected_tile != -1 ? V2_(-0.5f, -0.5f) : V2_(-1.0f, -1.0f);
|
||||
per_frame.mouse = tile_pos;
|
||||
|
||||
if (dragging_tile_change && selected_tile != -1) {
|
||||
per_frame.drag_start[0] = drag_start_pos[0];
|
||||
per_frame.drag_start[1] = drag_start_pos[1];
|
||||
Sint32x2 grid_tile_pos = grid_tile_pos_from_floor_intersection(drag_start_pos);
|
||||
per_frame.drag_start = grid_tile_pos;
|
||||
} else {
|
||||
per_frame.drag_start[0] = tile_x;
|
||||
per_frame.drag_start[1] = tile_y;
|
||||
per_frame.drag_start = tile_pos;
|
||||
}
|
||||
|
||||
SDL_PushGPUVertexUniformData(command_buffer, 1, &per_frame, sizeof(per_frame));
|
||||
@@ -2098,12 +2114,16 @@ int main(int argc, char **argv) {
|
||||
{ 1.0f, 1.0f, 1.0f, 0.1f },
|
||||
{ 1.0f, 0.0f, 1.0f, 1.0f },
|
||||
};
|
||||
|
||||
Uint32 num_grid_cells = current_map.height * current_map.width;
|
||||
if (selected_tile_kind != -1)
|
||||
num_grid_cells = (current_map.height + 1) * (current_map.width + 1);
|
||||
|
||||
SDL_BindGPUGraphicsPipeline(render_pass, grid_graphics_pipeline);
|
||||
SDL_BindGPUIndexBuffer(render_pass, &index_buffer_binding, SDL_GPU_INDEXELEMENTSIZE_16BIT);
|
||||
SDL_BindGPUVertexBuffers(render_pass, 0, vertex_buffers, SDL_arraysize(vertex_buffers));
|
||||
SDL_PushGPUFragmentUniformData(command_buffer, 0, &tints, sizeof(tints));
|
||||
SDL_DrawGPUIndexedPrimitives(render_pass, SDL_arraysize(grid_indices), current_map.height * current_map.width, 0, 0, 0);
|
||||
SDL_DrawGPUIndexedPrimitives(render_pass, SDL_arraysize(grid_indices), num_grid_cells, 0, 0, 0);
|
||||
}
|
||||
|
||||
SDL_EndGPURenderPass(render_pass);
|
||||
|
||||
Reference in New Issue
Block a user