From fb94881f9f888e1b5bad425bf19ca71bdc8d14b1 Mon Sep 17 00:00:00 2001 From: kichikuou Date: Sat, 12 Jun 2021 22:20:46 +0900 Subject: [PATCH 1/5] Remove flip_y field from texture It was introduced to flip texture image rendered by DrawDungeon when presenting on the screen. In GALZOO this approach does not work because dungeon texture is also used as the source image of gfx functions. After this, DrawDungeon directly generates vertically flipped image, by tweaking the projection matrix. --- include/gfx/gfx.h | 1 - src/dungeon/dungeon.c | 17 +++++++++-------- src/video.c | 10 ---------- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/include/gfx/gfx.h b/include/gfx/gfx.h index 5222c45..e93d2d1 100644 --- a/include/gfx/gfx.h +++ b/include/gfx/gfx.h @@ -38,7 +38,6 @@ typedef struct texture { mat4 world_transform; int w, h; bool has_alpha; - bool flip_y; int alpha_mod; enum draw_method draw_method; } Texture; diff --git a/src/dungeon/dungeon.c b/src/dungeon/dungeon.c index 3cb1003..976947e 100644 --- a/src/dungeon/dungeon.c +++ b/src/dungeon/dungeon.c @@ -50,11 +50,8 @@ struct dungeon_context *dungeon_context_create(int surface) if (!sp) VM_ERROR("DrawDungeon.Init: invalid surface %d", surface); - // Dungeon scene will be rendered to this texture. Unlike other textures, - // its (0,0) is at the bottom-left, so it needs to be flipped vertically - // when displayed on the screen. + // Dungeon scene will be rendered to this texture. struct texture *texture = sprite_get_texture(sp); - texture->flip_y = true; glGenRenderbuffers(1, &ctx->depth_buffer); glBindRenderbuffer(GL_RENDERBUFFER, ctx->depth_buffer); @@ -80,10 +77,6 @@ void dungeon_context_free(struct dungeon_context *ctx) glDeleteRenderbuffers(1, &ctx->depth_buffer); dungeon_map_free(ctx->map); - struct sact_sprite *sp = sact_get_sprite(ctx->surface); - if (sp) - sprite_get_texture(sp)->flip_y = false; - free(ctx); } @@ -226,6 +219,13 @@ void dungeon_render(struct dungeon_context *ctx) model_view_matrix(&ctx->camera, view_transform); glm_perspective(M_PI / 3.0, (float)texture->w / texture->h, 0.5, 100.0, proj_transform); + // Tweak the projection transform so that the rendering result is vertically + // flipped. If we render the scene normally, the resulting image will be + // bottom-up (the first pixel is at the bottom-left), but we want a top-down + // image (the first pixel is at the top-left). + proj_transform[1][1] *= -1; + glFrontFace(GL_CW); + int dgn_x = round(ctx->camera.pos[0] / 2.0); int dgn_y = round(ctx->camera.pos[1] / 2.0); int dgn_z = round(ctx->camera.pos[2] / -2.0); @@ -233,6 +233,7 @@ void dungeon_render(struct dungeon_context *ctx) struct dgn_cell **cells = dgn_get_visible_cells(ctx->dgn, dgn_x, dgn_y, dgn_z, &nr_cells); dungeon_renderer_render(ctx->renderer, cells, nr_cells, view_transform, proj_transform); + glFrontFace(GL_CCW); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); diff --git a/src/video.c b/src/video.c index e023df3..0cd6644 100644 --- a/src/video.c +++ b/src/video.c @@ -234,7 +234,6 @@ static void main_surface_init(int w, int h) main_surface.w = w; main_surface.h = h; main_surface.has_alpha = true; - main_surface.flip_y = false; main_surface.alpha_mod = 255; main_surface.draw_method = DRAW_METHOD_NORMAL; @@ -371,10 +370,6 @@ void gfx_render_texture(struct texture *t, Rectangle *r) t->world_transform[3][0] = r ? r->x : 0; t->world_transform[3][1] = r ? r->y : 0; - if (t->flip_y) { - t->world_transform[3][1] += t->world_transform[1][1]; - t->world_transform[1][1] *= -1; - } struct gfx_render_job job = { .shader = &default_shader.s, @@ -385,10 +380,6 @@ void gfx_render_texture(struct texture *t, Rectangle *r) }; gfx_render(&job); - if (t->flip_y) { - t->world_transform[1][1] *= -1; - t->world_transform[3][1] -= t->world_transform[1][1]; - } if (t->draw_method != DRAW_METHOD_NORMAL || t->alpha_mod != 255) glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); } @@ -412,7 +403,6 @@ static void init_texture(struct texture *t, int w, int h) t->h = h; t->has_alpha = true; - t->flip_y = false; t->alpha_mod = 255; t->draw_method = DRAW_METHOD_NORMAL; From 9c6bf5c110b53f9f7dcfbc54146ee4be4561de32 Mon Sep 17 00:00:00 2001 From: kichikuou Date: Sat, 12 Jun 2021 23:52:52 +0900 Subject: [PATCH 2/5] DrawDungeon: Move walk-flag management code out of map.c So that ctx->map can just be null in DrawDungeon14 (GALZOO), where 2D maps are not drawn by the HLL. --- include/dungeon/dgn.h | 7 ++ include/dungeon/dungeon.h | 5 ++ include/dungeon/map.h | 6 +- src/dungeon/dgn.c | 19 ++++- src/dungeon/dungeon.c | 140 ++++++++++++++++++++++++++++++++ src/dungeon/map.c | 167 ++------------------------------------ src/hll/DrawDungeon.c | 8 +- 7 files changed, 181 insertions(+), 171 deletions(-) diff --git a/include/dungeon/dgn.h b/include/dungeon/dgn.h index df69673..c194294 100644 --- a/include/dungeon/dgn.h +++ b/include/dungeon/dgn.h @@ -80,6 +80,7 @@ struct dgn_cell { // Runtime data (not stored in .dgn) int x, y, z; + int walked; int event_blend_rate; float north_door_angle; float south_door_angle; @@ -119,6 +120,12 @@ void dgn_free(struct dgn *dgn); int dgn_cell_index(struct dgn *dgn, uint32_t x, uint32_t y, uint32_t z); struct dgn_cell *dgn_cell_at(struct dgn *dgn, uint32_t x, uint32_t y, uint32_t z); +int dgn_calc_conquer(struct dgn *dgn); + +static inline int dgn_nr_cells(struct dgn *dgn) +{ + return dgn->size_x * dgn->size_y * dgn->size_z; +} static inline bool dgn_is_in_map(struct dgn *dgn, uint32_t x, uint32_t y, uint32_t z) { diff --git a/include/dungeon/dungeon.h b/include/dungeon/dungeon.h index 79bc0f0..2674262 100644 --- a/include/dungeon/dungeon.h +++ b/include/dungeon/dungeon.h @@ -22,6 +22,7 @@ #include #include +struct page; struct dgn; struct dtx; struct tes; @@ -61,6 +62,10 @@ void dungeon_context_free(struct dungeon_context *ctx); bool dungeon_load(struct dungeon_context *ctx, int num); void dungeon_set_camera(int surface, float x, float y, float z, float angle, float angle_p); void dungeon_render(struct dungeon_context *ctx); +void dungeon_set_walked(int surface, int x, int y, int z, int flag); +int dungeon_calc_conquer(int surface); +bool dungeon_load_walk_data(int surface, int map, struct page **page); +bool dungeon_save_walk_data(int surface, int map, struct page **page); struct dungeon_context *dungeon_get_context(int surface); void dungeon_update(void); diff --git a/include/dungeon/map.h b/include/dungeon/map.h index 6f8db86..614a306 100644 --- a/include/dungeon/map.h +++ b/include/dungeon/map.h @@ -17,7 +17,6 @@ #ifndef SYSTEM4_DUNGEON_MAP_H #define SYSTEM4_DUNGEON_MAP_H -struct page; struct dungeon_context; struct dungeon_map; @@ -33,9 +32,6 @@ void dungeon_map_set_all_view(int surface, int flag); void dungeon_map_set_cg(int surface, int index, int sprite); void dungeon_map_set_small_map_floor(int surface, int floor); void dungeon_map_set_large_map_floor(int surface, int floor); -void dungeon_map_set_walked(int surface, int x, int y, int z, int flag); -int dungeon_map_calc_conquer(int surface); -bool dungeon_map_load_walk_data(int surface, int map, struct page **page); -bool dungeon_map_save_walk_data(int surface, int map, struct page **page); +void dungeon_map_reveal(struct dungeon_context *ctx, int x, int y, int z); #endif /* SYSTEM4_DUNGEON_MAP_H */ diff --git a/src/dungeon/dgn.c b/src/dungeon/dgn.c index bf432ad..ff7873b 100644 --- a/src/dungeon/dgn.c +++ b/src/dungeon/dgn.c @@ -42,7 +42,7 @@ struct dgn *dgn_parse(uint8_t *data, size_t size) dgn->size_z = buffer_read_int32(&r); buffer_skip(&r, 40); - int nr_cells = dgn->size_x * dgn->size_y * dgn->size_z; + int nr_cells = dgn_nr_cells(dgn); dgn->cells = xcalloc(nr_cells, sizeof(struct dgn_cell)); uint32_t x = 0, y = 0, z = 0; for (int i = 0; i < nr_cells; i++) { @@ -146,7 +146,7 @@ struct dgn *dgn_parse(uint8_t *data, size_t size) void dgn_free(struct dgn *dgn) { - int nr_cells = dgn->size_x * dgn->size_y * dgn->size_z; + int nr_cells = dgn_nr_cells(dgn); for (int i = 0; i < nr_cells; i++) { if (dgn->cells[i].visible_cells) @@ -175,6 +175,21 @@ struct dgn_cell *dgn_cell_at(struct dgn *dgn, uint32_t x, uint32_t y, uint32_t z return &dgn->cells[dgn_cell_index(dgn, x, y, z)]; } +int dgn_calc_conquer(struct dgn *dgn) +{ + int nr_cells = dgn_nr_cells(dgn); + int enterable = 0; + int walked = 0; + for (int i = 0; i < nr_cells; i++) { + if (!dgn->cells[i].enterable) + continue; + enterable++; + if (dgn->cells[i].walked) + walked++; + } + return walked * 100 / enterable; +} + struct pvs_cell { struct dgn_cell *cell; int distance; diff --git a/src/dungeon/dungeon.c b/src/dungeon/dungeon.c index 976947e..4bcbdc1 100644 --- a/src/dungeon/dungeon.c +++ b/src/dungeon/dungeon.c @@ -36,6 +36,7 @@ #include "sact.h" #include "sprite.h" #include "vm.h" +#include "vm/page.h" #include "xsystem4.h" #ifndef M_PI @@ -239,3 +240,142 @@ void dungeon_render(struct dungeon_context *ctx) glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); gfx_reset_framebuffer(GL_DRAW_FRAMEBUFFER, fbo); } + +static void neighbor_reveal(struct dungeon_context *ctx, int x, int y, int z) +{ + struct dgn_cell *cell = dgn_cell_at(ctx->dgn, x, y, z); + if (cell->floor < 0) { + cell->walked = 1; + dungeon_map_reveal(ctx, x, y, z); + } +} + +void dungeon_set_walked(int surface, int x, int y, int z, int flag) +{ + struct dungeon_context *ctx = dungeon_get_context(surface); + if (!ctx) + return; + dgn_cell_at(ctx->dgn, x, y, z)->walked = 1; + dungeon_map_reveal(ctx, x, y, z); + if (x > 0) + neighbor_reveal(ctx, x - 1, y, z); + if (x + 1u < ctx->dgn->size_x) + neighbor_reveal(ctx, x + 1, y, z); + if (z > 0) + neighbor_reveal(ctx, x, y, z - 1); + if (z + 1u < ctx->dgn->size_z) + neighbor_reveal(ctx, x, y, z + 1); +} + +int dungeon_calc_conquer(int surface) +{ + struct dungeon_context *ctx = dungeon_get_context(surface); + if (!ctx || !ctx->dgn) + return 0; + return dgn_calc_conquer(ctx->dgn); +} + +/* + * WalkData serialization format (in Rance VI): + * + * struct WalkData { + * int version; // zero + * int nr_maps; + * struct { + * int map_no; + * int size_x, size_y, size_z; + * int cells[size_x * size_y * size_z]; + * } maps[nr_maps]; + * }; + */ + +enum { + WALK_DATA_NOT_FOUND = -1, + WALK_DATA_BROKEN = -2, +}; + +static int find_walk_data(struct page *array, int map_no, struct dgn *dgn) +{ + if (!array) + return WALK_DATA_BROKEN; + if (array->type != ARRAY_PAGE || array->a_type != AIN_ARRAY_INT || array->rank != 1) + VM_ERROR("Not a flat integer array"); + + int ptr = 0; + if (array->nr_vars < 2 || array->values[ptr++].i != 0) + return WALK_DATA_BROKEN; + int nr_maps = array->values[ptr++].i; + + for (int i = 0; i < nr_maps; i++) { + if (array->nr_vars < ptr + 4) + return WALK_DATA_BROKEN; + int no = array->values[ptr].i; + uint32_t size_x = array->values[ptr + 1].i; + uint32_t size_y = array->values[ptr + 2].i; + uint32_t size_z = array->values[ptr + 3].i; + int nr_cells = size_x * size_y * size_z; + if (no == map_no) { + if (size_x != dgn->size_x || size_y != dgn->size_y || size_z != dgn->size_z) + return WALK_DATA_BROKEN; + if (ptr + 4 + nr_cells > array->nr_vars) + return WALK_DATA_BROKEN; + return ptr; + } + ptr += 4 + nr_cells; + } + return WALK_DATA_NOT_FOUND; +} + +bool dungeon_load_walk_data(int surface, int map, struct page **page) +{ + struct dungeon_context *ctx = dungeon_get_context(surface); + if (!ctx || !ctx->dgn) + return false; + struct page *array = *page; + + int offset = find_walk_data(array, map, ctx->dgn); + if (offset < 0) + return false; + + offset += 4; + int nr_cells = dgn_nr_cells(ctx->dgn); + for (struct dgn_cell *c = ctx->dgn->cells; c < ctx->dgn->cells + nr_cells; c++) { + if (array->values[offset].i) + dungeon_map_reveal(ctx, c->x, c->y, c->z); + c->walked = array->values[offset++].i; + } + + return true; +} + +bool dungeon_save_walk_data(int surface, int map, struct page **page) +{ + struct dungeon_context *ctx = dungeon_get_context(surface); + if (!ctx || !ctx->dgn) + return false; + struct page *array = *page; + int nr_cells = dgn_nr_cells(ctx->dgn); + + int offset = find_walk_data(array, map, ctx->dgn); + if (offset == WALK_DATA_NOT_FOUND) { + offset = array->nr_vars; + array->values[1].i += 1; + union vm_value dim = { .i = array->nr_vars + 4 + nr_cells }; + *page = array = realloc_array(array, 1, &dim, AIN_ARRAY_INT, 0, false); + } else if (offset == WALK_DATA_BROKEN) { + if (array) + WARNING("Discarding broken walk data"); + union vm_value dim = { .i = 2 + 4 + nr_cells }; + *page = array = realloc_array(array, 1, &dim, AIN_ARRAY_INT, 0, false); + array->values[0].i = 0; + array->values[1].i = 1; + offset = 2; + } + array->values[offset++].i = map; + array->values[offset++].i = ctx->dgn->size_x; + array->values[offset++].i = ctx->dgn->size_y; + array->values[offset++].i = ctx->dgn->size_z; + for (int i = 0; i < nr_cells; i++) + array->values[offset++].i = ctx->dgn->cells[i].walked; + return true; +} diff --git a/src/dungeon/map.c b/src/dungeon/map.c index 73f6546..de3c627 100644 --- a/src/dungeon/map.c +++ b/src/dungeon/map.c @@ -24,7 +24,6 @@ #include "gfx/gfx.h" #include "sact.h" #include "vm.h" -#include "vm/page.h" #ifndef M_PI #define M_PI (3.14159265358979323846) @@ -60,7 +59,6 @@ struct dungeon_map { int large_map_floor; bool radar; bool all_visible; - int *walk_data; int offset_x, offset_y; }; @@ -85,7 +83,6 @@ void dungeon_map_free(struct dungeon_map *map) for (int i = 0; i < map->nr_textures; i++) gfx_delete_texture(&map->textures[i]); free(map->textures); - free(map->walk_data); free(map); } @@ -96,7 +93,6 @@ void dungeon_map_init(struct dungeon_context *ctx) map->textures = xcalloc(dgn->size_y, sizeof(struct texture)); map->nr_textures = dgn->size_y; - map->walk_data = xcalloc(dgn->size_x * dgn->size_y * dgn->size_z, sizeof(int)); // Calculate the bounding box on the XZ plane so that map is drawn in the // center of the texture. uint32_t min_x = dgn->size_x; @@ -130,11 +126,10 @@ void dungeon_map_init(struct dungeon_context *ctx) } } -static void reveal_cell(struct dungeon_context *ctx, int dgn_x, int dgn_y, int dgn_z) +void dungeon_map_reveal(struct dungeon_context *ctx, int x, int y, int z) { - ctx->map->walk_data[dgn_cell_index(ctx->dgn, dgn_x, dgn_y, dgn_z)] = 1; - struct texture *dst = &ctx->map->textures[dgn_y]; - Point pos = texture_pos(ctx, dgn_x, dgn_z); + struct texture *dst = &ctx->map->textures[y]; + Point pos = texture_pos(ctx, x, z); gfx_fill_amap(dst, pos.x, pos.y, CS, CS, 255); } @@ -302,14 +297,10 @@ void dungeon_map_draw_lmap(int surface, int sprite) static void redraw_event_symbols(struct dungeon_context *ctx) { - struct dgn *dgn = ctx->dgn; - for (uint32_t y = 0; y < dgn->size_y; y++) { - for (uint32_t z = 0; z < dgn->size_z; z++) { - for (uint32_t x = 0; x < dgn->size_x; x++) { - if (dgn_cell_at(dgn, x, y, z)->floor_event) - dungeon_map_update_cell(ctx, x, y, z); - } - } + int nr_cells = dgn_nr_cells(ctx->dgn); + for (struct dgn_cell *c = ctx->dgn->cells; c < ctx->dgn->cells + nr_cells; c++) { + if (c->floor_event) + dungeon_map_update_cell(ctx, c->x, c->y, c->z); } } @@ -356,147 +347,3 @@ void dungeon_map_set_large_map_floor(int surface, int floor) return; ctx->map->large_map_floor = floor; } - -void dungeon_map_set_walked(int surface, int x, int y, int z, int flag) -{ - struct dungeon_context *ctx = dungeon_get_context(surface); - if (!ctx) - return; - reveal_cell(ctx, x, y, z); - if (x > 0 && dgn_cell_at(ctx->dgn, x - 1, y, z)->floor < 0) - reveal_cell(ctx, x - 1, y, z); - if (x + 1u < ctx->dgn->size_x && dgn_cell_at(ctx->dgn, x + 1, y, z)->floor < 0) - reveal_cell(ctx, x + 1, y, z); - if (z > 0 && dgn_cell_at(ctx->dgn, x, y, z - 1)->floor < 0) - reveal_cell(ctx, x, y, z - 1); - if (z + 1u < ctx->dgn->size_z && dgn_cell_at(ctx->dgn, x, y, z + 1)->floor < 0) - reveal_cell(ctx, x, y, z + 1); -} - -int dungeon_map_calc_conquer(int surface) -{ - struct dungeon_context *ctx = dungeon_get_context(surface); - if (!ctx || !ctx->dgn) - return 0; - - int nr_cells = ctx->dgn->size_x * ctx->dgn->size_y * ctx->dgn->size_z; - int enterable = 0; - int walked = 0; - for (int i = 0; i < nr_cells; i++) { - if (!ctx->dgn->cells[i].enterable) - continue; - enterable++; - if (ctx->map->walk_data[i]) - walked++; - } - return walked * 100 / enterable; -} - -/* - * WalkData serialization format (in Rance VI): - * - * struct WalkData { - * int version; // zero - * int nr_maps; - * struct { - * int map_no; - * int size_x, size_y, size_z; - * int cells[size_x * size_y * size_z]; - * } maps[nr_maps]; - * }; - */ - -enum { - WALK_DATA_NOT_FOUND = -1, - WALK_DATA_BROKEN = -2, -}; - -static int find_walk_data(struct page *array, int map_no, struct dgn *dgn) -{ - if (!array) - return WALK_DATA_BROKEN; - if (array->type != ARRAY_PAGE || array->a_type != AIN_ARRAY_INT || array->rank != 1) - VM_ERROR("Not a flat integer array"); - - int ptr = 0; - if (array->nr_vars < 2 || array->values[ptr++].i != 0) - return WALK_DATA_BROKEN; - int nr_maps = array->values[ptr++].i; - - for (int i = 0; i < nr_maps; i++) { - if (array->nr_vars < ptr + 4) - return WALK_DATA_BROKEN; - int no = array->values[ptr].i; - uint32_t size_x = array->values[ptr + 1].i; - uint32_t size_y = array->values[ptr + 2].i; - uint32_t size_z = array->values[ptr + 3].i; - int nr_cells = size_x * size_y * size_z; - if (no == map_no) { - if (size_x != dgn->size_x || size_y != dgn->size_y || size_z != dgn->size_z) - return WALK_DATA_BROKEN; - if (ptr + 4 + nr_cells > array->nr_vars) - return WALK_DATA_BROKEN; - return ptr; - } - ptr += 4 + nr_cells; - } - return WALK_DATA_NOT_FOUND; -} - -bool dungeon_map_load_walk_data(int surface, int map, struct page **page) -{ - struct dungeon_context *ctx = dungeon_get_context(surface); - if (!ctx || !ctx->dgn) - return false; - struct page *array = *page; - - int offset = find_walk_data(array, map, ctx->dgn); - if (offset < 0) - return false; - - offset += 4; - int i = 0; - for (uint32_t z = 0; z < ctx->dgn->size_z; z++) { - for (uint32_t y = 0; y < ctx->dgn->size_y; y++) { - for (uint32_t x = 0; x < ctx->dgn->size_x; x++) { - if (array->values[offset].i) - reveal_cell(ctx, x, y, z); - ctx->map->walk_data[i++] = array->values[offset++].i; - } - } - } - - return true; -} - -bool dungeon_map_save_walk_data(int surface, int map, struct page **page) -{ - struct dungeon_context *ctx = dungeon_get_context(surface); - if (!ctx || !ctx->dgn) - return false; - struct page *array = *page; - int nr_cells = ctx->dgn->size_x * ctx->dgn->size_y * ctx->dgn->size_z; - - int offset = find_walk_data(array, map, ctx->dgn); - if (offset == WALK_DATA_NOT_FOUND) { - offset = array->nr_vars; - array->values[1].i += 1; - union vm_value dim = { .i = array->nr_vars + 4 + nr_cells }; - *page = array = realloc_array(array, 1, &dim, AIN_ARRAY_INT, 0, false); - } else if (offset == WALK_DATA_BROKEN) { - if (array) - WARNING("Discarding broken walk data"); - union vm_value dim = { .i = 2 + 4 + nr_cells }; - *page = array = realloc_array(array, 1, &dim, AIN_ARRAY_INT, 0, false); - array->values[0].i = 0; - array->values[1].i = 1; - offset = 2; - } - array->values[offset++].i = map; - array->values[offset++].i = ctx->dgn->size_x; - array->values[offset++].i = ctx->dgn->size_y; - array->values[offset++].i = ctx->dgn->size_z; - for (int i = 0; i < nr_cells; i++) - array->values[offset++].i = ctx->map->walk_data[i]; - return true; -} diff --git a/src/hll/DrawDungeon.c b/src/hll/DrawDungeon.c index 81e82b1..37cd395 100644 --- a/src/hll/DrawDungeon.c +++ b/src/hll/DrawDungeon.c @@ -360,12 +360,12 @@ HLL_LIBRARY(DrawDungeon, HLL_EXPORT(SetDrawMapRadar, dungeon_map_set_radar), HLL_EXPORT(SetDrawHalfFlag, DrawDungeon_SetDrawHalfFlag), HLL_EXPORT(GetDrawHalfFlag, DrawDungeon_GetDrawHalfFlag), - HLL_EXPORT(SetWalked, dungeon_map_set_walked), + HLL_EXPORT(SetWalked, dungeon_set_walked), HLL_TODO_EXPORT(SetWalkedAll, DrawDungeon_SetWalkedAll), HLL_TODO_EXPORT(CalcNumofFloor, DrawDungeon_CalcNumofFloor), HLL_TODO_EXPORT(CalcNumofWalk, DrawDungeon_CalcNumofWalk), HLL_TODO_EXPORT(CalcNumofWalk2, DrawDungeon_CalcNumofWalk2), - HLL_EXPORT(CalcConquer, dungeon_map_calc_conquer), + HLL_EXPORT(CalcConquer, dungeon_calc_conquer), HLL_EXPORT(SetInterlaceMode, DrawDungeon_SetInterlaceMode), HLL_EXPORT(SetDirect3DMode, DrawDungeon_SetDirect3DMode), HLL_EXPORT(SaveDrawSettingFlag, DrawDungeon_SaveDrawSettingFlag), @@ -378,6 +378,6 @@ HLL_LIBRARY(DrawDungeon, HLL_EXPORT(GetTexSound, DrawDungeon_GetTexSound), HLL_EXPORT(StopTimer, DrawDungeon_StopTimer), HLL_EXPORT(RestartTimer, DrawDungeon_RestartTimer), - HLL_EXPORT(LoadWalkData, dungeon_map_load_walk_data), - HLL_EXPORT(SaveWalkData, dungeon_map_save_walk_data) + HLL_EXPORT(LoadWalkData, dungeon_load_walk_data), + HLL_EXPORT(SaveWalkData, dungeon_save_walk_data) ); From 1d8615d14f7a2b7644bbefbda29d9ea17161078c Mon Sep 17 00:00:00 2001 From: kichikuou Date: Sat, 12 Jun 2021 22:50:37 +0900 Subject: [PATCH 3/5] Initial implementation of DrawDungeon14.hll (GALZOO Island) Major differences from DrawDungeon.hll are: - DGN, DTX, TES are loaded from individual files, not from a DLF archive - 2D map functions are not used - (unimplemented) Spinning motion of event markers - (unimplemented) Additional 3D object types (polygon models and roofs) --- include/dungeon/dungeon.h | 10 +- include/dungeon/map.h | 2 +- include/dungeon/renderer.h | 2 +- src/dungeon/dungeon.c | 122 +++++++++++----- src/dungeon/map.c | 25 ++-- src/dungeon/renderer.c | 63 +++++--- src/ffi.c | 2 + src/hll/DrawDungeon.c | 288 +++++++++++++++++++++---------------- 8 files changed, 318 insertions(+), 196 deletions(-) diff --git a/include/dungeon/dungeon.h b/include/dungeon/dungeon.h index 2674262..f63d491 100644 --- a/include/dungeon/dungeon.h +++ b/include/dungeon/dungeon.h @@ -29,6 +29,12 @@ struct tes; struct dungeon_renderer; struct dungeon_map; +enum draw_dungeon_version { + DRAW_DUNGEON_1, // Rance VI + // DRAW_DUNGEON_2, // Dungeons & Dolls + DRAW_DUNGEON_14 // GALZOO Island +}; + struct camera { float pos[3]; float angle; @@ -45,6 +51,7 @@ struct camera { */ struct dungeon_context { + enum draw_dungeon_version version; int surface; bool loaded; bool draw_enabled; @@ -57,12 +64,13 @@ struct dungeon_context { GLuint depth_buffer; }; -struct dungeon_context *dungeon_context_create(int surface); +struct dungeon_context *dungeon_context_create(enum draw_dungeon_version version, int surface); void dungeon_context_free(struct dungeon_context *ctx); bool dungeon_load(struct dungeon_context *ctx, int num); void dungeon_set_camera(int surface, float x, float y, float z, float angle, float angle_p); void dungeon_render(struct dungeon_context *ctx); void dungeon_set_walked(int surface, int x, int y, int z, int flag); +int dungeon_get_walked(int surface, int x, int y, int z); int dungeon_calc_conquer(int surface); bool dungeon_load_walk_data(int surface, int map, struct page **page); bool dungeon_save_walk_data(int surface, int map, struct page **page); diff --git a/include/dungeon/map.h b/include/dungeon/map.h index 614a306..e8559f3 100644 --- a/include/dungeon/map.h +++ b/include/dungeon/map.h @@ -20,7 +20,7 @@ struct dungeon_context; struct dungeon_map; -struct dungeon_map *dungeon_map_create(void); +struct dungeon_map *dungeon_map_create(enum draw_dungeon_version version); void dungeon_map_free(struct dungeon_map *map); void dungeon_map_init(struct dungeon_context *ctx); void dungeon_map_update_cell(struct dungeon_context *ctx, int x, int y, int z); diff --git a/include/dungeon/renderer.h b/include/dungeon/renderer.h index 014f5d8..4919365 100644 --- a/include/dungeon/renderer.h +++ b/include/dungeon/renderer.h @@ -24,7 +24,7 @@ struct dgn_cell; struct dtx; struct dungeon_renderer; -struct dungeon_renderer *dungeon_renderer_create(struct dtx *dtx, GLuint *event_textures, int nr_event_textures); +struct dungeon_renderer *dungeon_renderer_create(enum draw_dungeon_version version, struct dtx *dtx, GLuint *event_textures, int nr_event_textures); void dungeon_renderer_free(struct dungeon_renderer *r); void dungeon_renderer_render(struct dungeon_renderer *r, struct dgn_cell **cells, int nr_cells, mat4 view_transform, mat4 proj_transform); diff --git a/src/dungeon/dungeon.c b/src/dungeon/dungeon.c index 4bcbdc1..e8263b8 100644 --- a/src/dungeon/dungeon.c +++ b/src/dungeon/dungeon.c @@ -25,6 +25,7 @@ #include "system4/archive.h" #include "system4/cg.h" #include "system4/dlf.h" +#include "system4/file.h" #include "dungeon/dgn.h" #include "dungeon/dtx.h" @@ -43,9 +44,10 @@ #define M_PI (3.14159265358979323846) #endif -struct dungeon_context *dungeon_context_create(int surface) +struct dungeon_context *dungeon_context_create(enum draw_dungeon_version version, int surface) { struct dungeon_context *ctx = xcalloc(1, sizeof(struct dungeon_context)); + ctx->version = version; ctx->surface = surface; struct sact_sprite *sp = sact_get_sprite(ctx->surface); if (!sp) @@ -59,7 +61,7 @@ struct dungeon_context *dungeon_context_create(int surface) glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, texture->w, texture->h); glBindRenderbuffer(GL_RENDERBUFFER, 0); - ctx->map = dungeon_map_create(); + ctx->map = dungeon_map_create(version); return ctx; } @@ -76,7 +78,8 @@ void dungeon_context_free(struct dungeon_context *ctx) dungeon_renderer_free(ctx->renderer); glDeleteRenderbuffers(1, &ctx->depth_buffer); - dungeon_map_free(ctx->map); + if (ctx->map) + dungeon_map_free(ctx->map); free(ctx); } @@ -127,34 +130,65 @@ bool dungeon_load(struct dungeon_context *ctx, int num) if (ctx->loaded) VM_ERROR("Dungeon is already loaded"); - char *path = gamedir_path("Data/DungeonData.dlf"); - int error = ARCHIVE_SUCCESS; - struct archive *dlf = (struct archive *)dlf_open(path, ARCHIVE_MMAP, &error); - if (error == ARCHIVE_FILE_ERROR) { - WARNING("dlf_open(\"%s\"): %s", path, strerror(errno)); - } else if (error == ARCHIVE_BAD_ARCHIVE_ERROR) { - WARNING("dlf_open(\"%s\"): invalid .dlf file", path); - } - free(path); - if (!dlf) - return false; + if (ctx->version == DRAW_DUNGEON_1) { + char *path = gamedir_path("Data/DungeonData.dlf"); + int error = ARCHIVE_SUCCESS; + struct archive *dlf = (struct archive *)dlf_open(path, ARCHIVE_MMAP, &error); + if (error == ARCHIVE_FILE_ERROR) { + WARNING("dlf_open(\"%s\"): %s", path, strerror(errno)); + } else if (error == ARCHIVE_BAD_ARCHIVE_ERROR) { + WARNING("dlf_open(\"%s\"): invalid .dlf file", path); + } + free(path); + if (!dlf) + return false; - struct archive_data *dgn = archive_get(dlf, num * 3); - if (dgn) { - ctx->dgn = dgn_parse(dgn->data, dgn->size); - archive_free_data(dgn); + struct archive_data *dgn = archive_get(dlf, num * 3); + if (dgn) { + ctx->dgn = dgn_parse(dgn->data, dgn->size); + archive_free_data(dgn); + } + struct archive_data *dtx = archive_get(dlf, num * 3 + 1); + if (dtx) { + ctx->dtx = dtx_parse(dtx->data, dtx->size); + archive_free_data(dtx); + } + struct archive_data *tes = archive_get(dlf, num * 3 + 2); + if (tes) { + ctx->tes = tes_parse(tes->data, tes->size); + archive_free_data(tes); + } + archive_free(dlf); + } else if (ctx->version == DRAW_DUNGEON_14) { + char buf[100]; + sprintf(buf, "Data/map%02d.dgn", num); + char *path = gamedir_path(buf); + + size_t len; + uint8_t *dgn = file_read(path, &len); + if (dgn) { + ctx->dgn = dgn_parse(dgn, len); + free(dgn); + } + + strcpy(path + strlen(path) - 3, "dtx"); + uint8_t *dtx = file_read(path, &len); + if (dtx) { + ctx->dtx = dtx_parse(dtx, len); + free(dtx); + } + + strcpy(path + strlen(path) - 3, "tes"); + uint8_t *tes = file_read(path, &len); + if (tes) { + ctx->tes = tes_parse(tes, len); + free(tes); + } + free(path); + } else { + ERROR("Invalid DrawDungeon version %d", ctx->version); } - struct archive_data *dtx = archive_get(dlf, num * 3 + 1); - if (dtx) { - ctx->dtx = dtx_parse(dtx->data, dtx->size); - archive_free_data(dtx); - } - struct archive_data *tes = archive_get(dlf, num * 3 + 2); - if (tes) { - ctx->tes = tes_parse(tes->data, tes->size); - archive_free_data(tes); - } - archive_free(dlf); + if (!ctx->dgn || !ctx->dtx) { WARNING("Cannot load dungeon %d", num); return false; @@ -165,7 +199,7 @@ bool dungeon_load(struct dungeon_context *ctx, int num) if (!event_textures) return false; - ctx->renderer = dungeon_renderer_create(ctx->dtx, event_textures, nr_event_textures); + ctx->renderer = dungeon_renderer_create(ctx->version, ctx->dtx, event_textures, nr_event_textures); dungeon_map_init(ctx); @@ -257,14 +291,24 @@ void dungeon_set_walked(int surface, int x, int y, int z, int flag) return; dgn_cell_at(ctx->dgn, x, y, z)->walked = 1; dungeon_map_reveal(ctx, x, y, z); - if (x > 0) - neighbor_reveal(ctx, x - 1, y, z); - if (x + 1u < ctx->dgn->size_x) - neighbor_reveal(ctx, x + 1, y, z); - if (z > 0) - neighbor_reveal(ctx, x, y, z - 1); - if (z + 1u < ctx->dgn->size_z) - neighbor_reveal(ctx, x, y, z + 1); + if (ctx->version == DRAW_DUNGEON_1) { + if (x > 0) + neighbor_reveal(ctx, x - 1, y, z); + if (x + 1u < ctx->dgn->size_x) + neighbor_reveal(ctx, x + 1, y, z); + if (z > 0) + neighbor_reveal(ctx, x, y, z - 1); + if (z + 1u < ctx->dgn->size_z) + neighbor_reveal(ctx, x, y, z + 1); + } +} + +int dungeon_get_walked(int surface, int x, int y, int z) +{ + struct dungeon_context *ctx = dungeon_get_context(surface); + if (!ctx || !ctx->dgn) + return 0; + return dgn_cell_at(ctx->dgn, x, y, z)->walked; } int dungeon_calc_conquer(int surface) @@ -276,7 +320,7 @@ int dungeon_calc_conquer(int surface) } /* - * WalkData serialization format (in Rance VI): + * WalkData serialization format: * * struct WalkData { * int version; // zero diff --git a/src/dungeon/map.c b/src/dungeon/map.c index de3c627..6f52d1e 100644 --- a/src/dungeon/map.c +++ b/src/dungeon/map.c @@ -70,8 +70,11 @@ static Point texture_pos(struct dungeon_context *ctx, int x, int z) }; } -struct dungeon_map *dungeon_map_create(void) +struct dungeon_map *dungeon_map_create(enum draw_dungeon_version version) { + if (version == DRAW_DUNGEON_14) + return NULL; // GALZOO does not use DrawDungeon's 2D map functions. + struct dungeon_map *map = xcalloc(1, sizeof(struct dungeon_map)); map->small_map_floor = -1; map->large_map_floor = -1; @@ -90,6 +93,8 @@ void dungeon_map_init(struct dungeon_context *ctx) { struct dungeon_map *map = ctx->map; struct dgn *dgn = ctx->dgn; + if (!map) + return; map->textures = xcalloc(dgn->size_y, sizeof(struct texture)); map->nr_textures = dgn->size_y; @@ -128,6 +133,8 @@ void dungeon_map_init(struct dungeon_context *ctx) void dungeon_map_reveal(struct dungeon_context *ctx, int x, int y, int z) { + if (!ctx->map) + return; struct texture *dst = &ctx->map->textures[y]; Point pos = texture_pos(ctx, x, z); gfx_fill_amap(dst, pos.x, pos.y, CS, CS, 255); @@ -154,6 +161,8 @@ static void draw_symbol(struct dungeon_context *ctx, struct texture *dst, int x, void dungeon_map_update_cell(struct dungeon_context *ctx, int dgn_x, int dgn_y, int dgn_z) { + if (!ctx->map) + return; struct dgn_cell *cell = dgn_cell_at(ctx->dgn, dgn_x, dgn_y, dgn_z); struct texture *dst = &ctx->map->textures[dgn_y]; Point pos = texture_pos(ctx, dgn_x, dgn_z); @@ -238,7 +247,7 @@ static int player_symbol(struct dungeon_context *ctx) void dungeon_map_draw(int surface, int sprite) { struct dungeon_context *ctx = dungeon_get_context(surface); - if (!ctx) + if (!ctx || !ctx->map) return; struct sact_sprite *sp = sact_get_sprite(sprite); if (!sp) @@ -270,7 +279,7 @@ void dungeon_map_draw(int surface, int sprite) void dungeon_map_draw_lmap(int surface, int sprite) { struct dungeon_context *ctx = dungeon_get_context(surface); - if (!ctx) + if (!ctx || !ctx->map) return; struct sact_sprite *sp = sact_get_sprite(sprite); if (!sp) @@ -307,7 +316,7 @@ static void redraw_event_symbols(struct dungeon_context *ctx) void dungeon_map_set_radar(int surface, int flag) { struct dungeon_context *ctx = dungeon_get_context(surface); - if (!ctx || ctx->map->radar == flag) + if (!ctx || !ctx->map || ctx->map->radar == flag) return; ctx->map->radar = flag; redraw_event_symbols(ctx); @@ -316,7 +325,7 @@ void dungeon_map_set_radar(int surface, int flag) void dungeon_map_set_all_view(int surface, int flag) { struct dungeon_context *ctx = dungeon_get_context(surface); - if (!ctx || ctx->map->all_visible == flag) + if (!ctx || !ctx->map || ctx->map->all_visible == flag) return; ctx->map->all_visible = flag; redraw_event_symbols(ctx); @@ -325,7 +334,7 @@ void dungeon_map_set_all_view(int surface, int flag) void dungeon_map_set_cg(int surface, int index, int sprite) { struct dungeon_context *ctx = dungeon_get_context(surface); - if (!ctx) + if (!ctx || !ctx->map) return; if (index < 0 || index >= NR_SYMBOLS) VM_ERROR("DrawDungeon.SetMapCG: index %d is out of bounds", index); @@ -335,7 +344,7 @@ void dungeon_map_set_cg(int surface, int index, int sprite) void dungeon_map_set_small_map_floor(int surface, int floor) { struct dungeon_context *ctx = dungeon_get_context(surface); - if (!ctx) + if (!ctx || !ctx->map) return; ctx->map->small_map_floor = floor; } @@ -343,7 +352,7 @@ void dungeon_map_set_small_map_floor(int surface, int floor) void dungeon_map_set_large_map_floor(int surface, int floor) { struct dungeon_context *ctx = dungeon_get_context(surface); - if (!ctx) + if (!ctx || !ctx->map) return; ctx->map->large_map_floor = floor; } diff --git a/src/dungeon/renderer.c b/src/dungeon/renderer.c index 9f27f15..f1f5338 100644 --- a/src/dungeon/renderer.c +++ b/src/dungeon/renderer.c @@ -22,6 +22,7 @@ #include "system4.h" #include "system4/cg.h" +#include "dungeon/dungeon.h" #include "dungeon/dgn.h" #include "dungeon/dtx.h" #include "dungeon/renderer.h" @@ -35,31 +36,40 @@ struct marker_info { int floor_marker; }; -enum rance6_floor_marker { - MAGIC_CIRCLE = 1, - RED_OCTAGRAM = 63, +enum floor_marker { + // Rance VI + R6_MAGIC_CIRCLE = 1, + R6_RED_OCTAGRAM = 63, + // GALZOO Island + GZ_MAGIC_CIRCLE = 0, }; static const struct marker_info rance6_marker_info[] = { - { 11, 41, 3, MAGIC_CIRCLE}, // treasure chest - { 12, 51, 7, RED_OCTAGRAM}, // enemy - { 14, 8, 5, MAGIC_CIRCLE}, // green star - { 15, 21, 10, MAGIC_CIRCLE}, // heart - { 16, 45, 5, MAGIC_CIRCLE}, // BP cross - { 17, 58, 5, MAGIC_CIRCLE}, // exit - { 18, 31, 10, MAGIC_CIRCLE}, // teleporter - {140, 13, 5, RED_OCTAGRAM}, // red star + { 11, 41, 3, R6_MAGIC_CIRCLE}, // treasure chest + { 12, 51, 7, R6_RED_OCTAGRAM}, // enemy + { 14, 8, 5, R6_MAGIC_CIRCLE}, // green star + { 15, 21, 10, R6_MAGIC_CIRCLE}, // heart + { 16, 45, 5, R6_MAGIC_CIRCLE}, // BP cross + { 17, 58, 5, R6_MAGIC_CIRCLE}, // exit + { 18, 31, 10, R6_MAGIC_CIRCLE}, // teleporter + {140, 13, 5, R6_RED_OCTAGRAM}, // red star {0}, }; -static const struct marker_info *get_marker_info(int event_type) -{ - for (const struct marker_info *info = rance6_marker_info; info->event_type; info++) { - if (info->event_type == event_type) - return info; - } - return NULL; -} +static const struct marker_info galzoo_marker_info[] = { + {11, 1, 1, GZ_MAGIC_CIRCLE}, // item + {12, 2, 1, GZ_MAGIC_CIRCLE}, // enemy + {14, 3, 1, GZ_MAGIC_CIRCLE}, // star + {15, 4, 1, GZ_MAGIC_CIRCLE}, // heart + {17, 5, 1, GZ_MAGIC_CIRCLE}, // exit + {18, 6, 1, GZ_MAGIC_CIRCLE}, // teleporter + {0}, +}; + +static const struct marker_info *marker_tables[] = { + [DRAW_DUNGEON_1] = rance6_marker_info, + [DRAW_DUNGEON_14] = galzoo_marker_info +}; struct geometry; struct material; @@ -84,10 +94,20 @@ struct dungeon_renderer { GLuint *event_textures; int nr_event_textures; + const struct marker_info *marker_table; struct skybox *skybox; }; +static const struct marker_info *get_marker_info(struct dungeon_renderer *r, int event_type) +{ + for (const struct marker_info *info = r->marker_table; info->event_type; info++) { + if (info->event_type == event_type) + return info; + } + return NULL; +} + struct vertex { GLfloat x, y, z, u, v; }; @@ -213,7 +233,7 @@ static struct material *get_material(struct dungeon_renderer *r, int type, int i return m; } -struct dungeon_renderer *dungeon_renderer_create(struct dtx *dtx, GLuint *event_textures, int nr_event_textures) +struct dungeon_renderer *dungeon_renderer_create(enum draw_dungeon_version version, struct dtx *dtx, GLuint *event_textures, int nr_event_textures) { struct dungeon_renderer *r = xcalloc(1, sizeof(struct dungeon_renderer)); @@ -240,6 +260,7 @@ struct dungeon_renderer *dungeon_renderer_create(struct dtx *dtx, GLuint *event_ r->event_textures = event_textures; r->nr_event_textures = nr_event_textures; + r->marker_table = marker_tables[version]; r->skybox = skybox_create(dtx); @@ -482,7 +503,7 @@ static void draw_cell(struct dungeon_renderer *r, struct dgn_cell *cell, bool re } } if (cell->floor_event && !render_opaque) { - const struct marker_info *info = get_marker_info(cell->floor_event); + const struct marker_info *info = get_marker_info(r, cell->floor_event); if (info) { uint32_t t = SDL_GetTicks(); draw_floor_marker(r, info, x, y, z, t); diff --git a/src/ffi.c b/src/ffi.c index 42fd856..cefdeea 100644 --- a/src/ffi.c +++ b/src/ffi.c @@ -291,6 +291,7 @@ extern struct static_library lib_Confirm2; extern struct static_library lib_CrayfishLogViewer; extern struct static_library lib_DataFile; extern struct static_library lib_DrawDungeon; +extern struct static_library lib_DrawDungeon14; extern struct static_library lib_DrawGraph; extern struct static_library lib_DrawMovie2; extern struct static_library lib_DrawPluginManager; @@ -339,6 +340,7 @@ static struct static_library *static_libraries[] = { &lib_CrayfishLogViewer, &lib_DataFile, &lib_DrawDungeon, + &lib_DrawDungeon14, &lib_DrawGraph, &lib_DrawMovie2, &lib_DrawPluginManager, diff --git a/src/hll/DrawDungeon.c b/src/hll/DrawDungeon.c index 37cd395..c968481 100644 --- a/src/hll/DrawDungeon.c +++ b/src/hll/DrawDungeon.c @@ -28,6 +28,16 @@ static struct dungeon_context *current_context = NULL; +static int dungeon_init(enum draw_dungeon_version version, int surface) +{ + if (current_context) + VM_ERROR("Dungeon is already associated with surface %d", current_context->surface); + if (surface < 0) + return 0; + current_context = dungeon_context_create(version, surface); + return 1; +} + struct dungeon_context *dungeon_get_context(int surface) { if (!current_context || surface != current_context->surface) @@ -49,14 +59,22 @@ static struct dgn_cell *dungeon_get_cell(int surface, int x, int y, int z) return dgn_cell_at(ctx->dgn, x, y, z); } +static void DrawDungeon_ModuleFini(void) +{ + if (current_context) { + dungeon_context_free(current_context); + current_context = NULL; + } +} + static int DrawDungeon_Init(int surface) { - if (current_context) - VM_ERROR("Dungeon is already associated with surface %d", current_context->surface); - if (surface < 0) - return 0; - current_context = dungeon_context_create(surface); - return 1; + return dungeon_init(DRAW_DUNGEON_1, surface); +} + +static int DrawDungeon14_Init(int surface) +{ + return dungeon_init(DRAW_DUNGEON_14, surface); } static void DrawDungeon_Release(int surface) @@ -261,123 +279,143 @@ static int DrawDungeon_GetTexSound(int surface, int type, int num) HLL_QUIET_UNIMPLEMENTED( , void, DrawDungeon, StopTimer, void); HLL_QUIET_UNIMPLEMENTED( , void, DrawDungeon, RestartTimer, void); +#define DRAW_DUNGEON_EXPORTS \ + HLL_EXPORT(_ModuleFini, DrawDungeon_ModuleFini), \ + HLL_EXPORT(Release, DrawDungeon_Release), \ + HLL_EXPORT(SetDrawFlag, DrawDungeon_SetDrawFlag), \ + HLL_EXPORT(BeginLoad, DrawDungeon_BeginLoad), \ + HLL_EXPORT(IsLoading, DrawDungeon_IsLoading), \ + HLL_EXPORT(IsSucceededLoading, DrawDungeon_IsSucceededLoading), \ + HLL_TODO_EXPORT(GetLoadingPercent, DrawDungeon_GetLoadingPercent), \ + HLL_TODO_EXPORT(LoadFromFile, DrawDungeon_LoadFromFile), \ + HLL_TODO_EXPORT(LoadTexture, DrawDungeon_LoadTexture), \ + HLL_TODO_EXPORT(LoadEventTexture, DrawDungeon_LoadEventTexture), \ + HLL_EXPORT(GetMapX, DrawDungeon_GetMapX), \ + HLL_EXPORT(GetMapY, DrawDungeon_GetMapY), \ + HLL_EXPORT(GetMapZ, DrawDungeon_GetMapZ), \ + HLL_EXPORT(SetCamera, dungeon_set_camera), \ + HLL_EXPORT(IsInMap, DrawDungeon_IsInMap), \ + HLL_EXPORT(IsFloor, DrawDungeon_IsFloor), \ + HLL_TODO_EXPORT(IsFloorFillTexture, DrawDungeon_IsFloorFillTexture), \ + HLL_EXPORT(IsStair, DrawDungeon_IsStair), \ + HLL_EXPORT(IsStairN, DrawDungeon_IsStairN), \ + HLL_EXPORT(IsStairW, DrawDungeon_IsStairW), \ + HLL_EXPORT(IsStairS, DrawDungeon_IsStairS), \ + HLL_EXPORT(IsStairE, DrawDungeon_IsStairE), \ + HLL_EXPORT(IsWallN, DrawDungeon_IsWallN), \ + HLL_EXPORT(IsWallW, DrawDungeon_IsWallW), \ + HLL_EXPORT(IsWallS, DrawDungeon_IsWallS), \ + HLL_EXPORT(IsWallE, DrawDungeon_IsWallE), \ + HLL_EXPORT(IsDoorN, DrawDungeon_IsDoorN), \ + HLL_EXPORT(IsDoorW, DrawDungeon_IsDoorW), \ + HLL_EXPORT(IsDoorS, DrawDungeon_IsDoorS), \ + HLL_EXPORT(IsDoorE, DrawDungeon_IsDoorE), \ + HLL_EXPORT(IsEnter, DrawDungeon_IsEnter), \ + HLL_EXPORT(IsEnterN, DrawDungeon_IsEnterN), \ + HLL_EXPORT(IsEnterW, DrawDungeon_IsEnterW), \ + HLL_EXPORT(IsEnterS, DrawDungeon_IsEnterS), \ + HLL_EXPORT(IsEnterE, DrawDungeon_IsEnterE), \ + HLL_EXPORT(GetEvFloor, DrawDungeon_GetEvFloor), \ + HLL_EXPORT(GetEvWallN, DrawDungeon_GetEvWallN), \ + HLL_EXPORT(GetEvWallW, DrawDungeon_GetEvWallW), \ + HLL_EXPORT(GetEvWallS, DrawDungeon_GetEvWallS), \ + HLL_EXPORT(GetEvWallE, DrawDungeon_GetEvWallE), \ + HLL_EXPORT(GetEvFloor2, DrawDungeon_GetEvFloor2), \ + HLL_EXPORT(GetEvWallN2, DrawDungeon_GetEvWallN2), \ + HLL_EXPORT(GetEvWallW2, DrawDungeon_GetEvWallW2), \ + HLL_EXPORT(GetEvWallS2, DrawDungeon_GetEvWallS2), \ + HLL_EXPORT(GetEvWallE2, DrawDungeon_GetEvWallE2), \ + HLL_EXPORT(GetTexFloor, DrawDungeon_GetTexFloor), \ + HLL_EXPORT(GetTexCeiling, DrawDungeon_GetTexCeiling), \ + HLL_EXPORT(GetTexWallN, DrawDungeon_GetTexWallN), \ + HLL_EXPORT(GetTexWallW, DrawDungeon_GetTexWallW), \ + HLL_EXPORT(GetTexWallS, DrawDungeon_GetTexWallS), \ + HLL_EXPORT(GetTexWallE, DrawDungeon_GetTexWallE), \ + HLL_EXPORT(GetTexDoorN, DrawDungeon_GetTexDoorN), \ + HLL_EXPORT(GetTexDoorW, DrawDungeon_GetTexDoorW), \ + HLL_EXPORT(GetTexDoorS, DrawDungeon_GetTexDoorS), \ + HLL_EXPORT(GetTexDoorE, DrawDungeon_GetTexDoorE), \ + HLL_EXPORT(GetTexStair, DrawDungeon_GetTexStair), \ + HLL_EXPORT(GetBattleBack, DrawDungeon_GetBattleBack), \ + HLL_EXPORT(SetDoorNAngle, DrawDungeon_SetDoorNAngle), \ + HLL_EXPORT(SetDoorWAngle, DrawDungeon_SetDoorWAngle), \ + HLL_EXPORT(SetDoorSAngle, DrawDungeon_SetDoorSAngle), \ + HLL_EXPORT(SetDoorEAngle, DrawDungeon_SetDoorEAngle), \ + HLL_EXPORT(SetEvFloor, DrawDungeon_SetEvFloor), \ + HLL_EXPORT(SetEvWallN, DrawDungeon_SetEvWallN), \ + HLL_EXPORT(SetEvWallW, DrawDungeon_SetEvWallW), \ + HLL_EXPORT(SetEvWallS, DrawDungeon_SetEvWallS), \ + HLL_EXPORT(SetEvWallE, DrawDungeon_SetEvWallE), \ + HLL_EXPORT(SetEvFloor2, DrawDungeon_SetEvFloor2), \ + HLL_EXPORT(SetEvWallN2, DrawDungeon_SetEvWallN2), \ + HLL_EXPORT(SetEvWallW2, DrawDungeon_SetEvWallW2), \ + HLL_EXPORT(SetEvWallS2, DrawDungeon_SetEvWallS2), \ + HLL_EXPORT(SetEvWallE2, DrawDungeon_SetEvWallE2), \ + HLL_TODO_EXPORT(SetEvMag, DrawDungeon_SetEvMag), \ + HLL_EXPORT(SetEvRate, DrawDungeon_SetEvRate), \ + HLL_EXPORT(SetEnter, DrawDungeon_SetEnter), \ + HLL_EXPORT(SetEnterN, DrawDungeon_SetEnterN), \ + HLL_EXPORT(SetEnterW, DrawDungeon_SetEnterW), \ + HLL_EXPORT(SetEnterS, DrawDungeon_SetEnterS), \ + HLL_EXPORT(SetEnterE, DrawDungeon_SetEnterE), \ + HLL_EXPORT(SetTexFloor, DrawDungeon_SetTexFloor), \ + HLL_EXPORT(SetTexCeiling, DrawDungeon_SetTexCeiling), \ + HLL_EXPORT(SetTexWallN, DrawDungeon_SetTexWallN), \ + HLL_EXPORT(SetTexWallW, DrawDungeon_SetTexWallW), \ + HLL_EXPORT(SetTexWallS, DrawDungeon_SetTexWallS), \ + HLL_EXPORT(SetTexWallE, DrawDungeon_SetTexWallE), \ + HLL_EXPORT(SetTexDoorN, DrawDungeon_SetTexDoorN), \ + HLL_EXPORT(SetTexDoorW, DrawDungeon_SetTexDoorW), \ + HLL_EXPORT(SetTexDoorS, DrawDungeon_SetTexDoorS), \ + HLL_EXPORT(SetTexDoorE, DrawDungeon_SetTexDoorE), \ + HLL_TODO_EXPORT(SetSkyTextureSet, DrawDungeon_SetSkyTextureSet), \ + HLL_EXPORT(DrawMap, dungeon_map_draw), \ + HLL_EXPORT(SetMapAllViewFlag, dungeon_map_set_all_view), \ + HLL_EXPORT(SetDrawMapFloor, dungeon_map_set_small_map_floor), \ + HLL_EXPORT(DrawLMap, dungeon_map_draw_lmap), \ + HLL_EXPORT(SetMapCG, dungeon_map_set_cg), \ + HLL_EXPORT(SetDrawLMapFloor, dungeon_map_set_large_map_floor), \ + HLL_EXPORT(SetDrawMapRadar, dungeon_map_set_radar), \ + HLL_EXPORT(SetDrawHalfFlag, DrawDungeon_SetDrawHalfFlag), \ + HLL_EXPORT(GetDrawHalfFlag, DrawDungeon_GetDrawHalfFlag), \ + HLL_EXPORT(SetWalked, dungeon_set_walked), \ + HLL_TODO_EXPORT(SetWalkedAll, DrawDungeon_SetWalkedAll), \ + HLL_TODO_EXPORT(CalcNumofFloor, DrawDungeon_CalcNumofFloor), \ + HLL_TODO_EXPORT(CalcNumofWalk, DrawDungeon_CalcNumofWalk), \ + HLL_TODO_EXPORT(CalcNumofWalk2, DrawDungeon_CalcNumofWalk2), \ + HLL_EXPORT(CalcConquer, dungeon_calc_conquer), \ + HLL_EXPORT(SetInterlaceMode, DrawDungeon_SetInterlaceMode), \ + HLL_EXPORT(SetDirect3DMode, DrawDungeon_SetDirect3DMode), \ + HLL_EXPORT(SaveDrawSettingFlag, DrawDungeon_SaveDrawSettingFlag), \ + HLL_EXPORT(GetDrawSettingFlag, DrawDungeon_GetDrawSettingFlag), \ + HLL_EXPORT(IsDrawSettingFile, DrawDungeon_IsDrawSettingFile), \ + HLL_EXPORT(DeleteDrawSettingFile, DrawDungeon_DeleteDrawSettingFile), \ + HLL_EXPORT(IsSSEFlag, DrawDungeon_IsSSEFlag), \ + HLL_EXPORT(SetSSEFlag, DrawDungeon_SetSSEFlag), \ + HLL_EXPORT(IsPVSData, DrawDungeon_IsPVSData), \ + HLL_EXPORT(GetTexSound, DrawDungeon_GetTexSound), \ + HLL_EXPORT(StopTimer, DrawDungeon_StopTimer), \ + HLL_EXPORT(RestartTimer, DrawDungeon_RestartTimer), \ + HLL_EXPORT(LoadWalkData, dungeon_load_walk_data), \ + HLL_EXPORT(SaveWalkData, dungeon_save_walk_data) + HLL_LIBRARY(DrawDungeon, - HLL_EXPORT(Init, DrawDungeon_Init), - HLL_EXPORT(Release, DrawDungeon_Release), - HLL_EXPORT(SetDrawFlag, DrawDungeon_SetDrawFlag), - HLL_EXPORT(BeginLoad, DrawDungeon_BeginLoad), - HLL_EXPORT(IsLoading, DrawDungeon_IsLoading), - HLL_EXPORT(IsSucceededLoading, DrawDungeon_IsSucceededLoading), - HLL_TODO_EXPORT(GetLoadingPercent, DrawDungeon_GetLoadingPercent), - HLL_TODO_EXPORT(LoadFromFile, DrawDungeon_LoadFromFile), - HLL_TODO_EXPORT(LoadTexture, DrawDungeon_LoadTexture), - HLL_TODO_EXPORT(LoadEventTexture, DrawDungeon_LoadEventTexture), - HLL_EXPORT(GetMapX, DrawDungeon_GetMapX), - HLL_EXPORT(GetMapY, DrawDungeon_GetMapY), - HLL_EXPORT(GetMapZ, DrawDungeon_GetMapZ), - HLL_EXPORT(SetCamera, dungeon_set_camera), - HLL_EXPORT(IsInMap, DrawDungeon_IsInMap), - HLL_EXPORT(IsFloor, DrawDungeon_IsFloor), - HLL_TODO_EXPORT(IsFloorFillTexture, DrawDungeon_IsFloorFillTexture), - HLL_EXPORT(IsStair, DrawDungeon_IsStair), - HLL_EXPORT(IsStairN, DrawDungeon_IsStairN), - HLL_EXPORT(IsStairW, DrawDungeon_IsStairW), - HLL_EXPORT(IsStairS, DrawDungeon_IsStairS), - HLL_EXPORT(IsStairE, DrawDungeon_IsStairE), - HLL_EXPORT(IsWallN, DrawDungeon_IsWallN), - HLL_EXPORT(IsWallW, DrawDungeon_IsWallW), - HLL_EXPORT(IsWallS, DrawDungeon_IsWallS), - HLL_EXPORT(IsWallE, DrawDungeon_IsWallE), - HLL_EXPORT(IsDoorN, DrawDungeon_IsDoorN), - HLL_EXPORT(IsDoorW, DrawDungeon_IsDoorW), - HLL_EXPORT(IsDoorS, DrawDungeon_IsDoorS), - HLL_EXPORT(IsDoorE, DrawDungeon_IsDoorE), - HLL_EXPORT(IsEnter, DrawDungeon_IsEnter), - HLL_EXPORT(IsEnterN, DrawDungeon_IsEnterN), - HLL_EXPORT(IsEnterW, DrawDungeon_IsEnterW), - HLL_EXPORT(IsEnterS, DrawDungeon_IsEnterS), - HLL_EXPORT(IsEnterE, DrawDungeon_IsEnterE), - HLL_EXPORT(GetEvFloor, DrawDungeon_GetEvFloor), - HLL_EXPORT(GetEvWallN, DrawDungeon_GetEvWallN), - HLL_EXPORT(GetEvWallW, DrawDungeon_GetEvWallW), - HLL_EXPORT(GetEvWallS, DrawDungeon_GetEvWallS), - HLL_EXPORT(GetEvWallE, DrawDungeon_GetEvWallE), - HLL_EXPORT(GetEvFloor2, DrawDungeon_GetEvFloor2), - HLL_EXPORT(GetEvWallN2, DrawDungeon_GetEvWallN2), - HLL_EXPORT(GetEvWallW2, DrawDungeon_GetEvWallW2), - HLL_EXPORT(GetEvWallS2, DrawDungeon_GetEvWallS2), - HLL_EXPORT(GetEvWallE2, DrawDungeon_GetEvWallE2), - HLL_EXPORT(GetTexFloor, DrawDungeon_GetTexFloor), - HLL_EXPORT(GetTexCeiling, DrawDungeon_GetTexCeiling), - HLL_EXPORT(GetTexWallN, DrawDungeon_GetTexWallN), - HLL_EXPORT(GetTexWallW, DrawDungeon_GetTexWallW), - HLL_EXPORT(GetTexWallS, DrawDungeon_GetTexWallS), - HLL_EXPORT(GetTexWallE, DrawDungeon_GetTexWallE), - HLL_EXPORT(GetTexDoorN, DrawDungeon_GetTexDoorN), - HLL_EXPORT(GetTexDoorW, DrawDungeon_GetTexDoorW), - HLL_EXPORT(GetTexDoorS, DrawDungeon_GetTexDoorS), - HLL_EXPORT(GetTexDoorE, DrawDungeon_GetTexDoorE), - HLL_EXPORT(GetTexStair, DrawDungeon_GetTexStair), - HLL_EXPORT(GetBattleBack, DrawDungeon_GetBattleBack), - HLL_EXPORT(SetDoorNAngle, DrawDungeon_SetDoorNAngle), - HLL_EXPORT(SetDoorWAngle, DrawDungeon_SetDoorWAngle), - HLL_EXPORT(SetDoorSAngle, DrawDungeon_SetDoorSAngle), - HLL_EXPORT(SetDoorEAngle, DrawDungeon_SetDoorEAngle), - HLL_EXPORT(SetEvFloor, DrawDungeon_SetEvFloor), - HLL_EXPORT(SetEvWallN, DrawDungeon_SetEvWallN), - HLL_EXPORT(SetEvWallW, DrawDungeon_SetEvWallW), - HLL_EXPORT(SetEvWallS, DrawDungeon_SetEvWallS), - HLL_EXPORT(SetEvWallE, DrawDungeon_SetEvWallE), - HLL_EXPORT(SetEvFloor2, DrawDungeon_SetEvFloor2), - HLL_EXPORT(SetEvWallN2, DrawDungeon_SetEvWallN2), - HLL_EXPORT(SetEvWallW2, DrawDungeon_SetEvWallW2), - HLL_EXPORT(SetEvWallS2, DrawDungeon_SetEvWallS2), - HLL_EXPORT(SetEvWallE2, DrawDungeon_SetEvWallE2), - HLL_TODO_EXPORT(SetEvMag, DrawDungeon_SetEvMag), - HLL_EXPORT(SetEvRate, DrawDungeon_SetEvRate), - HLL_EXPORT(SetEnter, DrawDungeon_SetEnter), - HLL_EXPORT(SetEnterN, DrawDungeon_SetEnterN), - HLL_EXPORT(SetEnterW, DrawDungeon_SetEnterW), - HLL_EXPORT(SetEnterS, DrawDungeon_SetEnterS), - HLL_EXPORT(SetEnterE, DrawDungeon_SetEnterE), - HLL_EXPORT(SetTexFloor, DrawDungeon_SetTexFloor), - HLL_EXPORT(SetTexCeiling, DrawDungeon_SetTexCeiling), - HLL_EXPORT(SetTexWallN, DrawDungeon_SetTexWallN), - HLL_EXPORT(SetTexWallW, DrawDungeon_SetTexWallW), - HLL_EXPORT(SetTexWallS, DrawDungeon_SetTexWallS), - HLL_EXPORT(SetTexWallE, DrawDungeon_SetTexWallE), - HLL_EXPORT(SetTexDoorN, DrawDungeon_SetTexDoorN), - HLL_EXPORT(SetTexDoorW, DrawDungeon_SetTexDoorW), - HLL_EXPORT(SetTexDoorS, DrawDungeon_SetTexDoorS), - HLL_EXPORT(SetTexDoorE, DrawDungeon_SetTexDoorE), - HLL_TODO_EXPORT(SetSkyTextureSet, DrawDungeon_SetSkyTextureSet), - HLL_EXPORT(DrawMap, dungeon_map_draw), - HLL_EXPORT(SetMapAllViewFlag, dungeon_map_set_all_view), - HLL_EXPORT(SetDrawMapFloor, dungeon_map_set_small_map_floor), - HLL_EXPORT(DrawLMap, dungeon_map_draw_lmap), - HLL_EXPORT(SetMapCG, dungeon_map_set_cg), - HLL_EXPORT(SetDrawLMapFloor, dungeon_map_set_large_map_floor), - HLL_EXPORT(SetDrawMapRadar, dungeon_map_set_radar), - HLL_EXPORT(SetDrawHalfFlag, DrawDungeon_SetDrawHalfFlag), - HLL_EXPORT(GetDrawHalfFlag, DrawDungeon_GetDrawHalfFlag), - HLL_EXPORT(SetWalked, dungeon_set_walked), - HLL_TODO_EXPORT(SetWalkedAll, DrawDungeon_SetWalkedAll), - HLL_TODO_EXPORT(CalcNumofFloor, DrawDungeon_CalcNumofFloor), - HLL_TODO_EXPORT(CalcNumofWalk, DrawDungeon_CalcNumofWalk), - HLL_TODO_EXPORT(CalcNumofWalk2, DrawDungeon_CalcNumofWalk2), - HLL_EXPORT(CalcConquer, dungeon_calc_conquer), - HLL_EXPORT(SetInterlaceMode, DrawDungeon_SetInterlaceMode), - HLL_EXPORT(SetDirect3DMode, DrawDungeon_SetDirect3DMode), - HLL_EXPORT(SaveDrawSettingFlag, DrawDungeon_SaveDrawSettingFlag), - HLL_EXPORT(GetDrawSettingFlag, DrawDungeon_GetDrawSettingFlag), - HLL_EXPORT(IsDrawSettingFile, DrawDungeon_IsDrawSettingFile), - HLL_EXPORT(DeleteDrawSettingFile, DrawDungeon_DeleteDrawSettingFile), - HLL_EXPORT(IsSSEFlag, DrawDungeon_IsSSEFlag), - HLL_EXPORT(SetSSEFlag, DrawDungeon_SetSSEFlag), - HLL_EXPORT(IsPVSData, DrawDungeon_IsPVSData), - HLL_EXPORT(GetTexSound, DrawDungeon_GetTexSound), - HLL_EXPORT(StopTimer, DrawDungeon_StopTimer), - HLL_EXPORT(RestartTimer, DrawDungeon_RestartTimer), - HLL_EXPORT(LoadWalkData, dungeon_load_walk_data), - HLL_EXPORT(SaveWalkData, dungeon_save_walk_data) - ); + HLL_EXPORT(Init, DrawDungeon_Init), + DRAW_DUNGEON_EXPORTS + ); + +HLL_WARN_UNIMPLEMENTED( , void, DrawDungeon14, SetRasterAmp, int nSurface, float fAmp); +HLL_WARN_UNIMPLEMENTED( , void, DrawDungeon14, SetLapFilter, int surface, int type, int r, int g, int b); +HLL_WARN_UNIMPLEMENTED(1, bool, DrawDungeon14, GetDrawMapObjectFlag, int nSurface); +HLL_WARN_UNIMPLEMENTED( , void, DrawDungeon14, SetDrawMapObjectFlag, int nSurface, bool bFlag); + +HLL_LIBRARY(DrawDungeon14, + HLL_EXPORT(Init, DrawDungeon14_Init), + DRAW_DUNGEON_EXPORTS, + HLL_EXPORT(GetWalked, dungeon_get_walked), + HLL_TODO_EXPORT(SetRasterScroll, DrawDungeon14_SetRasterScroll), + HLL_EXPORT(SetRasterAmp, DrawDungeon14_SetRasterAmp), + HLL_EXPORT(SetLapFilter, DrawDungeon14_SetLapFilter), + HLL_EXPORT(GetDrawMapObjectFlag, DrawDungeon14_GetDrawMapObjectFlag), + HLL_EXPORT(SetDrawMapObjectFlag, DrawDungeon14_SetDrawMapObjectFlag) + ); From 1fdd88ff4d5fdd87610879a2b0fd0a920a04980c Mon Sep 17 00:00:00 2001 From: kichikuou Date: Sun, 13 Jun 2021 15:48:49 +0900 Subject: [PATCH 4/5] DrawDungeon14: Implement spinning motion of event markers --- src/dungeon/renderer.c | 57 +++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/src/dungeon/renderer.c b/src/dungeon/renderer.c index f1f5338..ffcc769 100644 --- a/src/dungeon/renderer.c +++ b/src/dungeon/renderer.c @@ -57,12 +57,12 @@ static const struct marker_info rance6_marker_info[] = { }; static const struct marker_info galzoo_marker_info[] = { - {11, 1, 1, GZ_MAGIC_CIRCLE}, // item - {12, 2, 1, GZ_MAGIC_CIRCLE}, // enemy - {14, 3, 1, GZ_MAGIC_CIRCLE}, // star - {15, 4, 1, GZ_MAGIC_CIRCLE}, // heart - {17, 5, 1, GZ_MAGIC_CIRCLE}, // exit - {18, 6, 1, GZ_MAGIC_CIRCLE}, // teleporter + {11, 1, 0, GZ_MAGIC_CIRCLE}, // item + {12, 2, 0, GZ_MAGIC_CIRCLE}, // enemy + {14, 3, 0, GZ_MAGIC_CIRCLE}, // star + {15, 4, 0, GZ_MAGIC_CIRCLE}, // heart + {17, 5, 0, GZ_MAGIC_CIRCLE}, // exit + {18, 6, 0, GZ_MAGIC_CIRCLE}, // teleporter {0}, }; @@ -87,6 +87,7 @@ struct dungeon_renderer { struct geometry *door_left_geometry; struct geometry *door_right_geometry; struct geometry *stairs_geometry; + struct geometry *floating_marker_geometry; struct material *materials; int nr_materials; @@ -162,6 +163,19 @@ static const struct vertex stairs_vertices[] = { {-1, -3/3.f, 3/3.f, 0, 12/12.f}, }; +static const struct vertex floating_marker_vertices[] = { + {-0.9, 0.9, 0.0, 0.0, 0.0}, + {-0.9, -0.9, 0.0, 0.0, 1.0}, + { 0.9, 0.9, 0.0, 1.0, 0.0}, + { 0.9, -0.9, 0.0, 1.0, 1.0}, + { 0.9, -0.9, 0.0, 1.0, 1.0}, // degenerate triangle + { 0.9, 0.9, 0.0, 0.0, 0.0}, // degenerate triangle + { 0.9, 0.9, 0.0, 0.0, 0.0}, + { 0.9, -0.9, 0.0, 0.0, 1.0}, + {-0.9, 0.9, 0.0, 1.0, 0.0}, + {-0.9, -0.9, 0.0, 1.0, 1.0}, +}; + struct geometry { GLuint vao; GLuint attr_buffer; @@ -247,6 +261,7 @@ struct dungeon_renderer *dungeon_renderer_create(enum draw_dungeon_version versi 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)); + r->floating_marker_geometry = geometry_create(r, floating_marker_vertices, sizeof(floating_marker_vertices)); const int nr_types = DTX_DOOR + 1; r->materials = xcalloc(nr_types * dtx->nr_columns, sizeof(struct material)); @@ -275,6 +290,7 @@ void dungeon_renderer_free(struct dungeon_renderer *r) geometry_free(r->door_left_geometry); geometry_free(r->door_right_geometry); geometry_free(r->stairs_geometry); + geometry_free(r->floating_marker_geometry); for (int i = 0; i < r->nr_materials; i++) delete_material(&r->materials[i]); @@ -344,17 +360,28 @@ static void draw_floor_marker(struct dungeon_renderer *r, const struct marker_in glDepthFunc(GL_LESS); } -static void draw_floating_marker(struct dungeon_renderer *r, const struct marker_info *info, float x, float y, float z, int blend_rate, uint32_t t, mat4 v) +static void draw_floating_marker(struct dungeon_renderer *r, const struct marker_info *info, float x, float y, float z, int blend_rate, uint32_t t, mat4 view_mat) { - int frame = t / 100; // 100ms per frame - int texture = info->texture_index + frame % info->texture_count; - mat4 billboard = MAT4( - v[0][0], v[0][1], v[0][2], x, - v[1][0], v[1][1], v[1][2], y, - v[2][0], v[2][1], v[2][2], z, - 0, 0, 0, 1); + int texture = info->texture_index; + mat4 m = MAT4( + 1, 0, 0, x, + 0, 1, 0, y, + 0, 0, 1, z, + 0, 0, 0, 1); + if (info->texture_count) { + int frame = t / 100; // 100ms per frame + texture += frame % info->texture_count; + // Make a billboard matrix + mat3 r; + glm_mat4_pick3t(view_mat, r); + glm_mat4_ins3(r, m); + } else { + float angle = t / -(M_PI * 100.0); + glm_rotate_y(m, angle, m); + } + glUniform1f(r->alpha_mod, blend_rate / 255.0); - draw(r, r->wall_geometry, r->event_textures[texture], billboard); + draw(r, r->floating_marker_geometry, r->event_textures[texture], m); glUniform1f(r->alpha_mod, 1.0); } From 946e3bdab6c9ce07cad42e195249cc97ce127519 Mon Sep 17 00:00:00 2001 From: kichikuou Date: Sun, 13 Jun 2021 16:55:20 +0900 Subject: [PATCH 5/5] DrawDungeon14: Implement {Get,Set}DrawMapObjectFlag --- include/dungeon/renderer.h | 2 ++ src/dungeon/renderer.c | 14 +++++++++++++- src/hll/DrawDungeon.c | 19 +++++++++++++++++-- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/include/dungeon/renderer.h b/include/dungeon/renderer.h index 4919365..2e4c993 100644 --- a/include/dungeon/renderer.h +++ b/include/dungeon/renderer.h @@ -27,5 +27,7 @@ struct dungeon_renderer; struct dungeon_renderer *dungeon_renderer_create(enum draw_dungeon_version version, struct dtx *dtx, GLuint *event_textures, int nr_event_textures); void dungeon_renderer_free(struct dungeon_renderer *r); void dungeon_renderer_render(struct dungeon_renderer *r, struct dgn_cell **cells, int nr_cells, mat4 view_transform, mat4 proj_transform); +void dungeon_renderer_enable_event_markers(struct dungeon_renderer *r, bool enable); +bool dungeon_renderer_event_markers_enabled(struct dungeon_renderer *r); #endif /* SYSTEM4_DUNGEON_RENDERER_H */ diff --git a/src/dungeon/renderer.c b/src/dungeon/renderer.c index ffcc769..c055d15 100644 --- a/src/dungeon/renderer.c +++ b/src/dungeon/renderer.c @@ -96,6 +96,7 @@ struct dungeon_renderer { GLuint *event_textures; int nr_event_textures; const struct marker_info *marker_table; + bool draw_event_markers; struct skybox *skybox; }; @@ -276,6 +277,7 @@ struct dungeon_renderer *dungeon_renderer_create(enum draw_dungeon_version versi r->event_textures = event_textures; r->nr_event_textures = nr_event_textures; r->marker_table = marker_tables[version]; + r->draw_event_markers = true; r->skybox = skybox_create(dtx); @@ -529,7 +531,7 @@ static void draw_cell(struct dungeon_renderer *r, struct dgn_cell *cell, bool re draw(r, r->stairs_geometry, material->texture, matrices[cell->stairs_orientation]); } } - if (cell->floor_event && !render_opaque) { + if (r->draw_event_markers && cell->floor_event && !render_opaque) { const struct marker_info *info = get_marker_info(r, cell->floor_event); if (info) { uint32_t t = SDL_GetTicks(); @@ -563,3 +565,13 @@ void dungeon_renderer_render(struct dungeon_renderer *r, struct dgn_cell **cells glUseProgram(0); } + +void dungeon_renderer_enable_event_markers(struct dungeon_renderer *r, bool enable) +{ + r->draw_event_markers = enable; +} + +bool dungeon_renderer_event_markers_enabled(struct dungeon_renderer *r) +{ + return r->draw_event_markers; +} diff --git a/src/hll/DrawDungeon.c b/src/hll/DrawDungeon.c index c968481..01bbeb9 100644 --- a/src/hll/DrawDungeon.c +++ b/src/hll/DrawDungeon.c @@ -23,6 +23,7 @@ #include "dungeon/dgn.h" #include "dungeon/dungeon.h" #include "dungeon/map.h" +#include "dungeon/renderer.h" #include "dungeon/tes.h" #include "hll.h" @@ -406,8 +407,22 @@ HLL_LIBRARY(DrawDungeon, HLL_WARN_UNIMPLEMENTED( , void, DrawDungeon14, SetRasterAmp, int nSurface, float fAmp); HLL_WARN_UNIMPLEMENTED( , void, DrawDungeon14, SetLapFilter, int surface, int type, int r, int g, int b); -HLL_WARN_UNIMPLEMENTED(1, bool, DrawDungeon14, GetDrawMapObjectFlag, int nSurface); -HLL_WARN_UNIMPLEMENTED( , void, DrawDungeon14, SetDrawMapObjectFlag, int nSurface, bool bFlag); + +bool DrawDungeon14_GetDrawMapObjectFlag(int surface) +{ + struct dungeon_context *ctx = dungeon_get_context(surface); + if (!ctx || !ctx->renderer) + return true; + return dungeon_renderer_event_markers_enabled(ctx->renderer); +} + +void DrawDungeon14_SetDrawMapObjectFlag(int surface, bool flag) +{ + struct dungeon_context *ctx = dungeon_get_context(surface); + if (!ctx || !ctx->renderer) + return; + dungeon_renderer_enable_event_markers(ctx->renderer, flag); +} HLL_LIBRARY(DrawDungeon14, HLL_EXPORT(Init, DrawDungeon14_Init),