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.295 by root, Mon Dec 21 03:30:22 2009 UTC vs.
Revision 1.309 by root, Mon Dec 26 22:30:21 2011 UTC

41#include <SDL_opengl.h> 41#include <SDL_opengl.h>
42 42
43/* work around os x broken headers */ 43/* work around os x broken headers */
44#ifdef __MACOSX__ 44#ifdef __MACOSX__
45typedef 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);
46#endif 48#endif
47 49
48#define PANGO_ENABLE_BACKEND 50#define PANGO_ENABLE_BACKEND
49#define G_DISABLE_CAST_CHECKS 51#define G_DISABLE_CAST_CHECKS
50 52
80#define expect_false(expr) expect ((expr) != 0, 0) 82#define expect_false(expr) expect ((expr) != 0, 0)
81#define expect_true(expr) expect ((expr) != 0, 1) 83#define expect_true(expr) expect ((expr) != 0, 1)
82 84
83#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, object replacement character */ 85#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, object replacement character */
84 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 */
85#define FOW_DARKNESS 64 89#define FOW_DARKNESS 50
86#define DARKNESS_ADJUST(n) ((29 * (int)(n)) >> 5) /* times 0.9 */ 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{
457 ev.code = 1; 479 ev.code = 1;
458 ev.data1 = (void *)(long)channel; 480 ev.data1 = (void *)(long)channel;
459 ev.data2 = 0; 481 ev.data2 = 0;
460 482
461 SDL_PushEvent ((SDL_Event *)&ev); 483 SDL_PushEvent ((SDL_Event *)&ev);
484}
485
486static unsigned int
487div255 (unsigned int n)
488{
489 return (n + (n >> 8)) >> 8;
462} 490}
463 491
464static unsigned int 492static unsigned int
465minpot (unsigned int n) 493minpot (unsigned int n)
466{ 494{
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
927 955
928 SDL_WM_SetCaption ("Deliantra MORPG Client " VERSION, "Deliantra"); 956 SDL_WM_SetCaption ("Deliantra MORPG Client " VERSION, "Deliantra");
929#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);
930#include "glfunc.h" 958#include "glfunc.h"
931#undef GL_FUNC 959#undef GL_FUNC
960
961 if (!gl.ActiveTexture ) gl.ActiveTexture = gl.ActiveTextureARB;
962 if (!gl.MultiTexCoord2f) gl.MultiTexCoord2f = gl.MultiTexCoord2fARB;
932 } 963 }
933} 964}
934 OUTPUT: 965 OUTPUT:
935 RETVAL 966 RETVAL
936 967
1021 1052
1022 XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("DC::UI::Event", 1)))); 1053 XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("DC::UI::Event", 1))));
1023 } 1054 }
1024} 1055}
1025 1056
1057char *
1058SDL_AudioDriverName ()
1059 CODE:
1060{
1061 char buf [256];
1062 if (!SDL_AudioDriverName (buf, sizeof (buf)))
1063 XSRETURN_UNDEF;
1064
1065 RETVAL = buf;
1066}
1067 OUTPUT:
1068 RETVAL
1069
1026int 1070int
1027Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 4096) 1071Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 4096)
1028 POSTCALL: 1072 POSTCALL:
1029 Mix_HookMusicFinished (music_finished); 1073 Mix_HookMusicFinished (music_finished);
1030 Mix_ChannelFinished (channel_finished); 1074 Mix_ChannelFinished (channel_finished);
1092add_font (char *file) 1136add_font (char *file)
1093 CODE: 1137 CODE:
1094 RETVAL = FcConfigAppFontAddFile (0, (const FcChar8 *)file); 1138 RETVAL = FcConfigAppFontAddFile (0, (const FcChar8 *)file);
1095 OUTPUT: 1139 OUTPUT:
1096 RETVAL 1140 RETVAL
1141
1142void
1143IMG_Init (int flags = IMG_INIT_JPG | IMG_INIT_PNG)
1144
1145void
1146Mix_Init (int flags = MIX_INIT_MOD | MIX_INIT_MP3 | MIX_INIT_OGG)
1097 1147
1098void 1148void
1099load_image_inline (SV *image_) 1149load_image_inline (SV *image_)
1100 ALIAS: 1150 ALIAS:
1101 load_image_file = 1 1151 load_image_file = 1
1665 glDisable (GL_BLEND); 1715 glDisable (GL_BLEND);
1666 } 1716 }
1667} 1717}
1668 1718
1669void 1719void
1670draw_fow_texture (float intensity, int name1, float s1, float t1, float w1, float h1, float blend = 0.f, float dx = 0.f, float dy = 0.f, int name2 = 0, float s2 = 0.f, float t2 = 0.f, float w2 = 0.f, float h2 = 0.f) 1720draw_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)
1671 PROTOTYPE: @ 1721 PROTOTYPE: @
1672 CODE: 1722 CODE:
1673{ 1723{
1724 glEnable (GL_BLEND);
1725 glBlendFunc (intensity ? GL_SRC_ALPHA : GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1674 glEnable (GL_TEXTURE_2D); 1726 glEnable (GL_TEXTURE_2D);
1675 glEnable (GL_BLEND);
1676 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1677 glBindTexture (GL_TEXTURE_2D, name1); 1727 glBindTexture (GL_TEXTURE_2D, name1);
1678 1728
1679 glColor3f (intensity, intensity, intensity); 1729 glColor3f (intensity, intensity, intensity);
1680 glPushMatrix (); 1730 glPushMatrix ();
1681 glScalef (1./3, 1./3, 1.); 1731 glScalef (1./3, 1./3, 1.);
1682 1732
1683 if (blend > 0.f) 1733 if (blend > 0.f)
1684 { 1734 {
1685 float S2, T2; /* 0. 0. for texture 2 */ 1735 float dx3 = dx * -3.f / w;
1686 float w = w1 > w2 ? w1 : w2; 1736 float dy3 = dy * -3.f / h;
1687 float h = h1 > h2 ? h1 : h2;
1688 GLfloat env_color[4] = { 0., 0., 0., blend }; 1737 GLfloat env_color[4] = { 0., 0., 0., blend };
1689 1738
1690 /* interpolate the two shadow textures */ 1739 /* interpolate the two shadow textures */
1691 /* stage 0 == rgb(glcolor) + alpha(t0) */ 1740 /* stage 0 == rgb(glcolor) + alpha(t0) */
1692 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1741 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1697 glBindTexture (GL_TEXTURE_2D, name2); 1746 glBindTexture (GL_TEXTURE_2D, name2);
1698 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 1747 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
1699 1748
1700 /* rgb == rgb(glcolor) */ 1749 /* rgb == rgb(glcolor) */
1701 glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); 1750 glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
1702 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_CONSTANT); 1751 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
1703 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); 1752 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
1704 1753
1705 /* alpha = interpolate t0, t1 by env_alpha */ 1754 /* alpha = interpolate t0, t1 by env_alpha */
1706 glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, env_color); 1755 glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, env_color);
1707 1756
1713 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA); 1762 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
1714 1763
1715 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_CONSTANT); 1764 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_CONSTANT);
1716 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA); 1765 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
1717 1766
1718 s1 *= w / w1;
1719 t1 *= h / h1;
1720
1721 dx *= -3.f / w2;
1722 dy *= -3.f / h2;
1723 dx *= w / w2;
1724 dy *= h / h2;
1725
1726 s2 *= w / w2;
1727 t2 *= h / h2;
1728
1729 glBegin (GL_QUADS); 1767 glBegin (GL_QUADS);
1730 gl.MultiTexCoord2f (GL_TEXTURE0, 0, 0); gl.MultiTexCoord2f (GL_TEXTURE1, dx , dy ); glVertex2f ( 0, 0); 1768 gl.MultiTexCoord2f (GL_TEXTURE0, 0, 0); gl.MultiTexCoord2f (GL_TEXTURE1, dx3 , dy3 ); glVertex2i (0, 0);
1731 gl.MultiTexCoord2f (GL_TEXTURE0, 0, t1); gl.MultiTexCoord2f (GL_TEXTURE1, dx , dy + t2); glVertex2f ( 0, h1); 1769 gl.MultiTexCoord2f (GL_TEXTURE0, 0, t); gl.MultiTexCoord2f (GL_TEXTURE1, dx3 , dy3 + t); glVertex2i (0, h);
1732 gl.MultiTexCoord2f (GL_TEXTURE0, s1, t1); gl.MultiTexCoord2f (GL_TEXTURE1, dx + s2, dy + t2); glVertex2f (w1, h1); 1770 gl.MultiTexCoord2f (GL_TEXTURE0, s, t); gl.MultiTexCoord2f (GL_TEXTURE1, dx3 + s, dy3 + t); glVertex2i (w, h);
1733 gl.MultiTexCoord2f (GL_TEXTURE0, s1, 0); gl.MultiTexCoord2f (GL_TEXTURE1, dx + s2, dy ); glVertex2f (w1, 0); 1771 gl.MultiTexCoord2f (GL_TEXTURE0, s, 0); gl.MultiTexCoord2f (GL_TEXTURE1, dx3 + s, dy3 ); glVertex2i (w, 0);
1734 glEnd (); 1772 glEnd ();
1735 1773
1736 glDisable (GL_TEXTURE_2D); 1774 glDisable (GL_TEXTURE_2D);
1737 gl.ActiveTexture (GL_TEXTURE0); 1775 gl.ActiveTexture (GL_TEXTURE0);
1738 } 1776 }
1740 { 1778 {
1741 /* simple blending of one texture, also opengl <1.3 path */ 1779 /* simple blending of one texture, also opengl <1.3 path */
1742 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1780 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1743 1781
1744 glBegin (GL_QUADS); 1782 glBegin (GL_QUADS);
1745 glTexCoord2f ( 0, 0); glVertex2f ( 0, 0); 1783 glTexCoord2f (0, 0); glVertex2f (0, 0);
1746 glTexCoord2f ( 0, t1); glVertex2f ( 0, h1); 1784 glTexCoord2f (0, t); glVertex2f (0, h);
1747 glTexCoord2f (s1, t1); glVertex2f (w1, h1); 1785 glTexCoord2f (s, t); glVertex2f (w, h);
1748 glTexCoord2f (s1, 0); glVertex2f (w1, 0); 1786 glTexCoord2f (s, 0); glVertex2f (w, 0);
1749 glEnd (); 1787 glEnd ();
1750 } 1788 }
1789
1790 /* draw ?-marks or equivalent, this is very clumsy code :/ */
1791 {
1792 int x, y;
1793 int dx3 = dx * 3;
1794 int dy3 = dy * 3;
1795
1796 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1797 glBindTexture (GL_TEXTURE_2D, hidden_tex);
1798 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1799 glTranslatef (-1., -1., 0);
1800 glBegin (GL_QUADS);
1801
1802 for (y = 1; y < h; y += 3)
1803 {
1804 int y1 = y - dy3;
1805 int y1valid = y1 >= 0 && y1 < h;
1806
1807 for (x = 1; x < w; x += 3)
1808 {
1809 int x1 = x - dx3;
1810 uint8_t h1 = data1 [x + y * w] == DARKNESS_ADJUST (255 - FOW_DARKNESS);
1811 uint8_t h2;
1812
1813 if (y1valid && x1 >= 0 && x1 < w)
1814 h2 = data2 [x1 + y1 * w] == DARKNESS_ADJUST (255 - FOW_DARKNESS);
1815 else
1816 h2 = 1; /* out of range == invisible */
1817
1818 if (h1 || h2)
1819 {
1820 float alpha = h1 == h2 ? 1.f : h1 ? 1.f - blend : blend;
1821 glColor4f (1., 1., 1., alpha);
1822
1823 glTexCoord2f (0, 0.); glVertex2i (x , y );
1824 glTexCoord2f (0, 1.); glVertex2i (x , y + 3);
1825 glTexCoord2f (1, 1.); glVertex2i (x + 3, y + 3);
1826 glTexCoord2f (1, 0.); glVertex2i (x + 3, y );
1827 }
1828 }
1829 }
1830 }
1831
1832 glEnd ();
1751 1833
1752 glPopMatrix (); 1834 glPopMatrix ();
1753 1835
1754 glDisable (GL_TEXTURE_2D); 1836 glDisable (GL_TEXTURE_2D);
1755 glDisable (GL_BLEND); 1837 glDisable (GL_BLEND);
1976 { 2058 {
1977 ext = *data++; 2059 ext = *data++;
1978 cmd = ext & 0x7f; 2060 cmd = ext & 0x7f;
1979 2061
1980 if (cmd < 4) 2062 if (cmd < 4)
1981 cell->darkness = 255 - ext * 64 + 1; 2063 cell->darkness = 255 - ext * 64 + 1; /* make sure this doesn't collide with FOW_DARKNESS */
1982 else if (cmd == 5) // health 2064 else if (cmd == 5) // health
1983 { 2065 {
1984 cell->stat_width = 1; 2066 cell->stat_width = 1;
1985 cell->stat_hp = *data++; 2067 cell->stat_hp = *data++;
1986 } 2068 }
2061 ? self->row + y 2143 ? self->row + y
2062 : 0; 2144 : 0;
2063 2145
2064 for (x = x0; x < x1; x++) 2146 for (x = x0; x < x1; x++)
2065 { 2147 {
2066 int r = 32, g = 32, b = 32, a = 192; 2148 unsigned int r = 32, g = 32, b = 32, a = 192;
2067 2149
2068 if (row && row->c0 <= x && x < row->c1) 2150 if (row && row->c0 <= x && x < row->c1)
2069 { 2151 {
2070 mapcell *cell = row->col + (x - row->c0); 2152 mapcell *cell = row->col + (x - row->c0);
2071 2153
2073 { 2155 {
2074 maptex tex = self->tex [cell->tile [z]]; 2156 maptex tex = self->tex [cell->tile [z]];
2075 int a0 = 255 - tex.a; 2157 int a0 = 255 - tex.a;
2076 int a1 = tex.a; 2158 int a1 = tex.a;
2077 2159
2078 r = (r * a0 + tex.r * a1) / 255; 2160 r = div255 (r * a0 + tex.r * a1);
2079 g = (g * a0 + tex.g * a1) / 255; 2161 g = div255 (g * a0 + tex.g * a1);
2080 b = (b * a0 + tex.b * a1) / 255; 2162 b = div255 (b * a0 + tex.b * a1);
2081 a = (a * a0 + tex.a * a1) / 255; 2163 a = div255 (a * a0 + tex.a * a1);
2082 } 2164 }
2083 } 2165 }
2084 2166
2085 *map++ = (r ) 2167 *map++ = (r )
2086 | (g << 8) 2168 | (g << 8)
2093} 2175}
2094 OUTPUT: 2176 OUTPUT:
2095 RETVAL 2177 RETVAL
2096 2178
2097void 2179void
2098draw (DC::Map self, int mx, int my, int sw, int sh, int T, U32 player = 0xffffffff, int sdx = 0, int sdy = 0) 2180draw (DC::Map self, int mx, int my, int sw, int sh, int Tw, int Th, U32 player = 0xffffffff, int sdx = 0, int sdy = 0)
2099 CODE: 2181 CODE:
2100{ 2182{
2101 int x, y, z; 2183 int x, y, z;
2102 2184
2103 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ()); 2185 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
2107 int pl_x, pl_y; 2189 int pl_x, pl_y;
2108 maptex pl_tex; 2190 maptex pl_tex;
2109 rc_t *rc = rc_alloc (); 2191 rc_t *rc = rc_alloc ();
2110 rc_t *rc_ov = rc_alloc (); 2192 rc_t *rc_ov = rc_alloc ();
2111 rc_key_t key; 2193 rc_key_t key;
2112 rc_array_t *arr, *arr_hidden; 2194 rc_array_t *arr;
2113 2195
2114 pl_tex.name = 0; 2196 pl_tex.name = 0;
2115 2197
2116 // that's current max. sorry. 2198 // that's current max. sorry.
2117 if (sw > 255) sw = 255; 2199 if (sw > 255) sw = 255;
2154 } 2236 }
2155 2237
2156 glEnable (GL_BLEND); 2238 glEnable (GL_BLEND);
2157 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2239 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2158 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 2240 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
2159
2160 key.texname = self->tex [TEXID_HIDDEN].name;
2161 arr_hidden = rc_array (rc_ov, &key);
2162 2241
2163 for (z = 0; z <= 2; z++) 2242 for (z = 0; z <= 2; z++)
2164 { 2243 {
2165 memset (smooth_level, 0, sizeof (smooth_level)); 2244 memset (smooth_level, 0, sizeof (smooth_level));
2166 key.texname = -1; 2245 key.texname = -1;
2190 2269
2191 key.texname = tex.name; 2270 key.texname = tex.name;
2192 arr = rc_array (rc, &key); 2271 arr = rc_array (rc, &key);
2193 } 2272 }
2194 2273
2195 px = (x + 1) * T - tex.w; 2274 px = (x + 1) * Th - tex.w;
2196 py = (y + 1) * T - tex.h; 2275 py = (y + 1) * Tw - tex.h;
2197 2276
2198 if (expect_false (cell->player == player) && expect_false (z == 2)) 2277 if (expect_false (cell->player == player) && expect_false (z == 2))
2199 { 2278 {
2200 pl_x = px; 2279 pl_x = px;
2201 pl_y = py; 2280 pl_y = py;
2246 skey.x = x ; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0400); 2325 skey.x = x ; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0400);
2247 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0800); 2326 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0800);
2248 } 2327 }
2249 } 2328 }
2250 2329
2251 if (expect_false (z == 2)) 2330 if (expect_false (z == 2) && expect_false (cell->flags))
2252 { 2331 {
2253 /* draw question marks on top of hidden spaces */ 2332 // overlays such as the speech bubble, probably more to come
2254 if (!cell->darkness) 2333 if (cell->flags & 1)
2255 { 2334 {
2256 maptex tex = self->tex [TEXID_HIDDEN];
2257 int px = (x + 1) * T - tex.w;
2258 int py = (y + 1) * T - tex.h;
2259
2260 rc_t2f_v3f (arr_hidden, 0 , 0 , px , py , 0);
2261 rc_t2f_v3f (arr_hidden, 0 , tex.t, px , py + tex.h, 0);
2262 rc_t2f_v3f (arr_hidden, tex.s, tex.t, px + tex.w, py + tex.h, 0);
2263 rc_t2f_v3f (arr_hidden, tex.s, 0 , px + tex.w, py , 0);
2264 }
2265
2266 if (expect_false (cell->flags))
2267 {
2268 // overlays such as the speech bubble, probably more to come
2269 if (cell->flags & 1)
2270 {
2271 rc_key_t key_ov = key; 2335 rc_key_t key_ov = key;
2272 maptex tex = self->tex [TEXID_SPEECH]; 2336 maptex tex = self->tex [TEXID_SPEECH];
2273 rc_array_t *arr; 2337 rc_array_t *arr;
2274 int px = x * T + T * 2 / 32; 2338 int px = x * Tw + Tw * 2 / 32;
2275 int py = y * T - T * 6 / 32; 2339 int py = y * Th - Th * 6 / 32;
2276 2340
2277 key_ov.texname = tex.name; 2341 key_ov.texname = tex.name;
2278 arr = rc_array (rc_ov, &key_ov); 2342 arr = rc_array (rc_ov, &key_ov);
2279 2343
2280 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2344 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
2281 rc_t2f_v3f (arr, 0 , tex.t, px , py + T, 0); 2345 rc_t2f_v3f (arr, 0 , tex.t, px , py + Th, 0);
2282 rc_t2f_v3f (arr, tex.s, tex.t, px + T, py + T, 0); 2346 rc_t2f_v3f (arr, tex.s, tex.t, px + Tw, py + Th, 0);
2283 rc_t2f_v3f (arr, tex.s, 0 , px + T, py , 0); 2347 rc_t2f_v3f (arr, tex.s, 0 , px + Tw, py , 0);
2284 }
2285 } 2348 }
2286 } 2349 }
2287 } 2350 }
2288 } 2351 }
2289 2352
2316 if (!(bits & 0x1000) 2379 if (!(bits & 0x1000)
2317 && skey->level == level 2380 && skey->level == level
2318 && level > smooth_max [skey->x][skey->y]) 2381 && level > smooth_max [skey->x][skey->y])
2319 { 2382 {
2320 maptex tex = self->tex [skey->tile]; 2383 maptex tex = self->tex [skey->tile];
2321 int px = (((int)skey->x) - 1) * T; 2384 int px = (((int)skey->x) - 1) * Tw;
2322 int py = (((int)skey->y) - 1) * T; 2385 int py = (((int)skey->y) - 1) * Th;
2323 int border = bits & 15; 2386 int border = bits & 15;
2324 int corner = (bits >> 8) & ~(bits >> 4) & 15; 2387 int corner = (bits >> 8) & ~(bits >> 4) & 15;
2325 float dx = tex.s * .0625f; // 16 images/row 2388 float dx = tex.s * .0625f; // 16 images/row
2326 float dy = tex.t * .5f ; // 2 images/column 2389 float dy = tex.t * .5f ; // 2 images/column
2327 2390
2340 2403
2341 if (border) 2404 if (border)
2342 { 2405 {
2343 float ox = border * dx; 2406 float ox = border * dx;
2344 2407
2345 glTexCoord2f (ox , 0.f ); glVertex2i (px , py ); 2408 glTexCoord2f (ox , 0.f ); glVertex2i (px , py );
2346 glTexCoord2f (ox , dy ); glVertex2i (px , py + T); 2409 glTexCoord2f (ox , dy ); glVertex2i (px , py + Th);
2347 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py + T); 2410 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py + Th);
2348 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + T, py ); 2411 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + Tw, py );
2349 } 2412 }
2350 2413
2351 if (corner) 2414 if (corner)
2352 { 2415 {
2353 float ox = corner * dx; 2416 float ox = corner * dx;
2354 2417
2355 glTexCoord2f (ox , dy ); glVertex2i (px , py ); 2418 glTexCoord2f (ox , dy ); glVertex2i (px , py );
2356 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + T); 2419 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + Th);
2357 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + T, py + T); 2420 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + Tw, py + Th);
2358 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py ); 2421 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py );
2359 } 2422 }
2360 } 2423 }
2361 } 2424 }
2362 } 2425 }
2363 } 2426 }
2404 for (x = 0; x < sw; x++) 2467 for (x = 0; x < sw; x++)
2405 if (row->c0 <= x + mx && x + mx < row->c1) 2468 if (row->c0 <= x + mx && x + mx < row->c1)
2406 { 2469 {
2407 mapcell *cell = row->col + (x + mx - row->c0); 2470 mapcell *cell = row->col + (x + mx - row->c0);
2408 2471
2409 int px = x * T; 2472 int px = x * Tw;
2410 int py = y * T; 2473 int py = y * Th;
2411 2474
2412 if (expect_false (cell->player == player)) 2475 if (expect_false (cell->player == player))
2413 { 2476 {
2414 px += sdx; 2477 px += sdx;
2415 py += sdy; 2478 py += sdy;
2416 } 2479 }
2417 2480
2418 if (cell->stat_hp) 2481 if (cell->stat_hp)
2419 { 2482 {
2420 int width = cell->stat_width * T; 2483 int width = cell->stat_width * Tw;
2421 int thick = (sh * T / 32 + 27) / 28 + 1 + cell->stat_width; 2484 int thick = (sh * Th / 32 + 27) / 28 + 1 + cell->stat_width;
2422 2485
2423 glColor3ub (0, 0, 0); 2486 glColor3ub (0, 0, 0);
2424 glRectf (px + 1, py - thick - 2, 2487 glRectf (px + 1, py - thick - 2,
2425 px + width - 1, py); 2488 px + width - 1, py);
2426 2489
2463 int x, y; 2526 int x, y;
2464 2527
2465 glEnable (GL_TEXTURE_2D); 2528 glEnable (GL_TEXTURE_2D);
2466 /* GL_REPLACE would be correct, as we don't need to modulate alpha, 2529 /* GL_REPLACE would be correct, as we don't need to modulate alpha,
2467 * but the nvidia driver (185.18.14) mishandles alpha textures 2530 * but the nvidia driver (185.18.14) mishandles alpha textures
2468 * ansd takes the colour from god knows where instead of using 2531 * and takes the colour from god knows where instead of using
2469 * Cp. MODULATE results in the same colour, but slightly different 2532 * Cp. MODULATE results in the same colour, but slightly different
2470 * alpha, but atcually gives us the correct colour with nvidia. 2533 * alpha, but atcually gives us the correct colour with nvidia.
2471 */ 2534 */
2472 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 2535 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
2473 glEnable (GL_BLEND); 2536 glEnable (GL_BLEND);
2502void 2565void
2503fow_texture (DC::Map self, int mx, int my, int sw, int sh) 2566fow_texture (DC::Map self, int mx, int my, int sw, int sh)
2504 PPCODE: 2567 PPCODE:
2505{ 2568{
2506 int x, y; 2569 int x, y;
2507 int sw1 = sw + 2; 2570 int sw1 = sw + 2;
2508 int sh1 = sh + 2; 2571 int sh1 = sh + 2;
2509 int sh3 = sh * 3; 2572 int sh3 = sh * 3;
2510 int sw34 = (sw * 3 + 3) & ~3; 2573 int sw3 = sw * 3;
2574 SV *darkness3_sv = sv_2mortal (newSV (sw3 * sh3));
2575 uint8_t *darkness3 = (uint8_t *)SvPVX (darkness3_sv);
2511 uint8_t *darkness1 = (uint8_t *)malloc (sw1 * sh1); 2576 uint8_t *darkness1 = (uint8_t *)malloc (sw1 * sh1);
2512 SV *darkness3_sv = sv_2mortal (newSV (sw34 * sh3)); 2577 memset (darkness1, 0, sw1*sh1);
2513 uint8_t *darkness3 = (uint8_t *)SvPVX (darkness3_sv);
2514 2578
2515 SvPOK_only (darkness3_sv); 2579 SvPOK_only (darkness3_sv);
2516 SvCUR_set (darkness3_sv, sw34 * sh3); 2580 SvCUR_set (darkness3_sv, sw3 * sh3);
2517 2581
2518 mx += self->x - 1; 2582 mx += self->x - 1;
2519 my += self->y - 1; 2583 my += self->y - 1;
2520
2521 memset (darkness1, DARKNESS_ADJUST (255 - FOW_DARKNESS), sw1 * sh1);
2522 2584
2523 for (y = 0; y < sh1; y++) 2585 for (y = 0; y < sh1; y++)
2524 if (0 <= y + my && y + my < self->rows) 2586 if (0 <= y + my && y + my < self->rows)
2525 { 2587 {
2526 maprow *row = self->row + (y + my); 2588 maprow *row = self->row + (y + my);
2559 2621
2560 uint8_t r13 = (d13 + d23 + d12) / 3; 2622 uint8_t r13 = (d13 + d23 + d12) / 3;
2561 uint8_t r23 = d23; 2623 uint8_t r23 = d23;
2562 uint8_t r33 = (d23 + d33 + d32) / 3; 2624 uint8_t r33 = (d23 + d33 + d32) / 3;
2563 2625
2564 darkness3 [(y * 3 ) * sw34 + (x * 3 )] = MAX (d22, r11); 2626 darkness3 [(y * 3 ) * sw3 + (x * 3 )] = MAX (d22, r11);
2565 darkness3 [(y * 3 ) * sw34 + (x * 3 + 1)] = MAX (d22, r21); 2627 darkness3 [(y * 3 ) * sw3 + (x * 3 + 1)] = MAX (d22, r21);
2566 darkness3 [(y * 3 ) * sw34 + (x * 3 + 2)] = MAX (d22, r31); 2628 darkness3 [(y * 3 ) * sw3 + (x * 3 + 2)] = MAX (d22, r31);
2567 darkness3 [(y * 3 + 1) * sw34 + (x * 3 )] = MAX (d22, r12); 2629 darkness3 [(y * 3 + 1) * sw3 + (x * 3 )] = MAX (d22, r12);
2568 darkness3 [(y * 3 + 1) * sw34 + (x * 3 + 1)] = MAX (d22, r22); 2630 darkness3 [(y * 3 + 1) * sw3 + (x * 3 + 1)] = MAX (d22, r22); /* this MUST be == d22 */
2569 darkness3 [(y * 3 + 1) * sw34 + (x * 3 + 2)] = MAX (d22, r32); 2631 darkness3 [(y * 3 + 1) * sw3 + (x * 3 + 2)] = MAX (d22, r32);
2570 darkness3 [(y * 3 + 2) * sw34 + (x * 3 )] = MAX (d22, r13); 2632 darkness3 [(y * 3 + 2) * sw3 + (x * 3 )] = MAX (d22, r13);
2571 darkness3 [(y * 3 + 2) * sw34 + (x * 3 + 1)] = MAX (d22, r23); 2633 darkness3 [(y * 3 + 2) * sw3 + (x * 3 + 1)] = MAX (d22, r23);
2572 darkness3 [(y * 3 + 2) * sw34 + (x * 3 + 2)] = MAX (d22, r33); 2634 darkness3 [(y * 3 + 2) * sw3 + (x * 3 + 2)] = MAX (d22, r33);
2573 } 2635 }
2574 2636
2575 free (darkness1); 2637 free (darkness1);
2576 2638
2577 EXTEND (SP, 3); 2639 EXTEND (SP, 3);
2578 PUSHs (sv_2mortal (newSViv (sw34))); 2640 PUSHs (sv_2mortal (newSViv (sw3)));
2579 PUSHs (sv_2mortal (newSViv (sh3))); 2641 PUSHs (sv_2mortal (newSViv (sh3)));
2580 PUSHs (darkness3_sv); 2642 PUSHs (darkness3_sv);
2581} 2643}
2582 2644
2583SV * 2645SV *
2781 if (RETVAL < 0) 2843 if (RETVAL < 0)
2782 { 2844 {
2783 RETVAL = Mix_GroupOldest (-1); 2845 RETVAL = Mix_GroupOldest (-1);
2784 2846
2785 if (RETVAL < 0) 2847 if (RETVAL < 0)
2848 {
2849 // happens sometimes, maybe it just stopped playing(?)
2850 RETVAL = Mix_GroupAvailable (-1);
2851
2852 if (RETVAL < 0)
2786 XSRETURN_UNDEF; 2853 XSRETURN_UNDEF;
2787 2854 }
2855 else
2788 Mix_HaltChannel (RETVAL); 2856 Mix_HaltChannel (RETVAL);
2789 } 2857 }
2790 2858
2791 Mix_UnregisterAllEffects (RETVAL); 2859 Mix_UnregisterAllEffects (RETVAL);
2792 Mix_Volume (RETVAL, 128); 2860 Mix_Volume (RETVAL, 128);
2793} 2861}
2852 Mix_SetReverseStereo (self, flip); 2920 Mix_SetReverseStereo (self, flip);
2853 2921
2854MODULE = Deliantra::Client PACKAGE = DC::MixChunk 2922MODULE = Deliantra::Client PACKAGE = DC::MixChunk
2855 2923
2856PROTOTYPES: DISABLE 2924PROTOTYPES: DISABLE
2925
2926void
2927decoders ()
2928 PPCODE:
2929#if SDL_MIXER_MAJOR_VERSION > 1 || SDL_MIXER_MINOR_VERSION > 2 || SDL_MIXER_PATCHLEVEL >= 10
2930 int i, num = Mix_GetNumChunkDecoders ();
2931 EXTEND (SP, num);
2932 for (i = 0; i < num; ++i)
2933 PUSHs (sv_2mortal (newSVpv (Mix_GetChunkDecoder (i), 0)));
2934#else
2935 XPUSHs (sv_2mortal (newSVpv ("(sdl mixer too old)", 0)));
2936#endif
2857 2937
2858DC::MixChunk 2938DC::MixChunk
2859new (SV *class, DC::RW rwops) 2939new (SV *class, DC::RW rwops)
2860 CODE: 2940 CODE:
2861 RETVAL = Mix_LoadWAV_RW (rwops, 1); 2941 RETVAL = Mix_LoadWAV_RW (rwops, 1);
2894 OUTPUT: 2974 OUTPUT:
2895 RETVAL 2975 RETVAL
2896 2976
2897MODULE = Deliantra::Client PACKAGE = DC::MixMusic 2977MODULE = Deliantra::Client PACKAGE = DC::MixMusic
2898 2978
2979void
2980decoders ()
2981 PPCODE:
2982#if SDL_MIXER_MAJOR_VERSION > 1 || SDL_MIXER_MINOR_VERSION > 2 || SDL_MIXER_PATCHLEVEL >= 10
2983 int i, num = Mix_GetNumMusicDecoders ();
2984 EXTEND (SP, num);
2985 for (i = 0; i < num; ++i)
2986 PUSHs (sv_2mortal (newSVpv (Mix_GetMusicDecoder (i), 0)));
2987#else
2988 XPUSHs (sv_2mortal (newSVpv ("(sdl mixer too old)", 0)));
2989#endif
2990
2899int 2991int
2900volume (int volume = -1) 2992volume (int volume = -1)
2901 PROTOTYPE: ;$ 2993 PROTOTYPE: ;$
2902 CODE: 2994 CODE:
2903 if (items > 0) 2995 if (items > 0)
2913 3005
2914void 3006void
2915halt () 3007halt ()
2916 CODE: 3008 CODE:
2917 Mix_HaltMusic (); 3009 Mix_HaltMusic ();
3010
3011int
3012playing ()
3013 CODE:
3014 RETVAL = Mix_PlayingMusic ();
3015 OUTPUT:
3016 RETVAL
2918 3017
2919DC::MixMusic 3018DC::MixMusic
2920new (SV *class, DC::RW rwops) 3019new (SV *class, DC::RW rwops)
2921 CODE: 3020 CODE:
2922 RETVAL = Mix_LoadMUS_RW (rwops); 3021 RETVAL = Mix_LoadMUS_RW (rwops);
3062 const_iv (GL_FUNC_SUBTRACT), 3161 const_iv (GL_FUNC_SUBTRACT),
3063 const_iv (GL_FUNC_REVERSE_SUBTRACT), 3162 const_iv (GL_FUNC_REVERSE_SUBTRACT),
3064# undef const_iv 3163# undef const_iv
3065 }; 3164 };
3066 3165
3067 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 3166 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
3068 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 3167 newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
3069 3168
3070 texture_av = newAV (); 3169 texture_av = newAV ();
3071 AvREAL_off (texture_av); 3170 AvREAL_off (texture_av);
3072} 3171}
3073 3172
3116 RETVAL 3215 RETVAL
3117 3216
3118int glGetError () 3217int glGetError ()
3119 3218
3120void glFinish () 3219void glFinish ()
3220
3221void glFlush ()
3121 3222
3122void glClear (int mask) 3223void glClear (int mask)
3123 3224
3124void glClearColor (float r, float g, float b, float a = 1.0) 3225void glClearColor (float r, float g, float b, float a = 1.0)
3125 PROTOTYPE: @ 3226 PROTOTYPE: @
3296void glNewList (int list, int mode = GL_COMPILE) 3397void glNewList (int list, int mode = GL_COMPILE)
3297 3398
3298void glEndList () 3399void glEndList ()
3299 3400
3300void glCallList (int list) 3401void glCallList (int list)
3402
3403void c_init ()
3404 CODE:
3405 glPixelStorei (GL_PACK_ALIGNMENT , 1);
3406 glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
3301 3407
3302MODULE = Deliantra::Client PACKAGE = DC::UI::Base 3408MODULE = Deliantra::Client PACKAGE = DC::UI::Base
3303 3409
3304PROTOTYPES: DISABLE 3410PROTOTYPES: DISABLE
3305 3411

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines