--- deliantra/Deliantra-Client/Client.xs 2006/07/13 01:54:18 1.131 +++ deliantra/Deliantra-Client/Client.xs 2006/08/18 02:25:12 1.144 @@ -85,10 +85,10 @@ #include "pango-fontmap.c" #include "pango-render.c" -typedef Mix_Chunk *CFClient__MixChunk; -typedef Mix_Music *CFClient__MixMusic; +typedef Mix_Chunk *CFPlus__MixChunk; +typedef Mix_Music *CFPlus__MixMusic; -typedef PangoFontDescription *CFClient__Font; +typedef PangoFontDescription *CFPlus__Font; static int shape_attr_p (PangoLayoutRun *run) @@ -112,10 +112,10 @@ PangoLayout *pl; float r, g, b, a; // default color for rgba mode int base_height; - CFClient__Font font; -} *CFClient__Layout; + CFPlus__Font font; +} *CFPlus__Layout; -static CFClient__Font default_font; +static CFPlus__Font default_font; static PangoContext *opengl_context; static PangoFontMap *opengl_fontmap; @@ -130,7 +130,7 @@ } static void -layout_update_font (CFClient__Layout self) +layout_update_font (CFPlus__Layout self) { /* use a random scale factor to account for unknown descenders, 0.8 works * reasonably well with bitstream vera @@ -144,14 +144,21 @@ } static void -layout_get_pixel_size (CFClient__Layout self, int *w, int *h) +layout_get_pixel_size (CFPlus__Layout self, int *w, int *h) { - pango_layout_get_pixel_size (self->pl, w, h); + PangoRectangle rect; - if (!*w) *w = 1; - if (!*h) *h = 1; + // get_pixel_* wrongly rounds down + pango_layout_get_extents (self->pl, 0, &rect); - *w = (*w + 3) & ~3; + rect.width = (rect.width + PANGO_SCALE - 1) / PANGO_SCALE; + rect.height = (rect.height + PANGO_SCALE - 1) / PANGO_SCALE; + + if (!rect.width) rect.width = 1; + if (!rect.height) rect.height = 1; + + *w = rect.width; + *h = rect.height; } typedef uint16_t mapface; @@ -164,8 +171,9 @@ } maptex; typedef struct { - int16_t darkness; + uint16_t darkness; mapface face[3]; + uint8_t stat_hp; } mapcell; typedef struct { @@ -184,7 +192,7 @@ int32_t rows; maprow *row; -} *CFClient__Map; +} *CFPlus__Map; static char * prepend (char *ptr, int sze, int inc) @@ -212,7 +220,7 @@ #define Prepend(type,ptr,sze,inc) (ptr) = (type *)prepend ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type)) static maprow * -map_get_row (CFClient__Map self, int y) +map_get_row (CFPlus__Map self, int y) { if (0 > y) { @@ -260,13 +268,13 @@ } static mapcell * -map_get_cell (CFClient__Map self, int x, int y) +map_get_cell (CFPlus__Map self, int x, int y) { return row_get_cell (map_get_row (self, y), x); } static void -map_clear (CFClient__Map self) +map_clear (CFPlus__Map self) { int r; @@ -284,7 +292,7 @@ } static void -map_blank (CFClient__Map self, int x0, int y0, int w, int h) +map_blank (CFPlus__Map self, int x0, int y0, int w, int h) { int x, y; maprow *row; @@ -303,7 +311,7 @@ if (x >= row->c1) break; - row->col[x - row->c0].darkness = -1; + row->col[x - row->c0].darkness = 0; } } } @@ -351,13 +359,13 @@ return n + 1; } -MODULE = CFClient PACKAGE = CFClient +MODULE = CFPlus PACKAGE = CFPlus PROTOTYPES: ENABLE BOOT: { - HV *stash = gv_stashpv ("CFClient", 1); + HV *stash = gv_stashpv ("CFPlus", 1); static const struct { const char *name; IV iv; @@ -514,8 +522,10 @@ SDL_GL_SetAttribute (SDL_GL_ACCUM_ALPHA_SIZE, 0); SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); +#if SDL_VERSION_ATLEAST(1,2,10) SDL_GL_SetAttribute (SDL_GL_ACCELERATED_VISUAL, 1); SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 1); +#endif SDL_EnableUNICODE (1); SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); @@ -612,7 +622,7 @@ break; } - XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv))); + XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("CFPlus::UI::Event", 1)))); } } @@ -751,9 +761,9 @@ CODE: _exit (retval); -MODULE = CFClient PACKAGE = CFClient::Font +MODULE = CFPlus PACKAGE = CFPlus::Font -CFClient::Font +CFPlus::Font new_from_file (SV *class, char *path, int id = 0) CODE: { @@ -766,23 +776,23 @@ RETVAL void -DESTROY (CFClient::Font self) +DESTROY (CFPlus::Font self) CODE: pango_font_description_free (self); void -make_default (CFClient::Font self) +make_default (CFPlus::Font self) CODE: default_font = self; -MODULE = CFClient PACKAGE = CFClient::Layout +MODULE = CFPlus PACKAGE = CFPlus::Layout void reset_glyph_cache () CODE: tc_clear (); -CFClient::Layout +CFPlus::Layout new (SV *class) CODE: New (0, RETVAL, 1, struct cf_layout); @@ -801,13 +811,13 @@ RETVAL void -DESTROY (CFClient::Layout self) +DESTROY (CFPlus::Layout self) CODE: g_object_unref (self->pl); Safefree (self); void -set_text (CFClient::Layout self, SV *text_) +set_text (CFPlus::Layout self, SV *text_) CODE: { STRLEN textlen; @@ -817,7 +827,7 @@ } void -set_markup (CFClient::Layout self, SV *text_) +set_markup (CFPlus::Layout self, SV *text_) CODE: { STRLEN textlen; @@ -827,7 +837,7 @@ } void -set_shapes (CFClient::Layout self, ...) +set_shapes (CFPlus::Layout self, ...) CODE: { PangoAttrList *attrs = 0; @@ -872,7 +882,7 @@ } void -get_shapes (CFClient::Layout self) +get_shapes (CFPlus::Layout self) PPCODE: { PangoLayoutIter *iter = pango_layout_get_iter (self->pl); @@ -897,7 +907,7 @@ } int -has_wrapped (CFClient::Layout self) +has_wrapped (CFPlus::Layout self) CODE: { int lines = 1; @@ -912,7 +922,7 @@ RETVAL SV * -get_text (CFClient::Layout self) +get_text (CFPlus::Layout self) CODE: RETVAL = newSVpv (pango_layout_get_text (self->pl), 0); sv_utf8_decode (RETVAL); @@ -920,7 +930,7 @@ RETVAL void -set_foreground (CFClient::Layout self, float r, float g, float b, float a = 1.) +set_foreground (CFPlus::Layout self, float r, float g, float b, float a = 1.) CODE: self->r = r; self->g = g; @@ -928,7 +938,7 @@ self->a = a; void -set_font (CFClient::Layout self, CFClient::Font font = 0) +set_font (CFPlus::Layout self, CFPlus::Font font = 0) CODE: if (self->font != font) { @@ -937,7 +947,7 @@ } void -set_height (CFClient::Layout self, int base_height) +set_height (CFPlus::Layout self, int base_height) CODE: if (self->base_height != base_height) { @@ -946,22 +956,22 @@ } void -set_width (CFClient::Layout self, int max_width = -1) +set_width (CFPlus::Layout self, int max_width = -1) CODE: pango_layout_set_width (self->pl, max_width < 0 ? max_width : max_width * PANGO_SCALE); void -set_indent (CFClient::Layout self, int indent) +set_indent (CFPlus::Layout self, int indent) CODE: pango_layout_set_indent (self->pl, indent * PANGO_SCALE); void -set_spacing (CFClient::Layout self, int spacing) +set_spacing (CFPlus::Layout self, int spacing) CODE: pango_layout_set_spacing (self->pl, spacing * PANGO_SCALE); void -set_ellipsise (CFClient::Layout self, int ellipsise) +set_ellipsise (CFPlus::Layout self, int ellipsise) CODE: pango_layout_set_ellipsize (self->pl, ellipsise == 1 ? PANGO_ELLIPSIZE_START @@ -971,12 +981,12 @@ ); void -set_single_paragraph_mode (CFClient::Layout self, int spm) +set_single_paragraph_mode (CFPlus::Layout self, int spm) CODE: pango_layout_set_single_paragraph_mode (self->pl, !!spm); void -size (CFClient::Layout self) +size (CFPlus::Layout self) PPCODE: { int w, h; @@ -989,7 +999,7 @@ } int -descent (CFClient::Layout self) +descent (CFPlus::Layout self) CODE: { PangoRectangle rect; @@ -1001,7 +1011,7 @@ RETVAL int -xy_to_index (CFClient::Layout self, int x, int y) +xy_to_index (CFPlus::Layout self, int x, int y) CODE: { int index, trailing; @@ -1012,7 +1022,7 @@ RETVAL void -cursor_pos (CFClient::Layout self, int index) +cursor_pos (CFPlus::Layout self, int index) PPCODE: { PangoRectangle strong_pos; @@ -1025,15 +1035,16 @@ } void -render (CFClient::Layout self, float x, float y) +render (CFPlus::Layout self, float x, float y, int flags = 0) PPCODE: pango_opengl_render_layout_subpixel ( self->pl, x * PANGO_SCALE, y * PANGO_SCALE, - self->r, self->g, self->b, self->a + self->r, self->g, self->b, self->a, + flags ); -MODULE = CFClient PACKAGE = CFClient::Texture +MODULE = CFPlus PACKAGE = CFPlus::Texture void pad2pot (SV *data_, SV *w_, SV *h_) @@ -1121,9 +1132,9 @@ } } -MODULE = CFClient PACKAGE = CFClient::Map +MODULE = CFPlus PACKAGE = CFPlus::Map -CFClient::Map +CFPlus::Map new (SV *class, int map_width, int map_height) CODE: New (0, RETVAL, 1, struct map); @@ -1143,7 +1154,7 @@ RETVAL void -DESTROY (CFClient::Map self) +DESTROY (CFPlus::Map self) CODE: { map_clear (self); @@ -1153,12 +1164,12 @@ } void -clear (CFClient::Map self) +clear (CFPlus::Map self) CODE: map_clear (self); void -set_face (CFClient::Map self, int face, int texid) +set_face (CFPlus::Map self, int face, int texid) CODE: { while (self->faces <= face) @@ -1171,7 +1182,7 @@ } void -set_texture (CFClient::Map self, int texid, int name, int w, int h, float s, float t, int r, int g, int b, int a) +set_texture (CFPlus::Map self, int texid, int name, int w, int h, float s, float t, int r, int g, int b, int a) CODE: { while (self->texs <= texid) @@ -1205,7 +1216,7 @@ } int -ox (CFClient::Map self) +ox (CFPlus::Map self) ALIAS: oy = 1 x = 2 @@ -1226,7 +1237,7 @@ RETVAL void -scroll (CFClient::Map self, int dx, int dy) +scroll (CFPlus::Map self, int dx, int dy) CODE: { if (dx > 0) @@ -1252,7 +1263,7 @@ } void -map1a_update (CFClient::Map self, SV *data_) +map1a_update (CFPlus::Map self, SV *data_, int extmap) CODE: { uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_); @@ -1271,18 +1282,41 @@ if (flags & 15) { - if (cell->darkness < 0) + if (!cell->darkness) { - cell->darkness = 0; + cell->darkness = 256; cell->face [0] = 0; cell->face [1] = 0; cell->face [2] = 0; + cell->stat_hp = 0; } - cell->darkness = flags & 8 ? *data++ : 255; - //TODO: don't trust server data to be in-range(!) + if (flags & 8) + { + if (extmap) + { + uint8_t ext, cmd; + + do + { + ext = *data++; + cmd = ext & 0x3f; + + if (ext < 4) + cell->darkness = 255 - ext * 64 + 1; + else if (ext == 5) // health + cell->stat_hp = *data++; + else if (ext & 0x40) // unknown, multibyte => skip + data += *data + 1; + } + while (cmd & 0x80); + } + else + cell->darkness = *data++ + 1; + } + if (flags & 4) { cell->face [0] = self->face [(data [0] << 8) + data [1]]; data += 2; @@ -1299,12 +1333,12 @@ } } else - cell->darkness = -1; + cell->darkness = 0; } } SV * -mapmap (CFClient::Map self, int x0, int y0, int w, int h) +mapmap (CFPlus::Map self, int x0, int y0, int w, int h) CODE: { int x1, x; @@ -1364,7 +1398,7 @@ RETVAL void -draw (CFClient::Map self, int shift_x, int shift_y, int x0, int y0, int sw, int sh) +draw (CFPlus::Map self, int shift_x, int shift_y, int x0, int y0, int sw, int sh) CODE: { int vx, vy; @@ -1436,10 +1470,37 @@ glDisable (GL_TEXTURE_2D); glDisable (GL_BLEND); + + for (y = 0; y < sh; y++) + if (0 <= y + vy && y + vy < self->rows) + { + maprow *row = self->row + (y + vy); + + for (x = 0; x < sw; x++) + if (row->c0 <= x + vx && x + vx < row->c1) + { + mapcell *cell = row->col + (x + vx - row->c0); + + int px = x * 32; + int py = y * 32; + + if (cell->stat_hp) + { + glColor3ub (0, 0, 0); + glRectf (px + 1, py + 1, px + 31, py + 4); + + glColor3ub (0, 255, 0); + glBegin (GL_LINES); + glVertex2f (px + 2, py + 2.5f); + glVertex2f (px + 29.f - cell->stat_hp * (28.f / 255.f), py + 2.5f); + glEnd (); + } + } + } } void -draw_magicmap (CFClient::Map self, int dx, int dy, int w, int h, unsigned char *data) +draw_magicmap (CFPlus::Map self, int dx, int dy, int w, int h, unsigned char *data) CODE: { static float color[16][3] = { @@ -1499,7 +1560,7 @@ } void -fow_texture (CFClient::Map self, int shift_x, int shift_y, int x0, int y0, int sw, int sh) +fow_texture (CFPlus::Map self, int shift_x, int shift_y, int x0, int y0, int sw, int sh) PPCODE: { int vx, vy; @@ -1525,9 +1586,9 @@ { mapcell *cell = row->col + (x + vx - row->c0); - darkness[y * sw4 + x] = cell->darkness < 0 - ? 255 - FOW_DARKNESS - : 255 - cell->darkness; + darkness[y * sw4 + x] = cell->darkness + ? 255 - (cell->darkness - 1) + : 255 - FOW_DARKNESS; } } @@ -1538,7 +1599,7 @@ } SV * -get_rect (CFClient::Map self, int x0, int y0, int w, int h) +get_rect (CFPlus::Map self, int x0, int y0, int w, int h) CODE: { int x, y, x1, y1; @@ -1610,7 +1671,7 @@ RETVAL void -set_rect (CFClient::Map self, int x0, int y0, uint8_t *data) +set_rect (CFPlus::Map self, int x0, int y0, uint8_t *data) PPCODE: { int x, y, z; @@ -1652,9 +1713,9 @@ if (flags & 2) { face[1] = *data++ << 8; face[1] |= *data++; } if (flags & 4) { face[2] = *data++ << 8; face[2] |= *data++; } - if (cell->darkness <= 0) + if (cell->darkness == 0) { - cell->darkness = -1; + cell->darkness = 0; for (z = 0; z <= 2; z++) { @@ -1669,9 +1730,9 @@ } } -MODULE = CFClient PACKAGE = CFClient::MixChunk +MODULE = CFPlus PACKAGE = CFPlus::MixChunk -CFClient::MixChunk +CFPlus::MixChunk new_from_file (SV *class, char *path) CODE: RETVAL = Mix_LoadWAV (path); @@ -1679,25 +1740,25 @@ RETVAL void -DESTROY (CFClient::MixChunk self) +DESTROY (CFPlus::MixChunk self) CODE: Mix_FreeChunk (self); int -volume (CFClient::MixChunk self, int volume = -1) +volume (CFPlus::MixChunk self, int volume = -1) CODE: RETVAL = Mix_VolumeChunk (self, volume); OUTPUT: RETVAL int -play (CFClient::MixChunk self, int channel = -1, int loops = 0, int ticks = -1) +play (CFPlus::MixChunk self, int channel = -1, int loops = 0, int ticks = -1) CODE: RETVAL = Mix_PlayChannelTimed (channel, self, loops, ticks); OUTPUT: RETVAL -MODULE = CFClient PACKAGE = CFClient::MixMusic +MODULE = CFPlus PACKAGE = CFPlus::MixMusic int volume (int volume = -1) @@ -1706,7 +1767,7 @@ OUTPUT: RETVAL -CFClient::MixMusic +CFPlus::MixMusic new_from_file (SV *class, char *path) CODE: RETVAL = Mix_LoadMUS (path); @@ -1714,22 +1775,22 @@ RETVAL void -DESTROY (CFClient::MixMusic self) +DESTROY (CFPlus::MixMusic self) CODE: Mix_FreeMusic (self); int -play (CFClient::MixMusic self, int loops = -1) +play (CFPlus::MixMusic self, int loops = -1) CODE: RETVAL = Mix_PlayMusic (self, loops); OUTPUT: RETVAL -MODULE = CFClient PACKAGE = CFClient::OpenGL +MODULE = CFPlus PACKAGE = CFPlus::OpenGL BOOT: { - HV *stash = gv_stashpv ("CFClient::OpenGL", 1); + HV *stash = gv_stashpv ("CFPlus::OpenGL", 1); static const struct { const char *name; IV iv; @@ -1802,6 +1863,7 @@ const_iv (GL_CONVOLUTION_BORDER_MODE), const_iv (GL_CONSTANT_BORDER), const_iv (GL_LINES), + const_iv (GL_LINE_STRIP), const_iv (GL_LINE_LOOP), const_iv (GL_QUADS), const_iv (GL_QUAD_STRIP), @@ -2008,4 +2070,3 @@ void glCallList (int list) -