/* * File: z_title.c * Overlay: ovl_title * Description: Displays the Nintendo Logo */ #define NORMAL_GAMEPLAY #include "global.h" #include "alloca.h" #include "textures/nintendo_rogo_static/nintendo_rogo_static.h" #include #include "GameVersions.h" #include const char* GetGameVersionString(); char* quote; void Title_PrintBuildInfo(Gfx** gfxp) { Gfx* g; //GfxPrint* printer; GfxPrint printer; const char* gameVersionStr = GetGameVersionString(); g = *gfxp; g = func_8009411C(g); //printer = alloca(sizeof(GfxPrint)); GfxPrint_Init(&printer); GfxPrint_Open(&printer, g); GfxPrint_SetColor(&printer, 255, 155, 255, 255); GfxPrint_SetPos(&printer, 12, 20); #ifdef _MSC_VER GfxPrint_Printf(&printer, "MSVC SHIP"); #elif __clang__ GfxPrint_Printf(&printer, "CLANG SHIP"); #else GfxPrint_Printf(&printer, "GCC SHIP"); #endif GfxPrint_SetPos(&printer, 5, 4); GfxPrint_Printf(&printer, "Game Version: %s", gameVersionStr); GfxPrint_SetColor(&printer, 255, 255, 255, 255); GfxPrint_SetPos(&printer, 2, 22); GfxPrint_Printf(&printer, quote); GfxPrint_SetPos(&printer, 1, 25); GfxPrint_Printf(&printer, "Build Date:%s", gBuildDate); GfxPrint_SetPos(&printer, 3, 26); GfxPrint_Printf(&printer, "%s", gBuildTeam); GfxPrint_SetPos(&printer, 3, 28); GfxPrint_Printf(&printer, "Release Version: %s", gBuildVersion); g = GfxPrint_Close(&printer); GfxPrint_Destroy(&printer); *gfxp = g; } const char* quotes[11] = { "My boy! This peace is what all true warriors strive for!", "Hmm. How can we help?", "Zelda! Duke Onkled is under attack by the evil forces of Ganon!", "I'm going to Gamelon to aid him.", "I'll take the Triforce of Courage to protect me.", "If you don't hear from me in a month, send Link.", "Enough! My ship sails in the morning.", "I wonder what's for dinner.", "You've saved me!", "After you've scrubbed all the floors in Hyrule, then we can talk about mercy! Take him away!", "Waaaahahahohohahahahahahaha" }; char* SetQuote() { srand(time(NULL)); int randomQuote = rand() % 11; return quotes[randomQuote]; } const char* GetGameVersionString() { uint32_t gameVersion = ResourceMgr_GetGameVersion(); switch (gameVersion) { case OOT_NTSC_10: return "N64 NTSC 1.0"; case OOT_NTSC_11: return "N64 NTSC 1.1"; case OOT_NTSC_12: return "N64 NTSC 1.2"; case OOT_PAL_10: return "N64 PAL 1.0"; case OOT_PAL_11: return "N64 PAL 1.1"; case OOT_PAL_GC: return "GC PAL"; case OOT_PAL_MQ: return "GC PAL MQ"; case OOT_PAL_GC_DBG1: return "GC PAL DEBUG"; case OOT_PAL_GC_DBG2: return "GC PAL DEBUG MQ"; case OOT_IQUE_CN: return "IQUE CN"; case OOT_IQUE_TW: return "IQUE TW"; default: return "UNKNOWN"; } } // Note: In other rom versions this function also updates unk_1D4, coverAlpha, addAlpha, visibleDuration to calculate // the fade-in/fade-out + the duration of the n64 logo animation void Title_Calc(TitleContext* this) { #ifdef NORMAL_GAMEPLAY if ((this->coverAlpha == 0) && (this->visibleDuration != 0)) { this->visibleDuration--; this->unk_1D4--; if (this->unk_1D4 == 0) { this->unk_1D4 = 400; } } else { this->coverAlpha += this->addAlpha; if (this->coverAlpha <= 0) { this->coverAlpha = 0; this->addAlpha = 3; } else if (this->coverAlpha >= 0xFF) { this->coverAlpha = 0xFF; this->exit = 1; } } this->uls = this->ult & 0x7F; this->ult++; if (gSkipLogoTest || gLoadFileSelect) { this->exit = 1; } #else this->exit = 1; #endif } void Title_SetupView(TitleContext* this, f32 x, f32 y, f32 z) { View* view = &this->view; Vec3f eye; Vec3f lookAt; Vec3f up; eye.x = x; eye.y = y; eye.z = z; up.x = up.z = 0.0f; lookAt.x = lookAt.y = lookAt.z = 0.0f; up.y = 1.0f; func_800AA460(view, 30.0f, 10.0f, 12800.0f); func_800AA358(view, &eye, &lookAt, &up); func_800AAA50(view, 0xF); } void Title_Draw(TitleContext* this) { static s16 sTitleRotY = 0; static Lights1 sTitleLights = gdSPDefLights1(0x64, 0x64, 0x64, 0xFF, 0xFF, 0xFF, 0x45, 0x45, 0x45); u16 y; u16 idx; s32 pad1; Vec3f v3; Vec3f v1; Vec3f v2; s32 pad2[2]; OPEN_DISPS(this->state.gfxCtx); v3.x = 69; v3.y = 69; v3.z = 69; v2.x = -4949.148; v2.y = 4002.5417; v1.x = 0; v1.y = 0; v1.z = 0; v2.z = 1119.0837; char* n64LogoTex = ResourceMgr_LoadTexByName(nintendo_rogo_static_Tex_000000); func_8002EABC(&v1, &v2, &v3, this->state.gfxCtx); gSPSetLights1(POLY_OPA_DISP++, sTitleLights); Title_SetupView(this, 0, 150.0, 300.0); func_80093D18(this->state.gfxCtx); Matrix_Translate(-53.0, -5.0, 0, MTXMODE_NEW); Matrix_Scale(1.0, 1.0, 1.0, MTXMODE_APPLY); Matrix_RotateZYX(0, sTitleRotY, 0, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(this->state.gfxCtx), G_MTX_LOAD); gSPDisplayList(POLY_OPA_DISP++, gNintendo64LogoDL); func_800944C4(this->state.gfxCtx); gDPPipeSync(POLY_OPA_DISP++); gDPSetCycleType(POLY_OPA_DISP++, G_CYC_2CYCLE); gDPSetRenderMode(POLY_OPA_DISP++, G_RM_XLU_SURF2, G_RM_OPA_CI | CVG_DST_WRAP); gDPSetCombineLERP(POLY_OPA_DISP++, TEXEL1, PRIMITIVE, ENV_ALPHA, TEXEL0, 0, 0, 0, TEXEL0, PRIMITIVE, ENVIRONMENT, COMBINED, ENVIRONMENT, COMBINED, 0, PRIMITIVE, 0); gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 170, 255, 255, 255); gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 255, 128); gDPLoadMultiBlock(POLY_OPA_DISP++, nintendo_rogo_static_Tex_001800, 0x100, 1, G_IM_FMT_I, G_IM_SIZ_8b, 32, 32, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 5, 5, 2, 11); for (idx = 0, y = 94; idx < 16; idx++, y += 2) { gDPLoadTextureBlock(POLY_OPA_DISP++, &n64LogoTex[0x180 * idx], G_IM_FMT_I, G_IM_SIZ_8b, 192, 2, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gDPSetTileSize(POLY_OPA_DISP++, 1, this->uls, (this->ult & 0x7F) - idx * 4, 0, 0); gSPTextureRectangle(POLY_OPA_DISP++, 388, y << 2, 1156, (y + 2) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); } Environment_FillScreen(this->state.gfxCtx, 0, 0, 0, (s16)this->coverAlpha, FILL_SCREEN_XLU); sTitleRotY += 300; CLOSE_DISPS(this->state.gfxCtx); } void Title_Main(GameState* thisx) { TitleContext* this = (TitleContext*)thisx; OPEN_DISPS(this->state.gfxCtx); gSPSegment(POLY_OPA_DISP++, 0, NULL); gSPSegment(POLY_OPA_DISP++, 1, this->staticSegment); func_80095248(this->state.gfxCtx, 0, 0, 0); Title_Calc(this); Title_Draw(this); if (1) { Gfx* gfx = POLY_OPA_DISP; s32 pad; Title_PrintBuildInfo(&gfx); POLY_OPA_DISP = gfx; } if (this->exit) { gSaveContext.seqId = (u8)NA_BGM_DISABLED; gSaveContext.natureAmbienceId = 0xFF; gSaveContext.gameMode = 1; this->state.running = false; if (gLoadFileSelect) SET_NEXT_GAMESTATE(&this->state, FileChoose_Init, FileChooseContext); else SET_NEXT_GAMESTATE(&this->state, Opening_Init, OpeningContext); } CLOSE_DISPS(this->state.gfxCtx); } void Title_Destroy(GameState* thisx) { TitleContext* this = (TitleContext*)thisx; Sram_InitSram(&this->state); } void Title_Init(GameState* thisx) { //u32 size = 0; TitleContext* this = (TitleContext*)thisx; FileChooseContext* FileChooseCtx = (FileChooseContext*)thisx; if (CVar_GetS32("gSkipLogoTitle",0)) { bool saveloading = false; Sram_InitSram(&this->state.init); gSaveContext.language = CVar_GetS32("gLanguages", 0); s32 selectedfile = CVar_GetS32("gSaveFileID", 0); if (selectedfile == 4) { if (CVar_GetS32("gDebugEnabled",0)) { selectedfile = 0xFF; } else { selectedfile = 3; } } if (selectedfile < 0) { selectedfile = 3; //If somehow the save file number under 0 revert back to 3 to prevent boot error } if(selectedfile == 3){ saveloading = true; gSaveContext.seqId = (u8)NA_BGM_DISABLED; gSaveContext.natureAmbienceId = 0xFF; gSaveContext.gameMode = 1; SET_NEXT_GAMESTATE(&this->state, FileChoose_Init, FileChooseContext); this->state.running = false; return; } else if (selectedfile == 0xFF || selectedfile > 3) { saveloading = true; Sram_InitDebugSave(); gSaveContext.fileNum = selectedfile; SET_NEXT_GAMESTATE(&this->state, Select_Init, SelectContext); this->state.running = false; return; } else if (selectedfile >= 0 && selectedfile <= 2) { if (Save_Exist(selectedfile) == true) { //The file exist load it saveloading = true; gSaveContext.fileNum = selectedfile; Sram_OpenSave(); gSaveContext.gameMode = 0; gSaveContext.magic = gSaveContext.magic; SET_NEXT_GAMESTATE(&this->state, Gameplay_Init, GlobalContext); this->state.running = false; return; } else { if (CVar_GetS32("gCreateNewSave",0)) { //File do not exist create a new save file saveloading = true; Sram_InitSram(&FileChooseCtx->state.init); gSaveContext.fileNum = selectedfile; Sram_InitSave(FileChooseCtx); Sram_OpenSave(); gSaveContext.gameMode = 0; SET_NEXT_GAMESTATE(&this->state, Gameplay_Init, GlobalContext); this->state.running = false; return; } else { //File do not exist but user do not wish to auto create a save file with blank name saveloading = true; gSaveContext.seqId = (u8)NA_BGM_DISABLED; gSaveContext.natureAmbienceId = 0xFF; gSaveContext.gameMode = 1; SET_NEXT_GAMESTATE(&this->state, FileChoose_Init, FileChooseContext); this->state.running = false; return; } } } } else { quote = SetQuote(); this->staticSegment = NULL; //this->staticSegment = GAMESTATE_ALLOC_MC(&this->state, size); osSyncPrintf("z_title.c\n"); //ASSERT(this->staticSegment != NULL); //ResourceMgr_CacheDirectory("nintendo_rogo_static*"); // Disable vismono D_801614B0.a = 0; R_UPDATE_RATE = 1; Matrix_Init(&this->state); View_Init(&this->view, this->state.gfxCtx); this->state.main = Title_Main; this->state.destroy = Title_Destroy; this->exit = false; gSaveContext.fileNum = 0xFF; this->ult = 0; this->unk_1D4 = 0x14; this->coverAlpha = 255; this->addAlpha = -3; this->visibleDuration = 0x3C; } }