Path: blob/master/SonicMania/Objects/Menu/UICarousel.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: UICarousel Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89#if MANIA_USE_PLUS10ObjectUICarousel *UICarousel;1112void UICarousel_Update(void) {}1314void UICarousel_LateUpdate(void)15{16RSDK_THIS(UICarousel);1718if (self->parent) {19UICarousel_HandleScrolling();20UICarousel_HandleButtonPositions();2122self->offset.x -= self->offset.x >> 2;23self->offset.y -= self->offset.y >> 2;2425if (abs(self->offset.y) <= 0x10000)26self->offset.y = 0;27}28}2930void UICarousel_StaticUpdate(void) {}3132void UICarousel_Draw(void) {}3334void UICarousel_Create(void *data)35{36RSDK_THIS(UICarousel);3738if (!SceneInfo->inEditor) {39self->startPos.x = self->position.x;40self->startPos.y = self->position.y;41self->active = ACTIVE_BOUNDS;4243self->unused1 = 0;44self->unused2 = 0;45self->unused3 = 0;46self->unused4 = 0;4748self->visible = false;49self->updateRange.x = 0x800000;50self->updateRange.y = 0x800000;51self->scrollOffset = -1;52self->buttonID = -1;53self->minOffset = 0;54self->maxOffset = 20;55}56}5758void UICarousel_StageLoad(void) {}5960void UICarousel_HandleScrolling(void)61{62RSDK_THIS(UICarousel);6364EntityUIControl *control = (EntityUIControl *)self->parent;65int32 buttonID = self->buttonID;6667if (control->buttonID != buttonID) {68int32 max = control->buttonCount - 1;69bool32 movedUp = false;70bool32 movedDown = false;7172if (buttonID != -1) {73if (!buttonID && control->buttonID == max) {74movedUp = true;75}76else if (buttonID == max && !control->buttonID) {77movedDown = true;78}79else {80if (control->buttonID < buttonID)81movedUp = true;82else if (control->buttonID > buttonID)83movedDown = true;84}85}8687// Bug Details:88// This is HORRIBLY broken when using touch controls89// the virtual scrolling expects buttons to only be incremented one at a time90// HOWEVER, using touch you can jump to any visible button, which can be jumping 2 or more buttons at a time!!91// as a result of that, the scrollOffset & virtualIndex will become misaligned from the visual buttonID and mess up controls and visuals92// Fix:93// find a way to increment by however many buttons we jumped, rather than just by 194// this is slightly harder than it sounds due to the virtual scroll & wrapping being applied9596int32 scrollOffset = self->scrollOffset;97if (movedUp) {98--self->virtualIndex;99self->scrollOffset = self->virtualIndex - (control->buttonCount >> 1);100}101else if (movedDown) {102++self->virtualIndex;103self->scrollOffset = self->virtualIndex - (control->buttonCount >> 1);104}105106if (self->maxOffset != -1) {107if (self->scrollOffset + control->buttonCount > self->maxOffset + 1)108self->scrollOffset = self->maxOffset - control->buttonCount + 1;109110if (self->virtualIndex > self->maxOffset - 1) {111self->virtualIndex = self->maxOffset - 1;112control->buttonID = buttonID;113}114}115116if (self->minOffset != -1) {117if (self->scrollOffset < self->minOffset - 1)118self->scrollOffset = self->minOffset - 1;119120if (self->virtualIndex < self->minOffset) {121self->virtualIndex = self->minOffset;122control->buttonID = buttonID;123}124}125126if (self->scrollOffset >= scrollOffset) {127if (self->scrollOffset > scrollOffset)128self->offset.y += abs(self->shift.y);129130self->buttonID = control->buttonID;131}132else {133self->offset.y -= abs(self->shift.y);134self->buttonID = control->buttonID;135}136}137}138139void UICarousel_HandleButtonPositions(void)140{141RSDK_THIS(UICarousel);142143EntityUIControl *control = (EntityUIControl *)self->parent;144145Vector2 positions[0x10];146memset(positions, 0, sizeof(positions));147148for (int32 i = 0; i < control->buttonCount; ++i) {149positions[i].x = self->position.x;150positions[i].y = self->position.y - (self->shift.y * i);151}152153for (int32 i = 0; i < control->buttonCount; ++i) {154EntityUIButton *item = control->buttons[i];155156int32 id = (i - self->scrollOffset) % control->buttonCount;157if (id < 0)158id += control->buttonCount;159160item->position.x = positions[id].x + self->offset.x;161item->position.y = positions[id].y + self->offset.y;162item->drawGroup = id - control->buttonCount + 12;163}164}165166#if GAME_INCLUDE_EDITOR167void UICarousel_EditorDraw(void)168{169RSDK_THIS(UICarousel);170171DrawHelpers_DrawRectOutline(self->position.x + self->clipOffset.x, self->position.y + self->clipOffset.y, self->clipSize.x, self->clipSize.y,1720xFF0000);173}174175void UICarousel_EditorLoad(void) {}176#endif177178void UICarousel_Serialize(void)179{180RSDK_EDITABLE_VAR(UICarousel, VAR_VECTOR2, shift);181RSDK_EDITABLE_VAR(UICarousel, VAR_VECTOR2, clipSize);182RSDK_EDITABLE_VAR(UICarousel, VAR_VECTOR2, clipOffset);183}184#endif185186187