1 #ifndef _ROGUEVIZ_H_
2 #define _ROGUEVIZ_H_
3 // See: http://www.roguetemple.com/z/hyper/rogueviz.php
4 
5 #include "../hyper.h"
6 
7 #define RVPATH HYPERPATH "rogueviz/"
8 
9 #ifndef CAP_NCONF
10 #define CAP_NCONF 0
11 #endif
12 
13 #ifndef CAP_RVSLIDES
14 #define CAP_RVSLIDES (CAP_TOUR && !ISWEB)
15 #endif
16 
17 namespace rogueviz {
18   using namespace hr;
19 
20   constexpr flagtype RV_GRAPH = 1;
21   constexpr flagtype RV_WHICHWEIGHT = 2; // sag
22   constexpr flagtype RV_AUTO_MAXWEIGHT = 4; // sag
23   constexpr flagtype RV_COMPRESS_LABELS = 8; // do not display some labels
24   constexpr flagtype RV_COLOR_TREE = 16; // color vertex together with tree parents
25   constexpr flagtype RV_HAVE_WEIGHT = 32; // edges have weights
26   constexpr flagtype RV_INVERSE_WEIGHT = 64; // edit weight, not 1/weight
27 
28   inline flagtype vizflags;
29   extern string weight_label;
30   extern ld maxweight;
31 
32   extern int vertex_shape;
33 
34   void drawExtra();
35   void close();
36 
37   void init(flagtype flags);
38 
39   struct edgetype {
40     double visible_from;
41     double visible_from_hi;
42     double visible_from_help;
43     unsigned color, color_hi;
44     string name;
45     };
46 
47   edgetype *add_edgetype(const string& name);
48 
49   static const unsigned DEFAULT_COLOR = 0x471293B5;
50 
51   extern edgetype default_edgetype;
52 
53   extern vector<shared_ptr<edgetype>> edgetypes;
54 
55   struct edgeinfo {
56     int i, j;
57     double weight, weight2;
58     vector<glvertex> prec;
59     basic_textureinfo tinf;
60     cell *orig;
61     int lastdraw;
62     edgetype *type;
edgeinfoedgeinfo63     edgeinfo(edgetype *t) { orig = NULL; lastdraw = -1; type = t; }
64     };
65 
66   extern vector<edgeinfo*> edgeinfos;
67   void addedge0(int i, int j, edgeinfo *ei);
68   void addedge(int i, int j, edgeinfo *ei);
69   void addedge(int i, int j, double wei, bool subdiv, edgetype *t);
70   extern vector<int> legend;
71   extern vector<cell*> named;
72 
73   #if CAP_TEXTURE
74   struct rvimage {
75     basic_textureinfo tinf;
76     texture::texture_data tdata;
77     vector<hyperpoint> vertices;
78     };
79   #endif
80 
81   extern int brm_limit;
82 
83   struct colorpair {
84     color_t color1, color2;
85     char shade;
86     #if CAP_TEXTURE
87     shared_ptr<rvimage> img;
88     #endif
89     colorpair(color_t col = 0xC0C0C0FF) { shade = 0; color1 = color2 = col; }
90     };
91 
92   struct vertexdata {
93     vector<pair<int, edgeinfo*> > edges;
94     string name;
95     colorpair cp;
96     edgeinfo *virt;
97     bool special;
98     int data;
99     string *info;
100     shmup::monster *m;
vertexdatavertexdata101     vertexdata() { virt = NULL; m = NULL; info = NULL; special = false; }
102     };
103 
104   extern vector<vertexdata> vdata;
105 
106   void storeall(int from = 0);
107 
108   extern vector<reaction_t> cleanup;
109 
110   void do_cleanup();
111 
rv_hook(hookset<T> & m,int prio,U && hook)112   template<class T, class U> void rv_hook(hookset<T>& m, int prio, U&& hook) {
113     int p = addHook(m, prio, hook);
114     auto del = [&m, p] {
115       delHook(m, p);
116       };
117     if(tour::on) tour::on_restore(del);
118     else cleanup.push_back(del);
119     }
120 
121   namespace anygraph {
122     extern double R, alpha, T;
123     extern vector<pair<double, double> > coords;
124 
125     void fixedges();
126     void read(string fn, bool subdiv = true, bool doRebase = true, bool doStore = true);
127     extern int N;
128     }
129 
130   extern bool showlabels;
131 
132   extern bool rog3;
133   extern bool rvwarp;
134 
135   extern colorpair dftcolor;
136 
137   inline hookset<void(vertexdata&, cell*, shmup::monster*, int)> hooks_drawvertex;
138   inline hookset<bool(edgeinfo*, bool store)> hooks_alt_edges;
139   inline purehookset hooks_rvmenu;
140   inline hookset<bool()> hooks_rvmenu_replace;
141   inline hookset<bool(int&, string&, FILE*)> hooks_readcolor;
142   inline purehookset hooks_close;
143 
144   void readcolor(const string& cfname);
145 
146   void close();
147   extern bool showlabels;
148 
149   namespace pres {
150     using namespace hr::tour;
151 #if CAP_RVSLIDES
152     inline hookset<void(string, vector<slide>&)> hooks_build_rvtour;
153     slide *gen_rvtour();
154     #if CAP_TEXTURE
155     void draw_texture(texture::texture_data& tex);
156     #endif
157 
roguevizslide(char c,const T & t,const U & f)158 template<class T, class U> function<void(presmode)> roguevizslide(char c, const T& t, const U& f) {
159   return [c,t,f] (presmode mode) {
160     f(mode);
161     patterns::canvasback = 0x101010;
162     setCanvas(mode, c);
163     if(mode == 1 || mode == pmGeometryStart) t();
164 
165     if(mode == 3 || mode == pmGeometry || mode == pmGeometryReset) {
166       rogueviz::close();
167       shmup::clearMonsters();
168       if(mode == pmGeometryReset && !(slides[currentslide].flags & QUICKGEO)) t();
169       }
170 
171     slidecommand = "toggle the player";
172     if(mode == 4)
173       mapeditor::drawplayer = !mapeditor::drawplayer;
174     pd_from = NULL;
175     };
176   }
177 
roguevizslide(char c,const T & t)178 template<class T> function<void(presmode)> roguevizslide(char c, const T& t) { return roguevizslide(c, t, [] (presmode mode) {}); }
179 
180 template<class T, class U>
roguevizslide_action(char c,const T & t,const U & act)181 function<void(presmode)> roguevizslide_action(char c, const T& t, const U& act) {
182   return [c,t,act] (presmode mode) {
183     patterns::canvasback = 0x101010;
184     setCanvas(mode, c);
185     if(mode == pmStart || mode == pmGeometryStart) t();
186 
187     act(mode);
188 
189     if(mode == pmStop || mode == pmGeometry || mode == pmGeometryReset) {
190       rogueviz::close();
191       shmup::clearMonsters();
192       if(mode == pmGeometryReset && !(slides[currentslide].flags & QUICKGEO)) t();
193       }
194 
195     };
196   }
197 
198 
199     void add_end(vector<slide>& s);
200 
add_temporary_hook(int mode,hookset<T> & m,int prio,U && hook)201     template<class T, class U> void add_temporary_hook(int mode, hookset<T>& m, int prio, U&& hook) {
202       using namespace tour;
203       if(mode == pmStart) {
204         int p = addHook(m, prio, hook);
205         on_restore([&m, p] {
206           delHook(m, p);
207           });
208         }
209       }
210 
211   /* maks graphs in presentations */
212   struct grapher {
213 
214     ld minx, miny, maxx, maxy;
215 
216     shiftmatrix T;
217 
218     grapher(ld _minx, ld _miny, ld _maxx, ld _maxy);
219     void line(hyperpoint h1, hyperpoint h2, color_t col);
220     void arrow(hyperpoint h1, hyperpoint h2, ld sca, color_t col = 0xFF);
221     shiftmatrix pos(ld x, ld y, ld sca);
222     };
223 
224   void add_stat(presmode mode, const bool_reaction_t& stat);
225   void compare_projections(presmode mode, eModel a, eModel b);
226   void no_other_hud(presmode mode);
227   void empty_screen(presmode mode, color_t col = 0xFFFFFFFF);
228   void show_picture(presmode mode, string s);
229   void use_angledir(presmode mode, bool reset);
230   void slide_error(presmode mode, string s);
231 
232   inline ld angle = 0;
233   inline int dir = -1;
234   hyperpoint p2(ld x, ld y);
235 #endif
236   }
237 
238   void createViz(int id, cell *c, transmatrix at);
239 
240   extern map<string, int> labeler;
241   bool id_known(const string& s);
242   int getid(const string& s);
243   int getnewid(string s);
244   extern string fname;
245 
246   bool rv_ignore(char c);
247 
248   colorpair perturb(colorpair cp);
249   void queuedisk(const shiftmatrix& V, const colorpair& cp, bool legend, const string* info, int i);
250 
251 /* 3D models */
252 
253 namespace objmodels {
254 
255   using tf_result = pair<int, hyperpoint>;
256 
257   using transformer = std::function<tf_result(hyperpoint)>;
258   using subdivider = std::function<int(vector<hyperpoint>&)>;
259 
260   inline ld prec = 1;
261 
262   struct object {
263     hpcshape sh;
264     basic_textureinfo tv;
265     color_t color;
266     };
267 
268   struct model_data : gi_extension {
269     ld prec_used;
270     vector<shared_ptr<object>> objs;
271     void render(const shiftmatrix& V);
272     };
273 
default_transformer(hyperpoint h)274   inline tf_result default_transformer(hyperpoint h) { return {0, direct_exp(h) };}
275 
default_subdivider(vector<hyperpoint> & hys)276   inline int default_subdivider(vector<hyperpoint>& hys) {
277     if(euclid) return 1;
278     ld maxlen = prec * max(hypot_d(3, hys[1] - hys[0]), max(hypot_d(3, hys[2] - hys[0]), hypot_d(3, hys[2] - hys[1])));
279     return int(ceil(maxlen));
280     }
281 
282   #if CAP_TEXTURE
283   struct model {
284 
285     string path, fname;
286     reaction_t preparer;
287     transformer tf;
288     subdivider sd;
289 
290     bool is_available, av_checked;
291 
292     model(string path = "", string fn = "",
293       transformer tf = default_transformer,
294       reaction_t prep = [] {},
295       subdivider sd = default_subdivider
pathmodel296       ) : path(path), fname(fn), preparer(prep), tf(tf), sd(sd) { av_checked = false; }
297 
298     map<string, texture::texture_data> materials;
299     map<string, color_t> colors;
300 
301     /* private */
302     void load_obj(model_data& objects);
303 
304     model_data& get();
305 
rendermodel306     void render(const shiftmatrix& V) { get().render(V); }
307 
308     bool available();
309     };
310 
311   void add_model_settings();
312   #endif
313 
314   }
315 
316 #if CAP_RVSLIDES
317 #define addHook_rvslides(x, y) addHook(rogueviz::pres::hooks_build_rvtour, x, y)
318 #define addHook_slideshows(x, y) addHook(tour::ss::hooks_extra_slideshows, x, y)
319 #define addHook_rvtour(x, y) addHook(pres::hooks_build_rvtour, x, y)
320 #else
321 #define addHook_rvslides(x, y) 0
322 #define addHook_slideshows(x, y) 0
323 #define addHook_rvtour(x, y) 0
324 #endif
325   }
326 
327 #endif
328