mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-30 05:23:00 +00:00 
			
		
		
		
	animate parameters from the edit dialog
This commit is contained in:
		| @@ -211,8 +211,7 @@ namespace binary { | ||||
| auto bt_config = addHook(hooks_args, 0, [] () { | ||||
|   using namespace arg; | ||||
|   if(argis("-btwidth")) { | ||||
|     shift_arg_formula(vid.binary_width); | ||||
|     need_reset_geometry = true; | ||||
|     shift_arg_formula(vid.binary_width, delayed_geo_reset); | ||||
|     return 0; | ||||
|     } | ||||
|   return 1; | ||||
|   | ||||
							
								
								
									
										69
									
								
								config.cpp
									
									
									
									
									
								
							
							
						
						
									
										69
									
								
								config.cpp
									
									
									
									
									
								
							| @@ -639,9 +639,9 @@ void edit_sightrange() { | ||||
|       XLAT("Roughly 42% cells are on the edge of your sight range. Reducing " | ||||
|       "the sight range makes HyperRogue work faster, but also makes " | ||||
|       "the game effectively harder.")); | ||||
|     dialog::reaction = [] () {  | ||||
|       doOvergenerate(); | ||||
|       }; | ||||
|     dialog::reaction = doOvergenerate; | ||||
|     dialog::bound_low(1-getDistLimit()); | ||||
|     dialog::bound_up(allowIncreasedSight() ? gp::dist_2() * 5 : 0); | ||||
|     } | ||||
|   else { | ||||
|     dialog::editNumber(vid.smart_range_detail, 1, 50, 1, 8, XLAT("minimum visible cell in pixels"), ""); | ||||
| @@ -775,7 +775,7 @@ void showGraphConfig() { | ||||
|     if(xuni == 'j') { | ||||
|       dialog::editNumber(whatever, -10, 10, 1, 0, XLAT("whatever"),  | ||||
|         XLAT("Whatever.")); | ||||
|       dialog::reaction = resetGeometry; | ||||
|       dialog::reaction = delayed_geo_reset; | ||||
|       } | ||||
|    | ||||
|     if(xuni == 'a') dialog::editNumber(vid.sspeed, -5, 5, 1, 0,  | ||||
| @@ -827,7 +827,7 @@ void showGraphConfig() { | ||||
|     if(xuni == 'L') { | ||||
|       dialog::editNumber(vid.linequality, -3, 5, 1, 1, XLAT("line quality"),  | ||||
|         XLAT("Higher numbers make the curved lines smoother, but reduce the performance.")); | ||||
|       dialog::reaction = [] () { resetGeometry(); }; | ||||
|       dialog::reaction = delayed_geo_reset; | ||||
|       } | ||||
|    | ||||
|     if(xuni == 'C') { | ||||
| @@ -837,15 +837,17 @@ void showGraphConfig() { | ||||
|       } | ||||
|  | ||||
|   #if CAP_FRAMELIMIT     | ||||
|     if(xuni == 'l')  | ||||
|     if(xuni == 'l') { | ||||
|       dialog::editNumber(vid.framelimit, 5, 300, 10, 300, XLAT("framerate limit"), ""); | ||||
|       dialog::bound_low(5); | ||||
|       } | ||||
|   #endif | ||||
|        | ||||
|     if(xuni =='b') { | ||||
|       dialog::editNumber(fontscale, 25, 400, 10, 100, XLAT("font scale"), ""); | ||||
|       #if !ISMOBILE | ||||
|         dialog::reaction = [] () { setfsize = true; if(fontscale < 25) fontscale = 25; do_setfsize(); }; | ||||
|       #endif | ||||
|       const int minfontscale = ISMOBILE ? 50 : 25; | ||||
|       dialog::reaction = [] () { setfsize = true; do_setfsize(); }; | ||||
|       dialog::bound_low(minfontscale); | ||||
|       } | ||||
|    | ||||
|     if(xuni =='p')  | ||||
| @@ -962,9 +964,27 @@ void showBasicConfig() { | ||||
|  | ||||
|     if(CAP_AUDIO && xuni == 'b') { | ||||
|       dialog::editNumber(musicvolume, 0, 128, 10, 60, XLAT("background music volume"), ""); | ||||
|       dialog::reaction = [] () { | ||||
|         #if CAP_SDLAUDIO | ||||
|         Mix_VolumeMusic(musicvolume); | ||||
|         #endif | ||||
|         #if ISANDROID | ||||
|         settingsChanged = true; | ||||
|         #endif | ||||
|         }; | ||||
|       dialog::bound_low(0); | ||||
|       dialog::bound_up(MIX_MAX_VOLUME); | ||||
|       } | ||||
|  | ||||
|     if(CAP_AUDIO && xuni == 'e') { | ||||
|       dialog::editNumber(effvolume, 0, 128, 10, 60, XLAT("sound effects volume"), ""); | ||||
|       dialog::reaction = [] () { | ||||
|         #if ISANDROID | ||||
|         settingsChanged = true; | ||||
|         #endif | ||||
|         }; | ||||
|       dialog::bound_low(0); | ||||
|       dialog::bound_up(MIX_MAX_VOLUME); | ||||
|       } | ||||
|      | ||||
|     if(CAP_TRANS && xuni == 'l') | ||||
| @@ -1282,20 +1302,31 @@ void show3D() { | ||||
|     using namespace geom3; | ||||
|     dialog::handleNavigation(sym, uni); | ||||
|      | ||||
|     if(uni == 'n')  | ||||
|     if(uni == 'n') { | ||||
|       dialog::editNumber(geom3::highdetail, 0, 5, .5, 7, XLAT("High detail range"), ""); | ||||
|     else if(uni == 'm')  | ||||
|       dialog::reaction = [] () { | ||||
|         if(highdetail > middetail) middetail = highdetail; | ||||
|         }; | ||||
|       } | ||||
|     else if(uni == 'm') { | ||||
|       dialog::editNumber(geom3::middetail, 0, 5, .5, 7, XLAT("Mid detail range"), ""); | ||||
|       dialog::reaction = [] () { | ||||
|         if(highdetail > middetail) highdetail = middetail; | ||||
|         }; | ||||
|       } | ||||
|     else if(uni == 'c')  | ||||
|       tc_camera = ticks, | ||||
|       dialog::editNumber(geom3::camera, 0, 5, .1, 1, XLAT("Camera level above the plane"), ""); | ||||
|       dialog::editNumber(geom3::camera, 0, 5, .1, 1, XLAT("Camera level above the plane"), ""), | ||||
|       dialog::reaction = delayed_geo_reset; | ||||
|     else if(uni == 'g')  | ||||
|       tc_depth = ticks, | ||||
|       dialog::editNumber(geom3::depth, 0, 5, .1, 1, XLAT("Ground level below the plane"), ""); | ||||
|       dialog::editNumber(geom3::depth, 0, 5, .1, 1, XLAT("Ground level below the plane"), ""), | ||||
|       dialog::reaction = delayed_geo_reset; | ||||
|     else if(uni == 'a')  | ||||
|       projectionDialog(); | ||||
|     else if(uni == 'w') { | ||||
|       dialog::editNumber(geom3::wall_height, 0, 1, .1, .3, XLAT("Height of walls"), ""); | ||||
|       dialog::reaction = delayed_geo_reset; | ||||
|       dialog::extra_options = [] () { | ||||
|         dialog::addBoolItem(XLAT("auto-adjust in Goldberg grids"), geom3::gp_autoscale_heights, 'o'); | ||||
|         dialog::add_action([] () { | ||||
| @@ -1308,13 +1339,17 @@ void show3D() { | ||||
|         }; | ||||
|       } | ||||
|     else if(uni == 'l')  | ||||
|       dialog::editNumber(geom3::lake_top, 0, 1, .1, .25, XLAT("Level of water surface"), ""); | ||||
|       dialog::editNumber(geom3::lake_top, 0, 1, .1, .25, XLAT("Level of water surface"), ""), | ||||
|       dialog::reaction = delayed_geo_reset; | ||||
|     else if(uni == 'k')  | ||||
|       dialog::editNumber(geom3::lake_bottom, 0, 1, .1, .9, XLAT("Level of water bottom"), ""); | ||||
|       dialog::editNumber(geom3::lake_bottom, 0, 1, .1, .9, XLAT("Level of water bottom"), ""), | ||||
|       dialog::reaction = delayed_geo_reset; | ||||
|     else if(uni == 'r')  | ||||
|       dialog::editNumber(geom3::rock_wall_ratio, 0, 1, .1, .9, XLAT("Rock-III to wall ratio"), ""); | ||||
|       dialog::editNumber(geom3::rock_wall_ratio, 0, 1, .1, .9, XLAT("Rock-III to wall ratio"), ""), | ||||
|       dialog::reaction = delayed_geo_reset; | ||||
|     else if(uni == 'h') | ||||
|       dialog::editNumber(geom3::human_wall_ratio, 0, 1, .1, .7, XLAT("Human to wall ratio"), ""); | ||||
|       dialog::editNumber(geom3::human_wall_ratio, 0, 1, .1, .7, XLAT("Human to wall ratio"), ""), | ||||
|       dialog::reaction = delayed_geo_reset; | ||||
|  | ||||
|     else if(uni == 'e') | ||||
|       pushScreen(showStereo); | ||||
|   | ||||
| @@ -785,12 +785,19 @@ namespace conformal { | ||||
|       else if(uni == 'x' && pmodel == mdBall)  | ||||
|         dialog::editNumber(vid.ballproj, 0, 100, .1, 0, XLAT("projection in ball model"),  | ||||
|           "This parameter affects the ball model the same way as the projection parameter affects the disk model."); | ||||
|       else if(sym == 'x' && pmodel == mdPolygonal) | ||||
|       else if(sym == 'x' && pmodel == mdPolygonal) { | ||||
|         dialog::editNumber(polygonal::SI, 3, 10, 1, 4, XLAT("polygon sides"), ""); | ||||
|       else if(sym == 'y' && pmodel == mdPolygonal) | ||||
|         dialog::reaction = polygonal::solve; | ||||
|         }         | ||||
|       else if(sym == 'y' && pmodel == mdPolygonal) { | ||||
|         dialog::editNumber(polygonal::STAR, -1, 1, .1, 0, XLAT("star factor"), ""); | ||||
|       else if(sym == 'n' && pmodel == mdPolygonal) | ||||
|         dialog::reaction = polygonal::solve; | ||||
|         } | ||||
|       else if(sym == 'n' && pmodel == mdPolygonal) { | ||||
|         dialog::editNumber(polygonal::deg, 2, polygonal::MSI-1, 1, 2, XLAT("degree of the approximation"), ""); | ||||
|         dialog::reaction = polygonal::solve; | ||||
|         dialog::bound_low(0); dialog::bound_up(polygonal::MSI-1); | ||||
|         } | ||||
|       else if(sym == 'x' && pmodel == mdPolynomial)  { | ||||
|         polygonal::maxcoef = max(polygonal::maxcoef, polygonal::coefid); | ||||
|         int ci = polygonal::coefid + 1; | ||||
| @@ -801,8 +808,10 @@ namespace conformal { | ||||
|         int ci = polygonal::coefid + 1; | ||||
|         dialog::editNumber(polygonal::coefi[polygonal::coefid], -10, 10, .01/ci/ci, 0, XLAT("coefficient (imaginary)"), ""); | ||||
|         } | ||||
|       else if(sym == 'n' && pmodel == mdPolynomial) | ||||
|       else if(sym == 'n' && pmodel == mdPolynomial) { | ||||
|         dialog::editNumber(polygonal::coefid, 0, polygonal::MSI-1, 1, 0, XLAT("which coefficient"), ""); | ||||
|         dialog::bound_low(0); dialog::bound_up(polygonal::MSI-1); | ||||
|         } | ||||
|       else if(sym == 'r') { | ||||
|         if(rotation < 0) rotation = 0; | ||||
|         dialog::editNumber(rotation, 0, 360, 90, 0, XLAT("rotation"),  | ||||
| @@ -886,10 +895,14 @@ namespace conformal { | ||||
|       pushScreen(model_menu); | ||||
|     else if(sym == 'a')  | ||||
|       dialog::editNumber(lvspeed, -5, 5, .1, 1, XLAT("animation speed"), ""); | ||||
|     else if(sym == 'd')  | ||||
|     else if(sym == 'd') { | ||||
|       dialog::editNumber(bandhalf, 5, 1000, 5, 200, XLAT("band width"), ""); | ||||
|     else if(sym == 's')  | ||||
|       dialog::bound_low(5); | ||||
|       } | ||||
|     else if(sym == 's') { | ||||
|       dialog::editNumber(bandsegment, 500, 32000, 500, 16000, XLAT("band segment"), ""); | ||||
|       dialog::bound_low(500); | ||||
|       } | ||||
|     else if(sym == 'p')  | ||||
|       dialog::editNumber(extra_line_steps, 0, 5, 1, 1, XLAT("extend the ends"),  | ||||
|         "0 = start at the game start, endat the end position; " | ||||
|   | ||||
| @@ -527,15 +527,15 @@ int read_cheat_args() { | ||||
|     } | ||||
|   else if(argis("-we")) {     | ||||
|     PHASEFROM(2); | ||||
|     shift_arg_formula(whatever); resetGeometry(); | ||||
|     shift_arg_formula(whatever, delayed_geo_reset); | ||||
|     } | ||||
|   else if(argis("-wei")) {     | ||||
|     PHASEFROM(2); | ||||
|     shift(); whateveri = argi(); resetGeometry(); | ||||
|     shift(); whateveri = argi(); delayed_geo_reset(); | ||||
|     } | ||||
|   else if(argis("-wei2")) { | ||||
|     PHASEFROM(2); | ||||
|     shift(); whateveri2 = argi(); resetGeometry(); | ||||
|     shift(); whateveri2 = argi(); delayed_geo_reset(); | ||||
|     } | ||||
|   else if(argis("-W3")) { | ||||
|     shift(); top_land = readland(args()); cheat(); | ||||
|   | ||||
							
								
								
									
										143
									
								
								dialogs.cpp
									
									
									
									
									
								
							
							
						
						
									
										143
									
								
								dialogs.cpp
									
									
									
									
									
								
							| @@ -604,102 +604,46 @@ namespace dialog { | ||||
|    | ||||
|   reaction_t extra_options; | ||||
|    | ||||
|   void affect(char kind) { | ||||
|  | ||||
|     if(kind == 's') { | ||||
|       exp_parser ep; | ||||
|       ep.s = ne.s; | ||||
|       ld x = real(ep.parse()); | ||||
|       if(!ep.ok()) return; | ||||
|       if(ne.sc.positive && x <= 0) return; | ||||
|       *ne.editwhat = x; | ||||
|       if(ne.intval) *ne.intval = ldtoint(*ne.editwhat); | ||||
|       } | ||||
|     if(kind == 'v') { | ||||
|       if(ne.intval) *ne.intval = ldtoint(*ne.editwhat); | ||||
|       ne.s = disp(*ne.editwhat); | ||||
|       } | ||||
|      | ||||
|   void apply_slider() { | ||||
|     if(ne.intval) *ne.intval = ldtoint(*ne.editwhat); | ||||
|     if(reaction) reaction(); | ||||
|     if(ne.intval) *ne.editwhat = *ne.intval; | ||||
|     ne.s = disp(*ne.editwhat); | ||||
|     anims::deanimate(*ne.editwhat); | ||||
|     } | ||||
|    | ||||
| #if CAP_AUDIO | ||||
|     if(ne.intval == &musicvolume) { | ||||
|       if(musicvolume < 0)  | ||||
|         *ne.editwhat = musicvolume = 0, affect('v'); | ||||
|       else if(musicvolume > MIX_MAX_VOLUME)  | ||||
|         *ne.editwhat = musicvolume = MIX_MAX_VOLUME, affect('v'); | ||||
| #if CAP_SDLAUDIO | ||||
|       else Mix_VolumeMusic(musicvolume); | ||||
| #endif | ||||
| #if ISANDROID | ||||
|       settingsChanged = true; | ||||
| #endif | ||||
|       } | ||||
|   void apply_edit() { | ||||
|     exp_parser ep; | ||||
|     ep.s = ne.s; | ||||
|     ld x = real(ep.parse()); | ||||
|     if(!ep.ok()) return; | ||||
|     if(ne.sc.positive && x <= 0) return; | ||||
|     *ne.editwhat = x; | ||||
|     if(ne.intval) *ne.intval = ldtoint(*ne.editwhat); | ||||
|     if(ne.animatable) anims::animate_parameter(*ne.editwhat, ne.s, reaction ? reaction : reaction_final);     | ||||
|     if(reaction) reaction(); | ||||
|     } | ||||
|  | ||||
|     if(ne.intval == &effvolume) { | ||||
|       if(effvolume < 0)  | ||||
|         *ne.editwhat = effvolume = 0, affect('v'); | ||||
|       else if(effvolume > MIX_MAX_VOLUME)  | ||||
|         *ne.editwhat = effvolume = MIX_MAX_VOLUME, affect('v'); | ||||
| #if ISANDROID | ||||
|       settingsChanged = true; | ||||
| #endif | ||||
|       } | ||||
| #endif | ||||
|   void bound_low(ld val) { | ||||
|     auto r = reaction; | ||||
|     reaction = [r, val] () { | ||||
|       if(*ne.editwhat < val) { | ||||
|         *ne.editwhat = val; | ||||
|         if(ne.intval) *ne.intval = ldtoint(*ne.editwhat); | ||||
|         } | ||||
|       if(r) r(); | ||||
|       }; | ||||
|     } | ||||
|  | ||||
|     if(ne.intval == &vid.framelimit && vid.framelimit < 5)  | ||||
|       *ne.editwhat = vid.framelimit = 5, affect('v'); | ||||
|  | ||||
| #if ISMOBILE==1 | ||||
|     if(ne.intval == &fontscale && fontscale < 50)  | ||||
|       *ne.editwhat = fontscale = 50, affect('v'); | ||||
| #endif | ||||
|  | ||||
|     // if(ne.editwhat == &whatever) resetGeometry(); | ||||
|  | ||||
|     if(ne.intval == &sightrange_bonus && sightrange_bonus < 1-getDistLimit())  | ||||
|       *ne.editwhat = sightrange_bonus = 1-getDistLimit(), affect('v'); | ||||
|      | ||||
|     int msr = allowIncreasedSight() ? gp::dist_2() * 5 : 0; | ||||
|  | ||||
|     if(ne.intval == &sightrange_bonus && sightrange_bonus > msr)  | ||||
|       *ne.editwhat = sightrange_bonus = msr, affect('v'); | ||||
|      | ||||
|     if(ne.intval == &conformal::bandhalf && conformal::bandhalf < 5)  | ||||
|       *ne.editwhat = *ne.intval = 5, affect('v'); | ||||
|      | ||||
|     if(ne.intval == &conformal::bandsegment && conformal::bandsegment < 500)  | ||||
|       *ne.editwhat = *ne.intval = 500, affect('v'); | ||||
|  | ||||
|     if(ne.intval == &polygonal::coefid && polygonal::coefid < 0)  | ||||
|       *ne.editwhat = *ne.intval = 0, affect('v'); | ||||
|        | ||||
|     if(ne.intval == &polygonal::coefid && polygonal::coefid >= polygonal::MSI)  | ||||
|       *ne.editwhat = *ne.intval = polygonal::MSI-1, affect('v'); | ||||
|        | ||||
|     if(ne.intval == &polygonal::deg && polygonal::deg < 0)  | ||||
|       *ne.editwhat = *ne.intval = polygonal::MSI-1, affect('v'); | ||||
|        | ||||
|     if(ne.intval == &polygonal::deg && polygonal::deg >= polygonal::MSI)  | ||||
|       *ne.editwhat = *ne.intval = polygonal::MSI-1, affect('v'); | ||||
|        | ||||
|     if(ne.intval == &polygonal::SI) polygonal::solve(); | ||||
|     if(ne.editwhat == &polygonal::STAR) polygonal::solve(); | ||||
|      | ||||
|     polygonal::solve(); | ||||
|      | ||||
|     if(ne.editwhat == &geom3::highdetail && geom3::highdetail > geom3::middetail) | ||||
|       geom3::middetail = geom3::highdetail; | ||||
|      | ||||
|     if(ne.editwhat == &geom3::middetail && geom3::highdetail > geom3::middetail) | ||||
|       geom3::highdetail = geom3::middetail; | ||||
|      | ||||
|     if(cmode & sm::A3) { | ||||
|       buildpolys(); | ||||
|   #if CAP_GL | ||||
|       resetGL(); | ||||
|   #endif | ||||
|      } | ||||
|   void bound_up(ld val) { | ||||
|     auto r = reaction; | ||||
|     reaction = [r, val] () { | ||||
|       if(*ne.editwhat > val) { | ||||
|         *ne.editwhat = val; | ||||
|         if(ne.intval) *ne.intval = ldtoint(*ne.editwhat); | ||||
|         } | ||||
|       if(r) r(); | ||||
|       }; | ||||
|     } | ||||
|  | ||||
|   int numberdark; | ||||
| @@ -737,12 +681,12 @@ namespace dialog { | ||||
|       handleNavigation(sym, uni); | ||||
|       if((uni >= '0' && uni <= '9') || among(uni, '.', '+', '-', '*', '/', '^', '(', ')') || (uni >= 'a' && uni <= 'z')) { | ||||
|         ne.s += uni; | ||||
|         affect('s'); | ||||
|         apply_edit(); | ||||
|         } | ||||
|       else if(uni == '\b' || uni == '\t') { | ||||
|         ne.s = ne.s. substr(0, isize(ne.s)-1); | ||||
|         sscanf(ne.s.c_str(), LDF, ne.editwhat); | ||||
|         affect('s'); | ||||
|         apply_edit(); | ||||
|         } | ||||
|   #if !ISMOBILE | ||||
|       else if(sym == SDLK_RIGHT || sym == SDLK_KP6) { | ||||
| @@ -750,19 +694,19 @@ namespace dialog { | ||||
|           (*ne.editwhat)++; | ||||
|         else | ||||
|           *ne.editwhat = ne.sc.inverse(ne.sc.direct(*ne.editwhat) + shiftmul * ne.step); | ||||
|         affect('v'); | ||||
|         apply_slider(); | ||||
|         } | ||||
|       else if(sym == SDLK_LEFT || sym == SDLK_KP4) { | ||||
|         if(ne.intval && abs(shiftmul) < .6) | ||||
|           (*ne.editwhat)--; | ||||
|         else | ||||
|           *ne.editwhat = ne.sc.inverse(ne.sc.direct(*ne.editwhat) - shiftmul * ne.step); | ||||
|         affect('v'); | ||||
|         apply_slider(); | ||||
|         } | ||||
|   #endif | ||||
|       else if(sym == SDLK_HOME) { | ||||
|         *ne.editwhat = ne.dft; | ||||
|         affect('v'); | ||||
|         apply_slider(); | ||||
|         } | ||||
|       else if(uni == 500) { | ||||
|         int sl, sr; | ||||
| @@ -773,7 +717,7 @@ namespace dialog { | ||||
|         ld d = (mousex - sl + .0) / (sr-sl); | ||||
|         *ne.editwhat =  | ||||
|           ne.sc.inverse(d * (ne.sc.direct(ne.vmax) - ne.sc.direct(ne.vmin)) + ne.sc.direct(ne.vmin)); | ||||
|         affect('v'); | ||||
|         apply_slider(); | ||||
|         } | ||||
|       else if(doexiton(sym, uni)) { popScreen(); if(reaction_final) reaction_final(); } | ||||
|       }; | ||||
| @@ -847,11 +791,14 @@ namespace dialog { | ||||
|     reaction_final = reaction_t(); | ||||
|     extra_options = reaction_t(); | ||||
|     numberdark = 0; | ||||
|     ne.animatable = true; | ||||
|     anims::get_parameter_animation(x, ne.s); | ||||
|     } | ||||
|  | ||||
|   void editNumber(int& x, int vmin, int vmax, int step, int dft, string title, string help) { | ||||
|     editNumber(ne.intbuf, vmin, vmax, step, dft, title, help); | ||||
|     ne.intbuf = x; ne.intval = &x; ne.s = its(x); | ||||
|     ne.animatable = false; | ||||
|     } | ||||
|    | ||||
|   void helpToEdit(int& x, int vmin, int vmax, int step, int dft) { | ||||
|   | ||||
| @@ -438,7 +438,7 @@ void showEuclideanMenu() { | ||||
|         else if(binarytiling) { | ||||
|           dialog::editNumber(vid.binary_width, 0, 2, 0.1, 1, XLAT("binary tiling width"), ""); | ||||
|           dialog::reaction = [] () { | ||||
|             resetGeometry();  | ||||
|             need_reset_geometry = true; | ||||
|             #if CAP_TEXTURE | ||||
|             texture::config.remap(); | ||||
|             #endif | ||||
|   | ||||
							
								
								
									
										15
									
								
								hyper.h
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								hyper.h
									
									
									
									
									
								
							| @@ -1735,6 +1735,7 @@ namespace dialog { | ||||
|     string title, help; | ||||
|     scaler sc; | ||||
|     int *intval; ld intbuf; | ||||
|     bool animatable; | ||||
|     }; | ||||
|    | ||||
|   extern numberEditor ne; | ||||
| @@ -1769,6 +1770,9 @@ namespace dialog { | ||||
|   void editNumber(int& x, int vmin, int vmax, int step, int dft, string title, string help); | ||||
|   inline void scaleLog() { ne.sc = logarithmic; } | ||||
|   inline void scaleSinh() { ne.sc = asinhic; } | ||||
|   void bound_low(ld val); | ||||
|   void bound_up(ld val); | ||||
|  | ||||
|   void handleNavigation(int &sym, int &uni); | ||||
|    | ||||
|   namespace zoom { | ||||
| @@ -2053,6 +2057,11 @@ int darkena(int c, int lev, int a); | ||||
| extern cell *shpos[MAXPLAYER][SHSIZE]; | ||||
| extern int cshpos; | ||||
|  | ||||
| namespace anims { | ||||
|   void animate_parameter(ld &x, string f, const reaction_t& r); | ||||
|   void deanimate(ld &x); | ||||
|   void get_parameter_animation(ld &x, string& f); | ||||
|   } | ||||
|  | ||||
| namespace arg { | ||||
| #if CAP_COMMANDLINE | ||||
| @@ -2068,7 +2077,7 @@ namespace arg { | ||||
|   bool argis(const string& s); | ||||
|   unsigned arghex(); | ||||
|  | ||||
|   inline void shift_arg_formula(ld& x) { shift(); x = argf(); }   | ||||
|   inline void shift_arg_formula(ld& x, const reaction_t& r = reaction_t()) { shift(); x = argf(); anims::animate_parameter(x, args(), r); } | ||||
|    | ||||
|   void init(int _argc, char **_argv); | ||||
|    | ||||
| @@ -4276,7 +4285,7 @@ struct exp_parser { | ||||
|   map<string, cld> extra_params; | ||||
|  | ||||
|   bool ok() { return at == isize(s); } | ||||
|   char next() { if(at == isize(s) || at == -1) return 0; else return s[at]; } | ||||
|   char next(int step=0) { if(at >= isize(s)-step || at == -1) return 0; else return s[at+step]; } | ||||
|    | ||||
|   bool eat(const char *c) { | ||||
|     int orig_at = at; | ||||
| @@ -4342,5 +4351,7 @@ struct bandfixer { | ||||
|   bandfixer(transmatrix& T) : bw(band_shift, band_shift) { fix_the_band(T); } | ||||
|   }; | ||||
|  | ||||
| inline void delayed_geo_reset() { need_reset_geometry = true; } | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -242,7 +242,7 @@ namespace mapstream { | ||||
|         } | ||||
|       } | ||||
|      | ||||
|     resetGeometry(); | ||||
|     need_reset_geometry = true; | ||||
|  | ||||
|     initcells(); | ||||
|     if(shmup::on) shmup::init(); | ||||
|   | ||||
							
								
								
									
										119
									
								
								screenshot.cpp
									
									
									
									
									
								
							
							
						
						
									
										119
									
								
								screenshot.cpp
									
									
									
									
									
								
							| @@ -370,45 +370,46 @@ void moved() { | ||||
|   playermoved = false; | ||||
|   } | ||||
|  | ||||
| struct animatable_parameter { | ||||
|   ld& value; | ||||
|   dialog::scaler sc; | ||||
|   ld values[2]; | ||||
|   bool need_reset; | ||||
|   animatable_parameter(ld& val, bool r = false) : value(val), sc(dialog::identity), need_reset(r) {} | ||||
|   animatable_parameter(ld& val, dialog::scaler s) : value(val), sc(s), need_reset(false) {} | ||||
| struct animated_parameter { | ||||
|   ld *value; | ||||
|   ld last; | ||||
|   string formula; | ||||
|   reaction_t reaction; | ||||
|   }; | ||||
|  | ||||
| vector<animatable_parameter> animatable_parameters = { | ||||
|   animatable_parameter(vid.scale, dialog::asinhic), | ||||
|   animatable_parameter(vid.alpha, dialog::asinhic), | ||||
|   animatable_parameter(vid.linewidth), | ||||
|   animatable_parameter(vid.xposition), | ||||
|   animatable_parameter(vid.yposition), | ||||
|   animatable_parameter(vid.ballangle), | ||||
|   animatable_parameter(vid.yshift), | ||||
|   animatable_parameter(polygonal::STAR), | ||||
|   animatable_parameter(stereo::ipd), | ||||
|   animatable_parameter(stereo::lr_eyewidth), | ||||
|   animatable_parameter(stereo::anaglyph_eyewidth), | ||||
|   animatable_parameter(stereo::fov), | ||||
|   animatable_parameter(vid.euclid_to_sphere), | ||||
|   animatable_parameter(vid.twopoint_param), | ||||
|   animatable_parameter(vid.stretch), | ||||
|   animatable_parameter(vid.binary_width, true), | ||||
|   animatable_parameter(geom3::depth, false), | ||||
|   animatable_parameter(geom3::camera, true), | ||||
|   animatable_parameter(geom3::wall_height, true), | ||||
|   animatable_parameter(vid.ballproj), | ||||
|   animatable_parameter(surface::dini_b), | ||||
|   animatable_parameter(surface::hyper_b), | ||||
|   animatable_parameter(conformal::halfplane_scale), | ||||
|   animatable_parameter(conformal::model_transition), | ||||
|   animatable_parameter(conformal::top_z, dialog::logarithmic), | ||||
|   }; | ||||
| vector<animated_parameter> aps; | ||||
|  | ||||
| ld anim_param = 0; | ||||
| int paramstate = 0; | ||||
| void deanimate(ld &x) { | ||||
|   for(int i=0; i<isize(aps); i++)  | ||||
|     if(aps[i].value == &x) | ||||
|       aps.erase(aps.begin() + (i--)); | ||||
|   } | ||||
|  | ||||
| void get_parameter_animation(ld &x, string &s) { | ||||
|   for(auto &ap: aps) | ||||
|     if(ap.value == &x && ap.last == x) | ||||
|       s = ap.formula; | ||||
|   } | ||||
|  | ||||
| void animate_parameter(ld &x, string f, const reaction_t& r) { | ||||
|   deanimate(x); | ||||
|   aps.emplace_back(animated_parameter{&x, x, f, r}); | ||||
|   } | ||||
|  | ||||
| int ap_changes; | ||||
|  | ||||
| void apply_animated_parameters() { | ||||
|   ap_changes = 0; | ||||
|   for(auto &ap: aps) { | ||||
|     if(*ap.value != ap.last) continue; | ||||
|     *ap.value = parseld(ap.formula); | ||||
|     if(*ap.value != ap.last) { | ||||
|       if(ap.reaction) ap.reaction(); | ||||
|       ap_changes++; | ||||
|       ap.last = *ap.value; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
| bool needs_highqual; | ||||
|  | ||||
| @@ -502,23 +503,6 @@ void apply() { | ||||
|     else | ||||
|       vid.ballangle += ballangle_rotation * 360 * t / period; | ||||
|     } | ||||
|   if(paramstate == 2 && anim_param) { | ||||
|     ld phase = (1 + sin(anim_param * 2 * M_PI * ticks / period)) / 2; | ||||
|     for(auto& ap: animatable_parameters) if(ap.values[0] != ap.values[1]) { | ||||
|       ap.value = ap.sc.inverse(ap.sc.direct(ap.values[0]) * phase + ap.sc.direct(ap.values[1]) * (1-phase)); | ||||
|       if(ap.need_reset) { | ||||
|         if(!inHighQual) needs_highqual = true; | ||||
|         else need_reset_geometry = true; | ||||
|         } | ||||
|       if(&ap.value == &surface::hyper_b) run_shape(surface::dsHyperlike); | ||||
|       if(&ap.value == &surface::dini_b) { | ||||
|         if(!inHighQual) needs_highqual = true; | ||||
|         else surface::run_shape(surface::dsDini); | ||||
|         } | ||||
|       } | ||||
|     if(need_reset_geometry) resetGeometry(), need_reset_geometry = false; | ||||
|     calcparam(); | ||||
|     } | ||||
|   if(joukowsky_anim) { | ||||
|     ld t = ticks / period; | ||||
|     t = t - floor(t); | ||||
| @@ -529,8 +513,10 @@ void apply() { | ||||
|       conformal::model_transition = t / 1.1; | ||||
|       vid.scale = (1 - conformal::model_transition) / 2.; | ||||
|       } | ||||
|     calcparam(); | ||||
|     } | ||||
|   apply_animated_parameters(); | ||||
|   if(need_reset_geometry) resetGeometry(), need_reset_geometry = false; | ||||
|   calcparam(); | ||||
|   } | ||||
|  | ||||
| void rollback() { | ||||
| @@ -576,16 +562,6 @@ void display_animation() { | ||||
|     } | ||||
|   } | ||||
|  | ||||
| void next_paramstate() { | ||||
|   if(paramstate == 2) { | ||||
|     for(auto& ap: animatable_parameters)  ap.values[0] = ap.values[1]; | ||||
|     paramstate--; | ||||
|     } | ||||
|   for(auto& ap: animatable_parameters)  | ||||
|     ap.values[paramstate] = ap.value; | ||||
|   paramstate++; | ||||
|   } | ||||
|  | ||||
| void animator(string caption, ld& param, char key) { | ||||
|   dialog::addBoolItem(caption, param, key); | ||||
|   if(param) dialog::lastItem().value = fts(param); | ||||
| @@ -597,12 +573,6 @@ void animator(string caption, ld& param, char key) { | ||||
|           "The value of 1 means that the period of this animation equals the period set in the animation menu. " | ||||
|           "Larger values correspond to faster animations."); | ||||
|  | ||||
|       if(¶m == &anim_param) | ||||
|         s = XLAT( | ||||
|           "Most graphical parameters with real values can have their values changed during the animation. " | ||||
|           "To achieve this effect, 'choose parameters to animate', change the parameters to their final values " | ||||
|           "in the animation, and 'choose parameters to animate' again.\n\n") + s; | ||||
|        | ||||
|       dialog::editNumber(param, 0, 10, 1, 1, caption, s);  | ||||
|       } | ||||
|     else param = 0; | ||||
| @@ -757,9 +727,10 @@ void show() { | ||||
|   else if(among(pmodel, mdHyperboloid, mdHemisphere, mdBall)) | ||||
|     animator(XLAT("3D rotation"), ballangle_rotation, 'r'); | ||||
|    | ||||
|   /* | ||||
|   animator(XLAT("animate parameter change"), anim_param, 'P'); | ||||
|   dialog::addSelItem(XLAT("choose parameters to animate"), its(paramstate), 'C'); | ||||
|   dialog::add_action(next_paramstate); | ||||
|   dialog::add_action(next_paramstate); */ | ||||
|  | ||||
|   dialog::addBoolItem(XLAT("history mode"), (conformal::on || conformal::includeHistory), 'h'); | ||||
|   dialog::add_action([] () { pushScreen(conformal::history_menu); }); | ||||
| @@ -787,10 +758,6 @@ int readArgs() { | ||||
|   else if(argis("-animmenu")) { | ||||
|     PHASE(3); showstartmenu = false; pushScreen(show); | ||||
|     } | ||||
|   else if(argis("-animparam")) { | ||||
|     PHASE(2); next_paramstate(); | ||||
|     if(paramstate >= 2) anim_param = 1; | ||||
|     } | ||||
|   else if(argis("-animperiod")) { | ||||
|     PHASE(2); shift_arg_formula(period); | ||||
|     } | ||||
| @@ -857,7 +824,7 @@ bool any_animation() { | ||||
|   if(conformal::on) return true; | ||||
|   if(ma) return true; | ||||
|   if(ballangle_rotation || rug_rotation1 || rug_rotation2) return true; | ||||
|   if(paramstate == 2) return true; | ||||
|   if(ap_changes) return true; | ||||
|   return false; | ||||
|   } | ||||
|  | ||||
|   | ||||
							
								
								
									
										28
									
								
								util.cpp
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								util.cpp
									
									
									
									
									
								
							| @@ -176,7 +176,7 @@ cld exp_parser::parse(int prio) { | ||||
|     string name; | ||||
|     while(true) { | ||||
|       char c = next(); | ||||
|       if((c >= '0' && c <= '9') || c == '.' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_') | ||||
|       if((c >= '0' && c <= '9') || (c == '.' && next(1) != '.') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_') | ||||
|         name += c, at++; | ||||
|       else break; | ||||
|       } | ||||
| @@ -193,14 +193,14 @@ cld exp_parser::parse(int prio) { | ||||
|     string number; | ||||
|     while(true) { | ||||
|       char c = next(); | ||||
|       if((c >= '0' && c <= '9') || c == '.' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_') | ||||
|       if((c >= '0' && c <= '9') || (c == '.' && next(1) != '.') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_') | ||||
|         number += c, at++; | ||||
|       else break; | ||||
|       } | ||||
|     if(number == "e") res = exp(1); | ||||
|     else if(number == "i") res = cld(0, 1); | ||||
|     else if(number == "p" || number == "pi") res = M_PI; | ||||
|     else if(number == "" && next() == '-') res = 0, prio = 0; | ||||
|     else if(number == "" && next() == '-') { at++; res = -parse(prio); } | ||||
|     else if(number == "") at = -1; | ||||
|     else if(extra_params.count(number)) res = extra_params[number]; | ||||
|     else if(number == "s") res = ticks / 1000.; | ||||
| @@ -209,11 +209,23 @@ cld exp_parser::parse(int prio) { | ||||
|     else { std::stringstream ss; res = 0; ss << number; ss >> res; } | ||||
|     } | ||||
|   while(true) { | ||||
|     if(next() == '+' && prio == 0) at++, res = res + parse(1); | ||||
|     else if(next() == '-' && prio == 0) at++, res = res - parse(1); | ||||
|     else if(next() == '*' && prio <= 1) at++, res = res * parse(2); | ||||
|     else if(next() == '/' && prio <= 1) at++, res = res / parse(2); | ||||
|     else if(next() == '^') at++, res = pow(res, parse(3)); | ||||
|     if(next() == '.' && next(1) == '.' && prio == 0) { | ||||
|       vector<cld> rest = { res }; | ||||
|       while(next() == '.' && next(1) == '.') { | ||||
|         at += 2; rest.push_back(parse(10)); | ||||
|         } | ||||
|       ld v = ticks * (isize(rest)-1.) / anims::period; | ||||
|       int vf = v; | ||||
|       v -= vf; | ||||
|       vf %= (isize(rest)-1); | ||||
|       res = rest[vf] + (rest[vf+1] - rest[vf]) * v; | ||||
|       return res; | ||||
|       } | ||||
|     else if(next() == '+' && prio <= 10) at++, res = res + parse(20); | ||||
|     else if(next() == '-' && prio <= 10) at++, res = res - parse(20); | ||||
|     else if(next() == '*' && prio <= 20) at++, res = res * parse(30); | ||||
|     else if(next() == '/' && prio <= 20) at++, res = res / parse(30); | ||||
|     else if(next() == '^') at++, res = pow(res, parse(40)); | ||||
|     else break; | ||||
|     } | ||||
|   return res; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue