From c2206e5830e298e21c7940ac586f8587b4ad33ee Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Mon, 30 Nov 2015 21:51:53 -0500 Subject: [PATCH] starting new parser --- 4coder_custom.cpp | 35 -- 4coder_custom.h | 5 +- 4coder_helper.h | 57 ++- 4cpp_preprocessor.cpp | 39 +- 4ed.cpp | 37 +- 4ed.h | 20 +- 4ed_app_target.cpp | 61 +-- 4ed_color_view.cpp | 68 ++- 4ed_command.cpp | 35 +- 4ed_config.h | 52 +++ 4ed_debug_view.cpp | 10 +- 4ed_dll_reader.cpp | 378 ++++++++++++++++ 4ed_dll_reader.h | 441 +++++++++++++++++++ 4ed_file_view.cpp | 149 +++++-- 4ed_keyboard.cpp | 88 +--- 4ed_layout.cpp | 6 +- 4ed_linux_keyboard.cpp | 32 +- 4ed_math.cpp | 56 ++- 4ed_meta.h | 7 + 4ed_rendering.cpp | 912 +++++++++++++-------------------------- 4ed_rendering.h | 127 ++++-- 4ed_rendering_helper.cpp | 215 +++++++++ 4ed_rendering_old.cpp | 405 +++++++++++++++++ 4ed_style.cpp | 14 +- 4ed_system.h | 20 +- 4ed_win32_keyboard.cpp | 80 ++++ dll_reader.cpp | 206 +++++++++ linux_4ed.cpp | 146 +++---- test/dll_test.cpp | 37 ++ test/experiment.cpp | 64 ++- win32_4ed.cpp | 263 +++++------ 31 files changed, 2799 insertions(+), 1266 deletions(-) create mode 100644 4ed_config.h create mode 100644 4ed_dll_reader.cpp create mode 100644 4ed_dll_reader.h create mode 100644 4ed_rendering_helper.cpp create mode 100644 4ed_rendering_old.cpp create mode 100644 4ed_win32_keyboard.cpp create mode 100644 dll_reader.cpp create mode 100644 test/dll_test.cpp diff --git a/4coder_custom.cpp b/4coder_custom.cpp index 49d504e6..95faa706 100644 --- a/4coder_custom.cpp +++ b/4coder_custom.cpp @@ -2,41 +2,6 @@ * Example use of customization API */ -// NOTE(allen|a3.1): NEW THINGS TO LOOK FOR: -// mapid_user_custom - define maps other than the built in global and file maps -// -// inherit_map - override bindings or add new bindings in a new map with another -// -// set_hook - if you were using start_hook, it is still available if you use set_hook -// -// push_parameter - see description of parameter stack immediately below -// clear_parameters -// exec_command_keep_stack -// -// THE PARAMETER STACK: -// In this version I have introduced a parameter stack. -// Calls to commands through exec_command can now be parameterized -// by first pushing parameters onto that stack. This is achieved through -// the push_parameter. If you look at the signature for the function it -// uses a "Dynamic" struct, but 4coder_helper.h has overrides that accept -// ints or strings. The helper functions also take care of copying the -// strings inline into the stack so that you don't have to maintain your copy. -// -// If you'd like to optimize out the extra copy it will work, just use the -// main app.push_parameter and keep the memory of the string alive until -// the stack is cleared. -// -// A call to exec_command executes the command with the current stack, -// then clears the stack. To keep the stack use exec_command_keep_stack. -// -// If you would like to allocate your own memory, you can tie your memory -// to the parameter stack by calling push_memory which takes a cmd_context and len. -// It will return a char* to your memory block. Until you call clear_parameters -// or exec_command the memory will remain on the stack for you to use. Memory -// chunks on the stack are ignored by commands that use parameters, so your memory -// will not influence the behavior of any commands. -// - #include "4coder_custom.h" #include "4coder_helper.h" diff --git a/4coder_custom.h b/4coder_custom.h index 2836de11..e7abb8c3 100644 --- a/4coder_custom.h +++ b/4coder_custom.h @@ -3,6 +3,10 @@ #define MDFR_CTRL 1 #define MDFR_ALT 2 #define MDFR_SHIFT 4 +#define MDFR_NUMPAD 8 + +// NOTE(allen): These need not be used direct +#define MDFR_EXACT 128 typedef u16 Code; @@ -215,7 +219,6 @@ struct Buffer_Summary{ int file_id; int size; - const char *data; int file_name_len; int buffer_name_len; diff --git a/4coder_helper.h b/4coder_helper.h index 9e502b16..43639de9 100644 --- a/4coder_helper.h +++ b/4coder_helper.h @@ -92,34 +92,69 @@ end_map(Bind_Helper *helper){ helper->group = 0; } +struct Bind_Target{ + short code; + unsigned char modifiers; +}; + +inline Bind_Target +ekey(short code, unsigned char modifiers){ + Bind_Target target; + target.code = code; + target.modifiers = modifiers | MDFR_EXACT; + return target; +} + +inline Bind_Target +tkey(short code, unsigned char modifiers){ + Bind_Target target; + target.code = code; + target.modifiers = modifiers; + return target; +} + inline void -bind(Bind_Helper *helper, short code, unsigned char modifiers, int cmdid){ +bind(Bind_Helper *helper, Bind_Target target, int cmdid){ if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN; if (!helper->error) ++helper->group->map_begin.bind_count; Binding_Unit unit; unit.type = unit_binding; unit.binding.command_id = cmdid; - unit.binding.code = code; - unit.binding.modifiers = modifiers; + unit.binding.code = target.code; + unit.binding.modifiers = target.modifiers; write_unit(helper, unit); } inline void -bind_me(Bind_Helper *helper, short code, unsigned char modifiers, Custom_Command_Function *func){ +bind_me(Bind_Helper *helper, Bind_Target target, Custom_Command_Function *func){ if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN; if (!helper->error) ++helper->group->map_begin.bind_count; Binding_Unit unit; unit.type = unit_callback; unit.callback.func = func; - unit.callback.code = code; - unit.callback.modifiers = modifiers; + unit.callback.code = target.code; + unit.callback.modifiers = target.modifiers; write_unit(helper, unit); } +inline void +bind(Bind_Helper *helper, short code, unsigned char modifiers, int cmdid){ + Bind_Target target; + target.code = tkey(code, modifiers); + bind(helper, target, cmdid); +} + +inline void +bind_me(Bind_Helper *helper, short code, unsigned char modifiers, Custom_Command_Function *func){ + Bind_Target target; + target.code = tkey(code, modifiers); + bind_me(helper, target, func); +} + inline void bind_vanilla_keys(Bind_Helper *helper, int cmdid){ bind(helper, 0, 0, cmdid); @@ -130,6 +165,16 @@ bind_me_vanilla_keys(Bind_Helper *helper, Custom_Command_Function *func){ bind_me(helper, 0, 0, func); } +inline void +bind_vanilla_keys(Bind_Helper *helper, unsigned char modifiers, int cmdid){ + bind(helper, 0, modifiers, cmdid); +} + +inline void +bind_me_vanilla_keys(Bind_Helper *helper, unsigned char modifiers, Custom_Command_Function *func){ + bind_me(helper, 0, modifiers, func); +} + inline void inherit_map(Bind_Helper *helper, int mapid){ if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN; diff --git a/4cpp_preprocessor.cpp b/4cpp_preprocessor.cpp index b5376846..cbbb685e 100644 --- a/4cpp_preprocessor.cpp +++ b/4cpp_preprocessor.cpp @@ -107,8 +107,7 @@ table_copy(Table *table_src, Table *table_dst){ } } -// TODO(allen): File_Data not Parse_File -struct Cpp_Parse_File{ +struct Cpp_File_Data{ Cpp_File file; Cpp_Token_Stack tokens; String filename; @@ -124,7 +123,7 @@ struct Cpp_Macro_Data{ }; union Cpp_Def_Slot{ - Cpp_Parse_File file; + Cpp_File_Data file; Cpp_Macro_Data macro; }; @@ -289,13 +288,13 @@ cpp_get_memory_request(Cpp_Preproc_State *state, Cpp_Parse_Definitions *definiti return request; } -internal Cpp_Parse_File* +internal Cpp_File_Data* cpp_get_parse_file(Cpp_Parse_Definitions *definitions, int file_index){ return &definitions->slots[file_index].file; } internal void -cpp_set_parse_file(Cpp_Parse_Definitions *definitions, int file_index, Cpp_Parse_File file){ +cpp_set_parse_file(Cpp_Parse_Definitions *definitions, int file_index, Cpp_File_Data file){ definitions->slots[file_index].file = file; } @@ -328,7 +327,7 @@ cpp_provide_memory(Cpp_Memory_Request request, void *memory){ Cpp_Parse_Definitions *definitions = request.definitions; int size = request.size >> 1; - Cpp_Parse_File new_file = {}; + Cpp_File_Data new_file = {}; new_file.tokens.tokens = (Cpp_Token*)memory; new_file.tokens.max_count = size / sizeof(Cpp_Token); new_file.file.data = ((char*)memory) + size; @@ -514,7 +513,7 @@ struct Preserve_Checkpoint{ internal Preserve_Checkpoint cpp__checkpoint_preserve_write(Cpp_Parse_Definitions *definitions){ - Cpp_Parse_File *file = cpp_get_parse_file(definitions, definitions->string_file_index); + Cpp_File_Data *file = cpp_get_parse_file(definitions, definitions->string_file_index); Preserve_Checkpoint check; check.start_write_pos = definitions->string_write_pos; check.start_token_count = file->tokens.count; @@ -524,14 +523,14 @@ cpp__checkpoint_preserve_write(Cpp_Parse_Definitions *definitions){ internal void cpp__restore_preserve_write(Cpp_Parse_Definitions *definitions, Preserve_Checkpoint check){ - Cpp_Parse_File *file = cpp_get_parse_file(definitions, definitions->string_file_index); + Cpp_File_Data *file = cpp_get_parse_file(definitions, definitions->string_file_index); definitions->string_write_pos = check.start_write_pos; file->tokens.count = check.start_token_count; } internal void cpp__preserve_string(Cpp_Parse_Definitions *definitions, String string){ - Cpp_Parse_File *string_file = cpp_get_parse_file(definitions, definitions->string_file_index); + Cpp_File_Data *string_file = cpp_get_parse_file(definitions, definitions->string_file_index); _Assert(string_file->file.size - definitions->string_write_pos >= string.size); copy_fast_unsafe(string_file->file.data + definitions->string_write_pos, string); definitions->string_write_pos += string.size; @@ -539,7 +538,7 @@ cpp__preserve_string(Cpp_Parse_Definitions *definitions, String string){ internal Cpp_Loose_Token cpp__preserve_token(Cpp_Parse_Definitions *definitions, Cpp_Token token){ - Cpp_Parse_File *string_file = cpp_get_parse_file(definitions, definitions->string_file_index); + Cpp_File_Data *string_file = cpp_get_parse_file(definitions, definitions->string_file_index); _Assert(string_file->tokens.count < string_file->tokens.max_count); Cpp_Loose_Token loose; loose.file_index = definitions->string_file_index; @@ -552,7 +551,7 @@ cpp__preserve_token(Cpp_Parse_Definitions *definitions, Cpp_Token token){ internal void cpp__preserve_string(Preserve_Checkpoint *check, Cpp_Parse_Definitions *definitions, String string){ if (!check->out_of_memory){ - Cpp_Parse_File *string_file = cpp_get_parse_file(definitions, definitions->string_file_index); + Cpp_File_Data *string_file = cpp_get_parse_file(definitions, definitions->string_file_index); if (string_file->file.size - definitions->string_write_pos >= string.size){ copy_fast_unsafe(string_file->file.data + definitions->string_write_pos, string); definitions->string_write_pos += string.size; @@ -567,7 +566,7 @@ internal Cpp_Loose_Token cpp__preserve_token(Preserve_Checkpoint *check, Cpp_Parse_Definitions *definitions, Cpp_Token token){ Cpp_Loose_Token loose = {}; if (!check->out_of_memory){ - Cpp_Parse_File *string_file = cpp_get_parse_file(definitions, definitions->string_file_index); + Cpp_File_Data *string_file = cpp_get_parse_file(definitions, definitions->string_file_index); if (string_file->tokens.count < string_file->tokens.max_count){ loose.file_index = definitions->string_file_index; loose.token_index = string_file->tokens.count; @@ -913,7 +912,7 @@ cpp__preproc_normal_step_nonalloc(Cpp_Preproc_State *state, Cpp_Parse_Definition } Cpp_Visit visit = {}; - Cpp_Parse_File visit_file; + Cpp_File_Data visit_file; Cpp_Token visit_token; if (expansion->out_type == EXPAN_NORMAL){ @@ -1353,7 +1352,7 @@ cpp__preproc_normal_step_nonalloc(Cpp_Preproc_State *state, Cpp_Parse_Definition bool variadic = 0; if (macro->param_count != 0){ int macro_file_index = macro->file_index; - Cpp_Parse_File file = *cpp_get_parse_file(definitions, macro_file_index); + Cpp_File_Data file = *cpp_get_parse_file(definitions, macro_file_index); int i = macro->first_param_index; Cpp_Token token = file.tokens.tokens[i]; for (;;){ @@ -1461,13 +1460,13 @@ cpp__preproc_normal_step_nonalloc(Cpp_Preproc_State *state, Cpp_Parse_Definition internal int cpp__get_parameter_i(Cpp_Preproc_State *state, Cpp_Parse_Definitions * definitions, - Cpp_Parse_File *macro_file, Cpp_Token token, int param_start, int param_count){ + Cpp_File_Data *macro_file, Cpp_Token token, int param_start, int param_count){ int param_i = -1; if (token.type == CPP_TOKEN_IDENTIFIER){ String token_str = make_string(macro_file->file.data + token.start, token.size); for (int j = 0; j < param_count; ++j){ Cpp_Loose_Token param_loose = state->tokens.tokens[j + param_start]; - Cpp_Parse_File *file = cpp_get_parse_file(definitions, param_loose.file_index); + Cpp_File_Data *file = cpp_get_parse_file(definitions, param_loose.file_index); Cpp_Token param_token = file->tokens.tokens[param_loose.token_index]; String param_str = make_string(file->file.data + param_token.start, param_token.size); if (match(token_str, param_str)){ @@ -1486,7 +1485,7 @@ cpp__preproc_big_step_nonalloc(Cpp_Preproc_State *state, Cpp_Parse_Definitions * Cpp_Expansion *expansion = state->expansions + state->expansion_level; Cpp_Macro_Data macro = *cpp_get_macro_data(definitions, expansion->file_index); - Cpp_Parse_File *macro_file = cpp_get_parse_file(definitions, macro.file_index); + Cpp_File_Data *macro_file = cpp_get_parse_file(definitions, macro.file_index); switch (expansion->out_type){ case EXPAN_BIG_PROCESS_ARGS: { @@ -1667,7 +1666,7 @@ cpp__preproc_big_step_nonalloc(Cpp_Preproc_State *state, Cpp_Parse_Definitions * cpp__push_loose_token(&checkpoint, state, loose.file_index, loose.token_index, loose.blocked); } Cpp_Loose_Token loose = state->tokens.tokens[j]; - Cpp_Parse_File *end_file = cpp_get_parse_file(definitions, loose.file_index); + Cpp_File_Data *end_file = cpp_get_parse_file(definitions, loose.file_index); Cpp_Token end_token = end_file->tokens.tokens[loose.token_index]; String end_string = make_string(end_file->file.data + end_token.start, end_token.size); cpp__spare_write(&str_checkpoint, state, end_string); @@ -1683,7 +1682,7 @@ cpp__preproc_big_step_nonalloc(Cpp_Preproc_State *state, Cpp_Parse_Definitions * if (range.start < range.end){ int j = range.start; Cpp_Loose_Token loose = state->tokens.tokens[j]; - Cpp_Parse_File *start_file = cpp_get_parse_file(definitions, loose.file_index); + Cpp_File_Data *start_file = cpp_get_parse_file(definitions, loose.file_index); Cpp_Token start_token = start_file->tokens.tokens[loose.token_index]; String start_string = make_string(start_file->file.data + start_token.start, start_token.size); cpp__spare_write(&str_checkpoint, state, start_string); @@ -1860,7 +1859,7 @@ cpp__preproc_strfy_step_nonalloc(Cpp_Preproc_State *state, Cpp_Parse_Definitions Spare_String_Checkpoint checkpoint = cpp__checkpoint_spare_string(state); if (do_body){ - Cpp_Parse_File visit_file; + Cpp_File_Data visit_file; Cpp_Token visit_token; visit_file = *cpp_get_parse_file(definitions, visit.file_index); diff --git a/4ed.cpp b/4ed.cpp index a3b05add..fc258873 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -112,12 +112,9 @@ app_get_map_index(App_Vars *vars, i32 mapid){ internal Command_Map* app_get_map(App_Vars *vars, i32 mapid){ Command_Map *map = 0; - if (mapid >= mapid_user_custom) - map = vars->user_maps + mapid - mapid_user_custom; - else if (mapid == mapid_global) - map = &vars->map_top; - else if (mapid == mapid_file) - map = &vars->map_file; + if (mapid >= mapid_user_custom) map = vars->user_maps + mapid - mapid_user_custom; + else if (mapid == mapid_global) map = &vars->map_top; + else if (mapid == mapid_file) map = &vars->map_file; return map; } @@ -740,7 +737,7 @@ app_open_file(System_Functions *system, new_view->map = app_get_map(vars, target_file->base_map_id); #if BUFFER_EXPERIMENT_SCALPEL <= 0 - if (created_file && target_file->tokens_exist) + if (created_file && target_file->tokens_exist && target_file->token_stack.tokens == 0) file_first_lex_parallel(system, &mem->general, target_file); #endif } @@ -1690,7 +1687,6 @@ extern "C"{ Working_Set *working_set = cmd->working_set; buffer.file_id = (int)(file - working_set->files); buffer.size = file->buffer.size; - buffer.data = (const char*)file->buffer.data; buffer.file_name_len = file->source_path.size; buffer.buffer_name_len = file->live_name.size; buffer.file_name = file->source_path.str; @@ -1990,7 +1986,7 @@ app_hardcode_styles(App_Vars *vars){ styles = vars->styles.styles; style = styles; - Font *fonts = vars->fonts.fonts; + Render_Font *fonts = vars->fonts.fonts; ///////////////// style_set_name(style, make_lit_string("4coder")); @@ -2206,10 +2202,11 @@ app_hardcode_styles(App_Vars *vars){ } internal bool32 -app_load_font(System_Functions *system, - Font *font, char *filename, i32 size, void *memory, +app_load_font(Render_Target *target, System_Functions *system, + Render_Font *font, char *filename, i32 size, void *memory, i32 *used, i32 tab_width, String name){ - if (font_load(system, font, filename, size, memory, font_predict_size(size), used, tab_width)){ + if (font_load(target, system, font, filename, size, memory, + font_predict_size(size), used, tab_width)){ font->loaded = 1; font->name_[ArrayCount(font->name_)-1] = 0; font->name = make_string(font->name_, 0, ArrayCount(font->name_)-1); @@ -2453,45 +2450,43 @@ external App_Init_Sig(app_init){ vars->hooks[hook_open_file] = default_open_file_hook; } - if (!font_init()) return 0; - vars->fonts.max = 6; - vars->fonts.fonts = push_array(partition, Font, vars->fonts.max); + vars->fonts.fonts = push_array(partition, Render_Font, vars->fonts.max); { i32 font_count = 0; i32 memory_used; memory_used = 0; - app_load_font(system, + app_load_font(target, system, vars->fonts.fonts + font_count++, "liberation-mono.ttf", 17, partition_current(partition), &memory_used, 4, make_lit_string("liberation mono")); push_block(partition, memory_used); memory_used = 0; - app_load_font(system, + app_load_font(target, system, vars->fonts.fonts + font_count++, "LiberationSans-Regular.ttf", 17, partition_current(partition), &memory_used, 4, make_lit_string("liberation sans")); push_block(partition, memory_used); memory_used = 0; - app_load_font(system, + app_load_font(target, system, vars->fonts.fonts + font_count++, "Hack-Regular.ttf", 17, partition_current(partition), &memory_used, 4, make_lit_string("hack")); push_block(partition, memory_used); memory_used = 0; - app_load_font(system, + app_load_font(target, system, vars->fonts.fonts + font_count++, "CutiveMono-Regular.ttf", 17, partition_current(partition), &memory_used, 4, make_lit_string("cutive mono")); push_block(partition, memory_used); memory_used = 0; - app_load_font(system, + app_load_font(target, system, vars->fonts.fonts + font_count++, "Inconsolata-Regular.ttf", 17, partition_current(partition), &memory_used, 4, make_lit_string("inconsolata")); @@ -2502,7 +2497,7 @@ external App_Init_Sig(app_init){ extra.size = 17; vars->config_api.set_extra_font(&extra); memory_used = 0; - if (app_load_font(system, + if (app_load_font(target, system, vars->fonts.fonts + font_count, extra.file_name, extra.size, partition_current(partition), &memory_used, 4, make_string_slowly(extra.font_name))){ diff --git a/4ed.h b/4ed.h index 0d083c46..30b24553 100644 --- a/4ed.h +++ b/4ed.h @@ -12,23 +12,6 @@ #ifndef FRED_H #define FRED_H -#if SOFTWARE_RENDER -struct Render_Target{ - void *pixel_data; - i32 width, height, pitch; -}; -#else -struct Render_Target{ - void *handle; - void *context; - i32_Rect clip_boxes[5]; - i32 clip_top; - i32 width, height; - i32 bound_texture; - u32 color; -}; -#endif - struct Application_Memory{ void *vars_memory; i32 vars_memory_size; @@ -118,6 +101,7 @@ struct Thread_Context; #define App_Init_Sig(name) \ b32 name(System_Functions *system, \ + Render_Target *target, \ Application_Memory *memory, \ Key_Codes *loose_codes, \ Clipboard_Contents clipboard, \ @@ -137,7 +121,7 @@ enum Application_Mouse_Cursor{ struct Application_Step_Result{ Application_Mouse_Cursor mouse_cursor_type; - b32 redraw; + b32 redraw; }; #define App_Step_Sig(name) Application_Step_Result \ diff --git a/4ed_app_target.cpp b/4ed_app_target.cpp index 45e3494d..124baa15 100644 --- a/4ed_app_target.cpp +++ b/4ed_app_target.cpp @@ -1,7 +1,7 @@ /* * Mr. 4th Dimention - Allen Webster * - * 13.11.2014 + * 13.11.2015 * * Application layer build target * @@ -9,50 +9,7 @@ // TOP -#ifdef FRED_NOT_PACKAGE - -#define FRED_INTERNAL 1 -#define FRED_SLOW 1 - -#define FRED_PRINT_DEBUG 1 -#define FRED_PRINT_DEBUG_FILE_LINE 0 -#define FRED_PROFILING 1 -#define FRED_PROFILING_OS 0 -#define FRED_FULL_ERRORS 0 - -#else - -#define FRED_SLOW 0 -#define FRED_INTERNAL 0 - -#define FRED_PRINT_DEBUG 0 -#define FRED_PRINT_DEBUG_FILE_LINE 0 -#define FRED_PROFILING 0 -#define FRED_PROFILING_OS 0 -#define FRED_FULL_ERRORS 0 - -#endif - -#define SOFTWARE_RENDER 0 - -#if FRED_INTERNAL == 0 -#undef FRED_PRINT_DEBUG -#define FRED_PRINT_DEBUG 0 -#undef FRED_PROFILING -#define FRED_PROFILING 0 -#undef FRED_PROFILING_OS -#define FRED_PROFILING_OS 0 -#endif - -#if FRED_PRINT_DEBUG == 0 -#undef FRED_PRINT_DEBUG_FILE_LINE -#define FRED_PRINT_DEBUG_FILE_LINE 0 -#undef FRED_PRINT_DEBUG_FILE_LINE -#define FRED_PROFILING_OS 0 -#endif - -#define FPS 30 -#define FRAME_TIME (1000000 / FPS) +#include "4ed_config.h" #define BUFFER_EXPERIMENT_SCALPEL 0 @@ -67,25 +24,15 @@ #include "4ed_math.cpp" #include "4coder_custom.h" #include "4ed_system.h" -#include "4ed.h" #include "4ed_rendering.h" - -#if defined(_WIN32) -# include -# include -#elif defined(__linux__) -# include -# include -#else -# error UNSUPPORTED PLATFORM -#endif +#include "4ed.h" #include "4ed_internal.h" #define FCPP_LEXER_IMPLEMENTATION #include "4cpp_lexer.h" -#include "4ed_rendering.cpp" +#include "4ed_rendering_helper.cpp" #include "4ed_command.cpp" #include "4ed_layout.cpp" #include "4ed_style.cpp" diff --git a/4ed_color_view.cpp b/4ed_color_view.cpp index d0058659..a50a82e1 100644 --- a/4ed_color_view.cpp +++ b/4ed_color_view.cpp @@ -125,14 +125,14 @@ view_to_color_view(View *view){ internal void draw_gradient_slider(Render_Target *target, Vec4 base, i32 channel, - i32 steps, real32 top, real32_Rect slider, bool32 hsla){ + i32 steps, f32 top, f32_Rect slider, b32 hsla){ Vec4 low, high; - real32 *lowv, *highv; - real32 x; - real32 next_x; - real32 x_step; - real32 v_step; - real32 m; + f32 *lowv, *highv; + f32 x; + f32 next_x; + f32 x_step; + f32 v_step; + f32 m; x = (real32)slider.x0; x_step = (real32)(slider.x1 - slider.x0) / steps; @@ -176,21 +176,21 @@ draw_gradient_slider(Render_Target *target, Vec4 base, i32 channel, } inline void -draw_hsl_slider(Render_Target *target, Vec4 base, i32 channel, i32 steps, real32 top, - real32_Rect slider){ +draw_hsl_slider(Render_Target *target, Vec4 base, i32 channel, + i32 steps, real32 top, f32_Rect slider){ draw_gradient_slider(target, base, channel, steps, top, slider, 1); } inline void -draw_rgb_slider(Render_Target *target, Vec4 base, i32 channel, i32 steps, real32 top, - real32_Rect slider){ +draw_rgb_slider(Render_Target *target, Vec4 base, i32 channel, + i32 steps, f32 top, f32_Rect slider){ draw_gradient_slider(target, base, channel, steps, top, slider, 0); } internal void do_label(UI_State *state, UI_Layout *layout, char *text, real32 height = 2.f){ Style *style = state->style; - Font *font = style->font; + Render_Font *font = style->font; i32_Rect label = layout_rect(layout, FLOOR32(font->height * height)); if (!state->input_stage){ @@ -274,7 +274,6 @@ do_scroll_bar(UI_State *state, i32_Rect rect){ get_colors(state, &back, &fore, wid, ui_style); draw_rectangle(target, top_arrow, back); draw_rectangle_outline(target, top_arrow, outline); - draw_triangle_3corner(target, x0, y0, x1, y1, x2, y2, fore); ++wid.sub_id2; y0 = (w_2_3 + bottom_arrow.y0); @@ -283,7 +282,6 @@ do_scroll_bar(UI_State *state, i32_Rect rect){ get_colors(state, &back, &fore, wid, ui_style); draw_rectangle(target, bottom_arrow, back); draw_rectangle_outline(target, bottom_arrow, outline); - draw_triangle_3corner(target, x0, y0, x1, y1, x2, y2, fore); ++wid.sub_id2; get_colors(state, &back, &fore, wid, ui_style); @@ -295,10 +293,10 @@ do_scroll_bar(UI_State *state, i32_Rect rect){ } internal void -do_single_slider(i32 sub_id, Color_UI *ui, i32 channel, bool32 is_rgba, - i32 grad_steps, real32 top, real32_Rect slider, real32 v_handle, +do_single_slider(i32 sub_id, Color_UI *ui, i32 channel, b32 is_rgba, + i32 grad_steps, f32 top, f32_Rect slider, f32 v_handle, i32_Rect rect){ - real32_Rect click_box = slider; + f32_Rect click_box = slider; click_box.y0 -= v_handle; if (ui->state.input_stage){ @@ -349,7 +347,7 @@ internal void do_hsl_sliders(Color_UI *ui, i32_Rect rect){ real32 bar_width = (real32)(rect.x1 - rect.x0 - 20); if (bar_width > 45){ - real32_Rect slider; + f32_Rect slider; real32 y; i32 sub_id; @@ -410,7 +408,7 @@ do_channel_field(i32 sub_id, Color_UI *ui, u8 *channel, Channel_Field_Type ftype i32 y, u32 color, u32 back, i32 x0, i32 x1){ bool32 result = 0; Render_Target *target = ui->state.target; - Font *font = ui->state.font; + Render_Font *font = ui->state.font; i32_Rect hit_region; hit_region.x0 = x0; @@ -509,7 +507,7 @@ do_channel_field(i32 sub_id, Color_UI *ui, u8 *channel, Channel_Field_Type ftype } } else{ - real32_Rect r = f32R(hit_region); + f32_Rect r = f32R(hit_region); r.x0 += indx*ui->hex_advance+1; r.x1 = r.x0+ui->hex_advance+1; draw_rectangle(target, r, back); @@ -537,8 +535,8 @@ do_rgb_sliders(Color_UI *ui, i32_Rect rect){ rect.x0 = hex_x1; real32 bar_width = (real32)(rect.x1 - rect.x0 - 20); - real32_Rect slider; - real32 y; + f32_Rect slider; + f32 y; i32 sub_id; u8 channel; @@ -603,7 +601,7 @@ begin_layout(Blob_Layout *layout, i32_Rect rect){ internal void do_blob(Color_UI *ui, Blob_Layout *layout, u32 color, bool32 *set_me, i32 sub_id){ i32_Rect rect = layout->rect; - real32_Rect blob; + f32_Rect blob; blob.x0 = (real32)layout->x; blob.y0 = (real32)layout->y; blob.x1 = blob.x0 + layout->size; @@ -690,7 +688,7 @@ do_palette(Color_UI *ui, i32_Rect rect){ if (!ui->state.input_stage){ Render_Target *target = ui->state.target; - Font *font = style->font; + Render_Font *font = style->font; draw_string(target, font, "Global Palette: right click to save color", layout.x, layout.rect.y0, style->main.default_color); } @@ -711,7 +709,7 @@ do_palette(Color_UI *ui, i32_Rect rect){ internal void do_sub_button(i32 id, Color_UI *ui, char *text){ - Font *font = ui->state.font; + Render_Font *font = ui->state.font; i32_Rect rect = layout_rect(&ui->layout, font->height + 2); @@ -743,7 +741,7 @@ do_color_adjuster(Color_UI *ui, u32 *color, u32 text_color, u32 back_color, char *name){ i32 id = raw_ptr_dif(color, ui->state.style); Render_Target *target = ui->state.target; - Font *font = ui->state.font; + Render_Font *font = ui->state.font; i32 character_h = font->height; u32 text = 0, back = 0; @@ -832,7 +830,7 @@ do_color_adjuster(Color_UI *ui, u32 *color, internal void do_style_name(Color_UI *ui){ i32 id = -3; - Font *font = ui->state.font; + Render_Font *font = ui->state.font; i32_Rect srect = layout_rect(&ui->layout, font->height); @@ -878,7 +876,7 @@ do_style_name(Color_UI *ui){ } internal bool32 -do_font_option(Color_UI *ui, Font *font){ +do_font_option(Color_UI *ui, Render_Font *font){ bool32 result = 0; i32 sub_id = (i32)(font); i32_Rect orect = layout_rect(&ui->layout, font->height); @@ -915,7 +913,7 @@ internal void do_font_switch(Color_UI *ui){ i32 id = -2; Render_Target *target = ui->state.target; - Font *font = ui->state.font; + Render_Font *font = ui->state.font; i32 character_h = font->height; i32_Rect srect = layout_rect(&ui->layout, character_h); @@ -946,7 +944,7 @@ do_font_switch(Color_UI *ui){ if (is_selected(&ui->state, wid)){ Font_Set *fonts = ui->fonts; - Font *font_opt = fonts->fonts; + Render_Font *font_opt = fonts->fonts; i32 count = fonts->count; srect = layout_rect(&ui->layout, character_h/2); if (!ui->state.input_stage) @@ -1188,7 +1186,7 @@ update_highlighting(Color_View *color_view){ internal bool32 do_style_preview(Library_UI *ui, Style *style, i32 toggle = -1){ bool32 result = 0; - Font *font = style->font; + Render_Font *font = style->font; i32 id; if (style == ui->state.style) id = 2; else id = raw_ptr_dif(style, ui->styles->styles) + 100; @@ -1275,7 +1273,7 @@ internal bool32 do_main_file_box(System_Functions *system, UI_State *state, UI_Layout *layout, Hot_Directory *hot_directory, char *end = 0){ bool32 result = 0; Style *style = state->style; - Font *font = style->font; + Render_Font *font = style->font; i32_Rect box = layout_rect(layout, font->height + 2); String *string = &hot_directory->string; @@ -1303,7 +1301,7 @@ internal bool32 do_main_string_box(System_Functions *system, UI_State *state, UI_Layout *layout, String *string){ bool32 result = 0; Style *style = state->style; - Font *font = style->font; + Render_Font *font = style->font; i32_Rect box = layout_rect(layout, font->height + 2); if (state->input_stage){ @@ -1328,7 +1326,7 @@ internal bool32 do_list_option(i32 id, UI_State *state, UI_Layout *layout, String text){ bool32 result = 0; Style *style = state->style; - Font *font = style->font; + Render_Font *font = style->font; i32 character_h = font->height; i32_Rect box = layout_rect(layout, font->height*2); @@ -1365,7 +1363,7 @@ internal bool32 do_file_option(i32 id, UI_State *state, UI_Layout *layout, String filename, bool32 is_folder, String extra){ bool32 result = 0; Style *style = state->style; - Font *font = style->font; + Render_Font *font = style->font; i32 character_h = font->height; i32_Rect box = layout_rect(layout, font->height*2); diff --git a/4ed_command.cpp b/4ed_command.cpp index d720c226..0e037d3b 100644 --- a/4ed_command.cpp +++ b/4ed_command.cpp @@ -9,8 +9,12 @@ // TOP -typedef void (*Command_Function)(System_Functions *system, - struct Command_Data *command, struct Command_Binding binding); +#define Command_Function_Sig(name) void (name)( \ + System_Functions *system, \ + struct Command_Data *command, \ + struct Command_Binding binding) + +typedef Command_Function_Sig(*Command_Function); struct Command_Binding{ Command_Function function; @@ -29,12 +33,13 @@ internal void command_null(Command_Data *command); internal i64 map_hash(u16 event_code, u8 modifiers){ - i64 result = (event_code << 4) | modifiers; + i64 result = (event_code << 8) | modifiers; return result; } internal b32 -map_add(Command_Map *map, u16 event_code, u8 modifiers, Command_Function function, Custom_Command_Function *custom = 0){ +map_add(Command_Map *map, u16 event_code, u8 modifiers, Command_Function function, + Custom_Command_Function *custom = 0){ Assert(map->count * 8 < map->max * 7); Command_Binding bind; bind.function = function; @@ -115,21 +120,33 @@ internal Command_Binding map_extract(Command_Map *map, Key_Single key){ Command_Binding bind = {}; - u8 command = MDFR_NONE; b32 ctrl = key.modifiers[CONTROL_KEY_CONTROL]; b32 alt = key.modifiers[CONTROL_KEY_ALT]; b32 shift = key.modifiers[CONTROL_KEY_SHIFT] && key.key.loose_keycode; + u16 code; + u8 command = MDFR_NONE; if (shift) command |= MDFR_SHIFT; if (ctrl) command |= MDFR_CTRL; if (alt) command |= MDFR_ALT; - u16 code = key.key.character_no_caps_lock; - if (code == 0) code = key.key.keycode; + command |= MDFR_EXACT; + code = key.key.keycode; map_find(map, code, command, &bind); - if (bind.function == 0 && key.key.character_no_caps_lock != 0){ - map_get_vanilla_keyboard_default(map, command, &bind); + command &= ~(MDFR_EXACT); + code = key.key.character_no_caps_lock; + if (code == 0){ + code = key.key.keycode; + map_find(map, code, command, &bind); + } + else{ + command &= ~(MDFR_SHIFT); + + map_find(map, code, command, &bind); + if (bind.function == 0){ + map_get_vanilla_keyboard_default(map, command, &bind); + } } return bind; diff --git a/4ed_config.h b/4ed_config.h new file mode 100644 index 00000000..4b09fb1a --- /dev/null +++ b/4ed_config.h @@ -0,0 +1,52 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 13.11.2014 + * + * Application layer build target + * + */ + +// TOP + +#ifdef FRED_NOT_PACKAGE + +#define FRED_INTERNAL 1 +#define FRED_SLOW 1 + +#define FRED_PRINT_DEBUG 1 +#define FRED_PRINT_DEBUG_FILE_LINE 0 +#define FRED_PROFILING 1 +#define FRED_PROFILING_OS 0 +#define FRED_FULL_ERRORS 0 + +#else + +#define FRED_SLOW 0 +#define FRED_INTERNAL 0 + +#define FRED_PRINT_DEBUG 0 +#define FRED_PRINT_DEBUG_FILE_LINE 0 +#define FRED_PROFILING 0 +#define FRED_PROFILING_OS 0 +#define FRED_FULL_ERRORS 0 + +#endif + +#if FRED_INTERNAL == 0 +#undef FRED_PRINT_DEBUG +#define FRED_PRINT_DEBUG 0 +#undef FRED_PROFILING +#define FRED_PROFILING 0 +#undef FRED_PROFILING_OS +#define FRED_PROFILING_OS 0 +#endif + +#if FRED_PRINT_DEBUG == 0 +#undef FRED_PRINT_DEBUG_FILE_LINE +#define FRED_PRINT_DEBUG_FILE_LINE 0 +#undef FRED_PRINT_DEBUG_FILE_LINE +#define FRED_PROFILING_OS 0 +#endif + +// BOTTOM diff --git a/4ed_debug_view.cpp b/4ed_debug_view.cpp index 71dbee05..a26495fc 100644 --- a/4ed_debug_view.cpp +++ b/4ed_debug_view.cpp @@ -23,7 +23,7 @@ struct Dbg_Past_Key{ struct Debug_View{ View view_base; - Font *font; + Render_Font *font; Debug_Mode mode; Dbg_Past_Key past_keys[32]; i32 past_key_count, past_key_pos; @@ -38,7 +38,7 @@ view_to_debug_view(View *view){ internal i32 draw_general_memory(Debug_View *view, i32_Rect rect, Render_Target *target, i32 y){ - Font *font = view->font; + Render_Font *font = view->font; i32 y_advance = font->height; Bubble *sentinel = &view->view_base.mem->general.sentinel; @@ -94,7 +94,7 @@ draw_general_memory(Debug_View *view, i32_Rect rect, Render_Target *target, i32 internal i32 draw_system_memory(System_Functions *system, Debug_View *view, i32_Rect rect, Render_Target *target, i32 y){ - Font *font = view->font; + Render_Font *font = view->font; i32 y_advance = font->height; Bubble *sentinel = system->internal_sentinel(); @@ -182,7 +182,7 @@ draw_modifiers(Debug_View *view, Render_Target *target, internal i32 draw_key_event(Debug_View *view, Render_Target *target, Dbg_Past_Key *key, i32 x, i32 y, u32 on_color, u32 off_color){ - Font *font = view->font; + Render_Font *font = view->font; draw_modifiers(view, target, key->modifiers, on_color, off_color, &x, y); @@ -213,7 +213,7 @@ draw_os_events(Debug_View *view, i32_Rect rect, Render_Target *target, x = rect.x0; y = rect.y0; - Font *font = view->font; + Render_Font *font = view->font; draw_modifiers(view, target, active_input->keys.modifiers, 0xFFFFFFFF, 0xFF444444, &x, y); diff --git a/4ed_dll_reader.cpp b/4ed_dll_reader.cpp new file mode 100644 index 00000000..ac1adeb0 --- /dev/null +++ b/4ed_dll_reader.cpp @@ -0,0 +1,378 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 20.11.2015 + * + * DLL loader declarations for 4coder + * + */ + +// TOP + +// TODO(allen): +// Check the relocation table, if it contains anything that +// is platform specific generate an error to avoid calling +// into invalid code. + +i32 +dll_compare(char *a, char *b, i32 len){ + i32 result; + char *e; + + result = 0; + e = a + len; + for (;a < e && *a == *b; ++a, ++b); + if (a < e){ + if (*a < *b) result = -1; + else result = 1; + } + + return(result); +} + +enum DLL_Error{ + dll_err_too_small_for_header = 1, + dll_err_wrong_MZ_signature, + dll_err_wrong_DOS_error, + dll_err_wrong_PE_signature, + dll_err_unrecognized_bit_signature, +}; + +b32 +dll_parse_headers(Data file, DLL_Data *dll, i32 *error){ + b32 result; + i32 pe_offset; + i32 read_pos; + + result = 1; + if (file.size <= sizeof(DOS_Header) + DOS_error_size){ + if (error) *error = dll_err_too_small_for_header; + result = 0; + goto dll_parse_end; + } + + dll->dos_header = (DOS_Header*)file.data; + + if (dll_compare(dll->dos_header->signature, "MZ", 2) != 0){ + if (error) *error = dll_err_wrong_MZ_signature; + result = 0; + goto dll_parse_end; + } + + if (file.size <= DOS_error_offset + DOS_error_size){ + if (error) *error = dll_err_too_small_for_header; + result = 0; + goto dll_parse_end; + } + + if (dll_compare((char*)(file.data + DOS_error_offset), DOS_error_message, + sizeof(DOS_error_message) - 1) != 0){ + if (error) *error = dll_err_wrong_DOS_error; + result = 0; + goto dll_parse_end; + } + + pe_offset = dll->dos_header->e_lfanew; + read_pos = pe_offset; + + if (file.size <= read_pos + PE_header_size){ + if (error) *error = dll_err_too_small_for_header; + result = 0; + goto dll_parse_end; + } + + if (dll_compare((char*)(file.data + read_pos), + PE_header, PE_header_size) != 0){ + if (error) *error = dll_err_wrong_PE_signature; + result = 0; + goto dll_parse_end; + } + + read_pos += PE_header_size; + + if (file.size <= read_pos + sizeof(COFF_Header)){ + if (error) *error = dll_err_too_small_for_header; + result = 0; + goto dll_parse_end; + } + + dll->coff_header = (COFF_Header*)(file.data + read_pos); + read_pos += sizeof(COFF_Header); + + if (file.size <= read_pos + dll->coff_header->size_of_optional_header){ + if (error) *error = dll_err_too_small_for_header; + result = 0; + goto dll_parse_end; + } + + dll->opt_header_32 = (PE_Opt_Header_32Bit*)(file.data + read_pos); + dll->opt_header_64 = (PE_Opt_Header_64Bit*)(file.data + read_pos); + read_pos += dll->coff_header->size_of_optional_header; + + if (dll->opt_header_32->signature != bitsig_32bit && + dll->opt_header_32->signature != bitsig_64bit){ + if (error) *error = dll_err_unrecognized_bit_signature; + result = 0; + goto dll_parse_end; + } + + if (dll->opt_header_32->signature == bitsig_32bit) dll->is_64bit = 0; + else dll->is_64bit = 1; + + dll->section_defs = (PE_Section_Definition*)(file.data + read_pos); + +dll_parse_end: + return(result); +} + +i32 +dll_total_loaded_size(DLL_Data *dll){ + COFF_Header *coff_header; + PE_Section_Definition *section_def; + i32 result, section_end, i; + + coff_header = dll->coff_header; + section_def = dll->section_defs; + result = 0; + + for (i = 0; i < coff_header->number_of_sections; ++i, ++section_def){ + section_end = section_def->loaded_location + section_def->loaded_size; + if (section_end > result){ + result = section_end; + } + } + + return(result); +} + +b32 +dll_perform_reloc(DLL_Loaded *loaded){ + Data img; + byte *base; + Relocation_Block_Header *header; + Relocation_Block_Entry *entry; + Data_Directory *data_directory; + u32 cursor; + u32 bytes_in_table; + u32 block_end; + u32 type; + u32 offset; + b32 result; + b32 highadj_stage; + + u64 dif64; + + result = 1; + img = loaded->img; + if (loaded->is_64bit){ + data_directory = loaded->opt_header_64->data_directory; + dif64 = ((u64)img.data - (u64)loaded->opt_header_64->image_base); + } + else{ + data_directory = loaded->opt_header_32->data_directory; + dif64 = ((u64)img.data - (u64)loaded->opt_header_32->image_base); + } + data_directory += image_dir_base_reloc_table; + base = img.data + data_directory->virtual_address; + bytes_in_table = data_directory->size; + + highadj_stage = 1; + + + for (cursor = 0; cursor < bytes_in_table;){ + header = (Relocation_Block_Header*)(base + cursor); + block_end = cursor + header->block_size; + cursor += sizeof(Relocation_Block_Header); + + for (;cursor < block_end;){ + entry = (Relocation_Block_Entry*)(base + cursor); + cursor += sizeof(Relocation_Block_Entry); + + type = (u32)(entry->entry & reloc_entry_type_mask) >> reloc_entry_type_shift; + offset = (u32)(entry->entry & reloc_entry_offset_mask) + header->page_base_offset; + + switch (type){ + case image_base_absolute: break; + + case image_base_high: + case image_base_low: + case image_base_highlow: + case image_base_highadj: + case image_base_arm_mov32a: + case image_base_arm_mov32t: + case image_base_mips_jmpaddr16: + result = 0; + goto dll_reloc_end; + + case image_base_dir64: + *(u64*)(img.data + offset) += dif64; + break; + } + } + } + +dll_reloc_end: + return(result); +} + +b32 +dll_load_sections(Data img, DLL_Loaded *loaded, + Data file, DLL_Data *dll){ + COFF_Header *coff_header; + PE_Section_Definition *section_def; + u32 header_size; + u32 size; + u32 i; + + coff_header = dll->coff_header; + section_def = dll->section_defs; + + header_size = + (u32)((byte*)(section_def + coff_header->number_of_sections) - file.data); + + memcpy(img.data, file.data, header_size); + memset(img.data + header_size, 0, img.size - header_size); + + for (i = 0; i < coff_header->number_of_sections; ++i, ++section_def){ + size = section_def->loaded_size; + if (size > section_def->disk_size) + size = section_def->disk_size; + + memcpy(img.data + section_def->loaded_location, + file.data + section_def->disk_location, + size); + + if (dll_compare(section_def->name, ".text", 5) == 0){ + loaded->text_start = section_def->loaded_location; + loaded->text_size = section_def->loaded_size; + } + } + + return(1); +} + +void +dll_load(Data img, DLL_Loaded *loaded, Data file, DLL_Data *dll){ + Data_Directory *export_dir; + + dll_load_sections(img, loaded, file, dll); + loaded->img = img; + + loaded->dos_header = (DOS_Header*)((byte*)img.data + ((byte*)dll->dos_header - file.data)); + loaded->coff_header = (COFF_Header*)((byte*)img.data + ((byte*)dll->coff_header - file.data)); + + loaded->opt_header_32 = (PE_Opt_Header_32Bit*) + ((byte*)img.data + ((byte*)dll->opt_header_32 - file.data)); + loaded->opt_header_64 = (PE_Opt_Header_64Bit*) + ((byte*)img.data + ((byte*)dll->opt_header_64 - file.data)); + + loaded->section_defs = (PE_Section_Definition*) + ((byte*)img.data + ((byte*)dll->section_defs - file.data)); + + loaded->is_64bit = dll->is_64bit; + + if (dll->is_64bit){ + export_dir = dll->opt_header_64->data_directory; + } + else{ + export_dir = dll->opt_header_32->data_directory; + } + export_dir += image_dir_entry_export; + loaded->export_start = export_dir->virtual_address; + + dll_perform_reloc(loaded); +} + +void* +dll_load_function(DLL_Loaded *dll, char *func_name, i32 size){ + Data img; + DLL_Export_Directory_Table *export_dir; + DLL_Export_Address *address_ptr; + DLL_Export_Name *name_ptr; + void *result; + u32 count, i; + u32 result_offset; + u32 ordinal; + + img = dll->img; + export_dir = (DLL_Export_Directory_Table*)(img.data + dll->export_start); + + count = export_dir->number_of_name_pointers; + name_ptr = (DLL_Export_Name*)(img.data + export_dir->name_pointer_offset); + + result = 0; + for (i = 0; i < count; ++i, ++name_ptr){ + if (dll_compare((char*)img.data + name_ptr->name_offset, + func_name, size) == 0){ + ordinal = ((u16*)(img.data + export_dir->ordinal_offset))[i]; +#if 0 + // NOTE(allen): The MS docs say to do this, but + // it appears to just be downright incorrect. + ordinal -= export_dir->ordinal_base; +#endif + address_ptr = (DLL_Export_Address*)(img.data + export_dir->address_offset); + address_ptr += ordinal; + result_offset = address_ptr->export_offset; + result = (img.data + result_offset); + break; + } + } + + return(result); +} + +#define MachineCase(x) case x: result = #x; *len = sizeof(#x) - 1; break + +char* +dll_machine_type_str(u16 machine, i32 *len){ + char *result; + i32 extra; + + if (!len) len = &extra; + result = 0; + + switch (machine){ + MachineCase(intel_i386); + MachineCase(intel_i860); + + MachineCase(mips_r3000); + MachineCase(mips_little_endian); + MachineCase(mips_r10000); + + MachineCase(old_alpha_axp); + MachineCase(alpha_axp); + + MachineCase(hitachi_sh3); + MachineCase(hitachi_sh3_dsp); + MachineCase(hitachi_sh4); + MachineCase(hitachi_sh5); + + MachineCase(arm_little_endian); + MachineCase(thumb); + + MachineCase(matsushita_am33); + MachineCase(power_pc_little_endian); + MachineCase(power_pc_with_floating); + + MachineCase(intel_ia64); + MachineCase(mips16); + MachineCase(motorola_68000_series); + + MachineCase(alpha_axp_64_bit); + + MachineCase(mips_with_fpu); + MachineCase(mips16_with_fpu); + MachineCase(eft_byte_code); + + MachineCase(amd_amd64); + MachineCase(mitsubishi_m32r_little_endian); + MachineCase(clr_pure_msil); + } + + return(result); +} + +#undef MachineCase + +// BOTTOM + diff --git a/4ed_dll_reader.h b/4ed_dll_reader.h new file mode 100644 index 00000000..90c3bd82 --- /dev/null +++ b/4ed_dll_reader.h @@ -0,0 +1,441 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 20.11.2015 + * + * DLL loader declarations for 4coder + * + */ + +// TOP + +struct DOS_Header { + char signature[2]; + i16 lastsize; + i16 nblocks; + i16 nreloc; + i16 hdrsize; + i16 minalloc; + i16 maxalloc; + i16 ss; + i16 sp; + i16 checksum; + i16 ip; + i16 cs; + i16 relocpos; + i16 noverlay; + i16 reserved1[4]; + i16 oem_id; + i16 oem_info; + i16 reserved2[10]; + i32 e_lfanew; +}; + +enum Target_Machine_Code{ + intel_i386 = 0x14C, + intel_i860 = 0x14D, + + mips_r3000 = 0x162, + mips_little_endian = 0x166, + mips_r10000 = 0x168, + + old_alpha_axp = 0x183, + alpha_axp = 0x184, + + hitachi_sh3 = 0x1a2, + hitachi_sh3_dsp = 0x1a3, + hitachi_sh4 = 0x1a6, + hitachi_sh5 = 0x1a8, + + arm_little_endian = 0x1c0, + thumb = 0x1c2, + + matsushita_am33 = 0x1d3, + power_pc_little_endian = 0x1f0, + power_pc_with_floating = 0x1f1, + + intel_ia64 = 0x200, + mips16 = 0x266, + motorola_68000_series = 0x268, + + alpha_axp_64_bit = 0x284, + + mips_with_fpu = 0x366, + mips16_with_fpu = 0x466, + eft_byte_code = 0xebc, + + amd_amd64 = 0x8664, + mitsubishi_m32r_little_endian = 0x9041, + clr_pure_msil = 0xc0ee +}; + +#define file_is_exe 0x2 +#define file_is_non_reloctable 0x200 +#define file_is_dll 0x2000 + +struct COFF_Header{ + u16 machine; + u16 number_of_sections; + u32 time_date_stamp; + u32 pointer_to_symbol_table; + u32 number_of_symbols; + u16 size_of_optional_header; + u16 characteristics; +}; + +struct Data_Directory{ + u32 virtual_address; + u32 size; +}; + +// This version is untested +struct PE_Opt_Header_32Bit{ + // Universal Portion + i16 signature; + i8 major_linker_version; + i8 minor_linker_version; + i32 size_of_code; + i32 size_of_initialized_data; + i32 size_of_uninitialized_data; + i32 address_of_entry_point; + i32 base_of_code; + i32 base_of_data; + + // Windows Portion + i32 image_base; + i32 section_alignment; + i32 file_alignment; + i16 major_OS_version; + i16 minor_OS_version; + i16 major_image_version; + i16 minor_image_version; + i16 major_subsystem_version; + i16 minor_subsystem_version; + i32 reserved; + i32 size_of_image; + i32 size_of_headers; + i32 checksum; + i16 subsystem; + i16 DLL_characteristics; + i32 size_of_stack_reserve; + i32 size_of_stack_commit; + i32 size_of_heap_reserve; + i32 size_of_heap_commit; + i32 loader_flags; + i32 number_of_rva_and_sizes; + Data_Directory data_directory[16]; +}; + +struct PE_Opt_Header_64Bit{ + // Universal Portion + u16 signature; + u8 major_linker_version; + u8 minor_linker_version; + u32 size_of_code; + u32 size_of_initialized_data; + u32 size_of_uninitialized_data; + u32 address_of_entry_point; + u32 base_of_code; + + // Windows Portion + u64 image_base; + u32 section_alignment; + u32 file_alignment; + u16 major_OS_version; + u16 minor_OS_version; + u16 major_image_version; + u16 minor_image_version; + u16 major_subsystem_version; + u16 minor_subsystem_version; + u32 reserved; + u32 size_of_image; + u32 size_of_headers; + u32 checksum; + u16 subsystem; + u16 DLL_characteristics; + u64 size_of_stack_reserve; + u64 size_of_stack_commit; + u64 size_of_heap_reserve; + u64 size_of_heap_commit; + u32 loader_flags; + u32 number_of_rva_and_sizes; + Data_Directory data_directory[16]; +}; + +#define bitsig_32bit 267 +#define bitsig_64bit 523 + +#define image_dir_entry_export 0 +#define image_dir_entry_import 1 +#define image_dir_entry_resource 2 +#define image_dir_base_reloc_table 5 +#define image_dir_entry_bound_import 11 + +struct PE_Section_Definition{ + char name[8]; + u32 loaded_size; + u32 loaded_location; + u32 disk_size; + u32 disk_location; + u32 disk_relocs; + u32 reserved1; + u16 number_of_relocs; + u16 reserved2; + u32 flags; +}; + +#define image_scn_type_no_pad 0x00000008 +#define image_scn_cnt_code 0x00000020 +#define image_scn_cnt_initialized_data 0x00000040 +#define image_scn_cnt_uninitialized_data 0x00000080 +#define image_scn_lnk_other 0x00000100 +#define image_scn_lnk_info 0x00000200 +#define image_scn_lnk_remove 0x00000800 +#define image_scn_lnk_comdat 0x00001000 +#define image_scn_no_defer_spec_exc 0x00004000 +#define image_scn_gprel 0x00008000 +#define image_scn_mem_fardata 0x00008000 +#define image_scn_mem_purgeable 0x00020000 +#define image_scn_mem_16BIT 0x00020000 +#define image_scn_mem_locked 0x00040000 +#define image_scn_mem_preload 0x00080000 + +#define image_scn_align_1bytes 0x00100000 +#define image_scn_align_2bytes 0x00200000 +#define image_scn_align_4bytes 0x00300000 +#define image_scn_align_8bytes 0x00400000 +#define image_scn_align_16bytes 0x00500000 +#define image_scn_align_32bytes 0x00600000 +#define image_scn_align_64bytes 0x00700000 +#define image_scn_align_128bytes 0x00800000 +#define image_scn_align_256bytes 0x00900000 +#define image_scn_align_512bytes 0x00A00000 +#define image_scn_align_1024bytes 0x00B00000 +#define image_scn_align_2048bytes 0x00C00000 +#define image_scn_align_4096bytes 0x00D00000 +#define image_scn_align_8192bytes 0x00E00000 +#define image_scn_align_mask 0x00F00000 + +#define image_scn_lnk_nreloc_ovfl 0x01000000 +#define image_scn_mem_discardable 0x02000000 +#define image_scn_mem_not_cached 0x04000000 +#define image_scn_mem_not_paged 0x08000000 +#define image_scn_mem_shared 0x10000000 +#define image_scn_mem_execute 0x20000000 +#define image_scn_mem_read 0x40000000 +#define image_scn_mem_write 0x80000000 + +#pragma pack(push, 1) +struct COFF_Relocation{ + u32 virtual_address; + u32 symbol_table_index; + u16 type; +}; +#pragma pack(pop) + +enum Image_Rel_Amd64{ + image_rel_amd64_absolute = 0x00, + image_rel_amd64_addr64 = 0x01, + image_rel_amd64_addr32 = 0x02, + image_rel_amd64_addr32nb = 0x03, + image_rel_amd64_rel32 = 0x04, + image_rel_amd64_rel32_1 = 0x05, + image_rel_amd64_rel32_2 = 0x06, + image_rel_amd64_rel32_3 = 0x07, + image_rel_amd64_rel32_4 = 0x08, + image_rel_amd64_rel32_5 = 0x09, + image_rel_amd64_section = 0x0A, + image_rel_amd64_secrel = 0x0B, + image_rel_amd64_secrel7 = 0x0C, + image_rel_amd64_token = 0x0D, + image_rel_amd64_srel32 = 0x0E, + image_rel_amd64_pair = 0x0F, + image_rel_amd64_sspan32 = 0x10 +}; + +enum Image_Rel_Arm{ + image_rel_arm_absolute = 0x0, + image_rel_arm_addr32 = 0x1, + image_rel_arm_addr32nb = 0x2, + image_rel_arm_branch24 = 0x3, + image_rel_arm_branch11 = 0x4, + image_rel_arm_token = 0x5, + image_rel_arm_blx24 = 0x6, + image_rel_arm_blx11 = 0x7, + image_rel_arm_section = 0x8, + image_rel_arm_secrel = 0x9, + image_rel_arm_mov32a = 0xA, + image_rel_arm_mov32t = 0xB, + image_rel_arm_branch20t = 0xC, + image_rel_arm_branch24t = 0xD, + image_rel_arm_blx32t = 0xE +}; + +enum Image_Rel_Arm64{ + image_rel_arm64_absolute = 0x0, + image_rel_arm64_addr32 = 0x1, + image_rel_arm64_addr32nb = 0x2, + image_rel_arm64_branch26 = 0x3, + image_rel_arm64_pagebase_rel21 = 0x4, + image_rel_arm64_rel21 = 0x5, + image_rel_arm64_pageoffset_12a = 0x6, + image_rel_arm64_pageoffset_12l = 0x7, + image_rel_arm64_secrel = 0x8, + image_rel_arm64_secrel_low12a = 0x9, + image_rel_arm64_secrel_high12a = 0xA, + image_rel_arm64_secrel_low12l = 0xB, + image_rel_arm64_token = 0xC, + image_rel_arm64_section = 0xD, + image_rel_arm64_addr64 = 0xE +}; + +// NOTE(allen): +// skipped Hitachi SuperH +// skiiped IBM PowerPC + +enum Image_Rel_i386{ + image_rel_i386_absolute = 0x0, + image_rel_i386_dir16 = 0x1, + image_rel_i386_rel16 = 0x2, + image_rel_i386_dir32 = 0x3, + image_rel_i386_dir32nb = 0x4, + image_rel_i386_seg12 = 0x5, + image_rel_i386_section = 0x6, + image_rel_i386_secrel = 0x7, + image_rel_i386_token = 0x8, + image_rel_i386_secrel7 = 0x9, + image_rel_i386_rel32 = 0xA +}; + +// NOTE(allen): +// skipped ia64 +// skipped MIPS +// skiiped Mitsubishi + +struct Relocation_Block_Header{ + u32 page_base_offset; + u32 block_size; +}; + +#define reloc_entry_type_mask 0xF000 +#define reloc_entry_type_shift 12 +#define reloc_entry_offset_mask 0x0FFF + +struct Relocation_Block_Entry{ + u16 entry; +}; + +enum DLL_Relocation_Type{ + image_base_absolute, + // nothing + + image_base_high, + // add high 16 bits of diff to 16 bits at offset + + image_base_low, + // add low 16 bits of diff to 16 bits at offset + + image_base_highlow, + // adds all 32 bits to 32 bits at offset + + image_base_highadj, + // consumes two slots: high 16 bits at location, low 16 bits at next location + + image_base_arm_mov32a, + // mips: jump instruction; arm: MOVW+MOVT + + image_base_reserved1, + + image_base_arm_mov32t, + // MOVW+MOVT in Thumb mode + + image_base_reserved2, + + image_base_mips_jmpaddr16, + // mips16 jump instruction + + image_base_dir64 + // adds to 64 bits field +}; + +struct DLL_Data{ + DOS_Header *dos_header; + COFF_Header *coff_header; + PE_Opt_Header_32Bit *opt_header_32; + PE_Opt_Header_64Bit *opt_header_64; + PE_Section_Definition *section_defs; + b32 is_64bit; +}; + +struct DLL_Loaded{ + DOS_Header *dos_header; + COFF_Header *coff_header; + PE_Opt_Header_32Bit *opt_header_32; + PE_Opt_Header_64Bit *opt_header_64; + PE_Section_Definition *section_defs; + b32 is_64bit; + + Data img; + u32 export_start; + u32 text_start; + u32 text_size; +}; + +struct DLL_Export_Directory_Table{ + u32 export_flags; + u32 time_date_stamp; + u16 major_version; + u16 minor_version; + u32 name_offset; + u32 ordinal_base; + u32 number_of_addresses; + u32 number_of_name_pointers; + u32 address_offset; + u32 name_pointer_offset; + u32 ordinal_offset; +}; + +struct DLL_Export_Address{ + u32 export_offset; +}; + +struct DLL_Export_Name{ + u32 name_offset; +}; + +struct DLL_Export_Ordinal{ + u16 ordinal; +}; + +struct DLL_Debug_Entry{ + u32 characteristics; + u32 time_date_stamp; + u16 major_version; + u16 minor_version; + u32 type; + u32 size_of_data; + u32 offset_of_data; + u32 disk_offset_of_data; +} thingy; + +enum DLL_Debug_Type{ + img_dbg_type_unknown, + img_dbg_type_coff, + img_dbg_type_codeview, + img_dbg_type_fpo, + img_dbg_type_misc, + img_dbg_type_exception, + img_dbg_type_fixup, + img_dbg_type_omap_to_src, + img_dbg_type_omap_from_src +}; + +char DOS_error_message[] = "This program cannot be run in DOS mode."; +i32 DOS_error_offset = 0x4E; +i32 DOS_error_size = sizeof(DOS_error_message) - 1; + +char PE_header[] = {'P', 'E', 0, 0}; +i32 PE_header_size = 4; + +// BOTTOM + diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index 990b60a4..0f7be9c2 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -87,7 +87,7 @@ struct Undo_Data{ struct Editing_File{ Buffer_Type buffer; - Font *font; + Render_Font *font; i32 cursor_pos; b32 is_dummy; @@ -558,7 +558,7 @@ widget_match(Widget_ID s1, Widget_ID s2){ struct UI_State{ Render_Target *target; Style *style; - Font *font; + Render_Font *font; Mouse_Summary *mouse; Key_Summary *keys; Key_Codes *codes; @@ -983,7 +983,7 @@ internal bool32 do_text_field(Widget_ID wid, UI_State *state, UI_Layout *layout, String prompt, String dest){ bool32 result = 0; - Font *font = state->font; + Render_Font *font = state->font; i32 character_h = font->height; i32_Rect rect = layout_rect(layout, character_h); @@ -1231,7 +1231,7 @@ file_grow_starts_as_needed(General_Memory *general, Buffer_Type *buffer, i32 add internal void file_measure_starts_widths(System_Functions *system, - General_Memory *general, Buffer_Type *buffer, Font *font){ + General_Memory *general, Buffer_Type *buffer, Render_Font *font){ ProfileMomentFunction(); if (!buffer->line_starts){ i32 max = buffer->line_max = Kbytes(1); @@ -1331,7 +1331,7 @@ struct Opaque_Font_Advance{ }; inline Opaque_Font_Advance -get_opaque_font_advance(Font *font){ +get_opaque_font_advance(Render_Font *font){ Opaque_Font_Advance result; result.data = (char*)font->chardata + OffsetOfPtr(font->chardata, xadvance); result.stride = sizeof(*font->chardata); @@ -1373,7 +1373,7 @@ file_measure_widths(General_Memory *general, Buffer_Type *buffer, Font *font){ internal void file_remeasure_widths(System_Functions *system, - General_Memory *general, Buffer_Type *buffer, Font *font, + General_Memory *general, Buffer_Type *buffer, Render_Font *font, i32 line_start, i32 line_end, i32 line_shift){ #if BUFFER_EXPERIMENT_SCALPEL <= 3 ProfileMomentFunction(); @@ -1400,7 +1400,7 @@ view_compute_lowest_line(File_View *view){ } else{ Style *style = view->style; - Font *font = style->font; + Render_Font *font = style->font; real32 wrap_y = view->line_wrap_y[last_line]; lowest_line = FLOOR32(wrap_y / font->height); f32 max_width = view_compute_width(view); @@ -1438,9 +1438,9 @@ view_measure_wraps(System_Functions *system, } } - Font *font = view->style->font; - real32 line_height = (real32)font->height; - real32 max_width = view_compute_width(view); + Render_Font *font = view->style->font; + f32 line_height = (f32)font->height; + f32 max_width = view_compute_width(view); buffer_measure_wrap_y(buffer, view->line_wrap_y, line_height, max_width); view->line_count = line_count; @@ -1456,7 +1456,8 @@ alloc_for_buffer(void *context, int *size){ internal void file_create_from_string(System_Functions *system, - Mem_Options *mem, Editing_File *file, char *filename, Font *font, String val, b32 super_locked = 0){ + Mem_Options *mem, Editing_File *file, char *filename, + Render_Font *font, String val, b32 super_locked = 0){ *file = {}; General_Memory *general = &mem->general; #if BUFFER_EXPERIMENT_SCALPEL <= 3 @@ -1517,10 +1518,11 @@ file_create_from_string(System_Functions *system, } internal bool32 -file_create(System_Functions *system, Mem_Options *mem, Editing_File *file, char *filename, Font *font){ +file_create(System_Functions *system, Mem_Options *mem, Editing_File *file, + char *filename, Render_Font *font){ bool32 result = 0; - File_Data raw_file = system->load_file(filename); + Data raw_file = system->load_file(filename); if (raw_file.data){ result = 1; String val = make_string((char*)raw_file.data, raw_file.size); @@ -1532,7 +1534,8 @@ file_create(System_Functions *system, Mem_Options *mem, Editing_File *file, char } internal b32 -file_create_empty(System_Functions *system, Mem_Options *mem, Editing_File *file, char *filename, Font *font){ +file_create_empty(System_Functions *system, Mem_Options *mem, Editing_File *file, + char *filename, Render_Font *font){ b32 result = 1; String empty_str = {}; file_create_from_string(system, mem, file, filename, font, empty_str); @@ -1540,7 +1543,8 @@ file_create_empty(System_Functions *system, Mem_Options *mem, Editing_File *file } internal b32 -file_create_super_locked(System_Functions *system, Mem_Options *mem, Editing_File *file, char *filename, Font *font){ +file_create_super_locked(System_Functions *system, Mem_Options *mem, Editing_File *file, + char *filename, Render_Font *font){ b32 result = 1; String empty_str = {}; file_create_from_string(system, mem, file, filename, font, empty_str, 1); @@ -1617,7 +1621,7 @@ struct Shift_Information{ i32 start, end, amount; }; -#if BUFFER_EXPERIMENT_SCALPEL <= 0 +#if 0 //BUFFER_EXPERIMENT_SCALPEL <= 0 internal Job_Callback(job_full_lex){ Editing_File *file = (Editing_File*)data[0]; @@ -1680,6 +1684,83 @@ Job_Callback(job_full_lex){ file->tokens_complete = 1; file->still_lexing = 0; } +#else + +internal void +system_grow_memory(System_Functions *system, Data *memory){ + byte *old = memory->data; + i32 new_size = memory->size * 2; + memory->data = (byte*)system->get_memory(new_size); + memcpy(memory->data, old, memory->size); + system->free_memory(old); + memory->size = new_size; +} + +internal void +full_lex(System_Functions *system, Editing_File *file, General_Memory *general){ + Cpp_File cpp_file; + cpp_file.data = file->buffer.data; + cpp_file.size = file->buffer.size; + + Data memory_; + memory_.size = 64 << 10; + memory_.data = (byte*)system->get_memory(memory_.size); + + Data *memory = &memory_; + + Cpp_Token_Stack tokens; + tokens.tokens = (Cpp_Token*)memory->data; + tokens.max_count = memory->size / sizeof(Cpp_Token); + tokens.count = 0; + + Cpp_Lex_Data status; + status = cpp_lex_file_nonalloc(cpp_file, &tokens); + while (!status.complete){ + //system->grow_thread_memory(memory); + system_grow_memory(system, memory); + tokens.tokens = (Cpp_Token*)memory->data; + tokens.max_count = memory->size / sizeof(Cpp_Token); + status = cpp_lex_file_nonalloc(cpp_file, &tokens, status); + } + + i32 new_max = LargeRoundUp(tokens.count, Kbytes(1)); + if (file->token_stack.tokens){ + file->token_stack.tokens = (Cpp_Token*) + general_memory_reallocate_nocopy(general, file->token_stack.tokens, new_max*sizeof(Cpp_Token), BUBBLE_TOKENS); + } + else{ + file->token_stack.tokens = (Cpp_Token*) + general_memory_allocate(general, new_max*sizeof(Cpp_Token), BUBBLE_TOKENS); + } + + i32 copy_amount = Kbytes(8); + i32 uncoppied = tokens.count*sizeof(Cpp_Token); + if (copy_amount > uncoppied) copy_amount = uncoppied; + + u8 *dest = (u8*)file->token_stack.tokens; + u8 *src = (u8*)tokens.tokens; + + while (uncoppied > 0){ + memcpy(dest, src, copy_amount); + dest += copy_amount; + src += copy_amount; + uncoppied -= copy_amount; + if (copy_amount > uncoppied) copy_amount = uncoppied; + } + + file->token_stack.count = tokens.count; + file->token_stack.max_count = new_max; + system->force_redraw(); + + // NOTE(allen): These are outside the locked section because I don't + // think getting these out of order will cause critical bugs, and I + // want to minimize what's done in locked sections. + file->tokens_complete = 1; + file->still_lexing = 0; + + system->free_memory(memory_.data); +} + #endif internal void @@ -1705,13 +1786,17 @@ file_first_lex_parallel(System_Functions *system, file->tokens_complete = 0; file->tokens_exist = 1; file->still_lexing = 1; + + full_lex(system, file, general); +#if 0 Job_Data job; job.callback = job_full_lex; job.data[0] = file; job.data[1] = general; job.memory_request = Kbytes(64); file->lex_job = system->post_job(BACKGROUND_THREADS, job); +#endif } internal void @@ -1790,13 +1875,17 @@ file_relex_parallel(System_Functions *system, } file->still_lexing = 1; + + full_lex(system, file, general); +#if 0 Job_Data job; job.callback = job_full_lex; job.data[0] = file; job.data[1] = general; job.memory_request = Kbytes(64); file->lex_job = system->post_job(BACKGROUND_THREADS, job); +#endif } } #endif @@ -2093,7 +2182,7 @@ view_compute_cursor_from_pos(File_View *view, i32 pos){ #if BUFFER_EXPERIMENT_SCALPEL <= 3 Editing_File *file = view->file; Style *style = view->style; - Font *font = style->font; + Render_Font *font = style->font; real32 max_width = view_compute_width(view); @@ -2110,7 +2199,7 @@ view_compute_cursor_from_unwrapped_xy(File_View *view, real32 seek_x, real32 see #if BUFFER_EXPERIMENT_SCALPEL <= 3 Editing_File *file = view->file; Style *style = view->style; - Font *font = style->font; + Render_Font *font = style->font; real32 max_width = view_compute_width(view); @@ -2127,7 +2216,7 @@ view_compute_cursor_from_wrapped_xy(File_View *view, real32 seek_x, real32 seek_ #if BUFFER_EXPERIMENT_SCALPEL <= 3 Editing_File *file = view->file; Style *style = view->style; - Font *font = style->font; + Render_Font *font = style->font; real32 max_width = view_compute_width(view); @@ -2207,7 +2296,7 @@ view_set_file(System_Functions *system, view->locked = file->super_locked; General_Memory *general = &view->view_base.mem->general; - Font *font = style->font; + Render_Font *font = style->font; view->style = style; view->font_advance = font->advance; view->font_height = font->height; @@ -2313,7 +2402,7 @@ view_set_widget(File_View *view, File_View_Widget_Type type){ } inline i32 -view_widget_height(File_View *view, Font *font){ +view_widget_height(File_View *view, Render_Font *font){ i32 result = 0; switch (view->widget.type){ case FWIDG_NONE: break; @@ -2325,7 +2414,7 @@ view_widget_height(File_View *view, Font *font){ } inline i32_Rect -view_widget_rect(File_View *view, Font *font){ +view_widget_rect(File_View *view, Render_Font *font){ Panel *panel = view->view_base.panel; i32_Rect whole = panel->inner; i32_Rect result; @@ -3530,7 +3619,7 @@ internal bool32 do_button(i32 id, UI_State *state, UI_Layout *layout, char *text, i32 height_mult, bool32 is_toggle = 0, bool32 on = 0){ bool32 result = 0; - Font *font = state->font; + Render_Font *font = state->font; i32 character_h = font->height; i32_Rect btn_rect = layout_rect(layout, character_h * height_mult); @@ -3578,7 +3667,7 @@ do_button(i32 id, UI_State *state, UI_Layout *layout, char *text, i32 height_mul internal bool32 do_undo_slider(Widget_ID wid, UI_State *state, UI_Layout *layout, i32 max, i32 v, Undo_Data *undo, i32 *out){ bool32 result = 0; - Font *font = state->font; + Render_Font *font = state->font; i32 character_h = font->height; i32_Rect containing_rect = layout_rect(layout, character_h); @@ -3630,7 +3719,7 @@ do_undo_slider(Widget_ID wid, UI_State *state, UI_Layout *layout, i32 max, i32 v } if (show_ticks){ - real32_Rect tick; + f32_Rect tick; tick.x0 = (real32)click_rect.x0 - 1; tick.x1 = (real32)click_rect.x0 + 1; tick.y0 = (real32)bar_top - 3; @@ -3684,7 +3773,7 @@ do_undo_slider(Widget_ID wid, UI_State *state, UI_Layout *layout, i32 max, i32 v } if (show_ticks){ - real32_Rect tick; + f32_Rect tick; tick.x0 = (real32)click_rect.x0 - 1; tick.x1 = (real32)click_rect.x0 + 1; tick.y0 = (real32)bar_top - 3; @@ -3727,7 +3816,7 @@ step_file_view(System_Functions *system, View *view_, i32_Rect rect, File_View *view = (File_View*)view_; Editing_File *file = view->file; Style *style = view->style; - Font *font = style->font; + Render_Font *font = style->font; f32 line_height = (f32)font->height; f32 cursor_y = view_get_cursor_y(view); @@ -3949,7 +4038,7 @@ draw_file_view(View *view_, i32_Rect rect, bool32 is_active, File_View *view = (File_View*)view_; Editing_File *file = view->file; Style *style = view->style; - Font *font = style->font; + Render_Font *font = style->font; Interactive_Bar bar; bar.style = style->main.file_info_style; @@ -4097,7 +4186,7 @@ draw_file_view(View *view_, i32_Rect rect, bool32 is_active, if (view->widget.type != FWIDG_NONE){ UI_Style ui_style = get_ui_style_upper(style); - Font *font = style->font; + Render_Font *font = style->font; i32_Rect widg_rect = view_widget_rect(view, font); draw_rectangle(target, widg_rect, ui_style.dark); @@ -4338,7 +4427,7 @@ HANDLE_COMMAND_SIG(handle_command_file_view){ if (result.hit_newline || result.hit_ctrl_newline){ i32 line_number = str_to_int(*string); - Font *font = file_view->style->font; + Render_Font *font = file_view->style->font; if (line_number < 1) line_number = 1; file_view->cursor = view_compute_cursor_from_unwrapped_xy(file_view, 0, (real32)(line_number-1)*font->height); diff --git a/4ed_keyboard.cpp b/4ed_keyboard.cpp index 2d971bd4..228fb6ae 100644 --- a/4ed_keyboard.cpp +++ b/4ed_keyboard.cpp @@ -1,7 +1,7 @@ /* * Mr. 4th Dimention - Allen Webster * - * 12.17.2014 + * 16.11.2014 * * Win32-US Keyboard layer for 4coder * @@ -13,90 +13,27 @@ globalvar u16 keycode_lookup_table[255]; globalvar u16 loose_keycode_lookup_table[255]; internal void -keycode_init(Key_Codes *codes){ - // NOTE(allen): Assign values to the global keycodes. - // Skip over the ascii characters that are used as codes. - u16 code = 1, loose; +set_dynamic_key_names(Key_Codes *codes){ + u16 code = 1; u16 *codes_array = (u16*)codes; - for (i32 i = 0; i < sizeof(Key_Codes)/2;){ + for (i32 i = 0; i < sizeof(*codes)/sizeof(codes->up);){ switch (code){ case '\n': code++; break; case '\t': code++; break; case 0x20: code = 0x7F; break; - - default: - codes_array[i++] = code++; } - } - - // NOTE(allen): lookup table for conversion from - // win32 vk values to fred_keycode values. - for (u8 i = 0; i < 255; ++i){ - if ((i >= '0' && i <= '9') || - (i >= 'A' && i <= 'Z')){ - keycode_lookup_table[i] = i; - loose_keycode_lookup_table[i] = 0; - } - else{ - loose = 0; - switch (i){ - case VK_SPACE: code = loose = ' '; break; - case VK_BACK: code = loose = codes->back; break; - case VK_OEM_MINUS: code = '-'; break; - case VK_OEM_PLUS: code = '='; break; - case VK_SUBTRACT: code = '-'; break; - case VK_ADD: code = '+'; break; - case VK_MULTIPLY: code = '*'; break; - case VK_DIVIDE: code = '/'; break; - - case VK_OEM_3: code = '`'; break; - case VK_OEM_5: code = '\\'; break; - case VK_OEM_4: code = '['; break; - case VK_OEM_6: code = ']'; break; - case VK_TAB: code = loose = '\t'; break; - case VK_RETURN: code = loose = '\n'; break; - case VK_OEM_7: code = '\''; break; - - case VK_OEM_1: code = ';'; break; - case VK_OEM_2: code = '/'; break; - case VK_OEM_PERIOD: code = '.'; break; - case VK_OEM_COMMA: code = ','; break; - case VK_UP: code = loose = codes->up; break; - case VK_DOWN: code = loose = codes->down; break; - case VK_LEFT: code = loose = codes->left; break; - case VK_RIGHT: code = loose = codes->right; break; - case VK_DELETE: code = loose = codes->del; break; - - case VK_INSERT: code = loose = codes->insert; break; - case VK_HOME: code = loose = codes->home; break; - case VK_END: code = loose = codes->end; break; - case VK_PRIOR: code = loose = codes->page_up; break; - case VK_NEXT: code = loose = codes->page_down; break; - case VK_ESCAPE: code = loose = codes->esc; break; - - case VK_NUMPAD0: - case VK_NUMPAD1: case VK_NUMPAD2: case VK_NUMPAD3: - case VK_NUMPAD4: case VK_NUMPAD5: case VK_NUMPAD6: - case VK_NUMPAD7: case VK_NUMPAD8: case VK_NUMPAD9: - code = (i - VK_NUMPAD0) + '0'; break; - - default: code = 0; break; - } - - keycode_lookup_table[i] = code; - loose_keycode_lookup_table[i] = loose; - } + codes_array[i++] = code++; } } inline u16 -keycode_lookup(u8 virtual_keycode){ - return keycode_lookup_table[virtual_keycode]; +keycode_lookup(u8 system_code){ + return keycode_lookup_table[system_code]; } inline u16 -loose_keycode_lookup(u8 virtual_keycode){ - return loose_keycode_lookup_table[virtual_keycode]; +loose_keycode_lookup(u8 system_code){ + return loose_keycode_lookup_table[system_code]; } inline b32 @@ -105,10 +42,9 @@ keycode_has_ascii(u16 keycode){ } internal u8 -keycode_to_character_ascii(Key_Codes *codes, - u16 keycode, - bool32 shift, - bool32 caps_lock){ +translate_key(u16 keycode, + b32 shift, + b32 caps_lock){ u8 character = 0; if (keycode >= 'A' && keycode <= 'Z'){ if (caps_lock) shift = !shift; diff --git a/4ed_layout.cpp b/4ed_layout.cpp index 49cdeefc..fcf57ded 100644 --- a/4ed_layout.cpp +++ b/4ed_layout.cpp @@ -26,7 +26,7 @@ struct Interactive_Bar{ real32 pos_x, pos_y; real32 text_shift_x, text_shift_y; i32_Rect rect; - Font *font; + Render_Font *font; }; enum View_Message{ @@ -135,7 +135,7 @@ struct Editing_Layout{ internal void intbar_draw_string(Render_Target *target, Interactive_Bar *bar, u8 *str, u32 char_color){ - Font *font = bar->font; + Render_Font *font = bar->font; for (i32 i = 0; str[i]; ++i){ char c = str[i]; font_draw_glyph(target, font, c, @@ -150,7 +150,7 @@ internal void intbar_draw_string(Render_Target *target, Interactive_Bar *bar, String str, u32 char_color){ - Font *font = bar->font; + Render_Font *font = bar->font; for (i32 i = 0; i < str.size; ++i){ char c = str.str[i]; font_draw_glyph(target, font, c, diff --git a/4ed_linux_keyboard.cpp b/4ed_linux_keyboard.cpp index 5a1afa65..58cd726c 100644 --- a/4ed_linux_keyboard.cpp +++ b/4ed_linux_keyboard.cpp @@ -9,12 +9,34 @@ // TOP -internal Key_Event_Data -get_key_event(SDL_Event *event){ - Key_Event_Data result = {}; - return result; -} +#include "4ed_keyboard.cpp" +internal void +keycode_init(Key_Codes *codes){ + set_dynamic_key_names(codes); + + u16 code, loose; + for (u16 i = 0; i < 255; ++i){ + if (i >= 'a' && i <= 'z'){ + keycode_lookup_table[i] = i + ('A' - 'a'); + loose_keycode_lookup_table[i] = 0; + } + + else if (i >= '0' && i <= '9'){ + keycode_lookup_table[i] = i; + loose_keycode_lookup_table[i] = 0; + } + + else{ + loose = 0; + switch (i){ + } + + keycode_lookup_table[i] = code; + loose_keycode_lookup_table[i] = loose; + } + } +} // BOTTOM diff --git a/4ed_math.cpp b/4ed_math.cpp index 087668ed..c82c5c44 100644 --- a/4ed_math.cpp +++ b/4ed_math.cpp @@ -103,7 +103,7 @@ struct i32_Rect{ i32 x1, y1; }; -struct real32_Rect{ +struct f32_Rect{ f32 x0, y0; f32 x1, y1; }; @@ -117,7 +117,7 @@ i32R(i32 l, i32 t, i32 r, i32 b){ } inline i32_Rect -i32R(real32_Rect r){ +i32R(f32_Rect r){ i32_Rect rect; rect.x0 = (i32)r.x0; rect.y0 = (i32)r.y0; @@ -134,53 +134,53 @@ i32XYWH(i32 x, i32 y, i32 w, i32 h){ return rect; } -inline real32_Rect -f32R(real32 l, real32 t, real32 r, real32 b){ - real32_Rect rect; +inline f32_Rect +f32R(f32 l, f32 t, f32 r, f32 b){ + f32_Rect rect; rect.x0 = l; rect.y0 = t; rect.x1 = r; rect.y1 = b; return rect; } -inline real32_Rect +inline f32_Rect f32R(i32_Rect r){ - real32_Rect rect; - rect.x0 = (real32)r.x0; - rect.y0 = (real32)r.y0; - rect.x1 = (real32)r.x1; - rect.y1 = (real32)r.y1; + f32_Rect rect; + rect.x0 = (f32)r.x0; + rect.y0 = (f32)r.y0; + rect.x1 = (f32)r.x1; + rect.y1 = (f32)r.y1; return rect; } -inline real32_Rect +inline f32_Rect f32XYWH(f32 x, f32 y, f32 w, f32 h){ - real32_Rect rect; + f32_Rect rect; rect.x0 = x; rect.y0 = y; rect.x1 = x+w; rect.y1 = y+h; return rect; } -inline bool32 +inline b32 hit_check(i32 x, i32 y, i32 x0, i32 y0, i32 x1, i32 y1){ return (x >= x0 && x < x1 && y >= y0 && y < y1); } -inline bool32 +inline b32 hit_check(i32 x, i32 y, i32_Rect rect){ return (hit_check(x, y, rect.x0, rect.y0, rect.x1, rect.y1)); } -inline bool32 -hit_check(i32 x, i32 y, real32 x0, real32 y0, real32 x1, real32 y1){ +inline b32 +hit_check(i32 x, i32 y, f32 x0, f32 y0, f32 x1, f32 y1){ return (x >= x0 && x < x1 && y >= y0 && y < y1); } -inline bool32 -hit_check(i32 x, i32 y, real32_Rect rect){ +inline b32 +hit_check(i32 x, i32 y, f32_Rect rect){ return (hit_check(x, y, rect.x0, rect.y0, rect.x1, rect.y1)); } -inline bool32 +inline b32 positive_area(i32_Rect rect){ return (rect.x0 < rect.x1 && rect.y0 < rect.y1); } @@ -195,12 +195,26 @@ get_inner_rect(i32_Rect outer, i32 margin){ return r; } -inline bool32 +inline b32 fits_inside(i32_Rect rect, i32_Rect outer){ return (rect.x0 >= outer.x0 && rect.x1 <= outer.x1 && rect.y0 >= outer.y0 && rect.y1 <= outer.y1); } +inline i32_Rect +rect_clamp_to_rect(i32_Rect rect, i32_Rect clamp_box){ + if (rect.x0 < clamp_box.x0) rect.x0 = clamp_box.x0; + if (rect.y0 < clamp_box.y0) rect.y0 = clamp_box.y0; + if (rect.x1 > clamp_box.x1) rect.x1 = clamp_box.x1; + if (rect.y1 > clamp_box.y1) rect.y1 = clamp_box.y1; + return rect; +} + +inline i32_Rect +rect_clamp_to_rect(i32 left, i32 top, i32 right, i32 bottom, i32_Rect clamp_box){ + return rect_clamp_to_rect(i32R(left, top, right, bottom), clamp_box); +} + /* * Vectors */ diff --git a/4ed_meta.h b/4ed_meta.h index ef2dab80..9a863467 100644 --- a/4ed_meta.h +++ b/4ed_meta.h @@ -28,11 +28,18 @@ typedef i8 bool8; typedef i32 b32; typedef i8 b8; +typedef uint8_t byte; + typedef float real32; typedef double real64; typedef float f32; typedef double f64; +struct Data{ + byte *data; + i32 size; +}; + #define external extern "C" #define internal static #define globalvar static diff --git a/4ed_rendering.cpp b/4ed_rendering.cpp index 70fae083..b55ceca8 100644 --- a/4ed_rendering.cpp +++ b/4ed_rendering.cpp @@ -9,246 +9,274 @@ // TOP -internal i32_Rect -rect_clamp_to_rect(i32_Rect rect, i32_Rect clamp_box){ - if (rect.x0 < clamp_box.x0) rect.x0 = clamp_box.x0; - if (rect.y0 < clamp_box.y0) rect.y0 = clamp_box.y0; - if (rect.x1 > clamp_box.x1) rect.x1 = clamp_box.x1; - if (rect.y1 > clamp_box.y1) rect.y1 = clamp_box.y1; +inline void +draw_set_clip(Render_Target *target, i32_Rect clip_box){ + glScissor(clip_box.x0, + target->height - clip_box.y1, + clip_box.x1 - clip_box.x0, + clip_box.y1 - clip_box.y0); +} + +inline void +draw_bind_texture(Render_Target *target, i32 texid){ + if (target->bound_texture != texid){ + glBindTexture(GL_TEXTURE_2D, texid); + target->bound_texture = texid; + } +} + +inline void +draw_set_color(Render_Target *target, u32 color){ + if (target->color != color){ + target->color = color; + Vec4 c = unpack_color4(color); + glColor4f(c.r, c.g, c.b, c.a); + } +} + +internal void +draw_push_clip(Render_Target *target, i32_Rect clip_box){ + Assert(target->clip_top == -1 || + fits_inside(clip_box, target->clip_boxes[target->clip_top])); + Assert(target->clip_top+1 < ArrayCount(target->clip_boxes)); + target->clip_boxes[++target->clip_top] = clip_box; + draw_set_clip(target, clip_box); +} + +internal void +draw_pop_clip(Render_Target *target){ + Assert(target->clip_top > 0); + --target->clip_top; + draw_set_clip(target, target->clip_boxes[target->clip_top]); +} + +#define PutStruct(s,x) *(s*)(target->push_buffer + target->size) = x; target->size += sizeof(s) + +internal void +draw_push_piece(Render_Target *target, Render_Piece_Combined piece){ + PutStruct(Render_Piece_Header, piece.header); - return rect; -} - -inline i32_Rect -rect_clamp_to_rect(i32 left, i32 top, i32 right, i32 bottom, i32_Rect clamp_box){ - return rect_clamp_to_rect(i32R(left, top, right, bottom), clamp_box); -} - -inline i32_Rect -rect_from_target(Render_Target *target){ - return i32R(0, 0, target->width, target->height); -} - -#if SOFTWARE_RENDER -internal void -draw_clear(Render_Target *target, u32 color){ - u8 *pixel_line = (u8*)target->pixel_data; - for (i32 pixel_y = 0; pixel_y < target->height; ++pixel_y){ - u32 *pixel = (u32*)pixel_line; - for (i32 pixel_x = 0; pixel_x < target->width; ++pixel_x){ - *pixel++ = color; - } - pixel_line += target->pitch; - } -} - -internal void -draw_vertical_line(Render_Target *target, - i32 x, i32 top, i32 bottom, - u32 color){ - if (x >= 0 && x < target->width){ - if (top < 0){ - top = 0; - } - if (bottom >= target->height){ - bottom = target->height - 1; - } + switch (piece.header.type){ + case piece_type_rectangle: + case piece_type_outline: + PutStruct(Render_Piece_Rectangle, piece.rectangle); + break; - if (top <= bottom){ - i32 y_range = bottom - top; - u8 *pixel_line = (u8*)target->pixel_data + top*target->pitch; - for (i32 pixel_y = 0; pixel_y <= y_range; ++pixel_y){ - u32 *pixel = (u32*)pixel_line + x; - *pixel = color; - pixel_line += target->pitch; - } - } - } + case piece_type_gradient: + PutStruct(Render_Piece_Gradient, piece.gradient); + break; + + case piece_type_glyph: + case piece_type_mono_glyph: + PutStruct(Render_Piece_Glyph, piece.glyph); + break; + + case piece_type_mono_glyph_advance: + PutStruct(Render_Piece_Glyph_Advance, piece.glyph_advance); + break; + } + + Assert(target->size <= target->max); } -internal void -draw_horizontal_line(Render_Target *target, - i32 y, i32 left, i32 right, - u32 color){ - if (y >= 0 && y < target->height){ - if (left < 0){ - left = 0; - } - if (right >= target->width){ - right = target->width - 1; - } - - if (left <= right){ - i32 x_range = right - left; - u8 *pixel_line = (u8*)target->pixel_data + y*target->pitch; - u32 *pixel = (u32*)pixel_line + left; - for (i32 pixel_x = 0; pixel_x <= x_range; ++pixel_x){ - *pixel = color; - ++pixel; - } - } - } -} +#define ExtractStruct(s) ((s*)cursor); cursor += sizeof(s) -internal void -draw_rectangle_blend_2corner_unclamped(Render_Target *target, - Blit_Rect rect, u32 color){ - if (rect.x_start < rect.x_end && rect.y_start < rect.y_end){ - i32 y_range = rect.y_end - rect.y_start; - i32 x_range = rect.x_end - rect.x_start; - - u8 a,r,g,b; - a = (u8)(color >> 24); - r = (u8)(color >> 16); - g = (u8)(color >> 8); - b = (u8)(color >> 0); - - real32 blend = (a/255.f); - real32 pr, pg, pb; - pr = r*blend; - pg = g*blend; - pb = b*blend; - - real32 inv_blend = 1.f - blend; - - u8 *pixel_line = (u8*)target->pixel_data + rect.y_start*target->pitch; - for (i32 pixel_y = 0; pixel_y < y_range; ++pixel_y){ - u32 *pixel = (u32*)pixel_line + rect.x_start; - for (i32 pixel_x = 0; pixel_x < x_range; ++pixel_x){ - u8 dr,dg,db; - dr = (u8)(*pixel >> 16); - dg = (u8)(*pixel >> 8); - db = (u8)(*pixel >> 0); - - dr = (u8)(dr*inv_blend + pr); - dg = (u8)(dg*inv_blend + pg); - db = (u8)(db*inv_blend + pb); - - *pixel = (dr << 16) | (dg << 8) | (db); - ++pixel; - } - pixel_line += target->pitch; - } - } -} - -internal void -draw_rectangle_noblend_2corner_unclamped(Render_Target *target, - Blit_Rect rect, u32 color){ - if (rect.x_start < rect.x_end && rect.y_start < rect.y_end){ - i32 y_range = rect.y_end - rect.y_start; - i32 x_range = rect.x_end - rect.x_start; - - u8 *pixel_line = (u8*)target->pixel_data + rect.y_start*target->pitch; - for (i32 pixel_y = 0; pixel_y < y_range; ++pixel_y){ - u32 *pixel = (u32*)pixel_line + rect.x_start; - for (i32 pixel_x = 0; pixel_x < x_range; ++pixel_x){ - *pixel++ = color; - } - pixel_line += target->pitch; - } - } -} - -// NOTE(allen): uses of this can be replaced with draw_rectangle_2corner_unclamped -// if it is guaranteed that clip_box will be within the target area. inline void -draw_rectangle_2corner_clipped(Render_Target *target, - i32 left, i32 top, i32 right, i32 bottom, - u32 color, Blit_Rect clip_box){ - clip_box = rect_clamp_to_rect(clip_box, rect_from_target(target)); - Blit_Rect rect = rect_clamp_to_rect(left, top, right, bottom, clip_box); - draw_rectangle_noblend_2corner_unclamped(target, rect, color); +private_draw_rectangle(Render_Target *target, f32_Rect rect, u32 color){ + draw_set_color(target, color); + draw_bind_texture(target, 0); + glBegin(GL_QUADS); + { + glVertex2f(rect.x0, rect.y0); + glVertex2f(rect.x0, rect.y1); + glVertex2f(rect.x1, rect.y1); + glVertex2f(rect.x1, rect.y0); + } + glEnd(); } inline void -draw_rectangle_2corner(Render_Target *target, - i32 left, i32 top, i32 right, i32 bottom, - u32 color){ - Blit_Rect rect = rect_clamp_to_rect(left, top, right, bottom, rect_from_target(target)); - draw_rectangle_noblend_2corner_unclamped(target, rect, color); +private_draw_rectangle_outline(Render_Target *target, f32_Rect rect, u32 color){ + f32_Rect r; + r.x0 = rect.x0 + .5f; + r.y0 = rect.y0 + .5f; + r.x1 = rect.x1 - .5f; + r.y1 = rect.y1 - .5f; + + draw_set_color(target, color); + draw_bind_texture(target, 0); + glBegin(GL_LINE_STRIP); + { + glVertex2f(r.x0, r.y0); + glVertex2f(r.x1, r.y0); + glVertex2f(r.x1, r.y1); + glVertex2f(r.x0, r.y1); + glVertex2f(r.x0, r.y0); + } + glEnd(); } inline void -draw_rectangle_clipped(Render_Target *target, - i32 x, i32 y, i32 w, i32 h, - u32 color, Blit_Rect clip_box){ - draw_rectangle_2corner_clipped(target, x, y, x+w, y+h, color, clip_box); +private_draw_gradient(Render_Target *target, f32_Rect rect, + Vec4 color_left, Vec4 color_right){ + Vec4 cl = color_left; + Vec4 cr = color_right; + + draw_bind_texture(target, 0); + glBegin(GL_QUADS); + { + glColor4f(cl.r, cl.g, cl.b, cl.a); + glVertex2f(rect.x0, rect.y0); + glVertex2f(rect.x0, rect.y1); + + glColor4f(cr.r, cr.g, cr.b, cr.a); + glVertex2f(rect.x1, rect.y1); + glVertex2f(rect.x1, rect.y0); + } + glEnd(); } inline void -draw_rectangle(Render_Target *target, - i32 x, i32 y, i32 w, i32 h, - u32 color){ - draw_rectangle_2corner(target, x, y, x+w, y+h, color); +private_draw_glyph(Render_Target *target, Render_Font *font, + u16 character, f32 x, f32 y, u32 color){ + f32 x_shift, y_shift; + x_shift = 0; + y_shift = (f32)font->ascent; + + x += x_shift; + y += y_shift; + + stbtt_aligned_quad q; + stbtt_GetBakedQuadUnrounded(font->chardata, font->tex_width, font->tex_height, + character, &x, &y, &q, 1); + + draw_set_color(target, color); + draw_bind_texture(target, font->tex); + glBegin(GL_QUADS); + { + glTexCoord2f(q.s0, q.t1); glVertex2f(q.x0, q.y1); + glTexCoord2f(q.s1, q.t1); glVertex2f(q.x1, q.y1); + glTexCoord2f(q.s1, q.t0); glVertex2f(q.x1, q.y0); + glTexCoord2f(q.s0, q.t0); glVertex2f(q.x0, q.y0); + } + glEnd(); +} + +inline void +private_draw_glyph_mono(Render_Target *target, Render_Font *font, u16 character, + f32 x, f32 y, f32 advance, u32 color){ + f32 x_shift, y_shift; + i32 left = font->chardata[character].x0; + i32 right = font->chardata[character].x1; + i32 width = (right - left); + x_shift = (f32)(advance - width) * .5f - font->chardata[character].xoff; + y_shift = (f32)font->ascent; + + x += x_shift; + y += y_shift; + + stbtt_aligned_quad q; + stbtt_GetBakedQuadUnrounded(font->chardata, font->tex_width, font->tex_height, character, &x, &y, &q, 1); + + draw_set_color(target, color); + draw_bind_texture(target, font->tex); + glBegin(GL_QUADS); + { + glTexCoord2f(q.s0, q.t1); glVertex2f(q.x0, q.y1); + glTexCoord2f(q.s1, q.t1); glVertex2f(q.x1, q.y1); + glTexCoord2f(q.s1, q.t0); glVertex2f(q.x1, q.y0); + glTexCoord2f(q.s0, q.t0); glVertex2f(q.x0, q.y0); + } + glEnd(); +} + +inline void +private_draw_glyph_mono(Render_Target *target, Render_Font *font, u16 character, + real32 x, real32 y, u32 color){ + private_draw_glyph_mono(target, font, character, x, y, (f32)font->advance, color); } internal void -draw_rectangle_outline_unclamped(Render_Target *target, - i32 x, i32 y, i32 w, i32 h, - u32 color, Blit_Rect rect){ - if (rect.x_start <= rect.x_end && rect.y_start <= rect.y_end){ - if (rect.y_start == y){ - draw_horizontal_line(target, - rect.y_start, rect.x_start, rect.x_end-1, - color); - } - - if (rect.y_end == y+h){ - draw_horizontal_line(target, - rect.y_end-1, rect.x_start, rect.x_end-1, - color); - } - - if (rect.x_start == x){ - draw_vertical_line(target, - rect.x_start, rect.y_start, rect.y_end-1, - color); - } - - if (rect.x_end == x+w){ - draw_vertical_line(target, - rect.x_end-1, rect.y_start, rect.y_end-1, - color); - } - } +launch_rendering(Render_Target *target){ + byte *cursor = target->push_buffer; + byte *cursor_end = cursor + target->size; + + for (; cursor < cursor_end;){ + Render_Piece_Header *header = ExtractStruct(Render_Piece_Header); + + i32 type = header->type; + switch (type){ + case piece_type_rectangle: + { + Render_Piece_Rectangle *rectangle = + ExtractStruct(Render_Piece_Rectangle); + private_draw_rectangle(target, rectangle->rect, rectangle->color); + }break; + + case piece_type_outline: + { + Render_Piece_Rectangle *rectangle = + ExtractStruct(Render_Piece_Rectangle); + private_draw_rectangle_outline(target, rectangle->rect, rectangle->color); + }break; + + case piece_type_gradient: + { + Render_Piece_Gradient *gradient = + ExtractStruct(Render_Piece_Gradient); + private_draw_gradient(target, gradient->rect, + unpack_color4(gradient->left_color), + unpack_color4(gradient->right_color)); + }break; + + case piece_type_glyph: + { + Render_Piece_Glyph *glyph = + ExtractStruct(Render_Piece_Glyph); + Render_Font *font = glyph->font_id; + + private_draw_glyph(target, font, glyph->character, + glyph->pos.x, glyph->pos.y, glyph->color); + }break; + + case piece_type_mono_glyph: + { + Render_Piece_Glyph *glyph = + ExtractStruct(Render_Piece_Glyph); + Render_Font *font = glyph->font_id; + + private_draw_glyph_mono(target, font, glyph->character, + glyph->pos.x, glyph->pos.y, glyph->color); + }break; + + case piece_type_mono_glyph_advance: + { + Render_Piece_Glyph_Advance *glyph = + ExtractStruct(Render_Piece_Glyph_Advance); + Render_Font *font = glyph->font_id; + + private_draw_glyph_mono(target, font, glyph->character, + glyph->pos.x, glyph->pos.y, + glyph->advance, glyph->color); + }break; + } + } } -internal void -draw_rectangle_outline_clipped(Render_Target *target, - i32 x, i32 y, i32 w, i32 h, - u32 color, Blit_Rect clip_box){ - clip_box = rect_clamp_to_rect(clip_box, rect_from_target(target)); - Blit_Rect rect = rect_clamp_to_rect(x, y, x+w, y+h, clip_box); - draw_rectangle_outline_unclamped(target, x, y, w, h, color, rect); -} - -internal void -draw_rectangle_outline(Render_Target *target, - i32 x, i32 y, i32 w, i32 h, - u32 color){ - Blit_Rect rect = rect_clamp_to_rect(x, y, x+w, y+h, rect_from_target(target)); - draw_rectangle_outline_unclamped(target, x, y, w, h, color, rect); -} - -// TODO(allen): eliminate this? -internal i32 -font_init(){ - return 1; -} - -inline internal i32 -font_predict_size(i32 pt_size){ - return pt_size*pt_size*128; -} +#undef ExtractStruct internal i32 -font_load(Font *font_out, i32 pt_size, - void *font_block, i32 font_block_size, - i32 *memory_used_out){ +draw_font_load(System_Functions *system, + Render_Font *font_out, + char *filename, + i32 pt_size, + void *font_block, + i32 font_block_size, + i32 *memory_used_out, + i32 tab_width){ i32 result = 1; - File_Data file; - file = system_load_file((u8*)"liberation-mono.ttf"); + Data file; + file = system->load_file(filename); if (!file.data){ result = 0; @@ -277,280 +305,59 @@ font_load(Font *font_out, i32 pt_size, font_out->descent = (i32)(scaled_descent); font_out->line_skip = (i32)(scaled_line_gap); - i32 max_advance = 0; - - bool32 block_full = 0, block_overfull = 0; u8 *memory_cursor = (u8*)font_block; - for (u16 code_point = 0; code_point < 128; ++code_point){ - i32 glyph_index; - - if (block_full){ - block_overfull = 1; - font_out->glyphs[code_point] = {}; - continue; - } - - else{ - glyph_index = stbtt_FindGlyphIndex(&font, code_point); - if (glyph_index != 0){ - font_out->glyphs[code_point].exists = 1; - - i32 left, right, top, bottom; - stbtt_GetGlyphBitmapBox(&font, glyph_index, scale, scale, &left, &top, &right, &bottom); - - i32 glyph_width, glyph_height; - i32 data_width, data_height; - glyph_width = right - left; - glyph_height = bottom - top; - data_width = glyph_width + 2; - data_height = glyph_height + 2; - - font_out->glyphs[code_point].minx = left; - font_out->glyphs[code_point].maxx = right; - font_out->glyphs[code_point].miny = top; - font_out->glyphs[code_point].maxy = bottom; - font_out->glyphs[code_point].width = data_width; - font_out->glyphs[code_point].height = data_height; - - i32 advance, left_bearing; - stbtt_GetGlyphHMetrics(&font, glyph_index, &advance, &left_bearing); - - font_out->glyphs[code_point].left_shift = (i32)(scale*left_bearing); - - if (advance > max_advance){ - max_advance = advance; - } - - u8 *data = memory_cursor; - memory_cursor = memory_cursor + data_width*data_height; - - i32 size_after_glyph = (i32)((u8*)memory_cursor - (u8*)font_block); - if (size_after_glyph >= font_block_size){ - block_full = 1; - if (size_after_glyph > font_block_size){ - block_overfull = 1; - } - } - else{ - font_out->glyphs[code_point].data = data; - u8 *data_start = data + data_width + 1; - stbtt_MakeGlyphBitmap(&font, data_start, - glyph_width, glyph_height, data_width, - scale, scale, - glyph_index); - } - } - else{ - font_out->glyphs[code_point] = {}; - } - } + Assert(pt_size*pt_size*128 <= font_block_size); + + i32 tex_width, tex_height; + tex_width = pt_size*128; + tex_height = pt_size*2; + + font_out->tex_width = tex_width; + font_out->tex_height = tex_height; + + if (stbtt_BakeFontBitmap((u8*)file.data, 0, (real32)pt_size, + memory_cursor, tex_width, tex_height, 0, 128, font_out->chardata) <= 0){ + result = 0; } - font_out->advance = Ceil(max_advance*scale); + else{ + GLuint font_tex; + glGenTextures(1, &font_tex); + glBindTexture(GL_TEXTURE_2D, font_tex); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex_width, tex_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, memory_cursor); + + font_out->tex = font_tex; + glBindTexture(GL_TEXTURE_2D, 0); + } + + font_out->chardata['\r'] = font_out->chardata[' ']; + font_out->chardata['\n'] = font_out->chardata[' ']; + font_out->chardata['\t'] = font_out->chardata[' ']; + font_out->chardata['\t'].xadvance *= tab_width; + + i32 max_advance = 0; + for (u16 code_point = 0; code_point < 128; ++code_point){ + if (stbtt_FindGlyphIndex(&font, code_point) != 0){ + font_out->glyphs[code_point].exists = 1; + i32 advance = CEIL32(font_out->chardata[code_point].xadvance); + if (max_advance < advance) max_advance = advance; + font_out->advance_data[code_point] = font_out->chardata[code_point].xadvance; + } + } + font_out->advance = max_advance - 1; } - system_free_file(file); + system->free_file(file); } return result; } -internal void -font_draw_glyph_subpixel(Render_Target *target, - Font *font, u16 character, - real32 x, real32 y, u32 color, - Blit_Rect clip){ - if (clip.x_start <= clip.x_end && clip.y_start <= clip.y_end){ - Glyph_Data glyph = font->glyphs[character]; - - Vec2 s_origin = V2(x - 1.f, y - 1.f); - - i32 left_most = (i32)(x); - i32 top_most = (i32)(y); - - real32 xe = x + glyph.width - 2; - real32 ye = y + glyph.height - 2; - i32 right_most = (i32)(xe)+(xe>0)*((i32)xe != xe); - i32 bottom_most = (i32)(ye)+(ye>0)*((i32)ye != ye); - - if (left_most < clip.x_start){ - left_most = clip.x_start; - } - - if (top_most < clip.y_start){ - top_most = clip.y_start; - } - - if (right_most >= clip.x_end){ - right_most = clip.x_end - 1; - } - - if (bottom_most >= clip.y_end){ - bottom_most = clip.y_end - 1; - } - - u8 *dest_data = (u8*)target->pixel_data; - u8 *src_data = (u8*)glyph.data; - - i32 width = glyph.width; - i32 target_pitch = target->pitch; - - real32 inv_255 = 1.f / 255.f; - - real32 cr,cg,cb,ca; - cb = (real32)((color) & 0xFF); - cg = (real32)((color >> 8) & 0xFF); - cr = (real32)((color >> 16) & 0xFF); - ca = (real32)((color >> 24) & 0xFF); - - i32 lox_start = (i32)(left_most - s_origin.x); - i32 loy_start = (i32)(top_most - s_origin.y); - - real32 lX = left_most - s_origin.x - lox_start; - real32 lY = top_most - s_origin.y - loy_start; - - real32 inv_lX = 1.f - lX; - real32 inv_lY = 1.f - lY; - - i32 loy = loy_start * width; - - u8 *dest_line = (dest_data + top_most*target_pitch); - for (i32 y = top_most; y <= bottom_most; ++y){ - u8 src_a[4]; - - i32 lox_loy = lox_start + loy; - src_a[0] = *(src_data + (lox_loy)); - src_a[2] = *(src_data + (lox_loy + width)); - - u32 *dest_pixel = (u32*)(dest_line) + left_most; - - for (i32 x = left_most; x <= right_most; ++x){ - src_a[1] = *(src_data + (lox_loy + 1)); - src_a[3] = *(src_data + (lox_loy + 1 + width)); - - real32 alpha = (src_a[0]*(inv_lX) + src_a[1]*(lX))*(inv_lY) + - (src_a[2]*(inv_lX) + src_a[3]*(lX))*(lY); - alpha *= inv_255; - - u32 dp = *dest_pixel; - - real32 dr,dg,db,da; - db = (real32)((dp) & 0xFF); - dg = (real32)((dp >> 8) & 0xFF); - dr = (real32)((dp >> 16) & 0xFF); - da = (real32)((dp >> 24) & 0xFF); - - db = db + (cb - db)*alpha; - dg = dg + (cg - dg)*alpha; - dr = dr + (cr - dr)*alpha; - da = da + (ca - da)*alpha; - - *dest_pixel = ((u8)db) | (((u8)dg) << 8) | (((u8)dr) << 16) | (((u8)da) << 24); - - ++dest_pixel; - ++lox_loy; - - src_a[0] = src_a[1]; - src_a[2] = src_a[3]; - } - loy += width; - dest_line += target_pitch; - } - } -} - -internal void -font_draw_glyph(Render_Target *target, Font *font, u16 character, - real32 x, real32 y, u32 color){ - Glyph_Data glyph = font->glyphs[character]; - - i32 left = glyph.minx; - i32 right = glyph.maxx; - i32 width = right - left; - - real32 x_shift, y_shift; - x_shift = glyph.left_shift + (real32)width / font->advance; - y_shift = (real32)font->ascent + glyph.miny; - - x += x_shift; - y += y_shift; - - i32 xi, yi; - xi = (i32)(x); - yi = (i32)(y); - - Blit_Rect rect = rect_clamp_to_rect(xi, yi, xi+glyph.width-1, yi+glyph.height-1, rect_from_target(target)); - font_draw_glyph_subpixel(target, font, character, x, y, color, rect); -} - -internal void -font_draw_glyph_clipped(Render_Target *target, - Font *font, u16 character, - real32 x, real32 y, u32 color, - Blit_Rect clip_box){ - Glyph_Data glyph = font->glyphs[character]; - - i32 left = glyph.minx; - i32 right = glyph.maxx; - i32 width = right - left; - - real32 x_shift, y_shift; - x_shift = glyph.left_shift + (real32)width / font->advance; - y_shift = (real32)font->ascent + glyph.miny; - - x += x_shift; - y += y_shift; - - i32 xi, yi; - xi = (i32)(x); - yi = (i32)(y); - - clip_box = rect_clamp_to_rect(clip_box, rect_from_target(target)); - Blit_Rect rect = rect_clamp_to_rect(xi, yi, xi+glyph.width-1, yi+glyph.height-1, clip_box); - font_draw_glyph_subpixel(target, font, character, x, y, color, rect); -} - -#else - -inline void -draw_set_clip(Render_Target *target, i32_Rect clip_box){ - glScissor(clip_box.x0, - target->height - clip_box.y1, - clip_box.x1 - clip_box.x0, - clip_box.y1 - clip_box.y0); -} - -inline void -draw_push_clip(Render_Target *target, i32_Rect clip_box){ - Assert(target->clip_top == -1 || - fits_inside(clip_box, target->clip_boxes[target->clip_top])); - Assert(target->clip_top+1 < ArrayCount(target->clip_boxes)); - target->clip_boxes[++target->clip_top] = clip_box; - draw_set_clip(target, clip_box); -} - -inline void -draw_pop_clip(Render_Target *target){ - Assert(target->clip_top > 0); - --target->clip_top; - draw_set_clip(target, target->clip_boxes[target->clip_top]); -} - -inline void -draw_bind_texture(Render_Target *target, i32 texid){ - if (target->bound_texture != texid){ - glBindTexture(GL_TEXTURE_2D, texid); - target->bound_texture = texid; - } -} - -internal void -draw_set_color(Render_Target *target, u32 color){ - if (target->color != color){ - target->color = color; - Vec4 c = unpack_color4(color); - glColor4f(c.r, c.g, c.b, c.a); - } -} +#if 0 internal void draw_rectangle(Render_Target *target, i32_Rect rect, u32 color){ @@ -566,20 +373,6 @@ draw_rectangle(Render_Target *target, i32_Rect rect, u32 color){ glEnd(); } -internal void -draw_rectangle(Render_Target *target, real32_Rect rect, u32 color){ - draw_set_color(target, color); - draw_bind_texture(target, 0); - glBegin(GL_QUADS); - { - glVertex2f(rect.x0, rect.y0); - glVertex2f(rect.x0, rect.y1); - glVertex2f(rect.x1, rect.y1); - glVertex2f(rect.x1, rect.y0); - } - glEnd(); -} - internal void draw_triangle_3corner(Render_Target *target, real32 x0, real32 y0, @@ -597,53 +390,12 @@ draw_triangle_3corner(Render_Target *target, glEnd(); } -internal void -draw_gradient_2corner_clipped(Render_Target *target, real32_Rect rect, - Vec4 color_left, Vec4 color_right){ - Vec4 cl = color_left; - Vec4 cr = color_right; - - draw_bind_texture(target, 0); - glBegin(GL_QUADS); - { - glColor4f(cl.r, cl.g, cl.b, cl.a); - glVertex2f(rect.x0, rect.y0); - glVertex2f(rect.x0, rect.y1); - - glColor4f(cr.r, cr.g, cr.b, cr.a); - glVertex2f(rect.x1, rect.y1); - glVertex2f(rect.x1, rect.y0); - } - glEnd(); -} - inline void draw_gradient_2corner_clipped(Render_Target *target, real32 l, real32 t, real32 r, real32 b, Vec4 color_left, Vec4 color_right){ draw_gradient_2corner_clipped(target, f32R(l,t,r,b), color_left, color_right); } -internal void -draw_rectangle_outline(Render_Target *target, real32_Rect rect, u32 color){ - real32_Rect r; - r.x0 = rect.x0 + .5f; - r.y0 = rect.y0 + .5f; - r.x1 = rect.x1 - .5f; - r.y1 = rect.y1 - .5f; - - draw_set_color(target, color); - draw_bind_texture(target, 0); - glBegin(GL_LINE_STRIP); - { - glVertex2f(r.x0, r.y0); - glVertex2f(r.x1, r.y0); - glVertex2f(r.x1, r.y1); - glVertex2f(r.x0, r.y1); - glVertex2f(r.x0, r.y0); - } - glEnd(); -} - inline void draw_rectangle_outline(Render_Target *target, i32_Rect rect, u32 color){ draw_rectangle_outline(target, f32R(rect), color); @@ -657,12 +409,6 @@ draw_margin(Render_Target *target, i32_Rect outer, i32_Rect inner, u32 color){ draw_rectangle(target, i32R(inner.x1, inner.y0, outer.x1, inner.y1), color); } -// TODO(allen): eliminate this? -internal i32 -font_init(){ - return 1; -} - inline internal i32 font_predict_size(i32 pt_size){ return pt_size*pt_size*128; @@ -670,7 +416,7 @@ font_predict_size(i32 pt_size){ internal i32 font_load(System_Functions *system, - Font *font_out, char *filename, i32 pt_size, + Render_Font *font_out, char *filename, i32 pt_size, void *font_block, i32 font_block_size, i32 *memory_used_out, i32 tab_width){ i32 result = 1; @@ -757,76 +503,17 @@ font_load(System_Functions *system, } internal void -font_set_tabwidth(Font *font, i32 tab_width){ +font_set_tabwidth(Render_Font *font, i32 tab_width){ font->chardata['\t'].xadvance *= font->chardata[' '].xadvance * tab_width; } -internal void -font_draw_glyph_mono(Render_Target *target, Font *font, u16 character, - real32 x, real32 y, real32 advance, u32 color){ - real32 x_shift, y_shift; - i32 left = font->chardata[character].x0; - i32 right = font->chardata[character].x1; - i32 width = (right - left); - x_shift = (real32)(advance - width) * .5f - font->chardata[character].xoff; - y_shift = (real32)font->ascent; - - x += x_shift; - y += y_shift; - - stbtt_aligned_quad q; - stbtt_GetBakedQuadUnrounded(font->chardata, font->tex_width, font->tex_height, character, &x, &y, &q, 1); - - draw_set_color(target, color); - draw_bind_texture(target, font->tex); - glBegin(GL_QUADS); - { - glTexCoord2f(q.s0, q.t1); glVertex2f(q.x0, q.y1); - glTexCoord2f(q.s1, q.t1); glVertex2f(q.x1, q.y1); - glTexCoord2f(q.s1, q.t0); glVertex2f(q.x1, q.y0); - glTexCoord2f(q.s0, q.t0); glVertex2f(q.x0, q.y0); - } - glEnd(); -} - -inline void -font_draw_glyph_mono(Render_Target *target, Font *font, u16 character, - real32 x, real32 y, u32 color){ - font_draw_glyph_mono(target, font, character, x, y, (real32)font->advance, color); -} - -internal void -font_draw_glyph(Render_Target *target, Font *font, u16 character, - real32 x, real32 y, u32 color){ - real32 x_shift, y_shift; - x_shift = 0; - y_shift = (real32)font->ascent; - - x += x_shift; - y += y_shift; - - stbtt_aligned_quad q; - stbtt_GetBakedQuadUnrounded(font->chardata, font->tex_width, font->tex_height, character, &x, &y, &q, 1); - - draw_set_color(target, color); - draw_bind_texture(target, font->tex); - glBegin(GL_QUADS); - { - glTexCoord2f(q.s0, q.t1); glVertex2f(q.x0, q.y1); - glTexCoord2f(q.s1, q.t1); glVertex2f(q.x1, q.y1); - glTexCoord2f(q.s1, q.t0); glVertex2f(q.x1, q.y0); - glTexCoord2f(q.s0, q.t0); glVertex2f(q.x0, q.y0); - } - glEnd(); -} - inline real32 -font_get_glyph_width(Font *font, u16 character){ +font_get_glyph_width(Render_Font *font, u16 character){ return font->chardata[character].xadvance; } internal real32 -font_string_width(Font *font, char *str){ +font_string_width(Render_Font *font, char *str){ real32 x = 0; for (i32 i = 0; str[i]; ++i){ x += font_get_glyph_width(font, str[i]); @@ -835,7 +522,7 @@ font_string_width(Font *font, char *str){ } internal i32 -draw_string(Render_Target *target, Font *font, char *str, +draw_string(Render_Target *target, Render_Font *font, char *str, i32 x_, i32 y, u32 color){ real32 x = (real32)x_; for (i32 i = 0; str[i]; ++i){ @@ -848,7 +535,7 @@ draw_string(Render_Target *target, Font *font, char *str, } internal real32 -draw_string_mono(Render_Target *target, Font *font, char *str, +draw_string_mono(Render_Target *target, Render_Font *font, char *str, real32 x, real32 y, real32 advance, u32 color){ for (i32 i = 0; str[i]; ++i){ font_draw_glyph_mono(target, font, str[i], @@ -859,7 +546,7 @@ draw_string_mono(Render_Target *target, Font *font, char *str, } internal i32 -draw_string(Render_Target *target, Font *font, String str, +draw_string(Render_Target *target, Render_Font *font, String str, i32 x_, i32 y, u32 color){ real32 x = (real32)x_; for (i32 i = 0; i < str.size; ++i){ @@ -872,7 +559,7 @@ draw_string(Render_Target *target, Font *font, String str, } internal real32 -draw_string_mono(Render_Target *target, Font *font, String str, +draw_string_mono(Render_Target *target, Render_Font *font, String str, real32 x, real32 y, real32 advance, u32 color){ for (i32 i = 0; i < str.size; ++i){ font_draw_glyph_mono(target, font, str.str[i], @@ -883,7 +570,7 @@ draw_string_mono(Render_Target *target, Font *font, String str, } internal real32 -font_get_max_width(Font *font, char *characters){ +font_get_max_width(Render_Font *font, char *characters){ stbtt_bakedchar *chardata = font->chardata; real32 cx, x = 0; for (i32 i = 0; characters[i]; ++i){ @@ -894,14 +581,13 @@ font_get_max_width(Font *font, char *characters){ } internal real32 -font_get_string_width(Font *font, String string){ +font_get_string_width(Render_Font *font, String string){ real32 result = 0; for (i32 i = 0; i < string.size; ++i){ font_get_glyph_width(font, string.str[i]); } return result; } - #endif // BOTTOM diff --git a/4ed_rendering.h b/4ed_rendering.h index 572279e5..bed4bdce 100644 --- a/4ed_rendering.h +++ b/4ed_rendering.h @@ -1,46 +1,28 @@ /* * Mr. 4th Dimention - Allen Webster * - * 12.17.2014 + * 17.12.2014 * * Rendering layer for project codename "4ed" * */ +// TOP + #ifndef FRED_RENDERING_H #define FRED_RENDERING_H #define STB_TRUETYPE_IMPLEMENTATION #include "stb_truetype.h" -#if SOFTWARE_RENDER struct Glyph_Data{ - void *data; - i32 width, height; - i32 minx, maxx, miny, maxy; - i32 left_shift; - bool32 exists; + b32 exists; }; -struct Font{ - Glyph_Data glyphs[128]; - i32 height, ascent, descent, line_skip; - i32 advance; -}; -#else -struct Glyph_Data{ -#if 0 - i32 width, height; - i32 minx, maxx, miny, maxy; - i32 left_shift; -#endif - bool32 exists; -}; - -struct Font{ +struct Render_Font{ char name_[24]; String name; - bool32 loaded; + b32 loaded; Glyph_Data glyphs[256]; stbtt_bakedchar chardata[256]; @@ -50,6 +32,101 @@ struct Font{ u32 tex; i32 tex_width, tex_height; }; -#endif + +struct Render_Target; + +#define Draw_Push_Clip_Sig(name) void name(Render_Target *target, i32_Rect clip_box) +typedef Draw_Push_Clip_Sig(Draw_Push_Clip); + +#define Draw_Pop_Clip_Sig(name) void name(Render_Target *target) +typedef Draw_Pop_Clip_Sig(Draw_Pop_Clip); + +enum Render_Piece_Type{ + piece_type_rectangle, + piece_type_outline, + piece_type_gradient, + piece_type_glyph, + piece_type_mono_glyph, + piece_type_mono_glyph_advance +}; + +struct Render_Piece_Header{ + i32 type; +}; + +struct Render_Piece_Rectangle{ + f32_Rect rect; + u32 color; +}; + +struct Render_Piece_Gradient{ + f32_Rect rect; + u32 left_color, right_color; +}; + +struct Render_Piece_Glyph{ + Vec2 pos; + u32 color; + Render_Font *font_id; + u16 character; +}; + +struct Render_Piece_Glyph_Advance{ + Vec2 pos; + u32 color; + f32 advance; + Render_Font *font_id; + u16 character; +}; + +struct Render_Piece_Combined{ + Render_Piece_Header header; + union{ + Render_Piece_Rectangle rectangle; + Render_Piece_Gradient gradient; + Render_Piece_Glyph glyph; + Render_Piece_Glyph_Advance glyph_advance; + }; +}; + +#define Draw_Push_Piece_Sig(name) void name(Render_Target *target, Render_Piece_Combined piece) +typedef Draw_Push_Piece_Sig(Draw_Push_Piece); + +#define Font_Load_Sig(name) i32 name( \ + System_Functions *system, \ + Render_Font *font_out, \ + char *filename, \ + i32 pt_size, \ + void *font_block, \ + i32 font_block_size, \ + i32 *memory_used_out, \ + i32 tab_width) +typedef Font_Load_Sig(Font_Load); + +struct Render_Target{ + void *handle; + void *context; + i32_Rect clip_boxes[5]; + i32 clip_top; + i32 width, height; + i32 bound_texture; + u32 color; + + byte *push_buffer; + i32 size, max; + + Draw_Push_Clip *push_clip; + Draw_Pop_Clip *pop_clip; + Draw_Push_Piece *push_piece; + Font_Load *font_load; +}; + +inline i32_Rect +rect_from_target(Render_Target *target){ + return i32R(0, 0, target->width, target->height); +} #endif + +// BOTTOM + diff --git a/4ed_rendering_helper.cpp b/4ed_rendering_helper.cpp new file mode 100644 index 00000000..161fdda3 --- /dev/null +++ b/4ed_rendering_helper.cpp @@ -0,0 +1,215 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 12.17.2014 + * + * Rendering layer for project codename "4ed" + * + */ + +// TOP + +inline void +draw_push_clip(Render_Target *target, i32_Rect clip_box){ + target->push_clip(target, clip_box); +} + +inline void +draw_pop_clip(Render_Target *target){ + target->pop_clip(target); +} + +internal void +draw_rectangle(Render_Target *target, i32_Rect rect, u32 color){ + Render_Piece_Combined piece; + piece.header.type = piece_type_rectangle; + piece.rectangle.rect = f32R(rect); + piece.rectangle.color = color; + target->push_piece(target, piece); +} + +internal void +draw_rectangle(Render_Target *target, f32_Rect rect, u32 color){ + Render_Piece_Combined piece; + piece.header.type = piece_type_rectangle; + piece.rectangle.rect = rect; + piece.rectangle.color = color; + target->push_piece(target, piece); +} + +internal void +draw_gradient_2corner_clipped(Render_Target *target, f32_Rect rect, + Vec4 left_color, Vec4 right_color){ + Render_Piece_Combined piece; + piece.header.type = piece_type_gradient; + piece.gradient.rect = rect; + piece.gradient.left_color = pack_color4(left_color); + piece.gradient.right_color = pack_color4(right_color); + target->push_piece(target, piece); +} + +inline void +draw_gradient_2corner_clipped(Render_Target *target, f32 l, f32 t, f32 r, f32 b, + Vec4 color_left, Vec4 color_right){ + draw_gradient_2corner_clipped(target, f32R(l,t,r,b), color_left, color_right); +} + +internal void +draw_rectangle_outline(Render_Target *target, f32_Rect rect, u32 color){ + Render_Piece_Combined piece; + piece.header.type = piece_type_outline; + piece.rectangle.rect = rect; + piece.rectangle.color = color; + target->push_piece(target, piece); +} + +inline void +draw_rectangle_outline(Render_Target *target, i32_Rect rect, u32 color){ + draw_rectangle_outline(target, f32R(rect), color); +} + +internal void +draw_margin(Render_Target *target, i32_Rect outer, i32_Rect inner, u32 color){ + draw_rectangle(target, i32R(outer.x0, outer.y0, outer.x1, inner.y0), color); + draw_rectangle(target, i32R(outer.x0, inner.y1, outer.x1, outer.y1), color); + draw_rectangle(target, i32R(outer.x0, inner.y0, inner.x0, inner.y1), color); + draw_rectangle(target, i32R(inner.x1, inner.y0, outer.x1, inner.y1), color); +} + +inline internal i32 +font_predict_size(i32 pt_size){ + return pt_size*pt_size*128; +} + +internal i32 +font_load(Render_Target *target, System_Functions *system, + Render_Font *font_out, char *filename, i32 pt_size, + void *font_block, i32 font_block_size, + i32 *memory_used_out, i32 tab_width){ + i32 result = + target->font_load(system, font_out, filename, pt_size, + font_block, font_block_size, memory_used_out, tab_width); + return result; +} + +internal void +font_set_tabwidth(Render_Font *font, i32 tab_width){ + font->chardata['\t'].xadvance *= font->chardata[' '].xadvance * tab_width; +} + +// TODO(allen): Abstract Render_Font all the fucking way out of the app side code. +internal void +font_draw_glyph_mono(Render_Target *target, Render_Font *font, u16 character, + f32 x, f32 y, f32 advance, u32 color){ + Render_Piece_Combined piece; + piece.header.type = piece_type_mono_glyph; + piece.glyph.pos.x = x; + piece.glyph.pos.y = y; + piece.glyph.color = color; + piece.glyph.font_id = font; + piece.glyph.character = character; + target->push_piece(target, piece); +} + +inline void +font_draw_glyph_mono(Render_Target *target, Render_Font *font, u16 character, + real32 x, real32 y, u32 color){ + font_draw_glyph_mono(target, font, character, x, y, (real32)font->advance, color); +} + +internal void +font_draw_glyph(Render_Target *target, Render_Font *font, u16 character, + f32 x, f32 y, u32 color){ + Render_Piece_Combined piece; + piece.header.type = piece_type_glyph; + piece.glyph.pos.x = x; + piece.glyph.pos.y = y; + piece.glyph.color = color; + piece.glyph.font_id = font; + piece.glyph.character = character; + target->push_piece(target, piece); +} + +inline real32 +font_get_glyph_width(Render_Font *font, u16 character){ + return font->chardata[character].xadvance; +} + +internal real32 +font_string_width(Render_Font *font, char *str){ + real32 x = 0; + for (i32 i = 0; str[i]; ++i){ + x += font_get_glyph_width(font, str[i]); + } + return x; +} + +internal i32 +draw_string(Render_Target *target, Render_Font *font, char *str, + i32 x_, i32 y, u32 color){ + real32 x = (real32)x_; + for (i32 i = 0; str[i]; ++i){ + char c = str[i]; + font_draw_glyph(target, font, c, + x, (real32)y, color); + x += font_get_glyph_width(font, c); + } + return CEIL32(x); +} + +internal real32 +draw_string_mono(Render_Target *target, Render_Font *font, char *str, + real32 x, real32 y, real32 advance, u32 color){ + for (i32 i = 0; str[i]; ++i){ + font_draw_glyph_mono(target, font, str[i], + x, y, advance, color); + x += advance; + } + return x; +} + +internal i32 +draw_string(Render_Target *target, Render_Font *font, String str, + i32 x_, i32 y, u32 color){ + real32 x = (real32)x_; + for (i32 i = 0; i < str.size; ++i){ + char c = str.str[i]; + font_draw_glyph(target, font, c, + x, (real32)y, color); + x += font_get_glyph_width(font, c); + } + return CEIL32(x); +} + +internal real32 +draw_string_mono(Render_Target *target, Render_Font *font, String str, + real32 x, real32 y, real32 advance, u32 color){ + for (i32 i = 0; i < str.size; ++i){ + font_draw_glyph_mono(target, font, str.str[i], + x, y, advance, color); + x += advance; + } + return x; +} + +internal real32 +font_get_max_width(Render_Font *font, char *characters){ + stbtt_bakedchar *chardata = font->chardata; + real32 cx, x = 0; + for (i32 i = 0; characters[i]; ++i){ + cx = chardata[characters[i]].xadvance; + if (x < cx) x = cx; + } + return x; +} + +internal real32 +font_get_string_width(Render_Font *font, String string){ + real32 result = 0; + for (i32 i = 0; i < string.size; ++i){ + font_get_glyph_width(font, string.str[i]); + } + return result; +} + +// BOTTOM diff --git a/4ed_rendering_old.cpp b/4ed_rendering_old.cpp new file mode 100644 index 00000000..41a140a1 --- /dev/null +++ b/4ed_rendering_old.cpp @@ -0,0 +1,405 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 12.17.2014 + * + * Rendering layer for project codename "4ed" + * + */ + +// TOP + +#if 0 +inline void +draw_set_clip(Render_Target *target, i32_Rect clip_box){ + glScissor(clip_box.x0, + target->height - clip_box.y1, + clip_box.x1 - clip_box.x0, + clip_box.y1 - clip_box.y0); +} + +inline void +draw_push_clip(Render_Target *target, i32_Rect clip_box){ + Assert(target->clip_top == -1 || + fits_inside(clip_box, target->clip_boxes[target->clip_top])); + Assert(target->clip_top+1 < ArrayCount(target->clip_boxes)); + target->clip_boxes[++target->clip_top] = clip_box; + draw_set_clip(target, clip_box); +} + +inline void +draw_pop_clip(Render_Target *target){ + Assert(target->clip_top > 0); + --target->clip_top; + draw_set_clip(target, target->clip_boxes[target->clip_top]); +} + +inline void +draw_bind_texture(Render_Target *target, i32 texid){ + if (target->bound_texture != texid){ + glBindTexture(GL_TEXTURE_2D, texid); + target->bound_texture = texid; + } +} + +internal void +draw_set_color(Render_Target *target, u32 color){ + if (target->color != color){ + target->color = color; + Vec4 c = unpack_color4(color); + glColor4f(c.r, c.g, c.b, c.a); + } +} + +internal void +draw_rectangle(Render_Target *target, i32_Rect rect, u32 color){ + draw_set_color(target, color); + draw_bind_texture(target, 0); + glBegin(GL_QUADS); + { + glVertex2i(rect.x0, rect.y0); + glVertex2i(rect.x0, rect.y1); + glVertex2i(rect.x1, rect.y1); + glVertex2i(rect.x1, rect.y0); + } + glEnd(); +} + +internal void +draw_rectangle(Render_Target *target, real32_Rect rect, u32 color){ + draw_set_color(target, color); + draw_bind_texture(target, 0); + glBegin(GL_QUADS); + { + glVertex2f(rect.x0, rect.y0); + glVertex2f(rect.x0, rect.y1); + glVertex2f(rect.x1, rect.y1); + glVertex2f(rect.x1, rect.y0); + } + glEnd(); +} + +internal void +draw_triangle_3corner(Render_Target *target, + real32 x0, real32 y0, + real32 x1, real32 y1, + real32 x2, real32 y2, + u32 color){ + draw_set_color(target, color); + draw_bind_texture(target, 0); + glBegin(GL_TRIANGLES); + { + glVertex2f(x0, y0); + glVertex2f(x1, y1); + glVertex2f(x2, y2); + } + glEnd(); +} + +internal void +draw_gradient_2corner_clipped(Render_Target *target, real32_Rect rect, + Vec4 color_left, Vec4 color_right){ + Vec4 cl = color_left; + Vec4 cr = color_right; + + draw_bind_texture(target, 0); + glBegin(GL_QUADS); + { + glColor4f(cl.r, cl.g, cl.b, cl.a); + glVertex2f(rect.x0, rect.y0); + glVertex2f(rect.x0, rect.y1); + + glColor4f(cr.r, cr.g, cr.b, cr.a); + glVertex2f(rect.x1, rect.y1); + glVertex2f(rect.x1, rect.y0); + } + glEnd(); +} + +inline void +draw_gradient_2corner_clipped(Render_Target *target, real32 l, real32 t, real32 r, real32 b, + Vec4 color_left, Vec4 color_right){ + draw_gradient_2corner_clipped(target, f32R(l,t,r,b), color_left, color_right); +} + +internal void +draw_rectangle_outline(Render_Target *target, real32_Rect rect, u32 color){ + real32_Rect r; + r.x0 = rect.x0 + .5f; + r.y0 = rect.y0 + .5f; + r.x1 = rect.x1 - .5f; + r.y1 = rect.y1 - .5f; + + draw_set_color(target, color); + draw_bind_texture(target, 0); + glBegin(GL_LINE_STRIP); + { + glVertex2f(r.x0, r.y0); + glVertex2f(r.x1, r.y0); + glVertex2f(r.x1, r.y1); + glVertex2f(r.x0, r.y1); + glVertex2f(r.x0, r.y0); + } + glEnd(); +} + +inline void +draw_rectangle_outline(Render_Target *target, i32_Rect rect, u32 color){ + draw_rectangle_outline(target, f32R(rect), color); +} + +internal void +draw_margin(Render_Target *target, i32_Rect outer, i32_Rect inner, u32 color){ + draw_rectangle(target, i32R(outer.x0, outer.y0, outer.x1, inner.y0), color); + draw_rectangle(target, i32R(outer.x0, inner.y1, outer.x1, outer.y1), color); + draw_rectangle(target, i32R(outer.x0, inner.y0, inner.x0, inner.y1), color); + draw_rectangle(target, i32R(inner.x1, inner.y0, outer.x1, inner.y1), color); +} + +// TODO(allen): eliminate this? +internal i32 +font_init(){ + return 1; +} + +inline internal i32 +font_predict_size(i32 pt_size){ + return pt_size*pt_size*128; +} + +internal i32 +font_load(System_Functions *system, + Render_Font *font_out, char *filename, i32 pt_size, + void *font_block, i32 font_block_size, + i32 *memory_used_out, i32 tab_width){ + i32 result = 1; + File_Data file; + file = system->load_file(filename); + + if (!file.data){ + result = 0; + } + + else{ + stbtt_fontinfo font; + if (!stbtt_InitFont(&font, (u8*)file.data, 0)){ + result = 0; + } + else{ + i32 ascent, descent, line_gap; + real32 scale; + + stbtt_GetFontVMetrics(&font, &ascent, &descent, &line_gap); + scale = stbtt_ScaleForPixelHeight(&font, (real32)pt_size); + + real32 scaled_ascent, scaled_descent, scaled_line_gap; + + scaled_ascent = scale*ascent; + scaled_descent = scale*descent; + scaled_line_gap = scale*line_gap; + + font_out->height = (i32)(scaled_ascent - scaled_descent + scaled_line_gap); + font_out->ascent = (i32)(scaled_ascent); + font_out->descent = (i32)(scaled_descent); + font_out->line_skip = (i32)(scaled_line_gap); + + u8 *memory_cursor = (u8*)font_block; + Assert(pt_size*pt_size*128 <= font_block_size); + + i32 tex_width, tex_height; + tex_width = pt_size*128; + tex_height = pt_size*2; + + font_out->tex_width = tex_width; + font_out->tex_height = tex_height; + + if (stbtt_BakeFontBitmap((u8*)file.data, 0, (real32)pt_size, + memory_cursor, tex_width, tex_height, 0, 128, font_out->chardata) <= 0){ + result = 0; + } + + else{ + GLuint font_tex; + glGenTextures(1, &font_tex); + glBindTexture(GL_TEXTURE_2D, font_tex); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex_width, tex_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, memory_cursor); + + font_out->tex = font_tex; + glBindTexture(GL_TEXTURE_2D, 0); + } + + font_out->chardata['\r'] = font_out->chardata[' ']; + font_out->chardata['\n'] = font_out->chardata[' ']; + font_out->chardata['\t'] = font_out->chardata[' ']; + font_out->chardata['\t'].xadvance *= tab_width; + + i32 max_advance = 0; + for (u16 code_point = 0; code_point < 128; ++code_point){ + if (stbtt_FindGlyphIndex(&font, code_point) != 0){ + font_out->glyphs[code_point].exists = 1; + i32 advance = CEIL32(font_out->chardata[code_point].xadvance); + if (max_advance < advance) max_advance = advance; + font_out->advance_data[code_point] = font_out->chardata[code_point].xadvance; + } + } + font_out->advance = max_advance - 1; + } + system->free_file(file); + } + + return result; +} + +internal void +font_set_tabwidth(Render_Font *font, i32 tab_width){ + font->chardata['\t'].xadvance *= font->chardata[' '].xadvance * tab_width; +} + +internal void +font_draw_glyph_mono(Render_Target *target, Render_Font *font, u16 character, + real32 x, real32 y, real32 advance, u32 color){ + real32 x_shift, y_shift; + i32 left = font->chardata[character].x0; + i32 right = font->chardata[character].x1; + i32 width = (right - left); + x_shift = (real32)(advance - width) * .5f - font->chardata[character].xoff; + y_shift = (real32)font->ascent; + + x += x_shift; + y += y_shift; + + stbtt_aligned_quad q; + stbtt_GetBakedQuadUnrounded(font->chardata, font->tex_width, font->tex_height, character, &x, &y, &q, 1); + + draw_set_color(target, color); + draw_bind_texture(target, font->tex); + glBegin(GL_QUADS); + { + glTexCoord2f(q.s0, q.t1); glVertex2f(q.x0, q.y1); + glTexCoord2f(q.s1, q.t1); glVertex2f(q.x1, q.y1); + glTexCoord2f(q.s1, q.t0); glVertex2f(q.x1, q.y0); + glTexCoord2f(q.s0, q.t0); glVertex2f(q.x0, q.y0); + } + glEnd(); +} + +inline void +font_draw_glyph_mono(Render_Target *target, Render_Font *font, u16 character, + real32 x, real32 y, u32 color){ + font_draw_glyph_mono(target, font, character, x, y, (real32)font->advance, color); +} + +internal void +font_draw_glyph(Render_Target *target, Render_Font *font, u16 character, + real32 x, real32 y, u32 color){ + real32 x_shift, y_shift; + x_shift = 0; + y_shift = (real32)font->ascent; + + x += x_shift; + y += y_shift; + + stbtt_aligned_quad q; + stbtt_GetBakedQuadUnrounded(font->chardata, font->tex_width, font->tex_height, character, &x, &y, &q, 1); + + draw_set_color(target, color); + draw_bind_texture(target, font->tex); + glBegin(GL_QUADS); + { + glTexCoord2f(q.s0, q.t1); glVertex2f(q.x0, q.y1); + glTexCoord2f(q.s1, q.t1); glVertex2f(q.x1, q.y1); + glTexCoord2f(q.s1, q.t0); glVertex2f(q.x1, q.y0); + glTexCoord2f(q.s0, q.t0); glVertex2f(q.x0, q.y0); + } + glEnd(); +} + +inline real32 +font_get_glyph_width(Render_Font *font, u16 character){ + return font->chardata[character].xadvance; +} + +internal real32 +font_string_width(Render_Font *font, char *str){ + real32 x = 0; + for (i32 i = 0; str[i]; ++i){ + x += font_get_glyph_width(font, str[i]); + } + return x; +} + +internal i32 +draw_string(Render_Target *target, Render_Font *font, char *str, + i32 x_, i32 y, u32 color){ + real32 x = (real32)x_; + for (i32 i = 0; str[i]; ++i){ + char c = str[i]; + font_draw_glyph(target, font, c, + x, (real32)y, color); + x += font_get_glyph_width(font, c); + } + return CEIL32(x); +} + +internal real32 +draw_string_mono(Render_Target *target, Render_Font *font, char *str, + real32 x, real32 y, real32 advance, u32 color){ + for (i32 i = 0; str[i]; ++i){ + font_draw_glyph_mono(target, font, str[i], + x, y, advance, color); + x += advance; + } + return x; +} + +internal i32 +draw_string(Render_Target *target, Render_Font *font, String str, + i32 x_, i32 y, u32 color){ + real32 x = (real32)x_; + for (i32 i = 0; i < str.size; ++i){ + char c = str.str[i]; + font_draw_glyph(target, font, c, + x, (real32)y, color); + x += font_get_glyph_width(font, c); + } + return CEIL32(x); +} + +internal real32 +draw_string_mono(Render_Target *target, Render_Font *font, String str, + real32 x, real32 y, real32 advance, u32 color){ + for (i32 i = 0; i < str.size; ++i){ + font_draw_glyph_mono(target, font, str.str[i], + x, y, advance, color); + x += advance; + } + return x; +} + +internal real32 +font_get_max_width(Render_Font *font, char *characters){ + stbtt_bakedchar *chardata = font->chardata; + real32 cx, x = 0; + for (i32 i = 0; characters[i]; ++i){ + cx = chardata[characters[i]].xadvance; + if (x < cx) x = cx; + } + return x; +} + +internal real32 +font_get_string_width(Render_Font *font, String string){ + real32 result = 0; + for (i32 i = 0; i < string.size; ++i){ + font_get_glyph_width(font, string.str[i]); + } + return result; +} +#endif + +// BOTTOM diff --git a/4ed_style.cpp b/4ed_style.cpp index 192c20e1..f2a07e6d 100644 --- a/4ed_style.cpp +++ b/4ed_style.cpp @@ -214,7 +214,7 @@ struct Style_File_Format{ struct Style{ char name_[24]; String name; - Font *font; + Render_Font *font; Style_Main_Data main; bool32 font_changed; }; @@ -225,7 +225,7 @@ struct Style_Library{ }; struct Font_Set{ - Font *fonts; + Render_Font *fonts; i32 count, max; }; @@ -243,12 +243,12 @@ style_set_name(Style *style, String name){ copy(&style->name, name); } -internal Font* +internal Render_Font* font_set_extract(Font_Set *fonts, char *name, i32 size){ String n = make_string(name, size); i32 count = fonts->count; - Font *result = 0; - Font *font = fonts->fonts; + Render_Font *result = 0; + Render_Font *font = fonts->fonts; for (i32 i = 0; i < count; ++i, ++font){ if (match(n, font->name)){ result = font; @@ -479,7 +479,7 @@ style_library_import(System_Functions *system, char *filename, Font_Set *fonts, Style *out, i32 max, i32 *count_opt, i32 *total_opt = 0){ b32 result = 1; - File_Data file = system->load_file(filename); + Data file = system->load_file(filename); Style_Page_Header *h = 0; if (!file.data){ @@ -573,7 +573,7 @@ style_library_add(Style_Library *library, Style *style){ internal Style_File_Format* style_format_for_file(Style *style, Style_File_Format *out){ - Font *font = style->font; + Render_Font *font = style->font; out->name_size = style->name.size; memcpy(out->name, style->name.str, ArrayCount(out->name)); out->font_name_size = font->name.size; diff --git a/4ed_system.h b/4ed_system.h index 95673d99..741d3259 100644 --- a/4ed_system.h +++ b/4ed_system.h @@ -15,17 +15,12 @@ struct Plat_Handle{ u32 d[4]; }; -struct File_Data{ - void *data; - u32 size; -}; - struct Time_Stamp{ u64 time; b32 success; }; -#define Sys_Load_File_Sig(name) File_Data name(char *filename) +#define Sys_Load_File_Sig(name) Data name(char *filename) typedef Sys_Load_File_Sig(System_Load_File); #define Sys_Save_File_Sig(name) i32 name(char *filename, void *data, i32 size) @@ -40,10 +35,8 @@ typedef Sys_File_Time_Stamp_Sig(System_File_Time_Stamp); #define Sys_Time_Stamp_Now_Sig(name) u64 name() typedef Sys_Time_Stamp_Now_Sig(System_Time_Stamp_Now); -#if 0 -#define Sys_Free_File_Sig(name) void name(File_Data file) +#define Sys_Free_File_Sig(name) void name(Data file) typedef Sys_Free_File_Sig(System_Free_File); -#endif #define Sys_Get_Current_Directory_Sig(name) i32 name(char *out, i32 max) typedef Sys_Get_Current_Directory_Sig(System_Get_Current_Directory); @@ -127,8 +120,9 @@ struct Thread_Memory{ i32 id; }; -#define Job_Callback(name) void name(System_Functions *system, Thread_Context *thread, Thread_Memory *memory, void *data[2]) -typedef Job_Callback(Job_Callback); +#define Job_Callback_Sig(name) void name(\ + System_Functions *system, Thread_Context *thread, Thread_Memory *memory, void *data[2]) +typedef Job_Callback_Sig(Job_Callback); struct Job_Data{ Job_Callback *callback; @@ -169,6 +163,9 @@ typedef INTERNAL_Sys_Sentinel_Sig(INTERNAL_System_Sentinel); #define INTERNAL_Sys_Get_Thread_States_Sig(name) void name(Thread_Group_ID id, b8 *running, i32 *pending) typedef INTERNAL_Sys_Get_Thread_States_Sig(INTERNAL_System_Get_Thread_States); +#define INTERNAL_Sys_Debug_Message_Sig(name) void name(char *message) +typedef INTERNAL_Sys_Debug_Message_Sig(INTERNAL_System_Debug_Message); + struct System_Functions{ System_Load_File *load_file; System_Save_File *save_file; @@ -206,6 +203,7 @@ struct System_Functions{ INTERNAL_System_Sentinel *internal_sentinel; INTERNAL_System_Get_Thread_States *internal_get_thread_states; + INTERNAL_System_Debug_Message *internal_debug_message; }; // BOTTOM diff --git a/4ed_win32_keyboard.cpp b/4ed_win32_keyboard.cpp new file mode 100644 index 00000000..fcd27375 --- /dev/null +++ b/4ed_win32_keyboard.cpp @@ -0,0 +1,80 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 12.17.2014 + * + * Win32-US Keyboard layer for 4coder + * + */ + +// TOP + +#include "4ed_keyboard.cpp" + +internal void +keycode_init(Key_Codes *codes){ + set_dynamic_key_names(codes); + + u16 code, loose; + for (u8 i = 0; i < 255; ++i){ + if ((i >= '0' && i <= '9') || + (i >= 'A' && i <= 'Z')){ + keycode_lookup_table[i] = i; + loose_keycode_lookup_table[i] = 0; + } + + else{ + loose = 0; + switch (i){ + case VK_SPACE: code = loose = ' '; break; + case VK_BACK: code = loose = codes->back; break; + case VK_OEM_MINUS: code = '-'; break; + case VK_OEM_PLUS: code = '='; break; + case VK_SUBTRACT: code = '-'; break; + case VK_ADD: code = '+'; break; + case VK_MULTIPLY: code = '*'; break; + case VK_DIVIDE: code = '/'; break; + + case VK_OEM_3: code = '`'; break; + case VK_OEM_5: code = '\\'; break; + case VK_OEM_4: code = '['; break; + case VK_OEM_6: code = ']'; break; + case VK_TAB: code = loose = '\t'; break; + case VK_RETURN: code = loose = '\n'; break; + case VK_OEM_7: code = '\''; break; + + case VK_OEM_1: code = ';'; break; + case VK_OEM_2: code = '/'; break; + case VK_OEM_PERIOD: code = '.'; break; + case VK_OEM_COMMA: code = ','; break; + + case VK_DELETE: code = loose = codes->del; break; + case VK_UP: code = loose = codes->up; break; + case VK_DOWN: code = loose = codes->down; break; + case VK_LEFT: code = loose = codes->left; break; + case VK_RIGHT: code = loose = codes->right; break; + + case VK_INSERT: code = loose = codes->insert; break; + case VK_HOME: code = loose = codes->home; break; + case VK_END: code = loose = codes->end; break; + case VK_PRIOR: code = loose = codes->page_up; break; + case VK_NEXT: code = loose = codes->page_down; break; + case VK_ESCAPE: code = loose = codes->esc; break; + + case VK_NUMPAD0: + case VK_NUMPAD1: case VK_NUMPAD2: case VK_NUMPAD3: + case VK_NUMPAD4: case VK_NUMPAD5: case VK_NUMPAD6: + case VK_NUMPAD7: case VK_NUMPAD8: case VK_NUMPAD9: + code = (i - VK_NUMPAD0) + '0'; break; + + default: code = 0; break; + } + + keycode_lookup_table[i] = code; + loose_keycode_lookup_table[i] = loose; + } + } +} + +// BOTTOM + diff --git a/dll_reader.cpp b/dll_reader.cpp new file mode 100644 index 00000000..11bfeaa7 --- /dev/null +++ b/dll_reader.cpp @@ -0,0 +1,206 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 12.12.2014 + * + * Application layer for project codename "4ed" + * + */ + +// TOP + +#include "4ed_meta.h" +#include "4ed_dll_reader.h" +#include "4ed_dll_reader.cpp" + +i32 +compare(char *a, char *b, i32 len){ + i32 result; + char *e; + + result = 0; + e = a + len; + for (;a < e && *a == *b; ++a, ++b); + if (a < e){ + if (*a < *b) result = -1; + else result = 1; + } + + return(result); +} + +#include +#include +#include + +Data +load_file(char *filename){ + Data result; + FILE * file; + + result = {}; + file = fopen(filename, "rb"); + if (!file){ + printf("file %s not found\n", filename); + } + else{ + fseek(file, 0, SEEK_END); + result.size = ftell(file); + fseek(file, 0, SEEK_SET); + result.data = (byte*)malloc(result.size); + fread(result.data, 1, result.size, file); + fclose(file); + } + + return(result); +} + +void +show_reloc_block(Data file, DLL_Data *dll, PE_Section_Definition *reloc_section){ + byte *base; + Relocation_Block_Header *header; + Relocation_Block_Entry *entry; + u32 cursor; + u32 bytes_in_table; + u32 block_end; + + base = file.data + reloc_section->disk_location; + if (dll->is_64bit) bytes_in_table = dll->opt_header_64->data_directory[image_dir_base_reloc_table].size; + else bytes_in_table = dll->opt_header_32->data_directory[image_dir_base_reloc_table].size; + + for (cursor = 0; cursor < bytes_in_table;){ + header = (Relocation_Block_Header*)(base + cursor); + block_end = cursor + header->block_size; + cursor += sizeof(Relocation_Block_Header); + + printf("block-size: %d\n", header->block_size); + printf("offset-base: %d\n", header->page_base_offset); + + for (;cursor < block_end;){ + entry = (Relocation_Block_Entry*)(base + cursor); + cursor += sizeof(Relocation_Block_Entry); + printf("reloc: type %d offset %d\n", + (i32)(entry->entry & reloc_entry_type_mask) >> reloc_entry_type_shift, + (i32)(entry->entry & reloc_entry_offset_mask)); + } + } +} + +typedef int (Function)(int a, int b); + +#include + +#define UseWinDll 0 + +int +main(int argc, char **argv){ + Function *func; + i32 x; + +#if UseWinDll + HMODULE module; + + if (argc < 2){ + printf("usage: dll_reader \n"); + exit(1); + } + + module = LoadLibraryA(argv[1]); + + if (!module){ + printf("failed to load file %s\n", argv[1]); + exit(1); + } + + func = (Function*)GetProcAddress(module, "test_func"); + +#else + Data file, img; + DLL_Data dll; + DLL_Loaded dll_loaded; + PE_Section_Definition *section_def; + i32 error; + i32 i; + + if (argc < 2){ + printf("usage: dll_reader \n"); + exit(1); + } + + file = load_file(argv[1]); + + if (!file.data){ + printf("failed to load file %s\n", argv[1]); + exit(1); + } + + if (!dll_parse_headers(file, &dll, &error)){ + printf("header error %d\n", error); + exit(1); + } + + printf("this appears to be a dll\n"); + + printf("symbol-count: %d symbol-addr: %d\n", + dll.coff_header->number_of_symbols, + dll.coff_header->pointer_to_symbol_table); + + if (dll.is_64bit) printf("64bit\n"); + else printf("32bit\n"); + + printf("built for machine: %s\n", dll_machine_type_str(dll.coff_header->machine, 0)); + + if (dll.is_64bit){ + printf("number of directories: %d\n", dll.opt_header_64->number_of_rva_and_sizes); + } + else{ + printf("number of directories: %d\n", dll.opt_header_32->number_of_rva_and_sizes); + } + + printf("\nbeginning section decode now\n"); + + section_def = dll.section_defs; + for (i = 0; i < dll.coff_header->number_of_sections; ++i, ++section_def){ + if (section_def->name[7] == 0){ + printf("name: %s\n", section_def->name); + } + else{ + printf("name: %.*s\n", 8, section_def->name); + } + printf("img-size: %d img-loc: %d\ndisk-size: %d disk-loc: %d\n", + section_def->loaded_size, section_def->loaded_location, + section_def->disk_size, section_def->disk_location); + + if (compare(section_def->name, ".reloc", 6) == 0){ + show_reloc_block(file, &dll, section_def); + } + } + + img.size = dll_total_loaded_size(&dll); + printf("image size: %d\n", img.size); + + img.data = (byte*) + VirtualAlloc((LPVOID)Tbytes(3), img.size, + MEM_COMMIT | MEM_RESERVE, + PAGE_READWRITE); + dll_load(img, &dll_loaded, file, &dll); + + DWORD _extra; + VirtualProtect(img.data + dll_loaded.text_start, + dll_loaded.text_size, + PAGE_EXECUTE_READ, + &_extra); + + func = (Function*)dll_load_function(&dll_loaded, "test_func", 9); +#endif + + x = func(10, 20); + printf("%d\n", x); + + x = func(1, 2); + printf("%d\n", x); + + return(0); +} + +// BOTTOM diff --git a/linux_4ed.cpp b/linux_4ed.cpp index 9cb773c2..539a8850 100644 --- a/linux_4ed.cpp +++ b/linux_4ed.cpp @@ -75,18 +75,27 @@ #include #include #include -#include + +#include +#include + #include +#include + #include "4ed_internal.h" #include "4ed_linux_keyboard.cpp" #define printe(m) printf("%s:%d: %s\n", __FILE__, __LINE__, #m) struct Linux_Vars{ - Application_Memory mem; + Key_Codes codes; Key_Input_Data input; + Mouse_State mouse; + Render_Target target; + Application_Memory mem; b32 keep_going; + b32 force_redraw; Clipboard_Contents clipboard; @@ -95,6 +104,7 @@ struct Linux_Vars{ System_Functions *system; App_Functions app; Config_API config_api; + }; Linux_Vars linuxvars; @@ -206,13 +216,11 @@ LinuxLoadAppCode(){ --size); memcpy(path + size + 1, app_code_file, app_code_file_len + 1); - linuxvars.app_code = SDL_LoadObject(path); + linuxvars.app_code = 0; if (linuxvars.app_code){ result = 1; - linuxvars.app.init = (App_Init*) - SDL_LoadFunction(linuxvars.app_code, "app_init"); - linuxvars.app.step = (App_Step*) - SDL_LoadFunction(linuxvars.app_code, "app_step"); + linuxvars.app.init = (App_Init*)0; + linuxvars.app.step = (App_Step*)0; } else{ // TODO(allen): initialization failure @@ -232,6 +240,11 @@ Sys_Release_Lock_Sig(system_release_lock){ AllowLocal(id); } +internal +Sys_Force_Redraw_Sig(system_force_redraw){ + linuxvars.force_redraw = 1; +} + internal void LinuxLoadSystemCode(){ linuxvars.system->get_memory_full = system_get_memory_; @@ -275,16 +288,13 @@ LinuxLoadSystemCode(){ #endif } +internal void +LinuxShowScreen(){ +} + int main(){ linuxvars = {}; - if (SDL_Init(SDL_INIT_VIDEO)){ - // TODO(allen): initialization failure - printe(SDL_Init); - return(1); - } - SDL_EnableUNICODE(1); - if (!LinuxLoadAppCode()){ return(1); } @@ -293,14 +303,7 @@ int main(){ System_Functions *system = &system_; linuxvars.system = system; LinuxLoadSystemCode(); - - const SDL_VideoInfo *info = SDL_GetVideoInfo(); - if (!info){ - // TODO(allen): initialization failure - printe(info); - return(1); - } - + { void *base; #if FRED_INTERNAL @@ -329,72 +332,59 @@ int main(){ i32 width = 800; i32 height = 600; - i32 bpp = info->vfmt->BitsPerPixel; - - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - - i32 flags = SDL_OPENGL; - - if (SDL_SetVideoMode(width, height, bpp, flags) == 0){ - // TODO(allen): initialization failure - printe(SDL_SetVideoMode); - return(1); - } - - SDL_WM_SetCaption("4coder-window", 0); + i32 bpp = 24; + linuxvars.target.width = width; + linuxvars.target.height = height; + + keycode_init(&linuxvars.codes); + system_acquire_lock(FRAME_LOCK); b32 first = 1; linuxvars.keep_going = 1; - - SDL_Event event; - for (;linuxvars.keep_going && SDL_WaitEvent(&event);){ - b32 pass_to_app = 0; - + i64 timer_start = system_time(); + + for (;linuxvars.keep_going;){ linuxvars.input = {}; linuxvars.clipboard = {}; - switch (event.type){ - case SDL_ACTIVEEVENT: - { - if ((event.active.state & SDL_APPACTIVE) && event.active.gain) - pass_to_app = 1; - }break; - - case SDL_KEYDOWN: - { - pass_to_app = 1; - linuxvars.input.press[linuxvars.input.press_count++] = - get_key_event(&event); - }break; - - case SDL_QUIT: - { - linuxvars.keep_going = 0; - }break; + linuxvars.mouse.wheel = 0; + linuxvars.force_redraw = 0; + for (;0;){ } - if (pass_to_app){ - Application_Step_Result app_result = - linuxvars.app.step(linuxvars.system, - 0, - 0, - &linuxvars.input, - 0, - 1, - 0, - &linuxvars.mem, - linuxvars.clipboard, - first, 1); - - - - SDL_GL_SwapBuffers(); + linuxvars.mouse.left_button_prev = linuxvars.mouse.left_button; + linuxvars.mouse.right_button_prev = linuxvars.mouse.right_button; + +#if 0 + Application_Step_Result app_result = + linuxvars.app.step(linuxvars.system, + &linuxvars.codes, + &linuxvars.input, + &linuxvars.mouse, + &linuxvars.target, + &linuxvars.mem, + linuxvars.clipboard, + 1, first, linuxvars.force_redraw); +#else + Application_Step_Result app_result = {}; +#endif + + if (1 || linuxvars.force_redraw){ + //glClearColor(1.f, 1.f, 0.f, 1.f); + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + LinuxShowScreen(); + linuxvars.force_redraw = 0; } + + i64 timer_target = timer_start + frame_useconds; + i64 timer_end = system_time(); + for (;timer_end < timer_target;){ + i64 samount = timer_target - timer_end; + usleep(samount); + timer_end = system_time(); + } + timer_start = system_time(); } return(0); diff --git a/test/dll_test.cpp b/test/dll_test.cpp new file mode 100644 index 00000000..3c70cf73 --- /dev/null +++ b/test/dll_test.cpp @@ -0,0 +1,37 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 12.12.2014 + * + * Application layer for project codename "4ed" + * + */ + +// TOP + +#define dll_export extern "C" + +int stuff[] = { + 1, 2 +}; + +struct Crap{ + int x; + int *stuff; +}; + +Crap crap = { 0, stuff }; + +dll_export int +test_func(int a, int b){ + int r; + r = a + crap.stuff[crap.x]; + + crap.stuff[crap.x] = b; + crap.x = (crap.x+1)&1; + + return(r); +} + +// BOTTOM + diff --git a/test/experiment.cpp b/test/experiment.cpp index bd7e96bf..f70a3d47 100644 --- a/test/experiment.cpp +++ b/test/experiment.cpp @@ -9,21 +9,6 @@ // TOP -// HOLY GRAIL -#if 0 -int main(){ - Parse_Context context; - Parse_Definitions definitions; - Cpp_Parse_Preprocessor_State state; - - cpp_default_context(&context, COMPILER_MSVC, PLATFORM_WIN32); - cpp_default_definitions(&definitions, COMPILER_MSVC, PLATFORM_WIN32); - cpp_set_target_file(&definitions, &state, "TARGET.cpp"); - - cpp_parse(&context, &definitions, &state); -} -#endif - #include "../4ed_meta.h" #include "../4cpp_types.h" @@ -31,6 +16,7 @@ int main(){ #include "../4cpp_string.h" #define FCPP_LEXER_IMPLEMENTATION #include "../4cpp_lexer.h" +#include "../4cpp_preprocessor.cpp" #include #include @@ -58,20 +44,21 @@ system_is_absoute_path(char *path){ #define Assert assert #define TentativeAssert assert -#include "../4cpp_preprocessor.cpp" - Cpp_File quickie_file(char *filename){ - Cpp_File result; + Cpp_File result = {}; FILE *file = fopen(filename, "rb"); - TentativeAssert(file); - fseek(file, 0, SEEK_END); - result.size = ftell(file); - fseek(file, 0, SEEK_SET); - result.data = (char*)malloc(result.size); - fread(result.data, 1, result.size, file); - fclose(file); + if (file){ + fseek(file, 0, SEEK_END); + result.size = ftell(file); + if (result.size > 0){ + fseek(file, 0, SEEK_SET); + result.data = (char*)malloc(result.size); + fread(result.data, 1, result.size, file); + } + fclose(file); + } return result; } @@ -87,12 +74,20 @@ quickie_file(String filename){ #define STRICT_MEM_TEST 1 -#if 1 -int main(){ - char TEST_FILE[] = "parser_test6.cpp"; +int main(int argc, char **argv){ + if (argc < 2){ + printf("usage: %s \n", argv[0]); + return 1; + } + char *TEST_FILE = argv[1]; Cpp_File target_file; target_file = quickie_file(TEST_FILE); + + if (target_file.data == 0){ + printf("could not open file %s\n", TEST_FILE); + exit(1); + } Cpp_Token_Stack target_tokens = {}; cpp_lex_file(target_file, &target_tokens); @@ -138,7 +133,7 @@ int main(){ #endif string_tokens.tokens = (Cpp_Token*)malloc(sizeof(Cpp_Token)*string_tokens.max_count); - Cpp_Parse_File string_parse_file; + Cpp_File_Data string_parse_file; string_parse_file.file = string_file; string_parse_file.tokens = string_tokens; string_parse_file.filename = string_filename; @@ -201,6 +196,10 @@ int main(){ for (; cpp_has_more_files(&request); cpp_get_next_file(&request)){ if (!cpp_try_reuse_file(&request)){ Cpp_File new_file = quickie_file(request.filename); + if (new_file.data == 0){ + printf("could not open file %s\n", request.filename); + exit(1); + } Cpp_Token_Stack new_tokens = {}; cpp_lex_file(new_file, &new_tokens); cpp_provide_file(&request, new_file, new_tokens); @@ -210,7 +209,7 @@ int main(){ if (result.error_code){ String error_message = cpp_get_error(result.error_code); - Cpp_Parse_File file = *cpp_get_parse_file(&definitions, result.file_index); + Cpp_File_Data file = *cpp_get_parse_file(&definitions, result.file_index); Cpp_Token token = file.tokens.tokens[result.token_index]; bool terminate = cpp_recommend_termination(result.error_code); @@ -229,11 +228,11 @@ int main(){ } if (result.emit){ - Cpp_Parse_File file = *cpp_get_parse_file(&definitions, result.file_index); + Cpp_File_Data file = *cpp_get_parse_file(&definitions, result.file_index); Cpp_Token token = file.tokens.tokens[result.token_index]; if (result.from_macro){ - Cpp_Parse_File file = *cpp_get_parse_file(&definitions, result.invoking_file_index); + Cpp_File_Data file = *cpp_get_parse_file(&definitions, result.invoking_file_index); Cpp_Token token = file.tokens.tokens[result.invoking_token_index]; printf("EXPANDING %.*s => ", token.size, file.file.data + token.start); @@ -249,7 +248,6 @@ int main(){ return 0; } -#endif // BOTTOM diff --git a/win32_4ed.cpp b/win32_4ed.cpp index 7ded78a1..68ae375c 100644 --- a/win32_4ed.cpp +++ b/win32_4ed.cpp @@ -9,47 +9,7 @@ // TOP -#ifdef FRED_NOT_PACKAGE - -#define FRED_INTERNAL 1 -#define FRED_SLOW 1 - -#define FRED_PRINT_DEBUG 1 -#define FRED_PRINT_DEBUG_FILE_LINE 0 -#define FRED_PROFILING 1 -#define FRED_PROFILING_OS 0 -#define FRED_FULL_ERRORS 0 - -#else - -#define FRED_SLOW 0 -#define FRED_INTERNAL 0 - -#define FRED_PRINT_DEBUG 0 -#define FRED_PRINT_DEBUG_FILE_LINE 0 -#define FRED_PROFILING 0 -#define FRED_PROFILING_OS 0 -#define FRED_FULL_ERRORS 0 - -#endif - -#define SOFTWARE_RENDER 0 - -#if FRED_INTERNAL == 0 -#undef FRED_PRINT_DEBUG -#define FRED_PRINT_DEBUG 0 -#undef FRED_PROFILING -#define FRED_PROFILING 0 -#undef FRED_PROFILING_OS -#define FRED_PROFILING_OS 0 -#endif - -#if FRED_PRINT_DEBUG == 0 -#undef FRED_PRINT_DEBUG_FILE_LINE -#define FRED_PRINT_DEBUG_FILE_LINE 0 -#undef FRED_PRINT_DEBUG_FILE_LINE -#define FRED_PROFILING_OS 0 -#endif +#include "4ed_config.h" #define FPS 30 #define frame_useconds (1000000 / FPS) @@ -63,18 +23,21 @@ #include "4cpp_string.h" #include "4ed_mem.cpp" - #include "4ed_math.cpp" + +#include "4ed_dll_reader.h" #include "4coder_custom.h" #include "4ed_system.h" -#include "4ed.h" #include "4ed_rendering.h" +#include "4ed.h" #include #include +#include "4ed_dll_reader.cpp" +#include "4ed_rendering.cpp" #include "4ed_internal.h" -#include "4ed_keyboard.cpp" +#include "4ed_win32_keyboard.cpp" struct Full_Job_Data{ Job_Data job; @@ -108,24 +71,14 @@ struct Thread_Group{ i32 count; }; +#define UseWinDll 0 + struct Win32_Vars{ HWND window_handle; Key_Codes key_codes; Key_Input_Data input_data, previous_data; -#if SOFTWARE_RENDER - BITMAPINFO bmp_info; - union{ - struct{ - void *pixel_data; - i32 width, height, pitch; - }; - Render_Target target; - }; - i32 true_pixel_size; -#else Render_Target target; -#endif u32 volatile force_redraw; @@ -153,7 +106,11 @@ struct Win32_Vars{ i64 start_pcount; HMODULE custom; +#if UseWinDll HMODULE app_code; +#else + DLL_Loaded app_dll; +#endif System_Functions *system; App_Functions app; @@ -167,11 +124,19 @@ struct Win32_Vars{ globalvar Win32_Vars win32vars; globalvar Application_Memory win32memory; +#if FRED_INTERNAL internal Bubble* INTERNAL_system_sentinel(){ return (&win32vars.internal_bubble); } +internal void +INTERNAL_system_debug_message(char *message){ + OutputDebugString(message); +} + +#endif + internal void* system_get_memory_(i32 size, i32 line_number, char *file_name){ void *ptr = 0; @@ -213,9 +178,9 @@ system_free_memory(void *block){ } } -internal File_Data +internal Data system_load_file(char *filename){ - File_Data result = {}; + Data result = {}; HANDLE file; file = CreateFile((char*)filename, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); @@ -232,7 +197,7 @@ system_load_file(char *filename){ } result.size = (lo) + (((u64)hi) << 32); - result.data = system_get_memory(result.size); + result.data = (byte*)system_get_memory(result.size); if (!result.data){ CloseHandle(file); @@ -243,7 +208,7 @@ system_load_file(char *filename){ DWORD read_size; BOOL read_result = ReadFile(file, result.data, result.size, &read_size, 0); - if (!read_result || read_size != result.size){ + if (!read_result || read_size != (u32)result.size){ CloseHandle(file); system_free_memory(result.data); result = {}; @@ -316,7 +281,7 @@ system_time(){ } internal void -system_free_file(File_Data data){ +system_free_file(Data data){ system_free_memory(data.data); } @@ -437,31 +402,13 @@ system_post_clipboard(String str){ } } -#if SOFTWARE_RENDER -internal void -Win32RedrawScreen(HDC hdc){ - win32vars.bmp_info.bmiHeader.biHeight = - -win32vars.bmp_info.bmiHeader.biHeight; - SetDIBitsToDevice(hdc, - 0, 0, - win32vars.width, win32vars.height, - 0, 0, - 0, win32vars.height, - win32vars.pixel_data, - &win32vars.bmp_info, - DIB_RGB_COLORS); - win32vars.bmp_info.bmiHeader.biHeight = - -win32vars.bmp_info.bmiHeader.biHeight; -} - -#else - internal void Win32RedrawScreen(HDC hdc){ + launch_rendering(&win32vars.target); + win32vars.target.size = 0; glFlush(); SwapBuffers(hdc); } -#endif internal void Win32Resize(i32 width, i32 height){ @@ -583,43 +530,19 @@ Win32Callback(HWND hwnd, UINT uMsg, case WM_SIZE: { -#if SOFTWARE_RENDER - i32 new_width = LOWORD(lParam); - i32 new_height = HIWORD(lParam); - i32 new_pitch = new_width * 4; - - if (new_height*new_pitch > win32vars.true_pixel_size){ - system_free_memory(win32vars.pixel_data); - - win32vars.pixel_data = system_get_memory(new_height*new_pitch); - win32vars.true_pixel_size = new_height*new_pitch; - - if (!win32vars.pixel_data){ - win32vars.keep_playing = 0; - } - } - - win32vars.width = new_width; - win32vars.height = new_height; - win32vars.pitch = new_pitch; - - win32vars.bmp_info.bmiHeader.biWidth = win32vars.width; - win32vars.bmp_info.bmiHeader.biHeight = win32vars.height; -#else if (win32vars.target.handle){ i32 new_width = LOWORD(lParam); i32 new_height = HIWORD(lParam); Win32Resize(new_width, new_height); } -#endif }break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); - + Clipboard_Contents empty_contents = {}; win32vars.app.step(win32vars.system, &win32vars.key_codes, @@ -755,6 +678,8 @@ system_post_job(Thread_Group_ID group_id, Job_Data job){ queue->jobs[write_index].running_thread = THREAD_NOT_ASSIGNED; queue->jobs[write_index].id = result; success = 1; + + // TODO } } @@ -969,10 +894,16 @@ system_cli_end_update(CLI_Handles *cli){ return close_me; } +void +DUMP(byte *d, i32 size){ + //system_save_file("DUMP", d, size); +} + internal b32 Win32LoadAppCode(){ b32 result = 0; - + +#if UseWinDll win32vars.app_code = LoadLibraryA("4ed_app.dll"); if (win32vars.app_code){ result = 1; @@ -982,6 +913,50 @@ Win32LoadAppCode(){ GetProcAddress(win32vars.app_code, "app_step"); } + DUMP((byte*)(win32vars.app.step) - 0x39000, Kbytes(400)); +#else + Data file = system_load_file("4ed_app.dll"); + + if (file.data){ + i32 error; + DLL_Data dll_data; + if (dll_parse_headers(file, &dll_data, &error)){ + Data img; + img.size = dll_total_loaded_size(&dll_data); + img.data = (byte*) + VirtualAlloc((LPVOID)Tbytes(3), img.size, + MEM_COMMIT | MEM_RESERVE, + PAGE_READWRITE); + + dll_load(img, &win32vars.app_dll, file, &dll_data); + + DWORD extra_; + VirtualProtect(img.data + win32vars.app_dll.text_start, + win32vars.app_dll.text_size, + PAGE_EXECUTE_READ, + &extra_); + + result = 1; + win32vars.app.init = (App_Init*) + dll_load_function(&win32vars.app_dll, "app_init", 8); + + win32vars.app.step = (App_Step*) + dll_load_function(&win32vars.app_dll, "app_step", 8); + } + else{ + // TODO(allen): file loading error + } + + system_free_file(file); + + DUMP((byte*)(Tbytes(3)), Kbytes(400)); + } + else{ + // TODO(allen): file loading error + } + +#endif + return result; } @@ -1023,6 +998,7 @@ Win32LoadSystemCode(){ win32vars.system->internal_sentinel = INTERNAL_system_sentinel; win32vars.system->internal_get_thread_states = INTERNAL_get_thread_states; + win32vars.system->internal_debug_message = INTERNAL_system_debug_message; } int @@ -1032,6 +1008,12 @@ WinMain(HINSTANCE hInstance, int nCmdShow){ win32vars = {}; +#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; +#endif + if (!Win32LoadAppCode()){ // TODO(allen): Failed to load app code, serious problem. return 99; @@ -1048,12 +1030,6 @@ WinMain(HINSTANCE hInstance, QueryPerformanceCounter(&lpf); win32vars.start_pcount = lpf.QuadPart; -#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; -#endif - keycode_init(&win32vars.key_codes); #ifdef FRED_SUPER @@ -1120,12 +1096,8 @@ WinMain(HINSTANCE hInstance, if (!AdjustWindowRect(&window_rect, WS_OVERLAPPEDWINDOW, false)){ // TODO(allen): non-fatal diagnostics } - -#if SOFTWARE_RENDER -#define WINDOW_NAME "4coder-softrender-window" -#else + #define WINDOW_NAME "4coder-window" -#endif HWND window_handle = {}; window_handle = CreateWindowA( @@ -1146,30 +1118,7 @@ WinMain(HINSTANCE hInstance, HDC hdc = GetDC(window_handle); GetClientRect(window_handle, &window_rect); - -#if SOFTWARE_RENDER - win32vars.width = window_rect.right - window_rect.left; - win32vars.height = window_rect.bottom - window_rect.top; - - win32vars.pitch = win32vars.width*4; -#define bmi_header win32vars.bmp_info.bmiHeader - bmi_header = {}; - bmi_header.biSize = sizeof(BITMAPINFOHEADER); - bmi_header.biWidth = win32vars.width; - bmi_header.biHeight = win32vars.height; - bmi_header.biPlanes = 1; - bmi_header.biBitCount = 32; - bmi_header.biCompression = BI_RGB; -#undef bmi_header - - win32vars.true_pixel_size = win32vars.height*win32vars.pitch; - win32vars.pixel_data = system_get_memory(win32vars.true_pixel_size); - - if (!win32vars.pixel_data){ - return 3; - } - -#else + static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, @@ -1204,7 +1153,6 @@ WinMain(HINSTANCE hInstance, glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); Win32Resize(window_rect.right - window_rect.left, window_rect.bottom - window_rect.top); -#endif LPVOID base; #if FRED_INTERNAL @@ -1261,8 +1209,16 @@ WinMain(HINSTANCE hInstance, } } } + + win32vars.target.push_clip = draw_push_clip; + win32vars.target.pop_clip = draw_pop_clip; + win32vars.target.push_piece = draw_push_piece; + win32vars.target.font_load = draw_font_load; + + win32vars.target.max = Mbytes(1); + win32vars.target.push_buffer = (byte*)system_get_memory(win32vars.target.max); - if (!win32vars.app.init(win32vars.system, + if (!win32vars.app.init(win32vars.system, &win32vars.target, &win32memory, &win32vars.key_codes, win32vars.clipboard_contents, win32vars.config_api)){ return 5; @@ -1329,24 +1285,20 @@ WinMain(HINSTANCE hInstance, b32 caps_lock = win32vars.input_data.caps_lock; for (i32 i = 0; i < win32vars.input_data.press_count; ++i){ i16 keycode = win32vars.input_data.press[i].keycode; - win32vars.input_data.press[i].character = - keycode_to_character_ascii(&win32vars.key_codes, keycode, - shift, caps_lock); + win32vars.input_data.press[i].character = + translate_key(keycode, shift, caps_lock); win32vars.input_data.press[i].character_no_caps_lock = - keycode_to_character_ascii(&win32vars.key_codes, keycode, - shift, 0); + translate_key(keycode, shift, 0); } for (i32 i = 0; i < win32vars.input_data.hold_count; ++i){ i16 keycode = win32vars.input_data.hold[i].keycode; + win32vars.input_data.hold[i].character = - keycode_to_character_ascii(&win32vars.key_codes, keycode, - shift, caps_lock); - + translate_key(keycode, shift, caps_lock); win32vars.input_data.hold[i].character_no_caps_lock = - keycode_to_character_ascii(&win32vars.key_codes, keycode, - shift, 0); + translate_key(keycode, shift, 0); } win32vars.clipboard_contents = {}; @@ -1392,13 +1344,10 @@ WinMain(HINSTANCE hInstance, switch (result.mouse_cursor_type){ case APP_MOUSE_CURSOR_ARROW: SetCursor(win32vars.cursor_arrow); break; - case APP_MOUSE_CURSOR_IBEAM: SetCursor(win32vars.cursor_ibeam); break; - case APP_MOUSE_CURSOR_LEFTRIGHT: SetCursor(win32vars.cursor_leftright); break; - case APP_MOUSE_CURSOR_UPDOWN: SetCursor(win32vars.cursor_updown); break; }