ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/Client.xs
(Generate patch)

Comparing deliantra/Deliantra-Client/Client.xs (file contents):
Revision 1.277 by root, Mon Sep 1 06:18:09 2008 UTC vs.
Revision 1.292 by root, Fri Dec 4 15:04:56 2009 UTC

81#define expect_false(expr) expect ((expr) != 0, 0) 81#define expect_false(expr) expect ((expr) != 0, 0)
82#define expect_true(expr) expect ((expr) != 0, 1) 82#define expect_true(expr) expect ((expr) != 0, 1)
83 83
84#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, object replacement character */ 84#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, object replacement character */
85 85
86#define FOW_DARKNESS 32 86#define FOW_DARKNESS 64
87 87
88#define MAP_EXTEND_X 32 88#define MAP_EXTEND_X 32
89#define MAP_EXTEND_Y 512 89#define MAP_EXTEND_Y 512
90 90
91#define MIN_FONT_HEIGHT 10 91#define MIN_FONT_HEIGHT 10
92 92
93/* mask out modifiers we are not interested in */ 93/* mask out modifiers we are not interested in */
94#define MOD_MASK (KMOD_CTRL | KMOD_SHIFT | KMOD_ALT | KMOD_META) 94#define MOD_MASK (KMOD_CTRL | KMOD_SHIFT | KMOD_ALT | KMOD_META)
95 95
96#define KMOD_LRAM 0x10000 // our extension 96#define KMOD_LRAM 0x10000 // our extension
97
98#define TEXID_SPEECH 1
99#define TEXID_NOFACE 2
100#define TEXID_HIDDEN 3
97 101
98static AV *texture_av; 102static AV *texture_av;
99 103
100static struct 104static struct
101{ 105{
233 int w, h; 237 int w, h;
234 float s, t; 238 float s, t;
235 uint8_t r, g, b, a; 239 uint8_t r, g, b, a;
236 tileid smoothtile; 240 tileid smoothtile;
237 uint8_t smoothlevel; 241 uint8_t smoothlevel;
242 uint8_t unused; /* set to zero on use */
238} maptex; 243} maptex;
239 244
240typedef struct { 245typedef struct {
241 uint32_t player; 246 uint32_t player;
242 tileid tile[3]; 247 tileid tile[3];
1206#if DEBUG 1211#if DEBUG
1207 VALGRIND_DO_LEAK_CHECK; 1212 VALGRIND_DO_LEAK_CHECK;
1208#endif 1213#endif
1209} 1214}
1210 1215
1216int
1217SvREFCNT (SV *sv)
1218 CODE:
1219 RETVAL = SvREFCNT (sv);
1220 OUTPUT:
1221 RETVAL
1222
1211MODULE = Deliantra::Client PACKAGE = DC::Font 1223MODULE = Deliantra::Client PACKAGE = DC::Font
1212 1224
1213PROTOTYPES: DISABLE 1225PROTOTYPES: DISABLE
1214 1226
1215DC::Font 1227DC::Font
1759 //glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 1771 //glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1760 // use uglier nearest interpolation because linear suffers 1772 // use uglier nearest interpolation because linear suffers
1761 // from transparent color bleeding and ugly wrapping effects. 1773 // from transparent color bleeding and ugly wrapping effects.
1762 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1774 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1763} 1775}
1776
1777void
1778expire_textures (DC::Map self, int texid, int count)
1779 PPCODE:
1780 for (; texid < self->texs && count; ++texid, --count)
1781 {
1782 maptex *tex = self->tex + texid;
1783
1784 if (tex->name)
1785 {
1786 if (tex->unused)
1787 {
1788 tex->name = 0;
1789 tex->unused = 0;
1790 XPUSHs (sv_2mortal (newSViv (texid)));
1791 }
1792 else
1793 tex->unused = 1;
1794 }
1795 }
1764 1796
1765int 1797int
1766ox (DC::Map self) 1798ox (DC::Map self)
1767 ALIAS: 1799 ALIAS:
1768 oy = 1 1800 oy = 1
1889 cell->tile [z] = self->face2tile [face]; 1921 cell->tile [z] = self->face2tile [face];
1890 1922
1891 if (cell->tile [z]) 1923 if (cell->tile [z])
1892 { 1924 {
1893 maptex *tex = self->tex + cell->tile [z]; 1925 maptex *tex = self->tex + cell->tile [z];
1926 tex->unused = 0;
1894 if (!tex->name) 1927 if (!tex->name)
1895 av_push (missing, newSViv (cell->tile [z])); 1928 av_push (missing, newSViv (cell->tile [z]));
1896 1929
1897 if (tex->smoothtile) 1930 if (tex->smoothtile)
1898 { 1931 {
1899 maptex *smooth = self->tex + tex->smoothtile; 1932 maptex *smooth = self->tex + tex->smoothtile;
1933 smooth->unused = 0;
1900 if (!smooth->name) 1934 if (!smooth->name)
1901 av_push (missing, newSViv (tex->smoothtile)); 1935 av_push (missing, newSViv (tex->smoothtile));
1902 } 1936 }
1903 } 1937 }
1904 } 1938 }
1975 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level 2009 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level
1976 static uint8_t smooth_max[256][256]; // egad, fast and wasteful on memory (64k) 2010 static uint8_t smooth_max[256][256]; // egad, fast and wasteful on memory (64k)
1977 smooth_key skey; 2011 smooth_key skey;
1978 int pl_x, pl_y; 2012 int pl_x, pl_y;
1979 maptex pl_tex; 2013 maptex pl_tex;
1980 rc_t *rc = rc_alloc (); 2014 rc_t *rc = rc_alloc ();
2015 rc_t *rc_ov = rc_alloc ();
1981 rc_key_t key; 2016 rc_key_t key;
1982 rc_array_t *arr; 2017 rc_array_t *arr, *arr_hidden;
1983 2018
1984 pl_tex.name = 0; 2019 pl_tex.name = 0;
1985 2020
1986 // thats current max. sorry. 2021 // that's current max. sorry.
1987 if (sw > 255) sw = 255; 2022 if (sw > 255) sw = 255;
1988 if (sh > 255) sh = 255; 2023 if (sh > 255) sh = 255;
1989 2024
1990 // clear key, in case of extra padding 2025 // clear key, in case of extra padding
1991 memset (&skey, 0, sizeof (skey)); 2026 memset (&skey, 0, sizeof (skey));
1995 key.g = 255; 2030 key.g = 255;
1996 key.b = 255; 2031 key.b = 255;
1997 key.a = 255; 2032 key.a = 255;
1998 key.mode = GL_QUADS; 2033 key.mode = GL_QUADS;
1999 key.format = GL_T2F_V3F; 2034 key.format = GL_T2F_V3F;
2000 key.texname = -1;
2001 2035
2002 mx += self->x; 2036 mx += self->x;
2003 my += self->y; 2037 my += self->y;
2004 2038
2005 // first pass: determine smooth_max 2039 // first pass: determine smooth_max
2026 2060
2027 glEnable (GL_BLEND); 2061 glEnable (GL_BLEND);
2028 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2062 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2029 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 2063 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
2030 2064
2065 key.texname = self->tex [TEXID_HIDDEN].name;
2066 arr_hidden = rc_array (rc_ov, &key);
2067
2031 for (z = 0; z <= 2; z++) 2068 for (z = 0; z <= 2; z++)
2032 { 2069 {
2033 memset (smooth_level, 0, sizeof (smooth_level)); 2070 memset (smooth_level, 0, sizeof (smooth_level));
2071 key.texname = -1;
2034 2072
2035 for (y = 0; y < sh; y++) 2073 for (y = 0; y < sh; y++)
2036 if (0 <= y + my && y + my < self->rows) 2074 if (0 <= y + my && y + my < self->rows)
2037 { 2075 {
2038 maprow *row = self->row + (y + my); 2076 maprow *row = self->row + (y + my);
2044 tileid tile = cell->tile [z]; 2082 tileid tile = cell->tile [z];
2045 2083
2046 if (tile) 2084 if (tile)
2047 { 2085 {
2048 maptex tex = self->tex [tile]; 2086 maptex tex = self->tex [tile];
2049 int px = (x + 1) * T - tex.w; 2087 int px, py;
2050 int py = (y + 1) * T - tex.h;
2051 2088
2052 if (key.texname != tex.name) 2089 if (key.texname != tex.name)
2053 { 2090 {
2091 self->tex [tile].unused = 0;
2092
2054 if (!tex.name) 2093 if (!tex.name)
2055 tex = self->tex [2]; /* missing, replace by noface */ 2094 tex = self->tex [TEXID_NOFACE]; /* missing, replace by noface */
2056 2095
2057 key.texname = tex.name; 2096 key.texname = tex.name;
2058 arr = rc_array (rc, &key); 2097 arr = rc_array (rc, &key);
2059 } 2098 }
2099
2100 px = (x + 1) * T - tex.w;
2101 py = (y + 1) * T - tex.h;
2060 2102
2061 if (expect_false (cell->player == player) && expect_false (z == 2)) 2103 if (expect_false (cell->player == player) && expect_false (z == 2))
2062 { 2104 {
2063 pl_x = px; 2105 pl_x = px;
2064 pl_y = py; 2106 pl_y = py;
2069 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2111 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
2070 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0); 2112 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0);
2071 rc_t2f_v3f (arr, tex.s, tex.t, px + tex.w, py + tex.h, 0); 2113 rc_t2f_v3f (arr, tex.s, tex.t, px + tex.w, py + tex.h, 0);
2072 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0); 2114 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0);
2073 2115
2074 if (expect_false (cell->flags) && expect_false (z == 2))
2075 {
2076 // overlays such as the speech bubble, probably more to come
2077 if (cell->flags & 1)
2078 {
2079 maptex tex = self->tex [1];
2080 int px = x * T + T * 2 / 32;
2081 int py = y * T - T * 6 / 32;
2082
2083 if (tex.name)
2084 {
2085 if (key.texname != tex.name)
2086 {
2087 key.texname = tex.name;
2088 arr = rc_array (rc, &key);
2089 }
2090
2091 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
2092 rc_t2f_v3f (arr, 0 , tex.t, px , py + T, 0);
2093 rc_t2f_v3f (arr, tex.s, tex.t, px + T, py + T, 0);
2094 rc_t2f_v3f (arr, tex.s, 0 , px + T, py , 0);
2095 }
2096 }
2097 }
2098
2099 // update smooth hash 2116 // update smooth hash
2100 if (tex.smoothtile) 2117 if (tex.smoothtile)
2101 { 2118 {
2102 skey.tile = tex.smoothtile; 2119 skey.tile = tex.smoothtile;
2103 skey.level = tex.smoothlevel; 2120 skey.level = tex.smoothlevel;
2131 // corners 2148 // corners
2132 skey.x = x + 2; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0100); 2149 skey.x = x + 2; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0100);
2133 skey.x = x ; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0200); 2150 skey.x = x ; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0200);
2134 skey.x = x ; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0400); 2151 skey.x = x ; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0400);
2135 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0800); 2152 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0800);
2153 }
2154 }
2155
2156 if (expect_false (z == 2))
2157 {
2158 /* draw question marks on top of hidden spaces */
2159 if (!cell->darkness)
2160 {
2161 maptex tex = self->tex [TEXID_HIDDEN];
2162 int px = (x + 1) * T - tex.w;
2163 int py = (y + 1) * T - tex.h;
2164
2165 rc_t2f_v3f (arr_hidden, 0 , 0 , px , py , 0);
2166 rc_t2f_v3f (arr_hidden, 0 , tex.t, px , py + tex.h, 0);
2167 rc_t2f_v3f (arr_hidden, tex.s, tex.t, px + tex.w, py + tex.h, 0);
2168 rc_t2f_v3f (arr_hidden, tex.s, 0 , px + tex.w, py , 0);
2169 }
2170
2171 if (expect_false (cell->flags))
2172 {
2173 // overlays such as the speech bubble, probably more to come
2174 if (cell->flags & 1)
2175 {
2176 rc_key_t key_ov = key;
2177 maptex tex = self->tex [TEXID_SPEECH];
2178 rc_array_t *arr;
2179 int px = x * T + T * 2 / 32;
2180 int py = y * T - T * 6 / 32;
2181
2182 key_ov.texname = tex.name;
2183 arr = rc_array (rc_ov, &key_ov);
2184
2185 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
2186 rc_t2f_v3f (arr, 0 , tex.t, px , py + T, 0);
2187 rc_t2f_v3f (arr, tex.s, tex.t, px + T, py + T, 0);
2188 rc_t2f_v3f (arr, tex.s, 0 , px + T, py , 0);
2189 }
2136 } 2190 }
2137 } 2191 }
2138 } 2192 }
2139 } 2193 }
2140 2194
2180 { 2234 {
2181 // this time avoiding texture state changes 2235 // this time avoiding texture state changes
2182 // save gobs of state changes. 2236 // save gobs of state changes.
2183 if (key.texname != tex.name) 2237 if (key.texname != tex.name)
2184 { 2238 {
2239 self->tex [skey->tile].unused = 0;
2240
2185 glEnd (); 2241 glEnd ();
2186 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name); 2242 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name);
2187 glBegin (GL_QUADS); 2243 glBegin (GL_QUADS);
2188 } 2244 }
2189 2245
2235 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0); 2291 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0);
2236 2292
2237 rc_draw (rc); 2293 rc_draw (rc);
2238 } 2294 }
2239 2295
2296 rc_draw (rc_ov);
2297 rc_clear (rc_ov);
2298
2240 glDisable (GL_BLEND); 2299 glDisable (GL_BLEND);
2241 rc_free (rc); 2300 rc_free (rc);
2301 rc_free (rc_ov);
2242 2302
2243 // top layer: overlays such as the health bar 2303 // top layer: overlays such as the health bar
2244 for (y = 0; y < sh; y++) 2304 for (y = 0; y < sh; y++)
2245 if (0 <= y + my && y + my < self->rows) 2305 if (0 <= y + my && y + my < self->rows)
2246 { 2306 {
2251 { 2311 {
2252 mapcell *cell = row->col + (x + mx - row->c0); 2312 mapcell *cell = row->col + (x + mx - row->c0);
2253 2313
2254 int px = x * T; 2314 int px = x * T;
2255 int py = y * T; 2315 int py = y * T;
2316
2317 if (expect_false (cell->player == player))
2318 {
2319 px += sdx;
2320 py += sdy;
2321 }
2256 2322
2257 if (cell->stat_hp) 2323 if (cell->stat_hp)
2258 { 2324 {
2259 int width = cell->stat_width * T; 2325 int width = cell->stat_width * T;
2260 int thick = (sh * T / 32 + 27) / 28 + 1 + cell->stat_width; 2326 int thick = (sh * T / 32 + 27) / 28 + 1 + cell->stat_width;
2300 }; 2366 };
2301 2367
2302 int x, y; 2368 int x, y;
2303 2369
2304 glEnable (GL_TEXTURE_2D); 2370 glEnable (GL_TEXTURE_2D);
2371 /* GL_REPLACE would be correct, as we don't need to modulate alpha,
2372 * but the nvidia driver (185.18.14) mishandles alpha textures
2373 * ansd takes the colour from god knows where instead of using
2374 * Cp. MODULATE results in the same colour, but slightly different
2375 * alpha, but atcually gives us the correct colour with nvidia.
2376 */
2305 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 2377 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
2306 glEnable (GL_BLEND); 2378 glEnable (GL_BLEND);
2307 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2379 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2308 glBegin (GL_QUADS); 2380 glBegin (GL_QUADS);
2309 2381
2310 for (y = 0; y < h; y++) 2382 for (y = 0; y < h; y++)
2317 float *c = color [m & 15]; 2389 float *c = color [m & 15];
2318 2390
2319 float tx1 = m & 0x40 ? 0.5 : 0.; 2391 float tx1 = m & 0x40 ? 0.5 : 0.;
2320 float tx2 = tx1 + 0.5; 2392 float tx2 = tx1 + 0.5;
2321 2393
2322 glColor4f (c[0], c[1], c[2], 0.75); 2394 glColor4f (c[0], c[1], c[2], 1);
2323 glTexCoord2f (tx1, 0.); glVertex2i (x , y ); 2395 glTexCoord2f (tx1, 0.); glVertex2i (x , y );
2324 glTexCoord2f (tx1, 1.); glVertex2i (x , y + 1); 2396 glTexCoord2f (tx1, 1.); glVertex2i (x , y + 1);
2325 glTexCoord2f (tx2, 1.); glVertex2i (x + 1, y + 1); 2397 glTexCoord2f (tx2, 1.); glVertex2i (x + 1, y + 1);
2326 glTexCoord2f (tx2, 0.); glVertex2i (x + 1, y ); 2398 glTexCoord2f (tx2, 0.); glVertex2i (x + 1, y );
2327 } 2399 }
2884 const_iv (GL_NICEST), 2956 const_iv (GL_NICEST),
2885 const_iv (GL_V2F), 2957 const_iv (GL_V2F),
2886 const_iv (GL_V3F), 2958 const_iv (GL_V3F),
2887 const_iv (GL_T2F_V3F), 2959 const_iv (GL_T2F_V3F),
2888 const_iv (GL_T2F_N3F_V3F), 2960 const_iv (GL_T2F_N3F_V3F),
2961 const_iv (GL_FUNC_ADD),
2962 const_iv (GL_FUNC_SUBTRACT),
2963 const_iv (GL_FUNC_REVERSE_SUBTRACT),
2889# undef const_iv 2964# undef const_iv
2890 }; 2965 };
2891 2966
2892 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 2967 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
2893 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 2968 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
2900disable_GL_EXT_blend_func_separate () 2975disable_GL_EXT_blend_func_separate ()
2901 CODE: 2976 CODE:
2902 gl.BlendFuncSeparate = 0; 2977 gl.BlendFuncSeparate = 0;
2903 gl.BlendFuncSeparateEXT = 0; 2978 gl.BlendFuncSeparateEXT = 0;
2904 2979
2980void
2981apple_nvidia_bug (int enable)
2982
2905char * 2983char *
2906gl_vendor () 2984gl_vendor ()
2907 CODE: 2985 CODE:
2908 RETVAL = (char *)glGetString (GL_VENDOR); 2986 RETVAL = (char *)glGetString (GL_VENDOR);
2909 OUTPUT: 2987 OUTPUT:
2958 3036
2959void glBlendFuncSeparate (int sa, int da, int saa, int daa) 3037void glBlendFuncSeparate (int sa, int da, int saa, int daa)
2960 CODE: 3038 CODE:
2961 gl_BlendFuncSeparate (sa, da, saa, daa); 3039 gl_BlendFuncSeparate (sa, da, saa, daa);
2962 3040
3041# void glBlendEquation (int se)
3042
2963void glDepthMask (int flag) 3043void glDepthMask (int flag)
2964 3044
2965void glLogicOp (int opcode) 3045void glLogicOp (int opcode)
2966 3046
2967void glColorMask (int red, int green, int blue, int alpha) 3047void glColorMask (int red, int green, int blue, int alpha)
3001void glRotate (float angle, float x, float y, float z) 3081void glRotate (float angle, float x, float y, float z)
3002 CODE: 3082 CODE:
3003 glRotatef (angle, x, y, z); 3083 glRotatef (angle, x, y, z);
3004 3084
3005void glColor (float r, float g, float b, float a = 1.0) 3085void glColor (float r, float g, float b, float a = 1.0)
3086 PROTOTYPE: @
3006 ALIAS: 3087 ALIAS:
3007 glColor_premultiply = 1 3088 glColor_premultiply = 1
3008 CODE: 3089 CODE:
3009 if (ix) 3090 if (ix)
3010 { 3091 {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines