Nugget
Bare-metal libraries and examples for the original PlayStation
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) { m_target += FixedPoint<>(items, int32_t(0)); }
146
153 void activate();
154
156 void update(const Trig<>& trig);
157
158 unsigned currentIndex() const { return m_selected; }
159 unsigned visibleCount() const { return m_slotCount; }
161 const Slot& slot(unsigned n) const { return m_slots[n]; }
163 const Cursor& cursor() const { return m_cursor; }
165 Angle cursorAngle() const { return m_cursorAngle; }
166
167 private:
168 // Slide BOTH by whole laps together, so their difference (which is what the
169 // settle animation rides on) is untouched and neither can drift out of range
170 // after a few million frames of cranking.
171 void normalize();
172
173 unsigned wrap(int32_t i) const;
174
175 unsigned resolve() const {
176 FixedPoint<> half(int32_t(0), int32_t(FixedPoint<>::scale / 2));
177 return wrap((m_position + half).integer<int32_t>());
178 }
179
180 void emit(Event e) {
181 if (m_callback) m_callback(e);
182 }
183
184 void build(const Trig<>& trig);
185
186 FixedPoint<> fadeFor(FixedPoint<> d) const;
187
188 static Vertex vtx(FixedPoint<> x, FixedPoint<> y) {
189 return Vertex{{.x = int16_t(x.integer<int32_t>()), .y = int16_t(y.integer<int32_t>())}};
190 }
191
192 Vertex at(FixedPoint<> r, FixedPoint<> cosT, FixedPoint<> sinT) const {
193 int16_t x = int16_t(m_config.center.x + (r * cosT).integer<int32_t>());
194 int16_t y = int16_t(m_config.center.y + (r * sinT).integer<int32_t>());
195 return Vertex{{.x = x, .y = y}};
196 }
197
198 Config m_config;
199 eastl::function<void(Event)> m_callback = nullptr;
200 Angle m_cursorAngle;
201 FixedPoint<> m_angleStep;
202 FixedPoint<> m_position;
203 FixedPoint<> m_target;
204 Cursor m_cursor = {};
205 Slot m_slots[c_maxSlots];
206 unsigned m_slotCount = 0;
207 unsigned m_itemCount = 0;
208 unsigned m_selected = 0;
209};
210
211} // 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:161
const Cursor & cursor() const
Where to draw the cursor marker, just inside the ring at the cursor angle.
Definition helix-selector.hh:163
Angle cursorAngle() const
The cursor's current angle, if you want to orient the marker you draw.
Definition helix-selector.hh:165
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:158
unsigned visibleCount() const
Definition helix-selector.hh:159
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:310
int i
Definition gte-regio.c:299
Definition lua.hh:40
FixedPoint< 10 > Angle
A fixed point angle.
Definition trigonometry.hh:48
char e[1]
Definition string.c:119
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
The Vertex struct.
Definition common.hh:47
int16_t y
Definition common.hh:53
int16_t x
Definition common.hh:50