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.175 by root, Fri Apr 6 08:09:42 2007 UTC vs.
Revision 1.211 by root, Sat Jul 28 00:45:28 2007 UTC

6# include <wininet.h> 6# include <wininet.h>
7# pragma warning(disable:4244) 7# pragma warning(disable:4244)
8# pragma warning(disable:4761) 8# pragma warning(disable:4761)
9#endif 9#endif
10 10
11//#define DEBUG 1
12#if DEBUG
13# include <valgrind/memcheck.h>
14#endif
15
11#include "EXTERN.h" 16#include "EXTERN.h"
12#include "perl.h" 17#include "perl.h"
13#include "XSUB.h" 18#include "XSUB.h"
14 19
15#ifdef _WIN32 20#ifdef _WIN32
21#include <string.h> 26#include <string.h>
22#include <stdio.h> 27#include <stdio.h>
23#include <stdlib.h> 28#include <stdlib.h>
24 29
25#include <SDL.h> 30#include <SDL.h>
31#include <SDL_thread.h>
26#include <SDL_endian.h> 32#include <SDL_endian.h>
27#include <SDL_image.h> 33#include <SDL_image.h>
28#include <SDL_mixer.h> 34#include <SDL_mixer.h>
29#include <SDL_opengl.h> 35#include <SDL_opengl.h>
30 36
56# define PARACHUTE SDL_INIT_NOPARACHUTE 62# define PARACHUTE SDL_INIT_NOPARACHUTE
57#else 63#else
58# define PARACHUTE 0 64# define PARACHUTE 0
59#endif 65#endif
60 66
67static AV *texture_av;
68
61static struct 69static struct
62{ 70{
63#define GL_FUNC(ptr,name) ptr name; 71#define GL_FUNC(ptr,name) ptr name;
64#include "glfunc.h" 72#include "glfunc.h"
65#undef GL_FUNC 73#undef GL_FUNC
66} gl; 74} gl;
67 75
76static void
68static void gl_BlendFuncSeparate (GLenum sa, GLenum da, GLenum saa, GLenum daa) 77gl_BlendFuncSeparate (GLenum sa, GLenum da, GLenum saa, GLenum daa)
69{ 78{
70 if (gl.BlendFuncSeparate) 79 if (gl.BlendFuncSeparate)
71 gl.BlendFuncSeparate (sa, da, saa, daa); 80 gl.BlendFuncSeparate (sa, da, saa, daa);
72 else if (gl.BlendFuncSeparateEXT) 81 else if (gl.BlendFuncSeparateEXT)
73 gl.BlendFuncSeparateEXT (sa, da, saa, daa); 82 gl.BlendFuncSeparateEXT (sa, da, saa, daa);
74 else 83 else
75 glBlendFunc (sa, da); 84 glBlendFunc (sa, da);
76} 85}
77 86
87static GLuint
88gen_texture ()
89{
90 GLuint name;
91
92 if (AvFILL (texture_av) >= 0)
93 name = (GLuint)(size_t)av_pop (texture_av);
94 else
95 glGenTextures (1, &name);
96
97 return name;
98}
99
100static void
101del_texture (GLuint name)
102{
103 /* make a half-assed attempt at returning the memory used by the texture */
104 /* textures are frequently being reused by cfplus anyway */
105 /*glBindTexture (GL_TEXTURE_2D, name);*/
106 /*glTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA, 0, 0, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0);*/
107 av_push (texture_av, (SV *)(size_t)name);
108 glDeleteTextures (1, &name);
109}
110
78#include "texcache.c" 111#include "texcache.c"
79 112
80#include "pango-font.c" 113#include "pango-font.c"
81#include "pango-fontmap.c" 114#include "pango-fontmap.c"
82#include "pango-render.c" 115#include "pango-render.c"
163typedef struct { 196typedef struct {
164 int name; 197 int name;
165 int w, h; 198 int w, h;
166 float s, t; 199 float s, t;
167 uint8_t r, g, b, a; 200 uint8_t r, g, b, a;
201 tileid smoothtile;
202 uint8_t smoothlevel;
168} maptex; 203} maptex;
169 204
170typedef struct { 205typedef struct {
171 uint32_t player; 206 uint32_t player;
172 tileid tile[3]; 207 tileid tile[3];
173 uint16_t darkness; 208 uint16_t darkness;
174 uint8_t stat_width, stat_hp, flags; 209 uint8_t stat_width, stat_hp, flags, smoothmax;
175} mapcell; 210} mapcell;
176 211
177typedef struct { 212typedef struct {
178 int32_t c0, c1; 213 int32_t c0, c1;
179 mapcell *col; 214 mapcell *col;
335 cell->player = 0; 370 cell->player = 0;
336 } 371 }
337 } 372 }
338} 373}
339 374
375typedef struct {
376 tileid tile;
377 uint8_t x, y, level;
378} smooth_key;
379
380static void
381smooth_or_bits (HV *hv, smooth_key *key, IV bits)
382{
383 SV **sv = hv_fetch (hv, (char *)key, sizeof (*key), 1);
384
385 if (SvIOK (*sv))
386 SvIV_set (*sv, SvIVX (*sv) | bits);
387 else
388 sv_setiv (*sv, bits);
389}
390
340static void 391static void
341music_finished (void) 392music_finished (void)
342{ 393{
343 SDL_UserEvent ev; 394 SDL_UserEvent ev;
344 395
381} 432}
382 433
383/* SDL should provide this, really. */ 434/* SDL should provide this, really. */
384#define SDLK_MODIFIER_MIN 300 435#define SDLK_MODIFIER_MIN 300
385#define SDLK_MODIFIER_MAX 314 436#define SDLK_MODIFIER_MAX 314
437
438/******************************************************************************/
439
440static GV *draw_x_gv, *draw_y_gv, *draw_w_gv, *draw_h_gv;
441static GV *hover_gv;
442
443static int
444within_widget (SV *widget, NV x, NV y)
445{
446 HV *self;
447 SV **svp;
448 NV wx, ww, wy, wh;
449
450 if (!SvROK (widget))
451 return 0;
452
453 self = (HV *)SvRV (widget);
454
455 if (SvTYPE (self) != SVt_PVHV)
456 return 0;
457
458 svp = hv_fetch (self, "y", 1, 0); wy = svp ? SvNV (*svp) : 0.;
459 if (y < wy)
460 return 0;
461
462 svp = hv_fetch (self, "h", 1, 0); wh = svp ? SvNV (*svp) : 0.;
463 if (y >= wy + wh)
464 return 0;
465
466 svp = hv_fetch (self, "x", 1, 0); wx = svp ? SvNV (*svp) : 0.;
467 if (x < wx)
468 return 0;
469
470 svp = hv_fetch (self, "w", 1, 0); ww = svp ? SvNV (*svp) : 0.;
471 if (x >= wx + ww)
472 return 0;
473
474 svp = hv_fetch (self, "can_events", sizeof ("can_events") - 1, 0);
475 if (!svp || !SvTRUE (*svp))
476 return 0;
477
478 return 1;
479}
386 480
387MODULE = CFPlus PACKAGE = CFPlus 481MODULE = CFPlus PACKAGE = CFPlus
388 482
389PROTOTYPES: ENABLE 483PROTOTYPES: ENABLE
390 484
537 opengl_fontmap = pango_opengl_font_map_new (); 631 opengl_fontmap = pango_opengl_font_map_new ();
538 pango_opengl_font_map_set_default_substitute ((PangoOpenGLFontMap *)opengl_fontmap, substitute_func, 0, 0); 632 pango_opengl_font_map_set_default_substitute ((PangoOpenGLFontMap *)opengl_fontmap, substitute_func, 0, 0);
539 opengl_context = pango_opengl_font_map_create_context ((PangoOpenGLFontMap *)opengl_fontmap); 633 opengl_context = pango_opengl_font_map_create_context ((PangoOpenGLFontMap *)opengl_fontmap);
540} 634}
541 635
636char *
637SDL_GetError ()
638
542int 639int
543SDL_Init (U32 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | PARACHUTE) 640SDL_Init (U32 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | PARACHUTE)
544 641
545void 642void
546SDL_Quit () 643SDL_Quit ()
547 644
548void 645void
549SDL_ListModes () 646SDL_ListModes (int rgb, int alpha)
550 PPCODE: 647 PPCODE:
551{ 648{
552 SDL_Rect **m; 649 SDL_Rect **m;
553 650
554 SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 5); 651 SDL_GL_SetAttribute (SDL_GL_RED_SIZE , rgb);
555 SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 5); 652 SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, rgb);
556 SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5); 653 SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE , rgb);
557 SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, 1); 654 SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, alpha);
558 655
559 SDL_GL_SetAttribute (SDL_GL_BUFFER_SIZE, 15); 656 SDL_GL_SetAttribute (SDL_GL_BUFFER_SIZE, 15);
560 SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 0); 657 SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE , 0);
561 658
562 SDL_GL_SetAttribute (SDL_GL_ACCUM_RED_SIZE, 0); 659 SDL_GL_SetAttribute (SDL_GL_ACCUM_RED_SIZE , 0);
563 SDL_GL_SetAttribute (SDL_GL_ACCUM_GREEN_SIZE, 0); 660 SDL_GL_SetAttribute (SDL_GL_ACCUM_GREEN_SIZE, 0);
564 SDL_GL_SetAttribute (SDL_GL_ACCUM_BLUE_SIZE, 0); 661 SDL_GL_SetAttribute (SDL_GL_ACCUM_BLUE_SIZE , 0);
565 SDL_GL_SetAttribute (SDL_GL_ACCUM_ALPHA_SIZE, 0); 662 SDL_GL_SetAttribute (SDL_GL_ACCUM_ALPHA_SIZE, 0);
566 663
567 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); 664 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
568#if SDL_VERSION_ATLEAST(1,2,10) 665#if SDL_VERSION_ATLEAST(1,2,10)
569 SDL_GL_SetAttribute (SDL_GL_ACCELERATED_VISUAL, 1); 666 SDL_GL_SetAttribute (SDL_GL_ACCELERATED_VISUAL, 1);
570 SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 1); 667 SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 1);
571#endif 668#endif
572 669
573 SDL_EnableUNICODE (1);
574 SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
575
576 m = SDL_ListModes (0, SDL_FULLSCREEN | SDL_OPENGL); 670 m = SDL_ListModes (0, SDL_FULLSCREEN | SDL_OPENGL);
577 671
578 if (m && m != (SDL_Rect **)-1) 672 if (m && m != (SDL_Rect **)-1)
579 while (*m) 673 while (*m)
580 { 674 {
675 if ((*m)->w >= 640 && (*m)->h >= 480)
676 {
581 AV *av = newAV (); 677 AV *av = newAV ();
582 av_push (av, newSViv ((*m)->w)); 678 av_push (av, newSViv ((*m)->w));
583 av_push (av, newSViv ((*m)->h)); 679 av_push (av, newSViv ((*m)->h));
680 av_push (av, newSViv (rgb));
681 av_push (av, newSViv (alpha));
584 XPUSHs (sv_2mortal (newRV_noinc ((SV *)av))); 682 XPUSHs (sv_2mortal (newRV_noinc ((SV *)av)));
683 }
585 684
586 ++m; 685 ++m;
587 } 686 }
588} 687}
589 688
590char *
591SDL_GetError ()
592
593int 689int
594SDL_SetVideoMode (int w, int h, int fullscreen) 690SDL_SetVideoMode (int w, int h, int rgb, int alpha, int fullscreen)
595 CODE: 691 CODE:
692{
693 SDL_EnableUNICODE (1);
694 SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
695
696 SDL_GL_SetAttribute (SDL_GL_RED_SIZE , rgb);
697 SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, rgb);
698 SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE , rgb);
699 SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, alpha);
700
596 RETVAL = !!SDL_SetVideoMode ( 701 RETVAL = !!SDL_SetVideoMode (
597 w, h, 0, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0) 702 w, h, 0, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0)
598 ); 703 );
704
599 if (RETVAL) 705 if (RETVAL)
600 { 706 {
707 av_clear (texture_av);
708
601 SDL_WM_SetCaption ("Crossfire+ Client " VERSION, "Crossfire+"); 709 SDL_WM_SetCaption ("Crossfire+ Client " VERSION, "Crossfire+");
602# define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name); 710#define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name);
603# include "glfunc.h" 711#include "glfunc.h"
604# undef GL_FUNC 712#undef GL_FUNC
605 } 713 }
714}
606 OUTPUT: 715 OUTPUT:
607 RETVAL 716 RETVAL
608 717
609void 718void
610SDL_GL_SwapBuffers () 719SDL_GL_SwapBuffers ()
611 720
612char * 721char *
613SDL_GetKeyName (int sym) 722SDL_GetKeyName (int sym)
614 723
724int
725SDL_GetAppState ()
726
615void 727void
616SDL_PollEvent () 728poll_events ()
617 PPCODE: 729 PPCODE:
618{ 730{
619 SDL_Event ev; 731 SDL_Event ev;
620 732
621 while (SDL_PollEvent (&ev)) 733 SDL_PumpEvents ();
734 while (SDL_PeepEvents (&ev, 1, SDL_GETEVENT, SDL_ALLEVENTS) > 0)
622 { 735 {
623 HV *hv = newHV (); 736 HV *hv = newHV ();
624 hv_store (hv, "type", 4, newSViv (ev.type), 0); 737 hv_store (hv, "type", 4, newSViv (ev.type), 0);
625 738
626 switch (ev.type) 739 switch (ev.type)
638 hv_store (hv, "gain", 4, newSViv (ev.active.gain), 0); 751 hv_store (hv, "gain", 4, newSViv (ev.active.gain), 0);
639 hv_store (hv, "state", 5, newSViv (ev.active.state), 0); 752 hv_store (hv, "state", 5, newSViv (ev.active.state), 0);
640 break; 753 break;
641 754
642 case SDL_MOUSEMOTION: 755 case SDL_MOUSEMOTION:
756 {
757 int state = ev.motion.state;
758 int x = ev.motion.x;
759 int y = ev.motion.y;
760 int xrel = ev.motion.xrel;
761 int yrel = ev.motion.yrel;
762
763 /* do simplistic event compression */
764 while (SDL_PeepEvents (&ev, 1, SDL_PEEKEVENT, SDL_EVENTMASK (SDL_MOUSEMOTION)) > 0
765 && state == ev.motion.state)
766 {
767 xrel += ev.motion.xrel;
768 yrel += ev.motion.yrel;
769 x = ev.motion.x;
770 y = ev.motion.y;
771 SDL_PeepEvents (&ev, 1, SDL_GETEVENT, SDL_EVENTMASK (SDL_MOUSEMOTION));
772 }
773
643 hv_store (hv, "mod", 3, newSViv (SDL_GetModState ()), 0); 774 hv_store (hv, "mod", 3, newSViv (SDL_GetModState ()), 0);
644
645 hv_store (hv, "state", 5, newSViv (ev.motion.state), 0); 775 hv_store (hv, "state", 5, newSViv (state), 0);
646 hv_store (hv, "x", 1, newSViv (ev.motion.x), 0); 776 hv_store (hv, "x", 1, newSViv (x), 0);
647 hv_store (hv, "y", 1, newSViv (ev.motion.y), 0); 777 hv_store (hv, "y", 1, newSViv (y), 0);
648 hv_store (hv, "xrel", 4, newSViv (ev.motion.xrel), 0); 778 hv_store (hv, "xrel", 4, newSViv (xrel), 0);
649 hv_store (hv, "yrel", 4, newSViv (ev.motion.yrel), 0); 779 hv_store (hv, "yrel", 4, newSViv (yrel), 0);
780 }
650 break; 781 break;
651 782
652 case SDL_MOUSEBUTTONDOWN: 783 case SDL_MOUSEBUTTONDOWN:
653 case SDL_MOUSEBUTTONUP: 784 case SDL_MOUSEBUTTONUP:
654 hv_store (hv, "mod", 3, newSViv (SDL_GetModState ()), 0); 785 hv_store (hv, "mod", 3, newSViv (SDL_GetModState ()), 0);
669 XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("CFPlus::UI::Event", 1)))); 800 XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("CFPlus::UI::Event", 1))));
670 } 801 }
671} 802}
672 803
673int 804int
674Mix_OpenAudio (int frequency = 48000, int format = MIX_DEFAULT_FORMAT, int channels = 1, int chunksize = 2048) 805Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 4096)
675 POSTCALL: 806 POSTCALL:
676 Mix_HookMusicFinished (music_finished); 807 Mix_HookMusicFinished (music_finished);
677 Mix_ChannelFinished (channel_finished); 808 Mix_ChannelFinished (channel_finished);
678 809
679void 810void
683Mix_AllocateChannels (int numchans = -1) 814Mix_AllocateChannels (int numchans = -1)
684 815
685void 816void
686lowdelay (int fd, int val = 1) 817lowdelay (int fd, int val = 1)
687 CODE: 818 CODE:
688#ifndef _WIN32
689 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof (val)); 819 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&val, sizeof (val));
690#endif
691 820
692void 821void
693win32_proxy_info () 822win32_proxy_info ()
694 PPCODE: 823 PPCODE:
695{ 824{
836 ExitThread (retval); // unclean, please beam me up 965 ExitThread (retval); // unclean, please beam me up
837#else 966#else
838 _exit (retval); 967 _exit (retval);
839#endif 968#endif
840 969
970void
971debug ()
972 CODE:
973{
974#if DEBUG
975 VALGRIND_DO_LEAK_CHECK;
976#endif
977}
978
841MODULE = CFPlus PACKAGE = CFPlus::Font 979MODULE = CFPlus PACKAGE = CFPlus::Font
980
981PROTOTYPES: DISABLE
842 982
843CFPlus::Font 983CFPlus::Font
844new_from_file (SV *class, char *path, int id = 0) 984new_from_file (SV *class, char *path, int id = 0)
845 CODE: 985 CODE:
846{ 986{
857 CODE: 997 CODE:
858 pango_font_description_free (self); 998 pango_font_description_free (self);
859 999
860void 1000void
861make_default (CFPlus::Font self) 1001make_default (CFPlus::Font self)
1002 PROTOTYPE: $
862 CODE: 1003 CODE:
863 default_font = self; 1004 default_font = self;
864 1005
865MODULE = CFPlus PACKAGE = CFPlus::Layout 1006MODULE = CFPlus PACKAGE = CFPlus::Layout
866 1007
1008PROTOTYPES: DISABLE
1009
867void 1010void
868reset_glyph_cache () 1011reset_glyph_cache ()
1012 PROTOTYPE:
869 CODE: 1013 CODE:
870 tc_clear (); 1014 tc_clear ();
871 1015
872CFPlus::Layout 1016CFPlus::Layout
873new (SV *class) 1017new (SV *class)
1160 flags 1304 flags
1161 ); 1305 );
1162 1306
1163MODULE = CFPlus PACKAGE = CFPlus::Texture 1307MODULE = CFPlus PACKAGE = CFPlus::Texture
1164 1308
1165void 1309PROTOTYPES: ENABLE
1166pad2pot (SV *data_, SV *w_, SV *h_)
1167 CODE:
1168{
1169 int ow = SvIV (w_);
1170 int oh = SvIV (h_);
1171 1310
1172 if (ow && oh) 1311int minpot (int n)
1312
1313void
1314pad (SV *data_, int ow, int oh, int nw, int nh)
1315 CODE:
1316{
1317 if ((nw != ow || nh != oh) && SvOK (data_))
1173 { 1318 {
1174 int nw = minpot (ow);
1175 int nh = minpot (oh);
1176
1177 if (nw != ow || nh != oh)
1178 {
1179 if (SvOK (data_))
1180 {
1181 STRLEN datalen; 1319 STRLEN datalen;
1182 char *data = SvPVbyte (data_, datalen); 1320 char *data = SvPVbyte (data_, datalen);
1183 int bpp = datalen / (ow * oh); 1321 int bpp = datalen / (ow * oh);
1184 SV *result_ = sv_2mortal (newSV (nw * nh * bpp)); 1322 SV *result_ = sv_2mortal (newSV (nw * nh * bpp));
1185 1323
1186 SvPOK_only (result_); 1324 SvPOK_only (result_);
1187 SvCUR_set (result_, nw * nh * bpp); 1325 SvCUR_set (result_, nw * nh * bpp);
1188 1326
1189 memset (SvPVX (result_), 0, nw * nh * bpp); 1327 memset (SvPVX (result_), 0, nw * nh * bpp);
1190 while (oh--) 1328 while (oh--)
1191 memcpy (SvPVX (result_) + oh * nw * bpp, data + oh * ow * bpp, ow * bpp); 1329 memcpy (SvPVX (result_) + oh * nw * bpp, data + oh * ow * bpp, ow * bpp);
1192 1330
1193 sv_setsv (data_, result_); 1331 sv_setsv (data_, result_);
1194 }
1195
1196 sv_setiv (w_, nw);
1197 sv_setiv (h_, nh);
1198 }
1199 } 1332 }
1200} 1333}
1201 1334
1202void 1335void
1203draw_quad (SV *self, float x, float y, float w = 0., float h = 0.) 1336draw_quad (SV *self, float x, float y, float w = 0., float h = 0.)
1246 glDisable (GL_ALPHA_TEST); 1379 glDisable (GL_ALPHA_TEST);
1247 glDisable (GL_BLEND); 1380 glDisable (GL_BLEND);
1248 } 1381 }
1249} 1382}
1250 1383
1384IV texture_valid_2d (GLint internalformat, GLsizei w, GLsizei h, GLenum format, GLenum type)
1385 CODE:
1386{
1387 GLint width;
1388 glTexImage2D (GL_PROXY_TEXTURE_2D, 0, internalformat, w, h, 0, format, type, 0);
1389 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
1390 RETVAL = width > 0;
1391}
1392 OUTPUT:
1393 RETVAL
1394
1251MODULE = CFPlus PACKAGE = CFPlus::Map 1395MODULE = CFPlus PACKAGE = CFPlus::Map
1396
1397PROTOTYPES: DISABLE
1252 1398
1253CFPlus::Map 1399CFPlus::Map
1254new (SV *class) 1400new (SV *class)
1255 CODE: 1401 CODE:
1256 New (0, RETVAL, 1, struct map); 1402 New (0, RETVAL, 1, struct map);
1292set_tileid (CFPlus::Map self, int face, int tile) 1438set_tileid (CFPlus::Map self, int face, int tile)
1293 CODE: 1439 CODE:
1294{ 1440{
1295 need_facenum (self, face); self->face2tile [face] = tile; 1441 need_facenum (self, face); self->face2tile [face] = tile;
1296 need_texid (self, tile); 1442 need_texid (self, tile);
1443}
1444
1445void
1446set_smooth (CFPlus::Map self, int face, int smooth, int level)
1447 CODE:
1448{
1449 tileid texid;
1450 maptex *tex;
1451
1452 if (face < 0 || face >= self->faces)
1453 return;
1454
1455 if (smooth < 0 || smooth >= self->faces)
1456 return;
1457
1458 texid = self->face2tile [face];
1459
1460 if (!texid)
1461 return;
1462
1463 tex = self->tex + texid;
1464 tex->smoothtile = self->face2tile [smooth];
1465 tex->smoothlevel = level;
1297} 1466}
1298 1467
1299void 1468void
1300set_texture (CFPlus::Map self, int texid, int name, int w, int h, float s, float t, int r, int g, int b, int a) 1469set_texture (CFPlus::Map self, int texid, int name, int w, int h, float s, float t, int r, int g, int b, int a)
1301 CODE: 1470 CODE:
1352 CODE: 1521 CODE:
1353{ 1522{
1354 if (dx > 0) 1523 if (dx > 0)
1355 map_blank (self, self->x, self->y, dx, self->h); 1524 map_blank (self, self->x, self->y, dx, self->h);
1356 else if (dx < 0) 1525 else if (dx < 0)
1357 map_blank (self, self->x + self->w + dx + 1, self->y, -dx, self->h); 1526 map_blank (self, self->x + self->w + dx, self->y, -dx, self->h);
1358 1527
1359 if (dy > 0) 1528 if (dy > 0)
1360 map_blank (self, self->x, self->y, self->w, dy); 1529 map_blank (self, self->x, self->y, self->w, dy);
1361 else if (dy < 0) 1530 else if (dy < 0)
1362 map_blank (self, self->x, self->y + self->h + dy + 1, self->w, -dy); 1531 map_blank (self, self->x, self->y + self->h + dy, self->w, -dy);
1363 1532
1364 self->ox += dx; self->x += dx; 1533 self->ox += dx; self->x += dx;
1365 self->oy += dy; self->y += dy; 1534 self->oy += dy; self->y += dy;
1366 1535
1367 while (self->y < 0) 1536 while (self->y < 0)
1421 } 1590 }
1422 else if (cmd == 6) // monster width 1591 else if (cmd == 6) // monster width
1423 cell->stat_width = *data++ + 1; 1592 cell->stat_width = *data++ + 1;
1424 else if (cmd == 0x47) 1593 else if (cmd == 0x47)
1425 { 1594 {
1426 if (*data == 8) 1595 if (*data == 4)
1427 ; // decode player uuid 1596 ; // decode player count
1428 1597
1429 data += *data + 1; 1598 data += *data + 1;
1430 } 1599 }
1431 else if (cmd == 8) // cell flags 1600 else if (cmd == 8) // cell flags
1432 cell->flags = *data++; 1601 cell->flags = *data++;
1524 1693
1525void 1694void
1526draw (CFPlus::Map self, int mx, int my, int sw, int sh, int T) 1695draw (CFPlus::Map self, int mx, int my, int sw, int sh, int T)
1527 CODE: 1696 CODE:
1528{ 1697{
1698 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
1699 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level
1700 static uint8_t smooth_max[256][256]; // egad, fats and wasteful on memory (64k)
1701 smooth_key skey;
1529 int x, y, z; 1702 int x, y, z;
1530 int last_name; 1703 int last_name;
1704
1705 // thats current max. sorry.
1706 if (sw > 255) sw = 255;
1707 if (sh > 255) sh = 255;
1708
1709 // clear key, in case of extra padding
1710 memset (&skey, 0, sizeof (skey));
1531 1711
1532 glColor4ub (255, 255, 255, 255); 1712 glColor4ub (255, 255, 255, 255);
1533 1713
1534 glEnable (GL_BLEND); 1714 glEnable (GL_BLEND);
1535 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1715 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1541 last_name = 0; 1721 last_name = 0;
1542 1722
1543 mx += self->x; 1723 mx += self->x;
1544 my += self->y; 1724 my += self->y;
1545 1725
1726 // first pass: determine smooth_max
1727 // rather ugly, if you ask me
1728 // could also be stored inside mapcell and updated on change
1729 memset (smooth_max, 0, sizeof (smooth_max));
1730
1731 for (y = 0; y < sh; y++)
1732 if (0 <= y + my && y + my < self->rows)
1733 {
1734 maprow *row = self->row + (y + my);
1735
1736 for (x = 0; x < sw; x++)
1737 if (row->c0 <= x + mx && x + mx < row->c1)
1738 {
1739 mapcell *cell = row->col + (x + mx - row->c0);
1740
1741 smooth_max[x + 1][y + 1] =
1742 MAX (self->tex [cell->tile [0]].smoothlevel,
1743 MAX (self->tex [cell->tile [1]].smoothlevel,
1744 self->tex [cell->tile [2]].smoothlevel));
1745 }
1746 }
1747
1546 for (z = 0; z < 3; z++) 1748 for (z = 0; z <= 2; z++)
1749 {
1750 memset (smooth_level, 0, sizeof (smooth_level));
1751
1547 for (y = 0; y < sh; y++) 1752 for (y = 0; y < sh; y++)
1548 if (0 <= y + my && y + my < self->rows) 1753 if (0 <= y + my && y + my < self->rows)
1549 { 1754 {
1550 maprow *row = self->row + (y + my); 1755 maprow *row = self->row + (y + my);
1551 1756
1552 for (x = 0; x < sw; x++) 1757 for (x = 0; x < sw; x++)
1553 if (row->c0 <= x + mx && x + mx < row->c1) 1758 if (row->c0 <= x + mx && x + mx < row->c1)
1554 { 1759 {
1555 mapcell *cell = row->col + (x + mx - row->c0); 1760 mapcell *cell = row->col + (x + mx - row->c0);
1556 tileid tile = cell->tile [z]; 1761 tileid tile = cell->tile [z];
1762
1763 if (tile)
1764 {
1765 maptex tex = self->tex [tile];
1766 int px = (x + 1) * T - tex.w;
1767 int py = (y + 1) * T - tex.h;
1768
1769 // suppressing texture state switches here
1770 // is only moderately effective, but worth the extra effort
1771 if (last_name != tex.name)
1772 {
1773 if (!tex.name)
1774 tex = self->tex [2]; /* missing, replace by noface */
1775
1776 glEnd ();
1777 glBindTexture (GL_TEXTURE_2D, last_name = tex.name);
1778 glBegin (GL_QUADS);
1779 }
1780
1781 glTexCoord2f (0 , 0 ); glVertex2f (px , py );
1782 glTexCoord2f (0 , tex.t); glVertex2f (px , py + tex.h);
1783 glTexCoord2f (tex.s, tex.t); glVertex2f (px + tex.w, py + tex.h);
1784 glTexCoord2f (tex.s, 0 ); glVertex2f (px + tex.w, py );
1785
1786 if (cell->flags && z == 2)
1787 {
1788 if (cell->flags & 1)
1789 {
1790 maptex tex = self->tex [1];
1791 int px = x * T + T * 2 / 32;
1792 int py = y * T - T * 6 / 32;
1793
1794 glEnd ();
1795 glBindTexture (GL_TEXTURE_2D, last_name = tex.name);
1796 glBegin (GL_QUADS);
1797
1798 glTexCoord2f (0 , 0 ); glVertex2f (px , py );
1799 glTexCoord2f (0 , tex.t); glVertex2f (px , py + T);
1800 glTexCoord2f (tex.s, tex.t); glVertex2f (px + T, py + T);
1801 glTexCoord2f (tex.s, 0 ); glVertex2f (px + T, py );
1802 }
1803 }
1804
1805 // update smooth hash
1806 if (tex.smoothtile)
1807 {
1808 skey.tile = tex.smoothtile;
1809 skey.level = tex.smoothlevel;
1810
1811 smooth_level [tex.smoothlevel >> 5] |= ((uint32_t)1) << (tex.smoothlevel & 31);
1812
1813 // add bits to current tile and all neighbours. skey.x|y is
1814 // shifted +1|+1 so we always stay positive.
1815
1816 // bits is ___n cccc CCCC bbbb
1817 // n do not draw borders&corners
1818 // c draw these corners, but...
1819 // C ... not these
1820 // b draw these borders
1821
1822 // borders: 1 ┃· 2 ━━ 4 ·┃ 8 ··
1823 // ┃· ·· ·┃ ━━
1824
1825 // corners: 1 ┛· 2 ·┗ 4 ·· 8 ··
1826 // ·· ·· ·┏ ┓·
1827
1828 // full tile
1829 skey.x = x + 1; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x1000);
1830
1831 // borders
1832 skey.x = x + 2; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x0091);
1833 skey.x = x + 1; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0032);
1834 skey.x = x ; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x0064);
1835 skey.x = x + 1; skey.y = y ; smooth_or_bits (smooth, &skey, 0x00c8);
1836
1837 // corners
1838 skey.x = x + 2; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0100);
1839 skey.x = x ; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0200);
1840 skey.x = x ; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0400);
1841 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0800);
1842 }
1843 }
1557 1844 }
1845 }
1846
1847 // go through all smoothlevels, lowest to highest, then draw.
1848 // this is basically counting sort
1849 {
1850 int w, b;
1851
1852 for (w = 0; w < 256 / 32; ++w)
1853 {
1854 uint32_t smask = smooth_level [w];
1558 if (tile) 1855 if (smask)
1856 for (b = 0; b < 32; ++b)
1857 if (smask & (((uint32_t)1) << b))
1559 { 1858 {
1560 maptex tex = self->tex [tile]; 1859 int level = (w << 5) | b;
1561 int px = (x + 1) * T - tex.w; 1860 HE *he;
1562 int py = (y + 1) * T - tex.h;
1563 1861
1564 if (last_name != tex.name) 1862 hv_iterinit (smooth);
1863 while ((he = hv_iternext (smooth)))
1565 { 1864 {
1865 smooth_key *skey = (smooth_key *)HeKEY (he);
1866 IV bits = SvIVX (HeVAL (he));
1867
1566 if (!tex.name) 1868 if (!(bits & 0x1000)
1567 tex = self->tex [2]; /* missing, replace by noface */ 1869 && skey->level == level
1568 1870 && level > smooth_max [skey->x][skey->y])
1569 glEnd ();
1570 glBindTexture (GL_TEXTURE_2D, last_name = tex.name);
1571 glBegin (GL_QUADS);
1572 }
1573
1574 glTexCoord2f (0 , 0 ); glVertex2f (px , py );
1575 glTexCoord2f (0 , tex.t); glVertex2f (px , py + tex.h);
1576 glTexCoord2f (tex.s, tex.t); glVertex2f (px + tex.w, py + tex.h);
1577 glTexCoord2f (tex.s, 0 ); glVertex2f (px + tex.w, py );
1578
1579 if (cell->flags && z == 2)
1580 {
1581 if (cell->flags & 1)
1582 { 1871 {
1583 maptex tex = self->tex [1]; 1872 maptex tex = self->tex [skey->tile];
1584 int px = x * T + T * 2 / 32; 1873 int px = (((int)skey->x) - 1) * T;
1585 int py = y * T - T * 6 / 32; 1874 int py = (((int)skey->y) - 1) * T;
1875 int border = bits & 15;
1876 int corner = (bits >> 8) & ~(bits >> 4) & 15;
1877 float dx = tex.s * .0625f; // 16 images/row
1878 float dy = tex.t * .5f ; // 2 images/column
1586 1879
1880 // this time naively avoiding texture state changes
1881 // save gobs of state changes.
1882 if (last_name != tex.name)
1883 {
1884 if (!tex.name)
1885 continue; // smoothing not yet available
1886
1587 glEnd (); 1887 glEnd ();
1588 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1888 glBindTexture (GL_TEXTURE_2D, last_name = tex.name);
1589 glBegin (GL_QUADS); 1889 glBegin (GL_QUADS);
1890 }
1590 1891
1892 if (border)
1893 {
1894 float ox = border * dx;
1895
1896 glTexCoord2f (ox , 0.f ); glVertex2f (px , py );
1897 glTexCoord2f (ox , dy ); glVertex2f (px , py + T);
1898 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py + T);
1899 glTexCoord2f (ox + dx, 0.f ); glVertex2f (px + T, py );
1900 }
1901
1902 if (corner)
1903 {
1904 float ox = corner * dx;
1905
1591 glTexCoord2f (0 , 0 ); glVertex2f (px , py ); 1906 glTexCoord2f (ox , dy ); glVertex2f (px , py );
1592 glTexCoord2f (0 , tex.t); glVertex2f (px , py + T); 1907 glTexCoord2f (ox , dy * 2.f); glVertex2f (px , py + T);
1593 glTexCoord2f (tex.s, tex.t); glVertex2f (px + T, py + T); 1908 glTexCoord2f (ox + dx, dy * 2.f); glVertex2f (px + T, py + T);
1594 glTexCoord2f (tex.s, 0 ); glVertex2f (px + T, py ); 1909 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py );
1910 }
1595 } 1911 }
1596 } 1912 }
1597 } 1913 }
1598 }
1599 } 1914 }
1915 }
1916
1917 hv_clear (smooth);
1918 }
1600 1919
1601 glEnd (); 1920 glEnd ();
1602 1921
1603 glDisable (GL_TEXTURE_2D); 1922 glDisable (GL_TEXTURE_2D);
1604 glDisable (GL_BLEND); 1923 glDisable (GL_BLEND);
1698void 2017void
1699fow_texture (CFPlus::Map self, int mx, int my, int sw, int sh) 2018fow_texture (CFPlus::Map self, int mx, int my, int sw, int sh)
1700 PPCODE: 2019 PPCODE:
1701{ 2020{
1702 int x, y; 2021 int x, y;
2022 int sw1 = sw + 2;
2023 int sh1 = sh + 2;
2024 int sh3 = sh * 3;
1703 int sw4 = (sw + 3) & ~3; 2025 int sw34 = (sw * 3 + 3) & ~3;
2026 uint8_t *darkness1 = (uint8_t *)malloc (sw1 * sh1);
1704 SV *darkness_sv = sv_2mortal (newSV (sw4 * sh)); 2027 SV *darkness3_sv = sv_2mortal (newSV (sw34 * sh3));
1705 uint8_t *darkness = (uint8_t *)SvPVX (darkness_sv); 2028 uint8_t *darkness3 = (uint8_t *)SvPVX (darkness3_sv);
1706 2029
1707 memset (darkness, 255, sw4 * sh);
1708 SvPOK_only (darkness_sv); 2030 SvPOK_only (darkness3_sv);
1709 SvCUR_set (darkness_sv, sw4 * sh); 2031 SvCUR_set (darkness3_sv, sw34 * sh3);
1710 2032
1711 mx += self->x; 2033 mx += self->x - 1;
1712 my += self->y; 2034 my += self->y - 1;
1713 2035
2036 memset (darkness1, 255, sw1 * sh1);
2037
1714 for (y = 0; y < sh; y++) 2038 for (y = 0; y < sh1; y++)
1715 if (0 <= y + my && y + my < self->rows) 2039 if (0 <= y + my && y + my < self->rows)
1716 { 2040 {
1717 maprow *row = self->row + (y + my); 2041 maprow *row = self->row + (y + my);
1718 2042
1719 for (x = 0; x < sw; x++) 2043 for (x = 0; x < sw1; x++)
1720 if (row->c0 <= x + mx && x + mx < row->c1) 2044 if (row->c0 <= x + mx && x + mx < row->c1)
1721 { 2045 {
1722 mapcell *cell = row->col + (x + mx - row->c0); 2046 mapcell *cell = row->col + (x + mx - row->c0);
1723 2047
1724 darkness[y * sw4 + x] = cell->darkness 2048 darkness1 [y * sw1 + x] = cell->darkness
1725 ? 255 - (cell->darkness - 1) 2049 ? 255 - (cell->darkness - 1)
1726 : 255 - FOW_DARKNESS; 2050 : 255 - FOW_DARKNESS;
1727 } 2051 }
1728 } 2052 }
1729 2053
2054 for (y = 0; y < sh; ++y)
2055 for (x = 0; x < sw; ++x)
2056 {
2057 uint8_t d11 = darkness1 [(y ) * sw1 + x ];
2058 uint8_t d21 = darkness1 [(y ) * sw1 + x + 1];
2059 uint8_t d31 = darkness1 [(y ) * sw1 + x + 2];
2060 uint8_t d12 = darkness1 [(y + 1) * sw1 + x ];
2061 uint8_t d22 = darkness1 [(y + 1) * sw1 + x + 1];
2062 uint8_t d32 = darkness1 [(y + 1) * sw1 + x + 2];
2063 uint8_t d13 = darkness1 [(y + 2) * sw1 + x ];
2064 uint8_t d23 = darkness1 [(y + 2) * sw1 + x + 1];
2065 uint8_t d33 = darkness1 [(y + 2) * sw1 + x + 2];
2066
2067 uint8_t r11 = (d11 + d21 + d12) / 3;
2068 uint8_t r21 = d21;
2069 uint8_t r31 = (d21 + d31 + d32) / 3;
2070
2071 uint8_t r12 = d12;
2072 uint8_t r22 = d22;
2073 uint8_t r32 = d32;
2074
2075 uint8_t r13 = (d13 + d23 + d12) / 3;
2076 uint8_t r23 = d23;
2077 uint8_t r33 = (d23 + d33 + d32) / 3;
2078
2079 darkness3 [(y * 3 ) * sw34 + (x * 3 )] = MAX (d22, r11);
2080 darkness3 [(y * 3 ) * sw34 + (x * 3 + 1)] = MAX (d22, r21);
2081 darkness3 [(y * 3 ) * sw34 + (x * 3 + 2)] = MAX (d22, r31);
2082 darkness3 [(y * 3 + 1) * sw34 + (x * 3 )] = MAX (d22, r12);
2083 darkness3 [(y * 3 + 1) * sw34 + (x * 3 + 1)] = MAX (d22, r22);
2084 darkness3 [(y * 3 + 1) * sw34 + (x * 3 + 2)] = MAX (d22, r32);
2085 darkness3 [(y * 3 + 2) * sw34 + (x * 3 )] = MAX (d22, r13);
2086 darkness3 [(y * 3 + 2) * sw34 + (x * 3 + 1)] = MAX (d22, r23);
2087 darkness3 [(y * 3 + 2) * sw34 + (x * 3 + 2)] = MAX (d22, r33);
2088 }
2089
2090 free (darkness1);
2091
1730 EXTEND (SP, 3); 2092 EXTEND (SP, 3);
1731 PUSHs (sv_2mortal (newSViv (sw4))); 2093 PUSHs (sv_2mortal (newSViv (sw34)));
1732 PUSHs (sv_2mortal (newSViv (sh))); 2094 PUSHs (sv_2mortal (newSViv (sh3)));
1733 PUSHs (darkness_sv); 2095 PUSHs (darkness3_sv);
1734} 2096}
1735 2097
1736SV * 2098SV *
1737get_rect (CFPlus::Map self, int x0, int y0, int w, int h) 2099get_rect (CFPlus::Map self, int x0, int y0, int w, int h)
1738 CODE: 2100 CODE:
1872 } 2234 }
1873} 2235}
1874 2236
1875MODULE = CFPlus PACKAGE = CFPlus::MixChunk 2237MODULE = CFPlus PACKAGE = CFPlus::MixChunk
1876 2238
2239PROTOTYPES: DISABLE
2240
2241CFPlus::MixChunk
2242new (SV *class, SV *data_sv)
2243 CODE:
2244{
2245 STRLEN datalen;
2246 char *data = SvPVbyte (data_sv, datalen);
2247
2248 RETVAL = Mix_LoadWAV_RW (SDL_RWFromConstMem (data, datalen), 1);
2249}
2250 OUTPUT:
2251 RETVAL
2252
1877CFPlus::MixChunk 2253CFPlus::MixChunk
1878new_from_file (SV *class, char *path) 2254new_from_file (SV *class, char *path)
1879 CODE: 2255 CODE:
1880 RETVAL = Mix_LoadWAV (path); 2256 RETVAL = Mix_LoadWAV (path);
1881 OUTPUT: 2257 OUTPUT:
1902 2278
1903MODULE = CFPlus PACKAGE = CFPlus::MixMusic 2279MODULE = CFPlus PACKAGE = CFPlus::MixMusic
1904 2280
1905int 2281int
1906volume (int volume = -1) 2282volume (int volume = -1)
2283 PROTOTYPE: ;$
1907 CODE: 2284 CODE:
1908 RETVAL = Mix_VolumeMusic (volume); 2285 RETVAL = Mix_VolumeMusic (volume);
1909 OUTPUT: 2286 OUTPUT:
1910 RETVAL 2287 RETVAL
1911 2288
2289int
2290fade_out (int ms)
2291 CODE:
2292 RETVAL = Mix_FadeOutMusic (ms);
2293 OUTPUT:
2294 RETVAL
2295
1912CFPlus::MixMusic 2296CFPlus::MixMusic
1913new_from_file (SV *class, char *path) 2297new_from_file (SV *class, char *path)
1914 CODE: 2298 CODE:
1915 RETVAL = Mix_LoadMUS (path); 2299 RETVAL = Mix_LoadMUS (path);
1916 OUTPUT: 2300 OUTPUT:
1926 CODE: 2310 CODE:
1927 RETVAL = Mix_PlayMusic (self, loops); 2311 RETVAL = Mix_PlayMusic (self, loops);
1928 OUTPUT: 2312 OUTPUT:
1929 RETVAL 2313 RETVAL
1930 2314
2315int
2316fade_in_pos (CFPlus::MixMusic self, int loops, int ms, double position)
2317 CODE:
2318 RETVAL = Mix_FadeInMusicPos (self, loops, ms, position);
2319 OUTPUT:
2320 RETVAL
2321
1931MODULE = CFPlus PACKAGE = CFPlus::OpenGL 2322MODULE = CFPlus PACKAGE = CFPlus::OpenGL
2323
2324PROTOTYPES: ENABLE
1932 2325
1933BOOT: 2326BOOT:
1934{ 2327{
1935 HV *stash = gv_stashpv ("CFPlus::OpenGL", 1); 2328 HV *stash = gv_stashpv ("CFPlus::OpenGL", 1);
1936 static const struct { 2329 static const struct {
1937 const char *name; 2330 const char *name;
1938 IV iv; 2331 IV iv;
1939 } *civ, const_iv[] = { 2332 } *civ, const_iv[] = {
1940# define const_iv(name) { # name, (IV)name } 2333# define const_iv(name) { # name, (IV)name }
2334 const_iv (GL_VENDOR),
2335 const_iv (GL_VERSION),
2336 const_iv (GL_EXTENSIONS),
1941 const_iv (GL_COLOR_MATERIAL), 2337 const_iv (GL_COLOR_MATERIAL),
1942 const_iv (GL_SMOOTH), 2338 const_iv (GL_SMOOTH),
1943 const_iv (GL_FLAT), 2339 const_iv (GL_FLAT),
1944 const_iv (GL_DITHER), 2340 const_iv (GL_DITHER),
1945 const_iv (GL_BLEND), 2341 const_iv (GL_BLEND),
1949 const_iv (GL_ALPHA_TEST), 2345 const_iv (GL_ALPHA_TEST),
1950 const_iv (GL_NORMALIZE), 2346 const_iv (GL_NORMALIZE),
1951 const_iv (GL_RESCALE_NORMAL), 2347 const_iv (GL_RESCALE_NORMAL),
1952 const_iv (GL_FRONT), 2348 const_iv (GL_FRONT),
1953 const_iv (GL_BACK), 2349 const_iv (GL_BACK),
2350 const_iv (GL_AUX0),
1954 const_iv (GL_AND), 2351 const_iv (GL_AND),
1955 const_iv (GL_ONE), 2352 const_iv (GL_ONE),
1956 const_iv (GL_ZERO), 2353 const_iv (GL_ZERO),
1957 const_iv (GL_SRC_ALPHA), 2354 const_iv (GL_SRC_ALPHA),
1958 const_iv (GL_DST_ALPHA), 2355 const_iv (GL_DST_ALPHA),
1972 const_iv (GL_LUMINANCE), 2369 const_iv (GL_LUMINANCE),
1973 const_iv (GL_LUMINANCE_ALPHA), 2370 const_iv (GL_LUMINANCE_ALPHA),
1974 const_iv (GL_FLOAT), 2371 const_iv (GL_FLOAT),
1975 const_iv (GL_UNSIGNED_INT_8_8_8_8_REV), 2372 const_iv (GL_UNSIGNED_INT_8_8_8_8_REV),
1976 const_iv (GL_COMPILE), 2373 const_iv (GL_COMPILE),
2374 const_iv (GL_PROXY_TEXTURE_1D),
2375 const_iv (GL_PROXY_TEXTURE_2D),
1977 const_iv (GL_TEXTURE_1D), 2376 const_iv (GL_TEXTURE_1D),
1978 const_iv (GL_TEXTURE_2D), 2377 const_iv (GL_TEXTURE_2D),
1979 const_iv (GL_TEXTURE_ENV), 2378 const_iv (GL_TEXTURE_ENV),
1980 const_iv (GL_TEXTURE_MAG_FILTER), 2379 const_iv (GL_TEXTURE_MAG_FILTER),
1981 const_iv (GL_TEXTURE_MIN_FILTER), 2380 const_iv (GL_TEXTURE_MIN_FILTER),
2002 const_iv (GL_COLOR_LOGIC_OP), 2401 const_iv (GL_COLOR_LOGIC_OP),
2003 const_iv (GL_SEPARABLE_2D), 2402 const_iv (GL_SEPARABLE_2D),
2004 const_iv (GL_CONVOLUTION_2D), 2403 const_iv (GL_CONVOLUTION_2D),
2005 const_iv (GL_CONVOLUTION_BORDER_MODE), 2404 const_iv (GL_CONVOLUTION_BORDER_MODE),
2006 const_iv (GL_CONSTANT_BORDER), 2405 const_iv (GL_CONSTANT_BORDER),
2406 const_iv (GL_POINTS),
2007 const_iv (GL_LINES), 2407 const_iv (GL_LINES),
2008 const_iv (GL_LINE_STRIP), 2408 const_iv (GL_LINE_STRIP),
2009 const_iv (GL_LINE_LOOP), 2409 const_iv (GL_LINE_LOOP),
2010 const_iv (GL_QUADS), 2410 const_iv (GL_QUADS),
2011 const_iv (GL_QUAD_STRIP), 2411 const_iv (GL_QUAD_STRIP),
2012 const_iv (GL_TRIANGLES), 2412 const_iv (GL_TRIANGLES),
2013 const_iv (GL_TRIANGLE_STRIP), 2413 const_iv (GL_TRIANGLE_STRIP),
2014 const_iv (GL_TRIANGLE_FAN), 2414 const_iv (GL_TRIANGLE_FAN),
2415 const_iv (GL_POLYGON),
2015 const_iv (GL_PERSPECTIVE_CORRECTION_HINT), 2416 const_iv (GL_PERSPECTIVE_CORRECTION_HINT),
2417 const_iv (GL_POINT_SMOOTH_HINT),
2418 const_iv (GL_LINE_SMOOTH_HINT),
2419 const_iv (GL_POLYGON_SMOOTH_HINT),
2420 const_iv (GL_GENERATE_MIPMAP_HINT),
2016 const_iv (GL_FASTEST), 2421 const_iv (GL_FASTEST),
2422 const_iv (GL_DONT_CARE),
2423 const_iv (GL_NICEST),
2017 const_iv (GL_V2F), 2424 const_iv (GL_V2F),
2018 const_iv (GL_V3F), 2425 const_iv (GL_V3F),
2019 const_iv (GL_T2F_V3F), 2426 const_iv (GL_T2F_V3F),
2020 const_iv (GL_T2F_N3F_V3F), 2427 const_iv (GL_T2F_N3F_V3F),
2021# undef const_iv 2428# undef const_iv
2022 }; 2429 };
2023 2430
2024 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 2431 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
2025 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 2432 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
2433
2434 texture_av = newAV ();
2435 AvREAL_off (texture_av);
2026} 2436}
2027 2437
2028char * 2438char *
2029gl_vendor () 2439gl_vendor ()
2030 CODE: 2440 CODE:
2044 CODE: 2454 CODE:
2045 RETVAL = (char *)glGetString (GL_EXTENSIONS); 2455 RETVAL = (char *)glGetString (GL_EXTENSIONS);
2046 OUTPUT: 2456 OUTPUT:
2047 RETVAL 2457 RETVAL
2048 2458
2459const char *glGetString (GLenum pname)
2460
2461GLint glGetInteger (GLenum pname)
2462 CODE:
2463 glGetIntegerv (pname, &RETVAL);
2464 OUTPUT:
2465 RETVAL
2466
2467GLdouble glGetDouble (GLenum pname)
2468 CODE:
2469 glGetDoublev (pname, &RETVAL);
2470 OUTPUT:
2471 RETVAL
2472
2049int glGetError () 2473int glGetError ()
2050 2474
2051void glFinish () 2475void glFinish ()
2052 2476
2053void glClear (int mask) 2477void glClear (int mask)
2090# near_ and far_ are due to microsofts buggy "c" compiler 2514# near_ and far_ are due to microsofts buggy "c" compiler
2091void glFrustum (double left, double right, double bottom, double top, double near_, double far_) 2515void glFrustum (double left, double right, double bottom, double top, double near_, double far_)
2092 2516
2093# near_ and far_ are due to microsofts buggy "c" compiler 2517# near_ and far_ are due to microsofts buggy "c" compiler
2094void glOrtho (double left, double right, double bottom, double top, double near_, double far_) 2518void glOrtho (double left, double right, double bottom, double top, double near_, double far_)
2519
2520PROTOTYPES: DISABLE
2095 2521
2096void glViewport (int x, int y, int width, int height) 2522void glViewport (int x, int y, int width, int height)
2097 2523
2098void glScissor (int x, int y, int width, int height) 2524void glScissor (int x, int y, int width, int height)
2099 2525
2107 2533
2108void glRotate (float angle, float x, float y, float z) 2534void glRotate (float angle, float x, float y, float z)
2109 CODE: 2535 CODE:
2110 glRotatef (angle, x, y, z); 2536 glRotatef (angle, x, y, z);
2111 2537
2112void glBegin (int mode)
2113
2114void glEnd ()
2115
2116void glColor (float r, float g, float b, float a = 1.0) 2538void glColor (float r, float g, float b, float a = 1.0)
2117 PROTOTYPE: @
2118 ALIAS: 2539 ALIAS:
2119 glColor_premultiply = 1 2540 glColor_premultiply = 1
2120 CODE: 2541 CODE:
2121 if (ix) 2542 if (ix)
2122 { 2543 {
2125 b *= a; 2546 b *= a;
2126 } 2547 }
2127 // microsoft visual "c" rounds instead of truncating... 2548 // microsoft visual "c" rounds instead of truncating...
2128 glColor4f (r, g, b, a); 2549 glColor4f (r, g, b, a);
2129 2550
2130void glInterleavedArrays (int format, int stride, char *data)
2131
2132void glDrawElements (int mode, int count, int type, char *indices)
2133
2134# 1.2 void glDrawRangeElements (int mode, int start, int end
2135
2136void glRasterPos (float x, float y, float z = 0.) 2551void glRasterPos (float x, float y, float z = 0.)
2137 CODE: 2552 CODE:
2138 glRasterPos3f (0, 0, z); 2553 glRasterPos3f (0, 0, z);
2139 glBitmap (0, 0, 0, 0, x, y, 0); 2554 glBitmap (0, 0, 0, 0, x, y, 0);
2140 2555
2144 2559
2145void glTexCoord (float s, float t) 2560void glTexCoord (float s, float t)
2146 CODE: 2561 CODE:
2147 glTexCoord2f (s, t); 2562 glTexCoord2f (s, t);
2148 2563
2564void glRect (float x1, float y1, float x2, float y2)
2565 CODE:
2566 glRectf (x1, y1, x2, y2);
2567
2568PROTOTYPES: ENABLE
2569
2570void glBegin (int mode)
2571
2572void glEnd ()
2573
2574void glPointSize (GLfloat size)
2575
2576void glLineWidth (GLfloat width)
2577
2578void glInterleavedArrays (int format, int stride, char *data)
2579
2580void glDrawElements (int mode, int count, int type, char *indices)
2581
2582# 1.2 void glDrawRangeElements (int mode, int start, int end
2583
2149void glTexEnv (int target, int pname, float param) 2584void glTexEnv (int target, int pname, float param)
2150 CODE: 2585 CODE:
2151 glTexEnvf (target, pname, param); 2586 glTexEnvf (target, pname, param);
2152 2587
2153void glTexParameter (int target, int pname, float param) 2588void glTexParameter (int target, int pname, float param)
2175 2610
2176void glCopyTexImage2D (int target, int level, int internalformat, int x, int y, int width, int height, int border) 2611void glCopyTexImage2D (int target, int level, int internalformat, int x, int y, int width, int height, int border)
2177 2612
2178void glDrawPixels (int width, int height, int format, int type, char *pixels) 2613void glDrawPixels (int width, int height, int format, int type, char *pixels)
2179 2614
2615void glPixelZoom (float x, float y)
2616
2180void glCopyPixels (int x, int y, int width, int height, int type = GL_COLOR) 2617void glCopyPixels (int x, int y, int width, int height, int type = GL_COLOR)
2181 2618
2182int glGenTexture () 2619int glGenTexture ()
2183 CODE: 2620 CODE:
2184{ 2621 RETVAL = gen_texture ();
2185 GLuint name;
2186 glGenTextures (1, &name);
2187 RETVAL = name;
2188}
2189 OUTPUT: 2622 OUTPUT:
2190 RETVAL 2623 RETVAL
2191 2624
2192void glDeleteTexture (int name) 2625void glDeleteTexture (int name)
2193 CODE: 2626 CODE:
2194{
2195 GLuint name_ = name;
2196 glDeleteTextures (1, &name_); 2627 del_texture (name);
2197} 2628
2198
2199int glGenList () 2629int glGenList ()
2200 CODE: 2630 CODE:
2201 RETVAL = glGenLists (1); 2631 RETVAL = glGenLists (1);
2202 OUTPUT: 2632 OUTPUT:
2203 RETVAL 2633 RETVAL
2210 2640
2211void glEndList () 2641void glEndList ()
2212 2642
2213void glCallList (int list) 2643void glCallList (int list)
2214 2644
2645MODULE = CFPlus PACKAGE = CFPlus::UI::Base
2646
2647PROTOTYPES: DISABLE
2648
2649void
2650find_widget (SV *self, NV x, NV y)
2651 PPCODE:
2652{
2653 if (within_widget (self, x, y))
2654 XPUSHs (self);
2655}
2656
2657BOOT:
2658{
2659 hover_gv = gv_fetchpv ("CFPlus::UI::HOVER", 1, SVt_NV);
2660
2661 draw_x_gv = gv_fetchpv ("CFPlus::UI::Base::draw_x", 1, SVt_NV);
2662 draw_y_gv = gv_fetchpv ("CFPlus::UI::Base::draw_y", 1, SVt_NV);
2663 draw_w_gv = gv_fetchpv ("CFPlus::UI::Base::draw_w", 1, SVt_NV);
2664 draw_h_gv = gv_fetchpv ("CFPlus::UI::Base::draw_h", 1, SVt_NV);
2665}
2666
2667void
2668draw (SV *self)
2669 CODE:
2670{
2671 HV *hv;
2672 SV **svp;
2673 NV x, y, w, h;
2674 SV *draw_x_sv = GvSV (draw_x_gv);
2675 SV *draw_y_sv = GvSV (draw_y_gv);
2676 SV *draw_w_sv = GvSV (draw_w_gv);
2677 SV *draw_h_sv = GvSV (draw_h_gv);
2678 SV *hover;
2679 double draw_x, draw_y, draw_w, draw_h;
2680
2681 if (!SvROK (self))
2682 croak ("CFPlus::Base::draw: %s not a reference", SvPV_nolen (self));
2683
2684 hv = (HV *)SvRV (self);
2685
2686 if (SvTYPE (hv) != SVt_PVHV)
2687 croak ("CFPlus::Base::draw: %s not a hashref", SvPV_nolen (self));
2688
2689 svp = hv_fetch (hv, "w", 1, 0); w = svp ? SvNV (*svp) : 0.;
2690 svp = hv_fetch (hv, "h", 1, 0); h = svp ? SvNV (*svp) : 0.;
2691
2692 if (!h || !w)
2693 XSRETURN_EMPTY;
2694
2695 svp = hv_fetch (hv, "x", 1, 0); x = svp ? SvNV (*svp) : 0.;
2696 svp = hv_fetch (hv, "y", 1, 0); y = svp ? SvNV (*svp) : 0.;
2697
2698 draw_x = SvNV (draw_x_sv) + x;
2699 draw_y = SvNV (draw_y_sv) + y;
2700
2701 if (draw_x + w < 0 || draw_x >= SvNV (draw_w_sv)
2702 || draw_y + h < 0 || draw_y >= SvNV (draw_h_sv))
2703 XSRETURN_EMPTY;
2704
2705 sv_setnv (draw_x_sv, draw_x);
2706 sv_setnv (draw_y_sv, draw_y);
2707
2708 glPushMatrix ();
2709 glTranslated (x, y, 0);
2710
2711 if (SvROK (GvSV (hover_gv)) && SvRV (GvSV (hover_gv)) == (SV *)hv)
2712 {
2713 svp = hv_fetch (hv, "can_hover", sizeof ("can_hover") - 1, 0);
2714
2715 if (svp && SvTRUE (*svp))
2716 {
2717 glColor4f (1*0.2f, 0.8*0.2f, 0.5*0.2f, 0.2f);
2718 glEnable (GL_BLEND);
2719 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
2720 glBegin (GL_QUADS);
2721 glVertex2f (0, 0);
2722 glVertex2f (w, 0);
2723 glVertex2f (w, h);
2724 glVertex2f (0, h);
2725 glEnd ();
2726 glDisable (GL_BLEND);
2727 }
2728 }
2729#if 0
2730 if ($ENV{CFPLUS_DEBUG} & 1) {
2731 glPushMatrix;
2732 glColor 1, 1, 0, 1;
2733 glTranslate 0.375, 0.375;
2734 glBegin GL_LINE_LOOP;
2735 glVertex 0 , 0;
2736 glVertex $self->{w} - 1, 0;
2737 glVertex $self->{w} - 1, $self->{h} - 1;
2738 glVertex 0 , $self->{h} - 1;
2739 glEnd;
2740 glPopMatrix;
2741 #CFPlus::UI::Label->new (w => $self->{w}, h => $self->{h}, text => $self, fontsize => 0)->_draw;
2742 }
2743#endif
2744 PUSHMARK (SP);
2745 XPUSHs (self);
2746 PUTBACK;
2747 call_method ("_draw", G_VOID | G_DISCARD);
2748 SPAGAIN;
2749
2750 glPopMatrix ();
2751
2752 draw_x = draw_x - x; sv_setnv (draw_x_sv, draw_x);
2753 draw_y = draw_y - y; sv_setnv (draw_y_sv, draw_y);
2754}
2755

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines