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.210 by root, Tue Jul 24 18:24:03 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);
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
1877CFPlus::MixChunk 2241CFPlus::MixChunk
1878new_from_file (SV *class, char *path) 2242new_from_file (SV *class, char *path)
1879 CODE: 2243 CODE:
1880 RETVAL = Mix_LoadWAV (path); 2244 RETVAL = Mix_LoadWAV (path);
1881 OUTPUT: 2245 OUTPUT:
1902 2266
1903MODULE = CFPlus PACKAGE = CFPlus::MixMusic 2267MODULE = CFPlus PACKAGE = CFPlus::MixMusic
1904 2268
1905int 2269int
1906volume (int volume = -1) 2270volume (int volume = -1)
2271 PROTOTYPE: ;$
1907 CODE: 2272 CODE:
1908 RETVAL = Mix_VolumeMusic (volume); 2273 RETVAL = Mix_VolumeMusic (volume);
1909 OUTPUT: 2274 OUTPUT:
1910 RETVAL 2275 RETVAL
1911 2276
2277int
2278fade_out (int ms)
2279 CODE:
2280 RETVAL = Mix_FadeOutMusic (ms);
2281 OUTPUT:
2282 RETVAL
2283
1912CFPlus::MixMusic 2284CFPlus::MixMusic
1913new_from_file (SV *class, char *path) 2285new_from_file (SV *class, char *path)
1914 CODE: 2286 CODE:
1915 RETVAL = Mix_LoadMUS (path); 2287 RETVAL = Mix_LoadMUS (path);
1916 OUTPUT: 2288 OUTPUT:
1926 CODE: 2298 CODE:
1927 RETVAL = Mix_PlayMusic (self, loops); 2299 RETVAL = Mix_PlayMusic (self, loops);
1928 OUTPUT: 2300 OUTPUT:
1929 RETVAL 2301 RETVAL
1930 2302
2303int
2304fade_in_pos (CFPlus::MixMusic self, int loops, int ms, double position)
2305 CODE:
2306 RETVAL = Mix_FadeInMusicPos (self, loops, ms, position);
2307 OUTPUT:
2308 RETVAL
2309
1931MODULE = CFPlus PACKAGE = CFPlus::OpenGL 2310MODULE = CFPlus PACKAGE = CFPlus::OpenGL
2311
2312PROTOTYPES: ENABLE
1932 2313
1933BOOT: 2314BOOT:
1934{ 2315{
1935 HV *stash = gv_stashpv ("CFPlus::OpenGL", 1); 2316 HV *stash = gv_stashpv ("CFPlus::OpenGL", 1);
1936 static const struct { 2317 static const struct {
1937 const char *name; 2318 const char *name;
1938 IV iv; 2319 IV iv;
1939 } *civ, const_iv[] = { 2320 } *civ, const_iv[] = {
1940# define const_iv(name) { # name, (IV)name } 2321# define const_iv(name) { # name, (IV)name }
2322 const_iv (GL_VENDOR),
2323 const_iv (GL_VERSION),
2324 const_iv (GL_EXTENSIONS),
1941 const_iv (GL_COLOR_MATERIAL), 2325 const_iv (GL_COLOR_MATERIAL),
1942 const_iv (GL_SMOOTH), 2326 const_iv (GL_SMOOTH),
1943 const_iv (GL_FLAT), 2327 const_iv (GL_FLAT),
1944 const_iv (GL_DITHER), 2328 const_iv (GL_DITHER),
1945 const_iv (GL_BLEND), 2329 const_iv (GL_BLEND),
1949 const_iv (GL_ALPHA_TEST), 2333 const_iv (GL_ALPHA_TEST),
1950 const_iv (GL_NORMALIZE), 2334 const_iv (GL_NORMALIZE),
1951 const_iv (GL_RESCALE_NORMAL), 2335 const_iv (GL_RESCALE_NORMAL),
1952 const_iv (GL_FRONT), 2336 const_iv (GL_FRONT),
1953 const_iv (GL_BACK), 2337 const_iv (GL_BACK),
2338 const_iv (GL_AUX0),
1954 const_iv (GL_AND), 2339 const_iv (GL_AND),
1955 const_iv (GL_ONE), 2340 const_iv (GL_ONE),
1956 const_iv (GL_ZERO), 2341 const_iv (GL_ZERO),
1957 const_iv (GL_SRC_ALPHA), 2342 const_iv (GL_SRC_ALPHA),
1958 const_iv (GL_DST_ALPHA), 2343 const_iv (GL_DST_ALPHA),
1972 const_iv (GL_LUMINANCE), 2357 const_iv (GL_LUMINANCE),
1973 const_iv (GL_LUMINANCE_ALPHA), 2358 const_iv (GL_LUMINANCE_ALPHA),
1974 const_iv (GL_FLOAT), 2359 const_iv (GL_FLOAT),
1975 const_iv (GL_UNSIGNED_INT_8_8_8_8_REV), 2360 const_iv (GL_UNSIGNED_INT_8_8_8_8_REV),
1976 const_iv (GL_COMPILE), 2361 const_iv (GL_COMPILE),
2362 const_iv (GL_PROXY_TEXTURE_1D),
2363 const_iv (GL_PROXY_TEXTURE_2D),
1977 const_iv (GL_TEXTURE_1D), 2364 const_iv (GL_TEXTURE_1D),
1978 const_iv (GL_TEXTURE_2D), 2365 const_iv (GL_TEXTURE_2D),
1979 const_iv (GL_TEXTURE_ENV), 2366 const_iv (GL_TEXTURE_ENV),
1980 const_iv (GL_TEXTURE_MAG_FILTER), 2367 const_iv (GL_TEXTURE_MAG_FILTER),
1981 const_iv (GL_TEXTURE_MIN_FILTER), 2368 const_iv (GL_TEXTURE_MIN_FILTER),
2002 const_iv (GL_COLOR_LOGIC_OP), 2389 const_iv (GL_COLOR_LOGIC_OP),
2003 const_iv (GL_SEPARABLE_2D), 2390 const_iv (GL_SEPARABLE_2D),
2004 const_iv (GL_CONVOLUTION_2D), 2391 const_iv (GL_CONVOLUTION_2D),
2005 const_iv (GL_CONVOLUTION_BORDER_MODE), 2392 const_iv (GL_CONVOLUTION_BORDER_MODE),
2006 const_iv (GL_CONSTANT_BORDER), 2393 const_iv (GL_CONSTANT_BORDER),
2394 const_iv (GL_POINTS),
2007 const_iv (GL_LINES), 2395 const_iv (GL_LINES),
2008 const_iv (GL_LINE_STRIP), 2396 const_iv (GL_LINE_STRIP),
2009 const_iv (GL_LINE_LOOP), 2397 const_iv (GL_LINE_LOOP),
2010 const_iv (GL_QUADS), 2398 const_iv (GL_QUADS),
2011 const_iv (GL_QUAD_STRIP), 2399 const_iv (GL_QUAD_STRIP),
2012 const_iv (GL_TRIANGLES), 2400 const_iv (GL_TRIANGLES),
2013 const_iv (GL_TRIANGLE_STRIP), 2401 const_iv (GL_TRIANGLE_STRIP),
2014 const_iv (GL_TRIANGLE_FAN), 2402 const_iv (GL_TRIANGLE_FAN),
2403 const_iv (GL_POLYGON),
2015 const_iv (GL_PERSPECTIVE_CORRECTION_HINT), 2404 const_iv (GL_PERSPECTIVE_CORRECTION_HINT),
2405 const_iv (GL_POINT_SMOOTH_HINT),
2406 const_iv (GL_LINE_SMOOTH_HINT),
2407 const_iv (GL_POLYGON_SMOOTH_HINT),
2408 const_iv (GL_GENERATE_MIPMAP_HINT),
2016 const_iv (GL_FASTEST), 2409 const_iv (GL_FASTEST),
2410 const_iv (GL_DONT_CARE),
2411 const_iv (GL_NICEST),
2017 const_iv (GL_V2F), 2412 const_iv (GL_V2F),
2018 const_iv (GL_V3F), 2413 const_iv (GL_V3F),
2019 const_iv (GL_T2F_V3F), 2414 const_iv (GL_T2F_V3F),
2020 const_iv (GL_T2F_N3F_V3F), 2415 const_iv (GL_T2F_N3F_V3F),
2021# undef const_iv 2416# undef const_iv
2022 }; 2417 };
2023 2418
2024 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 2419 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
2025 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 2420 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
2421
2422 texture_av = newAV ();
2423 AvREAL_off (texture_av);
2026} 2424}
2027 2425
2028char * 2426char *
2029gl_vendor () 2427gl_vendor ()
2030 CODE: 2428 CODE:
2044 CODE: 2442 CODE:
2045 RETVAL = (char *)glGetString (GL_EXTENSIONS); 2443 RETVAL = (char *)glGetString (GL_EXTENSIONS);
2046 OUTPUT: 2444 OUTPUT:
2047 RETVAL 2445 RETVAL
2048 2446
2447const char *glGetString (GLenum pname)
2448
2449GLint glGetInteger (GLenum pname)
2450 CODE:
2451 glGetIntegerv (pname, &RETVAL);
2452 OUTPUT:
2453 RETVAL
2454
2455GLdouble glGetDouble (GLenum pname)
2456 CODE:
2457 glGetDoublev (pname, &RETVAL);
2458 OUTPUT:
2459 RETVAL
2460
2049int glGetError () 2461int glGetError ()
2050 2462
2051void glFinish () 2463void glFinish ()
2052 2464
2053void glClear (int mask) 2465void glClear (int mask)
2090# near_ and far_ are due to microsofts buggy "c" compiler 2502# near_ and far_ are due to microsofts buggy "c" compiler
2091void glFrustum (double left, double right, double bottom, double top, double near_, double far_) 2503void glFrustum (double left, double right, double bottom, double top, double near_, double far_)
2092 2504
2093# near_ and far_ are due to microsofts buggy "c" compiler 2505# near_ and far_ are due to microsofts buggy "c" compiler
2094void glOrtho (double left, double right, double bottom, double top, double near_, double far_) 2506void glOrtho (double left, double right, double bottom, double top, double near_, double far_)
2507
2508PROTOTYPES: DISABLE
2095 2509
2096void glViewport (int x, int y, int width, int height) 2510void glViewport (int x, int y, int width, int height)
2097 2511
2098void glScissor (int x, int y, int width, int height) 2512void glScissor (int x, int y, int width, int height)
2099 2513
2107 2521
2108void glRotate (float angle, float x, float y, float z) 2522void glRotate (float angle, float x, float y, float z)
2109 CODE: 2523 CODE:
2110 glRotatef (angle, x, y, z); 2524 glRotatef (angle, x, y, z);
2111 2525
2112void glBegin (int mode)
2113
2114void glEnd ()
2115
2116void glColor (float r, float g, float b, float a = 1.0) 2526void glColor (float r, float g, float b, float a = 1.0)
2117 PROTOTYPE: @
2118 ALIAS: 2527 ALIAS:
2119 glColor_premultiply = 1 2528 glColor_premultiply = 1
2120 CODE: 2529 CODE:
2121 if (ix) 2530 if (ix)
2122 { 2531 {
2125 b *= a; 2534 b *= a;
2126 } 2535 }
2127 // microsoft visual "c" rounds instead of truncating... 2536 // microsoft visual "c" rounds instead of truncating...
2128 glColor4f (r, g, b, a); 2537 glColor4f (r, g, b, a);
2129 2538
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.) 2539void glRasterPos (float x, float y, float z = 0.)
2137 CODE: 2540 CODE:
2138 glRasterPos3f (0, 0, z); 2541 glRasterPos3f (0, 0, z);
2139 glBitmap (0, 0, 0, 0, x, y, 0); 2542 glBitmap (0, 0, 0, 0, x, y, 0);
2140 2543
2144 2547
2145void glTexCoord (float s, float t) 2548void glTexCoord (float s, float t)
2146 CODE: 2549 CODE:
2147 glTexCoord2f (s, t); 2550 glTexCoord2f (s, t);
2148 2551
2552void glRect (float x1, float y1, float x2, float y2)
2553 CODE:
2554 glRectf (x1, y1, x2, y2);
2555
2556PROTOTYPES: ENABLE
2557
2558void glBegin (int mode)
2559
2560void glEnd ()
2561
2562void glPointSize (GLfloat size)
2563
2564void glLineWidth (GLfloat width)
2565
2566void glInterleavedArrays (int format, int stride, char *data)
2567
2568void glDrawElements (int mode, int count, int type, char *indices)
2569
2570# 1.2 void glDrawRangeElements (int mode, int start, int end
2571
2149void glTexEnv (int target, int pname, float param) 2572void glTexEnv (int target, int pname, float param)
2150 CODE: 2573 CODE:
2151 glTexEnvf (target, pname, param); 2574 glTexEnvf (target, pname, param);
2152 2575
2153void glTexParameter (int target, int pname, float param) 2576void glTexParameter (int target, int pname, float param)
2175 2598
2176void glCopyTexImage2D (int target, int level, int internalformat, int x, int y, int width, int height, int border) 2599void glCopyTexImage2D (int target, int level, int internalformat, int x, int y, int width, int height, int border)
2177 2600
2178void glDrawPixels (int width, int height, int format, int type, char *pixels) 2601void glDrawPixels (int width, int height, int format, int type, char *pixels)
2179 2602
2603void glPixelZoom (float x, float y)
2604
2180void glCopyPixels (int x, int y, int width, int height, int type = GL_COLOR) 2605void glCopyPixels (int x, int y, int width, int height, int type = GL_COLOR)
2181 2606
2182int glGenTexture () 2607int glGenTexture ()
2183 CODE: 2608 CODE:
2184{ 2609 RETVAL = gen_texture ();
2185 GLuint name;
2186 glGenTextures (1, &name);
2187 RETVAL = name;
2188}
2189 OUTPUT: 2610 OUTPUT:
2190 RETVAL 2611 RETVAL
2191 2612
2192void glDeleteTexture (int name) 2613void glDeleteTexture (int name)
2193 CODE: 2614 CODE:
2194{
2195 GLuint name_ = name;
2196 glDeleteTextures (1, &name_); 2615 del_texture (name);
2197} 2616
2198
2199int glGenList () 2617int glGenList ()
2200 CODE: 2618 CODE:
2201 RETVAL = glGenLists (1); 2619 RETVAL = glGenLists (1);
2202 OUTPUT: 2620 OUTPUT:
2203 RETVAL 2621 RETVAL
2210 2628
2211void glEndList () 2629void glEndList ()
2212 2630
2213void glCallList (int list) 2631void glCallList (int list)
2214 2632
2633MODULE = CFPlus PACKAGE = CFPlus::UI::Base
2634
2635PROTOTYPES: DISABLE
2636
2637void
2638find_widget (SV *self, NV x, NV y)
2639 PPCODE:
2640{
2641 if (within_widget (self, x, y))
2642 XPUSHs (self);
2643}
2644
2645BOOT:
2646{
2647 hover_gv = gv_fetchpv ("CFPlus::UI::HOVER", 1, SVt_NV);
2648
2649 draw_x_gv = gv_fetchpv ("CFPlus::UI::Base::draw_x", 1, SVt_NV);
2650 draw_y_gv = gv_fetchpv ("CFPlus::UI::Base::draw_y", 1, SVt_NV);
2651 draw_w_gv = gv_fetchpv ("CFPlus::UI::Base::draw_w", 1, SVt_NV);
2652 draw_h_gv = gv_fetchpv ("CFPlus::UI::Base::draw_h", 1, SVt_NV);
2653}
2654
2655void
2656draw (SV *self)
2657 CODE:
2658{
2659 HV *hv;
2660 SV **svp;
2661 NV x, y, w, h;
2662 SV *draw_x_sv = GvSV (draw_x_gv);
2663 SV *draw_y_sv = GvSV (draw_y_gv);
2664 SV *draw_w_sv = GvSV (draw_w_gv);
2665 SV *draw_h_sv = GvSV (draw_h_gv);
2666 SV *hover;
2667 double draw_x, draw_y, draw_w, draw_h;
2668
2669 if (!SvROK (self))
2670 croak ("CFPlus::Base::draw: %s not a reference", SvPV_nolen (self));
2671
2672 hv = (HV *)SvRV (self);
2673
2674 if (SvTYPE (hv) != SVt_PVHV)
2675 croak ("CFPlus::Base::draw: %s not a hashref", SvPV_nolen (self));
2676
2677 svp = hv_fetch (hv, "w", 1, 0); w = svp ? SvNV (*svp) : 0.;
2678 svp = hv_fetch (hv, "h", 1, 0); h = svp ? SvNV (*svp) : 0.;
2679
2680 if (!h || !w)
2681 XSRETURN_EMPTY;
2682
2683 svp = hv_fetch (hv, "x", 1, 0); x = svp ? SvNV (*svp) : 0.;
2684 svp = hv_fetch (hv, "y", 1, 0); y = svp ? SvNV (*svp) : 0.;
2685
2686 draw_x = SvNV (draw_x_sv) + x;
2687 draw_y = SvNV (draw_y_sv) + y;
2688
2689 if (draw_x + w < 0 || draw_x >= SvNV (draw_w_sv)
2690 || draw_y + h < 0 || draw_y >= SvNV (draw_h_sv))
2691 XSRETURN_EMPTY;
2692
2693 sv_setnv (draw_x_sv, draw_x);
2694 sv_setnv (draw_y_sv, draw_y);
2695
2696 glPushMatrix ();
2697 glTranslated (x, y, 0);
2698
2699 if (SvROK (GvSV (hover_gv)) && SvRV (GvSV (hover_gv)) == (SV *)hv)
2700 {
2701 svp = hv_fetch (hv, "can_hover", sizeof ("can_hover") - 1, 0);
2702
2703 if (svp && SvTRUE (*svp))
2704 {
2705 glColor4f (1*0.2f, 0.8*0.2f, 0.5*0.2f, 0.2f);
2706 glEnable (GL_BLEND);
2707 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
2708 glBegin (GL_QUADS);
2709 glVertex2f (0, 0);
2710 glVertex2f (w, 0);
2711 glVertex2f (w, h);
2712 glVertex2f (0, h);
2713 glEnd ();
2714 glDisable (GL_BLEND);
2715 }
2716 }
2717#if 0
2718 if ($ENV{CFPLUS_DEBUG} & 1) {
2719 glPushMatrix;
2720 glColor 1, 1, 0, 1;
2721 glTranslate 0.375, 0.375;
2722 glBegin GL_LINE_LOOP;
2723 glVertex 0 , 0;
2724 glVertex $self->{w} - 1, 0;
2725 glVertex $self->{w} - 1, $self->{h} - 1;
2726 glVertex 0 , $self->{h} - 1;
2727 glEnd;
2728 glPopMatrix;
2729 #CFPlus::UI::Label->new (w => $self->{w}, h => $self->{h}, text => $self, fontsize => 0)->_draw;
2730 }
2731#endif
2732 PUSHMARK (SP);
2733 XPUSHs (self);
2734 PUTBACK;
2735 call_method ("_draw", G_VOID | G_DISCARD);
2736 SPAGAIN;
2737
2738 glPopMatrix ();
2739
2740 draw_x = draw_x - x; sv_setnv (draw_x_sv, draw_x);
2741 draw_y = draw_y - y; sv_setnv (draw_y_sv, draw_y);
2742}
2743

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines