--- deliantra/Deliantra-Client/Client.xs 2009/12/21 23:52:34 1.296 +++ deliantra/Deliantra-Client/Client.xs 2010/10/14 00:02:39 1.306 @@ -43,6 +43,8 @@ /* work around os x broken headers */ #ifdef __MACOSX__ typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); #endif #define PANGO_ENABLE_BACKEND @@ -99,7 +101,25 @@ #define TEXID_SPEECH 1 #define TEXID_NOFACE 2 -#define TEXID_HIDDEN 3 + +static char * +fast_sv_grow (SV *sv, STRLEN need) +{ + STRLEN len = SvLEN (sv); + STRLEN want = SvCUR (sv) + need; + + if (expect_false (len < want)) + { + do + len *= 2; + while (len < want); + + sv_grow (sv, len); + } + + SvCUR_set (sv, want); + return SvEND (sv) - need; +} static AV *texture_av; @@ -464,6 +484,12 @@ } static unsigned int +div255 (unsigned int n) +{ + return (n + (n >> 8)) >> 8; +} + +static unsigned int minpot (unsigned int n) { if (!n) @@ -931,6 +957,9 @@ #define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name); #include "glfunc.h" #undef GL_FUNC + + if (!gl.ActiveTexture ) gl.ActiveTexture = gl.ActiveTextureARB; + if (!gl.MultiTexCoord2f) gl.MultiTexCoord2f = gl.MultiTexCoord2fARB; } } OUTPUT: @@ -1025,6 +1054,19 @@ } } +char * +SDL_AudioDriverName () + CODE: +{ + char buf [256]; + if (!SDL_AudioDriverName (buf, sizeof (buf))) + XSRETURN_UNDEF; + + RETVAL = buf; +} + OUTPUT: + RETVAL + int Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 4096) POSTCALL: @@ -1098,6 +1140,9 @@ RETVAL void +IMG_Init (int flags = IMG_INIT_JPG | IMG_INIT_PNG) + +void load_image_inline (SV *image_) ALIAS: load_image_file = 1 @@ -1673,9 +1718,9 @@ PROTOTYPE: @ CODE: { - glEnable (GL_TEXTURE_2D); glEnable (GL_BLEND); - glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glBlendFunc (intensity ? GL_SRC_ALPHA : GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glEnable (GL_TEXTURE_2D); glBindTexture (GL_TEXTURE_2D, name1); glColor3f (intensity, intensity, intensity); @@ -1700,7 +1745,7 @@ /* rgb == rgb(glcolor) */ glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); - glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_CONSTANT); + glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR); glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); /* alpha = interpolate t0, t1 by env_alpha */ @@ -2097,7 +2142,7 @@ for (x = x0; x < x1; x++) { - int r = 32, g = 32, b = 32, a = 192; + unsigned int r = 32, g = 32, b = 32, a = 192; if (row && row->c0 <= x && x < row->c1) { @@ -2109,10 +2154,10 @@ int a0 = 255 - tex.a; int a1 = tex.a; - r = (r * a0 + tex.r * a1) / 255; - g = (g * a0 + tex.g * a1) / 255; - b = (b * a0 + tex.b * a1) / 255; - a = (a * a0 + tex.a * a1) / 255; + r = div255 (r * a0 + tex.r * a1); + g = div255 (g * a0 + tex.g * a1); + b = div255 (b * a0 + tex.b * a1); + a = div255 (a * a0 + tex.a * a1); } } @@ -2129,7 +2174,7 @@ RETVAL void -draw (DC::Map self, int mx, int my, int sw, int sh, int T, U32 player = 0xffffffff, int sdx = 0, int sdy = 0) +draw (DC::Map self, int mx, int my, int sw, int sh, int Tw, int Th, U32 player = 0xffffffff, int sdx = 0, int sdy = 0) CODE: { int x, y, z; @@ -2143,7 +2188,7 @@ rc_t *rc = rc_alloc (); rc_t *rc_ov = rc_alloc (); rc_key_t key; - rc_array_t *arr, *arr_hidden; + rc_array_t *arr; pl_tex.name = 0; @@ -2191,9 +2236,6 @@ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - key.texname = self->tex [TEXID_HIDDEN].name; - arr_hidden = rc_array (rc_ov, &key); - for (z = 0; z <= 2; z++) { memset (smooth_level, 0, sizeof (smooth_level)); @@ -2226,8 +2268,8 @@ arr = rc_array (rc, &key); } - px = (x + 1) * T - tex.w; - py = (y + 1) * T - tex.h; + px = (x + 1) * Th - tex.w; + py = (y + 1) * Tw - tex.h; if (expect_false (cell->player == player) && expect_false (z == 2)) { @@ -2290,16 +2332,16 @@ rc_key_t key_ov = key; maptex tex = self->tex [TEXID_SPEECH]; rc_array_t *arr; - int px = x * T + T * 2 / 32; - int py = y * T - T * 6 / 32; + int px = x * Tw + Tw * 2 / 32; + int py = y * Th - Th * 6 / 32; key_ov.texname = tex.name; arr = rc_array (rc_ov, &key_ov); - rc_t2f_v3f (arr, 0 , 0 , px , py , 0); - rc_t2f_v3f (arr, 0 , tex.t, px , py + T, 0); - rc_t2f_v3f (arr, tex.s, tex.t, px + T, py + T, 0); - rc_t2f_v3f (arr, tex.s, 0 , px + T, py , 0); + rc_t2f_v3f (arr, 0 , 0 , px , py , 0); + rc_t2f_v3f (arr, 0 , tex.t, px , py + Th, 0); + rc_t2f_v3f (arr, tex.s, tex.t, px + Tw, py + Th, 0); + rc_t2f_v3f (arr, tex.s, 0 , px + Tw, py , 0); } } } @@ -2336,8 +2378,8 @@ && level > smooth_max [skey->x][skey->y]) { maptex tex = self->tex [skey->tile]; - int px = (((int)skey->x) - 1) * T; - int py = (((int)skey->y) - 1) * T; + 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 @@ -2360,20 +2402,20 @@ { float ox = border * dx; - glTexCoord2f (ox , 0.f ); glVertex2i (px , py ); - glTexCoord2f (ox , dy ); glVertex2i (px , py + T); - glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py + T); - glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + T, py ); + glTexCoord2f (ox , 0.f ); glVertex2i (px , py ); + glTexCoord2f (ox , dy ); glVertex2i (px , py + Th); + glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py + Th); + glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + Tw, py ); } if (corner) { float ox = corner * dx; - glTexCoord2f (ox , dy ); glVertex2i (px , py ); - glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + T); - glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + T, py + T); - glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py ); + glTexCoord2f (ox , dy ); glVertex2i (px , py ); + glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + Th); + glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + Tw, py + Th); + glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py ); } } } @@ -2424,8 +2466,8 @@ { mapcell *cell = row->col + (x + mx - row->c0); - int px = x * T; - int py = y * T; + int px = x * Tw; + int py = y * Th; if (expect_false (cell->player == player)) { @@ -2435,8 +2477,8 @@ if (cell->stat_hp) { - int width = cell->stat_width * T; - int thick = (sh * T / 32 + 27) / 28 + 1 + cell->stat_width; + int width = cell->stat_width * Tw; + int thick = (sh * Th / 32 + 27) / 28 + 1 + cell->stat_width; glColor3ub (0, 0, 0); glRectf (px + 1, py - thick - 2, @@ -2799,9 +2841,15 @@ RETVAL = Mix_GroupOldest (-1); if (RETVAL < 0) - XSRETURN_UNDEF; + { + // happens sometimes, maybe it just stopped playing(?) + RETVAL = Mix_GroupAvailable (-1); - Mix_HaltChannel (RETVAL); + if (RETVAL < 0) + XSRETURN_UNDEF; + } + else + Mix_HaltChannel (RETVAL); } Mix_UnregisterAllEffects (RETVAL); @@ -2871,6 +2919,18 @@ PROTOTYPES: DISABLE +void +decoders () + PPCODE: +#if SDL_MIXER_MAJOR_VERSION > 1 || SDL_MIXER_MINOR_VERSION > 2 || SDL_MIXER_PATCHLEVEL >= 10 + int i, num = Mix_GetNumChunkDecoders (); + EXTEND (SP, num); + for (i = 0; i < num; ++i) + PUSHs (sv_2mortal (newSVpv (Mix_GetChunkDecoder (i), 0))); +#else + XPUSHs (sv_2mortal (newSVpv ("(sdl mixer too old)", 0))); +#endif + DC::MixChunk new (SV *class, DC::RW rwops) CODE: @@ -2912,6 +2972,18 @@ MODULE = Deliantra::Client PACKAGE = DC::MixMusic +void +decoders () + PPCODE: +#if SDL_MIXER_MAJOR_VERSION > 1 || SDL_MIXER_MINOR_VERSION > 2 || SDL_MIXER_PATCHLEVEL >= 10 + int i, num = Mix_GetNumMusicDecoders (); + EXTEND (SP, num); + for (i = 0; i < num; ++i) + PUSHs (sv_2mortal (newSVpv (Mix_GetMusicDecoder (i), 0))); +#else + XPUSHs (sv_2mortal (newSVpv ("(sdl mixer too old)", 0))); +#endif + int volume (int volume = -1) PROTOTYPE: ;$ @@ -2932,6 +3004,13 @@ CODE: Mix_HaltMusic (); +int +playing () + CODE: + RETVAL = Mix_PlayingMusic (); + OUTPUT: + RETVAL + DC::MixMusic new (SV *class, DC::RW rwops) CODE: @@ -3135,6 +3214,8 @@ void glFinish () +void glFlush () + void glClear (int mask) void glClearColor (float r, float g, float b, float a = 1.0)