From 9ccc4ab0c753fdfaa0eac4745f21cebb57de9ecb Mon Sep 17 00:00:00 2001 From: kichikuou Date: Sat, 7 Jun 2025 07:23:57 +0900 Subject: [PATCH] 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. --- src/parts/motion.c | 52 ++++++++++++++++++++++++++++++++------ src/parts/parts.c | 13 +++++++++- src/parts/parts_internal.h | 5 +++- 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/src/parts/motion.c b/src/parts/motion.c index 5827321..13a593f 100644 --- a/src/parts/motion.c +++ b/src/parts/motion.c @@ -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) diff --git a/src/parts/parts.c b/src/parts/parts.c index 4402a07..521129e 100644 --- a/src/parts/parts.c +++ b/src/parts/parts.c @@ -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; diff --git a/src/parts/parts_internal.h b/src/parts/parts_internal.h index db3b6ee..11030d1 100644 --- a/src/parts/parts_internal.h +++ b/src/parts/parts_internal.h @@ -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);