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.215 by root, Tue Jul 31 00:50:04 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
1030 RETVAL->g = 1.; 1054 RETVAL->g = 1.;
1031 RETVAL->b = 1.; 1055 RETVAL->b = 1.;
1032 RETVAL->a = 1.; 1056 RETVAL->a = 1.;
1033 RETVAL->base_height = MIN_FONT_HEIGHT; 1057 RETVAL->base_height = MIN_FONT_HEIGHT;
1034 RETVAL->font = 0; 1058 RETVAL->font = 0;
1059 RETVAL->rc = rc_alloc ();
1035 1060
1036 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR); 1061 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
1037 layout_update_font (RETVAL); 1062 layout_update_font (RETVAL);
1038 OUTPUT: 1063 OUTPUT:
1039 RETVAL 1064 RETVAL
1040 1065
1041void 1066void
1042DESTROY (CFPlus::Layout self) 1067DESTROY (CFPlus::Layout self)
1043 CODE: 1068 CODE:
1044 g_object_unref (self->pl); 1069 g_object_unref (self->pl);
1070 rc_free (self->rc);
1045 Safefree (self); 1071 Safefree (self);
1046 1072
1047void 1073void
1048set_text (CFPlus::Layout self, SV *text_) 1074set_text (CFPlus::Layout self, SV *text_)
1049 CODE: 1075 CODE:
1301 } 1327 }
1302} 1328}
1303 1329
1304void 1330void
1305render (CFPlus::Layout self, float x, float y, int flags = 0) 1331render (CFPlus::Layout self, float x, float y, int flags = 0)
1306 PPCODE: 1332 CODE:
1333 rc_clear (self->rc);
1307 pango_opengl_render_layout_subpixel ( 1334 pango_opengl_render_layout_subpixel (
1308 self->pl, 1335 self->pl,
1336 self->rc,
1309 x * PANGO_SCALE, y * PANGO_SCALE, 1337 x * PANGO_SCALE, y * PANGO_SCALE,
1310 self->r, self->g, self->b, self->a, 1338 self->r, self->g, self->b, self->a,
1311 flags 1339 flags
1312 ); 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}
1313 1363
1314MODULE = CFPlus PACKAGE = CFPlus::Texture 1364MODULE = CFPlus PACKAGE = CFPlus::Texture
1315 1365
1316PROTOTYPES: ENABLE 1366PROTOTYPES: ENABLE
1317
1318int minpot (int n)
1319 1367
1320void 1368void
1321pad (SV *data_, int ow, int oh, int nw, int nh) 1369pad (SV *data_, int ow, int oh, int nw, int nh)
1322 CODE: 1370 CODE:
1323{ 1371{
1349{ 1397{
1350 HV *hv = (HV *)SvRV (self); 1398 HV *hv = (HV *)SvRV (self);
1351 float s = SvNV (*hv_fetch (hv, "s", 1, 1)); 1399 float s = SvNV (*hv_fetch (hv, "s", 1, 1));
1352 float t = SvNV (*hv_fetch (hv, "t", 1, 1)); 1400 float t = SvNV (*hv_fetch (hv, "t", 1, 1));
1353 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;
1354 1405
1355 if (items < 5) 1406 if (items < 5)
1356 { 1407 {
1357 w = SvNV (*hv_fetch (hv, "w", 1, 1)); 1408 w = SvNV (*hv_fetch (hv, "w", 1, 1));
1358 h = SvNV (*hv_fetch (hv, "h", 1, 1)); 1409 h = SvNV (*hv_fetch (hv, "h", 1, 1));
1547 self->rows += MAP_EXTEND_Y; 1598 self->rows += MAP_EXTEND_Y;
1548 self->y += MAP_EXTEND_Y; 1599 self->y += MAP_EXTEND_Y;
1549 } 1600 }
1550} 1601}
1551 1602
1552void 1603SV *
1553map1a_update (CFPlus::Map self, SV *data_, int extmap) 1604map1a_update (CFPlus::Map self, SV *data_, int extmap)
1554 CODE: 1605 CODE:
1555{ 1606{
1556 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_); 1607 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_);
1557 uint8_t *data_end = (uint8_t *)SvEND (data_); 1608 uint8_t *data_end = (uint8_t *)SvEND (data_);
1558 mapcell *cell; 1609 mapcell *cell;
1559 int x, y, flags; 1610 int x, y, z, flags;
1611 AV *missing = newAV ();
1612 RETVAL = newRV_noinc ((SV *)missing);
1560 1613
1561 while (data < data_end - 1) 1614 while (data < data_end - 1)
1562 { 1615 {
1563 flags = (data [0] << 8) + data [1]; data += 2; 1616 flags = (data [0] << 8) + data [1]; data += 2;
1564 1617
1615 } 1668 }
1616 else 1669 else
1617 cell->darkness = *data++ + 1; 1670 cell->darkness = *data++ + 1;
1618 } 1671 }
1619 1672
1673 for (z = 0; z <= 2; ++z)
1620 if (flags & 4) 1674 if (flags & (4 >> z))
1621 { 1675 {
1622 faceid face = (data [0] << 8) + data [1]; data += 2; 1676 faceid face = (data [0] << 8) + data [1]; data += 2;
1623 need_facenum (self, face); 1677 need_facenum (self, face);
1624 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 }
1625 } 1693 }
1626
1627 if (flags & 2)
1628 {
1629 faceid face = (data [0] << 8) + data [1]; data += 2;
1630 need_facenum (self, face);
1631 cell->tile [1] = self->face2tile [face];
1632 }
1633
1634 if (flags & 1)
1635 {
1636 faceid face = (data [0] << 8) + data [1]; data += 2;
1637 need_facenum (self, face);
1638 cell->tile [2] = self->face2tile [face];
1639 }
1640 } 1694 }
1641 else 1695 else
1642 cell->darkness = 0; 1696 cell->darkness = 0;
1643 } 1697 }
1644} 1698}
1699 OUTPUT:
1700 RETVAL
1645 1701
1646SV * 1702SV *
1647mapmap (CFPlus::Map self, int x0, int y0, int w, int h) 1703mapmap (CFPlus::Map self, int x0, int y0, int w, int h)
1648 CODE: 1704 CODE:
1649{ 1705{
1700 1756
1701void 1757void
1702draw (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)
1703 CODE: 1759 CODE:
1704{ 1760{
1761 int x, y, z;
1762
1705 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ()); 1763 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
1706 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
1707 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)
1708 smooth_key skey; 1766 smooth_key skey;
1709 int x, y, z; 1767
1710 int last_name; 1768 rc_t *rc = rc_alloc ();
1769 rc_key_t key;
1770 rc_array_t *arr;
1711 1771
1712 // thats current max. sorry. 1772 // thats current max. sorry.
1713 if (sw > 255) sw = 255; 1773 if (sw > 255) sw = 255;
1714 if (sh > 255) sh = 255; 1774 if (sh > 255) sh = 255;
1715 1775
1716 // clear key, in case of extra padding 1776 // clear key, in case of extra padding
1717 memset (&skey, 0, sizeof (skey)); 1777 memset (&skey, 0, sizeof (skey));
1718 1778
1719 glColor4ub (255, 255, 255, 255); 1779 memset (&key, 0, sizeof (key));
1720 1780 key.r = 255;
1721 glEnable (GL_BLEND); 1781 key.g = 255;
1722 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1782 key.b = 255;
1723 glEnable (GL_TEXTURE_2D); 1783 key.a = 255;
1724 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1784 key.mode = GL_QUADS;
1725 1785 key.format = GL_T2F_V3F;
1726 glBegin (GL_QUADS); 1786 key.texname = -1;
1727
1728 last_name = 0;
1729 1787
1730 mx += self->x; 1788 mx += self->x;
1731 my += self->y; 1789 my += self->y;
1732 1790
1733 // first pass: determine smooth_max 1791 // first pass: determine smooth_max
1749 MAX (self->tex [cell->tile [0]].smoothlevel, 1807 MAX (self->tex [cell->tile [0]].smoothlevel,
1750 MAX (self->tex [cell->tile [1]].smoothlevel, 1808 MAX (self->tex [cell->tile [1]].smoothlevel,
1751 self->tex [cell->tile [2]].smoothlevel)); 1809 self->tex [cell->tile [2]].smoothlevel));
1752 } 1810 }
1753 } 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);
1754 1816
1755 for (z = 0; z <= 2; z++) 1817 for (z = 0; z <= 2; z++)
1756 { 1818 {
1757 memset (smooth_level, 0, sizeof (smooth_level)); 1819 memset (smooth_level, 0, sizeof (smooth_level));
1758 1820
1768 tileid tile = cell->tile [z]; 1830 tileid tile = cell->tile [z];
1769 1831
1770 if (tile) 1832 if (tile)
1771 { 1833 {
1772 maptex tex = self->tex [tile]; 1834 maptex tex = self->tex [tile];
1773 int px = (x + 1) * T - tex.w; 1835 int px, py;
1774 int py = (y + 1) * T - tex.h;
1775 1836
1776 // suppressing texture state switches here
1777 // is only moderately effective, but worth the extra effort
1778 if (last_name != tex.name) 1837 if (key.texname != tex.name)
1779 { 1838 {
1780 if (!tex.name) 1839 if (!tex.name)
1781 tex = self->tex [2]; /* missing, replace by noface */ 1840 tex = self->tex [2]; /* missing, replace by noface */
1782 1841
1783 glEnd (); 1842 key.texname = tex.name;
1784 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1843 arr = rc_array (rc, &key);
1785 glBegin (GL_QUADS);
1786 } 1844 }
1787 1845
1788 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);
1789 glTexCoord2f (0 , tex.t); glVertex2f (px , py + tex.h); 1850 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0);
1790 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);
1791 glTexCoord2f (tex.s, 0 ); glVertex2f (px + tex.w, py ); 1852 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0);
1792 1853
1793 if (cell->flags && z == 2) 1854 if (cell->flags && z == 2)
1794 { 1855 {
1856 // overlays such as the speech bubble, probably more to come
1795 if (cell->flags & 1) 1857 if (cell->flags & 1)
1796 { 1858 {
1797 maptex tex = self->tex [1]; 1859 maptex tex = self->tex [1];
1798 int px = x * T + T * 2 / 32; 1860 int px = x * T + T * 2 / 32;
1799 int py = y * T - T * 6 / 32; 1861 int py = y * T - T * 6 / 32;
1800 1862
1863 if (tex.name)
1801 glEnd (); 1864 {
1802 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);
1803 glBegin (GL_QUADS); 1875 }
1804
1805 glTexCoord2f (0 , 0 ); glVertex2f (px , py );
1806 glTexCoord2f (0 , tex.t); glVertex2f (px , py + T);
1807 glTexCoord2f (tex.s, tex.t); glVertex2f (px + T, py + T);
1808 glTexCoord2f (tex.s, 0 ); glVertex2f (px + T, py );
1809 } 1876 }
1810 } 1877 }
1811 1878
1812 // update smooth hash 1879 // update smooth hash
1813 if (tex.smoothtile) 1880 if (tex.smoothtile)
1849 } 1916 }
1850 } 1917 }
1851 } 1918 }
1852 } 1919 }
1853 1920
1921 rc_draw (rc);
1922 rc_clear (rc);
1923
1854 // go through all smoothlevels, lowest to highest, then draw. 1924 // go through all smoothlevels, lowest to highest, then draw.
1855 // this is basically counting sort 1925 // this is basically counting sort
1856 { 1926 {
1857 int w, b; 1927 int w, b;
1858 1928
1929 glEnable (GL_TEXTURE_2D);
1930 glBegin (GL_QUADS);
1859 for (w = 0; w < 256 / 32; ++w) 1931 for (w = 0; w < 256 / 32; ++w)
1860 { 1932 {
1861 uint32_t smask = smooth_level [w]; 1933 uint32_t smask = smooth_level [w];
1862 if (smask) 1934 if (smask)
1863 for (b = 0; b < 32; ++b) 1935 for (b = 0; b < 32; ++b)
1882 int border = bits & 15; 1954 int border = bits & 15;
1883 int corner = (bits >> 8) & ~(bits >> 4) & 15; 1955 int corner = (bits >> 8) & ~(bits >> 4) & 15;
1884 float dx = tex.s * .0625f; // 16 images/row 1956 float dx = tex.s * .0625f; // 16 images/row
1885 float dy = tex.t * .5f ; // 2 images/column 1957 float dy = tex.t * .5f ; // 2 images/column
1886 1958
1887 // this time naively avoiding texture state changes
1888 // save gobs of state changes.
1889 if (last_name != tex.name) 1959 if (tex.name)
1890 { 1960 {
1961 // this time avoiding texture state changes
1962 // save gobs of state changes.
1891 if (!tex.name) 1963 if (key.texname != tex.name)
1892 continue; // smoothing not yet available 1964 {
1893
1894 glEnd (); 1965 glEnd ();
1895 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1966 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name);
1896 glBegin (GL_QUADS); 1967 glBegin (GL_QUADS);
1897 } 1968 }
1898 1969
1899 if (border) 1970 if (border)
1900 { 1971 {
1901 float ox = border * dx; 1972 float ox = border * dx;
1902 1973
1903 glTexCoord2f (ox , 0.f ); glVertex2f (px , py ); 1974 glTexCoord2f (ox , 0.f ); glVertex2i (px , py );
1904 glTexCoord2f (ox , dy ); glVertex2f (px , py + T); 1975 glTexCoord2f (ox , dy ); glVertex2i (px , py + T);
1905 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py + T); 1976 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py + T);
1906 glTexCoord2f (ox + dx, 0.f ); glVertex2f (px + T, py ); 1977 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + T, py );
1907 } 1978 }
1908 1979
1909 if (corner) 1980 if (corner)
1910 { 1981 {
1911 float ox = corner * dx; 1982 float ox = corner * dx;
1912 1983
1913 glTexCoord2f (ox , dy ); glVertex2f (px , py ); 1984 glTexCoord2f (ox , dy ); glVertex2i (px , py );
1914 glTexCoord2f (ox , dy * 2.f); glVertex2f (px , py + T); 1985 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + T);
1915 glTexCoord2f (ox + dx, dy * 2.f); glVertex2f (px + T, py + T); 1986 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + T, py + T);
1916 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py ); 1987 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py );
1988 }
1917 } 1989 }
1918 } 1990 }
1919 } 1991 }
1920 } 1992 }
1921 } 1993 }
1994
1995 glEnd ();
1996 glDisable (GL_TEXTURE_2D);
1997 key.texname = -1;
1922 } 1998 }
1923 1999
1924 hv_clear (smooth); 2000 hv_clear (smooth);
1925 } 2001 }
1926 2002
1927 glEnd ();
1928
1929 glDisable (GL_TEXTURE_2D);
1930 glDisable (GL_BLEND); 2003 glDisable (GL_BLEND);
2004 rc_free (rc);
1931 2005
1932 // top layer: overlays such as the health bar 2006 // top layer: overlays such as the health bar
1933 for (y = 0; y < sh; y++) 2007 for (y = 0; y < sh; y++)
1934 if (0 <= y + my && y + my < self->rows) 2008 if (0 <= y + my && y + my < self->rows)
1935 { 2009 {
2184 int x, y, z; 2258 int x, y, z;
2185 int w, h; 2259 int w, h;
2186 int x1, y1; 2260 int x1, y1;
2187 2261
2188 if (*data++ != 0) 2262 if (*data++ != 0)
2189 return; /* version mismatch */ 2263 XSRETURN_EMPTY; /* version mismatch */
2190 2264
2191 w = *data++ << 8; w |= *data++; 2265 w = *data++ << 8; w |= *data++;
2192 h = *data++ << 8; h |= *data++; 2266 h = *data++ << 8; h |= *data++;
2193 2267
2194 // 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
2260 CODE: 2334 CODE:
2261 RETVAL = SDL_RWFromFile (path, mode); 2335 RETVAL = SDL_RWFromFile (path, mode);
2262 OUTPUT: 2336 OUTPUT:
2263 RETVAL 2337 RETVAL
2264 2338
2339# fails on win32:
2340# CFPlus.xs(2268) : error C2059: syntax error : '('
2265void 2341#void
2266close (CFPlus::RW self) 2342#close (CFPlus::RW self)
2267 CODE: 2343# CODE:
2268 SDL_RWclose (self); 2344# (self->(close)) (self);
2269 2345
2270MODULE = CFPlus PACKAGE = CFPlus::Channel 2346MODULE = CFPlus PACKAGE = CFPlus::Channel
2271 2347
2272PROTOTYPES: DISABLE 2348PROTOTYPES: DISABLE
2273 2349
2309 Mix_FadeOutChannel (self, ticks); 2385 Mix_FadeOutChannel (self, ticks);
2310 2386
2311int 2387int
2312volume (CFPlus::Channel self, int volume) 2388volume (CFPlus::Channel self, int volume)
2313 CODE: 2389 CODE:
2314 RETVAL = Mix_Volume (self, volume); 2390 RETVAL = Mix_Volume (self, CLAMP (volume, 0, 128));
2315 OUTPUT: 2391 OUTPUT:
2316 RETVAL 2392 RETVAL
2317 2393
2318void 2394void
2319unregister_all_effects (CFPlus::Channel self) 2395unregister_all_effects (CFPlus::Channel self)
2321 Mix_UnregisterAllEffects (self); 2397 Mix_UnregisterAllEffects (self);
2322 2398
2323void 2399void
2324set_panning (CFPlus::Channel self, int left, int right) 2400set_panning (CFPlus::Channel self, int left, int right)
2325 CODE: 2401 CODE:
2402 left = CLAMP (left , 0, 255);
2403 right = CLAMP (right, 0, 255);
2326 Mix_SetPanning (self, left, right); 2404 Mix_SetPanning (self, left, right);
2327 2405
2328void 2406void
2329set_distance (CFPlus::Channel self, int distance) 2407set_distance (CFPlus::Channel self, int distance)
2330 CODE: 2408 CODE:
2331 Mix_SetDistance (self, distance); 2409 Mix_SetDistance (self, CLAMP (distance, 0, 255));
2332 2410
2333void 2411void
2334set_position (CFPlus::Channel self, int angle, int distance) 2412set_position (CFPlus::Channel self, int angle, int distance)
2335 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);
2336 Mix_SetPosition (self, angle, distance); 2421 Mix_SetPosition (self, angle, CLAMP (distance, 0, 255));
2422}
2337 2423
2338void 2424void
2339set_reverse_stereo (CFPlus::Channel self, int flip) 2425set_reverse_stereo (CFPlus::Channel self, int flip)
2340 CODE: 2426 CODE:
2341 Mix_SetReverseStereo (self, flip); 2427 Mix_SetReverseStereo (self, flip);
2357 Mix_FreeChunk (self); 2443 Mix_FreeChunk (self);
2358 2444
2359int 2445int
2360volume (CFPlus::MixChunk self, int volume = -1) 2446volume (CFPlus::MixChunk self, int volume = -1)
2361 CODE: 2447 CODE:
2448 if (items > 1)
2449 volume = CLAMP (volume, 0, 128);
2362 RETVAL = Mix_VolumeChunk (self, volume); 2450 RETVAL = Mix_VolumeChunk (self, volume);
2363 OUTPUT: 2451 OUTPUT:
2364 RETVAL 2452 RETVAL
2365 2453
2366CFPlus::Channel 2454CFPlus::Channel
2385 2473
2386int 2474int
2387volume (int volume = -1) 2475volume (int volume = -1)
2388 PROTOTYPE: ;$ 2476 PROTOTYPE: ;$
2389 CODE: 2477 CODE:
2478 if (items > 0)
2479 volume = CLAMP (volume, 0, 128);
2390 RETVAL = Mix_VolumeMusic (volume); 2480 RETVAL = Mix_VolumeMusic (volume);
2391 OUTPUT: 2481 OUTPUT:
2392 RETVAL 2482 RETVAL
2393 2483
2394void 2484void
2474 const_iv (GL_INTENSITY), 2564 const_iv (GL_INTENSITY),
2475 const_iv (GL_LUMINANCE), 2565 const_iv (GL_LUMINANCE),
2476 const_iv (GL_LUMINANCE_ALPHA), 2566 const_iv (GL_LUMINANCE_ALPHA),
2477 const_iv (GL_FLOAT), 2567 const_iv (GL_FLOAT),
2478 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),
2479 const_iv (GL_COMPILE), 2575 const_iv (GL_COMPILE),
2480 const_iv (GL_PROXY_TEXTURE_1D), 2576 const_iv (GL_PROXY_TEXTURE_1D),
2481 const_iv (GL_PROXY_TEXTURE_2D), 2577 const_iv (GL_PROXY_TEXTURE_2D),
2482 const_iv (GL_TEXTURE_1D), 2578 const_iv (GL_TEXTURE_1D),
2483 const_iv (GL_TEXTURE_2D), 2579 const_iv (GL_TEXTURE_2D),
2522 const_iv (GL_PERSPECTIVE_CORRECTION_HINT), 2618 const_iv (GL_PERSPECTIVE_CORRECTION_HINT),
2523 const_iv (GL_POINT_SMOOTH_HINT), 2619 const_iv (GL_POINT_SMOOTH_HINT),
2524 const_iv (GL_LINE_SMOOTH_HINT), 2620 const_iv (GL_LINE_SMOOTH_HINT),
2525 const_iv (GL_POLYGON_SMOOTH_HINT), 2621 const_iv (GL_POLYGON_SMOOTH_HINT),
2526 const_iv (GL_GENERATE_MIPMAP_HINT), 2622 const_iv (GL_GENERATE_MIPMAP_HINT),
2623 const_iv (GL_TEXTURE_COMPRESSION_HINT),
2527 const_iv (GL_FASTEST), 2624 const_iv (GL_FASTEST),
2528 const_iv (GL_DONT_CARE), 2625 const_iv (GL_DONT_CARE),
2529 const_iv (GL_NICEST), 2626 const_iv (GL_NICEST),
2530 const_iv (GL_V2F), 2627 const_iv (GL_V2F),
2531 const_iv (GL_V3F), 2628 const_iv (GL_V3F),
2539 2636
2540 texture_av = newAV (); 2637 texture_av = newAV ();
2541 AvREAL_off (texture_av); 2638 AvREAL_off (texture_av);
2542} 2639}
2543 2640
2641void
2642disable_GL_EXT_blend_func_separate ()
2643 CODE:
2644 gl.BlendFuncSeparate = 0;
2645 gl.BlendFuncSeparateEXT = 0;
2646
2544char * 2647char *
2545gl_vendor () 2648gl_vendor ()
2546 CODE: 2649 CODE:
2547 RETVAL = (char *)glGetString (GL_VENDOR); 2650 RETVAL = (char *)glGetString (GL_VENDOR);
2548 OUTPUT: 2651 OUTPUT:
2669 2772
2670void glRect (float x1, float y1, float x2, float y2) 2773void glRect (float x1, float y1, float x2, float y2)
2671 CODE: 2774 CODE:
2672 glRectf (x1, y1, x2, y2); 2775 glRectf (x1, y1, x2, y2);
2673 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
2674PROTOTYPES: ENABLE 2786PROTOTYPES: ENABLE
2675 2787
2676void glBegin (int mode) 2788void glBegin (int mode)
2677 2789
2678void glEnd () 2790void glEnd ()
2779 NV x, y, w, h; 2891 NV x, y, w, h;
2780 SV *draw_x_sv = GvSV (draw_x_gv); 2892 SV *draw_x_sv = GvSV (draw_x_gv);
2781 SV *draw_y_sv = GvSV (draw_y_gv); 2893 SV *draw_y_sv = GvSV (draw_y_gv);
2782 SV *draw_w_sv = GvSV (draw_w_gv); 2894 SV *draw_w_sv = GvSV (draw_w_gv);
2783 SV *draw_h_sv = GvSV (draw_h_gv); 2895 SV *draw_h_sv = GvSV (draw_h_gv);
2784 SV *hover;
2785 double draw_x, draw_y, draw_w, draw_h; 2896 double draw_x, draw_y;
2786 2897
2787 if (!SvROK (self)) 2898 if (!SvROK (self))
2788 croak ("CFPlus::Base::draw: %s not a reference", SvPV_nolen (self)); 2899 croak ("CFPlus::Base::draw: %s not a reference", SvPV_nolen (self));
2789 2900
2790 hv = (HV *)SvRV (self); 2901 hv = (HV *)SvRV (self);
2818 { 2929 {
2819 svp = hv_fetch (hv, "can_hover", sizeof ("can_hover") - 1, 0); 2930 svp = hv_fetch (hv, "can_hover", sizeof ("can_hover") - 1, 0);
2820 2931
2821 if (svp && SvTRUE (*svp)) 2932 if (svp && SvTRUE (*svp))
2822 { 2933 {
2823 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);
2824 glEnable (GL_BLEND); 2935 glEnable (GL_BLEND);
2825 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 2936 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
2826 glBegin (GL_QUADS); 2937 glBegin (GL_QUADS);
2827 glVertex2f (0, 0); 2938 glVertex2f (0, 0);
2828 glVertex2f (w, 0); 2939 glVertex2f (w, 0);
2831 glEnd (); 2942 glEnd ();
2832 glDisable (GL_BLEND); 2943 glDisable (GL_BLEND);
2833 } 2944 }
2834 } 2945 }
2835#if 0 2946#if 0
2836 if ($ENV{CFPLUS_DEBUG} & 1) { 2947 // draw borders, for debugging
2837 glPushMatrix; 2948 glPushMatrix ();
2838 glColor 1, 1, 0, 1; 2949 glColor4f (1., 1., 0., 1.);
2839 glTranslate 0.375, 0.375; 2950 glTranslatef (.5, .5, 0.);
2840 glBegin GL_LINE_LOOP; 2951 glBegin (GL_LINE_LOOP);
2841 glVertex 0 , 0; 2952 glVertex2f (0 , 0);
2842 glVertex $self->{w} - 1, 0; 2953 glVertex2f (w - 1, 0);
2843 glVertex $self->{w} - 1, $self->{h} - 1; 2954 glVertex2f (w - 1, h - 1);
2844 glVertex 0 , $self->{h} - 1; 2955 glVertex2f (0 , h - 1);
2845 glEnd; 2956 glEnd ();
2846 glPopMatrix; 2957 glPopMatrix ();
2847 #CFPlus::UI::Label->new (w => $self->{w}, h => $self->{h}, text => $self, fontsize => 0)->_draw;
2848 }
2849#endif 2958#endif
2850 PUSHMARK (SP); 2959 PUSHMARK (SP);
2851 XPUSHs (self); 2960 XPUSHs (self);
2852 PUTBACK; 2961 PUTBACK;
2853 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