parts: Implement PE_AddWholeMotionVibrationSize

It vibrates the whole screen. To implement this, this introduces a
global motion list and parts_set_global_pos(), which sets the position
of the root of the parts tree.
This commit is contained in:
kichikuou
2025-06-10 09:35:11 +09:00
parent 13a00c131d
commit 9ccc4ab0c7
3 changed files with 60 additions and 10 deletions
+44 -8
View File
@@ -33,6 +33,9 @@ static inline float deg2rad(float deg)
static TAILQ_HEAD(sound_motion_list, sound_motion) sound_motion_list =
TAILQ_HEAD_INITIALIZER(sound_motion_list);
static struct parts_motion_list global_motion_list =
TAILQ_HEAD_INITIALIZER(global_motion_list);
// true after call to BeginMotion until the motion ends or EndMotion is called
static bool is_motion = false;
// the elapsed time of the current motion
@@ -54,31 +57,41 @@ static void parts_motion_free(struct parts_motion *motion)
free(motion);
}
void parts_clear_motion(struct parts *parts)
static void parts_motion_list_clear(struct parts_motion_list *motion_list)
{
while (!TAILQ_EMPTY(&parts->motion)) {
struct parts_motion *motion = TAILQ_FIRST(&parts->motion);
TAILQ_REMOVE(&parts->motion, motion, entry);
while (!TAILQ_EMPTY(motion_list)) {
struct parts_motion *motion = TAILQ_FIRST(motion_list);
TAILQ_REMOVE(motion_list, motion, entry);
parts_motion_free(motion);
}
}
void parts_add_motion(struct parts *parts, struct parts_motion *motion)
static void parts_motion_list_add(struct parts_motion_list *motion_list, struct parts_motion *motion)
{
struct parts_motion *p;
TAILQ_FOREACH(p, &parts->motion, entry) {
TAILQ_FOREACH(p, motion_list, entry) {
if (p->begin_time > motion->begin_time) {
TAILQ_INSERT_BEFORE(p, motion, entry);
return;
}
}
TAILQ_INSERT_TAIL(&parts->motion, motion, entry);
TAILQ_INSERT_TAIL(motion_list, motion, entry);
if (motion->end_time > motion_end_t)
motion_end_t = motion->end_time;
// FIXME? What happens if we add a motion while is_motion=true?
// Should we call parts_update_motion here?
}
void parts_clear_motion(struct parts *parts)
{
parts_motion_list_clear(&parts->motion);
}
void parts_add_motion(struct parts *parts, struct parts_motion *motion)
{
parts_motion_list_add(&parts->motion, motion);
}
static inline float motion_progress(struct parts_motion *m, int t)
{
return (float)(t - m->begin_time) / (m->end_time - m->begin_time);
@@ -184,6 +197,20 @@ static void parts_update_with_motion(struct parts *parts, struct parts_motion *m
}
}
static void parts_update_global_motion(void)
{
struct parts_motion *motion;
TAILQ_FOREACH(motion, &global_motion_list, entry) {
switch (motion->type) {
case PARTS_MOTION_VIBRATION_SIZE:
parts_set_global_pos(motion_vibration_point(motion, motion_t));
break;
default:
WARNING("Invalid global motion type: %d", motion->type);
}
}
}
static void parts_update_all_motion(void)
{
struct parts *parts;
@@ -198,6 +225,7 @@ static void parts_update_all_motion(void)
parts_update_with_motion(parts, motion);
}
}
parts_update_global_motion();
struct sound_motion *sound;
TAILQ_FOREACH(sound, &sound_motion_list, entry) {
@@ -227,6 +255,7 @@ static void parts_init_all_motion(void)
}
}
}
parts_update_global_motion();
}
static void parts_fini_all_motion(void)
@@ -236,6 +265,8 @@ static void parts_fini_all_motion(void)
parts_clear_motion(parts);
}
parts_motion_list_clear(&global_motion_list);
while (!TAILQ_EMPTY(&sound_motion_list)) {
struct sound_motion *motion = TAILQ_FIRST(&sound_motion_list);
TAILQ_REMOVE(&sound_motion_list, motion, entry);
@@ -433,7 +464,12 @@ void PE_AddMotionVibrationSize(int parts_no, int begin_w, int begin_h, int begin
void PE_AddWholeMotionVibrationSize(int begin_w, int begin_h, int begin_t, int end_t)
{
UNIMPLEMENTED("(%d, %d, %d, %d)", begin_w, begin_h, begin_t, end_t);
struct parts_motion *motion = parts_motion_alloc(PARTS_MOTION_VIBRATION_SIZE, begin_t, end_t);
motion->begin.x = begin_w;
motion->begin.y = begin_h;
motion->end.x = 0;
motion->end.y = 0;
parts_motion_list_add(&global_motion_list, motion);
}
void PE_AddMotionSound(int sound_no, int begin_t)
+12 -1
View File
@@ -32,6 +32,7 @@
struct parts_list parts_list = TAILQ_HEAD_INITIALIZER(parts_list);
static struct parts_list dirty_list = TAILQ_HEAD_INITIALIZER(dirty_list);
static struct hash_table *parts_table = NULL;
static Point root_pos = { 0, 0 };
#define PARTS_PARAMS_INITIALIZER (struct parts_params) { \
.z = 1, \
@@ -357,10 +358,20 @@ void parts_set_pos(struct parts *parts, Point pos)
parts->local.pos.x = pos.x;
parts->local.pos.y = pos.y;
parts_recalculate_hitbox(parts);
parts_update_global_pos(parts, parts->parent ? parts->parent->global.pos : (Point){0,0});
parts_update_global_pos(parts, parts->parent ? parts->parent->global.pos : root_pos);
parts_dirty(parts);
}
void parts_set_global_pos(Point pos)
{
root_pos = pos;
struct parts *parts;
PARTS_LIST_FOREACH(parts) {
parts_update_global_pos(parts, root_pos);
}
parts_engine_dirty();
}
static void parts_update_global_z(struct parts *parts, int parent_z)
{
parts->global.z = parent_z + parts->local.z;
+4 -1
View File
@@ -70,6 +70,8 @@ struct parts_motion {
int end_time;
};
TAILQ_HEAD(parts_motion_list, parts_motion);
struct sound_motion {
TAILQ_ENTRY(sound_motion) entry;
int begin_time;
@@ -323,7 +325,7 @@ struct parts {
int linked_from;
int draw_filter;
bool message_window;
TAILQ_HEAD(, parts_motion) motion;
struct parts_motion_list motion;
};
#define PARTS_LIST_FOREACH(iter) TAILQ_FOREACH(iter, &parts_list, parts_list_entry)
@@ -342,6 +344,7 @@ struct parts_gauge *parts_get_vgauge(struct parts *parts, int state);
struct parts_construction_process *parts_get_construction_process(struct parts *parts, int state);
struct parts_flash *parts_get_flash(struct parts *parts, int state);
void parts_set_pos(struct parts *parts, Point pos);
void parts_set_global_pos(Point pos);
void parts_set_dims(struct parts *parts, struct parts_common *common, int w, int h);
void parts_set_scale_x(struct parts *parts, float mag);
void parts_set_scale_y(struct parts *parts, float mag);