--- deliantra/Deliantra-Client/Client.xs 2007/04/21 09:21:03 1.185 +++ deliantra/Deliantra-Client/Client.xs 2007/07/12 17:56:50 1.194 @@ -8,6 +8,11 @@ # pragma warning(disable:4761) #endif +//#define DEBUG 1 +#if DEBUG +# include +#endif + #include "EXTERN.h" #include "perl.h" #include "XSUB.h" @@ -58,6 +63,8 @@ # define PARACHUTE 0 #endif +static AV *texture_av; + static struct { #define GL_FUNC(ptr,name) ptr name; @@ -65,7 +72,8 @@ #undef GL_FUNC } gl; -static void gl_BlendFuncSeparate (GLenum sa, GLenum da, GLenum saa, GLenum daa) +static void +gl_BlendFuncSeparate (GLenum sa, GLenum da, GLenum saa, GLenum daa) { if (gl.BlendFuncSeparate) gl.BlendFuncSeparate (sa, da, saa, daa); @@ -75,6 +83,30 @@ glBlendFunc (sa, da); } +static GLuint +gen_texture () +{ + GLuint name; + + if (AvFILL (texture_av) >= 0) + name = (GLuint)(size_t)av_pop (texture_av); + else + glGenTextures (1, &name); + + return name; +} + +static void +del_texture (GLuint 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 *)(size_t)name); + glDeleteTextures (1, &name); +} + #include "texcache.c" #include "pango-font.c" @@ -402,17 +434,12 @@ #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; @@ -621,10 +648,13 @@ ); if (RETVAL) { + av_clear (texture_av); + SDL_WM_SetCaption ("Crossfire+ Client " VERSION, "Crossfire+"); # define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name); # include "glfunc.h" # undef GL_FUNC + } OUTPUT: RETVAL @@ -859,6 +889,15 @@ _exit (retval); #endif +void +debug () + CODE: +{ +#if DEBUG + VALGRIND_DO_LEAK_CHECK; +#endif +} + MODULE = CFPlus PACKAGE = CFPlus::Font CFPlus::Font @@ -1398,12 +1437,12 @@ if (dx > 0) map_blank (self, self->x, self->y, dx, self->h); else if (dx < 0) - map_blank (self, self->x + self->w + dx + 1, self->y, -dx, self->h); + map_blank (self, self->x + self->w + dx, self->y, -dx, self->h); if (dy > 0) map_blank (self, self->x, self->y, self->w, dy); else if (dy < 0) - map_blank (self, self->x, self->y + self->h + dy + 1, self->w, -dy); + map_blank (self, self->x, self->y + self->h + dy, self->w, -dy); self->ox += dx; self->x += dx; self->oy += dy; self->y += dy; @@ -1602,7 +1641,6 @@ // 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) @@ -1623,6 +1661,8 @@ 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) { @@ -1717,79 +1757,79 @@ } } } - } - // go through all smoothlevels, lowest to highest, then draw. - // this is basically counting sort - { - int w, b; - - for (w = 0; w < 256 / 32; ++w) + // go through all smoothlevels, lowest to highest, then draw. + // this is basically counting sort { - 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; + int w, b; - hv_iterinit (smooth); - while ((he = hv_iternext (smooth))) + 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)) { - smooth_key *skey = (smooth_key *)HeKEY (he); - IV bits = SvIVX (HeVAL (he)); + int level = (w << 5) | b; + HE *he; - if (!(bits & 0x1000) - && skey->level == level - && level >= smooth_max [skey->x][skey->y]) + hv_iterinit (smooth); + while ((he = hv_iternext (smooth))) { - 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 + smooth_key *skey = (smooth_key *)HeKEY (he); + IV bits = SvIVX (HeVAL (he)); - glEnd (); - glBindTexture (GL_TEXTURE_2D, last_name = tex.name); - glBegin (GL_QUADS); - } - - if (border) + if (!(bits & 0x1000) + && skey->level == level + && level > smooth_max [skey->x][skey->y]) { - 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 ); + 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 ); + } } } } - } + } } - } - //hv_clear (smooth); + hv_clear (smooth); + } glEnd (); @@ -2102,6 +2142,13 @@ OUTPUT: RETVAL +int +fade_out (int ms) + CODE: + RETVAL = Mix_FadeOutMusic (ms); + OUTPUT: + RETVAL + CFPlus::MixMusic new_from_file (SV *class, char *path) CODE: @@ -2216,6 +2263,9 @@ for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); + + texture_av = newAV (); + AvREAL_off (texture_av); } char * @@ -2374,28 +2424,14 @@ int glGenTexture () CODE: -{ - GLuint name; - if (AvFILL (texture_av) >= 0) - name = (GLuint)av_pop (texture_av); - else - glGenTextures (1, &name); - RETVAL = name; -} + RETVAL = gen_texture (); OUTPUT: RETVAL void glDeleteTexture (int name) CODE: -{ - /* 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_);*/ -} - + del_texture (name); + int glGenList () CODE: RETVAL = glGenLists (1);