work on mugab edits

master
Allen Webster 2015-11-02 19:43:36 -05:00
parent a89b46fda7
commit 60dab2731c
11 changed files with 797 additions and 382 deletions

View File

@ -236,7 +236,7 @@ extern "C" GET_BINDING_DATA(get_bindings){
bind(context, codes->down, MDFR_ALT, cmdid_stop_rewind_fastforward);
bind(context, 'h', MDFR_CTRL, cmdid_history_backward);
bind(context, 'H', MDFR_CTRL, cmdid_history_forward);
bind(context, 'd', MDFR_CTRL, cmdid_delete_chunk);
bind(context, 'd', MDFR_CTRL, cmdid_delete_range);
bind(context, 'l', MDFR_CTRL, cmdid_toggle_line_wrap);
bind(context, 'L', MDFR_CTRL, cmdid_toggle_endline_mode);
bind(context, 'u', MDFR_CTRL, cmdid_to_uppercase);

View File

@ -69,7 +69,7 @@ enum Command_ID{
cmdid_cut,
cmdid_paste,
cmdid_paste_next,
cmdid_delete_chunk,
cmdid_delete_range,
cmdid_timeline_scrub,
cmdid_undo,
cmdid_redo,

159
4ed.cpp
View File

@ -135,6 +135,8 @@ globalvar Application_Links app_links;
#define REQ_VIEW(n) View *n = command->view; if (!n) return
#define REQ_FILE_VIEW(n) File_View *n = view_to_file_view(command->view); if (!n) return
#define REQ_OPEN_FILE_VIEW(n) File_View *n = view_to_file_view(command->view); if (!n || n->locked) return
#define REQ_FILE_HISTORY(n,v) Editing_File *n = (v)->file; if (!n || !buffer_good(&n->buffer) || n->is_dummy || !n->undo.undo.edits) return
#define REQ_FILE(n,v) Editing_File *n = (v)->file; if (!n || !buffer_good(&n->buffer) || n->is_dummy) return
#define REQ_COLOR_VIEW(n) Color_View *n = view_to_color_view(command->view); if (!n) return
#define REQ_DBG_VIEW(n) Debug_View *n = view_to_debug_view(command->view); if (!n) return
@ -206,7 +208,7 @@ COMMAND_DECL(null){
COMMAND_DECL(write_character){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_OPEN_FILE_VIEW(view);
REQ_FILE(file, view);
USE_LAYOUT(layout);
USE_MEM(mem);
@ -223,7 +225,7 @@ COMMAND_DECL(write_character){
view_replace_range(mem, view, layout, pos, pos, (u8*)string.str, string.size, next_cursor_pos);
view_cursor_move(view, next_cursor_pos);
if (view->mark >= pos) view->mark += string.size;
view->file->cursor_pos = view->cursor.pos;
file->cursor_pos = view->cursor.pos;
}
COMMAND_DECL(seek_whitespace_right){
@ -233,7 +235,6 @@ COMMAND_DECL(seek_whitespace_right){
REQ_FILE(file, view);
i32 pos = buffer_seek_whitespace_right(&file->buffer, view->cursor.pos);
view_cursor_move(view, pos);
#endif
}
@ -245,7 +246,6 @@ COMMAND_DECL(seek_whitespace_left){
REQ_FILE(file, view);
i32 pos = buffer_seek_whitespace_left(&file->buffer, view->cursor.pos);
view_cursor_move(view, pos);
#endif
}
@ -356,7 +356,7 @@ COMMAND_DECL(seek_white_or_token_left){
}
COMMAND_DECL(seek_alphanumeric_right){
#if BUFFER_EXPERIMENT_SCALPEL <= 1
#if BUFFER_EXPERIMENT_SCALPEL <= 2
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -367,7 +367,7 @@ COMMAND_DECL(seek_alphanumeric_right){
}
COMMAND_DECL(seek_alphanumeric_left){
#if BUFFER_EXPERIMENT_SCALPEL <= 1
#if BUFFER_EXPERIMENT_SCALPEL <= 2
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -378,7 +378,7 @@ COMMAND_DECL(seek_alphanumeric_left){
}
COMMAND_DECL(seek_alphanumeric_or_camel_right){
#if BUFFER_EXPERIMENT_SCALPEL <= 1
#if BUFFER_EXPERIMENT_SCALPEL <= 2
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -390,7 +390,7 @@ COMMAND_DECL(seek_alphanumeric_or_camel_right){
}
COMMAND_DECL(seek_alphanumeric_or_camel_left){
#if BUFFER_EXPERIMENT_SCALPEL <= 1
#if BUFFER_EXPERIMENT_SCALPEL <= 2
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -404,7 +404,7 @@ COMMAND_DECL(seek_alphanumeric_or_camel_left){
COMMAND_DECL(search){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
REQ_FILE(fixed, view);
USE_VARS(vars);
view_set_widget(view, FWIDG_SEARCH);
@ -416,7 +416,7 @@ COMMAND_DECL(search){
COMMAND_DECL(rsearch){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
REQ_FILE(fixed, view);
USE_VARS(vars);
view_set_widget(view, FWIDG_SEARCH);
@ -428,7 +428,7 @@ COMMAND_DECL(rsearch){
COMMAND_DECL(goto_line){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
REQ_FILE(fixed, view);
USE_VARS(vars);
view_set_widget(view, FWIDG_GOTO_LINE);
@ -460,7 +460,7 @@ COMMAND_DECL(copy){
COMMAND_DECL(cut){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_OPEN_FILE_VIEW(view);
REQ_FILE(file, view);
USE_WORKING_SET(working_set);
USE_LAYOUT(layout);
@ -481,7 +481,7 @@ COMMAND_DECL(cut){
COMMAND_DECL(paste){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_OPEN_FILE_VIEW(view);
REQ_FILE(file, view);
USE_WORKING_SET(working_set);
USE_LAYOUT(layout);
@ -516,7 +516,7 @@ COMMAND_DECL(paste){
COMMAND_DECL(paste_next){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_OPEN_FILE_VIEW(view);
REQ_FILE(file, view);
USE_WORKING_SET(working_set);
USE_LAYOUT(layout);
@ -552,9 +552,9 @@ COMMAND_DECL(paste_next){
}
}
COMMAND_DECL(delete_chunk){
COMMAND_DECL(delete_range){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_OPEN_FILE_VIEW(view);
REQ_FILE(file, view);
USE_LAYOUT(layout);
USE_MEM(mem);
@ -572,7 +572,7 @@ COMMAND_DECL(delete_chunk){
COMMAND_DECL(timeline_scrub){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
REQ_FILE_HISTORY(file, view);
view_set_widget(view, FWIDG_TIMELINES);
view->widget.timeline.undo_line = 1;
@ -582,6 +582,7 @@ COMMAND_DECL(timeline_scrub){
COMMAND_DECL(undo){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE_HISTORY(file, view);
USE_LAYOUT(layout);
USE_MEM(mem);
@ -591,6 +592,7 @@ COMMAND_DECL(undo){
COMMAND_DECL(redo){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE_HISTORY(file, view);
USE_LAYOUT(layout);
USE_MEM(mem);
@ -600,6 +602,7 @@ COMMAND_DECL(redo){
COMMAND_DECL(increase_rewind_speed){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE_HISTORY(file, view);
i32 rewind_speed = ROUND32(view->rewind_speed * 4.f);
if (rewind_speed > 1) rewind_speed >>= 1;
@ -613,6 +616,7 @@ COMMAND_DECL(increase_rewind_speed){
COMMAND_DECL(increase_fastforward_speed){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE_HISTORY(file, view);
i32 neg_rewind_speed = -ROUND32(view->rewind_speed * 4.f);
if (neg_rewind_speed > 1) neg_rewind_speed >>= 1;
@ -626,6 +630,7 @@ COMMAND_DECL(increase_fastforward_speed){
COMMAND_DECL(stop_rewind_fastforward){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE_HISTORY(file, view);
view->rewind_speed = 0;
}
@ -633,7 +638,7 @@ COMMAND_DECL(stop_rewind_fastforward){
COMMAND_DECL(history_backward){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
REQ_FILE_HISTORY(file, view);
USE_LAYOUT(layout);
USE_MEM(mem);
@ -643,7 +648,7 @@ COMMAND_DECL(history_backward){
COMMAND_DECL(history_forward){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
REQ_FILE_HISTORY(file, view);
USE_LAYOUT(layout);
USE_MEM(mem);
@ -698,7 +703,7 @@ app_open_file(App_Vars *vars, General_Memory *general, Panel *panel,
view_replace_major(new_view, panel, live_set);
File_View *file_view = file_view_init(new_view, &vars->delay, &vars->layout);
File_View *file_view = file_view_init(new_view, &vars->layout);
result = file_view;
View *old_view = command_data->view;
@ -830,7 +835,7 @@ COMMAND_DECL(save){
String *file_path = &file->source_path;
if (file_path->size > 0){
file_save(&mem->part, file, (u8*)file_path->str);
file_save(&mem->part, file, file_path->str);
}
}
@ -1219,7 +1224,6 @@ COMMAND_DECL(move_left){
i32 pos = view->cursor.pos;
if (pos > 0) --pos;
view_cursor_move(view, pos);
}
@ -1231,13 +1235,12 @@ COMMAND_DECL(move_right){
i32 size = buffer_size(&file->buffer);
i32 pos = view->cursor.pos;
if (pos < size) ++pos;
view_cursor_move(view, pos);
}
COMMAND_DECL(delete){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_OPEN_FILE_VIEW(view);
REQ_FILE(file, view);
USE_LAYOUT(layout);
USE_MEM(mem);
@ -1261,7 +1264,7 @@ COMMAND_DECL(delete){
COMMAND_DECL(backspace){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_OPEN_FILE_VIEW(view);
REQ_FILE(file, view);
USE_LAYOUT(layout);
USE_MEM(mem);
@ -1292,7 +1295,7 @@ COMMAND_DECL(move_up){
real32 px = view->preferred_x;
if (cy >= 0){
view->cursor = view_compute_cursor_from_xy(view, px, cy);
view->file->cursor_pos = view->cursor.pos;
file->cursor_pos = view->cursor.pos;
}
}
@ -1304,7 +1307,7 @@ COMMAND_DECL(move_down){
real32 cy = view_get_cursor_y(view)+view->style->font->height;
real32 px = view->preferred_x;
view->cursor = view_compute_cursor_from_xy(view, px, cy);
view->file->cursor_pos = view->cursor.pos;
file->cursor_pos = view->cursor.pos;
}
COMMAND_DECL(seek_end_of_line){
@ -1539,27 +1542,47 @@ COMMAND_DECL(build){
USE_LIVE_SET(live_set);
USE_PANEL(panel);
char *buffer_name = "*cli process*";
char *path = "..\\misc";
char *script = "test";
if (vars->cli_processes.count < vars->cli_processes.max){
Get_File_Result file = working_set_get_available_file(working_set);
if (file.file){
file_create_empty(&mem->general, file.file, (u8*)"*cli process*", style->font);
table_add(&working_set->table, file.file->source_path, file.index);
Editing_File *file = working_set_contains(working_set, make_string_slowly(buffer_name));
i32 index;
if (!file){
Get_File_Result get_file = working_set_get_available_file(working_set);
file = get_file.file;
index = get_file.index;
}
else{
i32 proc_count = vars->cli_processes.count;
for (i32 i = 0; i < proc_count; ++i){
if (vars->cli_processes.procs[i].out_file == file){
vars->cli_processes.procs[i].out_file = 0;
}
}
index = (int)(file - vars->working_set.files);
}
if (file){
file_create_super_locked(&mem->general, file, (u8*)buffer_name, style->font);
table_add(&working_set->table, file->live_name, index);
View *new_view = live_set_alloc_view(live_set, mem);
view_replace_major(new_view, panel, live_set);
File_View *file_view = file_view_init(new_view, &vars->delay, &vars->layout);
view_set_file(file_view, file.file, style,
File_View *file_view = file_view_init(new_view, &vars->layout);
view_set_file(file_view, file, style,
vars->hooks[hook_open_file], command, app_links);
file.file->tokens_exist = 0;
new_view->map = app_get_map(vars, file.file->base_map_id);
new_view->map = app_get_map(vars, file->base_map_id);
i32 i = vars->cli_processes.count++;
CLI_Process *proc = vars->cli_processes.procs + i;
if (!system_cli_call("..\\misc", "build_all_test", &proc->cli)){
if (!system_cli_call(path, script, &proc->cli)){
--vars->cli_processes.count;
}
proc->out_file = file.file;
proc->out_file = file;
}
else{
// TODO(allen): feedback message - no available file
@ -1608,25 +1631,6 @@ extern "C"{
if (function) function(cmd, binding);
update_command_data(cmd->vars, cmd);
#if 0
App_Vars *vars = cmd->vars;
Command_Data command_data;
command_data.vars = vars;
command_data.mem = &vars->mem;
command_data.working_set = &vars->working_set;
command_data.layout = &vars->layout;
command_data.panel = command_data.layout->panels + command_data.layout->active_panel;
command_data.view = command_data.panel->view;
command_data.live_set = &vars->live_set;
command_data.style = &vars->style;
command_data.delay = &vars->delay;
command_data.screen_width = cmd->screen_width;
command_data.screen_height = cmd->screen_height;
command_data.key = cmd->key;
command_data.part = cmd->part;
*cmd = command_data;
#endif
}
PUSH_PARAMETER_SIG(external_push_parameter){
@ -1755,7 +1759,7 @@ setup_file_commands(Command_Map *commands, Partition *part, Key_Codes *codes, Co
map_add(commands, codes->down, MDFR_ALT, command_stop_rewind_fastforward);
map_add(commands, 'h', MDFR_CTRL, command_history_backward);
map_add(commands, 'H', MDFR_CTRL, command_history_forward);
map_add(commands, 'd', MDFR_CTRL, command_delete_chunk);
map_add(commands, 'd', MDFR_CTRL, command_delete_range);
map_add(commands, 'l', MDFR_CTRL, command_toggle_line_wrap);
map_add(commands, '?', MDFR_CTRL, command_toggle_show_whitespace);
map_add(commands, '|', MDFR_CTRL, command_toggle_tokens);
@ -1830,7 +1834,7 @@ setup_command_table(){
SET(cut);
SET(paste);
SET(paste_next);
SET(delete_chunk);
SET(delete_range);
SET(timeline_scrub);
SET(undo);
SET(redo);
@ -1998,7 +2002,6 @@ app_hardcode_styles(App_Vars *vars){
style->main.paste_color = 0xFFDDEE00;
style->main.undo_color = 0xFF00DDEE;
style->main.next_undo_color = 0xFF006E77;
style->main.highlight_junk_color = 0xff3a0000;
style->main.highlight_white_color = 0xff003a3a;
@ -2086,7 +2089,6 @@ app_hardcode_styles(App_Vars *vars){
style->main.paste_color = 0xFFDDEE00;
style->main.undo_color = 0xFF00DDEE;
style->main.next_undo_color = 0xFF006E77;
style->main.highlight_junk_color = 0xff3a0000;
style->main.highlight_white_color = 0xFF151F2A;
@ -2127,7 +2129,6 @@ app_hardcode_styles(App_Vars *vars){
style->main.paste_color = 0xFF900090;
style->main.undo_color = 0xFF606090;
style->main.next_undo_color = 0xFF404070;
style->main.highlight_junk_color = 0xff3a0000;
style->main.highlight_white_color = 0xff003a3a;
@ -2168,7 +2169,6 @@ app_hardcode_styles(App_Vars *vars){
style->main.paste_color = 0xFF00B8B8;
style->main.undo_color = 0xFFB800B8;
style->main.next_undo_color = 0xFF5C005C;
style->main.highlight_junk_color = 0xFFFF7878;
style->main.highlight_white_color = 0xFFBCBCBC;
@ -2592,7 +2592,7 @@ app_step(Thread_Context *thread, Key_Codes *codes,
}
// NOTE(allen): update child processes
{
if (time_step){
Temp_Memory temp = begin_temp_memory(&vars->mem.part);
u32 max = Kbytes(32);
char *dest = push_array(&vars->mem.part, char, max);
@ -2610,7 +2610,7 @@ app_step(Thread_Context *thread, Key_Codes *codes,
amount = eol_in_place_convert_in(dest, amount);
Edit_Spec spec = {};
spec.step.type = ED_NORMAL;
spec.step.edit.start = buffer_size(&out_file->buffer);
spec.step.edit.start = buffer_size(&out_file->buffer);
spec.step.edit.end = spec.step.edit.start;
spec.step.edit.len = amount;
spec.step.pre_pos = new_cursor;
@ -2622,11 +2622,22 @@ app_step(Thread_Context *thread, Key_Codes *codes,
new_cursor = spec.step.post_pos;
}
}
if (system_cli_end_update(&proc->cli)){
*proc = vars->cli_processes.procs[--count];
--i;
}
Panel *panel = vars->layout.panels;
i32 panel_count = vars->layout.panel_count;
for (i32 i = 0; i < panel_count; ++i, ++panel){
View *view = panel->view;
if (view && view->is_minor) view = view->major;
File_View *fview = view_to_file_view(view);
if (fview){
view_cursor_move(fview, new_cursor);
}
}
}
vars->cli_processes.count = count;
@ -3043,7 +3054,7 @@ app_step(Thread_Context *thread, Key_Codes *codes,
if (fview){
Editing_File *file = fview->file;
if (file && !file->is_dummy){
file_save_and_set_names(&vars->mem.part, file, (u8*)string->str);
file_save_and_set_names(&vars->mem.part, file, string->str);
}
}
}break;
@ -3051,8 +3062,8 @@ app_step(Thread_Context *thread, Key_Codes *codes,
case DACT_SAVE:
{
Editing_File *file = working_set_lookup_file(working_set, *string);
if (file && !file->is_dummy){
file_save(&vars->mem.part, file, (u8*)file->source_path.str);
if (!file->is_dummy){
file_save(&vars->mem.part, file, file->source_path.str);
}
}break;
@ -3065,7 +3076,7 @@ app_step(Thread_Context *thread, Key_Codes *codes,
View *new_view = live_set_alloc_view(live_set, mem);
view_replace_major(new_view, panel, live_set);
File_View *file_view = file_view_init(new_view, &vars->delay, &vars->layout);
File_View *file_view = file_view_init(new_view, &vars->layout);
command_data.view = (View*)file_view;
view_set_file(file_view, file.file, style,
vars->hooks[hook_open_file], &command_data, app_links);
@ -3082,10 +3093,12 @@ app_step(Thread_Context *thread, Key_Codes *codes,
View *new_view = live_set_alloc_view(live_set, mem);
view_replace_major(new_view, panel, live_set);
File_View *file_view = file_view_init(new_view, &vars->delay, &vars->layout);
File_View *file_view = file_view_init(new_view, &vars->layout);
command_data.view = (View*)file_view;
view_set_file(file_view, file, style,
vars->hooks[hook_open_file], &command_data, app_links);
new_view->map = app_get_map(vars, file->base_map_id);
}
}break;
@ -3095,7 +3108,7 @@ app_step(Thread_Context *thread, Key_Codes *codes,
Editing_File *file = working_set_lookup_file(working_set, *string);
if (file){
table_remove(&working_set->table, file->source_path);
kill_buffer(general, file, live_set, &vars->layout);
kill_file(general, file, live_set, &vars->layout);
}
}break;
@ -3108,7 +3121,7 @@ app_step(Thread_Context *thread, Key_Codes *codes,
case SYNC_GOOD:
{
table_remove(&working_set->table, file->source_path);
kill_buffer(general, file, live_set, &vars->layout);
kill_file(general, file, live_set, &vars->layout);
view_remove_minor(panel, live_set);
}break;
@ -3186,7 +3199,7 @@ app_step(Thread_Context *thread, Key_Codes *codes,
Editing_File *file = vars->working_set.files;
for (i32 i = vars->working_set.file_index_count; i > 0; --i, ++file){
if (buffer_good(&file->buffer) && !file->is_dummy){
file_measure_widths(&vars->mem.general, file, vars->style.font);
file_measure_widths(&vars->mem.general, &file->buffer, vars->style.font);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -143,7 +143,10 @@ struct Style_Main_Data{
u32 highlight_white_color;
u32 paste_color;
u32 undo_color;
u32 next_undo_color;
u32 result_link_color;
u32 related_link_color;
u32 error_link_color;
u32 warning_link_color;
Interactive_Style file_info_style;
};
@ -186,6 +189,10 @@ enum Style_Color_Tag{
STAG_PASTE_COLOR,
STAG_UNDO_COLOR,
STAG_NEXT_UNDO_COLOR,
STAG_RESULT_LINK_COLOR,
STAG_RELATED_LINK_COLOR,
STAG_ERROR_LINK_COLOR,
STAG_WARNING_LINK_COLOR,
// never below this
STAG_COUNT
};
@ -350,7 +357,6 @@ style_form_convert(Style_File_Format_v4 *o, Style_File_Format_v3 *i){
o->main.highlight_white_color = i->main.highlight_white_color;
o->main.paste_color = i->main.paste_color;
o->main.undo_color = i->main.paste_color ^ 0x00FFFFFF;
o->main.next_undo_color = i->main.paste_color ^ 0x00FFFFFF;
o->main.file_info_style = i->main.file_info_style;
o->main.file_info_style.bar_active_color = i->main.file_info_style.bar_color;
}
@ -395,7 +401,11 @@ style_index_by_tag(Style *s, u32 tag){
case STAG_PASTE_COLOR: result = &s->main.paste_color; break;
case STAG_UNDO_COLOR: result = &s->main.undo_color; break;
case STAG_NEXT_UNDO_COLOR: result = &s->main.next_undo_color; break;
case STAG_RESULT_LINK_COLOR: result = &s->main.result_link_color; break;
case STAG_RELATED_LINK_COLOR: result = &s->main.related_link_color; break;
case STAG_ERROR_LINK_COLOR: result = &s->main.error_link_color; break;
case STAG_WARNING_LINK_COLOR: result = &s->main.warning_link_color; break;
}
return result;
}

View File

@ -131,7 +131,7 @@ buffer_seek_whitespace_up(Buffer_Type *buffer, int pos){
int no_hard;
size = buffer_size(buffer);
loop = buffer_backify_loop(buffer, pos, 1);
loop = buffer_backify_loop(buffer, pos-1, 1);
for (;buffer_backify_good(&loop);
buffer_backify_next(&loop)){
@ -245,18 +245,22 @@ buffer_seek_alphanumeric_right(Buffer_Type *buffer, int pos){
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos < end && is_alphanumeric_true(data[pos]); ++pos);
if (!is_alphanumeric_true(data[pos])) break;
for (; pos < end; ++pos){
if (!is_alphanumeric_true(data[pos])) goto buffer_seek_alphanumeric_right_mid;
}
}
buffer_seek_alphanumeric_right_mid:
for (;buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos < end && !is_alphanumeric_true(data[pos]); ++pos);
if (is_alphanumeric_true(data[pos])) break;
for (; pos < end; ++pos){
if (is_alphanumeric_true(data[pos])) goto buffer_seek_alphanumeric_right_end;
}
}
buffer_seek_alphanumeric_right_end:
return(pos);
}
@ -276,16 +280,19 @@ buffer_seek_alphanumeric_left(Buffer_Type *buffer, int pos){
buffer_backify_next(&loop)){
end = loop.absolute_pos;
data = loop.data - end;
for (; pos >= end && !is_alphanumeric_true(data[pos]); --pos);
if (is_alphanumeric_true(data[pos])) break;
for (; pos >= end; --pos){
if (is_alphanumeric_true(data[pos])) goto buffer_seek_alphanumeric_left_mid;
}
}
buffer_seek_alphanumeric_left_mid:
for (;buffer_backify_good(&loop);
buffer_backify_next(&loop)){
end = loop.absolute_pos;
data = loop.data - end;
for (; pos >= end && is_alphanumeric_true(data[pos]); --pos);
if (!is_alphanumeric_true(data[pos])) break;
for (; pos >= end; --pos){
if (!is_alphanumeric_true(data[pos])) goto buffer_seek_alphanumeric_left_end;
}
}
++pos;
@ -294,6 +301,7 @@ buffer_seek_alphanumeric_left(Buffer_Type *buffer, int pos){
pos = 0;
}
buffer_seek_alphanumeric_left_end:
return(pos);
}
@ -1069,6 +1077,9 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
switch (ch){
case '\n':
write_render_item_inline(item, i, ' ', x, y, advance_data, stride, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
@ -1078,11 +1089,17 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
case 0:
ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, stride, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
x += ch_width;
ch_width = write_render_item_inline(item, i, '0', x, y, advance_data, stride, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
x += ch_width;
@ -1090,11 +1107,17 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
case '\r':
ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, stride, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
x += ch_width;
ch_width = write_render_item_inline(item, i, 'r', x, y, advance_data, stride, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
x += ch_width;
@ -1102,10 +1125,16 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
case '\t':
ch_width_sub = write_render_item_inline(item, i, '\\', x, y, advance_data, stride, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
write_render_item_inline(item, i, 't', x + ch_width_sub, y, advance_data, stride, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
x += ch_width;
@ -1113,9 +1142,13 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
default:
write_render_item(item, i, ch, x, y, ch_width, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
x += ch_width;
break;
}
if (y > height + shift_y) goto buffer_get_render_data_end;
@ -1127,6 +1160,9 @@ buffer_get_render_data_end:
ch = 0;
ch_width = measure_character(advance_data, stride, ' ');
write_render_item(item, size, ch, x, y, ch_width, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = -1;
#endif
++item_i;
++item;
x += ch_width;

View File

@ -110,25 +110,6 @@ buffer_end_init(Gap_Buffer_Init *init){
return(result);
}
internal_4tech void*
buffer_edit_provide_memory(Gap_Buffer *buffer, void *new_data, int new_max){
void *result;
int new_gap_size;
assert_4tech(new_max >= buffer_size(buffer));
result = buffer->data;
new_gap_size = new_max - buffer_size(buffer);
memcpy_4tech(new_data, buffer->data, buffer->size1);
memcpy_4tech((char*)new_data + buffer->size1 + new_gap_size, buffer->data + buffer->size1 + buffer->gap_size, buffer->size2);
buffer->data = (char*)new_data;
buffer->gap_size = new_gap_size;
buffer->max = new_max;
return(result);
}
typedef struct{
Gap_Buffer *buffer;
char *data, *base;
@ -334,5 +315,24 @@ buffer_batch_edit_step(Buffer_Batch_State *state, Gap_Buffer *buffer, Buffer_Edi
return(result);
}
internal_4tech void*
buffer_edit_provide_memory(Gap_Buffer *buffer, void *new_data, int new_max){
void *result;
int new_gap_size;
assert_4tech(new_max >= buffer_size(buffer));
result = buffer->data;
new_gap_size = new_max - buffer_size(buffer);
memcpy_4tech(new_data, buffer->data, buffer->size1);
memcpy_4tech((char*)new_data + buffer->size1 + new_gap_size, buffer->data + buffer->size1 + buffer->gap_size, buffer->size2);
buffer->data = (char*)new_data;
buffer->gap_size = new_gap_size;
buffer->max = new_max;
return(result);
}
// BOTTOM

View File

@ -92,20 +92,6 @@ buffer_end_init(Buffer_Init *init){
return(result);
}
internal_4tech void*
buffer_edit_provide_memory(Buffer *buffer, void *new_data, int new_max){
void *result;
assert_4tech(new_max >= buffer->size);
result = buffer->data;
memcpy_4tech(new_data, buffer->data, buffer->size);
buffer->data = (char*)new_data;
buffer->max = new_max;
return(result);
}
typedef struct{
Buffer *buffer;
char *data, *end;
@ -226,5 +212,19 @@ buffer_batch_edit_step(Buffer_Batch_State *state, Buffer *buffer, Buffer_Edit *s
return(result);
}
internal_4tech void*
buffer_edit_provide_memory(Buffer *buffer, void *new_data, int new_max){
void *result;
assert_4tech(new_max >= buffer->size);
result = buffer->data;
memcpy_4tech(new_data, buffer->data, buffer->size);
buffer->data = (char*)new_data;
buffer->max = new_max;
return(result);
}
// BOTTOM

View File

@ -28,6 +28,7 @@ typedef struct{
typedef struct{
Fixed_Width_Gap_Buffer *gaps;
int chunk_count;
int chunk_alloced;
int chunk_max;
int size;
@ -37,6 +38,9 @@ typedef struct{
int widths_count;
int line_max;
int widths_max;
int grow_gaps;
int edit_stage;
} Multi_Gap_Buffer;
inline_4tech int
@ -59,9 +63,9 @@ typedef struct{
int size;
int chunk_i;
int chunk_count;
int chunk_alloc;
} Multi_Gap_Buffer_Init;
internal_4tech Multi_Gap_Buffer_Init
buffer_begin_init(Multi_Gap_Buffer *buffer, char *data, int size){
Multi_Gap_Buffer_Init init;
@ -69,7 +73,9 @@ buffer_begin_init(Multi_Gap_Buffer *buffer, char *data, int size){
init.data = data;
init.size = size;
init.chunk_i = 0;
init.chunk_count = div_ceil_4tech(size, fixed_width_buffer_half_size);
init.chunk_alloc = div_ceil_4tech(size, fixed_width_buffer_half_size);
init.chunk_count = init.chunk_alloc;
if (init.chunk_alloc < 4) init.chunk_alloc = 4;
return(init);
}
@ -77,7 +83,7 @@ internal_4tech int
buffer_init_need_more(Multi_Gap_Buffer_Init *init){
int result;
result = 1;
if (init->buffer->gaps && init->chunk_i == init->chunk_count)
if (init->buffer->gaps && init->chunk_i == init->chunk_alloc)
result = 0;
return(result);
}
@ -88,7 +94,7 @@ buffer_init_page_size(Multi_Gap_Buffer_Init *init){
int result;
buffer = init->buffer;
if (buffer->gaps) result = fixed_width_buffer_size;
else result = init->chunk_count * 2 * sizeof(*buffer->gaps);
else result = init->chunk_alloc * 2 * sizeof(*buffer->gaps);
return(result);
}
@ -123,12 +129,14 @@ buffer_end_init(Multi_Gap_Buffer_Init *init){
if (buffer->gaps){
if (buffer->chunk_max >= div_ceil_4tech(init->size, fixed_width_buffer_half_size)){
buffer->chunk_count = init->chunk_count;
if (buffer->chunk_count == 0) buffer->chunk_count = 1;
buffer->chunk_alloced = init->chunk_alloc;
result = 1;
data = init->data;
total_size = init->size;
gap = buffer->gaps;
count = init->chunk_count;
count = buffer->chunk_count;
size = fixed_width_buffer_half_size;
pos = 0;
start_pos = 0;
@ -151,7 +159,7 @@ buffer_end_init(Multi_Gap_Buffer_Init *init){
gap->size2 = size2;
gap->gap_size = fixed_width_buffer_size - size1 - size2;
memmove_4tech(gap->data + size1 + gap->gap_size, gap->data + size1, size2);
gap->start_pos = start_pos;
start_pos += size1 + size2;
}
@ -171,25 +179,24 @@ internal_4tech int
buffer_find_chunk(Multi_Gap_Buffer *buffer, int pos){
Fixed_Width_Gap_Buffer *gaps;
int start, end, m, this_pos;
if (pos == buffer_size(buffer)){
m = buffer->chunk_count;
}
else{
gaps = buffer->gaps;
start = 0;
end = buffer->chunk_count;
for(;;){
m = (start + end) / 2;
this_pos = gaps[m].start_pos;
if (this_pos < pos) start = m;
else if (this_pos > pos) end = m;
else break;
if (start+1 == end){
m = start; break;
}
assert_4tech(start < end);
gaps = buffer->gaps;
start = 0;
end = buffer->chunk_count;
for(;;){
m = (start + end) / 2;
this_pos = gaps[m].start_pos;
if (this_pos < pos) start = m;
else if (this_pos > pos) end = m;
else{
--m;
if (m < 0) m = 0;
break;
}
if (start+1 == end){
m = start; break;
}
assert_4tech(start < end);
}
return(m);
@ -222,7 +229,7 @@ buffer_stringify_loop(Multi_Gap_Buffer *buffer, int start, int end){
gap = result.gaps + result.chunk_end;
end -= gap->start_pos;
if (end < gap->size1) result.end = end;
if (end <= gap->size1) result.end = end;
else result.end = end + gap->gap_size;
gap = result.gaps + result.chunk_i;
@ -272,6 +279,10 @@ buffer_stringify_next(Multi_Gap_Buffer_Stringify_Loop *loop){
loop->pos = 0;
loop->absolute_pos = gap->start_pos;
temp_end = gap->size1;
if (gap->size1 == 0){
loop->pos = gap->gap_size;
temp_end = fixed_width_buffer_size;
}
}
if (loop->chunk_i == loop->chunk_end && temp_end > loop->end) temp_end = loop->end;
loop->size = temp_end - loop->pos;
@ -301,7 +312,7 @@ buffer_backify_loop(Multi_Gap_Buffer *buffer, int start, int end){
result.buffer = buffer;
result.gaps = buffer->gaps;
result.chunk_i = buffer_find_chunk(buffer, start);
result.chunk_i = buffer_find_chunk(buffer, start-1);
result.chunk_end = buffer_find_chunk(buffer, end);
gap = result.gaps + result.chunk_end;
@ -369,12 +380,20 @@ buffer_backify_next(Multi_Gap_Buffer_Backify_Loop *loop){
internal_4tech int
buffer_replace_range(Multi_Gap_Buffer *buffer, int start, int end, char *str, int len, int *shift_amount_out, int *request_amount){
Fixed_Width_Gap_Buffer *gaps, *gap;
Fixed_Width_Gap_Buffer *gaps, *gap, *dgap;
char *data;
int move_size;
int gap_start, gap_end;
int result;
int size;
int local_end;
int shift_amount;
int required_empty_buffers;
int supplanted_gaps;
int dpos;
int head_size, middle_size, tail_size;
int mem_pos, local_start_pos;
debug_4tech(int osize);
size = buffer_size(buffer);
assert_4tech(0 <= start);
@ -386,35 +405,58 @@ buffer_replace_range(Multi_Gap_Buffer *buffer, int start, int end, char *str, in
gaps = buffer->gaps;
gap_start = buffer_find_chunk(buffer, start);
gap_end = buffer_find_chunk(buffer, end);
gap = gaps + gap_start;
if (gap_start < gap_end){
memmove_4tech(gap + 1, gaps + gap_end, sizeof(*gaps)*(buffer->chunk_count - gap_end));
buffer->chunk_count -= (gap_end - gap_start + 1);
++gap;
local_end = end - gap->start_pos;
if (gap->size1 >= local_end){
gap->size2 -= (local_end - gap->size1);
gap->size1 = 0;
if (buffer->edit_stage == 0){
buffer->size += *shift_amount_out;
for (gap = gaps + gap_end + 1;
gap < gaps + buffer->chunk_count;
++gap){
gap->start_pos += *shift_amount_out;
}
else{
memmove_4tech(gap->data, gap->data + local_end, gap->size1 - local_end);
gap->size1 -= local_end;
}
--gap;
buffer->edit_stage = 1;
}
gap = gaps + gap_start;
if (buffer->edit_stage == 1){
if (gap_start < gap_end && gap_start+1 < buffer->chunk_count){
supplanted_gaps = gap_end - gap_start + 1;
if (buffer->chunk_max - buffer->chunk_alloced >= supplanted_gaps){
++gap;
memcpy_4tech(gaps + buffer->chunk_alloced, gap, sizeof(*gaps)*supplanted_gaps);
memmove_4tech(gap, gaps + gap_end, sizeof(*gaps)*(buffer->chunk_alloced - gap_start - 1));
buffer->chunk_count -= (gap_end - gap_start + 1);
local_end = end - gap->start_pos;
if (gap->size1 >= local_end){
gap->size2 -= (local_end - gap->size1);
gap->size1 = 0;
}
else{
memmove_4tech(gap->data, gap->data + local_end, gap->size1 - local_end);
gap->size1 -= local_end;
}
--gap;
}
else{
buffer->grow_gaps = 1;
*request_amount = round_up_4tech(sizeof(*gaps)*(supplanted_gaps+buffer->chunk_max*2), 4<<10);
result = 1;
goto mugab_replace_range_end;
}
}
buffer->edit_stage = 2;
}
if (end > gap->size1 + gap->size2) end = gap->size1 + gap->size2;
shift_amount = (len - (end - start));
start -= gap->start_pos;
end -= gap->start_pos;
if (end > gap->size1 + gap->size2) end = gap->size1 + gap->size2;
if (shift_amount + gap->size1 + gap->size2 <= fixed_width_buffer_size){
start -= gap->start_pos;
end -= gap->start_pos;
data = gap->data;
debug_4tech(osize = gap->size1 + gap->size2);
if (end < gap->size1){
move_size = gap->size1 - end;
memmove_4tech(data + gap->size1 + gap->gap_size - move_size, data + end, move_size);
@ -429,20 +471,206 @@ buffer_replace_range(Multi_Gap_Buffer *buffer, int start, int end, char *str, in
}
memcpy_4tech(data + start, str, len);
gap->size2 = size - end;
gap->size2 = fixed_width_buffer_size - (end + gap->gap_size);
gap->size1 = start + len;
gap->gap_size -= shift_amount;
assert_4tech(gap->size1 + gap->size2 == size + shift_amount);
assert_4tech(gap->size1 + gap->gap_size + gap->size2 == gap->max);
assert_4tech(gap->size1 + gap->size2 == osize + shift_amount);
assert_4tech(gap->size1 + gap->gap_size + gap->size2 == fixed_width_buffer_size);
result = 0;
buffer->edit_stage = 0;
if (gap_start < gap_end){
++gap;
gap->start_pos += shift_amount;
}
}
else{
div_ceil_4tech(shift_amount, fixed_width_buffer_half_size);
result = 1;
required_empty_buffers = div_ceil_4tech(shift_amount, fixed_width_buffer_half_size);
if (buffer->chunk_alloced - buffer->chunk_count >= required_empty_buffers){
if (buffer->chunk_max - buffer->chunk_alloced >= required_empty_buffers){
memcpy_4tech(gaps + buffer->chunk_alloced, gaps + buffer->chunk_count, sizeof(*gaps)*required_empty_buffers);
memmove_4tech(gap + required_empty_buffers + 1, gap + 1, sizeof(*gaps)*(buffer->chunk_count - gap_start - 1));
memcpy_4tech(gap + 1, gaps + buffer->chunk_alloced, sizeof(*gaps)*required_empty_buffers);
data = gap->data;
if (end < gap->size1){
move_size = gap->size1 - end;
memmove_4tech(data + gap->size1 + gap->gap_size - move_size, data + end, move_size);
gap->size1 -= move_size + (end - start);
gap->size2 += move_size;
}
else if (start > gap->size1){
move_size = start - gap->size1;
memmove_4tech(data + gap->size1, data + gap->size1 + gap->gap_size, move_size);
gap->size1 += move_size;
gap->size2 -= move_size + (end - start);
}
else{
if (end > gap->size1){
gap->size2 -= (end - gap->size1);
}
gap->size1 = start;
}
if (gap->size1 > fixed_width_buffer_half_size){
move_size = gap->size1 - fixed_width_buffer_half_size;
memmove_4tech(data + gap->size1 + gap->gap_size - move_size, data + end, move_size);
gap->size1 -= move_size + (end - start);
gap->size2 += move_size;
}
else if (gap->size2 > fixed_width_buffer_half_size){
move_size = gap->size2 - fixed_width_buffer_half_size;
memmove_4tech(data + gap->size1, data + gap->size1 + gap->gap_size, move_size);
gap->size1 += move_size;
gap->size2 -= move_size + (end - start);
}
dgap = gap + required_empty_buffers;
dpos = gap->size1 + gap->gap_size;
memcpy_4tech(dgap->data + dpos, data + dpos, gap->size2);
dgap->size2 = gap->size2;
gap->size2 = 0;
middle_size = div_ceil_4tech(len, (required_empty_buffers * 2));
head_size = middle_size;
tail_size = middle_size;
if (head_size + gap->size1 + 256 > fixed_width_buffer_size){
head_size = fixed_width_buffer_size - gap->size1 - 256;
if (head_size < 0) head_size = 0;
}
if (tail_size + dgap->size2 + 256 > fixed_width_buffer_size){
tail_size = fixed_width_buffer_size - dgap->size2 - 256;
if (tail_size < 0) tail_size = 0;
}
if (required_empty_buffers-1 > 0)
middle_size = div_ceil_4tech(len - head_size - tail_size, (required_empty_buffers-1)*2);
else
middle_size = 0;
mem_pos = 0;
if (head_size > len - mem_pos) head_size = len - mem_pos;
gap->size2 = head_size;
gap->gap_size = fixed_width_buffer_size - gap->size1 - gap->size2;
memcpy_4tech(gap->data + fixed_width_buffer_size - head_size, str + mem_pos, head_size);
mem_pos += head_size;
local_start_pos = gap->start_pos + gap->size1 + gap->size2;
++gap;
for (;gap < dgap; ++gap){
gap->start_pos = local_start_pos;
if (middle_size > len - mem_pos) middle_size = len - mem_pos;
gap->size1 = middle_size;
memcpy_4tech(gap->data, str + mem_pos, middle_size);
mem_pos += middle_size;
if (middle_size > len - mem_pos) middle_size = len - mem_pos;
gap->size2 = middle_size;
memcpy_4tech(gap->data + fixed_width_buffer_size - middle_size, str + mem_pos, middle_size);
mem_pos += middle_size;
gap->gap_size = fixed_width_buffer_size - (gap->size1 + gap->size2);
local_start_pos += gap->size1 + gap->size2;
++gap;
}
if (tail_size > len - mem_pos) tail_size = len - mem_pos;
gap->start_pos = local_start_pos;
gap->size1 = tail_size;
gap->gap_size = fixed_width_buffer_size - gap->size1 - gap->size2;
memcpy_4tech(gap->data, str + mem_pos, tail_size);
mem_pos += tail_size;
assert_4tech(mem_pos == len);
buffer->chunk_count += required_empty_buffers;
result = 0;
buffer->edit_stage = 0;
}
else{
buffer->grow_gaps = 1;
*request_amount = round_up_4tech(sizeof(*gaps)*(required_empty_buffers+buffer->chunk_max*2), 4<<10);
result = 1;
goto mugab_replace_range_end;
}
}
else{
if (buffer->chunk_alloced < buffer->chunk_max){
*request_amount = fixed_width_buffer_size;
result = 1;
}
else{
buffer->grow_gaps = 1;
*request_amount = round_up_4tech(sizeof(*gaps)*(1+buffer->chunk_max*2), 4<<10);
result = 1;
}
}
}
mugab_replace_range_end:
return(result);
}
internal_4tech void*
buffer_edit_provide_memory(Multi_Gap_Buffer *buffer, void *new_data, int size){
void *result;
Fixed_Width_Gap_Buffer *gap;
if (buffer->grow_gaps){
assert_4tech(size >= buffer->chunk_max*sizeof(*buffer->gaps));
result = buffer->gaps;
memcpy_4tech(new_data, buffer->gaps, buffer->chunk_alloced*sizeof(*buffer->gaps));
buffer->gaps = (Fixed_Width_Gap_Buffer*)new_data;
buffer->chunk_max = size / sizeof(*buffer->gaps);
buffer->grow_gaps = 0;
}
else{
assert_4tech(buffer->chunk_max > buffer->chunk_alloced);
assert_4tech(size >= fixed_width_buffer_size);
gap = &buffer->gaps[buffer->chunk_alloced++];
*gap = {};
gap->data = (char*)new_data;
result = 0;
}
return(result);
}
internal_4tech int
buffer_mugab_check(Multi_Gap_Buffer *buffer){
Fixed_Width_Gap_Buffer *gap;
int result;
int total_size;
int i, count;
assert_4tech(buffer->chunk_count <= buffer->chunk_alloced);
assert_4tech(buffer->chunk_alloced <= buffer->chunk_max);
count = buffer->chunk_count;
total_size = 0;
gap = buffer->gaps;
for (i = 0; i < count; ++i, ++gap){
assert_4tech(gap->size1 + gap->size2 + gap->gap_size == fixed_width_buffer_size);
assert_4tech(gap->start_pos == total_size);
total_size += gap->size1 + gap->size2;
}
assert_4tech(total_size == buffer->size);
assert_4tech(buffer->edit_stage == 0);
assert_4tech(buffer->grow_gaps == 0);
result = 1;
return(result);
}

View File

@ -157,6 +157,8 @@ typedef struct{
int glyphid;
float x0, y0;
float x1, y1;
int chunk_i;
} Buffer_Render_Item;
inline_4tech void

View File

@ -58,7 +58,7 @@
#define FPS 30
#define FRAME_TIME (1000000 / FPS)
#define BUFFER_EXPERIMENT_SCALPEL 0
#define BUFFER_EXPERIMENT_SCALPEL 1
#include "4ed_meta.h"