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.322 by root, Sun Nov 18 01:43:12 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
199 } 193 }
200 194
201 return 0; 195 return 0;
202} 196}
203 197
204typedef struct 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} *DC__Layout; 204};
205
206typedef cf_layout *DC__Layout;
211 207
212static DC__Font default_font; 208static DC__Font default_font;
213static PangoContext *opengl_context; 209static PangoContext *opengl_context;
214static PangoFontMap *opengl_fontmap; 210static PangoFontMap *opengl_fontmap;
215 211
253 249
254 *w = rect.width; 250 *w = rect.width;
255 *h = rect.height; 251 *h = rect.height;
256} 252}
257 253
254/////////////////////////////////////////////////////////////////////////////
255
258typedef uint16_t tileid; 256typedef uint16_t tileid;
259typedef uint16_t faceid; 257typedef uint16_t faceid;
260 258
261typedef struct { 259struct maptex
260{
262 GLuint name; 261 GLuint name;
263 int w, h; 262 int w, h;
264 float s, t; 263 float s, t;
265 uint8_t r, g, b, a; 264 uint8_t r, g, b, a;
266 tileid smoothtile; 265 tileid smoothtile;
267 uint8_t smoothlevel; 266 uint8_t smoothlevel;
268 uint8_t unused; /* set to zero on use */ 267 uint8_t unused; /* set to zero on use */
269} maptex; 268};
270 269
271typedef struct { 270struct mapcell
271{
272 uint32_t player; 272 uint32_t player;
273 tileid tile[3]; 273 tileid tile[3];
274 uint16_t darkness; 274 uint16_t darkness;
275 uint8_t stat_width, stat_hp, flags, smoothmax; 275 uint8_t stat_width, stat_hp, flags, smoothmax;
276} mapcell; 276};
277 277
278typedef struct { 278struct maprow
279{
279 int32_t c0, c1; 280 int32_t c0, c1;
280 mapcell *col; 281 mapcell *col;
281} maprow; 282};
282 283
283typedef struct map { 284struct mapgrid {
284 int x, y, w, h; 285 int x, y, w, h;
285 int ox, oy; /* offset to virtual global coordinate system */ 286 int ox, oy; /* offset to virtual global coordinate system */
286 int faces; tileid *face2tile; // [faceid] 287 int faces; tileid *face2tile; // [faceid]
287 int texs; maptex *tex; // [tileid] 288 int texs; maptex *tex; // [tileid]
288 289
289 int32_t rows; 290 int32_t rows;
290 maprow *row; 291 maprow *row;
291} *DC__Map; 292};
292 293
293static char * 294typedef mapgrid *DC__Map;
295
296template<typename T>
297static void
294prepend (char *ptr, int sze, int inc) 298prepend (T *&ptr, int sze, int inc)
295{ 299{
296 char *p; 300 T *p;
297 301
298 New (0, p, sze + inc, char); 302 Newx (p, inc + sze, T);
299 Zero (p, inc, char); 303 Zero (p, inc, T);
300 Move (ptr, p + inc, sze, char); 304 Move (ptr, p + inc, sze, T);
301 Safefree (ptr); 305 Safefree (ptr);
302 306
303 return p; 307 ptr = p;
304} 308}
305 309
306static char * 310template<typename T>
307append (char *ptr, int sze, int inc)
308{
309 Renew (ptr, sze + inc, char);
310 Zero (ptr + sze, inc, char);
311
312 return ptr;
313}
314
315#define Append(type,ptr,sze,inc) (ptr) = (type *)append ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type))
316#define Prepend(type,ptr,sze,inc) (ptr) = (type *)prepend ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type))
317
318static void 311static void
312append (T *&ptr, int sze, int inc)
313{
314 Renew (ptr, sze + inc, T);
315 Zero (ptr + sze, inc, T);
316}
317
318static void
319need_facenum (struct map *self, faceid face) 319need_facenum (struct mapgrid *self, faceid face)
320{ 320{
321 while (self->faces <= face) 321 while (self->faces <= face)
322 { 322 {
323 Append (tileid, self->face2tile, self->faces, self->faces); 323 append (self->face2tile, self->faces, self->faces);
324 self->faces *= 2; 324 self->faces *= 2;
325 } 325 }
326} 326}
327 327
328static void 328static void
329need_texid (struct map *self, int texid) 329need_texid (struct mapgrid *self, int texid)
330{ 330{
331 while (self->texs <= texid) 331 while (self->texs <= texid)
332 { 332 {
333 Append (maptex, self->tex, self->texs, self->texs); 333 append (self->tex, self->texs, self->texs);
334 self->texs *= 2; 334 self->texs *= 2;
335 } 335 }
336} 336}
337 337
338static maprow * 338static maprow *
339map_get_row (DC__Map self, int y) 339map_get_row (mapgrid *self, int y)
340{ 340{
341 if (0 > y) 341 if (0 > y)
342 { 342 {
343 int extend = - y + MAP_EXTEND_Y; 343 int extend = - y + MAP_EXTEND_Y;
344 Prepend (maprow, self->row, self->rows, extend); 344 prepend (self->row, self->rows, extend);
345 345
346 self->rows += extend; 346 self->rows += extend;
347 self->y += extend; 347 self->y += extend;
348 y += extend; 348 y += extend;
349 } 349 }
350 else if (y >= self->rows) 350 else if (y >= self->rows)
351 { 351 {
352 int extend = y - self->rows + MAP_EXTEND_Y; 352 int extend = y - self->rows + MAP_EXTEND_Y;
353 Append (maprow, self->row, self->rows, extend); 353 append (self->row, self->rows, extend);
354 self->rows += extend; 354 self->rows += extend;
355 } 355 }
356 356
357 return self->row + y; 357 return self->row + y;
358} 358}
368 } 368 }
369 369
370 if (row->c0 > x) 370 if (row->c0 > x)
371 { 371 {
372 int extend = row->c0 - x + MAP_EXTEND_X; 372 int extend = row->c0 - x + MAP_EXTEND_X;
373 Prepend (mapcell, row->col, row->c1 - row->c0, extend); 373 prepend (row->col, row->c1 - row->c0, extend);
374 row->c0 -= extend; 374 row->c0 -= extend;
375 } 375 }
376 else if (x >= row->c1) 376 else if (x >= row->c1)
377 { 377 {
378 int extend = x - row->c1 + MAP_EXTEND_X; 378 int extend = x - row->c1 + MAP_EXTEND_X;
379 Append (mapcell, row->col, row->c1 - row->c0, extend); 379 append (row->col, row->c1 - row->c0, extend);
380 row->c1 += extend; 380 row->c1 += extend;
381 } 381 }
382 382
383 return row->col + (x - row->c0); 383 return row->col + (x - row->c0);
384} 384}
385 385
386static mapcell * 386static mapcell *
387map_get_cell (DC__Map self, int x, int y) 387map_get_cell (mapgrid *self, int x, int y)
388{ 388{
389 return row_get_cell (map_get_row (self, y), x); 389 return row_get_cell (map_get_row (self, y), x);
390} 390}
391 391
392static void 392static void
393map_clear (DC__Map self) 393map_clear (mapgrid *self)
394{ 394{
395 int r; 395 int r;
396 396
397 for (r = 0; r < self->rows; r++) 397 for (r = 0; r < self->rows; r++)
398 Safefree (self->row[r].col); 398 Safefree (self->row[r].col);
416 (cell)->flags = 0; \ 416 (cell)->flags = 0; \
417 (cell)->player = 0; \ 417 (cell)->player = 0; \
418 } while (0) 418 } while (0)
419 419
420static void 420static void
421map_blank (DC__Map self, int x0, int y0, int w, int h) 421map_blank (mapgrid *self, int x0, int y0, int w, int h)
422{ 422{
423 int x, y; 423 int x, y;
424 maprow *row; 424 maprow *row;
425 mapcell *cell; 425 mapcell *cell;
426 426
526 n |= n >> 4; 526 n |= n >> 4;
527 n |= n >> 8; 527 n |= n >> 8;
528 n |= n >> 16; 528 n |= n >> 16;
529 529
530 return n + 1; 530 return n + 1;
531}
532
533static unsigned int
534popcount (unsigned int n)
535{
536 n -= (n >> 1) & 0x55555555U;
537 n = ((n >> 2) & 0x33333333U) + (n & 0x33333333U);
538 n = ((n >> 4) + n) & 0x0f0f0f0fU;
539 n *= 0x01010101U;
540
541 return n >> 24;
542} 531}
543 532
544/* SDL should provide this, really. */ 533/* SDL should provide this, really. */
545#define SDLK_MODIFIER_MIN 300 534#define SDLK_MODIFIER_MIN 300
546#define SDLK_MODIFIER_MAX 314 535#define SDLK_MODIFIER_MAX 314
878NV ceil (NV x) 867NV ceil (NV x)
879 868
880IV minpot (UV n) 869IV minpot (UV n)
881 870
882IV popcount (UV n) 871IV popcount (UV n)
872 CODE:
873 RETVAL = ecb_popcount32 (n);
874 OUTPUT:
875 RETVAL
883 876
884NV distance (NV dx, NV dy) 877NV distance (NV dx, NV dy)
885 CODE: 878 CODE:
886 RETVAL = pow (dx * dx + dy * dy, 0.5); 879 RETVAL = pow (dx * dx + dy * dy, 0.5);
887 OUTPUT: 880 OUTPUT:
1361 tc_restore (); 1354 tc_restore ();
1362 1355
1363DC::Layout 1356DC::Layout
1364new (SV *klass) 1357new (SV *klass)
1365 CODE: 1358 CODE:
1366 New (0, RETVAL, 1, struct cf_layout); 1359 RETVAL = new cf_layout;
1367 1360
1368 RETVAL->pl = pango_layout_new (opengl_context); 1361 RETVAL->pl = pango_layout_new (opengl_context);
1369 RETVAL->r = 1.; 1362 RETVAL->r = 1.;
1370 RETVAL->g = 1.; 1363 RETVAL->g = 1.;
1371 RETVAL->b = 1.; 1364 RETVAL->b = 1.;
1372 RETVAL->a = 1.; 1365 RETVAL->a = 1.;
1373 RETVAL->base_height = MIN_FONT_HEIGHT; 1366 RETVAL->base_height = MIN_FONT_HEIGHT;
1374 RETVAL->font = 0; 1367 RETVAL->font = 0;
1375 RETVAL->rc = rc_alloc ();
1376 1368
1377 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR); 1369 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
1378 layout_update_font (RETVAL); 1370 layout_update_font (RETVAL);
1379 OUTPUT: 1371 OUTPUT:
1380 RETVAL 1372 RETVAL
1381 1373
1382void 1374void
1383DESTROY (DC::Layout self) 1375DESTROY (DC::Layout self)
1384 CODE: 1376 CODE:
1385 g_object_unref (self->pl); 1377 g_object_unref (self->pl);
1386 rc_free (self->rc);
1387 Safefree (self); 1378 delete self;
1388 1379
1389void 1380void
1390set_text (DC::Layout self, SV *text_) 1381set_text (DC::Layout self, SV *text_)
1391 CODE: 1382 CODE:
1392{ 1383{
1646} 1637}
1647 1638
1648void 1639void
1649render (DC::Layout self, float x, float y, int flags = 0) 1640render (DC::Layout self, float x, float y, int flags = 0)
1650 CODE: 1641 CODE:
1651 rc_clear (self->rc); 1642 self->rc.clear ();
1652 pango_opengl_render_layout_subpixel ( 1643 pango_opengl_render_layout_subpixel (
1653 self->pl, 1644 self->pl,
1654 self->rc, 1645 &self->rc,
1655 x * PANGO_SCALE, y * PANGO_SCALE, 1646 x * PANGO_SCALE, y * PANGO_SCALE,
1656 self->r, self->g, self->b, self->a, 1647 self->r, self->g, self->b, self->a,
1657 flags 1648 flags
1658 ); 1649 );
1659 // we assume that context_change actually clears/frees stuff 1650 // we assume that context_change actually clears/frees stuff
1670 gl_BlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 1661 gl_BlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
1671 GL_ONE , GL_ONE_MINUS_SRC_ALPHA); 1662 GL_ONE , GL_ONE_MINUS_SRC_ALPHA);
1672 glEnable (GL_ALPHA_TEST); 1663 glEnable (GL_ALPHA_TEST);
1673 glAlphaFunc (GL_GREATER, 7.f / 255.f); 1664 glAlphaFunc (GL_GREATER, 7.f / 255.f);
1674 1665
1675 rc_draw (self->rc); 1666 self->rc.draw ();
1676 1667
1677 glDisable (GL_ALPHA_TEST); 1668 glDisable (GL_ALPHA_TEST);
1678 glDisable (GL_BLEND); 1669 glDisable (GL_BLEND);
1679 glDisable (GL_TEXTURE_2D); 1670 glDisable (GL_TEXTURE_2D);
1680} 1671}
1894PROTOTYPES: DISABLE 1885PROTOTYPES: DISABLE
1895 1886
1896DC::Map 1887DC::Map
1897new (SV *klass) 1888new (SV *klass)
1898 CODE: 1889 CODE:
1899 New (0, RETVAL, 1, struct map); 1890 New (0, RETVAL, 1, mapgrid);
1900 RETVAL->x = 0; 1891 RETVAL->x = 0;
1901 RETVAL->y = 0; 1892 RETVAL->y = 0;
1902 RETVAL->w = 0; 1893 RETVAL->w = 0;
1903 RETVAL->h = 0; 1894 RETVAL->h = 0;
1904 RETVAL->ox = 0; 1895 RETVAL->ox = 0;
2050 self->ox += dx; self->x += dx; 2041 self->ox += dx; self->x += dx;
2051 self->oy += dy; self->y += dy; 2042 self->oy += dy; self->y += dy;
2052 2043
2053 while (self->y < 0) 2044 while (self->y < 0)
2054 { 2045 {
2055 Prepend (maprow, self->row, self->rows, MAP_EXTEND_Y); 2046 prepend (self->row, self->rows, MAP_EXTEND_Y);
2056 2047
2057 self->rows += MAP_EXTEND_Y; 2048 self->rows += MAP_EXTEND_Y;
2058 self->y += MAP_EXTEND_Y; 2049 self->y += MAP_EXTEND_Y;
2059 } 2050 }
2060} 2051}
2216draw (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)
2217 CODE: 2208 CODE:
2218{ 2209{
2219 int x, y, z; 2210 int x, y, z;
2220 2211
2221 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level
2222 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!
2223 smooth_key skey;
2224 int pl_x, pl_y; 2213 int pl_x, pl_y;
2225 maptex pl_tex; 2214 maptex pl_tex;
2226 rc_t *rc = rc_alloc (); 2215 rc_t rc;
2227 rc_t *rc_ov = rc_alloc (); 2216 rc_t rc_ov;
2228 rc_key_t key; 2217 rc_key_t key;
2229 rc_array_t *arr; 2218 rc_t::array_t *arr;
2230 2219
2231 pl_tex.name = 0; 2220 pl_tex.name = 0;
2232 2221
2233 // that's current max. sorry. 2222 // that's current max. sorry.
2234 if (sw > 255) sw = 255; 2223 if (sw > 255) sw = 255;
2235 if (sh > 255) sh = 255; 2224 if (sh > 255) sh = 255;
2236
2237 // clear key, in case of extra padding
2238 memset (&skey, 0, sizeof (skey));
2239 2225
2240 memset (&key, 0, sizeof (key)); 2226 memset (&key, 0, sizeof (key));
2241 key.r = 255; 2227 key.r = 255;
2242 key.g = 255; 2228 key.g = 255;
2243 key.b = 255; 2229 key.b = 255;
2249 my += self->y; 2235 my += self->y;
2250 2236
2251 // first pass: determine smooth_max 2237 // first pass: determine smooth_max
2252 // rather ugly, if you ask me 2238 // rather ugly, if you ask me
2253 // could also be stored inside mapcell and updated on change 2239 // could also be stored inside mapcell and updated on change
2254 memset (smooth_max, 0, sizeof (smooth_max)); 2240 memset (smooth_max, 0, sizeof (smooth_max[0]) * (sh + 1));
2255 2241
2256 for (y = 0; y < sh; y++) 2242 for (y = 0; y < sh; y++)
2257 if (0 <= y + my && y + my < self->rows) 2243 if (0 <= y + my && y + my < self->rows)
2258 { 2244 {
2259 maprow *row = self->row + (y + my); 2245 maprow *row = self->row + (y + my);
2274 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2260 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2275 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 2261 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
2276 2262
2277 for (z = 0; z <= 2; z++) 2263 for (z = 0; z <= 2; z++)
2278 { 2264 {
2265 std::bitset<256> smooth_level; // one bit for every possible smooth level
2266 smooth_key skey;
2279 smooth_hash smooth; 2267 smooth_hash smooth;
2280 memset (smooth_level, 0, sizeof (smooth_level));
2281 key.texname = -1; 2268 key.texname = -1;
2282 2269
2283 for (y = 0; y < sh; y++) 2270 for (y = 0; y < sh; y++)
2284 if (0 <= y + my && y + my < self->rows) 2271 if (0 <= y + my && y + my < self->rows)
2285 { 2272 {
2302 2289
2303 if (!tex.name) 2290 if (!tex.name)
2304 tex = self->tex [TEXID_NOFACE]; /* missing, replace by noface */ 2291 tex = self->tex [TEXID_NOFACE]; /* missing, replace by noface */
2305 2292
2306 key.texname = tex.name; 2293 key.texname = tex.name;
2307 arr = rc_array (rc, &key); 2294 arr = &rc.array (key);
2308 } 2295 }
2309 2296
2310 px = (x + 1) * Th - tex.w; 2297 px = (x + 1) * Th - tex.w;
2311 py = (y + 1) * Tw - tex.h; 2298 py = (y + 1) * Tw - tex.h;
2312 2299
2313 if (expect_false (cell->player == player) && expect_false (z == 2)) 2300 if (ecb_expect_false (cell->player == player) && ecb_expect_false (z == 2))
2314 { 2301 {
2315 pl_x = px; 2302 pl_x = px;
2316 pl_y = py; 2303 pl_y = py;
2317 pl_tex = tex; 2304 pl_tex = tex;
2318 continue; 2305 continue;
2319 } 2306 }
2320 2307
2321 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2308 arr->t2f_v3f (0 , 0 , px , py , 0);
2322 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0); 2309 arr->t2f_v3f (0 , tex.t, px , py + tex.h, 0);
2323 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);
2324 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0); 2311 arr->t2f_v3f (tex.s, 0 , px + tex.w, py , 0);
2325 2312
2326 // update smooth hash 2313 // update smooth hash
2327 if (tex.smoothtile) 2314 if (tex.smoothtile)
2328 { 2315 {
2329 skey.tile = tex.smoothtile; 2316 skey.tile = tex.smoothtile;
2330 skey.level = tex.smoothlevel; 2317 skey.level = tex.smoothlevel;
2331 2318
2332 smooth_level [tex.smoothlevel >> 5] |= ((uint32_t)1) << (tex.smoothlevel & 31); 2319 smooth_level[tex.smoothlevel] = 1;
2333 2320
2334 // 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
2335 // shifted +1|+1 so we always stay positive. 2322 // shifted +1|+1 so we always stay positive.
2336 2323
2337 // bits is ___n cccc CCCC bbbb 2324 // bits is ___n cccc CCCC bbbb
2361 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);
2362 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);
2363 } 2350 }
2364 } 2351 }
2365 2352
2366 if (expect_false (z == 2) && expect_false (cell->flags)) 2353 if (ecb_expect_false (z == 2) && ecb_expect_false (cell->flags))
2367 { 2354 {
2368 // overlays such as the speech bubble, probably more to come 2355 // overlays such as the speech bubble, probably more to come
2369 if (cell->flags & 1) 2356 if (cell->flags & 1)
2370 { 2357 {
2371 rc_key_t key_ov = key; 2358 rc_key_t key_ov = key;
2372 maptex tex = self->tex [TEXID_SPEECH]; 2359 maptex tex = self->tex[TEXID_SPEECH];
2373 rc_array_t *arr;
2374 int px = x * Tw + Tw * 2 / 32; 2360 int px = x * Tw + Tw * 2 / 32;
2375 int py = y * Th - Th * 6 / 32; 2361 int py = y * Th - Th * 6 / 32;
2376 2362
2377 key_ov.texname = tex.name; 2363 key_ov.texname = tex.name;
2378 arr = rc_array (rc_ov, &key_ov); 2364 rc_t::array_t &arr = rc_ov.array (key_ov);
2379 2365
2380 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2366 arr.t2f_v3f (0 , 0 , px , py , 0);
2381 rc_t2f_v3f (arr, 0 , tex.t, px , py + Th, 0); 2367 arr.t2f_v3f (0 , tex.t, px , py + Th, 0);
2382 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);
2383 rc_t2f_v3f (arr, tex.s, 0 , px + Tw, py , 0); 2369 arr.t2f_v3f (tex.s, 0 , px + Tw, py , 0);
2384 } 2370 }
2385 } 2371 }
2386 } 2372 }
2387 } 2373 }
2388 2374
2389 rc_draw (rc); 2375 rc.draw ();
2390 rc_clear (rc); 2376 rc.clear ();
2391 2377
2392 // go through all smoothlevels, lowest to highest, then draw. 2378 // go through all smoothlevels, lowest to highest, then draw.
2393 // this is basically counting sort 2379 // this is basically counting sort
2394 { 2380 {
2395 int w, b; 2381 int w, b;
2396 2382
2397 glEnable (GL_TEXTURE_2D); 2383 glEnable (GL_TEXTURE_2D);
2398 glBegin (GL_QUADS); 2384 glBegin (GL_QUADS);
2399 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)
2400 { 2388 {
2401 uint32_t smask = smooth_level [w]; 2389 smooth_key &skey = it->first;
2402 if (smask) 2390 IV bits = it->second;
2403 for (b = 0; b < 32; ++b) 2391
2404 if (smask & (((uint32_t)1) << b)) 2392 if (!(bits & 0x1000)
2393 && skey.level == level
2394 && level > smooth_max [skey.x][skey.y])
2405 { 2395 {
2406 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
2407 HE *he; 2404 if (tex.name)
2408
2409 for (auto &&it = smooth.begin (); it != smooth.end (); ++it)
2410 { 2405 {
2411 smooth_key &skey = it->first; 2406 // this time avoiding texture state changes
2412 IV bits = it->second; 2407 // save gobs of state changes.
2413 2408 if (key.texname != tex.name)
2414 if (!(bits & 0x1000)
2415 && skey.level == level
2416 && level > smooth_max [skey.x][skey.y])
2417 { 2409 {
2418 maptex tex = self->tex [skey.tile];
2419 int px = (((int)skey.x) - 1) * Tw;
2420 int py = (((int)skey.y) - 1) * Th;
2421 int border = bits & 15;
2422 int corner = (bits >> 8) & ~(bits >> 4) & 15;
2423 float dx = tex.s * .0625f; // 16 images/row
2424 float dy = tex.t * .5f ; // 2 images/column
2425
2426 if (tex.name)
2427 {
2428 // this time avoiding texture state changes
2429 // save gobs of state changes.
2430 if (key.texname != tex.name)
2431 {
2432 self->tex [skey.tile].unused = 0; 2410 self->tex [skey.tile].unused = 0;
2433 2411
2434 glEnd (); 2412 glEnd ();
2435 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name); 2413 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name);
2436 glBegin (GL_QUADS); 2414 glBegin (GL_QUADS);
2437 } 2415 }
2438 2416
2439 if (border) 2417 if (border)
2440 { 2418 {
2441 float ox = border * dx; 2419 float ox = border * dx;
2442 2420
2443 glTexCoord2f (ox , 0.f ); glVertex2i (px , py ); 2421 glTexCoord2f (ox , 0.f ); glVertex2i (px , py );
2444 glTexCoord2f (ox , dy ); glVertex2i (px , py + Th); 2422 glTexCoord2f (ox , dy ); glVertex2i (px , py + Th);
2445 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py + Th); 2423 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py + Th);
2446 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + Tw, py ); 2424 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + Tw, py );
2447 } 2425 }
2448 2426
2449 if (corner) 2427 if (corner)
2450 { 2428 {
2451 float ox = corner * dx; 2429 float ox = corner * dx;
2452 2430
2453 glTexCoord2f (ox , dy ); glVertex2i (px , py ); 2431 glTexCoord2f (ox , dy ); glVertex2i (px , py );
2454 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + Th); 2432 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + Th);
2455 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + Tw, py + Th); 2433 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + Tw, py + Th);
2456 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py ); 2434 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py );
2457 }
2458 }
2459 } 2435 }
2460 } 2436 }
2461 } 2437 }
2462 } 2438 }
2463 2439
2464 glEnd (); 2440 glEnd ();
2465 glDisable (GL_TEXTURE_2D); 2441 glDisable (GL_TEXTURE_2D);
2466 key.texname = -1; 2442 key.texname = -1;
2467 } 2443 }
2472 maptex tex = pl_tex; 2448 maptex tex = pl_tex;
2473 int px = pl_x + sdx; 2449 int px = pl_x + sdx;
2474 int py = pl_y + sdy; 2450 int py = pl_y + sdy;
2475 2451
2476 key.texname = tex.name; 2452 key.texname = tex.name;
2477 arr = rc_array (rc, &key); 2453 rc_t::array_t &arr = rc.array (key);
2478 2454
2479 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2455 arr.t2f_v3f (0 , 0 , px , py , 0);
2480 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0); 2456 arr.t2f_v3f (0 , tex.t, px , py + tex.h, 0);
2481 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);
2482 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0); 2458 arr.t2f_v3f (tex.s, 0 , px + tex.w, py , 0);
2483 2459
2484 rc_draw (rc); 2460 rc.draw ();
2485 } 2461 }
2486 2462
2487 rc_draw (rc_ov); 2463 rc_ov.draw ();
2488 rc_clear (rc_ov); 2464 rc_ov.clear ();
2489 2465
2490 glDisable (GL_BLEND); 2466 glDisable (GL_BLEND);
2491 rc_free (rc);
2492 rc_free (rc_ov);
2493 2467
2494 // top layer: overlays such as the health bar 2468 // top layer: overlays such as the health bar
2495 for (y = 0; y < sh; y++) 2469 for (y = 0; y < sh; y++)
2496 if (0 <= y + my && y + my < self->rows) 2470 if (0 <= y + my && y + my < self->rows)
2497 { 2471 {
2503 mapcell *cell = row->col + (x + mx - row->c0); 2477 mapcell *cell = row->col + (x + mx - row->c0);
2504 2478
2505 int px = x * Tw; 2479 int px = x * Tw;
2506 int py = y * Th; 2480 int py = y * Th;
2507 2481
2508 if (expect_false (cell->player == player)) 2482 if (ecb_expect_false (cell->player == player))
2509 { 2483 {
2510 px += sdx; 2484 px += sdx;
2511 py += sdy; 2485 py += sdy;
2512 } 2486 }
2513 2487

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines