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