mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-30 13:32:59 +00:00 
			
		
		
		
	 ced3bbcad4
			
		
	
	ced3bbcad4
	
	
	
		
			
			C++20 introduces `std::format` and we `using namespace std`, so some of these would be ambiguous in C++20.
		
			
				
	
	
		
			634 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			634 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "../hyper.h"
 | |
| 
 | |
| // A tool to create smooth manually controlled movement animations in 3D geometries.
 | |
| 
 | |
| // Press 'f' to start controlling
 | |
| 
 | |
| // 'qweasdzxc' will move the camera and additionally rotate the view a bit (except 's')
 | |
| 
 | |
| // 'b' goes back 1 frame, 'e' undoes 30 frames
 | |
| 
 | |
| // 'r' starts recording
 | |
| 
 | |
| // 1234 change movement speed (see console for details)
 | |
| // 67890 change rotation speed (see console for details)
 | |
| 
 | |
| namespace hr {
 | |
| 
 | |
| bool saving_positions;
 | |
| 
 | |
| bool smooth_aim = true;
 | |
| 
 | |
| int next_pos_tick;
 | |
| 
 | |
| struct frame {
 | |
|   transmatrix V;
 | |
|   transmatrix lp;
 | |
|   transmatrix msm;
 | |
|   cell *co;
 | |
|   int steps_to_change;
 | |
|   int step_smoothing;
 | |
|   ld stepdist;
 | |
|   ld stepang;
 | |
|   };
 | |
| 
 | |
| vector<frame> saved;
 | |
| 
 | |
| int collection;
 | |
| 
 | |
| bool recording;
 | |
| bool keys_on = false;
 | |
| ld stepdist = 0.02;
 | |
| ld stepang = 0.01;
 | |
| EX int step_smoothing = 1;
 | |
| EX int steps_to_change;
 | |
| 
 | |
| void move_camera1(transmatrix T);
 | |
| 
 | |
| void recall(frame& f = saved.back()) {
 | |
|   View = f.V;
 | |
|   current_display->local_perspective = f.lp;
 | |
|   stretch::mstretch_matrix = f.msm;
 | |
|   centerover = f.co;
 | |
|   steps_to_change = f.steps_to_change;
 | |
|   step_smoothing = f.step_smoothing;
 | |
|   stepdist = f.stepdist;
 | |
|   stepang = f.stepang;
 | |
|   playermoved = false;
 | |
|   }
 | |
| 
 | |
| frame saveframe() {
 | |
|   frame f;
 | |
|   f.V = View;
 | |
|   f.lp = current_display->local_perspective;
 | |
|   f.msm = stretch::mstretch_matrix;
 | |
|   f.co = centerover;
 | |
|   f.steps_to_change = steps_to_change;
 | |
|   f.step_smoothing = step_smoothing;
 | |
|   f.stepdist = stepdist;
 | |
|   f.stepang = stepang;
 | |
|   playermoved = false;
 | |
|   return f;
 | |
|   }
 | |
| 
 | |
| void trailer_frame() {
 | |
|   // if(saving_positions || !isize(saved)) 
 | |
|   if(!recording && keys_on) queuestr(current_display->xcenter, current_display->ycenter, 0, 16, "+", 0xFFFFFFFF);
 | |
|   if(!recording && keys_on) queuestr(current_display->xcenter/2, current_display->ycenter, 0, 16, "+", 0xFFFFFFFF);
 | |
|   if(!recording && keys_on) queuestr(current_display->xcenter*3/2, current_display->ycenter, 0, 16, "+", 0xFFFFFFFF);
 | |
|   if(!recording && keys_on) queuestr(mousex, mousey, 0, 16, "+", 0xFFFFFFFF);
 | |
|   }
 | |
| 
 | |
| ld next_stepdist = stepdist;
 | |
| ld next_stepang = stepang;
 | |
| 
 | |
| void apply_steps_to_change() {
 | |
|   if(steps_to_change) {
 | |
|     stepang = stepang + (next_stepang-stepang) / steps_to_change;
 | |
|     stepdist = stepdist + (next_stepdist-stepdist) / steps_to_change;
 | |
|     steps_to_change--;
 | |
|     }
 | |
|   }
 | |
| 
 | |
| bool trailer_turn(int delta) {
 | |
|   if(saving_positions) {
 | |
|     collection += delta * 60;
 | |
|     while(collection > 1000) {
 | |
|       apply_steps_to_change();
 | |
|       collection -= 1000;
 | |
|       View = cpush(2, -stepdist) * View;
 | |
|             
 | |
|       if(smooth_aim) {
 | |
|         ld dx = (mousex - current_display->xcenter) * stepang / -50.;
 | |
|         ld dy = (mousey - current_display->ycenter) * stepang / -50.;
 | |
|         View = cspin(0, 2, dx) * cspin(1, 2, dy) * View;
 | |
|         }
 | |
|       optimizeview();
 | |
|       saved.emplace_back(saveframe());
 | |
|       if(isize(saved) % 100 == 0)
 | |
|         println(hlog, "frames = ", isize(saved));
 | |
|       }
 | |
|     }
 | |
|   return true;
 | |
|   }
 | |
| 
 | |
| ld spin_distance = 0;
 | |
| 
 | |
| bool spinning_around;
 | |
| 
 | |
| bool fixed_orientation;
 | |
| 
 | |
| transmatrix orientation_to_fix;
 | |
| 
 | |
| string videofile;
 | |
| 
 | |
| void move_camera1(transmatrix T) {
 | |
|   // println(hlog, "rayfix: saving frame ", isize(saved));
 | |
|   // optimizeview();
 | |
|   // ray::cast();
 | |
|   optimizeview();
 | |
|   saved.emplace_back(saveframe());
 | |
|   if(spinning_around) {
 | |
|     for(int s=0; s<100; s++) 
 | |
|       shift_view(ztangent(-spin_distance/100));
 | |
|     rotate_view(T);
 | |
|     for(int s=0; s<100; s++) 
 | |
|       shift_view(ztangent(spin_distance/100));
 | |
|     }
 | |
|   else {
 | |
|     shift_view(ztangent(-stepdist));
 | |
|     spin_distance += stepdist;
 | |
|     rotate_view(T);
 | |
|     }
 | |
|   if(fixed_orientation) {
 | |
|     println(hlog, "cat ", inverse(View) * C0);
 | |
|     transmatrix iView = inverse(View);
 | |
|     iView = nisot::translate(iView * C0) * orientation_to_fix;
 | |
|     View = inverse(iView);
 | |
|     println(hlog, "cat ", inverse(View) * C0);
 | |
|     }
 | |
|   }
 | |
| 
 | |
| bool move_camera(transmatrix T) {
 | |
|   for(int it=0; it<5; it++) 
 | |
|     move_camera1(T);
 | |
|   println(hlog, "frames = ", isize(saved), " distance = ", spin_distance);
 | |
|   playermoved = false;
 | |
|   return true;
 | |
|   }
 | |
| 
 | |
| template<class Type> bool move_camera_smoothchange(const Type& T) {
 | |
|   for(int it=0; it<5; it++) {
 | |
|     println(hlog, "steps_to_change = ", steps_to_change, " stepdist = ", stepdist);
 | |
|     apply_steps_to_change();
 | |
|     move_camera1(T());
 | |
|     }
 | |
|   println(hlog, "frames = ", isize(saved), " distance = ", spin_distance);
 | |
|   playermoved = false;
 | |
|   return true;
 | |
|   }
 | |
| 
 | |
| bool spin_around(transmatrix T) {
 | |
|   for(int it=0; it<5; it++) {
 | |
|     }
 | |
|   println(hlog, "frames = ", isize(saved), " spinning");
 | |
|   playermoved = false;
 | |
|   return true;
 | |
|   }
 | |
| 
 | |
| namespace sn {   pair<heptagon*,heptagon*> getcoord(heptagon *h); }
 | |
| 
 | |
| bignum bdiff(heptagon *h1, heptagon *h2) {
 | |
|   if(h1 == h2) return 0;
 | |
|   auto p = bdiff(h1->move(3), h2->move(3));
 | |
|   int d = h1->c.spin(3) - h2->c.spin(3);
 | |
|   println(hlog, "d=", d, " p = ", p.get_str(10000));
 | |
|   return p + p + bignum(d);
 | |
|   }
 | |
| 
 | |
| #define BASE 10
 | |
| 
 | |
| /*
 | |
| void o_addmul(bignum& b0, const bignum& b, int factor) {
 | |
|   int K = isize(b.digits);
 | |
|   if(K > isize(b0.digits)) b0.digits.resize(K);
 | |
|   int carry = 0;
 | |
|   for(int i=0; ; i++) {
 | |
|     bool cnt = (i<K || (carry > 0 && carry < -1) || (carry == -1 && i < isize(b0.digits)));
 | |
|     println(hlog, "cnt = ", cnt, " carry = ", carry
 | |
|     if(!cnt) break;
 | |
|     println(hlog, "i=", i, " carry start=", carry);
 | |
|     if(i >= isize(b0.digits)) b0.digits.push_back(0);
 | |
|     long long l = b0.digits[i];
 | |
|     l += carry;
 | |
|     if(i < K) l += b.digits[i] * factor;
 | |
|     carry = 0;
 | |
|     if(l >= BASE) carry = l / BASE;
 | |
|     if(l < 0) carry = -(BASE-1-l) / BASE;
 | |
|     l -= carry * BASE;
 | |
|     b0.digits[i] = l;
 | |
|     println(hlog, "carry=", carry);
 | |
|     }
 | |
|   println(hlog, "carry end=", carry);
 | |
|   if(carry < 0) b0.digits.back() -= BASE;
 | |
|   while(isize(b0.digits) && b0.digits.back() == 0) b0.digits.pop_back();
 | |
|   } */
 | |
| 
 | |
| void get_b4_distance() {
 | |
|   heptagon *h1 = currentmap->gamestart()->master;
 | |
|   heptagon *h2 = centerover->master;
 | |
|   if(h1->distance != h2->distance)
 | |
|     println(hlog, "Z difference: ", h2->distance - h1->distance);
 | |
|   else if(sn::in()) {
 | |
|     auto c1 = sn::getcoord(h1);
 | |
|     auto c2 = sn::getcoord(h2);
 | |
|     println(hlog, "X difference: ", bdiff(c1.first, c2.first).get_str(10000));
 | |
|     println(hlog, "Y difference: ", bdiff(c1.second, c2.second).get_str(10000));
 | |
|     println(hlog, "X difference> ", bdiff(c2.first, c1.first).get_str(10000));
 | |
|     println(hlog, "Y difference> ", bdiff(c2.second, c1.second).get_str(10000));
 | |
|     }
 | |
|   }
 | |
| 
 | |
| void load_animation(string fname) {
 | |
|   fhstream f(fname, "r");
 | |
|   int siz;
 | |
|   f.read<int>(siz);
 | |
|   saved.resize(siz);
 | |
|   for(int i=0; i<isize(saved); i++) {
 | |
|     auto& s = saved[i];
 | |
|     hread_raw(f, s.V);
 | |
|     hread_raw(f, s.lp);
 | |
|     int tmp = 0; hread_raw(f, tmp);
 | |
|     if(cryst) {
 | |
|       crystal::coord co;
 | |
|       hread_raw(f, co);
 | |
|       s.co = crystal::get_heptagon_at(co)->c7;
 | |
|       }
 | |
|     else
 | |
|     if(nil) {
 | |
|       nilv::mvec co;
 | |
|       hread_raw(f, co);
 | |
|       s.co = nilv::get_heptagon_at(co)->c7;
 | |
|       }
 | |
|     else if(bounded) {    
 | |
|       auto ac = currentmap->allcells();
 | |
|       int i;
 | |
|       hread_raw(f, i);
 | |
|       s.co = ac[i];
 | |
|       }
 | |
|     else s.co = cwt.at;
 | |
|     }
 | |
|   println(hlog, "loaded animation of ", isize(saved), " frames");
 | |
|   recall();
 | |
|   }
 | |
| 
 | |
| EX transmatrix spintox_good(const hyperpoint& H) {
 | |
|   if(GDIM == 2 || prod) return spintox(H); 
 | |
|   double v = -atan2(H[2], H[1]);
 | |
|   return cspin(2, 1, -v) * spintoc(cspin(2, 1, v) * H, 0, 1) *cspin(2, 1, v);
 | |
|   // cspin(2, 1, v) * spintoc(cspin(2, 1, -v) * H, 0, 1);
 | |
|   }
 | |
| 
 | |
| void denan() {
 | |
|   for(int i=1; i<isize(saved)-1; i++) {
 | |
|     auto& s = saved[i];
 | |
|     if(isnan(s.V[0][0])) {
 | |
|       println(hlog, "nan at ", i, " @ ", s.co);
 | |
|       saved[i] = saved[i-1];
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
| transmatrix relm(cell *a, cell *b) {
 | |
|   forCellIdEx(c, id, b) if(c == a) return currentmap->adj(b, id);
 | |
|   forCellIdEx(c, id, b) 
 | |
|     forCellIdEx(d, id2, c) if(d == a) return currentmap->adj(b, id) * currentmap->adj(c, id2);
 | |
|   return currentmap->relative_matrix(a, b, C0);
 | |
|   }  
 | |
| 
 | |
| void smoothen() {
 | |
|   ld total = 0;
 | |
|   
 | |
|   for(int a=1; a<3; a++)
 | |
|   for(int i=1; i<isize(saved)-1; i++) if((a^i)&1) {
 | |
|     auto& s = saved[i];
 | |
|     auto& sl = saved[i-1];
 | |
|     auto& sn = saved[i+1];
 | |
|     forCellCM(c, s.co);
 | |
|     hyperpoint hl = s.V * relm(sl.co, s.co) * inverse(sl.V) * C0;
 | |
|     hyperpoint hn = s.V * relm(sl.co, s.co) * inverse(sn.V) * C0;
 | |
|     hyperpoint hm = mid(hl, hn);
 | |
|     if(isnan(hm[0])) {
 | |
|       println(hlog, "Vl = ", sl.V);
 | |
|       println(hlog, "V  = ", s.V);
 | |
|       println(hlog, "Vn = ", sn.V);
 | |
|       println(hlog, "cells ", sl.co, s.co, sn.co);
 | |
|       println(hlog, "crl= ", relm(sl.co, s.co));
 | |
|       println(hlog, "crm= ", relm(sn.co, s.co));
 | |
|       continue;
 | |
|       }
 | |
|     total += hdist0(hm);
 | |
|     s.V = gpushxto0(hm) * s.V;
 | |
|     auto xhn = gpushxto0(hm) * hn;
 | |
|     transmatrix T = cspin(0, 2, -M_PI/2) * spintox_good(cspin(0, 2, M_PI/2) * xhn) * cspin(0, 2, M_PI/2);
 | |
|     s.V = T * s.V;
 | |
|     // println(hlog, hn, " -> ", T * xhn);
 | |
|     }
 | |
|   println(hlog, "total = ", total);
 | |
|   }
 | |
| 
 | |
| string mrec_file = "devmods/manual/%05d.png";
 | |
| 
 | |
| int mrec_fps = 60;
 | |
| 
 | |
| int mrec_first = 0, mrec_last = 999999;
 | |
| 
 | |
| int mrec_first_opt = 0, mrec_last_opt = 0;
 | |
| 
 | |
| void set_stepdist(ld x) {
 | |
|   println(hlog, "stepdist = ", x);
 | |
|   next_stepdist = x;
 | |
|   steps_to_change = step_smoothing;
 | |
|   }
 | |
| 
 | |
| void set_stepang(ld x) {
 | |
|   println(hlog, "stepang = ", x);
 | |
|   next_stepang = x;
 | |
|   steps_to_change = step_smoothing;
 | |
|   }
 | |
| 
 | |
| void do_recording() {
 | |
|   recording = true;
 | |
|   if(mouseaim_sensitivity) {
 | |
|     mouseaim_sensitivity = 0;
 | |
|     println(hlog, "disabled mouseaim");
 | |
|     return;
 | |
|     }
 | |
|   if(musicvolume) {
 | |
|     println(hlog, "disabled music");
 | |
|     musicvolume = 0;
 | |
|     Mix_VolumeMusic(0);
 | |
|     return;
 | |
|     }
 | |
|   
 | |
|   dynamicval dp(arg::pos, arg::pos);
 | |
|   dynamicval vs(vid, vid);
 | |
|   for(arg::pos=mrec_first_opt; arg::pos < mrec_last_opt; arg::pos++) {
 | |
|     int r = callhandlers(1, hooks_args);
 | |
|     switch (r) {
 | |
|       case 0: arg::lshift(); break;
 | |
|       case 1: 
 | |
|         printf("Unknown option: %s\n", arg::argcs()); break;
 | |
|       case 2:
 | |
|         printf("Error\n"); break;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|   println(hlog, "starting recording");
 | |
|   shot::take("anim/start.png");
 | |
|   saving_positions = false;
 | |
| //      vid.cells_drawn_limit = 1000000;      
 | |
|   int i = 0;
 | |
| 
 | |
|   system("mkdir -p devmods/manual/");
 | |
|   
 | |
|   auto f = [&] {
 | |
|     for(auto& p: saved) {
 | |
|       recall(p);
 | |
|       println(hlog, "rayfix: render ", i);
 | |
|       ticks = i * 1000 / mrec_fps;
 | |
|       
 | |
|       if(i >= mrec_first && i < mrec_last) {
 | |
|         string s = hr::format(mrec_file.c_str(), i);
 | |
|         println(hlog, "recording frame ", i, "/", isize(saved), " to ", s);
 | |
|         shot::take(s);
 | |
|         }
 | |
|       else 
 | |
|         println(hlog, "skipping frame ", i);
 | |
|       
 | |
|       i++;
 | |
|       }
 | |
|     return true;
 | |
|     };
 | |
|     
 | |
|   if(videofile != "") {
 | |
|     anims::record_video(videofile, f);
 | |
|     }
 | |
|   else 
 | |
|     f();
 | |
| 
 | |
|   // lasti = i;
 | |
|   recording = false;
 | |
|   }
 | |
|   
 | |
| void show_man_options() {
 | |
|   gamescreen(2);
 | |
|   dialog::init("manual animation");
 | |
|   
 | |
|   dialog::addSelItem("stepdist", fts(next_stepdist), 'd');
 | |
|   dialog::add_action([] {
 | |
|     dialog::editNumber(next_stepdist, 0, 1, 0.001, 0.02, "stepdist", "stepdist");
 | |
|     dialog::reaction = [] { set_stepdist(next_stepdist); };
 | |
|     });
 | |
| 
 | |
|   dialog::addSelItem("stepang", fts(next_stepang), 'a');
 | |
|   dialog::add_action([] {
 | |
|     dialog::editNumber(next_stepang, 0, 1, 0.001, 0.02, "stepang", "stepang");
 | |
|     dialog::reaction = [] { set_stepang(next_stepang); };
 | |
|     });
 | |
| 
 | |
|   dialog::addItem("b4 distance", 'b');
 | |
|   dialog::add_action(get_b4_distance);
 | |
| 
 | |
|   dialog::addSelItem("step smoothing", its(step_smoothing), 's');
 | |
|   dialog::add_action([] {
 | |
|     dialog::editNumber(step_smoothing, 1, 30, 1, 1, "step_smoothing", "step_smoothing");
 | |
|     dialog::reaction = [] { steps_to_change = step_smoothing; };
 | |
|     });
 | |
| 
 | |
|   dialog::addItem("save path", '[');
 | |
|   dialog::add_action([] {
 | |
|     fhstream f("devmods/manan-record.mar", "w");
 | |
|     f.write<int>(isize(saved));
 | |
|     for(int i=0; i<isize(saved); i++) {
 | |
|       auto& s = saved[i];
 | |
|       hwrite_raw(f, s.V);
 | |
|       hwrite_raw(f, s.lp);
 | |
|       int tmp = 0; hwrite_raw(f, tmp);
 | |
|       if(cryst) {
 | |
|         auto at = crystal::get_coord(s.co->master);
 | |
|         hwrite_raw(f, at);
 | |
|         }
 | |
|       else if(nil) {
 | |
|         auto at = nilv::get_coord(s.co->master);
 | |
|         hwrite_raw(f, at);
 | |
|         }
 | |
|       else if(bounded) {
 | |
|         auto ac = currentmap->allcells();
 | |
|         for(int i=0; i<isize(ac); i++) if(ac[i] == s.co)
 | |
|           hwrite_raw(f, i);
 | |
|         }
 | |
|       }
 | |
|     println(hlog, "saved animation of ", isize(saved), " frames");
 | |
|     });
 | |
| 
 | |
|   dialog::addItem("load path", ']');
 | |
|   dialog::add_action([] {
 | |
|     load_animation("devmods/manan-record.mar");
 | |
|     });
 | |
|   
 | |
|   dialog::addItem("do record", 'r');
 | |
|   dialog::add_action(do_recording);
 | |
| 
 | |
|   dialog::addItem("clear", 'c');
 | |
|   dialog::add_action([] { saved.clear(); });
 | |
| 
 | |
|   dialog::display();      
 | |
|   }
 | |
|   
 | |
| bool trailer_handleKey(int sym, int uni) {  
 | |
| 
 | |
|   if(sym == 'f' && (cmode & sm::NORMAL)) {
 | |
|     keys_on = !keys_on;
 | |
|     println(hlog, "keys_on = ", keys_on);
 | |
|     return true;
 | |
|     }
 | |
| 
 | |
|   if(keys_on && (cmode & sm::NORMAL)) {
 | |
| 
 | |
|     if(sym == ',') { vid.fov *= 1.1; mouseaim_sensitivity *= 1.1; println(hlog, "fov = ", vid.fov, " sens = ", mouseaim_sensitivity); }
 | |
|     if(sym == '.') { vid.fov /= 1.1; mouseaim_sensitivity /= 1.1; println(hlog, "fov = ", vid.fov, " sens = ", mouseaim_sensitivity); }
 | |
| 
 | |
|     if(sym == 't') {
 | |
|       if(!saved.empty()) {
 | |
|         println(hlog, "frames = ", isize(saved));
 | |
|         saved.pop_back();
 | |
|         }
 | |
|       if(!saved.empty()) {
 | |
|         recall();
 | |
|         }
 | |
|       return true;
 | |
|       }
 | |
|   
 | |
|     /* if(sym == 'e') {
 | |
|       dialog::editNumber(stepdist, 0, 1, 0.1, 0.1, "", "");
 | |
|       dialog::scaleLog();
 | |
|       } */
 | |
|                 
 | |
|     if(sym == 's') return move_camera_smoothchange([&] { return Id; });
 | |
|       
 | |
|     if(sym == 'a') return move_camera_smoothchange([&] { return cspin(0, 2, stepang); });
 | |
|   
 | |
|     if(sym == 'd') return move_camera_smoothchange([&] { return cspin(0, 2, -stepang); });
 | |
|   
 | |
|     if(sym == 'q') return move_camera_smoothchange([&] { return cspin(0, 2, stepang) * cspin(1, 2, stepang); });
 | |
|     if(sym == 'w') return move_camera_smoothchange([&] { return cspin(1, 2, stepang); });
 | |
|     if(sym == 'e') return move_camera_smoothchange([&] { return cspin(0, 2, -stepang) * cspin(1, 2, stepang); });
 | |
|   
 | |
|     if(sym == 'z') return move_camera_smoothchange([&] { return cspin(0, 2, stepang) * cspin(1, 2, -stepang); });
 | |
|     if(sym == 'x') return move_camera_smoothchange([&] { return cspin(1, 2, -stepang); });
 | |
|     if(sym == 'c') return move_camera_smoothchange([&] { return cspin(0, 2, -stepang) * cspin(1, 2, -stepang); });
 | |
| 
 | |
|     
 | |
|     if(sym == '1') { set_stepdist(0); return true; }
 | |
|     if(sym == '2') { set_stepdist(0.005); return true; }
 | |
|     if(sym == '3') { set_stepdist(0.02); return true; }
 | |
|     if(sym == '5') { set_stepang(0); return true; }
 | |
| 
 | |
|     if(sym == '6') { set_stepang(0.001); return true; }
 | |
|     if(sym == '7') { set_stepang(0.003); return true; }
 | |
|     if(sym == '8') { set_stepang(0.01); return true; }
 | |
|     if(sym == '9') { set_stepang(0.03); return true; }
 | |
|     if(sym == '0') { set_stepang(0.1); return true; }
 | |
|     
 | |
|     if(sym == 'o') { 
 | |
|       println(hlog, "spin_distance = ", spin_distance, " reset to 0, i to spin");
 | |
|       spin_distance = 0;
 | |
|       return true;
 | |
|       }
 | |
|     
 | |
|     if(sym == 'j') {      
 | |
|       fixed_orientation = !fixed_orientation;
 | |
|       orientation_to_fix = inverse(inverse(nisot::translate(inverse(View) * C0)) * inverse(View));
 | |
| 
 | |
| 
 | |
|       transmatrix iView = inverse(View);
 | |
|       orientation_to_fix = inverse(nisot::translate(iView * C0)) * iView;
 | |
| 
 | |
|       println(hlog, "fixed_orientation = ", orientation_to_fix);
 | |
|       return true;
 | |
|       }
 | |
|   
 | |
|     if(sym == 'i') { 
 | |
|       spinning_around = !spinning_around;
 | |
|       if(spinning_around) println(hlog, "spinning mode");
 | |
|       else println(hlog, "tank mode");
 | |
|       }
 | |
|   
 | |
|     if(sym == SDLK_F4) {
 | |
|       saving_positions = !saving_positions;
 | |
|       next_pos_tick = ticks;
 | |
|       println(hlog, "saving_positions = ", saving_positions);
 | |
|       mouseaim_sensitivity = 0;
 | |
|       return true;
 | |
|       }
 | |
|   
 | |
|     if(sym == 'b' && isize(saved) > 1) {
 | |
|       saved.pop_back();
 | |
|       println(hlog, "back to ", isize(saved), " frames");
 | |
|       recall();
 | |
|       return true;
 | |
|       }
 | |
|   
 | |
|     if(sym == 'u') {
 | |
|       for(int i=0; i<30; i++) if(isize(saved)) saved.pop_back();
 | |
|       println(hlog, "back to ", isize(saved), " frames");
 | |
|       if(isize(saved)) recall();
 | |
|       return true;
 | |
|       }
 | |
|     
 | |
|     if(sym == 'r') pushScreen(show_man_options);
 | |
|     }
 | |
|     
 | |
|   return false;
 | |
|   }
 | |
| 
 | |
| int ma_readArgs() {
 | |
|   using namespace arg;
 | |
|            
 | |
|   if(0) ;
 | |
|   else if(argis("-loada")) {
 | |
|     start_game();
 | |
|     shift(); load_animation(args());
 | |
|     }
 | |
|   else if(argis("-smoothen")) {
 | |
|     PHASEFROM(2); 
 | |
|     shift(); int nsm = argi();
 | |
|     denan();
 | |
|     for(int i=0; i<nsm; i++) smoothen();
 | |
|     }
 | |
|   else if(argis("-mrecf")) {
 | |
|     PHASEFROM(2);
 | |
|     shift(); mrec_first = argi();
 | |
|     }
 | |
|   else if(argis("-mrecl")) {
 | |
|     PHASEFROM(2);
 | |
|     shift(); mrec_last = argi();
 | |
|     }
 | |
|   else if(argis("-mrec-to")) {
 | |
|     PHASEFROM(2);
 | |
|     shift(); mrec_file = args();
 | |
|     }
 | |
|   else if(argis("-mrecv")) {
 | |
|     PHASEFROM(2);
 | |
|     shift(); videofile = args();
 | |
|     }
 | |
|   else if(argis("-mrec-fps")) {
 | |
|     PHASEFROM(2);
 | |
|     shift(); mrec_fps = argi();    
 | |
|     }
 | |
|   else if(argis("-shot-half")) {
 | |
|     shot::shotx /= 2;
 | |
|     shot::shoty /= 2;
 | |
|     }
 | |
|   else if(argis("-mrec-opt")) {
 | |
|     PHASEFROM(2);
 | |
|     shift(); string cap = args();
 | |
|     shift(); mrec_first_opt = pos;
 | |
|     while(args() != cap) shift();
 | |
|     mrec_last_opt = pos;
 | |
|     }
 | |
|   else return 1;
 | |
|   return 0;
 | |
|   }
 | |
| 
 | |
| 
 | |
| auto mahook = 
 | |
|   addHook(hooks_handleKey, 100, trailer_handleKey)
 | |
| + addHook(hooks_drawmap, 100, trailer_frame)
 | |
| + addHook(shmup::hooks_turn, 100, trailer_turn)
 | |
| + addHook(hooks_args, 100, ma_readArgs)
 | |
| + 0;
 | |
| 
 | |
| }
 |