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.320 by root, Sun Nov 18 01:00:10 2018 UTC vs.
Revision 1.322 by root, Sun Nov 18 01:43:12 2018 UTC

15 15
16#include "EXTERN.h" 16#include "EXTERN.h"
17#include "perl.h" 17#include "perl.h"
18#include "XSUB.h" 18#include "XSUB.h"
19 19
20#include "flat_hash_map.hpp"
21
20#ifdef _WIN32 22#ifdef _WIN32
21# undef pipe 23# undef pipe
22// microsoft vs. C 24// microsoft vs. C
23# define sqrtf(x) sqrt(x) 25# define sqrtf(x) sqrt(x)
24# define atan2f(x,y) atan2(x,y) 26# define atan2f(x,y) atan2(x,y)
25# define M_PI 3.14159265f 27# define M_PI 3.14159265f
26#endif 28#endif
27 29
28#include <assert.h> 30#include <cassert>
29#include <math.h> 31#include <cmath>
30#include <string.h> 32#include <cstring>
31#include <stdio.h> 33#include <cstdio>
32#include <stdlib.h> 34#include <cstdlib>
35
36#include <utility>
33 37
34#define USE_RWOPS 1 // for SDL_mixer:LoadMUS_RW 38#define USE_RWOPS 1 // for SDL_mixer:LoadMUS_RW
35 39
36#include <SDL.h> 40#include <SDL.h>
37#include <SDL_thread.h> 41#include <SDL_thread.h>
439 CELL_CLEAR (cell); 443 CELL_CLEAR (cell);
440 } 444 }
441 } 445 }
442} 446}
443 447
444typedef struct { 448struct smooth_key
449{
445 tileid tile; 450 tileid tile;
446 uint8_t x, y, level; 451 uint8_t x, y, level;
447} smooth_key; 452
453 bool operator == (const smooth_key &o) const
454 {
455 return tile == o.tile && x == o.x && y == o.y && level == o.level;
456 }
457};
458
459typedef ska::flat_hash_map<smooth_key, IV> smooth_hash;
460
461namespace std {
462 template <>
463 struct hash<smooth_key>
464 {
465 size_t operator () (const smooth_key &v) const
466 {
467 return v.tile + (v.x << 8) + (v.y << 16) + (v.level << 24);
468 }
469 };
470}
448 471
449static void 472static void
450smooth_or_bits (HV *hv, smooth_key *key, IV bits) 473smooth_or_bits (smooth_hash &h, smooth_key &key, IV bits)
451{ 474{
452 SV **sv = hv_fetch (hv, (char *)key, sizeof (*key), 1); 475 auto &&it = h.find (key);
453 476
454 if (SvIOK (*sv)) 477 if (it == h.end ())
455 SvIV_set (*sv, SvIVX (*sv) | bits); 478 h.insert (std::make_pair (key, bits));
456 else 479 else
457 sv_setiv (*sv, bits); 480 it->second |= bits;
458} 481}
459 482
460static void 483static void
461music_finished (void) 484music_finished (void)
462{ 485{
481 ev.data2 = 0; 504 ev.data2 = 0;
482 505
483 SDL_PushEvent ((SDL_Event *)&ev); 506 SDL_PushEvent ((SDL_Event *)&ev);
484} 507}
485 508
509// approximately divide by 255
486static unsigned int 510static unsigned int
487div255 (unsigned int n) 511div255 (unsigned int n)
488{ 512{
489 return (n + (n >> 8)) >> 8; 513 return (n + (n >> 8)) >> 8;
490} 514}
1083 OUTPUT: 1107 OUTPUT:
1084 RETVAL 1108 RETVAL
1085 1109
1086int 1110int
1087Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 4096) 1111Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 4096)
1088 POSTCALL: 1112 POSTCALL:
1089 Mix_HookMusicFinished (music_finished); 1113 Mix_HookMusicFinished (music_finished);
1090 Mix_ChannelFinished (channel_finished); 1114 Mix_ChannelFinished (channel_finished);
1091 1115
1092void 1116void
1093Mix_QuerySpec () 1117Mix_QuerySpec ()
1917 1941
1918void 1942void
1919set_smooth (DC::Map self, int face, int smooth, int level) 1943set_smooth (DC::Map self, int face, int smooth, int level)
1920 CODE: 1944 CODE:
1921{ 1945{
1922 tileid texid; 1946 tileid texid;
1923 maptex *tex; 1947 maptex *tex;
1924 1948
1925 if (face < 0 || face >= self->faces) 1949 if (face < 0 || face >= self->faces)
1926 return; 1950 return;
1927 1951
1928 if (smooth < 0 || smooth >= self->faces) 1952 if (smooth < 0 || smooth >= self->faces)
1929 return; 1953 return;
1930 1954
1931 texid = self->face2tile [face]; 1955 texid = self->face2tile [face];
1932 1956
1933 if (!texid) 1957 if (!texid)
1934 return; 1958 return;
1935 1959
1936 tex = self->tex + texid; 1960 tex = self->tex + texid;
1969} 1993}
1970 1994
1971void 1995void
1972expire_textures (DC::Map self, int texid, int count) 1996expire_textures (DC::Map self, int texid, int count)
1973 PPCODE: 1997 PPCODE:
1974 for (; texid < self->texs && count; ++texid, --count) 1998 for (; texid < self->texs && count; ++texid, --count)
1975 { 1999 {
1976 maptex *tex = self->tex + texid; 2000 maptex *tex = self->tex + texid;
1977 2001
1978 if (tex->name) 2002 if (tex->name)
1979 { 2003 {
2181 | (b << 16) 2205 | (b << 16)
2182 | (a << 24); 2206 | (a << 24);
2183 } 2207 }
2184 } 2208 }
2185 2209
2186 RETVAL = map_sv; 2210 RETVAL = map_sv;
2187} 2211}
2188 OUTPUT: 2212 OUTPUT:
2189 RETVAL 2213 RETVAL
2190 2214
2191void 2215void
2192draw (DC::Map self, int mx, int my, int sw, int sh, int Tw, int Th, U32 player = 0xffffffff, int sdx = 0, int sdy = 0) 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)
2193 CODE: 2217 CODE:
2194{ 2218{
2195 int x, y, z; 2219 int x, y, z;
2196 2220
2197 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
2198 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level 2221 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level
2199 static uint8_t smooth_max[256][256]; // egad, fast and wasteful on memory (64k) 2222 static uint8_t smooth_max[256][256]; // egad, fast and wasteful on memory (64k)
2200 smooth_key skey; 2223 smooth_key skey;
2201 int pl_x, pl_y; 2224 int pl_x, pl_y;
2202 maptex pl_tex; 2225 maptex pl_tex;
2251 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2274 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2252 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 2275 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
2253 2276
2254 for (z = 0; z <= 2; z++) 2277 for (z = 0; z <= 2; z++)
2255 { 2278 {
2279 smooth_hash smooth;
2256 memset (smooth_level, 0, sizeof (smooth_level)); 2280 memset (smooth_level, 0, sizeof (smooth_level));
2257 key.texname = -1; 2281 key.texname = -1;
2258 2282
2259 for (y = 0; y < sh; y++) 2283 for (y = 0; y < sh; y++)
2260 if (0 <= y + my && y + my < self->rows) 2284 if (0 <= y + my && y + my < self->rows)
2321 2345
2322 // corners: 1 ┛· 2 ·┗ 4 ·· 8 ·· 2346 // corners: 1 ┛· 2 ·┗ 4 ·· 8 ··
2323 // ·· ·· ·┏ ┓· 2347 // ·· ·· ·┏ ┓·
2324 2348
2325 // full tile 2349 // full tile
2326 skey.x = x + 1; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x1000); 2350 skey.x = x + 1; skey.y = y + 1; smooth_or_bits (smooth, skey, 0x1000);
2327 2351
2328 // borders 2352 // borders
2329 skey.x = x + 2; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x0091); 2353 skey.x = x + 2; skey.y = y + 1; smooth_or_bits (smooth, skey, 0x0091);
2330 skey.x = x + 1; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0032); 2354 skey.x = x + 1; skey.y = y + 2; smooth_or_bits (smooth, skey, 0x0032);
2331 skey.x = x ; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x0064); 2355 skey.x = x ; skey.y = y + 1; smooth_or_bits (smooth, skey, 0x0064);
2332 skey.x = x + 1; skey.y = y ; smooth_or_bits (smooth, &skey, 0x00c8); 2356 skey.x = x + 1; skey.y = y ; smooth_or_bits (smooth, skey, 0x00c8);
2333 2357
2334 // corners 2358 // corners
2335 skey.x = x + 2; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0100); 2359 skey.x = x + 2; skey.y = y + 2; smooth_or_bits (smooth, skey, 0x0100);
2336 skey.x = x ; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0200); 2360 skey.x = x ; skey.y = y + 2; smooth_or_bits (smooth, skey, 0x0200);
2337 skey.x = x ; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0400); 2361 skey.x = x ; skey.y = y ; smooth_or_bits (smooth, skey, 0x0400);
2338 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0800); 2362 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, skey, 0x0800);
2339 } 2363 }
2340 } 2364 }
2341 2365
2342 if (expect_false (z == 2) && expect_false (cell->flags)) 2366 if (expect_false (z == 2) && expect_false (cell->flags))
2343 { 2367 {
2380 if (smask & (((uint32_t)1) << b)) 2404 if (smask & (((uint32_t)1) << b))
2381 { 2405 {
2382 int level = (w << 5) | b; 2406 int level = (w << 5) | b;
2383 HE *he; 2407 HE *he;
2384 2408
2385 hv_iterinit (smooth); 2409 for (auto &&it = smooth.begin (); it != smooth.end (); ++it)
2386 while ((he = hv_iternext (smooth)))
2387 { 2410 {
2388 smooth_key *skey = (smooth_key *)HeKEY (he); 2411 smooth_key &skey = it->first;
2389 IV bits = SvIVX (HeVAL (he)); 2412 IV bits = it->second;
2390 2413
2391 if (!(bits & 0x1000) 2414 if (!(bits & 0x1000)
2392 && skey->level == level 2415 && skey.level == level
2393 && level > smooth_max [skey->x][skey->y]) 2416 && level > smooth_max [skey.x][skey.y])
2394 { 2417 {
2395 maptex tex = self->tex [skey->tile]; 2418 maptex tex = self->tex [skey.tile];
2396 int px = (((int)skey->x) - 1) * Tw; 2419 int px = (((int)skey.x) - 1) * Tw;
2397 int py = (((int)skey->y) - 1) * Th; 2420 int py = (((int)skey.y) - 1) * Th;
2398 int border = bits & 15; 2421 int border = bits & 15;
2399 int corner = (bits >> 8) & ~(bits >> 4) & 15; 2422 int corner = (bits >> 8) & ~(bits >> 4) & 15;
2400 float dx = tex.s * .0625f; // 16 images/row 2423 float dx = tex.s * .0625f; // 16 images/row
2401 float dy = tex.t * .5f ; // 2 images/column 2424 float dy = tex.t * .5f ; // 2 images/column
2402 2425
2404 { 2427 {
2405 // this time avoiding texture state changes 2428 // this time avoiding texture state changes
2406 // save gobs of state changes. 2429 // save gobs of state changes.
2407 if (key.texname != tex.name) 2430 if (key.texname != tex.name)
2408 { 2431 {
2409 self->tex [skey->tile].unused = 0; 2432 self->tex [skey.tile].unused = 0;
2410 2433
2411 glEnd (); 2434 glEnd ();
2412 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name); 2435 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name);
2413 glBegin (GL_QUADS); 2436 glBegin (GL_QUADS);
2414 } 2437 }
2440 2463
2441 glEnd (); 2464 glEnd ();
2442 glDisable (GL_TEXTURE_2D); 2465 glDisable (GL_TEXTURE_2D);
2443 key.texname = -1; 2466 key.texname = -1;
2444 } 2467 }
2445
2446 hv_clear (smooth);
2447 } 2468 }
2448 2469
2449 if (pl_tex.name) 2470 if (pl_tex.name)
2450 { 2471 {
2451 maptex tex = pl_tex; 2472 maptex tex = pl_tex;
2720 else 2741 else
2721 *data++ = 0; 2742 *data++ = 0;
2722 } 2743 }
2723 } 2744 }
2724 2745
2725 /* if size is w*h + 5 then no data has been found */ 2746 /* if size is w*h + 5 then no data has been found */
2726 if (data - (uint8_t *)SvPVX (data_sv) != w * h + 5) 2747 if (data - (uint8_t *)SvPVX (data_sv) != w * h + 5)
2727 { 2748 {
2728 SvPOK_only (data_sv); 2749 SvPOK_only (data_sv);
2729 SvCUR_set (data_sv, data - (uint8_t *)SvPVX (data_sv)); 2750 SvCUR_set (data_sv, data - (uint8_t *)SvPVX (data_sv));
2730 } 2751 }
2731 2752
2732 RETVAL = data_sv; 2753 RETVAL = data_sv;
2733} 2754}
2734 OUTPUT: 2755 OUTPUT:
2735 RETVAL 2756 RETVAL
2736 2757
2737void 2758void
3427 3448
3428void 3449void
3429find_widget (SV *self, NV x, NV y) 3450find_widget (SV *self, NV x, NV y)
3430 PPCODE: 3451 PPCODE:
3431{ 3452{
3432 if (within_widget (self, x, y)) 3453 if (within_widget (self, x, y))
3433 XPUSHs (self); 3454 XPUSHs (self);
3434} 3455}
3435 3456
3436BOOT: 3457BOOT:
3437{ 3458{
3445 3466
3446void 3467void
3447draw (SV *self) 3468draw (SV *self)
3448 CODE: 3469 CODE:
3449{ 3470{
3450 HV *hv; 3471 HV *hv;
3451 SV **svp; 3472 SV **svp;
3452 NV x, y, w, h; 3473 NV x, y, w, h;
3453 SV *draw_x_sv = GvSV (draw_x_gv); 3474 SV *draw_x_sv = GvSV (draw_x_gv);
3454 SV *draw_y_sv = GvSV (draw_y_gv); 3475 SV *draw_y_sv = GvSV (draw_y_gv);
3455 SV *draw_w_sv = GvSV (draw_w_gv); 3476 SV *draw_w_sv = GvSV (draw_w_gv);
3456 SV *draw_h_sv = GvSV (draw_h_gv); 3477 SV *draw_h_sv = GvSV (draw_h_gv);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines