--- /dev/null
+[submodule "lib/onyx-net"]
+ path = lib/onyx-net
+ url = https://github.com/onyx-lang/onyx-net.git
--- /dev/null
+Subproject commit 79c85f4bf532700f45227504fcd982c31ceb4ac4
#load "perlin/module"
#load "stb_image/module"
#load "stb_truetype/module"
-#load "onyx_net/src/module"
+#load "onyx-net/src/module"
--- /dev/null
+
+use package core
+use package glfw3
+use package opengles
+
+#local {
+ ip_addr: [..] u8;
+ port: [..] u8;
+ name: [..] u8;
+}
+
+Connect_Menu :: struct {
+ init :: (_: rawptr) {
+ array.clear(^port);
+ port_buffer: [8] u8;
+ string.concat(^port, conv.format(port_buffer, "{}", (package runtime.vars).Game_Port));
+ }
+
+ leave :: (_: rawptr) {
+ array.free(^ip_addr);
+ array.free(^port);
+ array.free(^name);
+ }
+
+ join :: (_: rawptr) {
+ net_connect(ip_addr, ~~ conv.str_to_i64(port));
+
+ pop_game_state();
+ push_game_state(Game_State, null);
+ }
+
+ draw :: (_: rawptr) {
+ if is_key_just_down(GLFW_KEY_ESCAPE) {
+ glfwSetWindowShouldClose(window, true);
+ }
+
+ glDisable(GL_DEPTH_TEST);
+ glClearColor(0.1, 0.1, 0.1, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ draw_textbox(.{0, 0, 200, 40}, ^ip_addr, "IP Address");
+ draw_textbox(.{0, 40, 200, 40}, ^port, "Port");
+ draw_textbox(.{0, 80, 200, 40}, ^name, "Name");
+
+ if draw_button(.{0, 120, 200, 40}, "Join") {
+ join(_);
+ }
+ }
+}
\ No newline at end of file
use package glfw3
use package opengles
use package stb_truetype
-use package core.intrinsics.onyx { __initialize }
-#local onet :: package onyx_net
#local {
world_shader: Shader;
world: ^World;
selected_block: Vector3i;
+Game_State :: struct {
+ init :: game_init;
+ update :: game_update;
+ draw :: game_draw;
+}
-@Temporary host: ^onet.Host;
-@Temporary peer: ^onet.Peer;
-
-
-game_init :: () {
+game_init :: (_: rawptr) {
world_shader = shader_make("assets/shaders/world.glsl");
shader_link_world_matrix_block(world_shader);
world = world_make();
player = player_make();
player.camera = ^camera;
-
- __initialize(^camera);
- camera_set_fov(^camera, 75);
- ww, wh: i32;
- glfwGetWindowSize(window, ^ww, ^wh);
- camera_set_window_size(^camera, ~~ww, ~~wh);
-
- addr: net.Socket_Address;
- addr.addr = net.str_to_ipv4("127.0.0.1");
- addr.port = (package runtime.vars).Game_Port;
- host', _ := onet.host_create(null, 1);
- peer = onet.host_connect(host, ^addr, 2);
}
-game_update :: (dt: f32) {
- for host->get_events(timeout=0) {
- if it.type == .Connection {
- chat_messages << "[Connected to server]";
- }
-
- if it.type == .Message {
- chat_messages << string.alloc_copy(it.data);
- }
- }
+game_update :: (_: rawptr, dt: f32) {
+ net_pulse();
if is_key_just_down(GLFW_KEY_ESCAPE) {
if cursor_grabbed {
update_world_matrix();
}
-game_draw :: () {
+game_draw :: (_: rawptr) {
draw_scene();
ww, wh: i32;
chunk_highlight_block(~~selected_block.x, ~~selected_block.y, ~~selected_block.z);
}
-
chat_messages: [..] [] u8;
-pending_message: [..] u8;
draw_chat :: () {
glDisable(GL_DEPTH_TEST);
font_draw(chat_font, 10, y, chat_messages[i]);
}
+ #persist pending_message: [..] u8;
if draw_textbox(.{0, ~~(wh - 32), 400, 32}, ^pending_message) == .Enter_Pressed {
if pending_message.count > 0 {
- send_message(string.alloc_copy(pending_message));
+ net_send_message(string.alloc_copy(pending_message));
array.clear(^pending_message);
}
}
-
- send_message :: (message: [] u8) {
- packet := new(onet.Packet);
- packet.flags |= .Reliable;
- packet.data = message;
- onet.peer_send(peer, 0, packet);
- }
}
cursor_grabbed := false;
use package core
use package glfw3
use package opengles
+use package core.intrinsics.onyx { __initialize }
#local runtime :: package runtime
+State :: struct {
+ data: rawptr;
+
+ init: (rawptr) -> void;
+ deinit: (rawptr) -> void;
+ enter: (rawptr, ^State) -> void;
+ leave: (rawptr) -> void;
+ update: (rawptr, dt: f32) -> void;
+ draw: (rawptr) -> void;
+}
+
+#local state_stack: [..] State;
+
+push_game_state :: (state: type_expr, data: rawptr) -> ^State {
+ s := array.alloc_one(^state_stack);
+ type_info.populate_struct_vtable(s, state, safe=false);
+ s.data = data;
+
+ parent := array.get_ptr(state_stack, -2) if state_stack.count > 1 else null;
+ if parent != null {
+ if parent.deinit != null_proc do parent.deinit(parent.data);
+ }
+
+ if s.init != null_proc do s.init(s.data);
+ if s.enter != null_proc do s.enter(s.data, parent);
+
+ return s;
+}
+
+pop_game_state :: () -> ^State {
+ if state_stack.count > 0 {
+ s := array.pop(^state_stack);
+ if s.leave != null_proc do s.leave(s.data);
+ if s.deinit != null_proc do s.deinit(s.data);
+ return array.get_ptr(state_stack, -1);
+ }
+
+ return null;
+}
+
init :: () {
window = create_window();
glInit(glfwGetLoadProcAddress());
shaders_init();
fonts_init();
immediate_init();
+
+ __initialize(^camera);
+ camera_set_fov(^camera, 75);
+ ww, wh: i32;
+ glfwGetWindowSize(window, ^ww, ^wh);
+ camera_set_window_size(^camera, ~~ww, ~~wh);
- game_init();
+ array.init(^state_stack, 16);
+ push_game_state(Connect_Menu, null);
update_view_matrix();
update_world_matrix();
update :: (dt: f32) {
input_update();
- game_update(dt);
+ state := ^state_stack[state_stack.count - 1];
+ if state.update != null_proc {
+ state.update(state.data, dt);
+ }
}
draw :: () {
- game_draw();
+ state := ^state_stack[state_stack.count - 1];
+ if state.draw != null_proc {
+ state.draw(state.data);
+ }
if debug_screen {
immediate_set_color(.{1, 0, 1, 0.5});
}
immediate_flush();
- glfwSwapBuffers(window);
input_post_update();
ui_end_frame();
+ glfwSwapBuffers(window);
}
main_loop :: () {
--- /dev/null
+
+
+net_connect :: (ip_addr: [] u8, port: u16) {
+ addr: net.Socket_Address;
+ addr.addr = net.str_to_ipv4(ip_addr);
+ addr.port = port;
+ host', _ := onet.host_create(null, 1);
+ peer = onet.host_connect(host, ^addr, 2);
+}
+
+net_pulse :: () {
+ for host->get_events(timeout=0) {
+ if it.type == .Connection {
+ chat_messages << "[Connected to server]";
+ }
+
+ if it.type == .Message {
+ chat_messages << string.alloc_copy(it.data);
+ }
+ }
+}
+
+@Temporary
+net_send_message :: (message: str) {
+ packet := new(onet.Packet);
+ packet.flags |= .Reliable;
+ packet.data = message;
+ onet.peer_send(peer, 0, packet);
+}
+
+
+#local {
+ use package core
+ onet :: package onyx_net
+
+ host: ^onet.Host;
+ peer: ^onet.Peer;
+}
+
+
#load "./../src/config"
#load "server"
-#load "onyx_net/src/module"
+#load "onyx-net/src/module"
Type :: enum (u8) {
Connect;
Verify_Connect;
+ Connection_Rejected;
Disconnect;
Player_Joined;
Connect :: struct #pack {
use base: Packet_Base;
+ name: str;
+ client_version: u32;
}
+Verify_Connect :: struct #pack {
+ use base: Packet_Base;
+ player_id: u16;
+}
+Connection_Rejected :: struct #pack {
+ use base: Packet_Base;
+ Reason :: enum {
+ Server_Full :: 1;
+ Outdated_Client :: 2;
+ }
+ reason: Reason;
+}