diff --git a/client/include/engine.h b/client/include/engine.h index cb45372..cbef20c 100644 --- a/client/include/engine.h +++ b/client/include/engine.h @@ -8,17 +8,17 @@ typedef struct ClientContextStruct ClientContext; -typedef bool (*app_text_callback)( +typedef void (*app_text_callback)( ClientContext* context, unsigned int codepoint); -typedef bool (*app_key_callback)( +typedef void (*app_key_callback)( ClientContext* context, int key, int action, int mods); -typedef bool (*app_button_callback)( +typedef void (*app_button_callback)( ClientContext* context, float x, float y, @@ -26,12 +26,12 @@ typedef bool (*app_button_callback)( int action, int mods); -typedef bool (*app_scroll_callback)( +typedef void (*app_scroll_callback)( ClientContext* context, double x, double y); -typedef bool (*app_cursor_callback)( +typedef void (*app_cursor_callback)( ClientContext* context, float x, float y); @@ -53,15 +53,12 @@ struct ClientContextStruct { vec3 velocity; vec2 rotation; - int32_t key_spin[2]; - vec2 cur_spin; + int32_t spin[2]; double distance; int32_t zoom; - bool camera_mode; - float key_spin_speed; - float cur_spin_speed; + float spin_speed; float zoom_speed; float move_speed; diff --git a/client/include/gpu.h b/client/include/gpu.h index 371db0b..ec1f5fd 100644 --- a/client/include/gpu.h +++ b/client/include/gpu.h @@ -150,6 +150,8 @@ typedef struct RenderContextStruct { VkRenderPass render_pass; VkCommandBuffer* swapchain_command_buffers; + uint64_t swapchain_command_buffer_record_id; + uint64_t* swapchain_command_buffer_record_ids; FrameContext frame[MAX_FRAMES_IN_FLIGHT]; diff --git a/client/include/ui.h b/client/include/ui.h index 86f0bf1..609be4d 100644 --- a/client/include/ui.h +++ b/client/include/ui.h @@ -266,11 +266,16 @@ VkResult load_texture( UIContext* context, uint32_t* index); -VkResult create_container( +VkResult load_container( ContainerInput* container, RenderContext* gpu, UIContext* context); +VkResult unload_container( + uint32_t id, + RenderContext* gpu, + UIContext* context); + VkResult create_layer( uint32_t index, LayerInput* input, @@ -289,7 +294,7 @@ VkResult update_ui_context_resolution( RenderContext* gpu); VkResult update_ui_string( - char* string, + const char* string, uint32_t container_id, uint32_t layer_index, uint32_t string_index, diff --git a/client/src/editor.c b/client/src/editor.c index ffc058c..79672f9 100644 --- a/client/src/editor.c +++ b/client/src/editor.c @@ -7,20 +7,54 @@ #include #include -#define COLOR_PICK_CONTAINER_ID 0x03 -typedef struct EditorDataStruct { - uint32_t selected_region; +#define COLOR_PICK_CONTAINER_ID 0x02 +#define MODE_STRING_CONTAINER_ID 0x01 - uint32_t clicked_region; - uint32_t clicked_hex; - uint32_t clicked_vertex; +typedef enum EditorModeEnum { + MODE_NONE, + MODE_VERTEX, + MODE_NEIGHBOR, + MODE_HEX, + MODE_REGION, + MODE_MAX_ENUM, +} EditorMode; + +const char* ModeStrings[] = { + "None", + "Vertex", + "Neighbor", + "Hex", + "Region", +}; + +typedef struct EditorDataStruct EditorData; + +typedef void(*ModeKeyCallback)(EditorData* data, ClientContext* context, int action, int mods); + +typedef struct ModeKeyStruct { + int key; + ModeKeyCallback logic; +} ModeKey; + +struct EditorDataStruct { + EditorMode mode; + + ModeKey* mode_keys[MODE_MAX_ENUM]; + uint32_t mode_key_counts[MODE_MAX_ENUM]; + + uint32_t selected_max; + uint32_t selected_count; + + uint32_t* selected_regions; + uint32_t* selected_hexes; + uint32_t* selected_vertices; double current_hsv[3]; vec4 current; vec4 saved[12]; char string[10]; int string_len; -} EditorData; +}; uint32_t hex_color(vec4 color) { @@ -475,6 +509,7 @@ SAVED_COLOR_BUTTON_CALLBACK(11); .button = saved_color_button_callback_##n, \ } +// TODO: Make load from current state instead of having a default state VkResult color_ui(ClientContext* context) { GPUString strings[] = { { @@ -691,7 +726,7 @@ VkResult color_ui(ClientContext* context) { .callback_count = sizeof(callbacks)/sizeof(UICallbacks), }; - return create_container(&container, &context->render, &context->ui); + return load_container(&container, &context->render, &context->ui); } VkResult hex_info_ui(ClientContext* context) { @@ -789,495 +824,252 @@ VkResult hex_info_ui(ClientContext* context) { .layer_count = 1, }; - return create_container(&container, &context->render, &context->ui); + return load_container(&container, &context->render, &context->ui); } -VkResult region_info_ui(ClientContext* context) { +VkResult mode_string_ui(ClientContext* context) { + VkResult result; - GPUString strings[] = { - { - .pos = {0, 33}, - .color = {1, 1, 1, 1}, - .size = 32, - .offset = 0, - .length = 0, - .font = 0, - }, - { - .pos = {0, 33 + 1*40}, - .color = {1, 1, 1, 1}, - .size = 32, - .offset = 11, - .length = 0, - .font = 0, - }, - { - .pos = {0, 33 + 2*40}, - .color = {1, 1, 1, 1}, - .size = 32, - .offset = 18, - .length = 0, - .font = 0, - }, - { - .pos = {0, 33 + 3*40}, - .color = {1, 1, 1, 1}, - .size = 32, - .offset = 25, - .length = 0, - .font = 0, - }, + GPUString string = { + .pos = {0, 32}, + .font = 0, + .size = 32, + .length = strlen(ModeStrings[MODE_NONE]), + .color = {1, 1, 1, 1}, }; - GPUDrawable drawables[] = { - { - .pos = {0, 0}, - .size = {225, 155}, - .color = {{0.4, 0.4, 0.4, 0.8}, {0.4, 0.4, 0.4, 0.8}, {0.4, 0.4, 0.4, 0.8}, {0.4, 0.4, 0.4, 0.8}}, - }, - }; + uint32_t codes[8]; + VK_RESULT(map_string(ModeStrings[MODE_NONE], codes, 0, 0, &context->ui)); LayerInput layer = { - .strings = strings, - .num_strings = sizeof(strings)/sizeof(GPUString), - .max_strings = sizeof(strings)/sizeof(GPUString) + 4, - .max_codes = 100, - .drawables = drawables, - .num_drawables = sizeof(drawables)/sizeof(GPUDrawable), + .max_codes = 8, + .codes = codes, + .num_codes = strlen(ModeStrings[MODE_NONE]), + .num_strings = 1, + .strings = &string, }; ContainerInput container = { - .id = 0x01, - .size = {225, 155}, - .offset = {0, 0}, - .anchor = ANCHOR_TOP_RIGHT, - .layers = &layer, + .id = MODE_STRING_CONTAINER_ID, .layer_count = 1, + .layers = &layer, + .anchor = ANCHOR_TOP_LEFT, + .size = {160, 40}, }; - return create_container(&container, &context->render, &context->ui); + return load_container(&container, &context->render, &context->ui); } -VkResult update_region_info_ui(ClientContext* context) { - char temp[20]; - VkResult result; +VkResult update_mode_string(ClientContext* context, EditorData* data) { + return update_ui_string(ModeStrings[data->mode], MODE_STRING_CONTAINER_ID, 0, 0, &context->ui, &context->render); +} + +void editor_key_callback(ClientContext* context, int key, int action, int mods) { EditorData* data = context->app_data; + for(uint32_t i = 0; i < data->mode_key_counts[data->mode]; i++) { + if(data->mode_keys[data->mode][i].key == key) { + data->mode_keys[data->mode][i].logic(data, context, action, mods); + return; + } + } - if(data->selected_region >= MAX_LOADED_REGIONS) { - snprintf(temp, - sizeof(temp), - ""); - VK_RESULT(update_ui_string(temp, 0x01, 0, 0, &context->ui, &context->render)); - - snprintf( - temp, - sizeof(temp), - ""); - VK_RESULT(update_ui_string(temp, 0x01, 0, 1, &context->ui, &context->render)); - - snprintf( - temp, - sizeof(temp), - ""); - VK_RESULT(update_ui_string(temp, 0x01, 0, 2, &context->ui, &context->render)); - - snprintf( - temp, - sizeof(temp), - ""); - VK_RESULT(update_ui_string(temp, 0x01, 0, 3, &context->ui, &context->render)); - } else { - HexRegion* selected_region = context->hex.regions[data->selected_region]; - snprintf(temp, - sizeof(temp), - "Region %4d", data->selected_region); - VK_RESULT(update_ui_string(temp, 0x01, 0, 0, &context->ui, &context->render)); - - snprintf( - temp, - sizeof(temp), - "Q: %4d", selected_region->data.position.q); - VK_RESULT(update_ui_string(temp, 0x01, 0, 1, &context->ui, &context->render)); - - snprintf( - temp, - sizeof(temp), - "R: %4d", selected_region->data.position.r); - VK_RESULT(update_ui_string(temp, 0x01, 0, 2, &context->ui, &context->render)); - - snprintf( - temp, - sizeof(temp), - "Y: %4d", selected_region->data.y); - VK_RESULT(update_ui_string(temp, 0x01, 0, 3, &context->ui, &context->render)); + for(uint32_t i = 0; i < data->mode_key_counts[MODE_NONE]; i++) { + if(data->mode_keys[MODE_NONE][i].key == key) { + data->mode_keys[MODE_NONE][i].logic(data, context, action, mods); + return; + } } +} - return VK_SUCCESS; +void spin_cam(ClientContext* context, int action, int mods, unsigned int axis, float amount) { + (void)mods; + if(action == GLFW_PRESS) context->spin[axis] += amount; + else if(action == GLFW_RELEASE) context->spin[axis] -= amount; } -VkResult update_hex_info_ui(ClientContext* context) { - char temp[20]; - VkResult result; - EditorData* data = context->app_data; +void spin_cam_left(EditorData* data, ClientContext* context, int action, int mods) { + (void)data; + spin_cam(context, action, mods, 0, -1); +} +void spin_cam_right(EditorData* data, ClientContext* context, int action, int mods) { + (void)data; + spin_cam(context, action, mods, 0, 1); +} - if(data->clicked_region >= MAX_LOADED_REGIONS) { - snprintf( - temp, - sizeof(temp), - ""); - VK_RESULT(update_ui_string(temp, 0x02, 0, 0, &context->ui, &context->render)); - - snprintf( - temp, - sizeof(temp), - ""); - VK_RESULT(update_ui_string(temp, 0x02, 0, 1, &context->ui, &context->render)); - - snprintf( - temp, - sizeof(temp), - ""); - VK_RESULT(update_ui_string(temp, 0x02, 0, 2, &context->ui, &context->render)); - - snprintf( - temp, - sizeof(temp), - ""); - VK_RESULT(update_ui_string(temp, 0x02, 0, 3, &context->ui, &context->render)); - - snprintf( - temp, - sizeof(temp), - ""); - VK_RESULT(update_ui_string(temp, 0x02, 0, 4, &context->ui, &context->render)); - - snprintf( - temp, - sizeof(temp), - ""); - VK_RESULT(update_ui_string(temp, 0x02, 0, 5, &context->ui, &context->render)); - - snprintf( - temp, - sizeof(temp), - ""); - VK_RESULT(update_ui_string(temp, 0x02, 0, 6, &context->ui, &context->render)); - - snprintf( - temp, - sizeof(temp), - ""); - VK_RESULT(update_ui_string(temp, 0x02, 0, 7, &context->ui, &context->render)); - } else { - HexRegion* region = context->hex.regions[data->clicked_region]; - GPUHex* hex = ®ion->data.hexes[data->clicked_hex]; - snprintf(temp, - sizeof(temp), - "%d-%d", - data->clicked_region, - data->clicked_hex); - VK_RESULT(update_ui_string(temp, 0x02, 0, 0, &context->ui, &context->render)); - - HexCoord hex_world; - hex_qr(data->clicked_hex, &hex_world); - - fprintf(stderr, "region: %d\n", data->clicked_region); - HexCoord region_coord = {region->data.position.q, region->data.position.r}; - HexCoord region_world; - region_qr(region_coord, ®ion_world); - hex_add(region_world, &hex_world); - - snprintf( - temp, - sizeof(temp), - "%d, %d, %d, %d", - hex_world.q, - hex_world.r, - region->data.y, - data->clicked_vertex); - VK_RESULT(update_ui_string(temp, 0x02, 0, 1, &context->ui, &context->render)); - - snprintf( - temp, - sizeof(temp), - "%02.02f %02.02f %02.02f", - hex->height[0], hex->height[1], hex->height[2]); - VK_RESULT(update_ui_string(temp, 0x02, 0, 2, &context->ui, &context->render)); - - snprintf( - temp, - sizeof(temp), - "%02.02f %02.02f %02.02f", - hex->height[3], hex->height[4], hex->height[5]); - VK_RESULT(update_ui_string(temp, 0x02, 0, 3, &context->ui, &context->render)); - - snprintf( - temp, - sizeof(temp), - "%08X", - hex->color[0]); - VK_RESULT(update_ui_string(temp, 0x02, 0, 4, &context->ui, &context->render)); - - snprintf( - temp, - sizeof(temp), - "%08X %08X", - hex->color[1], hex->color[2]); - VK_RESULT(update_ui_string(temp, 0x02, 0, 5, &context->ui, &context->render)); - - snprintf( - temp, - sizeof(temp), - "%08X %08X", - hex->color[3], hex->color[4]); - VK_RESULT(update_ui_string(temp, 0x02, 0, 6, &context->ui, &context->render)); - - snprintf( - temp, - sizeof(temp), - "%08X %08X", - hex->color[5], hex->color[6]); - VK_RESULT(update_ui_string(temp, 0x02, 0, 7, &context->ui, &context->render)); - } +void spin_cam_up(EditorData* data, ClientContext* context, int action, int mods) { + (void)data; + spin_cam(context, action, mods, 1, 1); +} - return VK_SUCCESS; +void spin_cam_down(EditorData* data, ClientContext* context, int action, int mods) { + (void)data; + spin_cam(context, action, mods, 1, -1); } -bool editor_key_callback(ClientContext* context, int key, int action, int mods) { - uint32_t start, next_region; +void move_cam(ClientContext* context, int action, int mods, unsigned int axis, float amount) { + (void)mods; + if(action == GLFW_PRESS) context->velocity[axis] += amount; + else if(action == GLFW_RELEASE) context->velocity[axis] -= amount; +} - if(action != GLFW_PRESS) return false; +void move_cam_up(EditorData* data, ClientContext* context, int action, int mods) { + (void)data; + move_cam(context, action, mods, 1, 1); +} - EditorData* data = context->app_data; - HexRegion* region = NULL; - - switch(key) { - case GLFW_KEY_EQUAL: - data->selected_region = add_hex_region(context); - update_region_info_ui(context); - update_hex_info_ui(context); - break; - - case GLFW_KEY_MINUS: - if(data->selected_region < MAX_LOADED_REGIONS) { - free_hex_region(data->selected_region, &context->hex, &context->render); - start = data->selected_region; - next_region = start; - do { - next_region -= 1; - if(next_region > MAX_LOADED_REGIONS) next_region = MAX_LOADED_REGIONS; - if(next_region != MAX_LOADED_REGIONS && context->hex.regions[next_region] != NULL) break; - } while(next_region != start); - if(next_region == start) { - data->selected_region = MAX_LOADED_REGIONS; - } else { - data->selected_region = next_region; - } - update_region_info_ui(context); - update_hex_info_ui(context); - } - break; - - case GLFW_KEY_LEFT_BRACKET: - start = data->selected_region; - next_region = start; - do { - next_region -= 1; - if(next_region > MAX_LOADED_REGIONS) next_region = MAX_LOADED_REGIONS; - if(next_region != MAX_LOADED_REGIONS && context->hex.regions[next_region] != NULL) break; - } while(next_region != start); - data->selected_region = next_region; - update_region_info_ui(context); - break; - - case GLFW_KEY_RIGHT_BRACKET: - start = data->selected_region; - next_region = start; - do { - next_region += 1; - if(next_region > MAX_LOADED_REGIONS) next_region = 0; - if(next_region != MAX_LOADED_REGIONS && context->hex.regions[next_region] != NULL) break; - } while(next_region != start); - data->selected_region = next_region; - update_region_info_ui(context); - break; - - case GLFW_KEY_I: - if(data->selected_region < MAX_LOADED_REGIONS) { - context->hex.regions[data->selected_region]->data.position.q += 1; - add_transfer( - &context->hex.regions[data->selected_region]->data.position, - context->hex.regions[data->selected_region]->region, - offsetof(GPUHexRegion, position), - sizeof(uint32_t), - context->render.current_frame, - &context->render); - } - update_region_info_ui(context); - break; - case GLFW_KEY_K: - if(data->selected_region < MAX_LOADED_REGIONS) { - context->hex.regions[data->selected_region]->data.position.q -= 1; - add_transfer( - &context->hex.regions[data->selected_region]->data.position.q, - context->hex.regions[data->selected_region]->region, - offsetof(GPUHexRegion, position) + offsetof(HexCoord, q), - sizeof(uint32_t), - context->render.current_frame, - &context->render); - } - update_region_info_ui(context); - break; - case GLFW_KEY_J: - if(data->selected_region < MAX_LOADED_REGIONS) { - context->hex.regions[data->selected_region]->data.position.r += 1; - add_transfer( - &context->hex.regions[data->selected_region]->data.position.r, - context->hex.regions[data->selected_region]->region, - offsetof(GPUHexRegion, position) + offsetof(HexCoord, r), - sizeof(uint32_t), - context->render.current_frame, - &context->render); - } - update_region_info_ui(context); - break; - case GLFW_KEY_L: - if(data->selected_region < MAX_LOADED_REGIONS) { - context->hex.regions[data->selected_region]->data.position.r -= 1; - add_transfer( - &context->hex.regions[data->selected_region]->data.position.r, - context->hex.regions[data->selected_region]->region, - offsetof(GPUHexRegion, position) + offsetof(HexCoord, r), - sizeof(uint32_t), - context->render.current_frame, - &context->render); - } - update_region_info_ui(context); - break; - case GLFW_KEY_O: - if(data->selected_region < MAX_LOADED_REGIONS) { - context->hex.regions[data->selected_region]->data.y += 1; - add_transfer( - &context->hex.regions[data->selected_region]->data.y, - context->hex.regions[data->selected_region]->region, - offsetof(GPUHexRegion, y), - sizeof(int32_t), - context->render.current_frame, - &context->render); - } - update_region_info_ui(context); - break; - case GLFW_KEY_U: - if(data->selected_region < MAX_LOADED_REGIONS) { - context->hex.regions[data->selected_region]->data.y -= 1; - add_transfer( - &context->hex.regions[data->selected_region]->data.y, - context->hex.regions[data->selected_region]->region, - offsetof(GPUHexRegion, y), - sizeof(int32_t), - context->render.current_frame, - &context->render); - } - update_region_info_ui(context); - break; - - case GLFW_KEY_Y: - if(data->clicked_region < MAX_LOADED_REGIONS && data->clicked_vertex != 0) { - region = context->hex.regions[data->clicked_region]; - float height = region->data.hexes[data->clicked_hex].height[data->clicked_vertex-1] + 0.1; - - if(~mods & GLFW_MOD_CONTROL) { - uint32_t n_vertex[2], n_hex[2]; - HexCoord n_region[2]; - HexCoord world, region_center; - - region_qr(region->data.position, ®ion_center); - hex_qr(data->clicked_hex, &world); - hex_add(region_center, &world); - hex_vertex_neighbors(data->clicked_vertex, world, n_vertex, n_region, n_hex); - - uint32_t n0, n1; - first_matching_region(n_region[0], region->data.y, &n0, &context->hex); - first_matching_region(n_region[1], region->data.y, &n1, &context->hex); - - if(n0 != MAX_LOADED_REGIONS) set_vertex_height(height, n0, n_hex[0], n_vertex[0], context); - if(n1 != MAX_LOADED_REGIONS) set_vertex_height(height, n1, n_hex[1], n_vertex[1], context); - } - set_vertex_height(height, data->clicked_region, data->clicked_hex, data->clicked_vertex, context); - update_hex_info_ui(context); - } - break; +void move_cam_down(EditorData* data, ClientContext* context, int action, int mods) { + (void)data; + move_cam(context, action, mods, 1, -1); +} - case GLFW_KEY_H: - if(data->clicked_region < MAX_LOADED_REGIONS && data->clicked_vertex != 0) { - region = context->hex.regions[data->clicked_region]; - float height = region->data.hexes[data->clicked_hex].height[data->clicked_vertex-1] - 0.1; +void move_cam_left(EditorData* data, ClientContext* context, int action, int mods) { + (void)data; + move_cam(context, action, mods, 0, -1); +} - if(~mods & GLFW_MOD_CONTROL) { - uint32_t n_vertex[2], n_hex[2]; - HexCoord n_region[2]; - HexCoord world, region_center; +void move_cam_right(EditorData* data, ClientContext* context, int action, int mods) { + (void)data; + move_cam(context, action, mods, 0, 1); +} - region_qr(region->data.position, ®ion_center); - hex_qr(data->clicked_hex, &world); - hex_add(region_center, &world); - hex_vertex_neighbors(data->clicked_vertex, world, n_vertex, n_region, n_hex); +void move_cam_forward(EditorData* data, ClientContext* context, int action, int mods) { + (void)data; + move_cam(context, action, mods, 2, 1); +} - uint32_t n0, n1; - first_matching_region(n_region[0], region->data.y, &n0, &context->hex); - first_matching_region(n_region[1], region->data.y, &n1, &context->hex); +void move_cam_backwards(EditorData* data, ClientContext* context, int action, int mods) { + (void)data; + move_cam(context, action, mods, 2, -1); +} - if(n0 != MAX_LOADED_REGIONS) set_vertex_height(height, n0, n_hex[0], n_vertex[0], context); - if(n1 != MAX_LOADED_REGIONS) set_vertex_height(height, n1, n_hex[1], n_vertex[1], context); - } - set_vertex_height(height, data->clicked_region, data->clicked_hex, data->clicked_vertex, context); - update_hex_info_ui(context); - } - break; - - case GLFW_KEY_E: - if(data->clicked_region < MAX_LOADED_REGIONS) { - region = context->hex.regions[data->clicked_region]; - uint32_t n_vertex[2], n_hex[2]; - HexCoord n_region[2]; - HexCoord world, region_center; - - if(data->clicked_vertex != 0 && data->clicked_vertex <= 6) { - region_qr(region->data.position, ®ion_center); - hex_qr(data->clicked_hex, &world); - hex_add(region_center, &world); - hex_vertex_neighbors(data->clicked_vertex, world, n_vertex, n_region, n_hex); - - uint32_t n0, n1; - first_matching_region(n_region[0], region->data.y, &n0, &context->hex); - first_matching_region(n_region[1], region->data.y, &n1, &context->hex); - - if(n0 != MAX_LOADED_REGIONS) set_vertex_color(data->current, n0, n_hex[0], n_vertex[0], context); - if(n1 != MAX_LOADED_REGIONS) set_vertex_color(data->current, n1, n_hex[1], n_vertex[1], context); - } - set_vertex_color(data->current, data->clicked_region, data->clicked_hex, data->clicked_vertex, context); - update_hex_info_ui(context); - } - break; +void clear_mode(EditorData* data, ClientContext* context, int action, int mods) { + (void)mods; + if(action == GLFW_PRESS) { + data->mode = MODE_NONE; + update_mode_string(context, data); + data->selected_count = 0; + unload_container(COLOR_PICK_CONTAINER_ID, &context->render, &context->ui); + } +} + +void enter_vertex_mode(EditorData* data, ClientContext* context, int action, int mods) { + (void)mods; + if(action == GLFW_PRESS) { + data->mode = MODE_VERTEX; + update_mode_string(context, data); + data->selected_count = 0; + color_ui(context); + } +} + +void enter_neighbor_mode(EditorData* data, ClientContext* context, int action, int mods) { + (void)mods; + if(action == GLFW_PRESS) { + data->mode = MODE_NEIGHBOR; + update_mode_string(context, data); + data->selected_count = 0; + color_ui(context); + } +} + +void enter_hex_mode(EditorData* data, ClientContext* context, int action, int mods) { + (void)mods; + if(action == GLFW_PRESS) { + data->mode = MODE_HEX; + update_mode_string(context, data); + data->selected_count = 0; + color_ui(context); } +} - return false; +void enter_region_mode(EditorData* data, ClientContext* context, int action, int mods) { + (void)mods; + if(action == GLFW_PRESS) { + data->mode = MODE_REGION; + update_mode_string(context, data); + data->selected_count = 0; + unload_container(COLOR_PICK_CONTAINER_ID, &context->render, &context->ui); + } } void editor_startup(ClientContext* context) { - region_info_ui(context); - hex_info_ui(context); - color_ui(context); + mode_string_ui(context); + // TODO: Remove when region mode is implemented + add_hex_region(context); +} + +void resize_selected(EditorData* data, unsigned int size) { + uint32_t* new_regions = malloc(sizeof(uint32_t)*size); + uint32_t* new_hexes = malloc(sizeof(uint32_t)*size); + uint32_t* new_vertices = malloc(sizeof(uint32_t)*size); + + if(data->selected_regions != NULL) { + memcpy(new_regions, data->selected_regions, data->selected_count); + free(data->selected_regions); + } + + if(data->selected_hexes != NULL) { + memcpy(new_hexes, data->selected_hexes, data->selected_count); + free(data->selected_hexes); + } + + if(data->selected_vertices != NULL) { + memcpy(new_vertices, data->selected_vertices, data->selected_count); + } + + data->selected_regions = new_regions; + data->selected_hexes = new_hexes; + data->selected_vertices = new_vertices; + data->selected_max = size; } int main() { EditorData* data = malloc(sizeof(EditorData)); memset(data, 0, sizeof(EditorData)); - data->selected_region = MAX_LOADED_REGIONS; - data->clicked_region = MAX_LOADED_REGIONS; - data->clicked_hex = UINT32_MAX; - data->clicked_vertex = UINT32_MAX; + data->selected_count = 0; + resize_selected(data, 1); + + data->mode_key_counts[MODE_NONE] = 15; + for(int i = 0; i < MODE_MAX_ENUM; i++) { + data->mode_keys[i] = malloc(sizeof(ModeKey)*data->mode_key_counts[i]); + } + + // Mode Switches + data->mode_keys[MODE_NONE][0].key = GLFW_KEY_ESCAPE; + data->mode_keys[MODE_NONE][0].logic = clear_mode; + data->mode_keys[MODE_NONE][1].key = GLFW_KEY_V; + data->mode_keys[MODE_NONE][1].logic = enter_vertex_mode; + data->mode_keys[MODE_NONE][2].key = GLFW_KEY_N; + data->mode_keys[MODE_NONE][2].logic = enter_neighbor_mode; + data->mode_keys[MODE_NONE][3].key = GLFW_KEY_H; + data->mode_keys[MODE_NONE][3].logic = enter_hex_mode; + data->mode_keys[MODE_NONE][4].key = GLFW_KEY_R; + data->mode_keys[MODE_NONE][4].logic = enter_region_mode; + + // Camera Movement + data->mode_keys[MODE_NONE][5].key = GLFW_KEY_SPACE; + data->mode_keys[MODE_NONE][5].logic = move_cam_up; + data->mode_keys[MODE_NONE][6].key = GLFW_KEY_LEFT_SHIFT; + data->mode_keys[MODE_NONE][6].logic = move_cam_down; + data->mode_keys[MODE_NONE][7].key = GLFW_KEY_LEFT; + data->mode_keys[MODE_NONE][7].logic = move_cam_left; + data->mode_keys[MODE_NONE][8].key = GLFW_KEY_RIGHT; + data->mode_keys[MODE_NONE][8].logic = move_cam_right; + data->mode_keys[MODE_NONE][9].key = GLFW_KEY_UP; + data->mode_keys[MODE_NONE][9].logic = move_cam_forward; + data->mode_keys[MODE_NONE][10].key = GLFW_KEY_DOWN; + data->mode_keys[MODE_NONE][10].logic = move_cam_backwards; + + // Camera Spin + data->mode_keys[MODE_NONE][11].key = GLFW_KEY_A; + data->mode_keys[MODE_NONE][11].logic = spin_cam_left; + data->mode_keys[MODE_NONE][12].key = GLFW_KEY_D; + data->mode_keys[MODE_NONE][12].logic = spin_cam_right; + data->mode_keys[MODE_NONE][13].key = GLFW_KEY_W; + data->mode_keys[MODE_NONE][13].logic = spin_cam_up; + data->mode_keys[MODE_NONE][14].key = GLFW_KEY_S; + data->mode_keys[MODE_NONE][14].logic = spin_cam_down; return run_app(data, editor_startup, NULL, NULL, editor_key_callback, NULL, NULL, NULL); } diff --git a/client/src/engine.c b/client/src/engine.c index 93d5fbd..eb3206e 100644 --- a/client/src/engine.c +++ b/client/src/engine.c @@ -12,7 +12,7 @@ void text_callback(GLFWwindow* window, unsigned int codepoint) { &context->render, codepoint)) return; - if(context->app_text != NULL && context->app_text(context, codepoint)) return; + if(context->app_text != NULL) context->app_text(context, codepoint); } void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { @@ -29,84 +29,7 @@ void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod &context->render, key, action, mods)) return; - if(context->app_key != NULL && context->app_key(context, key, action, mods)) return; - - switch(key) { - case GLFW_KEY_A: - if(action == GLFW_PRESS) { - context->key_spin[0] -= 1; - } else if(action == GLFW_RELEASE) { - context->key_spin[0] += 1; - } - break; - case GLFW_KEY_D: - if(action == GLFW_PRESS) { - context->key_spin[0] += 1; - } else if(action == GLFW_RELEASE) { - context->key_spin[0] -= 1; - } - break; - - case GLFW_KEY_W: - if(action == GLFW_PRESS) { - context->key_spin[1] += 1; - } else if(action == GLFW_RELEASE) { - context->key_spin[1] -= 1; - } - break; - case GLFW_KEY_S: - if(action == GLFW_PRESS) { - context->key_spin[1] -= 1; - } else if(action == GLFW_RELEASE) { - context->key_spin[1] += 1; - } - break; - - case GLFW_KEY_UP: - if(action == GLFW_PRESS) { - context->velocity[2] += 1; - } else if(action == GLFW_RELEASE) { - context->velocity[2] -= 1; - } - break; - case GLFW_KEY_DOWN: - if(action == GLFW_PRESS) { - context->velocity[2] -= 1; - } else if(action == GLFW_RELEASE) { - context->velocity[2] += 1; - } - break; - - case GLFW_KEY_LEFT: - if(action == GLFW_PRESS) { - context->velocity[0] -= 1; - } else if(action == GLFW_RELEASE) { - context->velocity[0] += 1; - } - break; - case GLFW_KEY_RIGHT: - if(action == GLFW_PRESS) { - context->velocity[0] += 1; - } else if(action == GLFW_RELEASE) { - context->velocity[0] -= 1; - } - break; - - case GLFW_KEY_LEFT_SHIFT: - if(action == GLFW_PRESS) { - context->velocity[1] -= 1; - } else if(action == GLFW_RELEASE) { - context->velocity[1] += 1; - } - break; - case GLFW_KEY_SPACE: - if(action == GLFW_PRESS) { - context->velocity[1] += 1; - } else if(action == GLFW_RELEASE) { - context->velocity[1] -= 1; - } - break; - } + if(context->app_key != NULL) context->app_key(context, key, action, mods); } void button_callback(GLFWwindow* window, int button, int action, int mods) { @@ -154,8 +77,6 @@ void button_callback(GLFWwindow* window, int button, int action, int mods) { } } - if(context->app_button != NULL && context->app_button(context, cursor[0], cursor[1], button, action, mods)) return; - if(ui_intersect(cursor, &context->render, &context->ui, UI_EVENT_BUTTON, &container, &layer, &element, position)) { Container* container_ptr = context_container(container, &context->ui); for(uint32_t c = 0; c < container_ptr->callback_count; c++) { @@ -176,15 +97,7 @@ void button_callback(GLFWwindow* window, int button, int action, int mods) { } } - if(button == GLFW_MOUSE_BUTTON_MIDDLE) { - if(action == GLFW_PRESS) { - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - context->camera_mode = true; - } else { - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); - context->camera_mode = false; - } - } + if(context->app_button != NULL) context->app_button(context, cursor[0], cursor[1], button, action, mods); } void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) { @@ -203,8 +116,6 @@ void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) { &context->render, xoffset, yoffset)) return; - if(context->app_scroll != NULL && context->app_scroll(context, xoffset, yoffset)) return; - if(ui_intersect( context->ui.cursor, &context->render, @@ -228,9 +139,9 @@ void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) { break; } } - } else { - context->zoom = -yoffset; } + + if(context->app_scroll != NULL) context->app_scroll(context, xoffset, yoffset); } void cursor_callback(GLFWwindow* window, double xpos, double ypos) { @@ -239,57 +150,48 @@ void cursor_callback(GLFWwindow* window, double xpos, double ypos) { uint32_t element; uint32_t layer; vec2 position; - vec2 last_cursor = { - context->ui.cursor[0], - context->ui.cursor[1], - }; context->ui.cursor[0] = xpos; context->ui.cursor[1] = ypos; - if(context->camera_mode == true) { - context->cur_spin[0] = (xpos - last_cursor[0])/context->render.swapchain_extent.width*-100; - context->cur_spin[1] = (ypos - last_cursor[1])/context->render.swapchain_extent.height*100; - } else { - if(context->ui.active_callbacks != NULL && context->ui.active_callbacks->cursor != NULL) { - Container* container_ptr = context_container(context->ui.active_container, &context->ui); - GPUDrawable* drawable_ptr = &container_ptr->layers[context->ui.active_layer].drawables_buffer[context->ui.active_element]; - vec2 element_pos = { - drawable_ptr->pos[0] + container_ptr->data.offset[0], - drawable_ptr->pos[1] + container_ptr->data.offset[1], - }; - anchor_offset(&context->render, container_ptr, element_pos); - vec2 element_size = { - drawable_ptr->size[0], - drawable_ptr->size[1], - }; - if(context->ui.active_callbacks->cursor( - context->ui.active_callbacks->data, - &context->ui, - &context->render, - (context->ui.cursor[0] - element_pos[0])/element_size[0], - (context->ui.cursor[1] - element_pos[1])/element_size[1])) return; - } + if(context->ui.active_callbacks != NULL && context->ui.active_callbacks->cursor != NULL) { + Container* container_ptr = context_container(context->ui.active_container, &context->ui); + GPUDrawable* drawable_ptr = &container_ptr->layers[context->ui.active_layer].drawables_buffer[context->ui.active_element]; + vec2 element_pos = { + drawable_ptr->pos[0] + container_ptr->data.offset[0], + drawable_ptr->pos[1] + container_ptr->data.offset[1], + }; + anchor_offset(&context->render, container_ptr, element_pos); + vec2 element_size = { + drawable_ptr->size[0], + drawable_ptr->size[1], + }; + if(context->ui.active_callbacks->cursor( + context->ui.active_callbacks->data, + &context->ui, + &context->render, + (context->ui.cursor[0] - element_pos[0])/element_size[0], + (context->ui.cursor[1] - element_pos[1])/element_size[1])) return; + } - if(context->app_cursor != NULL && context->app_cursor(context, xpos, ypos)) return; - - if(ui_intersect(context->ui.cursor, &context->render, &context->ui, UI_EVENT_CURSOR, &container, &layer, &element, position)) { - Container* container_ptr = context_container(container, &context->ui); - for(uint32_t c = 0; c < container_ptr->callback_count; c++) { - if(container_ptr->callbacks[c].element == element) { - if(container_ptr->callbacks[c].cursor != NULL) { - container_ptr->callbacks[c].cursor( - container_ptr->callbacks[c].data, - &context->ui, - &context->render, - position[0], - position[1]); - } - break; + if(ui_intersect(context->ui.cursor, &context->render, &context->ui, UI_EVENT_CURSOR, &container, &layer, &element, position)) { + Container* container_ptr = context_container(container, &context->ui); + for(uint32_t c = 0; c < container_ptr->callback_count; c++) { + if(container_ptr->callbacks[c].element == element) { + if(container_ptr->callbacks[c].cursor != NULL) { + container_ptr->callbacks[c].cursor( + container_ptr->callbacks[c].data, + &context->ui, + &context->render, + position[0], + position[1]); } + break; } } } + + if(context->app_cursor != NULL) context->app_cursor(context, xpos, ypos); } int app_main(ClientContext* context) { @@ -303,16 +205,13 @@ int app_main(ClientContext* context) { // Reset callback variables context->zoom = 0; - context->cur_spin[0] = 0; - context->cur_spin[1] = 0; glfwPollEvents(); if(context->app_frame != NULL) context->app_frame(context); - if((context->key_spin[0] != 0 || context->key_spin[1] != 0 || + if((context->spin[0] != 0 || context->spin[1] != 0 || context->velocity[0] != 0 || context->velocity[1] != 0 || context->velocity[2] != 0 || context->zoom != 0 || - context->cur_spin[0] != 0 || context->cur_spin[1] != 0 || context->render.framebuffer_recreated == true)) { @@ -322,16 +221,14 @@ int app_main(ClientContext* context) { VK_RESULT(update_ui_context_resolution(&context->ui, &context->render)); } - context->rotation[0] += (float)context->key_spin[0]*delta_time*context->key_spin_speed; - context->rotation[0] += (float)context->cur_spin[0]*delta_time*context->cur_spin_speed; + context->rotation[0] += (float)context->spin[0]*delta_time*context->spin_speed; if(context->rotation[0] > 2*M_PI) { context->rotation[0] -= 2*M_PI; } else if(context->rotation[0] < 0) { context->rotation[0] += 2*M_PI; } - context->rotation[1] += (float)context->key_spin[1]*delta_time*context->key_spin_speed; - context->rotation[1] += (float)context->cur_spin[1]*delta_time*context->cur_spin_speed; + context->rotation[1] += (float)context->spin[1]*delta_time*context->spin_speed; if(context->rotation[1] > (M_PI/2 - 0.1)) { context->rotation[1] = (M_PI/2 - 0.1); } else if(context->rotation[1] < 0) { @@ -393,8 +290,7 @@ int run_app( context->rotation[0] = 3*M_PI/2; context->rotation[1] = M_PI/4; context->distance = 25; - context->key_spin_speed = 1.0; - context->cur_spin_speed = 1.0; + context->spin_speed = 1.0; context->zoom_speed = 1.0; context->move_speed = 0.1; diff --git a/client/src/gpu.c b/client/src/gpu.c index 589cff0..04c2e30 100644 --- a/client/src/gpu.c +++ b/client/src/gpu.c @@ -1064,6 +1064,10 @@ VkResult init_vulkan(GLFWwindow* window, RenderContext* context) { return VK_ERROR_VALIDATION_FAILED_EXT; } + context->swapchain_command_buffer_record_id = 1; + context->swapchain_command_buffer_record_ids = malloc(sizeof(uint64_t)*context->swapchain_image_count); + memset(context->swapchain_command_buffer_record_ids, 0, sizeof(uint64_t)*context->swapchain_image_count); + VK_RESULT(create_image_views( context->device, context->swapchain_image_count, diff --git a/client/src/ui.c b/client/src/ui.c index a034434..60604b7 100644 --- a/client/src/ui.c +++ b/client/src/ui.c @@ -227,10 +227,45 @@ VkResult create_ui_pipeline( return VK_SUCCESS; } -VkResult create_container( +VkResult unload_container( + uint32_t id, + RenderContext* gpu, + UIContext* context) { + uint32_t index = 0xFFFFFFFF; + for(uint32_t i = 0; i < context->max_containers; i++) { + if(context->containers[i].id == id) { + index = i; + break; + } + } + + if(index == 0xFFFFFFFF) { + return VK_ERROR_VALIDATION_FAILED_EXT; + } + + context->containers[index].id = 0; + + for(uint32_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { + vmaDestroyBuffer(gpu->allocator, context->containers[index].container[i], context->containers[index].container_memory[i]); + context->containers[index].address[i] = 0; + } + + context->containers[index].layer_count = 0; + + return VK_SUCCESS; +} + +VkResult load_container( ContainerInput* container, RenderContext* gpu, UIContext* context) { + if(container == NULL) return VK_ERROR_VALIDATION_FAILED_EXT; + if(container->id == 0) return VK_ERROR_VALIDATION_FAILED_EXT; + + for(uint32_t i = 0; i < context->max_containers; i++) { + if(context->containers[i].id == container->id) return VK_ERROR_VALIDATION_FAILED_EXT; + } + uint32_t index = 0xFFFFFFFF; for(uint32_t i = 0; i < context->max_containers; i++) { if(context->containers[i].id == 0x00000000) { @@ -1167,7 +1202,7 @@ Container* context_container(uint32_t container_id, UIContext* ui) { } VkResult update_ui_string( - char* string, + const char* string, uint32_t container_id, uint32_t layer_index, uint32_t string_index,