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.208 by root, Sat Jul 21 16:07:53 2007 UTC vs.
Revision 1.225 by root, Sat Aug 11 12:07:54 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;
434/* SDL should provide this, really. */ 445/* SDL should provide this, really. */
435#define SDLK_MODIFIER_MIN 300 446#define SDLK_MODIFIER_MIN 300
436#define SDLK_MODIFIER_MAX 314 447#define SDLK_MODIFIER_MAX 314
437 448
438/******************************************************************************/ 449/******************************************************************************/
450
451static GV *draw_x_gv, *draw_y_gv, *draw_w_gv, *draw_h_gv;
452static GV *hover_gv;
439 453
440static int 454static int
441within_widget (SV *widget, NV x, NV y) 455within_widget (SV *widget, NV x, NV y)
442{ 456{
443 HV *self; 457 HV *self;
797 XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("CFPlus::UI::Event", 1)))); 811 XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("CFPlus::UI::Event", 1))));
798 } 812 }
799} 813}
800 814
801int 815int
802Mix_OpenAudio (int frequency = 48000, int format = MIX_DEFAULT_FORMAT, int channels = 1, int chunksize = 2048) 816Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 1024)
803 POSTCALL: 817 POSTCALL:
804 Mix_HookMusicFinished (music_finished); 818 Mix_HookMusicFinished (music_finished);
805 Mix_ChannelFinished (channel_finished); 819 Mix_ChannelFinished (channel_finished);
806 820
807void 821void
808Mix_CloseAudio () 822Mix_CloseAudio ()
809 823
810int 824int
811Mix_AllocateChannels (int numchans = -1) 825Mix_AllocateChannels (int numchans = -1)
826
827const char *
828Mix_GetError ()
812 829
813void 830void
814lowdelay (int fd, int val = 1) 831lowdelay (int fd, int val = 1)
815 CODE: 832 CODE:
816 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&val, sizeof (val)); 833 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&val, sizeof (val));
858 STRLEN image_len; 875 STRLEN image_len;
859 char *image = (char *)SvPVbyte (image_, image_len); 876 char *image = (char *)SvPVbyte (image_, image_len);
860 SDL_Surface *surface, *surface2; 877 SDL_Surface *surface, *surface2;
861 SDL_PixelFormat fmt; 878 SDL_PixelFormat fmt;
862 SDL_RWops *rw = ix 879 SDL_RWops *rw = ix
863 ? SDL_RWFromFile (image, "r") 880 ? SDL_RWFromFile (image, "rb")
864 : SDL_RWFromConstMem (image, image_len); 881 : SDL_RWFromConstMem (image, image_len);
865 882
866 if (!rw) 883 if (!rw)
867 croak ("load_image: %s", SDL_GetError ()); 884 croak ("load_image: %s", SDL_GetError ());
868 885
1020 RETVAL->g = 1.; 1037 RETVAL->g = 1.;
1021 RETVAL->b = 1.; 1038 RETVAL->b = 1.;
1022 RETVAL->a = 1.; 1039 RETVAL->a = 1.;
1023 RETVAL->base_height = MIN_FONT_HEIGHT; 1040 RETVAL->base_height = MIN_FONT_HEIGHT;
1024 RETVAL->font = 0; 1041 RETVAL->font = 0;
1042 RETVAL->rc = rc_alloc ();
1025 1043
1026 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR); 1044 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
1027 layout_update_font (RETVAL); 1045 layout_update_font (RETVAL);
1028 OUTPUT: 1046 OUTPUT:
1029 RETVAL 1047 RETVAL
1030 1048
1031void 1049void
1032DESTROY (CFPlus::Layout self) 1050DESTROY (CFPlus::Layout self)
1033 CODE: 1051 CODE:
1034 g_object_unref (self->pl); 1052 g_object_unref (self->pl);
1053 rc_free (self->rc);
1035 Safefree (self); 1054 Safefree (self);
1036 1055
1037void 1056void
1038set_text (CFPlus::Layout self, SV *text_) 1057set_text (CFPlus::Layout self, SV *text_)
1039 CODE: 1058 CODE:
1291 } 1310 }
1292} 1311}
1293 1312
1294void 1313void
1295render (CFPlus::Layout self, float x, float y, int flags = 0) 1314render (CFPlus::Layout self, float x, float y, int flags = 0)
1296 PPCODE: 1315 CODE:
1316 rc_clear (self->rc);
1297 pango_opengl_render_layout_subpixel ( 1317 pango_opengl_render_layout_subpixel (
1298 self->pl, 1318 self->pl,
1319 self->rc,
1299 x * PANGO_SCALE, y * PANGO_SCALE, 1320 x * PANGO_SCALE, y * PANGO_SCALE,
1300 self->r, self->g, self->b, self->a, 1321 self->r, self->g, self->b, self->a,
1301 flags 1322 flags
1302 ); 1323 );
1324 // we assume that context_change actually clears/frees stuff
1325 // and does not do any recomputation...
1326 pango_layout_context_changed (self->pl);
1327
1328void
1329draw (CFPlus::Layout self)
1330 CODE:
1331{
1332 glEnable (GL_TEXTURE_2D);
1333 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1334 glEnable (GL_BLEND);
1335 gl_BlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
1336 GL_ONE , GL_ONE_MINUS_SRC_ALPHA);
1337 glEnable (GL_ALPHA_TEST);
1338 glAlphaFunc (GL_GREATER, 7.f / 255.f);
1339
1340 rc_draw (self->rc);
1341
1342 glDisable (GL_ALPHA_TEST);
1343 glDisable (GL_BLEND);
1344 glDisable (GL_TEXTURE_2D);
1345}
1303 1346
1304MODULE = CFPlus PACKAGE = CFPlus::Texture 1347MODULE = CFPlus PACKAGE = CFPlus::Texture
1305 1348
1306PROTOTYPES: ENABLE 1349PROTOTYPES: ENABLE
1307 1350
1339{ 1382{
1340 HV *hv = (HV *)SvRV (self); 1383 HV *hv = (HV *)SvRV (self);
1341 float s = SvNV (*hv_fetch (hv, "s", 1, 1)); 1384 float s = SvNV (*hv_fetch (hv, "s", 1, 1));
1342 float t = SvNV (*hv_fetch (hv, "t", 1, 1)); 1385 float t = SvNV (*hv_fetch (hv, "t", 1, 1));
1343 int name = SvIV (*hv_fetch (hv, "name", 4, 1)); 1386 int name = SvIV (*hv_fetch (hv, "name", 4, 1));
1387
1388 if (name <= 0)
1389 XSRETURN_EMPTY;
1344 1390
1345 if (items < 5) 1391 if (items < 5)
1346 { 1392 {
1347 w = SvNV (*hv_fetch (hv, "w", 1, 1)); 1393 w = SvNV (*hv_fetch (hv, "w", 1, 1));
1348 h = SvNV (*hv_fetch (hv, "h", 1, 1)); 1394 h = SvNV (*hv_fetch (hv, "h", 1, 1));
1537 self->rows += MAP_EXTEND_Y; 1583 self->rows += MAP_EXTEND_Y;
1538 self->y += MAP_EXTEND_Y; 1584 self->y += MAP_EXTEND_Y;
1539 } 1585 }
1540} 1586}
1541 1587
1542void 1588SV *
1543map1a_update (CFPlus::Map self, SV *data_, int extmap) 1589map1a_update (CFPlus::Map self, SV *data_, int extmap)
1544 CODE: 1590 CODE:
1545{ 1591{
1546 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_); 1592 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_);
1547 uint8_t *data_end = (uint8_t *)SvEND (data_); 1593 uint8_t *data_end = (uint8_t *)SvEND (data_);
1548 mapcell *cell; 1594 mapcell *cell;
1549 int x, y, flags; 1595 int x, y, z, flags;
1596 AV *missing = newAV ();
1597 RETVAL = newRV_noinc ((SV *)missing);
1550 1598
1551 while (data < data_end - 1) 1599 while (data < data_end - 1)
1552 { 1600 {
1553 flags = (data [0] << 8) + data [1]; data += 2; 1601 flags = (data [0] << 8) + data [1]; data += 2;
1554 1602
1605 } 1653 }
1606 else 1654 else
1607 cell->darkness = *data++ + 1; 1655 cell->darkness = *data++ + 1;
1608 } 1656 }
1609 1657
1658 for (z = 0; z <= 2; ++z)
1610 if (flags & 4) 1659 if (flags & (4 >> z))
1611 { 1660 {
1612 faceid face = (data [0] << 8) + data [1]; data += 2; 1661 faceid face = (data [0] << 8) + data [1]; data += 2;
1613 need_facenum (self, face); 1662 need_facenum (self, face);
1614 cell->tile [0] = self->face2tile [face]; 1663 cell->tile [z] = self->face2tile [face];
1664
1665 if (cell->tile [z])
1666 {
1667 maptex *tex = self->tex + cell->tile [z];
1668 if (!tex->name)
1669 av_push (missing, newSViv (cell->tile [z]));
1670
1671 if (tex->smoothtile)
1672 {
1673 maptex *smooth = self->tex + tex->smoothtile;
1674 if (!smooth->name)
1675 av_push (missing, newSViv (tex->smoothtile));
1676 }
1677 }
1615 } 1678 }
1616
1617 if (flags & 2)
1618 {
1619 faceid face = (data [0] << 8) + data [1]; data += 2;
1620 need_facenum (self, face);
1621 cell->tile [1] = self->face2tile [face];
1622 }
1623
1624 if (flags & 1)
1625 {
1626 faceid face = (data [0] << 8) + data [1]; data += 2;
1627 need_facenum (self, face);
1628 cell->tile [2] = self->face2tile [face];
1629 }
1630 } 1679 }
1631 else 1680 else
1632 cell->darkness = 0; 1681 cell->darkness = 0;
1633 } 1682 }
1634} 1683}
1684 OUTPUT:
1685 RETVAL
1635 1686
1636SV * 1687SV *
1637mapmap (CFPlus::Map self, int x0, int y0, int w, int h) 1688mapmap (CFPlus::Map self, int x0, int y0, int w, int h)
1638 CODE: 1689 CODE:
1639{ 1690{
1690 1741
1691void 1742void
1692draw (CFPlus::Map self, int mx, int my, int sw, int sh, int T) 1743draw (CFPlus::Map self, int mx, int my, int sw, int sh, int T)
1693 CODE: 1744 CODE:
1694{ 1745{
1746 int x, y, z;
1747
1695 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ()); 1748 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
1696 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level 1749 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level
1697 static uint8_t smooth_max[256][256]; // egad, fats and wasteful on memory (64k) 1750 static uint8_t smooth_max[256][256]; // egad, fats and wasteful on memory (64k)
1698 smooth_key skey; 1751 smooth_key skey;
1699 int x, y, z; 1752
1700 int last_name; 1753 rc_t *rc = rc_alloc ();
1754 rc_key_t key;
1755 rc_array_t *arr;
1701 1756
1702 // thats current max. sorry. 1757 // thats current max. sorry.
1703 if (sw > 255) sw = 255; 1758 if (sw > 255) sw = 255;
1704 if (sh > 255) sh = 255; 1759 if (sh > 255) sh = 255;
1705 1760
1706 // clear key, in case of extra padding 1761 // clear key, in case of extra padding
1707 memset (&skey, 0, sizeof (skey)); 1762 memset (&skey, 0, sizeof (skey));
1708 1763
1709 glColor4ub (255, 255, 255, 255); 1764 memset (&key, 0, sizeof (key));
1710 1765 key.r = 255;
1711 glEnable (GL_BLEND); 1766 key.g = 255;
1712 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1767 key.b = 255;
1713 glEnable (GL_TEXTURE_2D); 1768 key.a = 255;
1714 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1769 key.mode = GL_QUADS;
1715 1770 key.format = GL_T2F_V3F;
1716 glBegin (GL_QUADS); 1771 key.texname = -1;
1717
1718 last_name = 0;
1719 1772
1720 mx += self->x; 1773 mx += self->x;
1721 my += self->y; 1774 my += self->y;
1722 1775
1723 // first pass: determine smooth_max 1776 // first pass: determine smooth_max
1739 MAX (self->tex [cell->tile [0]].smoothlevel, 1792 MAX (self->tex [cell->tile [0]].smoothlevel,
1740 MAX (self->tex [cell->tile [1]].smoothlevel, 1793 MAX (self->tex [cell->tile [1]].smoothlevel,
1741 self->tex [cell->tile [2]].smoothlevel)); 1794 self->tex [cell->tile [2]].smoothlevel));
1742 } 1795 }
1743 } 1796 }
1797
1798 glEnable (GL_BLEND);
1799 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1800 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1744 1801
1745 for (z = 0; z <= 2; z++) 1802 for (z = 0; z <= 2; z++)
1746 { 1803 {
1747 memset (smooth_level, 0, sizeof (smooth_level)); 1804 memset (smooth_level, 0, sizeof (smooth_level));
1748 1805
1758 tileid tile = cell->tile [z]; 1815 tileid tile = cell->tile [z];
1759 1816
1760 if (tile) 1817 if (tile)
1761 { 1818 {
1762 maptex tex = self->tex [tile]; 1819 maptex tex = self->tex [tile];
1763 int px = (x + 1) * T - tex.w; 1820 int px, py;
1764 int py = (y + 1) * T - tex.h;
1765 1821
1766 // suppressing texture state switches here 1822 // suppressing texture state switches here
1767 // is only moderately effective, but worth the extra effort 1823 // is only moderately effective, but worth the extra effort
1768 if (last_name != tex.name) 1824 if (key.texname != tex.name)
1769 { 1825 {
1770 if (!tex.name) 1826 if (!tex.name)
1771 tex = self->tex [2]; /* missing, replace by noface */ 1827 tex = self->tex [2]; /* missing, replace by noface */
1772 1828
1773 glEnd (); 1829 key.texname = tex.name;
1774 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1830 arr = rc_array (rc, &key);
1775 glBegin (GL_QUADS);
1776 } 1831 }
1777 1832
1778 glTexCoord2f (0 , 0 ); glVertex2f (px , py ); 1833 px = (x + 1) * T - tex.w;
1834 py = (y + 1) * T - tex.h;
1835
1836 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
1779 glTexCoord2f (0 , tex.t); glVertex2f (px , py + tex.h); 1837 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0);
1780 glTexCoord2f (tex.s, tex.t); glVertex2f (px + tex.w, py + tex.h); 1838 rc_t2f_v3f (arr, tex.s, tex.t, px + tex.w, py + tex.h, 0);
1781 glTexCoord2f (tex.s, 0 ); glVertex2f (px + tex.w, py ); 1839 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0);
1782 1840
1783 if (cell->flags && z == 2) 1841 if (cell->flags && z == 2)
1784 { 1842 {
1843 // overlays such as the speech bubble, probably more to come
1785 if (cell->flags & 1) 1844 if (cell->flags & 1)
1786 { 1845 {
1787 maptex tex = self->tex [1]; 1846 maptex tex = self->tex [1];
1788 int px = x * T + T * 2 / 32; 1847 int px = x * T + T * 2 / 32;
1789 int py = y * T - T * 6 / 32; 1848 int py = y * T - T * 6 / 32;
1790 1849
1850 if (tex.name)
1791 glEnd (); 1851 {
1792 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1852 if (key.texname != tex.name)
1853 {
1854 key.texname = tex.name;
1855 arr = rc_array (rc, &key);
1856 }
1857
1858 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
1859 rc_t2f_v3f (arr, 0 , tex.t, px , py + T, 0);
1860 rc_t2f_v3f (arr, tex.s, tex.t, px + T, py + T, 0);
1861 rc_t2f_v3f (arr, tex.s, 0 , px + T, py , 0);
1793 glBegin (GL_QUADS); 1862 }
1794
1795 glTexCoord2f (0 , 0 ); glVertex2f (px , py );
1796 glTexCoord2f (0 , tex.t); glVertex2f (px , py + T);
1797 glTexCoord2f (tex.s, tex.t); glVertex2f (px + T, py + T);
1798 glTexCoord2f (tex.s, 0 ); glVertex2f (px + T, py );
1799 } 1863 }
1800 } 1864 }
1801 1865
1802 // update smooth hash 1866 // update smooth hash
1803 if (tex.smoothtile) 1867 if (tex.smoothtile)
1838 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0800); 1902 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0800);
1839 } 1903 }
1840 } 1904 }
1841 } 1905 }
1842 } 1906 }
1907
1908 rc_draw (rc);
1909 rc_clear (rc);
1843 1910
1844 // go through all smoothlevels, lowest to highest, then draw. 1911 // go through all smoothlevels, lowest to highest, then draw.
1845 // this is basically counting sort 1912 // this is basically counting sort
1846 { 1913 {
1847 int w, b; 1914 int w, b;
1872 int border = bits & 15; 1939 int border = bits & 15;
1873 int corner = (bits >> 8) & ~(bits >> 4) & 15; 1940 int corner = (bits >> 8) & ~(bits >> 4) & 15;
1874 float dx = tex.s * .0625f; // 16 images/row 1941 float dx = tex.s * .0625f; // 16 images/row
1875 float dy = tex.t * .5f ; // 2 images/column 1942 float dy = tex.t * .5f ; // 2 images/column
1876 1943
1877 // this time naively avoiding texture state changes
1878 // save gobs of state changes.
1879 if (last_name != tex.name) 1944 if (tex.name)
1880 { 1945 {
1946 // this time avoiding texture state changes
1947 // save gobs of state changes.
1881 if (!tex.name) 1948 if (key.texname != tex.name)
1882 continue; // smoothing not yet available
1883
1884 glEnd (); 1949 {
1885 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1950 key.texname = tex.name;
1886 glBegin (GL_QUADS); 1951 arr = rc_array (rc, &key);
1887 } 1952 }
1888 1953
1889 if (border) 1954 if (border)
1890 { 1955 {
1891 float ox = border * dx; 1956 float ox = border * dx;
1892 1957
1893 glTexCoord2f (ox , 0.f ); glVertex2f (px , py ); 1958 rc_t2f_v3f (arr, ox , 0.f , px , py , 0);
1894 glTexCoord2f (ox , dy ); glVertex2f (px , py + T); 1959 rc_t2f_v3f (arr, ox , dy , px , py + T, 0);
1895 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py + T); 1960 rc_t2f_v3f (arr, ox + dx, dy , px + T, py + T, 0);
1896 glTexCoord2f (ox + dx, 0.f ); glVertex2f (px + T, py ); 1961 rc_t2f_v3f (arr, ox + dx, 0.f , px + T, py , 0);
1897 } 1962 }
1898 1963
1899 if (corner) 1964 if (corner)
1900 { 1965 {
1901 float ox = corner * dx; 1966 float ox = corner * dx;
1902 1967
1903 glTexCoord2f (ox , dy ); glVertex2f (px , py ); 1968 rc_t2f_v3f (arr, ox , dy , px , py , 0);
1904 glTexCoord2f (ox , dy * 2.f); glVertex2f (px , py + T); 1969 rc_t2f_v3f (arr, ox , dy * 2.f, px , py + T, 0);
1905 glTexCoord2f (ox + dx, dy * 2.f); glVertex2f (px + T, py + T); 1970 rc_t2f_v3f (arr, ox + dx, dy * 2.f, px + T, py + T, 0);
1906 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py ); 1971 rc_t2f_v3f (arr, ox + dx, dy , px + T, py , 0);
1972 }
1907 } 1973 }
1908 } 1974 }
1909 } 1975 }
1910 } 1976 }
1911 } 1977 }
1912 } 1978 }
1913 1979
1914 hv_clear (smooth); 1980 hv_clear (smooth);
1981 rc_draw (rc);
1982 rc_clear (rc);
1915 } 1983 }
1916 1984
1917 glEnd ();
1918
1919 glDisable (GL_TEXTURE_2D);
1920 glDisable (GL_BLEND); 1985 glDisable (GL_BLEND);
1986 rc_free (rc);
1921 1987
1922 // top layer: overlays such as the health bar 1988 // top layer: overlays such as the health bar
1923 for (y = 0; y < sh; y++) 1989 for (y = 0; y < sh; y++)
1924 if (0 <= y + my && y + my < self->rows) 1990 if (0 <= y + my && y + my < self->rows)
1925 { 1991 {
2229 } 2295 }
2230 } 2296 }
2231 } 2297 }
2232} 2298}
2233 2299
2300MODULE = CFPlus PACKAGE = CFPlus::RW
2301
2302CFPlus::RW
2303new (SV *class, SV *data_sv)
2304 CODE:
2305{
2306 STRLEN datalen;
2307 char *data = SvPVbyte (data_sv, datalen);
2308
2309 RETVAL = SDL_RWFromConstMem (data, datalen);
2310}
2311 OUTPUT:
2312 RETVAL
2313
2314CFPlus::RW
2315new_from_file (SV *class, const char *path, const char *mode = "rb")
2316 CODE:
2317 RETVAL = SDL_RWFromFile (path, mode);
2318 OUTPUT:
2319 RETVAL
2320
2321# fails on win32:
2322# CFPlus.xs(2268) : error C2059: syntax error : '('
2323#void
2324#close (CFPlus::RW self)
2325# CODE:
2326# (self->(close)) (self);
2327
2328MODULE = CFPlus PACKAGE = CFPlus::Channel
2329
2330PROTOTYPES: DISABLE
2331
2332CFPlus::Channel
2333find ()
2334 CODE:
2335{
2336 RETVAL = Mix_GroupAvailable (-1);
2337
2338 if (RETVAL < 0)
2339 {
2340 RETVAL = Mix_GroupOldest (-1);
2341
2342 if (RETVAL < 0)
2343 XSRETURN_UNDEF;
2344
2345 Mix_HaltChannel (RETVAL);
2346 }
2347
2348 Mix_UnregisterAllEffects (RETVAL);
2349 Mix_Volume (RETVAL, 128);
2350}
2351 OUTPUT:
2352 RETVAL
2353
2354void
2355halt (CFPlus::Channel self)
2356 CODE:
2357 Mix_HaltChannel (self);
2358
2359void
2360expire (CFPlus::Channel self, int ticks = -1)
2361 CODE:
2362 Mix_ExpireChannel (self, ticks);
2363
2364void
2365fade_out (CFPlus::Channel self, int ticks = -1)
2366 CODE:
2367 Mix_FadeOutChannel (self, ticks);
2368
2369int
2370volume (CFPlus::Channel self, int volume)
2371 CODE:
2372 RETVAL = Mix_Volume (self, CLAMP (volume, 0, 128));
2373 OUTPUT:
2374 RETVAL
2375
2376void
2377unregister_all_effects (CFPlus::Channel self)
2378 CODE:
2379 Mix_UnregisterAllEffects (self);
2380
2381void
2382set_panning (CFPlus::Channel self, int left, int right)
2383 CODE:
2384 left = CLAMP (left , 0, 255);
2385 right = CLAMP (right, 0, 255);
2386 Mix_SetPanning (self, left, right);
2387
2388void
2389set_distance (CFPlus::Channel self, int distance)
2390 CODE:
2391 Mix_SetDistance (self, CLAMP (distance, 0, 255));
2392
2393void
2394set_position (CFPlus::Channel self, int angle, int distance)
2395 CODE:
2396
2397void
2398set_position_r (CFPlus::Channel self, int dx, int dy, int maxdistance)
2399 CODE:
2400{
2401 int distance = sqrtf (dx * dx + dy * dy) * (255.f / sqrtf (maxdistance * maxdistance));
2402 int angle = 360 + (int)roundf (atan2f (dx, -dy) * 180.f / (float)M_PI);
2403 Mix_SetPosition (self, angle, CLAMP (distance, 0, 255));
2404}
2405
2406void
2407set_reverse_stereo (CFPlus::Channel self, int flip)
2408 CODE:
2409 Mix_SetReverseStereo (self, flip);
2410
2234MODULE = CFPlus PACKAGE = CFPlus::MixChunk 2411MODULE = CFPlus PACKAGE = CFPlus::MixChunk
2235 2412
2236PROTOTYPES: DISABLE 2413PROTOTYPES: DISABLE
2237 2414
2238CFPlus::MixChunk 2415CFPlus::MixChunk
2239new_from_file (SV *class, char *path) 2416new (SV *class, CFPlus::RW rwops)
2240 CODE: 2417 CODE:
2241 RETVAL = Mix_LoadWAV (path); 2418 RETVAL = Mix_LoadWAV_RW (rwops, 1);
2242 OUTPUT: 2419 OUTPUT:
2243 RETVAL 2420 RETVAL
2244 2421
2245void 2422void
2246DESTROY (CFPlus::MixChunk self) 2423DESTROY (CFPlus::MixChunk self)
2248 Mix_FreeChunk (self); 2425 Mix_FreeChunk (self);
2249 2426
2250int 2427int
2251volume (CFPlus::MixChunk self, int volume = -1) 2428volume (CFPlus::MixChunk self, int volume = -1)
2252 CODE: 2429 CODE:
2430 if (items > 1)
2431 volume = CLAMP (volume, 0, 128);
2253 RETVAL = Mix_VolumeChunk (self, volume); 2432 RETVAL = Mix_VolumeChunk (self, volume);
2254 OUTPUT: 2433 OUTPUT:
2255 RETVAL 2434 RETVAL
2256 2435
2257int 2436CFPlus::Channel
2258play (CFPlus::MixChunk self, int channel = -1, int loops = 0, int ticks = -1) 2437play (CFPlus::MixChunk self, CFPlus::Channel channel = -1, int loops = 0, int ticks = -1)
2259 CODE: 2438 CODE:
2439{
2260 RETVAL = Mix_PlayChannelTimed (channel, self, loops, ticks); 2440 RETVAL = Mix_PlayChannelTimed (channel, self, loops, ticks);
2441
2442 if (RETVAL < 0)
2443 XSRETURN_UNDEF;
2444
2445 if (channel < 0)
2446 {
2447 Mix_UnregisterAllEffects (RETVAL);
2448 Mix_Volume (RETVAL, 128);
2449 }
2450}
2261 OUTPUT: 2451 OUTPUT:
2262 RETVAL 2452 RETVAL
2263 2453
2264MODULE = CFPlus PACKAGE = CFPlus::MixMusic 2454MODULE = CFPlus PACKAGE = CFPlus::MixMusic
2265 2455
2266int 2456int
2267volume (int volume = -1) 2457volume (int volume = -1)
2268 PROTOTYPE: ;$ 2458 PROTOTYPE: ;$
2269 CODE: 2459 CODE:
2460 if (items > 0)
2461 volume = CLAMP (volume, 0, 128);
2270 RETVAL = Mix_VolumeMusic (volume); 2462 RETVAL = Mix_VolumeMusic (volume);
2271 OUTPUT: 2463 OUTPUT:
2272 RETVAL 2464 RETVAL
2273 2465
2274int 2466void
2275fade_out (int ms) 2467fade_out (int ms)
2276 CODE: 2468 CODE:
2277 RETVAL = Mix_FadeOutMusic (ms); 2469 Mix_FadeOutMusic (ms);
2278 OUTPUT: 2470
2279 RETVAL 2471void
2472halt ()
2473 CODE:
2474 Mix_HaltMusic ();
2280 2475
2281CFPlus::MixMusic 2476CFPlus::MixMusic
2282new_from_file (SV *class, char *path) 2477new (SV *class, CFPlus::RW rwops)
2283 CODE: 2478 CODE:
2284 RETVAL = Mix_LoadMUS (path); 2479 RETVAL = Mix_LoadMUS_RW (rwops);
2285 OUTPUT: 2480 OUTPUT:
2286 RETVAL 2481 RETVAL
2287 2482
2288void 2483void
2289DESTROY (CFPlus::MixMusic self) 2484DESTROY (CFPlus::MixMusic self)
2295 CODE: 2490 CODE:
2296 RETVAL = Mix_PlayMusic (self, loops); 2491 RETVAL = Mix_PlayMusic (self, loops);
2297 OUTPUT: 2492 OUTPUT:
2298 RETVAL 2493 RETVAL
2299 2494
2300int 2495void
2301fade_in_pos (CFPlus::MixMusic self, int loops, int ms, double position) 2496fade_in_pos (CFPlus::MixMusic self, int loops, int ms, double position)
2302 CODE: 2497 CODE:
2303 RETVAL = Mix_FadeInMusicPos (self, loops, ms, position); 2498 Mix_FadeInMusicPos (self, loops, ms, position);
2304 OUTPUT:
2305 RETVAL
2306 2499
2307MODULE = CFPlus PACKAGE = CFPlus::OpenGL 2500MODULE = CFPlus PACKAGE = CFPlus::OpenGL
2308 2501
2309PROTOTYPES: ENABLE 2502PROTOTYPES: ENABLE
2310 2503
2544 2737
2545void glTexCoord (float s, float t) 2738void glTexCoord (float s, float t)
2546 CODE: 2739 CODE:
2547 glTexCoord2f (s, t); 2740 glTexCoord2f (s, t);
2548 2741
2742void glRect (float x1, float y1, float x2, float y2)
2743 CODE:
2744 glRectf (x1, y1, x2, y2);
2745
2549PROTOTYPES: ENABLE 2746PROTOTYPES: ENABLE
2550 2747
2551void glBegin (int mode) 2748void glBegin (int mode)
2552 2749
2553void glEnd () 2750void glEnd ()
2626MODULE = CFPlus PACKAGE = CFPlus::UI::Base 2823MODULE = CFPlus PACKAGE = CFPlus::UI::Base
2627 2824
2628PROTOTYPES: DISABLE 2825PROTOTYPES: DISABLE
2629 2826
2630void 2827void
2631find_widget (SV *widget, NV x, NV y) 2828find_widget (SV *self, NV x, NV y)
2632 PPCODE: 2829 PPCODE:
2633{ 2830{
2634 if (within_widget (widget, x, y)) 2831 if (within_widget (self, x, y))
2635 XPUSHs (widget); 2832 XPUSHs (self);
2636} 2833}
2637 2834
2835BOOT:
2836{
2837 hover_gv = gv_fetchpv ("CFPlus::UI::HOVER", 1, SVt_NV);
2838
2839 draw_x_gv = gv_fetchpv ("CFPlus::UI::Base::draw_x", 1, SVt_NV);
2840 draw_y_gv = gv_fetchpv ("CFPlus::UI::Base::draw_y", 1, SVt_NV);
2841 draw_w_gv = gv_fetchpv ("CFPlus::UI::Base::draw_w", 1, SVt_NV);
2842 draw_h_gv = gv_fetchpv ("CFPlus::UI::Base::draw_h", 1, SVt_NV);
2843}
2844
2845void
2846draw (SV *self)
2847 CODE:
2848{
2849 HV *hv;
2850 SV **svp;
2851 NV x, y, w, h;
2852 SV *draw_x_sv = GvSV (draw_x_gv);
2853 SV *draw_y_sv = GvSV (draw_y_gv);
2854 SV *draw_w_sv = GvSV (draw_w_gv);
2855 SV *draw_h_sv = GvSV (draw_h_gv);
2856 SV *hover;
2857 double draw_x, draw_y, draw_w, draw_h;
2858
2859 if (!SvROK (self))
2860 croak ("CFPlus::Base::draw: %s not a reference", SvPV_nolen (self));
2861
2862 hv = (HV *)SvRV (self);
2863
2864 if (SvTYPE (hv) != SVt_PVHV)
2865 croak ("CFPlus::Base::draw: %s not a hashref", SvPV_nolen (self));
2866
2867 svp = hv_fetch (hv, "w", 1, 0); w = svp ? SvNV (*svp) : 0.;
2868 svp = hv_fetch (hv, "h", 1, 0); h = svp ? SvNV (*svp) : 0.;
2869
2870 if (!h || !w)
2871 XSRETURN_EMPTY;
2872
2873 svp = hv_fetch (hv, "x", 1, 0); x = svp ? SvNV (*svp) : 0.;
2874 svp = hv_fetch (hv, "y", 1, 0); y = svp ? SvNV (*svp) : 0.;
2875
2876 draw_x = SvNV (draw_x_sv) + x;
2877 draw_y = SvNV (draw_y_sv) + y;
2878
2879 if (draw_x + w < 0 || draw_x >= SvNV (draw_w_sv)
2880 || draw_y + h < 0 || draw_y >= SvNV (draw_h_sv))
2881 XSRETURN_EMPTY;
2882
2883 sv_setnv (draw_x_sv, draw_x);
2884 sv_setnv (draw_y_sv, draw_y);
2885
2886 glPushMatrix ();
2887 glTranslated (x, y, 0);
2888
2889 if (SvROK (GvSV (hover_gv)) && SvRV (GvSV (hover_gv)) == (SV *)hv)
2890 {
2891 svp = hv_fetch (hv, "can_hover", sizeof ("can_hover") - 1, 0);
2892
2893 if (svp && SvTRUE (*svp))
2894 {
2895 glColor4f (1*0.2f, 0.8*0.2f, 0.5*0.2f, 0.2f);
2896 glEnable (GL_BLEND);
2897 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
2898 glBegin (GL_QUADS);
2899 glVertex2f (0, 0);
2900 glVertex2f (w, 0);
2901 glVertex2f (w, h);
2902 glVertex2f (0, h);
2903 glEnd ();
2904 glDisable (GL_BLEND);
2905 }
2906 }
2907#if 0
2908 if ($ENV{CFPLUS_DEBUG} & 1) {
2909 glPushMatrix;
2910 glColor 1, 1, 0, 1;
2911 glTranslate 0.375, 0.375;
2912 glBegin GL_LINE_LOOP;
2913 glVertex 0 , 0;
2914 glVertex $self->{w} - 1, 0;
2915 glVertex $self->{w} - 1, $self->{h} - 1;
2916 glVertex 0 , $self->{h} - 1;
2917 glEnd;
2918 glPopMatrix;
2919 #CFPlus::UI::Label->new (w => $self->{w}, h => $self->{h}, text => $self, fontsize => 0)->_draw;
2920 }
2921#endif
2922 PUSHMARK (SP);
2923 XPUSHs (self);
2924 PUTBACK;
2925 call_method ("_draw", G_VOID | G_DISCARD);
2926 SPAGAIN;
2927
2928 glPopMatrix ();
2929
2930 draw_x = draw_x - x; sv_setnv (draw_x_sv, draw_x);
2931 draw_y = draw_y - y; sv_setnv (draw_y_sv, draw_y);
2932}
2933

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines