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.296 by root, Mon Dec 21 23:52:34 2009 UTC vs.
Revision 1.323 by root, Sun Nov 18 01:48:39 2018 UTC

15 15
16#include "EXTERN.h" 16#include "EXTERN.h"
17#include "perl.h" 17#include "perl.h"
18#include "XSUB.h" 18#include "XSUB.h"
19 19
20#include "flat_hash_map.hpp"
21
20#ifdef _WIN32 22#ifdef _WIN32
21# undef pipe 23# undef pipe
22// microsoft vs. C 24// microsoft vs. C
23# define sqrtf(x) sqrt(x) 25# define sqrtf(x) sqrt(x)
24# define atan2f(x,y) atan2(x,y) 26# define atan2f(x,y) atan2(x,y)
25# define M_PI 3.14159265f 27# define M_PI 3.14159265f
26#endif 28#endif
27 29
28#include <assert.h> 30#include <cassert>
29#include <math.h> 31#include <cmath>
30#include <string.h> 32#include <cstring>
31#include <stdio.h> 33#include <cstdio>
32#include <stdlib.h> 34#include <cstdlib>
35
36#include <utility>
33 37
34#define USE_RWOPS 1 // for SDL_mixer:LoadMUS_RW 38#define USE_RWOPS 1 // for SDL_mixer:LoadMUS_RW
35 39
36#include <SDL.h> 40#include <SDL.h>
37#include <SDL_thread.h> 41#include <SDL_thread.h>
41#include <SDL_opengl.h> 45#include <SDL_opengl.h>
42 46
43/* work around os x broken headers */ 47/* work around os x broken headers */
44#ifdef __MACOSX__ 48#ifdef __MACOSX__
45typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); 49typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
50typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
51typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t);
46#endif 52#endif
47 53
48#define PANGO_ENABLE_BACKEND 54#define PANGO_ENABLE_BACKEND
49#define G_DISABLE_CAST_CHECKS 55#define G_DISABLE_CAST_CHECKS
50 56
51#include <glib/gmacros.h> 57#include <glib.h>
52 58
53#include <pango/pango.h> 59#include <pango/pango.h>
54 60
55#ifndef PANGO_VERSION_CHECK 61#ifndef PANGO_VERSION_CHECK
56# define PANGO_VERSION_CHECK(a,b,c) 0 62# define PANGO_VERSION_CHECK(a,b,c) 0
97 103
98#define KMOD_LRAM 0x10000 // our extension 104#define KMOD_LRAM 0x10000 // our extension
99 105
100#define TEXID_SPEECH 1 106#define TEXID_SPEECH 1
101#define TEXID_NOFACE 2 107#define TEXID_NOFACE 2
102#define TEXID_HIDDEN 3 108
109static char *
110fast_sv_grow (SV *sv, STRLEN need)
111{
112 STRLEN len = SvLEN (sv);
113 STRLEN want = SvCUR (sv) + need;
114
115 if (expect_false (len < want))
116 {
117 do
118 len *= 2;
119 while (len < want);
120
121 sv_grow (sv, len);
122 }
123
124 SvCUR_set (sv, want);
125 return SvEND (sv) - need;
126}
103 127
104static AV *texture_av; 128static AV *texture_av;
105 129
106static struct 130static struct
107{ 131{
164{ 188{
165 GSList *attrs = run->item->analysis.extra_attrs; 189 GSList *attrs = run->item->analysis.extra_attrs;
166 190
167 while (attrs) 191 while (attrs)
168 { 192 {
169 PangoAttribute *attr = attrs->data; 193 PangoAttribute *attr = (PangoAttribute *)attrs->data;
170 194
171 if (attr->klass->type == PANGO_ATTR_SHAPE) 195 if (attr->klass->type == PANGO_ATTR_SHAPE)
172 return 1; 196 return 1;
173 197
174 attrs = attrs->next; 198 attrs = attrs->next;
175 } 199 }
176 200
177 return 0; 201 return 0;
178} 202}
179 203
180typedef struct cf_layout { 204struct cf_layout {
181 PangoLayout *pl; 205 PangoLayout *pl;
182 float r, g, b, a; // default color for rgba mode 206 float r, g, b, a; // default color for rgba mode
183 int base_height; 207 int base_height;
184 DC__Font font; 208 DC__Font font;
185 rc_t *rc; 209 rc_t *rc;
186} *DC__Layout; 210};
211
212typedef cf_layout *DC__Layout;
187 213
188static DC__Font default_font; 214static DC__Font default_font;
189static PangoContext *opengl_context; 215static PangoContext *opengl_context;
190static PangoFontMap *opengl_fontmap; 216static PangoFontMap *opengl_fontmap;
191 217
192static void 218static void
193substitute_func (FcPattern *pattern, gpointer data) 219substitute_func (FcPattern *pattern, gpointer data)
194{ 220{
195 FcPatternAddBool (pattern, FC_HINTING, 1); 221 FcPatternAddBool (pattern, FC_HINTING, 1);
196#ifdef FC_HINT_STYLE 222#ifdef FC_HINT_STYLE
197 FcPatternAddBool (pattern, FC_HINT_STYLE, FC_HINT_FULL); 223 FcPatternAddInteger (pattern, FC_HINT_STYLE, FC_HINT_FULL);
198#endif 224#endif
199 FcPatternAddBool (pattern, FC_AUTOHINT, 0); 225 FcPatternAddBool (pattern, FC_AUTOHINT, 0);
200} 226}
201 227
202static void 228static void
232} 258}
233 259
234typedef uint16_t tileid; 260typedef uint16_t tileid;
235typedef uint16_t faceid; 261typedef uint16_t faceid;
236 262
237typedef struct { 263struct maptex
264{
238 GLuint name; 265 GLuint name;
239 int w, h; 266 int w, h;
240 float s, t; 267 float s, t;
241 uint8_t r, g, b, a; 268 uint8_t r, g, b, a;
242 tileid smoothtile; 269 tileid smoothtile;
243 uint8_t smoothlevel; 270 uint8_t smoothlevel;
244 uint8_t unused; /* set to zero on use */ 271 uint8_t unused; /* set to zero on use */
245} maptex; 272};
246 273
247typedef struct { 274struct mapcell
275{
248 uint32_t player; 276 uint32_t player;
249 tileid tile[3]; 277 tileid tile[3];
250 uint16_t darkness; 278 uint16_t darkness;
251 uint8_t stat_width, stat_hp, flags, smoothmax; 279 uint8_t stat_width, stat_hp, flags, smoothmax;
252} mapcell; 280};
253 281
254typedef struct { 282struct maprow
283{
255 int32_t c0, c1; 284 int32_t c0, c1;
256 mapcell *col; 285 mapcell *col;
257} maprow; 286};
258 287
259typedef struct map { 288struct mapgrid {
260 int x, y, w, h; 289 int x, y, w, h;
261 int ox, oy; /* offset to virtual global coordinate system */ 290 int ox, oy; /* offset to virtual global coordinate system */
262 int faces; tileid *face2tile; // [faceid] 291 int faces; tileid *face2tile; // [faceid]
263 int texs; maptex *tex; // [tileid] 292 int texs; maptex *tex; // [tileid]
264 293
265 int32_t rows; 294 int32_t rows;
266 maprow *row; 295 maprow *row;
267} *DC__Map; 296};
297
298typedef mapgrid *DC__Map;
268 299
269static char * 300static char *
270prepend (char *ptr, int sze, int inc) 301prepend (char *ptr, int sze, int inc)
271{ 302{
272 char *p; 303 char *p;
290 321
291#define Append(type,ptr,sze,inc) (ptr) = (type *)append ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type)) 322#define Append(type,ptr,sze,inc) (ptr) = (type *)append ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type))
292#define Prepend(type,ptr,sze,inc) (ptr) = (type *)prepend ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type)) 323#define Prepend(type,ptr,sze,inc) (ptr) = (type *)prepend ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type))
293 324
294static void 325static void
295need_facenum (struct map *self, faceid face) 326need_facenum (struct mapgrid *self, faceid face)
296{ 327{
297 while (self->faces <= face) 328 while (self->faces <= face)
298 { 329 {
299 Append (tileid, self->face2tile, self->faces, self->faces); 330 Append (tileid, self->face2tile, self->faces, self->faces);
300 self->faces *= 2; 331 self->faces *= 2;
301 } 332 }
302} 333}
303 334
304static void 335static void
305need_texid (struct map *self, int texid) 336need_texid (struct mapgrid *self, int texid)
306{ 337{
307 while (self->texs <= texid) 338 while (self->texs <= texid)
308 { 339 {
309 Append (maptex, self->tex, self->texs, self->texs); 340 Append (maptex, self->tex, self->texs, self->texs);
310 self->texs *= 2; 341 self->texs *= 2;
311 } 342 }
312} 343}
313 344
314static maprow * 345static maprow *
315map_get_row (DC__Map self, int y) 346map_get_row (mapgrid *self, int y)
316{ 347{
317 if (0 > y) 348 if (0 > y)
318 { 349 {
319 int extend = - y + MAP_EXTEND_Y; 350 int extend = - y + MAP_EXTEND_Y;
320 Prepend (maprow, self->row, self->rows, extend); 351 Prepend (maprow, self->row, self->rows, extend);
358 389
359 return row->col + (x - row->c0); 390 return row->col + (x - row->c0);
360} 391}
361 392
362static mapcell * 393static mapcell *
363map_get_cell (DC__Map self, int x, int y) 394map_get_cell (mapgrid *self, int x, int y)
364{ 395{
365 return row_get_cell (map_get_row (self, y), x); 396 return row_get_cell (map_get_row (self, y), x);
366} 397}
367 398
368static void 399static void
369map_clear (DC__Map self) 400map_clear (mapgrid *self)
370{ 401{
371 int r; 402 int r;
372 403
373 for (r = 0; r < self->rows; r++) 404 for (r = 0; r < self->rows; r++)
374 Safefree (self->row[r].col); 405 Safefree (self->row[r].col);
392 (cell)->flags = 0; \ 423 (cell)->flags = 0; \
393 (cell)->player = 0; \ 424 (cell)->player = 0; \
394 } while (0) 425 } while (0)
395 426
396static void 427static void
397map_blank (DC__Map self, int x0, int y0, int w, int h) 428map_blank (mapgrid *self, int x0, int y0, int w, int h)
398{ 429{
399 int x, y; 430 int x, y;
400 maprow *row; 431 maprow *row;
401 mapcell *cell; 432 mapcell *cell;
402 433
419 CELL_CLEAR (cell); 450 CELL_CLEAR (cell);
420 } 451 }
421 } 452 }
422} 453}
423 454
424typedef struct { 455struct smooth_key
456{
425 tileid tile; 457 tileid tile;
426 uint8_t x, y, level; 458 uint8_t x, y, level;
427} smooth_key; 459
460 bool operator == (const smooth_key &o) const
461 {
462 return tile == o.tile && x == o.x && y == o.y && level == o.level;
463 }
464};
465
466typedef ska::flat_hash_map<smooth_key, IV> smooth_hash;
467
468namespace std {
469 template <>
470 struct hash<smooth_key>
471 {
472 size_t operator () (const smooth_key &v) const
473 {
474 return v.tile + (v.x << 8) + (v.y << 16) + (v.level << 24);
475 }
476 };
477}
428 478
429static void 479static void
430smooth_or_bits (HV *hv, smooth_key *key, IV bits) 480smooth_or_bits (smooth_hash &h, smooth_key &key, IV bits)
431{ 481{
432 SV **sv = hv_fetch (hv, (char *)key, sizeof (*key), 1); 482 auto &&it = h.find (key);
433 483
434 if (SvIOK (*sv)) 484 if (it == h.end ())
435 SvIV_set (*sv, SvIVX (*sv) | bits); 485 h.insert (std::make_pair (key, bits));
436 else 486 else
437 sv_setiv (*sv, bits); 487 it->second |= bits;
438} 488}
439 489
440static void 490static void
441music_finished (void) 491music_finished (void)
442{ 492{
459 ev.code = 1; 509 ev.code = 1;
460 ev.data1 = (void *)(long)channel; 510 ev.data1 = (void *)(long)channel;
461 ev.data2 = 0; 511 ev.data2 = 0;
462 512
463 SDL_PushEvent ((SDL_Event *)&ev); 513 SDL_PushEvent ((SDL_Event *)&ev);
514}
515
516// approximately divide by 255
517static unsigned int
518div255 (unsigned int n)
519{
520 return (n + (n >> 8)) >> 8;
464} 521}
465 522
466static unsigned int 523static unsigned int
467minpot (unsigned int n) 524minpot (unsigned int n)
468{ 525{
551 608
552 return mod; 609 return mod;
553} 610}
554 611
555static void 612static void
556deliantra_main () 613deliantra_main (SV *real_main)
557{ 614{
558 char *argv[] = { 0 }; 615 dSP;
559 call_argv ("::main", G_DISCARD | G_VOID, argv); 616
617 PUSHMARK (SP);
618 call_sv (real_main, G_DISCARD | G_VOID);
560} 619}
561 620
562#ifdef __MACOSX__ 621#ifdef __MACOSX__
622 static SV *real_main;
623
563 /* to due surprising braindamage on the side of SDL design, we 624 /* to due surprising braindamage on the side of SDL design, we
564 * do some mind-boggling hack here: SDL requires a custom main() 625 * do some mind-boggling hack here: SDL requires a custom main()
565 * on OS X, so... we provide one and call the original main(), which, 626 * on OS X, so... we provide one and call the original main(), which,
566 * due to share dlibrary magic, calls -lSDLmain's main, not perl's main, 627 * due to shared library magic, calls -lSDLmain's main, not perl's main,
567 * and which calls our main (== SDL_main) back. 628 * and which calls our main (== SDL_main) back.
568 */ 629 */
569 extern C_LINKAGE int 630 extern C_LINKAGE int
570 main (int argc, char *argv[]) 631 main (int argc, char *argv[])
571 { 632 {
572 deliantra_main (); 633 deliantra_main (real_main);
573 } 634 }
574 635
575 #undef main 636 #undef main
576 637
577 extern C_LINKAGE int main (int argc, char *argv[]); 638 extern C_LINKAGE int main (int argc, char *argv[]);
578 639
579 static void 640 static void
580 SDL_braino (void) 641 SDL_main_hack (SV *real_main_)
581 { 642 {
643 real_main = real_main_;
644
582 char *argv[] = { "deliantra client", 0 }; 645 char *argv[] = { "deliantra client", 0 };
583 (main) (1, argv); 646 (main) (1, argv);
584 } 647 }
585#else 648#else
586 static void 649 static void
587 SDL_braino (void) 650 SDL_main_hack (SV *real_main)
588 { 651 {
589 deliantra_main (); 652 deliantra_main (real_main);
590 } 653 }
591#endif 654#endif
592 655
593MODULE = Deliantra::Client PACKAGE = DC 656MODULE = Deliantra::Client PACKAGE = DC
594 657
795 858
796 const_iv (FOW_DARKNESS) 859 const_iv (FOW_DARKNESS)
797# undef const_iv 860# undef const_iv
798 }; 861 };
799 862
800 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 863 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
801 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 864 newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
802 865
803 assert (SDLK_MODIFIER_MIN == SDLK_NUMLOCK); 866 assert (SDLK_MODIFIER_MIN == SDLK_NUMLOCK);
804 assert (SDLK_MODIFIER_MAX == SDLK_COMPOSE); 867 assert (SDLK_MODIFIER_MAX == SDLK_COMPOSE);
805} 868}
806 869
845#endif 908#endif
846} 909}
847 910
848char *SDL_GetError () 911char *SDL_GetError ()
849 912
850void SDL_braino () 913void SDL_main_hack (SV *real_main)
914 PROTOTYPE: &
851 915
852int SDL_Init (U32 flags) 916int SDL_Init (U32 flags)
853 917
854int SDL_InitSubSystem (U32 flags) 918int SDL_InitSubSystem (U32 flags)
855 919
856void SDL_QuitSubSystem (U32 flags) 920void SDL_QuitSubSystem (U32 flags)
857 921
858void SDL_Quit () 922void SDL_Quit ()
859 923
860int SDL_GL_SetAttribute (int attr, int value) 924int SDL_GL_SetAttribute (int attr, int value)
925 C_ARGS: (SDL_GLattr)attr, value
861 926
862int SDL_GL_GetAttribute (int attr) 927int SDL_GL_GetAttribute (int attr)
863 CODE: 928 CODE:
864 if (SDL_GL_GetAttribute (attr, &RETVAL)) 929 if (SDL_GL_GetAttribute ((SDL_GLattr)attr, &RETVAL))
865 XSRETURN_UNDEF; 930 XSRETURN_UNDEF;
866 OUTPUT: 931 OUTPUT:
867 RETVAL 932 RETVAL
868 933
869void 934void
924 ); 989 );
925 990
926 if (RETVAL) 991 if (RETVAL)
927 { 992 {
928 av_clear (texture_av); 993 av_clear (texture_av);
929
930 SDL_WM_SetCaption ("Deliantra MORPG Client " VERSION, "Deliantra");
931#define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name); 994#define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name);
932#include "glfunc.h" 995#include "glfunc.h"
933#undef GL_FUNC 996#undef GL_FUNC
997 if (!gl.ActiveTexture ) gl.ActiveTexture = gl.ActiveTextureARB;
998 if (!gl.MultiTexCoord2f) gl.MultiTexCoord2f = gl.MultiTexCoord2fARB;
934 } 999 }
935} 1000}
936 OUTPUT: 1001 OUTPUT:
937 RETVAL 1002 RETVAL
1003
1004void
1005SDL_WM_SetCaption (const char *title, const char *icon)
938 1006
939void 1007void
940SDL_GL_SwapBuffers () 1008SDL_GL_SwapBuffers ()
941 1009
942char * 1010char *
943SDL_GetKeyName (int sym) 1011SDL_GetKeyName (int sym)
1012 C_ARGS: (SDLKey)sym
944 1013
945int 1014int
946SDL_GetAppState () 1015SDL_GetAppState ()
947 1016
948int 1017int
949SDL_GetModState () 1018SDL_GetModState ()
950 1019
1020int
1021SDL_WaitEvent ()
1022 C_ARGS: 0
1023
951void 1024void
1025SDL_PumpEvents ()
1026
1027void
952poll_events () 1028peep_events ()
953 PPCODE: 1029 PPCODE:
954{ 1030{
955 SDL_Event ev; 1031 SDL_Event ev;
956 1032
957 SDL_PumpEvents (); 1033 SDL_PumpEvents ();
1023 1099
1024 XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("DC::UI::Event", 1)))); 1100 XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("DC::UI::Event", 1))));
1025 } 1101 }
1026} 1102}
1027 1103
1104char *
1105SDL_AudioDriverName ()
1106 CODE:
1107{
1108 char buf [256];
1109 if (!SDL_AudioDriverName (buf, sizeof (buf)))
1110 XSRETURN_UNDEF;
1111
1112 RETVAL = buf;
1113}
1114 OUTPUT:
1115 RETVAL
1116
1028int 1117int
1029Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 4096) 1118Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 4096)
1030 POSTCALL: 1119 POSTCALL:
1031 Mix_HookMusicFinished (music_finished); 1120 Mix_HookMusicFinished (music_finished);
1032 Mix_ChannelFinished (channel_finished); 1121 Mix_ChannelFinished (channel_finished);
1033 1122
1034void 1123void
1035Mix_QuerySpec () 1124Mix_QuerySpec ()
1094add_font (char *file) 1183add_font (char *file)
1095 CODE: 1184 CODE:
1096 RETVAL = FcConfigAppFontAddFile (0, (const FcChar8 *)file); 1185 RETVAL = FcConfigAppFontAddFile (0, (const FcChar8 *)file);
1097 OUTPUT: 1186 OUTPUT:
1098 RETVAL 1187 RETVAL
1188
1189void
1190IMG_Init (int flags = IMG_INIT_JPG | IMG_INIT_PNG)
1191
1192# MIX_INIT_MP3 gives smpeg + libstdc++ + libgcc_s
1193void
1194Mix_Init (int flags = MIX_INIT_MOD | MIX_INIT_OGG)
1099 1195
1100void 1196void
1101load_image_inline (SV *image_) 1197load_image_inline (SV *image_)
1102 ALIAS: 1198 ALIAS:
1103 load_image_file = 1 1199 load_image_file = 1
1149 1245
1150 SDL_LockSurface (surface2); 1246 SDL_LockSurface (surface2);
1151 EXTEND (SP, 6); 1247 EXTEND (SP, 6);
1152 PUSHs (sv_2mortal (newSViv (surface2->w))); 1248 PUSHs (sv_2mortal (newSViv (surface2->w)));
1153 PUSHs (sv_2mortal (newSViv (surface2->h))); 1249 PUSHs (sv_2mortal (newSViv (surface2->h)));
1154 PUSHs (sv_2mortal (newSVpvn (surface2->pixels, surface2->h * surface2->pitch))); 1250 PUSHs (sv_2mortal (newSVpvn ((const char *)surface2->pixels, surface2->h * surface2->pitch)));
1155 PUSHs (sv_2mortal (newSViv (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA) ? GL_RGBA : GL_RGB))); 1251 PUSHs (sv_2mortal (newSViv (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA) ? GL_RGBA : GL_RGB)));
1156 PUSHs (sv_2mortal (newSViv (GL_RGBA))); 1252 PUSHs (sv_2mortal (newSViv (GL_RGBA)));
1157 PUSHs (sv_2mortal (newSViv (GL_UNSIGNED_BYTE))); 1253 PUSHs (sv_2mortal (newSViv (GL_UNSIGNED_BYTE)));
1158 SDL_UnlockSurface (surface2); 1254 SDL_UnlockSurface (surface2);
1159 1255
1231MODULE = Deliantra::Client PACKAGE = DC::Font 1327MODULE = Deliantra::Client PACKAGE = DC::Font
1232 1328
1233PROTOTYPES: DISABLE 1329PROTOTYPES: DISABLE
1234 1330
1235DC::Font 1331DC::Font
1236new_from_file (SV *class, char *path, int id = 0) 1332new_from_file (SV *klass, char *path, int id = 0)
1237 CODE: 1333 CODE:
1238{ 1334{
1239 int count; 1335 int count;
1240 FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)path, id, 0, &count); 1336 FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)path, id, 0, &count);
1241 RETVAL = pango_fc_font_description_from_pattern (pattern, 0); 1337 RETVAL = pango_fc_font_description_from_pattern (pattern, 0);
1270 PROTOTYPE: 1366 PROTOTYPE:
1271 CODE: 1367 CODE:
1272 tc_restore (); 1368 tc_restore ();
1273 1369
1274DC::Layout 1370DC::Layout
1275new (SV *class) 1371new (SV *klass)
1276 CODE: 1372 CODE:
1277 New (0, RETVAL, 1, struct cf_layout); 1373 New (0, RETVAL, 1, struct cf_layout);
1278 1374
1279 RETVAL->pl = pango_layout_new (opengl_context); 1375 RETVAL->pl = pango_layout_new (opengl_context);
1280 RETVAL->r = 1.; 1376 RETVAL->r = 1.;
1429 1525
1430void 1526void
1431set_height (DC::Layout self, int base_height) 1527set_height (DC::Layout self, int base_height)
1432 CODE: 1528 CODE:
1433 if (self->base_height != base_height) 1529 if (self->base_height != base_height)
1434 { 1530 {
1435 self->base_height = base_height; 1531 self->base_height = base_height;
1436 layout_update_font (self); 1532 layout_update_font (self);
1437 } 1533 }
1438 1534
1439void 1535void
1671void 1767void
1672draw_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) 1768draw_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)
1673 PROTOTYPE: @ 1769 PROTOTYPE: @
1674 CODE: 1770 CODE:
1675{ 1771{
1772 glEnable (GL_BLEND);
1773 glBlendFunc (intensity ? GL_SRC_ALPHA : GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1676 glEnable (GL_TEXTURE_2D); 1774 glEnable (GL_TEXTURE_2D);
1677 glEnable (GL_BLEND);
1678 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1679 glBindTexture (GL_TEXTURE_2D, name1); 1775 glBindTexture (GL_TEXTURE_2D, name1);
1680 1776
1681 glColor3f (intensity, intensity, intensity); 1777 glColor3f (intensity, intensity, intensity);
1682 glPushMatrix (); 1778 glPushMatrix ();
1683 glScalef (1./3, 1./3, 1.); 1779 glScalef (1./3, 1./3, 1.);
1698 glBindTexture (GL_TEXTURE_2D, name2); 1794 glBindTexture (GL_TEXTURE_2D, name2);
1699 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 1795 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
1700 1796
1701 /* rgb == rgb(glcolor) */ 1797 /* rgb == rgb(glcolor) */
1702 glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); 1798 glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
1703 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_CONSTANT); 1799 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
1704 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); 1800 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
1705 1801
1706 /* alpha = interpolate t0, t1 by env_alpha */ 1802 /* alpha = interpolate t0, t1 by env_alpha */
1707 glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, env_color); 1803 glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, env_color);
1708 1804
1803MODULE = Deliantra::Client PACKAGE = DC::Map 1899MODULE = Deliantra::Client PACKAGE = DC::Map
1804 1900
1805PROTOTYPES: DISABLE 1901PROTOTYPES: DISABLE
1806 1902
1807DC::Map 1903DC::Map
1808new (SV *class) 1904new (SV *klass)
1809 CODE: 1905 CODE:
1810 New (0, RETVAL, 1, struct map); 1906 New (0, RETVAL, 1, mapgrid);
1811 RETVAL->x = 0; 1907 RETVAL->x = 0;
1812 RETVAL->y = 0; 1908 RETVAL->y = 0;
1813 RETVAL->w = 0; 1909 RETVAL->w = 0;
1814 RETVAL->h = 0; 1910 RETVAL->h = 0;
1815 RETVAL->ox = 0; 1911 RETVAL->ox = 0;
1852 1948
1853void 1949void
1854set_smooth (DC::Map self, int face, int smooth, int level) 1950set_smooth (DC::Map self, int face, int smooth, int level)
1855 CODE: 1951 CODE:
1856{ 1952{
1857 tileid texid; 1953 tileid texid;
1858 maptex *tex; 1954 maptex *tex;
1859 1955
1860 if (face < 0 || face >= self->faces) 1956 if (face < 0 || face >= self->faces)
1861 return; 1957 return;
1862 1958
1863 if (smooth < 0 || smooth >= self->faces) 1959 if (smooth < 0 || smooth >= self->faces)
1864 return; 1960 return;
1865 1961
1866 texid = self->face2tile [face]; 1962 texid = self->face2tile [face];
1867 1963
1868 if (!texid) 1964 if (!texid)
1869 return; 1965 return;
1870 1966
1871 tex = self->tex + texid; 1967 tex = self->tex + texid;
1904} 2000}
1905 2001
1906void 2002void
1907expire_textures (DC::Map self, int texid, int count) 2003expire_textures (DC::Map self, int texid, int count)
1908 PPCODE: 2004 PPCODE:
1909 for (; texid < self->texs && count; ++texid, --count) 2005 for (; texid < self->texs && count; ++texid, --count)
1910 { 2006 {
1911 maptex *tex = self->tex + texid; 2007 maptex *tex = self->tex + texid;
1912 2008
1913 if (tex->name) 2009 if (tex->name)
1914 { 2010 {
1969 self->y += MAP_EXTEND_Y; 2065 self->y += MAP_EXTEND_Y;
1970 } 2066 }
1971} 2067}
1972 2068
1973SV * 2069SV *
1974map1a_update (DC::Map self, SV *data_, int extmap) 2070map1a_update (DC::Map self, SV *data_)
1975 CODE: 2071 CODE:
1976{ 2072{
1977 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_); 2073 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_);
1978 uint8_t *data_end = (uint8_t *)SvEND (data_); 2074 uint8_t *data_end = (uint8_t *)SvEND (data_);
1979 mapcell *cell; 2075 mapcell *cell;
2000 2096
2001 //TODO: don't trust server data to be in-range(!) 2097 //TODO: don't trust server data to be in-range(!)
2002 2098
2003 if (flags & 8) 2099 if (flags & 8)
2004 { 2100 {
2101 uint8_t ext, cmd;
2102
2005 if (extmap) 2103 do
2006 { 2104 {
2007 uint8_t ext, cmd; 2105 ext = *data++;
2106 cmd = ext & 0x7f;
2008 2107
2009 do 2108 if (cmd < 4)
2109 cell->darkness = 255 - ext * 64 + 1; /* make sure this doesn't collide with FOW_DARKNESS */
2110 else if (cmd == 5) // health
2010 { 2111 {
2011 ext = *data++;
2012 cmd = ext & 0x7f;
2013
2014 if (cmd < 4)
2015 cell->darkness = 255 - ext * 64 + 1; /* make sure this doesn't collide with FOW_DARKNESS */
2016 else if (cmd == 5) // health
2017 {
2018 cell->stat_width = 1; 2112 cell->stat_width = 1;
2019 cell->stat_hp = *data++; 2113 cell->stat_hp = *data++;
2020 }
2021 else if (cmd == 6) // monster width
2022 cell->stat_width = *data++ + 1;
2023 else if (cmd == 0x47)
2024 {
2025 if (*data == 1) cell->player = data [1];
2026 else if (*data == 2) cell->player = data [2] + (data [1] << 8);
2027 else if (*data == 3) cell->player = data [3] + (data [2] << 8) + (data [1] << 16);
2028 else if (*data == 4) cell->player = data [4] + (data [3] << 8) + (data [2] << 16) + (data [1] << 24);
2029
2030 data += *data + 1;
2031 }
2032 else if (cmd == 8) // cell flags
2033 cell->flags = *data++;
2034 else if (ext & 0x40) // unknown, multibyte => skip
2035 data += *data + 1;
2036 else
2037 data++;
2038 } 2114 }
2039 while (ext & 0x80); 2115 else if (cmd == 6) // monster width
2116 cell->stat_width = *data++ + 1;
2117 else if (cmd == 0x47)
2118 {
2119 if (*data == 1) cell->player = data [1];
2120 else if (*data == 2) cell->player = data [2] + (data [1] << 8);
2121 else if (*data == 3) cell->player = data [3] + (data [2] << 8) + (data [1] << 16);
2122 else if (*data == 4) cell->player = data [4] + (data [3] << 8) + (data [2] << 16) + (data [1] << 24);
2123
2124 data += *data + 1;
2125 }
2126 else if (cmd == 8) // cell flags
2127 cell->flags = *data++;
2128 else if (ext & 0x40) // unknown, multibyte => skip
2129 data += *data + 1;
2130 else
2131 data++;
2040 } 2132 }
2041 else 2133 while (ext & 0x80);
2042 cell->darkness = *data++ + 1;
2043 } 2134 }
2044 2135
2045 for (z = 0; z <= 2; ++z) 2136 for (z = 0; z <= 2; ++z)
2046 if (flags & (4 >> z)) 2137 if (flags & (4 >> z))
2047 { 2138 {
2095 ? self->row + y 2186 ? self->row + y
2096 : 0; 2187 : 0;
2097 2188
2098 for (x = x0; x < x1; x++) 2189 for (x = x0; x < x1; x++)
2099 { 2190 {
2100 int r = 32, g = 32, b = 32, a = 192; 2191 unsigned int r = 32, g = 32, b = 32, a = 192;
2101 2192
2102 if (row && row->c0 <= x && x < row->c1) 2193 if (row && row->c0 <= x && x < row->c1)
2103 { 2194 {
2104 mapcell *cell = row->col + (x - row->c0); 2195 mapcell *cell = row->col + (x - row->c0);
2105 2196
2107 { 2198 {
2108 maptex tex = self->tex [cell->tile [z]]; 2199 maptex tex = self->tex [cell->tile [z]];
2109 int a0 = 255 - tex.a; 2200 int a0 = 255 - tex.a;
2110 int a1 = tex.a; 2201 int a1 = tex.a;
2111 2202
2112 r = (r * a0 + tex.r * a1) / 255; 2203 r = div255 (r * a0 + tex.r * a1);
2113 g = (g * a0 + tex.g * a1) / 255; 2204 g = div255 (g * a0 + tex.g * a1);
2114 b = (b * a0 + tex.b * a1) / 255; 2205 b = div255 (b * a0 + tex.b * a1);
2115 a = (a * a0 + tex.a * a1) / 255; 2206 a = div255 (a * a0 + tex.a * a1);
2116 } 2207 }
2117 } 2208 }
2118 2209
2119 *map++ = (r ) 2210 *map++ = (r )
2120 | (g << 8) 2211 | (g << 8)
2121 | (b << 16) 2212 | (b << 16)
2122 | (a << 24); 2213 | (a << 24);
2123 } 2214 }
2124 } 2215 }
2125 2216
2126 RETVAL = map_sv; 2217 RETVAL = map_sv;
2127} 2218}
2128 OUTPUT: 2219 OUTPUT:
2129 RETVAL 2220 RETVAL
2130 2221
2131void 2222void
2132draw (DC::Map self, int mx, int my, int sw, int sh, int T, U32 player = 0xffffffff, int sdx = 0, int sdy = 0) 2223draw (DC::Map self, int mx, int my, int sw, int sh, int Tw, int Th, U32 player = 0xffffffff, int sdx = 0, int sdy = 0)
2133 CODE: 2224 CODE:
2134{ 2225{
2135 int x, y, z; 2226 int x, y, z;
2136 2227
2137 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
2138 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level 2228 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level
2139 static uint8_t smooth_max[256][256]; // egad, fast and wasteful on memory (64k) 2229 static uint8_t smooth_max[256][256]; // egad, fast and wasteful on memory (64k)
2140 smooth_key skey; 2230 smooth_key skey;
2141 int pl_x, pl_y; 2231 int pl_x, pl_y;
2142 maptex pl_tex; 2232 maptex pl_tex;
2143 rc_t *rc = rc_alloc (); 2233 rc_t *rc = rc_alloc ();
2144 rc_t *rc_ov = rc_alloc (); 2234 rc_t *rc_ov = rc_alloc ();
2145 rc_key_t key; 2235 rc_key_t key;
2146 rc_array_t *arr, *arr_hidden; 2236 rc_array_t *arr;
2147 2237
2148 pl_tex.name = 0; 2238 pl_tex.name = 0;
2149 2239
2150 // that's current max. sorry. 2240 // that's current max. sorry.
2151 if (sw > 255) sw = 255; 2241 if (sw > 255) sw = 255;
2189 2279
2190 glEnable (GL_BLEND); 2280 glEnable (GL_BLEND);
2191 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2281 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2192 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 2282 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
2193 2283
2194 key.texname = self->tex [TEXID_HIDDEN].name;
2195 arr_hidden = rc_array (rc_ov, &key);
2196
2197 for (z = 0; z <= 2; z++) 2284 for (z = 0; z <= 2; z++)
2198 { 2285 {
2286 smooth_hash smooth;
2199 memset (smooth_level, 0, sizeof (smooth_level)); 2287 memset (smooth_level, 0, sizeof (smooth_level));
2200 key.texname = -1; 2288 key.texname = -1;
2201 2289
2202 for (y = 0; y < sh; y++) 2290 for (y = 0; y < sh; y++)
2203 if (0 <= y + my && y + my < self->rows) 2291 if (0 <= y + my && y + my < self->rows)
2224 2312
2225 key.texname = tex.name; 2313 key.texname = tex.name;
2226 arr = rc_array (rc, &key); 2314 arr = rc_array (rc, &key);
2227 } 2315 }
2228 2316
2229 px = (x + 1) * T - tex.w; 2317 px = (x + 1) * Th - tex.w;
2230 py = (y + 1) * T - tex.h; 2318 py = (y + 1) * Tw - tex.h;
2231 2319
2232 if (expect_false (cell->player == player) && expect_false (z == 2)) 2320 if (expect_false (cell->player == player) && expect_false (z == 2))
2233 { 2321 {
2234 pl_x = px; 2322 pl_x = px;
2235 pl_y = py; 2323 pl_y = py;
2264 2352
2265 // corners: 1 ┛· 2 ·┗ 4 ·· 8 ·· 2353 // corners: 1 ┛· 2 ·┗ 4 ·· 8 ··
2266 // ·· ·· ·┏ ┓· 2354 // ·· ·· ·┏ ┓·
2267 2355
2268 // full tile 2356 // full tile
2269 skey.x = x + 1; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x1000); 2357 skey.x = x + 1; skey.y = y + 1; smooth_or_bits (smooth, skey, 0x1000);
2270 2358
2271 // borders 2359 // borders
2272 skey.x = x + 2; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x0091); 2360 skey.x = x + 2; skey.y = y + 1; smooth_or_bits (smooth, skey, 0x0091);
2273 skey.x = x + 1; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0032); 2361 skey.x = x + 1; skey.y = y + 2; smooth_or_bits (smooth, skey, 0x0032);
2274 skey.x = x ; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x0064); 2362 skey.x = x ; skey.y = y + 1; smooth_or_bits (smooth, skey, 0x0064);
2275 skey.x = x + 1; skey.y = y ; smooth_or_bits (smooth, &skey, 0x00c8); 2363 skey.x = x + 1; skey.y = y ; smooth_or_bits (smooth, skey, 0x00c8);
2276 2364
2277 // corners 2365 // corners
2278 skey.x = x + 2; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0100); 2366 skey.x = x + 2; skey.y = y + 2; smooth_or_bits (smooth, skey, 0x0100);
2279 skey.x = x ; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0200); 2367 skey.x = x ; skey.y = y + 2; smooth_or_bits (smooth, skey, 0x0200);
2280 skey.x = x ; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0400); 2368 skey.x = x ; skey.y = y ; smooth_or_bits (smooth, skey, 0x0400);
2281 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0800); 2369 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, skey, 0x0800);
2282 } 2370 }
2283 } 2371 }
2284 2372
2285 if (expect_false (z == 2) && expect_false (cell->flags)) 2373 if (expect_false (z == 2) && expect_false (cell->flags))
2286 { 2374 {
2288 if (cell->flags & 1) 2376 if (cell->flags & 1)
2289 { 2377 {
2290 rc_key_t key_ov = key; 2378 rc_key_t key_ov = key;
2291 maptex tex = self->tex [TEXID_SPEECH]; 2379 maptex tex = self->tex [TEXID_SPEECH];
2292 rc_array_t *arr; 2380 rc_array_t *arr;
2293 int px = x * T + T * 2 / 32; 2381 int px = x * Tw + Tw * 2 / 32;
2294 int py = y * T - T * 6 / 32; 2382 int py = y * Th - Th * 6 / 32;
2295 2383
2296 key_ov.texname = tex.name; 2384 key_ov.texname = tex.name;
2297 arr = rc_array (rc_ov, &key_ov); 2385 arr = rc_array (rc_ov, &key_ov);
2298 2386
2299 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2387 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
2300 rc_t2f_v3f (arr, 0 , tex.t, px , py + T, 0); 2388 rc_t2f_v3f (arr, 0 , tex.t, px , py + Th, 0);
2301 rc_t2f_v3f (arr, tex.s, tex.t, px + T, py + T, 0); 2389 rc_t2f_v3f (arr, tex.s, tex.t, px + Tw, py + Th, 0);
2302 rc_t2f_v3f (arr, tex.s, 0 , px + T, py , 0); 2390 rc_t2f_v3f (arr, tex.s, 0 , px + Tw, py , 0);
2303 } 2391 }
2304 } 2392 }
2305 } 2393 }
2306 } 2394 }
2307 2395
2323 if (smask & (((uint32_t)1) << b)) 2411 if (smask & (((uint32_t)1) << b))
2324 { 2412 {
2325 int level = (w << 5) | b; 2413 int level = (w << 5) | b;
2326 HE *he; 2414 HE *he;
2327 2415
2328 hv_iterinit (smooth); 2416 for (auto &&it = smooth.begin (); it != smooth.end (); ++it)
2329 while ((he = hv_iternext (smooth)))
2330 { 2417 {
2331 smooth_key *skey = (smooth_key *)HeKEY (he); 2418 smooth_key &skey = it->first;
2332 IV bits = SvIVX (HeVAL (he)); 2419 IV bits = it->second;
2333 2420
2334 if (!(bits & 0x1000) 2421 if (!(bits & 0x1000)
2335 && skey->level == level 2422 && skey.level == level
2336 && level > smooth_max [skey->x][skey->y]) 2423 && level > smooth_max [skey.x][skey.y])
2337 { 2424 {
2338 maptex tex = self->tex [skey->tile]; 2425 maptex tex = self->tex [skey.tile];
2339 int px = (((int)skey->x) - 1) * T; 2426 int px = (((int)skey.x) - 1) * Tw;
2340 int py = (((int)skey->y) - 1) * T; 2427 int py = (((int)skey.y) - 1) * Th;
2341 int border = bits & 15; 2428 int border = bits & 15;
2342 int corner = (bits >> 8) & ~(bits >> 4) & 15; 2429 int corner = (bits >> 8) & ~(bits >> 4) & 15;
2343 float dx = tex.s * .0625f; // 16 images/row 2430 float dx = tex.s * .0625f; // 16 images/row
2344 float dy = tex.t * .5f ; // 2 images/column 2431 float dy = tex.t * .5f ; // 2 images/column
2345 2432
2347 { 2434 {
2348 // this time avoiding texture state changes 2435 // this time avoiding texture state changes
2349 // save gobs of state changes. 2436 // save gobs of state changes.
2350 if (key.texname != tex.name) 2437 if (key.texname != tex.name)
2351 { 2438 {
2352 self->tex [skey->tile].unused = 0; 2439 self->tex [skey.tile].unused = 0;
2353 2440
2354 glEnd (); 2441 glEnd ();
2355 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name); 2442 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name);
2356 glBegin (GL_QUADS); 2443 glBegin (GL_QUADS);
2357 } 2444 }
2358 2445
2359 if (border) 2446 if (border)
2360 { 2447 {
2361 float ox = border * dx; 2448 float ox = border * dx;
2362 2449
2363 glTexCoord2f (ox , 0.f ); glVertex2i (px , py ); 2450 glTexCoord2f (ox , 0.f ); glVertex2i (px , py );
2364 glTexCoord2f (ox , dy ); glVertex2i (px , py + T); 2451 glTexCoord2f (ox , dy ); glVertex2i (px , py + Th);
2365 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py + T); 2452 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py + Th);
2366 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + T, py ); 2453 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + Tw, py );
2367 } 2454 }
2368 2455
2369 if (corner) 2456 if (corner)
2370 { 2457 {
2371 float ox = corner * dx; 2458 float ox = corner * dx;
2372 2459
2373 glTexCoord2f (ox , dy ); glVertex2i (px , py ); 2460 glTexCoord2f (ox , dy ); glVertex2i (px , py );
2374 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + T); 2461 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + Th);
2375 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + T, py + T); 2462 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + Tw, py + Th);
2376 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py ); 2463 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py );
2377 } 2464 }
2378 } 2465 }
2379 } 2466 }
2380 } 2467 }
2381 } 2468 }
2383 2470
2384 glEnd (); 2471 glEnd ();
2385 glDisable (GL_TEXTURE_2D); 2472 glDisable (GL_TEXTURE_2D);
2386 key.texname = -1; 2473 key.texname = -1;
2387 } 2474 }
2388
2389 hv_clear (smooth);
2390 } 2475 }
2391 2476
2392 if (pl_tex.name) 2477 if (pl_tex.name)
2393 { 2478 {
2394 maptex tex = pl_tex; 2479 maptex tex = pl_tex;
2422 for (x = 0; x < sw; x++) 2507 for (x = 0; x < sw; x++)
2423 if (row->c0 <= x + mx && x + mx < row->c1) 2508 if (row->c0 <= x + mx && x + mx < row->c1)
2424 { 2509 {
2425 mapcell *cell = row->col + (x + mx - row->c0); 2510 mapcell *cell = row->col + (x + mx - row->c0);
2426 2511
2427 int px = x * T; 2512 int px = x * Tw;
2428 int py = y * T; 2513 int py = y * Th;
2429 2514
2430 if (expect_false (cell->player == player)) 2515 if (expect_false (cell->player == player))
2431 { 2516 {
2432 px += sdx; 2517 px += sdx;
2433 py += sdy; 2518 py += sdy;
2434 } 2519 }
2435 2520
2436 if (cell->stat_hp) 2521 if (cell->stat_hp)
2437 { 2522 {
2438 int width = cell->stat_width * T; 2523 int width = cell->stat_width * Tw;
2439 int thick = (sh * T / 32 + 27) / 28 + 1 + cell->stat_width; 2524 int thick = (sh * Th / 32 + 27) / 28 + 1 + cell->stat_width;
2440 2525
2441 glColor3ub (0, 0, 0); 2526 glColor3ub (0, 0, 0);
2442 glRectf (px + 1, py - thick - 2, 2527 glRectf (px + 1, py - thick - 2,
2443 px + width - 1, py); 2528 px + width - 1, py);
2444 2529
2524 int x, y; 2609 int x, y;
2525 int sw1 = sw + 2; 2610 int sw1 = sw + 2;
2526 int sh1 = sh + 2; 2611 int sh1 = sh + 2;
2527 int sh3 = sh * 3; 2612 int sh3 = sh * 3;
2528 int sw3 = sw * 3; 2613 int sw3 = sw * 3;
2529 uint8_t *darkness1 = (uint8_t *)malloc (sw1 * sh1);
2530 SV *darkness3_sv = sv_2mortal (newSV (sw3 * sh3)); 2614 SV *darkness3_sv = sv_2mortal (newSV (sw3 * sh3));
2531 uint8_t *darkness3 = (uint8_t *)SvPVX (darkness3_sv); 2615 uint8_t *darkness3 = (uint8_t *)SvPVX (darkness3_sv);
2616 uint8_t *darkness1 = (uint8_t *)malloc (sw1 * sh1);
2617 memset (darkness1, 0, sw1*sh1);
2532 2618
2533 SvPOK_only (darkness3_sv); 2619 SvPOK_only (darkness3_sv);
2534 SvCUR_set (darkness3_sv, sw3 * sh3); 2620 SvCUR_set (darkness3_sv, sw3 * sh3);
2535 2621
2536 mx += self->x - 1; 2622 mx += self->x - 1;
2662 else 2748 else
2663 *data++ = 0; 2749 *data++ = 0;
2664 } 2750 }
2665 } 2751 }
2666 2752
2667 /* if size is w*h + 5 then no data has been found */ 2753 /* if size is w*h + 5 then no data has been found */
2668 if (data - (uint8_t *)SvPVX (data_sv) != w * h + 5) 2754 if (data - (uint8_t *)SvPVX (data_sv) != w * h + 5)
2669 { 2755 {
2670 SvPOK_only (data_sv); 2756 SvPOK_only (data_sv);
2671 SvCUR_set (data_sv, data - (uint8_t *)SvPVX (data_sv)); 2757 SvCUR_set (data_sv, data - (uint8_t *)SvPVX (data_sv));
2672 } 2758 }
2673 2759
2674 RETVAL = data_sv; 2760 RETVAL = data_sv;
2675} 2761}
2676 OUTPUT: 2762 OUTPUT:
2677 RETVAL 2763 RETVAL
2678 2764
2679void 2765void
2686 STRLEN len; 2772 STRLEN len;
2687 uint8_t *data, *end; 2773 uint8_t *data, *end;
2688 2774
2689 len = SvLEN (data_sv); 2775 len = SvLEN (data_sv);
2690 SvGROW (data_sv, len + 8); // reserve at least 7+ bytes more 2776 SvGROW (data_sv, len + 8); // reserve at least 7+ bytes more
2691 data = SvPVbyte_nolen (data_sv); 2777 data = (uint8_t *)SvPVbyte_nolen (data_sv);
2692 end = data + len + 8; 2778 end = data + len + 8;
2693 2779
2694 if (len < 5) 2780 if (len < 5)
2695 XSRETURN_EMPTY; 2781 XSRETURN_EMPTY;
2696 2782
2757} 2843}
2758 2844
2759MODULE = Deliantra::Client PACKAGE = DC::RW 2845MODULE = Deliantra::Client PACKAGE = DC::RW
2760 2846
2761DC::RW 2847DC::RW
2762new (SV *class, SV *data_sv) 2848new (SV *klass, SV *data_sv)
2763 CODE: 2849 CODE:
2764{ 2850{
2765 STRLEN datalen; 2851 STRLEN datalen;
2766 char *data = SvPVbyte (data_sv, datalen); 2852 char *data = SvPVbyte (data_sv, datalen);
2767 2853
2769} 2855}
2770 OUTPUT: 2856 OUTPUT:
2771 RETVAL 2857 RETVAL
2772 2858
2773DC::RW 2859DC::RW
2774new_from_file (SV *class, const char *path, const char *mode = "rb") 2860new_from_file (SV *klass, const char *path, const char *mode = "rb")
2775 CODE: 2861 CODE:
2776 RETVAL = SDL_RWFromFile (path, mode); 2862 RETVAL = SDL_RWFromFile (path, mode);
2777 OUTPUT: 2863 OUTPUT:
2778 RETVAL 2864 RETVAL
2779 2865
2797 if (RETVAL < 0) 2883 if (RETVAL < 0)
2798 { 2884 {
2799 RETVAL = Mix_GroupOldest (-1); 2885 RETVAL = Mix_GroupOldest (-1);
2800 2886
2801 if (RETVAL < 0) 2887 if (RETVAL < 0)
2888 {
2889 // happens sometimes, maybe it just stopped playing(?)
2890 RETVAL = Mix_GroupAvailable (-1);
2891
2892 if (RETVAL < 0)
2802 XSRETURN_UNDEF; 2893 XSRETURN_UNDEF;
2803 2894 }
2895 else
2804 Mix_HaltChannel (RETVAL); 2896 Mix_HaltChannel (RETVAL);
2805 } 2897 }
2806 2898
2807 Mix_UnregisterAllEffects (RETVAL); 2899 Mix_UnregisterAllEffects (RETVAL);
2808 Mix_Volume (RETVAL, 128); 2900 Mix_Volume (RETVAL, 128);
2809} 2901}
2869 2961
2870MODULE = Deliantra::Client PACKAGE = DC::MixChunk 2962MODULE = Deliantra::Client PACKAGE = DC::MixChunk
2871 2963
2872PROTOTYPES: DISABLE 2964PROTOTYPES: DISABLE
2873 2965
2966void
2967decoders ()
2968 PPCODE:
2969#if SDL_MIXER_MAJOR_VERSION > 1 || SDL_MIXER_MINOR_VERSION > 2 || SDL_MIXER_PATCHLEVEL >= 10
2970 int i, num = Mix_GetNumChunkDecoders ();
2971 EXTEND (SP, num);
2972 for (i = 0; i < num; ++i)
2973 PUSHs (sv_2mortal (newSVpv (Mix_GetChunkDecoder (i), 0)));
2974#else
2975 XPUSHs (sv_2mortal (newSVpv ("(sdl mixer too old)", 0)));
2976#endif
2977
2874DC::MixChunk 2978DC::MixChunk
2875new (SV *class, DC::RW rwops) 2979new (SV *klass, DC::RW rwops)
2876 CODE: 2980 CODE:
2877 RETVAL = Mix_LoadWAV_RW (rwops, 1); 2981 RETVAL = Mix_LoadWAV_RW (rwops, 1);
2878 OUTPUT: 2982 OUTPUT:
2879 RETVAL 2983 RETVAL
2880 2984
2910 OUTPUT: 3014 OUTPUT:
2911 RETVAL 3015 RETVAL
2912 3016
2913MODULE = Deliantra::Client PACKAGE = DC::MixMusic 3017MODULE = Deliantra::Client PACKAGE = DC::MixMusic
2914 3018
3019void
3020decoders ()
3021 PPCODE:
3022#if SDL_MIXER_MAJOR_VERSION > 1 || SDL_MIXER_MINOR_VERSION > 2 || SDL_MIXER_PATCHLEVEL >= 10
3023 int i, num = Mix_GetNumMusicDecoders ();
3024 EXTEND (SP, num);
3025 for (i = 0; i < num; ++i)
3026 PUSHs (sv_2mortal (newSVpv (Mix_GetMusicDecoder (i), 0)));
3027#else
3028 XPUSHs (sv_2mortal (newSVpv ("(sdl mixer too old)", 0)));
3029#endif
3030
2915int 3031int
2916volume (int volume = -1) 3032volume (int volume = -1)
2917 PROTOTYPE: ;$ 3033 PROTOTYPE: ;$
2918 CODE: 3034 CODE:
2919 if (items > 0) 3035 if (items > 0)
2930void 3046void
2931halt () 3047halt ()
2932 CODE: 3048 CODE:
2933 Mix_HaltMusic (); 3049 Mix_HaltMusic ();
2934 3050
3051int
3052playing ()
3053 CODE:
3054 RETVAL = Mix_PlayingMusic ();
3055 OUTPUT:
3056 RETVAL
3057
2935DC::MixMusic 3058DC::MixMusic
2936new (SV *class, DC::RW rwops) 3059new (SV *klass, DC::RW rwops)
2937 CODE: 3060 CODE:
2938 RETVAL = Mix_LoadMUS_RW (rwops); 3061 RETVAL = Mix_LoadMUS_RW (rwops);
2939 OUTPUT: 3062 OUTPUT:
2940 RETVAL 3063 RETVAL
2941 3064
3078 const_iv (GL_FUNC_SUBTRACT), 3201 const_iv (GL_FUNC_SUBTRACT),
3079 const_iv (GL_FUNC_REVERSE_SUBTRACT), 3202 const_iv (GL_FUNC_REVERSE_SUBTRACT),
3080# undef const_iv 3203# undef const_iv
3081 }; 3204 };
3082 3205
3083 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 3206 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
3084 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 3207 newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
3085 3208
3086 texture_av = newAV (); 3209 texture_av = newAV ();
3087 AvREAL_off (texture_av); 3210 AvREAL_off (texture_av);
3088} 3211}
3089 3212
3094 gl.BlendFuncSeparateEXT = 0; 3217 gl.BlendFuncSeparateEXT = 0;
3095 3218
3096void 3219void
3097apple_nvidia_bug (int enable) 3220apple_nvidia_bug (int enable)
3098 3221
3099char * 3222const char *
3100gl_vendor () 3223gl_vendor ()
3101 CODE: 3224 CODE:
3102 RETVAL = (char *)glGetString (GL_VENDOR); 3225 RETVAL = (const char *)glGetString (GL_VENDOR);
3103 OUTPUT: 3226 OUTPUT:
3104 RETVAL 3227 RETVAL
3105 3228
3106char * 3229const char *
3107gl_version () 3230gl_version ()
3108 CODE: 3231 CODE:
3109 RETVAL = (char *)glGetString (GL_VERSION); 3232 RETVAL = (const char *)glGetString (GL_VERSION);
3110 OUTPUT: 3233 OUTPUT:
3111 RETVAL 3234 RETVAL
3112 3235
3113char * 3236const char *
3114gl_extensions () 3237gl_extensions ()
3115 CODE: 3238 CODE:
3116 RETVAL = (char *)glGetString (GL_EXTENSIONS); 3239 RETVAL = (const char *)glGetString (GL_EXTENSIONS);
3117 OUTPUT: 3240 OUTPUT:
3118 RETVAL 3241 RETVAL
3119 3242
3120const char *glGetString (GLenum pname) 3243const char *glGetString (GLenum pname)
3244 CODE:
3245 RETVAL = (const char *)glGetString (pname);
3246 OUTPUT:
3247 RETVAL
3121 3248
3122GLint glGetInteger (GLenum pname) 3249GLint glGetInteger (GLenum pname)
3123 CODE: 3250 CODE:
3124 glGetIntegerv (pname, &RETVAL); 3251 glGetIntegerv (pname, &RETVAL);
3125 OUTPUT: 3252 OUTPUT:
3132 RETVAL 3259 RETVAL
3133 3260
3134int glGetError () 3261int glGetError ()
3135 3262
3136void glFinish () 3263void glFinish ()
3264
3265void glFlush ()
3137 3266
3138void glClear (int mask) 3267void glClear (int mask)
3139 3268
3140void glClearColor (float r, float g, float b, float a = 1.0) 3269void glClearColor (float r, float g, float b, float a = 1.0)
3141 PROTOTYPE: @ 3270 PROTOTYPE: @
3326 3455
3327void 3456void
3328find_widget (SV *self, NV x, NV y) 3457find_widget (SV *self, NV x, NV y)
3329 PPCODE: 3458 PPCODE:
3330{ 3459{
3331 if (within_widget (self, x, y)) 3460 if (within_widget (self, x, y))
3332 XPUSHs (self); 3461 XPUSHs (self);
3333} 3462}
3334 3463
3335BOOT: 3464BOOT:
3336{ 3465{
3344 3473
3345void 3474void
3346draw (SV *self) 3475draw (SV *self)
3347 CODE: 3476 CODE:
3348{ 3477{
3349 HV *hv; 3478 HV *hv;
3350 SV **svp; 3479 SV **svp;
3351 NV x, y, w, h; 3480 NV x, y, w, h;
3352 SV *draw_x_sv = GvSV (draw_x_gv); 3481 SV *draw_x_sv = GvSV (draw_x_gv);
3353 SV *draw_y_sv = GvSV (draw_y_gv); 3482 SV *draw_y_sv = GvSV (draw_y_gv);
3354 SV *draw_w_sv = GvSV (draw_w_gv); 3483 SV *draw_w_sv = GvSV (draw_w_gv);
3355 SV *draw_h_sv = GvSV (draw_h_gv); 3484 SV *draw_h_sv = GvSV (draw_h_gv);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines