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

76# include <netinet/in.h> 76# include <netinet/in.h>
77# include <netinet/tcp.h> 77# include <netinet/tcp.h>
78# include <inttypes.h> 78# include <inttypes.h>
79#endif 79#endif
80 80
81#if __GNUC__ >= 4 81#include "ecb.h"
82# define expect(expr,value) __builtin_expect ((expr),(value))
83#else
84# define expect(expr,value) (expr)
85#endif
86
87#define expect_false(expr) expect ((expr) != 0, 0)
88#define expect_true(expr) expect ((expr) != 0, 1)
89 82
90#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, object replacement character */ 83#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, object replacement character */
91 84
92/* 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 */
93/* then anything that is computed by incoming darkness */ 86/* then anything that is computed by incoming darkness */
111fast_sv_grow (SV *sv, STRLEN need) 104fast_sv_grow (SV *sv, STRLEN need)
112{ 105{
113 STRLEN len = SvLEN (sv); 106 STRLEN len = SvLEN (sv);
114 STRLEN want = SvCUR (sv) + need; 107 STRLEN want = SvCUR (sv) + need;
115 108
116 if (expect_false (len < want)) 109 if (ecb_expect_false (len < want))
117 { 110 {
118 do 111 do
119 len *= 2; 112 len *= 2;
120 while (len < want); 113 while (len < want);
121 114
205struct cf_layout { 198struct cf_layout {
206 PangoLayout *pl; 199 PangoLayout *pl;
207 float r, g, b, a; // default color for rgba mode 200 float r, g, b, a; // default color for rgba mode
208 int base_height; 201 int base_height;
209 DC__Font font; 202 DC__Font font;
210 rc_t *rc; 203 rc_t rc;
211}; 204};
212 205
213typedef cf_layout *DC__Layout; 206typedef cf_layout *DC__Layout;
214 207
215static DC__Font default_font; 208static DC__Font default_font;
255 if (!rect.height) rect.height = 1; 248 if (!rect.height) rect.height = 1;
256 249
257 *w = rect.width; 250 *w = rect.width;
258 *h = rect.height; 251 *h = rect.height;
259} 252}
253
254/////////////////////////////////////////////////////////////////////////////
260 255
261typedef uint16_t tileid; 256typedef uint16_t tileid;
262typedef uint16_t faceid; 257typedef uint16_t faceid;
263 258
264struct maptex 259struct maptex
296 maprow *row; 291 maprow *row;
297}; 292};
298 293
299typedef mapgrid *DC__Map; 294typedef mapgrid *DC__Map;
300 295
301static char * 296template<typename T>
297static void
302prepend (char *ptr, int sze, int inc) 298prepend (T *&ptr, int sze, int inc)
303{ 299{
304 char *p; 300 T *p;
305 301
306 New (0, p, sze + inc, char); 302 Newx (p, inc + sze, T);
307 Zero (p, inc, char); 303 Zero (p, inc, T);
308 Move (ptr, p + inc, sze, char); 304 Move (ptr, p + inc, sze, T);
309 Safefree (ptr); 305 Safefree (ptr);
310 306
311 return p; 307 ptr = p;
312} 308}
313 309
314static char * 310template<typename T>
311static void
315append (char *ptr, int sze, int inc) 312append (T *&ptr, int sze, int inc)
316{ 313{
317 Renew (ptr, sze + inc, char); 314 Renew (ptr, sze + inc, T);
318 Zero (ptr + sze, inc, char); 315 Zero (ptr + sze, inc, T);
319
320 return ptr;
321} 316}
322
323#define Append(type,ptr,sze,inc) (ptr) = (type *)append ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type))
324#define Prepend(type,ptr,sze,inc) (ptr) = (type *)prepend ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type))
325 317
326static void 318static void
327need_facenum (struct mapgrid *self, faceid face) 319need_facenum (struct mapgrid *self, faceid face)
328{ 320{
329 while (self->faces <= face) 321 while (self->faces <= face)
330 { 322 {
331 Append (tileid, self->face2tile, self->faces, self->faces); 323 append (self->face2tile, self->faces, self->faces);
332 self->faces *= 2; 324 self->faces *= 2;
333 } 325 }
334} 326}
335 327
336static void 328static void
337need_texid (struct mapgrid *self, int texid) 329need_texid (struct mapgrid *self, int texid)
338{ 330{
339 while (self->texs <= texid) 331 while (self->texs <= texid)
340 { 332 {
341 Append (maptex, self->tex, self->texs, self->texs); 333 append (self->tex, self->texs, self->texs);
342 self->texs *= 2; 334 self->texs *= 2;
343 } 335 }
344} 336}
345 337
346static maprow * 338static maprow *
347map_get_row (mapgrid *self, int y) 339map_get_row (mapgrid *self, int y)
348{ 340{
349 if (0 > y) 341 if (0 > y)
350 { 342 {
351 int extend = - y + MAP_EXTEND_Y; 343 int extend = - y + MAP_EXTEND_Y;
352 Prepend (maprow, self->row, self->rows, extend); 344 prepend (self->row, self->rows, extend);
353 345
354 self->rows += extend; 346 self->rows += extend;
355 self->y += extend; 347 self->y += extend;
356 y += extend; 348 y += extend;
357 } 349 }
358 else if (y >= self->rows) 350 else if (y >= self->rows)
359 { 351 {
360 int extend = y - self->rows + MAP_EXTEND_Y; 352 int extend = y - self->rows + MAP_EXTEND_Y;
361 Append (maprow, self->row, self->rows, extend); 353 append (self->row, self->rows, extend);
362 self->rows += extend; 354 self->rows += extend;
363 } 355 }
364 356
365 return self->row + y; 357 return self->row + y;
366} 358}
376 } 368 }
377 369
378 if (row->c0 > x) 370 if (row->c0 > x)
379 { 371 {
380 int extend = row->c0 - x + MAP_EXTEND_X; 372 int extend = row->c0 - x + MAP_EXTEND_X;
381 Prepend (mapcell, row->col, row->c1 - row->c0, extend); 373 prepend (row->col, row->c1 - row->c0, extend);
382 row->c0 -= extend; 374 row->c0 -= extend;
383 } 375 }
384 else if (x >= row->c1) 376 else if (x >= row->c1)
385 { 377 {
386 int extend = x - row->c1 + MAP_EXTEND_X; 378 int extend = x - row->c1 + MAP_EXTEND_X;
387 Append (mapcell, row->col, row->c1 - row->c0, extend); 379 append (row->col, row->c1 - row->c0, extend);
388 row->c1 += extend; 380 row->c1 += extend;
389 } 381 }
390 382
391 return row->col + (x - row->c0); 383 return row->col + (x - row->c0);
392} 384}
534 n |= n >> 4; 526 n |= n >> 4;
535 n |= n >> 8; 527 n |= n >> 8;
536 n |= n >> 16; 528 n |= n >> 16;
537 529
538 return n + 1; 530 return n + 1;
539}
540
541static unsigned int
542popcount (unsigned int n)
543{
544 n -= (n >> 1) & 0x55555555U;
545 n = ((n >> 2) & 0x33333333U) + (n & 0x33333333U);
546 n = ((n >> 4) + n) & 0x0f0f0f0fU;
547 n *= 0x01010101U;
548
549 return n >> 24;
550} 531}
551 532
552/* SDL should provide this, really. */ 533/* SDL should provide this, really. */
553#define SDLK_MODIFIER_MIN 300 534#define SDLK_MODIFIER_MIN 300
554#define SDLK_MODIFIER_MAX 314 535#define SDLK_MODIFIER_MAX 314
886NV ceil (NV x) 867NV ceil (NV x)
887 868
888IV minpot (UV n) 869IV minpot (UV n)
889 870
890IV popcount (UV n) 871IV popcount (UV n)
872 CODE:
873 RETVAL = ecb_popcount32 (n);
874 OUTPUT:
875 RETVAL
891 876
892NV distance (NV dx, NV dy) 877NV distance (NV dx, NV dy)
893 CODE: 878 CODE:
894 RETVAL = pow (dx * dx + dy * dy, 0.5); 879 RETVAL = pow (dx * dx + dy * dy, 0.5);
895 OUTPUT: 880 OUTPUT:
1369 tc_restore (); 1354 tc_restore ();
1370 1355
1371DC::Layout 1356DC::Layout
1372new (SV *klass) 1357new (SV *klass)
1373 CODE: 1358 CODE:
1374 New (0, RETVAL, 1, struct cf_layout); 1359 RETVAL = new cf_layout;
1375 1360
1376 RETVAL->pl = pango_layout_new (opengl_context); 1361 RETVAL->pl = pango_layout_new (opengl_context);
1377 RETVAL->r = 1.; 1362 RETVAL->r = 1.;
1378 RETVAL->g = 1.; 1363 RETVAL->g = 1.;
1379 RETVAL->b = 1.; 1364 RETVAL->b = 1.;
1380 RETVAL->a = 1.; 1365 RETVAL->a = 1.;
1381 RETVAL->base_height = MIN_FONT_HEIGHT; 1366 RETVAL->base_height = MIN_FONT_HEIGHT;
1382 RETVAL->font = 0; 1367 RETVAL->font = 0;
1383 RETVAL->rc = rc_alloc ();
1384 1368
1385 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR); 1369 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
1386 layout_update_font (RETVAL); 1370 layout_update_font (RETVAL);
1387 OUTPUT: 1371 OUTPUT:
1388 RETVAL 1372 RETVAL
1389 1373
1390void 1374void
1391DESTROY (DC::Layout self) 1375DESTROY (DC::Layout self)
1392 CODE: 1376 CODE:
1393 g_object_unref (self->pl); 1377 g_object_unref (self->pl);
1394 rc_free (self->rc);
1395 Safefree (self); 1378 delete self;
1396 1379
1397void 1380void
1398set_text (DC::Layout self, SV *text_) 1381set_text (DC::Layout self, SV *text_)
1399 CODE: 1382 CODE:
1400{ 1383{
1654} 1637}
1655 1638
1656void 1639void
1657render (DC::Layout self, float x, float y, int flags = 0) 1640render (DC::Layout self, float x, float y, int flags = 0)
1658 CODE: 1641 CODE:
1659 rc_clear (self->rc); 1642 self->rc.clear ();
1660 pango_opengl_render_layout_subpixel ( 1643 pango_opengl_render_layout_subpixel (
1661 self->pl, 1644 self->pl,
1662 self->rc, 1645 &self->rc,
1663 x * PANGO_SCALE, y * PANGO_SCALE, 1646 x * PANGO_SCALE, y * PANGO_SCALE,
1664 self->r, self->g, self->b, self->a, 1647 self->r, self->g, self->b, self->a,
1665 flags 1648 flags
1666 ); 1649 );
1667 // we assume that context_change actually clears/frees stuff 1650 // we assume that context_change actually clears/frees stuff
1678 gl_BlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 1661 gl_BlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
1679 GL_ONE , GL_ONE_MINUS_SRC_ALPHA); 1662 GL_ONE , GL_ONE_MINUS_SRC_ALPHA);
1680 glEnable (GL_ALPHA_TEST); 1663 glEnable (GL_ALPHA_TEST);
1681 glAlphaFunc (GL_GREATER, 7.f / 255.f); 1664 glAlphaFunc (GL_GREATER, 7.f / 255.f);
1682 1665
1683 rc_draw (self->rc); 1666 self->rc.draw ();
1684 1667
1685 glDisable (GL_ALPHA_TEST); 1668 glDisable (GL_ALPHA_TEST);
1686 glDisable (GL_BLEND); 1669 glDisable (GL_BLEND);
1687 glDisable (GL_TEXTURE_2D); 1670 glDisable (GL_TEXTURE_2D);
1688} 1671}
2058 self->ox += dx; self->x += dx; 2041 self->ox += dx; self->x += dx;
2059 self->oy += dy; self->y += dy; 2042 self->oy += dy; self->y += dy;
2060 2043
2061 while (self->y < 0) 2044 while (self->y < 0)
2062 { 2045 {
2063 Prepend (maprow, self->row, self->rows, MAP_EXTEND_Y); 2046 prepend (self->row, self->rows, MAP_EXTEND_Y);
2064 2047
2065 self->rows += MAP_EXTEND_Y; 2048 self->rows += MAP_EXTEND_Y;
2066 self->y += MAP_EXTEND_Y; 2049 self->y += MAP_EXTEND_Y;
2067 } 2050 }
2068} 2051}
2227 int x, y, z; 2210 int x, y, z;
2228 2211
2229 static uint8_t smooth_max[256][256]; // egad, fast and wasteful on memory (64k), also, static! 2212 static uint8_t smooth_max[256][256]; // egad, fast and wasteful on memory (64k), also, static!
2230 int pl_x, pl_y; 2213 int pl_x, pl_y;
2231 maptex pl_tex; 2214 maptex pl_tex;
2232 rc_t *rc = rc_alloc (); 2215 rc_t rc;
2233 rc_t *rc_ov = rc_alloc (); 2216 rc_t rc_ov;
2234 rc_key_t key; 2217 rc_key_t key;
2235 rc_array_t *arr; 2218 rc_t::array_t *arr;
2236 2219
2237 pl_tex.name = 0; 2220 pl_tex.name = 0;
2238 2221
2239 // that's current max. sorry. 2222 // that's current max. sorry.
2240 if (sw > 255) sw = 255; 2223 if (sw > 255) sw = 255;
2306 2289
2307 if (!tex.name) 2290 if (!tex.name)
2308 tex = self->tex [TEXID_NOFACE]; /* missing, replace by noface */ 2291 tex = self->tex [TEXID_NOFACE]; /* missing, replace by noface */
2309 2292
2310 key.texname = tex.name; 2293 key.texname = tex.name;
2311 arr = rc_array (rc, &key); 2294 arr = &rc.array (key);
2312 } 2295 }
2313 2296
2314 px = (x + 1) * Th - tex.w; 2297 px = (x + 1) * Th - tex.w;
2315 py = (y + 1) * Tw - tex.h; 2298 py = (y + 1) * Tw - tex.h;
2316 2299
2317 if (expect_false (cell->player == player) && expect_false (z == 2)) 2300 if (ecb_expect_false (cell->player == player) && ecb_expect_false (z == 2))
2318 { 2301 {
2319 pl_x = px; 2302 pl_x = px;
2320 pl_y = py; 2303 pl_y = py;
2321 pl_tex = tex; 2304 pl_tex = tex;
2322 continue; 2305 continue;
2323 } 2306 }
2324 2307
2325 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2308 arr->t2f_v3f (0 , 0 , px , py , 0);
2326 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0); 2309 arr->t2f_v3f (0 , tex.t, px , py + tex.h, 0);
2327 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);
2328 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0); 2311 arr->t2f_v3f (tex.s, 0 , px + tex.w, py , 0);
2329 2312
2330 // update smooth hash 2313 // update smooth hash
2331 if (tex.smoothtile) 2314 if (tex.smoothtile)
2332 { 2315 {
2333 skey.tile = tex.smoothtile; 2316 skey.tile = tex.smoothtile;
2365 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);
2366 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);
2367 } 2350 }
2368 } 2351 }
2369 2352
2370 if (expect_false (z == 2) && expect_false (cell->flags)) 2353 if (ecb_expect_false (z == 2) && ecb_expect_false (cell->flags))
2371 { 2354 {
2372 // overlays such as the speech bubble, probably more to come 2355 // overlays such as the speech bubble, probably more to come
2373 if (cell->flags & 1) 2356 if (cell->flags & 1)
2374 { 2357 {
2375 rc_key_t key_ov = key; 2358 rc_key_t key_ov = key;
2376 maptex tex = self->tex [TEXID_SPEECH]; 2359 maptex tex = self->tex[TEXID_SPEECH];
2377 rc_array_t *arr;
2378 int px = x * Tw + Tw * 2 / 32; 2360 int px = x * Tw + Tw * 2 / 32;
2379 int py = y * Th - Th * 6 / 32; 2361 int py = y * Th - Th * 6 / 32;
2380 2362
2381 key_ov.texname = tex.name; 2363 key_ov.texname = tex.name;
2382 arr = rc_array (rc_ov, &key_ov); 2364 rc_t::array_t &arr = rc_ov.array (key_ov);
2383 2365
2384 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2366 arr.t2f_v3f (0 , 0 , px , py , 0);
2385 rc_t2f_v3f (arr, 0 , tex.t, px , py + Th, 0); 2367 arr.t2f_v3f (0 , tex.t, px , py + Th, 0);
2386 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);
2387 rc_t2f_v3f (arr, tex.s, 0 , px + Tw, py , 0); 2369 arr.t2f_v3f (tex.s, 0 , px + Tw, py , 0);
2388 } 2370 }
2389 } 2371 }
2390 } 2372 }
2391 } 2373 }
2392 2374
2393 rc_draw (rc); 2375 rc.draw ();
2394 rc_clear (rc); 2376 rc.clear ();
2395 2377
2396 // go through all smoothlevels, lowest to highest, then draw. 2378 // go through all smoothlevels, lowest to highest, then draw.
2397 // this is basically counting sort 2379 // this is basically counting sort
2398 { 2380 {
2399 int w, b; 2381 int w, b;
2466 maptex tex = pl_tex; 2448 maptex tex = pl_tex;
2467 int px = pl_x + sdx; 2449 int px = pl_x + sdx;
2468 int py = pl_y + sdy; 2450 int py = pl_y + sdy;
2469 2451
2470 key.texname = tex.name; 2452 key.texname = tex.name;
2471 arr = rc_array (rc, &key); 2453 rc_t::array_t &arr = rc.array (key);
2472 2454
2473 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2455 arr.t2f_v3f (0 , 0 , px , py , 0);
2474 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0); 2456 arr.t2f_v3f (0 , tex.t, px , py + tex.h, 0);
2475 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);
2476 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0); 2458 arr.t2f_v3f (tex.s, 0 , px + tex.w, py , 0);
2477 2459
2478 rc_draw (rc); 2460 rc.draw ();
2479 } 2461 }
2480 2462
2481 rc_draw (rc_ov); 2463 rc_ov.draw ();
2482 rc_clear (rc_ov); 2464 rc_ov.clear ();
2483 2465
2484 glDisable (GL_BLEND); 2466 glDisable (GL_BLEND);
2485 rc_free (rc);
2486 rc_free (rc_ov);
2487 2467
2488 // top layer: overlays such as the health bar 2468 // top layer: overlays such as the health bar
2489 for (y = 0; y < sh; y++) 2469 for (y = 0; y < sh; y++)
2490 if (0 <= y + my && y + my < self->rows) 2470 if (0 <= y + my && y + my < self->rows)
2491 { 2471 {
2497 mapcell *cell = row->col + (x + mx - row->c0); 2477 mapcell *cell = row->col + (x + mx - row->c0);
2498 2478
2499 int px = x * Tw; 2479 int px = x * Tw;
2500 int py = y * Th; 2480 int py = y * Th;
2501 2481
2502 if (expect_false (cell->player == player)) 2482 if (ecb_expect_false (cell->player == player))
2503 { 2483 {
2504 px += sdx; 2484 px += sdx;
2505 py += sdy; 2485 py += sdy;
2506 } 2486 }
2507 2487

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines