This commit is contained in:
Nunuhara Cabbage
2021-06-20 11:00:41 -07:00
46 changed files with 1170 additions and 495 deletions
+7
View File
@@ -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)
{
+14 -1
View File
@@ -22,12 +22,19 @@
#include <stdint.h>
#include <GL/glew.h>
struct page;
struct dgn;
struct dtx;
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;
@@ -44,6 +51,7 @@ struct camera {
*/
struct dungeon_context {
enum draw_dungeon_version version;
int surface;
bool loaded;
bool draw_enabled;
@@ -56,11 +64,16 @@ 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);
struct dungeon_context *dungeon_get_context(int surface);
void dungeon_update(void);
+2 -6
View File
@@ -17,11 +17,10 @@
#ifndef SYSTEM4_DUNGEON_MAP_H
#define SYSTEM4_DUNGEON_MAP_H
struct page;
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);
@@ -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 */
+65
View File
@@ -0,0 +1,65 @@
/* Copyright (C) 2021 kichikuou <KichikuouChrome@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#ifndef SYSTEM4_POLYOBJ_H
#define SYSTEM4_POLYOBJ_H
#include <stddef.h>
#include <stdint.h>
#include <cglm/types.h>
struct polyobj_location {
uint32_t offset;
uint32_t length;
};
struct polyobj {
uint8_t *data;
size_t size;
int nr_textures;
struct polyobj_location *textures;
int nr_objects;
struct polyobj_location *objects;
};
struct polyobj_triangle {
int material;
int index[3];
vec2 uv[3];
};
struct polyobj_part {
int nr_vertices;
vec3 *vertices;
int nr_triangles;
struct polyobj_triangle *triangles;
};
struct polyobj_object {
char *name;
int nr_materials;
int *materials;
int nr_parts;
struct polyobj_part *parts;
};
struct polyobj *polyobj_load(const char *path);
void polyobj_free(struct polyobj *po);
struct cg *polyobj_get_texture(struct polyobj *po, int index);
struct polyobj_object *polyobj_get_object(struct polyobj *po, int index);
void polyobj_object_free(struct polyobj_object *obj);
#endif /* SYSTEM4_POLYOBJ_H */
+4 -1
View File
@@ -22,10 +22,13 @@
struct dgn_cell;
struct dtx;
struct polyobj;
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, struct polyobj *po);
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 */
+2 -2
View File
@@ -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;
@@ -88,7 +87,7 @@ void gfx_init_texture_blank(struct texture *t, int w, int h);
void gfx_init_texture_with_cg(struct texture *t, struct cg *cg);
void gfx_init_texture_rgba(struct texture *t, int w, int h, SDL_Color color);
void gfx_init_texture_rgb(struct texture *t, int w, int h, SDL_Color color);
void gfx_init_texture_with_pixels(struct texture *t, int w, int h, void *pixels, GLenum format);
void gfx_init_texture_with_pixels(struct texture *t, int w, int h, void *pixels);
void gfx_copy_main_surface(struct texture *dst);
void gfx_delete_texture(struct texture *t);
GLuint gfx_set_framebuffer(GLenum target, Texture *t, int x, int y, int w, int h);
@@ -102,6 +101,7 @@ void gfx_copy(struct texture *dst, int dx, int dy, struct texture *src, int sx,
void gfx_copy_bright(struct texture *dst, int dx, int dy, struct texture *src, int sx, int sy, int w, int h, int rate);
void gfx_copy_amap(struct texture *dst, int dx, int dy, struct texture *src, int sx, int sy, int w, int h);
void gfx_copy_sprite(struct texture *dst, int dx, int dy, struct texture *src, int sx, int sy, int w, int h, SDL_Color color);
void gfx_sprite_copy_amap(struct texture *dst, int dx, int dy, struct texture *src, int sx, int sy, int w, int h, int alpha_key);
void gfx_copy_color_reverse(struct texture *dst, int dx, int dy, struct texture *src, int sx, int sy, int w, int h);
void gfx_copy_use_amap_under(struct texture *dst, int dx, int dy, struct texture *src, int sx, int sy, int w, int h, int threshold);
void gfx_copy_use_amap_border(struct texture *dst, int dx, int dy, struct texture *src, int sx, int sy, int w, int h, int threshold);
+1 -1
View File
@@ -35,7 +35,7 @@ int sact_Effect(int type, int time, int key);
int sact_SP_GetUnuseNum(int min);
int sact_SP_Count(void);
int sact_SP_Enum(struct page **array);
#define sact_SP_GetMaxZ scene_get_max_z
int sact_SP_GetMaxZ(void);
int sact_SP_SetCG(int sp, int cg);
int sact_SP_SetCGFromFile(int sp, struct string *filename);
int sact_SP_SaveCG(int sp, struct string *filename);
-1
View File
@@ -47,7 +47,6 @@ void scene_render(void);
void scene_flip(void);
int scene_set_wp(int cg_no);
int scene_set_wp_color(int r, int g, int b);
int scene_get_max_z(void);
void scene_set_sprite_z(struct sprite *sp, int z);
void scene_set_sprite_z2(struct sprite *sp, int z, int z2);
-2
View File
@@ -14,8 +14,6 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#version 140
uniform sampler2D tex;
uniform float threshold;
-2
View File
@@ -14,8 +14,6 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#version 140
uniform sampler2D tex;
uniform vec4 color;
-2
View File
@@ -14,8 +14,6 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#version 140
uniform sampler2D tex;
in vec2 tex_coord;
+28
View File
@@ -0,0 +1,28 @@
/* Copyright (C) 2019 Nunuhara Cabbage <nunuhara@haniwa.technology>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
uniform sampler2D tex;
uniform vec4 color;
in vec2 tex_coord;
out vec4 frag_color;
void main() {
vec4 texel = texture(tex, tex_coord);
if (texel.a == color.a)
discard;
frag_color = texel;
}
-2
View File
@@ -14,8 +14,6 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#version 140
uniform sampler2D tex;
in vec2 tex_coord;
-2
View File
@@ -14,8 +14,6 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#version 140
uniform sampler2D tex;
uniform vec4 color;
-2
View File
@@ -14,8 +14,6 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#version 140
uniform sampler2D tex;
uniform float threshold;
-2
View File
@@ -14,8 +14,6 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#version 140
uniform sampler2D tex;
uniform float threshold;
-2
View File
@@ -14,8 +14,6 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#version 140
uniform sampler2D tex;
uniform float alpha_mod;
-2
View File
@@ -14,8 +14,6 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#version 140
uniform mat4 local_transform;
uniform mat4 view_transform;
uniform mat4 proj_transform;
-2
View File
@@ -14,8 +14,6 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#version 140
uniform samplerCube tex;
in vec3 tex_coord;
-2
View File
@@ -14,8 +14,6 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#version 140
uniform mat4 view_transform;
uniform mat4 proj_transform;
-3
View File
@@ -14,9 +14,6 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#version 140
uniform sampler2D tex; // the new scene
uniform sampler2D old; // the old scene
uniform float progress; // effect progress (0..1)
-2
View File
@@ -14,8 +14,6 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#version 140
uniform sampler2D tex; // the new scene
uniform sampler2D old; // the old scene
uniform vec2 resolution; // the screen resolution
-2
View File
@@ -14,8 +14,6 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#version 140
uniform vec4 color;
in vec2 tex_coord;
-2
View File
@@ -14,8 +14,6 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#version 140
uniform sampler2D tex;
uniform float threshold;
uniform vec4 color;
-2
View File
@@ -14,8 +14,6 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#version 140
uniform sampler2D tex;
uniform float threshold;
uniform vec4 color;
+2 -4
View File
@@ -14,8 +14,6 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#version 140
uniform sampler2D tex;
uniform vec2 bot_left;
uniform vec2 top_right;
@@ -29,11 +27,11 @@ float point_in_rect(vec2 p, vec2 bot_left, vec2 top_right) {
}
void main() {
ivec2 size = textureSize(tex, 0);
vec2 size = vec2(textureSize(tex, 0));
vec2 tex_bot_left = bot_left / size;
vec2 tex_top_right = top_right / size;
vec4 texel = texture(tex, tex_coord);
float t = point_in_rect(tex_coord, tex_bot_left, tex_top_right);
frag_color = t * texel + (1 - t) * vec4(0, 0, 0, 0);
frag_color = t * texel + (1.0 - t) * vec4(0, 0, 0, 0);
}
+3 -5
View File
@@ -14,8 +14,6 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#version 140
uniform sampler2D tex;
uniform vec2 bot_left;
uniform vec2 top_right;
@@ -29,12 +27,12 @@ float point_in_rect(vec2 p, vec2 bot_left, vec2 top_right) {
}
void main() {
ivec2 size = textureSize(tex, 0);
vec2 size = vec2(textureSize(tex, 0));
vec2 tex_bot_left = bot_left / size;
vec2 tex_top_right = top_right / size;
vec4 texel = texture(tex, tex_coord);
texel.a = 1;
texel.a = 1.0;
float t = point_in_rect(tex_coord, tex_bot_left, tex_top_right);
frag_color = t * texel + (1 - t) * vec4(0, 0, 0, 0);
frag_color = t * texel + (1.0 - t) * vec4(0, 0, 0, 0);
}
-2
View File
@@ -14,8 +14,6 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#version 140
uniform sampler2D tex;
uniform float alpha_mod;
-2
View File
@@ -14,8 +14,6 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#version 140
uniform mat4 world_transform;
uniform mat4 view_transform;
+15
View File
@@ -59,6 +59,7 @@ struct copy_data {
static struct copy_shader copy_shader;
static struct copy_shader copy_color_reverse_shader;
static struct copy_shader copy_key_shader;
static struct copy_shader copy_alpha_key_shader;
static struct copy_shader copy_use_amap_under_shader;
static struct copy_shader copy_use_amap_border_shader;
static struct copy_shader blend_amap_color_shader;
@@ -102,6 +103,9 @@ void gfx_draw_init(void)
// copy shader which also discards fragments matching a color key
load_copy_shader(&copy_key_shader, "shaders/render.v.glsl", "shaders/copy_key.f.glsl");
// copy shader which also discards fragments matching an alpha key
load_copy_shader(&copy_alpha_key_shader, "shaders/render.v.glsl", "shaders/copy_alpha_key.f.glsl");
// copy shader that only keeps fragments below a certain alpha threshold
load_copy_shader(&copy_use_amap_under_shader, "shaders/render.v.glsl", "shaders/copy_use_amap_under.f.glsl");
@@ -226,6 +230,17 @@ void gfx_copy_sprite(Texture *dst, int dx, int dy, Texture *src, int sx, int sy,
restore_blend_mode();
}
void gfx_sprite_copy_amap(Texture *dst, int dx, int dy, Texture *src, int sx, int sy, int w, int h, int alpha_key)
{
glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_ONE, GL_ZERO);
struct copy_data data = COPY_DATA(dx, dy, sx, sy, w, h);
data.a = alpha_key / 255.0;
run_copy_shader(&copy_alpha_key_shader.s, dst, src, &data);
restore_blend_mode();
}
void gfx_copy_color_reverse(struct texture *dst, int dx, int dy, struct texture *src, int sx, int sy, int w, int h)
{
glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ZERO, GL_ONE);
+23 -4
View File
@@ -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++) {
@@ -89,9 +89,13 @@ struct dgn *dgn_parse(uint8_t *data, size_t size)
}
buffer_skip(&r, 4);
cell->battle_background = buffer_read_int32(&r);
if (dgn->version != DGN_VER_GALZOO)
if (dgn->version != DGN_VER_GALZOO) {
cell->polyobj_index = -1;
cell->roof_orientation = -1;
cell->roof_texture = -1;
cell->roof_underside_texture = -1;
continue;
}
cell->polyobj_index = buffer_read_int32(&r);
cell->polyobj_scale = buffer_read_float(&r);
cell->polyobj_rotation_y = buffer_read_float(&r);
@@ -146,7 +150,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 +179,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;
+237 -38
View File
@@ -25,43 +25,44 @@
#include "system4/archive.h"
#include "system4/cg.h"
#include "system4/dlf.h"
#include "system4/file.h"
#include "dungeon/dgn.h"
#include "dungeon/dtx.h"
#include "dungeon/dungeon.h"
#include "dungeon/map.h"
#include "dungeon/polyobj.h"
#include "dungeon/renderer.h"
#include "dungeon/tes.h"
#include "gfx/gfx.h"
#include "sact.h"
#include "sprite.h"
#include "vm.h"
#include "vm/page.h"
#include "xsystem4.h"
#ifndef M_PI
#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)
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);
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;
}
@@ -78,11 +79,8 @@ void dungeon_context_free(struct dungeon_context *ctx)
dungeon_renderer_free(ctx->renderer);
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;
if (ctx->map)
dungeon_map_free(ctx->map);
free(ctx);
}
@@ -130,37 +128,78 @@ static GLuint *load_event_textures(int *nr_textures_out)
bool dungeon_load(struct dungeon_context *ctx, int num)
{
struct polyobj *polyobj = NULL;
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);
char *polyobj_path = gamedir_path("Data/PolyObj.lin");
polyobj = polyobj_load(polyobj_path);
free(polyobj_path);
if (!polyobj) {
WARNING("Cannot load Data/PolyObj.lin");
return false;
}
} 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;
@@ -171,7 +210,10 @@ 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, polyobj);
if (polyobj)
polyobj_free(polyobj);
dungeon_map_init(ctx);
@@ -226,6 +268,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,8 +282,158 @@ 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);
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 (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)
{
struct dungeon_context *ctx = dungeon_get_context(surface);
if (!ctx || !ctx->dgn)
return 0;
return dgn_calc_conquer(ctx->dgn);
}
/*
* WalkData serialization format:
*
* 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;
}
+24 -168
View File
@@ -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;
};
@@ -72,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;
@@ -85,7 +86,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);
}
@@ -93,10 +93,11 @@ 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;
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 +131,12 @@ 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);
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);
}
@@ -159,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);
@@ -243,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)
@@ -275,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)
@@ -302,21 +306,17 @@ 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);
}
}
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);
@@ -325,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);
@@ -334,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);
@@ -344,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;
}
@@ -352,151 +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;
}
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;
}
+133
View File
@@ -0,0 +1,133 @@
/* Copyright (C) 2021 kichikuou <KichikuouChrome@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include "system4.h"
#include "system4/buffer.h"
#include "system4/cg.h"
#include "system4/file.h"
#include "dungeon/polyobj.h"
struct polyobj *polyobj_load(const char *path)
{
size_t size;
uint8_t *data = file_read(path, &size);
if (!data)
return NULL;
struct buffer r;
buffer_init(&r, data, size);
if (memcmp(buffer_strdata(&r), "POL\0\0\0\0\0", 8))
return NULL;
buffer_skip(&r, 8);
struct polyobj *po = xcalloc(1, sizeof(struct polyobj));
po->data = data;
po->size = size;
po->nr_textures = buffer_read_int32(&r);
po->textures = xcalloc(po->nr_textures, sizeof(struct polyobj_location));
for (int i = 0; i < po->nr_textures; i++) {
po->textures[i].offset = buffer_read_int32(&r);
po->textures[i].length = buffer_read_int32(&r);
}
po->nr_objects = buffer_read_int32(&r);
po->objects = xcalloc(po->nr_objects, sizeof(struct polyobj_location));
for (int i = 0; i < po->nr_objects; i++) {
po->objects[i].offset = buffer_read_int32(&r);
po->objects[i].length = buffer_read_int32(&r);
}
return po;
}
void polyobj_free(struct polyobj *po)
{
free(po->textures);
free(po->objects);
free(po->data);
free(po);
}
struct cg *polyobj_get_texture(struct polyobj *po, int index)
{
if (index < 0 || index >= po->nr_textures)
return NULL;
struct polyobj_location *loc = &po->textures[index];
return cg_load_buffer(po->data + loc->offset, loc->length);
}
struct polyobj_object *polyobj_get_object(struct polyobj *po, int index)
{
if (index < 0 || index >= po->nr_objects)
return NULL;
struct polyobj_location *loc = &po->objects[index];
struct buffer r;
buffer_init(&r, po->data + loc->offset, loc->length);
struct polyobj_object *obj = xcalloc(1, sizeof(struct polyobj_object));
obj->name = strdup(buffer_strdata(&r));
buffer_skip(&r, strlen(obj->name) + 1);
if (memcmp(buffer_strdata(&r), "POO\0\0\0\0\0", 8)) {
polyobj_object_free(obj);
return NULL;
}
buffer_skip(&r, 8);
obj->nr_materials = buffer_read_int32(&r);
obj->materials = xcalloc(obj->nr_materials, sizeof(int));
for (int i = 0; i < obj->nr_materials; i++)
obj->materials[i] = buffer_read_int32(&r);
obj->nr_parts = buffer_read_int32(&r);
obj->parts = xcalloc(obj->nr_parts, sizeof(struct polyobj_part));
for (int i = 0; i < obj->nr_parts; i++) {
struct polyobj_part *part = &obj->parts[i];
part->nr_vertices = buffer_read_int32(&r);
part->vertices = xcalloc(part->nr_vertices, sizeof(vec3));
for (int j = 0; j < part->nr_vertices; j++) {
part->vertices[j][0] = buffer_read_float(&r);
part->vertices[j][1] = buffer_read_float(&r);
part->vertices[j][2] = buffer_read_float(&r);
}
part->nr_triangles = buffer_read_int32(&r);
part->triangles = xcalloc(part->nr_triangles, sizeof(struct polyobj_triangle));
for (int j = 0; j < part->nr_triangles; j++) {
struct polyobj_triangle *triangle = &part->triangles[j];
triangle->material = buffer_read_int32(&r);
triangle->index[0] = buffer_read_int32(&r);
triangle->index[1] = buffer_read_int32(&r);
triangle->index[2] = buffer_read_int32(&r);
triangle->uv[0][0] = buffer_read_float(&r);
triangle->uv[0][1] = buffer_read_float(&r);
triangle->uv[1][0] = buffer_read_float(&r);
triangle->uv[1][1] = buffer_read_float(&r);
triangle->uv[2][0] = buffer_read_float(&r);
triangle->uv[2][1] = buffer_read_float(&r);
}
}
return obj;
}
void polyobj_object_free(struct polyobj_object *obj)
{
for (int i = 0; i < obj->nr_parts; i++) {
struct polyobj_part *part = &obj->parts[i];
free(part->vertices);
free(part->triangles);
}
free(obj->parts);
free(obj->materials);
free(obj->name);
free(obj);
}
+260 -66
View File
@@ -20,10 +20,13 @@
#include <cglm/cglm.h>
#include <GL/glew.h>
#include "system4.h"
#include "system4/buffer.h"
#include "system4/cg.h"
#include "dungeon/dungeon.h"
#include "dungeon/dgn.h"
#include "dungeon/dtx.h"
#include "dungeon/polyobj.h"
#include "dungeon/renderer.h"
#include "dungeon/skybox.h"
#include "gfx/gfx.h"
@@ -35,34 +38,44 @@ 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, 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},
};
static const struct marker_info *marker_tables[] = {
[DRAW_DUNGEON_1] = rance6_marker_info,
[DRAW_DUNGEON_14] = galzoo_marker_info
};
struct geometry;
struct material;
struct object3d;
struct dungeon_renderer {
struct shader shader;
@@ -76,7 +89,9 @@ struct dungeon_renderer {
struct geometry *wall_geometry;
struct geometry *door_left_geometry;
struct geometry *door_right_geometry;
struct geometry *roof_geometry;
struct geometry *stairs_geometry;
struct geometry *floating_marker_geometry;
struct material *materials;
int nr_materials;
@@ -84,10 +99,26 @@ struct dungeon_renderer {
GLuint *event_textures;
int nr_event_textures;
const struct marker_info *marker_table;
bool draw_event_markers;
int nr_polyobjs;
struct object3d *polyobjs;
int nr_polyobj_materials;
struct material *polyobj_materials;
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;
};
@@ -113,6 +144,13 @@ static const struct vertex door_right_vertices[] = {
{ 0.0, -1.0, 0.0, 1.0, 1.0},
};
static const struct vertex roof_vertices[] = {
{-1.0, 1.0, -1.0, 0.0, 0.0},
{-1.0, -1.0, 1.0, 0.0, 1.0},
{ 1.0, 1.0, -1.0, 1.0, 0.0},
{ 1.0, -1.0, 1.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},
@@ -142,16 +180,31 @@ 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;
int nr_vertices;
GLenum mode;
};
static struct geometry *geometry_create(struct dungeon_renderer *r, const struct vertex *vertices, size_t size)
static struct geometry *geometry_create(struct dungeon_renderer *r, const struct vertex *vertices, size_t size, GLenum mode)
{
struct geometry *g = xcalloc(1, sizeof(struct geometry));
g->nr_vertices = size / sizeof(struct vertex);
g->mode = mode;
glGenVertexArrays(1, &g->vao);
glBindVertexArray(g->vao);
@@ -181,11 +234,8 @@ struct material {
bool opaque;
};
static void init_material(struct material *m, struct dtx *dtx, int type, int index)
static void init_material(struct material *m, struct cg *cg)
{
struct cg *cg = dtx_create_cg(dtx, type, index);
if (!cg)
return;
glGenTextures(1, &m->texture);
glBindTexture(GL_TEXTURE_2D, m->texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cg->metrics.w, cg->metrics.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, cg->pixels);
@@ -196,7 +246,6 @@ static void init_material(struct material *m, struct dtx *dtx, int type, int ind
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
m->opaque = !cg->metrics.has_alpha;
cg_free(cg);
}
static void delete_material(struct material *m)
@@ -213,7 +262,77 @@ 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 mesh {
struct geometry *geometry;
int material;
};
struct object3d {
int nr_meshes;
struct mesh *meshes;
};
static void init_object3d(struct object3d *o3d, struct dungeon_renderer *r, const struct polyobj_object *obj)
{
o3d->nr_meshes = obj->nr_materials;
o3d->meshes = xcalloc(obj->nr_materials, sizeof(struct mesh));
for (int i = 0; i < obj->nr_materials; i++)
o3d->meshes[i].material = obj->materials[i];
struct buffer *bufs = xcalloc(obj->nr_materials, sizeof(struct buffer));
for (int i = 0; i < obj->nr_parts; i++) {
const struct polyobj_part *part = &obj->parts[i];
for (int j = 0; j < part->nr_triangles; j++) {
const struct polyobj_triangle *triangle = &part->triangles[j];
for (int k = 0; k < 3; k++) {
const int ltor[] = {0, 2, 1}; // left->right handed system
const vec3 *pos = &part->vertices[triangle->index[ltor[k]]];
const vec2 *uv = &triangle->uv[ltor[k]];
buffer_write_float(&bufs[triangle->material], (*pos)[0]); // x
buffer_write_float(&bufs[triangle->material], (*pos)[1]); // y
buffer_write_float(&bufs[triangle->material], -(*pos)[2]); // z
buffer_write_float(&bufs[triangle->material], (*uv)[0]); // u
buffer_write_float(&bufs[triangle->material], (*uv)[1]); // v
}
}
}
for (int i = 0; i < obj->nr_materials; i++) {
o3d->meshes[i].geometry = geometry_create(r, (const struct vertex *)bufs[i].buf, bufs[i].index, GL_TRIANGLES);
free(bufs[i].buf);
}
free(bufs);
}
static void delete_object3d(struct object3d *o3d)
{
for (int i = 0; i < o3d->nr_meshes; i++)
geometry_free(o3d->meshes[i].geometry);
free(o3d->meshes);
}
static void init_polyobjs(struct dungeon_renderer *r, struct polyobj *po)
{
r->nr_polyobj_materials = po->nr_textures;
r->polyobj_materials = xcalloc(po->nr_textures, sizeof(struct material));
for (int i = 0; i < po->nr_textures; i++) {
struct cg *cg = polyobj_get_texture(po, i);
init_material(&r->polyobj_materials[i], cg);
cg_free(cg);
}
r->nr_polyobjs = po->nr_objects;
r->polyobjs = xcalloc(po->nr_objects, sizeof(struct object3d));
for (int i = 0; i < po->nr_objects; i++) {
struct polyobj_object *obj = polyobj_get_object(po, i);
if (!obj)
continue;
init_object3d(&r->polyobjs[i], r, obj);
polyobj_object_free(obj);
}
}
struct dungeon_renderer *dungeon_renderer_create(enum draw_dungeon_version version, struct dtx *dtx, GLuint *event_textures, int nr_event_textures, struct polyobj *po)
{
struct dungeon_renderer *r = xcalloc(1, sizeof(struct dungeon_renderer));
@@ -223,16 +342,22 @@ struct dungeon_renderer *dungeon_renderer_create(struct dtx *dtx, GLuint *event_
r->alpha_mod = glGetUniformLocation(r->shader.program, "alpha_mod");
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));
r->wall_geometry = geometry_create(r, wall_vertices, sizeof(wall_vertices), GL_TRIANGLE_STRIP);
r->door_left_geometry = geometry_create(r, door_left_vertices, sizeof(door_left_vertices), GL_TRIANGLE_STRIP);
r->door_right_geometry = geometry_create(r, door_right_vertices, sizeof(door_right_vertices), GL_TRIANGLE_STRIP);
r->roof_geometry = geometry_create(r, roof_vertices, sizeof(roof_vertices), GL_TRIANGLE_STRIP);
r->stairs_geometry = geometry_create(r, stairs_vertices, sizeof(stairs_vertices), GL_TRIANGLE_STRIP);
r->floating_marker_geometry = geometry_create(r, floating_marker_vertices, sizeof(floating_marker_vertices), GL_TRIANGLE_STRIP);
const int nr_types = DTX_DOOR + 1;
r->materials = xcalloc(nr_types * dtx->nr_columns, sizeof(struct material));
for (int type = 0; type < nr_types; type++) {
for (int i = 0; i < dtx->nr_columns; i++) {
init_material(&r->materials[type * dtx->nr_columns + i], dtx, type, i);
struct cg *cg = dtx_create_cg(dtx, type, i);
if (!cg)
continue;
init_material(&r->materials[type * dtx->nr_columns + i], cg);
cg_free(cg);
}
}
r->nr_dtx_columns = dtx->nr_columns;
@@ -240,6 +365,11 @@ 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->draw_event_markers = true;
if (po)
init_polyobjs(r, po);
r->skybox = skybox_create(dtx);
@@ -253,7 +383,9 @@ void dungeon_renderer_free(struct dungeon_renderer *r)
geometry_free(r->wall_geometry);
geometry_free(r->door_left_geometry);
geometry_free(r->door_right_geometry);
geometry_free(r->roof_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]);
@@ -262,6 +394,13 @@ void dungeon_renderer_free(struct dungeon_renderer *r)
glDeleteTextures(r->nr_event_textures, r->event_textures);
free(r->event_textures);
for (int i = 0; i < r->nr_polyobjs; i++)
delete_object3d(&r->polyobjs[i]);
free(r->polyobjs);
for (int i = 0; i < r->nr_polyobj_materials; i++)
delete_material(&r->polyobj_materials[i]);
free(r->polyobj_materials);
skybox_free(r->skybox);
free(r);
@@ -277,7 +416,7 @@ static void draw(struct dungeon_renderer *r, struct geometry *geometry, GLuint t
glUniform1i(r->shader.texture, 0);
glBindVertexArray(geometry->vao);
glDrawArrays(GL_TRIANGLE_STRIP, 0, geometry->nr_vertices);
glDrawArrays(geometry->mode, 0, geometry->nr_vertices);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
}
@@ -323,20 +462,59 @@ 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);
}
static void draw_object3d(struct dungeon_renderer *r, struct object3d *o3d, bool render_opaque, vec3 pos, float scale, float rotation_y)
{
mat4 m;
glm_translate_make(m, pos);
glm_rotate_y(m, glm_rad(rotation_y), m);
glm_scale_uni(m, scale);
for (int i = 0; i < o3d->nr_meshes; i++) {
struct mesh *mesh = &o3d->meshes[i];
struct material *material = &r->polyobj_materials[mesh->material];
if (material->opaque != render_opaque)
continue;
draw(r, mesh->geometry, material->texture, m);
}
}
static void stairs_matrix(mat4 dst, float x, float y, float z, int orientation)
{
vec3 pos = {x, y, z};
glm_translate_make(dst, pos);
const float cos[4] = {1, 0, -1, 0};
const float sin[4] = {0, 1, 0, -1};
dst[0][0] = cos[orientation % 4];
dst[0][2] = -sin[orientation % 4];
dst[2][0] = sin[orientation % 4];
dst[2][2] = cos[orientation % 4];
}
static void draw_cell(struct dungeon_renderer *r, struct dgn_cell *cell, bool render_opaque, mat4 view_transform)
{
float x = 2.0 * cell->x;
@@ -456,33 +634,39 @@ static void draw_cell(struct dungeon_renderer *r, struct dgn_cell *cell, bool re
if (cell->stairs_texture >= 0) {
struct material *material = get_material(r, DTX_STAIRS, cell->stairs_texture);
if (material && material->opaque == render_opaque) {
mat4 matrices[4] = {
MAT4(
1, 0, 0, x,
0, 1, 0, y,
0, 0, 1, z,
0, 0, 0, 1),
MAT4(
0, 0, 1, x,
0, 1, 0, y,
-1, 0, 0, z,
0, 0, 0, 1),
MAT4(
-1, 0, 0, x,
0, 1, 0, y,
0, 0, -1, z,
0, 0, 0, 1),
MAT4(
0, 0, -1, x,
0, 1, 0, y,
1, 0, 0, z,
0, 0, 0, 1)
};
draw(r, r->stairs_geometry, material->texture, matrices[cell->stairs_orientation]);
mat4 m;
stairs_matrix(m, x, y, z, cell->stairs_orientation);
draw(r, r->stairs_geometry, material->texture, m);
}
}
if (cell->floor_event && !render_opaque) {
const struct marker_info *info = get_marker_info(cell->floor_event);
if (cell->roof_texture >= 0) {
struct material *material = get_material(r, DTX_STAIRS, cell->roof_texture);
if (material && material->opaque == render_opaque) {
mat4 m;
stairs_matrix(m, x, y, z, cell->roof_orientation);
draw(r, r->roof_geometry, material->texture, m);
}
}
if (cell->roof_underside_texture >= 0) {
struct material *material = get_material(r, DTX_STAIRS, cell->roof_underside_texture);
if (material && material->opaque == render_opaque) {
mat4 m;
stairs_matrix(m, x, y, z, cell->roof_orientation);
glCullFace(GL_FRONT);
draw(r, r->roof_geometry, material->texture, m);
glCullFace(GL_BACK);
}
}
if (cell->polyobj_index >= 0) {
vec3 pos = {
x + cell->polyobj_position_x,
y + cell->polyobj_position_y - 1,
z - cell->polyobj_position_z
};
draw_object3d(r, &r->polyobjs[cell->polyobj_index], render_opaque, pos, cell->polyobj_scale, cell->polyobj_rotation_y);
}
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();
draw_floor_marker(r, info, x, y, z, t);
@@ -515,3 +699,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;
}
+4
View File
@@ -291,9 +291,11 @@ 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;
extern struct static_library lib_DrawSimpleText;
extern struct static_library lib_File;
extern struct static_library lib_FileOperation;
extern struct static_library lib_GoatGUIEngine;
@@ -338,9 +340,11 @@ static struct static_library *static_libraries[] = {
&lib_CrayfishLogViewer,
&lib_DataFile,
&lib_DrawDungeon,
&lib_DrawDungeon14,
&lib_DrawGraph,
&lib_DrawMovie2,
&lib_DrawPluginManager,
&lib_DrawSimpleText,
&lib_File,
&lib_FileOperation,
&lib_GoatGUIEngine,
+1 -1
View File
@@ -111,7 +111,7 @@ static void render_text(struct fnl_font_face *font, struct text_style *ts, Textu
}
// create texture from surface
gfx_init_texture_with_pixels(dst, width, height, surf, GL_RGBA);
gfx_init_texture_with_pixels(dst, width, height, surf);
free(surf);
free(glyphs);
}
+178 -125
View File
@@ -23,11 +23,22 @@
#include "dungeon/dgn.h"
#include "dungeon/dungeon.h"
#include "dungeon/map.h"
#include "dungeon/renderer.h"
#include "dungeon/tes.h"
#include "hll.h"
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 +60,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 +280,157 @@ 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_map_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(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_map_load_walk_data),
HLL_EXPORT(SaveWalkData, dungeon_map_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);
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),
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)
);
+7 -2
View File
@@ -232,7 +232,12 @@ static void DrawGraph_FillAMapUnderBorder(int dst, int x, int y, int w, int h, i
//void DrawGraph_FillMultiply(int dst, int x, int y, int w, int h, int r, int g, int b);
//void DrawGraph_SaturDP_DPxSA(int dst, int dx, int dy, int src, int sx, int sy, int w, int h);
//void DrawGraph_ScreenDA_DAxSA(int dst, int dx, int dy, int src, int sx, int sy, int w, int h);
//void DrawGraph_SpriteCopyAMap(int dst, int dx, int dy, int src, int sx, int sy, int w, int h, int key);
static void DrawGraph_SpriteCopyAMap(int dst, int dx, int dy, int src, int sx, int sy, int w, int h, int key)
{
gfx_sprite_copy_amap(DTEX(dst), dx, dy, STEX(src), sx, sy, w, h, key);
}
//void DrawGraph_BrightDestOnly(int dst, int x, int y, int w, int h, int rate);
//void DrawGraph_CopyTextureWrap(int dst, int dx, int dy, int dw, int dh, int src, int sx, int sy, int sw, int sh, int u, int v);
//void DrawGraph_CopyTextureWrapAlpha(int dst, int dx, int dy, int dw, int dh, int src, int sx, int sy, int sw, int sh, int u, int v, int alpha);
@@ -351,7 +356,7 @@ HLL_LIBRARY(DrawGraph,
//HLL_EXPORT(SaturDP_DPxSA, DrawGraph_SaturDP_DPxSA),
//HLL_EXPORT(ScreenDA_DAxSA, DrawGraph_ScreenDA_DAxSA),
HLL_EXPORT(AddDA_DAxSA, DrawGraph_AddDA_DAxSA),
//HLL_EXPORT(SpriteCopyAMap, DrawGraph_SpriteCopyAMap),
HLL_EXPORT(SpriteCopyAMap, DrawGraph_SpriteCopyAMap),
HLL_EXPORT(BlendDA_DAxSA, DrawGraph_BlendDA_DAxSA),
HLL_EXPORT(SubDA_DAxSA, DrawGraph_SubDA_DAxSA),
//HLL_EXPORT(BrightDestOnly, DrawGraph_BrightDestOnly),
+87
View File
@@ -0,0 +1,87 @@
/* Copyright (C) 2021 kichikuou <KichikuouChrome@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#include "system4/string.h"
#include "hll.h"
#include "gfx/gfx.h"
#include "sact.h"
static int size = 20;
static int weight = 1; // in pixels
static int pitch = 0;
static bool DrawSimpleText_DrawToAlphaMap(int sp_no, int x, int y, struct string *s)
{
struct sact_sprite *sp = sact_get_sprite(sp_no);
if (!sp)
return NULL;
sprite_dirty(sp);
int orig_weight = gfx_get_font_weight();
int orig_size = gfx_get_font_size();
int orig_space = gfx_get_font_space();
gfx_set_font_weight(weight <= 1 ? FW_NORMAL : FW_BOLD);
gfx_set_font_size(size);
gfx_set_font_space(pitch);
gfx_draw_text_to_amap(sprite_get_texture(sp), x, y, s->text);
gfx_set_font_weight(orig_weight);
gfx_set_font_size(orig_size);
gfx_set_font_space(orig_space);
return true;
}
static void DrawSimpleText_SetSize(int n)
{
size = n;
}
static int DrawSimpleText_GetSize(void)
{
return size;
}
static void DrawSimpleText_SetWeight(int n)
{
weight = n;
}
static int DrawSimpleText_GetWeight(void)
{
return weight;
}
static void DrawSimpleText_SetPitch(int n)
{
pitch = n;
}
static int DrawSimpleText_GetPitch(void)
{
return pitch;
}
HLL_LIBRARY(DrawSimpleText,
HLL_EXPORT(DrawToAlphaMap, DrawSimpleText_DrawToAlphaMap),
HLL_EXPORT(SetSize, DrawSimpleText_SetSize),
HLL_EXPORT(GetSize, DrawSimpleText_GetSize),
HLL_EXPORT(SetWeight, DrawSimpleText_SetWeight),
HLL_EXPORT(GetWeight, DrawSimpleText_GetWeight),
HLL_EXPORT(SetPitch, DrawSimpleText_SetPitch),
HLL_EXPORT(GetPitch, DrawSimpleText_GetPitch)
);
+25 -2
View File
@@ -17,12 +17,14 @@
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <cglm/cglm.h>
#ifndef M_PI
#define M_PI (3.14159265358979323846)
#endif
#include "hll.h"
#include "vm/page.h"
struct shuffle_table {
int id;
@@ -150,11 +152,31 @@ static int Math_RandTable(int num)
//void Math_RandTable2Init(int num, struct page *array);
//int Math_RandTable2(int num);
int Math_Ceil(float f)
static int Math_Ceil(float f)
{
return (int)ceilf(f);
}
static bool Math_BezierCurve(struct page **x_array, struct page **y_array, int num, float t, int *result_x, int *result_y)
{
vec2 *coeffs = xmalloc(num * sizeof(vec2));
for (int i = 0; i < num; i++) {
coeffs[i][0] = (*x_array)->values[i].i;
coeffs[i][1] = (*y_array)->values[i].i;
}
// De Casteljau's algorithm.
for (; num > 1; num--) {
for (int i = 0; i < num - 1; i++)
glm_vec2_lerp(coeffs[i], coeffs[i + 1], t, coeffs[i]);
}
*result_x = coeffs[0][0];
*result_y = coeffs[0][1];
free(coeffs);
return true;
}
HLL_LIBRARY(Math,
HLL_EXPORT(Cos, Math_Cos),
HLL_EXPORT(Sin, Math_Sin),
@@ -181,5 +203,6 @@ HLL_LIBRARY(Math,
HLL_EXPORT(SwapF, Math_SwapF),
HLL_EXPORT(Log, logf),
HLL_EXPORT(Log10, log10f),
HLL_EXPORT(Ceil, Math_Ceil));
HLL_EXPORT(Ceil, Math_Ceil),
HLL_EXPORT(BezierCurve, Math_BezierCurve));
+10
View File
@@ -183,6 +183,16 @@ int sact_SP_Enum(struct page **array)
return count;
}
int sact_SP_GetMaxZ(void)
{
int max_z = 0;
for (int i = 0; i < nr_sprites; i++) {
if (sprites[i] && max_z < sprites[i]->sp.z)
max_z = sprites[i]->sp.z;
}
return max_z;
}
int sact_SP_SetCG(int sp_no, int cg_no)
{
struct sact_sprite *sp = sact_get_sprite(sp_no);
+2
View File
@@ -23,6 +23,7 @@ xsystem4 = ['audio.c',
'dungeon/dtx.c',
'dungeon/dungeon.c',
'dungeon/map.c',
'dungeon/polyobj.c',
'dungeon/renderer.c',
'dungeon/skybox.c',
'dungeon/tes.c',
@@ -47,6 +48,7 @@ xsystem4 = ['audio.c',
'hll/DrawGraph.c',
'hll/DrawMovie2.c',
'hll/DrawPluginManager.c',
'hll/DrawSimpleText.c',
'hll/File.c',
'hll/FileOperation.c',
'hll/GoatGUIEngine.c',
-7
View File
@@ -112,13 +112,6 @@ int scene_set_wp_color(int r, int g, int b)
return 1;
}
int scene_get_max_z(void)
{
if (TAILQ_EMPTY(&sprite_list))
return 0;
return TAILQ_LAST(&sprite_list, listhead)->z;
}
void scene_set_sprite_z(struct sprite *sp, int z)
{
sp->z = z;
+5 -3
View File
@@ -252,10 +252,12 @@ static void get_glyph(TTF_Font *f, Texture *dst, char *msg, SDL_Color color)
WARNING("Text rendering failed: %s", msg);
return;
}
if (s->format->format != SDL_PIXELFORMAT_BGRA32) {
WARNING("Wrong pixel format from SDL_ttf");
if (s->format->format != SDL_PIXELFORMAT_RGBA32) {
SDL_Surface *tmp = SDL_ConvertSurfaceFormat(s, SDL_PIXELFORMAT_RGBA32, 0);
SDL_FreeSurface(s);
s = tmp;
}
gfx_init_texture_with_pixels(dst, s->w, s->h, s->pixels, GL_BGRA);
gfx_init_texture_with_pixels(dst, s->w, s->h, s->pixels);
SDL_FreeSurface(s);
}
+31 -21
View File
@@ -32,6 +32,19 @@
struct sdl_private sdl;
/*
* Define this to target OpenGL ES 3.0.
*/
//#define USE_GLES
static const GLchar glsl_preamble[] =
#ifdef USE_GLES
"#version 300 es\n"
"precision highp float;\n";
#else
"#version 140\n";
#endif
/*
* Transform from the window coordinate system -> clip-space.
*
@@ -84,16 +97,17 @@ static GLuint load_shader_file(const char *path, GLenum type)
{
GLint shader_compiled;
GLuint shader;
const GLchar *source;
source = read_shader_file(path);
const GLchar *source[2] = {
glsl_preamble,
read_shader_file(path)
};
shader = glCreateShader(type);
glShaderSource(shader, 1, &source, NULL);
glShaderSource(shader, 2, source, NULL);
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_compiled);
if (!shader_compiled)
ERROR("Failed to compile shader: %s", path);
free((char*)source);
free((char*)source[1]);
return shader;
}
@@ -164,9 +178,15 @@ int gfx_init(void)
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
ERROR("SDL_Init failed: %s", SDL_GetError());
#ifdef USE_GLES
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
#else
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
#endif
sdl.format = SDL_AllocFormat(SDL_PIXELFORMAT_RGBA32);
sdl.window = SDL_CreateWindow("XSystem4",
@@ -234,7 +254,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 +390,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 +400,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,21 +423,20 @@ 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;
}
void gfx_init_texture_with_pixels(struct texture *t, int w, int h, void *pixels, GLenum format)
void gfx_init_texture_with_pixels(struct texture *t, int w, int h, void *pixels)
{
init_texture(t, w, h);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, format, GL_UNSIGNED_BYTE, pixels);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
}
void gfx_init_texture_with_cg(struct texture *t, struct cg *cg)
{
gfx_init_texture_with_pixels(t, cg->metrics.w, cg->metrics.h, cg->pixels, GL_RGBA);
gfx_init_texture_with_pixels(t, cg->metrics.w, cg->metrics.h, cg->pixels);
t->has_alpha = cg->metrics.has_alpha;
}
@@ -439,7 +449,7 @@ void gfx_init_texture_rgba(struct texture *t, int w, int h, SDL_Color color)
pixels[i] = c;
}
gfx_init_texture_with_pixels(t, w, h, pixels, GL_RGBA);
gfx_init_texture_with_pixels(t, w, h, pixels);
free(pixels);
}
@@ -459,13 +469,13 @@ void gfx_init_texture_rgb(struct texture *t, int w, int h, SDL_Color color)
void gfx_init_texture_blank(struct texture *t, int w, int h)
{
gfx_init_texture_with_pixels(t, w, h, NULL, GL_RGBA);
gfx_init_texture_with_pixels(t, w, h, NULL);
}
void gfx_copy_main_surface(struct texture *dst)
{
init_texture(dst, main_surface.w, main_surface.h);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, main_surface.w, main_surface.h, 0);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, main_surface.w, main_surface.h, 0);
}
void gfx_delete_texture(struct texture *t)