mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-30 21:42:59 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			398 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			398 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #ifndef _ROGUEVIZ_H_
 | |
| #define _ROGUEVIZ_H_
 | |
| // See: http://www.roguetemple.com/z/hyper/rogueviz.php
 | |
| 
 | |
| #include "../hyper.h"
 | |
| 
 | |
| #ifdef HYPERPATH
 | |
| #define RVPATH HYPERPATH "rogueviz/"
 | |
| #else
 | |
| #define RVPATH "rogueviz/"
 | |
| #endif
 | |
| 
 | |
| #ifndef CAP_NCONF
 | |
| #define CAP_NCONF 0
 | |
| #endif
 | |
| 
 | |
| #ifndef CAP_RVSLIDES
 | |
| #define CAP_RVSLIDES (CAP_TOUR && !ISWEB)
 | |
| #endif
 | |
| 
 | |
| #ifndef CAP_MODELS
 | |
| #define CAP_MODELS (!ISWEB)
 | |
| #endif
 | |
| 
 | |
| namespace rogueviz {
 | |
|   using namespace hr;
 | |
|   
 | |
|   constexpr flagtype RV_GRAPH = 1;
 | |
|   constexpr flagtype RV_WHICHWEIGHT = 2; // sag
 | |
|   constexpr flagtype RV_AUTO_MAXWEIGHT = 4; // sag
 | |
|   constexpr flagtype RV_COMPRESS_LABELS = 8; // do not display some labels
 | |
|   constexpr flagtype RV_COLOR_TREE = 16; // color vertex together with tree parents
 | |
|   constexpr flagtype RV_HAVE_WEIGHT = 32; // edges have weights
 | |
|   constexpr flagtype RV_INVERSE_WEIGHT = 64; // edit weight, not 1/weight
 | |
|   
 | |
|   inline flagtype vizflags;
 | |
|   extern string weight_label;
 | |
|   extern ld maxweight;
 | |
|   extern ld ggamma;
 | |
|   extern bool highlight_target;
 | |
|   
 | |
|   extern int vertex_shape;
 | |
|   extern int search_for;
 | |
| 
 | |
|   void drawExtra();
 | |
|   void close();
 | |
| 
 | |
|   void init(flagtype flags);
 | |
|   
 | |
|   void graph_rv_hooks();
 | |
| 
 | |
|   struct edgetype {
 | |
|     double visible_from;
 | |
|     double visible_from_hi;
 | |
|     unsigned color, color_hi;
 | |
|     string name;
 | |
|     };
 | |
| 
 | |
|   edgetype *add_edgetype(const string& name);
 | |
|   
 | |
|   static constexpr unsigned DEFAULT_COLOR = 0x471293B5;
 | |
| 
 | |
|   extern edgetype default_edgetype;
 | |
|   
 | |
|   extern vector<shared_ptr<edgetype>> edgetypes;
 | |
|     
 | |
|   struct edgeinfo {
 | |
|     int i, j;
 | |
|     double weight, weight2;
 | |
|     vector<glvertex> prec;
 | |
|     basic_textureinfo tinf;
 | |
|     cell *orig;
 | |
|     int lastdraw;
 | |
|     edgetype *type;
 | |
|     edgeinfo(edgetype *t) { orig = NULL; lastdraw = -1; type = t; }
 | |
|     };
 | |
| 
 | |
|   extern vector<edgeinfo*> edgeinfos;
 | |
|   void addedge0(int i, int j, edgeinfo *ei);
 | |
|   void addedge(int i, int j, edgeinfo *ei);
 | |
|   void addedge(int i, int j, double wei, bool subdiv, edgetype *t);
 | |
|   extern vector<int> legend;
 | |
|   extern vector<cell*> named;
 | |
|   
 | |
|   int readLabel(fhstream& f);
 | |
| 
 | |
|   #if CAP_TEXTURE
 | |
|   struct rvimage {
 | |
|     basic_textureinfo tinf;
 | |
|     texture::texture_data tdata;
 | |
|     vector<hyperpoint> vertices;
 | |
|     };
 | |
|   #endif
 | |
|   
 | |
|   extern int brm_limit;
 | |
| 
 | |
|   struct colorpair {
 | |
|     color_t color1, color2;
 | |
|     char shade;
 | |
|     #if CAP_TEXTURE
 | |
|     shared_ptr<rvimage> img;
 | |
|     #endif
 | |
|     colorpair(color_t col = 0xC0C0C0FF) { shade = 0; color1 = color2 = col; }
 | |
|     };
 | |
|   
 | |
|   struct vertexdata {
 | |
|     vector<pair<int, edgeinfo*> > edges;
 | |
|     string name;
 | |
|     colorpair cp;
 | |
|     edgeinfo *virt;
 | |
|     bool special;
 | |
|     int data;
 | |
|     vector<string> urls;
 | |
|     vector<string> infos;
 | |
|     color_t spillcolor;
 | |
|     shmup::monster *m;
 | |
|     vertexdata() { virt = NULL; m = NULL; special = false; spillcolor = DEFAULT_COLOR; }
 | |
|     };
 | |
|   
 | |
|   extern vector<vertexdata> vdata;
 | |
|  
 | |
|   void storeall(int from = 0);
 | |
|   
 | |
|   extern bool showlabels;
 | |
| 
 | |
|   extern bool rog3;
 | |
|   extern bool rvwarp;
 | |
| 
 | |
|   extern colorpair dftcolor;
 | |
|   
 | |
|   inline hookset<void(vertexdata&, cell*, shmup::monster*, int)> hooks_drawvertex;
 | |
|   inline hookset<bool(edgeinfo*, bool store)> hooks_alt_edges;
 | |
|   inline purehookset hooks_rvmenu;
 | |
|   inline hookset<bool()> hooks_rvmenu_replace;
 | |
|   inline hookset<bool(int&, string&, FILE*)> hooks_readcolor;
 | |
|   
 | |
|   void readcolor(const string& cfname);
 | |
| 
 | |
|   void close();
 | |
|   extern bool showlabels;
 | |
| 
 | |
|   namespace pres {
 | |
|     using namespace hr::tour;
 | |
| #if CAP_RVSLIDES
 | |
|     inline hookset<void(string, vector<slide>&)> hooks_build_rvtour;
 | |
|     slide *gen_rvtour();
 | |
|     #if CAP_TEXTURE
 | |
|     void draw_texture(texture::texture_data& tex, ld dx = 0, ld dy = 0, ld scale = 1);
 | |
|     #endif
 | |
| 
 | |
|     extern map<string, texture::texture_data> textures;
 | |
| 
 | |
| inline void setCanvasChar(presmode mode, char c) {
 | |
|   if(c == '0') {
 | |
|     setCanvasColor(mode, 0x101010, [] {});
 | |
|     }
 | |
|   if(c == 'd') {
 | |
|     setCanvas(mode, &ccolor::landscape_dark);
 | |
|     }
 | |
|   }
 | |
| 
 | |
| template<class T, class U> function<void(presmode)> roguevizslide(char c, const T& t, const U& f) {
 | |
|   return [c,t,f] (presmode mode) {
 | |
|     f(mode);
 | |
|     setCanvasChar(mode, c);
 | |
|     if(mode == 1 || mode == pmGeometryStart) t();
 | |
|   
 | |
|     if(mode == 3 || mode == pmGeometry || mode == pmGeometryReset) {
 | |
|       rogueviz::close();
 | |
|       shmup::clearMonsters();
 | |
|       if(mode == pmGeometryReset && !(slides[currentslide].flags & QUICKGEO)) t();
 | |
|       }
 | |
|   
 | |
|     slidecommand = "toggle the player";
 | |
|     if(mode == 4) 
 | |
|       mapeditor::drawplayer = !mapeditor::drawplayer;
 | |
|     pd_from = NULL;
 | |
|     };
 | |
|   }
 | |
| 
 | |
| template<class T> function<void(presmode)> roguevizslide(char c, const T& t) { return roguevizslide(c, t, [] (presmode mode) {}); }
 | |
| 
 | |
| template<class T, class U>
 | |
| function<void(presmode)> roguevizslide_action(char c, const T& t, const U& act) {
 | |
|   return [c,t,act] (presmode mode) {
 | |
|     setCanvasChar(mode, c);
 | |
|     if(mode == pmStart || mode == pmGeometryStart) t();
 | |
|   
 | |
|     act(mode);
 | |
| 
 | |
|     if(mode == pmStop || mode == pmGeometry || mode == pmGeometryReset) {
 | |
|       rogueviz::close();
 | |
|       shmup::clearMonsters();
 | |
|       if(mode == pmGeometryReset && !(slides[currentslide].flags & QUICKGEO)) t();
 | |
|       }
 | |
|   
 | |
|     };
 | |
|   }
 | |
| 
 | |
| 
 | |
|     void add_end(vector<slide>& s);
 | |
| 
 | |
|     template<class T, class U> void add_temporary_hook(int mode, hookset<T>& m, int prio, U&& hook) {
 | |
|       using namespace tour;
 | |
|       if(mode == pmStart) {
 | |
|         int p = addHook(m, prio, hook);
 | |
|         on_restore([&m, p] { 
 | |
|           delHook(m, p); 
 | |
|           });
 | |
|         }
 | |
|       }
 | |
| 
 | |
|   /* maks graphs in presentations */
 | |
|   struct grapher {
 | |
|   
 | |
|     ld minx, miny, maxx, maxy;
 | |
|     
 | |
|     shiftmatrix T;
 | |
|     
 | |
|     grapher(ld _minx, ld _miny, ld _maxx, ld _maxy);
 | |
|     void line(hyperpoint h1, hyperpoint h2, color_t col);
 | |
|     void arrow(hyperpoint h1, hyperpoint h2, ld sca, color_t col = 0xFF);
 | |
|     shiftmatrix pos(ld x, ld y, ld sca);
 | |
|     };
 | |
|   
 | |
|   void add_stat(presmode mode, const bool_reaction_t& stat);  
 | |
|   void compare_projections(presmode mode, eModel a, eModel b);
 | |
|   void no_other_hud(presmode mode);
 | |
|   void replace_hud(presmode mode, reaction_t f);
 | |
|   void non_game_slide(presmode mode);
 | |
|   void non_game_slide_scroll(presmode mode);
 | |
|   void white_screen(presmode mode, color_t col = 0xFFFFFFFF);
 | |
|   void empty_screen(presmode mode, color_t col = 0xFFFFFFFF);
 | |
|   void show_picture(presmode mode, string s, flagtype flags = 0);
 | |
|   void sub_picture(string s, flagtype flags = 0, ld dx = 0, ld dy = 0, ld scale = 1);
 | |
|   void show_animation(presmode mode, string s, int sx, int sy, int frames, int fps);
 | |
|   void use_angledir(presmode mode, bool reset);
 | |
|   void slide_error(presmode mode, string s);
 | |
| 
 | |
|   static constexpr flagtype LATEX_COLOR = 1;
 | |
|   
 | |
|   void show_latex(presmode mode, string s);
 | |
|   string latex_cachename(string s, flagtype flags);
 | |
|   void dialog_add_latex(string s, color_t color, int size = 100, flagtype flag = 0);
 | |
|   void dialog_may_latex(string latex, string normal, color_t col = dialog::dialogcolor, int size = 100, flagtype flag = 0);
 | |
|   void uses_game(presmode mode, string name, reaction_t launcher, reaction_t restore);
 | |
|   void latex_slide(presmode mode, string s, flagtype flags = 0, int size = 100);
 | |
|   void latex_in_space(const shiftmatrix& V, ld scale, string s, color_t col, flagtype flags);
 | |
|   
 | |
|   inline purehookset hooks_latex_slide, hooks_post_latex_slide;
 | |
| 
 | |
|   inline ld angle = 0;
 | |
|   inline int dir = -1;
 | |
|   hyperpoint p2(ld x, ld y);
 | |
| #endif
 | |
|   }
 | |
| 
 | |
|   void createViz(int id, cell *c, transmatrix at);
 | |
| 
 | |
|   extern map<string, int> labeler;
 | |
|   bool id_known(const string& s);
 | |
|   int getid(const string& s);
 | |
|   int getnewid(string s);
 | |
|   extern string fname;
 | |
| 
 | |
|   bool rv_ignore(char c);
 | |
| 
 | |
|   colorpair perturb(colorpair cp);
 | |
|   void queuedisk(const shiftmatrix& V, const colorpair& cp, bool legend, const string* url, int i);
 | |
| 
 | |
| /* 3D models */
 | |
| 
 | |
| namespace objmodels {
 | |
| 
 | |
|   using tf_result = pair<int, hyperpoint>;
 | |
| 
 | |
|   using transformer = std::function<tf_result(hyperpoint)>;
 | |
|   using subdivider = std::function<int(vector<hyperpoint>&)>;
 | |
|   
 | |
|   inline ld prec = 1;
 | |
|   
 | |
|   inline bool shift_to_ctr = false;
 | |
| 
 | |
|   struct object {
 | |
|     hpcshape sh;
 | |
|     string mtlname;
 | |
|     basic_textureinfo tv;
 | |
|     color_t color;
 | |
|     };
 | |
|   
 | |
|   struct model_data : gi_extension {
 | |
|     ld prec_used;
 | |
|     vector<shared_ptr<object>> objs;
 | |
|     vector<int> objindex;
 | |
|     void render(const shiftmatrix& V);
 | |
|     };
 | |
|   
 | |
|   #if CAP_TEXTURE
 | |
|   struct model {
 | |
|   
 | |
|     string path, fname;
 | |
|   
 | |
|     bool is_available, av_checked;
 | |
| 
 | |
|     model(string path = "", string fn = "") : path(path), fname(fn) { av_checked = false; }
 | |
|   
 | |
|     map<string, texture::texture_data> materials;
 | |
|     map<string, color_t> colors;
 | |
|     
 | |
|     /* private */
 | |
|     virtual void load_obj(model_data& objects);
 | |
|     
 | |
|     virtual model_data& get();
 | |
| 
 | |
|     virtual void prepare() {}
 | |
|     virtual void postprocess() {}
 | |
| 
 | |
|     virtual color_t read_color(ld a, ld b, ld c);
 | |
| 
 | |
|     virtual hyperpoint transform(hyperpoint h);
 | |
| 
 | |
|     virtual int subdivision(vector<hyperpoint>& hys);
 | |
| 
 | |
|     virtual void render(const shiftmatrix& V) { get().render(V); }
 | |
| 
 | |
|     virtual void process_triangle(vector<hyperpoint>& hys, vector<hyperpoint>& tot, bool textured, object *co);
 | |
|     
 | |
|     bool available();
 | |
| 
 | |
|     virtual ~model() {}
 | |
|     };
 | |
| 
 | |
|   void add_model_settings();
 | |
|   #endif
 | |
|   
 | |
|   }
 | |
| 
 | |
| #if CAP_RVSLIDES
 | |
| #define addHook_rvslides(x, y) addHook(rogueviz::pres::hooks_build_rvtour, x, y)
 | |
| #define addHook_slideshows(x, y) addHook(tour::ss::hooks_extra_slideshows, x, y)
 | |
| #define addHook_rvtour(x, y) addHook(pres::hooks_build_rvtour, x, y)
 | |
| #else
 | |
| #define addHook_rvslides(x, y) 0
 | |
| #define addHook_slideshows(x, y) 0
 | |
| #define addHook_rvtour(x, y) 0
 | |
| #endif
 | |
| 
 | |
|   /* parallelize a computation */
 | |
|   inline int threads = 1;
 | |
| 
 | |
|   #if CAP_THREAD
 | |
|   template<class T> auto parallelize(long long N, T action) -> decltype(action(0,0)) {
 | |
|     if(threads == 1) return action(0,N);
 | |
|     std::vector<std::thread> v;
 | |
|     typedef decltype(action(0,0)) Res;
 | |
|     std::vector<Res> results(threads);
 | |
|     for(int k=0; k<threads; k++)
 | |
|       v.emplace_back([&,k] () { 
 | |
|         results[k] = action(N*k/threads, N*(k+1)/threads); 
 | |
|         });
 | |
|     for(std::thread& t:v) t.join();
 | |
|     Res res = 0;
 | |
|     for(Res r: results) res += r;
 | |
|     return res;
 | |
|     }
 | |
|   #else
 | |
|   template<class T> auto parallelize(long long N, T action) -> decltype(action(0,0)) {
 | |
|     return action(0, N);
 | |
|     }
 | |
|   #endif
 | |
| 
 | |
| namespace smoothcam {
 | |
|   void save_animation(hstream& f);
 | |
|   void load_animation(hstream& f);
 | |
|   void handle_animation(ld);
 | |
|   void enable();
 | |
|   extern bool animate_on;
 | |
|   extern ld last_time;
 | |
|   void enable_and_show();
 | |
|   void backup();
 | |
|   void append_backup();
 | |
|   void set_time(ld t);
 | |
|   }
 | |
| 
 | |
| #if RVCOL
 | |
| enum class rvlc { num, s, ms };
 | |
| void rv_achievement(const string& name);
 | |
| void rv_leaderboard(const string& name, int score, int highisgood, rvlc x);
 | |
| void rv_leaderboard(const string& name, int score, int highisgood, rvlc x, const string& data);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| #if RVCOL
 | |
| using rogueviz::rvlc;
 | |
| #endif
 | |
| 
 | |
| #endif
 | 
