Removed hex references to focus on UI, need to add lua
							parent
							
								
									099b4cd13c
								
							
						
					
					
						commit
						74d905cf2f
					
				| @ -1,176 +0,0 @@ | ||||
| #ifndef HEX_H | ||||
| #define HEX_H | ||||
| 
 | ||||
| #include "gpu.h" | ||||
| #include "vulkan/vulkan_core.h" | ||||
| 
 | ||||
| #define MAX_RAYS 10 | ||||
| #define MAX_HIGHLIGHTS 10 | ||||
| #define MAX_POINTS 10 | ||||
| 
 | ||||
| #define MAX_LOADED_REGIONS 2500 | ||||
| #define REGION_SIZE 10 | ||||
| #define REGION_HEX_COUNT (3*REGION_SIZE*(REGION_SIZE-1)+1) | ||||
| #define HEX_X 0.75 | ||||
| #define SQRT3 1.732050807568877193176604123436845839023590087890625 | ||||
| #define HEX_Z (SQRT3/2) | ||||
| #define REGION_DIAMETER (2*REGION_SIZE-1) | ||||
| #define REGION_WIDTH (HEX_X*REGION_DIAMETER) | ||||
| #define REGION_HEIGHT (HEX_Z*REGION_DIAMETER) | ||||
| 
 | ||||
| #define max(a, b) ((a > b) ? a : b) | ||||
| #define min(a, b) ((a < b) ? a : b) | ||||
| 
 | ||||
| typedef struct HexCoordStruct { | ||||
|   int32_t q; | ||||
|   int32_t r; | ||||
| } HexCoord; | ||||
| 
 | ||||
| extern vec3 hex_vertices[]; | ||||
| extern vec3 hex_starts[]; | ||||
| extern vec3 hex_directions[]; | ||||
| extern HexCoord hex_starts_qr[]; | ||||
| extern HexCoord hex_directions_qr[]; | ||||
| extern int hex_indices[]; | ||||
| 
 | ||||
| typedef struct GPUHexStruct { | ||||
|   float    height[6]; | ||||
|   uint32_t color[7]; | ||||
| } GPUHex; | ||||
| 
 | ||||
| typedef struct GPUHexRegionStruct { | ||||
|   HexCoord position; | ||||
|   int32_t y; | ||||
|   uint32_t map; | ||||
| 
 | ||||
|   GPUHex hexes[REGION_HEX_COUNT]; | ||||
| } GPUHexRegion; | ||||
| 
 | ||||
| typedef struct HexRegionStruct { | ||||
|   VkDeviceAddress address; | ||||
|   VkBuffer region; | ||||
|   VmaAllocation region_memory; | ||||
| 
 | ||||
|   GPUHexRegion data; | ||||
| } HexRegion; | ||||
| 
 | ||||
| typedef struct GPURayStruct { | ||||
|   vec4 start; | ||||
|   vec4 end; | ||||
|   vec4 color; | ||||
| } GPURay; | ||||
| 
 | ||||
| typedef struct GPUHighlightStruct { | ||||
|   vec4 color; | ||||
|   uint32_t region; | ||||
|   uint32_t hex; | ||||
|   float offset; | ||||
| } GPUHighlight; | ||||
| 
 | ||||
| typedef struct GPUPointStruct { | ||||
|   vec4 color; | ||||
|   uint32_t region; | ||||
|   uint32_t hex; | ||||
|   uint32_t vertex; | ||||
|   float size; | ||||
|   float offset; | ||||
| } GPUPoint; | ||||
| 
 | ||||
| typedef struct GPUHexContextStruct { | ||||
|   mat4 proj; | ||||
|   mat4 view; | ||||
|   uint32_t current_map; | ||||
|   VkDeviceAddress rays; | ||||
|   VkDeviceAddress points; | ||||
|   VkDeviceAddress highlights; | ||||
|   VkDeviceAddress regions[MAX_LOADED_REGIONS]; | ||||
| } GPUHexContext; | ||||
| 
 | ||||
| typedef struct HexContextStruct { | ||||
|   VkDeviceAddress address[MAX_FRAMES_IN_FLIGHT]; | ||||
|   VkBuffer        context[MAX_FRAMES_IN_FLIGHT]; | ||||
|   VmaAllocation   context_memory[MAX_FRAMES_IN_FLIGHT];  | ||||
| 
 | ||||
|   VkBuffer rays[MAX_FRAMES_IN_FLIGHT]; | ||||
|   VkBuffer points[MAX_FRAMES_IN_FLIGHT]; | ||||
|   VkBuffer highlights[MAX_FRAMES_IN_FLIGHT]; | ||||
|   VmaAllocation rays_memory[MAX_FRAMES_IN_FLIGHT]; | ||||
|   VmaAllocation points_memory[MAX_FRAMES_IN_FLIGHT]; | ||||
|   VmaAllocation highlights_memory[MAX_FRAMES_IN_FLIGHT]; | ||||
| 
 | ||||
|   GPURay rays_buffer[MAX_RAYS]; | ||||
|   GPUHighlight highlights_buffer[MAX_HIGHLIGHTS]; | ||||
|   GPUPoint points_buffer[MAX_POINTS]; | ||||
| 
 | ||||
|   mat4 inverse; | ||||
| 
 | ||||
|   GraphicsPipeline graphics; | ||||
|   GraphicsPipeline highlight_pipeline; | ||||
|   GraphicsPipeline point_pipeline; | ||||
|   GraphicsPipeline ray_pipeline; | ||||
| 
 | ||||
|   HexRegion* regions[MAX_LOADED_REGIONS]; | ||||
|   GPUHexContext data; | ||||
| } HexContext; | ||||
| 
 | ||||
