From 2ad6eba94fa99ffc683a1a67e2777432354acfd0 Mon Sep 17 00:00:00 2001 From: kichikuou Date: Sat, 5 Jun 2021 14:50:17 +0900 Subject: [PATCH] DrawDungeon: Implement SetDoor[NWSE]Angle Now door animation works. --- include/dungeon/dgn.h | 4 +++ src/dungeon/renderer.c | 48 ++++++++++++++++++++++++++++--- src/hll/DrawDungeon.c | 64 +++++++++++++++++++++--------------------- 3 files changed, 80 insertions(+), 36 deletions(-) diff --git a/include/dungeon/dgn.h b/include/dungeon/dgn.h index 12a553b..df69673 100644 --- a/include/dungeon/dgn.h +++ b/include/dungeon/dgn.h @@ -81,6 +81,10 @@ struct dgn_cell { // Runtime data (not stored in .dgn) int x, y, z; int event_blend_rate; + float north_door_angle; + float south_door_angle; + float east_door_angle; + float west_door_angle; int32_t floor_event2; int32_t north_event2; int32_t south_event2; diff --git a/src/dungeon/renderer.c b/src/dungeon/renderer.c index 3570f63..9f27f15 100644 --- a/src/dungeon/renderer.c +++ b/src/dungeon/renderer.c @@ -74,6 +74,8 @@ struct dungeon_renderer { GLint vertex_uv; struct geometry *wall_geometry; + struct geometry *door_left_geometry; + struct geometry *door_right_geometry; struct geometry *stairs_geometry; struct material *materials; @@ -97,6 +99,20 @@ static const struct vertex wall_vertices[] = { { 1.0, -1.0, 0.0, 1.0, 1.0}, }; +static const struct vertex door_left_vertices[] = { + { 0.0, 1.0, 0.0, 0.0, 0.0}, + { 0.0, -1.0, 0.0, 0.0, 1.0}, + { 1.0, 1.0, 0.0, 0.5, 0.0}, + { 1.0, -1.0, 0.0, 0.5, 1.0}, +}; + +static const struct vertex door_right_vertices[] = { + {-1.0, 1.0, 0.0, 0.5, 0.0}, + {-1.0, -1.0, 0.0, 0.5, 1.0}, + { 0.0, 1.0, 0.0, 1.0, 0.0}, + { 0.0, -1.0, 0.0, 1.0, 1.0}, +}; + static const struct vertex stairs_vertices[] = { { 1, 3/3.f, -3/3.f, 1, 0/12.f}, {-1, 3/3.f, -3/3.f, 0, 0/12.f}, @@ -208,6 +224,8 @@ struct dungeon_renderer *dungeon_renderer_create(struct dtx *dtx, GLuint *event_ r->vertex_uv = glGetAttribLocation(r->shader.program, "vertex_uv"); r->wall_geometry = geometry_create(r, wall_vertices, sizeof(wall_vertices)); + r->door_left_geometry = geometry_create(r, door_left_vertices, sizeof(door_left_vertices)); + r->door_right_geometry = geometry_create(r, door_right_vertices, sizeof(door_right_vertices)); r->stairs_geometry = geometry_create(r, stairs_vertices, sizeof(stairs_vertices)); const int nr_types = DTX_DOOR + 1; @@ -233,6 +251,8 @@ void dungeon_renderer_free(struct dungeon_renderer *r) glDeleteProgram(r->shader.program); geometry_free(r->wall_geometry); + geometry_free(r->door_left_geometry); + geometry_free(r->door_right_geometry); geometry_free(r->stairs_geometry); for (int i = 0; i < r->nr_materials; i++) @@ -262,6 +282,26 @@ static void draw(struct dungeon_renderer *r, struct geometry *geometry, GLuint t glBindTexture(GL_TEXTURE_2D, 0); } +static void draw_door(struct dungeon_renderer *r, GLuint texture, float angle, mat4 transform, float dx, float dz) +{ + if (angle == 0.0) { + draw(r, r->wall_geometry, texture, transform); + return; + } + mat4 m; + glm_mat4_copy(transform, m); + m[3][0] += dx; + m[3][2] += dz; + glm_rotate_y(m, angle * (M_PI/180), m); + draw(r, r->door_left_geometry, texture, m); + + glm_mat4_copy(transform, m); + m[3][0] -= dx; + m[3][2] -= dz; + glm_rotate_y(m, angle * -(M_PI/180), m); + draw(r, r->door_right_geometry, texture, m); +} + static void draw_floor_marker(struct dungeon_renderer *r, const struct marker_info *info, float x, float y, float z, uint32_t t) { float rad = t / 400.0; @@ -377,7 +417,7 @@ static void draw_cell(struct dungeon_renderer *r, struct dgn_cell *cell, bool re 0, 1, 0, y, 0, 0, 1, z-1, 0, 0, 0, 1); - draw(r, r->wall_geometry, material->texture, m); + draw_door(r, material->texture, cell->north_door_angle, m, -1, 0); } } if (cell->south_door >= 0) { @@ -388,7 +428,7 @@ static void draw_cell(struct dungeon_renderer *r, struct dgn_cell *cell, bool re 0, 1, 0, y, 0, 0, -1, z+1, 0, 0, 0, 1); - draw(r, r->wall_geometry, material->texture, m); + draw_door(r, material->texture, cell->south_door_angle, m, 1, 0); } } if (cell->east_door >= 0) { @@ -399,7 +439,7 @@ static void draw_cell(struct dungeon_renderer *r, struct dgn_cell *cell, bool re 0, 1, 0, y, 1, 0, 0, z, 0, 0, 0, 1); - draw(r, r->wall_geometry, material->texture, m); + draw_door(r, material->texture, cell->east_door_angle, m, 0, -1); } } if (cell->west_door >= 0) { @@ -410,7 +450,7 @@ static void draw_cell(struct dungeon_renderer *r, struct dgn_cell *cell, bool re 0, 1, 0, y, -1, 0, 0, z, 0, 0, 0, 1); - draw(r, r->wall_geometry, material->texture, m); + draw_door(r, material->texture, cell->west_door_angle, m, 0, 1); } } if (cell->stairs_texture >= 0) { diff --git a/src/hll/DrawDungeon.c b/src/hll/DrawDungeon.c index 434f88b..bf03430 100644 --- a/src/hll/DrawDungeon.c +++ b/src/hll/DrawDungeon.c @@ -186,8 +186,8 @@ CELL_GETTER(DrawDungeon_GetTexDoorE, -1, cell->east_door); CELL_GETTER(DrawDungeon_GetTexStair, -1, cell->stairs_texture); CELL_GETTER(DrawDungeon_GetBattleBack, -1, cell->battle_background); -#define CELL_SETTER(name, expr, update_map) \ - static void name(int surface, int x, int y, int z, int value) \ +#define CELL_SETTER(name, type, expr, update_map) \ + static void name(int surface, int x, int y, int z, type value) \ { \ struct dungeon_context *ctx = dungeon_get_context(surface); \ if (!ctx || !ctx->dgn || !dgn_is_in_map(ctx->dgn, x, y, z)) \ @@ -198,37 +198,37 @@ CELL_GETTER(DrawDungeon_GetBattleBack, -1, cell->battle_background); dungeon_map_update_cell(ctx, x, y, z); \ } -HLL_WARN_UNIMPLEMENTED( , void, DrawDungeon, SetDoorNAngle, int surface, int x, int y, int z, float angle); -HLL_WARN_UNIMPLEMENTED( , void, DrawDungeon, SetDoorWAngle, int surface, int x, int y, int z, float angle); -HLL_WARN_UNIMPLEMENTED( , void, DrawDungeon, SetDoorSAngle, int surface, int x, int y, int z, float angle); -HLL_WARN_UNIMPLEMENTED( , void, DrawDungeon, SetDoorEAngle, int surface, int x, int y, int z, float angle); -CELL_SETTER(DrawDungeon_SetEvFloor, cell->floor_event, true); -CELL_SETTER(DrawDungeon_SetEvWallN, cell->north_event, true); -CELL_SETTER(DrawDungeon_SetEvWallW, cell->west_event, true); -CELL_SETTER(DrawDungeon_SetEvWallS, cell->south_event, true); -CELL_SETTER(DrawDungeon_SetEvWallE, cell->east_event, true); -CELL_SETTER(DrawDungeon_SetEvFloor2, cell->floor_event2, false); -CELL_SETTER(DrawDungeon_SetEvWallN2, cell->north_event2, false); -CELL_SETTER(DrawDungeon_SetEvWallW2, cell->west_event2, false); -CELL_SETTER(DrawDungeon_SetEvWallS2, cell->south_event2, false); -CELL_SETTER(DrawDungeon_SetEvWallE2, cell->east_event2, false); +CELL_SETTER(DrawDungeon_SetDoorNAngle, float, cell->north_door_angle, false); +CELL_SETTER(DrawDungeon_SetDoorWAngle, float, cell->west_door_angle, false); +CELL_SETTER(DrawDungeon_SetDoorSAngle, float, cell->south_door_angle, false); +CELL_SETTER(DrawDungeon_SetDoorEAngle, float, cell->east_door_angle, false); +CELL_SETTER(DrawDungeon_SetEvFloor, int, cell->floor_event, true); +CELL_SETTER(DrawDungeon_SetEvWallN, int, cell->north_event, true); +CELL_SETTER(DrawDungeon_SetEvWallW, int, cell->west_event, true); +CELL_SETTER(DrawDungeon_SetEvWallS, int, cell->south_event, true); +CELL_SETTER(DrawDungeon_SetEvWallE, int, cell->east_event, true); +CELL_SETTER(DrawDungeon_SetEvFloor2, int, cell->floor_event2, false); +CELL_SETTER(DrawDungeon_SetEvWallN2, int, cell->north_event2, false); +CELL_SETTER(DrawDungeon_SetEvWallW2, int, cell->west_event2, false); +CELL_SETTER(DrawDungeon_SetEvWallS2, int, cell->south_event2, false); +CELL_SETTER(DrawDungeon_SetEvWallE2, int, cell->east_event2, false); //void DrawDungeon_SetEvMag(int surface, int x, int y, int z, float mag); -CELL_SETTER(DrawDungeon_SetEvRate, cell->event_blend_rate, false); -CELL_SETTER(DrawDungeon_SetEnter, cell->enterable, false); -CELL_SETTER(DrawDungeon_SetEnterN, cell->enterable_north, true); -CELL_SETTER(DrawDungeon_SetEnterW, cell->enterable_west, true); -CELL_SETTER(DrawDungeon_SetEnterS, cell->enterable_south, true); -CELL_SETTER(DrawDungeon_SetEnterE, cell->enterable_east, true); -CELL_SETTER(DrawDungeon_SetTexFloor, cell->floor, true); -CELL_SETTER(DrawDungeon_SetTexCeiling, cell->ceiling, false); -CELL_SETTER(DrawDungeon_SetTexWallN, cell->north_wall, true); -CELL_SETTER(DrawDungeon_SetTexWallW, cell->west_wall, true); -CELL_SETTER(DrawDungeon_SetTexWallS, cell->south_wall, true); -CELL_SETTER(DrawDungeon_SetTexWallE, cell->east_wall, true); -CELL_SETTER(DrawDungeon_SetTexDoorN, cell->north_door, true); -CELL_SETTER(DrawDungeon_SetTexDoorW, cell->west_door, true); -CELL_SETTER(DrawDungeon_SetTexDoorS, cell->south_door, true); -CELL_SETTER(DrawDungeon_SetTexDoorE, cell->east_door, true); +CELL_SETTER(DrawDungeon_SetEvRate, int, cell->event_blend_rate, false); +CELL_SETTER(DrawDungeon_SetEnter, int, cell->enterable, false); +CELL_SETTER(DrawDungeon_SetEnterN, int, cell->enterable_north, true); +CELL_SETTER(DrawDungeon_SetEnterW, int, cell->enterable_west, true); +CELL_SETTER(DrawDungeon_SetEnterS, int, cell->enterable_south, true); +CELL_SETTER(DrawDungeon_SetEnterE, int, cell->enterable_east, true); +CELL_SETTER(DrawDungeon_SetTexFloor, int, cell->floor, true); +CELL_SETTER(DrawDungeon_SetTexCeiling, int, cell->ceiling, false); +CELL_SETTER(DrawDungeon_SetTexWallN, int, cell->north_wall, true); +CELL_SETTER(DrawDungeon_SetTexWallW, int, cell->west_wall, true); +CELL_SETTER(DrawDungeon_SetTexWallS, int, cell->south_wall, true); +CELL_SETTER(DrawDungeon_SetTexWallE, int, cell->east_wall, true); +CELL_SETTER(DrawDungeon_SetTexDoorN, int, cell->north_door, true); +CELL_SETTER(DrawDungeon_SetTexDoorW, int, cell->west_door, true); +CELL_SETTER(DrawDungeon_SetTexDoorS, int, cell->south_door, true); +CELL_SETTER(DrawDungeon_SetTexDoorE, int, cell->east_door, true); //void DrawDungeon_SetSkyTextureSet(int surface, int set); HLL_WARN_UNIMPLEMENTED( , void, DrawDungeon, SetDrawMapRadar, int surface, int flag);