Merge pull request #75 from kichikuou/tt3

Fixes / improvements for Toushin Toshi 3
This commit is contained in:
Nunuhara Cabbage
2022-10-12 20:05:20 -07:00
committed by GitHub
4 changed files with 36 additions and 4 deletions
+1
View File
@@ -42,6 +42,7 @@ struct model {
int nr_bones;
struct bone *bones;
struct hash_table *bone_map; // bone id in POL/MOT -> struct bone *
struct hash_table *bone_name_map; // bone name -> (struct bone * | NULL)
vec3 aabb[2]; // axis-aligned bounding box
};
+17 -2
View File
@@ -355,6 +355,14 @@ static struct bone *add_bone(struct model *model, struct pol *pol, struct pol_bo
glm_quat_mat4(pol_bone->rotq, bone->inverse_bind_matrix);
glm_translate(bone->inverse_bind_matrix, pol_bone->pos);
// Update bone_name_map. If the bone name is not unique in the POL, set the
// map value to NULL so that ID matching will be used.
struct ht_slot *slot = ht_put(model->bone_name_map, pol_bone->name, bone);
if (slot->value != bone) {
NOTICE("%s: non-unique bone %s", model->path, pol_bone->name);
slot->value = NULL;
}
model->nr_bones++;
return bone;
}
@@ -401,6 +409,7 @@ struct model *model_load(struct archive *aar, const char *path)
if (pol->nr_bones > MAX_BONES)
ERROR("%s: Too many bones (%u)", model->path, pol->nr_bones);
model->bone_map = ht_create(pol->nr_bones * 3 / 2);
model->bone_name_map = ht_create(pol->nr_bones * 3 / 2);
model->bones = xcalloc(pol->nr_bones, sizeof(struct bone));
for (uint32_t i = 0; i < pol->nr_bones; i++) {
add_bone(model, pol, &pol->bones[i]);
@@ -470,6 +479,8 @@ void model_free(struct model *model)
free(model->bones);
if (model->bone_map)
ht_free_int(model->bone_map);
if (model->bone_name_map)
ht_free(model->bone_name_map);
free(model->path);
free(model);
@@ -505,9 +516,13 @@ struct motion *motion_load(const char *name, struct RE_instance *instance, struc
// Reorder mot->motions so that motion for model->bones[i] can be
// accessed by mot->motions[i].
for (uint32_t i = 0; i < mot->nr_bones; i++) {
struct bone *bone = ht_get_int(model->bone_map, mot->motions[i]->id, NULL);
// Match by name first, since some MOT have wrong bone IDs (e.g. maidsan_ahoge_*).
struct bone *bone = ht_get(model->bone_name_map, mot->motions[i]->name, NULL);
// If it is not found or is NULL (non-unique bone name), match by bone ID.
if (!bone)
ERROR("%s: invalid bone id %d", name, mot->motions[i]->id);
bone = ht_get_int(model->bone_map, mot->motions[i]->id, NULL);
if (!bone)
ERROR("%s: invalid bone \"%s\" (%d)", name, mot->motions[i]->name, mot->motions[i]->id);
mot->motions[i]->id = bone->index;
}
qsort(mot->motions, mot->nr_bones, sizeof(struct mot_bone *), cmp_motions_by_bone_id);
+16
View File
@@ -217,6 +217,21 @@ static void effect_oscillate(float rate)
gfx_copy(dst, delta_x, delta_y, &effect.new, 0, 0, dst->w, dst->h);
}
static void effect_tv_switch_off(float rate)
{
Texture *dst = gfx_main_surface();
if (rate < 0.5f) {
int h = max(1, (int)(dst->h * (1.0f - rate * 2.0f)));
gfx_copy_stretch(dst, 0, dst->h * rate, dst->w, h,
&effect.old, 0, 0, effect.old.w, effect.old.h);
} else {
rate -= 0.5f;
int w = dst->w * (1.0f - rate * 2.0f);
gfx_copy_stretch(dst, dst->w * rate, dst->h / 2, w, 1,
&effect.old, 0, 0, effect.old.w, effect.old.h);
}
}
static void effect_zoom_in_crossfade(float rate)
{
Texture *dst = gfx_main_surface();
@@ -238,6 +253,7 @@ static effect_fun effect_functions[NR_EFFECTS] = {
[EFFECT_WHITEOUT] = effect_whiteout,
[EFFECT_WHITEIN] = effect_whitein,
[EFFECT_OSCILLATE] = effect_oscillate,
[EFFECT_TV_SWITCH_OFF] = effect_tv_switch_off,
[EFFECT_ZOOM_LR] = effect_zoom_lr,
[EFFECT_ZOOM_RL] = effect_zoom_rl,
[EFFECT_ZOOM_IN_CROSSFADE] = effect_zoom_in_crossfade,
+2 -2
View File
@@ -80,14 +80,14 @@ static int MsgSkip_Init(struct string *name)
static void MsgSkip_SetFlag(int msgnum)
{
if (msgnum >= nr_flags)
if (msgnum < 0 || msgnum >= nr_flags)
return;
flags[msgnum] = 1;
}
static int MsgSkip_GetFlag(int msgnum)
{
if (msgnum >= nr_flags)
if (msgnum < 0 || msgnum >= nr_flags)
return 0;
return !!flags[msgnum];
}