Files
ac-decomp/src/actor/ac_train_window.c
T

539 lines
16 KiB
C

#include "ac_train_window.h"
#include "m_common_data.h"
#include "m_debug.h"
#include "m_name_table.h"
#include "evw_anime.h"
#include "m_rcp.h"
#include "m_play.h"
#include "sys_matrix.h"
// clang-format off
static u16 aTrainWindow_tree_pal_table[15][16] ATTRIBUTE_ALIGN(32) = {
{
0x0724,0xA443,
0xBCA4,0xDD25,
0xF5E7,0xF209,
0xFECD,0x0545,
0x9885,0xA0C5,
0xAD05,0xBD66,
0xCDE8,0xD2FA,
0xE77C,0xF3BE
},
{
0x0724,0xA443,
0xBCA4,0xDD25,
0xF5E7,0xF209,
0xFECD,0x0655,
0x98C5,0xA105,
0xB165,0xC1E6,
0xD268,0xD2FA,
0xE77C,0xF3BE
},
{
0x0724,0xA443,
0xBCA4,0xDD25,
0xF5E7,0xF209,
0xFECD,0x0464,
0x90C3,0x9504,
0xA184,0xAA05,
0xB287,0xD2FA,
0xE77C,0xF3BE
},
{
0x0724,0xA443,
0xBCA4,0xDD25,
0xF5E7,0xF209,
0xFECD,0x0164,
0x80E5,0x8145,
0x89A4,0x9A60,
0xB300,0xD380,
0xEFE8,0x8000
},
{
0x0724,0xA443,
0xBCA4,0xDD25,
0xF5E7,0xF209,
0xFECD,0x0C37,
0xB086,0xC8A7,
0xE0C7,0xF109,
0xF98C,0xFE10,
0xFF18,0x8000
},
{
0x0724,0xA443,
0xBCA4,0xDD25,
0xF5E7,0xF209,
0xFECD,0x0066,
0x80C9,0x8127,
0x8186,0x8202,
0x82C1,0x9380,
0xCBE8,0x8000
},
{
0x0724,0xA443,
0xBCA4,0xDD25,
0xF5E7,0xF209,
0xFECD,0x0058,
0x80C9,0x80E8,
0x8148,0x81C8,
0x8268,0x9326,
0xC3EB,0x8000
},
{
0x0724,0xA443,
0xBCA4,0xDD25,
0xF5E7,0xF209,
0xFECD,0x0353,
0x8CC2,0x9102,
0x9963,0xA5C4,
0xB242,0xC6E4,
0xDB88,0x8000
},
{
0x0724,0xA443,
0xBCA4,0xDD25,
0xF5E7,0xF209,
0xFECD,0x0564,
0x90C5,0x9924,
0xA984,0xBA03,
0xD2A3,0xE304,
0xEF6A,0x8000
},
{
0x0724,0xA443,
0xBCA4,0xDD25,
0xF5E7,0xF209,
0xFECD,0x0842,
0xA463,0xB4A2,
0xC502,0xD961,
0xE9E1,0xF682,
0xFF26,0x8000
},
{
0x0724,0xA443,
0xBCA4,0xDD25,
0xF5E7,0xF209,
0xFECD,0x0814,
0xB024,0xC044,
0xCC85,0xE0C6,
0xF128,0xFE0B,
0xFEEB,0x8000
},
{
0x0724,0xA443,
0xBCA4,0xDD25,
0xF5E7,0xF209,
0xFECD,0x0734,
0xA484,0xAC83,
0xBCC4,0xD503,
0xE985,0xF629,
0xFF0E,0x8000
},
{
0x0724,0xA443,
0xBCA4,0xDD25,
0xF5E7,0xF209,
0xFECD,0x0635,
0xA085,0xA8C5,
0xB505,0xC566,
0xD5E8,0xEE8A,
0xFF2C,0x8000
},
{
0x0724,0xA443,
0xBCA4,0xDD25,
0xF5E7,0xF209,
0xFECD,0x0545,
0x9885,0xA0C5,
0xAD05,0xBD66,
0xCDE8,0xD2FA,
0xE77C,0xF3BE
},
{
0x0724,0xA443,
0xBCA4,0xDD25,
0xF5E7,0xF209,
0xFECD,0x0545,
0x9885,0xA0C5,
0xAD05,0xBD66,
0xCDE8,0xD2FA,
0xE77C,0xF3BE
},
};
// clang-format on
static EVW_ANIME_SCROLL aTrainWindow_out_cloud = { 0, -2, 64, 64 };
static EVW_ANIME_DATA aTrainWindow_evw_anime_data = { -2, EVW_ANIME_TYPE_SCROLL1, &aTrainWindow_out_cloud };
static void Train_Window_Actor_ct(ACTOR*, GAME*);
static void Train_Window_Actor_dt(ACTOR*, GAME*);
static void Train_Window_Actor_move(ACTOR*, GAME*);
static void Train_Window_Actor_draw(ACTOR*, GAME*);
ACTOR_PROFILE Train_Window_Profile = {
mAc_PROFILE_TRAIN_WINDOW,
ACTOR_PART_ITEM,
ACTOR_STATE_NO_DRAW_WHILE_CULLED | ACTOR_STATE_NO_MOVE_WHILE_CULLED,
ETC_TRAIN_WINDOW,
ACTOR_OBJ_BANK_TRAINWINDOW,
sizeof(TRAIN_WINDOW_ACTOR),
&Train_Window_Actor_ct,
&Train_Window_Actor_dt,
&Train_Window_Actor_move,
&Train_Window_Actor_draw,
NULL,
};
static int aTrainWindow_NoDraw(ACTOR*, GAME*);
static int aTrainWindow_DrawGoneOutTunnel(ACTOR*, GAME*);
static int aTrainWindow_DrawInTunnel(ACTOR*, GAME*);
extern Gfx rom_train_out_tunnel_model[];
extern Gfx rom_train_out_bgsky_model[];
extern Gfx rom_train_out_bgcloud_modelT[];
extern Gfx rom_train_out_bgtree_modelT[];
extern Gfx rom_train_out_shineglass_modelT[];
static int aTrainWindow_GetTreePalletIdx() {
static u8 till_data[15][2] = {
{ 0x02, 0x03 }, { 0x02, 0x11 }, { 0x02, 0x18 }, { 0x04, 0x03 }, { 0x04, 0x08 },
{ 0x07, 0x16 }, { 0x09, 0x0F }, { 0x0A, 0x05 }, { 0x0A, 0x17 }, { 0x0B, 0x07 },
{ 0x0B, 0x0E }, { 0x0B, 0x1C }, { 0x0C, 0x0A }, { 0x0C, 0x11 }, { 0x0C, 0x1F },
};
int i;
lbRTC_month_t month = Common_Get(time.rtc_time.month);
lbRTC_day_t day = Common_Get(time.rtc_time.day);
for (i = 0; i < 15; i++) {
if (month < till_data[i][0]) {
return i;
}
if (month == till_data[i][0] && day <= till_data[i][1]) {
return i;
}
}
return 0;
}
static void Train_Window_Actor_ct(ACTOR* actor, GAME* game) {
TRAIN_WINDOW_ACTOR* window = (TRAIN_WINDOW_ACTOR*)actor;
switch (Save_Get(scene_no)) {
case SCENE_START_DEMO:
case SCENE_START_DEMO3:
window->draw_type = &aTrainWindow_NoDraw;
window->Single_Scrollx = 0;
window->Single_Scrolly = 0;
window->Two_Scrollx1 = 0;
window->Two_Scrolly1 = 0;
window->Two_Scrollx2 = 0;
window->Two_Scrolly2 = 0;
window->scroll_speed = 0.07f;
break;
case SCENE_START_DEMO2:
window->draw_type = &aTrainWindow_DrawGoneOutTunnel;
window->Single_Scrollx = 1000;
window->Single_Scrolly = 0;
window->Two_Scrollx1 = 1000;
window->Two_Scrolly1 = 0;
window->Two_Scrollx2 = 0;
window->Two_Scrolly2 = 0;
window->scroll_speed = 1.0f;
break;
}
window->pallete_id = aTrainWindow_GetTreePalletIdx();
window->current_pallete = aTrainWindow_tree_pal_table[window->pallete_id];
window->TreeScrollx = 500;
window->TreeScrolly = 0;
window->pos.x = 0;
window->pos.y = 0;
window->pos.z = 0;
window->xlu_alpha = 254.0f;
}
static void Train_Window_Actor_dt(ACTOR* actor, GAME* game) {
}
static u8 aTW_GetNowAlpha() {
if ((Common_Get(time.now_sec) >= 14400) && (Common_Get(time.now_sec) < 72000)) {
if (Common_Get(time.now_sec) < 43200) {
return 255.0f * ((f32)(Common_Get(time.now_sec) - 14400) / 28800.0f);
}
return 255.0f * (1.0f - ((f32)(Common_Get(time.now_sec) - 43200) / 28800.0f));
} else if (Common_Get(time.now_sec) < 14400) {
return 200.0f * (1.0f - (0.5f + ((f32)Common_Get(time.now_sec) / 28800.0f)));
} else {
return 200.0f * ((f32)Common_Get(time.now_sec - 72000) / 28800.0f);
}
}
static void Train_Window_Actor_move(ACTOR* actor, GAME* game) {
TRAIN_WINDOW_ACTOR* window = (TRAIN_WINDOW_ACTOR*)actor;
f32 alpha;
window->TreeScrollx += 5;
add_calc(&window->xlu_alpha, aTW_GetNowAlpha(), window->scroll_speed, 50.0f, 1.0f);
if ((Common_Get(time.now_sec) < 14400) || (Common_Get(time.now_sec) >= 72000)) {
alpha = 0.0f;
} else if (Common_Get(time.now_sec) >= 43200) {
alpha = 160.0f + (-160.0f * ((f32)(Common_Get(time.now_sec) - 43200) / 28800.0f));
} else {
alpha = 160.0f * ((f32)(Common_Get(time.now_sec) - 14400) / 28800.0f);
}
add_calc(&window->lod_factor, alpha, 0.3f, 50.0f, 1.0f);
}
static int aTrainWindow_OperateScrollLimit(int a, int b, int c) {
b >>= 1;
if (b != 0) {
if (b > 0) {
if (a + b > c) {
return c;
}
return a + b;
}
if (b >= 0) {
return a;
}
if (a + b < c) {
return c;
}
return a + b;
}
return a;
}
static Gfx* aTrainWindow_TileScroll(u32* x, u32* y, int xamt, int yamt, int xend, int yend, int width, int height,
GRAPH** graph) {
*x = aTrainWindow_OperateScrollLimit(*x, xamt, xend);
*y = aTrainWindow_OperateScrollLimit(*y, yamt, yend);
return tex_scroll2(*graph, *x, *y, width, height);
}
static Gfx* aTrainWindow_TileScroll2(u32* x1, u32* y1, int x1amt, int y1amt, int x1end, int y1end, int width1,
int height1, u32* x2, u32* y2, int x2amt, int y2amt, int x2end, int y2end,
int width2, int height2, GRAPH** graph) {
*x1 = aTrainWindow_OperateScrollLimit(*x1, x1amt, x1end);
*y1 = aTrainWindow_OperateScrollLimit(*y1, y1amt, y1end);
*x2 = aTrainWindow_OperateScrollLimit(*x2, x2amt, x2end);
*y2 = aTrainWindow_OperateScrollLimit(*y2, y2amt, y2end);
return two_tex_scroll(*graph, 0, *x1, *y1, width1, height1, 1, *x2, *y2, width2, height2);
}
static int aTrainWindow_DrawGoneOutTunnel(ACTOR* actor, GAME* game) {
TRAIN_WINDOW_ACTOR* window = (TRAIN_WINDOW_ACTOR*)actor;
GRAPH** graph = &game->graph;
Gfx* ssc;
Gfx* tsc;
ssc = aTrainWindow_TileScroll(&window->Single_Scrollx, &window->Single_Scrolly, 0, 0, 1000, 0, 64, 32, graph);
tsc = aTrainWindow_TileScroll2(&window->Two_Scrollx1, &window->Two_Scrolly1, 0, 0, 1000, 0, 64, 8,
&window->Two_Scrollx2, &window->Two_Scrolly2, 0, 0, 0, 0, 16, 16, graph);
if ((ssc == NULL) || (tsc == NULL)) {
return 0;
} else {
OPEN_DISP(*graph);
gSPSegment(NOW_POLY_OPA_DISP++, 11, ssc);
gSPSegment(NOW_POLY_XLU_DISP++, 11, ssc);
gSPSegment(NOW_POLY_OPA_DISP++, 12, tsc);
gSPSegment(NOW_POLY_XLU_DISP++, 12, tsc);
CLOSE_DISP(*graph);
return 1;
}
}
static int aTrainWindow_DrawGoingOutTunnel(ACTOR* actor, GAME* game) {
TRAIN_WINDOW_ACTOR* window = (TRAIN_WINDOW_ACTOR*)actor;
Gfx* tsc;
Gfx* ssc;
GRAPH** graph = &game->graph;
ssc = aTrainWindow_TileScroll(&window->Single_Scrollx, &window->Single_Scrolly, 30, 0, 1000, 0, 64, 32, graph);
tsc = aTrainWindow_TileScroll2(&window->Two_Scrollx1, &window->Two_Scrolly1, 30, 0, 1000, 0, 64, 8,
&window->Two_Scrollx2, &window->Two_Scrolly2, 0, 0, 0, 0, 16, 16, graph);
if ((ssc == NULL) || (tsc == NULL)) {
return 0;
} else {
OPEN_DISP(*graph);
gSPSegment(NOW_POLY_OPA_DISP++, 11, ssc);
gSPSegment(NOW_POLY_XLU_DISP++, 11, ssc);
gSPSegment(NOW_POLY_OPA_DISP++, 12, tsc);
gSPSegment(NOW_POLY_XLU_DISP++, 12, tsc);
CLOSE_DISP(*graph);
if (((int)window->Single_Scrollx == 1000) && ((int)window->Two_Scrollx1 == 1000)) {
window->draw_type = aTrainWindow_DrawGoneOutTunnel;
window->pallete_id = aTrainWindow_GetTreePalletIdx();
window->current_pallete = aTrainWindow_tree_pal_table[window->pallete_id];
}
return 1;
}
}
static int aTrainWindow_NoDraw(ACTOR* actor, GAME* game) {
TRAIN_WINDOW_ACTOR* window = (TRAIN_WINDOW_ACTOR*)actor;
window->draw_type = aTrainWindow_DrawInTunnel;
return 0;
}
static int aTrainWindow_DrawInTunnel(ACTOR* actor, GAME* game) {
TRAIN_WINDOW_ACTOR* window = (TRAIN_WINDOW_ACTOR*)actor;
Gfx* tsc;
Gfx* ssc;
GRAPH** graph = &game->graph;
ssc = aTrainWindow_TileScroll(&window->Single_Scrollx, &window->Single_Scrolly, 0, 0, 1000, 0, 64, 32, graph);
tsc = aTrainWindow_TileScroll2(&window->Two_Scrollx1, &window->Two_Scrolly1, 0, 0, 1000, 0, 64, 8,
&window->Two_Scrollx2, &window->Two_Scrolly2, 0, 0, 0, 0, 16, 16, graph);
if ((ssc == NULL) || (tsc == NULL)) {
return 0;
} else {
OPEN_DISP(*graph);
gSPSegment(NOW_POLY_OPA_DISP++, 11, ssc);
gSPSegment(NOW_POLY_XLU_DISP++, 11, ssc);
gSPSegment(NOW_POLY_OPA_DISP++, 12, tsc);
gSPSegment(NOW_POLY_XLU_DISP++, 12, tsc);
CLOSE_DISP(*graph);
if (Common_Get(sunlight_flag) != 0) {
window->pallete_id = aTrainWindow_GetTreePalletIdx();
window->current_pallete = aTrainWindow_tree_pal_table[window->pallete_id];
window->draw_type = aTrainWindow_DrawGoingOutTunnel;
}
return 1;
}
}
static void aTrainWindow_SetLightPrimColorDetail(GAME* game, u32 r, u32 g, u32 b, int l, int poly_a, int xlu_a) {
GAME_PLAY* play = (GAME_PLAY*)game;
int i;
int current_color;
u8 color[3];
GRAPH* graph;
for (i = 0; i < 3; i++) {
current_color = play->global_light.ambientColor[i] + play->kankyo.base_light.sun_color[i];
switch (i) {
case 0:
current_color += r;
break;
case 1:
current_color += g;
break;
case 2:
current_color += b;
break;
}
if (current_color < 0) {
current_color = 0;
} else if (current_color >= 256) {
current_color = 255;
}
color[i] = current_color;
}
if (l < 0) {
l = 0;
} else if (l > 255) {
l = 255;
}
if (poly_a < 0) {
poly_a = 0;
} else if (poly_a > 255) {
poly_a = 255;
}
if (xlu_a < 0) {
xlu_a = 0;
} else if (xlu_a > 255) {
xlu_a = 255;
}
graph = play->game.graph;
OPEN_DISP(graph);
gDPSetPrimColor(NOW_POLY_OPA_DISP++, 0, l, color[0], color[1], color[2], poly_a);
gDPSetPrimColor(NOW_POLY_XLU_DISP++, 0, l, color[0], color[1], color[2], xlu_a);
CLOSE_DISP(graph);
}
static void aTrainWindow_SetTreeTextureScroll(ACTOR* actor, GAME* game) {
TRAIN_WINDOW_ACTOR* window = (TRAIN_WINDOW_ACTOR*)actor;
Gfx* tree;
GRAPH** graph = &game->graph;
tree = tex_scroll2(*graph, window->TreeScrollx, window->TreeScrolly, 128, 32);
OPEN_DISP(*graph);
gSPSegment(NOW_POLY_OPA_DISP++, 8, tree);
gSPSegment(NOW_POLY_XLU_DISP++, 8, tree);
CLOSE_DISP(*graph);
}
static void Train_Window_Actor_draw(ACTOR* actor, GAME* game) {
GAME_PLAY* play = (GAME_PLAY*)game;
TRAIN_WINDOW_ACTOR* window = (TRAIN_WINDOW_ACTOR*)actor;
GRAPH* graph = game->graph;
Matrix_translate(0.0f, 0.0f, 0.0f, MTX_LOAD);
Matrix_scale(0.05f, 0.05f, 0.05f, MTX_MULT);
OPEN_DISP(graph);
gSPMatrix(NOW_POLY_OPA_DISP++, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPMatrix(NOW_POLY_XLU_DISP++, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
_texture_z_light_fog_prim(game->graph);
_texture_z_light_fog_prim_xlu(game->graph);
if (window->draw_type(actor, game) != 0) {
aTrainWindow_SetLightPrimColorDetail(game, 0, 0, 0, 127, 255, (u8)window->xlu_alpha);
gSPSegment(NOW_POLY_XLU_DISP++, 10, window->current_pallete);
Evw_Anime_Set(play, &aTrainWindow_evw_anime_data);
aTrainWindow_SetLightPrimColorDetail(game, 0, 0, 0, 43, 255, window->xlu_alpha);
gSPDisplayList(NOW_POLY_OPA_DISP++, rom_train_out_tunnel_model);
aTrainWindow_SetLightPrimColorDetail(game, 0, 0, 0, 127, 255, window->xlu_alpha);
gSPDisplayList(NOW_POLY_OPA_DISP++, rom_train_out_bgsky_model);
aTrainWindow_SetLightPrimColorDetail(game, 0, 0, 0, 127, 255, window->xlu_alpha);
gSPDisplayList(NOW_POLY_XLU_DISP++, rom_train_out_bgcloud_modelT);
aTrainWindow_SetTreeTextureScroll(actor, game);
aTrainWindow_SetLightPrimColorDetail(
game, GETREG(CRV, CRV_DEBUG_RED_VALUE) - 80, GETREG(CRV, CRV_DEBUG_GREEN_VALUE) - 70,
GETREG(CRV, CRV_DEBUG_BLUE_VALUE) - 160, GETREG(CRV, CRV_DEBUG_LOD_VALUE) + 27, 255, window->xlu_alpha);
gSPDisplayList(NOW_POLY_XLU_DISP++, rom_train_out_bgtree_modelT);
aTrainWindow_SetLightPrimColorDetail(game, 0, 0, 0, window->lod_factor, 255, window->xlu_alpha);
gSPDisplayList(NOW_POLY_XLU_DISP++, rom_train_out_shineglass_modelT);
}
CLOSE_DISP(graph);
}