-Subproject commit 27c896ce946092882f9665b1ec39f6a3d74c5094
+Subproject commit d851e9c7762bba2c40e9ea0e4fdeb4e935009406
tx := (ww - 200) / 2;
ty := (wh - 160) / 2;
- textbox_list_start();
- draw_textbox(.{tx, ty+0, 200, 40}, ^ip_addr, "IP Address");
- draw_textbox(.{tx, ty+40, 200, 40}, ^port, "Port");
- draw_textbox(.{tx, ty+80, 200, 40}, ^name, "Name");
- textbox_list_end();
+ ui.textbox_list_start();
+ ui.draw_textbox(.{tx, ty+0, 200, 40}, ^ip_addr, "IP Address");
+ ui.draw_textbox(.{tx, ty+40, 200, 40}, ^port, "Port");
+ ui.draw_textbox(.{tx, ty+80, 200, 40}, ^name, "Name");
+ ui.textbox_list_end();
- if draw_button(.{tx, ty+120, 200, 40}, "Join") {
+ if ui.draw_button(.{tx, ty+120, 200, 40}, "Join") {
join(_);
}
}
}
leave :: (_: rawptr) {
- array.free(^ip_addr);
- array.free(^port);
- array.free(^name);
+ delete(^ip_addr);
+ delete(^port);
+ delete(^name);
}
update :: (_: rawptr, dt: f32) {
Game_State :: struct {
init :: game_init;
+ deinit :: game_deinit;
update :: game_update;
draw :: game_draw;
}
Meshes.init();
}
+game_deinit :: (_: rawptr) {
+ net_send_disconnect();
+ net_disconnect();
+}
+
game_update :: (_: rawptr, dt: f32) {
net_pulse();
// A very hacky wait to have the click the capture mouse.
immediate_push_scissor(0, 0, 0, 0);
if !cursor_grabbed {
- if draw_button(.{ 0, 0, ~~ww, ~~wh }, "") {
+ if ui.draw_button(.{ 0, 0, ~~ww, ~~wh }, "") {
toggle_cursor_grabbed();
}
}
shader_use(player_shader);
shader_set_uniform(player_shader, #cstr "color", Color.{1,0,0});
for^ other_players.entries {
- update_model_matrix(it.value.position - .{0,0.8,0}, .{0.5, 1, 0.5});
+ update_model_matrix(it.value.position - .{0,0.8,0}, .{0.3, 1, 0.3});
mesh_draw(Meshes.white_box);
}
}
}
#persist pending_message: [..] u8;
- if draw_textbox(.{0, ~~(wh - 32), 400, 32}, ^pending_message) == .Enter_Pressed {
+ if ui.draw_textbox(.{0, ~~(wh - 32), 400, 32}, ^pending_message) == .Enter_Pressed {
if pending_message.count > 0 {
net_send_chat_message(string.alloc_copy(pending_message));
array.clear(^pending_message);
use package glfw3
immediate_init :: () {
- memory.alloc_slice(^vertex_data, Maximum_Vertex_Count);
+ vertex_data = make([] Immediate_Vertex, Maximum_Vertex_Count);
vertex_count = 0;
imgui_shader = shader_make(Shader_Path);
//
// Very simple immediate mode UI
//
+package ui
use package core
use package opengles
use package glfw3
+use package main
UI_Id :: u32
-ui_end_frame :: () {
+end_frame :: () {
hot_item_depth_needed = hot_item_depth;
if !hot_item_was_set do set_hot_item(0);
hot_item_depth = 0;
animation_state := get_animation(hash);
mx, my := mouse_get_position();
- contains := Rect.contains(r, .{~~mx, ~~my});
+ contains := r->contains(.{~~mx, ~~my});
if is_active_item(hash) {
renew_active_item(hash);
}
}
- if Rect.contains(r, .{ ~~mx, ~~my }) {
+ if r->contains(.{ ~~mx, ~~my }) {
set_hot_item(hash);
}
text_x := x + border_width;
text_y := y + font.em + (h - text_height) / 2;
- contains := Rect.contains(r, .{~~mx, ~~my});
+ contains := r->contains(.{~~mx, ~~my});
if is_hot_item(hash) && !is_active_item(hash) {
if is_button_down(GLFW_MOUSE_BUTTON_LEFT) && contains {
animation_state := get_animation(hash);
mx, my := mouse_get_position();
- contains := Rect.contains(r, .{~~mx, ~~my});
+ contains := r->contains(.{~~mx, ~~my});
if is_active_item(hash) {
renew_active_item(hash);
animation_state := get_animation(hash);
mx, my := mouse_get_position();
- contains := Rect.contains(r, .{~~mx, ~~my});
+ contains := r->contains(.{~~mx, ~~my});
if is_active_item(hash) {
renew_active_item(hash);
state = ^scroll_states[hash];
}
- contains := Rect.contains(r, .{~~mx, ~~my});
+ contains := r->contains(.{~~mx, ~~my});
if contains {
scroll_delta := mouse_get_scroll_vector();
state.xscroll -= scroll_delta.x * 20;
use package core.intrinsics.onyx { __initialize }
#local runtime :: package runtime
+#package {
+ ui :: package ui
+}
+
State :: struct {
data: rawptr;
update_window_matrix();
}
+deinit :: () {
+ while state_stack.count > 0 {
+ pop_game_state();
+ }
+}
+
create_window :: () => {
#if runtime.compiler_os == .Linux {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
immediate_flush();
input_post_update();
- ui_end_frame();
+ ui.end_frame();
glfwSwapBuffers(window);
}
init();
main_loop();
+ deinit();
}
player.velocity = moved.velocity;
player.facing = moved.facing;
}
+
+ case .Block_Updates {
+ block_updates := cast(^packets.Block_Updates) packet;
+
+ update_count := block_updates.update_count;
+ updates := ([] packets.Block_Updates.Update).{ ~~^block_updates.updates, ~~update_count };
+ for updates {
+ pos := it.position;
+ world_set_block(world, pos.x, pos.y, pos.z, it.new_block);
+ }
+ }
}
}
net_send_disconnect :: () {
disconnect := new(packets.Disconnect);
disconnect.player_id = player_id;
+
+ p := new(onet.Packet);
+ p.data = .{ ~~disconnect, sizeof typeof *disconnect };
+ p.free_data = true;
+ onet.peer_send(peer, 0, p);
}
net_send_chat_message :: (message: str) {
onet.peer_send(peer, 0, p);
}
+net_send_block_updates :: (updates: [] packets.Block_Updates.Update) {
+ size := sizeof packets.Block_Updates + updates.count * sizeof packets.Block_Updates.Update;
+ block_updates := cast(^packets.Block_Updates) calloc(size);
+ block_updates.type = .Block_Updates;
+ block_updates.update_count = ~~updates.count;
+
+ block_update := cast(^packets.Block_Updates.Update) ^block_updates.updates;
+ for updates.count {
+ block_update[it].position = updates[it].position;
+ block_update[it].new_block = updates[it].new_block;
+ }
+
+ p := new(onet.Packet);
+ p.data = .{ ~~block_updates, size };
+ p.free_data = true;
+ onet.peer_send(peer, 0, p);
+}
Remote_Player :: struct {
name: str;
use package core
use package opengles
-Block :: #distinct u32;
-#operator == macro (b1, b2: Block) => cast(u32) b1 == cast(u32) b2;
-#operator != macro (b1, b2: Block) => cast(u32) b1 != cast(u32) b2;
-
-Block_Empty :: cast(Block) 0;
-
-Block_Options :: struct {
- texture_enabled := true;
-}
-
-block_make :: (red, green, blue: f32, brightness: f32, options := Block_Options.{}) -> Block {
- r := cast(u32) (red * 15.0f);
- g := cast(u32) (green * 15.0f);
- b := cast(u32) (blue * 15.0f);
- i := cast(u32) (brightness * 15.0f);
-
- tex := 1 if options.texture_enabled else 0;
-
- return ~~((tex << 16) | (i << 12) | (b << 8) | (g << 4) | r);
-}
-
Chunk_Vertex :: struct {
position : Vector3;
texture : Vector2;
~~(y * Chunk_Size),
~~(z * Chunk_Size),
};
- memory.alloc_slice(^chunk.blocks, Chunk_Size * Chunk_Size * Chunk_Size);
- memory.fill_slice(chunk.blocks, Block_Empty);
+
+ chunk.blocks = make([] Block, Chunk_Size*Chunk_Size*Chunk_Size);
+ array.fill(chunk.blocks, Block_Empty);
return chunk;
}
chunk_free :: (chunk: ^Chunk) {
chunk_destroy_mesh(chunk);
- memory.free_slice(^chunk.blocks);
- cfree(chunk);
+ delete(^chunk.blocks);
+ delete(chunk);
}
#local in_chunk_bounds :: macro (x, y, z: i32) -> bool {
mesh = null;
}
- verticies := array.make(Chunk_Vertex, capacity=512);
- defer array.free(^verticies);
+ verticies := make([..] Chunk_Vertex, 512);
+ defer delete(^verticies);
chunk_foreach(chunk) {
if block == Block_Empty do continue;
body_aabb := get_collision_object(new_pos);
for^ aabbs {
- if AABB.intersects(body_aabb, *it) {
+ if body_aabb->intersects(*it) {
if delta.y < 0 do on_ground = true;
return 0;
}
forward := camera_get_forward(camera);
facing := forward;
facing.y = 0;
- facing = Vector3.norm(facing);
+ facing = facing->norm();
xz_vel := Vector3.{0,0,0};
if is_key_down(GLFW_KEY_W) do xz_vel += facing;
xz_vel := direction_to_move;
- if Vector3.mag(xz_vel) > 0 do xz_vel = Vector3.norm(xz_vel) * speed;
+ if xz_vel->mag() > 0 do xz_vel = xz_vel->norm() * speed;
body.vel.x = xz_vel.x;
body.vel.z = xz_vel.z;
}
if is_button_just_down(GLFW_MOUSE_BUTTON_LEFT) {
- world_set_block(world, selected_block.x, selected_block.y, selected_block.z, Block_Empty);
+ net_send_block_updates(.[.{selected_block, Block_Empty}]);
}
if is_button_just_down(GLFW_MOUSE_BUTTON_RIGHT) {
target := selected_block + dir;
- world_set_block(world, target.x, target.y, target.z, block_make(1,0,0,1));
+ net_send_block_updates(.[.{target, block_make(1,0,0,1)}]);
}
}
world.center_chunk = .{0,0,0};
sl := world.chunk_dist * 2 + 1;
- memory.alloc_slice(^world.chunks, sl * sl * sl);
- memory.fill_slice(world.chunks, null);
+ world.chunks = make([] ^Chunk, sl * sl * sl);
+ array.fill(world.chunks, null);
return world;
}
if center_chunk == new_center do return;
sl := world.chunk_dist * 2 + 1;
- current_chunks := memory.copy_slice(world.chunks);
- memory.fill_slice(world.chunks, null);
+ current_chunks := array.copy(world.chunks);
+ array.fill(world.chunks, null);
center_chunk = new_center;
for current_chunks {
if world_get_chunk(world, x, y, z) == null do world.chunks_to_load << .{x, y, z};
}
- memory.free_slice(^current_chunks);
+ delete(^current_chunks);
}
world_get_aabbs :: (use world: ^World, center: Vector3, radius: f32, buffer: [] AABB = .[]) -> [] AABB {
package runtime.vars
ONYX_MODULE_DIR :: ""
+
+Game_Version :: 0x0001
+Game_Port :: cast(u16) 5123
+
+#load_path "./../lib"
#load "server"
#load "./../client/utils/vecmath"
-#load "./../shared/packets"
+#load_all "./../shared"
#load "onyx-net/src/module"
}
}
- case .Chat_Message {
+ case .Chat_Message, .Block_Updates {
+ @TODO // Validation of block updates
+
packet := new(onet.Packet);
packet.flags |= .Reliable;
packet.data = memory.copy_slice(packet_data);
player.position = moved.position;
player.velocity = moved.velocity;
- player.facing = moved.facing;
+ player.facing = moved.facing;
packet := new(onet.Packet);
packet.data = memory.copy_slice(packet_data);
package packets
-use package main { Vector3 }
+use package main { Vector3, Vector3i }
+use package main { Block }
Type :: enum (u8) {
Connect;
Player_Joined;
Player_Left;
Player_Moved;
+
+ Block_Updates;
}
Packet_Base :: struct #pack {
message_data: void;
}
+Block_Updates :: struct #pack {
+ use base := Packet_Base.{ .Block_Updates };
+ update_count: u16;
+ updates: void;
+
+ Update :: struct {
+ position: Vector3i;
+ new_block: Block;
+ }
+}
\ No newline at end of file
--- /dev/null
+
+Block :: #distinct u32;
+#operator == macro (b1, b2: Block) => cast(u32) b1 == cast(u32) b2;
+#operator != macro (b1, b2: Block) => cast(u32) b1 != cast(u32) b2;
+
+Block_Empty :: cast(Block) 0;
+
+Block_Options :: struct {
+ texture_enabled := true;
+}
+
+block_make :: (red, green, blue: f32, brightness: f32, options := Block_Options.{}) -> Block {
+ r := cast(u32) (red * 15.0f);
+ g := cast(u32) (green * 15.0f);
+ b := cast(u32) (blue * 15.0f);
+ i := cast(u32) (brightness * 15.0f);
+
+ tex := 1 if options.texture_enabled else 0;
+
+ return ~~((tex << 16) | (i << 12) | (b << 8) | (g << 4) | r);
+}
+