Path: blob/master/SonicMania/Objects/Menu/UIChoice.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: UIChoice Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectUIChoice *UIChoice;1011void UIChoice_Update(void)12{13RSDK_THIS(UIChoice);1415EntityUIButton *parent = (EntityUIButton *)self->parent;16bool32 disabled = self->disabled;1718self->touchPosSizeS.x = self->size.x;19self->touchPosSizeS.y = self->size.y;20self->touchPosOffsetS.y = 0;21self->touchPosSizeS.x = (self->touchPosSizeS.x + 3 * self->size.y) >> 1;22self->touchPosSizeS.y = self->size.y + 0x60000;23self->touchPosOffsetS.x = -(self->touchPosSizeS.x >> 1);2425if (parent && (disabled || parent->disabled))26disabled = true;2728if (self->aniFrames != UIWidgets->textFrames || self->isDisabled != disabled) {29if (disabled)30RSDK.SetSpriteAnimation(UIWidgets->textFrames, 7, &self->labelAnimator, true, 0);31else32RSDK.SetSpriteAnimation(UIWidgets->textFrames, self->listID, &self->labelAnimator, true, self->frameID);3334self->aniFrames = UIWidgets->textFrames;35self->isDisabled = disabled;36}3738StateMachine_Run(self->state);3940if (parent && parent->state == UIButton_State_HandleButtonLeave) {41self->textBounceOffset = 0;42self->buttonBounceOffset = 0;43self->isSelected = false;44self->state = UIChoice_State_HandleButtonLeave;45}46}4748void UIChoice_LateUpdate(void) {}4950void UIChoice_StaticUpdate(void) {}5152void UIChoice_Draw(void)53{54RSDK_THIS(UIChoice);5556Vector2 drawPos;57int32 size = (self->size.x + self->size.y) >> 16;5859drawPos.x = self->position.x;60drawPos.y = self->position.y;61drawPos.x -= self->buttonBounceOffset;62drawPos.y -= self->buttonBounceOffset;63#if MANIA_USE_PLUS64UIWidgets_DrawParallelogram(drawPos.x, drawPos.y, size, self->size.y >> 16, self->bgEdgeSize, (UIWidgets->buttonColor >> 16) & 0xFF,65(UIWidgets->buttonColor >> 8) & 0xFF, (UIWidgets->buttonColor) & 0xFF);66#else67UIWidgets_DrawParallelogram(drawPos.x, drawPos.y, size, self->size.y >> 16, self->bgEdgeSize, 0xF0, 0xF0, 0xF0);68#endif6970drawPos.x = self->position.x;71drawPos.y = self->position.y;72drawPos.x += self->buttonBounceOffset;73drawPos.y += self->buttonBounceOffset;74UIWidgets_DrawParallelogram(drawPos.x, drawPos.y, size, self->size.y >> 16, self->bgEdgeSize, 0x00, 0x00, 0x00);7576EntityUIButton *parent = (EntityUIButton *)self->parent;77if (self->arrowWidth > 0 && self->isSelected && !(self->disabled || parent->disabled)) {78drawPos.x = self->position.x;79drawPos.y = self->position.y;80drawPos.y += self->textBounceOffset;81drawPos.x -= self->arrowWidth << 15;82drawPos.x += self->buttonBounceOffset;83drawPos.y += self->buttonBounceOffset;84RSDK.DrawSprite(&self->leftArrowAnimator, &drawPos, false);8586drawPos.x = self->position.x;87drawPos.y = self->position.y;88drawPos.y += self->textBounceOffset;89drawPos.x += self->arrowWidth << 15;90drawPos.x += self->buttonBounceOffset;91drawPos.y += self->buttonBounceOffset;92RSDK.DrawSprite(&self->rightArrowAnimator, &drawPos, false);93}9495if (self->textVisible) {96drawPos.x = self->position.x;97drawPos.y = self->position.y;98drawPos.y = self->textBounceOffset + self->position.y;99drawPos.x = self->buttonBounceOffset + self->position.x;100drawPos.y += self->buttonBounceOffset;101102switch (self->align) {103case UIBUTTON_ALIGN_LEFT: drawPos.x += -0x60000 - (self->size.x >> 1); break;104105default:106case UIBUTTON_ALIGN_CENTER: break;107108case UIBUTTON_ALIGN_RIGHT: drawPos.x += (self->size.x >> 1) - 0x60000; break;109}110111if (self->auxIcon)112RSDK.DrawSprite(&self->iconAnimator, &drawPos, false);113114if (!self->noText)115RSDK.DrawSprite(&self->labelAnimator, &drawPos, false);116}117}118119void UIChoice_Create(void *data)120{121RSDK_THIS(UIChoice);122123if (!SceneInfo->inEditor) {124self->visible = true;125self->drawGroup = 2;126self->active = ACTIVE_NEVER;127self->updateRange.x = 0x800000;128self->updateRange.y = 0x400000;129self->bgEdgeSize = self->size.y >> 16;130self->size.y = abs(self->size.y);131self->textVisible = true;132133self->touchCB = UIChoice_CheckTouch;134135self->aniFrames = UIWidgets->textFrames;136RSDK.SetSpriteAnimation(UIWidgets->textFrames, self->listID, &self->labelAnimator, true, self->frameID);137RSDK.SetSpriteAnimation(UIChoice->aniFrames, self->auxListID, &self->iconAnimator, true, self->auxFrameID);138RSDK.SetSpriteAnimation(UIWidgets->uiFrames, 2, &self->leftArrowAnimator, true, 0);139RSDK.SetSpriteAnimation(UIWidgets->uiFrames, 2, &self->rightArrowAnimator, true, 1);140}141}142143void UIChoice_StageLoad(void) { UIChoice->aniFrames = RSDK.LoadSpriteAnimation("UI/SaveSelect.bin", SCOPE_STAGE); }144145void UIChoice_SetChoiceActive(EntityUIChoice *choice)146{147if (choice) {148EntityUIButton *parent = (EntityUIButton *)choice->parent;149150choice->active = ACTIVE_BOUNDS;151if (!parent->disabled)152choice->visible = true;153154choice->textBounceOffset = 0;155choice->buttonBounceOffset = 0;156choice->textBounceVelocity = -0x20000;157choice->buttonBounceVelocity = -0x20000;158choice->isSelected = true;159choice->state = UIChoice_State_HandleButtonEnter;160}161}162163void UIChoice_SetChoiceInactive(EntityUIChoice *choice)164{165if (choice) {166choice->textBounceOffset = 0;167choice->buttonBounceOffset = 0;168choice->isSelected = false;169choice->state = UIChoice_State_HandleButtonLeave;170}171}172173void UIChoice_TouchedCB_Left(void)174{175RSDK_THIS(UIChoice);176177EntityUIButton *parent = (EntityUIButton *)self->parent;178179int32 selection = parent->selection;180if (--selection < 0) {181while (selection < 0) selection += parent->choiceCount;182}183EntityUIButton *choice = UIButton_GetChoicePtr(parent, selection);184185while ((choice && choice->disabled) && selection != parent->selection) {186if (--selection < 0) {187while (selection < 0) selection += parent->choiceCount;188}189190choice = UIButton_GetChoicePtr(parent, selection);191}192193if (selection != parent->selection) {194UIButton_SetChoiceSelectionWithCB(parent, selection);195RSDK.PlaySfx(UIWidgets->sfxBleep, false, 255);196}197}198199void UIChoice_TouchedCB_Right(void)200{201RSDK_THIS(UIChoice);202203EntityUIButton *parent = (EntityUIButton *)self->parent;204205int32 selection = (parent->selection + 1) % parent->choiceCount;206EntityUIButton *choice = UIButton_GetChoicePtr(parent, selection);207208while ((choice && choice->disabled) && selection != parent->selection) {209selection = (selection + 1) % parent->choiceCount;210choice = UIButton_GetChoicePtr(parent, selection);211}212213if (selection != parent->selection) {214UIButton_SetChoiceSelectionWithCB(parent, selection);215RSDK.PlaySfx(UIWidgets->sfxBleep, false, 255);216}217}218219bool32 UIChoice_CheckTouch(void)220{221RSDK_THIS(UIChoice);222223void (*callbacks[2])(void);224Vector2 touchStart[2];225Vector2 touchEnd[2];226227callbacks[0] = UIChoice_TouchedCB_Left;228callbacks[1] = UIChoice_TouchedCB_Right;229230touchStart[0].x = self->touchPosSizeS.x;231touchStart[0].y = self->touchPosSizeS.y;232touchStart[1].x = self->touchPosSizeS.x;233touchStart[1].y = self->touchPosSizeS.y;234235touchEnd[0].x = self->touchPosOffsetS.x;236touchEnd[0].y = self->touchPosOffsetS.y;237touchEnd[1].x = -self->touchPosOffsetS.x;238touchEnd[1].y = self->touchPosOffsetS.y;239240bool32 pressed = false;241for (int32 i = 0; i < 2; ++i) {242if (TouchInfo->count) {243int32 sizeX = touchStart[i].x >> 1;244int32 sizeY = touchStart[i].y >> 1;245246for (int32 t = 0; t < TouchInfo->count; ++t) {247int32 x = (ScreenInfo->position.x << 16) - ((TouchInfo->x[t] * ScreenInfo->size.x) * -65536.0f);248int32 y = (ScreenInfo->position.y << 16) - ((TouchInfo->y[t] * ScreenInfo->size.y) * -65536.0f);249250int32 touchX = abs(touchEnd[i].x + self->position.x - x);251int32 touchY = abs(touchEnd[i].y + self->position.y - y);252if (touchX < sizeX && touchY < sizeY) {253self->touchID = i;254pressed = true;255}256}257}258else if (self->touchPressed && self->touchID == i && !self->disabled) {259#if RETRO_USE_MOD_LOADER260StateMachine_Run(callbacks[i]);261#else262callbacks[i]();263#endif264}265}266267self->touchPressed = pressed;268269return pressed;270}271272void UIChoice_State_HandleButtonLeave(void)273{274RSDK_THIS(UIChoice);275276if (self->textBounceOffset) {277int32 offset = -(self->textBounceOffset / abs(self->textBounceOffset));278self->textBounceOffset += offset << 15;279280if (offset < 0 && self->textBounceOffset < 0)281self->textBounceOffset = 0;282else if (offset > 0 && self->textBounceOffset > 0)283self->textBounceOffset = 0;284}285286if (self->buttonBounceOffset) {287int32 offset = -(self->buttonBounceOffset / abs(self->buttonBounceOffset));288self->buttonBounceOffset += offset << 16;289290if (offset < 0 && self->buttonBounceOffset < 0)291self->buttonBounceOffset = 0;292else if (offset > 0 && self->buttonBounceOffset > 0)293self->buttonBounceOffset = 0;294}295}296297void UIChoice_State_HandleButtonEnter(void)298{299RSDK_THIS(UIChoice);300301self->textBounceVelocity += 0x4000;302self->textBounceOffset += self->textBounceVelocity;303304if (self->textBounceOffset >= 0 && self->textBounceVelocity > 0) {305self->textBounceOffset = 0;306self->textBounceVelocity = 0;307}308309self->buttonBounceVelocity += 0x4800;310self->buttonBounceOffset += self->buttonBounceVelocity;311312if (self->buttonBounceOffset >= -0x20000 && self->buttonBounceVelocity > 0) {313self->buttonBounceOffset = -0x20000;314self->buttonBounceVelocity = 0;315}316}317318#if GAME_INCLUDE_EDITOR319void UIChoice_EditorDraw(void)320{321RSDK_THIS(UIChoice);322323int32 sizeY = self->size.y;324325self->drawGroup = 2;326self->updateRange.x = 0x800000;327self->updateRange.y = 0x400000;328self->bgEdgeSize = self->size.y >> 16;329self->size.y = abs(self->size.y);330self->textVisible = true;331self->aniFrames = UIWidgets->textFrames;332333RSDK.SetSpriteAnimation(UIWidgets->textFrames, self->listID, &self->labelAnimator, true, self->frameID);334RSDK.SetSpriteAnimation(UIChoice->aniFrames, self->auxListID, &self->iconAnimator, true, self->auxFrameID);335RSDK.SetSpriteAnimation(UIWidgets->uiFrames, 2, &self->leftArrowAnimator, true, 0);336RSDK.SetSpriteAnimation(UIWidgets->uiFrames, 2, &self->rightArrowAnimator, true, 1);337338self->isSelected = showGizmos();339// Crash prevention340self->parent = (Entity *)self;341342UIChoice_Draw();343344self->size.y = sizeY;345}346347void UIChoice_EditorLoad(void)348{349UIChoice->aniFrames = RSDK.LoadSpriteAnimation("UI/SaveSelect.bin", SCOPE_STAGE);350351RSDK_ACTIVE_VAR(UIChoice, align);352RSDK_ENUM_VAR("Left", UIBUTTON_ALIGN_LEFT);353RSDK_ENUM_VAR("Center", UIBUTTON_ALIGN_CENTER);354RSDK_ENUM_VAR("Right", UIBUTTON_ALIGN_RIGHT);355}356#endif357358void UIChoice_Serialize(void)359{360RSDK_EDITABLE_VAR(UIChoice, VAR_BOOL, disabled);361RSDK_EDITABLE_VAR(UIChoice, VAR_VECTOR2, size);362RSDK_EDITABLE_VAR(UIChoice, VAR_ENUM, listID);363RSDK_EDITABLE_VAR(UIChoice, VAR_ENUM, frameID);364RSDK_EDITABLE_VAR(UIChoice, VAR_BOOL, noText);365RSDK_EDITABLE_VAR(UIChoice, VAR_BOOL, auxIcon);366RSDK_EDITABLE_VAR(UIChoice, VAR_ENUM, auxListID);367RSDK_EDITABLE_VAR(UIChoice, VAR_ENUM, auxFrameID);368RSDK_EDITABLE_VAR(UIChoice, VAR_ENUM, align);369RSDK_EDITABLE_VAR(UIChoice, VAR_ENUM, arrowWidth);370}371372373