--- deliantra/Deliantra-Client/Client.xs 2018/11/18 01:15:04 1.321 +++ deliantra/Deliantra-Client/Client.xs 2018/11/18 01:43:12 1.322 @@ -17,6 +17,8 @@ #include "perl.h" #include "XSUB.h" +#include "flat_hash_map.hpp" + #ifdef _WIN32 # undef pipe // microsoft vs. C @@ -25,11 +27,13 @@ # define M_PI 3.14159265f #endif -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include + +#include #define USE_RWOPS 1 // for SDL_mixer:LoadMUS_RW @@ -441,20 +445,39 @@ } } -typedef struct { +struct smooth_key +{ tileid tile; uint8_t x, y, level; -} smooth_key; + + bool operator == (const smooth_key &o) const + { + return tile == o.tile && x == o.x && y == o.y && level == o.level; + } +}; + +typedef ska::flat_hash_map smooth_hash; + +namespace std { + template <> + struct hash + { + size_t operator () (const smooth_key &v) const + { + return v.tile + (v.x << 8) + (v.y << 16) + (v.level << 24); + } + }; +} static void -smooth_or_bits (HV *hv, smooth_key *key, IV bits) +smooth_or_bits (smooth_hash &h, smooth_key &key, IV bits) { - SV **sv = hv_fetch (hv, (char *)key, sizeof (*key), 1); + auto &&it = h.find (key); - if (SvIOK (*sv)) - SvIV_set (*sv, SvIVX (*sv) | bits); + if (it == h.end ()) + h.insert (std::make_pair (key, bits)); else - sv_setiv (*sv, bits); + it->second |= bits; } static void @@ -2195,7 +2218,6 @@ { int x, y, z; - HV *smooth = (HV *)sv_2mortal ((SV *)newHV ()); uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level static uint8_t smooth_max[256][256]; // egad, fast and wasteful on memory (64k) smooth_key skey; @@ -2254,6 +2276,7 @@ for (z = 0; z <= 2; z++) { + smooth_hash smooth; memset (smooth_level, 0, sizeof (smooth_level)); key.texname = -1; @@ -2324,19 +2347,19 @@ // ·· ·· ·┏ ┓· // full tile - skey.x = x + 1; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x1000); + skey.x = x + 1; skey.y = y + 1; smooth_or_bits (smooth, skey, 0x1000); // borders - skey.x = x + 2; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x0091); - skey.x = x + 1; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0032); - skey.x = x ; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x0064); - skey.x = x + 1; skey.y = y ; smooth_or_bits (smooth, &skey, 0x00c8); + skey.x = x + 2; skey.y = y + 1; smooth_or_bits (smooth, skey, 0x0091); + skey.x = x + 1; skey.y = y + 2; smooth_or_bits (smooth, skey, 0x0032); + skey.x = x ; skey.y = y + 1; smooth_or_bits (smooth, skey, 0x0064); + skey.x = x + 1; skey.y = y ; smooth_or_bits (smooth, skey, 0x00c8); // corners - skey.x = x + 2; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0100); - skey.x = x ; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0200); - skey.x = x ; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0400); - skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0800); + skey.x = x + 2; skey.y = y + 2; smooth_or_bits (smooth, skey, 0x0100); + skey.x = x ; skey.y = y + 2; smooth_or_bits (smooth, skey, 0x0200); + skey.x = x ; skey.y = y ; smooth_or_bits (smooth, skey, 0x0400); + skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, skey, 0x0800); } } @@ -2383,19 +2406,18 @@ int level = (w << 5) | b; HE *he; - hv_iterinit (smooth); - while ((he = hv_iternext (smooth))) + for (auto &&it = smooth.begin (); it != smooth.end (); ++it) { - smooth_key *skey = (smooth_key *)HeKEY (he); - IV bits = SvIVX (HeVAL (he)); + smooth_key &skey = it->first; + IV bits = it->second; if (!(bits & 0x1000) - && skey->level == level - && level > smooth_max [skey->x][skey->y]) + && skey.level == level + && level > smooth_max [skey.x][skey.y]) { - maptex tex = self->tex [skey->tile]; - int px = (((int)skey->x) - 1) * Tw; - int py = (((int)skey->y) - 1) * Th; + maptex tex = self->tex [skey.tile]; + int px = (((int)skey.x) - 1) * Tw; + int py = (((int)skey.y) - 1) * Th; int border = bits & 15; int corner = (bits >> 8) & ~(bits >> 4) & 15; float dx = tex.s * .0625f; // 16 images/row @@ -2407,7 +2429,7 @@ // save gobs of state changes. if (key.texname != tex.name) { - self->tex [skey->tile].unused = 0; + self->tex [skey.tile].unused = 0; glEnd (); glBindTexture (GL_TEXTURE_2D, key.texname = tex.name); @@ -2443,8 +2465,6 @@ glDisable (GL_TEXTURE_2D); key.texname = -1; } - - hv_clear (smooth); } if (pl_tex.name)