-onyx build -I ../src -o game.wasm && onyxrun game.wasm
+onyx build -I ../src -o game.wasm $@ && onyxrun game.wasm
#load "world"
#load "font"
#load "shader"
+#load "input"
+#load "physics"
// Onyx library code
#load "stb_truetype"
use package core
+@GlobalVariable
+camera: Camera;
+
Camera :: struct {
fov: f32; // Radians
window_width, window_height: f32;
chunk_highlight_block :: (x, y, z: f32) {
data := 0xf000;
- vertex_data := cast(^Chunk_Vertex) alloca(sizeof Chunk_Vertex * 8);
+ vertex_data := cast(^Chunk_Vertex) alloc.from_stack(sizeof Chunk_Vertex * 8);
vertex_data[0] = .{.{x-0.001,y-0.001,z-0.001},data};
vertex_data[1] = .{.{x-0.001,y+1.001,z-0.001},data};
vertex_data[2] = .{.{x+1.001,y+1.001,z-0.001},data};
return font;
}
-alloca :: macro (size: u32) -> rawptr {
- defer __stack_top = ~~(cast(^u8) __stack_top + size);
- return __stack_top;
-}
-
font_print :: (font: Font, x, y: f32, format: str, va: ..any) {
buf: [1024] u8;
msg := conv.str_format_va(buf, format, va);
}
font_draw :: (font: Font, x, y: f32, msg: str) {
- quads: ^stbtt_aligned_quad = alloca(msg.count * sizeof stbtt_aligned_quad);
+ quads: ^stbtt_aligned_quad = alloc.from_stack(msg.count * sizeof stbtt_aligned_quad);
quad_num := 0;
x_, y_ := x, y;
--- /dev/null
+use package core
+use package glfw3
+
+#local {
+ keys_last_frame: [..] u32
+ last_buttons: [3] bool
+}
+
+handle_key_event :: (key, scancode, action, mod: u32) {
+ switch action {
+ case GLFW_PRESS, GLFW_REPEAT {
+
+ }
+
+ case GLFW_RELEASE {
+
+ }
+ }
+}
+
+is_key_down :: (key: u32) {
+
+}
+
+is_key_just_down :: (key: u32) {
+
+}
+
+is_key_just_up :: (key: u32) {
+
+}
+
+handle_button_event :: (button, action, mod: u32) {
+
+}
+
+is_button_down :: (button: u32) {
+
+}
+
+is_button_just_down :: (button: u32) {
+
+}
use package core.intrinsics.onyx { __initialize }
#local runtime :: package runtime
-window: GLFWwindow_p;
-camera: Camera;
+#local {
+ world: ^World;
+ world_shader: Shader;
+ font: Font;
+ selected_block: Vector3i;
+
+ window: GLFWwindow_p;
+}
create_window :: () => {
#if runtime.OS == runtime.OS_Linux {
glfwSwapInterval(1);
glfwSetWindowSizeCallback(window, "on_resize");
glfwSetKeyCallback(window, "on_key");
+ glfwSetMouseButtonCallback(window, "on_mouse_button");
}
#export "on_resize" (window: GLFWwindow_p, width, height: u32) {
}
}
+#export "on_mouse_button" (window: GLFWwindow_p, button, action, mod: u32) {
+
+}
+
cursor_grabbed := false;
toggle_cursor_grabbed :: () {
cursor_grabbed = !cursor_grabbed;
}
}
-world: ^World;
-world_shader: Shader;
-font: Font;
-selected_block: Vector3i;
-
setup_opengl :: () {
glInit(glfwGetLoadProcAddress());
}
dir: Vector3i;
- if !world_ray_cast(.{ camera.position, forward }, 40, null, (_, p) => {
+ if !ray_cast(.{ camera.position, forward }, 40, null, (_, p) => {
return world_get_block(world, p.x, p.y, p.z) != Block_Empty;
}, ^selected_block, ^dir) {
selected_block = .{0,0,0};
}
if glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS {
- world_set_block(world, selected_block.x, selected_block.y, selected_block.z, Block_Empty);
+ world_set_block(world, selected_block.x, selected_block.y, selected_block.z, block_make(0,0,0,1));
}
update_world_matrix();
}
-debug_screen := true;
-game_fps: i32;
+#local {
+ debug_screen := true;
+ game_fps: i32;
+}
draw :: () {
- glClearColor(.7, .7, .9, 1);
+ // glClearColor(.7, .7, .9, 1);
+ glClearColor(0.1, 0.1, 0.1, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shader_use(world_shader);
- glLineWidth(2);
world_draw(world);
+
+ glLineWidth(2);
chunk_highlight_block(~~selected_block.x, ~~selected_block.y, ~~selected_block.z);
+ #if false {
+ aabb_buffer := (cast(^AABB) alloc.from_stack(sizeof [128] AABB))[0 .. 128];
+ aabbs := world_get_aabbs(world, camera.position, 5, aabb_buffer);
+ for^ aabbs do chunk_highlight_block(it.x0, it.y0, it.z0);
+ }
+
if debug_screen {
ww, wh: i32;
glfwGetWindowSize(window, ^ww, ^wh);
frame_count = 0;
}
- update(~~dt);
+ update(cast(f32) dt);
draw();
}
}
--- /dev/null
+use package core
+
+PhysicsBody :: struct {
+ pos: Vector3;
+ vel: Vector3;
+ acc: Vector3;
+}
+
+
+physics_body_move :: (use body: ^PhysicsBody, world: ^World) {
+ aabb_buffer := cast([16] AABB) alloc.from_stack(sizeof [16] AABB);
+
+ aabbs := world_get_aabbs(world, pos, Vector3.mag(vel));
+ for aabb: aabbs {
+
+ }
+}
+
+
chunk_set(chunk, x % Chunk_Size, y % Chunk_Size, z % Chunk_Size, block);
}
+@Relocate // to a utils file
+AABB :: struct {
+ x0, y0, z0, x1, y1, z1: f32;
+
+ intersects :: (a1, a2: AABB) -> bool {
+ return a1.x0 < a2.x1 && a1.x1 > a2.x0
+ && a1.y0 < a2.y1 && a1.y1 > a2.y0
+ && a1.z0 < a2.z1 && a1.z1 > a2.z0;
+ }
+
+ contains :: (a: AABB, v: Vector3) -> bool {
+ return a.x0 < v.x && v.x < a.x1
+ && a.y0 < v.y && v.y < a.y1
+ && a.z0 < v.z && v.z < a.z1;
+ }
+}
+
+world_get_aabbs :: (use world: ^World, center: Vector3, radius: f32, buffer: [] AABB = .[]) -> [] AABB {
+ is_dynamic := buffer.count == 0;
+ aabbs: [..] AABB;
+ buffer_pos := 0;
+
+ pos := Vector3i.{ ~~math.floor(center.x), ~~math.floor(center.y), ~~math.floor(center.z) };
+ rad := cast(i32) math.ceil(radius);
+
+ for x: pos.x-rad .. pos.x+rad+1 {
+ for y: pos.y-rad .. pos.y+rad+1 {
+ for z: pos.z-rad .. pos.z+rad+1 {
+ if world_get_block(world, x, y, z) != Block_Empty {
+ aabb := AABB.{
+ ~~x, ~~y, ~~z,
+ ~~(x+1), ~~(y+1), ~~(z+1)
+ };
+
+ if is_dynamic {
+ aabbs << aabb;
+ } else {
+ buffer[buffer_pos] = aabb;
+ buffer_pos += 1;
+ if buffer_pos >= buffer.count do break break break;
+ }
+ }
+ }
+ }
+ }
+
+ if is_dynamic do return aabbs;
+ return buffer[0 .. buffer_pos];
+}
+
+
+@Relocate // to a utils file
Ray :: struct {
origin, direction: Vector3;
}
-world_ray_cast :: (ray: Ray, max_distance: f32, ctx: $T, is_solid: (T, Vector3i) -> bool, out_block: ^Vector3i, out_dir: ^Vector3i) -> bool {
+@Relocate // to a utils file
+ray_cast :: (ray: Ray, max_distance: f32, ctx: $T, is_solid: (T, Vector3i) -> bool, out_block: ^Vector3i, out_dir: ^Vector3i) -> bool {
pos := Vector3i.{ ~~math.floor(ray.origin.x), ~~math.floor(ray.origin.y), ~~math.floor(ray.origin.z) };
dir := ray.direction;
pos.x += step.x;
tmax.x += tdelta.x;
- *out_dir = Vector3i.{ -step.x, 0, 0 };
+ *out_dir = .{ -step.x, 0, 0 };
} else {
if tmax.z > radius {
pos.z += step.z;
tmax.z += tdelta.z;
- *out_dir = Vector3i.{ 0, 0, -step.z };
+ *out_dir = .{ 0, 0, -step.z };
}
} else {
pos.y += step.y;
tmax.y += tdelta.y;
- *out_dir = Vector3i.{ 0, -step.y, 0 };
+ *out_dir = .{ 0, -step.y, 0 };
} else {
if tmax.z > radius {
pos.z += step.z;
tmax.z += tdelta.z;
- *out_dir = Vector3i.{ 0, 0, -step.z };
+ *out_dir = .{ 0, 0, -step.z };
}
}
}