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.253 by root, Fri Dec 28 20:59:14 2007 UTC vs.
Revision 1.294 by root, Sat Dec 19 05:06:56 2009 UTC

39#include <SDL_endian.h> 39#include <SDL_endian.h>
40#include <SDL_image.h> 40#include <SDL_image.h>
41#include <SDL_mixer.h> 41#include <SDL_mixer.h>
42#include <SDL_opengl.h> 42#include <SDL_opengl.h>
43 43
44/* work around os x broken headers */
45#ifdef __MACOSX__
46typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
47#endif
48
44#define PANGO_ENABLE_BACKEND 49#define PANGO_ENABLE_BACKEND
45#define G_DISABLE_CAST_CHECKS 50#define G_DISABLE_CAST_CHECKS
46 51
47#include <glib/gmacros.h> 52#include <glib/gmacros.h>
48 53
49#include <pango/pango.h> 54#include <pango/pango.h>
50 55
51#if !(defined (PANGO_VERSION_CHECK) && PANGO_VERSION_CHECK (1, 15, 2)) 56#ifndef PANGO_VERSION_CHECK
57# define PANGO_VERSION_CHECK(a,b,c) 0
58#endif
59
60#if !PANGO_VERSION_CHECK (1, 15, 2)
52# define pango_layout_get_line_readonly pango_layout_get_line_readonly 61# define pango_layout_get_line_readonly pango_layout_get_line
53# define pango_layout_get_lines_readonly pango_layout_get_lines_readonly 62# define pango_layout_get_lines_readonly pango_layout_get_lines
54# define pango_layout_iter_get_line_readonly pango_layout_iter_get_line_readonly 63# define pango_layout_iter_get_line_readonly pango_layout_iter_get_line
55# define pango_layout_iter_get_run_readonly pango_layout_iter_get_run_readonly 64# define pango_layout_iter_get_run_readonly pango_layout_iter_get_run
56#endif 65#endif
57 66
58#ifndef _WIN32 67#ifndef _WIN32
59# include <sys/types.h> 68# include <sys/types.h>
60# include <sys/socket.h> 69# include <sys/socket.h>
61# include <netinet/in.h> 70# include <netinet/in.h>
62# include <netinet/tcp.h> 71# include <netinet/tcp.h>
63# include <inttypes.h> 72# include <inttypes.h>
64#endif 73#endif
65 74
75#if __GNUC__ >= 4
76# define expect(expr,value) __builtin_expect ((expr),(value))
77#else
78# define expect(expr,value) (expr)
79#endif
80
81#define expect_false(expr) expect ((expr) != 0, 0)
82#define expect_true(expr) expect ((expr) != 0, 1)
83
66#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, object replacement character */ 84#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, object replacement character */
67 85
68#define FOW_DARKNESS 32 86#define FOW_DARKNESS 64
87#define DARKNESS_ADJUST(n) ((29 * (int)(n)) >> 5) /* times 0.9 */
69 88
70#define MAP_EXTEND_X 32 89#define MAP_EXTEND_X 32
71#define MAP_EXTEND_Y 512 90#define MAP_EXTEND_Y 512
72 91
73#define MIN_FONT_HEIGHT 10 92#define MIN_FONT_HEIGHT 10
74 93
75/* mask out modifiers we are not interested in */ 94/* mask out modifiers we are not interested in */
76#define MOD_MASK (KMOD_CTRL | KMOD_SHIFT | KMOD_ALT | KMOD_META) 95#define MOD_MASK (KMOD_CTRL | KMOD_SHIFT | KMOD_ALT | KMOD_META)
77 96
78#if 0 97#define KMOD_LRAM 0x10000 // our extension
79# define PARACHUTE SDL_INIT_NOPARACHUTE 98
80#else 99#define TEXID_SPEECH 1
81# define PARACHUTE 0 100#define TEXID_NOFACE 2
82#endif 101#define TEXID_HIDDEN 3
83 102
84static AV *texture_av; 103static AV *texture_av;
85 104
86static struct 105static struct
87{ 106{
181 200
182static void 201static void
183layout_update_font (DC__Layout self) 202layout_update_font (DC__Layout self)
184{ 203{
185 /* use a random scale factor to account for unknown descenders, 0.8 works 204 /* use a random scale factor to account for unknown descenders, 0.8 works
186 * reasonably well with bitstream vera 205 * reasonably well with dejavu/bistream fonts
187 */ 206 */
188 PangoFontDescription *font = self->font ? self->font : default_font; 207 PangoFontDescription *font = self->font ? self->font : default_font;
189 208
190 pango_font_description_set_absolute_size (font, 209 pango_font_description_set_absolute_size (font,
191 MAX (MIN_FONT_HEIGHT, self->base_height) * (PANGO_SCALE * 8 / 10)); 210 MAX (MIN_FONT_HEIGHT, self->base_height) * (PANGO_SCALE * 8 / 10));
219 int w, h; 238 int w, h;
220 float s, t; 239 float s, t;
221 uint8_t r, g, b, a; 240 uint8_t r, g, b, a;
222 tileid smoothtile; 241 tileid smoothtile;
223 uint8_t smoothlevel; 242 uint8_t smoothlevel;
243 uint8_t unused; /* set to zero on use */
224} maptex; 244} maptex;
225 245
226typedef struct { 246typedef struct {
227 uint32_t player; 247 uint32_t player;
228 tileid tile[3]; 248 tileid tile[3];
360 self->oy = 0; 380 self->oy = 0;
361 self->row = 0; 381 self->row = 0;
362 self->rows = 0; 382 self->rows = 0;
363} 383}
364 384
385#define CELL_CLEAR(cell) \
386 do { \
387 if ((cell)->player) \
388 (cell)->tile [2] = 0; \
389 (cell)->darkness = 0; \
390 (cell)->stat_hp = 0; \
391 (cell)->flags = 0; \
392 (cell)->player = 0; \
393 } while (0)
394
365static void 395static void
366map_blank (DC__Map self, int x0, int y0, int w, int h) 396map_blank (DC__Map self, int x0, int y0, int w, int h)
367{ 397{
368 int x, y; 398 int x, y;
369 maprow *row; 399 maprow *row;
383 if (x >= row->c1) 413 if (x >= row->c1)
384 break; 414 break;
385 415
386 cell = row->col + x - row->c0; 416 cell = row->col + x - row->c0;
387 417
388 cell->darkness = 0; 418 CELL_CLEAR (cell);
389 cell->stat_hp = 0;
390 cell->flags = 0;
391 cell->player = 0;
392 } 419 }
393 } 420 }
394} 421}
395 422
396typedef struct { 423typedef struct {
507 if (!svp || !SvTRUE (*svp)) 534 if (!svp || !SvTRUE (*svp))
508 return 0; 535 return 0;
509 536
510 return 1; 537 return 1;
511} 538}
539
540/******************************************************************************/
541
542/* process keyboard modifiers */
543static int
544mod_munge (int mod)
545{
546 mod &= MOD_MASK;
547
548 if (mod & (KMOD_META | KMOD_ALT))
549 mod |= KMOD_LRAM;
550
551 return mod;
552}
553
554static void
555deliantra_main ()
556{
557 char *argv[] = { 0 };
558 call_argv ("::main", G_DISCARD | G_VOID, argv);
559}
560
561#ifdef __MACOSX__
562 /* to due surprising braindamage on the side of SDL design, we
563 * do some mind-boggling hack here: SDL requires a custom main()
564 * on OS X, so... we provide one and call the original main(), which,
565 * due to share dlibrary magic, calls -lSDLmain's main, not perl's main,
566 * and which calls our main (== SDL_main) back.
567 */
568 extern C_LINKAGE int
569 main (int argc, char *argv[])
570 {
571 deliantra_main ();
572 }
573
574 #undef main
575
576 extern C_LINKAGE int main (int argc, char *argv[]);
577
578 static void
579 SDL_braino (void)
580 {
581 char *argv[] = { "deliantra client", 0 };
582 (main) (1, argv);
583 }
584#else
585 static void
586 SDL_braino (void)
587 {
588 deliantra_main ();
589 }
590#endif
512 591
513MODULE = Deliantra::Client PACKAGE = DC 592MODULE = Deliantra::Client PACKAGE = DC
514 593
515PROTOTYPES: ENABLE 594PROTOTYPES: ENABLE
516 595
545 const_iv (SDL_USEREVENT), 624 const_iv (SDL_USEREVENT),
546 625
547 const_iv (SDL_APPINPUTFOCUS), 626 const_iv (SDL_APPINPUTFOCUS),
548 const_iv (SDL_APPMOUSEFOCUS), 627 const_iv (SDL_APPMOUSEFOCUS),
549 const_iv (SDL_APPACTIVE), 628 const_iv (SDL_APPACTIVE),
629
630
631 const_iv (SDLK_UNKNOWN),
632 const_iv (SDLK_FIRST),
633 const_iv (SDLK_BACKSPACE),
634 const_iv (SDLK_TAB),
635 const_iv (SDLK_CLEAR),
636 const_iv (SDLK_RETURN),
637 const_iv (SDLK_PAUSE),
638 const_iv (SDLK_ESCAPE),
639 const_iv (SDLK_SPACE),
640 const_iv (SDLK_EXCLAIM),
641 const_iv (SDLK_QUOTEDBL),
642 const_iv (SDLK_HASH),
643 const_iv (SDLK_DOLLAR),
644 const_iv (SDLK_AMPERSAND),
645 const_iv (SDLK_QUOTE),
646 const_iv (SDLK_LEFTPAREN),
647 const_iv (SDLK_RIGHTPAREN),
648 const_iv (SDLK_ASTERISK),
649 const_iv (SDLK_PLUS),
650 const_iv (SDLK_COMMA),
651 const_iv (SDLK_MINUS),
652 const_iv (SDLK_PERIOD),
653 const_iv (SDLK_SLASH),
654 const_iv (SDLK_0),
655 const_iv (SDLK_1),
656 const_iv (SDLK_2),
657 const_iv (SDLK_3),
658 const_iv (SDLK_4),
659 const_iv (SDLK_5),
660 const_iv (SDLK_6),
661 const_iv (SDLK_7),
662 const_iv (SDLK_8),
663 const_iv (SDLK_9),
664 const_iv (SDLK_COLON),
665 const_iv (SDLK_SEMICOLON),
666 const_iv (SDLK_LESS),
667 const_iv (SDLK_EQUALS),
668 const_iv (SDLK_GREATER),
669 const_iv (SDLK_QUESTION),
670 const_iv (SDLK_AT),
671
672 const_iv (SDLK_LEFTBRACKET),
673 const_iv (SDLK_BACKSLASH),
674 const_iv (SDLK_RIGHTBRACKET),
675 const_iv (SDLK_CARET),
676 const_iv (SDLK_UNDERSCORE),
677 const_iv (SDLK_BACKQUOTE),
678 const_iv (SDLK_DELETE),
550 679
551 const_iv (SDLK_FIRST), 680 const_iv (SDLK_FIRST),
552 const_iv (SDLK_LAST), 681 const_iv (SDLK_LAST),
553 const_iv (SDLK_KP0), 682 const_iv (SDLK_KP0),
554 const_iv (SDLK_KP1), 683 const_iv (SDLK_KP1),
630 const_iv (KMOD_RMETA), 759 const_iv (KMOD_RMETA),
631 const_iv (KMOD_NUM), 760 const_iv (KMOD_NUM),
632 const_iv (KMOD_CAPS), 761 const_iv (KMOD_CAPS),
633 const_iv (KMOD_MODE), 762 const_iv (KMOD_MODE),
634 763
764 const_iv (KMOD_LRAM),
765
635 const_iv (MIX_DEFAULT_FORMAT), 766 const_iv (MIX_DEFAULT_FORMAT),
767
768 const_iv (SDL_INIT_TIMER),
769 const_iv (SDL_INIT_AUDIO),
770 const_iv (SDL_INIT_VIDEO),
771 const_iv (SDL_INIT_CDROM),
772 const_iv (SDL_INIT_JOYSTICK),
773 const_iv (SDL_INIT_EVERYTHING),
774 const_iv (SDL_INIT_NOPARACHUTE),
775 const_iv (SDL_INIT_EVENTTHREAD),
776
777 const_iv (SDL_GL_RED_SIZE),
778 const_iv (SDL_GL_GREEN_SIZE),
779 const_iv (SDL_GL_BLUE_SIZE),
780 const_iv (SDL_GL_ALPHA_SIZE),
781 const_iv (SDL_GL_DOUBLEBUFFER),
782 const_iv (SDL_GL_BUFFER_SIZE),
783 const_iv (SDL_GL_DEPTH_SIZE),
784 const_iv (SDL_GL_STENCIL_SIZE),
785 const_iv (SDL_GL_ACCUM_RED_SIZE),
786 const_iv (SDL_GL_ACCUM_GREEN_SIZE),
787 const_iv (SDL_GL_ACCUM_BLUE_SIZE),
788 const_iv (SDL_GL_ACCUM_ALPHA_SIZE),
789 const_iv (SDL_GL_STEREO),
790 const_iv (SDL_GL_MULTISAMPLEBUFFERS),
791 const_iv (SDL_GL_MULTISAMPLESAMPLES),
792 const_iv (SDL_GL_ACCELERATED_VISUAL),
793 const_iv (SDL_GL_SWAP_CONTROL),
794
795 const_iv (FOW_DARKNESS)
636# undef const_iv 796# undef const_iv
637 }; 797 };
638 798
639 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 799 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
640 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 800 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
669 CODE: 829 CODE:
670{ 830{
671 opengl_fontmap = pango_opengl_font_map_new (); 831 opengl_fontmap = pango_opengl_font_map_new ();
672 pango_opengl_font_map_set_default_substitute ((PangoOpenGLFontMap *)opengl_fontmap, substitute_func, 0, 0); 832 pango_opengl_font_map_set_default_substitute ((PangoOpenGLFontMap *)opengl_fontmap, substitute_func, 0, 0);
673 opengl_context = pango_opengl_font_map_create_context ((PangoOpenGLFontMap *)opengl_fontmap); 833 opengl_context = pango_opengl_font_map_create_context ((PangoOpenGLFontMap *)opengl_fontmap);
674#if defined (PANGO_VERSION_CHECK) && PANGO_VERSION_CHECK (1, 15, 2) 834 /*pango_context_set_font_description (opengl_context, default_font);*/
835#if PANGO_VERSION_CHECK (1, 15, 2)
675 pango_context_set_language (opengl_context, pango_language_from_string ("en")); 836 pango_context_set_language (opengl_context, pango_language_from_string ("en"));
676 /*pango_context_set_base_dir (opengl_context, PANGO_DIRECTION_WEAK_LTR);*/ 837 /*pango_context_set_base_dir (opengl_context, PANGO_DIRECTION_WEAK_LTR);*/
677#endif 838#endif
678} 839}
679 840
680char *
681SDL_GetError () 841char *SDL_GetError ()
682 842
683int 843void SDL_braino ()
684SDL_Init (U32 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | PARACHUTE)
685 844
686void 845int SDL_Init (U32 flags)
846
847int SDL_InitSubSystem (U32 flags)
848
849void SDL_QuitSubSystem (U32 flags)
850
687SDL_Quit () 851void SDL_Quit ()
852
853int SDL_GL_SetAttribute (int attr, int value)
854
855int SDL_GL_GetAttribute (int attr)
856 CODE:
857 if (SDL_GL_GetAttribute (attr, &RETVAL))
858 XSRETURN_UNDEF;
859 OUTPUT:
860 RETVAL
688 861
689void 862void
690SDL_ListModes (int rgb, int alpha) 863SDL_ListModes (int rgb, int alpha)
691 PPCODE: 864 PPCODE:
692{ 865{
704 SDL_GL_SetAttribute (SDL_GL_ACCUM_GREEN_SIZE, 0); 877 SDL_GL_SetAttribute (SDL_GL_ACCUM_GREEN_SIZE, 0);
705 SDL_GL_SetAttribute (SDL_GL_ACCUM_BLUE_SIZE , 0); 878 SDL_GL_SetAttribute (SDL_GL_ACCUM_BLUE_SIZE , 0);
706 SDL_GL_SetAttribute (SDL_GL_ACCUM_ALPHA_SIZE, 0); 879 SDL_GL_SetAttribute (SDL_GL_ACCUM_ALPHA_SIZE, 0);
707 880
708 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); 881 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
709#if SDL_VERSION_ATLEAST(1,2,10)
710 SDL_GL_SetAttribute (SDL_GL_ACCELERATED_VISUAL, 1);
711 SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 1); 882 SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 1);
712#endif
713 883
714 m = SDL_ListModes (0, SDL_FULLSCREEN | SDL_OPENGL); 884 m = SDL_ListModes (0, SDL_FULLSCREEN | SDL_OPENGL);
715 885
716 if (m && m != (SDL_Rect **)-1) 886 if (m && m != (SDL_Rect **)-1)
717 while (*m) 887 while (*m)
718 { 888 {
719 if ((*m)->w >= 800 && (*m)->h >= 480) 889 if ((*m)->w >= 400 && (*m)->h >= 300)
720 { 890 {
721 AV *av = newAV (); 891 AV *av = newAV ();
722 av_push (av, newSViv ((*m)->w)); 892 av_push (av, newSViv ((*m)->w));
723 av_push (av, newSViv ((*m)->h)); 893 av_push (av, newSViv ((*m)->h));
724 av_push (av, newSViv (rgb)); 894 av_push (av, newSViv (rgb));
766SDL_GetKeyName (int sym) 936SDL_GetKeyName (int sym)
767 937
768int 938int
769SDL_GetAppState () 939SDL_GetAppState ()
770 940
941int
942SDL_GetModState ()
943
771void 944void
772poll_events () 945poll_events ()
773 PPCODE: 946 PPCODE:
774{ 947{
775 SDL_Event ev; 948 SDL_Event ev;
784 { 957 {
785 case SDL_KEYDOWN: 958 case SDL_KEYDOWN:
786 case SDL_KEYUP: 959 case SDL_KEYUP:
787 hv_store (hv, "state", 5, newSViv (ev.key.state), 0); 960 hv_store (hv, "state", 5, newSViv (ev.key.state), 0);
788 hv_store (hv, "sym", 3, newSViv (ev.key.keysym.sym), 0); 961 hv_store (hv, "sym", 3, newSViv (ev.key.keysym.sym), 0);
789 hv_store (hv, "mod", 3, newSViv (ev.key.keysym.mod & MOD_MASK), 0); 962 hv_store (hv, "mod", 3, newSViv (mod_munge (ev.key.keysym.mod)), 0);
790 hv_store (hv, "cmod", 4, newSViv (SDL_GetModState () & MOD_MASK), 0); /* current mode */ 963 hv_store (hv, "cmod", 4, newSViv (mod_munge (SDL_GetModState ())), 0); /* current mode */
791 hv_store (hv, "unicode", 7, newSViv (ev.key.keysym.unicode), 0); 964 hv_store (hv, "unicode", 7, newSViv (ev.key.keysym.unicode), 0);
792 break; 965 break;
793 966
794 case SDL_ACTIVEEVENT: 967 case SDL_ACTIVEEVENT:
795 hv_store (hv, "gain", 4, newSViv (ev.active.gain), 0); 968 hv_store (hv, "gain", 4, newSViv (ev.active.gain), 0);
813 x = ev.motion.x; 986 x = ev.motion.x;
814 y = ev.motion.y; 987 y = ev.motion.y;
815 SDL_PeepEvents (&ev, 1, SDL_GETEVENT, SDL_EVENTMASK (SDL_MOUSEMOTION)); 988 SDL_PeepEvents (&ev, 1, SDL_GETEVENT, SDL_EVENTMASK (SDL_MOUSEMOTION));
816 } 989 }
817 990
818 hv_store (hv, "mod", 3, newSViv (SDL_GetModState () & MOD_MASK), 0); 991 hv_store (hv, "mod", 3, newSViv (mod_munge (SDL_GetModState ())), 0);
819 hv_store (hv, "state", 5, newSViv (state), 0); 992 hv_store (hv, "state", 5, newSViv (state), 0);
820 hv_store (hv, "x", 1, newSViv (x), 0); 993 hv_store (hv, "x", 1, newSViv (x), 0);
821 hv_store (hv, "y", 1, newSViv (y), 0); 994 hv_store (hv, "y", 1, newSViv (y), 0);
822 hv_store (hv, "xrel", 4, newSViv (xrel), 0); 995 hv_store (hv, "xrel", 4, newSViv (xrel), 0);
823 hv_store (hv, "yrel", 4, newSViv (yrel), 0); 996 hv_store (hv, "yrel", 4, newSViv (yrel), 0);
908 } 1081 }
909 } 1082 }
910#endif 1083#endif
911} 1084}
912 1085
913void 1086int
914add_font (char *file) 1087add_font (char *file)
915 CODE: 1088 CODE:
916 FcConfigAppFontAddFile (0, (const FcChar8 *)file); 1089 RETVAL = FcConfigAppFontAddFile (0, (const FcChar8 *)file);
1090 OUTPUT:
1091 RETVAL
917 1092
918void 1093void
919load_image_inline (SV *image_) 1094load_image_inline (SV *image_)
920 ALIAS: 1095 ALIAS:
921 load_image_file = 1 1096 load_image_file = 1
1037#if DEBUG 1212#if DEBUG
1038 VALGRIND_DO_LEAK_CHECK; 1213 VALGRIND_DO_LEAK_CHECK;
1039#endif 1214#endif
1040} 1215}
1041 1216
1217int
1218SvREFCNT (SV *sv)
1219 CODE:
1220 RETVAL = SvREFCNT (sv);
1221 OUTPUT:
1222 RETVAL
1223
1042MODULE = Deliantra::Client PACKAGE = DC::Font 1224MODULE = Deliantra::Client PACKAGE = DC::Font
1043 1225
1044PROTOTYPES: DISABLE 1226PROTOTYPES: DISABLE
1045 1227
1046DC::Font 1228DC::Font
1331 PPCODE: 1513 PPCODE:
1332{ 1514{
1333 int line, x; 1515 int line, x;
1334 1516
1335 pango_layout_index_to_line_x (self->pl, index, trailing, &line, &x); 1517 pango_layout_index_to_line_x (self->pl, index, trailing, &line, &x);
1336#if !(defined (PANGO_VERSION_CHECK) && PANGO_VERSION_CHECK (1, 17, 3)) 1518#if !PANGO_VERSION_CHECK (1, 17, 3)
1337 /* pango bug: line is between 1..numlines, not 0..numlines-1 */ 1519 /* pango bug: line is between 1..numlines, not 0..numlines-1 */
1338 --line; 1520 --line;
1339#endif 1521#endif
1340 EXTEND (SP, 2); 1522 EXTEND (SP, 2);
1341 PUSHs (sv_2mortal (newSViv (line))); 1523 PUSHs (sv_2mortal (newSViv (line)));
1475 if (ix) 1657 if (ix)
1476 { 1658 {
1477 glDisable (GL_ALPHA_TEST); 1659 glDisable (GL_ALPHA_TEST);
1478 glDisable (GL_BLEND); 1660 glDisable (GL_BLEND);
1479 } 1661 }
1662}
1663
1664void
1665draw_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)
1666 PROTOTYPE: @
1667 CODE:
1668{
1669 glEnable (GL_TEXTURE_2D);
1670 glEnable (GL_BLEND);
1671 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1672 glBindTexture (GL_TEXTURE_2D, name1);
1673
1674 glColor3f (intensity, intensity, intensity);
1675 glPushMatrix ();
1676 glScalef (1./3, 1./3, 1.);
1677
1678 if (blend > 0.f)
1679 {
1680 float S2, T2; /* 0. 0. for texture 2 */
1681 float w = w1 > w2 ? w1 : w2;
1682 float h = h1 > h2 ? h1 : h2;
1683 GLfloat env_color[4] = { 0., 0., 0., blend };
1684
1685 /* interpolate the two shadow textures */
1686 /* stage 0 == rgb(glcolor) + alpha(t0) */
1687 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1688
1689 /* stage 1 == rgb(glcolor) + alpha(interpolate t0, t1, texenv) */
1690 gl.ActiveTexture (GL_TEXTURE1);
1691 glEnable (GL_TEXTURE_2D);
1692 glBindTexture (GL_TEXTURE_2D, name2);
1693 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
1694
1695 /* rgb == rgb(glcolor) */
1696 glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
1697 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_CONSTANT);
1698 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
1699
1700 /* alpha = interpolate t0, t1 by env_alpha */
1701 glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, env_color);
1702
1703 glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE);
1704 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
1705 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
1706
1707 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PREVIOUS);
1708 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
1709
1710 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_CONSTANT);
1711 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
1712
1713 s1 *= w / w1;
1714 t1 *= h / h1;
1715
1716 dx *= -3.f / w2;
1717 dy *= -3.f / h2;
1718 dx *= w / w2;
1719 dy *= h / h2;
1720
1721 s2 *= w / w2;
1722 t2 *= h / h2;
1723
1724 glBegin (GL_QUADS);
1725 gl.MultiTexCoord2f (GL_TEXTURE0, 0, 0); gl.MultiTexCoord2f (GL_TEXTURE1, dx , dy ); glVertex2f ( 0, 0);
1726 gl.MultiTexCoord2f (GL_TEXTURE0, 0, t1); gl.MultiTexCoord2f (GL_TEXTURE1, dx , dy + t2); glVertex2f ( 0, h1);
1727 gl.MultiTexCoord2f (GL_TEXTURE0, s1, t1); gl.MultiTexCoord2f (GL_TEXTURE1, dx + s2, dy + t2); glVertex2f (w1, h1);
1728 gl.MultiTexCoord2f (GL_TEXTURE0, s1, 0); gl.MultiTexCoord2f (GL_TEXTURE1, dx + s2, dy ); glVertex2f (w1, 0);
1729 glEnd ();
1730
1731 glDisable (GL_TEXTURE_2D);
1732 gl.ActiveTexture (GL_TEXTURE0);
1733 }
1734 else
1735 {
1736 /* simple blending of one texture, also opengl <1.3 path */
1737 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1738
1739 glBegin (GL_QUADS);
1740 glTexCoord2f ( 0, 0); glVertex2f ( 0, 0);
1741 glTexCoord2f ( 0, t1); glVertex2f ( 0, h1);
1742 glTexCoord2f (s1, t1); glVertex2f (w1, h1);
1743 glTexCoord2f (s1, 0); glVertex2f (w1, 0);
1744 glEnd ();
1745 }
1746
1747 glPopMatrix ();
1748
1749 glDisable (GL_TEXTURE_2D);
1750 glDisable (GL_BLEND);
1480} 1751}
1481 1752
1482IV texture_valid_2d (GLint internalformat, GLsizei w, GLsizei h, GLenum format, GLenum type) 1753IV texture_valid_2d (GLint internalformat, GLsizei w, GLsizei h, GLenum format, GLenum type)
1483 CODE: 1754 CODE:
1484{ 1755{
1590 //glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 1861 //glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1591 // use uglier nearest interpolation because linear suffers 1862 // use uglier nearest interpolation because linear suffers
1592 // from transparent color bleeding and ugly wrapping effects. 1863 // from transparent color bleeding and ugly wrapping effects.
1593 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1864 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1594} 1865}
1866
1867void
1868expire_textures (DC::Map self, int texid, int count)
1869 PPCODE:
1870 for (; texid < self->texs && count; ++texid, --count)
1871 {
1872 maptex *tex = self->tex + texid;
1873
1874 if (tex->name)
1875 {
1876 if (tex->unused)
1877 {
1878 tex->name = 0;
1879 tex->unused = 0;
1880 XPUSHs (sv_2mortal (newSViv (texid)));
1881 }
1882 else
1883 tex->unused = 1;
1884 }
1885 }
1595 1886
1596int 1887int
1597ox (DC::Map self) 1888ox (DC::Map self)
1598 ALIAS: 1889 ALIAS:
1599 oy = 1 1890 oy = 1
1677 uint8_t ext, cmd; 1968 uint8_t ext, cmd;
1678 1969
1679 do 1970 do
1680 { 1971 {
1681 ext = *data++; 1972 ext = *data++;
1682 cmd = ext & 0x3f; 1973 cmd = ext & 0x7f;
1683 1974
1684 if (cmd < 4) 1975 if (cmd < 4)
1685 cell->darkness = 255 - ext * 64 + 1; 1976 cell->darkness = 255 - ext * 64 + 1;
1686 else if (cmd == 5) // health 1977 else if (cmd == 5) // health
1687 { 1978 {
1690 } 1981 }
1691 else if (cmd == 6) // monster width 1982 else if (cmd == 6) // monster width
1692 cell->stat_width = *data++ + 1; 1983 cell->stat_width = *data++ + 1;
1693 else if (cmd == 0x47) 1984 else if (cmd == 0x47)
1694 { 1985 {
1695 if (*data == 4) 1986 if (*data == 1) cell->player = data [1];
1696 ; // decode player count 1987 else if (*data == 2) cell->player = data [2] + (data [1] << 8);
1988 else if (*data == 3) cell->player = data [3] + (data [2] << 8) + (data [1] << 16);
1989 else if (*data == 4) cell->player = data [4] + (data [3] << 8) + (data [2] << 16) + (data [1] << 24);
1697 1990
1698 data += *data + 1; 1991 data += *data + 1;
1699 } 1992 }
1700 else if (cmd == 8) // cell flags 1993 else if (cmd == 8) // cell flags
1701 cell->flags = *data++; 1994 cell->flags = *data++;
1718 cell->tile [z] = self->face2tile [face]; 2011 cell->tile [z] = self->face2tile [face];
1719 2012
1720 if (cell->tile [z]) 2013 if (cell->tile [z])
1721 { 2014 {
1722 maptex *tex = self->tex + cell->tile [z]; 2015 maptex *tex = self->tex + cell->tile [z];
2016 tex->unused = 0;
1723 if (!tex->name) 2017 if (!tex->name)
1724 av_push (missing, newSViv (cell->tile [z])); 2018 av_push (missing, newSViv (cell->tile [z]));
1725 2019
1726 if (tex->smoothtile) 2020 if (tex->smoothtile)
1727 { 2021 {
1728 maptex *smooth = self->tex + tex->smoothtile; 2022 maptex *smooth = self->tex + tex->smoothtile;
2023 smooth->unused = 0;
1729 if (!smooth->name) 2024 if (!smooth->name)
1730 av_push (missing, newSViv (tex->smoothtile)); 2025 av_push (missing, newSViv (tex->smoothtile));
1731 } 2026 }
1732 } 2027 }
1733 } 2028 }
1734 } 2029 }
1735 else 2030 else
1736 cell->darkness = 0; 2031 CELL_CLEAR (cell);
1737 } 2032 }
1738} 2033}
1739 OUTPUT: 2034 OUTPUT:
1740 RETVAL 2035 RETVAL
1741 2036
1793} 2088}
1794 OUTPUT: 2089 OUTPUT:
1795 RETVAL 2090 RETVAL
1796 2091
1797void 2092void
1798draw (DC::Map self, int mx, int my, int sw, int sh, int T) 2093draw (DC::Map self, int mx, int my, int sw, int sh, int T, U32 player = 0xffffffff, int sdx = 0, int sdy = 0)
1799 CODE: 2094 CODE:
1800{ 2095{
1801 int x, y, z; 2096 int x, y, z;
1802 2097
1803 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ()); 2098 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
1804 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level 2099 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level
1805 static uint8_t smooth_max[256][256]; // egad, fast and wasteful on memory (64k) 2100 static uint8_t smooth_max[256][256]; // egad, fast and wasteful on memory (64k)
1806 smooth_key skey; 2101 smooth_key skey;
1807 2102 int pl_x, pl_y;
2103 maptex pl_tex;
1808 rc_t *rc = rc_alloc (); 2104 rc_t *rc = rc_alloc ();
2105 rc_t *rc_ov = rc_alloc ();
1809 rc_key_t key; 2106 rc_key_t key;
1810 rc_array_t *arr; 2107 rc_array_t *arr, *arr_hidden;
1811 2108
2109 pl_tex.name = 0;
2110
1812 // thats current max. sorry. 2111 // that's current max. sorry.
1813 if (sw > 255) sw = 255; 2112 if (sw > 255) sw = 255;
1814 if (sh > 255) sh = 255; 2113 if (sh > 255) sh = 255;
1815 2114
1816 // clear key, in case of extra padding 2115 // clear key, in case of extra padding
1817 memset (&skey, 0, sizeof (skey)); 2116 memset (&skey, 0, sizeof (skey));
1821 key.g = 255; 2120 key.g = 255;
1822 key.b = 255; 2121 key.b = 255;
1823 key.a = 255; 2122 key.a = 255;
1824 key.mode = GL_QUADS; 2123 key.mode = GL_QUADS;
1825 key.format = GL_T2F_V3F; 2124 key.format = GL_T2F_V3F;
1826 key.texname = -1;
1827 2125
1828 mx += self->x; 2126 mx += self->x;
1829 my += self->y; 2127 my += self->y;
1830 2128
1831 // first pass: determine smooth_max 2129 // first pass: determine smooth_max
1852 2150
1853 glEnable (GL_BLEND); 2151 glEnable (GL_BLEND);
1854 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2152 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1855 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 2153 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1856 2154
2155 key.texname = self->tex [TEXID_HIDDEN].name;
2156 arr_hidden = rc_array (rc_ov, &key);
2157
1857 for (z = 0; z <= 2; z++) 2158 for (z = 0; z <= 2; z++)
1858 { 2159 {
1859 memset (smooth_level, 0, sizeof (smooth_level)); 2160 memset (smooth_level, 0, sizeof (smooth_level));
2161 key.texname = -1;
1860 2162
1861 for (y = 0; y < sh; y++) 2163 for (y = 0; y < sh; y++)
1862 if (0 <= y + my && y + my < self->rows) 2164 if (0 <= y + my && y + my < self->rows)
1863 { 2165 {
1864 maprow *row = self->row + (y + my); 2166 maprow *row = self->row + (y + my);
1874 maptex tex = self->tex [tile]; 2176 maptex tex = self->tex [tile];
1875 int px, py; 2177 int px, py;
1876 2178
1877 if (key.texname != tex.name) 2179 if (key.texname != tex.name)
1878 { 2180 {
2181 self->tex [tile].unused = 0;
2182
1879 if (!tex.name) 2183 if (!tex.name)
1880 tex = self->tex [2]; /* missing, replace by noface */ 2184 tex = self->tex [TEXID_NOFACE]; /* missing, replace by noface */
1881 2185
1882 key.texname = tex.name; 2186 key.texname = tex.name;
1883 arr = rc_array (rc, &key); 2187 arr = rc_array (rc, &key);
1884 } 2188 }
1885 2189
1886 px = (x + 1) * T - tex.w; 2190 px = (x + 1) * T - tex.w;
1887 py = (y + 1) * T - tex.h; 2191 py = (y + 1) * T - tex.h;
2192
2193 if (expect_false (cell->player == player) && expect_false (z == 2))
2194 {
2195 pl_x = px;
2196 pl_y = py;
2197 pl_tex = tex;
2198 continue;
2199 }
1888 2200
1889 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2201 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
1890 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0); 2202 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0);
1891 rc_t2f_v3f (arr, tex.s, tex.t, px + tex.w, py + tex.h, 0); 2203 rc_t2f_v3f (arr, tex.s, tex.t, px + tex.w, py + tex.h, 0);
1892 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0); 2204 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0);
1893
1894 if (cell->flags && z == 2)
1895 {
1896 // overlays such as the speech bubble, probably more to come
1897 if (cell->flags & 1)
1898 {
1899 maptex tex = self->tex [1];
1900 int px = x * T + T * 2 / 32;
1901 int py = y * T - T * 6 / 32;
1902
1903 if (tex.name)
1904 {
1905 if (key.texname != tex.name)
1906 {
1907 key.texname = tex.name;
1908 arr = rc_array (rc, &key);
1909 }
1910
1911 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
1912 rc_t2f_v3f (arr, 0 , tex.t, px , py + T, 0);
1913 rc_t2f_v3f (arr, tex.s, tex.t, px + T, py + T, 0);
1914 rc_t2f_v3f (arr, tex.s, 0 , px + T, py , 0);
1915 }
1916 }
1917 }
1918 2205
1919 // update smooth hash 2206 // update smooth hash
1920 if (tex.smoothtile) 2207 if (tex.smoothtile)
1921 { 2208 {
1922 skey.tile = tex.smoothtile; 2209 skey.tile = tex.smoothtile;
1951 // corners 2238 // corners
1952 skey.x = x + 2; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0100); 2239 skey.x = x + 2; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0100);
1953 skey.x = x ; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0200); 2240 skey.x = x ; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0200);
1954 skey.x = x ; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0400); 2241 skey.x = x ; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0400);
1955 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0800); 2242 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0800);
2243 }
2244 }
2245
2246 if (expect_false (z == 2))
2247 {
2248 /* draw question marks on top of hidden spaces */
2249 if (!cell->darkness)
2250 {
2251 maptex tex = self->tex [TEXID_HIDDEN];
2252 int px = (x + 1) * T - tex.w;
2253 int py = (y + 1) * T - tex.h;
2254
2255 rc_t2f_v3f (arr_hidden, 0 , 0 , px , py , 0);
2256 rc_t2f_v3f (arr_hidden, 0 , tex.t, px , py + tex.h, 0);
2257 rc_t2f_v3f (arr_hidden, tex.s, tex.t, px + tex.w, py + tex.h, 0);
2258 rc_t2f_v3f (arr_hidden, tex.s, 0 , px + tex.w, py , 0);
2259 }
2260
2261 if (expect_false (cell->flags))
2262 {
2263 // overlays such as the speech bubble, probably more to come
2264 if (cell->flags & 1)
2265 {
2266 rc_key_t key_ov = key;
2267 maptex tex = self->tex [TEXID_SPEECH];
2268 rc_array_t *arr;
2269 int px = x * T + T * 2 / 32;
2270 int py = y * T - T * 6 / 32;
2271
2272 key_ov.texname = tex.name;
2273 arr = rc_array (rc_ov, &key_ov);
2274
2275 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
2276 rc_t2f_v3f (arr, 0 , tex.t, px , py + T, 0);
2277 rc_t2f_v3f (arr, tex.s, tex.t, px + T, py + T, 0);
2278 rc_t2f_v3f (arr, tex.s, 0 , px + T, py , 0);
2279 }
1956 } 2280 }
1957 } 2281 }
1958 } 2282 }
1959 } 2283 }
1960 2284
2000 { 2324 {
2001 // this time avoiding texture state changes 2325 // this time avoiding texture state changes
2002 // save gobs of state changes. 2326 // save gobs of state changes.
2003 if (key.texname != tex.name) 2327 if (key.texname != tex.name)
2004 { 2328 {
2329 self->tex [skey->tile].unused = 0;
2330
2005 glEnd (); 2331 glEnd ();
2006 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name); 2332 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name);
2007 glBegin (GL_QUADS); 2333 glBegin (GL_QUADS);
2008 } 2334 }
2009 2335
2038 } 2364 }
2039 2365
2040 hv_clear (smooth); 2366 hv_clear (smooth);
2041 } 2367 }
2042 2368
2369 if (pl_tex.name)
2370 {
2371 maptex tex = pl_tex;
2372 int px = pl_x + sdx;
2373 int py = pl_y + sdy;
2374
2375 key.texname = tex.name;
2376 arr = rc_array (rc, &key);
2377
2378 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
2379 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0);
2380 rc_t2f_v3f (arr, tex.s, tex.t, px + tex.w, py + tex.h, 0);
2381 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0);
2382
2383 rc_draw (rc);
2384 }
2385
2386 rc_draw (rc_ov);
2387 rc_clear (rc_ov);
2388
2043 glDisable (GL_BLEND); 2389 glDisable (GL_BLEND);
2044 rc_free (rc); 2390 rc_free (rc);
2391 rc_free (rc_ov);
2045 2392
2046 // top layer: overlays such as the health bar 2393 // top layer: overlays such as the health bar
2047 for (y = 0; y < sh; y++) 2394 for (y = 0; y < sh; y++)
2048 if (0 <= y + my && y + my < self->rows) 2395 if (0 <= y + my && y + my < self->rows)
2049 { 2396 {
2054 { 2401 {
2055 mapcell *cell = row->col + (x + mx - row->c0); 2402 mapcell *cell = row->col + (x + mx - row->c0);
2056 2403
2057 int px = x * T; 2404 int px = x * T;
2058 int py = y * T; 2405 int py = y * T;
2406
2407 if (expect_false (cell->player == player))
2408 {
2409 px += sdx;
2410 py += sdy;
2411 }
2059 2412
2060 if (cell->stat_hp) 2413 if (cell->stat_hp)
2061 { 2414 {
2062 int width = cell->stat_width * T; 2415 int width = cell->stat_width * T;
2063 int thick = (sh * T / 32 + 27) / 28 + 1 + cell->stat_width; 2416 int thick = (sh * T / 32 + 27) / 28 + 1 + cell->stat_width;
2103 }; 2456 };
2104 2457
2105 int x, y; 2458 int x, y;
2106 2459
2107 glEnable (GL_TEXTURE_2D); 2460 glEnable (GL_TEXTURE_2D);
2461 /* GL_REPLACE would be correct, as we don't need to modulate alpha,
2462 * but the nvidia driver (185.18.14) mishandles alpha textures
2463 * ansd takes the colour from god knows where instead of using
2464 * Cp. MODULATE results in the same colour, but slightly different
2465 * alpha, but atcually gives us the correct colour with nvidia.
2466 */
2108 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 2467 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
2109 glEnable (GL_BLEND); 2468 glEnable (GL_BLEND);
2110 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2469 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2111 glBegin (GL_QUADS); 2470 glBegin (GL_QUADS);
2112 2471
2113 for (y = 0; y < h; y++) 2472 for (y = 0; y < h; y++)
2120 float *c = color [m & 15]; 2479 float *c = color [m & 15];
2121 2480
2122 float tx1 = m & 0x40 ? 0.5 : 0.; 2481 float tx1 = m & 0x40 ? 0.5 : 0.;
2123 float tx2 = tx1 + 0.5; 2482 float tx2 = tx1 + 0.5;
2124 2483
2125 glColor4f (c[0], c[1], c[2], 0.75); 2484 glColor4f (c[0], c[1], c[2], 1);
2126 glTexCoord2f (tx1, 0.); glVertex2i (x , y ); 2485 glTexCoord2f (tx1, 0.); glVertex2i (x , y );
2127 glTexCoord2f (tx1, 1.); glVertex2i (x , y + 1); 2486 glTexCoord2f (tx1, 1.); glVertex2i (x , y + 1);
2128 glTexCoord2f (tx2, 1.); glVertex2i (x + 1, y + 1); 2487 glTexCoord2f (tx2, 1.); glVertex2i (x + 1, y + 1);
2129 glTexCoord2f (tx2, 0.); glVertex2i (x + 1, y ); 2488 glTexCoord2f (tx2, 0.); glVertex2i (x + 1, y );
2130 } 2489 }
2152 SvCUR_set (darkness3_sv, sw34 * sh3); 2511 SvCUR_set (darkness3_sv, sw34 * sh3);
2153 2512
2154 mx += self->x - 1; 2513 mx += self->x - 1;
2155 my += self->y - 1; 2514 my += self->y - 1;
2156 2515
2157 memset (darkness1, 255, sw1 * sh1); 2516 memset (darkness1, DARKNESS_ADJUST (255 - FOW_DARKNESS), sw1 * sh1);
2158 2517
2159 for (y = 0; y < sh1; y++) 2518 for (y = 0; y < sh1; y++)
2160 if (0 <= y + my && y + my < self->rows) 2519 if (0 <= y + my && y + my < self->rows)
2161 { 2520 {
2162 maprow *row = self->row + (y + my); 2521 maprow *row = self->row + (y + my);
2165 if (row->c0 <= x + mx && x + mx < row->c1) 2524 if (row->c0 <= x + mx && x + mx < row->c1)
2166 { 2525 {
2167 mapcell *cell = row->col + (x + mx - row->c0); 2526 mapcell *cell = row->col + (x + mx - row->c0);
2168 2527
2169 darkness1 [y * sw1 + x] = cell->darkness 2528 darkness1 [y * sw1 + x] = cell->darkness
2170 ? 255 - (cell->darkness - 1) 2529 ? DARKNESS_ADJUST (255 - (cell->darkness - 1))
2171 : 255 - FOW_DARKNESS; 2530 : DARKNESS_ADJUST (255 - FOW_DARKNESS);
2172 } 2531 }
2173 } 2532 }
2174 2533
2175 for (y = 0; y < sh; ++y) 2534 for (y = 0; y < sh; ++y)
2176 for (x = 0; x < sw; ++x) 2535 for (x = 0; x < sw; ++x)
2282 else 2641 else
2283 *data++ = 0; 2642 *data++ = 0;
2284 } 2643 }
2285 } 2644 }
2286 2645
2646 /* if size is w*h + 5 then no data has been found */
2647 if (data - (uint8_t *)SvPVX (data_sv) != w * h + 5)
2648 {
2287 SvPOK_only (data_sv); 2649 SvPOK_only (data_sv);
2288 SvCUR_set (data_sv, data - (uint8_t *)SvPVX (data_sv)); 2650 SvCUR_set (data_sv, data - (uint8_t *)SvPVX (data_sv));
2651 }
2652
2289 RETVAL = data_sv; 2653 RETVAL = data_sv;
2290} 2654}
2291 OUTPUT: 2655 OUTPUT:
2292 RETVAL 2656 RETVAL
2293 2657
2294void 2658void
2295set_rect (DC::Map self, int x0, int y0, uint8_t *data) 2659set_rect (DC::Map self, int x0, int y0, SV *data_sv)
2296 PPCODE: 2660 PPCODE:
2297{ 2661{
2298 int x, y, z; 2662 int x, y, z;
2299 int w, h; 2663 int w, h;
2300 int x1, y1; 2664 int x1, y1;
2665 STRLEN len;
2666 uint8_t *data, *end;
2667
2668 len = SvLEN (data_sv);
2669 SvGROW (data_sv, len + 8); // reserve at least 7+ bytes more
2670 data = SvPVbyte_nolen (data_sv);
2671 end = data + len + 8;
2672
2673 if (len < 5)
2674 XSRETURN_EMPTY;
2301 2675
2302 if (*data++ != 0) 2676 if (*data++ != 0)
2303 XSRETURN_EMPTY; /* version mismatch */ 2677 XSRETURN_EMPTY; /* version mismatch */
2304 2678
2305 w = *data++ << 8; w |= *data++; 2679 w = *data++ << 8; w |= *data++;
2320 { 2694 {
2321 maprow *row = map_get_row (self, y); 2695 maprow *row = map_get_row (self, y);
2322 2696
2323 for (x = x0; x < x1; x++) 2697 for (x = x0; x < x1; x++)
2324 { 2698 {
2699 uint8_t flags;
2700
2701 if (data + 7 >= end)
2702 XSRETURN_EMPTY;
2703
2325 uint8_t flags = *data++; 2704 flags = *data++;
2326 2705
2327 if (flags) 2706 if (flags)
2328 { 2707 {
2329 mapcell *cell = row_get_cell (row, x); 2708 mapcell *cell = row_get_cell (row, x);
2330 tileid tile[3] = { 0, 0, 0 }; 2709 tileid tile[3] = { 0, 0, 0 };
2333 if (flags & 2) { tile[1] = *data++ << 8; tile[1] |= *data++; } 2712 if (flags & 2) { tile[1] = *data++ << 8; tile[1] |= *data++; }
2334 if (flags & 4) { tile[2] = *data++ << 8; tile[2] |= *data++; } 2713 if (flags & 4) { tile[2] = *data++ << 8; tile[2] |= *data++; }
2335 2714
2336 if (cell->darkness == 0) 2715 if (cell->darkness == 0)
2337 { 2716 {
2338 cell->darkness = 0; 2717 /*cell->darkness = 0;*/
2718 EXTEND (SP, 3);
2339 2719
2340 for (z = 0; z <= 2; z++) 2720 for (z = 0; z <= 2; z++)
2341 { 2721 {
2342 tileid t = tile [z]; 2722 tileid t = tile [z];
2343 2723
2344 if (t >= self->texs || (t && !self->tex [t].name)) 2724 if (t >= self->texs || (t && !self->tex [t].name))
2345 { 2725 {
2346 XPUSHs (sv_2mortal (newSViv (t))); 2726 PUSHs (sv_2mortal (newSViv (t)));
2347 need_texid (self, t); 2727 need_texid (self, t);
2348 } 2728 }
2349 2729
2350 cell->tile [z] = t; 2730 cell->tile [z] = t;
2351 } 2731 }
2568 } *civ, const_iv[] = { 2948 } *civ, const_iv[] = {
2569# define const_iv(name) { # name, (IV)name } 2949# define const_iv(name) { # name, (IV)name }
2570 const_iv (GL_VENDOR), 2950 const_iv (GL_VENDOR),
2571 const_iv (GL_VERSION), 2951 const_iv (GL_VERSION),
2572 const_iv (GL_EXTENSIONS), 2952 const_iv (GL_EXTENSIONS),
2953 const_iv (GL_MAX_TEXTURE_UNITS),
2573 const_iv (GL_COLOR_MATERIAL), 2954 const_iv (GL_COLOR_MATERIAL),
2574 const_iv (GL_SMOOTH), 2955 const_iv (GL_SMOOTH),
2575 const_iv (GL_FLAT), 2956 const_iv (GL_FLAT),
2576 const_iv (GL_DITHER), 2957 const_iv (GL_DITHER),
2577 const_iv (GL_BLEND), 2958 const_iv (GL_BLEND),
2589 const_iv (GL_ZERO), 2970 const_iv (GL_ZERO),
2590 const_iv (GL_SRC_ALPHA), 2971 const_iv (GL_SRC_ALPHA),
2591 const_iv (GL_DST_ALPHA), 2972 const_iv (GL_DST_ALPHA),
2592 const_iv (GL_ONE_MINUS_SRC_ALPHA), 2973 const_iv (GL_ONE_MINUS_SRC_ALPHA),
2593 const_iv (GL_ONE_MINUS_DST_ALPHA), 2974 const_iv (GL_ONE_MINUS_DST_ALPHA),
2975 const_iv (GL_SRC_COLOR),
2976 const_iv (GL_DST_COLOR),
2977 const_iv (GL_ONE_MINUS_SRC_COLOR),
2978 const_iv (GL_ONE_MINUS_DST_COLOR),
2594 const_iv (GL_SRC_ALPHA_SATURATE), 2979 const_iv (GL_SRC_ALPHA_SATURATE),
2595 const_iv (GL_RGB), 2980 const_iv (GL_RGB),
2596 const_iv (GL_RGBA), 2981 const_iv (GL_RGBA),
2597 const_iv (GL_RGBA4), 2982 const_iv (GL_RGBA4),
2598 const_iv (GL_RGBA8), 2983 const_iv (GL_RGBA8),
2666 const_iv (GL_NICEST), 3051 const_iv (GL_NICEST),
2667 const_iv (GL_V2F), 3052 const_iv (GL_V2F),
2668 const_iv (GL_V3F), 3053 const_iv (GL_V3F),
2669 const_iv (GL_T2F_V3F), 3054 const_iv (GL_T2F_V3F),
2670 const_iv (GL_T2F_N3F_V3F), 3055 const_iv (GL_T2F_N3F_V3F),
3056 const_iv (GL_FUNC_ADD),
3057 const_iv (GL_FUNC_SUBTRACT),
3058 const_iv (GL_FUNC_REVERSE_SUBTRACT),
2671# undef const_iv 3059# undef const_iv
2672 }; 3060 };
2673 3061
2674 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 3062 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
2675 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 3063 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
2682disable_GL_EXT_blend_func_separate () 3070disable_GL_EXT_blend_func_separate ()
2683 CODE: 3071 CODE:
2684 gl.BlendFuncSeparate = 0; 3072 gl.BlendFuncSeparate = 0;
2685 gl.BlendFuncSeparateEXT = 0; 3073 gl.BlendFuncSeparateEXT = 0;
2686 3074
3075void
3076apple_nvidia_bug (int enable)
3077
2687char * 3078char *
2688gl_vendor () 3079gl_vendor ()
2689 CODE: 3080 CODE:
2690 RETVAL = (char *)glGetString (GL_VENDOR); 3081 RETVAL = (char *)glGetString (GL_VENDOR);
2691 OUTPUT: 3082 OUTPUT:
2740 3131
2741void glBlendFuncSeparate (int sa, int da, int saa, int daa) 3132void glBlendFuncSeparate (int sa, int da, int saa, int daa)
2742 CODE: 3133 CODE:
2743 gl_BlendFuncSeparate (sa, da, saa, daa); 3134 gl_BlendFuncSeparate (sa, da, saa, daa);
2744 3135
3136# void glBlendEquation (int se)
3137
2745void glDepthMask (int flag) 3138void glDepthMask (int flag)
2746 3139
2747void glLogicOp (int opcode) 3140void glLogicOp (int opcode)
2748 3141
2749void glColorMask (int red, int green, int blue, int alpha) 3142void glColorMask (int red, int green, int blue, int alpha)
2783void glRotate (float angle, float x, float y, float z) 3176void glRotate (float angle, float x, float y, float z)
2784 CODE: 3177 CODE:
2785 glRotatef (angle, x, y, z); 3178 glRotatef (angle, x, y, z);
2786 3179
2787void glColor (float r, float g, float b, float a = 1.0) 3180void glColor (float r, float g, float b, float a = 1.0)
3181 PROTOTYPE: @
2788 ALIAS: 3182 ALIAS:
2789 glColor_premultiply = 1 3183 glColor_premultiply = 1
2790 CODE: 3184 CODE:
2791 if (ix) 3185 if (ix)
2792 { 3186 {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines