|  |  |  | @ -1,4 +1,5 @@ | 
		
	
		
			
				|  |  |  |  | #include "GLFW/glfw3.h" | 
		
	
		
			
				|  |  |  |  | #include <stdio.h> | 
		
	
		
			
				|  |  |  |  | #define CGLM_PRINT_PRECISION 10 | 
		
	
		
			
				|  |  |  |  | #define CGLM_DEFINE_PRINTS 1 | 
		
	
		
			
				|  |  |  |  | #include "ui.h" | 
		
	
	
		
			
				
					|  |  |  | @ -41,6 +42,9 @@ typedef struct ClientContextStruct { | 
		
	
		
			
				|  |  |  |  |   float   cur_spin_speed; | 
		
	
		
			
				|  |  |  |  |   float   zoom_speed; | 
		
	
		
			
				|  |  |  |  |   float   move_speed; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   uint32_t selected_region; | 
		
	
		
			
				|  |  |  |  |   uint32_t last_selected_region; | 
		
	
		
			
				|  |  |  |  | } ClientContext; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void* network_thread(void* data) { | 
		
	
	
		
			
				
					|  |  |  | @ -79,42 +83,101 @@ VkResult add_hex_region(ClientContext* context) { | 
		
	
		
			
				|  |  |  |  |   return VK_SUCCESS; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | VkResult main_thread(ClientContext* context) { | 
		
	
		
			
				|  |  |  |  |   VkResult result; | 
		
	
		
			
				|  |  |  |  | char region_info_strs[][20] = { | 
		
	
		
			
				|  |  |  |  |   "Region XXXX", | 
		
	
		
			
				|  |  |  |  |   "Q: XXXX", | 
		
	
		
			
				|  |  |  |  |   "R: XXXX", | 
		
	
		
			
				|  |  |  |  |   "Y: XXXX", | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | uint32_t region_info_str_off[] = { | 
		
	
		
			
				|  |  |  |  |   0, | 
		
	
		
			
				|  |  |  |  |   11, | 
		
	
		
			
				|  |  |  |  |   18, | 
		
	
		
			
				|  |  |  |  |   25, | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | VkResult region_info_ui(ClientContext* context) { | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   GPUString strings[] = { | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       .pos = {0, 32}, | 
		
	
		
			
				|  |  |  |  |       .pos = {0, 33}, | 
		
	
		
			
				|  |  |  |  |       .color = {1, 1, 1, 1}, | 
		
	
		
			
				|  |  |  |  |       .size = 32, | 
		
	
		
			
				|  |  |  |  |       .offset = region_info_str_off[0], | 
		
	
		
			
				|  |  |  |  |       .length = strlen(region_info_strs[0]), | 
		
	
		
			
				|  |  |  |  |       .font = 0, | 
		
	
		
			
				|  |  |  |  |     }, | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       .pos = {0, 33 + 1*40}, | 
		
	
		
			
				|  |  |  |  |       .color = {1, 1, 1, 1}, | 
		
	
		
			
				|  |  |  |  |       .size = 32, | 
		
	
		
			
				|  |  |  |  |       .color = {1.0, 1.0, 1.0, 1.0}, | 
		
	
		
			
				|  |  |  |  |       .offset = 0, | 
		
	
		
			
				|  |  |  |  |       .length = 0, | 
		
	
		
			
				|  |  |  |  |       .offset = region_info_str_off[1], | 
		
	
		
			
				|  |  |  |  |       .length = strlen(region_info_strs[1]), | 
		
	
		
			
				|  |  |  |  |       .font = 0, | 
		
	
		
			
				|  |  |  |  |     }, | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       .pos = {0, 33 + 2*40}, | 
		
	
		
			
				|  |  |  |  |       .color = {1, 1, 1, 1}, | 
		
	
		
			
				|  |  |  |  |       .size = 32, | 
		
	
		
			
				|  |  |  |  |       .offset = region_info_str_off[2], | 
		
	
		
			
				|  |  |  |  |       .length = strlen(region_info_strs[2]), | 
		
	
		
			
				|  |  |  |  |       .font = 0, | 
		
	
		
			
				|  |  |  |  |     }, | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       .pos = {0, 33 + 3*40}, | 
		
	
		
			
				|  |  |  |  |       .color = {1, 1, 1, 1}, | 
		
	
		
			
				|  |  |  |  |       .size = 32, | 
		
	
		
			
				|  |  |  |  |       .offset = region_info_str_off[3], | 
		
	
		
			
				|  |  |  |  |       .length = strlen(region_info_strs[3]), | 
		
	
		
			
				|  |  |  |  |       .font = 0, | 
		
	
		
			
				|  |  |  |  |     }, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   GPUDrawable drawables[] = {}; | 
		
	
		
			
				|  |  |  |  |   uint32_t codes[43/4]; | 
		
	
		
			
				|  |  |  |  |   VkResult result; | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(map_string(region_info_strs[0], codes, region_info_str_off[0], 0, context->ui)); | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(map_string(region_info_strs[1], codes, region_info_str_off[1], 0, context->ui)); | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(map_string(region_info_strs[2], codes, region_info_str_off[2], 0, context->ui)); | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(map_string(region_info_strs[3], codes, region_info_str_off[3], 0, context->ui)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   GPUDrawable drawables[] = { | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       .pos = {0, 0}, | 
		
	
		
			
				|  |  |  |  |       .size = {225, 155}, | 
		
	
		
			
				|  |  |  |  |       .color = {0.4, 0.4, 0.4, 0.4}, | 
		
	
		
			
				|  |  |  |  |     }, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   LayerInput layer = { | 
		
	
		
			
				|  |  |  |  |     .strings = strings, | 
		
	
		
			
				|  |  |  |  |     .num_strings = sizeof(strings)/sizeof(GPUString), | 
		
	
		
			
				|  |  |  |  |     .max_codes = 50, | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     .max_strings = sizeof(strings)/sizeof(GPUString) + 4, | 
		
	
		
			
				|  |  |  |  |     .codes = codes, | 
		
	
		
			
				|  |  |  |  |     .num_codes = sizeof(codes)/sizeof(uint32_t), | 
		
	
		
			
				|  |  |  |  |     .max_codes = sizeof(codes)/sizeof(uint32_t) + 100, | 
		
	
		
			
				|  |  |  |  |     .drawables = drawables, | 
		
	
		
			
				|  |  |  |  |     .num_drawables = sizeof(drawables)/sizeof(GPUDrawable), | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   ContainerInput container = { | 
		
	
		
			
				|  |  |  |  |     .id = 1, | 
		
	
		
			
				|  |  |  |  |     .size = {WINDOW_MIN_WIDTH, WINDOW_MIN_HEIGHT}, | 
		
	
		
			
				|  |  |  |  |     .layer_count = 1, | 
		
	
		
			
				|  |  |  |  |   ContainerInput region_info = { | 
		
	
		
			
				|  |  |  |  |     .id = 0x01, | 
		
	
		
			
				|  |  |  |  |     .size = {225, 155}, | 
		
	
		
			
				|  |  |  |  |     .offset = {0, 0}, | 
		
	
		
			
				|  |  |  |  |     .anchor = ANCHOR_TOP_RIGHT, | 
		
	
		
			
				|  |  |  |  |     .layers = &layer, | 
		
	
		
			
				|  |  |  |  |     .layer_count = 1, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   create_container(&container, context->render, context->ui); | 
		
	
		
			
				|  |  |  |  |   return create_container(®ion_info, context->render, context->ui); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | VkResult main_thread(ClientContext* context) { | 
		
	
		
			
				|  |  |  |  |   VkResult result; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VK_RESULT(region_info_ui(context)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   //
 | 
		
	
		
			
				|  |  |  |  |   int frame = 0; | 
		
	
		
			
				|  |  |  |  |   double last_frame_time = 0; | 
		
	
		
			
				|  |  |  |  |   while(glfwWindowShouldClose(context->window) == 0) { | 
		
	
		
			
				|  |  |  |  |     double frame_time = glfwGetTime(); | 
		
	
	
		
			
				
					|  |  |  | @ -128,16 +191,68 @@ VkResult main_thread(ClientContext* context) { | 
		
	
		
			
				|  |  |  |  |     context->cur_spin[1] = 0; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     glfwPollEvents(); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if(context->selected_region != context->last_selected_region) { | 
		
	
		
			
				|  |  |  |  |       context->last_selected_region = context->selected_region; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       HexRegion* selected_region = context->hex->regions[context->selected_region]; | 
		
	
		
			
				|  |  |  |  |       snprintf(region_info_strs[0], | 
		
	
		
			
				|  |  |  |  |           sizeof(region_info_strs[0]), | 
		
	
		
			
				|  |  |  |  |           "Region %4d", context->selected_region); | 
		
	
		
			
				|  |  |  |  |       VK_RESULT(update_ui_string(region_info_strs[0], 0, 0, 0, context->ui, context->render)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       if(selected_region == NULL) { | 
		
	
		
			
				|  |  |  |  |         snprintf( | 
		
	
		
			
				|  |  |  |  |             region_info_strs[1], | 
		
	
		
			
				|  |  |  |  |             sizeof(region_info_strs[1]), | 
		
	
		
			
				|  |  |  |  |             ""); | 
		
	
		
			
				|  |  |  |  |         VK_RESULT(update_ui_string(region_info_strs[1], 0, 0, 1, context->ui, context->render)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         snprintf( | 
		
	
		
			
				|  |  |  |  |             region_info_strs[2], | 
		
	
		
			
				|  |  |  |  |             sizeof(region_info_strs[2]), | 
		
	
		
			
				|  |  |  |  |             ""); | 
		
	
		
			
				|  |  |  |  |         VK_RESULT(update_ui_string(region_info_strs[2], 0, 0, 2, context->ui, context->render)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         snprintf( | 
		
	
		
			
				|  |  |  |  |             region_info_strs[3], | 
		
	
		
			
				|  |  |  |  |             sizeof(region_info_strs[3]), | 
		
	
		
			
				|  |  |  |  |             ""); | 
		
	
		
			
				|  |  |  |  |         VK_RESULT(update_ui_string(region_info_strs[3], 0, 0, 3, context->ui, context->render)); | 
		
	
		
			
				|  |  |  |  |       } else { | 
		
	
		
			
				|  |  |  |  |         snprintf( | 
		
	
		
			
				|  |  |  |  |             region_info_strs[1], | 
		
	
		
			
				|  |  |  |  |             sizeof(region_info_strs[1]), | 
		
	
		
			
				|  |  |  |  |             "Q: %4d", selected_region->data.q); | 
		
	
		
			
				|  |  |  |  |         VK_RESULT(update_ui_string(region_info_strs[1], 0, 0, 1, context->ui, context->render)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         snprintf( | 
		
	
		
			
				|  |  |  |  |             region_info_strs[2], | 
		
	
		
			
				|  |  |  |  |             sizeof(region_info_strs[2]), | 
		
	
		
			
				|  |  |  |  |             "R: %4d", selected_region->data.r); | 
		
	
		
			
				|  |  |  |  |         VK_RESULT(update_ui_string(region_info_strs[2], 0, 0, 2, context->ui, context->render)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         snprintf( | 
		
	
		
			
				|  |  |  |  |             region_info_strs[3], | 
		
	
		
			
				|  |  |  |  |             sizeof(region_info_strs[3]), | 
		
	
		
			
				|  |  |  |  |             "Y: %4d", selected_region->data.y); | 
		
	
		
			
				|  |  |  |  |         VK_RESULT(update_ui_string(region_info_strs[3], 0, 0, 3, context->ui, context->render)); | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if((context->key_spin[0] != 0 || context->key_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) && frame > 0) { | 
		
	
		
			
				|  |  |  |  |        context->render->framebuffer_recreated == true)) { | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       if(context->render->framebuffer_recreated == true) { | 
		
	
		
			
				|  |  |  |  |         context->render->framebuffer_recreated = false; | 
		
	
		
			
				|  |  |  |  |         VK_RESULT(update_hex_proj(context->render, context->hex)); | 
		
	
		
			
				|  |  |  |  |         VK_RESULT(update_ui_context_resolution(context->ui, context->render)); | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       context->rotation[0] += (float)context->key_spin[0]*delta_time*context->key_spin_speed;  | 
		
	
	
		
			
				
					|  |  |  | @ -183,7 +298,6 @@ VkResult main_thread(ClientContext* context) { | 
		
	
		
			
				|  |  |  |  |       fprintf(stderr, "draw_frame error: %s\n", string_VkResult(result)); | 
		
	
		
			
				|  |  |  |  |       glfwDestroyWindow(context->window); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     frame += 1; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     last_frame_time = frame_time; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
	
		
			
				
					|  |  |  | @ -272,10 +386,27 @@ void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod | 
		
	
		
			
				|  |  |  |  |     break; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   case GLFW_KEY_EQUAL: | 
		
	
		
			
				|  |  |  |  |     if(action == GLFW_RELEASE) { | 
		
	
		
			
				|  |  |  |  |     if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |       add_hex_region(context); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     break; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   case GLFW_KEY_LEFT_BRACKET: | 
		
	
		
			
				|  |  |  |  |     if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |       context->selected_region -= 1; | 
		
	
		
			
				|  |  |  |  |       if(context->selected_region > MAX_LOADED_REGIONS) { | 
		
	
		
			
				|  |  |  |  |         context->selected_region = MAX_LOADED_REGIONS; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     break; | 
		
	
		
			
				|  |  |  |  |   case GLFW_KEY_RIGHT_BRACKET: | 
		
	
		
			
				|  |  |  |  |     if(action == GLFW_PRESS) { | 
		
	
		
			
				|  |  |  |  |       context->selected_region += 1; | 
		
	
		
			
				|  |  |  |  |       if(context->selected_region > MAX_LOADED_REGIONS) { | 
		
	
		
			
				|  |  |  |  |         context->selected_region = 0; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     break; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -374,6 +505,9 @@ int main() { | 
		
	
		
			
				|  |  |  |  |     .cur_spin_speed = 1.0, | 
		
	
		
			
				|  |  |  |  |     .zoom_speed = 1.0, | 
		
	
		
			
				|  |  |  |  |     .move_speed = 0.1, | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     .selected_region = MAX_LOADED_REGIONS, | 
		
	
		
			
				|  |  |  |  |     .last_selected_region = 0, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  |   if(context.window == NULL || context.render == NULL || context.ui == NULL || context.hex == NULL) { | 
		
	
		
			
				|  |  |  |  |     return VK_ERROR_OUT_OF_HOST_MEMORY; | 
		
	
	
		
			
				
					|  |  |  | 
 |