Author:ptrace Comitter:ptrace Date:2026-05-02 09:16:49 UTC

init

diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..805c007 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ # Jai .build /bin diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/README.md diff --git a/build.jai b/build.jai new file mode 100644 index 0000000..1abc4f7 --- /dev/null +++ b/build.jai @@ -0,0 +1,140 @@ #import "Basic"; #import "Compiler"; #import "File"; #import "Autorun"; build :: () {     args := get_build_options().compile_time_command_line;     // args     args_help               := array_find(args, "help");     args_compiler_silent    := array_find(args, "silent");     args_program_run        := array_find(args, "run");     args_build_release      := array_find(args, "release");     args_memory_debug       := array_find(args, "memory");     // program args     program_args := program_args_collect(args);     defer array_free(program_args);     // -----------------------------------------     w := compiler_create_workspace();     if !w {         log("Workspace creation failed.");         return;     }     set_build_options_dc(.{ do_output = false });     if args_help {         args_help_print();         return;     }     print("The workspace w is %\n", w);     make_directory_if_it_does_not_exist("bin");     make_directory_if_it_does_not_exist("bin/debug");     make_directory_if_it_does_not_exist("bin/release");     target_options := get_build_options(w);     target_options.output_executable_name = "program";     if args_compiler_silent  target_options.text_output_flags = 0;     if args_build_release {         build_release(w, *target_options);     } else {         build_debug(w, *target_options);     }     compiler_begin_intercept(w);     add_build_file(tprint("%src/main.jai", #filepath), w);     add_build_string(tprint("MEMORY_DEBUGGER_ENABLED :: %;", args_memory_debug), w);     compiler_response := message_loop();     compiler_end_intercept(w);     if !compiler_response {         log("Compiler response failed.");         return;     }     if args_program_run  run_build_result_of_workspace(w, program_args); } build_debug :: (w: Workspace, target_options: *Build_Options) {     log("Choosing debug options...");     target_options.backend =.X64;     target_options.output_path = "bin/debug";     set_optimization(target_options, Optimization_Type.DEBUG, true);     set_build_options(target_options.*, w); } build_release :: (w: Workspace, target_options: *Build_Options) {     log("Choosing release options...");     target_options.backend = .LLVM;     target_options.output_path = "bin/release";     set_optimization(target_options, Optimization_Type.VERY_OPTIMIZED);     set_build_options(target_options.*, w); } args_help_print :: () {     help_message := #string _END_ Usage:  jai build.jai - [OPTIONS] :: [PROGRAM ARGS] Options:     help        Prints this help menu.     silent      Disables compiler/linker statistics.     run         Runs your program afterwards.     release     Builds with release options. If omitted, it builds a debug build.     memory      Enables the memory leak detector. Passing Args to your Program:     If you want to supply args to your program, pass it like that:         `jai build.jai - run :: my_arg1 foo bar abc ABC`     Everything after the `::` get's forwarded to your program. _END_;     log(help_message); } program_args_collect :: (args: []string, divider: string = "::") -> [..]string {     buf: [..]string;     success, match := array_find(args, divider);     if success  for i: match+1..args.count-1  array_add(*buf, args[i]);     return buf; } message_loop :: () -> success: bool {     while true {         message := compiler_wait_for_message();         if !message break;         if message.kind == {         case .COMPLETE;             message_complete := cast(*Message_Complete) message;             return message_complete.error_code == 0;         }     }     return false; } #placeholder MEMORY_DEBUGGER_ENABLED; main :: () {} #run build(); diff --git a/modules/raylib b/modules/raylib new file mode 120000 index 0000000..30ac3f9 --- /dev/null +++ b/modules/raylib @@ -0,0 +1 @@ /home/ptrace/dev/_LIBS/jai/raylib-jai/Raylib \ No newline at end of file diff --git a/src/main.jai b/src/main.jai new file mode 100644 index 0000000..6d88628 --- /dev/null +++ b/src/main.jai @@ -0,0 +1,220 @@ #import "Basic"()(     MEMORY_DEBUGGER = MEMORY_DEBUGGER_ENABLED ); #import "Math"; #import "Print_Vars"; #import "raylib"; /*         (0)         / \       (1) (2)       /     \  (3, 4)     (5, 6) l = 2 * i + 1 r = 2 * i + 2 parent = floor((i - 1) / 2) [     0, 1, 2,  ] */ rects := Rectangle.[     { -200.0, -160.0, 40.0, 45.0 },     { -140.0, -100.0, 25.0, 25.0 },     { -7.0, 60.0, 70.0, 50.0 },     { 55.0, 75.0, 25.0, 25.0 },     { -180.0, 40.0, 45.0, 25.0 },     { 120.0, 20.0, 9.0, 16.0 },     { 10.0, 35.0, 25.0, 15.0 },     { -80.0, 100.0, 21.0, 32.0 },     { 30.0, -70.0, 9.0, 16.0 }, ]; color_choice := Color.[     ORANGE,     YELLOW,     GREEN,     BLUE, ]; NODE_INTERNAL :: -6; NODE_ROOT     :: -9; NODE_EMPTY    :: -1; DRAW_BV :: true; Aabb :: struct {     upper_bound: Vector2;     lower_bound: Vector2; } Tree :: struct {     data: [..]int; } Node :: struct {     parent: int = NODE_EMPTY;     left: int   = NODE_EMPTY;     right: int  = NODE_EMPTY; } #if false main :: () {     #if MEMORY_DEBUGGER_ENABLED defer report_memory_leaks();     log("Hello, Sailor!");     camera: Camera2D;     camera.offset = { 400.0, 300.0 };     camera.zoom = 1.0;     SetTraceLogLevel(.LOG_NONE);     SetConfigFlags(.FLAG_MSAA_4X_HINT);     InitWindow(800, 600, "Template");     defer CloseWindow();     SetTargetFPS(60);     push_allocator(temp);     while !WindowShouldClose() {         BeginDrawing();         defer EndDrawing();         ClearBackground({ 42, 42, 60, 255 });         {             BeginMode2D(camera);             defer EndMode2D();             // box1 := make_aabb(rects[0]);             // box2 := make_aabb(rects[1]);             // u := aabb_bv_union(box1, box2);             // Make AABBs             aabbs: [..]Aabb;             for rects array_add(*aabbs, make_aabb(it));             for rects DrawRectangleLinesEx(                 it,                 1.0,                 color_choice[it_index % color_choice.count]             );             // sleep_milliseconds(500);         }         DrawFPS(10, 10);         DrawText(TextFormat("Frame Time: %f s", GetFrameTime()), 10, 30, 20, WHITE);         reset_temporary_storage();     } } else main :: () {     log("Offline");     tree: Tree;     array_add(*tree.data, 100);     array_add(*tree.data, 110);     array_add(*tree.data, 120);     array_add(*tree.data, 111);     array_add(*tree.data, 112);     array_add(*tree.data, 121);     array_add(*tree.data, 122);     log_vars(tree.data);     t := tree_access_node(tree, 0);     log_vars(t);     tree_split_node(*tree, 2, 400, 401);     log_vars(tree.data);     t = tree_access_node(tree, 2);     log_vars(t); } /** Continue:     - Refit     - Rotate     - Collapse */ tree_split_node :: (tree: *Tree, index: int, left: int, right: int) {     i_left  := 2 * index + 1;     i_right := 2 * index + 2;     while tree.data.count <= i_right {         array_add(*tree.data, NODE_EMPTY);     }     tree.data[i_left]  = left;     tree.data[i_right] = right;     tree.data[index]   = NODE_INTERNAL;     // tree.data[index] becomes an internal node — refit its bounding volume } tree_access_node :: (tree: Tree, index: int) -> Node {     node: Node;     i_left   := 2 * index + 1;     i_right  := 2 * index + 2;     i_parent := cast(int)floor((index - 1.0) / 2.0);     for int.[i_left, i_right] {         if it > tree.data.count return node;     }     node.left   = tree.data[i_left];     node.right  = tree.data[i_right];     node.parent = ifx i_parent < 0 then NODE_ROOT else tree.data[i_parent];     return node; } make_aabb :: (rect: Rectangle) -> Aabb {     a: Aabb;     a.upper_bound = { rect.x, rect.y };     a.lower_bound = { rect.x + rect.width , rect.y + rect.height };     return a; } aabb_draw :: (a: Aabb) {     #if !DRAW_BV return;     rect := Rectangle.{         a.upper_bound.x,         a.upper_bound.y,         a.lower_bound.x - a.upper_bound.x,         a.lower_bound.y - a.upper_bound.y     };     DrawRectangleLinesEx(rect, 1.0, RED); } aabb_bv_compute_surface_area :: (a: Aabb) -> float {     d := a.upper_bound - a.lower_bound;     return 2.0 * (d.x * d.y); } aabb_bv_union :: (a: Aabb, b: Aabb) -> Aabb {     c: Aabb;     c.upper_bound = min(a.upper_bound, b.upper_bound);     c.lower_bound = max(a.lower_bound, b.lower_bound);     return c; }