diff --git a/3d-models.cpp b/3d-models.cpp index dd848a6f..d85e84ce 100644 --- a/3d-models.cpp +++ b/3d-models.cpp @@ -879,7 +879,7 @@ void geometry_information::make_shadow(hpcshape& sh) { void geometry_information::make_3d_models() { if(GDIM == 2 || noGUI) return; eyepos = WDIM == 2 ? 0.875 : 0.925; - DEBBI(DF_POLY, ("make_3d_models")); + DEBBI(debug_poly, ("make_3d_models")); shcenter = tile_center(); #if CAP_GL @@ -891,7 +891,7 @@ void geometry_information::make_3d_models() { #endif if(WDIM == 2 || euclid) { - DEBB(DF_POLY, ("shadows")); + DEBB(debug_poly, ("shadows")); for(hpcshape* sh: {&shBatWings, &shBugBody, &shBullBody, &shButterflyWing, &shCatBody, &shDogBody, &shDogTorso, &shEagle, &shFemaleBody, &shFlailMissile, &shGadflyWing, &shGargoyleWings, &shHawk, &shJiangShi, &shKnife, &shPBody, &shPHead, &shRaiderBody, &shReptileBody, &shSkeletonBody, &shTongue, &shTrapArrow, &shTrylobite, @@ -903,7 +903,7 @@ void geometry_information::make_3d_models() { for(int i=0; i<8; i++) make_shadow(shAsteroid[i]); } - DEBB(DF_POLY, ("humanoids")); + DEBB(debug_poly, ("humanoids")); make_humanoid_3d(shPBody); make_humanoid_3d(shYeti); make_humanoid_3d(shFemaleBody); @@ -918,7 +918,7 @@ void geometry_information::make_3d_models() { // shRaiderBody = shPBody; // shJiangShi = shPBody; - DEBB(DF_POLY, ("heads")); + DEBB(debug_poly, ("heads")); make_head_3d(shFemaleHair); make_head_3d(shPHead); make_head_3d(shTurban1); @@ -942,7 +942,7 @@ void geometry_information::make_3d_models() { make_head_3d(shJiangShiCap2); make_head_3d(shTerraHead); - DEBB(DF_POLY, ("armors")); + DEBB(debug_poly, ("armors")); make_armor_3d(shKnightArmor); make_armor_3d(shKnightCloak, 2); make_armor_3d(shPrinceDress); @@ -961,7 +961,7 @@ void geometry_information::make_3d_models() { make_armor_3d(shHood, 2); - DEBB(DF_POLY, ("feet and paws")); + DEBB(debug_poly, ("feet and paws")); make_foot_3d(shHumanFoot); make_foot_3d(shYetiFoot); make_skeletal(shSkeletalFoot, WDIM == 2 ? zc(0.5) + human_height/40 - FLOOR : 0); @@ -983,7 +983,7 @@ void geometry_information::make_3d_models() { make_paw_3d(shDogFrontPaw, shDogFrontLeg); make_paw_3d(shDogRearPaw, shDogRearLeg); - DEBB(DF_POLY, ("revolution")); + DEBB(debug_poly, ("revolution")); // make_abody_3d(shWolfBody, 0.01); // make_ahead_3d(shWolfHead); // make_ahead_3d(shFamiliarHead); @@ -1076,7 +1076,7 @@ void geometry_information::make_3d_models() { make_revolution_cut(shButterflyWing, 180, 0, 0.05*S); finishshape(); - DEBB(DF_POLY, ("animatebirds")); + DEBB(debug_poly, ("animatebirds")); animate_bird(shEagle, shAnimatedEagle, 0.05*S); animate_bird(shTinyBird, shAnimatedTinyEagle, 0.05*S/2); @@ -1088,7 +1088,7 @@ void geometry_information::make_3d_models() { animate_bird(shBatWings, shAnimatedBat, 0.05*S); animate_bird(shBatBody, shAnimatedBat2, 0.05*S); - DEBB(DF_POLY, ("disablers")); + DEBB(debug_poly, ("disablers")); disable(shWolfRearLeg); disable(shWolfFrontLeg); @@ -1123,7 +1123,7 @@ void geometry_information::make_3d_models() { make_head_only(); - DEBB(DF_POLY, ("balls")); + DEBB(debug_poly, ("balls")); make_ball(shDisk, orbsize*.2, 2); make_ball(shHeptaMarker, zhexf*.2, 1); make_ball(shSnowball, zhexf*.1, 1); @@ -1173,7 +1173,7 @@ void geometry_information::make_3d_models() { clone_shape(shRose, shRoseItem); shift_shape(shRose, FLOOR - human_height * 1/20); - DEBB(DF_POLY, ("slime")); + DEBB(debug_poly, ("slime")); bshape(shSlime, PPR::MONSTER_BODY); hyperpoint tip = xtangent(1); hyperpoint atip = xtangent(-1); @@ -1197,7 +1197,7 @@ void geometry_information::make_3d_models() { shift_shape(shMagicSword, ABODY); shift_shape(shMagicShovel, ABODY); - DEBB(DF_POLY, ("eyes")); + DEBB(debug_poly, ("eyes")); adjust_eye(shSlimeEyes, shSlime, FLATEYE, 0, 2, 2); adjust_eye(shGhostEyes, shGhost, GHOST, GHOST, 2, WDIM == 2 ? 2 : 4); adjust_eye(shMiniEyes, shMiniGhost, GHOST, GHOST, 2, 2); diff --git a/achievement.cpp b/achievement.cpp index b49821d9..47206733 100644 --- a/achievement.cpp +++ b/achievement.cpp @@ -909,12 +909,14 @@ EX void check_total_victory() { hadtotalvictory = true; achievement_gain("TOTALVICTORY"); } - + +EX debugflag debug_achievements = {"steam_achievements"}; + /** gain the victory achievements. * @param hyper true for the Hyperstone victory, and false for the Orb of Yendor victory. */ EX void achievement_victory(bool hyper) { - DEBBI(DF_STEAM, ("achievement_victory")) + if(debug_achievements) println(hlog, "achievement_victory"); if(offlineMode) return; #if CAP_ACHIEVE if(cheater) return; @@ -931,7 +933,8 @@ EX void achievement_victory(bool hyper) { if(ineligible_starting_land) return; if(use_custom_land_list) return; LATE( achievement_victory(hyper); ) - DEBB(DF_STEAM, ("after checks")) + + if(debug_achievements) println(hlog, "after checks"); int t = getgametime(); @@ -982,7 +985,8 @@ EX void achievement_victory(bool hyper) { } } - DEBB(DF_STEAM, ("uploading scores")) + if(debug_achievements) println(hlog, "uploading scores"); + upload_score(ih1, t); upload_score(ih2, turncount); #endif diff --git a/arbitrile.cpp b/arbitrile.cpp index 795b3397..6f6e2b0a 100644 --- a/arbitrile.cpp +++ b/arbitrile.cpp @@ -275,7 +275,7 @@ void shape::build_from_angles_edges(bool is_comb) { vector matrices; for(int i=0; i& old_shvids, map& old_to_n int chg = 1; while(chg) { - if(debugflags & DF_GEOM) { + if(debug_geometry) { println(hlog, "current table of equals:"); int eqid = 0; for(auto& eq: equal) { @@ -2117,7 +2117,7 @@ EX void convert() { cyclefix(alpha, 0); sh.angles.push_back(alpha); } - if(debugflags & DF_GEOM) { + if(debug_geometry) { println(hlog, "shape ", i, ":"); indenter indp(2); println(hlog, "vertices=", sh.vertices); diff --git a/archimedean.cpp b/archimedean.cpp index 227eaf84..6943256d 100644 --- a/archimedean.cpp +++ b/archimedean.cpp @@ -141,7 +141,7 @@ EX int gcd(int x, int y) { return x ? gcd(y%x, x) : y < 0 ? -y : y; } void archimedean_tiling::make_match(int a, int i, int b, int j) { if(isize(adjacent[a]) != isize(adjacent[b])) { - DEBB(DF_GEOM, ("(error here)")); + if(debug_geometry) println(hlog, "make_match error"); errormsg = XLAT("polygons match incorrectly"); errors++; } @@ -291,9 +291,9 @@ void archimedean_tiling::prepare() { for(int oi=0; oi<1; oi++) { int at = (i+oi)%N; int inv = oi; - DEBB0(DF_GEOM, ("vertex ")); + if(debug_geometry) print(hlog, "vertex "); for(int z=0; z [%d %d]\n", at, inv))); + if(debug_geometry) print(hlog, "-> ", tie(at, inv)); } } for(int i=0; i= isize(adjacent[ai])) aj = 0; } - DEBB(DF_GEOM, (hr::format("-> [%d %d]\n", ai, aj))); + if(debug_geometry) println(hlog, "-> ", tie(ai, aj)); make_match(i, j, ai, aj); } } @@ -406,10 +406,9 @@ void archimedean_tiling::regroup() { for(int i=0; i gi(ginf[geometry].g, ginf[gArchimedean].g); @@ -727,15 +726,15 @@ struct hrmap_archimedean : hrmap { alt = (heptagon*) s; } - DEBB(DF_GEOM, ("look for: ", alt, " / ", kz(T * C0))); + if(debug_geometry) println(hlog, "look for: ", alt, " / ", kz(T * C0)); for(auto& p2: altmap[alt]) if(same_point_may_warn(p2.second * tile_center(), T * tile_center())) { - DEBB(DF_GEOM, ("cell found: ", p2.first)); + if(debug_geometry) println(hlog, "cell found: ", p2.first); for(int d2=0; d2degree(); d2++) { heptspin hs(p2.first, d2); auto& t2 = current.get_triangle(p2.first, d2); transmatrix T1 = T * spin(M_PI + t2.first); - DEBB(DF_GEOM, ("compare: ", kz(T1 * lxpush0(1)), ":: ", kz(p2.second * lxpush0(1)))); + if(debug_geometry) println(hlog, "compare: ", kz(T1 * lxpush0(1)), ":: ", kz(p2.second * lxpush0(1))); if(same_point_may_warn(T1 * lxpush0(1), p2.second * lxpush0(1))) { // T1 = p2.second @@ -754,7 +753,7 @@ struct hrmap_archimedean : hrmap { return h->move(d); } } - DEBB(DF_GEOM, ("but rotation not found")); + if(debug_geometry) println(hlog, "but rotation not found"); } auto& t2 = current.get_triangle(current.get_adj(hi)); @@ -904,10 +903,12 @@ struct hrmap_archimedean : hrmap { EX hrmap *new_map() { return new hrmap_archimedean; } +EX debugflag debug_archimedean_map = {"archimedean_map"}; + heptagon *build_child(heptspin p, pair adj) { indenter ind; auto h = buildHeptagon1(tailored_alloc (isize(current.adjacent[adj.first])), p.at, p.spin, hstate(1), 0); - DEBB(DF_GEOM, ("NEW ", p, " ~ ", heptspin(h, 0))); + if(debug_archimedean_map) println(hlog, "NEW ", p, " ~ ", heptspin(h, 0)); id_of(h) = adj.first; parent_index_of(h) = adj.second; int nei = neighbors_of(h); @@ -951,23 +952,21 @@ void connect_digons_too(heptspin h1, heptspin h2) { // no need to specify archimedean_gmatrix and altmap hnew->c.connect(1, h2); h1--, h2++; - DEBB(DF_GEOM, (hr::format("OL2 %p.%d ~ %p.%d\n", hr::voidp(h1.at), h1.spin, hr::voidp(h2.at), h2.spin))); + if(debug_archimedean_map) println(hlog, hr::format("OL2 %p.%d ~ %p.%d\n", hr::voidp(h1.at), h1.spin, hr::voidp(h2.at), h2.spin)); h1.at->c.connect(h1.spin, h2); } } void connectHeptagons(heptspin hi, heptspin hs) { - DEBB(DF_GEOM, ("OLD ", hi, " ~ ", hs)); + if(debug_archimedean_map) println(hlog, "OLD ", hi, " ~ ", hs); if(hi.at->move(hi.spin) == hs.at && hi.at->c.spin(hi.spin) == hs.spin) { - DEBB(DF_GEOM, (hr::format("WARNING: already connected\n"))); + if(debug_map_warnings) println(hlog, "WARNING: already connected"); return; } if(hi.peek()) { - DEBB(DF_GEOM, (hr::format("ERROR: already connected left\n"))); throw hr_archimedean_error("Archimedean error: already connected left"); } if(hs.peek()) { - DEBB(DF_GEOM, (hr::format("ERROR: already connected right\n"))); throw hr_archimedean_error("Archimedean error: already connected right"); } hi.at->c.connect(hi.spin, hs); @@ -1095,7 +1094,7 @@ void archimedean_tiling::parse() { EX bool load_symbol(const string& s, bool switch_geom) { archimedean_tiling at; at.parse(s); if(at.errors) { - DEBB(DF_ERROR | DF_GEOM, ("error: ", at.errormsg)); + if(debug_errors) println(hlog, "error: ", at.errormsg); return false; } if(!switch_geom && geometry != gArchimedean) return true; @@ -1392,7 +1391,7 @@ EX void show() { archimedean_tiling tested; tested.parse(s); if(tested.errors) { - DEBB(DF_GEOM | DF_WARN, ("WARNING: ", tested.errors, " errors on ", s, " '", tested.errormsg, "'")); + if(debug_warnings) println(hlog, "WARNING: ", tested.errors, " errors on ", s, " '", tested.errormsg, "'"); } else { tested.coloring = col; diff --git a/asonov.cpp b/asonov.cpp index 91e38d43..9d65899a 100644 --- a/asonov.cpp +++ b/asonov.cpp @@ -88,7 +88,7 @@ EX void prepare() { lambda[0] = b + sqrt(b*b-1); lambda[1] = b - sqrt(b*b-1); - DEBB(DF_GEOM, ("b = ", b, " lambda = ", lambda)); + if(debug_geometry) println(hlog, "asonov: b = ", b, " lambda = ", lambda); transmatrix eigen = Id; @@ -103,7 +103,7 @@ EX void prepare() { ty = point3(ieigen[0][1], ieigen[1][1], 0) * vid.binary_width; tz = -point3(0, 0, log(lambda[0])); - DEBB(DF_GEOM, ("tx = ", tx, " ty = ", ty, " tz = ", tz)); + if(debug_geometry) println(hlog, "tx = ", tx, " ty = ", ty, " tz = ", tz); straighten = inverse(build_matrix(asonov::tx/2, asonov::ty/2, asonov::tz/2, C0)); } diff --git a/attack.cpp b/attack.cpp index a9c447a5..25201180 100644 --- a/attack.cpp +++ b/attack.cpp @@ -476,7 +476,7 @@ EX bignum ivy_total() { EX void killMonster(cell *c, eMonster who, flagtype deathflags IS(0)) { eMonster m = c->monst; - DEBBI(DF_TURN, ("killmonster ", dnameof(m))); + DEBBI(debug_turn, ("killmonster ", dnameof(m))); if(!m) return; diff --git a/basegraph.cpp b/basegraph.cpp index 587c1d22..9b2815ee 100644 --- a/basegraph.cpp +++ b/basegraph.cpp @@ -251,6 +251,8 @@ EX vector> font_names = { EX int last_font_id = 0; EX int font_id = 0; +EX debugflag debug_init_font = {"init_font", true}; + #ifdef FONTCONFIG TTF_Font* findfont(int siz) { @@ -289,7 +291,7 @@ TTF_Font* findfont(int siz) { FcPatternDestroy(pat); FcFini(); cfont->use_fontconfig = false; - if(debugflags & DF_INIT) println(hlog, "fontpath is: ", cfont->filename); + if(debug_init_font) println(hlog, "fontpath is: ", cfont->filename); return TTF_OpenFont(cfont->filename.c_str(), siz); } #endif @@ -410,7 +412,7 @@ EX bool model_needs_depth() { } EX void setGLProjection(color_t col IS(backcolor)) { - DEBBI(DF_GRAPH, ("setGLProjection")); + DEBBI(debug_graph, ("setGLProjection")); GLERR("pre_setGLProjection"); glClearColor(part(col, 2) / 255.0, part(col, 1) / 255.0, part(col, 0) / 255.0, 1); @@ -568,7 +570,7 @@ void sdltogl(SDL_Surface *txt, glfont_t& f, int ch) { EX void init_glfont(int size) { if(cfont->glfont[size]) return; - DEBBI(DF_GRAPH, ("init GL font: ", size)); + DEBBI(debug_init_font, ("init GL font: ", size)); #if !CAP_TABFONT loadfont(size); @@ -755,7 +757,7 @@ bool gl_print(int x, int y, int shift, int size, const char *s, color_t color, i EX purehookset hooks_resetGL; EX void resetGL() { - DEBBI(DF_INIT | DF_GRAPH, ("reset GL")) + DEBBI(debug_init_graph, ("reset GL")) callhooks(hooks_resetGL); #if CAP_GLFONT for(auto& cf: fontdatas) @@ -1015,9 +1017,11 @@ void addMessageToLog(msginfo& m, vector& log) { EX void clearMessages() { msgs.clear(); } +EX debugflag debug_messages = {"messages", true}; + EX void addMessage(string s, char spamtype) { LATE( addMessage(s, spamtype); ) - DEBB(DF_MSG, ("addMessage: ", s)); + DEBB(debug_messages, ("addMessage: ", s)); msginfo m; m.msg = s; m.spamtype = spamtype; m.flashout = false; m.stamp = ticks; @@ -1097,7 +1101,7 @@ EX void drawmessage(const string& s, int& y, color_t col) { } EX void drawmessages() { - DEBBI(DF_GRAPH, ("draw messages")); + DEBBI(debug_graph, ("draw messages")); int i = 0; int t = ticks; for(int j=0; j>= 1; } diff --git a/cell.cpp b/cell.cpp index 61431550..116e914f 100644 --- a/cell.cpp +++ b/cell.cpp @@ -10,6 +10,8 @@ #include "hyper.h" namespace hr { +EX debugflag debug_map_warnings = {"map_warnings", true}; + #if HDR extern int default_levs(); @@ -570,9 +572,11 @@ EX cell *fractal_rep(cell *c) { } } +EX debugflag debug_init_cells = {"init_cells", true}; + /** create a map in the current geometry */ EX void initcells() { - DEBB(DF_INIT, ("initcells")); + indenter_finish dif(debug_init_cells, "initcells"); if(embedded_plane) { geom3::swap_direction = -1; @@ -627,19 +631,25 @@ EX void initcells() { // origin->emeraldval = } +EX debugflag debug_memory_cell = {"memory_cell"}; + EX void clearcell(cell *c) { if(!c) return; - DEBB(DF_MEMORY, (hr::format("c%d %p\n", c->type, hr::voidp(c)))); + indenter_finish(debug_memory_cell, hr::format("memory_cell %d %p\n", c->type, hr::voidp(c))); for(int t=0; ttype; t++) if(c->move(t)) { - DEBB(DF_MEMORY, (hr::format("mov %p [%p] S%d\n", hr::voidp(c->move(t)), hr::voidp(c->move(t)->move(c->c.spin(t))), c->c.spin(t)))); + if(debug_memory_cell) + println(hlog, hr::format("mov %p [%p] S%d\n", hr::voidp(c->move(t)), hr::voidp(c->move(t)->move(c->c.spin(t))), c->c.spin(t))); if(c->move(t)->move(c->c.spin(t)) != NULL && c->move(t)->move(c->c.spin(t)) != c) { - DEBB(DF_MEMORY | DF_ERROR, (hr::format("cell error: type = %d %d -> %d\n", c->type, t, c->c.spin(t)))); - if(worst_precision_error < 1e-3) exit(1); + if(debug_errors || debug_memory_cell) + println(hlog, hr::format("cell error: type = %d %d -> %d\n", c->type, t, c->c.spin(t))); + if(worst_precision_error < 1e-3) + throw hr_exception("clearcell"); } c->move(t)->move(c->c.spin(t)) = NULL; } - DEBB(DF_MEMORY, (hr::format("DEL %p\n", hr::voidp(c)))); + if(debug_memory_cell) + println(hlog, hr::format("DEL %p\n", hr::voidp(c))); gp::delete_mapped(c); destroy_cell(c); } @@ -692,11 +702,12 @@ EX void clearfrom(heptagon *at) { at = q.front(); // if(q.size() > maxq) maxq = q.size(); q.pop(); - DEBB(DF_MEMORY, ("from %p", at)); + if(debug_memory_cell) println(hlog, "from %p", at); if(!at->c7 && !ls::voronoi_structure()) { heptagon *h = dynamic_cast ((cdata_or_heptagon*) at->cdata); if(h) { - if(h->alt != at) { DEBB(DF_MEMORY | DF_ERROR, ("alt error :: h->alt = ", h->alt, " expected ", at)); } + if(h->alt != at && (debug_memory_cell || debug_errors)) + println(hlog, "alt error :: h->alt = ", h->alt, " expected ", at); cell *c = h->c7; subcell(c, destroycellcontents); h->alt = NULL; @@ -710,12 +721,10 @@ EX void clearfrom(heptagon *at) { q.push(at->move(i)); unlink_cdata(at->move(i)); at->move(i)->alt = &deletion_marker; - DEBB(DF_MEMORY, ("!mov ", at->move(i), " [", at->move(i)->move(at->c.spin(i)), "]")); + if(debug_memory_cell) println(hlog, "!mov ", at->move(i), " [", at->move(i)->move(at->c.spin(i)), "]"); if(at->move(i)->move(at->c.spin(i)) != NULL && - at->move(i)->move(at->c.spin(i)) != at) { - DEBB(DF_MEMORY | DF_ERROR, ("hept error")); - exit(1); - } + at->move(i)->move(at->c.spin(i)) != at) + throw hr_exception("hept error"); at->move(i)->move(at->c.spin(i)) = NULL; at->move(i) = NULL; } @@ -733,7 +742,7 @@ EX void verifycell(cell *c) { if(BITRUNCATED && c == c->master->c7) verifycell(c2); if(c2->move(c->c.spin(i)) && c2->move(c->c.spin(i)) != c) { printf("cell error %p:%d [%d] %p:%d [%d]\n", hr::voidp(c), i, c->type, hr::voidp(c2), c->c.spin(i), c2->type); - exit(1); + throw hr_exception("error during verifycell"); } } } @@ -1759,7 +1768,7 @@ EX int auto_compute_range(cell *c) { int z = isize(cl.dists); int d = cl.dists.back(); while(cl.dists[z-1] == d) z--; - if(cgflags & DF_GEOM) { + if(debug_geometry) { println(hlog, "last distance = ", cl.dists.back()); println(hlog, "ball size = ", isize(cl.dists)); println(hlog, "previous ball size = ", z); diff --git a/commandline.cpp b/commandline.cpp index a90792e8..a7323550 100644 --- a/commandline.cpp +++ b/commandline.cpp @@ -187,42 +187,6 @@ int arg::readCommon() { PHASE(1); offlineMode = true; } - else if(argis("-no-stamp")) { - debugflags &=~ DF_TIME; - } - else if(argis("-debf")) { - shift(); - string s = args(); - for(char c: s) { - for(int i=0; i= '0' && c <= '9') { - debugflags &= DF_TIME; - if(c >= '1') - debugflags |= DF_INIT | DF_WARN | DF_MSG | DF_ERROR; - if(c >= '2') - debugflags |= DF_GEOM | DF_GP | DF_LOG | DF_FIELD | DF_POLY; - if(c >= '3') - debugflags |= DF_TURN | DF_STEAM; - if(c >= '4') - debugflags |= DF_GRAPH | DF_MEMORY; - } - else if(c == '+') { - if(debugfile) fclose(debugfile); - shift(); - println(hlog, "writing to ", argcs()); - debugfile = fopen(argcs(), "at"); - } - else if(c == '@') { - if(debugfile) fclose(debugfile); - shift(); - println(hlog, "writing to ", argcs()); - debugfile = fopen(argcs(), "wt"); - } - } - } else if(argis("-run")) { PHASE(3); start_game(); diff --git a/complex.cpp b/complex.cpp index 3de3bb76..77073e7e 100644 --- a/complex.cpp +++ b/complex.cpp @@ -3594,9 +3594,9 @@ auto ccm = addHook(hooks_clearmemory, 0, [] () { eliminate_if(heat::offscreen_fire, is_cell_removed); eliminate_if(princess::infos, [] (princess::info*& i) { if(is_cell_removed(i->princess) || is_cell_removed(i->prison)) { - DEBB(DF_MEMORY, ("removing a princess")) + DEBB(debug_memory, ("removing a princess")) if(i->princess && !is_cell_removed(i->princess)) { - DEBB(DF_MEMORY, ("faking a princess")) + DEBB(debug_memory, ("faking a princess")) princess::newFakeInfo(i->princess); } delete i; diff --git a/config.cpp b/config.cpp index f6c34b1b..c7a66103 100644 --- a/config.cpp +++ b/config.cpp @@ -1082,6 +1082,8 @@ EX void font_reaction() { EX void initConfig() { + DEBBI(debug_init_config, ("initconfig")); + // basic config param_i(vid.flashtime, "flashtime", 8); @@ -1939,8 +1941,11 @@ EX void resetConfig() { #endif #if CAP_CONFIG + +EX debugflag debug_init_config = {"init_config", true}; + EX void saveConfig() { - DEBB(DF_INIT, ("save config\n")); + indenter_finish(debug_init_config, "saveConfig"); FILE *f = fopen(conffile, "wt"); if(!f) { addMessage(s0 + "Could not open the config file: " + conffile); @@ -2012,7 +2017,7 @@ EX void loadNewConfig(FILE *f) { EX void loadConfig() { - DEBB(DF_INIT, ("load config")); + indenter_finish(debug_init_config, "loadConfig"); vid.xres = 9999; vid.yres = 9999; vid.framelimit = 999; FILE *f = fopen(conffile, "rt"); if(f) { @@ -2029,7 +2034,8 @@ EX void loadConfig() { } fclose(f); - DEBB(DF_INIT, ("Loaded configuration: %s\n", conffile)); + if(debug_init_config) + println(hlog, "Loaded configuration: ", conffile); } geom3::apply_always3(); diff --git a/control.cpp b/control.cpp index 707b0af3..65e25a71 100644 --- a/control.cpp +++ b/control.cpp @@ -146,7 +146,7 @@ EX int keybd_subdir = 1; EX bool keybd_subdir_enabled = 0; EX void movepckeydir(int d) { - DEBB(DF_GRAPH, ("movepckeydir\n")); + if(debug_graph) println(hlog, "movepckeydir(", d, ")"); // EUCLIDEAN if(protect_memory()) return; @@ -251,8 +251,12 @@ EX void initJoysticks_async() { #endif } +EX debugflag debug_init_joy = {"init_joy"}; +EX debugflag debug_joy_error = {"joy_error"}; +EX debugflag debug_joy = {"joy"}; + EX void countJoysticks() { - DEBB(DF_INIT, ("opening joysticks")); + indenter_finish(debug_init_joy, "countJoysticks"); #if SDLVER <= 2 numsticks = SDL_NumJoysticks(); #else @@ -272,12 +276,11 @@ EX void countJoysticks() { EX void initJoysticks() { - DEBBI(DF_INIT, ("init joystick")); + indenter_finish(debug_init_joy, "initJoysticks"); - DEBB(DF_INIT, ("init joystick subsystem")); if (SDL_error_in(SDL_InitSubSystem(SDL_INIT_JOYSTICK))) { - printf("Failed to initialize joysticks.\n"); + if(debug_joy_error) println(hlog, "Failed to initialize joysticks."); numsticks = 0; return; } @@ -287,7 +290,7 @@ EX void initJoysticks() { } EX void closeJoysticks() { - DEBB(DF_INIT, ("close joysticks")); + indenter_finish(debug_init_joy, "closeJoysticks"); for(int i=0; i buggycells; +map *all_debugflags; + +void add_debugflag(const string& s, debugflag *d) { + if(!all_debugflags) all_debugflags = new map; + if(all_debugflags->count(s)) printf("warning: duplicate debugflag: %s\n", s.c_str()); + (*all_debugflags)[s] = d; + } + +EX debugflag debug_errors = {"error", true}; +EX debugflag debug_warnings = {"warning", true}; +EX debugflag debug_memory = {"memory"}; +EX debugflag debug_init = {"init", true}; + #if HDR template void limitgen(T... args) { @@ -873,6 +886,35 @@ int read_cheat_args() { cheat(); gen_wandering = false; } + else if(argis("-log")) { + shift(); auto s = args(); + if(debug_init) println(hlog, "logging: '", s, "'"); + for(auto& w: *all_debugflags) if(w.first.find(s) != string::npos) w.second->enabled = true; + } + else if(argis("-log-all")) { + if(debug_init) println(hlog, "logging all"); + for(auto& w: *all_debugflags) w.second->enabled = true; + } + else if(argis("-no-log")) { + shift(); auto s = args(); + if(debug_init) println(hlog, "not logging: '", s, "'"); + for(auto& w: *all_debugflags) if(w.first.find(s) != string::npos) w.second->enabled = false; + } + else if(argis("-log-none")) { + for(auto& w: *all_debugflags) w.second->enabled = false; + } + else if(argis("-log-to")) { + shift(); + if(debug_init) println(hlog, "writing to ", argcs()); + if(debugfile) fclose(debugfile); + debugfile = fopen(argcs(), "wt"); + } + else if(argis("-log-append")) { + shift(); + if(debug_init) println(hlog, "writing to ", argcs()); + if(debugfile) fclose(debugfile); + debugfile = fopen(argcs(), "at"); + } else if(argis("-canvasfloor")) { shift(); canvasfloor = argi(); for(int i=0; i line_vertices; #endif EX void glflush() { - DEBBI(DF_GRAPH, ("glflush")); + DEBBI(debug_graph, ("glflush")); #if MINIMIZE_GL_CALLS if(isize(triangle_vertices)) { // printf("%3d | %d shapes, %d/%d vertices\n", lprio, shapes_merged, isize(triangle_vertices), isize(line_vertices)); @@ -1817,10 +1817,12 @@ bool broken_projection(dqi_poly& p0) { return false; } +EX debugflag debug_vertex = {"vertex"}; + void dqi_poly::draw() { if(flags & POLY_DEBUG) debug_this(); - if(debugflags & DF_VERTEX) { + if(debug_vertex) { println(hlog, int(prio), ": V=", V, " o=", offset, " c=", cnt, " ot=", offset_texture, " ol=", outline, " lw=", linewidth, " f=", (color_t) flags, " i=", intester, " c=", cache, " ti=", (cell*) tinf); for(int i=0; i dv (pmodel, mdHyperboloidFlat); for(auto& ptd: ptds) @@ -2457,7 +2459,7 @@ EX void set_vr_sphere() { EX int hemi_side = 0; EX void draw_main() { - DEBBI(DF_GRAPH, ("draw_main")); + DEBBI(debug_graph, ("draw_main")); if(pconf.back_and_front == 1 && vid.consider_shader_projection) { dynamicval pa(pconf.back_and_front); @@ -2546,20 +2548,20 @@ EX void draw_main() { glflush(); } else { - DEBB(DF_GRAPH, ("draw_main1")); + DEBB(debug_graph, ("draw_main1")); if(ray::in_use && !ray::comparison_mode) { ray::cast(); reset_projection(); } - DEBB(DF_GRAPH, ("outcircle")); + DEBB(debug_graph, ("outcircle")); for(auto& ptd: ptds) if(ptd->prio == PPR::OUTCIRCLE) ptd->draw(); if(two_sided_model()) draw_backside(); for(auto& ptd: ptds) if(ptd->prio != PPR::OUTCIRCLE) { - DEBBI(DF_VERTEX, ("prio: ", int(ptd->prio), " color ", ptd->color)); + DEBBI(debug_vertex, ("prio: ", int(ptd->prio), " color ", ptd->color)); dynamicval ss(spherespecial, among(ptd->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE) ? 0 : spherespecial); ptd->draw(); } @@ -2582,7 +2584,7 @@ EX void draw_main() { EX void drawqueue() { - DEBBI(DF_GRAPH, ("drawqueue")); + DEBBI(debug_graph, ("drawqueue")); #if CAP_WRL if(wrl::in) { wrl::render(); return; } @@ -2611,7 +2613,7 @@ EX void drawqueue() { sort_drawqueue(); - DEBB(DF_GRAPH, ("sort walls")); + DEBB(debug_graph, ("sort walls")); if(GDIM == 2) for(PPR p: all_side_prios) { diff --git a/environment.cpp b/environment.cpp index d2142896..59802837 100644 --- a/environment.cpp +++ b/environment.cpp @@ -833,11 +833,11 @@ EX void monstersTurn() { reset_spill(); checkSwitch(); mirror::breakAll(); - DEBB(DF_TURN, ("bfs")); + DEBB(debug_turn, ("bfs")); bfs(); - DEBB(DF_TURN, ("charge")); + DEBB(debug_turn, ("charge")); if(elec::havecharge) elec::act(); - DEBB(DF_TURN, ("mmo")); + DEBB(debug_turn, ("mmo")); int phase2 = (1 & items[itOrbSpeed]); if(!phase2) movemonsters(); @@ -858,11 +858,11 @@ EX void monstersTurn() { refreshFriend(dcal[i]); } } - DEBB(DF_TURN, ("rop")); + DEBB(debug_turn, ("rop")); if(!dual::state) reduceOrbPowers(); int phase1 = (1 & items[itOrbSpeed]); if(dual::state && items[itOrbSpeed]) phase1 = !phase1; - DEBB(DF_TURN, ("lc")); + DEBB(debug_turn, ("lc")); if(!phase1) livecaves(); if(!phase1) ca::simulate(); if(!phase1) heat::processfires(); @@ -885,7 +885,7 @@ EX void monstersTurn() { crush_now = std::move(crush_next); crush_next.clear(); - DEBB(DF_TURN, ("heat")); + DEBB(debug_turn, ("heat")); heat::processheat(); // if(elec::havecharge) elec::drawcharges(); @@ -899,7 +899,7 @@ EX void monstersTurn() { for(cell *pc: player_positions()) checkFreedom(pc); - DEBB(DF_TURN, ("check")); + DEBB(debug_turn, ("check")); checkmove(); if(canmove) elec::checklightningfast(); diff --git a/fieldpattern.cpp b/fieldpattern.cpp index 861f9790..c5903788 100644 --- a/fieldpattern.cpp +++ b/fieldpattern.cpp @@ -75,6 +75,8 @@ EX int btspin(int id, int d) { return groupspin(id, d, S7); } +EX debugflag debug_field = {"geometry_field"}; + #if HDR static constexpr int ERR = -99; @@ -529,7 +531,8 @@ bool fpattern::generate_all3() { if(isize(matrices) >= limitv) { println(hlog, "limitv exceeded"); return false; } } hashv = compute_hash(); - DEBB(DF_FIELD, ("all = ", isize(matrices), "/", local_group, " = ", isize(matrices) / local_group, " hash = ", hashv, " count = ", ++hash_found[hashv])); + if(debug_field) + println(hlog, "all = ", isize(matrices), "/", local_group, " = ", isize(matrices) / local_group, " hash = ", hashv, " count = ", ++hash_found[hashv]); if(use_quotient_fp) generate_quotientgroup(); @@ -604,9 +607,11 @@ EX purehookset hooks_solve3; int fpattern::solve3() { + indenter_finish(debug_field, "fpattern::solve3"); + reg3::generate_fulls(); - DEBB(DF_FIELD, ("generating isometries for ", Field)); + if(debug_field) println(hlog, "generating isometries for ", Field); auto iso3 = generate_isometries(); auto iso4 = generate_isometries3(); @@ -625,7 +630,8 @@ int fpattern::solve3() { if(check_order(M, 2)) possible_P.push_back(M); - DEBB(DF_FIELD, ("field = ", Field, " #P = ", isize(possible_P), " #X = ", isize(possible_X), " #R = ", isize(possible_R), " r_order = ", cgi.r_order, " xp_order = ", cgi.xp_order)); + if(debug_field) + println(hlog, "field = ", Field, " #P = ", isize(possible_P), " #X = ", isize(possible_X), " #R = ", isize(possible_R), " r_order = ", cgi.r_order, " xp_order = ", cgi.xp_order); for(auto& xX: possible_X) for(auto& xP: possible_P) if(check_order(mmul(xP, xX), cgi.xp_order)) @@ -653,7 +659,8 @@ int fpattern::solve3() { ok: - DEBB(DF_FIELD, ("cmb = ", cmb, " for field = ", Field)); + if(debug_field) + println(hlog, "cmb = ", cmb, " for field = ", Field); return cmb; } @@ -802,8 +809,9 @@ vector fpattern::find_triplets() { return transcript; }; - - DEBB(DF_FIELD, ("looking for alternate solutions")); + + if(debug_field) println(hlog, "looking for alternate solutions"); + auto orig_transcript = compute_transcript(1, S7); set> transcripts_seen; @@ -824,7 +832,7 @@ vector fpattern::find_triplets() { cc.push_back(i); } - DEBB(DF_FIELD, ("conjugacy_classes = ", cc)); + if(debug_field) println(hlog, "conjugacy_classes = ", cc); vector tinf; triplet_info ti; @@ -832,7 +840,7 @@ vector fpattern::find_triplets() { tinf.push_back(ti); for(int i: conjugacy_classes) if(gorder(i) == S7) { - DEBB(DF_FIELD, ("checking i=", i)); + if(debug_field) println(hlog, "checking i=", i); for(int j=1; j fpattern::find_triplets() { } } - DEBB(DF_FIELD, ("solutions found = ", isize(transcripts_seen))); + if(debug_field) println(hlog, "solutions found = ", isize(transcripts_seen)); return tinf; } @@ -879,10 +887,10 @@ void fpattern::build() { connections.push_back(matcode[PM]); } - DEBB(DF_FIELD, ("Computing inverses...\n")); + if(debug_field) println(hlog, "Computing inverses...\n"); int N = isize(matrices); - DEBB(DF_FIELD, ("Number of heptagons: %d\n", N)); + if(debug_field) println(hlog, "Number of heptagons: %d\n", N); if(WDIM == 3) return; @@ -911,7 +919,7 @@ void fpattern::build() { if(i%S7 == S7-1) printf("\n"); } - DEBB(DF_FIELD, ("triplet_id = ", triplet_id, " N = ", N)); + if(debug_field) println(hlog, "triplet_id = ", triplet_id, " N = ", N); if(triplet_id) { auto triplets = find_triplets(); if(triplet_id >= 0 && triplet_id < isize(triplets)) { @@ -920,12 +928,12 @@ void fpattern::build() { P = matrices[ti.j]; dynamicval t(triplet_id, 0); build(); - DEBB(DF_FIELD, ("triplet built successfully")); + if(debug_field) println(hlog, "triplet built successfully"); return; } } - DEBB(DF_FIELD, ("Built.\n")); + if(debug_field) println(hlog, "Built.\n"); } int fpattern::getdist(pair a, vector& dists) { @@ -991,7 +999,7 @@ void fpattern::analyze() { } } - DEBB(DF_FIELD, ("variation = %d\n", int(variation))); + if(debug_field) println(hlog, "variation = %d\n", int(variation)); int N = isize(connections); markers.resize(N); @@ -1039,7 +1047,7 @@ void fpattern::analyze() { if(disthep[connections[i]] < disthep[i] && disthep[connections[btspin(i,u)]] < disthep[i]) circrad = disthep[i]; - DEBB(DF_FIELD, ("maxdist = %d otherpole = %d circrad = %d\n", maxdist, otherpole, circrad)); + if(debug_field) println(hlog, "maxdist = %d otherpole = %d circrad = %d\n", maxdist, otherpole, circrad); matrix PRRR = strtomatrix("PRRR"); matrix PRRPRRRRR = strtomatrix("PRRPRRRRR"); @@ -1051,7 +1059,7 @@ void fpattern::analyze() { wallorder = order(Wall); wallid = matcode[Wall]; - DEBB(DF_FIELD, ("wall order = %d\n", wallorder)); + if(debug_field) println(hlog, "wall order = %d\n", wallorder); #define SETDIST(X, d, it) {int c = matcode[X]; indist[d].push_back(c); if(it == itNone) ; else if(markers[c] && markers[c] != it) markers[c] = itBuggy; else markers[c] = it; } @@ -1067,8 +1075,7 @@ void fpattern::analyze() { } int walldist = dijkstra(distwall, indist); - DEBB(DF_FIELD, ("wall dist = %d\n", walldist)); - + if(debug_field) println(hlog, "wall dist = %d\n", walldist); W = strtomatrix("RRRRPR"); for(int j=0; j osym && rots % osym == 0) { int rep = rots / osym; @@ -260,7 +261,8 @@ void geometry_information::bshape2(hpcshape& sh, PPR prio, int shapeid, matrixli nh = m.second[r] * z, mapped++; } } - if(mapped == 0 && (debugflags & DF_GEOM)) printf("warning: not mapped (shapeid %d)\n", shapeid); + if(mapped == 0 && debug_geometry) + println(hlog, "warning: not mapped shapeid = ", shapeid); if(invalid) { apeirogonal = true; for(auto h: head) tail.push_back(h); @@ -395,7 +397,7 @@ void geometry_information::generate_floorshapes_for(int id, cell *c) { #if CAP_IRR else if(IRREGULAR) { - DEBBI(DF_POLY, ("generate_floorshapes: irregular")); + DEBBI(debug_poly, ("generate_floorshapes: irregular")); auto& vs = irr::cells[id]; siid = vs.is_pseudohept; @@ -444,7 +446,7 @@ void geometry_information::generate_floorshapes_for(int id, cell *c) { } #endif - DEBBI(DF_POLY, ("generate_floorshapes_for ", id)); + DEBBI(debug_poly, ("generate_floorshapes_for ", id)); for(auto pfsh: all_plain_floorshapes) { auto& fsh = *pfsh; @@ -1383,7 +1385,7 @@ void geometry_information::make_floor_textures_here() { EX void make_floor_textures() { if(noGUI || !vid.usingGL) return; - DEBBI(DF_POLY, ("make_floor_textures")); + DEBBI(debug_poly, ("make_floor_textures")); dynamicval geu(euc::eu, euc::eu); dynamicval g(geometry, gEuclidSquare); dynamicval gm(pmodel, mdDisk); diff --git a/geometry.cpp b/geometry.cpp index 0f7e84ed..663a0cda 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -8,6 +8,8 @@ #include "hyper.h" namespace hr { +EX debugflag debug_geometry = {"geometry"}; + #if HDR struct usershapelayer { vector list; @@ -646,7 +648,7 @@ void geometry_information::generate_faces() { void geometry_information::prepare_basics() { - DEBBI(DF_INIT | DF_POLY | DF_GEOM, ("prepare_basics")); + indenter_finish dif(debug_geometry, "prepare_basics"); hexshift = 0; @@ -790,9 +792,9 @@ void geometry_information::prepare_basics() { if(BITRUNCATED) plevel_twisted = (M_PI - 2 * alpha6 - alpha7) * fake::around * 2; } - DEBB(DF_GEOM | DF_POLY, - (hr::format("S7=%d S6=%d hexf = " LDF" hcross = " LDF" tessf = " LDF" hexshift = " LDF " hexhex = " LDF " hexv = " LDF "\n", S7, S6, hexf, hcrossf, tessf, hexshift, - hexhexdist, hexvdist))); + if(debug_geometry) println(hlog, + hr::format("S7=%d S6=%d hexf = " LDF" hcross = " LDF" tessf = " LDF" hexshift = " LDF " hexhex = " LDF " hexv = " LDF "\n", S7, S6, hexf, hcrossf, tessf, hexshift, + hexhexdist, hexvdist)); hybrid_finish: @@ -831,7 +833,6 @@ void geometry_information::prepare_basics() { geometry = gFake; ld our = xpush0(hcrossf)[0] / xpush0(hcrossf)[GDIM]; fake::scale = our / orig; - // if(debugflags & DF_GEOM) } if(fake::in() && WDIM == 3) { @@ -918,7 +919,8 @@ void geometry_information::prepare_basics() { if(inv) psl_steps = 2 * S3; if(single_step < 0) single_step = -single_step; } - DEBB(DF_GEOM | DF_POLY, ("steps = ", psl_steps, " / ", single_step)); + + if(debug_geometry) println(hlog, "steps = ", psl_steps, " / ", single_step); plevel = M_PI * single_step / psl_steps; if(hybrid::underlying == gFake) { auto s3 = fake::around; @@ -1067,7 +1069,7 @@ EX namespace geom3 { void geometry_information::prepare_compute3() { using namespace geom3; - DEBBI(DF_INIT | DF_POLY | DF_GEOM, ("geom3::compute")); + indenter_finish dig(debug_geometry, "prepare_compute3"); // tanh(depth) / tanh(camera) == pconf.alpha if(GDIM == 3 || flipped || changing_embedded_settings); @@ -1462,7 +1464,8 @@ EX void check_cgi() { for(auto& t: cgis) if(!t.second.use_count) timestamps.emplace_back(-t.second.timestamp, t.first); sort(timestamps.begin(), timestamps.end()); while(isize(timestamps) > limit && timestamps.back().first != -ntimestamp) { - DEBB(DF_GEOM, ("erasing geometry ", timestamps.back().second)); + if(debug_geometry) + println(hlog, "erasing geometry ", timestamps.back().second); cgis.erase(timestamps.back().second); timestamps.pop_back(); } diff --git a/goldberg.cpp b/goldberg.cpp index 84881556..ffebd1a3 100644 --- a/goldberg.cpp +++ b/goldberg.cpp @@ -17,6 +17,8 @@ extern hrmap *currentmap; EX namespace gp { + EX debugflag debug_gp = {"graph_gp"}; + #if HDR struct loc : pair { loc() {} @@ -214,7 +216,7 @@ EX namespace gp { if(peek(wcw)) { auto wcw1 = get_localwalk(wc1, dir1); if(wcw + wstep != wcw1) { - DEBB(DF_GP, (at1, " : ", (wcw+wstep), " / ", wcw1, " (pull error from ", at, " :: ", wcw, ")") ); + DEBB(debug_gp, (at1, " : ", (wcw+wstep), " / ", wcw1, " (pull error from ", at, " :: ", wcw, ")") ); exit(1); } if(do_adjm) wc1.adjm = wc.adjm * get_adj(wcw.at, wcw.spin); @@ -223,7 +225,7 @@ EX namespace gp { } if(peek(wcw)) { set_localwalk(wc1, dir1, wcw + wstep); - DEBB(DF_GP, (at1, " :", wcw+wstep, " (pulled from ", at, " :: ", wcw, ")")); + DEBB(debug_gp, (at1, " :", wcw+wstep, " (pulled from ", at, " :: ", wcw, ")")); if(do_adjm) wc1.adjm = wc.adjm * get_adj(wcw.at, wcw.spin); return true; } @@ -236,12 +238,12 @@ EX namespace gp { auto& wc = get_mapping(at); auto wcw = get_localwalk(wc, dir); auto& wc1 = get_mapping(at + eudir(dir)); - DEBB0(DF_GP, (hr::format(" md:%02d s:%d", wc.mindir, wc.cw.spin)); ) - DEBB0(DF_GP, (" connection ", at, "/", dir, " ", wc.cw+dir, "=", wcw, " ~ ", at+eudir(dir), "/", dir1, " "); ) + DEBB0(debug_gp, (hr::format(" md:%02d s:%d", wc.mindir, wc.cw.spin)); ) + DEBB0(debug_gp, (" connection ", at, "/", dir, " ", wc.cw+dir, "=", wcw, " ~ ", at+eudir(dir), "/", dir1, " "); ) if(!wc1.cw.at) { wc1.start = wc.start; if(peek(wcw)) { - DEBB0(DF_GP, (" (pulled) "); ) + DEBB0(debug_gp, (" (pulled) "); ) set_localwalk(wc1, dir1, wcw + wstep); if(do_adjm) wc1.adjm = wc.adjm * get_adj(wcw.at, wcw.spin); } @@ -251,27 +253,25 @@ EX namespace gp { set_localwalk(wc1, dir1, wcw + wstep); if(do_adjm) wc1.adjm = wc.adjm; spawn++; - DEBB0(DF_GP, (" (created) "); ) + DEBB0(debug_gp, (" (created) "); ) } } - DEBB0(DF_GP, (wc1.cw+dir1, " ")); + DEBB0(debug_gp, (wc1.cw+dir1, " ")); auto wcw1 = get_localwalk(wc1, dir1); if(peek(wcw)) { if(wcw+wstep != wcw1) { - DEBB(DF_GP, ("FAIL: ", wcw, " connected to ", wcw+wstep, " not to ", wcw1); exit(1); ) + DEBB(debug_gp, ("FAIL: ", wcw, " connected to ", wcw+wstep, " not to ", wcw1); exit(1); ) } else { - DEBB(DF_GP, ("(was there)")); + DEBB(debug_gp, ("(was there)")); } } else { - DEBB(DF_GP, ("ok")); + DEBB(debug_gp, ("ok")); peek(wcw) = wcw1.at; wcw.at->c.setspin(wcw.spin, wcw1.spin, wcw.mirrored != wcw1.mirrored); - if(wcw+wstep != wcw1) { - DEBB(DF_GP | DF_ERROR, ("assertion failed")); - exit(1); - } + if(wcw+wstep != wcw1) + throw hr_exception("assertion failed in gp::conn1"); } if(do_adjm) { get_adj(wcw.at, wcw.spin) = inverse(wc.adjm) * wc1.adjm; @@ -295,18 +295,18 @@ EX namespace gp { auto& ac0 = get_mapping(at); ac0.cw = cellwalker(hs.at->c7, hs.spin, hs.mirrored); ac0.start = at; - DEBB(DF_GP, (at, " : ", ac0.cw)); + DEBB(debug_gp, (at, " : ", ac0.cw)); return ac0; } EX void extend_map(cell *c, int d) { - DEBB(DF_GP, ("EXTEND ",c, " ", d)); + DEBB(debug_gp, ("EXTEND ",c, " ", d)); indenter ind(2); if(c->master->c7 != c) { auto c1 = c; auto d1 = d; while(c->master->c7 != c) { - DEBB(DF_GP, (c, " direction 0 corresponds to ", c->move(0), " direction ", c->c.spin(0)); ) + DEBB(debug_gp, (c, " direction 0 corresponds to ", c->move(0), " direction ", c->c.spin(0)); ) d = c->c.spin(0); c = c->move(0); } @@ -465,13 +465,13 @@ EX namespace gp { for(int i=0; ialpha = -atan2(next[1], next[0]) * 6 / S7; - DEBB(DF_GEOM | DF_POLY, ("scale = ", scale)); + DEBB(debug_geometry, ("scale = ", scale)); } } diff --git a/graph-player.cpp b/graph-player.cpp index 303ad76c..32ea8a9b 100644 --- a/graph-player.cpp +++ b/graph-player.cpp @@ -752,9 +752,11 @@ EX void draw_movement_arrows(cell *c, const transmatrix& V, int df) { if(keylist != "") queuestr(shiftless(V), keysize * mapfontscale / 100, keylist, col >> 8, 1); } +debugflag debug_movestar = {"graph_movestar"}; + EX void drawmovestar(double dx, double dy) { - DEBBI(DF_GRAPH, ("draw movestar")); + indenter_finish(debug_movestar, "drawmovestar"); if(viewdists) return; if(GDIM == 3) return; diff --git a/graph.cpp b/graph.cpp index 11a4b968..adeedb3d 100644 --- a/graph.cpp +++ b/graph.cpp @@ -289,8 +289,12 @@ void sumaura(int v) { vector auravertices; #endif +EX debugflag debug_graph = {"graph"}; + +EX debugflag debug_aura = {"graph_aura"}; + EX void drawaura() { - DEBBI(DF_GRAPH, ("draw aura")); + indenter_finish(debug_aura, "drawaura"); if(!haveaura()) return; if(vid.stereo_mode) return; double rad = current_display->radius; @@ -1359,11 +1363,13 @@ EX void center_multiplayer_map(const vector& hs) { } } +EX debugflag debug_map = {"graph_map"}; + EX void drawthemap() { + indenter_finish(debug_map, "drawthemap"); + check_cgi(); cgi.require_shapes(); - - DEBBI(DF_GRAPH, ("draw the map")); last_firelimit = firelimit; firelimit = 0; @@ -1546,9 +1552,11 @@ EX ld get_stereo_param() { return 0; } +EX debugflag debug_calcparam = {"graph_param"}; + EX void calcparam() { - DEBBI(DF_GRAPH, ("calc param")); + indenter_finish(debug_calcparam, "calcparam"); auto cd = current_display; cd->xtop = vid.xres * cd->xmin; @@ -1623,9 +1631,8 @@ EX function wrap_drawfullmap = drawfullmap; bool force_sphere_outline = false; EX void drawfullmap() { + indenter_finish(debug_map, "drawfullmap"); - DEBBI(DF_GRAPH, ("draw full map")); - check_cgi(); cgi.require_shapes(); @@ -1916,7 +1923,7 @@ EX color_t titlecolor; EX void drawscreen() { - DEBBI(DF_GRAPH, ("drawscreen")); + indenter_finish(debug_map, "drawscreen"); #if CAP_GL GLWRAP; #endif @@ -2025,7 +2032,7 @@ EX void drawscreen() { // SDL_UnlockSurface(s); glflush(); - DEBB(DF_GRAPH, ("swapbuffers")); + if(debug_map) println(hlog, "swapbuffers"); #if CAP_VR vrhr::submit(); @@ -2042,15 +2049,19 @@ EX void drawscreen() { //printf("\ec"); } +EX debugflag debug_init_graph = {"init_graph"}; + EX void restartGraph() { - DEBBI(DF_INIT, ("restartGraph")); + indenter_finish di(debug_init_graph, "restartGraph"); if(!autocheat) linepatterns::clearAll(); if(currentmap) resetview(); } +EX debugflag debug_graph_memory = {"graph_memory"}; + auto graphcm = addHook(hooks_clearmemory, 0, [] () { - DEBBI(DF_MEMORY, ("clear graph memory")); + indenter_finish di(debug_graph_memory, "graph_memory"); mouseover = centerover = lmouseover = NULL; gmatrix.clear(); gmatrix0.clear(); current_display->all_drawn_copies.clear(); clearAnimations(); diff --git a/help.cpp b/help.cpp index f0a17b1e..58a44508 100644 --- a/help.cpp +++ b/help.cpp @@ -89,7 +89,7 @@ EX hookset hooks_build_help; EX void buildHelpText() { if(callhandlers(0, hooks_build_help)) return; - DEBBI(DF_GRAPH, ("buildHelpText")); + DEBBI(debug_graph, ("buildHelpText")); help = XLAT("Welcome to HyperRogue"); #if ISANDROID @@ -911,7 +911,7 @@ template void set_help_to(T t) { } EX void describeMouseover() { - DEBBI(DF_GRAPH, ("describeMouseover")); + DEBBI(debug_graph, ("describeMouseover")); if(callhandlers(0, hooks_global_mouseover)) return; diff --git a/hprint.cpp b/hprint.cpp index 0dccde33..c3465e4b 100644 --- a/hprint.cpp +++ b/hprint.cpp @@ -10,27 +10,6 @@ namespace hr { EX FILE *debugfile; -#if HDR -#define DF_INIT 1 // always display these -#define DF_MSG 2 // always display these -#define DF_WARN 4 // always display these -#define DF_ERROR 8 // always display these -#define DF_STEAM 16 -#define DF_GRAPH 32 -#define DF_TURN 64 -#define DF_FIELD 128 -#define DF_GEOM 256 -#define DF_MEMORY 512 -#define DF_TIME 1024 // a flag to display timestamps -#define DF_GP 2048 -#define DF_POLY 4096 -#define DF_LOG 8192 -#define DF_VERTEX 16384 -#define DF_KEYS "imwesxufgbtoplv" -#endif - -EX int debugflags = DF_INIT | DF_ERROR | DF_WARN | DF_MSG | DF_TIME | DF_LOG; - EX string s0; EX string its(int i) { return hr::format("%d", i); } @@ -321,15 +300,23 @@ struct indenter_finish : indenter { indenter tmp(-2); println(hlog, s); } + explicit indenter_finish(bool b, string s): indenter(b ? 2 : 0) { + if(b) { + indenter tmp(-2); + println(hlog, s); + } + } ~indenter_finish() { if(hlog.indentation != ind.backup) println(hlog, "(done)"); } }; #endif +EX debugflag debug_stamps = {"stamps", true}; + void logger::write_char(char c) { if(doindent) { doindent = false; - if(debugflags & DF_TIME) { + if(debug_stamps) { string s = get_stamp(); if(s != "") { for(char c: s) special_log(c); special_log(' '); } } @@ -538,9 +525,9 @@ EX string as_nice_cstring(string o) { #define DEBB0(r,x) #define DEBBI(r,x) #else -#define DEBB(r,x) { if(debugflags & (r)) { println_log x; } } -#define DEBB0(r,x) { if(debugflags & (r)) { print_log x; } } -#define DEBBI(r,x) { if(debugflags & (r)) { println_log x; } } indenter_finish _debbi(debugflags & (r)); +#define DEBB(r,x) { if(r) { println_log x; } } +#define DEBB0(r,x) { if(r) { print_log x; } } +#define DEBBI(r,x) { if(r) { println_log x; } } indenter_finish _debbi(r); #endif #endif diff --git a/hyper.h b/hyper.h index 49b63295..5ffac2eb 100644 --- a/hyper.h +++ b/hyper.h @@ -950,6 +950,24 @@ static inline void set_flag(flagtype& f, flagtype which, bool b) { else f &= ~which; } +void add_debugflag(const string& s, struct debugflag *d); + +/** Flags to enable debugging. + * A debugflag can be defined with e.g.: debugflag memory_cell("memory_cell") + * and used as in: if(memory_cell) { ... output debugging info ... } + * Then a commandline parameter '-debug memory' will enable all flags with 'memory' in its name + */ + +struct debugflag { + bool enabled; + debugflag(string s, bool initial = false) { + add_debugflag(s, this); + enabled = initial; + } + operator bool() { return enabled; } + void flip() { enabled = !enabled; } + }; + } /** this macro is used to delay performing the action in case if everything is rolled back */ diff --git a/hypgraph.cpp b/hypgraph.cpp index bb660be9..11b4b899 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -2327,7 +2327,6 @@ EX void centerpc(ld aspd) { if(ors::mode == 2 && vid.sspeed < 5) return; if(vid.sspeed >= 4.99) aspd = 1000; - DEBBI(DF_GRAPH, ("center pc")); auto mam = move_affected_matrices(0); for(auto pV: mam) ors::unrotate(*pV); @@ -2458,7 +2457,7 @@ void ballgeometry() { } EX void resetview() { - DEBBI(DF_GRAPH, ("reset view")); + indenter_finish dif(debug_graph, "resetview"); // EUCLIDEAN decide_lpu(); NLP = Id; diff --git a/legacy.cpp b/legacy.cpp index b3707df1..a6e9f459 100644 --- a/legacy.cpp +++ b/legacy.cpp @@ -428,6 +428,65 @@ int read_legacy_args() { return 0; } +struct legacy_flag { + char key; + int level; + debugflag *df; + }; + +vector legacy_flags = { + // INIT + legacy_flag{'i', 1, &debug_init}, + legacy_flag{'i', 1, &debug_init_music}, + legacy_flag{'i', 1, &debug_init_graph}, + legacy_flag{'i', 1, &debug_init_joy}, + legacy_flag{'i', 1, &debug_init_cells}, + legacy_flag{'i', 1, &debug_init_config}, + legacy_flag{'i', 1, &debug_init_font}, + // MSG + legacy_flag{'m', 1, &debug_messages}, + // WARN + legacy_flag{'w', 1, &debug_warnings}, + legacy_flag{'w', 1, &debug_map_warnings}, + // ERROR + legacy_flag{'e', 1, &debug_errors}, + legacy_flag{'e', 1, &debug_music_error}, + legacy_flag{'e', 1, &debug_joy_error}, + // STEAM + legacy_flag{'s', 3, &debug_achievements}, + // GRAPH + legacy_flag{'x', 4, &debug_aura}, + legacy_flag{'x', 4, &debug_map}, + legacy_flag{'x', 4, &debug_calcparam}, + legacy_flag{'x', 4, &debug_graph}, + legacy_flag{'x', 4, &debug_joy}, + legacy_flag{'x', 4, &debug_control}, + // TURN + legacy_flag{'u', 3, &debug_turn}, + // FIELD + legacy_flag{'f', 2, &fieldpattern::debug_field}, + // GEOM + legacy_flag{'g', 2, &debug_geometry}, + legacy_flag{'g', 4, &arcm::debug_archimedean_map}, + // MEMORY + legacy_flag{'b', 4, &debug_memory}, + legacy_flag{'b', 4, &debug_graph_memory}, + legacy_flag{'b', 4, &debug_memory_cell}, + // TIME + legacy_flag{'t', 9, &debug_stamps}, + // GP + legacy_flag{'o', 2, &gp::debug_gp}, + // POLY + legacy_flag{'p', 2, &debug_poly}, + // VERTEX + legacy_flag{'v', 9, &debug_vertex} + }; + +void set_legacy_flags(char key = 0, int level = 0, bool val = true) { + for(auto& lf: legacy_flags) if((!key || lf.key == key) && lf.level <= level && lf.df) + lf.df->enabled = val; + } + int read_legacy_args_anim() { using namespace anims; using namespace arg; @@ -529,6 +588,33 @@ int read_legacy_args_anim() { #endif vid.stereo_mode = sStereographic; } + else if(argis("-debf")) { + shift(); + string s = args(); + for(char c: s) { + if(c >= 'a' && c <= 'z') + set_legacy_flags(c, 0, true); + else if(c >= '0' && c <= '9') { + set_legacy_flags(0, 8, false); + set_legacy_flags(0, c - '0', true); + } + else if(c == '+') { + if(debugfile) fclose(debugfile); + shift(); + println(hlog, "writing to ", argcs()); + debugfile = fopen(argcs(), "at"); + } + else if(c == '@') { + if(debugfile) fclose(debugfile); + shift(); + println(hlog, "writing to ", argcs()); + debugfile = fopen(argcs(), "wt"); + } + } + } + else if(argis("-no-stamp")) { + debug_stamps.flip(); + } else return 1; return 0; } diff --git a/menus.cpp b/menus.cpp index 2c9cb32f..a2ebd28c 100644 --- a/menus.cpp +++ b/menus.cpp @@ -22,8 +22,8 @@ int PREC(ld x) { } EX void showOverview() { - cmode = sm::ZOOMABLE | sm::OVERVIEW; - DEBBI(DF_GRAPH, ("show overview")); + cmode = sm::ZOOMABLE | sm::OVERVIEW; + indenter_finish dif(debug_graph, "show overview"); if(dialog::infix != "") mouseovers = dialog::infix; @@ -1254,7 +1254,7 @@ EX string gettimestamp(msginfo& m) { } EX void showMessageLog() { - DEBBI(DF_GRAPH, ("show message log")); + indenter_finish dif(debug_graph, "showMessageLog"); int lines = vid.yres / vid.fsize - 2; int maxpos = isize(gamelog) - lines; diff --git a/monstermove.cpp b/monstermove.cpp index 4036748a..38813aaa 100644 --- a/monstermove.cpp +++ b/monstermove.cpp @@ -1698,11 +1698,11 @@ EX void movegolems(flagtype flags) { auto recorduse = orbused; - DEBB(DF_TURN, ("stayval")); + DEBB(debug_turn, ("stayval")); int bestv = stayvalue(m, c); vector bdirs; - DEBB(DF_TURN, ("moveval")); + DEBB(debug_turn, ("moveval")); for(int k=0; ktype; k++) if(c->move(k)) { int val = movevalue(m, c, k, flags); @@ -1752,7 +1752,7 @@ EX void movegolems(flagtype flags) { } else { passable_for(m, c2, c, P_DEADLY); - DEBB(DF_TURN, ("move")); + DEBB(debug_turn, ("move")); moveMonster(mi); if(m != moTameBomberbird && m != moFriendlyGhost) moveBoatIfUsingOne(mi); @@ -1769,7 +1769,7 @@ EX void movegolems(flagtype flags) { empathyMove(mi); } - DEBB(DF_TURN, ("other")); + DEBB(debug_turn, ("other")); } } achievement_count("GOLEM", qg, 0); @@ -2048,7 +2048,7 @@ EX void movemonsters() { ambush::distance = 0; #endif - DEBB(DF_TURN, ("lava1")); + DEBB(debug_turn, ("lava1")); orboflava(1); #if CAP_COMPLEX2 @@ -2060,80 +2060,80 @@ EX void movemonsters() { specialMoves(); - DEBB(DF_TURN, ("jumpers")); + DEBB(debug_turn, ("jumpers")); if(havewhat & HF_JUMP) { groupmove(moFrog, 0); groupmove(moVaulter, 0); groupmove(moPhaser, 0); } - DEBB(DF_TURN, ("ghosts")); + DEBB(debug_turn, ("ghosts")); moveghosts(); - DEBB(DF_TURN, ("butterflies")); + DEBB(debug_turn, ("butterflies")); moveButterflies(); - DEBB(DF_TURN, ("normal")); + DEBB(debug_turn, ("normal")); moveNormals(moYeti); - DEBB(DF_TURN, ("slow")); + DEBB(debug_turn, ("slow")); if(havewhat & HF_SLOW) moveNormals(moTortoise); if(sagefresh) sagephase = 0; - DEBB(DF_TURN, ("ivy")); + DEBB(debug_turn, ("ivy")); moveivy(); - DEBB(DF_TURN, ("slimes")); + DEBB(debug_turn, ("slimes")); groupmove(moSlime, 0); - DEBB(DF_TURN, ("sharks")); + DEBB(debug_turn, ("sharks")); if(havewhat & HF_SHARK) groupmove(moShark, 0); - DEBB(DF_TURN, ("eagles")); + DEBB(debug_turn, ("eagles")); if(havewhat & HF_BIRD) groupmove(moEagle, 0); if(havewhat & HF_EAGLES) groupmove(moEagle, MF_NOATTACKS | MF_ONLYEAGLE); - DEBB(DF_TURN, ("eagles")); + DEBB(debug_turn, ("eagles")); if(havewhat & HF_REPTILE) groupmove(moReptile, 0); - DEBB(DF_TURN, ("air")); + DEBB(debug_turn, ("air")); if(havewhat & HF_AIR) { airmap.clear(); groupmove(moAirElemental, 0); buildAirmap(); } - DEBB(DF_TURN, ("earth")); + DEBB(debug_turn, ("earth")); if(havewhat & HF_EARTH) groupmove(moEarthElemental, 0); - DEBB(DF_TURN, ("water")); + DEBB(debug_turn, ("water")); if(havewhat & HF_WATER) groupmove(moWaterElemental, 0); - DEBB(DF_TURN, ("void")); + DEBB(debug_turn, ("void")); if(havewhat & HF_VOID) groupmove(moVoidBeast, 0); - DEBB(DF_TURN, ("leader")); + DEBB(debug_turn, ("leader")); if(havewhat & HF_LEADER) groupmove(moPirate, 0); - DEBB(DF_TURN, ("mutant")); + DEBB(debug_turn, ("mutant")); if((havewhat & HF_MUTANT) || (closed_or_bounded && among(specialland, laOvergrown, laClearing))) movemutant(); - DEBB(DF_TURN, ("bugs")); + DEBB(debug_turn, ("bugs")); if(havewhat & HF_BUG) hive::movebugs(); - DEBB(DF_TURN, ("whirlpool")); + DEBB(debug_turn, ("whirlpool")); if(havewhat & HF_WHIRLPOOL) whirlpool::move(); - DEBB(DF_TURN, ("whirlwind")); + DEBB(debug_turn, ("whirlwind")); if(havewhat & HF_WHIRLWIND) whirlwind::move(); #if CAP_COMPLEX2 - DEBB(DF_TURN, ("westwall")); + DEBB(debug_turn, ("westwall")); if(havewhat & HF_WESTWALL) westwall::move(); #endif for(cell *pc: player_positions()) if(pc->item == itOrbSafety) return; - DEBB(DF_TURN, ("river")); + DEBB(debug_turn, ("river")); if(havewhat & HF_RIVER) prairie::move(); - /* DEBB(DF_TURN, ("magnet")); + /* DEBB(debug_turn, ("magnet")); if(havewhat & HF_MAGNET) groupmove(moSouthPole, 0), groupmove(moNorthPole, 0); */ - DEBB(DF_TURN, ("bugs")); + DEBB(debug_turn, ("bugs")); if(havewhat & HF_HEXD) groupmove(moHexDemon, 0); if(havewhat & HF_DICE) groupmove(moAnimatedDie, 0); if(havewhat & HF_ALT) groupmove(moAltDemon, 0); if(havewhat & HF_MONK) groupmove(moMonk, 0); - DEBB(DF_TURN, ("worm")); + DEBB(debug_turn, ("worm")); cell *savepos[MAXPLAYER]; for(int i=0; itype; i++) { - cellwalker cw(c, i); - if(cycle_discrepancy(cw)) println(hlog, cw, " ", cycle_discrepancy(cw)); - } - if(debugflags & DF_GEOM) for(cell *c: ac) for(int i=0; itype; i++) { - auto err = get_shift(cellwalker(c, i)) + get_shift(cellwalker(c, i)+wstep); - if(err) - println(hlog, "two-side error: ", err, " on ", cellwalker(c, i)); + if(debug_geometry) { + indenter_finish in("fix_bounded_cycles"); + for(cell *c: ac) for(int i=0; itype; i++) { + cellwalker cw(c, i); + if(cycle_discrepancy(cw)) println(hlog, cw, " ", cycle_discrepancy(cw)); + } + for(cell *c: ac) for(int i=0; itype; i++) { + auto err = get_shift(cellwalker(c, i)) + get_shift(cellwalker(c, i)+wstep); + if(err) + println(hlog, "two-side error: ", err, " on ", cellwalker(c, i)); + } } }); } diff --git a/pcmove.cpp b/pcmove.cpp index 77b43d11..e6c210ca 100644 --- a/pcmove.cpp +++ b/pcmove.cpp @@ -9,6 +9,8 @@ namespace hr { +EX debugflag debug_turn = {"turn"}; + EX int illegal_moves; EX bool keepLightning = false; @@ -366,7 +368,7 @@ bool pcmove::movepcto() { flipplayer = false; if(multi::players > 1) multi::flipped[multi::cpid] = false; } - DEBBI(checkonly ? 0 : DF_TURN, ("movepc")); + DEBBI(checkonly ? 0 : debug_turn, ("movepc")); if(!checkonly) invismove = false; boatmove = false; @@ -486,7 +488,7 @@ bool pcmove::after_move() { achievement_gain("SEVENMINE"); } - DEBB(DF_TURN, ("done")); + DEBB(debug_turn, ("done")); return true; } diff --git a/polygons.cpp b/polygons.cpp index f7a94be7..02dd0d1d 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -10,6 +10,8 @@ namespace hr { +EX debugflag debug_poly = {"graph_poly"}; + #if HDR static constexpr ld NEWSHAPE = (-13.5); #endif @@ -1185,7 +1187,7 @@ void geometry_information::prepare_shapes() { symmetriesAt.clear(); allshapes.clear(); - DEBBI(DF_POLY, ("buildpolys")); + DEBBI(debug_poly, ("buildpolys")); if(WDIM == 3 && !mhybrid) { if(sphere) SD3 = 3, SD7 = 5; diff --git a/reg3.cpp b/reg3.cpp index 7f9a5064..e36345a7 100644 --- a/reg3.cpp +++ b/reg3.cpp @@ -161,7 +161,7 @@ EX namespace reg3 { ld f0 = 0.5; ld f1 = binsearch(0.5, 1, [&] (ld d) { hyperpoint c = lerp(b, a, d); - if(debugflags & DF_GEOM) + if(debug_geometry) println(hlog, "d=", d, " c= ", c, " material = ", material(c)); return material(c) <= 0; }); @@ -174,7 +174,7 @@ EX namespace reg3 { for(int it=0; it<100; it++) { ld fa = (f0*2+f1) / 3; ld fb = (f0*1+f1*2) / 3; - if(debugflags & DF_GEOM) + if(debug_geometry) println(hlog, "f(", fa, ") = ", f(fa), " f(", fb, ") = ", f(fb)); if(f(fa) > f(fb)) f0 = fa; else f1 = fb; @@ -234,10 +234,10 @@ EX namespace reg3 { cgi.adjmoves[0] = cpush(0, between_centers) * cspin180(0, 2); for(int i=1; i nb; @@ -1266,7 +1267,8 @@ EX namespace reg3 { if(v == by) ; else if(v[index] % by[index] == 0) nb.insert(v - by * (v[index] / by[index])); - else println(hlog, "error"); + else if(debug_errors || debug_geometry) + println(hlog, "simplification error"); boundaries = std::move(nb); break; @@ -1935,7 +1937,7 @@ EX namespace reg3 { for(int i=0; i quality(bantar_config cp) { int notry = 0; +debugflags debug_bantar = {"demo_bantar"}; + void bantar() { if(!on) return; cwt = cellwalker(currentmap->gamestart(), 0); @@ -234,8 +236,8 @@ void bantar() { bool tres = test_uniq(cwt, -1, 15, NULL); auto q = quality(bc); if(tres) { - DEBB(DF_LOG, ("gens = ", gens)); - DEBB(DF_LOG, ("testing quality ", q, " ", make_pair(celldist(bc.first), celldist(bc.second)), ", result = ", tres)); + DEBB(debug_bantar, ("gens = ", gens)); + DEBB(debug_bantar, ("testing quality ", q, " ", make_pair(celldist(bc.first), celldist(bc.second)), ", result = ", tres)); lnotry--; if(lnotry <= 0) goto picked; } // if(tres) goto picked; diff --git a/rogueviz/som/kohonen.cpp b/rogueviz/som/kohonen.cpp index 6c69f9ba..dfaf9844 100644 --- a/rogueviz/som/kohonen.cpp +++ b/rogueviz/som/kohonen.cpp @@ -5,6 +5,10 @@ namespace rogueviz { namespace kohonen { +debugflag debug_kohonen("kohonen", true); +debugflag debug_kohonen_dispersion("kohonen_dispersion"); +debugflag debug_kohonen_error("kohonen_error", true); + int columns; vector data; @@ -65,19 +69,13 @@ bool noshow = false; vector samples_to_show; void loadsamples(const string& fname) { + DEBBI(debug_kohonen, ("Loading samples: ", fname)); data.clear(); samples_to_show.clear(); clear(); fhstream f(fname, "rt"); - if(!f.f) { - fprintf(stderr, "Could not load samples: %s\n", fname.c_str()); - return; - } - if(!scan(f, columns)) { - printf("Bad format: %s\n", fname.c_str()); - return; - } - printf("Loading samples: %s\n", fname.c_str()); + if(!f.f) return file_error(fname); + if(!scan(f, columns)) return file_format_error(fname); while(true) { sample s; bool shown = false; @@ -509,7 +507,7 @@ void buildcellcrawler(cell *c, cellcrawler& cr, int dir) { d.clear(); - // DEBBI(DF_LOG, ("Building dispersion, precision = ", dispersion_precision, " end_at = ", dispersion_end_at, "...\n")); + DEBBI(debug_kohonen_dispersion, ("Building dispersion, precision = ", dispersion_precision, " end_at = ", dispersion_end_at, "...\n")); for(iter=0; dispersion_count ? true : vmax > vmin * dispersion_end_at; iter++) { if(iter % dispersion_each == 0) { @@ -535,13 +533,14 @@ void buildcellcrawler(cell *c, cellcrawler& cr, int dir) { } if(!dispersion_count) { if(!dispersion_long) dispersion_count = isize(d); - DEBB(DF_LOG, ("Dispersion count = ", isize(d), " celldist = ", celldist(c))); + DEBB(debug_kohonen_dispersion, ("Dispersion count = ", isize(d), " celldist = ", celldist(c))); + } + + if(debug_kohonen_dispersion) { + println(hlog, "dlast = ", d.back()); + println(hlog, "dlast2 = ", d[d.size()-2]); + println(hlog, "vmin=", vmin, " vmax=",vmax, " end_at=", dispersion_end_at); } - /* - println(hlog, "dlast = ", d.back()); - println(hlog, "dlast2 = ", d[d.size()-2]); - println(hlog, "vmin=", vmin, " vmax=",vmax, " end_at=", dispersion_end_at); - */ } } @@ -607,20 +606,22 @@ void verify_crawlers() { int uniq = 0, failures = 0; - printf("Verifying crawlers...\n"); + if(debug_kohonen) printf("Verifying crawlers...\n"); for(cell *c: allcells) { auto id = get_cellcrawler_id(c); if(allcrawlers.count(id.first)) { bool b = verify_crawler(allcrawlers[id.first], cellwalker(c, id.second)); if(!b) { - printf("cell %p: type = %d id = %d dir = %d / earlier crawler failed\n", hr::voidp(c), c->type, id.first, id.second); + if(debug_kohonen_dispersion) + printf("cell %p: type = %d id = %d dir = %d / earlier crawler failed\n", hr::voidp(c), c->type, id.first, id.second); failures++; } } else { for(int i=0; itype; i++) for(auto& cc: allcrawlers) if(verify_crawler(cc.second, cellwalker(c, i))) { - printf("cell %p: type = %d id = %d dir = %d / also works id %d in direction %d\n", hr::voidp(c), c->type, id.first, id.second, cc.first, i); + if(debug_kohonen_dispersion) + printf("cell %p: type = %d id = %d dir = %d / also works id %d in direction %d\n", hr::voidp(c), c->type, id.first, id.second, cc.first, i); uniq--; goto breakcheck; } @@ -631,9 +632,10 @@ void verify_crawlers() { uniq++; } } - printf("Crawlers constructed: %d (%d unique, %d failures)\n", isize(allcrawlers), uniq, failures); + if(debug_kohonen) + printf("Crawlers constructed: %d (%d unique, %d failures)\n", isize(allcrawlers), uniq, failures); setindex(false); - if(failures) exit(1); + if(failures) throw hr_exception("verify_crawler error"); } bool finished() { return t == 0; } @@ -809,7 +811,8 @@ vector gen_neuron_cells() { while(at < isize(allcells) && hdist0(tC0(ggmatrix(allcells[at]))) < dist + 1e-6) at++; int at1 = kohrestrict; while(at1 > 0 && hdist0(tC0(ggmatrix(allcells[at1-1]))) > dist - 1e-6) at1--; - printf("Cells numbered [%d,%d) are in the same distance\n", at1, at); + if(debug_kohonen) + println(hlog, "Cells numbered [", at1, ",", at, ") are in the same distance"); allcells.resize(kohrestrict); for(int i=kohrestrict; i gen_neuron_cells() { void create_neurons() { initialize_rv(); - if(!samples) { - fprintf(stderr, "Error: SOM without samples\n"); - exit(1); - } + if(!samples) + throw hr_exception("SOM without samples"); weight_label = "quantity"; - DEBBI(DF_LOG, ("Creating neurons")); + DEBBI(debug_kohonen, ("Creating neurons")); auto allcells = gen_neuron_cells(); @@ -844,12 +845,12 @@ void create_neurons() { } for(neuron& n: net) for(int d=BARLEV; d>=7; d--) setdist(n.where, d, NULL); - DEBB(DF_LOG, ("number of neurons = ", cells)); + DEBB(debug_kohonen, ("number of neurons = ", cells)); } void set_neuron_initial() { initialize_neurons(); - DEBBI(DF_LOG, ("Setting initial neuron values")); + DEBBI(debug_kohonen, ("Setting initial neuron values")); for(int i=0; i &walkers, vectorid, " sample = ", c); if(isize(pre) > max_shortcut_length) { @@ -575,7 +575,7 @@ EX void shortcut_found(tcell *c, tcell *alt, vector &walkers, vectorlast_dir = c->any_nearer; auto& sh1 = *sh; - if(debugflags & DF_GEOM) println(hlog, "exhaustive search:"); + if(debug_geometry) println(hlog, "exhaustive search:"); indenter ind(2); tcell* c1 = first_tcell; while(c1) { @@ -595,11 +595,11 @@ EX void find_new_shortcuts(tcell *c, int d, tcell *alt, int newdir, int delta) { if(flags & w_known_distances) return; ufindc(c); - if(debugflags & DF_GEOM) + if(debug_geometry) println(hlog, "solid ", c, " changes ", c->dist, " to ", d, " alt=", alt); if(newdir == c->any_nearer) { - if(debugflags & DF_GEOM) + if(debug_geometry) println(hlog, "same direction"); return; } @@ -785,7 +785,7 @@ EX void be_solid(tcell *c) { look_for_shortcuts(c); ufindc(c); if(c->dist == MYSTERY) { - if(debugflags & DF_GEOM) + if(debug_geometry) println(hlog, "set solid but no dist ", c); debuglist = { c }; throw rulegen_failure("set solid but no dist"); @@ -832,7 +832,7 @@ EX void look_for_shortcuts(tcell *c, shortcut& sh) { process_fix_queue(); if(tw.at->dist < c->dist) { - if(debugflags & DF_GEOM) + if(debug_geometry) println(hlog, "smart shortcut updated ", c->dist, " to ", tw.at->dist); } push_unify(tw, tw0); @@ -1236,7 +1236,7 @@ int get_side(twalker what) { cw = get_parent_dir(cw); if(cw.peek()->dist >= cw.at->dist) { handle_distance_errors(); - if(debugflags & DF_GEOM) + if(debug_geometry) println(hlog, "get_parent_dir error at ", cw, " and ", cw.at->move(cw.spin), ": ", cw.at->dist, "::", cw.at->move(cw.spin)->dist); throw rulegen_failure("get_parent_dir error"); } @@ -1513,7 +1513,7 @@ EX void rules_iteration_for(twalker& cw) { else if(ts.rules != cids) { handle_distance_errors(); auto& r = ts.rules; - if(debugflags & DF_GEOM) { + if(debug_geometry) { println(hlog, "merging ", ts.rules, " vs ", cids); } int mismatches = 0; @@ -1555,7 +1555,7 @@ EX void rules_iteration_for(twalker& cw) { void minimize_rules() { states_premini = isize(treestates); - if(debugflags & DF_GEOM) + if(debug_geometry) println(hlog, "minimizing rules..."); int next_id = isize(treestates); @@ -1599,7 +1599,7 @@ void minimize_rules() { } } - if(debugflags & DF_GEOM) + if(debug_geometry) println(hlog, "final new_ids = ", new_ids, " / ", next_id); if(1) { @@ -1686,7 +1686,7 @@ void find_possible_parents() { int pp = 0; for(auto& ts: treestates) if(ts.is_possible_parent) pp++; - if(debugflags & DF_GEOM) + if(debug_geometry) println(hlog, pp, " of ", isize(treestates), " states are possible_parents"); } @@ -1756,10 +1756,10 @@ void verified_treewalk(twalker& tw, int id, int dir) { if((flags & w_examine_all) || !branch_conflicts_seen.count(conflict_id)) { branch_conflicts_seen.insert(conflict_id); important.push_back(tw.at); - if(debugflags & DF_GEOM) + if(debug_geometry) println(hlog, "branch conflict ", conflict_id, " found"); } - else if(debugflags & DF_GEOM) + else if(debug_geometry) println(hlog, "branch conflict ", conflict_id, " found again"); debuglist = {tw, tw+wstep}; throw verify_advance_failed(); @@ -1772,7 +1772,7 @@ bool examine_branch(int id, int left, int right) { if(WDIM == 3) return true; auto rg = treestates[id].giver; - if(debugflags & DF_GEOM) + if(debug_geometry) println(hlog, "need to examine branches ", tie(left, right), " of ", id, " starting from ", rg, " step = ", rg+left+wstep, " vs ", rg+right+wstep); indenter ind(2); @@ -1972,10 +1972,10 @@ EX void rules_iteration() { } handle_distance_errors(); - if(debugflags & DF_GEOM) + if(debug_geometry) println(hlog, "number of treestates = ", isize(treestates)); rule_root = get_treestate_id(t_origin[0]).second; - if(debugflags & DF_GEOM) + if(debug_geometry) println(hlog, "rule_root = ", rule_root); for(int id=0; id v; for(auto c: single_live_branch_close_to_root) v.push_back(c); - if(debugflags & DF_GEOM) + if(debug_geometry) println(hlog, "changed single_live_branch_close_to_root from ", q, " to ", v); debuglist = { treestates[id].giver }; clear_sidecache_and_codes(); @@ -2506,7 +2506,7 @@ EX bool prepare_rules() { rules_known_for = arb::current.name; rule_status = XLAT("rules generated successfully: %1 states using %2-%3 cells", its(isize(treestates)), its(tcellcount), its(tunified)); - if(debugflags & DF_GEOM) println(hlog, rule_status); + if(debug_geometry) println(hlog, rule_status); return true; } catch(rulegen_retry& e) { @@ -2518,7 +2518,7 @@ EX bool prepare_rules() { catch(rulegen_failure& e) { rule_status = XLAT("bug: %1", e.what()); } - if(debugflags & DF_GEOM) println(hlog, rule_status); + if(debug_geometry) println(hlog, rule_status); return false; } @@ -2612,9 +2612,9 @@ EX void parse_treestate(arb::arbi_tiling& c, exp_parser& ep) { if(qparent > 1) throw hr_parse_exception("multiple parent at " + ep.where()); if(qparent == 1) { ts.parent_dir = sumparent; - if(debugflags & DF_GEOM) println(hlog, "before: ", ts.rules); + if(debug_geometry) println(hlog, "before: ", ts.rules); std::rotate(ts.rules.begin(), ts.rules.begin() + sumparent, ts.rules.end()); - if(debugflags & DF_GEOM) println(hlog, "after : ", ts.rules); + if(debug_geometry) println(hlog, "after : ", ts.rules); } ep.force_eat(")"); } diff --git a/savemem.cpp b/savemem.cpp index 10da4564..101bc115 100644 --- a/savemem.cpp +++ b/savemem.cpp @@ -69,13 +69,13 @@ void recursive_delete(heptagon *h, int i) { if(h2->move(i) && h2->move(i)->move(0) == h2) recursive_delete(h2, i); } if(h2->alt && h2->alt->alt == h2->alt) { - DEBB(DF_MEMORY, ("destroying alternate map ", h2->alt)); + DEBB(debug_memory, ("destroying alternate map ", h2->alt)); for(hrmap *& hm: allmaps) { if(hm->getOrigin() == h2->alt) { delete hm; hm = allmaps.back(); allmaps.pop_back(); - DEBB(DF_MEMORY, ("map found (", isize(allmaps), " altmaps total)")); + DEBB(debug_memory, ("map found (", isize(allmaps), " altmaps total)")); break; } } @@ -155,7 +155,7 @@ EX void save_memory() { if(last_cleared && celldist(at->c7) < celldist(last_cleared->c7)) return; - DEBB(DF_MEMORY, ("celldist = ", make_pair(celldist(cwt.at), celldist(at->c7)))); + DEBB(debug_memory, ("celldist = ", make_pair(celldist(cwt.at), celldist(at->c7)))); heptagon *at1 = at; while(at != last_cleared && at != orig) { @@ -168,7 +168,7 @@ EX void save_memory() { } last_cleared = at1; - DEBB(DF_MEMORY, ("current cellcount = ", cellcount)); + DEBB(debug_memory, ("current cellcount = ", cellcount)); sort(removed_cells.begin(), removed_cells.end()); callhooks(hooks_removecells); diff --git a/sound.cpp b/sound.cpp index eb125a9e..6c34553b 100644 --- a/sound.cpp +++ b/sound.cpp @@ -101,8 +101,11 @@ EX hookset hooks_sync_music; EX bool music_out_of_focus = false; +EX debugflag debug_music = {"music"}; +EX debugflag debug_music_error = {"music_error"}; + EX void handlemusic() { - DEBBI(DF_GRAPH, ("handle music")); + indenter_finish hm(debug_music, "handlemusic"); if(audio && musicvolume) { eLand id = getCurrentLandForMusic(); if(callhandlers(false, hooks_music, id)) return; @@ -120,7 +123,7 @@ EX void handlemusic() { if(!music[id]) { memory_for_lib(); music[id] = Mix_LoadMUS(musfname[id].c_str()); - if(!music[id]) { + if(!music[id] && debug_music_error) { printf("Mix_LoadMUS: %s\n", Mix_GetError()); } } @@ -159,8 +162,10 @@ EX void resetmusic() { constexpr eLand mfcode(const char* buf) { return eLand((buf[0] - '0') * 10 + buf[1] - '0'); } #endif +EX debugflag debug_init_music = {"init_music", true}; + EX bool loadMusicInfo(string dir) { - DEBBI(DF_INIT, ("load music info")); + indenter_finish hm(debug_init_music, "loadMusicInfo"); if(dir == "") return false; FILE *f = fopen(dir.c_str(), "rt"); if(f) { @@ -178,7 +183,7 @@ EX bool loadMusicInfo(string dir) { else musfname[id] = buf+5; music_available = true; } - else { + else if(debug_music_error) { fprintf(stderr, "warning: bad soundtrack id, use the following format:\n"); fprintf(stderr, "[##] */filename\n"); fprintf(stderr, "where ## are two digits, and */ is optional and replaced by path to the music\n"); diff --git a/system.cpp b/system.cpp index 7eee49de..7d1cf6dc 100644 --- a/system.cpp +++ b/system.cpp @@ -191,7 +191,7 @@ EX void reset_cheats() { /** \brief initialize the game */ EX void initgame() { - DEBBI(DF_INIT, ("initGame")); + DEBBI(debug_init, ("initGame")); if(!safety) reset_cheats(); callhooks(hooks_initgame); @@ -1095,7 +1095,7 @@ scores::score scorebox; EX bool save_cheats; EX void saveStats(bool emergency IS(false)) { - DEBBI(DF_INIT, ("saveStats [", scorefile, "]")); + DEBBI(debug_init, ("saveStats [", scorefile, "]")); if(autocheat && !save_cheats) return; if(scorefile == "") return; @@ -1232,7 +1232,7 @@ EX void saveStats(bool emergency IS(false)) { fprintf(f, "\n\n\n"); #if !ISMOBILE - DEBB(DF_INIT, ("Game statistics saved to ", scorefile)); + DEBB(debug_init, ("Game statistics saved to ", scorefile)); addMessage(XLAT("Game statistics saved to %1", scorefile)); #endif fclose(f); @@ -1247,7 +1247,7 @@ EX void loadsave() { #if CAP_TOUR if(tour::on) return; #endif - DEBBI(DF_INIT, ("loadSave")); + DEBBI(debug_init, ("loadSave")); FILE *f = fopen(scorefile.c_str(), "rt"); havesave = f; @@ -1440,7 +1440,7 @@ EX void load_last_save() { EX void stop_game() { if(!game_active) return; if(dual::split(stop_game)) return; - DEBBI(DF_INIT, ("stop_game")); + DEBBI(debug_init, ("stop_game")); achievement_final(true); save_if_needed(); for(int i=0; i