Merged macos platform layer branch into master; building on windows

master
Allen Webster 2020-01-16 18:26:19 -08:00
commit 9e72096bdf
41 changed files with 6666 additions and 1886 deletions

View File

@ -453,7 +453,7 @@ buffer_line_y_difference(Application_Links *app, Buffer_ID buffer_id,
i64 line_a, i64 line_b){
Models *models = (Models*)app->cmd_context;
Editing_File *file = imp_get_file(models, buffer_id);
f32 result = {};
f32 result = 0.0f;
if (api_check_buffer(file)){
Face *face = font_set_face_from_id(&models->font_set, face_id);
if (face != 0){
@ -544,7 +544,7 @@ buffer_relative_character_from_pos(Application_Links *app, Buffer_ID buffer_id,
{
Models *models = (Models*)app->cmd_context;
Editing_File *file = imp_get_file(models, buffer_id);
i64 result = {};
i64 result = 0;
if (api_check_buffer(file)){
Face *face = font_set_face_from_id(&models->font_set, face_id);
if (face != 0){
@ -580,7 +580,7 @@ api(custom) function f32
view_line_y_difference(Application_Links *app, View_ID view_id, i64 line_a, i64 line_b){
Models *models = (Models*)app->cmd_context;
View *view = imp_get_view(models, view_id);
f32 result = {};
f32 result = 0.0f;
if (api_check_view(view)){
result = view_line_y_difference(app->tctx, models, view, line_a, line_b);
}
@ -635,7 +635,7 @@ api(custom) function i64
view_relative_character_from_pos(Application_Links *app, View_ID view_id, i64 base_line, i64 pos){
Models *models = (Models*)app->cmd_context;
View *view = imp_get_view(models, view_id);
i64 result = {};
i64 result = 0;
if (api_check_view(view)){
result = view_relative_character_from_pos(app->tctx, models, view, base_line, pos);
}
@ -646,7 +646,7 @@ api(custom) function i64
view_pos_from_relative_character(Application_Links *app, View_ID view_id, i64 base_line, i64 character){
Models *models = (Models*)app->cmd_context;
View *view = imp_get_view(models, view_id);
i64 result = {};
i64 result = 0;
if (api_check_view(view)){
result = view_pos_from_relative_character(app->tctx, models, view, base_line, character);
}
@ -730,7 +730,7 @@ api(custom) function Dirty_State
buffer_get_dirty_state(Application_Links *app, Buffer_ID buffer_id){
Models *models = (Models*)app->cmd_context;
Editing_File *file = imp_get_file(models, buffer_id);
Dirty_State result = {};
Dirty_State result = 0;
if (api_check_buffer(file)){
result = file->state.dirty;
}
@ -2814,7 +2814,7 @@ api(custom) function Text_Layout_ID
text_layout_create(Application_Links *app, Buffer_ID buffer_id, Rect_f32 rect, Buffer_Point buffer_point){
Models *models = (Models*)app->cmd_context;
Editing_File *file = imp_get_file(models, buffer_id);
Text_Layout_ID result = {};
Text_Layout_ID result = 0;
if (api_check_buffer(file)){
Thread_Context *tctx = app->tctx;
Scratch_Block scratch(tctx);
@ -2962,7 +2962,7 @@ text_layout_character_on_screen(Application_Links *app, Text_Layout_ID layout_id
y += line.height;
}
// TODO(allen): optimization: This is some fairly heavy computation. We really
// TODO(allen): optimization: This is some fairly heavy computation. We really
// need to accelerate the (pos -> item) lookup within a single
// Buffer_Layout_Item_List.
b32 is_first_item = true;

View File

@ -658,7 +658,7 @@ buffer_get_pos_range_from_line_number(Gap_Buffer *buffer, i64 line_number){
internal i64
buffer_get_first_pos_from_line_number(Gap_Buffer *buffer, i64 line_number){
i64 result = {};
i64 result = 0;
if (line_number < 1){
result = 0;
}
@ -673,7 +673,7 @@ buffer_get_first_pos_from_line_number(Gap_Buffer *buffer, i64 line_number){
internal i64
buffer_get_last_pos_from_line_number(Gap_Buffer *buffer, i64 line_number){
i64 result = {};
i64 result = 0;
if (line_number < 1){
result = 0;
}

View File

@ -125,7 +125,7 @@ find_all_matches_forward(Arena *arena, i32 maximum_output_count,
jump_back_0:
if (n + 1 == needle.size){
String_Match_Flag flags = {};
String_Match_Flag flags = 0;
if (!(last_insensitive >= 0 &&
j <= (u64)last_insensitive &&
(u64)last_insensitive < j + needle.size)){
@ -245,7 +245,7 @@ find_all_matches_backward(Arena *arena, i32 maximum_output_count,
jump_back_0:
if (n + 1 == needle.size){
String_Match_Flag flags = {};
String_Match_Flag flags = 0;
if (!(last_insensitive < size &&
j >= last_insensitive &&
last_insensitive > j - (i64)needle.size)){

View File

@ -43,6 +43,7 @@ char *platform_names[] = {
enum{
Compiler_CL,
Compiler_GCC,
Compiler_Clang,
//
Compiler_COUNT,
Compiler_None = Compiler_COUNT,
@ -51,6 +52,7 @@ enum{
char *compiler_names[] = {
"cl",
"gcc",
"clang",
};
#if OS_WINDOWS
@ -67,6 +69,11 @@ char *compiler_names[] = {
# define This_Compiler Compiler_CL
#elif COMPILER_GCC
# define This_Compiler Compiler_GCC
<<<<<<< HEAD
=======
#elif COMPILER_CLANG
# define This_Compiler Compiler_Clang
>>>>>>> yuval_macos_platform_layer
#else
# error This compilers is not enumerated.
#endif
@ -90,7 +97,7 @@ char *includes[] = { "custom", FOREIGN "/freetype2", 0, };
char *windows_platform_layer[] = { "platform_win32/win32_4ed.cpp", 0 };
char *linux_platform_layer[] = { "platform_linux/linux_4ed.cpp", 0 };
char *mac_platform_layer[] = { "platform_mac/mac_4ed.m", "platform_mac/mac_4ed.cpp", 0 };
char *mac_platform_layer[] = { "platform_mac/mac_4ed.mm", 0 };
char **platform_layers[Platform_COUNT] = {
windows_platform_layer,
@ -100,12 +107,13 @@ char **platform_layers[Platform_COUNT] = {
char *windows_cl_platform_inc[] = { "platform_all", 0 };
char *linux_gcc_platform_inc[] = { "platform_all", "platform_unix", 0 };
char *mac_gcc_platform_inc[] = { "platform_all", "platform_unix", 0 };
char *mac_clang_platform_inc[] = { "platform_all", "platform_unix", 0 };
char **platform_includes[Platform_COUNT][Compiler_COUNT] = {
{windows_cl_platform_inc, 0 },
{0 , linux_gcc_platform_inc},
{0 , mac_gcc_platform_inc },
{windows_cl_platform_inc, 0 , 0},
{0 , linux_gcc_platform_inc, 0},
{0 , 0 , mac_clang_platform_inc},
};
char *default_custom_target = "../code/custom/4coder_default_bindings.cpp";
@ -298,6 +306,7 @@ build(Arena *arena, u32 flags, u32 arch, char *code_path, char **code_files, cha
#define GCC_LIBS_X64 GCC_LIBS_COMMON
#define GCC_LIBS_X86 GCC_LIBS_COMMON
<<<<<<< HEAD
#elif OS_MAC
# define GCC_OPTS \
@ -317,6 +326,9 @@ FOREIGN "/x64/libfreetype-mac.a"
#define GCC_LIBS_X86 GCC_LIBS_COMMON \
FOREIGN "/x86/libfreetype-mac.a"
#else
# error gcc options not set for this platform
=======
#else
# error gcc options not set for this platform
#endif
@ -391,6 +403,120 @@ build(Arena *arena, u32 flags, u32 arch, char *code_path, char **code_files, cha
fm_popdir(temp);
}
#elif COMPILER_CLANG
#if OS_MAC
# define CLANG_OPTS \
"-Wno-write-strings -Wno-deprecated-declarations " \
"-Wno-comment -Wno-switch -Wno-null-dereference " \
"-Wno-tautological-compare -Wno-unused-result " \
"-Wno-missing-declarations -Wno-nullability-completeness " \
"-std=c++11 "
#define CLANG_LIBS_COMMON \
"-framework Cocoa -framework QuartzCore " \
"-framework CoreServices " \
"-framework OpenGL -framework IOKit -framework Metal -framework MetalKit "
#define CLANG_LIBS_X64 CLANG_LIBS_COMMON \
FOREIGN "/x64/libfreetype-mac.a"
#define CLANG_LIBS_X86 CLANG_LIBS_COMMON \
FOREIGN "/x86/libfreetype-mac.a"
#else
# error clang options not set for this platform
>>>>>>> yuval_macos_platform_layer
#endif
internal void
build(Arena *arena, u32 flags, u32 arch, char *code_path, char **code_files, char *out_path, char *out_file, char **defines, char **exports, char **inc_folders){
Build_Line line;
fm_init_build_line(&line);
switch (arch){
case Arch_X64:
fm_add_to_line(line, "-m64");
fm_add_to_line(line, "-DFTECH_64_BIT"); break;
case Arch_X86:
fm_add_to_line(line, "-m32");
fm_add_to_line(line, "-DFTECH_32_BIT"); break;
default: InvalidPath;
}
if (flags & OPTS){
<<<<<<< HEAD
fm_add_to_line(line, GCC_OPTS);
=======
fm_add_to_line(line, CLANG_OPTS);
>>>>>>> yuval_macos_platform_layer
}
fm_add_to_line(line, "-I%s", code_path);
if (inc_folders != 0){
for (u32 i = 0; inc_folders[i] != 0; ++i){
char *str = fm_str(arena, code_path, "/", inc_folders[i]);
fm_add_to_line(line, "-I%s", str);
}
}
if (flags & DEBUG_INFO){
fm_add_to_line(line, "-g -O0");
}
if (flags & OPTIMIZATION){
fm_add_to_line(line, "-O3");
}
if (flags & SHARED_CODE){
fm_add_to_line(line, "-shared");
}
if (defines != 0){
for (u32 i = 0; defines[i]; ++i){
char *define_flag = fm_str(arena, "-D", defines[i]);
fm_add_to_line(line, "%s", define_flag);
}
}
fm_add_to_line(line, "-I\"%s\"", code_path);
for (u32 i = 0; code_files[i] != 0; ++i){
fm_add_to_line(line, "\"%s/%s\"", code_path, code_files[i]);
}
if (flags & LIBS){
if (arch == Arch_X64){
<<<<<<< HEAD
fm_add_to_line(line, GCC_LIBS_X64);
}
else if (arch == Arch_X86)
{
fm_add_to_line(line, GCC_LIBS_X86);
=======
fm_add_to_line(line, CLANG_LIBS_X64);
}
else if (arch == Arch_X86)
{
fm_add_to_line(line, CLANG_LIBS_X86);
>>>>>>> yuval_macos_platform_layer
}
}
fm_finish_build_line(&line);
Temp_Dir temp = fm_pushdir(out_path);
<<<<<<< HEAD
systemf("g++ %s -o %s", line.build_options, out_file);
=======
// systemf("clang++ %s -E -o %s", line.build_options, "4ed.i");
systemf("clang++ %s -o %s", line.build_options, out_file);
>>>>>>> yuval_macos_platform_layer
fm_popdir(temp);
}
#else
# error build function not defined for this compiler
#endif
@ -427,7 +553,11 @@ buildsuper(Arena *arena, char *cdir, char *file, u32 arch){
BEGIN_TIME_SECTION();
Temp_Dir temp = fm_pushdir(fm_str(arena, BUILD_DIR));
char *build_script = fm_str(arena, "custom/bin/buildsuper_", arch_names[arch], BAT);
char *build_script_postfix = "";
if (This_OS == Platform_Mac){
build_script_postfix = "-mac";
}
char *build_script = fm_str(arena, "custom/bin/buildsuper_", arch_names[arch], build_script_postfix, BAT);
char *build_command = fm_str(arena, "\"", cdir, "/", build_script, "\" \"", file, "\"");
if (This_OS == Platform_Windows){
@ -584,10 +714,10 @@ int main(int argc, char **argv){
Assert(n < sizeof(cdir));
END_TIME_SECTION("current directory");
u32 flags = DEBUG_INFO | SUPER;
u32 flags = SUPER;
u32 arch = Arch_X64;
#if defined(DEV_BUILD) || defined(DEV_BUILD_X86)
flags |= INTERNAL;
flags |= DEBUG_INFO | INTERNAL;
#endif
#if defined(OPT_BUILD) || defined(OPT_BUILD_X86)
flags |= OPTIMIZATION;

43
bin/build-mac.sh Executable file
View File

@ -0,0 +1,43 @@
#!/bin/bash
# If any command errors, stop the script
set -e
# Set up directories (mirrors build.bat)
# NOTE(yuval): Replaced readlink with realpath which works for both macOS and Linux
ME="$(realpath "$0")"
LOCATION="$(dirname "$ME")"
SRC_ROOT="$(dirname "$LOCATION")"
PROJECT_ROOT="$(dirname "$SRC_ROOT")"
if [ ! -d "$PROJECT_ROOT/build" ]; then
mkdir "$PROJECT_ROOT/build"
fi
BUILD_ROOT="$PROJECT_ROOT/build"
BIN_ROOT="$SRC_ROOT/bin"
CUSTOM_ROOT="$SRC_ROOT/custom"
CUSTOM_BIN="$CUSTOM_ROOT/bin"
# Get the build mode
BUILD_MODE="$1"
if [ -z "$BUILD_MODE" ]; then
BUILD_MODE="-DDEV_BUILD"
fi
# Get the OS specific flags
chmod +rx "$BIN_ROOT/detect_os.sh"
os=$("$BIN_ROOT/detect_os.sh")
if [[ "$os" == "linux" ]]; then
WARNINGS="-Wno-write-strings -Wno-comment"
elif [[ "$os" == "mac" ]]; then
WARNINGS="-Wno-write-strings -Wno-comment -Wno-null-dereference -Wno-logical-op-parentheses -Wno-switch"
fi
FLAGS="-D_GNU_SOURCE -fPIC -fpermissive $BUILD_MODE"
INCLUDES="-I$SRC_ROOT -I$CUSTOM_ROOT"
# Execute
clang++ $WARNINGS $FLAGS $INCLUDES "$BIN_ROOT/4ed_build.cpp" -g -o "$BUILD_ROOT/build"
pushd "$SRC_ROOT"
"$BUILD_ROOT/build"
popd

5
bin/build_x86-mac.sh Normal file
View File

@ -0,0 +1,5 @@
#!/bin/bash
./build.sh -DDEV_BUILD_X86

View File

@ -1727,7 +1727,7 @@ Ii32_size(i32 pos, i32 size){
function Range_i64
Ii64_size(i64 pos, i64 size){
return(Ii64(pos, pos + size));
}
}
function Range_u64
Iu64_size(u64 pos, u64 size){
return(Iu64(pos, pos + size));
@ -6967,10 +6967,10 @@ global_const u8 integer_symbol_reverse[128] = {
global_const u8 base64[64] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'_', '$',
};
@ -6987,7 +6987,7 @@ global_const u8 base64_reverse[128] = {
function u64
digit_count_from_integer(u64 x, u32 radix){
u64 result = {};
u64 result = 0;
if (radix >= 2 && radix <= 16){
if (x == 0){
result = 1;

View File

@ -31,14 +31,34 @@
# error architecture not supported yet
# endif
#elif defined(__clang__)
# define COMPILER_CLANG 1
# if defined(__APPLE__) && defined(__MACH__)
# define OS_MAC 1
# else
# error This compiler/platform combo is not supported yet
# endif
# if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
# define ARCH_X64 1
# elif defined(i386) || defined(__i386) || defined(__i386__)
# define ARCH_X86 1
# elif defined(__aarch64__)
# define ARCH_ARM64 1
# elif defined(__arm__)
# define ARCH_ARM32 1
# else
# error architecture not supported yet
# endif
#elif defined(__GNUC__) || defined(__GNUG__)
# define COMPILER_GCC 1
# if defined(__gnu_linux__)
# define OS_LINUX 1
# elif defined(__APPLE__) && defined(__MACH__)
# define OS_MAC 1
# else
# error This compiler/platform combo is not supported yet
# endif
@ -92,6 +112,9 @@
#if !defined(COMPILER_GCC)
#define COMPILER_GCC 0
#endif
#if !defined(COMPILER_CLANG)
#define COMPILER_CLANG 0
#endif
#if !defined(OS_WINDOWS)
#define OS_WINDOWS 0
#endif
@ -121,12 +144,11 @@
#endif
#endif
#if OS_WINDOWS
# if ARCH_32BIT
# define CALL_CONVENTION __stdcall
# else
# define CALL_CONVENTION
# endif
// NOTE(yuval): Changed this so that CALL_CONVENTION will be defined for all platforms
#if ARCH_32BIT
# define CALL_CONVENTION __stdcall
#else
# define CALL_CONVENTION
#endif
#if defined(JUST_GUESS_INTS)
@ -834,7 +856,7 @@ enum{
struct String_Const_char{
char *str;
u64 size;
u64 size;
};
struct String_Const_u8{
union{
@ -922,25 +944,25 @@ struct Node_String_Const_u32{
struct List_String_Const_char{
Node_String_Const_char *first;
Node_String_Const_char *last;
u64 total_size;
u64 total_size;
i32 node_count;
};
struct List_String_Const_u8{
Node_String_Const_u8 *first;
Node_String_Const_u8 *last;
u64 total_size;
u64 total_size;
i32 node_count;
};
struct List_String_Const_u16{
Node_String_Const_u16 *first;
Node_String_Const_u16 *last;
u64 total_size;
u64 total_size;
i32 node_count;
};
struct List_String_Const_u32{
Node_String_Const_u32 *first;
Node_String_Const_u32 *last;
u64 total_size;
u64 total_size;
i32 node_count;
};
@ -951,7 +973,7 @@ struct Node_String_Const_Any{
struct List_String_Const_Any{
Node_String_Const_Any *first;
Node_String_Const_Any *last;
u64 total_size;
u64 total_size;
i32 node_count;
};
@ -960,40 +982,40 @@ struct String_char{
String_Const_char string;
struct{
char *str;
u64 size;
u64 size;
};
};
u64 cap;
u64 cap;
};
struct String_u8{
union{
String_Const_u8 string;
struct{
u8 *str;
u64 size;
u64 size;
};
};
u64 cap;
u64 cap;
};
struct String_u16{
union{
String_Const_u16 string;
struct{
u16 *str;
u64 size;
u64 size;
};
};
u64 cap;
u64 cap;
};
struct String_u32{
union{
String_Const_u32 string;
struct{
u32 *str;
u64 size;
u64 size;
};
};
u64 cap;
u64 cap;
};
struct String_Any{
@ -1001,8 +1023,8 @@ struct String_Any{
union{
struct{
void *str;
u64 size;
u64 cap;
u64 size;
u64 cap;
};
String_char s_char;
String_u8 s_u8;
@ -1089,7 +1111,7 @@ struct Base_Allocator{
struct Cursor{
u8 *base;
u64 pos;
u64 pos;
u64 cap;
};
struct Temp_Memory_Cursor{
@ -1229,7 +1251,7 @@ struct Heap_Node{
struct{
Heap_Basic_Node order;
Heap_Basic_Node alloc;
u64 size;
u64 size;
};
u8 force_size__[64];
};
@ -1240,8 +1262,8 @@ struct Heap{
Arena *arena;
Heap_Basic_Node in_order;
Heap_Basic_Node free_nodes;
u64 used_space;
u64 total_space;
u64 used_space;
u64 total_space;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -425,21 +425,21 @@ function Command_Trigger_List
map_get_triggers_recursive(Arena *arena, Mapping *mapping, Command_Map *map, Command_Binding binding){
Command_Trigger_List result = {};
if (mapping != 0){
for (i32 safety_counter = 0;
map != 0 && safety_counter < 40;
safety_counter += 1){
Command_Trigger_List list = map_get_triggers_non_recursive(mapping, map, binding);
for (Command_Trigger *node = list.first, *next = 0;
node != 0;
node = next){
next = node->next;
Command_Trigger *nnode = push_array_write(arena, Command_Trigger, 1, node);
sll_queue_push(result.first, result.last, nnode);
for (i32 safety_counter = 0;
map != 0 && safety_counter < 40;
safety_counter += 1){
Command_Trigger_List list = map_get_triggers_non_recursive(mapping, map, binding);
for (Command_Trigger *node = list.first, *next = 0;
node != 0;
node = next){
next = node->next;
Command_Trigger *nnode = push_array_write(arena, Command_Trigger, 1, node);
sll_queue_push(result.first, result.last, nnode);
}
map = mapping_get_map(mapping, map->parent);
}
map = mapping_get_map(mapping, map->parent);
}
}
return(result);
}
@ -721,7 +721,7 @@ map_set_binding_l(Mapping *mapping, Command_Map *map, Custom_Command_Function *c
va_start(args, code2);
Command_Binding binding = {};
binding.custom = custom;
map_set_binding_lv(mapping, map, binding, code1, code2, args);
map_set_binding_lv(mapping, map, binding, code1, code2, args);
va_end(args);
}
#endif
@ -755,7 +755,7 @@ map_set_binding_l(m, map, BindFWrap_(F), InputEventKind_MouseMove, 0, __VA_ARGS_
#define BindCore(F, K, ...) \
map_set_binding_l(m, map, BindFWrap_(F), InputEventKind_Core, (K), __VA_ARGS__, 0)
#elif COMPILER_GCC
#elif COMPILER_GCC | COMPILER_CLANG
#define Bind(F, K, ...) \
map_set_binding_l(m, map, BindFWrap_(F), InputEventKind_KeyStroke, (K), ##__VA_ARGS__, 0)

View File

@ -40,7 +40,7 @@ draw_string(Application_Links *app, Face_ID font_id, String_Const_u8 string, Vec
function Vec2_f32
draw_string(Application_Links *app, Face_ID font_id, String_Const_u8 string, Vec2_f32 p, FColor color){
ARGB_Color argb = fcolor_resolve(color);
draw_string(app, font_id, string, p, argb);
return(draw_string(app, font_id, string, p, argb));
}
function void
@ -356,7 +356,7 @@ draw_line_number_margin(Application_Links *app, View_ID view_id, Buffer_ID buffe
Vec2_f32 p = V2f32(margin.x0, line_y.min);
Temp_Memory_Block temp(scratch);
Fancy_String *string = push_fancy_stringf(scratch, 0, line_color,
"%*lld",
"%*lld",
line_count_digit_count,
line_number);
draw_fancy_string(app, face_id, fcolor_zero(), string, p);
@ -719,6 +719,7 @@ draw_original_4coder_style_cursor_mark_highlight(Application_Links *app, View_ID
b32 has_highlight_range = draw_highlight_range(app, view_id, buffer, text_layout_id, roundness);
if (!has_highlight_range){
i32 cursor_sub_id = default_cursor_sub_id();
i64 cursor_pos = view_get_cursor_pos(app, view_id);
i64 mark_pos = view_get_mark_pos(app, view_id);
if (is_active_view){

View File

@ -347,11 +347,11 @@ function Fancy_String*
push_fancy_string_fixed(Arena *arena, Fancy_Line *line, FColor fore,
String_Const_u8 value, i32 max){
if (value.size <= max){
return(push_fancy_stringf(arena, line, 0, fore, 0.f, 0.f,
return(push_fancy_stringf(arena, line, (Face_ID)0, fore, 0.f, 0.f,
"%-*.*s", max, string_expand(value)));
}
else{
return(push_fancy_stringf(arena, line, 0, fore, 0.f, 0.f,
return(push_fancy_stringf(arena, line, (Face_ID)0, fore, 0.f, 0.f,
"%-*.*s...", max - 3, string_expand(value)));
}
}
@ -360,12 +360,12 @@ push_fancy_string_fixed(Arena *arena, Fancy_Line *line,
f32 pre_margin, f32 post_margin, String_Const_u8 value,
i32 max){
if (value.size <= max){
return(push_fancy_stringf(arena, line, 0, fcolor_zero(),
return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(),
pre_margin, post_margin,
"%-*.*s", max, string_expand(value)));
}
else{
return(push_fancy_stringf(arena, line, 0, fcolor_zero(),
return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(),
pre_margin, post_margin,
"%-*.*s...", max - 3, string_expand(value)));
}
@ -374,11 +374,11 @@ function Fancy_String*
push_fancy_string_fixed(Arena *arena, Fancy_Line *line, String_Const_u8 value,
i32 max){
if (value.size <= max){
return(push_fancy_stringf(arena, line, 0, fcolor_zero(), 0.f, 0.f,
return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(), 0.f, 0.f,
"%-*.*s", max, string_expand(value)));
}
else{
return(push_fancy_stringf(arena, line, 0, fcolor_zero(), 0.f, 0.f,
return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(), 0.f, 0.f,
"%-*.*s...", max - 3, string_expand(value)));
}
}
@ -452,11 +452,11 @@ function Fancy_String*
push_fancy_string_trunc(Arena *arena, Fancy_Line *line, FColor fore,
String_Const_u8 value, i32 max){
if (value.size <= max){
return(push_fancy_stringf(arena, line, 0, fore, 0.f, 0.f,
return(push_fancy_stringf(arena, line, (Face_ID)0, fore, 0.f, 0.f,
"%.*s", string_expand(value)));
}
else{
return(push_fancy_stringf(arena, line, 0, fore, 0.f, 0.f,
return(push_fancy_stringf(arena, line, (Face_ID)0, fore, 0.f, 0.f,
"%.*s...", max - 3, value.str));
}
}
@ -465,12 +465,12 @@ push_fancy_string_trunc(Arena *arena, Fancy_Line *line,
f32 pre_margin, f32 post_margin, String_Const_u8 value,
i32 max){
if (value.size <= max){
return(push_fancy_stringf(arena, line, 0, fcolor_zero(),
return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(),
pre_margin, post_margin,
"%.*s", string_expand(value)));
}
else{
return(push_fancy_stringf(arena, line, 0, fcolor_zero(),
return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(),
pre_margin, post_margin,
"%.*s...", max - 3, value.str));
}
@ -479,11 +479,11 @@ function Fancy_String*
push_fancy_string_trunc(Arena *arena, Fancy_Line *line, String_Const_u8 value,
i32 max){
if (value.size <= max){
return(push_fancy_stringf(arena, line, 0, fcolor_zero(), 0.f, 0.f,
return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(), 0.f, 0.f,
"%.*s", string_expand(value)));
}
else{
return(push_fancy_stringf(arena, line, 0, fcolor_zero(), 0.f, 0.f,
return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(), 0.f, 0.f,
"%.*s...", max - 3, value.str));
}
}
@ -620,7 +620,7 @@ draw_fancy_string__inner(Application_Links *app, Face_ID face, FColor fore, Fanc
use_fore = string->fore;
}
if (use_face != 0){
ARGB_Color use_argb = fcolor_resolve(use_fore);
ARGB_Color use_argb = fcolor_resolve(use_fore);
Face_Metrics metrics = get_face_metrics(app, use_face);
f32 down_shift = (base_line - metrics.ascent);
down_shift = clamp_bot(0.f, down_shift);
@ -668,7 +668,7 @@ get_fancy_string_height(Application_Links *app, Face_ID face,
function f32
get_fancy_string_text_height(Application_Links *app, Face_ID face,
Fancy_String *string){
Fancy_String *string){
Fancy_String *next = string->next;
string->next = 0;
f32 result = get_fancy_string_text_height__inner(app, face, string);
@ -700,10 +700,10 @@ function f32
get_fancy_line_width(Application_Links *app, Face_ID face, Fancy_Line *line){
f32 result = 0.f;
if (line != 0){
if (line->face != 0){
face = line->face;
}
result = get_fancy_string_width__inner(app, face, line->first);
if (line->face != 0){
face = line->face;
}
result = get_fancy_string_width__inner(app, face, line->first);
}
return(result);
}
@ -749,12 +749,12 @@ draw_fancy_line(Application_Links *app, Face_ID face, FColor fore,
Fancy_Line *line, Vec2_f32 p, u32 flags, Vec2_f32 delta){
Vec2_f32 result = {};
if (line != 0){
if (line->face != 0){
face = line->face;
}
if (fcolor_is_valid(line->fore)){
fore = line->fore;
}
if (line->face != 0){
face = line->face;
}
if (fcolor_is_valid(line->fore)){
fore = line->fore;
}
result = draw_fancy_string__inner(app, face, fore, line->first, p, flags, delta);
}
return(result);

View File

@ -115,7 +115,7 @@ internal void fm__swap_ptr(char **A, char **B);
fm__swap_ptr(&line.build_options, &line.build_options_prev); \
}while(0)
#elif COMPILER_GCC
#elif COMPILER_GCC | COMPILER_CLANG
#define fm_add_to_line(line, str, ...) do{ \
snprintf(line.build_options, line.build_max, "%s " str, \
@ -259,9 +259,9 @@ extern "C"{
#define OPEN_ALWAYS 4
#define TRUNCATE_EXISTING 5
#define FILE_ATTRIBUTE_READONLY 0x00000001
#define FILE_ATTRIBUTE_NORMAL 0x00000080
#define FILE_ATTRIBUTE_TEMPORARY 0x00000100
#define FILE_ATTRIBUTE_READONLY 0x00000001
#define FILE_ATTRIBUTE_NORMAL 0x00000080
#define FILE_ATTRIBUTE_TEMPORARY 0x00000100
global u64 perf_frequency;
@ -370,9 +370,9 @@ fm_copy_file(char *file, char *newname){
internal void
fm_copy_all(char *source, char *folder){
fprintf(stdout, "copy %s to %s\n", source, folder);
fflush(stdout);
systemf("xcopy /s /e /y /q %s %s > nul", source, folder);
fprintf(stdout, "copy %s to %s\n", source, folder);
fflush(stdout);
systemf("xcopy /s /e /y /q %s %s > nul", source, folder);
}
internal void

View File

@ -5,7 +5,10 @@
// TOP
#include <stdlib.h>
#include <malloc.h>
#if !OS_MAC
# include <malloc.h>
#endif
internal void*
base_reserve__malloc(void *user_data, u64 size, u64 *size_out, String_Const_u8 location){

View File

@ -54,7 +54,7 @@ struct Color_Array{
api(custom)
struct Color_Table{
Color_Array *arrays;
Color_Array *arrays;
u32 count;
};
@ -742,7 +742,7 @@ struct View_Context{
u64 delta_rule_memory_size;
b32 hides_buffer;
struct Mapping *mapping;
i64 map_id;
i64 map_id;
};
api(custom)
@ -778,4 +778,3 @@ struct Process_State{
};
#endif

View File

@ -0,0 +1,30 @@
#!/bin/bash
# If any command errors, stop the script
set -e
# Store the real CWD
ME="$(realpath "$0")"
LOCATION="$(dirname "$ME")"
CODE_HOME="$(dirname "$LOCATION")"
# Find the most reasonable candidate build file
SOURCE="$1"
if [ -z "$SOURCE" ]; then
SOURCE="$(readlink -f "$CODE_HOME/4coder_default_bindings.cpp")"
fi
# NOTE(yuval): Removed -Wno-writable-strings as it is the same as -Wno-write-strings
opts="-Wno-write-strings -Wno-null-dereference -Wno-comment -Wno-switch -Wno-missing-declarations -Wno-logical-op-parentheses -g"
arch=-m64
preproc_file=4coder_command_metadata.i
meta_macros="-DMETA_PASS"
clang++ -I"$CODE_HOME" $meta_macros $arch $opts $debug -std=gnu++0x "$SOURCE" -E -o $preproc_file
clang++ -I"$CODE_HOME" $opts $debug -std=gnu++0x "$CODE_HOME/4coder_metadata_generator.cpp" -o "$CODE_HOME/metadata_generator"
"$CODE_HOME/metadata_generator" -R "$CODE_HOME" "$PWD/$preproc_file"
clang++ -I"$CODE_HOME" $arch $opts $debug -std=c++11 "$SOURCE" -shared -o custom_4coder.so -fPIC
rm "$CODE_HOME/metadata_generator"
rm $preproc_file

View File

@ -0,0 +1,53 @@
#!/bin/bash
# Store the real CWD
REAL_PWD="$PWD"
# Find the code home folder
TARGET_FILE="$0"
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
while [ -L "$TARGET_FILE" ]
do
TARGET_FILE=`readlink $TARGET_FILE`
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
done
PHYS_DIR=`pwd -P`
SCRIPT_FILE=$PHYS_DIR/$TARGET_FILE
code_home=$(dirname "$SCRIPT_FILE")
# Find the most reasonable candidate build file
SOURCE="$1"
if [ -z "$SOURCE" ]; then
SOURCE="$code_home/4coder_default_bindings.cpp"
fi
TARGET_FILE="$SOURCE"
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
while [ -L "$TARGET_FILE" ]
do
TARGET_FILE=`readlink $TARGET_FILE`
cd `dirname $TARGET_FILE`
TARGET_FILE=`basename $TARGET_FILE`
done
PHYS_DIR=`pwd -P`
SOURCE=$PHYS_DIR/$TARGET_FILE
# NOTE(yuval): Removed -Wno-writable-strings as it is the same as -Wno-write-strings
opts="-Wno-write-strings -Wno-null-dereference -Wno-comment -Wno-switch -g"
arch=-m32
cd "$REAL_PWD"
preproc_file=4coder_command_metadata.i
meta_macros="-DMETA_PASS"
g++ -I"$code_home" $meta_macros $arch $opts $debug -std=gnu++0x "$SOURCE" -E -o $preproc_file
g++ -I"$code_home" $opts $debug -std=gnu++0x "$code_home/4coder_metadata_generator.cpp" -o metadata_generator
./metadata_generator -R "$code_home" "$PWD/$preproc_file"
g++ -I"$code_home" $arch $opts $debug -std=gnu++0x "$SOURCE" -shared -o custom_4coder.so -fPIC
rm metadata_generator
rm $preproc_file

View File

@ -1,212 +1,212 @@
enum{
KeyCode_A = 1,
KeyCode_B = 2,
KeyCode_C = 3,
KeyCode_D = 4,
KeyCode_E = 5,
KeyCode_F = 6,
KeyCode_G = 7,
KeyCode_H = 8,
KeyCode_I = 9,
KeyCode_J = 10,
KeyCode_K = 11,
KeyCode_L = 12,
KeyCode_M = 13,
KeyCode_N = 14,
KeyCode_O = 15,
KeyCode_P = 16,
KeyCode_Q = 17,
KeyCode_R = 18,
KeyCode_S = 19,
KeyCode_T = 20,
KeyCode_U = 21,
KeyCode_V = 22,
KeyCode_W = 23,
KeyCode_X = 24,
KeyCode_Y = 25,
KeyCode_Z = 26,
KeyCode_0 = 27,
KeyCode_1 = 28,
KeyCode_2 = 29,
KeyCode_3 = 30,
KeyCode_4 = 31,
KeyCode_5 = 32,
KeyCode_6 = 33,
KeyCode_7 = 34,
KeyCode_8 = 35,
KeyCode_9 = 36,
KeyCode_Space = 37,
KeyCode_Tick = 38,
KeyCode_Minus = 39,
KeyCode_Equal = 40,
KeyCode_LeftBracket = 41,
KeyCode_RightBracket = 42,
KeyCode_Semicolon = 43,
KeyCode_Quote = 44,
KeyCode_Comma = 45,
KeyCode_Period = 46,
KeyCode_ForwardSlash = 47,
KeyCode_BackwardSlash = 48,
KeyCode_Tab = 49,
KeyCode_Escape = 50,
KeyCode_Pause = 51,
KeyCode_Up = 52,
KeyCode_Down = 53,
KeyCode_Left = 54,
KeyCode_Right = 55,
KeyCode_Backspace = 56,
KeyCode_Return = 57,
KeyCode_Delete = 58,
KeyCode_Insert = 59,
KeyCode_Home = 60,
KeyCode_End = 61,
KeyCode_PageUp = 62,
KeyCode_PageDown = 63,
KeyCode_CapsLock = 64,
KeyCode_NumLock = 65,
KeyCode_ScrollLock = 66,
KeyCode_Menu = 67,
KeyCode_Shift = 68,
KeyCode_Control = 69,
KeyCode_Alt = 70,
KeyCode_Command = 71,
KeyCode_F1 = 72,
KeyCode_F2 = 73,
KeyCode_F3 = 74,
KeyCode_F4 = 75,
KeyCode_F5 = 76,
KeyCode_F6 = 77,
KeyCode_F7 = 78,
KeyCode_F8 = 79,
KeyCode_F9 = 80,
KeyCode_F10 = 81,
KeyCode_F11 = 82,
KeyCode_F12 = 83,
KeyCode_F13 = 84,
KeyCode_F14 = 85,
KeyCode_F15 = 86,
KeyCode_F16 = 87,
KeyCode_COUNT = 88,
KeyCode_A = 1,
KeyCode_B = 2,
KeyCode_C = 3,
KeyCode_D = 4,
KeyCode_E = 5,
KeyCode_F = 6,
KeyCode_G = 7,
KeyCode_H = 8,
KeyCode_I = 9,
KeyCode_J = 10,
KeyCode_K = 11,
KeyCode_L = 12,
KeyCode_M = 13,
KeyCode_N = 14,
KeyCode_O = 15,
KeyCode_P = 16,
KeyCode_Q = 17,
KeyCode_R = 18,
KeyCode_S = 19,
KeyCode_T = 20,
KeyCode_U = 21,
KeyCode_V = 22,
KeyCode_W = 23,
KeyCode_X = 24,
KeyCode_Y = 25,
KeyCode_Z = 26,
KeyCode_0 = 27,
KeyCode_1 = 28,
KeyCode_2 = 29,
KeyCode_3 = 30,
KeyCode_4 = 31,
KeyCode_5 = 32,
KeyCode_6 = 33,
KeyCode_7 = 34,
KeyCode_8 = 35,
KeyCode_9 = 36,
KeyCode_Space = 37,
KeyCode_Tick = 38,
KeyCode_Minus = 39,
KeyCode_Equal = 40,
KeyCode_LeftBracket = 41,
KeyCode_RightBracket = 42,
KeyCode_Semicolon = 43,
KeyCode_Quote = 44,
KeyCode_Comma = 45,
KeyCode_Period = 46,
KeyCode_ForwardSlash = 47,
KeyCode_BackwardSlash = 48,
KeyCode_Tab = 49,
KeyCode_Escape = 50,
KeyCode_Pause = 51,
KeyCode_Up = 52,
KeyCode_Down = 53,
KeyCode_Left = 54,
KeyCode_Right = 55,
KeyCode_Backspace = 56,
KeyCode_Return = 57,
KeyCode_Delete = 58,
KeyCode_Insert = 59,
KeyCode_Home = 60,
KeyCode_End = 61,
KeyCode_PageUp = 62,
KeyCode_PageDown = 63,
KeyCode_CapsLock = 64,
KeyCode_NumLock = 65,
KeyCode_ScrollLock = 66,
KeyCode_Menu = 67,
KeyCode_Shift = 68,
KeyCode_Control = 69,
KeyCode_Alt = 70,
KeyCode_Command = 71,
KeyCode_F1 = 72,
KeyCode_F2 = 73,
KeyCode_F3 = 74,
KeyCode_F4 = 75,
KeyCode_F5 = 76,
KeyCode_F6 = 77,
KeyCode_F7 = 78,
KeyCode_F8 = 79,
KeyCode_F9 = 80,
KeyCode_F10 = 81,
KeyCode_F11 = 82,
KeyCode_F12 = 83,
KeyCode_F13 = 84,
KeyCode_F14 = 85,
KeyCode_F15 = 86,
KeyCode_F16 = 87,
KeyCode_COUNT = 88,
};
global char* key_code_name[KeyCode_COUNT] = {
"None",
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"Space",
"Tick",
"Minus",
"Equal",
"LeftBracket",
"RightBracket",
"Semicolon",
"Quote",
"Comma",
"Period",
"ForwardSlash",
"BackwardSlash",
"Tab",
"Escape",
"Pause",
"Up",
"Down",
"Left",
"Right",
"Backspace",
"Return",
"Delete",
"Insert",
"Home",
"End",
"PageUp",
"PageDown",
"CapsLock",
"NumLock",
"ScrollLock",
"Menu",
"Shift",
"Control",
"Alt",
"Command",
"F1",
"F2",
"F3",
"F4",
"F5",
"F6",
"F7",
"F8",
"F9",
"F10",
"F11",
"F12",
"F13",
"F14",
"F15",
"F16",
"None",
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"Space",
"Tick",
"Minus",
"Equal",
"LeftBracket",
"RightBracket",
"Semicolon",
"Quote",
"Comma",
"Period",
"ForwardSlash",
"BackwardSlash",
"Tab",
"Escape",
"Pause",
"Up",
"Down",
"Left",
"Right",
"Backspace",
"Return",
"Delete",
"Insert",
"Home",
"End",
"PageUp",
"PageDown",
"CapsLock",
"NumLock",
"ScrollLock",
"Menu",
"Shift",
"Control",
"Alt",
"Command",
"F1",
"F2",
"F3",
"F4",
"F5",
"F6",
"F7",
"F8",
"F9",
"F10",
"F11",
"F12",
"F13",
"F14",
"F15",
"F16",
};
enum{
MouseCode_Left = 1,
MouseCode_Middle = 2,
MouseCode_Right = 3,
MouseCode_COUNT = 4,
MouseCode_Left = 1,
MouseCode_Middle = 2,
MouseCode_Right = 3,
MouseCode_COUNT = 4,
};
global char* mouse_code_name[MouseCode_COUNT] = {
"None",
"Left",
"Middle",
"Right",
"None",
"Left",
"Middle",
"Right",
};
enum{
CoreCode_Startup = 1,
CoreCode_Animate = 2,
CoreCode_ClickActivateView = 3,
CoreCode_ClickDeactivateView = 4,
CoreCode_TryExit = 5,
CoreCode_FileExternallyModified = 6,
CoreCode_NewClipboardContents = 7,
CoreCode_COUNT = 8,
CoreCode_Startup = 1,
CoreCode_Animate = 2,
CoreCode_ClickActivateView = 3,
CoreCode_ClickDeactivateView = 4,
CoreCode_TryExit = 5,
CoreCode_FileExternallyModified = 6,
CoreCode_NewClipboardContents = 7,
CoreCode_COUNT = 8,
};
global char* core_code_name[CoreCode_COUNT] = {
"None",
"Startup",
"Animate",
"ClickActivateView",
"ClickDeactivateView",
"TryExit",
"FileExternallyModified",
"NewClipboardContents",
"None",
"Startup",
"Animate",
"ClickActivateView",
"ClickDeactivateView",
"TryExit",
"FileExternallyModified",
"NewClipboardContents",
};

View File

@ -43,447 +43,453 @@ lexeme_table_lookup(u64 *hash_array, String_Const_u8 *key_array,
}
#endif
u64 cpp_main_keys_hash_array[121] = {
0x0000000000000000,0x03cf3a59df2800d7,0x31804e296403b305,0x3b709b613539c371,
0x3b709aad95fb97b3,0x0000000000000000,0x14996033a5460d1b,0x3180604229f03e4d,
0x0000000000000000,0x0000000000000000,0x14996033a7e5b03b,0x0000000000000000,
0x03cf3a58ab580caf,0x0000000000000000,0x0000000000000000,0x1901b5d07bbd53e1,
0x3180496d6573ea51,0x0000000000000000,0x0000000000000000,0x0000000000000000,
0x0000000000000000,0x0000000000000000,0x3b709aaa9c896d6b,0xf11624614cefdacf,
0x3b709b7949044f87,0x0000000000000000,0x3b709aaa14b4549f,0xf114e97ba34018a3,
0x3180604229f29813,0x0000000000000000,0x1904509dbde2a353,0x03cf3a596f0f2511,
0x14996033a5507959,0x0000000000000000,0x5f3f9fc0d0a0c93f,0x03cf3a58b58c753b,
0x0000000000000000,0x0000000000000000,0xf10f7eff9095fb23,0x3b709aaa68405a55,
0x3b709b61a18cc255,0x3b709aaa7edd8723,0x0000000000000000,0xc8abc849dbd6ac9f,
0x0000000000000000,0x7e5f4ab862627b7b,0x0000000000000000,0x0000000000000000,
0xf114b8e386ce372d,0x14996033a5580e25,0x0000000000000000,0x14996033a7d21aed,
0x3b709b61a19e76af,0x0000000000000000,0x14996033ab0ae5d3,0x14996033a5509f41,
0x0000000000000000,0x0000000000000000,0x0000000000000000,0x03cf3a58b646fa01,
0xf10e5cfb2d0856c9,0x8d730a2abbb45b53,0x0000000000000000,0x3b709b4626a5db05,
0x0000000000000000,0x03cf3a59de20fa7b,0x0000000000000000,0x14996033a6b2b45f,
0xf10f17d125465a91,0x03cf3a59dfc04c9f,0x5f3f9fc0d0a0ba41,0x0000000000000000,
0x5f3f9fc0d0a6ec81,0x0000000000000000,0x3b709aaa4a86002b,0x0000000000000000,
0x0000000000000000,0x5f3f9fc0d0a00819,0x0000000000000000,0x0000000000000000,
0xc8abc849dbd6adb5,0x0000000000000000,0x0000000000000000,0x0000000000000000,
0x5f3f9fc0d0a0d087,0x0000000000000000,0x0000000000000000,0x31806cea0e7fbb29,
0x0000000000000000,0x0000000000000000,0x31806c8004d41f17,0x3b709b468ffbb151,
0x03cf3a59df3fc9f3,0x1744d2f34117d803,0x0000000000000000,0x0000000000000000,
0x0000000000000000,0x0000000000000000,0x03cf3a596ff8a353,0x0000000000000000,
0x0000000000000000,0x1a21e4856eaac353,0x3b709aaa7cdf92c5,0x0000000000000000,
0x14996033a553c5cb,0x03cf3a58b52cfddd,0x0000000000000000,0x31804dc503d40aab,
0x0a1c76541b3d4ccf,0x9721eca88effbb53,0xf10ea2bb4912c001,0x14996033a54db691,
0x0000000000000000,0xf1165cbc0c8e31e1,0xf10e41346ef0ed11,0x0000000000000000,
0x0000000000000000,0x0000000000000000,0x3b709aaa4b875f33,0xf10f7c240be83eed,
0x0000000000000000,
u64 cpp_main_keys_hash_array[124] = {
0x26092f2f0215ece3,0x0000000000000000,0x5ce5a2eda58b1f23,0xb2d6c5c6769fa3a3,
0xb9ddf454bfe26d23,0x0000000000000000,0xcd0f6cfa687dd553,0x0000000000000000,
0x0000000000000000,0x5ce5a2e0c5100279,0x5ce5a2ede7babb3d,0x0000000000000000,
0x0000000000000000,0x6f6d951cb7cb582d,0x0e10b5f7624a6565,0xf889fe35be4428e3,
0x6f6d951cb404483f,0x26092f2f02f1c5ef,0x0000000000000000,0xe2b3ddb2fb5b2e6b,
0x0000000000000000,0x6f6d951cb4ea937d,0x0000000000000000,0x0000000000000000,
0x0000000000000000,0x0e10b1af23a24eb5,0x5ce5a2f3706ea43f,0x0000000000000000,
0xb2d6ca88b991d451,0xe2b3ddb2fb5a20a9,0x0000000000000000,0x26092f2f02d33cab,
0x0000000000000000,0x0000000000000000,0x5ce5a2e66f839a73,0x0000000000000000,
0x5ce5a2eda5890521,0x0000000000000000,0x6f6d951cb4228ddb,0x6f6d951cba73c8ab,
0xb9ddf454bfe26e41,0xd50b424c05eec7e9,0x8557f78510d2bb43,0x0000000000000000,
0x0000000000000000,0x26092f2f020b132d,0x0000000000000000,0x0000000000000000,
0xe2b3ddb2fb5bc1c9,0x0000000000000000,0x8ef935ae0949ace3,0x0000000000000000,
0x0000000000000000,0x0000000000000000,0x0000000000000000,0x26092f2f02d2781b,
0x26092f2f02e7a15d,0xb2d6c74182f6a66d,0x0000000000000000,0x0000000000000000,
0x0000000000000000,0x0000000000000000,0x0000000000000000,0x26092f2f02e78453,
0xe2b3ddb2fb5bd5b5,0xb2d6c74182f6a7e9,0x0000000000000000,0x0000000000000000,
0xb2d6c6c7361150b5,0x5ce5a2e0b306cde5,0x0000000000000000,0x0000000000000000,
0x0000000000000000,0x0000000000000000,0x5ce5a2e7e5c24db3,0x26092f2f0216583b,
0x0e101bb85ac205ad,0x6f6d951cacb1aa35,0x0000000000000000,0x0000000000000000,
0x0000000000000000,0x5ce5a2e197faf9d9,0xe2b3ddb2fb5baba1,0x6f6d951cba402e7b,
0x26092f2f02e1d2eb,0x0000000000000000,0x73a9345f7aa71363,0x0000000000000000,
0x0e10b66610117f15,0x0000000000000000,0xe95e136b18f58763,0x0e10078c941fcafb,
0x0000000000000000,0x0000000000000000,0x5ce5a2f37530abf3,0xb2d6c68c37b0f1f7,
0x5ce5a2e7e4364fe9,0x5ce5a2f37536698d,0x0000000000000000,0x0000000000000000,
0x5ce5a2e049adcf39,0x0000000000000000,0x0000000000000000,0x0e100efea5987c03,
0x6f6d951c847de2fb,0x0e106caf9da9bbbd,0x0e109bd9232f3723,0x0000000000000000,
0x6f6d951c86ec6929,0x0000000000000000,0x0000000000000000,0x0e114d6868e6156b,
0x6f6d951c8f3e1899,0x0e105b1fdc2b41ad,0xb2d6c5dc5a9a53e5,0x0000000000000000,
0x0000000000000000,0x0000000000000000,0x26092f2f0212aa4b,0x0000000000000000,
0x0000000000000000,0x0000000000000000,0x5ce5a2f37ca36a8b,0xcd1ba7f6b56d6ce3,
};
u8 cpp_main_keys_key_array_1[] = {0x63,0x6c,0x61,0x73,0x73,};
u8 cpp_main_keys_key_array_2[] = {0x74,0x79,0x70,0x65,0x64,0x65,0x66,};
u8 cpp_main_keys_key_array_3[] = {0x64,0x6f,0x75,0x62,0x6c,0x65,};
u8 cpp_main_keys_key_array_4[] = {0x74,0x79,0x70,0x65,0x69,0x64,};
u8 cpp_main_keys_key_array_6[] = {0x6c,0x6f,0x6e,0x67,};
u8 cpp_main_keys_key_array_7[] = {0x61,0x6c,0x69,0x67,0x6e,0x6f,0x66,};
u8 cpp_main_keys_key_array_10[] = {0x74,0x68,0x69,0x73,};
u8 cpp_main_keys_key_array_12[] = {0x73,0x68,0x6f,0x72,0x74,};
u8 cpp_main_keys_key_array_15[] = {0x6e,0x61,0x6d,0x65,0x73,0x70,0x61,0x63,0x65,};
u8 cpp_main_keys_key_array_16[] = {0x70,0x72,0x69,0x76,0x61,0x74,0x65,};
u8 cpp_main_keys_key_array_22[] = {0x70,0x75,0x62,0x6c,0x69,0x63,};
u8 cpp_main_keys_key_array_23[] = {0x6e,0x6f,0x65,0x78,0x63,0x65,0x70,0x74,};
u8 cpp_main_keys_key_array_24[] = {0x66,0x72,0x69,0x65,0x6e,0x64,};
u8 cpp_main_keys_key_array_0[] = {0x74,0x72,0x75,0x65,};
u8 cpp_main_keys_key_array_2[] = {0x73,0x69,0x67,0x6e,0x65,0x64,};
u8 cpp_main_keys_key_array_3[] = {0x76,0x69,0x72,0x74,0x75,0x61,0x6c,};
u8 cpp_main_keys_key_array_4[] = {0x64,0x6f,};
u8 cpp_main_keys_key_array_6[] = {0x70,0x72,0x6f,0x74,0x65,0x63,0x74,0x65,0x64,};
u8 cpp_main_keys_key_array_9[] = {0x64,0x6f,0x75,0x62,0x6c,0x65,};
u8 cpp_main_keys_key_array_10[] = {0x70,0x75,0x62,0x6c,0x69,0x63,};
u8 cpp_main_keys_key_array_13[] = {0x63,0x6c,0x61,0x73,0x73,};
u8 cpp_main_keys_key_array_14[] = {0x74,0x65,0x6d,0x70,0x6c,0x61,0x74,0x65,};
u8 cpp_main_keys_key_array_15[] = {0x73,0x74,0x61,0x74,0x69,0x63,0x5f,0x63,0x61,0x73,0x74,};
u8 cpp_main_keys_key_array_16[] = {0x63,0x61,0x74,0x63,0x68,};
u8 cpp_main_keys_key_array_17[] = {0x67,0x6f,0x74,0x6f,};
u8 cpp_main_keys_key_array_19[] = {0x61,0x73,0x6d,};
u8 cpp_main_keys_key_array_21[] = {0x62,0x72,0x65,0x61,0x6b,};
u8 cpp_main_keys_key_array_25[] = {0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,};
u8 cpp_main_keys_key_array_26[] = {0x73,0x77,0x69,0x74,0x63,0x68,};
u8 cpp_main_keys_key_array_27[] = {0x65,0x78,0x70,0x6c,0x69,0x63,0x69,0x74,};
u8 cpp_main_keys_key_array_28[] = {0x61,0x6c,0x69,0x67,0x6e,0x61,0x73,};
u8 cpp_main_keys_key_array_30[] = {0x73,0x74,0x61,0x74,0x69,0x63,0x5f,0x63,0x61,0x73,0x74,};
u8 cpp_main_keys_key_array_31[] = {0x66,0x61,0x6c,0x73,0x65,};
u8 cpp_main_keys_key_array_32[] = {0x63,0x68,0x61,0x72,};
u8 cpp_main_keys_key_array_34[] = {0x6e,0x65,0x77,};
u8 cpp_main_keys_key_array_35[] = {0x75,0x73,0x69,0x6e,0x67,};
u8 cpp_main_keys_key_array_38[] = {0x75,0x6e,0x73,0x69,0x67,0x6e,0x65,0x64,};
u8 cpp_main_keys_key_array_39[] = {0x72,0x65,0x74,0x75,0x72,0x6e,};
u8 cpp_main_keys_key_array_40[] = {0x65,0x78,0x74,0x65,0x72,0x6e,};
u8 cpp_main_keys_key_array_41[] = {0x73,0x69,0x67,0x6e,0x65,0x64,};
u8 cpp_main_keys_key_array_43[] = {0x64,0x6f,};
u8 cpp_main_keys_key_array_45[] = {0x74,0x68,0x72,0x65,0x61,0x64,0x5f,0x6c,0x6f,0x63,0x61,0x6c,};
u8 cpp_main_keys_key_array_48[] = {0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,};
u8 cpp_main_keys_key_array_49[] = {0x65,0x6e,0x75,0x6d,};
u8 cpp_main_keys_key_array_51[] = {0x74,0x72,0x75,0x65,};
u8 cpp_main_keys_key_array_52[] = {0x65,0x78,0x70,0x6f,0x72,0x74,};
u8 cpp_main_keys_key_array_54[] = {0x76,0x6f,0x69,0x64,};
u8 cpp_main_keys_key_array_55[] = {0x63,0x61,0x73,0x65,};
u8 cpp_main_keys_key_array_59[] = {0x77,0x68,0x69,0x6c,0x65,};
u8 cpp_main_keys_key_array_60[] = {0x6f,0x70,0x65,0x72,0x61,0x74,0x6f,0x72,};
u8 cpp_main_keys_key_array_61[] = {0x63,0x6f,0x6e,0x73,0x74,0x5f,0x63,0x61,0x73,0x74,};
u8 cpp_main_keys_key_array_63[] = {0x69,0x6e,0x6c,0x69,0x6e,0x65,};
u8 cpp_main_keys_key_array_65[] = {0x62,0x72,0x65,0x61,0x6b,};
u8 cpp_main_keys_key_array_67[] = {0x67,0x6f,0x74,0x6f,};
u8 cpp_main_keys_key_array_68[] = {0x74,0x65,0x6d,0x70,0x6c,0x61,0x74,0x65,};
u8 cpp_main_keys_key_array_69[] = {0x63,0x61,0x74,0x63,0x68,};
u8 cpp_main_keys_key_array_70[] = {0x66,0x6f,0x72,};
u8 cpp_main_keys_key_array_72[] = {0x74,0x72,0x79,};
u8 cpp_main_keys_key_array_74[] = {0x73,0x74,0x61,0x74,0x69,0x63,};
u8 cpp_main_keys_key_array_77[] = {0x61,0x73,0x6d,};
u8 cpp_main_keys_key_array_80[] = {0x69,0x66,};
u8 cpp_main_keys_key_array_84[] = {0x69,0x6e,0x74,};
u8 cpp_main_keys_key_array_87[] = {0x6e,0x75,0x6c,0x6c,0x70,0x74,0x72,};
u8 cpp_main_keys_key_array_90[] = {0x64,0x65,0x66,0x61,0x75,0x6c,0x74,};
u8 cpp_main_keys_key_array_91[] = {0x64,0x65,0x6c,0x65,0x74,0x65,};
u8 cpp_main_keys_key_array_92[] = {0x63,0x6f,0x6e,0x73,0x74,};
u8 cpp_main_keys_key_array_93[] = {0x70,0x72,0x6f,0x74,0x65,0x63,0x74,0x65,0x64,};
u8 cpp_main_keys_key_array_98[] = {0x66,0x6c,0x6f,0x61,0x74,};
u8 cpp_main_keys_key_array_101[] = {0x64,0x79,0x6e,0x61,0x6d,0x69,0x63,0x5f,0x63,0x61,0x73,0x74,};
u8 cpp_main_keys_key_array_102[] = {0x73,0x69,0x7a,0x65,0x6f,0x66,};
u8 cpp_main_keys_key_array_104[] = {0x62,0x6f,0x6f,0x6c,};
u8 cpp_main_keys_key_array_105[] = {0x75,0x6e,0x69,0x6f,0x6e,};
u8 cpp_main_keys_key_array_107[] = {0x76,0x69,0x72,0x74,0x75,0x61,0x6c,};
u8 cpp_main_keys_key_array_108[] = {0x73,0x74,0x61,0x74,0x69,0x63,0x5f,0x61,0x73,0x73,0x65,0x72,0x74,};
u8 cpp_main_keys_key_array_109[] = {0x72,0x65,0x69,0x6e,0x74,0x65,0x72,0x70,0x72,0x65,0x74,0x5f,0x63,0x61,0x73,0x74,};
u8 cpp_main_keys_key_array_110[] = {0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,};
u8 cpp_main_keys_key_array_111[] = {0x65,0x6c,0x73,0x65,};
u8 cpp_main_keys_key_array_113[] = {0x64,0x65,0x63,0x6c,0x74,0x79,0x70,0x65,};
u8 cpp_main_keys_key_array_114[] = {0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,};
u8 cpp_main_keys_key_array_118[] = {0x73,0x74,0x72,0x75,0x63,0x74,};
u8 cpp_main_keys_key_array_119[] = {0x74,0x79,0x70,0x65,0x6e,0x61,0x6d,0x65,};
String_Const_u8 cpp_main_keys_key_array[121] = {
u8 cpp_main_keys_key_array_28[] = {0x74,0x79,0x70,0x65,0x64,0x65,0x66,};
u8 cpp_main_keys_key_array_29[] = {0x74,0x72,0x79,};
u8 cpp_main_keys_key_array_31[] = {0x65,0x6c,0x73,0x65,};
u8 cpp_main_keys_key_array_34[] = {0x72,0x65,0x74,0x75,0x72,0x6e,};
u8 cpp_main_keys_key_array_36[] = {0x73,0x69,0x7a,0x65,0x6f,0x66,};
u8 cpp_main_keys_key_array_38[] = {0x63,0x6f,0x6e,0x73,0x74,};
u8 cpp_main_keys_key_array_39[] = {0x66,0x61,0x6c,0x73,0x65,};
u8 cpp_main_keys_key_array_40[] = {0x69,0x66,};
u8 cpp_main_keys_key_array_41[] = {0x73,0x74,0x61,0x74,0x69,0x63,0x5f,0x61,0x73,0x73,0x65,0x72,0x74,};
u8 cpp_main_keys_key_array_42[] = {0x74,0x68,0x72,0x65,0x61,0x64,0x5f,0x6c,0x6f,0x63,0x61,0x6c,};
u8 cpp_main_keys_key_array_45[] = {0x74,0x68,0x69,0x73,};
u8 cpp_main_keys_key_array_48[] = {0x69,0x6e,0x74,};
u8 cpp_main_keys_key_array_50[] = {0x64,0x79,0x6e,0x61,0x6d,0x69,0x63,0x5f,0x63,0x61,0x73,0x74,};
u8 cpp_main_keys_key_array_55[] = {0x65,0x6e,0x75,0x6d,};
u8 cpp_main_keys_key_array_56[] = {0x63,0x68,0x61,0x72,};
u8 cpp_main_keys_key_array_57[] = {0x61,0x6c,0x69,0x67,0x6e,0x61,0x73,};
u8 cpp_main_keys_key_array_63[] = {0x63,0x61,0x73,0x65,};
u8 cpp_main_keys_key_array_64[] = {0x66,0x6f,0x72,};
u8 cpp_main_keys_key_array_65[] = {0x61,0x6c,0x69,0x67,0x6e,0x6f,0x66,};
u8 cpp_main_keys_key_array_68[] = {0x64,0x65,0x66,0x61,0x75,0x6c,0x74,};
u8 cpp_main_keys_key_array_69[] = {0x64,0x65,0x6c,0x65,0x74,0x65,};
u8 cpp_main_keys_key_array_74[] = {0x65,0x78,0x74,0x65,0x72,0x6e,};
u8 cpp_main_keys_key_array_75[] = {0x6c,0x6f,0x6e,0x67,};
u8 cpp_main_keys_key_array_76[] = {0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,};
u8 cpp_main_keys_key_array_77[] = {0x77,0x68,0x69,0x6c,0x65,};
u8 cpp_main_keys_key_array_81[] = {0x69,0x6e,0x6c,0x69,0x6e,0x65,};
u8 cpp_main_keys_key_array_82[] = {0x6e,0x65,0x77,};
u8 cpp_main_keys_key_array_83[] = {0x66,0x6c,0x6f,0x61,0x74,};
u8 cpp_main_keys_key_array_84[] = {0x62,0x6f,0x6f,0x6c,};
u8 cpp_main_keys_key_array_86[] = {0x63,0x6f,0x6e,0x73,0x74,0x5f,0x63,0x61,0x73,0x74,};
u8 cpp_main_keys_key_array_88[] = {0x6f,0x70,0x65,0x72,0x61,0x74,0x6f,0x72,};
u8 cpp_main_keys_key_array_90[] = {0x72,0x65,0x69,0x6e,0x74,0x65,0x72,0x70,0x72,0x65,0x74,0x5f,0x63,0x61,0x73,0x74,};
u8 cpp_main_keys_key_array_91[] = {0x65,0x78,0x70,0x6c,0x69,0x63,0x69,0x74,};
u8 cpp_main_keys_key_array_94[] = {0x73,0x74,0x72,0x75,0x63,0x74,};
u8 cpp_main_keys_key_array_95[] = {0x6e,0x75,0x6c,0x6c,0x70,0x74,0x72,};
u8 cpp_main_keys_key_array_96[] = {0x65,0x78,0x70,0x6f,0x72,0x74,};
u8 cpp_main_keys_key_array_97[] = {0x73,0x74,0x61,0x74,0x69,0x63,};
u8 cpp_main_keys_key_array_100[] = {0x66,0x72,0x69,0x65,0x6e,0x64,};
u8 cpp_main_keys_key_array_103[] = {0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,};
u8 cpp_main_keys_key_array_104[] = {0x75,0x73,0x69,0x6e,0x67,};
u8 cpp_main_keys_key_array_105[] = {0x64,0x65,0x63,0x6c,0x74,0x79,0x70,0x65,};
u8 cpp_main_keys_key_array_106[] = {0x75,0x6e,0x73,0x69,0x67,0x6e,0x65,0x64,};
u8 cpp_main_keys_key_array_108[] = {0x73,0x68,0x6f,0x72,0x74,};
u8 cpp_main_keys_key_array_111[] = {0x74,0x79,0x70,0x65,0x6e,0x61,0x6d,0x65,};
u8 cpp_main_keys_key_array_112[] = {0x75,0x6e,0x69,0x6f,0x6e,};
u8 cpp_main_keys_key_array_113[] = {0x6e,0x6f,0x65,0x78,0x63,0x65,0x70,0x74,};
u8 cpp_main_keys_key_array_114[] = {0x70,0x72,0x69,0x76,0x61,0x74,0x65,};
u8 cpp_main_keys_key_array_118[] = {0x76,0x6f,0x69,0x64,};
u8 cpp_main_keys_key_array_122[] = {0x74,0x79,0x70,0x65,0x69,0x64,};
u8 cpp_main_keys_key_array_123[] = {0x6e,0x61,0x6d,0x65,0x73,0x70,0x61,0x63,0x65,};
String_Const_u8 cpp_main_keys_key_array[124] = {
{cpp_main_keys_key_array_0, 4},
{0, 0},
{cpp_main_keys_key_array_1, 5},
{cpp_main_keys_key_array_2, 7},
{cpp_main_keys_key_array_3, 6},
{cpp_main_keys_key_array_4, 6},
{cpp_main_keys_key_array_2, 6},
{cpp_main_keys_key_array_3, 7},
{cpp_main_keys_key_array_4, 2},
{0, 0},
{cpp_main_keys_key_array_6, 4},
{cpp_main_keys_key_array_7, 7},
{cpp_main_keys_key_array_6, 9},
{0, 0},
{0, 0},
{cpp_main_keys_key_array_10, 4},
{0, 0},
{cpp_main_keys_key_array_12, 5},
{cpp_main_keys_key_array_9, 6},
{cpp_main_keys_key_array_10, 6},
{0, 0},
{0, 0},
{cpp_main_keys_key_array_15, 9},
{cpp_main_keys_key_array_16, 7},
{cpp_main_keys_key_array_13, 5},
{cpp_main_keys_key_array_14, 8},
{cpp_main_keys_key_array_15, 11},
{cpp_main_keys_key_array_16, 5},
{cpp_main_keys_key_array_17, 4},
{0, 0},
{cpp_main_keys_key_array_19, 3},
{0, 0},
{cpp_main_keys_key_array_21, 5},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{cpp_main_keys_key_array_22, 6},
{cpp_main_keys_key_array_23, 8},
{cpp_main_keys_key_array_24, 6},
{0, 0},
{cpp_main_keys_key_array_25, 8},
{cpp_main_keys_key_array_26, 6},
{cpp_main_keys_key_array_27, 8},
{0, 0},
{cpp_main_keys_key_array_28, 7},
{cpp_main_keys_key_array_29, 3},
{0, 0},
{cpp_main_keys_key_array_30, 11},
{cpp_main_keys_key_array_31, 5},
{cpp_main_keys_key_array_32, 4},
{0, 0},
{cpp_main_keys_key_array_34, 3},
{cpp_main_keys_key_array_35, 5},
{cpp_main_keys_key_array_31, 4},
{0, 0},
{0, 0},
{cpp_main_keys_key_array_38, 8},
{cpp_main_keys_key_array_39, 6},
{cpp_main_keys_key_array_40, 6},
{cpp_main_keys_key_array_41, 6},
{cpp_main_keys_key_array_34, 6},
{0, 0},
{cpp_main_keys_key_array_43, 2},
{cpp_main_keys_key_array_36, 6},
{0, 0},
{cpp_main_keys_key_array_45, 12},
{cpp_main_keys_key_array_38, 5},
{cpp_main_keys_key_array_39, 5},
{cpp_main_keys_key_array_40, 2},
{cpp_main_keys_key_array_41, 13},
{cpp_main_keys_key_array_42, 12},
{0, 0},
{0, 0},
{cpp_main_keys_key_array_45, 4},
{0, 0},
{0, 0},
{cpp_main_keys_key_array_48, 3},
{0, 0},
{cpp_main_keys_key_array_50, 12},
{0, 0},
{0, 0},
{cpp_main_keys_key_array_48, 8},
{cpp_main_keys_key_array_49, 4},
{0, 0},
{cpp_main_keys_key_array_51, 4},
{cpp_main_keys_key_array_52, 6},
{0, 0},
{cpp_main_keys_key_array_54, 4},
{cpp_main_keys_key_array_55, 4},
{cpp_main_keys_key_array_56, 4},
{cpp_main_keys_key_array_57, 7},
{0, 0},
{0, 0},
{0, 0},
{cpp_main_keys_key_array_59, 5},
{cpp_main_keys_key_array_60, 8},
{cpp_main_keys_key_array_61, 10},
{0, 0},
{cpp_main_keys_key_array_63, 6},
{0, 0},
{cpp_main_keys_key_array_65, 5},
{cpp_main_keys_key_array_63, 4},
{cpp_main_keys_key_array_64, 3},
{cpp_main_keys_key_array_65, 7},
{0, 0},
{0, 0},
{cpp_main_keys_key_array_68, 7},
{cpp_main_keys_key_array_69, 6},
{0, 0},
{0, 0},
{cpp_main_keys_key_array_67, 4},
{cpp_main_keys_key_array_68, 8},
{cpp_main_keys_key_array_69, 5},
{cpp_main_keys_key_array_70, 3},
{0, 0},
{cpp_main_keys_key_array_72, 3},
{0, 0},
{cpp_main_keys_key_array_74, 6},
{0, 0},
{0, 0},
{cpp_main_keys_key_array_77, 3},
{0, 0},
{0, 0},
{cpp_main_keys_key_array_80, 2},
{cpp_main_keys_key_array_75, 4},
{cpp_main_keys_key_array_76, 8},
{cpp_main_keys_key_array_77, 5},
{0, 0},
{0, 0},
{0, 0},
{cpp_main_keys_key_array_84, 3},
{cpp_main_keys_key_array_81, 6},
{cpp_main_keys_key_array_82, 3},
{cpp_main_keys_key_array_83, 5},
{cpp_main_keys_key_array_84, 4},
{0, 0},
{cpp_main_keys_key_array_86, 10},
{0, 0},
{cpp_main_keys_key_array_88, 8},
{0, 0},
{cpp_main_keys_key_array_90, 16},
{cpp_main_keys_key_array_91, 8},
{0, 0},
{0, 0},
{cpp_main_keys_key_array_87, 7},
{cpp_main_keys_key_array_94, 6},
{cpp_main_keys_key_array_95, 7},
{cpp_main_keys_key_array_96, 6},
{cpp_main_keys_key_array_97, 6},
{0, 0},
{0, 0},
{cpp_main_keys_key_array_90, 7},
{cpp_main_keys_key_array_91, 6},
{cpp_main_keys_key_array_92, 5},
{cpp_main_keys_key_array_93, 9},
{cpp_main_keys_key_array_100, 6},
{0, 0},
{0, 0},
{cpp_main_keys_key_array_103, 8},
{cpp_main_keys_key_array_104, 5},
{cpp_main_keys_key_array_105, 8},
{cpp_main_keys_key_array_106, 8},
{0, 0},
{cpp_main_keys_key_array_108, 5},
{0, 0},
{0, 0},
{cpp_main_keys_key_array_98, 5},
{0, 0},
{0, 0},
{cpp_main_keys_key_array_101, 12},
{cpp_main_keys_key_array_102, 6},
{0, 0},
{cpp_main_keys_key_array_104, 4},
{cpp_main_keys_key_array_105, 5},
{0, 0},
{cpp_main_keys_key_array_107, 7},
{cpp_main_keys_key_array_108, 13},
{cpp_main_keys_key_array_109, 16},
{cpp_main_keys_key_array_110, 8},
{cpp_main_keys_key_array_111, 4},
{0, 0},
{cpp_main_keys_key_array_111, 8},
{cpp_main_keys_key_array_112, 5},
{cpp_main_keys_key_array_113, 8},
{cpp_main_keys_key_array_114, 8},
{cpp_main_keys_key_array_114, 7},
{0, 0},
{0, 0},
{0, 0},
{cpp_main_keys_key_array_118, 6},
{cpp_main_keys_key_array_119, 8},
{cpp_main_keys_key_array_118, 4},
{0, 0},
{0, 0},
{0, 0},
{cpp_main_keys_key_array_122, 6},
{cpp_main_keys_key_array_123, 9},
};
Lexeme_Table_Value cpp_main_keys_value_array[121] = {
Lexeme_Table_Value cpp_main_keys_value_array[124] = {
{8, TokenCppKind_LiteralTrue},
{0, 0},
{4, TokenCppKind_Signed},
{4, TokenCppKind_Virtual},
{4, TokenCppKind_Do},
{0, 0},
{4, TokenCppKind_Protected},
{0, 0},
{0, 0},
{4, TokenCppKind_Double},
{4, TokenCppKind_Public},
{0, 0},
{0, 0},
{4, TokenCppKind_Class},
{4, TokenCppKind_Typedef},
{4, TokenCppKind_Double},
{4, TokenCppKind_TypeID},
{4, TokenCppKind_Template},
{4, TokenCppKind_StaticCast},
{4, TokenCppKind_Catch},
{4, TokenCppKind_Goto},
{0, 0},
{4, TokenCppKind_Long},
{4, TokenCppKind_AlignOf},
{4, TokenCppKind_Asm},
{0, 0},
{4, TokenCppKind_Break},
{0, 0},
{0, 0},
{0, 0},
{4, TokenCppKind_Volatile},
{4, TokenCppKind_Switch},
{0, 0},
{4, TokenCppKind_Typedef},
{4, TokenCppKind_Try},
{0, 0},
{4, TokenCppKind_Else},
{0, 0},
{0, 0},
{4, TokenCppKind_Return},
{0, 0},
{4, TokenCppKind_SizeOf},
{0, 0},
{4, TokenCppKind_Const},
{8, TokenCppKind_LiteralFalse},
{4, TokenCppKind_If},
{4, TokenCppKind_StaticAssert},
{4, TokenCppKind_ThreadLocal},
{0, 0},
{0, 0},
{4, TokenCppKind_This},
{0, 0},
{4, TokenCppKind_Short},
{0, 0},
{0, 0},
{4, TokenCppKind_Namespace},
{4, TokenCppKind_Private},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{4, TokenCppKind_Public},
{4, TokenCppKind_NoExcept},
{4, TokenCppKind_Friend},
{0, 0},
{4, TokenCppKind_Switch},
{4, TokenCppKind_Explicit},
{4, TokenCppKind_AlignAs},
{0, 0},
{4, TokenCppKind_StaticCast},
{8, TokenCppKind_LiteralFalse},
{4, TokenCppKind_Char},
{0, 0},
{4, TokenCppKind_New},
{4, TokenCppKind_Using},
{0, 0},
{0, 0},
{4, TokenCppKind_Unsigned},
{4, TokenCppKind_Return},
{4, TokenCppKind_Extern},
{4, TokenCppKind_Signed},
{0, 0},
{4, TokenCppKind_Do},
{0, 0},
{4, TokenCppKind_ThreadLocal},
{0, 0},
{0, 0},
{4, TokenCppKind_Continue},
{4, TokenCppKind_Enum},
{0, 0},
{8, TokenCppKind_LiteralTrue},
{4, TokenCppKind_Export},
{0, 0},
{4, TokenCppKind_Void},
{4, TokenCppKind_Case},
{0, 0},
{0, 0},
{0, 0},
{4, TokenCppKind_While},
{4, TokenCppKind_Operator},
{4, TokenCppKind_ConstCast},
{0, 0},
{4, TokenCppKind_Inline},
{0, 0},
{4, TokenCppKind_Break},
{0, 0},
{4, TokenCppKind_Goto},
{4, TokenCppKind_Template},
{4, TokenCppKind_Catch},
{4, TokenCppKind_For},
{0, 0},
{4, TokenCppKind_Try},
{0, 0},
{4, TokenCppKind_Static},
{0, 0},
{0, 0},
{4, TokenCppKind_Asm},
{0, 0},
{0, 0},
{4, TokenCppKind_If},
{0, 0},
{0, 0},
{0, 0},
{4, TokenCppKind_Int},
{0, 0},
{4, TokenCppKind_DynamicCast},
{0, 0},
{4, TokenCppKind_NullPtr},
{0, 0},
{0, 0},
{0, 0},
{4, TokenCppKind_Enum},
{4, TokenCppKind_Char},
{4, TokenCppKind_AlignAs},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{4, TokenCppKind_Case},
{4, TokenCppKind_For},
{4, TokenCppKind_AlignOf},
{0, 0},
{0, 0},
{4, TokenCppKind_Default},
{4, TokenCppKind_Delete},
{4, TokenCppKind_Const},
{4, TokenCppKind_Protected},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{4, TokenCppKind_Float},
{0, 0},
{0, 0},
{4, TokenCppKind_DynamicCast},
{4, TokenCppKind_SizeOf},
{0, 0},
{4, TokenCppKind_Bool},
{4, TokenCppKind_Union},
{0, 0},
{4, TokenCppKind_Virtual},
{4, TokenCppKind_StaticAssert},
{4, TokenCppKind_ReinterpretCast},
{4, TokenCppKind_Volatile},
{4, TokenCppKind_Else},
{0, 0},
{4, TokenCppKind_DeclType},
{4, TokenCppKind_Extern},
{4, TokenCppKind_Long},
{4, TokenCppKind_Register},
{4, TokenCppKind_While},
{0, 0},
{0, 0},
{0, 0},
{4, TokenCppKind_Inline},
{4, TokenCppKind_New},
{4, TokenCppKind_Float},
{4, TokenCppKind_Bool},
{0, 0},
{4, TokenCppKind_ConstCast},
{0, 0},
{4, TokenCppKind_Operator},
{0, 0},
{4, TokenCppKind_ReinterpretCast},
{4, TokenCppKind_Explicit},
{0, 0},
{0, 0},
{4, TokenCppKind_Struct},
{4, TokenCppKind_NullPtr},
{4, TokenCppKind_Export},
{4, TokenCppKind_Static},
{0, 0},
{0, 0},
{4, TokenCppKind_Friend},
{0, 0},
{0, 0},
{4, TokenCppKind_Continue},
{4, TokenCppKind_Using},
{4, TokenCppKind_DeclType},
{4, TokenCppKind_Unsigned},
{0, 0},
{4, TokenCppKind_Short},
{0, 0},
{0, 0},
{4, TokenCppKind_Typename},
{4, TokenCppKind_Union},
{4, TokenCppKind_NoExcept},
{4, TokenCppKind_Private},
{0, 0},
{0, 0},
{0, 0},
{4, TokenCppKind_Void},
{0, 0},
{0, 0},
{0, 0},
{4, TokenCppKind_TypeID},
{4, TokenCppKind_Namespace},
};
i32 cpp_main_keys_slot_count = 121;
u64 cpp_main_keys_seed = 0x57fd2e8360fc723f;
i32 cpp_main_keys_slot_count = 124;
u64 cpp_main_keys_seed = 0x8546da5e0b8a4494;
u64 cpp_pp_directives_hash_array[25] = {
0x0000000000000000,0x0000000000000000,0xfcbe0e69ab5f0ab5,0x0000000000000000,
0xdfa7f6eb98ca462d,0xdfa7f6ebae1c243d,0x26e6293f7c60a9d7,0x0000000000000000,
0xfcbe0e6b92eff62d,0x0000000000000000,0xdfa7f6604dbd1a65,0xfcbe0e69ab4edf49,
0x0000000000000000,0xdfa7f6ee4efdc3a3,0xfcbe0e6b014df297,0x26e6293f7c60632d,
0x0000000000000000,0xfcbe0e6b09dcce2d,0x0000000000000000,0x0000000000000000,
0x26e6293f722aa025,0xa6ba73c3a74f4285,0xb0a57847c3818ea9,0x0000000000000000,
0xb0a595ffc01d0bd5,
0xa9c93e3b092cb44d,0x0000000000000000,0x0dd88216be8f0f45,0x0000000000000000,
0x0dd88216bc8af78d,0x92a889595c683c55,0xdab9e300145b906f,0x92a889577e972a4b,
0x0000000000000000,0x0dd88216bb8053ff,0x0000000000000000,0x0dd88216bd573601,
0x0000000000000000,0xdab9e300142a071d,0x0000000000000000,0xa9c93ef34054fce1,
0x0dd88216a4783a45,0xdab9e300145b9a25,0x92a889595b4a2105,0x0000000000000000,
0x86d1d427e10cd86d,0x0000000000000000,0x92a889590753d01d,0x0000000000000000,
0x0000000000000000,
};
u8 cpp_pp_directives_key_array_2[] = {0x65,0x6e,0x64,0x69,0x66,};
u8 cpp_pp_directives_key_array_4[] = {0x69,0x66,0x6e,0x64,0x65,0x66,};
u8 cpp_pp_directives_key_array_5[] = {0x69,0x6d,0x70,0x6f,0x72,0x74,};
u8 cpp_pp_directives_key_array_0[] = {0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,};
u8 cpp_pp_directives_key_array_2[] = {0x69,0x66,0x64,0x65,0x66,};
u8 cpp_pp_directives_key_array_4[] = {0x65,0x6e,0x64,0x69,0x66,};
u8 cpp_pp_directives_key_array_5[] = {0x69,0x66,0x6e,0x64,0x65,0x66,};
u8 cpp_pp_directives_key_array_6[] = {0x65,0x6c,0x73,0x65,};
u8 cpp_pp_directives_key_array_8[] = {0x69,0x66,0x64,0x65,0x66,};
u8 cpp_pp_directives_key_array_10[] = {0x64,0x65,0x66,0x69,0x6e,0x65,};
u8 cpp_pp_directives_key_array_7[] = {0x70,0x72,0x61,0x67,0x6d,0x61,};
u8 cpp_pp_directives_key_array_9[] = {0x75,0x73,0x69,0x6e,0x67,};
u8 cpp_pp_directives_key_array_11[] = {0x65,0x72,0x72,0x6f,0x72,};
u8 cpp_pp_directives_key_array_13[] = {0x70,0x72,0x61,0x67,0x6d,0x61,};
u8 cpp_pp_directives_key_array_14[] = {0x75,0x73,0x69,0x6e,0x67,};
u8 cpp_pp_directives_key_array_15[] = {0x65,0x6c,0x69,0x66,};
u8 cpp_pp_directives_key_array_17[] = {0x75,0x6e,0x64,0x65,0x66,};
u8 cpp_pp_directives_key_array_20[] = {0x6c,0x69,0x6e,0x65,};
u8 cpp_pp_directives_key_array_21[] = {0x69,0x66,};
u8 cpp_pp_directives_key_array_22[] = {0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,};
u8 cpp_pp_directives_key_array_24[] = {0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,};
u8 cpp_pp_directives_key_array_13[] = {0x6c,0x69,0x6e,0x65,};
u8 cpp_pp_directives_key_array_15[] = {0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,};
u8 cpp_pp_directives_key_array_16[] = {0x75,0x6e,0x64,0x65,0x66,};
u8 cpp_pp_directives_key_array_17[] = {0x65,0x6c,0x69,0x66,};
u8 cpp_pp_directives_key_array_18[] = {0x69,0x6d,0x70,0x6f,0x72,0x74,};
u8 cpp_pp_directives_key_array_20[] = {0x69,0x66,};
u8 cpp_pp_directives_key_array_22[] = {0x64,0x65,0x66,0x69,0x6e,0x65,};
String_Const_u8 cpp_pp_directives_key_array[25] = {
{0, 0},
{cpp_pp_directives_key_array_0, 7},
{0, 0},
{cpp_pp_directives_key_array_2, 5},
{0, 0},
{cpp_pp_directives_key_array_4, 6},
{cpp_pp_directives_key_array_4, 5},
{cpp_pp_directives_key_array_5, 6},
{cpp_pp_directives_key_array_6, 4},
{cpp_pp_directives_key_array_7, 6},
{0, 0},
{cpp_pp_directives_key_array_8, 5},
{cpp_pp_directives_key_array_9, 5},
{0, 0},
{cpp_pp_directives_key_array_10, 6},
{cpp_pp_directives_key_array_11, 5},
{0, 0},
{cpp_pp_directives_key_array_13, 6},
{cpp_pp_directives_key_array_14, 5},
{cpp_pp_directives_key_array_15, 4},
{cpp_pp_directives_key_array_13, 4},
{0, 0},
{cpp_pp_directives_key_array_17, 5},
{cpp_pp_directives_key_array_15, 7},
{cpp_pp_directives_key_array_16, 5},
{cpp_pp_directives_key_array_17, 4},
{cpp_pp_directives_key_array_18, 6},
{0, 0},
{cpp_pp_directives_key_array_20, 2},
{0, 0},
{cpp_pp_directives_key_array_22, 6},
{0, 0},
{0, 0},
{cpp_pp_directives_key_array_20, 4},
{cpp_pp_directives_key_array_21, 2},
{cpp_pp_directives_key_array_22, 7},
{0, 0},
{cpp_pp_directives_key_array_24, 7},
};
Lexeme_Table_Value cpp_pp_directives_value_array[25] = {
{0, 0},
{0, 0},
{5, TokenCppKind_PPEndIf},
{0, 0},
{5, TokenCppKind_PPIfNDef},
{5, TokenCppKind_PPImport},
{5, TokenCppKind_PPElse},
{5, TokenCppKind_PPVersion},
{0, 0},
{5, TokenCppKind_PPIfDef},
{0, 0},
{5, TokenCppKind_PPDefine},
{5, TokenCppKind_PPEndIf},
{5, TokenCppKind_PPIfNDef},
{5, TokenCppKind_PPElse},
{5, TokenCppKind_PPPragma},
{0, 0},
{5, TokenCppKind_PPUsing},
{0, 0},
{5, TokenCppKind_PPError},
{0, 0},
{5, TokenCppKind_PPPragma},
{5, TokenCppKind_PPUsing},
{5, TokenCppKind_PPElIf},
{0, 0},
{5, TokenCppKind_PPUndef},
{0, 0},
{0, 0},
{5, TokenCppKind_PPLine},
{5, TokenCppKind_PPIf},
{5, TokenCppKind_PPInclude},
{0, 0},
{5, TokenCppKind_PPVersion},
{5, TokenCppKind_PPInclude},
{5, TokenCppKind_PPUndef},
{5, TokenCppKind_PPElIf},
{5, TokenCppKind_PPImport},
{0, 0},
{5, TokenCppKind_PPIf},
{0, 0},
{5, TokenCppKind_PPDefine},
{0, 0},
{0, 0},
};
i32 cpp_pp_directives_slot_count = 25;
u64 cpp_pp_directives_seed = 0xe34ca5b52cfeb288;
u64 cpp_pp_directives_seed = 0x6e8a1011f7d8dd90;
u64 cpp_pp_keys_hash_array[2] = {
0x0000000000000000,0xbef27711d7aba2b5,
0x56dd32803fcaa4ab,0x0000000000000000,
};
u8 cpp_pp_keys_key_array_1[] = {0x64,0x65,0x66,0x69,0x6e,0x65,0x64,};
u8 cpp_pp_keys_key_array_0[] = {0x64,0x65,0x66,0x69,0x6e,0x65,0x64,};
String_Const_u8 cpp_pp_keys_key_array[2] = {
{cpp_pp_keys_key_array_0, 7},
{0, 0},
{cpp_pp_keys_key_array_1, 7},
};
Lexeme_Table_Value cpp_pp_keys_value_array[2] = {
{0, 0},
{4, TokenCppKind_PPDefined},
{0, 0},
};
i32 cpp_pp_keys_slot_count = 2;
u64 cpp_pp_keys_seed = 0x5c61314da2466695;
u64 cpp_pp_keys_seed = 0xbb7907ea1860ef2c;
struct Lex_State_Cpp{
u32 flags_ZF0;
u32 flags_KF0;

View File

@ -93,53 +93,53 @@ typedef b32 system_set_fullscreen_type(b32 full_screen);
typedef b32 system_is_fullscreen_type(void);
typedef Input_Modifier_Set system_get_keyboard_modifiers_type(Arena* arena);
struct API_VTable_system{
system_get_path_type *get_path;
system_get_canonical_type *get_canonical;
system_get_file_list_type *get_file_list;
system_quick_file_attributes_type *quick_file_attributes;
system_load_handle_type *load_handle;
system_load_attributes_type *load_attributes;
system_load_file_type *load_file;
system_load_close_type *load_close;
system_save_file_type *save_file;
system_load_library_type *load_library;
system_release_library_type *release_library;
system_get_proc_type *get_proc;
system_now_time_type *now_time;
system_wake_up_timer_create_type *wake_up_timer_create;
system_wake_up_timer_release_type *wake_up_timer_release;
system_wake_up_timer_set_type *wake_up_timer_set;
system_signal_step_type *signal_step;
system_sleep_type *sleep;
system_post_clipboard_type *post_clipboard;
system_cli_call_type *cli_call;
system_cli_begin_update_type *cli_begin_update;
system_cli_update_step_type *cli_update_step;
system_cli_end_update_type *cli_end_update;
system_open_color_picker_type *open_color_picker;
system_get_screen_scale_factor_type *get_screen_scale_factor;
system_thread_launch_type *thread_launch;
system_thread_join_type *thread_join;
system_thread_free_type *thread_free;
system_thread_get_id_type *thread_get_id;
system_acquire_global_frame_mutex_type *acquire_global_frame_mutex;
system_release_global_frame_mutex_type *release_global_frame_mutex;
system_mutex_make_type *mutex_make;
system_mutex_acquire_type *mutex_acquire;
system_mutex_release_type *mutex_release;
system_mutex_free_type *mutex_free;
system_condition_variable_make_type *condition_variable_make;
system_condition_variable_wait_type *condition_variable_wait;
system_condition_variable_signal_type *condition_variable_signal;
system_condition_variable_free_type *condition_variable_free;
system_memory_allocate_type *memory_allocate;
system_memory_set_protection_type *memory_set_protection;
system_memory_free_type *memory_free;
system_memory_annotation_type *memory_annotation;
system_show_mouse_cursor_type *show_mouse_cursor;
system_set_fullscreen_type *set_fullscreen;
system_is_fullscreen_type *is_fullscreen;
system_get_keyboard_modifiers_type *get_keyboard_modifiers;
system_get_path_type *get_path;
system_get_canonical_type *get_canonical;
system_get_file_list_type *get_file_list;
system_quick_file_attributes_type *quick_file_attributes;
system_load_handle_type *load_handle;
system_load_attributes_type *load_attributes;
system_load_file_type *load_file;
system_load_close_type *load_close;
system_save_file_type *save_file;
system_load_library_type *load_library;
system_release_library_type *release_library;
system_get_proc_type *get_proc;
system_now_time_type *now_time;
system_wake_up_timer_create_type *wake_up_timer_create;
system_wake_up_timer_release_type *wake_up_timer_release;
system_wake_up_timer_set_type *wake_up_timer_set;
system_signal_step_type *signal_step;
system_sleep_type *sleep;
system_post_clipboard_type *post_clipboard;
system_cli_call_type *cli_call;
system_cli_begin_update_type *cli_begin_update;
system_cli_update_step_type *cli_update_step;
system_cli_end_update_type *cli_end_update;
system_open_color_picker_type *open_color_picker;
system_get_screen_scale_factor_type *get_screen_scale_factor;
system_thread_launch_type *thread_launch;
system_thread_join_type *thread_join;
system_thread_free_type *thread_free;
system_thread_get_id_type *thread_get_id;
system_acquire_global_frame_mutex_type *acquire_global_frame_mutex;
system_release_global_frame_mutex_type *release_global_frame_mutex;
system_mutex_make_type *mutex_make;
system_mutex_acquire_type *mutex_acquire;
system_mutex_release_type *mutex_release;
system_mutex_free_type *mutex_free;
system_condition_variable_make_type *condition_variable_make;
system_condition_variable_wait_type *condition_variable_wait;
system_condition_variable_signal_type *condition_variable_signal;
system_condition_variable_free_type *condition_variable_free;
system_memory_allocate_type *memory_allocate;
system_memory_set_protection_type *memory_set_protection;
system_memory_free_type *memory_free;
system_memory_annotation_type *memory_annotation;
system_show_mouse_cursor_type *show_mouse_cursor;
system_set_fullscreen_type *set_fullscreen;
system_is_fullscreen_type *is_fullscreen;
system_get_keyboard_modifiers_type *get_keyboard_modifiers;
};
#if defined(STATIC_LINK_API)
internal String_Const_u8 system_get_path(Arena* arena, System_Path_Code path_code);

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.metadata_generator</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

535
metal/4ed_metal_render.mm Normal file
View File

@ -0,0 +1,535 @@
/* 4coder Metal render implementation */
#undef clamp
#undef function
#import <simd/simd.h>
#import <MetalKit/MetalKit.h>
#include "AAPLShaderTypes.h"
#define function static
////////////////////////////////
typedef id<MTLTexture> Metal_Texture;
struct Metal_Buffer{
Node node;
id<MTLBuffer> buffer;
u32 size;
u64 last_reuse_time;
};
////////////////////////////////
@interface Metal_Renderer : NSObject<MTKViewDelegate>
@property (nonatomic) Render_Target *target;
- (nonnull instancetype)initWithMetalKitView:(nonnull MTKView*)mtkView target:(Render_Target*)target;
- (u32)get_texture_of_dim:(Vec3_i32)dim kind:(Texture_Kind)kind;
- (b32)fill_texture:(u32)texture kind:(Texture_Kind)kind pos:(Vec3_i32)p dim:(Vec3_i32)dim data:(void*)data;
- (void)bind_texture:(u32)handle encoder:(id<MTLRenderCommandEncoder>)render_encoder;
- (Metal_Buffer*)get_reusable_buffer_with_size:(NSUInteger)size;
- (void)add_reusable_buffer:(Metal_Buffer*)buffer;
@end
////////////////////////////////
global_const u32 metal__max_textures = 256;
////////////////////////////////
global_const char *metal__shaders_source = R"(
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
////////////////////////////////
typedef struct{
float2 xy [[attribute(0)]];
float3 uvw [[attribute(1)]];
uint32_t color [[attribute(2)]];
float half_thickness [[attribute(3)]];
} Vertex;
// NOTE(yuval): Vertex shader outputs and fragment shader inputs
typedef struct{
// NOTE(yuval): Vertex shader output
float4 position [[position]];
// NOTE(yuval): Fragment shader inputs
float4 color;
float3 uvw;
float2 xy;
float2 adjusted_half_dim;
float half_thickness;
} Rasterizer_Data;
////////////////////////////////
vertex Rasterizer_Data
vertex_shader(Vertex in [[stage_in]],
constant float4x4 &proj [[buffer(1)]]){
Rasterizer_Data out;
// NOTE(yuval): Calculate position in NDC
out.position = proj * float4(in.xy, 0.0, 1.0);
// NOTE(yuval): Convert color to float4 format
out.color.b = ((float((in.color ) & 0xFFu)) / 255.0);
out.color.g = ((float((in.color >> 8u) & 0xFFu)) / 255.0);
out.color.r = ((float((in.color >> 16u) & 0xFFu)) / 255.0);
out.color.a = ((float((in.color >> 24u) & 0xFFu)) / 255.0);
// NOTE(yuval): Pass uvw coordinates to the fragment shader
out.uvw = in.uvw;
// NOTE(yuval): Calculate adjusted half dim
float2 center = in.uvw.xy;
float2 half_dim = abs(in.xy - center);
out.adjusted_half_dim = (half_dim - in.uvw.zz + float2(0.5, 0.5));
// NOTE(yuval): Pass half_thickness to the fragment shader
out.half_thickness = in.half_thickness;
// NOTE(yuval): Pass xy to the fragment shader
out.xy = in.xy;
return(out);
}
////////////////////////////////
float
rectangle_sd(float2 p, float2 b){
float2 d = (abs(p) - b);
float result = (length(max(d, float2(0.0, 0.0))) + min(max(d.x, d.y), 0.0));
return(result);
}
fragment float4
fragment_shader(Rasterizer_Data in [[stage_in]],
texture2d_array<half> in_texture [[texture(0)]]){
float has_thickness = step(0.49, in.half_thickness);
float does_not_have_thickness = (1.0 - has_thickness);
constexpr sampler texture_sampler(coord::normalized, min_filter::linear, mag_filter::linear, mip_filter::linear);
half sample_value = in_texture.sample(texture_sampler, in.uvw.xy, in.uvw.z).r;
sample_value *= does_not_have_thickness;
float2 center = in.uvw.xy;
float roundness = in.uvw.z;
float sd = rectangle_sd(in.xy - center, in.adjusted_half_dim);
sd = sd - roundness;
sd = (abs(sd + in.half_thickness) - in.half_thickness);
float shape_value = (1.0 - smoothstep(-1.0, 0.0, sd));
shape_value *= has_thickness;
float4 out_color = float4(in.color.xyz, in.color.a * (sample_value + shape_value));
return(out_color);
}
)";
////////////////////////////////
function Metal_Buffer*
metal__make_buffer(u32 size, id<MTLDevice> device){
Metal_Buffer *result = (Metal_Buffer*)malloc(sizeof(Metal_Buffer));
// NOTE(yuval): Create the vertex buffer
MTLResourceOptions options = MTLCPUCacheModeWriteCombined|MTLResourceStorageModeManaged;
result->buffer = [device newBufferWithLength:size options:options];
result->size = size;
// NOTE(yuval): Set the last_reuse_time to the current time
result->last_reuse_time = system_now_time();
return result;
}
////////////////////////////////
@implementation Metal_Renderer{
id<MTLDevice> device;
id<MTLRenderPipelineState> pipeline_state;
id<MTLCommandQueue> command_queue;
id<MTLCaptureScope> capture_scope;
Node buffer_cache;
u64 last_buffer_cache_purge_time;
Metal_Texture *textures;
u32 next_texture_handle_index;
}
- (nonnull instancetype)initWithMetalKitView:(nonnull MTKView*)mtk_view target:(Render_Target*)target{
self = [super init];
if (self == nil){
return(nil);
}
_target = target;
NSError *error = nil;
device = mtk_view.device;
// NOTE(yuval): Compile the shaders
id<MTLFunction> vertex_function = nil;
id<MTLFunction> fragment_function = nil;
{
NSString *shaders_source_str = [NSString stringWithUTF8String:metal__shaders_source];
MTLCompileOptions *options = [[MTLCompileOptions alloc] init];
options.fastMathEnabled = YES;
id<MTLLibrary> shader_library = [device newLibraryWithSource:shaders_source_str
options:options error:&error];
vertex_function = [shader_library newFunctionWithName:@"vertex_shader"];
fragment_function = [shader_library newFunctionWithName:@"fragment_shader"];
[options release];
}
Assert(error == nil);
Assert((vertex_function != nil) && (fragment_function != nil));
// NOTE(yuval): Configure the pipeline descriptor
{
MTLVertexDescriptor *vertexDescriptor = [MTLVertexDescriptor vertexDescriptor];
vertexDescriptor.attributes[0].offset = OffsetOfMember(Render_Vertex, xy);
vertexDescriptor.attributes[0].format = MTLVertexFormatFloat2; // position
vertexDescriptor.attributes[0].bufferIndex = 0;
vertexDescriptor.attributes[1].offset = OffsetOfMember(Render_Vertex, uvw);
vertexDescriptor.attributes[1].format = MTLVertexFormatFloat3; // texCoords
vertexDescriptor.attributes[1].bufferIndex = 0;
vertexDescriptor.attributes[2].offset = OffsetOfMember(Render_Vertex, color);
vertexDescriptor.attributes[2].format = MTLVertexFormatUInt; // color
vertexDescriptor.attributes[2].bufferIndex = 0;
vertexDescriptor.attributes[3].offset = OffsetOfMember(Render_Vertex, half_thickness);
vertexDescriptor.attributes[3].format = MTLVertexFormatFloat; // position
vertexDescriptor.attributes[3].bufferIndex = 0;
vertexDescriptor.layouts[0].stepRate = 1;
vertexDescriptor.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex;
vertexDescriptor.layouts[0].stride = sizeof(Render_Vertex);
MTLRenderPipelineDescriptor *pipeline_state_descriptor = [[MTLRenderPipelineDescriptor alloc] init];
pipeline_state_descriptor.label = @"4coder Metal Renderer Pipeline";
pipeline_state_descriptor.vertexFunction = vertex_function;
pipeline_state_descriptor.fragmentFunction = fragment_function;
pipeline_state_descriptor.vertexDescriptor = vertexDescriptor;
pipeline_state_descriptor.colorAttachments[0].pixelFormat = mtk_view.colorPixelFormat;
pipeline_state_descriptor.colorAttachments[0].blendingEnabled = YES;
pipeline_state_descriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd;
pipeline_state_descriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
pipeline_state_descriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
pipeline_state_descriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
pipeline_state_descriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne;
pipeline_state_descriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
pipeline_state = [device newRenderPipelineStateWithDescriptor:pipeline_state_descriptor
error:&error];
}
Assert(error == nil);
// NOTE(yuval): Create the command queue
command_queue = [device newCommandQueue];
// NOTE(yuval): Initialize buffer caching
dll_init_sentinel(&buffer_cache);
last_buffer_cache_purge_time = system_now_time();
// NOTE(yuval): Initialize the textures array
textures = (Metal_Texture*)system_memory_allocate(metal__max_textures * sizeof(Metal_Texture), file_name_line_number_lit_u8);
next_texture_handle_index = 0;
// NOTE(yuval): Create the fallback texture
_target->fallback_texture_id = [self get_texture_of_dim:V3i32(2, 2, 1)
kind:TextureKind_Mono];
u8 white_block[] = {0xFF, 0xFF, 0xFF, 0xFF};
[self fill_texture:_target->fallback_texture_id
kind:TextureKind_Mono
pos:V3i32(0, 0, 0)
dim:V3i32(2, 2, 1)
data:white_block];
// NOTE(yuval): Create a capture scope for gpu frame capture
capture_scope = [[MTLCaptureManager sharedCaptureManager]
newCaptureScopeWithDevice:device];
capture_scope.label = @"4coder Metal Capture Scope";
return(self);
}
- (void)mtkView:(nonnull MTKView*)view drawableSizeWillChange:(CGSize)size{
// NOTE(yuval): Nothing to do here because we use the render target's dimentions for rendering
}
- (void)drawInMTKView:(nonnull MTKView*)view{
#if FRED_INTERNAL
[capture_scope beginScope];
#endif
// HACK(yuval): This is the best way I found to force valid width and height without drawing on the next draw cycle (1 frame delay).
CGSize drawable_size = [view drawableSize];
i32 width = (i32)Min(_target->width, drawable_size.width);
i32 height = (i32)Min(_target->height, drawable_size.height);
Font_Set *font_set = (Font_Set*)_target->font_set;
// NOTE(yuval): Create the command buffer
id<MTLCommandBuffer> command_buffer = [command_queue commandBuffer];
command_buffer.label = @"4coder Metal Render Command";
// NOTE(yuval): Obtain the render pass descriptor from the renderer's view
MTLRenderPassDescriptor *render_pass_descriptor = view.currentRenderPassDescriptor;
if (render_pass_descriptor != nil){
render_pass_descriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.0f, 0.0f, 0.0f, 1.0f);
// NOTE(yuval): Create the render command encoder
id<MTLRenderCommandEncoder> render_encoder =
[command_buffer renderCommandEncoderWithDescriptor:render_pass_descriptor];
render_encoder.label = @"4coder Render Encoder";
// NOTE(yuval): Set the region of the drawable to draw into
[render_encoder setViewport:(MTLViewport){0.0, 0.0, (double)width, (double)height, 0.0, 1.0}];
// NOTE(yuval): Set the render pipeline to use for drawing
[render_encoder setRenderPipelineState:pipeline_state];
// NOTE(yuval): Calculate the projection matrix
float left = 0, right = (float)width;
float bottom = (float)height, top = 0;
float near_depth = -1.0f, far_depth = 1.0f;
float proj[16] = {
2.0f / (right - left), 0.0f, 0.0f, 0.0f,
0.0f, 2.0f / (top - bottom), 0.0f, 0.0f,
0.0f, 0.0f, -1.0f / (far_depth - near_depth), 0.0f,
-((right + left) / (right - left)), -((top + bottom) / (top - bottom)),
-(near_depth / (far_depth - near_depth)), 1.0f
};
// NOTE(yuval): Calculate required vertex buffer size
i32 all_vertex_count = 0;
for (Render_Group *group = _target->group_first;
group;
group = group->next){
all_vertex_count += group->vertex_list.vertex_count;
}
u32 vertex_buffer_size = (all_vertex_count * sizeof(Render_Vertex));
// NOTE(yuval): Find & Get a vertex buffer matching the required size
Metal_Buffer *buffer = [self get_reusable_buffer_with_size:vertex_buffer_size];
// NOTE(yuval): Pass the vertex buffer to the vertex shader
[render_encoder setVertexBuffer:buffer->buffer
offset:0
atIndex:0];
// NOTE(yuval): Pass the projection matrix to the vertex shader
[render_encoder setVertexBytes:&proj
length:sizeof(proj)
atIndex:1];
u32 buffer_offset = 0;
for (Render_Group *group = _target->group_first;
group;
group = group->next){
// NOTE(yuval): Set scissor rect
{
Rect_i32 box = Ri32(group->clip_box);
NSUInteger x0 = (NSUInteger)Min(Max(0, box.x0), width - 1);
NSUInteger x1 = (NSUInteger)Min(Max(0, box.x1), width);
NSUInteger y0 = (NSUInteger)Min(Max(0, box.y0), height - 1);
NSUInteger y1 = (NSUInteger)Min(Max(0, box.y1), height);
MTLScissorRect scissor_rect;
scissor_rect.x = x0;
scissor_rect.y = y0;
scissor_rect.width = (x1 - x0);
scissor_rect.height = (y1 - y0);
[render_encoder setScissorRect:scissor_rect];
}
i32 vertex_count = group->vertex_list.vertex_count;
if (vertex_count > 0){
// NOTE(yuval): Bind a texture
{
Face* face = font_set_face_from_id(font_set, group->face_id);
if (face != 0){
// NOTE(yuval): Bind face texture
[self bind_texture:face->texture
encoder:render_encoder];
} else{
// NOTE(yuval): Bind fallback texture
[self bind_texture:_target->fallback_texture_id
encoder:render_encoder];
}
}
// NOTE(yuval): Copy the vertex data to the vertex buffer
{
u8 *group_buffer_contents = (u8*)[buffer->buffer contents] + buffer_offset;
u8 *cursor = group_buffer_contents;
for (Render_Vertex_Array_Node *node = group->vertex_list.first;
node;
node = node->next){
i32 size = node->vertex_count * sizeof(*node->vertices);
memcpy(cursor, node->vertices, size);
cursor += size;
}
NSUInteger data_size = (NSUInteger)(cursor - group_buffer_contents);
NSRange modify_range = NSMakeRange(buffer_offset, data_size);
[buffer->buffer didModifyRange:modify_range];
}
// NOTE(yuval): Set the vertex buffer offset to the beginning of the group's vertices
[render_encoder setVertexBufferOffset:buffer_offset atIndex:0];
// NOTE(yuval): Draw the vertices
[render_encoder drawPrimitives:MTLPrimitiveTypeTriangle
vertexStart:0
vertexCount:vertex_count];
buffer_offset += (vertex_count * sizeof(Render_Vertex));
}
}
[render_encoder endEncoding];
// NOTE(yuval): Schedule a present once the framebuffer is complete using the current drawable
[command_buffer presentDrawable:view.currentDrawable];
[command_buffer addCompletedHandler:^(id<MTLCommandBuffer>){
dispatch_async(dispatch_get_main_queue(), ^{
[self add_reusable_buffer:buffer];
});
}];
}
// NOTE(yuval): Finalize rendering here and push the command buffer to the GPU
[command_buffer commit];
#if FRED_INTERNAL
[capture_scope endScope];
#endif
}
- (u32)get_texture_of_dim:(Vec3_i32)dim kind:(Texture_Kind)kind{
u32 handle = next_texture_handle_index;
// NOTE(yuval): Create a texture descriptor
MTLTextureDescriptor *texture_descriptor = [[MTLTextureDescriptor alloc] init];
texture_descriptor.textureType = MTLTextureType2DArray;
texture_descriptor.pixelFormat = MTLPixelFormatR8Unorm;
texture_descriptor.width = dim.x;
texture_descriptor.height = dim.y;
texture_descriptor.depth = dim.z;
// NOTE(yuval): Create the texture from the device using the descriptor and add it to the textures array
Metal_Texture texture = [device newTextureWithDescriptor:texture_descriptor];
textures[handle] = texture;
next_texture_handle_index += 1;
return handle;
}
- (b32)fill_texture:(u32)handle kind:(Texture_Kind)kind pos:(Vec3_i32)p dim:(Vec3_i32)dim data:(void*)data{
b32 result = false;
if (data){
Metal_Texture texture = textures[handle];
if (texture != 0){
MTLRegion replace_region = {
{(NSUInteger)p.x, (NSUInteger)p.y, (NSUInteger)p.z},
{(NSUInteger)dim.x, (NSUInteger)dim.y, (NSUInteger)dim.z}
};
// NOTE(yuval): Fill the texture with data
[texture replaceRegion:replace_region
mipmapLevel:0
withBytes:data
bytesPerRow:dim.x];
result = true;
}
}
return result;
}
- (void)bind_texture:(u32)handle encoder:(id<MTLRenderCommandEncoder>)render_encoder{
Metal_Texture texture = textures[handle];
if (texture != 0){
[render_encoder setFragmentTexture:texture
atIndex:0];
}
}
- (Metal_Buffer*)get_reusable_buffer_with_size:(NSUInteger)size{
// NOTE(yuval): This routine is a modified version of Dear ImGui's MetalContext::dequeueReusableBufferOfLength in imgui_impl_metal.mm
u64 now = system_now_time();
// NOTE(yuval): Purge old buffers that haven't been useful for a while
if ((now - last_buffer_cache_purge_time) > 1000000){
Node prev_buffer_cache = buffer_cache;
dll_init_sentinel(&buffer_cache);
for (Node *node = prev_buffer_cache.next;
node != &buffer_cache;
node = node->next){
Metal_Buffer *candidate = CastFromMember(Metal_Buffer, node, node);
if (candidate->last_reuse_time > last_buffer_cache_purge_time){
dll_insert(&buffer_cache, node);
}
}
last_buffer_cache_purge_time = now;
}
// NOTE(yuval): See if we have a buffer we can reuse
Metal_Buffer *best_candidate = 0;
for (Node *node = buffer_cache.next;
node != &buffer_cache;
node = node->next){
Metal_Buffer *candidate = CastFromMember(Metal_Buffer, node, node);
if ((candidate->size >= size) && ((!best_candidate) || (best_candidate->last_reuse_time > candidate->last_reuse_time))){
best_candidate = candidate;
}
}
Metal_Buffer *result;
if (best_candidate){
// NOTE(yuval): A best candidate has been found! Remove it from the buffer list and set its last reuse time.
dll_remove(&best_candidate->node);
best_candidate->last_reuse_time = now;
result = best_candidate;
} else{
// NOTE(yuval): No luck; make a new buffer.
result = metal__make_buffer(size, device);
}
return result;
}
- (void)add_reusable_buffer:(Metal_Buffer*)buffer{
// NOTE(yuval): This routine is a modified version of Dear ImGui's MetalContext::enqueueReusableBuffer in imgui_impl_metal.mm
dll_insert(&buffer_cache, &buffer->node);
}
@end

25
metal/AAPLShaderTypes.h Normal file
View File

@ -0,0 +1,25 @@
/*
See LICENSE folder for this samples licensing information.
Abstract:
Header containing types and enum constants shared between Metal shaders and C/ObjC source
*/
#ifndef AAPLShaderTypes_h
#define AAPLShaderTypes_h
#undef clamp
#include <simd/simd.h>
#define clamp(a,x,b) clamp_((a),(x),(b))
// This structure defines the layout of vertices sent to the vertex
// shader. This header is shared between the .metal shader and C code, to guarantee that
// the layout of the vertex array in the C code matches the layout that the .metal
// vertex shader expects.
typedef struct
{
vector_float2 position;
vector_float4 color;
} AAPLVertex;
#endif /* AAPLShaderTypes_h */

64
metal/AAPLShaders.metal Normal file
View File

@ -0,0 +1,64 @@
/*
See LICENSE folder for this samples licensing information.
Abstract:
Metal shaders used for this sample
*/
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
// Include header shared between this Metal shader code and C code executing Metal API commands.
#import "AAPLShaderTypes.h"
// Vertex shader outputs and fragment shader inputs
typedef struct
{
// The [[position]] attribute of this member indicates that this value
// is the clip space position of the vertex when this structure is
// returned from the vertex function.
float4 position [[position]];
// Since this member does not have a special attribute, the rasterizer
// interpolates its value with the values of the other triangle vertices
// and then passes the interpolated value to the fragment shader for each
// fragment in the triangle.
float4 color;
} RasterizerData;
vertex RasterizerData
vertexShader(uint vertexID [[vertex_id]],
constant AAPLVertex *vertices [[buffer(AAPLVertexInputIndexVertices)]],
constant vector_uint2 *viewportSizePointer [[buffer(AAPLVertexInputIndexViewportSize)]])
{
RasterizerData out;
// Index into the array of positions to get the current vertex.
// The positions are specified in pixel dimensions (i.e. a value of 100
// is 100 pixels from the origin).
float2 pixelSpacePosition = vertices[vertexID].position.xy;
// Get the viewport size and cast to float.
vector_float2 viewportSize = vector_float2(*viewportSizePointer);
// To convert from positions in pixel space to positions in clip-space,
// divide the pixel coordinates by half the size of the viewport.
out.position = vector_float4(0.0, 0.0, 0.0, 1.0);
out.position.xy = pixelSpacePosition / (viewportSize / 2.0);
// Pass the input color directly to the rasterizer.
out.color = vertices[vertexID].color;
return out;
}
fragment float4 fragmentShader(RasterizerData in [[stage_in]])
{
// Return the interpolated color.
return in.color;
}

View File

@ -12,8 +12,6 @@
#if !defined(FRED_OPENGL_DEFINES_H)
#define FRED_OPENGL_DEFINES_H
#include <GL/gl.h>
#define GL_TEXTURE_MAX_LEVEL 0x813D
#define GL_MULTISAMPLE 0x809D
@ -224,9 +222,6 @@ typedef void GL_Debug_Function(GLenum src,
void *user_data);
typedef GL_Debug_Function *GLDEBUGPROC;
#define GL_FUNC(N,R,P) typedef R (CALL_CONVENTION N##_Function)P; N##_Function *N = 0;
#include "4ed_opengl_funcs.h"
#endif
// BOTTOM

View File

@ -9,8 +9,6 @@
// TOP
#include "4ed_opengl_defines.h"
internal void
gl__bind_texture(Render_Target *t, i32 texid){
if (t->bound_texture != texid){
@ -225,11 +223,16 @@ gl_render(Render_Target *t){
#if !SHIP_MODE
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, 0, false);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, 0, false);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0, 0, true);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, 0, true);
glDebugMessageCallback(gl__error_callback, 0);
if (glDebugMessageControl){
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, 0, false);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, 0, false);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0, 0, true);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, 0, true);
}
if (glDebugMessageCallback){
glDebugMessageCallback(gl__error_callback, 0);
}
#endif
////////////////////////////////
@ -256,7 +259,7 @@ gl_render(Render_Target *t){
////////////////////////////////
{
{
t->fallback_texture_id = gl__get_texture(V3i32(2, 2, 1), TextureKind_Mono);
u8 white_block[] = { 0xFF, 0xFF, 0xFF, 0xFF, };
gl__fill_texture(TextureKind_Mono, 0, V3i32(0, 0, 0), V3i32(2, 2, 1), white_block);
@ -282,6 +285,7 @@ gl_render(Render_Target *t){
t->free_texture_first = 0;
t->free_texture_last = 0;
u64 begin_draw = system_now_time();
for (Render_Group *group = t->group_first;
group != 0;
group = group->next){

1361
platform_mac/mac_4ed.mm Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,927 @@
/* macOS System/Graphics/Font API Implementations */
/********************/
/* System API */
/********************/
////////////////////////////////
function
system_get_path_sig(){
String_Const_u8 result = {};
switch (path_code){
case SystemPath_CurrentDirectory:
{
char *working_dir = getcwd(NULL, 0);
u64 working_dir_length = cstring_length(working_dir);
// TODO(yuval): Maybe use push_string_copy instead
u8 *out = push_array(arena, u8, working_dir_length);
block_copy(out, working_dir, working_dir_length);
free(working_dir);
result = SCu8(out, working_dir_length);
} break;
case SystemPath_Binary:
{
local_persist b32 has_stashed_4ed_path = false;
if (!has_stashed_4ed_path){
local_const i32 binary_path_capacity = KB(32);
u8 *memory = (u8*)system_memory_allocate(binary_path_capacity, file_name_line_number_lit_u8);
pid_t pid = getpid();
i32 size = proc_pidpath(pid, memory, binary_path_capacity);
Assert(size <= binary_path_capacity - 1);
mac_vars.binary_path = SCu8(memory, size);
mac_vars.binary_path = string_remove_last_folder(mac_vars.binary_path);
mac_vars.binary_path.str[mac_vars.binary_path.size] = 0;
has_stashed_4ed_path = true;
}
result = push_string_copy(arena, mac_vars.binary_path);
} break;
}
return(result);
}
function
system_get_canonical_sig(){
NSString *path_ns_str =
[[NSString alloc] initWithBytes:name.data length:name.size encoding:NSUTF8StringEncoding];
NSString *standardized_path_ns_str = [path_ns_str stringByStandardizingPath];
String_Const_u8 standardized_path = SCu8((u8*)[standardized_path_ns_str UTF8String],[standardized_path_ns_str lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
String_Const_u8 result = push_string_copy(arena, standardized_path);
[path_ns_str release];
return(result);
}
////////////////////////////////
function File_Attributes
mac_get_file_attributes(struct stat file_stat) {
File_Attributes result;
result.size = file_stat.st_size;
result.last_write_time = file_stat.st_mtimespec.tv_sec;
result.flags = 0;
if (S_ISDIR(file_stat.st_mode)) {
result.flags |= FileAttribute_IsDirectory;
}
return(result);
}
function inline File_Attributes
mac_file_attributes_from_path(char *path) {
File_Attributes result = {};
struct stat file_stat;
if (stat(path, &file_stat) == 0){
result = mac_get_file_attributes(file_stat);
}
return(result);
}
function inline File_Attributes
mac_file_attributes_from_fd(i32 fd) {
File_Attributes result = {};
struct stat file_stat;
if (fstat(fd, &file_stat) == 0){
result = mac_get_file_attributes(file_stat);
}
return(result);
}
function
system_get_file_list_sig(){
File_List result = {};
u8 *c_directory = push_array(arena, u8, directory.size + 1);
block_copy(c_directory, directory.str, directory.size);
c_directory[directory.size] = 0;
DIR *dir = opendir((char*)c_directory);
if (dir){
File_Info* first = 0;
File_Info* last = 0;
i32 count = 0;
for (struct dirent *entry = readdir(dir);
entry;
entry = readdir(dir)){
char *c_file_name = entry->d_name;
String_Const_u8 file_name = SCu8(c_file_name);
if (string_match(file_name, string_u8_litexpr(".")) || string_match(file_name, string_u8_litexpr(".."))){
continue;
}
File_Info *info = push_array(arena, File_Info, 1);
sll_queue_push(first, last, info);
count += 1;
info->file_name = push_string_copy(arena, file_name);
// NOTE(yuval): Get file attributes
{
Temp_Memory temp = begin_temp(arena);
b32 append_slash = false;
u64 file_path_size = directory.size + file_name.size;
if (string_get_character(directory, directory.size - 1) != '/'){
append_slash = true;
file_path_size += 1;
}
char *file_path = push_array(arena, char, file_path_size + 1);
char *file_path_at = file_path;
block_copy(file_path_at, directory.str, directory.size);
file_path_at += directory.size;
if (append_slash){
*file_path_at = '/';
file_path_at += 1;
}
block_copy(file_path_at, file_name.str, file_name.size);
file_path_at += file_name.size;
*file_path_at = 0;
info->attributes = mac_file_attributes_from_path(file_path);
end_temp(temp);
}
}
closedir(dir);
result.infos = push_array(arena, File_Info*, count);
result.count = count;
i32 index = 0;
for (File_Info *node = first;
node != 0;
node = node->next){
result.infos[index] = node;
index += 1;
}
}
return(result);
}
function
system_quick_file_attributes_sig(){
Temp_Memory temp = begin_temp(scratch);
char *c_file_name = push_array(scratch, char, file_name.size + 1);
block_copy(c_file_name, file_name.str, file_name.size);
c_file_name[file_name.size] = 0;
File_Attributes result = mac_file_attributes_from_path(c_file_name);
end_temp(temp);
return(result);
}
function inline Plat_Handle
mac_to_plat_handle(i32 fd){
Plat_Handle result = *(Plat_Handle*)(&fd);
return(result);
}
function inline i32
mac_to_fd(Plat_Handle handle){
i32 result = *(i32*)(&handle);
return(result);
}
function
system_load_handle_sig(){
b32 result = false;
i32 fd = open(file_name, O_RDONLY);
if ((fd != -1) && (fd != 0)) {
*out = mac_to_plat_handle(fd);
result = true;
}
return(result);
}
function
system_load_attributes_sig(){
i32 fd = mac_to_fd(handle);
File_Attributes result = mac_file_attributes_from_fd(fd);
return(result);
}
function
system_load_file_sig(){
i32 fd = mac_to_fd(handle);
do{
ssize_t bytes_read = read(fd, buffer, size);
if (bytes_read == -1){
if (errno != EINTR){
// NOTE(yuval): An error occured while reading from the file descriptor
break;
}
} else{
size -= bytes_read;
buffer += bytes_read;
}
} while (size > 0);
b32 result = (size == 0);
return(result);
}
function
system_load_close_sig(){
b32 result = true;
i32 fd = mac_to_fd(handle);
if (close(fd) == -1){
// NOTE(yuval): An error occured while close the file descriptor
result = false;
}
return(result);
}
function
system_save_file_sig(){
File_Attributes result = {};
i32 fd = open(file_name, O_WRONLY | O_TRUNC | O_CREAT, 00640);
if (fd != -1) {
do{
ssize_t bytes_written = write(fd, data.str, data.size);
if (bytes_written == -1){
if (errno != EINTR){
// NOTE(yuval): An error occured while writing to the file descriptor
break;
}
} else{
data.size -= bytes_written;
data.str += bytes_written;
}
} while (data.size > 0);
if (data.size == 0) {
result = mac_file_attributes_from_fd(fd);
}
close(fd);
}
return(result);
}
////////////////////////////////
function inline System_Library
mac_to_system_library(void *dl_handle){
System_Library result = *(System_Library*)(&dl_handle);
return(result);
}
function inline void*
mac_to_dl_handle(System_Library system_lib){
void *result = *(void**)(&system_lib);
return(result);
}
function
system_load_library_sig(){
b32 result = false;
void *lib = 0;
// NOTE(yuval): Open library handle
{
Temp_Memory temp = begin_temp(scratch);
char *c_file_name = push_array(scratch, char, file_name.size + 1);
block_copy(c_file_name, file_name.str, file_name.size);
c_file_name[file_name.size] = 0;
lib = dlopen(c_file_name, RTLD_LAZY | RTLD_GLOBAL);
end_temp(temp);
}
if (lib){
*out = mac_to_system_library(lib);
result = true;
}
return(result);
}
function
system_release_library_sig(){
void *lib = mac_to_dl_handle(handle);
i32 rc = dlclose(lib);
b32 result = (rc == 0);
return(result);
}
function
system_get_proc_sig(){
void *lib = mac_to_dl_handle(handle);
Void_Func *result = (Void_Func*)dlsym(lib, proc_name);
return(result);
}
////////////////////////////////
function
system_now_time_sig(){
u64 now = mach_absolute_time();
// NOTE(yuval): Now time nanoseconds conversion
f64 now_nano = (f64)((f64)now *
((f64)mac_vars.timebase_info.numer /
(f64)mac_vars.timebase_info.denom));
// NOTE(yuval): Conversion to useconds
u64 result = (u64)(now_nano * 1.0E-3);
return(result);
}
function
system_wake_up_timer_create_sig(){
Mac_Object *object = mac_alloc_object(MacObjectKind_Timer);
dll_insert(&mac_vars.timer_objects, &object->node);
object->timer = nil;
Plat_Handle result = mac_to_plat_handle(object);
return(result);
}
function
system_wake_up_timer_release_sig(){
Mac_Object *object = mac_to_object(handle);
if (object->kind == MacObjectKind_Timer){
if ((object->timer != nil) && [object->timer isValid]) {
[object->timer invalidate];
mac_free_object(object);
}
}
}
function
system_wake_up_timer_set_sig(){
Mac_Object *object = mac_to_object(handle);
if (object->kind == MacObjectKind_Timer){
f64 time_seconds = ((f64)time_milliseconds / 1000.0);
object->timer = [NSTimer scheduledTimerWithTimeInterval:time_seconds
target:mac_vars.view
selector:@selector(request_display)
userInfo:nil repeats:NO];
}
}
function
system_signal_step_sig(){
if (!mac_vars.step_requested){
[NSTimer scheduledTimerWithTimeInterval:0.0
target:mac_vars.view
selector:@selector(request_display)
userInfo:nil repeats:NO];
mac_vars.step_requested = true;
}
}
function
system_sleep_sig(){
u64 nanoseconds = (microseconds * Thousand(1));
u64 abs_sleep_time = (u64)((f64)nanoseconds *
((f64)mac_vars.timebase_info.denom /
(f64)mac_vars.timebase_info.numer));
u64 now = mach_absolute_time();
mach_wait_until(now + abs_sleep_time);
}
////////////////////////////////
function
system_post_clipboard_sig(){
Arena *arena = &mac_vars.clip_post_arena;
if (arena->base_allocator == 0){
*arena = make_arena_system();
} else{
linalloc_clear(arena);
}
mac_vars.clip_post.str = push_array(arena, u8, str.size + 1);
if (mac_vars.clip_post.str != 0){
block_copy(mac_vars.clip_post.str, str.str, str.size);
mac_vars.clip_post.str[str.size] = 0;
mac_vars.clip_post.size = str.size;
} else{
// NOTE(yuval): Failed to allocate buffer for clipboard post
}
}
////////////////////////////////
function
system_cli_call_sig(){
b32 result = false;
int pipe_fds[2];
if (pipe(pipe_fds) == -1){
perror("system_cli_call: pipe");
return(false);
}
pid_t child_pid = fork();
if (child_pid == -1){
perror("system_cli_call: fork");
return(false);
}
enum { PIPE_FD_READ, PIPE_FD_WRITE };
if (child_pid == 0){
// NOTE(yuval): Child Process
close(pipe_fds[PIPE_FD_READ]);
dup2(pipe_fds[PIPE_FD_WRITE], STDOUT_FILENO);
dup2(pipe_fds[PIPE_FD_WRITE], STDERR_FILENO);
if (chdir(path) == -1){
perror("system_cli_call: chdir");
exit(1);
}
char* argv[] = {"sh", "-c", script, 0};
if (execv("/bin/sh", argv) == -1){
perror("system_cli_call: execv");
}
exit(1);
} else{
// NOTE(yuval): Parent Process
close(pipe_fds[PIPE_FD_WRITE]);
*(pid_t*)&cli_out->proc = child_pid;
*(int*)&cli_out->out_read = pipe_fds[PIPE_FD_READ];
*(int*)&cli_out->out_write = pipe_fds[PIPE_FD_WRITE];
mac_vars.running_cli += 1;
}
return(true);
}
function
system_cli_begin_update_sig(){
// NOTE(yuval): Nothing to do here.
}
function
system_cli_update_step_sig(){
int pipe_read_fd = *(int*)&cli->out_read;
fd_set fds;
FD_ZERO(&fds);
FD_SET(pipe_read_fd, &fds);
struct timeval tv = {};
size_t space_left = max;
char* ptr = dest;
while (space_left > 0 && (select(pipe_read_fd + 1, &fds, NULL, NULL, &tv) == 1)){
ssize_t num = read(pipe_read_fd, ptr, space_left);
if (num == -1){
perror("system_cli_update_step: read");
} else if (num == 0){
// NOTE(inso): EOF
break;
} else{
ptr += num;
space_left -= num;
}
}
*amount = (ptr - dest);
b32 result = ((ptr - dest) > 0);
return(result);
}
function
system_cli_end_update_sig(){
b32 close_me = false;
pid_t pid = *(pid_t*)&cli->proc;
int status;
if (pid && (waitpid(pid, &status, WNOHANG) > 0)){
cli->exit = WEXITSTATUS(status);
close(*(int*)&cli->out_read);
close(*(int*)&cli->out_write);
mac_vars.running_cli -= 1;
close_me = true;
}
return(close_me);
}
////////////////////////////////
function
system_open_color_picker_sig(){
NotImplemented;
}
function
system_get_screen_scale_factor_sig(){
f32 result = mac_vars.screen_scale_factor;
return(result);
}
////////////////////////////////
function void*
mac_thread_wrapper(void *ptr){
Mac_Object *object = (Mac_Object*)ptr;
Thread_Function *proc = object->thread.proc;
void *object_ptr = object->thread.ptr;
pthread_mutex_lock(&mac_vars.thread_launch_mutex);
{
mac_vars.waiting_for_launch = false;
pthread_cond_signal(&mac_vars.thread_launch_cv);
}
pthread_mutex_unlock(&mac_vars.thread_launch_mutex);
proc(object_ptr);
return(0);
}
function
system_thread_launch_sig(){
Mac_Object *object = mac_alloc_object(MacObjectKind_Thread);
object->thread.proc = proc;
object->thread.ptr = ptr;
pthread_mutex_lock(&mac_vars.thread_launch_mutex);
{
mac_vars.waiting_for_launch = true;
pthread_create(&object->thread.thread, 0, mac_thread_wrapper, object);
while (mac_vars.waiting_for_launch){
pthread_cond_wait(&mac_vars.thread_launch_cv, &mac_vars.thread_launch_mutex);
}
}
pthread_mutex_unlock(&mac_vars.thread_launch_mutex);
System_Thread result = mac_to_plat_handle(object);
return(result);
}
function
system_thread_join_sig(){
Mac_Object *object = mac_to_object(thread);
if (object->kind == MacObjectKind_Thread){
pthread_join(object->thread.thread, 0);
}
}
function
system_thread_free_sig(){
Mac_Object* object = mac_to_object(thread);
if (object->kind == MacObjectKind_Thread){
mac_free_object(object);
}
}
function
system_thread_get_id_sig(){
pthread_t id = pthread_self();
i32 result = *(i32*)(&id);
return(result);
}
function
system_mutex_make_sig(){
Mac_Object *object = mac_alloc_object(MacObjectKind_Mutex);
pthread_mutex_init(&object->mutex, 0);
System_Mutex result = mac_to_plat_handle(object);
return(result);
}
function
system_mutex_acquire_sig(){
Mac_Object *object = mac_to_object(mutex);
if (object->kind == MacObjectKind_Mutex){
pthread_mutex_lock(&object->mutex);
}
}
function
system_mutex_release_sig(){
Mac_Object *object = mac_to_object(mutex);
if (object->kind == MacObjectKind_Mutex){
pthread_mutex_unlock(&object->mutex);
}
}
function
system_mutex_free_sig(){
Mac_Object *object = mac_to_object(mutex);
if (object->kind == MacObjectKind_Mutex){
pthread_mutex_destroy(&object->mutex);
mac_free_object(object);
}
}
function
system_acquire_global_frame_mutex_sig(){
if (tctx->kind == ThreadKind_AsyncTasks){
system_mutex_acquire(mac_vars.global_frame_mutex);
}
}
function
system_release_global_frame_mutex_sig(){
if (tctx->kind == ThreadKind_AsyncTasks){
system_mutex_release(mac_vars.global_frame_mutex);
}
}
function
system_condition_variable_make_sig(){
Mac_Object *object = mac_alloc_object(MacObjectKind_CV);
pthread_cond_init(&object->cv, 0);
System_Condition_Variable result = mac_to_plat_handle(object);
return(result);
}
function
system_condition_variable_wait_sig(){
Mac_Object *object_cv = mac_to_object(cv);
Mac_Object *object_mutex = mac_to_object(mutex);
if ((object_cv->kind == MacObjectKind_CV) && (object_mutex->kind == MacObjectKind_Mutex)){
pthread_cond_wait(&object_cv->cv, &object_mutex->mutex);
}
}
function
system_condition_variable_signal_sig(){
Mac_Object *object = mac_to_object(cv);
if (object->kind == MacObjectKind_CV){
pthread_cond_signal(&object->cv);
}
}
function
system_condition_variable_free_sig(){
Mac_Object *object = mac_to_object(cv);
if (object->kind == MacObjectKind_CV){
pthread_cond_destroy(&object->cv);
mac_free_object(object);
}
}
////////////////////////////////
struct Memory_Annotation_Tracker_Node{
Memory_Annotation_Tracker_Node *next;
Memory_Annotation_Tracker_Node *prev;
String_Const_u8 location;
u64 size;
};
struct Memory_Annotation_Tracker{
Memory_Annotation_Tracker_Node *first;
Memory_Annotation_Tracker_Node *last;
i32 count;
};
global Memory_Annotation_Tracker memory_tracker = {};
global pthread_mutex_t memory_tracker_mutex;
global_const u64 ALLOCATION_SIZE_ADJUSTMENT = 64;
function void*
mac_memory_allocate_extended(void *base, u64 size, String_Const_u8 location){
u64 adjusted_size = size + ALLOCATION_SIZE_ADJUSTMENT;
void *memory = mmap(base, adjusted_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
Memory_Annotation_Tracker_Node *node = (Memory_Annotation_Tracker_Node*)memory;
pthread_mutex_lock(&memory_tracker_mutex);
{
zdll_push_back(memory_tracker.first, memory_tracker.last, node);
memory_tracker.count += 1;
}
pthread_mutex_unlock(&memory_tracker_mutex);
node->location = location;
node->size = size;
void* result = (node + 1);
return(result);
}
function void
mac_memory_free_extended(void *ptr){
Memory_Annotation_Tracker_Node *node = (Memory_Annotation_Tracker_Node*)ptr;
node -= 1;
pthread_mutex_lock(&memory_tracker_mutex);
{
zdll_remove(memory_tracker.first, memory_tracker.last, node);
memory_tracker.count -= 1;
}
pthread_mutex_unlock(&memory_tracker_mutex);
munmap(node, node->size + ALLOCATION_SIZE_ADJUSTMENT);
}
function
system_memory_allocate_sig(){
void* result = mac_memory_allocate_extended(0, size, location);
return(result);
}
function
system_memory_set_protection_sig(){
b32 result = true;
int protect = 0;
switch (flags & 0x7){
case 0:
{
protect = PROT_NONE;
} break;
case MemProtect_Read:
{
protect = PROT_READ;
} break;
case MemProtect_Write:
case MemProtect_Read | MemProtect_Write:
{
protect = PROT_READ | PROT_WRITE;
} break;
case MemProtect_Execute:
{
protect = PROT_EXEC;
} break;
case MemProtect_Execute | MemProtect_Read:
{
protect = PROT_READ | PROT_EXEC;
} break;
// NOTE(inso): some W^X protection things might be unhappy about this one
case MemProtect_Execute | MemProtect_Write:
case MemProtect_Execute | MemProtect_Write | MemProtect_Read:
{
protect = PROT_READ | PROT_WRITE | PROT_EXEC;
} break;
}
Memory_Annotation_Tracker_Node *node = (Memory_Annotation_Tracker_Node*)ptr;
node -= 1;
if(mprotect(node, size, protect) == -1){
result = false;
}
return(result);
}
function
system_memory_free_sig(){
mac_memory_free_extended(ptr);
}
function
system_memory_annotation_sig(){
Memory_Annotation result = {};
pthread_mutex_lock(&memory_tracker_mutex);
{
for (Memory_Annotation_Tracker_Node *node = memory_tracker.first;
node != 0;
node = node->next){
// TODO(yuval): Fix the API so that annotations would not mess with the system memory.
// Memory_Annotation_Node *r_node = push_array(arena, Memory_Annotation_Node, 1);
Memory_Annotation_Node *r_node = (Memory_Annotation_Node*)malloc(sizeof(Memory_Annotation_Node));
sll_queue_push(result.first, result.last, r_node);
result.count += 1;
r_node->location = node->location;
r_node->address = node + 1;
r_node->size = node->size;
}
}
pthread_mutex_unlock(&memory_tracker_mutex);
return(result);
}
////////////////////////////////
function
system_show_mouse_cursor_sig(){
mac_vars.cursor_show = show;
}
function
system_set_fullscreen_sig(){
// NOTE(yuval): Read comment in system_set_fullscreen_sig in win32_4ed.cpp
mac_vars.do_toggle = (mac_vars.full_screen != full_screen);
b32 success = true;
return(success);
}
function
system_is_fullscreen_sig(){
// NOTE(yuval): Read comment in system_is_fullscreen_sig in win32_4ed.cpp
b32 result = (mac_vars.full_screen != mac_vars.do_toggle);
return(result);
}
function
system_get_keyboard_modifiers_sig(){
Input_Modifier_Set result = copy_modifier_set(arena, &mac_vars.input_chunk.pers.modifiers);
return(result);
}
////////////////////////////////
/**********************/
/* Graphics API */
/**********************/
////////////////////////////////
function
graphics_get_texture_sig(){
u32 result = renderer->get_texture(renderer, dim, texture_kind);
return(result);
}
function
graphics_fill_texture_sig(){
b32 result = renderer->fill_texture(renderer, texture_kind, texture, p, dim, data);
return(result);
}
////////////////////////////////
/******************/
/* Font API */
/******************/
////////////////////////////////
function
font_make_face_sig(){
Face* result = ft__font_make_face(arena, description, scale_factor);
return(result);
}
////////////////////////////////

View File

@ -0,0 +1,83 @@
/* Mac Metal layer for 4coder */
#import "metal/4ed_metal_render.mm"
////////////////////////////////
struct Mac_Metal{
Mac_Renderer base;
Metal_Renderer *renderer;
MTKView *view;
};
////////////////////////////////
function
mac_render_sig(mac_metal__render){
#if defined(FRED_INTERNAL)
printf("Redering using Metal!\n");
#endif
Mac_Metal *metal = (Mac_Metal*)renderer;
[metal->view draw];
}
function
mac_get_texture_sig(mac_metal__get_texture){
Mac_Metal *metal = (Mac_Metal*)renderer;
u32 result = [metal->renderer get_texture_of_dim:dim
kind:texture_kind];
return(result);
}
function
mac_fill_texture_sig(mac_metal__fill_texture){
Mac_Metal *metal = (Mac_Metal*)renderer;
b32 result = [metal->renderer fill_texture:texture
kind:texture_kind
pos:p
dim:dim
data:data];
return(result);
}
function Mac_Metal*
mac_metal__init(NSWindow *window, Render_Target *target){
// NOTE(yuval): Create the Mac Metal rendere
Mac_Metal *metal = (Mac_Metal*)system_memory_allocate(sizeof(Mac_Metal),
file_name_line_number_lit_u8);
metal->base.render = mac_metal__render;
metal->base.get_texture = mac_metal__get_texture;
metal->base.fill_texture = mac_metal__fill_texture;
// NOTE(yuval): Create the Metal view
NSView *content_view = [window contentView];
metal->view = [[MTKView alloc] initWithFrame:[content_view bounds]];
[metal->view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[metal->view setPaused:YES];
[metal->view setEnableSetNeedsDisplay:NO];
metal->view.device = MTLCreateSystemDefaultDevice();
// NOTE(yuval): Add the Metal view as a subview of the window
[content_view addSubview:metal->view];
// NOTE(yuval): Create the Metal renderer and set it as the Metal view's delegate
metal->renderer = [[Metal_Renderer alloc] initWithMetalKitView:metal->view target:target];
metal->view.delegate = metal->renderer;
return(metal);
}
////////////////////////////////
// TODO(yuval): This function should be exported to a DLL
function
mac_load_renderer_sig(mac_load_metal_renderer){
Mac_Renderer *renderer = (Mac_Renderer*)mac_metal__init(window, target);
return(renderer);
}

View File

@ -782,7 +782,7 @@ osx_init(){
osxvars.input.first_step = true;
//
// HACK(allen):
// HACK(allen):
// Previously zipped stuff is here, it should be zipped in the new pattern now.
//

View File

@ -814,9 +814,9 @@ osx_list_loadable_fonts(void){
NSString *font_n = fonts[i];
char *font_n_c = (char*)[font_n UTF8String];
NSFont *font = [font_manager
fontWithFamily:font_n
traits:NSUnboldFontMask|NSUnitalicFontMask
weight:5
fontWithFamily:font_n
traits:NSUnboldFontMask|NSUnitalicFontMask
weight:5
size:12];
NSString *path = get_font_path(font);
char *path_c = 0;

View File

@ -0,0 +1,183 @@
/* Mac OpenGL layer for 4coder */
#include "mac_4ed_renderer.h"
////////////////////////////////
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl.h>
#include "opengl/4ed_opengl_defines.h"
#define GL_FUNC(N,R,P) typedef R (CALL_CONVENTION N##_Function)P; N##_Function *N = 0;
#include "mac_4ed_opengl_funcs.h"
////////////////////////////////
#include "opengl/4ed_opengl_render.cpp"
////////////////////////////////
@interface OpenGL_View : NSOpenGLView
- (void)init_gl;
- (void)render:(Render_Target*)target;
@end
////////////////////////////////
struct Mac_OpenGL{
Mac_Renderer base;
OpenGL_View *view;
};
////////////////////////////////
@implementation OpenGL_View{
b32 gl_is_initialized;
}
- (id)init{
self = [super init];
if (self == nil){
return nil;
}
gl_is_initialized = false;
[self init_gl];
return self;
}
- (void)dealloc{
[super dealloc];
}
- (void)prepareOpenGL{
[super prepareOpenGL];
[[self openGLContext] makeCurrentContext];
// NOTE(yuval): Setup vsync
GLint swap_int = 1;
[[self openGLContext] setValues:&swap_int forParameter:NSOpenGLCPSwapInterval];
}
- (void)awakeFromNib{
[self init_gl];
}
- (void)reshape{
[super reshape];
[[self openGLContext] makeCurrentContext];
[[self openGLContext] update];
}
- (void)init_gl{
if (gl_is_initialized){
return;
}
// NOTE(yuval): Setup OpenGL
NSOpenGLPixelFormatAttribute opengl_attrs[] = {
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
NSOpenGLPFAAccelerated,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAColorSize, 32,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFADepthSize, 24,
0
};
NSOpenGLPixelFormat *pixel_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:opengl_attrs];
if (pixel_format == nil){
fprintf(stderr, "Error creating OpenGLPixelFormat\n");
exit(1);
}
NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:pixel_format shareContext:nil];
[self setPixelFormat:pixel_format];
[self setOpenGLContext:context];
[context makeCurrentContext];
[pixel_format release];
gl_is_initialized = true;
}
- (void)render:(Render_Target*)target{
Assert(gl_is_initialized);
CGLLockContext([[self openGLContext] CGLContextObj]);
[[self openGLContext] makeCurrentContext];
gl_render(target);
[[self openGLContext] flushBuffer];
CGLUnlockContext([[self openGLContext] CGLContextObj]);
}
@end
////////////////////////////////
function
mac_render_sig(mac_gl__render){
#if defined(FRED_INTERNAL)
printf("Redering using OpenGL!\n");
#endif
Mac_OpenGL *gl = (Mac_OpenGL*)renderer;
[gl->view render:target];
}
function
mac_get_texture_sig(mac_gl__get_texture){
u32 result = gl__get_texture(dim, texture_kind);
return(result);
}
function
mac_fill_texture_sig(mac_gl__fill_texture){
b32 result = gl__fill_texture(texture_kind, texture, p, dim, data);
return(result);
}
function Mac_OpenGL*
mac_gl__init(NSWindow *window, Render_Target *target){
// NOTE(yuval): Create the Mac OpenGL Renderer
Mac_OpenGL *gl = (Mac_OpenGL*)system_memory_allocate(sizeof(Mac_OpenGL),
file_name_line_number_lit_u8);
gl->base.render = mac_gl__render;
gl->base.get_texture = mac_gl__get_texture;
gl->base.fill_texture = mac_gl__fill_texture;
// NOTE(yuval): Create the OpenGL view
NSView *content_view = [window contentView];
gl->view = [[OpenGL_View alloc] init];
[gl->view setFrame:[content_view bounds]];
[gl->view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[gl->view setWantsBestResolutionOpenGLSurface:YES];
// NOTE(yuval): Add the OpenGL view as a subview of the window
[content_view addSubview:gl->view];
// NOTE(yuval): Load gl functions
void *gl_image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
#define GL_FUNC(f,R,P) ((f) = (f##_Function*)dlsym(gl_image, #f));
#include "mac_4ed_opengl_funcs.h"
return(gl);
}
////////////////////////////////
// TODO(yuval): This function should be exported to a DLL
function
mac_load_renderer_sig(mac_load_opengl_renderer){
Mac_Renderer *renderer = (Mac_Renderer*)mac_gl__init(window, target);
return(renderer);
}

View File

@ -0,0 +1,17 @@
/* Mac OpenGL functions for 4coder */
// TOP
/* Usage:
#define GL_FUNC(N,R,P) ~~~~
#include "4ed_opengl_funcs.h"
*/
GL_FUNC(glDebugMessageControl, void, (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled))
GL_FUNC(glDebugMessageCallback, void, (GLDEBUGPROC callback, const void *userParam))
GL_FUNC(glGenVertexArrays, void, (GLsizei n, GLuint *arrays))
GL_FUNC(glBindVertexArray, void, (GLuint array))
GL_FUNC(glVertexAttribIPointer, void, (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer))
#undef GL_FUNC

View File

@ -0,0 +1,44 @@
/* Mac Renderer Abstraction */
#if !defined(FRED_MAC_RENDERER_H)
#define FRED_MAC_RENDERER_H
////////////////////////////////
// TODO(yuval): This should be refactored into a platform independent renderer
struct Mac_Renderer;
#define mac_render_sig(name) void name(Mac_Renderer *renderer, Render_Target *target)
typedef mac_render_sig(mac_render_type);
#define mac_get_texture_sig(name) u32 name(Mac_Renderer *renderer, Vec3_i32 dim, Texture_Kind texture_kind)
typedef mac_get_texture_sig(mac_get_texture_type);
#define mac_fill_texture_sig(name) b32 name(Mac_Renderer *renderer, Texture_Kind texture_kind, u32 texture, Vec3_i32 p, Vec3_i32 dim, void* data)
typedef mac_fill_texture_sig(mac_fill_texture_type);
typedef i32 Mac_Renderer_Kind;
enum{
MacRenderer_OpenGL,
MacRenderer_Metal,
//
MacRenderer_COUNT
};
struct Mac_Renderer{
mac_render_type *render;
mac_get_texture_type *get_texture;
mac_fill_texture_type *fill_texture;
};
////////////////////////////////
// NOTE(yuval): This is the actual platform dependent function that each renderer implementation implements and should be exported into a DLL
#define mac_load_renderer_sig(name) Mac_Renderer* name(NSWindow *window, Render_Target *target)
typedef mac_load_renderer_sig(mac_load_renderer_type);
////////////////////////////////
#endif

View File

@ -0,0 +1,26 @@
/* Mac Renderer Abstraction Implementation */
// TODO(yuval): This should NOT be included here once the renderer is exported to a DLL
#import "mac_4ed_opengl.mm"
#import "mac_4ed_metal.mm"
// TODO(yuval): Replace this array with an array of the paths to the renderer dlls
global mac_load_renderer_type *mac_renderer_load_functions[MacRenderer_COUNT] = {
mac_load_opengl_renderer,
mac_load_metal_renderer
};
function Mac_Renderer*
mac_init_renderer(Mac_Renderer_Kind kind, NSWindow *window, Render_Target *target){
// TODO(yuval): Import renderer load function from a DLL instead of using an array of the load functions. This would allow us to switch the renderer backend and implemented new backends with ease.
mac_load_renderer_type *load_renderer = mac_renderer_load_functions[kind];
Mac_Renderer *result = load_renderer(window, target);
if (!result){
mac_error_box("Unable to initialize the renderer!");
}
return result;
}

View File

@ -0,0 +1,24 @@
/* Types and functions for communication between C++ and Objective-C layers. */
#if !defined(MAC_OBJECTIVE_C_TO_CPP_LINKS_H)
#define MAC_OBJECTIVE_C_TO_CPP_LINKS_H
// In C++ layer
external String_Const_u8
mac_SCu8(u8* str, u64 size);
external String_Const_u8
mac_push_string_copy(Arena *arena, String_Const_u8 src);
external void
mac_init();
// In Objective-C layer
external String_Const_u8
mac_standardize_path(Arena* arena, String_Const_u8 path);
external i32
mac_get_binary_path(void* buffer, u32 size);
#endif

View File

@ -64,7 +64,7 @@ Sys_Memory_Allocate_Sig(system_memory_allocate){
return(result);
}
internal
internal
Sys_Memory_Set_Protection_Sig(system_memory_set_protection){
bool32 result = true;

View File

@ -335,7 +335,7 @@ system_set_fullscreen_sig(){
internal
system_is_fullscreen_sig(){
// NOTE(allen): Report the fullscreen status as it would be set at the beginning of the
// NOTE(allen): Report the fullscreen status as it would be set at the beginning of the
// next frame. That is, take into account all fullscreen toggle requests that have come in
// already this frame. Read: "full_screen XOR do_toggle"
b32 result = (win32vars.full_screen != win32vars.do_toggle);
@ -605,6 +605,9 @@ os_popup_error(char *title, char *message){
#include "4ed_font_provider_freetype.cpp"
#include <GL/gl.h>
#include "opengl/4ed_opengl_defines.h"
#define GL_FUNC(N,R,P) typedef R (CALL_CONVENTION N##_Function)P; N##_Function *N = 0;
#include "opengl/4ed_opengl_funcs.h"
#include "opengl/4ed_opengl_render.cpp"
internal

View File

@ -444,7 +444,7 @@ color_picker_hook(HWND Window, UINT Message, WPARAM WParam, LPARAM LParam){
// Would it have killed you to update rgbResult continuously, or at least
// provide a GetCurrentColor() call???
//
// Anyway, since the color picker doesn't tell us when the color is
// Anyway, since the color picker doesn't tell us when the color is
// changed, what we do is watch for messages that repaint the color
// swatch, which is dialog id 0x2c5, and then we sample it to see what
// color it is. No, I'm not fucking kidding, that's what we do.
@ -533,7 +533,7 @@ internal
system_open_color_picker_sig(){
// TODO(allen): review
// NOTE(casey): Because this is going to be used by a semi-permanent thread, we need to
// copy it to system memory where it can live as long as it wants, no matter what we do
// copy it to system memory where it can live as long as it wants, no matter what we do
// over here on the 4coder threads.
Color_Picker *perm = (Color_Picker*)system_memory_allocate(sizeof(Color_Picker), string_u8_litexpr(file_name_line_number));
*perm = *picker;