2018-02-08 23:40:26 +00:00
|
|
|
// Hyperbolic Rogue -- control
|
|
|
|
// Copyright (C) 2011-2018 Zeno Rogue, see 'hyper.cpp' for details
|
|
|
|
|
2018-06-10 23:58:31 +00:00
|
|
|
namespace hr {
|
|
|
|
|
2017-07-10 18:47:38 +00:00
|
|
|
int frames;
|
|
|
|
bool outoffocus = false;
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX int mousex, mousey;
|
|
|
|
EX hyperpoint mouseh, mouseoh;
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX bool leftclick, rightclick, targetclick, hiliteclick, anyshiftclick, wheelclick;
|
|
|
|
EX bool forcetarget, lshiftclick, lctrlclick, numlock_on;
|
|
|
|
EX bool gtouched;
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2019-08-09 21:39:36 +00:00
|
|
|
EX bool holdmouse;
|
2017-11-06 22:22:13 +00:00
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX int getcstat, lgetcstat;
|
2019-08-09 21:39:36 +00:00
|
|
|
EX ld getcshift;
|
2019-08-09 19:00:52 +00:00
|
|
|
EX bool inslider;
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2019-08-09 20:07:03 +00:00
|
|
|
EX function <void(int sym, int uni)> keyhandler = [] (int sym, int uni) {};
|
|
|
|
EX function <bool(SDL_Event &ev)> joyhandler = [] (SDL_Event &ev) {return false;};
|
2018-11-18 02:18:11 +00:00
|
|
|
|
2019-08-09 21:39:36 +00:00
|
|
|
#if HDR
|
|
|
|
// what part of the compass does 'skip turn'
|
|
|
|
static const auto SKIPFAC = .4;
|
|
|
|
#endif
|
2017-07-10 18:47:38 +00:00
|
|
|
|
|
|
|
// is the player using mouse? (used for auto-cross)
|
2019-08-09 19:00:52 +00:00
|
|
|
EX bool mousing = true;
|
2017-07-10 18:47:38 +00:00
|
|
|
|
|
|
|
// is the mouse button pressed?
|
2019-08-09 19:00:52 +00:00
|
|
|
EX bool mousepressed = false;
|
|
|
|
EX bool mousemoved = false;
|
|
|
|
EX bool actonrelease = false;
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2019-05-29 13:41:55 +00:00
|
|
|
bool mousepan, oldmousepan;
|
2019-06-28 07:47:10 +00:00
|
|
|
#if CAP_MOUSEGRAB
|
2019-08-09 19:00:52 +00:00
|
|
|
EX ld mouseaim_x, mouseaim_y;
|
2019-06-28 07:47:10 +00:00
|
|
|
#endif
|
2019-08-09 19:00:52 +00:00
|
|
|
EX ld mouseaim_sensitivity = 0.01;
|
2019-05-29 13:41:55 +00:00
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX int timetowait;
|
2018-07-22 10:50:03 +00:00
|
|
|
|
2017-07-22 23:33:27 +00:00
|
|
|
#if CAP_SDLJOY
|
2019-08-09 20:07:03 +00:00
|
|
|
EX int joyx, joyy, panjoyx, panjoyy;
|
|
|
|
EX movedir joydir;
|
2017-07-22 23:33:27 +00:00
|
|
|
#endif
|
|
|
|
|
2019-08-09 20:07:03 +00:00
|
|
|
EX movedir mousedest;
|
|
|
|
EX ld shiftmul = 1;
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX cell *mouseover, *mouseover2, *lmouseover;
|
2017-07-10 18:47:38 +00:00
|
|
|
ld modist, modist2, centdist;
|
|
|
|
|
|
|
|
int lastt;
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX bool mouseout() {
|
2017-07-10 18:47:38 +00:00
|
|
|
if((getcstat != '-' && getcstat) || (lgetcstat && lgetcstat != '-')) return true;
|
|
|
|
return outofmap(mouseh);
|
|
|
|
}
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX bool mouseout2() {
|
2017-07-10 18:47:38 +00:00
|
|
|
if((getcstat && getcstat != '-') || (lgetcstat && lgetcstat != '-')) return true;
|
|
|
|
return outofmap(mouseh) || outofmap(mouseoh);
|
|
|
|
}
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX movedir vectodir(const hyperpoint& P) {
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2018-08-17 22:46:45 +00:00
|
|
|
transmatrix U = ggmatrix(cwt.at);
|
2019-06-25 18:02:11 +00:00
|
|
|
if(GDIM == 3 && WDIM == 2) U = radar_transform * U;
|
2019-08-06 10:00:46 +00:00
|
|
|
if(nisot::local_perspective_used()) U = nisot::local_perspective * U;
|
2018-07-16 18:06:09 +00:00
|
|
|
|
|
|
|
hyperpoint H = sphereflip * tC0(U);
|
2018-07-23 14:07:27 +00:00
|
|
|
transmatrix Centered = sphereflip * rgpushxto0(H);
|
2018-07-16 18:06:09 +00:00
|
|
|
|
2017-07-10 18:47:38 +00:00
|
|
|
ld binv = 99;
|
|
|
|
|
2017-10-27 18:07:58 +00:00
|
|
|
ld dirdist[MAX_EDGE];
|
2018-07-16 18:06:09 +00:00
|
|
|
|
2018-08-17 22:46:45 +00:00
|
|
|
for(int i=0; i<cwt.at->type; i++) {
|
2018-07-16 18:06:09 +00:00
|
|
|
transmatrix T;
|
2018-09-10 16:46:09 +00:00
|
|
|
if(compute_relamatrix((cwt+i).peek(), cwt.at, i, T)) {
|
2018-07-16 18:06:09 +00:00
|
|
|
dirdist[i] = intval(U * T * C0, Centered * P);
|
|
|
|
}
|
2018-08-17 22:46:45 +00:00
|
|
|
//xspinpush0(-i * 2 * M_PI /cwt.at->type, .5), P);
|
2017-07-10 18:47:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
movedir res;
|
|
|
|
res.d = -1;
|
|
|
|
|
2018-08-17 22:46:45 +00:00
|
|
|
for(int i=0; i<cwt.at->type; i++) {
|
2017-07-10 18:47:38 +00:00
|
|
|
if(dirdist[i] < binv) {
|
|
|
|
binv = dirdist[i];
|
|
|
|
res.d = i;
|
2018-08-17 22:46:45 +00:00
|
|
|
res.subdir = dirdist[(i+1)%cwt.at->type] < dirdist[(i+cwt.at->type-1)%cwt.at->type] ? 1 : -1;
|
2017-07-10 18:47:38 +00:00
|
|
|
}
|
|
|
|
}
|
2018-07-23 14:07:27 +00:00
|
|
|
|
2017-07-10 18:47:38 +00:00
|
|
|
// if(euclid) bdir = (bdir + 3) % 6;
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX void remission() {
|
2017-09-30 09:36:01 +00:00
|
|
|
if(!canmove && (cmode & sm::NORMAL)) showMissionScreen();
|
|
|
|
}
|
2019-02-26 10:57:50 +00:00
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX hyperpoint move_destination_vec(int d) {
|
2019-06-25 18:02:11 +00:00
|
|
|
if(WDIM == 2) return spin(-d * M_PI/4) * tC0(pushone());
|
|
|
|
// else if(WDIM == 2 && pmodel == mdPerspective) return cspin(0, 2, d * M_PI/4) * tC0(pushone());
|
|
|
|
// else if(WDIM == 2) return spin(-d * M_PI/4) * tC0(pushone());
|
2019-02-27 13:43:15 +00:00
|
|
|
else if(d&1) return cspin(0, 1, d > 4 ? M_PI/2 : -M_PI/2) * tC0(pushone());
|
2019-02-26 10:57:50 +00:00
|
|
|
else return cspin(0, 2, d * M_PI/4) * tC0(pushone());
|
|
|
|
}
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX void movepckeydir(int d) {
|
2019-05-12 23:57:40 +00:00
|
|
|
DEBB(DF_GRAPH, ("movepckeydir\n"));
|
2017-07-10 18:47:38 +00:00
|
|
|
// EUCLIDEAN
|
2019-02-26 10:57:50 +00:00
|
|
|
|
2019-06-06 17:37:17 +00:00
|
|
|
if(protect_memory()) return;
|
|
|
|
|
2019-02-26 10:57:50 +00:00
|
|
|
movedir md = vectodir(move_destination_vec(d));
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2017-09-30 09:36:01 +00:00
|
|
|
if(!canmove) movepcto(md), remission(); else movepcto(md);
|
2017-07-10 18:47:38 +00:00
|
|
|
}
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX void calcMousedest() {
|
2017-07-10 18:47:38 +00:00
|
|
|
if(mouseout()) return;
|
|
|
|
if(vid.revcontrol == true) { mouseh[0] = -mouseh[0]; mouseh[1] = -mouseh[1]; }
|
2018-08-17 22:46:45 +00:00
|
|
|
ld mousedist = intval(mouseh, tC0(ggmatrix(cwt.at)));
|
2017-07-10 18:47:38 +00:00
|
|
|
mousedest.d = -1;
|
|
|
|
|
|
|
|
cellwalker bcwt = cwt;
|
|
|
|
|
2017-10-27 18:07:58 +00:00
|
|
|
ld dists[MAX_EDGE];
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2018-08-17 22:46:45 +00:00
|
|
|
transmatrix U = ggmatrix(cwt.at);
|
2018-07-16 18:06:09 +00:00
|
|
|
|
2018-08-17 22:46:45 +00:00
|
|
|
for(int i=0; i<cwt.at->type; i++) {
|
2018-07-16 18:06:09 +00:00
|
|
|
transmatrix T;
|
2018-08-17 22:46:45 +00:00
|
|
|
if(compute_relamatrix(cwt.at->move(i), cwt.at, i, T))
|
2018-07-16 18:06:09 +00:00
|
|
|
dists[i] = intval(mouseh, U * T * C0);
|
|
|
|
else
|
|
|
|
dists[i] = HUGE_VAL;
|
|
|
|
}
|
2018-08-17 22:46:45 +00:00
|
|
|
// confusingGeometry() ? ggmatrix(cwt.at) * calc_relative_matrix(cwt.at->move(i), cwt.at, i) : shmup::ggmatrix(cwt.at->move(i))));
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2018-08-17 22:46:45 +00:00
|
|
|
for(int i=0; i<cwt.at->type; i++) if(dists[i] < mousedist) {
|
2017-07-10 18:47:38 +00:00
|
|
|
mousedist = dists[i];
|
2019-08-09 12:39:21 +00:00
|
|
|
mousedest.d = cwt.at->c.fix(i - cwt.spin);
|
2017-07-10 18:47:38 +00:00
|
|
|
|
|
|
|
mousedest.subdir =
|
2019-08-09 12:39:21 +00:00
|
|
|
dists[cwt.at->c.fix(i+1)] < dists[cwt.at->c.fix(i-1)] ? 1 : -1;
|
2017-07-10 18:47:38 +00:00
|
|
|
|
|
|
|
if(cwt.mirrored)
|
2019-08-09 12:39:21 +00:00
|
|
|
mousedest.d = cwt.at->c.fix(-mousedest.d),
|
2017-07-10 18:47:38 +00:00
|
|
|
mousedest.subdir = -mousedest.subdir;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(vid.revcontrol == true) { mouseh[0] = -mouseh[0]; mouseh[1] = -mouseh[1]; }
|
|
|
|
cwt = bcwt;
|
|
|
|
}
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX void mousemovement() {
|
2019-06-28 07:57:11 +00:00
|
|
|
if(DIM == 3) {
|
|
|
|
if(WDIM == 2) {
|
|
|
|
if(View[2][2] < -0.75)
|
|
|
|
movepcto(MD_DROP, 1);
|
|
|
|
else if(View[2][2] > 0.75)
|
|
|
|
movepcto(-1, 1);
|
|
|
|
else
|
|
|
|
movepckeydir(6);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
movepckeydir(6);
|
|
|
|
return;
|
|
|
|
}
|
2019-06-06 17:37:17 +00:00
|
|
|
|
|
|
|
if(protect_memory()) return;
|
|
|
|
|
2017-07-10 18:47:38 +00:00
|
|
|
calcMousedest();
|
2017-09-30 09:36:01 +00:00
|
|
|
if(!canmove) movepcto(mousedest), remission(); else movepcto(mousedest);
|
2017-07-10 18:47:38 +00:00
|
|
|
lmouseover = NULL;
|
|
|
|
}
|
|
|
|
|
2017-07-22 23:33:27 +00:00
|
|
|
#if CAP_SDLJOY
|
2019-08-09 20:07:03 +00:00
|
|
|
EX SDL_Joystick* sticks[8];
|
|
|
|
EX int numsticks;
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX void initJoysticks() {
|
2019-05-12 23:57:40 +00:00
|
|
|
DEBB(DF_INIT, ("init joysticks"));
|
2017-07-10 18:47:38 +00:00
|
|
|
numsticks = SDL_NumJoysticks();
|
|
|
|
if(numsticks > 8) numsticks = 8;
|
|
|
|
for(int i=0; i<numsticks; i++) {
|
|
|
|
sticks[i] = SDL_JoystickOpen(i);
|
2017-10-16 16:57:14 +00:00
|
|
|
/* printf("axes = %d, balls = %d, buttons = %d, hats = %d\n",
|
2017-07-10 18:47:38 +00:00
|
|
|
SDL_JoystickNumAxes(sticks[i]),
|
|
|
|
SDL_JoystickNumBalls(sticks[i]),
|
|
|
|
SDL_JoystickNumButtons(sticks[i]),
|
|
|
|
SDL_JoystickNumHats(sticks[i])
|
2017-10-16 16:57:14 +00:00
|
|
|
); */
|
2017-07-10 18:47:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX void closeJoysticks() {
|
2019-05-12 23:57:40 +00:00
|
|
|
DEBB(DF_INIT, ("close joysticks"));
|
2017-07-10 18:47:38 +00:00
|
|
|
for(int i=0; i<numsticks; i++) {
|
|
|
|
SDL_JoystickClose(sticks[i]), sticks[i] = NULL;
|
|
|
|
}
|
|
|
|
numsticks = 0;
|
|
|
|
}
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX void checkjoy() {
|
2019-05-12 23:57:40 +00:00
|
|
|
DEBB(DF_GRAPH, ("check joy"));
|
2017-07-10 18:47:38 +00:00
|
|
|
if(!DEFAULTCONTROL) return;
|
|
|
|
ld joyvalue1 = sqr(vid.joyvalue);
|
|
|
|
ld joyvalue2 = sqr(vid.joyvalue2);
|
|
|
|
|
|
|
|
ld jx = joyx;
|
|
|
|
ld jy = joyy;
|
|
|
|
ld sq = jx*jx+jy*jy;
|
|
|
|
|
|
|
|
static int laststate = 0;
|
|
|
|
int curstate = sq < joyvalue1 ? 0 : sq < joyvalue2 ? 1 : 2;
|
|
|
|
if(curstate != laststate) flashMessages(), laststate = curstate;
|
|
|
|
|
|
|
|
if(autojoy) {
|
|
|
|
if(sq < joyvalue1) { if(joydir.d >= 0) movepcto(joydir); joydir.d = -1; return; }
|
|
|
|
if(sq < joyvalue2 && joydir.d == -1) return;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if(sq < joyvalue1) { joydir.d = -1; return; }
|
|
|
|
}
|
|
|
|
|
|
|
|
joydir = vectodir(hpxy(jx, jy));
|
|
|
|
}
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX void checkpanjoy(double t) {
|
2017-07-10 18:47:38 +00:00
|
|
|
if(shmup::on) return;
|
|
|
|
|
|
|
|
if(vid.joypanspeed < 1e-7) return;
|
|
|
|
|
|
|
|
if(sqr(panjoyx) + sqr(panjoyy) < sqr(vid.joypanthreshold))
|
|
|
|
return;
|
|
|
|
|
|
|
|
ld jx = panjoyx * t * vid.joypanspeed;
|
|
|
|
ld jy = panjoyy * t * vid.joypanspeed;
|
|
|
|
|
|
|
|
playermoved = false;
|
|
|
|
View = gpushxto0(hpxy(jx, jy)) * View;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
bool quitmainloop = false;
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX bool doexiton(int sym, int uni) {
|
2017-07-10 18:47:38 +00:00
|
|
|
if(sym == SDLK_ESCAPE) return true;
|
|
|
|
if(sym == SDLK_F10) return true;
|
2018-01-05 13:16:48 +00:00
|
|
|
if(sym == PSEUDOKEY_RELEASE) return false;
|
2018-12-15 14:17:06 +00:00
|
|
|
#ifndef FAKE_SDL
|
2018-12-13 16:33:49 +00:00
|
|
|
if(sym == SDLK_LSHIFT) return false;
|
|
|
|
if(sym == SDLK_RSHIFT) return false;
|
|
|
|
if(sym == SDLK_LCTRL) return false;
|
|
|
|
if(sym == SDLK_RCTRL) return false;
|
|
|
|
if(sym == SDLK_LALT) return false;
|
|
|
|
if(sym == SDLK_RALT) return false;
|
2018-12-15 14:17:06 +00:00
|
|
|
#endif
|
2017-07-10 18:47:38 +00:00
|
|
|
if(uni != 0) return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-08-09 20:07:03 +00:00
|
|
|
EX bool didsomething;
|
2017-07-10 18:47:38 +00:00
|
|
|
|
|
|
|
typedef SDL_Event eventtype;
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX bool smooth_scrolling = false;
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX void handlePanning(int sym, int uni) {
|
2019-05-29 13:41:55 +00:00
|
|
|
if(mousepan && dual::split([=] { handlePanning(sym, uni); })) return;
|
2019-02-28 17:58:02 +00:00
|
|
|
if(DIM == 3) {
|
|
|
|
if(sym == PSEUDOKEY_WHEELUP) View = cpush(2, -0.05*shiftmul) * View, didsomething = true, playermoved = false;
|
|
|
|
if(sym == PSEUDOKEY_WHEELDOWN) View = cpush(2, 0.05*shiftmul) * View, didsomething = true, playermoved = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(rug::rugged || smooth_scrolling) {
|
|
|
|
return;
|
|
|
|
}
|
2019-02-22 20:37:47 +00:00
|
|
|
|
2017-07-22 23:33:27 +00:00
|
|
|
#if !ISPANDORA
|
2019-02-21 17:46:53 +00:00
|
|
|
if(sym == SDLK_END && DIM == 3) {
|
2019-07-25 10:14:18 +00:00
|
|
|
View = solmul(cpush(2, -0.2*shiftmul), View), didsomething = true, playermoved = false;
|
2019-02-21 17:46:53 +00:00
|
|
|
}
|
2019-02-22 20:37:30 +00:00
|
|
|
if(sym == SDLK_HOME && DIM == 3) {
|
2019-07-25 10:14:18 +00:00
|
|
|
View = solmul(cpush(2, +0.2*shiftmul), View), didsomething = true, playermoved = false;
|
2019-02-22 20:37:30 +00:00
|
|
|
}
|
2017-07-10 18:47:38 +00:00
|
|
|
if(sym == SDLK_RIGHT) {
|
|
|
|
if(conformal::on)
|
|
|
|
conformal::lvspeed += 0.1 * shiftmul;
|
2019-02-21 17:46:53 +00:00
|
|
|
else if(DIM == 3)
|
|
|
|
View = cspin(0, 2, -0.2*shiftmul) * View, didsomething = true;
|
2017-07-10 18:47:38 +00:00
|
|
|
else
|
|
|
|
View = xpush(-0.2*shiftmul) * View, playermoved = false, didsomething = true;
|
|
|
|
}
|
|
|
|
if(sym == SDLK_LEFT) {
|
|
|
|
if(conformal::on)
|
|
|
|
conformal::lvspeed -= 0.1 * shiftmul;
|
2019-02-21 17:46:53 +00:00
|
|
|
else if(DIM == 3)
|
|
|
|
View = cspin(0, 2, 0.2*shiftmul) * View, didsomething = true;
|
2017-07-10 18:47:38 +00:00
|
|
|
else
|
|
|
|
View = xpush(+0.2*shiftmul) * View, playermoved = false, didsomething = true;
|
|
|
|
}
|
|
|
|
if(sym == SDLK_UP) {
|
|
|
|
if(conformal::on)
|
|
|
|
conformal::lvspeed += 0.1 * shiftmul;
|
2019-02-21 17:46:53 +00:00
|
|
|
else if(DIM == 3)
|
|
|
|
View = cspin(1, 2, 0.2*shiftmul) * View, didsomething = true;
|
2017-07-10 18:47:38 +00:00
|
|
|
else
|
|
|
|
View = ypush(+0.2*shiftmul) * View, playermoved = false, didsomething = true;
|
|
|
|
}
|
|
|
|
if(sym == SDLK_DOWN) {
|
|
|
|
if(conformal::on)
|
|
|
|
conformal::lvspeed -= 0.1 * shiftmul;
|
2019-02-21 17:46:53 +00:00
|
|
|
else if(DIM == 3)
|
|
|
|
View = cspin(1, 2, -0.2*shiftmul) * View, didsomething = true;
|
2017-07-10 18:47:38 +00:00
|
|
|
else
|
|
|
|
View = ypush(-0.2*shiftmul) * View, playermoved = false, didsomething = true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if(sym == SDLK_PAGEUP) {
|
|
|
|
if(conformal::on)
|
|
|
|
conformal::rotation++;
|
|
|
|
else
|
2019-05-26 16:04:02 +00:00
|
|
|
View = spin(M_PI/cgi.S21/2*shiftmul) * View, didsomething = true;
|
2017-07-10 18:47:38 +00:00
|
|
|
}
|
|
|
|
if(sym == SDLK_PAGEDOWN) {
|
|
|
|
if(conformal::on)
|
|
|
|
conformal::rotation++;
|
|
|
|
else
|
2019-05-26 16:04:02 +00:00
|
|
|
View = spin(-M_PI/cgi.S21/2*shiftmul) * View, didsomething = true;
|
2017-07-10 18:47:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(sym == SDLK_PAGEUP || sym == SDLK_PAGEDOWN)
|
2018-08-17 22:46:45 +00:00
|
|
|
if(isGravityLand(cwt.at->land)) playermoved = false;
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2019-02-28 17:58:02 +00:00
|
|
|
if(sym == PSEUDOKEY_WHEELUP && DIM == 2) {
|
2018-11-17 18:24:02 +00:00
|
|
|
ld jx = (mousex - current_display->xcenter - .0) / current_display->radius / 10;
|
|
|
|
ld jy = (mousey - current_display->ycenter - .0) / current_display->radius / 10;
|
2017-07-10 18:47:38 +00:00
|
|
|
playermoved = false;
|
|
|
|
View = gpushxto0(hpxy(jx, jy)) * View;
|
|
|
|
sym = 1;
|
|
|
|
}
|
|
|
|
}
|
2017-10-28 23:57:34 +00:00
|
|
|
|
|
|
|
#ifdef SCALETUNER
|
|
|
|
double tunev = .1;
|
|
|
|
|
|
|
|
bool handleTune(int sym, int uni) {
|
|
|
|
if(uni == 'q') { tunev *= .5; return true; }
|
|
|
|
else if(uni == 'e') { tunev *= 2; return true; }
|
|
|
|
else if(uni == 'w') bscale7 += tunev*shiftmul;
|
|
|
|
else if(uni == 's') bscale7 -= tunev*shiftmul;
|
|
|
|
else if(uni == 'a') brot7 -= tunev*shiftmul;
|
|
|
|
else if(uni == 'd') brot7 += tunev*shiftmul;
|
|
|
|
else if(uni == 'i') bscale6 += tunev*shiftmul;
|
|
|
|
else if(uni == 'k') bscale6 -= tunev*shiftmul;
|
|
|
|
else if(uni == 'j') brot6 -= tunev*shiftmul;
|
|
|
|
else if(uni == 'l') brot6 += tunev*shiftmul;
|
|
|
|
else if(uni == 'z')
|
|
|
|
bscale7 = bscale6 = 1, brot7 = brot6 = 0;
|
|
|
|
else return false;
|
2019-05-21 22:03:26 +00:00
|
|
|
println(hlog, spaced(bscale7, brot7, bscale6, brot6));
|
2017-10-28 23:57:34 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif
|
2017-12-01 23:20:35 +00:00
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX purehookset hooks_fixticks;
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX void handleKeyNormal(int sym, int uni) {
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2018-02-12 15:20:47 +00:00
|
|
|
if(cheater && sym < 256 && sym > 0) {
|
2017-07-10 18:47:38 +00:00
|
|
|
if(applyCheat(uni, mouseover))
|
2018-12-13 13:53:44 +00:00
|
|
|
uni = sym = 0;
|
2017-07-10 18:47:38 +00:00
|
|
|
}
|
|
|
|
|
2018-12-15 14:20:27 +00:00
|
|
|
#if CAP_SHOT
|
2018-12-13 13:53:44 +00:00
|
|
|
if(uni == 'A') { pushScreen(shot::menu); uni = sym = 0; }
|
2018-12-15 14:20:27 +00:00
|
|
|
#endif
|
2018-12-13 12:33:08 +00:00
|
|
|
|
2017-07-10 18:47:38 +00:00
|
|
|
if(DEFAULTNOR(sym)) handlePanning(sym, uni);
|
2017-10-28 23:57:34 +00:00
|
|
|
|
|
|
|
#ifdef SCALETUNER
|
|
|
|
if(handleTune(sym, uni)) return;
|
|
|
|
#endif
|
2017-07-10 18:47:38 +00:00
|
|
|
|
|
|
|
if(!(uni >= 'A' && uni <= 'Z') && DEFAULTCONTROL) {
|
|
|
|
if(sym == 'l' || sym == 'd' || sym == SDLK_KP6) movepckeydir(0);
|
|
|
|
if(sym == 'n' || sym == 'c' || sym == SDLK_KP3) movepckeydir(1);
|
|
|
|
if(sym == 'j' || sym == 'x' || sym == SDLK_KP2) movepckeydir(2);
|
|
|
|
if(sym == 'b' || sym == 'z' || sym == SDLK_KP1) movepckeydir(3);
|
|
|
|
if(sym == 'h' || sym == 'a' || sym == SDLK_KP4) movepckeydir(4);
|
|
|
|
if(sym == 'y' || sym == 'q' || sym == SDLK_KP7) movepckeydir(5);
|
|
|
|
if(sym == 'k' || sym == 'w' || sym == SDLK_KP8) movepckeydir(6);
|
|
|
|
if(sym == 'u' || sym == 'e' || sym == SDLK_KP9) movepckeydir(7);
|
|
|
|
}
|
|
|
|
|
2017-07-24 22:21:36 +00:00
|
|
|
#if ISPANDORA
|
2017-07-10 18:47:38 +00:00
|
|
|
if(DEFAULTCONTROL) {
|
|
|
|
if(sym == SDLK_RIGHT) movepckeydir(0);
|
|
|
|
if(sym == SDLK_LEFT) movepckeydir(4);
|
|
|
|
if(sym == SDLK_DOWN) movepckeydir(2 + (leftclick?1:0) - (rightclick?1:0));
|
|
|
|
if(sym == SDLK_UP) movepckeydir(6 - (leftclick?1:0) + (rightclick?1:0));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2018-12-06 10:43:10 +00:00
|
|
|
if(DEFAULTNOR(sym)) {
|
2017-07-10 18:47:38 +00:00
|
|
|
gmodekeys(sym, uni);
|
2018-12-06 10:43:10 +00:00
|
|
|
if(uni == 'm' && canmove && (centerover == cwt ? mouseover : centerover.at))
|
2017-07-10 18:47:38 +00:00
|
|
|
performMarkCommand(mouseover);
|
|
|
|
}
|
|
|
|
|
2018-03-02 12:05:31 +00:00
|
|
|
if(DEFAULTCONTROL) {
|
2017-07-10 18:47:38 +00:00
|
|
|
if(sym == '.' || sym == 's') movepcto(-1, 1);
|
|
|
|
if((sym == SDLK_DELETE || sym == SDLK_KP_PERIOD || sym == 'g') && uni != 'G' && uni != 'G'-64)
|
|
|
|
movepcto(MD_DROP, 1);
|
2017-07-12 17:50:39 +00:00
|
|
|
if(sym == 't' && uni != 'T' && uni != 'T'-64 && canmove) {
|
2017-11-03 19:55:18 +00:00
|
|
|
if(playermoved && items[itStrongWind]) {
|
2018-08-17 22:46:45 +00:00
|
|
|
cell *c = whirlwind::jumpDestination(cwt.at);
|
|
|
|
if(c) centerover.at = c;
|
2017-07-10 18:47:38 +00:00
|
|
|
}
|
2019-03-10 17:39:17 +00:00
|
|
|
targetRangedOrb(DIM == 3 ? mouseover : centerover.at, roKeyboard);
|
2017-07-10 18:47:38 +00:00
|
|
|
sym = 0; uni = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(sym == SDLK_KP5 && DEFAULTCONTROL) movepcto(-1, 1);
|
|
|
|
|
|
|
|
if(sym == SDLK_F5) {
|
2018-05-26 23:06:54 +00:00
|
|
|
#if CAP_DAILY
|
|
|
|
if(daily::on) daily::handleQuit(1);
|
|
|
|
else
|
|
|
|
#endif
|
2017-07-10 18:47:38 +00:00
|
|
|
if(needConfirmation())
|
|
|
|
pushScreen(showMission);
|
2018-06-10 22:58:38 +00:00
|
|
|
else restart_game();
|
2017-07-10 18:47:38 +00:00
|
|
|
}
|
|
|
|
|
2018-05-03 11:14:43 +00:00
|
|
|
if(sym == SDLK_ESCAPE) {
|
|
|
|
if(viewdists)
|
|
|
|
viewdists = false;
|
|
|
|
else
|
|
|
|
showMissionScreen();
|
|
|
|
}
|
2017-07-10 18:47:38 +00:00
|
|
|
|
|
|
|
if(sym == SDLK_F10) {
|
2018-05-26 23:06:54 +00:00
|
|
|
#if CAP_DAILY
|
|
|
|
if(daily::on) daily::handleQuit(2);
|
|
|
|
else
|
|
|
|
#endif
|
2017-07-10 18:47:38 +00:00
|
|
|
if(needConfirmation()) pushScreen(showMission);
|
|
|
|
else quitmainloop = true;
|
|
|
|
}
|
|
|
|
|
2018-11-17 18:24:02 +00:00
|
|
|
if(uni == 'o' && DEFAULTNOR(sym)) get_o_key().second();
|
2017-07-22 23:33:27 +00:00
|
|
|
#if CAP_INV
|
2017-07-10 18:47:38 +00:00
|
|
|
if(uni == 'i' && DEFAULTNOR(sym) && inv::on)
|
|
|
|
pushScreen(inv::show);
|
|
|
|
#endif
|
|
|
|
|
2019-02-22 20:37:30 +00:00
|
|
|
if(((sym == SDLK_HOME && DIM == 2) || sym == SDLK_F3 || sym == ' ') && DEFAULTNOR(sym))
|
2017-07-10 18:47:38 +00:00
|
|
|
fullcenter();
|
|
|
|
|
|
|
|
if(sym == 'v' && DEFAULTNOR(sym))
|
|
|
|
pushScreen(showMainMenu);
|
|
|
|
|
|
|
|
if(sym == '-' || sym == PSEUDOKEY_WHEELDOWN) {
|
|
|
|
actonrelease = false;
|
|
|
|
|
|
|
|
shmup::cpid = 0;
|
|
|
|
if(mouseover &&
|
|
|
|
targetclick && (!shmup::on || numplayers() == 1) && targetRangedOrb(mouseover, forcetarget ? roMouseForce : roMouse)) {
|
|
|
|
}
|
|
|
|
else if(forcetarget)
|
|
|
|
;
|
2018-03-02 12:05:31 +00:00
|
|
|
else if(rug::rugged && rug::renderonce)
|
|
|
|
;
|
2017-07-10 18:47:38 +00:00
|
|
|
else if(!DEFAULTCONTROL) {
|
|
|
|
if(!shmup::on)
|
|
|
|
multi::mousemovement(mouseover);
|
|
|
|
}
|
2017-11-13 10:08:06 +00:00
|
|
|
else if(handleCompass()) ;
|
|
|
|
else
|
|
|
|
mousemovement();
|
2017-07-10 18:47:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(sym == SDLK_F1) gotoHelp(help);
|
2019-06-06 17:37:17 +00:00
|
|
|
|
|
|
|
if(sym == PSEUDOKEY_MEMORY) pushScreen(show_memory_menu);
|
2017-07-10 18:47:38 +00:00
|
|
|
}
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX bool need_mouseh = false;
|
2017-12-27 12:48:06 +00:00
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX void fix_mouseh() {
|
2017-12-27 12:48:06 +00:00
|
|
|
if(!need_mouseh) ;
|
|
|
|
#if CAP_RUG
|
|
|
|
else if(rug::rugged)
|
|
|
|
mouseh = rug::gethyper(mousex, mousey);
|
|
|
|
#endif
|
2019-05-28 23:09:38 +00:00
|
|
|
else {
|
|
|
|
if(dual::state) {
|
|
|
|
if(cmode & (sm::NORMAL | sm::DRAW | sm::MAP)) {
|
|
|
|
dual::main_side = (mousex >= current_display->xcenter);
|
|
|
|
dual::switch_to(dual::main_side);
|
|
|
|
}
|
|
|
|
dual::in_subscreen([=] () { calcparam(); mouseh = gethyper(mousex, mousey); });
|
|
|
|
}
|
|
|
|
else mouseh = gethyper(mousex, mousey);
|
|
|
|
}
|
2017-12-27 13:09:39 +00:00
|
|
|
need_mouseh = false;
|
2017-12-27 12:48:06 +00:00
|
|
|
}
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX void handlekey(int sym, int uni) {
|
2017-07-10 18:47:38 +00:00
|
|
|
|
|
|
|
if(callhandlers(false, hooks_handleKey, sym, uni)) return;
|
|
|
|
|
|
|
|
keyhandler(sym, uni);
|
|
|
|
}
|
|
|
|
|
2019-08-09 20:07:03 +00:00
|
|
|
EX void resize_screen_to(int x, int y);
|
|
|
|
|
2017-07-22 23:33:27 +00:00
|
|
|
#if !CAP_SDL
|
2019-08-09 19:00:52 +00:00
|
|
|
EX void mainloopiter() { printf("(compiled without SDL -- no action)\n"); quitmainloop = true; }
|
2019-08-09 20:07:03 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if CAP_SDL
|
2017-07-10 18:47:38 +00:00
|
|
|
|
|
|
|
// Warning: a very long function! todo: refactor
|
|
|
|
|
|
|
|
int cframelimit = 1000;
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX void resize_screen_to(int x, int y) {
|
2019-05-29 14:40:15 +00:00
|
|
|
dual::split_or_do([&] {
|
|
|
|
vid.xres = x;
|
|
|
|
vid.yres = y;
|
|
|
|
vid.killreduction = 0;
|
|
|
|
});
|
2018-04-21 10:14:25 +00:00
|
|
|
extern bool setfsize;
|
|
|
|
setfsize = true;
|
|
|
|
setvideomode();
|
|
|
|
}
|
|
|
|
|
2019-08-06 19:03:26 +00:00
|
|
|
int lastframe;
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX void mainloopiter() {
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2019-05-12 23:57:40 +00:00
|
|
|
DEBB(DF_GRAPH, ("main loop\n"));
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2017-07-22 23:33:27 +00:00
|
|
|
#if !CAP_SDLGFX && !CAP_GL
|
2017-07-10 18:47:38 +00:00
|
|
|
vid.wallmode = 0;
|
|
|
|
vid.monmode = 0;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
optimizeview();
|
|
|
|
|
2018-10-23 14:58:19 +00:00
|
|
|
conformal::configure();
|
|
|
|
|
2019-08-06 19:03:26 +00:00
|
|
|
lastt = ticks;
|
2017-07-10 18:47:38 +00:00
|
|
|
ticks = SDL_GetTicks();
|
2017-12-01 23:20:35 +00:00
|
|
|
callhooks(hooks_fixticks);
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2019-08-06 19:03:26 +00:00
|
|
|
timetowait = lastframe + 1000 / cframelimit - ticks;
|
2017-07-10 18:47:38 +00:00
|
|
|
|
|
|
|
cframelimit = vid.framelimit;
|
|
|
|
if(outoffocus && cframelimit > 10) cframelimit = 10;
|
2017-07-12 17:50:39 +00:00
|
|
|
|
|
|
|
bool normal = cmode & sm::NORMAL;
|
2019-08-06 19:03:26 +00:00
|
|
|
|
2018-07-09 18:38:20 +00:00
|
|
|
shmup::turn(ticks - lastt);
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2018-07-09 18:38:20 +00:00
|
|
|
if(!shmup::on && (multi::alwaysuse || multi::players > 1) && normal)
|
2017-07-10 18:47:38 +00:00
|
|
|
timetowait = 0, multi::handleMulti(ticks - lastt);
|
|
|
|
|
2019-05-05 15:31:55 +00:00
|
|
|
if(vid.sspeed >= 5 && gmatrix.count(cwt.at) && !elliptic && !shmup::on) {
|
2018-08-17 22:46:45 +00:00
|
|
|
cwtV = gmatrix[cwt.at] * ddspin(cwt.at, cwt.spin);
|
2017-07-10 18:47:38 +00:00
|
|
|
if(cwt.mirrored) playerV = playerV * Mirror;
|
|
|
|
}
|
2019-02-26 01:35:30 +00:00
|
|
|
|
2019-02-28 16:48:14 +00:00
|
|
|
mousepan = (cmode & (sm::NORMAL | sm::DRAW | sm::MAP)) && DIM == 3 && mouseaim_sensitivity;
|
2019-02-26 01:35:30 +00:00
|
|
|
if(mousepan != oldmousepan) {
|
|
|
|
oldmousepan = mousepan;
|
2019-06-28 07:47:10 +00:00
|
|
|
#if CAP_MOUSEGRAB
|
2019-02-26 01:35:30 +00:00
|
|
|
if(mousepan) {
|
|
|
|
SDL_WM_GrabInput(SDL_GRAB_ON);
|
|
|
|
SDL_ShowCursor(SDL_DISABLE);
|
|
|
|
mouseaim_x = mouseaim_y = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
SDL_WM_GrabInput( SDL_GRAB_OFF );
|
|
|
|
SDL_ShowCursor(SDL_ENABLE);
|
|
|
|
SDL_WarpMouse(vid.xres/2, vid.yres/2);
|
|
|
|
mouseaim_x = mouseaim_y = 0;
|
|
|
|
}
|
2019-06-28 07:47:10 +00:00
|
|
|
#endif
|
2019-02-26 01:35:30 +00:00
|
|
|
}
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2018-09-05 22:48:11 +00:00
|
|
|
#if ISWEB
|
|
|
|
timetowait = 0;
|
|
|
|
#endif
|
|
|
|
|
2017-07-10 18:47:38 +00:00
|
|
|
if(timetowait > 0)
|
|
|
|
SDL_Delay(timetowait);
|
|
|
|
else {
|
2018-07-23 03:14:19 +00:00
|
|
|
ors::check_orientation();
|
2017-07-12 17:50:39 +00:00
|
|
|
if(cmode & sm::CENTER) {
|
2019-06-25 08:31:07 +00:00
|
|
|
ld aspd = (ticks - lastt) / 1000.0 * exp(vid.sspeed);
|
2017-07-10 18:47:38 +00:00
|
|
|
if(playermoved && vid.sspeed > -4.99 && !outoffocus)
|
2019-06-25 08:31:07 +00:00
|
|
|
centerpc(aspd);
|
|
|
|
else if(DIM == 3)
|
|
|
|
spinEdge(aspd);
|
2018-09-04 21:27:27 +00:00
|
|
|
#if CAP_SDLJOY
|
2017-07-10 18:47:38 +00:00
|
|
|
if(panjoyx || panjoyy)
|
|
|
|
checkpanjoy((ticks - lastt) / 1000.0);
|
2018-09-04 21:27:27 +00:00
|
|
|
#endif
|
2017-07-10 18:47:38 +00:00
|
|
|
}
|
|
|
|
tortoise::updateVals(ticks - lastt);
|
|
|
|
frames++;
|
|
|
|
if(!outoffocus) {
|
|
|
|
drawscreen();
|
|
|
|
}
|
2019-08-06 19:03:26 +00:00
|
|
|
lastframe = ticks;
|
2017-07-10 18:47:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Uint8 *keystate = SDL_GetKeyState(NULL);
|
|
|
|
rightclick = keystate[SDLK_RCTRL];
|
|
|
|
leftclick = keystate[SDLK_RSHIFT];
|
|
|
|
lctrlclick = keystate[SDLK_LCTRL];
|
|
|
|
lshiftclick = keystate[SDLK_LSHIFT];
|
|
|
|
forcetarget = (keystate[SDLK_RSHIFT] | keystate[SDLK_LSHIFT]);
|
|
|
|
hiliteclick = keystate[SDLK_LALT] | keystate[SDLK_RALT];
|
|
|
|
anyshiftclick = keystate[SDLK_LSHIFT] | keystate[SDLK_RSHIFT];
|
|
|
|
wheelclick = false;
|
|
|
|
|
|
|
|
getcshift = 1;
|
|
|
|
if(keystate[SDLK_LSHIFT] || keystate[SDLK_RSHIFT]) getcshift = -1;
|
|
|
|
if(keystate[SDLK_LCTRL] || keystate[SDLK_RCTRL]) getcshift /= 10;
|
|
|
|
if(keystate[SDLK_LALT] || keystate[SDLK_RALT]) getcshift *= 10;
|
|
|
|
|
|
|
|
didsomething = false;
|
|
|
|
|
|
|
|
if(vid.shifttarget&1) {
|
|
|
|
leftclick = false;
|
|
|
|
targetclick = keystate[SDLK_RSHIFT] | keystate[SDLK_LSHIFT];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
leftclick = keystate[SDLK_RSHIFT];
|
|
|
|
targetclick = true;
|
|
|
|
}
|
|
|
|
|
2017-07-22 23:33:27 +00:00
|
|
|
#if CAP_SDLAUDIO
|
2017-07-10 18:47:38 +00:00
|
|
|
if(audio) handlemusic();
|
|
|
|
#endif
|
2019-06-06 17:37:17 +00:00
|
|
|
apply_memory_reserve();
|
2017-07-10 18:47:38 +00:00
|
|
|
SDL_Event ev;
|
2019-05-12 23:57:40 +00:00
|
|
|
DEBB(DF_GRAPH, ("polling for events\n"));
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2019-02-26 01:35:30 +00:00
|
|
|
if(DIM == 3 && !shmup::on && !rug::rugged) {
|
2019-06-28 07:47:10 +00:00
|
|
|
#if CAP_MOUSEGRAB
|
2019-02-26 01:35:30 +00:00
|
|
|
View = cspin(0, 2, -mouseaim_x) * cspin(1, 2, -mouseaim_y) * View;
|
|
|
|
mouseaim_x = mouseaim_y = 0;
|
2019-06-28 07:47:10 +00:00
|
|
|
#endif
|
2019-02-26 01:35:30 +00:00
|
|
|
}
|
|
|
|
|
2019-02-25 17:39:36 +00:00
|
|
|
if(smooth_scrolling && !shmup::on && !rug::rugged) {
|
2019-02-22 20:37:47 +00:00
|
|
|
static int lastticks;
|
|
|
|
ld t = (ticks - lastticks) * shiftmul / 1000.;
|
|
|
|
lastticks = ticks;
|
|
|
|
Uint8 *keystate = SDL_GetKeyState(NULL);
|
|
|
|
if(keystate[SDLK_END] && DIM == 3 && DEFAULTNOR(SDLK_END))
|
|
|
|
View = cpush(2, -t) * View, didsomething = true, playermoved = false;
|
|
|
|
if(keystate[SDLK_HOME] && DIM == 3 && DEFAULTNOR(SDLK_HOME))
|
|
|
|
View = cpush(2, t) * View, didsomething = true, playermoved = false;
|
|
|
|
if(keystate[SDLK_RIGHT] && DEFAULTNOR(SDLK_RIGHT))
|
2019-02-25 17:39:36 +00:00
|
|
|
View = (DIM == 2 ? xpush(-t) : cspin(0, 2, -t)) * View, didsomething = true, playermoved = playermoved && DIM == 3;
|
2019-02-22 20:37:47 +00:00
|
|
|
if(keystate[SDLK_LEFT] && DEFAULTNOR(SDLK_LEFT))
|
2019-02-25 17:39:36 +00:00
|
|
|
View = (DIM == 2 ? xpush(t) : cspin(0, 2, t)) * View, didsomething = true, playermoved = playermoved && DIM == 3;
|
2019-02-22 20:37:47 +00:00
|
|
|
if(keystate[SDLK_UP] && DEFAULTNOR(SDLK_UP))
|
2019-02-25 17:39:36 +00:00
|
|
|
View = (DIM == 2 ? ypush(t) : cspin(1, 2, t)) * View, didsomething = true, playermoved = playermoved && DIM == 3;
|
2019-02-22 20:37:47 +00:00
|
|
|
if(keystate[SDLK_DOWN] && DEFAULTNOR(SDLK_DOWN))
|
2019-02-25 17:39:36 +00:00
|
|
|
View = (DIM == 2 ? ypush(-t) : cspin(1, 2, -t)) * View, didsomething = true, playermoved = playermoved && DIM == 3;
|
2019-02-22 20:37:47 +00:00
|
|
|
if(keystate[SDLK_PAGEUP] && DEFAULTNOR(SDLK_PAGEUP)) {
|
|
|
|
if(conformal::on)
|
|
|
|
conformal::rotation+=t;
|
|
|
|
else
|
|
|
|
View = spin(t) * View, didsomething = true;
|
|
|
|
}
|
|
|
|
if(keystate[SDLK_PAGEDOWN] && DEFAULTNOR(SDLK_PAGEDOWN)) {
|
|
|
|
if(conformal::on)
|
|
|
|
conformal::rotation-=t;
|
|
|
|
else
|
|
|
|
View = spin(-t) * View, didsomething = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-25 23:10:23 +00:00
|
|
|
achievement_pump();
|
|
|
|
while(SDL_PollEvent(&ev)) handle_event(ev);
|
|
|
|
fix_mouseh();
|
|
|
|
}
|
2017-12-27 12:48:06 +00:00
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX void handle_event(SDL_Event& ev) {
|
2018-05-25 23:10:23 +00:00
|
|
|
bool normal = cmode & sm::NORMAL;
|
|
|
|
Uint8 *keystate = SDL_GetKeyState(NULL);
|
|
|
|
|
2019-05-12 23:57:40 +00:00
|
|
|
DEBB(DF_GRAPH, ("got event type #%d\n", ev.type));
|
2017-07-10 18:47:38 +00:00
|
|
|
int sym = 0;
|
|
|
|
int uni = 0;
|
|
|
|
shiftmul = 1;
|
|
|
|
|
|
|
|
/* if(ev.type == SDL_JOYDEVICEADDED || ev.type == SDL_JOYDEVICEREMOVED) {
|
|
|
|
joyx = joyy = 0;
|
|
|
|
panjoyx = panjoyy = 0;
|
|
|
|
closeJoysticks();
|
|
|
|
initJoysticks();
|
2017-10-15 23:22:24 +00:00
|
|
|
} */
|
2017-07-10 18:47:38 +00:00
|
|
|
|
|
|
|
if(ev.type == SDL_ACTIVEEVENT) {
|
|
|
|
if(ev.active.state & SDL_APPINPUTFOCUS) {
|
|
|
|
if(ev.active.gain) {
|
|
|
|
outoffocus = false;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
outoffocus = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-21 10:14:25 +00:00
|
|
|
if(ev.type == SDL_VIDEORESIZE)
|
|
|
|
resize_screen_to(ev.resize.w, ev.resize.h);
|
2017-07-10 18:47:38 +00:00
|
|
|
|
|
|
|
if(ev.type == SDL_VIDEOEXPOSE) {
|
|
|
|
drawscreen();
|
|
|
|
}
|
2017-08-13 18:49:38 +00:00
|
|
|
|
2017-10-15 23:22:24 +00:00
|
|
|
#if CAP_SDLJOY
|
2017-07-16 21:00:55 +00:00
|
|
|
if(ev.type == SDL_JOYAXISMOTION && normal && DEFAULTCONTROL) {
|
2017-07-10 18:47:38 +00:00
|
|
|
if(ev.jaxis.which == 0) {
|
|
|
|
if(ev.jaxis.axis == 0)
|
|
|
|
joyx = ev.jaxis.value;
|
|
|
|
else if(ev.jaxis.axis == 1)
|
|
|
|
joyy = ev.jaxis.value;
|
|
|
|
else if(ev.jaxis.axis == 3)
|
|
|
|
panjoyx = ev.jaxis.value;
|
|
|
|
else if(ev.jaxis.axis == 4)
|
|
|
|
panjoyy = ev.jaxis.value;
|
|
|
|
checkjoy();
|
|
|
|
// printf("panjoy = %d,%d\n", panjoyx, panjoyy);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if(ev.jaxis.axis == 0)
|
|
|
|
panjoyx = ev.jaxis.value;
|
|
|
|
else
|
|
|
|
panjoyy = ev.jaxis.value;
|
|
|
|
}
|
|
|
|
}
|
2017-07-12 17:50:39 +00:00
|
|
|
|
2018-11-18 02:18:11 +00:00
|
|
|
if(joyhandler && joyhandler(ev)) ;
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2017-07-16 21:00:55 +00:00
|
|
|
else if(ev.type == SDL_JOYHATMOTION && !normal) {
|
|
|
|
if(ev.jhat.value == SDL_HAT_UP) sym = SDLK_UP;
|
|
|
|
if(ev.jhat.value == SDL_HAT_DOWN) sym = SDLK_DOWN;
|
|
|
|
if(ev.jhat.value == SDL_HAT_LEFT) sym = SDLK_LEFT;
|
|
|
|
if(ev.jhat.value == SDL_HAT_RIGHT) sym = SDLK_RIGHT;
|
|
|
|
}
|
|
|
|
|
|
|
|
else if(ev.type == SDL_JOYBUTTONDOWN && normal && DEFAULTCONTROL) {
|
2017-07-10 18:47:38 +00:00
|
|
|
flashMessages();
|
|
|
|
movepcto(joydir);
|
|
|
|
checkjoy();
|
|
|
|
}
|
|
|
|
|
2017-07-16 21:00:55 +00:00
|
|
|
else if(ev.type == SDL_JOYBUTTONDOWN && !normal) {
|
|
|
|
sym = uni = SDLK_RETURN;
|
|
|
|
}
|
2017-08-13 18:49:38 +00:00
|
|
|
#endif
|
2017-07-16 21:00:55 +00:00
|
|
|
|
2017-07-10 18:47:38 +00:00
|
|
|
if(ev.type == SDL_KEYDOWN) {
|
|
|
|
flashMessages();
|
|
|
|
mousing = false;
|
|
|
|
sym = ev.key.keysym.sym;
|
|
|
|
uni = ev.key.keysym.unicode;
|
|
|
|
if(ev.key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT)) shiftmul = -1;
|
|
|
|
if(ev.key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) shiftmul /= 10;
|
2018-12-06 11:31:51 +00:00
|
|
|
numlock_on = ev.key.keysym.mod & KMOD_NUM;
|
2017-07-10 18:47:38 +00:00
|
|
|
if(sym == SDLK_RETURN && (ev.key.keysym.mod & (KMOD_LALT | KMOD_RALT))) {
|
|
|
|
sym = 0; uni = 0;
|
|
|
|
switchFullscreen();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dialog::handleZooming(ev);
|
|
|
|
|
2017-07-12 17:50:39 +00:00
|
|
|
if(sym == SDLK_F1 && normal && playermoved)
|
2017-07-10 18:47:38 +00:00
|
|
|
help = "@";
|
|
|
|
|
2017-07-12 17:50:39 +00:00
|
|
|
bool rollchange = (cmode & sm::OVERVIEW) && getcstat >= 2000 && cheater;
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2017-12-30 16:00:35 +00:00
|
|
|
bool anyctrl = keystate[SDLK_LCTRL] || keystate[SDLK_RCTRL];
|
|
|
|
bool anyshift = keystate[SDLK_LSHIFT] || keystate[SDLK_RSHIFT];
|
|
|
|
|
2017-08-18 01:24:15 +00:00
|
|
|
if(ev.type == SDL_MOUSEBUTTONDOWN || ev.type == SDL_MOUSEBUTTONUP) {
|
2017-08-06 12:50:16 +00:00
|
|
|
mousepressed = ev.type == SDL_MOUSEBUTTONDOWN;
|
|
|
|
if(mousepressed) flashMessages();
|
2017-07-10 18:47:38 +00:00
|
|
|
mousing = true;
|
2018-01-04 11:25:02 +00:00
|
|
|
bool was_holdmouse = holdmouse;
|
2017-11-06 22:22:13 +00:00
|
|
|
holdmouse = false;
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2017-08-06 12:50:16 +00:00
|
|
|
bool act = false;
|
|
|
|
|
|
|
|
if(vid.quickmouse) {
|
|
|
|
act = ev.type == SDL_MOUSEBUTTONDOWN;
|
2017-07-10 18:47:38 +00:00
|
|
|
}
|
2017-08-06 12:50:16 +00:00
|
|
|
else {
|
|
|
|
act = actonrelease && ev.type == SDL_MOUSEBUTTONUP;
|
|
|
|
actonrelease = ev.type == SDL_MOUSEBUTTONDOWN;
|
2017-12-30 16:00:35 +00:00
|
|
|
}
|
2017-08-13 19:37:29 +00:00
|
|
|
|
2018-01-04 11:25:02 +00:00
|
|
|
fix_mouseh();
|
|
|
|
|
|
|
|
if(was_holdmouse && ev.type == SDL_MOUSEBUTTONUP)
|
|
|
|
sym = uni = PSEUDOKEY_RELEASE;
|
2017-12-27 12:48:06 +00:00
|
|
|
|
2017-08-06 12:50:16 +00:00
|
|
|
if(!act) ;
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2017-08-06 12:50:16 +00:00
|
|
|
else if(ev.button.button==SDL_BUTTON_RIGHT || leftclick)
|
2017-07-10 18:47:38 +00:00
|
|
|
sym = SDLK_F1;
|
2017-12-30 16:00:35 +00:00
|
|
|
else if(ev.button.button==SDL_BUTTON_MIDDLE || rightclick) {
|
2017-07-10 18:47:38 +00:00
|
|
|
sym = 1, didsomething = true;
|
2017-12-30 16:00:35 +00:00
|
|
|
if(anyshift)
|
|
|
|
vid.xposition = vid.yposition = 0;
|
|
|
|
}
|
2017-08-06 12:50:16 +00:00
|
|
|
else if(ev.button.button == SDL_BUTTON_LEFT) {
|
2017-07-10 18:47:38 +00:00
|
|
|
sym = getcstat, uni = getcstat, shiftmul = getcshift;
|
|
|
|
}
|
2017-08-06 12:50:16 +00:00
|
|
|
|
|
|
|
else if(ev.button.button==SDL_BUTTON_WHEELDOWN) {
|
2019-02-28 17:58:02 +00:00
|
|
|
if(anyctrl && anyshift && !rug::rugged && DIM == 2) {
|
2017-12-30 16:00:35 +00:00
|
|
|
mapeditor::scaleall(1/1.2);
|
2017-08-13 19:37:29 +00:00
|
|
|
vid.alpha /= 1.2;
|
|
|
|
}
|
2019-02-28 17:58:02 +00:00
|
|
|
else if(anyctrl && !rug::rugged && DIM == 2)
|
2017-12-30 16:00:35 +00:00
|
|
|
mapeditor::scaleall(pow(2, -.25));
|
2019-02-28 17:58:02 +00:00
|
|
|
else if(anyshift && !rug::rugged && DIM == 2)
|
2017-08-13 19:37:29 +00:00
|
|
|
vid.alpha -= 0.25;
|
|
|
|
else if(rollchange) {
|
2017-08-06 12:50:16 +00:00
|
|
|
sym = getcstat, uni = getcstat, shiftmul = getcshift, wheelclick = true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sym = uni = PSEUDOKEY_WHEELDOWN;
|
|
|
|
}
|
2017-07-10 18:47:38 +00:00
|
|
|
}
|
2017-08-06 12:50:16 +00:00
|
|
|
if(ev.button.button==SDL_BUTTON_WHEELUP) {
|
2019-02-28 17:58:02 +00:00
|
|
|
if(anyctrl && anyshift && !rug::rugged && DIM == 2) {
|
2017-12-30 16:00:35 +00:00
|
|
|
mapeditor::scaleall(1.2);
|
2017-08-13 19:37:29 +00:00
|
|
|
vid.alpha *= 1.2;
|
|
|
|
}
|
2019-02-28 17:58:02 +00:00
|
|
|
else if(anyctrl && !rug::rugged && DIM == 2)
|
2017-12-30 16:00:35 +00:00
|
|
|
mapeditor::scaleall(pow(2, .25));
|
2019-02-28 17:58:02 +00:00
|
|
|
else if(anyshift && !rug::rugged && DIM == 2)
|
2017-08-13 19:37:29 +00:00
|
|
|
vid.alpha += 0.25;
|
|
|
|
else if(rollchange) {
|
2017-08-06 12:50:16 +00:00
|
|
|
sym = getcstat, uni = getcstat, shiftmul = -getcshift, wheelclick = true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sym = uni = PSEUDOKEY_WHEELUP;
|
|
|
|
}
|
2017-07-10 18:47:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ev.type == SDL_MOUSEMOTION) {
|
|
|
|
mouseoh = mouseh;
|
|
|
|
|
2017-12-30 16:00:35 +00:00
|
|
|
int lmousex = mousex, lmousey = mousey;
|
|
|
|
|
2017-07-10 18:47:38 +00:00
|
|
|
mousing = true;
|
|
|
|
mousemoved = true;
|
|
|
|
mousex = ev.motion.x;
|
|
|
|
mousey = ev.motion.y;
|
2017-12-27 12:48:06 +00:00
|
|
|
|
2019-02-26 01:35:30 +00:00
|
|
|
if(mousepan) {
|
|
|
|
mousex = vid.xres/2;
|
|
|
|
mousey = vid.yres/2;
|
|
|
|
mouseaim_x += ev.motion.xrel * mouseaim_sensitivity;
|
|
|
|
mouseaim_y += ev.motion.yrel * mouseaim_sensitivity;
|
|
|
|
}
|
|
|
|
|
2017-12-27 12:48:06 +00:00
|
|
|
need_mouseh = true;
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2017-12-30 16:00:35 +00:00
|
|
|
if(holdmouse && getcstat == '-') sym = uni = getcstat, fix_mouseh();
|
2017-07-10 18:47:38 +00:00
|
|
|
|
2017-12-30 16:00:35 +00:00
|
|
|
if((rightclick || (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON_MMASK)) && !mouseout2()) {
|
|
|
|
fix_mouseh();
|
|
|
|
if(anyctrl) {
|
2018-11-17 18:24:02 +00:00
|
|
|
vid.xposition += (mousex - lmousex) * 1. / current_display->scrsize,
|
|
|
|
vid.yposition += (mousey - lmousey) * 1. / current_display->scrsize;
|
2017-12-30 16:00:35 +00:00
|
|
|
}
|
2019-02-21 17:46:53 +00:00
|
|
|
else if(mouseh[DIM] < 50 && mouseoh[DIM] < 50) {
|
2017-12-30 16:00:35 +00:00
|
|
|
panning(mouseoh, mouseh);
|
|
|
|
}
|
2017-07-10 18:47:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef SIMULATE_JOYSTICK
|
|
|
|
// pretend that both joysticks are present
|
|
|
|
stick = panstick = (SDL_Joystick*) (&vid);
|
2018-11-17 18:24:02 +00:00
|
|
|
panjoyx = 20 * (mousex - current_display->xcenter);
|
|
|
|
panjoyy = 20 * (mousey - current_display->ycenter);
|
2017-07-10 18:47:38 +00:00
|
|
|
checkjoy();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if(mousepressed && inslider) {
|
|
|
|
sym = getcstat, uni = getcstat, shiftmul = getcshift;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ev.type == SDL_QUIT) {
|
2018-05-26 23:06:54 +00:00
|
|
|
#if CAP_DAILY
|
|
|
|
if(daily::on) daily::handleQuit(3);
|
|
|
|
else
|
|
|
|
#endif
|
2017-07-12 17:50:39 +00:00
|
|
|
if(needConfirmation() && !(cmode & sm::MISSION)) showMissionScreen();
|
2017-07-10 18:47:38 +00:00
|
|
|
else quitmainloop = true;
|
|
|
|
}
|
2018-07-09 16:10:28 +00:00
|
|
|
|
|
|
|
if(sym == SDLK_F4 && anyshift) {
|
|
|
|
nomap = !nomap;
|
|
|
|
sym = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(sym == SDLK_F2 && anyshift) {
|
|
|
|
nohud = !nohud;
|
|
|
|
sym = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(sym == SDLK_F3 && anyshift) {
|
|
|
|
nofps = !nofps;
|
|
|
|
sym = 0;
|
|
|
|
}
|
2017-12-30 16:00:35 +00:00
|
|
|
|
2017-07-10 18:47:38 +00:00
|
|
|
handlekey(sym, uni);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX void mainloop() {
|
2017-08-17 23:15:48 +00:00
|
|
|
if(noGUI) return;
|
2017-07-10 18:47:38 +00:00
|
|
|
lastt = 0;
|
2017-07-22 23:33:27 +00:00
|
|
|
#if ISWEB
|
2017-07-10 18:47:38 +00:00
|
|
|
initweb();
|
|
|
|
emscripten_set_main_loop(mainloopiter, 0, true);
|
|
|
|
#else
|
|
|
|
while(!quitmainloop) mainloopiter();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2017-07-22 23:33:27 +00:00
|
|
|
#if ISMOBILE==1
|
2019-08-09 19:00:52 +00:00
|
|
|
EX void displayabutton(int px, int py, string s, int col) {
|
2017-07-10 18:47:38 +00:00
|
|
|
// TMP
|
|
|
|
int siz = vid.yres > vid.xres ? vid.fsize*2 : vid.fsize * 3/2;
|
2017-11-07 12:40:56 +00:00
|
|
|
int rad = (int) realradius();
|
2018-11-17 18:24:02 +00:00
|
|
|
if(vid.stereo_mode == sLR) rad = 99999;
|
2017-11-07 12:40:56 +00:00
|
|
|
int vrx = min(rad, vid.xres/2 - 40);
|
2018-11-17 18:24:02 +00:00
|
|
|
int vry = min(rad, min(current_display->ycenter, vid.yres - current_display->ycenter) - 20);
|
|
|
|
int x = current_display->xcenter + px * vrx;
|
|
|
|
int y = current_display->ycenter + py * (vry - siz/2);
|
2017-07-10 18:47:38 +00:00
|
|
|
int vrr = int(hypot(vrx, vry) * sqrt(2.));
|
|
|
|
if(gtouched && !mouseover
|
2018-11-17 18:24:02 +00:00
|
|
|
&& abs(mousex - current_display->xcenter) < vrr
|
|
|
|
&& abs(mousey - current_display->ycenter) < vrr
|
|
|
|
&& hypot(mousex-current_display->xcenter, mousey-current_display->ycenter) > vrr
|
|
|
|
&& px == (mousex > current_display->xcenter ? 1 : -1)
|
|
|
|
&& py == (mousey > current_display->ycenter ? 1 : -1)
|
2017-07-10 18:47:38 +00:00
|
|
|
) col = 0xFF0000;
|
|
|
|
if(displayfr(x, y, 0, siz, s, col, 8+8*px))
|
|
|
|
buttonclicked = true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX bool interpret_as_direction(int sym, int uni) {
|
2018-12-15 14:17:06 +00:00
|
|
|
#ifdef FAKE_SDL
|
|
|
|
return false;
|
|
|
|
#else
|
2018-12-06 11:31:51 +00:00
|
|
|
return (sym >= SDLK_KP0 && sym <= SDLK_KP9 && !numlock_on);
|
2018-12-15 14:17:06 +00:00
|
|
|
#endif
|
2018-12-06 11:31:51 +00:00
|
|
|
}
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX int get_direction_key(int sym, int uni) {
|
2018-12-06 11:31:51 +00:00
|
|
|
if(interpret_as_direction(sym, uni)) {
|
2018-12-15 14:17:06 +00:00
|
|
|
#ifndef FAKE_SDL
|
2018-12-06 11:31:51 +00:00
|
|
|
if(sym == SDLK_KP1) return SDLK_END;
|
|
|
|
if(sym == SDLK_KP2) return SDLK_DOWN;
|
|
|
|
if(sym == SDLK_KP3) return SDLK_PAGEDOWN;
|
|
|
|
if(sym == SDLK_KP4) return SDLK_LEFT;
|
|
|
|
if(sym == SDLK_KP6) return SDLK_RIGHT;
|
|
|
|
if(sym == SDLK_KP7) return SDLK_HOME;
|
|
|
|
if(sym == SDLK_KP8) return SDLK_UP;
|
|
|
|
if(sym == SDLK_KP8) return SDLK_PAGEUP;
|
2018-12-15 14:17:06 +00:00
|
|
|
#endif
|
2018-12-06 11:31:51 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return sym;
|
2018-12-06 10:43:10 +00:00
|
|
|
}
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX bool gmodekeys(int sym, int uni) {
|
2018-02-03 13:31:17 +00:00
|
|
|
#if CAP_RUG
|
2019-03-30 22:45:28 +00:00
|
|
|
if(rug::rugged && rug::handlekeys(sym, uni)) return true;
|
2018-02-03 13:31:17 +00:00
|
|
|
#endif
|
2019-03-30 22:45:28 +00:00
|
|
|
|
|
|
|
if(NUMBERKEY == '6') { vid.grid = !vid.grid; return true; }
|
|
|
|
if(NUMBERKEY == '7') { vid.darkhepta = !vid.darkhepta; return true; }
|
|
|
|
|
2019-02-26 11:23:07 +00:00
|
|
|
if(DIM == 2) {
|
|
|
|
if(NUMBERKEY == '1' && !rug::rugged) { vid.alpha = 999; vid.scale = 998; vid.xposition = vid.yposition = 0; }
|
2019-03-30 22:45:28 +00:00
|
|
|
else if(NUMBERKEY == '2' && !rug::rugged) { vid.alpha = 1; vid.scale = 0.4; vid.xposition = vid.yposition = 0; }
|
|
|
|
else if(NUMBERKEY == '3' && !rug::rugged) { vid.alpha = 1; vid.scale = 1; vid.xposition = vid.yposition = 0; }
|
|
|
|
else if(NUMBERKEY == '4' && !rug::rugged) { vid.alpha = 0; vid.scale = 1; vid.xposition = vid.yposition = 0; }
|
|
|
|
else if(NUMBERKEY == '5') { vid.wallmode += 60 + (shiftmul > 0 ? 1 : -1); vid.wallmode %= 6; }
|
|
|
|
else if(NUMBERKEY == '8') { vid.monmode += 60 + (shiftmul > 0 ? 1 : -1); vid.monmode %= 6; }
|
|
|
|
else if(uni == '%') {
|
2019-02-26 11:23:07 +00:00
|
|
|
if(vid.wallmode == 0) vid.wallmode = 6;
|
|
|
|
vid.wallmode--;
|
|
|
|
}
|
2019-03-30 22:45:28 +00:00
|
|
|
else return false;
|
|
|
|
return true;
|
2019-02-26 11:23:07 +00:00
|
|
|
}
|
2019-02-27 12:30:09 +00:00
|
|
|
else {
|
2019-05-30 09:31:24 +00:00
|
|
|
auto& ysh = (WDIM == 2 ? vid.camera : vid.yshift);
|
|
|
|
if(NUMBERKEY == '1') { ysh = 0; vid.sspeed = 0; }
|
|
|
|
else if(NUMBERKEY == '2') { ysh = 0; vid.sspeed = -10; }
|
|
|
|
else if(NUMBERKEY == '3') { ysh = 1; vid.sspeed = 0; }
|
2019-03-30 22:45:28 +00:00
|
|
|
else if(NUMBERKEY == '5') { vid.wallmode = vid.wallmode == 5 ? 4 : 5; }
|
|
|
|
else return false;
|
|
|
|
return true;
|
2019-02-27 12:30:09 +00:00
|
|
|
}
|
2017-07-12 16:03:53 +00:00
|
|
|
}
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX bool haveMobileCompass() {
|
2018-07-22 13:54:44 +00:00
|
|
|
#if ISMOBILE
|
|
|
|
if(longclick) return false;
|
2017-11-13 10:08:06 +00:00
|
|
|
#else
|
|
|
|
if(forcetarget) return false;
|
|
|
|
#endif
|
2019-02-24 18:40:01 +00:00
|
|
|
if(DIM == 3) return false;
|
2018-06-22 12:47:24 +00:00
|
|
|
return canmove && !shmup::on && vid.mobilecompasssize > 0 && isize(screens) == 1;
|
2017-11-13 10:08:06 +00:00
|
|
|
}
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX bool handleCompass() {
|
2017-11-13 10:08:06 +00:00
|
|
|
if(!haveMobileCompass()) return false;
|
|
|
|
|
|
|
|
using namespace shmupballs;
|
2018-02-08 21:27:12 +00:00
|
|
|
|
2017-11-13 10:08:06 +00:00
|
|
|
int dx = mousex - xmove;
|
|
|
|
int dy = mousey - yb;
|
|
|
|
int h = hypot(dx, dy);
|
|
|
|
if(h < rad) {
|
|
|
|
if(h < rad*SKIPFAC) movepcto(MD_WAIT);
|
|
|
|
else {
|
2018-07-23 14:08:08 +00:00
|
|
|
hyperpoint param = hpxy(dx * 1. / rad, dy * 1. / rad);
|
|
|
|
|
|
|
|
movedir md = vectodir(param);
|
|
|
|
|
|
|
|
if(!canmove) movepcto(md), remission(); else movepcto(md);
|
2017-11-13 10:08:06 +00:00
|
|
|
}
|
|
|
|
getcstat = 0;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2018-06-10 23:58:31 +00:00
|
|
|
|
2018-07-23 03:14:19 +00:00
|
|
|
// orientation sensitivity
|
2019-08-09 19:00:52 +00:00
|
|
|
EX namespace ors {
|
2018-07-23 03:14:19 +00:00
|
|
|
|
|
|
|
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() {
|
2019-07-03 02:55:45 +00:00
|
|
|
return MirrorX * hr::getOrientation() * MirrorX;
|
2018-07-23 03:14:19 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX void reset() {
|
2018-07-23 03:14:19 +00:00
|
|
|
#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
|
|
|
|
}
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX void show() {
|
2018-07-23 03:14:19 +00:00
|
|
|
#if CAP_ORIENTATION
|
2018-12-13 16:02:10 +00:00
|
|
|
cmode = sm::SIDE | sm::MAYDARK;
|
2018-07-23 03:14:19 +00:00
|
|
|
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');
|
2019-03-30 22:59:51 +00:00
|
|
|
dialog::add_action_push(showStereo);
|
2018-07-23 03:14:19 +00:00
|
|
|
|
|
|
|
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([] () {
|
2019-06-28 07:54:28 +00:00
|
|
|
if(!sphere) set_geometry(gSphere), start_game();
|
2018-07-23 03:14:19 +00:00
|
|
|
mode = 0; fullcenter();
|
|
|
|
mode = 2; sensitivity = 1;
|
2018-11-17 18:24:02 +00:00
|
|
|
vid.stereo_mode = sLR; vid.ipd = 0.2;
|
2018-07-23 03:14:19 +00:00
|
|
|
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;
|
2018-08-19 14:28:36 +00:00
|
|
|
hyperpoint spinpoint = gpushxto0(h) * T * xpush0(1);
|
2018-07-23 03:14:19 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2019-07-03 02:55:45 +00:00
|
|
|
int first_check, last_check;
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX void check_orientation() {
|
2018-07-23 03:14:19 +00:00
|
|
|
#if CAP_ORIENTATION
|
|
|
|
if(!mode) return;
|
2019-07-03 02:55:45 +00:00
|
|
|
|
|
|
|
if(ticks > last_check + 2000) first_check = ticks;
|
|
|
|
last_check = ticks;
|
|
|
|
|
|
|
|
if(ticks < first_check + 500) {
|
2018-07-23 03:14:19 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2019-08-09 19:00:52 +00:00
|
|
|
EX }
|
2018-07-23 03:14:19 +00:00
|
|
|
|
2018-06-10 23:58:31 +00:00
|
|
|
}
|