#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); }