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.221 by root, Fri Aug 10 04:02:13 2007 UTC vs.
Revision 1.230 by root, Sun Aug 19 12:56:24 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;
708 715
709 if (RETVAL) 716 if (RETVAL)
710 { 717 {
711 av_clear (texture_av); 718 av_clear (texture_av);
712 719
713 SDL_WM_SetCaption ("Crossfire+ Client " VERSION, "Crossfire+"); 720 SDL_WM_SetCaption ("Crossfire TRT Client " VERSION, "Crossfire TRT");
714#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);
715#include "glfunc.h" 722#include "glfunc.h"
716#undef GL_FUNC 723#undef GL_FUNC
717 } 724 }
718} 725}
1030 RETVAL->g = 1.; 1037 RETVAL->g = 1.;
1031 RETVAL->b = 1.; 1038 RETVAL->b = 1.;
1032 RETVAL->a = 1.; 1039 RETVAL->a = 1.;
1033 RETVAL->base_height = MIN_FONT_HEIGHT; 1040 RETVAL->base_height = MIN_FONT_HEIGHT;
1034 RETVAL->font = 0; 1041 RETVAL->font = 0;
1042 RETVAL->rc = rc_alloc ();
1035 1043
1036 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR); 1044 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
1037 layout_update_font (RETVAL); 1045 layout_update_font (RETVAL);
1038 OUTPUT: 1046 OUTPUT:
1039 RETVAL 1047 RETVAL
1040 1048
1041void 1049void
1042DESTROY (CFPlus::Layout self) 1050DESTROY (CFPlus::Layout self)
1043 CODE: 1051 CODE:
1044 g_object_unref (self->pl); 1052 g_object_unref (self->pl);
1053 rc_free (self->rc);
1045 Safefree (self); 1054 Safefree (self);
1046 1055
1047void 1056void
1048set_text (CFPlus::Layout self, SV *text_) 1057set_text (CFPlus::Layout self, SV *text_)
1049 CODE: 1058 CODE:
1301 } 1310 }
1302} 1311}
1303 1312
1304void 1313void
1305render (CFPlus::Layout self, float x, float y, int flags = 0) 1314render (CFPlus::Layout self, float x, float y, int flags = 0)
1306 PPCODE: 1315 CODE:
1316 rc_clear (self->rc);
1307 pango_opengl_render_layout_subpixel ( 1317 pango_opengl_render_layout_subpixel (
1308 self->pl, 1318 self->pl,
1319 self->rc,
1309 x * PANGO_SCALE, y * PANGO_SCALE, 1320 x * PANGO_SCALE, y * PANGO_SCALE,
1310 self->r, self->g, self->b, self->a, 1321 self->r, self->g, self->b, self->a,
1311 flags 1322 flags
1312 ); 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}
1313 1346
1314MODULE = CFPlus PACKAGE = CFPlus::Texture 1347MODULE = CFPlus PACKAGE = CFPlus::Texture
1315 1348
1316PROTOTYPES: ENABLE 1349PROTOTYPES: ENABLE
1317 1350
1708 1741
1709void 1742void
1710draw (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)
1711 CODE: 1744 CODE:
1712{ 1745{
1746 int x, y, z;
1747
1713 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ()); 1748 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
1714 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
1715 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)
1716 smooth_key skey; 1751 smooth_key skey;
1717 int x, y, z; 1752
1718 int last_name; 1753 rc_t *rc = rc_alloc ();
1754 rc_key_t key;
1755 rc_array_t *arr;
1719 1756
1720 // thats current max. sorry. 1757 // thats current max. sorry.
1721 if (sw > 255) sw = 255; 1758 if (sw > 255) sw = 255;
1722 if (sh > 255) sh = 255; 1759 if (sh > 255) sh = 255;
1723 1760
1724 // clear key, in case of extra padding 1761 // clear key, in case of extra padding
1725 memset (&skey, 0, sizeof (skey)); 1762 memset (&skey, 0, sizeof (skey));
1726 1763
1727 glColor4ub (255, 255, 255, 255); 1764 memset (&key, 0, sizeof (key));
1728 1765 key.r = 255;
1729 glEnable (GL_BLEND); 1766 key.g = 255;
1730 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1767 key.b = 255;
1731 glEnable (GL_TEXTURE_2D); 1768 key.a = 255;
1732 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1769 key.mode = GL_QUADS;
1733 1770 key.format = GL_T2F_V3F;
1734 glBegin (GL_QUADS);
1735
1736 last_name = -1; 1771 key.texname = -1;
1737 1772
1738 mx += self->x; 1773 mx += self->x;
1739 my += self->y; 1774 my += self->y;
1740 1775
1741 // first pass: determine smooth_max 1776 // first pass: determine smooth_max
1757 MAX (self->tex [cell->tile [0]].smoothlevel, 1792 MAX (self->tex [cell->tile [0]].smoothlevel,
1758 MAX (self->tex [cell->tile [1]].smoothlevel, 1793 MAX (self->tex [cell->tile [1]].smoothlevel,
1759 self->tex [cell->tile [2]].smoothlevel)); 1794 self->tex [cell->tile [2]].smoothlevel));
1760 } 1795 }
1761 } 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);
1762 1801
1763 for (z = 0; z <= 2; z++) 1802 for (z = 0; z <= 2; z++)
1764 { 1803 {
1765 memset (smooth_level, 0, sizeof (smooth_level)); 1804 memset (smooth_level, 0, sizeof (smooth_level));
1766 1805
1778 if (tile) 1817 if (tile)
1779 { 1818 {
1780 maptex tex = self->tex [tile]; 1819 maptex tex = self->tex [tile];
1781 int px, py; 1820 int px, py;
1782 1821
1783 // suppressing texture state switches here
1784 // is only moderately effective, but worth the extra effort
1785 if (last_name != tex.name) 1822 if (key.texname != tex.name)
1786 { 1823 {
1787 if (!tex.name) 1824 if (!tex.name)
1788 tex = self->tex [2]; /* missing, replace by noface */ 1825 tex = self->tex [2]; /* missing, replace by noface */
1789 1826
1790 glEnd (); 1827 key.texname = tex.name;
1791 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1828 arr = rc_array (rc, &key);
1792 glBegin (GL_QUADS);
1793 } 1829 }
1794 1830
1795 px = (x + 1) * T - tex.w; 1831 px = (x + 1) * T - tex.w;
1796 py = (y + 1) * T - tex.h; 1832 py = (y + 1) * T - tex.h;
1797 1833
1798 glTexCoord2f (0 , 0 ); glVertex2f (px , py ); 1834 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
1799 glTexCoord2f (0 , tex.t); glVertex2f (px , py + tex.h); 1835 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); 1836 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 ); 1837 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0);
1802 1838
1803 if (cell->flags && z == 2) 1839 if (cell->flags && z == 2)
1804 { 1840 {
1841 // overlays such as the speech bubble, probably more to come
1805 if (cell->flags & 1) 1842 if (cell->flags & 1)
1806 { 1843 {
1807 maptex tex = self->tex [1]; 1844 maptex tex = self->tex [1];
1808 int px = x * T + T * 2 / 32; 1845 int px = x * T + T * 2 / 32;
1809 int py = y * T - T * 6 / 32; 1846 int py = y * T - T * 6 / 32;
1810 1847
1848 if (tex.name)
1811 glEnd (); 1849 {
1812 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);
1813 glBegin (GL_QUADS); 1860 }
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 } 1861 }
1820 } 1862 }
1821 1863
1822 // update smooth hash 1864 // update smooth hash
1823 if (tex.smoothtile) 1865 if (tex.smoothtile)
1859 } 1901 }
1860 } 1902 }
1861 } 1903 }
1862 } 1904 }
1863 1905
1906 rc_draw (rc);
1907 rc_clear (rc);
1908
1864 // go through all smoothlevels, lowest to highest, then draw. 1909 // go through all smoothlevels, lowest to highest, then draw.
1865 // this is basically counting sort 1910 // this is basically counting sort
1866 { 1911 {
1867 int w, b; 1912 int w, b;
1868 1913
1914 glEnable (GL_TEXTURE_2D);
1915 glBegin (GL_QUADS);
1869 for (w = 0; w < 256 / 32; ++w) 1916 for (w = 0; w < 256 / 32; ++w)
1870 { 1917 {
1871 uint32_t smask = smooth_level [w]; 1918 uint32_t smask = smooth_level [w];
1872 if (smask) 1919 if (smask)
1873 for (b = 0; b < 32; ++b) 1920 for (b = 0; b < 32; ++b)
1892 int border = bits & 15; 1939 int border = bits & 15;
1893 int corner = (bits >> 8) & ~(bits >> 4) & 15; 1940 int corner = (bits >> 8) & ~(bits >> 4) & 15;
1894 float dx = tex.s * .0625f; // 16 images/row 1941 float dx = tex.s * .0625f; // 16 images/row
1895 float dy = tex.t * .5f ; // 2 images/column 1942 float dy = tex.t * .5f ; // 2 images/column
1896 1943
1897 // this time naively avoiding texture state changes
1898 // save gobs of state changes.
1899 if (last_name != tex.name) 1944 if (tex.name)
1900 { 1945 {
1946 // this time avoiding texture state changes
1947 // save gobs of state changes.
1901 if (!tex.name) 1948 if (key.texname != tex.name)
1902 continue; // smoothing not yet available 1949 {
1903
1904 glEnd (); 1950 glEnd ();
1905 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1951 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name);
1906 glBegin (GL_QUADS); 1952 glBegin (GL_QUADS);
1907 } 1953 }
1908 1954
1909 if (border) 1955 if (border)
1910 { 1956 {
1911 float ox = border * dx; 1957 float ox = border * dx;
1912 1958
1913 glTexCoord2f (ox , 0.f ); glVertex2f (px , py ); 1959 glTexCoord2f (ox , 0.f ); glVertex2i (px , py );
1914 glTexCoord2f (ox , dy ); glVertex2f (px , py + T); 1960 glTexCoord2f (ox , dy ); glVertex2i (px , py + T);
1915 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py + T); 1961 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py + T);
1916 glTexCoord2f (ox + dx, 0.f ); glVertex2f (px + T, py ); 1962 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + T, py );
1917 } 1963 }
1918 1964
1919 if (corner) 1965 if (corner)
1920 { 1966 {
1921 float ox = corner * dx; 1967 float ox = corner * dx;
1922 1968
1923 glTexCoord2f (ox , dy ); glVertex2f (px , py ); 1969 glTexCoord2f (ox , dy ); glVertex2i (px , py );
1924 glTexCoord2f (ox , dy * 2.f); glVertex2f (px , py + T); 1970 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + T);
1925 glTexCoord2f (ox + dx, dy * 2.f); glVertex2f (px + T, py + T); 1971 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + T, py + T);
1926 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py ); 1972 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py );
1973 }
1927 } 1974 }
1928 } 1975 }
1929 } 1976 }
1930 } 1977 }
1931 } 1978 }
1979
1980 glEnd ();
1981 glDisable (GL_TEXTURE_2D);
1982 key.texname = -1;
1932 } 1983 }
1933 1984
1934 hv_clear (smooth); 1985 hv_clear (smooth);
1935 } 1986 }
1936 1987
1937 glEnd ();
1938
1939 glDisable (GL_TEXTURE_2D);
1940 glDisable (GL_BLEND); 1988 glDisable (GL_BLEND);
1989 rc_free (rc);
1941 1990
1942 // top layer: overlays such as the health bar 1991 // top layer: overlays such as the health bar
1943 for (y = 0; y < sh; y++) 1992 for (y = 0; y < sh; y++)
1944 if (0 <= y + my && y + my < self->rows) 1993 if (0 <= y + my && y + my < self->rows)
1945 { 1994 {
2194 int x, y, z; 2243 int x, y, z;
2195 int w, h; 2244 int w, h;
2196 int x1, y1; 2245 int x1, y1;
2197 2246
2198 if (*data++ != 0) 2247 if (*data++ != 0)
2199 return; /* version mismatch */ 2248 XSRETURN_EMPTY; /* version mismatch */
2200 2249
2201 w = *data++ << 8; w |= *data++; 2250 w = *data++ << 8; w |= *data++;
2202 h = *data++ << 8; h |= *data++; 2251 h = *data++ << 8; h |= *data++;
2203 2252
2204 // 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
2500 const_iv (GL_INTENSITY), 2549 const_iv (GL_INTENSITY),
2501 const_iv (GL_LUMINANCE), 2550 const_iv (GL_LUMINANCE),
2502 const_iv (GL_LUMINANCE_ALPHA), 2551 const_iv (GL_LUMINANCE_ALPHA),
2503 const_iv (GL_FLOAT), 2552 const_iv (GL_FLOAT),
2504 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),
2505 const_iv (GL_COMPILE), 2560 const_iv (GL_COMPILE),
2506 const_iv (GL_PROXY_TEXTURE_1D), 2561 const_iv (GL_PROXY_TEXTURE_1D),
2507 const_iv (GL_PROXY_TEXTURE_2D), 2562 const_iv (GL_PROXY_TEXTURE_2D),
2508 const_iv (GL_TEXTURE_1D), 2563 const_iv (GL_TEXTURE_1D),
2509 const_iv (GL_TEXTURE_2D), 2564 const_iv (GL_TEXTURE_2D),
2805 NV x, y, w, h; 2860 NV x, y, w, h;
2806 SV *draw_x_sv = GvSV (draw_x_gv); 2861 SV *draw_x_sv = GvSV (draw_x_gv);
2807 SV *draw_y_sv = GvSV (draw_y_gv); 2862 SV *draw_y_sv = GvSV (draw_y_gv);
2808 SV *draw_w_sv = GvSV (draw_w_gv); 2863 SV *draw_w_sv = GvSV (draw_w_gv);
2809 SV *draw_h_sv = GvSV (draw_h_gv); 2864 SV *draw_h_sv = GvSV (draw_h_gv);
2810 SV *hover;
2811 double draw_x, draw_y, draw_w, draw_h; 2865 double draw_x, draw_y;
2812 2866
2813 if (!SvROK (self)) 2867 if (!SvROK (self))
2814 croak ("CFPlus::Base::draw: %s not a reference", SvPV_nolen (self)); 2868 croak ("CFPlus::Base::draw: %s not a reference", SvPV_nolen (self));
2815 2869
2816 hv = (HV *)SvRV (self); 2870 hv = (HV *)SvRV (self);
2844 { 2898 {
2845 svp = hv_fetch (hv, "can_hover", sizeof ("can_hover") - 1, 0); 2899 svp = hv_fetch (hv, "can_hover", sizeof ("can_hover") - 1, 0);
2846 2900
2847 if (svp && SvTRUE (*svp)) 2901 if (svp && SvTRUE (*svp))
2848 { 2902 {
2849 glColor4f (1*0.2f, 0.8*0.2f, 0.5*0.2f, 0.2f); 2903 glColor4f (1.0f * 0.2f, 0.8f * 0.2f, 0.5f * 0.2f, 0.2f);
2850 glEnable (GL_BLEND); 2904 glEnable (GL_BLEND);
2851 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 2905 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
2852 glBegin (GL_QUADS); 2906 glBegin (GL_QUADS);
2853 glVertex2f (0, 0); 2907 glVertex2f (0, 0);
2854 glVertex2f (w, 0); 2908 glVertex2f (w, 0);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines