DragonblocksAlpha-*.zip
src/version.h
screenshot-*.png
+*.conf
void main()
{
outColor = texture(textures[int(fragmentTextureIndex + 0.5)], fragmentTextureCoords) * vec4(fragmentColor, 1.0);
- outColor.rgb = mix(outColor.rgb, fogColor, clamp(length(fragmentPosition - cameraPos) / 255.0, 0.0, 1.0));
+ outColor.rgb = mix(outColor.rgb, fogColor, clamp(length(fragmentPosition - cameraPos) / RENDER_DISTANCE, 0.0, 1.0));
if (outColor.a == 0.0)
discard;
set(COMMON_SOURCES
${DEPS_SOURCES}
+ config.c
day.c
environment.c
map.c
client/camera.c
client/client.c
client/client_commands.c
+ client/client_config.c
client/client_map.c
client/client_node.c
client/client_player.c
server/mapgen.c
server/server.c
server/server_commands.c
+ server/server_config.c
server/server_map.c
server/trees.c
server/voxelctx.c
--- /dev/null
+#include "config.h"
+#include "client/client_config.h"
+
+struct ClientConfig client_config = {
+ .antialiasing = 4,
+ .mipmap = true,
+ .render_distance = 255.0,
+};
+
+__attribute__((constructor)) static void client_config_init()
+{
+ config_read("client.conf", (ConfigEntry[]) {
+ {
+ .type = CT_UINT,
+ .key = "antialiasing",
+ .value = &client_config.antialiasing,
+ },
+ {
+ .type = CT_BOOL,
+ .key = "mipmap",
+ .value = &client_config.mipmap,
+ },
+ {
+ .type = CT_FLOAT,
+ .key = "render_distance",
+ .value = &client_config.render_distance,
+ }
+ }, 3);
+}
+
--- /dev/null
+#ifndef _CLIENT_CONFIG_H_
+#define _CLIENT_CONFIG_H_
+
+#include <stdbool.h>
+
+extern struct ClientConfig {
+ unsigned int antialiasing;
+ bool mipmap;
+ double render_distance;
+} client_config;
+
+#endif
#include "client/facecache.h"
#include "client/client_map.h"
#include "client/client_player.h"
+#include "client/debug_menu.h"
#include "util.h"
#define MAX_BLOCK_REQUESTS 4
#include <stdio.h>
#include <GL/glew.h>
#include <GL/gl.h>
+#include "client/client_config.h"
+#include "client/client_map.h"
#include "client/client_player.h"
#include "client/debug_menu.h"
#include "client/gui.h"
DME_FULLSCREEN,
DME_OPENGL,
DME_GPU,
+ DME_ANTIALIASING,
+ DME_MIPMAP,
+ DME_RENDER_DISTANCE,
+ DME_SIMULATION_DISTANCE,
DME_COUNT,
} DebugMenuEntry;
{
gui_set_text(gui_elements[DME_GPU], format_string("%s", glGetString(GL_RENDERER)));
}
+
+void debug_menu_update_antialiasing()
+{
+ gui_set_text(gui_elements[DME_ANTIALIASING], client_config.antialiasing > 1
+ ? format_string("antialiasing: %u samples", client_config.antialiasing)
+ : format_string("antialiasing: disabled")
+ );
+}
+
+void debug_menu_update_mipmap()
+{
+ gui_set_text(gui_elements[DME_MIPMAP], format_string("mipmap: %s", client_config.mipmap ? "enabled" : "disabled"));
+}
+
+void debug_menu_update_render_distance()
+{
+ gui_set_text(gui_elements[DME_RENDER_DISTANCE], format_string("render distance: %.1lf", client_config.render_distance));
+}
+
+void debug_menu_update_simulation_distance()
+{
+ gui_set_text(gui_elements[DME_SIMULATION_DISTANCE], format_string("simulation distance: %u", client_map.simulation_distance));
+}
void debug_menu_update_fullscreen();
void debug_menu_update_opengl();
void debug_menu_update_gpu();
+void debug_menu_update_antialiasing();
+void debug_menu_update_mipmap();
+void debug_menu_update_render_distance();
+void debug_menu_update_simulation_distance();
#endif
debug_menu_update_fullscreen();
debug_menu_update_opengl();
debug_menu_update_gpu();
+ debug_menu_update_antialiasing();
+ debug_menu_update_mipmap();
+ debug_menu_update_render_distance();
+ debug_menu_update_simulation_distance();
crosshair_init();
#include <stdio.h>
#include "client/camera.h"
#include "client/client.h"
+#include "client/client_config.h"
#include "client/frustum.h"
#include "client/scene.h"
#include "client/shader.h"
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &scene.max_texture_units);
- char max_texture_units_def[BUFSIZ];
- sprintf(max_texture_units_def, "#define MAX_TEXTURE_UNITS %d\n", scene.max_texture_units);
+ char *shader_defs = format_string(
+ "#define MAX_TEXTURE_UNITS %d\n"
+ "#define RENDER_DISTANCE %lf\n",
+ scene.max_texture_units,
+ client_config.render_distance
+ );
- if (! shader_program_create(RESSOURCEPATH "shaders/3d", &scene.prog, max_texture_units_def)) {
+ if (! shader_program_create(RESSOURCEPATH "shaders/3d", &scene.prog, shader_defs)) {
fprintf(stderr, "Failed to create 3D shader program\n");
return false;
}
+ free(shader_defs);
+
scene.loc_model = glGetUniformLocation(scene.prog, "model");
scene.loc_VP = glGetUniformLocation(scene.prog, "VP");
scene.loc_daylight = glGetUniformLocation(scene.prog, "daylight");
glProgramUniform1iv(scene.prog, glGetUniformLocation(scene.prog, "textures"), scene.max_texture_units, texture_indices);
scene.fov = 86.1f;
- scene.render_distance = 255.0f;
return true;
}
object_delete(obj);
} else {
f32 distance = sqrt(pow(obj->pos.x - camera.eye[0], 2) + pow(obj->pos.y - camera.eye[1], 2) + pow(obj->pos.z - camera.eye[2], 2));
- if (distance < scene.render_distance && object_before_render(obj, dtime)) {
+ if (distance < client_config.render_distance && object_before_render(obj, dtime)) {
if (obj->transparent)
bintree_insert(&scene.transparent_objects, &distance, obj);
else
void scene_on_resize(int width, int height)
{
- mat4x4_perspective(scene.projection, scene.fov / 180.0f * M_PI, (float) width / (float) height, 0.01f, scene.render_distance + 28.0f);
+ mat4x4_perspective(scene.projection, scene.fov / 180.0f * M_PI, (float) width / (float) height, 0.01f, client_config.render_distance + 28.0f);
}
GLuint scene_get_max_texture_units()
#include <stb/stb_image.h>
#include <stdbool.h>
#include <dragontype/list.h>
+#include "client/client_config.h"
#include "client/texture.h"
#include "util.h"
glBindTexture(GL_TEXTURE_2D, texture->id);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipmap ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (mipmap && client_config.mipmap) ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
#include <stdio.h>
#include <GL/glew.h>
#include <GL/gl.h>
+#include "client/client_config.h"
#include "client/debug_menu.h"
#include "client/game.h"
#include "client/gui.h"
return false;
}
- glfwWindowHint(GLFW_SAMPLES, 8);
+ glfwWindowHint(GLFW_SAMPLES, client_config.antialiasing);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include "config.h"
+
+void config_read(char *path, ConfigEntry *entries, size_t num_entries)
+{
+ FILE *f = fopen(path, "r");
+
+ if (! f)
+ return;
+
+ printf("Reading config from %s\n", path);
+
+ while (! feof(f)) {
+ char key[BUFSIZ];
+ fscanf(f, "%s", key);
+
+ bool found = false;
+ for (size_t i = 0; i < num_entries; i++) {
+ ConfigEntry *entry = &entries[i];
+ if (strcmp(key, entry->key) == 0) {
+ bool valid = false;
+
+ switch (entry->type) {
+ case CT_STRING: {
+ char value[BUFSIZ];
+
+ if (! fscanf(f, "%s", value))
+ break;
+
+ valid = true;
+ *(char **) entry->value = strdup(value);
+ } break;
+
+ case CT_INT:
+ if (fscanf(f, "%d", (int *) entry->value))
+ valid = true;
+
+ break;
+
+ case CT_UINT:
+ if (fscanf(f, "%u", (unsigned int *) entry->value))
+ valid = true;
+
+ break;
+
+ case CT_FLOAT:
+ if (fscanf(f, "%lf", (double *) entry->value))
+ valid = true;
+
+ break;
+
+ case CT_BOOL: {
+ char value[BUFSIZ];
+
+ if (! fscanf(f, "%s", value))
+ break;
+
+ valid = true;
+
+ if (strcmp(value, "on") == 0 || strcmp(value, "yes") == 0 || strcmp(value, "true") == 0)
+ *(bool *) entry->value = true;
+ else if (strcmp(value, "off") == 0 || strcmp(value, "no") == 0 || strcmp(value, "false") == 0)
+ *(bool *) entry->value = false;
+ else
+ valid = false;
+
+ } break;
+ }
+
+ if (! valid)
+ fprintf(stderr, "Invalid value for setting %s in %s\n", key, path);
+
+ found = true;
+ break;
+ }
+ }
+
+ if (! found)
+ fprintf(stderr, "Unknown setting %s in %s\n", key, path);
+ }
+}
--- /dev/null
+#ifndef _CONFIG_H_
+#define _CONFIG_H_
+
+#include <stddef.h>
+
+typedef enum
+{
+ CT_STRING,
+ CT_INT,
+ CT_UINT,
+ CT_FLOAT,
+ CT_BOOL,
+} ConfigType;
+
+typedef struct
+{
+ ConfigType type;
+ char *key;
+ void *value;
+} ConfigEntry;
+
+void config_read(char *path, ConfigEntry *entries, size_t num_entries);
+
+#endif
// start up the server after socket was created, then accept connections until interrupted, then shutdown server
static void server_run(int fd)
{
- server.config.simulation_distance = 10;
-
server.sockfd = fd;
pthread_rwlock_init(&server.clients_rwlck, NULL);
server.clients = list_create(NULL);
List clients; // Client * -> NULL map with all connected clients
pthread_rwlock_t players_rwlck; // lock to protect player list
List players; // char * -> Client * map with clients that have finished auth
- struct {
- u32 simulation_distance; // perimeter of the cube that players can see blocks in is simulation_distance * 2 + 1
- } config; // configuration, ToDo: read from config file
} Server;
typedef struct Client
#include "day.h"
#include "server/database.h"
#include "server/server.h"
+#include "server/server_config.h"
#include "server/server_map.h"
#include "perlin.h"
#include "util.h"
bool ret = write_u32(client->fd, CC_AUTH) && write_u8(client->fd, success);
if (ret && success)
ret = ret
- && write_u32(client->fd, CC_INFO) && write_u32(client->fd, client->server->config.simulation_distance) && write_s32(client->fd, seed)
+ && write_u32(client->fd, CC_INFO) && write_u32(client->fd, server_config.simulation_distance) && write_s32(client->fd, seed)
&& write_u32(client->fd, CC_SETPOS) && write_v3f64(client->fd, client->pos)
&& write_u32(client->fd, CC_TIMEOFDAY) && write_u64(client->fd, (u64) get_time_of_day());
pthread_mutex_unlock(&client->mtx);
--- /dev/null
+#include "config.h"
+#include "server/server_config.h"
+
+struct ServerConfig server_config = {
+ .simulation_distance = 10,
+};
+
+__attribute__((constructor)) static void server_config_init()
+{
+ config_read("server.conf", (ConfigEntry[]) {
+ {
+ .type = CT_UINT,
+ .key = "simulation_distance",
+ .value = &server_config.simulation_distance,
+ },
+ }, 1);
+}
+
--- /dev/null
+#ifndef _SERVER_CONFIG_H_
+#define _SERVER_CONFIG_H_
+
+extern struct ServerConfig {
+ unsigned int simulation_distance;
+} server_config;
+
+#endif
-#define _GNU_SOURCE
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "map.h"
#include "server/database.h"
#include "server/mapgen.h"
+#include "server/server_config.h"
#include "server/server_map.h"
#include "signal_handlers.h"
#include "util.h"
ITERATE_LIST(&server->players, pair) {
Client *client = pair->value;
- if (within_simulation_distance(client->pos, block->pos, server->config.simulation_distance))
+ if (within_simulation_distance(client->pos, block->pos, server_config.simulation_distance))
send_block(client, block);
}
pthread_rwlock_unlock(&server->players_rwlck);
// handle block request from client (thread safe)
void server_map_requested_block(Client *client, v3s32 pos)
{
- if (within_simulation_distance(client->pos, pos, server->config.simulation_distance)) {
+ if (within_simulation_distance(client->pos, pos, server_config.simulation_distance)) {
MapBlock *block = map_get_block(server_map.map, pos, true);
pthread_mutex_lock(&block->mtx);
void server_map_prepare_spawn()
{
s32 done = 0;
- s32 dist = server->config.simulation_distance;
+ s32 dist = server_config.simulation_distance;
s32 total = (dist * 2 + 1);
total *= total * total;
s32 last_percentage = -1;