Path: blob/main/RSDKv4/NativeObjects/MenuControl.cpp
817 views
#include "RetroEngine.hpp"12bool usePhysicalControls = false;34void MenuControl_Create(void *objPtr)5{6RSDK_THIS(MenuControl);7SetMusicTrack("MainMenu.ogg", 0, true, 106596);8CREATE_ENTITY(MenuBG);910self->buttons[self->buttonCount] = (NativeEntity_AchievementsButton *)CREATE_ENTITY(StartGameButton);11self->buttonFlags[self->buttonCount] = BUTTON_STARTGAME;12self->buttonCount++;1314self->buttons[self->buttonCount] = (NativeEntity_AchievementsButton *)CREATE_ENTITY(TimeAttackButton);15self->buttonFlags[self->buttonCount] = BUTTON_TIMEATTACK;16self->buttonCount++;1718#if RETRO_USE_MOD_LOADER19int vsID = GetSceneID(STAGELIST_PRESENTATION, "2P VS");20if (vsID != -1) {21#else22if (Engine.gameType == GAME_SONIC2) {23#endif24self->buttons[self->buttonCount] = (NativeEntity_AchievementsButton *)CREATE_ENTITY(MultiplayerButton);25self->buttonFlags[self->buttonCount] = BUTTON_MULTIPLAYER;26self->buttonCount++;27}2829if (Engine.onlineActive) {30self->buttons[self->buttonCount] = CREATE_ENTITY(AchievementsButton);31self->buttonFlags[self->buttonCount] = BUTTON_ACHIEVEMENTS;32self->buttonCount++;3334self->buttons[self->buttonCount] = (NativeEntity_AchievementsButton *)CREATE_ENTITY(LeaderboardsButton);35self->buttonFlags[self->buttonCount] = BUTTON_LEADERBOARDS;36self->buttonCount++;37}3839self->buttons[self->buttonCount] = (NativeEntity_AchievementsButton *)CREATE_ENTITY(OptionsButton);40self->buttonFlags[self->buttonCount] = BUTTON_OPTIONS;41self->buttonCount++;4243self->backButton = CREATE_ENTITY(BackButton);44self->backButton->visible = false;45self->backButton->x = 240.0;46self->backButton->y = -160.0;47self->backButton->z = 0.0;4849self->segaIDButton = CREATE_ENTITY(SegaIDButton);50self->segaIDButton->y = -92.0;51self->segaIDButton->texX = 0.0;52self->segaIDButton->x = SCREEN_CENTERX_F - 32.0;5354self->buttonIncline = 0.15707964f; // this but less precise ---> M_PI / 255self->buttonSpacing = 0.078539819f; // this but less precise ---> M_PI / 456self->menuEndPos = (self->buttonCount * self->buttonIncline) * 0.5;5758float offset = 0.0;59for (int b = 0; b < self->buttonCount; ++b) {60NativeEntity_AchievementsButton *button = self->buttons[b];61float sin = sinf(self->buttonMovePos + offset);62float cos = cosf(self->buttonMovePos + offset);63button->x = 1024.0 * sin;64button->z = (cos * -512.0) + 672.0;65button->y = (128.0 * sin) + 16.0;66button->visible = button->z <= 288.0;67offset += self->buttonIncline;68}6970PlayMusic(0, 0);71if (Engine.gameDeviceType == RETRO_STANDARD)72usePhysicalControls = true;73BackupNativeObjects();74}75void MenuControl_Main(void *objPtr)76{77RSDK_THIS(MenuControl);78NativeEntity_SegaIDButton *segaIDButton = self->segaIDButton;79NativeEntity_BackButton *backButton = self->backButton;8081switch (self->state) {82case MENUCONTROL_STATE_MAIN: {83CheckKeyDown(&keyDown);84CheckKeyPress(&keyPress);8586if (segaIDButton->alpha < 0x100 && Engine.language != RETRO_JP && !(Engine.language == RETRO_ZH || Engine.language == RETRO_ZS)87&& Engine.gameDeviceType == RETRO_MOBILE)88segaIDButton->alpha += 8;8990if (!usePhysicalControls) {91switch (self->stateInput) {92case MENUCONTROL_STATEINPUT_CHECKTOUCH: {93if (touches > 0) {94if (!keyDown.left && !keyDown.right) {95segaIDButton->state = SEGAIDBUTTON_STATE_IDLE;96if (CheckTouchRect(0.0, 16.0, 56.0, 56.0) >= 0) {97BackupNativeObjects();98self->releaseTouchX = touchXF[0];99self->stateInput = MENUCONTROL_STATEINPUT_HANDLERELEASE;100self->buttonID = ceilf(self->buttonMovePos / -self->buttonSpacing);101self->buttons[self->buttonID]->g = 0xC0;102}103else {104if (CheckTouchRect(self->segaIDButton->x, self->segaIDButton->y, 20.0, 20.0) >= 0 && segaIDButton->alpha > 64) {105segaIDButton->state = SEGAIDBUTTON_STATE_PRESSED;106}107else {108self->stateInput = MENUCONTROL_STATEINPUT_HANDLEDRAG;109self->lastDragTouchDistance = 0.0;110self->dragTouchX = touchXF[0];111self->lastButtonMovePos = self->buttonMovePos;112}113}114}115else {116segaIDButton->state = SEGAIDBUTTON_STATE_IDLE;117usePhysicalControls = true;118self->buttonID = ceilf(self->buttonMovePos / -self->buttonSpacing);119self->buttons[self->buttonID]->g = 0xC0;120}121}122else if (segaIDButton->state == SEGAIDBUTTON_STATE_PRESSED) {123segaIDButton->state = SEGAIDBUTTON_STATE_IDLE;124PlaySfxByName("Menu Select", false);125ShowPromoPopup(0, "MoreGames");126}127else if (keyDown.left || keyDown.right) {128segaIDButton->state = SEGAIDBUTTON_STATE_IDLE;129usePhysicalControls = true;130self->buttonID = ceilf(self->buttonMovePos / -self->buttonSpacing);131self->buttons[self->buttonID]->g = 0xC0;132}133break;134}135136case MENUCONTROL_STATEINPUT_HANDLEDRAG: {137if (touches <= 0) {138self->stateInput = MENUCONTROL_STATEINPUT_HANDLEMOVEMENT;139}140else {141self->autoButtonMoveVelocity = 0.0;142self->dragTouchDistance = (self->dragTouchX - touchXF[0]) * -0.0007;143if (abs(self->lastDragTouchDistance) > 0.0) {144self->autoButtonMoveVelocity = self->dragTouchDistance - self->lastDragTouchDistance;145self->buttonMovePos += self->autoButtonMoveVelocity;146}147self->lastDragTouchDistance = self->dragTouchDistance;148}149break;150}151152case MENUCONTROL_STATEINPUT_HANDLEMOVEMENT: {153self->autoButtonMoveVelocity /= (1.125 * (60.0 * Engine.deltaTime));154self->buttonMovePos += self->autoButtonMoveVelocity;155float max = -(self->menuEndPos - self->buttonSpacing);156157if (max - 0.05 > self->buttonMovePos || self->buttonMovePos > 0.05)158self->autoButtonMoveVelocity = 0.0;159160if (abs(self->autoButtonMoveVelocity) < 0.0025) {161if (self->buttonMovePos == self->lastButtonMovePos && self->dragTouchX < 0.0) {162self->buttonMovePos += 0.00001;163}164165if (self->buttonMovePos <= self->lastButtonMovePos) {166self->targetButtonMovePos = floorf(self->buttonMovePos / self->buttonSpacing) * self->buttonSpacing;167168if (self->targetButtonMovePos > self->lastButtonMovePos - self->buttonSpacing)169self->targetButtonMovePos = self->lastButtonMovePos - self->buttonSpacing;170171if (self->targetButtonMovePos < max)172self->targetButtonMovePos = max;173}174else {175self->targetButtonMovePos = ceilf(self->buttonMovePos / self->buttonSpacing) * self->buttonSpacing;176177if (self->targetButtonMovePos < self->buttonSpacing + self->lastButtonMovePos)178self->targetButtonMovePos = self->buttonSpacing + self->lastButtonMovePos;179180if (self->targetButtonMovePos > 0.0)181self->targetButtonMovePos = 0.0;182}183184self->stateInput = MENUCONTROL_STATEINPUT_MOVE;185self->buttonMovePos += (self->targetButtonMovePos - self->buttonMovePos) / ((60.0 * Engine.deltaTime) * 8.0);186}187break;188}189190case MENUCONTROL_STATEINPUT_MOVE: {191if (touches > 0) {192self->stateInput = MENUCONTROL_STATEINPUT_HANDLEDRAG;193self->lastDragTouchDistance = 0.0;194self->dragTouchX = touchXF[0];195}196else {197self->buttonMovePos += (self->targetButtonMovePos - self->buttonMovePos) / ((60.0 * Engine.deltaTime) * 6.0);198if (abs(self->targetButtonMovePos - self->buttonMovePos) < 0.00025) {199self->buttonMovePos = self->targetButtonMovePos;200self->stateInput = MENUCONTROL_STATEINPUT_CHECKTOUCH;201}202}203break;204}205206case MENUCONTROL_STATEINPUT_HANDLERELEASE: {207if (touches > 0) {208if (CheckTouchRect(0.0, 16.0, 56.0, 56.0) < 0) {209self->buttons[self->buttonID]->g = 0xFF;210}211else {212self->buttons[self->buttonID]->g = 0xC0;213if (abs(self->releaseTouchX - touchXF[0]) > 8.0f) {214self->stateInput = MENUCONTROL_STATEINPUT_HANDLEDRAG;215self->dragTouchX = self->buttonID;216self->lastDragTouchDistance = 0.0;217self->lastButtonMovePos = self->buttonMovePos;218self->buttons[self->buttonID]->g = 0xFF;219}220}221}222else {223if (self->buttons[self->buttonID]->g == 0xC0) {224self->buttons[self->buttonID]->labelPtr->state = TEXTLABEL_STATE_BLINK_FAST;225self->timer = 0.0;226self->state = MENUCONTROL_STATE_ACTION;227PlaySfxByName("Menu Select", false);228}229self->buttons[self->buttonID]->g = 0xFF;230self->stateInput = MENUCONTROL_STATEINPUT_CHECKTOUCH;231}232break;233}234235default: break;236}237}238else {239if (self->stateInput == MENUCONTROL_STATEINPUT_HANDLEDRAG) {240self->buttonMovePos +=241(((self->buttonMoveVelocity + self->targetButtonMovePos) - self->buttonMovePos) / ((60.0 * Engine.deltaTime) * 8.0));242243if (abs(self->targetButtonMovePos - self->buttonMovePos) < 0.001) {244self->buttonMovePos = self->targetButtonMovePos;245self->stateInput = MENUCONTROL_STATEINPUT_CHECKTOUCH;246}247}248else {249if (touches <= 0) {250if (keyPress.right && self->buttonMovePos > -(self->menuEndPos - self->buttonSpacing)) {251self->stateInput = MENUCONTROL_STATEINPUT_HANDLEDRAG;252self->targetButtonMovePos -= self->buttonSpacing;253PlaySfxByName("Menu Move", false);254self->buttonMoveVelocity = -0.01;255self->buttonID++;256if (self->buttonID >= self->buttonCount)257self->buttonID = self->buttonCount - 1;258}259else if (keyPress.left && self->buttonMovePos < 0.0) {260self->stateInput = MENUCONTROL_STATEINPUT_HANDLEDRAG;261self->targetButtonMovePos += self->buttonSpacing;262PlaySfxByName("Menu Move", false);263self->buttonMoveVelocity = 0.01;264self->buttonID--;265if (self->buttonID > self->buttonCount)266self->buttonID = 0;267}268else if ((keyPress.start || keyPress.A) && !Engine.nativeMenuFadeIn) {269BackupNativeObjects();270self->buttons[self->buttonID]->labelPtr->state = TEXTLABEL_STATE_BLINK_FAST;271self->timer = 0.0;272self->state = MENUCONTROL_STATE_ACTION;273PlaySfxByName("Menu Select", false);274}275276for (int i = 0; i < self->buttonCount; ++i) {277self->buttons[i]->g = 0xFF;278}279self->buttons[self->buttonID]->g = 0xC0;280}281else {282usePhysicalControls = false;283for (int i = 0; i < self->buttonCount; ++i) {284self->buttons[i]->g = 0xFF;285}286}287}288}289290float offset = self->buttonMovePos;291for (int i = 0; i < self->buttonCount; ++i) {292NativeEntity_AchievementsButton *button = self->buttons[i];293button->x = 1024.0 * sinf(self->buttonMovePos + offset);294button->y = (sinf(self->buttonMovePos + offset) * 128.0) + 16.0;295button->z = (cosf(self->buttonMovePos + offset) * -512.0) + 672.0;296button->visible = button->z <= 288.0;297offset += self->buttonIncline;298}299300if (!self->stateInput) {301if (self->dialogTimer) {302self->dialogTimer--;303}304else if (keyPress.B && !Engine.nativeMenuFadeIn) {305self->dialog = CREATE_ENTITY(DialogPanel);306SetStringToFont(self->dialog->text, strExitGame, FONT_TEXT);307self->state = MENUCONTROL_STATE_DIALOGWAIT;308PlaySfxByName("Resume", false);309}310}311break;312}313314case MENUCONTROL_STATE_ACTION: {315self->timer += Engine.deltaTime;316if (self->timer > 0.5) {317self->timer = 0.0;318NativeEntity_AchievementsButton *button = self->buttons[self->buttonID];319switch (self->buttonFlags[self->buttonID]) {320case BUTTON_STARTGAME:321self->state = MENUCONTROL_STATE_ENTERSUBMENU;322self->autoButtonMoveVelocity = 0.0;323button->g = 0xFF;324self->buttons[self->buttonID]->labelPtr->state = TEXTLABEL_STATE_NONE;325self->backButton->visible = true;326SetGlobalVariableByName("options.vsMode", false);327CREATE_ENTITY(SaveSelect);328break;329330case BUTTON_TIMEATTACK:331self->state = MENUCONTROL_STATE_ENTERSUBMENU;332self->autoButtonMoveVelocity = 0.0;333button->g = 0xFF;334button->labelPtr->state = TEXTLABEL_STATE_NONE;335self->backButton->visible = true;336CREATE_ENTITY(TimeAttack);337break;338339case BUTTON_MULTIPLAYER:340self->state = MENUCONTROL_STATE_MAIN;341button->labelPtr->state = TEXTLABEL_STATE_IDLE;342SetGlobalVariableByName("options.saveSlot", 0);343SetGlobalVariableByName("options.gameMode", 0);344SetGlobalVariableByName("options.vsMode", 0);345SetGlobalVariableByName("player.lives", 3);346SetGlobalVariableByName("player.score", 0);347SetGlobalVariableByName("player.scoreBonus", 50000);348SetGlobalVariableByName("specialStage.listPos", 0);349SetGlobalVariableByName("specialStage.emeralds", 0);350SetGlobalVariableByName("specialStage.nextZone", 0);351SetGlobalVariableByName("timeAttack.result", 0);352SetGlobalVariableByName("lampPostID", 0);353SetGlobalVariableByName("starPostID", 0);354if (Engine.onlineActive) {355#if !RETRO_USE_ORIGINAL_CODE356BackupNativeObjects();357int id = GetSceneID(STAGELIST_PRESENTATION, "2P VS");358if (id == -1)359id = 3;360InitStartingStage(STAGELIST_PRESENTATION, id, 0);361#else362InitStartingStage(STAGELIST_PRESENTATION, 3, 0);363#endif364CREATE_ENTITY(FadeScreen);365}366else {367self->dialog = CREATE_ENTITY(DialogPanel);368self->dialog->buttonCount = DLGTYPE_OK;369SetStringToFont(self->dialog->text, strNetworkMessage, FONT_TEXT);370self->state = MENUCONTROL_STATE_DIALOGWAIT;371}372break;373374case BUTTON_ACHIEVEMENTS:375if (Engine.onlineActive && false) {376ShowAchievementsScreen();377}378else {379self->state = MENUCONTROL_STATE_MAIN;380self->dialog = CREATE_ENTITY(DialogPanel);381self->dialog->buttonCount = DLGTYPE_OK;382SetStringToFont(self->dialog->text, strNetworkMessage, FONT_TEXT);383self->state = MENUCONTROL_STATE_DIALOGWAIT;384}385button->labelPtr->state = TEXTLABEL_STATE_IDLE;386break;387388case BUTTON_LEADERBOARDS:389self->state = MENUCONTROL_STATE_MAIN;390if (Engine.onlineActive && false) {391ShowLeaderboardsScreen();392}393else {394self->dialog = CREATE_ENTITY(DialogPanel);395self->dialog->buttonCount = DLGTYPE_OK;396SetStringToFont(self->dialog->text, strNetworkMessage, FONT_TEXT);397self->state = MENUCONTROL_STATE_DIALOGWAIT;398}399button->labelPtr->state = TEXTLABEL_STATE_IDLE;400break;401402case BUTTON_OPTIONS:403self->state = MENUCONTROL_STATE_ENTERSUBMENU;404self->autoButtonMoveVelocity = 0.0;405button->g = 0xFF;406button->labelPtr->state = TEXTLABEL_STATE_NONE;407self->backButton->visible = true;408CREATE_ENTITY(OptionsMenu);409break;410411default:412self->state = MENUCONTROL_STATE_MAIN;413button->labelPtr->state = TEXTLABEL_STATE_IDLE;414break;415}416}417break;418}419420case MENUCONTROL_STATE_NONE: break;421422case MENUCONTROL_STATE_ENTERSUBMENU: {423if (segaIDButton->alpha > 0)424segaIDButton->alpha -= 8;425426self->autoButtonMoveVelocity -= 0.125 * (60.0 * Engine.deltaTime);427428for (int i = 0; i < self->buttonCount; ++i) {429if (self->buttonID != i) {430if (self->buttonID != i)431self->buttons[i]->z += ((60.0 * Engine.deltaTime) * self->autoButtonMoveVelocity);432}433}434435self->timer += Engine.deltaTime;436self->autoButtonMoveVelocity -= 0.125 * (60.0 * Engine.deltaTime);437438if (self->timer > 0.5) {439NativeEntity_AchievementsButton *button = self->buttons[self->buttonID];440float div = (60.0 * Engine.deltaTime) * 16.0;441442button->x += ((112.0 - button->x) / div);443button->y += ((64.0 - button->y) / div);444button->z += ((200.0 - button->z) / div);445self->backButton->z += ((320.0 - self->backButton->z) / div);446}447448if (self->timer > 1.5) {449self->timer = 0.0;450self->state = MENUCONTROL_STATE_SUBMENU;451452for (int i = 0; i < self->buttonCount; ++i) {453if (self->buttonID != i) {454if (self->buttonID != i)455self->buttons[i]->visible = false;456}457}458}459break;460}461462case MENUCONTROL_STATE_SUBMENU: {463CheckKeyDown(&keyDown);464CheckKeyPress(&keyPress);465if (touches <= 0) {466if (self->backButton->g == 0xC0) {467PlaySfxByName("Menu Back", false);468self->backButton->g = 0xFF;469self->state = MENUCONTROL_STATE_EXITSUBMENU;470}471}472else {473backButton = self->backButton;474if (CheckTouchRect(122.0, -80.0, 32.0, 32.0) < 0)475backButton->g = 0xFF;476else477backButton->g = 0xC0;478}479if (keyPress.B) {480PlaySfxByName("Menu Back", false);481self->backButton->g = 0xFF;482self->state = MENUCONTROL_STATE_EXITSUBMENU;483}484break;485}486487case MENUCONTROL_STATE_EXITSUBMENU: {488self->backButton->z = ((0.0 - self->backButton->z) / (16.0 * (60.0 * Engine.deltaTime))) + self->backButton->z;489self->timer += Engine.deltaTime;490if (self->timer > 0.25) {491float offset = self->buttonMovePos;492float div = (60.0 * Engine.deltaTime) * 8.0;493494for (int i = 0; i < self->buttonCount; ++i) {495if (self->buttonID != i) {496NativeEntity_AchievementsButton *button = self->buttons[i];497button->z = ((((cosf(offset + self->buttonMovePos) * -512.0) + 672.0) - button->z) / div) + button->z;498button->visible = true;499}500offset += self->buttonIncline;501}502503NativeEntity_AchievementsButton *curButton = self->buttons[self->buttonID];504curButton->labelPtr->state = TEXTLABEL_STATE_IDLE;505curButton->x += ((0.0 - curButton->x) / div);506curButton->y += ((16.0 - curButton->y) / div);507curButton->z += ((160.0 - curButton->z) / div);508}509510if (self->timer > 1.0) {511self->timer = 0.0;512self->autoButtonMoveVelocity = 0.0;513self->state = MENUCONTROL_STATE_MAIN;514}515break;516}517518case MENUCONTROL_STATE_DIALOGWAIT: {519if (self->dialog->selection == DLG_NO || self->dialog->selection == DLG_OK) {520self->state = MENUCONTROL_STATE_MAIN;521self->dialogTimer = 50;522}523else if (self->dialog->selection == DLG_YES) {524ExitGame();525self->dialogTimer = 50;526self->state = MENUCONTROL_STATE_MAIN;527}528break;529}530531default: break;532}533}534535536