mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-27 14:37:16 +00:00
device orientation-based scrolling on mobiles
This commit is contained in:
parent
bd77680518
commit
6c0a052470
@ -629,7 +629,7 @@ void achievement_final(bool really_final) {
|
||||
specific_improved = 0;
|
||||
specific_what = 0;
|
||||
|
||||
if(specials == 0) improveItemScores();
|
||||
if(specialcode == 0) improveItemScores();
|
||||
|
||||
int tg = gold();
|
||||
if(tg && haveLeaderboard(sid)) {
|
||||
|
@ -661,7 +661,7 @@ void showGraphConfig() {
|
||||
char xuni = uni | 96;
|
||||
|
||||
if(uni >= 32 && uni < 64) xuni = uni;
|
||||
|
||||
|
||||
if(xuni == 'u') vid.particles = !vid.particles;
|
||||
if(xuni == 'd') vid.graphglyph = (1+vid.graphglyph)%3;
|
||||
|
||||
@ -829,6 +829,8 @@ void showBasicConfig() {
|
||||
|
||||
dialog::addBoolItem(XLAT("forget faraway cells"), memory_saving_mode, 'y');
|
||||
|
||||
dialog::addSelItem(XLAT("scrolling by device rotation"), ors::choices[ors::mode], '1');
|
||||
|
||||
if(CAP_SHMUP && !ISMOBILE)
|
||||
dialog::addSelItem(XLAT("configure keys/joysticks"), "", 'p');
|
||||
|
||||
@ -846,6 +848,8 @@ void showBasicConfig() {
|
||||
|
||||
if(uni >= 32 && uni < 64) xuni = uni;
|
||||
|
||||
if(xuni == '1') pushScreen(ors::show);
|
||||
|
||||
if(uni == 'M') vid.quickmouse = !vid.quickmouse;
|
||||
else if(xuni == 'm') vid.skipstart = !vid.skipstart;
|
||||
|
||||
@ -1467,5 +1471,5 @@ int read_gamemode_args() {
|
||||
|
||||
auto ah_config = addHook(hooks_args, 0, read_config_args) + addHook(hooks_args, 0, read_gamemode_args);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
141
control.cpp
141
control.cpp
@ -517,6 +517,7 @@ void mainloopiter() {
|
||||
if(timetowait > 0)
|
||||
SDL_Delay(timetowait);
|
||||
else {
|
||||
ors::check_orientation();
|
||||
if(cmode & sm::CENTER) {
|
||||
if(playermoved && vid.sspeed > -4.99 && !outoffocus)
|
||||
centerpc((ticks - lastt) / 1000.0 * exp(vid.sspeed));
|
||||
@ -908,4 +909,144 @@ bool handleCompass() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// orientation sensitivity
|
||||
namespace ors {
|
||||
|
||||
int mode;
|
||||
double sensitivity = 1;
|
||||
|
||||
int when_enabled;
|
||||
transmatrix last_orientation;
|
||||
transmatrix relative_matrix = Id;
|
||||
|
||||
string choices[3] = {"OFF", "relative", "absolute"};
|
||||
|
||||
#if CAP_ORIENTATION
|
||||
transmatrix getOrientation() {
|
||||
return MirrorX * MirrorZ * hr::getOrientation() * MirrorX * MirrorZ;
|
||||
}
|
||||
#endif
|
||||
|
||||
void reset() {
|
||||
#if CAP_ORIENTATION
|
||||
if(mode) last_orientation = getOrientation();
|
||||
relative_matrix = Id;
|
||||
#endif
|
||||
}
|
||||
|
||||
void delayed_reset() {
|
||||
#if CAP_ORIENTATION
|
||||
relative_matrix = Id; when_enabled = ticks;
|
||||
#endif
|
||||
}
|
||||
|
||||
void show() {
|
||||
#if CAP_ORIENTATION
|
||||
cmode = sm::SIDE;
|
||||
gamescreen(0);
|
||||
|
||||
dialog::init(XLAT("scrolling by device rotation"));
|
||||
|
||||
dialog::addHelp(XLAT(
|
||||
"This lets you scroll the map by rotating your device. It can be e.g. used to "
|
||||
"play the spherical mode of HyperRogue in mobile VR goggles -- the \"spherical VR\" "
|
||||
"button configures this; this VR mode can be disabled by touching the screen for 1 second."));
|
||||
|
||||
dialog::addSelItem(XLAT("mode"), choices[mode], 'm');
|
||||
dialog::add_action([] () { int m = (mode + 1) % 3; mode = 0; fullcenter(); mode = m; delayed_reset(); });
|
||||
dialog::addSelItem(XLAT("sensitivity"), fts(sensitivity), 's');
|
||||
dialog::add_action([] () {
|
||||
dialog::editNumber(sensitivity, -10, 10, 1, 1, XLAT("sensitivity"),
|
||||
XLAT("1 means that rotating the device by 1 radian corresponds to scrolling by 1 unit. In spherical geometry, 1 unit = 1 radian."));
|
||||
});
|
||||
|
||||
dialog::addBreak(100);
|
||||
|
||||
dialog::addItem(XLAT("stereo vision config"), 'e');
|
||||
dialog::add_action([] () { pushScreen(showStereo); });
|
||||
|
||||
dialog::addItem(XLAT("experiment with geometry"), 'g');
|
||||
dialog::add_action([] () { runGeometryExperiments(); });
|
||||
|
||||
dialog::addSelItem(XLAT("projection"), fts(vid.alpha), 'p');
|
||||
dialog::add_action([] () { projectionDialog(); });
|
||||
|
||||
dialog::addSelItem(XLAT("scale factor"), fts(vid.scale), 'z');
|
||||
dialog::add_action([] () { editScale(); });
|
||||
|
||||
dialog::addItem(XLAT("spherical VR"), 'v');
|
||||
dialog::add_action([] () {
|
||||
if(!sphere) { targetgeometry = gSphere; restart_game(rg::geometry); }
|
||||
mode = 0; fullcenter();
|
||||
mode = 2; sensitivity = 1;
|
||||
stereo::mode = sLR; stereo::ipd = 0.2;
|
||||
vid.alpha = 0; vid.scale = 1;
|
||||
});
|
||||
|
||||
dialog::addBreak(100);
|
||||
|
||||
dialog::addBack();
|
||||
|
||||
dialog::display();
|
||||
#endif
|
||||
}
|
||||
|
||||
void relative_apply() {
|
||||
if(ors::mode == 1) View = relative_matrix * View;
|
||||
}
|
||||
|
||||
void relative_unapply() {
|
||||
if(ors::mode == 1) View = inverse(relative_matrix) * View;
|
||||
}
|
||||
|
||||
transmatrix change_geometry(const transmatrix& T) {
|
||||
if(sphere && sensitivity == 1) return T;
|
||||
ld alpha, beta, push;
|
||||
|
||||
{
|
||||
dynamicval<eGeometry> g(geometry, gSphere);
|
||||
hyperpoint h = T * C0;
|
||||
push = hdist0(h);
|
||||
alpha = atan2(h[1], h[0]);
|
||||
if(push == 0) alpha = 0;
|
||||
hyperpoint spinpoint = gpushxto0(h) * T * xpush(1) * C0;
|
||||
beta = atan2(spinpoint[1], spinpoint[0]);
|
||||
}
|
||||
|
||||
// gpushxto0(h) * T * xpush(1) * C0 == spin(beta) * xpush(1) * C0
|
||||
// gpushxto0(h) * T == spin(beta)
|
||||
// T = rgpushxto0(h) * spin(beta)
|
||||
|
||||
|
||||
transmatrix U = spin(-alpha) * xpush(push * sensitivity) * spin(-beta+alpha);
|
||||
|
||||
return U;
|
||||
}
|
||||
|
||||
void unrotate(transmatrix& T) {
|
||||
if(mode == 1) T = inverse(relative_matrix) * T;
|
||||
}
|
||||
|
||||
void rerotate(transmatrix& T) {
|
||||
if(mode == 1) T = (relative_matrix) * T;
|
||||
}
|
||||
|
||||
void check_orientation() {
|
||||
#if CAP_ORIENTATION
|
||||
if(!mode) return;
|
||||
if(ticks < when_enabled + 500) {
|
||||
last_orientation = getOrientation();
|
||||
return;
|
||||
}
|
||||
transmatrix next_orientation = MirrorX * getOrientation();
|
||||
transmatrix T = inverse(next_orientation) * last_orientation;
|
||||
if(mode == 1) unrotate(View), unrotate(cwtV);
|
||||
relative_matrix = change_geometry(T);
|
||||
if(mode == 1) rerotate(View), rerotate(cwtV);
|
||||
if(mode == 2) View = relative_matrix * View, last_orientation = next_orientation;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
12
hyper.h
12
hyper.h
@ -3727,4 +3727,16 @@ extern void switchHardcore();
|
||||
extern bool using_perspective;
|
||||
|
||||
void generateAlts(heptagon *h, int levs = irr::on ? 1 : S3-3, bool link_cdata = true);
|
||||
|
||||
namespace ors {
|
||||
extern int mode;
|
||||
extern string choices[];
|
||||
void show();
|
||||
void apply();
|
||||
void check_orientation();
|
||||
void unrotate(transmatrix& T);
|
||||
void rerotate(transmatrix& T);
|
||||
void reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -242,6 +242,9 @@ const transmatrix Mirror = {{{1,0,0}, {0,-1,0}, {0,0,1}}};
|
||||
// mirror image
|
||||
const transmatrix MirrorX = {{{-1,0,0}, {0,1,0}, {0,0,1}}};
|
||||
|
||||
// mirror image
|
||||
const transmatrix MirrorZ = {{{1,0,0}, {0,1,0}, {0,0,-1}}};
|
||||
|
||||
// rotate by PI
|
||||
const transmatrix pispin = {{{-1,0,0}, {0,-1,0}, {0,0,1}}};
|
||||
|
||||
|
@ -730,8 +730,12 @@ void spinEdge(ld aspd) {
|
||||
}
|
||||
|
||||
void centerpc(ld aspd) {
|
||||
if(ors::mode == 2 && vid.sspeed < 5) return;
|
||||
if(vid.sspeed >= 4.99) aspd = 1000;
|
||||
DEBB(DF_GRAPH, (debugfile,"center pc\n"));
|
||||
|
||||
ors::unrotate(cwtV); ors::unrotate(View);
|
||||
|
||||
hyperpoint H = ypush(-vid.yshift) * sphereflip * tC0(cwtV);
|
||||
ld R = H[0] == 0 && H[1] == 0 ? 0 : hdist0(H); // = sqrt(H[0] * H[0] + H[1] * H[1]);
|
||||
if(R < 1e-9) {
|
||||
@ -741,6 +745,7 @@ void centerpc(ld aspd) {
|
||||
} */
|
||||
spinEdge(aspd);
|
||||
fixmatrix(View);
|
||||
ors::rerotate(cwtV); ors::rerotate(View);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -766,6 +771,8 @@ void centerpc(ld aspd) {
|
||||
fixmatrix(View);
|
||||
spinEdge(aspd);
|
||||
}
|
||||
|
||||
ors::rerotate(cwtV); ors::rerotate(View);
|
||||
}
|
||||
|
||||
void optimizeview() {
|
||||
|
12
init.cpp
12
init.cpp
@ -168,6 +168,7 @@ void handleclick(MOBPAR_FORMAL) {
|
||||
if(andmode == 0 && shmup::on) ; // just fire, do not change modes
|
||||
else {
|
||||
if(andmode == 1) {
|
||||
ors::reset();
|
||||
centerpc(INF);
|
||||
View = Id;
|
||||
viewctr.h = cwt.c->master;
|
||||
@ -235,6 +236,8 @@ void mobile_draw(MOBPAR_FORMAL) {
|
||||
if(lastt > ticks) lastt = ticks;
|
||||
int tdiff = ticks - lastt;
|
||||
|
||||
ors::check_orientation();
|
||||
|
||||
if(playermoved && vid.sspeed > -4.99)
|
||||
centerpc(tdiff / 1000.0 * exp(vid.sspeed));
|
||||
|
||||
@ -287,6 +290,11 @@ void mobile_draw(MOBPAR_FORMAL) {
|
||||
#endif
|
||||
mouseh = gethyper(mousex, mousey);
|
||||
|
||||
inmenu = isize(screens) > 1;
|
||||
|
||||
if(!inmenu && stereo::mode == stereo::sLR && ors::mode)
|
||||
mousex = vid.xres/2, mousey = vid.yres/2, mouseh = sphereflip * C0;
|
||||
|
||||
// if(debfile) fprintf(debfile, "d1\n"), fflush(debfile);
|
||||
frames++;
|
||||
if(conformal::on) conformal::apply();
|
||||
@ -303,8 +311,6 @@ void mobile_draw(MOBPAR_FORMAL) {
|
||||
shiftmul = getcshift;
|
||||
calcMousedest();
|
||||
|
||||
inmenu = isize(screens) > 1;
|
||||
|
||||
if(lclicked && !clicked && !inmenu) handleclick(MOBPAR_ACTUAL);
|
||||
|
||||
if(inmenu && !clicked && !lclicked) inmenu = false;
|
||||
@ -336,6 +342,8 @@ void mobile_draw(MOBPAR_FORMAL) {
|
||||
if(lclicked && !clicked) {
|
||||
if(rug::rugged)
|
||||
rug::select();
|
||||
else if(ors::mode && !longclick)
|
||||
normal_reaction = true;
|
||||
else
|
||||
pushScreen(showStereo);
|
||||
}
|
||||
|
@ -1176,6 +1176,7 @@ void switch_game_mode(char switchWhat) {
|
||||
break;
|
||||
|
||||
case rg::geometry:
|
||||
ors::reset();
|
||||
if(geometry == targetgeometry) geometry = gNormal;
|
||||
else geometry = targetgeometry;
|
||||
if(chaosmode && (euclid || sphere || quotient)) chaosmode = false;
|
||||
|
Loading…
Reference in New Issue
Block a user