mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-23 22:45:09 -04:00
forgor to pull lmao
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:
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef AC_STRUCTURE_H
|
||||
#define AC_STRUCTURE_H
|
||||
|
||||
#include "types.h"
|
||||
#include "m_actor.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef ACTOR* (*aSTR_SETUP_ACTOR_PROC)(GAME_PLAY*, mActor_name_t, int, f32, f32);
|
||||
|
||||
// TODO: finish clip
|
||||
typedef struct actor_structure_clip_s {
|
||||
aSTR_SETUP_ACTOR_PROC setup_actor_proc;
|
||||
} aSTR_Clip_c;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -22,6 +22,9 @@ extern void sAdo_SysLevStart(u8 id);
|
||||
|
||||
extern void sAdo_SysTrgStart(u16 id);
|
||||
|
||||
extern void sAdos_KishaStatusLevel(f32 speed, u32 ongenNum1, u16 angle1, f32 distance1, u32 ongenNum2, u16 angle2, f32 distance2);
|
||||
extern void sAdos_KishaStatusTrg(u8 state);
|
||||
|
||||
/* Not sure about the last param name */
|
||||
extern void sAdo_VoiceSe(u8 num, u8 num2, u8 num3, s16 character_idx, u8 scale, u8 mode);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -127,6 +127,19 @@ struct actor_s {
|
||||
|
||||
#define mActor_NONE_PROC1 ((mActor_proc)none_proc1)
|
||||
|
||||
typedef struct actor_list_s {
|
||||
int num_actors;
|
||||
ACTOR* actor;
|
||||
} Actor_list;
|
||||
|
||||
typedef struct actor_info_s {
|
||||
int total_num;
|
||||
Actor_list list[ACTOR_PART_NUM];
|
||||
} Actor_info;
|
||||
|
||||
extern void Actor_delete(ACTOR* actor);
|
||||
extern ACTOR* Actor_info_fgName_search(Actor_info* actor_info, mActor_name_t fg_name, int part);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
+4
-1
@@ -4,6 +4,7 @@
|
||||
#include "types.h"
|
||||
#include "ac_gyoei_h.h"
|
||||
#include "ac_insect_h.h"
|
||||
#include "ac_structure.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -13,7 +14,9 @@ extern "C" {
|
||||
typedef struct clip_s {
|
||||
/* 0x000 */ void* _000[(0x07C - 0x000) / sizeof(void*)];
|
||||
/* 0x07C */ aINS_Clip_c* insect_clip;
|
||||
/* 0x080 */ void* _080[(0x0AC - 0x080) / sizeof(void*)];
|
||||
/* 0x080 */ void* _080[(0x08C - 0x080) / sizeof(void*)];
|
||||
/* 0x08C */ aSTR_Clip_c* structure_clip;
|
||||
/* 0x090 */ void* _090[(0x0AC - 0x090) / sizeof(void*)];
|
||||
/* 0x0AC */ aGYO_Clip_c* gyo_clip;
|
||||
/* 0x0B0 */ void* _0B0[(0x104 - 0x0B0) / sizeof(void*)];
|
||||
} Clip_c;
|
||||
|
||||
@@ -57,6 +57,7 @@ extern int mCoBG_CheckWaterAttribute(u32 attribute);
|
||||
extern f32 mCoBG_GetBgY_AngleS_FromWpos(s_xyz* angle_to_ground, xyz_t wpos, f32 offset);
|
||||
extern int mCoBG_CheckWaterAttribute_OutOfSea(u32 attribute);
|
||||
extern int mCoBG_CheckHole_OrgAttr(u32 attribute);
|
||||
extern f32 mCoBG_GetBgY_OnlyCenter_FromWpos2(xyz_t wpos, f32 foot_dist);
|
||||
|
||||
extern f32 mCoBG_GetWaterHeight_File(xyz_t wpos, char* file, int line);
|
||||
#define mCoBG_GetWaterHeight(wpos) mCoBG_GetWaterHeight_File(wpos, __FILE__, __LINE__)
|
||||
|
||||
+21
-3
@@ -162,7 +162,9 @@ typedef struct common_data_s {
|
||||
/* 0x02651E */ mActor_name_t last_field_id;
|
||||
/* 0x026520 */ u8 in_initial_block; /* when TRUE, the player is in the acre which they exited a building. FALSE otherwise. */
|
||||
/* 0x026521 */ u8 submenu_disabled; /* when set, submenus cannot be accessed from start button */
|
||||
/* 0x026522 */ u8 _26522[0x2666C - 0x26522];
|
||||
/* 0x026522 */ u8 sunlight_flag;
|
||||
/* 0x026523 */ u8 train_flag;
|
||||
/* 0x026522 */ u8 _26524[0x2666C - 0x26524];
|
||||
/* 0x02666C */ s16 weather;
|
||||
/* 0x02666E */ s16 weather_intensity;
|
||||
/* 0x026670 */ lbRTC_time_c weather_time;
|
||||
@@ -173,11 +175,27 @@ typedef struct common_data_s {
|
||||
/* 0x02852E */ s16 goods_power;
|
||||
/* 0x028530 */ Door_data_c door_data; /* misc door data */
|
||||
/* 0x028544 */ Door_data_c structure_exit_door_data; /* door data for when exiting a building */
|
||||
/* 0x028558 */ u8 tmp1[0x28879 - 0x28558];
|
||||
/* 0x028558 */ u8 tmp1[0x02883E - 0x28558];
|
||||
/* 0x02883E */ u8 train_coming_flag; /* state tracker for when train is going to spawn/has spawned */
|
||||
/* 0x02883F */ u8 train_exists_flag; /* state tracker for when train exists */
|
||||
/* 0x028840 */ u8 train_control_state; /* current train state */
|
||||
/* 0x028841 */ u8 train_last_control_state; /* previous train state */
|
||||
/* 0x028842 */ u8 train_signal;
|
||||
/* 0x028843 */ u8 train_day;
|
||||
/* 0x028844 */ u8 train_action;
|
||||
/* 0x028845 */ u8 train_timer;
|
||||
/* 0x028848 */ u32 train_start_timer;
|
||||
/* 0x02884C */ f32 train_speed;
|
||||
/* 0x028850 */ xyz_t train_position;
|
||||
/* 0x02885C */ f32 unused_02885C;
|
||||
/* 0x028860 */ f32 unused_028860;
|
||||
/* 0x028864 */ u16 unused_028864;
|
||||
/* 0x028866 */ u16 unused_028866;
|
||||
/* 0x028868 */ u8 _028868[0x028879 - 0x028868];
|
||||
/* 0x028879 */ u8 auto_nwrite_count;
|
||||
/* 0x02887A */ lbRTC_year_t auto_nwrite_year;
|
||||
/* 0x02887C */ u8 save_error_type; /* set to one of the mFRm_ERROR_* states when save is invalid */
|
||||
/* 0x02887D */ u8 train_coming_flag; /* set when the train is coming */
|
||||
/* 0x02887D */ u8 train_approaching_flag; /* set when the train is coming */
|
||||
/* 0x02887E */ u8 buried_treasure_flag; /* when set, treasure cannot be buried */
|
||||
/* 0x02887F */ u8 spnpc_first_talk_flags;
|
||||
/* 0x028880 */ u8 needlework_first_talk_flags;
|
||||
|
||||
@@ -90,6 +90,16 @@ typedef struct location_info_s {
|
||||
/* 0x10 */ mActor_name_t* block_data;
|
||||
} mFI_unit_c;
|
||||
|
||||
typedef struct block_table_s {
|
||||
s8 block_x;
|
||||
s8 block_z;
|
||||
|
||||
f32 pos_x;
|
||||
f32 pos_z;
|
||||
|
||||
mActor_name_t* items;
|
||||
} mFI_block_tbl_c;
|
||||
|
||||
extern int mFI_CheckFieldData();
|
||||
extern mActor_name_t mFI_GetFieldId();
|
||||
extern int mFI_GetClimate();
|
||||
|
||||
@@ -466,6 +466,10 @@ extern int mNT_check_unknown(mActor_name_t item_no);
|
||||
|
||||
#define EXIT_DOOR 0x4080
|
||||
|
||||
#define TRAIN_STATION 0x5809
|
||||
#define TRAIN0 0x580A
|
||||
#define TRAIN1 0x580B
|
||||
|
||||
#define SP_NPC_START 0xD000
|
||||
#define SP_NPC_ARTIST (SP_NPC_START + 0) // D000
|
||||
#define SP_NPC_BROKER (SP_NPC_START + 1) // D001
|
||||
|
||||
+6
-2
@@ -8,6 +8,7 @@
|
||||
#include "m_camera2.h"
|
||||
#include "m_submenu.h"
|
||||
#include "m_pause.h"
|
||||
#include "m_field_info.h"
|
||||
#include "m_play_h.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -18,12 +19,15 @@ extern "C" {
|
||||
struct game_play_s {
|
||||
/* 0x0000 */ GAME game;
|
||||
// TODO: finish
|
||||
/* 0x00E0 */ u8 _00E0[0x1A68 - 0x00E0];
|
||||
/* 0x00E0 */ int _00E0;
|
||||
/* 0x00E4 */ mFI_block_tbl_c block_table;
|
||||
/* 0x00F4 */ mFI_block_tbl_c last_block_table;
|
||||
/* 0x0104 */ u8 _0104[0x1A68 - 0x0104];
|
||||
/* 0x1A68 */ View view;
|
||||
/* 0x1B88 */ Camera2 camera;
|
||||
/* 0x1CC0 */ u8 _1CC0[0x1DA0 - 0x1CC0];
|
||||
/* 0x1DA0 */ pause_t pause;
|
||||
/* 0x1DA8 */ u8 _1DA8[0x1DEC - 0x1DA8];
|
||||
/* 0x1DA8 */ Actor_info actor_info;
|
||||
/* 0x1DEC */ Submenu submenu;
|
||||
/* 0x1FA4 */ u8 _1FA4[0x200C - 0x1FA4];
|
||||
/* 0x200C */ MtxF matrix;
|
||||
|
||||
@@ -7,6 +7,15 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum field_draw_type {
|
||||
FIELD_DRAW_TYPE_OUTDOORS,
|
||||
FIELD_DRAW_TYPE_INDOORS,
|
||||
FIELD_DRAW_TYPE_TRAIN,
|
||||
FIELD_DRAW_TYPE_PLAYER_SELECT,
|
||||
|
||||
FIELD_DRAW_TYPE_NUM
|
||||
};
|
||||
|
||||
/*
|
||||
TODO: is this right? I assume so based on file names but
|
||||
there may be a better place for this
|
||||
|
||||
@@ -61,6 +61,8 @@ enum {
|
||||
#define mTM_SECONDS_IN_HALFDAY 12*60*60
|
||||
#define mTM_SECONDS_IN_DAY 24*60*60
|
||||
|
||||
#define mTM_MINUTES_IN_HOUR 60
|
||||
|
||||
typedef struct time_calendar_term_s {
|
||||
lbRTC_month_t month;
|
||||
lbRTC_day_t day;
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef M_TRAIN_CONTROL_H
|
||||
#define M_TRAIN_CONTROL_H
|
||||
|
||||
#include "types.h"
|
||||
#include "m_play_h.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define mTRC_SLOW_SPEED 2.0f // speed stopping/starting
|
||||
#define mTRC_FAST_SPEED 6.0f // speed when farther away from station
|
||||
|
||||
enum {
|
||||
mTRC_ACTION_NONE,
|
||||
mTRC_ACTION_SPAWN_MOVING,
|
||||
mTRC_ACTION_BEGIN_SLOWDOWN,
|
||||
mTRC_ACTION_BEGIN_STOP,
|
||||
mTRC_ACTION_SIGNAL_STOPPED,
|
||||
mTRC_ACTION_WAIT_STOPPED,
|
||||
mTRC_ACTION_SIGNAL_STARTING,
|
||||
mTRC_ACTION_BEGIN_PULL_OUT,
|
||||
mTRC_ACTION_SPEED_UP,
|
||||
|
||||
mTRC_ACTION_NUM
|
||||
};
|
||||
|
||||
extern void mTRC_init();
|
||||
extern void mTRC_move(GAME_PLAY* play);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+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; \
|
||||
} \
|
||||
|
||||
@@ -0,0 +1,530 @@
|
||||
#include "m_train_control.h"
|
||||
|
||||
#include "m_common_data.h"
|
||||
#include "m_play.h"
|
||||
#include "m_player.h"
|
||||
#include "m_player_lib.h"
|
||||
#include "sys_math.h"
|
||||
#include "sys_math3d.h"
|
||||
#include "audio.h"
|
||||
#include "m_event.h"
|
||||
#include "m_scene.h"
|
||||
#include "m_lib.h"
|
||||
#include "m_name_table.h"
|
||||
#include "m_collision_bg.h"
|
||||
|
||||
#define mTRC_RTC_TIME_SECONDS(rtc_time) (rtc_time->sec + (rtc_time->min + rtc_time->hour * mTM_MINUTES_IN_HOUR) * mTM_SECONDS_IN_MINUTE)
|
||||
|
||||
static void mTRC_SetMicPos(GAME_PLAY* play, xyz_t* mic_pos) {
|
||||
xyz_t pos;
|
||||
PLAYER_ACTOR* player = get_player_actor_withoutCheck(play);
|
||||
Door_data_c* door = Common_GetPointer(structure_exit_door_data);
|
||||
f32 z = cosf_table(0.0f) * 77.0f; // cos(0) = 1, 1.0f * 77.0f = 77.0f
|
||||
f32 x = sinf_table(0.0f) * 77.0f; // sin(0) = 0, 0.0f * 77.0f = 0.0f
|
||||
|
||||
if (Common_Get(field_type) != mFI_FIELDTYPE2_FG) {
|
||||
xyz_t_move_s_xyz(&pos, &door->exit_position);
|
||||
}
|
||||
else {
|
||||
if (player != NULL) {
|
||||
xyz_t_move(&pos, &player->actor_class.world_position);
|
||||
}
|
||||
else {
|
||||
xyz_t_move(&pos, &ZeroVec);
|
||||
}
|
||||
}
|
||||
|
||||
mic_pos->x = pos.x + x; // equates to pos.x + 0.0f = pos.x
|
||||
mic_pos->y = pos.y + 240.0f;
|
||||
mic_pos->z = pos.z + z; // equates to pos.z + 77.0f
|
||||
}
|
||||
|
||||
static void mTRC_KishaStatusLevel(GAME_PLAY* play, xyz_t pos, f32 speed) {
|
||||
xyz_t mic_pos;
|
||||
|
||||
f32 x;
|
||||
f32 y;
|
||||
f32 z;
|
||||
|
||||
s16 angle;
|
||||
u16 unsigned_angle;
|
||||
f32 distance;
|
||||
|
||||
s16 angle2;
|
||||
u16 unsigned_angle2;
|
||||
f32 distance2;
|
||||
|
||||
mTRC_SetMicPos(play, &mic_pos);
|
||||
x = pos.x - mic_pos.x;
|
||||
y = pos.y - mic_pos.y;
|
||||
z = pos.z - mic_pos.z;
|
||||
|
||||
angle = atans_table(z, x);
|
||||
distance = sqrtf(x * x + y * y + z * z);
|
||||
unsigned_angle = (int)angle;
|
||||
|
||||
x = (pos.x - 250.0f) - mic_pos.x;
|
||||
y = pos.y - mic_pos.y;
|
||||
z = pos.z - mic_pos.z;
|
||||
|
||||
angle2 = atans_table(z, x);
|
||||
distance2 = sqrtf(x * x + y * y + z * z);
|
||||
unsigned_angle2 = (int)angle2;
|
||||
|
||||
sAdos_KishaStatusLevel(speed, Common_GetPointer(train_coming_flag), unsigned_angle, distance, Common_GetPointer(train_exists_flag), unsigned_angle2, distance2);
|
||||
}
|
||||
|
||||
static void mTRC_KishaStatusTrg(u8 state) {
|
||||
if (state == 1) {
|
||||
Common_Set(train_approaching_flag, TRUE);
|
||||
}
|
||||
|
||||
sAdos_KishaStatusTrg(state);
|
||||
}
|
||||
|
||||
static int aTRC_area_check(GAME_PLAY* play, xyz_t pos) {
|
||||
int block_x;
|
||||
int block_z;
|
||||
int x_diff;
|
||||
|
||||
mFI_Wpos2BlockNum(&block_x, &block_z, pos);
|
||||
x_diff = (block_x - play->block_table.block_x) >= 0 ? (block_x - play->block_table.block_x) : -(block_x - play->block_table.block_x);
|
||||
|
||||
if (x_diff >= 2 || block_z != play->block_table.block_z) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int mTRC_go_process() {
|
||||
int res = FALSE;
|
||||
int demo_no = mEv_CheckTitleDemo();
|
||||
|
||||
if (((int)demo_no == 0 || demo_no == 1 || demo_no == -9) && Common_Get(field_draw_type) != FIELD_DRAW_TYPE_TRAIN && Common_Get(field_draw_type) != FIELD_DRAW_TYPE_PLAYER_SELECT) {
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#define HOUR_MIN_SEC_TO_SECS(h, m, s) (h * 3600 + m * 60 + s)
|
||||
static u32 mTRC_get_depart_time() {
|
||||
static u32 time_table[25] = {
|
||||
HOUR_MIN_SEC_TO_SECS( 0, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS( 1, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS( 2, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS( 3, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS( 4, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS( 5, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS( 6, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS( 7, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS( 8, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS( 9, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS(10, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS(11, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS(12, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS(13, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS(14, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS(15, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS(16, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS(17, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS(18, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS(19, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS(20, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS(21, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS(22, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS(23, 19, 0),
|
||||
HOUR_MIN_SEC_TO_SECS(24, 19, 0)
|
||||
};
|
||||
|
||||
int i = 0;
|
||||
u32 depart_time;
|
||||
lbRTC_time_c* rtc_time = Common_GetPointer(time.rtc_time);
|
||||
u32 now_sec = mTRC_RTC_TIME_SECONDS(rtc_time);
|
||||
int day;
|
||||
|
||||
while (TRUE) {
|
||||
if (time_table[i] >= now_sec) {
|
||||
depart_time = time_table[i] - HOUR_MIN_SEC_TO_SECS(0, 4, 10);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
Common_Set(train_day, rtc_time->day);
|
||||
return depart_time;
|
||||
}
|
||||
|
||||
static int mTRC_time_check() {
|
||||
u32 now_sec = mTRC_RTC_TIME_SECONDS(Common_GetPointer(time.rtc_time));
|
||||
return now_sec >= Common_Get(train_start_timer);
|
||||
}
|
||||
|
||||
static void mTRC_mati_init() {
|
||||
xyz_t pos;
|
||||
|
||||
Common_Set(train_action, mTRC_ACTION_WAIT_STOPPED);
|
||||
Common_Set(train_flag, TRUE);
|
||||
Common_Set(train_signal, TRUE);
|
||||
Common_Set(train_control_state, 1);
|
||||
Common_Set(train_last_control_state, 1);
|
||||
|
||||
pos.x = 2376.0f;
|
||||
pos.z = 740.0f;
|
||||
pos.y = 180.0f;
|
||||
Common_Set(train_position, pos);
|
||||
}
|
||||
|
||||
static void mTRC_demo_init() {
|
||||
xyz_t pos;
|
||||
lbRTC_time_c* rtc_time = Common_GetPointer(time.rtc_time);
|
||||
|
||||
Common_Set(train_action, mTRC_ACTION_BEGIN_SLOWDOWN);
|
||||
Common_Set(train_speed, mTRC_SLOW_SPEED);
|
||||
Common_Set(train_flag, TRUE);
|
||||
Common_Set(train_start_timer, mTRC_RTC_TIME_SECONDS(rtc_time) - HOUR_MIN_SEC_TO_SECS(0, 4, 50));
|
||||
Common_Set(train_day, Common_Get(time.rtc_time.day));
|
||||
Common_Set(train_control_state, 0);
|
||||
Common_Set(train_last_control_state, 0);
|
||||
|
||||
pos.x = 2037.0f;
|
||||
pos.z = 740.0f;
|
||||
pos.y = 180.0f;
|
||||
Common_Set(train_position, pos);
|
||||
}
|
||||
|
||||
static void mTRC_call_init() {
|
||||
xyz_t pos;
|
||||
|
||||
Common_Set(train_action, mTRC_ACTION_BEGIN_SLOWDOWN);
|
||||
Common_Set(train_speed, 0.0f);
|
||||
Common_Set(train_flag, TRUE);
|
||||
Common_Set(train_control_state, 1);
|
||||
Common_Set(train_last_control_state, 1);
|
||||
|
||||
pos.x = 1904.0f;
|
||||
pos.z = 740.0f;
|
||||
pos.y = 180.0f;
|
||||
Common_Set(train_position, pos);
|
||||
}
|
||||
|
||||
static void mTRC_norm_init() {
|
||||
xyz_t pos;
|
||||
|
||||
Common_Set(train_action, mTRC_ACTION_SPAWN_MOVING);
|
||||
Common_Set(train_speed, 0.0f);
|
||||
Common_Set(train_flag, TRUE);
|
||||
Common_Set(train_control_state, 0);
|
||||
Common_Set(train_last_control_state, 0);
|
||||
|
||||
pos.x = 320.0f;
|
||||
pos.z = 740.0f;
|
||||
pos.y = 180.0f;
|
||||
Common_Set(train_position, pos);
|
||||
}
|
||||
|
||||
static int mTRC_schedule(GAME_PLAY* play) {
|
||||
int res = -1;
|
||||
|
||||
if (mEv_CheckTitleDemo() == 1) {
|
||||
if (Common_Get(train_action) == mTRC_ACTION_NONE) {
|
||||
mTRC_mati_init();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
switch (Common_Get(train_coming_flag)) {
|
||||
case 3:
|
||||
{
|
||||
Common_Set(train_coming_flag, 0);
|
||||
mTRC_demo_init();
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
if (!aTRC_area_check(play, Common_Get(train_position)) && Common_Get(train_action) >= mTRC_ACTION_SIGNAL_STARTING) {
|
||||
mTRC_call_init();
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Common_Get(train_action) < mTRC_ACTION_SIGNAL_STARTING && Common_Get(train_action) != mTRC_ACTION_NONE) {
|
||||
Common_Set(train_coming_flag, FALSE);
|
||||
Common_Set(train_control_state, 1);
|
||||
Common_Set(train_last_control_state, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (Common_Get(train_action) == mTRC_ACTION_NONE) {
|
||||
mTRC_call_init();
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
if (Common_Get(train_action) == mTRC_ACTION_NONE && mEv_CheckArbeit() == FALSE && mTRC_time_check()) {
|
||||
mTRC_norm_init();
|
||||
res = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* TODO: @nonmatching something to do with common data loading at start of function */
|
||||
static void mTRC_trainControl(GAME_PLAY* play, int state) {
|
||||
u8 signal = Common_Get(train_signal);
|
||||
u8 action = Common_Get(train_action);
|
||||
u8 timer = Common_Get(train_timer);
|
||||
u32 start_timer = Common_Get(train_start_timer);
|
||||
f32 speed = Common_Get(train_speed);
|
||||
xyz_t pos = Common_Get(train_position);
|
||||
u8 day = Common_Get(time.rtc_time.day);
|
||||
|
||||
if (Common_Get(train_day) != day) {
|
||||
if (start_timer >= mTM_SECONDS_IN_DAY) {
|
||||
start_timer = start_timer - mTM_SECONDS_IN_DAY;
|
||||
}
|
||||
|
||||
Common_Set(train_day, day);
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case mTRC_ACTION_SPAWN_MOVING:
|
||||
{
|
||||
int block_x;
|
||||
int block_z;
|
||||
|
||||
speed = mTRC_FAST_SPEED;
|
||||
mFI_Wpos2BlockNum(&block_x, &block_z, pos);
|
||||
|
||||
if (block_x >= 2) {
|
||||
action = mTRC_ACTION_BEGIN_SLOWDOWN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case mTRC_ACTION_BEGIN_SLOWDOWN:
|
||||
{
|
||||
chase_f(&speed, mTRC_SLOW_SPEED, 0.01f);
|
||||
if (pos.x > 2165.0f) {
|
||||
action = mTRC_ACTION_BEGIN_STOP;
|
||||
speed = mTRC_SLOW_SPEED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case mTRC_ACTION_BEGIN_STOP:
|
||||
{
|
||||
chase_f(&speed, 0.0f, 0.005f);
|
||||
if (fabsf(speed) < 0.008f) {
|
||||
signal = TRUE;
|
||||
timer = 48;
|
||||
action = mTRC_ACTION_SIGNAL_STOPPED;
|
||||
state = 2;
|
||||
speed = 0.0f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case mTRC_ACTION_SIGNAL_STOPPED:
|
||||
{
|
||||
if (timer == 0) {
|
||||
action = mTRC_ACTION_WAIT_STOPPED;
|
||||
start_timer += 310;
|
||||
}
|
||||
else {
|
||||
timer--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case mTRC_ACTION_WAIT_STOPPED:
|
||||
{
|
||||
if (Common_Get(train_control_state) != Common_Get(train_last_control_state)) {
|
||||
Common_Set(train_control_state, Common_Get(train_last_control_state));
|
||||
signal = FALSE;
|
||||
Common_Set(train_signal, FALSE);
|
||||
}
|
||||
else {
|
||||
if (Common_Get(train_control_state) == 0 && mTRC_time_check()) {
|
||||
signal = FALSE;
|
||||
Common_Set(train_signal, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (signal == FALSE) {
|
||||
timer = 84;
|
||||
action = mTRC_ACTION_SIGNAL_STARTING;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case mTRC_ACTION_SIGNAL_STARTING:
|
||||
{
|
||||
if (timer == 0) {
|
||||
timer = 180;
|
||||
action = mTRC_ACTION_BEGIN_PULL_OUT;
|
||||
state = 3;
|
||||
}
|
||||
else {
|
||||
timer--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case mTRC_ACTION_BEGIN_PULL_OUT:
|
||||
{
|
||||
chase_f(&speed, mTRC_SLOW_SPEED, 0.00345f);
|
||||
|
||||
if (timer == 0) {
|
||||
action = mTRC_ACTION_SPEED_UP;
|
||||
}
|
||||
else {
|
||||
timer--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case mTRC_ACTION_SPEED_UP:
|
||||
{
|
||||
chase_f(&speed, mTRC_FAST_SPEED, 0.00345);
|
||||
if (pos.x > 4400.0f) {
|
||||
start_timer = mTRC_get_depart_time();
|
||||
action = mTRC_ACTION_NONE;
|
||||
Common_Set(train_flag, FALSE);
|
||||
state = 4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (action != mTRC_ACTION_NONE) {
|
||||
ACTOR* train_actor = Actor_info_fgName_search(&play->actor_info, TRAIN0, ACTOR_PART_ITEM);
|
||||
if (Common_Get(train_flag) == FALSE && train_actor == NULL) {
|
||||
Common_Set(train_flag, TRUE);
|
||||
}
|
||||
|
||||
pos.x += 0.5f * speed;
|
||||
mTRC_KishaStatusLevel(play, pos, speed);
|
||||
}
|
||||
|
||||
if (state >= 0) {
|
||||
mTRC_KishaStatusTrg(state);
|
||||
}
|
||||
|
||||
Common_Set(train_signal, signal);
|
||||
Common_Set(train_action, action);
|
||||
Common_Set(train_timer, timer);
|
||||
Common_Set(train_start_timer, start_timer);
|
||||
Common_Set(train_speed, speed);
|
||||
Common_Set(train_position, pos);
|
||||
}
|
||||
|
||||
static void mTRC_trainSet(GAME_PLAY* play) {
|
||||
ACTOR* train_actor;
|
||||
ACTOR* caboose_actor;
|
||||
xyz_t pos = Common_Get(train_position);
|
||||
xyz_t xz_pos;
|
||||
xyz_t xyz_pos;
|
||||
|
||||
if (Common_Get(field_type) != mFI_FIELDTYPE2_FG || !Common_Get(train_flag)) {
|
||||
return;
|
||||
}
|
||||
else if (Common_Get(clip).structure_clip != NULL) {
|
||||
f32 x = pos.x;
|
||||
xz_pos.x = pos.x;
|
||||
xz_pos.z = 740.0f;
|
||||
xz_pos.y = 0.0f;
|
||||
|
||||
if (aTRC_area_check(play, xz_pos)) {
|
||||
train_actor = Actor_info_fgName_search(&play->actor_info, TRAIN0, ACTOR_PART_ITEM);
|
||||
if (train_actor == NULL) {
|
||||
/* spawn train actor since it doesn't exist */
|
||||
train_actor = (*Common_Get(clip.structure_clip)->setup_actor_proc)(play, TRAIN0, -1, x, 740.0f);
|
||||
|
||||
/* for whatever reason, train actor didn't spawn, so exit */
|
||||
if (train_actor == NULL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
xyz_pos.x = xz_pos.x;
|
||||
xyz_pos.z = xz_pos.z;
|
||||
xyz_pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(xyz_pos, 0.0f);
|
||||
|
||||
xyz_t_move(&train_actor->world_position, &xyz_pos);
|
||||
}
|
||||
|
||||
x -= 250.0f;
|
||||
caboose_actor = Actor_info_fgName_search(&play->actor_info, TRAIN1, ACTOR_PART_ITEM);
|
||||
if (caboose_actor == NULL) {
|
||||
caboose_actor = (*Common_Get(clip.structure_clip)->setup_actor_proc)(play, TRAIN1, -1, x, 740.0f);
|
||||
if (caboose_actor == NULL) {
|
||||
Actor_delete(train_actor);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
xyz_pos.x = x;
|
||||
xyz_pos.z = 740.0f;
|
||||
xyz_pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(xyz_pos, 0.0f);
|
||||
|
||||
xyz_t_move(&caboose_actor->world_position, &xyz_pos);
|
||||
}
|
||||
|
||||
Common_Set(train_flag, FALSE);
|
||||
|
||||
train_actor->block_x = -1;
|
||||
train_actor->block_z = -1;
|
||||
train_actor->child_actor = caboose_actor;
|
||||
|
||||
caboose_actor->block_x = -1;
|
||||
caboose_actor->block_z = -1;
|
||||
caboose_actor->parent_actor = train_actor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern void mTRC_init() {
|
||||
Common_Set(train_start_timer, mTRC_get_depart_time());
|
||||
Common_Set(train_coming_flag, 0);
|
||||
Common_Set(train_exists_flag, FALSE);
|
||||
Common_Set(train_control_state, 0);
|
||||
Common_Set(train_last_control_state, 0);
|
||||
Common_Set(train_signal, FALSE);
|
||||
Common_Set(train_action, 0);
|
||||
Common_Set(train_timer, 0);
|
||||
Common_Set(train_speed, 0.0f);
|
||||
Common_Set(train_position, ZeroVec);
|
||||
Common_Set(train_approaching_flag, FALSE);
|
||||
Common_Set(train_flag, FALSE);
|
||||
}
|
||||
|
||||
extern void mTRC_move(GAME_PLAY* play) {
|
||||
PLAYER_ACTOR* player = get_player_actor_withoutCheck(play);
|
||||
int state;
|
||||
Common_Set(train_approaching_flag, FALSE);
|
||||
|
||||
if (!mTRC_go_process() || player == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
state = mTRC_schedule(play);
|
||||
mTRC_trainControl(play, state);
|
||||
mTRC_trainSet(play);
|
||||
}
|
||||
+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