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.210 by root, Tue Jul 24 18:24:03 2007 UTC vs.
Revision 1.222 by root, Sat Aug 11 06:34:26 2007 UTC

17#include "perl.h" 17#include "perl.h"
18#include "XSUB.h" 18#include "XSUB.h"
19 19
20#ifdef _WIN32 20#ifdef _WIN32
21# undef pipe 21# undef pipe
22// microsoft vs. C
23# define sqrtf(x) sqrt(x)
24# define roundf(x) (int)(x)
25# define atan2f(x,y) atan2(x,y)
26# define M_PI 3.14159265f
22#endif 27#endif
23 28
24#include <assert.h> 29#include <assert.h>
25#include <math.h> 30#include <math.h>
26#include <string.h> 31#include <string.h>
27#include <stdio.h> 32#include <stdio.h>
28#include <stdlib.h> 33#include <stdlib.h>
34
35#define USE_RWOPS 1 // for SDL_mixer:LoadMUS_RW
29 36
30#include <SDL.h> 37#include <SDL.h>
31#include <SDL_thread.h> 38#include <SDL_thread.h>
32#include <SDL_endian.h> 39#include <SDL_endian.h>
33#include <SDL_image.h> 40#include <SDL_image.h>
112 119
113#include "pango-font.c" 120#include "pango-font.c"
114#include "pango-fontmap.c" 121#include "pango-fontmap.c"
115#include "pango-render.c" 122#include "pango-render.c"
116 123
124typedef IV CFPlus__Channel;
125typedef SDL_RWops *CFPlus__RW;
117typedef Mix_Chunk *CFPlus__MixChunk; 126typedef Mix_Chunk *CFPlus__MixChunk;
118typedef Mix_Music *CFPlus__MixMusic; 127typedef Mix_Music *CFPlus__MixMusic;
119 128
120typedef PangoFontDescription *CFPlus__Font; 129typedef PangoFontDescription *CFPlus__Font;
121 130
800 XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("CFPlus::UI::Event", 1)))); 809 XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("CFPlus::UI::Event", 1))));
801 } 810 }
802} 811}
803 812
804int 813int
805Mix_OpenAudio (int frequency = 48000, int format = MIX_DEFAULT_FORMAT, int channels = 1, int chunksize = 2048) 814Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 1024)
806 POSTCALL: 815 POSTCALL:
807 Mix_HookMusicFinished (music_finished); 816 Mix_HookMusicFinished (music_finished);
808 Mix_ChannelFinished (channel_finished); 817 Mix_ChannelFinished (channel_finished);
809 818
810void 819void
811Mix_CloseAudio () 820Mix_CloseAudio ()
812 821
813int 822int
814Mix_AllocateChannels (int numchans = -1) 823Mix_AllocateChannels (int numchans = -1)
824
825const char *
826Mix_GetError ()
815 827
816void 828void
817lowdelay (int fd, int val = 1) 829lowdelay (int fd, int val = 1)
818 CODE: 830 CODE:
819 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&val, sizeof (val)); 831 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&val, sizeof (val));
861 STRLEN image_len; 873 STRLEN image_len;
862 char *image = (char *)SvPVbyte (image_, image_len); 874 char *image = (char *)SvPVbyte (image_, image_len);
863 SDL_Surface *surface, *surface2; 875 SDL_Surface *surface, *surface2;
864 SDL_PixelFormat fmt; 876 SDL_PixelFormat fmt;
865 SDL_RWops *rw = ix 877 SDL_RWops *rw = ix
866 ? SDL_RWFromFile (image, "r") 878 ? SDL_RWFromFile (image, "rb")
867 : SDL_RWFromConstMem (image, image_len); 879 : SDL_RWFromConstMem (image, image_len);
868 880
869 if (!rw) 881 if (!rw)
870 croak ("load_image: %s", SDL_GetError ()); 882 croak ("load_image: %s", SDL_GetError ());
871 883
1343 HV *hv = (HV *)SvRV (self); 1355 HV *hv = (HV *)SvRV (self);
1344 float s = SvNV (*hv_fetch (hv, "s", 1, 1)); 1356 float s = SvNV (*hv_fetch (hv, "s", 1, 1));
1345 float t = SvNV (*hv_fetch (hv, "t", 1, 1)); 1357 float t = SvNV (*hv_fetch (hv, "t", 1, 1));
1346 int name = SvIV (*hv_fetch (hv, "name", 4, 1)); 1358 int name = SvIV (*hv_fetch (hv, "name", 4, 1));
1347 1359
1360 if (name <= 0)
1361 XSRETURN_EMPTY;
1362
1348 if (items < 5) 1363 if (items < 5)
1349 { 1364 {
1350 w = SvNV (*hv_fetch (hv, "w", 1, 1)); 1365 w = SvNV (*hv_fetch (hv, "w", 1, 1));
1351 h = SvNV (*hv_fetch (hv, "h", 1, 1)); 1366 h = SvNV (*hv_fetch (hv, "h", 1, 1));
1352 } 1367 }
1540 self->rows += MAP_EXTEND_Y; 1555 self->rows += MAP_EXTEND_Y;
1541 self->y += MAP_EXTEND_Y; 1556 self->y += MAP_EXTEND_Y;
1542 } 1557 }
1543} 1558}
1544 1559
1545void 1560SV *
1546map1a_update (CFPlus::Map self, SV *data_, int extmap) 1561map1a_update (CFPlus::Map self, SV *data_, int extmap)
1547 CODE: 1562 CODE:
1548{ 1563{
1549 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_); 1564 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_);
1550 uint8_t *data_end = (uint8_t *)SvEND (data_); 1565 uint8_t *data_end = (uint8_t *)SvEND (data_);
1551 mapcell *cell; 1566 mapcell *cell;
1552 int x, y, flags; 1567 int x, y, z, flags;
1568 AV *missing = newAV ();
1569 RETVAL = newRV_noinc ((SV *)missing);
1553 1570
1554 while (data < data_end - 1) 1571 while (data < data_end - 1)
1555 { 1572 {
1556 flags = (data [0] << 8) + data [1]; data += 2; 1573 flags = (data [0] << 8) + data [1]; data += 2;
1557 1574
1608 } 1625 }
1609 else 1626 else
1610 cell->darkness = *data++ + 1; 1627 cell->darkness = *data++ + 1;
1611 } 1628 }
1612 1629
1630 for (z = 0; z <= 2; ++z)
1613 if (flags & 4) 1631 if (flags & (4 >> z))
1614 { 1632 {
1615 faceid face = (data [0] << 8) + data [1]; data += 2; 1633 faceid face = (data [0] << 8) + data [1]; data += 2;
1616 need_facenum (self, face); 1634 need_facenum (self, face);
1617 cell->tile [0] = self->face2tile [face]; 1635 cell->tile [z] = self->face2tile [face];
1636
1637 if (cell->tile [z])
1638 {
1639 maptex *tex = self->tex + cell->tile [z];
1640 if (!tex->name)
1641 av_push (missing, newSViv (cell->tile [z]));
1642
1643 if (tex->smoothtile)
1644 {
1645 maptex *smooth = self->tex + tex->smoothtile;
1646 if (!smooth->name)
1647 av_push (missing, newSViv (tex->smoothtile));
1648 }
1649 }
1618 } 1650 }
1619
1620 if (flags & 2)
1621 {
1622 faceid face = (data [0] << 8) + data [1]; data += 2;
1623 need_facenum (self, face);
1624 cell->tile [1] = self->face2tile [face];
1625 }
1626
1627 if (flags & 1)
1628 {
1629 faceid face = (data [0] << 8) + data [1]; data += 2;
1630 need_facenum (self, face);
1631 cell->tile [2] = self->face2tile [face];
1632 }
1633 } 1651 }
1634 else 1652 else
1635 cell->darkness = 0; 1653 cell->darkness = 0;
1636 } 1654 }
1637} 1655}
1656 OUTPUT:
1657 RETVAL
1638 1658
1639SV * 1659SV *
1640mapmap (CFPlus::Map self, int x0, int y0, int w, int h) 1660mapmap (CFPlus::Map self, int x0, int y0, int w, int h)
1641 CODE: 1661 CODE:
1642{ 1662{
1716 glEnable (GL_TEXTURE_2D); 1736 glEnable (GL_TEXTURE_2D);
1717 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1737 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1718 1738
1719 glBegin (GL_QUADS); 1739 glBegin (GL_QUADS);
1720 1740
1721 last_name = 0; 1741 last_name = -1;
1722 1742
1723 mx += self->x; 1743 mx += self->x;
1724 my += self->y; 1744 my += self->y;
1725 1745
1726 // first pass: determine smooth_max 1746 // first pass: determine smooth_max
1761 tileid tile = cell->tile [z]; 1781 tileid tile = cell->tile [z];
1762 1782
1763 if (tile) 1783 if (tile)
1764 { 1784 {
1765 maptex tex = self->tex [tile]; 1785 maptex tex = self->tex [tile];
1766 int px = (x + 1) * T - tex.w; 1786 int px, py;
1767 int py = (y + 1) * T - tex.h;
1768 1787
1769 // suppressing texture state switches here 1788 // suppressing texture state switches here
1770 // is only moderately effective, but worth the extra effort 1789 // is only moderately effective, but worth the extra effort
1771 if (last_name != tex.name) 1790 if (last_name != tex.name)
1772 { 1791 {
1775 1794
1776 glEnd (); 1795 glEnd ();
1777 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1796 glBindTexture (GL_TEXTURE_2D, last_name = tex.name);
1778 glBegin (GL_QUADS); 1797 glBegin (GL_QUADS);
1779 } 1798 }
1799
1800 px = (x + 1) * T - tex.w;
1801 py = (y + 1) * T - tex.h;
1780 1802
1781 glTexCoord2f (0 , 0 ); glVertex2f (px , py ); 1803 glTexCoord2f (0 , 0 ); glVertex2f (px , py );
1782 glTexCoord2f (0 , tex.t); glVertex2f (px , py + tex.h); 1804 glTexCoord2f (0 , tex.t); glVertex2f (px , py + tex.h);
1783 glTexCoord2f (tex.s, tex.t); glVertex2f (px + tex.w, py + tex.h); 1805 glTexCoord2f (tex.s, tex.t); glVertex2f (px + tex.w, py + tex.h);
1784 glTexCoord2f (tex.s, 0 ); glVertex2f (px + tex.w, py ); 1806 glTexCoord2f (tex.s, 0 ); glVertex2f (px + tex.w, py );
2232 } 2254 }
2233 } 2255 }
2234 } 2256 }
2235} 2257}
2236 2258
2259MODULE = CFPlus PACKAGE = CFPlus::RW
2260
2261CFPlus::RW
2262new (SV *class, SV *data_sv)
2263 CODE:
2264{
2265 STRLEN datalen;
2266 char *data = SvPVbyte (data_sv, datalen);
2267
2268 RETVAL = SDL_RWFromConstMem (data, datalen);
2269}
2270 OUTPUT:
2271 RETVAL
2272
2273CFPlus::RW
2274new_from_file (SV *class, const char *path, const char *mode = "rb")
2275 CODE:
2276 RETVAL = SDL_RWFromFile (path, mode);
2277 OUTPUT:
2278 RETVAL
2279
2280# fails on win32:
2281# CFPlus.xs(2268) : error C2059: syntax error : '('
2282#void
2283#close (CFPlus::RW self)
2284# CODE:
2285# (self->(close)) (self);
2286
2287MODULE = CFPlus PACKAGE = CFPlus::Channel
2288
2289PROTOTYPES: DISABLE
2290
2291CFPlus::Channel
2292find ()
2293 CODE:
2294{
2295 RETVAL = Mix_GroupAvailable (-1);
2296
2297 if (RETVAL < 0)
2298 {
2299 RETVAL = Mix_GroupOldest (-1);
2300
2301 if (RETVAL < 0)
2302 XSRETURN_UNDEF;
2303
2304 Mix_HaltChannel (RETVAL);
2305 }
2306
2307 Mix_UnregisterAllEffects (RETVAL);
2308 Mix_Volume (RETVAL, 128);
2309}
2310 OUTPUT:
2311 RETVAL
2312
2313void
2314halt (CFPlus::Channel self)
2315 CODE:
2316 Mix_HaltChannel (self);
2317
2318void
2319expire (CFPlus::Channel self, int ticks = -1)
2320 CODE:
2321 Mix_ExpireChannel (self, ticks);
2322
2323void
2324fade_out (CFPlus::Channel self, int ticks = -1)
2325 CODE:
2326 Mix_FadeOutChannel (self, ticks);
2327
2328int
2329volume (CFPlus::Channel self, int volume)
2330 CODE:
2331 RETVAL = Mix_Volume (self, CLAMP (volume, 0, 128));
2332 OUTPUT:
2333 RETVAL
2334
2335void
2336unregister_all_effects (CFPlus::Channel self)
2337 CODE:
2338 Mix_UnregisterAllEffects (self);
2339
2340void
2341set_panning (CFPlus::Channel self, int left, int right)
2342 CODE:
2343 left = CLAMP (left , 0, 255);
2344 right = CLAMP (right, 0, 255);
2345 Mix_SetPanning (self, left, right);
2346
2347void
2348set_distance (CFPlus::Channel self, int distance)
2349 CODE:
2350 Mix_SetDistance (self, CLAMP (distance, 0, 255));
2351
2352void
2353set_position (CFPlus::Channel self, int angle, int distance)
2354 CODE:
2355
2356void
2357set_position_r (CFPlus::Channel self, int dx, int dy, int maxdistance)
2358 CODE:
2359{
2360 int distance = sqrtf (dx * dx + dy * dy) * (255.f / sqrtf (maxdistance * maxdistance));
2361 int angle = 360 + (int)roundf (atan2f (dx, -dy) * 180.f / (float)M_PI);
2362 Mix_SetPosition (self, angle, CLAMP (distance, 0, 255));
2363}
2364
2365void
2366set_reverse_stereo (CFPlus::Channel self, int flip)
2367 CODE:
2368 Mix_SetReverseStereo (self, flip);
2369
2237MODULE = CFPlus PACKAGE = CFPlus::MixChunk 2370MODULE = CFPlus PACKAGE = CFPlus::MixChunk
2238 2371
2239PROTOTYPES: DISABLE 2372PROTOTYPES: DISABLE
2240 2373
2241CFPlus::MixChunk 2374CFPlus::MixChunk
2242new_from_file (SV *class, char *path) 2375new (SV *class, CFPlus::RW rwops)
2243 CODE: 2376 CODE:
2244 RETVAL = Mix_LoadWAV (path); 2377 RETVAL = Mix_LoadWAV_RW (rwops, 1);
2245 OUTPUT: 2378 OUTPUT:
2246 RETVAL 2379 RETVAL
2247 2380
2248void 2381void
2249DESTROY (CFPlus::MixChunk self) 2382DESTROY (CFPlus::MixChunk self)
2251 Mix_FreeChunk (self); 2384 Mix_FreeChunk (self);
2252 2385
2253int 2386int
2254volume (CFPlus::MixChunk self, int volume = -1) 2387volume (CFPlus::MixChunk self, int volume = -1)
2255 CODE: 2388 CODE:
2389 if (items > 1)
2390 volume = CLAMP (volume, 0, 128);
2256 RETVAL = Mix_VolumeChunk (self, volume); 2391 RETVAL = Mix_VolumeChunk (self, volume);
2257 OUTPUT: 2392 OUTPUT:
2258 RETVAL 2393 RETVAL
2259 2394
2260int 2395CFPlus::Channel
2261play (CFPlus::MixChunk self, int channel = -1, int loops = 0, int ticks = -1) 2396play (CFPlus::MixChunk self, CFPlus::Channel channel = -1, int loops = 0, int ticks = -1)
2262 CODE: 2397 CODE:
2398{
2263 RETVAL = Mix_PlayChannelTimed (channel, self, loops, ticks); 2399 RETVAL = Mix_PlayChannelTimed (channel, self, loops, ticks);
2400
2401 if (RETVAL < 0)
2402 XSRETURN_UNDEF;
2403
2404 if (channel < 0)
2405 {
2406 Mix_UnregisterAllEffects (RETVAL);
2407 Mix_Volume (RETVAL, 128);
2408 }
2409}
2264 OUTPUT: 2410 OUTPUT:
2265 RETVAL 2411 RETVAL
2266 2412
2267MODULE = CFPlus PACKAGE = CFPlus::MixMusic 2413MODULE = CFPlus PACKAGE = CFPlus::MixMusic
2268 2414
2269int 2415int
2270volume (int volume = -1) 2416volume (int volume = -1)
2271 PROTOTYPE: ;$ 2417 PROTOTYPE: ;$
2272 CODE: 2418 CODE:
2419 if (items > 0)
2420 volume = CLAMP (volume, 0, 128);
2273 RETVAL = Mix_VolumeMusic (volume); 2421 RETVAL = Mix_VolumeMusic (volume);
2274 OUTPUT: 2422 OUTPUT:
2275 RETVAL 2423 RETVAL
2276 2424
2277int 2425void
2278fade_out (int ms) 2426fade_out (int ms)
2279 CODE: 2427 CODE:
2280 RETVAL = Mix_FadeOutMusic (ms); 2428 Mix_FadeOutMusic (ms);
2281 OUTPUT: 2429
2282 RETVAL 2430void
2431halt ()
2432 CODE:
2433 Mix_HaltMusic ();
2283 2434
2284CFPlus::MixMusic 2435CFPlus::MixMusic
2285new_from_file (SV *class, char *path) 2436new (SV *class, CFPlus::RW rwops)
2286 CODE: 2437 CODE:
2287 RETVAL = Mix_LoadMUS (path); 2438 RETVAL = Mix_LoadMUS_RW (rwops);
2288 OUTPUT: 2439 OUTPUT:
2289 RETVAL 2440 RETVAL
2290 2441
2291void 2442void
2292DESTROY (CFPlus::MixMusic self) 2443DESTROY (CFPlus::MixMusic self)
2298 CODE: 2449 CODE:
2299 RETVAL = Mix_PlayMusic (self, loops); 2450 RETVAL = Mix_PlayMusic (self, loops);
2300 OUTPUT: 2451 OUTPUT:
2301 RETVAL 2452 RETVAL
2302 2453
2303int 2454void
2304fade_in_pos (CFPlus::MixMusic self, int loops, int ms, double position) 2455fade_in_pos (CFPlus::MixMusic self, int loops, int ms, double position)
2305 CODE: 2456 CODE:
2306 RETVAL = Mix_FadeInMusicPos (self, loops, ms, position); 2457 Mix_FadeInMusicPos (self, loops, ms, position);
2307 OUTPUT:
2308 RETVAL
2309 2458
2310MODULE = CFPlus PACKAGE = CFPlus::OpenGL 2459MODULE = CFPlus PACKAGE = CFPlus::OpenGL
2311 2460
2312PROTOTYPES: ENABLE 2461PROTOTYPES: ENABLE
2313 2462

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines