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.209 by root, Sat Jul 21 22:54:52 2007 UTC vs.
Revision 1.235 by root, Tue Aug 28 01:23:47 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>
107 av_push (texture_av, (SV *)(size_t)name); 114 av_push (texture_av, (SV *)(size_t)name);
108 glDeleteTextures (1, &name); 115 glDeleteTextures (1, &name);
109} 116}
110 117
111#include "texcache.c" 118#include "texcache.c"
119#include "rendercache.c"
112 120
113#include "pango-font.c" 121#include "pango-font.c"
114#include "pango-fontmap.c" 122#include "pango-fontmap.c"
115#include "pango-render.c" 123#include "pango-render.c"
116 124
125typedef IV CFPlus__Channel;
126typedef SDL_RWops *CFPlus__RW;
117typedef Mix_Chunk *CFPlus__MixChunk; 127typedef Mix_Chunk *CFPlus__MixChunk;
118typedef Mix_Music *CFPlus__MixMusic; 128typedef Mix_Music *CFPlus__MixMusic;
119 129
120typedef PangoFontDescription *CFPlus__Font; 130typedef PangoFontDescription *CFPlus__Font;
121 131
140typedef struct cf_layout { 150typedef struct cf_layout {
141 PangoLayout *pl; 151 PangoLayout *pl;
142 float r, g, b, a; // default color for rgba mode 152 float r, g, b, a; // default color for rgba mode
143 int base_height; 153 int base_height;
144 CFPlus__Font font; 154 CFPlus__Font font;
155 rc_t *rc;
145} *CFPlus__Layout; 156} *CFPlus__Layout;
146 157
147static CFPlus__Font default_font; 158static CFPlus__Font default_font;
148static PangoContext *opengl_context; 159static PangoContext *opengl_context;
149static PangoFontMap *opengl_fontmap; 160static PangoFontMap *opengl_fontmap;
192 203
193typedef uint16_t tileid; 204typedef uint16_t tileid;
194typedef uint16_t faceid; 205typedef uint16_t faceid;
195 206
196typedef struct { 207typedef struct {
197 int name; 208 GLuint name;
198 int w, h; 209 int w, h;
199 float s, t; 210 float s, t;
200 uint8_t r, g, b, a; 211 uint8_t r, g, b, a;
201 tileid smoothtile; 212 tileid smoothtile;
202 uint8_t smoothlevel; 213 uint8_t smoothlevel;
427 n |= n >> 4; 438 n |= n >> 4;
428 n |= n >> 8; 439 n |= n >> 8;
429 n |= n >> 16; 440 n |= n >> 16;
430 441
431 return n + 1; 442 return n + 1;
443}
444
445static unsigned int
446popcount (unsigned int n)
447{
448 n -= (n >> 1) & 0x55555555U;
449 n = ((n >> 2) & 0x33333333U) + (n & 0x33333333U);
450 n = ((n >> 4) + n) & 0x0f0f0f0fU;
451 n *= 0x01010101U;
452
453 return n >> 24;
432} 454}
433 455
434/* SDL should provide this, really. */ 456/* SDL should provide this, really. */
435#define SDLK_MODIFIER_MIN 300 457#define SDLK_MODIFIER_MIN 300
436#define SDLK_MODIFIER_MAX 314 458#define SDLK_MODIFIER_MAX 314
514 536
515 const_iv (SDL_APPINPUTFOCUS), 537 const_iv (SDL_APPINPUTFOCUS),
516 const_iv (SDL_APPMOUSEFOCUS), 538 const_iv (SDL_APPMOUSEFOCUS),
517 const_iv (SDL_APPACTIVE), 539 const_iv (SDL_APPACTIVE),
518 540
541 const_iv (SDLK_FIRST),
542 const_iv (SDLK_LAST),
519 const_iv (SDLK_KP0), 543 const_iv (SDLK_KP0),
520 const_iv (SDLK_KP1), 544 const_iv (SDLK_KP1),
521 const_iv (SDLK_KP2), 545 const_iv (SDLK_KP2),
522 const_iv (SDLK_KP3), 546 const_iv (SDLK_KP3),
523 const_iv (SDLK_KP4), 547 const_iv (SDLK_KP4),
622 646
623NV floor (NV x) 647NV floor (NV x)
624 648
625NV ceil (NV x) 649NV ceil (NV x)
626 650
651IV minpot (UV n)
652
653IV popcount (UV n)
654
627void 655void
628pango_init () 656pango_init ()
629 CODE: 657 CODE:
630{ 658{
631 opengl_fontmap = pango_opengl_font_map_new (); 659 opengl_fontmap = pango_opengl_font_map_new ();
704 732
705 if (RETVAL) 733 if (RETVAL)
706 { 734 {
707 av_clear (texture_av); 735 av_clear (texture_av);
708 736
709 SDL_WM_SetCaption ("Crossfire+ Client " VERSION, "Crossfire+"); 737 SDL_WM_SetCaption ("Crossfire TRT Client " VERSION, "Crossfire TRT");
710#define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name); 738#define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name);
711#include "glfunc.h" 739#include "glfunc.h"
712#undef GL_FUNC 740#undef GL_FUNC
713 } 741 }
714} 742}
800 XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("CFPlus::UI::Event", 1)))); 828 XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("CFPlus::UI::Event", 1))));
801 } 829 }
802} 830}
803 831
804int 832int
805Mix_OpenAudio (int frequency = 48000, int format = MIX_DEFAULT_FORMAT, int channels = 1, int chunksize = 2048) 833Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 1024)
806 POSTCALL: 834 POSTCALL:
807 Mix_HookMusicFinished (music_finished); 835 Mix_HookMusicFinished (music_finished);
808 Mix_ChannelFinished (channel_finished); 836 Mix_ChannelFinished (channel_finished);
809 837
810void 838void
811Mix_CloseAudio () 839Mix_CloseAudio ()
812 840
813int 841int
814Mix_AllocateChannels (int numchans = -1) 842Mix_AllocateChannels (int numchans = -1)
843
844const char *
845Mix_GetError ()
815 846
816void 847void
817lowdelay (int fd, int val = 1) 848lowdelay (int fd, int val = 1)
818 CODE: 849 CODE:
819 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&val, sizeof (val)); 850 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&val, sizeof (val));
861 STRLEN image_len; 892 STRLEN image_len;
862 char *image = (char *)SvPVbyte (image_, image_len); 893 char *image = (char *)SvPVbyte (image_, image_len);
863 SDL_Surface *surface, *surface2; 894 SDL_Surface *surface, *surface2;
864 SDL_PixelFormat fmt; 895 SDL_PixelFormat fmt;
865 SDL_RWops *rw = ix 896 SDL_RWops *rw = ix
866 ? SDL_RWFromFile (image, "r") 897 ? SDL_RWFromFile (image, "rb")
867 : SDL_RWFromConstMem (image, image_len); 898 : SDL_RWFromConstMem (image, image_len);
868 899
869 if (!rw) 900 if (!rw)
870 croak ("load_image: %s", SDL_GetError ()); 901 croak ("load_image: %s", SDL_GetError ());
871 902
1023 RETVAL->g = 1.; 1054 RETVAL->g = 1.;
1024 RETVAL->b = 1.; 1055 RETVAL->b = 1.;
1025 RETVAL->a = 1.; 1056 RETVAL->a = 1.;
1026 RETVAL->base_height = MIN_FONT_HEIGHT; 1057 RETVAL->base_height = MIN_FONT_HEIGHT;
1027 RETVAL->font = 0; 1058 RETVAL->font = 0;
1059 RETVAL->rc = rc_alloc ();
1028 1060
1029 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR); 1061 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
1030 layout_update_font (RETVAL); 1062 layout_update_font (RETVAL);
1031 OUTPUT: 1063 OUTPUT:
1032 RETVAL 1064 RETVAL
1033 1065
1034void 1066void
1035DESTROY (CFPlus::Layout self) 1067DESTROY (CFPlus::Layout self)
1036 CODE: 1068 CODE:
1037 g_object_unref (self->pl); 1069 g_object_unref (self->pl);
1070 rc_free (self->rc);
1038 Safefree (self); 1071 Safefree (self);
1039 1072
1040void 1073void
1041set_text (CFPlus::Layout self, SV *text_) 1074set_text (CFPlus::Layout self, SV *text_)
1042 CODE: 1075 CODE:
1294 } 1327 }
1295} 1328}
1296 1329
1297void 1330void
1298render (CFPlus::Layout self, float x, float y, int flags = 0) 1331render (CFPlus::Layout self, float x, float y, int flags = 0)
1299 PPCODE: 1332 CODE:
1333 rc_clear (self->rc);
1300 pango_opengl_render_layout_subpixel ( 1334 pango_opengl_render_layout_subpixel (
1301 self->pl, 1335 self->pl,
1336 self->rc,
1302 x * PANGO_SCALE, y * PANGO_SCALE, 1337 x * PANGO_SCALE, y * PANGO_SCALE,
1303 self->r, self->g, self->b, self->a, 1338 self->r, self->g, self->b, self->a,
1304 flags 1339 flags
1305 ); 1340 );
1341 // we assume that context_change actually clears/frees stuff
1342 // and does not do any recomputation...
1343 pango_layout_context_changed (self->pl);
1344
1345void
1346draw (CFPlus::Layout self)
1347 CODE:
1348{
1349 glEnable (GL_TEXTURE_2D);
1350 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1351 glEnable (GL_BLEND);
1352 gl_BlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
1353 GL_ONE , GL_ONE_MINUS_SRC_ALPHA);
1354 glEnable (GL_ALPHA_TEST);
1355 glAlphaFunc (GL_GREATER, 7.f / 255.f);
1356
1357 rc_draw (self->rc);
1358
1359 glDisable (GL_ALPHA_TEST);
1360 glDisable (GL_BLEND);
1361 glDisable (GL_TEXTURE_2D);
1362}
1306 1363
1307MODULE = CFPlus PACKAGE = CFPlus::Texture 1364MODULE = CFPlus PACKAGE = CFPlus::Texture
1308 1365
1309PROTOTYPES: ENABLE 1366PROTOTYPES: ENABLE
1310
1311int minpot (int n)
1312 1367
1313void 1368void
1314pad (SV *data_, int ow, int oh, int nw, int nh) 1369pad (SV *data_, int ow, int oh, int nw, int nh)
1315 CODE: 1370 CODE:
1316{ 1371{
1342{ 1397{
1343 HV *hv = (HV *)SvRV (self); 1398 HV *hv = (HV *)SvRV (self);
1344 float s = SvNV (*hv_fetch (hv, "s", 1, 1)); 1399 float s = SvNV (*hv_fetch (hv, "s", 1, 1));
1345 float t = SvNV (*hv_fetch (hv, "t", 1, 1)); 1400 float t = SvNV (*hv_fetch (hv, "t", 1, 1));
1346 int name = SvIV (*hv_fetch (hv, "name", 4, 1)); 1401 int name = SvIV (*hv_fetch (hv, "name", 4, 1));
1402
1403 if (name <= 0)
1404 XSRETURN_EMPTY;
1347 1405
1348 if (items < 5) 1406 if (items < 5)
1349 { 1407 {
1350 w = SvNV (*hv_fetch (hv, "w", 1, 1)); 1408 w = SvNV (*hv_fetch (hv, "w", 1, 1));
1351 h = SvNV (*hv_fetch (hv, "h", 1, 1)); 1409 h = SvNV (*hv_fetch (hv, "h", 1, 1));
1540 self->rows += MAP_EXTEND_Y; 1598 self->rows += MAP_EXTEND_Y;
1541 self->y += MAP_EXTEND_Y; 1599 self->y += MAP_EXTEND_Y;
1542 } 1600 }
1543} 1601}
1544 1602
1545void 1603SV *
1546map1a_update (CFPlus::Map self, SV *data_, int extmap) 1604map1a_update (CFPlus::Map self, SV *data_, int extmap)
1547 CODE: 1605 CODE:
1548{ 1606{
1549 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_); 1607 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_);
1550 uint8_t *data_end = (uint8_t *)SvEND (data_); 1608 uint8_t *data_end = (uint8_t *)SvEND (data_);
1551 mapcell *cell; 1609 mapcell *cell;
1552 int x, y, flags; 1610 int x, y, z, flags;
1611 AV *missing = newAV ();
1612 RETVAL = newRV_noinc ((SV *)missing);
1553 1613
1554 while (data < data_end - 1) 1614 while (data < data_end - 1)
1555 { 1615 {
1556 flags = (data [0] << 8) + data [1]; data += 2; 1616 flags = (data [0] << 8) + data [1]; data += 2;
1557 1617
1608 } 1668 }
1609 else 1669 else
1610 cell->darkness = *data++ + 1; 1670 cell->darkness = *data++ + 1;
1611 } 1671 }
1612 1672
1673 for (z = 0; z <= 2; ++z)
1613 if (flags & 4) 1674 if (flags & (4 >> z))
1614 { 1675 {
1615 faceid face = (data [0] << 8) + data [1]; data += 2; 1676 faceid face = (data [0] << 8) + data [1]; data += 2;
1616 need_facenum (self, face); 1677 need_facenum (self, face);
1617 cell->tile [0] = self->face2tile [face]; 1678 cell->tile [z] = self->face2tile [face];
1679
1680 if (cell->tile [z])
1681 {
1682 maptex *tex = self->tex + cell->tile [z];
1683 if (!tex->name)
1684 av_push (missing, newSViv (cell->tile [z]));
1685
1686 if (tex->smoothtile)
1687 {
1688 maptex *smooth = self->tex + tex->smoothtile;
1689 if (!smooth->name)
1690 av_push (missing, newSViv (tex->smoothtile));
1691 }
1692 }
1618 } 1693 }
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 } 1694 }
1634 else 1695 else
1635 cell->darkness = 0; 1696 cell->darkness = 0;
1636 } 1697 }
1637} 1698}
1699 OUTPUT:
1700 RETVAL
1638 1701
1639SV * 1702SV *
1640mapmap (CFPlus::Map self, int x0, int y0, int w, int h) 1703mapmap (CFPlus::Map self, int x0, int y0, int w, int h)
1641 CODE: 1704 CODE:
1642{ 1705{
1693 1756
1694void 1757void
1695draw (CFPlus::Map self, int mx, int my, int sw, int sh, int T) 1758draw (CFPlus::Map self, int mx, int my, int sw, int sh, int T)
1696 CODE: 1759 CODE:
1697{ 1760{
1761 int x, y, z;
1762
1698 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ()); 1763 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
1699 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level 1764 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level
1700 static uint8_t smooth_max[256][256]; // egad, fats and wasteful on memory (64k) 1765 static uint8_t smooth_max[256][256]; // egad, fast and wasteful on memory (64k)
1701 smooth_key skey; 1766 smooth_key skey;
1702 int x, y, z; 1767
1703 int last_name; 1768 rc_t *rc = rc_alloc ();
1769 rc_key_t key;
1770 rc_array_t *arr;
1704 1771
1705 // thats current max. sorry. 1772 // thats current max. sorry.
1706 if (sw > 255) sw = 255; 1773 if (sw > 255) sw = 255;
1707 if (sh > 255) sh = 255; 1774 if (sh > 255) sh = 255;
1708 1775
1709 // clear key, in case of extra padding 1776 // clear key, in case of extra padding
1710 memset (&skey, 0, sizeof (skey)); 1777 memset (&skey, 0, sizeof (skey));
1711 1778
1712 glColor4ub (255, 255, 255, 255); 1779 memset (&key, 0, sizeof (key));
1713 1780 key.r = 255;
1714 glEnable (GL_BLEND); 1781 key.g = 255;
1715 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1782 key.b = 255;
1716 glEnable (GL_TEXTURE_2D); 1783 key.a = 255;
1717 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1784 key.mode = GL_QUADS;
1718 1785 key.format = GL_T2F_V3F;
1719 glBegin (GL_QUADS); 1786 key.texname = -1;
1720
1721 last_name = 0;
1722 1787
1723 mx += self->x; 1788 mx += self->x;
1724 my += self->y; 1789 my += self->y;
1725 1790
1726 // first pass: determine smooth_max 1791 // first pass: determine smooth_max
1742 MAX (self->tex [cell->tile [0]].smoothlevel, 1807 MAX (self->tex [cell->tile [0]].smoothlevel,
1743 MAX (self->tex [cell->tile [1]].smoothlevel, 1808 MAX (self->tex [cell->tile [1]].smoothlevel,
1744 self->tex [cell->tile [2]].smoothlevel)); 1809 self->tex [cell->tile [2]].smoothlevel));
1745 } 1810 }
1746 } 1811 }
1812
1813 glEnable (GL_BLEND);
1814 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1815 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1747 1816
1748 for (z = 0; z <= 2; z++) 1817 for (z = 0; z <= 2; z++)
1749 { 1818 {
1750 memset (smooth_level, 0, sizeof (smooth_level)); 1819 memset (smooth_level, 0, sizeof (smooth_level));
1751 1820
1761 tileid tile = cell->tile [z]; 1830 tileid tile = cell->tile [z];
1762 1831
1763 if (tile) 1832 if (tile)
1764 { 1833 {
1765 maptex tex = self->tex [tile]; 1834 maptex tex = self->tex [tile];
1766 int px = (x + 1) * T - tex.w; 1835 int px, py;
1767 int py = (y + 1) * T - tex.h;
1768 1836
1769 // suppressing texture state switches here
1770 // is only moderately effective, but worth the extra effort
1771 if (last_name != tex.name) 1837 if (key.texname != tex.name)
1772 { 1838 {
1773 if (!tex.name) 1839 if (!tex.name)
1774 tex = self->tex [2]; /* missing, replace by noface */ 1840 tex = self->tex [2]; /* missing, replace by noface */
1775 1841
1776 glEnd (); 1842 key.texname = tex.name;
1777 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1843 arr = rc_array (rc, &key);
1778 glBegin (GL_QUADS);
1779 } 1844 }
1780 1845
1781 glTexCoord2f (0 , 0 ); glVertex2f (px , py ); 1846 px = (x + 1) * T - tex.w;
1847 py = (y + 1) * T - tex.h;
1848
1849 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
1782 glTexCoord2f (0 , tex.t); glVertex2f (px , py + tex.h); 1850 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0);
1783 glTexCoord2f (tex.s, tex.t); glVertex2f (px + tex.w, py + tex.h); 1851 rc_t2f_v3f (arr, tex.s, tex.t, px + tex.w, py + tex.h, 0);
1784 glTexCoord2f (tex.s, 0 ); glVertex2f (px + tex.w, py ); 1852 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0);
1785 1853
1786 if (cell->flags && z == 2) 1854 if (cell->flags && z == 2)
1787 { 1855 {
1856 // overlays such as the speech bubble, probably more to come
1788 if (cell->flags & 1) 1857 if (cell->flags & 1)
1789 { 1858 {
1790 maptex tex = self->tex [1]; 1859 maptex tex = self->tex [1];
1791 int px = x * T + T * 2 / 32; 1860 int px = x * T + T * 2 / 32;
1792 int py = y * T - T * 6 / 32; 1861 int py = y * T - T * 6 / 32;
1793 1862
1863 if (tex.name)
1794 glEnd (); 1864 {
1795 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1865 if (key.texname != tex.name)
1866 {
1867 key.texname = tex.name;
1868 arr = rc_array (rc, &key);
1869 }
1870
1871 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
1872 rc_t2f_v3f (arr, 0 , tex.t, px , py + T, 0);
1873 rc_t2f_v3f (arr, tex.s, tex.t, px + T, py + T, 0);
1874 rc_t2f_v3f (arr, tex.s, 0 , px + T, py , 0);
1796 glBegin (GL_QUADS); 1875 }
1797
1798 glTexCoord2f (0 , 0 ); glVertex2f (px , py );
1799 glTexCoord2f (0 , tex.t); glVertex2f (px , py + T);
1800 glTexCoord2f (tex.s, tex.t); glVertex2f (px + T, py + T);
1801 glTexCoord2f (tex.s, 0 ); glVertex2f (px + T, py );
1802 } 1876 }
1803 } 1877 }
1804 1878
1805 // update smooth hash 1879 // update smooth hash
1806 if (tex.smoothtile) 1880 if (tex.smoothtile)
1842 } 1916 }
1843 } 1917 }
1844 } 1918 }
1845 } 1919 }
1846 1920
1921 rc_draw (rc);
1922 rc_clear (rc);
1923
1847 // go through all smoothlevels, lowest to highest, then draw. 1924 // go through all smoothlevels, lowest to highest, then draw.
1848 // this is basically counting sort 1925 // this is basically counting sort
1849 { 1926 {
1850 int w, b; 1927 int w, b;
1851 1928
1929 glEnable (GL_TEXTURE_2D);
1930 glBegin (GL_QUADS);
1852 for (w = 0; w < 256 / 32; ++w) 1931 for (w = 0; w < 256 / 32; ++w)
1853 { 1932 {
1854 uint32_t smask = smooth_level [w]; 1933 uint32_t smask = smooth_level [w];
1855 if (smask) 1934 if (smask)
1856 for (b = 0; b < 32; ++b) 1935 for (b = 0; b < 32; ++b)
1875 int border = bits & 15; 1954 int border = bits & 15;
1876 int corner = (bits >> 8) & ~(bits >> 4) & 15; 1955 int corner = (bits >> 8) & ~(bits >> 4) & 15;
1877 float dx = tex.s * .0625f; // 16 images/row 1956 float dx = tex.s * .0625f; // 16 images/row
1878 float dy = tex.t * .5f ; // 2 images/column 1957 float dy = tex.t * .5f ; // 2 images/column
1879 1958
1880 // this time naively avoiding texture state changes
1881 // save gobs of state changes.
1882 if (last_name != tex.name) 1959 if (tex.name)
1883 { 1960 {
1961 // this time avoiding texture state changes
1962 // save gobs of state changes.
1884 if (!tex.name) 1963 if (key.texname != tex.name)
1885 continue; // smoothing not yet available 1964 {
1886
1887 glEnd (); 1965 glEnd ();
1888 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1966 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name);
1889 glBegin (GL_QUADS); 1967 glBegin (GL_QUADS);
1890 } 1968 }
1891 1969
1892 if (border) 1970 if (border)
1893 { 1971 {
1894 float ox = border * dx; 1972 float ox = border * dx;
1895 1973
1896 glTexCoord2f (ox , 0.f ); glVertex2f (px , py ); 1974 glTexCoord2f (ox , 0.f ); glVertex2i (px , py );
1897 glTexCoord2f (ox , dy ); glVertex2f (px , py + T); 1975 glTexCoord2f (ox , dy ); glVertex2i (px , py + T);
1898 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py + T); 1976 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py + T);
1899 glTexCoord2f (ox + dx, 0.f ); glVertex2f (px + T, py ); 1977 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + T, py );
1900 } 1978 }
1901 1979
1902 if (corner) 1980 if (corner)
1903 { 1981 {
1904 float ox = corner * dx; 1982 float ox = corner * dx;
1905 1983
1906 glTexCoord2f (ox , dy ); glVertex2f (px , py ); 1984 glTexCoord2f (ox , dy ); glVertex2i (px , py );
1907 glTexCoord2f (ox , dy * 2.f); glVertex2f (px , py + T); 1985 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + T);
1908 glTexCoord2f (ox + dx, dy * 2.f); glVertex2f (px + T, py + T); 1986 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + T, py + T);
1909 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py ); 1987 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py );
1988 }
1910 } 1989 }
1911 } 1990 }
1912 } 1991 }
1913 } 1992 }
1914 } 1993 }
1994
1995 glEnd ();
1996 glDisable (GL_TEXTURE_2D);
1997 key.texname = -1;
1915 } 1998 }
1916 1999
1917 hv_clear (smooth); 2000 hv_clear (smooth);
1918 } 2001 }
1919 2002
1920 glEnd ();
1921
1922 glDisable (GL_TEXTURE_2D);
1923 glDisable (GL_BLEND); 2003 glDisable (GL_BLEND);
2004 rc_free (rc);
1924 2005
1925 // top layer: overlays such as the health bar 2006 // top layer: overlays such as the health bar
1926 for (y = 0; y < sh; y++) 2007 for (y = 0; y < sh; y++)
1927 if (0 <= y + my && y + my < self->rows) 2008 if (0 <= y + my && y + my < self->rows)
1928 { 2009 {
2177 int x, y, z; 2258 int x, y, z;
2178 int w, h; 2259 int w, h;
2179 int x1, y1; 2260 int x1, y1;
2180 2261
2181 if (*data++ != 0) 2262 if (*data++ != 0)
2182 return; /* version mismatch */ 2263 XSRETURN_EMPTY; /* version mismatch */
2183 2264
2184 w = *data++ << 8; w |= *data++; 2265 w = *data++ << 8; w |= *data++;
2185 h = *data++ << 8; h |= *data++; 2266 h = *data++ << 8; h |= *data++;
2186 2267
2187 // we need to do this 'cause we don't keep an absolute coord system for rows 2268 // we need to do this 'cause we don't keep an absolute coord system for rows
2232 } 2313 }
2233 } 2314 }
2234 } 2315 }
2235} 2316}
2236 2317
2318MODULE = CFPlus PACKAGE = CFPlus::RW
2319
2320CFPlus::RW
2321new (SV *class, SV *data_sv)
2322 CODE:
2323{
2324 STRLEN datalen;
2325 char *data = SvPVbyte (data_sv, datalen);
2326
2327 RETVAL = SDL_RWFromConstMem (data, datalen);
2328}
2329 OUTPUT:
2330 RETVAL
2331
2332CFPlus::RW
2333new_from_file (SV *class, const char *path, const char *mode = "rb")
2334 CODE:
2335 RETVAL = SDL_RWFromFile (path, mode);
2336 OUTPUT:
2337 RETVAL
2338
2339# fails on win32:
2340# CFPlus.xs(2268) : error C2059: syntax error : '('
2341#void
2342#close (CFPlus::RW self)
2343# CODE:
2344# (self->(close)) (self);
2345
2346MODULE = CFPlus PACKAGE = CFPlus::Channel
2347
2348PROTOTYPES: DISABLE
2349
2350CFPlus::Channel
2351find ()
2352 CODE:
2353{
2354 RETVAL = Mix_GroupAvailable (-1);
2355
2356 if (RETVAL < 0)
2357 {
2358 RETVAL = Mix_GroupOldest (-1);
2359
2360 if (RETVAL < 0)
2361 XSRETURN_UNDEF;
2362
2363 Mix_HaltChannel (RETVAL);
2364 }
2365
2366 Mix_UnregisterAllEffects (RETVAL);
2367 Mix_Volume (RETVAL, 128);
2368}
2369 OUTPUT:
2370 RETVAL
2371
2372void
2373halt (CFPlus::Channel self)
2374 CODE:
2375 Mix_HaltChannel (self);
2376
2377void
2378expire (CFPlus::Channel self, int ticks = -1)
2379 CODE:
2380 Mix_ExpireChannel (self, ticks);
2381
2382void
2383fade_out (CFPlus::Channel self, int ticks = -1)
2384 CODE:
2385 Mix_FadeOutChannel (self, ticks);
2386
2387int
2388volume (CFPlus::Channel self, int volume)
2389 CODE:
2390 RETVAL = Mix_Volume (self, CLAMP (volume, 0, 128));
2391 OUTPUT:
2392 RETVAL
2393
2394void
2395unregister_all_effects (CFPlus::Channel self)
2396 CODE:
2397 Mix_UnregisterAllEffects (self);
2398
2399void
2400set_panning (CFPlus::Channel self, int left, int right)
2401 CODE:
2402 left = CLAMP (left , 0, 255);
2403 right = CLAMP (right, 0, 255);
2404 Mix_SetPanning (self, left, right);
2405
2406void
2407set_distance (CFPlus::Channel self, int distance)
2408 CODE:
2409 Mix_SetDistance (self, CLAMP (distance, 0, 255));
2410
2411void
2412set_position (CFPlus::Channel self, int angle, int distance)
2413 CODE:
2414
2415void
2416set_position_r (CFPlus::Channel self, int dx, int dy, int maxdistance)
2417 CODE:
2418{
2419 int distance = sqrtf (dx * dx + dy * dy) * (255.f / sqrtf (maxdistance * maxdistance));
2420 int angle = 360 + (int)roundf (atan2f (dx, -dy) * 180.f / (float)M_PI);
2421 Mix_SetPosition (self, angle, CLAMP (distance, 0, 255));
2422}
2423
2424void
2425set_reverse_stereo (CFPlus::Channel self, int flip)
2426 CODE:
2427 Mix_SetReverseStereo (self, flip);
2428
2237MODULE = CFPlus PACKAGE = CFPlus::MixChunk 2429MODULE = CFPlus PACKAGE = CFPlus::MixChunk
2238 2430
2239PROTOTYPES: DISABLE 2431PROTOTYPES: DISABLE
2240 2432
2241CFPlus::MixChunk 2433CFPlus::MixChunk
2242new_from_file (SV *class, char *path) 2434new (SV *class, CFPlus::RW rwops)
2243 CODE: 2435 CODE:
2244 RETVAL = Mix_LoadWAV (path); 2436 RETVAL = Mix_LoadWAV_RW (rwops, 1);
2245 OUTPUT: 2437 OUTPUT:
2246 RETVAL 2438 RETVAL
2247 2439
2248void 2440void
2249DESTROY (CFPlus::MixChunk self) 2441DESTROY (CFPlus::MixChunk self)
2251 Mix_FreeChunk (self); 2443 Mix_FreeChunk (self);
2252 2444
2253int 2445int
2254volume (CFPlus::MixChunk self, int volume = -1) 2446volume (CFPlus::MixChunk self, int volume = -1)
2255 CODE: 2447 CODE:
2448 if (items > 1)
2449 volume = CLAMP (volume, 0, 128);
2256 RETVAL = Mix_VolumeChunk (self, volume); 2450 RETVAL = Mix_VolumeChunk (self, volume);
2257 OUTPUT: 2451 OUTPUT:
2258 RETVAL 2452 RETVAL
2259 2453
2260int 2454CFPlus::Channel
2261play (CFPlus::MixChunk self, int channel = -1, int loops = 0, int ticks = -1) 2455play (CFPlus::MixChunk self, CFPlus::Channel channel = -1, int loops = 0, int ticks = -1)
2262 CODE: 2456 CODE:
2457{
2263 RETVAL = Mix_PlayChannelTimed (channel, self, loops, ticks); 2458 RETVAL = Mix_PlayChannelTimed (channel, self, loops, ticks);
2459
2460 if (RETVAL < 0)
2461 XSRETURN_UNDEF;
2462
2463 if (channel < 0)
2464 {
2465 Mix_UnregisterAllEffects (RETVAL);
2466 Mix_Volume (RETVAL, 128);
2467 }
2468}
2264 OUTPUT: 2469 OUTPUT:
2265 RETVAL 2470 RETVAL
2266 2471
2267MODULE = CFPlus PACKAGE = CFPlus::MixMusic 2472MODULE = CFPlus PACKAGE = CFPlus::MixMusic
2268 2473
2269int 2474int
2270volume (int volume = -1) 2475volume (int volume = -1)
2271 PROTOTYPE: ;$ 2476 PROTOTYPE: ;$
2272 CODE: 2477 CODE:
2478 if (items > 0)
2479 volume = CLAMP (volume, 0, 128);
2273 RETVAL = Mix_VolumeMusic (volume); 2480 RETVAL = Mix_VolumeMusic (volume);
2274 OUTPUT: 2481 OUTPUT:
2275 RETVAL 2482 RETVAL
2276 2483
2277int 2484void
2278fade_out (int ms) 2485fade_out (int ms)
2279 CODE: 2486 CODE:
2280 RETVAL = Mix_FadeOutMusic (ms); 2487 Mix_FadeOutMusic (ms);
2281 OUTPUT: 2488
2282 RETVAL 2489void
2490halt ()
2491 CODE:
2492 Mix_HaltMusic ();
2283 2493
2284CFPlus::MixMusic 2494CFPlus::MixMusic
2285new_from_file (SV *class, char *path) 2495new (SV *class, CFPlus::RW rwops)
2286 CODE: 2496 CODE:
2287 RETVAL = Mix_LoadMUS (path); 2497 RETVAL = Mix_LoadMUS_RW (rwops);
2288 OUTPUT: 2498 OUTPUT:
2289 RETVAL 2499 RETVAL
2290 2500
2291void 2501void
2292DESTROY (CFPlus::MixMusic self) 2502DESTROY (CFPlus::MixMusic self)
2298 CODE: 2508 CODE:
2299 RETVAL = Mix_PlayMusic (self, loops); 2509 RETVAL = Mix_PlayMusic (self, loops);
2300 OUTPUT: 2510 OUTPUT:
2301 RETVAL 2511 RETVAL
2302 2512
2303int 2513void
2304fade_in_pos (CFPlus::MixMusic self, int loops, int ms, double position) 2514fade_in_pos (CFPlus::MixMusic self, int loops, int ms, double position)
2305 CODE: 2515 CODE:
2306 RETVAL = Mix_FadeInMusicPos (self, loops, ms, position); 2516 Mix_FadeInMusicPos (self, loops, ms, position);
2307 OUTPUT:
2308 RETVAL
2309 2517
2310MODULE = CFPlus PACKAGE = CFPlus::OpenGL 2518MODULE = CFPlus PACKAGE = CFPlus::OpenGL
2311 2519
2312PROTOTYPES: ENABLE 2520PROTOTYPES: ENABLE
2313 2521
2356 const_iv (GL_INTENSITY), 2564 const_iv (GL_INTENSITY),
2357 const_iv (GL_LUMINANCE), 2565 const_iv (GL_LUMINANCE),
2358 const_iv (GL_LUMINANCE_ALPHA), 2566 const_iv (GL_LUMINANCE_ALPHA),
2359 const_iv (GL_FLOAT), 2567 const_iv (GL_FLOAT),
2360 const_iv (GL_UNSIGNED_INT_8_8_8_8_REV), 2568 const_iv (GL_UNSIGNED_INT_8_8_8_8_REV),
2569 const_iv (GL_COMPRESSED_ALPHA_ARB),
2570 const_iv (GL_COMPRESSED_LUMINANCE_ARB),
2571 const_iv (GL_COMPRESSED_LUMINANCE_ALPHA_ARB),
2572 const_iv (GL_COMPRESSED_INTENSITY_ARB),
2573 const_iv (GL_COMPRESSED_RGB_ARB),
2574 const_iv (GL_COMPRESSED_RGBA_ARB),
2361 const_iv (GL_COMPILE), 2575 const_iv (GL_COMPILE),
2362 const_iv (GL_PROXY_TEXTURE_1D), 2576 const_iv (GL_PROXY_TEXTURE_1D),
2363 const_iv (GL_PROXY_TEXTURE_2D), 2577 const_iv (GL_PROXY_TEXTURE_2D),
2364 const_iv (GL_TEXTURE_1D), 2578 const_iv (GL_TEXTURE_1D),
2365 const_iv (GL_TEXTURE_2D), 2579 const_iv (GL_TEXTURE_2D),
2404 const_iv (GL_PERSPECTIVE_CORRECTION_HINT), 2618 const_iv (GL_PERSPECTIVE_CORRECTION_HINT),
2405 const_iv (GL_POINT_SMOOTH_HINT), 2619 const_iv (GL_POINT_SMOOTH_HINT),
2406 const_iv (GL_LINE_SMOOTH_HINT), 2620 const_iv (GL_LINE_SMOOTH_HINT),
2407 const_iv (GL_POLYGON_SMOOTH_HINT), 2621 const_iv (GL_POLYGON_SMOOTH_HINT),
2408 const_iv (GL_GENERATE_MIPMAP_HINT), 2622 const_iv (GL_GENERATE_MIPMAP_HINT),
2623 const_iv (GL_TEXTURE_COMPRESSION_HINT),
2409 const_iv (GL_FASTEST), 2624 const_iv (GL_FASTEST),
2410 const_iv (GL_DONT_CARE), 2625 const_iv (GL_DONT_CARE),
2411 const_iv (GL_NICEST), 2626 const_iv (GL_NICEST),
2412 const_iv (GL_V2F), 2627 const_iv (GL_V2F),
2413 const_iv (GL_V3F), 2628 const_iv (GL_V3F),
2421 2636
2422 texture_av = newAV (); 2637 texture_av = newAV ();
2423 AvREAL_off (texture_av); 2638 AvREAL_off (texture_av);
2424} 2639}
2425 2640
2641void
2642disable_GL_EXT_blend_func_separate ()
2643 CODE:
2644 gl.BlendFuncSeparate = 0;
2645 gl.BlendFuncSeparateEXT = 0;
2646
2426char * 2647char *
2427gl_vendor () 2648gl_vendor ()
2428 CODE: 2649 CODE:
2429 RETVAL = (char *)glGetString (GL_VENDOR); 2650 RETVAL = (char *)glGetString (GL_VENDOR);
2430 OUTPUT: 2651 OUTPUT:
2547 2768
2548void glTexCoord (float s, float t) 2769void glTexCoord (float s, float t)
2549 CODE: 2770 CODE:
2550 glTexCoord2f (s, t); 2771 glTexCoord2f (s, t);
2551 2772
2773void glRect (float x1, float y1, float x2, float y2)
2774 CODE:
2775 glRectf (x1, y1, x2, y2);
2776
2777void glRect_lineloop (float x1, float y1, float x2, float y2)
2778 CODE:
2779 glBegin (GL_LINE_LOOP);
2780 glVertex2f (x1, y1);
2781 glVertex2f (x2, y1);
2782 glVertex2f (x2, y2);
2783 glVertex2f (x1, y2);
2784 glEnd ();
2785
2552PROTOTYPES: ENABLE 2786PROTOTYPES: ENABLE
2553 2787
2554void glBegin (int mode) 2788void glBegin (int mode)
2555 2789
2556void glEnd () 2790void glEnd ()
2657 NV x, y, w, h; 2891 NV x, y, w, h;
2658 SV *draw_x_sv = GvSV (draw_x_gv); 2892 SV *draw_x_sv = GvSV (draw_x_gv);
2659 SV *draw_y_sv = GvSV (draw_y_gv); 2893 SV *draw_y_sv = GvSV (draw_y_gv);
2660 SV *draw_w_sv = GvSV (draw_w_gv); 2894 SV *draw_w_sv = GvSV (draw_w_gv);
2661 SV *draw_h_sv = GvSV (draw_h_gv); 2895 SV *draw_h_sv = GvSV (draw_h_gv);
2662 SV *hover;
2663 double draw_x, draw_y, draw_w, draw_h; 2896 double draw_x, draw_y;
2664 2897
2665 if (!SvROK (self)) 2898 if (!SvROK (self))
2666 croak ("CFPlus::Base::draw: %s not a reference", SvPV_nolen (self)); 2899 croak ("CFPlus::Base::draw: %s not a reference", SvPV_nolen (self));
2667 2900
2668 hv = (HV *)SvRV (self); 2901 hv = (HV *)SvRV (self);
2696 { 2929 {
2697 svp = hv_fetch (hv, "can_hover", sizeof ("can_hover") - 1, 0); 2930 svp = hv_fetch (hv, "can_hover", sizeof ("can_hover") - 1, 0);
2698 2931
2699 if (svp && SvTRUE (*svp)) 2932 if (svp && SvTRUE (*svp))
2700 { 2933 {
2701 glColor4f (1*0.2f, 0.8*0.2f, 0.5*0.2f, 0.2f); 2934 glColor4f (1.0f * 0.2f, 0.8f * 0.2f, 0.5f * 0.2f, 0.2f);
2702 glEnable (GL_BLEND); 2935 glEnable (GL_BLEND);
2703 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 2936 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
2704 glBegin (GL_QUADS); 2937 glBegin (GL_QUADS);
2705 glVertex2f (0, 0); 2938 glVertex2f (0, 0);
2706 glVertex2f (w, 0); 2939 glVertex2f (w, 0);
2709 glEnd (); 2942 glEnd ();
2710 glDisable (GL_BLEND); 2943 glDisable (GL_BLEND);
2711 } 2944 }
2712 } 2945 }
2713#if 0 2946#if 0
2714 if ($ENV{CFPLUS_DEBUG} & 1) { 2947 // draw borders, for debugging
2715 glPushMatrix; 2948 glPushMatrix ();
2716 glColor 1, 1, 0, 1; 2949 glColor4f (1., 1., 0., 1.);
2717 glTranslate 0.375, 0.375; 2950 glTranslatef (.5, .5, 0.);
2718 glBegin GL_LINE_LOOP; 2951 glBegin (GL_LINE_LOOP);
2719 glVertex 0 , 0; 2952 glVertex2f (0 , 0);
2720 glVertex $self->{w} - 1, 0; 2953 glVertex2f (w - 1, 0);
2721 glVertex $self->{w} - 1, $self->{h} - 1; 2954 glVertex2f (w - 1, h - 1);
2722 glVertex 0 , $self->{h} - 1; 2955 glVertex2f (0 , h - 1);
2723 glEnd; 2956 glEnd ();
2724 glPopMatrix; 2957 glPopMatrix ();
2725 #CFPlus::UI::Label->new (w => $self->{w}, h => $self->{h}, text => $self, fontsize => 0)->_draw;
2726 }
2727#endif 2958#endif
2728 PUSHMARK (SP); 2959 PUSHMARK (SP);
2729 XPUSHs (self); 2960 XPUSHs (self);
2730 PUTBACK; 2961 PUTBACK;
2731 call_method ("_draw", G_VOID | G_DISCARD); 2962 call_method ("_draw", G_VOID | G_DISCARD);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines