--- deliantra/Deliantra-Client/Client.xs 2009/12/22 00:08:11 1.297 +++ deliantra/Deliantra-Client/Client.xs 2011/12/27 09:17:27 1.311 @@ -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 @@ -100,6 +102,25 @@ #define TEXID_SPEECH 1 #define TEXID_NOFACE 2 +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; static struct @@ -463,6 +484,12 @@ } static unsigned int +div255 (unsigned int n) +{ + return (n + (n >> 8)) >> 8; +} + +static unsigned int minpot (unsigned int n) { if (!n) @@ -555,14 +582,14 @@ deliantra_main () { char *argv[] = { 0 }; - call_argv ("::main", G_DISCARD | G_VOID, argv); + call_argv ("DC::Main::main", G_DISCARD | G_VOID, argv); } #ifdef __MACOSX__ /* to due surprising braindamage on the side of SDL design, we * do some mind-boggling hack here: SDL requires a custom main() * on OS X, so... we provide one and call the original main(), which, - * due to share dlibrary magic, calls -lSDLmain's main, not perl's main, + * due to shared library magic, calls -lSDLmain's main, not perl's main, * and which calls our main (== SDL_main) back. */ extern C_LINKAGE int @@ -796,8 +823,8 @@ # undef const_iv }; - for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) - newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); + for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--) + newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv)); assert (SDLK_MODIFIER_MIN == SDLK_NUMLOCK); assert (SDLK_MODIFIER_MAX == SDLK_COMPOSE); @@ -930,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: @@ -947,8 +977,15 @@ int SDL_GetModState () +int +SDL_WaitEvent () + C_ARGS: 0 + +void +SDL_PumpEvents () + void -poll_events () +peep_events () PPCODE: { SDL_Event ev; @@ -1024,6 +1061,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: @@ -1097,6 +1147,12 @@ RETVAL void +IMG_Init (int flags = IMG_INIT_JPG | IMG_INIT_PNG) + +void +Mix_Init (int flags = MIX_INIT_MOD | MIX_INIT_MP3 | MIX_INIT_OGG) + +void load_image_inline (SV *image_) ALIAS: load_image_file = 1 @@ -1672,9 +1728,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); @@ -1699,7 +1755,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 */ @@ -2096,7 +2152,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) { @@ -2108,10 +2164,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); } } @@ -2128,7 +2184,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; @@ -2222,8 +2278,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)) { @@ -2286,16 +2342,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); } } } @@ -2332,8 +2388,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 @@ -2356,20 +2412,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 ); } } } @@ -2420,8 +2476,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)) { @@ -2431,8 +2487,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, @@ -2522,9 +2578,10 @@ int sh1 = sh + 2; int sh3 = sh * 3; int sw3 = sw * 3; - uint8_t *darkness1 = (uint8_t *)malloc (sw1 * sh1); SV *darkness3_sv = sv_2mortal (newSV (sw3 * sh3)); uint8_t *darkness3 = (uint8_t *)SvPVX (darkness3_sv); + uint8_t *darkness1 = (uint8_t *)malloc (sw1 * sh1); + memset (darkness1, 0, sw1*sh1); SvPOK_only (darkness3_sv); SvCUR_set (darkness3_sv, sw3 * sh3); @@ -2795,9 +2852,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); @@ -2867,6 +2930,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: @@ -2908,6 +2983,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: ;$ @@ -2928,6 +3015,13 @@ CODE: Mix_HaltMusic (); +int +playing () + CODE: + RETVAL = Mix_PlayingMusic (); + OUTPUT: + RETVAL + DC::MixMusic new (SV *class, DC::RW rwops) CODE: @@ -3076,8 +3170,8 @@ # undef const_iv }; - for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) - newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); + for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--) + newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv)); texture_av = newAV (); AvREAL_off (texture_av); @@ -3131,6 +3225,8 @@ void glFinish () +void glFlush () + void glClear (int mask) void glClearColor (float r, float g, float b, float a = 1.0)