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.323 by root, Sun Nov 18 01:48:39 2018 UTC vs.
Revision 1.331 by root, Mon Nov 19 00:10:34 2018 UTC

32#include <cstring> 32#include <cstring>
33#include <cstdio> 33#include <cstdio>
34#include <cstdlib> 34#include <cstdlib>
35 35
36#include <utility> 36#include <utility>
37#include <bitset>
37 38
38#define USE_RWOPS 1 // for SDL_mixer:LoadMUS_RW 39#define USE_RWOPS 1 // for SDL_mixer:LoadMUS_RW
39 40
40#include <SDL.h> 41#include <SDL.h>
41#include <SDL_thread.h> 42#include <SDL_thread.h>
75# include <netinet/in.h> 76# include <netinet/in.h>
76# include <netinet/tcp.h> 77# include <netinet/tcp.h>
77# include <inttypes.h> 78# include <inttypes.h>
78#endif 79#endif
79 80
80#if __GNUC__ >= 4 81#include "ecb.h"
81# define expect(expr,value) __builtin_expect ((expr),(value))
82#else
83# define expect(expr,value) (expr)
84#endif
85
86#define expect_false(expr) expect ((expr) != 0, 0)
87#define expect_true(expr) expect ((expr) != 0, 1)
88 82
89#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, object replacement character */ 83#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, object replacement character */
90 84
91/* this is used as fow flag as well, so has to have a different value */ 85/* this is used as fow flag as well, so has to have a different value */
92/* then anything that is computed by incoming darkness */ 86/* then anything that is computed by incoming darkness */
110fast_sv_grow (SV *sv, STRLEN need) 104fast_sv_grow (SV *sv, STRLEN need)
111{ 105{
112 STRLEN len = SvLEN (sv); 106 STRLEN len = SvLEN (sv);
113 STRLEN want = SvCUR (sv) + need; 107 STRLEN want = SvCUR (sv) + need;
114 108
115 if (expect_false (len < want)) 109 if (ecb_expect_false (len < want))
116 { 110 {
117 do 111 do
118 len *= 2; 112 len *= 2;
119 while (len < want); 113 while (len < want);
120 114
204struct cf_layout { 198struct cf_layout {
205 PangoLayout *pl; 199 PangoLayout *pl;
206 float r, g, b, a; // default color for rgba mode 200 float r, g, b, a; // default color for rgba mode
207 int base_height; 201 int base_height;
208 DC__Font font; 202 DC__Font font;
209 rc_t *rc; 203 rc_t rc;
210}; 204};
211 205
212typedef cf_layout *DC__Layout; 206typedef cf_layout *DC__Layout;
213 207
214static DC__Font default_font; 208static DC__Font default_font;
254 if (!rect.height) rect.height = 1; 248 if (!rect.height) rect.height = 1;
255 249
256 *w = rect.width; 250 *w = rect.width;
257 *h = rect.height; 251 *h = rect.height;
258} 252}
253
254/////////////////////////////////////////////////////////////////////////////
259 255
260typedef uint16_t tileid; 256typedef uint16_t tileid;
261typedef uint16_t faceid; 257typedef uint16_t faceid;
262 258
263struct maptex 259struct maptex
295 maprow *row; 291 maprow *row;
296}; 292};
297 293
298typedef mapgrid *DC__Map; 294typedef mapgrid *DC__Map;
299 295
300static char * 296template<typename T>
297static void
301prepend (char *ptr, int sze, int inc) 298prepend (T *&ptr, int sze, int inc)
302{ 299{
303 char *p; 300 T *p;
304 301
305 New (0, p, sze + inc, char); 302 Newx (p, inc + sze, T);
306 Zero (p, inc, char); 303 Zero (p, inc, T);
307 Move (ptr, p + inc, sze, char); 304 Move (ptr, p + inc, sze, T);
308 Safefree (ptr); 305 Safefree (ptr);
309 306
310 return p; 307 ptr = p;
311} 308}
312 309
313static char * 310template<typename T>
311static void
314append (char *ptr, int sze, int inc) 312append (T *&ptr, int sze, int inc)
315{ 313{
316 Renew (ptr, sze + inc, char); 314 Renew (ptr, sze + inc, T);
317 Zero (ptr + sze, inc, char); 315 Zero (ptr + sze, inc, T);
318
319 return ptr;
320} 316}
321
322#define Append(type,ptr,sze,inc) (ptr) = (type *)append ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type))
323#define Prepend(type,ptr,sze,inc) (ptr) = (type *)prepend ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type))
324 317
325static void 318static void
326need_facenum (struct mapgrid *self, faceid face) 319need_facenum (struct mapgrid *self, faceid face)
327{ 320{
328 while (self->faces <= face) 321 while (self->faces <= face)
329 { 322 {
330 Append (tileid, self->face2tile, self->faces, self->faces); 323 append (self->face2tile, self->faces, self->faces);
331 self->faces *= 2; 324 self->faces *= 2;
332 } 325 }
333} 326}
334 327
335static void 328static void
336need_texid (struct mapgrid *self, int texid) 329need_texid (struct mapgrid *self, int texid)
337{ 330{
338 while (self->texs <= texid) 331 while (self->texs <= texid)
339 { 332 {
340 Append (maptex, self->tex, self->texs, self->texs); 333 append (self->tex, self->texs, self->texs);
341 self->texs *= 2; 334 self->texs *= 2;
342 } 335 }
343} 336}
344 337
345static maprow * 338static maprow *
346map_get_row (mapgrid *self, int y) 339map_get_row (mapgrid *self, int y)
347{ 340{
348 if (0 > y) 341 if (0 > y)
349 { 342 {
350 int extend = - y + MAP_EXTEND_Y; 343 int extend = - y + MAP_EXTEND_Y;
351 Prepend (maprow, self->row, self->rows, extend); 344 prepend (self->row, self->rows, extend);
352 345
353 self->rows += extend; 346 self->rows += extend;
354 self->y += extend; 347 self->y += extend;
355 y += extend; 348 y += extend;
356 } 349 }
357 else if (y >= self->rows) 350 else if (y >= self->rows)
358 { 351 {
359 int extend = y - self->rows + MAP_EXTEND_Y; 352 int extend = y - self->rows + MAP_EXTEND_Y;
360 Append (maprow, self->row, self->rows, extend); 353 append (self->row, self->rows, extend);
361 self->rows += extend; 354 self->rows += extend;
362 } 355 }
363 356
364 return self->row + y; 357 return self->row + y;
365} 358}
375 } 368 }
376 369
377 if (row->c0 > x) 370 if (row->c0 > x)
378 { 371 {
379 int extend = row->c0 - x + MAP_EXTEND_X; 372 int extend = row->c0 - x + MAP_EXTEND_X;
380 Prepend (mapcell, row->col, row->c1 - row->c0, extend); 373 prepend (row->col, row->c1 - row->c0, extend);
381 row->c0 -= extend; 374 row->c0 -= extend;
382 } 375 }
383 else if (x >= row->c1) 376 else if (x >= row->c1)
384 { 377 {
385 int extend = x - row->c1 + MAP_EXTEND_X; 378 int extend = x - row->c1 + MAP_EXTEND_X;
386 Append (mapcell, row->col, row->c1 - row->c0, extend); 379 append (row->col, row->c1 - row->c0, extend);
387 row->c1 += extend; 380 row->c1 += extend;
388 } 381 }
389 382
390 return row->col + (x - row->c0); 383 return row->col + (x - row->c0);
391} 384}
533 n |= n >> 4; 526 n |= n >> 4;
534 n |= n >> 8; 527 n |= n >> 8;
535 n |= n >> 16; 528 n |= n >> 16;
536 529
537 return n + 1; 530 return n + 1;
538}
539
540static unsigned int
541popcount (unsigned int n)
542{
543 n -= (n >> 1) & 0x55555555U;
544 n = ((n >> 2) & 0x33333333U) + (n & 0x33333333U);
545 n = ((n >> 4) + n) & 0x0f0f0f0fU;
546 n *= 0x01010101U;
547
548 return n >> 24;
549} 531}
550 532
551/* SDL should provide this, really. */ 533/* SDL should provide this, really. */
552#define SDLK_MODIFIER_MIN 300 534#define SDLK_MODIFIER_MIN 300
553#define SDLK_MODIFIER_MAX 314 535#define SDLK_MODIFIER_MAX 314
885NV ceil (NV x) 867NV ceil (NV x)
886 868
887IV minpot (UV n) 869IV minpot (UV n)
888 870
889IV popcount (UV n) 871IV popcount (UV n)
872 CODE:
873 RETVAL = ecb_popcount32 (n);
874 OUTPUT:
875 RETVAL
890 876
891NV distance (NV dx, NV dy) 877NV distance (NV dx, NV dy)
892 CODE: 878 CODE:
893 RETVAL = pow (dx * dx + dy * dy, 0.5); 879 RETVAL = pow (dx * dx + dy * dy, 0.5);
894 OUTPUT: 880 OUTPUT:
1368 tc_restore (); 1354 tc_restore ();
1369 1355
1370DC::Layout 1356DC::Layout
1371new (SV *klass) 1357new (SV *klass)
1372 CODE: 1358 CODE:
1373 New (0, RETVAL, 1, struct cf_layout); 1359 RETVAL = new cf_layout;
1374 1360
1375 RETVAL->pl = pango_layout_new (opengl_context); 1361 RETVAL->pl = pango_layout_new (opengl_context);
1376 RETVAL->r = 1.; 1362 RETVAL->r = 1.;
1377 RETVAL->g = 1.; 1363 RETVAL->g = 1.;
1378 RETVAL->b = 1.; 1364 RETVAL->b = 1.;
1379 RETVAL->a = 1.; 1365 RETVAL->a = 1.;
1380 RETVAL->base_height = MIN_FONT_HEIGHT; 1366 RETVAL->base_height = MIN_FONT_HEIGHT;
1381 RETVAL->font = 0; 1367 RETVAL->font = 0;
1382 RETVAL->rc = rc_alloc ();
1383 1368
1384 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR); 1369 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
1385 layout_update_font (RETVAL); 1370 layout_update_font (RETVAL);
1386 OUTPUT: 1371 OUTPUT:
1387 RETVAL 1372 RETVAL
1388 1373
1389void 1374void
1390DESTROY (DC::Layout self) 1375DESTROY (DC::Layout self)
1391 CODE: 1376 CODE:
1392 g_object_unref (self->pl); 1377 g_object_unref (self->pl);
1393 rc_free (self->rc);
1394 Safefree (self); 1378 delete self;
1395 1379
1396void 1380void
1397set_text (DC::Layout self, SV *text_) 1381set_text (DC::Layout self, SV *text_)
1398 CODE: 1382 CODE:
1399{ 1383{
1653} 1637}
1654 1638
1655void 1639void
1656render (DC::Layout self, float x, float y, int flags = 0) 1640render (DC::Layout self, float x, float y, int flags = 0)
1657 CODE: 1641 CODE:
1658 rc_clear (self->rc); 1642 self->rc.clear ();
1659 pango_opengl_render_layout_subpixel ( 1643 pango_opengl_render_layout_subpixel (
1660 self->pl, 1644 self->pl,
1661 self->rc, 1645 &self->rc,
1662 x * PANGO_SCALE, y * PANGO_SCALE, 1646 x * PANGO_SCALE, y * PANGO_SCALE,
1663 self->r, self->g, self->b, self->a, 1647 self->r, self->g, self->b, self->a,
1664 flags 1648 flags
1665 ); 1649 );
1666 // we assume that context_change actually clears/frees stuff 1650 // we assume that context_change actually clears/frees stuff
1677 gl_BlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 1661 gl_BlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
1678 GL_ONE , GL_ONE_MINUS_SRC_ALPHA); 1662 GL_ONE , GL_ONE_MINUS_SRC_ALPHA);
1679 glEnable (GL_ALPHA_TEST); 1663 glEnable (GL_ALPHA_TEST);
1680 glAlphaFunc (GL_GREATER, 7.f / 255.f); 1664 glAlphaFunc (GL_GREATER, 7.f / 255.f);
1681 1665
1682 rc_draw (self->rc); 1666 self->rc.draw ();
1683 1667
1684 glDisable (GL_ALPHA_TEST); 1668 glDisable (GL_ALPHA_TEST);
1685 glDisable (GL_BLEND); 1669 glDisable (GL_BLEND);
1686 glDisable (GL_TEXTURE_2D); 1670 glDisable (GL_TEXTURE_2D);
1687} 1671}
2057 self->ox += dx; self->x += dx; 2041 self->ox += dx; self->x += dx;
2058 self->oy += dy; self->y += dy; 2042 self->oy += dy; self->y += dy;
2059 2043
2060 while (self->y < 0) 2044 while (self->y < 0)
2061 { 2045 {
2062 Prepend (maprow, self->row, self->rows, MAP_EXTEND_Y); 2046 prepend (self->row, self->rows, MAP_EXTEND_Y);
2063 2047
2064 self->rows += MAP_EXTEND_Y; 2048 self->rows += MAP_EXTEND_Y;
2065 self->y += MAP_EXTEND_Y; 2049 self->y += MAP_EXTEND_Y;
2066 } 2050 }
2067} 2051}
2223draw (DC::Map self, int mx, int my, int sw, int sh, int Tw, int Th, U32 player = 0xffffffff, int sdx = 0, int sdy = 0) 2207draw (DC::Map self, int mx, int my, int sw, int sh, int Tw, int Th, U32 player = 0xffffffff, int sdx = 0, int sdy = 0)
2224 CODE: 2208 CODE:
2225{ 2209{
2226 int x, y, z; 2210 int x, y, z;
2227 2211
2228 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level
2229 static uint8_t smooth_max[256][256]; // egad, fast and wasteful on memory (64k) 2212 static uint8_t smooth_max[256][256]; // egad, fast and wasteful on memory (64k), also, static!
2230 smooth_key skey;
2231 int pl_x, pl_y; 2213 int pl_x, pl_y;
2232 maptex pl_tex; 2214 maptex pl_tex;
2233 rc_t *rc = rc_alloc (); 2215 rc_t rc;
2234 rc_t *rc_ov = rc_alloc (); 2216 rc_t rc_ov;
2235 rc_key_t key; 2217 rc_key_t key;
2236 rc_array_t *arr; 2218 rc_t::array_t *arr;
2237 2219
2238 pl_tex.name = 0; 2220 pl_tex.name = 0;
2239 2221
2240 // that's current max. sorry. 2222 // that's current max. sorry.
2241 if (sw > 255) sw = 255; 2223 if (sw > 255) sw = 255;
2242 if (sh > 255) sh = 255; 2224 if (sh > 255) sh = 255;
2243
2244 // clear key, in case of extra padding
2245 memset (&skey, 0, sizeof (skey));
2246 2225
2247 memset (&key, 0, sizeof (key)); 2226 memset (&key, 0, sizeof (key));
2248 key.r = 255; 2227 key.r = 255;
2249 key.g = 255; 2228 key.g = 255;
2250 key.b = 255; 2229 key.b = 255;
2256 my += self->y; 2235 my += self->y;
2257 2236
2258 // first pass: determine smooth_max 2237 // first pass: determine smooth_max
2259 // rather ugly, if you ask me 2238 // rather ugly, if you ask me
2260 // could also be stored inside mapcell and updated on change 2239 // could also be stored inside mapcell and updated on change
2261 memset (smooth_max, 0, sizeof (smooth_max)); 2240 memset (smooth_max, 0, sizeof (smooth_max[0]) * (sh + 1));
2262 2241
2263 for (y = 0; y < sh; y++) 2242 for (y = 0; y < sh; y++)
2264 if (0 <= y + my && y + my < self->rows) 2243 if (0 <= y + my && y + my < self->rows)
2265 { 2244 {
2266 maprow *row = self->row + (y + my); 2245 maprow *row = self->row + (y + my);
2281 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2260 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2282 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 2261 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
2283 2262
2284 for (z = 0; z <= 2; z++) 2263 for (z = 0; z <= 2; z++)
2285 { 2264 {
2265 std::bitset<256> smooth_level; // one bit for every possible smooth level
2266 smooth_key skey;
2286 smooth_hash smooth; 2267 smooth_hash smooth;
2287 memset (smooth_level, 0, sizeof (smooth_level));
2288 key.texname = -1; 2268 key.texname = -1;
2289 2269
2290 for (y = 0; y < sh; y++) 2270 for (y = 0; y < sh; y++)
2291 if (0 <= y + my && y + my < self->rows) 2271 if (0 <= y + my && y + my < self->rows)
2292 { 2272 {
2309 2289
2310 if (!tex.name) 2290 if (!tex.name)
2311 tex = self->tex [TEXID_NOFACE]; /* missing, replace by noface */ 2291 tex = self->tex [TEXID_NOFACE]; /* missing, replace by noface */
2312 2292
2313 key.texname = tex.name; 2293 key.texname = tex.name;
2314 arr = rc_array (rc, &key); 2294 arr = &rc.array (key);
2315 } 2295 }
2316 2296
2317 px = (x + 1) * Th - tex.w; 2297 px = (x + 1) * Th - tex.w;
2318 py = (y + 1) * Tw - tex.h; 2298 py = (y + 1) * Tw - tex.h;
2319 2299
2320 if (expect_false (cell->player == player) && expect_false (z == 2)) 2300 if (ecb_expect_false (cell->player == player) && ecb_expect_false (z == 2))
2321 { 2301 {
2322 pl_x = px; 2302 pl_x = px;
2323 pl_y = py; 2303 pl_y = py;
2324 pl_tex = tex; 2304 pl_tex = tex;
2325 continue; 2305 continue;
2326 } 2306 }
2327 2307
2328 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2308 arr->t2f_v3f (0 , 0 , px , py , 0);
2329 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0); 2309 arr->t2f_v3f (0 , tex.t, px , py + tex.h, 0);
2330 rc_t2f_v3f (arr, tex.s, tex.t, px + tex.w, py + tex.h, 0); 2310 arr->t2f_v3f (tex.s, tex.t, px + tex.w, py + tex.h, 0);
2331 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0); 2311 arr->t2f_v3f (tex.s, 0 , px + tex.w, py , 0);
2332 2312
2333 // update smooth hash 2313 // update smooth hash
2334 if (tex.smoothtile) 2314 if (tex.smoothtile)
2335 { 2315 {
2336 skey.tile = tex.smoothtile; 2316 skey.tile = tex.smoothtile;
2337 skey.level = tex.smoothlevel; 2317 skey.level = tex.smoothlevel;
2338 2318
2339 smooth_level [tex.smoothlevel >> 5] |= ((uint32_t)1) << (tex.smoothlevel & 31); 2319 smooth_level[tex.smoothlevel] = 1;
2340 2320
2341 // add bits to current tile and all neighbours. skey.x|y is 2321 // add bits to current tile and all neighbours. skey.x|y is
2342 // shifted +1|+1 so we always stay positive. 2322 // shifted +1|+1 so we always stay positive.
2343 2323
2344 // bits is ___n cccc CCCC bbbb 2324 // bits is ___n cccc CCCC bbbb
2368 skey.x = x ; skey.y = y ; smooth_or_bits (smooth, skey, 0x0400); 2348 skey.x = x ; skey.y = y ; smooth_or_bits (smooth, skey, 0x0400);
2369 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, skey, 0x0800); 2349 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, skey, 0x0800);
2370 } 2350 }
2371 } 2351 }
2372 2352
2373 if (expect_false (z == 2) && expect_false (cell->flags)) 2353 if (ecb_expect_false (z == 2) && ecb_expect_false (cell->flags))
2374 { 2354 {
2375 // overlays such as the speech bubble, probably more to come 2355 // overlays such as the speech bubble, probably more to come
2376 if (cell->flags & 1) 2356 if (cell->flags & 1)
2377 { 2357 {
2378 rc_key_t key_ov = key; 2358 rc_key_t key_ov = key;
2379 maptex tex = self->tex [TEXID_SPEECH]; 2359 maptex tex = self->tex[TEXID_SPEECH];
2380 rc_array_t *arr;
2381 int px = x * Tw + Tw * 2 / 32; 2360 int px = x * Tw + Tw * 2 / 32;
2382 int py = y * Th - Th * 6 / 32; 2361 int py = y * Th - Th * 6 / 32;
2383 2362
2384 key_ov.texname = tex.name; 2363 key_ov.texname = tex.name;
2385 arr = rc_array (rc_ov, &key_ov); 2364 rc_t::array_t &arr = rc_ov.array (key_ov);
2386 2365
2387 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2366 arr.t2f_v3f (0 , 0 , px , py , 0);
2388 rc_t2f_v3f (arr, 0 , tex.t, px , py + Th, 0); 2367 arr.t2f_v3f (0 , tex.t, px , py + Th, 0);
2389 rc_t2f_v3f (arr, tex.s, tex.t, px + Tw, py + Th, 0); 2368 arr.t2f_v3f (tex.s, tex.t, px + Tw, py + Th, 0);
2390 rc_t2f_v3f (arr, tex.s, 0 , px + Tw, py , 0); 2369 arr.t2f_v3f (tex.s, 0 , px + Tw, py , 0);
2391 } 2370 }
2392 } 2371 }
2393 } 2372 }
2394 } 2373 }
2395 2374
2396 rc_draw (rc); 2375 rc.draw ();
2397 rc_clear (rc); 2376 rc.clear ();
2398 2377
2399 // go through all smoothlevels, lowest to highest, then draw. 2378 // go through all smoothlevels, lowest to highest, then draw.
2400 // this is basically counting sort 2379 // this is basically counting sort
2401 { 2380 {
2402 int w, b; 2381 int w, b;
2403 2382
2404 glEnable (GL_TEXTURE_2D); 2383 glEnable (GL_TEXTURE_2D);
2405 glBegin (GL_QUADS); 2384 glBegin (GL_QUADS);
2406 for (w = 0; w < 256 / 32; ++w) 2385 for (int level = 0; level < smooth_level.size (); ++level)
2386 if (smooth_level[level])
2387 for (auto &&it = smooth.begin (); it != smooth.end (); ++it)
2407 { 2388 {
2408 uint32_t smask = smooth_level [w]; 2389 smooth_key &skey = it->first;
2409 if (smask) 2390 IV bits = it->second;
2410 for (b = 0; b < 32; ++b) 2391
2411 if (smask & (((uint32_t)1) << b)) 2392 if (!(bits & 0x1000)
2393 && skey.level == level
2394 && level > smooth_max [skey.x][skey.y])
2412 { 2395 {
2413 int level = (w << 5) | b; 2396 maptex tex = self->tex [skey.tile];
2397 int px = (((int)skey.x) - 1) * Tw;
2398 int py = (((int)skey.y) - 1) * Th;
2399 int border = bits & 15;
2400 int corner = (bits >> 8) & ~(bits >> 4) & 15;
2401 float dx = tex.s * .0625f; // 16 images/row
2402 float dy = tex.t * .5f ; // 2 images/column
2403
2414 HE *he; 2404 if (tex.name)
2415
2416 for (auto &&it = smooth.begin (); it != smooth.end (); ++it)
2417 { 2405 {
2418 smooth_key &skey = it->first; 2406 // this time avoiding texture state changes
2419 IV bits = it->second; 2407 // save gobs of state changes.
2420 2408 if (key.texname != tex.name)
2421 if (!(bits & 0x1000)
2422 && skey.level == level
2423 && level > smooth_max [skey.x][skey.y])
2424 { 2409 {
2425 maptex tex = self->tex [skey.tile];
2426 int px = (((int)skey.x) - 1) * Tw;
2427 int py = (((int)skey.y) - 1) * Th;
2428 int border = bits & 15;
2429 int corner = (bits >> 8) & ~(bits >> 4) & 15;
2430 float dx = tex.s * .0625f; // 16 images/row
2431 float dy = tex.t * .5f ; // 2 images/column
2432
2433 if (tex.name)
2434 {
2435 // this time avoiding texture state changes
2436 // save gobs of state changes.
2437 if (key.texname != tex.name)
2438 {
2439 self->tex [skey.tile].unused = 0; 2410 self->tex [skey.tile].unused = 0;
2440 2411
2441 glEnd (); 2412 glEnd ();
2442 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name); 2413 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name);
2443 glBegin (GL_QUADS); 2414 glBegin (GL_QUADS);
2444 } 2415 }
2445 2416
2446 if (border) 2417 if (border)
2447 { 2418 {
2448 float ox = border * dx; 2419 float ox = border * dx;
2449 2420
2450 glTexCoord2f (ox , 0.f ); glVertex2i (px , py ); 2421 glTexCoord2f (ox , 0.f ); glVertex2i (px , py );
2451 glTexCoord2f (ox , dy ); glVertex2i (px , py + Th); 2422 glTexCoord2f (ox , dy ); glVertex2i (px , py + Th);
2452 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py + Th); 2423 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py + Th);
2453 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + Tw, py ); 2424 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + Tw, py );
2454 } 2425 }
2455 2426
2456 if (corner) 2427 if (corner)
2457 { 2428 {
2458 float ox = corner * dx; 2429 float ox = corner * dx;
2459 2430
2460 glTexCoord2f (ox , dy ); glVertex2i (px , py ); 2431 glTexCoord2f (ox , dy ); glVertex2i (px , py );
2461 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + Th); 2432 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + Th);
2462 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + Tw, py + Th); 2433 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + Tw, py + Th);
2463 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py ); 2434 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py );
2464 }
2465 }
2466 } 2435 }
2467 } 2436 }
2468 } 2437 }
2469 } 2438 }
2470 2439
2471 glEnd (); 2440 glEnd ();
2472 glDisable (GL_TEXTURE_2D); 2441 glDisable (GL_TEXTURE_2D);
2473 key.texname = -1; 2442 key.texname = -1;
2474 } 2443 }
2479 maptex tex = pl_tex; 2448 maptex tex = pl_tex;
2480 int px = pl_x + sdx; 2449 int px = pl_x + sdx;
2481 int py = pl_y + sdy; 2450 int py = pl_y + sdy;
2482 2451
2483 key.texname = tex.name; 2452 key.texname = tex.name;
2484 arr = rc_array (rc, &key); 2453 rc_t::array_t &arr = rc.array (key);
2485 2454
2486 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2455 arr.t2f_v3f (0 , 0 , px , py , 0);
2487 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0); 2456 arr.t2f_v3f (0 , tex.t, px , py + tex.h, 0);
2488 rc_t2f_v3f (arr, tex.s, tex.t, px + tex.w, py + tex.h, 0); 2457 arr.t2f_v3f (tex.s, tex.t, px + tex.w, py + tex.h, 0);
2489 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0); 2458 arr.t2f_v3f (tex.s, 0 , px + tex.w, py , 0);
2490 2459
2491 rc_draw (rc); 2460 rc.draw ();
2492 } 2461 }
2493 2462
2494 rc_draw (rc_ov); 2463 rc_ov.draw ();
2495 rc_clear (rc_ov); 2464 rc_ov.clear ();
2496 2465
2497 glDisable (GL_BLEND); 2466 glDisable (GL_BLEND);
2498 rc_free (rc);
2499 rc_free (rc_ov);
2500 2467
2501 // top layer: overlays such as the health bar 2468 // top layer: overlays such as the health bar
2502 for (y = 0; y < sh; y++) 2469 for (y = 0; y < sh; y++)
2503 if (0 <= y + my && y + my < self->rows) 2470 if (0 <= y + my && y + my < self->rows)
2504 { 2471 {
2510 mapcell *cell = row->col + (x + mx - row->c0); 2477 mapcell *cell = row->col + (x + mx - row->c0);
2511 2478
2512 int px = x * Tw; 2479 int px = x * Tw;
2513 int py = y * Th; 2480 int py = y * Th;
2514 2481
2515 if (expect_false (cell->player == player)) 2482 if (ecb_expect_false (cell->player == player))
2516 { 2483 {
2517 px += sdx; 2484 px += sdx;
2518 py += sdy; 2485 py += sdy;
2519 } 2486 }
2520 2487

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines