boiled out the redraw nonsense, close to event drive now

This commit is contained in:
Allen Webster 2016-05-03 12:15:08 -04:00
parent dd0661e0e5
commit 653cc0bf23
10 changed files with 736 additions and 854 deletions

View File

@ -249,7 +249,6 @@ enum Param_ID{
enum Hook_ID{
hook_start,
hook_open_file,
hook_frame,
hook_new_file,
hook_file_out_of_sync,
// never below this

View File

@ -77,45 +77,6 @@ HOOK_SIG(my_file_settings){
return(0);
}
HOOK_SIG(my_frame){
// NOTE(allen|a4): Please use me sparingly! This get's called roughly once every *33 ms*
// if everything is going well. But if you start doing a lot in here, there's nothing 4codes does
// to stop you from making it a lot slower.
int result = 0;
Theme_Color theme_color_1[] = {
{Stag_Cursor, 0x00FF00},
{Stag_At_Cursor, 0x000000}
};
Theme_Color theme_color_2[2] = {
{Stag_Cursor, 0x000000},
{Stag_At_Cursor, 0xFFFFFF}
};
Theme_Color *theme_color;
++blink_t;
if (blink_t == 20 || blink_t == 40){
if (blink_t == 20){
theme_color = theme_color_2;
}
else{
theme_color = theme_color_1;
blink_t = 0;
}
result = 1;
app->set_theme_colors(app, theme_color, 2);
}
// return non-zero if you do anything that might change the screen!
// 4coder won't redraw unless you tell it you've changed something important.
// If you redraw *all* the time it's going to slow 4coder down and increase power consumption.
return(result);
}
CUSTOM_COMMAND_SIG(write_allen_todo){
write_string(app, make_lit_string("// TODO(allen): "));
}

216
4ed.cpp
View File

@ -235,7 +235,7 @@ COMMAND_DECL(null){
}
COMMAND_DECL(write_character){
ProfileMomentFunction();
USE_MODELS(models);
REQ_OPEN_VIEW(view);
REQ_FILE(file, view);
@ -282,7 +282,7 @@ seek_token_right(Cpp_Token_Stack *tokens, i32 pos){
}
COMMAND_DECL(seek_left){
ProfileMomentFunction();
REQ_READABLE_VIEW(view);
REQ_FILE(file, view);
@ -335,7 +335,7 @@ COMMAND_DECL(seek_left){
}
COMMAND_DECL(seek_right){
ProfileMomentFunction();
REQ_READABLE_VIEW(view);
REQ_FILE(file, view);
@ -390,7 +390,7 @@ COMMAND_DECL(seek_right){
}
COMMAND_DECL(seek_whitespace_up){
ProfileMomentFunction();
REQ_READABLE_VIEW(view);
REQ_FILE(file, view);
@ -399,7 +399,7 @@ COMMAND_DECL(seek_whitespace_up){
}
COMMAND_DECL(seek_whitespace_down){
ProfileMomentFunction();
REQ_READABLE_VIEW(view);
REQ_FILE(file, view);
@ -408,7 +408,7 @@ COMMAND_DECL(seek_whitespace_down){
}
COMMAND_DECL(center_view){
ProfileMomentFunction();
USE_VIEW(view);
REQ_FILE(file, view);
@ -428,7 +428,7 @@ COMMAND_DECL(center_view){
}
COMMAND_DECL(word_complete){
ProfileMomentFunction();
USE_MODELS(models);
USE_VARS(vars);
REQ_OPEN_VIEW(view);
@ -588,7 +588,7 @@ COMMAND_DECL(word_complete){
}
COMMAND_DECL(set_mark){
ProfileMomentFunction();
REQ_READABLE_VIEW(view);
REQ_FILE(file, view);
@ -596,7 +596,7 @@ COMMAND_DECL(set_mark){
}
COMMAND_DECL(copy){
ProfileMomentFunction();
USE_MODELS(models);
REQ_READABLE_VIEW(view);
REQ_FILE(file, view);
@ -631,7 +631,7 @@ COMMAND_DECL(copy){
}
COMMAND_DECL(cut){
ProfileMomentFunction();
USE_MODELS(models);
REQ_OPEN_VIEW(view);
REQ_FILE(file, view);
@ -672,7 +672,7 @@ COMMAND_DECL(cut){
}
COMMAND_DECL(paste){
ProfileMomentFunction();
USE_MODELS(models);
REQ_OPEN_VIEW(view);
REQ_FILE(file, view);
@ -702,7 +702,7 @@ COMMAND_DECL(paste){
}
COMMAND_DECL(paste_next){
ProfileMomentFunction();
USE_MODELS(models);
REQ_OPEN_VIEW(view);
REQ_FILE(file, view);
@ -737,7 +737,7 @@ COMMAND_DECL(paste_next){
}
COMMAND_DECL(delete_range){
ProfileMomentFunction();
USE_MODELS(models);
REQ_OPEN_VIEW(view);
REQ_FILE(file, view);
@ -756,7 +756,7 @@ COMMAND_DECL(delete_range){
}
COMMAND_DECL(timeline_scrub){
ProfileMomentFunction();
REQ_OPEN_VIEW(view);
REQ_FILE_HISTORY(file, view);
@ -766,7 +766,7 @@ COMMAND_DECL(timeline_scrub){
}
COMMAND_DECL(undo){
ProfileMomentFunction();
USE_MODELS(models);
REQ_OPEN_VIEW(view);
REQ_FILE_HISTORY(file, view);
@ -775,7 +775,7 @@ COMMAND_DECL(undo){
}
COMMAND_DECL(redo){
ProfileMomentFunction();
USE_MODELS(models);
REQ_OPEN_VIEW(view);
REQ_FILE_HISTORY(file, view);
@ -784,7 +784,7 @@ COMMAND_DECL(redo){
}
COMMAND_DECL(history_backward){
ProfileMomentFunction();
USE_MODELS(models);
REQ_OPEN_VIEW(view);
REQ_FILE_HISTORY(file, view);
@ -793,7 +793,7 @@ COMMAND_DECL(history_backward){
}
COMMAND_DECL(history_forward){
ProfileMomentFunction();
USE_MODELS(models);
REQ_OPEN_VIEW(view);
REQ_FILE_HISTORY(file, view);
@ -802,7 +802,7 @@ COMMAND_DECL(history_forward){
}
COMMAND_DECL(interactive_new){
ProfileMomentFunction();
USE_MODELS(models);
USE_VIEW(view);
@ -828,7 +828,7 @@ struct App_Open_File_Result{
};
COMMAND_DECL(interactive_open){
ProfileMomentFunction();
USE_MODELS(models);
USE_PANEL(panel);
USE_VIEW(view);
@ -908,7 +908,7 @@ view_file_in_panel(Command_Data *cmd, Panel *panel, Editing_File *file){
// - Keep current version open and do some sort of diff to keep
// the cursor position correct
COMMAND_DECL(reopen){
ProfileMomentFunction();
USE_VARS(vars);
USE_MODELS(models);
USE_VIEW(view);
@ -933,7 +933,7 @@ COMMAND_DECL(reopen){
}
COMMAND_DECL(save){
ProfileMomentFunction();
USE_MODELS(models);
USE_VIEW(view);
USE_FILE(file, view);
@ -1009,7 +1009,7 @@ COMMAND_DECL(save){
}
COMMAND_DECL(change_active_panel){
ProfileMomentFunction();
USE_MODELS(models);
USE_PANEL(panel);
@ -1021,7 +1021,7 @@ COMMAND_DECL(change_active_panel){
}
COMMAND_DECL(interactive_switch_buffer){
ProfileMomentFunction();
USE_VIEW(view);
USE_MODELS(models);
@ -1030,7 +1030,7 @@ COMMAND_DECL(interactive_switch_buffer){
}
COMMAND_DECL(interactive_kill_buffer){
ProfileMomentFunction();
USE_VIEW(view);
USE_MODELS(models);
@ -1039,7 +1039,7 @@ COMMAND_DECL(interactive_kill_buffer){
}
COMMAND_DECL(kill_buffer){
ProfileMomentFunction();
USE_MODELS(models);
USE_VIEW(view);
USE_FILE(file, view);
@ -1068,7 +1068,7 @@ COMMAND_DECL(kill_buffer){
}
COMMAND_DECL(toggle_line_wrap){
ProfileMomentFunction();
REQ_READABLE_VIEW(view);
REQ_FILE(file, view);
@ -1092,14 +1092,14 @@ COMMAND_DECL(toggle_line_wrap){
}
COMMAND_DECL(toggle_show_whitespace){
ProfileMomentFunction();
REQ_READABLE_VIEW(view);
view->show_whitespace = !view->show_whitespace;
}
COMMAND_DECL(toggle_tokens){
#if BUFFER_EXPERIMENT_SCALPEL <= 0
ProfileMomentFunction();
USE_MODELS(models);
REQ_OPEN_VIEW(view);
REQ_FILE(file, view);
@ -1145,7 +1145,7 @@ case_change_range(System_Functions *system,
}
COMMAND_DECL(to_uppercase){
ProfileMomentFunction();
USE_MODELS(models);
REQ_OPEN_VIEW(view);
REQ_FILE(file, view);
@ -1153,7 +1153,7 @@ COMMAND_DECL(to_uppercase){
}
COMMAND_DECL(to_lowercase){
ProfileMomentFunction();
USE_MODELS(models);
REQ_OPEN_VIEW(view);
REQ_FILE(file, view);
@ -1161,7 +1161,7 @@ COMMAND_DECL(to_lowercase){
}
COMMAND_DECL(clean_all_lines){
ProfileMomentFunction();
USE_MODELS(models);
REQ_OPEN_VIEW(view);
REQ_FILE(file, view);
@ -1170,7 +1170,7 @@ COMMAND_DECL(clean_all_lines){
}
COMMAND_DECL(eol_dosify){
ProfileMomentFunction();
REQ_READABLE_VIEW(view);
REQ_FILE(file, view);
@ -1179,7 +1179,7 @@ COMMAND_DECL(eol_dosify){
}
COMMAND_DECL(eol_nixify){
ProfileMomentFunction();
REQ_READABLE_VIEW(view);
REQ_FILE(file, view);
@ -1188,7 +1188,7 @@ COMMAND_DECL(eol_nixify){
}
COMMAND_DECL(auto_tab_range){
ProfileMomentFunction();
USE_MODELS(models);
REQ_OPEN_VIEW(view);
REQ_FILE(file, view);
@ -1233,7 +1233,7 @@ COMMAND_DECL(auto_tab_range){
}
COMMAND_DECL(open_panel_vsplit){
ProfileMomentFunction();
USE_VARS(vars);
USE_MODELS(models);
USE_PANEL(panel);
@ -1261,7 +1261,7 @@ COMMAND_DECL(open_panel_vsplit){
}
COMMAND_DECL(open_panel_hsplit){
ProfileMomentFunction();
USE_VARS(vars);
USE_MODELS(models);
USE_PANEL(panel);
@ -1289,7 +1289,7 @@ COMMAND_DECL(open_panel_hsplit){
}
COMMAND_DECL(close_panel){
ProfileMomentFunction();
USE_MODELS(models);
USE_PANEL(panel);
USE_VIEW(view);
@ -1370,7 +1370,7 @@ COMMAND_DECL(close_panel){
}
COMMAND_DECL(move_left){
ProfileMomentFunction();
REQ_READABLE_VIEW(view);
REQ_FILE(file, view);
@ -1380,7 +1380,7 @@ COMMAND_DECL(move_left){
}
COMMAND_DECL(move_right){
ProfileMomentFunction();
REQ_READABLE_VIEW(view);
REQ_FILE(file, view);
@ -1391,7 +1391,7 @@ COMMAND_DECL(move_right){
}
COMMAND_DECL(delete){
ProfileMomentFunction();
USE_MODELS(models);
REQ_OPEN_VIEW(view);
REQ_FILE(file, view);
@ -1412,7 +1412,7 @@ COMMAND_DECL(delete){
}
COMMAND_DECL(backspace){
ProfileMomentFunction();
USE_MODELS(models);
REQ_OPEN_VIEW(view);
REQ_FILE(file, view);
@ -1434,7 +1434,7 @@ COMMAND_DECL(backspace){
}
COMMAND_DECL(move_up){
ProfileMomentFunction();
USE_MODELS(models);
REQ_READABLE_VIEW(view);
REQ_FILE(file, view);
@ -1449,7 +1449,7 @@ COMMAND_DECL(move_up){
}
COMMAND_DECL(move_down){
ProfileMomentFunction();
USE_MODELS(models);
REQ_READABLE_VIEW(view);
REQ_FILE(file, view);
@ -1462,7 +1462,7 @@ COMMAND_DECL(move_down){
}
COMMAND_DECL(seek_end_of_line){
ProfileMomentFunction();
REQ_READABLE_VIEW(view);
REQ_FILE(file, view);
@ -1471,7 +1471,7 @@ COMMAND_DECL(seek_end_of_line){
}
COMMAND_DECL(seek_beginning_of_line){
ProfileMomentFunction();
REQ_READABLE_VIEW(view);
REQ_FILE(file, view);
@ -1480,7 +1480,7 @@ COMMAND_DECL(seek_beginning_of_line){
}
COMMAND_DECL(page_down){
ProfileMomentFunction();
REQ_READABLE_VIEW(view);
f32 height = view_file_height(view);
@ -1494,7 +1494,7 @@ COMMAND_DECL(page_down){
}
COMMAND_DECL(page_up){
ProfileMomentFunction();
REQ_READABLE_VIEW(view);
f32 height = view_file_height(view);
@ -1508,7 +1508,7 @@ COMMAND_DECL(page_up){
}
COMMAND_DECL(open_color_tweaker){
ProfileMomentFunction();
USE_VIEW(view);
USE_MODELS(models);
@ -1516,7 +1516,7 @@ COMMAND_DECL(open_color_tweaker){
}
COMMAND_DECL(open_config){
ProfileMomentFunction();
USE_VIEW(view);
USE_MODELS(models);
@ -1524,7 +1524,7 @@ COMMAND_DECL(open_config){
}
COMMAND_DECL(open_menu){
ProfileMomentFunction();
USE_VIEW(view);
USE_MODELS(models);
@ -1532,7 +1532,7 @@ COMMAND_DECL(open_menu){
}
COMMAND_DECL(close_minor_view){
ProfileMomentFunction();
USE_VIEW(view);
USE_MODELS(models);
@ -1544,7 +1544,7 @@ COMMAND_DECL(close_minor_view){
}
COMMAND_DECL(cursor_mark_swap){
ProfileMomentFunction();
REQ_READABLE_VIEW(view);
i32 pos = view->cursor.pos;
@ -1553,12 +1553,12 @@ COMMAND_DECL(cursor_mark_swap){
}
COMMAND_DECL(user_callback){
ProfileMomentFunction();
if (binding.custom) binding.custom(&app_links);
}
COMMAND_DECL(set_settings){
ProfileMomentFunction();
REQ_READABLE_VIEW(view);
REQ_FILE(file, view);
USE_MODELS(models);
@ -1641,7 +1641,7 @@ COMMAND_DECL(set_settings){
}
COMMAND_DECL(command_line){
ProfileMomentFunction();
USE_VARS(vars);
USE_MODELS(models);
USE_PANEL(panel);
@ -3487,25 +3487,18 @@ update_cli_handle_with_file(System_Functions *system, Models *models,
}
App_Step_Sig(app_step){
ProfileStart(OS_syncing);
Application_Step_Result app_result = *result;
app_result.redraw = force_redraw;
App_Vars *vars = (App_Vars*)memory->vars_memory;
Models *models = &vars->models;
target->partition = &models->mem.part;
if (first_step || !time_step){
app_result.redraw = 1;
}
// NOTE(allen): OS clipboard event handling
if (clipboard.str){
String *dest = working_set_next_clipboard_string(&models->mem.general, &models->working_set, clipboard.size);
dest->size = eol_convert_in(dest->str, clipboard.str, clipboard.size);
}
// TODO(allen): profile this see if it's costing me lots of power (I think it is).
// NOTE(allen): check files are up to date
{
File_Node *node, *used_nodes;
@ -3519,22 +3512,22 @@ App_Step_Sig(app_step){
time_stamp = system->file_time_stamp(make_c_str(file->name.source_path));
if (time_stamp > 0){
File_Sync_State prev_sync = buffer_get_sync(file);
file->state.last_sys_write_time = time_stamp;
#if 0
File_Sync_State prev_sync = buffer_get_sync(file);
file->state.sync = buffer_get_sync(file);
if (file->state.last_sys_write_time != file->state.last_4ed_write_time){
if (file->state.sync != prev_sync){
app_result.redraw = 1;
}
}
#endif
}
}
}
// NOTE(allen): update child processes
if (time_step){
if (dt > 0){
Temp_Memory temp = begin_temp_memory(&models->mem.part);
u32 max = Kbytes(32);
char *dest = push_array(&models->mem.part, char, max);
@ -3546,7 +3539,6 @@ App_Step_Sig(app_step){
if (file != 0){
i32 r = update_cli_handle_with_file(system, models, &proc->cli, file, dest, max, 0);
if (r) app_result.redraw = 1;
if (r < 0){
*proc = vars->cli_processes.procs[--count];
--i;
@ -3582,8 +3574,6 @@ App_Step_Sig(app_step){
// be handled in the same place.
view_change_size(system, &models->mem.general, view);
}
app_result.redraw = 1;
}
}
@ -3598,9 +3588,6 @@ App_Step_Sig(app_step){
mouse->wheel = -mouse->wheel;
ProfileEnd(OS_syncing);
ProfileStart(hover_status);
// NOTE(allen): detect mouse hover status
i32 mx = mouse->x;
i32 my = mouse->y;
@ -3677,11 +3664,8 @@ App_Step_Sig(app_step){
mouse_divider_id = 0;
}
}
ProfileEnd(hover_status);
// NOTE(allen): prepare to start executing commands
ProfileStart(prepare_commands);
Command_Data *cmd = &vars->command_data;
cmd->models = models;
@ -3757,10 +3741,8 @@ App_Step_Sig(app_step){
do_feedback_message(system, models, welcome);
}
}
ProfileEnd(prepare_commands);
// NOTE(allen): try to abort the command corroutine if we are shutting down
ProfileStart(try_to_shutdown);
if (app_result.trying_to_kill){
b32 there_is_unsaved = 0;
@ -3802,16 +3784,13 @@ App_Step_Sig(app_step){
IAct_Sure_To_Close, IInt_Sure_To_Close, make_lit_string("Are you sure?"));
models->command_coroutine = command_coroutine;
app_result.redraw = 1;
}
else{
app_result.perform_kill = 1;
}
}
ProfileEnd(try_to_shutdown);
// NOTE(allen): process the command_coroutine if it is unfinished
ProfileStart(command_coroutine);
b8 consumed_input[6] = {0};
if (models->command_coroutine != 0){
@ -3860,7 +3839,6 @@ App_Step_Sig(app_step){
if (pass_in){
models->command_coroutine =
system->resume_coroutine(command_coroutine, &user_in, models->command_coroutine_flags);
app_result.redraw = 1;
// TOOD(allen): Deduplicate
// TODO(allen): Should I somehow allow a view to clean up however it wants after a
@ -3924,7 +3902,6 @@ App_Step_Sig(app_step){
if (pass_in){
models->command_coroutine = system->resume_coroutine(command_coroutine, &user_in,
models->command_coroutine_flags);
app_result.redraw = 1;
// TOOD(allen): Deduplicate
// TODO(allen): Should I somehow allow a view to clean up however it wants after a
@ -3937,20 +3914,9 @@ App_Step_Sig(app_step){
}
update_command_data(vars, cmd);
ProfileEnd(command_coroutine);
ProfileStart(frame_hook);
if (models->hooks[hook_frame]){
if ((models->hooks[hook_frame])(&app_links)){
app_result.redraw = 1;
}
}
ProfileStart(frame_hook);
// NOTE(allen): pass raw input to the panels
ProfileStart(step);
Input_Summary dead_input = {};
dead_input.mouse.x = mouse->x;
dead_input.mouse.y = mouse->y;
@ -4002,9 +3968,7 @@ App_Step_Sig(app_step){
view = panel->view;
active = (panel == cmd->panel);
input = (active)?(active_input):(dead_input);
if (step_file_view(system, view, active_view, input)){
app_result.redraw = 1;
}
step_file_view(system, view, active_view, input);
}
for (dll_items(panel, used_panels)){
@ -4014,17 +3978,13 @@ App_Step_Sig(app_step){
if (panel == mouse_panel && !mouse->out_of_window){
input.mouse = mouse_state;
}
if (do_input_file_view(system, exchange, view, panel->inner, active, &input)){
app_result.redraw = 1;
}
do_input_file_view(system, exchange, view, panel->inner, active, &input);
}
}
update_command_data(vars, cmd);
ProfileEnd(step);
// NOTE(allen): command execution
ProfileStart(command);
if (!consumed_input[0] || !consumed_input[1]){
b32 consumed_input2[2] = {0};
@ -4065,7 +4025,6 @@ App_Step_Sig(app_step){
models->command_coroutine = system->launch_coroutine(models->command_coroutine,
&cmd_in, models->command_coroutine_flags);
models->prev_command = cmd_bind;
app_result.redraw = 1;
}
}
}break;
@ -4084,9 +4043,7 @@ App_Step_Sig(app_step){
}
update_command_data(vars, cmd);
ProfileEnd(command);
ProfileStart(resizing);
// NOTE(allen): panel resizing
switch (vars->state){
case APP_STATE_EDIT:
@ -4158,7 +4115,6 @@ App_Step_Sig(app_step){
case APP_STATE_RESIZING:
{
app_result.redraw = 1;
if (mouse->l){
Panel_Divider *divider = vars->resizing.divider;
if (divider->v_divider){
@ -4185,14 +4141,11 @@ App_Step_Sig(app_step){
if (mouse_in_edit_area && mouse_panel != 0 && mouse->press_l){
models->layout.active_panel = (i32)(mouse_panel - models->layout.panels);
app_result.redraw = 1;
}
update_command_data(vars, cmd);
ProfileEnd(resizing);
// NOTE(allen): processing sys app bindings
ProfileStart(sys_app_bind_processing);
{
Mem_Options *mem = &models->mem;
General_Memory *general = &mem->general;
@ -4236,8 +4189,6 @@ App_Step_Sig(app_step){
view_measure_wraps(system, general, iter.view);
view_cursor_move(iter.view, preload_settings.start_line, 0);
}
app_result.redraw = 1;
}
else{
if (binding->fail & SysAppCreateNewBuffer){
@ -4250,8 +4201,6 @@ App_Step_Sig(app_step){
working_set_remove(system, &models->working_set, ed_file->name.source_path);
working_set_free_file(&models->working_set, ed_file);
}
app_result.redraw = 1;
}
exchange_free_file(exchange, binding->sys_id);
@ -4283,10 +4232,8 @@ App_Step_Sig(app_step){
}
}
}
ProfileEnd(sys_app_bind_processing);
// NOTE(allen): process as many delayed actions as possible
ProfileStart(delayed_actions);
if (models->delay1.count > 0){
Working_Set *working_set = &models->working_set;
Mem_Options *mem = &models->mem;
@ -4321,8 +4268,6 @@ App_Step_Sig(app_step){
{
String filename = string;
i32 file_id;
filename.str[0] = char_to_lower(filename.str[0]);
result.file = working_set_contains(system, working_set, filename);
if (result.file == 0){
@ -4522,9 +4467,7 @@ App_Step_Sig(app_step){
}
end_temp_memory(param_stack_temp);
ProfileEnd(delayed_actions);
ProfileStart(resize);
// NOTE(allen): send resize messages to panels that have changed size
{
Panel *panel, *used_panels;
@ -4539,9 +4482,7 @@ App_Step_Sig(app_step){
panel->prev_inner = inner;
}
}
ProfileEnd(resize);
ProfileStart(style_change);
// NOTE(allen): send style change messages if the style has changed
if (models->global_font.font_changed){
models->global_font.font_changed = 0;
@ -4564,11 +4505,9 @@ App_Step_Sig(app_step){
remeasure_file_view(system, panel->view, panel->inner);
}
}
ProfileEnd(style_change);
ProfileStart(redraw);
if (mouse_panel != models->prev_mouse_panel) app_result.redraw = 1;
if (app_result.redraw){
// NOTE(allen): rendering
{
begin_render_section(target, system);
target->clip_top = -1;
@ -4610,9 +4549,7 @@ App_Step_Sig(app_step){
end_render_section(target, system);
}
ProfileEnd(redraw);
ProfileStart(get_cursor);
// NOTE(allen): get cursor type
if (mouse_in_edit_area){
app_result.mouse_cursor_type = APP_MOUSE_CURSOR_ARROW;
@ -4631,8 +4568,7 @@ App_Step_Sig(app_step){
}
}
models->prev_mouse_panel = mouse_panel;
ProfileEnd(get_cursor);
app_result.lctrl_lalt_is_altgr = models->settings.lctrl_lalt_is_altgr;
*result = app_result;

3
4ed.h
View File

@ -97,7 +97,6 @@ enum Application_Mouse_Cursor{
struct Application_Step_Result{
Application_Mouse_Cursor mouse_cursor_type;
b32 redraw;
b32 lctrl_lalt_is_altgr;
b32 trying_to_kill;
b32 perform_kill;
@ -111,7 +110,7 @@ name(System_Functions *system, \
Application_Memory *memory, \
Exchange *exchange, \
String clipboard, \
b32 time_step, b32 first_step, b32 force_redraw, \
f32 dt, b32 first_step, \
Application_Step_Result *result)
typedef App_Step_Sig(App_Step);

View File

@ -429,7 +429,11 @@ working_set_add(System_Functions *system, Working_Set *working_set, Editing_File
working_set__grow_if_needed(&working_set->table, general, system, tbl_string_hash, tbl_file_compare);
working_set__entry_comp(system, file->name.source_path, &entry_comp);
entry_comp.entry.id = file->id;
table_add(&working_set->table, &entry_comp, system, tbl_string_hash, tbl_file_compare);
if (table_add(&working_set->table, &entry_comp, system, tbl_string_hash, tbl_file_compare)){
if (!uhash_equal(entry_comp.hash, uhash_zero())){
system->file_track(file->name.source_path);
}
}
}
inline void
@ -437,6 +441,9 @@ working_set_remove(System_Functions *system, Working_Set *working_set, String fi
File_Entry_Comparison entry_comp;
working_set__entry_comp(system, filename, &entry_comp);
table_remove_match(&working_set->table, &entry_comp, system, tbl_string_hash, tbl_file_compare);
if (!uhash_equal(entry_comp.hash, uhash_zero())){
system->file_untrack(filename);
}
}
// TODO(allen): Pick better first options.
@ -444,8 +451,6 @@ internal Editing_File*
working_set_lookup_file(Working_Set *working_set, String string){
Editing_File *file = 0;
replace_char(string, '\\', '/');
{
File_Node *node, *used_nodes;
used_nodes = &working_set->used_sentinel;
@ -562,8 +567,6 @@ internal b32
filename_match(String query, Absolutes *absolutes, String filename, b32 case_sensitive){
b32 result;
result = (query.size == 0);
replace_char(query, '\\', '/');
replace_char(filename, '\\', '/');
if (!result) result = wildcard_match(absolutes, filename, case_sensitive);
return result;
}
@ -576,8 +579,6 @@ hot_directory_first_match(Hot_Directory *hot_directory,
b32 case_sensitive){
Hot_Directory_Match result = {};
replace_char(str, '\\', '/');
Absolutes absolutes;
if (!exact_match)
get_absolutes(str, &absolutes, 1, 1);

View File

@ -382,7 +382,6 @@ file_grow_starts_widths_as_needed(General_Memory *general, Buffer_Type *buffer,
internal void
file_measure_starts_widths(System_Functions *system, General_Memory *general,
Buffer_Type *buffer, float *advance_data){
ProfileMomentFunction();
if (!buffer->line_starts){
i32 max = buffer->line_max = Kbytes(1);
buffer->line_starts = (i32*)general_memory_allocate(general, max*sizeof(i32), BUBBLE_STARTS);
@ -441,17 +440,6 @@ get_opaque_font_advance(Render_Font *font){
return result;
}
#if 0
internal void
file_remeasure_widths_(System_Functions *system,
General_Memory *general, Buffer_Type *buffer, Render_Font *font,
i32 line_start, i32 line_end, i32 line_shift){
ProfileMomentFunction();
file_grow_starts_widths_as_needed(general, buffer, line_shift);
buffer_remeasure_widths(buffer, font->advance_data, line_start, line_end, line_shift);
}
#endif
inline i32
view_wrapped_line_span(f32 line_width, f32 max_width){
i32 line_count = CEIL32(line_width / max_width);
@ -485,7 +473,6 @@ view_compute_lowest_line(View *view){
internal void
view_measure_wraps(System_Functions *system,
General_Memory *general, View *view){
ProfileMomentFunction();
Buffer_Type *buffer;
buffer = &view->file->state.buffer;
@ -1655,7 +1642,6 @@ internal void
file_do_single_edit(System_Functions *system,
Models *models, Editing_File *file,
Edit_Spec spec, History_Mode history_mode, b32 use_high_permission = 0){
ProfileMomentFunction();
if (!use_high_permission && file->settings.read_only) return;
Mem_Options *mem = &models->mem;
@ -1731,7 +1717,6 @@ file_do_single_edit(System_Functions *system,
internal void
file_do_white_batch_edit(System_Functions *system, Models *models, Editing_File *file,
Edit_Spec spec, History_Mode history_mode, b32 use_high_permission = 0){
ProfileMomentFunction();
if (!use_high_permission && file->settings.read_only) return;
Mem_Options *mem = &models->mem;
@ -5540,7 +5525,7 @@ search_hit_add(General_Memory *general, Table *hits, String_Space *space, char *
*hits = new_hits;
}
if (!table_add(hits, &ostring, space->space, tbl_offset_string_hash, tbl_offset_string_compare)){
if (table_add(hits, &ostring, space->space, tbl_offset_string_hash, tbl_offset_string_compare)){
result = 1;
strspace_keep_prev(space);
}

View File

@ -10,37 +10,6 @@
// TOP
#if FRED_INTERNAL == 1
#define ProfileStart_(name, start, counter, hit, thread, n, c)
#define ProfileEnd_(name, start, counter, hit, thread)
#define ProfileMoment_(name, counter, thread)
#if 0
#define ProfileStart(name) char *_pname_##name; i64 _pstart_##name; \
i32 _pcounter_##name; u32 _phit_##name; \
ProfileStart_(_pname_##name, _pstart_##name, _pcounter_##name, \
_phit_##name, system->thread_get_id(thread), \
#name, __COUNTER__)
#define ProfileEnd(name) ProfileEnd_(_pname_##name, _pstart_##name, \
_pcounter_##name, _phit_##name, \
system->thread_get_id(thread))
#define ProfileMoment(name, thread) ProfileMoment_(#name, __COUNTER__, thread)
#define ProfileMomentFunction() ProfileMoment_(__FUNCTION__, __COUNTER__, 0)
#else
#define ProfileStart(name)
#define ProfileEnd(name)
#define ProfileMoment(name)
#define ProfileMomentFunction()
#endif
struct Sys_Bubble : public Bubble{
i32 line_number;
@ -49,11 +18,6 @@ struct Sys_Bubble : public Bubble{
#else
#define ProfileStart(name)
#define ProfileEnd(name)
#define ProfileMoment(name)
#define ProfileMomentFunction()
#endif
// BOTTOM

View File

@ -45,6 +45,13 @@ typedef Sys_Set_File_List_Sig(System_Set_File_List);
#define Sys_File_Unique_Hash_Sig(name) Unique_Hash name(String filename, b32 *success)
typedef Sys_File_Unique_Hash_Sig(System_File_Unique_Hash);
#define Sys_File_Track_Sig(name) void name(String filename)
typedef Sys_File_Track_Sig(System_File_Track);
#define Sys_File_Untrack_Sig(name) void name(String filename)
typedef Sys_File_Untrack_Sig(System_File_Untrack);
#define Sys_Post_Clipboard_Sig(name) void name(String str)
typedef Sys_Post_Clipboard_Sig(System_Post_Clipboard);
@ -193,10 +200,12 @@ typedef INTERNAL_Sys_Get_Thread_States_Sig(INTERNAL_System_Get_Thread_States);
typedef INTERNAL_Sys_Debug_Message_Sig(INTERNAL_System_Debug_Message);
struct System_Functions{
// files: 3
// files: 4
System_File_Time_Stamp *file_time_stamp;
System_Set_File_List *set_file_list;
System_File_Unique_Hash *file_unique_hash;
System_File_Track *file_track;
System_File_Untrack *file_untrack;
// file system navigation (4coder_custom.h): 2
File_Exists_Function *file_exists;
@ -262,9 +271,16 @@ struct File_Exchange{
i32 num_active, max;
};
struct Write_Event{
Write_Event *next, *prev;
String filename;
u64 time_stamp;
};
struct Exchange{
Thread_Exchange thread;
File_Exchange file;
Write_Event write_event_sentinel;
};
// BOTTOM

View File

@ -1,258 +1,258 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 14.02.2016
*
* 4tech C style genereic hash table
*
*/
// TOP
#define TableHashEmpty 0
#define TableHashDeleted 1
#define TableHashMin 0x10000000
typedef u32 Hash_Function(void *item, void *arg);
typedef i32 Compare_Function(void *key, void *item, void *arg);
struct Table{
u32 *hash_array;
u8 *data_array;
i32 count, max;
i32 item_size;
};
internal i32
table_required_mem_size(i32 table_size, i32 item_size){
i32 mem_size, hash_size;
hash_size = ((table_size * sizeof(u32)) + 7) & ~7;
mem_size = hash_size + table_size * item_size;
return(mem_size);
}
internal void
table_init_memory(Table *table, void *memory, i32 table_size, i32 item_size){
i32 hash_size = table_size * sizeof(u32);
hash_size = (hash_size + 7) & ~7;
table->hash_array = (u32*)memory;
table->data_array = (u8*)(table->hash_array) + hash_size;
table->count = 0;
table->max = table_size;
table->item_size = item_size;
}
internal b32
table_at_capacity(Table *table){
b32 result = 1;
if (table->count * 8 < table->max * 7){
result = 0;
}
return(result);
}
internal b32
table_add(Table *table, void *item, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){
u32 hash, *inspect;
i32 i;
Assert(table->count * 8 < table->max * 7);
hash = (hash_func(item, arg) | TableHashMin);
i = hash % table->max;
inspect = table->hash_array + i;
while (*inspect >= TableHashMin){
if (*inspect == hash){
if (comp_func(item, table->data_array + i*table->item_size, arg) == 0){
return(1);
}
}
++i;
++inspect;
if (i == table->max){
i = 0;
inspect = table->hash_array;
}
}
*inspect = hash;
memcpy(table->data_array + i*table->item_size, item, table->item_size);
++table->count;
return(0);
}
internal b32
table_find_pos(Table *table, void *search_key, void *arg, i32 *pos, i32 *index, Hash_Function *hash_func, Compare_Function *comp_func){
u32 hash, *inspect;
i32 i;
Assert((table->count - 1) * 8 < table->max * 7);
hash = (hash_func(search_key, arg) | TableHashMin);
i = hash % table->max;
inspect = table->hash_array + i;
while (*inspect != TableHashEmpty){
if (*inspect == hash){
if (comp_func(search_key, table->data_array + i*table->item_size, arg) == 0){
if (pos) *pos = i*table->item_size;
if (index) *index = i;
return(1);
}
}
++i;
++inspect;
if (i == table->max){
i = 0;
inspect = table->hash_array;
}
}
return(0);
}
inline void*
table_find_item(Table *table, void *search_key, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){
i32 pos;
void *result = 0;
if (table_find_pos(table, search_key, arg, &pos, 0, hash_func, comp_func)){
result = table->data_array + pos;
}
return(result);
}
inline void
table_remove_index(Table *table, i32 index){
table->hash_array[index] = TableHashDeleted;
--table->count;
}
inline b32
table_remove_match(Table *table, void *search_key, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){
i32 index;
b32 result = 0;
if (table_find_pos(table, search_key, arg, 0, &index, hash_func, comp_func)){
table_remove_index(table, index);
result = 1;
}
return(result);
}
inline void
table_clear(Table *table){
table->count = 0;
memset(table->hash_array, 0, table->max*sizeof(*table->hash_array));
}
internal void
table_rehash(Table *src, Table *dst, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){
i32 i, c, count, item_size;
u32 *hash_item;
u8 *data_item;
Assert((dst->count + src->count - 1) * 7 < dst->max * 8);
Assert(dst->item_size == src->item_size);
count = src->count;
hash_item = src->hash_array;
data_item = src->data_array;
item_size = src->item_size;
for (i = 0, c = 0; c < count; ++i, ++hash_item, data_item += item_size){
if (*hash_item >= TableHashMin){
++c;
table_add(dst, data_item, arg, hash_func, comp_func);
}
}
}
internal u32
tbl_string_hash(void *item, void *arg){
String *string = (String*)item;
char *str;
i32 i,len;
u32 x = 5381;
char c;
(void)arg;
str = string->str;
len = string->size;
i = 0;
while (i < len){
c = str[i++];
x = ((x << 5) + x) + c;
}
return(x);
}
internal i32
tbl_string_compare(void *a, void *b, void *arg){
String *stra = (String*)a;
String *strb = (String*)b;
i32 result = !match(*stra, *strb);
return(result);
}
internal u32
tbl_offset_string_hash(void *item, void *arg){
Offset_String *string = (Offset_String*)item;
char *str;
i32 i,len;
u32 x = 5381;
char c;
str = ((char*)arg) + string->offset;
len = string->size;
i = 0;
while (i < len){
c = str[i++];
x = ((x << 5) + x) + c;
}
return(x);
}
internal i32
tbl_offset_string_compare(void *a, void *b, void *arg){
Offset_String *ostra = (Offset_String*)a;
Offset_String *ostrb = (Offset_String*)b;
String stra = make_string((char*)arg + ostra->offset, ostra->size);
String strb = make_string((char*)arg + ostrb->offset, ostrb->size);
i32 result = !match(stra, strb);
return(result);
}
struct String_Space{
char *space;
i32 pos, new_pos, max;
};
internal Offset_String
strspace_append(String_Space *space, char *str, i32 len){
Offset_String result = {};
if (space->new_pos + len <= space->max){
result.offset = space->new_pos;
result.size = len;
memcpy(space->space + space->new_pos, str, len);
space->new_pos = space->pos + len;
}
return(result);
}
internal void
strspace_keep_prev(String_Space *space){
space->pos = space->new_pos;
}
internal void
strspace_discard_prev(String_Space *space){
space->new_pos = space->pos;
}
// BOTTOM
/*
* Mr. 4th Dimention - Allen Webster
*
* 14.02.2016
*
* 4tech C style genereic hash table
*
*/
// TOP
#define TableHashEmpty 0
#define TableHashDeleted 1
#define TableHashMin 0x10000000
typedef u32 Hash_Function(void *item, void *arg);
typedef i32 Compare_Function(void *key, void *item, void *arg);
struct Table{
u32 *hash_array;
u8 *data_array;
i32 count, max;
i32 item_size;
};
internal i32
table_required_mem_size(i32 table_size, i32 item_size){
i32 mem_size, hash_size;
hash_size = ((table_size * sizeof(u32)) + 7) & ~7;
mem_size = hash_size + table_size * item_size;
return(mem_size);
}
internal void
table_init_memory(Table *table, void *memory, i32 table_size, i32 item_size){
i32 hash_size = table_size * sizeof(u32);
hash_size = (hash_size + 7) & ~7;
table->hash_array = (u32*)memory;
table->data_array = (u8*)(table->hash_array) + hash_size;
table->count = 0;
table->max = table_size;
table->item_size = item_size;
}
internal b32
table_at_capacity(Table *table){
b32 result = 1;
if (table->count * 8 < table->max * 7){
result = 0;
}
return(result);
}
internal b32
table_add(Table *table, void *item, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){
u32 hash, *inspect;
i32 i;
Assert(table->count * 8 < table->max * 7);
hash = (hash_func(item, arg) | TableHashMin);
i = hash % table->max;
inspect = table->hash_array + i;
while (*inspect >= TableHashMin){
if (*inspect == hash){
if (comp_func(item, table->data_array + i*table->item_size, arg) == 0){
return(1);
}
}
++i;
++inspect;
if (i == table->max){
i = 0;
inspect = table->hash_array;
}
}
*inspect = hash;
memcpy(table->data_array + i*table->item_size, item, table->item_size);
++table->count;
return(0);
}
internal b32
table_find_pos(Table *table, void *search_key, void *arg, i32 *pos, i32 *index, Hash_Function *hash_func, Compare_Function *comp_func){
u32 hash, *inspect;
i32 i;
Assert((table->count - 1) * 8 < table->max * 7);
hash = (hash_func(search_key, arg) | TableHashMin);
i = hash % table->max;
inspect = table->hash_array + i;
while (*inspect != TableHashEmpty){
if (*inspect == hash){
if (comp_func(search_key, table->data_array + i*table->item_size, arg) == 0){
if (pos) *pos = i*table->item_size;
if (index) *index = i;
return(1);
}
}
++i;
++inspect;
if (i == table->max){
i = 0;
inspect = table->hash_array;
}
}
return(0);
}
inline void*
table_find_item(Table *table, void *search_key, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){
i32 pos;
void *result = 0;
if (table_find_pos(table, search_key, arg, &pos, 0, hash_func, comp_func)){
result = table->data_array + pos;
}
return(result);
}
inline void
table_remove_index(Table *table, i32 index){
table->hash_array[index] = TableHashDeleted;
--table->count;
}
inline b32
table_remove_match(Table *table, void *search_key, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){
i32 index;
b32 result = 0;
if (table_find_pos(table, search_key, arg, 0, &index, hash_func, comp_func)){
table_remove_index(table, index);
result = 1;
}
return(result);
}
inline void
table_clear(Table *table){
table->count = 0;
memset(table->hash_array, 0, table->max*sizeof(*table->hash_array));
}
internal void
table_rehash(Table *src, Table *dst, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){
i32 i, c, count, item_size;
u32 *hash_item;
u8 *data_item;
Assert((dst->count + src->count - 1) * 7 < dst->max * 8);
Assert(dst->item_size == src->item_size);
count = src->count;
hash_item = src->hash_array;
data_item = src->data_array;
item_size = src->item_size;
for (i = 0, c = 0; c < count; ++i, ++hash_item, data_item += item_size){
if (*hash_item >= TableHashMin){
++c;
table_add(dst, data_item, arg, hash_func, comp_func);
}
}
}
internal u32
tbl_string_hash(void *item, void *arg){
String *string = (String*)item;
char *str;
i32 i,len;
u32 x = 5381;
char c;
(void)arg;
str = string->str;
len = string->size;
i = 0;
while (i < len){
c = str[i++];
x = ((x << 5) + x) + c;
}
return(x);
}
internal i32
tbl_string_compare(void *a, void *b, void *arg){
String *stra = (String*)a;
String *strb = (String*)b;
i32 result = !match(*stra, *strb);
return(result);
}
internal u32
tbl_offset_string_hash(void *item, void *arg){
Offset_String *string = (Offset_String*)item;
char *str;
i32 i,len;
u32 x = 5381;
char c;
str = ((char*)arg) + string->offset;
len = string->size;
i = 0;
while (i < len){
c = str[i++];
x = ((x << 5) + x) + c;
}
return(x);
}
internal i32
tbl_offset_string_compare(void *a, void *b, void *arg){
Offset_String *ostra = (Offset_String*)a;
Offset_String *ostrb = (Offset_String*)b;
String stra = make_string((char*)arg + ostra->offset, ostra->size);
String strb = make_string((char*)arg + ostrb->offset, ostrb->size);
i32 result = !match(stra, strb);
return(result);
}
struct String_Space{
char *space;
i32 pos, new_pos, max;
};
internal Offset_String
strspace_append(String_Space *space, char *str, i32 len){
Offset_String result = {};
if (space->new_pos + len <= space->max){
result.offset = space->new_pos;
result.size = len;
memcpy(space->space + space->new_pos, str, len);
space->new_pos = space->pos + len;
}
return(result);
}
internal void
strspace_keep_prev(String_Space *space){
space->pos = space->new_pos;
}
internal void
strspace_discard_prev(String_Space *space){
space->new_pos = space->pos;
}
// BOTTOM

View File

@ -47,9 +47,12 @@
#define FPS 30
#define frame_useconds (1000000 / FPS)
// TODO(allen): Do we still need all of these? I've abandoned the
// main thread / update loop thread thing for a while at least.
#define WM_4coder_LOAD_FONT (WM_USER + 1)
#define WM_4coder_PAINT (WM_USER + 2)
#define WM_4coder_SET_CURSOR (WM_USER + 3)
#define WM_4coder_ANIMATE (WM_USER + 4)
struct Thread_Context{
u32 job_id;
@ -84,8 +87,6 @@ struct Win32_Input_Chunk_Transient{
i8 mouse_wheel;
b8 trying_to_kill;
b8 redraw;
};
struct Win32_Input_Chunk_Persistent{
@ -159,10 +160,9 @@ struct Win32_Vars{
Font_Load_System fnt;
// NOTE(allen): I don't expect to have many of these, but it pays
// to look a head a little so this is set up so that we can just bump
// it up if needed.
Win32_Coroutine coroutine_data[2];
// NOTE(allen): Going to do an experiment that
// will involve more coroutines.
Win32_Coroutine coroutine_data[18];
Win32_Coroutine *coroutine_free;
};
@ -463,6 +463,14 @@ Sys_Set_File_List_Sig(system_set_file_list){
}
}
internal
Sys_File_Track_Sig(system_file_track){
}
internal
Sys_File_Untrack_Sig(system_file_untrack){
}
internal
Sys_File_Unique_Hash_Sig(system_file_unique_hash){
Unique_Hash hash = {0};
@ -1088,6 +1096,8 @@ Win32LoadSystemCode(){
win32vars.system->file_time_stamp = system_file_time_stamp;
win32vars.system->file_unique_hash = system_file_unique_hash;
win32vars.system->set_file_list = system_set_file_list;
win32vars.system->file_track = system_file_track;
win32vars.system->file_untrack = system_file_untrack;
win32vars.system->file_exists = system_file_exists;
win32vars.system->directory_cd = system_directory_cd;
@ -1391,7 +1401,6 @@ Win32Callback(HWND hwnd, UINT uMsg,
i32 new_height = HIWORD(lParam);
Win32Resize(new_width, new_height);
win32vars.input_chunk.trans.redraw = 1;
}
}break;
@ -1474,185 +1483,180 @@ Win32Callback(HWND hwnd, UINT uMsg,
return result;
}
internal void
UpdateStep(){
i64 timer_start = system_time();
system_acquire_lock(INPUT_LOCK);
Win32_Input_Chunk input_chunk = win32vars.input_chunk;
win32vars.input_chunk.trans = {};
system_release_lock(INPUT_LOCK);
input_chunk.pers.control_keys[MDFR_CAPS_INDEX] = GetKeyState(VK_CAPITAL) & 0x1;
POINT mouse_point;
if (GetCursorPos(&mouse_point) && ScreenToClient(win32vars.window_handle, &mouse_point)){
if (mouse_point.x < 0 || mouse_point.x >= win32vars.target.width ||
mouse_point.y < 0 || mouse_point.y >= win32vars.target.height){
input_chunk.trans.out_of_window = 1;
}
}
else{
input_chunk.trans.out_of_window = 1;
}
win32vars.clipboard_contents = {};
if (win32vars.clipboard_sequence != 0){
DWORD new_number = GetClipboardSequenceNumber();
if (new_number != win32vars.clipboard_sequence){
win32vars.clipboard_sequence = new_number;
if (win32vars.next_clipboard_is_self){
win32vars.next_clipboard_is_self = 0;
}
else if (IsClipboardFormatAvailable(CF_TEXT)){
if (OpenClipboard(win32vars.window_handle)){
HANDLE clip_data;
clip_data = GetClipboardData(CF_TEXT);
if (clip_data){
win32vars.clipboard_contents.str = (char*)GlobalLock(clip_data);
if (win32vars.clipboard_contents.str){
win32vars.clipboard_contents.size = str_size((char*)win32vars.clipboard_contents.str);
GlobalUnlock(clip_data);
}
}
CloseClipboard();
}
}
}
}
Key_Input_Data input_data;
Mouse_State mouse;
Application_Step_Result result;
input_data = input_chunk.trans.key_data;
mouse.out_of_window = input_chunk.trans.out_of_window;
mouse.l = input_chunk.pers.mouse_l;
mouse.press_l = input_chunk.trans.mouse_l_press;
mouse.release_l = input_chunk.trans.mouse_l_release;
mouse.r = input_chunk.pers.mouse_r;
mouse.press_r = input_chunk.trans.mouse_r_press;
mouse.release_r = input_chunk.trans.mouse_r_release;
mouse.wheel = input_chunk.trans.mouse_wheel;
mouse.x = input_chunk.pers.mouse_x;
mouse.y = input_chunk.pers.mouse_y;
result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT;
result.lctrl_lalt_is_altgr = win32vars.lctrl_lalt_is_altgr;
result.trying_to_kill = input_chunk.trans.trying_to_kill;
result.perform_kill = 0;
// NOTE(allen): The expected dt given the frame limit in seconds.
f32 dt = frame_useconds / 1000000.f;
win32vars.app.step(win32vars.system,
&input_data,
&mouse,
&win32vars.target,
&memory_vars,
&exchange_vars,
win32vars.clipboard_contents,
dt, win32vars.first,
&result);
if (result.perform_kill){
win32vars.input_chunk.pers.keep_playing = 0;
}
Win32SetCursorFromUpdate(result.mouse_cursor_type);
win32vars.lctrl_lalt_is_altgr = result.lctrl_lalt_is_altgr;
Win32RedrawFromUpdate();
win32vars.first = 0;
{
File_Slot *file;
int d = 0;
for (file = exchange_vars.file.active.next;
file != &exchange_vars.file.active;
file = file->next){
++d;
if (file->flags & FEx_Save){
Assert((file->flags & FEx_Request) == 0);
file->flags &= (~FEx_Save);
if (system_save_file(file->filename, file->data, file->size)){
file->flags |= FEx_Save_Complete;
}
else{
file->flags |= FEx_Save_Failed;
}
}
if (file->flags & FEx_Request){
Assert((file->flags & FEx_Save) == 0);
file->flags &= (~FEx_Request);
Data sysfile =
system_load_file(file->filename);
if (sysfile.data == 0){
file->flags |= FEx_Not_Exist;
}
else{
file->flags |= FEx_Ready;
file->data = sysfile.data;
file->size = sysfile.size;
}
}
}
int free_list_count = 0;
for (file = exchange_vars.file.free_list.next;
file != &exchange_vars.file.free_list;
file = file->next){
++free_list_count;
if (file->data){
system_free_memory(file->data);
}
}
if (exchange_vars.file.free_list.next != &exchange_vars.file.free_list){
Assert(free_list_count != 0);
ex__insert_range(exchange_vars.file.free_list.next, exchange_vars.file.free_list.prev,
&exchange_vars.file.available);
exchange_vars.file.num_active -= free_list_count;
}
ex__check(&exchange_vars.file);
}
i64 timer_end = system_time();
i64 end_target = (timer_start + frame_useconds);
system_release_lock(FRAME_LOCK);
while (timer_end < end_target){
DWORD samount = (DWORD)((end_target - timer_end) / 1000);
if (samount > 0) Sleep(samount);
timer_end = system_time();
}
system_acquire_lock(FRAME_LOCK);
timer_start = system_time();
PostMessage(NULL, WM_4coder_ANIMATE, 0, 0);
}
DWORD
UpdateLoop(LPVOID param){
ConvertThreadToFiber(0);
for (;win32vars.input_chunk.pers.keep_playing;){
i64 timer_start = system_time();
system_acquire_lock(INPUT_LOCK);
Win32_Input_Chunk input_chunk = win32vars.input_chunk;
win32vars.input_chunk.trans = {};
system_release_lock(INPUT_LOCK);
input_chunk.pers.control_keys[MDFR_CAPS_INDEX] = GetKeyState(VK_CAPITAL) & 0x1;
POINT mouse_point;
if (GetCursorPos(&mouse_point) && ScreenToClient(win32vars.window_handle, &mouse_point)){
if (mouse_point.x < 0 || mouse_point.x >= win32vars.target.width ||
mouse_point.y < 0 || mouse_point.y >= win32vars.target.height){
input_chunk.trans.out_of_window = 1;
}
}
else{
input_chunk.trans.out_of_window = 1;
}
win32vars.clipboard_contents = {};
if (win32vars.clipboard_sequence != 0){
DWORD new_number = GetClipboardSequenceNumber();
if (new_number != win32vars.clipboard_sequence){
win32vars.clipboard_sequence = new_number;
if (win32vars.next_clipboard_is_self){
win32vars.next_clipboard_is_self = 0;
}
else if (IsClipboardFormatAvailable(CF_TEXT)){
if (OpenClipboard(win32vars.window_handle)){
HANDLE clip_data;
clip_data = GetClipboardData(CF_TEXT);
if (clip_data){
win32vars.clipboard_contents.str = (char*)GlobalLock(clip_data);
if (win32vars.clipboard_contents.str){
win32vars.clipboard_contents.size = str_size((char*)win32vars.clipboard_contents.str);
GlobalUnlock(clip_data);
}
}
CloseClipboard();
}
}
}
}
u32 redraw = exchange_vars.thread.force_redraw;
if (redraw) exchange_vars.thread.force_redraw = 0;
redraw = redraw || input_chunk.trans.redraw;
Key_Input_Data input_data;
Mouse_State mouse;
Application_Step_Result result;
input_data = input_chunk.trans.key_data;
mouse.out_of_window = input_chunk.trans.out_of_window;
mouse.l = input_chunk.pers.mouse_l;
mouse.press_l = input_chunk.trans.mouse_l_press;
mouse.release_l = input_chunk.trans.mouse_l_release;
mouse.r = input_chunk.pers.mouse_r;
mouse.press_r = input_chunk.trans.mouse_r_press;
mouse.release_r = input_chunk.trans.mouse_r_release;
mouse.wheel = input_chunk.trans.mouse_wheel;
mouse.x = input_chunk.pers.mouse_x;
mouse.y = input_chunk.pers.mouse_y;
result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT;
result.redraw = redraw;
result.lctrl_lalt_is_altgr = win32vars.lctrl_lalt_is_altgr;
result.trying_to_kill = input_chunk.trans.trying_to_kill;
result.perform_kill = 0;
win32vars.app.step(win32vars.system,
&input_data,
&mouse,
&win32vars.target,
&memory_vars,
&exchange_vars,
win32vars.clipboard_contents,
1, win32vars.first, redraw,
&result);
if (result.perform_kill){
win32vars.input_chunk.pers.keep_playing = 0;
}
ProfileStart(OS_frame_out);
Win32SetCursorFromUpdate(result.mouse_cursor_type);
win32vars.lctrl_lalt_is_altgr = result.lctrl_lalt_is_altgr;
if (result.redraw) Win32RedrawFromUpdate();
win32vars.first = 0;
ProfileEnd(OS_frame_out);
ProfileStart(OS_file_process);
{
File_Slot *file;
int d = 0;
for (file = exchange_vars.file.active.next;
file != &exchange_vars.file.active;
file = file->next){
++d;
if (file->flags & FEx_Save){
Assert((file->flags & FEx_Request) == 0);
file->flags &= (~FEx_Save);
if (system_save_file(file->filename, file->data, file->size)){
file->flags |= FEx_Save_Complete;
}
else{
file->flags |= FEx_Save_Failed;
}
}
if (file->flags & FEx_Request){
Assert((file->flags & FEx_Save) == 0);
file->flags &= (~FEx_Request);
Data sysfile =
system_load_file(file->filename);
if (sysfile.data == 0){
file->flags |= FEx_Not_Exist;
}
else{
file->flags |= FEx_Ready;
file->data = sysfile.data;
file->size = sysfile.size;
}
}
}
int free_list_count = 0;
for (file = exchange_vars.file.free_list.next;
file != &exchange_vars.file.free_list;
file = file->next){
++free_list_count;
if (file->data){
system_free_memory(file->data);
}
}
if (exchange_vars.file.free_list.next != &exchange_vars.file.free_list){
Assert(free_list_count != 0);
ex__insert_range(exchange_vars.file.free_list.next, exchange_vars.file.free_list.prev,
&exchange_vars.file.available);
exchange_vars.file.num_active -= free_list_count;
}
ex__check(&exchange_vars.file);
}
ProfileEnd(OS_file_process);
ProfileStart(frame_sleep);
i64 timer_end = system_time();
i64 end_target = (timer_start + frame_useconds);
system_release_lock(FRAME_LOCK);
while (timer_end < end_target){
DWORD samount = (DWORD)((end_target - timer_end) / 1000);
if (samount > 0) Sleep(samount);
timer_end = system_time();
}
system_acquire_lock(FRAME_LOCK);
timer_start = system_time();
ProfileEnd(frame_sleep);
UpdateStep();
}
return(0);
}
@ -1667,149 +1671,149 @@ WinMain(HINSTANCE hInstance,
LPSTR lpCmdLine,
int nCmdShow){
#else
int
main(int argc, char **argv){
#endif
HINSTANCE hInstance = GetModuleHandle(0);
HANDLE original_out = GetStdHandle(STD_OUTPUT_HANDLE);
win32vars = {};
exchange_vars = {};
#if FRED_INTERNAL
win32vars.internal_bubble.next = &win32vars.internal_bubble;
win32vars.internal_bubble.prev = &win32vars.internal_bubble;
win32vars.internal_bubble.flags = MEM_BUBBLE_SYS_DEBUG;
int main(int argc, char **argv){
#endif
if (!Win32LoadAppCode()){
// TODO(allen): Failed to load app code, serious problem.
return 99;
}
HINSTANCE hInstance = GetModuleHandle(0);
HANDLE original_out = GetStdHandle(STD_OUTPUT_HANDLE);
System_Functions system_;
System_Functions *system = &system_;
win32vars.system = system;
Win32LoadSystemCode();
win32vars = {};
exchange_vars = {};
ConvertThreadToFiber(0);
win32vars.coroutine_free = win32vars.coroutine_data;
for (i32 i = 0; i+1 < ArrayCount(win32vars.coroutine_data); ++i){
win32vars.coroutine_data[i].next = win32vars.coroutine_data + i + 1;
}
LPVOID base;
#if FRED_INTERNAL
base = (LPVOID)Tbytes(1);
win32vars.internal_bubble.next = &win32vars.internal_bubble;
win32vars.internal_bubble.prev = &win32vars.internal_bubble;
win32vars.internal_bubble.flags = MEM_BUBBLE_SYS_DEBUG;
#endif
if (!Win32LoadAppCode()){
// TODO(allen): Failed to load app code, serious problem.
return 99;
}
System_Functions system_;
System_Functions *system = &system_;
win32vars.system = system;
Win32LoadSystemCode();
ConvertThreadToFiber(0);
win32vars.coroutine_free = win32vars.coroutine_data;
for (i32 i = 0; i+1 < ArrayCount(win32vars.coroutine_data); ++i){
win32vars.coroutine_data[i].next = win32vars.coroutine_data + i + 1;
}
LPVOID base;
#if FRED_INTERNAL
base = (LPVOID)Tbytes(1);
#else
base = (LPVOID)0;
base = (LPVOID)0;
#endif
memory_vars.vars_memory_size = Mbytes(2);
memory_vars.vars_memory = VirtualAlloc(base, memory_vars.vars_memory_size,
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE);
memory_vars.vars_memory_size = Mbytes(2);
memory_vars.vars_memory = VirtualAlloc(base, memory_vars.vars_memory_size,
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE);
#if FRED_INTERNAL
base = (LPVOID)Tbytes(2);
base = (LPVOID)Tbytes(2);
#else
base = (LPVOID)0;
base = (LPVOID)0;
#endif
memory_vars.target_memory_size = Mbytes(512);
memory_vars.target_memory = VirtualAlloc(base, memory_vars.target_memory_size,
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE);
memory_vars.target_memory_size = Mbytes(512);
memory_vars.target_memory = VirtualAlloc(base, memory_vars.target_memory_size,
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE);
base = (LPVOID)0;
memory_vars.user_memory_size = Mbytes(2);
memory_vars.user_memory = VirtualAlloc(base, memory_vars.target_memory_size,
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE);
//
base = (LPVOID)0;
memory_vars.user_memory_size = Mbytes(2);
memory_vars.user_memory = VirtualAlloc(base, memory_vars.target_memory_size,
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE);
//
if (!memory_vars.vars_memory){
return 4;
}
if (!memory_vars.vars_memory){
return 4;
}
DWORD required = GetCurrentDirectory(0, 0);
required += 1;
required *= 4;
char *current_directory_mem = (char*)system_get_memory(required);
DWORD written = GetCurrentDirectory(required, current_directory_mem);
DWORD required = GetCurrentDirectory(0, 0);
required += 1;
required *= 4;
char *current_directory_mem = (char*)system_get_memory(required);
DWORD written = GetCurrentDirectory(required, current_directory_mem);
String current_directory = make_string(current_directory_mem, written, required);
terminate_with_null(&current_directory);
replace_char(current_directory, '\\', '/');
String current_directory = make_string(current_directory_mem, written, required);
terminate_with_null(&current_directory);
replace_char(current_directory, '\\', '/');
Command_Line_Parameters clparams;
clparams.argv = argv;
clparams.argc = argc;
Command_Line_Parameters clparams;
clparams.argv = argv;
clparams.argc = argc;
char **files;
i32 *file_count;
char **files;
i32 *file_count;
files = 0;
file_count = 0;
files = 0;
file_count = 0;
i32 output_size =
win32vars.app.read_command_line(system,
&memory_vars,
current_directory,
&win32vars.settings,
&files, &file_count,
clparams);
//
i32 output_size =
win32vars.app.read_command_line(system,
&memory_vars,
current_directory,
&win32vars.settings,
&files, &file_count,
clparams);
//
if (output_size > 0){
DWORD written;
WriteFile(original_out, memory_vars.target_memory, output_size, &written, 0);
}
if (output_size != 0) return 0;
if (output_size > 0){
DWORD written;
WriteFile(original_out, memory_vars.target_memory, output_size, &written, 0);
}
if (output_size != 0) return 0;
#ifdef FRED_SUPER
char *custom_file_default = "4coder_custom.dll";
char *custom_file;
if (win32vars.settings.custom_dll) custom_file = win32vars.settings.custom_dll;
else custom_file = custom_file_default;
char *custom_file_default = "4coder_custom.dll";
char *custom_file;
if (win32vars.settings.custom_dll) custom_file = win32vars.settings.custom_dll;
else custom_file = custom_file_default;
win32vars.custom = LoadLibraryA(custom_file);
if (!win32vars.custom && custom_file != custom_file_default){
if (!win32vars.settings.custom_dll_is_strict){
win32vars.custom = LoadLibraryA(custom_file_default);
}
win32vars.custom = LoadLibraryA(custom_file);
if (!win32vars.custom && custom_file != custom_file_default){
if (!win32vars.settings.custom_dll_is_strict){
win32vars.custom = LoadLibraryA(custom_file_default);
}
}
if (win32vars.custom){
win32vars.custom_api.get_alpha_4coder_version = (_Get_Version_Function*)
GetProcAddress(win32vars.custom, "get_alpha_4coder_version");
//
if (win32vars.custom_api.get_alpha_4coder_version == 0 ||
win32vars.custom_api.get_alpha_4coder_version(MAJOR, MINOR, PATCH) == 0){
printf("Error: application and custom version numbers don't match");
return 22;
}
win32vars.custom_api.get_bindings = (Get_Binding_Data_Function*)
GetProcAddress(win32vars.custom, "get_bindings");
if (win32vars.custom){
win32vars.custom_api.get_alpha_4coder_version = (_Get_Version_Function*)
GetProcAddress(win32vars.custom, "get_alpha_4coder_version");
//
if (win32vars.custom_api.get_alpha_4coder_version == 0 ||
win32vars.custom_api.get_alpha_4coder_version(MAJOR, MINOR, PATCH) == 0){
printf("Error: application and custom version numbers don't match");
return 22;
}
win32vars.custom_api.get_bindings = (Get_Binding_Data_Function*)
GetProcAddress(win32vars.custom, "get_bindings");
}
#endif
//FreeConsole();
sysshared_filter_real_files(files, file_count);
LARGE_INTEGER lpf;
QueryPerformanceFrequency(&lpf);
win32vars.performance_frequency = lpf.QuadPart;
QueryPerformanceCounter(&lpf);
win32vars.start_pcount = lpf.QuadPart;
FILETIME filetime;
GetSystemTimeAsFileTime(&filetime);
win32vars.start_time = ((u64)filetime.dwHighDateTime << 32) | (filetime.dwLowDateTime);
win32vars.start_time /= 10;
keycode_init();
if (win32vars.custom_api.get_bindings == 0){
win32vars.custom_api.get_bindings = (Get_Binding_Data_Function*)get_bindings;
}
@ -1821,12 +1825,12 @@ WinMain(HINSTANCE hInstance,
Thread_Memory thread_memory[ArrayCount(background)];
win32vars.thread_memory = thread_memory;
exchange_vars.thread.queues[BACKGROUND_THREADS].semaphore =
Win32GenHandle(
CreateSemaphore(0, 0, win32vars.groups[BACKGROUND_THREADS].count, 0)
);
CreateSemaphore(0, 0, win32vars.groups[BACKGROUND_THREADS].count, 0)
);
u32 creation_flag = 0;
for (i32 i = 0; i < win32vars.groups[BACKGROUND_THREADS].count; ++i){
Thread_Context *thread = win32vars.groups[BACKGROUND_THREADS].threads + i;
@ -1835,40 +1839,40 @@ WinMain(HINSTANCE hInstance,
Thread_Memory *memory = win32vars.thread_memory + i;
*memory = {};
memory->id = thread->id;
thread->queue = &exchange_vars.thread.queues[BACKGROUND_THREADS];
thread->handle = CreateThread(0, 0, ThreadProc, thread, creation_flag, (LPDWORD)&thread->windows_id);
}
Assert(win32vars.locks);
for (i32 i = 0; i < LOCK_COUNT; ++i){
win32vars.locks[i] = CreateSemaphore(0, 1, 1, 0);
}
win32vars.DEBUG_sysmem_lock = CreateSemaphore(0, 1, 1, 0);
Win32LoadRenderCode();
win32vars.target.max = Mbytes(1);
win32vars.target.push_buffer = (byte*)system_get_memory(win32vars.target.max);
win32vars.cursor_ibeam = LoadCursor(NULL, IDC_IBEAM);
win32vars.cursor_arrow = LoadCursor(NULL, IDC_ARROW);
win32vars.cursor_leftright = LoadCursor(NULL, IDC_SIZEWE);
win32vars.cursor_updown = LoadCursor(NULL, IDC_SIZENS);
win32vars.prev_mouse_cursor = APP_MOUSE_CURSOR_ARROW;
WNDCLASS window_class = {};
window_class.style = CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
window_class.lpfnWndProc = Win32Callback;
window_class.hInstance = hInstance;
window_class.lpszClassName = "4coder-win32-wndclass";
WNDCLASS window_class = {};
window_class.style = CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
window_class.lpfnWndProc = Win32Callback;
window_class.hInstance = hInstance;
window_class.lpszClassName = "4coder-win32-wndclass";
window_class.hIcon = LoadIcon(hInstance, "main");
if (!RegisterClass(&window_class)){
return 1;
}
if (!RegisterClass(&window_class)){
return 1;
}
RECT window_rect = {};
if (win32vars.settings.set_window_size){
window_rect.right = win32vars.settings.window_w;
window_rect.bottom = win32vars.settings.window_h;
@ -1877,17 +1881,17 @@ WinMain(HINSTANCE hInstance,
window_rect.right = 800;
window_rect.bottom = 600;
}
if (!AdjustWindowRect(&window_rect, WS_OVERLAPPEDWINDOW, false)){
// TODO(allen): non-fatal diagnostics
}
#define WINDOW_NAME "4coder-window: " VERSION
i32 window_x;
i32 window_y;
i32 window_style;
if (win32vars.settings.set_window_pos){
window_x = win32vars.settings.window_x;
window_y = win32vars.settings.window_y;
@ -1896,15 +1900,15 @@ WinMain(HINSTANCE hInstance,
window_x = CW_USEDEFAULT;
window_y = CW_USEDEFAULT;
}
window_style = WS_OVERLAPPEDWINDOW | WS_VISIBLE;
if (win32vars.settings.maximize_window){
window_style |= WS_MAXIMIZE;
}
// TODO(allen): not Windows XP compatible, do we care?
SetProcessDPIAware();
HWND window_handle = {};
window_handle = CreateWindowA(
window_class.lpszClassName,
@ -1913,18 +1917,18 @@ WinMain(HINSTANCE hInstance,
window_rect.right - window_rect.left,
window_rect.bottom - window_rect.top,
0, 0, hInstance, 0);
if (window_handle == 0){
return 2;
}
// TODO(allen): errors?
win32vars.window_handle = window_handle;
HDC hdc = GetDC(window_handle);
win32vars.window_hdc = hdc;
GetClientRect(window_handle, &window_rect);
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
@ -1942,35 +1946,35 @@ WinMain(HINSTANCE hInstance,
PFD_MAIN_PLANE,
0,
0, 0, 0 };
i32 pixel_format;
pixel_format = ChoosePixelFormat(hdc, &pfd);
SetPixelFormat(hdc, pixel_format, &pfd);
win32vars.target.handle = hdc;
win32vars.target.context = wglCreateContext(hdc);
wglMakeCurrent(hdc, (HGLRC)win32vars.target.context);
glEnable(GL_TEXTURE_2D);
glEnable(GL_SCISSOR_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Win32Resize(window_rect.right - window_rect.left, window_rect.bottom - window_rect.top);
win32vars.clipboard_sequence = GetClipboardSequenceNumber();
if (win32vars.clipboard_sequence == 0){
system_post_clipboard(make_lit_string(""));
win32vars.clipboard_sequence = GetClipboardSequenceNumber();
win32vars.next_clipboard_is_self = 0;
if (win32vars.clipboard_sequence == 0){
// TODO(allen): diagnostics
}
}
}
else{
if (IsClipboardFormatAvailable(CF_TEXT)){
if (OpenClipboard(win32vars.window_handle)){
@ -1990,49 +1994,66 @@ WinMain(HINSTANCE hInstance,
File_Slot file_slots[32];
sysshared_init_file_exchange(&exchange_vars, file_slots, ArrayCount(file_slots), 0);
Font_Load_Parameters params[32];
sysshared_init_font_params(&win32vars.fnt, params, ArrayCount(params));
win32vars.app.init(win32vars.system, &win32vars.target,
&memory_vars, &exchange_vars,
win32vars.clipboard_contents, current_directory,
win32vars.custom_api);
&memory_vars, &exchange_vars,
win32vars.clipboard_contents, current_directory,
win32vars.custom_api);
system_free_memory(current_directory.str);
win32vars.input_chunk.pers.keep_playing = 1;
win32vars.first = 1;
timeBeginPeriod(1);
win32vars.input_chunk.pers.keep_playing = 1;
win32vars.first = 1;
timeBeginPeriod(1);
#if 0
win32vars.update_loop_thread =
CreateThread(0,
0,
UpdateLoop,
0,
CREATE_SUSPENDED,
&win32vars.update_loop_thread_id);
0,
UpdateLoop,
0,
CREATE_SUSPENDED,
&win32vars.update_loop_thread_id);
#endif
system_acquire_lock(FRAME_LOCK);
SetForegroundWindow(window_handle);
SetActiveWindow(window_handle);
ResumeThread(win32vars.update_loop_thread);
MSG msg;
for (;win32vars.input_chunk.pers.keep_playing && GetMessage(&msg, 0, 0, 0);){
if (msg.message == WM_QUIT){
system_acquire_lock(INPUT_LOCK);
win32vars.input_chunk.pers.keep_playing = 0;
system_release_lock(INPUT_LOCK);
}else{
TranslateMessage(&msg);
DispatchMessage(&msg);
for (;win32vars.input_chunk.pers.keep_playing;){
if (GetMessage(&msg, 0, 0, 0)){
if (msg.message == WM_QUIT){
//system_acquire_lock(INPUT_LOCK);
win32vars.input_chunk.pers.keep_playing = 0;
//system_release_lock(INPUT_LOCK);
}else{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
while (PeekMessage(&msg, 0, 0, 0, 1)){
if (msg.message == WM_QUIT){
//system_acquire_lock(INPUT_LOCK);
win32vars.input_chunk.pers.keep_playing = 0;
//system_release_lock(INPUT_LOCK);
}else{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
UpdateStep();
}
}
return 0;
return 0;
}
// BOTTOM