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.327 by root, Sun Nov 18 12:01:50 2018 UTC vs.
Revision 1.335 by root, Mon Nov 19 01:56:11 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)) 82#include "salloc.h"
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 83
90#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, object replacement character */ 84#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, object replacement character */
91 85
92/* this is used as fow flag as well, so has to have a different value */ 86/* this is used as fow flag as well, so has to have a different value */
93/* then anything that is computed by incoming darkness */ 87/* then anything that is computed by incoming darkness */
105#define KMOD_LRAM 0x10000 // our extension 99#define KMOD_LRAM 0x10000 // our extension
106 100
107#define TEXID_SPEECH 1 101#define TEXID_SPEECH 1
108#define TEXID_NOFACE 2 102#define TEXID_NOFACE 2
109 103
104// approximately divide by 255
105static unsigned int
106div255 (unsigned int n)
107{
108 return (n + (n >> 8)) >> 8;
109}
110
111static unsigned int
112minpot (unsigned int n)
113{
114 if (!n)
115 return 0;
116
117 --n;
118
119 n |= n >> 1;
120 n |= n >> 2;
121 n |= n >> 4;
122 n |= n >> 8;
123 n |= n >> 16;
124
125 return n + 1;
126}
127
110static char * 128static char *
111fast_sv_grow (SV *sv, STRLEN need) 129fast_sv_grow (SV *sv, STRLEN need)
112{ 130{
113 STRLEN len = SvLEN (sv); 131 STRLEN len = SvLEN (sv);
114 STRLEN want = SvCUR (sv) + need; 132 STRLEN want = SvCUR (sv) + need;
115 133
116 if (expect_false (len < want)) 134 if (ecb_expect_false (len < want))
117 { 135 {
118 do 136 do
119 len *= 2; 137 len *= 2;
120 while (len < want); 138 while (len < want);
121 139
255 if (!rect.height) rect.height = 1; 273 if (!rect.height) rect.height = 1;
256 274
257 *w = rect.width; 275 *w = rect.width;
258 *h = rect.height; 276 *h = rect.height;
259} 277}
278
279/////////////////////////////////////////////////////////////////////////////
260 280
261typedef uint16_t tileid; 281typedef uint16_t tileid;
262typedef uint16_t faceid; 282typedef uint16_t faceid;
263 283
264struct maptex 284struct maptex
287}; 307};
288 308
289struct mapgrid { 309struct mapgrid {
290 int x, y, w, h; 310 int x, y, w, h;
291 int ox, oy; /* offset to virtual global coordinate system */ 311 int ox, oy; /* offset to virtual global coordinate system */
292 std::vector<tileid> tile; 312 int faces; tileid *face2tile; // [faceid]
293 std::vector<maptex> tex; 313 int texs; maptex *tex; // [tileid]
294 314
295 int32_t rows; 315 int32_t rows;
296 maprow *row; 316 maprow *row;
297
298 ~mapgrid ()
299 {
300 clear_cells ();
301 }
302
303 void clear_cells ();
304}; 317};
305 318
306typedef mapgrid *DC__Map; 319typedef mapgrid *DC__Map;
307 320
308static char * 321template<typename T>
322ecb_cold static void
309prepend (char *ptr, int sze, int inc) 323prepend (T *&ptr, int sze, int inc)
310{ 324{
311 char *p; 325 T *p;
312 326
313 New (0, p, sze + inc, char); 327 Newx (p, inc + sze, T);
314 Zero (p, inc, char); 328 Zero (p, inc, T);
315 Move (ptr, p + inc, sze, char); 329 Move (ptr, p + inc, sze, T);
316 Safefree (ptr); 330 Safefree (ptr);
317 331
318 return p; 332 ptr = p;
319} 333}
320 334
321static char * 335template<typename T>
336ecb_cold static void
322append (char *ptr, int sze, int inc) 337append (T *&ptr, int sze, int inc)
323{ 338{
324 Renew (ptr, sze + inc, char); 339 Renew (ptr, sze + inc, T);
325 Zero (ptr + sze, inc, char); 340 Zero (ptr + sze, inc, T);
341}
326 342
343static void
344need_facenum (struct mapgrid *self, faceid face)
345{
346 if (ecb_expect_true (self->faces > face))
327 return ptr; 347 return;
328}
329 348
330#define Append(type,ptr,sze,inc) (ptr) = (type *)append ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type)) 349 size_t newsize = minpot (face + 1);
331#define Prepend(type,ptr,sze,inc) (ptr) = (type *)prepend ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type)) 350 append (self->face2tile, self->faces, newsize - self->faces);
351 self->faces = newsize;
352}
353
354static void
355need_texid (struct mapgrid *self, int texid)
356{
357 if (ecb_expect_true (self->texs > texid))
358 return;
359
360 size_t newsize = minpot (texid + 1);
361 append (self->tex, self->texs, newsize - self->texs);
362 self->texs = newsize;
363}
332 364
333static maprow * 365static maprow *
334map_get_row (mapgrid *self, int y) 366map_get_row (mapgrid *self, int y)
335{ 367{
336 if (0 > y) 368 if (0 > y)
337 { 369 {
338 int extend = - y + MAP_EXTEND_Y; 370 int extend = - y + MAP_EXTEND_Y;
339 Prepend (maprow, self->row, self->rows, extend); 371 prepend (self->row, self->rows, extend);
340 372
341 self->rows += extend; 373 self->rows += extend;
342 self->y += extend; 374 self->y += extend;
343 y += extend; 375 y += extend;
344 } 376 }
345 else if (y >= self->rows) 377 else if (y >= self->rows)
346 { 378 {
347 int extend = y - self->rows + MAP_EXTEND_Y; 379 int extend = y - self->rows + MAP_EXTEND_Y;
348 Append (maprow, self->row, self->rows, extend); 380 append (self->row, self->rows, extend);
349 self->rows += extend; 381 self->rows += extend;
350 } 382 }
351 383
352 return self->row + y; 384 return self->row + y;
353} 385}
363 } 395 }
364 396
365 if (row->c0 > x) 397 if (row->c0 > x)
366 { 398 {
367 int extend = row->c0 - x + MAP_EXTEND_X; 399 int extend = row->c0 - x + MAP_EXTEND_X;
368 Prepend (mapcell, row->col, row->c1 - row->c0, extend); 400 prepend (row->col, row->c1 - row->c0, extend);
369 row->c0 -= extend; 401 row->c0 -= extend;
370 } 402 }
371 else if (x >= row->c1) 403 else if (x >= row->c1)
372 { 404 {
373 int extend = x - row->c1 + MAP_EXTEND_X; 405 int extend = x - row->c1 + MAP_EXTEND_X;
374 Append (mapcell, row->col, row->c1 - row->c0, extend); 406 append (row->col, row->c1 - row->c0, extend);
375 row->c1 += extend; 407 row->c1 += extend;
376 } 408 }
377 409
378 return row->col + (x - row->c0); 410 return row->col + (x - row->c0);
379} 411}
382map_get_cell (mapgrid *self, int x, int y) 414map_get_cell (mapgrid *self, int x, int y)
383{ 415{
384 return row_get_cell (map_get_row (self, y), x); 416 return row_get_cell (map_get_row (self, y), x);
385} 417}
386 418
387void mapgrid::clear_cells () 419static void
420map_clear (mapgrid *self)
388{ 421{
389 int r; 422 int r;
390 423
391 for (r = 0; r < rows; r++) 424 for (r = 0; r < self->rows; r++)
392 Safefree (row[r].col); 425 Safefree (self->row[r].col);
393 426
394 Safefree (row); 427 Safefree (self->row);
395 428
396 x = 0; 429 self->x = 0;
397 y = 0; 430 self->y = 0;
398 ox = 0; 431 self->ox = 0;
399 oy = 0; 432 self->oy = 0;
400 row = 0; 433 self->row = 0;
401 rows = 0; 434 self->rows = 0;
402} 435}
403 436
404#define CELL_CLEAR(cell) \ 437#define CELL_CLEAR(cell) \
405 do { \ 438 do { \
406 if ((cell)->player) \ 439 if ((cell)->player) \
448 { 481 {
449 return tile == o.tile && x == o.x && y == o.y && level == o.level; 482 return tile == o.tile && x == o.x && y == o.y && level == o.level;
450 } 483 }
451}; 484};
452 485
453typedef ska::flat_hash_map<smooth_key, IV> smooth_hash; 486typedef ska::flat_hash_map<smooth_key, IV, std::hash<smooth_key>, std::equal_to<smooth_key>, slice_allocator<smooth_key>> smooth_hash;
454 487
455namespace std { 488namespace std {
456 template <> 489 template <>
457 struct hash<smooth_key> 490 struct hash<smooth_key>
458 { 491 {
496 ev.code = 1; 529 ev.code = 1;
497 ev.data1 = (void *)(long)channel; 530 ev.data1 = (void *)(long)channel;
498 ev.data2 = 0; 531 ev.data2 = 0;
499 532
500 SDL_PushEvent ((SDL_Event *)&ev); 533 SDL_PushEvent ((SDL_Event *)&ev);
501}
502
503// approximately divide by 255
504static unsigned int
505div255 (unsigned int n)
506{
507 return (n + (n >> 8)) >> 8;
508}
509
510static unsigned int
511minpot (unsigned int n)
512{
513 if (!n)
514 return 0;
515
516 --n;
517
518 n |= n >> 1;
519 n |= n >> 2;
520 n |= n >> 4;
521 n |= n >> 8;
522 n |= n >> 16;
523
524 return n + 1;
525}
526
527static unsigned int
528popcount (unsigned int n)
529{
530 n -= (n >> 1) & 0x55555555U;
531 n = ((n >> 2) & 0x33333333U) + (n & 0x33333333U);
532 n = ((n >> 4) + n) & 0x0f0f0f0fU;
533 n *= 0x01010101U;
534
535 return n >> 24;
536} 534}
537 535
538/* SDL should provide this, really. */ 536/* SDL should provide this, really. */
539#define SDLK_MODIFIER_MIN 300 537#define SDLK_MODIFIER_MIN 300
540#define SDLK_MODIFIER_MAX 314 538#define SDLK_MODIFIER_MAX 314
871 869
872NV ceil (NV x) 870NV ceil (NV x)
873 871
874IV minpot (UV n) 872IV minpot (UV n)
875 873
874UV ld32 (UV n)
875 CODE:
876 RETVAL = ecb_ld32 (n);
877 OUTPUT:
878 RETVAL
879
876IV popcount (UV n) 880IV popcount (UV n)
881 CODE:
882 RETVAL = ecb_popcount32 (n);
883 OUTPUT:
884 RETVAL
877 885
878NV distance (NV dx, NV dy) 886NV distance (NV dx, NV dy)
879 CODE: 887 CODE:
880 RETVAL = pow (dx * dx + dy * dy, 0.5); 888 RETVAL = pow (dx * dx + dy * dy, 0.5);
881 OUTPUT: 889 OUTPUT:
1886PROTOTYPES: DISABLE 1894PROTOTYPES: DISABLE
1887 1895
1888DC::Map 1896DC::Map
1889new (SV *klass) 1897new (SV *klass)
1890 CODE: 1898 CODE:
1891 RETVAL = new mapgrid; 1899 New (0, RETVAL, 1, mapgrid);
1892 RETVAL->x = 0; 1900 RETVAL->x = 0;
1893 RETVAL->y = 0; 1901 RETVAL->y = 0;
1894 RETVAL->w = 0; 1902 RETVAL->w = 0;
1895 RETVAL->h = 0; 1903 RETVAL->h = 0;
1896 RETVAL->ox = 0; 1904 RETVAL->ox = 0;
1897 RETVAL->oy = 0; 1905 RETVAL->oy = 0;
1906 RETVAL->faces = 8192; Newz (0, RETVAL->face2tile, RETVAL->faces, tileid);
1907 RETVAL->texs = 8192; Newz (0, RETVAL->tex , RETVAL->texs , maptex);
1898 RETVAL->rows = 0; 1908 RETVAL->rows = 0;
1899 RETVAL->row = 0; 1909 RETVAL->row = 0;
1900 OUTPUT: 1910 OUTPUT:
1901 RETVAL 1911 RETVAL
1902 1912
1903void 1913void
1904DESTROY (DC::Map self) 1914DESTROY (DC::Map self)
1905 CODE: 1915 CODE:
1906{ 1916{
1917 map_clear (self);
1918 Safefree (self->face2tile);
1919 Safefree (self->tex);
1907 delete self; 1920 Safefree (self);
1908} 1921}
1909 1922
1910void 1923void
1911resize (DC::Map self, int map_width, int map_height) 1924resize (DC::Map self, int map_width, int map_height)
1912 CODE: 1925 CODE:
1914 self->h = map_height; 1927 self->h = map_height;
1915 1928
1916void 1929void
1917clear (DC::Map self) 1930clear (DC::Map self)
1918 CODE: 1931 CODE:
1919 self->clear_cells (); 1932 map_clear (self);
1920 1933
1921void 1934void
1922set_tileid (DC::Map self, int face, int tile) 1935set_tileid (DC::Map self, int face, int tile)
1923 CODE: 1936 CODE:
1924{ 1937{
1925 if (self->tile.size () <= face) self->tile.resize (face + 1); 1938 need_facenum (self, face); self->face2tile [face] = tile;
1926 self->tile[face] = tile; 1939 need_texid (self, tile);
1927 if (self->tex.size () <= tile) self->tex .resize (tile + 1);
1928} 1940}
1929 1941
1930void 1942void
1931set_smooth (DC::Map self, int face, int smooth, int level) 1943set_smooth (DC::Map self, int face, int smooth, int level)
1932 CODE: 1944 CODE:
1933{ 1945{
1946 tileid texid;
1947 maptex *tex;
1948
1934 if (face < 0 || face >= self->tile.size ()) 1949 if (face < 0 || face >= self->faces)
1935 return; 1950 return;
1936 1951
1937 if (smooth < 0 || smooth >= self->tile.size ()) 1952 if (smooth < 0 || smooth >= self->faces)
1938 return; 1953 return;
1939 1954
1940 tileid texid = self->tile[face]; 1955 texid = self->face2tile [face];
1941 1956
1942 if (!texid) 1957 if (!texid)
1943 return; 1958 return;
1944 1959
1945 maptex &tex = self->tex[texid]; 1960 tex = self->tex + texid;
1946 tex.smoothtile = self->tile[smooth]; 1961 tex->smoothtile = self->face2tile [smooth];
1947 tex.smoothlevel = level; 1962 tex->smoothlevel = level;
1948} 1963}
1949 1964
1950void 1965void
1951set_texture (DC::Map self, int texid, int name, int w, int h, float s, float t, int r, int g, int b, int a) 1966set_texture (DC::Map self, int texid, int name, int w, int h, float s, float t, int r, int g, int b, int a)
1952 CODE: 1967 CODE:
1953{ 1968{
1954 if (self->tex.size () < texid) self->tex.resize (texid + 1); 1969 need_texid (self, texid);
1955 1970
1956 { 1971 {
1957 maptex &tex = self->tex[texid]; 1972 maptex *tex = self->tex + texid;
1958 1973
1959 tex.name = name; 1974 tex->name = name;
1960 tex.w = w; 1975 tex->w = w;
1961 tex.h = h; 1976 tex->h = h;
1962 tex.s = s; 1977 tex->s = s;
1963 tex.t = t; 1978 tex->t = t;
1964 tex.r = r; 1979 tex->r = r;
1965 tex.g = g; 1980 tex->g = g;
1966 tex.b = b; 1981 tex->b = b;
1967 tex.a = a; 1982 tex->a = a;
1968 } 1983 }
1969 1984
1970 // somewhat hackish, but for textures that require it, it really 1985 // somewhat hackish, but for textures that require it, it really
1971 // improves the look, and most others don't suffer. 1986 // improves the look, and most others don't suffer.
1972 glBindTexture (GL_TEXTURE_2D, name); 1987 glBindTexture (GL_TEXTURE_2D, name);
1978} 1993}
1979 1994
1980void 1995void
1981expire_textures (DC::Map self, int texid, int count) 1996expire_textures (DC::Map self, int texid, int count)
1982 PPCODE: 1997 PPCODE:
1983 for (; texid < self->tex.size () && count; ++texid, --count) 1998 for (; texid < self->texs && count; ++texid, --count)
1984 { 1999 {
1985 maptex &tex = self->tex[texid]; 2000 maptex *tex = self->tex + texid;
1986 2001
1987 if (tex.name) 2002 if (tex->name)
1988 { 2003 {
1989 if (tex.unused) 2004 if (tex->unused)
1990 { 2005 {
1991 tex.name = 0; 2006 tex->name = 0;
1992 tex.unused = 0; 2007 tex->unused = 0;
1993 XPUSHs (sv_2mortal (newSViv (texid))); 2008 XPUSHs (sv_2mortal (newSViv (texid)));
1994 } 2009 }
1995 else 2010 else
1996 tex.unused = 1; 2011 tex->unused = 1;
1997 } 2012 }
1998 } 2013 }
1999 2014
2000int 2015int
2001ox (DC::Map self) 2016ox (DC::Map self)
2035 self->ox += dx; self->x += dx; 2050 self->ox += dx; self->x += dx;
2036 self->oy += dy; self->y += dy; 2051 self->oy += dy; self->y += dy;
2037 2052
2038 while (self->y < 0) 2053 while (self->y < 0)
2039 { 2054 {
2040 Prepend (maprow, self->row, self->rows, MAP_EXTEND_Y); 2055 prepend (self->row, self->rows, MAP_EXTEND_Y);
2041 2056
2042 self->rows += MAP_EXTEND_Y; 2057 self->rows += MAP_EXTEND_Y;
2043 self->y += MAP_EXTEND_Y; 2058 self->y += MAP_EXTEND_Y;
2044 } 2059 }
2045} 2060}
2112 } 2127 }
2113 2128
2114 for (z = 0; z <= 2; ++z) 2129 for (z = 0; z <= 2; ++z)
2115 if (flags & (4 >> z)) 2130 if (flags & (4 >> z))
2116 { 2131 {
2117 faceid face = (data[0] << 8) + data[1]; data += 2; 2132 faceid face = (data [0] << 8) + data [1]; data += 2;
2118 if (self->tile.size () <= face) self->tile.resize (face + 1); 2133 need_facenum (self, face);
2119 cell->tile[z] = self->tile[face]; 2134 cell->tile [z] = self->face2tile [face];
2120 2135
2121 if (cell->tile[z]) 2136 if (cell->tile [z])
2122 { 2137 {
2123 maptex &tex = self->tex[cell->tile[z]]; 2138 maptex *tex = self->tex + cell->tile [z];
2124 tex.unused = 0; 2139 tex->unused = 0;
2125 if (!tex.name) 2140 if (!tex->name)
2126 av_push (missing, newSViv (cell->tile [z])); 2141 av_push (missing, newSViv (cell->tile [z]));
2127 2142
2128 if (tex.smoothtile) 2143 if (tex->smoothtile)
2129 { 2144 {
2130 maptex &smooth = self->tex[tex.smoothtile]; 2145 maptex *smooth = self->tex + tex->smoothtile;
2131 smooth.unused = 0; 2146 smooth->unused = 0;
2132 if (!smooth.name) 2147 if (!smooth->name)
2133 av_push (missing, newSViv (tex.smoothtile)); 2148 av_push (missing, newSViv (tex->smoothtile));
2134 } 2149 }
2135 } 2150 }
2136 } 2151 }
2137 } 2152 }
2138 else 2153 else
2289 } 2304 }
2290 2305
2291 px = (x + 1) * Th - tex.w; 2306 px = (x + 1) * Th - tex.w;
2292 py = (y + 1) * Tw - tex.h; 2307 py = (y + 1) * Tw - tex.h;
2293 2308
2294 if (expect_false (cell->player == player) && expect_false (z == 2)) 2309 if (ecb_expect_false (cell->player == player) && ecb_expect_false (z == 2))
2295 { 2310 {
2296 pl_x = px; 2311 pl_x = px;
2297 pl_y = py; 2312 pl_y = py;
2298 pl_tex = tex; 2313 pl_tex = tex;
2299 continue; 2314 continue;
2342 skey.x = x ; skey.y = y ; smooth_or_bits (smooth, skey, 0x0400); 2357 skey.x = x ; skey.y = y ; smooth_or_bits (smooth, skey, 0x0400);
2343 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, skey, 0x0800); 2358 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, skey, 0x0800);
2344 } 2359 }
2345 } 2360 }
2346 2361
2347 if (expect_false (z == 2) && expect_false (cell->flags)) 2362 if (ecb_expect_false (z == 2) && ecb_expect_false (cell->flags))
2348 { 2363 {
2349 // overlays such as the speech bubble, probably more to come 2364 // overlays such as the speech bubble, probably more to come
2350 if (cell->flags & 1) 2365 if (cell->flags & 1)
2351 { 2366 {
2352 rc_key_t key_ov = key; 2367 rc_key_t key_ov = key;
2471 mapcell *cell = row->col + (x + mx - row->c0); 2486 mapcell *cell = row->col + (x + mx - row->c0);
2472 2487
2473 int px = x * Tw; 2488 int px = x * Tw;
2474 int py = y * Th; 2489 int py = y * Th;
2475 2490
2476 if (expect_false (cell->player == player)) 2491 if (ecb_expect_false (cell->player == player))
2477 { 2492 {
2478 px += sdx; 2493 px += sdx;
2479 py += sdy; 2494 py += sdy;
2480 } 2495 }
2481 2496
2787 2802
2788 for (z = 0; z <= 2; z++) 2803 for (z = 0; z <= 2; z++)
2789 { 2804 {
2790 tileid t = tile [z]; 2805 tileid t = tile [z];
2791 2806
2792 if (t >= self->tex.size () || (t && !self->tex[t].name)) 2807 if (t >= self->texs || (t && !self->tex [t].name))
2793 { 2808 {
2794 PUSHs (sv_2mortal (newSViv (t))); 2809 PUSHs (sv_2mortal (newSViv (t)));
2795 if (self->tex.size () <= t) self->tex.resize (t + 1); 2810 need_texid (self, t);
2796 } 2811 }
2797 2812
2798 cell->tile[z] = t; 2813 cell->tile [z] = t;
2799 } 2814 }
2800 } 2815 }
2801 } 2816 }
2802 } 2817 }
2803 } 2818 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines