diff --git a/achievement.cpp b/achievement.cpp index 3e16fe8b..c60a3b49 100644 --- a/achievement.cpp +++ b/achievement.cpp @@ -633,7 +633,7 @@ void achievement_victory(bool hyper) { if(chaosmode) return; DEBB(DF_STEAM, (debugfile,"after checks\n")) - int t = savetime + time(NULL) - timerstart; + int t = getgametime(); if(hyper && shmup::on) return; if(hyper && inv::on) return; diff --git a/basegraph.cpp b/basegraph.cpp index 4813cc6f..fe1cd616 100644 --- a/basegraph.cpp +++ b/basegraph.cpp @@ -725,6 +725,12 @@ void flashMessages() { } } +string fullmsg(msginfo& m) { + string s = m.msg; + if(m.quantity > 1) s += " (x" + its(m.quantity) + ")"; + return s; + } + void addMessageToLog(msginfo& m, vector& log) { if(size(log) != 0) { @@ -735,7 +741,7 @@ void addMessageToLog(msginfo& m, vector& log) { return; } } - if(size(log) < 200) + if(size(log) < 1000) log.push_back(m); else { for(int i=0; i 1) s += " (x" + its(msgs[j].quantity) + ")"; - drawmessage(s, y, col); + drawmessage(fullmsg(msgs[j]), y, col); } } else { @@ -829,10 +836,8 @@ void drawmessages() { int age = msgs[j].flashout * (t - msgs[j].stamp); int x = vid.msgleft ? 0 : vid.xres / 2; int y = vid.yres - vid.fsize * (size(msgs) - j) - (ISIOS ? 4 : 0); - string s = msgs[j].msg; - if(msgs[j].quantity > 1) s += " (x" + its(msgs[j].quantity) + ")"; poly_outline = gradient(bordcolor, backcolor, 0, age, 256*vid.flashtime) << 8; - displayfr(x, y, 1, vid.fsize, s, gradient(forecolor, backcolor, 0, age, 256*vid.flashtime), vid.msgleft ? 0 : 8); + displayfr(x, y, 1, vid.fsize, fullmsg(msgs[j]), gradient(forecolor, backcolor, 0, age, 256*vid.flashtime), vid.msgleft ? 0 : 8); } } } diff --git a/config.cpp b/config.cpp index d1caabcc..5af030d4 100644 --- a/config.cpp +++ b/config.cpp @@ -188,6 +188,10 @@ void initConfig() { // basic config addsaver(vid.flashtime, "flashtime", 8); + addsaver(vid.msgleft, "message style", 2); + addsaver(vid.msglimit, "message limit", 5); + addsaver(vid.timeformat, "message log time format", 0); + addsaver(vid.mobilecompasssize, "mobile compass size", 30); addsaver(vid.axes, "movement help", 1); addsaver(vid.shifttarget, "shift-targetting", 2); @@ -302,9 +306,6 @@ void initConfig() { addsaver(viewdists, "expansion mode"); - addsaver(vid.msgleft, "message style", 2); - addsaver(vid.msglimit, "message limit", 5); - #if CAP_SHMUP shmup::initConfig(); #endif diff --git a/game.cpp b/game.cpp index 0d5369ce..1c2df4ba 100644 --- a/game.cpp +++ b/game.cpp @@ -3789,7 +3789,6 @@ void killHardcorePlayer(int id, flagtype flags) { else { canmove = false; achievement_final(true); - msgscroll = 0; } } @@ -5669,7 +5668,6 @@ void checkmove() { if(multi::players > 1 && !multi::checkonly) return; if(hardcore) return; - msgscroll = 0; bool orbusedbak[ittypes]; // do not activate orbs! diff --git a/hyper.h b/hyper.h index b0b78abe..643bf483 100644 --- a/hyper.h +++ b/hyper.h @@ -237,8 +237,6 @@ namespace shmup { // graph -extern int msgscroll; - void showMissionScreen(); void restartGraph(); @@ -370,6 +368,7 @@ struct videopar { bool drawmousecircle; // draw the circle around the mouse bool skipstart; // skip the start menu int quickmouse; // quick mouse on the map + int timeformat; // time format used in the message log }; extern videopar vid; @@ -1374,6 +1373,9 @@ charstyle& getcs(int id = multi::cpid); struct msginfo { int stamp; + time_t rtstamp; + int gtstamp; + int turnstamp; char flashout; char spamtype; int quantity; @@ -1582,3 +1584,11 @@ void gainItem(eItem it); void destroyTrapsOn(cell *c); void destroyTrapsAround(cell *c); + +extern int messagelogpos; + +void showMessageLog(); + +int getgametime(); +string getgametime_s(int timespent = getgametime()); +extern int stampbase; diff --git a/init.cpp b/init.cpp index ccbf1652..ae8f6bf6 100644 --- a/init.cpp +++ b/init.cpp @@ -453,7 +453,7 @@ string buildScoreDescription() { s += XLAT("HyperRogue for Android"); s += " ( " VER "), http://www.roguetemple.com/z/hyper/\n"; - s += XLAT("Date: %1 time: %2 s ", buf, its(savetime + time(NULL) - timerstart)); + s += XLAT("Date: %1 time: %2 s ", buf, getgametime()); s += XLAT("distance: %1\n", its(celldist(cwt.c))); // s += buf2; if(cheater) s += XLAT("Cheats: ") + its(cheater) + "\n"; diff --git a/menus.cpp b/menus.cpp index fd2a1ea0..1271ff76 100644 --- a/menus.cpp +++ b/menus.cpp @@ -659,6 +659,17 @@ void showEuclideanMenu() { bool showstartmenu; +bool showHalloween() { + if(canmove) return false; + time_t t = time(NULL); + struct tm tm = *localtime(&t); + int month = tm.tm_mon + 1; + int day = tm.tm_mday; + if(month == 10 && day >= 24) return true; + if(month == 11 && day <= 7) return true; + return false; + } + void showStartMenu() { gamescreen(2); @@ -700,6 +711,12 @@ void showStartMenu() { dialog::addInfo(XLAT("see the visualizations")); #endif + if(showHalloween()) { + dialog::addBreak(100); + dialog::addBigItem(XLAT1("Halloween"), 'z'); + dialog::addInfo(XLAT("Halloween mini-game")); + } + dialog::addBreak(100); dialog::addBigItem(XLAT("main menu"), 'm'); dialog::addInfo(XLAT("more options")); @@ -729,6 +746,19 @@ void showStartMenu() { if(shmup::on != (uni == 's')) restartGame('s'); clearMessages(); welcomeMessage(); + stampbase = ticks; + } + else if(uni == 'z') { + popScreenAll(); + resetModes(); + stampbase = ticks; + if(!sphere) { + specialland = laHalloween; + targetgeometry = gSphere; + restartGame('g'); + vid.alpha = 999; + vid.scale = 998; + } } #if CAP_TOUR else if(uni == 't') { @@ -751,8 +781,13 @@ void showStartMenu() { quitmainloop = true; else if(sym == SDLK_F1) gotoHelp(help); - else if(sym == SDLK_ESCAPE || sym == ' ') + else if(sym == SDLK_ESCAPE || sym == ' ') { popScreen(); + timerstart = time(NULL); + stampbase = ticks; + clearMessages(); + welcomeMessage(); + } }; } @@ -774,3 +809,66 @@ void setAppropriateOverview() { } } +int messagelogpos; +int timeformat; +int stampbase; + +string gettimestamp(msginfo& m) { + char buf[128]; + switch(timeformat) { + case 0: + return its(m.turnstamp); + case 1: + strftime(buf, 128, "%H:%M:%S", localtime(&m.rtstamp)); + return buf; + case 2: + snprintf(buf, 128, "%2d:%02d", m.gtstamp/60, m.gtstamp % 60); + return buf; + case 3: + { int t = m.stamp - stampbase; + bool sign = t < 0; + if(sign) t = -t; + snprintf(buf, 128, "%2d:%02d.%03d", t/60000, (t/1000) % 60, t % 1000); + string s = buf; + if(sign) s = "-"+s; + return s; + } + } + return ""; + } + +void showMessageLog() { + DEBB(DF_GRAPH, (debugfile,"show message log\n")); + + int lines = vid.yres / vid.fsize - 2; + int maxpos = size(gamelog) - lines; + messagelogpos = min(messagelogpos, maxpos); + messagelogpos = max(messagelogpos, 0); + + for(int y=0; y= 30 || tkills() >= 50) && !cheater && !quitsaves(); } -int msgscroll = 0; +int getgametime() { + return (int) (savetime + (timerstopped ? 0 : (time(NULL) - timerstart))); + } -string timeline() { - int timespent = (int) (savetime + (timerstopped ? 0 : (time(NULL) - timerstart))); +string getgametime_s(int timespent) { char buf[20]; sprintf(buf, "%d:%02d", timespent/60, timespent % 60); + return buf; + } + +string timeline() { return shmup::on ? - XLAT("%1 knives (%2)", its(turncount), buf) + XLAT("%1 knives (%2)", its(turncount), getgametime_s()) : - XLAT("%1 turns (%2)", its(turncount), buf); + XLAT("%1 turns (%2)", its(turncount), getgametime_s()); } void noaction() {} @@ -258,29 +263,21 @@ hint hints[] = { { 0, - []() { - if(canmove) return false; - time_t t = time(NULL); - struct tm tm = *localtime(&t); - int month = tm.tm_mon + 1; - int day = tm.tm_mday; - if(month == 10 && day >= 24) return true; - if(month == 11 && day <= 7) return true; - return false; - }, + []() { return showHalloween(); }, []() { dialog::addItem(XLAT("Halloween mini-game"), 'z'); }, [] () { if(!sphere) { + resetModes(); specialland = laHalloween; targetgeometry = gSphere; - restartGame('E'); + restartGame('g'); vid.alpha = 999; vid.scale = 998; } else { - restartGame('E'); + resetModes(); vid.alpha = 1; vid.scale = 1; } @@ -385,22 +382,6 @@ void showMission() { dialog::addInfo(timeline(), 0xC0C0C0); } - msgs.clear(); - if(msgscroll < 0) msgscroll = 0; - int gls = size(gamelog) - msgscroll; - int mnum = 0; - for(int i=gls-5; i=0) { - msginfo m; - m.spamtype = 0; - m.flashout = true; - m.stamp = ticks-128*vid.flashtime-128*(gls-i); - m.msg = gamelog[i].msg; - m.quantity = gamelog[i].quantity; - mnum++, - msgs.push_back(m); - } - dialog::addBreak(100); #if CAP_TOUR @@ -456,13 +437,10 @@ void showMission() { #if CAP_ANDROIDSHARE dialog::addItem(XLAT("SHARE"), 's'-96); #endif - dialog::addBreak(500); } + dialog::addItem(XLAT("message log"), 'l'); dialog::display(); - - if(mnum) - displayfr(vid.xres/2, vid.yres-vid.fsize*(mnum+1), 2, vid.fsize/2, XLAT("last messages:"), 0xC0C0C0, 8); } void handleKeyQuit(int sym, int uni) { @@ -480,11 +458,8 @@ void handleKeyQuit(int sym, int uni) { restartGame(); msgs.clear(); } - else if(sym == SDLK_UP || sym == SDLK_KP8 || sym == PSEUDOKEY_WHEELUP) msgscroll++; - else if(sym == SDLK_DOWN || sym == SDLK_KP2 || sym == PSEUDOKEY_WHEELDOWN) msgscroll--; - else if(sym == SDLK_PAGEUP || sym == SDLK_KP9) msgscroll+=5; - else if(sym == SDLK_PAGEDOWN || sym == SDLK_KP3) msgscroll-=5; else if(uni == 'v') popScreenAll(), pushScreen(showMainMenu); + else if(uni == 'l') popScreenAll(), pushScreen(showMessageLog), messagelogpos = size(gamelog); else if(uni == 'z') hints[hinttoshow].action(); else if(sym == SDLK_F3 || (sym == ' ' || sym == SDLK_HOME)) fullcenter(); @@ -502,7 +477,6 @@ void handleKeyQuit(int sym, int uni) { else if(doexiton(sym, uni) && !didsomething) { popScreen(); - msgscroll = 0; msgs.clear(); if(!canmove) { addMessage(XLAT("GAME OVER")); @@ -520,7 +494,6 @@ void showMissionScreen() { popScreenAll(); pushScreen(showMission); achievement_final(false); - msgscroll = 0; #if CAP_TOUR if(!tour::on)