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.249 by root, Fri Dec 28 15:40:07 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#if 0 94/* mask out modifiers we are not interested in */
76# define PARACHUTE SDL_INIT_NOPARACHUTE 95#define MOD_MASK (KMOD_CTRL | KMOD_SHIFT | KMOD_ALT | KMOD_META)
77#else 96
78# define PARACHUTE 0 97#define KMOD_LRAM 0x10000 // our extension
79#endif 98
99#define TEXID_SPEECH 1
100#define TEXID_NOFACE 2
101#define TEXID_HIDDEN 3
80 102
81static AV *texture_av; 103static AV *texture_av;
82 104
83static struct 105static struct
84{ 106{
178 200
179static void 201static void
180layout_update_font (DC__Layout self) 202layout_update_font (DC__Layout self)
181{ 203{
182 /* 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
183 * reasonably well with bitstream vera 205 * reasonably well with dejavu/bistream fonts
184 */ 206 */
185 PangoFontDescription *font = self->font ? self->font : default_font; 207 PangoFontDescription *font = self->font ? self->font : default_font;
186 208
187 pango_font_description_set_absolute_size (font, 209 pango_font_description_set_absolute_size (font,
188 MAX (MIN_FONT_HEIGHT, self->base_height) * (PANGO_SCALE * 8 / 10)); 210 MAX (MIN_FONT_HEIGHT, self->base_height) * (PANGO_SCALE * 8 / 10));
216 int w, h; 238 int w, h;
217 float s, t; 239 float s, t;
218 uint8_t r, g, b, a; 240 uint8_t r, g, b, a;
219 tileid smoothtile; 241 tileid smoothtile;
220 uint8_t smoothlevel; 242 uint8_t smoothlevel;
243 uint8_t unused; /* set to zero on use */
221} maptex; 244} maptex;
222 245
223typedef struct { 246typedef struct {
224 uint32_t player; 247 uint32_t player;
225 tileid tile[3]; 248 tileid tile[3];
357 self->oy = 0; 380 self->oy = 0;
358 self->row = 0; 381 self->row = 0;
359 self->rows = 0; 382 self->rows = 0;
360} 383}
361 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
362static void 395static void
363map_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)
364{ 397{
365 int x, y; 398 int x, y;
366 maprow *row; 399 maprow *row;
380 if (x >= row->c1) 413 if (x >= row->c1)
381 break; 414 break;
382 415
383 cell = row->col + x - row->c0; 416 cell = row->col + x - row->c0;
384 417
385 cell->darkness = 0; 418 CELL_CLEAR (cell);
386 cell->stat_hp = 0;
387 cell->flags = 0;
388 cell->player = 0;
389 } 419 }
390 } 420 }
391} 421}
392 422
393typedef struct { 423typedef struct {
504 if (!svp || !SvTRUE (*svp)) 534 if (!svp || !SvTRUE (*svp))
505 return 0; 535 return 0;
506 536
507 return 1; 537 return 1;
508} 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
509 591
510MODULE = Deliantra::Client PACKAGE = DC 592MODULE = Deliantra::Client PACKAGE = DC
511 593
512PROTOTYPES: ENABLE 594PROTOTYPES: ENABLE
513 595
542 const_iv (SDL_USEREVENT), 624 const_iv (SDL_USEREVENT),
543 625
544 const_iv (SDL_APPINPUTFOCUS), 626 const_iv (SDL_APPINPUTFOCUS),
545 const_iv (SDL_APPMOUSEFOCUS), 627 const_iv (SDL_APPMOUSEFOCUS),
546 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),
547 679
548 const_iv (SDLK_FIRST), 680 const_iv (SDLK_FIRST),
549 const_iv (SDLK_LAST), 681 const_iv (SDLK_LAST),
550 const_iv (SDLK_KP0), 682 const_iv (SDLK_KP0),
551 const_iv (SDLK_KP1), 683 const_iv (SDLK_KP1),
627 const_iv (KMOD_RMETA), 759 const_iv (KMOD_RMETA),
628 const_iv (KMOD_NUM), 760 const_iv (KMOD_NUM),
629 const_iv (KMOD_CAPS), 761 const_iv (KMOD_CAPS),
630 const_iv (KMOD_MODE), 762 const_iv (KMOD_MODE),
631 763
764 const_iv (KMOD_LRAM),
765
632 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)
633# undef const_iv 796# undef const_iv
634 }; 797 };
635 798
636 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; )
637 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 800 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
666 CODE: 829 CODE:
667{ 830{
668 opengl_fontmap = pango_opengl_font_map_new (); 831 opengl_fontmap = pango_opengl_font_map_new ();
669 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);
670 opengl_context = pango_opengl_font_map_create_context ((PangoOpenGLFontMap *)opengl_fontmap); 833 opengl_context = pango_opengl_font_map_create_context ((PangoOpenGLFontMap *)opengl_fontmap);
671#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)
672 pango_context_set_language (opengl_context, pango_language_from_string ("en")); 836 pango_context_set_language (opengl_context, pango_language_from_string ("en"));
673 pango_context_set_base_dir (opengl_context, PANGO_DIRECTION_WEAK_LTR); 837 /*pango_context_set_base_dir (opengl_context, PANGO_DIRECTION_WEAK_LTR);*/
674#endif 838#endif
675} 839}
676 840
677char *
678SDL_GetError () 841char *SDL_GetError ()
679 842
680int 843void SDL_braino ()
681SDL_Init (U32 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | PARACHUTE)
682 844
683void 845int SDL_Init (U32 flags)
846
847int SDL_InitSubSystem (U32 flags)
848
849void SDL_QuitSubSystem (U32 flags)
850
684SDL_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
685 861
686void 862void
687SDL_ListModes (int rgb, int alpha) 863SDL_ListModes (int rgb, int alpha)
688 PPCODE: 864 PPCODE:
689{ 865{
701 SDL_GL_SetAttribute (SDL_GL_ACCUM_GREEN_SIZE, 0); 877 SDL_GL_SetAttribute (SDL_GL_ACCUM_GREEN_SIZE, 0);
702 SDL_GL_SetAttribute (SDL_GL_ACCUM_BLUE_SIZE , 0); 878 SDL_GL_SetAttribute (SDL_GL_ACCUM_BLUE_SIZE , 0);
703 SDL_GL_SetAttribute (SDL_GL_ACCUM_ALPHA_SIZE, 0); 879 SDL_GL_SetAttribute (SDL_GL_ACCUM_ALPHA_SIZE, 0);
704 880
705 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); 881 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
706#if SDL_VERSION_ATLEAST(1,2,10)
707 SDL_GL_SetAttribute (SDL_GL_ACCELERATED_VISUAL, 1);
708 SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 1); 882 SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 1);
709#endif
710 883
711 m = SDL_ListModes (0, SDL_FULLSCREEN | SDL_OPENGL); 884 m = SDL_ListModes (0, SDL_FULLSCREEN | SDL_OPENGL);
712 885
713 if (m && m != (SDL_Rect **)-1) 886 if (m && m != (SDL_Rect **)-1)
714 while (*m) 887 while (*m)
715 { 888 {
716 if ((*m)->w >= 800 && (*m)->h >= 480) 889 if ((*m)->w >= 400 && (*m)->h >= 300)
717 { 890 {
718 AV *av = newAV (); 891 AV *av = newAV ();
719 av_push (av, newSViv ((*m)->w)); 892 av_push (av, newSViv ((*m)->w));
720 av_push (av, newSViv ((*m)->h)); 893 av_push (av, newSViv ((*m)->h));
721 av_push (av, newSViv (rgb)); 894 av_push (av, newSViv (rgb));
763SDL_GetKeyName (int sym) 936SDL_GetKeyName (int sym)
764 937
765int 938int
766SDL_GetAppState () 939SDL_GetAppState ()
767 940
941int
942SDL_GetModState ()
943
768void 944void
769poll_events () 945poll_events ()
770 PPCODE: 946 PPCODE:
771{ 947{
772 SDL_Event ev; 948 SDL_Event ev;
781 { 957 {
782 case SDL_KEYDOWN: 958 case SDL_KEYDOWN:
783 case SDL_KEYUP: 959 case SDL_KEYUP:
784 hv_store (hv, "state", 5, newSViv (ev.key.state), 0); 960 hv_store (hv, "state", 5, newSViv (ev.key.state), 0);
785 hv_store (hv, "sym", 3, newSViv (ev.key.keysym.sym), 0); 961 hv_store (hv, "sym", 3, newSViv (ev.key.keysym.sym), 0);
786 hv_store (hv, "mod", 3, newSViv (ev.key.keysym.mod), 0); 962 hv_store (hv, "mod", 3, newSViv (mod_munge (ev.key.keysym.mod)), 0);
787 hv_store (hv, "cmod", 4, newSViv (SDL_GetModState ()), 0); /* current mode */ 963 hv_store (hv, "cmod", 4, newSViv (mod_munge (SDL_GetModState ())), 0); /* current mode */
788 hv_store (hv, "unicode", 7, newSViv (ev.key.keysym.unicode), 0); 964 hv_store (hv, "unicode", 7, newSViv (ev.key.keysym.unicode), 0);
789 break; 965 break;
790 966
791 case SDL_ACTIVEEVENT: 967 case SDL_ACTIVEEVENT:
792 hv_store (hv, "gain", 4, newSViv (ev.active.gain), 0); 968 hv_store (hv, "gain", 4, newSViv (ev.active.gain), 0);
810 x = ev.motion.x; 986 x = ev.motion.x;
811 y = ev.motion.y; 987 y = ev.motion.y;
812 SDL_PeepEvents (&ev, 1, SDL_GETEVENT, SDL_EVENTMASK (SDL_MOUSEMOTION)); 988 SDL_PeepEvents (&ev, 1, SDL_GETEVENT, SDL_EVENTMASK (SDL_MOUSEMOTION));
813 } 989 }
814 990
815 hv_store (hv, "mod", 3, newSViv (SDL_GetModState ()), 0); 991 hv_store (hv, "mod", 3, newSViv (mod_munge (SDL_GetModState ())), 0);
816 hv_store (hv, "state", 5, newSViv (state), 0); 992 hv_store (hv, "state", 5, newSViv (state), 0);
817 hv_store (hv, "x", 1, newSViv (x), 0); 993 hv_store (hv, "x", 1, newSViv (x), 0);
818 hv_store (hv, "y", 1, newSViv (y), 0); 994 hv_store (hv, "y", 1, newSViv (y), 0);
819 hv_store (hv, "xrel", 4, newSViv (xrel), 0); 995 hv_store (hv, "xrel", 4, newSViv (xrel), 0);
820 hv_store (hv, "yrel", 4, newSViv (yrel), 0); 996 hv_store (hv, "yrel", 4, newSViv (yrel), 0);
821 } 997 }
822 break; 998 break;
823 999
824 case SDL_MOUSEBUTTONDOWN: 1000 case SDL_MOUSEBUTTONDOWN:
825 case SDL_MOUSEBUTTONUP: 1001 case SDL_MOUSEBUTTONUP:
826 hv_store (hv, "mod", 3, newSViv (SDL_GetModState ()), 0); 1002 hv_store (hv, "mod", 3, newSViv (SDL_GetModState () & MOD_MASK), 0);
827 1003
828 hv_store (hv, "button", 6, newSViv (ev.button.button), 0); 1004 hv_store (hv, "button", 6, newSViv (ev.button.button), 0);
829 hv_store (hv, "state", 5, newSViv (ev.button.state), 0); 1005 hv_store (hv, "state", 5, newSViv (ev.button.state), 0);
830 hv_store (hv, "x", 1, newSViv (ev.button.x), 0); 1006 hv_store (hv, "x", 1, newSViv (ev.button.x), 0);
831 hv_store (hv, "y", 1, newSViv (ev.button.y), 0); 1007 hv_store (hv, "y", 1, newSViv (ev.button.y), 0);
905 } 1081 }
906 } 1082 }
907#endif 1083#endif
908} 1084}
909 1085
910void 1086int
911add_font (char *file) 1087add_font (char *file)
912 CODE: 1088 CODE:
913 FcConfigAppFontAddFile (0, (const FcChar8 *)file); 1089 RETVAL = FcConfigAppFontAddFile (0, (const FcChar8 *)file);
1090 OUTPUT:
1091 RETVAL
914 1092
915void 1093void
916load_image_inline (SV *image_) 1094load_image_inline (SV *image_)
917 ALIAS: 1095 ALIAS:
918 load_image_file = 1 1096 load_image_file = 1
1034#if DEBUG 1212#if DEBUG
1035 VALGRIND_DO_LEAK_CHECK; 1213 VALGRIND_DO_LEAK_CHECK;
1036#endif 1214#endif
1037} 1215}
1038 1216
1217int
1218SvREFCNT (SV *sv)
1219 CODE:
1220 RETVAL = SvREFCNT (sv);
1221 OUTPUT:
1222 RETVAL
1223
1039MODULE = Deliantra::Client PACKAGE = DC::Font 1224MODULE = Deliantra::Client PACKAGE = DC::Font
1040 1225
1041PROTOTYPES: DISABLE 1226PROTOTYPES: DISABLE
1042 1227
1043DC::Font 1228DC::Font
1312 1497
1313void 1498void
1314cursor_pos (DC::Layout self, int index) 1499cursor_pos (DC::Layout self, int index)
1315 PPCODE: 1500 PPCODE:
1316{ 1501{
1317 PangoRectangle strong_pos; 1502 PangoRectangle pos;
1318 pango_layout_get_cursor_pos (self->pl, index, &strong_pos, 0); 1503 pango_layout_get_cursor_pos (self->pl, index, &pos, 0);
1319 1504
1320 EXTEND (SP, 3); 1505 EXTEND (SP, 3);
1321 PUSHs (sv_2mortal (newSViv (strong_pos.x / PANGO_SCALE))); 1506 PUSHs (sv_2mortal (newSViv (pos.x / PANGO_SCALE)));
1322 PUSHs (sv_2mortal (newSViv (strong_pos.y / PANGO_SCALE))); 1507 PUSHs (sv_2mortal (newSViv (pos.y / PANGO_SCALE)));
1323 PUSHs (sv_2mortal (newSViv (strong_pos.height / PANGO_SCALE))); 1508 PUSHs (sv_2mortal (newSViv (pos.height / PANGO_SCALE)));
1324} 1509}
1325 1510
1326void 1511void
1327index_to_line_x (DC::Layout self, int index, int trailing = 0) 1512index_to_line_x (DC::Layout self, int index, int trailing = 0)
1328 PPCODE: 1513 PPCODE:
1329{ 1514{
1330 int line, x; 1515 int line, x;
1331 1516
1332 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);
1333#if !(defined (PANGO_VERSION_CHECK) && PANGO_VERSION_CHECK (1, 17, 3)) 1518#if !PANGO_VERSION_CHECK (1, 17, 3)
1334 /* pango bug: line is between 1..numlines, not 0..numlines-1 */ 1519 /* pango bug: line is between 1..numlines, not 0..numlines-1 */
1335 --line; 1520 --line;
1336#endif 1521#endif
1337 EXTEND (SP, 2); 1522 EXTEND (SP, 2);
1338 PUSHs (sv_2mortal (newSViv (line))); 1523 PUSHs (sv_2mortal (newSViv (line)));
1472 if (ix) 1657 if (ix)
1473 { 1658 {
1474 glDisable (GL_ALPHA_TEST); 1659 glDisable (GL_ALPHA_TEST);
1475 glDisable (GL_BLEND); 1660 glDisable (GL_BLEND);
1476 } 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);
1477} 1751}
1478 1752
1479IV 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)
1480 CODE: 1754 CODE:
1481{ 1755{
1587 //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);
1588 // use uglier nearest interpolation because linear suffers 1862 // use uglier nearest interpolation because linear suffers
1589 // from transparent color bleeding and ugly wrapping effects. 1863 // from transparent color bleeding and ugly wrapping effects.
1590 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1864 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1591} 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 }
1592 1886
1593int 1887int
1594ox (DC::Map self) 1888ox (DC::Map self)
1595 ALIAS: 1889 ALIAS:
1596 oy = 1 1890 oy = 1
1674 uint8_t ext, cmd; 1968 uint8_t ext, cmd;
1675 1969
1676 do 1970 do
1677 { 1971 {
1678 ext = *data++; 1972 ext = *data++;
1679 cmd = ext & 0x3f; 1973 cmd = ext & 0x7f;
1680 1974
1681 if (cmd < 4) 1975 if (cmd < 4)
1682 cell->darkness = 255 - ext * 64 + 1; 1976 cell->darkness = 255 - ext * 64 + 1;
1683 else if (cmd == 5) // health 1977 else if (cmd == 5) // health
1684 { 1978 {
1687 } 1981 }
1688 else if (cmd == 6) // monster width 1982 else if (cmd == 6) // monster width
1689 cell->stat_width = *data++ + 1; 1983 cell->stat_width = *data++ + 1;
1690 else if (cmd == 0x47) 1984 else if (cmd == 0x47)
1691 { 1985 {
1692 if (*data == 4) 1986 if (*data == 1) cell->player = data [1];
1693 ; // 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);
1694 1990
1695 data += *data + 1; 1991 data += *data + 1;
1696 } 1992 }
1697 else if (cmd == 8) // cell flags 1993 else if (cmd == 8) // cell flags
1698 cell->flags = *data++; 1994 cell->flags = *data++;
1715 cell->tile [z] = self->face2tile [face]; 2011 cell->tile [z] = self->face2tile [face];
1716 2012
1717 if (cell->tile [z]) 2013 if (cell->tile [z])
1718 { 2014 {
1719 maptex *tex = self->tex + cell->tile [z]; 2015 maptex *tex = self->tex + cell->tile [z];
2016 tex->unused = 0;
1720 if (!tex->name) 2017 if (!tex->name)
1721 av_push (missing, newSViv (cell->tile [z])); 2018 av_push (missing, newSViv (cell->tile [z]));
1722 2019
1723 if (tex->smoothtile) 2020 if (tex->smoothtile)
1724 { 2021 {
1725 maptex *smooth = self->tex + tex->smoothtile; 2022 maptex *smooth = self->tex + tex->smoothtile;
2023 smooth->unused = 0;
1726 if (!smooth->name) 2024 if (!smooth->name)
1727 av_push (missing, newSViv (tex->smoothtile)); 2025 av_push (missing, newSViv (tex->smoothtile));
1728 } 2026 }
1729 } 2027 }
1730 } 2028 }
1731 } 2029 }
1732 else 2030 else
1733 cell->darkness = 0; 2031 CELL_CLEAR (cell);
1734 } 2032 }
1735} 2033}
1736 OUTPUT: 2034 OUTPUT:
1737 RETVAL 2035 RETVAL
1738 2036
1790} 2088}
1791 OUTPUT: 2089 OUTPUT:
1792 RETVAL 2090 RETVAL
1793 2091
1794void 2092void
1795draw (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)
1796 CODE: 2094 CODE:
1797{ 2095{
1798 int x, y, z; 2096 int x, y, z;
1799 2097
1800 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ()); 2098 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
1801 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
1802 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)
1803 smooth_key skey; 2101 smooth_key skey;
1804 2102 int pl_x, pl_y;
2103 maptex pl_tex;
1805 rc_t *rc = rc_alloc (); 2104 rc_t *rc = rc_alloc ();
2105 rc_t *rc_ov = rc_alloc ();
1806 rc_key_t key; 2106 rc_key_t key;
1807 rc_array_t *arr; 2107 rc_array_t *arr, *arr_hidden;
1808 2108
2109 pl_tex.name = 0;
2110
1809 // thats current max. sorry. 2111 // that's current max. sorry.
1810 if (sw > 255) sw = 255; 2112 if (sw > 255) sw = 255;
1811 if (sh > 255) sh = 255; 2113 if (sh > 255) sh = 255;
1812 2114
1813 // clear key, in case of extra padding 2115 // clear key, in case of extra padding
1814 memset (&skey, 0, sizeof (skey)); 2116 memset (&skey, 0, sizeof (skey));
1818 key.g = 255; 2120 key.g = 255;
1819 key.b = 255; 2121 key.b = 255;
1820 key.a = 255; 2122 key.a = 255;
1821 key.mode = GL_QUADS; 2123 key.mode = GL_QUADS;
1822 key.format = GL_T2F_V3F; 2124 key.format = GL_T2F_V3F;
1823 key.texname = -1;
1824 2125
1825 mx += self->x; 2126 mx += self->x;
1826 my += self->y; 2127 my += self->y;
1827 2128
1828 // first pass: determine smooth_max 2129 // first pass: determine smooth_max
1849 2150
1850 glEnable (GL_BLEND); 2151 glEnable (GL_BLEND);
1851 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2152 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1852 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 2153 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1853 2154
2155 key.texname = self->tex [TEXID_HIDDEN].name;
2156 arr_hidden = rc_array (rc_ov, &key);
2157
1854 for (z = 0; z <= 2; z++) 2158 for (z = 0; z <= 2; z++)
1855 { 2159 {
1856 memset (smooth_level, 0, sizeof (smooth_level)); 2160 memset (smooth_level, 0, sizeof (smooth_level));
2161 key.texname = -1;
1857 2162
1858 for (y = 0; y < sh; y++) 2163 for (y = 0; y < sh; y++)
1859 if (0 <= y + my && y + my < self->rows) 2164 if (0 <= y + my && y + my < self->rows)
1860 { 2165 {
1861 maprow *row = self->row + (y + my); 2166 maprow *row = self->row + (y + my);
1871 maptex tex = self->tex [tile]; 2176 maptex tex = self->tex [tile];
1872 int px, py; 2177 int px, py;
1873 2178
1874 if (key.texname != tex.name) 2179 if (key.texname != tex.name)
1875 { 2180 {
2181 self->tex [tile].unused = 0;
2182
1876 if (!tex.name) 2183 if (!tex.name)
1877 tex = self->tex [2]; /* missing, replace by noface */ 2184 tex = self->tex [TEXID_NOFACE]; /* missing, replace by noface */
1878 2185
1879 key.texname = tex.name; 2186 key.texname = tex.name;
1880 arr = rc_array (rc, &key); 2187 arr = rc_array (rc, &key);
1881 } 2188 }
1882 2189
1883 px = (x + 1) * T - tex.w; 2190 px = (x + 1) * T - tex.w;
1884 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 }
1885 2200
1886 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2201 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
1887 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);
1888 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);
1889 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);
1890
1891 if (cell->flags && z == 2)
1892 {
1893 // overlays such as the speech bubble, probably more to come
1894 if (cell->flags & 1)
1895 {
1896 maptex tex = self->tex [1];
1897 int px = x * T + T * 2 / 32;
1898 int py = y * T - T * 6 / 32;
1899
1900 if (tex.name)
1901 {
1902 if (key.texname != tex.name)
1903 {
1904 key.texname = tex.name;
1905 arr = rc_array (rc, &key);
1906 }
1907
1908 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
1909 rc_t2f_v3f (arr, 0 , tex.t, px , py + T, 0);
1910 rc_t2f_v3f (arr, tex.s, tex.t, px + T, py + T, 0);
1911 rc_t2f_v3f (arr, tex.s, 0 , px + T, py , 0);
1912 }
1913 }
1914 }
1915 2205
1916 // update smooth hash 2206 // update smooth hash
1917 if (tex.smoothtile) 2207 if (tex.smoothtile)
1918 { 2208 {
1919 skey.tile = tex.smoothtile; 2209 skey.tile = tex.smoothtile;
1948 // corners 2238 // corners
1949 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);
1950 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);
1951 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);
1952 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 }
1953 } 2280 }
1954 } 2281 }
1955 } 2282 }
1956 } 2283 }
1957 2284
1997 { 2324 {
1998 // this time avoiding texture state changes 2325 // this time avoiding texture state changes
1999 // save gobs of state changes. 2326 // save gobs of state changes.
2000 if (key.texname != tex.name) 2327 if (key.texname != tex.name)
2001 { 2328 {
2329 self->tex [skey->tile].unused = 0;
2330
2002 glEnd (); 2331 glEnd ();
2003 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name); 2332 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name);
2004 glBegin (GL_QUADS); 2333 glBegin (GL_QUADS);
2005 } 2334 }
2006 2335
2035 } 2364 }
2036 2365
2037 hv_clear (smooth); 2366 hv_clear (smooth);
2038 } 2367 }
2039 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
2040 glDisable (GL_BLEND); 2389 glDisable (GL_BLEND);
2041 rc_free (rc); 2390 rc_free (rc);
2391 rc_free (rc_ov);
2042 2392
2043 // top layer: overlays such as the health bar 2393 // top layer: overlays such as the health bar
2044 for (y = 0; y < sh; y++) 2394 for (y = 0; y < sh; y++)
2045 if (0 <= y + my && y + my < self->rows) 2395 if (0 <= y + my && y + my < self->rows)
2046 { 2396 {
2051 { 2401 {
2052 mapcell *cell = row->col + (x + mx - row->c0); 2402 mapcell *cell = row->col + (x + mx - row->c0);
2053 2403
2054 int px = x * T; 2404 int px = x * T;
2055 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 }
2056 2412
2057 if (cell->stat_hp) 2413 if (cell->stat_hp)
2058 { 2414 {
2059 int width = cell->stat_width * T; 2415 int width = cell->stat_width * T;
2060 int thick = (sh * T / 32 + 27) / 28 + 1 + cell->stat_width; 2416 int thick = (sh * T / 32 + 27) / 28 + 1 + cell->stat_width;
2100 }; 2456 };
2101 2457
2102 int x, y; 2458 int x, y;
2103 2459
2104 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 */
2105 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 2467 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
2106 glEnable (GL_BLEND); 2468 glEnable (GL_BLEND);
2107 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2469 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2108 glBegin (GL_QUADS); 2470 glBegin (GL_QUADS);
2109 2471
2110 for (y = 0; y < h; y++) 2472 for (y = 0; y < h; y++)
2117 float *c = color [m & 15]; 2479 float *c = color [m & 15];
2118 2480
2119 float tx1 = m & 0x40 ? 0.5 : 0.; 2481 float tx1 = m & 0x40 ? 0.5 : 0.;
2120 float tx2 = tx1 + 0.5; 2482 float tx2 = tx1 + 0.5;
2121 2483
2122 glColor4f (c[0], c[1], c[2], 0.75); 2484 glColor4f (c[0], c[1], c[2], 1);
2123 glTexCoord2f (tx1, 0.); glVertex2i (x , y ); 2485 glTexCoord2f (tx1, 0.); glVertex2i (x , y );
2124 glTexCoord2f (tx1, 1.); glVertex2i (x , y + 1); 2486 glTexCoord2f (tx1, 1.); glVertex2i (x , y + 1);
2125 glTexCoord2f (tx2, 1.); glVertex2i (x + 1, y + 1); 2487 glTexCoord2f (tx2, 1.); glVertex2i (x + 1, y + 1);
2126 glTexCoord2f (tx2, 0.); glVertex2i (x + 1, y ); 2488 glTexCoord2f (tx2, 0.); glVertex2i (x + 1, y );
2127 } 2489 }
2149 SvCUR_set (darkness3_sv, sw34 * sh3); 2511 SvCUR_set (darkness3_sv, sw34 * sh3);
2150 2512
2151 mx += self->x - 1; 2513 mx += self->x - 1;
2152 my += self->y - 1; 2514 my += self->y - 1;
2153 2515
2154 memset (darkness1, 255, sw1 * sh1); 2516 memset (darkness1, DARKNESS_ADJUST (255 - FOW_DARKNESS), sw1 * sh1);
2155 2517
2156 for (y = 0; y < sh1; y++) 2518 for (y = 0; y < sh1; y++)
2157 if (0 <= y + my && y + my < self->rows) 2519 if (0 <= y + my && y + my < self->rows)
2158 { 2520 {
2159 maprow *row = self->row + (y + my); 2521 maprow *row = self->row + (y + my);
2162 if (row->c0 <= x + mx && x + mx < row->c1) 2524 if (row->c0 <= x + mx && x + mx < row->c1)
2163 { 2525 {
2164 mapcell *cell = row->col + (x + mx - row->c0); 2526 mapcell *cell = row->col + (x + mx - row->c0);
2165 2527
2166 darkness1 [y * sw1 + x] = cell->darkness 2528 darkness1 [y * sw1 + x] = cell->darkness
2167 ? 255 - (cell->darkness - 1) 2529 ? DARKNESS_ADJUST (255 - (cell->darkness - 1))
2168 : 255 - FOW_DARKNESS; 2530 : DARKNESS_ADJUST (255 - FOW_DARKNESS);
2169 } 2531 }
2170 } 2532 }
2171 2533
2172 for (y = 0; y < sh; ++y) 2534 for (y = 0; y < sh; ++y)
2173 for (x = 0; x < sw; ++x) 2535 for (x = 0; x < sw; ++x)
2279 else 2641 else
2280 *data++ = 0; 2642 *data++ = 0;
2281 } 2643 }
2282 } 2644 }
2283 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 {
2284 SvPOK_only (data_sv); 2649 SvPOK_only (data_sv);
2285 SvCUR_set (data_sv, data - (uint8_t *)SvPVX (data_sv)); 2650 SvCUR_set (data_sv, data - (uint8_t *)SvPVX (data_sv));
2651 }
2652
2286 RETVAL = data_sv; 2653 RETVAL = data_sv;
2287} 2654}
2288 OUTPUT: 2655 OUTPUT:
2289 RETVAL 2656 RETVAL
2290 2657
2291void 2658void
2292set_rect (DC::Map self, int x0, int y0, uint8_t *data) 2659set_rect (DC::Map self, int x0, int y0, SV *data_sv)
2293 PPCODE: 2660 PPCODE:
2294{ 2661{
2295 int x, y, z; 2662 int x, y, z;
2296 int w, h; 2663 int w, h;
2297 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;
2298 2675
2299 if (*data++ != 0) 2676 if (*data++ != 0)
2300 XSRETURN_EMPTY; /* version mismatch */ 2677 XSRETURN_EMPTY; /* version mismatch */
2301 2678
2302 w = *data++ << 8; w |= *data++; 2679 w = *data++ << 8; w |= *data++;
2317 { 2694 {
2318 maprow *row = map_get_row (self, y); 2695 maprow *row = map_get_row (self, y);
2319 2696
2320 for (x = x0; x < x1; x++) 2697 for (x = x0; x < x1; x++)
2321 { 2698 {
2699 uint8_t flags;
2700
2701 if (data + 7 >= end)
2702 XSRETURN_EMPTY;
2703
2322 uint8_t flags = *data++; 2704 flags = *data++;
2323 2705
2324 if (flags) 2706 if (flags)
2325 { 2707 {
2326 mapcell *cell = row_get_cell (row, x); 2708 mapcell *cell = row_get_cell (row, x);
2327 tileid tile[3] = { 0, 0, 0 }; 2709 tileid tile[3] = { 0, 0, 0 };
2330 if (flags & 2) { tile[1] = *data++ << 8; tile[1] |= *data++; } 2712 if (flags & 2) { tile[1] = *data++ << 8; tile[1] |= *data++; }
2331 if (flags & 4) { tile[2] = *data++ << 8; tile[2] |= *data++; } 2713 if (flags & 4) { tile[2] = *data++ << 8; tile[2] |= *data++; }
2332 2714
2333 if (cell->darkness == 0) 2715 if (cell->darkness == 0)
2334 { 2716 {
2335 cell->darkness = 0; 2717 /*cell->darkness = 0;*/
2718 EXTEND (SP, 3);
2336 2719
2337 for (z = 0; z <= 2; z++) 2720 for (z = 0; z <= 2; z++)
2338 { 2721 {
2339 tileid t = tile [z]; 2722 tileid t = tile [z];
2340 2723
2341 if (t >= self->texs || (t && !self->tex [t].name)) 2724 if (t >= self->texs || (t && !self->tex [t].name))
2342 { 2725 {
2343 XPUSHs (sv_2mortal (newSViv (t))); 2726 PUSHs (sv_2mortal (newSViv (t)));
2344 need_texid (self, t); 2727 need_texid (self, t);
2345 } 2728 }
2346 2729
2347 cell->tile [z] = t; 2730 cell->tile [z] = t;
2348 } 2731 }
2565 } *civ, const_iv[] = { 2948 } *civ, const_iv[] = {
2566# define const_iv(name) { # name, (IV)name } 2949# define const_iv(name) { # name, (IV)name }
2567 const_iv (GL_VENDOR), 2950 const_iv (GL_VENDOR),
2568 const_iv (GL_VERSION), 2951 const_iv (GL_VERSION),
2569 const_iv (GL_EXTENSIONS), 2952 const_iv (GL_EXTENSIONS),
2953 const_iv (GL_MAX_TEXTURE_UNITS),
2570 const_iv (GL_COLOR_MATERIAL), 2954 const_iv (GL_COLOR_MATERIAL),
2571 const_iv (GL_SMOOTH), 2955 const_iv (GL_SMOOTH),
2572 const_iv (GL_FLAT), 2956 const_iv (GL_FLAT),
2573 const_iv (GL_DITHER), 2957 const_iv (GL_DITHER),
2574 const_iv (GL_BLEND), 2958 const_iv (GL_BLEND),
2586 const_iv (GL_ZERO), 2970 const_iv (GL_ZERO),
2587 const_iv (GL_SRC_ALPHA), 2971 const_iv (GL_SRC_ALPHA),
2588 const_iv (GL_DST_ALPHA), 2972 const_iv (GL_DST_ALPHA),
2589 const_iv (GL_ONE_MINUS_SRC_ALPHA), 2973 const_iv (GL_ONE_MINUS_SRC_ALPHA),
2590 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),
2591 const_iv (GL_SRC_ALPHA_SATURATE), 2979 const_iv (GL_SRC_ALPHA_SATURATE),
2592 const_iv (GL_RGB), 2980 const_iv (GL_RGB),
2593 const_iv (GL_RGBA), 2981 const_iv (GL_RGBA),
2594 const_iv (GL_RGBA4), 2982 const_iv (GL_RGBA4),
2595 const_iv (GL_RGBA8), 2983 const_iv (GL_RGBA8),
2663 const_iv (GL_NICEST), 3051 const_iv (GL_NICEST),
2664 const_iv (GL_V2F), 3052 const_iv (GL_V2F),
2665 const_iv (GL_V3F), 3053 const_iv (GL_V3F),
2666 const_iv (GL_T2F_V3F), 3054 const_iv (GL_T2F_V3F),
2667 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),
2668# undef const_iv 3059# undef const_iv
2669 }; 3060 };
2670 3061
2671 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; )
2672 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 3063 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
2679disable_GL_EXT_blend_func_separate () 3070disable_GL_EXT_blend_func_separate ()
2680 CODE: 3071 CODE:
2681 gl.BlendFuncSeparate = 0; 3072 gl.BlendFuncSeparate = 0;
2682 gl.BlendFuncSeparateEXT = 0; 3073 gl.BlendFuncSeparateEXT = 0;
2683 3074
3075void
3076apple_nvidia_bug (int enable)
3077
2684char * 3078char *
2685gl_vendor () 3079gl_vendor ()
2686 CODE: 3080 CODE:
2687 RETVAL = (char *)glGetString (GL_VENDOR); 3081 RETVAL = (char *)glGetString (GL_VENDOR);
2688 OUTPUT: 3082 OUTPUT:
2737 3131
2738void glBlendFuncSeparate (int sa, int da, int saa, int daa) 3132void glBlendFuncSeparate (int sa, int da, int saa, int daa)
2739 CODE: 3133 CODE:
2740 gl_BlendFuncSeparate (sa, da, saa, daa); 3134 gl_BlendFuncSeparate (sa, da, saa, daa);
2741 3135
3136# void glBlendEquation (int se)
3137
2742void glDepthMask (int flag) 3138void glDepthMask (int flag)
2743 3139
2744void glLogicOp (int opcode) 3140void glLogicOp (int opcode)
2745 3141
2746void glColorMask (int red, int green, int blue, int alpha) 3142void glColorMask (int red, int green, int blue, int alpha)
2780void glRotate (float angle, float x, float y, float z) 3176void glRotate (float angle, float x, float y, float z)
2781 CODE: 3177 CODE:
2782 glRotatef (angle, x, y, z); 3178 glRotatef (angle, x, y, z);
2783 3179
2784void 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: @
2785 ALIAS: 3182 ALIAS:
2786 glColor_premultiply = 1 3183 glColor_premultiply = 1
2787 CODE: 3184 CODE:
2788 if (ix) 3185 if (ix)
2789 { 3186 {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines