starting new parser
parent
5b41098824
commit
c2206e5830
|
@ -2,41 +2,6 @@
|
|||
* Example use of customization API
|
||||
*/
|
||||
|
||||
// NOTE(allen|a3.1): NEW THINGS TO LOOK FOR:
|
||||
// mapid_user_custom - define maps other than the built in global and file maps
|
||||
//
|
||||
// inherit_map - override bindings or add new bindings in a new map with another
|
||||
//
|
||||
// set_hook - if you were using start_hook, it is still available if you use set_hook
|
||||
//
|
||||
// push_parameter - see description of parameter stack immediately below
|
||||
// clear_parameters
|
||||
// exec_command_keep_stack
|
||||
//
|
||||
// THE PARAMETER STACK:
|
||||
// In this version I have introduced a parameter stack.
|
||||
// Calls to commands through exec_command can now be parameterized
|
||||
// by first pushing parameters onto that stack. This is achieved through
|
||||
// the push_parameter. If you look at the signature for the function it
|
||||
// uses a "Dynamic" struct, but 4coder_helper.h has overrides that accept
|
||||
// ints or strings. The helper functions also take care of copying the
|
||||
// strings inline into the stack so that you don't have to maintain your copy.
|
||||
//
|
||||
// If you'd like to optimize out the extra copy it will work, just use the
|
||||
// main app.push_parameter and keep the memory of the string alive until
|
||||
// the stack is cleared.
|
||||
//
|
||||
// A call to exec_command executes the command with the current stack,
|
||||
// then clears the stack. To keep the stack use exec_command_keep_stack.
|
||||
//
|
||||
// If you would like to allocate your own memory, you can tie your memory
|
||||
// to the parameter stack by calling push_memory which takes a cmd_context and len.
|
||||
// It will return a char* to your memory block. Until you call clear_parameters
|
||||
// or exec_command the memory will remain on the stack for you to use. Memory
|
||||
// chunks on the stack are ignored by commands that use parameters, so your memory
|
||||
// will not influence the behavior of any commands.
|
||||
//
|
||||
|
||||
#include "4coder_custom.h"
|
||||
#include "4coder_helper.h"
|
||||
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
#define MDFR_CTRL 1
|
||||
#define MDFR_ALT 2
|
||||
#define MDFR_SHIFT 4
|
||||
#define MDFR_NUMPAD 8
|
||||
|
||||
// NOTE(allen): These need not be used direct
|
||||
#define MDFR_EXACT 128
|
||||
|
||||
typedef u16 Code;
|
||||
|
||||
|
@ -215,7 +219,6 @@ struct Buffer_Summary{
|
|||
int file_id;
|
||||
|
||||
int size;
|
||||
const char *data;
|
||||
|
||||
int file_name_len;
|
||||
int buffer_name_len;
|
||||
|
|
|
@ -92,34 +92,69 @@ end_map(Bind_Helper *helper){
|
|||
helper->group = 0;
|
||||
}
|
||||
|
||||
struct Bind_Target{
|
||||
short code;
|
||||
unsigned char modifiers;
|
||||
};
|
||||
|
||||
inline Bind_Target
|
||||
ekey(short code, unsigned char modifiers){
|
||||
Bind_Target target;
|
||||
target.code = code;
|
||||
target.modifiers = modifiers | MDFR_EXACT;
|
||||
return target;
|
||||
}
|
||||
|
||||
inline Bind_Target
|
||||
tkey(short code, unsigned char modifiers){
|
||||
Bind_Target target;
|
||||
target.code = code;
|
||||
target.modifiers = modifiers;
|
||||
return target;
|
||||
}
|
||||
|
||||
inline void
|
||||
bind(Bind_Helper *helper, short code, unsigned char modifiers, int cmdid){
|
||||
bind(Bind_Helper *helper, Bind_Target target, int cmdid){
|
||||
if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN;
|
||||
if (!helper->error) ++helper->group->map_begin.bind_count;
|
||||
|
||||
Binding_Unit unit;
|
||||
unit.type = unit_binding;
|
||||
unit.binding.command_id = cmdid;
|
||||
unit.binding.code = code;
|
||||
unit.binding.modifiers = modifiers;
|
||||
unit.binding.code = target.code;
|
||||
unit.binding.modifiers = target.modifiers;
|
||||
|
||||
write_unit(helper, unit);
|
||||
}
|
||||
|
||||
inline void
|
||||
bind_me(Bind_Helper *helper, short code, unsigned char modifiers, Custom_Command_Function *func){
|
||||
bind_me(Bind_Helper *helper, Bind_Target target, Custom_Command_Function *func){
|
||||
if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN;
|
||||
if (!helper->error) ++helper->group->map_begin.bind_count;
|
||||
|
||||
Binding_Unit unit;
|
||||
unit.type = unit_callback;
|
||||
unit.callback.func = func;
|
||||
unit.callback.code = code;
|
||||
unit.callback.modifiers = modifiers;
|
||||
unit.callback.code = target.code;
|
||||
unit.callback.modifiers = target.modifiers;
|
||||
|
||||
write_unit(helper, unit);
|
||||
}
|
||||
|
||||
inline void
|
||||
bind(Bind_Helper *helper, short code, unsigned char modifiers, int cmdid){
|
||||
Bind_Target target;
|
||||
target.code = tkey(code, modifiers);
|
||||
bind(helper, target, cmdid);
|
||||
}
|
||||
|
||||
inline void
|
||||
bind_me(Bind_Helper *helper, short code, unsigned char modifiers, Custom_Command_Function *func){
|
||||
Bind_Target target;
|
||||
target.code = tkey(code, modifiers);
|
||||
bind_me(helper, target, func);
|
||||
}
|
||||
|
||||
inline void
|
||||
bind_vanilla_keys(Bind_Helper *helper, int cmdid){
|
||||
bind(helper, 0, 0, cmdid);
|
||||
|
@ -130,6 +165,16 @@ bind_me_vanilla_keys(Bind_Helper *helper, Custom_Command_Function *func){
|
|||
bind_me(helper, 0, 0, func);
|
||||
}
|
||||
|
||||
inline void
|
||||
bind_vanilla_keys(Bind_Helper *helper, unsigned char modifiers, int cmdid){
|
||||
bind(helper, 0, modifiers, cmdid);
|
||||
}
|
||||
|
||||
inline void
|
||||
bind_me_vanilla_keys(Bind_Helper *helper, unsigned char modifiers, Custom_Command_Function *func){
|
||||
bind_me(helper, 0, modifiers, func);
|
||||
}
|
||||
|
||||
inline void
|
||||
inherit_map(Bind_Helper *helper, int mapid){
|
||||
if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN;
|
||||
|
|
|
@ -107,8 +107,7 @@ table_copy(Table *table_src, Table *table_dst){
|
|||
}
|
||||
}
|
||||
|
||||
// TODO(allen): File_Data not Parse_File
|
||||
struct Cpp_Parse_File{
|
||||
struct Cpp_File_Data{
|
||||
Cpp_File file;
|
||||
Cpp_Token_Stack tokens;
|
||||
String filename;
|
||||
|
@ -124,7 +123,7 @@ struct Cpp_Macro_Data{
|
|||
};
|
||||
|
||||
union Cpp_Def_Slot{
|
||||
Cpp_Parse_File file;
|
||||
Cpp_File_Data file;
|
||||
Cpp_Macro_Data macro;
|
||||
};
|
||||
|
||||
|
@ -289,13 +288,13 @@ cpp_get_memory_request(Cpp_Preproc_State *state, Cpp_Parse_Definitions *definiti
|
|||
return request;
|
||||
}
|
||||
|
||||
internal Cpp_Parse_File*
|
||||
internal Cpp_File_Data*
|
||||
cpp_get_parse_file(Cpp_Parse_Definitions *definitions, int file_index){
|
||||
return &definitions->slots[file_index].file;
|
||||
}
|
||||
|
||||
internal void
|
||||
cpp_set_parse_file(Cpp_Parse_Definitions *definitions, int file_index, Cpp_Parse_File file){
|
||||
cpp_set_parse_file(Cpp_Parse_Definitions *definitions, int file_index, Cpp_File_Data file){
|
||||
definitions->slots[file_index].file = file;
|
||||
}
|
||||
|
||||
|
@ -328,7 +327,7 @@ cpp_provide_memory(Cpp_Memory_Request request, void *memory){
|
|||
|
||||
Cpp_Parse_Definitions *definitions = request.definitions;
|
||||
int size = request.size >> 1;
|
||||
Cpp_Parse_File new_file = {};
|
||||
Cpp_File_Data new_file = {};
|
||||
new_file.tokens.tokens = (Cpp_Token*)memory;
|
||||
new_file.tokens.max_count = size / sizeof(Cpp_Token);
|
||||
new_file.file.data = ((char*)memory) + size;
|
||||
|
@ -514,7 +513,7 @@ struct Preserve_Checkpoint{
|
|||
|
||||
internal Preserve_Checkpoint
|
||||
cpp__checkpoint_preserve_write(Cpp_Parse_Definitions *definitions){
|
||||
Cpp_Parse_File *file = cpp_get_parse_file(definitions, definitions->string_file_index);
|
||||
Cpp_File_Data *file = cpp_get_parse_file(definitions, definitions->string_file_index);
|
||||
Preserve_Checkpoint check;
|
||||
check.start_write_pos = definitions->string_write_pos;
|
||||
check.start_token_count = file->tokens.count;
|
||||
|
@ -524,14 +523,14 @@ cpp__checkpoint_preserve_write(Cpp_Parse_Definitions *definitions){
|
|||
|
||||
internal void
|
||||
cpp__restore_preserve_write(Cpp_Parse_Definitions *definitions, Preserve_Checkpoint check){
|
||||
Cpp_Parse_File *file = cpp_get_parse_file(definitions, definitions->string_file_index);
|
||||
Cpp_File_Data *file = cpp_get_parse_file(definitions, definitions->string_file_index);
|
||||
definitions->string_write_pos = check.start_write_pos;
|
||||
file->tokens.count = check.start_token_count;
|
||||
}
|
||||
|
||||
internal void
|
||||
cpp__preserve_string(Cpp_Parse_Definitions *definitions, String string){
|
||||
Cpp_Parse_File *string_file = cpp_get_parse_file(definitions, definitions->string_file_index);
|
||||
Cpp_File_Data *string_file = cpp_get_parse_file(definitions, definitions->string_file_index);
|
||||
_Assert(string_file->file.size - definitions->string_write_pos >= string.size);
|
||||
copy_fast_unsafe(string_file->file.data + definitions->string_write_pos, string);
|
||||
definitions->string_write_pos += string.size;
|
||||
|
@ -539,7 +538,7 @@ cpp__preserve_string(Cpp_Parse_Definitions *definitions, String string){
|
|||
|
||||
internal Cpp_Loose_Token
|
||||
cpp__preserve_token(Cpp_Parse_Definitions *definitions, Cpp_Token token){
|
||||
Cpp_Parse_File *string_file = cpp_get_parse_file(definitions, definitions->string_file_index);
|
||||
Cpp_File_Data *string_file = cpp_get_parse_file(definitions, definitions->string_file_index);
|
||||
_Assert(string_file->tokens.count < string_file->tokens.max_count);
|
||||
Cpp_Loose_Token loose;
|
||||
loose.file_index = definitions->string_file_index;
|
||||
|
@ -552,7 +551,7 @@ cpp__preserve_token(Cpp_Parse_Definitions *definitions, Cpp_Token token){
|
|||
internal void
|
||||
cpp__preserve_string(Preserve_Checkpoint *check, Cpp_Parse_Definitions *definitions, String string){
|
||||
if (!check->out_of_memory){
|
||||
Cpp_Parse_File *string_file = cpp_get_parse_file(definitions, definitions->string_file_index);
|
||||
Cpp_File_Data *string_file = cpp_get_parse_file(definitions, definitions->string_file_index);
|
||||
if (string_file->file.size - definitions->string_write_pos >= string.size){
|
||||
copy_fast_unsafe(string_file->file.data + definitions->string_write_pos, string);
|
||||
definitions->string_write_pos += string.size;
|
||||
|
@ -567,7 +566,7 @@ internal Cpp_Loose_Token
|
|||
cpp__preserve_token(Preserve_Checkpoint *check, Cpp_Parse_Definitions *definitions, Cpp_Token token){
|
||||
Cpp_Loose_Token loose = {};
|
||||
if (!check->out_of_memory){
|
||||
Cpp_Parse_File *string_file = cpp_get_parse_file(definitions, definitions->string_file_index);
|
||||
Cpp_File_Data *string_file = cpp_get_parse_file(definitions, definitions->string_file_index);
|
||||
if (string_file->tokens.count < string_file->tokens.max_count){
|
||||
loose.file_index = definitions->string_file_index;
|
||||
loose.token_index = string_file->tokens.count;
|
||||
|
@ -913,7 +912,7 @@ cpp__preproc_normal_step_nonalloc(Cpp_Preproc_State *state, Cpp_Parse_Definition
|
|||
}
|
||||
|
||||
Cpp_Visit visit = {};
|
||||
Cpp_Parse_File visit_file;
|
||||
Cpp_File_Data visit_file;
|
||||
Cpp_Token visit_token;
|
||||
|
||||
if (expansion->out_type == EXPAN_NORMAL){
|
||||
|
@ -1353,7 +1352,7 @@ cpp__preproc_normal_step_nonalloc(Cpp_Preproc_State *state, Cpp_Parse_Definition
|
|||
bool variadic = 0;
|
||||
if (macro->param_count != 0){
|
||||
int macro_file_index = macro->file_index;
|
||||
Cpp_Parse_File file = *cpp_get_parse_file(definitions, macro_file_index);
|
||||
Cpp_File_Data file = *cpp_get_parse_file(definitions, macro_file_index);
|
||||
int i = macro->first_param_index;
|
||||
Cpp_Token token = file.tokens.tokens[i];
|
||||
for (;;){
|
||||
|
@ -1461,13 +1460,13 @@ cpp__preproc_normal_step_nonalloc(Cpp_Preproc_State *state, Cpp_Parse_Definition
|
|||
|
||||
internal int
|
||||
cpp__get_parameter_i(Cpp_Preproc_State *state, Cpp_Parse_Definitions * definitions,
|
||||
Cpp_Parse_File *macro_file, Cpp_Token token, int param_start, int param_count){
|
||||
Cpp_File_Data *macro_file, Cpp_Token token, int param_start, int param_count){
|
||||
int param_i = -1;
|
||||
if (token.type == CPP_TOKEN_IDENTIFIER){
|
||||
String token_str = make_string(macro_file->file.data + token.start, token.size);
|
||||
for (int j = 0; j < param_count; ++j){
|
||||
Cpp_Loose_Token param_loose = state->tokens.tokens[j + param_start];
|
||||
Cpp_Parse_File *file = cpp_get_parse_file(definitions, param_loose.file_index);
|
||||
Cpp_File_Data *file = cpp_get_parse_file(definitions, param_loose.file_index);
|
||||
Cpp_Token param_token = file->tokens.tokens[param_loose.token_index];
|
||||
String param_str = make_string(file->file.data + param_token.start, param_token.size);
|
||||
if (match(token_str, param_str)){
|
||||
|
@ -1486,7 +1485,7 @@ cpp__preproc_big_step_nonalloc(Cpp_Preproc_State *state, Cpp_Parse_Definitions *
|
|||
Cpp_Expansion *expansion = state->expansions + state->expansion_level;
|
||||
|
||||
Cpp_Macro_Data macro = *cpp_get_macro_data(definitions, expansion->file_index);
|
||||
Cpp_Parse_File *macro_file = cpp_get_parse_file(definitions, macro.file_index);
|
||||
Cpp_File_Data *macro_file = cpp_get_parse_file(definitions, macro.file_index);
|
||||
switch (expansion->out_type){
|
||||
case EXPAN_BIG_PROCESS_ARGS:
|
||||
{
|
||||
|
@ -1667,7 +1666,7 @@ cpp__preproc_big_step_nonalloc(Cpp_Preproc_State *state, Cpp_Parse_Definitions *
|
|||
cpp__push_loose_token(&checkpoint, state, loose.file_index, loose.token_index, loose.blocked);
|
||||
}
|
||||
Cpp_Loose_Token loose = state->tokens.tokens[j];
|
||||
Cpp_Parse_File *end_file = cpp_get_parse_file(definitions, loose.file_index);
|
||||
Cpp_File_Data *end_file = cpp_get_parse_file(definitions, loose.file_index);
|
||||
Cpp_Token end_token = end_file->tokens.tokens[loose.token_index];
|
||||
String end_string = make_string(end_file->file.data + end_token.start, end_token.size);
|
||||
cpp__spare_write(&str_checkpoint, state, end_string);
|
||||
|
@ -1683,7 +1682,7 @@ cpp__preproc_big_step_nonalloc(Cpp_Preproc_State *state, Cpp_Parse_Definitions *
|
|||
if (range.start < range.end){
|
||||
int j = range.start;
|
||||
Cpp_Loose_Token loose = state->tokens.tokens[j];
|
||||
Cpp_Parse_File *start_file = cpp_get_parse_file(definitions, loose.file_index);
|
||||
Cpp_File_Data *start_file = cpp_get_parse_file(definitions, loose.file_index);
|
||||
Cpp_Token start_token = start_file->tokens.tokens[loose.token_index];
|
||||
String start_string = make_string(start_file->file.data + start_token.start, start_token.size);
|
||||
cpp__spare_write(&str_checkpoint, state, start_string);
|
||||
|
@ -1860,7 +1859,7 @@ cpp__preproc_strfy_step_nonalloc(Cpp_Preproc_State *state, Cpp_Parse_Definitions
|
|||
Spare_String_Checkpoint checkpoint = cpp__checkpoint_spare_string(state);
|
||||
|
||||
if (do_body){
|
||||
Cpp_Parse_File visit_file;
|
||||
Cpp_File_Data visit_file;
|
||||
Cpp_Token visit_token;
|
||||
|
||||
visit_file = *cpp_get_parse_file(definitions, visit.file_index);
|
||||
|
|
37
4ed.cpp
37
4ed.cpp
|
@ -112,12 +112,9 @@ app_get_map_index(App_Vars *vars, i32 mapid){
|
|||
internal Command_Map*
|
||||
app_get_map(App_Vars *vars, i32 mapid){
|
||||
Command_Map *map = 0;
|
||||
if (mapid >= mapid_user_custom)
|
||||
map = vars->user_maps + mapid - mapid_user_custom;
|
||||
else if (mapid == mapid_global)
|
||||
map = &vars->map_top;
|
||||
else if (mapid == mapid_file)
|
||||
map = &vars->map_file;
|
||||
if (mapid >= mapid_user_custom) map = vars->user_maps + mapid - mapid_user_custom;
|
||||
else if (mapid == mapid_global) map = &vars->map_top;
|
||||
else if (mapid == mapid_file) map = &vars->map_file;
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -740,7 +737,7 @@ app_open_file(System_Functions *system,
|
|||
new_view->map = app_get_map(vars, target_file->base_map_id);
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
if (created_file && target_file->tokens_exist)
|
||||
if (created_file && target_file->tokens_exist && target_file->token_stack.tokens == 0)
|
||||
file_first_lex_parallel(system, &mem->general, target_file);
|
||||
#endif
|
||||
}
|
||||
|
@ -1690,7 +1687,6 @@ extern "C"{
|
|||
Working_Set *working_set = cmd->working_set;
|
||||
buffer.file_id = (int)(file - working_set->files);
|
||||
buffer.size = file->buffer.size;
|
||||
buffer.data = (const char*)file->buffer.data;
|
||||
buffer.file_name_len = file->source_path.size;
|
||||
buffer.buffer_name_len = file->live_name.size;
|
||||
buffer.file_name = file->source_path.str;
|
||||
|
@ -1990,7 +1986,7 @@ app_hardcode_styles(App_Vars *vars){
|
|||
styles = vars->styles.styles;
|
||||
style = styles;
|
||||
|
||||
Font *fonts = vars->fonts.fonts;
|
||||
Render_Font *fonts = vars->fonts.fonts;
|
||||
|
||||
/////////////////
|
||||
style_set_name(style, make_lit_string("4coder"));
|
||||
|
@ -2206,10 +2202,11 @@ app_hardcode_styles(App_Vars *vars){
|
|||
}
|
||||
|
||||
internal bool32
|
||||
app_load_font(System_Functions *system,
|
||||
Font *font, char *filename, i32 size, void *memory,
|
||||
app_load_font(Render_Target *target, System_Functions *system,
|
||||
Render_Font *font, char *filename, i32 size, void *memory,
|
||||
i32 *used, i32 tab_width, String name){
|
||||
if (font_load(system, font, filename, size, memory, font_predict_size(size), used, tab_width)){
|
||||
if (font_load(target, system, font, filename, size, memory,
|
||||
font_predict_size(size), used, tab_width)){
|
||||
font->loaded = 1;
|
||||
font->name_[ArrayCount(font->name_)-1] = 0;
|
||||
font->name = make_string(font->name_, 0, ArrayCount(font->name_)-1);
|
||||
|
@ -2453,45 +2450,43 @@ external App_Init_Sig(app_init){
|
|||
vars->hooks[hook_open_file] = default_open_file_hook;
|
||||
}
|
||||
|
||||
if (!font_init()) return 0;
|
||||
|
||||
vars->fonts.max = 6;
|
||||
vars->fonts.fonts = push_array(partition, Font, vars->fonts.max);
|
||||
vars->fonts.fonts = push_array(partition, Render_Font, vars->fonts.max);
|
||||
|
||||
{
|
||||
i32 font_count = 0;
|
||||
i32 memory_used;
|
||||
|
||||
memory_used = 0;
|
||||
app_load_font(system,
|
||||
app_load_font(target, system,
|
||||
vars->fonts.fonts + font_count++, "liberation-mono.ttf", 17,
|
||||
partition_current(partition),
|
||||
&memory_used, 4, make_lit_string("liberation mono"));
|
||||
push_block(partition, memory_used);
|
||||
|
||||
memory_used = 0;
|
||||
app_load_font(system,
|
||||
app_load_font(target, system,
|
||||
vars->fonts.fonts + font_count++, "LiberationSans-Regular.ttf", 17,
|
||||
partition_current(partition),
|
||||
&memory_used, 4, make_lit_string("liberation sans"));
|
||||
push_block(partition, memory_used);
|
||||
|
||||
memory_used = 0;
|
||||
app_load_font(system,
|
||||
app_load_font(target, system,
|
||||
vars->fonts.fonts + font_count++, "Hack-Regular.ttf", 17,
|
||||
partition_current(partition),
|
||||
&memory_used, 4, make_lit_string("hack"));
|
||||
push_block(partition, memory_used);
|
||||
|
||||
memory_used = 0;
|
||||
app_load_font(system,
|
||||
app_load_font(target, system,
|
||||
vars->fonts.fonts + font_count++, "CutiveMono-Regular.ttf", 17,
|
||||
partition_current(partition),
|
||||
&memory_used, 4, make_lit_string("cutive mono"));
|
||||
push_block(partition, memory_used);
|
||||
|
||||
memory_used = 0;
|
||||
app_load_font(system,
|
||||
app_load_font(target, system,
|
||||
vars->fonts.fonts + font_count++, "Inconsolata-Regular.ttf", 17,
|
||||
partition_current(partition),
|
||||
&memory_used, 4, make_lit_string("inconsolata"));
|
||||
|
@ -2502,7 +2497,7 @@ external App_Init_Sig(app_init){
|
|||
extra.size = 17;
|
||||
vars->config_api.set_extra_font(&extra);
|
||||
memory_used = 0;
|
||||
if (app_load_font(system,
|
||||
if (app_load_font(target, system,
|
||||
vars->fonts.fonts + font_count, extra.file_name, extra.size,
|
||||
partition_current(partition),
|
||||
&memory_used, 4, make_string_slowly(extra.font_name))){
|
||||
|
|
20
4ed.h
20
4ed.h
|
@ -12,23 +12,6 @@
|
|||
#ifndef FRED_H
|
||||
#define FRED_H
|
||||
|
||||
#if SOFTWARE_RENDER
|
||||
struct Render_Target{
|
||||
void *pixel_data;
|
||||
i32 width, height, pitch;
|
||||
};
|
||||
#else
|
||||
struct Render_Target{
|
||||
void *handle;
|
||||
void *context;
|
||||
i32_Rect clip_boxes[5];
|
||||
i32 clip_top;
|
||||
i32 width, height;
|
||||
i32 bound_texture;
|
||||
u32 color;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct Application_Memory{
|
||||
void *vars_memory;
|
||||
i32 vars_memory_size;
|
||||
|
@ -118,6 +101,7 @@ struct Thread_Context;
|
|||
|
||||
#define App_Init_Sig(name) \
|
||||
b32 name(System_Functions *system, \
|
||||
Render_Target *target, \
|
||||
Application_Memory *memory, \
|
||||
Key_Codes *loose_codes, \
|
||||
Clipboard_Contents clipboard, \
|
||||
|
@ -137,7 +121,7 @@ enum Application_Mouse_Cursor{
|
|||
|
||||
struct Application_Step_Result{
|
||||
Application_Mouse_Cursor mouse_cursor_type;
|
||||
b32 redraw;
|
||||
b32 redraw;
|
||||
};
|
||||
|
||||
#define App_Step_Sig(name) Application_Step_Result \
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 13.11.2014
|
||||
* 13.11.2015
|
||||
*
|
||||
* Application layer build target
|
||||
*
|
||||
|
@ -9,50 +9,7 @@
|
|||
|
||||
// TOP
|
||||
|
||||
#ifdef FRED_NOT_PACKAGE
|
||||
|
||||
#define FRED_INTERNAL 1
|
||||
#define FRED_SLOW 1
|
||||
|
||||
#define FRED_PRINT_DEBUG 1
|
||||
#define FRED_PRINT_DEBUG_FILE_LINE 0
|
||||
#define FRED_PROFILING 1
|
||||
#define FRED_PROFILING_OS 0
|
||||
#define FRED_FULL_ERRORS 0
|
||||
|
||||
#else
|
||||
|
||||
#define FRED_SLOW 0
|
||||
#define FRED_INTERNAL 0
|
||||
|
||||
#define FRED_PRINT_DEBUG 0
|
||||
#define FRED_PRINT_DEBUG_FILE_LINE 0
|
||||
#define FRED_PROFILING 0
|
||||
#define FRED_PROFILING_OS 0
|
||||
#define FRED_FULL_ERRORS 0
|
||||
|
||||
#endif
|
||||
|
||||
#define SOFTWARE_RENDER 0
|
||||
|
||||
#if FRED_INTERNAL == 0
|
||||
#undef FRED_PRINT_DEBUG
|
||||
#define FRED_PRINT_DEBUG 0
|
||||
#undef FRED_PROFILING
|
||||
#define FRED_PROFILING 0
|
||||
#undef FRED_PROFILING_OS
|
||||
#define FRED_PROFILING_OS 0
|
||||
#endif
|
||||
|
||||
#if FRED_PRINT_DEBUG == 0
|
||||
#undef FRED_PRINT_DEBUG_FILE_LINE
|
||||
#define FRED_PRINT_DEBUG_FILE_LINE 0
|
||||
#undef FRED_PRINT_DEBUG_FILE_LINE
|
||||
#define FRED_PROFILING_OS 0
|
||||
#endif
|
||||
|
||||
#define FPS 30
|
||||
#define FRAME_TIME (1000000 / FPS)
|
||||
#include "4ed_config.h"
|
||||
|
||||
#define BUFFER_EXPERIMENT_SCALPEL 0
|
||||
|
||||
|
@ -67,25 +24,15 @@
|
|||
#include "4ed_math.cpp"
|
||||
#include "4coder_custom.h"
|
||||
#include "4ed_system.h"
|
||||
#include "4ed.h"
|
||||
#include "4ed_rendering.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <windows.h>
|
||||
# include <GL/gl.h>
|
||||
#elif defined(__linux__)
|
||||
# include <SDL/SDL.h>
|
||||
# include <GL/gl.h>
|
||||
#else
|
||||
# error UNSUPPORTED PLATFORM
|
||||
#endif
|
||||
#include "4ed.h"
|
||||
|
||||
#include "4ed_internal.h"
|
||||
|
||||
#define FCPP_LEXER_IMPLEMENTATION
|
||||
#include "4cpp_lexer.h"
|
||||
|
||||
#include "4ed_rendering.cpp"
|
||||
#include "4ed_rendering_helper.cpp"
|
||||
#include "4ed_command.cpp"
|
||||
#include "4ed_layout.cpp"
|
||||
#include "4ed_style.cpp"
|
||||
|
|
|
@ -125,14 +125,14 @@ view_to_color_view(View *view){
|
|||
|
||||
internal void
|
||||
draw_gradient_slider(Render_Target *target, Vec4 base, i32 channel,
|
||||
i32 steps, real32 top, real32_Rect slider, bool32 hsla){
|
||||
i32 steps, f32 top, f32_Rect slider, b32 hsla){
|
||||
Vec4 low, high;
|
||||
real32 *lowv, *highv;
|
||||
real32 x;
|
||||
real32 next_x;
|
||||
real32 x_step;
|
||||
real32 v_step;
|
||||
real32 m;
|
||||
f32 *lowv, *highv;
|
||||
f32 x;
|
||||
f32 next_x;
|
||||
f32 x_step;
|
||||
f32 v_step;
|
||||
f32 m;
|
||||
|
||||
x = (real32)slider.x0;
|
||||
x_step = (real32)(slider.x1 - slider.x0) / steps;
|
||||
|
@ -176,21 +176,21 @@ draw_gradient_slider(Render_Target *target, Vec4 base, i32 channel,
|
|||
}
|
||||
|
||||
inline void
|
||||
draw_hsl_slider(Render_Target *target, Vec4 base, i32 channel, i32 steps, real32 top,
|
||||
real32_Rect slider){
|
||||
draw_hsl_slider(Render_Target *target, Vec4 base, i32 channel,
|
||||
i32 steps, real32 top, f32_Rect slider){
|
||||
draw_gradient_slider(target, base, channel, steps, top, slider, 1);
|
||||
}
|
||||
|
||||
inline void
|
||||
draw_rgb_slider(Render_Target *target, Vec4 base, i32 channel, i32 steps, real32 top,
|
||||
real32_Rect slider){
|
||||
draw_rgb_slider(Render_Target *target, Vec4 base, i32 channel,
|
||||
i32 steps, f32 top, f32_Rect slider){
|
||||
draw_gradient_slider(target, base, channel, steps, top, slider, 0);
|
||||
}
|
||||
|
||||
internal void
|
||||
do_label(UI_State *state, UI_Layout *layout, char *text, real32 height = 2.f){
|
||||
Style *style = state->style;
|
||||
Font *font = style->font;
|
||||
Render_Font *font = style->font;
|
||||
i32_Rect label = layout_rect(layout, FLOOR32(font->height * height));
|
||||
|
||||
if (!state->input_stage){
|
||||
|
@ -274,7 +274,6 @@ do_scroll_bar(UI_State *state, i32_Rect rect){
|
|||
get_colors(state, &back, &fore, wid, ui_style);
|
||||
draw_rectangle(target, top_arrow, back);
|
||||
draw_rectangle_outline(target, top_arrow, outline);
|
||||
draw_triangle_3corner(target, x0, y0, x1, y1, x2, y2, fore);
|
||||
|
||||
++wid.sub_id2;
|
||||
y0 = (w_2_3 + bottom_arrow.y0);
|
||||
|
@ -283,7 +282,6 @@ do_scroll_bar(UI_State *state, i32_Rect rect){
|
|||
get_colors(state, &back, &fore, wid, ui_style);
|
||||
draw_rectangle(target, bottom_arrow, back);
|
||||
draw_rectangle_outline(target, bottom_arrow, outline);
|
||||
draw_triangle_3corner(target, x0, y0, x1, y1, x2, y2, fore);
|
||||
|
||||
++wid.sub_id2;
|
||||
get_colors(state, &back, &fore, wid, ui_style);
|
||||
|
@ -295,10 +293,10 @@ do_scroll_bar(UI_State *state, i32_Rect rect){
|
|||
}
|
||||
|
||||
internal void
|
||||
do_single_slider(i32 sub_id, Color_UI *ui, i32 channel, bool32 is_rgba,
|
||||
i32 grad_steps, real32 top, real32_Rect slider, real32 v_handle,
|
||||
do_single_slider(i32 sub_id, Color_UI *ui, i32 channel, b32 is_rgba,
|
||||
i32 grad_steps, f32 top, f32_Rect slider, f32 v_handle,
|
||||
i32_Rect rect){
|
||||
real32_Rect click_box = slider;
|
||||
f32_Rect click_box = slider;
|
||||
click_box.y0 -= v_handle;
|
||||
|
||||
if (ui->state.input_stage){
|
||||
|
@ -349,7 +347,7 @@ internal void
|
|||
do_hsl_sliders(Color_UI *ui, i32_Rect rect){
|
||||
real32 bar_width = (real32)(rect.x1 - rect.x0 - 20);
|
||||
if (bar_width > 45){
|
||||
real32_Rect slider;
|
||||
f32_Rect slider;
|
||||
real32 y;
|
||||
i32 sub_id;
|
||||
|
||||
|
@ -410,7 +408,7 @@ do_channel_field(i32 sub_id, Color_UI *ui, u8 *channel, Channel_Field_Type ftype
|
|||
i32 y, u32 color, u32 back, i32 x0, i32 x1){
|
||||
bool32 result = 0;
|
||||
Render_Target *target = ui->state.target;
|
||||
Font *font = ui->state.font;
|
||||
Render_Font *font = ui->state.font;
|
||||
|
||||
i32_Rect hit_region;
|
||||
hit_region.x0 = x0;
|
||||
|
@ -509,7 +507,7 @@ do_channel_field(i32 sub_id, Color_UI *ui, u8 *channel, Channel_Field_Type ftype
|
|||
}
|
||||
}
|
||||
else{
|
||||
real32_Rect r = f32R(hit_region);
|
||||
f32_Rect r = f32R(hit_region);
|
||||
r.x0 += indx*ui->hex_advance+1;
|
||||
r.x1 = r.x0+ui->hex_advance+1;
|
||||
draw_rectangle(target, r, back);
|
||||
|
@ -537,8 +535,8 @@ do_rgb_sliders(Color_UI *ui, i32_Rect rect){
|
|||
rect.x0 = hex_x1;
|
||||
real32 bar_width = (real32)(rect.x1 - rect.x0 - 20);
|
||||
|
||||
real32_Rect slider;
|
||||
real32 y;
|
||||
f32_Rect slider;
|
||||
f32 y;
|
||||
i32 sub_id;
|
||||
u8 channel;
|
||||
|
||||
|
@ -603,7 +601,7 @@ begin_layout(Blob_Layout *layout, i32_Rect rect){
|
|||
internal void
|
||||
do_blob(Color_UI *ui, Blob_Layout *layout, u32 color, bool32 *set_me, i32 sub_id){
|
||||
i32_Rect rect = layout->rect;
|
||||
real32_Rect blob;
|
||||
f32_Rect blob;
|
||||
blob.x0 = (real32)layout->x;
|
||||
blob.y0 = (real32)layout->y;
|
||||
blob.x1 = blob.x0 + layout->size;
|
||||
|
@ -690,7 +688,7 @@ do_palette(Color_UI *ui, i32_Rect rect){
|
|||
|
||||
if (!ui->state.input_stage){
|
||||
Render_Target *target = ui->state.target;
|
||||
Font *font = style->font;
|
||||
Render_Font *font = style->font;
|
||||
draw_string(target, font, "Global Palette: right click to save color",
|
||||
layout.x, layout.rect.y0, style->main.default_color);
|
||||
}
|
||||
|
@ -711,7 +709,7 @@ do_palette(Color_UI *ui, i32_Rect rect){
|
|||
|
||||
internal void
|
||||
do_sub_button(i32 id, Color_UI *ui, char *text){
|
||||
Font *font = ui->state.font;
|
||||
Render_Font *font = ui->state.font;
|
||||
|
||||
i32_Rect rect = layout_rect(&ui->layout, font->height + 2);
|
||||
|
||||
|
@ -743,7 +741,7 @@ do_color_adjuster(Color_UI *ui, u32 *color,
|
|||
u32 text_color, u32 back_color, char *name){
|
||||
i32 id = raw_ptr_dif(color, ui->state.style);
|
||||
Render_Target *target = ui->state.target;
|
||||
Font *font = ui->state.font;
|
||||
Render_Font *font = ui->state.font;
|
||||
i32 character_h = font->height;
|
||||
u32 text = 0, back = 0;
|
||||
|
||||
|
@ -832,7 +830,7 @@ do_color_adjuster(Color_UI *ui, u32 *color,
|
|||
internal void
|
||||
do_style_name(Color_UI *ui){
|
||||
i32 id = -3;
|
||||
Font *font = ui->state.font;
|
||||
Render_Font *font = ui->state.font;
|
||||
|
||||
i32_Rect srect = layout_rect(&ui->layout, font->height);
|
||||
|
||||
|
@ -878,7 +876,7 @@ do_style_name(Color_UI *ui){
|
|||
}
|
||||
|
||||
internal bool32
|
||||
do_font_option(Color_UI *ui, Font *font){
|
||||
do_font_option(Color_UI *ui, Render_Font *font){
|
||||
bool32 result = 0;
|
||||
i32 sub_id = (i32)(font);
|
||||
i32_Rect orect = layout_rect(&ui->layout, font->height);
|
||||
|
@ -915,7 +913,7 @@ internal void
|
|||
do_font_switch(Color_UI *ui){
|
||||
i32 id = -2;
|
||||
Render_Target *target = ui->state.target;
|
||||
Font *font = ui->state.font;
|
||||
Render_Font *font = ui->state.font;
|
||||
i32 character_h = font->height;
|
||||
|
||||
i32_Rect srect = layout_rect(&ui->layout, character_h);
|
||||
|
@ -946,7 +944,7 @@ do_font_switch(Color_UI *ui){
|
|||
|
||||
if (is_selected(&ui->state, wid)){
|
||||
Font_Set *fonts = ui->fonts;
|
||||
Font *font_opt = fonts->fonts;
|
||||
Render_Font *font_opt = fonts->fonts;
|
||||
i32 count = fonts->count;
|
||||
srect = layout_rect(&ui->layout, character_h/2);
|
||||
if (!ui->state.input_stage)
|
||||
|
@ -1188,7 +1186,7 @@ update_highlighting(Color_View *color_view){
|
|||
internal bool32
|
||||
do_style_preview(Library_UI *ui, Style *style, i32 toggle = -1){
|
||||
bool32 result = 0;
|
||||
Font *font = style->font;
|
||||
Render_Font *font = style->font;
|
||||
i32 id;
|
||||
if (style == ui->state.style) id = 2;
|
||||
else id = raw_ptr_dif(style, ui->styles->styles) + 100;
|
||||
|
@ -1275,7 +1273,7 @@ internal bool32
|
|||
do_main_file_box(System_Functions *system, UI_State *state, UI_Layout *layout, Hot_Directory *hot_directory, char *end = 0){
|
||||
bool32 result = 0;
|
||||
Style *style = state->style;
|
||||
Font *font = style->font;
|
||||
Render_Font *font = style->font;
|
||||
i32_Rect box = layout_rect(layout, font->height + 2);
|
||||
String *string = &hot_directory->string;
|
||||
|
||||
|
@ -1303,7 +1301,7 @@ internal bool32
|
|||
do_main_string_box(System_Functions *system, UI_State *state, UI_Layout *layout, String *string){
|
||||
bool32 result = 0;
|
||||
Style *style = state->style;
|
||||
Font *font = style->font;
|
||||
Render_Font *font = style->font;
|
||||
i32_Rect box = layout_rect(layout, font->height + 2);
|
||||
|
||||
if (state->input_stage){
|
||||
|
@ -1328,7 +1326,7 @@ internal bool32
|
|||
do_list_option(i32 id, UI_State *state, UI_Layout *layout, String text){
|
||||
bool32 result = 0;
|
||||
Style *style = state->style;
|
||||
Font *font = style->font;
|
||||
Render_Font *font = style->font;
|
||||
i32 character_h = font->height;
|
||||
|
||||
i32_Rect box = layout_rect(layout, font->height*2);
|
||||
|
@ -1365,7 +1363,7 @@ internal bool32
|
|||
do_file_option(i32 id, UI_State *state, UI_Layout *layout, String filename, bool32 is_folder, String extra){
|
||||
bool32 result = 0;
|
||||
Style *style = state->style;
|
||||
Font *font = style->font;
|
||||
Render_Font *font = style->font;
|
||||
i32 character_h = font->height;
|
||||
|
||||
i32_Rect box = layout_rect(layout, font->height*2);
|
||||
|
|
|
@ -9,8 +9,12 @@
|
|||
|
||||
// TOP
|
||||
|
||||
typedef void (*Command_Function)(System_Functions *system,
|
||||
struct Command_Data *command, struct Command_Binding binding);
|
||||
#define Command_Function_Sig(name) void (name)( \
|
||||
System_Functions *system, \
|
||||
struct Command_Data *command, \
|
||||
struct Command_Binding binding)
|
||||
|
||||
typedef Command_Function_Sig(*Command_Function);
|
||||
|
||||
struct Command_Binding{
|
||||
Command_Function function;
|
||||
|
@ -29,12 +33,13 @@ internal void command_null(Command_Data *command);
|
|||
|
||||
internal i64
|
||||
map_hash(u16 event_code, u8 modifiers){
|
||||
i64 result = (event_code << 4) | modifiers;
|
||||
i64 result = (event_code << 8) | modifiers;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal b32
|
||||
map_add(Command_Map *map, u16 event_code, u8 modifiers, Command_Function function, Custom_Command_Function *custom = 0){
|
||||
map_add(Command_Map *map, u16 event_code, u8 modifiers, Command_Function function,
|
||||
Custom_Command_Function *custom = 0){
|
||||
Assert(map->count * 8 < map->max * 7);
|
||||
Command_Binding bind;
|
||||
bind.function = function;
|
||||
|
@ -115,21 +120,33 @@ internal Command_Binding
|
|||
map_extract(Command_Map *map, Key_Single key){
|
||||
Command_Binding bind = {};
|
||||
|
||||
u8 command = MDFR_NONE;
|
||||
b32 ctrl = key.modifiers[CONTROL_KEY_CONTROL];
|
||||
b32 alt = key.modifiers[CONTROL_KEY_ALT];
|
||||
b32 shift = key.modifiers[CONTROL_KEY_SHIFT] && key.key.loose_keycode;
|
||||
u16 code;
|
||||
u8 command = MDFR_NONE;
|
||||
|
||||
if (shift) command |= MDFR_SHIFT;
|
||||
if (ctrl) command |= MDFR_CTRL;
|
||||
if (alt) command |= MDFR_ALT;
|
||||
|
||||
u16 code = key.key.character_no_caps_lock;
|
||||
if (code == 0) code = key.key.keycode;
|
||||
command |= MDFR_EXACT;
|
||||
code = key.key.keycode;
|
||||
map_find(map, code, command, &bind);
|
||||
|
||||
if (bind.function == 0 && key.key.character_no_caps_lock != 0){
|
||||
map_get_vanilla_keyboard_default(map, command, &bind);
|
||||
command &= ~(MDFR_EXACT);
|
||||
code = key.key.character_no_caps_lock;
|
||||
if (code == 0){
|
||||
code = key.key.keycode;
|
||||
map_find(map, code, command, &bind);
|
||||
}
|
||||
else{
|
||||
command &= ~(MDFR_SHIFT);
|
||||
|
||||
map_find(map, code, command, &bind);
|
||||
if (bind.function == 0){
|
||||
map_get_vanilla_keyboard_default(map, command, &bind);
|
||||
}
|
||||
}
|
||||
|
||||
return bind;
|
||||
|
|
|
@ -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
|
|
@ -23,7 +23,7 @@ struct Dbg_Past_Key{
|
|||
|
||||
struct Debug_View{
|
||||
View view_base;
|
||||
Font *font;
|
||||
Render_Font *font;
|
||||
Debug_Mode mode;
|
||||
Dbg_Past_Key past_keys[32];
|
||||
i32 past_key_count, past_key_pos;
|
||||
|
@ -38,7 +38,7 @@ view_to_debug_view(View *view){
|
|||
|
||||
internal i32
|
||||
draw_general_memory(Debug_View *view, i32_Rect rect, Render_Target *target, i32 y){
|
||||
Font *font = view->font;
|
||||
Render_Font *font = view->font;
|
||||
i32 y_advance = font->height;
|
||||
Bubble *sentinel = &view->view_base.mem->general.sentinel;
|
||||
|
||||
|
@ -94,7 +94,7 @@ draw_general_memory(Debug_View *view, i32_Rect rect, Render_Target *target, i32
|
|||
|
||||
internal i32
|
||||
draw_system_memory(System_Functions *system, Debug_View *view, i32_Rect rect, Render_Target *target, i32 y){
|
||||
Font *font = view->font;
|
||||
Render_Font *font = view->font;
|
||||
i32 y_advance = font->height;
|
||||
Bubble *sentinel = system->internal_sentinel();
|
||||
|
||||
|
@ -182,7 +182,7 @@ draw_modifiers(Debug_View *view, Render_Target *target,
|
|||
internal i32
|
||||
draw_key_event(Debug_View *view, Render_Target *target,
|
||||
Dbg_Past_Key *key, i32 x, i32 y, u32 on_color, u32 off_color){
|
||||
Font *font = view->font;
|
||||
Render_Font *font = view->font;
|
||||
draw_modifiers(view, target, key->modifiers,
|
||||
on_color, off_color, &x, y);
|
||||
|
||||
|
@ -213,7 +213,7 @@ draw_os_events(Debug_View *view, i32_Rect rect, Render_Target *target,
|
|||
x = rect.x0;
|
||||
y = rect.y0;
|
||||
|
||||
Font *font = view->font;
|
||||
Render_Font *font = view->font;
|
||||
|
||||
draw_modifiers(view, target, active_input->keys.modifiers,
|
||||
0xFFFFFFFF, 0xFF444444, &x, y);
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -87,7 +87,7 @@ struct Undo_Data{
|
|||
|
||||
struct Editing_File{
|
||||
Buffer_Type buffer;
|
||||
Font *font;
|
||||
Render_Font *font;
|
||||
|
||||
i32 cursor_pos;
|
||||
b32 is_dummy;
|
||||
|
@ -558,7 +558,7 @@ widget_match(Widget_ID s1, Widget_ID s2){
|
|||
struct UI_State{
|
||||
Render_Target *target;
|
||||
Style *style;
|
||||
Font *font;
|
||||
Render_Font *font;
|
||||
Mouse_Summary *mouse;
|
||||
Key_Summary *keys;
|
||||
Key_Codes *codes;
|
||||
|
@ -983,7 +983,7 @@ internal bool32
|
|||
do_text_field(Widget_ID wid, UI_State *state, UI_Layout *layout,
|
||||
String prompt, String dest){
|
||||
bool32 result = 0;
|
||||
Font *font = state->font;
|
||||
Render_Font *font = state->font;
|
||||
i32 character_h = font->height;
|
||||
|
||||
i32_Rect rect = layout_rect(layout, character_h);
|
||||
|
@ -1231,7 +1231,7 @@ file_grow_starts_as_needed(General_Memory *general, Buffer_Type *buffer, i32 add
|
|||
|
||||
internal void
|
||||
file_measure_starts_widths(System_Functions *system,
|
||||
General_Memory *general, Buffer_Type *buffer, Font *font){
|
||||
General_Memory *general, Buffer_Type *buffer, Render_Font *font){
|
||||
ProfileMomentFunction();
|
||||
if (!buffer->line_starts){
|
||||
i32 max = buffer->line_max = Kbytes(1);
|
||||
|
@ -1331,7 +1331,7 @@ struct Opaque_Font_Advance{
|
|||
};
|
||||
|
||||
inline Opaque_Font_Advance
|
||||
get_opaque_font_advance(Font *font){
|
||||
get_opaque_font_advance(Render_Font *font){
|
||||
Opaque_Font_Advance result;
|
||||
result.data = (char*)font->chardata + OffsetOfPtr(font->chardata, xadvance);
|
||||
result.stride = sizeof(*font->chardata);
|
||||
|
@ -1373,7 +1373,7 @@ file_measure_widths(General_Memory *general, Buffer_Type *buffer, Font *font){
|
|||
|
||||
internal void
|
||||
file_remeasure_widths(System_Functions *system,
|
||||
General_Memory *general, Buffer_Type *buffer, Font *font,
|
||||
General_Memory *general, Buffer_Type *buffer, Render_Font *font,
|
||||
i32 line_start, i32 line_end, i32 line_shift){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
ProfileMomentFunction();
|
||||
|
@ -1400,7 +1400,7 @@ view_compute_lowest_line(File_View *view){
|
|||
}
|
||||
else{
|
||||
Style *style = view->style;
|
||||
Font *font = style->font;
|
||||
Render_Font *font = style->font;
|
||||
real32 wrap_y = view->line_wrap_y[last_line];
|
||||
lowest_line = FLOOR32(wrap_y / font->height);
|
||||
f32 max_width = view_compute_width(view);
|
||||
|
@ -1438,9 +1438,9 @@ view_measure_wraps(System_Functions *system,
|
|||
}
|
||||
}
|
||||
|
||||
Font *font = view->style->font;
|
||||
real32 line_height = (real32)font->height;
|
||||
real32 max_width = view_compute_width(view);
|
||||
Render_Font *font = view->style->font;
|
||||
f32 line_height = (f32)font->height;
|
||||
f32 max_width = view_compute_width(view);
|
||||
buffer_measure_wrap_y(buffer, view->line_wrap_y, line_height, max_width);
|
||||
|
||||
view->line_count = line_count;
|
||||
|
@ -1456,7 +1456,8 @@ alloc_for_buffer(void *context, int *size){
|
|||
|
||||
internal void
|
||||
file_create_from_string(System_Functions *system,
|
||||
Mem_Options *mem, Editing_File *file, char *filename, Font *font, String val, b32 super_locked = 0){
|
||||
Mem_Options *mem, Editing_File *file, char *filename,
|
||||
Render_Font *font, String val, b32 super_locked = 0){
|
||||
*file = {};
|
||||
General_Memory *general = &mem->general;
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
|
@ -1517,10 +1518,11 @@ file_create_from_string(System_Functions *system,
|
|||
}
|
||||
|
||||
internal bool32
|
||||
file_create(System_Functions *system, Mem_Options *mem, Editing_File *file, char *filename, Font *font){
|
||||
file_create(System_Functions *system, Mem_Options *mem, Editing_File *file,
|
||||
char *filename, Render_Font *font){
|
||||
bool32 result = 0;
|
||||
|
||||
File_Data raw_file = system->load_file(filename);
|
||||
Data raw_file = system->load_file(filename);
|
||||
if (raw_file.data){
|
||||
result = 1;
|
||||
String val = make_string((char*)raw_file.data, raw_file.size);
|
||||
|
@ -1532,7 +1534,8 @@ file_create(System_Functions *system, Mem_Options *mem, Editing_File *file, char
|
|||
}
|
||||
|
||||
internal b32
|
||||
file_create_empty(System_Functions *system, Mem_Options *mem, Editing_File *file, char *filename, Font *font){
|
||||
file_create_empty(System_Functions *system, Mem_Options *mem, Editing_File *file,
|
||||
char *filename, Render_Font *font){
|
||||
b32 result = 1;
|
||||
String empty_str = {};
|
||||
file_create_from_string(system, mem, file, filename, font, empty_str);
|
||||
|
@ -1540,7 +1543,8 @@ file_create_empty(System_Functions *system, Mem_Options *mem, Editing_File *file
|
|||
}
|
||||
|
||||
internal b32
|
||||
file_create_super_locked(System_Functions *system, Mem_Options *mem, Editing_File *file, char *filename, Font *font){
|
||||
file_create_super_locked(System_Functions *system, Mem_Options *mem, Editing_File *file,
|
||||
char *filename, Render_Font *font){
|
||||
b32 result = 1;
|
||||
String empty_str = {};
|
||||
file_create_from_string(system, mem, file, filename, font, empty_str, 1);
|
||||
|
@ -1617,7 +1621,7 @@ struct Shift_Information{
|
|||
i32 start, end, amount;
|
||||
};
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
#if 0 //BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
internal
|
||||
Job_Callback(job_full_lex){
|
||||
Editing_File *file = (Editing_File*)data[0];
|
||||
|
@ -1680,6 +1684,83 @@ Job_Callback(job_full_lex){
|
|||
file->tokens_complete = 1;
|
||||
file->still_lexing = 0;
|
||||
}
|
||||
#else
|
||||
|
||||
internal void
|
||||
system_grow_memory(System_Functions *system, Data *memory){
|
||||
byte *old = memory->data;
|
||||
i32 new_size = memory->size * 2;
|
||||
memory->data = (byte*)system->get_memory(new_size);
|
||||
memcpy(memory->data, old, memory->size);
|
||||
system->free_memory(old);
|
||||
memory->size = new_size;
|
||||
}
|
||||
|
||||
internal void
|
||||
full_lex(System_Functions *system, Editing_File *file, General_Memory *general){
|
||||
Cpp_File cpp_file;
|
||||
cpp_file.data = file->buffer.data;
|
||||
cpp_file.size = file->buffer.size;
|
||||
|
||||
Data memory_;
|
||||
memory_.size = 64 << 10;
|
||||
memory_.data = (byte*)system->get_memory(memory_.size);
|
||||
|
||||
Data *memory = &memory_;
|
||||
|
||||
Cpp_Token_Stack tokens;
|
||||
tokens.tokens = (Cpp_Token*)memory->data;
|
||||
tokens.max_count = memory->size / sizeof(Cpp_Token);
|
||||
tokens.count = 0;
|
||||
|
||||
Cpp_Lex_Data status;
|
||||
status = cpp_lex_file_nonalloc(cpp_file, &tokens);
|
||||
while (!status.complete){
|
||||
//system->grow_thread_memory(memory);
|
||||
system_grow_memory(system, memory);
|
||||
tokens.tokens = (Cpp_Token*)memory->data;
|
||||
tokens.max_count = memory->size / sizeof(Cpp_Token);
|
||||
status = cpp_lex_file_nonalloc(cpp_file, &tokens, status);
|
||||
}
|
||||
|
||||
i32 new_max = LargeRoundUp(tokens.count, Kbytes(1));
|
||||
if (file->token_stack.tokens){
|
||||
file->token_stack.tokens = (Cpp_Token*)
|
||||
general_memory_reallocate_nocopy(general, file->token_stack.tokens, new_max*sizeof(Cpp_Token), BUBBLE_TOKENS);
|
||||
}
|
||||
else{
|
||||
file->token_stack.tokens = (Cpp_Token*)
|
||||
general_memory_allocate(general, new_max*sizeof(Cpp_Token), BUBBLE_TOKENS);
|
||||
}
|
||||
|
||||
i32 copy_amount = Kbytes(8);
|
||||
i32 uncoppied = tokens.count*sizeof(Cpp_Token);
|
||||
if (copy_amount > uncoppied) copy_amount = uncoppied;
|
||||
|
||||
u8 *dest = (u8*)file->token_stack.tokens;
|
||||
u8 *src = (u8*)tokens.tokens;
|
||||
|
||||
while (uncoppied > 0){
|
||||
memcpy(dest, src, copy_amount);
|
||||
dest += copy_amount;
|
||||
src += copy_amount;
|
||||
uncoppied -= copy_amount;
|
||||
if (copy_amount > uncoppied) copy_amount = uncoppied;
|
||||
}
|
||||
|
||||
file->token_stack.count = tokens.count;
|
||||
file->token_stack.max_count = new_max;
|
||||
system->force_redraw();
|
||||
|
||||
// NOTE(allen): These are outside the locked section because I don't
|
||||
// think getting these out of order will cause critical bugs, and I
|
||||
// want to minimize what's done in locked sections.
|
||||
file->tokens_complete = 1;
|
||||
file->still_lexing = 0;
|
||||
|
||||
system->free_memory(memory_.data);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
internal void
|
||||
|
@ -1705,13 +1786,17 @@ file_first_lex_parallel(System_Functions *system,
|
|||
file->tokens_complete = 0;
|
||||
file->tokens_exist = 1;
|
||||
file->still_lexing = 1;
|
||||
|
||||
full_lex(system, file, general);
|
||||
|
||||
#if 0
|
||||
Job_Data job;
|
||||
job.callback = job_full_lex;
|
||||
job.data[0] = file;
|
||||
job.data[1] = general;
|
||||
job.memory_request = Kbytes(64);
|
||||
file->lex_job = system->post_job(BACKGROUND_THREADS, job);
|
||||
#endif
|
||||
}
|
||||
|
||||
internal void
|
||||
|
@ -1790,13 +1875,17 @@ file_relex_parallel(System_Functions *system,
|
|||
}
|
||||
|
||||
file->still_lexing = 1;
|
||||
|
||||
full_lex(system, file, general);
|
||||
|
||||
#if 0
|
||||
Job_Data job;
|
||||
job.callback = job_full_lex;
|
||||
job.data[0] = file;
|
||||
job.data[1] = general;
|
||||
job.memory_request = Kbytes(64);
|
||||
file->lex_job = system->post_job(BACKGROUND_THREADS, job);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -2093,7 +2182,7 @@ view_compute_cursor_from_pos(File_View *view, i32 pos){
|
|||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
Editing_File *file = view->file;
|
||||
Style *style = view->style;
|
||||
Font *font = style->font;
|
||||
Render_Font *font = style->font;
|
||||
|
||||
real32 max_width = view_compute_width(view);
|
||||
|
||||
|
@ -2110,7 +2199,7 @@ view_compute_cursor_from_unwrapped_xy(File_View *view, real32 seek_x, real32 see
|
|||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
Editing_File *file = view->file;
|
||||
Style *style = view->style;
|
||||
Font *font = style->font;
|
||||
Render_Font *font = style->font;
|
||||
|
||||
real32 max_width = view_compute_width(view);
|
||||
|
||||
|
@ -2127,7 +2216,7 @@ view_compute_cursor_from_wrapped_xy(File_View *view, real32 seek_x, real32 seek_
|
|||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
Editing_File *file = view->file;
|
||||
Style *style = view->style;
|
||||
Font *font = style->font;
|
||||
Render_Font *font = style->font;
|
||||
|
||||
real32 max_width = view_compute_width(view);
|
||||
|
||||
|
@ -2207,7 +2296,7 @@ view_set_file(System_Functions *system,
|
|||
view->locked = file->super_locked;
|
||||
|
||||
General_Memory *general = &view->view_base.mem->general;
|
||||
Font *font = style->font;
|
||||
Render_Font *font = style->font;
|
||||
view->style = style;
|
||||
view->font_advance = font->advance;
|
||||
view->font_height = font->height;
|
||||
|
@ -2313,7 +2402,7 @@ view_set_widget(File_View *view, File_View_Widget_Type type){
|
|||
}
|
||||
|
||||
inline i32
|
||||
view_widget_height(File_View *view, Font *font){
|
||||
view_widget_height(File_View *view, Render_Font *font){
|
||||
i32 result = 0;
|
||||
switch (view->widget.type){
|
||||
case FWIDG_NONE: break;
|
||||
|
@ -2325,7 +2414,7 @@ view_widget_height(File_View *view, Font *font){
|
|||
}
|
||||
|
||||
inline i32_Rect
|
||||
view_widget_rect(File_View *view, Font *font){
|
||||
view_widget_rect(File_View *view, Render_Font *font){
|
||||
Panel *panel = view->view_base.panel;
|
||||
i32_Rect whole = panel->inner;
|
||||
i32_Rect result;
|
||||
|
@ -3530,7 +3619,7 @@ internal bool32
|
|||
do_button(i32 id, UI_State *state, UI_Layout *layout, char *text, i32 height_mult,
|
||||
bool32 is_toggle = 0, bool32 on = 0){
|
||||
bool32 result = 0;
|
||||
Font *font = state->font;
|
||||
Render_Font *font = state->font;
|
||||
i32 character_h = font->height;
|
||||
|
||||
i32_Rect btn_rect = layout_rect(layout, character_h * height_mult);
|
||||
|
@ -3578,7 +3667,7 @@ do_button(i32 id, UI_State *state, UI_Layout *layout, char *text, i32 height_mul
|
|||
internal bool32
|
||||
do_undo_slider(Widget_ID wid, UI_State *state, UI_Layout *layout, i32 max, i32 v, Undo_Data *undo, i32 *out){
|
||||
bool32 result = 0;
|
||||
Font *font = state->font;
|
||||
Render_Font *font = state->font;
|
||||
i32 character_h = font->height;
|
||||
|
||||
i32_Rect containing_rect = layout_rect(layout, character_h);
|
||||
|
@ -3630,7 +3719,7 @@ do_undo_slider(Widget_ID wid, UI_State *state, UI_Layout *layout, i32 max, i32 v
|
|||
}
|
||||
|
||||
if (show_ticks){
|
||||
real32_Rect tick;
|
||||
f32_Rect tick;
|
||||
tick.x0 = (real32)click_rect.x0 - 1;
|
||||
tick.x1 = (real32)click_rect.x0 + 1;
|
||||
tick.y0 = (real32)bar_top - 3;
|
||||
|
@ -3684,7 +3773,7 @@ do_undo_slider(Widget_ID wid, UI_State *state, UI_Layout *layout, i32 max, i32 v
|
|||
}
|
||||
|
||||
if (show_ticks){
|
||||
real32_Rect tick;
|
||||
f32_Rect tick;
|
||||
tick.x0 = (real32)click_rect.x0 - 1;
|
||||
tick.x1 = (real32)click_rect.x0 + 1;
|
||||
tick.y0 = (real32)bar_top - 3;
|
||||
|
@ -3727,7 +3816,7 @@ step_file_view(System_Functions *system, View *view_, i32_Rect rect,
|
|||
File_View *view = (File_View*)view_;
|
||||
Editing_File *file = view->file;
|
||||
Style *style = view->style;
|
||||
Font *font = style->font;
|
||||
Render_Font *font = style->font;
|
||||
|
||||
f32 line_height = (f32)font->height;
|
||||
f32 cursor_y = view_get_cursor_y(view);
|
||||
|
@ -3949,7 +4038,7 @@ draw_file_view(View *view_, i32_Rect rect, bool32 is_active,
|
|||
File_View *view = (File_View*)view_;
|
||||
Editing_File *file = view->file;
|
||||
Style *style = view->style;
|
||||
Font *font = style->font;
|
||||
Render_Font *font = style->font;
|
||||
|
||||
Interactive_Bar bar;
|
||||
bar.style = style->main.file_info_style;
|
||||
|
@ -4097,7 +4186,7 @@ draw_file_view(View *view_, i32_Rect rect, bool32 is_active,
|
|||
if (view->widget.type != FWIDG_NONE){
|
||||
UI_Style ui_style = get_ui_style_upper(style);
|
||||
|
||||
Font *font = style->font;
|
||||
Render_Font *font = style->font;
|
||||
i32_Rect widg_rect = view_widget_rect(view, font);
|
||||
|
||||
draw_rectangle(target, widg_rect, ui_style.dark);
|
||||
|
@ -4338,7 +4427,7 @@ HANDLE_COMMAND_SIG(handle_command_file_view){
|
|||
|
||||
if (result.hit_newline || result.hit_ctrl_newline){
|
||||
i32 line_number = str_to_int(*string);
|
||||
Font *font = file_view->style->font;
|
||||
Render_Font *font = file_view->style->font;
|
||||
if (line_number < 1) line_number = 1;
|
||||
file_view->cursor =
|
||||
view_compute_cursor_from_unwrapped_xy(file_view, 0, (real32)(line_number-1)*font->height);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 12.17.2014
|
||||
* 16.11.2014
|
||||
*
|
||||
* Win32-US Keyboard layer for 4coder
|
||||
*
|
||||
|
@ -13,90 +13,27 @@ globalvar u16 keycode_lookup_table[255];
|
|||
globalvar u16 loose_keycode_lookup_table[255];
|
||||
|
||||
internal void
|
||||
keycode_init(Key_Codes *codes){
|
||||
// NOTE(allen): Assign values to the global keycodes.
|
||||
// Skip over the ascii characters that are used as codes.
|
||||
u16 code = 1, loose;
|
||||
set_dynamic_key_names(Key_Codes *codes){
|
||||
u16 code = 1;
|
||||
u16 *codes_array = (u16*)codes;
|
||||
for (i32 i = 0; i < sizeof(Key_Codes)/2;){
|
||||
for (i32 i = 0; i < sizeof(*codes)/sizeof(codes->up);){
|
||||
switch (code){
|
||||
case '\n': code++; break;
|
||||
case '\t': code++; break;
|
||||
case 0x20: code = 0x7F; break;
|
||||
|
||||
default:
|
||||
codes_array[i++] = code++;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(allen): lookup table for conversion from
|
||||
// win32 vk values to fred_keycode values.
|
||||
for (u8 i = 0; i < 255; ++i){
|
||||
if ((i >= '0' && i <= '9') ||
|
||||
(i >= 'A' && i <= 'Z')){
|
||||
keycode_lookup_table[i] = i;
|
||||
loose_keycode_lookup_table[i] = 0;
|
||||
}
|
||||
else{
|
||||
loose = 0;
|
||||
switch (i){
|
||||
case VK_SPACE: code = loose = ' '; break;
|
||||
case VK_BACK: code = loose = codes->back; break;
|
||||
case VK_OEM_MINUS: code = '-'; break;
|
||||
case VK_OEM_PLUS: code = '='; break;
|
||||
case VK_SUBTRACT: code = '-'; break;
|
||||
case VK_ADD: code = '+'; break;
|
||||
case VK_MULTIPLY: code = '*'; break;
|
||||
case VK_DIVIDE: code = '/'; break;
|
||||
|
||||
case VK_OEM_3: code = '`'; break;
|
||||
case VK_OEM_5: code = '\\'; break;
|
||||
case VK_OEM_4: code = '['; break;
|
||||
case VK_OEM_6: code = ']'; break;
|
||||
case VK_TAB: code = loose = '\t'; break;
|
||||
case VK_RETURN: code = loose = '\n'; break;
|
||||
case VK_OEM_7: code = '\''; break;
|
||||
|
||||
case VK_OEM_1: code = ';'; break;
|
||||
case VK_OEM_2: code = '/'; break;
|
||||
case VK_OEM_PERIOD: code = '.'; break;
|
||||
case VK_OEM_COMMA: code = ','; break;
|
||||
case VK_UP: code = loose = codes->up; break;
|
||||
case VK_DOWN: code = loose = codes->down; break;
|
||||
case VK_LEFT: code = loose = codes->left; break;
|
||||
case VK_RIGHT: code = loose = codes->right; break;
|
||||
case VK_DELETE: code = loose = codes->del; break;
|
||||
|
||||
case VK_INSERT: code = loose = codes->insert; break;
|
||||
case VK_HOME: code = loose = codes->home; break;
|
||||
case VK_END: code = loose = codes->end; break;
|
||||
case VK_PRIOR: code = loose = codes->page_up; break;
|
||||
case VK_NEXT: code = loose = codes->page_down; break;
|
||||
case VK_ESCAPE: code = loose = codes->esc; break;
|
||||
|
||||
case VK_NUMPAD0:
|
||||
case VK_NUMPAD1: case VK_NUMPAD2: case VK_NUMPAD3:
|
||||
case VK_NUMPAD4: case VK_NUMPAD5: case VK_NUMPAD6:
|
||||
case VK_NUMPAD7: case VK_NUMPAD8: case VK_NUMPAD9:
|
||||
code = (i - VK_NUMPAD0) + '0'; break;
|
||||
|
||||
default: code = 0; break;
|
||||
}
|
||||
|
||||
keycode_lookup_table[i] = code;
|
||||
loose_keycode_lookup_table[i] = loose;
|
||||
}
|
||||
codes_array[i++] = code++;
|
||||
}
|
||||
}
|
||||
|
||||
inline u16
|
||||
keycode_lookup(u8 virtual_keycode){
|
||||
return keycode_lookup_table[virtual_keycode];
|
||||
keycode_lookup(u8 system_code){
|
||||
return keycode_lookup_table[system_code];
|
||||
}
|
||||
|
||||
inline u16
|
||||
loose_keycode_lookup(u8 virtual_keycode){
|
||||
return loose_keycode_lookup_table[virtual_keycode];
|
||||
loose_keycode_lookup(u8 system_code){
|
||||
return loose_keycode_lookup_table[system_code];
|
||||
}
|
||||
|
||||
inline b32
|
||||
|
@ -105,10 +42,9 @@ keycode_has_ascii(u16 keycode){
|
|||
}
|
||||
|
||||
internal u8
|
||||
keycode_to_character_ascii(Key_Codes *codes,
|
||||
u16 keycode,
|
||||
bool32 shift,
|
||||
bool32 caps_lock){
|
||||
translate_key(u16 keycode,
|
||||
b32 shift,
|
||||
b32 caps_lock){
|
||||
u8 character = 0;
|
||||
if (keycode >= 'A' && keycode <= 'Z'){
|
||||
if (caps_lock) shift = !shift;
|
||||
|
|
|
@ -26,7 +26,7 @@ struct Interactive_Bar{
|
|||
real32 pos_x, pos_y;
|
||||
real32 text_shift_x, text_shift_y;
|
||||
i32_Rect rect;
|
||||
Font *font;
|
||||
Render_Font *font;
|
||||
};
|
||||
|
||||
enum View_Message{
|
||||
|
@ -135,7 +135,7 @@ struct Editing_Layout{
|
|||
internal void
|
||||
intbar_draw_string(Render_Target *target, Interactive_Bar *bar,
|
||||
u8 *str, u32 char_color){
|
||||
Font *font = bar->font;
|
||||
Render_Font *font = bar->font;
|
||||
for (i32 i = 0; str[i]; ++i){
|
||||
char c = str[i];
|
||||
font_draw_glyph(target, font, c,
|
||||
|
@ -150,7 +150,7 @@ internal void
|
|||
intbar_draw_string(Render_Target *target,
|
||||
Interactive_Bar *bar, String str,
|
||||
u32 char_color){
|
||||
Font *font = bar->font;
|
||||
Render_Font *font = bar->font;
|
||||
for (i32 i = 0; i < str.size; ++i){
|
||||
char c = str.str[i];
|
||||
font_draw_glyph(target, font, c,
|
||||
|
|
|
@ -9,12 +9,34 @@
|
|||
|
||||
// TOP
|
||||
|
||||
internal Key_Event_Data
|
||||
get_key_event(SDL_Event *event){
|
||||
Key_Event_Data result = {};
|
||||
return result;
|
||||
}
|
||||
#include "4ed_keyboard.cpp"
|
||||
|
||||
internal void
|
||||
keycode_init(Key_Codes *codes){
|
||||
set_dynamic_key_names(codes);
|
||||
|
||||
u16 code, loose;
|
||||
for (u16 i = 0; i < 255; ++i){
|
||||
if (i >= 'a' && i <= 'z'){
|
||||
keycode_lookup_table[i] = i + ('A' - 'a');
|
||||
loose_keycode_lookup_table[i] = 0;
|
||||
}
|
||||
|
||||
else if (i >= '0' && i <= '9'){
|
||||
keycode_lookup_table[i] = i;
|
||||
loose_keycode_lookup_table[i] = 0;
|
||||
}
|
||||
|
||||
else{
|
||||
loose = 0;
|
||||
switch (i){
|
||||
}
|
||||
|
||||
keycode_lookup_table[i] = code;
|
||||
loose_keycode_lookup_table[i] = loose;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
|
56
4ed_math.cpp
56
4ed_math.cpp
|
@ -103,7 +103,7 @@ struct i32_Rect{
|
|||
i32 x1, y1;
|
||||
};
|
||||
|
||||
struct real32_Rect{
|
||||
struct f32_Rect{
|
||||
f32 x0, y0;
|
||||
f32 x1, y1;
|
||||
};
|
||||
|
@ -117,7 +117,7 @@ i32R(i32 l, i32 t, i32 r, i32 b){
|
|||
}
|
||||
|
||||
inline i32_Rect
|
||||
i32R(real32_Rect r){
|
||||
i32R(f32_Rect r){
|
||||
i32_Rect rect;
|
||||
rect.x0 = (i32)r.x0;
|
||||
rect.y0 = (i32)r.y0;
|
||||
|
@ -134,53 +134,53 @@ i32XYWH(i32 x, i32 y, i32 w, i32 h){
|
|||
return rect;
|
||||
}
|
||||
|
||||
inline real32_Rect
|
||||
f32R(real32 l, real32 t, real32 r, real32 b){
|
||||
real32_Rect rect;
|
||||
inline f32_Rect
|
||||
f32R(f32 l, f32 t, f32 r, f32 b){
|
||||
f32_Rect rect;
|
||||
rect.x0 = l; rect.y0 = t;
|
||||
rect.x1 = r; rect.y1 = b;
|
||||
return rect;
|
||||
}
|
||||
|
||||
inline real32_Rect
|
||||
inline f32_Rect
|
||||
f32R(i32_Rect r){
|
||||
real32_Rect rect;
|
||||
rect.x0 = (real32)r.x0;
|
||||
rect.y0 = (real32)r.y0;
|
||||
rect.x1 = (real32)r.x1;
|
||||
rect.y1 = (real32)r.y1;
|
||||
f32_Rect rect;
|
||||
rect.x0 = (f32)r.x0;
|
||||
rect.y0 = (f32)r.y0;
|
||||
rect.x1 = (f32)r.x1;
|
||||
rect.y1 = (f32)r.y1;
|
||||
return rect;
|
||||
}
|
||||
|
||||
inline real32_Rect
|
||||
inline f32_Rect
|
||||
f32XYWH(f32 x, f32 y, f32 w, f32 h){
|
||||
real32_Rect rect;
|
||||
f32_Rect rect;
|
||||
rect.x0 = x; rect.y0 = y;
|
||||
rect.x1 = x+w; rect.y1 = y+h;
|
||||
return rect;
|
||||
}
|
||||
|
||||
inline bool32
|
||||
inline b32
|
||||
hit_check(i32 x, i32 y, i32 x0, i32 y0, i32 x1, i32 y1){
|
||||
return (x >= x0 && x < x1 && y >= y0 && y < y1);
|
||||
}
|
||||
|
||||
inline bool32
|
||||
inline b32
|
||||
hit_check(i32 x, i32 y, i32_Rect rect){
|
||||
return (hit_check(x, y, rect.x0, rect.y0, rect.x1, rect.y1));
|
||||
}
|
||||
|
||||
inline bool32
|
||||
hit_check(i32 x, i32 y, real32 x0, real32 y0, real32 x1, real32 y1){
|
||||
inline b32
|
||||
hit_check(i32 x, i32 y, f32 x0, f32 y0, f32 x1, f32 y1){
|
||||
return (x >= x0 && x < x1 && y >= y0 && y < y1);
|
||||
}
|
||||
|
||||
inline bool32
|
||||
hit_check(i32 x, i32 y, real32_Rect rect){
|
||||
inline b32
|
||||
hit_check(i32 x, i32 y, f32_Rect rect){
|
||||
return (hit_check(x, y, rect.x0, rect.y0, rect.x1, rect.y1));
|
||||
}
|
||||
|
||||
inline bool32
|
||||
inline b32
|
||||
positive_area(i32_Rect rect){
|
||||
return (rect.x0 < rect.x1 && rect.y0 < rect.y1);
|
||||
}
|
||||
|
@ -195,12 +195,26 @@ get_inner_rect(i32_Rect outer, i32 margin){
|
|||
return r;
|
||||
}
|
||||
|
||||
inline bool32
|
||||
inline b32
|
||||
fits_inside(i32_Rect rect, i32_Rect outer){
|
||||
return (rect.x0 >= outer.x0 && rect.x1 <= outer.x1 &&
|
||||
rect.y0 >= outer.y0 && rect.y1 <= outer.y1);
|
||||
}
|
||||
|
||||
inline i32_Rect
|
||||
rect_clamp_to_rect(i32_Rect rect, i32_Rect clamp_box){
|
||||
if (rect.x0 < clamp_box.x0) rect.x0 = clamp_box.x0;
|
||||
if (rect.y0 < clamp_box.y0) rect.y0 = clamp_box.y0;
|
||||
if (rect.x1 > clamp_box.x1) rect.x1 = clamp_box.x1;
|
||||
if (rect.y1 > clamp_box.y1) rect.y1 = clamp_box.y1;
|
||||
return rect;
|
||||
}
|
||||
|
||||
inline i32_Rect
|
||||
rect_clamp_to_rect(i32 left, i32 top, i32 right, i32 bottom, i32_Rect clamp_box){
|
||||
return rect_clamp_to_rect(i32R(left, top, right, bottom), clamp_box);
|
||||
}
|
||||
|
||||
/*
|
||||
* Vectors
|
||||
*/
|
||||
|
|
|
@ -28,11 +28,18 @@ typedef i8 bool8;
|
|||
typedef i32 b32;
|
||||
typedef i8 b8;
|
||||
|
||||
typedef uint8_t byte;
|
||||
|
||||
typedef float real32;
|
||||
typedef double real64;
|
||||
typedef float f32;
|
||||
typedef double f64;
|
||||
|
||||
struct Data{
|
||||
byte *data;
|
||||
i32 size;
|
||||
};
|
||||
|
||||
#define external extern "C"
|
||||
#define internal static
|
||||
#define globalvar static
|
||||
|
|
File diff suppressed because it is too large
Load Diff
127
4ed_rendering.h
127
4ed_rendering.h
|
@ -1,46 +1,28 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 12.17.2014
|
||||
* 17.12.2014
|
||||
*
|
||||
* Rendering layer for project codename "4ed"
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
#ifndef FRED_RENDERING_H
|
||||
#define FRED_RENDERING_H
|
||||
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#include "stb_truetype.h"
|
||||
|
||||
#if SOFTWARE_RENDER
|
||||
struct Glyph_Data{
|
||||
void *data;
|
||||
i32 width, height;
|
||||
i32 minx, maxx, miny, maxy;
|
||||
i32 left_shift;
|
||||
bool32 exists;
|
||||
b32 exists;
|
||||
};
|
||||
|
||||
struct Font{
|
||||
Glyph_Data glyphs[128];
|
||||
i32 height, ascent, descent, line_skip;
|
||||
i32 advance;
|
||||
};
|
||||
#else
|
||||
struct Glyph_Data{
|
||||
#if 0
|
||||
i32 width, height;
|
||||
i32 minx, maxx, miny, maxy;
|
||||
i32 left_shift;
|
||||
#endif
|
||||
bool32 exists;
|
||||
};
|
||||
|
||||
struct Font{
|
||||
struct Render_Font{
|
||||
char name_[24];
|
||||
String name;
|
||||
bool32 loaded;
|
||||
b32 loaded;
|
||||
|
||||
Glyph_Data glyphs[256];
|
||||
stbtt_bakedchar chardata[256];
|
||||
|
@ -50,6 +32,101 @@ struct Font{
|
|||
u32 tex;
|
||||
i32 tex_width, tex_height;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct Render_Target;
|
||||
|
||||
#define Draw_Push_Clip_Sig(name) void name(Render_Target *target, i32_Rect clip_box)
|
||||
typedef Draw_Push_Clip_Sig(Draw_Push_Clip);
|
||||
|
||||
#define Draw_Pop_Clip_Sig(name) void name(Render_Target *target)
|
||||
typedef Draw_Pop_Clip_Sig(Draw_Pop_Clip);
|
||||
|
||||
enum Render_Piece_Type{
|
||||
piece_type_rectangle,
|
||||
piece_type_outline,
|
||||
piece_type_gradient,
|
||||
piece_type_glyph,
|
||||
piece_type_mono_glyph,
|
||||
piece_type_mono_glyph_advance
|
||||
};
|
||||
|
||||
struct Render_Piece_Header{
|
||||
i32 type;
|
||||
};
|
||||
|
||||
struct Render_Piece_Rectangle{
|
||||
f32_Rect rect;
|
||||
u32 color;
|
||||
};
|
||||
|
||||
struct Render_Piece_Gradient{
|
||||
f32_Rect rect;
|
||||
u32 left_color, right_color;
|
||||
};
|
||||
|
||||
struct Render_Piece_Glyph{
|
||||
Vec2 pos;
|
||||
u32 color;
|
||||
Render_Font *font_id;
|
||||
u16 character;
|
||||
};
|
||||
|
||||
struct Render_Piece_Glyph_Advance{
|
||||
Vec2 pos;
|
||||
u32 color;
|
||||
f32 advance;
|
||||
Render_Font *font_id;
|
||||
u16 character;
|
||||
};
|
||||
|
||||
struct Render_Piece_Combined{
|
||||
Render_Piece_Header header;
|
||||
union{
|
||||
Render_Piece_Rectangle rectangle;
|
||||
Render_Piece_Gradient gradient;
|
||||
Render_Piece_Glyph glyph;
|
||||
Render_Piece_Glyph_Advance glyph_advance;
|
||||
};
|
||||
};
|
||||
|
||||
#define Draw_Push_Piece_Sig(name) void name(Render_Target *target, Render_Piece_Combined piece)
|
||||
typedef Draw_Push_Piece_Sig(Draw_Push_Piece);
|
||||
|
||||
#define Font_Load_Sig(name) i32 name( \
|
||||
System_Functions *system, \
|
||||
Render_Font *font_out, \
|
||||
char *filename, \
|
||||
i32 pt_size, \
|
||||
void *font_block, \
|
||||
i32 font_block_size, \
|
||||
i32 *memory_used_out, \
|
||||
i32 tab_width)
|
||||
typedef Font_Load_Sig(Font_Load);
|
||||
|
||||
struct Render_Target{
|
||||
void *handle;
|
||||
void *context;
|
||||
i32_Rect clip_boxes[5];
|
||||
i32 clip_top;
|
||||
i32 width, height;
|
||||
i32 bound_texture;
|
||||
u32 color;
|
||||
|
||||
byte *push_buffer;
|
||||
i32 size, max;
|
||||
|
||||
Draw_Push_Clip *push_clip;
|
||||
Draw_Pop_Clip *pop_clip;
|
||||
Draw_Push_Piece *push_piece;
|
||||
Font_Load *font_load;
|
||||
};
|
||||
|
||||
inline i32_Rect
|
||||
rect_from_target(Render_Target *target){
|
||||
return i32R(0, 0, target->width, target->height);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -214,7 +214,7 @@ struct Style_File_Format{
|
|||
struct Style{
|
||||
char name_[24];
|
||||
String name;
|
||||
Font *font;
|
||||
Render_Font *font;
|
||||
Style_Main_Data main;
|
||||
bool32 font_changed;
|
||||
};
|
||||
|
@ -225,7 +225,7 @@ struct Style_Library{
|
|||
};
|
||||
|
||||
struct Font_Set{
|
||||
Font *fonts;
|
||||
Render_Font *fonts;
|
||||
i32 count, max;
|
||||
};
|
||||
|
||||
|
@ -243,12 +243,12 @@ style_set_name(Style *style, String name){
|
|||
copy(&style->name, name);
|
||||
}
|
||||
|
||||
internal Font*
|
||||
internal Render_Font*
|
||||
font_set_extract(Font_Set *fonts, char *name, i32 size){
|
||||
String n = make_string(name, size);
|
||||
i32 count = fonts->count;
|
||||
Font *result = 0;
|
||||
Font *font = fonts->fonts;
|
||||
Render_Font *result = 0;
|
||||
Render_Font *font = fonts->fonts;
|
||||
for (i32 i = 0; i < count; ++i, ++font){
|
||||
if (match(n, font->name)){
|
||||
result = font;
|
||||
|
@ -479,7 +479,7 @@ style_library_import(System_Functions *system,
|
|||
char *filename, Font_Set *fonts, Style *out, i32 max,
|
||||
i32 *count_opt, i32 *total_opt = 0){
|
||||
b32 result = 1;
|
||||
File_Data file = system->load_file(filename);
|
||||
Data file = system->load_file(filename);
|
||||
Style_Page_Header *h = 0;
|
||||
|
||||
if (!file.data){
|
||||
|
@ -573,7 +573,7 @@ style_library_add(Style_Library *library, Style *style){
|
|||
|
||||
internal Style_File_Format*
|
||||
style_format_for_file(Style *style, Style_File_Format *out){
|
||||
Font *font = style->font;
|
||||
Render_Font *font = style->font;
|
||||
out->name_size = style->name.size;
|
||||
memcpy(out->name, style->name.str, ArrayCount(out->name));
|
||||
out->font_name_size = font->name.size;
|
||||
|
|
20
4ed_system.h
20
4ed_system.h
|
@ -15,17 +15,12 @@ struct Plat_Handle{
|
|||
u32 d[4];
|
||||
};
|
||||
|
||||
struct File_Data{
|
||||
void *data;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct Time_Stamp{
|
||||
u64 time;
|
||||
b32 success;
|
||||
};
|
||||
|
||||
#define Sys_Load_File_Sig(name) File_Data name(char *filename)
|
||||
#define Sys_Load_File_Sig(name) Data name(char *filename)
|
||||
typedef Sys_Load_File_Sig(System_Load_File);
|
||||
|
||||
#define Sys_Save_File_Sig(name) i32 name(char *filename, void *data, i32 size)
|
||||
|
@ -40,10 +35,8 @@ typedef Sys_File_Time_Stamp_Sig(System_File_Time_Stamp);
|
|||
#define Sys_Time_Stamp_Now_Sig(name) u64 name()
|
||||
typedef Sys_Time_Stamp_Now_Sig(System_Time_Stamp_Now);
|
||||
|
||||
#if 0
|
||||
#define Sys_Free_File_Sig(name) void name(File_Data file)
|
||||
#define Sys_Free_File_Sig(name) void name(Data file)
|
||||
typedef Sys_Free_File_Sig(System_Free_File);
|
||||
#endif
|
||||
|
||||
#define Sys_Get_Current_Directory_Sig(name) i32 name(char *out, i32 max)
|
||||
typedef Sys_Get_Current_Directory_Sig(System_Get_Current_Directory);
|
||||
|
@ -127,8 +120,9 @@ struct Thread_Memory{
|
|||
i32 id;
|
||||
};
|
||||
|
||||
#define Job_Callback(name) void name(System_Functions *system, Thread_Context *thread, Thread_Memory *memory, void *data[2])
|
||||
typedef Job_Callback(Job_Callback);
|
||||
#define Job_Callback_Sig(name) void name(\
|
||||
System_Functions *system, Thread_Context *thread, Thread_Memory *memory, void *data[2])
|
||||
typedef Job_Callback_Sig(Job_Callback);
|
||||
|
||||
struct Job_Data{
|
||||
Job_Callback *callback;
|
||||
|
@ -169,6 +163,9 @@ typedef INTERNAL_Sys_Sentinel_Sig(INTERNAL_System_Sentinel);
|
|||
#define INTERNAL_Sys_Get_Thread_States_Sig(name) void name(Thread_Group_ID id, b8 *running, i32 *pending)
|
||||
typedef INTERNAL_Sys_Get_Thread_States_Sig(INTERNAL_System_Get_Thread_States);
|
||||
|
||||
#define INTERNAL_Sys_Debug_Message_Sig(name) void name(char *message)
|
||||
typedef INTERNAL_Sys_Debug_Message_Sig(INTERNAL_System_Debug_Message);
|
||||
|
||||
struct System_Functions{
|
||||
System_Load_File *load_file;
|
||||
System_Save_File *save_file;
|
||||
|
@ -206,6 +203,7 @@ struct System_Functions{
|
|||
|
||||
INTERNAL_System_Sentinel *internal_sentinel;
|
||||
INTERNAL_System_Get_Thread_States *internal_get_thread_states;
|
||||
INTERNAL_System_Debug_Message *internal_debug_message;
|
||||
};
|
||||
|
||||
// BOTTOM
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
146
linux_4ed.cpp
146
linux_4ed.cpp
|
@ -75,18 +75,27 @@
|
|||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include <GL/gl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "4ed_internal.h"
|
||||
#include "4ed_linux_keyboard.cpp"
|
||||
|
||||
#define printe(m) printf("%s:%d: %s\n", __FILE__, __LINE__, #m)
|
||||
|
||||
struct Linux_Vars{
|
||||
Application_Memory mem;
|
||||
Key_Codes codes;
|
||||
Key_Input_Data input;
|
||||
Mouse_State mouse;
|
||||
Render_Target target;
|
||||
Application_Memory mem;
|
||||
b32 keep_going;
|
||||
b32 force_redraw;
|
||||
|
||||
Clipboard_Contents clipboard;
|
||||
|
||||
|
@ -95,6 +104,7 @@ struct Linux_Vars{
|
|||
System_Functions *system;
|
||||
App_Functions app;
|
||||
Config_API config_api;
|
||||
|
||||
};
|
||||
|
||||
Linux_Vars linuxvars;
|
||||
|
@ -206,13 +216,11 @@ LinuxLoadAppCode(){
|
|||
--size);
|
||||
memcpy(path + size + 1, app_code_file, app_code_file_len + 1);
|
||||
|
||||
linuxvars.app_code = SDL_LoadObject(path);
|
||||
linuxvars.app_code = 0;
|
||||
if (linuxvars.app_code){
|
||||
result = 1;
|
||||
linuxvars.app.init = (App_Init*)
|
||||
SDL_LoadFunction(linuxvars.app_code, "app_init");
|
||||
linuxvars.app.step = (App_Step*)
|
||||
SDL_LoadFunction(linuxvars.app_code, "app_step");
|
||||
linuxvars.app.init = (App_Init*)0;
|
||||
linuxvars.app.step = (App_Step*)0;
|
||||
}
|
||||
else{
|
||||
// TODO(allen): initialization failure
|
||||
|
@ -232,6 +240,11 @@ Sys_Release_Lock_Sig(system_release_lock){
|
|||
AllowLocal(id);
|
||||
}
|
||||
|
||||
internal
|
||||
Sys_Force_Redraw_Sig(system_force_redraw){
|
||||
linuxvars.force_redraw = 1;
|
||||
}
|
||||
|
||||
internal void
|
||||
LinuxLoadSystemCode(){
|
||||
linuxvars.system->get_memory_full = system_get_memory_;
|
||||
|
@ -275,16 +288,13 @@ LinuxLoadSystemCode(){
|
|||
#endif
|
||||
}
|
||||
|
||||
internal void
|
||||
LinuxShowScreen(){
|
||||
}
|
||||
|
||||
int main(){
|
||||
linuxvars = {};
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO)){
|
||||
// TODO(allen): initialization failure
|
||||
printe(SDL_Init);
|
||||
return(1);
|
||||
}
|
||||
SDL_EnableUNICODE(1);
|
||||
|
||||
if (!LinuxLoadAppCode()){
|
||||
return(1);
|
||||
}
|
||||
|
@ -293,14 +303,7 @@ int main(){
|
|||
System_Functions *system = &system_;
|
||||
linuxvars.system = system;
|
||||
LinuxLoadSystemCode();
|
||||
|
||||
const SDL_VideoInfo *info = SDL_GetVideoInfo();
|
||||
if (!info){
|
||||
// TODO(allen): initialization failure
|
||||
printe(info);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
void *base;
|
||||
#if FRED_INTERNAL
|
||||
|
@ -329,72 +332,59 @@ int main(){
|
|||
|
||||
i32 width = 800;
|
||||
i32 height = 600;
|
||||
i32 bpp = info->vfmt->BitsPerPixel;
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
|
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
|
||||
i32 flags = SDL_OPENGL;
|
||||
|
||||
if (SDL_SetVideoMode(width, height, bpp, flags) == 0){
|
||||
// TODO(allen): initialization failure
|
||||
printe(SDL_SetVideoMode);
|
||||
return(1);
|
||||
}
|
||||
|
||||
SDL_WM_SetCaption("4coder-window", 0);
|
||||
i32 bpp = 24;
|
||||
|
||||
linuxvars.target.width = width;
|
||||
linuxvars.target.height = height;
|
||||
|
||||
keycode_init(&linuxvars.codes);
|
||||
|
||||
system_acquire_lock(FRAME_LOCK);
|
||||
b32 first = 1;
|
||||
linuxvars.keep_going = 1;
|
||||
|
||||
SDL_Event event;
|
||||
for (;linuxvars.keep_going && SDL_WaitEvent(&event);){
|
||||
b32 pass_to_app = 0;
|
||||
|
||||
i64 timer_start = system_time();
|
||||
|
||||
for (;linuxvars.keep_going;){
|
||||
linuxvars.input = {};
|
||||
linuxvars.clipboard = {};
|
||||
switch (event.type){
|
||||
case SDL_ACTIVEEVENT:
|
||||
{
|
||||
if ((event.active.state & SDL_APPACTIVE) && event.active.gain)
|
||||
pass_to_app = 1;
|
||||
}break;
|
||||
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
pass_to_app = 1;
|
||||
linuxvars.input.press[linuxvars.input.press_count++] =
|
||||
get_key_event(&event);
|
||||
}break;
|
||||
|
||||
case SDL_QUIT:
|
||||
{
|
||||
linuxvars.keep_going = 0;
|
||||
}break;
|
||||
linuxvars.mouse.wheel = 0;
|
||||
linuxvars.force_redraw = 0;
|
||||
|
||||
for (;0;){
|
||||
}
|
||||
|
||||
if (pass_to_app){
|
||||
Application_Step_Result app_result =
|
||||
linuxvars.app.step(linuxvars.system,
|
||||
0,
|
||||
0,
|
||||
&linuxvars.input,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
&linuxvars.mem,
|
||||
linuxvars.clipboard,
|
||||
first, 1);
|
||||
|
||||
|
||||
|
||||
SDL_GL_SwapBuffers();
|
||||
linuxvars.mouse.left_button_prev = linuxvars.mouse.left_button;
|
||||
linuxvars.mouse.right_button_prev = linuxvars.mouse.right_button;
|
||||
|
||||
#if 0
|
||||
Application_Step_Result app_result =
|
||||
linuxvars.app.step(linuxvars.system,
|
||||
&linuxvars.codes,
|
||||
&linuxvars.input,
|
||||
&linuxvars.mouse,
|
||||
&linuxvars.target,
|
||||
&linuxvars.mem,
|
||||
linuxvars.clipboard,
|
||||
1, first, linuxvars.force_redraw);
|
||||
#else
|
||||
Application_Step_Result app_result = {};
|
||||
#endif
|
||||
|
||||
if (1 || linuxvars.force_redraw){
|
||||
//glClearColor(1.f, 1.f, 0.f, 1.f);
|
||||
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
LinuxShowScreen();
|
||||
linuxvars.force_redraw = 0;
|
||||
}
|
||||
|
||||
i64 timer_target = timer_start + frame_useconds;
|
||||
i64 timer_end = system_time();
|
||||
for (;timer_end < timer_target;){
|
||||
i64 samount = timer_target - timer_end;
|
||||
usleep(samount);
|
||||
timer_end = system_time();
|
||||
}
|
||||
timer_start = system_time();
|
||||
}
|
||||
|
||||
return(0);
|
||||
|
|
|
@ -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
|
||||
|
|
@ -9,21 +9,6 @@
|
|||
|
||||
// TOP
|
||||
|
||||
// HOLY GRAIL
|
||||
#if 0
|
||||
int main(){
|
||||
Parse_Context context;
|
||||
Parse_Definitions definitions;
|
||||
Cpp_Parse_Preprocessor_State state;
|
||||
|
||||
cpp_default_context(&context, COMPILER_MSVC, PLATFORM_WIN32);
|
||||
cpp_default_definitions(&definitions, COMPILER_MSVC, PLATFORM_WIN32);
|
||||
cpp_set_target_file(&definitions, &state, "TARGET.cpp");
|
||||
|
||||
cpp_parse(&context, &definitions, &state);
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "../4ed_meta.h"
|
||||
|
||||
#include "../4cpp_types.h"
|
||||
|
@ -31,6 +16,7 @@ int main(){
|
|||
#include "../4cpp_string.h"
|
||||
#define FCPP_LEXER_IMPLEMENTATION
|
||||
#include "../4cpp_lexer.h"
|
||||
#include "../4cpp_preprocessor.cpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
@ -58,20 +44,21 @@ system_is_absoute_path(char *path){
|
|||
#define Assert assert
|
||||
#define TentativeAssert assert
|
||||
|
||||
#include "../4cpp_preprocessor.cpp"
|
||||
|
||||
Cpp_File
|
||||
quickie_file(char *filename){
|
||||
Cpp_File result;
|
||||
Cpp_File result = {};
|
||||
|
||||
FILE *file = fopen(filename, "rb");
|
||||
TentativeAssert(file);
|
||||
fseek(file, 0, SEEK_END);
|
||||
result.size = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
result.data = (char*)malloc(result.size);
|
||||
fread(result.data, 1, result.size, file);
|
||||
fclose(file);
|
||||
if (file){
|
||||
fseek(file, 0, SEEK_END);
|
||||
result.size = ftell(file);
|
||||
if (result.size > 0){
|
||||
fseek(file, 0, SEEK_SET);
|
||||
result.data = (char*)malloc(result.size);
|
||||
fread(result.data, 1, result.size, file);
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -87,12 +74,20 @@ quickie_file(String filename){
|
|||
|
||||
#define STRICT_MEM_TEST 1
|
||||
|
||||
#if 1
|
||||
int main(){
|
||||
char TEST_FILE[] = "parser_test6.cpp";
|
||||
int main(int argc, char **argv){
|
||||
if (argc < 2){
|
||||
printf("usage: %s <file>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
char *TEST_FILE = argv[1];
|
||||
|
||||
Cpp_File target_file;
|
||||
target_file = quickie_file(TEST_FILE);
|
||||
|
||||
if (target_file.data == 0){
|
||||
printf("could not open file %s\n", TEST_FILE);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Cpp_Token_Stack target_tokens = {};
|
||||
cpp_lex_file(target_file, &target_tokens);
|
||||
|
@ -138,7 +133,7 @@ int main(){
|
|||
#endif
|
||||
string_tokens.tokens = (Cpp_Token*)malloc(sizeof(Cpp_Token)*string_tokens.max_count);
|
||||
|
||||
Cpp_Parse_File string_parse_file;
|
||||
Cpp_File_Data string_parse_file;
|
||||
string_parse_file.file = string_file;
|
||||
string_parse_file.tokens = string_tokens;
|
||||
string_parse_file.filename = string_filename;
|
||||
|
@ -201,6 +196,10 @@ int main(){
|
|||
for (; cpp_has_more_files(&request); cpp_get_next_file(&request)){
|
||||
if (!cpp_try_reuse_file(&request)){
|
||||
Cpp_File new_file = quickie_file(request.filename);
|
||||
if (new_file.data == 0){
|
||||
printf("could not open file %s\n", request.filename);
|
||||
exit(1);
|
||||
}
|
||||
Cpp_Token_Stack new_tokens = {};
|
||||
cpp_lex_file(new_file, &new_tokens);
|
||||
cpp_provide_file(&request, new_file, new_tokens);
|
||||
|
@ -210,7 +209,7 @@ int main(){
|
|||
|
||||
if (result.error_code){
|
||||
String error_message = cpp_get_error(result.error_code);
|
||||
Cpp_Parse_File file = *cpp_get_parse_file(&definitions, result.file_index);
|
||||
Cpp_File_Data file = *cpp_get_parse_file(&definitions, result.file_index);
|
||||
Cpp_Token token = file.tokens.tokens[result.token_index];
|
||||
bool terminate = cpp_recommend_termination(result.error_code);
|
||||
|
||||
|
@ -229,11 +228,11 @@ int main(){
|
|||
}
|
||||
|
||||
if (result.emit){
|
||||
Cpp_Parse_File file = *cpp_get_parse_file(&definitions, result.file_index);
|
||||
Cpp_File_Data file = *cpp_get_parse_file(&definitions, result.file_index);
|
||||
Cpp_Token token = file.tokens.tokens[result.token_index];
|
||||
|
||||
if (result.from_macro){
|
||||
Cpp_Parse_File file = *cpp_get_parse_file(&definitions, result.invoking_file_index);
|
||||
Cpp_File_Data file = *cpp_get_parse_file(&definitions, result.invoking_file_index);
|
||||
Cpp_Token token = file.tokens.tokens[result.invoking_token_index];
|
||||
|
||||
printf("EXPANDING %.*s => ", token.size, file.file.data + token.start);
|
||||
|
@ -249,7 +248,6 @@ int main(){
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
|
263
win32_4ed.cpp
263
win32_4ed.cpp
|
@ -9,47 +9,7 @@
|
|||
|
||||
// TOP
|
||||
|
||||
#ifdef FRED_NOT_PACKAGE
|
||||
|
||||
#define FRED_INTERNAL 1
|
||||
#define FRED_SLOW 1
|
||||
|
||||
#define FRED_PRINT_DEBUG 1
|
||||
#define FRED_PRINT_DEBUG_FILE_LINE 0
|
||||
#define FRED_PROFILING 1
|
||||
#define FRED_PROFILING_OS 0
|
||||
#define FRED_FULL_ERRORS 0
|
||||
|
||||
#else
|
||||
|
||||
#define FRED_SLOW 0
|
||||
#define FRED_INTERNAL 0
|
||||
|
||||
#define FRED_PRINT_DEBUG 0
|
||||
#define FRED_PRINT_DEBUG_FILE_LINE 0
|
||||
#define FRED_PROFILING 0
|
||||
#define FRED_PROFILING_OS 0
|
||||
#define FRED_FULL_ERRORS 0
|
||||
|
||||
#endif
|
||||
|
||||
#define SOFTWARE_RENDER 0
|
||||
|
||||
#if FRED_INTERNAL == 0
|
||||
#undef FRED_PRINT_DEBUG
|
||||
#define FRED_PRINT_DEBUG 0
|
||||
#undef FRED_PROFILING
|
||||
#define FRED_PROFILING 0
|
||||
#undef FRED_PROFILING_OS
|
||||
#define FRED_PROFILING_OS 0
|
||||
#endif
|
||||
|
||||
#if FRED_PRINT_DEBUG == 0
|
||||
#undef FRED_PRINT_DEBUG_FILE_LINE
|
||||
#define FRED_PRINT_DEBUG_FILE_LINE 0
|
||||
#undef FRED_PRINT_DEBUG_FILE_LINE
|
||||
#define FRED_PROFILING_OS 0
|
||||
#endif
|
||||
#include "4ed_config.h"
|
||||
|
||||
#define FPS 30
|
||||
#define frame_useconds (1000000 / FPS)
|
||||
|
@ -63,18 +23,21 @@
|
|||
#include "4cpp_string.h"
|
||||
|
||||
#include "4ed_mem.cpp"
|
||||
|
||||
#include "4ed_math.cpp"
|
||||
|
||||
#include "4ed_dll_reader.h"
|
||||
#include "4coder_custom.h"
|
||||
#include "4ed_system.h"
|
||||
#include "4ed.h"
|
||||
#include "4ed_rendering.h"
|
||||
#include "4ed.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <GL/gl.h>
|
||||
|
||||
#include "4ed_dll_reader.cpp"
|
||||
#include "4ed_rendering.cpp"
|
||||
#include "4ed_internal.h"
|
||||
#include "4ed_keyboard.cpp"
|
||||
#include "4ed_win32_keyboard.cpp"
|
||||
|
||||
struct Full_Job_Data{
|
||||
Job_Data job;
|
||||
|
@ -108,24 +71,14 @@ struct Thread_Group{
|
|||
i32 count;
|
||||
};
|
||||
|
||||
#define UseWinDll 0
|
||||
|
||||
struct Win32_Vars{
|
||||
HWND window_handle;
|
||||
Key_Codes key_codes;
|
||||
Key_Input_Data input_data, previous_data;
|
||||
|
||||
#if SOFTWARE_RENDER
|
||||
BITMAPINFO bmp_info;
|
||||
union{
|
||||
struct{
|
||||
void *pixel_data;
|
||||
i32 width, height, pitch;
|
||||
};
|
||||
Render_Target target;
|
||||
};
|
||||
i32 true_pixel_size;
|
||||
#else
|
||||
Render_Target target;
|
||||
#endif
|
||||
|
||||
u32 volatile force_redraw;
|
||||
|
||||
|
@ -153,7 +106,11 @@ struct Win32_Vars{
|
|||
i64 start_pcount;
|
||||
|
||||
HMODULE custom;
|
||||
#if UseWinDll
|
||||
HMODULE app_code;
|
||||
#else
|
||||
DLL_Loaded app_dll;
|
||||
#endif
|
||||
|
||||
System_Functions *system;
|
||||
App_Functions app;
|
||||
|
@ -167,11 +124,19 @@ struct Win32_Vars{
|
|||
globalvar Win32_Vars win32vars;
|
||||
globalvar Application_Memory win32memory;
|
||||
|
||||
#if FRED_INTERNAL
|
||||
internal Bubble*
|
||||
INTERNAL_system_sentinel(){
|
||||
return (&win32vars.internal_bubble);
|
||||
}
|
||||
|
||||
internal void
|
||||
INTERNAL_system_debug_message(char *message){
|
||||
OutputDebugString(message);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
internal void*
|
||||
system_get_memory_(i32 size, i32 line_number, char *file_name){
|
||||
void *ptr = 0;
|
||||
|
@ -213,9 +178,9 @@ system_free_memory(void *block){
|
|||
}
|
||||
}
|
||||
|
||||
internal File_Data
|
||||
internal Data
|
||||
system_load_file(char *filename){
|
||||
File_Data result = {};
|
||||
Data result = {};
|
||||
HANDLE file;
|
||||
file = CreateFile((char*)filename, GENERIC_READ, 0, 0,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
|
@ -232,7 +197,7 @@ system_load_file(char *filename){
|
|||
}
|
||||
|
||||
result.size = (lo) + (((u64)hi) << 32);
|
||||
result.data = system_get_memory(result.size);
|
||||
result.data = (byte*)system_get_memory(result.size);
|
||||
|
||||
if (!result.data){
|
||||
CloseHandle(file);
|
||||
|
@ -243,7 +208,7 @@ system_load_file(char *filename){
|
|||
DWORD read_size;
|
||||
BOOL read_result = ReadFile(file, result.data, result.size,
|
||||
&read_size, 0);
|
||||
if (!read_result || read_size != result.size){
|
||||
if (!read_result || read_size != (u32)result.size){
|
||||
CloseHandle(file);
|
||||
system_free_memory(result.data);
|
||||
result = {};
|
||||
|
@ -316,7 +281,7 @@ system_time(){
|
|||
}
|
||||
|
||||
internal void
|
||||
system_free_file(File_Data data){
|
||||
system_free_file(Data data){
|
||||
system_free_memory(data.data);
|
||||
}
|
||||
|
||||
|
@ -437,31 +402,13 @@ system_post_clipboard(String str){
|
|||
}
|
||||
}
|
||||
|
||||
#if SOFTWARE_RENDER
|
||||
internal void
|
||||
Win32RedrawScreen(HDC hdc){
|
||||
win32vars.bmp_info.bmiHeader.biHeight =
|
||||
-win32vars.bmp_info.bmiHeader.biHeight;
|
||||
SetDIBitsToDevice(hdc,
|
||||
0, 0,
|
||||
win32vars.width, win32vars.height,
|
||||
0, 0,
|
||||
0, win32vars.height,
|
||||
win32vars.pixel_data,
|
||||
&win32vars.bmp_info,
|
||||
DIB_RGB_COLORS);
|
||||
win32vars.bmp_info.bmiHeader.biHeight =
|
||||
-win32vars.bmp_info.bmiHeader.biHeight;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
internal void
|
||||
Win32RedrawScreen(HDC hdc){
|
||||
launch_rendering(&win32vars.target);
|
||||
win32vars.target.size = 0;
|
||||
glFlush();
|
||||
SwapBuffers(hdc);
|
||||
}
|
||||
#endif
|
||||
|
||||
internal void
|
||||
Win32Resize(i32 width, i32 height){
|
||||
|
@ -583,43 +530,19 @@ Win32Callback(HWND hwnd, UINT uMsg,
|
|||
|
||||
case WM_SIZE:
|
||||
{
|
||||
#if SOFTWARE_RENDER
|
||||
i32 new_width = LOWORD(lParam);
|
||||
i32 new_height = HIWORD(lParam);
|
||||
i32 new_pitch = new_width * 4;
|
||||
|
||||
if (new_height*new_pitch > win32vars.true_pixel_size){
|
||||
system_free_memory(win32vars.pixel_data);
|
||||
|
||||
win32vars.pixel_data = system_get_memory(new_height*new_pitch);
|
||||
win32vars.true_pixel_size = new_height*new_pitch;
|
||||
|
||||
if (!win32vars.pixel_data){
|
||||
win32vars.keep_playing = 0;
|
||||
}
|
||||
}
|
||||
|
||||
win32vars.width = new_width;
|
||||
win32vars.height = new_height;
|
||||
win32vars.pitch = new_pitch;
|
||||
|
||||
win32vars.bmp_info.bmiHeader.biWidth = win32vars.width;
|
||||
win32vars.bmp_info.bmiHeader.biHeight = win32vars.height;
|
||||
#else
|
||||
if (win32vars.target.handle){
|
||||
i32 new_width = LOWORD(lParam);
|
||||
i32 new_height = HIWORD(lParam);
|
||||
|
||||
Win32Resize(new_width, new_height);
|
||||
}
|
||||
#endif
|
||||
}break;
|
||||
|
||||
case WM_PAINT:
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc = BeginPaint(hwnd, &ps);
|
||||
|
||||
|
||||
Clipboard_Contents empty_contents = {};
|
||||
win32vars.app.step(win32vars.system,
|
||||
&win32vars.key_codes,
|
||||
|
@ -755,6 +678,8 @@ system_post_job(Thread_Group_ID group_id, Job_Data job){
|
|||
queue->jobs[write_index].running_thread = THREAD_NOT_ASSIGNED;
|
||||
queue->jobs[write_index].id = result;
|
||||
success = 1;
|
||||
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -969,10 +894,16 @@ system_cli_end_update(CLI_Handles *cli){
|
|||
return close_me;
|
||||
}
|
||||
|
||||
void
|
||||
DUMP(byte *d, i32 size){
|
||||
//system_save_file("DUMP", d, size);
|
||||
}
|
||||
|
||||
internal b32
|
||||
Win32LoadAppCode(){
|
||||
b32 result = 0;
|
||||
|
||||
|
||||
#if UseWinDll
|
||||
win32vars.app_code = LoadLibraryA("4ed_app.dll");
|
||||
if (win32vars.app_code){
|
||||
result = 1;
|
||||
|
@ -982,6 +913,50 @@ Win32LoadAppCode(){
|
|||
GetProcAddress(win32vars.app_code, "app_step");
|
||||
}
|
||||
|
||||
DUMP((byte*)(win32vars.app.step) - 0x39000, Kbytes(400));
|
||||
#else
|
||||
Data file = system_load_file("4ed_app.dll");
|
||||
|
||||
if (file.data){
|
||||
i32 error;
|
||||
DLL_Data dll_data;
|
||||
if (dll_parse_headers(file, &dll_data, &error)){
|
||||
Data img;
|
||||
img.size = dll_total_loaded_size(&dll_data);
|
||||
img.data = (byte*)
|
||||
VirtualAlloc((LPVOID)Tbytes(3), img.size,
|
||||
MEM_COMMIT | MEM_RESERVE,
|
||||
PAGE_READWRITE);
|
||||
|
||||
dll_load(img, &win32vars.app_dll, file, &dll_data);
|
||||
|
||||
DWORD extra_;
|
||||
VirtualProtect(img.data + win32vars.app_dll.text_start,
|
||||
win32vars.app_dll.text_size,
|
||||
PAGE_EXECUTE_READ,
|
||||
&extra_);
|
||||
|
||||
result = 1;
|
||||
win32vars.app.init = (App_Init*)
|
||||
dll_load_function(&win32vars.app_dll, "app_init", 8);
|
||||
|
||||
win32vars.app.step = (App_Step*)
|
||||
dll_load_function(&win32vars.app_dll, "app_step", 8);
|
||||
}
|
||||
else{
|
||||
// TODO(allen): file loading error
|
||||
}
|
||||
|
||||
system_free_file(file);
|
||||
|
||||
DUMP((byte*)(Tbytes(3)), Kbytes(400));
|
||||
}
|
||||
else{
|
||||
// TODO(allen): file loading error
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1023,6 +998,7 @@ Win32LoadSystemCode(){
|
|||
|
||||
win32vars.system->internal_sentinel = INTERNAL_system_sentinel;
|
||||
win32vars.system->internal_get_thread_states = INTERNAL_get_thread_states;
|
||||
win32vars.system->internal_debug_message = INTERNAL_system_debug_message;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1032,6 +1008,12 @@ WinMain(HINSTANCE hInstance,
|
|||
int nCmdShow){
|
||||
win32vars = {};
|
||||
|
||||
#if FRED_INTERNAL
|
||||
win32vars.internal_bubble.next = &win32vars.internal_bubble;
|
||||
win32vars.internal_bubble.prev = &win32vars.internal_bubble;
|
||||
win32vars.internal_bubble.flags = MEM_BUBBLE_SYS_DEBUG;
|
||||
#endif
|
||||
|
||||
if (!Win32LoadAppCode()){
|
||||
// TODO(allen): Failed to load app code, serious problem.
|
||||
return 99;
|
||||
|
@ -1048,12 +1030,6 @@ WinMain(HINSTANCE hInstance,
|
|||
QueryPerformanceCounter(&lpf);
|
||||
win32vars.start_pcount = lpf.QuadPart;
|
||||
|
||||
#if FRED_INTERNAL
|
||||
win32vars.internal_bubble.next = &win32vars.internal_bubble;
|
||||
win32vars.internal_bubble.prev = &win32vars.internal_bubble;
|
||||
win32vars.internal_bubble.flags = MEM_BUBBLE_SYS_DEBUG;
|
||||
#endif
|
||||
|
||||
keycode_init(&win32vars.key_codes);
|
||||
|
||||
#ifdef FRED_SUPER
|
||||
|
@ -1120,12 +1096,8 @@ WinMain(HINSTANCE hInstance,
|
|||
if (!AdjustWindowRect(&window_rect, WS_OVERLAPPEDWINDOW, false)){
|
||||
// TODO(allen): non-fatal diagnostics
|
||||
}
|
||||
|
||||
#if SOFTWARE_RENDER
|
||||
#define WINDOW_NAME "4coder-softrender-window"
|
||||
#else
|
||||
|
||||
#define WINDOW_NAME "4coder-window"
|
||||
#endif
|
||||
|
||||
HWND window_handle = {};
|
||||
window_handle = CreateWindowA(
|
||||
|
@ -1146,30 +1118,7 @@ WinMain(HINSTANCE hInstance,
|
|||
HDC hdc = GetDC(window_handle);
|
||||
|
||||
GetClientRect(window_handle, &window_rect);
|
||||
|
||||
#if SOFTWARE_RENDER
|
||||
win32vars.width = window_rect.right - window_rect.left;
|
||||
win32vars.height = window_rect.bottom - window_rect.top;
|
||||
|
||||
win32vars.pitch = win32vars.width*4;
|
||||
#define bmi_header win32vars.bmp_info.bmiHeader
|
||||
bmi_header = {};
|
||||
bmi_header.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bmi_header.biWidth = win32vars.width;
|
||||
bmi_header.biHeight = win32vars.height;
|
||||
bmi_header.biPlanes = 1;
|
||||
bmi_header.biBitCount = 32;
|
||||
bmi_header.biCompression = BI_RGB;
|
||||
#undef bmi_header
|
||||
|
||||
win32vars.true_pixel_size = win32vars.height*win32vars.pitch;
|
||||
win32vars.pixel_data = system_get_memory(win32vars.true_pixel_size);
|
||||
|
||||
if (!win32vars.pixel_data){
|
||||
return 3;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static PIXELFORMATDESCRIPTOR pfd = {
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
1,
|
||||
|
@ -1204,7 +1153,6 @@ WinMain(HINSTANCE hInstance,
|
|||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
Win32Resize(window_rect.right - window_rect.left, window_rect.bottom - window_rect.top);
|
||||
#endif
|
||||
|
||||
LPVOID base;
|
||||
#if FRED_INTERNAL
|
||||
|
@ -1261,8 +1209,16 @@ WinMain(HINSTANCE hInstance,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
win32vars.target.push_clip = draw_push_clip;
|
||||
win32vars.target.pop_clip = draw_pop_clip;
|
||||
win32vars.target.push_piece = draw_push_piece;
|
||||
win32vars.target.font_load = draw_font_load;
|
||||
|
||||
win32vars.target.max = Mbytes(1);
|
||||
win32vars.target.push_buffer = (byte*)system_get_memory(win32vars.target.max);
|
||||
|
||||
if (!win32vars.app.init(win32vars.system,
|
||||
if (!win32vars.app.init(win32vars.system, &win32vars.target,
|
||||
&win32memory, &win32vars.key_codes,
|
||||
win32vars.clipboard_contents, win32vars.config_api)){
|
||||
return 5;
|
||||
|
@ -1329,24 +1285,20 @@ WinMain(HINSTANCE hInstance,
|
|||
b32 caps_lock = win32vars.input_data.caps_lock;
|
||||
for (i32 i = 0; i < win32vars.input_data.press_count; ++i){
|
||||
i16 keycode = win32vars.input_data.press[i].keycode;
|
||||
win32vars.input_data.press[i].character =
|
||||
keycode_to_character_ascii(&win32vars.key_codes, keycode,
|
||||
shift, caps_lock);
|
||||
|
||||
win32vars.input_data.press[i].character =
|
||||
translate_key(keycode, shift, caps_lock);
|
||||
win32vars.input_data.press[i].character_no_caps_lock =
|
||||
keycode_to_character_ascii(&win32vars.key_codes, keycode,
|
||||
shift, 0);
|
||||
translate_key(keycode, shift, 0);
|
||||
}
|
||||
|
||||
for (i32 i = 0; i < win32vars.input_data.hold_count; ++i){
|
||||
i16 keycode = win32vars.input_data.hold[i].keycode;
|
||||
|
||||
win32vars.input_data.hold[i].character =
|
||||
keycode_to_character_ascii(&win32vars.key_codes, keycode,
|
||||
shift, caps_lock);
|
||||
|
||||
translate_key(keycode, shift, caps_lock);
|
||||
win32vars.input_data.hold[i].character_no_caps_lock =
|
||||
keycode_to_character_ascii(&win32vars.key_codes, keycode,
|
||||
shift, 0);
|
||||
translate_key(keycode, shift, 0);
|
||||
}
|
||||
|
||||
win32vars.clipboard_contents = {};
|
||||
|
@ -1392,13 +1344,10 @@ WinMain(HINSTANCE hInstance,
|
|||
switch (result.mouse_cursor_type){
|
||||
case APP_MOUSE_CURSOR_ARROW:
|
||||
SetCursor(win32vars.cursor_arrow); break;
|
||||
|
||||
case APP_MOUSE_CURSOR_IBEAM:
|
||||
SetCursor(win32vars.cursor_ibeam); break;
|
||||
|
||||
case APP_MOUSE_CURSOR_LEFTRIGHT:
|
||||
SetCursor(win32vars.cursor_leftright); break;
|
||||
|
||||
case APP_MOUSE_CURSOR_UPDOWN:
|
||||
SetCursor(win32vars.cursor_updown); break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue