11 #include <GLFW/glfw3.h>
13 #include "mapblock_meshgen.h"
20 void client_disconnect(bool send, const char *detail)
22 pthread_mutex_lock(&client.mtx);
23 if (client.state != CS_DISCONNECTED) {
25 write_u32(client.fd, SC_DISCONNECT);
27 client.state = CS_DISCONNECTED;
28 printf("Disconnected %s%s%s\n", INBRACES(detail));
31 pthread_mutex_unlock(&client.mtx);
36 static void *reciever_thread(void *unused)
40 handle_packets(&client);
43 client_disconnect(false, "network error");
48 static void client_loop()
51 printf("Failed to initialize GLFW\n");
55 glfwWindowHint(GLFW_SAMPLES, 8);
56 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
57 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
58 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
64 GLFWwindow *window = glfwCreateWindow(width, height, "Dragonblocks", NULL, NULL);
67 fprintf(stderr, "Failed to create window\n");
72 glfwMakeContextCurrent(window);
73 if (glewInit() != GLEW_OK) {
74 fprintf(stderr, "Failed to initialize GLEW\n");
78 glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
80 const char *shader_path;
83 shader_path = "shaders";
85 shader_path = "../shaders";
88 ShaderProgram *prog = create_shader_program(shader_path);
90 fprintf(stderr, "Failed to create shader program\n");
94 v3f pos = {0.0f, 0.0f, 0.0f};
96 mat4x4 view, projection;
98 mat4x4_translate(view, -pos.x, -pos.y, -pos.z);
99 mat4x4_perspective(projection, 86.1f / 180.0f * M_PI, (float) width / (float) height, 0.01f, 1000.0f);
101 glUseProgram(prog->id);
102 glUniformMatrix4fv(prog->loc_view, 1, GL_FALSE, view[0]);
103 glUniformMatrix4fv(prog->loc_projection, 1, GL_FALSE, projection[0]);
105 while (! glfwWindowShouldClose(window) && client.state != CS_DISCONNECTED && ! interrupted) {
106 glEnable(GL_DEPTH_TEST);
107 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
108 glClearColor(0.52941176470588f, 0.8078431372549f, 0.92156862745098f, 1.0f);
110 bool view_changed = false;
112 if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
115 } else if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
118 } if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
121 } else if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
124 } if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) {
127 } else if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) {
133 mat4x4_translate(view, -pos.x, -pos.y, -pos.z);
134 glUniformMatrix4fv(prog->loc_view, 1, GL_FALSE, view[0]);
137 scene_render(client.scene, prog);
139 glfwSwapBuffers(window);
143 delete_shader_program(prog);
146 static bool client_name_prompt()
148 printf("Enter name: ");
151 if (scanf("%s", name) == EOF)
153 client.name = strdup(name);
154 pthread_mutex_lock(&client.mtx);
155 if (write_u32(client.fd, SC_AUTH) && write(client.fd, client.name, strlen(client.name) + 1)) {
156 client.state = CS_AUTH;
157 printf("Authenticating...\n");
159 pthread_mutex_unlock(&client.mtx);
163 static bool client_authenticate()
166 switch (client.state) {
168 if (client_name_prompt())
180 case CS_DISCONNECTED:
187 static void client_start(int fd)
190 pthread_mutex_init(&client.mtx, NULL);
191 client.state = CS_CREATED;
193 client.map = map_create();
194 client.scene = scene_create();
196 mapblock_meshgen_init(client.map, client.scene);
198 pthread_t recv_thread;
199 pthread_create(&recv_thread, NULL, &reciever_thread, NULL);
201 if (client_authenticate())
204 if (client.state != CS_DISCONNECTED)
205 client_disconnect(true, NULL);
210 mapblock_meshgen_stop();
212 map_delete(client.map);
213 scene_delete(client.scene);
215 pthread_mutex_destroy(&client.mtx);
218 int main(int argc, char **argv)
220 program_name = argv[0];
223 internal_error("missing address or port");
225 struct addrinfo hints = {
226 .ai_family = AF_UNSPEC,
227 .ai_socktype = SOCK_STREAM,
229 .ai_flags = AI_NUMERICSERV,
232 struct addrinfo *info = NULL;
234 int gai_state = getaddrinfo(argv[1], argv[2], &hints, &info);
237 internal_error(gai_strerror(gai_state));
239 int fd = socket(info->ai_family, info->ai_socktype, info->ai_protocol);
242 syscall_error("socket");
244 if (connect(fd, info->ai_addr, info->ai_addrlen) == -1)
245 syscall_error("connect");
247 char *addrstr = address_string((struct sockaddr_in6 *) info->ai_addr);
248 printf("Connected to %s\n", addrstr);
253 init_signal_handlers();