diff --git a/graph.cpp b/graph.cpp index 08c37c540..d25bbb719 100644 --- a/graph.cpp +++ b/graph.cpp @@ -2412,6 +2412,7 @@ void drawaura() { } } glflush(); + current_display->set_projection(0, false); glhr::switch_mode(glhr::gmVarColored, glhr::shader_projection::standard); glhr::id_modelview(); glhr::prepare(auravertices); diff --git a/hyper.cpp b/hyper.cpp index a858777c6..c2cb53d6f 100644 --- a/hyper.cpp +++ b/hyper.cpp @@ -65,8 +65,10 @@ int main(int argc, char **argv) { start_game(); #endif #if !ISWEB - if(showstartmenu && !vid.skipstart) + if(showstartmenu && !vid.skipstart) { + startanims::pick(); pushScreen(showStartMenu); + } #endif mainloop(); finishAll(); diff --git a/hyper.h b/hyper.h index 9828ff867..7b1223252 100644 --- a/hyper.h +++ b/hyper.h @@ -2590,6 +2590,8 @@ extern bool useRangedOrb; void addaura(hyperpoint h, color_t col, int fd); void addauraspecial(hyperpoint h, color_t col, int dir); +void drawaura(); +void clearaura(); void drawBug(const cellwalker& cw, color_t col); @@ -4429,6 +4431,11 @@ namespace anims { extern ld period, cycle_length, parabolic_length, rug_angle, circle_radius, circle_spins; } +namespace startanims { + extern reaction_t current; + void pick(); + } + extern int animation_lcm; extern ld animation_factor; ld parseld(const string& s); diff --git a/menus.cpp b/menus.cpp index f83efc59d..8bcef6a60 100644 --- a/menus.cpp +++ b/menus.cpp @@ -255,7 +255,7 @@ void showMainMenu() { else if(uni == 'd') pushScreen(showDisplayMode); else if(uni == 'm') pushScreen(showChangeMode); else if(uni == 'R') dialog::do_if_confirmed([] { - popScreenAll(), pushScreen(showStartMenu); + popScreenAll(), startanims::pick(), pushScreen(showStartMenu); }); #if CAP_SAVE else if(uni == 't') scores::load(); @@ -602,7 +602,7 @@ void showStartMenu() { daily_mode = 20; } - gamescreen(2); + startanims::current(); getcstat = ' '; @@ -813,6 +813,7 @@ void showStartMenu() { clearMessages(); welcomeMessage(); } + else if(sym == SDLK_F5) startanims::pick(); }; } diff --git a/polygons.cpp b/polygons.cpp index 753a5f274..eddb22728 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -1526,6 +1526,7 @@ hpcshape shWestHat1, shWestHat2, shGunInHand, shKnightArmor, shKnightCloak, shWightCloak, shGhost, shEyes, shSlime, shJelly, shJoint, shWormHead, shTentHead, shShark, shWormSegment, shSmallWormSegment, shWormTail, shSmallWormTail, + shMiniGhost, shMiniEyes, shHedgehogBlade, shHedgehogBladePlayer, shWolfBody, shWolfHead, shWolfLegs, shWolfEyes, shWolfFrontLeg, shWolfRearLeg, shWolfFrontPaw, shWolfRearPaw, @@ -2356,6 +2357,7 @@ void buildpolys() { // monsters bshape(shGhost, PPR::MONSTER_BODY, scalefactor, 69); + bshape(shMiniGhost, PPR::MONSTER_BODY, scalefactor/3, 69); bshape(shGargoyleWings, PPR::MONSTER_CLOAK, scalefactor, 70); bshape(shGargoyleBody, PPR::MONSTER_BODY, scalefactor, 71); bshape(shDogStripes, PPR::MONSTER_ARMOR1, scalefactor, 72); @@ -2490,6 +2492,7 @@ void buildpolys() { bshape(shFlowerHand, PPR::MONSTER_WPN, scalefactor, 133); bshape(shPFace, PPR::MONSTER_FACE, scalefactor, 134); bshape(shEyes, PPR::MONSTER_EYE0, scalefactor, 135); + bshape(shMiniEyes, PPR::MONSTER_EYE0, scalefactor/3, 135); bshape(shShark, PPR::MONSTER_BODY, scalefactor, 136); bshape(shTinyShark, PPR::MONSTER_BODY, scalefactor / 2, 136); bshape(shBugBody, PPR::MONSTER_BODY, scalefactor, 137); diff --git a/screenshot.cpp b/screenshot.cpp index 39033b227..53af6655d 100644 --- a/screenshot.cpp +++ b/screenshot.cpp @@ -1006,4 +1006,124 @@ bool center_music() { } #endif + +namespace startanims { + +int ticks_start = 0; + +void null_animation() { + gamescreen(2); + } + +void joukowsky() { + dynamicval dm(pmodel, mdJoukowskyInverted); + dynamicval dt(conformal::model_orientation, ticks / 25.); + dynamicval dv(vid.use_smart_range, 2); + dynamicval ds(vid.scale, 1/4.); + conformal::configure(); + dynamicval dc(ringcolor, 0); + gamescreen(2); + } + +void bandspin() { + dynamicval dm(pmodel, mdBand); + dynamicval dt(conformal::model_orientation, ticks / 25.); + dynamicval dv(vid.use_smart_range, 2); + conformal::configure(); + gamescreen(2); + } + +void perspective() { + ld x = sin(ticks / 1500.); + x += 1; + x /= 2; + x *= 1.5; + x = tan(x); + dynamicval da(vid.alpha, x); + dynamicval ds(vid.scale, (1+x)/2); + calcparam(); + gamescreen(2); + } + +void rug() { + dynamicval b(rug::rugged, true); + rug::physics(); + rug::apply_rotation(rotmatrix(ticks / 3000., 1, 2)); + gamescreen(2); + rug::apply_rotation(rotmatrix(-ticks / 3000., 1, 2)); + } + +void spin_around() { + dynamicval da(vid.alpha, 999); + dynamicval ds(vid.scale, 500); + ld alpha = 2 * M_PI * ticks / 10000.; + ld circle_radius = acosh(2.); + dynamicval dv(View, spin(-cos_auto(circle_radius)*alpha) * xpush(circle_radius) * spin(alpha) * View); + gamescreen(2); + } + +reaction_t add_to_frame; + +void draw_ghost(const transmatrix V) { + queuepoly(V, shMiniGhost, 0xFFFFFFC0); + queuepoly(V, shMiniEyes, 0xFF); + } + +void row_of_ghosts() { + dynamicval r(add_to_frame, [] { + for(ld x=-5; x<=5; x+=0.2) + for(ld y=-5; y<=5; y+=0.2) { + ld ay = y + (ticks % 1000) / 1000.; + draw_ghost(xpush(x) * spin(M_PI/2) * xpush(ay)); + } + }); + dynamicval rd(mapeditor::drawplayer, false); + gamescreen(2); + } + +void army_of_ghosts() { + dynamicval rd(mapeditor::drawplayer, false); + dynamicval r(add_to_frame, [] { + for(ld x=-3; x<=3; x+=0.5) { + int minv = int(cosh(x) * 3); + for(ld y=-minv; y<=minv; y+=0.5) { + ld ay = y + (ticks % 2000) / 2000.; + draw_ghost(spin(M_PI/2) * xpush(ay / cosh(x)) * spin(-M_PI/2) * xpush(x) * spin(M_PI/2)); + } + } + }); + gamescreen(2); + } + +void ghost_spiral() { + dynamicval r(add_to_frame, [] { + ld t = (ticks - ticks_start - 2000) / 150000.; + for(ld i=3; i<=40; i++) { + draw_ghost(spin(t * i * 2 * M_PI) * xpush(asinh(15. / i)) * spin(M_PI/2)); + } + }); + gamescreen(2); + } + +// more start animations: +// - fly a ghost around center, in Gans model +// - triangle edges? + +reaction_t current = null_animation; + +void pick() { + if(((gold() > 0 || tkills() > 0) && canmove) || geometry != gNormal || ISWEB || ISMOBILE) { + current = null_animation; + return; + } + vector known = { null_animation, perspective, joukowsky, bandspin, rug, spin_around, row_of_ghosts, ghost_spiral, army_of_ghosts }; + int id = rand() % 9; + current = known[id]; + ticks_start = ticks; + if(id == 4) rug::init(), rug::rugged = false; + } + +auto sanimhook = addHook(hooks_frame, 100, []() { if(add_to_frame) add_to_frame(); }); + +} }