#ifndef _ROGUEVIZ_H_ #define _ROGUEVIZ_H_ // See: http://www.roguetemple.com/z/hyper/rogueviz.php #include "../hyper.h" #define RVPATH HYPERPATH "rogueviz/" #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 const unsigned DEFAULT_COLOR = 0x471293B5; extern edgetype default_edgetype; extern vector> edgetypes; struct edgeinfo { int i, j; double weight, weight2; vector prec; basic_textureinfo tinf; cell *orig; int lastdraw; edgetype *type; edgeinfo(edgetype *t) { orig = NULL; lastdraw = -1; type = t; } }; extern vector 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 legend; extern vector named; int readLabel(fhstream& f); #if CAP_TEXTURE struct rvimage { basic_textureinfo tinf; texture::texture_data tdata; vector vertices; }; #endif extern int brm_limit; struct colorpair { color_t color1, color2; char shade; #if CAP_TEXTURE shared_ptr img; #endif colorpair(color_t col = 0xC0C0C0FF) { shade = 0; color1 = color2 = col; } }; struct vertexdata { vector > edges; string name; colorpair cp; edgeinfo *virt; bool special; int data; string *info; shmup::monster *m; vertexdata() { virt = NULL; m = NULL; info = NULL; special = false; } }; extern vector vdata; void storeall(int from = 0); extern vector cleanup; void do_cleanup(); inline void on_cleanup_or_next(const reaction_t& del) { #if CAP_TOUR if(tour::on) tour::on_restore(del); else #endif cleanup.push_back(del); } template void rv_change(T& variable, const T& value) { T backup = variable; variable = value; on_cleanup_or_next([backup, &variable] { variable = backup; }); } template void rv_hook(hookset& m, int prio, U&& hook) { int p = addHook(m, prio, hook); auto del = [&m, p] { delHook(m, p); }; on_cleanup_or_next(del); } extern bool showlabels; extern bool rog3; extern bool rvwarp; extern colorpair dftcolor; inline hookset hooks_drawvertex; inline hookset hooks_alt_edges; inline purehookset hooks_rvmenu; inline hookset hooks_rvmenu_replace; inline hookset hooks_readcolor; inline purehookset hooks_close; void readcolor(const string& cfname); void close(); extern bool showlabels; namespace pres { using namespace hr::tour; #if CAP_RVSLIDES inline hookset&)> 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 textures; template function roguevizslide(char c, const T& t, const U& f) { return [c,t,f] (presmode mode) { f(mode); patterns::canvasback = 0x101010; setCanvas(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 function roguevizslide(char c, const T& t) { return roguevizslide(c, t, [] (presmode mode) {}); } template function roguevizslide_action(char c, const T& t, const U& act) { return [c,t,act] (presmode mode) { patterns::canvasback = 0x101010; setCanvas(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& s); template void add_temporary_hook(int mode, hookset& 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 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 const flagtype LATEX_COLOR = 1; void show_latex(presmode mode, string s); 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); inline purehookset hooks_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 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* info, int i); /* 3D models */ namespace objmodels { using tf_result = pair; using transformer = std::function; using subdivider = std::function&)>; inline ld prec = 1; inline bool shift_to_ctr = false; struct object { hpcshape sh; basic_textureinfo tv; color_t color; }; struct model_data : gi_extension { ld prec_used; vector> objs; vector 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 materials; map 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& hys); virtual void render(const shiftmatrix& V) { get().render(V); } virtual void process_triangle(vector& hys, vector& tot, bool textured, object *co); bool available(); }; 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 auto parallelize(long long N, T action) -> decltype(action(0,0)) { if(threads == 1) return action(0,N); std::vector v; typedef decltype(action(0,0)) Res; std::vector results(threads); for(int k=0; k auto parallelize(long long N, T action) -> decltype(action(0,0)) { return action(0, N); } #endif } #endif