--- deliantra/Deliantra-Client/Client.xs 2010/05/02 21:22:20 1.305 +++ deliantra/Deliantra-Client/Client.xs 2012/11/23 12:39:05 1.317 @@ -102,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 @@ -465,6 +484,12 @@ } static unsigned int +div255 (unsigned int n) +{ + return (n + (n >> 8)) >> 8; +} + +static unsigned int minpot (unsigned int n) { if (!n) @@ -554,23 +579,27 @@ } static void -deliantra_main () +deliantra_main (SV *real_main) { - char *argv[] = { 0 }; - call_argv ("::main", G_DISCARD | G_VOID, argv); + dSP; + + PUSHMARK (SP); + call_sv (real_main, G_DISCARD | G_VOID); } #ifdef __MACOSX__ + static SV *real_main; + /* 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 main (int argc, char *argv[]) { - deliantra_main (); + deliantra_main (real_main); } #undef main @@ -578,16 +607,18 @@ extern C_LINKAGE int main (int argc, char *argv[]); static void - SDL_braino (void) + SDL_main_hack (SV *real_main_) { + real_main = real_main_; + char *argv[] = { "deliantra client", 0 }; (main) (1, argv); } #else static void - SDL_braino (void) + SDL_main_hack (SV *real_main) { - deliantra_main (); + deliantra_main (real_main); } #endif @@ -798,8 +829,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); @@ -848,7 +879,8 @@ char *SDL_GetError () -void SDL_braino () +void SDL_main_hack (SV *real_main) + PROTOTYPE: & int SDL_Init (U32 flags) @@ -927,12 +959,9 @@ if (RETVAL) { av_clear (texture_av); - - SDL_WM_SetCaption ("Deliantra MORPG Client " VERSION, "Deliantra"); #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; } @@ -941,6 +970,9 @@ RETVAL void +SDL_WM_SetCaption (const char *title, const char *icon) + +void SDL_GL_SwapBuffers () char * @@ -952,8 +984,15 @@ int SDL_GetModState () +int +SDL_WaitEvent () + C_ARGS: 0 + +void +SDL_PumpEvents () + void -poll_events () +peep_events () PPCODE: { SDL_Event ev; @@ -1117,6 +1156,10 @@ void IMG_Init (int flags = IMG_INIT_JPG | IMG_INIT_PNG) +# MIX_INIT_MP3 gives smpeg + libstdc++ + libgcc_s +void +Mix_Init (int flags = MIX_INIT_MOD | MIX_INIT_OGG) + void load_image_inline (SV *image_) ALIAS: @@ -1451,7 +1494,7 @@ set_height (DC::Layout self, int base_height) CODE: if (self->base_height != base_height) - { + { self->base_height = base_height; layout_update_font (self); } @@ -1991,7 +2034,7 @@ } SV * -map1a_update (DC::Map self, SV *data_, int extmap) +map1a_update (DC::Map self, SV *data_) CODE: { uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_); @@ -2022,44 +2065,39 @@ if (flags & 8) { - if (extmap) + uint8_t ext, cmd; + + do { - uint8_t ext, cmd; + ext = *data++; + cmd = ext & 0x7f; - do + if (cmd < 4) + cell->darkness = 255 - ext * 64 + 1; /* make sure this doesn't collide with FOW_DARKNESS */ + else if (cmd == 5) // health { - ext = *data++; - cmd = ext & 0x7f; - - if (cmd < 4) - cell->darkness = 255 - ext * 64 + 1; /* make sure this doesn't collide with FOW_DARKNESS */ - else if (cmd == 5) // health - { - cell->stat_width = 1; - cell->stat_hp = *data++; - } - else if (cmd == 6) // monster width - cell->stat_width = *data++ + 1; - else if (cmd == 0x47) - { - if (*data == 1) cell->player = data [1]; - else if (*data == 2) cell->player = data [2] + (data [1] << 8); - else if (*data == 3) cell->player = data [3] + (data [2] << 8) + (data [1] << 16); - else if (*data == 4) cell->player = data [4] + (data [3] << 8) + (data [2] << 16) + (data [1] << 24); + cell->stat_width = 1; + cell->stat_hp = *data++; + } + else if (cmd == 6) // monster width + cell->stat_width = *data++ + 1; + else if (cmd == 0x47) + { + if (*data == 1) cell->player = data [1]; + else if (*data == 2) cell->player = data [2] + (data [1] << 8); + else if (*data == 3) cell->player = data [3] + (data [2] << 8) + (data [1] << 16); + else if (*data == 4) cell->player = data [4] + (data [3] << 8) + (data [2] << 16) + (data [1] << 24); - data += *data + 1; - } - else if (cmd == 8) // cell flags - cell->flags = *data++; - else if (ext & 0x40) // unknown, multibyte => skip - data += *data + 1; - else - data++; + data += *data + 1; } - while (ext & 0x80); + else if (cmd == 8) // cell flags + cell->flags = *data++; + else if (ext & 0x40) // unknown, multibyte => skip + data += *data + 1; + else + data++; } - else - cell->darkness = *data++ + 1; + while (ext & 0x80); } for (z = 0; z <= 2; ++z) @@ -2117,7 +2155,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) { @@ -2129,10 +2167,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); } } @@ -2149,7 +2187,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; @@ -2243,8 +2281,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)) { @@ -2307,16 +2345,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); } } } @@ -2353,8 +2391,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 @@ -2377,20 +2415,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 ); } } } @@ -2441,8 +2479,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)) { @@ -2452,8 +2490,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, @@ -2543,9 +2581,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); @@ -3134,8 +3173,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);