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.293 by root, Thu Dec 17 02:49:38 2009 UTC vs.
Revision 1.311 by root, Tue Dec 27 09:17:27 2011 UTC

19 19
20#ifdef _WIN32 20#ifdef _WIN32
21# undef pipe 21# undef pipe
22// microsoft vs. C 22// microsoft vs. C
23# define sqrtf(x) sqrt(x) 23# define sqrtf(x) sqrt(x)
24# define roundf(x) (int)(x)
25# define atan2f(x,y) atan2(x,y) 24# define atan2f(x,y) atan2(x,y)
26# define M_PI 3.14159265f 25# define M_PI 3.14159265f
27#endif 26#endif
28 27
29#include <assert.h> 28#include <assert.h>
42#include <SDL_opengl.h> 41#include <SDL_opengl.h>
43 42
44/* work around os x broken headers */ 43/* work around os x broken headers */
45#ifdef __MACOSX__ 44#ifdef __MACOSX__
46typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); 45typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
46typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
47typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t);
47#endif 48#endif
48 49
49#define PANGO_ENABLE_BACKEND 50#define PANGO_ENABLE_BACKEND
50#define G_DISABLE_CAST_CHECKS 51#define G_DISABLE_CAST_CHECKS
51 52
81#define expect_false(expr) expect ((expr) != 0, 0) 82#define expect_false(expr) expect ((expr) != 0, 0)
82#define expect_true(expr) expect ((expr) != 0, 1) 83#define expect_true(expr) expect ((expr) != 0, 1)
83 84
84#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, object replacement character */ 85#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, object replacement character */
85 86
87/* this is used as fow flag as well, so has to have a different value */
88/* then anything that is computed by incoming darkness */
86#define FOW_DARKNESS 64 89#define FOW_DARKNESS 50
90#define DARKNESS_ADJUST(n) (n)
87 91
88#define MAP_EXTEND_X 32 92#define MAP_EXTEND_X 32
89#define MAP_EXTEND_Y 512 93#define MAP_EXTEND_Y 512
90 94
91#define MIN_FONT_HEIGHT 10 95#define MIN_FONT_HEIGHT 10
95 99
96#define KMOD_LRAM 0x10000 // our extension 100#define KMOD_LRAM 0x10000 // our extension
97 101
98#define TEXID_SPEECH 1 102#define TEXID_SPEECH 1
99#define TEXID_NOFACE 2 103#define TEXID_NOFACE 2
100#define TEXID_HIDDEN 3 104
105static char *
106fast_sv_grow (SV *sv, STRLEN need)
107{
108 STRLEN len = SvLEN (sv);
109 STRLEN want = SvCUR (sv) + need;
110
111 if (expect_false (len < want))
112 {
113 do
114 len *= 2;
115 while (len < want);
116
117 sv_grow (sv, len);
118 }
119
120 SvCUR_set (sv, want);
121 return SvEND (sv) - need;
122}
101 123
102static AV *texture_av; 124static AV *texture_av;
103 125
104static struct 126static struct
105{ 127{
460 482
461 SDL_PushEvent ((SDL_Event *)&ev); 483 SDL_PushEvent ((SDL_Event *)&ev);
462} 484}
463 485
464static unsigned int 486static unsigned int
487div255 (unsigned int n)
488{
489 return (n + (n >> 8)) >> 8;
490}
491
492static unsigned int
465minpot (unsigned int n) 493minpot (unsigned int n)
466{ 494{
467 if (!n) 495 if (!n)
468 return 0; 496 return 0;
469 497
552 580
553static void 581static void
554deliantra_main () 582deliantra_main ()
555{ 583{
556 char *argv[] = { 0 }; 584 char *argv[] = { 0 };
557 call_argv ("::main", G_DISCARD | G_VOID, argv); 585 call_argv ("DC::Main::main", G_DISCARD | G_VOID, argv);
558} 586}
559 587
560#ifdef __MACOSX__ 588#ifdef __MACOSX__
561 /* to due surprising braindamage on the side of SDL design, we 589 /* to due surprising braindamage on the side of SDL design, we
562 * do some mind-boggling hack here: SDL requires a custom main() 590 * do some mind-boggling hack here: SDL requires a custom main()
563 * on OS X, so... we provide one and call the original main(), which, 591 * on OS X, so... we provide one and call the original main(), which,
564 * due to share dlibrary magic, calls -lSDLmain's main, not perl's main, 592 * due to shared library magic, calls -lSDLmain's main, not perl's main,
565 * and which calls our main (== SDL_main) back. 593 * and which calls our main (== SDL_main) back.
566 */ 594 */
567 extern C_LINKAGE int 595 extern C_LINKAGE int
568 main (int argc, char *argv[]) 596 main (int argc, char *argv[])
569 { 597 {
793 821
794 const_iv (FOW_DARKNESS) 822 const_iv (FOW_DARKNESS)
795# undef const_iv 823# undef const_iv
796 }; 824 };
797 825
798 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 826 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
799 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 827 newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
800 828
801 assert (SDLK_MODIFIER_MIN == SDLK_NUMLOCK); 829 assert (SDLK_MODIFIER_MIN == SDLK_NUMLOCK);
802 assert (SDLK_MODIFIER_MAX == SDLK_COMPOSE); 830 assert (SDLK_MODIFIER_MAX == SDLK_COMPOSE);
803} 831}
804 832
820NV ceil (NV x) 848NV ceil (NV x)
821 849
822IV minpot (UV n) 850IV minpot (UV n)
823 851
824IV popcount (UV n) 852IV popcount (UV n)
853
854NV distance (NV dx, NV dy)
855 CODE:
856 RETVAL = pow (dx * dx + dy * dy, 0.5);
857 OUTPUT:
858 RETVAL
825 859
826void 860void
827pango_init () 861pango_init ()
828 CODE: 862 CODE:
829{ 863{
921 955
922 SDL_WM_SetCaption ("Deliantra MORPG Client " VERSION, "Deliantra"); 956 SDL_WM_SetCaption ("Deliantra MORPG Client " VERSION, "Deliantra");
923#define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name); 957#define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name);
924#include "glfunc.h" 958#include "glfunc.h"
925#undef GL_FUNC 959#undef GL_FUNC
960
961 if (!gl.ActiveTexture ) gl.ActiveTexture = gl.ActiveTextureARB;
962 if (!gl.MultiTexCoord2f) gl.MultiTexCoord2f = gl.MultiTexCoord2fARB;
926 } 963 }
927} 964}
928 OUTPUT: 965 OUTPUT:
929 RETVAL 966 RETVAL
930 967
938SDL_GetAppState () 975SDL_GetAppState ()
939 976
940int 977int
941SDL_GetModState () 978SDL_GetModState ()
942 979
980int
981SDL_WaitEvent ()
982 C_ARGS: 0
983
943void 984void
985SDL_PumpEvents ()
986
987void
944poll_events () 988peep_events ()
945 PPCODE: 989 PPCODE:
946{ 990{
947 SDL_Event ev; 991 SDL_Event ev;
948 992
949 SDL_PumpEvents (); 993 SDL_PumpEvents ();
1015 1059
1016 XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("DC::UI::Event", 1)))); 1060 XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("DC::UI::Event", 1))));
1017 } 1061 }
1018} 1062}
1019 1063
1064char *
1065SDL_AudioDriverName ()
1066 CODE:
1067{
1068 char buf [256];
1069 if (!SDL_AudioDriverName (buf, sizeof (buf)))
1070 XSRETURN_UNDEF;
1071
1072 RETVAL = buf;
1073}
1074 OUTPUT:
1075 RETVAL
1076
1020int 1077int
1021Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 4096) 1078Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 4096)
1022 POSTCALL: 1079 POSTCALL:
1023 Mix_HookMusicFinished (music_finished); 1080 Mix_HookMusicFinished (music_finished);
1024 Mix_ChannelFinished (channel_finished); 1081 Mix_ChannelFinished (channel_finished);
1086add_font (char *file) 1143add_font (char *file)
1087 CODE: 1144 CODE:
1088 RETVAL = FcConfigAppFontAddFile (0, (const FcChar8 *)file); 1145 RETVAL = FcConfigAppFontAddFile (0, (const FcChar8 *)file);
1089 OUTPUT: 1146 OUTPUT:
1090 RETVAL 1147 RETVAL
1148
1149void
1150IMG_Init (int flags = IMG_INIT_JPG | IMG_INIT_PNG)
1151
1152void
1153Mix_Init (int flags = MIX_INIT_MOD | MIX_INIT_MP3 | MIX_INIT_OGG)
1091 1154
1092void 1155void
1093load_image_inline (SV *image_) 1156load_image_inline (SV *image_)
1094 ALIAS: 1157 ALIAS:
1095 load_image_file = 1 1158 load_image_file = 1
1659 glDisable (GL_BLEND); 1722 glDisable (GL_BLEND);
1660 } 1723 }
1661} 1724}
1662 1725
1663void 1726void
1664draw_fow_texture (float intensity, int name1, float s1, float t1, float w1, float h1) 1727draw_fow_texture (float intensity, int hidden_tex, int name1, uint8_t *data1, float s, float t, int w, int h, float blend = 0.f, int dx = 0, int dy = 0, int name2 = 0, uint8_t *data2 = data1)
1665 PROTOTYPE: @ 1728 PROTOTYPE: @
1666 CODE: 1729 CODE:
1667{ 1730{
1731 glEnable (GL_BLEND);
1732 glBlendFunc (intensity ? GL_SRC_ALPHA : GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1668 glEnable (GL_TEXTURE_2D); 1733 glEnable (GL_TEXTURE_2D);
1669 glEnable (GL_BLEND); 1734 glBindTexture (GL_TEXTURE_2D, name1);
1670 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1671 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1672 1735
1673 glColor4f (intensity, intensity, intensity, 0.9); 1736 glColor3f (intensity, intensity, intensity);
1674 glPushMatrix (); 1737 glPushMatrix ();
1675 glScalef (1./3, 1./3, 1.); 1738 glScalef (1./3, 1./3, 1.);
1676 1739
1740 if (blend > 0.f)
1741 {
1742 float dx3 = dx * -3.f / w;
1743 float dy3 = dy * -3.f / h;
1744 GLfloat env_color[4] = { 0., 0., 0., blend };
1745
1746 /* interpolate the two shadow textures */
1747 /* stage 0 == rgb(glcolor) + alpha(t0) */
1748 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1749
1750 /* stage 1 == rgb(glcolor) + alpha(interpolate t0, t1, texenv) */
1751 gl.ActiveTexture (GL_TEXTURE1);
1752 glEnable (GL_TEXTURE_2D);
1677 glBindTexture (GL_TEXTURE_2D, name1); 1753 glBindTexture (GL_TEXTURE_2D, name2);
1754 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
1678 1755
1756 /* rgb == rgb(glcolor) */
1757 glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
1758 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
1759 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
1760
1761 /* alpha = interpolate t0, t1 by env_alpha */
1762 glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, env_color);
1763
1764 glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE);
1765 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
1766 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
1767
1768 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PREVIOUS);
1769 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
1770
1771 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_CONSTANT);
1772 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
1773
1774 glBegin (GL_QUADS);
1775 gl.MultiTexCoord2f (GL_TEXTURE0, 0, 0); gl.MultiTexCoord2f (GL_TEXTURE1, dx3 , dy3 ); glVertex2i (0, 0);
1776 gl.MultiTexCoord2f (GL_TEXTURE0, 0, t); gl.MultiTexCoord2f (GL_TEXTURE1, dx3 , dy3 + t); glVertex2i (0, h);
1777 gl.MultiTexCoord2f (GL_TEXTURE0, s, t); gl.MultiTexCoord2f (GL_TEXTURE1, dx3 + s, dy3 + t); glVertex2i (w, h);
1778 gl.MultiTexCoord2f (GL_TEXTURE0, s, 0); gl.MultiTexCoord2f (GL_TEXTURE1, dx3 + s, dy3 ); glVertex2i (w, 0);
1779 glEnd ();
1780
1781 glDisable (GL_TEXTURE_2D);
1782 gl.ActiveTexture (GL_TEXTURE0);
1783 }
1784 else
1785 {
1786 /* simple blending of one texture, also opengl <1.3 path */
1787 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1788
1789 glBegin (GL_QUADS);
1790 glTexCoord2f (0, 0); glVertex2f (0, 0);
1791 glTexCoord2f (0, t); glVertex2f (0, h);
1792 glTexCoord2f (s, t); glVertex2f (w, h);
1793 glTexCoord2f (s, 0); glVertex2f (w, 0);
1794 glEnd ();
1795 }
1796
1797 /* draw ?-marks or equivalent, this is very clumsy code :/ */
1798 {
1799 int x, y;
1800 int dx3 = dx * 3;
1801 int dy3 = dy * 3;
1802
1803 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1804 glBindTexture (GL_TEXTURE_2D, hidden_tex);
1805 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1806 glTranslatef (-1., -1., 0);
1679 glBegin (GL_QUADS); 1807 glBegin (GL_QUADS);
1680 glTexCoord2f ( 0, 0); glVertex2f ( 0, 0); 1808
1681 glTexCoord2f ( 0, t1); glVertex2f ( 0, h1); 1809 for (y = 1; y < h; y += 3)
1682 glTexCoord2f (s1, t1); glVertex2f (w1, h1); 1810 {
1683 glTexCoord2f (s1, 0); glVertex2f (w1, 0); 1811 int y1 = y - dy3;
1812 int y1valid = y1 >= 0 && y1 < h;
1813
1814 for (x = 1; x < w; x += 3)
1815 {
1816 int x1 = x - dx3;
1817 uint8_t h1 = data1 [x + y * w] == DARKNESS_ADJUST (255 - FOW_DARKNESS);
1818 uint8_t h2;
1819
1820 if (y1valid && x1 >= 0 && x1 < w)
1821 h2 = data2 [x1 + y1 * w] == DARKNESS_ADJUST (255 - FOW_DARKNESS);
1822 else
1823 h2 = 1; /* out of range == invisible */
1824
1825 if (h1 || h2)
1826 {
1827 float alpha = h1 == h2 ? 1.f : h1 ? 1.f - blend : blend;
1828 glColor4f (1., 1., 1., alpha);
1829
1830 glTexCoord2f (0, 0.); glVertex2i (x , y );
1831 glTexCoord2f (0, 1.); glVertex2i (x , y + 3);
1832 glTexCoord2f (1, 1.); glVertex2i (x + 3, y + 3);
1833 glTexCoord2f (1, 0.); glVertex2i (x + 3, y );
1834 }
1835 }
1836 }
1837 }
1838
1684 glEnd (); 1839 glEnd ();
1685 1840
1686 glPopMatrix (); 1841 glPopMatrix ();
1687 1842
1688 glDisable (GL_TEXTURE_2D); 1843 glDisable (GL_TEXTURE_2D);
1910 { 2065 {
1911 ext = *data++; 2066 ext = *data++;
1912 cmd = ext & 0x7f; 2067 cmd = ext & 0x7f;
1913 2068
1914 if (cmd < 4) 2069 if (cmd < 4)
1915 cell->darkness = 255 - ext * 64 + 1; 2070 cell->darkness = 255 - ext * 64 + 1; /* make sure this doesn't collide with FOW_DARKNESS */
1916 else if (cmd == 5) // health 2071 else if (cmd == 5) // health
1917 { 2072 {
1918 cell->stat_width = 1; 2073 cell->stat_width = 1;
1919 cell->stat_hp = *data++; 2074 cell->stat_hp = *data++;
1920 } 2075 }
1995 ? self->row + y 2150 ? self->row + y
1996 : 0; 2151 : 0;
1997 2152
1998 for (x = x0; x < x1; x++) 2153 for (x = x0; x < x1; x++)
1999 { 2154 {
2000 int r = 32, g = 32, b = 32, a = 192; 2155 unsigned int r = 32, g = 32, b = 32, a = 192;
2001 2156
2002 if (row && row->c0 <= x && x < row->c1) 2157 if (row && row->c0 <= x && x < row->c1)
2003 { 2158 {
2004 mapcell *cell = row->col + (x - row->c0); 2159 mapcell *cell = row->col + (x - row->c0);
2005 2160
2007 { 2162 {
2008 maptex tex = self->tex [cell->tile [z]]; 2163 maptex tex = self->tex [cell->tile [z]];
2009 int a0 = 255 - tex.a; 2164 int a0 = 255 - tex.a;
2010 int a1 = tex.a; 2165 int a1 = tex.a;
2011 2166
2012 r = (r * a0 + tex.r * a1) / 255; 2167 r = div255 (r * a0 + tex.r * a1);
2013 g = (g * a0 + tex.g * a1) / 255; 2168 g = div255 (g * a0 + tex.g * a1);
2014 b = (b * a0 + tex.b * a1) / 255; 2169 b = div255 (b * a0 + tex.b * a1);
2015 a = (a * a0 + tex.a * a1) / 255; 2170 a = div255 (a * a0 + tex.a * a1);
2016 } 2171 }
2017 } 2172 }
2018 2173
2019 *map++ = (r ) 2174 *map++ = (r )
2020 | (g << 8) 2175 | (g << 8)
2027} 2182}
2028 OUTPUT: 2183 OUTPUT:
2029 RETVAL 2184 RETVAL
2030 2185
2031void 2186void
2032draw (DC::Map self, int mx, int my, int sw, int sh, int T, U32 player = 0xffffffff, int sdx = 0, int sdy = 0) 2187draw (DC::Map self, int mx, int my, int sw, int sh, int Tw, int Th, U32 player = 0xffffffff, int sdx = 0, int sdy = 0)
2033 CODE: 2188 CODE:
2034{ 2189{
2035 int x, y, z; 2190 int x, y, z;
2036 2191
2037 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ()); 2192 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
2041 int pl_x, pl_y; 2196 int pl_x, pl_y;
2042 maptex pl_tex; 2197 maptex pl_tex;
2043 rc_t *rc = rc_alloc (); 2198 rc_t *rc = rc_alloc ();
2044 rc_t *rc_ov = rc_alloc (); 2199 rc_t *rc_ov = rc_alloc ();
2045 rc_key_t key; 2200 rc_key_t key;
2046 rc_array_t *arr, *arr_hidden; 2201 rc_array_t *arr;
2047 2202
2048 pl_tex.name = 0; 2203 pl_tex.name = 0;
2049 2204
2050 // that's current max. sorry. 2205 // that's current max. sorry.
2051 if (sw > 255) sw = 255; 2206 if (sw > 255) sw = 255;
2088 } 2243 }
2089 2244
2090 glEnable (GL_BLEND); 2245 glEnable (GL_BLEND);
2091 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2246 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2092 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 2247 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
2093
2094 key.texname = self->tex [TEXID_HIDDEN].name;
2095 arr_hidden = rc_array (rc_ov, &key);
2096 2248
2097 for (z = 0; z <= 2; z++) 2249 for (z = 0; z <= 2; z++)
2098 { 2250 {
2099 memset (smooth_level, 0, sizeof (smooth_level)); 2251 memset (smooth_level, 0, sizeof (smooth_level));
2100 key.texname = -1; 2252 key.texname = -1;
2124 2276
2125 key.texname = tex.name; 2277 key.texname = tex.name;
2126 arr = rc_array (rc, &key); 2278 arr = rc_array (rc, &key);
2127 } 2279 }
2128 2280
2129 px = (x + 1) * T - tex.w; 2281 px = (x + 1) * Th - tex.w;
2130 py = (y + 1) * T - tex.h; 2282 py = (y + 1) * Tw - tex.h;
2131 2283
2132 if (expect_false (cell->player == player) && expect_false (z == 2)) 2284 if (expect_false (cell->player == player) && expect_false (z == 2))
2133 { 2285 {
2134 pl_x = px; 2286 pl_x = px;
2135 pl_y = py; 2287 pl_y = py;
2180 skey.x = x ; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0400); 2332 skey.x = x ; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0400);
2181 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0800); 2333 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0800);
2182 } 2334 }
2183 } 2335 }
2184 2336
2185 if (expect_false (z == 2)) 2337 if (expect_false (z == 2) && expect_false (cell->flags))
2186 { 2338 {
2187 /* draw question marks on top of hidden spaces */ 2339 // overlays such as the speech bubble, probably more to come
2188 if (!cell->darkness) 2340 if (cell->flags & 1)
2189 { 2341 {
2190 maptex tex = self->tex [TEXID_HIDDEN];
2191 int px = (x + 1) * T - tex.w;
2192 int py = (y + 1) * T - tex.h;
2193
2194 rc_t2f_v3f (arr_hidden, 0 , 0 , px , py , 0);
2195 rc_t2f_v3f (arr_hidden, 0 , tex.t, px , py + tex.h, 0);
2196 rc_t2f_v3f (arr_hidden, tex.s, tex.t, px + tex.w, py + tex.h, 0);
2197 rc_t2f_v3f (arr_hidden, tex.s, 0 , px + tex.w, py , 0);
2198 }
2199
2200 if (expect_false (cell->flags))
2201 {
2202 // overlays such as the speech bubble, probably more to come
2203 if (cell->flags & 1)
2204 {
2205 rc_key_t key_ov = key; 2342 rc_key_t key_ov = key;
2206 maptex tex = self->tex [TEXID_SPEECH]; 2343 maptex tex = self->tex [TEXID_SPEECH];
2207 rc_array_t *arr; 2344 rc_array_t *arr;
2208 int px = x * T + T * 2 / 32; 2345 int px = x * Tw + Tw * 2 / 32;
2209 int py = y * T - T * 6 / 32; 2346 int py = y * Th - Th * 6 / 32;
2210 2347
2211 key_ov.texname = tex.name; 2348 key_ov.texname = tex.name;
2212 arr = rc_array (rc_ov, &key_ov); 2349 arr = rc_array (rc_ov, &key_ov);
2213 2350
2214 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2351 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
2215 rc_t2f_v3f (arr, 0 , tex.t, px , py + T, 0); 2352 rc_t2f_v3f (arr, 0 , tex.t, px , py + Th, 0);
2216 rc_t2f_v3f (arr, tex.s, tex.t, px + T, py + T, 0); 2353 rc_t2f_v3f (arr, tex.s, tex.t, px + Tw, py + Th, 0);
2217 rc_t2f_v3f (arr, tex.s, 0 , px + T, py , 0); 2354 rc_t2f_v3f (arr, tex.s, 0 , px + Tw, py , 0);
2218 }
2219 } 2355 }
2220 } 2356 }
2221 } 2357 }
2222 } 2358 }
2223 2359
2250 if (!(bits & 0x1000) 2386 if (!(bits & 0x1000)
2251 && skey->level == level 2387 && skey->level == level
2252 && level > smooth_max [skey->x][skey->y]) 2388 && level > smooth_max [skey->x][skey->y])
2253 { 2389 {
2254 maptex tex = self->tex [skey->tile]; 2390 maptex tex = self->tex [skey->tile];
2255 int px = (((int)skey->x) - 1) * T; 2391 int px = (((int)skey->x) - 1) * Tw;
2256 int py = (((int)skey->y) - 1) * T; 2392 int py = (((int)skey->y) - 1) * Th;
2257 int border = bits & 15; 2393 int border = bits & 15;
2258 int corner = (bits >> 8) & ~(bits >> 4) & 15; 2394 int corner = (bits >> 8) & ~(bits >> 4) & 15;
2259 float dx = tex.s * .0625f; // 16 images/row 2395 float dx = tex.s * .0625f; // 16 images/row
2260 float dy = tex.t * .5f ; // 2 images/column 2396 float dy = tex.t * .5f ; // 2 images/column
2261 2397
2274 2410
2275 if (border) 2411 if (border)
2276 { 2412 {
2277 float ox = border * dx; 2413 float ox = border * dx;
2278 2414
2279 glTexCoord2f (ox , 0.f ); glVertex2i (px , py ); 2415 glTexCoord2f (ox , 0.f ); glVertex2i (px , py );
2280 glTexCoord2f (ox , dy ); glVertex2i (px , py + T); 2416 glTexCoord2f (ox , dy ); glVertex2i (px , py + Th);
2281 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py + T); 2417 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py + Th);
2282 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + T, py ); 2418 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + Tw, py );
2283 } 2419 }
2284 2420
2285 if (corner) 2421 if (corner)
2286 { 2422 {
2287 float ox = corner * dx; 2423 float ox = corner * dx;
2288 2424
2289 glTexCoord2f (ox , dy ); glVertex2i (px , py ); 2425 glTexCoord2f (ox , dy ); glVertex2i (px , py );
2290 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + T); 2426 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + Th);
2291 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + T, py + T); 2427 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + Tw, py + Th);
2292 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py ); 2428 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py );
2293 } 2429 }
2294 } 2430 }
2295 } 2431 }
2296 } 2432 }
2297 } 2433 }
2338 for (x = 0; x < sw; x++) 2474 for (x = 0; x < sw; x++)
2339 if (row->c0 <= x + mx && x + mx < row->c1) 2475 if (row->c0 <= x + mx && x + mx < row->c1)
2340 { 2476 {
2341 mapcell *cell = row->col + (x + mx - row->c0); 2477 mapcell *cell = row->col + (x + mx - row->c0);
2342 2478
2343 int px = x * T; 2479 int px = x * Tw;
2344 int py = y * T; 2480 int py = y * Th;
2345 2481
2346 if (expect_false (cell->player == player)) 2482 if (expect_false (cell->player == player))
2347 { 2483 {
2348 px += sdx; 2484 px += sdx;
2349 py += sdy; 2485 py += sdy;
2350 } 2486 }
2351 2487
2352 if (cell->stat_hp) 2488 if (cell->stat_hp)
2353 { 2489 {
2354 int width = cell->stat_width * T; 2490 int width = cell->stat_width * Tw;
2355 int thick = (sh * T / 32 + 27) / 28 + 1 + cell->stat_width; 2491 int thick = (sh * Th / 32 + 27) / 28 + 1 + cell->stat_width;
2356 2492
2357 glColor3ub (0, 0, 0); 2493 glColor3ub (0, 0, 0);
2358 glRectf (px + 1, py - thick - 2, 2494 glRectf (px + 1, py - thick - 2,
2359 px + width - 1, py); 2495 px + width - 1, py);
2360 2496
2366 } 2502 }
2367 } 2503 }
2368} 2504}
2369 2505
2370void 2506void
2371draw_magicmap (DC::Map self, int dx, int dy, int w, int h, unsigned char *data) 2507draw_magicmap (DC::Map self, int w, int h, unsigned char *data)
2372 CODE: 2508 CODE:
2373{ 2509{
2374 static float color[16][3] = { 2510 static float color[16][3] = {
2375 { 0.00F, 0.00F, 0.00F }, 2511 { 0.00f, 0.00f, 0.00f },
2376 { 1.00F, 1.00F, 1.00F }, 2512 { 1.00f, 1.00f, 1.00f },
2377 { 0.00F, 0.00F, 0.55F }, 2513 { 0.00f, 0.00f, 0.55f },
2378 { 1.00F, 0.00F, 0.00F }, 2514 { 1.00f, 0.00f, 0.00f },
2379 2515
2380 { 1.00F, 0.54F, 0.00F }, 2516 { 1.00f, 0.54f, 0.00f },
2381 { 0.11F, 0.56F, 1.00F }, 2517 { 0.11f, 0.56f, 1.00f },
2382 { 0.93F, 0.46F, 0.00F }, 2518 { 0.93f, 0.46f, 0.00f },
2383 { 0.18F, 0.54F, 0.34F }, 2519 { 0.18f, 0.54f, 0.34f },
2384 2520
2385 { 0.56F, 0.73F, 0.56F }, 2521 { 0.56f, 0.73f, 0.56f },
2386 { 0.80F, 0.80F, 0.80F }, 2522 { 0.80f, 0.80f, 0.80f },
2387 { 0.55F, 0.41F, 0.13F }, 2523 { 0.55f, 0.41f, 0.13f },
2388 { 0.99F, 0.77F, 0.26F }, 2524 { 0.99f, 0.77f, 0.26f },
2389 2525
2390 { 0.74F, 0.65F, 0.41F }, 2526 { 0.74f, 0.65f, 0.41f },
2391 2527
2392 { 0.00F, 1.00F, 1.00F }, 2528 { 0.00f, 1.00f, 1.00f },
2393 { 1.00F, 0.00F, 1.00F }, 2529 { 1.00f, 0.00f, 1.00f },
2394 { 1.00F, 1.00F, 0.00F }, 2530 { 1.00f, 1.00f, 0.00f },
2395 }; 2531 };
2396 2532
2397 int x, y; 2533 int x, y;
2398 2534
2399 glEnable (GL_TEXTURE_2D); 2535 glEnable (GL_TEXTURE_2D);
2400 /* GL_REPLACE would be correct, as we don't need to modulate alpha, 2536 /* GL_REPLACE would be correct, as we don't need to modulate alpha,
2401 * but the nvidia driver (185.18.14) mishandles alpha textures 2537 * but the nvidia driver (185.18.14) mishandles alpha textures
2402 * ansd takes the colour from god knows where instead of using 2538 * and takes the colour from god knows where instead of using
2403 * Cp. MODULATE results in the same colour, but slightly different 2539 * Cp. MODULATE results in the same colour, but slightly different
2404 * alpha, but atcually gives us the correct colour with nvidia. 2540 * alpha, but atcually gives us the correct colour with nvidia.
2405 */ 2541 */
2406 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 2542 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
2407 glEnable (GL_BLEND); 2543 glEnable (GL_BLEND);
2415 2551
2416 if (m) 2552 if (m)
2417 { 2553 {
2418 float *c = color [m & 15]; 2554 float *c = color [m & 15];
2419 2555
2420 float tx1 = m & 0x40 ? 0.5 : 0.; 2556 float tx1 = m & 0x40 ? 0.5f : 0.f;
2421 float tx2 = tx1 + 0.5; 2557 float tx2 = tx1 + 0.5f;
2422 2558
2423 glColor4f (c[0], c[1], c[2], 1); 2559 glColor4f (c[0], c[1], c[2], 1);
2424 glTexCoord2f (tx1, 0.); glVertex2i (x , y ); 2560 glTexCoord2f (tx1, 0.); glVertex2i (x , y );
2425 glTexCoord2f (tx1, 1.); glVertex2i (x , y + 1); 2561 glTexCoord2f (tx1, 1.); glVertex2i (x , y + 1);
2426 glTexCoord2f (tx2, 1.); glVertex2i (x + 1, y + 1); 2562 glTexCoord2f (tx2, 1.); glVertex2i (x + 1, y + 1);
2436void 2572void
2437fow_texture (DC::Map self, int mx, int my, int sw, int sh) 2573fow_texture (DC::Map self, int mx, int my, int sw, int sh)
2438 PPCODE: 2574 PPCODE:
2439{ 2575{
2440 int x, y; 2576 int x, y;
2441 int sw1 = sw + 2; 2577 int sw1 = sw + 2;
2442 int sh1 = sh + 2; 2578 int sh1 = sh + 2;
2443 int sh3 = sh * 3; 2579 int sh3 = sh * 3;
2444 int sw34 = (sw * 3 + 3) & ~3; 2580 int sw3 = sw * 3;
2581 SV *darkness3_sv = sv_2mortal (newSV (sw3 * sh3));
2582 uint8_t *darkness3 = (uint8_t *)SvPVX (darkness3_sv);
2445 uint8_t *darkness1 = (uint8_t *)malloc (sw1 * sh1); 2583 uint8_t *darkness1 = (uint8_t *)malloc (sw1 * sh1);
2446 SV *darkness3_sv = sv_2mortal (newSV (sw34 * sh3)); 2584 memset (darkness1, 0, sw1*sh1);
2447 uint8_t *darkness3 = (uint8_t *)SvPVX (darkness3_sv);
2448 2585
2449 SvPOK_only (darkness3_sv); 2586 SvPOK_only (darkness3_sv);
2450 SvCUR_set (darkness3_sv, sw34 * sh3); 2587 SvCUR_set (darkness3_sv, sw3 * sh3);
2451 2588
2452 mx += self->x - 1; 2589 mx += self->x - 1;
2453 my += self->y - 1; 2590 my += self->y - 1;
2454
2455 memset (darkness1, 255 - FOW_DARKNESS, sw1 * sh1);
2456 2591
2457 for (y = 0; y < sh1; y++) 2592 for (y = 0; y < sh1; y++)
2458 if (0 <= y + my && y + my < self->rows) 2593 if (0 <= y + my && y + my < self->rows)
2459 { 2594 {
2460 maprow *row = self->row + (y + my); 2595 maprow *row = self->row + (y + my);
2463 if (row->c0 <= x + mx && x + mx < row->c1) 2598 if (row->c0 <= x + mx && x + mx < row->c1)
2464 { 2599 {
2465 mapcell *cell = row->col + (x + mx - row->c0); 2600 mapcell *cell = row->col + (x + mx - row->c0);
2466 2601
2467 darkness1 [y * sw1 + x] = cell->darkness 2602 darkness1 [y * sw1 + x] = cell->darkness
2468 ? 255 - (cell->darkness - 1) 2603 ? DARKNESS_ADJUST (255 - (cell->darkness - 1))
2469 : 255 - FOW_DARKNESS; 2604 : DARKNESS_ADJUST (255 - FOW_DARKNESS);
2470 } 2605 }
2471 } 2606 }
2472 2607
2473 for (y = 0; y < sh; ++y) 2608 for (y = 0; y < sh; ++y)
2474 for (x = 0; x < sw; ++x) 2609 for (x = 0; x < sw; ++x)
2493 2628
2494 uint8_t r13 = (d13 + d23 + d12) / 3; 2629 uint8_t r13 = (d13 + d23 + d12) / 3;
2495 uint8_t r23 = d23; 2630 uint8_t r23 = d23;
2496 uint8_t r33 = (d23 + d33 + d32) / 3; 2631 uint8_t r33 = (d23 + d33 + d32) / 3;
2497 2632
2498 darkness3 [(y * 3 ) * sw34 + (x * 3 )] = MAX (d22, r11); 2633 darkness3 [(y * 3 ) * sw3 + (x * 3 )] = MAX (d22, r11);
2499 darkness3 [(y * 3 ) * sw34 + (x * 3 + 1)] = MAX (d22, r21); 2634 darkness3 [(y * 3 ) * sw3 + (x * 3 + 1)] = MAX (d22, r21);
2500 darkness3 [(y * 3 ) * sw34 + (x * 3 + 2)] = MAX (d22, r31); 2635 darkness3 [(y * 3 ) * sw3 + (x * 3 + 2)] = MAX (d22, r31);
2501 darkness3 [(y * 3 + 1) * sw34 + (x * 3 )] = MAX (d22, r12); 2636 darkness3 [(y * 3 + 1) * sw3 + (x * 3 )] = MAX (d22, r12);
2502 darkness3 [(y * 3 + 1) * sw34 + (x * 3 + 1)] = MAX (d22, r22); 2637 darkness3 [(y * 3 + 1) * sw3 + (x * 3 + 1)] = MAX (d22, r22); /* this MUST be == d22 */
2503 darkness3 [(y * 3 + 1) * sw34 + (x * 3 + 2)] = MAX (d22, r32); 2638 darkness3 [(y * 3 + 1) * sw3 + (x * 3 + 2)] = MAX (d22, r32);
2504 darkness3 [(y * 3 + 2) * sw34 + (x * 3 )] = MAX (d22, r13); 2639 darkness3 [(y * 3 + 2) * sw3 + (x * 3 )] = MAX (d22, r13);
2505 darkness3 [(y * 3 + 2) * sw34 + (x * 3 + 1)] = MAX (d22, r23); 2640 darkness3 [(y * 3 + 2) * sw3 + (x * 3 + 1)] = MAX (d22, r23);
2506 darkness3 [(y * 3 + 2) * sw34 + (x * 3 + 2)] = MAX (d22, r33); 2641 darkness3 [(y * 3 + 2) * sw3 + (x * 3 + 2)] = MAX (d22, r33);
2507 } 2642 }
2508 2643
2509 free (darkness1); 2644 free (darkness1);
2510 2645
2511 EXTEND (SP, 3); 2646 EXTEND (SP, 3);
2512 PUSHs (sv_2mortal (newSViv (sw34))); 2647 PUSHs (sv_2mortal (newSViv (sw3)));
2513 PUSHs (sv_2mortal (newSViv (sh3))); 2648 PUSHs (sv_2mortal (newSViv (sh3)));
2514 PUSHs (darkness3_sv); 2649 PUSHs (darkness3_sv);
2515} 2650}
2516 2651
2517SV * 2652SV *
2715 if (RETVAL < 0) 2850 if (RETVAL < 0)
2716 { 2851 {
2717 RETVAL = Mix_GroupOldest (-1); 2852 RETVAL = Mix_GroupOldest (-1);
2718 2853
2719 if (RETVAL < 0) 2854 if (RETVAL < 0)
2855 {
2856 // happens sometimes, maybe it just stopped playing(?)
2857 RETVAL = Mix_GroupAvailable (-1);
2858
2859 if (RETVAL < 0)
2720 XSRETURN_UNDEF; 2860 XSRETURN_UNDEF;
2721 2861 }
2862 else
2722 Mix_HaltChannel (RETVAL); 2863 Mix_HaltChannel (RETVAL);
2723 } 2864 }
2724 2865
2725 Mix_UnregisterAllEffects (RETVAL); 2866 Mix_UnregisterAllEffects (RETVAL);
2726 Mix_Volume (RETVAL, 128); 2867 Mix_Volume (RETVAL, 128);
2727} 2868}
2774void 2915void
2775set_position_r (DC::Channel self, int dx, int dy, int maxdistance) 2916set_position_r (DC::Channel self, int dx, int dy, int maxdistance)
2776 CODE: 2917 CODE:
2777{ 2918{
2778 int distance = sqrtf (dx * dx + dy * dy) * (255.f / sqrtf (maxdistance * maxdistance)); 2919 int distance = sqrtf (dx * dx + dy * dy) * (255.f / sqrtf (maxdistance * maxdistance));
2779 int angle = 360 + (int)roundf (atan2f (dx, -dy) * 180.f / (float)M_PI); 2920 int angle = atan2f (dx, -dy) * 180.f / (float)M_PI + 360.f;
2780 Mix_SetPosition (self, angle, CLAMP (distance, 0, 255)); 2921 Mix_SetPosition (self, angle, CLAMP (distance, 0, 255));
2781} 2922}
2782 2923
2783void 2924void
2784set_reverse_stereo (DC::Channel self, int flip) 2925set_reverse_stereo (DC::Channel self, int flip)
2786 Mix_SetReverseStereo (self, flip); 2927 Mix_SetReverseStereo (self, flip);
2787 2928
2788MODULE = Deliantra::Client PACKAGE = DC::MixChunk 2929MODULE = Deliantra::Client PACKAGE = DC::MixChunk
2789 2930
2790PROTOTYPES: DISABLE 2931PROTOTYPES: DISABLE
2932
2933void
2934decoders ()
2935 PPCODE:
2936#if SDL_MIXER_MAJOR_VERSION > 1 || SDL_MIXER_MINOR_VERSION > 2 || SDL_MIXER_PATCHLEVEL >= 10
2937 int i, num = Mix_GetNumChunkDecoders ();
2938 EXTEND (SP, num);
2939 for (i = 0; i < num; ++i)
2940 PUSHs (sv_2mortal (newSVpv (Mix_GetChunkDecoder (i), 0)));
2941#else
2942 XPUSHs (sv_2mortal (newSVpv ("(sdl mixer too old)", 0)));
2943#endif
2791 2944
2792DC::MixChunk 2945DC::MixChunk
2793new (SV *class, DC::RW rwops) 2946new (SV *class, DC::RW rwops)
2794 CODE: 2947 CODE:
2795 RETVAL = Mix_LoadWAV_RW (rwops, 1); 2948 RETVAL = Mix_LoadWAV_RW (rwops, 1);
2828 OUTPUT: 2981 OUTPUT:
2829 RETVAL 2982 RETVAL
2830 2983
2831MODULE = Deliantra::Client PACKAGE = DC::MixMusic 2984MODULE = Deliantra::Client PACKAGE = DC::MixMusic
2832 2985
2986void
2987decoders ()
2988 PPCODE:
2989#if SDL_MIXER_MAJOR_VERSION > 1 || SDL_MIXER_MINOR_VERSION > 2 || SDL_MIXER_PATCHLEVEL >= 10
2990 int i, num = Mix_GetNumMusicDecoders ();
2991 EXTEND (SP, num);
2992 for (i = 0; i < num; ++i)
2993 PUSHs (sv_2mortal (newSVpv (Mix_GetMusicDecoder (i), 0)));
2994#else
2995 XPUSHs (sv_2mortal (newSVpv ("(sdl mixer too old)", 0)));
2996#endif
2997
2833int 2998int
2834volume (int volume = -1) 2999volume (int volume = -1)
2835 PROTOTYPE: ;$ 3000 PROTOTYPE: ;$
2836 CODE: 3001 CODE:
2837 if (items > 0) 3002 if (items > 0)
2847 3012
2848void 3013void
2849halt () 3014halt ()
2850 CODE: 3015 CODE:
2851 Mix_HaltMusic (); 3016 Mix_HaltMusic ();
3017
3018int
3019playing ()
3020 CODE:
3021 RETVAL = Mix_PlayingMusic ();
3022 OUTPUT:
3023 RETVAL
2852 3024
2853DC::MixMusic 3025DC::MixMusic
2854new (SV *class, DC::RW rwops) 3026new (SV *class, DC::RW rwops)
2855 CODE: 3027 CODE:
2856 RETVAL = Mix_LoadMUS_RW (rwops); 3028 RETVAL = Mix_LoadMUS_RW (rwops);
2996 const_iv (GL_FUNC_SUBTRACT), 3168 const_iv (GL_FUNC_SUBTRACT),
2997 const_iv (GL_FUNC_REVERSE_SUBTRACT), 3169 const_iv (GL_FUNC_REVERSE_SUBTRACT),
2998# undef const_iv 3170# undef const_iv
2999 }; 3171 };
3000 3172
3001 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 3173 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
3002 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 3174 newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
3003 3175
3004 texture_av = newAV (); 3176 texture_av = newAV ();
3005 AvREAL_off (texture_av); 3177 AvREAL_off (texture_av);
3006} 3178}
3007 3179
3050 RETVAL 3222 RETVAL
3051 3223
3052int glGetError () 3224int glGetError ()
3053 3225
3054void glFinish () 3226void glFinish ()
3227
3228void glFlush ()
3055 3229
3056void glClear (int mask) 3230void glClear (int mask)
3057 3231
3058void glClearColor (float r, float g, float b, float a = 1.0) 3232void glClearColor (float r, float g, float b, float a = 1.0)
3059 PROTOTYPE: @ 3233 PROTOTYPE: @
3230void glNewList (int list, int mode = GL_COMPILE) 3404void glNewList (int list, int mode = GL_COMPILE)
3231 3405
3232void glEndList () 3406void glEndList ()
3233 3407
3234void glCallList (int list) 3408void glCallList (int list)
3409
3410void c_init ()
3411 CODE:
3412 glPixelStorei (GL_PACK_ALIGNMENT , 1);
3413 glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
3235 3414
3236MODULE = Deliantra::Client PACKAGE = DC::UI::Base 3415MODULE = Deliantra::Client PACKAGE = DC::UI::Base
3237 3416
3238PROTOTYPES: DISABLE 3417PROTOTYPES: DISABLE
3239 3418

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines