28 # error This is a userspace-only header, not allowed by the current build.
31 #include <sifteo/menu/types.h>
40 inline Menu::Menu(
VideoBuffer &vid,
const MenuAssets *aAssets, MenuItem *aItems)
42 init(vid, aAssets, aItems);
45 inline void Menu::init(
VideoBuffer &vid,
const MenuAssets *aAssets, MenuItem *aItems)
48 hasBeenStarted =
false;
50 currentEvent.type = MENU_UNEVENTFUL;
53 changeState(MENU_STATE_START);
62 while (items[i].icon !=
NULL) {
63 if (kIconTileWidth == 0) {
64 kIconTileWidth = items[i].icon->tileWidth();
65 kIconTileHeight = items[i].icon->tileHeight();
66 kEndCapPadding = (kNumVisibleTilesX - kIconTileWidth) * (TILE / 2.f);
67 ASSERT((kItemPixelWidth() - kIconPixelWidth()) % TILE == 0);
69 ASSERT(items[i].icon->tileWidth() == kIconTileWidth);
70 ASSERT(items[i].icon->tileHeight() == kIconTileHeight);
74 if (items[i].label !=
NULL) {
75 ASSERT(items[i].label->tileWidth() == kNumVisibleTilesX);
76 if (kHeaderHeight == 0) {
77 kHeaderHeight = items[i].label->tileHeight();
79 ASSERT(items[i].label->tileHeight() == kHeaderHeight);
95 while (assets->tips[i] !=
NULL) {
96 ASSERT(assets->tips[i]->tileWidth() == kNumVisibleTilesX);
97 if (kFooterHeight == 0) {
98 kFooterHeight = assets->tips[i]->tileHeight();
100 ASSERT(assets->tips[i]->tileHeight() == kFooterHeight);
107 ASSERT(assets->background);
108 ASSERT(assets->background->tileWidth() == 1 && assets->background->tileHeight() == 1);
109 if (assets->footer) {
110 ASSERT(assets->footer->tileWidth() == kNumVisibleTilesX);
111 if (kFooterHeight == 0) {
112 kFooterHeight = assets->footer->tileHeight();
114 ASSERT(assets->footer->tileHeight() == kFooterHeight);
118 if (assets->header) {
119 ASSERT(assets->header->tileWidth() == kNumVisibleTilesX);
120 if (kHeaderHeight == 0) {
121 kHeaderHeight = assets->header->tileHeight();
123 ASSERT(assets->header->tileHeight() == kHeaderHeight);
132 setIconYOffset(kDefaultIconYOffset);
133 setPeekTiles(kDefaultPeekTiles);
141 inline CubeID Menu::cube()
const
143 return vid ? vid->
cube() : CubeID();
146 inline bool Menu::pollEvent(
struct MenuEvent *ev)
149 ASSERT(currentEvent.type != MENU_PREPAINT);
156 if (dispatchEvent(ev)) {
157 return (ev->type != MENU_EXIT);
164 if (currentState != MENU_STATE_START) {
167 if (dispatchEvent(ev)) {
168 return (ev->type != MENU_EXIT);
172 const float kAccelScalingFactor = -0.25f;
173 accel = kAccelScalingFactor * vid->virtualAccel().xy();
176 switch (currentState) {
177 case MENU_STATE_START:
180 case MENU_STATE_STATIC:
183 case MENU_STATE_TILTING:
186 case MENU_STATE_INERTIA:
189 case MENU_STATE_FINISH:
192 case MENU_STATE_HOP_UP:
195 case MENU_STATE_PAN_TARGET:
196 transFromPanTarget();
199 if (dispatchEvent(ev)) {
200 return (ev->type != MENU_EXIT);
204 switch (currentState) {
205 case MENU_STATE_START:
208 case MENU_STATE_STATIC:
211 case MENU_STATE_TILTING:
214 case MENU_STATE_INERTIA:
217 case MENU_STATE_FINISH:
220 case MENU_STATE_HOP_UP:
223 case MENU_STATE_PAN_TARGET:
227 if (dispatchEvent(ev)) {
228 return (ev->type != MENU_EXIT);
233 currentEvent.type = MENU_PREPAINT;
238 inline void Menu::reset()
240 changeState(MENU_STATE_START);
243 inline void Menu::replaceIcon(uint8_t item,
const AssetImage *icon,
const AssetImage *label)
247 items[item].icon = icon;
248 for (
int i = prev_ut; i < prev_ut + kNumTilesX; i++)
249 if (itemVisibleAtCol(item, i))
253 uint8_t currentItem = computeSelected();
254 items[item].label = label;
256 if (kHeaderHeight && currentState == MENU_STATE_STATIC &&
259 const AssetImage& label = items[currentItem].label
260 ? *items[currentItem].label
262 vid->bg1.image(
vec(0,0), label);
267 inline bool Menu::itemVisible(uint8_t item)
269 ASSERT(item >= 0 && item < numItems);
271 for (
int i =
MAX(0, prev_ut); i < prev_ut + kNumTilesX; i++) {
272 if (itemVisibleAtCol(item, i))
return true;
277 inline void Menu::setIconYOffset(uint8_t px)
279 ASSERT(px >= 0 || px < kNumTilesX * 8);
285 inline void Menu::setPeekTiles(uint8_t numTiles)
287 ASSERT(numTiles >= 1 || numTiles * 2 < kNumTilesX);
288 kPeekTiles = numTiles;
301 inline void Menu::anchor(uint8_t item,
bool hopUp, int8_t panTarget)
305 targetItem = panTarget;
308 position = stoppingPositionFor(startingItem);
309 prev_ut = computeCurrentTile() + kNumTilesX;
312 changeState(MENU_STATE_HOP_UP);
321 inline bool Menu::isTilted()
323 const float robustThreshold = kAccelThresholdOn * 1.3;
324 return (
abs(accel.x) >= robustThreshold);
327 inline bool Menu::isHorizontal()
329 const float robustThreshold = kAccelThresholdOn * 0.3;
330 return (
abs(accel.x) < robustThreshold);
333 inline bool Menu::isAtEdge()
335 uint8_t item = computeSelected();
336 return (item == 0 || item == numItems - 1);
339 inline bool Menu::isTiltingAtEdge()
345 uint8_t item = computeSelected();
346 int8_t direction = accel.x > 0 ? 1 : -1;
348 return ((direction < 0 && item == 0) ||
349 (direction > 0 && item == numItems - 1));
352 inline void Menu::setNumTips(uint8_t nt)
359 inline int Menu::getCurrentTip()
361 ASSERT(currentTip < numTips);
#define ASSERT(_x)
Runtime debug assertion.
Definition: macros.h:205
T abs(const T &value)
For any type, return the absolute value.
Definition: math.h:90
#define MAX(a, b)
Definition: macros.h:350
A memory buffer which holds graphics data.
Definition: video.h:145
#define NULL
Definition: macros.h:356
CubeID cube() const
Get the CubeID that this buffer is currently attached to.
Definition: video.h:181
Vector2< T > vec(T x, T y)
Create a Vector2, from a set of (x,y) coordinates.
Definition: math.h:658