diff --git a/CMakeFiles/omicron.dir/src/cube.c.o b/CMakeFiles/omicron.dir/src/cube.c.o index bab0660..d1d35ef 100644 Binary files a/CMakeFiles/omicron.dir/src/cube.c.o and b/CMakeFiles/omicron.dir/src/cube.c.o differ diff --git a/CMakeFiles/omicron.dir/src/inventory.c.o b/CMakeFiles/omicron.dir/src/inventory.c.o index 0763b3b..a30b2f4 100644 Binary files a/CMakeFiles/omicron.dir/src/inventory.c.o and b/CMakeFiles/omicron.dir/src/inventory.c.o differ diff --git a/CMakeFiles/omicron.dir/src/item.c.o b/CMakeFiles/omicron.dir/src/item.c.o index d472056..43ba060 100644 Binary files a/CMakeFiles/omicron.dir/src/item.c.o and b/CMakeFiles/omicron.dir/src/item.c.o differ diff --git a/CMakeFiles/omicron.dir/src/main.c.o b/CMakeFiles/omicron.dir/src/main.c.o index c9d20a9..69e01e4 100644 Binary files a/CMakeFiles/omicron.dir/src/main.c.o and b/CMakeFiles/omicron.dir/src/main.c.o differ diff --git a/CMakeFiles/omicron.dir/src/parser.c.o b/CMakeFiles/omicron.dir/src/parser.c.o index f2b0f8b..97ca949 100644 Binary files a/CMakeFiles/omicron.dir/src/parser.c.o and b/CMakeFiles/omicron.dir/src/parser.c.o differ diff --git a/CMakeFiles/omicron.dir/src/worldgen/biome_temperate.c.o b/CMakeFiles/omicron.dir/src/worldgen/biome_temperate.c.o index 192d3fa..71f1011 100644 Binary files a/CMakeFiles/omicron.dir/src/worldgen/biome_temperate.c.o and b/CMakeFiles/omicron.dir/src/worldgen/biome_temperate.c.o differ diff --git a/CMakeFiles/omicron.dir/src/worldgen/world.c.o b/CMakeFiles/omicron.dir/src/worldgen/world.c.o index c08d6ae..192a346 100644 Binary files a/CMakeFiles/omicron.dir/src/worldgen/world.c.o and b/CMakeFiles/omicron.dir/src/worldgen/world.c.o differ diff --git a/config.txt b/config.txt new file mode 100644 index 0000000..8738844 --- /dev/null +++ b/config.txt @@ -0,0 +1,7 @@ +SHOW_LIGHTS 1 +SHOW_ITEM 1 +SHOW_CROSSHAIRS 1 +SHOW_INFO_TEXT 1 +SHOW_CHAT_TEXT 1 +SHOW_PLAYER_NAMES 1 +FONT_SIZE 16 diff --git a/omicron b/omicron index 3507df1..9777553 100644 Binary files a/omicron and b/omicron differ diff --git a/shaders/block_fragment.glsl b/shaders/block_fragment.glsl index 0f92a22..7f920c4 100644 --- a/shaders/block_fragment.glsl +++ b/shaders/block_fragment.glsl @@ -24,33 +24,34 @@ void main() { discard; } - float df = cloud ? 1.0 - diffuse * 0.2 : diffuse; - float ao = cloud ? 1.0 - (1.0 - fragment_ao) * 0.2 : fragment_ao; - ao = min(1.0, ao + fragment_light); - df = min(1.0, df + fragment_light); + float df = cloud ? 1.0 - diffuse * 0.2 : diffuse; + float ao = cloud ? 1.0 - (1.0 - fragment_ao) * 0.3 : fragment_ao; + ao = min(1.0, ao + fragment_light); + df = min(1.0, df + fragment_light); - float value = max(0.3, daylight + fragment_light); - value = (value*0.5+0.2) + (value*0.3+0.1) * df; - value = (value*1.2) * (ao*0.7); - vec4 light_color = vec4(value, value, value, 1.0); - - vec3 a = vec3(texture2D(sky_sampler, vec2(timer, fog_height))) * sky_tint; - vec4 sky_color = vec4(a, 1.0); + float value = max(0.3, daylight + fragment_light); + value = (value*0.5+0.2) + (value*0.3+0.1) * df; + value = (value*1.2) * (ao*0.7); + vec4 light_color = vec4(value, value, value, 1.0); + + vec3 a = vec3(texture2D(sky_sampler, vec2(timer, fog_height))) * sky_tint; + vec4 sky_color = vec4(a, 1.0); + + if (color == vec4(1.0, 0.0, 1.0, 1.0)) { + discard; + } - if (color == vec4(1.0, 0.0, 1.0, 1.0)) { - discard; - } - if (color.a < 1.0) { - //color.a = 0.0; - //color = vec4(0.0); - discard; - } else { + //color.a = 0.0; + //color = vec4(0.0); + discard; + } else { color.a = 1.0; } - - color = color * light_color; - color = mix(color, sky_color, fog_factor); - gl_FragColor = vec4(color); + color = color * light_color; + color = mix(color, sky_color, fog_factor); + + gl_FragColor = vec4(color); + } diff --git a/shaders/text_fragment.glsl b/shaders/text_fragment.glsl index 6912993..d471280 100644 --- a/shaders/text_fragment.glsl +++ b/shaders/text_fragment.glsl @@ -12,8 +12,8 @@ void main() { discard; } - //else { - //color.a = max(color.a, 0.4); - //} + else { + color.a = max(color.a, 0.4); + } gl_FragColor = color; } diff --git a/src/config.h b/src/config.h index 913dc4f..149bdc5 100644 --- a/src/config.h +++ b/src/config.h @@ -1,6 +1,10 @@ #ifndef _config_h_ #define _config_h_ + +// TODO: Transfer the maximum of stuff to ingame tweakable config (main.c) + + //game #define FLY_SPEED 70 #define WALK_SPEED 6 @@ -16,9 +20,9 @@ // app parameters #define DEBUG 1 #define FULLSCREEN 0 //put to zero, fullscreen bugs -#define WINDOW_WIDTH 1024 +#define WINDOW_WIDTH 1366 #define WINDOW_HEIGHT 768 -#define VSYNC 1 +#define VSYNC 0 #define SCROLL_THRESHOLD 0.1 #define MAX_MESSAGES 10 #define DB_PATH "world/omicron-world.db" @@ -26,17 +30,9 @@ #define DAY_LENGTH 500 #define INVERT_MOUSE 0 -// rendering options -#define SHOW_LIGHTS 1 -#define SHOW_PLANTS 1 -#define SHOW_CLOUDS 1 -#define SHOW_TREES 1 -#define SHOW_ITEM 1 -#define SHOW_CROSSHAIRS 1 -#define SHOW_INFO_TEXT 1 -#define SHOW_CHAT_TEXT 1 -#define SHOW_PLAYER_NAMES 1 -#define FONT_SIZE 16 // 12 small, 16 average, 24, big +// rendering options +// were transfered to +// options in main.c // key bindings #define CRAFT_KEY_FORWARD 'W' @@ -57,10 +53,10 @@ #define CRAFT_KEY_SIGN '-' // advanced parameters -#define CREATE_CHUNK_RADIUS 10 -#define RENDER_CHUNK_RADIUS 6 -#define RENDER_SIGN_RADIUS 6 -#define DELETE_CHUNK_RADIUS 14 +#define CREATE_CHUNK_RADIUS 5 +#define RENDER_CHUNK_RADIUS 4 +#define RENDER_SIGN_RADIUS 1.5 +#define DELETE_CHUNK_RADIUS 6 #define CHUNK_SIZE 32 #define COMMIT_INTERVAL 5 diff --git a/src/cube.c b/src/cube.c index 1697553..2a3fd10 100644 --- a/src/cube.c +++ b/src/cube.c @@ -10,6 +10,14 @@ void make_cube_faces( int wleft, int wright, int wtop, int wbottom, int wfront, int wback, float x, float y, float z, float scale, NonCubeType noncube) { + /*static const float positions[6][4][3] = { + {{-1, -1, -1}, {-1, -1, +1}, {-1, +1, -1}, {-1, +1, +1}}, + {{+1, -1, -1}, {+1, -1, +1}, {+1, +1, -1}, {+1, +1, +1}}, + {{-1, +1, -1}, {-1, +1, +1}, {+1, +1, -1}, {+1, +1, +1}}, + {{-1, -1, -1}, {-1, -1, +1}, {+1, -1, -1}, {+1, -1, +1}}, + {{-1, -1, -1}, {-1, +1, -1}, {+1, -1, -1}, {+1, +1, -1}}, + {{-1, -1, +1}, {-1, +1, +1}, {+1, -1, +1}, {+1, +1, +1}} + };*/ static const float positions[6][4][3] = { {{-1, -1, -1}, {-1, -1, +1}, {-1, +1, -1}, {-1, +1, +1}}, {{+1, -1, -1}, {+1, -1, +1}, {+1, +1, -1}, {+1, +1, +1}}, @@ -18,6 +26,7 @@ void make_cube_faces( {{-1, -1, -1}, {-1, +1, -1}, {+1, -1, -1}, {+1, +1, -1}}, {{-1, -1, +1}, {-1, +1, +1}, {+1, -1, +1}, {+1, +1, +1}} }; + static const float normals[6][3] = { {-1, 0, 0}, {+1, 0, 0}, @@ -185,6 +194,7 @@ void make_plant( mat_apply(data, ma, 24, 0, 10); } +// Player model void make_player( float *data, float x, float y, float z, float rx, float ry) diff --git a/src/item.c b/src/item.c index 44c56be..3605699 100644 --- a/src/item.c +++ b/src/item.c @@ -21,6 +21,7 @@ const int items[] = { Item_COBBLE, Item_LIGHT_STONE, Item_DARK_STONE, + Item_TORCH, Item_CHEST, Item_TNT, Item_LEAVES, @@ -191,6 +192,7 @@ const int blocks[256][6] = { {0, 0, 0, 0, 0, 0}, // 88 {19, 19, 35, 0, 19, 19}, // 89 - swamp dirt {0, 0, 0, 0, 0, 0}, // 90 + {0, 0, 0, 0, 0, 16}, // 91 {0, 0, 0, 0, 0, 0} // - empty }; @@ -221,12 +223,13 @@ const int plants[256] = { 58, // 87 - mushroom 59, // 88 - mushroom patch 0, - 60 // 90 - swamp tall grass + 60, // 90 - swamp tall grass + 96 // 91 - torch }; const int obj[256] = { - 60 // 90 - swamp tall grass + 6 // test }; int is_plant(int w) { @@ -244,6 +247,7 @@ int is_plant(int w) { case Item_MUSHROOM: case Item_MUSHROOMS: case Item_SWAMP_TALL_GRASS: + case Item_TORCH: return 1; default: return 0; @@ -262,6 +266,7 @@ int is_obstacle(int w) { case Item_EMPTY: case Item_CLOUD: case Item_WATER: + case Item_TORCH: return 0; default: return 1; @@ -284,6 +289,7 @@ int is_transparent(int w) { case Item_GLASS: //case Item_LEAVES: //for better performance (8 fps -> 60fps OPTIMIZATION NEEDED!) case Item_WATER: //Just to stop Xray-ing + case Item_TORCH: return 1; default: return 0; @@ -322,6 +328,7 @@ int buildable_to(int w) { switch (w) { case Item_WATER: case Item_CLOUD: + case Item_TORCH: return 0; default: return 1; diff --git a/src/item.h b/src/item.h index 2b67246..c5974bc 100644 --- a/src/item.h +++ b/src/item.h @@ -84,6 +84,7 @@ typedef enum { Item_MUSHROOMS, Item_SWAMP_GRASS, Item_SWAMP_TALL_GRASS, + Item_TORCH, Item_max } Item; diff --git a/src/main.c b/src/main.c index 0e6778d..8a7453a 100644 --- a/src/main.c +++ b/src/main.c @@ -48,730 +48,743 @@ #define WORKER_BUSY 1 #define WORKER_DONE 2 +// initial values to allow the game to run without config +int SHOW_LIGHTS = 1; +int SHOW_PLANTS = 1; +int SHOW_CLOUDS = 1; +int SHOW_TREES = 1; +int SHOW_ITEM = 1; +int SHOW_CROSSHAIRS = 1; +int SHOW_INFO_TEXT = 1; +int SHOW_CHAT_TEXT = 1; +int SHOW_PLAYER_NAMES = 1; +int FONT_SIZE = 16; //16 + + typedef struct { - int p; - int q; - int load; - Map *block_maps[3][3]; - Map *light_maps[3][3]; - int miny; - int maxy; - int faces; - GLfloat *data; + int p; + int q; + int load; + Map *block_maps[3][3]; + Map *light_maps[3][3]; + int miny; + int maxy; + int faces; + GLfloat *data; } WorkerItem; typedef struct { - int index; - int state; - thrd_t thrd; - mtx_t mtx; - cnd_t cnd; - WorkerItem item; + int index; + int state; + thrd_t thrd; + mtx_t mtx; + cnd_t cnd; + WorkerItem item; } Worker; typedef struct { - int x; - int y; - int z; - int w; + int x; + int y; + int z; + int w; } Block; typedef struct { - float r; - float g; - float b; + float r; + float g; + float b; } SkyColor; typedef struct { - GLFWwindow *window; - Worker workers[WORKERS]; - Chunk chunks[MAX_CHUNKS]; - int chunk_count; - int create_radius; - int render_radius; - int delete_radius; - int sign_radius; - Player players[MAX_PLAYERS]; - int player_count; - int typing; - char typing_buffer[MAX_TEXT_LENGTH]; - int message_index; - char messages[MAX_MESSAGES][MAX_TEXT_LENGTH]; - int width; - int height; - int observe1; - int observe2; - int flying; - int item_index; - int scale; - int ortho; - float fov; - int suppress_char; - int mode; - int mode_changed; - char db_path[MAX_PATH_LENGTH]; - char server_addr[MAX_ADDR_LENGTH]; - int server_port; - int day_length; - int time_changed; - Block block0; - Block block1; - Block copy0; - Block copy1; - SkyColor sky_color; - SkyColor last_sky_color; - //int is_fullscreen; - Inventory inventory; + GLFWwindow *window; + Worker workers[WORKERS]; + Chunk chunks[MAX_CHUNKS]; + int chunk_count; + int create_radius; + int render_radius; + int delete_radius; + int sign_radius; + Player players[MAX_PLAYERS]; + int player_count; + int typing; + char typing_buffer[MAX_TEXT_LENGTH]; + int message_index; + char messages[MAX_MESSAGES][MAX_TEXT_LENGTH]; + int width; + int height; + int observe1; + int observe2; + int flying; + int item_index; + int scale; + int ortho; + float fov; + int suppress_char; + int mode; + int mode_changed; + char db_path[MAX_PATH_LENGTH]; + char server_addr[MAX_ADDR_LENGTH]; + int server_port; + int day_length; + int time_changed; + Block block0; + Block block1; + Block copy0; + Block copy1; + SkyColor sky_color; + SkyColor last_sky_color; + //int is_fullscreen; + Inventory inventory; } Model; static Model model; static Model *g = &model; float time_of_day() { - if (g->day_length <= 0) { - return 0.5; - } - float t; - t = glfwGetTime(); - t = t / g->day_length; - t = t - (int)t; - return t; + if (g->day_length <= 0) { + return 0.5; + } + float t; + t = glfwGetTime(); + t = t / g->day_length; + t = t - (int)t; + return t; } float get_daylight() { - float timer = time_of_day(); - if (timer < 0.5) { - float t = (timer - 0.25) * 100; - return 1 / (1 + powf(2, -t)); - } - else { - float t = (timer - 0.85) * 100; - return 1 - 1 / (1 + powf(2, -t)); - } + float timer = time_of_day(); + if (timer < 0.5) { + float t = (timer - 0.25) * 100; + return 1 / (1 + powf(2, -t)); + } + else { + float t = (timer - 0.85) * 100; + return 1 - 1 / (1 + powf(2, -t)); + } } void get_sky_tint(Biome biome, SkyColor *c) { - switch(biome) { - //Not needed - //case Biome_TEMPERATE: - case Biome_DESERT: - c->r = 1.6f; - c->g = 1.3f, - c->b = 1.0f; - break; - case Biome_MESA: - c->r = 2.2f; - c->g = 1.6f, - c->b = 1.7f; - break; - case Biome_RAINFOREST: - c->r = 1.5f; - c->g = 2.0f, - c->b = 2.0f; - break; - case Biome_TAIGA: - c->r = 2.0f; - c->g = 2.0f, - c->b = 2.0f; - break; - case Biome_SWAMP: - c->r = 0.4f; - c->g = 1.0f, - c->b = 0.6f; - break; - default: - c->r = 1.0f; - c->g = 1.5f, - c->b = 2.0f; - break; - } + switch(biome) { + //Not needed + //case Biome_TEMPERATE: + case Biome_DESERT: + c->r = 1.6f; + c->g = 1.3f, + c->b = 1.0f; + break; + case Biome_MESA: + c->r = 2.2f; + c->g = 1.6f, + c->b = 1.7f; + break; + case Biome_RAINFOREST: + c->r = 1.5f; + c->g = 2.0f, + c->b = 2.0f; + break; + case Biome_TAIGA: + c->r = 2.0f; + c->g = 2.0f, + c->b = 2.0f; + break; + case Biome_SWAMP: + c->r = 0.4f; + c->g = 1.0f, + c->b = 0.6f; + break; + default: + c->r = 1.0f; + c->g = 1.5f, + c->b = 2.0f; + break; + } } int get_scale_factor() { - int window_width, window_height; - int buffer_width, buffer_height; - glfwGetWindowSize(g->window, &window_width, &window_height); - glfwGetFramebufferSize(g->window, &buffer_width, &buffer_height); - int result = buffer_width / window_width; - result = MAX(1, result); - result = MIN(2, result); - return result; + int window_width, window_height; + int buffer_width, buffer_height; + glfwGetWindowSize(g->window, &window_width, &window_height); + glfwGetFramebufferSize(g->window, &buffer_width, &buffer_height); + int result = buffer_width / window_width; + result = MAX(1, result); + result = MIN(2, result); + return result; } void get_sight_vector(float rx, float ry, float *vx, float *vy, float *vz) { - float m = cosf(ry); - *vx = cosf(rx - RADIANS(90)) * m; - *vy = sinf(ry); - *vz = sinf(rx - RADIANS(90)) * m; + float m = cosf(ry); + *vx = cosf(rx - RADIANS(90)) * m; + *vy = sinf(ry); + *vz = sinf(rx - RADIANS(90)) * m; } void get_motion_vector(int flying, int sz, int sx, float rx, float ry, - float *vx, float *vy, float *vz) { - *vx = 0; *vy = 0; *vz = 0; - if (!sz && !sx) { - return; - } - float strafe = atan2f(sz, sx); - if (flying) { - float m = cosf(ry); - float y = sinf(ry); - if (sx) { - if (!sz) { - y = 0; - } - m = 1; - } - if (sz > 0) { - y = -y; - } - *vx = cosf(rx + strafe) * m; - *vy = y; - *vz = sinf(rx + strafe) * m; - } - else { - *vx = cosf(rx + strafe); - *vy = 0; - *vz = sinf(rx + strafe); - } + float *vx, float *vy, float *vz) { + *vx = 0; *vy = 0; *vz = 0; + if (!sz && !sx) { + return; + } + float strafe = atan2f(sz, sx); + if (flying) { + float m = cosf(ry); + float y = sinf(ry); + if (sx) { + if (!sz) { + y = 0; + } + m = 1; + } + if (sz > 0) { + y = -y; + } + *vx = cosf(rx + strafe) * m; + *vy = y; + *vz = sinf(rx + strafe) * m; + } + else { + *vx = cosf(rx + strafe); + *vy = 0; + *vz = sinf(rx + strafe); + } } GLuint gen_wireframe_buffer(float x, float y, float z, float n) { - float data[72]; - make_cube_wireframe(data, x, y, z, n); - return gen_buffer(sizeof(data), data); + float data[72]; + make_cube_wireframe(data, x, y, z, n); + return gen_buffer(sizeof(data), data); } GLuint gen_sky_buffer() { - float data[12288]; - make_sphere(data, 1, 3); - return gen_buffer(sizeof(data), data); + float data[12288]; + make_sphere(data, 1, 3); + return gen_buffer(sizeof(data), data); } GLuint gen_cube_buffer(float x, float y, float z, float n, int w) { - GLfloat *data = malloc_faces(10, 6); - float ao[6][4] = {0}; - float light[6][4] = { - {0.5, 0.5, 0.5, 0.5}, - {0.5, 0.5, 0.5, 0.5}, - {0.5, 0.5, 0.5, 0.5}, - {0.5, 0.5, 0.5, 0.5}, - {0.5, 0.5, 0.5, 0.5}, - {0.5, 0.5, 0.5, 0.5} - }; - make_cube(data, ao, light, 1, 1, 1, 1, 1, 1, x, y, z, n, w); - return gen_faces(10, 6, data); + GLfloat *data = malloc_faces(10, 6); + float ao[6][4] = {0}; + float light[6][4] = { + {0.5, 0.5, 0.5, 0.5}, + {0.5, 0.5, 0.5, 0.5}, + {0.5, 0.5, 0.5, 0.5}, + {0.5, 0.5, 0.5, 0.5}, + {0.5, 0.5, 0.5, 0.5}, + {0.5, 0.5, 0.5, 0.5} + }; + make_cube(data, ao, light, 1, 1, 1, 1, 1, 1, x, y, z, n, w); + return gen_faces(10, 6, data); } Player *find_player(int id) { - for (int i = 0; i < g->player_count; i++) { - Player *player = g->players + i; - if (player->id == id) { - return player; - } - } - return 0; + for (int i = 0; i < g->player_count; i++) { + Player *player = g->players + i; + if (player->id == id) { + return player; + } + } + return 0; } void update_player(Player *player, - float x, float y, float z, float rx, float ry, int interpolate) + float x, float y, float z, float rx, float ry, int interpolate) { - if (interpolate) { - State *s1 = &player->state1; - State *s2 = &player->state2; - memcpy(s1, s2, sizeof(State)); - s2->x = x; s2->y = y; s2->z = z; s2->rx = rx; s2->ry = ry; - s2->t = glfwGetTime(); - if (s2->rx - s1->rx > PI) { - s1->rx += 2 * PI; - } - if (s1->rx - s2->rx > PI) { - s1->rx -= 2 * PI; - } - } - else { - State *s = &player->state; - s->x = x; s->y = y; s->z = z; s->rx = rx; s->ry = ry; - del_buffer(player->buffer); - player->buffer = gen_player_buffer(s->x, s->y, s->z, s->rx, s->ry); - } + if (interpolate) { + State *s1 = &player->state1; + State *s2 = &player->state2; + memcpy(s1, s2, sizeof(State)); + s2->x = x; s2->y = y; s2->z = z; s2->rx = rx; s2->ry = ry; + s2->t = glfwGetTime(); + if (s2->rx - s1->rx > PI) { + s1->rx += 2 * PI; + } + if (s1->rx - s2->rx > PI) { + s1->rx -= 2 * PI; + } + } + else { + State *s = &player->state; + s->x = x; s->y = y; s->z = z; s->rx = rx; s->ry = ry; + del_buffer(player->buffer); + player->buffer = gen_player_buffer(s->x, s->y, s->z, s->rx, s->ry); + } } void interpolate_player(Player *player) { - State *s1 = &player->state1; - State *s2 = &player->state2; - float t1 = s2->t - s1->t; - float t2 = glfwGetTime() - s2->t; - t1 = MIN(t1, 1); - t1 = MAX(t1, 0.1); - float p = MIN(t2 / t1, 1); - update_player( - player, - s1->x + (s2->x - s1->x) * p, - s1->y + (s2->y - s1->y) * p, - s1->z + (s2->z - s1->z) * p, - s1->rx + (s2->rx - s1->rx) * p, - s1->ry + (s2->ry - s1->ry) * p, - 0); + State *s1 = &player->state1; + State *s2 = &player->state2; + float t1 = s2->t - s1->t; + float t2 = glfwGetTime() - s2->t; + t1 = MIN(t1, 1); + t1 = MAX(t1, 0.1); + float p = MIN(t2 / t1, 1); + update_player( + player, + s1->x + (s2->x - s1->x) * p, + s1->y + (s2->y - s1->y) * p, + s1->z + (s2->z - s1->z) * p, + s1->rx + (s2->rx - s1->rx) * p, + s1->ry + (s2->ry - s1->ry) * p, + 0); } void delete_player(int id) { - Player *player = find_player(id); - if (!player) { - return; - } - int count = g->player_count; - del_buffer(player->buffer); - Player *other = g->players + (--count); - memcpy(player, other, sizeof(Player)); - g->player_count = count; + Player *player = find_player(id); + if (!player) { + return; + } + int count = g->player_count; + del_buffer(player->buffer); + Player *other = g->players + (--count); + memcpy(player, other, sizeof(Player)); + g->player_count = count; } void delete_all_players() { - for (int i = 0; i < g->player_count; i++) { - Player *player = g->players + i; - del_buffer(player->buffer); - } - g->player_count = 0; + for (int i = 0; i < g->player_count; i++) { + Player *player = g->players + i; + del_buffer(player->buffer); + } + g->player_count = 0; } float player_player_distance(Player *p1, Player *p2) { - State *s1 = &p1->state; - State *s2 = &p2->state; - float x = s2->x - s1->x; - float y = s2->y - s1->y; - float z = s2->z - s1->z; - return sqrtf(x * x + y * y + z * z); + State *s1 = &p1->state; + State *s2 = &p2->state; + float x = s2->x - s1->x; + float y = s2->y - s1->y; + float z = s2->z - s1->z; + return sqrtf(x * x + y * y + z * z); } float player_crosshair_distance(Player *p1, Player *p2) { - State *s1 = &p1->state; - State *s2 = &p2->state; - float d = player_player_distance(p1, p2); - float vx, vy, vz; - get_sight_vector(s1->rx, s1->ry, &vx, &vy, &vz); - vx *= d; vy *= d; vz *= d; - float px, py, pz; - px = s1->x + vx; py = s1->y + vy; pz = s1->z + vz; - float x = s2->x - px; - float y = s2->y - py; - float z = s2->z - pz; - return sqrtf(x * x + y * y + z * z); + State *s1 = &p1->state; + State *s2 = &p2->state; + float d = player_player_distance(p1, p2); + float vx, vy, vz; + get_sight_vector(s1->rx, s1->ry, &vx, &vy, &vz); + vx *= d; vy *= d; vz *= d; + float px, py, pz; + px = s1->x + vx; py = s1->y + vy; pz = s1->z + vz; + float x = s2->x - px; + float y = s2->y - py; + float z = s2->z - pz; + return sqrtf(x * x + y * y + z * z); } Player *player_crosshair(Player *player) { - Player *result = 0; - float threshold = RADIANS(5); - float best = 0; - for (int i = 0; i < g->player_count; i++) { - Player *other = g->players + i; - if (other == player) { - continue; - } - float p = player_crosshair_distance(player, other); - float d = player_player_distance(player, other); - if (d < 96 && p / d < threshold) { - if (best == 0 || d < best) { - best = d; - result = other; - } - } - } - return result; + Player *result = 0; + float threshold = RADIANS(5); + float best = 0; + for (int i = 0; i < g->player_count; i++) { + Player *other = g->players + i; + if (other == player) { + continue; + } + float p = player_crosshair_distance(player, other); + float d = player_player_distance(player, other); + if (d < 96 && p / d < threshold) { + if (best == 0 || d < best) { + best = d; + result = other; + } + } + } + return result; } Chunk *find_chunk(int p, int q) { - for (int i = 0; i < g->chunk_count; i++) { - Chunk *chunk = g->chunks + i; - if (chunk->p == p && chunk->q == q) { - return chunk; - } - } - return 0; + for (int i = 0; i < g->chunk_count; i++) { + Chunk *chunk = g->chunks + i; + if (chunk->p == p && chunk->q == q) { + return chunk; + } + } + return 0; } int chunk_distance(Chunk *chunk, int p, int q) { - int dp = ABS(chunk->p - p); - int dq = ABS(chunk->q - q); - return MAX(dp, dq); + int dp = ABS(chunk->p - p); + int dq = ABS(chunk->q - q); + return MAX(dp, dq); } int chunk_visible(float planes[6][4], int p, int q, int miny, int maxy) { - int x = p * CHUNK_SIZE - 1; - int z = q * CHUNK_SIZE - 1; - int d = CHUNK_SIZE + 1; - float points[8][3] = { - {x + 0, miny, z + 0}, - {x + d, miny, z + 0}, - {x + 0, miny, z + d}, - {x + d, miny, z + d}, - {x + 0, maxy, z + 0}, - {x + d, maxy, z + 0}, - {x + 0, maxy, z + d}, - {x + d, maxy, z + d} - }; - int n = g->ortho ? 4 : 6; - for (int i = 0; i < n; i++) { - int in = 0; - int out = 0; - for (int j = 0; j < 8; j++) { - float d = - planes[i][0] * points[j][0] + - planes[i][1] * points[j][1] + - planes[i][2] * points[j][2] + - planes[i][3]; - if (d < 0) { - out++; - } - else { - in++; - } - if (in && out) { - break; - } - } - if (in == 0) { - return 0; - } - } - return 1; + int x = p * CHUNK_SIZE - 1; + int z = q * CHUNK_SIZE - 1; + int d = CHUNK_SIZE + 1; + float points[8][3] = { + {x + 0, miny, z + 0}, + {x + d, miny, z + 0}, + {x + 0, miny, z + d}, + {x + d, miny, z + d}, + {x + 0, maxy, z + 0}, + {x + d, maxy, z + 0}, + {x + 0, maxy, z + d}, + {x + d, maxy, z + d} + }; + int n = g->ortho ? 4 : 6; + for (int i = 0; i < n; i++) { + int in = 0; + int out = 0; + for (int j = 0; j < 8; j++) { + float d = + planes[i][0] * points[j][0] + + planes[i][1] * points[j][1] + + planes[i][2] * points[j][2] + + planes[i][3]; + if (d < 0) { + out++; + } + else { + in++; + } + if (in && out) { + break; + } + } + if (in == 0) { + return 0; + } + } + return 1; } int highest_block(float x, float z) { - int result = -1; - int nx = roundf(x); - int nz = roundf(z); - int p = chunked(x); - int q = chunked(z); - Chunk *chunk = find_chunk(p, q); - if (chunk) { - Map *map = &chunk->map; - MAP_FOR_EACH(map, ex, ey, ez, ew) { - if (is_obstacle(ew) && ex == nx && ez == nz) { - result = MAX(result, ey); - } - } END_MAP_FOR_EACH; - } - return result; + int result = -1; + int nx = roundf(x); + int nz = roundf(z); + int p = chunked(x); + int q = chunked(z); + Chunk *chunk = find_chunk(p, q); + if (chunk) { + Map *map = &chunk->map; + MAP_FOR_EACH(map, ex, ey, ez, ew) { + if (is_obstacle(ew) && ex == nx && ez == nz) { + result = MAX(result, ey); + } + } END_MAP_FOR_EACH; + } + return result; } int _hit_test( - Map *map, float max_distance, int previous, - float x, float y, float z, - float vx, float vy, float vz, - int *hx, int *hy, int *hz) + Map *map, float max_distance, int previous, + float x, float y, float z, + float vx, float vy, float vz, + int *hx, int *hy, int *hz) { - int m = 32; - int px = 0; - int py = 0; - int pz = 0; - for (int i = 0; i < max_distance * m; i++) { - int nx = roundf(x); - int ny = roundf(y); - int nz = roundf(z); - if (nx != px || ny != py || nz != pz) { - int hw = map_get(map, nx, ny, nz); - if (hw > 0) { - if (previous) { - *hx = px; *hy = py; *hz = pz; - } - else { - *hx = nx; *hy = ny; *hz = nz; - } - return hw; - } - px = nx; py = ny; pz = nz; - } - x += vx / m; y += vy / m; z += vz / m; - } - return 0; + int m = 32; + int px = 0; + int py = 0; + int pz = 0; + for (int i = 0; i < max_distance * m; i++) { + int nx = roundf(x); + int ny = roundf(y); + int nz = roundf(z); + if (nx != px || ny != py || nz != pz) { + int hw = map_get(map, nx, ny, nz); + if (hw > 0) { + if (previous) { + *hx = px; *hy = py; *hz = pz; + } + else { + *hx = nx; *hy = ny; *hz = nz; + } + return hw; + } + px = nx; py = ny; pz = nz; + } + x += vx / m; y += vy / m; z += vz / m; + } + return 0; } int hit_test( - int previous, float x, float y, float z, float rx, float ry, - int *bx, int *by, int *bz) + int previous, float x, float y, float z, float rx, float ry, + int *bx, int *by, int *bz) { - int result = 0; - float best = 0; - int p = chunked(x); - int q = chunked(z); - float vx, vy, vz; - get_sight_vector(rx, ry, &vx, &vy, &vz); - for (int i = 0; i < g->chunk_count; i++) { - Chunk *chunk = g->chunks + i; - if (chunk_distance(chunk, p, q) > 1) { - continue; - } - int hx, hy, hz; - int hw = _hit_test(&chunk->map, 8, previous, - x, y, z, vx, vy, vz, &hx, &hy, &hz); - if (hw > 0) { - float d = sqrtf( - powf(hx - x, 2) + powf(hy - y, 2) + powf(hz - z, 2)); - if (best == 0 || d < best) { - best = d; - *bx = hx; *by = hy; *bz = hz; - result = hw; - } - } - } - return result; + int result = 0; + float best = 0; + int p = chunked(x); + int q = chunked(z); + float vx, vy, vz; + get_sight_vector(rx, ry, &vx, &vy, &vz); + for (int i = 0; i < g->chunk_count; i++) { + Chunk *chunk = g->chunks + i; + if (chunk_distance(chunk, p, q) > 1) { + continue; + } + int hx, hy, hz; + int hw = _hit_test(&chunk->map, 8, previous, + x, y, z, vx, vy, vz, &hx, &hy, &hz); + if (hw > 0) { + float d = sqrtf( + powf(hx - x, 2) + powf(hy - y, 2) + powf(hz - z, 2)); + if (best == 0 || d < best) { + best = d; + *bx = hx; *by = hy; *bz = hz; + result = hw; + } + } + } + return result; } int hit_test_face(Player *player, int *x, int *y, int *z, int *face) { - State *s = &player->state; - int w = hit_test(0, s->x, s->y, s->z, s->rx, s->ry, x, y, z); - if (is_obstacle(w)) { - int hx, hy, hz; - hit_test(1, s->x, s->y, s->z, s->rx, s->ry, &hx, &hy, &hz); - int dx = hx - *x; - int dy = hy - *y; - int dz = hz - *z; - if (dx == -1 && dy == 0 && dz == 0) { - *face = 0; return 1; - } - if (dx == 1 && dy == 0 && dz == 0) { - *face = 1; return 1; - } - if (dx == 0 && dy == 0 && dz == -1) { - *face = 2; return 1; - } - if (dx == 0 && dy == 0 && dz == 1) { - *face = 3; return 1; - } - if (dx == 0 && dy == 1 && dz == 0) { - int degrees = roundf(DEGREES(atan2f(s->x - hx, s->z - hz))); - if (degrees < 0) { - degrees += 360; - } - int top = ((degrees + 45) / 90) % 4; - *face = 4 + top; return 1; - } - } - return 0; + State *s = &player->state; + int w = hit_test(0, s->x, s->y, s->z, s->rx, s->ry, x, y, z); + if (is_obstacle(w)) { + int hx, hy, hz; + hit_test(1, s->x, s->y, s->z, s->rx, s->ry, &hx, &hy, &hz); + int dx = hx - *x; + int dy = hy - *y; + int dz = hz - *z; + if (dx == -1 && dy == 0 && dz == 0) { + *face = 0; return 1; + } + if (dx == 1 && dy == 0 && dz == 0) { + *face = 1; return 1; + } + if (dx == 0 && dy == 0 && dz == -1) { + *face = 2; return 1; + } + if (dx == 0 && dy == 0 && dz == 1) { + *face = 3; return 1; + } + if (dx == 0 && dy == 1 && dz == 0) { + int degrees = roundf(DEGREES(atan2f(s->x - hx, s->z - hz))); + if (degrees < 0) { + degrees += 360; + } + int top = ((degrees + 45) / 90) % 4; + *face = 4 + top; return 1; + } + } + return 0; } int collide(int height, float *x, float *y, float *z) { - int result = 0; - int p = chunked(*x); - int q = chunked(*z); - Chunk *chunk = find_chunk(p, q); - if (!chunk) { - return result; - } - Map *map = &chunk->map; - int nx = roundf(*x); - int ny = roundf(*y); - int nz = roundf(*z); - float px = *x - nx; - float py = *y - ny; - float pz = *z - nz; - float pad = 0.25; - for (int dy = 0; dy < height; dy++) { - if (px < -pad && is_obstacle(map_get(map, nx - 1, ny - dy, nz))) { - *x = nx - pad; - } - if (px > pad && is_obstacle(map_get(map, nx + 1, ny - dy, nz))) { - *x = nx + pad; - } - if (py < -pad && is_obstacle(map_get(map, nx, ny - dy - 1, nz))) { - *y = ny - pad; - result = 1; - } - if (py > pad && is_obstacle(map_get(map, nx, ny - dy + 1, nz))) { - *y = ny + pad; - result = 1; - } - if (pz < -pad && is_obstacle(map_get(map, nx, ny - dy, nz - 1))) { - *z = nz - pad; - } - if (pz > pad && is_obstacle(map_get(map, nx, ny - dy, nz + 1))) { - *z = nz + pad; - } - } - return result; + int result = 0; + int p = chunked(*x); + int q = chunked(*z); + Chunk *chunk = find_chunk(p, q); + if (!chunk) { + return result; + } + Map *map = &chunk->map; + int nx = round(*x); + int ny = round(*y); + int nz = round(*z); + float px = *x - nx; + float py = *y - ny; + float pz = *z - nz; + float pad = 0.0625; + for (int dy = 0; dy < height; dy++) { + if (px < -pad && is_obstacle(map_get(map, nx - 1, ny - dy, nz))) { + *x = nx - pad; + } + if (px > pad && is_obstacle(map_get(map, nx + 1, ny - dy, nz))) { + *x = nx + pad; + } + if (py < -pad && is_obstacle(map_get(map, nx, ny - dy - 1, nz))) { + *y = ny - pad; + result = 1; + } + if (py > pad && is_obstacle(map_get(map, nx, ny - dy + 1, nz))) { + *y = ny + pad; + result = 1; + } + if (pz < -pad && is_obstacle(map_get(map, nx, ny - dy, nz - 1))) { + *z = nz - pad; + } + if (pz > pad && is_obstacle(map_get(map, nx, ny - dy, nz + 1))) { + *z = nz + pad; + } + } + return result; } int player_intersects_block( - int height, - float x, float y, float z, - int hx, int hy, int hz) + int height, + float x, float y, float z, + int hx, int hy, int hz) { - int nx = roundf(x); - int ny = roundf(y); - int nz = roundf(z); - for (int i = 0; i < height; i++) { - if (nx == hx && ny - i == hy && nz == hz) { - return 1; - } - } - return 0; + int nx = round(x); + int ny = round(y); + int nz = round(z); + for (int i = 0; i < height; i++) { + if (x == hx && y - i == hy && z == hz) { + return 1; + } + } + return 0; } int _gen_sign_buffer( - GLfloat *data, float x, float y, float z, int face, const char *text) + GLfloat *data, float x, float y, float z, int face, const char *text) { - static const int glyph_dx[8] = {0, 0, -1, 1, 1, 0, -1, 0}; - static const int glyph_dz[8] = {1, -1, 0, 0, 0, -1, 0, 1}; - static const int line_dx[8] = {0, 0, 0, 0, 0, 1, 0, -1}; - static const int line_dy[8] = {-1, -1, -1, -1, 0, 0, 0, 0}; - static const int line_dz[8] = {0, 0, 0, 0, 1, 0, -1, 0}; - if (face < 0 || face >= 8) { - return 0; - } - int count = 0; - float max_width = 64; - float line_height = 1.25; - char lines[1024]; - int rows = wrap(text, max_width, lines, 1024); - rows = MIN(rows, 5); - int dx = glyph_dx[face]; - int dz = glyph_dz[face]; - int ldx = line_dx[face]; - int ldy = line_dy[face]; - int ldz = line_dz[face]; - float n = 1.0 / (max_width / 10); - float sx = x - n * (rows - 1) * (line_height / 2) * ldx; - float sy = y - n * (rows - 1) * (line_height / 2) * ldy; - float sz = z - n * (rows - 1) * (line_height / 2) * ldz; - char *key; - char *line = tokenize(lines, "\n", &key); - while (line) { - int length = strlen(line); - int line_width = string_width(line); - line_width = MIN(line_width, max_width); - float rx = sx - dx * line_width / max_width / 2; - float ry = sy; - float rz = sz - dz * line_width / max_width / 2; - for (int i = 0; i < length; i++) { - int width = char_width(line[i]); - line_width -= width; - if (line_width < 0) { - break; - } - rx += dx * width / max_width / 2; - rz += dz * width / max_width / 2; - if (line[i] != ' ') { - make_character_3d( - data + count * 30, rx, ry, rz, n / 2, face, line[i]); - count++; - } - rx += dx * width / max_width / 2; - rz += dz * width / max_width / 2; - } - sx += n * line_height * ldx; - sy += n * line_height * ldy; - sz += n * line_height * ldz; - line = tokenize(NULL, "\n", &key); - rows--; - if (rows <= 0) { - break; - } - } - return count; + static const int glyph_dx[8] = {0, 0, -1, 1, 1, 0, -1, 0}; + static const int glyph_dz[8] = {1, -1, 0, 0, 0, -1, 0, 1}; + static const int line_dx[8] = {0, 0, 0, 0, 0, 1, 0, -1}; + static const int line_dy[8] = {-1, -1, -1, -1, 0, 0, 0, 0}; + static const int line_dz[8] = {0, 0, 0, 0, 1, 0, -1, 0}; + if (face < 0 || face >= 8) { + return 0; + } + int count = 0; + float max_width = 64; + float line_height = 1.25; + char lines[1024]; + int rows = wrap(text, max_width, lines, 1024); + rows = MIN(rows, 5); + int dx = glyph_dx[face]; + int dz = glyph_dz[face]; + int ldx = line_dx[face]; + int ldy = line_dy[face]; + int ldz = line_dz[face]; + float n = 1.0 / (max_width / 10); + float sx = x - n * (rows - 1) * (line_height / 2) * ldx; + float sy = y - n * (rows - 1) * (line_height / 2) * ldy; + float sz = z - n * (rows - 1) * (line_height / 2) * ldz; + char *key; + char *line = tokenize(lines, "\n", &key); + while (line) { + int length = strlen(line); + int line_width = string_width(line); + line_width = MIN(line_width, max_width); + float rx = sx - dx * line_width / max_width / 2; + float ry = sy; + float rz = sz - dz * line_width / max_width / 2; + for (int i = 0; i < length; i++) { + int width = char_width(line[i]); + line_width -= width; + if (line_width < 0) { + break; + } + rx += dx * width / max_width / 2; + rz += dz * width / max_width / 2; + if (line[i] != ' ') { + make_character_3d( + data + count * 30, rx, ry, rz, n / 2, face, line[i]); + count++; + } + rx += dx * width / max_width / 2; + rz += dz * width / max_width / 2; + } + sx += n * line_height * ldx; + sy += n * line_height * ldy; + sz += n * line_height * ldz; + line = tokenize(NULL, "\n", &key); + rows--; + if (rows <= 0) { + break; + } + } + return count; } void gen_sign_buffer(Chunk *chunk) { - SignList *signs = &chunk->signs; + SignList *signs = &chunk->signs; - // first pass - count characters - int max_faces = 0; - for (int i = 0; i < signs->size; i++) { - Sign *e = signs->data + i; - max_faces += strlen(e->text); - } + // first pass - count characters + int max_faces = 0; + for (int i = 0; i < signs->size; i++) { + Sign *e = signs->data + i; + max_faces += strlen(e->text); + } - // second pass - generate geometry - GLfloat *data = malloc_faces(5, max_faces); - int faces = 0; - for (int i = 0; i < signs->size; i++) { - Sign *e = signs->data + i; - faces += _gen_sign_buffer( - data + faces * 30, e->x, e->y, e->z, e->face, e->text); - } + // second pass - generate geometry + GLfloat *data = malloc_faces(5, max_faces); + int faces = 0; + for (int i = 0; i < signs->size; i++) { + Sign *e = signs->data + i; + faces += _gen_sign_buffer( + data + faces * 30, e->x, e->y, e->z, e->face, e->text); + } - del_buffer(chunk->sign_buffer); - chunk->sign_buffer = gen_faces(5, faces, data); - chunk->sign_faces = faces; + del_buffer(chunk->sign_buffer); + chunk->sign_buffer = gen_faces(5, faces, data); + chunk->sign_faces = faces; } int has_lights(Chunk *chunk) { - if (!SHOW_LIGHTS) { - return 0; - } - for (int dp = -1; dp <= 1; dp++) { - for (int dq = -1; dq <= 1; dq++) { - Chunk *other = chunk; - if (dp || dq) { - other = find_chunk(chunk->p + dp, chunk->q + dq); - } - if (!other) { - continue; - } - Map *map = &other->lights; - if (map->size) { - return 1; - } - } - } - return 0; + if (!SHOW_LIGHTS) { + return 0; + } + for (int dp = -1; dp <= 1; dp++) { + for (int dq = -1; dq <= 1; dq++) { + Chunk *other = chunk; + if (dp || dq) { + other = find_chunk(chunk->p + dp, chunk->q + dq); + } + if (!other) { + continue; + } + Map *map = &other->lights; + if (map->size) { + return 1; + } + } + } + return 0; } void dirty_chunk(Chunk *chunk) { - chunk->dirty = 1; - if (has_lights(chunk)) { - for (int dp = -1; dp <= 1; dp++) { - for (int dq = -1; dq <= 1; dq++) { - Chunk *other = find_chunk(chunk->p + dp, chunk->q + dq); - if (other) { - other->dirty = 1; - } - } - } - } + chunk->dirty = 1; + if (has_lights(chunk)) { + for (int dp = -1; dp <= 1; dp++) { + for (int dq = -1; dq <= 1; dq++) { + Chunk *other = find_chunk(chunk->p + dp, chunk->q + dq); + if (other) { + other->dirty = 1; + } + } + } + } } void occlusion( - char neighbors[27], char lights[27], float shades[27], - float ao[6][4], float light[6][4]) + char neighbors[27], char lights[27], float shades[27], + float ao[6][4], float light[6][4]) { - static const int lookup3[6][4][3] = { - {{0, 1, 3}, {2, 1, 5}, {6, 3, 7}, {8, 5, 7}}, - {{18, 19, 21}, {20, 19, 23}, {24, 21, 25}, {26, 23, 25}}, - {{6, 7, 15}, {8, 7, 17}, {24, 15, 25}, {26, 17, 25}}, - {{0, 1, 9}, {2, 1, 11}, {18, 9, 19}, {20, 11, 19}}, - {{0, 3, 9}, {6, 3, 15}, {18, 9, 21}, {24, 15, 21}}, - {{2, 5, 11}, {8, 5, 17}, {20, 11, 23}, {26, 17, 23}} - }; + static const int lookup3[6][4][3] = { + {{0, 1, 3}, {2, 1, 5}, {6, 3, 7}, {8, 5, 7}}, + {{18, 19, 21}, {20, 19, 23}, {24, 21, 25}, {26, 23, 25}}, + {{6, 7, 15}, {8, 7, 17}, {24, 15, 25}, {26, 17, 25}}, + {{0, 1, 9}, {2, 1, 11}, {18, 9, 19}, {20, 11, 19}}, + {{0, 3, 9}, {6, 3, 15}, {18, 9, 21}, {24, 15, 21}}, + {{2, 5, 11}, {8, 5, 17}, {20, 11, 23}, {26, 17, 23}} + }; static const int lookup4[6][4][4] = { - {{0, 1, 3, 4}, {1, 2, 4, 5}, {3, 4, 6, 7}, {4, 5, 7, 8}}, - {{18, 19, 21, 22}, {19, 20, 22, 23}, {21, 22, 24, 25}, {22, 23, 25, 26}}, - {{6, 7, 15, 16}, {7, 8, 16, 17}, {15, 16, 24, 25}, {16, 17, 25, 26}}, - {{0, 1, 9, 10}, {1, 2, 10, 11}, {9, 10, 18, 19}, {10, 11, 19, 20}}, - {{0, 3, 9, 12}, {3, 6, 12, 15}, {9, 12, 18, 21}, {12, 15, 21, 24}}, - {{2, 5, 11, 14}, {5, 8, 14, 17}, {11, 14, 20, 23}, {14, 17, 23, 26}} - }; - static const float curve[4] = {0.0, 0.25, 0.5, 0.75}; - for (int i = 0; i < 6; i++) { - for (int j = 0; j < 4; j++) { - int corner = neighbors[lookup3[i][j][0]]; - int side1 = neighbors[lookup3[i][j][1]]; - int side2 = neighbors[lookup3[i][j][2]]; - int value = side1 && side2 ? 3 : corner + side1 + side2; - float shade_sum = 0; - float light_sum = 0; - int is_light = lights[13] == 15; - for (int k = 0; k < 4; k++) { - shade_sum += shades[lookup4[i][j][k]]; - light_sum += lights[lookup4[i][j][k]]; - } - if (is_light) { - light_sum = 15 * 4 * 10; - } - float total = curve[value] + shade_sum / 4.0; - ao[i][j] = MIN(total, 1.0); - light[i][j] = light_sum / 15.0 / 4.0; - } - } + {{0, 1, 3, 4}, {1, 2, 4, 5}, {3, 4, 6, 7}, {4, 5, 7, 8}}, + {{18, 19, 21, 22}, {19, 20, 22, 23}, {21, 22, 24, 25}, {22, 23, 25, 26}}, + {{6, 7, 15, 16}, {7, 8, 16, 17}, {15, 16, 24, 25}, {16, 17, 25, 26}}, + {{0, 1, 9, 10}, {1, 2, 10, 11}, {9, 10, 18, 19}, {10, 11, 19, 20}}, + {{0, 3, 9, 12}, {3, 6, 12, 15}, {9, 12, 18, 21}, {12, 15, 21, 24}}, + {{2, 5, 11, 14}, {5, 8, 14, 17}, {11, 14, 20, 23}, {14, 17, 23, 26}} + }; + static const float curve[4] = {0.0, 0.25, 0.5, 0.75}; + for (int i = 0; i < 6; i++) { + for (int j = 0; j < 4; j++) { + int corner = neighbors[lookup3[i][j][0]]; + int side1 = neighbors[lookup3[i][j][1]]; + int side2 = neighbors[lookup3[i][j][2]]; + int value = side1 && side2 ? 3 : corner + side1 + side2; + float shade_sum = 0; + float light_sum = 0; + int is_light = lights[13] == 15; + for (int k = 0; k < 4; k++) { + shade_sum += shades[lookup4[i][j][k]]; + light_sum += lights[lookup4[i][j][k]]; + } + if (is_light) { + light_sum = 15 * 4 * 10; + } + float total = curve[value] + shade_sum / 4.0; + ao[i][j] = MIN(total, 1.0); + light[i][j] = light_sum / 15.0 / 4.0; + } + } } #define XZ_SIZE (CHUNK_SIZE * 3 + 2) @@ -783,43 +796,43 @@ void occlusion( int map_get_block(int x, int y, int z) { - int p = chunked(x); - int q = chunked(z); - Chunk *chunk = find_chunk(p, q); - if (chunk) { - Map *map = &chunk->map; - return map_get(map, x, y, z); - } - return 0; + int p = chunked(x); + int q = chunked(z); + Chunk *chunk = find_chunk(p, q); + if (chunk) { + Map *map = &chunk->map; + return map_get(map, x, y, z); + } + return 0; } void light_fill( - char *opaque, char *light, - int x, int y, int z, int w, int force) + char *opaque, char *light, + int x, int y, int z, int w, int force) { - if (x + w < XZ_LO || z + w < XZ_LO) { - return; - } - if (x - w > XZ_HI || z - w > XZ_HI) { - return; - } - if (y < 0 || y >= Y_SIZE) { - return; - } - if (light[XYZ(x, y, z)] >= w) { - return; - } - if (!force && opaque[XYZ(x, y, z)]) { - return; - } - light[XYZ(x, y, z)] = w--; - light_fill(opaque, light, x - 1, y, z, w, 0); - light_fill(opaque, light, x + 1, y, z, w, 0); - light_fill(opaque, light, x, y - 1, z, w, 0); - light_fill(opaque, light, x, y + 1, z, w, 0); - light_fill(opaque, light, x, y, z - 1, w, 0); - light_fill(opaque, light, x, y, z + 1, w, 0); + if (x + w < XZ_LO || z + w < XZ_LO) { + return; + } + if (x - w > XZ_HI || z - w > XZ_HI) { + return; + } + if (y < 0 || y >= Y_SIZE) { + return; + } + if (light[XYZ(x, y, z)] >= w) { + return; + } + if (!force && opaque[XYZ(x, y, z)]) { + return; + } + light[XYZ(x, y, z)] = w--; + light_fill(opaque, light, x - 1, y, z, w, 0); + light_fill(opaque, light, x + 1, y, z, w, 0); + light_fill(opaque, light, x, y - 1, z, w, 0); + light_fill(opaque, light, x, y + 1, z, w, 0); + light_fill(opaque, light, x, y, z - 1, w, 0); + light_fill(opaque, light, x, y, z + 1, w, 0); } int umap_get_block(Map *map, int x, int y, int z) { //optimized function for use during chunk generation @@ -827,94 +840,94 @@ int umap_get_block(Map *map, int x, int y, int z) { //optimized function for use } void compute_chunk(WorkerItem *item) { - char *opaque = (char *)calloc(XZ_SIZE * XZ_SIZE * Y_SIZE, sizeof(char)); - char *visible = (char *)calloc(XZ_SIZE * XZ_SIZE * Y_SIZE, sizeof(char)); - char *transparent = (char *)calloc(XZ_SIZE * XZ_SIZE * Y_SIZE, sizeof(char)); - char *light = (char *)calloc(XZ_SIZE * XZ_SIZE * Y_SIZE, sizeof(char)); - char *highest = (char *)calloc(XZ_SIZE * XZ_SIZE, sizeof(char)); + char *opaque = (char *)calloc(XZ_SIZE * XZ_SIZE * Y_SIZE, sizeof(char)); + char *visible = (char *)calloc(XZ_SIZE * XZ_SIZE * Y_SIZE, sizeof(char)); + char *transparent = (char *)calloc(XZ_SIZE * XZ_SIZE * Y_SIZE, sizeof(char)); + char *light = (char *)calloc(XZ_SIZE * XZ_SIZE * Y_SIZE, sizeof(char)); + char *highest = (char *)calloc(XZ_SIZE * XZ_SIZE, sizeof(char)); - int ox = item->p * CHUNK_SIZE - CHUNK_SIZE - 1; - int oy = -1; - int oz = item->q * CHUNK_SIZE - CHUNK_SIZE - 1; + int ox = item->p * CHUNK_SIZE - CHUNK_SIZE - 1; + int oy = -1; + int oz = item->q * CHUNK_SIZE - CHUNK_SIZE - 1; - // check for lights - int has_light = 0; - if (SHOW_LIGHTS) { - for (int a = 0; a < 3; a++) { - for (int b = 0; b < 3; b++) { - Map *map = item->light_maps[a][b]; - if (map && map->size) { - has_light = 1; - } - } - } - } + // check for lights + int has_light = 0; + if (SHOW_LIGHTS) { + for (int a = 0; a < 3; a++) { + for (int b = 0; b < 3; b++) { + Map *map = item->light_maps[a][b]; + if (map && map->size) { + has_light = 1; + } + } + } + } - // populate opaque array - for (int a = 0; a < 3; a++) { - for (int b = 0; b < 3; b++) { - Map *map = item->block_maps[a][b]; - if (!map) { - continue; - } - MAP_FOR_EACH(map, ex, ey, ez, ew) { - int x = ex - ox; - int y = ey - oy; - int z = ez - oz; - int w = ew; + // populate opaque array + for (int a = 0; a < 3; a++) { + for (int b = 0; b < 3; b++) { + Map *map = item->block_maps[a][b]; + if (!map) { + continue; + } + MAP_FOR_EACH(map, ex, ey, ez, ew) { + int x = ex - ox; + int y = ey - oy; + int z = ez - oz; + int w = ew; - // TODO: this should be unnecessary (but as long it works :3) - if (x < 0 || y < 0 || z < 0) { - continue; - } - if (x >= XZ_SIZE || y >= Y_SIZE || z >= XZ_SIZE) { - continue; - } - // END TODO + // TODO: this should be unnecessary (but as long it works :3) + if (x < 0 || y < 0 || z < 0) { + continue; + } + if (x >= XZ_SIZE || y >= Y_SIZE || z >= XZ_SIZE) { + continue; + } + // END TODO opaque[XYZ(x, y, z)] = !is_transparent(w); - transparent[XYZ(x, y, z)] = is_transparent(w); // dupe needed + transparent[XYZ(x, y, z)] = is_transparent(w); // dupe needed sorry visible[XYZ(x, y, z)] = !is_invisible(w); - - if (opaque[XYZ(x, y, z)]) { - highest[XZ(x, z)] = MAX(highest[XZ(x, z)], y); - } - } END_MAP_FOR_EACH; - } - } + + if (opaque[XYZ(x, y, z)]) { + highest[XZ(x, z)] = MAX(highest[XZ(x, z)], y); + } + } END_MAP_FOR_EACH; + } + } - // flood fill light intensities - if (has_light) { - for (int a = 0; a < 3; a++) { - for (int b = 0; b < 3; b++) { - Map *map = item->light_maps[a][b]; - if (!map) { - continue; - } - MAP_FOR_EACH(map, ex, ey, ez, ew) { - int x = ex - ox; - int y = ey - oy; - int z = ez - oz; - light_fill(opaque, light, x, y, z, ew, 1); - } END_MAP_FOR_EACH; - } - } - } + // flood fill light intensities + if (has_light) { + for (int a = 0; a < 3; a++) { + for (int b = 0; b < 3; b++) { + Map *map = item->light_maps[a][b]; + if (!map) { + continue; + } + MAP_FOR_EACH(map, ex, ey, ez, ew) { + int x = ex - ox; + int y = ey - oy; + int z = ez - oz; + light_fill(opaque, light, x, y, z, ew, 1); + } END_MAP_FOR_EACH; + } + } + } - Map *map = item->block_maps[1][1]; + Map *map = item->block_maps[1][1]; - // count exposed faces - int miny = 256; - int maxy = 0; - int faces = 0; - MAP_FOR_EACH(map, ex, ey, ez, ew) { - if (ew <= 0) { - continue; - } - - int x = ex - ox; - int y = ey - oy; - int z = ez - oz; - + // count exposed faces + int miny = 256; + int maxy = 0; + int faces = 0; + MAP_FOR_EACH(map, ex, ey, ez, ew) { + if (ew <= 0) { + continue; + } + + int x = ex - ox; + int y = ey - oy; + int z = ez - oz; + int f1 = !opaque[XYZ(x - 1, y, z)]; int f2 = !opaque[XYZ(x + 1, y, z)]; @@ -936,29 +949,46 @@ void compute_chunk(WorkerItem *item) { int i4 = visible[XYZ(x, y - 1, z)] && (ey > 0); int i5 = visible[XYZ(x, y, z - 1)]; int i6 = visible[XYZ(x, y, z + 1)]; - - if (is_transparent(ew) && !is_invisible(ew)) { + + if (is_transparent(ew) && !is_invisible(ew)) { if (v1 == 0) { f1 = 0; + } else { + f1 = 1; } if (v2 == 0) { f2 = 0; + } else { + f2 = 1; } if (v3 == 0) { f3 = 0; + } else { + f3 = 1; } + if (v4 == 0) { f4 = 0; + } else { + f4 = 1; } + if (v5 == 0) { f5 = 0; + } else { + f5 = 1; } + if (v6 == 0) { f6 = 0; - } + } else { + f6 = 1; + } + + /* //air check if (i1 == 0) { f1 = 1; @@ -979,39 +1009,40 @@ void compute_chunk(WorkerItem *item) { } if (i6 == 0) { f6 = 1; - } + } + */ } - - int total = f1 + f2 + f3 + f4 + f5 + f6; + + int total = f1 + f2 + f3 + f4 + f5 + f6; - if (total == 0) { + if (total == 0) { continue; - } - if (is_plant(ew)) { - total = 4; - } - miny = MIN(miny, ey); - maxy = MAX(maxy, ey); - faces += total; - } END_MAP_FOR_EACH; + } + if (is_plant(ew)) { + total = 4; + } + miny = MIN(miny, ey); + maxy = MAX(maxy, ey); + faces += total; + } END_MAP_FOR_EACH; - // generate geometry - GLfloat *data = malloc_faces(10, faces); - int offset = 0; - MAP_FOR_EACH(map, ex, ey, ez, ew) { - if (ew <= 0) { - continue; - } - int x = ex - ox; - int y = ey - oy; - int z = ez - oz; - int f1 = !opaque[XYZ(x - 1, y, z)]; - int f2 = !opaque[XYZ(x + 1, y, z)]; - int f3 = !opaque[XYZ(x, y + 1, z)]; - int f4 = !opaque[XYZ(x, y - 1, z)] && (ey > 0); - int f5 = !opaque[XYZ(x, y, z - 1)]; - int f6 = !opaque[XYZ(x, y, z + 1)]; - + // generate geometry + GLfloat *data = malloc_faces(10, faces); + int offset = 0; + MAP_FOR_EACH(map, ex, ey, ez, ew) { + if (ew <= 0) { + continue; + } + int x = ex - ox; + int y = ey - oy; + int z = ez - oz; + int f1 = !opaque[XYZ(x - 1, y, z)]; + int f2 = !opaque[XYZ(x + 1, y, z)]; + int f3 = !opaque[XYZ(x, y + 1, z)]; + int f4 = !opaque[XYZ(x, y - 1, z)] && (ey > 0); + int f5 = !opaque[XYZ(x, y, z - 1)]; + int f6 = !opaque[XYZ(x, y, z + 1)]; + int v1 = !transparent[XYZ(x - 1, y, z)]; int v2 = !transparent[XYZ(x + 1, y, z)]; int v3 = !transparent[XYZ(x, y + 1, z)]; @@ -1025,48 +1056,41 @@ void compute_chunk(WorkerItem *item) { int i4 = visible[XYZ(x, y - 1, z)] && (ey > 0); int i5 = visible[XYZ(x, y, z - 1)]; int i6 = visible[XYZ(x, y, z + 1)]; - - if (is_transparent(ew) && !is_invisible(ew)) { + + if (is_transparent(ew) && !is_invisible(ew)) { if (v1 == 0) { f1 = 0; + } else { + f1 = 1; } if (v2 == 0) { f2 = 0; + } else { + f2 = 1; } if (v3 == 0) { f3 = 0; + } else { + f3 = 1; } + if (v4 == 0) { f4 = 0; + } else { + f4 = 1; } + if (v5 == 0) { f5 = 0; - } - if (v6 == 0) { - f6 = 0; - } - - //air check - if (i1 == 0) { - f1 = 1; - } - if (i2 == 0) { - f2 = 1; - } - - if (i3 == 0) { - f3 = 1; - } - if (i4 == 0) { - f4 = 1; - } - - if (i5 == 0) { + } else { f5 = 1; } - if (i6 == 0) { + + if (v6 == 0) { + f6 = 0; + } else { f6 = 1; } } @@ -1074,1063 +1098,1070 @@ void compute_chunk(WorkerItem *item) { int total = f1 + f2 + f3 + f4 + f5 + f6; if (total == 0) { - continue; - } - char neighbors[27] = {0}; - char lights[27] = {0}; - float shades[27] = {0}; - int index = 0; - for (int dx = -1; dx <= 1; dx++) { - for (int dy = -1; dy <= 1; dy++) { - for (int dz = -1; dz <= 1; dz++) { - neighbors[index] = opaque[XYZ(x + dx, y + dy, z + dz)]; - lights[index] = light[XYZ(x + dx, y + dy, z + dz)]; - shades[index] = 0; - if (y + dy <= highest[XZ(x + dx, z + dz)]) { + continue; + } + char neighbors[27] = {0}; + char lights[27] = {0}; + float shades[27] = {0}; + int index = 0; + for (int dx = -1; dx <= 1; dx++) { + for (int dy = -1; dy <= 1; dy++) { + for (int dz = -1; dz <= 1; dz++) { + neighbors[index] = opaque[XYZ(x + dx, y + dy, z + dz)]; + lights[index] = light[XYZ(x + dx, y + dy, z + dz)]; + shades[index] = 0; + if (y + dy <= highest[XZ(x + dx, z + dz)]) { for (int oy = 0; oy < 8; oy++) { if (opaque[XYZ(x + dx, y + dy + oy, z + dz)]) { shades[index] = 1.0 - oy * 0.125; break; } } - } - index++; - } - } - } - float ao[6][4]; - float light[6][4]; - + } + index++; + } + } + } + float ao[6][4]; + float light[6][4]; + occlusion(neighbors, lights, shades, ao, light); - if (is_plant(ew)) { - total = 4; - float min_ao = 1; - float max_light = 0; - for (int a = 0; a < 6; a++) { - for (int b = 0; b < 4; b++) { - min_ao = MIN(min_ao, ao[a][b]); - max_light = MAX(max_light, light[a][b]); - } - } - float rotation = simplex2(ex, ez, 4, 0.5, 2) * 360; - make_plant( - data + offset, min_ao, max_light, - ex, ey, ez, 0.5, ew, rotation); - } - else if (is_noncube(ew) && noncube_type(ew) == NonCubeType_SLAB_LOWER) { - make_cube( - data + offset, ao, light, - f1, f2, f3, f4, f5, f6, - ex, ey, ez, 0.5, ew); - } - else { - make_cube( - data + offset, ao, light, - f1, f2, f3, f4, f5, f6, - ex, ey, ez, 0.5, ew); - } - offset += total * 60; - } END_MAP_FOR_EACH; + if (is_plant(ew)) { + total = 4; + float min_ao = 1; + float max_light = 0; + for (int a = 0; a < 6; a++) { + for (int b = 0; b < 4; b++) { + min_ao = MIN(min_ao, ao[a][b]); + max_light = MAX(max_light, light[a][b]); + } + } + float rotation = simplex2(ex, ez, 4, 0.5, 2) * 360; + make_plant( + data + offset, min_ao, max_light, + ex, ey, ez, 0.5, ew, rotation); + } + else if (is_noncube(ew) && noncube_type(ew) == NonCubeType_SLAB_LOWER) { + make_cube( + data + offset, ao, light, + f1, f2, f3, f4, f5, f6, + ex, ey, ez, 0.5, ew); + } + else { + make_cube( + data + offset, ao, light, + f1, f2, f3, f4, f5, f6, + ex, ey, ez, 0.5, ew); + } + offset += total * 60; + } END_MAP_FOR_EACH; - free(opaque); - free(visible); - free(transparent); - free(light); - free(highest); + free(opaque); + free(visible); + free(transparent); + free(light); + free(highest); - item->miny = miny; - item->maxy = maxy; - item->faces = faces; - item->data = data; + item->miny = miny; + item->maxy = maxy; + item->faces = faces; + item->data = data; } void generate_chunk(Chunk *chunk, WorkerItem *item) { - chunk->miny = item->miny; - chunk->maxy = item->maxy; - chunk->faces = item->faces; - del_buffer(chunk->buffer); - chunk->buffer = gen_faces(10, item->faces, item->data); - gen_sign_buffer(chunk); + chunk->miny = item->miny; + chunk->maxy = item->maxy; + chunk->faces = item->faces; + del_buffer(chunk->buffer); + chunk->buffer = gen_faces(10, item->faces, item->data); + gen_sign_buffer(chunk); } void gen_chunk_buffer(Chunk *chunk) { - WorkerItem _item; - WorkerItem *item = &_item; - item->p = chunk->p; - item->q = chunk->q; - for (int dp = -1; dp <= 1; dp++) { - for (int dq = -1; dq <= 1; dq++) { - Chunk *other = chunk; - if (dp || dq) { - other = find_chunk(chunk->p + dp, chunk->q + dq); - } - if (other) { - item->block_maps[dp + 1][dq + 1] = &other->map; - item->light_maps[dp + 1][dq + 1] = &other->lights; - } - else { - item->block_maps[dp + 1][dq + 1] = 0; - item->light_maps[dp + 1][dq + 1] = 0; - } - } - } - compute_chunk(item); - generate_chunk(chunk, item); - chunk->dirty = 0; + WorkerItem _item; + WorkerItem *item = &_item; + item->p = chunk->p; + item->q = chunk->q; + for (int dp = -1; dp <= 1; dp++) { + for (int dq = -1; dq <= 1; dq++) { + Chunk *other = chunk; + if (dp || dq) { + other = find_chunk(chunk->p + dp, chunk->q + dq); + } + if (other) { + item->block_maps[dp + 1][dq + 1] = &other->map; + item->light_maps[dp + 1][dq + 1] = &other->lights; + } + else { + item->block_maps[dp + 1][dq + 1] = 0; + item->light_maps[dp + 1][dq + 1] = 0; + } + } + } + compute_chunk(item); + generate_chunk(chunk, item); + chunk->dirty = 0; } void map_set_func(int x, int y, int z, int w, void *arg) { - Map *map = (Map *)arg; - map_set(map, x, y, z, w); + Map *map = (Map *)arg; + map_set(map, x, y, z, w); } void load_chunk(WorkerItem *item) { - int p = item->p; - int q = item->q; - Map *block_map = item->block_maps[1][1]; - Map *light_map = item->light_maps[1][1]; - create_world(p, q, map_set_func, block_map); - db_load_blocks(block_map, p, q); - db_load_lights(light_map, p, q); + int p = item->p; + int q = item->q; + Map *block_map = item->block_maps[1][1]; + Map *light_map = item->light_maps[1][1]; + create_world(p, q, map_set_func, block_map); + db_load_blocks(block_map, p, q); + db_load_lights(light_map, p, q); } void request_chunk(int p, int q) { - int key = db_get_key(p, q); - client_chunk(p, q, key); + int key = db_get_key(p, q); + client_chunk(p, q, key); } void init_chunk(Chunk *chunk, int p, int q) { - chunk->p = p; - chunk->q = q; - chunk->faces = 0; - chunk->sign_faces = 0; - chunk->buffer = 0; - chunk->sign_buffer = 0; - dirty_chunk(chunk); - SignList *signs = &chunk->signs; - sign_list_alloc(signs, 16); - db_load_signs(signs, p, q); - Map *block_map = &chunk->map; - Map *light_map = &chunk->lights; - int dx = p * CHUNK_SIZE - 1; - int dy = 0; - int dz = q * CHUNK_SIZE - 1; - map_alloc(block_map, dx, dy, dz, 0x7fff); - map_alloc(light_map, dx, dy, dz, 0xf); + chunk->p = p; + chunk->q = q; + chunk->faces = 0; + chunk->sign_faces = 0; + chunk->buffer = 0; + chunk->sign_buffer = 0; + dirty_chunk(chunk); + SignList *signs = &chunk->signs; + sign_list_alloc(signs, 16); + db_load_signs(signs, p, q); + Map *block_map = &chunk->map; + Map *light_map = &chunk->lights; + int dx = p * CHUNK_SIZE - 1; + int dy = 0; + int dz = q * CHUNK_SIZE - 1; + map_alloc(block_map, dx, dy, dz, 0x7fff); + map_alloc(light_map, dx, dy, dz, 0xf); } void create_chunk(Chunk *chunk, int p, int q) { - init_chunk(chunk, p, q); + init_chunk(chunk, p, q); - WorkerItem _item; - WorkerItem *item = &_item; - item->p = chunk->p; - item->q = chunk->q; - item->block_maps[1][1] = &chunk->map; - item->light_maps[1][1] = &chunk->lights; - load_chunk(item); + WorkerItem _item; + WorkerItem *item = &_item; + item->p = chunk->p; + item->q = chunk->q; + item->block_maps[1][1] = &chunk->map; + item->light_maps[1][1] = &chunk->lights; + load_chunk(item); - request_chunk(p, q); + request_chunk(p, q); } void delete_chunks() { - int count = g->chunk_count; - State *s1 = &g->players->state; - State *s2 = &(g->players + g->observe1)->state; - State *s3 = &(g->players + g->observe2)->state; - State *states[3] = {s1, s2, s3}; - for (int i = 0; i < count; i++) { - Chunk *chunk = g->chunks + i; - int delete = 1; - for (int j = 0; j < 3; j++) { - State *s = states[j]; - int p = chunked(s->x); - int q = chunked(s->z); - if (chunk_distance(chunk, p, q) < g->delete_radius) { - delete = 0; - break; - } - } - if (delete) { - map_free(&chunk->map); - map_free(&chunk->lights); - sign_list_free(&chunk->signs); - del_buffer(chunk->buffer); - del_buffer(chunk->sign_buffer); - Chunk *other = g->chunks + (--count); - memcpy(chunk, other, sizeof(Chunk)); - } - } - g->chunk_count = count; + int count = g->chunk_count; + State *s1 = &g->players->state; + State *s2 = &(g->players + g->observe1)->state; + State *s3 = &(g->players + g->observe2)->state; + State *states[3] = {s1, s2, s3}; + for (int i = 0; i < count; i++) { + Chunk *chunk = g->chunks + i; + int delete = 1; + for (int j = 0; j < 3; j++) { + State *s = states[j]; + int p = chunked(s->x); + int q = chunked(s->z); + if (chunk_distance(chunk, p, q) < g->delete_radius) { + delete = 0; + break; + } + } + if (delete) { + map_free(&chunk->map); + map_free(&chunk->lights); + sign_list_free(&chunk->signs); + del_buffer(chunk->buffer); + del_buffer(chunk->sign_buffer); + Chunk *other = g->chunks + (--count); + memcpy(chunk, other, sizeof(Chunk)); + } + } + g->chunk_count = count; } void delete_all_chunks() { - for (int i = 0; i < g->chunk_count; i++) { - Chunk *chunk = g->chunks + i; - map_free(&chunk->map); - map_free(&chunk->lights); - sign_list_free(&chunk->signs); - //printf("deleting: %d, %d\n", (int) chunk->buffer, (int) chunk->sign_buffer); - del_buffer(chunk->buffer); - del_buffer(chunk->sign_buffer); - } - g->chunk_count = 0; + for (int i = 0; i < g->chunk_count; i++) { + Chunk *chunk = g->chunks + i; + map_free(&chunk->map); + map_free(&chunk->lights); + sign_list_free(&chunk->signs); + //printf("deleting: %d, %d\n", (int) chunk->buffer, (int) chunk->sign_buffer); + del_buffer(chunk->buffer); + del_buffer(chunk->sign_buffer); + } + g->chunk_count = 0; } void check_workers() { - for (int i = 0; i < WORKERS; i++) { - Worker *worker = g->workers + i; - mtx_lock(&worker->mtx); - if (worker->state == WORKER_DONE) { - WorkerItem *item = &worker->item; - Chunk *chunk = find_chunk(item->p, item->q); - if (chunk) { - if (item->load) { - Map *block_map = item->block_maps[1][1]; - Map *light_map = item->light_maps[1][1]; - map_free(&chunk->map); - map_free(&chunk->lights); - map_copy(&chunk->map, block_map); - map_copy(&chunk->lights, light_map); - request_chunk(item->p, item->q); - } - generate_chunk(chunk, item); - } - for (int a = 0; a < 3; a++) { - for (int b = 0; b < 3; b++) { - Map *block_map = item->block_maps[a][b]; - Map *light_map = item->light_maps[a][b]; - if (block_map) { - map_free(block_map); - free(block_map); - } - if (light_map) { - map_free(light_map); - free(light_map); - } - } - } - worker->state = WORKER_IDLE; - } - mtx_unlock(&worker->mtx); - } + for (int i = 0; i < WORKERS; i++) { + Worker *worker = g->workers + i; + mtx_lock(&worker->mtx); + if (worker->state == WORKER_DONE) { + WorkerItem *item = &worker->item; + Chunk *chunk = find_chunk(item->p, item->q); + if (chunk) { + if (item->load) { + Map *block_map = item->block_maps[1][1]; + Map *light_map = item->light_maps[1][1]; + map_free(&chunk->map); + map_free(&chunk->lights); + map_copy(&chunk->map, block_map); + map_copy(&chunk->lights, light_map); + request_chunk(item->p, item->q); + } + generate_chunk(chunk, item); + } + for (int a = 0; a < 3; a++) { + for (int b = 0; b < 3; b++) { + Map *block_map = item->block_maps[a][b]; + Map *light_map = item->light_maps[a][b]; + if (block_map) { + map_free(block_map); + free(block_map); + } + if (light_map) { + map_free(light_map); + free(light_map); + } + } + } + worker->state = WORKER_IDLE; + } + mtx_unlock(&worker->mtx); + } } void force_chunks(Player *player) { - State *s = &player->state; - int p = chunked(s->x); - int q = chunked(s->z); - int r = 1; - for (int dp = -r; dp <= r; dp++) { - for (int dq = -r; dq <= r; dq++) { - int a = p + dp; - int b = q + dq; - Chunk *chunk = find_chunk(a, b); - if (chunk) { - if (chunk->dirty) { - gen_chunk_buffer(chunk); - } - } - else if (g->chunk_count < MAX_CHUNKS) { - chunk = g->chunks + g->chunk_count++; - create_chunk(chunk, a, b); - gen_chunk_buffer(chunk); - } - } - } + State *s = &player->state; + int p = chunked(s->x); + int q = chunked(s->z); + int r = 1; + for (int dp = -r; dp <= r; dp++) { + for (int dq = -r; dq <= r; dq++) { + int a = p + dp; + int b = q + dq; + Chunk *chunk = find_chunk(a, b); + if (chunk) { + if (chunk->dirty) { + gen_chunk_buffer(chunk); + } + } + else if (g->chunk_count < MAX_CHUNKS) { + chunk = g->chunks + g->chunk_count++; + create_chunk(chunk, a, b); + gen_chunk_buffer(chunk); + } + } + } } void ensure_chunks_worker(Player *player, Worker *worker) { - State *s = &player->state; - float matrix[16]; - set_matrix_3d( - matrix, g->width, g->height, - s->x, s->y, s->z, s->rx, s->ry, g->fov, g->ortho, g->render_radius); - float planes[6][4]; - frustum_planes(planes, g->render_radius, matrix); - int p = chunked(s->x); - int q = chunked(s->z); - int r = g->create_radius; - int start = 0x0fffffff; - int best_score = start; - int best_a = 0; - int best_b = 0; - for (int dp = -r; dp <= r; dp++) { - for (int dq = -r; dq <= r; dq++) { - int a = p + dp; - int b = q + dq; - int index = (ABS(a) ^ ABS(b)) % WORKERS; - if (index != worker->index) { - continue; - } - Chunk *chunk = find_chunk(a, b); - if (chunk && !chunk->dirty) { - continue; - } - int distance = MAX(ABS(dp), ABS(dq)); - int invisible = !chunk_visible(planes, a, b, 0, 256); - int priority = 0; - if (chunk) { - priority = chunk->buffer && chunk->dirty; - } - int score = (invisible << 24) | (priority << 16) | distance; - if (score < best_score) { - best_score = score; - best_a = a; - best_b = b; - } - } - } - if (best_score == start) { - return; - } - int a = best_a; - int b = best_b; - int load = 0; - Chunk *chunk = find_chunk(a, b); - if (!chunk) { - load = 1; - if (g->chunk_count < MAX_CHUNKS) { - chunk = g->chunks + g->chunk_count++; - init_chunk(chunk, a, b); - } - else { - return; - } - } - WorkerItem *item = &worker->item; - item->p = chunk->p; - item->q = chunk->q; - item->load = load; - for (int dp = -1; dp <= 1; dp++) { - for (int dq = -1; dq <= 1; dq++) { - Chunk *other = chunk; - if (dp || dq) { - other = find_chunk(chunk->p + dp, chunk->q + dq); - } - if (other) { - Map *block_map = malloc(sizeof(Map)); - map_copy(block_map, &other->map); - Map *light_map = malloc(sizeof(Map)); - map_copy(light_map, &other->lights); - item->block_maps[dp + 1][dq + 1] = block_map; - item->light_maps[dp + 1][dq + 1] = light_map; - } - else { - item->block_maps[dp + 1][dq + 1] = 0; - item->light_maps[dp + 1][dq + 1] = 0; - } - } - } - chunk->dirty = 0; - worker->state = WORKER_BUSY; - cnd_signal(&worker->cnd); + State *s = &player->state; + float matrix[16]; + set_matrix_3d( + matrix, g->width, g->height, + s->x, s->y, s->z, s->rx, s->ry, g->fov, g->ortho, g->render_radius); + float planes[6][4]; + frustum_planes(planes, g->render_radius, matrix); + int p = chunked(s->x); + int q = chunked(s->z); + int r = g->create_radius; + int start = 0x0fffffff; + int best_score = start; + int best_a = 0; + int best_b = 0; + for (int dp = -r; dp <= r; dp++) { + for (int dq = -r; dq <= r; dq++) { + int a = p + dp; + int b = q + dq; + int index = (ABS(a) ^ ABS(b)) % WORKERS; + if (index != worker->index) { + continue; + } + Chunk *chunk = find_chunk(a, b); + if (chunk && !chunk->dirty) { + continue; + } + int distance = MAX(ABS(dp), ABS(dq)); + int invisible = !chunk_visible(planes, a, b, 0, 256); + int priority = 0; + if (chunk) { + priority = chunk->buffer && chunk->dirty; + } + int score = (invisible << 24) | (priority << 16) | distance; + if (score < best_score) { + best_score = score; + best_a = a; + best_b = b; + } + } + } + if (best_score == start) { + return; + } + int a = best_a; + int b = best_b; + int load = 0; + Chunk *chunk = find_chunk(a, b); + if (!chunk) { + load = 1; + if (g->chunk_count < MAX_CHUNKS) { + chunk = g->chunks + g->chunk_count++; + init_chunk(chunk, a, b); + } + else { + return; + } + } + WorkerItem *item = &worker->item; + item->p = chunk->p; + item->q = chunk->q; + item->load = load; + for (int dp = -1; dp <= 1; dp++) { + for (int dq = -1; dq <= 1; dq++) { + Chunk *other = chunk; + if (dp || dq) { + other = find_chunk(chunk->p + dp, chunk->q + dq); + } + if (other) { + Map *block_map = malloc(sizeof(Map)); + map_copy(block_map, &other->map); + Map *light_map = malloc(sizeof(Map)); + map_copy(light_map, &other->lights); + item->block_maps[dp + 1][dq + 1] = block_map; + item->light_maps[dp + 1][dq + 1] = light_map; + } + else { + item->block_maps[dp + 1][dq + 1] = 0; + item->light_maps[dp + 1][dq + 1] = 0; + } + } + } + chunk->dirty = 0; + worker->state = WORKER_BUSY; + cnd_signal(&worker->cnd); } void ensure_chunks(Player *player) { - check_workers(); - force_chunks(player); - for (int i = 0; i < WORKERS; i++) { - Worker *worker = g->workers + i; - mtx_lock(&worker->mtx); - if (worker->state == WORKER_IDLE) { - ensure_chunks_worker(player, worker); - } - mtx_unlock(&worker->mtx); - } + check_workers(); + force_chunks(player); + for (int i = 0; i < WORKERS; i++) { + Worker *worker = g->workers + i; + mtx_lock(&worker->mtx); + if (worker->state == WORKER_IDLE) { + ensure_chunks_worker(player, worker); + } + mtx_unlock(&worker->mtx); + } } int worker_run(void *arg) { - Worker *worker = (Worker *)arg; - int running = 1; - while (running) { - mtx_lock(&worker->mtx); - while (worker->state != WORKER_BUSY) { - cnd_wait(&worker->cnd, &worker->mtx); - } - mtx_unlock(&worker->mtx); - WorkerItem *item = &worker->item; - if (item->load) { - load_chunk(item); - } - compute_chunk(item); - mtx_lock(&worker->mtx); - worker->state = WORKER_DONE; - mtx_unlock(&worker->mtx); - } - return 0; + Worker *worker = (Worker *)arg; + int running = 1; + while (running) { + mtx_lock(&worker->mtx); + while (worker->state != WORKER_BUSY) { + cnd_wait(&worker->cnd, &worker->mtx); + } + mtx_unlock(&worker->mtx); + WorkerItem *item = &worker->item; + if (item->load) { + load_chunk(item); + } + compute_chunk(item); + mtx_lock(&worker->mtx); + worker->state = WORKER_DONE; + mtx_unlock(&worker->mtx); + } + return 0; } void unset_sign(int x, int y, int z) { - int p = chunked(x); - int q = chunked(z); - Chunk *chunk = find_chunk(p, q); - if (chunk) { - SignList *signs = &chunk->signs; - if (sign_list_remove_all(signs, x, y, z)) { - chunk->dirty = 1; - db_delete_signs(x, y, z); - } - } - else { - db_delete_signs(x, y, z); - } + int p = chunked(x); + int q = chunked(z); + Chunk *chunk = find_chunk(p, q); + if (chunk) { + SignList *signs = &chunk->signs; + if (sign_list_remove_all(signs, x, y, z)) { + chunk->dirty = 1; + db_delete_signs(x, y, z); + } + } + else { + db_delete_signs(x, y, z); + } } void unset_sign_face(int x, int y, int z, int face) { - int p = chunked(x); - int q = chunked(z); - Chunk *chunk = find_chunk(p, q); - if (chunk) { - SignList *signs = &chunk->signs; - if (sign_list_remove(signs, x, y, z, face)) { - chunk->dirty = 1; - db_delete_sign(x, y, z, face); - } - } - else { - db_delete_sign(x, y, z, face); - } + int p = chunked(x); + int q = chunked(z); + Chunk *chunk = find_chunk(p, q); + if (chunk) { + SignList *signs = &chunk->signs; + if (sign_list_remove(signs, x, y, z, face)) { + chunk->dirty = 1; + db_delete_sign(x, y, z, face); + } + } + else { + db_delete_sign(x, y, z, face); + } } void _set_sign( - int p, int q, int x, int y, int z, int face, const char *text, int dirty) + int p, int q, int x, int y, int z, int face, const char *text, int dirty) { - if (strlen(text) == 0) { - unset_sign_face(x, y, z, face); - return; - } - Chunk *chunk = find_chunk(p, q); - if (chunk) { - SignList *signs = &chunk->signs; - sign_list_add(signs, x, y, z, face, text); - if (dirty) { - chunk->dirty = 1; - } - } - db_insert_sign(p, q, x, y, z, face, text); + if (strlen(text) == 0) { + unset_sign_face(x, y, z, face); + return; + } + Chunk *chunk = find_chunk(p, q); + if (chunk) { + SignList *signs = &chunk->signs; + sign_list_add(signs, x, y, z, face, text); + if (dirty) { + chunk->dirty = 1; + } + } + db_insert_sign(p, q, x, y, z, face, text); } void set_sign(int x, int y, int z, int face, const char *text) { - int p = chunked(x); - int q = chunked(z); - _set_sign(p, q, x, y, z, face, text, 1); - client_sign(x, y, z, face, text); + int p = chunked(x); + int q = chunked(z); + _set_sign(p, q, x, y, z, face, text, 1); + client_sign(x, y, z, face, text); } void toggle_light(int x, int y, int z) { - int p = chunked(x); - int q = chunked(z); - Chunk *chunk = find_chunk(p, q); - if (chunk) { - Map *map = &chunk->lights; - int w = map_get(map, x, y, z) ? 0 : 15; - map_set(map, x, y, z, w); - db_insert_light(p, q, x, y, z, w); - client_light(x, y, z, w); - dirty_chunk(chunk); - } + int p = chunked(x); + int q = chunked(z); + Chunk *chunk = find_chunk(p, q); + if (chunk) { + Map *map = &chunk->lights; + int w = map_get(map, x, y, z) ? 0 : 15; + map_set(map, x, y, z, w); + db_insert_light(p, q, x, y, z, w); + client_light(x, y, z, w); + dirty_chunk(chunk); + } } void set_light(int p, int q, int x, int y, int z, int w) { - Chunk *chunk = find_chunk(p, q); - if (chunk) { - Map *map = &chunk->lights; - if (map_set(map, x, y, z, w)) { - dirty_chunk(chunk); - db_insert_light(p, q, x, y, z, w); - } - } - else { - db_insert_light(p, q, x, y, z, w); - } + Chunk *chunk = find_chunk(p, q); + if (chunk) { + Map *map = &chunk->lights; + if (map_set(map, x, y, z, w)) { + dirty_chunk(chunk); + db_insert_light(p, q, x, y, z, w); + } + } + else { + db_insert_light(p, q, x, y, z, w); + } } void _set_block(int p, int q, int x, int y, int z, int w, int dirty) { - Chunk *chunk = find_chunk(p, q); - if (chunk) { - Map *map = &chunk->map; - if (map_set(map, x, y, z, w)) { - if (dirty) { - dirty_chunk(chunk); - } - db_insert_block(p, q, x, y, z, w); - } - } - else { - db_insert_block(p, q, x, y, z, w); - } - if (w == 0 && chunked(x) == p && chunked(z) == q) { - unset_sign(x, y, z); - set_light(p, q, x, y, z, 0); - } + Chunk *chunk = find_chunk(p, q); + if (chunk) { + Map *map = &chunk->map; + if (map_set(map, x, y, z, w)) { + if (dirty) { + dirty_chunk(chunk); + } + db_insert_block(p, q, x, y, z, w); + } + } + else { + db_insert_block(p, q, x, y, z, w); + } + if (w == 0 && chunked(x) == p && chunked(z) == q) { + unset_sign(x, y, z); + set_light(p, q, x, y, z, 0); + } } void set_block(int x, int y, int z, int w) { - int p = chunked(x); - int q = chunked(z); - _set_block(p, q, x, y, z, w, 1); - for (int dx = -1; dx <= 1; dx++) { - for (int dz = -1; dz <= 1; dz++) { - if (dx == 0 && dz == 0) { - continue; - } - if (dx && chunked(x + dx) == p) { - continue; - } - if (dz && chunked(z + dz) == q) { - continue; - } - _set_block(p + dx, q + dz, x, y, z, -w, 1); - } - } - client_block(x, y, z, w); + int p = chunked(x); + int q = chunked(z); + _set_block(p, q, x, y, z, w, 1); + for (int dx = -1; dx <= 1; dx++) { + for (int dz = -1; dz <= 1; dz++) { + if (dx == 0 && dz == 0) { + continue; + } + if (dx && chunked(x + dx) == p) { + continue; + } + if (dz && chunked(z + dz) == q) { + continue; + } + _set_block(p + dx, q + dz, x, y, z, -w, 1); + } + } + client_block(x, y, z, w); } void record_block(int x, int y, int z, int w) { - memcpy(&g->block1, &g->block0, sizeof(Block)); - g->block0.x = x; - g->block0.y = y; - g->block0.z = z; - g->block0.w = w; + memcpy(&g->block1, &g->block0, sizeof(Block)); + g->block0.x = x; + g->block0.y = y; + g->block0.z = z; + g->block0.w = w; } // Get_block was here int get_block(int x, int y, int z) { - int p = chunked(x); - int q = chunked(z); - Chunk *chunk = find_chunk(p, q); - if (chunk) { - Map *map = &chunk->map; - return map_get(map, x, y, z); - } - return 0; + int p = chunked(x); + int q = chunked(z); + Chunk *chunk = find_chunk(p, q); + if (chunk) { + Map *map = &chunk->map; + return map_get(map, x, y, z); + } + return 0; } void builder_block(int x, int y, int z, int w) { - if (y <= 0 || y >= BUILD_HEIGHT_LIMIT) { - return; - } - if (is_destructable(get_block(x, y, z))) { - set_block(x, y, z, 0); - } - if (w) { - set_block(x, y, z, w); - } + if (y <= 0 || y >= BUILD_HEIGHT_LIMIT) { + return; + } + if (is_destructable(get_block(x, y, z))) { + set_block(x, y, z, 0); + } + if (w) { + set_block(x, y, z, w); + } } int render_chunks(Attrib *attrib, Player *player) { - int result = 0; - State *s = &player->state; - ensure_chunks(player); - int p = chunked(s->x); - int q = chunked(s->z); - float light = get_daylight(); - float matrix[16]; - set_matrix_3d( - matrix, g->width, g->height, - s->x, s->y, s->z, s->rx, s->ry, g->fov, g->ortho, g->render_radius); - float planes[6][4]; - frustum_planes(planes, g->render_radius, matrix); - glUseProgram(attrib->program); - glUniformMatrix4fv(attrib->matrix, 1, GL_FALSE, matrix); - glUniform3f(attrib->camera, s->x, s->y, s->z); - glUniform1i(attrib->sampler, 0); - glUniform1i(attrib->extra1, 2); - glUniform1f(attrib->extra2, light); - glUniform1f(attrib->extra3, g->render_radius * CHUNK_SIZE); - glUniform1i(attrib->extra4, g->ortho); - glUniform1f(attrib->timer, time_of_day()); + int result = 0; + State *s = &player->state; + ensure_chunks(player); + int p = chunked(s->x); + int q = chunked(s->z); + float light = get_daylight(); + float matrix[16]; + set_matrix_3d( + matrix, g->width, g->height, + s->x, s->y, s->z, s->rx, s->ry, g->fov, g->ortho, g->render_radius); + float planes[6][4]; + frustum_planes(planes, g->render_radius, matrix); + glUseProgram(attrib->program); + glUniformMatrix4fv(attrib->matrix, 1, GL_FALSE, matrix); + glUniform3f(attrib->camera, s->x, s->y, s->z); + glUniform1i(attrib->sampler, 0); + glUniform1i(attrib->extra1, 2); + glUniform1f(attrib->extra2, light); + glUniform1f(attrib->extra3, g->render_radius * CHUNK_SIZE); + glUniform1i(attrib->extra4, g->ortho); + glUniform1f(attrib->timer, time_of_day()); - SkyColor *c = &g->sky_color; - glUniform3f(attrib->extra5, c->r, c->g, c->b); + SkyColor *c = &g->sky_color; + glUniform3f(attrib->extra5, c->r, c->g, c->b); - for (int i = 0; i < g->chunk_count; i++) { - Chunk *chunk = g->chunks + i; - if (chunk_distance(chunk, p, q) > g->render_radius) { - continue; - } - if (!chunk_visible( - planes, chunk->p, chunk->q, chunk->miny, chunk->maxy)) - { - continue; - } - draw_chunk(attrib, chunk); - result += chunk->faces; - } - return result; + for (int i = 0; i < g->chunk_count; i++) { + Chunk *chunk = g->chunks + i; + if (chunk_distance(chunk, p, q) > g->render_radius) { + continue; + } + if (!chunk_visible( + planes, chunk->p, chunk->q, chunk->miny, chunk->maxy)) + { + continue; + } + draw_chunk(attrib, chunk); + result += chunk->faces; + } + return result; } void render_signs(Attrib *attrib, Player *player) { - State *s = &player->state; - int p = chunked(s->x); - int q = chunked(s->z); - float matrix[16]; - set_matrix_3d( - matrix, g->width, g->height, - s->x, s->y, s->z, s->rx, s->ry, g->fov, g->ortho, g->render_radius); - float planes[6][4]; - frustum_planes(planes, g->render_radius, matrix); - glUseProgram(attrib->program); - glUniformMatrix4fv(attrib->matrix, 1, GL_FALSE, matrix); - glUniform1i(attrib->sampler, 3); - glUniform1i(attrib->extra1, 1); - for (int i = 0; i < g->chunk_count; i++) { - Chunk *chunk = g->chunks + i; - if (chunk_distance(chunk, p, q) > g->sign_radius) { - continue; - } - if (!chunk_visible( - planes, chunk->p, chunk->q, chunk->miny, chunk->maxy)) - { - continue; - } - draw_signs(attrib, chunk); - } + State *s = &player->state; + int p = chunked(s->x); + int q = chunked(s->z); + float matrix[16]; + set_matrix_3d( + matrix, g->width, g->height, + s->x, s->y, s->z, s->rx, s->ry, g->fov, g->ortho, g->render_radius); + float planes[6][4]; + frustum_planes(planes, g->render_radius, matrix); + glUseProgram(attrib->program); + glUniformMatrix4fv(attrib->matrix, 1, GL_FALSE, matrix); + glUniform1i(attrib->sampler, 3); + glUniform1i(attrib->extra1, 1); + for (int i = 0; i < g->chunk_count; i++) { + Chunk *chunk = g->chunks + i; + if (chunk_distance(chunk, p, q) > g->sign_radius) { + continue; + } + if (!chunk_visible( + planes, chunk->p, chunk->q, chunk->miny, chunk->maxy)) + { + continue; + } + draw_signs(attrib, chunk); + } } void render_sign(Attrib *attrib, Player *player) { - if (!g->typing || g->typing_buffer[0] != CRAFT_KEY_SIGN) { - return; - } - int x, y, z, face; - if (!hit_test_face(player, &x, &y, &z, &face)) { - return; - } - State *s = &player->state; - float matrix[16]; - set_matrix_3d( - matrix, g->width, g->height, - s->x, s->y, s->z, s->rx, s->ry, g->fov, g->ortho, g->render_radius); - glUseProgram(attrib->program); - glUniformMatrix4fv(attrib->matrix, 1, GL_FALSE, matrix); - glUniform1i(attrib->sampler, 3); - glUniform1i(attrib->extra1, 1); - char text[MAX_SIGN_LENGTH]; - strncpy(text, g->typing_buffer + 1, MAX_SIGN_LENGTH); - text[MAX_SIGN_LENGTH - 1] = '\0'; - GLfloat *data = malloc_faces(5, strlen(text)); - int length = _gen_sign_buffer(data, x, y, z, face, text); - GLuint buffer = gen_faces(5, length, data); - draw_sign(attrib, buffer, length); - del_buffer(buffer); + if (!g->typing || g->typing_buffer[0] != CRAFT_KEY_SIGN) { + return; + } + int x, y, z, face; + if (!hit_test_face(player, &x, &y, &z, &face)) { + return; + } + State *s = &player->state; + float matrix[16]; + set_matrix_3d( + matrix, g->width, g->height, + s->x, s->y, s->z, s->rx, s->ry, g->fov, g->ortho, g->render_radius); + glUseProgram(attrib->program); + glUniformMatrix4fv(attrib->matrix, 1, GL_FALSE, matrix); + glUniform1i(attrib->sampler, 3); + glUniform1i(attrib->extra1, 1); + char text[MAX_SIGN_LENGTH]; + strncpy(text, g->typing_buffer + 1, MAX_SIGN_LENGTH); + text[MAX_SIGN_LENGTH - 1] = '\0'; + GLfloat *data = malloc_faces(5, strlen(text)); + int length = _gen_sign_buffer(data, x, y, z, face, text); + GLuint buffer = gen_faces(5, length, data); + draw_sign(attrib, buffer, length); + del_buffer(buffer); } void render_players(Attrib *attrib, Player *player) { - State *s = &player->state; - float matrix[16]; - set_matrix_3d( - matrix, g->width, g->height, - s->x, s->y, s->z, s->rx, s->ry, g->fov, g->ortho, g->render_radius); - glUseProgram(attrib->program); - glUniformMatrix4fv(attrib->matrix, 1, GL_FALSE, matrix); - glUniform3f(attrib->camera, s->x, s->y, s->z); - glUniform1i(attrib->sampler, 0); - glUniform1f(attrib->timer, time_of_day()); - for (int i = 0; i < g->player_count; i++) { - Player *other = g->players + i; - if (other != player) { - draw_player(attrib, other); - } - } + State *s = &player->state; + float matrix[16]; + set_matrix_3d( + matrix, g->width, g->height, + s->x, s->y, s->z, s->rx, s->ry, g->fov, g->ortho, g->render_radius); + glUseProgram(attrib->program); + glUniformMatrix4fv(attrib->matrix, 1, GL_FALSE, matrix); + glUniform3f(attrib->camera, s->x, s->y, s->z); + glUniform1i(attrib->sampler, 0); + glUniform1f(attrib->timer, time_of_day()); + for (int i = 0; i < g->player_count; i++) { + Player *other = g->players + i; + if (other != player) { + draw_player(attrib, other); + } + } } void render_sky(Attrib *attrib, Player *player, GLuint buffer) { - State *s = &player->state; - float matrix[16]; - set_matrix_3d( - matrix, g->width, g->height, - 0, 0, 0, s->rx, s->ry, g->fov, 0, g->render_radius); - glUseProgram(attrib->program); - glUniformMatrix4fv(attrib->matrix, 1, GL_FALSE, matrix); - glUniform1i(attrib->sampler, 2); - glUniform1f(attrib->timer, time_of_day()); - glUniform3f(attrib->extra1, 1.0f, 1.0f, 1.0f); + State *s = &player->state; + float matrix[16]; + set_matrix_3d( + matrix, g->width, g->height, + 0, 0, 0, s->rx, s->ry, g->fov, 0, g->render_radius); + glUseProgram(attrib->program); + glUniformMatrix4fv(attrib->matrix, 1, GL_FALSE, matrix); + glUniform1i(attrib->sampler, 2); + glUniform1f(attrib->timer, time_of_day()); + glUniform3f(attrib->extra1, 1.0f, 1.0f, 1.0f); - SkyColor *c = &g->sky_color; - glUniform3f(attrib->extra1, c->r, c->g, c->b); + SkyColor *c = &g->sky_color; + glUniform3f(attrib->extra1, c->r, c->g, c->b); - draw_triangles_3d(attrib, buffer, 512 * 3); + draw_triangles_3d(attrib, buffer, 512 * 3); } void render_item(Attrib *attrib) { - float matrix[16]; - glUseProgram(attrib->program); - set_matrix_item(matrix, g->width, g->height, g->scale + 1); - glUniform3f(attrib->camera, 0, 0, 5); - glUniform1i(attrib->sampler, 0); - glUniform1f(attrib->timer, time_of_day()); - for(int i = 0; i < NUM_INVENTORY_VISIBLE; ++i) { - if(g->item_index + i >= item_count) { - break; - } + float matrix[16]; + glUseProgram(attrib->program); + set_matrix_item(matrix, g->width, g->height, g->scale + 1); + glUniform3f(attrib->camera, 0, 0, 5); + glUniform1i(attrib->sampler, 0); + glUniform1f(attrib->timer, time_of_day()); + for(int i = 0; i < NUM_INVENTORY_VISIBLE; ++i) { + if(g->item_index + i >= item_count) { + break; + } - glUniformMatrix4fv(attrib->matrix, 1, GL_FALSE, matrix); + glUniformMatrix4fv(attrib->matrix, 1, GL_FALSE, matrix); - int w = items[g->item_index + i]; - if (is_plant(w)) { - GLuint buffer = gen_plant_buffer(0, 0, 0, 0.5, w); - draw_plant(attrib, buffer); - del_buffer(buffer); - } - else { - GLuint buffer = gen_cube_buffer(0, 0, 0, 0.5, w); - draw_cube(attrib, buffer); - del_buffer(buffer); - } + int w = items[g->item_index + i]; + + //if (g->inventory.count[items[g->item_index]] == 0) { + // w = 0; + //} + + // TODO: g->inventory.count[items[g->item_index]] = 16; + + if (is_plant(w)) { + GLuint buffer = gen_plant_buffer(0, 0, 0, 0.5, w); + draw_plant(attrib, buffer); + del_buffer(buffer); + } + else { + GLuint buffer = gen_cube_buffer(0, 0, 0, 0.5, w); + draw_cube(attrib, buffer); + del_buffer(buffer); + } - if(!i) { - set_matrix_item(matrix, g->width, g->height, g->scale); - matrix[12] += 0.08f; - matrix[13] += 0.1f; - } + if(!i) { + set_matrix_item(matrix, g->width, g->height, g->scale); + matrix[12] += 0.08f; + matrix[13] += 0.1f; + } - matrix[13] += 0.25f; - } + matrix[13] += 0.25f; + } } void render_item_count(Attrib *attrib, float ts) { - const int buf_len = 4; + const int buf_len = 4; - float pos = 15.0f; - for(int i = 0; i < NUM_INVENTORY_VISIBLE; ++i) { - if(g->item_index + i >= item_count) { - break; - } + float pos = 15.0f; + for(int i = 0; i < NUM_INVENTORY_VISIBLE; ++i) { + if(g->item_index + i >= item_count) { + break; + } - char buf[buf_len]; - snprintf(buf, buf_len, "%d\n", Inventory_getCount(&g->inventory, items[g->item_index + i])); - //snprintf(buf, buf_len, "%d\n", g->inventory.count[items[g->item_index]]); + char buf[buf_len]; + snprintf(buf, buf_len, "%d\n", Inventory_getCount(&g->inventory, items[g->item_index + i])); + //snprintf(buf, buf_len, "%d\n", g->inventory.count[items[g->item_index]]); - render_text(attrib, ALIGN_CENTER, g->width - 20.0f, pos, ts, buf, g->width, g->height); - //printf("%d\n", g->width); + render_text(attrib, ALIGN_CENTER, g->width - 20.0f, pos, ts, buf, g->width, g->height); + //printf("%d\n", g->width); - float ratio_to_hardcoded = (g->height / 768.0f); - if(i) { - pos += 96.0f * ratio_to_hardcoded; - } else { - pos += 140.0f * ratio_to_hardcoded; - } - } + float ratio_to_hardcoded = (g->height / 768.0f); + if(i) { + pos += 96.0f * ratio_to_hardcoded; + } else { + pos += 140.0f * ratio_to_hardcoded; + } + } } void render_ui_texture(Attrib *attrib) { - float matrix[16]; - glUseProgram(attrib->program); - set_matrix_item(matrix, g->width, g->height, g->scale + 1); - glUniform3f(attrib->camera, 0, 0, 5); - glUniform1i(attrib->sampler, 0); - glUniform1f(attrib->timer, time_of_day()); - for(int i = 0; i < NUM_INVENTORY_VISIBLE; ++i) { - if(g->item_index + i >= item_count) { - break; - } + float matrix[16]; + glUseProgram(attrib->program); + set_matrix_item(matrix, g->width, g->height, g->scale + 1); + glUniform3f(attrib->camera, 0, 0, 5); + glUniform1i(attrib->sampler, 0); + glUniform1f(attrib->timer, time_of_day()); + for(int i = 0; i < NUM_INVENTORY_VISIBLE; ++i) { + if(g->item_index + i >= item_count) { + break; + } - glUniformMatrix4fv(attrib->matrix, 1, GL_FALSE, matrix); + glUniformMatrix4fv(attrib->matrix, 1, GL_FALSE, matrix); - int w = items[g->item_index + i]; - if (is_plant(w)) { - GLuint buffer = gen_plant_buffer(0, 0, 0, 0.5, w); - draw_plant(attrib, buffer); - del_buffer(buffer); - } - else { - GLuint buffer = gen_cube_buffer(0, 0, 0, 0.5, w); - draw_cube(attrib, buffer); - del_buffer(buffer); - } + int w = items[g->item_index + i]; + if (is_plant(w)) { + GLuint buffer = gen_plant_buffer(0, 0, 0, 0.5, w); + draw_plant(attrib, buffer); + del_buffer(buffer); + } + else { + GLuint buffer = gen_cube_buffer(0, 0, 0, 0.5, w); + draw_cube(attrib, buffer); + del_buffer(buffer); + } - if(!i) { - set_matrix_item(matrix, g->width, g->height, g->scale); - matrix[12] += 0.08f; - matrix[13] += 0.1f; - } + if(!i) { + set_matrix_item(matrix, g->width, g->height, g->scale); + matrix[12] += 0.08f; + matrix[13] += 0.1f; + } - matrix[13] += 0.25f; - } + matrix[13] += 0.25f; + } } void add_message(const char *text) { - //printf("%s\n", text); - snprintf( - g->messages[g->message_index], MAX_TEXT_LENGTH, "%s", text); - g->message_index = (g->message_index + 1) % MAX_MESSAGES; + //printf("%s\n", text); + snprintf( + g->messages[g->message_index], MAX_TEXT_LENGTH, "%s", text); + g->message_index = (g->message_index + 1) % MAX_MESSAGES; } void login() { - char username[128] = {0}; - char identity_token[128] = {0}; - char access_token[128] = {0}; - if (db_auth_get_selected(username, 128, identity_token, 128)) { - printf("Contacting login server for username: %s\n", username); - if (get_access_token( - access_token, 128, username, identity_token)) - { - printf("Successfully authenticated with the login server\n"); - client_login(username, access_token); - } - else { - printf("Failed to authenticate with the login server\n"); - client_login("", ""); - } - } - else { - printf("Logging in anonymously\n"); - client_login("", ""); - } + char username[128] = {0}; + char identity_token[128] = {0}; + char access_token[128] = {0}; + if (db_auth_get_selected(username, 128, identity_token, 128)) { + printf("Contacting login server for username: %s\n", username); + if (get_access_token( + access_token, 128, username, identity_token)) + { + printf("Successfully authenticated with the login server\n"); + client_login(username, access_token); + } + else { + printf("Failed to authenticate with the login server\n"); + client_login("", ""); + } + } + else { + printf("Logging in anonymously\n"); + client_login("", ""); + } } void copy() { - memcpy(&g->copy0, &g->block0, sizeof(Block)); - memcpy(&g->copy1, &g->block1, sizeof(Block)); + memcpy(&g->copy0, &g->block0, sizeof(Block)); + memcpy(&g->copy1, &g->block1, sizeof(Block)); } void paste() { - Block *c1 = &g->copy1; - Block *c2 = &g->copy0; - Block *p1 = &g->block1; - Block *p2 = &g->block0; - int scx = SIGN(c2->x - c1->x); - int scz = SIGN(c2->z - c1->z); - int spx = SIGN(p2->x - p1->x); - int spz = SIGN(p2->z - p1->z); - int oy = p1->y - c1->y; - int dx = ABS(c2->x - c1->x); - int dz = ABS(c2->z - c1->z); - for (int y = 0; y < 256; y++) { - for (int x = 0; x <= dx; x++) { - for (int z = 0; z <= dz; z++) { - int w = get_block(c1->x + x * scx, y, c1->z + z * scz); - builder_block(p1->x + x * spx, y + oy, p1->z + z * spz, w); - } - } - } + Block *c1 = &g->copy1; + Block *c2 = &g->copy0; + Block *p1 = &g->block1; + Block *p2 = &g->block0; + int scx = SIGN(c2->x - c1->x); + int scz = SIGN(c2->z - c1->z); + int spx = SIGN(p2->x - p1->x); + int spz = SIGN(p2->z - p1->z); + int oy = p1->y - c1->y; + int dx = ABS(c2->x - c1->x); + int dz = ABS(c2->z - c1->z); + for (int y = 0; y < 256; y++) { + for (int x = 0; x <= dx; x++) { + for (int z = 0; z <= dz; z++) { + int w = get_block(c1->x + x * scx, y, c1->z + z * scz); + builder_block(p1->x + x * spx, y + oy, p1->z + z * spz, w); + } + } + } } void array(Block *b1, Block *b2, int xc, int yc, int zc) { - if (b1->w != b2->w) { - return; - } - int w = b1->w; - int dx = b2->x - b1->x; - int dy = b2->y - b1->y; - int dz = b2->z - b1->z; - xc = dx ? xc : 1; - yc = dy ? yc : 1; - zc = dz ? zc : 1; - for (int i = 0; i < xc; i++) { - int x = b1->x + dx * i; - for (int j = 0; j < yc; j++) { - int y = b1->y + dy * j; - for (int k = 0; k < zc; k++) { - int z = b1->z + dz * k; - builder_block(x, y, z, w); - } - } - } + if (b1->w != b2->w) { + return; + } + int w = b1->w; + int dx = b2->x - b1->x; + int dy = b2->y - b1->y; + int dz = b2->z - b1->z; + xc = dx ? xc : 1; + yc = dy ? yc : 1; + zc = dz ? zc : 1; + for (int i = 0; i < xc; i++) { + int x = b1->x + dx * i; + for (int j = 0; j < yc; j++) { + int y = b1->y + dy * j; + for (int k = 0; k < zc; k++) { + int z = b1->z + dz * k; + builder_block(x, y, z, w); + } + } + } } void cube(Block *b1, Block *b2, int fill) { - if (b1->w != b2->w) { - return; - } - int w = b1->w; - int x1 = MIN(b1->x, b2->x); - int y1 = MIN(b1->y, b2->y); - int z1 = MIN(b1->z, b2->z); - int x2 = MAX(b1->x, b2->x); - int y2 = MAX(b1->y, b2->y); - int z2 = MAX(b1->z, b2->z); - int a = (x1 == x2) + (y1 == y2) + (z1 == z2); - for (int x = x1; x <= x2; x++) { - for (int y = y1; y <= y2; y++) { - for (int z = z1; z <= z2; z++) { - if (!fill) { - int n = 0; - n += x == x1 || x == x2; - n += y == y1 || y == y2; - n += z == z1 || z == z2; - if (n <= a) { - continue; - } - } - builder_block(x, y, z, w); - } - } - } + if (b1->w != b2->w) { + return; + } + int w = b1->w; + int x1 = MIN(b1->x, b2->x); + int y1 = MIN(b1->y, b2->y); + int z1 = MIN(b1->z, b2->z); + int x2 = MAX(b1->x, b2->x); + int y2 = MAX(b1->y, b2->y); + int z2 = MAX(b1->z, b2->z); + int a = (x1 == x2) + (y1 == y2) + (z1 == z2); + for (int x = x1; x <= x2; x++) { + for (int y = y1; y <= y2; y++) { + for (int z = z1; z <= z2; z++) { + if (!fill) { + int n = 0; + n += x == x1 || x == x2; + n += y == y1 || y == y2; + n += z == z1 || z == z2; + if (n <= a) { + continue; + } + } + builder_block(x, y, z, w); + } + } + } } void sphere(Block *center, int radius, int fill, int fx, int fy, int fz) { - static const float offsets[8][3] = { - {-0.5, -0.5, -0.5}, - {-0.5, -0.5, 0.5}, - {-0.5, 0.5, -0.5}, - {-0.5, 0.5, 0.5}, - {0.5, -0.5, -0.5}, - {0.5, -0.5, 0.5}, - {0.5, 0.5, -0.5}, - {0.5, 0.5, 0.5} - }; - int cx = center->x; - int cy = center->y; - int cz = center->z; - int w = center->w; - for (int x = cx - radius; x <= cx + radius; x++) { - if (fx && x != cx) { - continue; - } - for (int y = cy - radius; y <= cy + radius; y++) { - if (fy && y != cy) { - continue; - } - for (int z = cz - radius; z <= cz + radius; z++) { - if (fz && z != cz) { - continue; - } - int inside = 0; - int outside = fill; - for (int i = 0; i < 8; i++) { - float dx = x + offsets[i][0] - cx; - float dy = y + offsets[i][1] - cy; - float dz = z + offsets[i][2] - cz; - float d = sqrtf(dx * dx + dy * dy + dz * dz); - if (d < radius) { - inside = 1; - } - else { - outside = 1; - } - } - if (inside && outside) { - builder_block(x, y, z, w); - } - } - } - } + static const float offsets[8][3] = { + {-0.5, -0.5, -0.5}, + {-0.5, -0.5, 0.5}, + {-0.5, 0.5, -0.5}, + {-0.5, 0.5, 0.5}, + {0.5, -0.5, -0.5}, + {0.5, -0.5, 0.5}, + {0.5, 0.5, -0.5}, + {0.5, 0.5, 0.5} + }; + int cx = center->x; + int cy = center->y; + int cz = center->z; + int w = center->w; + for (int x = cx - radius; x <= cx + radius; x++) { + if (fx && x != cx) { + continue; + } + for (int y = cy - radius; y <= cy + radius; y++) { + if (fy && y != cy) { + continue; + } + for (int z = cz - radius; z <= cz + radius; z++) { + if (fz && z != cz) { + continue; + } + int inside = 0; + int outside = fill; + for (int i = 0; i < 8; i++) { + float dx = x + offsets[i][0] - cx; + float dy = y + offsets[i][1] - cy; + float dz = z + offsets[i][2] - cz; + float d = sqrtf(dx * dx + dy * dy + dz * dz); + if (d < radius) { + inside = 1; + } + else { + outside = 1; + } + } + if (inside && outside) { + builder_block(x, y, z, w); + } + } + } + } } void cylinder(Block *b1, Block *b2, int radius, int fill) { - if (b1->w != b2->w) { - return; - } - int w = b1->w; - int x1 = MIN(b1->x, b2->x); - int y1 = MIN(b1->y, b2->y); - int z1 = MIN(b1->z, b2->z); - int x2 = MAX(b1->x, b2->x); - int y2 = MAX(b1->y, b2->y); - int z2 = MAX(b1->z, b2->z); - int fx = x1 != x2; - int fy = y1 != y2; - int fz = z1 != z2; - if (fx + fy + fz != 1) { - return; - } - Block block = {x1, y1, z1, w}; - if (fx) { - for (int x = x1; x <= x2; x++) { - block.x = x; - sphere(&block, radius, fill, 1, 0, 0); - } - } - if (fy) { - for (int y = y1; y <= y2; y++) { - block.y = y; - sphere(&block, radius, fill, 0, 1, 0); - } - } - if (fz) { - for (int z = z1; z <= z2; z++) { - block.z = z; - sphere(&block, radius, fill, 0, 0, 1); - } - } + if (b1->w != b2->w) { + return; + } + int w = b1->w; + int x1 = MIN(b1->x, b2->x); + int y1 = MIN(b1->y, b2->y); + int z1 = MIN(b1->z, b2->z); + int x2 = MAX(b1->x, b2->x); + int y2 = MAX(b1->y, b2->y); + int z2 = MAX(b1->z, b2->z); + int fx = x1 != x2; + int fy = y1 != y2; + int fz = z1 != z2; + if (fx + fy + fz != 1) { + return; + } + Block block = {x1, y1, z1, w}; + if (fx) { + for (int x = x1; x <= x2; x++) { + block.x = x; + sphere(&block, radius, fill, 1, 0, 0); + } + } + if (fy) { + for (int y = y1; y <= y2; y++) { + block.y = y; + sphere(&block, radius, fill, 0, 1, 0); + } + } + if (fz) { + for (int z = z1; z <= z2; z++) { + block.z = z; + sphere(&block, radius, fill, 0, 0, 1); + } + } } void tree(Block *block) { - int bx = block->x; - int by = block->y; - int bz = block->z; - for (int y = by + 3; y < by + 8; y++) { - for (int dx = -3; dx <= 3; dx++) { - for (int dz = -3; dz <= 3; dz++) { - int dy = y - (by + 4); - int d = (dx * dx) + (dy * dy) + (dz * dz); - if (d < 11) { - builder_block(bx + dx, y, bz + dz, 15); - } - } - } - } - for (int y = by; y < by + 7; y++) { - builder_block(bx, y, bz, 5); - } + int bx = block->x; + int by = block->y; + int bz = block->z; + for (int y = by + 3; y < by + 8; y++) { + for (int dx = -3; dx <= 3; dx++) { + for (int dz = -3; dz <= 3; dz++) { + int dy = y - (by + 4); + int d = (dx * dx) + (dy * dy) + (dz * dz); + if (d < 11) { + builder_block(bx + dx, y, bz + dz, 15); + } + } + } + } + for (int y = by; y < by + 7; y++) { + builder_block(bx, y, bz, 5); + } } void time_command(double new_elapsed) { - glfwSetTime(fmod(new_elapsed, g->day_length)); - g->time_changed = 1; + glfwSetTime(fmod(new_elapsed, g->day_length)); + g->time_changed = 1; } void parse_command(const char *buffer, int forward) { - char username[128] = {0}; - char token[128] = {0}; - char server_addr[MAX_ADDR_LENGTH]; - int server_port = DEFAULT_PORT; - char filename[MAX_PATH_LENGTH]; - int radius, page, count, xc, yc, zc; - double time; - int is_allowing_time_change = !get_client_enabled(); - if (sscanf(buffer, "/identity %128s %128s", username, token) == 2) { - db_auth_set(username, token); - add_message("Successfully imported identity token!"); - login(); - } - else if (strcmp(buffer, "/logout") == 0) { - db_auth_select_none(); - login(); - } - else if (sscanf(buffer, "/login %128s", username) == 1) { - if (db_auth_select(username)) { - login(); - } - else { - add_message("Unknown username."); - } - } - else if (sscanf(buffer, - "/online %128s %d", server_addr, &server_port) >= 1) - { - g->mode_changed = 1; - g->mode = MODE_ONLINE; - strncpy(g->server_addr, server_addr, MAX_ADDR_LENGTH); - g->server_port = server_port; - snprintf(g->db_path, MAX_PATH_LENGTH, - "cache.%s.%d.db", g->server_addr, g->server_port); - } - else if (sscanf(buffer, "/offline %128s", filename) == 1) { - g->mode_changed = 1; - g->mode = MODE_OFFLINE; - snprintf(g->db_path, MAX_PATH_LENGTH, "%s.db", filename); - } - else if (strcmp(buffer, "/offline") == 0) { - g->mode_changed = 1; - g->mode = MODE_OFFLINE; - snprintf(g->db_path, MAX_PATH_LENGTH, "%s", DB_PATH); - } - else if (sscanf(buffer, "/view %d", &radius) == 1) { - if (radius >= 1 && radius <= 24) { - g->create_radius = radius; - g->render_radius = radius; - g->delete_radius = radius + 4; - } - else { - add_message("Viewing distance must be between 1 and 24."); - } - } - else if (strcmp(buffer, "/help") == 0) { + char username[128] = {0}; + char token[128] = {0}; + char server_addr[MAX_ADDR_LENGTH]; + int server_port = DEFAULT_PORT; + char filename[MAX_PATH_LENGTH]; + int radius, page, count, xc, yc, zc; + double time; + int is_allowing_time_change = !get_client_enabled(); + if (sscanf(buffer, "/identity %128s %128s", username, token) == 2) { + db_auth_set(username, token); + add_message("Successfully imported identity token!"); + login(); + } + else if (strcmp(buffer, "/logout") == 0) { + db_auth_select_none(); + login(); + } + else if (sscanf(buffer, "/login %128s", username) == 1) { + if (db_auth_select(username)) { + login(); + } + else { + add_message("Unknown username."); + } + } + else if (sscanf(buffer, + "/online %128s %d", server_addr, &server_port) >= 1) + { + g->mode_changed = 1; + g->mode = MODE_ONLINE; + strncpy(g->server_addr, server_addr, MAX_ADDR_LENGTH); + g->server_port = server_port; + snprintf(g->db_path, MAX_PATH_LENGTH, + "cache.%s.%d.db", g->server_addr, g->server_port); + } + else if (sscanf(buffer, "/offline %128s", filename) == 1) { + g->mode_changed = 1; + g->mode = MODE_OFFLINE; + snprintf(g->db_path, MAX_PATH_LENGTH, "%s.db", filename); + } + else if (strcmp(buffer, "/offline") == 0) { + g->mode_changed = 1; + g->mode = MODE_OFFLINE; + snprintf(g->db_path, MAX_PATH_LENGTH, "%s", DB_PATH); + } + else if (sscanf(buffer, "/view %d", &radius) == 1) { + if (radius >= 1 && radius <= 24) { + g->create_radius = radius; + g->render_radius = radius; + g->delete_radius = radius + 4; + } + else { + add_message("Viewing distance must be between 1 and 24."); + } + } + else if (strcmp(buffer, "/help") == 0) { add_message("Use /help to see the list of commands."); } @@ -2155,8 +2186,8 @@ void parse_command(const char *buffer, int forward) { "/(f)circlex & /(f)circley <~> & /(f)circlez <~>\n", "/(f)cylinder \n", "/day & /night & /time \n"}; - - for(int i = 0+MAX_MESSAGES*page; i < MAX_MESSAGES+MAX_MESSAGES*page; i++) { + + for(int i = 0+MAX_MESSAGES*page; i < MAX_MESSAGES+MAX_MESSAGES*page; i++) { const char *output = content[i]; if (output) { add_message(output); @@ -2164,87 +2195,87 @@ void parse_command(const char *buffer, int forward) { add_message(""); } } - } - else if (strcmp(buffer, "/copy") == 0) { - copy(); - } - else if (strcmp(buffer, "/paste") == 0) { - paste(); - } - else if (strcmp(buffer, "/tree") == 0) { - tree(&g->block0); - } - else if (sscanf(buffer, "/array %d %d %d", &xc, &yc, &zc) == 3) { - array(&g->block1, &g->block0, xc, yc, zc); - } - else if (sscanf(buffer, "/array %d", &count) == 1) { - array(&g->block1, &g->block0, count, count, count); - } - else if (strcmp(buffer, "/fcube") == 0) { - cube(&g->block0, &g->block1, 1); - } - else if (strcmp(buffer, "/cube") == 0) { - cube(&g->block0, &g->block1, 0); - } - else if (sscanf(buffer, "/fsphere %d", &radius) == 1) { - sphere(&g->block0, radius, 1, 0, 0, 0); - } - else if (sscanf(buffer, "/sphere %d", &radius) == 1) { - sphere(&g->block0, radius, 0, 0, 0, 0); - } - else if (sscanf(buffer, "/fcirclex %d", &radius) == 1) { - sphere(&g->block0, radius, 1, 1, 0, 0); - } - else if (sscanf(buffer, "/circlex %d", &radius) == 1) { - sphere(&g->block0, radius, 0, 1, 0, 0); - } - else if (sscanf(buffer, "/fcircley %d", &radius) == 1) { - sphere(&g->block0, radius, 1, 0, 1, 0); - } - else if (sscanf(buffer, "/circley %d", &radius) == 1) { - sphere(&g->block0, radius, 0, 0, 1, 0); - } - else if (sscanf(buffer, "/fcirclez %d", &radius) == 1) { - sphere(&g->block0, radius, 1, 0, 0, 1); - } - else if (sscanf(buffer, "/circlez %d", &radius) == 1) { - sphere(&g->block0, radius, 0, 0, 0, 1); - } - else if (sscanf(buffer, "/fcylinder %d", &radius) == 1) { - cylinder(&g->block0, &g->block1, radius, 1); - } - else if (sscanf(buffer, "/cylinder %d", &radius) == 1) { - cylinder(&g->block0, &g->block1, radius, 0); - } - else if (is_allowing_time_change && strcmp(buffer, "/day") == 0) { - time_command(DAY_LENGTH / 2.0); - } - else if (is_allowing_time_change && strcmp(buffer, "/night") == 0) { - time_command(0.0); - } - else if (is_allowing_time_change && sscanf(buffer, "/time %lf", &time) == 1) { - time_command(time); - } - else if (forward) { - client_talk(buffer); - } + } + else if (strcmp(buffer, "/copy") == 0) { + copy(); + } + else if (strcmp(buffer, "/paste") == 0) { + paste(); + } + else if (strcmp(buffer, "/tree") == 0) { + tree(&g->block0); + } + else if (sscanf(buffer, "/array %d %d %d", &xc, &yc, &zc) == 3) { + array(&g->block1, &g->block0, xc, yc, zc); + } + else if (sscanf(buffer, "/array %d", &count) == 1) { + array(&g->block1, &g->block0, count, count, count); + } + else if (strcmp(buffer, "/fcube") == 0) { + cube(&g->block0, &g->block1, 1); + } + else if (strcmp(buffer, "/cube") == 0) { + cube(&g->block0, &g->block1, 0); + } + else if (sscanf(buffer, "/fsphere %d", &radius) == 1) { + sphere(&g->block0, radius, 1, 0, 0, 0); + } + else if (sscanf(buffer, "/sphere %d", &radius) == 1) { + sphere(&g->block0, radius, 0, 0, 0, 0); + } + else if (sscanf(buffer, "/fcirclex %d", &radius) == 1) { + sphere(&g->block0, radius, 1, 1, 0, 0); + } + else if (sscanf(buffer, "/circlex %d", &radius) == 1) { + sphere(&g->block0, radius, 0, 1, 0, 0); + } + else if (sscanf(buffer, "/fcircley %d", &radius) == 1) { + sphere(&g->block0, radius, 1, 0, 1, 0); + } + else if (sscanf(buffer, "/circley %d", &radius) == 1) { + sphere(&g->block0, radius, 0, 0, 1, 0); + } + else if (sscanf(buffer, "/fcirclez %d", &radius) == 1) { + sphere(&g->block0, radius, 1, 0, 0, 1); + } + else if (sscanf(buffer, "/circlez %d", &radius) == 1) { + sphere(&g->block0, radius, 0, 0, 0, 1); + } + else if (sscanf(buffer, "/fcylinder %d", &radius) == 1) { + cylinder(&g->block0, &g->block1, radius, 1); + } + else if (sscanf(buffer, "/cylinder %d", &radius) == 1) { + cylinder(&g->block0, &g->block1, radius, 0); + } + else if (is_allowing_time_change && strcmp(buffer, "/day") == 0) { + time_command(DAY_LENGTH / 2.0); + } + else if (is_allowing_time_change && strcmp(buffer, "/night") == 0) { + time_command(0.0); + } + else if (is_allowing_time_change && sscanf(buffer, "/time %lf", &time) == 1) { + time_command(time); + } + else if (forward) { + client_talk(buffer); + } } void on_light() { - State *s = &g->players->state; - int hx, hy, hz; - int hw = hit_test(0, s->x, s->y, s->z, s->rx, s->ry, &hx, &hy, &hz); - if (hy > 0 && hy < BUILD_HEIGHT_LIMIT && is_destructable(hw)) { - toggle_light(hx, hy, hz); - compute_chunk; - } + State *s = &g->players->state; + int hx, hy, hz; + int hw = hit_test(0, s->x, s->y, s->z, s->rx, s->ry, &hx, &hy, &hz); + if (hy > 0 && hy < BUILD_HEIGHT_LIMIT && is_destructable(hw)) { + toggle_light(hx, hy, hz); + compute_chunk; + } } void on_left_click() { - State *s = &g->players->state; - int hx, hy, hz; - int hw = hit_test(0, s->x, s->y, s->z, s->rx, s->ry, &hx, &hy, &hz); - int mining = 1; + State *s = &g->players->state; + int hx, hy, hz; + int hw = hit_test(0, s->x, s->y, s->z, s->rx, s->ry, &hx, &hy, &hz); + int mining = 1; //while (mining = 1) { if (hy > 0 && hy < BUILD_HEIGHT_LIMIT && is_destructable(hw) && Inventory_collect(&g->inventory, hw)) { set_block(hx, hy, hz, 0); @@ -2257,556 +2288,572 @@ void on_left_click() { } void on_right_click() { - State *s = &g->players->state; - int hx, hy, hz; - int hw = hit_test(1, s->x, s->y, s->z, s->rx, s->ry, &hx, &hy, &hz); - - int nx, ny, nz; + State *s = &g->players->state; + int hx, hy, hz; + int hw = hit_test(1, s->x, s->y, s->z, s->rx, s->ry, &hx, &hy, &hz); + + int nx, ny, nz; int hwb = hit_test(0, s->x, s->y, s->z, s->rx, s->ry, &nx, &ny, &nz); - - /* if (ny > 0 && ny < BUILD_HEIGHT_LIMIT && !boom_on_click(hwb) && Inventory_use(&g->inventory, items[g->item_index])) { - sphere((get_block(hx, hy, hz)), 10, Item_EMPTY, nx, ny, nz); - } else*/ if (hy > 0 && hy < BUILD_HEIGHT_LIMIT && is_obstacle(hw) && Inventory_use(&g->inventory, items[g->item_index])) { - if (!player_intersects_block(2, s->x, s->y, s->z, hx, hy, hz)) { - set_block(hx, hy, hz, items[g->item_index]); - record_block(hx, hy, hz, items[g->item_index]); - } - } else if (ny > 0 && ny < BUILD_HEIGHT_LIMIT && !buildable_to(hwb) && Inventory_use(&g->inventory, items[g->item_index])) { - if (!player_intersects_block(2, s->x, s->y, s->z, hx, hy, hz)) { - set_block(nx, ny, nz, items[g->item_index]); + + //if (ny > 0 && ny < BUILD_HEIGHT_LIMIT && !boom_on_click(hwb) && Inventory_use(&g->inventory, items[g->item_index])) { + // sphere((get_block(hx, hy, hz)), 10, Item_EMPTY, nx, ny, nz); + //} + if (hy > 0 && hy < BUILD_HEIGHT_LIMIT && is_obstacle(hw) && Inventory_use(&g->inventory, items[g->item_index])) { + if (!player_intersects_block(2, s->x, s->y, s->z, hx, hy, hz)) { + set_block(hx, hy, hz, items[g->item_index]); record_block(hx, hy, hz, items[g->item_index]); } - } + } else if (ny > 0 && ny < BUILD_HEIGHT_LIMIT && !buildable_to(hwb) && Inventory_use(&g->inventory, items[g->item_index])) { + if (!player_intersects_block(2, s->x, s->y, s->z, hx, hy, hz)) { + //int bhw = hit_test(0, s->x, s->y, s->z, s->rx, s->ry, &nx, &ny, &nz); + //if (!is_obstacle(bhw)) { + set_block(nx, ny, nz, items[g->item_index]); + record_block(hx, hy, hz, items[g->item_index]); + //} + } + } } void on_middle_click() { - State *s = &g->players->state; - int hx, hy, hz; - int hw = hit_test(0, s->x, s->y, s->z, s->rx, s->ry, &hx, &hy, &hz); - for (int i = 0; i < item_count; i++) { - if (items[i] == hw) { - g->item_index = i; - break; - } - } + State *s = &g->players->state; + int hx, hy, hz; + int hw = hit_test(0, s->x, s->y, s->z, s->rx, s->ry, &hx, &hy, &hz); + for (int i = 0; i < item_count; i++) { + if (items[i] == hw) { + g->item_index = i; + break; + } + } } void on_key(GLFWwindow *window, int key, int scancode, int action, int mods) { - int control = mods & (GLFW_MOD_CONTROL | GLFW_MOD_SUPER); - int exclusive = - glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED; - if (action == GLFW_RELEASE) { - return; - } - if (key == GLFW_KEY_BACKSPACE) { - if (g->typing) { - int n = strlen(g->typing_buffer); - if (n > 0) { - g->typing_buffer[n - 1] = '\0'; - } - } - } - if (action != GLFW_PRESS) { - return; - } - if (key == GLFW_KEY_ESCAPE) { - if (g->typing) { - g->typing = 0; - } - } - if (key == GLFW_KEY_LEFT_ALT) { - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + int control = mods & (GLFW_MOD_CONTROL | GLFW_MOD_SUPER); + int exclusive = + glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED; + if (action == GLFW_RELEASE) { + return; + } + if (key == GLFW_KEY_BACKSPACE) { + if (g->typing) { + int n = strlen(g->typing_buffer); + if (n > 0) { + g->typing_buffer[n - 1] = '\0'; + } + } + } + if (action != GLFW_PRESS) { + return; + } + if (key == GLFW_KEY_ESCAPE) { + if (g->typing) { + g->typing = 0; + } + } + if (key == GLFW_KEY_LEFT_ALT) { + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + } + if (key == GLFW_KEY_ENTER) { + if (g->typing) { + if (mods & GLFW_MOD_SHIFT) { + int n = strlen(g->typing_buffer); + if (n < MAX_TEXT_LENGTH - 1) { + g->typing_buffer[n] = '\r'; + g->typing_buffer[n + 1] = '\0'; + } + } + else { + g->typing = 0; + if (g->typing_buffer[0] == CRAFT_KEY_SIGN) { + Player *player = g->players; + int x, y, z, face; + if (hit_test_face(player, &x, &y, &z, &face)) { + set_sign(x, y, z, face, g->typing_buffer + 1); + } + } + else if (g->typing_buffer[0] == '/') { + parse_command(g->typing_buffer, 1); + } + else { + client_talk(g->typing_buffer); + } + } + } + else { + if (control) { + on_right_click(); + } + else { + on_left_click(); + } + } + } + if (control && key == 'V') { + const char *buffer = glfwGetClipboardString(window); + if (g->typing) { + g->suppress_char = 1; + strncat(g->typing_buffer, buffer, + MAX_TEXT_LENGTH - strlen(g->typing_buffer) - 1); + } + else { + parse_command(buffer, 0); + } + } + if (!g->typing) { + if (key == CRAFT_KEY_FLY) { + g->flying = !g->flying; + } + if (key >= '1' && key <= '9') { + g->item_index = key - '1'; + } + if (key == '0') { + g->item_index = 9; + } + if (key == CRAFT_KEY_ITEM_NEXT) { + g->item_index = (g->item_index + 1) % item_count; + } + if (key == CRAFT_KEY_ITEM_PREV) { + g->item_index--; + if (g->item_index < 0) { + g->item_index = item_count - 1; + } + } + if (key == CRAFT_KEY_OBSERVE) { + g->observe1 = (g->observe1 + 1) % g->player_count; + } + if (key == CRAFT_KEY_OBSERVE_INSET) { + g->observe2 = (g->observe2 + 1) % g->player_count; + } } - if (key == GLFW_KEY_ENTER) { - if (g->typing) { - if (mods & GLFW_MOD_SHIFT) { - int n = strlen(g->typing_buffer); - if (n < MAX_TEXT_LENGTH - 1) { - g->typing_buffer[n] = '\r'; - g->typing_buffer[n + 1] = '\0'; - } - } - else { - g->typing = 0; - if (g->typing_buffer[0] == CRAFT_KEY_SIGN) { - Player *player = g->players; - int x, y, z, face; - if (hit_test_face(player, &x, &y, &z, &face)) { - set_sign(x, y, z, face, g->typing_buffer + 1); - } - } - else if (g->typing_buffer[0] == '/') { - parse_command(g->typing_buffer, 1); - } - else { - client_talk(g->typing_buffer); - } - } - } - else { - if (control) { - on_right_click(); - } - else { - on_left_click(); - } - } - } - if (control && key == 'V') { - const char *buffer = glfwGetClipboardString(window); - if (g->typing) { - g->suppress_char = 1; - strncat(g->typing_buffer, buffer, - MAX_TEXT_LENGTH - strlen(g->typing_buffer) - 1); - } - else { - parse_command(buffer, 0); - } - } - if (!g->typing) { - if (key == CRAFT_KEY_FLY) { - g->flying = !g->flying; - } - if (key >= '1' && key <= '9') { - g->item_index = key - '1'; - } - if (key == '0') { - g->item_index = 9; - } - if (key == CRAFT_KEY_ITEM_NEXT) { - g->item_index = (g->item_index + 1) % item_count; - } - if (key == CRAFT_KEY_ITEM_PREV) { - g->item_index--; - if (g->item_index < 0) { - g->item_index = item_count - 1; - } - } - if (key == CRAFT_KEY_OBSERVE) { - g->observe1 = (g->observe1 + 1) % g->player_count; - } - if (key == CRAFT_KEY_OBSERVE_INSET) { - g->observe2 = (g->observe2 + 1) % g->player_count; - } - } - /* - if(key == GLFW_KEY_F11) { - if(g->is_fullscreen) { - GLFWmonitor *monitor = NULL; - int mode_count; - monitor = glfwGetPrimaryMonitor(); - const GLFWvidmode *modes = glfwGetVideoModes(monitor, &mode_count); - int width = modes[mode_count - 1].width; - int height = modes[mode_count - 1].height; + /* + if(key == GLFW_KEY_F11) { + if(g->is_fullscreen) { + GLFWmonitor *monitor = NULL; + int mode_count; + monitor = glfwGetPrimaryMonitor(); + const GLFWvidmode *modes = glfwGetVideoModes(monitor, &mode_count); + int width = modes[mode_count - 1].width; + int height = modes[mode_count - 1].height; - glfwSetWindowMonitor(g->window, monitor, 0, 0, width, height, GLFW_DONT_CARE); - } else { - glfwSetWindowMonitor(g->window, NULL, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, GLFW_DONT_CARE); - } - } - */ + glfwSetWindowMonitor(g->window, monitor, 0, 0, width, height, GLFW_DONT_CARE); + } else { + glfwSetWindowMonitor(g->window, NULL, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, GLFW_DONT_CARE); + } + } + */ } void on_char(GLFWwindow *window, unsigned int u) { - if (g->suppress_char) { - g->suppress_char = 0; - return; - } - if (g->typing) { - if (u >= 32 && u < 128) { - char c = (char)u; - int n = strlen(g->typing_buffer); - if (n < MAX_TEXT_LENGTH - 1) { - g->typing_buffer[n] = c; - g->typing_buffer[n + 1] = '\0'; - } - } - } - else { - if (u == CRAFT_KEY_CHAT) { - g->typing = 1; - g->typing_buffer[0] = '\0'; - } - if (u == CRAFT_KEY_COMMAND) { - g->typing = 1; - g->typing_buffer[0] = '/'; - g->typing_buffer[1] = '\0'; - } - if (u == CRAFT_KEY_SIGN) { - g->typing = 1; - g->typing_buffer[0] = CRAFT_KEY_SIGN; - g->typing_buffer[1] = '\0'; - } - } + if (g->suppress_char) { + g->suppress_char = 0; + return; + } + if (g->typing) { + if (u >= 32 && u < 128) { + char c = (char)u; + int n = strlen(g->typing_buffer); + if (n < MAX_TEXT_LENGTH - 1) { + g->typing_buffer[n] = c; + g->typing_buffer[n + 1] = '\0'; + } + } + } + else { + if (u == CRAFT_KEY_CHAT) { + g->typing = 1; + g->typing_buffer[0] = '\0'; + } + if (u == CRAFT_KEY_COMMAND) { + g->typing = 1; + g->typing_buffer[0] = '/'; + g->typing_buffer[1] = '\0'; + } + if (u == CRAFT_KEY_SIGN) { + g->typing = 1; + g->typing_buffer[0] = CRAFT_KEY_SIGN; + g->typing_buffer[1] = '\0'; + } + } } void on_scroll(GLFWwindow *window, double xdelta, double ydelta) { - static double ypos = 0; - ypos += ydelta; - if (ypos < -SCROLL_THRESHOLD) { - g->item_index = (g->item_index + 1) % item_count; - ypos = 0; - } - if (ypos > SCROLL_THRESHOLD) { - g->item_index--; - if (g->item_index < 0) { - g->item_index = item_count - 1; - } - ypos = 0; - } + static double ypos = 0; + ypos += ydelta; + if (ypos < -SCROLL_THRESHOLD) { + g->item_index = (g->item_index + 1) % item_count; + ypos = 0; + } + if (ypos > SCROLL_THRESHOLD) { + g->item_index--; + if (g->item_index < 0) { + g->item_index = item_count - 1; + } + ypos = 0; + } } void on_mouse_button(GLFWwindow *window, int button, int action, int mods) { - int control = mods & (GLFW_MOD_CONTROL | GLFW_MOD_SUPER); - int exclusive = - glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED; - if (action != GLFW_PRESS) { - return; - } - if (button == GLFW_MOUSE_BUTTON_LEFT) { - if (exclusive) { - if (control) { - on_right_click(); - } - else { - on_left_click(); - } - } - else { - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - } - } - if (button == GLFW_MOUSE_BUTTON_RIGHT) { - if (exclusive) { - if (control) { - on_light(); - } - else { - on_right_click(); - } - } - } - if (button == GLFW_MOUSE_BUTTON_MIDDLE) { - if (exclusive) { - on_middle_click(); - } - } + int control = mods & (GLFW_MOD_CONTROL | GLFW_MOD_SUPER); + int exclusive = + glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED; + if (action != GLFW_PRESS) { + return; + } + if (button == GLFW_MOUSE_BUTTON_LEFT) { + if (exclusive) { + if (control) { + on_right_click(); + } + else { + on_left_click(); + } + } + else { + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + } + } + if (button == GLFW_MOUSE_BUTTON_RIGHT) { + if (exclusive) { + if (control) { + on_light(); + } + else { + on_right_click(); + } + } + } + if (button == GLFW_MOUSE_BUTTON_MIDDLE) { + if (exclusive) { + on_middle_click(); + } + } } void create_window() { - int window_width = WINDOW_WIDTH; - int window_height = WINDOW_HEIGHT; - GLFWmonitor *monitor = NULL; - if (FULLSCREEN) { - int mode_count; - monitor = glfwGetPrimaryMonitor(); - const GLFWvidmode *modes = glfwGetVideoModes(monitor, &mode_count); - window_width = modes[mode_count - 1].width; - window_height = modes[mode_count - 1].height; - } - g->window = glfwCreateWindow( - window_width, window_height, "Omicron, enjoy.", monitor, NULL); + int window_width = WINDOW_WIDTH; + int window_height = WINDOW_HEIGHT; + GLFWmonitor *monitor = NULL; + if (FULLSCREEN) { + int mode_count; + monitor = glfwGetPrimaryMonitor(); + const GLFWvidmode *modes = glfwGetVideoModes(monitor, &mode_count); + window_width = modes[mode_count - 1].width; + window_height = modes[mode_count - 1].height; + } + g->window = glfwCreateWindow( + window_width, window_height, "Omicron, enjoy.", monitor, NULL); - //g->is_fullscreen = FULLSCREEN; + //g->is_fullscreen = FULLSCREEN; } void handle_mouse_input() { - int exclusive = - glfwGetInputMode(g->window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED; - static double px = 0; - static double py = 0; - State *s = &g->players->state; - if (exclusive && (px || py)) { - double mx, my; - glfwGetCursorPos(g->window, &mx, &my); - float m = 0.0025; - s->rx += (mx - px) * m; - if (INVERT_MOUSE) { - s->ry += (my - py) * m; - } - else { - s->ry -= (my - py) * m; - } - if (s->rx < 0) { - s->rx += RADIANS(360); - } - if (s->rx >= RADIANS(360)){ - s->rx -= RADIANS(360); - } - s->ry = MAX(s->ry, -RADIANS(90)); - s->ry = MIN(s->ry, RADIANS(90)); - px = mx; - py = my; - } - else { - glfwGetCursorPos(g->window, &px, &py); - } + int exclusive = + glfwGetInputMode(g->window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED; + static double px = 0; + static double py = 0; + State *s = &g->players->state; + if (exclusive && (px || py)) { + double mx, my; + glfwGetCursorPos(g->window, &mx, &my); + float m = 0.0025; + s->rx += (mx - px) * m; + if (INVERT_MOUSE) { + s->ry += (my - py) * m; + } + else { + s->ry -= (my - py) * m; + } + if (s->rx < 0) { + s->rx += RADIANS(360); + } + if (s->rx >= RADIANS(360)){ + s->rx -= RADIANS(360); + } + s->ry = MAX(s->ry, -RADIANS(90)); + s->ry = MIN(s->ry, RADIANS(90)); + px = mx; + py = my; + } + else { + glfwGetCursorPos(g->window, &px, &py); + } } void handle_mouse_input_in_menu() { - static double px = 0; - static double py = 0; - glfwSetInputMode(g->window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); - glfwGetCursorPos(g->window, &px, &py); + static double px = 0; + static double py = 0; + glfwSetInputMode(g->window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + glfwGetCursorPos(g->window, &px, &py); } void handle_movement(double dt) { - static float dy = 0; - State *s = &g->players->state; - int sz = 0; - int sx = 0; - if (!g->typing) { - float m = dt * 1.0; - g->ortho = glfwGetKey(g->window, CRAFT_KEY_ORTHO) ? 64 : 0; - g->fov = glfwGetKey(g->window, CRAFT_KEY_ZOOM) ? 15 : 65; - if (glfwGetKey(g->window, CRAFT_KEY_FORWARD)) sz--; - if (glfwGetKey(g->window, CRAFT_KEY_BACKWARD)) sz++; - if (glfwGetKey(g->window, CRAFT_KEY_LEFT)) sx--; - if (glfwGetKey(g->window, CRAFT_KEY_RIGHT)) sx++; - if (glfwGetKey(g->window, GLFW_KEY_LEFT)) s->rx -= m; - if (glfwGetKey(g->window, GLFW_KEY_RIGHT)) s->rx += m; - if (glfwGetKey(g->window, GLFW_KEY_UP)) s->ry += m; - if (glfwGetKey(g->window, GLFW_KEY_DOWN)) s->ry -= m; - } - float vx, vy, vz; - get_motion_vector(g->flying, sz, sx, s->rx, s->ry, &vx, &vy, &vz); - int w = get_block(s->x, s->y, s->z); - int is_jump_pressed = glfwGetKey(g->window, CRAFT_KEY_JUMP); - int is_descend_pressed = glfwGetKey(g->window, CRAFT_KEY_DECSEND); - if (!g->typing) { - if (is_jump_pressed) { - if (g->flying) { - vy = 1; - } - else if (dy == 0) { - if (is_climbable(w)) { - dy = CLIMB_SPEED; - } else { - dy = 8; - } - } - } - else if (is_descend_pressed) { - if (is_climbable(w)) { - dy = -CLIMB_SPEED; + static float dy = 0; + State *s = &g->players->state; + int sz = 0; + int sx = 0; + if (!g->typing) { + float m = dt * 1.0; + g->ortho = glfwGetKey(g->window, CRAFT_KEY_ORTHO) ? 64 : 0; + g->fov = glfwGetKey(g->window, CRAFT_KEY_ZOOM) ? 15 : 65; + if (glfwGetKey(g->window, CRAFT_KEY_FORWARD)) sz--; + if (glfwGetKey(g->window, CRAFT_KEY_BACKWARD)) sz++; + if (glfwGetKey(g->window, CRAFT_KEY_LEFT)) sx--; + if (glfwGetKey(g->window, CRAFT_KEY_RIGHT)) sx++; + if (glfwGetKey(g->window, GLFW_KEY_LEFT)) s->rx -= m; + if (glfwGetKey(g->window, GLFW_KEY_RIGHT)) s->rx += m; + if (glfwGetKey(g->window, GLFW_KEY_UP)) s->ry += m; + if (glfwGetKey(g->window, GLFW_KEY_DOWN)) s->ry -= m; + } + float vx, vy, vz; + get_motion_vector(g->flying, sz, sx, s->rx, s->ry, &vx, &vy, &vz); + int w = get_block(s->x, s->y, s->z); + int is_jump_pressed = glfwGetKey(g->window, CRAFT_KEY_JUMP); + int is_descend_pressed = glfwGetKey(g->window, CRAFT_KEY_DECSEND); + if (!g->typing) { + if (is_jump_pressed) { + if (g->flying) { + vy = 1; + } + else if (dy == 0) { + if (is_climbable(w)) { + dy = CLIMB_SPEED; + } else { + dy = 8; + } } } - } - float speed = g->flying ? FLY_SPEED : WALK_SPEED; - int estimate = roundf(sqrtf( - powf(vx * speed, 2) + - powf(vy * speed + ABS(dy) * 2, 2) + - powf(vz * speed, 2)) * dt * 8); - int step = MAX(8, estimate); - float ut = dt / step; - vx = vx * ut * speed; - vy = vy * ut * speed; - vz = vz * ut * speed; - for (int i = 0; i < step; i++) { - if (g->flying) { - dy = 0; + else if (is_descend_pressed) { + if (is_climbable(w)) { + dy = -CLIMB_SPEED; + } + } + } + float speed = g->flying ? FLY_SPEED : WALK_SPEED; + int estimate = roundf(sqrtf( + powf(vx * speed, 2) + + powf(vy * speed + ABS(dy) * 2, 2) + + powf(vz * speed, 2)) * dt * 8); + int step = MAX(8, estimate); + float ut = dt / step; + vx = vx * ut * speed; + vy = vy * ut * speed; + vz = vz * ut * speed; + for (int i = 0; i < step; i++) { + if (g->flying) { + dy = 0; - if (is_descend_pressed) { - vy = -0.05f; - } - } - else { - if (is_climbable(w)) { - if (!is_jump_pressed) { - if (dy > 0) { - dy = 0.0f; - } - else if (!is_descend_pressed) { - dy = 0.0f; - } - } - } else if (is_liquid(w)) { - + if (is_descend_pressed) { + vy = -0.05f; + } + } + else { + if (is_climbable(w)) { + if (!is_jump_pressed) { + if (dy > 0) { + dy = 0.0f; + } + else if (!is_descend_pressed) { + dy = 0.0f; + } + } + } else if (is_liquid(w)) { + if (is_jump_pressed) { - dy = 8.0f; - //dy = 0; - - } else if (is_descend_pressed) { - dy = -1.2f; - //dy = 0; - - } else { - dy = -0.5f; - //dy = 0; - - } - + dy = 8.0f; + //dy = 0; + + } else if (is_descend_pressed) { + dy = -1.2f; + //dy = 0; + + } else { + dy = -0.5f; + //dy = 0; + + } + vx = vx*0.65; //vy = vy/1.6; vz = vz*0.65; - - } - else { - dy -= ut * 25; - dy = MAX(dy, -250); - } - } - s->x += vx; - s->y += vy + dy * ut; - s->z += vz; - if (collide(2, &s->x, &s->y, &s->z)) { - dy = 0; - } - } - if (s->y < 0) { - s->y = highest_block(s->x, s->z) + 2; - } + + } + else { + dy -= ut * 25; + dy = MAX(dy, -250); + } + } + s->x += vx; + s->y += vy + dy * ut; + s->z += vz; + if (collide(2, &s->x, &s->y, &s->z)) { + dy = 0; + } + } + if (s->y < 0) { + s->y = highest_block(s->x, s->z) + 2; + } } void menu_movement(double dt) { - static float dy = 0; - State *s = &g->players->state; - int sz = 0; - int sx = 0; - s->ry += 1; + // TODO: Allow the player to fall while in inventory + static float dy = 0; + State *s = &g->players->state; + int sz = 0; + int sx = 0; + s->ry += 1; } +void handle_liquids() { + State *s = &g->players->state; + int px = s->x; + int py = s->y; + int pz = s->z; + + //int nx, ny, nz; + //set_block(px, py+5, pz, 35); + Block block = {px, py, pz, 1}; + sphere(&block, 2, Item_EMPTY, px, py, pz); +} void parse_buffer(char *buffer) { - Player *me = g->players; - State *s = &g->players->state; - char *key; - char *line = tokenize(buffer, "\n", &key); - while (line) { - int pid; - float ux, uy, uz, urx, ury; - if (sscanf(line, "U,%d,%f,%f,%f,%f,%f", - &pid, &ux, &uy, &uz, &urx, &ury) == 6) - { - me->id = pid; - s->x = ux; s->y = uy; s->z = uz; s->rx = urx; s->ry = ury; - force_chunks(me); - if (uy == 0) { - s->y = highest_block(s->x, s->z) + 2; - } - } - int bp, bq, bx, by, bz, bw; - if (sscanf(line, "B,%d,%d,%d,%d,%d,%d", - &bp, &bq, &bx, &by, &bz, &bw) == 6) - { - _set_block(bp, bq, bx, by, bz, bw, 0); - if (player_intersects_block(2, s->x, s->y, s->z, bx, by, bz)) { - s->y = highest_block(s->x, s->z) + 2; - } - } - if (sscanf(line, "L,%d,%d,%d,%d,%d,%d", - &bp, &bq, &bx, &by, &bz, &bw) == 6) - { - set_light(bp, bq, bx, by, bz, bw); - } - float px, py, pz, prx, pry; - if (sscanf(line, "P,%d,%f,%f,%f,%f,%f", - &pid, &px, &py, &pz, &prx, &pry) == 6) - { - Player *player = find_player(pid); - if (!player && g->player_count < MAX_PLAYERS) { - player = g->players + g->player_count; - g->player_count++; - player->id = pid; - player->buffer = 0; - snprintf(player->name, MAX_NAME_LENGTH, "player%d", pid); - update_player(player, px, py, pz, prx, pry, 1); // twice - } - if (player) { - update_player(player, px, py, pz, prx, pry, 1); - } - } - if (sscanf(line, "D,%d", &pid) == 1) { - delete_player(pid); - } - int kp, kq, kk; - if (sscanf(line, "K,%d,%d,%d", &kp, &kq, &kk) == 3) { - db_set_key(kp, kq, kk); - } - if (sscanf(line, "R,%d,%d", &kp, &kq) == 2) { - Chunk *chunk = find_chunk(kp, kq); - if (chunk) { - dirty_chunk(chunk); - } - } - double elapsed; - int day_length; - if (sscanf(line, "E,%lf,%d", &elapsed, &day_length) == 2) { - glfwSetTime(fmod(elapsed, day_length)); - g->day_length = day_length; - g->time_changed = 1; - } - if (line[0] == 'T' && line[1] == ',') { - char *text = line + 2; - add_message(text); - } - char format[64]; - snprintf( - format, sizeof(format), "N,%%d,%%%ds", MAX_NAME_LENGTH - 1); - char name[MAX_NAME_LENGTH]; - if (sscanf(line, format, &pid, name) == 2) { - Player *player = find_player(pid); - if (player) { - strncpy(player->name, name, MAX_NAME_LENGTH); - } - } - snprintf( - format, sizeof(format), - "S,%%d,%%d,%%d,%%d,%%d,%%d,%%%d[^\n]", MAX_SIGN_LENGTH - 1); - int face; - char text[MAX_SIGN_LENGTH] = {0}; - if (sscanf(line, format, - &bp, &bq, &bx, &by, &bz, &face, text) >= 6) - { - _set_sign(bp, bq, bx, by, bz, face, text, 0); - } - line = tokenize(NULL, "\n", &key); - } + Player *me = g->players; + State *s = &g->players->state; + char *key; + char *line = tokenize(buffer, "\n", &key); + while (line) { + int pid; + float ux, uy, uz, urx, ury; + if (sscanf(line, "U,%d,%f,%f,%f,%f,%f", + &pid, &ux, &uy, &uz, &urx, &ury) == 6) + { + me->id = pid; + s->x = ux; s->y = uy; s->z = uz; s->rx = urx; s->ry = ury; + force_chunks(me); + if (uy == 0) { + s->y = highest_block(s->x, s->z) + 2; + } + } + int bp, bq, bx, by, bz, bw; + if (sscanf(line, "B,%d,%d,%d,%d,%d,%d", + &bp, &bq, &bx, &by, &bz, &bw) == 6) + { + _set_block(bp, bq, bx, by, bz, bw, 0); + if (player_intersects_block(2, s->x, s->y, s->z, bx, by, bz)) { + s->y = highest_block(s->x, s->z) + 2; + } + } + if (sscanf(line, "L,%d,%d,%d,%d,%d,%d", + &bp, &bq, &bx, &by, &bz, &bw) == 6) + { + set_light(bp, bq, bx, by, bz, bw); + } + float px, py, pz, prx, pry; + if (sscanf(line, "P,%d,%f,%f,%f,%f,%f", + &pid, &px, &py, &pz, &prx, &pry) == 6) + { + Player *player = find_player(pid); + if (!player && g->player_count < MAX_PLAYERS) { + player = g->players + g->player_count; + g->player_count++; + player->id = pid; + player->buffer = 0; + snprintf(player->name, MAX_NAME_LENGTH, "player%d", pid); + update_player(player, px, py, pz, prx, pry, 1); // twice + } + if (player) { + update_player(player, px, py, pz, prx, pry, 1); + } + } + if (sscanf(line, "D,%d", &pid) == 1) { + delete_player(pid); + } + int kp, kq, kk; + if (sscanf(line, "K,%d,%d,%d", &kp, &kq, &kk) == 3) { + db_set_key(kp, kq, kk); + } + if (sscanf(line, "R,%d,%d", &kp, &kq) == 2) { + Chunk *chunk = find_chunk(kp, kq); + if (chunk) { + dirty_chunk(chunk); + } + } + double elapsed; + int day_length; + if (sscanf(line, "E,%lf,%d", &elapsed, &day_length) == 2) { + glfwSetTime(fmod(elapsed, day_length)); + g->day_length = day_length; + g->time_changed = 1; + } + if (line[0] == 'T' && line[1] == ',') { + char *text = line + 2; + add_message(text); + } + char format[64]; + snprintf( + format, sizeof(format), "N,%%d,%%%ds", MAX_NAME_LENGTH - 1); + char name[MAX_NAME_LENGTH]; + if (sscanf(line, format, &pid, name) == 2) { + Player *player = find_player(pid); + if (player) { + strncpy(player->name, name, MAX_NAME_LENGTH); + } + } + snprintf( + format, sizeof(format), + "S,%%d,%%d,%%d,%%d,%%d,%%d,%%%d[^\n]", MAX_SIGN_LENGTH - 1); + int face; + char text[MAX_SIGN_LENGTH] = {0}; + if (sscanf(line, format, + &bp, &bq, &bx, &by, &bz, &face, text) >= 6) + { + _set_sign(bp, bq, bx, by, bz, face, text, 0); + } + line = tokenize(NULL, "\n", &key); + } } void update_sky_tint() { - SkyColor *c = &g->sky_color; - g->last_sky_color = *c; + SkyColor *c = &g->sky_color; + g->last_sky_color = *c; - State *s = &g->players->state; - int p = chunked(s->x); - int q = chunked(s->z); - int x = p * CHUNK_SIZE; - int z = q * CHUNK_SIZE; + State *s = &g->players->state; + int p = chunked(s->x); + int q = chunked(s->z); + int x = p * CHUNK_SIZE; + int z = q * CHUNK_SIZE; - SkyColor new_color; - get_sky_tint(biome_at_pos(q, x, z), &new_color); + SkyColor new_color; + get_sky_tint(biome_at_pos(q, x, z), &new_color); - //Interpolate sky color to get close to the actual value gradually. - //Technically, it won't arrive, but rather achieve an extremely close color. - c->r += 0.01 * (new_color.r - c->r); - c->g += 0.01 * (new_color.g - c->g); - c->b += 0.01 * (new_color.b - c->b); + //Interpolate sky color to get close to the actual value gradually. + //Technically, it won't arrive, but rather achieve an extremely close color. + c->r += 0.01 * (new_color.r - c->r); + c->g += 0.01 * (new_color.g - c->g); + c->b += 0.01 * (new_color.b - c->b); - //printf("c: %f last: %f\n", c->r, g->last_sky_color.r); + //printf("c: %f last: %f\n", c->r, g->last_sky_color.r); } void reset_model() { - memset(g->chunks, 0, sizeof(Chunk) * MAX_CHUNKS); - g->chunk_count = 0; - memset(g->players, 0, sizeof(Player) * MAX_PLAYERS); - g->player_count = 0; - g->observe1 = 0; - g->observe2 = 0; - g->flying = 0; - g->item_index = 0; - memset(g->typing_buffer, 0, sizeof(char) * MAX_TEXT_LENGTH); - g->typing = 0; - memset(g->messages, 0, sizeof(char) * MAX_MESSAGES * MAX_TEXT_LENGTH); - g->message_index = 0; - g->day_length = DAY_LENGTH; - glfwSetTime(g->day_length / 3.0); - g->time_changed = 1; + memset(g->chunks, 0, sizeof(Chunk) * MAX_CHUNKS); + g->chunk_count = 0; + memset(g->players, 0, sizeof(Player) * MAX_PLAYERS); + g->player_count = 0; + g->observe1 = 0; + g->observe2 = 0; + g->flying = 0; + g->item_index = 0; + memset(g->typing_buffer, 0, sizeof(char) * MAX_TEXT_LENGTH); + g->typing = 0; + memset(g->messages, 0, sizeof(char) * MAX_MESSAGES * MAX_TEXT_LENGTH); + g->message_index = 0; + g->day_length = DAY_LENGTH; + glfwSetTime(g->day_length / 3.0); + g->time_changed = 1; - g->sky_color = (SkyColor){0.0f, 0.0f, 0.0f}; - g->last_sky_color = g->sky_color; - Inventory_reset(&g->inventory); + g->sky_color = (SkyColor){0.0f, 0.0f, 0.0f}; + g->last_sky_color = g->sky_color; + Inventory_reset(&g->inventory); } void advance_cursor() { @@ -2818,331 +2865,548 @@ void advance_cursor() { pos = (pos+1) % 4; } +void edit_config(char param, int value) { + FILE *fconf; + fconf = fopen("config.txt","r+"); + + //fprintf(fconf,"%c %d \n", param, value); + fprintf(fconf,"lol \n"); +} + int main(int argc, char **argv) { - // INITIALIZATION // - curl_global_init(CURL_GLOBAL_DEFAULT); - srand(time(NULL)); - rand(); - - // TERMINAL TEST GUI // - - char world; - - // Header generated using -> https://fsymbols.com/generators/tarty/ - printf("\n▒█▀▀▀█ ▒█▀▄▀█ ▀█▀ ▒█▀▀█ ▒█▀▀█ ▒█▀▀▀█ ▒█▄░▒█ \n▒█░░▒█ ▒█▒█▒█ ▒█░ ▒█░░░ ▒█▄▄▀ ▒█░░▒█ ▒█▒█▒█ \n▒█▄▄▄█ ▒█░░▒█ ▄█▄ ▒█▄▄█ ▒█░▒█ ▒█▄▄▄█ ▒█░░▀█ \n a game not by azekill_DIABLO\n\n"); - - /* - printf("> Available World list:"); - struct dirent *de; // Pointer for directory entry + // INITIALIZATION // + curl_global_init(CURL_GLOBAL_DEFAULT); + srand(time(NULL)); + rand(); + + // TERMINAL UI // + /* + * This UI allows the player to know + * whether or not the game has launched + * properly. Also used for debug. + */ + + + // Header generated using -> https://fsymbols.com/generators/tarty/ + printf("\n▒█▀▀▀█ ▒█▀▄▀█ ▀█▀ ▒█▀▀█ ▒█▀▀█ ▒█▀▀▀█ ▒█▄░▒█ \n▒█░░▒█ ▒█▒█▒█ ▒█░ ▒█░░░ ▒█▄▄▀ ▒█░░▒█ ▒█▒█▒█ \n▒█▄▄▄█ ▒█░░▒█ ▄█▄ ▒█▄▄█ ▒█░▒█ ▒█▄▄▄█ ▒█░░▀█ \n a game not by azekill_DIABLO\n"); + // Sorry for the long line of code + + // unused world selection stuff + char world; + + /* + printf("> Available World list:"); + struct dirent *de; // Pointer for directory entry - // opendir() returns a pointer of DIR type. - DIR *dr = opendir("./world"); + // opendir() returns a pointer of DIR type. + DIR *dr = opendir("./world"); - // Refer http://pubs.opengroup.org/onlinepubs/7990989775/xsh/readdir.html - // for readdir() - while ((de = readdir(dr)) != NULL) - printf("%s\n", de->d_name); - - printf("> Enter the name of the world you want to load:"); - scanf("> %d", &world); - printf("> Loading selected world."); - */ - - //printf("> Press RETURN to start"); - //getchar(); + // Refer http://pubs.opengroup.org/onlinepubs/7990989775/xsh/readdir.html + // for readdir() + while ((de = readdir(dr)) != NULL) + printf("%s\n", de->d_name); + + printf("> Enter the name of the world you want to load:"); + scanf("> %d", &world); + printf("> Loading selected world."); + */ + + //printf("> Press RETURN to start"); + //getchar(); - - // WINDOW INITIALIZATION // - if (!glfwInit()) { - return -1; - } - create_window(); - if (!g->window) { - glfwTerminate(); - return -1; - } + + // WINDOW INITIALIZATION // + if (!glfwInit()) { + return -1; + } + create_window(); + if (!g->window) { + glfwTerminate(); + return -1; + } - glfwMakeContextCurrent(g->window); - glfwSwapInterval(VSYNC); - glfwSetInputMode(g->window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - glfwSetKeyCallback(g->window, on_key); - glfwSetCharCallback(g->window, on_char); - glfwSetMouseButtonCallback(g->window, on_mouse_button); - glfwSetScrollCallback(g->window, on_scroll); + glfwMakeContextCurrent(g->window); + glfwSwapInterval(VSYNC); + glfwSetInputMode(g->window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + glfwSetKeyCallback(g->window, on_key); + glfwSetCharCallback(g->window, on_char); + glfwSetMouseButtonCallback(g->window, on_mouse_button); + glfwSetScrollCallback(g->window, on_scroll); - if (glewInit() != GLEW_OK) { - return -1; - } + if (glewInit() != GLEW_OK) { + return -1; + } - glEnable(GL_DEPTH_TEST); - glEnable(GL_ALPHA_TEST); + glEnable(GL_DEPTH_TEST); + glEnable(GL_ALPHA_TEST); glEnable(GL_CULL_FACE); - glLogicOp(GL_INVERT); - glClearColor(0, 0, 0, 0); + glLogicOp(GL_INVERT); + glClearColor(0, 0, 0, 0); - //parser_parse_all(); - - GLuint texture; - glGenTextures(1, &texture); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - load_png_texture("textures/texture.png"); - - /*GLuint texture_obj; - glGenTextures(1, &texture_obj); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texture_obj); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - load_png_texture("textures/texture_obj.png");*/ + //parser_parse_all(); + + GLuint texture; + glGenTextures(1, &texture); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + load_png_texture("textures/texture.png"); + + /*GLuint texture_obj; + glGenTextures(1, &texture_obj); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture_obj); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + load_png_texture("textures/texture_obj.png");*/ - GLuint font; - glGenTextures(1, &font); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, font); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - load_png_texture("textures/font.png"); + GLuint font; + glGenTextures(1, &font); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, font); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + load_png_texture("textures/font.png"); - GLuint sky; - glGenTextures(1, &sky); - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, sky); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - load_png_texture("textures/sky.png"); + GLuint sky; + glGenTextures(1, &sky); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, sky); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + load_png_texture("textures/sky.png"); - GLuint sign; - glGenTextures(1, &sign); - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, sign); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - load_png_texture("textures/sign.png"); - - GLuint ui; - glGenTextures(1, &ui); - glActiveTexture(GL_TEXTURE4); - glBindTexture(GL_TEXTURE_2D, ui); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - load_png_texture("textures/ui.png"); - - GLuint logo; - glGenTextures(1, &logo); - glActiveTexture(GL_TEXTURE5); - glBindTexture(GL_TEXTURE_2D, logo); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - load_png_texture("textures/logo.png"); //logo.png - - GLuint background; - glGenTextures(1, &background); - glActiveTexture(GL_TEXTURE6); - glBindTexture(GL_TEXTURE_2D, background); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - load_png_texture("textures/background.png"); //background.png + GLuint sign; + glGenTextures(1, &sign); + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, sign); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + load_png_texture("textures/sign.png"); + + GLuint ui; + glGenTextures(1, &ui); + glActiveTexture(GL_TEXTURE4); + glBindTexture(GL_TEXTURE_2D, ui); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + load_png_texture("textures/ui.png"); + + GLuint logo; + glGenTextures(1, &logo); + glActiveTexture(GL_TEXTURE5); + glBindTexture(GL_TEXTURE_2D, logo); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + load_png_texture("textures/logo.png"); //logo.png + + GLuint background; + glGenTextures(1, &background); + glActiveTexture(GL_TEXTURE6); + glBindTexture(GL_TEXTURE_2D, background); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + load_png_texture("textures/background.png"); //background.png - // LOAD SHADERS // - Attrib block_attrib = {0}; - Attrib tblock_attrib = {0}; - Attrib line_attrib = {0}; - Attrib text_attrib = {0}; - Attrib sky_attrib = {0}; - Attrib ui_attrib = {0}; - Attrib logo_attrib = {0}; - GLuint program; + // LOAD SHADERS // + Attrib block_attrib = {0}; + Attrib tblock_attrib = {0}; + Attrib line_attrib = {0}; + Attrib text_attrib = {0}; + Attrib sky_attrib = {0}; + Attrib ui_attrib = {0}; + Attrib logo_attrib = {0}; + GLuint program; - program = load_program( - "shaders/block_vertex.glsl", "shaders/block_fragment.glsl"); - block_attrib.program = program; - block_attrib.position = glGetAttribLocation(program, "position"); - block_attrib.normal = glGetAttribLocation(program, "normal"); - block_attrib.uv = glGetAttribLocation(program, "uv"); - block_attrib.matrix = glGetUniformLocation(program, "matrix"); - block_attrib.sampler = glGetUniformLocation(program, "sampler"); - block_attrib.extra1 = glGetUniformLocation(program, "sky_sampler"); - block_attrib.extra2 = glGetUniformLocation(program, "daylight"); - block_attrib.extra3 = glGetUniformLocation(program, "fog_distance"); - block_attrib.extra4 = glGetUniformLocation(program, "ortho"); - block_attrib.camera = glGetUniformLocation(program, "camera"); - block_attrib.timer = glGetUniformLocation(program, "timer"); - block_attrib.extra5 = glGetUniformLocation(program, "sky_tint"); + program = load_program( + "shaders/block_vertex.glsl", "shaders/block_fragment.glsl"); + block_attrib.program = program; + block_attrib.position = glGetAttribLocation(program, "position"); + block_attrib.normal = glGetAttribLocation(program, "normal"); + block_attrib.uv = glGetAttribLocation(program, "uv"); + block_attrib.matrix = glGetUniformLocation(program, "matrix"); + block_attrib.sampler = glGetUniformLocation(program, "sampler"); + block_attrib.extra1 = glGetUniformLocation(program, "sky_sampler"); + block_attrib.extra2 = glGetUniformLocation(program, "daylight"); + block_attrib.extra3 = glGetUniformLocation(program, "fog_distance"); + block_attrib.extra4 = glGetUniformLocation(program, "ortho"); + block_attrib.camera = glGetUniformLocation(program, "camera"); + block_attrib.timer = glGetUniformLocation(program, "timer"); + block_attrib.extra5 = glGetUniformLocation(program, "sky_tint"); - program = load_program( - "shaders/tblock_vertex.glsl", "shaders/tblock_fragment.glsl"); - tblock_attrib.program = program; - tblock_attrib.position = glGetAttribLocation(program, "position"); - tblock_attrib.normal = glGetAttribLocation(program, "normal"); - tblock_attrib.uv = glGetAttribLocation(program, "uv"); - tblock_attrib.matrix = glGetUniformLocation(program, "matrix"); - tblock_attrib.sampler = glGetUniformLocation(program, "sampler"); - tblock_attrib.extra1 = glGetUniformLocation(program, "sky_sampler"); - tblock_attrib.extra2 = glGetUniformLocation(program, "daylight"); - tblock_attrib.extra3 = glGetUniformLocation(program, "fog_distance"); - tblock_attrib.extra4 = glGetUniformLocation(program, "ortho"); - tblock_attrib.camera = glGetUniformLocation(program, "camera"); - tblock_attrib.timer = glGetUniformLocation(program, "timer"); - tblock_attrib.extra5 = glGetUniformLocation(program, "sky_tint"); + program = load_program( + "shaders/tblock_vertex.glsl", "shaders/tblock_fragment.glsl"); + tblock_attrib.program = program; + tblock_attrib.position = glGetAttribLocation(program, "position"); + tblock_attrib.normal = glGetAttribLocation(program, "normal"); + tblock_attrib.uv = glGetAttribLocation(program, "uv"); + tblock_attrib.matrix = glGetUniformLocation(program, "matrix"); + tblock_attrib.sampler = glGetUniformLocation(program, "sampler"); + tblock_attrib.extra1 = glGetUniformLocation(program, "sky_sampler"); + tblock_attrib.extra2 = glGetUniformLocation(program, "daylight"); + tblock_attrib.extra3 = glGetUniformLocation(program, "fog_distance"); + tblock_attrib.extra4 = glGetUniformLocation(program, "ortho"); + tblock_attrib.camera = glGetUniformLocation(program, "camera"); + tblock_attrib.timer = glGetUniformLocation(program, "timer"); + tblock_attrib.extra5 = glGetUniformLocation(program, "sky_tint"); - program = load_program( - "shaders/line_vertex.glsl", "shaders/line_fragment.glsl"); - line_attrib.program = program; - line_attrib.position = glGetAttribLocation(program, "position"); - line_attrib.matrix = glGetUniformLocation(program, "matrix"); + program = load_program( + "shaders/line_vertex.glsl", "shaders/line_fragment.glsl"); + line_attrib.program = program; + line_attrib.position = glGetAttribLocation(program, "position"); + line_attrib.matrix = glGetUniformLocation(program, "matrix"); - program = load_program( - "shaders/text_vertex.glsl", "shaders/text_fragment.glsl"); - text_attrib.program = program; - text_attrib.position = glGetAttribLocation(program, "position"); - text_attrib.uv = glGetAttribLocation(program, "uv"); - text_attrib.matrix = glGetUniformLocation(program, "matrix"); - text_attrib.sampler = glGetUniformLocation(program, "sampler"); - text_attrib.extra1 = glGetUniformLocation(program, "is_sign"); + program = load_program( + "shaders/text_vertex.glsl", "shaders/text_fragment.glsl"); + text_attrib.program = program; + text_attrib.position = glGetAttribLocation(program, "position"); + text_attrib.uv = glGetAttribLocation(program, "uv"); + text_attrib.matrix = glGetUniformLocation(program, "matrix"); + text_attrib.sampler = glGetUniformLocation(program, "sampler"); + text_attrib.extra1 = glGetUniformLocation(program, "is_sign"); - program = load_program( - "shaders/sky_vertex.glsl", "shaders/sky_fragment.glsl"); - sky_attrib.program = program; - sky_attrib.position = glGetAttribLocation(program, "position"); - sky_attrib.normal = glGetAttribLocation(program, "normal"); - sky_attrib.uv = glGetAttribLocation(program, "uv"); - sky_attrib.matrix = glGetUniformLocation(program, "matrix"); - sky_attrib.sampler = glGetUniformLocation(program, "sampler"); - sky_attrib.timer = glGetUniformLocation(program, "timer"); - sky_attrib.extra1 = glGetUniformLocation(program, "sky_tint"); - - program = load_program( - "shaders/ui_vertex.glsl", "shaders/ui_fragment.glsl"); - ui_attrib.program = program; - ui_attrib.position = glGetAttribLocation(program, "position"); - ui_attrib.normal = glGetAttribLocation(program, "normal"); - ui_attrib.uv = glGetAttribLocation(program, "uv"); - ui_attrib.matrix = glGetUniformLocation(program, "matrix"); - ui_attrib.sampler = glGetUniformLocation(program, "sampler"); - ui_attrib.timer = glGetUniformLocation(program, "timer"); - ui_attrib.extra1 = glGetUniformLocation(program, "sky_tint"); - - program = load_program( - "shaders/ui_vertex.glsl", "shaders/ui_fragment.glsl"); - logo_attrib.program = program; - logo_attrib.position = glGetAttribLocation(program, "position"); - logo_attrib.normal = glGetAttribLocation(program, "normal"); - logo_attrib.uv = glGetAttribLocation(program, "uv"); - logo_attrib.matrix = glGetUniformLocation(program, "matrix"); - logo_attrib.sampler = glGetUniformLocation(program, "sampler"); - logo_attrib.timer = glGetUniformLocation(program, "timer"); + program = load_program( + "shaders/sky_vertex.glsl", "shaders/sky_fragment.glsl"); + sky_attrib.program = program; + sky_attrib.position = glGetAttribLocation(program, "position"); + sky_attrib.normal = glGetAttribLocation(program, "normal"); + sky_attrib.uv = glGetAttribLocation(program, "uv"); + sky_attrib.matrix = glGetUniformLocation(program, "matrix"); + sky_attrib.sampler = glGetUniformLocation(program, "sampler"); + sky_attrib.timer = glGetUniformLocation(program, "timer"); + sky_attrib.extra1 = glGetUniformLocation(program, "sky_tint"); + + program = load_program( + "shaders/ui_vertex.glsl", "shaders/ui_fragment.glsl"); + ui_attrib.program = program; + ui_attrib.position = glGetAttribLocation(program, "position"); + ui_attrib.normal = glGetAttribLocation(program, "normal"); + ui_attrib.uv = glGetAttribLocation(program, "uv"); + ui_attrib.matrix = glGetUniformLocation(program, "matrix"); + ui_attrib.sampler = glGetUniformLocation(program, "sampler"); + ui_attrib.timer = glGetUniformLocation(program, "timer"); + ui_attrib.extra1 = glGetUniformLocation(program, "sky_tint"); + + program = load_program( + "shaders/ui_vertex.glsl", "shaders/ui_fragment.glsl"); + logo_attrib.program = program; + logo_attrib.position = glGetAttribLocation(program, "position"); + logo_attrib.normal = glGetAttribLocation(program, "normal"); + logo_attrib.uv = glGetAttribLocation(program, "uv"); + logo_attrib.matrix = glGetUniformLocation(program, "matrix"); + logo_attrib.sampler = glGetUniformLocation(program, "sampler"); + logo_attrib.timer = glGetUniformLocation(program, "timer"); logo_attrib.extra1 = glGetUniformLocation(program, "sky_tint"); - // CHECK COMMAND LINE ARGUMENTS // - if (argc == 2 || argc == 3) { - g->mode = MODE_ONLINE; - strncpy(g->server_addr, argv[1], MAX_ADDR_LENGTH); - g->server_port = argc == 3 ? atoi(argv[2]) : DEFAULT_PORT; - snprintf(g->db_path, MAX_PATH_LENGTH, - "cache.%s.%d.db", g->server_addr, g->server_port); - } - else { - g->mode = MODE_OFFLINE; - snprintf(g->db_path, MAX_PATH_LENGTH, "%s", DB_PATH); - } - g->create_radius = CREATE_CHUNK_RADIUS; - g->render_radius = RENDER_CHUNK_RADIUS; - g->delete_radius = DELETE_CHUNK_RADIUS; - g->sign_radius = RENDER_SIGN_RADIUS; + // CHECK COMMAND LINE ARGUMENTS // + if (argc == 2 || argc == 3) { + g->mode = MODE_ONLINE; + strncpy(g->server_addr, argv[1], MAX_ADDR_LENGTH); + g->server_port = argc == 3 ? atoi(argv[2]) : DEFAULT_PORT; + snprintf(g->db_path, MAX_PATH_LENGTH, + "cache.%s.%d.db", g->server_addr, g->server_port); + } + else { + g->mode = MODE_OFFLINE; + snprintf(g->db_path, MAX_PATH_LENGTH, "%s", DB_PATH); + } - // INITIALIZE WORKER THREADS - for (int i = 0; i < WORKERS; i++) { - Worker *worker = g->workers + i; - worker->index = i; - worker->state = WORKER_IDLE; - mtx_init(&worker->mtx, mtx_plain); - cnd_init(&worker->cnd); - thrd_create(&worker->thrd, worker_run, worker); - } + g->create_radius = CREATE_CHUNK_RADIUS; + g->render_radius = RENDER_CHUNK_RADIUS; + g->delete_radius = DELETE_CHUNK_RADIUS; + g->sign_radius = RENDER_SIGN_RADIUS; - // OUTER LOOP // - int running = 1; - while (running) { - // DATABASE INITIALIZATION // - if (g->mode == MODE_OFFLINE || USE_CACHE) { - db_enable(); - if (db_init(g->db_path)) { - return -1; - } - if (g->mode == MODE_ONLINE) { - // TODO: support proper caching of signs (handle deletions) - db_delete_all_signs(); - } - } + // INITIALIZE WORKER THREADS + for (int i = 0; i < WORKERS; i++) { + Worker *worker = g->workers + i; + worker->index = i; + worker->state = WORKER_IDLE; + mtx_init(&worker->mtx, mtx_plain); + cnd_init(&worker->cnd); + thrd_create(&worker->thrd, worker_run, worker); + } - // CLIENT INITIALIZATION // - if (g->mode == MODE_ONLINE) { - client_enable(); - client_connect(g->server_addr, g->server_port); - client_start(); - client_version(1); - login(); - } + // OUTER LOOP // + int running = 1; + while (running) { + // DATABASE INITIALIZATION // + if (g->mode == MODE_OFFLINE || USE_CACHE) { + db_enable(); + if (db_init(g->db_path)) { + return -1; + } + if (g->mode == MODE_ONLINE) { + // TODO: support proper caching of signs (handle deletions) + db_delete_all_signs(); + } + } - // LOCAL VARIABLES // - reset_model(); - FPS fps = {0, 0, 0}; - double last_commit = glfwGetTime(); - double last_update = glfwGetTime(); - GLuint sky_buffer = gen_sky_buffer(); + // CLIENT INITIALIZATION // + if (g->mode == MODE_ONLINE) { + client_enable(); + client_connect(g->server_addr, g->server_port); + client_start(); + client_version(1); + login(); + } - Player *me = g->players; - State *s = &g->players->state; - me->id = 0; - me->name[0] = '\0'; - me->buffer = 0; - g->player_count = 1; + // LOCAL VARIABLES // + reset_model(); + FPS fps = {0, 0, 0}; + double last_commit = glfwGetTime(); + double last_update = glfwGetTime(); + GLuint sky_buffer = gen_sky_buffer(); - // LOAD STATE FROM DATABASE // - int loaded = db_load_state(&s->x, &s->y, &s->z, &s->rx, &s->ry); - force_chunks(me); - if (!loaded) { - s->y = highest_block(s->x, s->z) + 2; - } - - // BEGIN MAIN LOOP // + Player *me = g->players; + State *s = &g->players->state; + me->id = 0; + me->name[0] = '\0'; + me->buffer = 0; + me->hp = 20; + g->player_count = 1; + - double previous = glfwGetTime(); - - // ---------- //\ - // GAME MODES // \ - // ---------- // \ - - int game_state = 0; // switch: 0 menu (dflt), 1 normal - - while (1) { + //edit_config("FONT_SIZE", 18); + + + //for (int i = 0; i < 11; i++) { + /* + int *show_lights; + if (fscanf(fconf,"SHOW_LIGHTS %d", &show_lights)) { + + SHOW_LIGHTS = show_lights; + } else { + SHOW_LIGHTS = 1; + fprintf(fconf,"SHOW_LIGHTS 1 \n"); + } + + + int *show_plants; + if (fscanf(fconf,"SHOW_PLANTS %d", &show_plants)) { + + SHOW_PLANTS = show_plants; + } else { + SHOW_PLANTS = 1; + fprintf(fconf,"SHOW_PLANTS 1 \n"); + } + + + int *show_clouds; + if (fscanf(fconf,"SHOW_CLOUDS %d", &show_clouds)) { + + SHOW_CLOUDS = show_clouds; + } else { + SHOW_CLOUDS = 1; + fprintf(fconf,"SHOW_CLOUDS 1 \n"); + } + + + int *show_trees; + if (fscanf(fconf,"SHOW_TREES %d", &show_trees)) { + + SHOW_TREES = show_trees; + } else { + SHOW_TREES = 1; + fprintf(fconf,"SHOW_TREES 1 \n"); + } + + + int *show_item; + if (fscanf(fconf,"SHOW_ITEM %d", &show_item)) { + + SHOW_ITEM = show_item; + } else { + SHOW_ITEM = 1; + fprintf(fconf,"SHOW_ITEM 1 \n"); + } + + + int *show_crosshairs; + if (fscanf(fconf,"SHOW_CROSSHAIRS %d", &show_crosshairs)) { + + SHOW_CROSSHAIRS = show_crosshairs; + } else { + SHOW_CROSSHAIRS = 1; + fprintf(fconf,"SHOW_CROSSHAIRS 1\n"); + } + + int *show_info_text; + if (fscanf(fconf,"SHOW_INFO_TEXT %d", &show_info_text)) { + + SHOW_INFO_TEXT = show_info_text; + } else { + SHOW_INFO_TEXT = 1; + fprintf(fconf,"SHOW_INFO_TEXT 1 \n"); + } + + + int *show_chat_text; + if (fscanf(fconf,"SHOW_CHAT_TEXT %d", &show_chat_text)) { + + SHOW_CHAT_TEXT = show_chat_text; + } else { + SHOW_CHAT_TEXT = 1; + fprintf(fconf,"SHOW_CHAT_TEXT 1 \n"); + } + + + int *show_player_names; + if (fscanf(fconf,"SHOW_PLAYER_NAMES %d", &show_player_names)) { + + SHOW_PLAYER_NAMES = show_player_names; + } else { + SHOW_PLAYER_NAMES = 1; + fprintf(fconf,"SHOW_PLAYER_NAMES 1 \n"); + } + + + int *font_size; + if (fscanf(fconf, "FONT_SIZE %d", &font_size)) { + + FONT_SIZE = font_size; + //printf("if choosen: %d", font_size); + } else { + + fprintf(fconf,"FONT_SIZE 16 \n"); + //printf("else choosen"); + } + //}*/ + + + // LOAD STATE FROM DATABASE // + int loaded = db_load_state(&s->x, &s->y, &s->z, &s->rx, &s->ry); + force_chunks(me); + if (!loaded) { + s->y = highest_block(s->x, s->z) + 2; + } + + // --------------- // + // CHECKING CONFIG // + // --------------- // + + // TODO: Make the config editable from ingame config menu + + FILE *fconf; + fconf = fopen("config.txt","r"); + + int show_lights; + if (fscanf(fconf,"SHOW_LIGHTS %d\n", &show_lights)) { + SHOW_LIGHTS = show_lights; + + } + + int show_item; + if (fscanf(fconf,"SHOW_ITEM %d\n", &show_item)) { + SHOW_ITEM = show_item; + + } + + int show_crosshairs; + if (fscanf(fconf,"SHOW_CROSSHAIRS %d\n", &show_crosshairs)) { + SHOW_CROSSHAIRS = show_crosshairs; + } + + int show_info_text; + if (fscanf(fconf,"SHOW_INFO_TEXT %d\n", &show_info_text)) { + SHOW_INFO_TEXT = show_info_text; + } + + int show_chat_text; + if (fscanf(fconf,"SHOW_CHAT_TEXT %d\n", &show_chat_text)) { + SHOW_CHAT_TEXT = show_chat_text; + } + + int show_player_names; + if (fscanf(fconf,"SHOW_PLAYER_NAMES %d\n", &show_player_names)) { + SHOW_PLAYER_NAMES = show_player_names; + } + + int font_size; + if (fscanf(fconf, "FONT_SIZE %d\n", &font_size)) { + FONT_SIZE = font_size; + //printf("if choosen: %d", font_size); + } + + + + // BEGIN MAIN LOOP // + + double previous = glfwGetTime(); + + // ---------- //\ + // GAME MODES // \ + // ---------- // \ + + //glfwSetInputMode(g->window, GLFW_STICKY_KEYS, 1); + //glfwSetKeyCallback(window, key_callback); + + int game_state = 0; // switch: 0 menu (dflt), 1 normal + int menu_id = 0; // switch: 0 main menu, 1 config + int inventory = 0; // switch: 0 closed, 1 opened + int i_pressed = 0; // to avoid too fast toogling + + while (1) { + + // ----------------- // + // GENERAL FUNCTIONS // + // ----------------- // + + double now = glfwGetTime(); + double dt = now - previous; + dt = MIN(dt, 0.2); + dt = MAX(dt, 0.0); + previous = now; + + // WINDOW SIZE AND SCALE // + g->scale = get_scale_factor(); + glfwGetFramebufferSize(g->window, &g->width, &g->height); + glViewport(0, 0, g->width, g->height); + + // SWAP AND POLL // + glfwSwapBuffers(g->window); + glfwPollEvents(); + if (glfwWindowShouldClose(g->window)) { + running = 0; + break; + } + if (g->mode_changed) { + g->mode_changed = 0; + break; + } + + // HANDLE DATA FROM SERVER // + char *buffer = client_recv(); + if (buffer) { + parse_buffer(buffer); + free(buffer); + } + + // FLUSH DATABASE // + if (now - last_commit > COMMIT_INTERVAL) { + last_commit = now; + db_commit(); + } + + // SEND POSITION TO SERVER // + if (now - last_update > 0.1) { + last_update = now; + client_position(s->x, s->y, s->z, s->rx, s->ry); + } + // ----------------- // // FIRST MODE (MENU) // - // ----------------- // *is wip + // ----------------- // if (game_state == 0) { - // WINDOW SIZE AND SCALE // - g->scale = get_scale_factor(); - glfwGetFramebufferSize(g->window, &g->width, &g->height); - glViewport(0, 0, g->width, g->height); - - double now = glfwGetTime(); - double dt = now - previous; - dt = MIN(dt, 0.2); - dt = MAX(dt, 0.0); - previous = now; - // HANDLE MOUSE INPUT // handle_mouse_input_in_menu(); @@ -3153,25 +3417,6 @@ int main(int argc, char **argv) { // TURN AROUND RANDOMLY // //menu_movement(dt); - - // HANDLE DATA FROM SERVER // - char *buffer = client_recv(); - if (buffer) { - parse_buffer(buffer); - free(buffer); - } - - // FLUSH DATABASE // - if (now - last_commit > COMMIT_INTERVAL) { - last_commit = now; - db_commit(); - } - - // SEND POSITION TO SERVER // - if (now - last_update > 0.1) { - last_update = now; - client_position(s->x, s->y, s->z, s->rx, s->ry); - } // CLEAR SCREEN glClearColor(0.0f, 0.0f, 0.0f, 0.0f); @@ -3198,103 +3443,236 @@ int main(int argc, char **argv) { float tx = ts / 2; float ty = g->height - ts; - - // PLAY BUTTON TEXT // - //if (cx > (g->width/2-24*3) && cx < (g->width/2+24*3)) { - //if (cy > (g->height/2-22) && cy < (g->height/2+22)) { - snprintf(text_buffer, 1024, "Play"); - render_text(&text_attrib, ALIGN_LEFT, g->width/2-ts*1.5, g->height/2, ts, text_buffer, g->width, g->height); - //} - //} - - // MATRIX FOR GUI // - float matrix[16]; - set_matrix_2d(matrix, g->width, g->height); - glUseProgram(ui_attrib.program); - glUniformMatrix4fv(ui_attrib.matrix, 1, GL_FALSE, matrix); - glUniform1i(ui_attrib.sampler, 4); - glUniform1i(ui_attrib.extra1, 0); - - // PLAY BUTTON // - - GLuint button_left_on = gen_ui_buffer(g->width/2 - (24 * g->scale)*2, g->height/2, 24 * g->scale, 10); - GLuint button_middle_on = gen_ui_buffer(g->width/2 , g->height/2, 24 * g->scale, 11); - GLuint button_right_on = gen_ui_buffer(g->width/2 + (24 * g->scale)*2, g->height/2, 24 * g->scale, 12); - - GLuint button_left = gen_ui_buffer(g->width/2 - (24 * g->scale)*2, g->height/2, 24 * g->scale, 6); - GLuint button_middle = gen_ui_buffer(g->width/2 , g->height/2, 24 * g->scale, 7); - GLuint button_right = gen_ui_buffer(g->width/2 + (24 * g->scale)*2, g->height/2, 24 * g->scale, 8); - - - - if (cx > (g->width/2-24*3) && cx < (g->width/2+24*3) && cy > (g->height/2-22) && cy < (g->height/2+22)) { - draw_ui(&ui_attrib, button_left_on); - draw_ui(&ui_attrib, button_middle_on); - draw_ui(&ui_attrib, button_right_on); - - // CLICK ACTION - if (state == GLFW_PRESS) { - game_state = 1; - glfwSetInputMode(g->window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - } - - } else { - draw_ui(&ui_attrib, button_left); - draw_ui(&ui_attrib, button_middle); - draw_ui(&ui_attrib, button_right); - } - - del_buffer(button_left); - del_buffer(button_middle); - del_buffer(button_right); - - // RENDER LOGO // - //glUniformMatrix4fv(logo_attrib.matrix, 2, GL_TRUE, matrix); - glUniform1i(ui_attrib.sampler, 5); - GLuint logo_buffer = gen_logo_buffer(g->width/2, (g->height/4)*3, 128 * g->scale, 8); - draw_logo(&ui_attrib, logo_buffer); - del_buffer(logo_buffer); - - - - // RENDER TEXT // *optimisation needed for the render of lines. \n maybe? - snprintf(text_buffer, 1024, "Omicron version 0.6 `Menupdate`"); + snprintf(text_buffer, 1024, "Omicron version 0.7 `Tweaky Update`"); render_text(&text_attrib, ALIGN_LEFT, tx, ty, ts, text_buffer, g->width, g->height); //ty -= ts * 2; + snprintf(text_buffer, 1024, "Alpha"); + render_text(&text_attrib, ALIGN_LEFT, tx, ts+2, ts, text_buffer, g->width, g->height); - snprintf(text_buffer, 1024, "Credits:"); - render_text(&text_attrib, ALIGN_LEFT, g->width - ts*20, (ts+2)*3, ts, text_buffer, g->width, g->height); + if (menu_id == 0) { + // BUTTON TEXT // + + snprintf(text_buffer, 1024, "Play"); + render_text(&text_attrib, ALIGN_LEFT, g->width/2-ts*1.5, g->height/2, ts, text_buffer, g->width, g->height); + + snprintf(text_buffer, 1024, "X"); + render_text(&text_attrib, ALIGN_LEFT, g->width/2+ts*3-1, g->height/2-24*2, ts, text_buffer, g->width, g->height); + + snprintf(text_buffer, 1024, "Conf"); + render_text(&text_attrib, ALIGN_LEFT, g->width/2-ts*3-1, g->height/2-24*2, ts, text_buffer, g->width, g->height); + + + // MATRIX FOR GUI // + float matrix[16]; + set_matrix_2d(matrix, g->width, g->height); + glUseProgram(ui_attrib.program); + glUniformMatrix4fv(ui_attrib.matrix, 1, GL_FALSE, matrix); + glUniform1i(ui_attrib.sampler, 4); + glUniform1i(ui_attrib.extra1, 0); + + // BUTTONS // + + // PLAY + GLuint button_left_on = gen_ui_buffer(g->width/2 - (24 * g->scale)*2, g->height/2, 24 * g->scale, 10); + GLuint button_middle_on = gen_ui_buffer(g->width/2, g->height/2, 24 * g->scale, 11); + GLuint button_right_on = gen_ui_buffer(g->width/2 + (24 * g->scale)*2, g->height/2, 24 * g->scale, 12); - snprintf(text_buffer, 1024, "- Michael Fogleman"); - render_text(&text_attrib, ALIGN_LEFT, g->width - ts*20, (ts+2)*2, ts, text_buffer, g->width, g->height); - - snprintf(text_buffer, 1024, "- Twetzel"); - render_text(&text_attrib, ALIGN_LEFT, g->width - ts*20, (ts+2)*1, ts, text_buffer, g->width, g->height); - - - //snprintf(text_buffer, 1024, "sample test"); - //render_text(&text_attrib, ALIGN_RIGHT, tx, ty, ts, text_buffer, g->width, g->height); + GLuint button_left = gen_ui_buffer(g->width/2 - (24 * g->scale)*2, g->height/2, 24 * g->scale, 6); + GLuint button_middle = gen_ui_buffer(g->width/2, g->height/2, 24 * g->scale, 7); + GLuint button_right = gen_ui_buffer(g->width/2 + (24 * g->scale)*2, g->height/2, 24 * g->scale, 8); + + // EXIT + GLuint button_exit_on = gen_ui_buffer(g->width/2 + (24 * g->scale)*2, g->height/2 - (24 * g->scale)*2, 24 * g->scale, 9); + GLuint button_exit = gen_ui_buffer(g->width/2 + (24 * g->scale)*2, g->height/2 - (24 * g->scale)*2, 24 * g->scale, 5); + + // CONF + GLuint button_conf_left_on = gen_ui_buffer(g->width/2 - (24 * g->scale)*2, g->height/2 - (24 * g->scale)*2, 24 * g->scale, 10); + GLuint button_conf_right_on = gen_ui_buffer(g->width/2, g->height/2 - (24 * g->scale)*2, 24 * g->scale, 12); + + GLuint button_conf_right = gen_ui_buffer(g->width/2 - (24 * g->scale)*2, g->height/2 - (24 * g->scale)*2, 24 * g->scale, 6); + GLuint button_conf_left = gen_ui_buffer(g->width/2, g->height/2 - (24 * g->scale)*2, 24 * g->scale, 8); + + // PLAY + if (cx > (g->width/2-24*3) && cx < (g->width/2+24*3) && cy > (g->height/2-22) && cy < (g->height/2+22)) { + draw_ui(&ui_attrib, button_left_on); + draw_ui(&ui_attrib, button_middle_on); + draw_ui(&ui_attrib, button_right_on); + + // CLICK ACTION + if (state == GLFW_PRESS) { + game_state = 1; + glfwSetInputMode(g->window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + } + + } else { + draw_ui(&ui_attrib, button_left); + draw_ui(&ui_attrib, button_middle); + draw_ui(&ui_attrib, button_right); + } + + // EXIT + if (cx > (g->width/2+24) && cx < (g->width/2+24*3) && cy > (g->height/2+24) && cy < (g->height/2+24*3)) { + draw_ui(&ui_attrib, button_exit_on); + + if (state == GLFW_PRESS) { + // CLICK ACTION + printf("\n\n[Omicron] The game is closing ... Have a good day!\n"); + db_save_state(s->x, s->y, s->z, s->rx, s->ry); + db_close(); + db_disable(); + client_stop(); + client_disable(); + del_buffer(sky_buffer); + delete_all_chunks(); + delete_all_players(); + + //glfwTerminate(); + curl_global_cleanup(); + return 0; + } + + } else { + draw_ui(&ui_attrib, button_exit); + } + + // CONF + if (cx > (g->width/2-24*3) && cx < (g->width/2+24) && cy > (g->height/2+24) && cy < (g->height/2+24*3)) { + draw_ui(&ui_attrib, button_conf_left_on); + draw_ui(&ui_attrib, button_conf_right_on); + + if (state == GLFW_PRESS) { + // CLICK ACTION + menu_id = 1; + } + + } else { + draw_ui(&ui_attrib, button_conf_left); + draw_ui(&ui_attrib, button_conf_right); + } + del_buffer(button_left); + del_buffer(button_middle); + del_buffer(button_right); + + // RENDER LOGO // + //glUniformMatrix4fv(logo_attrib.matrix, 2, GL_TRUE, matrix); + glUniform1i(ui_attrib.sampler, 5); + GLuint logo_buffer = gen_logo_buffer(g->width/2, (g->height/5)*4, 256 * g->scale, 8); + draw_logo(&ui_attrib, logo_buffer); + del_buffer(logo_buffer); + + snprintf(text_buffer, 1024, "Credits:"); + render_text(&text_attrib, ALIGN_LEFT, g->width - ts*20, (ts+2)*3, ts, text_buffer, g->width, g->height); + + snprintf(text_buffer, 1024, "- Michael Fogleman"); + render_text(&text_attrib, ALIGN_LEFT, g->width - ts*20, (ts+2)*2, ts, text_buffer, g->width, g->height); + + snprintf(text_buffer, 1024, "- Twetzel"); + render_text(&text_attrib, ALIGN_LEFT, g->width - ts*20, (ts+2)*1, ts, text_buffer, g->width, g->height); + + //snprintf(text_buffer, 1024, "sample test"); + //render_text(&text_attrib, ALIGN_RIGHT, tx, ty, ts, text_buffer, g->width, g->height); + + } else if (menu_id == 1) { + + // BUTTON TEXT // + + snprintf(text_buffer, 1024, "Configuration"); + render_text(&text_attrib, ALIGN_LEFT, g->width/2-6*ts, g->height/2+ts*6, ts, text_buffer, g->width, g->height); + + snprintf(text_buffer, 1024, "* Show lights : %d", SHOW_LIGHTS); + render_text(&text_attrib, ALIGN_LEFT, g->width/2-ts*10, g->height/2+ts*2, ts, text_buffer, g->width, g->height); + + snprintf(text_buffer, 1024, "* Show crosshair : %d", SHOW_CROSSHAIRS); + render_text(&text_attrib, ALIGN_LEFT, g->width/2-ts*10, g->height/2+ts, ts, text_buffer, g->width, g->height); + + snprintf(text_buffer, 1024, "* Show infotext : %d", SHOW_INFO_TEXT); + render_text(&text_attrib, ALIGN_LEFT, g->width/2-ts*10, g->height/2, ts, text_buffer, g->width, g->height); + + snprintf(text_buffer, 1024, "* Show chat : %d", SHOW_CHAT_TEXT); + render_text(&text_attrib, ALIGN_LEFT, g->width/2-ts*10, g->height/2-ts, ts, text_buffer, g->width, g->height); + + snprintf(text_buffer, 1024, "* Show nametags : %d", SHOW_PLAYER_NAMES); + render_text(&text_attrib, ALIGN_LEFT, g->width/2-ts*10, g->height/2-ts*2, ts, text_buffer, g->width, g->height); + + snprintf(text_buffer, 1024, "* Font size : %d", FONT_SIZE); + render_text(&text_attrib, ALIGN_LEFT, g->width/2-ts*10, g->height/2-ts*3, ts, text_buffer, g->width, g->height); + + snprintf(text_buffer, 1024, "X"); + render_text(&text_attrib, ALIGN_LEFT, g->width/2+ts*11+5, g->height/2+ts*6-6, ts, text_buffer, g->width, g->height); + + + // MATRIX FOR GUI // + float matrix[16]; + set_matrix_2d(matrix, g->width, g->height); + glUseProgram(ui_attrib.program); + glUniformMatrix4fv(ui_attrib.matrix, 1, GL_FALSE, matrix); + glUniform1i(ui_attrib.sampler, 4); + glUniform1i(ui_attrib.extra1, 0); + + // BUTTONS // + + GLint offset = (24 * g->scale); + + // LEAVE BUTTON + GLuint button_exit_on = gen_ui_buffer(g->width/2 + 8 * offset - 9, g->height/2 + 4 * offset - 6, offset, 9); + GLuint button_exit = gen_ui_buffer(g->width/2 + 8 * offset - 9, g->height/2 + 4 * offset - 6, offset, 5); + + // LEAVE FUNCTION *sry long string ahead + if (cx > (g->width/2 + 8 * offset - 9 - 24) && cx < (g->width/2 + 8 * offset - 9 + 24) && cy > (g->height/2 - 4 * offset + 6 - 24) && cy < (g->height/2 - 4 * offset + 6 + 24)) { + draw_ui(&ui_attrib, button_exit_on); + + if (state == GLFW_PRESS) { + menu_id = 0; + } + + } else { + draw_ui(&ui_attrib, button_exit); + } + + // BACKGROUND + GLuint corner_uleft = gen_ui_buffer(g->width/2 - 8 * offset, g->height/2 + 4 * offset, offset, 17); + GLuint corner_dleft = gen_ui_buffer(g->width/2 - 8 * offset, g->height/2 - 3 * offset, offset, 19); + GLuint corner_uright = gen_ui_buffer(g->width/2 + 8 * offset, g->height/2 + 4 * offset, offset, 18); + GLuint button_dright = gen_ui_buffer(g->width/2 + 8 * offset, g->height/2 - 3 * offset, offset, 20); + + draw_ui(&ui_attrib, corner_uleft); + draw_ui(&ui_attrib, corner_dleft); + draw_ui(&ui_attrib, corner_uright); + draw_ui(&ui_attrib, button_dright); + + for (int i = 0; i < 7; ++i) { + GLuint top_bar = gen_ui_buffer(g->width/2 + i * 2 * offset - 6 * offset, g->height/2 + 4 * offset, offset, 21); + GLuint bottom_bar = gen_ui_buffer(g->width/2 + i * 2 * offset - 6 * offset, g->height/2 - 3 * offset, offset, 24); + draw_ui(&ui_attrib, top_bar); + draw_ui(&ui_attrib, bottom_bar); + + for (int j = 0; j < 3; ++j) { + GLuint filler = gen_ui_buffer(g->width/2 + i * 2 * offset - 6 * offset, g->height/2 + 2 * offset - j * 2 * offset, offset, 25); + draw_ui(&ui_attrib, filler); + } + } + + for (int j = 0; j < 3; ++j) { + GLuint left_bar = gen_ui_buffer(g->width/2 - 8 * offset, g->height/2 + 2 * offset - j * 2 * offset, offset, 23); + GLuint right_bar = gen_ui_buffer(g->width/2 + 8 * offset, g->height/2 + 2 * offset - j * 2 * offset, offset, 22); + draw_ui(&ui_attrib, left_bar); + draw_ui(&ui_attrib, right_bar); + } + + + del_buffer(button_exit); + del_buffer(button_exit_on); + } + // RENDER BACKGROUND // glUniform1i(ui_attrib.sampler, 6); - GLuint bg_buffer = gen_logo_buffer(g->width/2, g->height/2, g->width * g->scale, 1); + GLuint bg_buffer = gen_logo_buffer(g->width/2, g->height/2, (g->width * g->scale)*0.75, 1); draw_ui(&ui_attrib, bg_buffer); del_buffer(bg_buffer); - - // SWAP AND POLL // - glfwSwapBuffers(g->window); - glfwPollEvents(); - if (glfwWindowShouldClose(g->window)) { - running = 0; - break; - } - if (g->mode_changed) { - g->mode_changed = 0; - break; - } } @@ -3302,17 +3680,7 @@ int main(int argc, char **argv) { // SECOND MODE (NORMAL) // // -------------------- // - if (game_state == 1) { - if (INFINITE_STUFF == 1) { - g->inventory.count[items[g->item_index]] = 16; - //printf("%d %d\n", items[g->item_index], (int) g->inventory.count[items[g->item_index]]); - } - - // WINDOW SIZE AND SCALE // - g->scale = get_scale_factor(); - glfwGetFramebufferSize(g->window, &g->width, &g->height); - glViewport(0, 0, g->width, g->height); // FRAME RATE // if (g->time_changed) { @@ -3327,33 +3695,8 @@ int main(int argc, char **argv) { dt = MIN(dt, 0.2); dt = MAX(dt, 0.0); previous = now; - - // HANDLE MOUSE INPUT // - handle_mouse_input(); - // HANDLE MOVEMENT // - handle_movement(dt); - - // HANDLE DATA FROM SERVER // - char *buffer = client_recv(); - if (buffer) { - parse_buffer(buffer); - free(buffer); - } - - // FLUSH DATABASE // - if (now - last_commit > COMMIT_INTERVAL) { - last_commit = now; - db_commit(); - } - - // SEND POSITION TO SERVER // - if (now - last_update > 0.1) { - last_update = now; - client_position(s->x, s->y, s->z, s->rx, s->ry); - } - // PREPARE TO RENDER // update_sky_tint(); g->observe1 = g->observe1 % g->player_count; @@ -3376,7 +3719,7 @@ int main(int argc, char **argv) { render_signs(&text_attrib, player); render_sign(&text_attrib, player); render_players(&block_attrib, player); - + // RENDER HUD // glClear(GL_DEPTH_BUFFER_BIT); if (SHOW_CROSSHAIRS) { @@ -3386,12 +3729,12 @@ int main(int argc, char **argv) { float ts = FONT_SIZE * g->scale; float tx = ts / 2; float ty = g->height - ts; + float tyb = ts; if (SHOW_ITEM) { render_item(&block_attrib); render_item(&tblock_attrib); render_item_count(&text_attrib, ts); } - //render_gui_texture(&ui_attrib); // RENDER TEXT // if (SHOW_INFO_TEXT) { @@ -3399,61 +3742,38 @@ int main(int argc, char **argv) { char am_pm = hour < 12 ? 'a' : 'p'; hour = hour % 12; hour = hour ? hour : 12; - snprintf( - text_buffer, 1024, - "(%d, %d) (%.2f, %.2f, %.2f) [%d, %d, %d] %d%cm %dfps", - chunked(s->x), chunked(s->z), s->x, s->y, s->z, - g->player_count, g->chunk_count, - face_count * 2, hour, am_pm, fps.fps); + + // First line + snprintf(text_buffer, 1024, "%d fps | X=%.2f Y=%.2f Z=%.2f | ChunkX=%d ChunkZ=%d", + fps.fps, s->x, s->y, s->z, chunked(s->x), chunked(s->z)); render_text(&text_attrib, ALIGN_LEFT, tx, ty, ts, text_buffer, g->width, g->height); - ty -= ts * 2; + + // Second line + snprintf(text_buffer, 1024, "%d %cm | Players=%d | Chunks=%d | Faces=%d", + hour, am_pm, g->player_count, g->chunk_count, face_count * 2); + render_text(&text_attrib, ALIGN_LEFT, tx, ty-ts*2, ts, text_buffer, g->width, g->height); + + + //ty -= ts * 2; } - if (SHOW_CHAT_TEXT) { + if (SHOW_CHAT_TEXT==1) { for (int i = 0; i < MAX_MESSAGES; i++) { int index = (g->message_index + i) % MAX_MESSAGES; if (strlen(g->messages[index])) { - render_text(&text_attrib, ALIGN_LEFT, tx, ty, ts, + render_text(&text_attrib, ALIGN_LEFT, tx, tyb+ts*2, ts, g->messages[index], g->width, g->height); - ty -= ts * 2; + tyb += ts * 2; } } } - if (g->typing) { - snprintf(text_buffer, 1024, "> %s", g->typing_buffer); - render_text(&text_attrib, ALIGN_LEFT, tx, ty, ts, text_buffer, - g->width, g->height); - ty -= ts * 2; - } - if (SHOW_PLAYER_NAMES) { - if (player != me) { - render_text(&text_attrib, ALIGN_CENTER, - g->width / 2, ts, ts, player->name, - g->width, g->height); - } - Player *other = player_crosshair(player); - if (other) { - render_text(&text_attrib, ALIGN_CENTER, - g->width / 2, g->height / 2 - ts - 24, ts, - other->name, g->width, g->height); - } - } - - // RETURN TO MENU WHEN PRESSING ESCAPE - int esc = glfwGetKey(g->window, GLFW_KEY_ESCAPE); - if (esc == GLFW_PRESS) { - game_state = 0; - // Clear screen - glClearColor(0.0f, 0.0f, 0.0f, 1.0f ); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - } - - + + // RENDER PICTURE IN PICTURE // if (g->observe2) { player = g->players + g->observe2; - int pw = 256 * g->scale; - int ph = 256 * g->scale; + int pw = 64 * g->scale; // 256 seems to slow the game down + int ph = 64 * g->scale; // what's this for? int offset = 32 * g->scale; int pad = 3 * g->scale; int sw = pw + pad * 2; @@ -3484,37 +3804,173 @@ int main(int argc, char **argv) { g->width, g->height); } } + + if (inventory==0) { + if (INFINITE_STUFF == 1) { + g->inventory.count[items[g->item_index]] = 16; + //printf("%d %d\n", items[g->item_index], (int) g->inventory.count[items[g->item_index]]); + } - // SWAP AND POLL // - glfwSwapBuffers(g->window); - glfwPollEvents(); - if (glfwWindowShouldClose(g->window)) { - running = 0; - break; - } - if (g->mode_changed) { - g->mode_changed = 0; - break; + // HANDLE MOUSE INPUT // + handle_mouse_input(); + + + // HANDLE MOVEMENT // + handle_movement(dt); + + + if (g->typing) { + snprintf(text_buffer, 1024, "> %s_", g->typing_buffer); + render_text(&text_attrib, ALIGN_LEFT, tx, ts, ts, text_buffer, + g->width, g->height); + //tyb += ts * 2; + } + if (SHOW_PLAYER_NAMES) { + if (player != me) { + render_text(&text_attrib, ALIGN_CENTER, + g->width / 2, ts, ts, player->name, + g->width, g->height); + } + Player *other = player_crosshair(player); + if (other) { + render_text(&text_attrib, ALIGN_CENTER, + g->width / 2, g->height / 2 - ts - 24, ts, + other->name, g->width, g->height); + } + } + + // RETURN TO MENU WHEN PRESSING ESCAPE + int esc = glfwGetKey(g->window, GLFW_KEY_ESCAPE); + if (esc == GLFW_PRESS) { + game_state = 0; + // Clear screen + glClearColor(0.0f, 0.0f, 0.0f, 1.0f ); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + + // ENTER INVENTORY WHEN PRESSING I + int inv = glfwGetKey(g->window, GLFW_KEY_I); + + // Avoid entering inventory when typing in chat + if (!g->typing) { + if (inv == GLFW_PRESS) { + i_pressed = 1; + } + + // Enter inventory on key release to avoid fast toggle + if (inv == GLFW_RELEASE && i_pressed == 1) { + //inv = GLFW_RELEASE; + inventory = 1; + i_pressed = 0; + // Clear screen + glClearColor(0.0f, 0.0f, 0.0f, 1.0f ); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + } + + // OUTPUT IN TERMINAL // + //advance_cursor(); + } + + if (inventory==1) { + // TODO: Allow player to fall when inside inventory + + // RENDER HUD // + char text_buffer[1024]; + float ts = FONT_SIZE * g->scale; + float tx = ts / 2; + float ty = g->height - ts; + + // HANDLE MOUSE INPUT // + handle_mouse_input_in_menu(); + + // RENDER SOME TEXT + snprintf(text_buffer, 1024, "Inventory"); + render_text(&text_attrib, ALIGN_LEFT, g->width/2-4*ts, g->height/2+6*ts, ts, text_buffer, g->width, g->height); + + // LEAVE INVENTORY WHEN PRESSING I + int inv = glfwGetKey(g->window, GLFW_KEY_I); + + if (inv == GLFW_PRESS) { + i_pressed = 1; + } + if (inv == GLFW_RELEASE && i_pressed == 1) { + //inv = GLFW_RELEASE; + inventory = 0; + i_pressed = 0; + // Clear screen + glClearColor(0.0f, 0.0f, 0.0f, 1.0f ); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glfwSetInputMode(g->window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + } + + // MATRIX FOR GUI // + float matrix[16]; + set_matrix_2d(matrix, g->width, g->height); + glUseProgram(ui_attrib.program); + glUniformMatrix4fv(ui_attrib.matrix, 1, GL_FALSE, matrix); + glUniform1i(ui_attrib.sampler, 4); + glUniform1i(ui_attrib.extra1, 0); + + // INVENTORY // + + GLint offset = (24 * g->scale); + + // BACKGROUND + GLuint corner_uleft = gen_ui_buffer(g->width/2 - 8 * offset, g->height/2 + 4 * offset, offset, 17); + GLuint corner_dleft = gen_ui_buffer(g->width/2 - 8 * offset, g->height/2 - 3 * offset, offset, 19); + GLuint corner_uright = gen_ui_buffer(g->width/2 + 8 * offset, g->height/2 + 4 * offset, offset, 18); + GLuint button_dright = gen_ui_buffer(g->width/2 + 8 * offset, g->height/2 - 3 * offset, offset, 20); + + draw_ui(&ui_attrib, corner_uleft); + draw_ui(&ui_attrib, corner_dleft); + draw_ui(&ui_attrib, corner_uright); + draw_ui(&ui_attrib, button_dright); + + for (int i = 0; i < 7; ++i) { + GLuint top_bar = gen_ui_buffer(g->width/2 + i * 2 * offset - 6 * offset, g->height/2 + 4 * offset, offset, 21); + GLuint bottom_bar = gen_ui_buffer(g->width/2 + i * 2 * offset - 6 * offset, g->height/2 - 3 * offset, offset, 24); + draw_ui(&ui_attrib, top_bar); + draw_ui(&ui_attrib, bottom_bar); + + for (int j = 0; j < 3; ++j) { + GLuint filler = gen_ui_buffer(g->width/2 + i * 2 * offset - 6 * offset, g->height/2 + 2 * offset - j * 2 * offset, offset, 25); + draw_ui(&ui_attrib, filler); + } + } + + for (int j = 0; j < 3; ++j) { + GLuint left_bar = gen_ui_buffer(g->width/2 - 8 * offset, g->height/2 + 2 * offset - j * 2 * offset, offset, 23); + GLuint right_bar = gen_ui_buffer(g->width/2 + 8 * offset, g->height/2 + 2 * offset - j * 2 * offset, offset, 22); + draw_ui(&ui_attrib, left_bar); + draw_ui(&ui_attrib, right_bar); + } + + // ITEMS // + //for(int i = 0; i < 24; ++i) { + // GLuint buffer = gen_cube_buffer(20, 20, 20, 5, 25); + // draw_cube(&block_attrib, buffer); + // del_buffer(buffer); + //} + } - // OUTPUT IN TERMINAL // - //advance_cursor(); } - } + } - // SHUTDOWN // There's a segfault in this sequence - printf("\n\n[Omicron] The game is closing ... Have a good day!\n"); - db_save_state(s->x, s->y, s->z, s->rx, s->ry); - db_close(); // suspect #1 - db_disable(); // suspect #2 - client_stop(); - client_disable(); - del_buffer(sky_buffer); - delete_all_chunks(); // suspect #3 - delete_all_players(); - } + // SHUTDOWN // + printf("\n\n[Omicron] The game is closing... Have a good day!\n"); + db_save_state(s->x, s->y, s->z, s->rx, s->ry); + db_close(); + db_disable(); + client_stop(); + client_disable(); + del_buffer(sky_buffer); + delete_all_chunks(); + delete_all_players(); + } - glfwTerminate(); - curl_global_cleanup(); - return 0; + glfwTerminate(); // Causes segfaults??? + curl_global_cleanup(); + return 0; } diff --git a/src/worldgen/base_terrain.c b/src/worldgen/base_terrain.c index cf1de7f..e4cd74f 100644 --- a/src/worldgen/base_terrain.c +++ b/src/worldgen/base_terrain.c @@ -31,7 +31,7 @@ void generateBaseTerrain(int dx, int dz, int x, int z, int start_h, int h, int f } } - + // Caves for (int y = 1; y < 37; y++) { if (simplex3( @@ -46,5 +46,6 @@ void generateBaseTerrain(int dx, int dz, int x, int z, int start_h, int h, int f func(x, y, z, 0 * flag, arg); } } + } } diff --git a/src/worldgen/biome_temperate.c b/src/worldgen/biome_temperate.c index 9d1e384..0ba174d 100644 --- a/src/worldgen/biome_temperate.c +++ b/src/worldgen/biome_temperate.c @@ -7,7 +7,7 @@ void generateTemperate(int dx, int dz, int x, int z, int start_h, int h, int fla for (int y = start_h; y < h - 1; y++) { func(x, y, z, Item_STONE * flag, arg); } - for (int y = 0; y < 5; y++) { + for (int y = 0; y < 3; y++) { func(x, h-y-1, z, Item_SAND * flag, arg); } diff --git a/src/worldgen/world.c b/src/worldgen/world.c index abffe68..98f1573 100644 --- a/src/worldgen/world.c +++ b/src/worldgen/world.c @@ -33,12 +33,28 @@ void create_world(int p, int q, world_func func, void *arg) { int mh = g * simplex2(-x * 0.0005, -z * 0.0005, 2, 16.0, 2); mh += simplex2(-x * 0.0002, -z * 0.0002, 2, 16.0, 2) * simplex2(-x * 0.002, -z * 0.002, 2, 16.0, 2) * 100; - - mh += 16; + + mh += simplex2(-x * 0.02, -z * 0.02, 3, 8.0, 2); + + if (simplex2(-x * 0.0004, -z * 0.0004, 4, 4.0, 3)> 0.59) { + mh += 8; + } int h = f * mh; - + // Floating balls test + + /*for (int y = 0; y < 25; y++) { + if (simplex3( + x * 0.001, (y+h) * 0.001, z * 0.001, 6, 1, 2) > 0.52) + { + if (y < 255) { + func(x, (y+h), z, Item_COLOR_13 * flag, arg); + } + } + }*/ + + // Ocean system (generates water under y == 45) for (int y = 22; y < 45; y++) { func(x, y, z, Item_WATER * flag, arg); @@ -46,9 +62,9 @@ void create_world(int p, int q, world_func func, void *arg) { // ice on frigid biomes float biomen = simplex3(-x * 0.0005 * (1 / BIOME_SIZE), -z * 0.0005 * (1 / BIOME_SIZE), q * 0.001, 2, 16.0, 1); - if(biomen > (4.0f/5.0f) && biomen < (5.0f/5.0f)) { + if(biomen > (1.0f/6.0f) && biomen < (2.0f/6.0f)) { // 2 ice layers on water - if (simplex2(x * 0.0004, z * 0.0004, 8, 1.5, 2) > 0.6) { + if (simplex2(x * 0.0004, z * 0.0004, 8, 1.5, 2) > 0.59) { func(x, 43, z, Item_ICE * flag, arg); func(x, 44, z, Item_ICE * flag, arg); } @@ -78,7 +94,7 @@ void create_world(int p, int q, world_func func, void *arg) { // clouds - for (int y = 120; y < 200; y++) { + for (int y = 100; y < 180; y++) { if (simplex3( x * 0.001, y * 0.004, z * 0.001, 6, 1, 2) > 0.7) { @@ -108,23 +124,23 @@ Biome biome_at_pos(int q, int x, int z) { Biome biome = Biome_max; if(biomen > (1.0f/6.0f)) { - biome = Biome_TEMPERATE; + biome = Biome_TAIGA; } if(biomen > (2.0f/6.0f)) { - biome = Biome_DESERT; + biome = Biome_SWAMP; } if(biomen > (3.0f/6.0f)) { - biome = Biome_RAINFOREST; + biome = Biome_TEMPERATE; } if(biomen > (4.0f/6.0f)) { - biome = Biome_TAIGA; + biome = Biome_RAINFOREST; } if(biome == (5.0/6.0)) { - biome = Biome_MESA; + biome = Biome_DESERT; } if(biome == (Biome_max)) { - biome = Biome_SWAMP; + biome = Biome_MESA; } return biome; } diff --git a/textures/background-0.5-old.png b/textures/background-0.5-old.png new file mode 100644 index 0000000..ddf2a60 Binary files /dev/null and b/textures/background-0.5-old.png differ diff --git a/textures/background.png b/textures/background.png index a99c8be..b02e295 100644 Binary files a/textures/background.png and b/textures/background.png differ diff --git a/textures/font-alt.png b/textures/font-alt.png new file mode 100644 index 0000000..01ce986 Binary files /dev/null and b/textures/font-alt.png differ diff --git a/textures/font.png b/textures/font.png index 4c207ad..1f7cb1f 100644 Binary files a/textures/font.png and b/textures/font.png differ diff --git a/textures/logo-ugly.png b/textures/logo-ugly.png new file mode 100644 index 0000000..dd90d59 Binary files /dev/null and b/textures/logo-ugly.png differ diff --git a/textures/logo.png b/textures/logo.png index dd90d59..a77f833 100644 Binary files a/textures/logo.png and b/textures/logo.png differ diff --git a/textures/sign.png b/textures/sign.png index 3f01d87..0ff9551 100644 Binary files a/textures/sign.png and b/textures/sign.png differ diff --git a/textures/texture.png b/textures/texture.png index c408fee..1d70d8a 100644 Binary files a/textures/texture.png and b/textures/texture.png differ diff --git a/textures/ui.png b/textures/ui.png index 2360eb2..08a9a1c 100644 Binary files a/textures/ui.png and b/textures/ui.png differ