alloc big buffers on heap

This commit is contained in:
2026-01-09 05:42:08 +05:00
parent 01df4abcfb
commit bd23c66607
14 changed files with 245 additions and 230 deletions

View File

@@ -10,52 +10,52 @@ TimCell tim_cell(cstr s, u8 fg, u8 bg) {
}
void tim_clear_cells(void) {
size_t size = sizeof(tim.cells[0]) * tim.w * tim.h;
memset(tim.cells, 0, size);
size_t size = sizeof(tim->cells[0]) * tim->w * tim->h;
memset(tim->cells, 0, size);
}
void tim_draw_chr(TimCell cell, i32 x, i32 y) {
if (x >= 0 && x < tim.w && y >= 0 && y < tim.h) {
tim.cells[x + y * tim.w] = cell;
if (x >= 0 && x < tim->w && y >= 0 && y < tim->h) {
tim->cells[x + y * tim->w] = cell;
}
}
void tim_draw_row(TimCell cell, i32 x, i32 y, i32 w) {
if (y >= 0 && y < tim.h && w > 0) {
for (i32 i = MAX(x, 0); i < MIN(x + w, tim.w); i++) {
tim.cells[i + y * tim.w] = cell;
if (y >= 0 && y < tim->h && w > 0) {
for (i32 i = MAX(x, 0); i < MIN(x + w, tim->w); i++) {
tim->cells[i + y * tim->w] = cell;
}
}
}
void tim_draw_col(TimCell cell, i32 x, i32 y, i32 h) {
if (x >= 0 && x < tim.w && h > 0) {
for (i32 i = MAX(y, 0); i < MIN(y + h, tim.h); i++) {
tim.cells[x + i * tim.w] = cell;
if (x >= 0 && x < tim->w && h > 0) {
for (i32 i = MAX(y, 0); i < MIN(y + h, tim->h); i++) {
tim->cells[x + i * tim->w] = cell;
}
}
}
void tim_draw_lot(TimCell cell, i32 x, i32 y, i32 w, i32 h) {
if (w > 0 && h > 0) {
for (i32 iy = MAX(y, 0); iy < MIN(y + h, tim.h); iy++) {
for (i32 ix = MAX(x, 0); ix < MIN(x + w, tim.w); ix++) {
tim.cells[ix + iy * tim.w] = cell;
for (i32 iy = MAX(y, 0); iy < MIN(y + h, tim->h); iy++) {
for (i32 ix = MAX(x, 0); ix < MIN(x + w, tim->w); ix++) {
tim->cells[ix + iy * tim->w] = cell;
}
}
}
}
void tim_draw_str(cstr s, i32 x, i32 y, i32 w, u8 fg, u8 bg) {
if (s && y >= 0 && x < tim.w && y < tim.h ) {
i32 end = MIN(x + w, tim.w);
if (s && y >= 0 && x < tim->w && y < tim->h ) {
i32 end = MIN(x + w, tim->w);
bool wide = false;
for (i32 i = 0; s[i] && x < end; x++) {
TimCell c = tim_cell(&s[i], fg, bg);
wide = wide || tim_utf8_is_wide_perhaps(c.buf, c.n);
if (x >= 0) {
c.wide = wide;
tim.cells[x + y * tim.w] = c;
tim->cells[x + y * tim->w] = c;
}
i += c.n;
}
@@ -75,11 +75,11 @@ void tim_draw_box(i32 x, i32 y, i32 w, i32 h, u8 fg, u8 bg) {
}
void tim_draw_invert(i32 x, i32 y, i32 w) {
if (y >= 0 && y < tim.h && w > 0) {
for (i32 i = MAX(x, 0); i < MIN(x + w, tim.w); i++) {
TimCell c = tim.cells[i + y * tim.w];
tim.cells[i + y * tim.w].fg = c.bg;
tim.cells[i + y * tim.w].bg = c.fg;
if (y >= 0 && y < tim->h && w > 0) {
for (i32 i = MAX(x, 0); i < MIN(x + w, tim->w); i++) {
TimCell c = tim->cells[i + y * tim->w];
tim->cells[i + y * tim->w].fg = c.bg;
tim->cells[i + y * tim->w].bg = c.fg;
}
}
}

View File

@@ -39,20 +39,20 @@ void edit_delete(TimEditState* e) {
static i32 edit_event(TimEditState* e, TimRect r) {
if (tim_is_mouse_click_over(r)) {
// take focus
tim.focus = e;
tim->focus = e;
return 0;
}
if (tim.focus != e || tim.event.type != TimEvent_Key) {
if (tim->focus != e || tim->event.type != TimEvent_Key) {
// not focused or no key press
return 0;
}
tim.event.type = TimEvent_Void; // consume event
tim->event.type = TimEvent_Void; // consume event
switch (tim.event.key) {
switch (tim->event.key) {
case TimKey_Escape:
case TimKey_Enter:
tim.focus = 0; // release focus
tim->focus = 0; // release focus
break;
case TimKey_Delete:
edit_delete(e);
@@ -76,21 +76,21 @@ static i32 edit_event(TimEditState* e, TimRect r) {
e->cursor = e->length;
break;
default:
if (tim.event.key >= ' ') {
edit_insert(e, tim.event.s);
if (tim->event.key >= ' ') {
edit_insert(e, tim->event.s);
}
break;
}
return tim.event.key;
return tim->event.key;
}
i32 edit(TimEditState* e, i32 x, i32 y, i32 w, u64 color) {
TimRect r = tim_scope_rect_to_absolute(x, y, w, 3);
if (tim.event.type == TimEvent_Draw) {
if (tim->event.type == TimEvent_Draw) {
tim_draw_box(r.x, r.y, r.w, r.h, color >> 16, color >> 8);
if (tim.focus == e) {
if (tim->focus == e) {
char* s = e->s + tim_utf8_pos(e->s, e->cursor - r.w + 4);
i32 cur = MIN(r.w - 4, e->cursor);
tim_draw_str(s, r.x + 2, r.y + 1, r.w - 3, color, color >> 8);

View File

@@ -1,7 +1,7 @@
#include "tim.h"
bool tim_is_event_key(TimEventType type, TimKey key) {
return tim.event.type == type && tim.event.key == key;
return tim->event.type == type && tim->event.key == key;
}
bool tim_is_key_press(TimKey key) {
@@ -9,8 +9,8 @@ bool tim_is_key_press(TimKey key) {
}
bool tim_is_mouse_over(TimRect r) {
i32 x = tim.event.x;
i32 y = tim.event.y;
i32 x = tim->event.x;
i32 y = tim->event.y;
return x >= r.x && x < r.x + r.w && y >= r.y && y < r.y + r.h;
}

View File

@@ -1,19 +1,37 @@
#include "tim.h"
// TODO: remove global variables
static TimCell _tim_cells[TIM_MAX_CELLS << TIM_ENABLE_DBUF];
static char _tim_buf[TIM_MAX_BUF];
TimState tim = {
.cells = _tim_cells,
.cells_double_buf = _tim_cells,
.buf = _tim_buf,
};
static void tim_render(void);
TimState* tim = NULL;
static void tim_init(void){
tim = (TimState*)malloc(sizeof(TimState));
memset(tim, 0, sizeof(TimState));
size_t cdb_size = (TIM_MAX_CELLS << TIM_ENABLE_DBUF);
tim->cells_double_buf = (TimCell*)malloc(cdb_size * sizeof(TimCell));
tim->cells = tim->cells_double_buf;
tim->buf = (char*)malloc(TIM_MAX_BUF);
}
static void tim_deinit(void){
if(!tim)
return;
free(tim->cells_double_buf);
free(tim->buf);
free(tim);
tim = NULL;
}
bool tim_run(f32 fps) {
if(tim == NULL){
tim_init();
atexit(tim_deinit);
}
i32 timeout = (fps > 0) ? (i32)(1000 / fps) : 0;
while (true) {
switch (tim.loop_stage) {
switch (tim->loop_stage) {
case 0:
// runs only once
tim_init_terminal();
@@ -21,31 +39,144 @@ bool tim_run(f32 fps) {
// fallthru
case 1:
// process input event
tim.start_us = tim_time_usec();
if (tim.event.type != TimEvent_Draw) {
tim->start_us = tim_time_usec();
if (tim->event.type != TimEvent_Draw) {
// reset focus on mouse click
if (tim_is_event_key(TimEvent_Mouse, TimKey_MouseButtonLeft)) {
tim.focus = 0;
tim->focus = 0;
}
tim.loop_stage = 2;
tim->loop_stage = 2;
return true;
}
// fallthru
case 2:
// process draw event
tim_clear_cells();
tim.event.type = TimEvent_Draw;
tim.loop_stage = 3;
tim->event.type = TimEvent_Draw;
tim->loop_stage = 3;
return true;
case 3:
// render screen and wait for next event
tim_render();
tim.render_us = tim_time_usec() - tim.start_us;
tim->render_us = tim_time_usec() - tim->start_us;
tim_read_event(timeout); // blocks
// fallthru
default:
tim.loop_stage = 1;
tim->loop_stage = 1;
break;
}
} // while
}
// write character to output buffer
static void tim_put_chr(char c) {
if (tim->buf_size + 1 < TIM_MAX_BUF) {
tim->buf[tim->buf_size] = c;
tim->buf_size += 1;
}
}
// write string to output buffer
static void tim_put_str(cstr s, i32 size) {
if (size > 0 && tim->buf_size + size < TIM_MAX_BUF) {
memmove(&tim->buf[tim->buf_size], s, size);
tim->buf_size += size;
}
}
// write integer as decimal string to output buffer
static void tim_put_int(i32 i) {
// optimized for small positive values, reduces load by a third
char* buf = &tim->buf[tim->buf_size];
if (tim->buf_size + 11 >= TIM_MAX_BUF) {
// not enough space for 32 bit integer
} else if ((u32)i < 10) {
buf[0] = '0' + i;
tim->buf_size += 1;
} else if ((u32)i < 100) {
buf[0] = '0' + i / 10;
buf[1] = '0' + i % 10;
tim->buf_size += 2;
} else if ((u32)i < 1000) {
buf[0] = '0' + i / 100;
buf[1] = '0' + (i / 10) % 10;
buf[2] = '0' + i % 10;
tim->buf_size += 3;
} else {
tim->buf_size += sprintf(buf, "%d", i);
}
}
static void tim_render(void) {
i32 fg = -1;
i32 bg = -1;
bool wide = false;
bool skip = false;
// screen buffers
TimCell* new_cells = tim->cells_double_buf;
TimCell* old_cells = tim->cells_double_buf;
#if TIM_ENABLE_DBUF
new_cells += (tim->frame & 1) ? TIM_MAX_CELLS : 0;
old_cells += (tim->frame & 1) ? 0 : TIM_MAX_CELLS;
#endif
tim->buf_size = 0;
for (i32 i = 0; i < tim->w * tim->h; i++) {
TimCell c = new_cells[i];
#if TIM_ENABLE_DBUF
// do nothing if cells in look-ahead are identical
const i32 la = 8; // look-ahead
if (!tim->resized && !(i % la) && (i + la < TIM_MAX_CELLS) &&
!memcmp(new_cells + i, old_cells + i, la * sizeof(c))) {
skip = true;
i = i + la - 1;
continue;
}
#endif
// Set cursor position after a new line, after a string containing wide
// characters or after skipping identical cells.
bool new_line = i % tim->w == 0;
bool wide_spill = wide && (c.n == 0 || c.buf[0] == ' ');
bool wide_flank = wide && !wide_spill && !c.wide;
if (new_line || wide_flank || skip) {
tim_put_str(S("\33["));
tim_put_int((i / tim->w) + 1);
tim_put_chr(';');
tim_put_int((i % tim->w) + 1);
tim_put_chr('H');
}
wide = c.wide || wide_spill;
skip = false;
// change foreground color
if (c.fg != fg) {
fg = c.fg;
tim_put_str(S("\33[38;5;"));
tim_put_int(fg);
tim_put_chr('m');
}
// change background color
if (c.bg != bg) {
bg = c.bg;
tim_put_str(S("\33[48;5;"));
tim_put_int(bg);
tim_put_chr('m');
}
// write character
if (c.n) {
tim_put_str((char*)c.buf, c.n);
} else {
tim_put_chr(' ');
}
}
// duration depends on connection and terminal rendering speed
tim_write_str(tim->buf, tim->buf_size);
tim->resized = false;
tim->frame += 1; // frame counter
tim->cells = old_cells; // swap buffer
}

View File

@@ -1,114 +0,0 @@
#include "tim.h"
// write character to output buffer
static void tim_put_chr(char c) {
if (tim.buf_size + 1 < TIM_MAX_BUF) {
tim.buf[tim.buf_size] = c;
tim.buf_size += 1;
}
}
// write string to output buffer
static void tim_put_str(cstr s, i32 size) {
if (size > 0 && tim.buf_size + size < TIM_MAX_BUF) {
memmove(&tim.buf[tim.buf_size], s, size);
tim.buf_size += size;
}
}
// write integer as decimal string to output buffer
static void tim_put_int(i32 i) {
// optimized for small positive values, reduces load by a third
char* buf = &tim.buf[tim.buf_size];
if (tim.buf_size + 11 >= TIM_MAX_BUF) {
// not enough space for 32 bit integer
} else if ((u32)i < 10) {
buf[0] = '0' + i;
tim.buf_size += 1;
} else if ((u32)i < 100) {
buf[0] = '0' + i / 10;
buf[1] = '0' + i % 10;
tim.buf_size += 2;
} else if ((u32)i < 1000) {
buf[0] = '0' + i / 100;
buf[1] = '0' + (i / 10) % 10;
buf[2] = '0' + i % 10;
tim.buf_size += 3;
} else {
tim.buf_size += sprintf(buf, "%d", i);
}
}
void tim_render(void) {
i32 fg = -1;
i32 bg = -1;
bool wide = false;
bool skip = false;
// screen buffers
TimCell* new_cells = tim.cells_double_buf;
TimCell* old_cells = tim.cells_double_buf;
#if TIM_ENABLE_DBUF
new_cells += (tim.frame & 1) ? TIM_MAX_CELLS : 0;
old_cells += (tim.frame & 1) ? 0 : TIM_MAX_CELLS;
#endif
tim.buf_size = 0;
for (i32 i = 0; i < tim.w * tim.h; i++) {
TimCell c = new_cells[i];
#if TIM_ENABLE_DBUF
// do nothing if cells in look-ahead are identical
const i32 la = 8; // look-ahead
if (!tim.resized && !(i % la) && (i + la < TIM_MAX_CELLS) &&
!memcmp(new_cells + i, old_cells + i, la * sizeof(c))) {
skip = true;
i = i + la - 1;
continue;
}
#endif
// Set cursor position after a new line, after a string containing wide
// characters or after skipping identical cells.
bool new_line = i % tim.w == 0;
bool wide_spill = wide && (c.n == 0 || c.buf[0] == ' ');
bool wide_flank = wide && !wide_spill && !c.wide;
if (new_line || wide_flank || skip) {
tim_put_str(S("\33["));
tim_put_int((i / tim.w) + 1);
tim_put_chr(';');
tim_put_int((i % tim.w) + 1);
tim_put_chr('H');
}
wide = c.wide || wide_spill;
skip = false;
// change foreground color
if (c.fg != fg) {
fg = c.fg;
tim_put_str(S("\33[38;5;"));
tim_put_int(fg);
tim_put_chr('m');
}
// change background color
if (c.bg != bg) {
bg = c.bg;
tim_put_str(S("\33[48;5;"));
tim_put_int(bg);
tim_put_chr('m');
}
// write character
if (c.n) {
tim_put_str((char*)c.buf, c.n);
} else {
tim_put_chr(' ');
}
}
// duration depends on connection and terminal rendering speed
tim_write_str(tim.buf, tim.buf_size);
tim.resized = false;
tim.frame += 1; // frame counter
tim.cells = old_cells; // swap buffer
}

View File

@@ -1,7 +1,7 @@
#include "tim.h"
TimRect tim_scope_rect_to_absolute(i32 x, i32 y, i32 w, i32 h) {
TimRect p = tim.scopes[tim.scope]; // parent scope
TimRect p = tim->scopes[tim->scope]; // parent scope
x = (x == A && w == A) ? 0 : x; // special cases
y = (y == A && h == A) ? 0 : y; //
@@ -35,16 +35,16 @@ TimRect tim_scope_rect_to_absolute(i32 x, i32 y, i32 w, i32 h) {
}
i32 tim_enter_scope(i32 x, i32 y, i32 w, i32 h) {
if (tim.scope + 1 >= TIM_MAX_SCOPE) {
if (tim->scope + 1 >= TIM_MAX_SCOPE) {
return 0;
}
TimRect r = tim_scope_rect_to_absolute(x, y, w, h);
tim.scope += 1;
tim.scopes[tim.scope] = r;
tim->scope += 1;
tim->scopes[tim->scope] = r;
return 1;
}
i32 tim_exit_scope(void) {
tim.scope -= (tim.scope > 0);
tim->scope -= (tim->scope > 0);
return 0;
}

View File

@@ -15,7 +15,7 @@ void tim_write_str(cstr s, i32 size) {
void signal_handler(i32 signal) {
// signals are written into a fifo pipe and read by event loop
ssize_t _ = write(tim.signal_pipe[1], &signal, sizeof(signal));
ssize_t _ = write(tim->signal_pipe[1], &signal, sizeof(signal));
(void)_; // remove unused-result warning
}
@@ -27,16 +27,16 @@ void tim_update_screen_size(void) {
}
i32 w = ws.ws_col;
i32 h = ws.ws_row;
tim.resized = (u32)(w * h) <= TIM_MAX_CELLS && (w != tim.w || h != tim.h);
if (tim.resized) {
tim.w = tim.scopes[0].w = w;
tim.h = tim.scopes[0].h = h;
tim->resized = (u32)(w * h) <= TIM_MAX_CELLS && (w != tim->w || h != tim->h);
if (tim->resized) {
tim->w = tim->scopes[0].w = w;
tim->h = tim->scopes[0].h = h;
}
}
void tim_init_terminal(void) {
tcgetattr(STDOUT_FILENO, &tim.attr); // store attributes
struct termios attr = tim.attr; //
tcgetattr(STDOUT_FILENO, &tim->attr); // store attributes
struct termios attr = tim->attr; //
cfmakeraw(&attr); // configure raw mode
tcsetattr(STDOUT_FILENO, TCSADRAIN, &attr); // set new attributes
tim_write_str(S("\33[?2004l")); // reset bracketed paste mode
@@ -46,14 +46,14 @@ void tim_init_terminal(void) {
tim_write_str(S("\33[?1002h")); // enable button events
tim_write_str(S("\33[?1006h")); // use mouse sgr protocol
tim_update_screen_size(); // get terminal size
i32 err = pipe(tim.signal_pipe); // create signal pipe
i32 err = pipe(tim->signal_pipe); // create signal pipe
if (!err) { //
signal(SIGWINCH, signal_handler); // terminal size changed
}
}
void tim_reset_terminal(void) {
tcsetattr(STDOUT_FILENO, TCSADRAIN, &tim.attr); // restore attributes
tcsetattr(STDOUT_FILENO, TCSADRAIN, &tim->attr); // restore attributes
tim_write_str(S("\33[?1000l")); // disable mouse
tim_write_str(S("\33[?1002l")); // disable mouse
tim_write_str(S("\33[m")); // reset colors
@@ -120,10 +120,10 @@ bool parse_input(event* restrict e, i32 n) {
}
void tim_read_event(i32 timeout_ms) {
event* e = &tim.event;
event* e = &tim->event;
struct pollfd pfd[2] = {
{.fd = tim.signal_pipe[0], .events = POLLIN},
{.fd = tim->signal_pipe[0], .events = POLLIN},
{.fd = STDIN_FILENO, .events = POLLIN},
};
@@ -143,7 +143,7 @@ void tim_read_event(i32 timeout_ms) {
if (pfd[0].revents & POLLIN) {
// received signal
i32 sig = 0;
i32 n = read(tim.signal_pipe[0], &sig, sizeof(sig));
i32 n = read(tim->signal_pipe[0], &sig, sizeof(sig));
if (n > 0 && sig == SIGWINCH) {
// screen size changed
e->type = TimEvent_Draw;

View File

@@ -1,14 +1,14 @@
#include "tim.h"
void tim_frame(i32 x, i32 y, i32 w, i32 h, u64 color) {
if (tim.event.type == TimEvent_Draw) {
if (tim->event.type == TimEvent_Draw) {
TimRect r = tim_scope_rect_to_absolute(x, y, w, h);
tim_draw_box(r.x, r.y, r.w, r.h, color, color >> 8);
}
}
void label(cstr s, i32 x, i32 y, i32 w, i32 h, u64 color) {
if (tim.event.type == TimEvent_Draw) {
if (tim->event.type == TimEvent_Draw) {
TimText t = tim_scan_str(s);
w = (w == A) ? t.width : w;
h = (h == A) ? t.lines : h;
@@ -28,7 +28,7 @@ bool button(cstr txt, i32 x, i32 y, i32 w, i32 h, u64 color) {
h = (h == A) ? 3 : h;
TimRect r = tim_scope_rect_to_absolute(x, y, w, h);
if (tim.event.type == TimEvent_Draw) {
if (tim->event.type == TimEvent_Draw) {
tim_draw_box(r.x, r.y, r.w, r.h, color >> 16, color >> 8);
tim_draw_str(txt, r.x + (w - tw) / 2, r.y + h / 2, w, color, color >> 8);
}
@@ -39,7 +39,7 @@ bool check(cstr txt, i32* state, i32 x, i32 y, i32 w, u64 color) {
w = (w == A) ? tim_utf8_len(txt) + 4 : w;
TimRect r = tim_scope_rect_to_absolute(x, y, w, 1);
if (tim.event.type == TimEvent_Draw) {
if (tim->event.type == TimEvent_Draw) {
cstr st = *state == -1 ? "-" : *state ? "x" : " ";
tim_draw_str("[ ] ", r.x, r.y, 4, color, color >> 8);
tim_draw_str(st, r.x + 1, r.y, 1, color >> 16, color >> 8);
@@ -56,7 +56,7 @@ bool radio(cstr txt, i32* state, i32 v, i32 x, i32 y, i32 w, u64 color) {
w = (w == A) ? tim_utf8_len(txt) + 4 : w;
TimRect r = tim_scope_rect_to_absolute(x, y, w, 1);
if (tim.event.type == TimEvent_Draw) {
if (tim->event.type == TimEvent_Draw) {
cstr st = *state == v ? "o" : " ";
tim_draw_str("( ) ", r.x, r.y, 4, color, color >> 8);
tim_draw_str(st, r.x + 1, r.y, 1, color >> 16, color >> 8);

View File

@@ -25,19 +25,19 @@ void tim_update_screen_size(void) {
}
i32 w = csbi.srWindow.Right - csbi.srWindow.Left + 1;
i32 h = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
tim.resized = (u32)(w * h) <= TIM_MAX_CELLS && (w != tim.w || h != tim.h);
if (tim.resized) {
tim.w = tim.scopes[0].w = w;
tim.h = tim.scopes[0].h = h;
tim.window = csbi.srWindow;
tim->resized = (u32)(w * h) <= TIM_MAX_CELLS && (w != tim->w || h != tim->h);
if (tim->resized) {
tim->w = tim->scopes[0].w = w;
tim->h = tim->scopes[0].h = h;
tim->window = csbi.srWindow;
}
}
void tim_init_terminal(void) {
DWORD mode = 0;
HANDLE hin = GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(hin, &tim.mode_in); // get current input mode
mode = tim.mode_in; //
GetConsoleMode(hin, &tim->mode_in); // get current input mode
mode = tim->mode_in; //
mode &= ~ENABLE_ECHO_INPUT; // disable echo
mode &= ~ENABLE_LINE_INPUT; // disable line buffer
// TODO: enable ctrl-c again
@@ -49,14 +49,14 @@ void tim_init_terminal(void) {
SetConsoleMode(hin, mode); // set input mode
//
HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE); //
GetConsoleMode(hout, &tim.mode_out); // get current output mode
mode = tim.mode_out; //
GetConsoleMode(hout, &tim->mode_out); // get current output mode
mode = tim->mode_out; //
mode |= ENABLE_PROCESSED_OUTPUT; // enable ascii sequences
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; // enable vt sequences
SetConsoleMode(hout, mode); // set output mode
//
tim.cp_in = GetConsoleCP(); // get current code page
tim.cp_out = GetConsoleOutputCP(); //
tim->cp_in = GetConsoleCP(); // get current code page
tim->cp_out = GetConsoleOutputCP(); //
SetConsoleCP(CP_UTF8); // set utf8 in/out code page
SetConsoleOutputCP(CP_UTF8); //
tim_write_str(S("\33[?1049h")); // use alternate buffer
@@ -69,14 +69,14 @@ void tim_reset_terminal(void) {
tim_write_str(S("\33[?1049l")); // exit alternate buffer
HANDLE hin = GetStdHandle(STD_INPUT_HANDLE); //
HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE); //
SetConsoleMode(hin, tim.mode_in); // set original mode
SetConsoleMode(hout, tim.mode_out); //
SetConsoleCP(tim.cp_in); // set original code page
SetConsoleOutputCP(tim.cp_out); //
SetConsoleMode(hin, tim->mode_in); // set original mode
SetConsoleMode(hout, tim->mode_out); //
SetConsoleCP(tim->cp_in); // set original code page
SetConsoleOutputCP(tim->cp_out); //
}
void tim_read_event(i32 timeout_ms) {
TimEvent* e = &tim.event;
TimEvent* e = &tim->event;
HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
const i8 key_table[256] = {
@@ -150,8 +150,8 @@ void tim_read_event(i32 timeout_ms) {
tim_update_screen_size(); // workaround, see WINDOW_BUFFER_SIZE_EVENT
e->type = TimEvent_Mouse;
e->key = TimKey_MouseButtonLeft;
e->x = rec.Event.MouseEvent.dwMousePosition.X - tim.window.Left;
e->y = rec.Event.MouseEvent.dwMousePosition.Y - tim.window.Top;
e->x = rec.Event.MouseEvent.dwMousePosition.X - tim->window.Left;
e->y = rec.Event.MouseEvent.dwMousePosition.Y - tim->window.Top;
return;
}