hyperrogue/mobile.cpp

405 lines
10 KiB
C++

// Hyperbolic Rogue -- initialization, and stuff related to mobiles
// Copyright (C) 2011-2018 Zeno Rogue, see 'hyper.cpp' for details
/** \file init.cpp
* \brief initialization, and stuff related to mobiles
*/
#include "hyper.h"
namespace hr {
#if ISANDROID
string buildScoreDescription() {
string s;
time_t timer;
timer = time(NULL);
char buf[128]; strftime(buf, 128, "%c", localtime(&timer));
s += XLAT("HyperRogue for Android");
s += " ( " VER "), http://www.roguetemple.com/z/hyper/\n";
s += XLAT("Date: %1 time: %2 s ", buf, getgametime_s());
s += XLAT("distance: %1\n", its(celldist(cwt.at)));
if(cheater) s += XLAT("Cheats: ") + its(cheater) + "\n";
s += XLAT("Score: ") + its(gold());
for(int i=0; i<ittypes; i++) if(items[i]) {
string t = XLATN(iinf[i].name);
s += hr::format(" %s (%d)", t.c_str(), items[i]);
}
s += "\n";
s += XLAT("Kills: ") + its(tkills());
for(int i=1; i<motypes; i++) if(kills[i]) {
string t = XLATN(minf[i].name);
s += hr::format(" %s (%d)", t.c_str(), kills[i]);
}
s += "\n";
for(int i=0; i<gamelog.size(); i++) if(gamelog[i].msg != "") s += gamelog[i].msg + "\n";
return s;
}
#endif
#if ISMOBILE
int andmode;
bool lclicked = false;
EX bool clicked = false;
EX bool buttonclicked = false;
string lmouseovers;
bool inmenu = false;
bool wclick;
bool longclick;
bool verylongclick;
void handleScoreClick();
void openURL();
void displayTexts();
void controlMusic(int ticks);
void showHelp(MOBPAR_FORMAL, string nhelp) {
gotoHelp(nhelp);
}
bool useRangedOrb;
void handleclick(MOBPAR_FORMAL) {
if(handleCompass()) return;
if(buttonclicked || mouseout()) {
bool statkeys = andmode == 0 && !shmup::on && isize(screens) == 1;
if(statkeys && getcstat == 'g') {
movepcto(MD_DROP);
getcstat = 0;
}
else if(statkeys && getcstat == 'i') {
if(inv::on) pushScreen(inv::show);
getcstat = 0;
}
else if(statkeys && getcstat == 't') {
if(playermoved && items[itStrongWind]) {
cell *c = whirlwind::jumpDestination(cwt.at);
if(c) centerover = c;
}
targetRangedOrb(centerover, roKeyboard);
getcstat = 0;
}
else if(statkeys && getcstat == 'f') {
bow::switch_fire_mode();
getcstat = 0;
}
else if(getcstat != SDLK_F1 && getcstat != 'i' && getcstat != 't') {
int px = mousex < current_display->xcenter ? 0 : 1;
int py = mousey < current_display->ycenter ? 0 : 1;
if(isize(screens) == 1) {
if(px == 0 && py == 1) {
if(andmode == 0 && shmup::on) ;
else andmode = 10;
}
if(px == 1 && py == 1) {
if(andmode == 0 && shmup::on) ; // just fire, do not change modes
else {
if(andmode == 1) {
ors::reset();
centerpc(INF);
View = Id;
centerover = cwt.at;
}
andmode = 11;
}
}
if(px == 0 && py == 0) andmode = 22;
if(px == 1 && py == 0) andmode = 13;
}
}
else {
if(andmode == 0 && help != "@") {
addMessage(mouseovers);
showHelp(MOBPAR_ACTUAL, help);
andmode = 10;
getcstat = 0;
return;
}
}
}
if(andmode == 0 && isize(screens) == 1 && !mouseout()) {
bool forcetarget = longclick;
if(mouseover && targetclick && targetRangedOrb(mouseover, forcetarget ? roMouseForce : roMouse)) {
;
}
else if(!forcetarget) {
if(WDIM == 3 && wclick) movepcto(-1);
else if(GDIM == 3) mousemovement();
else movepcto(mousedest);
}
}
if(andmode == 10) {
if(!playerfound) {
centerpc(INF);
View = Id;
centerover = cwt.at;
}
playermoved = true;
}
if(andmode >= 10) andmode -= 10;
if(andmode == 3) {
pushScreen(showGameMenu);
andmode = 0;
}
}
int touchedAt;
#if CAP_ANDROIDSHARE
void shareScore(MOBPAR_FORMAL);
#endif
#if CAP_ORIENTATION
int first_check, last_check;
transmatrix main_last_orientation;
void apply_orientation() {
if(ticks > last_check + 2000) first_check = ticks;
last_check = ticks;
transmatrix T = MirrorX * hr::getOrientation() * MirrorX;
if(ticks < first_check + 500)
main_last_orientation = T;
else {
transmatrix next_orientation = T;
rotate_view(main_last_orientation);
if(WDIM == 2 && vid.fixed_yz) {
if(View[0][2] || View[1][2] || View[2][2]) {
View = cspin(0, 2, -atan2(View[0][2], View[2][2])) * View;
View = cspin(1, 2, -atan2(View[1][2], View[2][2])) * View;
}
}
rotate_view(inverse(next_orientation));
main_last_orientation = next_orientation;
}
}
#endif
EX void mobile_draw(MOBPAR_FORMAL) {
apply_memory_reserve();
optimizeview();
int lastt = ticks; ticks = SDL_GetTicks();
if(lastt > ticks) lastt = ticks;
int tdiff = ticks - lastt;
ors::check_orientation();
if(GDIM == 3 && !shmup::on && !rug::rugged)
apply_orientation();
if(rug::rugged) {
rug::using_rugview urv;
apply_orientation();
}
if(playermoved && vid.sspeed > -4.99)
centerpc(tdiff / 1000.0 * exp(vid.sspeed));
if(shmup::on && (andmode == 0 || andmode == 10) && isize(screens) == 1)
shmup::turn(tdiff);
safety = false;
vid.fsize = (min(vid.xres, vid.yres) * vid.fontscale + 50) / 3200;
mouseoh = mouseh;
gtouched = mousepressed = clicked;
wclick = lclicked && ticks > touchedAt + 250;
longclick = lclicked && ticks > touchedAt + 500;
verylongclick = longclick && ticks > touchedAt + 1000;
useRangedOrb =
longclick || (!(vid.shifttarget & 2) && haveRangedOrb() && lmouseover && lmouseover->cpdist > 1);
targetclick = ((vid.shifttarget & 2) && !shmup::on) ? longclick : true;
if(shmup::on) {
using namespace shmupballs;
if(hypot(mousex - xfire, mousey - yb) < rad) targetclick = false;
if(hypot(mousex - xmove, mousey - yb) < rad) targetclick = false;
}
if(cmode & sm::NORMAL) {
lmouseover_distant = mouseover;
lmouseover = (gtouched && lclicked) ? mouseover : NULL;
if(!shmup::on && !useRangedOrb && vid.mobilecompasssize) {
using namespace shmupballs;
int dx = mousex - xmove;
int dy = mousey - yb;
int h = hypot(dx, dy);
if(h < rad) {
if(h < rad*SKIPFAC) { lmouseover = cwt.at; mousedest.d = -1; }
else {
double d = vid.revcontrol ? -1 : 1;
mouseh = shiftless(hpxy(dx * d / rad, dy * d / rad));
calcMousedest();
}
}
}
if(andmode == 0 && !useRangedOrb && gtouched && lclicked) {
lmouseover = mousedest.d >= 0 ? cwt.at->modmove(cwt.spin + mousedest.d) : cwt.at;
}
}
#if CAP_RUG
if(rug::rugged)
mouseh = rug::gethyper(mousex, mousey);
else
#endif
mouseh = gethyper(mousex, mousey);
inmenu = isize(screens) > 1;
if(!inmenu && vid.stereo_mode == sLR && ors::mode)
mousex = vid.xres/2, mousey = vid.yres/2, mouseh = shiftless(sphereflip * C0);
frames++;
models::configure();
if(ticks > lastt) tortoise::updateVals(ticks - lastt);
if(clicked && !lclicked) touchedAt = ticks;
#if CAP_XGD
graphdata.clear();
#endif
getcstat = 0; shiftmul = 1; getcshift = 1;
drawscreen();
shiftmul = getcshift;
calcMousedest();
if(lclicked && !clicked && !inmenu) handleclick(MOBPAR_ACTUAL);
if(inmenu && !clicked && !lclicked) inmenu = false;
if(!clicked && !lclicked) invslider = false;
bool keyreact = lclicked && !clicked;
#if CAP_MENUSCALING
if(true) {
using namespace dialog::zoom;
if(zoomoff || !(cmode & sm::ZOOMABLE)) nozoom();
else if(clicked && !lclicked) initzoom();
else if(!clicked && zoomf > 1) stopzoom();
}
#endif
if(inslider) keyreact = true;
if(invslider || getcstat == PSEUDOKEY_LIST_SLIDER) keyreact = true;
#if CAP_ANDROIDSHARE
if(getcstat == 's'-96 && keyreact) {
popScreenAll();
shareScore(MOBPAR_ACTUAL);
}
#endif
bool normal_reaction = !inmenu;
if(normal_reaction && vid.stereo_mode == sLR) {
normal_reaction = false;
if(lclicked && !clicked) {
if(rug::rugged)
rug::select();
else if((ors::mode || GDIM == 3) && !verylongclick)
normal_reaction = true;
else
pushScreen(showStereo);
}
}
if(andmode == 2 && isize(screens) != 1) andmode = 12;
if((cmode & sm::NORMAL) && getcstat == '-')
getcstat = 0;
if(keyreact) {
handlekey(getcstat, getcstat);
}
#if ISIOS
displayTexts();
#endif
static int lticks_rug;
if(clicked && lclicked && andmode == 1 && normal_reaction) {
if(GDIM == 3 && !rug::rugged) {
View = cpush(2, -(ticks - lticks_rug) / 2500.) * View;
playermoved = false;
}
else if(!mouseout2() && mouseoh[2] < 50 && mouseh[2] < 50 && !rug::rugged) {
panning(mouseoh, mouseh);
}
}
#if CAP_RUG && CAP_ANIMATIONS
if(andmode == 1 && normal_reaction && rug::rugged && clicked && rug::move_on_touch)
anims::animate_rug_movement(rug::move_on_touch * (ticks - lticks_rug) / 2500.);
#endif
lticks_rug = ticks;
if(andmode == 1 && lclicked && !clicked && normal_reaction && mouseover)
mine::performMarkCommand(mouseover);
if(clicked && andmode == 2 && (mouseover != lmouseover || mouseovers != lmouseovers) && normal_reaction) {
addMessage(mouseovers);
lmouseovers = mouseovers;
}
if(andmode == 10 && clicked != lclicked) andmode = 0;
if(andmode == 20 && clicked != lclicked) andmode = 10;
if(andmode == 2 && lclicked && !clicked) {
showHelp(MOBPAR_ACTUAL, help);
}
else if(andmode == 4) {
achievement_final(false);
}
if(clicked && andmode == 12 && (mouseover != lmouseover || mouseovers != lmouseovers)) {
addMessage(mouseovers);
lmouseovers = mouseovers;
}
if(clicked != lclicked)
flashMessages();
// END
lclicked = clicked;
#if ISIOS
controlMusic(ticks - lastt);
#endif
}
#endif
}