1 // Hyperbolic Rogue -- initialization, and stuff related to mobiles
2 // Copyright (C) 2011-2018 Zeno Rogue, see 'hyper.cpp' for details
3 
4 /** \file init.cpp
5  *  \brief initialization, and stuff related to mobiles
6  */
7 
8 #include "hyper.h"
9 namespace hr {
10 
11 #if ISANDROID
buildScoreDescription()12 string buildScoreDescription() {
13   string s;
14   time_t timer;
15   timer = time(NULL);
16   char buf[128]; strftime(buf, 128, "%c", localtime(&timer));
17   char buf2[128];
18 
19   s += XLAT("HyperRogue for Android");
20   s += " ( " VER "), http://www.roguetemple.com/z/hyper/\n";
21   s += XLAT("Date: %1 time: %2 s ", buf, getgametime_s());
22   s += XLAT("distance: %1\n", its(celldist(cwt.at)));
23   // s += buf2;
24   if(cheater) s += XLAT("Cheats: ") + its(cheater) + "\n";
25   s += XLAT("Score: ") + its(gold());
26 
27   for(int i=0; i<ittypes; i++) if(items[i]) {
28     string t = XLATN(iinf[i].name);
29     sprintf(buf2, " %s (%d)", t.c_str(), items[i]);
30     s += buf2;
31     }
32   s += "\n";
33   s += XLAT("Kills: ") + its(tkills());
34   for(int i=1; i<motypes; i++) if(kills[i]) {
35     string t = XLATN(minf[i].name);
36     sprintf(buf2, " %s (%d)", t.c_str(), kills[i]);
37     s += buf2;
38     }
39   s += "\n";
40 
41   for(int i=0; i<gamelog.size(); i++) if(gamelog[i].msg != "") s += gamelog[i].msg + "\n";
42 
43   return s;
44   }
45 #endif
46 
47 #if ISMOBILE
48 
49 int andmode;
50 
51 bool lclicked = false;
52 EX bool clicked = false;
53 EX bool buttonclicked = false;
54 string lmouseovers;
55 bool inmenu = false;
56 
57 bool wclick;
58 bool longclick;
59 bool verylongclick;
60 
61 void handleScoreClick();
62 void openURL();
63 void displayTexts();
64 void controlMusic(int ticks);
65 
showHelp(MOBPAR_FORMAL,string nhelp)66 void showHelp(MOBPAR_FORMAL, string nhelp) {
67   gotoHelp(nhelp);
68   }
69 
70 bool useRangedOrb;
71 
handleclick(MOBPAR_FORMAL)72 void handleclick(MOBPAR_FORMAL) {
73 
74     if(handleCompass()) return;
75 
76     if(buttonclicked || mouseout()) {
77 
78       bool statkeys = andmode == 0 && !shmup::on && isize(screens) == 1;
79 
80       if(statkeys && getcstat == 'g') {
81         movepcto(MD_DROP);
82         getcstat = 0;
83         }
84 
85       else if(statkeys && getcstat == 'i') {
86         if(inv::on) pushScreen(inv::show);
87         getcstat = 0;
88         }
89 
90       else if(statkeys && getcstat == 't') {
91         if(playermoved && items[itStrongWind]) {
92           cell *c = whirlwind::jumpDestination(cwt.at);
93           if(c) centerover = c;
94           }
95         targetRangedOrb(centerover, roKeyboard);
96         getcstat = 0;
97         }
98 
99       else if(getcstat != SDLK_F1 && getcstat != 'i' && getcstat != 't') {
100         int px = mousex < current_display->xcenter ? 0 : 1;
101         int py = mousey < current_display->ycenter ? 0 : 1;
102 
103         if(isize(screens) == 1) {
104           if(px == 0 && py == 1) {
105             if(andmode == 0 && shmup::on) ;
106             else andmode = 10;
107             }
108           if(px == 1 && py == 1) {
109             if(andmode == 0 && shmup::on) ; // just fire, do not change modes
110             else {
111               if(andmode == 1) {
112                 ors::reset();
113                 centerpc(INF);
114                 View = Id;
115                 centerover = cwt.at;
116                 }
117               andmode = 11;
118               }
119             }
120           if(px == 0 && py == 0) andmode = 22;
121           if(px == 1 && py == 0) andmode = 13;
122           }
123         }
124 
125       else {
126         if(andmode == 0 && help != "@") {
127           addMessage(mouseovers);
128           showHelp(MOBPAR_ACTUAL, help);
129 	  andmode = 10;
130           getcstat = 0;
131           return;
132           }
133         }
134       }
135 
136     if(andmode == 0 && isize(screens) == 1 && !mouseout()) {
137 
138       bool forcetarget = longclick;
139 
140       if(mouseover && targetclick && targetRangedOrb(mouseover, forcetarget ? roMouseForce : roMouse)) {
141         ;
142         }
143       else if(!forcetarget) {
144         if(WDIM == 3 && wclick) movepcto(-1);
145         else if(GDIM == 3) mousemovement();
146         else movepcto(mousedest);
147         }
148       }
149 
150     if(andmode == 10) {
151       if(!playerfound) {
152         centerpc(INF);
153         View = Id;
154         centerover = cwt.at;
155         }
156       playermoved = true;
157       }
158 
159     if(andmode >= 10) andmode -= 10;
160 
161   if(andmode == 3) {
162     if(tour::on)
163       showMissionScreen();
164     else
165       pushScreen(showMainMenu);
166     andmode = 0;
167     }
168   }
169 
170 int touchedAt;
171 
172 #if CAP_ANDROIDSHARE
173 void shareScore(MOBPAR_FORMAL);
174 #endif
175 
176 #if CAP_ORIENTATION
177 int first_check, last_check;
178 transmatrix main_last_orientation;
179 
apply_orientation()180 void apply_orientation() {
181   if(ticks > last_check + 2000) first_check = ticks;
182   last_check = ticks;
183   transmatrix T = MirrorX * hr::getOrientation() * MirrorX;
184   if(ticks < first_check + 500)
185     main_last_orientation = T;
186   else {
187     transmatrix next_orientation = T;
188     rotate_view(main_last_orientation);
189     if(WDIM == 2 && vid.fixed_yz) {
190      if(View[0][2] || View[1][2] || View[2][2]) {
191         View = cspin(0, 2, -atan2(View[0][2], View[2][2])) * View;
192         View = cspin(1, 2, -atan2(View[1][2], View[2][2])) * View;
193         }
194       }
195     rotate_view(inverse(next_orientation));
196     main_last_orientation = next_orientation;
197     }
198   }
199 #endif
200 
mobile_draw(MOBPAR_FORMAL)201 EX void mobile_draw(MOBPAR_FORMAL) {
202 
203   apply_memory_reserve();
204   optimizeview();
205 
206   int lastt = ticks; ticks = SDL_GetTicks();
207   if(lastt > ticks) lastt = ticks;
208   int tdiff = ticks - lastt;
209 
210   ors::check_orientation();
211 
212   if(GDIM == 3 && !shmup::on && !rug::rugged)
213     apply_orientation();
214 
215   if(rug::rugged) {
216     rug::using_rugview urv;
217     apply_orientation();
218     }
219 
220   if(playermoved && vid.sspeed > -4.99)
221     centerpc(tdiff / 1000.0 * exp(vid.sspeed));
222 
223   if(shmup::on && (andmode == 0 || andmode == 10) && isize(screens) == 1)
224     shmup::turn(tdiff);
225 
226   safety = false;
227   vid.fsize = (min(vid.xres, vid.yres) * vid.fontscale + 50) / 3200;
228 
229   mouseoh = mouseh;
230   gtouched = mousepressed = clicked;
231 
232   wclick = lclicked && ticks > touchedAt + 250;
233   longclick = lclicked && ticks > touchedAt + 500;
234   verylongclick = longclick && ticks > touchedAt + 1000;
235 
236   useRangedOrb =
237     longclick || (!(vid.shifttarget & 2) && haveRangedOrb() && lmouseover && lmouseover->cpdist > 1);
238 
239   targetclick = ((vid.shifttarget & 2) && !shmup::on) ? longclick : true;
240 
241   if(shmup::on) {
242     using namespace shmupballs;
243     if(hypot(mousex - xfire, mousey - yb) < rad) targetclick = false;
244     if(hypot(mousex - xmove, mousey - yb) < rad) targetclick = false;
245     }
246 
247   if(cmode & sm::NORMAL) {
248     lmouseover_distant = mouseover;
249     lmouseover = (gtouched && lclicked) ? mouseover : NULL;
250     if(!shmup::on && !useRangedOrb && vid.mobilecompasssize) {
251       using namespace shmupballs;
252       int dx = mousex - xmove;
253       int dy = mousey - yb;
254       int h = hypot(dx, dy);
255       if(h < rad) {
256         if(h < rad*SKIPFAC) { lmouseover = cwt.at; mousedest.d = -1; }
257         else {
258           double d = vid.revcontrol ? -1 : 1;
259           mouseh = shiftless(hpxy(dx * d / rad, dy * d / rad));
260           calcMousedest();
261           }
262         }
263       }
264     if(andmode == 0 && !useRangedOrb && gtouched && lclicked) {
265       lmouseover = mousedest.d >= 0 ? cwt.at->modmove(cwt.spin + mousedest.d) : cwt.at;
266       }
267     }
268 
269   #if CAP_RUG
270   if(rug::rugged)
271     mouseh = rug::gethyper(mousex, mousey);
272   else
273   #endif
274     mouseh = gethyper(mousex, mousey);
275 
276   inmenu = isize(screens) > 1;
277 
278   if(!inmenu && vid.stereo_mode == sLR && ors::mode)
279     mousex = vid.xres/2, mousey = vid.yres/2, mouseh = shiftless(sphereflip * C0);
280 
281   frames++;
282   models::configure();
283 
284   if(ticks > lastt) tortoise::updateVals(ticks - lastt);
285 
286   if(clicked && !lclicked) touchedAt = ticks;
287 
288 #if CAP_XGD
289   graphdata.clear();
290 #endif
291   getcstat = 0; shiftmul = 1; getcshift = 1;
292   drawscreen();
293   shiftmul = getcshift;
294   calcMousedest();
295 
296   if(lclicked && !clicked && !inmenu) handleclick(MOBPAR_ACTUAL);
297 
298   if(inmenu && !clicked && !lclicked) inmenu = false;
299 
300   bool keyreact = lclicked && !clicked;
301 
302 #if CAP_MENUSCALING
303   if(true) {
304     using namespace dialog::zoom;
305     if(zoomoff || !(cmode & sm::ZOOMABLE)) nozoom();
306     else if(clicked && !lclicked) initzoom();
307     else if(!clicked && zoomf > 1) stopzoom();
308     }
309 #endif
310 
311   if(inslider) keyreact = true;
312 
313 #if CAP_ANDROIDSHARE
314   if(getcstat == 's'-96 && keyreact) {
315     popScreenAll();
316     shareScore(MOBPAR_ACTUAL);
317     }
318 #endif
319 
320   bool normal_reaction = !inmenu;
321 
322   if(normal_reaction && vid.stereo_mode == sLR) {
323     normal_reaction = false;
324     if(lclicked && !clicked) {
325       if(rug::rugged)
326         rug::select();
327       else if((ors::mode || GDIM == 3) && !verylongclick)
328         normal_reaction = true;
329       else
330         pushScreen(showStereo);
331       }
332     }
333 
334   if(andmode == 2 && isize(screens) != 1) andmode = 12;
335 
336   if((cmode & sm::NORMAL) && getcstat == '-')
337     getcstat = 0;
338 
339   if(keyreact) {
340     handlekey(getcstat, getcstat);
341     }
342 
343   #if ISIOS
344   displayTexts();
345   #endif
346 
347   static int lticks_rug;
348 
349   if(clicked && lclicked && andmode == 1 && normal_reaction) {
350     if(GDIM == 3 && !rug::rugged) {
351       View = cpush(2, -(ticks - lticks_rug) / 2500.) * View;
352       playermoved = false;
353       }
354     else if(!mouseout2() && mouseoh[2] < 50 && mouseh[2] < 50 && !rug::rugged) {
355       panning(mouseoh, mouseh);
356       }
357     }
358 
359 #if CAP_RUG && CAP_ANIMATIONS
360   if(andmode == 1 && normal_reaction && rug::rugged && clicked && rug::move_on_touch)
361     anims::animate_rug_movement(rug::move_on_touch * (ticks - lticks_rug) / 2500.);
362 #endif
363 
364   lticks_rug = ticks;
365 
366   if(andmode == 1 && lclicked && !clicked && normal_reaction && mouseover)
367     mine::performMarkCommand(mouseover);
368 
369   if(clicked && andmode == 2 && (mouseover != lmouseover || mouseovers != lmouseovers) && normal_reaction) {
370     addMessage(mouseovers);
371     lmouseovers = mouseovers;
372     }
373 
374   if(andmode == 10 && clicked != lclicked) andmode = 0;
375   if(andmode == 20 && clicked != lclicked) andmode = 10;
376 
377   if(andmode == 2 && lclicked && !clicked) {
378     showHelp(MOBPAR_ACTUAL, help);
379     }
380 
381   else if(andmode == 4) {
382     achievement_final(false);
383     }
384 
385   if(clicked && andmode == 12 && (mouseover != lmouseover || mouseovers != lmouseovers)) {
386     addMessage(mouseovers);
387     lmouseovers = mouseovers;
388     }
389 
390   if(clicked != lclicked)
391     flashMessages();
392 
393   // END
394   lclicked = clicked;
395 
396 #if ISIOS
397   controlMusic(ticks - lastt);
398   #endif
399   }
400 
401 #endif
402 
403 }
404