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.69 by root, Sun Apr 30 08:09:44 2006 UTC vs.
Revision 1.78 by root, Fri May 12 01:47:03 2006 UTC

1#ifdef _WIN32 1#ifdef _WIN32
2# include <malloc.h> 2# include <malloc.h>
3# pragma warning(disable:4244)
3#endif 4#endif
4 5
5#include "EXTERN.h" 6#include "EXTERN.h"
6#include "perl.h" 7#include "perl.h"
7#include "XSUB.h" 8#include "XSUB.h"
8 9
9#include <string.h> 10#include <string.h>
10#include <stdio.h> 11#include <stdio.h>
11 12
12#include <SDL.h> 13#include <SDL.h>
14#include <SDL_endian.h>
13#include <SDL_image.h> 15#include <SDL_image.h>
14#include <SDL_mixer.h> 16#include <SDL_mixer.h>
15#include <SDL_opengl.h> 17#include <SDL_opengl.h>
16 18
17#include <glib/gmacros.h> 19#include <glib/gmacros.h>
18 20
19#include <pango/pango.h> 21#include <pango/pango.h>
20#include <pango/pangofc-fontmap.h> 22#include <pango/pangofc-fontmap.h>
21#include <pango/pangoft2.h> 23#include <pango/pangoft2.h>
24#include <pango/pangocairo.h>
22 25
23#ifndef _WIN32 26#ifndef _WIN32
24# include <sys/types.h> 27# include <sys/types.h>
25# include <sys/socket.h> 28# include <sys/socket.h>
26# include <netinet/in.h> 29# include <netinet/in.h>
63typedef Mix_Music *CFClient__MixMusic; 66typedef Mix_Music *CFClient__MixMusic;
64 67
65typedef PangoFontDescription *CFClient__Font; 68typedef PangoFontDescription *CFClient__Font;
66 69
67typedef struct cf_layout { 70typedef struct cf_layout {
68 PangoLayout *pl; 71 PangoLayout *pl; // either derived from a cairo or ft2 context
72 int rgba; // wether we use rgba (cairo) or grayscale (ft2)
73 float r, g, b, a; // default color for rgba mode
69 int base_height; 74 int base_height;
70 CFClient__Font font; 75 CFClient__Font font;
71} *CFClient__Layout; 76} *CFClient__Layout;
72 77
73static CFClient__Font default_font; 78static CFClient__Font default_font;
74static PangoContext *context; 79static PangoContext *ft2_context, *cairo_context;
75static PangoFontMap *fontmap; 80static PangoFontMap *ft2_fontmap, *cairo_fontmap;
76 81
77static void 82static void
78substitute_func (FcPattern *pattern, gpointer data) 83substitute_func (FcPattern *pattern, gpointer data)
79{ 84{
80 FcPatternAddBool (pattern, FC_HINTING , 1); 85 FcPatternAddBool (pattern, FC_HINTING , 1);
98static void 103static void
99layout_get_pixel_size (CFClient__Layout self, int *w, int *h) 104layout_get_pixel_size (CFClient__Layout self, int *w, int *h)
100{ 105{
101 pango_layout_get_pixel_size (self->pl, w, h); 106 pango_layout_get_pixel_size (self->pl, w, h);
102 107
103 *w = (*w + 3) & ~3;
104 if (!*w) *w = 1; 108 if (!*w) *w = 1;
105 if (!*h) *h = 1; 109 if (!*h) *h = 1;
110
111 *w = (*w + 3) & ~3;
106} 112}
107 113
108typedef uint16_t mapface; 114typedef uint16_t mapface;
109 115
110typedef struct { 116typedef struct {
258 } 264 }
259 } 265 }
260} 266}
261 267
262static void 268static void
263music_finished () 269music_finished (void)
264{ 270{
265 SDL_UserEvent ev; 271 SDL_UserEvent ev;
266 272
267 ev.type = SDL_USEREVENT; 273 ev.type = SDL_USEREVENT;
268 ev.code = 0; 274 ev.code = 0;
269 ev.data1 = 0; 275 ev.data1 = 0;
276 ev.data2 = 0;
277
278 SDL_PushEvent ((SDL_Event *)&ev);
279}
280
281static void
282channel_finished (int channel)
283{
284 SDL_UserEvent ev;
285
286 ev.type = SDL_USEREVENT;
287 ev.code = 1;
288 ev.data1 = (void *)(long)channel;
270 ev.data2 = 0; 289 ev.data2 = 0;
271 290
272 SDL_PushEvent ((SDL_Event *)&ev); 291 SDL_PushEvent ((SDL_Event *)&ev);
273} 292}
274 293
386 }; 405 };
387 406
388 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 407 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
389 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 408 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
390 409
391 fontmap = pango_ft2_font_map_new (); 410 ft2_fontmap = pango_ft2_font_map_new ();
392 pango_ft2_font_map_set_default_substitute ((PangoFT2FontMap *)fontmap, substitute_func, 0, 0); 411 pango_ft2_font_map_set_default_substitute ((PangoFT2FontMap *)ft2_fontmap, substitute_func, 0, 0);
393 context = pango_ft2_font_map_create_context ((PangoFT2FontMap *)fontmap); 412 ft2_context = pango_ft2_font_map_create_context ((PangoFT2FontMap *)ft2_fontmap);
413
414 cairo_fontmap = pango_cairo_font_map_get_default ();
415 cairo_context = pango_cairo_font_map_create_context ((PangoCairoFontMap *)cairo_fontmap);
394} 416}
395 417
396int 418int
397SDL_Init (U32 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO) 419SDL_Init (U32 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO)
398 420
457 479
458 while (SDL_PollEvent (&ev)) 480 while (SDL_PollEvent (&ev))
459 { 481 {
460 HV *hv = newHV (); 482 HV *hv = newHV ();
461 hv_store (hv, "type", 4, newSViv (ev.type), 0); 483 hv_store (hv, "type", 4, newSViv (ev.type), 0);
484
462 switch (ev.type) 485 switch (ev.type)
463 { 486 {
464 case SDL_KEYDOWN: 487 case SDL_KEYDOWN:
465 case SDL_KEYUP: 488 case SDL_KEYUP:
466 hv_store (hv, "state", 5, newSViv (ev.key.state), 0); 489 hv_store (hv, "state", 5, newSViv (ev.key.state), 0);
486 case SDL_MOUSEBUTTONUP: 509 case SDL_MOUSEBUTTONUP:
487 hv_store (hv, "button", 6, newSViv (ev.button.button), 0); 510 hv_store (hv, "button", 6, newSViv (ev.button.button), 0);
488 hv_store (hv, "state", 5, newSViv (ev.button.state), 0); 511 hv_store (hv, "state", 5, newSViv (ev.button.state), 0);
489 hv_store (hv, "x", 1, newSViv (ev.button.x), 0); 512 hv_store (hv, "x", 1, newSViv (ev.button.x), 0);
490 hv_store (hv, "y", 1, newSViv (ev.button.y), 0); 513 hv_store (hv, "y", 1, newSViv (ev.button.y), 0);
514 break;
515
516 case SDL_USEREVENT:
517 hv_store (hv, "code", 4, newSViv (ev.user.code), 0);
518 hv_store (hv, "data1", 5, newSViv ((IV)ev.user.data1), 0);
519 hv_store (hv, "data2", 5, newSViv ((IV)ev.user.data2), 0);
520 break;
491 } 521 }
492 522
493 XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv))); 523 XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv)));
494 } 524 }
495} 525}
496 526
497int 527int
498Mix_OpenAudio (int frequency = 22050, int format = MIX_DEFAULT_FORMAT, int channels = 1, int chunksize = 512) 528Mix_OpenAudio (int frequency = 48000, int format = MIX_DEFAULT_FORMAT, int channels = 1, int chunksize = 2048)
499 POSTCALL: 529 POSTCALL:
500 Mix_HookMusicFinished (music_finished); 530 Mix_HookMusicFinished (music_finished);
531 Mix_ChannelFinished (channel_finished);
501 532
502void 533void
503Mix_CloseAudio () 534Mix_CloseAudio ()
504 535
505int 536int
640 exit (1); 671 exit (1);
641 672
642MODULE = CFClient PACKAGE = CFClient::Font 673MODULE = CFClient PACKAGE = CFClient::Font
643 674
644CFClient::Font 675CFClient::Font
645new_from_file (SV *class, char *path) 676new_from_file (SV *class, char *path, int id = 0)
646 CODE: 677 CODE:
647{ 678{
648 int count; 679 int count;
649 FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)path, 0, 0, &count); 680 FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)path, id, 0, &count);
650 RETVAL = pango_fc_font_description_from_pattern (pattern, 0); 681 RETVAL = pango_fc_font_description_from_pattern (pattern, 0);
651 FcPatternDestroy (pattern); 682 FcPatternDestroy (pattern);
652} 683}
653 OUTPUT: 684 OUTPUT:
654 RETVAL 685 RETVAL
664 default_font = self; 695 default_font = self;
665 696
666MODULE = CFClient PACKAGE = CFClient::Layout 697MODULE = CFClient PACKAGE = CFClient::Layout
667 698
668CFClient::Layout 699CFClient::Layout
669new (SV *class, int base_height = MIN_FONT_HEIGHT) 700new (SV *class, int rgba = 0)
670 CODE: 701 CODE:
671 New (0, RETVAL, 1, struct cf_layout); 702 New (0, RETVAL, 1, struct cf_layout);
672 RETVAL->pl = pango_layout_new (context); 703
673 RETVAL->base_height = base_height; 704 RETVAL->pl = pango_layout_new (rgba ? cairo_context : ft2_context);
705 RETVAL->rgba = rgba;
706 RETVAL->r = 1.;
707 RETVAL->g = 1.;
708 RETVAL->b = 1.;
709 RETVAL->a = 1.;
710 RETVAL->base_height = MIN_FONT_HEIGHT;
674 RETVAL->font = 0; 711 RETVAL->font = 0;
712
675 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR); 713 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
676 pango_layout_set_font_description (RETVAL->pl, default_font); 714 layout_update_font (RETVAL);
677 OUTPUT: 715 OUTPUT:
678 RETVAL 716 RETVAL
679 717
680void 718void
681DESTROY (CFClient::Layout self) 719DESTROY (CFClient::Layout self)
682 CODE: 720 CODE:
683 g_object_unref (self->pl); 721 g_object_unref (self->pl);
684 Safefree (self); 722 Safefree (self);
685 723
724int
725is_rgba (CFClient::Layout self)
726 CODE:
727 RETVAL = self->rgba;
728 OUTPUT:
729 RETVAL
730
686void 731void
687set_text (CFClient::Layout self, SV *text_) 732set_text (CFClient::Layout self, SV *text_)
688 CODE: 733 CODE:
689{ 734{
690 STRLEN textlen; 735 STRLEN textlen;
708 CODE: 753 CODE:
709 RETVAL = newSVpv (pango_layout_get_text (self->pl), 0); 754 RETVAL = newSVpv (pango_layout_get_text (self->pl), 0);
710 SvUTF8_on (RETVAL); 755 SvUTF8_on (RETVAL);
711 OUTPUT: 756 OUTPUT:
712 RETVAL 757 RETVAL
758
759void
760set_foreground (CFClient::Layout self, float r, float g, float b, float a = 1.)
761 CODE:
762 self->r = r;
763 self->g = g;
764 self->b = b;
765 self->a = a;
713 766
714void 767void
715set_font (CFClient::Layout self, CFClient::Font font = 0) 768set_font (CFClient::Layout self, CFClient::Font font = 0)
716 CODE: 769 CODE:
717 if (self->font != font) 770 if (self->font != font)
775render (CFClient::Layout self) 828render (CFClient::Layout self)
776 PPCODE: 829 PPCODE:
777{ 830{
778 SV *retval; 831 SV *retval;
779 int w, h; 832 int w, h;
780 FT_Bitmap bitmap;
781 833
782 layout_get_pixel_size (self, &w, &h); 834 layout_get_pixel_size (self, &w, &h);
783 835
836 if (self->rgba)
837 {
838 cairo_surface_t *surface;
839 cairo_t *cairo;
840
841 retval = newSV (w * h * 4);
842 SvPOK_only (retval);
843 SvCUR_set (retval, w * h * 4);
844
845 memset (SvPVX (retval), 0, w * h * 4);
846
847 surface = cairo_image_surface_create_for_data (
848 (void*)SvPVX (retval), CAIRO_FORMAT_ARGB32, w, h, w * 4);
849 cairo = cairo_create (surface);
850 cairo_set_source_rgba (cairo, self->r, self->g, self->b, self->a);
851
852 pango_cairo_show_layout (cairo, self->pl);
853
854 cairo_destroy (cairo);
855 cairo_surface_destroy (surface);
856
857 // what a mess, and its premultiplied, too :(
858 {
859 uint32_t *p = (uint32_t *)SvPVX (retval);
860 uint32_t *e = p + w * h;
861
862 while (p < e)
863 {
864 uint32_t rgba = *p;
865 rgba = (rgba >> 24) | (rgba << 8);
866 rgba = SDL_SwapBE32 (rgba);
867 *p++ = rgba;
868 }
869 }
870
871 EXTEND (SP, 5);
872 PUSHs (sv_2mortal (newSViv (w)));
873 PUSHs (sv_2mortal (newSViv (h)));
874 PUSHs (sv_2mortal (retval));
875 PUSHs (sv_2mortal (newSViv (GL_RGBA)));
876 PUSHs (sv_2mortal (newSViv (GL_RGBA)));
877 }
878 else
879 {
880 FT_Bitmap bitmap;
881
784 retval = newSV (w * h); 882 retval = newSV (w * h);
785 SvPOK_only (retval); 883 SvPOK_only (retval);
786 SvCUR_set (retval, w * h); 884 SvCUR_set (retval, w * h);
787 885
788 bitmap.rows = h; 886 bitmap.rows = h;
789 bitmap.width = w; 887 bitmap.width = w;
790 bitmap.pitch = w; 888 bitmap.pitch = w;
791 bitmap.buffer = (unsigned char*)SvPVX (retval); 889 bitmap.buffer = (unsigned char*)SvPVX (retval);
792 bitmap.num_grays = 256; 890 bitmap.num_grays = 256;
793 bitmap.pixel_mode = FT_PIXEL_MODE_GRAY; 891 bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
794 892
795 memset (bitmap.buffer, 0, w * h); 893 memset (bitmap.buffer, 0, w * h);
796 894
797 pango_ft2_render_layout (&bitmap, self->pl, 0 * PANGO_SCALE, 0 * PANGO_SCALE); 895 pango_ft2_render_layout (&bitmap, self->pl, 0 * PANGO_SCALE, 0 * PANGO_SCALE);
798 896
799 EXTEND (SP, 3); 897 EXTEND (SP, 5);
800 PUSHs (sv_2mortal (newSViv (w))); 898 PUSHs (sv_2mortal (newSViv (w)));
801 PUSHs (sv_2mortal (newSViv (h))); 899 PUSHs (sv_2mortal (newSViv (h)));
802 PUSHs (sv_2mortal (retval)); 900 PUSHs (sv_2mortal (retval));
901 PUSHs (sv_2mortal (newSViv (GL_ALPHA)));
902 PUSHs (sv_2mortal (newSViv (GL_ALPHA)));
903 }
803} 904}
804 905
805MODULE = CFClient PACKAGE = CFClient::Texture 906MODULE = CFClient PACKAGE = CFClient::Texture
806 907
807void 908void
808draw_quad (SV *self, float x, float y, float w = 0, float h = 0) 909draw_quad (SV *self, float x, float y, float w = 0, float h = 0)
809 PROTOTYPE: $$$;$$ 910 PROTOTYPE: $$$;$$
911 ALIAS:
912 draw_quad_alpha = 1
913 draw_quad_alpha_premultiplied = 2
810 CODE: 914 CODE:
811{ 915{
812 HV *hv = (HV *)SvRV (self); 916 HV *hv = (HV *)SvRV (self);
813 float s = SvNV (*hv_fetch (hv, "s", 1, 1)); 917 float s = SvNV (*hv_fetch (hv, "s", 1, 1));
814 float t = SvNV (*hv_fetch (hv, "t", 1, 1)); 918 float t = SvNV (*hv_fetch (hv, "t", 1, 1));
819 { 923 {
820 w = SvNV (*hv_fetch (hv, "w", 1, 1)); 924 w = SvNV (*hv_fetch (hv, "w", 1, 1));
821 h = SvNV (*hv_fetch (hv, "h", 1, 1)); 925 h = SvNV (*hv_fetch (hv, "h", 1, 1));
822 } 926 }
823 927
928 if (ix)
929 {
930 glEnable (GL_BLEND);
931 glBlendFunc (ix == 1 ? GL_SRC_ALPHA : GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
932 }
933
824 glBindTexture (GL_TEXTURE_2D, name); 934 glBindTexture (GL_TEXTURE_2D, name);
935
825 if (wrap_mode) { 936 if (wrap_mode)
937 {
826 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 938 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
827 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 939 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
828 } 940 }
941
829 glBegin (GL_QUADS); 942 glBegin (GL_QUADS);
830 glTexCoord2f (0, 0); glVertex2f (x , y ); 943 glTexCoord2f (0, 0); glVertex2f (x , y );
831 glTexCoord2f (0, t); glVertex2f (x , y + h); 944 glTexCoord2f (0, t); glVertex2f (x , y + h);
832 glTexCoord2f (s, t); glVertex2f (x + w, y + h); 945 glTexCoord2f (s, t); glVertex2f (x + w, y + h);
833 glTexCoord2f (s, 0); glVertex2f (x + w, y ); 946 glTexCoord2f (s, 0); glVertex2f (x + w, y );
834 glEnd (); 947 glEnd ();
948
949 if (ix)
950 glDisable (GL_BLEND);
835} 951}
836 952
837MODULE = CFClient PACKAGE = CFClient::Map 953MODULE = CFClient PACKAGE = CFClient::Map
838 954
839CFClient::Map 955CFClient::Map
1362 const_iv (GL_ONE_MINUS_DST_ALPHA), 1478 const_iv (GL_ONE_MINUS_DST_ALPHA),
1363 const_iv (GL_RGB), 1479 const_iv (GL_RGB),
1364 const_iv (GL_RGBA), 1480 const_iv (GL_RGBA),
1365 const_iv (GL_UNSIGNED_BYTE), 1481 const_iv (GL_UNSIGNED_BYTE),
1366 const_iv (GL_ALPHA), 1482 const_iv (GL_ALPHA),
1483 const_iv (GL_LUMINANCE),
1367 const_iv (GL_FLOAT), 1484 const_iv (GL_FLOAT),
1368 const_iv (GL_UNSIGNED_INT_8_8_8_8_REV), 1485 const_iv (GL_UNSIGNED_INT_8_8_8_8_REV),
1369 const_iv (GL_COMPILE), 1486 const_iv (GL_COMPILE),
1370 const_iv (GL_TEXTURE_1D), 1487 const_iv (GL_TEXTURE_1D),
1371 const_iv (GL_TEXTURE_2D), 1488 const_iv (GL_TEXTURE_2D),
1460void glEnd () 1577void glEnd ()
1461 1578
1462void glColor (float r, float g, float b, float a = 1.0) 1579void glColor (float r, float g, float b, float a = 1.0)
1463 PROTOTYPE: @ 1580 PROTOTYPE: @
1464 CODE: 1581 CODE:
1465 glColor4f (r, g, b, a); 1582 // 255.999 is close enough to correctness (256 and clamp)
1583 glColor4ub (r * 255.999, g * 255.999, b * 255.999, a * 255.999);
1466 1584
1467void glVertex (float x, float y, float z = 0.) 1585void glVertex (float x, float y, float z = 0.)
1468 CODE: 1586 CODE:
1469 glVertex3f (x, y, z); 1587 glVertex3f (x, y, z);
1470 1588

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines