gud ui
This commit is contained in:
@@ -60,8 +60,9 @@ Here is a breakdown of the next steps to advance the `attempt_1` implementation
|
||||
* The tape and annotations are currently lost when the program closes.
|
||||
* Move away from purely transient `VirtualAlloc` buffers to a memory-mapped file approach (or a manual Save/Load equivalent in WinAPI) to allow the "executable as source" to persist between sessions.
|
||||
|
||||
4. **Refine Visual Editor Interactions:**
|
||||
4. ~~**Refine Visual Editor Interactions:**~~ (Completed via `microui` integration)
|
||||
* Implement a proper internal text-editing cursor within the `STag_Data` and `STag_Format` (annotation) tokens, rather than relying on backspace-truncation and appendage.
|
||||
* Migrated to `microui` for immediate mode GUI floating panels, auto-layout token sizing (for a natural text look), and window resizing.
|
||||
|
||||
5. **Continuous Validation & Complex Control Flow:**
|
||||
* Expand the primitive set to allow for more complex, AST-less control flow (e.g., handling Lambdas or specific Basic Block jumps).
|
||||
|
||||
@@ -676,6 +676,11 @@ WinAPI void* ms_create_font_a(
|
||||
U4 iPitchAndFamily,
|
||||
char const* pszFaceName
|
||||
) asm("CreateFontA");
|
||||
WinAPI void* ms_create_compatible_dc(void* hdc) asm("CreateCompatibleDC");
|
||||
WinAPI void* ms_create_compatible_bitmap(void* hdc, S4 cx, S4 cy) asm("CreateCompatibleBitmap");
|
||||
WinAPI B4 ms_bit_blt(void* hdcDest, S4 x, S4 y, S4 w, S4 h, void* hdcSrc, S4 xSrc, S4 ySrc, U4 rop) asm("BitBlt");
|
||||
WinAPI B4 ms_delete_dc(void* hdc) asm("DeleteDC");
|
||||
WinAPI B4 ms_get_client_rect(void* hwnd, MS_RECT* lpRect) asm("GetClientRect");
|
||||
WinAPI void* ms_select_object(void* hdc, void* h) asm("SelectObject");
|
||||
WinAPI S4 ms_rectangle(void* hdc, S4 left, S4 top, S4 right, S4 bottom) asm("Rectangle");
|
||||
WinAPI S4 ms_set_bk_mode(void* hdc, S4 mode) asm("SetBkMode");
|
||||
@@ -685,9 +690,21 @@ WinAPI S4 ms_delete_object(void* ho) asm("
|
||||
#define MS_MEM_COMMIT 0x00001000
|
||||
#define MS_MEM_RESERVE 0x00002000
|
||||
#define MS_PAGE_READWRITE 0x04
|
||||
#define MS_SRCCOPY 0x00CC0020
|
||||
#define MS_WM_DESTROY 0x0002
|
||||
#define MS_WM_SIZE 0x0005
|
||||
#define MS_WM_PAINT 0x000F
|
||||
#define MS_WM_ERASEBKGND 0x0014
|
||||
#define MS_WM_KEYDOWN 0x0100
|
||||
#define MS_WM_KEYUP 0x0101
|
||||
#define MS_WM_MOUSEMOVE 0x0200
|
||||
#define MS_WM_LBUTTONDOWN 0x0201
|
||||
#define MS_WM_LBUTTONUP 0x0202
|
||||
#define MS_WM_RBUTTONDOWN 0x0204
|
||||
#define MS_WM_RBUTTONUP 0x0205
|
||||
#define MS_WM_MBUTTONDOWN 0x0207
|
||||
#define MS_WM_MBUTTONUP 0x0208
|
||||
#define MS_WM_MOUSEWHEEL 0x020A
|
||||
#define MS_WS_OVERLAPPEDWINDOW 0x00CF0000
|
||||
#define MS_WS_VISIBLE 0x10000000
|
||||
#define MS_VK_LEFT 0x25
|
||||
|
||||
360
attempt_1/main.c
360
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];
|
||||
|
||||
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];
|
||||
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_set_text_color(hdc, color);
|
||||
if (editor_mode == MODE_EDIT && i == cursor_idx) {
|
||||
ms_set_text_color(hdc, 0x001E1E1E);
|
||||
}
|
||||
int btn_w = 20 + text_width_cb(NULL, out_buf, 10);
|
||||
|
||||
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';
|
||||
// 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
mu_ctx.style->colors[MU_COLOR_BUTTON] = mu_color(color_u32 & 0xFF, (color_u32 >> 8) & 0xFF, (color_u32 >> 16) & 0xFF, 255);
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
mu_layout_set_next(&mu_ctx, mu_rect(x, y, btn_w, 22), 1);
|
||||
|
||||
ms_set_text_color(hdc, 0x00FFFFFF);
|
||||
char jit_str[64] = "Mode: Incremental | JIT Size: 0x000 bytes";
|
||||
if (mu_button(&mu_ctx, out_buf)) {
|
||||
cursor_idx = i;
|
||||
editor_mode = MODE_NAV;
|
||||
}
|
||||
|
||||
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);
|
||||
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";
|
||||
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);
|
||||
mu_text(&mu_ctx, state_str);
|
||||
|
||||
if (tape_count > 0 && cursor_idx < tape_count) {
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
mu_end(&mu_ctx);
|
||||
|
||||
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; }
|
||||
}
|
||||
@@ -823,6 +921,10 @@ int main(void) {
|
||||
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);
|
||||
scatter(pack_token(STag_Data, 0), 0);
|
||||
|
||||
888
attempt_1/main.c.bak
Normal file
888
attempt_1/main.c.bak
Normal file
@@ -0,0 +1,888 @@
|
||||
#include "duffle.amd64.win32.h"
|
||||
|
||||
// --- Semantic Tags (Using X-Macros & Enum_) ---
|
||||
#define Tag_Entries() \
|
||||
X(Define, "Define", 0x0018AEFF, ":") \
|
||||
X(Call, "Call", 0x00D6A454, "~") \
|
||||
X(Data, "Data", 0x0094BAA1, "$") \
|
||||
X(Imm, "Imm", 0x004AA4C2, "^") \
|
||||
X(Comment, "Comment", 0x00AAAAAA, ".") \
|
||||
X(Format, "Format", 0x003A2F3B, " ")
|
||||
|
||||
typedef Enum_(U4, STag) {
|
||||
#define X(n, s, c, p) tmpl(STag, n),
|
||||
Tag_Entries()
|
||||
#undef X
|
||||
STag_Count,
|
||||
};
|
||||
global U4 tag_colors[] = {
|
||||
#define X(n, s, c, p) c,
|
||||
Tag_Entries()
|
||||
#undef X
|
||||
};
|
||||
global const char* tag_prefixes[] = {
|
||||
#define X(n, s, c, p) p,
|
||||
Tag_Entries()
|
||||
#undef X
|
||||
};
|
||||
global const char* tag_names[] = {
|
||||
#define X(n, s, c, p) s,
|
||||
Tag_Entries()
|
||||
#undef X
|
||||
};
|
||||
|
||||
#define pack_token(tag, val) ((u4_(tag) << 28) | (u4_(val) & 0x0FFFFFFF))
|
||||
#define unpack_tag(token) ( ((token) >> 28) & 0x0F)
|
||||
#define unpack_val(token) ( (token) & 0x0FFFFFFF)
|
||||
|
||||
#define TOKENS_PER_ROW 8
|
||||
|
||||
#define MODE_NAV 0
|
||||
#define MODE_EDIT 1
|
||||
|
||||
global FArena tape_arena;
|
||||
global FArena anno_arena;
|
||||
global U8 cursor_idx = 0;
|
||||
global U4 editor_mode = MODE_NAV;
|
||||
global B4 mode_switch_now = false;
|
||||
|
||||
global FArena code_arena;
|
||||
|
||||
global U8 vm_rax = 0;
|
||||
global U8 vm_rdx = 0;
|
||||
global U8 vm_globals[16] = {0};
|
||||
|
||||
global B4 run_full = false;
|
||||
global U8 log_buffer[16] = {0};
|
||||
global U4 log_count = 0;
|
||||
global S4 scroll_y_offset = 0;
|
||||
|
||||
// New GDI log
|
||||
#define GDI_LOG_MAX_LINES 10
|
||||
#define GDI_LOG_MAX_LINE_LEN 128
|
||||
global char gdi_log_buffer[GDI_LOG_MAX_LINES][GDI_LOG_MAX_LINE_LEN] = {0};
|
||||
global U4 gdi_log_count = 0;
|
||||
|
||||
internal void debug_log(Str8 fmt, KTL_Str8 table) {
|
||||
// A static buffer for our log lines.
|
||||
LP_ UTF8 console_log_buffer[1024];
|
||||
mem_zero(u8_(console_log_buffer), 1024);
|
||||
|
||||
// Format the string.
|
||||
Str8 result = str8_fmt_ktl_buf(slice_ut_arr(console_log_buffer), table, fmt);
|
||||
|
||||
// Also write to our GDI log buffer
|
||||
if (gdi_log_count < GDI_LOG_MAX_LINES) {
|
||||
U4 len_to_copy = result.len < GDI_LOG_MAX_LINE_LEN - 1 ? result.len : GDI_LOG_MAX_LINE_LEN - 1;
|
||||
mem_copy(u8_(gdi_log_buffer[gdi_log_count]), u8_(result.ptr), len_to_copy);
|
||||
gdi_log_buffer[gdi_log_count][len_to_copy] = '\0';
|
||||
gdi_log_count++;
|
||||
}
|
||||
|
||||
// Get stdout handle.
|
||||
MS_Handle stdout_handle = ms_get_std_handle(MS_STD_OUTPUT);
|
||||
|
||||
// Write the formatted string.
|
||||
ms_write_console(stdout_handle, result.ptr, (U4)result.len, nullptr, 0);
|
||||
|
||||
// Write a newline.
|
||||
ms_write_console(stdout_handle, (UTF8 const*r)"\n", 1, nullptr, 0);
|
||||
}
|
||||
|
||||
U8 ms_builtin_print(U8 val, U8 rdx_val, U8 r8_val, U8 r9_val) {
|
||||
char hex1[9], hex2[9], hex3[9], hex4[9];
|
||||
u64_to_hex(val, hex1, 8); hex1[8] = '\0';
|
||||
u64_to_hex(rdx_val, hex2, 8); hex2[8] = '\0';
|
||||
u64_to_hex(r8_val, hex3, 8); hex3[8] = '\0';
|
||||
u64_to_hex(r9_val, hex4, 8); hex4[8] = '\0';
|
||||
|
||||
KTL_Slot_Str8 log_table[] = {
|
||||
{ ktl_str8_key("v1"), str8(hex1) },
|
||||
{ ktl_str8_key("v2"), str8(hex2) },
|
||||
{ ktl_str8_key("v3"), str8(hex3) },
|
||||
{ ktl_str8_key("v4"), str8(hex4) },
|
||||
};
|
||||
debug_log(str8("FFI PRINT -> RCX:<v1> RDX:<v2> R8:<v3> R9:<v4>"), ktl_str8_from_arr(log_table));
|
||||
if (log_count < 16) log_buffer[log_count++] = val;
|
||||
return val;
|
||||
}
|
||||
|
||||
// Visual Linker & O(1) Dictionary
|
||||
global U4 tape_to_code_offset[65536] = {0};
|
||||
|
||||
// --- WinAPI Persistence ---
|
||||
#define MS_GENERIC_READ 0x80000000
|
||||
#define MS_GENERIC_WRITE 0x40000000
|
||||
#define MS_CREATE_ALWAYS 2
|
||||
#define MS_OPEN_EXISTING 3
|
||||
#define MS_FILE_ATTRIBUTE_NORMAL 0x80
|
||||
#define MS_VK_F1 0x70
|
||||
#define MS_VK_F2 0x71
|
||||
|
||||
WinAPI void* ms_create_file_a(char const* lpFileName, U4 dwDesiredAccess, U4 dwShareMode, void* lpSecurityAttributes, U4 dwCreationDisposition, U4 dwFlagsAndAttributes, void* hTemplateFile) asm("CreateFileA");
|
||||
WinAPI B4 ms_write_file(void* hFile, void const* lpBuffer, U4 nNumberOfBytesToWrite, U4* lpNumberOfBytesWritten, void* lpOverlapped) asm("WriteFile");
|
||||
WinAPI B4 ms_read_file(void* hFile, void* lpBuffer, U4 nNumberOfBytesToRead, U4* lpNumberOfBytesRead, void* lpOverlapped) asm("ReadFile");
|
||||
WinAPI B4 ms_close_handle(void* hObject) asm("CloseHandle");
|
||||
|
||||
#define PRIM_SWAP 1
|
||||
#define PRIM_MULT 2
|
||||
#define PRIM_ADD 3
|
||||
#define PRIM_FETCH 4
|
||||
#define PRIM_DEC 5
|
||||
#define PRIM_STORE 6
|
||||
#define PRIM_RET_Z 7
|
||||
#define PRIM_RET 8
|
||||
#define PRIM_PRINT 9
|
||||
#define PRIM_RET_S 10
|
||||
#define PRIM_DUP 11
|
||||
#define PRIM_DROP 12
|
||||
#define PRIM_SUB 13
|
||||
|
||||
global const char* prim_names[] = {
|
||||
"",
|
||||
"SWAP ",
|
||||
"MULT ",
|
||||
"ADD ",
|
||||
"FETCH ",
|
||||
"DEC ",
|
||||
"STORE ",
|
||||
"RET_IF_Z",
|
||||
"RETURN ",
|
||||
"PRINT ",
|
||||
"RET_IF_S",
|
||||
"DUP ",
|
||||
"DROP ",
|
||||
"SUB "
|
||||
};
|
||||
|
||||
internal U4 resolve_name_to_index(const char* ref_name);
|
||||
internal void relink_tape(void);
|
||||
|
||||
IA_ void compile_and_run_tape(void);
|
||||
|
||||
internal void save_cartridge(void) {
|
||||
void* hFile = ms_create_file_a("cartridge.bin", MS_GENERIC_WRITE, 0, nullptr, MS_CREATE_ALWAYS, MS_FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (hFile != (void*)-1) {
|
||||
U4 written = 0;
|
||||
ms_write_file(hFile, & tape_arena.used, 8, & written, nullptr);
|
||||
ms_write_file(hFile, & anno_arena.used, 8, & written, nullptr);
|
||||
ms_write_file(hFile, & cursor_idx, 8, & written, nullptr);
|
||||
ms_write_file(hFile, (void*)tape_arena.start, (U4)tape_arena.used, & written, nullptr);
|
||||
ms_write_file(hFile, (void*)anno_arena.start, (U4)anno_arena.used, & written, nullptr);
|
||||
ms_close_handle(hFile);
|
||||
}
|
||||
}
|
||||
|
||||
internal void load_cartridge(void) {
|
||||
void* hFile = ms_create_file_a("cartridge.bin", MS_GENERIC_READ, 0, nullptr, MS_OPEN_EXISTING, MS_FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (hFile != (void*)-1) {
|
||||
U4 read = 0;
|
||||
ms_read_file(hFile, & tape_arena.used, 8, & read, nullptr);
|
||||
ms_read_file(hFile, & anno_arena.used, 8, & read, nullptr);
|
||||
ms_read_file(hFile, & cursor_idx, 8, & read, nullptr);
|
||||
ms_read_file(hFile, (void*)tape_arena.start, (U4)tape_arena.used, & read, nullptr);
|
||||
ms_read_file(hFile, (void*)anno_arena.start, (U4)anno_arena.used, & read, nullptr);
|
||||
ms_close_handle(hFile);
|
||||
relink_tape();
|
||||
compile_and_run_tape();
|
||||
}
|
||||
}
|
||||
|
||||
IA_ void scatter(U4 token, const char* anno_str) {
|
||||
if (tape_arena.used + sizeof(U4) <= tape_arena.capacity && anno_arena.used + sizeof(U8) <= anno_arena.capacity) {
|
||||
U4 tag = unpack_tag(token);
|
||||
U4 val = unpack_val(token);
|
||||
|
||||
if (anno_str && (tag == STag_Call || tag == STag_Imm)) {
|
||||
val = resolve_name_to_index(anno_str);
|
||||
}
|
||||
|
||||
U4*r ptr = u4_r(tape_arena.start + tape_arena.used);
|
||||
ptr[0] = pack_token(tag, val);
|
||||
tape_arena.used += sizeof(U4);
|
||||
U8*r aptr = u8_r(anno_arena.start + anno_arena.used);
|
||||
aptr[0] = 0;
|
||||
if (anno_str) {
|
||||
char* dest = (char*)aptr;
|
||||
int i = 0; while(i < 8 && anno_str[i]) { dest[i] = anno_str[i]; i ++; }
|
||||
}
|
||||
anno_arena.used += sizeof(U8);
|
||||
}
|
||||
}
|
||||
|
||||
internal void emit8(U1 b) {
|
||||
if (code_arena.used + 1 <= code_arena.capacity) {
|
||||
u1_r(code_arena.start + code_arena.used)[0] = b;
|
||||
code_arena.used += 1;
|
||||
}
|
||||
}
|
||||
internal void emit32(U4 val) {
|
||||
if (code_arena.used + 4 <= code_arena.capacity) {
|
||||
u4_r(code_arena.start + code_arena.used)[0] = val;
|
||||
code_arena.used += 4;
|
||||
}
|
||||
}
|
||||
|
||||
internal void pad32(void) {
|
||||
while ((code_arena.used % 4) != 0) emit8(0x90);
|
||||
}
|
||||
|
||||
internal U4 resolve_name_to_index(const char* ref_name) {
|
||||
U8 tape_count = tape_arena.used / sizeof(U4);
|
||||
U4*r tape_ptr = u4_r(tape_arena.start);
|
||||
U8*r anno_ptr = u8_r(anno_arena.start);
|
||||
|
||||
U8 prim_count = array_len(prim_names);
|
||||
for (int p = 1; p < prim_count; p++) {
|
||||
int match = 1;
|
||||
for (int c = 0; c < 8; c++) {
|
||||
char c1 = ref_name[c] ? ref_name[c] : ' ';
|
||||
char c2 = prim_names[p][c] ? prim_names[p][c] : ' ';
|
||||
if (c1 != c2) { match = 0; break; }
|
||||
}
|
||||
if (match) return p + 0x10000;
|
||||
}
|
||||
|
||||
for (U8 j = 0; j < tape_count; j++) {
|
||||
if (unpack_tag(tape_ptr[j]) == STag_Define) {
|
||||
char* def_name = (char*)&anno_ptr[j];
|
||||
int match = 1;
|
||||
for (int c = 0; c < 8; c++) {
|
||||
char c1 = ref_name[c] ? ref_name[c] : ' ';
|
||||
char c2 = def_name[c] ? def_name[c] : ' ';
|
||||
if (c1 != c2) { match = 0; break; }
|
||||
}
|
||||
if (match) return j;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal void relink_tape(void) {
|
||||
U8 tape_count = tape_arena.used / sizeof(U4);
|
||||
U4*r tape_ptr = u4_r(tape_arena.start);
|
||||
U8*r anno_ptr = u8_r(anno_arena.start);
|
||||
|
||||
for (U8 i = 0; i < tape_count; i++) {
|
||||
U4 t = tape_ptr[i];
|
||||
U4 tag = unpack_tag(t);
|
||||
if (tag == STag_Call || tag == STag_Imm) {
|
||||
char* ref_name = (char*)&anno_ptr[i];
|
||||
U4 new_val = resolve_name_to_index(ref_name);
|
||||
tape_ptr[i] = pack_token(tag, new_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void compile_action(U4 val)
|
||||
{
|
||||
if (val >= 0x10000) {
|
||||
U4 p = val - 0x10000;
|
||||
if (p == PRIM_SWAP) {
|
||||
emit8(0x48); emit8(0x87); emit8(0xC2);
|
||||
pad32();
|
||||
return;
|
||||
} else if (p == PRIM_MULT) {
|
||||
emit8(0x48); emit8(0x0F); emit8(0xAF); emit8(0xC2);
|
||||
pad32();
|
||||
return;
|
||||
} else if (p == PRIM_ADD) {
|
||||
emit8(0x48); emit8(0x01); emit8(0xD0);
|
||||
pad32();
|
||||
return;
|
||||
} else if (p == PRIM_SUB) {
|
||||
emit8(0x48); emit8(0x29); emit8(0xD0);
|
||||
pad32();
|
||||
return;
|
||||
} else if (p == PRIM_FETCH) {
|
||||
emit8(0x48); emit8(0x8B); emit8(0x04); emit8(0xC3); // mov rax, [rbx + rax*8]
|
||||
pad32();
|
||||
return;
|
||||
} else if (p == PRIM_DEC) {
|
||||
emit8(0x48); emit8(0xFF); emit8(0xC8);
|
||||
pad32();
|
||||
return;
|
||||
} else if (p == PRIM_STORE) {
|
||||
emit8(0x48); emit8(0x89); emit8(0x14); emit8(0xC3); // mov [rbx + rax*8], rdx
|
||||
pad32();
|
||||
return;
|
||||
} else if (p == PRIM_RET_Z) {
|
||||
emit8(0x48); emit8(0x85); emit8(0xC0);
|
||||
emit8(0x75); emit8(0x01);
|
||||
emit8(0xC3);
|
||||
pad32();
|
||||
return;
|
||||
} else if (p == PRIM_RET_S) {
|
||||
emit8(0x48); emit8(0x85); emit8(0xC0);
|
||||
emit8(0x79); emit8(0x01);
|
||||
emit8(0xC3);
|
||||
pad32();
|
||||
return;
|
||||
} else if (p == PRIM_RET) {
|
||||
emit8(0xC3);
|
||||
pad32();
|
||||
return;
|
||||
} else if (p == PRIM_DUP) {
|
||||
emit8(0x48); emit8(0x89); emit8(0xC2);
|
||||
pad32();
|
||||
return;
|
||||
} else if (p == PRIM_DROP) {
|
||||
emit8(0x48); emit8(0x89); emit8(0xD0);
|
||||
pad32();
|
||||
return;
|
||||
} else if (p == PRIM_PRINT) {
|
||||
// FFI Dance: Save RDX, Align RSP (32 shadow + 8 align = 40)
|
||||
emit8(0x52); // push rdx
|
||||
emit8(0x48); emit8(0x83); emit8(0xEC); emit8(0x28); // sub rsp, 40
|
||||
|
||||
// Map arguments: RCX=RAX, RDX=RDX(already loaded), R8=Globals[0], R9=Globals[1]
|
||||
emit8(0x48); emit8(0x89); emit8(0xC1); // mov rcx, rax
|
||||
emit8(0x4C); emit8(0x8B); emit8(0x03); // mov r8, [rbx]
|
||||
emit8(0x4C); emit8(0x8B); emit8(0x4B); emit8(0x08); // mov r9, [rbx+8]
|
||||
|
||||
// Load func ptr and call
|
||||
emit8(0x49); emit8(0xBA); // mov r10, ...
|
||||
U8 addr = u8_(& ms_builtin_print);
|
||||
emit32(u4_(addr & 0xFFFFFFFF));
|
||||
emit32(u4_(addr >> 32));
|
||||
emit8(0x41); emit8(0xFF); emit8(0xD2); // call r10
|
||||
|
||||
// Restore
|
||||
emit8(0x48); emit8(0x83); emit8(0xC4); emit8(0x28); // add rsp, 40
|
||||
emit8(0x5A); // pop rdx
|
||||
pad32();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (val > 0 && val < 0x10000) {
|
||||
U4 target = tape_to_code_offset[val];
|
||||
pad32();
|
||||
S4 rel32 = s4_(target) - s4_(code_arena.used + 5);
|
||||
emit8(0xE8);
|
||||
emit32(u4_(rel32));
|
||||
pad32();
|
||||
}
|
||||
}
|
||||
|
||||
IA_ void compile_and_run_tape(void)
|
||||
{
|
||||
farena_reset(& code_arena);
|
||||
log_count = 0;
|
||||
gdi_log_count = 0;
|
||||
|
||||
emit8(0x53); // push rbx (callee-saved; also aligns RSP to 0 mod 16)
|
||||
emit8(0x48); emit8(0x89); emit8(0xCB); // mov rbx, rcx (stable globals ptr for whole JIT session)
|
||||
emit8(0x48); emit8(0x8B); emit8(0x43); emit8(0x70); // mov rax, [rbx+0x70]
|
||||
emit8(0x48); emit8(0x8B); emit8(0x53); emit8(0x78); // mov rdx, [rbx+0x78]
|
||||
|
||||
U4*r tape_ptr = u4_r(tape_arena.start);
|
||||
U8*r anno_ptr = u8_r(anno_arena.start);
|
||||
B4 in_def = false;
|
||||
U4 def_jmp_offset = 0;
|
||||
U8 end_idx = run_full ? (tape_arena.used / sizeof(U4)) : (cursor_idx + 1);
|
||||
for (U8 i = 0; i < end_idx; i++)
|
||||
{
|
||||
U4 tag = unpack_tag(tape_ptr[i]);
|
||||
U4 val = unpack_val(tape_ptr[i]);
|
||||
|
||||
if (tag == STag_Define)
|
||||
{
|
||||
if (in_def == false) {
|
||||
pad32();
|
||||
emit8(0xE9);
|
||||
def_jmp_offset = code_arena.used;
|
||||
emit32(0);
|
||||
pad32();
|
||||
in_def = true;
|
||||
} else {
|
||||
emit8(0xC3);
|
||||
pad32();
|
||||
}
|
||||
|
||||
tape_to_code_offset[i] = code_arena.used;
|
||||
|
||||
emit8(0x48); emit8(0x87); emit8(0xC2);
|
||||
pad32();
|
||||
}
|
||||
else if (tag == STag_Call || tag == STag_Imm)
|
||||
{
|
||||
char* name = (char*)&anno_ptr[i];
|
||||
char val_hex[9];
|
||||
u64_to_hex(val, val_hex, 8);
|
||||
val_hex[8] = '\0';
|
||||
KTL_Slot_Str8 call_log_table[] = {
|
||||
{ ktl_str8_key("name"), str8(name) },
|
||||
{ ktl_str8_key("val"), str8(val_hex) },
|
||||
};
|
||||
debug_log(str8("Compiling call: <name> (val: <val>)"), ktl_str8_from_arr(call_log_table));
|
||||
|
||||
if (tag == STag_Imm && in_def) {
|
||||
emit8(0xC3);
|
||||
pad32();
|
||||
U4 current = code_arena.used;
|
||||
u4_r(code_arena.start + def_jmp_offset)[0] = current - (def_jmp_offset + 4);
|
||||
in_def = false;
|
||||
}
|
||||
compile_action(val);
|
||||
}
|
||||
else if (tag == STag_Data) {
|
||||
emit8(0x48); emit8(0x89); emit8(0xC2);
|
||||
emit8(0x48); emit8(0xC7); emit8(0xC0); emit32(val);
|
||||
pad32();
|
||||
}
|
||||
}
|
||||
|
||||
if (in_def) {
|
||||
emit8(0xC3);
|
||||
pad32();
|
||||
U4 current = code_arena.used;
|
||||
u4_r(code_arena.start + def_jmp_offset)[0] = current - (def_jmp_offset + 4);
|
||||
}
|
||||
|
||||
emit8(0x48); emit8(0x89); emit8(0x43); emit8(0x70); // mov [rbx+0x70], rax
|
||||
emit8(0x48); emit8(0x89); emit8(0x53); emit8(0x78); // mov [rbx+0x78], rdx
|
||||
emit8(0x5B); // pop rbx
|
||||
emit8(0xC3); // ret
|
||||
|
||||
typedef void JIT_Func(U8* globals_ptr);
|
||||
JIT_Func* func = (JIT_Func*)code_arena.start;
|
||||
func(vm_globals);
|
||||
|
||||
vm_rax = vm_globals[14];
|
||||
vm_rdx = vm_globals[15];
|
||||
|
||||
char rax_hex[9];
|
||||
u64_to_hex(vm_rax, rax_hex, 8);
|
||||
rax_hex[8] = '\0';
|
||||
char rdx_hex[9];
|
||||
u64_to_hex(vm_rdx, rdx_hex, 8);
|
||||
rdx_hex[8] = '\0';
|
||||
KTL_Slot_Str8 post_jit_log_table[] = {
|
||||
{ ktl_str8_key("rax"), str8(rax_hex) },
|
||||
{ ktl_str8_key("rdx"), str8(rdx_hex) },
|
||||
};
|
||||
debug_log(str8("JIT finished. RAX: <rax>, RDX: <rdx>"), ktl_str8_from_arr(post_jit_log_table));
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
U4 t = tape_ptr[cursor_idx];
|
||||
U4 tag = unpack_tag(t);
|
||||
U4 val = unpack_val(t);
|
||||
U1 c = u1_(wparam);
|
||||
|
||||
B4 should_skip = c < 32 || (c == 'e' && mode_switch_now);
|
||||
if (should_skip) { mode_switch_now = false; return 0; }
|
||||
|
||||
if (tag == STag_Data) {
|
||||
U4 digit = 16;
|
||||
if (c >= '0' && c <= '9') digit = c - '0';
|
||||
if (c >= 'a' && c <= 'f') digit = c - 'a' + 10;
|
||||
if (c >= 'A' && c <= 'F') digit = c - 'A' + 10;
|
||||
if (digit < 16) {
|
||||
val = ((val << 4) | digit) & 0x0FFFFFFF;
|
||||
tape_ptr[cursor_idx] = pack_token(tag, val);
|
||||
}
|
||||
}
|
||||
else if (tag != STag_Format) {
|
||||
U8*r anno_ptr = u8_r(anno_arena.start);
|
||||
char* anno_str = (char*) & anno_ptr[cursor_idx];
|
||||
int len = 0;
|
||||
while (len < 8 && anno_str[len] != '\0' && anno_str[len] != ' ') len ++;
|
||||
if (len < 8) {
|
||||
anno_str[len] = (char)c;
|
||||
for (int i = len + 1; i < 8; i++) anno_str[i] = '\0';
|
||||
|
||||
if (tag == STag_Call || tag == STag_Imm || tag == STag_Define) {
|
||||
U4 new_val = resolve_name_to_index(anno_str);
|
||||
tape_ptr[cursor_idx] = pack_token(tag, new_val);
|
||||
if (tag == STag_Define) relink_tape();
|
||||
}
|
||||
}
|
||||
}
|
||||
vm_rax = 0; vm_rdx = 0; mem_zero(u8_(vm_globals), sizeof(vm_globals));
|
||||
compile_and_run_tape();
|
||||
ms_invalidate_rect(hwnd, nullptr, true);
|
||||
return 0;
|
||||
}
|
||||
case MS_WM_KEYDOWN: {
|
||||
|
||||
if (wparam == 0x45 && editor_mode == MODE_NAV) {
|
||||
editor_mode = MODE_EDIT;
|
||||
mode_switch_now = true;
|
||||
ms_invalidate_rect(hwnd, nullptr, true);
|
||||
return 0;
|
||||
}
|
||||
if (wparam == 0x1B && editor_mode == MODE_EDIT) {
|
||||
editor_mode = MODE_NAV;
|
||||
relink_tape();
|
||||
ms_invalidate_rect(hwnd, nullptr, true);
|
||||
return 0;
|
||||
}
|
||||
if (editor_mode == MODE_EDIT) {
|
||||
if (wparam == MS_VK_BACK) {
|
||||
U4 t = tape_ptr[cursor_idx];
|
||||
U4 tag = unpack_tag(t);
|
||||
U4 val = unpack_val(t);
|
||||
if (tag == STag_Data) {
|
||||
val = val >> 4;
|
||||
tape_ptr[cursor_idx] = pack_token(tag, val);
|
||||
}
|
||||
else if (tag != STag_Format) {
|
||||
U8*r anno_ptr = u8_r(anno_arena.start);
|
||||
char* anno_str = (char*) & anno_ptr[cursor_idx];
|
||||
int len = 0;
|
||||
while (len < 8 && anno_str[len] != '\0' && anno_str[len] != ' ') len ++;
|
||||
if (len > 0) {
|
||||
anno_str[len - 1] = '\0';
|
||||
if (tag == STag_Call || tag == STag_Imm || tag == STag_Define) {
|
||||
U4 new_val = resolve_name_to_index(anno_str);
|
||||
tape_ptr[cursor_idx] = pack_token(tag, new_val);
|
||||
if (tag == STag_Define) relink_tape();
|
||||
}
|
||||
}
|
||||
}
|
||||
vm_rax = 0; vm_rdx = 0; mem_zero(u8_(vm_globals), sizeof(vm_globals));
|
||||
compile_and_run_tape();
|
||||
ms_invalidate_rect(hwnd, nullptr, true);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (wparam == MS_VK_RIGHT && cursor_idx < tape_count - 1) cursor_idx ++;
|
||||
if (wparam == MS_VK_LEFT && cursor_idx > 0) cursor_idx --;
|
||||
|
||||
if (wparam == MS_VK_UP) {
|
||||
U8 line_start = cursor_idx;
|
||||
while (line_start > 0 && unpack_tag(tape_ptr[line_start - 1]) != STag_Format) line_start--;
|
||||
if (line_start > 0) {
|
||||
U8 col = cursor_idx - line_start;
|
||||
U8 prev_line_start = line_start - 1;
|
||||
while (prev_line_start > 0 && unpack_tag(tape_ptr[prev_line_start - 1]) != STag_Format) prev_line_start--;
|
||||
U8 prev_line_len = (line_start - 1) - prev_line_start;
|
||||
cursor_idx = prev_line_start + (col < prev_line_len ? col : prev_line_len);
|
||||
}
|
||||
}
|
||||
if (wparam == MS_VK_DOWN) {
|
||||
U8 line_start = cursor_idx;
|
||||
while (line_start > 0 && unpack_tag(tape_ptr[line_start - 1]) != STag_Format) line_start --;
|
||||
U8 col = cursor_idx - line_start;
|
||||
U8 next_line_start = cursor_idx;
|
||||
while (next_line_start < tape_count && unpack_tag(tape_ptr[next_line_start]) != STag_Format) next_line_start ++;
|
||||
if (next_line_start < tape_count) {
|
||||
next_line_start ++;
|
||||
U8 next_line_end = next_line_start;
|
||||
while (next_line_end < tape_count && unpack_tag(tape_ptr[next_line_end]) != STag_Format) next_line_end ++;
|
||||
U8 next_line_len = next_line_end - next_line_start;
|
||||
cursor_idx = next_line_start + (col < next_line_len ? col : next_line_len);
|
||||
}
|
||||
}
|
||||
|
||||
if (wparam == MS_VK_PRIOR) { scroll_y_offset -= 100; if (scroll_y_offset < 0) scroll_y_offset = 0; }
|
||||
if (wparam == MS_VK_NEXT) { scroll_y_offset += 100; }
|
||||
if (wparam == MS_VK_F5) { run_full = !run_full; }
|
||||
if (wparam == MS_VK_F1) { save_cartridge(); }
|
||||
if (wparam == MS_VK_F2) { load_cartridge(); ms_invalidate_rect(hwnd, nullptr, true); }
|
||||
|
||||
if (wparam == MS_VK_TAB) {
|
||||
U4 t = tape_ptr[cursor_idx];
|
||||
U4 tag = (unpack_tag(t) + 1) % STag_Count;
|
||||
tape_ptr[cursor_idx] = pack_token(tag, unpack_val(t));
|
||||
}
|
||||
else if (wparam == MS_VK_BACK)
|
||||
{
|
||||
U8 delete_idx = cursor_idx;
|
||||
B4 is_shift = (ms_get_async_key_state(MS_VK_SHIFT) & 0x8000) != 0;
|
||||
if (is_shift == false) {
|
||||
if (cursor_idx > 0) {
|
||||
delete_idx = cursor_idx - 1;
|
||||
cursor_idx--;
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
if (tape_count > 0) {
|
||||
U8*r anno_ptr = u8_r(anno_arena.start);
|
||||
for (U8 i = delete_idx; i < tape_count - 1; i ++) {
|
||||
tape_ptr[i] = tape_ptr[i + 1];
|
||||
anno_ptr[i] = anno_ptr[i + 1];
|
||||
}
|
||||
tape_arena.used -= sizeof(U4);
|
||||
anno_arena.used -= sizeof(U8);
|
||||
}
|
||||
relink_tape();
|
||||
}
|
||||
else if (wparam == MS_VK_SPACE || wparam == MS_VK_RETURN) {
|
||||
B4 is_shift = (ms_get_async_key_state(MS_VK_SHIFT) & 0x8000) != 0;
|
||||
U8 insert_idx = cursor_idx;
|
||||
if (is_shift) insert_idx ++;
|
||||
|
||||
if (tape_arena.used + sizeof(U4) <= tape_arena.capacity && anno_arena.used + sizeof(U8) <= anno_arena.capacity) {
|
||||
U8*r anno_ptr = u8_r(anno_arena.start);
|
||||
for (U8 i = tape_count; i > insert_idx; i --) {
|
||||
tape_ptr[i] = tape_ptr[i-1];
|
||||
anno_ptr[i] = anno_ptr[i-1];
|
||||
}
|
||||
if (wparam == MS_VK_RETURN) {
|
||||
tape_ptr[insert_idx] = pack_token(STag_Format, 0xA);
|
||||
anno_ptr[insert_idx] = 0;
|
||||
} else {
|
||||
tape_ptr[insert_idx] = pack_token(STag_Comment, 0);
|
||||
anno_ptr[insert_idx] = 0;
|
||||
}
|
||||
if (is_shift) cursor_idx ++;
|
||||
tape_arena.used += sizeof(U4);
|
||||
anno_arena.used += sizeof(U8);
|
||||
}
|
||||
}
|
||||
|
||||
vm_rax = 0; vm_rdx = 0;
|
||||
mem_zero(u8_(vm_globals), sizeof(vm_globals));
|
||||
|
||||
compile_and_run_tape();
|
||||
|
||||
ms_invalidate_rect(hwnd, nullptr, true);
|
||||
return 0;
|
||||
}
|
||||
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);
|
||||
|
||||
ms_set_bk_mode(hdc, 1);
|
||||
|
||||
void* hBgBrush = ms_create_solid_brush(0x00222222);
|
||||
ms_select_object(hdc, hBgBrush);
|
||||
ms_rectangle(hdc, -1, -1, 3000, 3000);
|
||||
|
||||
void* hBrushEdit = ms_create_solid_brush(0x008E563B);
|
||||
void* hBrushNav = ms_create_solid_brush(0x00262F3B);
|
||||
|
||||
S4 start_x = 40, start_y = 60, spacing_x = 110, spacing_y = 35;
|
||||
S4 x = start_x, y = start_y;
|
||||
|
||||
U4*r tape_ptr = u4_r(tape_arena.start);
|
||||
U8*r anno_ptr = u8_r(anno_arena.start);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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";
|
||||
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";
|
||||
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) {
|
||||
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]) {
|
||||
semantics_str[13 + name_len] = tag_name[name_len];
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
case MS_WM_DESTROY: { ms_post_quit_message(0); return 0; }
|
||||
}
|
||||
return ms_def_window_proc_a(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
Slice tape_mem = slice_ut_(u8_(ms_virtual_alloc(nullptr, 64 * 1024, MS_MEM_COMMIT | MS_MEM_RESERVE, MS_PAGE_READWRITE)), 64 * 1024);
|
||||
Slice anno_mem = slice_ut_(u8_(ms_virtual_alloc(nullptr, 64 * 1024, MS_MEM_COMMIT | MS_MEM_RESERVE, MS_PAGE_READWRITE)), 64 * 1024);
|
||||
Slice code_mem = slice_ut_(u8_(ms_virtual_alloc(nullptr, 64 * 1024, MS_MEM_COMMIT | MS_MEM_RESERVE, MS_PAGE_EXECUTE_READWRITE)), 64 * 1024);
|
||||
if (! tape_mem.ptr || ! anno_mem.ptr || ! code_mem.ptr) ms_exit_process(1);
|
||||
|
||||
farena_init(& tape_arena, tape_mem);
|
||||
farena_init(& anno_arena, anno_mem);
|
||||
farena_init(& code_arena, code_mem);
|
||||
|
||||
scatter(pack_token(STag_Comment, 0), "INIT ");
|
||||
scatter(pack_token(STag_Data, 5), 0);
|
||||
scatter(pack_token(STag_Data, 0), 0);
|
||||
scatter(pack_token(STag_Imm, 0), "STORE ");
|
||||
|
||||
scatter(pack_token(STag_Data, 1), 0);
|
||||
scatter(pack_token(STag_Data, 1), 0);
|
||||
scatter(pack_token(STag_Imm, 0), "STORE ");
|
||||
|
||||
scatter(pack_token(STag_Format, 0xA), 0);
|
||||
|
||||
scatter(pack_token(STag_Define, 0), "F_STEP ");
|
||||
scatter(pack_token(STag_Data, 0), 0);
|
||||
scatter(pack_token(STag_Call, 0), "FETCH ");
|
||||
scatter(pack_token(STag_Call, 0), "RET_IF_Z");
|
||||
scatter(pack_token(STag_Format, 0xA), 0);
|
||||
|
||||
scatter(pack_token(STag_Data, 1), 0);
|
||||
scatter(pack_token(STag_Call, 0), "FETCH ");
|
||||
scatter(pack_token(STag_Data, 0), 0);
|
||||
scatter(pack_token(STag_Call, 0), "FETCH ");
|
||||
scatter(pack_token(STag_Call, 0), "MULT ");
|
||||
scatter(pack_token(STag_Data, 1), 0);
|
||||
scatter(pack_token(STag_Call, 0), "STORE ");
|
||||
scatter(pack_token(STag_Format, 0xA), 0);
|
||||
|
||||
scatter(pack_token(STag_Data, 0), 0);
|
||||
scatter(pack_token(STag_Call, 0), "FETCH ");
|
||||
scatter(pack_token(STag_Call, 0), "DEC ");
|
||||
scatter(pack_token(STag_Data, 0), 0);
|
||||
scatter(pack_token(STag_Call, 0), "STORE ");
|
||||
|
||||
scatter(pack_token(STag_Data, 1), 0);
|
||||
scatter(pack_token(STag_Call, 0), "FETCH ");
|
||||
scatter(pack_token(STag_Call, 0), "PRINT ");
|
||||
|
||||
scatter(pack_token(STag_Format, 0xA), 0);
|
||||
|
||||
scatter(pack_token(STag_Imm, 0), "F_STEP ");
|
||||
scatter(pack_token(STag_Imm, 0), "F_STEP ");
|
||||
scatter(pack_token(STag_Imm, 0), "F_STEP ");
|
||||
scatter(pack_token(STag_Imm, 0), "F_STEP ");
|
||||
scatter(pack_token(STag_Imm, 0), "F_STEP ");
|
||||
|
||||
relink_tape();
|
||||
run_full = true;
|
||||
compile_and_run_tape();
|
||||
run_full = false;
|
||||
|
||||
MS_WNDCLASSA wc;
|
||||
mem_fill(u8_(& wc), 0, sizeof(wc));
|
||||
wc.lpfnWndProc = win_proc;
|
||||
wc.hInstance = ms_get_stock_object(0);
|
||||
wc.lpszClassName = "ColorForthWindow";
|
||||
wc.hbrBackground = ms_get_stock_object(4);
|
||||
ms_register_class_a(& wc);
|
||||
|
||||
void* hwnd = ms_create_window_ex_a(0, wc.lpszClassName, "Sourceless Global Memory Explorer", MS_WS_OVERLAPPEDWINDOW | MS_WS_VISIBLE, 100, 100, 1100, 750, nullptr, nullptr, wc.hInstance, nullptr);
|
||||
MS_MSG msg;
|
||||
while (ms_get_message_a(& msg, nullptr, 0, 0)) { ms_translate_message(& msg); ms_dispatch_message_a(& msg); }
|
||||
ms_exit_process(0);
|
||||
return 0;
|
||||
}
|
||||
1208
attempt_1/microui.c
Normal file
1208
attempt_1/microui.c
Normal file
File diff suppressed because it is too large
Load Diff
296
attempt_1/microui.h
Normal file
296
attempt_1/microui.h
Normal file
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
** Copyright (c) 2024 rxi
|
||||
**
|
||||
** This library is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the MIT license. See `microui.c` for details.
|
||||
*/
|
||||
|
||||
#ifndef MICROUI_H
|
||||
#define MICROUI_H
|
||||
|
||||
#define MU_VERSION "2.02"
|
||||
|
||||
#define MU_COMMANDLIST_SIZE (256 * 1024)
|
||||
#define MU_ROOTLIST_SIZE 32
|
||||
#define MU_CONTAINERSTACK_SIZE 32
|
||||
#define MU_CLIPSTACK_SIZE 32
|
||||
#define MU_IDSTACK_SIZE 32
|
||||
#define MU_LAYOUTSTACK_SIZE 16
|
||||
#define MU_CONTAINERPOOL_SIZE 48
|
||||
#define MU_TREENODEPOOL_SIZE 48
|
||||
#define MU_MAX_WIDTHS 16
|
||||
#define MU_REAL float
|
||||
#define MU_REAL_FMT "%.3g"
|
||||
#define MU_SLIDER_FMT "%.2f"
|
||||
#define MU_MAX_FMT 127
|
||||
|
||||
#define mu_stack(T, n) struct { int idx; T items[n]; }
|
||||
#define mu_min(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define mu_max(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define mu_clamp(x, a, b) mu_min(b, mu_max(a, x))
|
||||
|
||||
enum {
|
||||
MU_CLIP_PART = 1,
|
||||
MU_CLIP_ALL
|
||||
};
|
||||
|
||||
enum {
|
||||
MU_COMMAND_JUMP = 1,
|
||||
MU_COMMAND_CLIP,
|
||||
MU_COMMAND_RECT,
|
||||
MU_COMMAND_TEXT,
|
||||
MU_COMMAND_ICON,
|
||||
MU_COMMAND_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
MU_COLOR_TEXT,
|
||||
MU_COLOR_BORDER,
|
||||
MU_COLOR_WINDOWBG,
|
||||
MU_COLOR_TITLEBG,
|
||||
MU_COLOR_TITLETEXT,
|
||||
MU_COLOR_PANELBG,
|
||||
MU_COLOR_BUTTON,
|
||||
MU_COLOR_BUTTONHOVER,
|
||||
MU_COLOR_BUTTONFOCUS,
|
||||
MU_COLOR_BASE,
|
||||
MU_COLOR_BASEHOVER,
|
||||
MU_COLOR_BASEFOCUS,
|
||||
MU_COLOR_SCROLLBASE,
|
||||
MU_COLOR_SCROLLTHUMB,
|
||||
MU_COLOR_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
MU_ICON_CLOSE = 1,
|
||||
MU_ICON_CHECK,
|
||||
MU_ICON_COLLAPSED,
|
||||
MU_ICON_EXPANDED,
|
||||
MU_ICON_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
MU_RES_ACTIVE = (1 << 0),
|
||||
MU_RES_SUBMIT = (1 << 1),
|
||||
MU_RES_CHANGE = (1 << 2)
|
||||
};
|
||||
|
||||
enum {
|
||||
MU_OPT_ALIGNCENTER = (1 << 0),
|
||||
MU_OPT_ALIGNRIGHT = (1 << 1),
|
||||
MU_OPT_NOINTERACT = (1 << 2),
|
||||
MU_OPT_NOFRAME = (1 << 3),
|
||||
MU_OPT_NORESIZE = (1 << 4),
|
||||
MU_OPT_NOSCROLL = (1 << 5),
|
||||
MU_OPT_NOCLOSE = (1 << 6),
|
||||
MU_OPT_NOTITLE = (1 << 7),
|
||||
MU_OPT_HOLDFOCUS = (1 << 8),
|
||||
MU_OPT_AUTOSIZE = (1 << 9),
|
||||
MU_OPT_POPUP = (1 << 10),
|
||||
MU_OPT_CLOSED = (1 << 11),
|
||||
MU_OPT_EXPANDED = (1 << 12)
|
||||
};
|
||||
|
||||
enum {
|
||||
MU_MOUSE_LEFT = (1 << 0),
|
||||
MU_MOUSE_RIGHT = (1 << 1),
|
||||
MU_MOUSE_MIDDLE = (1 << 2)
|
||||
};
|
||||
|
||||
enum {
|
||||
MU_KEY_SHIFT = (1 << 0),
|
||||
MU_KEY_CTRL = (1 << 1),
|
||||
MU_KEY_ALT = (1 << 2),
|
||||
MU_KEY_BACKSPACE = (1 << 3),
|
||||
MU_KEY_RETURN = (1 << 4)
|
||||
};
|
||||
|
||||
|
||||
typedef struct mu_Context mu_Context;
|
||||
typedef unsigned mu_Id;
|
||||
typedef MU_REAL mu_Real;
|
||||
typedef void* mu_Font;
|
||||
|
||||
typedef struct { int x, y; } mu_Vec2;
|
||||
typedef struct { int x, y, w, h; } mu_Rect;
|
||||
typedef struct { unsigned char r, g, b, a; } mu_Color;
|
||||
typedef struct { mu_Id id; int last_update; } mu_PoolItem;
|
||||
|
||||
typedef struct { int type, size; } mu_BaseCommand;
|
||||
typedef struct { mu_BaseCommand base; void *dst; } mu_JumpCommand;
|
||||
typedef struct { mu_BaseCommand base; mu_Rect rect; } mu_ClipCommand;
|
||||
typedef struct { mu_BaseCommand base; mu_Rect rect; mu_Color color; } mu_RectCommand;
|
||||
typedef struct { mu_BaseCommand base; mu_Font font; mu_Vec2 pos; mu_Color color; char str[1]; } mu_TextCommand;
|
||||
typedef struct { mu_BaseCommand base; mu_Rect rect; int id; mu_Color color; } mu_IconCommand;
|
||||
|
||||
typedef union {
|
||||
int type;
|
||||
mu_BaseCommand base;
|
||||
mu_JumpCommand jump;
|
||||
mu_ClipCommand clip;
|
||||
mu_RectCommand rect;
|
||||
mu_TextCommand text;
|
||||
mu_IconCommand icon;
|
||||
} mu_Command;
|
||||
|
||||
typedef struct {
|
||||
mu_Rect body;
|
||||
mu_Rect next;
|
||||
mu_Vec2 position;
|
||||
mu_Vec2 size;
|
||||
mu_Vec2 max;
|
||||
int widths[MU_MAX_WIDTHS];
|
||||
int items;
|
||||
int item_index;
|
||||
int next_row;
|
||||
int next_type;
|
||||
int indent;
|
||||
} mu_Layout;
|
||||
|
||||
typedef struct {
|
||||
mu_Command *head, *tail;
|
||||
mu_Rect rect;
|
||||
mu_Rect body;
|
||||
mu_Vec2 content_size;
|
||||
mu_Vec2 scroll;
|
||||
int zindex;
|
||||
int open;
|
||||
} mu_Container;
|
||||
|
||||
typedef struct {
|
||||
mu_Font font;
|
||||
mu_Vec2 size;
|
||||
int padding;
|
||||
int spacing;
|
||||
int indent;
|
||||
int title_height;
|
||||
int scrollbar_size;
|
||||
int thumb_size;
|
||||
mu_Color colors[MU_COLOR_MAX];
|
||||
} mu_Style;
|
||||
|
||||
struct mu_Context {
|
||||
/* callbacks */
|
||||
int (*text_width)(mu_Font font, const char *str, int len);
|
||||
int (*text_height)(mu_Font font);
|
||||
void (*draw_frame)(mu_Context *ctx, mu_Rect rect, int colorid);
|
||||
/* core state */
|
||||
mu_Style _style;
|
||||
mu_Style *style;
|
||||
mu_Id hover;
|
||||
mu_Id focus;
|
||||
mu_Id last_id;
|
||||
mu_Rect last_rect;
|
||||
int last_zindex;
|
||||
int updated_focus;
|
||||
int frame;
|
||||
mu_Container *hover_root;
|
||||
mu_Container *next_hover_root;
|
||||
mu_Container *scroll_target;
|
||||
char number_edit_buf[MU_MAX_FMT];
|
||||
mu_Id number_edit;
|
||||
/* stacks */
|
||||
mu_stack(char, MU_COMMANDLIST_SIZE) command_list;
|
||||
mu_stack(mu_Container*, MU_ROOTLIST_SIZE) root_list;
|
||||
mu_stack(mu_Container*, MU_CONTAINERSTACK_SIZE) container_stack;
|
||||
mu_stack(mu_Rect, MU_CLIPSTACK_SIZE) clip_stack;
|
||||
mu_stack(mu_Id, MU_IDSTACK_SIZE) id_stack;
|
||||
mu_stack(mu_Layout, MU_LAYOUTSTACK_SIZE) layout_stack;
|
||||
/* retained state pools */
|
||||
mu_PoolItem container_pool[MU_CONTAINERPOOL_SIZE];
|
||||
mu_Container containers[MU_CONTAINERPOOL_SIZE];
|
||||
mu_PoolItem treenode_pool[MU_TREENODEPOOL_SIZE];
|
||||
/* input state */
|
||||
mu_Vec2 mouse_pos;
|
||||
mu_Vec2 last_mouse_pos;
|
||||
mu_Vec2 mouse_delta;
|
||||
mu_Vec2 scroll_delta;
|
||||
int mouse_down;
|
||||
int mouse_pressed;
|
||||
int key_down;
|
||||
int key_pressed;
|
||||
char input_text[32];
|
||||
};
|
||||
|
||||
|
||||
mu_Vec2 mu_vec2(int x, int y);
|
||||
mu_Rect mu_rect(int x, int y, int w, int h);
|
||||
mu_Color mu_color(int r, int g, int b, int a);
|
||||
|
||||
void mu_init(mu_Context *ctx);
|
||||
void mu_begin(mu_Context *ctx);
|
||||
void mu_end(mu_Context *ctx);
|
||||
void mu_set_focus(mu_Context *ctx, mu_Id id);
|
||||
mu_Id mu_get_id(mu_Context *ctx, const void *data, int size);
|
||||
void mu_push_id(mu_Context *ctx, const void *data, int size);
|
||||
void mu_pop_id(mu_Context *ctx);
|
||||
void mu_push_clip_rect(mu_Context *ctx, mu_Rect rect);
|
||||
void mu_pop_clip_rect(mu_Context *ctx);
|
||||
mu_Rect mu_get_clip_rect(mu_Context *ctx);
|
||||
int mu_check_clip(mu_Context *ctx, mu_Rect r);
|
||||
mu_Container* mu_get_current_container(mu_Context *ctx);
|
||||
mu_Container* mu_get_container(mu_Context *ctx, const char *name);
|
||||
void mu_bring_to_front(mu_Context *ctx, mu_Container *cnt);
|
||||
|
||||
int mu_pool_init(mu_Context *ctx, mu_PoolItem *items, int len, mu_Id id);
|
||||
int mu_pool_get(mu_Context *ctx, mu_PoolItem *items, int len, mu_Id id);
|
||||
void mu_pool_update(mu_Context *ctx, mu_PoolItem *items, int idx);
|
||||
|
||||
void mu_input_mousemove(mu_Context *ctx, int x, int y);
|
||||
void mu_input_mousedown(mu_Context *ctx, int x, int y, int btn);
|
||||
void mu_input_mouseup(mu_Context *ctx, int x, int y, int btn);
|
||||
void mu_input_scroll(mu_Context *ctx, int x, int y);
|
||||
void mu_input_keydown(mu_Context *ctx, int key);
|
||||
void mu_input_keyup(mu_Context *ctx, int key);
|
||||
void mu_input_text(mu_Context *ctx, const char *text);
|
||||
|
||||
mu_Command* mu_push_command(mu_Context *ctx, int type, int size);
|
||||
int mu_next_command(mu_Context *ctx, mu_Command **cmd);
|
||||
void mu_set_clip(mu_Context *ctx, mu_Rect rect);
|
||||
void mu_draw_rect(mu_Context *ctx, mu_Rect rect, mu_Color color);
|
||||
void mu_draw_box(mu_Context *ctx, mu_Rect rect, mu_Color color);
|
||||
void mu_draw_text(mu_Context *ctx, mu_Font font, const char *str, int len, mu_Vec2 pos, mu_Color color);
|
||||
void mu_draw_icon(mu_Context *ctx, int id, mu_Rect rect, mu_Color color);
|
||||
|
||||
void mu_layout_row(mu_Context *ctx, int items, const int *widths, int height);
|
||||
void mu_layout_width(mu_Context *ctx, int width);
|
||||
void mu_layout_height(mu_Context *ctx, int height);
|
||||
void mu_layout_begin_column(mu_Context *ctx);
|
||||
void mu_layout_end_column(mu_Context *ctx);
|
||||
void mu_layout_set_next(mu_Context *ctx, mu_Rect r, int relative);
|
||||
mu_Rect mu_layout_next(mu_Context *ctx);
|
||||
|
||||
void mu_draw_control_frame(mu_Context *ctx, mu_Id id, mu_Rect rect, int colorid, int opt);
|
||||
void mu_draw_control_text(mu_Context *ctx, const char *str, mu_Rect rect, int colorid, int opt);
|
||||
int mu_mouse_over(mu_Context *ctx, mu_Rect rect);
|
||||
void mu_update_control(mu_Context *ctx, mu_Id id, mu_Rect rect, int opt);
|
||||
|
||||
#define mu_button(ctx, label) mu_button_ex(ctx, label, 0, MU_OPT_ALIGNCENTER)
|
||||
#define mu_textbox(ctx, buf, bufsz) mu_textbox_ex(ctx, buf, bufsz, 0)
|
||||
#define mu_slider(ctx, value, lo, hi) mu_slider_ex(ctx, value, lo, hi, 0, MU_SLIDER_FMT, MU_OPT_ALIGNCENTER)
|
||||
#define mu_number(ctx, value, step) mu_number_ex(ctx, value, step, MU_SLIDER_FMT, MU_OPT_ALIGNCENTER)
|
||||
#define mu_header(ctx, label) mu_header_ex(ctx, label, 0)
|
||||
#define mu_begin_treenode(ctx, label) mu_begin_treenode_ex(ctx, label, 0)
|
||||
#define mu_begin_window(ctx, title, rect) mu_begin_window_ex(ctx, title, rect, 0)
|
||||
#define mu_begin_panel(ctx, name) mu_begin_panel_ex(ctx, name, 0)
|
||||
|
||||
void mu_text(mu_Context *ctx, const char *text);
|
||||
void mu_label(mu_Context *ctx, const char *text);
|
||||
int mu_button_ex(mu_Context *ctx, const char *label, int icon, int opt);
|
||||
int mu_checkbox(mu_Context *ctx, const char *label, int *state);
|
||||
int mu_textbox_raw(mu_Context *ctx, char *buf, int bufsz, mu_Id id, mu_Rect r, int opt);
|
||||
int mu_textbox_ex(mu_Context *ctx, char *buf, int bufsz, int opt);
|
||||
int mu_slider_ex(mu_Context *ctx, mu_Real *value, mu_Real low, mu_Real high, mu_Real step, const char *fmt, int opt);
|
||||
int mu_number_ex(mu_Context *ctx, mu_Real *value, mu_Real step, const char *fmt, int opt);
|
||||
int mu_header_ex(mu_Context *ctx, const char *label, int opt);
|
||||
int mu_begin_treenode_ex(mu_Context *ctx, const char *label, int opt);
|
||||
void mu_end_treenode(mu_Context *ctx);
|
||||
int mu_begin_window_ex(mu_Context *ctx, const char *title, mu_Rect rect, int opt);
|
||||
void mu_end_window(mu_Context *ctx);
|
||||
void mu_open_popup(mu_Context *ctx, const char *name);
|
||||
int mu_begin_popup(mu_Context *ctx, const char *name);
|
||||
void mu_end_popup(mu_Context *ctx);
|
||||
void mu_begin_panel_ex(mu_Context *ctx, const char *name, int opt);
|
||||
void mu_end_panel(mu_Context *ctx);
|
||||
|
||||
#endif
|
||||
BIN
win_proc.c
Normal file
BIN
win_proc.c
Normal file
Binary file not shown.
Reference in New Issue
Block a user