Files
ac-decomp/rel/graph.c
T
2023-04-22 00:55:05 -04:00

289 lines
7.9 KiB
C

#include "graph.h"
#include "audio.h"
#include "dvderr.h"
#include "famicom_emu.h"
#include "first_game.h"
#include "game.h"
#include "irqmgr.h"
#include "libc64/malloc.h"
#include "libforest/emu64/emu64_wrapper.h"
#include "libjsys/jsyswrapper.h"
#include "libu64/debug.h"
#include "libultra/libultra.h"
#include "m_bgm.h"
#include "m_debug.h"
#include "m_game_dlftbls.h"
#include "m_play.h"
#include "m_prenmi.h"
#include "m_select.h"
#include "m_trademark.h"
#include "m_vibctl.h"
#include "player_select.h"
#include "save_menu.h"
#include "second_game.h"
#include "sys_dynamic.h"
#include "sys_ucode.h"
#include "zurumode.h"
GRAPH graph_class;
static int skip_frame; // TODO: this is actually declared in graph_main
u8 SoftResetEnable;
static int frame; // TODO: this is actually declared in graph_task_set00
#define CONSTRUCT_THA_GA(tha_ga, name, name2) \
(THA_GA_ct((tha_ga), sys_dynamic.##name, ##name2##_SIZE * sizeof(Gfx)))
static void graph_setup_double_buffer(GRAPH* this) {
bzero(&sys_dynamic, sizeof(dynamic_t));
sys_dynamic.start_magic = SYSDYNAMIC_START_MAGIC;
sys_dynamic.end_magic = SYSDYNAMIC_END_MAGIC;
CONSTRUCT_THA_GA(&this->bg_opaque_thaga, new0, NEW0);
CONSTRUCT_THA_GA(&this->bg_translucent_thaga, new1, NEW1);
CONSTRUCT_THA_GA(&this->polygon_opaque_thaga, poly_opa, POLY_OPA);
CONSTRUCT_THA_GA(&this->polygon_translucent_thaga, poly_xlu, POLY_XLU);
CONSTRUCT_THA_GA(&this->overlay_thaga, overlay, OVERLAY);
CONSTRUCT_THA_GA(&this->work_thaga, work, WORK);
CONSTRUCT_THA_GA(&this->font_thaga, font, FONT);
CONSTRUCT_THA_GA(&this->shadow_thaga, shadow, SHADOW);
CONSTRUCT_THA_GA(&this->light_thaga, light, LIGHT);
this->Gfx_list10 = sys_dynamic.new0;
this->Gfx_list11 = sys_dynamic.new1;
this->Gfx_list00 = sys_dynamic.poly_opa;
this->Gfx_list01 = sys_dynamic.poly_xlu;
this->Gfx_list04 = sys_dynamic.overlay;
this->Gfx_list05 = sys_dynamic.work;
this->Gfx_list07 = sys_dynamic.font;
this->Gfx_list08 = sys_dynamic.shadow;
this->Gfx_list09 = sys_dynamic.light;
this->gfxsave = NULL;
}
#define ARE_INIT_PROCS_EQUAL(proc0, proc1) \
(((void (*)(GAME*))proc0) == ((void (*)(GAME*))proc1))
static DLFTBL_GAME* game_get_next_game_dlftbl(GAME* game) {
void (*next_game_init_proc)(GAME*) = game_get_next_game_init(game);
if (ARE_INIT_PROCS_EQUAL(next_game_init_proc, first_game_init)) {
return &game_dlftbls[0];
} else if (ARE_INIT_PROCS_EQUAL(next_game_init_proc, select_init)) {
return &game_dlftbls[1];
} else if (ARE_INIT_PROCS_EQUAL(next_game_init_proc, play_init)) {
return &game_dlftbls[2];
} else if (ARE_INIT_PROCS_EQUAL(next_game_init_proc, second_game_init)) {
return &game_dlftbls[3];
} else if (ARE_INIT_PROCS_EQUAL(next_game_init_proc, trademark_init)) {
return &game_dlftbls[5];
} else if (ARE_INIT_PROCS_EQUAL(next_game_init_proc, player_select_init)) {
return &game_dlftbls[6];
} else if (ARE_INIT_PROCS_EQUAL(next_game_init_proc, save_menu_init)) {
return &game_dlftbls[7];
} else if (ARE_INIT_PROCS_EQUAL(next_game_init_proc, famicom_emu_init)) {
return &game_dlftbls[8];
} else if (ARE_INIT_PROCS_EQUAL(next_game_init_proc, prenmi_init)) {
return &game_dlftbls[9];
}
return NULL;
}
extern void graph_ct(GRAPH* this) {
bzero(this, sizeof(GRAPH));
this->frame_counter = 0;
this->cfb_bank = 0;
SETREG(SREG, 33, GETREG(SREG, 33) & ~2);
SETREG(SREG, 33, GETREG(SREG, 33) & ~1);
zurumode_init();
GRAPH_SET_DOING_POINT(this, CT);
}
extern void graph_dt(GRAPH* this) {
GRAPH_SET_DOING_POINT(this, DT);
zurumode_cleanup();
}
static void graph_task_set00(GRAPH* this) {
ucode_info ucode[2];
GRAPH_SET_DOING_POINT(this, WAIT_TASK);
GRAPH_SET_DOING_POINT(this, WAIT_TASK_FINISHED);
if (ResetStatus < IRQ_RESET_DELAY) {
this->last_dl = this->Gfx_list05;
if (this->taskEndCallback != NULL) {
this->taskEndCallback(this, this->taskEndData);
}
if (ResetStatus < IRQ_RESET_DELAY) {
ucode[0].type = UCODE_TYPE_POLY_TEXT;
ucode[1].type = UCODE_TYPE_SPRITE_TEXT;
ucode[0].ucode_p = ucode_GetPolyTextStart();
ucode[1].ucode_p = ucode_GetSpriteTextStart();
JW_BeginFrame();
emu64_init();
emu64_set_ucode_info(2, ucode);
emu64_set_first_ucode(ucode[0].ucode_p);
emu64_taskstart(this->Gfx_list05); /* work data */
emu64_cleanup();
JW_EndFrame();
frame++;
}
}
}
static int graph_draw_finish(GRAPH* this) {
int err;
OPEN_DISP(this);
gSPBranchList(NOW_WORK_DISP++, this->Gfx_list10);
gSPBranchList(NOW_BG_OPA_DISP++, this->Gfx_list08);
gSPBranchList(NOW_SHADOW_DISP++, this->Gfx_list11);
gSPBranchList(NOW_BG_XLU_DISP++, this->Gfx_list00);
gSPBranchList(NOW_POLY_OPA_DISP++, this->Gfx_list01);
gSPBranchList(NOW_POLY_XLU_DISP++, this->Gfx_list09);
gSPBranchList(NOW_LIGHT_DISP++, this->Gfx_list07);
gSPBranchList(NOW_FONT_DISP++, this->Gfx_list04);
gDPPipeSync(NOW_OVERLAY_DISP++);
gDPFullSync(NOW_OVERLAY_DISP++);
gSPEndDisplayList(NOW_OVERLAY_DISP++);
CLOSE_DISP(this);
err = FALSE;
SYSDYNAMIC_OPEN();
if (!SYSDYNAMIC_CHECK_START()) {
_dbg_hungup(__FILE__, 417);
}
if (!SYSDYNAMIC_CHECK_END()) {
err = TRUE;
_dbg_hungup(__FILE__, 425);
}
SYSDYNAMIC_CLOSE();
if (THA_GA_isCrash(&this->polygon_opaque_thaga)) {
err = TRUE;
}
if (THA_GA_isCrash(&this->polygon_translucent_thaga)) {
err = TRUE;
}
if (THA_GA_isCrash(&this->overlay_thaga)) {
err = TRUE;
}
if (THA_GA_isCrash(&this->font_thaga)) {
err = TRUE;
}
if (THA_GA_isCrash(&this->shadow_thaga)) {
err = TRUE;
}
if (THA_GA_isCrash(&this->light_thaga)) {
err = TRUE;
}
if (THA_GA_isCrash(&this->bg_opaque_thaga)) {
err = TRUE;
}
if (THA_GA_isCrash(&this->bg_translucent_thaga)) {
err = TRUE;
}
return err;
}
static void do_soft_reset(GAME* game) {
SoftResetEnable = FALSE;
mBGM_reset();
mVibctl_reset();
sAdo_SoftReset();
ResetTime = osGetTime();
ResetStatus = IRQ_RESET_PRENMI;
}
static void reset_check(GRAPH* this, GAME* game) {
if (SoftResetEnable && osShutdown) {
do_soft_reset(game);
}
}
static void graph_main(GRAPH* this, GAME* game) {
game->disable_prenmi = FALSE;
graph_setup_double_buffer(this);
game_get_controller(game);
game->disable_display = FALSE;
GRAPH_SET_DOING_POINT(this, GAME_MAIN);
game_main(game);
GRAPH_SET_DOING_POINT(this, GAME_MAIN_FINISHED);
if (ResetStatus < IRQ_RESET_DELAY) {
if (skip_frame < GETREG(SREG, 3)) {
skip_frame++;
this->frame_counter++;
} else if (game->disable_display == FALSE) {
skip_frame = 0;
if (graph_draw_finish(this) == FALSE) {
GRAPH_SET_DOING_POINT(this, TASK_SET);
graph_task_set00(this);
GRAPH_SET_DOING_POINT(this, TASK_SET_FINISHED);
this->frame_counter++;
if ((GETREG(SREG, 33) & 1) != 0) {
SETREG(SREG, 33, GETREG(SREG, 33) & ~1);
}
}
}
}
if (GETREG(SREG, 20) < 2) {
GRAPH_SET_DOING_POINT(this, AUDIO);
sAdo_GameFrame();
GRAPH_SET_DOING_POINT(this, AUDIO_FINISHED);
}
reset_check(this, game);
if (ResetStatus == IRQ_RESET_PRENMI && game->disable_prenmi == FALSE) {
GAME_GOTO_NEXT(game, prenmi, PRENMI);
}
}
extern void graph_proc(void* arg) {
GRAPH* __graph = &graph_class;
DLFTBL_GAME* dlftbl = &game_dlftbls[0];
graph_ct(&graph_class);
while (dlftbl != NULL) {
size_t size = dlftbl->alloc_size;
GAME* game = (GAME*)malloc(size);
game_class_p = game;
bzero(game, size);
GRAPH_SET_DOING_POINT(__graph, GAME_CT);
game_ct(game, dlftbl->init, __graph);
emu64_refresh();
GRAPH_SET_DOING_POINT(__graph, GAME_CT_FINISHED);
while (game_is_doing(game)) {
if (!dvderr_draw()) {
graph_main(__graph, game);
}
}
dlftbl = game_get_next_game_dlftbl(game);
GRAPH_SET_DOING_POINT(__graph, GAME_18);
GRAPH_SET_DOING_POINT(__graph, GAME_DT);
game_dt(game);
GRAPH_SET_DOING_POINT(__graph, GAME_DT_FINISHED);
free(game);
game_class_p = NULL;
}
graph_dt(__graph);
}