272 lines
8.8 KiB
Plaintext
272 lines
8.8 KiB
Plaintext
#import "File_Utilities";
|
|
|
|
console : *Console;
|
|
|
|
Command_Proc :: struct {
|
|
name: string;
|
|
proc: (arguments: [] string, buffer: *[..] Buffer_Entry);
|
|
}
|
|
|
|
Buffer_Entry :: struct {
|
|
text: string;
|
|
color: Color;
|
|
}
|
|
|
|
Console :: struct {
|
|
buffer: [..] Buffer_Entry;
|
|
current_string: string;
|
|
commands: [..] Command_Proc;
|
|
|
|
active: bool;
|
|
visible: bool;
|
|
open_amount: float;
|
|
animation_position: float; // 1.0 means fully visible
|
|
|
|
font: Font_Handle;
|
|
rect_pipeline: Pipeline_State_Handle;
|
|
text_pipeline: Pipeline_State_Handle;
|
|
vb: Buffer_Handle;
|
|
cursor_vb: Buffer_Handle;
|
|
verts: [..] Colored_Vert;
|
|
}
|
|
|
|
add_command :: (console: *Console, cmd: string, proc: (arguments: [] string, buffer: *[..] Buffer_Entry)) {
|
|
command : Command_Proc;
|
|
command.name = copy_string(cmd);
|
|
command.proc = proc;
|
|
|
|
array_add(*console.commands, command);
|
|
}
|
|
|
|
init_console :: () {
|
|
console = New(Console);
|
|
console.verts.allocator = temp;
|
|
buffer_size := size_of(Colored_Vert) * 12;
|
|
console.vb = create_vertex_buffer(renderer, null, xx buffer_size, stride=size_of(Colored_Vert), mappable=true);
|
|
console.cursor_vb = create_vertex_buffer(renderer, null, xx buffer_size, stride=size_of(Colored_Vert), mappable=true);
|
|
|
|
{
|
|
vs := create_vertex_shader(renderer, "../assets/shaders/ui_rect.hlsl", "VS");
|
|
ps := create_pixel_shader(renderer, "../assets/shaders/ui_rect.hlsl", "PS");
|
|
|
|
layout : [2] Vertex_Data_Info;
|
|
layout[0] = .{0, .POSITION2D, 0};
|
|
layout[1] = .{0, .COLOR_WITH_ALPHA, 0};
|
|
params : [0] Shader_Parameter;
|
|
|
|
console.rect_pipeline = create_pipeline_state(renderer, vs, ps, layout, params, blend_type=.TRANSPARENT);
|
|
}
|
|
|
|
{
|
|
vs := create_vertex_shader(renderer, "../assets/shaders/font.hlsl", "VS");
|
|
ps := create_pixel_shader(renderer, "../assets/shaders/font.hlsl", "PS");
|
|
|
|
layout : [3] Vertex_Data_Info;
|
|
layout[0] = .{0,.POSITION2D, 0};
|
|
layout[1] = .{0,.TEXCOORD0, 0};
|
|
layout[2] = .{0,.COLOR_WITH_ALPHA, 0};
|
|
params : [0] Shader_Parameter;
|
|
|
|
console.text_pipeline = create_pipeline_state(renderer, vs, ps, layout, params, blend_type=.TRANSPARENT);
|
|
}
|
|
|
|
console.font = create_font(renderer, "../assets/fonts/Inconsolata-Regular.ttf", 18);
|
|
console.current_string = alloc_string(256);
|
|
console.current_string.count = 0;
|
|
|
|
//add_command(console, "stats", toggle_stats);
|
|
//add_command(console, "camset", save_camera);
|
|
//add_command(console, "load", load_scene);
|
|
//add_command(console, "copy", copy_scene);
|
|
//add_command(console, "vsync", set_vsync);
|
|
|
|
//engine.console = console;
|
|
}
|
|
|
|
find_command :: (console: *Console, cmd_str: string) -> Command_Proc, bool {
|
|
for console.commands {
|
|
if equal(it.name, cmd_str) {
|
|
return it, true;
|
|
}
|
|
}
|
|
|
|
return .{}, false;
|
|
}
|
|
|
|
update_console :: () {
|
|
if key_down(.TILDE) {
|
|
console.active = !console.active;
|
|
input.has_char = false; // Make sure that the tilde is not used as the first input character in the console
|
|
}
|
|
|
|
if console.active {
|
|
if key_down(.BACKSPACE) {
|
|
if console.current_string.count > 0 {
|
|
console.current_string.count -= 1;
|
|
}
|
|
}
|
|
|
|
if key_down(.RETURN) {
|
|
if console.current_string.count > 0 {
|
|
// @Incomplete(niels): Using split with space will take spaces as part of the args.
|
|
// So each subsequent space will be an argument itself.
|
|
// This is a bit of a hacky fix for now
|
|
arguments := split(console.current_string, " ");
|
|
index := 0;
|
|
while index < arguments.count - 1 {
|
|
if arguments[index].count == 0 {
|
|
arguments[index] = arguments[arguments.count - 1];
|
|
arguments.count -= 1;
|
|
} else {
|
|
index += 1;
|
|
}
|
|
}
|
|
|
|
if arguments[arguments.count - 1].count == 0 {
|
|
arguments.count -= 1;
|
|
}
|
|
|
|
cmd, success := find_command(console, arguments[0]);
|
|
|
|
push_entry(*console.buffer, console.current_string, .{1,1,1,1});
|
|
|
|
if success {
|
|
cmd.proc(arguments, *console.buffer);
|
|
} else {
|
|
push_entry(*console.buffer, console.current_string, .{1,0,0,1});
|
|
}
|
|
|
|
console.current_string.count = 0;
|
|
}
|
|
}
|
|
|
|
if input.has_char {
|
|
if console.current_string.count < 256 {
|
|
console.current_string.data[console.current_string.count] = xx input.current_char;
|
|
console.current_string.count += 1;
|
|
input.has_char = false;
|
|
}
|
|
}
|
|
|
|
eat_all_input(*input);
|
|
}
|
|
}
|
|
|
|
make_vert :: (x: float, y: float, color: Color) -> Colored_Vert {
|
|
vert : Colored_Vert;
|
|
vert.position.x = x;
|
|
vert.position.y = y;
|
|
vert.color = color;
|
|
return vert;
|
|
}
|
|
|
|
add_rect :: (renderer: *Renderer, x: float, y: float, width: float, height: float, color: Color, verts: *[..] Colored_Vert) {
|
|
inv_w := 1.0 / cast(float)renderer.render_target_width;
|
|
inv_h := 1.0 / cast(float)renderer.render_target_height;
|
|
|
|
x = x * inv_w * 2.0 - 1.0;
|
|
y = (cast(float)renderer.render_target_height - y) * inv_h * 2.0 - 1.0;
|
|
w : float = width * inv_w * 2.0;
|
|
h : float = height * inv_h * 2.0;
|
|
|
|
array_add(verts, make_vert(x + w, y - h, color));
|
|
array_add(verts, make_vert(x, y - h, color));
|
|
array_add(verts, make_vert(x, y, color));
|
|
|
|
array_add(verts, make_vert(x + w, y - h, color));
|
|
array_add(verts, make_vert(x, y, color));
|
|
array_add(verts, make_vert(x + w, y, color));
|
|
}
|
|
|
|
render_console :: () {
|
|
if console.active {
|
|
console.visible = true;
|
|
console.open_amount += dt * 3.0;
|
|
} else {
|
|
console.open_amount -= dt * 3.0;
|
|
if console.open_amount <= 0.0 {
|
|
console.visible = false;
|
|
}
|
|
}
|
|
|
|
console.open_amount = clamp(console.open_amount, 0.0, 1.0);
|
|
|
|
if !console.visible return;
|
|
|
|
offset_y := (1.0 - console.open_amount) * 200.0 - 75;
|
|
|
|
console.verts.count = 0;
|
|
console_color : Color = .{48.0/255.0, 64.0/255.0, 36.0/255.0, 0.7};
|
|
console_line_color : Color = .{18.0/255.0, 34.0/255.0, 6.0/255.0, 0.7};
|
|
|
|
add_rect(renderer, 0.0, cast(float)renderer.render_target_height - 200 + offset_y, cast(float)renderer.render_target_width, 200.0, console_color, *console.verts);
|
|
add_rect(renderer, 0.0, cast(float)renderer.render_target_height - 30 + offset_y, cast(float)renderer.render_target_width, 30.0, console_line_color , *console.verts);
|
|
|
|
upload_data_to_buffer(renderer, console.vb, console.verts.data, cast(s32)console.verts.count * size_of(Colored_Vert));
|
|
|
|
push_cmd_set_draw_mode(renderer, .FILL);
|
|
push_cmd_set_depth_write(renderer, false);
|
|
push_cmd_set_pipeline_state(renderer, console.rect_pipeline);
|
|
|
|
push_cmd_set_vertex_buffer(renderer, console.vb);
|
|
push_cmd_draw(renderer, console.verts.count);
|
|
|
|
push_cmd_set_pipeline_state(renderer, console.text_pipeline);
|
|
font := *renderer.fonts[console.font - 1];
|
|
push_cmd_set_texture(renderer, 0, font.texture);
|
|
|
|
size := get_text_size(renderer, ">", console.font);
|
|
|
|
render_data := bake_text(renderer, 5.0, size.y - offset_y, ">", console.font, .{1,1,1,1});
|
|
push_cmd_set_vertex_buffer(renderer, render_data.vb);
|
|
push_cmd_draw(renderer, render_data.vert_count);
|
|
|
|
x := 15.0;
|
|
|
|
if console.current_string.count > 0 {
|
|
render_data := bake_text(renderer, x, size.y - offset_y, console.current_string, console.font, .{1,1,1,1});
|
|
push_cmd_set_vertex_buffer(renderer, render_data.vb);
|
|
push_cmd_draw(renderer, render_data.vert_count);
|
|
|
|
x = 10 + render_data.size.x + 2.0;
|
|
}
|
|
|
|
y := 37.0;
|
|
i := console.buffer.count - 1;
|
|
count := 0;
|
|
|
|
while i >= 0 && count < 8 {
|
|
defer i -= 1;
|
|
defer count += 1;
|
|
|
|
entry := console.buffer[i];
|
|
|
|
render_data := bake_text(renderer, 15.0, y - offset_y, entry.text, console.font, entry.color);
|
|
push_cmd_set_vertex_buffer(renderer, render_data.vb);
|
|
push_cmd_draw(renderer, render_data.vert_count);
|
|
|
|
y += 20.0;
|
|
}
|
|
|
|
console.verts.count = 0;
|
|
|
|
//#if !NEW_UI {
|
|
add_rect(renderer, x, cast(float)renderer.render_target_height - 25 + offset_y, 10, 20.0, .{1,1,1,1}, *console.verts);
|
|
//}
|
|
|
|
upload_data_to_buffer(renderer, console.cursor_vb, console.verts.data, cast(s32)console.verts.count * size_of(Colored_Vert));
|
|
|
|
push_cmd_set_draw_mode(renderer, .FILL);
|
|
push_cmd_set_depth_write(renderer, false);
|
|
push_cmd_set_pipeline_state(renderer, console.rect_pipeline);
|
|
push_cmd_set_vertex_buffer(renderer, console.cursor_vb);
|
|
push_cmd_draw(renderer, console.verts.count);
|
|
}
|
|
|
|
push_entry :: (buffer: *[..] Buffer_Entry, text: string, color: Color) {
|
|
entry : Buffer_Entry;
|
|
entry.text = copy_string(text);
|
|
entry.color = color;
|
|
array_add(buffer, entry);
|
|
}
|