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.213 by root, Sun Jul 29 04:14:45 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>
109 av_push (texture_av, (SV *)(size_t)name); 114 av_push (texture_av, (SV *)(size_t)name);
110 glDeleteTextures (1, &name); 115 glDeleteTextures (1, &name);
111} 116}
112 117
113#include "texcache.c" 118#include "texcache.c"
119#include "rendercache.c"
114 120
115#include "pango-font.c" 121#include "pango-font.c"
116#include "pango-fontmap.c" 122#include "pango-fontmap.c"
117#include "pango-render.c" 123#include "pango-render.c"
118 124
144typedef struct cf_layout { 150typedef struct cf_layout {
145 PangoLayout *pl; 151 PangoLayout *pl;
146 float r, g, b, a; // default color for rgba mode 152 float r, g, b, a; // default color for rgba mode
147 int base_height; 153 int base_height;
148 CFPlus__Font font; 154 CFPlus__Font font;
155 rc_t *rc;
149} *CFPlus__Layout; 156} *CFPlus__Layout;
150 157
151static CFPlus__Font default_font; 158static CFPlus__Font default_font;
152static PangoContext *opengl_context; 159static PangoContext *opengl_context;
153static PangoFontMap *opengl_fontmap; 160static PangoFontMap *opengl_fontmap;
196 203
197typedef uint16_t tileid; 204typedef uint16_t tileid;
198typedef uint16_t faceid; 205typedef uint16_t faceid;
199 206
200typedef struct { 207typedef struct {
201 int name; 208 GLuint name;
202 int w, h; 209 int w, h;
203 float s, t; 210 float s, t;
204 uint8_t r, g, b, a; 211 uint8_t r, g, b, a;
205 tileid smoothtile; 212 tileid smoothtile;
206 uint8_t smoothlevel; 213 uint8_t smoothlevel;
431 n |= n >> 4; 438 n |= n >> 4;
432 n |= n >> 8; 439 n |= n >> 8;
433 n |= n >> 16; 440 n |= n >> 16;
434 441
435 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;
436} 454}
437 455
438/* SDL should provide this, really. */ 456/* SDL should provide this, really. */
439#define SDLK_MODIFIER_MIN 300 457#define SDLK_MODIFIER_MIN 300
440#define SDLK_MODIFIER_MAX 314 458#define SDLK_MODIFIER_MAX 314
518 536
519 const_iv (SDL_APPINPUTFOCUS), 537 const_iv (SDL_APPINPUTFOCUS),
520 const_iv (SDL_APPMOUSEFOCUS), 538 const_iv (SDL_APPMOUSEFOCUS),
521 const_iv (SDL_APPACTIVE), 539 const_iv (SDL_APPACTIVE),
522 540
541 const_iv (SDLK_FIRST),
542 const_iv (SDLK_LAST),
523 const_iv (SDLK_KP0), 543 const_iv (SDLK_KP0),
524 const_iv (SDLK_KP1), 544 const_iv (SDLK_KP1),
525 const_iv (SDLK_KP2), 545 const_iv (SDLK_KP2),
526 const_iv (SDLK_KP3), 546 const_iv (SDLK_KP3),
527 const_iv (SDLK_KP4), 547 const_iv (SDLK_KP4),
626 646
627NV floor (NV x) 647NV floor (NV x)
628 648
629NV ceil (NV x) 649NV ceil (NV x)
630 650
651IV minpot (UV n)
652
653IV popcount (UV n)
654
631void 655void
632pango_init () 656pango_init ()
633 CODE: 657 CODE:
634{ 658{
635 opengl_fontmap = pango_opengl_font_map_new (); 659 opengl_fontmap = pango_opengl_font_map_new ();
708 732
709 if (RETVAL) 733 if (RETVAL)
710 { 734 {
711 av_clear (texture_av); 735 av_clear (texture_av);
712 736
713 SDL_WM_SetCaption ("Crossfire+ Client " VERSION, "Crossfire+"); 737 SDL_WM_SetCaption ("Crossfire TRT Client " VERSION, "Crossfire TRT");
714#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);
715#include "glfunc.h" 739#include "glfunc.h"
716#undef GL_FUNC 740#undef GL_FUNC
717 } 741 }
718} 742}
804 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))));
805 } 829 }
806} 830}
807 831
808int 832int
809Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 4096) 833Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 1024)
810 POSTCALL: 834 POSTCALL:
811 Mix_HookMusicFinished (music_finished); 835 Mix_HookMusicFinished (music_finished);
812 Mix_ChannelFinished (channel_finished); 836 Mix_ChannelFinished (channel_finished);
813 837
814void 838void
815Mix_CloseAudio () 839Mix_CloseAudio ()
816 840
817int 841int
818Mix_AllocateChannels (int numchans = -1) 842Mix_AllocateChannels (int numchans = -1)
843
844const char *
845Mix_GetError ()
819 846
820void 847void
821lowdelay (int fd, int val = 1) 848lowdelay (int fd, int val = 1)
822 CODE: 849 CODE:
823 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&val, sizeof (val)); 850 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&val, sizeof (val));
1027 RETVAL->g = 1.; 1054 RETVAL->g = 1.;
1028 RETVAL->b = 1.; 1055 RETVAL->b = 1.;
1029 RETVAL->a = 1.; 1056 RETVAL->a = 1.;
1030 RETVAL->base_height = MIN_FONT_HEIGHT; 1057 RETVAL->base_height = MIN_FONT_HEIGHT;
1031 RETVAL->font = 0; 1058 RETVAL->font = 0;
1059 RETVAL->rc = rc_alloc ();
1032 1060
1033 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR); 1061 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
1034 layout_update_font (RETVAL); 1062 layout_update_font (RETVAL);
1035 OUTPUT: 1063 OUTPUT:
1036 RETVAL 1064 RETVAL
1037 1065
1038void 1066void
1039DESTROY (CFPlus::Layout self) 1067DESTROY (CFPlus::Layout self)
1040 CODE: 1068 CODE:
1041 g_object_unref (self->pl); 1069 g_object_unref (self->pl);
1070 rc_free (self->rc);
1042 Safefree (self); 1071 Safefree (self);
1043 1072
1044void 1073void
1045set_text (CFPlus::Layout self, SV *text_) 1074set_text (CFPlus::Layout self, SV *text_)
1046 CODE: 1075 CODE:
1298 } 1327 }
1299} 1328}
1300 1329
1301void 1330void
1302render (CFPlus::Layout self, float x, float y, int flags = 0) 1331render (CFPlus::Layout self, float x, float y, int flags = 0)
1303 PPCODE: 1332 CODE:
1333 rc_clear (self->rc);
1304 pango_opengl_render_layout_subpixel ( 1334 pango_opengl_render_layout_subpixel (
1305 self->pl, 1335 self->pl,
1336 self->rc,
1306 x * PANGO_SCALE, y * PANGO_SCALE, 1337 x * PANGO_SCALE, y * PANGO_SCALE,
1307 self->r, self->g, self->b, self->a, 1338 self->r, self->g, self->b, self->a,
1308 flags 1339 flags
1309 ); 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}
1310 1363
1311MODULE = CFPlus PACKAGE = CFPlus::Texture 1364MODULE = CFPlus PACKAGE = CFPlus::Texture
1312 1365
1313PROTOTYPES: ENABLE 1366PROTOTYPES: ENABLE
1314
1315int minpot (int n)
1316 1367
1317void 1368void
1318pad (SV *data_, int ow, int oh, int nw, int nh) 1369pad (SV *data_, int ow, int oh, int nw, int nh)
1319 CODE: 1370 CODE:
1320{ 1371{
1346{ 1397{
1347 HV *hv = (HV *)SvRV (self); 1398 HV *hv = (HV *)SvRV (self);
1348 float s = SvNV (*hv_fetch (hv, "s", 1, 1)); 1399 float s = SvNV (*hv_fetch (hv, "s", 1, 1));
1349 float t = SvNV (*hv_fetch (hv, "t", 1, 1)); 1400 float t = SvNV (*hv_fetch (hv, "t", 1, 1));
1350 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;
1351 1405
1352 if (items < 5) 1406 if (items < 5)
1353 { 1407 {
1354 w = SvNV (*hv_fetch (hv, "w", 1, 1)); 1408 w = SvNV (*hv_fetch (hv, "w", 1, 1));
1355 h = SvNV (*hv_fetch (hv, "h", 1, 1)); 1409 h = SvNV (*hv_fetch (hv, "h", 1, 1));
1544 self->rows += MAP_EXTEND_Y; 1598 self->rows += MAP_EXTEND_Y;
1545 self->y += MAP_EXTEND_Y; 1599 self->y += MAP_EXTEND_Y;
1546 } 1600 }
1547} 1601}
1548 1602
1549void 1603SV *
1550map1a_update (CFPlus::Map self, SV *data_, int extmap) 1604map1a_update (CFPlus::Map self, SV *data_, int extmap)
1551 CODE: 1605 CODE:
1552{ 1606{
1553 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_); 1607 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_);
1554 uint8_t *data_end = (uint8_t *)SvEND (data_); 1608 uint8_t *data_end = (uint8_t *)SvEND (data_);
1555 mapcell *cell; 1609 mapcell *cell;
1556 int x, y, flags; 1610 int x, y, z, flags;
1611 AV *missing = newAV ();
1612 RETVAL = newRV_noinc ((SV *)missing);
1557 1613
1558 while (data < data_end - 1) 1614 while (data < data_end - 1)
1559 { 1615 {
1560 flags = (data [0] << 8) + data [1]; data += 2; 1616 flags = (data [0] << 8) + data [1]; data += 2;
1561 1617
1612 } 1668 }
1613 else 1669 else
1614 cell->darkness = *data++ + 1; 1670 cell->darkness = *data++ + 1;
1615 } 1671 }
1616 1672
1673 for (z = 0; z <= 2; ++z)
1617 if (flags & 4) 1674 if (flags & (4 >> z))
1618 { 1675 {
1619 faceid face = (data [0] << 8) + data [1]; data += 2; 1676 faceid face = (data [0] << 8) + data [1]; data += 2;
1620 need_facenum (self, face); 1677 need_facenum (self, face);
1621 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 }
1622 } 1693 }
1623
1624 if (flags & 2)
1625 {
1626 faceid face = (data [0] << 8) + data [1]; data += 2;
1627 need_facenum (self, face);
1628 cell->tile [1] = self->face2tile [face];
1629 }
1630
1631 if (flags & 1)
1632 {
1633 faceid face = (data [0] << 8) + data [1]; data += 2;
1634 need_facenum (self, face);
1635 cell->tile [2] = self->face2tile [face];
1636 }
1637 } 1694 }
1638 else 1695 else
1639 cell->darkness = 0; 1696 cell->darkness = 0;
1640 } 1697 }
1641} 1698}
1699 OUTPUT:
1700 RETVAL
1642 1701
1643SV * 1702SV *
1644mapmap (CFPlus::Map self, int x0, int y0, int w, int h) 1703mapmap (CFPlus::Map self, int x0, int y0, int w, int h)
1645 CODE: 1704 CODE:
1646{ 1705{
1697 1756
1698void 1757void
1699draw (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)
1700 CODE: 1759 CODE:
1701{ 1760{
1761 int x, y, z;
1762
1702 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ()); 1763 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
1703 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
1704 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)
1705 smooth_key skey; 1766 smooth_key skey;
1706 int x, y, z; 1767
1707 int last_name; 1768 rc_t *rc = rc_alloc ();
1769 rc_key_t key;
1770 rc_array_t *arr;
1708 1771
1709 // thats current max. sorry. 1772 // thats current max. sorry.
1710 if (sw > 255) sw = 255; 1773 if (sw > 255) sw = 255;
1711 if (sh > 255) sh = 255; 1774 if (sh > 255) sh = 255;
1712 1775
1713 // clear key, in case of extra padding 1776 // clear key, in case of extra padding
1714 memset (&skey, 0, sizeof (skey)); 1777 memset (&skey, 0, sizeof (skey));
1715 1778
1716 glColor4ub (255, 255, 255, 255); 1779 memset (&key, 0, sizeof (key));
1717 1780 key.r = 255;
1718 glEnable (GL_BLEND); 1781 key.g = 255;
1719 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1782 key.b = 255;
1720 glEnable (GL_TEXTURE_2D); 1783 key.a = 255;
1721 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1784 key.mode = GL_QUADS;
1722 1785 key.format = GL_T2F_V3F;
1723 glBegin (GL_QUADS); 1786 key.texname = -1;
1724
1725 last_name = 0;
1726 1787
1727 mx += self->x; 1788 mx += self->x;
1728 my += self->y; 1789 my += self->y;
1729 1790
1730 // first pass: determine smooth_max 1791 // first pass: determine smooth_max
1746 MAX (self->tex [cell->tile [0]].smoothlevel, 1807 MAX (self->tex [cell->tile [0]].smoothlevel,
1747 MAX (self->tex [cell->tile [1]].smoothlevel, 1808 MAX (self->tex [cell->tile [1]].smoothlevel,
1748 self->tex [cell->tile [2]].smoothlevel)); 1809 self->tex [cell->tile [2]].smoothlevel));
1749 } 1810 }
1750 } 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);
1751 1816
1752 for (z = 0; z <= 2; z++) 1817 for (z = 0; z <= 2; z++)
1753 { 1818 {
1754 memset (smooth_level, 0, sizeof (smooth_level)); 1819 memset (smooth_level, 0, sizeof (smooth_level));
1755 1820
1765 tileid tile = cell->tile [z]; 1830 tileid tile = cell->tile [z];
1766 1831
1767 if (tile) 1832 if (tile)
1768 { 1833 {
1769 maptex tex = self->tex [tile]; 1834 maptex tex = self->tex [tile];
1770 int px = (x + 1) * T - tex.w; 1835 int px, py;
1771 int py = (y + 1) * T - tex.h;
1772 1836
1773 // suppressing texture state switches here
1774 // is only moderately effective, but worth the extra effort
1775 if (last_name != tex.name) 1837 if (key.texname != tex.name)
1776 { 1838 {
1777 if (!tex.name) 1839 if (!tex.name)
1778 tex = self->tex [2]; /* missing, replace by noface */ 1840 tex = self->tex [2]; /* missing, replace by noface */
1779 1841
1780 glEnd (); 1842 key.texname = tex.name;
1781 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1843 arr = rc_array (rc, &key);
1782 glBegin (GL_QUADS);
1783 } 1844 }
1784 1845
1785 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);
1786 glTexCoord2f (0 , tex.t); glVertex2f (px , py + tex.h); 1850 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0);
1787 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);
1788 glTexCoord2f (tex.s, 0 ); glVertex2f (px + tex.w, py ); 1852 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0);
1789 1853
1790 if (cell->flags && z == 2) 1854 if (cell->flags && z == 2)
1791 { 1855 {
1856 // overlays such as the speech bubble, probably more to come
1792 if (cell->flags & 1) 1857 if (cell->flags & 1)
1793 { 1858 {
1794 maptex tex = self->tex [1]; 1859 maptex tex = self->tex [1];
1795 int px = x * T + T * 2 / 32; 1860 int px = x * T + T * 2 / 32;
1796 int py = y * T - T * 6 / 32; 1861 int py = y * T - T * 6 / 32;
1797 1862
1863 if (tex.name)
1798 glEnd (); 1864 {
1799 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);
1800 glBegin (GL_QUADS); 1875 }
1801
1802 glTexCoord2f (0 , 0 ); glVertex2f (px , py );
1803 glTexCoord2f (0 , tex.t); glVertex2f (px , py + T);
1804 glTexCoord2f (tex.s, tex.t); glVertex2f (px + T, py + T);
1805 glTexCoord2f (tex.s, 0 ); glVertex2f (px + T, py );
1806 } 1876 }
1807 } 1877 }
1808 1878
1809 // update smooth hash 1879 // update smooth hash
1810 if (tex.smoothtile) 1880 if (tex.smoothtile)
1846 } 1916 }
1847 } 1917 }
1848 } 1918 }
1849 } 1919 }
1850 1920
1921 rc_draw (rc);
1922 rc_clear (rc);
1923
1851 // go through all smoothlevels, lowest to highest, then draw. 1924 // go through all smoothlevels, lowest to highest, then draw.
1852 // this is basically counting sort 1925 // this is basically counting sort
1853 { 1926 {
1854 int w, b; 1927 int w, b;
1855 1928
1929 glEnable (GL_TEXTURE_2D);
1930 glBegin (GL_QUADS);
1856 for (w = 0; w < 256 / 32; ++w) 1931 for (w = 0; w < 256 / 32; ++w)
1857 { 1932 {
1858 uint32_t smask = smooth_level [w]; 1933 uint32_t smask = smooth_level [w];
1859 if (smask) 1934 if (smask)
1860 for (b = 0; b < 32; ++b) 1935 for (b = 0; b < 32; ++b)
1879 int border = bits & 15; 1954 int border = bits & 15;
1880 int corner = (bits >> 8) & ~(bits >> 4) & 15; 1955 int corner = (bits >> 8) & ~(bits >> 4) & 15;
1881 float dx = tex.s * .0625f; // 16 images/row 1956 float dx = tex.s * .0625f; // 16 images/row
1882 float dy = tex.t * .5f ; // 2 images/column 1957 float dy = tex.t * .5f ; // 2 images/column
1883 1958
1884 // this time naively avoiding texture state changes
1885 // save gobs of state changes.
1886 if (last_name != tex.name) 1959 if (tex.name)
1887 { 1960 {
1961 // this time avoiding texture state changes
1962 // save gobs of state changes.
1888 if (!tex.name) 1963 if (key.texname != tex.name)
1889 continue; // smoothing not yet available 1964 {
1890
1891 glEnd (); 1965 glEnd ();
1892 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1966 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name);
1893 glBegin (GL_QUADS); 1967 glBegin (GL_QUADS);
1894 } 1968 }
1895 1969
1896 if (border) 1970 if (border)
1897 { 1971 {
1898 float ox = border * dx; 1972 float ox = border * dx;
1899 1973
1900 glTexCoord2f (ox , 0.f ); glVertex2f (px , py ); 1974 glTexCoord2f (ox , 0.f ); glVertex2i (px , py );
1901 glTexCoord2f (ox , dy ); glVertex2f (px , py + T); 1975 glTexCoord2f (ox , dy ); glVertex2i (px , py + T);
1902 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py + T); 1976 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py + T);
1903 glTexCoord2f (ox + dx, 0.f ); glVertex2f (px + T, py ); 1977 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + T, py );
1904 } 1978 }
1905 1979
1906 if (corner) 1980 if (corner)
1907 { 1981 {
1908 float ox = corner * dx; 1982 float ox = corner * dx;
1909 1983
1910 glTexCoord2f (ox , dy ); glVertex2f (px , py ); 1984 glTexCoord2f (ox , dy ); glVertex2i (px , py );
1911 glTexCoord2f (ox , dy * 2.f); glVertex2f (px , py + T); 1985 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + T);
1912 glTexCoord2f (ox + dx, dy * 2.f); glVertex2f (px + T, py + T); 1986 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + T, py + T);
1913 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py ); 1987 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py );
1988 }
1914 } 1989 }
1915 } 1990 }
1916 } 1991 }
1917 } 1992 }
1918 } 1993 }
1994
1995 glEnd ();
1996 glDisable (GL_TEXTURE_2D);
1997 key.texname = -1;
1919 } 1998 }
1920 1999
1921 hv_clear (smooth); 2000 hv_clear (smooth);
1922 } 2001 }
1923 2002
1924 glEnd ();
1925
1926 glDisable (GL_TEXTURE_2D);
1927 glDisable (GL_BLEND); 2003 glDisable (GL_BLEND);
2004 rc_free (rc);
1928 2005
1929 // top layer: overlays such as the health bar 2006 // top layer: overlays such as the health bar
1930 for (y = 0; y < sh; y++) 2007 for (y = 0; y < sh; y++)
1931 if (0 <= y + my && y + my < self->rows) 2008 if (0 <= y + my && y + my < self->rows)
1932 { 2009 {
2181 int x, y, z; 2258 int x, y, z;
2182 int w, h; 2259 int w, h;
2183 int x1, y1; 2260 int x1, y1;
2184 2261
2185 if (*data++ != 0) 2262 if (*data++ != 0)
2186 return; /* version mismatch */ 2263 XSRETURN_EMPTY; /* version mismatch */
2187 2264
2188 w = *data++ << 8; w |= *data++; 2265 w = *data++ << 8; w |= *data++;
2189 h = *data++ << 8; h |= *data++; 2266 h = *data++ << 8; h |= *data++;
2190 2267
2191 // 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
2257 CODE: 2334 CODE:
2258 RETVAL = SDL_RWFromFile (path, mode); 2335 RETVAL = SDL_RWFromFile (path, mode);
2259 OUTPUT: 2336 OUTPUT:
2260 RETVAL 2337 RETVAL
2261 2338
2339# fails on win32:
2340# CFPlus.xs(2268) : error C2059: syntax error : '('
2262void 2341#void
2263close (CFPlus::RW self) 2342#close (CFPlus::RW self)
2264 CODE: 2343# CODE:
2265 SDL_RWclose (self); 2344# (self->(close)) (self);
2266 2345
2267MODULE = CFPlus PACKAGE = CFPlus::Channel 2346MODULE = CFPlus PACKAGE = CFPlus::Channel
2268 2347
2269PROTOTYPES: DISABLE 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
2270 2371
2271void 2372void
2272halt (CFPlus::Channel self) 2373halt (CFPlus::Channel self)
2273 CODE: 2374 CODE:
2274 Mix_HaltChannel (self); 2375 Mix_HaltChannel (self);
2284 Mix_FadeOutChannel (self, ticks); 2385 Mix_FadeOutChannel (self, ticks);
2285 2386
2286int 2387int
2287volume (CFPlus::Channel self, int volume) 2388volume (CFPlus::Channel self, int volume)
2288 CODE: 2389 CODE:
2289 RETVAL = Mix_Volume (self, volume); 2390 RETVAL = Mix_Volume (self, CLAMP (volume, 0, 128));
2290 OUTPUT: 2391 OUTPUT:
2291 RETVAL 2392 RETVAL
2292 2393
2293void 2394void
2294unregister_all_effects (CFPlus::Channel self) 2395unregister_all_effects (CFPlus::Channel self)
2296 Mix_UnregisterAllEffects (self); 2397 Mix_UnregisterAllEffects (self);
2297 2398
2298void 2399void
2299set_panning (CFPlus::Channel self, int left, int right) 2400set_panning (CFPlus::Channel self, int left, int right)
2300 CODE: 2401 CODE:
2402 left = CLAMP (left , 0, 255);
2403 right = CLAMP (right, 0, 255);
2301 Mix_SetPanning (self, left, right); 2404 Mix_SetPanning (self, left, right);
2302 2405
2303void 2406void
2304set_distance (CFPlus::Channel self, int distance) 2407set_distance (CFPlus::Channel self, int distance)
2305 CODE: 2408 CODE:
2306 Mix_SetDistance (self, distance); 2409 Mix_SetDistance (self, CLAMP (distance, 0, 255));
2307 2410
2308void 2411void
2309set_position (CFPlus::Channel self, int angle, int distance) 2412set_position (CFPlus::Channel self, int angle, int distance)
2310 CODE: 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);
2311 Mix_SetPosition (self, angle, distance); 2421 Mix_SetPosition (self, angle, CLAMP (distance, 0, 255));
2422}
2312 2423
2313void 2424void
2314set_reverse_stereo (CFPlus::Channel self, int flip) 2425set_reverse_stereo (CFPlus::Channel self, int flip)
2315 CODE: 2426 CODE:
2316 Mix_SetReverseStereo (self, flip); 2427 Mix_SetReverseStereo (self, flip);
2332 Mix_FreeChunk (self); 2443 Mix_FreeChunk (self);
2333 2444
2334int 2445int
2335volume (CFPlus::MixChunk self, int volume = -1) 2446volume (CFPlus::MixChunk self, int volume = -1)
2336 CODE: 2447 CODE:
2448 if (items > 1)
2449 volume = CLAMP (volume, 0, 128);
2337 RETVAL = Mix_VolumeChunk (self, volume); 2450 RETVAL = Mix_VolumeChunk (self, volume);
2338 OUTPUT: 2451 OUTPUT:
2339 RETVAL 2452 RETVAL
2340 2453
2341CFPlus::Channel 2454CFPlus::Channel
2342play (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)
2343 CODE: 2456 CODE:
2457{
2344 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 {
2345 Mix_UnregisterAllEffects (RETVAL); 2465 Mix_UnregisterAllEffects (RETVAL);
2466 Mix_Volume (RETVAL, 128);
2467 }
2468}
2346 OUTPUT: 2469 OUTPUT:
2347 RETVAL 2470 RETVAL
2348 2471
2349MODULE = CFPlus PACKAGE = CFPlus::MixMusic 2472MODULE = CFPlus PACKAGE = CFPlus::MixMusic
2350 2473
2351int 2474int
2352volume (int volume = -1) 2475volume (int volume = -1)
2353 PROTOTYPE: ;$ 2476 PROTOTYPE: ;$
2354 CODE: 2477 CODE:
2478 if (items > 0)
2479 volume = CLAMP (volume, 0, 128);
2355 RETVAL = Mix_VolumeMusic (volume); 2480 RETVAL = Mix_VolumeMusic (volume);
2356 OUTPUT: 2481 OUTPUT:
2357 RETVAL 2482 RETVAL
2358 2483
2359void 2484void
2439 const_iv (GL_INTENSITY), 2564 const_iv (GL_INTENSITY),
2440 const_iv (GL_LUMINANCE), 2565 const_iv (GL_LUMINANCE),
2441 const_iv (GL_LUMINANCE_ALPHA), 2566 const_iv (GL_LUMINANCE_ALPHA),
2442 const_iv (GL_FLOAT), 2567 const_iv (GL_FLOAT),
2443 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),
2444 const_iv (GL_COMPILE), 2575 const_iv (GL_COMPILE),
2445 const_iv (GL_PROXY_TEXTURE_1D), 2576 const_iv (GL_PROXY_TEXTURE_1D),
2446 const_iv (GL_PROXY_TEXTURE_2D), 2577 const_iv (GL_PROXY_TEXTURE_2D),
2447 const_iv (GL_TEXTURE_1D), 2578 const_iv (GL_TEXTURE_1D),
2448 const_iv (GL_TEXTURE_2D), 2579 const_iv (GL_TEXTURE_2D),
2487 const_iv (GL_PERSPECTIVE_CORRECTION_HINT), 2618 const_iv (GL_PERSPECTIVE_CORRECTION_HINT),
2488 const_iv (GL_POINT_SMOOTH_HINT), 2619 const_iv (GL_POINT_SMOOTH_HINT),
2489 const_iv (GL_LINE_SMOOTH_HINT), 2620 const_iv (GL_LINE_SMOOTH_HINT),
2490 const_iv (GL_POLYGON_SMOOTH_HINT), 2621 const_iv (GL_POLYGON_SMOOTH_HINT),
2491 const_iv (GL_GENERATE_MIPMAP_HINT), 2622 const_iv (GL_GENERATE_MIPMAP_HINT),
2623 const_iv (GL_TEXTURE_COMPRESSION_HINT),
2492 const_iv (GL_FASTEST), 2624 const_iv (GL_FASTEST),
2493 const_iv (GL_DONT_CARE), 2625 const_iv (GL_DONT_CARE),
2494 const_iv (GL_NICEST), 2626 const_iv (GL_NICEST),
2495 const_iv (GL_V2F), 2627 const_iv (GL_V2F),
2496 const_iv (GL_V3F), 2628 const_iv (GL_V3F),
2504 2636
2505 texture_av = newAV (); 2637 texture_av = newAV ();
2506 AvREAL_off (texture_av); 2638 AvREAL_off (texture_av);
2507} 2639}
2508 2640
2641void
2642disable_GL_EXT_blend_func_separate ()
2643 CODE:
2644 gl.BlendFuncSeparate = 0;
2645 gl.BlendFuncSeparateEXT = 0;
2646
2509char * 2647char *
2510gl_vendor () 2648gl_vendor ()
2511 CODE: 2649 CODE:
2512 RETVAL = (char *)glGetString (GL_VENDOR); 2650 RETVAL = (char *)glGetString (GL_VENDOR);
2513 OUTPUT: 2651 OUTPUT:
2634 2772
2635void glRect (float x1, float y1, float x2, float y2) 2773void glRect (float x1, float y1, float x2, float y2)
2636 CODE: 2774 CODE:
2637 glRectf (x1, y1, x2, y2); 2775 glRectf (x1, y1, x2, y2);
2638 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
2639PROTOTYPES: ENABLE 2786PROTOTYPES: ENABLE
2640 2787
2641void glBegin (int mode) 2788void glBegin (int mode)
2642 2789
2643void glEnd () 2790void glEnd ()
2744 NV x, y, w, h; 2891 NV x, y, w, h;
2745 SV *draw_x_sv = GvSV (draw_x_gv); 2892 SV *draw_x_sv = GvSV (draw_x_gv);
2746 SV *draw_y_sv = GvSV (draw_y_gv); 2893 SV *draw_y_sv = GvSV (draw_y_gv);
2747 SV *draw_w_sv = GvSV (draw_w_gv); 2894 SV *draw_w_sv = GvSV (draw_w_gv);
2748 SV *draw_h_sv = GvSV (draw_h_gv); 2895 SV *draw_h_sv = GvSV (draw_h_gv);
2749 SV *hover;
2750 double draw_x, draw_y, draw_w, draw_h; 2896 double draw_x, draw_y;
2751 2897
2752 if (!SvROK (self)) 2898 if (!SvROK (self))
2753 croak ("CFPlus::Base::draw: %s not a reference", SvPV_nolen (self)); 2899 croak ("CFPlus::Base::draw: %s not a reference", SvPV_nolen (self));
2754 2900
2755 hv = (HV *)SvRV (self); 2901 hv = (HV *)SvRV (self);
2783 { 2929 {
2784 svp = hv_fetch (hv, "can_hover", sizeof ("can_hover") - 1, 0); 2930 svp = hv_fetch (hv, "can_hover", sizeof ("can_hover") - 1, 0);
2785 2931
2786 if (svp && SvTRUE (*svp)) 2932 if (svp && SvTRUE (*svp))
2787 { 2933 {
2788 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);
2789 glEnable (GL_BLEND); 2935 glEnable (GL_BLEND);
2790 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 2936 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
2791 glBegin (GL_QUADS); 2937 glBegin (GL_QUADS);
2792 glVertex2f (0, 0); 2938 glVertex2f (0, 0);
2793 glVertex2f (w, 0); 2939 glVertex2f (w, 0);
2796 glEnd (); 2942 glEnd ();
2797 glDisable (GL_BLEND); 2943 glDisable (GL_BLEND);
2798 } 2944 }
2799 } 2945 }
2800#if 0 2946#if 0
2801 if ($ENV{CFPLUS_DEBUG} & 1) { 2947 // draw borders, for debugging
2802 glPushMatrix; 2948 glPushMatrix ();
2803 glColor 1, 1, 0, 1; 2949 glColor4f (1., 1., 0., 1.);
2804 glTranslate 0.375, 0.375; 2950 glTranslatef (.5, .5, 0.);
2805 glBegin GL_LINE_LOOP; 2951 glBegin (GL_LINE_LOOP);
2806 glVertex 0 , 0; 2952 glVertex2f (0 , 0);
2807 glVertex $self->{w} - 1, 0; 2953 glVertex2f (w - 1, 0);
2808 glVertex $self->{w} - 1, $self->{h} - 1; 2954 glVertex2f (w - 1, h - 1);
2809 glVertex 0 , $self->{h} - 1; 2955 glVertex2f (0 , h - 1);
2810 glEnd; 2956 glEnd ();
2811 glPopMatrix; 2957 glPopMatrix ();
2812 #CFPlus::UI::Label->new (w => $self->{w}, h => $self->{h}, text => $self, fontsize => 0)->_draw;
2813 }
2814#endif 2958#endif
2815 PUSHMARK (SP); 2959 PUSHMARK (SP);
2816 XPUSHs (self); 2960 XPUSHs (self);
2817 PUTBACK; 2961 PUTBACK;
2818 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