Path: blob/master/SonicMania/Objects/Menu/UIButtonPrompt.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: UIButtonPrompt Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectUIButtonPrompt *UIButtonPrompt;1011void UIButtonPrompt_Update(void)12{13RSDK_THIS(UIButtonPrompt);1415bool32 textChanged = false;16if (self->textSprite != UIWidgets->textFrames) {17RSDK.SetSpriteAnimation(UIWidgets->textFrames, 0, &self->promptAnimator, true, self->promptID);18textChanged = true;19self->textSprite = UIWidgets->textFrames;20}2122if (self->scale.x == 0x200 && self->scaleMax == 0x200 && self->scaleSpeed)23self->scaleSpeed = 0;2425StateMachine_Run(self->state);2627if (self->scale.x >= self->scaleMax) {28if (self->scale.x > self->scaleMax) {29self->scale.x -= self->scaleSpeed;30if (self->scale.x < self->scaleMax)31self->scale.x = self->scaleMax;32}33}34else {35self->scale.x += self->scaleSpeed;36if (self->scale.x > self->scaleMax)37self->scale.x = self->scaleMax;38}3940self->scale.y = self->scale.x;4142if (self->prevPrompt != self->promptID) {43RSDK.SetSpriteAnimation(UIWidgets->textFrames, 0, &self->promptAnimator, true, self->promptID);44self->prevPrompt = self->promptID;45}4647int32 button = self->buttonID;48if (self->prevButton != button) {49UIButtonPrompt_SetButtonSprites();50button = self->buttonID;51self->prevButton = button;52}5354if (sku_platform == PLATFORM_PC || sku_platform == PLATFORM_DEV) {55int32 mappings = UIButtonPrompt_GetButtonMappings(UIButtonPrompt->inputSlot, button);56if (textChanged || self->mappings != mappings) {57UIButtonPrompt_SetButtonSprites();58self->mappings = mappings;59}60}61}6263void UIButtonPrompt_LateUpdate(void)64{65RSDK_THIS(UIButtonPrompt);6667EntityUIControl *control = (EntityUIControl *)self->parent;68if (control && control->heading && self->headingAnchor) {69EntityUIHeading *heading = (EntityUIHeading *)control->heading;7071switch (self->headingAnchor) {72default:73case UIBUTTONPROMPT_ANCHOR_NONE: break;7475case UIBUTTONPROMPT_ANCHOR_TOPLEFT_ROW1:76self->position.x = heading->position.x - TO_FIXED(188);77self->position.y = heading->position.y - TO_FIXED(8);78break;7980case UIBUTTONPROMPT_ANCHOR_TOPRIGHT_ROW1:81self->position.x = heading->position.x + TO_FIXED(124);82self->position.y = heading->position.y - TO_FIXED(8);83break;8485case UIBUTTONPROMPT_ANCHOR_TOPLEFT_ROW2:86self->position.x = heading->position.x - TO_FIXED(188);87self->position.y = heading->position.y + TO_FIXED(16);88break;8990case UIBUTTONPROMPT_ANCHOR_TOPRIGHT_ROW2:91self->position.x = heading->position.x + TO_FIXED(124);92self->position.y = heading->position.y + TO_FIXED(16);93break;94}95}96}9798void UIButtonPrompt_StaticUpdate(void)99{100UIButtonPrompt->type = UIButtonPrompt_GetGamepadType();101102#if MANIA_USE_PLUS103int32 id = API_GetFilteredInputDeviceID(false, false, 0);104#else105int32 id = API_GetFilteredInputDeviceID(INPUT_NONE);106#endif107int32 gamepadType = API_GetInputDeviceType(id);108int32 deviceType = (gamepadType >> 8) & 0xFF;109110UIButtonPrompt->inputSlot = deviceType == DEVICE_TYPE_KEYBOARD ? (gamepadType & 0xFF) : CONT_P1;111}112113void UIButtonPrompt_Draw(void)114{115RSDK_THIS(UIButtonPrompt);116117UIButtonPrompt_SetButtonSprites();118119RSDK.DrawSprite(&self->decorAnimator, NULL, false);120121self->drawFX = FX_SCALE;122RSDK.DrawSprite(&self->buttonAnimator, NULL, false);123124self->drawFX = FX_NONE;125if (self->textVisible)126RSDK.DrawSprite(&self->promptAnimator, NULL, false);127}128129void UIButtonPrompt_Create(void *data)130{131RSDK_THIS(UIButtonPrompt);132133if (!SceneInfo->inEditor) {134self->startPos = self->position;135self->visible = true;136self->drawGroup = 2;137self->scaleMax = 0x200;138self->scaleSpeed = 0x10;139self->scale.x = 0x200;140self->scale.y = 0x200;141self->disableScale = false;142self->active = ACTIVE_BOUNDS;143self->updateRange.x = 0x2000000;144self->updateRange.y = 0x800000;145self->textVisible = true;146147RSDK.SetSpriteAnimation(UIButtonPrompt->aniFrames, 0, &self->decorAnimator, true, 0);148RSDK.SetSpriteAnimation(UIWidgets->textFrames, 0, &self->promptAnimator, true, self->promptID);149150UIButtonPrompt_SetButtonSprites();151152self->textSprite = UIWidgets->textFrames;153self->state = UIButtonPrompt_State_CheckIfSelected;154self->parent = NULL;155self->touchSize.x = 0x580000;156self->touchSize.y = 0x100000;157self->touchPos.x = 0x200000;158}159}160161void UIButtonPrompt_StageLoad(void)162{163UIButtonPrompt->type = UIBUTTONPROMPT_KEYBOARD;164UIButtonPrompt->inputSlot = CONT_P1;165166UIButtonPrompt->aniFrames = RSDK.LoadSpriteAnimation("UI/Buttons.bin", SCOPE_STAGE);167}168169int32 UIButtonPrompt_GetButtonMappings(int32 input, int32 button)170{171#if MANIA_USE_PLUS172switch (button) {173case UIBUTTONPROMPT_BUTTON_A: return ControllerInfo[input].keyA.keyMap;174case UIBUTTONPROMPT_BUTTON_B: return ControllerInfo[input].keyB.keyMap;175case UIBUTTONPROMPT_BUTTON_X: return ControllerInfo[input].keyX.keyMap;176case UIBUTTONPROMPT_BUTTON_Y: return ControllerInfo[input].keyY.keyMap;177case UIBUTTONPROMPT_BUTTON_START: return ControllerInfo[input].keyStart.keyMap;178case UIBUTTONPROMPT_BUTTON_SELECT: return ControllerInfo[input].keySelect.keyMap;179default: break;180}181#else182switch (button) {183case UIBUTTONPROMPT_BUTTON_A: return ControllerInfo[CONT_P1].keyA.keyMap;184case UIBUTTONPROMPT_BUTTON_B: return ControllerInfo[CONT_P1].keyB.keyMap;185case UIBUTTONPROMPT_BUTTON_X: return ControllerInfo[CONT_P1].keyX.keyMap;186case UIBUTTONPROMPT_BUTTON_Y: return ControllerInfo[CONT_P1].keyY.keyMap;187case UIBUTTONPROMPT_BUTTON_START: return ControllerInfo[CONT_P1].keyStart.keyMap;188case UIBUTTONPROMPT_BUTTON_SELECT: return ControllerInfo[CONT_P1].keySelect.keyMap;189default: break;190}191#endif192193return 0;194}195196int32 UIButtonPrompt_GetGamepadType(void)197{198#if MANIA_USE_PLUS199int32 id = API_GetFilteredInputDeviceID(false, false, 0);200#else201int32 id = API_GetFilteredInputDeviceID(INPUT_NONE);202#endif203int32 gamepadType = API_GetInputDeviceType(id);204205int32 deviceType = (gamepadType >> 8) & 0xFF;206if (deviceType == DEVICE_TYPE_KEYBOARD) {207switch (Localization->language) {208case LANGUAGE_FR: return UIBUTTONPROMPT_KEYBOARD_FR;209case LANGUAGE_IT: return UIBUTTONPROMPT_KEYBOARD_IT;210case LANGUAGE_GE: return UIBUTTONPROMPT_KEYBOARD_GE;211case LANGUAGE_SP: return UIBUTTONPROMPT_KEYBOARD_SP;212default: return UIBUTTONPROMPT_KEYBOARD;213}214}215else if (deviceType == DEVICE_TYPE_CONTROLLER) {216// I don't actually think saturn type is ever set in-engine, neat that it exists though217218switch (gamepadType & 0xFF) {219case DEVICE_XBOX: return UIBUTTONPROMPT_XBOX;220case DEVICE_PS4: return UIBUTTONPROMPT_PS4;221case DEVICE_SATURN: return UIBUTTONPROMPT_SATURN_WHITE;222case DEVICE_SWITCH_HANDHELD:223case DEVICE_SWITCH_JOY_GRIP:224case DEVICE_SWITCH_PRO: return UIBUTTONPROMPT_SWITCH;225case DEVICE_SWITCH_JOY_L: return UIBUTTONPROMPT_JOYCON_L;226case DEVICE_SWITCH_JOY_R: return UIBUTTONPROMPT_JOYCON_R;227default: break;228}229}230return UIBUTTONPROMPT_XBOX;231}232233uint8 UIButtonPrompt_MappingsToFrame(int32 mappings)234{235#if GAME_VERSION != VER_100236switch (mappings) {237case KEYMAP_BACK: return 14;238case KEYMAP_TAB: return 15;239case KEYMAP_RETURN: return 41;240case KEYMAP_SHIFT:241case KEYMAP_LSHIFT: return 42;242case KEYMAP_CONTROL:243case KEYMAP_LCONTROL: return 54;244case KEYMAP_MENU:245case KEYMAP_LMENU: return 55;246case KEYMAP_CAPITAL: return 29;247case KEYMAP_SPACE: return 56;248case KEYMAP_PRIOR: return 91;249case KEYMAP_NEXT: return 92;250case KEYMAP_END: return 93;251case KEYMAP_HOME: return 94;252case KEYMAP_LEFT: return 61;253case KEYMAP_UP: return 59;254case KEYMAP_RIGHT: return 62;255case KEYMAP_DOWN: return 60;256case KEYMAP_INSERT: return 95;257case KEYMAP_DELETE: return 96;258case KEYMAP_0: return 11;259case KEYMAP_1: return 2;260case KEYMAP_2: return 3;261case KEYMAP_3: return 4;262case KEYMAP_4: return 5;263case KEYMAP_5: return 6;264case KEYMAP_6: return 7;265case KEYMAP_7: return 8;266case KEYMAP_8: return 9;267case KEYMAP_9: return 10;268case KEYMAP_A: return 30;269case KEYMAP_B: return 47;270case KEYMAP_C: return 45;271case KEYMAP_D: return 32;272case KEYMAP_E: return 18;273case KEYMAP_F: return 33;274case KEYMAP_G: return 34;275case KEYMAP_H: return 35;276case KEYMAP_I: return 23;277case KEYMAP_J: return 36;278case KEYMAP_K: return 37;279case KEYMAP_L: return 38;280case KEYMAP_M: return 49;281case KEYMAP_N: return 48;282case KEYMAP_O: return 24;283case KEYMAP_P: return 25;284case KEYMAP_Q: return 16;285case KEYMAP_R: return 19;286case KEYMAP_S: return 31;287case KEYMAP_T: return 20;288case KEYMAP_U: return 22;289case KEYMAP_V: return 46;290case KEYMAP_W: return 17;291case KEYMAP_X: return 44;292case KEYMAP_Y: return 21;293case KEYMAP_Z: return 43;294case KEYMAP_NUMPAD0: return 77;295case KEYMAP_NUMPAD1: return 73;296case KEYMAP_NUMPAD2: return 74;297case KEYMAP_NUMPAD3: return 75;298case KEYMAP_NUMPAD4: return 70;299case KEYMAP_NUMPAD5: return 71;300case KEYMAP_NUMPAD6: return 72;301case KEYMAP_NUMPAD7: return 66;302case KEYMAP_NUMPAD8: return 67;303case KEYMAP_NUMPAD9: return 68;304case KEYMAP_MULTIPLY: return 64;305case KEYMAP_ADD: return 69;306case KEYMAP_SUBTRACT: return 65;307case KEYMAP_DECIMAL: return 78;308case KEYMAP_DIVIDE: return 63;309case KEYMAP_RSHIFT: return 53;310case KEYMAP_RCONTROL: return 58;311case KEYMAP_RMENU: return 57;312case KEYMAP_OEM_1: return 79;313case KEYMAP_OEM_PLUS: return 87;314case KEYMAP_OEM_COMMA: return 88;315case KEYMAP_OEM_MINUS: return 89;316case KEYMAP_OEM_PERIOD: return 90;317case KEYMAP_OEM_2: return 80;318case KEYMAP_OEM_3: return 81;319case KEYMAP_OEM_4: return 82;320case KEYMAP_OEM_5: return 83;321case KEYMAP_OEM_6: return 84;322case KEYMAP_OEM_7: return 85;323case KEYMAP_OEM_8: return 86;324default: return 0;325}326#else327switch (mappings) {328case KEYMAP_BACK: return 14;329case KEYMAP_TAB: return 15;330case KEYMAP_RETURN: return 41;331case KEYMAP_SHIFT:332case KEYMAP_LSHIFT: return 42;333case KEYMAP_CONTROL:334case KEYMAP_LCONTROL: return 54;335case KEYMAP_MENU: return 55;336case KEYMAP_CAPITAL: return 29;337case KEYMAP_SPACE: return 56;338case KEYMAP_LEFT: return 61;339case KEYMAP_UP: return 59;340case KEYMAP_RIGHT: return 62;341case KEYMAP_DOWN: return 60;342case KEYMAP_0: return 11;343case KEYMAP_1: return 2;344case KEYMAP_2: return 3;345case KEYMAP_3: return 4;346case KEYMAP_4: return 5;347case KEYMAP_5: return 6;348case KEYMAP_6: return 7;349case KEYMAP_7: return 8;350case KEYMAP_8: return 9;351case KEYMAP_9: return 10;352case KEYMAP_A: return 30;353case KEYMAP_B: return 47;354case KEYMAP_C: return 45;355case KEYMAP_D: return 32;356case KEYMAP_E: return 18;357case KEYMAP_F: return 33;358case KEYMAP_G: return 34;359case KEYMAP_H: return 35;360case KEYMAP_I: return 23;361case KEYMAP_J: return 36;362case KEYMAP_K: return 37;363case KEYMAP_L: return 38;364case KEYMAP_M: return 49;365case KEYMAP_N: return 48;366case KEYMAP_O: return 24;367case KEYMAP_P: return 25;368case KEYMAP_Q: return 16;369case KEYMAP_R: return 19;370case KEYMAP_S: return 31;371case KEYMAP_T: return 20;372case KEYMAP_U: return 22;373case KEYMAP_V: return 46;374case KEYMAP_W: return 17;375case KEYMAP_X: return 44;376case KEYMAP_Y: return 21;377case KEYMAP_Z: return 43;378case KEYMAP_NUMPAD0: return 77;379case KEYMAP_NUMPAD1: return 73;380case KEYMAP_NUMPAD2: return 74;381case KEYMAP_NUMPAD3: return 75;382case KEYMAP_NUMPAD4: return 70;383case KEYMAP_NUMPAD5: return 71;384case KEYMAP_NUMPAD6: return 72;385case KEYMAP_NUMPAD7: return 66;386case KEYMAP_NUMPAD8: return 67;387case KEYMAP_NUMPAD9: return 68;388case KEYMAP_MULTIPLY: return 64;389case KEYMAP_ADD: return 69;390case KEYMAP_SUBTRACT: return 65;391case KEYMAP_DECIMAL: return 78;392case KEYMAP_DIVIDE: return 63;393case KEYMAP_RSHIFT: return 53;394case KEYMAP_RCONTROL: return 58;395default: return 0;396}397#endif398return 0;399}400401void UIButtonPrompt_SetButtonSprites(void)402{403RSDK_THIS(UIButtonPrompt);404405if (SceneInfo->inEditor) {406RSDK.SetSpriteAnimation(UIButtonPrompt->aniFrames, UIBUTTONPROMPT_XBOX, &self->buttonAnimator, true, self->buttonID);407}408else {409int32 buttonID = self->buttonID;410if (API_GetConfirmButtonFlip() && buttonID <= 1)411buttonID ^= 1;412413#if MANIA_USE_PLUS414if (UIButtonPrompt->type != UIBUTTONPROMPT_KEYBOARD415&& (UIButtonPrompt->type < UIBUTTONPROMPT_KEYBOARD_FR || UIButtonPrompt->type > UIBUTTONPROMPT_KEYBOARD_SP)) {416RSDK.SetSpriteAnimation(UIButtonPrompt->aniFrames, UIButtonPrompt->type, &self->buttonAnimator, true, buttonID);417}418else {419// despite different languages existing here, the english one is always the one used420int32 mappings = UIButtonPrompt_GetButtonMappings(UIButtonPrompt->inputSlot, buttonID);421int32 frame = UIButtonPrompt_MappingsToFrame(mappings);422RSDK.SetSpriteAnimation(UIButtonPrompt->aniFrames, UIBUTTONPROMPT_KEYBOARD, &self->buttonAnimator, true, frame);423}424#else425426if (sku_platform != PLATFORM_PC && sku_platform != PLATFORM_DEV) {427RSDK.SetSpriteAnimation(UIButtonPrompt->aniFrames, UIButtonPrompt->type, &self->buttonAnimator, true, buttonID);428}429else {430int32 mappings = UIButtonPrompt_GetButtonMappings(UIButtonPrompt->inputSlot, buttonID);431if (UIButtonPrompt->type == UIBUTTONPROMPT_XBOX) {432RSDK.SetSpriteAnimation(UIButtonPrompt->aniFrames, UIBUTTONPROMPT_XBOX, &self->buttonAnimator, true, buttonID);433}434else {435int32 frame = UIButtonPrompt_MappingsToFrame(mappings);436RSDK.SetSpriteAnimation(UIButtonPrompt->aniFrames, UIBUTTONPROMPT_KEYBOARD, &self->buttonAnimator, true, frame);437}438}439#endif440}441}442443bool32 UIButtonPrompt_CheckTouch(void)444{445RSDK_THIS(UIButtonPrompt);446447EntityUIControl *control = (EntityUIControl *)self->parent;448if (control && !control->dialogHasFocus && !control->selectionDisabled) {449if (TouchInfo->count) {450int32 screenX = (ScreenInfo->position.x << 16);451int32 screenY = (ScreenInfo->position.y << 16);452int32 sizeX = self->touchSize.x >> 1;453int32 sizeY = self->touchSize.y >> 1;454455bool32 wasTouched = false;456for (int32 i = 0; i < TouchInfo->count; ++i) {457int32 x = screenX - ((TouchInfo->x[i] * ScreenInfo->size.x) * -65536.0f);458int32 y = screenY - ((TouchInfo->y[i] * ScreenInfo->size.y) * -65536.0f);459460int32 touchX = abs(self->touchPos.x + self->position.x - x);461int32 touchY = abs(self->touchPos.y + self->position.y - y);462if (touchX < sizeX && touchY < sizeY) {463wasTouched = true;464}465}466467self->touched = wasTouched;468}469else {470if (self->touched) {471self->timer = 0;472self->state = UIButtonPrompt_State_Selected;473}474self->touched = false;475}476}477478return self->touched;479}480481void UIButtonPrompt_State_CheckIfSelected(void)482{483RSDK_THIS(UIButtonPrompt);484485if (self->visible) {486if (UIButtonPrompt_CheckTouch()) {487self->scaleMax = 0x280;488489if (self->scaleSpeed < 0x10)490self->scaleSpeed = 0x10;491}492else if (!self->disableScale) {493self->scaleMax = 0x200;494}495}496}497498void UIButtonPrompt_State_Selected(void)499{500RSDK_THIS(UIButtonPrompt);501502self->scaleMax = 0x280;503504if (++self->timer == 16) {505self->timer = 0;506self->textVisible = true;507self->state = UIButtonPrompt_State_CheckIfSelected;508509int32 buttonID = self->buttonID;510if (API_GetConfirmButtonFlip() && buttonID <= 1)511buttonID ^= 1;512513UIControl_ClearInputs(buttonID);514}515516self->textVisible = !((self->timer >> 1) & 1);517}518519#if GAME_INCLUDE_EDITOR520void UIButtonPrompt_EditorDraw(void)521{522RSDK_THIS(UIButtonPrompt);523524self->startPos = self->position;525self->drawGroup = 2;526self->disableScale = false;527self->updateRange.x = 0x2000000;528self->updateRange.y = 0x800000;529self->textVisible = true;530RSDK.SetSpriteAnimation(UIButtonPrompt->aniFrames, 0, &self->decorAnimator, true, 0);531RSDK.SetSpriteAnimation(UIWidgets->textFrames, 0, &self->promptAnimator, true, self->promptID);532533UIButtonPrompt_SetButtonSprites();534self->textSprite = UIWidgets->textFrames;535536UIButtonPrompt_Draw();537}538539void UIButtonPrompt_EditorLoad(void)540{541UIButtonPrompt->aniFrames = RSDK.LoadSpriteAnimation("UI/Buttons.bin", SCOPE_STAGE);542543RSDK_ACTIVE_VAR(UIButtonPrompt, buttonID);544RSDK_ENUM_VAR("A", UIBUTTONPROMPT_BUTTON_A);545RSDK_ENUM_VAR("B", UIBUTTONPROMPT_BUTTON_B);546RSDK_ENUM_VAR("X", UIBUTTONPROMPT_BUTTON_X);547RSDK_ENUM_VAR("Y", UIBUTTONPROMPT_BUTTON_Y);548RSDK_ENUM_VAR("Start", UIBUTTONPROMPT_BUTTON_START);549RSDK_ENUM_VAR("Select", UIBUTTONPROMPT_BUTTON_SELECT);550551RSDK_ACTIVE_VAR(UIButtonPrompt, headingAnchor);552RSDK_ENUM_VAR("None", UIBUTTONPROMPT_ANCHOR_NONE);553RSDK_ENUM_VAR("Top-Left (Row 1)", UIBUTTONPROMPT_ANCHOR_TOPLEFT_ROW1);554RSDK_ENUM_VAR("Top-Right (Row 1)", UIBUTTONPROMPT_ANCHOR_TOPRIGHT_ROW1);555RSDK_ENUM_VAR("Top-Left (Row 2)", UIBUTTONPROMPT_ANCHOR_TOPLEFT_ROW2);556RSDK_ENUM_VAR("Top-Right (Row 2)", UIBUTTONPROMPT_ANCHOR_TOPRIGHT_ROW2);557}558#endif559560void UIButtonPrompt_Serialize(void)561{562RSDK_EDITABLE_VAR(UIButtonPrompt, VAR_ENUM, promptID);563RSDK_EDITABLE_VAR(UIButtonPrompt, VAR_ENUM, buttonID);564RSDK_EDITABLE_VAR(UIButtonPrompt, VAR_UINT8, headingAnchor);565}566567568