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.231 by root, Sun Aug 19 14:09:28 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;
704 715
705 if (RETVAL) 716 if (RETVAL)
706 { 717 {
707 av_clear (texture_av); 718 av_clear (texture_av);
708 719
709 SDL_WM_SetCaption ("Crossfire+ Client " VERSION, "Crossfire+"); 720 SDL_WM_SetCaption ("Crossfire TRT Client " VERSION, "Crossfire TRT");
710#define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name); 721#define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name);
711#include "glfunc.h" 722#include "glfunc.h"
712#undef GL_FUNC 723#undef GL_FUNC
713 } 724 }
714} 725}
800 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))));
801 } 812 }
802} 813}
803 814
804int 815int
805Mix_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)
806 POSTCALL: 817 POSTCALL:
807 Mix_HookMusicFinished (music_finished); 818 Mix_HookMusicFinished (music_finished);
808 Mix_ChannelFinished (channel_finished); 819 Mix_ChannelFinished (channel_finished);
809 820
810void 821void
811Mix_CloseAudio () 822Mix_CloseAudio ()
812 823
813int 824int
814Mix_AllocateChannels (int numchans = -1) 825Mix_AllocateChannels (int numchans = -1)
826
827const char *
828Mix_GetError ()
815 829
816void 830void
817lowdelay (int fd, int val = 1) 831lowdelay (int fd, int val = 1)
818 CODE: 832 CODE:
819 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&val, sizeof (val)); 833 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&val, sizeof (val));
861 STRLEN image_len; 875 STRLEN image_len;
862 char *image = (char *)SvPVbyte (image_, image_len); 876 char *image = (char *)SvPVbyte (image_, image_len);
863 SDL_Surface *surface, *surface2; 877 SDL_Surface *surface, *surface2;
864 SDL_PixelFormat fmt; 878 SDL_PixelFormat fmt;
865 SDL_RWops *rw = ix 879 SDL_RWops *rw = ix
866 ? SDL_RWFromFile (image, "r") 880 ? SDL_RWFromFile (image, "rb")
867 : SDL_RWFromConstMem (image, image_len); 881 : SDL_RWFromConstMem (image, image_len);
868 882
869 if (!rw) 883 if (!rw)
870 croak ("load_image: %s", SDL_GetError ()); 884 croak ("load_image: %s", SDL_GetError ());
871 885
1023 RETVAL->g = 1.; 1037 RETVAL->g = 1.;
1024 RETVAL->b = 1.; 1038 RETVAL->b = 1.;
1025 RETVAL->a = 1.; 1039 RETVAL->a = 1.;
1026 RETVAL->base_height = MIN_FONT_HEIGHT; 1040 RETVAL->base_height = MIN_FONT_HEIGHT;
1027 RETVAL->font = 0; 1041 RETVAL->font = 0;
1042 RETVAL->rc = rc_alloc ();
1028 1043
1029 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR); 1044 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
1030 layout_update_font (RETVAL); 1045 layout_update_font (RETVAL);
1031 OUTPUT: 1046 OUTPUT:
1032 RETVAL 1047 RETVAL
1033 1048
1034void 1049void
1035DESTROY (CFPlus::Layout self) 1050DESTROY (CFPlus::Layout self)
1036 CODE: 1051 CODE:
1037 g_object_unref (self->pl); 1052 g_object_unref (self->pl);
1053 rc_free (self->rc);
1038 Safefree (self); 1054 Safefree (self);
1039 1055
1040void 1056void
1041set_text (CFPlus::Layout self, SV *text_) 1057set_text (CFPlus::Layout self, SV *text_)
1042 CODE: 1058 CODE:
1294 } 1310 }
1295} 1311}
1296 1312
1297void 1313void
1298render (CFPlus::Layout self, float x, float y, int flags = 0) 1314render (CFPlus::Layout self, float x, float y, int flags = 0)
1299 PPCODE: 1315 CODE:
1316 rc_clear (self->rc);
1300 pango_opengl_render_layout_subpixel ( 1317 pango_opengl_render_layout_subpixel (
1301 self->pl, 1318 self->pl,
1319 self->rc,
1302 x * PANGO_SCALE, y * PANGO_SCALE, 1320 x * PANGO_SCALE, y * PANGO_SCALE,
1303 self->r, self->g, self->b, self->a, 1321 self->r, self->g, self->b, self->a,
1304 flags 1322 flags
1305 ); 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}
1306 1346
1307MODULE = CFPlus PACKAGE = CFPlus::Texture 1347MODULE = CFPlus PACKAGE = CFPlus::Texture
1308 1348
1309PROTOTYPES: ENABLE 1349PROTOTYPES: ENABLE
1310 1350
1342{ 1382{
1343 HV *hv = (HV *)SvRV (self); 1383 HV *hv = (HV *)SvRV (self);
1344 float s = SvNV (*hv_fetch (hv, "s", 1, 1)); 1384 float s = SvNV (*hv_fetch (hv, "s", 1, 1));
1345 float t = SvNV (*hv_fetch (hv, "t", 1, 1)); 1385 float t = SvNV (*hv_fetch (hv, "t", 1, 1));
1346 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;
1347 1390
1348 if (items < 5) 1391 if (items < 5)
1349 { 1392 {
1350 w = SvNV (*hv_fetch (hv, "w", 1, 1)); 1393 w = SvNV (*hv_fetch (hv, "w", 1, 1));
1351 h = SvNV (*hv_fetch (hv, "h", 1, 1)); 1394 h = SvNV (*hv_fetch (hv, "h", 1, 1));
1540 self->rows += MAP_EXTEND_Y; 1583 self->rows += MAP_EXTEND_Y;
1541 self->y += MAP_EXTEND_Y; 1584 self->y += MAP_EXTEND_Y;
1542 } 1585 }
1543} 1586}
1544 1587
1545void 1588SV *
1546map1a_update (CFPlus::Map self, SV *data_, int extmap) 1589map1a_update (CFPlus::Map self, SV *data_, int extmap)
1547 CODE: 1590 CODE:
1548{ 1591{
1549 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_); 1592 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_);
1550 uint8_t *data_end = (uint8_t *)SvEND (data_); 1593 uint8_t *data_end = (uint8_t *)SvEND (data_);
1551 mapcell *cell; 1594 mapcell *cell;
1552 int x, y, flags; 1595 int x, y, z, flags;
1596 AV *missing = newAV ();
1597 RETVAL = newRV_noinc ((SV *)missing);
1553 1598
1554 while (data < data_end - 1) 1599 while (data < data_end - 1)
1555 { 1600 {
1556 flags = (data [0] << 8) + data [1]; data += 2; 1601 flags = (data [0] << 8) + data [1]; data += 2;
1557 1602
1608 } 1653 }
1609 else 1654 else
1610 cell->darkness = *data++ + 1; 1655 cell->darkness = *data++ + 1;
1611 } 1656 }
1612 1657
1658 for (z = 0; z <= 2; ++z)
1613 if (flags & 4) 1659 if (flags & (4 >> z))
1614 { 1660 {
1615 faceid face = (data [0] << 8) + data [1]; data += 2; 1661 faceid face = (data [0] << 8) + data [1]; data += 2;
1616 need_facenum (self, face); 1662 need_facenum (self, face);
1617 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 }
1618 } 1678 }
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 } 1679 }
1634 else 1680 else
1635 cell->darkness = 0; 1681 cell->darkness = 0;
1636 } 1682 }
1637} 1683}
1684 OUTPUT:
1685 RETVAL
1638 1686
1639SV * 1687SV *
1640mapmap (CFPlus::Map self, int x0, int y0, int w, int h) 1688mapmap (CFPlus::Map self, int x0, int y0, int w, int h)
1641 CODE: 1689 CODE:
1642{ 1690{
1693 1741
1694void 1742void
1695draw (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)
1696 CODE: 1744 CODE:
1697{ 1745{
1746 int x, y, z;
1747
1698 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ()); 1748 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
1699 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
1700 static uint8_t smooth_max[256][256]; // egad, fats and wasteful on memory (64k) 1750 static uint8_t smooth_max[256][256]; // egad, fast and wasteful on memory (64k)
1701 smooth_key skey; 1751 smooth_key skey;
1702 int x, y, z; 1752
1703 int last_name; 1753 rc_t *rc = rc_alloc ();
1754 rc_key_t key;
1755 rc_array_t *arr;
1704 1756
1705 // thats current max. sorry. 1757 // thats current max. sorry.
1706 if (sw > 255) sw = 255; 1758 if (sw > 255) sw = 255;
1707 if (sh > 255) sh = 255; 1759 if (sh > 255) sh = 255;
1708 1760
1709 // clear key, in case of extra padding 1761 // clear key, in case of extra padding
1710 memset (&skey, 0, sizeof (skey)); 1762 memset (&skey, 0, sizeof (skey));
1711 1763
1712 glColor4ub (255, 255, 255, 255); 1764 memset (&key, 0, sizeof (key));
1713 1765 key.r = 255;
1714 glEnable (GL_BLEND); 1766 key.g = 255;
1715 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1767 key.b = 255;
1716 glEnable (GL_TEXTURE_2D); 1768 key.a = 255;
1717 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1769 key.mode = GL_QUADS;
1718 1770 key.format = GL_T2F_V3F;
1719 glBegin (GL_QUADS); 1771 key.texname = -1;
1720
1721 last_name = 0;
1722 1772
1723 mx += self->x; 1773 mx += self->x;
1724 my += self->y; 1774 my += self->y;
1725 1775
1726 // first pass: determine smooth_max 1776 // first pass: determine smooth_max
1742 MAX (self->tex [cell->tile [0]].smoothlevel, 1792 MAX (self->tex [cell->tile [0]].smoothlevel,
1743 MAX (self->tex [cell->tile [1]].smoothlevel, 1793 MAX (self->tex [cell->tile [1]].smoothlevel,
1744 self->tex [cell->tile [2]].smoothlevel)); 1794 self->tex [cell->tile [2]].smoothlevel));
1745 } 1795 }
1746 } 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);
1747 1801
1748 for (z = 0; z <= 2; z++) 1802 for (z = 0; z <= 2; z++)
1749 { 1803 {
1750 memset (smooth_level, 0, sizeof (smooth_level)); 1804 memset (smooth_level, 0, sizeof (smooth_level));
1751 1805
1761 tileid tile = cell->tile [z]; 1815 tileid tile = cell->tile [z];
1762 1816
1763 if (tile) 1817 if (tile)
1764 { 1818 {
1765 maptex tex = self->tex [tile]; 1819 maptex tex = self->tex [tile];
1766 int px = (x + 1) * T - tex.w; 1820 int px, py;
1767 int py = (y + 1) * T - tex.h;
1768 1821
1769 // suppressing texture state switches here
1770 // is only moderately effective, but worth the extra effort
1771 if (last_name != tex.name) 1822 if (key.texname != tex.name)
1772 { 1823 {
1773 if (!tex.name) 1824 if (!tex.name)
1774 tex = self->tex [2]; /* missing, replace by noface */ 1825 tex = self->tex [2]; /* missing, replace by noface */
1775 1826
1776 glEnd (); 1827 key.texname = tex.name;
1777 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1828 arr = rc_array (rc, &key);
1778 glBegin (GL_QUADS);
1779 } 1829 }
1780 1830
1781 glTexCoord2f (0 , 0 ); glVertex2f (px , py ); 1831 px = (x + 1) * T - tex.w;
1832 py = (y + 1) * T - tex.h;
1833
1834 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
1782 glTexCoord2f (0 , tex.t); glVertex2f (px , py + tex.h); 1835 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); 1836 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 ); 1837 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0);
1785 1838
1786 if (cell->flags && z == 2) 1839 if (cell->flags && z == 2)
1787 { 1840 {
1841 // overlays such as the speech bubble, probably more to come
1788 if (cell->flags & 1) 1842 if (cell->flags & 1)
1789 { 1843 {
1790 maptex tex = self->tex [1]; 1844 maptex tex = self->tex [1];
1791 int px = x * T + T * 2 / 32; 1845 int px = x * T + T * 2 / 32;
1792 int py = y * T - T * 6 / 32; 1846 int py = y * T - T * 6 / 32;
1793 1847
1848 if (tex.name)
1794 glEnd (); 1849 {
1795 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1850 if (key.texname != tex.name)
1851 {
1852 key.texname = tex.name;
1853 arr = rc_array (rc, &key);
1854 }
1855
1856 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
1857 rc_t2f_v3f (arr, 0 , tex.t, px , py + T, 0);
1858 rc_t2f_v3f (arr, tex.s, tex.t, px + T, py + T, 0);
1859 rc_t2f_v3f (arr, tex.s, 0 , px + T, py , 0);
1796 glBegin (GL_QUADS); 1860 }
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 } 1861 }
1803 } 1862 }
1804 1863
1805 // update smooth hash 1864 // update smooth hash
1806 if (tex.smoothtile) 1865 if (tex.smoothtile)
1842 } 1901 }
1843 } 1902 }
1844 } 1903 }
1845 } 1904 }
1846 1905
1906 rc_draw (rc);
1907 rc_clear (rc);
1908
1847 // go through all smoothlevels, lowest to highest, then draw. 1909 // go through all smoothlevels, lowest to highest, then draw.
1848 // this is basically counting sort 1910 // this is basically counting sort
1849 { 1911 {
1850 int w, b; 1912 int w, b;
1851 1913
1914 glEnable (GL_TEXTURE_2D);
1915 glBegin (GL_QUADS);
1852 for (w = 0; w < 256 / 32; ++w) 1916 for (w = 0; w < 256 / 32; ++w)
1853 { 1917 {
1854 uint32_t smask = smooth_level [w]; 1918 uint32_t smask = smooth_level [w];
1855 if (smask) 1919 if (smask)
1856 for (b = 0; b < 32; ++b) 1920 for (b = 0; b < 32; ++b)
1875 int border = bits & 15; 1939 int border = bits & 15;
1876 int corner = (bits >> 8) & ~(bits >> 4) & 15; 1940 int corner = (bits >> 8) & ~(bits >> 4) & 15;
1877 float dx = tex.s * .0625f; // 16 images/row 1941 float dx = tex.s * .0625f; // 16 images/row
1878 float dy = tex.t * .5f ; // 2 images/column 1942 float dy = tex.t * .5f ; // 2 images/column
1879 1943
1880 // this time naively avoiding texture state changes
1881 // save gobs of state changes.
1882 if (last_name != tex.name) 1944 if (tex.name)
1883 { 1945 {
1946 // this time avoiding texture state changes
1947 // save gobs of state changes.
1884 if (!tex.name) 1948 if (key.texname != tex.name)
1885 continue; // smoothing not yet available 1949 {
1886
1887 glEnd (); 1950 glEnd ();
1888 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1951 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name);
1889 glBegin (GL_QUADS); 1952 glBegin (GL_QUADS);
1890 } 1953 }
1891 1954
1892 if (border) 1955 if (border)
1893 { 1956 {
1894 float ox = border * dx; 1957 float ox = border * dx;
1895 1958
1896 glTexCoord2f (ox , 0.f ); glVertex2f (px , py ); 1959 glTexCoord2f (ox , 0.f ); glVertex2i (px , py );
1897 glTexCoord2f (ox , dy ); glVertex2f (px , py + T); 1960 glTexCoord2f (ox , dy ); glVertex2i (px , py + T);
1898 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py + T); 1961 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py + T);
1899 glTexCoord2f (ox + dx, 0.f ); glVertex2f (px + T, py ); 1962 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + T, py );
1900 } 1963 }
1901 1964
1902 if (corner) 1965 if (corner)
1903 { 1966 {
1904 float ox = corner * dx; 1967 float ox = corner * dx;
1905 1968
1906 glTexCoord2f (ox , dy ); glVertex2f (px , py ); 1969 glTexCoord2f (ox , dy ); glVertex2i (px , py );
1907 glTexCoord2f (ox , dy * 2.f); glVertex2f (px , py + T); 1970 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + T);
1908 glTexCoord2f (ox + dx, dy * 2.f); glVertex2f (px + T, py + T); 1971 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + T, py + T);
1909 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py ); 1972 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py );
1973 }
1910 } 1974 }
1911 } 1975 }
1912 } 1976 }
1913 } 1977 }
1914 } 1978 }
1979
1980 glEnd ();
1981 glDisable (GL_TEXTURE_2D);
1982 key.texname = -1;
1915 } 1983 }
1916 1984
1917 hv_clear (smooth); 1985 hv_clear (smooth);
1918 } 1986 }
1919 1987
1920 glEnd ();
1921
1922 glDisable (GL_TEXTURE_2D);
1923 glDisable (GL_BLEND); 1988 glDisable (GL_BLEND);
1989 rc_free (rc);
1924 1990
1925 // top layer: overlays such as the health bar 1991 // top layer: overlays such as the health bar
1926 for (y = 0; y < sh; y++) 1992 for (y = 0; y < sh; y++)
1927 if (0 <= y + my && y + my < self->rows) 1993 if (0 <= y + my && y + my < self->rows)
1928 { 1994 {
2177 int x, y, z; 2243 int x, y, z;
2178 int w, h; 2244 int w, h;
2179 int x1, y1; 2245 int x1, y1;
2180 2246
2181 if (*data++ != 0) 2247 if (*data++ != 0)
2182 return; /* version mismatch */ 2248 XSRETURN_EMPTY; /* version mismatch */
2183 2249
2184 w = *data++ << 8; w |= *data++; 2250 w = *data++ << 8; w |= *data++;
2185 h = *data++ << 8; h |= *data++; 2251 h = *data++ << 8; h |= *data++;
2186 2252
2187 // we need to do this 'cause we don't keep an absolute coord system for rows 2253 // we need to do this 'cause we don't keep an absolute coord system for rows
2232 } 2298 }
2233 } 2299 }
2234 } 2300 }
2235} 2301}
2236 2302
2303MODULE = CFPlus PACKAGE = CFPlus::RW
2304
2305CFPlus::RW
2306new (SV *class, SV *data_sv)
2307 CODE:
2308{
2309 STRLEN datalen;
2310 char *data = SvPVbyte (data_sv, datalen);
2311
2312 RETVAL = SDL_RWFromConstMem (data, datalen);
2313}
2314 OUTPUT:
2315 RETVAL
2316
2317CFPlus::RW
2318new_from_file (SV *class, const char *path, const char *mode = "rb")
2319 CODE:
2320 RETVAL = SDL_RWFromFile (path, mode);
2321 OUTPUT:
2322 RETVAL
2323
2324# fails on win32:
2325# CFPlus.xs(2268) : error C2059: syntax error : '('
2326#void
2327#close (CFPlus::RW self)
2328# CODE:
2329# (self->(close)) (self);
2330
2331MODULE = CFPlus PACKAGE = CFPlus::Channel
2332
2333PROTOTYPES: DISABLE
2334
2335CFPlus::Channel
2336find ()
2337 CODE:
2338{
2339 RETVAL = Mix_GroupAvailable (-1);
2340
2341 if (RETVAL < 0)
2342 {
2343 RETVAL = Mix_GroupOldest (-1);
2344
2345 if (RETVAL < 0)
2346 XSRETURN_UNDEF;
2347
2348 Mix_HaltChannel (RETVAL);
2349 }
2350
2351 Mix_UnregisterAllEffects (RETVAL);
2352 Mix_Volume (RETVAL, 128);
2353}
2354 OUTPUT:
2355 RETVAL
2356
2357void
2358halt (CFPlus::Channel self)
2359 CODE:
2360 Mix_HaltChannel (self);
2361
2362void
2363expire (CFPlus::Channel self, int ticks = -1)
2364 CODE:
2365 Mix_ExpireChannel (self, ticks);
2366
2367void
2368fade_out (CFPlus::Channel self, int ticks = -1)
2369 CODE:
2370 Mix_FadeOutChannel (self, ticks);
2371
2372int
2373volume (CFPlus::Channel self, int volume)
2374 CODE:
2375 RETVAL = Mix_Volume (self, CLAMP (volume, 0, 128));
2376 OUTPUT:
2377 RETVAL
2378
2379void
2380unregister_all_effects (CFPlus::Channel self)
2381 CODE:
2382 Mix_UnregisterAllEffects (self);
2383
2384void
2385set_panning (CFPlus::Channel self, int left, int right)
2386 CODE:
2387 left = CLAMP (left , 0, 255);
2388 right = CLAMP (right, 0, 255);
2389 Mix_SetPanning (self, left, right);
2390
2391void
2392set_distance (CFPlus::Channel self, int distance)
2393 CODE:
2394 Mix_SetDistance (self, CLAMP (distance, 0, 255));
2395
2396void
2397set_position (CFPlus::Channel self, int angle, int distance)
2398 CODE:
2399
2400void
2401set_position_r (CFPlus::Channel self, int dx, int dy, int maxdistance)
2402 CODE:
2403{
2404 int distance = sqrtf (dx * dx + dy * dy) * (255.f / sqrtf (maxdistance * maxdistance));
2405 int angle = 360 + (int)roundf (atan2f (dx, -dy) * 180.f / (float)M_PI);
2406 Mix_SetPosition (self, angle, CLAMP (distance, 0, 255));
2407}
2408
2409void
2410set_reverse_stereo (CFPlus::Channel self, int flip)
2411 CODE:
2412 Mix_SetReverseStereo (self, flip);
2413
2237MODULE = CFPlus PACKAGE = CFPlus::MixChunk 2414MODULE = CFPlus PACKAGE = CFPlus::MixChunk
2238 2415
2239PROTOTYPES: DISABLE 2416PROTOTYPES: DISABLE
2240 2417
2241CFPlus::MixChunk 2418CFPlus::MixChunk
2242new_from_file (SV *class, char *path) 2419new (SV *class, CFPlus::RW rwops)
2243 CODE: 2420 CODE:
2244 RETVAL = Mix_LoadWAV (path); 2421 RETVAL = Mix_LoadWAV_RW (rwops, 1);
2245 OUTPUT: 2422 OUTPUT:
2246 RETVAL 2423 RETVAL
2247 2424
2248void 2425void
2249DESTROY (CFPlus::MixChunk self) 2426DESTROY (CFPlus::MixChunk self)
2251 Mix_FreeChunk (self); 2428 Mix_FreeChunk (self);
2252 2429
2253int 2430int
2254volume (CFPlus::MixChunk self, int volume = -1) 2431volume (CFPlus::MixChunk self, int volume = -1)
2255 CODE: 2432 CODE:
2433 if (items > 1)
2434 volume = CLAMP (volume, 0, 128);
2256 RETVAL = Mix_VolumeChunk (self, volume); 2435 RETVAL = Mix_VolumeChunk (self, volume);
2257 OUTPUT: 2436 OUTPUT:
2258 RETVAL 2437 RETVAL
2259 2438
2260int 2439CFPlus::Channel
2261play (CFPlus::MixChunk self, int channel = -1, int loops = 0, int ticks = -1) 2440play (CFPlus::MixChunk self, CFPlus::Channel channel = -1, int loops = 0, int ticks = -1)
2262 CODE: 2441 CODE:
2442{
2263 RETVAL = Mix_PlayChannelTimed (channel, self, loops, ticks); 2443 RETVAL = Mix_PlayChannelTimed (channel, self, loops, ticks);
2444
2445 if (RETVAL < 0)
2446 XSRETURN_UNDEF;
2447
2448 if (channel < 0)
2449 {
2450 Mix_UnregisterAllEffects (RETVAL);
2451 Mix_Volume (RETVAL, 128);
2452 }
2453}
2264 OUTPUT: 2454 OUTPUT:
2265 RETVAL 2455 RETVAL
2266 2456
2267MODULE = CFPlus PACKAGE = CFPlus::MixMusic 2457MODULE = CFPlus PACKAGE = CFPlus::MixMusic
2268 2458
2269int 2459int
2270volume (int volume = -1) 2460volume (int volume = -1)
2271 PROTOTYPE: ;$ 2461 PROTOTYPE: ;$
2272 CODE: 2462 CODE:
2463 if (items > 0)
2464 volume = CLAMP (volume, 0, 128);
2273 RETVAL = Mix_VolumeMusic (volume); 2465 RETVAL = Mix_VolumeMusic (volume);
2274 OUTPUT: 2466 OUTPUT:
2275 RETVAL 2467 RETVAL
2276 2468
2277int 2469void
2278fade_out (int ms) 2470fade_out (int ms)
2279 CODE: 2471 CODE:
2280 RETVAL = Mix_FadeOutMusic (ms); 2472 Mix_FadeOutMusic (ms);
2281 OUTPUT: 2473
2282 RETVAL 2474void
2475halt ()
2476 CODE:
2477 Mix_HaltMusic ();
2283 2478
2284CFPlus::MixMusic 2479CFPlus::MixMusic
2285new_from_file (SV *class, char *path) 2480new (SV *class, CFPlus::RW rwops)
2286 CODE: 2481 CODE:
2287 RETVAL = Mix_LoadMUS (path); 2482 RETVAL = Mix_LoadMUS_RW (rwops);
2288 OUTPUT: 2483 OUTPUT:
2289 RETVAL 2484 RETVAL
2290 2485
2291void 2486void
2292DESTROY (CFPlus::MixMusic self) 2487DESTROY (CFPlus::MixMusic self)
2298 CODE: 2493 CODE:
2299 RETVAL = Mix_PlayMusic (self, loops); 2494 RETVAL = Mix_PlayMusic (self, loops);
2300 OUTPUT: 2495 OUTPUT:
2301 RETVAL 2496 RETVAL
2302 2497
2303int 2498void
2304fade_in_pos (CFPlus::MixMusic self, int loops, int ms, double position) 2499fade_in_pos (CFPlus::MixMusic self, int loops, int ms, double position)
2305 CODE: 2500 CODE:
2306 RETVAL = Mix_FadeInMusicPos (self, loops, ms, position); 2501 Mix_FadeInMusicPos (self, loops, ms, position);
2307 OUTPUT:
2308 RETVAL
2309 2502
2310MODULE = CFPlus PACKAGE = CFPlus::OpenGL 2503MODULE = CFPlus PACKAGE = CFPlus::OpenGL
2311 2504
2312PROTOTYPES: ENABLE 2505PROTOTYPES: ENABLE
2313 2506
2356 const_iv (GL_INTENSITY), 2549 const_iv (GL_INTENSITY),
2357 const_iv (GL_LUMINANCE), 2550 const_iv (GL_LUMINANCE),
2358 const_iv (GL_LUMINANCE_ALPHA), 2551 const_iv (GL_LUMINANCE_ALPHA),
2359 const_iv (GL_FLOAT), 2552 const_iv (GL_FLOAT),
2360 const_iv (GL_UNSIGNED_INT_8_8_8_8_REV), 2553 const_iv (GL_UNSIGNED_INT_8_8_8_8_REV),
2554 const_iv (GL_COMPRESSED_ALPHA_ARB),
2555 const_iv (GL_COMPRESSED_LUMINANCE_ARB),
2556 const_iv (GL_COMPRESSED_LUMINANCE_ALPHA_ARB),
2557 const_iv (GL_COMPRESSED_INTENSITY_ARB),
2558 const_iv (GL_COMPRESSED_RGB_ARB),
2559 const_iv (GL_COMPRESSED_RGBA_ARB),
2361 const_iv (GL_COMPILE), 2560 const_iv (GL_COMPILE),
2362 const_iv (GL_PROXY_TEXTURE_1D), 2561 const_iv (GL_PROXY_TEXTURE_1D),
2363 const_iv (GL_PROXY_TEXTURE_2D), 2562 const_iv (GL_PROXY_TEXTURE_2D),
2364 const_iv (GL_TEXTURE_1D), 2563 const_iv (GL_TEXTURE_1D),
2365 const_iv (GL_TEXTURE_2D), 2564 const_iv (GL_TEXTURE_2D),
2421 2620
2422 texture_av = newAV (); 2621 texture_av = newAV ();
2423 AvREAL_off (texture_av); 2622 AvREAL_off (texture_av);
2424} 2623}
2425 2624
2625void
2626disable_GL_EXT_blend_func_separate ()
2627 CODE:
2628 gl.BlendFuncSeparate = 0;
2629 gl.BlendFuncSeparateEXT = 0;
2630
2426char * 2631char *
2427gl_vendor () 2632gl_vendor ()
2428 CODE: 2633 CODE:
2429 RETVAL = (char *)glGetString (GL_VENDOR); 2634 RETVAL = (char *)glGetString (GL_VENDOR);
2430 OUTPUT: 2635 OUTPUT:
2547 2752
2548void glTexCoord (float s, float t) 2753void glTexCoord (float s, float t)
2549 CODE: 2754 CODE:
2550 glTexCoord2f (s, t); 2755 glTexCoord2f (s, t);
2551 2756
2757void glRect (float x1, float y1, float x2, float y2)
2758 CODE:
2759 glRectf (x1, y1, x2, y2);
2760
2552PROTOTYPES: ENABLE 2761PROTOTYPES: ENABLE
2553 2762
2554void glBegin (int mode) 2763void glBegin (int mode)
2555 2764
2556void glEnd () 2765void glEnd ()
2657 NV x, y, w, h; 2866 NV x, y, w, h;
2658 SV *draw_x_sv = GvSV (draw_x_gv); 2867 SV *draw_x_sv = GvSV (draw_x_gv);
2659 SV *draw_y_sv = GvSV (draw_y_gv); 2868 SV *draw_y_sv = GvSV (draw_y_gv);
2660 SV *draw_w_sv = GvSV (draw_w_gv); 2869 SV *draw_w_sv = GvSV (draw_w_gv);
2661 SV *draw_h_sv = GvSV (draw_h_gv); 2870 SV *draw_h_sv = GvSV (draw_h_gv);
2662 SV *hover;
2663 double draw_x, draw_y, draw_w, draw_h; 2871 double draw_x, draw_y;
2664 2872
2665 if (!SvROK (self)) 2873 if (!SvROK (self))
2666 croak ("CFPlus::Base::draw: %s not a reference", SvPV_nolen (self)); 2874 croak ("CFPlus::Base::draw: %s not a reference", SvPV_nolen (self));
2667 2875
2668 hv = (HV *)SvRV (self); 2876 hv = (HV *)SvRV (self);
2696 { 2904 {
2697 svp = hv_fetch (hv, "can_hover", sizeof ("can_hover") - 1, 0); 2905 svp = hv_fetch (hv, "can_hover", sizeof ("can_hover") - 1, 0);
2698 2906
2699 if (svp && SvTRUE (*svp)) 2907 if (svp && SvTRUE (*svp))
2700 { 2908 {
2701 glColor4f (1*0.2f, 0.8*0.2f, 0.5*0.2f, 0.2f); 2909 glColor4f (1.0f * 0.2f, 0.8f * 0.2f, 0.5f * 0.2f, 0.2f);
2702 glEnable (GL_BLEND); 2910 glEnable (GL_BLEND);
2703 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 2911 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
2704 glBegin (GL_QUADS); 2912 glBegin (GL_QUADS);
2705 glVertex2f (0, 0); 2913 glVertex2f (0, 0);
2706 glVertex2f (w, 0); 2914 glVertex2f (w, 0);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines