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.219 by root, Mon Aug 6 05:06:32 2007 UTC vs.
Revision 1.224 by root, Sat Aug 11 11:21:46 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
1550 self->rows += MAP_EXTEND_Y; 1556 self->rows += MAP_EXTEND_Y;
1551 self->y += MAP_EXTEND_Y; 1557 self->y += MAP_EXTEND_Y;
1552 } 1558 }
1553} 1559}
1554 1560
1555void 1561SV *
1556map1a_update (CFPlus::Map self, SV *data_, int extmap) 1562map1a_update (CFPlus::Map self, SV *data_, int extmap)
1557 CODE: 1563 CODE:
1558{ 1564{
1559 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_); 1565 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_);
1560 uint8_t *data_end = (uint8_t *)SvEND (data_); 1566 uint8_t *data_end = (uint8_t *)SvEND (data_);
1561 mapcell *cell; 1567 mapcell *cell;
1562 int x, y, flags; 1568 int x, y, z, flags;
1569 AV *missing = newAV ();
1570 RETVAL = newRV_noinc ((SV *)missing);
1563 1571
1564 while (data < data_end - 1) 1572 while (data < data_end - 1)
1565 { 1573 {
1566 flags = (data [0] << 8) + data [1]; data += 2; 1574 flags = (data [0] << 8) + data [1]; data += 2;
1567 1575
1618 } 1626 }
1619 else 1627 else
1620 cell->darkness = *data++ + 1; 1628 cell->darkness = *data++ + 1;
1621 } 1629 }
1622 1630
1631 for (z = 0; z <= 2; ++z)
1623 if (flags & 4) 1632 if (flags & (4 >> z))
1624 { 1633 {
1625 faceid face = (data [0] << 8) + data [1]; data += 2; 1634 faceid face = (data [0] << 8) + data [1]; data += 2;
1626 need_facenum (self, face); 1635 need_facenum (self, face);
1627 cell->tile [0] = self->face2tile [face]; 1636 cell->tile [z] = self->face2tile [face];
1637
1638 if (cell->tile [z])
1639 {
1640 maptex *tex = self->tex + cell->tile [z];
1641 if (!tex->name)
1642 av_push (missing, newSViv (cell->tile [z]));
1643
1644 if (tex->smoothtile)
1645 {
1646 maptex *smooth = self->tex + tex->smoothtile;
1647 if (!smooth->name)
1648 av_push (missing, newSViv (tex->smoothtile));
1649 }
1650 }
1628 } 1651 }
1629
1630 if (flags & 2)
1631 {
1632 faceid face = (data [0] << 8) + data [1]; data += 2;
1633 need_facenum (self, face);
1634 cell->tile [1] = self->face2tile [face];
1635 }
1636
1637 if (flags & 1)
1638 {
1639 faceid face = (data [0] << 8) + data [1]; data += 2;
1640 need_facenum (self, face);
1641 cell->tile [2] = self->face2tile [face];
1642 }
1643 } 1652 }
1644 else 1653 else
1645 cell->darkness = 0; 1654 cell->darkness = 0;
1646 } 1655 }
1647} 1656}
1657 OUTPUT:
1658 RETVAL
1648 1659
1649SV * 1660SV *
1650mapmap (CFPlus::Map self, int x0, int y0, int w, int h) 1661mapmap (CFPlus::Map self, int x0, int y0, int w, int h)
1651 CODE: 1662 CODE:
1652{ 1663{
1699 RETVAL = map_sv; 1710 RETVAL = map_sv;
1700} 1711}
1701 OUTPUT: 1712 OUTPUT:
1702 RETVAL 1713 RETVAL
1703 1714
1704SV * 1715void
1705draw (CFPlus::Map self, int mx, int my, int sw, int sh, int T) 1716draw (CFPlus::Map self, int mx, int my, int sw, int sh, int T)
1706 CODE: 1717 CODE:
1707{ 1718{
1719 int x, y, z;
1720
1708 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ()); 1721 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
1709 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level 1722 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level
1710 static uint8_t smooth_max[256][256]; // egad, fats and wasteful on memory (64k) 1723 static uint8_t smooth_max[256][256]; // egad, fats and wasteful on memory (64k)
1711 smooth_key skey; 1724 smooth_key skey;
1712 int x, y, z; 1725
1713 int last_name; 1726 rc_t *rc = rc_alloc ();
1714 AV *missing = newAV (); 1727 rc_key_t key;
1715 RETVAL = newRV_noinc ((SV *)missing); 1728 rc_array_t *arr;
1716 1729
1717 // thats current max. sorry. 1730 // thats current max. sorry.
1718 if (sw > 255) sw = 255; 1731 if (sw > 255) sw = 255;
1719 if (sh > 255) sh = 255; 1732 if (sh > 255) sh = 255;
1720 1733
1721 // clear key, in case of extra padding 1734 // clear key, in case of extra padding
1722 memset (&skey, 0, sizeof (skey)); 1735 memset (&skey, 0, sizeof (skey));
1723 1736
1724 glColor4ub (255, 255, 255, 255); 1737 memset (&key, 0, sizeof (key));
1725 1738 key.r = 255;
1726 glEnable (GL_BLEND); 1739 key.g = 255;
1727 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1740 key.b = 255;
1728 glEnable (GL_TEXTURE_2D); 1741 key.a = 255;
1729 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1742 key.mode = GL_QUADS;
1730 1743 key.format = GL_T2F_V3F;
1731 glBegin (GL_QUADS);
1732
1733 last_name = -1; 1744 key.texname = -1;
1734 1745
1735 mx += self->x; 1746 mx += self->x;
1736 my += self->y; 1747 my += self->y;
1737 1748
1738 // first pass: determine smooth_max 1749 // first pass: determine smooth_max
1754 MAX (self->tex [cell->tile [0]].smoothlevel, 1765 MAX (self->tex [cell->tile [0]].smoothlevel,
1755 MAX (self->tex [cell->tile [1]].smoothlevel, 1766 MAX (self->tex [cell->tile [1]].smoothlevel,
1756 self->tex [cell->tile [2]].smoothlevel)); 1767 self->tex [cell->tile [2]].smoothlevel));
1757 } 1768 }
1758 } 1769 }
1770
1771 glEnable (GL_BLEND);
1772 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1773 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1759 1774
1760 for (z = 0; z <= 2; z++) 1775 for (z = 0; z <= 2; z++)
1761 { 1776 {
1762 memset (smooth_level, 0, sizeof (smooth_level)); 1777 memset (smooth_level, 0, sizeof (smooth_level));
1763 1778
1777 maptex tex = self->tex [tile]; 1792 maptex tex = self->tex [tile];
1778 int px, py; 1793 int px, py;
1779 1794
1780 // suppressing texture state switches here 1795 // suppressing texture state switches here
1781 // is only moderately effective, but worth the extra effort 1796 // is only moderately effective, but worth the extra effort
1782 if (last_name != tex.name) 1797 if (key.texname != tex.name)
1783 { 1798 {
1784 if (!tex.name) 1799 if (!tex.name)
1785 {
1786 av_push (missing, newSViv (tile));
1787 tex = self->tex [2]; /* missing, replace by noface */ 1800 tex = self->tex [2]; /* missing, replace by noface */
1788 }
1789 1801
1790 glEnd (); 1802 key.texname = tex.name;
1791 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1803 arr = rc_array (rc, &key);
1792 glBegin (GL_QUADS);
1793 } 1804 }
1794 1805
1795 px = (x + 1) * T - tex.w; 1806 px = (x + 1) * T - tex.w;
1796 py = (y + 1) * T - tex.h; 1807 py = (y + 1) * T - tex.h;
1797 1808
1798 glTexCoord2f (0 , 0 ); glVertex2f (px , py ); 1809 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
1799 glTexCoord2f (0 , tex.t); glVertex2f (px , py + tex.h); 1810 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0);
1800 glTexCoord2f (tex.s, tex.t); glVertex2f (px + tex.w, py + tex.h); 1811 rc_t2f_v3f (arr, tex.s, tex.t, px + tex.w, py + tex.h, 0);
1801 glTexCoord2f (tex.s, 0 ); glVertex2f (px + tex.w, py ); 1812 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0);
1802 1813
1803 if (cell->flags && z == 2) 1814 if (cell->flags && z == 2)
1804 { 1815 {
1816 // overlays such as the speech bubble, probably more to come
1805 if (cell->flags & 1) 1817 if (cell->flags & 1)
1806 { 1818 {
1807 maptex tex = self->tex [1]; 1819 maptex tex = self->tex [1];
1808 int px = x * T + T * 2 / 32; 1820 int px = x * T + T * 2 / 32;
1809 int py = y * T - T * 6 / 32; 1821 int py = y * T - T * 6 / 32;
1810 1822
1823 if (tex.name)
1811 glEnd (); 1824 {
1812 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1825 if (key.texname != tex.name)
1826 {
1827 key.texname = tex.name;
1828 arr = rc_array (rc, &key);
1829 }
1830
1831 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
1832 rc_t2f_v3f (arr, 0 , tex.t, px , py + T, 0);
1833 rc_t2f_v3f (arr, tex.s, tex.t, px + T, py + T, 0);
1834 rc_t2f_v3f (arr, tex.s, 0 , px + T, py , 0);
1813 glBegin (GL_QUADS); 1835 }
1814
1815 glTexCoord2f (0 , 0 ); glVertex2f (px , py );
1816 glTexCoord2f (0 , tex.t); glVertex2f (px , py + T);
1817 glTexCoord2f (tex.s, tex.t); glVertex2f (px + T, py + T);
1818 glTexCoord2f (tex.s, 0 ); glVertex2f (px + T, py );
1819 } 1836 }
1820 } 1837 }
1821 1838
1822 // update smooth hash 1839 // update smooth hash
1823 if (tex.smoothtile) 1840 if (tex.smoothtile)
1858 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0800); 1875 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0800);
1859 } 1876 }
1860 } 1877 }
1861 } 1878 }
1862 } 1879 }
1880
1881 rc_draw (rc);
1882 rc_clear (rc);
1863 1883
1864 // go through all smoothlevels, lowest to highest, then draw. 1884 // go through all smoothlevels, lowest to highest, then draw.
1865 // this is basically counting sort 1885 // this is basically counting sort
1866 { 1886 {
1867 int w, b; 1887 int w, b;
1892 int border = bits & 15; 1912 int border = bits & 15;
1893 int corner = (bits >> 8) & ~(bits >> 4) & 15; 1913 int corner = (bits >> 8) & ~(bits >> 4) & 15;
1894 float dx = tex.s * .0625f; // 16 images/row 1914 float dx = tex.s * .0625f; // 16 images/row
1895 float dy = tex.t * .5f ; // 2 images/column 1915 float dy = tex.t * .5f ; // 2 images/column
1896 1916
1897 // this time naively avoiding texture state changes
1898 // save gobs of state changes.
1899 if (last_name != tex.name) 1917 if (tex.name)
1900 { 1918 {
1919 // this time avoiding texture state changes
1920 // save gobs of state changes.
1901 if (!tex.name) 1921 if (key.texname != tex.name)
1902 { 1922 {
1903 av_push (missing, newSViv (skey->tile)); 1923 key.texname = tex.name;
1904 continue; // smoothing not yet available 1924 arr = rc_array (rc, &key);
1905 } 1925 }
1906 1926
1907 glEnd ();
1908 glBindTexture (GL_TEXTURE_2D, last_name = tex.name);
1909 glBegin (GL_QUADS);
1910 }
1911
1912 if (border) 1927 if (border)
1913 { 1928 {
1914 float ox = border * dx; 1929 float ox = border * dx;
1915 1930
1916 glTexCoord2f (ox , 0.f ); glVertex2f (px , py ); 1931 rc_t2f_v3f (arr, ox , 0.f , px , py , 0);
1917 glTexCoord2f (ox , dy ); glVertex2f (px , py + T); 1932 rc_t2f_v3f (arr, ox , dy , px , py + T, 0);
1918 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py + T); 1933 rc_t2f_v3f (arr, ox + dx, dy , px + T, py + T, 0);
1919 glTexCoord2f (ox + dx, 0.f ); glVertex2f (px + T, py ); 1934 rc_t2f_v3f (arr, ox + dx, 0.f , px + T, py , 0);
1920 } 1935 }
1921 1936
1922 if (corner) 1937 if (corner)
1923 { 1938 {
1924 float ox = corner * dx; 1939 float ox = corner * dx;
1925 1940
1926 glTexCoord2f (ox , dy ); glVertex2f (px , py ); 1941 rc_t2f_v3f (arr, ox , dy , px , py , 0);
1927 glTexCoord2f (ox , dy * 2.f); glVertex2f (px , py + T); 1942 rc_t2f_v3f (arr, ox , dy * 2.f, px , py + T, 0);
1928 glTexCoord2f (ox + dx, dy * 2.f); glVertex2f (px + T, py + T); 1943 rc_t2f_v3f (arr, ox + dx, dy * 2.f, px + T, py + T, 0);
1929 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py ); 1944 rc_t2f_v3f (arr, ox + dx, dy , px + T, py , 0);
1945 }
1930 } 1946 }
1931 } 1947 }
1932 } 1948 }
1933 } 1949 }
1934 } 1950 }
1935 } 1951 }
1936 1952
1937 hv_clear (smooth); 1953 hv_clear (smooth);
1954 rc_draw (rc);
1955 rc_clear (rc);
1938 } 1956 }
1939 1957
1940 glEnd ();
1941
1942 glDisable (GL_TEXTURE_2D);
1943 glDisable (GL_BLEND); 1958 glDisable (GL_BLEND);
1959 rc_free (rc);
1944 1960
1945 // top layer: overlays such as the health bar 1961 // top layer: overlays such as the health bar
1946 for (y = 0; y < sh; y++) 1962 for (y = 0; y < sh; y++)
1947 if (0 <= y + my && y + my < self->rows) 1963 if (0 <= y + my && y + my < self->rows)
1948 { 1964 {
1971 px + width - 2 - cell->stat_hp * (width - 4) / 255, py - 1); 1987 px + width - 2 - cell->stat_hp * (width - 4) / 255, py - 1);
1972 } 1988 }
1973 } 1989 }
1974 } 1990 }
1975} 1991}
1976 OUTPUT:
1977 RETVAL
1978 1992
1979void 1993void
1980draw_magicmap (CFPlus::Map self, int dx, int dy, int w, int h, unsigned char *data) 1994draw_magicmap (CFPlus::Map self, int dx, int dy, int w, int h, unsigned char *data)
1981 CODE: 1995 CODE:
1982{ 1996{
2350 Mix_SetDistance (self, CLAMP (distance, 0, 255)); 2364 Mix_SetDistance (self, CLAMP (distance, 0, 255));
2351 2365
2352void 2366void
2353set_position (CFPlus::Channel self, int angle, int distance) 2367set_position (CFPlus::Channel self, int angle, int distance)
2354 CODE: 2368 CODE:
2369
2370void
2371set_position_r (CFPlus::Channel self, int dx, int dy, int maxdistance)
2372 CODE:
2373{
2374 int distance = sqrtf (dx * dx + dy * dy) * (255.f / sqrtf (maxdistance * maxdistance));
2375 int angle = 360 + (int)roundf (atan2f (dx, -dy) * 180.f / (float)M_PI);
2355 Mix_SetPosition (self, angle, CLAMP (distance, 0, 255)); 2376 Mix_SetPosition (self, angle, CLAMP (distance, 0, 255));
2377}
2356 2378
2357void 2379void
2358set_reverse_stereo (CFPlus::Channel self, int flip) 2380set_reverse_stereo (CFPlus::Channel self, int flip)
2359 CODE: 2381 CODE:
2360 Mix_SetReverseStereo (self, flip); 2382 Mix_SetReverseStereo (self, flip);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines