Nugget
Loading...
Searching...
No Matches
helix-selector.hh
Go to the documentation of this file.
1/*
2
3MIT License
4
5Copyright (c) 2026 PCSX-Redux authors
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26
27#pragma once
28
29#include <EASTL/functional.h>
30#include <stdint.h>
31
32#include "psyqo/fixed-point.hh"
34#include "psyqo/trigonometry.hh"
35
36namespace psyqo {
37
69 public:
70 struct Event {
72 unsigned index;
73 };
74
84 struct Slot {
85 unsigned index;
86 Vertex a, b, c, d;
88 FixedPoint<> scale;
89 FixedPoint<> fade;
90 };
91
100 struct Cursor {
102 };
103
104 struct Config {
105 Vertex center = {{.x = 160, .y = 120}};
106 FixedPoint<> innerRadius = 44.0; // cylinder radii, before projection
107 FixedPoint<> outerRadius = 68.0;
108 FixedPoint<> cameraDistance = 128.0; // h in the r = R * h / z divide
109 FixedPoint<> cursorZ = 150.0; // z of the item under the cursor
110 FixedPoint<> pitch = 10.0; // z travelled per item
111 FixedPoint<> gap = 0.88; // fraction of the angular step drawn
112 FixedPoint<> settleRate = 0.3; // per frame, toward the target
113 unsigned itemsPerTurn = 20;
114 // How much helix is on screen, in items. Since spokes are fixed, these do
115 // not decide WHETHER two quads share an angle - `i` and `i + itemsPerTurn`
116 // always do - they decide how many LAPS of that are visible either side of
117 // the cursor. `(nearSpan + farSpan + 1) / itemsPerTurn` turns, roughly.
118 unsigned nearSpan = 13; // items emitted toward the camera
119 unsigned farSpan = 13; // items emitted away from it
120 unsigned fadeItems = 5; // far-end fade ramp, in items
121 FixedPoint<> cursorGap = 5.0; // from the inner ring to the marker's tip
122 FixedPoint<> cursorLength = 9.0; // tip to base, along the spoke
123 FixedPoint<> cursorHalfWidth = 5.0;
124 };
125
126 static constexpr unsigned c_maxSlots = 48;
127
128 void setup(unsigned itemCount, const Config& config);
129
130 void setOnEvent(eastl::function<void(Event)>&& callback) { m_callback = eastl::move(callback); }
131
142 void setStickAngle(Angle a);
143
145 void step(int32_t items) {
146 m_target += FixedPoint<>(items, int32_t(0));
147 }
148
155 void activate();
156
158 void update(const Trig<>& trig);
159
160 unsigned currentIndex() const { return m_selected; }
161 unsigned visibleCount() const { return m_slotCount; }
163 const Slot& slot(unsigned n) const { return m_slots[n]; }
165 const Cursor& cursor() const { return m_cursor; }
167 Angle cursorAngle() const { return m_cursorAngle; }
168
169 private:
170 // Slide BOTH by whole laps together, so their difference (which is what the
171 // settle animation rides on) is untouched and neither can drift out of range
172 // after a few million frames of cranking.
173 void normalize();
174
175 unsigned wrap(int32_t i) const;
176
177 unsigned resolve() const {
178 FixedPoint<> half(int32_t(0), int32_t(FixedPoint<>::scale / 2));
179 return wrap((m_position + half).integer<int32_t>());
180 }
181
182 void emit(Event e) {
183 if (m_callback) m_callback(e);
184 }
185
186 void build(const Trig<>& trig);
187
188 FixedPoint<> fadeFor(FixedPoint<> d) const;
189
190 static Vertex vtx(FixedPoint<> x, FixedPoint<> y) {
191 return Vertex{{.x = int16_t(x.integer<int32_t>()), .y = int16_t(y.integer<int32_t>())}};
192 }
193
194 Vertex at(FixedPoint<> r, FixedPoint<> cosT, FixedPoint<> sinT) const {
195 int16_t x = int16_t(m_config.center.x + (r * cosT).integer<int32_t>());
196 int16_t y = int16_t(m_config.center.y + (r * sinT).integer<int32_t>());
197 return Vertex{{.x = x, .y = y}};
198 }
199
200 Config m_config;
201 eastl::function<void(Event)> m_callback = nullptr;
202 Angle m_cursorAngle;
203 FixedPoint<> m_angleStep;
204 FixedPoint<> m_position;
205 FixedPoint<> m_target;
206 Cursor m_cursor = {};
207 Slot m_slots[c_maxSlots];
208 unsigned m_slotCount = 0;
209 unsigned m_itemCount = 0;
210 unsigned m_selected = 0;
211};
212
213} // namespace psyqo
A helix selector, seen down its own axis.
Definition helix-selector.hh:68
const Slot & slot(unsigned n) const
Slot 0 is the furthest from the camera. Draw them in order.
Definition helix-selector.hh:163
const Cursor & cursor() const
Where to draw the cursor marker, just inside the ring at the cursor angle.
Definition helix-selector.hh:165
Angle cursorAngle() const
The cursor's current angle, if you want to orient the marker you draw.
Definition helix-selector.hh:167
static constexpr unsigned c_maxSlots
Definition helix-selector.hh:126
void setup(unsigned itemCount, const Config &config)
Definition helix-selector.cpp:31
unsigned currentIndex() const
Definition helix-selector.hh:160
unsigned visibleCount() const
Definition helix-selector.hh:161
void setStickAngle(Angle a)
Crank by an absolute stick angle.
Definition helix-selector.cpp:48
void update(const Trig<> &trig)
Settle one frame and rebuild the visible slots.
Definition helix-selector.cpp:74
void step(int32_t items)
Crank by whole items. This is the d-pad adapter.
Definition helix-selector.hh:145
void setOnEvent(eastl::function< void(Event)> &&callback)
Definition helix-selector.hh:130
void activate()
Your confirm button's rising edge.
Definition helix-selector.cpp:64
A trigonometry table.
Definition trigonometry.hh:74
uint32_t r
Definition cpu.c:222
int n
Definition dcache.c:225
int i
Definition gte-regio.c:287
Definition lua.hh:38
FixedPoint< 10 > Angle
A fixed point angle.
Definition trigonometry.hh:48
Definition helix-selector.hh:104
FixedPoint innerRadius
Definition helix-selector.hh:106
unsigned farSpan
Definition helix-selector.hh:119
FixedPoint outerRadius
Definition helix-selector.hh:107
FixedPoint gap
Definition helix-selector.hh:111
FixedPoint settleRate
Definition helix-selector.hh:112
FixedPoint cursorZ
Definition helix-selector.hh:109
FixedPoint pitch
Definition helix-selector.hh:110
unsigned itemsPerTurn
Definition helix-selector.hh:113
unsigned nearSpan
Definition helix-selector.hh:118
FixedPoint cursorGap
Definition helix-selector.hh:121
FixedPoint cameraDistance
Definition helix-selector.hh:108
FixedPoint cursorHalfWidth
Definition helix-selector.hh:123
FixedPoint cursorLength
Definition helix-selector.hh:122
unsigned fadeItems
Definition helix-selector.hh:120
Vertex center
Definition helix-selector.hh:105
The cursor marker, as a triangle you can draw directly.
Definition helix-selector.hh:100
Vertex tip
Definition helix-selector.hh:101
Vertex left
Definition helix-selector.hh:101
Vertex right
Definition helix-selector.hh:101
Definition helix-selector.hh:70
unsigned index
Definition helix-selector.hh:72
Type
Definition helix-selector.hh:71
@ SelectionChanged
Definition helix-selector.hh:71
@ Activated
Definition helix-selector.hh:71
enum psyqo::HelixSelector::Event::Type type
One visible item.
Definition helix-selector.hh:84
unsigned index
Definition helix-selector.hh:85
Vertex a
Definition helix-selector.hh:86
Vertex b
Definition helix-selector.hh:86
Vertex glyph
Definition helix-selector.hh:87
Vertex d
Definition helix-selector.hh:86
FixedPoint fade
Definition helix-selector.hh:89
Vertex c
Definition helix-selector.hh:86
FixedPoint scale
Definition helix-selector.hh:88
void void(ptr, size)
The Vertex struct.
Definition common.hh:47
int16_t y
Definition common.hh:53
int16_t x
Definition common.hh:50