Path: blob/main/RSDKv4/NativeObjects/PauseMenu.cpp
817 views
#include "RetroEngine.hpp"12int pauseMenuButtonCount;34void PauseMenu_Create(void *objPtr)5{6RSDK_THIS(PauseMenu);78// code has been here from TitleScreen_Create due to the possibility of opening the dev menu before this loads :(9#if !RETRO_USE_ORIGINAL_CODE10int heading = -1, labelTex = -1, textTex = -1;1112if (fontList[FONT_HEADING].count <= 2) {13if (Engine.useHighResAssets)14heading = LoadTexture("Data/Game/Menu/Heading_EN.png", TEXFMT_RGBA4444);15else16heading = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);17LoadBitmapFont("Data/Game/Menu/Heading_EN.fnt", FONT_HEADING, heading);18}1920if (fontList[FONT_LABEL].count <= 2) {21if (Engine.useHighResAssets)22labelTex = LoadTexture("Data/Game/Menu/Label_EN.png", TEXFMT_RGBA4444);23else24labelTex = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);25LoadBitmapFont("Data/Game/Menu/Label_EN.fnt", FONT_LABEL, labelTex);26}2728if (fontList[FONT_TEXT].count <= 2) {29textTex = LoadTexture("Data/Game/Menu/Text_EN.png", TEXFMT_RGBA4444);30LoadBitmapFont("Data/Game/Menu/Text_EN.fnt", FONT_TEXT, textTex);31}3233switch (Engine.language) {34case RETRO_JP:35if (heading >= 0) {36heading = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);37LoadBitmapFont("Data/Game/Menu/Heading_JA.fnt", FONT_HEADING, heading);38}3940if (labelTex >= 0) {41labelTex = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);42LoadBitmapFont("Data/Game/Menu/Label_JA.fnt", FONT_LABEL, labelTex);43}4445if (textTex >= 0) {46textTex = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);47LoadBitmapFont("Data/Game/Menu/Text_JA.fnt", FONT_TEXT, textTex);48}49break;50case RETRO_RU:51if (heading >= 0) {52if (Engine.useHighResAssets)53heading = LoadTexture("Data/Game/Menu/Heading_RU.png", TEXFMT_RGBA4444);54else55heading = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);56LoadBitmapFont("Data/Game/Menu/Heading_RU.fnt", FONT_HEADING, heading);57}5859if (labelTex >= 0) {60if (Engine.useHighResAssets)61labelTex = LoadTexture("Data/Game/Menu/Label_RU.png", TEXFMT_RGBA4444);62else63labelTex = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);64}65break;66case RETRO_KO:67if (heading >= 0) {68heading = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);69LoadBitmapFont("Data/Game/Menu/Heading_KO.fnt", FONT_HEADING, heading);70}7172if (labelTex >= 0) {73labelTex = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);74LoadBitmapFont("Data/Game/Menu/Label_KO.fnt", FONT_LABEL, labelTex);75}7677if (textTex >= 0) {78textTex = LoadTexture("Data/Game/Menu/Text_KO.png", TEXFMT_RGBA4444);79LoadBitmapFont("Data/Game/Menu/Text_KO.fnt", FONT_TEXT, textTex);80}81break;82case RETRO_ZH:83if (heading >= 0) {84heading = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);85LoadBitmapFont("Data/Game/Menu/Heading_ZH.fnt", FONT_HEADING, heading);86}8788if (labelTex >= 0) {89labelTex = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);90LoadBitmapFont("Data/Game/Menu/Label_ZH.fnt", FONT_LABEL, labelTex);91}9293if (textTex >= 0) {94textTex = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);95LoadBitmapFont("Data/Game/Menu/Text_ZH.fnt", FONT_TEXT, textTex);96}97break;98case RETRO_ZS:99if (heading >= 0) {100heading = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);101LoadBitmapFont("Data/Game/Menu/Heading_ZHS.fnt", FONT_HEADING, heading);102}103104if (labelTex >= 0) {105labelTex = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);106LoadBitmapFont("Data/Game/Menu/Label_ZHS.fnt", FONT_LABEL, labelTex);107}108109if (textTex >= 0) {110textTex = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);111LoadBitmapFont("Data/Game/Menu/Text_ZHS.fnt", FONT_TEXT, textTex);112}113break;114default: break;115}116#endif117118pauseMenuButtonCount = PMB_COUNT;119#if !RETRO_USE_ORIGINAL_CODE120if (!Engine.devMenu)121pauseMenuButtonCount--;122#endif123124self->retroGameLoop = (NativeEntity_RetroGameLoop *)GetNativeObject(0);125self->label = CREATE_ENTITY(TextLabel);126self->label->state = TEXTLABEL_STATE_IDLE;127self->label->z = 0.0;128self->label->scale = 0.2;129self->label->alpha = 0;130self->label->fontID = FONT_HEADING;131SetStringToFont(self->label->text, strPause, FONT_HEADING);132self->label->alignOffset = 512.0;133self->renderRot = DegreesToRad(22.5);134MatrixRotateYF(&self->label->renderMatrix, DegreesToRad(22.5));135MatrixTranslateXYZF(&self->matrix, -128.0, 80.0, 160.0);136MatrixMultiplyF(&self->label->renderMatrix, &self->matrix);137self->label->useRenderMatrix = true;138self->buttonX = ((SCREEN_CENTERX_F + -160.0) * -0.5) + -128.0;139for (int i = 0; i < pauseMenuButtonCount; ++i) {140NativeEntity_SubMenuButton *button = CREATE_ENTITY(SubMenuButton);141self->buttons[i] = button;142button->scale = 0.1;143button->matZ = 0.0;144button->matXOff = 512.0;145button->textY = -4.0;146self->buttonRot[i] = DegreesToRad(16.0);147MatrixRotateYF(&button->matrix, DegreesToRad(16.0));148MatrixTranslateXYZF(&self->matrix, self->buttonX, 48.0 - i * 30, 160.0);149MatrixMultiplyF(&self->buttons[i]->matrix, &self->matrix);150button->symbol = 1;151button->useMatrix = true;152}153if ((GetGlobalVariableByName("player.lives") <= 1 && GetGlobalVariableByName("options.gameMode") <= 1) || !activeStageList154|| GetGlobalVariableByName("options.attractMode") == 1 || GetGlobalVariableByName("options.vsMode") == 1) {155self->buttons[PMB_RESTART]->r = 0x80;156self->buttons[PMB_RESTART]->g = 0x80;157self->buttons[PMB_RESTART]->b = 0x80;158}159SetStringToFont(self->buttons[PMB_CONTINUE]->text, strContinue, FONT_LABEL);160SetStringToFont(self->buttons[PMB_RESTART]->text, strRestart, FONT_LABEL);161SetStringToFont(self->buttons[PMB_SETTINGS]->text, strSettings, FONT_LABEL);162SetStringToFont(self->buttons[PMB_EXIT]->text, strExit, FONT_LABEL);163#if !RETRO_USE_ORIGINAL_CODE164if (Engine.devMenu)165SetStringToFont(self->buttons[PMB_DEVMENU]->text, strDevMenu, FONT_LABEL);166#endif167self->textureCircle = LoadTexture("Data/Game/Menu/Circle.png", TEXFMT_RGBA4444);168self->rotationY = 0.0;169self->rotYOff = DegreesToRad(-16.0);170self->matrixX = 0.0;171self->matrixY = 0.0;172self->matrixZ = 160.0;173self->width = (1.75 * SCREEN_CENTERX_F) - ((SCREEN_CENTERX_F - 160) * 2);174if (Engine.gameDeviceType == RETRO_MOBILE)175self->textureDPad = LoadTexture("Data/Game/Menu/VirtualDPad.png", TEXFMT_RGBA8888);176self->dpadY = 104.0;177self->state = PAUSEMENU_STATE_ENTER;178self->miniPauseDisabled = true;179self->dpadX = SCREEN_CENTERX_F - 76.0;180self->dpadXSpecial = SCREEN_CENTERX_F - 52.0;181}182void PauseMenu_Main(void *objPtr)183{184RSDK_THIS(PauseMenu);185switch (self->state) {186case PAUSEMENU_STATE_SETUP: {187self->timer += Engine.deltaTime;188if (self->timer > 1.0) {189self->timer = 0.0;190self->state = PAUSEMENU_STATE_ENTER;191}192break;193}194case PAUSEMENU_STATE_ENTER: {195if (self->unusedAlpha < 0x100)196self->unusedAlpha += 8;197self->timer += Engine.deltaTime * 2;198self->label->alignOffset = self->label->alignOffset / (1.125 * (60.0 * Engine.deltaTime));199self->label->alpha = (256.0 * self->timer);200for (int i = 0; i < pauseMenuButtonCount; ++i)201self->buttons[i]->matXOff += ((-176.0 - self->buttons[i]->matXOff) / (16.0 * (60.0 * Engine.deltaTime)));202self->matrixX += ((self->width - self->matrixX) / ((60.0 * Engine.deltaTime) * 12.0));203self->matrixZ += ((512.0 - self->matrixZ) / ((60.0 * Engine.deltaTime) * 12.0));204self->rotationY += ((self->rotYOff - self->rotationY) / (16.0 * (60.0 * Engine.deltaTime)));205if (self->timer > 1.0) {206self->timer = 0.0;207self->state = PAUSEMENU_STATE_MAIN;208}209break;210}211case PAUSEMENU_STATE_MAIN: {212CheckKeyDown(&keyDown);213CheckKeyPress(&keyPress);214if (usePhysicalControls) {215if (touches > 0) {216usePhysicalControls = false;217}218else {219if (keyPress.up) {220PlaySfxByName("Menu Move", false);221self->buttonSelected--;222if (self->buttonSelected < PMB_CONTINUE)223self->buttonSelected = pauseMenuButtonCount - 1;224}225else if (keyPress.down) {226PlaySfxByName("Menu Move", false);227self->buttonSelected++;228if (self->buttonSelected >= pauseMenuButtonCount)229self->buttonSelected = PMB_CONTINUE;230}231for (int i = 0; i < pauseMenuButtonCount; ++i) self->buttons[i]->b = self->buttons[i]->r;232self->buttons[self->buttonSelected]->b = 0;233if (self->buttons[self->buttonSelected]->g > 0x80 && (keyPress.start || keyPress.A)) {234PlaySfxByName("Menu Select", false);235self->buttons[self->buttonSelected]->state = SUBMENUBUTTON_STATE_FLASHING2;236self->buttons[self->buttonSelected]->b = 0xFF;237self->state = PAUSEMENU_STATE_ACTION;238}239}240}241else {242for (int i = 0; i < pauseMenuButtonCount; ++i) {243if (touches > 0) {244if (self->buttons[i]->g > 0x80)245self->buttons[i]->b = (CheckTouchRect(-80.0, 48.0 - i * 30, 112.0, 12.0) < 0) * 0xFF;246else247self->buttons[i]->b = 0x80;248}249else if (!self->buttons[i]->b) {250self->buttonSelected = i;251PlaySfxByName("Menu Select", false);252self->buttons[i]->state = SUBMENUBUTTON_STATE_FLASHING2;253self->buttons[i]->b = 0xFF;254self->state = PAUSEMENU_STATE_ACTION;255break;256}257}258259if (self->state == PAUSEMENU_STATE_MAIN && (keyDown.up || keyDown.down)) {260self->buttonSelected = PMB_CONTINUE;261usePhysicalControls = true;262}263}264if (touches > 0) {265if (!self->miniPauseDisabled && CheckTouchRect(SCREEN_CENTERX_F, SCREEN_CENTERY_F, 112.0, 24.0) >= 0) {266self->buttonSelected = PMB_CONTINUE;267PlaySfxByName("Resume", false);268self->state = PAUSEMENU_STATE_ACTION;269}270}271else {272self->miniPauseDisabled = false;273if (self->makeSound) {274PlaySfxByName("Menu Select", false);275self->makeSound = false;276}277}278break;279}280case PAUSEMENU_STATE_CONTINUE: {281self->label->alignOffset += 10.0 * (60.0 * Engine.deltaTime);282self->timer += Engine.deltaTime * 2;283for (int i = 0; i < pauseMenuButtonCount; ++i) self->buttons[i]->matXOff += ((12.0 + i) * (60.0 * Engine.deltaTime));284self->matrixX += ((-self->matrixX) / (5.0 * (60.0 * Engine.deltaTime)));285self->matrixZ += ((160.0 - self->matrixZ) / (5.0 * (60.0 * Engine.deltaTime)));286self->rotationY += ((self->rotYOff - self->rotationY) / ((60.0 * Engine.deltaTime) * 6.0));287288if (self->timer > 0.9) {289mixFiltersOnJekyll = true;290RenderRetroBuffer(64, 160.0);291if (Engine.gameDeviceType == RETRO_MOBILE) {292if (activeStageList == STAGELIST_SPECIAL)293RenderImage(self->dpadXSpecial, self->dpadY, 160.0, 0.25, 0.25, 32.0, 32.0, 64.0, 64.0, 160.0, 258.0, 255, self->textureDPad);294else295RenderImage(self->dpadX, self->dpadY, 160.0, 0.25, 0.25, 32.0, 32.0, 64.0, 64.0, 160.0, 258.0, 255, self->textureDPad);296}297self->timer = 0.0;298ClearNativeObjects();299CREATE_ENTITY(RetroGameLoop);300if (Engine.gameDeviceType == RETRO_MOBILE)301CREATE_ENTITY(VirtualDPad)->pauseAlpha = 255;302ResumeSound();303Engine.gameMode = ENGINE_MAINGAME;304return;305}306break;307}308case PAUSEMENU_STATE_ACTION: {309if (!self->buttons[self->buttonSelected]->state) {310switch (self->buttonSelected) {311case PMB_CONTINUE:312self->state = PAUSEMENU_STATE_CONTINUE;313self->rotYOff = 0.0;314break;315case PMB_RESTART:316self->dialog = CREATE_ENTITY(DialogPanel);317SetStringToFont(self->dialog->text, GetGlobalVariableByName("options.gameMode") ? strRestartMessage : strNSRestartMessage,318FONT_TEXT);319self->state = PAUSEMENU_STATE_RESTART;320break;321case PMB_SETTINGS:322self->state = PAUSEMENU_STATE_ENTERSUBMENU;323self->rotInc = 0.0;324self->renderRotMax = DegreesToRad(-90.0);325for (int i = 0; i < pauseMenuButtonCount; ++i) {326self->rotMax[i] = DegreesToRad(-90.0);327self->buttonRotY[i] = 0.02 * (i + 1);328}329330break;331case PMB_EXIT:332self->dialog = CREATE_ENTITY(DialogPanel);333SetStringToFont(self->dialog->text, GetGlobalVariableByName("options.gameMode") ? strExitMessage : strNSExitMessage,334FONT_TEXT);335self->state = PAUSEMENU_STATE_EXIT;336if (Engine.gameType == GAME_SONIC1)337SetGlobalVariableByName("timeAttack.result", 1000000);338break;339#if !RETRO_USE_ORIGINAL_CODE340case PMB_DEVMENU:341self->state = PAUSEMENU_STATE_DEVMENU;342self->timer = 0.0;343break;344#endif345default: break;346}347}348break;349}350case PAUSEMENU_STATE_ENTERSUBMENU: {351if (self->renderRot > self->renderRotMax) {352self->rotInc -= 0.0025 * (Engine.deltaTime * 60.0);353self->renderRot += (Engine.deltaTime * 60.0) * self->rotInc;354self->rotInc -= 0.0025 * (Engine.deltaTime * 60.0);355MatrixRotateYF(&self->label->renderMatrix, self->renderRot);356MatrixTranslateXYZF(&self->matrix, self->buttonX, 80.0, 160.0);357MatrixMultiplyF(&self->label->renderMatrix, &self->matrix);358}359for (int i = 0; i < pauseMenuButtonCount; ++i) {360if (self->buttonRot[i] > self->rotMax[i]) {361self->buttonRotY[i] -= 0.0025 * (60.0 * Engine.deltaTime);362if (self->buttonRotY[i] < 0.0) {363self->buttonRot[i] += ((60.0 * Engine.deltaTime) * self->buttonRotY[i]);364}365self->buttonRotY[i] -= 0.0025 * (60.0 * Engine.deltaTime); // do it again ????366MatrixRotateYF(&self->buttons[i]->matrix, self->buttonRot[i]);367MatrixTranslateXYZF(&self->matrix, self->buttonX, 48.0 - i * 30, 160.0);368MatrixMultiplyF(&self->buttons[i]->matrix, &self->matrix);369}370}371if (self->rotMax[pauseMenuButtonCount - 1] >= self->buttonRot[pauseMenuButtonCount - 1]) {372self->state = PAUSEMENU_STATE_SUBMENU;373374self->rotInc = 0.0;375self->renderRotMax = DegreesToRad(22.5);376for (int i = 0; i < pauseMenuButtonCount; ++i) {377self->rotMax[i] = DegreesToRad(16.0);378self->buttonRotY[i] = -0.02 * (i + 1);379}380if (self->buttonSelected == 2) {381self->settingsScreen = CREATE_ENTITY(SettingsScreen);382self->settingsScreen->optionsMenu = (NativeEntity_OptionsMenu *)self;383self->settingsScreen->isPauseMenu = 1;384}385}386self->matrixX += ((1024.0 - self->matrixX) / ((60.0 * Engine.deltaTime) * 16.0));387break;388}389case PAUSEMENU_STATE_SUBMENU: break;390case PAUSEMENU_STATE_EXITSUBMENU: {391if (self->renderRotMax > self->renderRot) {392self->rotInc += 0.0025 * (Engine.deltaTime * 60.0);393self->renderRot += (Engine.deltaTime * 60.0) * self->rotInc;394self->rotInc += 0.0025 * (Engine.deltaTime * 60.0);395MatrixRotateYF(&self->label->renderMatrix, self->renderRot);396MatrixTranslateXYZF(&self->matrix, self->buttonX, 80.0, 160.0);397MatrixMultiplyF(&self->label->renderMatrix, &self->matrix);398}399400for (int i = 0; i < pauseMenuButtonCount; ++i) {401if (self->rotMax[i] > self->buttonRot[i]) {402self->buttonRotY[i] += 0.0025 * (60.0 * Engine.deltaTime);403if (self->buttonRotY[i] > 0.0)404self->buttonRot[i] += ((60.0 * Engine.deltaTime) * self->buttonRotY[i]);405self->buttonRotY[i] += 0.0025 * (60.0 * Engine.deltaTime);406if (self->buttonRot[i] > self->rotMax[i])407self->buttonRot[i] = self->rotMax[i];408MatrixRotateYF(&self->buttons[i]->matrix, self->buttonRot[i]);409MatrixTranslateXYZF(&self->matrix, self->buttonX, 48.0 - i * 30, 160.0);410MatrixMultiplyF(&self->buttons[i]->matrix, &self->matrix);411}412}413414float div = (60.0 * Engine.deltaTime) * 16.0;415self->matrixX += (((self->width - 32.0) - self->matrixX) / div);416if (self->width - 16.0 > self->matrixX) {417self->matrixX = self->width - 16.0;418self->state = PAUSEMENU_STATE_MAIN;419}420break;421}422case PAUSEMENU_STATE_RESTART: {423if (self->dialog->selection == DLG_YES) {424self->state = PAUSEMENU_STATE_SUBMENU;425Engine.gameMode = ENGINE_EXITPAUSE;426stageMode = STAGEMODE_LOAD;427if (GetGlobalVariableByName("options.gameMode") <= 1) {428SetGlobalVariableByName("player.lives", GetGlobalVariableByName("player.lives") - 1);429}430if (activeStageList != STAGELIST_SPECIAL) {431SetGlobalVariableByName("lampPostID", 0);432SetGlobalVariableByName("starPostID", 0);433}434self->dialog->state = DIALOGPANEL_STATE_IDLE;435StopMusic(true);436CREATE_ENTITY(FadeScreen);437break;438}439if (self->dialog->selection == DLG_NO)440self->state = PAUSEMENU_STATE_MAIN;441break;442}443case PAUSEMENU_STATE_EXIT: {444if (self->dialog->selection == DLG_YES) {445self->state = PAUSEMENU_STATE_SUBMENU;446#if !RETRO_USE_ORIGINAL_CODE447if (skipStartMenu) {448Engine.gameMode = ENGINE_MAINGAME;449self->dialog->state = DIALOGPANEL_STATE_IDLE;450NativeEntity_FadeScreen *fadeout = CREATE_ENTITY(FadeScreen);451fadeout->state = FADESCREEN_STATE_GAMEFADEOUT;452activeStageList = STAGELIST_PRESENTATION;453stageListPosition = 0;454stageMode = STAGEMODE_LOAD;455}456else {457#endif458Engine.gameMode = (GetGlobalVariableByName("options.gameMode") > 1) + ENGINE_ENDGAME;459self->dialog->state = DIALOGPANEL_STATE_IDLE;460CREATE_ENTITY(FadeScreen);461#if !RETRO_USE_ORIGINAL_CODE462}463#endif464}465else {466if (self->dialog->selection == DLG_YES || self->dialog->selection == DLG_NO || self->dialog->selection == DLG_OK) {467self->state = PAUSEMENU_STATE_MAIN;468self->unused2 = 50;469}470}471break;472}473#if !RETRO_USE_ORIGINAL_CODE474case PAUSEMENU_STATE_DEVMENU:475self->timer += Engine.deltaTime;476if (self->timer > 0.5) {477if (!self->devMenuFade) {478self->devMenuFade = CREATE_ENTITY(FadeScreen);479self->devMenuFade->state = FADESCREEN_STATE_FADEOUT;480}481if (!self->devMenuFade->delay || self->devMenuFade->timer >= self->devMenuFade->delay) {482ClearNativeObjects();483RenderRect(-SCREEN_CENTERX_F, SCREEN_CENTERY_F, 160.0, SCREEN_XSIZE_F, SCREEN_YSIZE_F, 0, 0, 0, 255);484CREATE_ENTITY(RetroGameLoop);485if (Engine.gameDeviceType == RETRO_MOBILE)486CREATE_ENTITY(VirtualDPad);487Engine.gameMode = ENGINE_INITDEVMENU;488return;489}490}491break;492#endif493default: break;494}495496SetRenderBlendMode(RENDER_BLEND_NONE);497NewRenderState();498MatrixRotateYF(&self->matrixTemp, self->rotationY);499MatrixTranslateXYZF(&self->matrix, self->matrixX, self->matrixY, self->matrixZ);500MatrixMultiplyF(&self->matrixTemp, &self->matrix);501SetRenderMatrix(&self->matrixTemp);502RenderRect(-SCREEN_CENTERX_F - 4.0, SCREEN_CENTERY_F + 4.0, 0.0, SCREEN_XSIZE_F + 8.0, SCREEN_YSIZE_F + 8.0, 0, 0, 0, 255);503RenderRetroBuffer(64, 0.0);504NewRenderState();505SetRenderMatrix(NULL);506if (Engine.gameDeviceType == RETRO_MOBILE && self->state != PAUSEMENU_STATE_SUBMENU) {507if (activeStageList == STAGELIST_SPECIAL)508RenderImage(self->dpadXSpecial, self->dpadY, 160.0, 0.25, 0.25, 32.0, 32.0, 64.0, 64.0, 160.0, 258.0, 255, self->textureDPad);509else510RenderImage(self->dpadX, self->dpadY, 160.0, 0.25, 0.25, 32.0, 32.0, 64.0, 64.0, 160.0, 258.0, 255, self->textureDPad);511}512SetRenderBlendMode(RENDER_BLEND_ALPHA);513NewRenderState();514}515516517