mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-23 06:34:18 -04:00
289 lines
7.9 KiB
C
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 "jsyswrap.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);
|
|
}
|