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.245 by root, Fri Dec 28 15:05:20 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>
55
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)
61# define pango_layout_get_line_readonly pango_layout_get_line
62# define pango_layout_get_lines_readonly pango_layout_get_lines
63# define pango_layout_iter_get_line_readonly pango_layout_iter_get_line
64# define pango_layout_iter_get_run_readonly pango_layout_iter_get_run
65#endif
50 66
51#ifndef _WIN32 67#ifndef _WIN32
52# include <sys/types.h> 68# include <sys/types.h>
53# include <sys/socket.h> 69# include <sys/socket.h>
54# include <netinet/in.h> 70# include <netinet/in.h>
55# include <netinet/tcp.h> 71# include <netinet/tcp.h>
56# include <inttypes.h> 72# include <inttypes.h>
57#endif 73#endif
58 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
59#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, object replacement character */ 84#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, object replacement character */
60 85
61#define FOW_DARKNESS 32 86#define FOW_DARKNESS 64
87#define DARKNESS_ADJUST(n) ((29 * (int)(n)) >> 5) /* times 0.9 */
62 88
63#define MAP_EXTEND_X 32 89#define MAP_EXTEND_X 32
64#define MAP_EXTEND_Y 512 90#define MAP_EXTEND_Y 512
65 91
66#define MIN_FONT_HEIGHT 10 92#define MIN_FONT_HEIGHT 10
67 93
68#if 0 94/* mask out modifiers we are not interested in */
69# define PARACHUTE SDL_INIT_NOPARACHUTE 95#define MOD_MASK (KMOD_CTRL | KMOD_SHIFT | KMOD_ALT | KMOD_META)
70#else 96
71# define PARACHUTE 0 97#define KMOD_LRAM 0x10000 // our extension
72#endif 98
99#define TEXID_SPEECH 1
100#define TEXID_NOFACE 2
101#define TEXID_HIDDEN 3
73 102
74static AV *texture_av; 103static AV *texture_av;
75 104
76static struct 105static struct
77{ 106{
171 200
172static void 201static void
173layout_update_font (DC__Layout self) 202layout_update_font (DC__Layout self)
174{ 203{
175 /* 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
176 * reasonably well with bitstream vera 205 * reasonably well with dejavu/bistream fonts
177 */ 206 */
178 PangoFontDescription *font = self->font ? self->font : default_font; 207 PangoFontDescription *font = self->font ? self->font : default_font;
179 208
180 pango_font_description_set_absolute_size (font, 209 pango_font_description_set_absolute_size (font,
181 MAX (MIN_FONT_HEIGHT, self->base_height) * (PANGO_SCALE * 8 / 10)); 210 MAX (MIN_FONT_HEIGHT, self->base_height) * (PANGO_SCALE * 8 / 10));
209 int w, h; 238 int w, h;
210 float s, t; 239 float s, t;
211 uint8_t r, g, b, a; 240 uint8_t r, g, b, a;
212 tileid smoothtile; 241 tileid smoothtile;
213 uint8_t smoothlevel; 242 uint8_t smoothlevel;
243 uint8_t unused; /* set to zero on use */
214} maptex; 244} maptex;
215 245
216typedef struct { 246typedef struct {
217 uint32_t player; 247 uint32_t player;
218 tileid tile[3]; 248 tileid tile[3];
350 self->oy = 0; 380 self->oy = 0;
351 self->row = 0; 381 self->row = 0;
352 self->rows = 0; 382 self->rows = 0;
353} 383}
354 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
355static void 395static void
356map_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)
357{ 397{
358 int x, y; 398 int x, y;
359 maprow *row; 399 maprow *row;
373 if (x >= row->c1) 413 if (x >= row->c1)
374 break; 414 break;
375 415
376 cell = row->col + x - row->c0; 416 cell = row->col + x - row->c0;
377 417
378 cell->darkness = 0; 418 CELL_CLEAR (cell);
379 cell->stat_hp = 0;
380 cell->flags = 0;
381 cell->player = 0;
382 } 419 }
383 } 420 }
384} 421}
385 422
386typedef struct { 423typedef struct {
497 if (!svp || !SvTRUE (*svp)) 534 if (!svp || !SvTRUE (*svp))
498 return 0; 535 return 0;
499 536
500 return 1; 537 return 1;
501} 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
502 591
503MODULE = Deliantra::Client PACKAGE = DC 592MODULE = Deliantra::Client PACKAGE = DC
504 593
505PROTOTYPES: ENABLE 594PROTOTYPES: ENABLE
506 595
535 const_iv (SDL_USEREVENT), 624 const_iv (SDL_USEREVENT),
536 625
537 const_iv (SDL_APPINPUTFOCUS), 626 const_iv (SDL_APPINPUTFOCUS),
538 const_iv (SDL_APPMOUSEFOCUS), 627 const_iv (SDL_APPMOUSEFOCUS),
539 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),
540 679
541 const_iv (SDLK_FIRST), 680 const_iv (SDLK_FIRST),
542 const_iv (SDLK_LAST), 681 const_iv (SDLK_LAST),
543 const_iv (SDLK_KP0), 682 const_iv (SDLK_KP0),
544 const_iv (SDLK_KP1), 683 const_iv (SDLK_KP1),
620 const_iv (KMOD_RMETA), 759 const_iv (KMOD_RMETA),
621 const_iv (KMOD_NUM), 760 const_iv (KMOD_NUM),
622 const_iv (KMOD_CAPS), 761 const_iv (KMOD_CAPS),
623 const_iv (KMOD_MODE), 762 const_iv (KMOD_MODE),
624 763
764 const_iv (KMOD_LRAM),
765
625 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)
626# undef const_iv 796# undef const_iv
627 }; 797 };
628 798
629 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; )
630 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 800 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
659 CODE: 829 CODE:
660{ 830{
661 opengl_fontmap = pango_opengl_font_map_new (); 831 opengl_fontmap = pango_opengl_font_map_new ();
662 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);
663 opengl_context = pango_opengl_font_map_create_context ((PangoOpenGLFontMap *)opengl_fontmap); 833 opengl_context = pango_opengl_font_map_create_context ((PangoOpenGLFontMap *)opengl_fontmap);
834 /*pango_context_set_font_description (opengl_context, default_font);*/
835#if PANGO_VERSION_CHECK (1, 15, 2)
836 pango_context_set_language (opengl_context, pango_language_from_string ("en"));
837 /*pango_context_set_base_dir (opengl_context, PANGO_DIRECTION_WEAK_LTR);*/
838#endif
664} 839}
665 840
666char *
667SDL_GetError () 841char *SDL_GetError ()
668 842
669int 843void SDL_braino ()
670SDL_Init (U32 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | PARACHUTE)
671 844
672void 845int SDL_Init (U32 flags)
846
847int SDL_InitSubSystem (U32 flags)
848
849void SDL_QuitSubSystem (U32 flags)
850
673SDL_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
674 861
675void 862void
676SDL_ListModes (int rgb, int alpha) 863SDL_ListModes (int rgb, int alpha)
677 PPCODE: 864 PPCODE:
678{ 865{
690 SDL_GL_SetAttribute (SDL_GL_ACCUM_GREEN_SIZE, 0); 877 SDL_GL_SetAttribute (SDL_GL_ACCUM_GREEN_SIZE, 0);
691 SDL_GL_SetAttribute (SDL_GL_ACCUM_BLUE_SIZE , 0); 878 SDL_GL_SetAttribute (SDL_GL_ACCUM_BLUE_SIZE , 0);
692 SDL_GL_SetAttribute (SDL_GL_ACCUM_ALPHA_SIZE, 0); 879 SDL_GL_SetAttribute (SDL_GL_ACCUM_ALPHA_SIZE, 0);
693 880
694 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); 881 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
695#if SDL_VERSION_ATLEAST(1,2,10)
696 SDL_GL_SetAttribute (SDL_GL_ACCELERATED_VISUAL, 1);
697 SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 1); 882 SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 1);
698#endif
699 883
700 m = SDL_ListModes (0, SDL_FULLSCREEN | SDL_OPENGL); 884 m = SDL_ListModes (0, SDL_FULLSCREEN | SDL_OPENGL);
701 885
702 if (m && m != (SDL_Rect **)-1) 886 if (m && m != (SDL_Rect **)-1)
703 while (*m) 887 while (*m)
704 { 888 {
705 if ((*m)->w >= 800 && (*m)->h >= 480) 889 if ((*m)->w >= 400 && (*m)->h >= 300)
706 { 890 {
707 AV *av = newAV (); 891 AV *av = newAV ();
708 av_push (av, newSViv ((*m)->w)); 892 av_push (av, newSViv ((*m)->w));
709 av_push (av, newSViv ((*m)->h)); 893 av_push (av, newSViv ((*m)->h));
710 av_push (av, newSViv (rgb)); 894 av_push (av, newSViv (rgb));
752SDL_GetKeyName (int sym) 936SDL_GetKeyName (int sym)
753 937
754int 938int
755SDL_GetAppState () 939SDL_GetAppState ()
756 940
941int
942SDL_GetModState ()
943
757void 944void
758poll_events () 945poll_events ()
759 PPCODE: 946 PPCODE:
760{ 947{
761 SDL_Event ev; 948 SDL_Event ev;
770 { 957 {
771 case SDL_KEYDOWN: 958 case SDL_KEYDOWN:
772 case SDL_KEYUP: 959 case SDL_KEYUP:
773 hv_store (hv, "state", 5, newSViv (ev.key.state), 0); 960 hv_store (hv, "state", 5, newSViv (ev.key.state), 0);
774 hv_store (hv, "sym", 3, newSViv (ev.key.keysym.sym), 0); 961 hv_store (hv, "sym", 3, newSViv (ev.key.keysym.sym), 0);
775 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);
776 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 */
777 hv_store (hv, "unicode", 7, newSViv (ev.key.keysym.unicode), 0); 964 hv_store (hv, "unicode", 7, newSViv (ev.key.keysym.unicode), 0);
778 break; 965 break;
779 966
780 case SDL_ACTIVEEVENT: 967 case SDL_ACTIVEEVENT:
781 hv_store (hv, "gain", 4, newSViv (ev.active.gain), 0); 968 hv_store (hv, "gain", 4, newSViv (ev.active.gain), 0);
799 x = ev.motion.x; 986 x = ev.motion.x;
800 y = ev.motion.y; 987 y = ev.motion.y;
801 SDL_PeepEvents (&ev, 1, SDL_GETEVENT, SDL_EVENTMASK (SDL_MOUSEMOTION)); 988 SDL_PeepEvents (&ev, 1, SDL_GETEVENT, SDL_EVENTMASK (SDL_MOUSEMOTION));
802 } 989 }
803 990
804 hv_store (hv, "mod", 3, newSViv (SDL_GetModState ()), 0); 991 hv_store (hv, "mod", 3, newSViv (mod_munge (SDL_GetModState ())), 0);
805 hv_store (hv, "state", 5, newSViv (state), 0); 992 hv_store (hv, "state", 5, newSViv (state), 0);
806 hv_store (hv, "x", 1, newSViv (x), 0); 993 hv_store (hv, "x", 1, newSViv (x), 0);
807 hv_store (hv, "y", 1, newSViv (y), 0); 994 hv_store (hv, "y", 1, newSViv (y), 0);
808 hv_store (hv, "xrel", 4, newSViv (xrel), 0); 995 hv_store (hv, "xrel", 4, newSViv (xrel), 0);
809 hv_store (hv, "yrel", 4, newSViv (yrel), 0); 996 hv_store (hv, "yrel", 4, newSViv (yrel), 0);
810 } 997 }
811 break; 998 break;
812 999
813 case SDL_MOUSEBUTTONDOWN: 1000 case SDL_MOUSEBUTTONDOWN:
814 case SDL_MOUSEBUTTONUP: 1001 case SDL_MOUSEBUTTONUP:
815 hv_store (hv, "mod", 3, newSViv (SDL_GetModState ()), 0); 1002 hv_store (hv, "mod", 3, newSViv (SDL_GetModState () & MOD_MASK), 0);
816 1003
817 hv_store (hv, "button", 6, newSViv (ev.button.button), 0); 1004 hv_store (hv, "button", 6, newSViv (ev.button.button), 0);
818 hv_store (hv, "state", 5, newSViv (ev.button.state), 0); 1005 hv_store (hv, "state", 5, newSViv (ev.button.state), 0);
819 hv_store (hv, "x", 1, newSViv (ev.button.x), 0); 1006 hv_store (hv, "x", 1, newSViv (ev.button.x), 0);
820 hv_store (hv, "y", 1, newSViv (ev.button.y), 0); 1007 hv_store (hv, "y", 1, newSViv (ev.button.y), 0);
894 } 1081 }
895 } 1082 }
896#endif 1083#endif
897} 1084}
898 1085
899void 1086int
900add_font (char *file) 1087add_font (char *file)
901 CODE: 1088 CODE:
902 FcConfigAppFontAddFile (0, (const FcChar8 *)file); 1089 RETVAL = FcConfigAppFontAddFile (0, (const FcChar8 *)file);
1090 OUTPUT:
1091 RETVAL
903 1092
904void 1093void
905load_image_inline (SV *image_) 1094load_image_inline (SV *image_)
906 ALIAS: 1095 ALIAS:
907 load_image_file = 1 1096 load_image_file = 1
1023#if DEBUG 1212#if DEBUG
1024 VALGRIND_DO_LEAK_CHECK; 1213 VALGRIND_DO_LEAK_CHECK;
1025#endif 1214#endif
1026} 1215}
1027 1216
1217int
1218SvREFCNT (SV *sv)
1219 CODE:
1220 RETVAL = SvREFCNT (sv);
1221 OUTPUT:
1222 RETVAL
1223
1028MODULE = Deliantra::Client PACKAGE = DC::Font 1224MODULE = Deliantra::Client PACKAGE = DC::Font
1029 1225
1030PROTOTYPES: DISABLE 1226PROTOTYPES: DISABLE
1031 1227
1032DC::Font 1228DC::Font
1165{ 1361{
1166 PangoLayoutIter *iter = pango_layout_get_iter (self->pl); 1362 PangoLayoutIter *iter = pango_layout_get_iter (self->pl);
1167 1363
1168 do 1364 do
1169 { 1365 {
1170 PangoLayoutRun *run = pango_layout_iter_get_run (iter); 1366 PangoLayoutRun *run = pango_layout_iter_get_run_readonly (iter);
1171 1367
1172 if (run && shape_attr_p (run)) 1368 if (run && shape_attr_p (run))
1173 { 1369 {
1174 PangoRectangle extents; 1370 PangoRectangle extents;
1175 pango_layout_iter_get_run_extents (iter, 0, &extents); 1371 pango_layout_iter_get_run_extents (iter, 0, &extents);
1279int 1475int
1280descent (DC::Layout self) 1476descent (DC::Layout self)
1281 CODE: 1477 CODE:
1282{ 1478{
1283 PangoRectangle rect; 1479 PangoRectangle rect;
1284 PangoLayoutLine *line = pango_layout_get_line (self->pl, 0); 1480 PangoLayoutLine *line = pango_layout_get_line_readonly (self->pl, 0);
1285 pango_layout_line_get_pixel_extents (line, 0, &rect); 1481 pango_layout_line_get_pixel_extents (line, 0, &rect);
1286 RETVAL = PANGO_DESCENT (rect); 1482 RETVAL = PANGO_DESCENT (rect);
1287} 1483}
1288 OUTPUT: 1484 OUTPUT:
1289 RETVAL 1485 RETVAL
1301 1497
1302void 1498void
1303cursor_pos (DC::Layout self, int index) 1499cursor_pos (DC::Layout self, int index)
1304 PPCODE: 1500 PPCODE:
1305{ 1501{
1306 PangoRectangle strong_pos; 1502 PangoRectangle pos;
1307 pango_layout_get_cursor_pos (self->pl, index, &strong_pos, 0); 1503 pango_layout_get_cursor_pos (self->pl, index, &pos, 0);
1308 1504
1309 EXTEND (SP, 3); 1505 EXTEND (SP, 3);
1310 PUSHs (sv_2mortal (newSViv (strong_pos.x / PANGO_SCALE))); 1506 PUSHs (sv_2mortal (newSViv (pos.x / PANGO_SCALE)));
1311 PUSHs (sv_2mortal (newSViv (strong_pos.y / PANGO_SCALE))); 1507 PUSHs (sv_2mortal (newSViv (pos.y / PANGO_SCALE)));
1312 PUSHs (sv_2mortal (newSViv (strong_pos.height / PANGO_SCALE))); 1508 PUSHs (sv_2mortal (newSViv (pos.height / PANGO_SCALE)));
1313} 1509}
1314 1510
1315void 1511void
1316index_to_line_x (DC::Layout self, int index, int trailing = 0) 1512index_to_line_x (DC::Layout self, int index, int trailing = 0)
1317 PPCODE: 1513 PPCODE:
1318{ 1514{
1319 int line, x; 1515 int line, x;
1320 1516
1321 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);
1322
1323#if !PANGO_VERSION_CHECK (1, 17. 3) 1518#if !PANGO_VERSION_CHECK (1, 17, 3)
1324 /* pango bug: line is between 1..numlines, not 0..numlines-1 */ 1519 /* pango bug: line is between 1..numlines, not 0..numlines-1 */
1325 --line; 1520 --line;
1326#endif 1521#endif
1327
1328 EXTEND (SP, 2); 1522 EXTEND (SP, 2);
1329 PUSHs (sv_2mortal (newSViv (line))); 1523 PUSHs (sv_2mortal (newSViv (line)));
1330 PUSHs (sv_2mortal (newSViv (x / PANGO_SCALE))); 1524 PUSHs (sv_2mortal (newSViv (x / PANGO_SCALE)));
1331} 1525}
1332 1526
1338 int index, trailing; 1532 int index, trailing;
1339 1533
1340 if (line < 0) 1534 if (line < 0)
1341 XSRETURN_EMPTY; 1535 XSRETURN_EMPTY;
1342 1536
1343 if (!(lp = pango_layout_get_line (self->pl, line))) 1537 if (!(lp = pango_layout_get_line_readonly (self->pl, line)))
1344 XSRETURN_EMPTY; /* do better */ 1538 XSRETURN_EMPTY; /* do better */
1345 1539
1346 pango_layout_line_x_to_index (lp, x * PANGO_SCALE, &index, &trailing); 1540 pango_layout_line_x_to_index (lp, x * PANGO_SCALE, &index, &trailing);
1347 1541
1348 EXTEND (SP, 2); 1542 EXTEND (SP, 2);
1463 if (ix) 1657 if (ix)
1464 { 1658 {
1465 glDisable (GL_ALPHA_TEST); 1659 glDisable (GL_ALPHA_TEST);
1466 glDisable (GL_BLEND); 1660 glDisable (GL_BLEND);
1467 } 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);
1468} 1751}
1469 1752
1470IV 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)
1471 CODE: 1754 CODE:
1472{ 1755{
1578 //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);
1579 // use uglier nearest interpolation because linear suffers 1862 // use uglier nearest interpolation because linear suffers
1580 // from transparent color bleeding and ugly wrapping effects. 1863 // from transparent color bleeding and ugly wrapping effects.
1581 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1864 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1582} 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 }
1583 1886
1584int 1887int
1585ox (DC::Map self) 1888ox (DC::Map self)
1586 ALIAS: 1889 ALIAS:
1587 oy = 1 1890 oy = 1
1665 uint8_t ext, cmd; 1968 uint8_t ext, cmd;
1666 1969
1667 do 1970 do
1668 { 1971 {
1669 ext = *data++; 1972 ext = *data++;
1670 cmd = ext & 0x3f; 1973 cmd = ext & 0x7f;
1671 1974
1672 if (cmd < 4) 1975 if (cmd < 4)
1673 cell->darkness = 255 - ext * 64 + 1; 1976 cell->darkness = 255 - ext * 64 + 1;
1674 else if (cmd == 5) // health 1977 else if (cmd == 5) // health
1675 { 1978 {
1678 } 1981 }
1679 else if (cmd == 6) // monster width 1982 else if (cmd == 6) // monster width
1680 cell->stat_width = *data++ + 1; 1983 cell->stat_width = *data++ + 1;
1681 else if (cmd == 0x47) 1984 else if (cmd == 0x47)
1682 { 1985 {
1683 if (*data == 4) 1986 if (*data == 1) cell->player = data [1];
1684 ; // 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);
1685 1990
1686 data += *data + 1; 1991 data += *data + 1;
1687 } 1992 }
1688 else if (cmd == 8) // cell flags 1993 else if (cmd == 8) // cell flags
1689 cell->flags = *data++; 1994 cell->flags = *data++;
1706 cell->tile [z] = self->face2tile [face]; 2011 cell->tile [z] = self->face2tile [face];
1707 2012
1708 if (cell->tile [z]) 2013 if (cell->tile [z])
1709 { 2014 {
1710 maptex *tex = self->tex + cell->tile [z]; 2015 maptex *tex = self->tex + cell->tile [z];
2016 tex->unused = 0;
1711 if (!tex->name) 2017 if (!tex->name)
1712 av_push (missing, newSViv (cell->tile [z])); 2018 av_push (missing, newSViv (cell->tile [z]));
1713 2019
1714 if (tex->smoothtile) 2020 if (tex->smoothtile)
1715 { 2021 {
1716 maptex *smooth = self->tex + tex->smoothtile; 2022 maptex *smooth = self->tex + tex->smoothtile;
2023 smooth->unused = 0;
1717 if (!smooth->name) 2024 if (!smooth->name)
1718 av_push (missing, newSViv (tex->smoothtile)); 2025 av_push (missing, newSViv (tex->smoothtile));
1719 } 2026 }
1720 } 2027 }
1721 } 2028 }
1722 } 2029 }
1723 else 2030 else
1724 cell->darkness = 0; 2031 CELL_CLEAR (cell);
1725 } 2032 }
1726} 2033}
1727 OUTPUT: 2034 OUTPUT:
1728 RETVAL 2035 RETVAL
1729 2036
1781} 2088}
1782 OUTPUT: 2089 OUTPUT:
1783 RETVAL 2090 RETVAL
1784 2091
1785void 2092void
1786draw (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)
1787 CODE: 2094 CODE:
1788{ 2095{
1789 int x, y, z; 2096 int x, y, z;
1790 2097
1791 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ()); 2098 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
1792 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
1793 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)
1794 smooth_key skey; 2101 smooth_key skey;
1795 2102 int pl_x, pl_y;
2103 maptex pl_tex;
1796 rc_t *rc = rc_alloc (); 2104 rc_t *rc = rc_alloc ();
2105 rc_t *rc_ov = rc_alloc ();
1797 rc_key_t key; 2106 rc_key_t key;
1798 rc_array_t *arr; 2107 rc_array_t *arr, *arr_hidden;
1799 2108
2109 pl_tex.name = 0;
2110
1800 // thats current max. sorry. 2111 // that's current max. sorry.
1801 if (sw > 255) sw = 255; 2112 if (sw > 255) sw = 255;
1802 if (sh > 255) sh = 255; 2113 if (sh > 255) sh = 255;
1803 2114
1804 // clear key, in case of extra padding 2115 // clear key, in case of extra padding
1805 memset (&skey, 0, sizeof (skey)); 2116 memset (&skey, 0, sizeof (skey));
1809 key.g = 255; 2120 key.g = 255;
1810 key.b = 255; 2121 key.b = 255;
1811 key.a = 255; 2122 key.a = 255;
1812 key.mode = GL_QUADS; 2123 key.mode = GL_QUADS;
1813 key.format = GL_T2F_V3F; 2124 key.format = GL_T2F_V3F;
1814 key.texname = -1;
1815 2125
1816 mx += self->x; 2126 mx += self->x;
1817 my += self->y; 2127 my += self->y;
1818 2128
1819 // first pass: determine smooth_max 2129 // first pass: determine smooth_max
1840 2150
1841 glEnable (GL_BLEND); 2151 glEnable (GL_BLEND);
1842 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2152 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1843 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 2153 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1844 2154
2155 key.texname = self->tex [TEXID_HIDDEN].name;
2156 arr_hidden = rc_array (rc_ov, &key);
2157
1845 for (z = 0; z <= 2; z++) 2158 for (z = 0; z <= 2; z++)
1846 { 2159 {
1847 memset (smooth_level, 0, sizeof (smooth_level)); 2160 memset (smooth_level, 0, sizeof (smooth_level));
2161 key.texname = -1;
1848 2162
1849 for (y = 0; y < sh; y++) 2163 for (y = 0; y < sh; y++)
1850 if (0 <= y + my && y + my < self->rows) 2164 if (0 <= y + my && y + my < self->rows)
1851 { 2165 {
1852 maprow *row = self->row + (y + my); 2166 maprow *row = self->row + (y + my);
1862 maptex tex = self->tex [tile]; 2176 maptex tex = self->tex [tile];
1863 int px, py; 2177 int px, py;
1864 2178
1865 if (key.texname != tex.name) 2179 if (key.texname != tex.name)
1866 { 2180 {
2181 self->tex [tile].unused = 0;
2182
1867 if (!tex.name) 2183 if (!tex.name)
1868 tex = self->tex [2]; /* missing, replace by noface */ 2184 tex = self->tex [TEXID_NOFACE]; /* missing, replace by noface */
1869 2185
1870 key.texname = tex.name; 2186 key.texname = tex.name;
1871 arr = rc_array (rc, &key); 2187 arr = rc_array (rc, &key);
1872 } 2188 }
1873 2189
1874 px = (x + 1) * T - tex.w; 2190 px = (x + 1) * T - tex.w;
1875 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 }
1876 2200
1877 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2201 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
1878 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);
1879 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);
1880 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);
1881
1882 if (cell->flags && z == 2)
1883 {
1884 // overlays such as the speech bubble, probably more to come
1885 if (cell->flags & 1)
1886 {
1887 maptex tex = self->tex [1];
1888 int px = x * T + T * 2 / 32;
1889 int py = y * T - T * 6 / 32;
1890
1891 if (tex.name)
1892 {
1893 if (key.texname != tex.name)
1894 {
1895 key.texname = tex.name;
1896 arr = rc_array (rc, &key);
1897 }
1898
1899 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
1900 rc_t2f_v3f (arr, 0 , tex.t, px , py + T, 0);
1901 rc_t2f_v3f (arr, tex.s, tex.t, px + T, py + T, 0);
1902 rc_t2f_v3f (arr, tex.s, 0 , px + T, py , 0);
1903 }
1904 }
1905 }
1906 2205
1907 // update smooth hash 2206 // update smooth hash
1908 if (tex.smoothtile) 2207 if (tex.smoothtile)
1909 { 2208 {
1910 skey.tile = tex.smoothtile; 2209 skey.tile = tex.smoothtile;
1939 // corners 2238 // corners
1940 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);
1941 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);
1942 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);
1943 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 }
1944 } 2280 }
1945 } 2281 }
1946 } 2282 }
1947 } 2283 }
1948 2284
1988 { 2324 {
1989 // this time avoiding texture state changes 2325 // this time avoiding texture state changes
1990 // save gobs of state changes. 2326 // save gobs of state changes.
1991 if (key.texname != tex.name) 2327 if (key.texname != tex.name)
1992 { 2328 {
2329 self->tex [skey->tile].unused = 0;
2330
1993 glEnd (); 2331 glEnd ();
1994 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name); 2332 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name);
1995 glBegin (GL_QUADS); 2333 glBegin (GL_QUADS);
1996 } 2334 }
1997 2335
2026 } 2364 }
2027 2365
2028 hv_clear (smooth); 2366 hv_clear (smooth);
2029 } 2367 }
2030 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
2031 glDisable (GL_BLEND); 2389 glDisable (GL_BLEND);
2032 rc_free (rc); 2390 rc_free (rc);
2391 rc_free (rc_ov);
2033 2392
2034 // top layer: overlays such as the health bar 2393 // top layer: overlays such as the health bar
2035 for (y = 0; y < sh; y++) 2394 for (y = 0; y < sh; y++)
2036 if (0 <= y + my && y + my < self->rows) 2395 if (0 <= y + my && y + my < self->rows)
2037 { 2396 {
2042 { 2401 {
2043 mapcell *cell = row->col + (x + mx - row->c0); 2402 mapcell *cell = row->col + (x + mx - row->c0);
2044 2403
2045 int px = x * T; 2404 int px = x * T;
2046 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 }
2047 2412
2048 if (cell->stat_hp) 2413 if (cell->stat_hp)
2049 { 2414 {
2050 int width = cell->stat_width * T; 2415 int width = cell->stat_width * T;
2051 int thick = (sh * T / 32 + 27) / 28 + 1 + cell->stat_width; 2416 int thick = (sh * T / 32 + 27) / 28 + 1 + cell->stat_width;
2091 }; 2456 };
2092 2457
2093 int x, y; 2458 int x, y;
2094 2459
2095 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 */
2096 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 2467 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
2097 glEnable (GL_BLEND); 2468 glEnable (GL_BLEND);
2098 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2469 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2099 glBegin (GL_QUADS); 2470 glBegin (GL_QUADS);
2100 2471
2101 for (y = 0; y < h; y++) 2472 for (y = 0; y < h; y++)
2108 float *c = color [m & 15]; 2479 float *c = color [m & 15];
2109 2480
2110 float tx1 = m & 0x40 ? 0.5 : 0.; 2481 float tx1 = m & 0x40 ? 0.5 : 0.;
2111 float tx2 = tx1 + 0.5; 2482 float tx2 = tx1 + 0.5;
2112 2483
2113 glColor4f (c[0], c[1], c[2], 0.75); 2484 glColor4f (c[0], c[1], c[2], 1);
2114 glTexCoord2f (tx1, 0.); glVertex2i (x , y ); 2485 glTexCoord2f (tx1, 0.); glVertex2i (x , y );
2115 glTexCoord2f (tx1, 1.); glVertex2i (x , y + 1); 2486 glTexCoord2f (tx1, 1.); glVertex2i (x , y + 1);
2116 glTexCoord2f (tx2, 1.); glVertex2i (x + 1, y + 1); 2487 glTexCoord2f (tx2, 1.); glVertex2i (x + 1, y + 1);
2117 glTexCoord2f (tx2, 0.); glVertex2i (x + 1, y ); 2488 glTexCoord2f (tx2, 0.); glVertex2i (x + 1, y );
2118 } 2489 }
2140 SvCUR_set (darkness3_sv, sw34 * sh3); 2511 SvCUR_set (darkness3_sv, sw34 * sh3);
2141 2512
2142 mx += self->x - 1; 2513 mx += self->x - 1;
2143 my += self->y - 1; 2514 my += self->y - 1;
2144 2515
2145 memset (darkness1, 255, sw1 * sh1); 2516 memset (darkness1, DARKNESS_ADJUST (255 - FOW_DARKNESS), sw1 * sh1);
2146 2517
2147 for (y = 0; y < sh1; y++) 2518 for (y = 0; y < sh1; y++)
2148 if (0 <= y + my && y + my < self->rows) 2519 if (0 <= y + my && y + my < self->rows)
2149 { 2520 {
2150 maprow *row = self->row + (y + my); 2521 maprow *row = self->row + (y + my);
2153 if (row->c0 <= x + mx && x + mx < row->c1) 2524 if (row->c0 <= x + mx && x + mx < row->c1)
2154 { 2525 {
2155 mapcell *cell = row->col + (x + mx - row->c0); 2526 mapcell *cell = row->col + (x + mx - row->c0);
2156 2527
2157 darkness1 [y * sw1 + x] = cell->darkness 2528 darkness1 [y * sw1 + x] = cell->darkness
2158 ? 255 - (cell->darkness - 1) 2529 ? DARKNESS_ADJUST (255 - (cell->darkness - 1))
2159 : 255 - FOW_DARKNESS; 2530 : DARKNESS_ADJUST (255 - FOW_DARKNESS);
2160 } 2531 }
2161 } 2532 }
2162 2533
2163 for (y = 0; y < sh; ++y) 2534 for (y = 0; y < sh; ++y)
2164 for (x = 0; x < sw; ++x) 2535 for (x = 0; x < sw; ++x)
2270 else 2641 else
2271 *data++ = 0; 2642 *data++ = 0;
2272 } 2643 }
2273 } 2644 }
2274 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 {
2275 SvPOK_only (data_sv); 2649 SvPOK_only (data_sv);
2276 SvCUR_set (data_sv, data - (uint8_t *)SvPVX (data_sv)); 2650 SvCUR_set (data_sv, data - (uint8_t *)SvPVX (data_sv));
2651 }
2652
2277 RETVAL = data_sv; 2653 RETVAL = data_sv;
2278} 2654}
2279 OUTPUT: 2655 OUTPUT:
2280 RETVAL 2656 RETVAL
2281 2657
2282void 2658void
2283set_rect (DC::Map self, int x0, int y0, uint8_t *data) 2659set_rect (DC::Map self, int x0, int y0, SV *data_sv)
2284 PPCODE: 2660 PPCODE:
2285{ 2661{
2286 int x, y, z; 2662 int x, y, z;
2287 int w, h; 2663 int w, h;
2288 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;
2289 2675
2290 if (*data++ != 0) 2676 if (*data++ != 0)
2291 XSRETURN_EMPTY; /* version mismatch */ 2677 XSRETURN_EMPTY; /* version mismatch */
2292 2678
2293 w = *data++ << 8; w |= *data++; 2679 w = *data++ << 8; w |= *data++;
2308 { 2694 {
2309 maprow *row = map_get_row (self, y); 2695 maprow *row = map_get_row (self, y);
2310 2696
2311 for (x = x0; x < x1; x++) 2697 for (x = x0; x < x1; x++)
2312 { 2698 {
2699 uint8_t flags;
2700
2701 if (data + 7 >= end)
2702 XSRETURN_EMPTY;
2703
2313 uint8_t flags = *data++; 2704 flags = *data++;
2314 2705
2315 if (flags) 2706 if (flags)
2316 { 2707 {
2317 mapcell *cell = row_get_cell (row, x); 2708 mapcell *cell = row_get_cell (row, x);
2318 tileid tile[3] = { 0, 0, 0 }; 2709 tileid tile[3] = { 0, 0, 0 };
2321 if (flags & 2) { tile[1] = *data++ << 8; tile[1] |= *data++; } 2712 if (flags & 2) { tile[1] = *data++ << 8; tile[1] |= *data++; }
2322 if (flags & 4) { tile[2] = *data++ << 8; tile[2] |= *data++; } 2713 if (flags & 4) { tile[2] = *data++ << 8; tile[2] |= *data++; }
2323 2714
2324 if (cell->darkness == 0) 2715 if (cell->darkness == 0)
2325 { 2716 {
2326 cell->darkness = 0; 2717 /*cell->darkness = 0;*/
2718 EXTEND (SP, 3);
2327 2719
2328 for (z = 0; z <= 2; z++) 2720 for (z = 0; z <= 2; z++)
2329 { 2721 {
2330 tileid t = tile [z]; 2722 tileid t = tile [z];
2331 2723
2332 if (t >= self->texs || (t && !self->tex [t].name)) 2724 if (t >= self->texs || (t && !self->tex [t].name))
2333 { 2725 {
2334 XPUSHs (sv_2mortal (newSViv (t))); 2726 PUSHs (sv_2mortal (newSViv (t)));
2335 need_texid (self, t); 2727 need_texid (self, t);
2336 } 2728 }
2337 2729
2338 cell->tile [z] = t; 2730 cell->tile [z] = t;
2339 } 2731 }
2556 } *civ, const_iv[] = { 2948 } *civ, const_iv[] = {
2557# define const_iv(name) { # name, (IV)name } 2949# define const_iv(name) { # name, (IV)name }
2558 const_iv (GL_VENDOR), 2950 const_iv (GL_VENDOR),
2559 const_iv (GL_VERSION), 2951 const_iv (GL_VERSION),
2560 const_iv (GL_EXTENSIONS), 2952 const_iv (GL_EXTENSIONS),
2953 const_iv (GL_MAX_TEXTURE_UNITS),
2561 const_iv (GL_COLOR_MATERIAL), 2954 const_iv (GL_COLOR_MATERIAL),
2562 const_iv (GL_SMOOTH), 2955 const_iv (GL_SMOOTH),
2563 const_iv (GL_FLAT), 2956 const_iv (GL_FLAT),
2564 const_iv (GL_DITHER), 2957 const_iv (GL_DITHER),
2565 const_iv (GL_BLEND), 2958 const_iv (GL_BLEND),
2577 const_iv (GL_ZERO), 2970 const_iv (GL_ZERO),
2578 const_iv (GL_SRC_ALPHA), 2971 const_iv (GL_SRC_ALPHA),
2579 const_iv (GL_DST_ALPHA), 2972 const_iv (GL_DST_ALPHA),
2580 const_iv (GL_ONE_MINUS_SRC_ALPHA), 2973 const_iv (GL_ONE_MINUS_SRC_ALPHA),
2581 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),
2582 const_iv (GL_SRC_ALPHA_SATURATE), 2979 const_iv (GL_SRC_ALPHA_SATURATE),
2583 const_iv (GL_RGB), 2980 const_iv (GL_RGB),
2584 const_iv (GL_RGBA), 2981 const_iv (GL_RGBA),
2585 const_iv (GL_RGBA4), 2982 const_iv (GL_RGBA4),
2586 const_iv (GL_RGBA8), 2983 const_iv (GL_RGBA8),
2654 const_iv (GL_NICEST), 3051 const_iv (GL_NICEST),
2655 const_iv (GL_V2F), 3052 const_iv (GL_V2F),
2656 const_iv (GL_V3F), 3053 const_iv (GL_V3F),
2657 const_iv (GL_T2F_V3F), 3054 const_iv (GL_T2F_V3F),
2658 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),
2659# undef const_iv 3059# undef const_iv
2660 }; 3060 };
2661 3061
2662 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; )
2663 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 3063 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
2670disable_GL_EXT_blend_func_separate () 3070disable_GL_EXT_blend_func_separate ()
2671 CODE: 3071 CODE:
2672 gl.BlendFuncSeparate = 0; 3072 gl.BlendFuncSeparate = 0;
2673 gl.BlendFuncSeparateEXT = 0; 3073 gl.BlendFuncSeparateEXT = 0;
2674 3074
3075void
3076apple_nvidia_bug (int enable)
3077
2675char * 3078char *
2676gl_vendor () 3079gl_vendor ()
2677 CODE: 3080 CODE:
2678 RETVAL = (char *)glGetString (GL_VENDOR); 3081 RETVAL = (char *)glGetString (GL_VENDOR);
2679 OUTPUT: 3082 OUTPUT:
2728 3131
2729void glBlendFuncSeparate (int sa, int da, int saa, int daa) 3132void glBlendFuncSeparate (int sa, int da, int saa, int daa)
2730 CODE: 3133 CODE:
2731 gl_BlendFuncSeparate (sa, da, saa, daa); 3134 gl_BlendFuncSeparate (sa, da, saa, daa);
2732 3135
3136# void glBlendEquation (int se)
3137
2733void glDepthMask (int flag) 3138void glDepthMask (int flag)
2734 3139
2735void glLogicOp (int opcode) 3140void glLogicOp (int opcode)
2736 3141
2737void glColorMask (int red, int green, int blue, int alpha) 3142void glColorMask (int red, int green, int blue, int alpha)
2771void glRotate (float angle, float x, float y, float z) 3176void glRotate (float angle, float x, float y, float z)
2772 CODE: 3177 CODE:
2773 glRotatef (angle, x, y, z); 3178 glRotatef (angle, x, y, z);
2774 3179
2775void 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: @
2776 ALIAS: 3182 ALIAS:
2777 glColor_premultiply = 1 3183 glColor_premultiply = 1
2778 CODE: 3184 CODE:
2779 if (ix) 3185 if (ix)
2780 { 3186 {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines