diff --git a/3d-models.cpp b/3d-models.cpp index df49d234..631e15d0 100644 --- a/3d-models.cpp +++ b/3d-models.cpp @@ -11,8 +11,8 @@ ld eyepos; #if MAXMDIM >= 4 -#define S (scalefactor / 0.805578) -#define SH (scalefactor / 0.805578 * geom3::height_width / 1.5) +#define S (cgi.scalefactor / 0.805578) +#define SH (cgi.scalefactor / 0.805578 * geom3::height_width / 1.5) #define revZ (WDIM == 2 ? -1 : 1) @@ -22,7 +22,7 @@ hyperpoint front_leg, rear_leg; transmatrix front_leg_move, rear_leg_move, front_leg_move_inverse, rear_leg_move_inverse; ld leg_length; -vector get_shape(hpcshape sh) { +vector geometry_information::get_shape(hpcshape sh) { vector res; for(int i=sh.s; i& vh) { ld zc(ld z) { if(WDIM == 2 && GDIM == 3) - return geom3::lev_to_factor(geom3::human_height * z); - return geom3::human_height * (z - 0.5); + return geom3::lev_to_factor(cgi.human_height * z); + return cgi.human_height * (z - 0.5); } transmatrix zpush(ld z) { return cpush(2, z); } -void add_cone(ld z0, const vector& vh, ld z1) { +void geometry_information::add_cone(ld z0, const vector& vh, ld z1) { last->flags |= POLY_TRIANGLES; for(int i=0; i& vh, ld z1) { } } -void add_prism_sync(ld z0, vector vh0, ld z1, vector vh1) { +void geometry_information::add_prism_sync(ld z0, vector vh0, ld z1, vector vh1) { last->flags |= POLY_TRIANGLES; for(int i=0; i vh0, ld z1, vector vh1 } } -void add_prism(ld z0, vector vh0, ld z1, vector vh1) { +void geometry_information::add_prism(ld z0, vector vh0, ld z1, vector vh1) { last->flags |= POLY_TRIANGLES; struct mixed { @@ -97,15 +97,15 @@ void add_prism(ld z0, vector vh0, ld z1, vector vh1) { } } -void shift_last(ld z) { +void geometry_information::shift_last(ld z) { for(int i=last->s; i scaleshape(const vector& vh, ld s) { return res; } -void make_ha_3d(hpcshape& sh, bool isarmor, ld scale) { +void geometry_information::make_ha_3d(hpcshape& sh, bool isarmor, ld scale) { shcenter = C0; auto groin = get_shape(shHumanGroin); @@ -191,14 +191,14 @@ void make_ha_3d(hpcshape& sh, bool isarmor, ld scale) { add_cone(zc(0.8), neck, zc(0.83)); int at0 = isize(hpc); - ld h = geom3::human_height; + ld h = human_height; if(isize(arm) > 3) { shcenter = get_center(arm); int arm0 = isize(hpc); - add_prism_sync(geom3::BODY - h*.03, arm, geom3::BODY + h*.03, arm); - add_cone(geom3::BODY + h*.03, arm, geom3::BODY + h*.05); - add_cone(geom3::BODY - h*.03, arm, geom3::BODY - h*.05); + add_prism_sync(BODY - h*.03, arm, BODY + h*.03, arm); + add_cone(BODY + h*.03, arm, BODY + h*.05); + add_cone(BODY - h*.03, arm, BODY - h*.05); int arm1 = isize(hpc); for(int i=arm0; i 3) { shcenter = get_center(hand); - add_cone(geom3::BODY, hand, geom3::BODY + 0.05 * geom3::human_height); - add_cone(geom3::BODY, hand, geom3::BODY - 0.05 * geom3::human_height); + add_cone(BODY, hand, BODY + 0.05 * human_height); + add_cone(BODY, hand, BODY - 0.05 * human_height); } int at1 = isize(hpc); for(int i=at0; i hs, int kind) { +void geometry_information::addtri(array hs, int kind) { ld ds[3]; ds[0] = hdist(hs[0], hs[1]); ds[1] = hdist(hs[1], hs[2]); @@ -287,7 +287,7 @@ void addtri(array hs, int kind) { } ld levels[6] = {0, 0.125, 0.125, 0.250, 0.375, 0.5}; for(int a=0; a<6; a++) for(int i=0; i<3; i++) - htx[a][i] = zpush(-min(shi[i], levels[a]) * geom3::human_height * revZ) * htx[a][i]; + htx[a][i] = zpush(-min(shi[i], levels[a]) * human_height * revZ) * htx[a][i]; hpcpush(htx[0][0]); hpcpush(htx[0][1]); @@ -320,7 +320,7 @@ void addtri(array hs, int kind) { } } -void make_armor_3d(hpcshape& sh, int kind = 1) { +void geometry_information::make_armor_3d(hpcshape& sh, int kind) { auto body = get_shape(sh); vector >> pts(2); @@ -345,12 +345,12 @@ void make_armor_3d(hpcshape& sh, int kind = 1) { add_texture(sh); if(&sh == &shHood || &sh == &shWightCloak || &sh == &shArmor) - shift_last(-geom3::HEAD); + shift_last(-HEAD); else - shift_last(-geom3::BODY); + shift_last(-BODY); } -void make_foot_3d(hpcshape& sh) { +void geometry_information::make_foot_3d(hpcshape& sh) { auto foot = get_shape(sh); auto leg = get_shape(shHumanLeg); auto leg5 = scaleshape(leg, 0.8); @@ -362,13 +362,13 @@ void make_foot_3d(hpcshape& sh) { add_prism_sync(zc(0.1), leg, zc(0.4), leg5); add_cone(zc(0.4), leg5, zc(0.45)); add_texture(sh); - // shift_last(-geom3::LEG0); + // shift_last(-LEG0); for(int i=last->s; i >> pts(2); @@ -414,10 +414,10 @@ void make_head_3d(hpcshape& sh) { } add_texture(sh); - shift_last(-geom3::HEAD); + shift_last(-HEAD); } -void make_paw_3d(hpcshape& sh, hpcshape& legsh) { +void geometry_information::make_paw_3d(hpcshape& sh, hpcshape& legsh) { auto foot = get_shape(sh); auto leg = get_shape(legsh); @@ -430,7 +430,7 @@ void make_paw_3d(hpcshape& sh, hpcshape& legsh) { add_texture(sh); } -void make_abody_3d(hpcshape& sh, ld tail) { +void geometry_information::make_abody_3d(hpcshape& sh, ld tail) { auto body = get_shape(sh); shcenter = get_center(body); @@ -448,10 +448,10 @@ void make_abody_3d(hpcshape& sh, ld tail) { add_cone(zc(0.4), body8, zc(0.36)); add_cone(zc(0.6), body8, zc(0.64)); add_texture(sh); - if(GDIM == 3 && WDIM == 2) shift_last(-geom3::ABODY); + if(GDIM == 3 && WDIM == 2) shift_last(-ABODY); } -void make_ahead_3d(hpcshape& sh) { +void geometry_information::make_ahead_3d(hpcshape& sh) { auto body = get_shape(sh); shcenter = get_center(body); auto body8 = scaleshape(body, 0.5); @@ -464,7 +464,7 @@ void make_ahead_3d(hpcshape& sh) { add_texture(sh); } -void make_skeletal(hpcshape& sh, ld push = 0) { +void geometry_information::make_skeletal(hpcshape& sh, ld push) { auto body = get_shape(sh); shcenter = get_center(body); @@ -477,7 +477,7 @@ void make_skeletal(hpcshape& sh, ld push = 0) { shift_last(-push); } -void make_revolution(hpcshape& sh, int mx = 180, ld push = 0) { +void geometry_information::make_revolution(hpcshape& sh, int mx, ld push) { auto body = get_shape(sh); bshape(sh, PPR::MONSTER_BODY); int step = (mx == 360 ? 24 : 10); @@ -498,7 +498,7 @@ void make_revolution(hpcshape& sh, int mx = 180, ld push = 0) { shift_last(-push); } -void make_revolution_cut(hpcshape &sh, int each = 180, ld push = 0, ld width = 99) { +void geometry_information::make_revolution_cut(hpcshape &sh, int each, ld push, ld width) { auto body = get_shape(sh); body.resize(isize(body) / 2); ld fx = body[0][0]; @@ -570,14 +570,14 @@ void disable(hpcshape& sh) { sh.s = sh.e = 0; } -void clone_shape(hpcshape& sh, hpcshape& target) { +void geometry_information::clone_shape(hpcshape& sh, hpcshape& target) { target = sh; target.s = isize(hpc); for(int i=sh.s; i d(vid.texture_step, 8); texture_order([&] (ld x, ld y) { using namespace hyperpoint_vec; @@ -606,7 +606,7 @@ void slimetriangle(hyperpoint a, hyperpoint b, hyperpoint c, ld rad, int lev) { }); } -void balltriangle(hyperpoint a, hyperpoint b, hyperpoint c, ld rad, int lev) { +void geometry_information::balltriangle(hyperpoint a, hyperpoint b, hyperpoint c, ld rad, int lev) { if(lev == 0) { hpcpush(a); hpcpush(b); @@ -623,7 +623,7 @@ void balltriangle(hyperpoint a, hyperpoint b, hyperpoint c, ld rad, int lev) { } } -void make_ball(hpcshape& sh, ld rad, int lev) { +void geometry_information::make_ball(hpcshape& sh, ld rad, int lev) { bshape(sh, sh.prio); sh.flags |= POLY_TRIANGLES; hyperpoint tip = xpush0(rad); @@ -652,7 +652,7 @@ hyperpoint psmin(hyperpoint H) { return res; } -void adjust_eye(hpcshape& eye, hpcshape head, ld shift_eye, ld shift_head, int q, ld zoom=1) { +void geometry_information::adjust_eye(hpcshape& eye, hpcshape head, ld shift_eye, ld shift_head, int q, ld zoom) { using namespace hyperpoint_vec; hyperpoint center = Hypc; for(int i=eye.s; i 0) center += hpc[i]; @@ -697,7 +697,7 @@ void adjust_eye(hpcshape& eye, hpcshape head, ld shift_eye, ld shift_head, int q // eye.prio = PPR::SUPERLINE; } -void shift_last_straight(ld z) { +void geometry_information::shift_last_straight(ld z) { for(int i=last->s; iflags |= POLY_TRIANGLES; add_texture(*last); - if(WDIM == 2) shift_last_straight(geom3::FLOOR); + if(WDIM == 2) shift_last_straight(FLOOR); finishshape(); shJelly = shSlime; - shift_shape(shMagicSword, geom3::ABODY); - shift_shape(shMagicShovel, geom3::ABODY); + shift_shape(shMagicSword, ABODY); + shift_shape(shMagicShovel, ABODY); DEBB(DF_POLY, ("eyes")); - adjust_eye(shSlimeEyes, shSlime, geom3::FLATEYE, 0, 2, 2); - adjust_eye(shGhostEyes, shGhost, geom3::GHOST, geom3::GHOST, 2, WDIM == 2 ? 2 : 4); - adjust_eye(shMiniEyes, shMiniGhost, geom3::GHOST, geom3::GHOST, 2, 2); + 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); adjust_eye(shWormEyes, shWormHead, 0, 0, 2, 4); adjust_eye(shDragonEyes, shDragonHead, 0, 0, 2, 4); @@ -1050,31 +1050,31 @@ void make_3d_models() { shRatEye2 = shWolf2; shRatEye3 = shWolf3; - adjust_eye(shWolf1, shDogHead, geom3::AHEAD, geom3::AHEAD, 1); - adjust_eye(shWolf2, shDogHead, geom3::AHEAD, geom3::AHEAD, 1); - adjust_eye(shWolf3, shDogHead, geom3::AHEAD, geom3::AHEAD, 1); - adjust_eye(shFamiliarEye, shWolfHead, geom3::AHEAD, geom3::AHEAD, 1); + adjust_eye(shWolf1, shDogHead, AHEAD, AHEAD, 1); + adjust_eye(shWolf2, shDogHead, AHEAD, AHEAD, 1); + adjust_eye(shWolf3, shDogHead, AHEAD, AHEAD, 1); + adjust_eye(shFamiliarEye, shWolfHead, AHEAD, AHEAD, 1); - adjust_eye(shRatEye1, shRatHead, geom3::AHEAD, geom3::AHEAD, 1); - adjust_eye(shRatEye2, shRatHead, geom3::AHEAD, geom3::AHEAD, 1); + adjust_eye(shRatEye1, shRatHead, AHEAD, AHEAD, 1); + adjust_eye(shRatEye2, shRatHead, AHEAD, AHEAD, 1); for(int i=shRatEye3.s; imove(1)->c.connect(1, origin->move(0), 2*current.N-1, false); } - base_distlimit = 0; + cgi.base_distlimit = 0; celllister cl(origin->c7, 1000, 200, NULL); - ginf[geometry].distlimit[!BITRUNCATED] = base_distlimit = cl.dists.back(); - if(sphere) base_distlimit = SEE_ALL; + ginf[geometry].distlimit[!BITRUNCATED] = cgi.base_distlimit = cl.dists.back(); + if(sphere) cgi.base_distlimit = SEE_ALL; } ~hrmap_archimedean() { @@ -784,7 +784,6 @@ int readArgs() { } else { set_geometry(gArchimedean); - need_reset_geometry = true; current = at; showstartmenu = false; } @@ -982,7 +981,6 @@ void next_variation() { PURE ? eVariation::dual : DUAL ? eVariation::bitruncated : eVariation::pure); - need_reset_geometry = true; start_game(); } @@ -1012,7 +1010,6 @@ void enable(archimedean_tiling& arct) { } } #endif - need_reset_geometry = true; start_game(); } diff --git a/basegraph.cpp b/basegraph.cpp index a4f865ae..30669009 100644 --- a/basegraph.cpp +++ b/basegraph.cpp @@ -693,7 +693,8 @@ void resetGL() { floor_textures = NULL; } #endif - resetGeometry(); // includes buildPoly + cgi.require_shapes(); + cgi.initPolyForGL(); } #endif @@ -1101,7 +1102,7 @@ void displayColorButton(int x, int y, const string& name, int key, int align, in } ld textscale() { - return vid.fsize / (current_display->radius * crossf) * (1+vid.alpha) * 2; + return vid.fsize / (current_display->radius * cgi.crossf) * (1+vid.alpha) * 2; } // bool notgl = false; @@ -1238,7 +1239,7 @@ void initgraph() { #if CAP_COMMANDLINE arg::read(2); #endif - precalc(); + cgi.prepare_basics(); #if CAP_SDL setvideomode(); diff --git a/binary-tiling.cpp b/binary-tiling.cpp index 8d19e194..179e433b 100644 --- a/binary-tiling.cpp +++ b/binary-tiling.cpp @@ -601,7 +601,7 @@ namespace binary { auto bt_config = addHook(hooks_args, 0, [] () { using namespace arg; if(argis("-btwidth")) { - shift_arg_formula(vid.binary_width, delayed_geo_reset); + shift_arg_formula(vid.binary_width); return 0; } return 1; diff --git a/blizzard.cpp b/blizzard.cpp index 641c8c78..613cad22 100644 --- a/blizzard.cpp +++ b/blizzard.cpp @@ -121,7 +121,7 @@ void drawBlizzards() { if(wmascii || wmblack) queuechr(tpartial, .2, '.', 0xFFFFFF); else - queuepoly(tpartial, shSnowball, 0xFFFFFF80); + queuepoly(tpartial, cgi.shSnowball, 0xFFFFFF80); } } @@ -130,9 +130,9 @@ void drawBlizzards() { /* if(isNeighbor(bc.c, mouseover)) { if(againstWind(mouseover, bc.c)) - queuepoly(*bc.gm, shHeptaMarker, 0x00C00040); + queuepoly(*bc.gm, cgi.shHeptaMarker, 0x00C00040); if(againstWind(bc.c, mouseover)) - queuepoly(*bc.gm, shHeptaMarker, 0xC0000040); + queuepoly(*bc.gm, cgi.shHeptaMarker, 0xC0000040); } */ forCellIdEx(c2, i, bc.c) if(bc.c == mouseover || c2 == mouseover) { @@ -144,7 +144,7 @@ void drawBlizzards() { if(isPlayerOn(bc.c)) col ^= 0x00000040; if(againstWind(bc.c, c2)) - queuepoly(*bc.gm * ddspin(bc.c, i) * xpush(cellgfxdist(bc.c, i)/2), shWindArrow, col); + queuepoly(*bc.gm * ddspin(bc.c, i) * xpush(cellgfxdist(bc.c, i)/2), cgi.shWindArrow, col); } int B = isize(bc.outorder); @@ -230,7 +230,7 @@ void drawArrowTraps() { transmatrix& tv = u ? t1 : t0; hyperpoint trel = inverse(tu) * tC0(tv); transmatrix tpartial = tu * rspintox(trel) * xpush(hdist0(trel) * tt / 401.0); - queuepoly(tpartial * ypush(.05), shTrapArrow, 0xFFFFFFFF); + queuepoly(tpartial * ypush(.05), cgi.shTrapArrow, 0xFFFFFFFF); } } #endif diff --git a/compileunits.h b/compileunits.h index 0352cfd5..19ee24b5 100644 --- a/compileunits.h +++ b/compileunits.h @@ -67,6 +67,8 @@ namespace hr { namespace inv { bool on, activating; } } #include "polygons.cpp" #include "3d-models.cpp" #include "floorshapes.cpp" +#include "usershapes.cpp" +#include "drawing.cpp" #include "mapeditor.cpp" #if CAP_MODEL #include "netgen.cpp" diff --git a/config.cpp b/config.cpp index 5d9155b3..04ce7a44 100644 --- a/config.cpp +++ b/config.cpp @@ -648,7 +648,8 @@ void loadConfig() { } polygonal::solve(); - precalc(); + check_cgi(); + cgi.prepare_basics(); } #endif @@ -855,7 +856,6 @@ void showGraphConfig() { else if(xuni == 'L') { dialog::editNumber(vid.linequality, -3, 5, 1, 1, XLAT("line quality"), XLAT("Higher numbers make the curved lines smoother, but reduce the performance.")); - dialog::reaction = delayed_geo_reset; } #if CAP_FRAMELIMIT @@ -913,7 +913,6 @@ void edit_whatever(char type, int index) { dialog::editNumber(whateveri[index], -10, 10, 1, 0, XLAT("whatever"), "i:" + its(index)); } - dialog::reaction = delayed_geo_reset; dialog::extra_options = [type, index] { dialog::addItem(XLAT("integer"), 'X'); dialog::add_action( [index] { popScreen(); edit_whatever('i', index); }); @@ -1259,7 +1258,6 @@ void add_edit_wall_quality(char c) { floor_textures = NULL; } #endif - need_reset_geometry = true; }; }); } @@ -1395,7 +1393,6 @@ void show3D() { else if(uni == 'c' && WDIM == 2) tc_camera = ticks, dialog::editNumber(geom3::camera, 0, 5, .1, 1, XLAT(GDIM == 2 ? "Camera level above the plane" : "Z shift"), ""), - dialog::reaction = [] { if(GDIM == 2) need_reset_geometry = true; }, dialog::extra_options = [] { dialog::addHelp(GDIM == 2 ? XLAT( "Camera is placed %1 absolute units above a plane P in a three-dimensional " @@ -1415,7 +1412,6 @@ void show3D() { else if(uni == 'g' && WDIM == 2) tc_depth = ticks, dialog::editNumber(geom3::depth, 0, 5, .1, 1, XLAT("Ground level below the plane"), ""), - dialog::reaction = delayed_geo_reset, dialog::extra_options = [] { dialog::addHelp(XLAT( "Ground level is actually an equidistant surface, " @@ -1438,28 +1434,21 @@ void show3D() { projectionDialog(); else if(uni == 'w' && WDIM == 2) { dialog::editNumber(geom3::wall_height, 0, 1, .1, .3, XLAT("Height of walls"), ""); - dialog::reaction = delayed_geo_reset; dialog::extra_options = [] () { dialog::addHelp(XLAT( "The height of walls, in absolute units. For the current values of g and c, " "wall height of %1 absolute units corresponds to projection value of %2.", - fts(actual_wall_height()), fts(factor_to_projection(geom3::WALL)))); + fts(actual_wall_height()), fts(factor_to_projection(cgi.WALL)))); dialog::addBoolItem(XLAT("auto-adjust in Goldberg grids"), geom3::gp_autoscale_heights, 'O'); dialog::add_action([] () { geom3::gp_autoscale_heights = !geom3::gp_autoscale_heights; - buildpolys(); - #if CAP_GL - resetGL(); - #endif }); }; } else if(uni == 'l' && WDIM == 2) - dialog::editNumber(geom3::lake_top, 0, 1, .1, .25, XLAT("Level of water surface"), ""), - dialog::reaction = delayed_geo_reset; + dialog::editNumber(geom3::lake_top, 0, 1, .1, .25, XLAT("Level of water surface"), ""); else if(uni == 'k' && WDIM == 2) - dialog::editNumber(geom3::lake_bottom, 0, 1, .1, .9, XLAT("Level of water bottom"), ""), - dialog::reaction = delayed_geo_reset; + dialog::editNumber(geom3::lake_bottom, 0, 1, .1, .9, XLAT("Level of water bottom"), ""); else if(uni == 'r' && WDIM == 2) dialog::editNumber(geom3::rock_wall_ratio, 0, 1, .1, .9, XLAT("Rock-III to wall ratio"), ""), dialog::extra_options = [] { dialog::addHelp(XLAT( @@ -1468,11 +1457,9 @@ void show3D() { "ground level.", fts(rock_wall_ratio), fts(wall_height * rock_wall_ratio), fts(cosh(depth - wall_height * rock_wall_ratio) / cosh(depth)))); - }, - dialog::reaction = delayed_geo_reset; + }; else if(uni == 'h' && WDIM == 2) dialog::editNumber(geom3::human_wall_ratio, 0, 1, .1, .7, XLAT("Human to wall ratio"), ""), - dialog::reaction = delayed_geo_reset, dialog::extra_options = [] { dialog::addHelp(XLAT( "Humans are %1 " "absolute units high. Your head travels %2 times the distance travelled by your " @@ -1482,11 +1469,9 @@ void show3D() { ); }; else if(uni == 'h' && WDIM == 3) - dialog::editNumber(geom3::height_width, 0, 1, .1, .7, XLAT("Height to width"), ""), - dialog::reaction = delayed_geo_reset; + dialog::editNumber(geom3::height_width, 0, 1, .1, .7, XLAT("Height to width"), ""); else if(uni == 'c' && WDIM == 3) - dialog::editNumber(geom3::creature_scale, 0, 1, .1, .7, XLAT("Creature scale"), ""), - dialog::reaction = delayed_geo_reset; + dialog::editNumber(geom3::creature_scale, 0, 1, .1, .7, XLAT("Creature scale"), ""); else if(uni == 'e') pushScreen(showStereo); @@ -1566,7 +1551,8 @@ void showCustomizeChar() { transmatrix V = atscreenpos(vid.xres/2, firsty, scale); double alpha = atan2(mousex - vid.xres/2, mousey - firsty) - M_PI/2; - drawMonsterType(moPlayer, NULL, V * spin(alpha), 0, cc_footphase / scale); + V = V * spin(alpha); + drawMonsterType(moPlayer, NULL, V, 0, cc_footphase / scale); quickqueue(); keyhandler = [] (int sym, int uni) { diff --git a/control.cpp b/control.cpp index 9f0f06b9..4c1e17e9 100644 --- a/control.cpp +++ b/control.cpp @@ -300,13 +300,13 @@ void handlePanning(int sym, int uni) { if(conformal::on) conformal::rotation++; else - View = spin(M_PI/S21/2*shiftmul) * View, didsomething = true; + View = spin(M_PI/cgi.S21/2*shiftmul) * View, didsomething = true; } if(sym == SDLK_PAGEDOWN) { if(conformal::on) conformal::rotation++; else - View = spin(-M_PI/S21/2*shiftmul) * View, didsomething = true; + View = spin(-M_PI/cgi.S21/2*shiftmul) * View, didsomething = true; } if(sym == SDLK_PAGEUP || sym == SDLK_PAGEDOWN) @@ -338,7 +338,6 @@ bool handleTune(int sym, int uni) { else if(uni == 'z') bscale7 = bscale6 = 1, brot7 = brot6 = 0; else return false; - resetGeometry(); println(hlog, spaced(bscale7, brot7, bscale6, brot6)); return true; } diff --git a/crystal.cpp b/crystal.cpp index 0ef1db29..9ea85a9d 100644 --- a/crystal.cpp +++ b/crystal.cpp @@ -1025,7 +1025,6 @@ void set_crystal(int sides) { static char buf[20]; sprintf(buf, "{%d,4}", sides); ginf[gCrystal].tiling_name = buf; - need_reset_geometry = true; if(sides < MAX_EDGE) ginf[gCrystal].distlimit = distlimit_table[sides]; } @@ -1329,7 +1328,6 @@ coord euclid3_to_crystal(euclid3::coord x) { void transform_crystal_to_euclid () { euclid3::clear_torus3(); geometry = gCubeTiling; - need_reset_geometry = true; auto e = new euclid3::hrmap_euclid3; auto m = crystal_map(); auto infront = cwt.cpeek(); @@ -1391,7 +1389,6 @@ void transform_euclid_to_crystal () { ginf[gCrystal].sides = 6; ginf[gCrystal].vertex = 4; ginf[gCrystal].tiling_name = "{6,4}"; - need_reset_geometry = true; ginf[gCrystal].distlimit = distlimit_table[6]; auto e = euclid3::cubemap(); diff --git a/debug.cpp b/debug.cpp index 93f7a50b..b94e9dad 100644 --- a/debug.cpp +++ b/debug.cpp @@ -338,7 +338,7 @@ struct debugScreen { if(what) { #if CAP_SHAPES - queuepoly(gmatrix[what], shAsymmetric, 0x80808080); + queuepoly(gmatrix[what], cgi.shAsymmetric, 0x80808080); #endif char buf[200]; sprintf(buf, "%p", what); @@ -682,13 +682,12 @@ int read_cheat_args() { else if(argis("-wef")) { PHASEFROM(2); shift(); int index = argi(); - shift_arg_formula(whatever[index], delayed_geo_reset); + shift_arg_formula(whatever[index]); } else if(argis("-wei")) { PHASEFROM(2); shift(); int index = argi(); shift(); whateveri[index] = argi(); - delayed_geo_reset(); } else if(argis("-W3")) { shift(); top_land = readland(args()); cheat(); diff --git a/drawing.cpp b/drawing.cpp new file mode 100644 index 00000000..0ef93989 --- /dev/null +++ b/drawing.cpp @@ -0,0 +1,1680 @@ + +// implementation of the rendering queue + +// Copyright (C) 2011-2019 Zeno Rogue, see 'hyper.cpp' for details + +namespace hr { + +unsigned char& part(color_t& col, int i) { + unsigned char* c = (unsigned char*) &col; +#if ISMOBILE + return c[i]; +#else +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + return c[sizeof(col) - 1 - i]; +#else + return c[i]; +#endif +#endif + } + +bool fatborder; + +color_t poly_outline; + +// #define STLSORT + +vector> ptds; + +#if CAP_GL +color_t text_color; +int text_shift; +GLuint text_texture; +int texts_merged; +int shapes_merged; + +vector text_vertices; + +#if MINIMIZE_GL_CALLS +color_t triangle_color, line_color; +vector triangle_vertices; +vector line_vertices; +void glapplymatrix(const transmatrix& V); +#endif + +void glflush() { + #if MINIMIZE_GL_CALLS + if(isize(triangle_vertices)) { + // printf("%08X %08X | %d shapes, %d/%d vertices\n", triangle_color, line_color, shapes_merged, isize(triangle_vertices), isize(line_vertices)); + if(triangle_color) { + glhr::be_nontextured(); + glapplymatrix(Id); + glhr::current_vertices = NULL; + glhr::vertices(triangle_vertices); + glhr::color2(triangle_color); + glDrawArrays(GL_TRIANGLES, 0, isize(triangle_vertices)); + } + triangle_vertices.clear(); + } + if(isize(line_vertices)) { + if(line_color) { + glhr::be_nontextured(); + glapplymatrix(Id); + glhr::current_vertices = NULL; + glhr::vertices(line_vertices); + glhr::color2(line_color); + glDrawArrays(GL_LINES, 0, isize(line_vertices)); + } + line_vertices.clear(); + } + shapes_merged = 0; + #endif + + if(isize(text_vertices)) { + // printf("%08X | %d texts, %d vertices\n", text_color, texts_merged, isize(text_vertices)); + glhr::be_textured(); + dynamicval pm(pmodel, mdUnchanged); + if(!svg::in) current_display->set_all(0); + glBindTexture(GL_TEXTURE_2D, text_texture); + glhr::color2(text_color); + glhr::set_depthtest(false); + for(int ed = (current_display->stereo_active() && text_shift)?-1:0; ed<2; ed+=2) { + glhr::set_modelview(glhr::translate(-ed*text_shift-current_display->xcenter,-current_display->ycenter, current_display->scrdist)); + current_display->set_mask(ed); + + glhr::current_vertices = NULL; + glhr::prepare(text_vertices); + glDrawArrays(GL_TRIANGLES, 0, isize(text_vertices)); + + GLERR("print"); + } + + if(current_display->stereo_active() && text_shift && !svg::in) current_display->set_mask(0); + + texts_merged = 0; + text_vertices.clear(); + } + } +#endif + +#if ISMOBILE==0 +SDL_Surface *aux; +#endif + +#if CAP_POLY +#define POLYMAX 60000 + +vector glcoords; + +#endif + +int spherespecial, spherephase; + +#if CAP_POLY +int polyi; + +int polyx[POLYMAX], polyxr[POLYMAX], polyy[POLYMAX]; + +int poly_flags; + +void add1(const hyperpoint& H) { + glcoords.push_back(glhr::pointtogl(H)); + } + +bool is_behind(const hyperpoint& H) { + return pmodel == mdDisk && (hyperbolic ? H[2] >= 0 : true) && vid.alpha + H[2] <= BEHIND_LIMIT; + } + +hyperpoint be_just_on_view(const hyperpoint& H1, const hyperpoint &H2) { + using namespace hyperpoint_vec; + // H1[2] * t + H2[2] * (1-t) == BEHIND_LIMIT - vid.alpha + // H2[2]- BEHIND_LIMIT + vid.alpha = t * (H2[2] - H1[2]) + ld t = (H2[2] - BEHIND_LIMIT + vid.alpha) / (H2[2] - H1[2]); + return H1 * t + H2 * (1-t); + } + +bool last_infront; + +bool nif_error_in(ld x1, ld y1, ld x2, ld y2) { + return pow(x1 * x2 + y2 * y2, 2) < (x1*x1+y1*y1)*(x2*x2+y2*y2)*.5; + } + +bool knowgood; +hyperpoint goodpoint; +vector> tofix; + +bool two_sided_model() { + if(DIM == 3) return false; + if(pmodel == mdHyperboloid) return !euclid; + // if(pmodel == mdHemisphere) return true; + if(pmodel == mdDisk) return sphere; + if(pmodel == mdHemisphere) return true; + if(pmodel == mdRotatedHyperboles) return true; + if(pmodel == mdSpiral && conformal::spiral_cone < 360) return true; + return false; + } + +int get_side(const hyperpoint& H) { + if(pmodel == mdDisk && sphere) { + double curnorm = H[0]*H[0]+H[1]*H[1]+H[2]*H[2]; + double horizon = curnorm / vid.alpha; + return (H[2] <= -horizon) ? -1 : 1; + } + if(pmodel == mdRotatedHyperboles) + return H[1] > 0 ? -1 : 1; + if(pmodel == mdHyperboloid && hyperbolic) + return (conformal::sin_ball * H[2] > -conformal::cos_ball * H[1]) ? -1 : 1; + if(pmodel == mdHyperboloid && sphere) + return (conformal::sin_ball * H[2] > conformal::cos_ball * H[1]) ? -1 : 1; + if(pmodel == mdHemisphere) { + hyperpoint res; + applymodel(H, res); + return res[2] < 0 ? -1 : 1; + } + if(pmodel == mdSpiral && conformal::spiral_cone < 360) { + return cone_side(H); + } + return 0; + } + +bool correct_side(const hyperpoint& H) { + return get_side(H) == spherespecial; + } + +hyperpoint Hlast; + +void fixpoint(glvertex& hscr, hyperpoint H) { + hyperpoint bad = H, good = goodpoint; + + for(int i=0; i<10; i++) { + hyperpoint mid = midz(bad, good); + if(correct_side(mid)) + good = mid; + else + bad = mid; + } + hyperpoint Hscr; + applymodel(good, Hscr); + hscr = glhr::makevertex(Hscr[0]*current_display->radius, Hscr[1]*current_display->radius*vid.stretch, Hscr[2]*current_display->radius); + } + +void addpoint(const hyperpoint& H) { + if(true) { + ld z = current_display->radius; + // if(vid.alpha + H[2] <= BEHIND_LIMIT && pmodel == mdDisk) poly_flags |= POLY_BEHIND; + + if(spherespecial) { + + if(correct_side(H)) { + poly_flags |= POLY_INFRONT, last_infront = false; + if(!knowgood || (spherespecial > 0 ? H[2]>goodpoint[2] : H[2]stereo_active()) glcoords[i][2] = 0; + + polyx[i] = current_display->xcenter + glcoords[i][0] - glcoords[i][2]; + polyxr[i] = current_display->xcenter + glcoords[i][0] + glcoords[i][2]; + polyy[i] = current_display->ycenter + glcoords[i][1]; + } + } + +void addpoly(const transmatrix& V, const vector &tab, int ofs, int cnt) { + if(pmodel == mdFlatten) { + for(int i=ofs; i(Hscr[0]*current_display->radius+10, Hscr[1]*current_display->radius*vid.stretch, Hscr[2]*vid.radius)); + glcoords.push_back(make_array(Hscr[0]*current_display->radius, Hscr[1]*current_display->radius*vid.stretch+10, Hscr[2]*vid.radius)); + glcoords.push_back(make_array(Hscr[0]*current_display->radius-10, Hscr[1]*current_display->radius*vid.stretch, Hscr[2]*vid.radius)); + glcoords.push_back(make_array(Hscr[0]*current_display->radius, Hscr[1]*current_display->radius*vid.stretch-10, Hscr[2]*vid.radius)); + glcoords.push_back(make_array(Hscr[0]*current_display->radius+10, Hscr[1]*current_display->radius*vid.stretch, Hscr[2]*vid.radius)); */ + } + } + +#if CAP_SDLGFX +void aapolylineColor(SDL_Surface *s, int*x, int *y, int polyi, color_t col) { + for(int i=1; i spx(px, px + polyi); + std::vector spy(py, py + polyi); + filledPolygonColor(s, spx.data(), spy.data(), polyi, col); + } +#endif + +#if CAP_TEXTURE +void drawTexturedTriangle(SDL_Surface *s, int *px, int *py, glvertex *tv, color_t col) { + transmatrix source = {{{ld(px[0]),ld(px[1]),ld(px[2])}, {ld(py[0]),ld(py[1]),ld(py[2])}, {1,1,1}}}; + transmatrix target = {{{tv[0][0],tv[1][0],tv[2][0]}, {tv[0][1],tv[1][1],tv[2][1]}, {1,1,1}}}; + transmatrix isource = inverse(source); + int minx = px[0], maxx = px[0]; + int miny = py[0], maxy = py[0]; + for(int i=1; i<3; i++) + minx = min(minx, px[i]), maxx = max(maxx, px[i]), + miny = min(miny, py[i]), maxy = max(maxy, py[i]); + for(int mx=minx; mx= -1e-7 && h[1] >= -1e-7 && h[2] >= -1e-7) { + hyperpoint ht = target * h; + int tw = texture::config.data.twidth; + int x = int(ht[0] * tw) & (tw-1); + int y = int(ht[1] * tw) & (tw-1); + color_t c = texture::config.data.texture_pixels[y * tw + x]; + auto& pix = qpixel(s, mx, my); + for(int p=0; p<3; p++) { + int alpha = part(c, 3) * part(col, 0); + auto& v = part(pix, p); + v = ((255*255 - alpha) * 255 * v + alpha * part(col, p+1) * part(c, p) + 255 * 255 * 255/2 + 1) / (255 * 255 * 255); + } + } + } + } +#endif + +#if CAP_GL + +void glapplymatrix(const transmatrix& V) { + GLfloat mat[16]; + int id = 0; + if(pmodel == mdPerspective && DIM == 3) { + if(spherephase & 4) { + for(int y=0; y<4; y++) { + for(int x=0; x<4; x++) mat[id++] = -V[x][y]; + } + } + else { + for(int y=0; y<4; y++) { + for(int x=0; x<4; x++) mat[id++] = V[x][y]; + } + } + glhr::set_modelview(glhr::as_glmatrix(mat)); + return; + } + + if(DIM == 3) { + for(int y=0; y<4; y++) + for(int x=0; x<4; x++) mat[id++] = V[x][y]; + } + else { + for(int y=0; y<3; y++) { + for(int x=0; x<3; x++) mat[id++] = V[x][y]; + mat[id++] = 0; + } + mat[12] = 0; + mat[13] = 0; + if(glhr::current_shader_projection != glhr::shader_projection::band) + mat[14] = GLfloat(vid.alpha); + else + mat[14] = 0; + mat[15] = 1; + } + + if(vid.stretch != 1) mat[1] *= vid.stretch, mat[5] *= vid.stretch, mat[9] *= vid.stretch, mat[13] *= vid.stretch; + + if(conformal::model_has_orientation()) { + if(DIM == 3) for(int a=0; a<4; a++) + conformal::apply_orientation_yz(mat[a*4+1], mat[a*4+2]); + for(int a=0; a<4; a++) + conformal::apply_orientation(mat[a*4], mat[a*4+1]); + } + + glhr::set_modelview(glhr::as_glmatrix(mat)); + } + +int global_projection; + +#if MAXMDIM >= 4 +extern renderbuffer *floor_textures; +#endif + +void dqi_poly::gldraw() { + auto& v = *tab; + int ioffset = offset; + +#if MINIMIZE_GL_CALLS + if(current_display->stereo_active() == 0 && !tinf && (color == 0 || ((flags & (POLY_VCONVEX | POLY_CCONVEX)) && !(flags & (POLY_INVERSE | POLY_FORCE_INVERTED))))) { + if(color != triangle_color || outline != line_color || texts_merged) { + glflush(); + triangle_color = color; + line_color = outline; + } + shapes_merged++; + + if((flags & POLY_CCONVEX) && !(flags & POLY_VCONVEX)) { + vector v2(cnt+1); + for(int i=0; i v2(cnt); + for(int i=0; itexture_id); + glhr::vertices_texture(v, tinf->tvertices, offset, offset_texture); + ioffset = 0; + #endif + } + else { + glhr::be_nontextured(); + + #if !ISANDROID + glhr::vertices(v); + #else + if(glhr::current_vertices != &v[offset]) { + glhr::current_vertices = &v[offset]; + glVertexAttribPointer(glhr::aPosition, 3, GL_FLOAT, GL_FALSE, sizeof(glvertex), &v[offset]); + // glVertexPointer(3, GL_FLOAT, sizeof(glvertex), &v[ps]); + // glhr::vertices(v); + } + offset = 0; + #endif + } + + for(int ed = current_display->stereo_active() ? -1 : 0; ed<2; ed+=2) { + if(global_projection && global_projection != ed) continue; + current_display->set_all(ed); + bool draw = color; + + if(shaderside_projection) { + if(glhr::current_shader_projection == glhr::shader_projection::band && V[2][2] > 1e8) continue; + glapplymatrix(V); + } + + if(draw) { + if(flags & POLY_TRIANGLES) { + glhr::color2(color, (flags & POLY_INTENSE) ? 2 : 1); + glhr::set_depthtest(model_needs_depth() && prio < PPR::SUPERLINE); + glhr::set_depthwrite(model_needs_depth() && prio != PPR::TRANSPARENT_SHADOW); + glhr::set_fogbase(prio == PPR::SKY ? 1.0 + 5 / sightranges[geometry] : 1.0); + glDrawArrays(GL_TRIANGLES, ioffset, cnt); + } + else { + glEnable(GL_STENCIL_TEST); + + glColorMask( GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE ); + glhr::set_depthtest(false); + glStencilOp( GL_INVERT, GL_INVERT, GL_INVERT); + glStencilFunc( GL_ALWAYS, 0x1, 0x1 ); + glhr::color2(0xFFFFFFFF); + glDrawArrays(tinf ? GL_TRIANGLES : GL_TRIANGLE_FAN, offset, cnt); + + current_display->set_mask(ed); + glhr::color2(color); + glhr::set_depthtest(model_needs_depth() && prio < PPR::SUPERLINE); + glhr::set_depthwrite(model_needs_depth() && prio != PPR::TRANSPARENT_SHADOW); + + if(flags & (POLY_INVERSE | POLY_FORCE_INVERTED)) { + glStencilOp( GL_ZERO, GL_ZERO, GL_ZERO); + glStencilFunc( GL_NOTEQUAL, 1, 1); + GLfloat xx = vid.xres; + GLfloat yy = vid.yres; + GLfloat dist = shaderside_projection ? current_display->scrdist : 0; + vector scr = { + glhr::makevertex(-xx, -yy, dist), + glhr::makevertex(+xx, -yy, dist), + glhr::makevertex(+xx, +yy, dist), + glhr::makevertex(-xx, +yy, dist) + }; + glhr::vertices(scr); + glhr::id_modelview(); + glDrawArrays(tinf ? GL_TRIANGLES : GL_TRIANGLE_FAN, 0, 4); + glhr::vertices(v); + if(shaderside_projection) glapplymatrix(V); + } + else { + glStencilOp( GL_ZERO, GL_ZERO, GL_ZERO); + glStencilFunc( GL_EQUAL, 1, 1); + glDrawArrays(tinf ? GL_TRIANGLES : GL_TRIANGLE_FAN, offset, cnt); + } + + glDisable(GL_STENCIL_TEST); + } + } + + if(outline && !(flags & POLY_TRIANGLES)) { + glhr::color2(outline); + glhr::set_depthtest(model_needs_depth() && prio < PPR::SUPERLINE); + glDrawArrays(GL_LINE_STRIP, offset, cnt); + } + } + } +#endif + +ld scale_at(const transmatrix& T) { + if(DIM == 3 && pmodel == mdPerspective) return 1 / (tC0(T))[2]; + using namespace hyperpoint_vec; + hyperpoint h1, h2, h3; + applymodel(tC0(T), h1); + applymodel(T * xpush0(.01), h2); + applymodel(T * ypush(.01) * C0, h3); + return sqrt(hypot_d(2, h2-h1) * hypot_d(2, h3-h1) / .0001); + } + +ld linewidthat(const hyperpoint& h) { + if(!(vid.antialias & AA_LINEWIDTH)) return 1; + else if(hyperbolic && pmodel == mdDisk && vid.alpha == 1) { + double dz = h[DIM]; + if(dz < 1 || abs(dz-current_display->scrdist) < 1e-6) return 1; + else { + double dx = sqrt(dz * dz - 1); + double dfc = dx/(dz+1); + dfc = 1 - dfc*dfc; + return dfc; + } + } + else if(svg::in || inHighQual) { + using namespace hyperpoint_vec; + hyperpoint h0 = h / zlevel(h); + transmatrix T = rgpushxto0(h0); + return scale_at(T); + } + return 1; + } + +// -radius to +3radius + +int mercator_coord; +int mercator_loop_min = 0, mercator_loop_max = 0; +ld mercator_period; + +void fixMercator(bool tinf) { + + if(pmodel == mdBand) + mercator_period = 4 * current_display->radius; + else + mercator_period = 2 * current_display->radius; + + if(!conformal::model_straight) + for(auto& g: glcoords) + conformal::apply_orientation(g[0], g[1]); + + if(pmodel == mdSinusoidal) + for(int i = 0; iradius / vid.stretch * M_PI); + + ld hperiod = mercator_period / 2; + + mercator_coord = 0; + + auto dist = [] (ld a, ld b) { return max(b, a-b); }; + + ld chypot = hypot(dist(vid.xres, current_display->xcenter), dist(vid.yres, current_display->ycenter)); + + ld cmin = -chypot/2, cmax = chypot/2, dmin = -chypot, dmax = chypot; + + if(mercator_coord) + swap(cmin, dmin), swap(cmax, dmax); + if(pmodel == mdSinusoidal) + dmin = -vid.stretch * current_display->radius / 2, dmax = vid.stretch * current_display->radius / 2; + if(pmodel == mdBandEquidistant) + dmin = -vid.stretch * current_display->radius / 2, dmax = vid.stretch * current_display->radius / 2; + if(pmodel == mdBandEquiarea) + dmin = -vid.stretch * current_display->radius / M_PI, dmax = vid.stretch * current_display->radius / M_PI; + + for(int i = 0; i hperiod) glcoords[0][mercator_coord] -= mercator_period; + } + + ld first = glcoords[0][mercator_coord]; + ld next = first; + + ld mincoord = first, maxcoord = first; + + for(int i = 0; i next + hperiod) + glcoords[i][mercator_coord] -= mercator_period; + next = glcoords[i][mercator_coord]; + mincoord = min(mincoord, glcoords[i][mercator_coord]); + maxcoord = max(maxcoord, glcoords[i][mercator_coord]); + } + + if(abs(mincoord) > 50000 || abs(maxcoord) > 50000 || std::isnan(mincoord) || std::isnan(maxcoord)) { + mercator_loop_max--; + return; + } + + ld last = first; + while(last < next - hperiod) last += mercator_period; + while(last > next + hperiod) last -= mercator_period; + + if(first == last) { + while(mincoord > cmin) + mercator_loop_min--, mincoord -= mercator_period; + while(maxcoord < cmax) + mercator_loop_max++, maxcoord += mercator_period; + if(pmodel == mdSinusoidal) + for(int i = 0; iradius / vid.stretch * M_PI); + if(!conformal::model_straight) + for(auto& g: glcoords) + conformal::apply_orientation(g[1], g[0]); + } + else { + if(tinf) { + // this cannot work in Mercator + mercator_loop_max--; return; + } + if(last < first) { + reverse(glcoords.begin(), glcoords.end()); + swap(first, last); + } + while(maxcoord > cmin) { + for(int i=0; iradius / vid.stretch * M_PI); + glcoords.push_back(glcoords.back()); + glcoords.push_back(glcoords[0]); + for(int u=1; u<=2; u++) { + auto& v = glcoords[isize(glcoords)-u][1-mercator_coord]; + v = v < 0 ? dmin : dmax; + } + if(!conformal::model_straight) + for(auto& g: glcoords) + conformal::apply_orientation(g[1], g[0]); + /* printf("cycling %d -> %d\n", base, qglcoords); + for(int a=0; aV * p->intester; + if(is_behind(h1)) { + if(sphere) { + for(int i=0; i<3; i++) h1[i] = -h1[i]; + poly_flags &= ~POLY_CENTERIN; + } + else + nofill = true; + } + applymodel(h1, hscr); hscr[0] *= current_display->radius; hscr[1] *= current_display->radius * vid.stretch; + for(int i=0; iV)) - 1) > 1e-6) nofill = true; + + /* nofill = true; + outline = (flags & POLY_CENTERIN) ? 0x00FF00FF : 0xFF0000FF; + addpoint(hscr); */ + } + + /* + if(poly_flags & POLY_BADCENTERIN) { + glcoords.push_back(glhr::makevertex(hscr[0]+10, hscr[1]*vid.stretch, hscr[2])); + glcoords.push_back(glhr::makevertex(hscr[0], hscr[1]*vid.stretch+10, hscr[2])); + glcoords.push_back(glhr::makevertex(hscr[0]-10, hscr[1]*vid.stretch, hscr[2])); + glcoords.push_back(glhr::makevertex(hscr[0], hscr[1]*vid.stretch-10, hscr[2])); + glcoords.push_back(glhr::makevertex(hscr[0]+10, hscr[1]*vid.stretch, hscr[2])); + } */ + } + +void compute_side_by_area() { + + double rarea = 0; + for(int i=0; i0) + poly_flags ^= POLY_INVERSE; + } + +ld get_width(dqi_poly* p) { + if(p->flags & POLY_PRECISE_WIDE) { + ld maxwidth = 0; + for(int i=0; icnt; i++) { + hyperpoint h1 = p->V * glhr::gltopoint((*p->tab)[p->offset+i]); + maxwidth = max(maxwidth, linewidthat(h1)); + } + return maxwidth * p->linewidth; + } + else if(p->flags & POLY_FORCEWIDE) + return p->linewidth; + else + return linewidthat(tC0(p->V)) * p->linewidth; + } + +void dqi_poly::draw() { + + dynamicval bs(hr::band_shift, band_shift); + if(!hyperbolic && among(pmodel, mdPolygonal, mdPolynomial)) { + bool any = false; + for(int i=0; i 0) any = true; + } + if(!any) return; + } + + if(sphere && tinf && DIM == 2 && cnt > 3) { + int i = cnt; + cnt = 3; + for(int j=0; j phases[MAX_PHASE]; + extern int twopoint_sphere_flips; + extern bool twopoint_do_flips; + int pha; + if(twopoint_do_flips) { + for(int i=0; iradius); h[1] *= vid.stretch; + if(i == 0) + phases[j].push_back(h); + else { + int best = -1; + ld bhypot = 1e60; + for(int j0=0; j0radius)); + + // check if the i-th edge intersects the boundary of the ellipse + // (which corresponds to the segment between the antipodes of foci) + // if yes, switch cpha to the opposite + hyperpoint h2 = V * glhr::gltopoint((*tab)[offset+(i+1)%cnt]); + + hyperpoint ah1 = h1, ah2 = h2; + conformal::apply_orientation(ah1[0], ah1[1]); + conformal::apply_orientation(ah2[0], ah2[1]); + if(ah1[1] * ah2[1] > 0) continue; + ld c1 = ah1[1], c2 = -ah2[1]; + if(c1 < 0) c1 = -c1, c2 = -c2; + hyperpoint h = ah1 * c1 + ah2 * c2; + h /= hypot_d(3, h); + if(h[2] < 0 && abs(h[0]) < sin(vid.twopoint_param)) cpha = 1-cpha, pha = 2; + } + if(cpha == 1) pha = 0; + } + } + dynamicval d1(pmodel, mdUnchanged); + dynamicval d2(V, Id); + dynamicval d3(offset, 0); + dynamicval d4(tab, tab); + for(int j=0; j d5(cnt, isize(phases[j])); + tab = &phases[j]; + draw(); + } + return; + } + + /* if(spherespecial && prio == PPR::MOBILE_ARROW) { + if(spherephase == 0) return; + dynamicval ss(spherespecial, 0); + draw(); + return; + } */ + +#if CAP_GL + if(vid.usingGL && (current_display->set_all(global_projection), shaderside_projection)) { + glLineWidth(get_width(this)); + flags &= ~POLY_INVERSE; + gldraw(); + return; + } +#endif + + glcoords.clear(); + poly_flags = flags; + + double d = 0, curradius = 0; + if(sphere) { + d = det(V); + curradius = pow(abs(d), 1/3.); + } + + /* outline = 0x80808080; + color = 0; */ + + last_infront = false; + + addpoly(V, *tab, offset, cnt); + if(!(sphere && vid.alpha < .9)) if(pmodel != mdJoukowsky) if(!(flags & POLY_ALWAYS_IN)) for(int i=1; i vid.xres * 2 || dy > vid.yres * 2) return; + } + if(poly_flags & POLY_BEHIND) return; + if(isize(glcoords) <= 1) return; + + mercator_loop_min = mercator_loop_max = 0; + if(sphere && mdBandAny()) + fixMercator(tinf); + + int poly_limit = max(vid.xres, vid.yres) * 2; + + + if(0) for(auto& p: glcoords) { + if(abs(p[0]) > poly_limit || abs(p[1]) > poly_limit) + return; // too large! + } + + bool equi = mdAzimuthalEqui() || pmodel == mdFisheye; + + bool nofill = false; + + if(poly_flags & POLY_NIF_ERROR) return; + + if(spherespecial == 1 && sphere && (poly_flags & POLY_INFRONT) && (poly_flags & POLY_NOTINFRONT) && vid.alpha <= 1) { + bool around_center = false; + for(int i=0; i 0 || equi)) can_have_inverse = true; + if(pmodel == mdJoukowsky) can_have_inverse = true; + if(pmodel == mdJoukowskyInverted && vid.skiprope) can_have_inverse = true; + if(pmodel == mdDisk && hyperbolic && vid.alpha <= -1) can_have_inverse = true; + if(pmodel == mdSpiral && vid.skiprope) can_have_inverse = true; + + if(can_have_inverse && !(poly_flags & POLY_ISSIDE)) { + + if(!tinf) + compute_side_by_centerin(this, nofill); + + else { + if(d < 0) poly_flags ^= POLY_INVERSE; + compute_side_by_area(); + } + + if(poly_flags & POLY_INVERSE) { + if(curradius < vid.alpha - 1e-6) return; + if(!sphere) return; + } + + } + else poly_flags &=~ POLY_INVERSE; + + if(spherespecial) { + if(!hiliteclick && !(poly_flags & POLY_INFRONT)) return; + } + + int lastl = 0; + + for(int l=mercator_loop_min; l <= mercator_loop_max; l++) { + + if(l || lastl) { + for(int i=0; iradius * cos(y / current_display->radius / vid.stretch * M_PI); + } + glcoords[i][mercator_coord] += conformal::ocos * mercator_period * (l - lastl); + glcoords[i][1-mercator_coord] += conformal::osin * mercator_period * (l - lastl); + } + lastl = l; + } + + if(equi && (poly_flags & POLY_INVERSE)) { + if(abs(zlevel(V * C0) - 1) < 1e-6 && !tinf) { + // we should fill the other side + ld h = atan2(glcoords[0][0], glcoords[0][1]); + for(int i=0; i<=360; i++) { + ld a = i * degree + h; + glcoords.push_back(glhr::makevertex(current_display->radius * sin(a), current_display->radius * vid.stretch * cos(a), current_display->scrdist)); + } + poly_flags ^= POLY_INVERSE; + } + else { + // If we are on a zlevel, the algorithm above will not work correctly. + // It is hard to tell what to do in this case. Just fill neither side + nofill = true; + } + } + + #if CAP_GL + if(vid.usingGL) { + poly_flags &= ~(POLY_VCONVEX | POLY_CCONVEX); + // if(pmodel == 0) for(int i=0; iscrdist; + if(tinf && (poly_flags & POLY_INVERSE)) { + return; + } + glLineWidth(get_width(this)); + dqi_poly npoly = (*this); + npoly.V = Id; + npoly.tab = &glcoords; + npoly.offset = 0; + npoly.cnt = isize(glcoords); + if(nofill) npoly.color = 0, npoly.tinf = NULL; + npoly.flags = poly_flags; + npoly.gldraw(); + continue; + } + #endif + + #if CAP_SVG==1 + if(svg::in) { + coords_to_poly(); + color_t col = color; + if(poly_flags & POLY_INVERSE) col = 0; + svg::polygon(polyx, polyy, polyi, col, outline, get_width(this)); + continue; + } + #endif + + coords_to_poly(); + + #if CAP_XGD==1 + gdpush(1); gdpush(color); gdpush(outline); gdpush(polyi); + for(int i=0; itvertices[offset_texture + i], color); + #endif + } + else if(poly_flags & POLY_INVERSE) { + int i = polyi; + if(true) { + polyx[i] = 0; polyy[i] = 0; i++; + polyx[i] = vid.xres; polyy[i] = 0; i++; + polyx[i] = vid.xres; polyy[i] = vid.yres; i++; + polyx[i] = 0; polyy[i] = vid.yres; i++; + polyx[i] = 0; polyy[i] = 0; i++; + } + filledPolygonColorI(s, polyx, polyy, polyi+5, color); + } + else + filledPolygonColorI(s, polyx, polyy, polyi, color); + + if(current_display->stereo_active()) filledPolygonColorI(aux, polyxr, polyy, polyi, color); + + ((vid.antialias & AA_NOGL) ?aapolylineColor:polylineColor)(s, polyx, polyy, polyi, outline); + if(current_display->stereo_active()) aapolylineColor(aux, polyxr, polyy, polyi, outline); + + if(vid.xres >= 2000 || fatborder) { + int xmi = 3000, xma = -3000; + for(int t=0; t xmi + 20) for(int x=-1; x<2; x++) for(int y=-1; y<=2; y++) if(x*x+y*y == 1) { + for(int t=0; t prettylinepoints; + +void prettypoint(const hyperpoint& h) { + prettylinepoints.push_back(glhr::pointtogl(h)); + } + +void prettylinesub(const hyperpoint& h1, const hyperpoint& h2, int lev) { + if(lev >= 0) { + hyperpoint h3 = midz(h1, h2); + prettylinesub(h1, h3, lev-1); + prettylinesub(h3, h2, lev-1); + } + else prettypoint(h2); + } + +void prettyline(hyperpoint h1, hyperpoint h2, color_t col, int lev, int flags, PPR prio) { + prettylinepoints.clear(); + prettypoint(h1); + prettylinesub(h1, h2, lev); + dqi_poly ptd; + ptd.V = Id; + ptd.band_shift = band_shift; + ptd.tab = &prettylinepoints; + ptd.offset = 0; + ptd.cnt = isize(prettylinepoints); + ptd.linewidth = vid.linewidth; + ptd.color = 0; + ptd.outline = col; + ptd.flags = POLY_ISSIDE | POLY_PRECISE_WIDE | flags; + ptd.tinf = NULL; + ptd.intester = C0; + ptd.prio = prio; + ptd.draw(); + } + +void prettypoly(const vector& t, color_t fillcol, color_t linecol, int lev) { + prettylinepoints.clear(); + prettypoint(t[0]); + for(int i=0; i curvedata; +int curvestart = 0; +bool keep_curvedata = false; + +void queuereset(eModel m, PPR prio) { + queueaction(prio, [m] () { pmodel = m; }); + } + +void dqi_line::draw() { + dynamicval d(vid.linewidth, width); + dynamicval bs(hr::band_shift, band_shift); + prettyline(H1, H2, color, prf, 0, prio); + } + +void dqi_string::draw() { + #if CAP_SVG + if(svg::in) { + svg::text(x, y, size, str, frame, color, align); + return; + } + #endif + #if ISMOBILE==0 + int fr = frame & 255; + displayfrSP(x, y, shift, fr, size, str, color, align, frame >> 8); + #else + displayfr(x, y, frame, size, str, color, align); + #endif + } + +void dqi_circle::draw() { + #if CAP_SVG + if(svg::in) { + svg::circle(x, y, size, color, fillcolor, linewidth); + } + else + #endif + drawCircle(x, y, size, color, fillcolor); + } + +void initquickqueue() { + ptds.clear(); + poly_outline = OUTLINE_NONE; + } + +void sortquickqueue() { + for(int i=1; iprio < ptds[i-1]->prio) { + swap(ptds[i], ptds[i-1]); + i--; + } + else i++; + } + +void quickqueue() { + spherespecial = 0; + reset_projection(); current_display->set_all(0); + int siz = isize(ptds); + for(int i=0; idraw(); + ptds.clear(); + } + +ld xintval(const hyperpoint& h) { + if(sphereflipped()) return -h[2]; + return -intval(h, C0); + } + +ld backbrightness = .25; + +purehookset hook_drawqueue; + +constexpr int PMAX = int(PPR::MAX); +int qp[PMAX], qp0[PMAX]; + +color_t darken_color(color_t& color, bool outline) { + int alpha = color & 255; + if(sphere && pmodel == mdDisk && vid.alpha <= 1) + return 0; + else { + if(outline && alpha < 255) + return color - alpha + int(backbrightness * alpha); + else + return (gradient(modelcolor>>8, color>>8, 0, backbrightness, 1)<<8) | 0xFF; + } + } + +void dqi_poly::draw_back() { + dynamicval dvo(outline, darken_color(outline, true)); + dynamicval dvc(color, darken_color(color, false)); + draw(); + } + +void dqi_line::draw_back() { + dynamicval dvc(color, darken_color(color, true)); + draw(); + } + +void sort_drawqueue() { + + for(int a=0; a>> subqueue; + for(auto& p: ptds) subqueue[p->prio == PPR::CIRCLE ? 0 : p->outline_group()].push_back(move(p)); + ptds.clear(); + for(auto& p: subqueue) for(auto& r: p.second) ptds.push_back(move(r)); + subqueue.clear(); + for(auto& p: ptds) subqueue[p->prio == PPR::CIRCLE ? 0 : p->color].push_back(move(p)); + ptds.clear(); + for(auto& p: subqueue) for(auto& r: p.second) ptds.push_back(move(r)); + #endif + + for(auto& p: ptds) { + int pd = p->prio - PPR::ZERO; + if(pd < 0 || pd >= PMAX) { + printf("Illegal priority %d\n", pd); + p->prio = PPR(rand() % int(PPR::MAX)); + } + qp[pd]++; + } + + int total = 0; + for(int a=0; a> ptds2; + ptds2.resize(siz); + + for(int i = 0; iprio)]++] = move(ptds[i]); + swap(ptds, ptds2); + } + +void reverse_priority(PPR p) { + reverse(ptds.begin()+qp0[int(p)], ptds.begin()+qp[int(p)]); + } + +void reverse_side_priorities() { + for(PPR p: {PPR::REDWALLs, PPR::REDWALLs2, PPR::REDWALLs3, PPR::WALL3s, + PPR::LAKEWALL, PPR::INLAKEWALL, PPR::BELOWBOTTOM}) + reverse_priority(p); + } + +// on the sphere, parts on the back are drawn first +void draw_backside() { + if(pmodel == mdHyperboloid && hyperbolic) { + dynamicval dv (pmodel, mdHyperboloidFlat); + for(auto& ptd: ptds) + if(!among(ptd->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE)) + ptd->draw(); + } + + spherespecial = sphereflipped() ? 1 : -1; + reset_projection(); + + if(pmodel == mdRotatedHyperboles) { + for(auto& ptd: ptds) + if(!among(ptd->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE)) + ptd->draw(); + glflush(); + } + else { + reverse_side_priorities(); + for(int i=ptds.size()-1; i>=0; i--) + if(!among(ptds[i]->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE)) + ptds[i]->draw_back(); + + glflush(); + reverse_side_priorities(); + } + + spherespecial *= -1; + spherephase = 1; + reset_projection(); + } + +extern bool lshiftclick, lctrlclick; + +void reverse_transparent_walls() { + int pt = int(PPR::TRANSPARENT_WALL); + reverse(&ptds[qp0[pt]], &ptds[qp[pt]]); + } + +void draw_main() { + if(sphere && DIM == 3 && pmodel == mdPerspective) { + for(int p: {1, 0, 2, 3}) { + if(elliptic && p < 2) continue; + glhr::set_depthwrite(true); + if(p == 0 || p == 3) { + #ifdef GL_ES + glClearDepthf(1.0f); + #else + glClearDepth(1.0f); + #endif + glDepthFunc(GL_LEQUAL); + } + else { + #ifdef GL_ES + glClearDepthf(0.0f); + #else + glClearDepth(0.0f); + #endif + glDepthFunc(GL_GEQUAL); + } + glClear(GL_DEPTH_BUFFER_BIT); + glhr::be_nontextured(); + spherephase = p; + reset_projection(); + for(auto& ptd: ptds) ptd->draw(); + if(elliptic) { + spherephase = p | 4; + reset_projection(); + for(auto& ptd: ptds) ptd->draw(); + } + // glflush(); + } + } + else { + 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) { + dynamicval ss(spherespecial, among(ptd->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE) ? 0 : spherespecial); + ptd->draw(); + } + glflush(); + } + } + + +void drawqueue() { + callhooks(hook_drawqueue); + reset_projection(); + // reset_projection() is not sufficient here, because we need to know shaderside_projection + +#if CAP_GL + if(vid.usingGL) + glClear(GL_STENCIL_BUFFER_BIT); +#endif + + profile_start(3); + + sort_drawqueue(); + + for(PPR p: {PPR::REDWALLs, PPR::REDWALLs2, PPR::REDWALLs3, PPR::WALL3s, + PPR::LAKEWALL, PPR::INLAKEWALL, PPR::BELOWBOTTOM}) + if(DIM == 2) sort(&ptds[qp0[int(p)]], &ptds[qp[int(p)]], + [] (const unique_ptr& p1, const unique_ptr& p2) { + auto ap1 = (dqi_poly&) *p1; + auto ap2 = (dqi_poly&) *p2; + return xintval(ap1.V * xpush0(.1)) + < xintval(ap2.V * xpush0(.1)); + }); + + for(PPR p: {PPR::TRANSPARENT_WALL}) + sort(&ptds[qp0[int(p)]], &ptds[qp[int(p)]], + [] (const unique_ptr& p1, const unique_ptr& p2) { + return p1->subprio > p2->subprio; + }); + + profile_stop(3); + +#if CAP_SDL + if(current_display->stereo_active() && !vid.usingGL) { + + if(aux && (aux->w != s->w || aux->h != s->h)) + SDL_FreeSurface(aux); + + if(!aux) { + aux = SDL_CreateRGBSurface(SDL_SWSURFACE,s->w,s->h,32,0,0,0,0); + } + + // SDL_LockSurface(aux); + // memset(aux->pixels, 0, vid.xres * vid.yres * 4); + // SDL_UnlockSurface(aux); + SDL_BlitSurface(s, NULL, aux, NULL); + } +#endif + + spherespecial = 0; + spherephase = 0; + reset_projection(); + + if(model_needs_depth() && current_display->stereo_active()) { + global_projection = -1; + draw_main(); + glClear(GL_DEPTH_BUFFER_BIT); + global_projection = +1; + draw_main(); + } + else { + draw_main(); + } + +#if CAP_SDL + if(vid.stereo_mode == sAnaglyph && !vid.usingGL) { + int qty = s->w * s->h; + int *a = (int*) s->pixels; + int *b = (int*) aux->pixels; + SDL_LockSurface(aux); + while(qty) { + *a = ((*a) & 0xFF0000) | ((*b) & 0x00FFFF); + a++; b++; qty--; + } + SDL_UnlockSurface(aux); + } + + if(vid.stereo_mode == sLR && !vid.usingGL) { + SDL_LockSurface(aux); + for(int y=0; y T& queuea(PPR prio, U... u) { + ptds.push_back(unique_ptr(new T (u...))); + ptds.back()->prio = prio; + return (T&) *ptds.back(); + } + +#if CAP_SHAPES +dqi_poly& queuepolyat(const transmatrix& V, const hpcshape& h, color_t col, PPR prio) { + if(prio == PPR::DEFAULT) prio = h.prio; + + auto& ptd = queuea (prio); + + ptd.V = V; + ptd.band_shift = band_shift; + ptd.offset = h.s; + ptd.cnt = h.e-h.s; + ptd.tab = &cgi.ourshape; + if(cblind) { + // protanopia + /* int r = (56 * part(col,3) + 43 * part(col,2)) / 100; + int g = (58 * part(col,3) + 42 * part(col,2)) / 100; + int b = (24 * part(col,2) + 75 * part(col,1)) / 100; */ + // deuteranopia + /* int r = (625 * part(col,3) + 375 * part(col,2)) / 1000; + int g = (700 * part(col,3) + 300 * part(col,2)) / 1000; + int b = (300 * part(col,2) + 700 * part(col,1)) / 1000; + part(col,3) = r; + part(col,2) = g; + part(col,1) = b; */ + part(col,2) = part(col,3) = (part(col,2) * 2 + part(col,3) + 1)/3; + } + ptd.color = (darkened(col >> 8) << 8) + (col & 0xFF); + ptd.outline = poly_outline; + ptd.linewidth = vid.linewidth; + ptd.flags = h.flags; + ptd.tinf = h.tinf; + ptd.offset_texture = h.texture_offset; + ptd.intester = h.intester; + return ptd; + } +#endif + +void addfloats(vector& v, hyperpoint h) { + for(int i=0; i<3; i++) v.push_back(h[i]); + } + +dqi_poly& queuetable(const transmatrix& V, const vector& f, int cnt, color_t linecol, color_t fillcol, PPR prio) { + + auto& ptd = queuea (prio); + + ptd.V = V; + ptd.band_shift = band_shift; + ptd.tab = &f; + ptd.offset = 0; + ptd.cnt = cnt; + ptd.color = fillcol; + ptd.outline = linecol; + ptd.linewidth = vid.linewidth; + ptd.flags = POLY_ISSIDE | POLY_PRECISE_WIDE; + ptd.tinf = NULL; + ptd.intester = C0; + return ptd; + } + +#if CAP_SHAPES +dqi_poly& queuepoly(const transmatrix& V, const hpcshape& h, color_t col) { + return queuepolyat(V,h,col,h.prio); + } + +void queuepolyb(const transmatrix& V, const hpcshape& h, color_t col, int b) { + queuepolyat(V,h,col,h.prio+b); + } +#endif + +void curvepoint(const hyperpoint& H1) { + curvedata.push_back(glhr::pointtogl(H1)); + } + +dqi_poly& queuecurve(color_t linecol, color_t fillcol, PPR prio) { + auto &res = queuetable(Id, curvedata, isize(curvedata)-curvestart, linecol, fillcol, prio); + res.offset = curvestart; + curvestart = isize(curvedata); + return res; + } + +dqi_action& queueaction(PPR prio, const reaction_t& action) { + return queuea (prio, action); + } + +dqi_line& queueline(const hyperpoint& H1, const hyperpoint& H2, color_t col, int prf, PPR prio) { + auto& ptd = queuea (prio); + + ptd.H1 = H1; + ptd.H2 = H2; + ptd.band_shift = band_shift; + ptd.prf = prf; + ptd.width = vid.linewidth; + ptd.color = (darkened(col >> 8) << 8) + (col & 0xFF); + + return ptd; + } + +void queuestr(int x, int y, int shift, int size, string str, color_t col, int frame, int align) { + auto& ptd = queuea (PPR::TEXT); + ptd.x = x; + ptd.y = y; + ptd.str = str; + ptd.align = align; + ptd.shift = shift; + ptd.size = size; + ptd.color = darkened(col); + ptd.frame = frame ? ((poly_outline & ~ 255)+frame) : 0; + } + +void queuechr(int x, int y, int shift, int size, char chr, color_t col, int frame, int align) { + auto& ptd = queuea (PPR::TEXT); + ptd.x = x; + ptd.y = y; + ptd.str = chr; + ptd.shift = shift; + ptd.size = size; + ptd.align = align; + ptd.color = col; + ptd.frame = frame ? (poly_outline & ~ 255) : 0; + } + +void queuecircle(int x, int y, int size, color_t color, PPR prio = PPR::CIRCLE, color_t fillcolor = 0) { + auto& ptd = queuea(prio); + ptd.x = x; + ptd.y = y; + ptd.size = size; + ptd.color = color; + ptd.fillcolor = fillcolor; + ptd.linewidth = vid.linewidth; + } + +void getcoord0(const hyperpoint& h, int& xc, int &yc, int &sc) { + hyperpoint hscr; + applymodel(h, hscr); + xc = current_display->xcenter + current_display->radius * hscr[0]; + yc = current_display->ycenter + current_display->radius * vid.stretch * hscr[1]; + sc = 0; + // EYETODO sc = vid.eye * current_display->radius * hscr[2]; + } + +void queuechr(const hyperpoint& h, int size, char chr, color_t col, int frame) { + if(invalid_point(h)) return; + if(DIM == 3 && invis_point(h)) return; + int xc, yc, sc; getcoord0(h, xc, yc, sc); + queuechr(xc, yc, sc, size, chr, col, frame); + } + +ld scale_in_pixels(const transmatrix& V) { + return scale_at(V) * cgi.scalefactor * current_display->radius / 2.5; + } + +void queuechr(const transmatrix& V, double size, char chr, color_t col, int frame) { + if(invalid_point(V)) return; + if(DIM == 3 && invis_point(tC0(V))) return; + int xc, yc, sc; getcoord0(tC0(V), xc, yc, sc); + queuechr(xc, yc, sc, scale_in_pixels(V) * size, chr, col, frame); + } + +void queuestr(const hyperpoint& h, int size, const string& chr, color_t col, int frame) { + if(invalid_point(h)) return; + if(DIM == 3 && invis_point(h)) return; + int xc, yc, sc; getcoord0(h, xc, yc, sc); + queuestr(xc, yc, sc, size, chr, col, frame); + } + +void queuestr(const transmatrix& V, double size, const string& chr, color_t col, int frame, int align) { + if(invalid_point(V)) return; + if(DIM == 3 && invis_point(tC0(V))) return; + int xc, yc, sc; getcoord0(tC0(V), xc, yc, sc); + // int xs, ys, ss; getcoord0(V * xpush0(.01), xs, ys, ss); + + queuestr(xc, yc, sc, scale_in_pixels(V) * size, chr, col, frame, align); + } + +void queuecircle(const transmatrix& V, double size, color_t col) { + if(invalid_point(V)) return; + if(DIM == 3 && invis_point(tC0(V))) return; + int xc, yc, sc; getcoord0(tC0(V), xc, yc, sc); + int xs, ys, ss; getcoord0(V * xpush0(.01), xs, ys, ss); + queuecircle(xc, yc, scale_in_pixels(V) * size, col); + } + +void queuemarkerat(const transmatrix& V, color_t col) { +#if CAP_SHAPES + queuepolyat(V, cgi.shTriangle, col, PPR::LINE); +#endif + } + +#endif + +} diff --git a/expansion.cpp b/expansion.cpp index e55853c7..93e6f81a 100644 --- a/expansion.cpp +++ b/expansion.cpp @@ -323,6 +323,7 @@ ld expansion_analyzer::get_growth() { if(!N) preliminary_grouping(), reduce_grouping(); vector eigen(N, 1); ld total; + for(int iter=0; iter<100000; iter++) { total = 0; vector neweigen(N, 0); @@ -828,7 +829,6 @@ int expansion_readArgs() { if(x+y > 10) continue; stop_game(); gp::param = gp::loc(x, y); - need_reset_geometry = true; set_variation(eVariation::goldberg); compute_coefficients(); } diff --git a/floorshapes.cpp b/floorshapes.cpp index f46372cf..7fc49812 100644 --- a/floorshapes.cpp +++ b/floorshapes.cpp @@ -1,40 +1,61 @@ namespace hr { #if CAP_SHAPES -vector all_plain_floorshapes; -vector all_escher_floorshapes; -plain_floorshape - shFloor, - shMFloor, shMFloor2, shMFloor3, shMFloor4, shFullFloor, - shBigTriangle, shTriheptaFloor, shBigHepta; +vector floor_texture_vertices; +renderbuffer *floor_textures; -escher_floorshape shStarFloor(1,2), - shCloudFloor(3, 4), - shCrossFloor(5, 6, 2, 54), - shChargedFloor(7, 385, 1, 10), - shSStarFloor(11, 12), - shOverFloor(13, 15, 1, 14), - shTriFloor(17, 18, 0, 385), - shFeatherFloor(19, 21, 1, 20), - shBarrowFloor(23, 24, 1, 25), - shNewFloor(26, 27, 2, 54), - shTrollFloor(28, 29), - shButterflyFloor(325, 326, 1, 178), - shLavaFloor(359, 360, 1, 178), - shLavaSeabed(386, 387, 1, 178), - shSeabed(334, 335), - shCloudSeabed(336, 337), - shCaveSeabed(338, 339, 2, 54), - shPalaceFloor(45, 46, 0, 385), - shDemonFloor(51, 50, 1, 178), - shCaveFloor(52, 53, 2, 54), - shDesertFloor(55, 56, 0, 4), - shPowerFloor(57, 58, 0, 12), /* dragon */ - shRoseFloor(174, 175, 1, 173), - shSwitchFloor(377, 378, 1, 379), - shTurtleFloor(176, 177, 1, 178), - shRedRockFloor[3] = {{55, 56}, {55, 56}, {55, 56}}, // 1 - .1 * i - shDragonFloor(181, 182, 2, 183); /* dragon */ +void geometry_information::init_floorshapes() { + all_escher_floorshapes.clear(); + all_plain_floorshapes = { + &shFloor, &shMFloor, &shMFloor2, &shMFloor3, &shMFloor4, + &shFullFloor, &shBigTriangle, &shTriheptaFloor, &shBigHepta + }; + + for(auto s: all_plain_floorshapes) s->is_plain = true; + + auto init_escher = [this] (escher_floorshape& sh, int s0, int s1, int noft=0, int s2=0) { + sh.shapeid0 = s0; + sh.shapeid1 = s1; + sh.noftype = noft; + sh.shapeid2 = s2; + sh.scale = 1; + sh.is_plain = false; + all_escher_floorshapes.push_back(&sh); + }; + + init_escher(shStarFloor, 1,2); + init_escher(shCloudFloor, 3, 4); + init_escher(shCrossFloor, 5, 6, 2, 54); + init_escher(shChargedFloor, 7, 385, 1, 10); + init_escher(shSStarFloor, 11, 12); + init_escher(shOverFloor, 13, 15, 1, 14); + init_escher(shTriFloor, 17, 18, 0, 385); + init_escher(shFeatherFloor, 19, 21, 1, 20); + init_escher(shBarrowFloor, 23, 24, 1, 25); + init_escher(shNewFloor, 26, 27, 2, 54); + init_escher(shTrollFloor, 28, 29); + init_escher(shButterflyFloor, 325, 326, 1, 178); + init_escher(shLavaFloor, 359, 360, 1, 178); + init_escher(shLavaSeabed, 386, 387, 1, 178); + init_escher(shSeabed, 334, 335); + init_escher(shCloudSeabed, 336, 337); + init_escher(shCaveSeabed, 338, 339, 2, 54); + init_escher(shPalaceFloor, 45, 46, 0, 385); + init_escher(shDemonFloor, 51, 50, 1, 178); + init_escher(shCaveFloor, 52, 53, 2, 54); + init_escher(shDesertFloor, 55, 56, 0, 4); + init_escher(shPowerFloor, 57, 58, 0, 12); /* dragon */ + init_escher(shRoseFloor, 174, 175, 1, 173); + init_escher(shSwitchFloor, 377, 378, 1, 379); + init_escher(shTurtleFloor, 176, 177, 1, 178); + for(int i: {0,1,2}) + init_escher(shRedRockFloor[i], 55, 56); + init_escher(shDragonFloor, 181, 182, 2, 183); /* dragon */ + + int ids = 0; + for(auto sh: all_plain_floorshapes) sh->id = ids++; + for(auto sh: all_escher_floorshapes) sh->id = ids++; + } typedef pair> matrixitem; @@ -108,7 +129,7 @@ void generate_matrices_scale(ld scale, int noft) { mesher ohex = msh(gNormal, 6, 0.329036, 0.566256, 0.620672, 0, 1); mesher ohept = msh(gNormal, 7, hexf7, hcrossf7, hcrossf7, M_PI/7, 1); if(!BITRUNCATED) { - mesher nall = msh(geometry, S7, rhexf, tessf, tessf, -M_PI, scale); + mesher nall = msh(geometry, S7, cgi.rhexf, cgi.tessf, cgi.tessf, -M_PI, scale); bool use = geosupport_football() < 2; if(use && noft == 1) { mesher opure = msh(gNormal, 7, 0.620672, 1.090550, 1.090550, M_PI/7, 1); @@ -127,12 +148,12 @@ void generate_matrices_scale(ld scale, int noft) { } } else { - generate_matrices(hex_matrices, ohex, msh(geometry, S6, hexvdist, hexhexdist, hcrossf, (S3-3)*M_PI/S3, scale)); - generate_matrices(hept_matrices, ohept, msh(geometry, S7, rhexf, hcrossf, hcrossf, euclid6?0:euclid4?0:M_PI/S7, scale)); + generate_matrices(hex_matrices, ohex, msh(geometry, S6, cgi.hexvdist, cgi.hexhexdist, cgi.hcrossf, (S3-3)*M_PI/S3, scale)); + generate_matrices(hept_matrices, ohept, msh(geometry, S7, cgi.rhexf, cgi.hcrossf, cgi.hcrossf, euclid6?0:euclid4?0:M_PI/S7, scale)); } } -void bshape2(hpcshape& sh, PPR prio, int shapeid, matrixlist& m) { +void geometry_information::bshape2(hpcshape& sh, PPR prio, int shapeid, matrixlist& m) { auto& matrices = m.v; int osym = m.o.sym; int nsym = m.n.sym; @@ -196,7 +217,7 @@ void bshape2(hpcshape& sh, PPR prio, int shapeid, matrixlist& m) { hpcpush(hpc[last->s]); } -void bshape_regular(floorshape &fsh, int id, int sides, int shift, ld size) { +void geometry_information::bshape_regular(floorshape &fsh, int id, int sides, int shift, ld size) { fsh.b.resize(2); fsh.shadow.resize(2); @@ -272,7 +293,7 @@ template void sizeto(T& t, int n) { // !siid equals pseudohept(c) -void generate_floorshapes_for(int id, cell *c, int siid, int sidir) { +void geometry_information::generate_floorshapes_for(int id, cell *c, int siid, int sidir) { DEBBI(DF_POLY, ("generate_floorshapes_for ", id)); for(auto pfsh: all_plain_floorshapes) { @@ -470,13 +491,13 @@ void generate_floorshapes_for(int id, cell *c, int siid, int sidir) { auto& fsh = *pfsh; for(int i=fsh.shadow[id].s; iflags |= POLY_TRIANGLES; - last->tinf = &fsh.tinf3; + last->tinf = &floor_texture_vertices[fsh.id]; last->texture_offset = 0; #if CAP_BT @@ -506,10 +527,10 @@ void generate_floorshapes_for(int id, cell *c, int siid, int sidir) { sizeto(fsh.cone[co], id); bshape(fsh.cone[co][id], fsh.prio); last->flags |= POLY_TRIANGLES; - last->tinf = &fsh.tinf3; + last->tinf = &floor_texture_vertices[fsh.id]; last->texture_offset = 0; - ld h = (geom3::FLOOR - geom3::WALL) / (co+1); - ld top = co ? (geom3::FLOOR + geom3::WALL) / 2 : geom3::WALL; + ld h = (FLOOR - WALL) / (co+1); + ld top = co ? (FLOOR + WALL) / 2 : WALL; #if CAP_BT if(binarytiling) for(int t=0; ttype; t++) @@ -534,9 +555,9 @@ void generate_floorshapes_for(int id, cell *c, int siid, int sidir) { } for(int l=0; l 0) { + if(id == -1 && sphere && isize(cgi.shFloor.b) > 0) { forCellEx(c1, c) if(!gmatrix0.count(c1)) return 0; } if(id == -1) build_plainshape(id, draw_li, c, siid, sidir); @@ -811,13 +833,12 @@ auto floor_hook = #if MAXMDIM >= 4 -renderbuffer *floor_textures; +void draw_shape_for_texture(floorshape* sh) { -void draw_shape_for_texture(floorshape* sh, int& id) { + int id = sh->id; ld gx = (id % 8) * 1.5 - 3.5 * 1.5; ld gy = (id / 8) * 1.5 - 3.5 * 1.5; - id++; if(1) { dynamicval v(vid.linewidth, 8); @@ -835,8 +856,8 @@ void draw_shape_for_texture(floorshape* sh, int& id) { for(int b=-1; b<=1; b++) queuepoly(eupush(gx+a/2., gy+b/2.), sh->b[0], 0xFFFFFFFF); - if(sh == &shCrossFloor) { - queuepoly(eupush(gx, gy) * spin(M_PI/4), shCross, 0x808080FF); + if(sh == &cgi.shCrossFloor) { + queuepoly(eupush(gx, gy) * spin(M_PI/4), cgi.shCross, 0x808080FF); } if(1) { @@ -849,8 +870,9 @@ void draw_shape_for_texture(floorshape* sh, int& id) { queuecurve(0x40404000 + sh->fstrength * 192/10, 0, PPR::LINE); } - sh->tinf3.tvertices.clear(); - sh->tinf3.texture_id = floor_textures->renderedTexture; + auto& ftv = floor_texture_vertices[sh->id]; + ftv.tvertices.clear(); + ftv.texture_id = floor_textures->renderedTexture; using namespace hyperpoint_vec; hyperpoint center = eupush(gx, gy) * C0; @@ -865,94 +887,98 @@ void draw_shape_for_texture(floorshape* sh, int& id) { glvec2 v; v[0] = (1 + inmodel[0] * vid.scale) / 2; v[1] = (1 - inmodel[1] * vid.scale) / 2; - sh->tinf3.tvertices.push_back(glhr::makevertex(v[0], v[1], 0)); + ftv.tvertices.push_back(glhr::makevertex(v[0], v[1], 0)); }); } const int FLOORTEXTURESIZE = 4096; -void make_floor_textures() { - if(1) { - DEBBI(DF_POLY, ("make_floor_textures")); - dynamicval g(geometry, gEuclidSquare); - dynamicval gm(pmodel, mdDisk); - dynamicval va(variation, eVariation::pure); - dynamicval a3(geom3::always3, false); - dynamicval hq(inHighQual, true); - dynamicval hd(darken, 0); - dynamicval gd(geom3::depth, 1); - dynamicval gc(geom3::camera, 1); +void geometry_information::make_floor_textures_here() { + require_shapes(); + + dynamicval vi(vid, vid); + vid.xres = FLOORTEXTURESIZE; + vid.yres = FLOORTEXTURESIZE; + vid.scale = 0.25; + vid.camera_angle = 0; + vid.alpha = 1; + dynamicval lw(vid.linewidth, 2); + + floor_textures = new renderbuffer(vid.xres, vid.yres, vid.usingGL); + resetbuffer rb; + + floor_texture_vertices.resize(isize(all_escher_floorshapes) + isize(all_plain_floorshapes)); - resetGeometry(); - dynamicval vi(vid, vid); - vid.xres = FLOORTEXTURESIZE; - vid.yres = FLOORTEXTURESIZE; - vid.scale = 0.25; - vid.camera_angle = 0; - vid.alpha = 1; - dynamicval lw(vid.linewidth, 2); + auto cd = current_display; + cd->xtop = cd->ytop = 0; + cd->xsize = cd->ysize = FLOORTEXTURESIZE; + cd->xcenter = cd->ycenter = cd->scrsize = FLOORTEXTURESIZE/2; + + cd->radius = cd->scrsize * vid.scale; - floor_textures = new renderbuffer(vid.xres, vid.yres, vid.usingGL); - resetbuffer rb; + floor_textures->enable(); + floor_textures->clear(0); // 0xE8E8E8 = 1 + + // gradient vertices + vector gv; + current_display->scrdist = 0; + gv.emplace_back(-1, -1, 0, 0, 0); + gv.emplace_back(+1, -1, 0, 0, 0); + gv.emplace_back(+1, +1, 1, 1, 1); + gv.emplace_back(-1, -1, 0, 0, 0); + gv.emplace_back(+1, +1, 1, 1, 1); + gv.emplace_back(-1, +1, 1, 1, 1); - auto cd = current_display; - cd->xtop = cd->ytop = 0; - cd->xsize = cd->ysize = FLOORTEXTURESIZE; - cd->xcenter = cd->ycenter = cd->scrsize = FLOORTEXTURESIZE/2; - - cd->radius = cd->scrsize * vid.scale; + glhr::switch_mode(glhr::gmVarColored, glhr::shader_projection::standard); + current_display->set_all(0); + glhr::new_projection(); + glhr::id_modelview(); + glhr::prepare(gv); + glhr::set_depthtest(false); + glDrawArrays(GL_TRIANGLES, 0, isize(gv)); + + shOverFloor.pstrength = 20; + shFeatherFloor.pstrength = 40; + shFeatherFloor.fstrength = 5; + shTrollFloor.pstrength = 25; + shCaveFloor.pstrength = 40; + shCaveFloor.fstrength = 0; + shDesertFloor.pstrength = 30; + shDesertFloor.fstrength =10; + shRoseFloor.pstrength = 30; + shDragonFloor.pstrength = 30; + shBarrowFloor.pstrength = 40; - floor_textures->enable(); - floor_textures->clear(0); // 0xE8E8E8 = 1 - - // gradient vertices - vector gv; - current_display->scrdist = 0; - gv.emplace_back(-1, -1, 0, 0, 0); - gv.emplace_back(+1, -1, 0, 0, 0); - gv.emplace_back(+1, +1, 1, 1, 1); - gv.emplace_back(-1, -1, 0, 0, 0); - gv.emplace_back(+1, +1, 1, 1, 1); - gv.emplace_back(-1, +1, 1, 1, 1); + // all using Tortoise + for(auto v: all_escher_floorshapes) if(v->shapeid2 == 178) v->pstrength = 20; + + ptds.clear(); + + for(auto v: all_plain_floorshapes) draw_shape_for_texture(v); + for(auto v: all_escher_floorshapes) draw_shape_for_texture(v); + + drawqueue(); + + /* + SDL_Surface *sdark = floor_textures->render(); + IMAGESAVE(sdark, "texture-test.png"); + */ + rb.reset(); + } - glhr::switch_mode(glhr::gmVarColored, glhr::shader_projection::standard); - current_display->set_all(0); - glhr::new_projection(); - glhr::id_modelview(); - glhr::prepare(gv); - glhr::set_depthtest(false); - glDrawArrays(GL_TRIANGLES, 0, isize(gv)); - - shOverFloor.pstrength = 20; - shFeatherFloor.pstrength = 40; - shFeatherFloor.fstrength = 5; - shTrollFloor.pstrength = 25; - shCaveFloor.pstrength = 40; - shCaveFloor.fstrength = 0; - shDesertFloor.pstrength = 30; - shDesertFloor.fstrength =10; - shRoseFloor.pstrength = 30; - shDragonFloor.pstrength = 30; - shBarrowFloor.pstrength = 40; - - // all using Tortoise - for(auto v: all_escher_floorshapes) if(v->shapeid2 == 178) v->pstrength = 20; - - ptds.clear(); - - int id = 0; - - for(auto v: all_plain_floorshapes) draw_shape_for_texture(v, id); - for(auto v: all_escher_floorshapes) draw_shape_for_texture(v, id); - - drawqueue(); - - /* - SDL_Surface *sdark = floor_textures->render(); - IMAGESAVE(sdark, "texture-test.png"); - */ - rb.reset(); - } +void make_floor_textures() { + DEBBI(DF_POLY, ("make_floor_textures")); + dynamicval g(geometry, gEuclidSquare); + dynamicval gm(pmodel, mdDisk); + dynamicval va(variation, eVariation::pure); + dynamicval a3(geom3::always3, false); + dynamicval hq(inHighQual, true); + dynamicval hd(darken, 0); + dynamicval gd(geom3::depth, 1); + dynamicval gc(geom3::camera, 1); + dynamicval dcgip(cgip, cgip); + check_cgi(); + cgi.make_floor_textures_here(); } diff --git a/game.cpp b/game.cpp index 66b2f0e1..2027013c 100644 --- a/game.cpp +++ b/game.cpp @@ -2916,7 +2916,7 @@ void buildRosemap() { } -int getDistLimit() { return base_distlimit; } +int getDistLimit() { return cgi.base_distlimit; } bool nogoSlow(cell *to, cell *from) { if(cellEdgeUnstable(to) && gravityLevelDiff(to, from) >= 0) return true; diff --git a/geom-exp.cpp b/geom-exp.cpp index 36271763..4192cef0 100644 --- a/geom-exp.cpp +++ b/geom-exp.cpp @@ -484,10 +484,10 @@ void showEuclideanMenu() { #if CAP_GP if(GOLDBERG && S3) - nom = 2 * (2*tv + ts * (gp::area-1)); + nom = 2 * (2*tv + ts * (cgi.gpdata->area-1)); if(GOLDBERG && S3 == 4) - nom = 2 * (2*tv + 2 * ts * (gp::area-1)); + nom = 2 * (2*tv + 2 * ts * (cgi.gpdata->area-1)); #endif int worldsize; @@ -625,7 +625,6 @@ void showEuclideanMenu() { dialog::add_action([] { dialog::editNumber(vid.binary_width, 0, 2, 0.1, 1, XLAT("binary tiling width"), ""); dialog::reaction = [] () { - need_reset_geometry = true; #if CAP_TEXTURE texture::config.remap(); #endif diff --git a/geometry.cpp b/geometry.cpp index cecd195b..3cea4969 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -5,30 +5,6 @@ namespace hr { -ld tessf, crossf, hexf, hcrossf, hexhexdist, hexvdist, hepvdist, rhexf; - -// tessf: distance from heptagon center to another heptagon center -// hexf: distance from heptagon center to small heptagon vertex -// hcrossf: distance from heptagon center to big heptagon vertex -// crossf: distance from heptagon center to adjacent cell center (either hcrossf or tessf) -// hexhexdist: distance between adjacent hexagon vertices -// hexvdist: distance between hexagon vertex and hexagon center -// hepvdist: distance between heptagon vertex and hexagon center (either hcrossf or something else) -// rhexf: distance from heptagon center to heptagon vertex (either hexf or hcrossf) - -int base_distlimit; - -transmatrix heptmove[MAX_EDGE], hexmove[MAX_EDGE]; -transmatrix invheptmove[MAX_EDGE], invhexmove[MAX_EDGE]; - -ld hexshift; - -ld sword_size = 0; - -ld corner_bonus = 0; - -ld asteroid_size[8]; - // the results are: // hexf = 0.378077 hcrossf = 0.620672 tessf = 1.090550 // hexhexdist = 0.566256 @@ -36,13 +12,11 @@ ld asteroid_size[8]; ld hcrossf7 = 0.620672; ld hexf7 = 0.378077; -ld scalefactor, orbsize, floorrad0, floorrad1, zhexf; - // the distance between two hexagon centers -void precalc() { +void geometry_information::prepare_basics() { - DEBBI(DF_INIT | DF_POLY | DF_GEOM, ("precalc")); + DEBBI(DF_INIT | DF_POLY | DF_GEOM, ("prepare_basics")); hexshift = 0; @@ -53,7 +27,6 @@ void precalc() { if(euclid) { // dynamicval g(geometry, gNormal); - // precalc(); } // for(int i=0; i= 4 void switch_always3() { if(rug::rugged) rug::close(); geom3::always3 = !geom3::always3; - need_reset_geometry = true; swapmatrix(View); callhooks(hooks_swapdim); } @@ -431,7 +401,6 @@ void switch_always3() { geom3::human_wall_ratio = 0.8; geom3::camera = 0; if(pmodel == mdDisk) pmodel = mdPerspective; - need_reset_geometry = true; swapmatrix(View); callhooks(hooks_swapdim); #if CAP_RACING @@ -445,7 +414,6 @@ void switch_always3() { geom3::camera = 1; geom3::depth = 1; if(pmodel == mdPerspective) pmodel = mdDisk; - need_reset_geometry = true; swapmatrix(View); callhooks(hooks_swapdim); } @@ -454,8 +422,50 @@ void switch_always3() { } -void initgeo() { - // printf("%Lf\n", (ld) hdist0(xpush(-1)*ypush(0.01)*xpush(1)*C0)); - precalc(); +geometry_information *cgip; +map cgis; + +void check_cgi() { + string s; + auto V = [&] (string a, string b) { s += a; s += ": "; s += b; s += "; "; }; + V("GEO", its(int(geometry))); + V("VAR", its(int(variation))); + + if(GOLDBERG) V("GP", its(gp::param.first) + "," + its(gp::param.second)); + if(IRREGULAR) V("IRR", its(irr::irrid)); + + if(geometry == gArchimedean) V("ARCM", arcm::current.symbol); + + if(geometry == gCrystal) V("CRYSTAL", its(ginf[gCrystal].sides) + its(ginf[gCrystal].vertex)); + + if(binarytiling || DIM == 3) V("WQ", its(vid.texture_step)); + + if(binarytiling) V("BT", fts(vid.binary_width)); + + if(GDIM == 2) { + V("CAMERA", fts(geom3::camera)); + } + + if(WDIM == 2) { + V("WH", fts(geom3::wall_height)); + V("HW", fts(geom3::human_wall_ratio)); + V("RW", fts(geom3::rock_wall_ratio)); + V("DEPTH", fts(geom3::depth)); + V("ASH", ONOFF(geom3::gp_autoscale_heights)); + V("LT", fts(geom3::lake_top)); + V("LB", fts(geom3::lake_bottom)); + } + + V("3D", ONOFF(geom3::always3)); + + if(WDIM == 3) { + V("CS", fts(geom3::creature_scale)); + V("HTW", fts(geom3::height_width)); + } + + V("LQ", its(vid.linequality)); + + cgip = &cgis[s]; } + } diff --git a/geometry2.cpp b/geometry2.cpp index 981b4301..7b389b07 100644 --- a/geometry2.cpp +++ b/geometry2.cpp @@ -35,7 +35,7 @@ transmatrix master_relative(cell *c, bool get_inverse) { } else { auto li = gp::get_local_info(c); - transmatrix T = spin(master_to_c7_angle()) * gp::Tf[li.last_dir][li.relative.first&31][li.relative.second&31][gp::fixg6(li.total_dir)]; + transmatrix T = spin(master_to_c7_angle()) * cgi.gpdata->Tf[li.last_dir][li.relative.first&31][li.relative.second&31][gp::fixg6(li.total_dir)]; if(get_inverse) T = inverse(T); return T; } @@ -43,7 +43,7 @@ transmatrix master_relative(cell *c, bool get_inverse) { #endif else if(BITRUNCATED && !euclid) { for(int d=0; dmaster->c7->move(d) == c) - return (get_inverse?invhexmove:hexmove)[d]; + return (get_inverse?cgi.invhexmove:cgi.hexmove)[d]; return Id; } else if(WDIM == 3 || euclid) @@ -90,8 +90,8 @@ transmatrix hrmap_standard::relative_matrix(cell *c2, cell *c1, const hyperpoint ld bestdist = 1e9; for(int d=0; dmove(d)) { int sp = h2->c.spin(d); - transmatrix S = heptmove[sp] * spin(2*M_PI*d/S7); - if(h2->c.mirror(d)) S = heptmove[sp] * Mirror * spin(2*M_PI*d/S7); + transmatrix S = cgi.heptmove[sp] * spin(2*M_PI*d/S7); + if(h2->c.mirror(d)) S = cgi.heptmove[sp] * Mirror * spin(2*M_PI*d/S7); if(h2->move(d) == h1) { transmatrix T1 = gm * S * where; auto curdist = hdist(tC0(T1), point_hint); @@ -99,7 +99,7 @@ transmatrix hrmap_standard::relative_matrix(cell *c2, cell *c1, const hyperpoint } if(geometry != gMinimal) for(int e=0; emove(d)->move(e) == h1) { int sp2 = h2->move(d)->c.spin(e); - transmatrix T1 = gm * heptmove[sp2] * spin(2*M_PI*e/S7) * S * where; + transmatrix T1 = gm * cgi.heptmove[sp2] * spin(2*M_PI*e/S7) * S * where; auto curdist = hdist(tC0(T1), point_hint); if(curdist < bestdist) T = T1, bestdist = curdist; } @@ -108,7 +108,7 @@ transmatrix hrmap_standard::relative_matrix(cell *c2, cell *c1, const hyperpoint } for(int d=0; dmove(d) == h1) { int sp = h2->c.spin(d); - return gm * heptmove[sp] * spin(2*M_PI*d/S7) * where; + return gm * cgi.heptmove[sp] * spin(2*M_PI*d/S7) * where; } if(among(geometry, gFieldQuotient, gBring, gMacbeath)) { int bestdist = 1000000, bestd = 0; @@ -117,7 +117,7 @@ transmatrix hrmap_standard::relative_matrix(cell *c2, cell *c1, const hyperpoint if(dist < bestdist) bestdist = dist, bestd = d; } int sp = h2->c.spin(bestd); - where = heptmove[sp] * spin(2*M_PI*bestd/S7) * where; + where = cgi.heptmove[sp] * spin(2*M_PI*bestd/S7) * where; h2 = h2->move(bestd); } #if CAP_CRYSTAL @@ -127,7 +127,7 @@ transmatrix hrmap_standard::relative_matrix(cell *c2, cell *c1, const hyperpoint if(visited.count(h3)) continue; visited.insert(h3); int sp3 = h2->c.spin(d3); - transmatrix where3 = heptmove[sp3] * spin(2*M_PI*d3/S7) * where; + transmatrix where3 = cgi.heptmove[sp3] * spin(2*M_PI*d3/S7) * where; ld dist = crystal::space_distance(h3->c7, c1); hbdist[dist].emplace_back(h3, where3); } @@ -140,12 +140,12 @@ transmatrix hrmap_standard::relative_matrix(cell *c2, cell *c1, const hyperpoint else if(h1->distance < h2->distance) { int sp = h2->c.spin(0); h2 = h2->move(0); - where = heptmove[sp] * where; + where = cgi.heptmove[sp] * where; } else { int sp = h1->c.spin(0); h1 = h1->move(0); - gm = gm * invheptmove[sp]; + gm = gm * cgi.invheptmove[sp]; } } /*if(hsol) { @@ -184,11 +184,11 @@ transmatrix calc_relative_matrix_help(cell *c, heptagon *h1) { #if CAP_GP else if(GOLDBERG && c != c->master->c7) { auto li = gp::get_local_info(c); - where = gp::Tf[li.last_dir][li.relative.first&31][li.relative.second&31][fix6(li.total_dir)]; + where = cgi.gpdata->Tf[li.last_dir][li.relative.first&31][li.relative.second&31][fix6(li.total_dir)]; } #endif else if(BITRUNCATED) for(int d=0; dc7->move(d) == c) - where = hexmove[d]; + where = cgi.hexmove[d]; // always add to last! while(h1 != h2) { for(int d=0; dmove(d) == h2) printf("(adj) "); @@ -196,13 +196,13 @@ transmatrix calc_relative_matrix_help(cell *c, heptagon *h1) { int sp = h2->c.spin(0); printf("A%d ", sp); h2 = h2->move(0); - where = heptmove[sp] * where; + where = cgi.heptmove[sp] * where; } else { int sp = h1->c.spin(0); printf("B%d ", sp); h1 = h1->move(0); - gm = gm * invheptmove[sp]; + gm = gm * cgi.invheptmove[sp]; } } println(hlog, "OK"); @@ -286,7 +286,7 @@ void virtualRebase(cell*& base, T& at, bool tohex, const U& check) { if(WDIM == 2 && !binarytiling) for(int d=0; dc.spin(d)*2*M_PI/S6) * invhexmove[d]; + transmatrix V2 = spin(-base->c.spin(d)*2*M_PI/S6) * cgi.invhexmove[d]; horo_distance newz(check(V2 * at)); if(newz < currz) { currz = newz; @@ -367,7 +367,7 @@ void virtualRebaseSimple(heptagon*& base, transmatrix& at) { for(int d=0; dtype == 8 && (i&1)) return crossf * sqrt(2); - return crossf; + if(c->type == 8 && (i&1)) return cgi.crossf * sqrt(2); + return cgi.crossf; } if(NONSTDVAR || archimedean || WDIM == 3) return hdist0(tC0(calc_relative_matrix(c->move(i), c, i))); - return !BITRUNCATED ? tessf : (c->type == 6 && (i&1)) ? hexhexdist : crossf; + return !BITRUNCATED ? cgi.tessf : (c->type == 6 && (i&1)) ? cgi.hexhexdist : cgi.crossf; } transmatrix cellrelmatrix(cell *c, int i) { @@ -415,7 +415,7 @@ hyperpoint randomPointIn(int t) { while(true) { hyperpoint h = xspinpush0(2*M_PI*(randd()-.5)/t, asinh(randd())); double d = - PURE ? tessf : t == 6 ? hexhexdist : crossf; + PURE ? cgi.tessf : t == 6 ? cgi.hexhexdist : cgi.crossf; if(hdist0(h) < hdist0(xpush(-d) * h)) return spin(2*M_PI/t * (rand() % t)) * h; } @@ -462,13 +462,13 @@ hyperpoint get_corner_position(cell *c, int cid, ld cf) { } #endif if(PURE) { - return ddspin(c,cid,M_PI/S7) * xpush0(hcrossf * 3 / cf); + return ddspin(c,cid,M_PI/S7) * xpush0(cgi.hcrossf * 3 / cf); } if(BITRUNCATED) { if(!ishept(c)) - return ddspin(c,cid,M_PI/S6) * xpush0(hexvdist * 3 / cf); + return ddspin(c,cid,M_PI/S6) * xpush0(cgi.hexvdist * 3 / cf); else - return ddspin(c,cid,M_PI/S7) * xpush0(rhexf * 3 / cf); + return ddspin(c,cid,M_PI/S7) * xpush0(cgi.rhexf * 3 / cf); } return C0; } @@ -613,7 +613,7 @@ hyperpoint get_warp_corner(cell *c, int cid) { #if CAP_IRR || CAP_ARCM if(IRREGULAR || archimedean) return midcorner(c, cid, .5); #endif - return ddspin(c,cid,M_PI/S7) * xpush0(tessf/2); + return ddspin(c,cid,M_PI/S7) * xpush0(cgi.tessf/2); } vector hrmap::get_vertices(cell* c) { diff --git a/goldberg.cpp b/goldberg.cpp index 421b5787..29fa08c5 100644 --- a/goldberg.cpp +++ b/goldberg.cpp @@ -46,8 +46,6 @@ namespace hr { namespace gp { loc param(1, 0); hyperpoint next; - ld alpha; - int area; struct goldberg_mapping_t { cellwalker cw; @@ -504,22 +502,18 @@ namespace hr { namespace gp { return normalize(spin(2*M_PI*sp/S7) * cornmul(T, corner)); } - transmatrix Tf[MAX_EDGE][32][32][6]; - - transmatrix corners; - transmatrix dir_matrix(int i) { cell cc; cc.type = S7; - return spin(-alpha) * build_matrix( + return spin(-cgi.gpdata->alpha) * build_matrix( C0, - ddspin(&cc, i) * xpush0(tessf), - ddspin(&cc, i+1) * xpush0(tessf), + ddspin(&cc, i) * xpush0(cgi.tessf), + ddspin(&cc, i+1) * xpush0(cgi.tessf), C03 ); } void prepare_matrices() { - corners = inverse(build_matrix( + cgi.gpdata->corners = inverse(build_matrix( loctoh_ort(loc(0,0)), loctoh_ort(param), loctoh_ort(param * loc(0,1)), @@ -532,9 +526,9 @@ namespace hr { namespace gp { for(int d=0; d<(S3==3?6:4); d++) { loc at = loc(x, y); - hyperpoint h = atz(T, corners, at, 6); - hyperpoint hl = atz(T, corners, at + eudir(d), 6); - Tf[i][x&31][y&31][d] = rgpushxto0(h) * rspintox(gpushxto0(h) * hl) * spin(M_PI); + hyperpoint h = atz(T, cgi.gpdata->corners, at, 6); + hyperpoint hl = atz(T, cgi.gpdata->corners, at + eudir(d), 6); + cgi.gpdata->Tf[i][x&31][y&31][d] = rgpushxto0(h) * rspintox(gpushxto0(h) * hl) * spin(M_PI); } } } @@ -542,10 +536,10 @@ namespace hr { namespace gp { hyperpoint get_corner_position(const local_info& li, int cid, ld cf = 3) { int i = li.last_dir; if(i == -1) - return atz(dir_matrix(cid), corners, li.relative, 0, cf); + return atz(dir_matrix(cid), cgi.gpdata->corners, li.relative, 0, cf); else { - auto& cellmatrix = Tf[i][li.relative.first&31][li.relative.second&31][fixg6(li.total_dir)]; - return inverse(cellmatrix) * atz(dir_matrix(i), corners, li.relative, fixg6(cid + li.total_dir), cf); + auto& cellmatrix = cgi.gpdata->Tf[i][li.relative.first&31][li.relative.second&31][fixg6(li.total_dir)]; + return inverse(cellmatrix) * atz(dir_matrix(i), cgi.gpdata->corners, li.relative, fixg6(cid + li.total_dir), cf); } } @@ -558,36 +552,34 @@ namespace hr { namespace gp { void compute_geometry() { center_locs.clear(); if(GOLDBERG) { + if(!cgi.gpdata) cgi.gpdata = make_shared(); int x = param.first; int y = param.second; if(S3 == 3) - area = ((2*x+y) * (2*x+y) + y*y*3) / 4; + cgi.gpdata->area = ((2*x+y) * (2*x+y) + y*y*3) / 4; else - area = x * x + y * y; + cgi.gpdata->area = x * x + y * y; next = point3(x+y/2., -y * sqrt(3) / 2, 0); ld scale = 1 / hypot_d(2, next); - crossf *= scale; - hepvdist *= scale; - hexhexdist *= scale; - hexvdist *= scale; - rhexf *= scale; + cgi.crossf *= scale; + cgi.hepvdist *= scale; + cgi.hexhexdist *= scale; + cgi.hexvdist *= scale; + cgi.rhexf *= scale; // spin = spintox(next); // ispin = rspintox(next); - alpha = -atan2(next[1], next[0]) * 6 / S7; + cgi.gpdata->alpha = -atan2(next[1], next[0]) * 6 / S7; if(S3 == 3) - base_distlimit = (base_distlimit + log(scale) / log(2.618)) / scale; + cgi.base_distlimit = (cgi.base_distlimit + log(scale) / log(2.618)) / scale; else - base_distlimit = 3 * max(param.first, param.second) + 2 * min(param.first, param.second); + cgi.base_distlimit = 3 * max(param.first, param.second) + 2 * min(param.first, param.second); if(S7 == 12) - base_distlimit = 2 * param.first + 2 * param.second + 1; - if(base_distlimit > SEE_ALL) - base_distlimit = SEE_ALL; + cgi.base_distlimit = 2 * param.first + 2 * param.second + 1; + if(cgi.base_distlimit > SEE_ALL) + cgi.base_distlimit = SEE_ALL; prepare_matrices(); DEBB(DF_GEOM | DF_POLY, ("scale = ", scale)); } - else { - alpha = 0; - } } loc config; @@ -625,7 +617,6 @@ namespace hr { namespace gp { stop_game(); set_variation(eVariation::bitruncated); } else { - if(param != xy) need_reset_geometry = true; param = xy; stop_game(); set_variation(eVariation::goldberg); } @@ -765,7 +756,7 @@ namespace hr { namespace gp { int sp = 0; auto& at = li.relative; again: - auto corner = corners * loctoh_ort(at); + auto corner = cgi.gpdata->corners * loctoh_ort(at); if(corner[1] < -1e-6 || corner[2] < -1e-6) { at = at * eudir(1); sp++; @@ -832,7 +823,7 @@ namespace hr { namespace gp { hyperpoint get_master_coordinates(cell *c) { auto li = get_local_info(c); be_in_triangle(li); - return corners * loctoh_ort(li.relative); + return cgi.gpdata->corners * loctoh_ort(li.relative); } int compute_dist(cell *c, int master_function(cell*)) { diff --git a/graph.cpp b/graph.cpp index cd7dd767..dc0d6254 100644 --- a/graph.cpp +++ b/graph.cpp @@ -127,7 +127,7 @@ int watercolor(int phase) { } int aircolor(int phase) { - return 0x8080FF00 | int(32 + 32 * sintick(200, phase * 1. / S21)); + return 0x8080FF00 | int(32 + 32 * sintick(200, phase * 1. / cgi.S21)); } int fghostcolor(cell *c) { @@ -160,8 +160,6 @@ int lightat, safetyat; void drawLightning() { lightat = ticks; } void drawSafety() { safetyat = ticks; } -void queueball(const transmatrix& V, ld rad, color_t col, eItem what); - void drawShield(const transmatrix& V, eItem it) { #if CAP_CURVE float ds = ptick(300); @@ -170,13 +168,13 @@ void drawShield(const transmatrix& V, eItem it) { col = (col & 0xFEFEFE) / 2; if(sphere && cwt.at->land == laHalloween && !wmblack && !wmascii) col = 0; - double d = it == itOrbShield ? hexf : hexf - .1; + double d = it == itOrbShield ? cgi.hexf : cgi.hexf - .1; int mt = sphere ? 7 : 5; if(DIM == 3) - queueball(V * zpush(geom3::GROIN1), geom3::human_height / 2, darkena(col, 0, 0xFF), itOrbShield); + queueball(V * zpush(cgi.GROIN1), cgi.human_height / 2, darkena(col, 0, 0xFF), itOrbShield); else { - for(ld a=0; a<=S84*mt+1e-6; a+=pow(.5, vid.linequality)) - curvepoint(V*xspinpush0(a * M_PI/S42, d + sin(ds + M_PI*2*a/4/mt)*.1)); + for(ld a=0; a<=cgi.S84*mt+1e-6; a+=pow(.5, vid.linequality)) + curvepoint(V*xspinpush0(a * M_PI/cgi.S42, d + sin(ds + M_PI*2*a/4/mt)*.1)); queuecurve(darkena(col, 0, 0xFF), 0x8080808, PPR::LINE); } #endif @@ -186,10 +184,10 @@ void drawSpeed(const transmatrix& V) { #if CAP_CURVE ld ds = ptick(10); color_t col = darkena(iinf[itOrbSpeed].color, 0, 0xFF); - if(DIM == 3) queueball(V * zpush(geom3::GROIN1), geom3::human_height * 0.55, col, itOrbSpeed); - else for(int b=0; bS42) z = S84-z; + double d = (1 + cos(a * M_PI/cgi.S42)) / 2; + double z = a; if(z>cgi.S42) z = cgi.S84-z; if(z <= 10) d += (10-z) * (10-z) * (10-z) / 3000.; - ld rad = hexf * (2.5 + .5 * sin(ds+u*.3)) * d; + ld rad = cgi.hexf * (2.5 + .5 * sin(ds+u*.3)) * d; transmatrix V1 = chei(V, u, 5); - curvepoint(V1*xspinpush0((S42+hdir+a-1) * M_PI/S42, rad)); + curvepoint(V1*xspinpush0((cgi.S42+hdir+a-1) * M_PI/cgi.S42, rad)); } queuecurve(col, 0x8080808, PPR::LINE); } @@ -276,7 +274,7 @@ void drawWinter(const transmatrix& V, ld hdir) { for(int u=0; u<20; u++) { ld rad = sin(ds+u * 2 * M_PI / 20) * M_PI / S7; transmatrix V1 = chei(V, u, 20); - queueline(V1*xspinpush0(M_PI+hdir+rad, hexf*.5), V1*xspinpush0(M_PI+hdir+rad, hexf*3), col, 2 + vid.linequality); + queueline(V1*xspinpush0(M_PI+hdir+rad, cgi.hexf*.5), V1*xspinpush0(M_PI+hdir+rad, cgi.hexf*3), col, 2 + vid.linequality); } #endif } @@ -288,7 +286,7 @@ void drawLightning(const transmatrix& V) { ld leng = 0.5 / (0.1 + (rand() % 100) / 100.0); ld rad = rand() % 1000; transmatrix V1 = chei(V, u, 20); - queueline(V1*xspinpush0(rad, hexf*0.3), V1*xspinpush0(rad, hexf*leng), col, 2 + vid.linequality); + queueline(V1*xspinpush0(rad, cgi.hexf*0.3), V1*xspinpush0(rad, cgi.hexf*leng), col, 2 + vid.linequality); } #endif } @@ -335,9 +333,9 @@ ld displayspin(cell *c, int d) { double hexshiftat(cell *c) { if(binarytiling) return 0; - if(ctof(c) && S7==6 && S3 == 4 && BITRUNCATED) return hexshift + 2*M_PI/S7; - if(ctof(c) && (S7==8 || S7 == 4) && S3 == 3 && BITRUNCATED) return hexshift + 2*M_PI/S7; - if(hexshift && ctof(c)) return hexshift; + if(ctof(c) && S7==6 && S3 == 4 && BITRUNCATED) return cgi.hexshift + 2*M_PI/S7; + if(ctof(c) && (S7==8 || S7 == 4) && S3 == 3 && BITRUNCATED) return cgi.hexshift + 2*M_PI/S7; + if(cgi.hexshift && ctof(c)) return cgi.hexshift; return 0; } @@ -366,20 +364,20 @@ void drawPlayerEffects(const transmatrix& V, cell *c, bool onplayer) { if(shmup::on && WDIM == 2) { #if CAP_SHAPES if(items[itOrbSword]) - queuepoly(V*spin(shmup::pc[multi::cpid]->swordangle), (peace::on ? shMagicShovel : shMagicSword), darkena(iinf[itOrbSword].color, 0, 0xC0 + 0x30 * sintick(200))); + queuepoly(V*spin(shmup::pc[multi::cpid]->swordangle), (peace::on ? cgi.shMagicShovel : cgi.shMagicSword), darkena(iinf[itOrbSword].color, 0, 0xC0 + 0x30 * sintick(200))); if(items[itOrbSword2]) - queuepoly(V*spin(shmup::pc[multi::cpid]->swordangle+M_PI), (peace::on ? shMagicShovel : shMagicSword), darkena(iinf[itOrbSword2].color, 0, 0xC0 + 0x30 * sintick(200))); + queuepoly(V*spin(shmup::pc[multi::cpid]->swordangle+M_PI), (peace::on ? cgi.shMagicShovel : cgi.shMagicSword), darkena(iinf[itOrbSword2].color, 0, 0xC0 + 0x30 * sintick(200))); #endif } else if(shmup::on && WDIM == 3) { #if CAP_SHAPES if(items[itOrbSword]) - queuepoly(V*shmup::swordmatrix[multi::cpid] * cspin(2, 0, M_PI/2) * cspin(1,2, ticks / 150.), (peace::on ? shMagicShovel : shMagicSword), darkena(iinf[itOrbSword].color, 0, 0xC0 + 0x30 * sintick(200))); + queuepoly(V*shmup::swordmatrix[multi::cpid] * cspin(2, 0, M_PI/2) * cspin(1,2, ticks / 150.), (peace::on ? cgi.shMagicShovel : cgi.shMagicSword), darkena(iinf[itOrbSword].color, 0, 0xC0 + 0x30 * sintick(200))); if(items[itOrbSword2]) - queuepoly(V*shmup::swordmatrix[multi::cpid] * cspin(2, 0, -M_PI/2) * cspin(1,2, ticks / 150.), (peace::on ? shMagicShovel : shMagicSword), darkena(iinf[itOrbSword2].color, 0, 0xC0 + 0x30 * sintick(200))); + queuepoly(V*shmup::swordmatrix[multi::cpid] * cspin(2, 0, -M_PI/2) * cspin(1,2, ticks / 150.), (peace::on ? cgi.shMagicShovel : cgi.shMagicSword), darkena(iinf[itOrbSword2].color, 0, 0xC0 + 0x30 * sintick(200))); #endif } @@ -399,10 +397,10 @@ void drawPlayerEffects(const transmatrix& V, cell *c, bool onplayer) { if((a+sword_angles/2)%sword_angles == ang && items[itOrbSword2]) continue; bool longer = sword::pos(cwt.at, a-1) != sword::pos(cwt.at, a+1); color_t col = darkena(0xC0C0C0, 0, 0xFF); - ld l0 = PURE ? 0.6 * scalefactor : longer ? 0.36 : 0.4; - ld l1 = PURE ? 0.7 * scalefactor : longer ? 0.44 : 0.42; - hyperpoint h0 = DIM == 3 ? xpush(l0) * zpush(geom3::FLOOR - geom3::human_height/50) * C0 : xpush0(l0); - hyperpoint h1 = DIM == 3 ? xpush(l1) * zpush(geom3::FLOOR - geom3::human_height/50) * C0 : xpush0(l1); + ld l0 = PURE ? 0.6 * cgi.scalefactor : longer ? 0.36 : 0.4; + ld l1 = PURE ? 0.7 * cgi.scalefactor : longer ? 0.44 : 0.42; + hyperpoint h0 = DIM == 3 ? xpush(l0) * zpush(cgi.FLOOR - cgi.human_height/50) * C0 : xpush0(l0); + hyperpoint h1 = DIM == 3 ? xpush(l1) * zpush(cgi.FLOOR - cgi.human_height/50) * C0 : xpush0(l1); transmatrix T = Vnow*spin(dda * M_PI / sword_angles); queueline(T*h0, T*h1, col, 1, PPR::SUPERLINE); } @@ -410,10 +408,10 @@ void drawPlayerEffects(const transmatrix& V, cell *c, bool onplayer) { #if CAP_SHAPES if(items[itOrbSword]) - queuepoly(Vnow*spin(M_PI+(-1-2*ang)*M_PI/sword_angles), (peace::on ? shMagicShovel : shMagicSword), darkena(iinf[itOrbSword].color, 0, 0x80 + 0x70 * sintick(200))); + queuepoly(Vnow*spin(M_PI+(-1-2*ang)*M_PI/sword_angles), (peace::on ? cgi.shMagicShovel : cgi.shMagicSword), darkena(iinf[itOrbSword].color, 0, 0x80 + 0x70 * sintick(200))); if(items[itOrbSword2]) - queuepoly(Vnow*spin((-1-2*ang)*M_PI/sword_angles), (peace::on ? shMagicShovel : shMagicSword), darkena(iinf[itOrbSword2].color, 0, 0x80 + 0x70 * sintick(200))); + queuepoly(Vnow*spin((-1-2*ang)*M_PI/sword_angles), (peace::on ? cgi.shMagicShovel : cgi.shMagicSword), darkena(iinf[itOrbSword2].color, 0, 0x80 + 0x70 * sintick(200))); #endif } } @@ -433,10 +431,10 @@ void drawPlayerEffects(const transmatrix& V, cell *c, bool onplayer) { if(tim > 2500) safetyat = 0; for(int u=tim; u<=2500; u++) { if((u-tim)%250) continue; - ld rad = hexf * u / 250; + ld rad = cgi.hexf * u / 250; color_t col = darkena(iinf[itOrbSafety].color, 0, 0xFF); PRING(a) - curvepoint(V*xspinpush0(a * M_PI / S42, rad)); + curvepoint(V*xspinpush0(a * M_PI / cgi.S42, rad)); queuecurve(col, 0, PPR::LINE); } } @@ -446,8 +444,8 @@ void drawStunStars(const transmatrix& V, int t) { #if CAP_SHAPES for(int i=0; i<3*t; i++) { transmatrix V2 = V * spin(M_PI * 2 * i / (3*t) + ptick(200)); - if(GDIM == 3) V2 = V2 * zpush(geom3::HEAD); - queuepolyat(V2, shFlailBall, 0xFFFFFFFF, PPR::STUNSTARS); + if(GDIM == 3) V2 = V2 * zpush(cgi.HEAD); + queuepolyat(V2, cgi.shFlailBall, 0xFFFFFFFF, PPR::STUNSTARS); } #endif } @@ -479,17 +477,17 @@ namespace tortoise { if(i >= 8 && i <= 11 && stuntime >= 3) continue; - queuepoly(V, shTortoise[i][b+small], d); + queuepoly(V, cgi.shTortoise[i][b+small], d); if((i >= 5 && i <= 7) || (i >= 9 && i <= 10)) - queuepoly(V * Mirror, shTortoise[i][b+small], d); + queuepoly(V * Mirror, cgi.shTortoise[i][b+small], d); if(i == 8) { for(int k=0; k>= 1; } - queuepoly(V, shTortoise[12][b+small], darkena(eyecolor, 0, 0xFF)); - queuepoly(V * Mirror, shTortoise[12][b+small], darkena(eyecolor, 0, 0xFF)); + queuepoly(V, cgi.shTortoise[12][b+small], darkena(eyecolor, 0, 0xFF)); + queuepoly(V * Mirror, cgi.shTortoise[12][b+small], darkena(eyecolor, 0, 0xFF)); } } #endif @@ -537,15 +535,15 @@ void animallegs(const transmatrix& V, eMonster mo, color_t col, double footphase if(!footphase) rightfoot = leftfoot = 0; - transmatrix VAML = mmscale(V, geom3::ALEG); + transmatrix VAML = mmscale(V, cgi.ALEG); hpcshape* sh[6][4] = { - {&shDogFrontPaw, &shDogRearPaw, &shDogFrontLeg, &shDogRearLeg}, - {&shWolfFrontPaw, &shWolfRearPaw, &shWolfFrontLeg, &shWolfRearLeg}, - {&shReptileFrontFoot, &shReptileRearFoot, &shReptileFrontLeg, &shReptileRearLeg}, - {&shBugLeg, NULL, NULL, NULL}, - {&shTrylobiteFrontClaw, &shTrylobiteRearClaw, &shTrylobiteFrontLeg, &shTrylobiteRearLeg}, - {&shBullFrontHoof, &shBullRearHoof, &shBullFrontHoof, &shBullRearHoof}, + {&cgi.shDogFrontPaw, &cgi.shDogRearPaw, &cgi.shDogFrontLeg, &cgi.shDogRearLeg}, + {&cgi.shWolfFrontPaw, &cgi.shWolfRearPaw, &cgi.shWolfFrontLeg, &cgi.shWolfRearLeg}, + {&cgi.shReptileFrontFoot, &cgi.shReptileRearFoot, &cgi.shReptileFrontLeg, &cgi.shReptileRearLeg}, + {&cgi.shBugLeg, NULL, NULL, NULL}, + {&cgi.shTrylobiteFrontClaw, &cgi.shTrylobiteRearClaw, &cgi.shTrylobiteFrontLeg, &cgi.shTrylobiteRearLeg}, + {&cgi.shBullFrontHoof, &cgi.shBullRearHoof, &cgi.shBullFrontHoof, &cgi.shBullRearHoof}, }; hpcshape **x = sh[mo == moRagingBull ? 5 : mo == moBug0 ? 3 : mo == moMetalBeast ? 4 : mo == moRunDog ? 0 : mo == moReptile ? 2 : 1]; @@ -558,14 +556,14 @@ void animallegs(const transmatrix& V, eMonster mo, color_t col, double footphase return; /* - if(WDIM == 2) V1 = V1 * zpush(geom3::GROIN); + if(WDIM == 2) V1 = V1 * zpush(cgi.GROIN); Tright = V1 * cspin(0, 2, rightfoot/SCALE * 3); Tleft = V1 * Mirror * cspin(2, 0, rightfoot/SCALE * 3); - if(WDIM == 2) Tleft = Tleft * zpush(-geom3::GROIN), Tright = Tright * zpush(-geom3::GROIN); + if(WDIM == 2) Tleft = Tleft * zpush(-cgi.GROIN), Tright = Tright * zpush(-cgi.GROIN); */ } - const transmatrix VL = mmscale(V, geom3::ALEG0); + const transmatrix VL = mmscale(V, cgi.ALEG0); if(x[0]) queuepolyat(VL * xpush(rightfoot), *x[0], col, PPR::MONSTER_FOOT); if(x[0]) queuepolyat(VL * Mirror * xpush(leftfoot), *x[0], col, PPR::MONSTER_FOOT); @@ -606,28 +604,28 @@ void ShadowV(const transmatrix& V, const hpcshape& bp, PPR prio) { #if CAP_SHAPES transmatrix otherbodyparts(const transmatrix& V, color_t col, eMonster who, double footphase) { -#define VFOOT (DIM == 2 ? V : mmscale(V, geom3::LEG0)) -#define VLEG mmscale(V, geom3::LEG) -#define VGROIN mmscale(V, geom3::GROIN) -#define VBODY mmscale(V, geom3::BODY) -#define VBODY1 mmscale(V, geom3::BODY1) -#define VBODY2 mmscale(V, geom3::BODY2) -#define VBODY3 mmscale(V, geom3::BODY3) -#define VNECK mmscale(V, geom3::NECK) -#define VHEAD mmscale(V, geom3::HEAD) -#define VHEAD1 mmscale(V, geom3::HEAD1) -#define VHEAD2 mmscale(V, geom3::HEAD2) -#define VHEAD3 mmscale(V, geom3::HEAD3) +#define VFOOT (DIM == 2 ? V : mmscale(V, cgi.LEG0)) +#define VLEG mmscale(V, cgi.LEG) +#define VGROIN mmscale(V, cgi.GROIN) +#define VBODY mmscale(V, cgi.BODY) +#define VBODY1 mmscale(V, cgi.BODY1) +#define VBODY2 mmscale(V, cgi.BODY2) +#define VBODY3 mmscale(V, cgi.BODY3) +#define VNECK mmscale(V, cgi.NECK) +#define VHEAD mmscale(V, cgi.HEAD) +#define VHEAD1 mmscale(V, cgi.HEAD1) +#define VHEAD2 mmscale(V, cgi.HEAD2) +#define VHEAD3 mmscale(V, cgi.HEAD3) #define VALEGS V -#define VABODY mmscale(V, geom3::ABODY) -#define VAHEAD mmscale(V, geom3::AHEAD) +#define VABODY mmscale(V, cgi.ABODY) +#define VAHEAD mmscale(V, cgi.AHEAD) #define VFISH V -#define VBIRD ((DIM == 3 || (where && bird_disruption(where))) ? (WDIM == 2 ? mmscale(V, geom3::BIRD) : V) : mmscale(V, geom3::BIRD + .05 * sintick(1000, (int) (size_t(where))/1000.))) -#define VGHOST mmscale(V, geom3::GHOST) +#define VBIRD ((DIM == 3 || (where && bird_disruption(where))) ? (WDIM == 2 ? mmscale(V, cgi.BIRD) : V) : mmscale(V, cgi.BIRD + .05 * sintick(1000, (int) (size_t(where))/1000.))) +#define VGHOST mmscale(V, cgi.GHOST) -#define VSLIMEEYE mscale(V, geom3::FLATEYE) +#define VSLIMEEYE mscale(V, cgi.FLATEYE) // if(!mmspatial && !footphase && who != moSkeleton) return; @@ -639,21 +637,21 @@ transmatrix otherbodyparts(const transmatrix& V, color_t col, eMonster who, doub // todo if(detaillevel >= 2 && DIM == 2) { - transmatrix VL = mmscale(V, geom3::LEG1); - queuepoly(VL * xpush(rightfoot*3/4), shHumanLeg, col); - queuepoly(VL * Mirror * xpush(-rightfoot*3/4), shHumanLeg, col); + transmatrix VL = mmscale(V, cgi.LEG1); + queuepoly(VL * xpush(rightfoot*3/4), cgi.shHumanLeg, col); + queuepoly(VL * Mirror * xpush(-rightfoot*3/4), cgi.shHumanLeg, col); } if(DIM == 2) { - transmatrix VL = mmscale(V, geom3::LEG); - queuepoly(VL * xpush(rightfoot/2), shHumanLeg, col); - queuepoly(VL * Mirror * xpush(-rightfoot/2), shHumanLeg, col); + transmatrix VL = mmscale(V, cgi.LEG); + queuepoly(VL * xpush(rightfoot/2), cgi.shHumanLeg, col); + queuepoly(VL * Mirror * xpush(-rightfoot/2), cgi.shHumanLeg, col); } if(detaillevel >= 2 && DIM == 2) { - transmatrix VL = mmscale(V, geom3::LEG3); - queuepoly(VL * xpush(rightfoot/4), shHumanLeg, col); - queuepoly(VL * Mirror * xpush(-rightfoot/4), shHumanLeg, col); + transmatrix VL = mmscale(V, cgi.LEG3); + queuepoly(VL * xpush(rightfoot/4), cgi.shHumanLeg, col); + queuepoly(VL * Mirror * xpush(-rightfoot/4), cgi.shHumanLeg, col); } transmatrix Tright, Tleft; @@ -664,41 +662,41 @@ transmatrix otherbodyparts(const transmatrix& V, color_t col, eMonster who, doub } else { transmatrix V1 = V; - if(WDIM == 2) V1 = V1 * zpush(geom3::GROIN); + if(WDIM == 2) V1 = V1 * zpush(cgi.GROIN); Tright = V1 * cspin(0, 2, rightfoot/ leg_length); Tleft = V1 * Mirror * cspin(2, 0, rightfoot / leg_length); - if(WDIM == 2) Tleft = Tleft * zpush(-geom3::GROIN), Tright = Tright * zpush(-geom3::GROIN); + if(WDIM == 2) Tleft = Tleft * zpush(-cgi.GROIN), Tright = Tright * zpush(-cgi.GROIN); } if(who == moWaterElemental && DIM == 2) { double fishtail = footfun(footphase / .4) / 4 * 1.5; - queuepoly(VFOOT * xpush(fishtail), shFishTail, watercolor(100)); + queuepoly(VFOOT * xpush(fishtail), cgi.shFishTail, watercolor(100)); } else if(who == moSkeleton) { - queuepoly(Tright, shSkeletalFoot, col); - queuepoly(Tleft, shSkeletalFoot, col); + queuepoly(Tright, cgi.shSkeletalFoot, col); + queuepoly(Tleft, cgi.shSkeletalFoot, col); return spin(rightfoot * wobble); } else if(isTroll(who) || who == moMonkey || who == moYeti || who == moRatling || who == moRatlingAvenger || who == moGoblin) { - queuepoly(Tright, shYetiFoot, col); - queuepoly(Tleft, shYetiFoot, col); + queuepoly(Tright, cgi.shYetiFoot, col); + queuepoly(Tleft, cgi.shYetiFoot, col); } else { - queuepoly(Tright, shHumanFoot, col); - queuepoly(Tleft, shHumanFoot, col); + queuepoly(Tright, cgi.shHumanFoot, col); + queuepoly(Tleft, cgi.shHumanFoot, col); } if(DIM == 3 || !mmspatial) return spin(rightfoot * wobble); if(detaillevel >= 2 && who != moZombie) - queuepoly(mmscale(V, geom3::NECK1), shHumanNeck, col); + queuepoly(mmscale(V, cgi.NECK1), cgi.shHumanNeck, col); if(detaillevel >= 1) { - queuepoly(VGROIN, shHumanGroin, col); - if(who != moZombie) queuepoly(VNECK, shHumanNeck, col); + queuepoly(VGROIN, cgi.shHumanGroin, col); + if(who != moZombie) queuepoly(VNECK, cgi.shHumanNeck, col); } if(detaillevel >= 2) { - queuepoly(mmscale(V, geom3::GROIN1), shHumanGroin, col); - if(who != moZombie) queuepoly(mmscale(V, geom3::NECK3), shHumanNeck, col); + queuepoly(mmscale(V, cgi.GROIN1), cgi.shHumanGroin, col); + if(who != moZombie) queuepoly(mmscale(V, cgi.NECK3), cgi.shHumanNeck, col); } return spin(rightfoot * wobble); @@ -742,7 +740,7 @@ void addradar(const transmatrix& V, char ch, color_t col, color_t outline) { } else { if(d > max_eu_dist) max_eu_dist = d; - if(d) h = h * (d / (max_eu_dist + scalefactor/4) / hypot_d(3, h)); + if(d) h = h * (d / (max_eu_dist + cgi.scalefactor/4) / hypot_d(3, h)); } radarpoints.emplace_back(radarpoint{h, ch, col, outline}); } @@ -764,14 +762,14 @@ transmatrix face_the_player(const transmatrix V) { hpcshape& orbshape(eOrbshape s) { switch(s) { - case osLove: return shLoveRing; - case osRanged: return shTargetRing; - case osOffensive: return shSawRing; - case osFriend: return shPeaceRing; - case osUtility: return shGearRing; - case osDirectional: return shSpearRing; - case osWarping: return shHeptaRing; - default: return shRing; + case osLove: return cgi.shLoveRing; + case osRanged: return cgi.shTargetRing; + case osOffensive: return cgi.shSawRing; + case osFriend: return cgi.shPeaceRing; + case osUtility: return cgi.shGearRing; + case osDirectional: return cgi.shSpearRing; + case osWarping: return cgi.shHeptaRing; + default: return cgi.shRing; } } @@ -784,24 +782,24 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, color_t icol, int pti auto spinptick = [c, pticks] (int period, ld phase=0) { return c ? spintick(period, phase) : spin((animation_factor * pticks + phase) / period); }; int ct6 = c ? ctof(c) : 1; hpcshape *xsh = - (it == itPirate || it == itKraken) ? &shPirateX : - (it == itBuggy || it == itBuggy2) ? &shPirateX : - it == itHolyGrail ? &shGrail : - isElementalShard(it) ? &shElementalShard : - (it == itBombEgg || it == itTrollEgg) ? &shEgg : - it == itHunting ? &shTriangle : - it == itDodeca ? &shDodeca : - xch == '*' ? &shGem[ct6] : - xch == '(' ? &shKnife : - it == itShard ? &shMFloor.b[0] : - it == itTreat ? &shTreat : - it == itSlime ? &shEgg : - xch == '%' ? &shDaisy : xch == '$' ? &shStar : xch == ';' ? &shTriangle : - xch == '!' ? &shTriangle : it == itBone ? &shNecro : it == itStatue ? &shStatue : - it == itIvory ? &shFigurine : - xch == '?' ? &shBookCover : - it == itKey ? &shKey : - it == itRevolver ? &shGun : + (it == itPirate || it == itKraken) ? &cgi.shPirateX : + (it == itBuggy || it == itBuggy2) ? &cgi.shPirateX : + it == itHolyGrail ? &cgi.shGrail : + isElementalShard(it) ? &cgi.shElementalShard : + (it == itBombEgg || it == itTrollEgg) ? &cgi.shEgg : + it == itHunting ? &cgi.shTriangle : + it == itDodeca ? &cgi.shDodeca : + xch == '*' ? &cgi.shGem[ct6] : + xch == '(' ? &cgi.shKnife : + it == itShard ? &cgi.shMFloor.b[0] : + it == itTreat ? &cgi.shTreat : + it == itSlime ? &cgi.shEgg : + xch == '%' ? &cgi.shDaisy : xch == '$' ? &cgi.shStar : xch == ';' ? &cgi.shTriangle : + xch == '!' ? &cgi.shTriangle : it == itBone ? &cgi.shNecro : it == itStatue ? &cgi.shStatue : + it == itIvory ? &cgi.shFigurine : + xch == '?' ? &cgi.shBookCover : + it == itKey ? &cgi.shKey : + it == itRevolver ? &cgi.shGun : NULL; if(c && doHighlight()) @@ -813,10 +811,10 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, color_t icol, int pti if(DIM == 3 && mapeditor::drawUserShape(V, mapeditor::sgItem, it, darkena(icol, 0, 0xFF), c)) return false; - if(WDIM == 3 && c == viewctr.at->c7 && pmodel == mdPerspective && hdist0(tC0(V)) < orbsize * 0.25) return false; + if(WDIM == 3 && c == viewctr.at->c7 && pmodel == mdPerspective && hdist0(tC0(V)) < cgi.orbsize * 0.25) return false; transmatrix Vit = V; - if(GDIM == 3 && WDIM == 2 && c) Vit = mscale(V, geom3::STUFF); + if(GDIM == 3 && WDIM == 2 && c) Vit = mscale(V, cgi.STUFF); if(DIM == 3 && c) Vit = face_the_player(Vit); // V * cspin(0, 2, ptick(618, 0)); @@ -830,18 +828,18 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, color_t icol, int pti } else if(it == itStrongWind) { - queuepoly(Vit * spinptick(750), shFan, darkena(icol, 0, 255)); + queuepoly(Vit * spinptick(750), cgi.shFan, darkena(icol, 0, 255)); } else if(it == itWarning) { - queuepoly(Vit * spinptick(750), shTriangle, darkena(icol, 0, 255)); + queuepoly(Vit * spinptick(750), cgi.shTriangle, darkena(icol, 0, 255)); } else if(it == itBabyTortoise) { int bits = c ? tortoise::babymap[c] : tortoise::last; int over = c && c->monst == moTortoise; - tortoise::draw(Vit * spinptick(5000) * ypush(crossf*.15), bits, over ? 4 : 2, 0); - // queuepoly(Vit, shHeptaMarker, darkena(tortoise::getMatchColor(bits), 0, 0xC0)); + tortoise::draw(Vit * spinptick(5000) * ypush(cgi.crossf*.15), bits, over ? 4 : 2, 0); + // queuepoly(Vit, cgi.shHeptaMarker, darkena(tortoise::getMatchColor(bits), 0, 0xC0)); } else if(it == itCompass) { @@ -872,48 +870,48 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, color_t icol, int pti else V2 = V; } if(DIM == 3) { - queuepoly(Vit, shRing, 0xFFFFFFFF); - if(WDIM == 2) V2 = mscale(V2, geom3::STUFF); + queuepoly(Vit, cgi.shRing, 0xFFFFFFFF); + if(WDIM == 2) V2 = mscale(V2, cgi.STUFF); V2 = V2 * cspin(1, 2, M_PI * sintick(100) / 39); - queuepoly(V2, shCompass3, 0xFF0000FF); - queuepoly(V2 * pispin, shCompass3, 0x000000FF); + queuepoly(V2, cgi.shCompass3, 0xFF0000FF); + queuepoly(V2 * pispin, cgi.shCompass3, 0x000000FF); } else { if(c) V2 = V2 * spin(M_PI * sintick(100) / 30); - queuepoly(V2, shCompass1, 0xFF8080FF); - queuepoly(V2, shCompass2, 0xFFFFFFFF); - queuepoly(V2, shCompass3, 0xFF0000FF); - queuepoly(V2 * pispin, shCompass3, 0x000000FF); + queuepoly(V2, cgi.shCompass1, 0xFF8080FF); + queuepoly(V2, cgi.shCompass2, 0xFFFFFFFF); + queuepoly(V2, cgi.shCompass3, 0xFF0000FF); + queuepoly(V2 * pispin, cgi.shCompass3, 0x000000FF); } xsh = NULL; } else if(it == itPalace) { - ld h = geom3::human_height; + ld h = cgi.human_height; if(GDIM == 3 && WDIM == 2) { dynamicval qfi2(qfi, qfi); transmatrix V2 = V * spin(ticks / 1500.); /* divisors should be higher than in plate renderer */ - qfi.fshape = &shMFloor2; + qfi.fshape = &cgi.shMFloor2; draw_shapevec(c, V2 * zpush(-h/30), qfi.fshape->levels[0], 0xFFD500FF, PPR::WALL); - qfi.fshape = &shMFloor3; + qfi.fshape = &cgi.shMFloor3; draw_shapevec(c, V2 * zpush(-h/25), qfi.fshape->levels[0], darkena(icol, 0, 0xFF), PPR::WALL); - qfi.fshape = &shMFloor4; + qfi.fshape = &cgi.shMFloor4; draw_shapevec(c, V2 * zpush(-h/20), qfi.fshape->levels[0], 0xFFD500FF, PPR::WALL); } else if(WDIM == 3) { transmatrix V2 = Vit * spin(ticks / 1500.); - draw_floorshape(c, V2 * zpush(h/100), shMFloor3, 0xFFD500FF); - draw_floorshape(c, V2 * zpush(h/50), shMFloor4, darkena(icol, 0, 0xFF)); - queuepoly(V2, shGem[ct6], 0xFFD500FF); + draw_floorshape(c, V2 * zpush(h/100), cgi.shMFloor3, 0xFFD500FF); + draw_floorshape(c, V2 * zpush(h/50), cgi.shMFloor4, darkena(icol, 0, 0xFF)); + queuepoly(V2, cgi.shGem[ct6], 0xFFD500FF); } else { transmatrix V2 = Vit * spin(ticks / 1500.); - draw_floorshape(c, V2, shMFloor3, 0xFFD500FF); - draw_floorshape(c, V2, shMFloor4, darkena(icol, 0, 0xFF)); - queuepoly(V2, shGem[ct6], 0xFFD500FF); + draw_floorshape(c, V2, cgi.shMFloor3, 0xFFD500FF); + draw_floorshape(c, V2, cgi.shMFloor4, darkena(icol, 0, 0xFF)); + queuepoly(V2, cgi.shGem[ct6], 0xFFD500FF); } xsh = NULL; } @@ -922,7 +920,7 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, color_t icol, int pti else if(it == itRose) { for(int u=0; u<4; u++) - queuepoly(Vit * spinptick(1500) * spin(2*M_PI / 3 / 4 * u), shRoseItem, darkena(icol, 0, hidden ? 0x30 : 0xA0)); + queuepoly(Vit * spinptick(1500) * spin(2*M_PI / 3 / 4 * u), cgi.shRoseItem, darkena(icol, 0, hidden ? 0x30 : 0xA0)); } else if(it == itBarrow && c) { @@ -931,7 +929,7 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, color_t icol, int pti (highwall(c) && wmspatial) ? 0x60 : 0xFF), PPR::HIDDEN); -// queuepoly(Vit*spin(M_PI+(1-2*ang)*2*M_PI/S84), shMagicSword, darkena(0xC00000, 0, 0x80 + 0x70 * sin(ticks / 200.0))); +// queuepoly(Vit*spin(M_PI+(1-2*ang)*2*M_PI/cgi.S84), cgi.shMagicSword, darkena(0xC00000, 0, 0x80 + 0x70 * sin(ticks / 200.0))); } else if(xsh) { @@ -944,11 +942,11 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, color_t icol, int pti transmatrix V2 = Vit * spinptick(1500); - if(xsh == &shBookCover && mmitem) { + if(xsh == &cgi.shBookCover && mmitem) { if(DIM == 3) - queuepoly(V2 * cpush(2, 1e-3), shBook, 0x805020FF); + queuepoly(V2 * cpush(2, 1e-3), cgi.shBook, 0x805020FF); else - queuepoly(V2, shBook, 0x805020FF); + queuepoly(V2, cgi.shBook, 0x805020FF); } PPR pr = PPR::ITEM; @@ -980,9 +978,9 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, color_t icol, int pti color_t col = darkena(icol, 0, int(0x80 + 0x70 * sinptick(300))); if(it == itOrbFish) - queuepolyat(Vit * spinptick(1500), shFishTail, col, PPR::ITEM_BELOW); + queuepolyat(Vit * spinptick(1500), cgi.shFishTail, col, PPR::ITEM_BELOW); - queuepolyat(Vit, shDisk, darkena(icol1, 0, inice ? 0x80 : hidden ? 0x20 : 0xC0), prio); + queuepolyat(Vit, cgi.shDisk, darkena(icol1, 0, inice ? 0x80 : hidden ? 0x20 : 0xC0), prio); queuepolyat(Vit * spinptick(1500), orbshape(iinf[it].orbshape), col, prio); } @@ -995,17 +993,17 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, color_t icol, int pti #if CAP_SHAPES void drawTerraWarrior(const transmatrix& V, int t, int hp, double footphase) { - ShadowV(V, shPBody); + ShadowV(V, cgi.shPBody); color_t col = linf[laTerracotta].color; int bcol = darkena(false ? 0xC0B23E : col, 0, 0xFF); const transmatrix VBS = otherbodyparts(V, bcol, moDesertman, footphase); - queuepoly(VBODY * VBS, shPBody, bcol); - if(!peace::on) queuepoly(VBODY * VBS * Mirror, shPSword, darkena(0xC0C0C0, 0, 0xFF)); - queuepoly(VBODY1 * VBS, shTerraArmor1, darkena(t > 0 ? 0x4040FF : col, 0, 0xFF)); - if(hp >= 4) queuepoly(VBODY2 * VBS, shTerraArmor2, darkena(t > 1 ? 0xC00000 : col, 0, 0xFF)); - if(hp >= 2) queuepoly(VBODY3 * VBS, shTerraArmor3, darkena(t > 2 ? 0x612600 : col, 0, 0xFF)); - queuepoly(VHEAD, shTerraHead, darkena(t > 4 ? 0x202020 : t > 3 ? 0x504040 : col, 0, 0xFF)); - queuepoly(VHEAD1, shPFace, bcol); + queuepoly(VBODY * VBS, cgi.shPBody, bcol); + if(!peace::on) queuepoly(VBODY * VBS * Mirror, cgi.shPSword, darkena(0xC0C0C0, 0, 0xFF)); + queuepoly(VBODY1 * VBS, cgi.shTerraArmor1, darkena(t > 0 ? 0x4040FF : col, 0, 0xFF)); + if(hp >= 4) queuepoly(VBODY2 * VBS, cgi.shTerraArmor2, darkena(t > 1 ? 0xC00000 : col, 0, 0xFF)); + if(hp >= 2) queuepoly(VBODY3 * VBS, cgi.shTerraArmor3, darkena(t > 2 ? 0x612600 : col, 0, 0xFF)); + queuepoly(VHEAD, cgi.shTerraHead, darkena(t > 4 ? 0x202020 : t > 3 ? 0x504040 : col, 0, 0xFF)); + queuepoly(VHEAD1, cgi.shPFace, bcol); } #endif @@ -1013,8 +1011,8 @@ color_t skincolor = 0xD0C080FF; void humanoid_eyes(const transmatrix& V, color_t ecol, color_t hcol = skincolor) { if(DIM == 3) { - queuepoly(VHEAD, shPHeadOnly, hcol); - queuepoly(VHEAD, shSkullEyes, ecol); + queuepoly(VHEAD, cgi.shPHeadOnly, hcol); + queuepoly(VHEAD, cgi.shSkullEyes, ecol); } } @@ -1026,21 +1024,21 @@ void drawPlayer(eMonster m, cell *where, const transmatrix& V, color_t col, doub if(cs.charid >= 8) { /* famililar */ if(!mmspatial && !footphase) - queuepoly(VALEGS, shWolfLegs, fc(150, cs.dresscolor, 4)); + queuepoly(VALEGS, cgi.shWolfLegs, fc(150, cs.dresscolor, 4)); else { - ShadowV(V, shWolfBody); + ShadowV(V, cgi.shWolfBody); animallegs(VALEGS, moWolf, fc(500, cs.dresscolor, 4), footphase); } - queuepoly(VABODY, shWolfBody, fc(0, cs.skincolor, 0)); - queuepoly(VAHEAD, shFamiliarHead, fc(500, cs.haircolor, 2)); + queuepoly(VABODY, cgi.shWolfBody, fc(0, cs.skincolor, 0)); + queuepoly(VAHEAD, cgi.shFamiliarHead, fc(500, cs.haircolor, 2)); if(!shmup::on || shmup::curtime >= shmup::getPlayer()->nextshot) { color_t col = items[itOrbDiscord] ? watercolor(0) : fc(314, cs.eyecolor, 3); - queuepoly(VAHEAD, shFamiliarEye, col); - queuepoly(VAHEAD * Mirror, shFamiliarEye, col); + queuepoly(VAHEAD, cgi.shFamiliarEye, col); + queuepoly(VAHEAD * Mirror, cgi.shFamiliarEye, col); } if(knighted) - queuepoly(VABODY, shKnightCloak, darkena(cloakcolor(knighted), 1, 0xFF)); + queuepoly(VABODY, cgi.shKnightCloak, darkena(cloakcolor(knighted), 1, 0xFF)); if(tortoise::seek()) tortoise::draw(VABODY, tortoise::seekbits, 4, 0); @@ -1048,25 +1046,25 @@ void drawPlayer(eMonster m, cell *where, const transmatrix& V, color_t col, doub else if(cs.charid >= 6) { /* dog */ if(!mmspatial && !footphase) - queuepoly(VABODY, shDogBody, fc(0, cs.skincolor, 0)); + queuepoly(VABODY, cgi.shDogBody, fc(0, cs.skincolor, 0)); else { - ShadowV(V, shDogTorso); + ShadowV(V, cgi.shDogTorso); animallegs(VALEGS, moRunDog, fc(500, cs.dresscolor, 4), footphase); - queuepoly(VABODY, shDogTorso, fc(0, cs.skincolor, 0)); + queuepoly(VABODY, cgi.shDogTorso, fc(0, cs.skincolor, 0)); } - queuepoly(VAHEAD, shDogHead, fc(150, cs.haircolor, 2)); + queuepoly(VAHEAD, cgi.shDogHead, fc(150, cs.haircolor, 2)); if(!shmup::on || shmup::curtime >= shmup::getPlayer()->nextshot) { color_t col = items[itOrbDiscord] ? watercolor(0) : fc(314, cs.eyecolor, 3); - queuepoly(VAHEAD, shWolf1, col); - queuepoly(VAHEAD, shWolf2, col); + queuepoly(VAHEAD, cgi.shWolf1, col); + queuepoly(VAHEAD, cgi.shWolf2, col); } color_t colnose = items[itOrbDiscord] ? watercolor(0) : fc(314, 0xFF, 3); - queuepoly(VAHEAD, shWolf3, colnose); + queuepoly(VAHEAD, cgi.shWolf3, colnose); if(knighted) - queuepoly(VABODY, shKnightCloak, darkena(cloakcolor(knighted), 1, 0xFF)); + queuepoly(VABODY, cgi.shKnightCloak, darkena(cloakcolor(knighted), 1, 0xFF)); if(tortoise::seek()) tortoise::draw(VABODY, tortoise::seekbits, 4, 0); @@ -1074,21 +1072,21 @@ void drawPlayer(eMonster m, cell *where, const transmatrix& V, color_t col, doub else if(cs.charid >= 4) { /* cat */ if(!mmspatial && !footphase) - queuepoly(VALEGS, shCatLegs, fc(500, cs.dresscolor, 4)); + queuepoly(VALEGS, cgi.shCatLegs, fc(500, cs.dresscolor, 4)); else { - ShadowV(V, shCatBody); + ShadowV(V, cgi.shCatBody); animallegs(VALEGS, moRunDog, fc(500, cs.dresscolor, 4), footphase); } - queuepoly(VABODY, shCatBody, fc(0, cs.skincolor, 0)); - queuepoly(VAHEAD, shCatHead, fc(150, cs.haircolor, 2)); + queuepoly(VABODY, cgi.shCatBody, fc(0, cs.skincolor, 0)); + queuepoly(VAHEAD, cgi.shCatHead, fc(150, cs.haircolor, 2)); if(!shmup::on || shmup::curtime >= shmup::getPlayer()->nextshot) { color_t col = items[itOrbDiscord] ? watercolor(0) : fc(314, cs.eyecolor, 3); - queuepoly(VAHEAD * xpush(.04), shWolf1, col); - queuepoly(VAHEAD * xpush(.04), shWolf2, col); + queuepoly(VAHEAD * xpush(.04), cgi.shWolf1, col); + queuepoly(VAHEAD * xpush(.04), cgi.shWolf2, col); } if(knighted) - queuepoly(VABODY, shKnightCloak, darkena(cloakcolor(knighted), 1, 0xFF)); + queuepoly(VABODY, cgi.shKnightCloak, darkena(cloakcolor(knighted), 1, 0xFF)); if(tortoise::seek()) tortoise::draw(VABODY, tortoise::seekbits, 4, 0); @@ -1097,29 +1095,29 @@ void drawPlayer(eMonster m, cell *where, const transmatrix& V, color_t col, doub /* human */ const transmatrix VBS = otherbodyparts(V, fc(0, cs.skincolor, 0), items[itOrbFish] ? moWaterElemental : moPlayer, footphase); - queuepoly(VBODY * VBS, (cs.charid&1) ? shFemaleBody : shPBody, fc(0, cs.skincolor, 0)); + queuepoly(VBODY * VBS, (cs.charid&1) ? cgi.shFemaleBody : cgi.shPBody, fc(0, cs.skincolor, 0)); - ShadowV(V, (cs.charid&1) ? shFemaleBody : shPBody); + ShadowV(V, (cs.charid&1) ? cgi.shFemaleBody : cgi.shPBody); if(cs.charid&1) - queuepoly(VBODY1 * VBS, shFemaleDress, fc(500, cs.dresscolor, 4)); + queuepoly(VBODY1 * VBS, cgi.shFemaleDress, fc(500, cs.dresscolor, 4)); if(cs.charid == 2) - queuepoly(VBODY2 * VBS, shPrinceDress, fc(400, cs.dresscolor, 5)); + queuepoly(VBODY2 * VBS, cgi.shPrinceDress, fc(400, cs.dresscolor, 5)); if(cs.charid == 3) - queuepoly(VBODY2 * VBS, shPrincessDress, fc(400, cs.dresscolor2, 5)); + queuepoly(VBODY2 * VBS, cgi.shPrincessDress, fc(400, cs.dresscolor2, 5)); if(items[itOrbSide3]) - queuepoly(VBODY * VBS, (cs.charid&1) ? shFerocityF : shFerocityM, fc(0, cs.skincolor, 0)); + queuepoly(VBODY * VBS, (cs.charid&1) ? cgi.shFerocityF : cgi.shFerocityM, fc(0, cs.skincolor, 0)); if(items[itOrbHorns]) { - queuepoly(VBODY * VBS, shBullHead, items[itOrbDiscord] ? watercolor(0) : 0xFF000030); - queuepoly(VBODY * VBS, shBullHorn, items[itOrbDiscord] ? watercolor(0) : 0xFF000040); - queuepoly(VBODY * VBS * Mirror, shBullHorn, items[itOrbDiscord] ? watercolor(0) : 0xFF000040); + queuepoly(VBODY * VBS, cgi.shBullHead, items[itOrbDiscord] ? watercolor(0) : 0xFF000030); + queuepoly(VBODY * VBS, cgi.shBullHorn, items[itOrbDiscord] ? watercolor(0) : 0xFF000040); + queuepoly(VBODY * VBS * Mirror, cgi.shBullHorn, items[itOrbDiscord] ? watercolor(0) : 0xFF000040); } if(items[itOrbSide1] && !shmup::on) - queuepoly(VBODY * VBS * spin(-M_PI/24), cs.charid >= 2 ? shSabre : shPSword, fc(314, cs.swordcolor, 3)); // 3 not colored + queuepoly(VBODY * VBS * spin(-M_PI/24), cs.charid >= 2 ? cgi.shSabre : cgi.shPSword, fc(314, cs.swordcolor, 3)); // 3 not colored transmatrix VWPN = cs.lefthanded ? VBODY * VBS * Mirror : VBODY * VBS; @@ -1127,52 +1125,52 @@ void drawPlayer(eMonster m, cell *where, const transmatrix& V, color_t col, doub else if(racing::on) { #if CAP_RACING if(racing::trophy[multi::cpid]) - queuepoly(VWPN, shTrophy, racing::trophy[multi::cpid]); + queuepoly(VWPN, cgi.shTrophy, racing::trophy[multi::cpid]); #endif } else if(items[itOrbThorns]) - queuepoly(VWPN, shHedgehogBladePlayer, items[itOrbDiscord] ? watercolor(0) : 0x00FF00FF); + queuepoly(VWPN, cgi.shHedgehogBladePlayer, items[itOrbDiscord] ? watercolor(0) : 0x00FF00FF); else if(!shmup::on && items[itOrbDiscord]) - queuepoly(VWPN, cs.charid >= 2 ? shSabre : shPSword, watercolor(0)); + queuepoly(VWPN, cs.charid >= 2 ? cgi.shSabre : cgi.shPSword, watercolor(0)); else if(items[itRevolver]) - queuepoly(VWPN, shGunInHand, fc(314, cs.swordcolor, 3)); // 3 not colored + queuepoly(VWPN, cgi.shGunInHand, fc(314, cs.swordcolor, 3)); // 3 not colored else if(items[itOrbSlaying]) { - queuepoly(VWPN, shFlailTrunk, fc(314, cs.swordcolor, 3)); - queuepoly(VWPN, shHammerHead, fc(314, cs.swordcolor, 3)); + queuepoly(VWPN, cgi.shFlailTrunk, fc(314, cs.swordcolor, 3)); + queuepoly(VWPN, cgi.shHammerHead, fc(314, cs.swordcolor, 3)); } else if(!shmup::on) - queuepoly(VWPN, cs.charid >= 2 ? shSabre : shPSword, fc(314, cs.swordcolor, 3)); // 3 not colored + queuepoly(VWPN, cs.charid >= 2 ? cgi.shSabre : cgi.shPSword, fc(314, cs.swordcolor, 3)); // 3 not colored else if(shmup::curtime >= shmup::getPlayer()->nextshot) - queuepoly(VWPN, shPKnife, fc(314, cs.swordcolor, 3)); // 3 not colored + queuepoly(VWPN, cgi.shPKnife, fc(314, cs.swordcolor, 3)); // 3 not colored if(items[itOrbBeauty]) { if(cs.charid&1) - queuepoly(VHEAD1, shFlowerHair, darkena(iinf[itOrbBeauty].color, 0, 0xFF)); + queuepoly(VHEAD1, cgi.shFlowerHair, darkena(iinf[itOrbBeauty].color, 0, 0xFF)); else - queuepoly(VWPN, shFlowerHand, darkena(iinf[itOrbBeauty].color, 0, 0xFF)); + queuepoly(VWPN, cgi.shFlowerHand, darkena(iinf[itOrbBeauty].color, 0, 0xFF)); } if(where && where->land == laWildWest) { - queuepoly(VHEAD1, shWestHat1, darkena(cs.swordcolor, 1, 0XFF)); - queuepoly(VHEAD2, shWestHat2, darkena(cs.swordcolor, 0, 0XFF)); + queuepoly(VHEAD1, cgi.shWestHat1, darkena(cs.swordcolor, 1, 0XFF)); + queuepoly(VHEAD2, cgi.shWestHat2, darkena(cs.swordcolor, 0, 0XFF)); } if(cheater && !autocheat) { - queuepoly(VHEAD1, (cs.charid&1) ? shGoatHead : shDemon, darkena(0xFFFF00, 0, 0xFF)); + queuepoly(VHEAD1, (cs.charid&1) ? cgi.shGoatHead : cgi.shDemon, darkena(0xFFFF00, 0, 0xFF)); // queuepoly(V, shHood, darkena(0xFF00, 1, 0xFF)); } else { - queuepoly(VHEAD, shPFace, fc(500, cs.skincolor, 1)); - queuepoly(VHEAD1, (cs.charid&1) ? shFemaleHair : shPHead, fc(150, cs.haircolor, 2)); + queuepoly(VHEAD, cgi.shPFace, fc(500, cs.skincolor, 1)); + queuepoly(VHEAD1, (cs.charid&1) ? cgi.shFemaleHair : cgi.shPHead, fc(150, cs.haircolor, 2)); } humanoid_eyes(V, cs.eyecolor, cs.skincolor); if(knighted) - queuepoly(VBODY * VBS, shKnightCloak, darkena(cloakcolor(knighted), 1, 0xFF)); + queuepoly(VBODY * VBS, cgi.shKnightCloak, darkena(cloakcolor(knighted), 1, 0xFF)); if(tortoise::seek()) - tortoise::draw(VBODY * VBS * ypush(-crossf*.25), tortoise::seekbits, 4, 0); + tortoise::draw(VBODY * VBS * ypush(-cgi.crossf*.25), tortoise::seekbits, 4, 0); } } } @@ -1195,71 +1193,71 @@ void drawMimic(eMonster m, cell *where, const transmatrix& V, color_t col, doubl if(mapeditor::drawUserShape(V, mapeditor::sgPlayer, cs.charid, darkena(col, 0, 0x80), where)) return; if(cs.charid >= 8) { - queuepoly(VABODY, shWolfBody, darkena(col, 0, 0xC0)); - ShadowV(V, shWolfBody); + queuepoly(VABODY, cgi.shWolfBody, darkena(col, 0, 0xC0)); + ShadowV(V, cgi.shWolfBody); if(mmspatial || footphase) animallegs(VALEGS, moWolf, darkena(col, 0, 0xC0), footphase); else - queuepoly(VABODY, shWolfLegs, darkena(col, 0, 0xC0)); + queuepoly(VABODY, cgi.shWolfLegs, darkena(col, 0, 0xC0)); - queuepoly(VABODY, shFamiliarHead, darkena(col, 0, 0xC0)); - queuepoly(VAHEAD, shFamiliarEye, darkena(col, 0, 0xC0)); - queuepoly(VAHEAD * Mirror, shFamiliarEye, darkena(col, 0, 0xC0)); + queuepoly(VABODY, cgi.shFamiliarHead, darkena(col, 0, 0xC0)); + queuepoly(VAHEAD, cgi.shFamiliarEye, darkena(col, 0, 0xC0)); + queuepoly(VAHEAD * Mirror, cgi.shFamiliarEye, darkena(col, 0, 0xC0)); } else if(cs.charid >= 6) { - ShadowV(V, shDogBody); - queuepoly(VAHEAD, shDogHead, darkena(col, 0, 0xC0)); + ShadowV(V, cgi.shDogBody); + queuepoly(VAHEAD, cgi.shDogHead, darkena(col, 0, 0xC0)); if(mmspatial || footphase) { animallegs(VALEGS, moRunDog, darkena(col, 0, 0xC0), footphase); - queuepoly(VABODY, shDogTorso, darkena(col, 0, 0xC0)); + queuepoly(VABODY, cgi.shDogTorso, darkena(col, 0, 0xC0)); } else - queuepoly(VABODY, shDogBody, darkena(col, 0, 0xC0)); - queuepoly(VABODY, shWolf1, darkena(col, 1, 0xC0)); - queuepoly(VABODY, shWolf2, darkena(col, 1, 0xC0)); - queuepoly(VABODY, shWolf3, darkena(col, 1, 0xC0)); + queuepoly(VABODY, cgi.shDogBody, darkena(col, 0, 0xC0)); + queuepoly(VABODY, cgi.shWolf1, darkena(col, 1, 0xC0)); + queuepoly(VABODY, cgi.shWolf2, darkena(col, 1, 0xC0)); + queuepoly(VABODY, cgi.shWolf3, darkena(col, 1, 0xC0)); } else if(cs.charid >= 4) { - ShadowV(V, shCatBody); - queuepoly(VABODY, shCatBody, darkena(col, 0, 0xC0)); - queuepoly(VAHEAD, shCatHead, darkena(col, 0, 0xC0)); + ShadowV(V, cgi.shCatBody); + queuepoly(VABODY, cgi.shCatBody, darkena(col, 0, 0xC0)); + queuepoly(VAHEAD, cgi.shCatHead, darkena(col, 0, 0xC0)); if(mmspatial || footphase) animallegs(VALEGS, moRunDog, darkena(col, 0, 0xC0), footphase); else - queuepoly(VALEGS, shCatLegs, darkena(col, 0, 0xC0)); - queuepoly(VAHEAD * xpush(.04), shWolf1, darkena(col, 1, 0xC0)); - queuepoly(VAHEAD * xpush(.04), shWolf2, darkena(col, 1, 0xC0)); + queuepoly(VALEGS, cgi.shCatLegs, darkena(col, 0, 0xC0)); + queuepoly(VAHEAD * xpush(.04), cgi.shWolf1, darkena(col, 1, 0xC0)); + queuepoly(VAHEAD * xpush(.04), cgi.shWolf2, darkena(col, 1, 0xC0)); } else { const transmatrix VBS = otherbodyparts(V, darkena(col, 0, 0x40), m, footphase); - queuepoly(VBODY * VBS, (cs.charid&1) ? shFemaleBody : shPBody, darkena(col, 0, 0X80)); + queuepoly(VBODY * VBS, (cs.charid&1) ? cgi.shFemaleBody : cgi.shPBody, darkena(col, 0, 0X80)); if(!shmup::on) { bool emp = items[itOrbEmpathy] && m != moShadow; if(items[itOrbThorns] && emp) - queuepoly(VBODY * VBS, shHedgehogBladePlayer, darkena(col, 0, 0x40)); + queuepoly(VBODY * VBS, cgi.shHedgehogBladePlayer, darkena(col, 0, 0x40)); if(items[itOrbSide1] && !shmup::on) - queuepoly(VBODY * VBS * spin(-M_PI/24), cs.charid >= 2 ? shSabre : shPSword, darkena(col, 0, 0x40)); + queuepoly(VBODY * VBS * spin(-M_PI/24), cs.charid >= 2 ? cgi.shSabre : cgi.shPSword, darkena(col, 0, 0x40)); if(items[itOrbSide3] && emp) - queuepoly(VBODY * VBS, (cs.charid&1) ? shFerocityF : shFerocityM, darkena(col, 0, 0x40)); + queuepoly(VBODY * VBS, (cs.charid&1) ? cgi.shFerocityF : cgi.shFerocityM, darkena(col, 0, 0x40)); - queuepoly(VBODY * VBS, (cs.charid >= 2 ? shSabre : shPSword), darkena(col, 0, 0XC0)); + queuepoly(VBODY * VBS, (cs.charid >= 2 ? cgi.shSabre : cgi.shPSword), darkena(col, 0, 0XC0)); } else if(!where || shmup::curtime >= shmup::getPlayer()->nextshot) - queuepoly(VBODY * VBS, shPKnife, darkena(col, 0, 0XC0)); + queuepoly(VBODY * VBS, cgi.shPKnife, darkena(col, 0, 0XC0)); if(knighted) - queuepoly(VBODY3 * VBS, shKnightCloak, darkena(col, 1, 0xC0)); + queuepoly(VBODY3 * VBS, cgi.shKnightCloak, darkena(col, 1, 0xC0)); - queuepoly(VHEAD1, (cs.charid&1) ? shFemaleHair : shPHead, darkena(col, 1, 0XC0)); - queuepoly(VHEAD, shPFace, darkena(col, 0, 0XC0)); + queuepoly(VHEAD1, (cs.charid&1) ? cgi.shFemaleHair : cgi.shPHead, darkena(col, 1, 0XC0)); + queuepoly(VHEAD, cgi.shPFace, darkena(col, 0, 0XC0)); if(cs.charid&1) - queuepoly(VBODY1 * VBS, shFemaleDress, darkena(col, 1, 0XC0)); + queuepoly(VBODY1 * VBS, cgi.shFemaleDress, darkena(col, 1, 0XC0)); if(cs.charid == 2) - queuepoly(VBODY2 * VBS, shPrinceDress, darkena(col, 1, 0XC0)); + queuepoly(VBODY2 * VBS, cgi.shPrinceDress, darkena(col, 1, 0XC0)); if(cs.charid == 3) - queuepoly(VBODY2 * VBS, shPrincessDress, darkena(col, 1, 0XC0)); + queuepoly(VBODY2 * VBS, cgi.shPrincessDress, darkena(col, 1, 0XC0)); humanoid_eyes(V, 0xFF, darkena(col, 0, 0x40)); } @@ -1294,7 +1292,7 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V1, color_t col int bits = where ? tortoise::getb(where) : tortoise::last; tortoise::draw(V, bits, 0, where ? where->stuntime : 0); if(tortoise::seek() && !tortoise::diff(bits) && where) - queuepoly(V, shRing, darkena(0xFFFFFF, 0, 0x80 + 0x70 * sintick(200))); + queuepoly(V, cgi.shRing, darkena(0xFFFFFF, 0, 0x80 + 0x70 * sintick(200))); return false; } @@ -1307,43 +1305,43 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V1, color_t col return false; case moBullet: - ShadowV(V, shKnife); - queuepoly(VBODY * spin(-M_PI/4), shKnife, getcs().swordcolor); + ShadowV(V, cgi.shKnife); + queuepoly(VBODY * spin(-M_PI/4), cgi.shKnife, getcs().swordcolor); return false; case moKnight: case moKnightMoved: { - ShadowV(V, shPBody); + ShadowV(V, cgi.shPBody); const transmatrix VBS = otherbodyparts(V, darkena(0xC0C0A0, 0, 0xC0), m, footphase); - queuepoly(VBODY * VBS, shPBody, darkena(0xC0C0A0, 0, 0xC0)); + queuepoly(VBODY * VBS, cgi.shPBody, darkena(0xC0C0A0, 0, 0xC0)); if(!racing::on) - queuepoly(VBODY * VBS, shPSword, darkena(0xFFFF00, 0, 0xFF)); - queuepoly(VBODY1 * VBS, shKnightArmor, darkena(0xD0D0D0, 1, 0xFF)); + queuepoly(VBODY * VBS, cgi.shPSword, darkena(0xFFFF00, 0, 0xFF)); + queuepoly(VBODY1 * VBS, cgi.shKnightArmor, darkena(0xD0D0D0, 1, 0xFF)); color_t col; if(!eubinary && where && where->master->alt) col = cloakcolor(roundTableRadius(where)); else col = cloakcolor(newRoundTableRadius()); - queuepoly(VBODY2 * VBS, shKnightCloak, darkena(col, 1, 0xFF)); - queuepoly(VHEAD1, shPHead, darkena(0x703800, 1, 0XFF)); - queuepoly(VHEAD, shPFace, darkena(0xC0C0A0, 0, 0XFF)); + queuepoly(VBODY2 * VBS, cgi.shKnightCloak, darkena(col, 1, 0xFF)); + queuepoly(VHEAD1, cgi.shPHead, darkena(0x703800, 1, 0XFF)); + queuepoly(VHEAD, cgi.shPFace, darkena(0xC0C0A0, 0, 0XFF)); humanoid_eyes(V, 0x000000FF); return false; } case moGolem: case moGolemMoved: { - ShadowV(V, shPBody); + ShadowV(V, cgi.shPBody); const transmatrix VBS = otherbodyparts(V, darkena(col, 1, 0XC0), m, footphase); - queuepoly(VBODY * VBS, shPBody, darkena(col, 0, 0XC0)); - queuepoly(VHEAD, shGolemhead, darkena(col, 1, 0XFF)); + queuepoly(VBODY * VBS, cgi.shPBody, darkena(col, 0, 0XC0)); + queuepoly(VHEAD, cgi.shGolemhead, darkena(col, 1, 0XFF)); humanoid_eyes(V, 0xC0C000FF, darkena(col, 0, 0xFF)); return false; } case moEvilGolem: case moIceGolem: { const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 2, 0xC0), m, footphase); - ShadowV(V, shPBody); - queuepoly(VBS, shPBody, darkena(col, 0, 0XC0)); - queuepoly(VHEAD, shGolemhead, darkena(col, 1, 0XFF)); + ShadowV(V, cgi.shPBody); + queuepoly(VBS, cgi.shPBody, darkena(col, 0, 0XC0)); + queuepoly(VHEAD, cgi.shGolemhead, darkena(col, 1, 0XFF)); humanoid_eyes(V, 0xFF0000FF, darkena(col, 0, 0xFF)); return false; } @@ -1355,126 +1353,126 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V1, color_t col int facecolor = evil ? 0xC0B090FF : 0xD0C080FF; - ShadowV(V, girl ? shFemaleBody : shPBody); + ShadowV(V, girl ? cgi.shFemaleBody : cgi.shPBody); const transmatrix VBS = otherbodyparts(V, facecolor, m, footphase); - queuepoly(VBODY * VBS, girl ? shFemaleBody : shPBody, facecolor); + queuepoly(VBODY * VBS, girl ? cgi.shFemaleBody : cgi.shPBody, facecolor); if(m == moPrincessArmed) - queuepoly(VBODY * VBS * Mirror, vid.cs.charid < 2 ? shSabre : shPSword, 0xFFFFFFFF); + queuepoly(VBODY * VBS * Mirror, vid.cs.charid < 2 ? cgi.shSabre : cgi.shPSword, 0xFFFFFFFF); if((m == moFalsePrincess || m == moRoseBeauty) && where && where->cpdist == 1) - queuepoly(VBODY * VBS, shPKnife, 0xFFFFFFFF); + queuepoly(VBODY * VBS, cgi.shPKnife, 0xFFFFFFFF); if(m == moRoseLady) { - queuepoly(VBODY * VBS, shPKnife, 0xFFFFFFFF); - queuepoly(VBODY * VBS * Mirror, shPKnife, 0xFFFFFFFF); + queuepoly(VBODY * VBS, cgi.shPKnife, 0xFFFFFFFF); + queuepoly(VBODY * VBS * Mirror, cgi.shPKnife, 0xFFFFFFFF); } if(girl) { - queuepoly(VBODY1 * VBS, shFemaleDress, evil ? 0xC000C0FF : 0x00C000FF); + queuepoly(VBODY1 * VBS, cgi.shFemaleDress, evil ? 0xC000C0FF : 0x00C000FF); if(vid.cs.charid < 2) - queuepoly(VBODY2 * VBS, shPrincessDress, (evil ? 0xC040C0C0 : 0x8080FFC0) | UNTRANS); + queuepoly(VBODY2 * VBS, cgi.shPrincessDress, (evil ? 0xC040C0C0 : 0x8080FFC0) | UNTRANS); } else { if(vid.cs.charid < 2) - queuepoly(VBODY1 * VBS, shPrinceDress, evil ? 0x802080FF : 0x404040FF); + queuepoly(VBODY1 * VBS, cgi.shPrinceDress, evil ? 0x802080FF : 0x404040FF); } if(m == moRoseLady) { - // queuepoly(V, girl ? shGoatHead : shDemon, 0x800000FF); + // queuepoly(V, girl ? cgi.shGoatHead : cgi.shDemon, 0x800000FF); // make her hair a bit darker to stand out in 3D - queuepoly(VHEAD1, girl ? shFemaleHair : shPHead, evil ? 0x500050FF : DIM == 3 ? 0x666A64FF : 0x332A22FF); + queuepoly(VHEAD1, girl ? cgi.shFemaleHair : cgi.shPHead, evil ? 0x500050FF : DIM == 3 ? 0x666A64FF : 0x332A22FF); } else if(m == moRoseBeauty) { if(girl) { - queuepoly(VHEAD1, shBeautyHair, 0xF0A0D0FF); - queuepoly(VHEAD2, shFlowerHair, 0xC00000FF); + queuepoly(VHEAD1, cgi.shBeautyHair, 0xF0A0D0FF); + queuepoly(VHEAD2, cgi.shFlowerHair, 0xC00000FF); } else { - queuepoly(VHEAD1, shPHead, 0xF0A0D0FF); - queuepoly(VBS, shFlowerHand, 0xC00000FF); - queuepoly(VBODY2 * VBS, shSuspenders, 0xC00000FF); + queuepoly(VHEAD1, cgi.shPHead, 0xF0A0D0FF); + queuepoly(VBS, cgi.shFlowerHand, 0xC00000FF); + queuepoly(VBODY2 * VBS, cgi.shSuspenders, 0xC00000FF); } } else { - queuepoly(VHEAD1, girl ? shFemaleHair : shPHead, + queuepoly(VHEAD1, girl ? cgi.shFemaleHair : cgi.shPHead, evil ? 0xC00000FF : 0x332A22FF); } - queuepoly(VHEAD, shPFace, facecolor); + queuepoly(VHEAD, cgi.shPFace, facecolor); humanoid_eyes(V, evil ? 0x0000C0FF : 0x00C000FF, facecolor); return false; } case moWolf: case moRedFox: case moWolfMoved: case moLavaWolf: { - ShadowV(V, shWolfBody); + ShadowV(V, cgi.shWolfBody); if(mmspatial || footphase) animallegs(VALEGS, moWolf, darkena(col, 0, 0xFF), footphase); else - queuepoly(VALEGS, shWolfLegs, darkena(col, 0, 0xFF)); - queuepoly(VABODY, shWolfBody, darkena(col, 0, 0xFF)); + queuepoly(VALEGS, cgi.shWolfLegs, darkena(col, 0, 0xFF)); + queuepoly(VABODY, cgi.shWolfBody, darkena(col, 0, 0xFF)); if(m == moRedFox) { - queuepoly(VABODY, shFoxTail1, darkena(col, 0, 0xFF)); - queuepoly(VABODY, shFoxTail2, darkena(0xFFFFFF, 0, 0xFF)); + queuepoly(VABODY, cgi.shFoxTail1, darkena(col, 0, 0xFF)); + queuepoly(VABODY, cgi.shFoxTail2, darkena(0xFFFFFF, 0, 0xFF)); } - queuepoly(VAHEAD, shWolfHead, darkena(col, 0, 0xFF)); - queuepoly(VAHEAD, shWolfEyes, darkena(col, 3, 0xFF)); + queuepoly(VAHEAD, cgi.shWolfHead, darkena(col, 0, 0xFF)); + queuepoly(VAHEAD, cgi.shWolfEyes, darkena(col, 3, 0xFF)); if(DIM == 3) { - queuepoly(VAHEAD, shFamiliarEye, 0xFF); - queuepoly(VAHEAD * Mirror, shFamiliarEye, 0xFF); + queuepoly(VAHEAD, cgi.shFamiliarEye, 0xFF); + queuepoly(VAHEAD * Mirror, cgi.shFamiliarEye, 0xFF); } return false; } case moReptile: { - ShadowV(V, shReptileBody); + ShadowV(V, cgi.shReptileBody); animallegs(VALEGS, moReptile, darkena(col, 0, 0xFF), footphase); - queuepoly(VABODY, shReptileBody, darkena(col, 0, 0xFF)); - queuepoly(VAHEAD, shReptileHead, darkena(col, 0, 0xFF)); - queuepoly(VAHEAD, shReptileEye, darkena(col, 3, 0xFF)); - queuepoly(VAHEAD * Mirror, shReptileEye, darkena(col, 3, 0xFF)); - queuepoly(VABODY, shReptileTail, darkena(col, 2, 0xFF)); + queuepoly(VABODY, cgi.shReptileBody, darkena(col, 0, 0xFF)); + queuepoly(VAHEAD, cgi.shReptileHead, darkena(col, 0, 0xFF)); + queuepoly(VAHEAD, cgi.shReptileEye, darkena(col, 3, 0xFF)); + queuepoly(VAHEAD * Mirror, cgi.shReptileEye, darkena(col, 3, 0xFF)); + queuepoly(VABODY, cgi.shReptileTail, darkena(col, 2, 0xFF)); return false; } case moSalamander: { - ShadowV(V, shReptileBody); + ShadowV(V, cgi.shReptileBody); animallegs(VALEGS, moReptile, darkena(0xD00000, 1, 0xFF), footphase); - queuepoly(VABODY, shReptileBody, darkena(0xD00000, 0, 0xFF)); - queuepoly(VAHEAD, shReptileHead, darkena(0xD00000, 1, 0xFF)); - queuepoly(VAHEAD, shReptileEye, darkena(0xD00000, 0, 0xFF)); - queuepoly(VAHEAD * Mirror, shReptileEye, darkena(0xD00000, 0, 0xFF)); - queuepoly(VABODY, shReptileTail, darkena(0xD08000, 0, 0xFF)); + queuepoly(VABODY, cgi.shReptileBody, darkena(0xD00000, 0, 0xFF)); + queuepoly(VAHEAD, cgi.shReptileHead, darkena(0xD00000, 1, 0xFF)); + queuepoly(VAHEAD, cgi.shReptileEye, darkena(0xD00000, 0, 0xFF)); + queuepoly(VAHEAD * Mirror, cgi.shReptileEye, darkena(0xD00000, 0, 0xFF)); + queuepoly(VABODY, cgi.shReptileTail, darkena(0xD08000, 0, 0xFF)); return false; } case moVineBeast: { - ShadowV(V, shWolfBody); + ShadowV(V, cgi.shWolfBody); if(mmspatial || footphase) animallegs(VALEGS, moWolf, 0x00FF00FF, footphase); else - queuepoly(VALEGS, shWolfLegs, 0x00FF00FF); - queuepoly(VABODY, shWolfBody, darkena(col, 1, 0xFF)); - queuepoly(VAHEAD, shWolfHead, darkena(col, 0, 0xFF)); - queuepoly(VAHEAD, shWolfEyes, 0xFF0000FF); + queuepoly(VALEGS, cgi.shWolfLegs, 0x00FF00FF); + queuepoly(VABODY, cgi.shWolfBody, darkena(col, 1, 0xFF)); + queuepoly(VAHEAD, cgi.shWolfHead, darkena(col, 0, 0xFF)); + queuepoly(VAHEAD, cgi.shWolfEyes, 0xFF0000FF); return false; } case moMouse: case moMouseMoved: { - queuepoly(VALEGS, shMouse, darkena(col, 0, 0xFF)); - queuepoly(VALEGS, shMouseLegs, darkena(col, 1, 0xFF)); - queuepoly(VALEGS, shMouseEyes, 0xFF); + queuepoly(VALEGS, cgi.shMouse, darkena(col, 0, 0xFF)); + queuepoly(VALEGS, cgi.shMouseLegs, darkena(col, 1, 0xFF)); + queuepoly(VALEGS, cgi.shMouseEyes, 0xFF); return false; } case moRunDog: case moHunterDog: case moHunterGuard: case moHunterChanging: case moFallingDog: { if(!mmspatial && !footphase) - queuepoly(VABODY, shDogBody, darkena(col, 0, 0xFF)); + queuepoly(VABODY, cgi.shDogBody, darkena(col, 0, 0xFF)); else { - ShadowV(V, shDogTorso); - queuepoly(VABODY, shDogTorso, darkena(col, 0, 0xFF)); + ShadowV(V, cgi.shDogTorso); + queuepoly(VABODY, cgi.shDogTorso, darkena(col, 0, 0xFF)); animallegs(VALEGS, moRunDog, m == moFallingDog ? 0xFFFFFFFF : darkena(col, 0, 0xFF), footphase); } - queuepoly(VAHEAD, shDogHead, darkena(col, 0, 0xFF)); + queuepoly(VAHEAD, cgi.shDogHead, darkena(col, 0, 0xFF)); { dynamicval dp(poly_outline); @@ -1486,38 +1484,38 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V1, color_t col int eyes = darkena(eyecolor, 0, 0xFF); if(redeyes) poly_outline = eyes; - queuepoly(VAHEAD, shWolf1, eyes).flags |= POLY_FORCEWIDE; - queuepoly(VAHEAD, shWolf2, eyes).flags |= POLY_FORCEWIDE; + queuepoly(VAHEAD, cgi.shWolf1, eyes).flags |= POLY_FORCEWIDE; + queuepoly(VAHEAD, cgi.shWolf2, eyes).flags |= POLY_FORCEWIDE; } - queuepoly(VAHEAD, shWolf3, darkena(m == moRunDog ? 0x202020 : 0x000000, 0, 0xFF)); + queuepoly(VAHEAD, cgi.shWolf3, darkena(m == moRunDog ? 0x202020 : 0x000000, 0, 0xFF)); return false; } case moOrangeDog: { if(!mmspatial && !footphase) - queuepoly(VABODY, shDogBody, darkena(0xFFFFFF, 0, 0xFF)); + queuepoly(VABODY, cgi.shDogBody, darkena(0xFFFFFF, 0, 0xFF)); else { - ShadowV(V, shDogTorso); - queuepoly(VABODY, shDogTorso, darkena(0xFFFFFF, 0, 0xFF)); + ShadowV(V, cgi.shDogTorso); + queuepoly(VABODY, cgi.shDogTorso, darkena(0xFFFFFF, 0, 0xFF)); animallegs(VALEGS, moRunDog, darkena(0xFFFFFF, 0, 0xFF), footphase); } - queuepoly(VAHEAD, shDogHead, darkena(0xFFFFFF, 0, 0xFF)); - queuepoly(VABODY, shDogStripes, darkena(0x303030, 0, 0xFF)); - queuepoly(VAHEAD, shWolf1, darkena(0x202020, 0, 0xFF)); - queuepoly(VAHEAD, shWolf2, darkena(0x202020, 0, 0xFF)); - queuepoly(VAHEAD, shWolf3, darkena(0x202020, 0, 0xFF)); + queuepoly(VAHEAD, cgi.shDogHead, darkena(0xFFFFFF, 0, 0xFF)); + queuepoly(VABODY, cgi.shDogStripes, darkena(0x303030, 0, 0xFF)); + queuepoly(VAHEAD, cgi.shWolf1, darkena(0x202020, 0, 0xFF)); + queuepoly(VAHEAD, cgi.shWolf2, darkena(0x202020, 0, 0xFF)); + queuepoly(VAHEAD, cgi.shWolf3, darkena(0x202020, 0, 0xFF)); return false; } case moShark: case moGreaterShark: case moCShark: - queuepoly(VFISH, shShark, darkena(col, 0, 0xFF)); + queuepoly(VFISH, cgi.shShark, darkena(col, 0, 0xFF)); return false; case moEagle: case moParrot: case moBomberbird: case moAlbatross: case moTameBomberbird: case moWindCrow: case moTameBomberbirdMoved: case moSandBird: case moAcidBird: { - ShadowV(V, shEagle); - auto& sh = DIM == 3 ? shAnimatedEagle[wingphase(200)] : shEagle; + ShadowV(V, cgi.shEagle); + auto& sh = DIM == 3 ? cgi.shAnimatedEagle[wingphase(200)] : cgi.shEagle; if(m == moParrot && DIM == 3) queuepolyat(VBIRD, sh, darkena(col, 0, 0xFF), PPR::SUPERLINE); else @@ -1526,60 +1524,60 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V1, color_t col } case moSparrowhawk: case moWestHawk: { - ShadowV(V, shHawk); - auto& sh = DIM == 3 ? shAnimatedHawk[wingphase(200)] : shHawk; + ShadowV(V, cgi.shHawk); + auto& sh = DIM == 3 ? cgi.shAnimatedHawk[wingphase(200)] : cgi.shHawk; queuepoly(VBIRD, sh, darkena(col, 0, 0xFF)); return false; } case moButterfly: { transmatrix Vwing = wingmatrix(100); - ShadowV(V * Vwing, shButterflyWing); + ShadowV(V * Vwing, cgi.shButterflyWing); if(DIM == 2) - queuepoly(VBIRD * Vwing, shButterflyWing, darkena(col, 0, 0xFF)); + queuepoly(VBIRD * Vwing, cgi.shButterflyWing, darkena(col, 0, 0xFF)); else - queuepoly(VBIRD, shAnimatedButterfly[wingphase(100)], darkena(col, 0, 0xFF)); - queuepoly(VBIRD, shButterflyBody, darkena(col, 2, 0xFF)); + queuepoly(VBIRD, cgi.shAnimatedButterfly[wingphase(100)], darkena(col, 0, 0xFF)); + queuepoly(VBIRD, cgi.shButterflyBody, darkena(col, 2, 0xFF)); return false; } case moGadfly: { transmatrix Vwing = wingmatrix(100); - ShadowV(V * Vwing, shGadflyWing); - queuepoly(VBIRD * Vwing, DIM == 2 ? shGadflyWing : shAnimatedGadfly[wingphase(100)], darkena(col, 0, 0xFF)); - queuepoly(VBIRD, shGadflyBody, darkena(col, 1, 0xFF)); - queuepoly(VBIRD, shGadflyEye, darkena(col, 2, 0xFF)); - queuepoly(VBIRD * Mirror, shGadflyEye, darkena(col, 2, 0xFF)); + ShadowV(V * Vwing, cgi.shGadflyWing); + queuepoly(VBIRD * Vwing, DIM == 2 ? cgi.shGadflyWing : cgi.shAnimatedGadfly[wingphase(100)], darkena(col, 0, 0xFF)); + queuepoly(VBIRD, cgi.shGadflyBody, darkena(col, 1, 0xFF)); + queuepoly(VBIRD, cgi.shGadflyEye, darkena(col, 2, 0xFF)); + queuepoly(VBIRD * Mirror, cgi.shGadflyEye, darkena(col, 2, 0xFF)); return false; } case moVampire: case moBat: { // vampires have no shadow and no mirror images - if(m == moBat) ShadowV(V, shBatWings); + if(m == moBat) ShadowV(V, cgi.shBatWings); if(m == moBat || !inmirrorcount) { - queuepoly(VBIRD, DIM == 2 ? shBatWings : shAnimatedBat[wingphase(100)], darkena(0x303030, 0, 0xFF)); - queuepoly(VBIRD, DIM == 2 ? shBatBody : shAnimatedBat2[wingphase(100)], darkena(0x606060, 0, 0xFF)); + queuepoly(VBIRD, DIM == 2 ? cgi.shBatWings : cgi.shAnimatedBat[wingphase(100)], darkena(0x303030, 0, 0xFF)); + queuepoly(VBIRD, DIM == 2 ? cgi.shBatBody : cgi.shAnimatedBat2[wingphase(100)], darkena(0x606060, 0, 0xFF)); } - /* queuepoly(V, shBatMouth, darkena(0xC00000, 0, 0xFF)); - queuepoly(V, shBatFang, darkena(0xFFC0C0, 0, 0xFF)); - queuepoly(V*Mirror, shBatFang, darkena(0xFFC0C0, 0, 0xFF)); - queuepoly(V, shBatEye, darkena(00000000, 0, 0xFF)); - queuepoly(V*Mirror, shBatEye, darkena(00000000, 0, 0xFF)); */ + /* queuepoly(V, cgi.shBatMouth, darkena(0xC00000, 0, 0xFF)); + queuepoly(V, cgi.shBatFang, darkena(0xFFC0C0, 0, 0xFF)); + queuepoly(V*Mirror, cgi.shBatFang, darkena(0xFFC0C0, 0, 0xFF)); + queuepoly(V, cgi.shBatEye, darkena(00000000, 0, 0xFF)); + queuepoly(V*Mirror, cgi.shBatEye, darkena(00000000, 0, 0xFF)); */ return false; } case moGargoyle: { - ShadowV(V, shGargoyleWings); - queuepoly(VBIRD, DIM == 2 ? shGargoyleWings : shAnimatedGargoyle[wingphase(300)], darkena(col, 0, 0xD0)); - queuepoly(VBIRD, DIM == 2 ? shGargoyleBody : shAnimatedGargoyle2[wingphase(300)], darkena(col, 0, 0xFF)); + ShadowV(V, cgi.shGargoyleWings); + queuepoly(VBIRD, DIM == 2 ? cgi.shGargoyleWings : cgi.shAnimatedGargoyle[wingphase(300)], darkena(col, 0, 0xD0)); + queuepoly(VBIRD, DIM == 2 ? cgi.shGargoyleBody : cgi.shAnimatedGargoyle2[wingphase(300)], darkena(col, 0, 0xFF)); return false; } case moZombie: { int c = darkena(col, where && where->land == laHalloween ? 1 : 0, 0xFF); const transmatrix VBS = otherbodyparts(V, c, m, footphase); - ShadowV(V, shPBody); - queuepoly(VBODY * VBS, shPBody, c); + ShadowV(V, cgi.shPBody); + queuepoly(VBODY * VBS, cgi.shPBody, c); return false; } @@ -1591,389 +1589,389 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V1, color_t col case moVariantWarrior: { const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 0, 0xC0), m, footphase); - ShadowV(V, shPBody); - queuepoly(VBS, shPBody, darkena(0xFFD500, 0, 0xF0)); - if(!peace::on) queuepoly(VBS, shPSword, 0xFFFF00FF); - queuepoly(VHEAD, shHood, 0x008000FF); + ShadowV(V, cgi.shPBody); + queuepoly(VBS, cgi.shPBody, darkena(0xFFD500, 0, 0xF0)); + if(!peace::on) queuepoly(VBS, cgi.shPSword, 0xFFFF00FF); + queuepoly(VHEAD, cgi.shHood, 0x008000FF); humanoid_eyes(V, 0xFFFF00FF); return false; } case moDesertman: { const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 0, 0xC0), m, footphase); - ShadowV(V, shPBody); - queuepoly(VBS, shPBody, darkena(col, 0, 0xC0)); - if(!peace::on) queuepoly(VBS, shPSword, 0xFFFF00FF); - queuepoly(VHEAD, shHood, 0xD0D000C0 | UNTRANS); + ShadowV(V, cgi.shPBody); + queuepoly(VBS, cgi.shPBody, darkena(col, 0, 0xC0)); + if(!peace::on) queuepoly(VBS, cgi.shPSword, 0xFFFF00FF); + queuepoly(VHEAD, cgi.shHood, 0xD0D000C0 | UNTRANS); humanoid_eyes(V, 0x301800FF); return false; } case moMonk: { const transmatrix VBS = otherbodyparts(V, darkena(col, 0, 0xC0), m, footphase); - ShadowV(V, shRaiderBody); - queuepoly(VBODY * VBS, shRaiderBody, darkena(col, 0, 0xFF)); - queuepoly(VBODY1 * VBS, shRaiderShirt, darkena(col, 2, 0xFF)); - if(!peace::on) queuepoly(VBODY * VBS, shPKnife, 0xFFC0C0C0); - queuepoly(VBODY2 * VBS, shRaiderArmor, darkena(col, 1, 0xFF)); - queuepolyat(VBODY3 * VBS, shRatCape2, darkena(col, 2, 0xFF), PPR::MONSTER_ARMOR0); - queuepoly(VHEAD1, shRaiderHelmet, darkena(col, 0, 0XFF)); - queuepoly(VHEAD, shPFace, darkena(0xC0C0A0, 0, 0XFF)); + ShadowV(V, cgi.shRaiderBody); + queuepoly(VBODY * VBS, cgi.shRaiderBody, darkena(col, 0, 0xFF)); + queuepoly(VBODY1 * VBS, cgi.shRaiderShirt, darkena(col, 2, 0xFF)); + if(!peace::on) queuepoly(VBODY * VBS, cgi.shPKnife, 0xFFC0C0C0); + queuepoly(VBODY2 * VBS, cgi.shRaiderArmor, darkena(col, 1, 0xFF)); + queuepolyat(VBODY3 * VBS, cgi.shRatCape2, darkena(col, 2, 0xFF), PPR::MONSTER_ARMOR0); + queuepoly(VHEAD1, cgi.shRaiderHelmet, darkena(col, 0, 0XFF)); + queuepoly(VHEAD, cgi.shPFace, darkena(0xC0C0A0, 0, 0XFF)); humanoid_eyes(V, 0x000000FF); return false; } case moCrusher: { const transmatrix VBS = otherbodyparts(V, darkena(col, 1, 0xFF), m, footphase); - ShadowV(V, shRaiderBody); - queuepoly(VBODY * VBS, shRaiderBody, darkena(col, 0, 0xFF)); - queuepoly(VBODY1 * VBS, shRaiderShirt, darkena(col, 2, 0xFF)); - queuepoly(VBODY2 * VBS, shRaiderArmor, darkena(col, 1, 0xFF)); - queuepoly(VBODY * VBS, shFlailTrunk, darkena(col, 1, 0XFF)); - queuepoly(VBODY1 * VBS, shHammerHead, darkena(col, 0, 0XFF)); - queuepoly(VHEAD1, shRaiderHelmet, darkena(col, 0, 0XFF)); - queuepoly(VHEAD, shPFace, darkena(0xC0C0A0, 0, 0XFF)); + ShadowV(V, cgi.shRaiderBody); + queuepoly(VBODY * VBS, cgi.shRaiderBody, darkena(col, 0, 0xFF)); + queuepoly(VBODY1 * VBS, cgi.shRaiderShirt, darkena(col, 2, 0xFF)); + queuepoly(VBODY2 * VBS, cgi.shRaiderArmor, darkena(col, 1, 0xFF)); + queuepoly(VBODY * VBS, cgi.shFlailTrunk, darkena(col, 1, 0XFF)); + queuepoly(VBODY1 * VBS, cgi.shHammerHead, darkena(col, 0, 0XFF)); + queuepoly(VHEAD1, cgi.shRaiderHelmet, darkena(col, 0, 0XFF)); + queuepoly(VHEAD, cgi.shPFace, darkena(0xC0C0A0, 0, 0XFF)); humanoid_eyes(V, 0x000000FF); return false; } case moPair: { const transmatrix VBS = otherbodyparts(V, darkena(col, 1, 0xFF), m, footphase); - ShadowV(V, shRaiderBody); - queuepoly(VBODY * VBS, shRaiderBody, darkena(col, 0, 0xFF)); - queuepoly(VBODY1 * VBS, shRaiderShirt, darkena(col, 2, 0xFF)); - queuepoly(VBODY2 * VBS, shRaiderArmor, darkena(col, 1, 0xFF)); - queuepoly(VBODY * VBS, shPickAxe, darkena(0xA0A0A0, 0, 0XFF)); - queuepoly(VHEAD1, shRaiderHelmet, darkena(col, 0, 0XFF)); - queuepoly(VHEAD, shPFace, darkena(0xC0C0A0, 0, 0XFF)); + ShadowV(V, cgi.shRaiderBody); + queuepoly(VBODY * VBS, cgi.shRaiderBody, darkena(col, 0, 0xFF)); + queuepoly(VBODY1 * VBS, cgi.shRaiderShirt, darkena(col, 2, 0xFF)); + queuepoly(VBODY2 * VBS, cgi.shRaiderArmor, darkena(col, 1, 0xFF)); + queuepoly(VBODY * VBS, cgi.shPickAxe, darkena(0xA0A0A0, 0, 0XFF)); + queuepoly(VHEAD1, cgi.shRaiderHelmet, darkena(col, 0, 0XFF)); + queuepoly(VHEAD, cgi.shPFace, darkena(0xC0C0A0, 0, 0XFF)); humanoid_eyes(V, 0x000000FF); return false; } case moAltDemon: case moHexDemon: { const transmatrix VBS = otherbodyparts(V, darkena(col, 0, 0xC0), m, footphase); - ShadowV(V, shRaiderBody); - queuepoly(VBODY * VBS, shRaiderBody, darkena(col, 0, 0xFF)); - queuepoly(VBODY1 * VBS, shRaiderShirt, darkena(col, 2, 0xFF)); - queuepoly(VBODY2 * VBS, shRaiderArmor, darkena(col, 1, 0xFF)); - if(!peace::on) queuepoly(VBODY * VBS, shPSword, 0xFFD0D0D0); - queuepoly(VHEAD1, shRaiderHelmet, darkena(col, 0, 0XFF)); - queuepoly(VHEAD, shPFace, darkena(0xC0C0A0, 0, 0XFF)); + ShadowV(V, cgi.shRaiderBody); + queuepoly(VBODY * VBS, cgi.shRaiderBody, darkena(col, 0, 0xFF)); + queuepoly(VBODY1 * VBS, cgi.shRaiderShirt, darkena(col, 2, 0xFF)); + queuepoly(VBODY2 * VBS, cgi.shRaiderArmor, darkena(col, 1, 0xFF)); + if(!peace::on) queuepoly(VBODY * VBS, cgi.shPSword, 0xFFD0D0D0); + queuepoly(VHEAD1, cgi.shRaiderHelmet, darkena(col, 0, 0XFF)); + queuepoly(VHEAD, cgi.shPFace, darkena(0xC0C0A0, 0, 0XFF)); humanoid_eyes(V, 0x000000FF); return false; } case moSkeleton: { const transmatrix VBS = VBODY * otherbodyparts(V, darkena(0xFFFFFF, 0, 0xFF), moSkeleton, footphase); - queuepoly(VBS, shSkeletonBody, darkena(0xFFFFFF, 0, 0xFF)); - if(DIM == 2) queuepoly(VHEAD, shSkull, darkena(0xFFFFFF, 0, 0xFF)); - if(DIM == 2) queuepoly(VHEAD1, shSkullEyes, 0x000000FF); + queuepoly(VBS, cgi.shSkeletonBody, darkena(0xFFFFFF, 0, 0xFF)); + if(DIM == 2) queuepoly(VHEAD, cgi.shSkull, darkena(0xFFFFFF, 0, 0xFF)); + if(DIM == 2) queuepoly(VHEAD1, cgi.shSkullEyes, 0x000000FF); humanoid_eyes(V, 0x000000FF, 0xFFFFFFFF); - ShadowV(V, shSkeletonBody); - queuepoly(VBS, shSabre, 0xFFFFFFFF); + ShadowV(V, cgi.shSkeletonBody); + queuepoly(VBS, cgi.shSabre, 0xFFFFFFFF); return false; } case moPalace: case moFatGuard: case moVizier: { - ShadowV(V, shPBody); + ShadowV(V, cgi.shPBody); const transmatrix VBS = otherbodyparts(V, darkena(0xFFD500, 0, 0xFF), m, footphase); if(m == moFatGuard) { - queuepoly(VBODY * VBS, shFatBody, darkena(0xC06000, 0, 0xFF)); + queuepoly(VBODY * VBS, cgi.shFatBody, darkena(0xC06000, 0, 0xFF)); col = 0xFFFFFF; if(!where || where->hitpoints >= 3) - queuepoly(VBODY1 * VBS, shKnightCloak, darkena(0xFFC0C0, 1, 0xFF)); + queuepoly(VBODY1 * VBS, cgi.shKnightCloak, darkena(0xFFC0C0, 1, 0xFF)); } else { - queuepoly(VBODY * VBS, shPBody, darkena(0xFFD500, 0, 0xFF)); - queuepoly(VBODY1 * VBS, shKnightArmor, m == moVizier ? 0xC000C0FF : + queuepoly(VBODY * VBS, cgi.shPBody, darkena(0xFFD500, 0, 0xFF)); + queuepoly(VBODY1 * VBS, cgi.shKnightArmor, m == moVizier ? 0xC000C0FF : darkena(0x00C000, 1, 0xFF)); if(where && where->hitpoints >= 3) - queuepoly(VBODY2 * VBS, shKnightCloak, m == moVizier ? 0x800080Ff : + queuepoly(VBODY2 * VBS, cgi.shKnightCloak, m == moVizier ? 0x800080Ff : darkena(0x00FF00, 1, 0xFF)); } - queuepoly(VHEAD1, shTurban1, darkena(col, 1, 0xFF)); + queuepoly(VHEAD1, cgi.shTurban1, darkena(col, 1, 0xFF)); if(!where || where->hitpoints >= 2) - queuepoly(VHEAD2, shTurban2, darkena(col, 0, 0xFF)); - queuepoly(VBODY * VBS, shSabre, 0xFFFFFFFF); + queuepoly(VHEAD2, cgi.shTurban2, darkena(col, 0, 0xFF)); + queuepoly(VBODY * VBS, cgi.shSabre, 0xFFFFFFFF); humanoid_eyes(V, 0x301800FF); return false; } case moCrystalSage: { const transmatrix VBS = VBODY * otherbodyparts(V, 0xFFFFFFFF, m, footphase); - ShadowV(V, shPBody); - queuepoly(VBS, shPBody, 0xFFFFFFFF); - queuepoly(VHEAD1, shPHead, 0xFFFFFFFF); - queuepoly(VHEAD, shPFace, 0xFFFFFFFF); + ShadowV(V, cgi.shPBody); + queuepoly(VBS, cgi.shPBody, 0xFFFFFFFF); + queuepoly(VHEAD1, cgi.shPHead, 0xFFFFFFFF); + queuepoly(VHEAD, cgi.shPFace, 0xFFFFFFFF); humanoid_eyes(V, 0xFFFFFFFF, 0xC0C0C0FF); return false; } case moHedge: { - ShadowV(V, shPBody); + ShadowV(V, cgi.shPBody); const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 1, 0xFF), m, footphase); - queuepoly(VBS, shPBody, darkena(col, 0, 0xFF)); - queuepoly(VBS, shHedgehogBlade, 0xC0C0C0FF); - queuepoly(VHEAD1, shPHead, 0x804000FF); - queuepoly(VHEAD, shPFace, 0xF09000FF); + queuepoly(VBS, cgi.shPBody, darkena(col, 0, 0xFF)); + queuepoly(VBS, cgi.shHedgehogBlade, 0xC0C0C0FF); + queuepoly(VHEAD1, cgi.shPHead, 0x804000FF); + queuepoly(VHEAD, cgi.shPFace, 0xF09000FF); humanoid_eyes(V, 0x00D000FF); return false; } case moYeti: case moMonkey: { const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 0, 0xC0), m, footphase); - ShadowV(V, shPBody); - queuepoly(VBS, shYeti, darkena(col, 0, 0xC0)); - queuepoly(VHEAD1, shPHead, darkena(col, 0, 0xFF)); + ShadowV(V, cgi.shPBody); + queuepoly(VBS, cgi.shYeti, darkena(col, 0, 0xC0)); + queuepoly(VHEAD1, cgi.shPHead, darkena(col, 0, 0xFF)); humanoid_eyes(V, 0x000000FF, darkena(col, 0, 0xFF)); return false; } case moResearcher: { const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 0, 0xFF), m, footphase); - ShadowV(V, shPBody); - queuepoly(VBS, shPBody, darkena(0xFFFF00, 0, 0xC0)); - queuepoly(VHEAD, shAztecHead, darkena(col, 0, 0xFF)); - queuepoly(VHEAD1, shAztecCap, darkena(0xC000C0, 0, 0xFF)); + ShadowV(V, cgi.shPBody); + queuepoly(VBS, cgi.shPBody, darkena(0xFFFF00, 0, 0xC0)); + queuepoly(VHEAD, cgi.shAztecHead, darkena(col, 0, 0xFF)); + queuepoly(VHEAD1, cgi.shAztecCap, darkena(0xC000C0, 0, 0xFF)); humanoid_eyes(V, 0x000000FF); return false; } case moFamiliar: { - ShadowV(V, shWolfBody); - queuepoly(VABODY, shWolfBody, darkena(0xA03000, 0, 0xFF)); + ShadowV(V, cgi.shWolfBody); + queuepoly(VABODY, cgi.shWolfBody, darkena(0xA03000, 0, 0xFF)); if(mmspatial || footphase) animallegs(VALEGS, moWolf, darkena(0xC04000, 0, 0xFF), footphase); else - queuepoly(VALEGS, shWolfLegs, darkena(0xC04000, 0, 0xFF)); + queuepoly(VALEGS, cgi.shWolfLegs, darkena(0xC04000, 0, 0xFF)); - queuepoly(VAHEAD, shFamiliarHead, darkena(0xC04000, 0, 0xFF)); - // queuepoly(V, shCatLegs, darkena(0x902000, 0, 0xFF)); + queuepoly(VAHEAD, cgi.shFamiliarHead, darkena(0xC04000, 0, 0xFF)); + // queuepoly(V, cgi.shCatLegs, darkena(0x902000, 0, 0xFF)); if(true) { - queuepoly(VAHEAD, shFamiliarEye, darkena(0xFFFF000, 0, 0xFF)); - queuepoly(VAHEAD * Mirror, shFamiliarEye, darkena(0xFFFF000, 0, 0xFF)); + queuepoly(VAHEAD, cgi.shFamiliarEye, darkena(0xFFFF000, 0, 0xFF)); + queuepoly(VAHEAD * Mirror, cgi.shFamiliarEye, darkena(0xFFFF000, 0, 0xFF)); } return false; } case moRanger: { - ShadowV(V, shPBody); + ShadowV(V, cgi.shPBody); const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 0, 0xFF), m, footphase); - queuepoly(VBS, shPBody, darkena(col, 0, 0xC0)); - if(!peace::on) queuepoly(VBS, shPSword, darkena(col, 0, 0xFF)); - queuepoly(VHEAD, shArmor, darkena(col, 1, 0xFF)); + queuepoly(VBS, cgi.shPBody, darkena(col, 0, 0xC0)); + if(!peace::on) queuepoly(VBS, cgi.shPSword, darkena(col, 0, 0xFF)); + queuepoly(VHEAD, cgi.shArmor, darkena(col, 1, 0xFF)); humanoid_eyes(V, 0x000000FF); return false; } case moNarciss: { - ShadowV(V, shPBody); + ShadowV(V, cgi.shPBody); const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 0, 0xFF), m, footphase); - queuepoly(VBS, shFlowerHand, darkena(col, 0, 0xFF)); - queuepoly(VBS, shPBody, 0xFFE080FF); - if(!peace::on) queuepoly(VBS, shPKnife, 0xC0C0C0FF); - queuepoly(VHEAD, shPFace, 0xFFE080FF); - queuepoly(VHEAD1, shPHead, 0x806A00FF); + queuepoly(VBS, cgi.shFlowerHand, darkena(col, 0, 0xFF)); + queuepoly(VBS, cgi.shPBody, 0xFFE080FF); + if(!peace::on) queuepoly(VBS, cgi.shPKnife, 0xC0C0C0FF); + queuepoly(VHEAD, cgi.shPFace, 0xFFE080FF); + queuepoly(VHEAD1, cgi.shPHead, 0x806A00FF); humanoid_eyes(V, 0x000000FF); return false; } case moMirrorSpirit: { - ShadowV(V, shPBody); + ShadowV(V, cgi.shPBody); const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 0, 0x90), m, footphase); - queuepoly(VBS, shPBody, darkena(col, 0, 0x90)); - if(!peace::on) queuepoly(VBS * Mirror, shPSword, darkena(col, 0, 0xD0)); - queuepoly(VHEAD1, shPHead, darkena(col, 1, 0x90)); - queuepoly(VHEAD2, shPFace, darkena(col, 1, 0x90)); - queuepoly(VHEAD, shArmor, darkena(col, 0, 0xC0)); + queuepoly(VBS, cgi.shPBody, darkena(col, 0, 0x90)); + if(!peace::on) queuepoly(VBS * Mirror, cgi.shPSword, darkena(col, 0, 0xD0)); + queuepoly(VHEAD1, cgi.shPHead, darkena(col, 1, 0x90)); + queuepoly(VHEAD2, cgi.shPFace, darkena(col, 1, 0x90)); + queuepoly(VHEAD, cgi.shArmor, darkena(col, 0, 0xC0)); humanoid_eyes(V, 0xFFFFFFFF, darkena(col, 0, 0xFF)); return false; } case moJiangshi: { - ShadowV(V, shJiangShi); - auto z2 = geom3::lev_to_factor(abs(sin(footphase * M_PI * 2)) * geom3::human_height); + ShadowV(V, cgi.shJiangShi); + auto z2 = geom3::lev_to_factor(abs(sin(footphase * M_PI * 2)) * cgi.human_height); auto V0 = V; auto V = mmscale(V0, z2); otherbodyparts(V, darkena(col, 0, 0xFF), m, m == moJiangshi ? 0 : footphase); - queuepoly(VBODY, shJiangShi, darkena(col, 0, 0xFF)); - queuepoly(VBODY1, shJiangShiDress, darkena(0x202020, 0, 0xFF)); - queuepoly(VHEAD, shTerraHead, darkena(0x101010, 0, 0xFF)); - queuepoly(VHEAD1, shPFace, darkena(col, 0, 0xFF)); - queuepoly(VHEAD2, shJiangShiCap1, darkena(0x800000, 0, 0xFF)); - queuepoly(VHEAD3, shJiangShiCap2, darkena(0x400000, 0, 0xFF)); + queuepoly(VBODY, cgi.shJiangShi, darkena(col, 0, 0xFF)); + queuepoly(VBODY1, cgi.shJiangShiDress, darkena(0x202020, 0, 0xFF)); + queuepoly(VHEAD, cgi.shTerraHead, darkena(0x101010, 0, 0xFF)); + queuepoly(VHEAD1, cgi.shPFace, darkena(col, 0, 0xFF)); + queuepoly(VHEAD2, cgi.shJiangShiCap1, darkena(0x800000, 0, 0xFF)); + queuepoly(VHEAD3, cgi.shJiangShiCap2, darkena(0x400000, 0, 0xFF)); humanoid_eyes(V, 0x000000FF, darkena(col, 0, 0xFF)); return false; } case moGhost: case moSeep: case moFriendlyGhost: { if(m == moFriendlyGhost) col = fghostcolor(where); - queuepolyat(VGHOST, shGhost, darkena(col, 0, m == moFriendlyGhost ? 0xC0 : 0x80), DIM == 3 ? PPR::SUPERLINE : shGhost.prio); - queuepolyat(VGHOST, shGhostEyes, 0xFF, DIM == 3 ? PPR::SUPERLINE : shEyes.prio); + queuepolyat(VGHOST, cgi.shGhost, darkena(col, 0, m == moFriendlyGhost ? 0xC0 : 0x80), DIM == 3 ? PPR::SUPERLINE : cgi.shGhost.prio); + queuepolyat(VGHOST, cgi.shGhostEyes, 0xFF, DIM == 3 ? PPR::SUPERLINE : cgi.shEyes.prio); return false; } case moVineSpirit: { - queuepoly(VGHOST, shGhost, 0xD0D0D0C0 | UNTRANS); - queuepolyat(VGHOST, shGhostEyes, 0xFF0000FF, DIM == 3 ? PPR::SUPERLINE : shGhostEyes.prio); + queuepoly(VGHOST, cgi.shGhost, 0xD0D0D0C0 | UNTRANS); + queuepolyat(VGHOST, cgi.shGhostEyes, 0xFF0000FF, DIM == 3 ? PPR::SUPERLINE : cgi.shGhostEyes.prio); return false; } case moFireFairy: { col = firecolor(0); const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 0, 0xFF), m, footphase); - ShadowV(V, shFemaleBody); - queuepoly(VBS, shFemaleBody, darkena(col, 0, 0XC0)); - queuepoly(VHEAD, shWitchHair, darkena(col, 1, 0xFF)); - queuepoly(VHEAD1, shPFace, darkena(col, 0, 0XFF)); + ShadowV(V, cgi.shFemaleBody); + queuepoly(VBS, cgi.shFemaleBody, darkena(col, 0, 0XC0)); + queuepoly(VHEAD, cgi.shWitchHair, darkena(col, 1, 0xFF)); + queuepoly(VHEAD1, cgi.shPFace, darkena(col, 0, 0XFF)); humanoid_eyes(V, darkena(col, 1, 0xFF)); return false; } case moSlime: { - queuepoly(VFISH, shSlime, darkena(col, 0, 0x80)); - queuepoly(VSLIMEEYE, shSlimeEyes, 0xFF); + queuepoly(VFISH, cgi.shSlime, darkena(col, 0, 0x80)); + queuepoly(VSLIMEEYE, cgi.shSlimeEyes, 0xFF); return false; } case moKrakenH: { - queuepoly(VFISH, shKrakenHead, darkena(col, 0, 0xD0)); - queuepoly(VFISH, shKrakenEye, 0xFFFFFFC0 | UNTRANS); - queuepoly(VFISH, shKrakenEye2, 0xC0); - queuepoly(VFISH * Mirror, shKrakenEye, 0xFFFFFFC0 | UNTRANS); - queuepoly(VFISH * Mirror, shKrakenEye2, 0xC0); + queuepoly(VFISH, cgi.shKrakenHead, darkena(col, 0, 0xD0)); + queuepoly(VFISH, cgi.shKrakenEye, 0xFFFFFFC0 | UNTRANS); + queuepoly(VFISH, cgi.shKrakenEye2, 0xC0); + queuepoly(VFISH * Mirror, cgi.shKrakenEye, 0xFFFFFFC0 | UNTRANS); + queuepoly(VFISH * Mirror, cgi.shKrakenEye2, 0xC0); return false; } case moKrakenT: { - queuepoly(VFISH, shSeaTentacle, darkena(col, 0, 0xD0)); + queuepoly(VFISH, cgi.shSeaTentacle, darkena(col, 0, 0xD0)); return false; } case moCultist: case moPyroCultist: case moCultistLeader: { const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 1, 0xFF), m, footphase); - ShadowV(V, shPBody); - queuepoly(VBS, shPBody, darkena(col, 0, 0xC0)); - if(!peace::on) queuepoly(VBS, shPSword, darkena(col, 2, 0xFF)); - queuepoly(VHEAD, shHood, darkena(col, 1, 0xFF)); + ShadowV(V, cgi.shPBody); + queuepoly(VBS, cgi.shPBody, darkena(col, 0, 0xC0)); + if(!peace::on) queuepoly(VBS, cgi.shPSword, darkena(col, 2, 0xFF)); + queuepoly(VHEAD, cgi.shHood, darkena(col, 1, 0xFF)); humanoid_eyes(V, 0x00FF00FF); return false; } case moPirate: { const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 0, 0xFF), m, footphase); - ShadowV(V, shPBody); - queuepoly(VBS, shPBody, darkena(0x404040, 0, 0xFF)); - queuepoly(VBS, shPirateHook, darkena(0xD0D0D0, 0, 0xFF)); - queuepoly(VHEAD, shPFace, darkena(0xFFFF80, 0, 0xFF)); - queuepoly(VHEAD1, shEyepatch, darkena(0, 0, 0xC0)); - queuepoly(VHEAD2, shPirateHood, darkena(col, 0, 0xFF)); + ShadowV(V, cgi.shPBody); + queuepoly(VBS, cgi.shPBody, darkena(0x404040, 0, 0xFF)); + queuepoly(VBS, cgi.shPirateHook, darkena(0xD0D0D0, 0, 0xFF)); + queuepoly(VHEAD, cgi.shPFace, darkena(0xFFFF80, 0, 0xFF)); + queuepoly(VHEAD1, cgi.shEyepatch, darkena(0, 0, 0xC0)); + queuepoly(VHEAD2, cgi.shPirateHood, darkena(col, 0, 0xFF)); humanoid_eyes(V, 0x000000FF); return false; } case moRatling: case moRatlingAvenger: { const transmatrix VBS = otherbodyparts(V, darkena(col, 0, 0xFF), m, footphase); - ShadowV(V, shYeti); - queuepoly(VLEG, shRatTail, darkena(col, 0, 0xFF)); - queuepoly(VBODY * VBS, shYeti, darkena(col, 1, 0xFF)); + ShadowV(V, cgi.shYeti); + queuepoly(VLEG, cgi.shRatTail, darkena(col, 0, 0xFF)); + queuepoly(VBODY * VBS, cgi.shYeti, darkena(col, 1, 0xFF)); float t = sintick(1000, where ? where->cpdist*M_PI : 0); int eyecol = t > 0.92 ? 0xFF0000 : 0; if(DIM == 2) { - queuepoly(VHEAD, shRatHead, darkena(col, 0, 0xFF)); - queuepoly(VHEAD, shWolf1, darkena(eyecol, 0, 0xFF)); - queuepoly(VHEAD, shWolf2, darkena(eyecol, 0, 0xFF)); - queuepoly(VHEAD, shWolf3, darkena(0x202020, 0, 0xFF)); - if(m == moRatlingAvenger) queuepoly(VHEAD1, shRatCape1, 0x303030FF); + queuepoly(VHEAD, cgi.shRatHead, darkena(col, 0, 0xFF)); + queuepoly(VHEAD, cgi.shWolf1, darkena(eyecol, 0, 0xFF)); + queuepoly(VHEAD, cgi.shWolf2, darkena(eyecol, 0, 0xFF)); + queuepoly(VHEAD, cgi.shWolf3, darkena(0x202020, 0, 0xFF)); + if(m == moRatlingAvenger) queuepoly(VHEAD1, cgi.shRatCape1, 0x303030FF); } else { - transmatrix V1 = V * zpush(geom3::AHEAD - zc(0.4) - zc(0.98) + geom3::HEAD); // * cpush(0, scalefactor * (-0.1)); - queuepoly(V1, shRatHead, darkena(col, 0, 0xFF)); + transmatrix V1 = V * zpush(cgi.AHEAD - zc(0.4) - zc(0.98) + cgi.HEAD); // * cpush(0, cgi.scalefactor * (-0.1)); + queuepoly(V1, cgi.shRatHead, darkena(col, 0, 0xFF)); /* - queuepoly(V1, shFamiliarEye, darkena(eyecol, 0, 0xFF)); - queuepoly(V1 * Mirror, shFamiliarEye, darkena(eyecol, 0, 0xFF)); - queuepoly(V1, shWolfEyes, darkena(col, 3, 0xFF)); + queuepoly(V1, cgi.shFamiliarEye, darkena(eyecol, 0, 0xFF)); + queuepoly(V1 * Mirror, cgi.shFamiliarEye, darkena(eyecol, 0, 0xFF)); + queuepoly(V1, cgi.shWolfEyes, darkena(col, 3, 0xFF)); */ - queuepoly(V1, shRatEye1, darkena(eyecol, 0, 0xFF)); - queuepoly(V1, shRatEye2, darkena(eyecol, 0, 0xFF)); - queuepoly(V1, shRatEye3, darkena(0x202020, 0, 0xFF)); - if(m == moRatlingAvenger) queuepoly(V1, shRatCape1, 0x303030FF); + queuepoly(V1, cgi.shRatEye1, darkena(eyecol, 0, 0xFF)); + queuepoly(V1, cgi.shRatEye2, darkena(eyecol, 0, 0xFF)); + queuepoly(V1, cgi.shRatEye3, darkena(0x202020, 0, 0xFF)); + if(m == moRatlingAvenger) queuepoly(V1, cgi.shRatCape1, 0x303030FF); } if(m == moRatlingAvenger) { - queuepoly(VBODY1 * VBS, shRatCape2, 0x484848FF); + queuepoly(VBODY1 * VBS, cgi.shRatCape2, 0x484848FF); } return false; } case moViking: { const transmatrix VBS = otherbodyparts(V, darkena(col, 1, 0xFF), m, footphase); - ShadowV(V, shPBody); - queuepoly(VBODY * VBS, shPBody, darkena(0xE00000, 0, 0xFF)); - if(!peace::on) queuepoly(VBODY * VBS, shPSword, darkena(0xD0D0D0, 0, 0xFF)); - queuepoly(VBODY1 * VBS, shKnightCloak, darkena(0x404040, 0, 0xFF)); - queuepoly(VHEAD, shVikingHelmet, darkena(0xC0C0C0, 0, 0XFF)); - queuepoly(VHEAD, shPFace, darkena(0xFFFF80, 0, 0xFF)); + ShadowV(V, cgi.shPBody); + queuepoly(VBODY * VBS, cgi.shPBody, darkena(0xE00000, 0, 0xFF)); + if(!peace::on) queuepoly(VBODY * VBS, cgi.shPSword, darkena(0xD0D0D0, 0, 0xFF)); + queuepoly(VBODY1 * VBS, cgi.shKnightCloak, darkena(0x404040, 0, 0xFF)); + queuepoly(VHEAD, cgi.shVikingHelmet, darkena(0xC0C0C0, 0, 0XFF)); + queuepoly(VHEAD, cgi.shPFace, darkena(0xFFFF80, 0, 0xFF)); humanoid_eyes(V, 0x000000FF); return false; } case moOutlaw: { const transmatrix VBS = otherbodyparts(V, darkena(col, 1, 0xFF), m, footphase); - ShadowV(V, shPBody); - queuepoly(VBODY * VBS, shPBody, darkena(col, 0, 0xFF)); - queuepoly(VBODY1 * VBS, shKnightCloak, darkena(col, 1, 0xFF)); - queuepoly(VHEAD1, shWestHat1, darkena(col, 2, 0XFF)); - queuepoly(VHEAD2, shWestHat2, darkena(col, 1, 0XFF)); - queuepoly(VHEAD, shPFace, darkena(0xFFFF80, 0, 0xFF)); - queuepoly(VBODY * VBS, shGunInHand, darkena(col, 1, 0XFF)); + ShadowV(V, cgi.shPBody); + queuepoly(VBODY * VBS, cgi.shPBody, darkena(col, 0, 0xFF)); + queuepoly(VBODY1 * VBS, cgi.shKnightCloak, darkena(col, 1, 0xFF)); + queuepoly(VHEAD1, cgi.shWestHat1, darkena(col, 2, 0XFF)); + queuepoly(VHEAD2, cgi.shWestHat2, darkena(col, 1, 0XFF)); + queuepoly(VHEAD, cgi.shPFace, darkena(0xFFFF80, 0, 0xFF)); + queuepoly(VBODY * VBS, cgi.shGunInHand, darkena(col, 1, 0XFF)); humanoid_eyes(V, 0x000000FF); return false; } case moNecromancer: { const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 0, 0xFF), m, footphase); - ShadowV(V, shPBody); - queuepoly(VBS, shPBody, 0xC00000C0 | UNTRANS); - queuepoly(VHEAD, shHood, darkena(col, 1, 0xFF)); + ShadowV(V, cgi.shPBody); + queuepoly(VBS, cgi.shPBody, 0xC00000C0 | UNTRANS); + queuepoly(VHEAD, cgi.shHood, darkena(col, 1, 0xFF)); humanoid_eyes(V, 0xFF0000FF); return false; } case moDraugr: { const transmatrix VBS = VBODY * otherbodyparts(V, 0x483828D0 | UNTRANS, m, footphase); - queuepoly(VBS, shPBody, 0x483828D0 | UNTRANS); - queuepoly(VBS, shPSword, 0xFFFFD0A0 | UNTRANS); - queuepoly(VHEAD, shPHead, 0x483828D0 | UNTRANS); + queuepoly(VBS, cgi.shPBody, 0x483828D0 | UNTRANS); + queuepoly(VBS, cgi.shPSword, 0xFFFFD0A0 | UNTRANS); + queuepoly(VHEAD, cgi.shPHead, 0x483828D0 | UNTRANS); humanoid_eyes(V, 0xFF0000FF, 0x483828FF); - // queuepoly(V, shSkull, 0xC06020D0); - //queuepoly(V, shSkullEyes, 0x000000D0); - // queuepoly(V, shWightCloak, 0xC0A080A0); + // queuepoly(V, cgi.shSkull, 0xC06020D0); + //queuepoly(V, cgi.shSkullEyes, 0x000000D0); + // queuepoly(V, cgi.shWightCloak, 0xC0A080A0); int b = where ? where->cpdist : 0; b--; if(b < 0) b = 0; if(b > 6) b = 6; - queuepoly(VHEAD1, shWightCloak, (0x605040A0 | UNTRANS) + 0x10101000 * b); + queuepoly(VHEAD1, cgi.shWightCloak, (0x605040A0 | UNTRANS) + 0x10101000 * b); return false; } case moVoidBeast: { const transmatrix VBS = VBODY * otherbodyparts(V, 0x080808D0 | UNTRANS, m, footphase); - queuepoly(VBS, shPBody, 0x080808D0 | UNTRANS); - queuepoly(VHEAD, shPHead, 0x080808D0 | UNTRANS); - queuepoly(VHEAD, shWightCloak, 0xFF0000A0 | UNTRANS); + queuepoly(VBS, cgi.shPBody, 0x080808D0 | UNTRANS); + queuepoly(VHEAD, cgi.shPHead, 0x080808D0 | UNTRANS); + queuepoly(VHEAD, cgi.shWightCloak, 0xFF0000A0 | UNTRANS); humanoid_eyes(V, 0xFF0000FF, 0x080808FF); return false; } case moGoblin: { const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 0, 0xFF), m, footphase); - ShadowV(V, shYeti); - queuepoly(VBS, shYeti, darkena(col, 0, 0xC0)); - queuepoly(VHEAD, shArmor, darkena(col, 1, 0XFF)); + ShadowV(V, cgi.shYeti); + queuepoly(VBS, cgi.shYeti, darkena(col, 0, 0xC0)); + queuepoly(VHEAD, cgi.shArmor, darkena(col, 1, 0XFF)); humanoid_eyes(V, 0x800000FF, darkena(col, 0, 0xFF)); return false; } @@ -1982,20 +1980,20 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V1, color_t col transmatrix V2 = V; if(m == moLancer) V2 = V * spin((where && where->type == 6) ? -M_PI/3 : -M_PI/2 ); - transmatrix Vh = mmscale(V2, geom3::HEAD); - transmatrix Vb = mmscale(V2, geom3::BODY); + transmatrix Vh = mmscale(V2, cgi.HEAD); + transmatrix Vb = mmscale(V2, cgi.BODY); Vb = Vb * otherbodyparts(V2, darkena(col, 1, 0xFF), m, footphase); - ShadowV(V2, shPBody); - queuepoly(Vb, shPBody, darkena(col, 0, 0xC0)); - queuepoly(Vh, m == moFlailer ? shArmor : shHood, darkena(col, 1, 0XFF)); + ShadowV(V2, cgi.shPBody); + queuepoly(Vb, cgi.shPBody, darkena(col, 0, 0xC0)); + queuepoly(Vh, m == moFlailer ? cgi.shArmor : cgi.shHood, darkena(col, 1, 0XFF)); if(m == moMiner) - queuepoly(Vb, shPickAxe, darkena(0xC0C0C0, 0, 0XFF)); + queuepoly(Vb, cgi.shPickAxe, darkena(0xC0C0C0, 0, 0XFF)); if(m == moLancer) - queuepoly(Vb, shPike, darkena(col, 0, 0XFF)); + queuepoly(Vb, cgi.shPike, darkena(col, 0, 0XFF)); if(m == moFlailer) { - queuepoly(Vb, shFlailBall, darkena(col, 0, 0XFF)); - queuepoly(Vb, shFlailChain, darkena(col, 1, 0XFF)); - queuepoly(Vb, shFlailTrunk, darkena(col, 0, 0XFF)); + queuepoly(Vb, cgi.shFlailBall, darkena(col, 0, 0XFF)); + queuepoly(Vb, cgi.shFlailChain, darkena(col, 1, 0XFF)); + queuepoly(Vb, cgi.shFlailTrunk, darkena(col, 0, 0XFF)); } humanoid_eyes(V, 0x000000FF); return false; @@ -2003,112 +2001,112 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V1, color_t col case moTroll: { const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 0, 0xFF), m, footphase); - ShadowV(V, shYeti); - queuepoly(VBS, shYeti, darkena(col, 0, 0xC0)); - queuepoly(VHEAD1, shPHead, darkena(col, 1, 0XFF)); - queuepoly(VHEAD, shPFace, darkena(col, 2, 0XFF)); + ShadowV(V, cgi.shYeti); + queuepoly(VBS, cgi.shYeti, darkena(col, 0, 0xC0)); + queuepoly(VHEAD1, cgi.shPHead, darkena(col, 1, 0XFF)); + queuepoly(VHEAD, cgi.shPFace, darkena(col, 2, 0XFF)); humanoid_eyes(V, 0x004000FF, darkena(col, 0, 0xFF)); return false; } case moFjordTroll: case moForestTroll: case moStormTroll: { const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 0, 0xFF), m, footphase); - ShadowV(V, shYeti); - queuepoly(VBS, shYeti, darkena(col, 0, 0xC0)); - queuepoly(VHEAD1, shPHead, darkena(col, 1, 0XFF)); - queuepoly(VHEAD, shPFace, darkena(col, 2, 0XFF)); + ShadowV(V, cgi.shYeti); + queuepoly(VBS, cgi.shYeti, darkena(col, 0, 0xC0)); + queuepoly(VHEAD1, cgi.shPHead, darkena(col, 1, 0XFF)); + queuepoly(VHEAD, cgi.shPFace, darkena(col, 2, 0XFF)); humanoid_eyes(V, 0x004000FF, darkena(col, 0, 0xFF)); return false; } case moDarkTroll: { const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 0, 0xFF), m, footphase); - ShadowV(V, shYeti); - queuepoly(VBS, shYeti, darkena(col, 0, 0xC0)); - queuepoly(VHEAD1, shPHead, darkena(col, 1, 0XFF)); - queuepoly(VHEAD, shPFace, 0xFFFFFF80 | UNTRANS); + ShadowV(V, cgi.shYeti); + queuepoly(VBS, cgi.shYeti, darkena(col, 0, 0xC0)); + queuepoly(VHEAD1, cgi.shPHead, darkena(col, 1, 0XFF)); + queuepoly(VHEAD, cgi.shPFace, 0xFFFFFF80 | UNTRANS); humanoid_eyes(V, 0x000000FF, darkena(col, 0, 0xFF)); return false; } case moRedTroll: { const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 0, 0xFF), m, footphase); - ShadowV(V, shYeti); - queuepoly(VBS, shYeti, darkena(col, 0, 0xC0)); - queuepoly(VHEAD1, shPHead, darkena(0xFF8000, 0, 0XFF)); - queuepoly(VHEAD, shPFace, 0xFFFFFF80 | UNTRANS); + ShadowV(V, cgi.shYeti); + queuepoly(VBS, cgi.shYeti, darkena(col, 0, 0xC0)); + queuepoly(VHEAD1, cgi.shPHead, darkena(0xFF8000, 0, 0XFF)); + queuepoly(VHEAD, cgi.shPFace, 0xFFFFFF80 | UNTRANS); humanoid_eyes(V, 0x000000FF, darkena(col, 0, 0xFF)); return false; } case moEarthElemental: { const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 1, 0xFF), m, footphase); - ShadowV(V, shWaterElemental); - queuepoly(VBS, shWaterElemental, darkena(col, 0, 0xC0)); - queuepoly(VHEAD1, shFemaleHair, darkena(col, 0, 0XFF)); - queuepoly(VHEAD, shPFace, 0xF0000080 | UNTRANS); + ShadowV(V, cgi.shWaterElemental); + queuepoly(VBS, cgi.shWaterElemental, darkena(col, 0, 0xC0)); + queuepoly(VHEAD1, cgi.shFemaleHair, darkena(col, 0, 0XFF)); + queuepoly(VHEAD, cgi.shPFace, 0xF0000080 | UNTRANS); humanoid_eyes(V, 0xD0D000FF, darkena(col, 1, 0xFF)); return false; } case moWaterElemental: { const transmatrix VBS = VBODY * otherbodyparts(V, watercolor(50), m, footphase); - ShadowV(V, shWaterElemental); - queuepoly(VBS, shWaterElemental, watercolor(0)); - queuepoly(VHEAD1, shFemaleHair, watercolor(100)); - queuepoly(VHEAD, shPFace, watercolor(200)); + ShadowV(V, cgi.shWaterElemental); + queuepoly(VBS, cgi.shWaterElemental, watercolor(0)); + queuepoly(VHEAD1, cgi.shFemaleHair, watercolor(100)); + queuepoly(VHEAD, cgi.shPFace, watercolor(200)); humanoid_eyes(V, 0x0000FFFF, watercolor(150)); return false; } case moFireElemental: { const transmatrix VBS = VBODY * otherbodyparts(V, darkena(firecolor(50), 0, 0xFF), m, footphase); - ShadowV(V, shWaterElemental); - queuepoly(VBS, shWaterElemental, darkena(firecolor(0), 0, 0xFF)); - queuepoly(VHEAD1, shFemaleHair, darkena(firecolor(100), 0, 0xFF)); - queuepoly(VHEAD, shPFace, darkena(firecolor(200), 0, 0xFF)); + ShadowV(V, cgi.shWaterElemental); + queuepoly(VBS, cgi.shWaterElemental, darkena(firecolor(0), 0, 0xFF)); + queuepoly(VHEAD1, cgi.shFemaleHair, darkena(firecolor(100), 0, 0xFF)); + queuepoly(VHEAD, cgi.shPFace, darkena(firecolor(200), 0, 0xFF)); humanoid_eyes(V, darkena(firecolor(200), 0, 0xFF), darkena(firecolor(50), 0, 0xFF)); return false; } case moAirElemental: { const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 0, 0x40), m, footphase); - ShadowV(V, shWaterElemental); - queuepoly(VBS, shWaterElemental, darkena(col, 0, 0x80)); - queuepoly(VHEAD1, shFemaleHair, darkena(col, 0, 0x80)); - queuepoly(VHEAD, shPFace, darkena(col, 0, 0x80)); + ShadowV(V, cgi.shWaterElemental); + queuepoly(VBS, cgi.shWaterElemental, darkena(col, 0, 0x80)); + queuepoly(VHEAD1, cgi.shFemaleHair, darkena(col, 0, 0x80)); + queuepoly(VHEAD, cgi.shPFace, darkena(col, 0, 0x80)); humanoid_eyes(V, 0xFFFFFFFF, darkena(col, 1, 0xFF)); return false; } case moWorm: case moWormwait: case moHexSnake: { - queuepoly(V, shWormHead, darkena(col, 0, 0xFF)); - queuepolyat(V, shWormEyes, 0xFF, PPR::ONTENTACLE_EYES); + queuepoly(V, cgi.shWormHead, darkena(col, 0, 0xFF)); + queuepolyat(V, cgi.shWormEyes, 0xFF, PPR::ONTENTACLE_EYES); return false; } case moDragonHead: { - queuepoly(V, shDragonHead, darkena(col, 0, 0xFF)); - queuepolyat(V, shDragonEyes, 0xFF, PPR::ONTENTACLE_EYES); + queuepoly(V, cgi.shDragonHead, darkena(col, 0, 0xFF)); + queuepolyat(V, cgi.shDragonEyes, 0xFF, PPR::ONTENTACLE_EYES); int noscolor = 0xFF0000FF; - queuepoly(V, shDragonNostril, noscolor); - queuepoly(V * Mirror, shDragonNostril, noscolor); + queuepoly(V, cgi.shDragonNostril, noscolor); + queuepoly(V * Mirror, cgi.shDragonNostril, noscolor); return false; } case moDragonTail: { - queuepoly(V, shDragonSegment, darkena(col, 0, 0xFF)); + queuepoly(V, cgi.shDragonSegment, darkena(col, 0, 0xFF)); return false; } case moTentacle: case moTentaclewait: case moTentacleEscaping: { - queuepoly(V, shTentHead, darkena(col, 0, 0xFF)); - ShadowV(V, shTentHead, PPR::GIANTSHADOW); + queuepoly(V, cgi.shTentHead, darkena(col, 0, 0xFF)); + ShadowV(V, cgi.shTentHead, PPR::GIANTSHADOW); return false; } case moAsteroid: { - queuepoly(V, shAsteroid[1], darkena(col, 0, 0xFF)); + queuepoly(V, cgi.shAsteroid[1], darkena(col, 0, 0xFF)); return false; } @@ -2118,56 +2116,56 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V1, color_t col if(isPrincess(m)) goto princess; else if(isBull(m)) { - ShadowV(V, shBullBody); + ShadowV(V, cgi.shBullBody); int hoofcol = darkena(gradient(0, col, 0, .65, 1), 0, 0xFF); if(mmspatial || footphase) animallegs(VALEGS, moRagingBull, hoofcol, footphase); - queuepoly(VABODY, shBullBody, darkena(gradient(0, col, 0, .80, 1), 0, 0xFF)); - queuepoly(VAHEAD, shBullHead, darkena(col, 0, 0xFF)); - queuepoly(VAHEAD, shBullHorn, darkena(0xFFFFFF, 0, 0xFF)); - queuepoly(VAHEAD * Mirror, shBullHorn, darkena(0xFFFFFF, 0, 0xFF)); + queuepoly(VABODY, cgi.shBullBody, darkena(gradient(0, col, 0, .80, 1), 0, 0xFF)); + queuepoly(VAHEAD, cgi.shBullHead, darkena(col, 0, 0xFF)); + queuepoly(VAHEAD, cgi.shBullHorn, darkena(0xFFFFFF, 0, 0xFF)); + queuepoly(VAHEAD * Mirror, cgi.shBullHorn, darkena(0xFFFFFF, 0, 0xFF)); } else if(isBug(m)) { - ShadowV(V, shBugBody); + ShadowV(V, cgi.shBugBody); if(!mmspatial && !footphase) - queuepoly(VABODY, shBugBody, darkena(col, 0, 0xFF)); + queuepoly(VABODY, cgi.shBugBody, darkena(col, 0, 0xFF)); else { animallegs(VALEGS, moBug0, darkena(col, 0, 0xFF), footphase); - queuepoly(VABODY, shBugAntenna, darkena(col, 1, 0xFF)); + queuepoly(VABODY, cgi.shBugAntenna, darkena(col, 1, 0xFF)); } - queuepoly(VABODY, shBugArmor, darkena(col, 1, 0xFF)); + queuepoly(VABODY, cgi.shBugArmor, darkena(col, 1, 0xFF)); } else if(isSwitch(m)) { - queuepoly(VFISH, shJelly, darkena(col, 0, 0xD0)); - queuepolyat(VBODY, shJelly, darkena(col, 0, 0xD0), PPR::MONSTER_BODY); - queuepolyat(VHEAD, shJelly, darkena(col, 0, 0xD0), PPR::MONSTER_HEAD); - queuepolyat(VHEAD, shSlimeEyes, 0xFF, PPR::MONSTER_HEAD); + queuepoly(VFISH, cgi.shJelly, darkena(col, 0, 0xD0)); + queuepolyat(VBODY, cgi.shJelly, darkena(col, 0, 0xD0), PPR::MONSTER_BODY); + queuepolyat(VHEAD, cgi.shJelly, darkena(col, 0, 0xD0), PPR::MONSTER_HEAD); + queuepolyat(VHEAD, cgi.shSlimeEyes, 0xFF, PPR::MONSTER_HEAD); } else if(isDemon(m)) { const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 0, 0xC0), m, footphase); - queuepoly(VBS, shPBody, darkena(col, 1, 0xC0)); - ShadowV(V, shPBody); + queuepoly(VBS, cgi.shPBody, darkena(col, 1, 0xC0)); + ShadowV(V, cgi.shPBody); int acol = col; if(xch == 'D') acol = 0xD0D0D0; - queuepoly(VHEAD, shDemon, darkena(acol, 0, 0xFF)); + queuepoly(VHEAD, cgi.shDemon, darkena(acol, 0, 0xFF)); humanoid_eyes(V, 0xFF0000FF, 0xC00000FF); } else if(isMagneticPole(m)) { if(m == moNorthPole) - queuepolyat(VBODY * spin(M_PI), shTentacle, 0x000000C0, PPR::TENTACLE1); - queuepolyat(VBODY, shDisk, darkena(col, 0, 0xFF), PPR::MONSTER_BODY); + queuepolyat(VBODY * spin(M_PI), cgi.shTentacle, 0x000000C0, PPR::TENTACLE1); + queuepolyat(VBODY, cgi.shDisk, darkena(col, 0, 0xFF), PPR::MONSTER_BODY); } else if(isMetalBeast(m) || m == moBrownBug) { - ShadowV(V, shTrylobite); + ShadowV(V, cgi.shTrylobite); if(!mmspatial) - queuepoly(VABODY, shTrylobite, darkena(col, 1, 0xC0)); + queuepoly(VABODY, cgi.shTrylobite, darkena(col, 1, 0xC0)); else { - queuepoly(VABODY, shTrylobiteBody, darkena(col, 1, 0xFF)); + queuepoly(VABODY, cgi.shTrylobiteBody, darkena(col, 1, 0xFF)); animallegs(VALEGS, moMetalBeast, darkena(col, 1, 0xFF), footphase); } int acol = col; - queuepoly(VAHEAD, shTrylobiteHead, darkena(acol, 0, 0xFF)); + queuepoly(VAHEAD, cgi.shTrylobiteHead, darkena(acol, 0, 0xFF)); } else if(isWitch(m)) { const transmatrix VBS = VBODY * otherbodyparts(V, darkena(col, 1, 0xFF), m, footphase); @@ -2177,22 +2175,22 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V1, color_t col if(m == moWitchFlash && where) drawFlash(V); if(m == moWitchSpeed && where) drawSpeed(V); if(m == moWitchFire) col = firecolor(0); - ShadowV(V, shFemaleBody); - queuepoly(VBS, shFemaleBody, darkena(col, 0, cc)); -// queuepoly(cV2, ct, shPSword, darkena(col, 0, 0XFF)); -// queuepoly(V, shHood, darkena(col, 0, 0XC0)); + ShadowV(V, cgi.shFemaleBody); + queuepoly(VBS, cgi.shFemaleBody, darkena(col, 0, cc)); +// queuepoly(cV2, ct, cgi.shPSword, darkena(col, 0, 0XFF)); +// queuepoly(V, cgi.shHood, darkena(col, 0, 0XC0)); if(m == moWitchFire) col = firecolor(100); - queuepoly(VHEAD1, shWitchHair, darkena(col, 1, cc)); + queuepoly(VHEAD1, cgi.shWitchHair, darkena(col, 1, cc)); if(m == moWitchFire) col = firecolor(200); - queuepoly(VHEAD, shPFace, darkena(col, 0, cc)); + queuepoly(VHEAD, cgi.shPFace, darkena(col, 0, cc)); if(m == moWitchFire) col = firecolor(300); - queuepoly(VBS, shWitchDress, darkena(col, 1, 0XC0)); + queuepoly(VBS, cgi.shWitchDress, darkena(col, 1, 0XC0)); humanoid_eyes(V, 0x000000FF); } // just for the HUD glyphs... else if(isAnyIvy(m)) { - queuepoly(V, shILeaf[0], darkena(col, 0, 0xFF)); + queuepoly(V, cgi.shILeaf[0], darkena(col, 0, 0xFF)); } else return true; @@ -2397,11 +2395,11 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m return false; if(isIvy(c) || isMutantIvy(c) || c->monst == moFriendlyIvy) - queuepoly(Vb, shIBranch, (col << 8) + 0xFF); + queuepoly(Vb, cgi.shIBranch, (col << 8) + 0xFF); /* else if(c->monst < moTentacle && wormstyle == 0) { - ShadowV(Vb, shTentacleX, PPR::GIANTSHADOW); - queuepoly(mmscale(Vb, geom3::ABODY), shTentacleX, 0xFF); - queuepoly(mmscale(Vb, geom3::ABODY), shTentacle, (col << 8) + 0xFF); + ShadowV(Vb, cgi.shTentacleX, PPR::GIANTSHADOW); + queuepoly(mmscale(Vb, cgi.ABODY), cgi.shTentacleX, 0xFF); + queuepoly(mmscale(Vb, cgi.ABODY), cgi.shTentacle, (col << 8) + 0xFF); } */ // else if(c->monst < moTentacle) { // } @@ -2409,8 +2407,8 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m else if(c->monst == moDragonHead || c->monst == moDragonTail) { char part = dragon::bodypart(c, dragon::findhead(c)); if(part != '2') { - queuepoly(mmscale(Vb, geom3::ABODY), shDragonSegment, darkena(col, 0, 0xFF)); - ShadowV(Vb, shDragonSegment, PPR::GIANTSHADOW); + queuepoly(mmscale(Vb, cgi.ABODY), cgi.shDragonSegment, darkena(col, 0, 0xFF)); + ShadowV(Vb, cgi.shDragonSegment, PPR::GIANTSHADOW); } } else { @@ -2422,13 +2420,13 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m col = minf[moTentacletail].color; } /* - queuepoly(mmscale(Vb, geom3::ABODY), shTentacleX, 0xFFFFFFFF); - queuepoly(mmscale(Vb, geom3::ABODY), shTentacle, (col << 8) + 0xFF); - ShadowV(Vb, shTentacleX, PPR::GIANTSHADOW); + queuepoly(mmscale(Vb, cgi.ABODY), cgi.shTentacleX, 0xFFFFFFFF); + queuepoly(mmscale(Vb, cgi.ABODY), cgi.shTentacle, (col << 8) + 0xFF); + ShadowV(Vb, cgi.shTentacleX, PPR::GIANTSHADOW); */ bool hexsnake = c->monst == moHexSnake || c->monst == moHexSnakeTail; bool thead = c->monst == moTentacle || c->monst == moTentaclewait || c->monst == moTentacleEscaping; - hpcshape& sh = hexsnake ? shWormSegment : shSmallWormSegment; + hpcshape& sh = hexsnake ? cgi.shWormSegment : cgi.shSmallWormSegment; ld wav = hexsnake ? 0 : c->monst < moTentacle ? 1/1.5 : 1; @@ -2446,7 +2444,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m // transmatrix Vbx2 = Vnext * xpush(length2 * i / 6.0); // Vbx = Vbx * rspintox(inverse(Vbx) * Vbx2 * C0) * pispin; ShadowV(Vbx, sh, PPR::GIANTSHADOW); - queuepoly(mmscale(Vbx, geom3::ABODY), sh, (col0 << 8) + 0xFF); + queuepoly(mmscale(Vbx, cgi.ABODY), sh, (col0 << 8) + 0xFF); } }); } @@ -2456,7 +2454,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m int hdir = displayspin(c, c->mondir); color_t col = darkena(0x606020, 0, 0xFF); for(int u=-1; u<=1; u++) - queueline(Vparam*xspinpush0(hdir+M_PI/2, u*crossf/5), Vparam*xspinpush(hdir, crossf)*xspinpush0(hdir+M_PI/2, u*crossf/5), col, 2 + vid.linequality); + queueline(Vparam*xspinpush0(hdir+M_PI/2, u*cgi.crossf/5), Vparam*xspinpush(hdir, cgi.crossf)*xspinpush0(hdir+M_PI/2, u*cgi.crossf/5), col, 2 + vid.linequality); } } @@ -2465,39 +2463,39 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m if(DIM == 3) { hyperpoint V0 = tC0(Vb); transmatrix Vs = rspintox(V0) * xpush(hdist0(V0)) * cspin(0, 2, -M_PI/2); - queuepoly(Vs, shILeaf[1], darkena(col, 0, 0xFF)); + queuepoly(Vs, cgi.shILeaf[1], darkena(col, 0, 0xFF)); } else { if(c->monmirror) Vb = Vb * Mirror; - queuepoly(mmscale(Vb, geom3::ABODY), shILeaf[ctof(c)], darkena(col, 0, 0xFF)); - ShadowV(Vb, shILeaf[ctof(c)], PPR::GIANTSHADOW); + queuepoly(mmscale(Vb, cgi.ABODY), cgi.shILeaf[ctof(c)], darkena(col, 0, 0xFF)); + ShadowV(Vb, cgi.shILeaf[ctof(c)], PPR::GIANTSHADOW); } } else if(m == moWorm || m == moWormwait || m == moHexSnake) { Vb = Vb * pispin; if(c->monmirror) Vb = Vb * Mirror; - transmatrix Vbh = mmscale(Vb, geom3::AHEAD); - queuepoly(Vbh, shWormHead, darkena(col, 0, 0xFF)); - queuepolyat(Vbh, shWormEyes, 0xFF, PPR::ONTENTACLE_EYES); - ShadowV(Vb, shWormHead, PPR::GIANTSHADOW); + transmatrix Vbh = mmscale(Vb, cgi.AHEAD); + queuepoly(Vbh, cgi.shWormHead, darkena(col, 0, 0xFF)); + queuepolyat(Vbh, cgi.shWormEyes, 0xFF, PPR::ONTENTACLE_EYES); + ShadowV(Vb, cgi.shWormHead, PPR::GIANTSHADOW); } else if(m == moDragonHead) { if(c->monmirror) Vb = Vb * Mirror; - transmatrix Vbh = mmscale(Vb, geom3::AHEAD); - ShadowV(Vb, shDragonHead, PPR::GIANTSHADOW); - queuepoly(Vbh, shDragonHead, darkena(col, c->hitpoints?0:1, 0xFF)); - queuepolyat(Vbh/* * pispin */, shDragonEyes, 0xFF, PPR::ONTENTACLE_EYES); + transmatrix Vbh = mmscale(Vb, cgi.AHEAD); + ShadowV(Vb, cgi.shDragonHead, PPR::GIANTSHADOW); + queuepoly(Vbh, cgi.shDragonHead, darkena(col, c->hitpoints?0:1, 0xFF)); + queuepolyat(Vbh/* * pispin */, cgi.shDragonEyes, 0xFF, PPR::ONTENTACLE_EYES); int noscolor = (c->hitpoints == 1 && c->stuntime ==1) ? 0xFF0000FF : 0xFF; - queuepoly(Vbh, shDragonNostril, noscolor); - queuepoly(Vbh * Mirror, shDragonNostril, noscolor); + queuepoly(Vbh, cgi.shDragonNostril, noscolor); + queuepoly(Vbh * Mirror, cgi.shDragonNostril, noscolor); } else if(m == moTentacle || m == moTentaclewait || m == moTentacleEscaping) { Vb = Vb * pispin; if(c->monmirror) Vb = Vb * Mirror; - transmatrix Vbh = mmscale(Vb, geom3::AHEAD); - queuepoly(Vbh, shTentHead, darkena(col, 0, 0xFF)); - ShadowV(Vb, shTentHead, PPR::GIANTSHADOW); + transmatrix Vbh = mmscale(Vb, cgi.AHEAD); + queuepoly(Vbh, cgi.shTentHead, darkena(col, 0, 0xFF)); + ShadowV(Vb, cgi.shTentHead, PPR::GIANTSHADOW); } else if(m == moDragonTail) { cell *c2 = NULL; @@ -2516,9 +2514,9 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m Vb = Vb0 * ddspin(c, nd, M_PI); } if(c->monmirror) Vb = Vb * Mirror; - transmatrix Vbb = mmscale(Vb, geom3::ABODY); - queuepoly(Vbb, shDragonTail, darkena(col, c->hitpoints?0:1, 0xFF)); - ShadowV(Vb, shDragonTail, PPR::GIANTSHADOW); + transmatrix Vbb = mmscale(Vb, cgi.ABODY); + queuepoly(Vbb, cgi.shDragonTail, darkena(col, c->hitpoints?0:1, 0xFF)); + ShadowV(Vb, cgi.shDragonTail, PPR::GIANTSHADOW); } else if(true) { if(nospinb) { @@ -2537,17 +2535,17 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m Vb = Vb0 * spin((hdir0 + hdir1)/2 + M_PI); } if(c->monmirror) Vb = Vb * Mirror; - transmatrix Vbb = mmscale(Vb, geom3::ABODY); + transmatrix Vbb = mmscale(Vb, cgi.ABODY); if(part == 'l' || part == '2') { - queuepoly(Vbb, shDragonLegs, darkena(col, c->hitpoints?0:1, 0xFF)); + queuepoly(Vbb, cgi.shDragonLegs, darkena(col, c->hitpoints?0:1, 0xFF)); } - queuepoly(Vbb, shDragonWings, darkena(col, c->hitpoints?0:1, 0xFF)); + queuepoly(Vbb, cgi.shDragonWings, darkena(col, c->hitpoints?0:1, 0xFF)); } } else { if(c->monst == moTentacletail && c->mondir == NODIR) { if(c->monmirror) Vb = Vb * Mirror; - queuepoly(Vb, shWormSegment, darkena(col, 0, 0xFF)); + queuepoly(Vb, cgi.shWormSegment, darkena(col, 0, 0xFF)); } else if(c->mondir == NODIR) { bool hexsnake = c->monst == moHexSnake || c->monst == moHexSnakeTail; @@ -2565,8 +2563,8 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m Vb = Vb0 * ddspin(c, nd, M_PI); } if(c->monmirror) Vb = Vb * Mirror; - transmatrix Vbb = mmscale(Vb, geom3::ABODY) * pispin; - hpcshape& sh = hexsnake ? shWormTail : shSmallWormTail; + transmatrix Vbb = mmscale(Vb, cgi.ABODY) * pispin; + hpcshape& sh = hexsnake ? cgi.shWormTail : cgi.shSmallWormTail; queuepoly(Vbb, sh, darkena(col, 0, 0xFF)); ShadowV(Vb, sh, PPR::GIANTSHADOW); } @@ -2648,20 +2646,20 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m ld length; chainAnimation(c, Vb, c->move(c->mondir), c->mondir, 0, Vparam, length); Vb = Vb * pispin; - Vb = Vb * xpush(tentacle_length - cellgfxdist(c, c->mondir)); + Vb = Vb * xpush(cgi.tentacle_length - cellgfxdist(c, c->mondir)); } else if(NONSTDVAR) { transmatrix T = calc_relative_matrix(c->move(c->mondir), c, c->mondir); - Vb = Vb * T * rspintox(tC0(inverse(T))) * xpush(tentacle_length); + Vb = Vb * T * rspintox(tC0(inverse(T))) * xpush(cgi.tentacle_length); } else { Vb = Vb * ddspin(c, c->mondir, M_PI); - Vb = Vb * xpush(tentacle_length - cellgfxdist(c, c->mondir)); + Vb = Vb * xpush(cgi.tentacle_length - cellgfxdist(c, c->mondir)); } if(c->monmirror) Vb = Vb * Mirror; // if(ctof(c) && !masterless) Vb = Vb * xpush(hexhexdist - hcrossf); - // return (!BITRUNCATED) ? tessf * gp::scale : (c->type == 6 && (i&1)) ? hexhexdist : crossf; + // return (!BITRUNCATED) ? tessf * gp::scale : (c->type == 6 && (i&1)) ? hexhexdist : cgi.crossf; return drawMonsterTypeDH(m, c, Vb, col, darkhistory, footphase); } @@ -2724,7 +2722,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col, bool m } else if(isWorm(m)) { - ld depth = geom3::factor_to_lev(wormhead(c) == c ? geom3::AHEAD : geom3::ABODY); + ld depth = geom3::factor_to_lev(wormhead(c) == c ? cgi.AHEAD : cgi.ABODY); footphase = 0; int q = ptds.size(); drawMonsterType(moPlayer, c, Vs, col, footphase); @@ -2995,7 +2993,7 @@ transmatrix applyDowndir(cell *c, const cellfunction& cf) { #if CAP_SHAPES void set_towerfloor(cell *c, const cellfunction& cf = coastvalEdge) { if(weirdhyperbolic || sphere) { - set_floor(shFloor); + set_floor(cgi.shFloor); return; } int j = -1; @@ -3018,16 +3016,16 @@ void set_towerfloor(cell *c, const cellfunction& cf = coastvalEdge) { } if(j >= 0) - set_floor(applyDowndir(c, cf), shTower[j]); + set_floor(applyDowndir(c, cf), cgi.shTower[j]); else if(c->wall != waLadder) - set_floor(shMFloor); + set_floor(cgi.shMFloor); } void set_zebrafloor(cell *c) { - if(masterless) { set_floor(shTower[10]); return; } + if(masterless) { set_floor(cgi.shTower[10]); return; } if(weirdhyperbolic) { - set_floor(shFloor); return; + set_floor(cgi.shFloor); return; } auto si = patterns::getpatterninfo(c, patterns::PAT_ZEBRA, patterns::SPF_SYM0123); @@ -3039,7 +3037,7 @@ void set_zebrafloor(cell *c) { else if(si.id >= 28 && si.id < 40) j = 3; else j = 0; - set_floor(applyPatterndir(c, si), shZebra[j]); + set_floor(applyPatterndir(c, si), cgi.shZebra[j]); } void set_maywarp_floor(cell *c); @@ -3069,7 +3067,7 @@ void set_reptile_floor(cell *c, const transmatrix& V, color_t col, bool nodetail transmatrix D = applyPatterndir(c, si); if(wmescher) - set_floor(D, shReptile[j][0]); + set_floor(D, cgi.shReptile[j][0]); else set_maywarp_floor(c); if(nodetails) return; @@ -3097,14 +3095,14 @@ void set_reptile_floor(cell *c, const transmatrix& V, color_t col, bool nodetail if(!chasmg) { if(wmescher) - queuepoly(V*D, shReptile[j][1], dcol); + queuepoly(V*D, cgi.shReptile[j][1], dcol); else - draw_floorshape(c, V, shMFloor, dcol); + draw_floorshape(c, V, cgi.shMFloor, dcol); } if(ecol != -1) { - queuepoly(V*D, shReptile[j][2], (ecol << 8) + 0xFF); - queuepoly(V*D, shReptile[j][3], (ecol << 8) + 0xFF); + queuepoly(V*D, cgi.shReptile[j][2], (ecol << 8) + 0xFF); + queuepoly(V*D, cgi.shReptile[j][3], (ecol << 8) + 0xFF); } } @@ -3129,18 +3127,18 @@ void set_emeraldfloor(cell *c) { else if(si.id == 36) j = 5; if(j >= 0) { - set_floor(applyPatterndir(c, si), shEmeraldFloor[j]); + set_floor(applyPatterndir(c, si), cgi.shEmeraldFloor[j]); return; } } - set_floor(shCaveFloor); + set_floor(cgi.shCaveFloor); } void viewBuggyCells(cell *c, transmatrix V) { for(int i=0; i> 1; poly_outline = OUTLINE_DEFAULT; - queuepoly(fixrot * spin(-d * M_PI/4), shArrow, col); + queuepoly(fixrot * spin(-d * M_PI/4), cgi.shArrow, col); if((c->type & 1) && (isStunnable(c->monst) || isPushable(c->wall))) { transmatrix Centered = rgpushxto0(tC0(cwtV)); int sd = md.subdir; - queuepoly(inverse(Centered) * rgpushxto0(Centered * tC0(V)) * rspintox(Centered*tC0(V)) * spin(-sd * M_PI/S7) * xpush(0.2), shArrow, col); + queuepoly(inverse(Centered) * rgpushxto0(Centered * tC0(V)) * rspintox(Centered*tC0(V)) * spin(-sd * M_PI/S7) * xpush(0.2), cgi.shArrow, col); } else if(!confusingGeometry()) break; } @@ -3810,10 +3808,10 @@ void floorShadow(cell *c, const transmatrix& V, color_t col) { return; // shadows break the depth testing dynamicval p(poly_outline, OUTLINE_TRANS); if(qfi.shape) { - queuepolyat(V * qfi.spin * shadowmulmatrix, *qfi.shape, col, PPR::WALLSHADOW); + queuepolyat(V * qfi.spin * cgi.shadowmulmatrix, *qfi.shape, col, PPR::WALLSHADOW); } else if(qfi.usershape >= 0) - mapeditor::drawUserShape(V * qfi.spin * shadowmulmatrix, mapeditor::sgFloor, qfi.usershape, col, c, PPR::WALLSHADOW); + mapeditor::drawUserShape(V * qfi.spin * cgi.shadowmulmatrix, mapeditor::sgFloor, qfi.usershape, col, c, PPR::WALLSHADOW); else draw_shapevec(c, V, qfi.fshape->shadow, col, PPR::WALLSHADOW); } @@ -3822,26 +3820,26 @@ void set_maywarp_floor(cell *c) { bool warp = isWarped(c); if(warp && !shmup::on && geosupport_football() == 2) { if(!stdhyperbolic) { - set_floor(shTriheptaFloor); + set_floor(cgi.shTriheptaFloor); return; } auto si = patterns::getpatterninfo(c, patterns::PAT_TYPES, 0); if(si.id == 0 || si.id == 1) - set_floor(shTriheptaFloor); + set_floor(cgi.shTriheptaFloor); else if(si.id >= 14) - set_floor(shFloor); + set_floor(cgi.shFloor); else - set_floor(applyPatterndir(c, si), shTriheptaSpecial[si.id]); + set_floor(applyPatterndir(c, si), cgi.shTriheptaSpecial[si.id]); } - else if(is_nice_dual(c)) set_floor(shBigTriangle); - else set_floor(shFloor); + else if(is_nice_dual(c)) set_floor(cgi.shBigTriangle); + else set_floor(cgi.shFloor); } void escherSidewall(cell *c, int sidepar, const transmatrix& V, color_t col) { if(sidepar >= SIDE_SLEV && sidepar <= SIDE_SLEV+2) { int sl = sidepar - SIDE_SLEV; for(int z=1; z<=4; z++) if(z == 1 || (z == 4 && detaillevel == 2)) - draw_qfi(c, mscale(V, zgrad0(geom3::slev * sl, geom3::slev * (sl+1), z, 4)), col, PPR::REDWALL-4+z+4*sl); + draw_qfi(c, mscale(V, zgrad0(cgi.slev * sl, cgi.slev * (sl+1), z, 4)), col, PPR::REDWALL-4+z+4*sl); } else if(sidepar == SIDE_WALL) { const int layers = 2 << detaillevel; @@ -3860,7 +3858,7 @@ void escherSidewall(cell *c, int sidepar, const transmatrix& V, color_t col) { } else if(sidepar == SIDE_BTOI) { const int layers = 1 << detaillevel; - draw_qfi(c, mscale(V, geom3::INFDEEP), col, PPR::MINUSINF); + draw_qfi(c, mscale(V, cgi.INFDEEP), col, PPR::MINUSINF); for(int z=1; zis_plain || !validsidepar[sidepar] || qfi.usershape >= 0) if(GDIM == 2) { + if(!qfi.fshape || !qfi.fshape->is_plain || !cgi.validsidepar[sidepar] || qfi.usershape >= 0) if(GDIM == 2) { escherSidewall(c, sidepar, V, col); return true; } if(!qfi.fshape) return true; - if(qfi.fshape == &shBigTriangle && pseudohept(c->move(i))) return false; - if(qfi.fshape == &shTriheptaFloor && !pseudohept(c) && !pseudohept(c->move(i))) return false; + if(qfi.fshape == &cgi.shBigTriangle && pseudohept(c->move(i))) return false; + if(qfi.fshape == &cgi.shTriheptaFloor && !pseudohept(c) && !pseudohept(c->move(i))) return false; PPR prio; /* if(mirr) prio = PPR::GLASS - 2; @@ -4100,7 +4098,7 @@ int getSnakelevColor(cell *c, int i, int last, int fd, color_t wcol) { void draw_wall(cell *c, const transmatrix& V, color_t wcol, color_t& zcol, int ct6, int fd) { if(DIM == 3 && WDIM == 2) { - if(!qfi.fshape) qfi.fshape = &shFullFloor; + if(!qfi.fshape) qfi.fshape = &cgi.shFullFloor; if(conegraph(c)) { draw_shapevec(c, V, qfi.fshape->cone[0], darkena(wcol, 0, 0xFF), PPR::WALL); dynamicval p(poly_outline, OUTLINE_TRANS); @@ -4111,7 +4109,7 @@ void draw_wall(cell *c, const transmatrix& V, color_t wcol, color_t& zcol, int c int hdir = 0; for(int i=0; itype; i++) if(c->move(i)->wall == waClosedGate) hdir = i; - queuepolyat(V * ddspin(c, hdir, M_PI), shPalaceGate, darkena(wcol, 0, 0xFF), wmspatial?PPR::WALL3A:PPR::WALL); + queuepolyat(V * ddspin(c, hdir, M_PI), cgi.shPalaceGate, darkena(wcol, 0, 0xFF), wmspatial?PPR::WALL3A:PPR::WALL); return; } color_t wcol0 = wcol; @@ -4138,12 +4136,12 @@ void draw_wall(cell *c, const transmatrix& V, color_t wcol, color_t& zcol, int c int hdir = 0; for(int i=0; itype; i++) if(c->move(i)->wall == waClosedGate) hdir = i; - transmatrix V2 = mscale(V, wmspatial?geom3::WALL:1) * ddspin(c, hdir, M_PI); - queuepolyat(V2, shPalaceGate, darkena(wcol, 0, 0xFF), wmspatial?PPR::WALL3A:PPR::WALL); + transmatrix V2 = mscale(V, wmspatial?cgi.WALL:1) * ddspin(c, hdir, M_PI); + queuepolyat(V2, cgi.shPalaceGate, darkena(wcol, 0, 0xFF), wmspatial?PPR::WALL3A:PPR::WALL); starcol = 0; } - hpcshape& shThisWall = isGrave(c->wall) ? shCross : shWall[ct6]; + hpcshape& shThisWall = isGrave(c->wall) ? cgi.shCross : cgi.shWall[ct6]; if(conegraph(c)) { const int layers = 2 << detaillevel; @@ -4160,7 +4158,7 @@ void draw_wall(cell *c, const transmatrix& V, color_t wcol, color_t& zcol, int c if(starcol) queuepoly(V, shThisWall, darkena(starcol, 0, 0xFF)); } else { - transmatrix Vdepth = mscale(V, geom3::WALL); + transmatrix Vdepth = mscale(V, cgi.WALL); int alpha = 0xFF; if(c->wall == waIcewall) alpha = 0xC0; @@ -4222,22 +4220,22 @@ void draw_gravity_particles(cell *c, const transmatrix V) { switch(gravity_state) { case gsNormal: for(int i=0; i<6; i++) { - transmatrix T = V * spin(i*degree*60) * xpush(crossf/3); + transmatrix T = V * spin(i*degree*60) * xpush(cgi.crossf/3); queueline(mmscale(T, levf(r0)) * C0, mmscale(T, levf(r1)) * C0, grav_normal_color); } break; case gsAnti: for(int i=0; i<6; i++) { - transmatrix T = V * spin(i*degree*60) * xpush(crossf/3); + transmatrix T = V * spin(i*degree*60) * xpush(cgi.crossf/3); queueline(mmscale(T, levf(r0)) * C0, mmscale(T, levf(r1)) * C0, antigrav_color); } break; case gsLevitation: for(int i=0; i<6; i++) { - transmatrix T0 = V * spin(i*degree*60 + tt/60. * degree) * xpush(crossf/3); - transmatrix T1 = V * spin(i*degree*60 + (tt/60. + 30) * degree) * xpush(crossf/3); + transmatrix T0 = V * spin(i*degree*60 + tt/60. * degree) * xpush(cgi.crossf/3); + transmatrix T1 = V * spin(i*degree*60 + (tt/60. + 30) * degree) * xpush(cgi.crossf/3); ld lv = levf(DIM == 3 ? (i+0.5)/6 : 0.5); queueline(mmscale(T0, lv) * C0, mmscale(T1, lv) * C0, levitate_color); } @@ -4249,24 +4247,24 @@ void draw_gravity_particles(cell *c, const transmatrix V) { switch(gravity_state) { case gsNormal: for(int i=0; i<6; i++) { - transmatrix T0 = V * spin(i*degree*60) * xpush(crossf/3 * (1-r0)); - transmatrix T1 = V * spin(i*degree*60) * xpush(crossf/3 * (1-r1)); + transmatrix T0 = V * spin(i*degree*60) * xpush(cgi.crossf/3 * (1-r0)); + transmatrix T1 = V * spin(i*degree*60) * xpush(cgi.crossf/3 * (1-r1)); queueline(T0 * C0, T1 * C0, grav_normal_color); } break; case gsAnti: for(int i=0; i<6; i++) { - transmatrix T0 = V * spin(i*degree*60) * xpush(crossf/3 * r0); - transmatrix T1 = V * spin(i*degree*60) * xpush(crossf/3 * r1); + transmatrix T0 = V * spin(i*degree*60) * xpush(cgi.crossf/3 * r0); + transmatrix T1 = V * spin(i*degree*60) * xpush(cgi.crossf/3 * r1); queueline(T0 * C0, T1 * C0, antigrav_color); } break; case gsLevitation: for(int i=0; i<6; i++) { - transmatrix T0 = V * spin(i*degree*60 + tt/60. * degree) * xpush(crossf/3); - transmatrix T1 = V * spin(i*degree*60 + (tt/60. + 30) * degree) * xpush(crossf/3); + transmatrix T0 = V * spin(i*degree*60 + tt/60. * degree) * xpush(cgi.crossf/3); + transmatrix T1 = V * spin(i*degree*60 + (tt/60. + 30) * degree) * xpush(cgi.crossf/3); queueline(T0 * C0, T1 * C0, levitate_color); } break; @@ -4352,8 +4350,8 @@ void drawBoat(cell *c, const transmatrix*& Vboat, transmatrix& Vboat0, transmatr nospin = c->wall == waBoat && applyAnimation(c, Vboat0, footphase, LAYER_BOAT); if(!nospin) Vboat0 = face_the_player(V); else Vboat0 = cspin(0, 2, M_PI) * Vboat0; - queuepolyat(mscale(Vboat0, scalefactor/2), shBoatOuter, outcol, PPR::BOATLEV2); - queuepolyat(mscale(Vboat0, scalefactor/2-0.01), shBoatInner, incol, PPR::BOATLEV2); + queuepolyat(mscale(Vboat0, cgi.scalefactor/2), cgi.shBoatOuter, outcol, PPR::BOATLEV2); + queuepolyat(mscale(Vboat0, cgi.scalefactor/2-0.01), cgi.shBoatInner, incol, PPR::BOATLEV2); return; } @@ -4361,7 +4359,7 @@ void drawBoat(cell *c, const transmatrix*& Vboat, transmatrix& Vboat0, transmatr if(wmspatial && c->wall == waBoat) { nospin = c->wall == waBoat && applyAnimation(c, Vboat0, footphase, LAYER_BOAT); if(!nospin) Vboat0 = Vboat0 * ddspin(c, c->mondir, M_PI); - queuepolyat(Vboat0, shBoatOuter, outcol, PPR::BOATLEV); + queuepolyat(Vboat0, cgi.shBoatOuter, outcol, PPR::BOATLEV); Vboat = &(Vboat0 = V); } if(c->wall == waBoat) { @@ -4375,21 +4373,21 @@ void drawBoat(cell *c, const transmatrix*& Vboat, transmatrix& Vboat0, transmatr animations[LAYER_SMALL][c].footphase = 0; } if(wmspatial && GDIM == 2) - queuepolyat(mscale(Vboat0, (geom3::LAKE+1)/2), shBoatOuter, outcol, PPR::BOATLEV2); - queuepoly(Vboat0, shBoatOuter, outcol); - queuepoly(Vboat0, shBoatInner, incol); + queuepolyat(mscale(Vboat0, (cgi.LAKE+1)/2), cgi.shBoatOuter, outcol, PPR::BOATLEV2); + queuepoly(Vboat0, cgi.shBoatOuter, outcol); + queuepoly(Vboat0, cgi.shBoatInner, incol); } void shmup_gravity_floor(cell *c) { if(DIM == 2 && cellEdgeUnstable(c)) - set_floor(shMFloor); + set_floor(cgi.shMFloor); else - set_floor(shFullFloor); + set_floor(cgi.shFullFloor); } ld mousedist(transmatrix T) { if(GDIM == 2) return intval(mouseh, tC0(T)); - hyperpoint T1 = tC0(mscale(T, geom3::FLOOR)); + hyperpoint T1 = tC0(mscale(T, cgi.FLOOR)); if(mouseaim_sensitivity) return sqhypot_d(2, T1) + (invis_point(T1) ? 1e10 : 0); hyperpoint h1; applymodel(T1, h1); @@ -4422,9 +4420,9 @@ void make_clipping_planes() { void gridline(const transmatrix& V1, const hyperpoint h1, const transmatrix& V2, const hyperpoint h2, color_t col, int prec) { if(WDIM == 2 && GDIM == 3) { - ld eps = geom3::human_height/100; - queueline(V1*orthogonal_move(h1,geom3::FLOOR+eps), V2*orthogonal_move(h2,geom3::FLOOR+eps), col, prec); - queueline(V1*orthogonal_move(h1,geom3::WALL-eps), V2*orthogonal_move(h2,geom3::WALL-eps), col, prec); + ld eps = cgi.human_height/100; + queueline(V1*orthogonal_move(h1,cgi.FLOOR+eps), V2*orthogonal_move(h2,cgi.FLOOR+eps), col, prec); + queueline(V1*orthogonal_move(h1,cgi.WALL-eps), V2*orthogonal_move(h2,cgi.WALL-eps), col, prec); } else queueline(V1*h1, V2*h2, col, prec); @@ -4437,7 +4435,7 @@ void gridline(const transmatrix& V, const hyperpoint h1, const hyperpoint h2, co void draw_grid_at(cell *c, const transmatrix& V) { dynamicval lw(vid.linewidth, vid.linewidth); - vid.linewidth *= scalefactor; + vid.linewidth *= cgi.scalefactor; // sphere: 0.3948 // sphere heptagonal: 0.5739 @@ -4458,7 +4456,7 @@ void draw_grid_at(cell *c, const transmatrix& V) { if(binarytiling && !among(t, 5, 6, 8)) continue; if(!binarytiling && c->move(t) < c) continue; dynamicval g(poly_outline, gridcolor(c, c->move(t))); - queuepoly(V, shWireframe3D[t], 0); + queuepoly(V, cgi.shWireframe3D[t], 0); } } #endif @@ -4612,7 +4610,7 @@ int ceiling_category(cell *c) { ld camera_level; int get_skybrightness(int mul = 1) { - ld s = 1 - mul * (camera_level - geom3::WALL) / -2; + ld s = 1 - mul * (camera_level - cgi.WALL) / -2; if(s > 1) return 255; if(s < 0) return 0; return int(s * 255); @@ -4626,23 +4624,23 @@ void draw_ceiling(cell *c, const transmatrix& V, int fd, color_t& fcol, color_t& /* ceilingless levels */ case 1: { if(fieldpattern::fieldval_uniq(c) % 3 == 0) { - auto &star = queuepolyat(V * zpush(geom3::SKY+0.5), shNightStar, 0xFFFFFFFF, PPR::SKY); + auto &star = queuepolyat(V * zpush(cgi.SKY+0.5), cgi.shNightStar, 0xFFFFFFFF, PPR::SKY); star.tinf = NULL; star.flags |= POLY_INTENSE; } int sk = get_skybrightness(); if(sk > 0) { - auto sky = draw_shapevec(c, V, shFullFloor.levels[SIDE_SKY], 0x000000FF + 0x100 * (sk/17), PPR::SKY); + auto sky = draw_shapevec(c, V, cgi.shFullFloor.levels[SIDE_SKY], 0x000000FF + 0x100 * (sk/17), PPR::SKY); if(sky) sky->tinf = NULL, sky->flags |= POLY_INTENSE; } if(c->land == laAsteroids) { if(fieldpattern::fieldval_uniq(c) % 9 < 3) { - auto &downstar = queuepolyat(V * zpush(-0.5-geom3::SKY), shNightStar, 0xFFFFFFFF, PPR::SKY); + auto &downstar = queuepolyat(V * zpush(-0.5-cgi.SKY), cgi.shNightStar, 0xFFFFFFFF, PPR::SKY); downstar.tinf = NULL; downstar.flags |= POLY_INTENSE; } sk = get_skybrightness(-1); - auto sky = draw_shapevec(c, V * MirrorZ, shFullFloor.levels[SIDE_SKY], 0x000000FF + 0x100 * (sk/17), PPR::SKY); + auto sky = draw_shapevec(c, V * MirrorZ, cgi.shFullFloor.levels[SIDE_SKY], 0x000000FF + 0x100 * (sk/17), PPR::SKY); if(sky) sky->tinf = NULL, sky->flags |= POLY_INTENSE; } return; @@ -4653,7 +4651,7 @@ void draw_ceiling(cell *c, const transmatrix& V, int fd, color_t& fcol, color_t& if(c->land == laWineyard) { col = 0x4040FF; if(emeraldval(c) / 4 == 11) { - auto &sun = queuepolyat(V * zpush(geom3::SKY+0.5), shSun, 0xFFFF00FF, PPR::SKY); + auto &sun = queuepolyat(V * zpush(cgi.SKY+0.5), cgi.shSun, 0xFFFF00FF, PPR::SKY); sun.tinf = NULL; sun.flags |= POLY_INTENSE; } @@ -4668,7 +4666,7 @@ void draw_ceiling(cell *c, const transmatrix& V, int fd, color_t& fcol, color_t& if(sk > 0) { col = gradient(0, col, 0, sk, 255); col = darkena(col, 0, 255); - auto sky = draw_shapevec(c, V, shFullFloor.levels[SIDE_SKY], col, PPR::SKY); + auto sky = draw_shapevec(c, V, cgi.shFullFloor.levels[SIDE_SKY], col, PPR::SKY); if(sky) sky->tinf = NULL; } @@ -4676,7 +4674,7 @@ void draw_ceiling(cell *c, const transmatrix& V, int fd, color_t& fcol, color_t& } case 3: { - if(camera_level <= geom3::WALL) return; + if(camera_level <= cgi.WALL) return; draw_shapevec(c, V, qfi.fshape->levels[SIDE_WALL], darkena(fcol, fd, 0xFF), PPR::WALL); forCellIdEx(c2, i, c) if(ceiling_category(c2) != 3) { @@ -4687,7 +4685,7 @@ void draw_ceiling(cell *c, const transmatrix& V, int fd, color_t& fcol, color_t& } case 4: { - if(camera_level <= geom3::HIGH2) return; + if(camera_level <= cgi.HIGH2) return; auto ispal = [&] (cell *c0) { return c0->land == laPalace && among(c0->wall, waPalace, waClosedGate, waOpenGate); }; color_t wcol2 = 0xFFD500; if(ispal(c)) { @@ -4705,20 +4703,20 @@ void draw_ceiling(cell *c, const transmatrix& V, int fd, color_t& fcol, color_t& if(among(c->wall, waClosedGate, waOpenGate)) draw_shapevec(c, V, qfi.fshape->levels[SIDE_WALL], 0x202020FF, PPR::WALL); if(true) { - auto &star = queuepolyat(V * zpush(geom3::SKY+0.5), shNightStar, 0xFFFFFFFF, PPR::SKY); + auto &star = queuepolyat(V * zpush(cgi.SKY+0.5), cgi.shNightStar, 0xFFFFFFFF, PPR::SKY); star.tinf = NULL; star.flags |= POLY_INTENSE; } int sk = get_skybrightness(); if(sk > 0) { - auto sky = draw_shapevec(c, V, shFullFloor.levels[SIDE_SKY], 0x000000FF + 0x100 * (sk/17), PPR::SKY); + auto sky = draw_shapevec(c, V, cgi.shFullFloor.levels[SIDE_SKY], 0x000000FF + 0x100 * (sk/17), PPR::SKY); if(sky) sky->tinf = NULL, sky->flags |= POLY_INTENSE; } break; } case 5: { - if(camera_level <= geom3::WALL) return; + if(camera_level <= cgi.WALL) return; if(pseudohept(c)) { forCellIdEx(c2, i, c) @@ -4728,13 +4726,13 @@ void draw_ceiling(cell *c, const transmatrix& V, int fd, color_t& fcol, color_t& draw_shapevec(c, V, qfi.fshape->levels[SIDE_WALL], darkena(fcol, fd, 0xFF), PPR::WALL); if(true) { - auto &star = queuepolyat(V * zpush(geom3::SKY+0.5), shNightStar, 0xFFFFFFFF, PPR::SKY); + auto &star = queuepolyat(V * zpush(cgi.SKY+0.5), cgi.shNightStar, 0xFFFFFFFF, PPR::SKY); star.tinf = NULL; star.flags |= POLY_INTENSE; } int sk = get_skybrightness(); if(sk > 0) { - auto sky = draw_shapevec(c, V, shFullFloor.levels[SIDE_SKY], 0x000000FF + 0x100 * (sk/17), PPR::SKY); + auto sky = draw_shapevec(c, V, cgi.shFullFloor.levels[SIDE_SKY], 0x000000FF + 0x100 * (sk/17), PPR::SKY); if(sky) sky->tinf = NULL, sky->flags |= POLY_INTENSE; } } @@ -4788,7 +4786,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { if(WDIM == 3 && pmodel == mdPerspective) { using namespace hyperpoint_vec; hyperpoint H = tC0(V); - for(hyperpoint& cpoint: clipping_planes) if((H|cpoint) < -sin_auto(corner_bonus)) { + for(hyperpoint& cpoint: clipping_planes) if((H|cpoint) < -sin_auto(cgi.corner_bonus)) { drawcell_in_radar(c, V); return; } @@ -4796,7 +4794,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { } #if CAP_SHAPES - set_floor(shFloor); + set_floor(cgi.shFloor); #endif ivoryz = isGravityLand(c->land); @@ -4907,7 +4905,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { #if CAP_SHAPES if(c->land == laNone && (cmode & sm::MAP)) { - queuepoly(V, shTriangle, 0xFF0000FF); + queuepoly(V, cgi.shTriangle, 0xFF0000FF); } #endif @@ -4970,10 +4968,10 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { if(c->wall == waThumperOn && DIM == 2) { ld ds = fractick(160); for(int u=0; u<5; u++) { - ld rad = hexf * (.3 * (u + ds)); - int tcol = darkena(gradient(forecolor, backcolor, 0, rad, 1.5 * hexf), 0, 0xFF); + ld rad = cgi.hexf * (.3 * (u + ds)); + int tcol = darkena(gradient(forecolor, backcolor, 0, rad, 1.5 * cgi.hexf), 0, 0xFF); PRING(a) - curvepoint(V*xspinpush0(a * M_PI / S42, rad)); + curvepoint(V*xspinpush0(a * M_PI / cgi.S42, rad)); queuecurve(tcol, 0, PPR::LINE); } } @@ -5042,7 +5040,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { for(int t=0; ttype; t++) if(c->move(t) && c->move(t)->ligon) { ld hdir = displayspin(c, t); int lcol = darkena(gradient(iinf[itOrbLightning].color, 0, 0, tim, 1100), 0, 0xFF); - queueline(V*chei(xspinpush(ticks * M_PI / S42, hexf/2), rand() % 1000, 1000) * C0, V*chei(xspinpush(hdir, crossf), rand() % 1000, 1000) * C0, lcol, 2 + vid.linequality); + queueline(V*chei(xspinpush(ticks * M_PI / cgi.S42, cgi.hexf/2), rand() % 1000, 1000) * C0, V*chei(xspinpush(hdir, cgi.crossf), rand() % 1000, 1000) * C0, lcol, 2 + vid.linequality); } } @@ -5079,16 +5077,16 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { const transmatrix *Vdp = WDIM == 3 ? &V: !wmspatial ? &V : - sl ? &(Vd0= mscale(V, DIM == 3 ? geom3::SLEV[sl] - geom3::FLOOR : geom3::SLEV[sl])) : - (highwall(c) && GDIM == 2) ? &(Vd0= mscale(V, (1+geom3::WALL)/2)) : + sl ? &(Vd0= mscale(V, DIM == 3 ? cgi.SLEV[sl] - cgi.FLOOR : cgi.SLEV[sl])) : + (highwall(c) && GDIM == 2) ? &(Vd0= mscale(V, (1+cgi.WALL)/2)) : #if CAP_SHAPES - (chasmg==1) ? &(Vd0 = mscale(V, DIM == 3 ? geom3::LAKE - geom3::FLOOR : geom3::LAKE)) : + (chasmg==1) ? &(Vd0 = mscale(V, DIM == 3 ? cgi.LAKE - cgi.FLOOR : cgi.LAKE)) : #endif &V; #if CAP_SHAPES transmatrix Vf0; - const transmatrix& Vf = (chasmg && wmspatial) ? (Vf0=mscale(V, geom3::BOTTOM)) : V; + const transmatrix& Vf = (chasmg && wmspatial) ? (Vf0=mscale(V, cgi.BOTTOM)) : V; #endif const transmatrix *Vboat = &(*Vdp); @@ -5112,16 +5110,16 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { zcol = 0; int rd = rosedist(c); if(rd == 1) - draw_floorshape(c, V, shRoseFloor, 0x80406020); + draw_floorshape(c, V, cgi.shRoseFloor, 0x80406020); if(rd == 2) - draw_floorshape(c, V, shRoseFloor, 0x80406040); + draw_floorshape(c, V, cgi.shRoseFloor, 0x80406040); if(c->land == laZebra) fd++; if(c->land == laHalloween && !wmblack) { - transmatrix Vdepth = wmspatial ? mscale(V, geom3::BOTTOM) : V; + transmatrix Vdepth = wmspatial ? mscale(V, cgi.BOTTOM) : V; if(DIM == 3) - draw_shapevec(c, V, shFullFloor.levels[SIDE_LAKE], darkena(firecolor(0, 10), 0, 0xDF), PPR::TRANSPARENT_LAKE); + draw_shapevec(c, V, cgi.shFullFloor.levels[SIDE_LAKE], darkena(firecolor(0, 10), 0, 0xDF), PPR::TRANSPARENT_LAKE); else - draw_floorshape(c, Vdepth, shFullFloor, darkena(firecolor(0, 10), 0, 0xDF), PPR::LAKEBOTTOM); + draw_floorshape(c, Vdepth, cgi.shFullFloor, darkena(firecolor(0, 10), 0, 0xDF), PPR::LAKEBOTTOM); } } @@ -5133,16 +5131,16 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { #endif else if(patterns::whichShape == '7') - set_floor(shBigHepta); + set_floor(cgi.shBigHepta); else if(patterns::whichShape == '8') - set_floor(shTriheptaFloor); + set_floor(cgi.shTriheptaFloor); else if(patterns::whichShape == '6') - set_floor(shBigTriangle); + set_floor(cgi.shBigTriangle); else if(among(patterns::whichShape, '9', '^')) - set_floor(shFullFloor); + set_floor(cgi.shFullFloor); #if CAP_TEXTURE else if(DIM == 2 && texture::config.apply(c, Vf, darkena(fcol, fd, 0xFF))) ; @@ -5165,46 +5163,46 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { transmatrix V2 = V * qfi.spin; if(!wmblack) for(int d=0; dtype; d++) { inmirrorcount+=d; - queuepolyat(V2 * spin(d*M_PI/S3), shHalfFloor[2], darkena(fcol, fd, 0xFF), PPR::FLOORa); - if(GDIM == 3 && camera_level > geom3::WALL && pmodel == mdPerspective) - queuepolyat(V2 * spin(d*M_PI/S3), shHalfFloor[5], darkena(fcol, fd, 0xFF), PPR::FLOORa); + queuepolyat(V2 * spin(d*M_PI/S3), cgi.shHalfFloor[2], darkena(fcol, fd, 0xFF), PPR::FLOORa); + if(GDIM == 3 && camera_level > cgi.WALL && pmodel == mdPerspective) + queuepolyat(V2 * spin(d*M_PI/S3), cgi.shHalfFloor[5], darkena(fcol, fd, 0xFF), PPR::FLOORa); inmirrorcount-=d; } if(GDIM == 3) { for(int d=0; d<6; d++) - queue_transparent_wall(V2 * spin(d*M_PI/S3), shHalfMirror[2], 0xC0C0C080); + queue_transparent_wall(V2 * spin(d*M_PI/S3), cgi.shHalfMirror[2], 0xC0C0C080); } else if(wmspatial) { const int layers = 2 << detaillevel; for(int z=1; z geom3::WALL && pmodel == mdPerspective) - queuepolyat(mirrorif(V2, !onleft), shHalfFloor[ct6+3], darkena(fcol, fd, 0xFF), PPR::FLOORa); + queuepolyat(mirrorif(V2, !onleft), cgi.shHalfFloor[ct6], darkena(fcol, fd, 0xFF), PPR::FLOORa); + if(GDIM == 3 && camera_level > cgi.WALL && pmodel == mdPerspective) + queuepolyat(mirrorif(V2, !onleft), cgi.shHalfFloor[ct6+3], darkena(fcol, fd, 0xFF), PPR::FLOORa); inmirrorcount--; - queuepolyat(mirrorif(V2, onleft), shHalfFloor[ct6], darkena(fcol, fd, 0xFF), PPR::FLOORa); - if(GDIM == 3 && camera_level > geom3::WALL && pmodel == mdPerspective) - queuepolyat(mirrorif(V2, onleft), shHalfFloor[ct6+3], darkena(fcol, fd, 0xFF), PPR::FLOORa); + queuepolyat(mirrorif(V2, onleft), cgi.shHalfFloor[ct6], darkena(fcol, fd, 0xFF), PPR::FLOORa); + if(GDIM == 3 && camera_level > cgi.WALL && pmodel == mdPerspective) + queuepolyat(mirrorif(V2, onleft), cgi.shHalfFloor[ct6+3], darkena(fcol, fd, 0xFF), PPR::FLOORa); } if(GDIM == 3) - queue_transparent_wall(V2, shHalfMirror[ct6], 0xC0C0C080); + queue_transparent_wall(V2, cgi.shHalfMirror[ct6], 0xC0C0C080); else if(wmspatial) { const int layers = 2 << detaillevel; for(int z=1; z p(poly_outline, OUTLINE_TRANS); queuepolyat(V2 * spin(M_PI*2/3), shSemiFloorShadow, SHADOW_WALL, DIM == 2 ? PPR::WALLSHADOW : PPR::TRANSPARENT_SHADOW); } - auto& side = queuepolyat(V2, shSemiFloorSide[SIDE_WALL], darkena(vcol, fd, 0xFF), PPR::WALL3A-2+away(V2)); - if(DIM == 3 && qfi.fshape) side.tinf = &shar.tinf3; + queuepolyat(DIM == 2 ? Vdepth : V2, cgi.shSemiFloor[0], darkena(vcol, fd, 0xFF), PPR::WALL3A); + {dynamicval p(poly_outline, OUTLINE_TRANS); queuepolyat(V2 * spin(M_PI*2/3), cgi.shSemiFloorShadow, SHADOW_WALL, DIM == 2 ? PPR::WALLSHADOW : PPR::TRANSPARENT_SHADOW); } + auto& side = queuepolyat(V2, cgi.shSemiFloorSide[SIDE_WALL], darkena(vcol, fd, 0xFF), PPR::WALL3A-2+away(V2)); + if(DIM == 3 && qfi.fshape) side.tinf = &floor_texture_vertices[shar.id]; - if(validsidepar[SIDE_WALL]) forCellIdEx(c2, j, c) { + if(cgi.validsidepar[SIDE_WALL]) forCellIdEx(c2, j, c) { int dis = i-j; dis %= 6; if(dis<0) dis += 6; @@ -5252,10 +5250,10 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { } else { - hpcshape *shar = shSemiFeatherFloor; + hpcshape *shar = cgi.shSemiFeatherFloor; - if(wmblack) shar = shSemiBFloor; - if(wmplain) shar = shSemiFloor; + if(wmblack) shar = cgi.shSemiBFloor; + if(wmplain) shar = cgi.shSemiFloor; queuepoly(V2, shar[0], darkena(winf[waVinePlant].color, fd, 0xFF)); @@ -5270,19 +5268,19 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { ; else if(wmblack) { - set_floor(shBFloor[ct6]); + set_floor(cgi.shBFloor[ct6]); int rd = rosedist(c); if(rd == 1) - queuepoly(Vf, shHeptaMarker, darkena(fcol, 0, 0x80)); + queuepoly(Vf, cgi.shHeptaMarker, darkena(fcol, 0, 0x80)); else if(rd == 2) - queuepoly(Vf, shHeptaMarker, darkena(fcol, 0, 0x40)); + queuepoly(Vf, cgi.shHeptaMarker, darkena(fcol, 0, 0x40)); } else if(isWarped(c) || is_nice_dual(c)) set_maywarp_floor(c); else if(wmplain) { - set_floor(shFloor); + set_floor(cgi.shFloor); } else if(randomPatternsMode && c->land != laBarrier && !isWarpedType(c->land)) { @@ -5295,26 +5293,26 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { else if(k == RPV_CYCLE && k7 < 4) set_towerfloor(c, celldist); else switch(j) { - case 0: set_floor(shCloudFloor); break; - case 1: set_floor(shFeatherFloor); break; - case 2: set_floor(shStarFloor); break; - case 3: set_floor(shTriFloor); break; - case 4: set_floor(shSStarFloor); break; - case 5: set_floor(shOverFloor); break; - case 6: set_floor(shFeatherFloor); break; - case 7: set_floor(shDemonFloor); break; - case 8: set_floor(shCrossFloor); break; - case 9: set_floor(shMFloor); break; - case 10: set_floor(shCaveFloor); break; - case 11: set_floor(shPowerFloor); break; - case 12: set_floor(shDesertFloor); break; - case 13: set_floor(shChargedFloor); break; - case 14: set_floor(shLavaFloor); break; + case 0: set_floor(cgi.shCloudFloor); break; + case 1: set_floor(cgi.shFeatherFloor); break; + case 2: set_floor(cgi.shStarFloor); break; + case 3: set_floor(cgi.shTriFloor); break; + case 4: set_floor(cgi.shSStarFloor); break; + case 5: set_floor(cgi.shOverFloor); break; + case 6: set_floor(cgi.shFeatherFloor); break; + case 7: set_floor(cgi.shDemonFloor); break; + case 8: set_floor(cgi.shCrossFloor); break; + case 9: set_floor(cgi.shMFloor); break; + case 10: set_floor(cgi.shCaveFloor); break; + case 11: set_floor(cgi.shPowerFloor); break; + case 12: set_floor(cgi.shDesertFloor); break; + case 13: set_floor(cgi.shChargedFloor); break; + case 14: set_floor(cgi.shLavaFloor); break; } } // else if(c->land == laPrairie && !eoh && allemptynear(c) && fieldpattern::getflowerdist(c) <= 1) - // queuepoly(Vf, shLeafFloor[ct6], darkena(fcol, fd, 0xFF)); + // queuepoly(Vf, cgi.shLeafFloor[ct6], darkena(fcol, fd, 0xFF)); /* else if(c->land == laPrairie && prairie::isriver(c)) @@ -5324,12 +5322,12 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { else switch(c->land) { case laPrairie: case laAlchemist: - set_floor(shCloudFloor); + set_floor(cgi.shCloudFloor); break; case laJungle: case laWineyard: - set_floor(shFeatherFloor); + set_floor(cgi.shFeatherFloor); break; case laZebra: @@ -5349,28 +5347,28 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { case laRlyeh: case laTemple: - set_floor(shTriFloor); + set_floor(cgi.shTriFloor); break; case laVolcano: case laVariant: - set_floor(shLavaFloor); + set_floor(cgi.shLavaFloor); break; case laRose: - set_floor(shRoseFloor); + set_floor(cgi.shRoseFloor); break; case laTortoise: - set_floor(shTurtleFloor); + set_floor(cgi.shTurtleFloor); break; case laBurial: case laRuins: - set_floor(shBarrowFloor); + set_floor(cgi.shBarrowFloor); break; case laTrollheim: - set_floor(shTrollFloor); + set_floor(cgi.shTrollFloor); break; /*case laMountain: @@ -5378,88 +5376,88 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { break; */ case laGraveyard: - set_floor(shCrossFloor); + set_floor(cgi.shCrossFloor); break; case laMotion: - set_floor(shMFloor); + set_floor(cgi.shMFloor); break; case laWhirlwind: case laEFire: case laEAir: case laEWater: case laEEarth: case laElementalWall: - set_floor(shNewFloor); + set_floor(cgi.shNewFloor); break; case laHell: - set_floor(shDemonFloor); + set_floor(cgi.shDemonFloor); break; case laIce: case laBlizzard: - set_floor(shStarFloor); + set_floor(cgi.shStarFloor); break; case laSwitch: - set_floor(shSwitchFloor); + set_floor(cgi.shSwitchFloor); if(ctof(c) && STDVAR && !archimedean && !binarytiling && GDIM == 2) for(int i=0; itype; i++) - queuepoly(Vf * ddspin(c, i, M_PI/S7) * xpush(rhexf), shSwitchDisk, darkena(minf[active_switch()].color, fd, 0xFF)); + queuepoly(Vf * ddspin(c, i, M_PI/S7) * xpush(cgi.rhexf), cgi.shSwitchDisk, darkena(minf[active_switch()].color, fd, 0xFF)); break; case laStorms: - set_floor(shChargedFloor); + set_floor(cgi.shChargedFloor); break; case laWildWest: - set_floor(shSStarFloor); + set_floor(cgi.shSStarFloor); break; case laPower: - set_floor(shPowerFloor); + set_floor(cgi.shPowerFloor); break; case laCaves: case laLivefjord: case laDeadCaves: - set_floor(shCaveFloor); + set_floor(cgi.shCaveFloor); break; case laDryForest: - set_floor(DIM == 3 ? shFeatherFloor : shDesertFloor); + set_floor(DIM == 3 ? cgi.shFeatherFloor : cgi.shDesertFloor); break; case laDesert: case laRedRock: case laSnakeNest: case laCocytus: - set_floor(shDesertFloor); + set_floor(cgi.shDesertFloor); break; case laBull: - set_floor(shButterflyFloor); + set_floor(cgi.shButterflyFloor); break; case laCaribbean: case laOcean: case laOceanWall: case laWhirlpool: - set_floor(shCloudFloor); + set_floor(cgi.shCloudFloor); break; case laKraken: case laDocks: - set_floor(shFullFloor); + set_floor(cgi.shFullFloor); break; case laPalace: case laTerracotta: - set_floor(shPalaceFloor); + set_floor(cgi.shPalaceFloor); break; case laDragon: - set_floor(shDragonFloor); + set_floor(cgi.shDragonFloor); break; case laOvergrown: case laClearing: case laHauntedWall: case laHaunted: case laHauntedBorder: - set_floor(shOverFloor); + set_floor(cgi.shOverFloor); break; case laMercuryRiver: { if(eoh) - set_floor(shFloor); + set_floor(cgi.shFloor); else { int bridgedir = -1; if(c->type == 6) { @@ -5469,17 +5467,17 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { bridgedir = i; } if(bridgedir == -1) - set_floor(shPalaceFloor); + set_floor(cgi.shPalaceFloor); else { transmatrix bspin = ddspin(c, bridgedir); - set_floor(bspin, shMercuryBridge[0]); + set_floor(bspin, cgi.shMercuryBridge[0]); // only needed in one direction if(c < c->move(bridgedir)) { bspin = Vf * bspin; - queuepoly(bspin, shMercuryBridge[1], darkena(fcol, fd+1, 0xFF)); + queuepoly(bspin, cgi.shMercuryBridge[1], darkena(fcol, fd+1, 0xFF)); if(wmspatial) { - queuepolyat(mscale(bspin, geom3::LAKE), shMercuryBridge[1], darkena(gradient(0, winf[waMercury].color, 0, 0.8,1), 0, 0x80), PPR::LAKELEV); - queuepolyat(mscale(bspin, geom3::BOTTOM), shMercuryBridge[1], darkena(0x202020, 0, 0xFF), PPR::LAKEBOTTOM); + queuepolyat(mscale(bspin, cgi.LAKE), cgi.shMercuryBridge[1], darkena(gradient(0, winf[waMercury].color, 0, 0.8,1), 0, 0x80), PPR::LAKELEV); + queuepolyat(mscale(bspin, cgi.BOTTOM), cgi.shMercuryBridge[1], darkena(0x202020, 0, 0xFF), PPR::LAKEBOTTOM); } } } @@ -5490,14 +5488,14 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { case laHive: if(c->wall != waFloorB && c->wall != waFloorA && c->wall != waMirror && c->wall != waCloud) { fd = 1; - set_floor(shFloor); + set_floor(cgi.shFloor); if(c->wall != waMirror && c->wall != waCloud && DIM == 2) - draw_floorshape(c, V, shMFloor, darkena(fcol, 2, 0xFF), PPR::FLOORa); + draw_floorshape(c, V, cgi.shMFloor, darkena(fcol, 2, 0xFF), PPR::FLOORa); if(c->wall != waMirror && c->wall != waCloud && DIM == 2) - draw_floorshape(c, V, shMFloor2, darkena(fcol, fcol==wcol ? 1 : 2, 0xFF), PPR::FLOORb); + draw_floorshape(c, V, cgi.shMFloor2, darkena(fcol, fcol==wcol ? 1 : 2, 0xFF), PPR::FLOORb); } else - set_floor(shFloor); + set_floor(cgi.shFloor); break; case laEndorian: @@ -5505,10 +5503,10 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { shmup_gravity_floor(c); else if(c->wall == waTrunk) - set_floor(shFloor); + set_floor(cgi.shFloor); else if(c->wall == waCanopy || c->wall == waSolidBranch || c->wall == waWeakBranch) - set_floor(shFeatherFloor); + set_floor(cgi.shFeatherFloor); else set_towerfloor(c); @@ -5523,13 +5521,13 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { case laBrownian: if(among(c->wall, waSea, waBoat)) - set_floor(shCloudFloor); + set_floor(cgi.shCloudFloor); else - set_floor(shTrollFloor); + set_floor(cgi.shTrollFloor); break; default: - set_floor(shFloor); + set_floor(cgi.shFloor); } // actually draw the floor @@ -5545,19 +5543,19 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { color_t col = c->land == laCocytus ? 0x080808FF : 0x101010FF; - if(qfi.fshape == &shCloudFloor) - set_floor(shCloudSeabed); - else if(qfi.fshape == &shLavaFloor) - set_floor(shLavaSeabed); - else if(qfi.fshape == &shFloor) - set_floor(shFullFloor); - else if(qfi.fshape == &shCaveFloor) - set_floor(shCaveSeabed); + if(qfi.fshape == &cgi.shCloudFloor) + set_floor(cgi.shCloudSeabed); + else if(qfi.fshape == &cgi.shLavaFloor) + set_floor(cgi.shLavaSeabed); + else if(qfi.fshape == &cgi.shFloor) + set_floor(cgi.shFullFloor); + else if(qfi.fshape == &cgi.shCaveFloor) + set_floor(cgi.shCaveSeabed); if(WDIM == 2 && GDIM == 3 && qfi.fshape) draw_shapevec(c, V, qfi.fshape->levels[SIDE_LTOB], col, PPR::LAKEBOTTOM); else - draw_qfi(c, mscale(V, geom3::BOTTOM), col, PPR::LAKEBOTTOM); + draw_qfi(c, mscale(V, cgi.BOTTOM), col, PPR::LAKEBOTTOM); int fd0 = fd ? fd-1 : 0; if(WDIM == 2 && GDIM == 3 && qfi.fshape) @@ -5580,7 +5578,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { int rd = rosedist(c); if(rd) { dynamicval qfi2(qfi, qfi); - qfi.fshape = &shRoseFloor; + qfi.fshape = &cgi.shRoseFloor; int t = isize(ptds); color_t rcol; if(rd == 1) rcol = 0x80406040; @@ -5604,7 +5602,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { auto si = patterns::getpatterninfo0(c); for(int i=(si.dir + MODFIXER) % si.symmetries; itype; i += si.symmetries) { - queuepoly(V * ddspin(c, i) * (si.reflect?Mirror:Id), shAsymmetric, darkena(0x000000, 0, 0xC0)); + queuepoly(V * ddspin(c, i) * (si.reflect?Mirror:Id), cgi.shAsymmetric, darkena(0x000000, 0, 0xC0)); si.dir += si.symmetries; } @@ -5620,7 +5618,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { dist0 >= geom3::middetail ? 0xFFFF8080 : 0XFFFFFF80; #if 1 - queuepoly(V, shHeptaMarker, darkena(col & 0xFFFFFF, 0, 0xFF)); + queuepoly(V, cgi.shHeptaMarker, darkena(col & 0xFFFFFF, 0, 0xFF)); #else char buf[64]; sprintf(buf, "%3.1f", float(dist0)); @@ -5632,14 +5630,14 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { if(realred(c->wall) && !wmspatial) { int s = snakelevel(c); - if(s >= 1) draw_floorshape(c, V, shRedRockFloor[0], getSnakelevColor(c, 0, 7, fd, wcol)); - if(s >= 2) draw_floorshape(c, V, shRedRockFloor[1], getSnakelevColor(c, 1, 7, fd, wcol)); - if(s >= 3) draw_floorshape(c, V, shRedRockFloor[2], getSnakelevColor(c, 2, 7, fd, wcol)); + if(s >= 1) draw_floorshape(c, V, cgi.shRedRockFloor[0], getSnakelevColor(c, 0, 7, fd, wcol)); + if(s >= 2) draw_floorshape(c, V, cgi.shRedRockFloor[1], getSnakelevColor(c, 1, 7, fd, wcol)); + if(s >= 3) draw_floorshape(c, V, cgi.shRedRockFloor[2], getSnakelevColor(c, 2, 7, fd, wcol)); } if(c->wall == waTower && !wmspatial) { fcol = 0xE8E8E8; - set_floor(shMFloor); + set_floor(cgi.shMFloor); } if(pseudohept(c) && ( @@ -5648,14 +5646,14 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { (c->land == laClearing && !BITRUNCATED))) { #if MAXMDIM >= 4 if(DIM == 3 && WDIM == 2) - queuepoly((*Vdp)*zpush(geom3::FLOOR), shHeptaMarker, wmblack ? 0x80808080 : 0x00000080); + queuepoly((*Vdp)*zpush(cgi.FLOOR), cgi.shHeptaMarker, wmblack ? 0x80808080 : 0x00000080); else #endif - queuepoly((*Vdp), shHeptaMarker, wmblack ? 0x80808080 : 0x00000080); + queuepoly((*Vdp), cgi.shHeptaMarker, wmblack ? 0x80808080 : 0x00000080); } if(conformal::includeHistory && conformal::inmovehistory.count(c)) - queuepoly((*Vdp), shHeptaMarker, 0x000000C0); + queuepoly((*Vdp), cgi.shHeptaMarker, 0x000000C0); char xch = winf[c->wall].glyph; @@ -5678,18 +5676,18 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { else if(c->move(a)->master->distance > c->master->distance && c->master->distance > viewctr.at->distance && !quotient) continue; } if(qfi.fshape && wmescher) { - auto& poly = queuepoly(V, shWall3D[a], darkena(wcol2 - d * get_darkval(a), 0, 0xFF)); + auto& poly = queuepoly(V, cgi.shWall3D[a], darkena(wcol2 - d * get_darkval(a), 0, 0xFF)); if(texture::config.tstate == texture::tsActive && isize(texture::config.tinf3.tvertices)) { poly.tinf = &texture::config.tinf3; poly.offset_texture = 0; } else { - poly.tinf = &qfi.fshape->tinf3; + poly.tinf = &floor_texture_vertices[qfi.fshape->id]; poly.offset_texture = 0; } } else - queuepoly(V, shPlainWall3D[a], darkena(wcol2 - d * get_darkval(a), 0, 0xFF)); + queuepoly(V, cgi.shPlainWall3D[a], darkena(wcol2 - d * get_darkval(a), 0, 0xFF)); } } else { @@ -5697,7 +5695,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { color_t t = transcolor(c, c->move(a), wcol); if(t) { t = t - get_darkval(a) * ((t & 0xF0F0F000) >> 4); - queue_transparent_wall(V, shPlainWall3D[a], t); + queue_transparent_wall(V, cgi.shPlainWall3D[a], t); } } if(among(c->wall, waBoat, waStrandedBoat)) drawBoat(c, Vboat, V, V); @@ -5714,27 +5712,27 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { else if(c->wall == waMineOpen) { int mines = countMinesAround(c); if(mines >= 10) - queuepoly(face_the_player(V), shBigMineMark[0], darkena(minecolors[(mines/10)%10], 0, 0xFF)); - queuepoly(face_the_player(V), shMineMark[0], darkena(minecolors[mines%10], 0, 0xFF)); + queuepoly(face_the_player(V), cgi.shBigMineMark[0], darkena(minecolors[(mines/10)%10], 0, 0xFF)); + queuepoly(face_the_player(V), cgi.shMineMark[0], darkena(minecolors[mines%10], 0, 0xFF)); } else if(winf[c->wall].glyph == '.' || among(c->wall, waFloorA, waFloorB, waChasm, waLadder, waCanopy) || isWatery(c) || isSulphuric(c->wall)) ; else if(c->wall == waBigBush || c->wall == waSolidBranch) - queuepolyat(face_the_player(V), shSolidBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+3); + queuepolyat(face_the_player(V), cgi.shSolidBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+3); else if(c->wall == waSmallBush || c->wall == waWeakBranch) - queuepolyat(face_the_player(V), shWeakBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+3); + queuepolyat(face_the_player(V), cgi.shWeakBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+3); else - queuepoly(face_the_player(V), chasmgraph(c) ? shSawRing : shRing, darkena(wcol, 0, 0xFF)); + queuepoly(face_the_player(V), chasmgraph(c) ? cgi.shSawRing : cgi.shRing, darkena(wcol, 0, 0xFF)); } int rd = rosedist(c); if(rd == 1) - queuepoly(face_the_player(V), shLoveRing, darkena(0x804060, 0, 0xFF)); + queuepoly(face_the_player(V), cgi.shLoveRing, darkena(0x804060, 0, 0xFF)); if(rd == 2) - queuepoly(face_the_player(V), shLoveRing, darkena(0x402030, 0, 0xFF)); + queuepoly(face_the_player(V), cgi.shLoveRing, darkena(0x402030, 0, 0xFF)); } #else if(0) ; @@ -5744,45 +5742,45 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { case waBigBush: if(detaillevel >= 2) - queuepolyat(mmscale(V, zgrad0(0, geom3::slev, 1, 2)), shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL); + queuepolyat(mmscale(V, zgrad0(0, cgi.slev, 1, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL); if(detaillevel >= 1) - queuepolyat(mmscale(V, geom3::SLEV[1]) * pispin, shWeakBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+1); + queuepolyat(mmscale(V, cgi.SLEV[1]) * pispin, cgi.shWeakBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+1); if(detaillevel >= 2) - queuepolyat(mmscale(V, zgrad0(0, geom3::slev, 3, 2)), shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL+2); - queuepolyat(mmscale(V, geom3::SLEV[2]), shSolidBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+3); + queuepolyat(mmscale(V, zgrad0(0, cgi.slev, 3, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL+2); + queuepolyat(mmscale(V, cgi.SLEV[2]), cgi.shSolidBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+3); break; case waSmallBush: if(detaillevel >= 2) - queuepolyat(mmscale(V, zgrad0(0, geom3::slev, 1, 2)), shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL); + queuepolyat(mmscale(V, zgrad0(0, cgi.slev, 1, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL); if(detaillevel >= 1) - queuepolyat(mmscale(V, geom3::SLEV[1]) * pispin, shWeakBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+1); + queuepolyat(mmscale(V, cgi.SLEV[1]) * pispin, cgi.shWeakBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+1); if(detaillevel >= 2) - queuepolyat(mmscale(V, zgrad0(0, geom3::slev, 3, 2)), shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL+2); - queuepolyat(mmscale(V, geom3::SLEV[2]), shWeakBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+3); + queuepolyat(mmscale(V, zgrad0(0, cgi.slev, 3, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL+2); + queuepolyat(mmscale(V, cgi.SLEV[2]), cgi.shWeakBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+3); break; case waSolidBranch: - queuepoly(DIM == 3 ? mscale(V, geom3::BODY) : V, shSolidBranch, darkena(wcol, 0, 0xFF)); + queuepoly(DIM == 3 ? mscale(V, cgi.BODY) : V, cgi.shSolidBranch, darkena(wcol, 0, 0xFF)); break; case waWeakBranch: - queuepoly(DIM == 3 ? mscale(V, geom3::BODY) : V, shWeakBranch, darkena(wcol, 0, 0xFF)); + queuepoly(DIM == 3 ? mscale(V, cgi.BODY) : V, cgi.shWeakBranch, darkena(wcol, 0, 0xFF)); break; case waLadder: if(DIM == 3) { #if MAXMDIM >= 4 - draw_shapevec(c, V * zpush(-geom3::human_height/20), shMFloor.levels[0], 0x804000FF, PPR::FLOOR+1); + draw_shapevec(c, V * zpush(-cgi.human_height/20), cgi.shMFloor.levels[0], 0x804000FF, PPR::FLOOR+1); #endif } else if(euclid) { - draw_floorshape(c, V, shMFloor, 0x804000FF); - draw_floorshape(c, V, shMFloor2, 0x000000FF); + draw_floorshape(c, V, cgi.shMFloor, 0x804000FF); + draw_floorshape(c, V, cgi.shMFloor2, 0x000000FF); } else { - draw_floorshape(c, V, shFloor, 0x804000FF, PPR::FLOOR+1); - draw_floorshape(c, V, shMFloor, 0x000000FF, PPR::FLOOR+2); + draw_floorshape(c, V, cgi.shFloor, 0x804000FF, PPR::FLOOR+1); + draw_floorshape(c, V, cgi.shMFloor, 0x000000FF, PPR::FLOOR+2); } break; @@ -5812,7 +5810,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { double footphase; applyAnimation(c, V2, footphase, LAYER_BOAT); - queuepolyat(V2, shStatue, + queuepolyat(V2, cgi.shStatue, darkena(winf[c->wall].color, 0, 0xFF), PPR::BIGSTATUE ); @@ -5823,9 +5821,9 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { if(drawstar(c)) { zcol = wcol; if(wmspatial) - queuepolyat(mscale(V, geom3::HELLSPIKE), shGiantStar[ct6], darkena(wcol, 0, 0x40), PPR::HELLSPIKE); + queuepolyat(mscale(V, cgi.HELLSPIKE), cgi.shGiantStar[ct6], darkena(wcol, 0, 0x40), PPR::HELLSPIKE); else - queuepoly(V, shGiantStar[ct6], darkena(wcol, 0, 0xFF)); + queuepoly(V, cgi.shGiantStar[ct6], darkena(wcol, 0, 0xFF)); } break; } @@ -5839,13 +5837,13 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { if(wmescher && geosupport_football() == 2 && pseudohept(c) && c->land == laPalace) V2 = V * spin(M_PI / c->type); if(DIM == 3) { #if MAXMDIM >= 4 - draw_shapevec(c, V2 * zpush(-geom3::human_height/40), shMFloor.levels[0], darkena(winf[c->wall].color, 0, 0xFF)); - draw_shapevec(c, V2 * zpush(-geom3::human_height/35), shMFloor2.levels[0], (!wmblack) ? darkena(fcol, 1, 0xFF) : darkena(0,1,0xFF)); + draw_shapevec(c, V2 * zpush(-cgi.human_height/40), cgi.shMFloor.levels[0], darkena(winf[c->wall].color, 0, 0xFF)); + draw_shapevec(c, V2 * zpush(-cgi.human_height/35), cgi.shMFloor2.levels[0], (!wmblack) ? darkena(fcol, 1, 0xFF) : darkena(0,1,0xFF)); #endif } else { - draw_floorshape(c, V2, shMFloor, darkena(winf[c->wall].color, 0, 0xFF)); - draw_floorshape(c, V2, shMFloor2, (!wmblack) ? darkena(fcol, 1, 0xFF) : darkena(0,1,0xFF)); + draw_floorshape(c, V2, cgi.shMFloor, darkena(winf[c->wall].color, 0, 0xFF)); + draw_floorshape(c, V2, cgi.shMFloor2, (!wmblack) ? darkena(fcol, 1, 0xFF) : darkena(0,1,0xFF)); } break; } @@ -5868,10 +5866,10 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { wcol = 0xFF0000; else wcol = gradient(wcol, 0xC00000, 0, rosephase, 6); - queuepoly(V, shThorns, 0xC080C0FF); + queuepoly(V, cgi.shThorns, 0xC080C0FF); for(int u=0; u<4; u+=2) - queuepoly(V * spin(2*M_PI / 3 / 4 * u), shRose, darkena(wcol, 0, 0xC0)); + queuepoly(V * spin(2*M_PI / 3 / 4 * u), cgi.shRose, darkena(wcol, 0, 0xC0)); break; } @@ -5886,14 +5884,14 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { if(wmspatial) { color_t col = winf[waGlass].color; int dcol = darkena(col, 0, 0x80); - transmatrix Vdepth = mscale((*Vdp), geom3::WALL); + transmatrix Vdepth = mscale((*Vdp), cgi.WALL); if(DIM == 3) - draw_shapevec(c, V, shMFloor.levels[SIDE_WALL], dcol, PPR::WALL); + draw_shapevec(c, V, cgi.shMFloor.levels[SIDE_WALL], dcol, PPR::WALL); else - draw_floorshape(c, Vdepth, shMFloor, dcol, PPR::WALL); // GLASS + draw_floorshape(c, Vdepth, cgi.shMFloor, dcol, PPR::WALL); // GLASS dynamicval dq(qfi, qfi); - set_floor(shMFloor); - if(validsidepar[SIDE_WALL]) forCellIdEx(c2, i, c) + set_floor(cgi.shMFloor); + if(cgi.validsidepar[SIDE_WALL]) forCellIdEx(c2, i, c) if(placeSidewall(c, i, SIDE_WALL, (*Vdp), dcol)) break; } break; @@ -5902,15 +5900,15 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { #if MAXMDIM >= 4 if(DIM == 3) for(int a=0; a<10; a++) - queuepoly(V * zpush(geom3::FLOOR + (geom3::WALL - geom3::FLOOR) * a/10.) * spin(a *degree) * spintick(PURE ? -1000 : -500, 1/12.), shFan, darkena(wcol, 0, 0xFF)); + queuepoly(V * zpush(cgi.FLOOR + (cgi.WALL - cgi.FLOOR) * a/10.) * spin(a *degree) * spintick(PURE ? -1000 : -500, 1/12.), cgi.shFan, darkena(wcol, 0, 0xFF)); else #endif - queuepoly(V * spintick(PURE ? -1000 : -500, 1/12.), shFan, darkena(wcol, 0, 0xFF)); + queuepoly(V * spintick(PURE ? -1000 : -500, 1/12.), cgi.shFan, darkena(wcol, 0, 0xFF)); break; case waArrowTrap: if(c->wparam >= 1) - queuepoly(mscale(V, geom3::FLOOR), shDisk, darkena(trapcol[c->wparam&3], 0, 0xFF)); + queuepoly(mscale(V, cgi.FLOOR), cgi.shDisk, darkena(trapcol[c->wparam&3], 0, 0xFF)); if(isCentralTrap(c)) arrowtraps.push_back(c); break; @@ -5918,22 +5916,22 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { if(DIM == 3) { #if MAXMDIM >= 4 - draw_shapevec(c, V * zpush(-geom3::human_height/40), shMFloor.levels[0], darkena(0xC00000, 0, 0xFF)); - draw_shapevec(c, V * zpush(-geom3::human_height/20), shMFloor2.levels[0], darkena(0x600000, 0, 0xFF)); + draw_shapevec(c, V * zpush(-cgi.human_height/40), cgi.shMFloor.levels[0], darkena(0xC00000, 0, 0xFF)); + draw_shapevec(c, V * zpush(-cgi.human_height/20), cgi.shMFloor2.levels[0], darkena(0x600000, 0, 0xFF)); #endif } else { - draw_floorshape(c, V, shMFloor, darkena(0xC00000, 0, 0xFF)); - draw_floorshape(c, V, shMFloor2, darkena(0x600000, 0, 0xFF)); + draw_floorshape(c, V, cgi.shMFloor, darkena(0xC00000, 0, 0xFF)); + draw_floorshape(c, V, cgi.shMFloor2, darkena(0x600000, 0, 0xFF)); } if(c->wparam >= 1) - queuepoly(mscale(V, geom3::FLOOR), shDisk, darkena(trapcol[c->wparam&3], 0, 0xFF)); + queuepoly(mscale(V, cgi.FLOOR), cgi.shDisk, darkena(trapcol[c->wparam&3], 0, 0xFF)); break; case waGiantRug: - queuepoly(V, shBigCarpet1, darkena(DIM == 3 ? 0 : 0xC09F00, 0, 0xFF)); - queuepoly(V, shBigCarpet2, darkena(DIM == 3 ? 0xC09F00 : 0x600000, 0, 0xFF)); - queuepoly(V, shBigCarpet3, darkena(DIM == 3 ? 0x600000 : 0xC09F00, 0, 0xFF)); + queuepoly(V, cgi.shBigCarpet1, darkena(DIM == 3 ? 0 : 0xC09F00, 0, 0xFF)); + queuepoly(V, cgi.shBigCarpet2, darkena(DIM == 3 ? 0xC09F00 : 0x600000, 0, 0xFF)); + queuepoly(V, cgi.shBigCarpet3, darkena(DIM == 3 ? 0x600000 : 0xC09F00, 0, 0xFF)); break; case waBarrier: @@ -5945,7 +5943,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { break; } const int layers = 2 << detaillevel; - dynamicval ds(qfi.shape, &shCircleFloor); + dynamicval ds(qfi.shape, &cgi.shCircleFloor); dynamicval dss(qfi.spin, Id); for(int z=1; z= 10) - queuepoly(V, shBigMineMark[ct6], darkena(minecolors[(mines/10) % 10], 0, 0xFF)); + queuepoly(V, cgi.shBigMineMark[ct6], darkena(minecolors[(mines/10) % 10], 0, 0xFF)); if(mines) - queuepoly(V, shMineMark[ct6], darkena(minecolors[mines%10], 0, 0xFF)); + queuepoly(V, cgi.shMineMark[ct6], darkena(minecolors[mines%10], 0, 0xFF)); break; } case waEditStatue: if(!mapeditor::drawUserShape(V * ddspin(c, c->mondir), mapeditor::sgWall, c->wparam, darkena(wcol, fd, 0xFF), c)) - queuepoly(V, shTriangle, darkena(wcol, fd, 0xFF)); + queuepoly(V, cgi.shTriangle, darkena(wcol, fd, 0xFF)); break; default: { @@ -5997,18 +5995,18 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { if(wmspatial) { color_t col = winf[c->wall].color; int dcol = darkena(col, 0, 0xC0); - transmatrix Vdepth = mscale((*Vdp), geom3::WALL); + transmatrix Vdepth = mscale((*Vdp), cgi.WALL); if(DIM == 3) - draw_shapevec(c, V, shMFloor.levels[SIDE_WALL], dcol, PPR::WALL); + draw_shapevec(c, V, cgi.shMFloor.levels[SIDE_WALL], dcol, PPR::WALL); else - draw_floorshape(c, Vdepth, shMFloor, dcol, PPR::WALL); // GLASS + draw_floorshape(c, Vdepth, cgi.shMFloor, dcol, PPR::WALL); // GLASS dynamicval dq(qfi, qfi); - set_floor(shMFloor); - if(validsidepar[SIDE_WALL]) forCellIdEx(c2, i, c) + set_floor(cgi.shMFloor); + if(cgi.validsidepar[SIDE_WALL]) forCellIdEx(c2, i, c) if(placeSidewall(c, i, SIDE_WALL, (*Vdp), dcol)) break; } else { - queuepoly(V, shMirror, darkena(wcol, 0, 0xC0)); + queuepoly(V, cgi.shMirror, darkena(wcol, 0, 0xC0)); } poly_outline = OUTLINE_DEFAULT; } @@ -6023,7 +6021,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { const int layers = 2 << detaillevel; for(int z=1; z<=layers; z++) { double zg = zgrad0(0, geom3::actual_wall_height(), z, layers); - queuepolyat(xyzscale(V, zg, zg), shBarrel, darkena((z&1) ? 0xFF0000 : 0xC00000, 0, 0xFF), PPR(PPR::REDWALLm+z)); + queuepolyat(xyzscale(V, zg, zg), cgi.shBarrel, darkena((z&1) ? 0xFF0000 : 0xC00000, 0, 0xFF), PPR(PPR::REDWALLm+z)); } } @@ -6035,7 +6033,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { dynamicval p(poly_outline, OUTLINE_TRANS); draw_shapevec(c, V, qfi.fshape->shadow, SHADOW_WALL, PPR::WALLSHADOW); } - else queuepoly(V2, shStar, darkena(wcol, 0, 0xF0)); + else queuepoly(V2, cgi.shStar, darkena(wcol, 0, 0xF0)); if(isFire(c) && rand() % 300 < ticks - lastt) drawParticle(c, wcol, 75); } @@ -6095,7 +6093,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { bool dbot = true; forCellIdEx(c2, i, c) if(chasmgraph(c2) == 2) { if(dbot) dbot = false, - draw_qfi(c, mscale(V, geom3::BOTTOM), 0x080808FF, PPR::LAKEBOTTOM); + draw_qfi(c, mscale(V, cgi.BOTTOM), 0x080808FF, PPR::LAKEBOTTOM); if(placeSidewall(c, i, SIDE_BTOI, V, D(.6))) break; } #undef D @@ -6104,7 +6102,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { // wall between lake and chasm -- no Escher here if(chasmg == 1) forCellIdEx(c2, i, c) if(chasmgraph(c2) == 2) { dynamicval qfib(qfi, qfi); - set_floor(shFullFloor); + set_floor(cgi.shFullFloor); placeSidewall(c, i, SIDE_LAKE, V, 0x202030FF); placeSidewall(c, i, SIDE_LTOB, V, 0x181820FF); placeSidewall(c, i, SIDE_BTOI, V, 0x101010FF); @@ -6133,8 +6131,8 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { setcolors(c, wcol2, fcol2); int starcol = c->wall == waVinePlant ? 0x60C000 : wcol2; c->wall = w; c->wparam = p; - draw_qfi(c, mscale(V, geom3::WALL), darkena(starcol, fd, 0xFF), PPR::WALL3); - queuepolyat(mscale(V, geom3::WALL), shWall[ct6], darkena(wcol2, 0, 0xFF), PPR::WALL3A); + draw_qfi(c, mscale(V, cgi.WALL), darkena(starcol, fd, 0xFF), PPR::WALL3); + queuepolyat(mscale(V, cgi.WALL), cgi.shWall[ct6], darkena(wcol2, 0, 0xFF), PPR::WALL3A); forCellIdEx(c2, i, c) if(placeSidewall(c, i, SIDE_WALL, V, darkena(wcol2, 1, 0xFF))) break; } @@ -6187,7 +6185,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { #if CAP_SHAPES if(Vboat != &V && Vboat != &Vboat0 && q != isize(ptds)) { if(WDIM == 2 && GDIM == 3) - pushdown(c, q, V, geom3::SLEV[sl] - geom3::FLOOR, false, false); + pushdown(c, q, V, cgi.SLEV[sl] - cgi.FLOOR, false, false); else pushdown(c, q, V, -geom3::factor_to_lev(zlevel(tC0((*Vboat)))), !isMultitile(c->monst), false); } @@ -6196,7 +6194,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { #if CAP_SHAPES if(!shmup::on && sword::at(c)) { - queuepolyat(V, shDisk, 0xC0404040, PPR::SWORDMARK); + queuepolyat(V, cgi.shDisk, 0xC0404040, PPR::SWORDMARK); } #endif @@ -6223,7 +6221,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { ph0 -= floor(ph0/M_PI)*M_PI; poly_outline = OUTLINE_TRANS; - queuepoly((*Vdp)*V0*xpush(hexf*-cos(ph0)), shDisk, aircol); + queuepoly((*Vdp)*V0*xpush(cgi.hexf*-cos(ph0)), cgi.shDisk, aircol); poly_outline = OUTLINE_DEFAULT; } } @@ -6238,7 +6236,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { } else { forCellIdEx(c2, i, c) if(againstWind(c, c2)) - queuepoly(V * ddspin(c, i) * xpush(cellgfxdist(c, i)/2), shWindArrow, 0x8080FF80); + queuepoly(V * ddspin(c, i) * xpush(cellgfxdist(c, i)/2), cgi.shWindArrow, 0x8080FF80); } } #endif @@ -6268,10 +6266,10 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { double ldist = cellgfxdist(c, whirlwind::dfrom[i]) * (1-ph1)/2 + cellgfxdist(c, whirlwind::dto[i]) * ph1/2; - // PURE ? crossf : c->type == 6 ? .2840 : 0.3399; + // PURE ? cgi.crossf : c->type == 6 ? .2840 : 0.3399; poly_outline = OUTLINE_TRANS; - queuepoly((*Vdp)*V0*xpush(ldist*(2*ph1-1)), shDisk, aircol); + queuepoly((*Vdp)*V0*xpush(ldist*(2*ph1-1)), cgi.shDisk, aircol); poly_outline = OUTLINE_DEFAULT; } @@ -6362,8 +6360,8 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { if(vid.grid && c->bardir != NODIR && c->bardir != NOBARRIERS && c->land != laHauntedWall && c->barleft != NOWALLSEP_USED) { color_t col = darkena(0x505050, 0, 0xFF); - queueline(tC0(V), V*tC0(heptmove[c->bardir]), col, 2 + vid.linequality); - queueline(tC0(V), V*tC0(hexmove[c->bardir]), col, 2 + vid.linequality); + queueline(tC0(V), V*tC0(cgi.heptmove[c->bardir]), col, 2 + vid.linequality); + queueline(tC0(V), V*tC0(cgi.hexmove[c->bardir]), col, 2 + vid.linequality); } #if CAP_MODEL @@ -6435,7 +6433,7 @@ void queuecircleat(cell *c, double rad, color_t col) { if(WDIM == 3) { dynamicval p(poly_outline, col); for(int i=0; itype; i++) { - queuepolyat(gmatrix[c], shWireframe3D[i], 0, PPR::SUPERLINE); + queuepolyat(gmatrix[c], cgi.shWireframe3D[i], 0, PPR::SUPERLINE); } return; } @@ -6444,29 +6442,29 @@ void queuecircleat(cell *c, double rad, color_t col) { for(int i=0; itype; i++) corners[i] = gmatrix[c] * rgpushxto0(get_corner_position(c, i, 3 / rad)); corners[c->type] = corners[0]; for(int i=0; itype; i++) { - queueline(mscale(corners[i], geom3::FLOOR) * C0, mscale(corners[i+1], geom3::FLOOR) * C0, col, 2, PPR::SUPERLINE); - queueline(mscale(corners[i], geom3::WALL) * C0, mscale(corners[i+1], geom3::WALL) * C0, col, 2, PPR::SUPERLINE); - queueline(mscale(corners[i], geom3::FLOOR) * C0, mscale(corners[i], geom3::WALL) * C0, col, 2, PPR::SUPERLINE); + queueline(mscale(corners[i], cgi.FLOOR) * C0, mscale(corners[i+1], cgi.FLOOR) * C0, col, 2, PPR::SUPERLINE); + queueline(mscale(corners[i], cgi.WALL) * C0, mscale(corners[i+1], cgi.WALL) * C0, col, 2, PPR::SUPERLINE); + queueline(mscale(corners[i], cgi.FLOOR) * C0, mscale(corners[i], cgi.WALL) * C0, col, 2, PPR::SUPERLINE); } return; } #if CAP_SHAPES if(vid.stereo_mode || sphere) { dynamicval p(poly_outline, col); - queuepolyat(gmatrix[c] * spintick(100), shGem[1], 0, PPR::LINE); + queuepolyat(gmatrix[c] * spintick(100), cgi.shGem[1], 0, PPR::LINE); return; } #endif queuecircle(gmatrix[c], rad, col); if(!wmspatial) return; if(highwall(c)) - queuecircle(mscale(gmatrix[c], geom3::WALL), rad, col); + queuecircle(mscale(gmatrix[c], cgi.WALL), rad, col); int sl; if((sl = snakelevel(c))) { - queuecircle(mscale(gmatrix[c], geom3::SLEV[sl]), rad, col); + queuecircle(mscale(gmatrix[c], cgi.SLEV[sl]), rad, col); } if(chasmgraph(c)) - queuecircle(mscale(gmatrix[c], geom3::LAKE), rad, col); + queuecircle(mscale(gmatrix[c], cgi.LAKE), rad, col); } #endif @@ -6646,7 +6644,7 @@ void drawMarkers() { transmatrix T2 = ggmatrix(c2); transmatrix T = T1 * rspintox(inverse(T1)*T2*C0) * xpush(hdist(T1*C0, T2*C0) * fractick(50, 0)); color_t aircol = (orbToTarget == itOrbAir ? 0x8080FF40 : 0x8080FF20); - queuepoly(T, shDisk, aircol); + queuepoly(T, cgi.shDisk, aircol); c1 = c2; } } @@ -6676,11 +6674,11 @@ void drawFlashes() { kill = tim > 300; int partcol = darkena(f.color, 0, DIM == 3 ? 255 : max(255 - tim*255/300, 0)); poly_outline = OUTLINE_DEFAULT; - ld t = f.spd * tim * scalefactor / 50000.; + ld t = f.spd * tim * cgi.scalefactor / 50000.; transmatrix T = DIM == 2 ? V * spin(f.angle) * xpush(t) : V * cspin(0, 1, f.angle) * cspin(0, 2, f.angle2) * cpush(2, t); - queuepoly(T, shParticle[f.size], partcol); + queuepoly(T, cgi.shParticle[f.size], partcol); #endif } @@ -6690,14 +6688,14 @@ void drawFlashes() { if(u < tim-150) continue; ld rad = u * 3 / 1000.; rad = rad * (5-rad) / 2; - rad *= hexf; + rad *= cgi.hexf; int flashcol = f.color; if(u > 500) flashcol = gradient(flashcol, 0, 500, u, 1100); flashcol = darkena(flashcol, 0, 0xFF); if(DIM == 3) - queueball(V * zpush(geom3::GROIN1), rad, flashcol, itDiamond); + queueball(V * zpush(cgi.GROIN1), rad, flashcol, itDiamond); else { - PRING(a) curvepoint(V*xspinpush0(a * M_PI / S42, rad)); + PRING(a) curvepoint(V*xspinpush0(a * M_PI / cgi.S42, rad)); queuecurve(flashcol, 0x8080808, PPR::LINE); } } @@ -6708,14 +6706,14 @@ void drawFlashes() { if(u < tim-250) continue; ld rad = u * 3 / 2000.; rad = rad * (5-rad) * 1.25; - rad *= hexf; + rad *= cgi.hexf; int flashcol = f.color; if(u > 1000) flashcol = gradient(flashcol, 0, 1000, u, 2200); flashcol = darkena(flashcol, 0, 0xFF); if(DIM == 3) - queueball(V * zpush(geom3::GROIN1), rad, flashcol, itRuby); + queueball(V * zpush(cgi.GROIN1), rad, flashcol, itRuby); else { - PRING(a) curvepoint(V*xspinpush0(a * M_PI / S42, rad)); + PRING(a) curvepoint(V*xspinpush0(a * M_PI / cgi.S42, rad)); queuecurve(flashcol, 0x8080808, PPR::LINE); } } @@ -6766,7 +6764,7 @@ ld wall_radar(cell *c, transmatrix T, ld max) { T = T * cpush(2, -step); virtualRebase(c, T, false); color_t col; - if(isWall3(c, col) || (WDIM == 2 && GDIM == 3 && tC0(T)[2] > geom3::FLOOR)) { + if(isWall3(c, col) || (WDIM == 2 && GDIM == 3 && tC0(T)[2] > cgi.FLOOR)) { T = T * cpush(2, step); step /= 2; i = 17; if(step < 1e-3) break; @@ -7051,7 +7049,7 @@ void drawmovestar(double dx, double dy) { #if CAP_SHAPES else if(vid.axes == 3) - queuepoly(Centered, shMovestar, starcol); + queuepoly(Centered, cgi.shMovestar, starcol); #endif else for(int d=0; d<8; d++) { @@ -7146,7 +7144,7 @@ void drawfullmap() { if(conformal::on) { char ch = 'A'; for(auto& v: conformal::v) { - queuepoly(ggmatrix(v->base) * v->at, shTriangle, 0x306090C0); + queuepoly(ggmatrix(v->base) * v->at, cgi.shTriangle, 0x306090C0); queuechr(ggmatrix(v->base) * v->at * C0, 10, ch++, 0xFF0000); } } @@ -7219,6 +7217,8 @@ void gamescreen(int _darken) { if(conformal::includeHistory) conformal::restore(); anims::apply(); + check_cgi(); + cgi.require_shapes(); #if CAP_RUG if(rug::rugged) { rug::actDraw(); @@ -7434,19 +7434,6 @@ auto graphcm = addHook(clearmemory, 0, [] () { clearAnimations(); }); -void resetGeometry() { - DEBBI(DF_POLY | DF_GRAPH, ("resetGeometry")); - #if MAXMDIM >= 4 - if(DIM == 3 && !floor_textures) - make_floor_textures(); - #endif - precalc(); -#if CAP_FIELD - if(hyperbolic && &currfp != &fieldpattern::fp_invalid) currfp.analyze(); -#endif - buildpolys(); - } - //=== animation map animations[ANIMLAYERS]; @@ -7545,7 +7532,7 @@ void drawBug(const cellwalker& cw, color_t col) { initquickqueue(); transmatrix V = ggmatrix(cw.at); if(cw.spin) V = V * ddspin(cw.at, cw.spin, M_PI); - queuepoly(V, shBugBody, col); + queuepoly(V, cgi.shBugBody, col); quickqueue(); #endif } diff --git a/hud.cpp b/hud.cpp index 6c9e5892..f3cff53a 100644 --- a/hud.cpp +++ b/hud.cpp @@ -187,9 +187,9 @@ bool displayglyph(int cx, int cy, int buttonsize, char glyph, color_t color, int if(m == moKrakenT || m == moDragonTail) bsize /= 2; if(m == moSlime) bsize = (2*bsize+1)/3; transmatrix V = atscreenpos(cx+buttonsize/2, cy, bsize*zoom); - if(isWorm(m) && wormscale != 1) + if(isWorm(m) && cgi.wormscale != 1) for(int i=0; i> 2; drawMonsterType(m, NULL, V, mcol, glyphphase[id]/500.0); @@ -345,7 +345,7 @@ void drawMobileArrow(int i) { double dx = xmove + rad*(1+SKIPFAC-.2)/2 * cos(alpha); double dy = yb + rad*(1+SKIPFAC-.2)/2 * sin(alpha); - queuepolyat(atscreenpos(dx, dy, scale) * spin(-alpha), shArrow, col, PPR::MOBILE_ARROW); + queuepolyat(atscreenpos(dx, dy, scale) * spin(-alpha), cgi.shArrow, col, PPR::MOBILE_ARROW); } #endif @@ -403,11 +403,11 @@ void draw_radar(bool cornermode) { if(d3) displaychr(int(cx + rad * r.h[0]), int(cy - rad * r.h[2] * si + rad * r.h[1] * co), 0, 8, r.glyph, r.color); else if(sph) displaychr(int(cx + (rad-10) * r.h[0]), int(cy + (rad-10) * r.h[2] * si + (rad-10) * r.h[1] * co), 0, +r.h[1] * si > r.h[2] * co ? 8 : 16, r.glyph, r.color); else if(hyp) { - int siz = 1/(1+r.h[3]) * scalefactor * current_display->radius / (inHighQual ? 10 : 6); + int siz = 1/(1+r.h[3]) * cgi.scalefactor * current_display->radius / (inHighQual ? 10 : 6); displaychr(int(cx + rad * r.h[0]), int(cy + rad * r.h[1]), 0, siz, r.glyph, r.color); } else { - displaychr(int(cx + rad * r.h[0]), int(cy + rad * r.h[1]), 0, rad * scalefactor / (max_eu_dist + scalefactor/4) * 0.8, r.glyph, r.color); + displaychr(int(cx + rad * r.h[0]), int(cy + rad * r.h[1]), 0, rad * cgi.scalefactor / (max_eu_dist + cgi.scalefactor/4) * 0.8, r.glyph, r.color); } } diff --git a/hyper.h b/hyper.h index da97d0c6..e61b7b33 100644 --- a/hyper.h +++ b/hyper.h @@ -2019,8 +2019,6 @@ void checkStunKill(cell *dest); void clearMessages(); -void resetGeometry(); - namespace shot { #if CAP_SHOT extern int shotx, shoty, shotformat; @@ -3174,6 +3172,7 @@ namespace irr { extern int place_attempts; extern int rearrange_max_attempts; extern int rearrange_less; + extern int irrid; void link_to_base(heptagon *h, heptspin base); void link_start(heptagon *h); void link_next(heptagon *h, int d); @@ -3309,7 +3308,6 @@ transmatrix screenpos(ld x, ld y); extern ld backbrightness; void initcells(); -void precalc(); extern const hyperpoint C02, C03; #define C0 (DIM == 2 ? C02 : C03) @@ -3336,10 +3334,6 @@ extern bool fixseed; extern eLand firstland0; extern int startseed; - -extern transmatrix heptmove[MAX_EDGE], hexmove[MAX_EDGE]; -extern transmatrix invheptmove[MAX_EDGE], invhexmove[MAX_EDGE]; - // heptspin hsstep(const heptspin &hs, int spin); extern void fixmatrix(transmatrix&); @@ -3512,12 +3506,6 @@ dqi_line& queueline(const hyperpoint& H1, const hyperpoint& H2, color_t col, int dqi_action& queueaction(PPR prio, const reaction_t& action); void queuereset(eModel m, PPR prio); - -extern ld tessf, crossf, hexf, hcrossf, hexhexdist, hexvdist, hepvdist, rhexf; -extern ld sword_size; - -extern ld scalefactor, orbsize, floorrad0, floorrad1, zhexf; - unsigned char& part(color_t& col, int i); transmatrix applyPatterndir(cell *c, const patterns::patterninfo& si); @@ -3608,6 +3596,8 @@ struct renderbuffer { void clear(color_t col); }; +extern renderbuffer *floor_textures; + struct resetbuffer { GLint drawFboId, readFboId; SDL_Surface *sreset; @@ -3791,12 +3781,9 @@ namespace gp { void compute_geometry(); void extend_map(cell *c, int d); extern loc param; - extern int area; extern int pseudohept_val(cell *); extern int last_dir(cell *c); extern void configure(); - extern ld alpha; - extern transmatrix Tf[MAX_EDGE][32][32][6]; struct local_info { int last_dir; @@ -3831,8 +3818,6 @@ int gamerange(); int numplayers(); -extern int base_distlimit; - bool has_nice_dual(); extern hyperpoint mid(const hyperpoint &h1, const hyperpoint &h2); @@ -4055,16 +4040,6 @@ struct hpcshape { int shs, she; }; -extern hpcshape shFullCross[2]; - -void bshape(hpcshape& sh, PPR prio); -void hpcpush(hyperpoint h); -void finishshape(); -void extra_vertices(); -extern vector hpc; - -extern hpcshape *last; - extern vector shPlainWall3D, shWireframe3D, shWall3D, shMiniWall3D; #endif @@ -4262,20 +4237,16 @@ void set_blizzard_frame(cell *c, int frameid); struct floorshape { bool is_plain; int shapeid; + int id; int pstrength; // pattern strength in 3D int fstrength; // frame strength in 3D PPR prio; vector b, shadow, side[SIDEPARS], gpside[SIDEPARS][MAX_EDGE], levels[SIDEPARS], cone[2]; - basic_textureinfo tinf3; floorshape() { prio = PPR::FLOOR; pstrength = fstrength = 10; } }; -extern vector all_plain_floorshapes; -extern vector all_escher_floorshapes; - struct plain_floorshape : floorshape { ld rad0, rad1; - plain_floorshape() { is_plain = true; all_plain_floorshapes.push_back(this); } void configure(ld r0, ld r1) { rad0 = r0; rad1 = r1; } }; @@ -4283,18 +4254,311 @@ struct plain_floorshape : floorshape { struct escher_floorshape : floorshape { int shapeid0, shapeid1, noftype, shapeid2; ld scale; - escher_floorshape(int s0, int s1, int noft=0, int s2=0) : shapeid0(s0), shapeid1(s1), noftype(noft), shapeid2(s2) { - all_escher_floorshapes.push_back(this); scale = 1; is_plain = false; - } + }; +#endif + +struct usershapelayer { + vector list; + bool sym; + int rots; + color_t color; + hyperpoint shift, spin; + ld zlevel; + int texture_offset; + PPR prio; }; -extern plain_floorshape - shFloor, - shMFloor, shMFloor2, shMFloor3, shMFloor4, shFullFloor, - shBigTriangle, shTriheptaFloor, shBigHepta; +static const int USERLAYERS = 32; -extern escher_floorshape shDragonFloor, shPowerFloor, shRedRockFloor[3]; -#endif +struct usershape { usershapelayer d[USERLAYERS]; }; + +extern array, mapeditor::USERSHAPEGROUPS> usershapes; +void initShape(int sg, int id); + +extern int usershape_changes; + +struct geometry_information { + + /* basic geometry parameters */ + + // tessf: distance from heptagon center to another heptagon center + // hexf: distance from heptagon center to small heptagon vertex + // hcrossf: distance from heptagon center to big heptagon vertex + // crossf: distance from heptagon center to adjacent cell center (either hcrossf or tessf) + // hexhexdist: distance between adjacent hexagon vertices + // hexvdist: distance between hexagon vertex and hexagon center + // hepvdist: distance between heptagon vertex and hexagon center (either hcrossf or something else) + // rhexf: distance from heptagon center to heptagon vertex (either hexf or hcrossf) + ld tessf, crossf, hexf, hcrossf, hexhexdist, hexvdist, hepvdist, rhexf; + + transmatrix heptmove[MAX_EDGE], hexmove[MAX_EDGE]; + transmatrix invheptmove[MAX_EDGE], invhexmove[MAX_EDGE]; + + int base_distlimit; + + /* shape parameters */ + ld sword_size; + ld scalefactor, orbsize, floorrad0, floorrad1, zhexf; + ld corner_bonus; + ld hexshift; + ld asteroid_size[8]; + ld wormscale; + ld tentacle_length; + + /* 3D parameters */ + ld INFDEEP, BOTTOM, HELLSPIKE, LAKE, WALL, FLOOR, STUFF, + SLEV[4], FLATEYE, + LEG0, LEG1, LEG, LEG3, GROIN, GROIN1, GHOST, + BODY, BODY1, BODY2, BODY3, + NECK1, NECK, NECK3, HEAD, HEAD1, HEAD2, HEAD3, + ALEG0, ALEG, ABODY, AHEAD, BIRD, LOWSKY, SKY, HIGH, HIGH2; + ld human_height, slev; + +#if CAP_SHAPES +hpcshape + shSemiFloorSide[SIDEPARS], + shBFloor[2], + shWave[8][2], + shCircleFloor, + shBarrel, + shWall[2], shMineMark[2], shBigMineMark[2], shFan, + shZebra[5], + shSwitchDisk, + shTower[11], + shEmeraldFloor[6], + shSemiFeatherFloor[2], + shSemiFloor[2], shSemiBFloor[2], shSemiFloorShadow, + shMercuryBridge[2], + shTriheptaSpecial[14], + shCross, shGiantStar[2], shLake, shMirror, + shHalfFloor[6], shHalfMirror[3], + shGem[2], shStar, shDisk, shDiskT, shDiskS, shDiskM, shDiskSq, shRing, + shTinyBird, shTinyShark, + shEgg, + shSpikedRing, shTargetRing, shSawRing, shGearRing, shPeaceRing, shHeptaRing, + shSpearRing, shLoveRing, + shDaisy, shTriangle, shNecro, shStatue, shKey, shWindArrow, + shGun, + shFigurine, shTreat, + shElementalShard, + // shBranch, + shIBranch, shTentacle, shTentacleX, shILeaf[2], + shMovestar, + shWolf, shYeti, shDemon, shGDemon, shEagle, shGargoyleWings, shGargoyleBody, + shFoxTail1, shFoxTail2, + shDogBody, shDogHead, shDogFrontLeg, shDogRearLeg, shDogFrontPaw, shDogRearPaw, + shDogTorso, + shHawk, + shCatBody, shCatLegs, shCatHead, shFamiliarHead, shFamiliarEye, + shWolf1, shWolf2, shWolf3, + shRatEye1, shRatEye2, shRatEye3, + shDogStripes, + shPBody, shPSword, shPKnife, + shFerocityM, shFerocityF, + shHumanFoot, shHumanLeg, shHumanGroin, shHumanNeck, shSkeletalFoot, shYetiFoot, + shMagicSword, shMagicShovel, shSeaTentacle, shKrakenHead, shKrakenEye, shKrakenEye2, + shArrow, + shPHead, shPFace, shGolemhead, shHood, shArmor, + shAztecHead, shAztecCap, + shSabre, shTurban1, shTurban2, shVikingHelmet, shRaiderHelmet, shRaiderArmor, shRaiderBody, shRaiderShirt, + shWestHat1, shWestHat2, shGunInHand, + shKnightArmor, shKnightCloak, shWightCloak, + shGhost, shEyes, shSlime, shJelly, shJoint, shWormHead, shTentHead, shShark, shWormSegment, shSmallWormSegment, shWormTail, shSmallWormTail, + shSlimeEyes, shDragonEyes, shWormEyes, shGhostEyes, + shMiniGhost, shMiniEyes, + shHedgehogBlade, shHedgehogBladePlayer, + shWolfBody, shWolfHead, shWolfLegs, shWolfEyes, + shWolfFrontLeg, shWolfRearLeg, shWolfFrontPaw, shWolfRearPaw, + shFemaleBody, shFemaleHair, shFemaleDress, shWitchDress, + shWitchHair, shBeautyHair, shFlowerHair, shFlowerHand, shSuspenders, shTrophy, + shBugBody, shBugArmor, shBugLeg, shBugAntenna, + shPickAxe, shPike, shFlailBall, shFlailTrunk, shFlailChain, shHammerHead, + shBook, shBookCover, shGrail, + shBoatOuter, shBoatInner, shCompass1, shCompass2, shCompass3, + shKnife, shTongue, shFlailMissile, shTrapArrow, + shPirateHook, shPirateHood, shEyepatch, shPirateX, + // shScratch, + shHeptaMarker, shSnowball, shSun, shNightStar, + shSkeletonBody, shSkull, shSkullEyes, shFatBody, shWaterElemental, + shPalaceGate, shFishTail, + shMouse, shMouseLegs, shMouseEyes, + shPrincessDress, shPrinceDress, + shWizardCape1, shWizardCape2, + shBigCarpet1, shBigCarpet2, shBigCarpet3, + shGoatHead, shRose, shRoseItem, shThorns, + shRatHead, shRatTail, shRatEyes, shRatCape1, shRatCape2, + shWizardHat1, shWizardHat2, + shTortoise[13][6], + shDragonLegs, shDragonTail, shDragonHead, shDragonSegment, shDragonNostril, + shDragonWings, + shSolidBranch, shWeakBranch, shBead0, shBead1, + shBatWings, shBatBody, shBatMouth, shBatFang, shBatEye, + shParticle[16], shAsteroid[8], + shReptile[5][4], + shReptileBody, shReptileHead, shReptileFrontFoot, shReptileRearFoot, + shReptileFrontLeg, shReptileRearLeg, shReptileTail, shReptileEye, + + shTrylobite, shTrylobiteHead, shTrylobiteBody, + shTrylobiteFrontLeg, shTrylobiteRearLeg, shTrylobiteFrontClaw, shTrylobiteRearClaw, + + shBullBody, shBullHead, shBullHorn, shBullRearHoof, shBullFrontHoof, + + shButterflyBody, shButterflyWing, shGadflyBody, shGadflyWing, shGadflyEye, + + shTerraArmor1, shTerraArmor2, shTerraArmor3, shTerraHead, shTerraFace, + shJiangShi, shJiangShiDress, shJiangShiCap1, shJiangShiCap2, + + shAsymmetric, + + shPBodyOnly, shPBodyArm, shPBodyHand, shPHeadOnly, + + shAnimatedEagle[30], shAnimatedTinyEagle[30], shAnimatedGadfly[30], shAnimatedHawk[30], shAnimatedButterfly[30], + shAnimatedGargoyle[30], shAnimatedGargoyle2[30], shAnimatedBat[30], shAnimatedBat2[30], + + shDodeca; + + vector shPlainWall3D, shWireframe3D, shWall3D, shMiniWall3D; + + vector all_plain_floorshapes; + vector all_escher_floorshapes; + + plain_floorshape + shFloor, + shMFloor, shMFloor2, shMFloor3, shMFloor4, shFullFloor, + shBigTriangle, shTriheptaFloor, shBigHepta; + + escher_floorshape + shStarFloor, shCloudFloor, shCrossFloor, shChargedFloor, + shSStarFloor, shOverFloor, shTriFloor, shFeatherFloor, + shBarrowFloor, shNewFloor, shTrollFloor, shButterflyFloor, + shLavaFloor, shLavaSeabed, shSeabed, shCloudSeabed, + shCaveSeabed, shPalaceFloor, shDemonFloor, shCaveFloor, + shDesertFloor, shPowerFloor, shRoseFloor, shSwitchFloor, + shTurtleFloor, shRedRockFloor[3], shDragonFloor; + + ld dlow_table[SIDEPARS], dhi_table[SIDEPARS], dfloor_table[SIDEPARS]; + + int prehpc; + vector hpc; + bool first; + + bool validsidepar[SIDEPARS]; + + vector ourshape; +#endif + + hpcshape shFullCross[2]; + hpcshape *last; + + int SD3, SD6, SD7, S12, S14, S21, S28, S42, S36, S84; + + vector> symmetriesAt; + + #ifndef SCALETUNER + static constexpr + #endif + double bscale7 = 1, brot7 = 0, bscale6 = 1, brot6 = 0; + + vector allshapes; + + transmatrix shadowmulmatrix; + + map ushr; + + void prepare_basics(); + void prepare_compute3(); + void prepare_shapes(); + void prepare_usershapes(); + + void hpcpush(hyperpoint h); + void chasmifyPoly(double fac, double fac2, int k); + void shift(hpcshape& sh, double dx, double dy, double dz); + void initPolyForGL(); + void extra_vertices(); + transmatrix ddi(int a, ld x); + void drawTentacle(hpcshape &h, ld rad, ld var, ld divby); + hyperpoint hpxyzsc(double x, double y, double z); + hyperpoint turtlevertex(int u, double x, double y, double z); + + void bshape(hpcshape& sh, PPR prio); + void finishshape(); + void bshape(hpcshape& sh, PPR prio, double shzoom, int shapeid, double bonus = 0, flagtype flags = 0); + + void copyshape(hpcshape& sh, hpcshape& orig, PPR prio); + void zoomShape(hpcshape& old, hpcshape& newsh, double factor, PPR prio); + void pushShape(usershapelayer& ds); + void make_sidewalls(); + void procedural_shapes(); + void make_wall(int id, vector vertices, bool force_triangles = false); + void create_wall3d(); + void configure_floorshapes(); + + void init_floorshapes(); + void bshape2(hpcshape& sh, PPR prio, int shapeid, struct matrixlist& m); + void bshape_regular(floorshape &fsh, int id, int sides, int shift, ld size); + void generate_floorshapes_for(int id, cell *c, int siid, int sidir); + void generate_floorshapes(); + void make_floor_textures_here(); + + vector get_shape(hpcshape sh); + void add_cone(ld z0, const vector& vh, ld z1); + void add_prism_sync(ld z0, vector vh0, ld z1, vector vh1); + void add_prism(ld z0, vector vh0, ld z1, vector vh1); + void shift_last(ld z); + void shift_shape(hpcshape& sh, ld z); + void shift_shape_orthogonally(hpcshape& sh, ld z); + void add_texture(hpcshape& sh); + void make_ha_3d(hpcshape& sh, bool isarmor, ld scale); + void make_humanoid_3d(hpcshape& sh); + void addtri(array hs, int kind); + void make_armor_3d(hpcshape& sh, int kind = 1); + void make_foot_3d(hpcshape& sh); + void make_head_only(); + void make_head_3d(hpcshape& sh); + void make_paw_3d(hpcshape& sh, hpcshape& legsh); + void make_abody_3d(hpcshape& sh, ld tail); + void make_ahead_3d(hpcshape& sh); + void make_skeletal(hpcshape& sh, ld push = 0); + void make_revolution(hpcshape& sh, int mx = 180, ld push = 0); + void make_revolution_cut(hpcshape &sh, int each = 180, ld push = 0, ld width = 99); + void clone_shape(hpcshape& sh, hpcshape& target); + void animate_bird(hpcshape& orig, hpcshape animated[30], ld body); + void slimetriangle(hyperpoint a, hyperpoint b, hyperpoint c, ld rad, int lev); + void balltriangle(hyperpoint a, hyperpoint b, hyperpoint c, ld rad, int lev); + void make_ball(hpcshape& sh, ld rad, int lev); + void adjust_eye(hpcshape& eye, hpcshape head, ld shift_eye, ld shift_head, int q, ld zoom=1); + void shift_last_straight(ld z); + void queueball(const transmatrix& V, ld rad, color_t col, eItem what); + void make_shadow(hpcshape& sh); + void make_3d_models(); + + /* Goldberg parameters */ + #if CAP_GP + struct gpdata_t { + transmatrix Tf[MAX_EDGE][32][32][6]; + transmatrix corners; + ld alpha; + int area; + }; + shared_ptr gpdata; + #endif + + int state; + int usershape_state; + + geometry_information() { last = NULL; state = usershape_state = 0; gpdata = NULL; } + + void require_basics() { if(state & 1) return; state |= 1; prepare_basics(); } + void require_shapes() { if(state & 2) return; state |= 2; prepare_shapes(); } + void require_usershapes() { if(usershape_state == usershape_changes) return; usershape_state = usershape_state; prepare_usershapes(); } + }; + +void make_floor_textures(); + +extern map cgis; +extern geometry_information *cgip; +void check_cgi(); +#define cgi (*cgip) #if ISMOBILE bool buttonclicked; @@ -4335,7 +4599,6 @@ extern int timetowait; extern vector > airmap; extern void compute_graphical_distance(); -extern ld scalef; struct help_extension { char key; @@ -4354,7 +4617,6 @@ namespace gamestack { } namespace geom3 { - extern ld BODY; extern ld depth, camera, wall_height, creature_scale, height_width; void switch_always3(); void switch_fpp(); @@ -4368,23 +4630,14 @@ ld frac(ld x); extern color_t poly_outline; -#if CAP_SHAPES -extern hpcshape shDisk, shTriangle, shHeptaMarker, shSnowball, shDiskT, shDiskS, shDiskSq, shDiskM, shTinyBird, shTinyShark, shAsymmetric; -#endif - extern std::mt19937 hrngen; bool anglestraight(cell *c, int d1, int d2); hyperpoint randomPointIn(int t); -void buildpolys(); - bool compute_relamatrix(cell *src, cell *tgt, int direction_hint, transmatrix& T); -extern bool need_reset_geometry; -extern ld hexshift; - extern bool noshadow, bright, nohelp, dont_face_pc; extern void switchHardcore(); @@ -4403,10 +4656,10 @@ namespace ors { bool saved_tortoise_on(cell *c); -#define RING(i) for(double i=0; i<=S84+1e-6; i+=SD3 * pow(.5, vid.linequality)) -#define REVRING(i) for(double i=S84; i>=-1e-6; i-=SD3 * pow(.5, vid.linequality)) -#define PRING(i) for(double i=0; i<=S84+1e-6; i+= pow(.5, vid.linequality)) -#define REVPRING(i) for(double i=S84; i>=-1e-6; i-=pow(.5, vid.linequality)) +#define RING(i) for(double i=0; i<=cgi.S84+1e-6; i+=SD3 * pow(.5, vid.linequality)) +#define REVRING(i) for(double i=cgi.S84; i>=-1e-6; i-=SD3 * pow(.5, vid.linequality)) +#define PRING(i) for(double i=0; i<=cgi.S84+1e-6; i+= pow(.5, vid.linequality)) +#define REVPRING(i) for(double i=cgi.S84; i>=-1e-6; i-=pow(.5, vid.linequality)) #if CAP_BT namespace binary { @@ -4794,6 +5047,7 @@ extern void calcTidalPhase(); void curvepoint(const hyperpoint& H1); dqi_poly& queuecurve(color_t linecol, color_t fillcol, PPR prio); +void queueball(const transmatrix& V, ld rad, color_t col, eItem what); ld cos_auto(ld x); ld sin_auto(ld x); @@ -5028,8 +5282,6 @@ struct bandfixer { bandfixer(transmatrix& T) : bw(band_shift, band_shift) { fix_the_band(T); } }; -inline void delayed_geo_reset() { need_reset_geometry = true; } - extern unordered_map params; namespace dq { @@ -5129,5 +5381,31 @@ inline void reset_projection() { new_projection_needed = true; } extern ld ptick(int period, ld phase = 0); void gridline(const transmatrix& V1, const hyperpoint h1, const transmatrix& V2, const hyperpoint h2, color_t col, int prec); void gridline(const transmatrix& V, const hyperpoint h1, const hyperpoint h2, color_t col, int prec); + +static const int POLY_DRAWLINES = 1; // draw the lines +static const int POLY_DRAWAREA = 2; // draw the area +static const int POLY_INVERSE = 4; // draw the inverse -- useful in stereographic projection +static const int POLY_ISSIDE = 8; // never draw in inverse +static const int POLY_BEHIND = 16; // there are points behind the camera +static const int POLY_TOOLARGE = 32; // some coordinates are too large -- best not to draw to avoid glitches +static const int POLY_INFRONT = 64; // on the sphere (orthogonal projection), do not draw without any points in front +static const int POLY_HASWALLS = 128; // floor shapes which have their sidewalls +static const int POLY_PLAIN = 256; // plain floors +static const int POLY_FULL = 512; // full floors +static const int POLY_HASSHADOW = 1024; // floor shapes which have their shadows, or can use shFloorShadow +static const int POLY_GP = 2048; // Goldberg shapes +static const int POLY_VCONVEX = 4096; // Convex shape (vertex) +static const int POLY_CCONVEX = 8192; // Convex shape (central) +static const int POLY_CENTERIN = 16384; // new system of side checking +static const int POLY_FORCEWIDE = (1<<15); // force wide lines +static const int POLY_NOTINFRONT = (1<<16); // points not in front +static const int POLY_NIF_ERROR = (1<<17); // points moved to the outline cross the image, disable +static const int POLY_BADCENTERIN = (1<<18); // new system of side checking +static const int POLY_PRECISE_WIDE = (1<<19); // precise width calculation +static const int POLY_FORCE_INVERTED = (1<<20); // force inverted +static const int POLY_ALWAYS_IN = (1<<21); // always draw this +static const int POLY_TRIANGLES = (1<<22); // made of TRIANGLES, not TRIANGLE_FAN +static const int POLY_INTENSE = (1<<23); // extra intense colors + } diff --git a/hyperpoint.cpp b/hyperpoint.cpp index d7cd0377..abd2ba8d 100644 --- a/hyperpoint.cpp +++ b/hyperpoint.cpp @@ -777,4 +777,21 @@ hyperpoint orthogonal_of_C0(hyperpoint h0, hyperpoint h1, hyperpoint h2) { return normalize(h); } +hyperpoint zshift(hyperpoint x, ld z) { + if(DIM == 3 && WDIM == 2) return orthogonal_move(x, z); + else return mscale(x, z); + } + +hyperpoint hpxd(ld d, ld x, ld y, ld z) { + hyperpoint H = hpxyz(d*x, d*y, z); + H = mid(H, H); + return H; + } + +ld signum(ld x) { return x<0?-1:x>0?1:0; } + +bool asign(ld y1, ld y2) { return signum(y1) != signum(y2); } + +ld xcross(ld x1, ld y1, ld x2, ld y2) { return x1 + (x2 - x1) * y1 / (y1 - y2); } + } diff --git a/hypgraph.cpp b/hypgraph.cpp index 633c63ca..8f479b87 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -672,7 +672,7 @@ bool outofmap(hyperpoint h) { if(GDIM == 3) return false; else if(euclid) - return h[2] < .5; // false; // h[0] * h[0] + h[1] * h[1] > 15 * crossf; + return h[2] < .5; // false; // h[0] * h[0] + h[1] * h[1] > 15 * cgi.crossf; else if(sphere) return h[2] < .1 && h[2] > -.1 && h[1] > -.1 && h[1] < .1 && h[0] > -.1 && h[0] < .1; else @@ -755,10 +755,9 @@ bool confusingGeometry() { } ld master_to_c7_angle() { + ld alpha = 0; #if CAP_GP - auto alpha = gp::alpha; - #else - auto alpha = 0; + if(cgi.gpdata) alpha = cgi.gpdata->alpha; #endif return (!BITRUNCATED && !binarytiling && !archimedean) ? M_PI + alpha : 0; } @@ -825,11 +824,11 @@ bool in_smart_range(const transmatrix& T) { if(DIM == 3) { if(-h1[2] + 2 * dz < conformal::clip_min || -h1[2] - 2 * dz > conformal::clip_max) return false; sort(dh, dh+DIM); - ld scale = sqrt(dh[1] * dh[2]) * scalefactor * hcrossf7; + ld scale = sqrt(dh[1] * dh[2]) * cgi.scalefactor * hcrossf7; if(scale <= (WDIM == 2 ? vid.smart_range_detail : vid.smart_range_detail_3)) return false; } else { - ld scale = sqrt(dh[0] * dh[1]) * scalefactor * hcrossf7; + ld scale = sqrt(dh[0] * dh[1]) * cgi.scalefactor * hcrossf7; if(scale <= vid.smart_range_detail) return false; } @@ -852,7 +851,7 @@ void drawrec(cell *c, const transmatrix& V) { if(!c2) continue; if(c2->move(0) != c) continue; if(c2 == c2->master->c7) continue; - transmatrix V1 = V * ddspin(c, i) * xpush(crossf) * iddspin(c2, 0) * spin(M_PI); + transmatrix V1 = V * ddspin(c, i) * xpush(cgi.crossf) * iddspin(c2, 0) * spin(M_PI); drawrec(c2, V1); } } */ @@ -861,7 +860,7 @@ void drawrec(cell *c, const transmatrix& V) { bool drawrec(cell *c, const transmatrix& V, gp::loc at, int dir, int maindir) { bool res = false; - transmatrix V1 = V * Tf[draw_li.last_dir][at.first&31][at.second&31][fixg6(dir)]; + transmatrix V1 = V * cgi.gpdata->Tf[draw_li.last_dir][at.first&31][at.second&31][fixg6(dir)]; if(do_draw(c, V1)) { /* auto li = get_local_info(c); if(fix6(dir) != fix6(li.total_dir)) printf("totaldir %d/%d\n", dir, li.total_dir); @@ -985,7 +984,7 @@ void hrmap_standard::draw() { int ds = hs.at->c.fix(hs.spin + d); // createMov(c, ds); if(c->move(ds) && c->c.spin(ds) == 0) { - transmatrix V2 = V1 * hexmove[d]; + transmatrix V2 = V1 * cgi.hexmove[d]; if(do_draw(c->move(ds), V2)) draw = true, drawcell(c->move(ds), V2, 0, hs.mirrored ^ c->c.mirror(ds)); @@ -999,7 +998,7 @@ void hrmap_standard::draw() { hstate s2 = transition(s, d); if(s2 == hsError) continue; heptspin hs2 = hs + d + wstep; - transmatrix Vd = V * heptmove[d]; + transmatrix Vd = V * cgi.heptmove[d]; bandfixer bf(Vd); drawn_cells.emplace_back(hs2, s2, Vd, band_shift); } @@ -1013,22 +1012,22 @@ transmatrix eumove(ld x, ld y) { Mat[DIM][DIM] = 1; if(a4) { - Mat[0][DIM] += x * crossf; - Mat[1][DIM] += y * crossf; + Mat[0][DIM] += x * cgi.crossf; + Mat[1][DIM] += y * cgi.crossf; } else { - Mat[0][DIM] += (x + y * .5) * crossf; - // Mat[DIM][0] += (x + y * .5) * crossf; - Mat[1][DIM] += y * q3 /2 * crossf; - // Mat[DIM][1] += y * q3 /2 * crossf; + Mat[0][DIM] += (x + y * .5) * cgi.crossf; + // Mat[DIM][0] += (x + y * .5) * cgi.crossf; + Mat[1][DIM] += y * q3 /2 * cgi.crossf; + // Mat[DIM][1] += y * q3 /2 * cgi.crossf; } ld v = a4 ? 1 : q3; - while(Mat[0][DIM] <= -16384 * crossf) Mat[0][DIM] += 32768 * crossf; - while(Mat[0][DIM] >= 16384 * crossf) Mat[0][DIM] -= 32768 * crossf; - while(Mat[1][DIM] <= -16384 * v * crossf) Mat[1][DIM] += 32768 * v * crossf; - while(Mat[1][DIM] >= 16384 * v * crossf) Mat[1][DIM] -= 32768 * v * crossf; + while(Mat[0][DIM] <= -16384 * cgi.crossf) Mat[0][DIM] += 32768 * cgi.crossf; + while(Mat[0][DIM] >= 16384 * cgi.crossf) Mat[0][DIM] -= 32768 * cgi.crossf; + while(Mat[1][DIM] <= -16384 * v * cgi.crossf) Mat[1][DIM] += 32768 * v * cgi.crossf; + while(Mat[1][DIM] >= 16384 * v * cgi.crossf) Mat[1][DIM] -= 32768 * v * cgi.crossf; return Mat; } @@ -1118,7 +1117,7 @@ void centerpc(ld aspd) { transmatrix T = shmup::pc[id]->at; if(WDIM == 2 && !masterless) T = master_relative(shmup::pc[id]->base) * T; int sl = snakelevel(cwt.at); - if(sl) T = T * zpush(geom3::SLEV[sl] - geom3::FLOOR); + if(sl) T = T * zpush(cgi.SLEV[sl] - cgi.FLOOR); View = inverse(T); if(WDIM == 2) View = cspin(0, 1, M_PI) * cspin(2, 1, M_PI/2 + shmup::playerturny[id]) * spin(-M_PI/2) * View; return; @@ -1135,7 +1134,7 @@ void centerpc(ld aspd) { #if MAXMDIM >= 4 if(GDIM == 3 && WDIM == 2) { int sl = snakelevel(cwt.at); - if(sl) T = T * zpush(geom3::SLEV[sl] - geom3::FLOOR); + if(sl) T = T * zpush(cgi.SLEV[sl] - cgi.FLOOR); } #endif hyperpoint H = inverse(actual_view_transform) * tC0(T); @@ -1223,7 +1222,7 @@ void optimizeview() { for(int i=-1; ixcenter); V[1][3] += (y - current_display->ycenter); - V[0][0] = size * 2 * hcrossf / crossf; - V[1][1] = size * 2 * hcrossf / crossf; + V[0][0] = size * 2 * cgi.hcrossf / cgi.crossf; + V[1][1] = size * 2 * cgi.hcrossf / cgi.crossf; } else { V[0][2] += (x - current_display->xcenter); V[1][2] += (y - current_display->ycenter); - V[0][0] = size * 2 * hcrossf / crossf; - V[1][1] = size * 2 * hcrossf / crossf; + V[0][0] = size * 2 * cgi.hcrossf / cgi.crossf; + V[1][1] = size * 2 * cgi.hcrossf / cgi.crossf; V[2][2] = current_display->scrdist; } @@ -1718,7 +1717,7 @@ bool do_draw(cell *c, const transmatrix& T) { } else { ld dist = hdist0(tC0(T)); - if(dist > sightranges[geometry] + (vid.sloppy_3d ? 0 : corner_bonus)) return false; + if(dist > sightranges[geometry] + (vid.sloppy_3d ? 0 : cgi.corner_bonus)) return false; if(dist <= extra_generation_distance && !limited_generation(c)) return false; } return true; diff --git a/irregular.cpp b/irregular.cpp index 45048f08..555053f0 100644 --- a/irregular.cpp +++ b/irregular.cpp @@ -1,5 +1,7 @@ namespace hr { namespace irr { +int irrid; + #if CAP_IRR ld density = 2; ld quality = .2; @@ -487,12 +489,12 @@ bool step(int delta) { for(auto& s: cells) { int d = -1; - ld dist = hcrossf / 2; + ld dist = cgi.hcrossf / 2; ld dists[8]; for(int i=0; i dists[(d+S7-1) % S7]) d = (d + S7 - 1) % S7; @@ -512,13 +514,13 @@ bool step(int delta) { void compute_geometry() { if(IRREGULAR) { ld scale = sqrt(isize(cells_of_heptagon) * 1. / isize(cells)); - crossf *= scale; - hepvdist *= scale; - rhexf *= scale; - hexhexdist *= scale; - hexvdist *= scale; - base_distlimit = (base_distlimit + log(scale) / log(2.618)) / scale; - if(base_distlimit > 25) base_distlimit = 25; + cgi.crossf *= scale; + cgi.hepvdist *= scale; + cgi.rhexf *= scale; + cgi.hexhexdist *= scale; + cgi.hexvdist *= scale; + cgi.base_distlimit = (cgi.base_distlimit + log(scale) / log(2.618)) / scale; + if(cgi.base_distlimit > 25) cgi.base_distlimit = 25; } } @@ -806,7 +808,7 @@ void start_game_on_created_map() { stop_game(); geometry = orig_geometry; variation = eVariation::irregular; - need_reset_geometry = true; + irrid++; gridmaking = false; start_game(); } @@ -874,7 +876,6 @@ void cancel_map_creation() { gridmaking = false; stop_game(); geometry = orig_geometry; - need_reset_geometry = true; start_game(); } @@ -986,7 +987,6 @@ void visual_creator() { } variation = eVariation::pure; - need_reset_geometry = true; start_game(); if(base) delete base; base = currentmap; diff --git a/mapeditor.cpp b/mapeditor.cpp index 83e6c49c..2beb9527 100644 --- a/mapeditor.cpp +++ b/mapeditor.cpp @@ -322,7 +322,7 @@ namespace mapstream { #endif } - need_reset_geometry = true; + usershape_changes++; initcells(); if(shmup::on) shmup::init(); @@ -496,9 +496,9 @@ namespace mapstream { } cellbyid.clear(); - buildpolys(); + check_cgi(); + cgi.require_basics(); bfs(); - restartGraph(); return true; } @@ -1056,7 +1056,7 @@ namespace mapeditor { dsCur->list.clear(); dsCur->sym = d==2; for(int i=sh.s; i < sh.s + (sh.e-sh.s)/d; i++) - dsCur->list.push_back(hpc[i]); + dsCur->list.push_back(cgi.hpc[i]); } #endif @@ -1121,25 +1121,25 @@ namespace mapeditor { if(front_config == eFront::equidistants) for(int i=0; i<4; i+=2) { for(int u=2; u<=20; u++) { PRING(d) { - curvepoint(d2 * xspinpush(M_PI*d/S42, u/20.) * zpush(front_edit) * C0); + curvepoint(d2 * xspinpush(M_PI*d/cgi.S42, u/20.) * zpush(front_edit) * C0); } queuecurve(cols[i + (u%5 != 0)], 0, i < 2 ? PPR::LINE : PPR::SUPERLINE); } - for(int d=0; dtype) != 0)], 0, i < 2 ? PPR::LINE : PPR::SUPERLINE); + for(int d=0; dtype) != 0)], 0, i < 2 ? PPR::LINE : PPR::SUPERLINE); } } return; } - for(int d=0; dtype) == 0) ? gridcolor : lightgrid; - queueline(d2 * C0, d2 * xspinpush0(M_PI*d/S42, 1), col, 4 + vid.linequality); + for(int d=0; dtype) == 0) ? gridcolor : lightgrid; + queueline(d2 * C0, d2 * xspinpush0(M_PI*d/cgi.S42, 1), col, 4 + vid.linequality); } for(int u=2; u<=20; u++) { PRING(d) { - curvepoint(d2 * xspinpush0(M_PI*d/S42, u/20.)); + curvepoint(d2 * xspinpush0(M_PI*d/cgi.S42, u/20.)); } queuecurve((u%5==0) ? gridcolor : lightgrid, 0, PPR::LINE); } @@ -1174,8 +1174,8 @@ namespace mapeditor { ld compute_area(hpcshape& sh) { ld area = 0; for(int i=sh.s; id[dslayer].sh; + cgi.require_usershapes(); + auto& sh = cgi.ushr[&us->d[dslayer]]; if(sh.e >= sh.s + 3) displayButton(vid.xres-8, vid.yres-8-fs*8, XLAT("area: %1", area_in_pi ? fts(compute_area(sh) / M_PI, 4) + "Ï€" : fts(compute_area(sh), 4)), 'w', 16); } @@ -1393,8 +1394,6 @@ namespace mapeditor { #endif } - bool rebuildPolys = false; - #if CAP_POLY void loadShapes(int sg, int id) { delete usershapes[sg][id]; @@ -1437,7 +1436,7 @@ namespace mapeditor { dsCur->rots = 1; dsCur->zlevel = 0; - for(auto& v: symmetriesAt) + for(auto& v: cgi.symmetriesAt) if(v[0] == ptd.offset) { dsCur->rots = v[1]; dsCur->sym = v[2] == 2; @@ -1451,7 +1450,7 @@ namespace mapeditor { layer++; if(layer == USERLAYERS) break; } - rebuildPolys = true; + usershape_changes++; } void applyToShape(int sg, int id, int uni, hyperpoint mh) { @@ -1477,7 +1476,7 @@ namespace mapeditor { if(uni == 'n' || xnew) { dsCur->list.clear(); dsCur->list.push_back(mh); - rebuildPolys = true; + usershape_changes++; } if(uni == 'u') @@ -1491,7 +1490,7 @@ namespace mapeditor { if(uni == 'a') { dsCur->list.push_back(mh); uni = 0; - rebuildPolys = true; + usershape_changes++; } else if(uni == 'c' || uni == 'd' || uni == 'm') { hyperpoint best = mh; @@ -1521,7 +1520,7 @@ namespace mapeditor { if(oldlist[i] != best) dsCur->list.push_back(oldlist[i]); } - rebuildPolys = true; + usershape_changes++; uni = 0; } else if(uni == COLORKEY) dsCur->color = colortouse; @@ -1537,7 +1536,7 @@ namespace mapeditor { dsCur->list.insert(dsCur->list.begin()+ew.pointid+(ew.side?1:0), mh); if(ew.side) ew.pointid++; - rebuildPolys = true; + usershape_changes++; } if(uni == 'D') { @@ -1561,41 +1560,41 @@ namespace mapeditor { if(ew.side == 1 && ew.pointid >= i) ew.pointid--; if(ew.side == 0 && ew.pointid > i) ew.pointid--; } - rebuildPolys = true; + usershape_changes++; } if(uni == 'K') { if(vid.cs.charid >= 4) { - loadShape(sg, id, shCatBody, 2, 0); - loadShape(sg, id, shCatHead, 2, 1); + loadShape(sg, id, cgi.shCatBody, 2, 0); + loadShape(sg, id, cgi.shCatHead, 2, 1); } else { - if(!(vid.cs.charid&1)) loadShape(sg, id, shPBody, 2, 0); - else loadShape(sg, id, shFemaleBody, 2, 0); + if(!(vid.cs.charid&1)) loadShape(sg, id, cgi.shPBody, 2, 0); + else loadShape(sg, id, cgi.shFemaleBody, 2, 0); - loadShape(sg, id, shPSword, 1, 1); + loadShape(sg, id, cgi.shPSword, 1, 1); if(vid.cs.charid&1) - loadShape(sg, id, shFemaleDress, 2, 2); + loadShape(sg, id, cgi.shFemaleDress, 2, 2); /* if(vid.cs.charid&1) - loadShape(sg, id, shPrincessDress, 1, 3); + loadShape(sg, id, cgi.shPrincessDress, 1, 3); else - loadShape(sg, id, shPrinceDress, 2, 3); */ + loadShape(sg, id, cgi.shPrinceDress, 2, 3); */ - loadShape(sg, id, shRatCape2, 1, 3); + loadShape(sg, id, cgi.shRatCape2, 1, 3); if(vid.cs.charid&1) - loadShape(sg, id, shFemaleHair, 2, 4); + loadShape(sg, id, cgi.shFemaleHair, 2, 4); else - loadShape(sg, id, shPHead, 2, 4); + loadShape(sg, id, cgi.shPHead, 2, 4); - loadShape(sg, id, shPFace, 2, 5); + loadShape(sg, id, cgi.shPFace, 2, 5); } - // loadShape(sg, id, shWolf, 2, dslayer); + // loadShape(sg, id, cgi.shWolf, 2, dslayer); - rebuildPolys = true; + usershape_changes++; } if(uni == '+') dsCur->rots++; @@ -1603,20 +1602,20 @@ namespace mapeditor { if(uni >= '1' && uni <= '9') { dsCur->rots = uni - '0'; if(dsCur->rots == 9) dsCur->rots = 21; - rebuildPolys = true; + usershape_changes++; } if(uni == '0') { dsCur->sym = !dsCur->sym; - rebuildPolys = true; + usershape_changes++; } if(uni == 't') { dsCur->shift = mh; - rebuildPolys = true; + usershape_changes++; } if(uni == 'y') { dsCur->spin = mh; - rebuildPolys = true; + usershape_changes++; } if(uni == COLORKEY) dsCur->color = colortouse; @@ -1691,7 +1690,7 @@ namespace mapeditor { } addMessage(XLAT("Pictures loaded from %1", picfile)); - buildpolys(); + usershape_changes++; return true; } @@ -1945,9 +1944,6 @@ namespace mapeditor { } } } - - if(rebuildPolys) - add_user_shapes(), rebuildPolys = false; } #endif @@ -2053,10 +2049,11 @@ namespace mapeditor { usershape *us = usershapes[group][id]; if(us) { + cgi.require_usershapes(); for(int i=0; id[i]); - hpcshape& sh(ds.sh); + hpcshape& sh(cgi.ushr[&ds]); if(sh.s != sh.e) { auto& last = queuepolyat(mmscale(V, DIM == 3 ? 0 : geom3::lev_to_factor(ds.zlevel)), sh, ds.color ? ds.color : color, prio); diff --git a/netgen.cpp b/netgen.cpp index f302deaf..9497027b 100644 --- a/netgen.cpp +++ b/netgen.cpp @@ -79,7 +79,7 @@ namespace hr { namespace netgen { int hdir = displayspin(c, i) + M_PI / S7; - transmatrix V2 = V * spin(hdir) * xpush(hexf); + transmatrix V2 = V * spin(hdir) * xpush(cgi.hexf); hcenter[ii][i] = V2 * C0; } @@ -91,7 +91,7 @@ namespace hr { namespace netgen { int hdir = displayspin(c, i); transmatrix V2 = - V * spin(hdir) * xpush(crossf) * spin(M_PI+M_PI/S7) * xpush(hexf); + V * spin(hdir) * xpush(cgi.crossf) * spin(M_PI+M_PI/S7) * xpush(cgi.hexf); hcenter[ii][i] = V2 * C0; } diff --git a/pattern2.cpp b/pattern2.cpp index 75300834..4d8de8db 100644 --- a/pattern2.cpp +++ b/pattern2.cpp @@ -491,7 +491,7 @@ int getHemisphere(cell *c, int which) { else if(GOLDBERG) { auto li = gp::get_local_info(c); gp::be_in_triangle(li); - auto corner = gp::corners * gp::loctoh_ort(li.relative); + auto corner = cgi.gpdata->corners * gp::loctoh_ort(li.relative); ld scored = corner[0] * getHemisphere(c->master->c7, which) + corner[1] * getHemisphere(c->master->move(li.last_dir)->c7, which) @@ -2223,7 +2223,7 @@ namespace linepatterns { if(fv2/4 == 4 || fv2/4 == 6 || fv2/4 == 5 || fv2/4 == 10) fv2 ^= 2; if((fv1&1) == (fv2&1)) continue; - double x = hexhexdist / 2; // sphere?.3651:euclid?.2611:.2849; + double x = cgi.hexhexdist / 2; // sphere?.3651:euclid?.2611:.2849; gridlinef(V, ddspin(c,i,-M_PI/S3) * xpush0(x), ddspin(c,i,M_PI/S3) * xpush0(x), @@ -2291,8 +2291,8 @@ namespace linepatterns { cell *c1 = createMov(c, (i+3) % 7); cell *c2 = createMov(c, (i+4) % 7); if(polarb50(c1) != a && polarb50(c2) != a) - gridlinef(V, ddspin(c,i,M_PI*5/7) * xpush0(tessf/2), - ddspin(c,i,M_PI*9/7) * xpush0(tessf/2), + gridlinef(V, ddspin(c,i,M_PI*5/7) * xpush0(cgi.tessf/2), + ddspin(c,i,M_PI*9/7) * xpush0(cgi.tessf/2), col, 1 + vid.linequality); } break; @@ -2300,15 +2300,15 @@ namespace linepatterns { case patPalacelike: if(pseudohept(c)) for(int i=0; i<7; i++) - gridlinef(V, ddspin(c,i,M_PI*5/7) * xpush0(tessf/2), - ddspin(c,i,M_PI*9/7) * xpush0(tessf/2), + gridlinef(V, ddspin(c,i,M_PI*5/7) * xpush0(cgi.tessf/2), + ddspin(c,i,M_PI*9/7) * xpush0(cgi.tessf/2), col, 1 + vid.linequality); break; case patBigTriangles: { if(is_master(c) && !euclid) for(int i=0; imaster->move(i) && c->master->move(i) < c->master) { - gridlinef(V, C0, xspinpush0(-2*M_PI*i/S7 - master_to_c7_angle(), tessf), col, 2 + vid.linequality); + gridlinef(V, C0, xspinpush0(-2*M_PI*i/S7 - master_to_c7_angle(), cgi.tessf), col, 2 + vid.linequality); } break; } @@ -2316,7 +2316,7 @@ namespace linepatterns { case patBigRings: { if(is_master(c) && !euclid) for(int i=0; imaster->move(i) && c->master->move(i) < c->master && c->master->move(i)->dm4 == c->master->dm4) - gridlinef(V, C0, xspinpush0(-2*M_PI*i/S7 - master_to_c7_angle(), tessf), col, 2 + vid.linequality); + gridlinef(V, C0, xspinpush0(-2*M_PI*i/S7 - master_to_c7_angle(), cgi.tessf), col, 2 + vid.linequality); break; } @@ -2362,10 +2362,10 @@ namespace linepatterns { } else { int p = emeraldval(c); - double hdist = hdist0(heptmove[0] * heptmove[2] * C0); + double hdist = hdist0(cgi.heptmove[0] * cgi.heptmove[2] * C0); if(pseudohept(c) && (p/4 == 10 || p/4 == 8)) for(int i=0; imove(i) && emeraldval(c->move(i)) == p-4) { - gridlinef(V, C0, tC0(heptmove[i]), col, 2 + vid.linequality); + gridlinef(V, C0, tC0(cgi.heptmove[i]), col, 2 + vid.linequality); gridlinef(V, C0, xspinpush0(-i * ALPHA, -hdist/2), col, 2 + vid.linequality); } } @@ -2392,8 +2392,8 @@ namespace linepatterns { heptagon *h2 = c->master->modmove(i-1); if(!h1 || !h2) continue; if(emeraldval(h1->c7)/4 == 8 && emeraldval(h2->c7)/4 == 8) - gridlinef(V, ddspin(c,i,M_PI*5/7) * xpush0(tessf/2), - ddspin(c,i,M_PI*9/7) * xpush0(tessf/2), + gridlinef(V, ddspin(c,i,M_PI*5/7) * xpush0(cgi.tessf/2), + ddspin(c,i,M_PI*9/7) * xpush0(cgi.tessf/2), col, 1 + vid.linequality); } } diff --git a/polygons.cpp b/polygons.cpp index f3ad89da..61bd3eda 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -1,122 +1,18 @@ // HyperRogue, shapes used for the vector graphics -// also the implementation of the rendering queue and svg renderer -// Copyright (C) 2011-2018 Zeno Rogue, see 'hyper.cpp' for details +// Copyright (C) 2011-2019 Zeno Rogue, see 'hyper.cpp' for details + +#if CAP_SHAPES namespace hr { -unsigned char& part(color_t& col, int i) { - unsigned char* c = (unsigned char*) &col; -#if ISMOBILE - return c[i]; -#else -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - return c[sizeof(col) - 1 - i]; -#else - return c[i]; -#endif -#endif - } - -ld signum(ld x) { return x<0?-1:x>0?1:0; } - -bool asign(ld y1, ld y2) { - return signum(y1) != signum(y2); - } - -ld xcross(ld x1, ld y1, ld x2, ld y2) { - return x1 + (x2 - x1) * y1 / (y1 - y2); - } - -// draw the lines -static const int POLY_DRAWLINES = 1; -// draw the area -static const int POLY_DRAWAREA = 2; -// draw the inverse -- useful in stereographic projection -static const int POLY_INVERSE = 4; -// never draw in inverse -static const int POLY_ISSIDE = 8; - -// there are points behind the camera -static const int POLY_BEHIND = 16; -// some coordinates are too large -- best not to draw to avoid glitches -static const int POLY_TOOLARGE = 32; -// on the sphere (orthogonal projection), do not draw without any points in front -static const int POLY_INFRONT = 64; - -// floor shapes which have their sidewalls -static const int POLY_HASWALLS = 128; -// plain floors -static const int POLY_PLAIN = 256; -// full floors -static const int POLY_FULL = 512; -// floor shapes which have their shadows, or can use shFloorShadow -static const int POLY_HASSHADOW = 1024; -// Goldberg shapes -static const int POLY_GP = 2048; - -// Convex shape (vertex) -static const int POLY_VCONVEX = 4096; -// Convex shape (central) -static const int POLY_CCONVEX = 8192; - -// new system of side checking -static const int POLY_CENTERIN = 16384; - -// force wide lines -static const int POLY_FORCEWIDE = (1<<15); - -// points not in front -static const int POLY_NOTINFRONT = (1<<16); - -// points moved to the outline cross the image, disable -static const int POLY_NIF_ERROR = (1<<17); - -// new system of side checking -static const int POLY_BADCENTERIN = (1<<18); - -// precise width calculation -static const int POLY_PRECISE_WIDE = (1<<19); - -// force inverted -static const int POLY_FORCE_INVERTED = (1<<20); - -// always draw this -static const int POLY_ALWAYS_IN = (1<<21); - -// made of TRIANGLES, not TRIANGLE_FAN -static const int POLY_TRIANGLES = (1<<22); - -// extra intense colors -static const int POLY_INTENSE = (1<<23); - -vector hpc; -basic_textureinfo user_triangles_texture; - -int prehpc; - -bool first; - -bool fatborder; - -color_t poly_outline; - -// #define STLSORT - -#define NEWSHAPE (-13.5) -#define WOLF (-15.5) +static constexpr ld NEWSHAPE = (-13.5); +static constexpr ld WOLF = (-15.5); extern long double polydata[]; -#if CAP_SHAPES -hpcshape *last = NULL; -#endif - -vector> ptds; - -#if CAP_SHAPES -void hpcpush(hyperpoint h) { +void geometry_information::hpcpush(hyperpoint h) { if(sphere) h = mid(h,h); ld threshold = (DIM == 3 || last->flags & POLY_TRIANGLES) ? 100 : (sphere ? (ISMOBWEB || NONSTDVAR ? .04 : .001) : 0.1) * pow(.25, vid.linequality); if(/*vid.usingGL && */!first) { @@ -132,15 +28,7 @@ void hpcpush(hyperpoint h) { hpc.push_back(h); } -bool validsidepar[SIDEPARS]; - -hyperpoint zshift(hyperpoint x, ld z) { - if(DIM == 3 && WDIM == 2) - return rgpushxto0(x) * cpush(2, z) * C0; - else return mscale(x, z); - } - -void chasmifyPoly(double fac, double fac2, int k) { +void geometry_information::chasmifyPoly(double fac, double fac2, int k) { if(GDIM == 2) { for(int i=isize(hpc)-1; i >= last->s; i--) { hpc.push_back(mscale(hpc[i], fac)); @@ -167,111 +55,28 @@ void chasmifyPoly(double fac, double fac2, int k) { texture_order([&] (ld x, ld y) { at((1-x+y)/2, (1-x-y)/2); }); texture_order([&] (ld x, ld y) { at((1-x-y)/2, (1+x-y)/2); }); texture_order([&] (ld x, ld y) { at((1+x-y)/2, (1+x+y)/2); }); - texture_order([&] (ld x, ld y) { at((1+x+y)/2, (1-x+y)/2); }); + texture_order([&] (ld x, ld y) { at((1+x+y)/2, (1-x+y)/2); }); } } -#endif -#if CAP_GL -color_t text_color; -int text_shift; -GLuint text_texture; -int texts_merged; -int shapes_merged; - -vector text_vertices; - -#if MINIMIZE_GL_CALLS -color_t triangle_color, line_color; -vector triangle_vertices; -vector line_vertices; -void glapplymatrix(const transmatrix& V); -#endif - -void glflush() { - #if MINIMIZE_GL_CALLS - if(isize(triangle_vertices)) { - // printf("%08X %08X | %d shapes, %d/%d vertices\n", triangle_color, line_color, shapes_merged, isize(triangle_vertices), isize(line_vertices)); - if(triangle_color) { - glhr::be_nontextured(); - glapplymatrix(Id); - glhr::current_vertices = NULL; - glhr::vertices(triangle_vertices); - glhr::color2(triangle_color); - glDrawArrays(GL_TRIANGLES, 0, isize(triangle_vertices)); - } - triangle_vertices.clear(); - } - if(isize(line_vertices)) { - if(line_color) { - glhr::be_nontextured(); - glapplymatrix(Id); - glhr::current_vertices = NULL; - glhr::vertices(line_vertices); - glhr::color2(line_color); - glDrawArrays(GL_LINES, 0, isize(line_vertices)); - } - line_vertices.clear(); - } - shapes_merged = 0; - #endif - - if(isize(text_vertices)) { - // printf("%08X | %d texts, %d vertices\n", text_color, texts_merged, isize(text_vertices)); - glhr::be_textured(); - dynamicval pm(pmodel, mdUnchanged); - if(!svg::in) current_display->set_all(0); - glBindTexture(GL_TEXTURE_2D, text_texture); - glhr::color2(text_color); - glhr::set_depthtest(false); - for(int ed = (current_display->stereo_active() && text_shift)?-1:0; ed<2; ed+=2) { - glhr::set_modelview(glhr::translate(-ed*text_shift-current_display->xcenter,-current_display->ycenter, current_display->scrdist)); - current_display->set_mask(ed); - - glhr::current_vertices = NULL; - glhr::prepare(text_vertices); - glDrawArrays(GL_TRIANGLES, 0, isize(text_vertices)); - - GLERR("print"); - } - - if(current_display->stereo_active() && text_shift && !svg::in) current_display->set_mask(0); - - texts_merged = 0; - text_vertices.clear(); - } - } -#endif - -#if CAP_SHAPES -void shift(hpcshape& sh, double dx, double dy, double dz) { +void geometry_information::shift(hpcshape& sh, double dx, double dy, double dz) { hyperpoint H = hpxyz(dx, dy, dz); transmatrix m = rgpushxto0(H); - for(int i=sh.s; i glcoords, ourshape; - -void initPolyForGL() { +void geometry_information::initPolyForGL() { ourshape.clear(); - + for(auto& h: hpc) ourshape.push_back(glhr::pointtogl(h)); - + glhr::store_in_buffer(ourshape); } -void extra_vertices() { +void geometry_information::extra_vertices() { while(isize(ourshape) < isize(hpc)) ourshape.push_back(glhr::pointtogl(hpc[isize(ourshape)])); glhr::store_in_buffer(ourshape); @@ -279,1515 +84,9 @@ void extra_vertices() { prehpc = isize(hpc); } -#endif +transmatrix geometry_information::ddi(int a, ld x) { return xspinpush(a * M_PI / S42, x); } -int spherespecial, spherephase; - -#if CAP_POLY -int polyi; - -int polyx[POLYMAX], polyxr[POLYMAX], polyy[POLYMAX]; - -int poly_flags; - -void add1(const hyperpoint& H) { - glcoords.push_back(glhr::pointtogl(H)); - } - -bool is_behind(const hyperpoint& H) { - return pmodel == mdDisk && (hyperbolic ? H[2] >= 0 : true) && vid.alpha + H[2] <= BEHIND_LIMIT; - } - -hyperpoint be_just_on_view(const hyperpoint& H1, const hyperpoint &H2) { - using namespace hyperpoint_vec; - // H1[2] * t + H2[2] * (1-t) == BEHIND_LIMIT - vid.alpha - // H2[2]- BEHIND_LIMIT + vid.alpha = t * (H2[2] - H1[2]) - ld t = (H2[2] - BEHIND_LIMIT + vid.alpha) / (H2[2] - H1[2]); - return H1 * t + H2 * (1-t); - } - -bool last_infront; - -bool nif_error_in(ld x1, ld y1, ld x2, ld y2) { - return pow(x1 * x2 + y2 * y2, 2) < (x1*x1+y1*y1)*(x2*x2+y2*y2)*.5; - } - -bool knowgood; -hyperpoint goodpoint; -vector> tofix; - -bool two_sided_model() { - if(DIM == 3) return false; - if(pmodel == mdHyperboloid) return !euclid; - // if(pmodel == mdHemisphere) return true; - if(pmodel == mdDisk) return sphere; - if(pmodel == mdHemisphere) return true; - if(pmodel == mdRotatedHyperboles) return true; - if(pmodel == mdSpiral && conformal::spiral_cone < 360) return true; - return false; - } - -int get_side(const hyperpoint& H) { - if(pmodel == mdDisk && sphere) { - double curnorm = H[0]*H[0]+H[1]*H[1]+H[2]*H[2]; - double horizon = curnorm / vid.alpha; - return (H[2] <= -horizon) ? -1 : 1; - } - if(pmodel == mdRotatedHyperboles) - return H[1] > 0 ? -1 : 1; - if(pmodel == mdHyperboloid && hyperbolic) - return (conformal::sin_ball * H[2] > -conformal::cos_ball * H[1]) ? -1 : 1; - if(pmodel == mdHyperboloid && sphere) - return (conformal::sin_ball * H[2] > conformal::cos_ball * H[1]) ? -1 : 1; - if(pmodel == mdHemisphere) { - hyperpoint res; - applymodel(H, res); - return res[2] < 0 ? -1 : 1; - } - if(pmodel == mdSpiral && conformal::spiral_cone < 360) { - return cone_side(H); - } - return 0; - } - -bool correct_side(const hyperpoint& H) { - return get_side(H) == spherespecial; - } - -hyperpoint Hlast; - -void fixpoint(glvertex& hscr, hyperpoint H) { - hyperpoint bad = H, good = goodpoint; - - for(int i=0; i<10; i++) { - hyperpoint mid = midz(bad, good); - if(correct_side(mid)) - good = mid; - else - bad = mid; - } - hyperpoint Hscr; - applymodel(good, Hscr); - hscr = glhr::makevertex(Hscr[0]*current_display->radius, Hscr[1]*current_display->radius*vid.stretch, Hscr[2]*current_display->radius); - } - -void addpoint(const hyperpoint& H) { - if(true) { - ld z = current_display->radius; - // if(vid.alpha + H[2] <= BEHIND_LIMIT && pmodel == mdDisk) poly_flags |= POLY_BEHIND; - - if(spherespecial) { - - if(correct_side(H)) { - poly_flags |= POLY_INFRONT, last_infront = false; - if(!knowgood || (spherespecial > 0 ? H[2]>goodpoint[2] : H[2]stereo_active()) glcoords[i][2] = 0; - - polyx[i] = current_display->xcenter + glcoords[i][0] - glcoords[i][2]; - polyxr[i] = current_display->xcenter + glcoords[i][0] + glcoords[i][2]; - polyy[i] = current_display->ycenter + glcoords[i][1]; - } - } - -void addpoly(const transmatrix& V, const vector &tab, int ofs, int cnt) { - if(pmodel == mdFlatten) { - for(int i=ofs; i(Hscr[0]*current_display->radius+10, Hscr[1]*current_display->radius*vid.stretch, Hscr[2]*vid.radius)); - glcoords.push_back(make_array(Hscr[0]*current_display->radius, Hscr[1]*current_display->radius*vid.stretch+10, Hscr[2]*vid.radius)); - glcoords.push_back(make_array(Hscr[0]*current_display->radius-10, Hscr[1]*current_display->radius*vid.stretch, Hscr[2]*vid.radius)); - glcoords.push_back(make_array(Hscr[0]*current_display->radius, Hscr[1]*current_display->radius*vid.stretch-10, Hscr[2]*vid.radius)); - glcoords.push_back(make_array(Hscr[0]*current_display->radius+10, Hscr[1]*current_display->radius*vid.stretch, Hscr[2]*vid.radius)); */ - } - } - -#if CAP_SDLGFX -void aapolylineColor(SDL_Surface *s, int*x, int *y, int polyi, color_t col) { - for(int i=1; i spx(px, px + polyi); - std::vector spy(py, py + polyi); - filledPolygonColor(s, spx.data(), spy.data(), polyi, col); - } -#endif - -#if CAP_TEXTURE -void drawTexturedTriangle(SDL_Surface *s, int *px, int *py, glvertex *tv, color_t col) { - transmatrix source = {{{ld(px[0]),ld(px[1]),ld(px[2])}, {ld(py[0]),ld(py[1]),ld(py[2])}, {1,1,1}}}; - transmatrix target = {{{tv[0][0],tv[1][0],tv[2][0]}, {tv[0][1],tv[1][1],tv[2][1]}, {1,1,1}}}; - transmatrix isource = inverse(source); - int minx = px[0], maxx = px[0]; - int miny = py[0], maxy = py[0]; - for(int i=1; i<3; i++) - minx = min(minx, px[i]), maxx = max(maxx, px[i]), - miny = min(miny, py[i]), maxy = max(maxy, py[i]); - for(int mx=minx; mx= -1e-7 && h[1] >= -1e-7 && h[2] >= -1e-7) { - hyperpoint ht = target * h; - int tw = texture::config.data.twidth; - int x = int(ht[0] * tw) & (tw-1); - int y = int(ht[1] * tw) & (tw-1); - color_t c = texture::config.data.texture_pixels[y * tw + x]; - auto& pix = qpixel(s, mx, my); - for(int p=0; p<3; p++) { - int alpha = part(c, 3) * part(col, 0); - auto& v = part(pix, p); - v = ((255*255 - alpha) * 255 * v + alpha * part(col, p+1) * part(c, p) + 255 * 255 * 255/2 + 1) / (255 * 255 * 255); - } - } - } - } -#endif - -#if CAP_GL - -void glapplymatrix(const transmatrix& V) { - GLfloat mat[16]; - int id = 0; - if(pmodel == mdPerspective && DIM == 3) { - if(spherephase & 4) { - for(int y=0; y<4; y++) { - for(int x=0; x<4; x++) mat[id++] = -V[x][y]; - } - } - else { - for(int y=0; y<4; y++) { - for(int x=0; x<4; x++) mat[id++] = V[x][y]; - } - } - glhr::set_modelview(glhr::as_glmatrix(mat)); - return; - } - - if(DIM == 3) { - for(int y=0; y<4; y++) - for(int x=0; x<4; x++) mat[id++] = V[x][y]; - } - else { - for(int y=0; y<3; y++) { - for(int x=0; x<3; x++) mat[id++] = V[x][y]; - mat[id++] = 0; - } - mat[12] = 0; - mat[13] = 0; - if(glhr::current_shader_projection != glhr::shader_projection::band) - mat[14] = GLfloat(vid.alpha); - else - mat[14] = 0; - mat[15] = 1; - } - - if(vid.stretch != 1) mat[1] *= vid.stretch, mat[5] *= vid.stretch, mat[9] *= vid.stretch, mat[13] *= vid.stretch; - - if(conformal::model_has_orientation()) { - if(DIM == 3) for(int a=0; a<4; a++) - conformal::apply_orientation_yz(mat[a*4+1], mat[a*4+2]); - for(int a=0; a<4; a++) - conformal::apply_orientation(mat[a*4], mat[a*4+1]); - } - - glhr::set_modelview(glhr::as_glmatrix(mat)); - } - -int global_projection; - -#if MAXMDIM >= 4 -extern renderbuffer *floor_textures; -#endif - -void dqi_poly::gldraw() { - auto& v = *tab; - int ioffset = offset; - -#if MINIMIZE_GL_CALLS - if(current_display->stereo_active() == 0 && !tinf && (color == 0 || ((flags & (POLY_VCONVEX | POLY_CCONVEX)) && !(flags & (POLY_INVERSE | POLY_FORCE_INVERTED))))) { - if(color != triangle_color || outline != line_color || texts_merged) { - glflush(); - triangle_color = color; - line_color = outline; - } - shapes_merged++; - - if((flags & POLY_CCONVEX) && !(flags & POLY_VCONVEX)) { - vector v2(cnt+1); - for(int i=0; i v2(cnt); - for(int i=0; itexture_id); - glhr::vertices_texture(v, tinf->tvertices, offset, offset_texture); - ioffset = 0; - #endif - } - else { - glhr::be_nontextured(); - - #if !ISANDROID - glhr::vertices(v); - #else - if(glhr::current_vertices != &v[offset]) { - glhr::current_vertices = &v[offset]; - glVertexAttribPointer(glhr::aPosition, 3, GL_FLOAT, GL_FALSE, sizeof(glvertex), &v[offset]); - // glVertexPointer(3, GL_FLOAT, sizeof(glvertex), &v[ps]); - // glhr::vertices(v); - } - offset = 0; - #endif - } - - for(int ed = current_display->stereo_active() ? -1 : 0; ed<2; ed+=2) { - if(global_projection && global_projection != ed) continue; - current_display->set_all(ed); - bool draw = color; - - if(shaderside_projection) { - if(glhr::current_shader_projection == glhr::shader_projection::band && V[2][2] > 1e8) continue; - glapplymatrix(V); - } - - if(draw) { - if(flags & POLY_TRIANGLES) { - glhr::color2(color, (flags & POLY_INTENSE) ? 2 : 1); - glhr::set_depthtest(model_needs_depth() && prio < PPR::SUPERLINE); - glhr::set_depthwrite(model_needs_depth() && prio != PPR::TRANSPARENT_SHADOW); - glhr::set_fogbase(prio == PPR::SKY ? 1.0 + 5 / sightranges[geometry] : 1.0); - glDrawArrays(GL_TRIANGLES, ioffset, cnt); - } - else { - glEnable(GL_STENCIL_TEST); - - glColorMask( GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE ); - glhr::set_depthtest(false); - glStencilOp( GL_INVERT, GL_INVERT, GL_INVERT); - glStencilFunc( GL_ALWAYS, 0x1, 0x1 ); - glhr::color2(0xFFFFFFFF); - glDrawArrays(tinf ? GL_TRIANGLES : GL_TRIANGLE_FAN, offset, cnt); - - current_display->set_mask(ed); - glhr::color2(color); - glhr::set_depthtest(model_needs_depth() && prio < PPR::SUPERLINE); - glhr::set_depthwrite(model_needs_depth() && prio != PPR::TRANSPARENT_SHADOW); - - if(flags & (POLY_INVERSE | POLY_FORCE_INVERTED)) { - glStencilOp( GL_ZERO, GL_ZERO, GL_ZERO); - glStencilFunc( GL_NOTEQUAL, 1, 1); - GLfloat xx = vid.xres; - GLfloat yy = vid.yres; - GLfloat dist = shaderside_projection ? current_display->scrdist : 0; - vector scr = { - glhr::makevertex(-xx, -yy, dist), - glhr::makevertex(+xx, -yy, dist), - glhr::makevertex(+xx, +yy, dist), - glhr::makevertex(-xx, +yy, dist) - }; - glhr::vertices(scr); - glhr::id_modelview(); - glDrawArrays(tinf ? GL_TRIANGLES : GL_TRIANGLE_FAN, 0, 4); - glhr::vertices(v); - if(shaderside_projection) glapplymatrix(V); - } - else { - glStencilOp( GL_ZERO, GL_ZERO, GL_ZERO); - glStencilFunc( GL_EQUAL, 1, 1); - glDrawArrays(tinf ? GL_TRIANGLES : GL_TRIANGLE_FAN, offset, cnt); - } - - glDisable(GL_STENCIL_TEST); - } - } - - if(outline && !(flags & POLY_TRIANGLES)) { - glhr::color2(outline); - glhr::set_depthtest(model_needs_depth() && prio < PPR::SUPERLINE); - glDrawArrays(GL_LINE_STRIP, offset, cnt); - } - } - } -#endif - -ld scale_at(const transmatrix& T) { - if(DIM == 3 && pmodel == mdPerspective) return 1 / (tC0(T))[2]; - using namespace hyperpoint_vec; - hyperpoint h1, h2, h3; - applymodel(tC0(T), h1); - applymodel(T * xpush0(.01), h2); - applymodel(T * ypush(.01) * C0, h3); - return sqrt(hypot_d(2, h2-h1) * hypot_d(2, h3-h1) / .0001); - } - -ld linewidthat(const hyperpoint& h) { - if(!(vid.antialias & AA_LINEWIDTH)) return 1; - else if(hyperbolic && pmodel == mdDisk && vid.alpha == 1) { - double dz = h[DIM]; - if(dz < 1 || abs(dz-current_display->scrdist) < 1e-6) return 1; - else { - double dx = sqrt(dz * dz - 1); - double dfc = dx/(dz+1); - dfc = 1 - dfc*dfc; - return dfc; - } - } - else if(svg::in || inHighQual) { - using namespace hyperpoint_vec; - hyperpoint h0 = h / zlevel(h); - transmatrix T = rgpushxto0(h0); - return scale_at(T); - } - return 1; - } - -// -radius to +3radius - -int mercator_coord; -int mercator_loop_min = 0, mercator_loop_max = 0; -ld mercator_period; - -void fixMercator(bool tinf) { - - if(pmodel == mdBand) - mercator_period = 4 * current_display->radius; - else - mercator_period = 2 * current_display->radius; - - if(!conformal::model_straight) - for(auto& g: glcoords) - conformal::apply_orientation(g[0], g[1]); - - if(pmodel == mdSinusoidal) - for(int i = 0; iradius / vid.stretch * M_PI); - - ld hperiod = mercator_period / 2; - - mercator_coord = 0; - - auto dist = [] (ld a, ld b) { return max(b, a-b); }; - - ld chypot = hypot(dist(vid.xres, current_display->xcenter), dist(vid.yres, current_display->ycenter)); - - ld cmin = -chypot/2, cmax = chypot/2, dmin = -chypot, dmax = chypot; - - if(mercator_coord) - swap(cmin, dmin), swap(cmax, dmax); - if(pmodel == mdSinusoidal) - dmin = -vid.stretch * current_display->radius / 2, dmax = vid.stretch * current_display->radius / 2; - if(pmodel == mdBandEquidistant) - dmin = -vid.stretch * current_display->radius / 2, dmax = vid.stretch * current_display->radius / 2; - if(pmodel == mdBandEquiarea) - dmin = -vid.stretch * current_display->radius / M_PI, dmax = vid.stretch * current_display->radius / M_PI; - - for(int i = 0; i hperiod) glcoords[0][mercator_coord] -= mercator_period; - } - - ld first = glcoords[0][mercator_coord]; - ld next = first; - - ld mincoord = first, maxcoord = first; - - for(int i = 0; i next + hperiod) - glcoords[i][mercator_coord] -= mercator_period; - next = glcoords[i][mercator_coord]; - mincoord = min(mincoord, glcoords[i][mercator_coord]); - maxcoord = max(maxcoord, glcoords[i][mercator_coord]); - } - - if(abs(mincoord) > 50000 || abs(maxcoord) > 50000 || std::isnan(mincoord) || std::isnan(maxcoord)) { - mercator_loop_max--; - return; - } - - ld last = first; - while(last < next - hperiod) last += mercator_period; - while(last > next + hperiod) last -= mercator_period; - - if(first == last) { - while(mincoord > cmin) - mercator_loop_min--, mincoord -= mercator_period; - while(maxcoord < cmax) - mercator_loop_max++, maxcoord += mercator_period; - if(pmodel == mdSinusoidal) - for(int i = 0; iradius / vid.stretch * M_PI); - if(!conformal::model_straight) - for(auto& g: glcoords) - conformal::apply_orientation(g[1], g[0]); - } - else { - if(tinf) { - // this cannot work in Mercator - mercator_loop_max--; return; - } - if(last < first) { - reverse(glcoords.begin(), glcoords.end()); - swap(first, last); - } - while(maxcoord > cmin) { - for(int i=0; iradius / vid.stretch * M_PI); - glcoords.push_back(glcoords.back()); - glcoords.push_back(glcoords[0]); - for(int u=1; u<=2; u++) { - auto& v = glcoords[isize(glcoords)-u][1-mercator_coord]; - v = v < 0 ? dmin : dmax; - } - if(!conformal::model_straight) - for(auto& g: glcoords) - conformal::apply_orientation(g[1], g[0]); - /* printf("cycling %d -> %d\n", base, qglcoords); - for(int a=0; aV * p->intester; - if(is_behind(h1)) { - if(sphere) { - for(int i=0; i<3; i++) h1[i] = -h1[i]; - poly_flags &= ~POLY_CENTERIN; - } - else - nofill = true; - } - applymodel(h1, hscr); hscr[0] *= current_display->radius; hscr[1] *= current_display->radius * vid.stretch; - for(int i=0; iV)) - 1) > 1e-6) nofill = true; - - /* nofill = true; - outline = (flags & POLY_CENTERIN) ? 0x00FF00FF : 0xFF0000FF; - addpoint(hscr); */ - } - - /* - if(poly_flags & POLY_BADCENTERIN) { - glcoords.push_back(glhr::makevertex(hscr[0]+10, hscr[1]*vid.stretch, hscr[2])); - glcoords.push_back(glhr::makevertex(hscr[0], hscr[1]*vid.stretch+10, hscr[2])); - glcoords.push_back(glhr::makevertex(hscr[0]-10, hscr[1]*vid.stretch, hscr[2])); - glcoords.push_back(glhr::makevertex(hscr[0], hscr[1]*vid.stretch-10, hscr[2])); - glcoords.push_back(glhr::makevertex(hscr[0]+10, hscr[1]*vid.stretch, hscr[2])); - } */ - } - -void compute_side_by_area() { - - double rarea = 0; - for(int i=0; i0) - poly_flags ^= POLY_INVERSE; - } - -ld get_width(dqi_poly* p) { - if(p->flags & POLY_PRECISE_WIDE) { - ld maxwidth = 0; - for(int i=0; icnt; i++) { - hyperpoint h1 = p->V * glhr::gltopoint((*p->tab)[p->offset+i]); - maxwidth = max(maxwidth, linewidthat(h1)); - } - return maxwidth * p->linewidth; - } - else if(p->flags & POLY_FORCEWIDE) - return p->linewidth; - else - return linewidthat(tC0(p->V)) * p->linewidth; - } - -void dqi_poly::draw() { - - dynamicval bs(hr::band_shift, band_shift); - if(!hyperbolic && among(pmodel, mdPolygonal, mdPolynomial)) { - bool any = false; - for(int i=0; i 0) any = true; - } - if(!any) return; - } - - if(sphere && tinf && DIM == 2 && cnt > 3) { - int i = cnt; - cnt = 3; - for(int j=0; j phases[MAX_PHASE]; - extern int twopoint_sphere_flips; - extern bool twopoint_do_flips; - int pha; - if(twopoint_do_flips) { - for(int i=0; iradius); h[1] *= vid.stretch; - if(i == 0) - phases[j].push_back(h); - else { - int best = -1; - ld bhypot = 1e60; - for(int j0=0; j0radius)); - - // check if the i-th edge intersects the boundary of the ellipse - // (which corresponds to the segment between the antipodes of foci) - // if yes, switch cpha to the opposite - hyperpoint h2 = V * glhr::gltopoint((*tab)[offset+(i+1)%cnt]); - - hyperpoint ah1 = h1, ah2 = h2; - conformal::apply_orientation(ah1[0], ah1[1]); - conformal::apply_orientation(ah2[0], ah2[1]); - if(ah1[1] * ah2[1] > 0) continue; - ld c1 = ah1[1], c2 = -ah2[1]; - if(c1 < 0) c1 = -c1, c2 = -c2; - hyperpoint h = ah1 * c1 + ah2 * c2; - h /= hypot_d(3, h); - if(h[2] < 0 && abs(h[0]) < sin(vid.twopoint_param)) cpha = 1-cpha, pha = 2; - } - if(cpha == 1) pha = 0; - } - } - dynamicval d1(pmodel, mdUnchanged); - dynamicval d2(V, Id); - dynamicval d3(offset, 0); - dynamicval d4(tab, tab); - for(int j=0; j d5(cnt, isize(phases[j])); - tab = &phases[j]; - draw(); - } - return; - } - - /* if(spherespecial && prio == PPR::MOBILE_ARROW) { - if(spherephase == 0) return; - dynamicval ss(spherespecial, 0); - draw(); - return; - } */ - -#if CAP_GL - if(vid.usingGL && (current_display->set_all(global_projection), shaderside_projection)) { - glLineWidth(get_width(this)); - flags &= ~POLY_INVERSE; - gldraw(); - return; - } -#endif - - glcoords.clear(); - poly_flags = flags; - - double d = 0, curradius = 0; - if(sphere) { - d = det(V); - curradius = pow(abs(d), 1/3.); - } - - /* outline = 0x80808080; - color = 0; */ - - last_infront = false; - - addpoly(V, *tab, offset, cnt); - if(!(sphere && vid.alpha < .9)) if(pmodel != mdJoukowsky) if(!(flags & POLY_ALWAYS_IN)) for(int i=1; i vid.xres * 2 || dy > vid.yres * 2) return; - } - if(poly_flags & POLY_BEHIND) return; - if(isize(glcoords) <= 1) return; - - mercator_loop_min = mercator_loop_max = 0; - if(sphere && mdBandAny()) - fixMercator(tinf); - - int poly_limit = max(vid.xres, vid.yres) * 2; - - - if(0) for(auto& p: glcoords) { - if(abs(p[0]) > poly_limit || abs(p[1]) > poly_limit) - return; // too large! - } - - bool equi = mdAzimuthalEqui() || pmodel == mdFisheye; - - bool nofill = false; - - if(poly_flags & POLY_NIF_ERROR) return; - - if(spherespecial == 1 && sphere && (poly_flags & POLY_INFRONT) && (poly_flags & POLY_NOTINFRONT) && vid.alpha <= 1) { - bool around_center = false; - for(int i=0; i 0 || equi)) can_have_inverse = true; - if(pmodel == mdJoukowsky) can_have_inverse = true; - if(pmodel == mdJoukowskyInverted && vid.skiprope) can_have_inverse = true; - if(pmodel == mdDisk && hyperbolic && vid.alpha <= -1) can_have_inverse = true; - if(pmodel == mdSpiral && vid.skiprope) can_have_inverse = true; - - if(can_have_inverse && !(poly_flags & POLY_ISSIDE)) { - - if(!tinf) - compute_side_by_centerin(this, nofill); - - else { - if(d < 0) poly_flags ^= POLY_INVERSE; - compute_side_by_area(); - } - - if(poly_flags & POLY_INVERSE) { - if(curradius < vid.alpha - 1e-6) return; - if(!sphere) return; - } - - } - else poly_flags &=~ POLY_INVERSE; - - if(spherespecial) { - if(!hiliteclick && !(poly_flags & POLY_INFRONT)) return; - } - - int lastl = 0; - - for(int l=mercator_loop_min; l <= mercator_loop_max; l++) { - - if(l || lastl) { - for(int i=0; iradius * cos(y / current_display->radius / vid.stretch * M_PI); - } - glcoords[i][mercator_coord] += conformal::ocos * mercator_period * (l - lastl); - glcoords[i][1-mercator_coord] += conformal::osin * mercator_period * (l - lastl); - } - lastl = l; - } - - if(equi && (poly_flags & POLY_INVERSE)) { - if(abs(zlevel(V * C0) - 1) < 1e-6 && !tinf) { - // we should fill the other side - ld h = atan2(glcoords[0][0], glcoords[0][1]); - for(int i=0; i<=360; i++) { - ld a = i * degree + h; - glcoords.push_back(glhr::makevertex(current_display->radius * sin(a), current_display->radius * vid.stretch * cos(a), current_display->scrdist)); - } - poly_flags ^= POLY_INVERSE; - } - else { - // If we are on a zlevel, the algorithm above will not work correctly. - // It is hard to tell what to do in this case. Just fill neither side - nofill = true; - } - } - - #if CAP_GL - if(vid.usingGL) { - poly_flags &= ~(POLY_VCONVEX | POLY_CCONVEX); - // if(pmodel == 0) for(int i=0; iscrdist; - if(tinf && (poly_flags & POLY_INVERSE)) { - return; - } - glLineWidth(get_width(this)); - dqi_poly npoly = (*this); - npoly.V = Id; - npoly.tab = &glcoords; - npoly.offset = 0; - npoly.cnt = isize(glcoords); - if(nofill) npoly.color = 0, npoly.tinf = NULL; - npoly.flags = poly_flags; - npoly.gldraw(); - continue; - } - #endif - - #if CAP_SVG==1 - if(svg::in) { - coords_to_poly(); - color_t col = color; - if(poly_flags & POLY_INVERSE) col = 0; - svg::polygon(polyx, polyy, polyi, col, outline, get_width(this)); - continue; - } - #endif - - coords_to_poly(); - - #if CAP_XGD==1 - gdpush(1); gdpush(color); gdpush(outline); gdpush(polyi); - for(int i=0; itvertices[offset_texture + i], color); - #endif - } - else if(poly_flags & POLY_INVERSE) { - int i = polyi; - if(true) { - polyx[i] = 0; polyy[i] = 0; i++; - polyx[i] = vid.xres; polyy[i] = 0; i++; - polyx[i] = vid.xres; polyy[i] = vid.yres; i++; - polyx[i] = 0; polyy[i] = vid.yres; i++; - polyx[i] = 0; polyy[i] = 0; i++; - } - filledPolygonColorI(s, polyx, polyy, polyi+5, color); - } - else - filledPolygonColorI(s, polyx, polyy, polyi, color); - - if(current_display->stereo_active()) filledPolygonColorI(aux, polyxr, polyy, polyi, color); - - ((vid.antialias & AA_NOGL) ?aapolylineColor:polylineColor)(s, polyx, polyy, polyi, outline); - if(current_display->stereo_active()) aapolylineColor(aux, polyxr, polyy, polyi, outline); - - if(vid.xres >= 2000 || fatborder) { - int xmi = 3000, xma = -3000; - for(int t=0; t xmi + 20) for(int x=-1; x<2; x++) for(int y=-1; y<=2; y++) if(x*x+y*y == 1) { - for(int t=0; t prettylinepoints; - -void prettypoint(const hyperpoint& h) { - prettylinepoints.push_back(glhr::pointtogl(h)); - } - -void prettylinesub(const hyperpoint& h1, const hyperpoint& h2, int lev) { - if(lev >= 0) { - hyperpoint h3 = midz(h1, h2); - prettylinesub(h1, h3, lev-1); - prettylinesub(h3, h2, lev-1); - } - else prettypoint(h2); - } - -void prettyline(hyperpoint h1, hyperpoint h2, color_t col, int lev, int flags, PPR prio) { - prettylinepoints.clear(); - prettypoint(h1); - prettylinesub(h1, h2, lev); - dqi_poly ptd; - ptd.V = Id; - ptd.band_shift = band_shift; - ptd.tab = &prettylinepoints; - ptd.offset = 0; - ptd.cnt = isize(prettylinepoints); - ptd.linewidth = vid.linewidth; - ptd.color = 0; - ptd.outline = col; - ptd.flags = POLY_ISSIDE | POLY_PRECISE_WIDE | flags; - ptd.tinf = NULL; - ptd.intester = C0; - ptd.prio = prio; - ptd.draw(); - } - -void prettypoly(const vector& t, color_t fillcol, color_t linecol, int lev) { - prettylinepoints.clear(); - prettypoint(t[0]); - for(int i=0; i curvedata; -int curvestart = 0; -bool keep_curvedata = false; - -void queuereset(eModel m, PPR prio) { - queueaction(prio, [m] () { pmodel = m; }); - } - -void dqi_line::draw() { - dynamicval d(vid.linewidth, width); - dynamicval bs(hr::band_shift, band_shift); - prettyline(H1, H2, color, prf, 0, prio); - } - -void dqi_string::draw() { - #if CAP_SVG - if(svg::in) { - svg::text(x, y, size, str, frame, color, align); - return; - } - #endif - #if ISMOBILE==0 - int fr = frame & 255; - displayfrSP(x, y, shift, fr, size, str, color, align, frame >> 8); - #else - displayfr(x, y, frame, size, str, color, align); - #endif - } - -void dqi_circle::draw() { - #if CAP_SVG - if(svg::in) { - svg::circle(x, y, size, color, fillcolor, linewidth); - } - else - #endif - drawCircle(x, y, size, color, fillcolor); - } - -void initquickqueue() { - ptds.clear(); - poly_outline = OUTLINE_NONE; - } - -void sortquickqueue() { - for(int i=1; iprio < ptds[i-1]->prio) { - swap(ptds[i], ptds[i-1]); - i--; - } - else i++; - } - -void quickqueue() { - spherespecial = 0; - reset_projection(); current_display->set_all(0); - int siz = isize(ptds); - for(int i=0; idraw(); - ptds.clear(); - } - -ld xintval(const hyperpoint& h) { - if(sphereflipped()) return -h[2]; - return -intval(h, C0); - } - -ld backbrightness = .25; - -purehookset hook_drawqueue; - -constexpr int PMAX = int(PPR::MAX); -int qp[PMAX], qp0[PMAX]; - -color_t darken_color(color_t& color, bool outline) { - int alpha = color & 255; - if(sphere && pmodel == mdDisk && vid.alpha <= 1) - return 0; - else { - if(outline && alpha < 255) - return color - alpha + int(backbrightness * alpha); - else - return (gradient(modelcolor>>8, color>>8, 0, backbrightness, 1)<<8) | 0xFF; - } - } - -void dqi_poly::draw_back() { - dynamicval dvo(outline, darken_color(outline, true)); - dynamicval dvc(color, darken_color(color, false)); - draw(); - } - -void dqi_line::draw_back() { - dynamicval dvc(color, darken_color(color, true)); - draw(); - } - -void sort_drawqueue() { - - for(int a=0; a>> subqueue; - for(auto& p: ptds) subqueue[p->prio == PPR::CIRCLE ? 0 : p->outline_group()].push_back(move(p)); - ptds.clear(); - for(auto& p: subqueue) for(auto& r: p.second) ptds.push_back(move(r)); - subqueue.clear(); - for(auto& p: ptds) subqueue[p->prio == PPR::CIRCLE ? 0 : p->color].push_back(move(p)); - ptds.clear(); - for(auto& p: subqueue) for(auto& r: p.second) ptds.push_back(move(r)); - #endif - - for(auto& p: ptds) { - int pd = p->prio - PPR::ZERO; - if(pd < 0 || pd >= PMAX) { - printf("Illegal priority %d\n", pd); - p->prio = PPR(rand() % int(PPR::MAX)); - } - qp[pd]++; - } - - int total = 0; - for(int a=0; a> ptds2; - ptds2.resize(siz); - - for(int i = 0; iprio)]++] = move(ptds[i]); - swap(ptds, ptds2); - } - -void reverse_priority(PPR p) { - reverse(ptds.begin()+qp0[int(p)], ptds.begin()+qp[int(p)]); - } - -void reverse_side_priorities() { - for(PPR p: {PPR::REDWALLs, PPR::REDWALLs2, PPR::REDWALLs3, PPR::WALL3s, - PPR::LAKEWALL, PPR::INLAKEWALL, PPR::BELOWBOTTOM}) - reverse_priority(p); - } - -// on the sphere, parts on the back are drawn first -void draw_backside() { - if(pmodel == mdHyperboloid && hyperbolic) { - dynamicval dv (pmodel, mdHyperboloidFlat); - for(auto& ptd: ptds) - if(!among(ptd->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE)) - ptd->draw(); - } - - spherespecial = sphereflipped() ? 1 : -1; - reset_projection(); - - if(pmodel == mdRotatedHyperboles) { - for(auto& ptd: ptds) - if(!among(ptd->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE)) - ptd->draw(); - glflush(); - } - else { - reverse_side_priorities(); - for(int i=ptds.size()-1; i>=0; i--) - if(!among(ptds[i]->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE)) - ptds[i]->draw_back(); - - glflush(); - reverse_side_priorities(); - } - - spherespecial *= -1; - spherephase = 1; - reset_projection(); - } - -extern bool lshiftclick, lctrlclick; - -void reverse_transparent_walls() { - int pt = int(PPR::TRANSPARENT_WALL); - reverse(&ptds[qp0[pt]], &ptds[qp[pt]]); - } - -void draw_main() { - if(sphere && DIM == 3 && pmodel == mdPerspective) { - for(int p: {1, 0, 2, 3}) { - if(elliptic && p < 2) continue; - glhr::set_depthwrite(true); - if(p == 0 || p == 3) { - #ifdef GL_ES - glClearDepthf(1.0f); - #else - glClearDepth(1.0f); - #endif - glDepthFunc(GL_LEQUAL); - } - else { - #ifdef GL_ES - glClearDepthf(0.0f); - #else - glClearDepth(0.0f); - #endif - glDepthFunc(GL_GEQUAL); - } - glClear(GL_DEPTH_BUFFER_BIT); - glhr::be_nontextured(); - spherephase = p; - reset_projection(); - for(auto& ptd: ptds) ptd->draw(); - if(elliptic) { - spherephase = p | 4; - reset_projection(); - for(auto& ptd: ptds) ptd->draw(); - } - // glflush(); - } - } - else { - 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) { - dynamicval ss(spherespecial, among(ptd->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE) ? 0 : spherespecial); - ptd->draw(); - } - glflush(); - } - } - -void drawqueue() { - callhooks(hook_drawqueue); - reset_projection(); - // reset_projection() is not sufficient here, because we need to know shaderside_projection - -#if CAP_GL - if(vid.usingGL) - glClear(GL_STENCIL_BUFFER_BIT); -#endif - - profile_start(3); - - sort_drawqueue(); - - for(PPR p: {PPR::REDWALLs, PPR::REDWALLs2, PPR::REDWALLs3, PPR::WALL3s, - PPR::LAKEWALL, PPR::INLAKEWALL, PPR::BELOWBOTTOM}) - if(DIM == 2) sort(&ptds[qp0[int(p)]], &ptds[qp[int(p)]], - [] (const unique_ptr& p1, const unique_ptr& p2) { - auto ap1 = (dqi_poly&) *p1; - auto ap2 = (dqi_poly&) *p2; - return xintval(ap1.V * xpush0(.1)) - < xintval(ap2.V * xpush0(.1)); - }); - - for(PPR p: {PPR::TRANSPARENT_WALL}) - sort(&ptds[qp0[int(p)]], &ptds[qp[int(p)]], - [] (const unique_ptr& p1, const unique_ptr& p2) { - return p1->subprio > p2->subprio; - }); - - profile_stop(3); - -#if CAP_SDL - if(current_display->stereo_active() && !vid.usingGL) { - - if(aux && (aux->w != s->w || aux->h != s->h)) - SDL_FreeSurface(aux); - - if(!aux) { - aux = SDL_CreateRGBSurface(SDL_SWSURFACE,s->w,s->h,32,0,0,0,0); - } - - // SDL_LockSurface(aux); - // memset(aux->pixels, 0, vid.xres * vid.yres * 4); - // SDL_UnlockSurface(aux); - SDL_BlitSurface(s, NULL, aux, NULL); - } -#endif - - spherespecial = 0; - spherephase = 0; - reset_projection(); - - if(model_needs_depth() && current_display->stereo_active()) { - global_projection = -1; - draw_main(); - glClear(GL_DEPTH_BUFFER_BIT); - global_projection = +1; - draw_main(); - } - else { - draw_main(); - } - -#if CAP_SDL - if(vid.stereo_mode == sAnaglyph && !vid.usingGL) { - int qty = s->w * s->h; - int *a = (int*) s->pixels; - int *b = (int*) aux->pixels; - SDL_LockSurface(aux); - while(qty) { - *a = ((*a) & 0xFF0000) | ((*b) & 0x00FFFF); - a++; b++; qty--; - } - SDL_UnlockSurface(aux); - } - - if(vid.stereo_mode == sLR && !vid.usingGL) { - SDL_LockSurface(aux); - for(int y=0; y shPlainWall3D, shWireframe3D, shWall3D, shMiniWall3D; - -#endif - -ld tentacle_length; - -#if CAP_SHAPES -#define USERLAYERS 32 - -struct usershapelayer { - vector list; - bool sym; - int rots; - color_t color; - hyperpoint shift, spin; - ld zlevel; - hpcshape sh; - int texture_offset; - }; - -struct usershape { - usershapelayer d[USERLAYERS]; - }; - -array, mapeditor::USERSHAPEGROUPS> usershapes; - -int SD3, SD6, SD7, S12, S14, S21, S28, S42, S36, S84; - -transmatrix ddi(int a, ld x) { return xspinpush(a * M_PI / S42, x); } - -void drawTentacle(hpcshape &h, ld rad, ld var, ld divby) { +void geometry_information::drawTentacle(hpcshape &h, ld rad, ld var, ld divby) { double tlength = max(crossf, hexhexdist); #if CAP_ARCM if(archimedean) tlength = arcm::current.scale(); @@ -1800,25 +99,17 @@ void drawTentacle(hpcshape &h, ld rad, ld var, ld divby) { hpcpush(ddi(S21, rad + var * sin(0 * M_PI/divby)) * C0); } -hyperpoint hpxd(ld d, ld x, ld y, ld z) { - hyperpoint H = hpxyz(d*x, d*y, z); - H = mid(H, H); - return H; - } - -hyperpoint hpxyzsc(double x, double y, double z) { +hyperpoint geometry_information::hpxyzsc(double x, double y, double z) { return hpxd(scalefactor, x,y,z); } -hyperpoint turtlevertex(int u, double x, double y, double z) { +hyperpoint geometry_information::turtlevertex(int u, double x, double y, double z) { ld scale = BITRUNCATED ? 1 : scalefactor; if(u) scale /= 2; return hpxd(scale, x, y, z); } -vector allshapes; - -void finishshape() { +void geometry_information::finishshape() { if(!last) return; last->e = isize(hpc); double area = 0; @@ -1837,7 +128,7 @@ void finishshape() { else for(int s=0; s<4; s++) { last->intester = C0; if(s == 0) { - for(int i=last->s; ie-1; i++) + for(int i=last->s; ie-1; i++) for(int j=0; j<3; j++) last->intester[j] += hpc[i][j]; last->intester = mid(last->intester, last->intester); @@ -1894,24 +185,18 @@ void finishshape() { printf("bad end\n"); */ } -void bshape(hpcshape& sh, PPR prio) { +void geometry_information::bshape(hpcshape& sh, PPR prio) { if(last) finishshape(); hpc.push_back(hpxy(0,0)); last = &sh; last->s = isize(hpc), last->prio = prio; last->flags = 0; last->tinf = NULL; - first = true; + first = true; } -vector> symmetriesAt; -#ifndef SCALETUNER -static const -#endif -double bscale7 = 1, brot7 = 0, bscale6 = 1, brot6 = 0; - -void bshape(hpcshape& sh, PPR prio, double shzoom, int shapeid, double bonus = 0, flagtype flags = 0) { +void geometry_information::bshape(hpcshape& sh, PPR prio, double shzoom, int shapeid, double bonus, flagtype flags) { bshape(sh, prio); int whereis = 0; while(polydata[whereis] != NEWSHAPE || polydata[whereis+1] != shapeid) whereis++; @@ -1937,7 +222,7 @@ void bshape(hpcshape& sh, PPR prio, double shzoom, int shapeid, double bonus = 0 shzoomx *= bscale7; shzoomy *= bscale7; bonus += brot7; - if(euclid) shzoomx *= .9, shzoomy *= .9, bonus += .3; + if(euclid) shzoomx *= .9, shzoomy *= .9, bonus += .3; } if(rots == 3) { rots2 = S3; @@ -1972,14 +257,15 @@ void bshape(hpcshape& sh, PPR prio, double shzoom, int shapeid, double bonus = 0 hpcpush(spin(2*M_PI*r/rots2) * ipoint(i, -1)); } hpcpush(ipoint(0, 1)); + finishshape(); } -void copyshape(hpcshape& sh, hpcshape& orig, PPR prio) { +void geometry_information::copyshape(hpcshape& sh, hpcshape& orig, PPR prio) { if(last) last->e = isize(hpc); sh = orig; sh.prio = prio; } -void zoomShape(hpcshape& old, hpcshape& newsh, double factor, PPR prio) { +void geometry_information::zoomShape(hpcshape& old, hpcshape& newsh, double factor, PPR prio) { bshape(newsh, prio); for(int i=old.s; iflags |= POLY_TRIANGLES; - - transmatrix T = rgpushxto0(ds.shift) * rspintox(ds.spin); - - int z = DIM == 3 ? 3 : 1; - - for(int r=0; r=0; i--) - hpcpush(T * spin(2*M_PI*r/ds.rots) * mirrortrans * ds.list[i]); - } - } - - if(DIM == 2) hpcpush(T * ds.list[0]); - - #if MAXMDIM >= 4 - if(DIM == 3) { - auto& utt = user_triangles_texture; - utt.texture_id = floor_textures->renderedTexture; - ds.texture_offset = isize(utt.tvertices); - for(int i=0; i ld gsca(bool geometry, ld factor, T... t) { +template ld gsca(bool geometry, ld factor, T... t) { if(geometry) return factor * gsca(t...); else return gsca(t...); } -template ld grot(bool geometry, ld factor, T... t) { +template ld grot(bool geometry, ld factor, T... t) { if(geometry) return factor + grot(t...); else return grot(t...); } -ld dlow_table[SIDEPARS], dhi_table[SIDEPARS], dfloor_table[SIDEPARS]; - #define SHADMUL (S3==4 ? 1.05 : 1.3) -void make_sidewalls() { +void geometry_information::make_sidewalls() { for(int i=0; i<=3; i++) - dfloor_table[i] = geom3::SLEV[i]; - dfloor_table[SIDE_WALL] = geom3::WALL; - dfloor_table[SIDE_LAKE] = geom3::LAKE; - dfloor_table[SIDE_LTOB] = geom3::BOTTOM; - dfloor_table[SIDE_BTOI] = geom3::INFDEEP; - dfloor_table[SIDE_HIGH] = geom3::HIGH; - dfloor_table[SIDE_HIGH2] = geom3::HIGH2; - dfloor_table[SIDE_SKY ] = geom3::SKY; - + dfloor_table[i] = SLEV[i]; + dfloor_table[SIDE_WALL] = WALL; + dfloor_table[SIDE_LAKE] = LAKE; + dfloor_table[SIDE_LTOB] = BOTTOM; + dfloor_table[SIDE_BTOI] = INFDEEP; + dfloor_table[SIDE_HIGH] = HIGH; + dfloor_table[SIDE_HIGH2] = HIGH2; + dfloor_table[SIDE_SKY ] = SKY; + // sidewall parameters for the 3D mode for(int k=0; k 0 && dhi > 0) || (dlow < 0 && dhi < 0) || GDIM == 3; - + bshape(shSemiFloorSide[k], PPR::LAKEWALL); for(int t=0; t<=3; t+=3) hpcpush(ddi(S7 + (3+t)*S14, floorrad0) * C0); chasmifyPoly(dlow, dhi, k); - } + } } -void procedural_shapes() { +void geometry_information::procedural_shapes() { bshape(shMovestar, PPR::MOVESTAR); for(int i=0; i<=8; i++) { hpcpush(xspinpush0(M_PI * i/4, crossf)); if(i != 8) hpcpush(xspinpush0(M_PI * i/4 + M_PI/8, crossf/4)); } - + // procedural floors - + bshape(shBarrel, PPR::FLOOR); for(int t=0; t<=S84; t+=2) hpcpush(ddi(t, floorrad1*.5) * C0); bshape(shCircleFloor, PPR::FLOOR); for(int t=0; t<=S84; t+=2) hpcpush(ddi(t, floorrad1*.9) * C0); - + for(int i=0; i<3; i++) for(int j=0; j<3; j++) shadowmulmatrix[i][j] = i==2&&j==2 ? 1: i==j ? SHADMUL: 0; - + for(int d=0; d<2; d++) { bshape(shSemiFloor[d], PPR::FLOOR); for(int t=0; t<=4; t++) hpcpush(ddi(S7 + (3+3*d+t%4)*S14, floorrad0) * C0); } // todo not shexf - - bshape(shBigCarpet1, PPR::GFLOORa); - for(int t=0; t<=S7; t++) hpcpush(ddi(t*12, -zhexf*2.1) * C0); + + bshape(shBigCarpet1, PPR::GFLOORa); + for(int t=0; t<=S7; t++) hpcpush(ddi(t*12, -zhexf*2.1) * C0); bshape(shBigCarpet2, PPR::GFLOORb); for(int t=0; t<=S7; t++) hpcpush(ddi(t*12, -zhexf*1.9) * C0); @@ -2187,7 +425,7 @@ void procedural_shapes() { } bshape(shWall[1], PPR::WALL); - int td = ((!BITRUNCATED || euclid) && !(S7&1)) ? S42+S6 : 0; + int td = ((!BITRUNCATED || euclid) && !(S7&1)) ? S42+S6 : 0; if(S7 == 6 || S7 == 4) { for(int t=0; t<=S6; t++) { hpcpush(ddi(S7 + t*S14, floorrad1) * C0); @@ -2385,7 +623,7 @@ void procedural_shapes() { } bshape(shILeaf[1], PPR::ONTENTACLE); - if(SD3 == 3 && SD7 % 3) + if(SD3 == 3 && SD7 % 3) for(int t=0; t<=SD7; t++) hpcpush(ddi(t*S36, zhexf*.8) * C0); else { for(int t=0; t<=SD7; t++) { @@ -2405,24 +643,23 @@ void procedural_shapes() { bshape(shHeptaMarker, PPR::HEPTAMARK); for(int t=0; t<=SD7; t++) hpcpush(ddi(t*S12, zhexf*.2) * C0); - + bshape(shSnowball, PPR::ITEM); for(int t=0; t<=SD7*4; t++) hpcpush(ddi(t*SD3, zhexf*.1) * C0); - + bshape(shRose, PPR::ITEM); PRING(t) hpcpush(xspinpush0(M_PI * t / (S42+.0), scalefactor * hcrossf7 * (0.2 + .15 * sin(M_PI * t / (S42+.0) * 3)))); - - finishshape(); + shRoseItem = shRose; bshape(shThorns, PPR::THORNS); - for(int t=0; t<=60; t++) + for(int t=0; t<=60; t++) hpcpush(xspinpush0(M_PI * t / 30.0, scalefactor * hcrossf7 * ((t&1) ? 0.3 : 0.6))); - + for(int i=0; i<16; i++) { bshape(shParticle[i], PPR::PARTICLE); - for(int t=0; t<6; t++) + for(int t=0; t<6; t++) // hpcpush(xspinpush0(M_PI * t * 2 / 6 + M_PI * 2/6 * hrand(100) / 150., (0.03 + hrand(100) * 0.0003) * scalefactor)); hpcpush(xspinpush0(M_PI * t * 2 / 6 + M_PI * 2/6 * randd() / 1.5, (0.03 + randd() * 0.03) * scalefactor)); hpc.push_back(hpc[last->s]); @@ -2432,11 +669,11 @@ void procedural_shapes() { asteroid_size[i] = scalefactor * 0.1 * pow(2, (i-1) * 1. / DIM); if(DIM == 3) asteroid_size[i] *= 7; bshape(shAsteroid[i], PPR::PARTICLE); - for(int t=0; t<12; t++) + for(int t=0; t<12; t++) hpcpush(xspinpush0(M_PI * t / 6, asteroid_size[i] * (1 - randd() * .2))); hpc.push_back(hpc[last->s]); } - + bshape(shSwitchDisk, PPR::FLOOR); for(int i=0; i<=S84; i+=S3) hpcpush(ddi(i, .06) * C0); } @@ -2447,9 +684,9 @@ void procedural_shapes() { // 1 = first edge should be doubled // 2 = use POLY_TRIANGLES // 4 = this is is a triangular face; otherwise, the face is rectangular, and x1+x2-x0 is the fourth vertex -void make_wall(int id, vector vertices, bool force_triangles = false) { +void geometry_information::make_wall(int id, vector vertices, bool force_triangles) { using namespace hyperpoint_vec; - + // orient correctly transmatrix T; set_column(T, 0, vertices[0]); @@ -2467,7 +704,7 @@ void make_wall(int id, vector vertices, bool force_triangles = false hyperpoint center = Hypc; for(auto v: vertices) center += v; int n = isize(vertices); - center /= n; + center /= n; for(int a=0; a make5(hyperpoint a, hyperpoint b, hyperpoint c) { return {a, (a+b)/2, b, b+c-a, c}; } -void create_wall3d() { +void geometry_information::create_wall3d() { if(WDIM == 2) return; using namespace hyperpoint_vec; shWall3D.resize(S7); @@ -2670,7 +907,7 @@ void create_wall3d() { int facesize = isize(reg3::cellshape) / S7; for(int w=0; w vertices; - for(int a=0; aflags |= POLY_TRIANGLES; } } - + corner_bonus = 0; for(hpcshape sh: shWall3D) for(int i=sh.s; i= 4 -extern void make_3d_models(); -#endif - -void buildpolys() { - symmetriesAt.clear(); allshapes.clear(); - geom3::compute(); #if CAP_GP gp::clear_plainshapes(); #endif DEBBI(DF_POLY, ("buildpolys")); - + if(WDIM == 3) { if(sphere) SD3 = 3, SD7 = 5; else SD3 = SD7 = 4; @@ -2815,22 +1048,24 @@ void buildpolys() { ld lenx = hdist(xpush0(hexvdist), spin(M_PI/S3) * xpush0(hexvdist)); ld hlenx = hdist(xpush0(hcrossf), spin(2*M_PI/S7) * xpush0(hcrossf)); - + bshape(shHalfMirror[2], PPR::WALL); - hpcpush(C0); hpcpush(xpush0(-len6*scalefactor)); chasmifyPoly(geom3::FLOOR, geom3::WALL, 0); + hpcpush(C0); hpcpush(xpush0(-len6*scalefactor)); chasmifyPoly(FLOOR, WALL, 0); bshape(shHalfMirror[1], PPR::WALL); if(PURE) { - hpcpush(xpush0(-hlen7)); hpcpush(xpush0(hcrossf+hlenx/2)); chasmifyPoly(geom3::FLOOR, geom3::WALL, 0); + hpcpush(xpush0(-hlen7)); hpcpush(xpush0(hcrossf+hlenx/2)); chasmifyPoly(FLOOR, WALL, 0); } else { - hpcpush(xpush0(-len7*scalefactor)); hpcpush(xpush0((hexf+lenx/2)*scalefactor)); chasmifyPoly(geom3::FLOOR, geom3::WALL, 0); + hpcpush(xpush0(-len7*scalefactor)); hpcpush(xpush0((hexf+lenx/2)*scalefactor)); chasmifyPoly(FLOOR, WALL, 0); } bshape(shHalfMirror[0], PPR::WALL); - hpcpush(xpush0(len6)); hpcpush(xpush0(-len6)); chasmifyPoly(geom3::FLOOR, geom3::WALL, 0); + hpcpush(xpush0(len6)); hpcpush(xpush0(-len6)); chasmifyPoly(FLOOR, WALL, 0); } - + bshape(shAsymmetric, PPR::TEXT, scalefactor, 374); - + + for(auto& sh: shTriheptaSpecial) sh.s = sh.e = 0; + bshape(shTriheptaSpecial[2], PPR::FLOOR, scalefactor, 32); bshape(shTriheptaSpecial[3], PPR::FLOOR, scalefactor, 33); bshape(shTriheptaSpecial[4], PPR::FLOOR, scalefactor, 34); @@ -2922,22 +1157,22 @@ void buildpolys() { bshape(shDragonTail, PPR::TENTACLE1, scalefactor * wormscale, 240); //239 alt bshape(shDragonNostril, PPR::ONTENTACLE_EYES, scalefactor * wormscale, 241); bshape(shDragonHead, PPR::ONTENTACLE, scalefactor * wormscale, 242); - + ld krsc = 1; if(sphere) krsc *= 1.4; if(S7 ==8) krsc *= 1.3; - + if(PURE && !euclid4) { tentacle_length = 1.52; bshape(shSeaTentacle, PPR::TENTACLE1, 1, 245); } else if(NONSTDVAR) { tentacle_length = 0.566256 * 1.6 * scalefactor * krsc; - bshape(shSeaTentacle, PPR::TENTACLE1, 1.6 * scalefactor * krsc, 246); + bshape(shSeaTentacle, PPR::TENTACLE1, 1.6 * scalefactor * krsc, 246); } else { tentacle_length = 0.566256 * scalefactor; - bshape(shSeaTentacle, PPR::TENTACLE1, scalefactor, 246); + bshape(shSeaTentacle, PPR::TENTACLE1, scalefactor, 246); } ld ksc = (!BITRUNCATED ? 1.8 : 1.5) * scalefactor * krsc; if(euclid4 && PURE) ksc *= .5; @@ -2975,7 +1210,9 @@ void buildpolys() { for(int i=0; i<5; i++) for(int j=0; j<4; j++) bshape(shReptile[i][j], j >= 2 ? PPR::LIZEYE : j == 1 ? PPR::FLOORa : PPR::FLOOR_DRAGON, scalefactor * gsca(euclid, 1.16), 277+i*4+j); - + + finishshape(); + shift(shReptile[1][2], 0.316534, -0.136547, 1.057752); shift(shReptile[1][3], 0.340722, -0.059946, 1.058152); @@ -2995,9 +1232,9 @@ void buildpolys() { bshape(shReptileFrontLeg, PPR::MONSTER_LEG, scalefactor, 301); bshape(shReptileRearLeg, PPR::MONSTER_LEG, scalefactor, 302); bshape(shReptileTail, PPR::MONSTER_BODY, scalefactor, 303); - bshape(shReptileEye, PPR::MONSTER_EYE0, scalefactor, 304); - bshape(shDodeca, PPR::ITEM, scalefactor, 305); - + bshape(shReptileEye, PPR::MONSTER_EYE0, scalefactor, 304); + bshape(shDodeca, PPR::ITEM, scalefactor, 305); + bshape(shTerraArmor1, PPR::MONSTER_BODY, scalefactor, 349); bshape(shTerraArmor2, PPR::MONSTER_BODY, scalefactor, 350); bshape(shTerraArmor3, PPR::MONSTER_BODY, scalefactor, 351); @@ -3050,7 +1287,7 @@ void buildpolys() { bshape(shGoatHead, PPR::MONSTER_HAIR, scalefactor, 101); bshape(shRatHead, PPR::MONSTER_HEAD, scalefactor, 102); - bshape(shRatEyes, PPR::MONSTER_EYE0, scalefactor, 103); + bshape(shRatEyes, PPR::MONSTER_EYE0, scalefactor, 103); bshape(shRatTail, PPR::MONSTER_LEG, scalefactor, 104); bshape(shRatCape1, PPR::MONSTER_HOODCLOAK2, scalefactor, 105); bshape(shRatCape2, PPR::MONSTER_HOODCLOAK1, scalefactor, 106); @@ -3187,279 +1424,27 @@ void buildpolys() { if(scalefactor > 1.5) bshape(shMagicSword, PPR::MAGICSWORD, scalefactor / 1.7570466583108084, 243); else bshape(shMagicSword, PPR::MAGICSWORD, scalefactor, 244); - + sword_size = 0; for(int i=shMagicSword.s; i= 4 make_3d_models(); #endif - - bshapeend(); - extern void add_user_shapes(); + + finishshape(); prehpc = isize(hpc); - add_user_shapes(); - } -void add_user_shapes() { - hpc.resize(prehpc); - last = NULL; - DEBB(DF_POLY, ("hpc = ", prehpc)); - - user_triangles_texture.tvertices.clear(); - - for(int i=0; id[l].sh, us->d[l].sh.prio); - pushShape(us->d[l]); - finishshape(); - } - } - - static int qhpc0; - int qhpc = isize(hpc); - if(qhpc != qhpc0 && (debugflags & (DF_GEOM | DF_POLY))) { - println(hlog, "qhpc = ", qhpc0=qhpc, " (", prehpc, "+", qhpc-prehpc, ")"); - println(hlog, "shapes = ", isize(allshapes)); - int inve=0, issi=0, vcon=0, ccon=0; - for(auto sh: allshapes) { - if(sh->flags & POLY_INVERSE) inve++; - if(sh->flags & POLY_ISSIDE) issi++; - if(sh->flags & POLY_VCONVEX) vcon++; - if(sh->flags & POLY_CCONVEX) ccon++; - } - println(hlog, format("inverse = %d isside = %d vcon = %d ccon = %d", inve, issi, vcon, ccon)); - } - initPolyForGL(); } -void initShape(int sg, int id) { - - if(!usershapes[sg][id]) { - usershape *us = new usershape; - usershapes[sg][id] = us; - - for(int i=0; id[i].sh.prio = PPR((sg == 3 ? 1:50) + i); - - us->d[i].rots = 1; - us->d[i].sym = 0; - us->d[i].shift = C0; - us->d[i].spin = Cx1; - us->d[i].color = 0; - us->d[i].zlevel = 0; - } - } - } -#else - -void buildpolys() { } -#endif - -template T& queuea(PPR prio, U... u) { - ptds.push_back(unique_ptr(new T (u...))); - ptds.back()->prio = prio; - return (T&) *ptds.back(); - } - -#if CAP_SHAPES -dqi_poly& queuepolyat(const transmatrix& V, const hpcshape& h, color_t col, PPR prio) { - if(prio == PPR::DEFAULT) prio = h.prio; - - auto& ptd = queuea (prio); - - ptd.V = V; - ptd.band_shift = band_shift; - ptd.offset = h.s; - ptd.cnt = h.e-h.s; - ptd.tab = &ourshape; - if(cblind) { - // protanopia - /* int r = (56 * part(col,3) + 43 * part(col,2)) / 100; - int g = (58 * part(col,3) + 42 * part(col,2)) / 100; - int b = (24 * part(col,2) + 75 * part(col,1)) / 100; */ - // deuteranopia - /* int r = (625 * part(col,3) + 375 * part(col,2)) / 1000; - int g = (700 * part(col,3) + 300 * part(col,2)) / 1000; - int b = (300 * part(col,2) + 700 * part(col,1)) / 1000; - part(col,3) = r; - part(col,2) = g; - part(col,1) = b; */ - part(col,2) = part(col,3) = (part(col,2) * 2 + part(col,3) + 1)/3; - } - ptd.color = (darkened(col >> 8) << 8) + (col & 0xFF); - ptd.outline = poly_outline; - ptd.linewidth = vid.linewidth; - ptd.flags = h.flags; - ptd.tinf = h.tinf; - ptd.offset_texture = h.texture_offset; - ptd.intester = h.intester; - return ptd; - } -#endif - -void addfloats(vector& v, hyperpoint h) { - for(int i=0; i<3; i++) v.push_back(h[i]); - } - -dqi_poly& queuetable(const transmatrix& V, const vector& f, int cnt, color_t linecol, color_t fillcol, PPR prio) { - - auto& ptd = queuea (prio); - - ptd.V = V; - ptd.band_shift = band_shift; - ptd.tab = &f; - ptd.offset = 0; - ptd.cnt = cnt; - ptd.color = fillcol; - ptd.outline = linecol; - ptd.linewidth = vid.linewidth; - ptd.flags = POLY_ISSIDE | POLY_PRECISE_WIDE; - ptd.tinf = NULL; - ptd.intester = C0; - return ptd; - } - -#if CAP_SHAPES -dqi_poly& queuepoly(const transmatrix& V, const hpcshape& h, color_t col) { - return queuepolyat(V,h,col,h.prio); - } - -void queuepolyb(const transmatrix& V, const hpcshape& h, color_t col, int b) { - queuepolyat(V,h,col,h.prio+b); - } -#endif - -void curvepoint(const hyperpoint& H1) { - curvedata.push_back(glhr::pointtogl(H1)); - } - -dqi_poly& queuecurve(color_t linecol, color_t fillcol, PPR prio) { - auto &res = queuetable(Id, curvedata, isize(curvedata)-curvestart, linecol, fillcol, prio); - res.offset = curvestart; - curvestart = isize(curvedata); - return res; - } - -dqi_action& queueaction(PPR prio, const reaction_t& action) { - return queuea (prio, action); - } - -dqi_line& queueline(const hyperpoint& H1, const hyperpoint& H2, color_t col, int prf, PPR prio) { - auto& ptd = queuea (prio); - - ptd.H1 = H1; - ptd.H2 = H2; - ptd.band_shift = band_shift; - ptd.prf = prf; - ptd.width = vid.linewidth; - ptd.color = (darkened(col >> 8) << 8) + (col & 0xFF); - - return ptd; - } - -void queuestr(int x, int y, int shift, int size, string str, color_t col, int frame, int align) { - auto& ptd = queuea (PPR::TEXT); - ptd.x = x; - ptd.y = y; - ptd.str = str; - ptd.align = align; - ptd.shift = shift; - ptd.size = size; - ptd.color = darkened(col); - ptd.frame = frame ? ((poly_outline & ~ 255)+frame) : 0; - } - -void queuechr(int x, int y, int shift, int size, char chr, color_t col, int frame, int align) { - auto& ptd = queuea (PPR::TEXT); - ptd.x = x; - ptd.y = y; - ptd.str = chr; - ptd.shift = shift; - ptd.size = size; - ptd.align = align; - ptd.color = col; - ptd.frame = frame ? (poly_outline & ~ 255) : 0; - } - -void queuecircle(int x, int y, int size, color_t color, PPR prio = PPR::CIRCLE, color_t fillcolor = 0) { - auto& ptd = queuea(prio); - ptd.x = x; - ptd.y = y; - ptd.size = size; - ptd.color = color; - ptd.fillcolor = fillcolor; - ptd.linewidth = vid.linewidth; - } - -void getcoord0(const hyperpoint& h, int& xc, int &yc, int &sc) { - hyperpoint hscr; - applymodel(h, hscr); - xc = current_display->xcenter + current_display->radius * hscr[0]; - yc = current_display->ycenter + current_display->radius * vid.stretch * hscr[1]; - sc = 0; - // EYETODO sc = vid.eye * current_display->radius * hscr[2]; - } - -void queuechr(const hyperpoint& h, int size, char chr, color_t col, int frame) { - if(invalid_point(h)) return; - if(DIM == 3 && invis_point(h)) return; - int xc, yc, sc; getcoord0(h, xc, yc, sc); - queuechr(xc, yc, sc, size, chr, col, frame); - } - -ld scale_in_pixels(const transmatrix& V) { - return scale_at(V) * scalefactor * current_display->radius / 2.5; - } - -void queuechr(const transmatrix& V, double size, char chr, color_t col, int frame) { - if(invalid_point(V)) return; - if(DIM == 3 && invis_point(tC0(V))) return; - int xc, yc, sc; getcoord0(tC0(V), xc, yc, sc); - queuechr(xc, yc, sc, scale_in_pixels(V) * size, chr, col, frame); - } - -void queuestr(const hyperpoint& h, int size, const string& chr, color_t col, int frame) { - if(invalid_point(h)) return; - if(DIM == 3 && invis_point(h)) return; - int xc, yc, sc; getcoord0(h, xc, yc, sc); - queuestr(xc, yc, sc, size, chr, col, frame); - } - -void queuestr(const transmatrix& V, double size, const string& chr, color_t col, int frame, int align) { - if(invalid_point(V)) return; - if(DIM == 3 && invis_point(tC0(V))) return; - int xc, yc, sc; getcoord0(tC0(V), xc, yc, sc); - // int xs, ys, ss; getcoord0(V * xpush0(.01), xs, ys, ss); - - queuestr(xc, yc, sc, scale_in_pixels(V) * size, chr, col, frame, align); - } - -void queuecircle(const transmatrix& V, double size, color_t col) { - if(invalid_point(V)) return; - if(DIM == 3 && invis_point(tC0(V))) return; - int xc, yc, sc; getcoord0(tC0(V), xc, yc, sc); - int xs, ys, ss; getcoord0(V * xpush0(.01), xs, ys, ss); - queuecircle(xc, yc, scale_in_pixels(V) * size, col); - } - -void queuemarkerat(const transmatrix& V, color_t col) { -#if CAP_SHAPES - queuepolyat(V, shTriangle, col, PPR::LINE); -#endif - } - -#if CAP_SHAPES long double polydata[] = { // shStarFloor[0] (6x1) NEWSHAPE, 1,6,1, 0.267355,0.153145, 0.158858,0.062321, 0.357493,-0.060252, @@ -3966,54 +1951,54 @@ NEWSHAPE, 251,1,1, -0.186883,0.074525, -0.165331,0.041449, -0.154901,0.003708, - // shArrow (1x2) NEWSHAPE, 252,1,2, -0.053383,0.030028, 0.040021,0.022234, 0.033369,0.056728, 0.101370,0.001114, // shTreat -NEWSHAPE, 253,3,2, 0.220188,0.075636, 0.089347,0.084922, 0.109762,0.055626, 0.120125,0.037135, 0.127589,0.018676, 0.128473,0.010613, +NEWSHAPE, 253,3,2, 0.220188,0.075636, 0.089347,0.084922, 0.109762,0.055626, 0.120125,0.037135, 0.127589,0.018676, 0.128473,0.010613, // shBatWings -NEWSHAPE, 254,1,2, 0.063731,-0.043246, 0.124072,-0.170024, 0.084056,-0.324550, -0.103512,-0.366996, -0.074400,-0.297599, -0.108529,-0.230913, -0.086972,-0.144190, -0.118951,-0.109801, -0.072887,-0.059221, -0.167080,-0.022888, +NEWSHAPE, 254,1,2, 0.063731,-0.043246, 0.124072,-0.170024, 0.084056,-0.324550, -0.103512,-0.366996, -0.074400,-0.297599, -0.108529,-0.230913, -0.086972,-0.144190, -0.118951,-0.109801, -0.072887,-0.059221, -0.167080,-0.022888, // shBatBody -NEWSHAPE, 255,1, 2, -0.061429,-0.022752, -0.059165,-0.038685, -0.141985,-0.103054, -0.043229,-0.050055, 0.029576,-0.056876, 0.080137,-0.153405, -0.107472,-0.114332, 0.084857,-0.172008, -0.094609,-0.230753, 0.085016,-0.193009, 0.060443,-0.299888, -0.096263,-0.356877, 0.086368,-0.322128, 0.128679,-0.167743, 0.068287,-0.038696, 0.148735,-0.073224, 0.174190,-0.061883, 0.183380,-0.032092, 0.157798,-0.016009, 0.118603,-0.015966, +NEWSHAPE, 255,1, 2, -0.061429,-0.022752, -0.059165,-0.038685, -0.141985,-0.103054, -0.043229,-0.050055, 0.029576,-0.056876, 0.080137,-0.153405, -0.107472,-0.114332, 0.084857,-0.172008, -0.094609,-0.230753, 0.085016,-0.193009, 0.060443,-0.299888, -0.096263,-0.356877, 0.086368,-0.322128, 0.128679,-0.167743, 0.068287,-0.038696, 0.148735,-0.073224, 0.174190,-0.061883, 0.183380,-0.032092, 0.157798,-0.016009, 0.118603,-0.015966, // shBatMouth -NEWSHAPE, 256, 1, 2, 0.065982,0.006826, 0.081971,0.027324, 0.091097,0.002277, +NEWSHAPE, 256, 1, 2, 0.065982,0.006826, 0.081971,0.027324, 0.091097,0.002277, // shBatFang -NEWSHAPE, 257, 1, 1, 0.084220,0.016514, 0.054588,0.011372, 0.088636,0.006606, +NEWSHAPE, 257, 1, 1, 0.084220,0.016514, 0.054588,0.011372, 0.088636,0.006606, // shBatEye -NEWSHAPE, 258, 1, 1, 0.100828,0.030855, 0.108021,0.024250, 0.106903,0.014878, 0.099146,0.009915, +NEWSHAPE, 258, 1, 1, 0.100828,0.030855, 0.108021,0.024250, 0.106903,0.014878, 0.099146,0.009915, // shHumanFoot -NEWSHAPE, 259, 1, 1, -0.091073,0.081161, -0.071926,0.092823, -0.046931,0.094885, -0.019968,0.097943, -0.001122,0.092149, 0.011212,0.084470, 0.010501,0.070502, -0.001155,0.056218, -0.018631,0.051502, -0.070956,0.049847, -0.086365,0.056093, -0.094267,0.064719, +NEWSHAPE, 259, 1, 1, -0.091073,0.081161, -0.071926,0.092823, -0.046931,0.094885, -0.019968,0.097943, -0.001122,0.092149, 0.011212,0.084470, 0.010501,0.070502, -0.001155,0.056218, -0.018631,0.051502, -0.070956,0.049847, -0.086365,0.056093, -0.094267,0.064719, // shHumanLeg -NEWSHAPE, 260, 1, 1, -0.085549,0.082560, -0.066987,0.087728, -0.050005,0.088432, -0.036738,0.073722, -0.033485,0.056714, -0.050113,0.042534, -0.076986,0.046956, -0.086334,0.058587, +NEWSHAPE, 260, 1, 1, -0.085549,0.082560, -0.066987,0.087728, -0.050005,0.088432, -0.036738,0.073722, -0.033485,0.056714, -0.050113,0.042534, -0.076986,0.046956, -0.086334,0.058587, // shHumanGroin -NEWSHAPE, 261, 1, 2, -0.092531,0.043227, -0.077988,0.087426, -0.048692,0.113964, -0.022425,0.100486, 0.002705,0.048193, +NEWSHAPE, 261, 1, 2, -0.092531,0.043227, -0.077988,0.087426, -0.048692,0.113964, -0.022425,0.100486, 0.002705,0.048193, // shHumanNeck NEWSHAPE, 262, 1, 2, -0.035947,0.023404, -0.011281,0.043922, 0.017582,0.045486, 0.031600,0, // shSemiFloorShadow -NEWSHAPE, 263, 1, 2, -0.317691,0.208329, 0.065767,0.397781, +NEWSHAPE, 263, 1, 2, -0.317691,0.208329, 0.065767,0.397781, // shSkeletalFoot -NEWSHAPE, 264, 1, 1, -0.082697,0.087468, -0.071752,0.102240, -0.048756,0.105169, 0.005645,0.101864, 0.009206,0.097754, 0.005659,0.094999, -0.043535,0.093347, -0.043804,0.090603, 0.007314,0.087046, 0.010873,0.084038, 0.005962,0.079364, -0.043239,0.079083, -0.045150,0.075798, 0.004608,0.072508, 0.010903,0.067865, 0.006269,0.060184, -0.065401,0.062704, -0.079938,0.072088, +NEWSHAPE, 264, 1, 1, -0.082697,0.087468, -0.071752,0.102240, -0.048756,0.105169, 0.005645,0.101864, 0.009206,0.097754, 0.005659,0.094999, -0.043535,0.093347, -0.043804,0.090603, 0.007314,0.087046, 0.010873,0.084038, 0.005962,0.079364, -0.043239,0.079083, -0.045150,0.075798, 0.004608,0.072508, 0.010903,0.067865, 0.006269,0.060184, -0.065401,0.062704, -0.079938,0.072088, // shDogBody -NEWSHAPE, 265, 1, 2, -0.310601,0.000000, -0.158251,0.009739, -0.149626,0.045009, -0.173168,0.066320, -0.250414,0.056912, -0.242122,0.064314, -0.253563,0.065926, -0.241104,0.075740, -0.249897,0.082453, -0.237118,0.081982, -0.246310,0.097762, -0.230366,0.088118, -0.210870,0.082352, -0.194727,0.083100, -0.180298,0.087679, -0.162032,0.087154, -0.135091,0.081542, -0.116083,0.068924, -0.106144,0.066340, -0.084057,0.063643, -0.061108,0.071892, -0.044295,0.077815, -0.021516,0.077698, 0.000000,0.078872, 0.025203,0.099613, 0.040964,0.113252, 0.067885,0.127285, 0.086481,0.135203, 0.104129,0.144556, 0.097579,0.132951, 0.112604,0.134635, 0.098603,0.124167, 0.118341,0.115901, 0.094688,0.115325, 0.079806,0.108826, 0.065011,0.097516, 0.053964,0.082746, 0.049028,0.066966, 0.045353,0.053708, 0.046494,0.040534, 0.051260,0.033378, 0.074561,0.026708, 0.111469,0.022294, +NEWSHAPE, 265, 1, 2, -0.310601,0.000000, -0.158251,0.009739, -0.149626,0.045009, -0.173168,0.066320, -0.250414,0.056912, -0.242122,0.064314, -0.253563,0.065926, -0.241104,0.075740, -0.249897,0.082453, -0.237118,0.081982, -0.246310,0.097762, -0.230366,0.088118, -0.210870,0.082352, -0.194727,0.083100, -0.180298,0.087679, -0.162032,0.087154, -0.135091,0.081542, -0.116083,0.068924, -0.106144,0.066340, -0.084057,0.063643, -0.061108,0.071892, -0.044295,0.077815, -0.021516,0.077698, 0.000000,0.078872, 0.025203,0.099613, 0.040964,0.113252, 0.067885,0.127285, 0.086481,0.135203, 0.104129,0.144556, 0.097579,0.132951, 0.112604,0.134635, 0.098603,0.124167, 0.118341,0.115901, 0.094688,0.115325, 0.079806,0.108826, 0.065011,0.097516, 0.053964,0.082746, 0.049028,0.066966, 0.045353,0.053708, 0.046494,0.040534, 0.051260,0.033378, 0.074561,0.026708, 0.111469,0.022294, // shDogHead -NEWSHAPE, 266, 1, 2, 0.063398,0.010010, 0.064517,0.018910, 0.069275,0.029860, 0.077732,0.029897, 0.081360,0.028715, 0.066249,0.039649, 0.106662,0.046229, 0.146020,0.025919, 0.159666,0.028110, 0.172131,0.020186, 0.172077,0.013438, 0.168613,0.007837, +NEWSHAPE, 266, 1, 2, 0.063398,0.010010, 0.064517,0.018910, 0.069275,0.029860, 0.077732,0.029897, 0.081360,0.028715, 0.066249,0.039649, 0.106662,0.046229, 0.146020,0.025919, 0.159666,0.028110, 0.172131,0.020186, 0.172077,0.013438, 0.168613,0.007837, // shDogTorso -NEWSHAPE, 267, 1, 2, -0.310601,0.000000, -0.158251,0.009739, -0.149626,0.045009, -0.116083,0.068924, -0.106144,0.066340, -0.084057,0.063643, -0.061108,0.071892, -0.044295,0.077815, -0.021516,0.077698, 0.000000,0.078872, 0.036721,0.067879, 0.045353,0.053708, 0.046494,0.040534, 0.051260,0.033378, 0.074561,0.026708, 0.111469,0.022294, +NEWSHAPE, 267, 1, 2, -0.310601,0.000000, -0.158251,0.009739, -0.149626,0.045009, -0.116083,0.068924, -0.106144,0.066340, -0.084057,0.063643, -0.061108,0.071892, -0.044295,0.077815, -0.021516,0.077698, 0.000000,0.078872, 0.036721,0.067879, 0.045353,0.053708, 0.046494,0.040534, 0.051260,0.033378, 0.074561,0.026708, 0.111469,0.022294, // shDogFrontPaw -NEWSHAPE, 268, 1, 1, -0.021458,0.071528, 0.056770,0.096454, 0.086625,0.096557, 0.094338,0.086062, 0.091509,0.069458, 0.029143,0.047289, -0.007695,0.037376, -0.024745,0.050039, +NEWSHAPE, 268, 1, 1, -0.021458,0.071528, 0.056770,0.096454, 0.086625,0.096557, 0.094338,0.086062, 0.091509,0.069458, 0.029143,0.047289, -0.007695,0.037376, -0.024745,0.050039, // shDogRearPaw -NEWSHAPE, 269, 1, 1, -0.120244,0.033095, -0.181823,0.053216, -0.199420,0.068325, -0.189994,0.093330, -0.169179,0.099289, -0.138237,0.080730, -0.088688,0.049026, -0.094739,0.030294, -0.102488,0.029755, +NEWSHAPE, 269, 1, 1, -0.120244,0.033095, -0.181823,0.053216, -0.199420,0.068325, -0.189994,0.093330, -0.169179,0.099289, -0.138237,0.080730, -0.088688,0.049026, -0.094739,0.030294, -0.102488,0.029755, // shDogFrontLeg -NEWSHAPE, 270, 1, 1, 0.050083,0.064552, 0.044492,0.047829, 0.018900,0.044470, 0.002224,0.057826, 0.003338,0.075664, 0.020042,0.089074, 0.034520,0.086856, 0.040087,0.084629, 0.052335,0.076832, +NEWSHAPE, 270, 1, 1, 0.050083,0.064552, 0.044492,0.047829, 0.018900,0.044470, 0.002224,0.057826, 0.003338,0.075664, 0.020042,0.089074, 0.034520,0.086856, 0.040087,0.084629, 0.052335,0.076832, // shDogRearLeg -NEWSHAPE, 271, 1, 1, -0.147691,0.079440, -0.120617,0.078177, -0.102586,0.061329, -0.100284,0.036771, -0.112610,0.034564, -0.133966,0.033491, -0.153171,0.040249, -0.157810,0.067153, +NEWSHAPE, 271, 1, 1, -0.147691,0.079440, -0.120617,0.078177, -0.102586,0.061329, -0.100284,0.036771, -0.112610,0.034564, -0.133966,0.033491, -0.153171,0.040249, -0.157810,0.067153, // shWolfFrontPaw -NEWSHAPE, 272, 1, 1, 0.044056,0.084808, 0.114167,0.147973, 0.121635,0.170511, 0.126416,0.144158, 0.148897,0.151675, 0.134077,0.125212, 0.157522,0.115923, 0.123842,0.098410, 0.074868,0.045141, 0.056665,0.043462, 0.046213,0.055016, 0.039626,0.070996, +NEWSHAPE, 272, 1, 1, 0.044056,0.084808, 0.114167,0.147973, 0.121635,0.170511, 0.126416,0.144158, 0.148897,0.151675, 0.134077,0.125212, 0.157522,0.115923, 0.123842,0.098410, 0.074868,0.045141, 0.056665,0.043462, 0.046213,0.055016, 0.039626,0.070996, // shWolfRearPaw -NEWSHAPE, 273, 1, 1, -0.228714,0.033559, -0.341382,0.086496, -0.314606,0.087990, -0.326169,0.109775, -0.303428,0.105707, -0.309485,0.135882, -0.287964,0.110057, -0.198121,0.069332, -0.187804,0.046735, -0.200044,0.035736, -0.213491,0.031344, +NEWSHAPE, 273, 1, 1, -0.228714,0.033559, -0.341382,0.086496, -0.314606,0.087990, -0.326169,0.109775, -0.303428,0.105707, -0.309485,0.135882, -0.287964,0.110057, -0.198121,0.069332, -0.187804,0.046735, -0.200044,0.035736, -0.213491,0.031344, // shWolfFrontLeg -NEWSHAPE, 274, 1, 1, 0.043124,0.086241, 0.073285,0.082608, 0.078919,0.072022, 0.084577,0.049131, 0.058349,0.030045, 0.038327,0.023872, 0.019412,0.043794, 0.027622,0.072180, +NEWSHAPE, 274, 1, 1, 0.043124,0.086241, 0.073285,0.082608, 0.078919,0.072022, 0.084577,0.049131, 0.058349,0.030045, 0.038327,0.023872, 0.019412,0.043794, 0.027622,0.072180, // shWolfRearLeg -NEWSHAPE, 275, 1, 1, -0.209981,0.074314, -0.168422,0.064352, -0.158696,0.031877, -0.173682,0.018683, -0.192122,0.019786, -0.221918,0.028600, -0.240782,0.055614, -0.225734,0.072687, +NEWSHAPE, 275, 1, 1, -0.209981,0.074314, -0.168422,0.064352, -0.158696,0.031877, -0.173682,0.018683, -0.192122,0.019786, -0.221918,0.028600, -0.240782,0.055614, -0.225734,0.072687, // shYetiFoot -NEWSHAPE, 276, 1, 1, -0.099231,0.063552, -0.100435,0.085928, -0.045726,0.113758, -0.046823,0.105908, 0.034547,0.103641, -0.006678,0.083479, 0.042290,0.067886, -0.004448,0.057826, 0.046713,0.042264, -0.033354,0.037802, -0.081272,0.036739, +NEWSHAPE, 276, 1, 1, -0.099231,0.063552, -0.100435,0.085928, -0.045726,0.113758, -0.046823,0.105908, 0.034547,0.103641, -0.006678,0.083479, 0.042290,0.067886, -0.004448,0.057826, 0.046713,0.042264, -0.033354,0.037802, -0.081272,0.036739, // inspired by "Reptiles" by M. C. Escher // shReptile[0][0] @@ -4023,33 +2008,33 @@ NEWSHAPE, 279, 1, 1, -0.252522,-0.071341, -0.245933,-0.086380, -0.256407,-0.1081 NEWSHAPE, 280, 1, 1, -0.258740,0.011957, -0.254596,-0.009727, -0.273495,-0.033201, -0.294516,-0.034869, -0.307872,-0.015362, -0.306068,0.008710, -0.288916,0.020706, // shReptile[1][0] NEWSHAPE, 281, 1, 1, 0.267913,-0.363961, 0.103423,-0.407902, 0.029926,-0.285688, 0.004562,-0.182498, -0.089218,-0.185966, -0.096986,-0.367985, -0.248327,-0.455994, -0.256139,-0.447327, -0.237682,-0.433175, -0.257547,-0.445407, -0.265780,-0.439947, -0.250475,-0.422667, -0.268312,-0.437951, -0.275164,-0.436243, -0.203450,-0.358525, -0.187185,-0.110088, -0.484119,-0.068248, -0.424486,0.012521, -0.323946,-0.003100, -0.200798,0.033484, -0.244734,0.222076, -0.357719,0.170021, -0.365522,0.192816, -0.333464,0.208694, -0.367623,0.196994, -0.371956,0.213819, -0.339807,0.232001, -0.373008,0.216200, -0.376113,0.227855, -0.287818,0.311052, -0.201927,0.336476, -0.162665,0.301719, -0.123143,0.195801, -0.085354,0.085987, 0.106772,0.103301, 0.235043,0.288663, 0.398887,0.202650, 0.392371,0.193980, 0.362197,0.205391, 0.393392,0.192794, 0.388672,0.184045, 0.354985,0.191178, 0.388962,0.181776, 0.383857,0.173107, 0.273977,0.186438, 0.201147,0.007597, 0.385514,-0.014104, 0.452378,-0.139100, 0.441679,-0.165374, 0.286863,-0.196581, 0.154996,-0.121531, 0.112780,-0.178884, 0.130676,-0.244138, 0.233120,-0.294200, 0.242235,-0.311655, 0.187156,-0.319959, 0.242817,-0.315142, 0.253181,-0.338344, 0.193625,-0.348671, 0.254919,-0.341938, -NEWSHAPE, 282, 1, 1, 0.326447,-0.044290, 0.268772,-0.053597, 0.235899,-0.055845, 0.171515,-0.048557, 0.088801,-0.018246, 0.037774,0.004993, -0.027541,0.016777, -0.088937,0.009667, -0.172537,-0.011240, -0.219668,-0.017765, -0.282928,-0.032376, -0.337206,-0.032470, -0.385877,-0.034804, -0.440028,-0.044474, -0.371779,-0.058999, -0.311902,-0.066325, -0.248815,-0.064253, -0.177727,-0.063011, -0.059856,-0.073519, 0.027306,-0.080984, 0.112403,-0.081788, 0.185321,-0.082903, 0.246089,-0.091503, 0.280118,-0.131876, 0.327222,-0.147933, 0.374578,-0.123044, 0.364318,-0.067249, -NEWSHAPE, 283, 7, 1, 0.027415,-0.009216, -NEWSHAPE, 284, 7, 1, 0.023426,0.005270, +NEWSHAPE, 282, 1, 1, 0.326447,-0.044290, 0.268772,-0.053597, 0.235899,-0.055845, 0.171515,-0.048557, 0.088801,-0.018246, 0.037774,0.004993, -0.027541,0.016777, -0.088937,0.009667, -0.172537,-0.011240, -0.219668,-0.017765, -0.282928,-0.032376, -0.337206,-0.032470, -0.385877,-0.034804, -0.440028,-0.044474, -0.371779,-0.058999, -0.311902,-0.066325, -0.248815,-0.064253, -0.177727,-0.063011, -0.059856,-0.073519, 0.027306,-0.080984, 0.112403,-0.081788, 0.185321,-0.082903, 0.246089,-0.091503, 0.280118,-0.131876, 0.327222,-0.147933, 0.374578,-0.123044, 0.364318,-0.067249, +NEWSHAPE, 283, 7, 1, 0.027415,-0.009216, +NEWSHAPE, 284, 7, 1, 0.023426,0.005270, // shReptile[2][0] NEWSHAPE, 285, 1, 1, 0.264174,-0.393902, 0.220100,-0.344820, 0.196314,-0.232131, 0.044844,-0.186655, 0.015265,-0.205081, -0.003936,-0.333213, -0.136120,-0.408084, -0.149930,-0.405620, -0.177207,-0.243366, -0.085946,-0.199911, -0.087381,-0.147154, -0.302464,-0.169877, -0.302092,-0.297549, -0.327187,-0.293024, -0.330841,-0.249219, -0.329911,-0.292299, -0.353906,-0.290880, -0.354914,-0.247858, -0.357304,-0.291341, -0.377715,-0.287105, -0.387134,-0.104888, -0.106049,-0.041562, -0.095545,0.040016, -0.302051,0.163655, -0.332611,0.319950, -0.310541,0.349402, -0.289857,0.281329, -0.303842,0.352541, -0.278525,0.372081, -0.261882,0.313955, -0.275092,0.376585, -0.247719,0.398573, -0.239799,0.336833, -0.214496,0.215823, -0.168074,0.170579, -0.067435,0.196926, 0.028714,0.266822, 0.015830,0.400766, 0.131125,0.319617, 0.148574,0.162459, 0.283651,0.088527, 0.295994,0.169290, 0.331188,0.179878, 0.329752,0.145196, 0.335770,0.181014, 0.363641,0.191082, 0.365077,0.157473, 0.367064,0.192650, 0.395018,0.204633, 0.405110,0.041551, 0.311991,0.015994, 0.195242,0.016634, 0.122740,-0.085748, 0.261020,-0.098708, 0.286694,-0.182139, 0.332188,-0.307144, 0.306926,-0.340004, 0.279202,-0.289607, 0.302360,-0.343229, 0.284083,-0.365340, 0.252717,-0.314768, 0.279532,-0.371945, -NEWSHAPE, 286, 1, 1, -0.127096,-0.255815, -0.091894,-0.241092, -0.073203,-0.219108, -0.050918,-0.160430, -0.046653,-0.121421, -0.028140,-0.044121, -0.017641,0.026545, 0.022513,0.133022, 0.050663,0.193120, 0.058157,0.270962, 0.054214,0.311270, 0.046360,0.353789, 0.068493,0.316069, 0.093492,0.242457, 0.080840,0.108339, 0.056390,0.006556, 0.031831,-0.062813, -0.001836,-0.143721, -0.034334,-0.239758, -0.041121,-0.297513, -0.071677,-0.333221, -0.108488,-0.343266, -0.135448,-0.293017, -NEWSHAPE, 287, 7, 1, -0.021896,-0.012396, -NEWSHAPE, 288, 7, 1, -0.023484,-0.012828, +NEWSHAPE, 286, 1, 1, -0.127096,-0.255815, -0.091894,-0.241092, -0.073203,-0.219108, -0.050918,-0.160430, -0.046653,-0.121421, -0.028140,-0.044121, -0.017641,0.026545, 0.022513,0.133022, 0.050663,0.193120, 0.058157,0.270962, 0.054214,0.311270, 0.046360,0.353789, 0.068493,0.316069, 0.093492,0.242457, 0.080840,0.108339, 0.056390,0.006556, 0.031831,-0.062813, -0.001836,-0.143721, -0.034334,-0.239758, -0.041121,-0.297513, -0.071677,-0.333221, -0.108488,-0.343266, -0.135448,-0.293017, +NEWSHAPE, 287, 7, 1, -0.021896,-0.012396, +NEWSHAPE, 288, 7, 1, -0.023484,-0.012828, // shReptile[3][0] -NEWSHAPE, 289, 1, 1, 0.276554,-0.041210, 0.310457,0.039428, 0.287105,0.072645, 0.169859,-0.000837, 0.151648,-0.089695, 0.191477,-0.149470, 0.280888,-0.183226, 0.341099,-0.338656, 0.273683,-0.366029, 0.209539,-0.273223, 0.105852,-0.172588, -0.061113,-0.279714, -0.013642,-0.342451, -0.058157,-0.375558, -0.090346,-0.316684, -0.061781,-0.378853, -0.101453,-0.409200, -0.128968,-0.341003, -0.106321,-0.412460, -0.147327,-0.447396, -0.196876,-0.316767, -0.070150,-0.182145, -0.133594,-0.036417, -0.294753,-0.151579, -0.409075,-0.148250, -0.444408,-0.105385, -0.374677,-0.113506, -0.443332,-0.098946, -0.434173,-0.078381, -0.367706,-0.088453, -0.432558,-0.074716, -0.428663,-0.053306, -0.293683,-0.069123, -0.141662,0.058415, -0.281560,0.174905, -0.249829,0.284696, -0.226324,0.297042, -0.119112,0.263418, -0.075663,0.144858, -0.021279,0.097533, 0.064463,0.189563, 0.011865,0.335469, -0.005820,0.393456, 0.044789,0.390508, 0.065571,0.321367, 0.047251,0.390455, 0.090068,0.386431, 0.103507,0.317601, 0.093275,0.386149, 0.130199,0.386756, 0.148881,0.163862, 0.089483,0.079942, 0.135587,0.047323, 0.293067,0.168426, 0.408382,0.092603, 0.384168,0.007719, 0.315700,-0.045433, 0.346149,0.015698, 0.313006,-0.045307, 0.295254,-0.041824, 0.326732,0.017229, 0.292941,-0.042281, -NEWSHAPE, 290, 1, 1, -0.130824,0.101694, -0.057151,-0.007670, 0.115177,-0.160650, 0.211980,-0.236858, 0.296693,-0.311866, 0.232978,-0.219581, 0.138912,-0.105664, -0.002855,0.058899, -0.100445,0.121752, -0.136992,0.183934, -0.144345,0.222791, -0.168225,0.256064, -0.232048,0.242113, -0.236767,0.213008, -0.234529,0.179695, -0.198210,0.146185, -0.167694,0.143175, -NEWSHAPE, 291, 7, 1, -0.019211,0.011243, -NEWSHAPE, 292, 7, 1, -0.017430,0.009904, +NEWSHAPE, 289, 1, 1, 0.276554,-0.041210, 0.310457,0.039428, 0.287105,0.072645, 0.169859,-0.000837, 0.151648,-0.089695, 0.191477,-0.149470, 0.280888,-0.183226, 0.341099,-0.338656, 0.273683,-0.366029, 0.209539,-0.273223, 0.105852,-0.172588, -0.061113,-0.279714, -0.013642,-0.342451, -0.058157,-0.375558, -0.090346,-0.316684, -0.061781,-0.378853, -0.101453,-0.409200, -0.128968,-0.341003, -0.106321,-0.412460, -0.147327,-0.447396, -0.196876,-0.316767, -0.070150,-0.182145, -0.133594,-0.036417, -0.294753,-0.151579, -0.409075,-0.148250, -0.444408,-0.105385, -0.374677,-0.113506, -0.443332,-0.098946, -0.434173,-0.078381, -0.367706,-0.088453, -0.432558,-0.074716, -0.428663,-0.053306, -0.293683,-0.069123, -0.141662,0.058415, -0.281560,0.174905, -0.249829,0.284696, -0.226324,0.297042, -0.119112,0.263418, -0.075663,0.144858, -0.021279,0.097533, 0.064463,0.189563, 0.011865,0.335469, -0.005820,0.393456, 0.044789,0.390508, 0.065571,0.321367, 0.047251,0.390455, 0.090068,0.386431, 0.103507,0.317601, 0.093275,0.386149, 0.130199,0.386756, 0.148881,0.163862, 0.089483,0.079942, 0.135587,0.047323, 0.293067,0.168426, 0.408382,0.092603, 0.384168,0.007719, 0.315700,-0.045433, 0.346149,0.015698, 0.313006,-0.045307, 0.295254,-0.041824, 0.326732,0.017229, 0.292941,-0.042281, +NEWSHAPE, 290, 1, 1, -0.130824,0.101694, -0.057151,-0.007670, 0.115177,-0.160650, 0.211980,-0.236858, 0.296693,-0.311866, 0.232978,-0.219581, 0.138912,-0.105664, -0.002855,0.058899, -0.100445,0.121752, -0.136992,0.183934, -0.144345,0.222791, -0.168225,0.256064, -0.232048,0.242113, -0.236767,0.213008, -0.234529,0.179695, -0.198210,0.146185, -0.167694,0.143175, +NEWSHAPE, 291, 7, 1, -0.019211,0.011243, +NEWSHAPE, 292, 7, 1, -0.017430,0.009904, // shReptile[4][0] NEWSHAPE, 293, 3, 1, 0.000458,0.307912, 0.204532,0.422468, 0.260617,0.384080, 0.177355,0.114658, 0.351515,0.031931, 0.411778,0.098785, 0.502998,0.070318, 0.433450,0.021025, 0.502176,0.057577, 0.563080,-0.085829, 0.478445,-0.055947, 0.558143,-0.094808, 0.534739,-0.111613, 0.420992,-0.057813, -NEWSHAPE, 294, 3, 1, -0.169183,-0.225979, -0.187272,-0.078673, -0.281255,0.003711, -0.095795,0.040777, -NEWSHAPE, 295, 7, 1, -0.019211,0.011243, -NEWSHAPE, 296, 7, 1, -0.017430,0.009904, +NEWSHAPE, 294, 3, 1, -0.169183,-0.225979, -0.187272,-0.078673, -0.281255,0.003711, -0.095795,0.040777, +NEWSHAPE, 295, 7, 1, -0.019211,0.011243, +NEWSHAPE, 296, 7, 1, -0.017430,0.009904, // shReptileBody NEWSHAPE, 297, 1, 1, 0.207893,0.052816, 0.154587,0.095216, 0.118624,0.121981, 0.077111,0.131872, 0.011141,0.103613, -0.040061,0.066768, -0.052300,0.056751, -0.041318,0.136239, -0.097277,0.126349, -0.146652,0.094036, -0.214827,0.059612, -0.280943,0.028321, -0.353759,-0.002290, -0.410588,-0.042794, -0.446484,-0.083934, -0.379856,-0.069065, -0.301215,-0.057970, -0.243697,-0.056411, -0.176013,-0.072872, -0.133073,-0.090579, -0.099458,-0.115103, -0.065944,-0.139713, -0.052291,-0.050065, 0.014488,-0.109218, 0.077073,-0.123987, 0.130941,-0.109677, 0.162455,-0.085149, 0.218159,-0.035985, // shReptileHead -NEWSHAPE, 298, 1, 2, 0.471485,-0.015757, 0.288467,-0.098421, 0.170941,-0.033237, +NEWSHAPE, 298, 1, 2, 0.471485,-0.015757, 0.288467,-0.098421, 0.170941,-0.033237, // shReptileFrontFoot -NEWSHAPE, 299, 1, 1, 0.250278,0.167235, 0.238951,0.195456, 0.195709,0.200188, 0.240500,0.197580, 0.232498,0.224361, 0.186427,0.225955, 0.227016,0.226262, 0.227409,0.260408, 0.102772,0.258192, 0.080173,0.252350, 0.059570,0.224171, 0.051410,0.202351, 0.074841,0.180175, 0.114709,0.161348, +NEWSHAPE, 299, 1, 1, 0.250278,0.167235, 0.238951,0.195456, 0.195709,0.200188, 0.240500,0.197580, 0.232498,0.224361, 0.186427,0.225955, 0.227016,0.226262, 0.227409,0.260408, 0.102772,0.258192, 0.080173,0.252350, 0.059570,0.224171, 0.051410,0.202351, 0.074841,0.180175, 0.114709,0.161348, // shReptileRearFoot -NEWSHAPE, 300, 1, 1, -0.067876,0.206615, -0.114088,0.181539, -0.272616,0.185109, -0.253628,0.222368, -0.216050,0.219537, -0.249625,0.225089, -0.240714,0.244505, -0.205182,0.244381, -0.232919,0.248821, -0.217457,0.272915, -0.099816,0.264976, -0.065058,0.238612, +NEWSHAPE, 300, 1, 1, -0.067876,0.206615, -0.114088,0.181539, -0.272616,0.185109, -0.253628,0.222368, -0.216050,0.219537, -0.249625,0.225089, -0.240714,0.244505, -0.205182,0.244381, -0.232919,0.248821, -0.217457,0.272915, -0.099816,0.264976, -0.065058,0.238612, // shReptileFrontLeg NEWSHAPE, 301, 1, 1, 0.047213,0.212458, 0.077946,0.248522, 0.130365,0.256196, 0.141554,0.241207, 0.148626,0.179026, 0.127519,0.104028, 0.091374,0.056830, 0.045625,0.063430, 0.028944,0.082379, 0.036887,0.150900, // shReptileRearLeg @@ -4057,164 +2042,162 @@ NEWSHAPE, 302, 1, 1, -0.098128,0.262832, -0.068071,0.236831, -0.053685,0.166798, // shReptileTail NEWSHAPE, 303, 1, 1, -0.419630,-0.067234, -0.351432,-0.034342, -0.278537,-0.003397, -0.200906,0.024692, -0.083503,0.034515, 0.041138,0.030019, 0.138446,0.017864, 0.197445,0.006731, 0.094656,-0.005568, 0.007778,0.003333, -0.085713,-0.003339, -0.197452,-0.013463, -0.280927,-0.023788, // shReptileEye -NEWSHAPE, 304, 1, 1, 0.288102,0.032160, 0.268177,0.043655, 0.265884,0.058115, 0.276356,0.070881, 0.290293,0.073602, 0.310905,0.064370, 0.308359,0.045081, +NEWSHAPE, 304, 1, 1, 0.288102,0.032160, 0.268177,0.043655, 0.265884,0.058115, 0.276356,0.070881, 0.290293,0.073602, 0.310905,0.064370, 0.308359,0.045081, // shDodeca, NEWSHAPE, 305, 5, 2, 0.123140,0.087570, 0.151044,0.006085, 0.141348,0.003141, 0.091602,0.003971, 0.064937,0.045676, 0.057217,0.044013, 0.086006,0.002395, 0.086006,-0.002395, // shBugLeg -NEWSHAPE, 306, 1, 1, -0.188132,0.071590, -0.106107,0.109975, -0.020337,0.032429, -0.010997,-0.052235, 0.027591,-0.128573, -0.009955,-0.162603, -0.123175,-0.156466, -0.129658,-0.186975, -0.003881,-0.192409, 0.048636,-0.145908, 0.045758,-0.106953, 0.012643,-0.040678, 0.031326,0.003847, 0.131788,0.118499, 0.134832,0.147039, 0.121802,0.186319, 0.018400,0.244215, 0.011672,0.216213, 0.079288,0.174654, 0.095323,0.160720, 0.088932,0.115998, 0.010444,0.037927, -0.102392,0.137814, +NEWSHAPE, 306, 1, 1, -0.188132,0.071590, -0.106107,0.109975, -0.020337,0.032429, -0.010997,-0.052235, 0.027591,-0.128573, -0.009955,-0.162603, -0.123175,-0.156466, -0.129658,-0.186975, -0.003881,-0.192409, 0.048636,-0.145908, 0.045758,-0.106953, 0.012643,-0.040678, 0.031326,0.003847, 0.131788,0.118499, 0.134832,0.147039, 0.121802,0.186319, 0.018400,0.244215, 0.011672,0.216213, 0.079288,0.174654, 0.095323,0.160720, 0.088932,0.115998, 0.010444,0.037927, -0.102392,0.137814, // shBugAntenna -NEWSHAPE, 307, 1, 2, -0.037388,-0.035738, 0.121931,-0.041931, 0.148538,-0.114729, 0.171226,-0.135647, 0.193388,-0.143787, 0.206926,-0.136091, 0.172174,-0.118855, 0.163075,-0.108717, 0.147190,-0.083002, 0.129680,-0.024281, +NEWSHAPE, 307, 1, 2, -0.037388,-0.035738, 0.121931,-0.041931, 0.148538,-0.114729, 0.171226,-0.135647, 0.193388,-0.143787, 0.206926,-0.136091, 0.172174,-0.118855, 0.163075,-0.108717, 0.147190,-0.083002, 0.129680,-0.024281, // shTrylobiteBody -NEWSHAPE, 308, 1, 2, 0.196119,0.032415, 0.090349,0.051694, 0.014858,0.048341, -0.084517,0.042642, -0.099309,0.031132, -0.146522,0.055533, -0.190296,0.065896, -0.234005,0.061772, -0.245550,0.053775, -0.212120,0.048191, -0.163612,0.030837, -0.143014,0.007540, +NEWSHAPE, 308, 1, 2, 0.196119,0.032415, 0.090349,0.051694, 0.014858,0.048341, -0.084517,0.042642, -0.099309,0.031132, -0.146522,0.055533, -0.190296,0.065896, -0.234005,0.061772, -0.245550,0.053775, -0.212120,0.048191, -0.163612,0.030837, -0.143014,0.007540, // shTrylobiteFrontClaw -NEWSHAPE, 309, 1, 1, 0.162924,0.164217, 0.134529,0.219357, 0.096861,0.266620, 0.040792,0.297621, 0.018375,0.280440, 0.073270,0.189478, 0.089713,0.132980, 0.111928,0.119234, 0.144100,0.124454, +NEWSHAPE, 309, 1, 1, 0.162924,0.164217, 0.134529,0.219357, 0.096861,0.266620, 0.040792,0.297621, 0.018375,0.280440, 0.073270,0.189478, 0.089713,0.132980, 0.111928,0.119234, 0.144100,0.124454, // shTrylobiteRearClaw -NEWSHAPE, 310, 1, 1, -0.014785,0.165073, -0.030220,0.198964, -0.060610,0.240281, -0.086102,0.254842, -0.112355,0.254248, -0.091511,0.215066, -0.070034,0.152230, -0.057129,0.134268, -0.041113,0.127236, -0.022776,0.135081, +NEWSHAPE, 310, 1, 1, -0.014785,0.165073, -0.030220,0.198964, -0.060610,0.240281, -0.086102,0.254842, -0.112355,0.254248, -0.091511,0.215066, -0.070034,0.152230, -0.057129,0.134268, -0.041113,0.127236, -0.022776,0.135081, // shTrylobiteFrontLeg -NEWSHAPE, 311, 1, 1, 0.196620,0.034345, 0.161944,0.165955, 0.131681,0.185106, 0.105471,0.183927, 0.090859,0.133459, 0.094842,0.063710, 0.082033,0.026880, 0.114740,0.000635, 0.168794,0.000330, +NEWSHAPE, 311, 1, 1, 0.196620,0.034345, 0.161944,0.165955, 0.131681,0.185106, 0.105471,0.183927, 0.090859,0.133459, 0.094842,0.063710, 0.082033,0.026880, 0.114740,0.000635, 0.168794,0.000330, // shTrylobiteRearLeg -NEWSHAPE, 312, 1, 1, 0.014403,0.049247, -0.005676,0.101370, -0.014283,0.164470, -0.036662,0.174292, -0.054954,0.173745, -0.070446,0.153946, -0.074749,0.083574, -0.082124,0.043654, -0.052716,0.016562, -0.009043,0.013419, +NEWSHAPE, 312, 1, 1, 0.014403,0.049247, -0.005676,0.101370, -0.014283,0.164470, -0.036662,0.174292, -0.054954,0.173745, -0.070446,0.153946, -0.074749,0.083574, -0.082124,0.043654, -0.052716,0.016562, -0.009043,0.013419, // shLeafFloor, -NEWSHAPE, 313, 3, 1, -0.124709,0.213831, -0.127071,0.274094, -0.099723,0.369490, -0.023215,0.462261, 0.072785,0.531016, 0.152171,0.570046, 0.244072,0.583021, 0.278329,0.581281, 0.289459,0.567347, 0.241111,0.530198, 0.189086,0.449607, 0.153336,0.354939, 0.133803,0.281218, 0.127619,0.205626, 0.145868,0.133361, 0.140560,0.107526, 0.106341,0.086253, 0.061487,0.046396, 0.029920,0.018377, 0.013295,0.007733, 0.050569,0.013990, 0.166612,0.102510, +NEWSHAPE, 313, 3, 1, -0.124709,0.213831, -0.127071,0.274094, -0.099723,0.369490, -0.023215,0.462261, 0.072785,0.531016, 0.152171,0.570046, 0.244072,0.583021, 0.278329,0.581281, 0.289459,0.567347, 0.241111,0.530198, 0.189086,0.449607, 0.153336,0.354939, 0.133803,0.281218, 0.127619,0.205626, 0.145868,0.133361, 0.140560,0.107526, 0.106341,0.086253, 0.061487,0.046396, 0.029920,0.018377, 0.013295,0.007733, 0.050569,0.013990, 0.166612,0.102510, // shLeafFloor, NEWSHAPE, 314, 1, 1, 0, 0, // shBullBody -NEWSHAPE, 315, 1, 2, -0.399002,0.000618, -0.412389,-0.011435, -0.383217,-0.004139, -0.396241,-0.020642, -0.365704,-0.007876, -0.335517,-0.003463, -0.306649,-0.005631, -0.286501,-0.014485, -0.270113,-0.034709, -0.263139,-0.079331, -0.257114,-0.110215, -0.247630,-0.125790, -0.231094,-0.131733, -0.215499,-0.134849, -0.198771,-0.130780, -0.184961,-0.120425, -0.176890,-0.110874, -0.170135,-0.107553, -0.128764,-0.126896, -0.138805,-0.126406, -0.089067,-0.151289, -0.099830,-0.154113, -0.066698,-0.158059, -0.043468,-0.159303, -0.027802,-0.156801, -0.033201,-0.163796, -0.009201,-0.151129, 0.003865,-0.145169, 0.002259,-0.154029, 0.022833,-0.142371, 0.035183,-0.139200, 0.057625,-0.133866, 0.085702,-0.138411, 0.106606,-0.143670, 0.123715,-0.148158, 0.139656,-0.143049, 0.152591,-0.131020, 0.170000,-0.108676, 0.194767,-0.076789, 0.218502,-0.057643, +NEWSHAPE, 315, 1, 2, -0.399002,0.000618, -0.412389,-0.011435, -0.383217,-0.004139, -0.396241,-0.020642, -0.365704,-0.007876, -0.335517,-0.003463, -0.306649,-0.005631, -0.286501,-0.014485, -0.270113,-0.034709, -0.263139,-0.079331, -0.257114,-0.110215, -0.247630,-0.125790, -0.231094,-0.131733, -0.215499,-0.134849, -0.198771,-0.130780, -0.184961,-0.120425, -0.176890,-0.110874, -0.170135,-0.107553, -0.128764,-0.126896, -0.138805,-0.126406, -0.089067,-0.151289, -0.099830,-0.154113, -0.066698,-0.158059, -0.043468,-0.159303, -0.027802,-0.156801, -0.033201,-0.163796, -0.009201,-0.151129, 0.003865,-0.145169, 0.002259,-0.154029, 0.022833,-0.142371, 0.035183,-0.139200, 0.057625,-0.133866, 0.085702,-0.138411, 0.106606,-0.143670, 0.123715,-0.148158, 0.139656,-0.143049, 0.152591,-0.131020, 0.170000,-0.108676, 0.194767,-0.076789, 0.218502,-0.057643, // shBullHorn -NEWSHAPE, 316, 1, 1, 0.321702,-0.078714, 0.329603,-0.122456, 0.342058,-0.140037, 0.360561,-0.149754, 0.379070,-0.152553, 0.395131,-0.150636, 0.423718,-0.142016, 0.448897,-0.133266, 0.441750,-0.150756, 0.426899,-0.163295, 0.403192,-0.169643, 0.371044,-0.173385, 0.345193,-0.167994, 0.313418,-0.152134, 0.303510,-0.135781, 0.297242,-0.118441, 0.292244,-0.102342, 0.308799,-0.096856, +NEWSHAPE, 316, 1, 1, 0.321702,-0.078714, 0.329603,-0.122456, 0.342058,-0.140037, 0.360561,-0.149754, 0.379070,-0.152553, 0.395131,-0.150636, 0.423718,-0.142016, 0.448897,-0.133266, 0.441750,-0.150756, 0.426899,-0.163295, 0.403192,-0.169643, 0.371044,-0.173385, 0.345193,-0.167994, 0.313418,-0.152134, 0.303510,-0.135781, 0.297242,-0.118441, 0.292244,-0.102342, 0.308799,-0.096856, // shBullRearHoof -NEWSHAPE, 317, 1, 1, -0.218107,-0.148042, -0.243390,-0.132449, -0.246496,-0.105156, -0.238188,-0.090308, -0.226562,-0.085665, -0.207006,-0.088878, -0.189916,-0.100015, -0.189059,-0.127164, -0.196081,-0.138609, +NEWSHAPE, 317, 1, 1, -0.218107,-0.148042, -0.243390,-0.132449, -0.246496,-0.105156, -0.238188,-0.090308, -0.226562,-0.085665, -0.207006,-0.088878, -0.189916,-0.100015, -0.189059,-0.127164, -0.196081,-0.138609, // shBullFrontHoof NEWSHAPE, 318, 1, 1, 0.110547,-0.088215, 0.135310,-0.087225, 0.144428,-0.099644, 0.144636,-0.125576, 0.135691,-0.137934, 0.121038,-0.142332, 0.104105,-0.138807, 0.088308,-0.128550, 0.088231,-0.113919, 0.096026,-0.102725, // shBullHead -NEWSHAPE, 319, 1, 2, 0.334622,-0.050250, 0.307607,-0.096839, 0.281739,-0.111332, 0.258180,-0.106443, 0.236906,-0.077841, 0.214842,-0.061865, 0.184962,-0.040355, 0.198626,-0.028054, 0.195166,-0.013460, 0.181470,-0.002240, +NEWSHAPE, 319, 1, 2, 0.334622,-0.050250, 0.307607,-0.096839, 0.281739,-0.111332, 0.258180,-0.106443, 0.236906,-0.077841, 0.214842,-0.061865, 0.184962,-0.040355, 0.198626,-0.028054, 0.195166,-0.013460, 0.181470,-0.002240, // shButterflyBody -NEWSHAPE, 320, 1, 2, 0.176732,-0.004396, 0.195200,-0.015935, 0.201979,-0.028577, 0.202087,-0.043427, 0.198784,-0.050031, 0.198704,-0.041226, 0.196945,-0.030227, 0.190734,-0.019233, 0.170044,-0.008793, 0.163946,-0.020339, 0.151703,-0.020894, 0.140009,-0.012649, 0.122852,-0.026418, 0.108465,-0.031392, 0.017314,-0.028016, 0.000470,-0.019079, -0.088765,-0.013614, -0.095608,-0.005678, +NEWSHAPE, 320, 1, 2, 0.176732,-0.004396, 0.195200,-0.015935, 0.201979,-0.028577, 0.202087,-0.043427, 0.198784,-0.050031, 0.198704,-0.041226, 0.196945,-0.030227, 0.190734,-0.019233, 0.170044,-0.008793, 0.163946,-0.020339, 0.151703,-0.020894, 0.140009,-0.012649, 0.122852,-0.026418, 0.108465,-0.031392, 0.017314,-0.028016, 0.000470,-0.019079, -0.088765,-0.013614, -0.095608,-0.005678, // shButterflyWing -NEWSHAPE, 321, 1, 2, 0.101344,-0.004988, 0.178342,-0.088519, 0.202439,-0.133112, 0.222376,-0.199882, 0.236304,-0.245909, 0.228546,-0.251735, 0.203290,-0.253007, 0.178432,-0.236979, 0.151432,-0.218854, 0.124491,-0.196352, 0.092144,-0.173026, 0.066111,-0.165612, 0.055720,-0.012369, 0.055445,-0.104987, 0.048098,-0.123101, 0.031857,-0.142619, 0.017719,-0.157675, -0.015575,-0.171093, -0.037946,-0.176348, -0.059503,-0.171340, -0.086100,-0.144824, -0.102753,-0.105546, -0.111188,-0.079719, -0.110326,-0.064989, -0.025725,-0.012627, -0.023585,-0.006998, +NEWSHAPE, 321, 1, 2, 0.101344,-0.004988, 0.178342,-0.088519, 0.202439,-0.133112, 0.222376,-0.199882, 0.236304,-0.245909, 0.228546,-0.251735, 0.203290,-0.253007, 0.178432,-0.236979, 0.151432,-0.218854, 0.124491,-0.196352, 0.092144,-0.173026, 0.066111,-0.165612, 0.055720,-0.012369, 0.055445,-0.104987, 0.048098,-0.123101, 0.031857,-0.142619, 0.017719,-0.157675, -0.015575,-0.171093, -0.037946,-0.176348, -0.059503,-0.171340, -0.086100,-0.144824, -0.102753,-0.105546, -0.111188,-0.079719, -0.110326,-0.064989, -0.025725,-0.012627, -0.023585,-0.006998, // shGadflyBody -NEWSHAPE, 322, 1, 2, 0.170044,-0.008793, 0.163946,-0.020339, 0.151703,-0.020894, 0.140009,-0.012649, 0.122852,-0.026418, 0.108465,-0.031392, 0.017314,-0.028016, 0.000470,-0.019079, +NEWSHAPE, 322, 1, 2, 0.170044,-0.008793, 0.163946,-0.020339, 0.151703,-0.020894, 0.140009,-0.012649, 0.122852,-0.026418, 0.108465,-0.031392, 0.017314,-0.028016, 0.000470,-0.019079, // shGadflyWing -NEWSHAPE, 323, 1, 2, 0.130571,-0.024552, -0.001114,-0.108092, -0.042319,-0.085751, -0.047826,-0.042265, 0.091301,-0.002227, 0.124928,-0.003346, +NEWSHAPE, 323, 1, 2, 0.130571,-0.024552, -0.001114,-0.108092, -0.042319,-0.085751, -0.047826,-0.042265, 0.091301,-0.002227, 0.124928,-0.003346, // shGadflyEye -NEWSHAPE, 324, 1, 1, 0.168968,-0.004476, 0.175788,-0.012316, 0.172390,-0.020150, 0.165580,-0.020138, 0.161038,-0.013420, 0.161033,-0.007828, +NEWSHAPE, 324, 1, 1, 0.168968,-0.004476, 0.175788,-0.012316, 0.172390,-0.020150, 0.165580,-0.020138, 0.161038,-0.013420, 0.161033,-0.007828, // inspired by "Seven Butterflies Pattern" by Doug Dunham (in turn inspired by M. C. Escher) // http://www.bridgesmathart.org/art-exhibits/bridges2001/dunham1/index.html // shButterflyFloor[0] -NEWSHAPE, 325, 3, 1, 0.003906,-0.017741, -0.005665,-0.023874, -0.001296,-0.059255, 0.008110,-0.088485, 0.021638,-0.119244, 0.001998,-0.123781, -0.025603,-0.125790, -0.042514,-0.132101, -0.062642,-0.134604, -0.080079,-0.114436, -0.119123,-0.090010, -0.141865,-0.078372, -0.171380,-0.068573, -0.219062,-0.058323, -0.143742,-0.087861, -0.091657,-0.119016, -0.064293,-0.149293, -0.035036,-0.174552, 0.008068,-0.188158, 0.033975,-0.202674, 0.014209,-0.230302, -0.012607,-0.273132, -0.029424,-0.294809, -0.225216,-0.161997, -0.242761,-0.128783, -0.243022,-0.100285, -0.242528,-0.076469, -0.253522,-0.113827, -0.276566,-0.145725, -0.242545,-0.170535, -0.250219,-0.181472, -0.286326,-0.161348, -0.293850,-0.153836, -0.307260,-0.144896, -0.340292,-0.119818, -0.408251,-0.088506, -0.397993,-0.073727, -0.374925,-0.086159, -0.356519,-0.086714, -0.343301,-0.057086, -0.319019,-0.041256, -0.278705,-0.010797, -0.342214,0.129479, -0.259524,0.175390, -0.228995,0.117575, -0.204395,0.063454, -0.257242,0.022435, -0.263564,0.003431, -0.193668,0.062052, -0.104991,0.119589, -0.107623,0.096041, -0.111440,0.076555, -0.126283,0.044518, -0.143519,0.037706, -0.175989,0.003239, -0.213542,-0.048387, -0.188075,-0.038009, -0.156904,-0.002863, -0.139409,0.021202, -0.129500,0.034230, +NEWSHAPE, 325, 3, 1, 0.003906,-0.017741, -0.005665,-0.023874, -0.001296,-0.059255, 0.008110,-0.088485, 0.021638,-0.119244, 0.001998,-0.123781, -0.025603,-0.125790, -0.042514,-0.132101, -0.062642,-0.134604, -0.080079,-0.114436, -0.119123,-0.090010, -0.141865,-0.078372, -0.171380,-0.068573, -0.219062,-0.058323, -0.143742,-0.087861, -0.091657,-0.119016, -0.064293,-0.149293, -0.035036,-0.174552, 0.008068,-0.188158, 0.033975,-0.202674, 0.014209,-0.230302, -0.012607,-0.273132, -0.029424,-0.294809, -0.225216,-0.161997, -0.242761,-0.128783, -0.243022,-0.100285, -0.242528,-0.076469, -0.253522,-0.113827, -0.276566,-0.145725, -0.242545,-0.170535, -0.250219,-0.181472, -0.286326,-0.161348, -0.293850,-0.153836, -0.307260,-0.144896, -0.340292,-0.119818, -0.408251,-0.088506, -0.397993,-0.073727, -0.374925,-0.086159, -0.356519,-0.086714, -0.343301,-0.057086, -0.319019,-0.041256, -0.278705,-0.010797, -0.342214,0.129479, -0.259524,0.175390, -0.228995,0.117575, -0.204395,0.063454, -0.257242,0.022435, -0.263564,0.003431, -0.193668,0.062052, -0.104991,0.119589, -0.107623,0.096041, -0.111440,0.076555, -0.126283,0.044518, -0.143519,0.037706, -0.175989,0.003239, -0.213542,-0.048387, -0.188075,-0.038009, -0.156904,-0.002863, -0.139409,0.021202, -0.129500,0.034230, // shButterflyFloor[1] -NEWSHAPE, 326, 7, 1, -0.199281,-0.117040, -0.202870,-0.110023, -0.247957,-0.128116, -0.298501,0.006170, -0.226086,0.045756, -0.061553,0.006677, -0.059070,0.020733, -0.217691,0.072727, +NEWSHAPE, 326, 7, 1, -0.199281,-0.117040, -0.202870,-0.110023, -0.247957,-0.128116, -0.298501,0.006170, -0.226086,0.045756, -0.061553,0.006677, -0.059070,0.020733, -0.217691,0.072727, // halfhepta -NEWSHAPE, 327, 1, 1, 0.335252,0.044112, 0.225849,0.283419, -0.081851,0.347313, -0.325491,0.159424, -0.323584,0.033019, +NEWSHAPE, 327, 1, 1, 0.335252,0.044112, 0.225849,0.283419, -0.081851,0.347313, -0.325491,0.159424, -0.323584,0.033019, // hepta mirror -NEWSHAPE, 328, 1, 2, -0.315398,0.010102, 0.568278,0.010645, +NEWSHAPE, 328, 1, 2, -0.315398,0.010102, 0.568278,0.010645, // halfhex -NEWSHAPE, 329, 1, 1, 0.263160,0.022375, 0.265137,0.152727, 0.000228,0.306625, -0.261438,0.151819, -0.263489,0.020161, +NEWSHAPE, 329, 1, 1, 0.263160,0.022375, 0.265137,0.152727, 0.000228,0.306625, -0.261438,0.151819, -0.263489,0.020161, // halfhex mirror -NEWSHAPE, 330, 1, 2, 0.262597,0.018558, -0.261563,0.016306, +NEWSHAPE, 330, 1, 2, 0.262597,0.018558, -0.261563,0.016306, -NEWSHAPE, 331, 1, 1, 0.148337,0.215535, 0.267624,0.150567, 0.262973,0.019662, 0.033981,0.019835, +NEWSHAPE, 331, 1, 1, 0.148337,0.215535, 0.267624,0.150567, 0.262973,0.019662, 0.033981,0.019835, // 0 0 1 [000000] -NEWSHAPE, 332, 6, 2, -0.016778,-0.008267, -0.261607,-0.011992, +NEWSHAPE, 332, 6, 2, -0.016778,-0.008267, -0.261607,-0.011992, NEWSHAPE, 333, 1, 2, 0.309841,0.030742, 0.317580,0.053457, 0.334636,0.058055, 0.348174,0.020510, 0.376877,0.022300, 0.687421,0.025648, 0.689655,0.067551, 0.764187,0.063670, 0.857074,0.041713, 0.877970,0.009947, -NEWSHAPE, 334, 3, 1, -0.105576,-0.310802, -0.089088,-0.290550, -0.093680,-0.249985, -0.122644,-0.145810, -0.163610,-0.059795, -0.218747,-0.008106, -0.248163,0.025043, -0.288167,0.072185, -0.343952,0.136311, -0.334320,0.175461, -0.167285,0.005435, -0.033821,-0.070939, 0.023553,-0.057189, 0.018549,-0.042281, -0.037669,-0.048310, -0.159595,0.014100, -0.324263,0.188022, -0.292243,0.222279, -0.156865,0.105267, -0.269602,0.234419, +NEWSHAPE, 334, 3, 1, -0.105576,-0.310802, -0.089088,-0.290550, -0.093680,-0.249985, -0.122644,-0.145810, -0.163610,-0.059795, -0.218747,-0.008106, -0.248163,0.025043, -0.288167,0.072185, -0.343952,0.136311, -0.334320,0.175461, -0.167285,0.005435, -0.033821,-0.070939, 0.023553,-0.057189, 0.018549,-0.042281, -0.037669,-0.048310, -0.159595,0.014100, -0.324263,0.188022, -0.292243,0.222279, -0.156865,0.105267, -0.269602,0.234419, // 3 1 0 [000000] -NEWSHAPE, 335, 7, 1, 0.630896,-0.017243, 0.635685,-0.036640, 0.598195,-0.013808, 0.578658,0.004348, 0.518765,0.041438, 0.473213,0.052123, 0.438282,0.057356, 0.363338,0.043998, 0.319911,0.024470, 0.305024,0.010850, 0.311704,-0.028346, 0.329285,-0.092284, 0.336019,-0.135243, 0.389245,-0.255305, 0.391920,-0.305109, 0.393425,-0.394636, 0.393988,-0.421032, 0.392645,-0.461313, 0.388233,-0.488635, +NEWSHAPE, 335, 7, 1, 0.630896,-0.017243, 0.635685,-0.036640, 0.598195,-0.013808, 0.578658,0.004348, 0.518765,0.041438, 0.473213,0.052123, 0.438282,0.057356, 0.363338,0.043998, 0.319911,0.024470, 0.305024,0.010850, 0.311704,-0.028346, 0.329285,-0.092284, 0.336019,-0.135243, 0.389245,-0.255305, 0.391920,-0.305109, 0.393425,-0.394636, 0.393988,-0.421032, 0.392645,-0.461313, 0.388233,-0.488635, -NEWSHAPE, 336, 6, 1, -0.275302,-0.159499, -0.271762,-0.143824, -0.259519,-0.121154, -0.233677,-0.073572, -0.230950,-0.048375, -0.253372,-0.021090, -0.282216,0.003606, -0.312272,0.027869, -0.333611,0.051397, -0.322056,0.102122, -0.310427,0.125702, -0.289273,0.151653, +NEWSHAPE, 336, 6, 1, -0.275302,-0.159499, -0.271762,-0.143824, -0.259519,-0.121154, -0.233677,-0.073572, -0.230950,-0.048375, -0.253372,-0.021090, -0.282216,0.003606, -0.312272,0.027869, -0.333611,0.051397, -0.322056,0.102122, -0.310427,0.125702, -0.289273,0.151653, // 3 1 0 [000000] -NEWSHAPE, 337, 7, 1, -0.344613,-0.163178, -0.343328,-0.158477, -0.339398,-0.155316, -0.331625,-0.143563, -0.312189,-0.120371, -0.298918,-0.094936, -0.290925,-0.065675, -0.303772,-0.033612, -0.318623,-0.019712, -0.333911,-0.009121, -0.358867,0.006952, -0.378653,0.024361, -0.388462,0.047480, -0.384686,0.080428, -0.365524,0.120307, -0.357683,0.137712, -0.349127,0.156460, +NEWSHAPE, 337, 7, 1, -0.344613,-0.163178, -0.343328,-0.158477, -0.339398,-0.155316, -0.331625,-0.143563, -0.312189,-0.120371, -0.298918,-0.094936, -0.290925,-0.065675, -0.303772,-0.033612, -0.318623,-0.019712, -0.333911,-0.009121, -0.358867,0.006952, -0.378653,0.024361, -0.388462,0.047480, -0.384686,0.080428, -0.365524,0.120307, -0.357683,0.137712, -0.349127,0.156460, -NEWSHAPE, 338, 3, 1, -0.236647,0.182860, -0.048267,0.312652, -0.029042,0.305930, -0.008857,0.306171, 0.028203,0.314150, 0.035096,0.317705, 0.052903,0.320051, 0.074068,0.315314, 0.103117,0.308962, 0.141064,0.295765, 0.177370,0.274685, 0.212797,0.248082, 0.250462,0.198914, +NEWSHAPE, 338, 3, 1, -0.236647,0.182860, -0.048267,0.312652, -0.029042,0.305930, -0.008857,0.306171, 0.028203,0.314150, 0.035096,0.317705, 0.052903,0.320051, 0.074068,0.315314, 0.103117,0.308962, 0.141064,0.295765, 0.177370,0.274685, 0.212797,0.248082, 0.250462,0.198914, // 3 1 0 [000000] -NEWSHAPE, 339, 7, 1, -0.311164,0.181794, -0.281489,0.184438, -0.224601,0.202893, -0.166641,0.244605, -0.128636,0.295175, -0.104773,0.341126, -0.103079,0.384939, -0.097144,0.419892, -0.083906,0.427485, -0.076666,0.412206, +NEWSHAPE, 339, 7, 1, -0.311164,0.181794, -0.281489,0.184438, -0.224601,0.202893, -0.166641,0.244605, -0.128636,0.295175, -0.104773,0.341126, -0.103079,0.384939, -0.097144,0.419892, -0.083906,0.427485, -0.076666,0.412206, NEWSHAPE, 340, 7, 1, 0.358115,-0.002263, 0.352245,-0.015654, 0.339277,-0.044366, 0.301027,-0.104037, 0.302282,-0.125857, 0.336188,-0.163014, 0.378199,-0.161820, 0.415940,-0.146184, 0.418836,-0.142581, 0.387934,-0.194555, 0.331182,-0.238021, 0.273850,-0.271284, -NEWSHAPE, 341, 1, 1, 0.058098,-0.184167, 0.043764,-0.193521, 0.030120,-0.205230, 0.062927,-0.201718, 0.085161,-0.207060, 0.103674,-0.214608, 0.119223,-0.223616, 0.129906,-0.266195, 0.124486,-0.282176, 0.070902,-0.310435, -0.020955,-0.372622, -0.046676,-0.402829, -0.083152,-0.396295, -0.125465,-0.373796, -0.149041,-0.292258, -0.123746,-0.212687, -0.154293,-0.114741, -0.205826,-0.089865, -0.236903,-0.086544, -0.188542,0.041769, -0.189476,0.058860, -0.192794,0.076530, -0.206156,0.046363, -0.221900,0.029778, -0.237693,0.017520, -0.253269,0.008558, -0.295485,0.020596, -0.306615,0.033280, -0.304296,0.093815, -0.312223,0.204459, -0.325522,0.241837, -0.301626,0.270159, -0.260984,0.295554, -0.178582,0.275202, -0.122319,0.213511, -0.022222,0.190992, 0.025088,0.223183, 0.043502,0.248436, 0.130444,0.142398, 0.145712,0.134661, 0.162674,0.128700, 0.143229,0.155355, 0.136739,0.177282, 0.134019,0.197088, 0.134046,0.215058, 0.165579,0.245599, 0.182129,0.248896, 0.233394,0.216620, 0.333178,0.168163, 0.372198,0.160992, 0.384778,0.126136, 0.386449,0.078242, 0.327623,0.017056, 0.246065,-0.000824, 0.176515,-0.076251, 0.180738,-0.133318, 0.193401,-0.161892, 0.058098,-0.184167, -NEWSHAPE, 342, 1, 1, 0.085922,-0.170851, 0.094684,-0.178713, 0.111076,-0.179370, 0.126675,-0.183798, 0.152543,-0.203864, 0.159822,-0.219394, 0.158645,-0.253717, 0.151002,-0.264105, 0.099747,-0.278812, 0.046291,-0.301056, 0.001653,-0.327469, -0.024257,-0.346115, -0.052036,-0.374799, -0.074384,-0.388585, -0.100523,-0.395273, -0.130621,-0.374380, -0.147379,-0.344657, -0.158388,-0.304821, -0.148369,-0.279439, -0.119203,-0.194952, -0.129525,-0.133964, -0.153101,-0.109438, -0.181621,-0.090898, -0.223761,-0.104234, -0.191091,-0.043735, -0.182715,-0.018133, -0.190922,0.011015, -0.202112,0.007358, -0.210877,-0.006510, -0.222511,-0.017805, -0.252823,-0.030174, -0.269912,-0.028713, -0.299048,-0.010532, -0.304223,0.001281, -0.291332,0.053023, -0.283868,0.110439, -0.284423,0.162303, -0.287616,0.194065, -0.298567,0.232464, -0.299332,0.258711, -0.292055,0.284692, -0.258912,0.300311, -0.224792,0.299962, -0.184789,0.289579, -0.167817,0.268211, -0.109232,0.200709, -0.051254,0.179154, -0.018226,0.187308, 0.012091,0.202737, 0.021611,0.245900, 0.057670,0.187357, 0.075654,0.167302, 0.105000,0.159836, 0.107428,0.171355, 0.099801,0.185880, 0.095836,0.201603, 0.100280,0.234038, 0.110090,0.248107, 0.140403,0.264249, 0.153221,0.262824, 0.191585,0.225789, 0.237577,0.190617, 0.282770,0.165166, 0.311873,0.152050, 0.350603,0.142335, 0.373716,0.129874, 0.392578,0.110581, 0.389533,0.074069, 0.372171,0.044695, 0.343177,0.015242, 0.316186,0.011228, 0.228435,-0.005757, 0.180779,-0.045190, 0.171327,-0.077870, 0.169530,-0.111839, 0.202150,-0.141666, 0.133421,-0.143622, 0.107061,-0.149169, 0.085922,-0.170851, -NEWSHAPE, 343, 1, 1, 0.123762,-0.146862, 0.148168,-0.159183, 0.171907,-0.173839, 0.194215,-0.193089, 0.194432,-0.231857, 0.182134,-0.248025, 0.118729,-0.258775, 0.010421,-0.297013, -0.053987,-0.359470, -0.067850,-0.369100, -0.094636,-0.374835, -0.116752,-0.372581, -0.136917,-0.354191, -0.147941,-0.314240, -0.129620,-0.188762, -0.137276,-0.139942, -0.169277,-0.114566, -0.218880,-0.123383, -0.206725,-0.105873, -0.189067,-0.033750, -0.211941,-0.048726, -0.236502,-0.061956, -0.264327,-0.071651, -0.298010,-0.052455, -0.305863,-0.033720, -0.283470,0.026565, -0.262431,0.139482, -0.284317,0.226489, -0.285725,0.243310, -0.277299,0.269375, -0.264289,0.287401, -0.238280,0.295669, -0.198169,0.285241, -0.098663,0.206635, -0.052555,0.188856, -0.014579,0.203881, 0.002587,0.251247, 0.011674,0.231966, 0.065305,0.180612, 0.063773,0.207909, 0.064595,0.235795, 0.070112,0.264740, 0.103578,0.284312, 0.123729,0.281745, 0.164741,0.232210, 0.252010,0.157531, 0.338304,0.132981, 0.353575,0.125790, 0.371935,0.105460, 0.381041,0.085180, 0.375197,0.058522, 0.346110,0.028999, 0.228283,-0.017873, 0.189831,-0.048914, 0.183856,-0.089315, 0.216293,-0.127864, 0.195051,-0.126093, 0.123762,-0.146862, -NEWSHAPE, 344, 1, 1, 0.176734,-0.128319, 0.183999,-0.139147, 0.224403,-0.163780, 0.239334,-0.182738, 0.230289,-0.228566, 0.217192,-0.239264, 0.096376,-0.250178, 0.041628,-0.264450, -0.012807,-0.297334, -0.043367,-0.322080, -0.108868,-0.364399, -0.136576,-0.367959, -0.150241,-0.361680, -0.162970,-0.349757, -0.155723,-0.340758, -0.143049,-0.329347, -0.136673,-0.296693, -0.139002,-0.273102, -0.137671,-0.229504, -0.129949,-0.174244, -0.118095,-0.156850, -0.112660,-0.151602, -0.127923,-0.130954, -0.158854,-0.123781, -0.190420,-0.128861, -0.206135,-0.137967, -0.222795,-0.149463, -0.206378,-0.120377, -0.199745,-0.105164, -0.199495,-0.088897, -0.212504,-0.089774, -0.254039,-0.112449, -0.277923,-0.115900, -0.313088,-0.085153, -0.315805,-0.068462, -0.264849,0.041625, -0.249834,0.096174, -0.251095,0.159758, -0.257246,0.198597, -0.261145,0.276482, -0.250374,0.302258, -0.238104,0.310953, -0.221413,0.316015, -0.217244,0.305239, -0.213698,0.288558, -0.188607,0.266709, -0.167012,0.256930, -0.129921,0.233979, -0.085925,0.199661, -0.076789,0.180698, -0.074961,0.173367, -0.049448,0.176262, -0.027770,0.199462, -0.016387,0.229339, -0.016415,0.247502, -0.018041,0.267678, -0.001061,0.238917, 0.008798,0.225566, 0.022761,0.217216, 0.028505,0.228921, 0.029636,0.276229, 0.038589,0.298638, 0.082799,0.313719, 0.098613,0.307726, 0.168473,0.208553, 0.208206,0.168276, 0.263902,0.137576, 0.300613,0.123483, 0.370013,0.087917, 0.386950,0.065701, 0.388345,0.050727, 0.384383,0.033742, 0.372967,0.035519, 0.356747,0.040789, 0.325280,0.029984, 0.306014,0.016172, 0.267592,-0.004475, 0.215874,-0.025417, 0.194884,-0.023848, 0.187621,-0.021765, 0.177371,-0.045308, 0.186624,-0.075681, 0.206807,-0.100478, 0.222550,-0.109535, 0.240836,-0.118215, 0.207439,-0.118540, 0.190947,-0.120402, 0.176734,-0.128319, -NEWSHAPE, 345, 1, 1, 0.227190,-0.112910, 0.227678,-0.122664, 0.258616,-0.141627, 0.284143,-0.179401, 0.271193,-0.219662, 0.253336,-0.228455, 0.186161,-0.226070, 0.083987,-0.230586, -0.035239,-0.293862, -0.071610,-0.335399, -0.107589,-0.345855, -0.138890,-0.318922, -0.137405,-0.245784, -0.139048,-0.174181, -0.178492,-0.141135, -0.221384,-0.154076, -0.211378,-0.140297, -0.220069,-0.135843, -0.251961,-0.153155, -0.297437,-0.156375, -0.325829,-0.125029, -0.324516,-0.105168, -0.288863,-0.048185, -0.241687,0.042558, -0.236872,0.177449, -0.254659,0.229716, -0.245725,0.266102, -0.206750,0.279743, -0.144153,0.241888, -0.081321,0.207510, -0.032980,0.225146, -0.022742,0.268762, -0.015812,0.253207, -0.007609,0.258507, -0.006655,0.294782, 0.013294,0.335776, 0.054636,0.344691, 0.071180,0.333623, 0.102702,0.274255, 0.157700,0.188028, 0.272111,0.116413, 0.326269,0.105683, 0.353314,0.079753, 0.345640,0.039179, 0.281558,0.003896, 0.220369,-0.033329, 0.211472,-0.084011, 0.244126,-0.114686, 0.227190,-0.112910, -NEWSHAPE, 346, 3, 1, -0.239730,-0.007608, -0.223885,0.067283, -0.220256,0.133782, -0.242650,0.195422, -0.253278,0.205455, -0.260377,0.171703, -0.282853,0.129264, -0.323970,0.130146, -0.298985,0.146911, -0.285820,0.188205, -0.265413,0.247080, -0.253036,0.259972, -0.219733,0.277154, -0.176198,0.277543, -0.141016,0.238755, -0.107826,0.210921, -0.064270,0.213048, -0.027789,0.236562, -0.013484,0.250322, 0.005700,0.314857, 0.015326,0.356416, 0.035962,0.374414, 0.050913,0.366903, -NEWSHAPE, 347, 3, 1, -0.224843,0.011231, -0.221774,0.155893, -0.237013,0.176616, -0.235167,0.161978, -0.233348,0.147389, -0.243466,0.116780, -0.268483,0.091378, -0.289413,0.094518, -0.303691,0.109465, -0.306027,0.164940, -0.298818,0.218829, -0.292029,0.245261, -0.240190,0.282931, -0.188317,0.284726, -0.152862,0.259042, -0.141074,0.232138, -0.099370,0.203720, -0.045785,0.208279, 0.009668,0.253588, 0.013535,0.280682, 0.018420,0.337425, 0.015783,0.401804, -0.001438,0.415925, 0.031579,0.404581, 0.041846,0.335206, 0.079240,0.235103, -NEWSHAPE, 348, 1, 1, 0.008663,-0.233609, 0.008598,-0.236670, 0.039937,-0.234457, 0.082195,-0.248873, 0.101194,-0.283516, 0.097960,-0.306736, 0.045069,-0.337983, -0.033666,-0.406661, -0.064823,-0.404114, -0.127271,-0.339591, -0.144421,-0.275485, -0.132327,-0.228734, -0.153707,-0.155774, -0.224124,-0.089714, -0.257905,-0.091799, -0.211227,-0.013730, -0.195172,0.041425, -0.206643,0.109302, -0.209261,0.110889, -0.223014,0.082642, -0.256628,0.053254, -0.296129,0.054121, -0.314621,0.068532, -0.315236,0.129961, -0.335346,0.232486, -0.317561,0.258195, -0.230459,0.280015, -0.166367,0.262815, -0.131926,0.228966, -0.058051,0.211001, 0.034367,0.238954, 0.049452,0.269252, 0.093723,0.189793, 0.133461,0.148311, 0.197980,0.124307, 0.200663,0.125781, 0.183077,0.151815, 0.174433,0.195619, 0.194935,0.229395, 0.216661,0.238204, 0.270167,0.208022, 0.369012,0.174175, 0.382384,0.145919, 0.357730,0.059576, 0.310788,0.012670, 0.264253,-0.000232, 0.211758,-0.055227, 0.189757,-0.149240, 0.208453,-0.177453, 0.117504,-0.176063, 0.061711,-0.189736, 0.008663,-0.233609, +NEWSHAPE, 341, 1, 1, 0.058098,-0.184167, 0.043764,-0.193521, 0.030120,-0.205230, 0.062927,-0.201718, 0.085161,-0.207060, 0.103674,-0.214608, 0.119223,-0.223616, 0.129906,-0.266195, 0.124486,-0.282176, 0.070902,-0.310435, -0.020955,-0.372622, -0.046676,-0.402829, -0.083152,-0.396295, -0.125465,-0.373796, -0.149041,-0.292258, -0.123746,-0.212687, -0.154293,-0.114741, -0.205826,-0.089865, -0.236903,-0.086544, -0.188542,0.041769, -0.189476,0.058860, -0.192794,0.076530, -0.206156,0.046363, -0.221900,0.029778, -0.237693,0.017520, -0.253269,0.008558, -0.295485,0.020596, -0.306615,0.033280, -0.304296,0.093815, -0.312223,0.204459, -0.325522,0.241837, -0.301626,0.270159, -0.260984,0.295554, -0.178582,0.275202, -0.122319,0.213511, -0.022222,0.190992, 0.025088,0.223183, 0.043502,0.248436, 0.130444,0.142398, 0.145712,0.134661, 0.162674,0.128700, 0.143229,0.155355, 0.136739,0.177282, 0.134019,0.197088, 0.134046,0.215058, 0.165579,0.245599, 0.182129,0.248896, 0.233394,0.216620, 0.333178,0.168163, 0.372198,0.160992, 0.384778,0.126136, 0.386449,0.078242, 0.327623,0.017056, 0.246065,-0.000824, 0.176515,-0.076251, 0.180738,-0.133318, 0.193401,-0.161892, 0.058098,-0.184167, +NEWSHAPE, 342, 1, 1, 0.085922,-0.170851, 0.094684,-0.178713, 0.111076,-0.179370, 0.126675,-0.183798, 0.152543,-0.203864, 0.159822,-0.219394, 0.158645,-0.253717, 0.151002,-0.264105, 0.099747,-0.278812, 0.046291,-0.301056, 0.001653,-0.327469, -0.024257,-0.346115, -0.052036,-0.374799, -0.074384,-0.388585, -0.100523,-0.395273, -0.130621,-0.374380, -0.147379,-0.344657, -0.158388,-0.304821, -0.148369,-0.279439, -0.119203,-0.194952, -0.129525,-0.133964, -0.153101,-0.109438, -0.181621,-0.090898, -0.223761,-0.104234, -0.191091,-0.043735, -0.182715,-0.018133, -0.190922,0.011015, -0.202112,0.007358, -0.210877,-0.006510, -0.222511,-0.017805, -0.252823,-0.030174, -0.269912,-0.028713, -0.299048,-0.010532, -0.304223,0.001281, -0.291332,0.053023, -0.283868,0.110439, -0.284423,0.162303, -0.287616,0.194065, -0.298567,0.232464, -0.299332,0.258711, -0.292055,0.284692, -0.258912,0.300311, -0.224792,0.299962, -0.184789,0.289579, -0.167817,0.268211, -0.109232,0.200709, -0.051254,0.179154, -0.018226,0.187308, 0.012091,0.202737, 0.021611,0.245900, 0.057670,0.187357, 0.075654,0.167302, 0.105000,0.159836, 0.107428,0.171355, 0.099801,0.185880, 0.095836,0.201603, 0.100280,0.234038, 0.110090,0.248107, 0.140403,0.264249, 0.153221,0.262824, 0.191585,0.225789, 0.237577,0.190617, 0.282770,0.165166, 0.311873,0.152050, 0.350603,0.142335, 0.373716,0.129874, 0.392578,0.110581, 0.389533,0.074069, 0.372171,0.044695, 0.343177,0.015242, 0.316186,0.011228, 0.228435,-0.005757, 0.180779,-0.045190, 0.171327,-0.077870, 0.169530,-0.111839, 0.202150,-0.141666, 0.133421,-0.143622, 0.107061,-0.149169, 0.085922,-0.170851, +NEWSHAPE, 343, 1, 1, 0.123762,-0.146862, 0.148168,-0.159183, 0.171907,-0.173839, 0.194215,-0.193089, 0.194432,-0.231857, 0.182134,-0.248025, 0.118729,-0.258775, 0.010421,-0.297013, -0.053987,-0.359470, -0.067850,-0.369100, -0.094636,-0.374835, -0.116752,-0.372581, -0.136917,-0.354191, -0.147941,-0.314240, -0.129620,-0.188762, -0.137276,-0.139942, -0.169277,-0.114566, -0.218880,-0.123383, -0.206725,-0.105873, -0.189067,-0.033750, -0.211941,-0.048726, -0.236502,-0.061956, -0.264327,-0.071651, -0.298010,-0.052455, -0.305863,-0.033720, -0.283470,0.026565, -0.262431,0.139482, -0.284317,0.226489, -0.285725,0.243310, -0.277299,0.269375, -0.264289,0.287401, -0.238280,0.295669, -0.198169,0.285241, -0.098663,0.206635, -0.052555,0.188856, -0.014579,0.203881, 0.002587,0.251247, 0.011674,0.231966, 0.065305,0.180612, 0.063773,0.207909, 0.064595,0.235795, 0.070112,0.264740, 0.103578,0.284312, 0.123729,0.281745, 0.164741,0.232210, 0.252010,0.157531, 0.338304,0.132981, 0.353575,0.125790, 0.371935,0.105460, 0.381041,0.085180, 0.375197,0.058522, 0.346110,0.028999, 0.228283,-0.017873, 0.189831,-0.048914, 0.183856,-0.089315, 0.216293,-0.127864, 0.195051,-0.126093, 0.123762,-0.146862, +NEWSHAPE, 344, 1, 1, 0.176734,-0.128319, 0.183999,-0.139147, 0.224403,-0.163780, 0.239334,-0.182738, 0.230289,-0.228566, 0.217192,-0.239264, 0.096376,-0.250178, 0.041628,-0.264450, -0.012807,-0.297334, -0.043367,-0.322080, -0.108868,-0.364399, -0.136576,-0.367959, -0.150241,-0.361680, -0.162970,-0.349757, -0.155723,-0.340758, -0.143049,-0.329347, -0.136673,-0.296693, -0.139002,-0.273102, -0.137671,-0.229504, -0.129949,-0.174244, -0.118095,-0.156850, -0.112660,-0.151602, -0.127923,-0.130954, -0.158854,-0.123781, -0.190420,-0.128861, -0.206135,-0.137967, -0.222795,-0.149463, -0.206378,-0.120377, -0.199745,-0.105164, -0.199495,-0.088897, -0.212504,-0.089774, -0.254039,-0.112449, -0.277923,-0.115900, -0.313088,-0.085153, -0.315805,-0.068462, -0.264849,0.041625, -0.249834,0.096174, -0.251095,0.159758, -0.257246,0.198597, -0.261145,0.276482, -0.250374,0.302258, -0.238104,0.310953, -0.221413,0.316015, -0.217244,0.305239, -0.213698,0.288558, -0.188607,0.266709, -0.167012,0.256930, -0.129921,0.233979, -0.085925,0.199661, -0.076789,0.180698, -0.074961,0.173367, -0.049448,0.176262, -0.027770,0.199462, -0.016387,0.229339, -0.016415,0.247502, -0.018041,0.267678, -0.001061,0.238917, 0.008798,0.225566, 0.022761,0.217216, 0.028505,0.228921, 0.029636,0.276229, 0.038589,0.298638, 0.082799,0.313719, 0.098613,0.307726, 0.168473,0.208553, 0.208206,0.168276, 0.263902,0.137576, 0.300613,0.123483, 0.370013,0.087917, 0.386950,0.065701, 0.388345,0.050727, 0.384383,0.033742, 0.372967,0.035519, 0.356747,0.040789, 0.325280,0.029984, 0.306014,0.016172, 0.267592,-0.004475, 0.215874,-0.025417, 0.194884,-0.023848, 0.187621,-0.021765, 0.177371,-0.045308, 0.186624,-0.075681, 0.206807,-0.100478, 0.222550,-0.109535, 0.240836,-0.118215, 0.207439,-0.118540, 0.190947,-0.120402, 0.176734,-0.128319, +NEWSHAPE, 345, 1, 1, 0.227190,-0.112910, 0.227678,-0.122664, 0.258616,-0.141627, 0.284143,-0.179401, 0.271193,-0.219662, 0.253336,-0.228455, 0.186161,-0.226070, 0.083987,-0.230586, -0.035239,-0.293862, -0.071610,-0.335399, -0.107589,-0.345855, -0.138890,-0.318922, -0.137405,-0.245784, -0.139048,-0.174181, -0.178492,-0.141135, -0.221384,-0.154076, -0.211378,-0.140297, -0.220069,-0.135843, -0.251961,-0.153155, -0.297437,-0.156375, -0.325829,-0.125029, -0.324516,-0.105168, -0.288863,-0.048185, -0.241687,0.042558, -0.236872,0.177449, -0.254659,0.229716, -0.245725,0.266102, -0.206750,0.279743, -0.144153,0.241888, -0.081321,0.207510, -0.032980,0.225146, -0.022742,0.268762, -0.015812,0.253207, -0.007609,0.258507, -0.006655,0.294782, 0.013294,0.335776, 0.054636,0.344691, 0.071180,0.333623, 0.102702,0.274255, 0.157700,0.188028, 0.272111,0.116413, 0.326269,0.105683, 0.353314,0.079753, 0.345640,0.039179, 0.281558,0.003896, 0.220369,-0.033329, 0.211472,-0.084011, 0.244126,-0.114686, 0.227190,-0.112910, +NEWSHAPE, 346, 3, 1, -0.239730,-0.007608, -0.223885,0.067283, -0.220256,0.133782, -0.242650,0.195422, -0.253278,0.205455, -0.260377,0.171703, -0.282853,0.129264, -0.323970,0.130146, -0.298985,0.146911, -0.285820,0.188205, -0.265413,0.247080, -0.253036,0.259972, -0.219733,0.277154, -0.176198,0.277543, -0.141016,0.238755, -0.107826,0.210921, -0.064270,0.213048, -0.027789,0.236562, -0.013484,0.250322, 0.005700,0.314857, 0.015326,0.356416, 0.035962,0.374414, 0.050913,0.366903, +NEWSHAPE, 347, 3, 1, -0.224843,0.011231, -0.221774,0.155893, -0.237013,0.176616, -0.235167,0.161978, -0.233348,0.147389, -0.243466,0.116780, -0.268483,0.091378, -0.289413,0.094518, -0.303691,0.109465, -0.306027,0.164940, -0.298818,0.218829, -0.292029,0.245261, -0.240190,0.282931, -0.188317,0.284726, -0.152862,0.259042, -0.141074,0.232138, -0.099370,0.203720, -0.045785,0.208279, 0.009668,0.253588, 0.013535,0.280682, 0.018420,0.337425, 0.015783,0.401804, -0.001438,0.415925, 0.031579,0.404581, 0.041846,0.335206, 0.079240,0.235103, +NEWSHAPE, 348, 1, 1, 0.008663,-0.233609, 0.008598,-0.236670, 0.039937,-0.234457, 0.082195,-0.248873, 0.101194,-0.283516, 0.097960,-0.306736, 0.045069,-0.337983, -0.033666,-0.406661, -0.064823,-0.404114, -0.127271,-0.339591, -0.144421,-0.275485, -0.132327,-0.228734, -0.153707,-0.155774, -0.224124,-0.089714, -0.257905,-0.091799, -0.211227,-0.013730, -0.195172,0.041425, -0.206643,0.109302, -0.209261,0.110889, -0.223014,0.082642, -0.256628,0.053254, -0.296129,0.054121, -0.314621,0.068532, -0.315236,0.129961, -0.335346,0.232486, -0.317561,0.258195, -0.230459,0.280015, -0.166367,0.262815, -0.131926,0.228966, -0.058051,0.211001, 0.034367,0.238954, 0.049452,0.269252, 0.093723,0.189793, 0.133461,0.148311, 0.197980,0.124307, 0.200663,0.125781, 0.183077,0.151815, 0.174433,0.195619, 0.194935,0.229395, 0.216661,0.238204, 0.270167,0.208022, 0.369012,0.174175, 0.382384,0.145919, 0.357730,0.059576, 0.310788,0.012670, 0.264253,-0.000232, 0.211758,-0.055227, 0.189757,-0.149240, 0.208453,-0.177453, 0.117504,-0.176063, 0.061711,-0.189736, 0.008663,-0.233609, -NEWSHAPE, 349, 1, 2, -0.121972,-0.043111, -0.114642,-0.068365, -0.088391,-0.109437, -0.091010,-0.186252, -0.070420,-0.268876, -0.057667,-0.278726, -0.022404,-0.276319, 0.004269,-0.280716, 0.026650,-0.269700, 0.029709,-0.230247, 0.015894,-0.219344, -0.003181,-0.226933, -0.023333,-0.226963, -0.014779,-0.180514, -0.018939,-0.137833, 0.007353,-0.112396, 0.031445,-0.054504, -NEWSHAPE, 350, 1, 2, -0.125160,-0.046277, -0.115709,-0.070478, -0.085233,-0.111539, -0.094180,-0.184127, -0.071510,-0.271096, -0.054491,-0.283139, -0.006399,-0.274075, -0.002121,-0.225846, -0.022277,-0.229136, -0.014789,-0.188031, -0.018940,-0.138896, 0.010503,-0.110284, 0.034592,-0.055557, -NEWSHAPE, 351, 1, 2, -0.121946,-0.031538, -0.111405,-0.049397, -0.096675,-0.069354, -0.087345,-0.111549, -0.015775,-0.131461, -0.086284,-0.110485, -0.103742,-0.183136, -0.083551,-0.182966, -0.069423,-0.115705, -0.082446,-0.182860, -0.056507,-0.184308, -0.046776,-0.124036, -0.055447,-0.183766, -0.033783,-0.184751, -0.028908,-0.130351, -0.033253,-0.184213, -0.004225,-0.188021, -0.009468,-0.136762, -0.003150,-0.102889, -0.000000,-0.075460, -0.095569,-0.069314, -0.000000,-0.075500, 0.026212,-0.067103, 0.037193,-0.053432, -0.109760,-0.048841, 0.019376,-0.051845, 0.019363,0.000523, 0.020425,-0.052894, 0.037736,-0.052411, 0.036122,-0.020417, -0.121335,-0.020485, 0.034027,-0.019893, 0.002093,-0.019887, 0.001048,-0.077037, 0.001047,-0.021457, 0.001570,0.001047, 0.003140,-0.019887, 0.034027,-0.020416, +NEWSHAPE, 349, 1, 2, -0.121972,-0.043111, -0.114642,-0.068365, -0.088391,-0.109437, -0.091010,-0.186252, -0.070420,-0.268876, -0.057667,-0.278726, -0.022404,-0.276319, 0.004269,-0.280716, 0.026650,-0.269700, 0.029709,-0.230247, 0.015894,-0.219344, -0.003181,-0.226933, -0.023333,-0.226963, -0.014779,-0.180514, -0.018939,-0.137833, 0.007353,-0.112396, 0.031445,-0.054504, +NEWSHAPE, 350, 1, 2, -0.125160,-0.046277, -0.115709,-0.070478, -0.085233,-0.111539, -0.094180,-0.184127, -0.071510,-0.271096, -0.054491,-0.283139, -0.006399,-0.274075, -0.002121,-0.225846, -0.022277,-0.229136, -0.014789,-0.188031, -0.018940,-0.138896, 0.010503,-0.110284, 0.034592,-0.055557, +NEWSHAPE, 351, 1, 2, -0.121946,-0.031538, -0.111405,-0.049397, -0.096675,-0.069354, -0.087345,-0.111549, -0.015775,-0.131461, -0.086284,-0.110485, -0.103742,-0.183136, -0.083551,-0.182966, -0.069423,-0.115705, -0.082446,-0.182860, -0.056507,-0.184308, -0.046776,-0.124036, -0.055447,-0.183766, -0.033783,-0.184751, -0.028908,-0.130351, -0.033253,-0.184213, -0.004225,-0.188021, -0.009468,-0.136762, -0.003150,-0.102889, -0.000000,-0.075460, -0.095569,-0.069314, -0.000000,-0.075500, 0.026212,-0.067103, 0.037193,-0.053432, -0.109760,-0.048841, 0.019376,-0.051845, 0.019363,0.000523, 0.020425,-0.052894, 0.037736,-0.052411, 0.036122,-0.020417, -0.121335,-0.020485, 0.034027,-0.019893, 0.002093,-0.019887, 0.001048,-0.077037, 0.001047,-0.021457, 0.001570,0.001047, 0.003140,-0.019887, 0.034027,-0.020416, NEWSHAPE, 352, 1, 2, 0.060794,0.001192, 0.058426,0.023847, 0.050054,0.030986, 0.042896,0.038130, 0.044109,0.042917, 0.032180,0.050058, 0.017884,0.059612, 0.005963,0.064401, -0.009546,0.068015, -0.022689,0.070455, -0.044247,0.070556, -0.053847,0.068206, -0.047819,0.065752, -0.040573,0.056087, -0.040563,0.053686, -0.053753,0.053753, -0.067016,0.056246, -0.076602,0.051418, -0.065710,0.040621, -0.063272,0.034621, -0.064461,0.031037, -0.074098,0.028683, -0.094756,0.031185, -0.082872,0.019931, -0.074452,0.013632, -NEWSHAPE, 353, 1, 2, -0.006280,-0.006803, -0.001570,-0.039786, 0.007333,-0.062332, 0.014659,-0.042408, 0.019888,-0.016748, 0.027740,-0.009945, +NEWSHAPE, 353, 1, 2, -0.006280,-0.006803, -0.001570,-0.039786, 0.007333,-0.062332, 0.014659,-0.042408, 0.019888,-0.016748, 0.027740,-0.009945, -NEWSHAPE, 354, 1, 2, 0.250609,-0.000793, 0.091262,-0.024449, 0.090008,-0.008476, -0.131783,-0.007990, -0.229492,-0.028849, -0.208244,0.002239, -NEWSHAPE, 355, 1, 2, -0.120944,-0.046316, -0.118320,-0.065458, -0.026635,-0.134194, 0.069939,-0.150868, 0.257603,-0.099875, 0.263931,-0.098916, 0.295208,-0.074359, 0.292228,-0.069765, 0.274479,-0.081250, 0.293481,-0.057622, 0.290757,-0.055430, 0.266210,-0.078038, 0.289156,-0.044495, 0.286442,-0.042311, 0.263022,-0.071079, 0.275695,-0.039346, 0.256850,-0.068686, 0.254313,-0.048283, 0.242683,-0.074603, 0.079643,-0.108059, 0.017947,-0.089316, 0.039133,-0.032229, +NEWSHAPE, 354, 1, 2, 0.250609,-0.000793, 0.091262,-0.024449, 0.090008,-0.008476, -0.131783,-0.007990, -0.229492,-0.028849, -0.208244,0.002239, +NEWSHAPE, 355, 1, 2, -0.120944,-0.046316, -0.118320,-0.065458, -0.026635,-0.134194, 0.069939,-0.150868, 0.257603,-0.099875, 0.263931,-0.098916, 0.295208,-0.074359, 0.292228,-0.069765, 0.274479,-0.081250, 0.293481,-0.057622, 0.290757,-0.055430, 0.266210,-0.078038, 0.289156,-0.044495, 0.286442,-0.042311, 0.263022,-0.071079, 0.275695,-0.039346, 0.256850,-0.068686, 0.254313,-0.048283, 0.242683,-0.074603, 0.079643,-0.108059, 0.017947,-0.089316, 0.039133,-0.032229, NEWSHAPE, 356, 1, 2, 0.038226,0.003813, 0.036965,0.050265, 0.023804,0.086855, 0.079552,0.105995, 0.217008,0.045866, 0.243467,0.129202, 0.068641,0.159263, -0.027665,0.143726, -0.122085,0.061736, -NEWSHAPE, 357, 1, 2, -0.056345,0.025535, -0.042089,0.052635, 0.008058,0.053871, 0.047795,0.029085, -NEWSHAPE, 358, 1, 2, -0.045357,0.025586, -0.031505,0.043770, 0.005524,0.044623, 0.033574,0.024080, +NEWSHAPE, 357, 1, 2, -0.056345,0.025535, -0.042089,0.052635, 0.008058,0.053871, 0.047795,0.029085, +NEWSHAPE, 358, 1, 2, -0.045357,0.025586, -0.031505,0.043770, 0.005524,0.044623, 0.033574,0.024080, -NEWSHAPE, 359, 3, 1, -0.266809,0.074675, -0.122340,0.044980, -0.116509,0.053995, -0.263332,0.086012, -0.243276,0.226327, -0.046949,0.233904, -0.045697,0.176132, 0.043359,0.148557, 0.174518,-0.035928, 0.185648,-0.026857, 0.048860,0.153622, -0.026215,0.175210, -0.030599,0.236932, 0.114203,0.249675, -NEWSHAPE, 360, 7, 1, -0.118455,0.162875, -0.179457,0.274805, -0.139062,0.404961, -0.014470,0.358081, 0.088081,0.314743, 0.043390,0.203194, -0.025414,0.211780, -0.019156,0.324240, -0.044420,0.213922, -0.097269,0.172336, -0.097226,0.166975, -0.013745,0.197716, +NEWSHAPE, 359, 3, 1, -0.266809,0.074675, -0.122340,0.044980, -0.116509,0.053995, -0.263332,0.086012, -0.243276,0.226327, -0.046949,0.233904, -0.045697,0.176132, 0.043359,0.148557, 0.174518,-0.035928, 0.185648,-0.026857, 0.048860,0.153622, -0.026215,0.175210, -0.030599,0.236932, 0.114203,0.249675, +NEWSHAPE, 360, 7, 1, -0.118455,0.162875, -0.179457,0.274805, -0.139062,0.404961, -0.014470,0.358081, 0.088081,0.314743, 0.043390,0.203194, -0.025414,0.211780, -0.019156,0.324240, -0.044420,0.213922, -0.097269,0.172336, -0.097226,0.166975, -0.013745,0.197716, NEWSHAPE, 361, 1, 2, -0.077784,0.096705, -0.112723,0.108509, -0.096729,0.084112, -0.130665,0.091676, -0.112529,0.069411, -0.150758,0.068526, -0.119865,0.047315, -0.151705,0.038980, -0.116648,0.028374, -0.149534,0.021061, -0.119798,0.000000, NEWSHAPE, 362, 1, 1, -0.098710,-0.040954, -0.120861,-0.011561, -0.169793,0.001055, -0.213918,-0.011649, -0.244439,-0.030821, -0.257630,-0.038325, -0.286489,-0.056656, -0.321137,-0.048332, -0.347048,-0.011856, -0.316514,-0.028969, -0.296328,-0.024605, -0.263040,0.006390, -0.210822,0.055089, -0.164571,0.054857, -0.130462,0.046293, -0.098742,0.054623, -0.091289,-0.004197, -NEWSHAPE, 363, 1, 2, -0.252495,0.014545, -0.330447,0.029660, -0.319594,0.016402, -0.419249,0.040217, -0.457189,-0.013336, -NEWSHAPE, 364, 1, 2, -0.486619,0.002830, -0.418060,0.040577, -0.427473,0.022591, -0.408958,0.019603, -0.426031,0.010325, -0.407739,0.001037, +NEWSHAPE, 363, 1, 2, -0.252495,0.014545, -0.330447,0.029660, -0.319594,0.016402, -0.419249,0.040217, -0.457189,-0.013336, +NEWSHAPE, 364, 1, 2, -0.486619,0.002830, -0.418060,0.040577, -0.427473,0.022591, -0.408958,0.019603, -0.426031,0.010325, -0.407739,0.001037, -NEWSHAPE, 365, 1, 2, -0.236444,-0.000864, -0.300824,-0.142089, 0.027603,-0.331178, 0.117026,-0.205327, +NEWSHAPE, 365, 1, 2, -0.236444,-0.000864, -0.300824,-0.142089, 0.027603,-0.331178, 0.117026,-0.205327, NEWSHAPE, 366, 1, 2, 0.120242,0.202432, 0.476077,0.202192, -NEWSHAPE, 367, 1, 2, -0.096569,0.019944, 0.040859,0.019906, 0.037742,0.058710, 0.116624,-0.000000, +NEWSHAPE, 367, 1, 2, -0.096569,0.019944, 0.040859,0.019906, 0.037742,0.058710, 0.116624,-0.000000, // overgrown for 4-5 to 4-7 non-bitrunc -NEWSHAPE, 368, 5, 1, -0.722750,-0.522024, -0.310675,-0.189104, -0.809015,-0.052887, -0.464722,0.060902, -1.057795,0.207750, -NEWSHAPE, 369, 6, 1, 1.125689,-0.648796, 0.574166,-0.456509, 0.822679,-1.131184, 0.174168,-0.605003, 0.411340,-1.336854, -NEWSHAPE, 370, 7, 1, 1.034599,-1.366924, 0.528060,-0.892063, 0.490794,-1.701844, 0.081991,-0.819912, 0.042928,-1.637383, +NEWSHAPE, 368, 5, 1, -0.722750,-0.522024, -0.310675,-0.189104, -0.809015,-0.052887, -0.464722,0.060902, -1.057795,0.207750, +NEWSHAPE, 369, 6, 1, 1.125689,-0.648796, 0.574166,-0.456509, 0.822679,-1.131184, 0.174168,-0.605003, 0.411340,-1.336854, +NEWSHAPE, 370, 7, 1, 1.034599,-1.366924, 0.528060,-0.892063, 0.490794,-1.701844, 0.081991,-0.819912, 0.042928,-1.637383, NEWSHAPE, 371, 1, 1, -0.013726,-0.304365, 0.244972,-0.147728, 0.266167,0.130112, 0.156825,0.210539, -0.271641,0.147226, -0.281599,-0.145412, -NEWSHAPE, 372, 1, 1, -0.514563,-0.238476, -0.340659,0.172987, -0.100245,0.368967, 0.214334,0.276255, 0.349294,-0.008293, 0.203063,-0.280225, -0.078470,-0.352806, +NEWSHAPE, 372, 1, 1, -0.514563,-0.238476, -0.340659,0.172987, -0.100245,0.368967, 0.214334,0.276255, 0.349294,-0.008293, 0.203063,-0.280225, -0.078470,-0.352806, NEWSHAPE, 373, 1, 1, -0.019312,0.304743, -0.289045,0.177117, -0.127176,-0.240665, 0.007400,-0.336712, 0.257684,-0.184398, 0.234654,0.191587, NEWSHAPE, 374, 1, 1, -0.229502,-0.051000, 0.320183,0.006447, 0.148302,0.144065, 0.173317,0.054954, -0.253447,0.021298, -NEWSHAPE, 375, 1, 2, -0.090497,-0.016548, -0.072731,-0.044408, -0.058869,-0.063422, -0.031762,-0.071442, -0.001140,-0.143435, 0.032854,-0.162181, 0.080022,-0.161459, 0.108605,-0.129676, 0.112564,-0.096396, 0.102658,-0.077590, 0.088332,-0.113771, 0.046216,-0.129074, 0.017935,-0.063369, 0.049033,-0.046641, 0.032200,-0.027430, +NEWSHAPE, 375, 1, 2, -0.090497,-0.016548, -0.072731,-0.044408, -0.058869,-0.063422, -0.031762,-0.071442, -0.001140,-0.143435, 0.032854,-0.162181, 0.080022,-0.161459, 0.108605,-0.129676, 0.112564,-0.096396, 0.102658,-0.077590, 0.088332,-0.113771, 0.046216,-0.129074, 0.017935,-0.063369, 0.049033,-0.046641, 0.032200,-0.027430, NEWSHAPE, 376, 1, 1, 0.202167,-0.134605, 0.204591,-0.145446, 0.192856,-0.139999, 0.180908,-0.136821, 0.063679,-0.150430, 0.054862,-0.154571, 0.051985,-0.159521, 0.036546,-0.062257, 0.043529,-0.066187, 0.054300,-0.069873, 0.182749,-0.064458, 0.195918,-0.057169, 0.204973,-0.052339, 0.199643,-0.078121, 0.042703,-0.084239, 0.199470,-0.077992, 0.199531,-0.090084, 0.044591,-0.098658, 0.198774,-0.089982, 0.199787,-0.100708, 0.045748,-0.113148, 0.198272,-0.100502, 0.200147,-0.110605, 0.048127,-0.124053, 0.198630,-0.110398, 0.199672,-0.121163, 0.050049,-0.138713, 0.198913,-0.121059, -NEWSHAPE, 377, 6, 1, -0.206510,0.223410, 0.017622,0.231073, 0.048705,0.240382, 0.069206,0.259727, -NEWSHAPE, 378, 7, 1, 0.349494,-0.088062, 0.159923,-0.228824, 0.145483,-0.260010, 0.142821,-0.290692, -NEWSHAPE, 379, 7, 1, 0.649585,0.084560, 0.623391,0.075842, 0.599921,0.058309, 0.572892,0.035489, 0.552783,-0.024612, +NEWSHAPE, 377, 6, 1, -0.206510,0.223410, 0.017622,0.231073, 0.048705,0.240382, 0.069206,0.259727, +NEWSHAPE, 378, 7, 1, 0.349494,-0.088062, 0.159923,-0.228824, 0.145483,-0.260010, 0.142821,-0.290692, +NEWSHAPE, 379, 7, 1, 0.649585,0.084560, 0.623391,0.075842, 0.599921,0.058309, 0.572892,0.035489, 0.552783,-0.024612, NEWSHAPE, 380, 1, 2, -0.157063,0.003936, -0.151414,0.044436, -0.065427,0.009052, -0.151414,0.044436, -0.151129,0.067964, -0.072440,0.024229, -0.150301,0.069258, -0.113069,0.110826, -0.037964,0.039249, -0.110463,0.109185, -0.011307,0.146227, -0.108855,0.111771, -0.113069,0.110826, -0.110452,0.155897, -0.007227,0.165082, -0.111749,0.156720, -0.114514,0.196200, 0.003252,0.188966, -0.009486,0.143350, 0.043508,0.083540, 0.057523,0.000604, -NEWSHAPE, 381, 1, 2, -0.128015,0.002500, -0.121343,0.106487, -0.104134,0.121999, -0.063293,0.274181, 0.038783,0.286293, 0.071085,0.292868, 0.087907,0.266956, 0.077475,0.243894, 0.083000,0.234337, 0.068629,0.220991, 0.042226,0.206757, 0.023044,0.227068, -0.009573,0.218873, -0.027348,0.140245, -0.005432,-0.096462, 0.020544,-0.030837, +NEWSHAPE, 381, 1, 2, -0.128015,0.002500, -0.121343,0.106487, -0.104134,0.121999, -0.063293,0.274181, 0.038783,0.286293, 0.071085,0.292868, 0.087907,0.266956, 0.077475,0.243894, 0.083000,0.234337, 0.068629,0.220991, 0.042226,0.206757, 0.023044,0.227068, -0.009573,0.218873, -0.027348,0.140245, -0.005432,-0.096462, 0.020544,-0.030837, NEWSHAPE, 382, 1, 2, 0.024784,0.028900, -0.009988,0.111744, -0.018320,0.147991, -0.006519,0.215354, 0.020083,0.223620, 0.029811,0.291799, -0.066579,0.278718, -0.136927,0.082023, -0.147101,-0.050084, NEWSHAPE, 383, 1, 2, 0.164154,0.032677, 0.112722,0.126268, 0.093106,0.144972, 0.036998,0.184005, -0.028137,0.220088, -0.088953,0.208314, -0.221199,0.117397, -0.270025,0.057450, -0.290973,0.020569, -NEWSHAPE, 384, 1, 2, 0.146470,0.021791, 0.134179,0.071381, 0.089857,0.116839, 0.039860,0.139410, -0.005910,0.150902, -0.047971,0.139775, -0.104973,0.100695, -0.147597,0.052809, -0.177722,0.017653, -0.186756,0.003107, +NEWSHAPE, 384, 1, 2, 0.146470,0.021791, 0.134179,0.071381, 0.089857,0.116839, 0.039860,0.139410, -0.005910,0.150902, -0.047971,0.139775, -0.104973,0.100695, -0.147597,0.052809, -0.177722,0.017653, -0.186756,0.003107, NEWSHAPE, 385, 7, 1, 0.354675,0, -NEWSHAPE, 386, 3, 1, 0.173768,0.275379, 0.340287,0.116342, 0.229291,-0.115277, -NEWSHAPE, 387, 7, 1, 0.315263,-0.310217, 0.085056,-0.287538, -NEWSHAPE, 388, 1, 1, 0.046590,0.284199, 0.028110,0.325611, 0.098711,0.333738, 0.088761,0.294314, 0.090351,0.227036, 0.092387,0.196322, 0.129546,0.192006, 0.168982,0.166667, 0.173088,0.117700, 0.022882,0.091527, 0.004586,0.133004, 0.022981,0.160866, 0.052990,0.184313, 0.085413,0.193910, 0.055297,0.184324, +NEWSHAPE, 386, 3, 1, 0.173768,0.275379, 0.340287,0.116342, 0.229291,-0.115277, +NEWSHAPE, 387, 7, 1, 0.315263,-0.310217, 0.085056,-0.287538, +NEWSHAPE, 388, 1, 1, 0.046590,0.284199, 0.028110,0.325611, 0.098711,0.333738, 0.088761,0.294314, 0.090351,0.227036, 0.092387,0.196322, 0.129546,0.192006, 0.168982,0.166667, 0.173088,0.117700, 0.022882,0.091527, 0.004586,0.133004, 0.022981,0.160866, 0.052990,0.184313, 0.085413,0.193910, 0.055297,0.184324, -NEWSHAPE, 389, 1, 2, -0.127943,0.000000, -0.121732,0.008437, -0.120752,0.047093, -0.114785,0.065246, -0.096531,0.082051, -0.079664,0.100183, -0.087015,0.156872, -0.056388,0.171466, -0.021870,0.150662, -0.022997,0.136774, -0.004819,0.120485, 0.007204,0.104455, 0.016748,0.083741, 0.026225,0.054833, 0.033323,0.030943, 0.034483,0.001189, 0.034483,-0.001189, -NEWSHAPE, 390, 1, 1, -0.079664,0.100183, -0.087015,0.156872, -0.090442,0.188317, -0.085023,0.215058, -0.078296,0.241201, -0.070101,0.263835, -0.062700,0.273833, -0.053763,0.276497, -0.037212,0.273273, -0.026261,0.230095, -0.024880,0.217700, -0.022225,0.198787, -0.020850,0.180288, -0.021870,0.150662, -0.022997,0.136774, -0.036634,0.100744, -NEWSHAPE, 391, 1, 1, -0.063645,0.226806, -0.078296,0.241201, -0.070101,0.263835, -0.062700,0.273833, -0.053763,0.276497, -0.030638,0.274461, -0.015319,0.275737, 0.001277,0.277150, 0.020384,0.271369, 0.038101,0.262896, 0.045596,0.255842, 0.062388,0.263558, 0.085371,0.258660, 0.084235,0.228817, 0.071073,0.213220, 0.048603,0.218088, 0.042541,0.228972, 0.028749,0.228742, 0.011222,0.224439, -0.012498,0.229969, -0.026261,0.230095, +NEWSHAPE, 389, 1, 2, -0.127943,0.000000, -0.121732,0.008437, -0.120752,0.047093, -0.114785,0.065246, -0.096531,0.082051, -0.079664,0.100183, -0.087015,0.156872, -0.056388,0.171466, -0.021870,0.150662, -0.022997,0.136774, -0.004819,0.120485, 0.007204,0.104455, 0.016748,0.083741, 0.026225,0.054833, 0.033323,0.030943, 0.034483,0.001189, 0.034483,-0.001189, +NEWSHAPE, 390, 1, 1, -0.079664,0.100183, -0.087015,0.156872, -0.090442,0.188317, -0.085023,0.215058, -0.078296,0.241201, -0.070101,0.263835, -0.062700,0.273833, -0.053763,0.276497, -0.037212,0.273273, -0.026261,0.230095, -0.024880,0.217700, -0.022225,0.198787, -0.020850,0.180288, -0.021870,0.150662, -0.022997,0.136774, -0.036634,0.100744, +NEWSHAPE, 391, 1, 1, -0.063645,0.226806, -0.078296,0.241201, -0.070101,0.263835, -0.062700,0.273833, -0.053763,0.276497, -0.030638,0.274461, -0.015319,0.275737, 0.001277,0.277150, 0.020384,0.271369, 0.038101,0.262896, 0.045596,0.255842, 0.062388,0.263558, 0.085371,0.258660, 0.084235,0.228817, 0.071073,0.213220, 0.048603,0.218088, 0.042541,0.228972, 0.028749,0.228742, 0.011222,0.224439, -0.012498,0.229969, -0.026261,0.230095, NEWSHAPE, 392, 1, 2, 0.060794,0.001192, 0.058426,0.023847, 0.050054,0.030986, 0.042896,0.038130, 0.044109,0.042917, 0.032180,0.050058, 0.017884,0.059612, 0.005963,0.064401, -0.009546,0.068015, -0.022689,0.070455, -0.053753,0.053753, -0.065710,0.040621, -0.074098,0.028683, -0.088611,0.020357, -0.087387,0.017956, NEWSHAPE }; -#endif - -#endif } +#endif diff --git a/racing.cpp b/racing.cpp index 552a53f3..3c3fb534 100644 --- a/racing.cpp +++ b/racing.cpp @@ -1316,7 +1316,7 @@ void markers() { draw_ghost(ghost); if(gmatrix.count(track[0])) { - hyperpoint h = WDIM == 2 && GDIM == 3 ? zpush(geom3::FLOOR - geom3::human_height/80) * C0 : C0; + hyperpoint h = WDIM == 2 && GDIM == 3 ? zpush(cgi.FLOOR - cgi.human_height/80) * C0 : C0; for(ld z=-start_line_width; z<=start_line_width; z+=0.1) curvepoint(ggmatrix(track[0]) * straight * parabolic1(z) * h); queuecurve(0xFFFFFFFF, 0, PPR::BFLOOR); diff --git a/rug.cpp b/rug.cpp index 91090563..3f235fe1 100644 --- a/rug.cpp +++ b/rug.cpp @@ -476,7 +476,7 @@ void buildTorusRug() { println(hlog, "factor = ", make_tuple(xfactor, yfactor, factor)); println(hlog, "scales = ", make_tuple(xscale, yscale)); - modelscale = xscale / crossf; + modelscale = xscale / cgi.crossf; } map, rugpoint*> glues; diff --git a/screenshot.cpp b/screenshot.cpp index 859aa1fb..fff65691 100644 --- a/screenshot.cpp +++ b/screenshot.cpp @@ -677,7 +677,6 @@ void apply() { } } apply_animated_parameters(); - if(need_reset_geometry) resetGeometry(), need_reset_geometry = false; calcparam(); } @@ -1120,12 +1119,12 @@ reaction_t add_to_frame; #if CAP_STARTANIM void draw_ghost(const transmatrix V, int id) { if(id % 13 == 0) { - queuepoly(V, shMiniGhost, 0xFFFF00C0); - queuepoly(V, shMiniEyes, 0xFF); + queuepoly(V, cgi.shMiniGhost, 0xFFFF00C0); + queuepoly(V, cgi.shMiniEyes, 0xFF); } else { - queuepoly(V, shMiniGhost, 0xFFFFFFC0); - queuepoly(V, shMiniEyes, 0xFF); + queuepoly(V, cgi.shMiniGhost, 0xFFFFFFC0); + queuepoly(V, cgi.shMiniEyes, 0xFF); } } diff --git a/shmup.cpp b/shmup.cpp index 5c2344cb..e7db4832 100644 --- a/shmup.cpp +++ b/shmup.cpp @@ -950,7 +950,7 @@ void profile(const char *buf) { } */ -#define SCALE scalefactor +#define SCALE cgi.scalefactor #define SCALE2 (SCALE*SCALE) namespace shmup { @@ -1076,7 +1076,7 @@ bool trackroute(monster *m, transmatrix goal, double spd) { d += spd; transmatrix nat = m->pat * rspintox(mat * C0) * xpush(d); - // queuepoly(nat, shKnife, 0xFFFFFFC0); + // queuepoly(nat, cgi.shKnife, 0xFFFFFFC0); cell *c2 = findbaseAround(nat, c); if(c2 != c && !passable_for(m->type, c2, c, P_CHAIN | P_ONPLAYER)) { @@ -1418,7 +1418,7 @@ void roseCurrents(transmatrix& nat, monster *m, int delta) { hyperpoint keytarget(int i) { double d = 2 + sin(curtime / 350.); - return pc[i]->pat * cpush0(WDIM == 3 ? 2 : 0, d * scalefactor); + return pc[i]->pat * cpush0(WDIM == 3 ? 2 : 0, d * cgi.scalefactor); } /* int charidof(int pid) { @@ -1428,8 +1428,8 @@ hyperpoint keytarget(int i) { return 0; } */ -ld getSwordSize() { return sword_size; } -ld getHornsSize() { return scalefactor * 0.33; } +ld getSwordSize() { return cgi.sword_size; } +ld getHornsSize() { return cgi.scalefactor * 0.33; } // used in 3D transmatrix swordmatrix[MAXPLAYER]; @@ -1777,7 +1777,7 @@ void movePlayer(monster *m, int delta) { if(isReptile(m->base->wall)) m->base->wparam = reptilemax(); - int steps = 1 + abs(int(playergo[cpid] / (.2 * scalefactor))); + int steps = 1 + abs(int(playergo[cpid] / (.2 * cgi.scalefactor))); playergo[cpid] /= steps; @@ -2385,7 +2385,7 @@ transmatrix frontpush(ld x) { ld collision_distance(monster *bullet, monster *target) { if(target->type == moAsteroid) - return SCALE * 0.15 + asteroid_size[target->hitpoints & 7]; + return SCALE * 0.15 + cgi.asteroid_size[target->hitpoints & 7]; return SCALE * 0.3; } @@ -3601,12 +3601,12 @@ bool drawMonster(const transmatrix& V, cell *c, const transmatrix*& Vboat, trans color_t incolor = magic ? 0x0060C0FF : 0x804000FF; if(WDIM == 2) { - queuepoly(Vboat0, shBoatOuter, outcolor); - queuepoly(Vboat0, shBoatInner, incolor); + queuepoly(Vboat0, cgi.shBoatOuter, outcolor); + queuepoly(Vboat0, cgi.shBoatInner, incolor); } if(WDIM == 3) { - queuepoly(mscale(Vboat0, scalefactor/2), shBoatOuter, outcolor); - queuepoly(mscale(Vboat0, scalefactor/2-0.01), shBoatInner, incolor); + queuepoly(mscale(Vboat0, cgi.scalefactor/2), cgi.shBoatOuter, outcolor); + queuepoly(mscale(Vboat0, cgi.scalefactor/2-0.01), cgi.shBoatInner, incolor); } } @@ -3651,7 +3651,7 @@ bool drawMonster(const transmatrix& V, cell *c, const transmatrix*& Vboat, trans queuechr(h, vid.fsize, '+', iinf[keyresult[cpid]].color); else { dynamicval p(poly_outline, darkena(iinf[keyresult[cpid]].color, 0, 255)); - queuepoly(rgpushxto0(h) * cspin(0, 1, ticks / 140.), shGem[1], 0); + queuepoly(rgpushxto0(h) * cspin(0, 1, ticks / 140.), cgi.shGem[1], 0); } } @@ -3667,39 +3667,39 @@ bool drawMonster(const transmatrix& V, cell *c, const transmatrix*& Vboat, trans else col = (minf[m->parenttype].color << 8) | 0xFF; if(getcs().charid >= 4) { - queuepoly(mmscale(view, 1.15), shPHead, col); - ShadowV(view, shPHead); + queuepoly(mmscale(view, 1.15), cgi.shPHead, col); + ShadowV(view, cgi.shPHead); } else if(peace::on) { - queuepolyat(mmscale(view, 1.15), shDisk, col, PPR::MISSILE); - ShadowV(view, shPHead); + queuepolyat(mmscale(view, 1.15), cgi.shDisk, col, PPR::MISSILE); + ShadowV(view, cgi.shPHead); } else { transmatrix t = view * spin(curtime / 50.0); - queuepoly(WDIM == 3 ? t : DIM == 3 ? mscale(t, geom3::BODY) : mmscale(t, 1.15), shKnife, col); - ShadowV(t, shKnife); + queuepoly(WDIM == 3 ? t : DIM == 3 ? mscale(t, cgi.BODY) : mmscale(t, 1.15), cgi.shKnife, col); + ShadowV(t, cgi.shKnife); } break; } case moArrowTrap: { - queuepoly(mmscale(view, 1.15), shTrapArrow, 0xFFFFFFFF); - ShadowV(view, shTrapArrow); + queuepoly(mmscale(view, 1.15), cgi.shTrapArrow, 0xFFFFFFFF); + ShadowV(view, cgi.shTrapArrow); break; } case moTongue: { - queuepoly(mmscale(view, 1.15), shTongue, (minf[m->parenttype].color << 8) | 0xFF); - ShadowV(view, shTongue); + queuepoly(mmscale(view, 1.15), cgi.shTongue, (minf[m->parenttype].color << 8) | 0xFF); + ShadowV(view, cgi.shTongue); break; } case moFireball: case moAirball: { // case moLightningBolt: - queuepoly(mmscale(view, 1.15), shPHead, (minf[m->type].color << 8) | 0xFF); - ShadowV(view, shPHead); + queuepoly(mmscale(view, 1.15), cgi.shPHead, (minf[m->type].color << 8) | 0xFF); + ShadowV(view, cgi.shPHead); break; } case moFlailBullet: case moCrushball: { transmatrix t = view * spin(curtime / 50.0); - queuepoly(mmscale(t, 1.15), shFlailMissile, (minf[m->type].color << 8) | 0xFF); - ShadowV(view, shFlailMissile); + queuepoly(mmscale(t, 1.15), cgi.shFlailMissile, (minf[m->type].color << 8) | 0xFF); + ShadowV(view, cgi.shFlailMissile); break; } case moAsteroid: { @@ -3707,11 +3707,11 @@ bool drawMonster(const transmatrix& V, cell *c, const transmatrix*& Vboat, trans transmatrix t = view; if(WDIM == 3) t = face_the_player(t); t = t * spin(curtime / 500.0); - ShadowV(t, shAsteroid[m->hitpoints & 7]); + ShadowV(t, cgi.shAsteroid[m->hitpoints & 7]); if(WDIM == 2) t = mmscale(t, 1.15); color_t col = WDIM == 3 ? 0xFFFFFF : minf[m->type].color; col <<= 8; - queuepoly(t, shAsteroid[m->hitpoints & 7], col | 0xFF); + queuepoly(t, cgi.shAsteroid[m->hitpoints & 7], col | 0xFF); break; } diff --git a/system.cpp b/system.cpp index 60e29064..aa22a7dc 100644 --- a/system.cpp +++ b/system.cpp @@ -6,8 +6,6 @@ namespace hr { -bool need_reset_geometry = true; - bool game_active; bool cblind; @@ -1091,39 +1089,48 @@ namespace gamestack { eGeometry geometry; eVariation variation; bool shmup; + void store(); + void restore(); }; vector gd; bool pushed() { return isize(gd); } + void gamedata::store() { + hmap = currentmap; + cwt = hr::cwt; + geometry = hr::geometry; + shmup = hr::shmup::on; + variation = hr::variation; + d = *current_display; + } + + void gamedata::restore() { + currentmap = hmap; + hr::cwt = cwt; + hr::geometry = geometry; + hr::variation = variation; + if(shmup::on) shmup::clearMonsters(); + shmup::on = shmup; + check_cgi(); + cgi.require_basics(); + *current_display = d; + bfs(); + } + void push() { if(geometry) { printf("ERROR: push implemented only in non-hyperbolic geometry\n"); exit(1); } - gamedata gdn; - gdn.hmap = currentmap; - gdn.cwt = cwt; - gdn.geometry = geometry; - gdn.shmup = shmup::on; - gdn.variation = variation; - gdn.d = *current_display; - gd.push_back(gdn); + gd.emplace_back(); + gd.back().store(); } void pop() { - gamedata& gdn = gd[isize(gd)-1]; - currentmap = gdn.hmap; - cwt = gdn.cwt; - geometry = gdn.geometry; - variation = gdn.variation; - if(shmup::on) shmup::clearMonsters(); - shmup::on = gdn.shmup; - resetGeometry(); - *current_display = gdn.d; + gd.back().restore(); gd.pop_back(); - bfs(); } }; @@ -1215,8 +1222,6 @@ void set_geometry(eGeometry target) { #endif if(DIM == 3 && old_DIM == 2 && pmodel == mdDisk) pmodel = mdPerspective; if(DIM == 2 && pmodel == mdPerspective) pmodel = mdDisk; - - need_reset_geometry = true; } } @@ -1231,7 +1236,6 @@ void set_variation(eVariation target) { target = eVariation::pure; } variation = target; - need_reset_geometry = true; } } @@ -1256,7 +1260,6 @@ void switch_game_mode(char switchWhat) { case rg::chaos: if(tactic::on) firstland = laIce; yendor::on = tactic::on = princess::challenge = false; - need_reset_geometry = true; chaosmode = !chaosmode; if(bounded) set_geometry(gNormal); racing::on = false; @@ -1272,7 +1275,6 @@ void switch_game_mode(char switchWhat) { gp::param = gp::loc(1, 1); #endif shmup::on = false; - need_reset_geometry = true; tour::on = !tour::on; racing::on = false; break; @@ -1359,7 +1361,8 @@ void start_game() { restart: game_active = true; gamegen_failure = false; - if(need_reset_geometry) resetGeometry(), need_reset_geometry = false; + check_cgi(); + cgi.require_basics(); initcells(); expansion.reset(); diff --git a/textures.cpp b/textures.cpp index 88a284fc..e1309466 100644 --- a/textures.cpp +++ b/textures.cpp @@ -337,7 +337,7 @@ bool texture_config::apply(cell *c, const transmatrix &V, color_t col) { if(config.tstate == tsAdjusting) { dynamicval d(poly_outline, slave_color); - draw_floorshape(c, V, shFullFloor, 0, PPR::LINE); + draw_floorshape(c, V, cgi.shFullFloor, 0, PPR::LINE); curvepoint(V * C0); for(int i=0; itype; i++) @@ -349,13 +349,13 @@ bool texture_config::apply(cell *c, const transmatrix &V, color_t col) { try { auto& mi = texture_map.at(si.id); - set_floor(shFullFloor); + set_floor(cgi.shFullFloor); qfi.tinf = &mi; qfi.spin = applyPatterndir(c, si); if(grid_color) { dynamicval d(poly_outline, grid_color); - draw_floorshape(c, V, shFullFloor, 0, PPR::FLOOR); + draw_floorshape(c, V, cgi.shFullFloor, 0, PPR::FLOOR); } if(using_aura()) { @@ -1571,7 +1571,6 @@ int textureArgs() { else if(argis("-txcl")) { PHASE(3); drawscreen(); config.load(); - need_reset_geometry = true; } else return 1; diff --git a/usershapes.cpp b/usershapes.cpp new file mode 100644 index 00000000..a530653b --- /dev/null +++ b/usershapes.cpp @@ -0,0 +1,108 @@ +#if CAP_SHAPES + +// HyperRogue, some functions for user-defined shapes + +// Copyright (C) 2011-2019 Zeno Rogue, see 'hyper.cpp' for details + +namespace hr { + +int usershape_changes; + +array, mapeditor::USERSHAPEGROUPS> usershapes; +void initShape(int sg, int id) { + + if(!usershapes[sg][id]) { + usershape *us = new usershape; + usershapes[sg][id] = us; + + for(int i=0; id[i].prio = PPR((sg == 3 ? 1:50) + i); + + us->d[i].rots = 1; + us->d[i].sym = 0; + us->d[i].shift = C0; + us->d[i].spin = Cx1; + us->d[i].color = 0; + us->d[i].zlevel = 0; + } + } + } + +basic_textureinfo user_triangles_texture; + +void geometry_information::pushShape(usershapelayer& ds) { + + if(ds.list.empty()) return; + if(DIM == 3) last->flags |= POLY_TRIANGLES; + + transmatrix T = rgpushxto0(ds.shift) * rspintox(ds.spin); + + int z = DIM == 3 ? 3 : 1; + + for(int r=0; r=0; i--) + hpcpush(T * spin(2*M_PI*r/ds.rots) * mirrortrans * ds.list[i]); + } + } + + if(DIM == 2) hpcpush(T * ds.list[0]); + + #if MAXMDIM >= 4 + if(DIM == 3) { + auto& utt = user_triangles_texture; + utt.texture_id = floor_textures->renderedTexture; + ds.texture_offset = isize(utt.tvertices); + for(int i=0; i