starting new parser

This commit is contained in:
Allen Webster 2015-11-30 21:51:53 -05:00
parent 5b41098824
commit c2206e5830
31 changed files with 2799 additions and 1266 deletions

View File

@ -2,41 +2,6 @@
* Example use of customization API * 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_custom.h"
#include "4coder_helper.h" #include "4coder_helper.h"

View File

@ -3,6 +3,10 @@
#define MDFR_CTRL 1 #define MDFR_CTRL 1
#define MDFR_ALT 2 #define MDFR_ALT 2
#define MDFR_SHIFT 4 #define MDFR_SHIFT 4
#define MDFR_NUMPAD 8
// NOTE(allen): These need not be used direct
#define MDFR_EXACT 128
typedef u16 Code; typedef u16 Code;
@ -215,7 +219,6 @@ struct Buffer_Summary{
int file_id; int file_id;
int size; int size;
const char *data;
int file_name_len; int file_name_len;
int buffer_name_len; int buffer_name_len;

View File

@ -92,34 +92,69 @@ end_map(Bind_Helper *helper){
helper->group = 0; 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 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->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN;
if (!helper->error) ++helper->group->map_begin.bind_count; if (!helper->error) ++helper->group->map_begin.bind_count;
Binding_Unit unit; Binding_Unit unit;
unit.type = unit_binding; unit.type = unit_binding;
unit.binding.command_id = cmdid; unit.binding.command_id = cmdid;
unit.binding.code = code; unit.binding.code = target.code;
unit.binding.modifiers = modifiers; unit.binding.modifiers = target.modifiers;
write_unit(helper, unit); write_unit(helper, unit);
} }
inline void 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->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN;
if (!helper->error) ++helper->group->map_begin.bind_count; if (!helper->error) ++helper->group->map_begin.bind_count;
Binding_Unit unit; Binding_Unit unit;
unit.type = unit_callback; unit.type = unit_callback;
unit.callback.func = func; unit.callback.func = func;
unit.callback.code = code; unit.callback.code = target.code;
unit.callback.modifiers = modifiers; unit.callback.modifiers = target.modifiers;
write_unit(helper, unit); 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 inline void
bind_vanilla_keys(Bind_Helper *helper, int cmdid){ bind_vanilla_keys(Bind_Helper *helper, int cmdid){
bind(helper, 0, 0, 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); 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 inline void
inherit_map(Bind_Helper *helper, int mapid){ inherit_map(Bind_Helper *helper, int mapid){
if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN; if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN;

View File

@ -107,8 +107,7 @@ table_copy(Table *table_src, Table *table_dst){
} }
} }
// TODO(allen): File_Data not Parse_File struct Cpp_File_Data{
struct Cpp_Parse_File{
Cpp_File file; Cpp_File file;
Cpp_Token_Stack tokens; Cpp_Token_Stack tokens;
String filename; String filename;
@ -124,7 +123,7 @@ struct Cpp_Macro_Data{
}; };
union Cpp_Def_Slot{ union Cpp_Def_Slot{
Cpp_Parse_File file; Cpp_File_Data file;
Cpp_Macro_Data macro; Cpp_Macro_Data macro;
}; };
@ -289,13 +288,13 @@ cpp_get_memory_request(Cpp_Preproc_State *state, Cpp_Parse_Definitions *definiti
return request; return request;
} }
internal Cpp_Parse_File* internal Cpp_File_Data*
cpp_get_parse_file(Cpp_Parse_Definitions *definitions, int file_index){ cpp_get_parse_file(Cpp_Parse_Definitions *definitions, int file_index){
return &definitions->slots[file_index].file; return &definitions->slots[file_index].file;
} }
internal void 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; 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; Cpp_Parse_Definitions *definitions = request.definitions;
int size = request.size >> 1; 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.tokens = (Cpp_Token*)memory;
new_file.tokens.max_count = size / sizeof(Cpp_Token); new_file.tokens.max_count = size / sizeof(Cpp_Token);
new_file.file.data = ((char*)memory) + size; new_file.file.data = ((char*)memory) + size;
@ -514,7 +513,7 @@ struct Preserve_Checkpoint{
internal Preserve_Checkpoint internal Preserve_Checkpoint
cpp__checkpoint_preserve_write(Cpp_Parse_Definitions *definitions){ 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; Preserve_Checkpoint check;
check.start_write_pos = definitions->string_write_pos; check.start_write_pos = definitions->string_write_pos;
check.start_token_count = file->tokens.count; check.start_token_count = file->tokens.count;
@ -524,14 +523,14 @@ cpp__checkpoint_preserve_write(Cpp_Parse_Definitions *definitions){
internal void internal void
cpp__restore_preserve_write(Cpp_Parse_Definitions *definitions, Preserve_Checkpoint check){ 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; definitions->string_write_pos = check.start_write_pos;
file->tokens.count = check.start_token_count; file->tokens.count = check.start_token_count;
} }
internal void internal void
cpp__preserve_string(Cpp_Parse_Definitions *definitions, String string){ 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); _Assert(string_file->file.size - definitions->string_write_pos >= string.size);
copy_fast_unsafe(string_file->file.data + definitions->string_write_pos, string); copy_fast_unsafe(string_file->file.data + definitions->string_write_pos, string);
definitions->string_write_pos += string.size; definitions->string_write_pos += string.size;
@ -539,7 +538,7 @@ cpp__preserve_string(Cpp_Parse_Definitions *definitions, String string){
internal Cpp_Loose_Token internal Cpp_Loose_Token
cpp__preserve_token(Cpp_Parse_Definitions *definitions, Cpp_Token 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); _Assert(string_file->tokens.count < string_file->tokens.max_count);
Cpp_Loose_Token loose; Cpp_Loose_Token loose;
loose.file_index = definitions->string_file_index; loose.file_index = definitions->string_file_index;
@ -552,7 +551,7 @@ cpp__preserve_token(Cpp_Parse_Definitions *definitions, Cpp_Token token){
internal void internal void
cpp__preserve_string(Preserve_Checkpoint *check, Cpp_Parse_Definitions *definitions, String string){ cpp__preserve_string(Preserve_Checkpoint *check, Cpp_Parse_Definitions *definitions, String string){
if (!check->out_of_memory){ 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){ if (string_file->file.size - definitions->string_write_pos >= string.size){
copy_fast_unsafe(string_file->file.data + definitions->string_write_pos, string); copy_fast_unsafe(string_file->file.data + definitions->string_write_pos, string);
definitions->string_write_pos += string.size; 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__preserve_token(Preserve_Checkpoint *check, Cpp_Parse_Definitions *definitions, Cpp_Token token){
Cpp_Loose_Token loose = {}; Cpp_Loose_Token loose = {};
if (!check->out_of_memory){ 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){ if (string_file->tokens.count < string_file->tokens.max_count){
loose.file_index = definitions->string_file_index; loose.file_index = definitions->string_file_index;
loose.token_index = string_file->tokens.count; 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_Visit visit = {};
Cpp_Parse_File visit_file; Cpp_File_Data visit_file;
Cpp_Token visit_token; Cpp_Token visit_token;
if (expansion->out_type == EXPAN_NORMAL){ 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; bool variadic = 0;
if (macro->param_count != 0){ if (macro->param_count != 0){
int macro_file_index = macro->file_index; 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; int i = macro->first_param_index;
Cpp_Token token = file.tokens.tokens[i]; Cpp_Token token = file.tokens.tokens[i];
for (;;){ for (;;){
@ -1461,13 +1460,13 @@ cpp__preproc_normal_step_nonalloc(Cpp_Preproc_State *state, Cpp_Parse_Definition
internal int internal int
cpp__get_parameter_i(Cpp_Preproc_State *state, Cpp_Parse_Definitions * definitions, 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; int param_i = -1;
if (token.type == CPP_TOKEN_IDENTIFIER){ if (token.type == CPP_TOKEN_IDENTIFIER){
String token_str = make_string(macro_file->file.data + token.start, token.size); String token_str = make_string(macro_file->file.data + token.start, token.size);
for (int j = 0; j < param_count; ++j){ for (int j = 0; j < param_count; ++j){
Cpp_Loose_Token param_loose = state->tokens.tokens[j + param_start]; 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]; 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); String param_str = make_string(file->file.data + param_token.start, param_token.size);
if (match(token_str, param_str)){ 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_Expansion *expansion = state->expansions + state->expansion_level;
Cpp_Macro_Data macro = *cpp_get_macro_data(definitions, expansion->file_index); 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){ switch (expansion->out_type){
case EXPAN_BIG_PROCESS_ARGS: 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__push_loose_token(&checkpoint, state, loose.file_index, loose.token_index, loose.blocked);
} }
Cpp_Loose_Token loose = state->tokens.tokens[j]; 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]; 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); String end_string = make_string(end_file->file.data + end_token.start, end_token.size);
cpp__spare_write(&str_checkpoint, state, end_string); 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){ if (range.start < range.end){
int j = range.start; int j = range.start;
Cpp_Loose_Token loose = state->tokens.tokens[j]; 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]; 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); String start_string = make_string(start_file->file.data + start_token.start, start_token.size);
cpp__spare_write(&str_checkpoint, state, start_string); 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); Spare_String_Checkpoint checkpoint = cpp__checkpoint_spare_string(state);
if (do_body){ if (do_body){
Cpp_Parse_File visit_file; Cpp_File_Data visit_file;
Cpp_Token visit_token; Cpp_Token visit_token;
visit_file = *cpp_get_parse_file(definitions, visit.file_index); visit_file = *cpp_get_parse_file(definitions, visit.file_index);

37
4ed.cpp
View File

@ -112,12 +112,9 @@ app_get_map_index(App_Vars *vars, i32 mapid){
internal Command_Map* internal Command_Map*
app_get_map(App_Vars *vars, i32 mapid){ app_get_map(App_Vars *vars, i32 mapid){
Command_Map *map = 0; Command_Map *map = 0;
if (mapid >= mapid_user_custom) if (mapid >= mapid_user_custom) map = vars->user_maps + 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_global) else if (mapid == mapid_file) map = &vars->map_file;
map = &vars->map_top;
else if (mapid == mapid_file)
map = &vars->map_file;
return map; return map;
} }
@ -740,7 +737,7 @@ app_open_file(System_Functions *system,
new_view->map = app_get_map(vars, target_file->base_map_id); new_view->map = app_get_map(vars, target_file->base_map_id);
#if BUFFER_EXPERIMENT_SCALPEL <= 0 #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); file_first_lex_parallel(system, &mem->general, target_file);
#endif #endif
} }
@ -1690,7 +1687,6 @@ extern "C"{
Working_Set *working_set = cmd->working_set; Working_Set *working_set = cmd->working_set;
buffer.file_id = (int)(file - working_set->files); buffer.file_id = (int)(file - working_set->files);
buffer.size = file->buffer.size; buffer.size = file->buffer.size;
buffer.data = (const char*)file->buffer.data;
buffer.file_name_len = file->source_path.size; buffer.file_name_len = file->source_path.size;
buffer.buffer_name_len = file->live_name.size; buffer.buffer_name_len = file->live_name.size;
buffer.file_name = file->source_path.str; buffer.file_name = file->source_path.str;
@ -1990,7 +1986,7 @@ app_hardcode_styles(App_Vars *vars){
styles = vars->styles.styles; styles = vars->styles.styles;
style = styles; style = styles;
Font *fonts = vars->fonts.fonts; Render_Font *fonts = vars->fonts.fonts;
///////////////// /////////////////
style_set_name(style, make_lit_string("4coder")); style_set_name(style, make_lit_string("4coder"));
@ -2206,10 +2202,11 @@ app_hardcode_styles(App_Vars *vars){
} }
internal bool32 internal bool32
app_load_font(System_Functions *system, app_load_font(Render_Target *target, System_Functions *system,
Font *font, char *filename, i32 size, void *memory, Render_Font *font, char *filename, i32 size, void *memory,
i32 *used, i32 tab_width, String name){ 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->loaded = 1;
font->name_[ArrayCount(font->name_)-1] = 0; font->name_[ArrayCount(font->name_)-1] = 0;
font->name = make_string(font->name_, 0, ArrayCount(font->name_)-1); 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; vars->hooks[hook_open_file] = default_open_file_hook;
} }
if (!font_init()) return 0;
vars->fonts.max = 6; 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 font_count = 0;
i32 memory_used; i32 memory_used;
memory_used = 0; memory_used = 0;
app_load_font(system, app_load_font(target, system,
vars->fonts.fonts + font_count++, "liberation-mono.ttf", 17, vars->fonts.fonts + font_count++, "liberation-mono.ttf", 17,
partition_current(partition), partition_current(partition),
&memory_used, 4, make_lit_string("liberation mono")); &memory_used, 4, make_lit_string("liberation mono"));
push_block(partition, memory_used); push_block(partition, memory_used);
memory_used = 0; memory_used = 0;
app_load_font(system, app_load_font(target, system,
vars->fonts.fonts + font_count++, "LiberationSans-Regular.ttf", 17, vars->fonts.fonts + font_count++, "LiberationSans-Regular.ttf", 17,
partition_current(partition), partition_current(partition),
&memory_used, 4, make_lit_string("liberation sans")); &memory_used, 4, make_lit_string("liberation sans"));
push_block(partition, memory_used); push_block(partition, memory_used);
memory_used = 0; memory_used = 0;
app_load_font(system, app_load_font(target, system,
vars->fonts.fonts + font_count++, "Hack-Regular.ttf", 17, vars->fonts.fonts + font_count++, "Hack-Regular.ttf", 17,
partition_current(partition), partition_current(partition),
&memory_used, 4, make_lit_string("hack")); &memory_used, 4, make_lit_string("hack"));
push_block(partition, memory_used); push_block(partition, memory_used);
memory_used = 0; memory_used = 0;
app_load_font(system, app_load_font(target, system,
vars->fonts.fonts + font_count++, "CutiveMono-Regular.ttf", 17, vars->fonts.fonts + font_count++, "CutiveMono-Regular.ttf", 17,
partition_current(partition), partition_current(partition),
&memory_used, 4, make_lit_string("cutive mono")); &memory_used, 4, make_lit_string("cutive mono"));
push_block(partition, memory_used); push_block(partition, memory_used);
memory_used = 0; memory_used = 0;
app_load_font(system, app_load_font(target, system,
vars->fonts.fonts + font_count++, "Inconsolata-Regular.ttf", 17, vars->fonts.fonts + font_count++, "Inconsolata-Regular.ttf", 17,
partition_current(partition), partition_current(partition),
&memory_used, 4, make_lit_string("inconsolata")); &memory_used, 4, make_lit_string("inconsolata"));
@ -2502,7 +2497,7 @@ external App_Init_Sig(app_init){
extra.size = 17; extra.size = 17;
vars->config_api.set_extra_font(&extra); vars->config_api.set_extra_font(&extra);
memory_used = 0; memory_used = 0;
if (app_load_font(system, if (app_load_font(target, system,
vars->fonts.fonts + font_count, extra.file_name, extra.size, vars->fonts.fonts + font_count, extra.file_name, extra.size,
partition_current(partition), partition_current(partition),
&memory_used, 4, make_string_slowly(extra.font_name))){ &memory_used, 4, make_string_slowly(extra.font_name))){

20
4ed.h
View File

@ -12,23 +12,6 @@
#ifndef FRED_H #ifndef FRED_H
#define 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{ struct Application_Memory{
void *vars_memory; void *vars_memory;
i32 vars_memory_size; i32 vars_memory_size;
@ -118,6 +101,7 @@ struct Thread_Context;
#define App_Init_Sig(name) \ #define App_Init_Sig(name) \
b32 name(System_Functions *system, \ b32 name(System_Functions *system, \
Render_Target *target, \
Application_Memory *memory, \ Application_Memory *memory, \
Key_Codes *loose_codes, \ Key_Codes *loose_codes, \
Clipboard_Contents clipboard, \ Clipboard_Contents clipboard, \
@ -137,7 +121,7 @@ enum Application_Mouse_Cursor{
struct Application_Step_Result{ struct Application_Step_Result{
Application_Mouse_Cursor mouse_cursor_type; Application_Mouse_Cursor mouse_cursor_type;
b32 redraw; b32 redraw;
}; };
#define App_Step_Sig(name) Application_Step_Result \ #define App_Step_Sig(name) Application_Step_Result \

View File

@ -1,7 +1,7 @@
/* /*
* Mr. 4th Dimention - Allen Webster * Mr. 4th Dimention - Allen Webster
* *
* 13.11.2014 * 13.11.2015
* *
* Application layer build target * Application layer build target
* *
@ -9,50 +9,7 @@
// TOP // TOP
#ifdef FRED_NOT_PACKAGE #include "4ed_config.h"
#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)
#define BUFFER_EXPERIMENT_SCALPEL 0 #define BUFFER_EXPERIMENT_SCALPEL 0
@ -67,25 +24,15 @@
#include "4ed_math.cpp" #include "4ed_math.cpp"
#include "4coder_custom.h" #include "4coder_custom.h"
#include "4ed_system.h" #include "4ed_system.h"
#include "4ed.h"
#include "4ed_rendering.h" #include "4ed_rendering.h"
#include "4ed.h"
#if defined(_WIN32)
# include <windows.h>
# include <GL/gl.h>
#elif defined(__linux__)
# include <SDL/SDL.h>
# include <GL/gl.h>
#else
# error UNSUPPORTED PLATFORM
#endif
#include "4ed_internal.h" #include "4ed_internal.h"
#define FCPP_LEXER_IMPLEMENTATION #define FCPP_LEXER_IMPLEMENTATION
#include "4cpp_lexer.h" #include "4cpp_lexer.h"
#include "4ed_rendering.cpp" #include "4ed_rendering_helper.cpp"
#include "4ed_command.cpp" #include "4ed_command.cpp"
#include "4ed_layout.cpp" #include "4ed_layout.cpp"
#include "4ed_style.cpp" #include "4ed_style.cpp"

View File

@ -125,14 +125,14 @@ view_to_color_view(View *view){
internal void internal void
draw_gradient_slider(Render_Target *target, Vec4 base, i32 channel, 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; Vec4 low, high;
real32 *lowv, *highv; f32 *lowv, *highv;
real32 x; f32 x;
real32 next_x; f32 next_x;
real32 x_step; f32 x_step;
real32 v_step; f32 v_step;
real32 m; f32 m;
x = (real32)slider.x0; x = (real32)slider.x0;
x_step = (real32)(slider.x1 - slider.x0) / steps; x_step = (real32)(slider.x1 - slider.x0) / steps;
@ -176,21 +176,21 @@ draw_gradient_slider(Render_Target *target, Vec4 base, i32 channel,
} }
inline void inline void
draw_hsl_slider(Render_Target *target, Vec4 base, i32 channel, i32 steps, real32 top, draw_hsl_slider(Render_Target *target, Vec4 base, i32 channel,
real32_Rect slider){ i32 steps, real32 top, f32_Rect slider){
draw_gradient_slider(target, base, channel, steps, top, slider, 1); draw_gradient_slider(target, base, channel, steps, top, slider, 1);
} }
inline void inline void
draw_rgb_slider(Render_Target *target, Vec4 base, i32 channel, i32 steps, real32 top, draw_rgb_slider(Render_Target *target, Vec4 base, i32 channel,
real32_Rect slider){ i32 steps, f32 top, f32_Rect slider){
draw_gradient_slider(target, base, channel, steps, top, slider, 0); draw_gradient_slider(target, base, channel, steps, top, slider, 0);
} }
internal void internal void
do_label(UI_State *state, UI_Layout *layout, char *text, real32 height = 2.f){ do_label(UI_State *state, UI_Layout *layout, char *text, real32 height = 2.f){
Style *style = state->style; Style *style = state->style;
Font *font = style->font; Render_Font *font = style->font;
i32_Rect label = layout_rect(layout, FLOOR32(font->height * height)); i32_Rect label = layout_rect(layout, FLOOR32(font->height * height));
if (!state->input_stage){ 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); get_colors(state, &back, &fore, wid, ui_style);
draw_rectangle(target, top_arrow, back); draw_rectangle(target, top_arrow, back);
draw_rectangle_outline(target, top_arrow, outline); draw_rectangle_outline(target, top_arrow, outline);
draw_triangle_3corner(target, x0, y0, x1, y1, x2, y2, fore);
++wid.sub_id2; ++wid.sub_id2;
y0 = (w_2_3 + bottom_arrow.y0); 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); get_colors(state, &back, &fore, wid, ui_style);
draw_rectangle(target, bottom_arrow, back); draw_rectangle(target, bottom_arrow, back);
draw_rectangle_outline(target, bottom_arrow, outline); draw_rectangle_outline(target, bottom_arrow, outline);
draw_triangle_3corner(target, x0, y0, x1, y1, x2, y2, fore);
++wid.sub_id2; ++wid.sub_id2;
get_colors(state, &back, &fore, wid, ui_style); get_colors(state, &back, &fore, wid, ui_style);
@ -295,10 +293,10 @@ do_scroll_bar(UI_State *state, i32_Rect rect){
} }
internal void internal void
do_single_slider(i32 sub_id, Color_UI *ui, i32 channel, bool32 is_rgba, do_single_slider(i32 sub_id, Color_UI *ui, i32 channel, b32 is_rgba,
i32 grad_steps, real32 top, real32_Rect slider, real32 v_handle, i32 grad_steps, f32 top, f32_Rect slider, f32 v_handle,
i32_Rect rect){ i32_Rect rect){
real32_Rect click_box = slider; f32_Rect click_box = slider;
click_box.y0 -= v_handle; click_box.y0 -= v_handle;
if (ui->state.input_stage){ if (ui->state.input_stage){
@ -349,7 +347,7 @@ internal void
do_hsl_sliders(Color_UI *ui, i32_Rect rect){ do_hsl_sliders(Color_UI *ui, i32_Rect rect){
real32 bar_width = (real32)(rect.x1 - rect.x0 - 20); real32 bar_width = (real32)(rect.x1 - rect.x0 - 20);
if (bar_width > 45){ if (bar_width > 45){
real32_Rect slider; f32_Rect slider;
real32 y; real32 y;
i32 sub_id; 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){ i32 y, u32 color, u32 back, i32 x0, i32 x1){
bool32 result = 0; bool32 result = 0;
Render_Target *target = ui->state.target; Render_Target *target = ui->state.target;
Font *font = ui->state.font; Render_Font *font = ui->state.font;
i32_Rect hit_region; i32_Rect hit_region;
hit_region.x0 = x0; hit_region.x0 = x0;
@ -509,7 +507,7 @@ do_channel_field(i32 sub_id, Color_UI *ui, u8 *channel, Channel_Field_Type ftype
} }
} }
else{ else{
real32_Rect r = f32R(hit_region); f32_Rect r = f32R(hit_region);
r.x0 += indx*ui->hex_advance+1; r.x0 += indx*ui->hex_advance+1;
r.x1 = r.x0+ui->hex_advance+1; r.x1 = r.x0+ui->hex_advance+1;
draw_rectangle(target, r, back); draw_rectangle(target, r, back);
@ -537,8 +535,8 @@ do_rgb_sliders(Color_UI *ui, i32_Rect rect){
rect.x0 = hex_x1; rect.x0 = hex_x1;
real32 bar_width = (real32)(rect.x1 - rect.x0 - 20); real32 bar_width = (real32)(rect.x1 - rect.x0 - 20);
real32_Rect slider; f32_Rect slider;
real32 y; f32 y;
i32 sub_id; i32 sub_id;
u8 channel; u8 channel;
@ -603,7 +601,7 @@ begin_layout(Blob_Layout *layout, i32_Rect rect){
internal void internal void
do_blob(Color_UI *ui, Blob_Layout *layout, u32 color, bool32 *set_me, i32 sub_id){ do_blob(Color_UI *ui, Blob_Layout *layout, u32 color, bool32 *set_me, i32 sub_id){
i32_Rect rect = layout->rect; i32_Rect rect = layout->rect;
real32_Rect blob; f32_Rect blob;
blob.x0 = (real32)layout->x; blob.x0 = (real32)layout->x;
blob.y0 = (real32)layout->y; blob.y0 = (real32)layout->y;
blob.x1 = blob.x0 + layout->size; blob.x1 = blob.x0 + layout->size;
@ -690,7 +688,7 @@ do_palette(Color_UI *ui, i32_Rect rect){
if (!ui->state.input_stage){ if (!ui->state.input_stage){
Render_Target *target = ui->state.target; 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", draw_string(target, font, "Global Palette: right click to save color",
layout.x, layout.rect.y0, style->main.default_color); layout.x, layout.rect.y0, style->main.default_color);
} }
@ -711,7 +709,7 @@ do_palette(Color_UI *ui, i32_Rect rect){
internal void internal void
do_sub_button(i32 id, Color_UI *ui, char *text){ 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); 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){ u32 text_color, u32 back_color, char *name){
i32 id = raw_ptr_dif(color, ui->state.style); i32 id = raw_ptr_dif(color, ui->state.style);
Render_Target *target = ui->state.target; Render_Target *target = ui->state.target;
Font *font = ui->state.font; Render_Font *font = ui->state.font;
i32 character_h = font->height; i32 character_h = font->height;
u32 text = 0, back = 0; u32 text = 0, back = 0;
@ -832,7 +830,7 @@ do_color_adjuster(Color_UI *ui, u32 *color,
internal void internal void
do_style_name(Color_UI *ui){ do_style_name(Color_UI *ui){
i32 id = -3; i32 id = -3;
Font *font = ui->state.font; Render_Font *font = ui->state.font;
i32_Rect srect = layout_rect(&ui->layout, font->height); i32_Rect srect = layout_rect(&ui->layout, font->height);
@ -878,7 +876,7 @@ do_style_name(Color_UI *ui){
} }
internal bool32 internal bool32
do_font_option(Color_UI *ui, Font *font){ do_font_option(Color_UI *ui, Render_Font *font){
bool32 result = 0; bool32 result = 0;
i32 sub_id = (i32)(font); i32 sub_id = (i32)(font);
i32_Rect orect = layout_rect(&ui->layout, font->height); i32_Rect orect = layout_rect(&ui->layout, font->height);
@ -915,7 +913,7 @@ internal void
do_font_switch(Color_UI *ui){ do_font_switch(Color_UI *ui){
i32 id = -2; i32 id = -2;
Render_Target *target = ui->state.target; Render_Target *target = ui->state.target;
Font *font = ui->state.font; Render_Font *font = ui->state.font;
i32 character_h = font->height; i32 character_h = font->height;
i32_Rect srect = layout_rect(&ui->layout, character_h); 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)){ if (is_selected(&ui->state, wid)){
Font_Set *fonts = ui->fonts; Font_Set *fonts = ui->fonts;
Font *font_opt = fonts->fonts; Render_Font *font_opt = fonts->fonts;
i32 count = fonts->count; i32 count = fonts->count;
srect = layout_rect(&ui->layout, character_h/2); srect = layout_rect(&ui->layout, character_h/2);
if (!ui->state.input_stage) if (!ui->state.input_stage)
@ -1188,7 +1186,7 @@ update_highlighting(Color_View *color_view){
internal bool32 internal bool32
do_style_preview(Library_UI *ui, Style *style, i32 toggle = -1){ do_style_preview(Library_UI *ui, Style *style, i32 toggle = -1){
bool32 result = 0; bool32 result = 0;
Font *font = style->font; Render_Font *font = style->font;
i32 id; i32 id;
if (style == ui->state.style) id = 2; if (style == ui->state.style) id = 2;
else id = raw_ptr_dif(style, ui->styles->styles) + 100; 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){ do_main_file_box(System_Functions *system, UI_State *state, UI_Layout *layout, Hot_Directory *hot_directory, char *end = 0){
bool32 result = 0; bool32 result = 0;
Style *style = state->style; Style *style = state->style;
Font *font = style->font; Render_Font *font = style->font;
i32_Rect box = layout_rect(layout, font->height + 2); i32_Rect box = layout_rect(layout, font->height + 2);
String *string = &hot_directory->string; 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){ do_main_string_box(System_Functions *system, UI_State *state, UI_Layout *layout, String *string){
bool32 result = 0; bool32 result = 0;
Style *style = state->style; Style *style = state->style;
Font *font = style->font; Render_Font *font = style->font;
i32_Rect box = layout_rect(layout, font->height + 2); i32_Rect box = layout_rect(layout, font->height + 2);
if (state->input_stage){ if (state->input_stage){
@ -1328,7 +1326,7 @@ internal bool32
do_list_option(i32 id, UI_State *state, UI_Layout *layout, String text){ do_list_option(i32 id, UI_State *state, UI_Layout *layout, String text){
bool32 result = 0; bool32 result = 0;
Style *style = state->style; Style *style = state->style;
Font *font = style->font; Render_Font *font = style->font;
i32 character_h = font->height; i32 character_h = font->height;
i32_Rect box = layout_rect(layout, font->height*2); 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){ do_file_option(i32 id, UI_State *state, UI_Layout *layout, String filename, bool32 is_folder, String extra){
bool32 result = 0; bool32 result = 0;
Style *style = state->style; Style *style = state->style;
Font *font = style->font; Render_Font *font = style->font;
i32 character_h = font->height; i32 character_h = font->height;
i32_Rect box = layout_rect(layout, font->height*2); i32_Rect box = layout_rect(layout, font->height*2);

View File

@ -9,8 +9,12 @@
// TOP // TOP
typedef void (*Command_Function)(System_Functions *system, #define Command_Function_Sig(name) void (name)( \
struct Command_Data *command, struct Command_Binding binding); System_Functions *system, \
struct Command_Data *command, \
struct Command_Binding binding)
typedef Command_Function_Sig(*Command_Function);
struct Command_Binding{ struct Command_Binding{
Command_Function function; Command_Function function;
@ -29,12 +33,13 @@ internal void command_null(Command_Data *command);
internal i64 internal i64
map_hash(u16 event_code, u8 modifiers){ map_hash(u16 event_code, u8 modifiers){
i64 result = (event_code << 4) | modifiers; i64 result = (event_code << 8) | modifiers;
return result; return result;
} }
internal b32 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); Assert(map->count * 8 < map->max * 7);
Command_Binding bind; Command_Binding bind;
bind.function = function; bind.function = function;
@ -115,21 +120,33 @@ internal Command_Binding
map_extract(Command_Map *map, Key_Single key){ map_extract(Command_Map *map, Key_Single key){
Command_Binding bind = {}; Command_Binding bind = {};
u8 command = MDFR_NONE;
b32 ctrl = key.modifiers[CONTROL_KEY_CONTROL]; b32 ctrl = key.modifiers[CONTROL_KEY_CONTROL];
b32 alt = key.modifiers[CONTROL_KEY_ALT]; b32 alt = key.modifiers[CONTROL_KEY_ALT];
b32 shift = key.modifiers[CONTROL_KEY_SHIFT] && key.key.loose_keycode; b32 shift = key.modifiers[CONTROL_KEY_SHIFT] && key.key.loose_keycode;
u16 code;
u8 command = MDFR_NONE;
if (shift) command |= MDFR_SHIFT; if (shift) command |= MDFR_SHIFT;
if (ctrl) command |= MDFR_CTRL; if (ctrl) command |= MDFR_CTRL;
if (alt) command |= MDFR_ALT; if (alt) command |= MDFR_ALT;
u16 code = key.key.character_no_caps_lock; command |= MDFR_EXACT;
if (code == 0) code = key.key.keycode; code = key.key.keycode;
map_find(map, code, command, &bind); map_find(map, code, command, &bind);
if (bind.function == 0 && key.key.character_no_caps_lock != 0){ command &= ~(MDFR_EXACT);
map_get_vanilla_keyboard_default(map, command, &bind); 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; return bind;

52
4ed_config.h Normal file
View File

@ -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

View File

@ -23,7 +23,7 @@ struct Dbg_Past_Key{
struct Debug_View{ struct Debug_View{
View view_base; View view_base;
Font *font; Render_Font *font;
Debug_Mode mode; Debug_Mode mode;
Dbg_Past_Key past_keys[32]; Dbg_Past_Key past_keys[32];
i32 past_key_count, past_key_pos; i32 past_key_count, past_key_pos;
@ -38,7 +38,7 @@ view_to_debug_view(View *view){
internal i32 internal i32
draw_general_memory(Debug_View *view, i32_Rect rect, Render_Target *target, i32 y){ 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; i32 y_advance = font->height;
Bubble *sentinel = &view->view_base.mem->general.sentinel; 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 internal i32
draw_system_memory(System_Functions *system, Debug_View *view, i32_Rect rect, Render_Target *target, i32 y){ 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; i32 y_advance = font->height;
Bubble *sentinel = system->internal_sentinel(); Bubble *sentinel = system->internal_sentinel();
@ -182,7 +182,7 @@ draw_modifiers(Debug_View *view, Render_Target *target,
internal i32 internal i32
draw_key_event(Debug_View *view, Render_Target *target, draw_key_event(Debug_View *view, Render_Target *target,
Dbg_Past_Key *key, i32 x, i32 y, u32 on_color, u32 off_color){ 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, draw_modifiers(view, target, key->modifiers,
on_color, off_color, &x, y); 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; x = rect.x0;
y = rect.y0; y = rect.y0;
Font *font = view->font; Render_Font *font = view->font;
draw_modifiers(view, target, active_input->keys.modifiers, draw_modifiers(view, target, active_input->keys.modifiers,
0xFFFFFFFF, 0xFF444444, &x, y); 0xFFFFFFFF, 0xFF444444, &x, y);

378
4ed_dll_reader.cpp Normal file
View File

@ -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

441
4ed_dll_reader.h Normal file
View File

@ -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

View File

@ -87,7 +87,7 @@ struct Undo_Data{
struct Editing_File{ struct Editing_File{
Buffer_Type buffer; Buffer_Type buffer;
Font *font; Render_Font *font;
i32 cursor_pos; i32 cursor_pos;
b32 is_dummy; b32 is_dummy;
@ -558,7 +558,7 @@ widget_match(Widget_ID s1, Widget_ID s2){
struct UI_State{ struct UI_State{
Render_Target *target; Render_Target *target;
Style *style; Style *style;
Font *font; Render_Font *font;
Mouse_Summary *mouse; Mouse_Summary *mouse;
Key_Summary *keys; Key_Summary *keys;
Key_Codes *codes; Key_Codes *codes;
@ -983,7 +983,7 @@ internal bool32
do_text_field(Widget_ID wid, UI_State *state, UI_Layout *layout, do_text_field(Widget_ID wid, UI_State *state, UI_Layout *layout,
String prompt, String dest){ String prompt, String dest){
bool32 result = 0; bool32 result = 0;
Font *font = state->font; Render_Font *font = state->font;
i32 character_h = font->height; i32 character_h = font->height;
i32_Rect rect = layout_rect(layout, character_h); 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 internal void
file_measure_starts_widths(System_Functions *system, 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(); ProfileMomentFunction();
if (!buffer->line_starts){ if (!buffer->line_starts){
i32 max = buffer->line_max = Kbytes(1); i32 max = buffer->line_max = Kbytes(1);
@ -1331,7 +1331,7 @@ struct Opaque_Font_Advance{
}; };
inline Opaque_Font_Advance inline Opaque_Font_Advance
get_opaque_font_advance(Font *font){ get_opaque_font_advance(Render_Font *font){
Opaque_Font_Advance result; Opaque_Font_Advance result;
result.data = (char*)font->chardata + OffsetOfPtr(font->chardata, xadvance); result.data = (char*)font->chardata + OffsetOfPtr(font->chardata, xadvance);
result.stride = sizeof(*font->chardata); result.stride = sizeof(*font->chardata);
@ -1373,7 +1373,7 @@ file_measure_widths(General_Memory *general, Buffer_Type *buffer, Font *font){
internal void internal void
file_remeasure_widths(System_Functions *system, 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){ i32 line_start, i32 line_end, i32 line_shift){
#if BUFFER_EXPERIMENT_SCALPEL <= 3 #if BUFFER_EXPERIMENT_SCALPEL <= 3
ProfileMomentFunction(); ProfileMomentFunction();
@ -1400,7 +1400,7 @@ view_compute_lowest_line(File_View *view){
} }
else{ else{
Style *style = view->style; Style *style = view->style;
Font *font = style->font; Render_Font *font = style->font;
real32 wrap_y = view->line_wrap_y[last_line]; real32 wrap_y = view->line_wrap_y[last_line];
lowest_line = FLOOR32(wrap_y / font->height); lowest_line = FLOOR32(wrap_y / font->height);
f32 max_width = view_compute_width(view); f32 max_width = view_compute_width(view);
@ -1438,9 +1438,9 @@ view_measure_wraps(System_Functions *system,
} }
} }
Font *font = view->style->font; Render_Font *font = view->style->font;
real32 line_height = (real32)font->height; f32 line_height = (f32)font->height;
real32 max_width = view_compute_width(view); f32 max_width = view_compute_width(view);
buffer_measure_wrap_y(buffer, view->line_wrap_y, line_height, max_width); buffer_measure_wrap_y(buffer, view->line_wrap_y, line_height, max_width);
view->line_count = line_count; view->line_count = line_count;
@ -1456,7 +1456,8 @@ alloc_for_buffer(void *context, int *size){
internal void internal void
file_create_from_string(System_Functions *system, 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 = {}; *file = {};
General_Memory *general = &mem->general; General_Memory *general = &mem->general;
#if BUFFER_EXPERIMENT_SCALPEL <= 3 #if BUFFER_EXPERIMENT_SCALPEL <= 3
@ -1517,10 +1518,11 @@ file_create_from_string(System_Functions *system,
} }
internal bool32 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; bool32 result = 0;
File_Data raw_file = system->load_file(filename); Data raw_file = system->load_file(filename);
if (raw_file.data){ if (raw_file.data){
result = 1; result = 1;
String val = make_string((char*)raw_file.data, raw_file.size); 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 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; b32 result = 1;
String empty_str = {}; String empty_str = {};
file_create_from_string(system, mem, file, filename, font, 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 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; b32 result = 1;
String empty_str = {}; String empty_str = {};
file_create_from_string(system, mem, file, filename, font, empty_str, 1); file_create_from_string(system, mem, file, filename, font, empty_str, 1);
@ -1617,7 +1621,7 @@ struct Shift_Information{
i32 start, end, amount; i32 start, end, amount;
}; };
#if BUFFER_EXPERIMENT_SCALPEL <= 0 #if 0 //BUFFER_EXPERIMENT_SCALPEL <= 0
internal internal
Job_Callback(job_full_lex){ Job_Callback(job_full_lex){
Editing_File *file = (Editing_File*)data[0]; Editing_File *file = (Editing_File*)data[0];
@ -1680,6 +1684,83 @@ Job_Callback(job_full_lex){
file->tokens_complete = 1; file->tokens_complete = 1;
file->still_lexing = 0; 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 #endif
internal void internal void
@ -1705,13 +1786,17 @@ file_first_lex_parallel(System_Functions *system,
file->tokens_complete = 0; file->tokens_complete = 0;
file->tokens_exist = 1; file->tokens_exist = 1;
file->still_lexing = 1; file->still_lexing = 1;
full_lex(system, file, general);
#if 0
Job_Data job; Job_Data job;
job.callback = job_full_lex; job.callback = job_full_lex;
job.data[0] = file; job.data[0] = file;
job.data[1] = general; job.data[1] = general;
job.memory_request = Kbytes(64); job.memory_request = Kbytes(64);
file->lex_job = system->post_job(BACKGROUND_THREADS, job); file->lex_job = system->post_job(BACKGROUND_THREADS, job);
#endif
} }
internal void internal void
@ -1790,13 +1875,17 @@ file_relex_parallel(System_Functions *system,
} }
file->still_lexing = 1; file->still_lexing = 1;
full_lex(system, file, general);
#if 0
Job_Data job; Job_Data job;
job.callback = job_full_lex; job.callback = job_full_lex;
job.data[0] = file; job.data[0] = file;
job.data[1] = general; job.data[1] = general;
job.memory_request = Kbytes(64); job.memory_request = Kbytes(64);
file->lex_job = system->post_job(BACKGROUND_THREADS, job); file->lex_job = system->post_job(BACKGROUND_THREADS, job);
#endif
} }
} }
#endif #endif
@ -2093,7 +2182,7 @@ view_compute_cursor_from_pos(File_View *view, i32 pos){
#if BUFFER_EXPERIMENT_SCALPEL <= 3 #if BUFFER_EXPERIMENT_SCALPEL <= 3
Editing_File *file = view->file; Editing_File *file = view->file;
Style *style = view->style; Style *style = view->style;
Font *font = style->font; Render_Font *font = style->font;
real32 max_width = view_compute_width(view); 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 #if BUFFER_EXPERIMENT_SCALPEL <= 3
Editing_File *file = view->file; Editing_File *file = view->file;
Style *style = view->style; Style *style = view->style;
Font *font = style->font; Render_Font *font = style->font;
real32 max_width = view_compute_width(view); 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 #if BUFFER_EXPERIMENT_SCALPEL <= 3
Editing_File *file = view->file; Editing_File *file = view->file;
Style *style = view->style; Style *style = view->style;
Font *font = style->font; Render_Font *font = style->font;
real32 max_width = view_compute_width(view); real32 max_width = view_compute_width(view);
@ -2207,7 +2296,7 @@ view_set_file(System_Functions *system,
view->locked = file->super_locked; view->locked = file->super_locked;
General_Memory *general = &view->view_base.mem->general; General_Memory *general = &view->view_base.mem->general;
Font *font = style->font; Render_Font *font = style->font;
view->style = style; view->style = style;
view->font_advance = font->advance; view->font_advance = font->advance;
view->font_height = font->height; view->font_height = font->height;
@ -2313,7 +2402,7 @@ view_set_widget(File_View *view, File_View_Widget_Type type){
} }
inline i32 inline i32
view_widget_height(File_View *view, Font *font){ view_widget_height(File_View *view, Render_Font *font){
i32 result = 0; i32 result = 0;
switch (view->widget.type){ switch (view->widget.type){
case FWIDG_NONE: break; case FWIDG_NONE: break;
@ -2325,7 +2414,7 @@ view_widget_height(File_View *view, Font *font){
} }
inline i32_Rect 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; Panel *panel = view->view_base.panel;
i32_Rect whole = panel->inner; i32_Rect whole = panel->inner;
i32_Rect result; i32_Rect result;
@ -3530,7 +3619,7 @@ internal bool32
do_button(i32 id, UI_State *state, UI_Layout *layout, char *text, i32 height_mult, do_button(i32 id, UI_State *state, UI_Layout *layout, char *text, i32 height_mult,
bool32 is_toggle = 0, bool32 on = 0){ bool32 is_toggle = 0, bool32 on = 0){
bool32 result = 0; bool32 result = 0;
Font *font = state->font; Render_Font *font = state->font;
i32 character_h = font->height; i32 character_h = font->height;
i32_Rect btn_rect = layout_rect(layout, character_h * height_mult); 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 internal bool32
do_undo_slider(Widget_ID wid, UI_State *state, UI_Layout *layout, i32 max, i32 v, Undo_Data *undo, i32 *out){ do_undo_slider(Widget_ID wid, UI_State *state, UI_Layout *layout, i32 max, i32 v, Undo_Data *undo, i32 *out){
bool32 result = 0; bool32 result = 0;
Font *font = state->font; Render_Font *font = state->font;
i32 character_h = font->height; i32 character_h = font->height;
i32_Rect containing_rect = layout_rect(layout, character_h); 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){ if (show_ticks){
real32_Rect tick; f32_Rect tick;
tick.x0 = (real32)click_rect.x0 - 1; tick.x0 = (real32)click_rect.x0 - 1;
tick.x1 = (real32)click_rect.x0 + 1; tick.x1 = (real32)click_rect.x0 + 1;
tick.y0 = (real32)bar_top - 3; 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){ if (show_ticks){
real32_Rect tick; f32_Rect tick;
tick.x0 = (real32)click_rect.x0 - 1; tick.x0 = (real32)click_rect.x0 - 1;
tick.x1 = (real32)click_rect.x0 + 1; tick.x1 = (real32)click_rect.x0 + 1;
tick.y0 = (real32)bar_top - 3; 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_; File_View *view = (File_View*)view_;
Editing_File *file = view->file; Editing_File *file = view->file;
Style *style = view->style; Style *style = view->style;
Font *font = style->font; Render_Font *font = style->font;
f32 line_height = (f32)font->height; f32 line_height = (f32)font->height;
f32 cursor_y = view_get_cursor_y(view); 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_; File_View *view = (File_View*)view_;
Editing_File *file = view->file; Editing_File *file = view->file;
Style *style = view->style; Style *style = view->style;
Font *font = style->font; Render_Font *font = style->font;
Interactive_Bar bar; Interactive_Bar bar;
bar.style = style->main.file_info_style; 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){ if (view->widget.type != FWIDG_NONE){
UI_Style ui_style = get_ui_style_upper(style); 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); i32_Rect widg_rect = view_widget_rect(view, font);
draw_rectangle(target, widg_rect, ui_style.dark); 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){ if (result.hit_newline || result.hit_ctrl_newline){
i32 line_number = str_to_int(*string); 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; if (line_number < 1) line_number = 1;
file_view->cursor = file_view->cursor =
view_compute_cursor_from_unwrapped_xy(file_view, 0, (real32)(line_number-1)*font->height); view_compute_cursor_from_unwrapped_xy(file_view, 0, (real32)(line_number-1)*font->height);

View File

@ -1,7 +1,7 @@
/* /*
* Mr. 4th Dimention - Allen Webster * Mr. 4th Dimention - Allen Webster
* *
* 12.17.2014 * 16.11.2014
* *
* Win32-US Keyboard layer for 4coder * Win32-US Keyboard layer for 4coder
* *
@ -13,90 +13,27 @@ globalvar u16 keycode_lookup_table[255];
globalvar u16 loose_keycode_lookup_table[255]; globalvar u16 loose_keycode_lookup_table[255];
internal void internal void
keycode_init(Key_Codes *codes){ set_dynamic_key_names(Key_Codes *codes){
// NOTE(allen): Assign values to the global keycodes. u16 code = 1;
// Skip over the ascii characters that are used as codes.
u16 code = 1, loose;
u16 *codes_array = (u16*)codes; 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){ switch (code){
case '\n': code++; break; case '\n': code++; break;
case '\t': code++; break; case '\t': code++; break;
case 0x20: code = 0x7F; break; case 0x20: code = 0x7F; break;
default:
codes_array[i++] = code++;
} }
} 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;
}
} }
} }
inline u16 inline u16
keycode_lookup(u8 virtual_keycode){ keycode_lookup(u8 system_code){
return keycode_lookup_table[virtual_keycode]; return keycode_lookup_table[system_code];
} }
inline u16 inline u16
loose_keycode_lookup(u8 virtual_keycode){ loose_keycode_lookup(u8 system_code){
return loose_keycode_lookup_table[virtual_keycode]; return loose_keycode_lookup_table[system_code];
} }
inline b32 inline b32
@ -105,10 +42,9 @@ keycode_has_ascii(u16 keycode){
} }
internal u8 internal u8
keycode_to_character_ascii(Key_Codes *codes, translate_key(u16 keycode,
u16 keycode, b32 shift,
bool32 shift, b32 caps_lock){
bool32 caps_lock){
u8 character = 0; u8 character = 0;
if (keycode >= 'A' && keycode <= 'Z'){ if (keycode >= 'A' && keycode <= 'Z'){
if (caps_lock) shift = !shift; if (caps_lock) shift = !shift;

View File

@ -26,7 +26,7 @@ struct Interactive_Bar{
real32 pos_x, pos_y; real32 pos_x, pos_y;
real32 text_shift_x, text_shift_y; real32 text_shift_x, text_shift_y;
i32_Rect rect; i32_Rect rect;
Font *font; Render_Font *font;
}; };
enum View_Message{ enum View_Message{
@ -135,7 +135,7 @@ struct Editing_Layout{
internal void internal void
intbar_draw_string(Render_Target *target, Interactive_Bar *bar, intbar_draw_string(Render_Target *target, Interactive_Bar *bar,
u8 *str, u32 char_color){ u8 *str, u32 char_color){
Font *font = bar->font; Render_Font *font = bar->font;
for (i32 i = 0; str[i]; ++i){ for (i32 i = 0; str[i]; ++i){
char c = str[i]; char c = str[i];
font_draw_glyph(target, font, c, font_draw_glyph(target, font, c,
@ -150,7 +150,7 @@ internal void
intbar_draw_string(Render_Target *target, intbar_draw_string(Render_Target *target,
Interactive_Bar *bar, String str, Interactive_Bar *bar, String str,
u32 char_color){ u32 char_color){
Font *font = bar->font; Render_Font *font = bar->font;
for (i32 i = 0; i < str.size; ++i){ for (i32 i = 0; i < str.size; ++i){
char c = str.str[i]; char c = str.str[i];
font_draw_glyph(target, font, c, font_draw_glyph(target, font, c,

View File

@ -9,12 +9,34 @@
// TOP // TOP
internal Key_Event_Data #include "4ed_keyboard.cpp"
get_key_event(SDL_Event *event){
Key_Event_Data result = {};
return result;
}
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 // BOTTOM

View File

@ -103,7 +103,7 @@ struct i32_Rect{
i32 x1, y1; i32 x1, y1;
}; };
struct real32_Rect{ struct f32_Rect{
f32 x0, y0; f32 x0, y0;
f32 x1, y1; f32 x1, y1;
}; };
@ -117,7 +117,7 @@ i32R(i32 l, i32 t, i32 r, i32 b){
} }
inline i32_Rect inline i32_Rect
i32R(real32_Rect r){ i32R(f32_Rect r){
i32_Rect rect; i32_Rect rect;
rect.x0 = (i32)r.x0; rect.x0 = (i32)r.x0;
rect.y0 = (i32)r.y0; rect.y0 = (i32)r.y0;
@ -134,53 +134,53 @@ i32XYWH(i32 x, i32 y, i32 w, i32 h){
return rect; return rect;
} }
inline real32_Rect inline f32_Rect
f32R(real32 l, real32 t, real32 r, real32 b){ f32R(f32 l, f32 t, f32 r, f32 b){
real32_Rect rect; f32_Rect rect;
rect.x0 = l; rect.y0 = t; rect.x0 = l; rect.y0 = t;
rect.x1 = r; rect.y1 = b; rect.x1 = r; rect.y1 = b;
return rect; return rect;
} }
inline real32_Rect inline f32_Rect
f32R(i32_Rect r){ f32R(i32_Rect r){
real32_Rect rect; f32_Rect rect;
rect.x0 = (real32)r.x0; rect.x0 = (f32)r.x0;
rect.y0 = (real32)r.y0; rect.y0 = (f32)r.y0;
rect.x1 = (real32)r.x1; rect.x1 = (f32)r.x1;
rect.y1 = (real32)r.y1; rect.y1 = (f32)r.y1;
return rect; return rect;
} }
inline real32_Rect inline f32_Rect
f32XYWH(f32 x, f32 y, f32 w, f32 h){ f32XYWH(f32 x, f32 y, f32 w, f32 h){
real32_Rect rect; f32_Rect rect;
rect.x0 = x; rect.y0 = y; rect.x0 = x; rect.y0 = y;
rect.x1 = x+w; rect.y1 = y+h; rect.x1 = x+w; rect.y1 = y+h;
return rect; return rect;
} }
inline bool32 inline b32
hit_check(i32 x, i32 y, i32 x0, i32 y0, i32 x1, i32 y1){ hit_check(i32 x, i32 y, i32 x0, i32 y0, i32 x1, i32 y1){
return (x >= x0 && x < x1 && y >= y0 && y < y1); return (x >= x0 && x < x1 && y >= y0 && y < y1);
} }
inline bool32 inline b32
hit_check(i32 x, i32 y, i32_Rect rect){ hit_check(i32 x, i32 y, i32_Rect rect){
return (hit_check(x, y, rect.x0, rect.y0, rect.x1, rect.y1)); return (hit_check(x, y, rect.x0, rect.y0, rect.x1, rect.y1));
} }
inline bool32 inline b32
hit_check(i32 x, i32 y, real32 x0, real32 y0, real32 x1, real32 y1){ hit_check(i32 x, i32 y, f32 x0, f32 y0, f32 x1, f32 y1){
return (x >= x0 && x < x1 && y >= y0 && y < y1); return (x >= x0 && x < x1 && y >= y0 && y < y1);
} }
inline bool32 inline b32
hit_check(i32 x, i32 y, real32_Rect rect){ hit_check(i32 x, i32 y, f32_Rect rect){
return (hit_check(x, y, rect.x0, rect.y0, rect.x1, rect.y1)); return (hit_check(x, y, rect.x0, rect.y0, rect.x1, rect.y1));
} }
inline bool32 inline b32
positive_area(i32_Rect rect){ positive_area(i32_Rect rect){
return (rect.x0 < rect.x1 && rect.y0 < rect.y1); return (rect.x0 < rect.x1 && rect.y0 < rect.y1);
} }
@ -195,12 +195,26 @@ get_inner_rect(i32_Rect outer, i32 margin){
return r; return r;
} }
inline bool32 inline b32
fits_inside(i32_Rect rect, i32_Rect outer){ fits_inside(i32_Rect rect, i32_Rect outer){
return (rect.x0 >= outer.x0 && rect.x1 <= outer.x1 && return (rect.x0 >= outer.x0 && rect.x1 <= outer.x1 &&
rect.y0 >= outer.y0 && rect.y1 <= outer.y1); 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 * Vectors
*/ */

View File

@ -28,11 +28,18 @@ typedef i8 bool8;
typedef i32 b32; typedef i32 b32;
typedef i8 b8; typedef i8 b8;
typedef uint8_t byte;
typedef float real32; typedef float real32;
typedef double real64; typedef double real64;
typedef float f32; typedef float f32;
typedef double f64; typedef double f64;
struct Data{
byte *data;
i32 size;
};
#define external extern "C" #define external extern "C"
#define internal static #define internal static
#define globalvar static #define globalvar static

File diff suppressed because it is too large Load Diff

View File

@ -1,46 +1,28 @@
/* /*
* Mr. 4th Dimention - Allen Webster * Mr. 4th Dimention - Allen Webster
* *
* 12.17.2014 * 17.12.2014
* *
* Rendering layer for project codename "4ed" * Rendering layer for project codename "4ed"
* *
*/ */
// TOP
#ifndef FRED_RENDERING_H #ifndef FRED_RENDERING_H
#define FRED_RENDERING_H #define FRED_RENDERING_H
#define STB_TRUETYPE_IMPLEMENTATION #define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h" #include "stb_truetype.h"
#if SOFTWARE_RENDER
struct Glyph_Data{ struct Glyph_Data{
void *data; b32 exists;
i32 width, height;
i32 minx, maxx, miny, maxy;
i32 left_shift;
bool32 exists;
}; };
struct Font{ struct Render_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{
char name_[24]; char name_[24];
String name; String name;
bool32 loaded; b32 loaded;
Glyph_Data glyphs[256]; Glyph_Data glyphs[256];
stbtt_bakedchar chardata[256]; stbtt_bakedchar chardata[256];
@ -50,6 +32,101 @@ struct Font{
u32 tex; u32 tex;
i32 tex_width, tex_height; 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 #endif
// BOTTOM

215
4ed_rendering_helper.cpp Normal file
View File

@ -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

405
4ed_rendering_old.cpp Normal file
View File

@ -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

View File

@ -214,7 +214,7 @@ struct Style_File_Format{
struct Style{ struct Style{
char name_[24]; char name_[24];
String name; String name;
Font *font; Render_Font *font;
Style_Main_Data main; Style_Main_Data main;
bool32 font_changed; bool32 font_changed;
}; };
@ -225,7 +225,7 @@ struct Style_Library{
}; };
struct Font_Set{ struct Font_Set{
Font *fonts; Render_Font *fonts;
i32 count, max; i32 count, max;
}; };
@ -243,12 +243,12 @@ style_set_name(Style *style, String name){
copy(&style->name, name); copy(&style->name, name);
} }
internal Font* internal Render_Font*
font_set_extract(Font_Set *fonts, char *name, i32 size){ font_set_extract(Font_Set *fonts, char *name, i32 size){
String n = make_string(name, size); String n = make_string(name, size);
i32 count = fonts->count; i32 count = fonts->count;
Font *result = 0; Render_Font *result = 0;
Font *font = fonts->fonts; Render_Font *font = fonts->fonts;
for (i32 i = 0; i < count; ++i, ++font){ for (i32 i = 0; i < count; ++i, ++font){
if (match(n, font->name)){ if (match(n, font->name)){
result = font; result = font;
@ -479,7 +479,7 @@ style_library_import(System_Functions *system,
char *filename, Font_Set *fonts, Style *out, i32 max, char *filename, Font_Set *fonts, Style *out, i32 max,
i32 *count_opt, i32 *total_opt = 0){ i32 *count_opt, i32 *total_opt = 0){
b32 result = 1; b32 result = 1;
File_Data file = system->load_file(filename); Data file = system->load_file(filename);
Style_Page_Header *h = 0; Style_Page_Header *h = 0;
if (!file.data){ if (!file.data){
@ -573,7 +573,7 @@ style_library_add(Style_Library *library, Style *style){
internal Style_File_Format* internal Style_File_Format*
style_format_for_file(Style *style, Style_File_Format *out){ 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; out->name_size = style->name.size;
memcpy(out->name, style->name.str, ArrayCount(out->name)); memcpy(out->name, style->name.str, ArrayCount(out->name));
out->font_name_size = font->name.size; out->font_name_size = font->name.size;

View File

@ -15,17 +15,12 @@ struct Plat_Handle{
u32 d[4]; u32 d[4];
}; };
struct File_Data{
void *data;
u32 size;
};
struct Time_Stamp{ struct Time_Stamp{
u64 time; u64 time;
b32 success; 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); typedef Sys_Load_File_Sig(System_Load_File);
#define Sys_Save_File_Sig(name) i32 name(char *filename, void *data, i32 size) #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() #define Sys_Time_Stamp_Now_Sig(name) u64 name()
typedef Sys_Time_Stamp_Now_Sig(System_Time_Stamp_Now); typedef Sys_Time_Stamp_Now_Sig(System_Time_Stamp_Now);
#if 0 #define Sys_Free_File_Sig(name) void name(Data file)
#define Sys_Free_File_Sig(name) void name(File_Data file)
typedef Sys_Free_File_Sig(System_Free_File); typedef Sys_Free_File_Sig(System_Free_File);
#endif
#define Sys_Get_Current_Directory_Sig(name) i32 name(char *out, i32 max) #define Sys_Get_Current_Directory_Sig(name) i32 name(char *out, i32 max)
typedef Sys_Get_Current_Directory_Sig(System_Get_Current_Directory); typedef Sys_Get_Current_Directory_Sig(System_Get_Current_Directory);
@ -127,8 +120,9 @@ struct Thread_Memory{
i32 id; i32 id;
}; };
#define Job_Callback(name) void name(System_Functions *system, Thread_Context *thread, Thread_Memory *memory, void *data[2]) #define Job_Callback_Sig(name) void name(\
typedef Job_Callback(Job_Callback); System_Functions *system, Thread_Context *thread, Thread_Memory *memory, void *data[2])
typedef Job_Callback_Sig(Job_Callback);
struct Job_Data{ struct Job_Data{
Job_Callback *callback; 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) #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); 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{ struct System_Functions{
System_Load_File *load_file; System_Load_File *load_file;
System_Save_File *save_file; System_Save_File *save_file;
@ -206,6 +203,7 @@ struct System_Functions{
INTERNAL_System_Sentinel *internal_sentinel; INTERNAL_System_Sentinel *internal_sentinel;
INTERNAL_System_Get_Thread_States *internal_get_thread_states; INTERNAL_System_Get_Thread_States *internal_get_thread_states;
INTERNAL_System_Debug_Message *internal_debug_message;
}; };
// BOTTOM // BOTTOM

80
4ed_win32_keyboard.cpp Normal file
View File

@ -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

206
dll_reader.cpp Normal file
View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <assert.h>
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 <Windows.h>
#define UseWinDll 0
int
main(int argc, char **argv){
Function *func;
i32 x;
#if UseWinDll
HMODULE module;
if (argc < 2){
printf("usage: dll_reader <dll-file>\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 <dll-file>\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

View File

@ -75,18 +75,27 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <SDL/SDL.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <GL/gl.h> #include <GL/gl.h>
#include <stdio.h>
#include "4ed_internal.h" #include "4ed_internal.h"
#include "4ed_linux_keyboard.cpp" #include "4ed_linux_keyboard.cpp"
#define printe(m) printf("%s:%d: %s\n", __FILE__, __LINE__, #m) #define printe(m) printf("%s:%d: %s\n", __FILE__, __LINE__, #m)
struct Linux_Vars{ struct Linux_Vars{
Application_Memory mem; Key_Codes codes;
Key_Input_Data input; Key_Input_Data input;
Mouse_State mouse;
Render_Target target;
Application_Memory mem;
b32 keep_going; b32 keep_going;
b32 force_redraw;
Clipboard_Contents clipboard; Clipboard_Contents clipboard;
@ -95,6 +104,7 @@ struct Linux_Vars{
System_Functions *system; System_Functions *system;
App_Functions app; App_Functions app;
Config_API config_api; Config_API config_api;
}; };
Linux_Vars linuxvars; Linux_Vars linuxvars;
@ -206,13 +216,11 @@ LinuxLoadAppCode(){
--size); --size);
memcpy(path + size + 1, app_code_file, app_code_file_len + 1); 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){ if (linuxvars.app_code){
result = 1; result = 1;
linuxvars.app.init = (App_Init*) linuxvars.app.init = (App_Init*)0;
SDL_LoadFunction(linuxvars.app_code, "app_init"); linuxvars.app.step = (App_Step*)0;
linuxvars.app.step = (App_Step*)
SDL_LoadFunction(linuxvars.app_code, "app_step");
} }
else{ else{
// TODO(allen): initialization failure // TODO(allen): initialization failure
@ -232,6 +240,11 @@ Sys_Release_Lock_Sig(system_release_lock){
AllowLocal(id); AllowLocal(id);
} }
internal
Sys_Force_Redraw_Sig(system_force_redraw){
linuxvars.force_redraw = 1;
}
internal void internal void
LinuxLoadSystemCode(){ LinuxLoadSystemCode(){
linuxvars.system->get_memory_full = system_get_memory_; linuxvars.system->get_memory_full = system_get_memory_;
@ -275,16 +288,13 @@ LinuxLoadSystemCode(){
#endif #endif
} }
internal void
LinuxShowScreen(){
}
int main(){ int main(){
linuxvars = {}; linuxvars = {};
if (SDL_Init(SDL_INIT_VIDEO)){
// TODO(allen): initialization failure
printe(SDL_Init);
return(1);
}
SDL_EnableUNICODE(1);
if (!LinuxLoadAppCode()){ if (!LinuxLoadAppCode()){
return(1); return(1);
} }
@ -293,14 +303,7 @@ int main(){
System_Functions *system = &system_; System_Functions *system = &system_;
linuxvars.system = system; linuxvars.system = system;
LinuxLoadSystemCode(); LinuxLoadSystemCode();
const SDL_VideoInfo *info = SDL_GetVideoInfo();
if (!info){
// TODO(allen): initialization failure
printe(info);
return(1);
}
{ {
void *base; void *base;
#if FRED_INTERNAL #if FRED_INTERNAL
@ -329,72 +332,59 @@ int main(){
i32 width = 800; i32 width = 800;
i32 height = 600; i32 height = 600;
i32 bpp = info->vfmt->BitsPerPixel; i32 bpp = 24;
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);
linuxvars.target.width = width;
linuxvars.target.height = height;
keycode_init(&linuxvars.codes);
system_acquire_lock(FRAME_LOCK); system_acquire_lock(FRAME_LOCK);
b32 first = 1; b32 first = 1;
linuxvars.keep_going = 1; linuxvars.keep_going = 1;
i64 timer_start = system_time();
SDL_Event event;
for (;linuxvars.keep_going && SDL_WaitEvent(&event);){ for (;linuxvars.keep_going;){
b32 pass_to_app = 0;
linuxvars.input = {}; linuxvars.input = {};
linuxvars.clipboard = {}; linuxvars.clipboard = {};
switch (event.type){ linuxvars.mouse.wheel = 0;
case SDL_ACTIVEEVENT: linuxvars.force_redraw = 0;
{
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;
for (;0;){
} }
if (pass_to_app){ linuxvars.mouse.left_button_prev = linuxvars.mouse.left_button;
Application_Step_Result app_result = linuxvars.mouse.right_button_prev = linuxvars.mouse.right_button;
linuxvars.app.step(linuxvars.system,
0, #if 0
0, Application_Step_Result app_result =
&linuxvars.input, linuxvars.app.step(linuxvars.system,
0, &linuxvars.codes,
1, &linuxvars.input,
0, &linuxvars.mouse,
&linuxvars.mem, &linuxvars.target,
linuxvars.clipboard, &linuxvars.mem,
first, 1); linuxvars.clipboard,
1, first, linuxvars.force_redraw);
#else
Application_Step_Result app_result = {};
SDL_GL_SwapBuffers(); #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); return(0);

37
test/dll_test.cpp Normal file
View File

@ -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

View File

@ -9,21 +9,6 @@
// TOP // 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 "../4ed_meta.h"
#include "../4cpp_types.h" #include "../4cpp_types.h"
@ -31,6 +16,7 @@ int main(){
#include "../4cpp_string.h" #include "../4cpp_string.h"
#define FCPP_LEXER_IMPLEMENTATION #define FCPP_LEXER_IMPLEMENTATION
#include "../4cpp_lexer.h" #include "../4cpp_lexer.h"
#include "../4cpp_preprocessor.cpp"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
@ -58,20 +44,21 @@ system_is_absoute_path(char *path){
#define Assert assert #define Assert assert
#define TentativeAssert assert #define TentativeAssert assert
#include "../4cpp_preprocessor.cpp"
Cpp_File Cpp_File
quickie_file(char *filename){ quickie_file(char *filename){
Cpp_File result; Cpp_File result = {};
FILE *file = fopen(filename, "rb"); FILE *file = fopen(filename, "rb");
TentativeAssert(file); if (file){
fseek(file, 0, SEEK_END); fseek(file, 0, SEEK_END);
result.size = ftell(file); result.size = ftell(file);
fseek(file, 0, SEEK_SET); if (result.size > 0){
result.data = (char*)malloc(result.size); fseek(file, 0, SEEK_SET);
fread(result.data, 1, result.size, file); result.data = (char*)malloc(result.size);
fclose(file); fread(result.data, 1, result.size, file);
}
fclose(file);
}
return result; return result;
} }
@ -87,12 +74,20 @@ quickie_file(String filename){
#define STRICT_MEM_TEST 1 #define STRICT_MEM_TEST 1
#if 1 int main(int argc, char **argv){
int main(){ if (argc < 2){
char TEST_FILE[] = "parser_test6.cpp"; printf("usage: %s <file>\n", argv[0]);
return 1;
}
char *TEST_FILE = argv[1];
Cpp_File target_file; Cpp_File target_file;
target_file = quickie_file(TEST_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_Token_Stack target_tokens = {};
cpp_lex_file(target_file, &target_tokens); cpp_lex_file(target_file, &target_tokens);
@ -138,7 +133,7 @@ int main(){
#endif #endif
string_tokens.tokens = (Cpp_Token*)malloc(sizeof(Cpp_Token)*string_tokens.max_count); 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.file = string_file;
string_parse_file.tokens = string_tokens; string_parse_file.tokens = string_tokens;
string_parse_file.filename = string_filename; string_parse_file.filename = string_filename;
@ -201,6 +196,10 @@ int main(){
for (; cpp_has_more_files(&request); cpp_get_next_file(&request)){ for (; cpp_has_more_files(&request); cpp_get_next_file(&request)){
if (!cpp_try_reuse_file(&request)){ if (!cpp_try_reuse_file(&request)){
Cpp_File new_file = quickie_file(request.filename); 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_Token_Stack new_tokens = {};
cpp_lex_file(new_file, &new_tokens); cpp_lex_file(new_file, &new_tokens);
cpp_provide_file(&request, new_file, new_tokens); cpp_provide_file(&request, new_file, new_tokens);
@ -210,7 +209,7 @@ int main(){
if (result.error_code){ if (result.error_code){
String error_message = cpp_get_error(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]; Cpp_Token token = file.tokens.tokens[result.token_index];
bool terminate = cpp_recommend_termination(result.error_code); bool terminate = cpp_recommend_termination(result.error_code);
@ -229,11 +228,11 @@ int main(){
} }
if (result.emit){ 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]; Cpp_Token token = file.tokens.tokens[result.token_index];
if (result.from_macro){ 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]; Cpp_Token token = file.tokens.tokens[result.invoking_token_index];
printf("EXPANDING %.*s => ", token.size, file.file.data + token.start); printf("EXPANDING %.*s => ", token.size, file.file.data + token.start);
@ -249,7 +248,6 @@ int main(){
return 0; return 0;
} }
#endif
// BOTTOM // BOTTOM

View File

@ -9,47 +9,7 @@
// TOP // TOP
#ifdef FRED_NOT_PACKAGE #include "4ed_config.h"
#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 FPS 30
#define frame_useconds (1000000 / FPS) #define frame_useconds (1000000 / FPS)
@ -63,18 +23,21 @@
#include "4cpp_string.h" #include "4cpp_string.h"
#include "4ed_mem.cpp" #include "4ed_mem.cpp"
#include "4ed_math.cpp" #include "4ed_math.cpp"
#include "4ed_dll_reader.h"
#include "4coder_custom.h" #include "4coder_custom.h"
#include "4ed_system.h" #include "4ed_system.h"
#include "4ed.h"
#include "4ed_rendering.h" #include "4ed_rendering.h"
#include "4ed.h"
#include <windows.h> #include <windows.h>
#include <GL/gl.h> #include <GL/gl.h>
#include "4ed_dll_reader.cpp"
#include "4ed_rendering.cpp"
#include "4ed_internal.h" #include "4ed_internal.h"
#include "4ed_keyboard.cpp" #include "4ed_win32_keyboard.cpp"
struct Full_Job_Data{ struct Full_Job_Data{
Job_Data job; Job_Data job;
@ -108,24 +71,14 @@ struct Thread_Group{
i32 count; i32 count;
}; };
#define UseWinDll 0
struct Win32_Vars{ struct Win32_Vars{
HWND window_handle; HWND window_handle;
Key_Codes key_codes; Key_Codes key_codes;
Key_Input_Data input_data, previous_data; 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; Render_Target target;
#endif
u32 volatile force_redraw; u32 volatile force_redraw;
@ -153,7 +106,11 @@ struct Win32_Vars{
i64 start_pcount; i64 start_pcount;
HMODULE custom; HMODULE custom;
#if UseWinDll
HMODULE app_code; HMODULE app_code;
#else
DLL_Loaded app_dll;
#endif
System_Functions *system; System_Functions *system;
App_Functions app; App_Functions app;
@ -167,11 +124,19 @@ struct Win32_Vars{
globalvar Win32_Vars win32vars; globalvar Win32_Vars win32vars;
globalvar Application_Memory win32memory; globalvar Application_Memory win32memory;
#if FRED_INTERNAL
internal Bubble* internal Bubble*
INTERNAL_system_sentinel(){ INTERNAL_system_sentinel(){
return (&win32vars.internal_bubble); return (&win32vars.internal_bubble);
} }
internal void
INTERNAL_system_debug_message(char *message){
OutputDebugString(message);
}
#endif
internal void* internal void*
system_get_memory_(i32 size, i32 line_number, char *file_name){ system_get_memory_(i32 size, i32 line_number, char *file_name){
void *ptr = 0; void *ptr = 0;
@ -213,9 +178,9 @@ system_free_memory(void *block){
} }
} }
internal File_Data internal Data
system_load_file(char *filename){ system_load_file(char *filename){
File_Data result = {}; Data result = {};
HANDLE file; HANDLE file;
file = CreateFile((char*)filename, GENERIC_READ, 0, 0, file = CreateFile((char*)filename, GENERIC_READ, 0, 0,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
@ -232,7 +197,7 @@ system_load_file(char *filename){
} }
result.size = (lo) + (((u64)hi) << 32); result.size = (lo) + (((u64)hi) << 32);
result.data = system_get_memory(result.size); result.data = (byte*)system_get_memory(result.size);
if (!result.data){ if (!result.data){
CloseHandle(file); CloseHandle(file);
@ -243,7 +208,7 @@ system_load_file(char *filename){
DWORD read_size; DWORD read_size;
BOOL read_result = ReadFile(file, result.data, result.size, BOOL read_result = ReadFile(file, result.data, result.size,
&read_size, 0); &read_size, 0);
if (!read_result || read_size != result.size){ if (!read_result || read_size != (u32)result.size){
CloseHandle(file); CloseHandle(file);
system_free_memory(result.data); system_free_memory(result.data);
result = {}; result = {};
@ -316,7 +281,7 @@ system_time(){
} }
internal void internal void
system_free_file(File_Data data){ system_free_file(Data data){
system_free_memory(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 internal void
Win32RedrawScreen(HDC hdc){ Win32RedrawScreen(HDC hdc){
launch_rendering(&win32vars.target);
win32vars.target.size = 0;
glFlush(); glFlush();
SwapBuffers(hdc); SwapBuffers(hdc);
} }
#endif
internal void internal void
Win32Resize(i32 width, i32 height){ Win32Resize(i32 width, i32 height){
@ -583,43 +530,19 @@ Win32Callback(HWND hwnd, UINT uMsg,
case WM_SIZE: 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){ if (win32vars.target.handle){
i32 new_width = LOWORD(lParam); i32 new_width = LOWORD(lParam);
i32 new_height = HIWORD(lParam); i32 new_height = HIWORD(lParam);
Win32Resize(new_width, new_height); Win32Resize(new_width, new_height);
} }
#endif
}break; }break;
case WM_PAINT: case WM_PAINT:
{ {
PAINTSTRUCT ps; PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps); HDC hdc = BeginPaint(hwnd, &ps);
Clipboard_Contents empty_contents = {}; Clipboard_Contents empty_contents = {};
win32vars.app.step(win32vars.system, win32vars.app.step(win32vars.system,
&win32vars.key_codes, &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].running_thread = THREAD_NOT_ASSIGNED;
queue->jobs[write_index].id = result; queue->jobs[write_index].id = result;
success = 1; success = 1;
// TODO
} }
} }
@ -969,10 +894,16 @@ system_cli_end_update(CLI_Handles *cli){
return close_me; return close_me;
} }
void
DUMP(byte *d, i32 size){
//system_save_file("DUMP", d, size);
}
internal b32 internal b32
Win32LoadAppCode(){ Win32LoadAppCode(){
b32 result = 0; b32 result = 0;
#if UseWinDll
win32vars.app_code = LoadLibraryA("4ed_app.dll"); win32vars.app_code = LoadLibraryA("4ed_app.dll");
if (win32vars.app_code){ if (win32vars.app_code){
result = 1; result = 1;
@ -982,6 +913,50 @@ Win32LoadAppCode(){
GetProcAddress(win32vars.app_code, "app_step"); 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; return result;
} }
@ -1023,6 +998,7 @@ Win32LoadSystemCode(){
win32vars.system->internal_sentinel = INTERNAL_system_sentinel; win32vars.system->internal_sentinel = INTERNAL_system_sentinel;
win32vars.system->internal_get_thread_states = INTERNAL_get_thread_states; win32vars.system->internal_get_thread_states = INTERNAL_get_thread_states;
win32vars.system->internal_debug_message = INTERNAL_system_debug_message;
} }
int int
@ -1032,6 +1008,12 @@ WinMain(HINSTANCE hInstance,
int nCmdShow){ int nCmdShow){
win32vars = {}; 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()){ if (!Win32LoadAppCode()){
// TODO(allen): Failed to load app code, serious problem. // TODO(allen): Failed to load app code, serious problem.
return 99; return 99;
@ -1048,12 +1030,6 @@ WinMain(HINSTANCE hInstance,
QueryPerformanceCounter(&lpf); QueryPerformanceCounter(&lpf);
win32vars.start_pcount = lpf.QuadPart; 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); keycode_init(&win32vars.key_codes);
#ifdef FRED_SUPER #ifdef FRED_SUPER
@ -1120,12 +1096,8 @@ WinMain(HINSTANCE hInstance,
if (!AdjustWindowRect(&window_rect, WS_OVERLAPPEDWINDOW, false)){ if (!AdjustWindowRect(&window_rect, WS_OVERLAPPEDWINDOW, false)){
// TODO(allen): non-fatal diagnostics // TODO(allen): non-fatal diagnostics
} }
#if SOFTWARE_RENDER
#define WINDOW_NAME "4coder-softrender-window"
#else
#define WINDOW_NAME "4coder-window" #define WINDOW_NAME "4coder-window"
#endif
HWND window_handle = {}; HWND window_handle = {};
window_handle = CreateWindowA( window_handle = CreateWindowA(
@ -1146,30 +1118,7 @@ WinMain(HINSTANCE hInstance,
HDC hdc = GetDC(window_handle); HDC hdc = GetDC(window_handle);
GetClientRect(window_handle, &window_rect); 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 = { static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), sizeof(PIXELFORMATDESCRIPTOR),
1, 1,
@ -1204,7 +1153,6 @@ WinMain(HINSTANCE hInstance,
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Win32Resize(window_rect.right - window_rect.left, window_rect.bottom - window_rect.top); Win32Resize(window_rect.right - window_rect.left, window_rect.bottom - window_rect.top);
#endif
LPVOID base; LPVOID base;
#if FRED_INTERNAL #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, &win32memory, &win32vars.key_codes,
win32vars.clipboard_contents, win32vars.config_api)){ win32vars.clipboard_contents, win32vars.config_api)){
return 5; return 5;
@ -1329,24 +1285,20 @@ WinMain(HINSTANCE hInstance,
b32 caps_lock = win32vars.input_data.caps_lock; b32 caps_lock = win32vars.input_data.caps_lock;
for (i32 i = 0; i < win32vars.input_data.press_count; ++i){ for (i32 i = 0; i < win32vars.input_data.press_count; ++i){
i16 keycode = win32vars.input_data.press[i].keycode; 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 = win32vars.input_data.press[i].character_no_caps_lock =
keycode_to_character_ascii(&win32vars.key_codes, keycode, translate_key(keycode, shift, 0);
shift, 0);
} }
for (i32 i = 0; i < win32vars.input_data.hold_count; ++i){ for (i32 i = 0; i < win32vars.input_data.hold_count; ++i){
i16 keycode = win32vars.input_data.hold[i].keycode; i16 keycode = win32vars.input_data.hold[i].keycode;
win32vars.input_data.hold[i].character = win32vars.input_data.hold[i].character =
keycode_to_character_ascii(&win32vars.key_codes, keycode, translate_key(keycode, shift, caps_lock);
shift, caps_lock);
win32vars.input_data.hold[i].character_no_caps_lock = win32vars.input_data.hold[i].character_no_caps_lock =
keycode_to_character_ascii(&win32vars.key_codes, keycode, translate_key(keycode, shift, 0);
shift, 0);
} }
win32vars.clipboard_contents = {}; win32vars.clipboard_contents = {};
@ -1392,13 +1344,10 @@ WinMain(HINSTANCE hInstance,
switch (result.mouse_cursor_type){ switch (result.mouse_cursor_type){
case APP_MOUSE_CURSOR_ARROW: case APP_MOUSE_CURSOR_ARROW:
SetCursor(win32vars.cursor_arrow); break; SetCursor(win32vars.cursor_arrow); break;
case APP_MOUSE_CURSOR_IBEAM: case APP_MOUSE_CURSOR_IBEAM:
SetCursor(win32vars.cursor_ibeam); break; SetCursor(win32vars.cursor_ibeam); break;
case APP_MOUSE_CURSOR_LEFTRIGHT: case APP_MOUSE_CURSOR_LEFTRIGHT:
SetCursor(win32vars.cursor_leftright); break; SetCursor(win32vars.cursor_leftright); break;
case APP_MOUSE_CURSOR_UPDOWN: case APP_MOUSE_CURSOR_UPDOWN:
SetCursor(win32vars.cursor_updown); break; SetCursor(win32vars.cursor_updown); break;
} }