ac-decomp/src/famicom_emu.c

208 lines
5.3 KiB
C

#include "famicom_emu.h"
#include "Famicom/famicomPriv.h"
#include "_mem.h"
#include "dolphin/gx.h"
#include "jsyswrap.h"
#include "libc64/sprintf.h"
#include "libjsys/jsyswrapper.h"
#include "m_common_data.h"
#include "m_debug.h"
#include "m_malloc.h"
#include "m_scene.h"
static int famicom_done = FALSE;
static int famicom_done_countdown = 0;
static void* freeXfbBase = NULL;
static u32 freeXfbSize = 0;
static void my_alloc_init(GAME* game, void* start, size_t size) {
u32 freebytes;
u32 alloc;
u32 aligned;
u32 tsize;
freebytes = game_getFreeBytes(game);
alloc = (u32)THA_alloc16(&game->tha, freebytes);
aligned = ALIGN_NEXT(alloc, 16);
tsize = aligned - alloc;
zelda_InitArena((void*)aligned, freebytes - tsize);
if ((start != NULL) && (size != 0)) {
zelda_AddBlockArena(start, size);
}
}
static void my_alloc_cleanup() {
zelda_CleanupArena();
}
static int my_zelda_getmemblocksize(void* ptr) {
return zelda_GetMemBlockSize(ptr);
}
static int my_zelda_gettotalfreesize() {
return zelda_GetTotalFreeSize();
}
static void* my_zelda_malloc_align(size_t size, u32 align) {
void* aligned = zelda_malloc_align(size, align);
if (aligned != NULL) {
memset(aligned, 0xFF, size);
}
return aligned;
}
static void my_zelda_free(void* ptr) {
zelda_free(ptr);
}
Famicom_MallocInfo my_malloc_func = {
my_zelda_malloc_align,
my_zelda_free,
my_zelda_getmemblocksize,
my_zelda_gettotalfreesize,
};
extern void famicom_emu_main(GAME* famicom) {
int padid;
pad_t* current_pad;
u32 combo;
if (!famicom_done) {
if (famicom_rom_load_check() < 0) {
Common_Set(my_room_message_control_flags, Common_Get(my_room_message_control_flags) | 1);
famicom_done = TRUE;
famicom_done_countdown = 0;
} else {
for (padid = 0; padid < 4; padid++) {
current_pad = &gamePT->pads[padid];
combo = current_pad->now.button | current_pad->on.button;
if (combo == (BUTTON_L | BUTTON_R | BUTTON_Z) || combo == (BUTTON_L | BUTTON_R | BUTTON_X | BUTTON_Y)) {
famicom_done = TRUE;
famicom_done_countdown = 60;
JC_JFWDisplay_startFadeOut(JC_JFWDisplay_getManager(), famicom_done_countdown);
break;
}
}
}
}
if (famicom_done) {
if (famicom_done_countdown == 0) {
return_emu_game(famicom);
} else {
famicom_done_countdown--;
}
}
JW_BeginFrame();
famicom->disable_display = 1;
if (!famicom_done) {
famicom_1frame();
} else {
static GXColor black_color = { 0, 0, 0, 0 };
void* manager = JC_JFWDisplay_getManager();
JC_JFWDisplay_clearEfb(manager, black_color);
}
JW_EndFrame();
}
extern void famicom_emu_init(GAME* game) {
int rom_id;
u8 player;
int debug;
void* manager;
const GXRenderModeObj* render;
famicom_done = FALSE;
famicom_done_countdown = 0;
game_resize_hyral(game, 0);
Common_Set(famicom_287F9, 0);
rom_id = Common_Get(current_famicom_rom);
player = Common_Get(player_no);
save_game_image = (GETREG(HREG, 4) == 1);
debug = GETREG(HREG, 3);
if ((rom_id > 0) && (debug != 0)) {
rom_id = debug > 0 ? debug : 0;
}
game->exec = famicom_emu_main;
game->cleanup = famicom_emu_cleanup;
while (sAdo_SubGameOK() == FALSE) {
VIWaitForRetrace();
sAdo_GameFrame();
}
manager = JC_JFWDisplay_getManager();
render = JC_JFWDisplay_getRenderMode(manager);
freeXfbBase = JC_JFWDisplay_changeToSingleXfb(manager, 1);
freeXfbSize = render->fbWidth * render->xfbHeight * sizeof(u16);
my_alloc_init(game, freeXfbBase, freeXfbSize);
if (famicom_init(rom_id, &my_malloc_func, player) != 0) {
Common_Set(my_room_message_control_flags, Common_Get(my_room_message_control_flags) | 1);
return_emu_game(game);
}
}
extern void famicom_emu_cleanup(GAME* game) {
JC_JFWDisplay_startFadeIn(JC_JFWDisplay_getManager(), 1);
if (famicom_cleanup() != 0) {
Common_Set(my_room_message_control_flags, Common_Get(my_room_message_control_flags) | 2);
}
my_alloc_cleanup();
if (freeXfbBase != NULL) {
JC_JFWDisplay_changeToDoubleXfb(JC_JFWDisplay_getManager());
freeXfbBase = NULL;
freeXfbSize = 0;
}
sAdo_SubGameEnd();
}
extern void* famicom_gba_getImage(u32 rom_id, size_t* size) {
static char* names[] = {
"cluclu", "usa_balloon", "donkey", "usa_jr_math", "pinball", "tennis", "usa_golf",
NULL, "usa_baseball", NULL, "usa_donkey3", "donkeyjr", "soccer", "exbike",
NULL, "usa_icecl", "mario", "smario", NULL,
};
char buf[256];
void* resource;
char* rom;
if (rom_id > 19) {
return 0;
}
rom = names[(rom_id == 0) ? 0 : rom_id - 1];
if (rom == NULL) {
return 0;
} else {
sprintf(buf, "/FAMICOM/GBA/jb_%s.bin.szs", rom);
resource = JC__JKRGetResource(buf);
if ((resource != NULL) && (size != NULL)) {
*size = JC__JKRGetMemBlockSize(0, resource);
}
}
return resource;
}
extern void famicom_gba_removeImage(void* p) {
JC__JKRRemoveResource(p);
}