--- deliantra/Deliantra-Client/Client.xs 2006/04/14 23:32:28 1.38 +++ deliantra/Deliantra-Client/Client.xs 2006/04/15 01:13:46 1.40 @@ -68,6 +68,7 @@ GLint name; int w, h; float s, t; + uint8_t r, g, b, a; } mapface; typedef struct { @@ -244,6 +245,8 @@ surface2 = SDL_ConvertSurface (surface, &fmt, SDL_SWSURFACE); + assert (surface2->pitch == surface2->w * 4); + EXTEND (SP, 5); PUSHs (sv_2mortal (newSViv (surface2->w))); PUSHs (sv_2mortal (newSViv (surface2->h))); @@ -259,12 +262,37 @@ } void +average (int x, int y, uint32_t *data) + PPCODE: +{ + uint32_t r = 0, g = 0, b = 0, a = 0; + + x = y = x * y; + + while (x--) + { + uint32_t p = *data++; + + r += (p ) & 255; + g += (p >> 8) & 255; + b += (p >> 16) & 255; + a += (p >> 24) & 255; + } + + EXTEND (SP, 4); + PUSHs (sv_2mortal (newSViv (r / y))); + PUSHs (sv_2mortal (newSViv (g / y))); + PUSHs (sv_2mortal (newSViv (b / y))); + PUSHs (sv_2mortal (newSViv (a / y))); +} + +void fatal (char *message) CODE: #ifdef WIN32 MessageBox (0, message, "Crossfire+ Fatal Error", MB_OK | MB_ICONERROR | MB_SETFOREGROUND); #else - fprintf (stderr, "%s\n", message); + fprintf (stderr, "FATAL: %s\n", message); #endif exit (1); @@ -456,7 +484,7 @@ map_clear (self); void -set_texture (CFClient::Map self, int face, int name, int w, int h, float s, float t) +set_texture (CFClient::Map self, int face, int name, int w, int h, float s, float t, int r, int g, int b, int a) CODE: { while (self->faces < face) @@ -465,11 +493,17 @@ self->faces *= 2; } - self->face [face].name = name; - self->face [face].w = w; - self->face [face].h = h; - self->face [face].s = s; - self->face [face].t = t; + mapface *f = self->face + face; + + f->name = name; + f->w = w; + f->h = h; + f->s = s; + f->t = t; + f->r = r; + f->g = g; + f->b = b; + f->a = a; } void @@ -579,6 +613,66 @@ } } +SV * +mapmap (CFClient::Map self, int w, int h) + CODE: +{ + int x0, x1, x; + int y0, y1, y; + int z; + SV *map_sv = newSV (w * h * sizeof (uint32_t)); + uint32_t *map = (uint32_t *)SvPVX (map_sv); + + SvPOK_only (map_sv); + SvCUR_set (map_sv, w * h * sizeof (uint32_t)); + + x0 = self->x - w / 2; x1 = x0 + w; + y0 = self->y - h / 2; y1 = y0 + h; + + for (y = y0; y < y1; y++) + { + maprow *row = 0 <= y && y < self->rows + ? self->row + y + : 0; + + for (x = x0; x < x1; x++) + { + int r = 32, g = 32, b = 32, a = 192; + + if (row && row->c0 <= x && x < row->c1) + { + mapcell *cell = row->col + (x - row->c0); + + for (z = 0; z <= 0; z++) + { + uint16_t face = cell->face [z]; + + if (face) + { + mapface tex = self->face [face]; + 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; + } + } + } + + *map++ = (r ) + | (g << 8) + | (b << 16) + | (a << 24); + } + } + + RETVAL = map_sv; +} + OUTPUT: + RETVAL + void draw (CFClient::Map self, int shift_x, int shift_y, int x0, int y0, int sw, int sh) PPCODE: