--- deliantra/Deliantra-Client/Client.xs 2007/04/10 09:39:48 1.176 +++ deliantra/Deliantra-Client/Client.xs 2007/04/21 09:21:03 1.185 @@ -347,7 +347,7 @@ static void smooth_or_bits (HV *hv, smooth_key *key, IV bits) { - SV **sv = hv_fetch (hv, (char *)key, sizeof (key), 1); + SV **sv = hv_fetch (hv, (char *)key, sizeof (*key), 1); if (SvIOK (*sv)) SvIV_set (*sv, SvIVX (*sv) | bits); @@ -402,12 +402,17 @@ #define SDLK_MODIFIER_MIN 300 #define SDLK_MODIFIER_MAX 314 +static AV *texture_av; + MODULE = CFPlus PACKAGE = CFPlus PROTOTYPES: ENABLE BOOT: { + texture_av = newAV (); + AvREAL_off (texture_av); + HV *stash = gv_stashpv ("CFPlus", 1); static const struct { const char *name; @@ -703,9 +708,7 @@ void lowdelay (int fd, int val = 1) CODE: -#ifndef _WIN32 - setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof (val)); -#endif + setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&val, sizeof (val)); void win32_proxy_info () @@ -1464,8 +1467,8 @@ cell->stat_width = *data++ + 1; else if (cmd == 0x47) { - if (*data == 8) - ; // decode player uuid + if (*data == 4) + ; // decode player count data += *data + 1; } @@ -1569,7 +1572,7 @@ { HV *smooth = (HV *)sv_2mortal ((SV *)newHV ()); uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level - uint8_t smooth_max[256][256]; + static uint8_t smooth_max[256][256]; // egad, fats and wasteful on memory (64k) smooth_key skey; int x, y, z; int last_name; @@ -1599,6 +1602,7 @@ // rather ugly, if you ask me // could also be stored inside mapcell and updated on change memset (smooth_max, 0, sizeof (smooth_max)); + memset (smooth_level, 0, sizeof (smooth_level)); for (y = 0; y < sh; y++) if (0 <= y + my && y + my < self->rows) @@ -1610,19 +1614,15 @@ { mapcell *cell = row->col + (x + mx - row->c0); - for (z = 0; z <= 2; z++) - { - uint8_t level = self->tex [cell->tile [z]].smoothlevel; - if (level > smooth_max [x + 1][y + 1]) - smooth_max [x + 1][y + 1] = level; - } + smooth_max[x + 1][y + 1] = + MAX (self->tex [cell->tile [0]].smoothlevel, + MAX (self->tex [cell->tile [1]].smoothlevel, + self->tex [cell->tile [2]].smoothlevel)); } } for (z = 0; z <= 2; z++) { - memset (smooth_level, 0, sizeof (smooth_level)); - for (y = 0; y < sh; y++) if (0 <= y + my && y + my < self->rows) { @@ -1687,12 +1687,24 @@ // add bits to current tile and all neighbours. skey.x|y is // shifted +1|+1 so we always stay positive. + // bits is ___n cccc CCCC bbbb + // n do not draw borders&corners + // c draw these corners, but... + // C ... not these + // b draw these borders + + // borders: 1 ┃· 2 ━━ 4 ·┃ 8 ·· + // ┃· ·· ·┃ ━━ + + // corners: 1 ┛· 2 ·┗ 4 ·· 8 ·· + // ·· ·· ·┏ ┓· + // full tile 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, 0x0031); - skey.x = x + 1; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0092); + 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); @@ -1705,85 +1717,79 @@ } } } + } + + // go through all smoothlevels, lowest to highest, then draw. + // this is basically counting sort + { + int w, b; - // go through all smoothlevels, lowest to highest, then draw - // this is basically counting sort + for (w = 0; w < 256 / 32; ++w) { - int w, b; + uint32_t smask = smooth_level [w]; + if (smask) + for (b = 0; b < 32; ++b) + if (smask & (((uint32_t)1) << b)) + { + int level = (w << 5) | b; + HE *he; - for (w = 0; w < 256 / 32; ++w) - { - uint32_t smask = smooth_level [w]; - if (smask) - for (b = 0; b < 32; ++b) - if (smask & (((uint32_t)1) << b)) + hv_iterinit (smooth); + while ((he = hv_iternext (smooth))) { - int level = (w << 5) | b; - HE *he; + smooth_key *skey = (smooth_key *)HeKEY (he); + IV bits = SvIVX (HeVAL (he)); - hv_iterinit (smooth); - while ((he = hv_iternext (smooth))) + if (!(bits & 0x1000) + && skey->level == level + && level >= smooth_max [skey->x][skey->y]) { - smooth_key *skey = (smooth_key *)HeKEY (he); - IV bits = SvIVX (HeVAL (he)); + maptex tex = self->tex [skey->tile]; + int px = (((int)skey->x) - 1) * T; + int py = (((int)skey->y) - 1) * T; + int border = bits & 15; + int corner = (bits >> 8) & ~(bits >> 4) & 15; + float dx = tex.s * .0625f; // 16 images/row + float dy = tex.t * .5f ; // 2 images/column + + // this time naively avoiding texture state changes + // save gobs of state changes. + if (last_name != tex.name) + { + if (!tex.name) + continue; // smoothing not yet available - // bits is ___n cccc CCCC bbbb - // n do not draw borders&corners - // c draw these corners, but... - // C ... not these - // b draw these borders - - if (!(bits & 0x1000) - && skey->level == level - && level >= smooth_max [skey->x][skey->y]) + glEnd (); + glBindTexture (GL_TEXTURE_2D, last_name = tex.name); + glBegin (GL_QUADS); + } + + if (border) + { + float ox = border * dx; + + glTexCoord2f (ox , 0.f ); glVertex2f (px , py ); + glTexCoord2f (ox , dy ); glVertex2f (px , py + T); + glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py + T); + glTexCoord2f (ox + dx, 0.f ); glVertex2f (px + T, py ); + } + + if (corner) { - maptex tex = self->tex [skey->tile]; - int px = (((int)skey->x) - 1) * T; - int py = (((int)skey->y) - 1) * T; - int border = bits & 15; - int corner = (bits >> 8) & ~(bits >> 4) & 15; - float dx = tex.s * .0625f; // 16 images/row - float dy = tex.t * .5f ; // 2 images/column - - // this time naively avoiding texture state changes - // save gobs of state changes. - if (last_name != tex.name) - { - if (!tex.name) - continue; // smoothing not yet available - - glEnd (); - glBindTexture (GL_TEXTURE_2D, last_name = tex.name); - glBegin (GL_QUADS); - } - - if (border) - { - float ox = border * dx; - - glTexCoord2f (ox , 0.f ); glVertex2f (px , py ); - glTexCoord2f (ox , dy ); glVertex2f (px , py + T); - glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py + T); - glTexCoord2f (ox + dx, 0.f ); glVertex2f (px + T, py ); - } - - if (corner) - { - float ox = corner * dx; - - glTexCoord2f (ox , dy ); glVertex2f (px , py ); - glTexCoord2f (ox , dy * 2.f); glVertex2f (px , py + T); - glTexCoord2f (ox + dx, dy * 2.f); glVertex2f (px + T, py + T); - glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py ); - } + float ox = corner * dx; + + glTexCoord2f (ox , dy ); glVertex2f (px , py ); + glTexCoord2f (ox , dy * 2.f); glVertex2f (px , py + T); + glTexCoord2f (ox + dx, dy * 2.f); glVertex2f (px + T, py + T); + glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py ); } } } - } + } } + } - hv_clear (smooth); - } + //hv_clear (smooth); glEnd (); @@ -2370,7 +2376,10 @@ CODE: { GLuint name; - glGenTextures (1, &name); + if (AvFILL (texture_av) >= 0) + name = (GLuint)av_pop (texture_av); + else + glGenTextures (1, &name); RETVAL = name; } OUTPUT: @@ -2379,8 +2388,12 @@ void glDeleteTexture (int name) CODE: { - GLuint name_ = name; - glDeleteTextures (1, &name_); + /* make a half-assed attempt at returning the memory used by the texture */ + /* textures are frequently being reused by cfplus anyway */ + glBindTexture (GL_TEXTURE_2D, name); + glTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA, 0, 0, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0); + av_push (texture_av, (SV *)name); + /*glDeleteTextures (1, &name_);*/ } int glGenList ()