mirror of
https://github.com/xtreme8000/CavEX.git
synced 2025-01-22 09:11:55 -05:00
Allow for different dimensions
This commit is contained in:
parent
2a69b646de
commit
bab1cc92c7
15 changed files with 116 additions and 58 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -56,6 +56,9 @@ struct client_rpc {
|
|||
vec2 rotation;
|
||||
} player_pos;
|
||||
uint64_t time_set;
|
||||
struct {
|
||||
enum world_dim dimension;
|
||||
} world_reset;
|
||||
} payload;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
struct server_local {
|
||||
struct {
|
||||
double x, y, z;
|
||||
enum world_dim dimension;
|
||||
bool has_pos;
|
||||
bool finished_loading;
|
||||
} player;
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue