Allow for different dimensions

This commit is contained in:
xtreme8000 2023-02-05 16:17:28 +01:00
parent 2a69b646de
commit bab1cc92c7
15 changed files with 116 additions and 58 deletions

View file

@ -20,12 +20,14 @@
#include <assert.h>
#include "daytime.h"
#include "game/game_state.h"
#include "util.h"
float daytime_brightness(float time) {
return glm_clamp(cos(daytime_celestial_angle(time) * 2.0F * GLM_PI) * 2.0F
+ 0.5F,
0.0F, 1.0F);
return (gstate.world.dimension == WORLD_DIM_OVERWORLD) ? glm_clamp(
cos(daytime_celestial_angle(time) * 2.0F * GLM_PI) * 2.0F + 0.5F,
0.0F, 1.0F) :
0.0F;
}
float daytime_celestial_angle(float time) {
@ -41,38 +43,41 @@ void daytime_sky_colors(float time, vec3 top_plane, vec3 bottom_plane,
vec3 atmosphere) {
assert(top_plane && bottom_plane && atmosphere);
float brightness_mul = daytime_brightness(time);
if(gstate.world.dimension == WORLD_DIM_OVERWORLD) {
float brightness_mul = daytime_brightness(time);
vec3 world_sky_color = {
0.6222222F - (0.7F / 3.0F) * 0.05F,
0.5F + (0.7F / 3.0F) * 0.1F,
1.0F,
};
vec3 world_sky_color = {
0.6222222F - (0.7F / 3.0F) * 0.05F,
0.5F + (0.7F / 3.0F) * 0.1F,
1.0F,
};
hsv2rgb(world_sky_color + 0, world_sky_color + 1, world_sky_color + 2);
glm_vec3_scale(world_sky_color, brightness_mul, world_sky_color);
hsv2rgb(world_sky_color + 0, world_sky_color + 1, world_sky_color + 2);
glm_vec3_scale(world_sky_color, brightness_mul, world_sky_color);
vec3 fog_color = {
0.7529412F * brightness_mul * 0.94F + 0.06F,
0.8470588F * brightness_mul * 0.94F + 0.06F,
1.0F * brightness_mul * 0.91F + 0.09F,
};
vec3 fog_color = {
0.7529412F * brightness_mul * 0.94F + 0.06F,
0.8470588F * brightness_mul * 0.94F + 0.06F,
1.0F * brightness_mul * 0.91F + 0.09F,
};
vec3 atmosphere_color;
glm_vec3_lerp(fog_color, world_sky_color, 0.29F, atmosphere_color);
glm_vec3_scale(atmosphere_color,
powf(0.8F, (1.0F - brightness_mul) * 11.0F),
atmosphere_color);
vec3 atmosphere_color;
glm_vec3_lerp(fog_color, world_sky_color, 0.29F, atmosphere_color);
glm_vec3_scale(atmosphere_color,
powf(0.8F, (1.0F - brightness_mul) * 11.0F),
atmosphere_color);
vec3 bottom_plane_color = {0.04F, 0.04F, 0.1F};
glm_vec3_muladd(world_sky_color, (vec3) {0.2F, 0.2F, 0.6F},
bottom_plane_color);
vec3 bottom_plane_color = {0.04F, 0.04F, 0.1F};
glm_vec3_muladd(world_sky_color, (vec3) {0.2F, 0.2F, 0.6F},
bottom_plane_color);
glm_vec3_scale(atmosphere_color, 255.0F, atmosphere_color);
glm_vec3_scale(world_sky_color, 255.0F, world_sky_color);
glm_vec3_scale(bottom_plane_color, 255.0F, bottom_plane_color);
glm_vec3_copy(world_sky_color, top_plane);
glm_vec3_copy(bottom_plane_color, bottom_plane);
glm_vec3_copy(atmosphere_color, atmosphere);
glm_vec3_scale(atmosphere_color, 255.0F, atmosphere);
glm_vec3_scale(world_sky_color, 255.0F, top_plane);
glm_vec3_scale(bottom_plane_color, 255.0F, bottom_plane);
} else {
vec3 const_color = {0.2F, 0.03F, 0.03F};
glm_vec3_scale(const_color, 255.0F, atmosphere);
glm_vec3_scale(const_color, 255.0F, top_plane);
glm_vec3_scale(const_color, 255.0F, bottom_plane);
}
}

View file

@ -137,10 +137,13 @@ int main(void) {
gfx_matrix_projection(gstate.camera.projection, true);
if(render_world) {
gfx_update_light(daytime_brightness(daytime));
gfx_update_light(daytime_brightness(daytime),
world_dimension_light(&gstate.world));
gutil_sky_box(gstate.camera.view, daytime_celestial_angle(daytime),
top_plane_color, bottom_plane_color);
if(gstate.world.dimension == WORLD_DIM_OVERWORLD)
gutil_sky_box(gstate.camera.view,
daytime_celestial_angle(daytime), top_plane_color,
bottom_plane_color);
gstate.stats.chunks_rendered
= world_render(&gstate.world, &gstate.camera, false);

View file

@ -92,6 +92,7 @@ void clin_process(struct client_rpc* call) {
world_unload_all(&gstate.world);
inventory_clear(&gstate.inventory);
gstate.world_loaded = false;
gstate.world.dimension = call->payload.world_reset.dimension;
if(gstate.current_screen == &screen_ingame)
screen_set(&screen_load_world);

View file

@ -56,6 +56,9 @@ struct client_rpc {
vec2 rotation;
} player_pos;
uint64_t time_set;
struct {
enum world_dim dimension;
} world_reset;
} payload;
};

View file

@ -62,6 +62,7 @@ static bool level_archive_read_internal(nbt_node* root,
case TAG_LONG:
*((int64_t*)result) = node->payload.tag_long;
return true;
case TAG_INT: *((int32_t*)result) = node->payload.tag_int; return true;
case TAG_SHORT:
*((int16_t*)result) = node->payload.tag_short;
return true;
@ -130,6 +131,7 @@ bool level_archive_read_inventory(struct level_archive* la,
}
// could use float* instead of vec3, but not sure of possible alignment for vec3
// (right now this means we can read three values at most)
static bool read_vector(nbt_node* node, nbt_type type, vec3 result,
size_t amount) {
assert(node && node->type == TAG_LIST && result && amount <= 3);
@ -153,7 +155,8 @@ static bool read_vector(nbt_node* node, nbt_type type, vec3 result,
}
bool level_archive_read_player(struct level_archive* la, vec3 position,
vec2 rotation, vec3 velocity) {
vec2 rotation, vec3 velocity,
enum world_dim* dimension) {
assert(la && la->data);
nbt_node* pos;
@ -168,6 +171,10 @@ bool level_archive_read_player(struct level_archive* la, vec3 position,
if(!level_archive_read(la, LEVEL_PLAYER_ROTATION, &rot, 0))
return false;
int32_t* dim;
if(!level_archive_read(la, LEVEL_PLAYER_DIMENSION, &dim, 0))
return false;
if(position && !read_vector(pos, TAG_DOUBLE, position, 3))
return false;
@ -183,6 +190,10 @@ bool level_archive_read_player(struct level_archive* la, vec3 position,
rotation[1] = tmp[1];
}
// ensures output is valid dimension
if(dimension)
*dimension = (dim == 0) ? WORLD_DIM_OVERWORLD : WORLD_DIM_NETHER;
return true;
}

View file

@ -29,6 +29,7 @@
#include "../cglm/cglm.h"
#include "../item/items.h"
#include "../world.h"
struct level_archive_tag {
const char* name;
@ -53,6 +54,8 @@ struct level_archive_tag {
(struct level_archive_tag) { ".Data.Player.Rotation", TAG_LIST }
#define LEVEL_PLAYER_VELOCITY \
(struct level_archive_tag) { ".Data.Player.Motion", TAG_LIST }
#define LEVEL_PLAYER_DIMENSION \
(struct level_archive_tag) { ".Data.Player.Dimension", TAG_INT }
#define LEVEL_PLAYER_INVENTORY \
(struct level_archive_tag) { ".Data.Player.Inventory", TAG_LIST }
@ -75,7 +78,8 @@ bool level_archive_read(struct level_archive* la, struct level_archive_tag tag,
bool level_archive_read_inventory(struct level_archive* la,
struct item_data* inventory, size_t length);
bool level_archive_read_player(struct level_archive* la, vec3 position,
vec2 rotation, vec3 velocity);
vec2 rotation, vec3 velocity,
enum world_dim* dimension);
void level_archive_destroy(struct level_archive* la);
#endif

View file

@ -25,7 +25,7 @@
#include "region_archive.h"
bool region_archive_create(struct region_archive* ra, string_t world_name,
w_coord_t x, w_coord_t z) {
w_coord_t x, w_coord_t z, enum world_dim dimension) {
assert(ra && world_name);
ra->offsets = malloc(sizeof(uint32_t) * REGION_SIZE * REGION_SIZE);
@ -33,8 +33,13 @@ bool region_archive_create(struct region_archive* ra, string_t world_name,
if(!ra->offsets)
return false;
string_init_printf(ra->file_name, "saves/%s/region/r.%i.%i.mcr", world_name,
x, z);
if(dimension == WORLD_DIM_OVERWORLD) {
string_init_printf(ra->file_name, "saves/%s/region/r.%i.%i.mcr",
world_name, x, z);
} else {
string_init_printf(ra->file_name, "saves/%s/DIM-1/region/r.%i.%i.mcr",
world_name, x, z);
}
ra->x = x;
ra->z = z;

View file

@ -43,7 +43,7 @@ ILIST_DEF(ilist_regions, struct region_archive, M_POD_OPLIST)
#define CHUNK_REGION_COORD(x) ((w_coord_t)floor(x / (float)REGION_SIZE))
bool region_archive_create(struct region_archive* ra, string_t world_name,
w_coord_t x, w_coord_t z);
w_coord_t x, w_coord_t z, enum world_dim dimension);
void region_archive_destroy(struct region_archive* ra);
bool region_archive_contains(struct region_archive* ra, w_coord_t x,
w_coord_t z, bool* chunk_exists);

View file

@ -47,7 +47,7 @@ static bool has_chunk(struct server_local* s, w_coord_t x, w_coord_t z) {
struct region_archive ra;
if(!region_archive_create(&ra, s->level_name, CHUNK_REGION_COORD(x),
CHUNK_REGION_COORD(z)))
CHUNK_REGION_COORD(z), s->player.dimension))
return false;
struct region_archive* lru;
@ -105,6 +105,7 @@ static void server_local_process(struct server_rpc* call, void* user) {
// save chunks here, then destroy all
clin_rpc_send(&(struct client_rpc) {
.type = CRPC_WORLD_RESET,
.payload.world_reset.dimension = WORLD_DIM_OVERWORLD,
});
ilist_regions_init(s->loaded_regions_lru);
@ -127,23 +128,26 @@ static void server_local_process(struct server_rpc* call, void* user) {
string_set(s->level_name, call->payload.load_world.name);
string_clear(call->payload.load_world.name);
clin_rpc_send(&(struct client_rpc) {
.type = CRPC_WORLD_RESET,
});
if(level_archive_create(&s->level, s->level_name)) {
vec3 pos;
if(level_archive_read_player(&s->level, pos, NULL, NULL)) {
enum world_dim dim;
if(level_archive_read_player(&s->level, pos, NULL, NULL,
&dim)) {
s->player.x = pos[0];
s->player.y = pos[1];
s->player.z = pos[2];
s->player.dimension = dim;
s->player.has_pos = true;
}
if(level_archive_read(&s->level, LEVEL_TIME, &s->world_time, 0))
s->world_time_start = time_get();
}
clin_rpc_send(&(struct client_rpc) {
.type = CRPC_WORLD_RESET,
.payload.world_reset.dimension = dim,
});
}
break;
}
}
@ -236,7 +240,8 @@ static void server_local_update(struct server_local* s) {
struct client_rpc pos;
pos.type = CRPC_PLAYER_POS;
if(level_archive_read_player(&s->level, pos.payload.player_pos.position,
pos.payload.player_pos.rotation, NULL))
pos.payload.player_pos.rotation, NULL,
NULL))
clin_rpc_send(&pos);
s->world_time_start = time_get();

View file

@ -35,6 +35,7 @@
struct server_local {
struct {
double x, y, z;
enum world_dim dimension;
bool has_pos;
bool finished_loading;
} player;

View file

@ -43,11 +43,6 @@ static uint8_t colors[256 * 3] ATTRIBUTE_ALIGN(32);
static bool gfx_matrix_texture_prev = false;
static bool gfx_fog_prev = false;
static const float light_lookup[16] = {
0.05F, 0.067F, 0.085F, 0.106F, 0.129F, 0.156F, 0.186F, 0.221F,
0.261F, 0.309F, 0.367F, 0.437F, 0.525F, 0.638F, 0.789F, 1.0F,
};
/*static void* thread_vsync(void* user) {
void* current_frame = NULL;
@ -236,13 +231,14 @@ void gfx_setup() {
GX_SetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_POS, GX_TEXMTX1);
gfx_update_light(1.0F);
// gfx_update_light(1.0F);
GX_DrawDone();
}
void gfx_update_light(float daytime) {
assert(daytime > -GLM_FLT_EPSILON && daytime < 1.0F + GLM_FLT_EPSILON);
void gfx_update_light(float daytime, const float* light_lookup) {
assert(daytime > -GLM_FLT_EPSILON && daytime < 1.0F + GLM_FLT_EPSILON
&& light_lookup);
for(int sky = 0; sky < 16; sky++) {
for(int torch = 0; torch < 16; torch++) {

View file

@ -42,7 +42,7 @@ enum gfx_texture {
};
void gfx_setup(void);
void gfx_update_light(float daytime);
void gfx_update_light(float daytime, const float* light_lookup);
void gfx_finish(bool vsync);
void gfx_flip_buffers(float* gpu_wait, float* vsync_wait);
void gfx_bind_texture(enum gfx_texture tex);

View file

@ -73,9 +73,9 @@ void gutil_sky_box(mat4 view_matrix, float celestial_angle, vec3 color_top,
GX_TexCoord2u8(0, 0);
GX_End();
gfx_blending(MODE_BLEND2);
gfx_fog(false);
gfx_texture(true);
gfx_blending(MODE_BLEND2);
gfx_bind_texture(TEXTURE_GUI2);
mat4 tmp;

View file

@ -653,3 +653,20 @@ bool world_aabb_intersection(struct world* w, struct AABB* a) {
return false;
}
static const float light_lookup_overworld[16] = {
0.05F, 0.067F, 0.085F, 0.106F, 0.129F, 0.156F, 0.186F, 0.221F,
0.261F, 0.309F, 0.367F, 0.437F, 0.525F, 0.638F, 0.789F, 1.0F,
};
static const float light_lookup_nether[16] = {
0.1F, 0.116F, 0.133F, 0.153F, 0.175F, 0.2F, 0.229F, 0.262F,
0.3F, 0.345F, 0.4F, 0.467F, 0.55F, 0.657F, 0.8F, 1.0F,
};
const float* world_dimension_light(struct world* w) {
assert(w);
return (w->dimension == WORLD_DIM_OVERWORLD) ? light_lookup_overworld :
light_lookup_nether;
}

View file

@ -67,6 +67,11 @@ struct world_modification_entry {
DICT_DEF2(dict_wsection, int64_t, M_BASIC_OPLIST, struct world_section,
M_POD_OPLIST)
enum world_dim {
WORLD_DIM_NETHER = -1,
WORLD_DIM_OVERWORLD = 0,
};
struct world {
dict_wsection_t sections;
struct chunk* world_chunk_cache;
@ -74,6 +79,7 @@ struct world {
ilist_chunks2_t gpu_busy_chunks;
ptime_t anim_timer;
struct stack lighting_updates;
enum world_dim dimension;
};
void world_create(struct world* w);
@ -104,5 +110,6 @@ void world_pre_render_clear(struct world* w);
size_t world_render(struct world* w, struct camera* c, bool pass);
bool world_aabb_intersection(struct world* w, struct AABB* a);
size_t world_loaded_chunks(struct world* w);
const float* world_dimension_light(struct world* w);
#endif