| typedef struct HexPushConstantStruct { | ||||
|   VkDeviceAddress context; | ||||
|   double time; | ||||
| } HexPushConstant; | ||||
| 
 | ||||
| VkResult create_hex_context( | ||||
|     RenderContext* gpu, | ||||
|     HexContext* context); | ||||
| 
 | ||||
| VkResult set_hex_region( | ||||
|     HexRegion* region, | ||||
|     HexContext* hex, | ||||
|     RenderContext* gpu); | ||||
| 
 | ||||
| VkResult allocate_hex_region( | ||||
|     int32_t q, int32_t r, int32_t y, | ||||
|     uint32_t map, | ||||
|     HexRegion** region, | ||||
|     HexContext* hex, | ||||
|     RenderContext* gpu); | ||||
| 
 | ||||
| VkResult free_hex_region( | ||||
|     uint32_t region_index, | ||||
|     HexContext* hex, | ||||
|     RenderContext* gpu); | ||||
| 
 | ||||
| bool ray_world_intersect( | ||||
|     float* distance, | ||||
|     uint32_t* vertex, | ||||
|     uint32_t* rid, | ||||
|     uint32_t* hid, | ||||
|     vec4 ray_start, | ||||
|     vec4 ray_end, | ||||
|     HexContext* context); | ||||
| 
 | ||||
| VkResult update_hex_proj( | ||||
|     RenderContext* gpu, | ||||
|     HexContext* hex); | ||||
| 
 | ||||
| VkResult update_hex_view( | ||||
|     vec3 position, | ||||
|     vec2 rotation, | ||||
|     double distance, | ||||
|     RenderContext* gpu, | ||||
|     HexContext* hex); | ||||
| 
 | ||||
| void hex_qr(uint32_t hex, HexCoord* world); | ||||
| 
 | ||||
| void region_qr(HexCoord region, HexCoord* world); | ||||
| 
 | ||||
| void hex_add(HexCoord from, HexCoord* to); | ||||
| 
 | ||||
| void hex_index(HexCoord world, HexCoord* region, uint32_t* hex); | ||||
| 
 | ||||
| void hex_vertex_neighbors( | ||||
|   uint32_t vertex, HexCoord hex, | ||||
|   uint32_t n_vertex[2], HexCoord n_region[2], uint32_t n_hex[2]); | ||||
| 
 | ||||
| void first_matching_region(HexCoord coord, int y, uint32_t* region, HexContext* context); | ||||
| 
 | ||||
| #endif | ||||
| @ -1,975 +0,0 @@ | ||||
| #include <stdio.h> | ||||
| #include "hex.h" | ||||
| #include "hsv.h" | ||||
| #include "engine.h" | ||||
| #include "vulkan/vulkan_core.h" | ||||
| 
 | ||||
| #include <math.h> | ||||
| #include <stdlib.h> | ||||
| 
 | ||||
| #define COLOR_PICK_CONTAINER_ID 0x02 | ||||
| #define MODE_STRING_CONTAINER_ID 0x01 | ||||
| 
 | ||||
| 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; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| uint32_t hex_color(vec4 color) { | ||||
|   return ((lrint(color[0]*255.0) & 0xFF) << 24) | ||||
|        + ((lrint(color[1]*255.0) & 0xFF) << 16) | ||||
|        + ((lrint(color[2]*255.0) & 0xFF) <<  8) | ||||
|        + ((lrint(color[3]*255.0) & 0xFF) <<  0); | ||||
| } | ||||
| 
 | ||||
| VkResult set_vertex_height(float height, uint32_t region, uint32_t hex, uint32_t vertex, ClientContext* context) { | ||||
|   if(vertex == 0) return VK_ERROR_VALIDATION_FAILED_EXT; | ||||
|   context->hex.regions[region]->data.hexes[hex].height[vertex-1] = height;  | ||||
|   return add_transfer( | ||||
|       &context->hex.regions[region]->data.hexes[hex].height[vertex-1], | ||||
|       context->hex.regions[region]->region, | ||||
|       offsetof(GPUHexRegion, hexes) | ||||
|       + sizeof(GPUHex)*hex | ||||
|       + offsetof(GPUHex, height) | ||||
|       + sizeof(float)*(vertex-1), | ||||
|       sizeof(float), | ||||
|       context->render.current_frame, | ||||
|       &context->render); | ||||
| } | ||||
| 
 | ||||
| VkResult set_vertex_color(vec4 color, uint32_t region, uint32_t hex, uint32_t vertex, ClientContext* context) { | ||||
|   context->hex.regions[region]->data.hexes[hex].color[vertex] = hex_color(color);  | ||||
|   return add_transfer( | ||||
|       &context->hex.regions[region]->data.hexes[hex].color[vertex], | ||||
|       context->hex.regions[region]->region, | ||||
|       offsetof(GPUHexRegion, hexes) | ||||
|       + sizeof(GPUHex)*hex | ||||
|       + offsetof(GPUHex, color) | ||||
|       + sizeof(uint32_t)*vertex, | ||||
|       sizeof(uint32_t), | ||||
|       context->render.current_frame, | ||||
|       &context->render); | ||||
| } | ||||
| 
 | ||||
