mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-23 06:34:18 -04:00
Implement & link m_vibctl.c
This commit is contained in:
@@ -86,6 +86,10 @@ m_view.c:
|
||||
.rodata: [0x806433D8, 0x80643408]
|
||||
sys_stacks.c:
|
||||
.bss: [0x812F5670, 0x812F9670]
|
||||
m_vibctl.c:
|
||||
.text: [0x8040387C, 0x804040F0]
|
||||
.rodata: [0x80643550, 0x806436C8]
|
||||
.bss: [0x812F3098, 0x812F31B8]
|
||||
THA_GA.c:
|
||||
.text: [0x80404AE0, 0x80404B40]
|
||||
TwoHeadArena.c:
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PAD_MOTOR_STOP 0
|
||||
#define PAD_MOTOR_RUMBLE 1
|
||||
#define PAD_MOTOR_STOP_HARD 2
|
||||
|
||||
#define PAD_BUTTON_LEFT 0x0001
|
||||
#define PAD_BUTTON_RIGHT 0x0002
|
||||
#define PAD_BUTTON_DOWN 0x0004
|
||||
|
||||
+76
-1
@@ -7,9 +7,84 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define mVibctl_FLAG_FORCE_STOP_NONE 0
|
||||
#define mVibctl_FLAG_FORCE_STOP0 (1 << 0) // 1
|
||||
#define mVibctl_FLAG_FORCE_STOP1 (1 << 1) // 2
|
||||
#define mVibctl_FLAG_FORCE_STOP2 (1 << 2) // 4
|
||||
#define mVibctl_FLAG_FORCE_STOP3 (1 << 3) // 8
|
||||
#define mVibctl_FLAG_FORCE_STOP_ALL (mVibctl_FLAG_FORCE_STOP0 | mVibctl_FLAG_FORCE_STOP1 | mVibctl_FLAG_FORCE_STOP2 | mVibctl_FLAG_FORCE_STOP3) // 15
|
||||
|
||||
enum {
|
||||
mVibctl_ELEM_ENTRY_ATTACK, // fade-in program
|
||||
mVibctl_ELEM_ENTRY_SUSTAIN, // sustain program
|
||||
mVibctl_ELEM_ENTRY_RELEASE, // fade-out program
|
||||
mVibctl_ELEM_ENTRY_END, // program has finished
|
||||
|
||||
mVibctl_ELEM_ENTRY_NUM = mVibctl_ELEM_ENTRY_END
|
||||
};
|
||||
|
||||
enum {
|
||||
mVibctl_VIB_PROG_NON, // rumble config attack, shake tree attack
|
||||
mVibctl_VIB_PROG_FFF, // fish touch bobber, fishing rod cast, rumble config sustain, Mouth of Truth furniture interaction attack & sustain, shovel hits soft object, net swing, axe cut attack & release, trip attack, pick weed sustain & release
|
||||
mVibctl_VIB_PROG_F, // unused?
|
||||
mVibctl_VIB_PROG_MF, // unused?
|
||||
mVibctl_VIB_PROG_MP, // unused?
|
||||
mVibctl_VIB_PROG_P, // rumble config release, shake tree release
|
||||
mVibctl_VIB_PROG_FUNBARI, // unused?
|
||||
mVibctl_VIB_PROG_ANAHORI, // digging with shovel
|
||||
mVibctl_VIB_PROG_ANAUME, // filling hole with shovel
|
||||
mVibctl_VIB_PROG_IMPACT, // fish bite bobber, shovel hits hard object
|
||||
mVibctl_VIB_PROG_KI_GA_TAORERU, // axe cut sustain
|
||||
mVibctl_VIB_PROG_KI_WO_YUSURU, // shake tree sustain
|
||||
mVibctl_VIB_PROG_KORONODA, // trip sustain
|
||||
mVibctl_VIB_PROG_SURPRISE, // Mouth of Truth furniture interaction release
|
||||
mVibctl_VIB_PROG_DUMMY_B, // unused?
|
||||
mVibctl_VIB_PROG_SAMPLE, // unused?
|
||||
|
||||
mVibctl_VIB_PROG_NUM
|
||||
};
|
||||
|
||||
#define mVibctl_ELEM_NUM 4
|
||||
|
||||
typedef struct vibration_element_entry_s {
|
||||
int type;
|
||||
int frames;
|
||||
f32 step;
|
||||
} mVibInfo_elem_entry_c;
|
||||
|
||||
typedef struct vibration_element_s {
|
||||
mVibInfo_elem_entry_c entries[mVibctl_ELEM_ENTRY_NUM];
|
||||
f32 step0;
|
||||
f32 step1;
|
||||
int now_entry;
|
||||
int state_idx;
|
||||
f32 frame_intensity;
|
||||
int entry_frame;
|
||||
f32 now_intensity;
|
||||
int command; // for padmgr, PAD_MOTOR_*
|
||||
} mVibElem_c;
|
||||
|
||||
typedef struct vibration_info_s {
|
||||
mVibElem_c* target_elem;
|
||||
mVibElem_c elements[mVibctl_ELEM_NUM];
|
||||
int num_elements;
|
||||
int force_stop;
|
||||
int last_force_stop;
|
||||
} mVibInfo_c;
|
||||
|
||||
typedef struct vibration_work_data_S {
|
||||
const u8* data;
|
||||
int count;
|
||||
} mVibWorkData_c;
|
||||
|
||||
extern void mVibctl_ct();
|
||||
extern void mVibctl_reset();
|
||||
extern void mVibctl_init0();
|
||||
extern void mVibctl_init();
|
||||
extern void mVibctl_reset();
|
||||
extern void mVibctl_entry(int total_frames, int attack_type, int sustain_type, int release_type, int attack_frames, int sustain_frames, int release_frames, f32 step);
|
||||
extern void mVibctl_simple_entry(int total_frames, int type, int attack_frames, int sustain_frames, int release_frames, f32 step);
|
||||
extern void mVibctl_set_force_stop(int force_stop);
|
||||
extern void mVibctl_clr_force_stop(int force_stop);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+9
-6
@@ -22,8 +22,8 @@ enum pads {
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
u8 last_intensity;
|
||||
u8 now_intensity;
|
||||
u8 last_command; // PAD_MOTOR_*
|
||||
u8 now_command; // PAD_MOTOR_*
|
||||
u8 frames;
|
||||
u8 _pad;
|
||||
} Motor_t;
|
||||
@@ -64,18 +64,21 @@ typedef struct {
|
||||
extern padmgr padmgr_class;
|
||||
|
||||
extern int padmgr_isConnectedController(int pad);
|
||||
extern void padmgr_force_stop_ON();
|
||||
extern void padmgr_force_stop_OFF();
|
||||
extern void padmgr_RumbleSet(int pad, int intensity);
|
||||
|
||||
#define padmgr_setClient(callback, param) \
|
||||
#define padmgr_setClient(callback_proc, param) \
|
||||
do { \
|
||||
padmgr* mgr = &padmgr_class; \
|
||||
mgr->callback = callback; \
|
||||
mgr->callback = callback_proc; \
|
||||
mgr->callback_param = param; \
|
||||
} while (0)
|
||||
|
||||
#define padmgr_removeClient(callback, param) \
|
||||
#define padmgr_removeClient(callback_proc, param) \
|
||||
do { \
|
||||
padmgr* mgr = &padmgr_class; \
|
||||
if (mgr->callback == (callback) && mgr->callback_param == (param)) { \
|
||||
if (mgr->callback == (callback_proc) && mgr->callback_param == (param)) { \
|
||||
mgr->callback = NULL; \
|
||||
mgr->callback_param = NULL; \
|
||||
} \
|
||||
|
||||
+490
@@ -0,0 +1,490 @@
|
||||
#include "m_vibctl.h"
|
||||
|
||||
#include "libultra/libultra.h"
|
||||
#include "padmgr.h"
|
||||
#include "m_common_data.h"
|
||||
#include "m_field_info.h"
|
||||
#include "m_event.h"
|
||||
#include "dolphin/pad.h"
|
||||
|
||||
static const u8 mVW_Non[1] = { PAD_MOTOR_STOP };
|
||||
|
||||
static const u8 mVW_FFF[1] = { PAD_MOTOR_RUMBLE };
|
||||
|
||||
static const u8 mVW_F[2] = {
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP
|
||||
};
|
||||
|
||||
static const u8 mVW_MF[3] = {
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP
|
||||
};
|
||||
|
||||
static const u8 mVW_MP[4] = {
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP
|
||||
};
|
||||
|
||||
static const u8 mVW_P[5] = {
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP
|
||||
};
|
||||
|
||||
static const u8 mVW_funbari[8] = {
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP_HARD
|
||||
};
|
||||
|
||||
static const u8 mVW_anahori[8] = {
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP
|
||||
};
|
||||
|
||||
static const u8 mVW_anaume[60] = {
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP_HARD
|
||||
};
|
||||
|
||||
static const u8 mVW_impact[9] = {
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP_HARD
|
||||
};
|
||||
|
||||
static const u8 mVW_ki_ga_taoreru[36] = {
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_RUMBLE
|
||||
};
|
||||
|
||||
static const u8 mVW_ki_wo_yusuru[13] = {
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP
|
||||
};
|
||||
|
||||
static const u8 mVW_koronoda[14] = {
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP
|
||||
};
|
||||
|
||||
static const u8 mVW_surprise[7] = {
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP
|
||||
};
|
||||
|
||||
static const u8 mVW_dummy_b[1] = { PAD_MOTOR_RUMBLE };
|
||||
|
||||
static const u8 mVW_sample[13] = {
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_RUMBLE,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP_HARD,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP,
|
||||
PAD_MOTOR_STOP
|
||||
};
|
||||
|
||||
#define VIB_PROG(name) { mVW_##name, ARRAY_SIZE(mVW_##name, u8) }
|
||||
static const mVibWorkData_c mVW_data[mVibctl_VIB_PROG_NUM] = {
|
||||
VIB_PROG(Non),
|
||||
VIB_PROG(FFF),
|
||||
VIB_PROG(F),
|
||||
VIB_PROG(MF),
|
||||
VIB_PROG(MP),
|
||||
VIB_PROG(P),
|
||||
VIB_PROG(funbari),
|
||||
VIB_PROG(anahori),
|
||||
VIB_PROG(anaume),
|
||||
VIB_PROG(impact),
|
||||
VIB_PROG(ki_ga_taoreru),
|
||||
VIB_PROG(ki_wo_yusuru),
|
||||
VIB_PROG(koronoda),
|
||||
VIB_PROG(surprise),
|
||||
VIB_PROG(dummy_b),
|
||||
VIB_PROG(sample)
|
||||
};
|
||||
|
||||
static mVibInfo_c mVib_info;
|
||||
|
||||
static void mVibElem_move(mVibElem_c* elem) {
|
||||
mVibInfo_elem_entry_c* now_entry = elem->entries + elem->now_entry;
|
||||
int type = now_entry->type;
|
||||
const mVibWorkData_c* work_data = &mVW_data[type];
|
||||
|
||||
elem->entry_frame++;
|
||||
elem->frame_intensity = elem->step1 * elem->step0;
|
||||
|
||||
if (elem->now_entry == mVibctl_ELEM_ENTRY_ATTACK) {
|
||||
elem->frame_intensity *= (f32)elem->entry_frame * now_entry->step;
|
||||
}
|
||||
else if (elem->now_entry == mVibctl_ELEM_ENTRY_RELEASE) {
|
||||
elem->frame_intensity *= now_entry->step * (now_entry->frames - elem->entry_frame);
|
||||
}
|
||||
|
||||
if (work_data->data[elem->state_idx] == PAD_MOTOR_RUMBLE) {
|
||||
/* only rumble when our current intensity has reached or surpassed 1.0f */
|
||||
elem->now_intensity += elem->frame_intensity;
|
||||
|
||||
if (elem->now_intensity >= 1.0f) {
|
||||
elem->command = PAD_MOTOR_RUMBLE;
|
||||
elem->now_intensity -= 1.0f;
|
||||
}
|
||||
else {
|
||||
elem->command = PAD_MOTOR_STOP;
|
||||
}
|
||||
}
|
||||
else {
|
||||
elem->command = work_data->data[elem->state_idx];
|
||||
}
|
||||
|
||||
{
|
||||
/* increment current program state index */
|
||||
int state_count = work_data->count;
|
||||
int now_state = elem->state_idx + 1;
|
||||
elem->state_idx = now_state;
|
||||
|
||||
/* check if program state index has rolled over */
|
||||
if (now_state >= state_count) {
|
||||
elem->state_idx = 0;
|
||||
}
|
||||
|
||||
/* check if current stage frames have ended, and if so, advanced to next one */
|
||||
if (elem->entry_frame >= now_entry->frames) {
|
||||
elem->now_entry++;
|
||||
elem->entry_frame = 0;
|
||||
elem->state_idx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mVibInfo_elem_entry(mVibInfo_c* vib_info, int total_frames, int attack_type, int sustain_type, int release_type, int attack_frames, int sustain_frames, int release_frames, f32 step) {
|
||||
if ((attack_frames != 0 || sustain_frames != 0 || release_frames != 0) && (step < 640.0f && vib_info->num_elements < mVibctl_ELEM_NUM)) {
|
||||
mVibElem_c* elem = vib_info->elements + vib_info->num_elements;
|
||||
bzero(elem, sizeof(mVibElem_c));
|
||||
|
||||
/* set attack phase configuration */
|
||||
elem->entries[mVibctl_ELEM_ENTRY_ATTACK].type = attack_type;
|
||||
elem->entries[mVibctl_ELEM_ENTRY_ATTACK].frames = attack_frames;
|
||||
elem->entries[mVibctl_ELEM_ENTRY_ATTACK].step = (attack_frames > 0) ? (1.0f / (f32)attack_frames) : -1.0f;
|
||||
|
||||
/* set sustain phase configuration */
|
||||
elem->entries[mVibctl_ELEM_ENTRY_SUSTAIN].type = sustain_type;
|
||||
elem->entries[mVibctl_ELEM_ENTRY_SUSTAIN].frames = sustain_frames;
|
||||
elem->entries[mVibctl_ELEM_ENTRY_SUSTAIN].step = (sustain_frames > 0) ? (1.0f / (f32)sustain_frames) : -1.0f;
|
||||
|
||||
/* set release phase configuration */
|
||||
elem->entries[mVibctl_ELEM_ENTRY_RELEASE].type = release_type;
|
||||
elem->entries[mVibctl_ELEM_ENTRY_RELEASE].frames = release_frames;
|
||||
elem->entries[mVibctl_ELEM_ENTRY_RELEASE].step = (release_frames > 0) ? (1.0f / (f32)release_frames) : -1.0f;
|
||||
|
||||
if (attack_frames == 0) {
|
||||
if (sustain_frames == 0) {
|
||||
elem->now_entry = mVibctl_ELEM_ENTRY_RELEASE;
|
||||
}
|
||||
else {
|
||||
elem->now_entry = mVibctl_ELEM_ENTRY_SUSTAIN;
|
||||
}
|
||||
}
|
||||
|
||||
elem->step1 = total_frames * 0.01f;
|
||||
|
||||
if (step < 41.0f) {
|
||||
elem->step0 = 1.0f;
|
||||
}
|
||||
else {
|
||||
elem->step0 = 1.0f / (step - 40.0f);
|
||||
}
|
||||
|
||||
vib_info->num_elements++;
|
||||
}
|
||||
}
|
||||
|
||||
static void mVibInfo_elem_delete(mVibInfo_c* vib_info, int elem_no) {
|
||||
int i;
|
||||
int n_elems = vib_info->num_elements - 1;
|
||||
|
||||
for (i = elem_no; i < n_elems; i++) {
|
||||
mVibElem_c* dst_elem = vib_info->elements + (i + 1);
|
||||
mVibElem_c* src_elem = vib_info->elements + i;
|
||||
bcopy(dst_elem, src_elem, sizeof(mVibElem_c));
|
||||
}
|
||||
|
||||
bzero(vib_info->elements + n_elems, sizeof(mVibElem_c));
|
||||
vib_info->num_elements--;
|
||||
}
|
||||
|
||||
static void mVibInfo_set_force_stop(mVibInfo_c* vib_info, int force_stop) {
|
||||
vib_info->force_stop |= force_stop;
|
||||
}
|
||||
|
||||
static void mVibInfo_clr_force_stop(mVibInfo_c* vib_info, int force_stop) {
|
||||
vib_info->force_stop &= ~force_stop;
|
||||
}
|
||||
|
||||
static void mVibInfo_set_target_elem(mVibInfo_c* vib_info) {
|
||||
int n_elems = vib_info->num_elements;
|
||||
f32 max = -10000.0f;
|
||||
mVibElem_c* elem = vib_info->elements;
|
||||
mVibElem_c* selected = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_elems; i++) {
|
||||
if (elem->frame_intensity > max) {
|
||||
max = elem->frame_intensity;
|
||||
selected = elem;
|
||||
}
|
||||
elem++;
|
||||
}
|
||||
|
||||
vib_info->target_elem = selected;
|
||||
}
|
||||
|
||||
static void mVibInfo_force(mVibInfo_c* vib_info) {
|
||||
if (Save_Get(config.vibration_enabled)) {
|
||||
mVibInfo_set_force_stop(vib_info, mVibctl_FLAG_FORCE_STOP0);
|
||||
}
|
||||
else {
|
||||
mVibInfo_clr_force_stop(vib_info, mVibctl_FLAG_FORCE_STOP0);
|
||||
}
|
||||
|
||||
if (vib_info->force_stop != mVibctl_FLAG_FORCE_STOP_NONE && vib_info->last_force_stop == mVibctl_FLAG_FORCE_STOP_NONE) {
|
||||
padmgr_force_stop_ON();
|
||||
}
|
||||
else if (vib_info->force_stop == mVibctl_FLAG_FORCE_STOP_NONE && vib_info->last_force_stop != mVibctl_FLAG_FORCE_STOP_NONE) {
|
||||
padmgr_force_stop_OFF();
|
||||
}
|
||||
|
||||
vib_info->last_force_stop = vib_info->force_stop;
|
||||
}
|
||||
|
||||
static void mVibInfo_set_motor(mVibInfo_c* vib_info) {
|
||||
if (vib_info->target_elem != NULL) {
|
||||
padmgr_RumbleSet(PAD0, vib_info->target_elem->command);
|
||||
}
|
||||
else {
|
||||
padmgr_RumbleSet(PAD0, PAD_MOTOR_STOP);
|
||||
}
|
||||
}
|
||||
|
||||
static void mVibInfo_move(mVibInfo_c* vib_info) {
|
||||
int i;
|
||||
|
||||
mVibInfo_force(vib_info);
|
||||
|
||||
for (i = 0; i < vib_info->num_elements; i++) {
|
||||
mVibElem_move(vib_info->elements + i);
|
||||
}
|
||||
|
||||
for (i = vib_info->num_elements - 1; i >= 0; i--) {
|
||||
if (vib_info->elements[i].now_entry >= mVibctl_ELEM_ENTRY_END) {
|
||||
mVibInfo_elem_delete(vib_info, i);
|
||||
}
|
||||
}
|
||||
|
||||
mVibInfo_set_target_elem(vib_info);
|
||||
|
||||
if (vib_info->force_stop == mVibctl_FLAG_FORCE_STOP_NONE) {
|
||||
mVibInfo_set_motor(vib_info);
|
||||
}
|
||||
}
|
||||
|
||||
static void mVibctl_check_title_demo() {
|
||||
if (mFI_CheckFieldData() && mFI_GET_TYPE(mFI_GetFieldId()) == mFI_FIELDTYPE_FG && mEv_CheckTitleDemo() > 0) {
|
||||
mVibctl_set_force_stop(mVibctl_FLAG_FORCE_STOP2);
|
||||
}
|
||||
else {
|
||||
mVibctl_clr_force_stop(mVibctl_FLAG_FORCE_STOP2);
|
||||
}
|
||||
}
|
||||
|
||||
static void mVibctl_callback(void* arg) {
|
||||
mVibctl_check_title_demo();
|
||||
mVibInfo_move(&mVib_info);
|
||||
}
|
||||
|
||||
extern void mVibctl_ct() {
|
||||
bzero(&mVib_info, sizeof(mVibInfo_c));
|
||||
}
|
||||
|
||||
extern void mVibctl_init0() {
|
||||
mVibctl_ct();
|
||||
}
|
||||
|
||||
extern void mVibctl_init() {
|
||||
padmgr_setClient(&mVibctl_callback, NULL);
|
||||
}
|
||||
|
||||
extern void mVibctl_cleanup() {
|
||||
padmgr_removeClient(&mVibctl_callback, NULL);
|
||||
}
|
||||
|
||||
extern void mVibctl_reset() {
|
||||
mVibctl_clr_force_stop(mVibctl_FLAG_FORCE_STOP_ALL);
|
||||
mVibctl_set_force_stop(mVibctl_FLAG_FORCE_STOP3);
|
||||
}
|
||||
|
||||
extern void mVibctl_entry(int total_frames, int attack_type, int sustain_type, int release_type, int attack_frames, int sustain_frames, int release_frames, f32 step) {
|
||||
mVibInfo_elem_entry(&mVib_info, total_frames, attack_type, sustain_type, release_type, attack_frames, sustain_frames, release_frames, step);
|
||||
}
|
||||
|
||||
extern void mVibctl_simple_entry(int total_frames, int type, int attack_frames, int sustain_frames, int release_frames, f32 step) {
|
||||
mVibInfo_elem_entry(&mVib_info, total_frames, type, type, type, attack_frames, sustain_frames, release_frames, step);
|
||||
}
|
||||
|
||||
extern void mVibctl_set_force_stop(int force_stop) {
|
||||
mVibInfo_set_force_stop(&mVib_info, force_stop);
|
||||
}
|
||||
|
||||
extern void mVibctl_clr_force_stop(int force_stop) {
|
||||
mVibInfo_clr_force_stop(&mVib_info, force_stop);
|
||||
}
|
||||
Reference in New Issue
Block a user