gud ui
This commit is contained in:
372
attempt_1/main.c
372
attempt_1/main.c
@@ -465,13 +465,76 @@ IA_ void compile_and_run_tape(void)
|
||||
debug_log(str8("JIT finished. RAX: <rax>, RDX: <rdx>"), ktl_str8_from_arr(post_jit_log_table));
|
||||
}
|
||||
|
||||
|
||||
#undef r
|
||||
#undef v
|
||||
#undef expect
|
||||
#include "microui.c"
|
||||
#undef expect
|
||||
#define expect(x,y) __builtin_expect(x, y) // so compiler knows the common path
|
||||
#define r restrict
|
||||
#define v volatile
|
||||
|
||||
global mu_Context mu_ctx;
|
||||
|
||||
internal int text_width_cb(mu_Font font, const char *str, int len) {
|
||||
if (len == -1) { len = 0; while (str[len]) len++; }
|
||||
return len * 11; // Approx 11px per char for Consolas 20
|
||||
}
|
||||
|
||||
internal int text_height_cb(mu_Font font) {
|
||||
return 20; // Consolas 20 height
|
||||
}
|
||||
|
||||
internal void gdi_draw_rect(void* hdc, mu_Rect rect, mu_Color color) {
|
||||
U1 red = ((U1*)&color)[0];
|
||||
U1 green = ((U1*)&color)[1];
|
||||
U1 blue = ((U1*)&color)[2];
|
||||
void* hBrush = ms_create_solid_brush((red) | (green << 8) | (blue << 16));
|
||||
void* hOldBrush = ms_select_object(hdc, hBrush);
|
||||
ms_rectangle(hdc, rect.x - 1, rect.y - 1, rect.x + rect.w + 1, rect.y + rect.h + 1);
|
||||
ms_select_object(hdc, hOldBrush);
|
||||
ms_delete_object(hBrush);
|
||||
}
|
||||
|
||||
internal void render_microui(void* hdc) {
|
||||
mu_Command *cmd = NULL;
|
||||
while (mu_next_command(&mu_ctx, &cmd)) {
|
||||
switch (cmd->type) {
|
||||
case MU_COMMAND_TEXT: {
|
||||
U1 red = ((U1*)&cmd->text.color)[0];
|
||||
U1 green = ((U1*)&cmd->text.color)[1];
|
||||
U1 blue = ((U1*)&cmd->text.color)[2];
|
||||
ms_set_text_color(hdc, (red) | (green << 8) | (blue << 16));
|
||||
int len = 0; while (cmd->text.str[len]) len++;
|
||||
ms_text_out_a(hdc, cmd->text.pos.x, cmd->text.pos.y, cmd->text.str, len);
|
||||
break;
|
||||
}
|
||||
case MU_COMMAND_RECT: {
|
||||
gdi_draw_rect(hdc, cmd->rect.rect, cmd->rect.color);
|
||||
break;
|
||||
}
|
||||
case MU_COMMAND_ICON: {
|
||||
gdi_draw_rect(hdc, cmd->icon.rect, cmd->icon.color);
|
||||
break;
|
||||
}
|
||||
case MU_COMMAND_CLIP: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam)
|
||||
{
|
||||
U8 tape_count = tape_arena.used / sizeof(U4);
|
||||
U4*r tape_ptr = u4_r(tape_arena.start);
|
||||
switch (msg) {
|
||||
case MS_WM_CHAR: {
|
||||
if (editor_mode != MODE_EDIT) return 0;
|
||||
char buf[2] = { (char)wparam, 0 };
|
||||
mu_input_text(&mu_ctx, buf);
|
||||
|
||||
if (editor_mode != MODE_EDIT) { ms_invalidate_rect(hwnd, nullptr, true); return 0; }
|
||||
|
||||
U4 t = tape_ptr[cursor_idx];
|
||||
U4 tag = unpack_tag(t);
|
||||
@@ -479,7 +542,7 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam)
|
||||
U1 c = u1_(wparam);
|
||||
|
||||
B4 should_skip = c < 32 || (c == 'e' && mode_switch_now);
|
||||
if (should_skip) { mode_switch_now = false; return 0; }
|
||||
if (should_skip) { mode_switch_now = false; ms_invalidate_rect(hwnd, nullptr, true); return 0; }
|
||||
|
||||
if (tag == STag_Data) {
|
||||
U4 digit = 16;
|
||||
@@ -512,7 +575,34 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam)
|
||||
ms_invalidate_rect(hwnd, nullptr, true);
|
||||
return 0;
|
||||
}
|
||||
case MS_WM_MOUSEMOVE: {
|
||||
mu_input_mousemove(&mu_ctx, lparam & 0xFFFF, (lparam >> 16) & 0xFFFF);
|
||||
ms_invalidate_rect(hwnd, nullptr, true);
|
||||
return 0;
|
||||
}
|
||||
case MS_WM_LBUTTONDOWN: {
|
||||
mu_input_mousedown(&mu_ctx, lparam & 0xFFFF, (lparam >> 16) & 0xFFFF, MU_MOUSE_LEFT);
|
||||
ms_invalidate_rect(hwnd, nullptr, true);
|
||||
return 0;
|
||||
}
|
||||
case MS_WM_LBUTTONUP: {
|
||||
mu_input_mouseup(&mu_ctx, lparam & 0xFFFF, (lparam >> 16) & 0xFFFF, MU_MOUSE_LEFT);
|
||||
ms_invalidate_rect(hwnd, nullptr, true);
|
||||
return 0;
|
||||
}
|
||||
case MS_WM_MOUSEWHEEL: {
|
||||
mu_input_scroll(&mu_ctx, 0, ((S4)(wparam >> 16)) / -30);
|
||||
ms_invalidate_rect(hwnd, nullptr, true);
|
||||
return 0;
|
||||
}
|
||||
case MS_WM_KEYDOWN: {
|
||||
int key = 0;
|
||||
if (wparam == MS_VK_BACK) key = MU_KEY_BACKSPACE;
|
||||
if (wparam == MS_VK_RETURN) key = MU_KEY_RETURN;
|
||||
if (wparam == 0x10) key = MU_KEY_SHIFT;
|
||||
if (wparam == 0x11) key = MU_KEY_CTRL;
|
||||
if (wparam == 0x12) key = MU_KEY_ALT;
|
||||
if (key) mu_input_keydown(&mu_ctx, key);
|
||||
|
||||
if (wparam == 0x45 && editor_mode == MODE_NAV) {
|
||||
editor_mode = MODE_EDIT;
|
||||
@@ -650,115 +740,122 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam)
|
||||
ms_invalidate_rect(hwnd, nullptr, true);
|
||||
return 0;
|
||||
}
|
||||
case MS_WM_KEYUP: {
|
||||
int key = 0;
|
||||
if (wparam == MS_VK_BACK) key = MU_KEY_BACKSPACE;
|
||||
if (wparam == MS_VK_RETURN) key = MU_KEY_RETURN;
|
||||
if (wparam == 0x10) key = MU_KEY_SHIFT;
|
||||
if (wparam == 0x11) key = MU_KEY_CTRL;
|
||||
if (wparam == 0x12) key = MU_KEY_ALT;
|
||||
if (key) mu_input_keyup(&mu_ctx, key);
|
||||
ms_invalidate_rect(hwnd, nullptr, true);
|
||||
return 0;
|
||||
}
|
||||
case MS_WM_SIZE: {
|
||||
ms_invalidate_rect(hwnd, nullptr, true);
|
||||
return 0;
|
||||
}
|
||||
case MS_WM_ERASEBKGND: {
|
||||
return 1;
|
||||
}
|
||||
case MS_WM_PAINT: {
|
||||
MS_PAINTSTRUCT ps;
|
||||
void* hdc = ms_begin_paint(hwnd, & ps);
|
||||
void* hFont = ms_create_font_a(20, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, "Consolas");
|
||||
void* hOldFont = ms_select_object(hdc, hFont);
|
||||
mu_begin(&mu_ctx);
|
||||
|
||||
ms_set_bk_mode(hdc, 1);
|
||||
if (mu_begin_window(&mu_ctx, "ColorForth Source Tape", mu_rect(10, 10, 900, 480))) {
|
||||
U4*r tape_ptr = u4_r(tape_arena.start);
|
||||
U8*r anno_ptr = u8_r(anno_arena.start);
|
||||
|
||||
void* hBgBrush = ms_create_solid_brush(0x00222222);
|
||||
ms_select_object(hdc, hBgBrush);
|
||||
ms_rectangle(hdc, -1, -1, 3000, 3000);
|
||||
S4 start_x = 5, start_y = 5, spacing_x = 6, spacing_y = 26;
|
||||
S4 x = start_x, y = start_y;
|
||||
|
||||
void* hBrushEdit = ms_create_solid_brush(0x008E563B);
|
||||
void* hBrushNav = ms_create_solid_brush(0x00262F3B);
|
||||
for (U8 i = 0; i < tape_count; i++) {
|
||||
U4 t = tape_ptr[i];
|
||||
U4 tag = unpack_tag(t);
|
||||
U4 val = unpack_val(t);
|
||||
U8 anno = anno_ptr[i];
|
||||
|
||||
S4 start_x = 40, start_y = 60, spacing_x = 110, spacing_y = 35;
|
||||
S4 x = start_x, y = start_y;
|
||||
if (tag == STag_Format && val == 0xA) {
|
||||
x = start_x;
|
||||
y += spacing_y;
|
||||
continue;
|
||||
}
|
||||
|
||||
U4*r tape_ptr = u4_r(tape_arena.start);
|
||||
U8*r anno_ptr = u8_r(anno_arena.start);
|
||||
U4 color_u32 = tag_colors[tag];
|
||||
const char* prefix = tag_prefixes[tag];
|
||||
|
||||
char val_str[9];
|
||||
if (tag == STag_Data) {
|
||||
u64_to_hex(val, val_str, 6);
|
||||
val_str[6] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
char* a_str = (char*) & anno;
|
||||
for(int c=0; c<8; c++) {
|
||||
val_str[c] = a_str[c] ? a_str[c] : ' ';
|
||||
}
|
||||
val_str[8] = '\0';
|
||||
}
|
||||
char out_buf[12];
|
||||
out_buf[0] = prefix[0];
|
||||
out_buf[1] = ' ';
|
||||
mem_copy(u8_(out_buf + 2), u8_(val_str), 8);
|
||||
out_buf[10] = '\0';
|
||||
|
||||
for (U8 i = 0; i < tape_count; i++)
|
||||
{
|
||||
if (x >= start_x + (TOKENS_PER_ROW * spacing_x)) {
|
||||
x = start_x; y += spacing_y;
|
||||
}
|
||||
S4 render_y = y - scroll_y_offset;
|
||||
if (i == cursor_idx && render_y >= 30 && render_y < 500) {
|
||||
ms_select_object(hdc, editor_mode == MODE_EDIT ? hBrushEdit : hBrushNav);
|
||||
ms_rectangle(hdc, x - 5, render_y - 2, x + 95, render_y + 22);
|
||||
}
|
||||
if (render_y >= 30 && render_y < 500)
|
||||
{
|
||||
U4 t = tape_ptr[i];
|
||||
U4 tag = unpack_tag(t);
|
||||
U4 val = unpack_val(t);
|
||||
U8 anno = anno_ptr[i];
|
||||
if (tag == STag_Format && val == 0xA) {
|
||||
ms_set_text_color(hdc, 0x00444444);
|
||||
ms_text_out_a(hdc, x, render_y, " \\n ", 6);
|
||||
x = start_x;
|
||||
y += spacing_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
U4 color = tag_colors[tag];
|
||||
const char* prefix = tag_prefixes[tag];
|
||||
|
||||
ms_set_text_color(hdc, color);
|
||||
if (editor_mode == MODE_EDIT && i == cursor_idx) {
|
||||
ms_set_text_color(hdc, 0x001E1E1E);
|
||||
}
|
||||
|
||||
char val_str[9];
|
||||
if (tag == STag_Data) {
|
||||
u64_to_hex(val, val_str, 6);
|
||||
val_str[6] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
char* a_str = (char*) & anno;
|
||||
for(int c=0; c<8; c++) {
|
||||
val_str[c] = a_str[c] ? a_str[c] : ' ';
|
||||
}
|
||||
val_str[8] = '\0';
|
||||
}
|
||||
char out_buf[12];
|
||||
out_buf[0] = prefix[0];
|
||||
out_buf[1] = ' ';
|
||||
mem_copy(u8_(out_buf + 2), u8_(val_str), 8);
|
||||
out_buf[10] = '\0';
|
||||
|
||||
ms_text_out_a(hdc, x, render_y, out_buf, 10);
|
||||
x += spacing_x;
|
||||
}
|
||||
}
|
||||
else if (unpack_tag(tape_ptr[i]) == STag_Format && unpack_val(tape_ptr[i]) == 0xA) {
|
||||
x = start_x;
|
||||
y += spacing_y;
|
||||
}
|
||||
else {
|
||||
x += spacing_x;
|
||||
}
|
||||
}
|
||||
int btn_w = 20 + text_width_cb(NULL, out_buf, 10);
|
||||
|
||||
// auto-wrap
|
||||
mu_Container* current_window = mu_get_current_container(&mu_ctx);
|
||||
if (x + btn_w > current_window->body.w - 15) {
|
||||
x = start_x;
|
||||
y += spacing_y;
|
||||
}
|
||||
|
||||
void* hHudBrush = ms_create_solid_brush(0x00141E23);
|
||||
ms_select_object(hdc, hHudBrush);
|
||||
ms_rectangle(hdc, -1, 500, 3000, 3000);
|
||||
ms_rectangle(hdc, -1, -1, 3000, 40);
|
||||
mu_ctx.style->colors[MU_COLOR_BUTTON] = mu_color(color_u32 & 0xFF, (color_u32 >> 8) & 0xFF, (color_u32 >> 16) & 0xFF, 255);
|
||||
|
||||
if (i == cursor_idx && editor_mode == MODE_EDIT) {
|
||||
mu_ctx.style->colors[MU_COLOR_TEXT] = mu_color(0,0,0,255);
|
||||
mu_ctx.style->colors[MU_COLOR_BUTTON] = mu_color(0x8E, 0x56, 0x3B, 255);
|
||||
} else if (i == cursor_idx && editor_mode == MODE_NAV) {
|
||||
mu_ctx.style->colors[MU_COLOR_BUTTON] = mu_color(0x26, 0x2F, 0x3B, 255);
|
||||
}
|
||||
|
||||
mu_layout_set_next(&mu_ctx, mu_rect(x, y, btn_w, 22), 1);
|
||||
|
||||
if (mu_button(&mu_ctx, out_buf)) {
|
||||
cursor_idx = i;
|
||||
editor_mode = MODE_NAV;
|
||||
}
|
||||
|
||||
ms_set_text_color(hdc, 0x00AAAAAA);
|
||||
ms_text_out_a(hdc, 40, 10, "x86-64 Machine Code Emitter | 2-Reg Stack | [F5] Toggle Run Mode | [PgUp/PgDn] Scroll", 85);
|
||||
|
||||
ms_set_text_color(hdc, 0x00FFFFFF);
|
||||
char jit_str[64] = "Mode: Incremental | JIT Size: 0x000 bytes";
|
||||
x += btn_w + spacing_x;
|
||||
|
||||
mu_ctx.style->colors[MU_COLOR_BUTTON] = mu_color(75, 75, 75, 255);
|
||||
mu_ctx.style->colors[MU_COLOR_TEXT] = mu_color(230, 230, 230, 255);
|
||||
}
|
||||
|
||||
// Dummy element to ensure scrolling bounds are correct
|
||||
mu_layout_set_next(&mu_ctx, mu_rect(start_x, y + spacing_y, 10, 10), 1);
|
||||
mu_draw_rect(&mu_ctx, mu_layout_next(&mu_ctx), mu_color(0,0,0,0));
|
||||
|
||||
mu_end_window(&mu_ctx);
|
||||
}
|
||||
|
||||
if (mu_begin_window(&mu_ctx, "HUD / Memory", mu_rect(10, 500, 900, 200))) {
|
||||
char jit_str[64] = "Mode: Incremental | JIT Size: 0x000 bytes";
|
||||
if (run_full) mem_copy(u8_(jit_str + 6), u8_("Full "), 11);
|
||||
u64_to_hex(code_arena.used, jit_str + 32, 3);
|
||||
ms_text_out_a(hdc, 40, 520, jit_str, 41);
|
||||
|
||||
char state_str[64] = "RAX: 00000000 | RDX: 00000000";
|
||||
mu_layout_row(&mu_ctx, 1, (int[]){-1}, 0);
|
||||
mu_text(&mu_ctx, "x86-64 Machine Code Emitter | 2-Reg Stack | [F5] Toggle Run Mode | [PgUp/PgDn] Scroll");
|
||||
mu_text(&mu_ctx, jit_str);
|
||||
|
||||
char state_str[64] = "RAX: 00000000 | RDX: 00000000";
|
||||
u64_to_hex(vm_rax, state_str + 5, 8);
|
||||
u64_to_hex(vm_rdx, state_str + 21, 8);
|
||||
ms_set_text_color(hdc, 0x0094BAA1);
|
||||
ms_text_out_a(hdc, 40, 550, state_str, 29);
|
||||
|
||||
if (tape_count > 0 && cursor_idx < tape_count) {
|
||||
mu_text(&mu_ctx, state_str);
|
||||
|
||||
if (tape_count > 0 && cursor_idx < tape_count) {
|
||||
U4 cur_tag = unpack_tag(tape_ptr[cursor_idx]);
|
||||
const char* tag_name = tag_names [cur_tag];
|
||||
U4 cur_color = tag_colors[cur_tag];
|
||||
char semantics_str[64] = "Current Tag: ";
|
||||
U4 name_len = 0;
|
||||
while (tag_name[name_len]) {
|
||||
@@ -766,47 +863,48 @@ S8 win_proc(void* hwnd, U4 msg, U8 wparam, S8 lparam)
|
||||
name_len ++;
|
||||
}
|
||||
semantics_str[13 + name_len] = '\0';
|
||||
ms_set_text_color(hdc, cur_color);
|
||||
ms_text_out_a(hdc, 40, 580, semantics_str, 13 + name_len);
|
||||
}
|
||||
|
||||
ms_set_text_color(hdc, 0x00C8C8C8);
|
||||
ms_text_out_a(hdc, 400, 520, "Global Memory (Contiguous Array):", 33);
|
||||
for (int i=0; i < 4; i ++) {
|
||||
char glob_str[32] = "[0]: 00000000";
|
||||
glob_str[1] = '0' + i;
|
||||
u64_to_hex(vm_globals[i], glob_str + 5, 8);
|
||||
ms_set_text_color(hdc, 0x00D6A454);
|
||||
ms_text_out_a(hdc, 400, 550 + (i * 25), glob_str, 13);
|
||||
}
|
||||
|
||||
ms_set_text_color(hdc, 0x00C8C8C8);
|
||||
ms_text_out_a(hdc, 750, 520, "Print Log:", 10);
|
||||
for (int i = 0; i<log_count && i < 4; i ++) {
|
||||
char log_str[32] = "00000000";
|
||||
u64_to_hex(log_buffer[i], log_str, 8);
|
||||
ms_set_text_color(hdc, 0x0094BAA1);
|
||||
ms_text_out_a(hdc, 750, 550 + (i * 25), log_str, 8);
|
||||
}
|
||||
|
||||
ms_set_text_color(hdc, 0x00C8C8C8);
|
||||
ms_text_out_a(hdc, 40, 650, "Debug Log:", 10);
|
||||
for (U4 i = 0; i < gdi_log_count; i++) {
|
||||
U4 len = 0;
|
||||
while(gdi_log_buffer[i][len] != '\0' && len < GDI_LOG_MAX_LINE_LEN) {
|
||||
len++;
|
||||
}
|
||||
ms_set_text_color(hdc, 0x00AAAAAA);
|
||||
ms_text_out_a(hdc, 40, 670 + (i * 20), gdi_log_buffer[i], len);
|
||||
mu_text(&mu_ctx, semantics_str);
|
||||
}
|
||||
mu_end_window(&mu_ctx);
|
||||
}
|
||||
|
||||
mu_end(&mu_ctx);
|
||||
|
||||
ms_select_object(hdc, hOldFont);
|
||||
ms_delete_object(hBgBrush);
|
||||
ms_delete_object(hBrushEdit);
|
||||
ms_delete_object(hBrushNav);
|
||||
ms_delete_object(hHudBrush);
|
||||
ms_end_paint(hwnd, & ps);
|
||||
return 0;
|
||||
MS_PAINTSTRUCT ps;
|
||||
void* hdc = ms_begin_paint(hwnd, & ps);
|
||||
|
||||
MS_RECT rect;
|
||||
ms_get_client_rect(hwnd, &rect);
|
||||
S4 width = rect.right - rect.left;
|
||||
S4 height = rect.bottom - rect.top;
|
||||
|
||||
void* memDC = ms_create_compatible_dc(hdc);
|
||||
void* memBitmap = ms_create_compatible_bitmap(hdc, width, height);
|
||||
void* oldBitmap = ms_select_object(memDC, memBitmap);
|
||||
|
||||
void* hFont = ms_create_font_a(20, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, "Consolas");
|
||||
void* hOldFont = ms_select_object(memDC, hFont);
|
||||
|
||||
ms_set_bk_mode(memDC, 1);
|
||||
|
||||
void* hBgBrush = ms_create_solid_brush(0x00222222);
|
||||
ms_select_object(memDC, hBgBrush);
|
||||
ms_rectangle(memDC, -1, -1, width + 2, height + 2);
|
||||
|
||||
render_microui(memDC);
|
||||
|
||||
ms_bit_blt(hdc, 0, 0, width, height, memDC, 0, 0, MS_SRCCOPY);
|
||||
|
||||
ms_select_object(memDC, hOldFont);
|
||||
ms_delete_object(hBgBrush);
|
||||
ms_delete_object(hFont);
|
||||
|
||||
ms_select_object(memDC, oldBitmap);
|
||||
ms_delete_object(memBitmap);
|
||||
ms_delete_dc(memDC);
|
||||
|
||||
ms_end_paint(hwnd, & ps);
|
||||
return 0;
|
||||
}
|
||||
case MS_WM_DESTROY: { ms_post_quit_message(0); return 0; }
|
||||
}
|
||||
@@ -822,6 +920,10 @@ int main(void) {
|
||||
farena_init(& tape_arena, tape_mem);
|
||||
farena_init(& anno_arena, anno_mem);
|
||||
farena_init(& code_arena, code_mem);
|
||||
|
||||
mu_init(&mu_ctx);
|
||||
mu_ctx.text_width = text_width_cb;
|
||||
mu_ctx.text_height = text_height_cb;
|
||||
|
||||
scatter(pack_token(STag_Comment, 0), "INIT ");
|
||||
scatter(pack_token(STag_Data, 5), 0);
|
||||
|
||||
Reference in New Issue
Block a user