| uint32_t add_hex_region(ClientContext* context) { | ||||
|   HexRegion* region; | ||||
| 
 | ||||
|   allocate_hex_region(0, 0, 0, context->hex.data.current_map, ®ion, &context->hex, &context->render); | ||||
| 
 | ||||
|   for(uint32_t hex = 0; hex < REGION_HEX_COUNT; hex++) { | ||||
|     region->data.hexes[hex].color[0] = 0xFFFFFFFF; | ||||
|     region->data.hexes[hex].color[1] = 0xFFFFFFFF; | ||||
|     region->data.hexes[hex].color[2] = 0xFFFFFFFF; | ||||
|     region->data.hexes[hex].color[3] = 0xFFFFFFFF; | ||||
|     region->data.hexes[hex].color[4] = 0xFFFFFFFF; | ||||
|     region->data.hexes[hex].color[5] = 0xFFFFFFFF; | ||||
|     region->data.hexes[hex].color[6] = 0xFFFFFFFF; | ||||
| 
 | ||||
|     region->data.hexes[hex].height[0] = 0; | ||||
|     region->data.hexes[hex].height[1] = 0; | ||||
|     region->data.hexes[hex].height[2] = 0; | ||||
|     region->data.hexes[hex].height[3] = 0; | ||||
|     region->data.hexes[hex].height[4] = 0; | ||||
|     region->data.hexes[hex].height[5] = 0; | ||||
|   } | ||||
| 
 | ||||
|   set_hex_region(region, &context->hex, &context->render); | ||||
| 
 | ||||
|   uint32_t i = 0; | ||||
|   for(; i < MAX_LOADED_REGIONS; i++) { | ||||
|     if(region == context->hex.regions[i]) { | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   return i; | ||||
| } | ||||
| 
 | ||||
| void update_hex_string(Container* container, UIContext* ui, RenderContext* gpu, EditorData* data) { | ||||
|   snprintf(data->string, 10, "#%02X%02X%02X%02X", | ||||
|       (uint)rintf(data->current[0]*255), | ||||
|       (uint)rintf(data->current[1]*255), | ||||
|       (uint)rintf(data->current[2]*255), | ||||
|       (uint)rintf(data->current[3]*255)); | ||||
|   data->string_len = 8; | ||||
|   update_ui_string(data->string, container, 0, 0, ui, gpu); | ||||
| } | ||||
| 
 | ||||
| void sv_square_pick(Container* container, UIContext* ui, RenderContext* gpu, EditorData* data, float s, float v) { | ||||
|   if(s < 0) s = 0; | ||||
|   if(s > 1) s = 1; | ||||
| 
 | ||||
|   if(v < 0) v = 0; | ||||
|   if(v > 1) v = 1; | ||||
| 
 | ||||
|   data->current_hsv[1] = s; | ||||
|   data->current_hsv[2] = v; | ||||
| 
 | ||||
|   Layer* layer = &container->layers[0]; | ||||
|   GPUDrawable* select_outline = &layer->drawables_buffer[3]; | ||||
|   GPUDrawable* select = &layer->drawables_buffer[4]; | ||||
| 
 | ||||
|   select->pos[0] = s*130 - 2; | ||||
|   select->pos[1] = 130 - v*130 - 2; | ||||
|    | ||||
|   select->color[0][1] = s; | ||||
|   select->color[0][2] = v; | ||||
| 
 | ||||
|   select->color[1][1] = s; | ||||
|   select->color[1][2] = v; | ||||
| 
 | ||||
|   select->color[2][1] = s; | ||||
|   select->color[2][2] = v; | ||||
| 
 | ||||
|   select->color[3][1] = s; | ||||
|   select->color[3][2] = v; | ||||
| 
 | ||||
|   select_outline->pos[0] = s*130 - 3; | ||||
|   select_outline->pos[1] = 130 - v*130 - 3; | ||||
| 
 | ||||
|   add_transfers( | ||||
|       &select_outline->pos[0], | ||||
|       layer->drawables, | ||||
|       3*sizeof(GPUDrawable) + offsetof(GPUDrawable, pos), | ||||
|       1*sizeof(vec2), | ||||
|       gpu); | ||||
| 
 | ||||
|   add_transfers( | ||||
|       &select->pos[0], | ||||
|       layer->drawables, | ||||
|       4*sizeof(GPUDrawable) + offsetof(GPUDrawable, pos), | ||||
|       1*sizeof(vec2), | ||||
|       gpu); | ||||
| 
 | ||||
|   add_transfers( | ||||
|       &select->color[0], | ||||
|       layer->drawables, | ||||
|       4*sizeof(GPUDrawable) + offsetof(GPUDrawable, color), | ||||
|       4*sizeof(vec4), | ||||
|       gpu); | ||||
| 
 | ||||
|   hsv_to_rgb(data->current_hsv, data->current); | ||||
|   update_hex_string(container, ui, gpu, data); | ||||
| } | ||||
| 
 | ||||
| bool sv_square_button_callback(Container* container, void* data, UIContext* ui, RenderContext* gpu, float x, float y, int button, int action, int mods) { | ||||
|   (void)mods; | ||||
|   (void)x; | ||||
| 
 | ||||
|   if(action == GLFW_PRESS && button == GLFW_MOUSE_BUTTON_LEFT) { | ||||
|     set_active_element(COLOR_PICK_CONTAINER_ID, 0, 1, ui); | ||||
|     sv_square_pick(container, ui, gpu, data, x, 1-y); | ||||
|   } else if(action == GLFW_RELEASE && button == GLFW_MOUSE_BUTTON_LEFT) { | ||||
|     clear_active_element(ui, gpu); | ||||
|   } | ||||
| 
 | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| bool sv_square_cursor_callback(Container* container, void* data, UIContext* ui, RenderContext* gpu, float x, float y) { | ||||
|   if(ui->active_element == 1 | ||||
|   && ui->active_layer == 0 | ||||
|   && ui->active_container == container) { | ||||
|     sv_square_pick(container, ui, gpu, data, x, 1-y); | ||||
|   } | ||||
| 
 | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| void hue_bar_set(Container* container, UIContext* ui, RenderContext* gpu, EditorData* data, float y) { | ||||
|   if(y < 0) y = 0; | ||||
|   if(y > 1) y = 1; | ||||
| 
 | ||||
|   data->current_hsv[0] = y; | ||||
| 
 | ||||
|   Layer* layer = &container->layers[0]; | ||||
|   GPUDrawable* sv_square = &layer->drawables_buffer[1]; | ||||
|   GPUDrawable* sv_select = &layer->drawables_buffer[4]; | ||||
|   GPUDrawable* hue_select = &layer->drawables_buffer[6]; | ||||
|    | ||||
|   sv_square->color[0][0] = y; | ||||
|   sv_square->color[1][0] = y; | ||||
|   sv_square->color[2][0] = y; | ||||
|   sv_square->color[3][0] = y; | ||||
| 
 | ||||
|   sv_select->color[0][0] = y; | ||||
|   sv_select->color[1][0] = y; | ||||
|   sv_select->color[2][0] = y; | ||||
|   sv_select->color[3][0] = y; | ||||
| 
 | ||||
|   hue_select->pos[1] = 2 + y*130; | ||||
| 
 | ||||
|   add_transfers( | ||||
|       &sv_square->color[0], | ||||
|       layer->drawables, | ||||
|       1*sizeof(GPUDrawable) + offsetof(GPUDrawable, color), | ||||
|       4*sizeof(vec4), | ||||
|       gpu); | ||||
| 
 | ||||
|   add_transfers( | ||||
|       &sv_select->color[0], | ||||
|       layer->drawables, | ||||
|       4*sizeof(GPUDrawable) + offsetof(GPUDrawable, color), | ||||
|       4*sizeof(vec4), | ||||
|       gpu); | ||||
| 
 | ||||
|   add_transfers( | ||||
|       &hue_select->pos[1], | ||||
|       layer->drawables, | ||||
|       6*sizeof(GPUDrawable) + offsetof(GPUDrawable, pos) + sizeof(float), | ||||
|       1*sizeof(float), | ||||
|       gpu); | ||||
| 
 | ||||
|   hsv_to_rgb(data->current_hsv, data->current); | ||||
|   update_hex_string(container, ui, gpu, data); | ||||
| } | ||||
| 
 | ||||
| bool hue_bar_scroll_callback(Container* container, void* data, UIContext* ui, RenderContext* gpu, double x, double y) { | ||||
|   (void)x; | ||||
| 
 | ||||
|   hue_bar_set(container, ui, gpu, data, y*0.01 + container->layers[0].drawables_buffer[1].color[0][0]); | ||||
| 
 | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| bool hue_bar_cursor_callback(Container* container, void*data, UIContext* ui, RenderContext* gpu, float x, float y) { | ||||
|   (void)x; | ||||
| 
 | ||||
|   if(ui->active_element == 2 | ||||
|   && ui->active_layer == 0 | ||||
|   && ui->active_container == container) { | ||||
|     hue_bar_set(container, ui, gpu, data, y); | ||||
|   } | ||||
| 
 | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| bool hue_bar_button_callback(Container* container, void* data, UIContext* ui, RenderContext* gpu, float x, float y, int button, int action, int mods) { | ||||
|   (void)mods; | ||||
|   (void)x; | ||||
| 
 | ||||
|   if(action == GLFW_PRESS && button == GLFW_MOUSE_BUTTON_LEFT) { | ||||
|     set_active_element(COLOR_PICK_CONTAINER_ID, 0, 2, ui); | ||||
|     hue_bar_set(container, ui, gpu, data, y); | ||||
|   } else if(action == GLFW_RELEASE && button == GLFW_MOUSE_BUTTON_LEFT) { | ||||
|     clear_active_element(ui, gpu); | ||||
|   } | ||||
| 
 | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| void hex_string_set_color(Container* container, RenderContext* gpu, float color) { | ||||
|   container->layers[0].drawables_buffer[5].color[0][2] = color; | ||||
|   container->layers[0].drawables_buffer[5].color[0][3] = color; | ||||
| 
 | ||||
|   container->layers[0].drawables_buffer[5].color[1][2] = color; | ||||
|   container->layers[0].drawables_buffer[5].color[1][3] = color; | ||||
| 
 | ||||
|   container->layers[0].drawables_buffer[5].color[2][2] = color; | ||||
|   container->layers[0].drawables_buffer[5].color[2][3] = color; | ||||
| 
 | ||||
|   container->layers[0].drawables_buffer[5].color[3][2] = color; | ||||
|   container->layers[0].drawables_buffer[5].color[3][3] = color; | ||||
| 
 | ||||
|   add_transfers( | ||||
|       &container->layers[0].drawables_buffer[5].color[0], | ||||
|       container->layers[0].drawables, | ||||
|       5*sizeof(GPUDrawable) + offsetof(GPUDrawable, color), | ||||
|       4*sizeof(vec4), | ||||
|       gpu); | ||||
| } | ||||
| 
 | ||||
| bool hex_string_text_callback(Container* container, void* ptr, UIContext* ui, RenderContext* gpu, unsigned int codepoint) { | ||||
|   EditorData* data = ptr; | ||||
| 
 | ||||
|   if(codepoint >= 'a' && codepoint <= 'f') { | ||||
|     codepoint += 'A' - 'a'; | ||||
|   } else if(!((codepoint >= 'A' && codepoint <= 'F') || (codepoint >= '0' && codepoint <= '9'))) { | ||||
|     return true; | ||||
|   } | ||||
| 
 | ||||
|   if(data->string_len < 8) { | ||||
|     data->string_len += 1; | ||||
|     data->string[data->string_len] = codepoint; | ||||
|     update_ui_string(data->string, container, 0, 0, ui, gpu); | ||||
|   } | ||||
| 
 | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| bool hex_string_key_callback(Container* container, void* ptr, UIContext* ui, RenderContext* gpu, int key, int action, int mods) { | ||||
|   (void)mods; | ||||
|   EditorData* data = ptr; | ||||
|   char tmp[3]; | ||||
| 
 | ||||
|   if(action == GLFW_PRESS) { | ||||
|     switch(key) { | ||||
|     case GLFW_KEY_ESCAPE: | ||||
|       hsv_to_rgb(data->current_hsv, data->current); | ||||
|       update_hex_string(container, ui, gpu, data); | ||||
|       clear_active_element(ui, gpu); | ||||
|       break; | ||||
|     case GLFW_KEY_ENTER: | ||||
|       // TODO: validate hex string and reset or set hsv
 | ||||
|       tmp[0] = data->string[1]; | ||||
|       tmp[1] = data->string[2]; | ||||
|       tmp[2] = 0; | ||||
|       data->current[0] = strtol(tmp, NULL, 16)/255.0; | ||||
| 
 | ||||
|       tmp[0] = data->string[3]; | ||||
|       tmp[1] = data->string[4]; | ||||
|       tmp[2] = 0; | ||||
|       data->current[1] = strtol(tmp, NULL, 16)/255.0; | ||||
| 
 | ||||
|       tmp[0] = data->string[5]; | ||||
|       tmp[1] = data->string[6]; | ||||
|       tmp[2] = 0; | ||||
|       data->current[2] = strtol(tmp, NULL, 16)/255.0; | ||||
| 
 | ||||
|       tmp[0] = data->string[7]; | ||||
|       tmp[1] = data->string[8]; | ||||
|       tmp[2] = 0; | ||||
|       data->current[3] = strtol(tmp, NULL, 16)/255.0; | ||||
| 
 | ||||
|       rgb_to_hsv(data->current, data->current_hsv); | ||||
|       hue_bar_set(container, ui, gpu, data, data->current_hsv[0]); | ||||
|       sv_square_pick(container, ui, gpu, data, data->current_hsv[1], data->current_hsv[2]); | ||||
| 
 | ||||
|       clear_active_element(ui, gpu); | ||||
|       break; | ||||
|     case GLFW_KEY_BACKSPACE: | ||||
|       if(data->string_len > 0) { | ||||
|         data->string[data->string_len] = '\0'; | ||||
|         data->string_len -= 1; | ||||
|         update_ui_string(data->string, container, 0, 0, ui, gpu); | ||||
|       } | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| bool hex_string_button_callback(Container* container, void* data, UIContext* ui, RenderContext* gpu, float x, float y, int button, int action, int mods) { | ||||
|   (void)data; | ||||
|   (void)mods; | ||||
|   (void)x; | ||||
|   (void)y; | ||||
| 
 | ||||
|   if(action == GLFW_PRESS && button == GLFW_MOUSE_BUTTON_LEFT) { | ||||
|     set_active_element(COLOR_PICK_CONTAINER_ID, 0, 5, ui); | ||||
|     hex_string_set_color(container, gpu, 1); | ||||
|   } | ||||
| 
 | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| void hex_string_deselect_callback(Container* container, void* data, UIContext* ui, RenderContext* gpu) { | ||||
|   (void)data; | ||||
|   (void)ui; | ||||
|   hex_string_set_color(container, gpu, 0); | ||||
| } | ||||
| 
 | ||||
| void set_saved_color(Container* container, RenderContext* gpu, EditorData* data, uint32_t index, vec4 color) { | ||||
|   data->saved[index][0] = color[0]; | ||||
|   data->saved[index][1] = color[1]; | ||||
|   data->saved[index][2] = color[2]; | ||||
|   data->saved[index][3] = color[3]; | ||||
| 
 | ||||
|   Layer* layer = &container->layers[0]; | ||||
|   GPUDrawable* saved_color = &layer->drawables_buffer[7 + index]; | ||||
| 
 | ||||
|   saved_color->color[0][0] = data->current[0]; | ||||
|   saved_color->color[0][1] = data->current[1]; | ||||
|   saved_color->color[0][2] = data->current[2]; | ||||
| 
 | ||||
|   saved_color->color[1][0] = data->current[0]; | ||||
|   saved_color->color[1][1] = data->current[1]; | ||||
|   saved_color->color[1][2] = data->current[2]; | ||||
| 
 | ||||
|   saved_color->color[2][0] = data->current[0]; | ||||
|   saved_color->color[2][1] = data->current[1]; | ||||
|   saved_color->color[2][2] = data->current[2]; | ||||
| 
 | ||||
|   saved_color->color[3][0] = data->current[0]; | ||||
|   saved_color->color[3][1] = data->current[1]; | ||||
|   saved_color->color[3][2] = data->current[2]; | ||||
| 
 | ||||
|   add_transfers( | ||||
|       &saved_color->color[0], | ||||
|       layer->drawables, | ||||
|       (7+index)*sizeof(GPUDrawable) + offsetof(GPUDrawable, color), | ||||
|       4*sizeof(vec4), | ||||
|       gpu); | ||||
| } | ||||
| 
 | ||||
| bool saved_color_button_callback( | ||||
|     Container* container, | ||||
|     void* ptr, | ||||
|     UIContext* ui, | ||||
|     RenderContext* gpu, | ||||
|     float x, float y, | ||||
|     int button, int action, int mods, | ||||
|     uint32_t index) { | ||||
|   (void)x; | ||||
|   (void)y; | ||||
|   (void)mods; | ||||
| 
 | ||||
|   EditorData* data = ptr; | ||||
| 
 | ||||
|   if(action == GLFW_PRESS) { | ||||
|     if(button == GLFW_MOUSE_BUTTON_LEFT) { | ||||
|       data->current[0] = data->saved[index][0]; | ||||
|       data->current[1] = data->saved[index][1]; | ||||
|       data->current[2] = data->saved[index][2]; | ||||
|       data->current[3] = data->saved[index][3]; | ||||
|       rgb_to_hsv(data->current, data->current_hsv); | ||||
|       hue_bar_set(container, ui, gpu, data, data->current_hsv[0]); | ||||
|       sv_square_pick(container, ui, gpu, data, data->current_hsv[1], data->current_hsv[2]); | ||||
|       update_hex_string(container, ui, gpu, data); | ||||
|     } else if(button == GLFW_MOUSE_BUTTON_RIGHT) { | ||||
|       set_saved_color(container, gpu, data, index, data->current); | ||||
|     } else if (button == GLFW_MOUSE_BUTTON_MIDDLE) { | ||||
|       vec4 clear = {0, 0, 0, 0}; | ||||
|       set_saved_color(container, gpu, data, index, clear); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| #define SAVED_COLOR_BUTTON_CALLBACK(n) \ | ||||
| bool saved_color_button_callback_##n(Container* container, void* data, UIContext* ui, RenderContext* gpu, float x, float y, int button, int action, int mods) { \ | ||||
|   return saved_color_button_callback(container, data, ui, gpu, x, y, button, action, mods, n); \ | ||||
| } | ||||
| 
 | ||||
| SAVED_COLOR_BUTTON_CALLBACK( 0); | ||||
| SAVED_COLOR_BUTTON_CALLBACK( 1); | ||||
| SAVED_COLOR_BUTTON_CALLBACK( 2); | ||||
| SAVED_COLOR_BUTTON_CALLBACK( 3); | ||||
| SAVED_COLOR_BUTTON_CALLBACK( 4); | ||||
| SAVED_COLOR_BUTTON_CALLBACK( 5); | ||||
| SAVED_COLOR_BUTTON_CALLBACK( 6); | ||||
| SAVED_COLOR_BUTTON_CALLBACK( 7); | ||||
| SAVED_COLOR_BUTTON_CALLBACK( 8); | ||||
| SAVED_COLOR_BUTTON_CALLBACK( 9); | ||||
| SAVED_COLOR_BUTTON_CALLBACK(10); | ||||
| SAVED_COLOR_BUTTON_CALLBACK(11); | ||||
| 
 | ||||
| #define SAVED_COLOR_CALLBACK_ENTRY(n) \ | ||||
|     { \ | ||||
|       .layer = 0, \ | ||||
|       .element = 7 + n, \ | ||||
|       .data = data, \ | ||||
|       .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[] = { | ||||
|     { | ||||
|       .pos = {2, 150}, | ||||
|       .color = {1, 1, 1, 1}, | ||||
|       .size = 16, | ||||
|       .offset = 0, | ||||
|       .length = 9, | ||||
|       .font = 0, | ||||
|     }, | ||||
|   }; | ||||
| 
 | ||||
|   GPUDrawable drawables[] = { | ||||
|     { | ||||
|       .pos = {0, 0}, | ||||
|       .size = {190, 150}, | ||||
|       .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}}, | ||||
|     }, | ||||
|     { | ||||
|       .type = DRAWABLE_TYPE_RECT_HSV, | ||||
|       .pos = {2, 2}, | ||||
|       .size = {130, 130}, | ||||
|       .color = {{0, 0, 1, 1}, {0, 1, 1, 1}, {0, 0, 0, 1}, {0, 1, 0, 1}}, | ||||
|       .events = UI_EVENT_BUTTON, | ||||
|     }, | ||||
|     { | ||||
|       .type = DRAWABLE_TYPE_RECT_HSV, | ||||
|       .pos = {134, 2}, | ||||
|       .size = {10, 130}, | ||||
|       .color = {{0, 1, 1, 1}, {0, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, | ||||
|       .events = UI_EVENT_BUTTON | UI_EVENT_SCROLL, | ||||
|     }, | ||||
|     { | ||||
|       .pos = {130-4, 130-4}, | ||||
|       .size = {7, 7}, | ||||
|       .color = {{0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}}, | ||||
|     }, | ||||
|     { | ||||
|       .type = DRAWABLE_TYPE_RECT_HSV, | ||||
|       .pos = {130-3, 130-3}, | ||||
|       .size = {5, 5}, | ||||
|       .color = {{1, 0, 0, 1}, {1, 0, 0, 1}, {1, 0, 0, 1}, {1, 0, 0, 1}}, | ||||
|     }, | ||||
|     { | ||||
|       .pos = {20, 134}, | ||||
|       .size = {95, 15}, | ||||
|       .events = UI_EVENT_BUTTON | UI_EVENT_CURSOR, | ||||
|     }, | ||||
|     { | ||||
|       .pos = {134, 2}, | ||||
|       .size = {10, 1}, | ||||
|       .color = {{0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}}, | ||||
|     }, | ||||
|     { | ||||
|       .pos = {146, 2}, | ||||
|       .size = {20, 20}, | ||||
|       .color = {{0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}}, | ||||
|       .events = UI_EVENT_BUTTON, | ||||
|     }, | ||||
|     { | ||||
|       .pos = {168, 2}, | ||||
|       .size = {20, 20}, | ||||
|       .color = {{0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}}, | ||||
|       .events = UI_EVENT_BUTTON, | ||||
|     }, | ||||
|     { | ||||
|       .pos = {146, 24}, | ||||
|       .size = {20, 20}, | ||||
|       .color = {{0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}}, | ||||
|       .events = UI_EVENT_BUTTON, | ||||
|     }, | ||||
|     { | ||||
|       .pos = {168, 24}, | ||||
|       .size = {20, 20}, | ||||
|       .color = {{0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}}, | ||||
|       .events = UI_EVENT_BUTTON, | ||||
|     }, | ||||
|     { | ||||
|       .pos = {146, 46}, | ||||
|       .size = {20, 20}, | ||||
|       .color = {{0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}}, | ||||
|       .events = UI_EVENT_BUTTON, | ||||
|     }, | ||||
|     { | ||||
|       .pos = {168, 46}, | ||||
|       .size = {20, 20}, | ||||
|       .color = {{0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}}, | ||||
|       .events = UI_EVENT_BUTTON, | ||||
|     }, | ||||
|     { | ||||
|       .pos = {146, 68}, | ||||
|       .size = {20, 20}, | ||||
|       .color = {{0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}}, | ||||
|       .events = UI_EVENT_BUTTON, | ||||
|     }, | ||||
|     { | ||||
|       .pos = {168, 68}, | ||||
|       .size = {20, 20}, | ||||
|       .color = {{0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}}, | ||||
|       .events = UI_EVENT_BUTTON, | ||||
|     }, | ||||
|     { | ||||
|       .pos = {146, 90}, | ||||
|       .size = {20, 20}, | ||||
|       .color = {{0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}}, | ||||
|       .events = UI_EVENT_BUTTON, | ||||
|     }, | ||||
|     { | ||||
|       .pos = {168, 90}, | ||||
|       .size = {20, 20}, | ||||
|       .color = {{0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}}, | ||||
|       .events = UI_EVENT_BUTTON, | ||||
|     }, | ||||
|     { | ||||
|       .pos = {146, 112}, | ||||
|       .size = {20, 20}, | ||||
|       .color = {{0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}}, | ||||
|       .events = UI_EVENT_BUTTON, | ||||
|     }, | ||||
|     { | ||||
|       .pos = {168, 112}, | ||||
|       .size = {20, 20}, | ||||
|       .color = {{0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}}, | ||||
|       .events = UI_EVENT_BUTTON, | ||||
|     }, | ||||
|   }; | ||||
| 
 | ||||
|   uint32_t codes[9]; | ||||
|   VkResult result; | ||||
|   VK_RESULT(map_string("#00000000", codes, 0, 0, &context->ui)); | ||||
| 
 | ||||
|   LayerInput layer = { | ||||
|     .strings = strings, | ||||
|     .num_strings = sizeof(strings)/sizeof(GPUString), | ||||
|     .codes = codes, | ||||
|     .num_codes = sizeof(codes)/sizeof(uint32_t), | ||||
|     .drawables = drawables, | ||||
|     .num_drawables = sizeof(drawables)/sizeof(GPUDrawable), | ||||
|   }; | ||||
| 
 | ||||
|   EditorData* data = context->app_data; | ||||
|   data->string_len = 8; | ||||
|   data->string[0] = '#'; | ||||
|   data->string[1] = '0'; | ||||
|   data->string[2] = '0'; | ||||
|   data->string[3] = '0'; | ||||
|   data->string[4] = '0'; | ||||
|   data->string[5] = '0'; | ||||
|   data->string[6] = '0'; | ||||
|   data->string[7] = 'F'; | ||||
|   data->string[8] = 'F'; | ||||
|   data->string[9] = '\0'; | ||||
| 
 | ||||
|   data->current[0] = 0; | ||||
|   data->current[1] = 0; | ||||
|   data->current[2] = 0; | ||||
|   data->current[3] = 1; | ||||
| 
 | ||||
|   for(uint32_t i = 0; i < 12; i++) { | ||||
|     data->saved[i][0] = 0; | ||||
|     data->saved[i][1] = 0; | ||||
|     data->saved[i][2] = 0; | ||||
|     data->saved[i][3] = 1; | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
|   UICallbacks callbacks[] = { | ||||
|     { | ||||
|       .layer = 0, | ||||
|       .element = 1, | ||||
|       .data = context->app_data, | ||||
|       .button = sv_square_button_callback, | ||||
|       .cursor = sv_square_cursor_callback, | ||||
|     }, | ||||
|     { | ||||
|       .layer = 0, | ||||
|       .element = 2, | ||||
|       .data = context->app_data, | ||||
|       .button = hue_bar_button_callback, | ||||
|       .cursor = hue_bar_cursor_callback, | ||||
|       .scroll = hue_bar_scroll_callback, | ||||
|     }, | ||||
|     { | ||||
|       .layer = 0, | ||||
|       .element = 5, | ||||
|       .data = context->app_data, | ||||
|       .button = hex_string_button_callback, | ||||
|       .key = hex_string_key_callback, | ||||
|       .text = hex_string_text_callback, | ||||
|       .deselect = hex_string_deselect_callback, | ||||
|     }, | ||||
|     SAVED_COLOR_CALLBACK_ENTRY( 0), | ||||
|     SAVED_COLOR_CALLBACK_ENTRY( 1), | ||||
|     SAVED_COLOR_CALLBACK_ENTRY( 2), | ||||
|     SAVED_COLOR_CALLBACK_ENTRY( 3), | ||||
|     SAVED_COLOR_CALLBACK_ENTRY( 4), | ||||
|     SAVED_COLOR_CALLBACK_ENTRY( 5), | ||||
|     SAVED_COLOR_CALLBACK_ENTRY( 6), | ||||
|     SAVED_COLOR_CALLBACK_ENTRY( 7), | ||||
|     SAVED_COLOR_CALLBACK_ENTRY( 8), | ||||
|     SAVED_COLOR_CALLBACK_ENTRY( 9), | ||||
|     SAVED_COLOR_CALLBACK_ENTRY(10), | ||||
|     SAVED_COLOR_CALLBACK_ENTRY(11), | ||||
|   }; | ||||
| 
 | ||||
|   ContainerInput container = { | ||||
|     .layers = &layer, | ||||
|     .layer_count = 1, | ||||
|     .anchor = ANCHOR_BOTTOM_LEFT, | ||||
|     .id = COLOR_PICK_CONTAINER_ID, | ||||
|     .offset = {0, 0}, | ||||
|     .size = {190, 150}, | ||||
|     .callbacks = callbacks, | ||||
|     .callback_count = sizeof(callbacks)/sizeof(UICallbacks), | ||||
|   }; | ||||
| 
 | ||||
|   return load_container(&container, &context->render, &context->ui); | ||||
| } | ||||
| 
 | ||||
| VkResult mode_string_ui(ClientContext* context) { | ||||
|   VkResult result; | ||||
| 
 | ||||
|   GPUString string = { | ||||
|     .pos = {0, 32}, | ||||
|     .font = 0, | ||||
|     .size = 32, | ||||
|     .length = strlen(ModeStrings[MODE_NONE]), | ||||
|     .color = {1, 1, 1, 1}, | ||||
|   }; | ||||
| 
 | ||||
|   uint32_t codes[8]; | ||||
|   VK_RESULT(map_string(ModeStrings[MODE_NONE], codes, 0, 0, &context->ui)); | ||||
| 
 | ||||
|   LayerInput layer = { | ||||
|     .max_codes = 8, | ||||
|     .codes = codes, | ||||
|     .num_codes = strlen(ModeStrings[MODE_NONE]), | ||||
|     .num_strings = 1, | ||||
|     .strings = &string, | ||||
|   }; | ||||
| 
 | ||||
|   ContainerInput container = { | ||||
|     .id = MODE_STRING_CONTAINER_ID, | ||||
|     .layer_count = 1, | ||||
|     .layers = &layer, | ||||
|     .anchor = ANCHOR_TOP_LEFT, | ||||
|     .size = {160, 40}, | ||||
|   }; | ||||
| 
 | ||||
|   return load_container(&container, &context->render, &context->ui); | ||||
| } | ||||
| 
 | ||||
| VkResult update_mode_string(ClientContext* context, EditorData* data) {  | ||||
|   Container* container = context_container(MODE_STRING_CONTAINER_ID, &context->ui); | ||||
|   return update_ui_string(ModeStrings[data->mode], container, 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; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   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; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 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; | ||||
| } | ||||
| 
 | ||||
| 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); | ||||
| } | ||||
| 
 | ||||
| void spin_cam_up(EditorData* data, ClientContext* context, int action, int mods) { | ||||
|   (void)data; | ||||
|   spin_cam(context, action, mods, 1, 1); | ||||
| } | ||||
| 
 | ||||
| void spin_cam_down(EditorData* data, ClientContext* context, int action, int mods) { | ||||
|   (void)data; | ||||
|   spin_cam(context, action, mods, 1, -1); | ||||
| } | ||||
| 
 | ||||
| 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; | ||||
| } | ||||
| 
 | ||||
| void move_cam_up(EditorData* data, ClientContext* context, int action, int mods) { | ||||
|   (void)data; | ||||
|   move_cam(context, action, mods, 1, 1); | ||||
| } | ||||
| 
 | ||||
| void move_cam_down(EditorData* data, ClientContext* context, int action, int mods) { | ||||
|   (void)data; | ||||
|   move_cam(context, action, mods, 1, -1); | ||||
| } | ||||
| 
 | ||||
| void move_cam_left(EditorData* data, ClientContext* context, int action, int mods) { | ||||
|   (void)data; | ||||
|   move_cam(context, action, mods, 0, -1); | ||||
| } | ||||
| 
 | ||||
| void move_cam_right(EditorData* data, ClientContext* context, int action, int mods) { | ||||
|   (void)data; | ||||
|   move_cam(context, action, mods, 0, 1); | ||||
| } | ||||
| 
 | ||||
| void move_cam_forward(EditorData* data, ClientContext* context, int action, int mods) { | ||||
|   (void)data; | ||||
|   move_cam(context, action, mods, 2, 1); | ||||
| } | ||||
| 
 | ||||
| void move_cam_backwards(EditorData* data, ClientContext* context, int action, int mods) { | ||||
|   (void)data; | ||||
|   move_cam(context, action, mods, 2, -1); | ||||
| } | ||||
| 
 | ||||
| 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); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 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) { | ||||
|   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_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); | ||||
| } | ||||
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								
		Loading…
	
		Reference in New Issue