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.57 by root, Fri Apr 21 07:09:10 2006 UTC vs.
Revision 1.93 by root, Tue May 23 18:54:37 2006 UTC

1#ifdef _WIN32 1#ifdef _WIN32
2# define _WIN32_WINNT 0x0500 // needed to get win2000 api calls
2# include <malloc.h> 3# include <malloc.h>
4# include <windows.h>
5# pragma warning(disable:4244)
3#endif 6#endif
4 7
5#include "EXTERN.h" 8#include "EXTERN.h"
6#include "perl.h" 9#include "perl.h"
7#include "XSUB.h" 10#include "XSUB.h"
8 11
12#include <math.h>
9#include <string.h> 13#include <string.h>
10#include <stdio.h> 14#include <stdio.h>
11 15
12#include <SDL.h> 16#include <SDL.h>
17#include <SDL_endian.h>
13#include <SDL_image.h> 18#include <SDL_image.h>
14#include <SDL_mixer.h> 19#include <SDL_mixer.h>
15#include <SDL_opengl.h> 20#include <SDL_opengl.h>
16 21
17#include <glib/gmacros.h> 22#include <glib/gmacros.h>
18 23
19#include <pango/pango.h> 24#include <pango/pango.h>
20#include <pango/pangofc-fontmap.h> 25#include <pango/pangofc-fontmap.h>
21#include <pango/pangoft2.h> 26#include <pango/pangoft2.h>
27#include <pango/pangocairo.h>
22 28
23#ifndef _WIN32 29#ifndef _WIN32
24# include <sys/types.h> 30# include <sys/types.h>
25# include <sys/socket.h> 31# include <sys/socket.h>
26# include <netinet/in.h> 32# include <netinet/in.h>
40#define FOW_DARKNESS 32 46#define FOW_DARKNESS 32
41 47
42#define MAP_EXTEND_X 32 48#define MAP_EXTEND_X 32
43#define MAP_EXTEND_Y 512 49#define MAP_EXTEND_Y 512
44 50
51#define MIN_FONT_HEIGHT 10
52
53#define GL_CALL(type,func,args) \
54 { \
55 static int init_; \
56 static type fptr_; \
57 \
58 if (!init_) \
59 { \
60 init_ = 1; \
61 fptr_ = (type)SDL_GL_GetProcAddress (# func); \
62 } \
63 \
64 if (fptr_) \
65 fptr_ args; \
66 }
67
45typedef Mix_Chunk *CFClient__MixChunk; 68typedef Mix_Chunk *CFClient__MixChunk;
46typedef Mix_Music *CFClient__MixMusic; 69typedef Mix_Music *CFClient__MixMusic;
47 70
48static PangoContext *context; 71typedef PangoFontDescription *CFClient__Font;
49static PangoFontMap *fontmap;
50 72
51typedef struct cf_layout { 73typedef struct cf_layout {
52 PangoLayout *pl; 74 PangoLayout *pl; // either derived from a cairo or ft2 context
75 int rgba; // wether we use rgba (cairo) or grayscale (ft2)
76 float r, g, b, a; // default color for rgba mode
53 int base_height; 77 int base_height;
78 CFClient__Font font;
54} *CFClient__Layout; 79} *CFClient__Layout;
80
81static CFClient__Font default_font;
82static PangoContext *ft2_context, *cairo_context;
83static PangoFontMap *ft2_fontmap, *cairo_fontmap;
55 84
56static void 85static void
57substitute_func (FcPattern *pattern, gpointer data) 86substitute_func (FcPattern *pattern, gpointer data)
58{ 87{
59 FcPatternAddBool (pattern, FC_HINTING , 1); 88 FcPatternAddBool (pattern, FC_HINTING , 1);
89#ifdef _WIN32
90 FcPatternAddBool (pattern, FC_AUTOHINT, 1);
91#else
60 FcPatternAddBool (pattern, FC_AUTOHINT, 0); 92 FcPatternAddBool (pattern, FC_AUTOHINT, 0);
93#endif
61} 94}
62 95
63static void 96static void
64layout_update (CFClient__Layout self) 97layout_update_font (CFClient__Layout self)
65{ 98{
66 /* use a random scale factor to account for unknown descenders, 0.8 works 99 /* use a random scale factor to account for unknown descenders, 0.8 works
67 * reasonably well with bitstream vera 100 * reasonably well with bitstream vera
68 */ 101 */
69 PangoFontDescription *font = pango_context_get_font_description (context); 102 PangoFontDescription *font = self->font ? self->font : default_font;
70 103
71 int height = self->base_height * (PANGO_SCALE * 8 / 10);
72
73 if (pango_font_description_get_size (font) != height)
74 {
75 pango_font_description_set_absolute_size (font, height); 104 pango_font_description_set_absolute_size (font,
76 pango_layout_context_changed (self->pl); 105 MAX (MIN_FONT_HEIGHT, self->base_height) * (PANGO_SCALE * 8 / 10));
77 } 106
107 pango_layout_set_font_description (self->pl, font);
78} 108}
79 109
80static void 110static void
81layout_get_pixel_size (CFClient__Layout self, int *w, int *h) 111layout_get_pixel_size (CFClient__Layout self, int *w, int *h)
82{ 112{
83 layout_update (self);
84
85 pango_layout_get_pixel_size (self->pl, w, h); 113 pango_layout_get_pixel_size (self->pl, w, h);
86 114
87 *w = (*w + 3) & ~3;
88 if (!*w) *w = 1; 115 if (!*w) *w = 1;
89 if (!*h) *h = 1; 116 if (!*h) *h = 1;
117
118 *w = (*w + 3) & ~3;
90} 119}
91 120
92typedef uint16_t mapface; 121typedef uint16_t mapface;
93 122
94typedef struct { 123typedef struct {
242 } 271 }
243 } 272 }
244} 273}
245 274
246static void 275static void
247music_finished () 276music_finished (void)
248{ 277{
249 SDL_UserEvent ev; 278 SDL_UserEvent ev;
250 279
251 ev.type = SDL_USEREVENT; 280 ev.type = SDL_USEREVENT;
252 ev.code = 0; 281 ev.code = 0;
253 ev.data1 = 0; 282 ev.data1 = 0;
283 ev.data2 = 0;
284
285 SDL_PushEvent ((SDL_Event *)&ev);
286}
287
288static void
289channel_finished (int channel)
290{
291 SDL_UserEvent ev;
292
293 ev.type = SDL_USEREVENT;
294 ev.code = 1;
295 ev.data1 = (void *)(long)channel;
254 ev.data2 = 0; 296 ev.data2 = 0;
255 297
256 SDL_PushEvent ((SDL_Event *)&ev); 298 SDL_PushEvent ((SDL_Event *)&ev);
257} 299}
258 300
369# undef const_iv 411# undef const_iv
370 }; 412 };
371 413
372 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 414 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
373 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 415 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
416}
374 417
418void
419pango_init ()
420 CODE:
421{
422 // delayed, so it can pick up new fonts added by AddFontResourceEx
375 fontmap = pango_ft2_font_map_new (); 423 ft2_fontmap = pango_ft2_font_map_new ();
376 pango_ft2_font_map_set_default_substitute ((PangoFT2FontMap *)fontmap, substitute_func, 0, 0); 424 pango_ft2_font_map_set_default_substitute ((PangoFT2FontMap *)ft2_fontmap, substitute_func, 0, 0);
377 context = pango_ft2_font_map_create_context ((PangoFT2FontMap *)fontmap); 425 ft2_context = pango_ft2_font_map_create_context ((PangoFT2FontMap *)ft2_fontmap);
426
427 cairo_fontmap = pango_cairo_font_map_get_default ();
428 cairo_context = pango_cairo_font_map_create_context ((PangoCairoFontMap *)cairo_fontmap);
378} 429}
379 430
380int 431int
381SDL_Init (U32 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO) 432SDL_Init (U32 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO)
382 433
392 SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 5); 443 SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 5);
393 SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 5); 444 SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 5);
394 SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5); 445 SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5);
395 SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, 1); 446 SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, 1);
396 447
448 SDL_GL_SetAttribute (SDL_GL_BUFFER_SIZE, 15);
449 SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 16);
450
397 SDL_GL_SetAttribute (SDL_GL_ACCUM_RED_SIZE, 0); 451 SDL_GL_SetAttribute (SDL_GL_ACCUM_RED_SIZE, 0);
398 SDL_GL_SetAttribute (SDL_GL_ACCUM_GREEN_SIZE, 0); 452 SDL_GL_SetAttribute (SDL_GL_ACCUM_GREEN_SIZE, 0);
399 SDL_GL_SetAttribute (SDL_GL_ACCUM_BLUE_SIZE, 0); 453 SDL_GL_SetAttribute (SDL_GL_ACCUM_BLUE_SIZE, 0);
400 SDL_GL_SetAttribute (SDL_GL_ACCUM_ALPHA_SIZE, 0); 454 SDL_GL_SetAttribute (SDL_GL_ACCUM_ALPHA_SIZE, 0);
401 455
402 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); 456 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
403 SDL_GL_SetAttribute (SDL_GL_BUFFER_SIZE, 15);
404 SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 0);
405 457
406 SDL_EnableUNICODE (1); 458 SDL_EnableUNICODE (1);
407 SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); 459 SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
408 460
409 m = SDL_ListModes (0, SDL_FULLSCREEN | SDL_OPENGL); 461 m = SDL_ListModes (0, SDL_FULLSCREEN | SDL_OPENGL);
418 470
419 ++m; 471 ++m;
420 } 472 }
421} 473}
422 474
475char *
476SDL_GetError ()
477
423int 478int
424SDL_SetVideoMode (int w, int h, int fullscreen) 479SDL_SetVideoMode (int w, int h, int fullscreen)
425 CODE: 480 CODE:
426 RETVAL = !!SDL_SetVideoMode ( 481 RETVAL = !!SDL_SetVideoMode (
427 w, h, 0, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0) 482 w, h, 0, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0)
436void 491void
437SDL_PollEvent () 492SDL_PollEvent ()
438 PPCODE: 493 PPCODE:
439{ 494{
440 SDL_Event ev; 495 SDL_Event ev;
496 int i;
497 static int modifier;
498 static int modkey[] = {
499 SDLK_RSHIFT, KMOD_RSHIFT,
500 SDLK_LSHIFT, KMOD_LSHIFT,
501 SDLK_RCTRL, KMOD_RCTRL,
502 SDLK_LCTRL, KMOD_LCTRL,
503 SDLK_RALT, KMOD_RALT,
504 SDLK_LALT, KMOD_LALT,
505 SDLK_RMETA, KMOD_RMETA,
506 SDLK_LMETA, KMOD_LMETA,
507 };
441 508
442 while (SDL_PollEvent (&ev)) 509 while (SDL_PollEvent (&ev))
443 { 510 {
444 HV *hv = newHV (); 511 HV *hv = newHV ();
445 hv_store (hv, "type", 4, newSViv (ev.type), 0); 512 hv_store (hv, "type", 4, newSViv (ev.type), 0);
513
446 switch (ev.type) 514 switch (ev.type)
447 { 515 {
448 case SDL_KEYDOWN: 516 case SDL_KEYDOWN:
449 case SDL_KEYUP: 517 case SDL_KEYUP:
518
519 for (i = 0; i < sizeof (modkey) / (sizeof (int) * 2); i++)
520 if (modkey [i * 2] == ev.key.keysym.sym)
521 {
522 if (ev.type == SDL_KEYDOWN)
523 modifier |= modkey [i * 2 + 1];
524 else
525 modifier &= ~modkey [i * 2 + 1];
526 break;
527 }
528
450 hv_store (hv, "state", 5, newSViv (ev.key.state), 0); 529 hv_store (hv, "state", 5, newSViv (ev.key.state), 0);
451 hv_store (hv, "sym", 3, newSViv (ev.key.keysym.sym), 0); 530 hv_store (hv, "sym", 3, newSViv (ev.key.keysym.sym), 0);
452 hv_store (hv, "mod", 3, newSViv (ev.key.keysym.mod), 0); 531 hv_store (hv, "mod", 3, newSViv (ev.key.keysym.mod), 0);
453 hv_store (hv, "unicode", 7, newSViv (ev.key.keysym.unicode), 0); 532 hv_store (hv, "unicode", 7, newSViv (ev.key.keysym.unicode), 0);
454 break; 533 break;
457 hv_store (hv, "gain", 4, newSViv (ev.active.gain), 0); 536 hv_store (hv, "gain", 4, newSViv (ev.active.gain), 0);
458 hv_store (hv, "state", 5, newSViv (ev.active.state), 0); 537 hv_store (hv, "state", 5, newSViv (ev.active.state), 0);
459 break; 538 break;
460 539
461 case SDL_MOUSEMOTION: 540 case SDL_MOUSEMOTION:
541 hv_store (hv, "mod", 3, newSViv (modifier), 0);
542
462 hv_store (hv, "state", 5, newSViv (ev.motion.state), 0); 543 hv_store (hv, "state", 5, newSViv (ev.motion.state), 0);
463 hv_store (hv, "x", 1, newSViv (ev.motion.x), 0); 544 hv_store (hv, "x", 1, newSViv (ev.motion.x), 0);
464 hv_store (hv, "y", 1, newSViv (ev.motion.y), 0); 545 hv_store (hv, "y", 1, newSViv (ev.motion.y), 0);
465 hv_store (hv, "xrel", 4, newSViv (ev.motion.xrel), 0); 546 hv_store (hv, "xrel", 4, newSViv (ev.motion.xrel), 0);
466 hv_store (hv, "yrel", 4, newSViv (ev.motion.yrel), 0); 547 hv_store (hv, "yrel", 4, newSViv (ev.motion.yrel), 0);
467 break; 548 break;
468 549
469 case SDL_MOUSEBUTTONDOWN: 550 case SDL_MOUSEBUTTONDOWN:
470 case SDL_MOUSEBUTTONUP: 551 case SDL_MOUSEBUTTONUP:
552 hv_store (hv, "mod", 3, newSViv (modifier), 0);
553
471 hv_store (hv, "button", 6, newSViv (ev.button.button), 0); 554 hv_store (hv, "button", 6, newSViv (ev.button.button), 0);
472 hv_store (hv, "state", 5, newSViv (ev.button.state), 0); 555 hv_store (hv, "state", 5, newSViv (ev.button.state), 0);
473 hv_store (hv, "x", 1, newSViv (ev.button.x), 0); 556 hv_store (hv, "x", 1, newSViv (ev.button.x), 0);
474 hv_store (hv, "y", 1, newSViv (ev.button.y), 0); 557 hv_store (hv, "y", 1, newSViv (ev.button.y), 0);
558 break;
559
560 case SDL_USEREVENT:
561 hv_store (hv, "code", 4, newSViv (ev.user.code), 0);
562 hv_store (hv, "data1", 5, newSViv ((IV)ev.user.data1), 0);
563 hv_store (hv, "data2", 5, newSViv ((IV)ev.user.data2), 0);
564 break;
475 } 565 }
476 566
477 XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv))); 567 XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv)));
478 } 568 }
479} 569}
480 570
481int 571int
482Mix_OpenAudio (int frequency = 22050, int format = MIX_DEFAULT_FORMAT, int channels = 1, int chunksize = 512) 572Mix_OpenAudio (int frequency = 48000, int format = MIX_DEFAULT_FORMAT, int channels = 1, int chunksize = 2048)
483 POSTCALL: 573 POSTCALL:
484 Mix_HookMusicFinished (music_finished); 574 Mix_HookMusicFinished (music_finished);
575 Mix_ChannelFinished (channel_finished);
485 576
486void 577void
487Mix_CloseAudio () 578Mix_CloseAudio ()
488 579
489int 580int
495#ifndef _WIN32 586#ifndef _WIN32
496 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof (val)); 587 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof (val));
497#endif 588#endif
498 589
499char * 590char *
591gl_vendor ()
592 CODE:
593 RETVAL = (char *)glGetString (GL_VENDOR);
594 OUTPUT:
595 RETVAL
596
597char *
500gl_version () 598gl_version ()
501 CODE: 599 CODE:
502 RETVAL = (char *)glGetString (GL_VERSION); 600 RETVAL = (char *)glGetString (GL_VERSION);
503 OUTPUT: 601 OUTPUT:
504 RETVAL 602 RETVAL
512 610
513void 611void
514add_font (char *file) 612add_font (char *file)
515 CODE: 613 CODE:
516 FcConfigAppFontAddFile (0, (const FcChar8 *)file); /* no idea wether this is required */ 614 FcConfigAppFontAddFile (0, (const FcChar8 *)file); /* no idea wether this is required */
517 615#ifdef _WIN32
518void 616 // cairo... sigh... requires win2000
519set_font (char *file) 617 AddFontResourceEx (file, FR_PRIVATE, 0);
520 CODE: 618#endif
521{
522 int count;
523 FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)file, 0, 0, &count);
524 PangoFontDescription *font = pango_fc_font_description_from_pattern (pattern, 0);
525 FcPatternDestroy (pattern);
526 pango_context_set_font_description (context, font);
527}
528 619
529void 620void
530load_image_inline (SV *image_) 621load_image_inline (SV *image_)
531 ALIAS: 622 ALIAS:
532 load_image_file = 1 623 load_image_file = 1
614 PUSHs (sv_2mortal (newSViv (b / y))); 705 PUSHs (sv_2mortal (newSViv (b / y)));
615 PUSHs (sv_2mortal (newSViv (a / y))); 706 PUSHs (sv_2mortal (newSViv (a / y)));
616} 707}
617 708
618void 709void
710error (char *message)
711 CODE:
712 fprintf (stderr, "ERROR: %s\n", message);
713#ifdef _WIN32
714 MessageBox (0, message, "Crossfire+ Error", MB_OK | MB_ICONERROR);
715#endif
716
717void
619fatal (char *message) 718fatal (char *message)
620 CODE: 719 CODE:
720 fprintf (stderr, "FATAL: %s\n", message);
621#ifdef _WIN32 721#ifdef _WIN32
622 MessageBox (0, message, "Crossfire+ Fatal Error", MB_OK | MB_ICONERROR | MB_SETFOREGROUND); 722 MessageBox (0, message, "Crossfire+ Fatal Error", MB_OK | MB_ICONERROR);
623#else
624 fprintf (stderr, "FATAL: %s\n", message);
625#endif 723#endif
626 exit (1); 724 exit (1);
627 725
726MODULE = CFClient PACKAGE = CFClient::Font
727
728CFClient::Font
729new_from_file (SV *class, char *path, int id = 0)
730 CODE:
731{
732 int count;
733 FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)path, id, 0, &count);
734 RETVAL = pango_fc_font_description_from_pattern (pattern, 0);
735 FcPatternDestroy (pattern);
736}
737 OUTPUT:
738 RETVAL
739
740void
741DESTROY (CFClient::Font self)
742 CODE:
743 pango_font_description_free (self);
744
745void
746make_default (CFClient::Font self)
747 CODE:
748 default_font = self;
749
628MODULE = CFClient PACKAGE = CFClient::Layout 750MODULE = CFClient PACKAGE = CFClient::Layout
629 751
630CFClient::Layout 752CFClient::Layout
631new (SV *class, int base_height = 10) 753new (SV *class, int rgba = 0)
632 CODE: 754 CODE:
755#if _WIN32
756 rgba = 0;//D
757#endif
633 New (0, RETVAL, 1, struct cf_layout); 758 New (0, RETVAL, 1, struct cf_layout);
634 RETVAL->base_height = base_height; 759
635 RETVAL->pl = pango_layout_new (context); 760 RETVAL->pl = pango_layout_new (rgba ? cairo_context : ft2_context);
761 RETVAL->rgba = rgba;
762 RETVAL->r = 1.;
763 RETVAL->g = 1.;
764 RETVAL->b = 1.;
765 RETVAL->a = 1.;
766 RETVAL->base_height = MIN_FONT_HEIGHT;
767 RETVAL->font = 0;
768
636 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR); 769 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
770 layout_update_font (RETVAL);
637 OUTPUT: 771 OUTPUT:
638 RETVAL 772 RETVAL
639 773
640void 774void
641DESTROY (CFClient::Layout self) 775DESTROY (CFClient::Layout self)
642 CODE: 776 CODE:
643 g_object_unref (self->pl); 777 g_object_unref (self->pl);
644 Safefree (self); 778 Safefree (self);
645 779
780int
781is_rgba (CFClient::Layout self)
782 CODE:
783 RETVAL = self->rgba;
784 OUTPUT:
785 RETVAL
786
646void 787void
647set_text (CFClient::Layout self, SV *text_) 788set_text (CFClient::Layout self, SV *text_)
648 CODE: 789 CODE:
649{ 790{
650 STRLEN textlen; 791 STRLEN textlen;
670 SvUTF8_on (RETVAL); 811 SvUTF8_on (RETVAL);
671 OUTPUT: 812 OUTPUT:
672 RETVAL 813 RETVAL
673 814
674void 815void
816set_foreground (CFClient::Layout self, float r, float g, float b, float a = 1.)
817 CODE:
818 self->r = r;
819 self->g = g;
820 self->b = b;
821 self->a = a;
822
823void
824set_font (CFClient::Layout self, CFClient::Font font = 0)
825 CODE:
826 if (self->font != font)
827 {
828 self->font = font;
829 layout_update_font (self);
830 }
831
832void
675set_height (CFClient::Layout self, int base_height) 833set_height (CFClient::Layout self, int base_height)
676 CODE: 834 CODE:
835 if (self->base_height != base_height)
836 {
677 self->base_height = base_height; 837 self->base_height = base_height;
838 layout_update_font (self);
839 }
678 840
679void 841void
680set_width (CFClient::Layout self, int max_width = -1) 842set_width (CFClient::Layout self, int max_width = -1)
681 CODE: 843 CODE:
682 pango_layout_set_width (self->pl, max_width < 0 ? max_width : max_width * PANGO_SCALE); 844 pango_layout_set_width (self->pl, max_width < 0 ? max_width : max_width * PANGO_SCALE);
845
846void
847set_indent (CFClient::Layout self, int indent)
848 CODE:
849 pango_layout_set_indent (self->pl, indent * PANGO_SCALE);
850
851void
852set_spacing (CFClient::Layout self, int spacing)
853 CODE:
854 pango_layout_set_spacing (self->pl, spacing * PANGO_SCALE);
855
856void
857set_ellipsise (CFClient::Layout self, int ellipsise)
858 CODE:
859 pango_layout_set_ellipsize (self->pl,
860 ellipsise == 1 ? PANGO_ELLIPSIZE_START
861 : ellipsise == 2 ? PANGO_ELLIPSIZE_MIDDLE
862 : ellipsise == 3 ? PANGO_ELLIPSIZE_END
863 : PANGO_ELLIPSIZE_NONE
864 );
865
866void
867set_single_paragraph_mode (CFClient::Layout self, int spm)
868 CODE:
869 pango_layout_set_single_paragraph_mode (self->pl, !!spm);
683 870
684void 871void
685size (CFClient::Layout self) 872size (CFClient::Layout self)
686 PPCODE: 873 PPCODE:
687{ 874{
688 int w, h; 875 int w, h;
689 876
690 layout_update (self);
691 layout_get_pixel_size (self, &w, &h); 877 layout_get_pixel_size (self, &w, &h);
692 878
693 EXTEND (SP, 2); 879 EXTEND (SP, 2);
694 PUSHs (sv_2mortal (newSViv (w))); 880 PUSHs (sv_2mortal (newSViv (w)));
695 PUSHs (sv_2mortal (newSViv (h))); 881 PUSHs (sv_2mortal (newSViv (h)));
698int 884int
699xy_to_index (CFClient::Layout self, int x, int y) 885xy_to_index (CFClient::Layout self, int x, int y)
700 CODE: 886 CODE:
701{ 887{
702 int index, trailing; 888 int index, trailing;
703
704 layout_update (self);
705 pango_layout_xy_to_index (self->pl, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing); 889 pango_layout_xy_to_index (self->pl, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing);
706
707 RETVAL = index; 890 RETVAL = index;
708} 891}
709 OUTPUT: 892 OUTPUT:
710 RETVAL 893 RETVAL
711 894
712void 895void
713cursor_pos (CFClient::Layout self, int index) 896cursor_pos (CFClient::Layout self, int index)
714 PPCODE: 897 PPCODE:
715{ 898{
716 PangoRectangle strong_pos; 899 PangoRectangle strong_pos;
717 layout_update (self);
718 pango_layout_get_cursor_pos (self->pl, index, &strong_pos, 0); 900 pango_layout_get_cursor_pos (self->pl, index, &strong_pos, 0);
719 901
720 EXTEND (SP, 3); 902 EXTEND (SP, 3);
721 PUSHs (sv_2mortal (newSViv (strong_pos.x / PANGO_SCALE))); 903 PUSHs (sv_2mortal (newSViv (strong_pos.x / PANGO_SCALE)));
722 PUSHs (sv_2mortal (newSViv (strong_pos.y / PANGO_SCALE))); 904 PUSHs (sv_2mortal (newSViv (strong_pos.y / PANGO_SCALE)));
727render (CFClient::Layout self) 909render (CFClient::Layout self)
728 PPCODE: 910 PPCODE:
729{ 911{
730 SV *retval; 912 SV *retval;
731 int w, h; 913 int w, h;
732 FT_Bitmap bitmap;
733 914
734 layout_update (self);
735 layout_get_pixel_size (self, &w, &h); 915 layout_get_pixel_size (self, &w, &h);
736 916
917 if (self->rgba)
918 {
919 cairo_surface_t *surface;
920 cairo_t *cairo;
921
922 retval = newSV (w * h * 4);
923 SvPOK_only (retval);
924 SvCUR_set (retval, w * h * 4);
925
926 memset (SvPVX (retval), 0, w * h * 4);
927
928 surface = cairo_image_surface_create_for_data (
929 (void*)SvPVX (retval), CAIRO_FORMAT_ARGB32, w, h, w * 4);
930 cairo = cairo_create (surface);
931 cairo_set_source_rgba (cairo, self->r, self->g, self->b, self->a);
932
933 pango_cairo_show_layout (cairo, self->pl);
934
935 cairo_destroy (cairo);
936 cairo_surface_destroy (surface);
937
938 // what a mess, and its premultiplied, too :(
939 {
940 uint32_t *p = (uint32_t *)SvPVX (retval);
941 uint32_t *e = p + w * h;
942
943 while (p < e)
944 {
945 uint32_t rgba = *p;
946 rgba = (rgba >> 24) | (rgba << 8);
947#if 0
948#ifdef _WIN32
949 {//D
950 uint8_t r = rgba >> 24;
951 uint8_t g = rgba >> 16;
952 uint8_t b = rgba >> 8;
953 uint8_t a = rgba >> 0;
954
955 rgba = (rgba & 0xffffff00) | a;
956 }
957#endif
958#endif
959 rgba = SDL_SwapBE32 (rgba);
960 *p++ = rgba;
961 }
962 }
963
964 EXTEND (SP, 5);
965 PUSHs (sv_2mortal (newSViv (w)));
966 PUSHs (sv_2mortal (newSViv (h)));
967 PUSHs (sv_2mortal (retval));
968 PUSHs (sv_2mortal (newSViv (GL_RGBA)));
969 PUSHs (sv_2mortal (newSViv (GL_RGBA)));
970 }
971 else
972 {
973 FT_Bitmap bitmap;
974
737 retval = newSV (w * h); 975 retval = newSV (w * h);
738 SvPOK_only (retval); 976 SvPOK_only (retval);
739 SvCUR_set (retval, w * h); 977 SvCUR_set (retval, w * h);
740 978
741 bitmap.rows = h; 979 bitmap.rows = h;
742 bitmap.width = w; 980 bitmap.width = w;
743 bitmap.pitch = w; 981 bitmap.pitch = w;
744 bitmap.buffer = (unsigned char*)SvPVX (retval); 982 bitmap.buffer = (unsigned char*)SvPVX (retval);
745 bitmap.num_grays = 256; 983 bitmap.num_grays = 256;
746 bitmap.pixel_mode = FT_PIXEL_MODE_GRAY; 984 bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
747 985
748 memset (bitmap.buffer, 0, w * h); 986 memset (bitmap.buffer, 0, w * h);
749 987
750 pango_ft2_render_layout (&bitmap, self->pl, 0 * PANGO_SCALE, 0 * PANGO_SCALE); 988 pango_ft2_render_layout (&bitmap, self->pl, 0 * PANGO_SCALE, 0 * PANGO_SCALE);
751 989
752 EXTEND (SP, 3); 990 EXTEND (SP, 5);
753 PUSHs (sv_2mortal (newSViv (w))); 991 PUSHs (sv_2mortal (newSViv (w)));
754 PUSHs (sv_2mortal (newSViv (h))); 992 PUSHs (sv_2mortal (newSViv (h)));
755 PUSHs (sv_2mortal (retval)); 993 PUSHs (sv_2mortal (retval));
994 PUSHs (sv_2mortal (newSViv (GL_ALPHA)));
995 PUSHs (sv_2mortal (newSViv (GL_ALPHA)));
996 }
756} 997}
757 998
758MODULE = CFClient PACKAGE = CFClient::Texture 999MODULE = CFClient PACKAGE = CFClient::Texture
759 1000
760void 1001void
761draw_quad (SV *self, float x, float y, float w = 0, float h = 0) 1002draw_quad (SV *self, float x, float y, float w = 0, float h = 0)
762 PROTOTYPE: $$$;$$ 1003 PROTOTYPE: $$$;$$
1004 ALIAS:
1005 draw_quad_alpha = 1
1006 draw_quad_alpha_premultiplied = 2
763 CODE: 1007 CODE:
764{ 1008{
765 HV *hv = (HV *)SvRV (self); 1009 HV *hv = (HV *)SvRV (self);
766 float s = SvNV (*hv_fetch (hv, "s", 1, 1)); 1010 float s = SvNV (*hv_fetch (hv, "s", 1, 1));
767 float t = SvNV (*hv_fetch (hv, "t", 1, 1)); 1011 float t = SvNV (*hv_fetch (hv, "t", 1, 1));
772 { 1016 {
773 w = SvNV (*hv_fetch (hv, "w", 1, 1)); 1017 w = SvNV (*hv_fetch (hv, "w", 1, 1));
774 h = SvNV (*hv_fetch (hv, "h", 1, 1)); 1018 h = SvNV (*hv_fetch (hv, "h", 1, 1));
775 } 1019 }
776 1020
1021 if (ix)
1022 {
1023 glEnable (GL_BLEND);
1024 glBlendFunc (ix == 1 ? GL_SRC_ALPHA : GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1025 glEnable (GL_ALPHA_TEST);
1026 glAlphaFunc (GL_GREATER, 0.01f);
1027 }
1028
777 glBindTexture (GL_TEXTURE_2D, name); 1029 glBindTexture (GL_TEXTURE_2D, name);
1030
778 if (wrap_mode) { 1031 if (wrap_mode)
1032 {
779 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 1033 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
780 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 1034 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
781 } 1035 }
1036
782 glBegin (GL_QUADS); 1037 glBegin (GL_QUADS);
783 glTexCoord2f (0, 0); glVertex2f (x , y ); 1038 glTexCoord2f (0, 0); glVertex2f (x , y );
784 glTexCoord2f (0, t); glVertex2f (x , y + h); 1039 glTexCoord2f (0, t); glVertex2f (x , y + h);
785 glTexCoord2f (s, t); glVertex2f (x + w, y + h); 1040 glTexCoord2f (s, t); glVertex2f (x + w, y + h);
786 glTexCoord2f (s, 0); glVertex2f (x + w, y ); 1041 glTexCoord2f (s, 0); glVertex2f (x + w, y );
787 glEnd (); 1042 glEnd ();
1043
1044 if (ix)
1045 {
1046 glDisable (GL_ALPHA_TEST);
1047 glDisable (GL_BLEND);
1048 }
788} 1049}
789 1050
790MODULE = CFClient PACKAGE = CFClient::Map 1051MODULE = CFClient PACKAGE = CFClient::Map
791 1052
792CFClient::Map 1053CFClient::Map
1301 } *civ, const_iv[] = { 1562 } *civ, const_iv[] = {
1302# define const_iv(name) { # name, (IV)name } 1563# define const_iv(name) { # name, (IV)name }
1303 const_iv (GL_COLOR_MATERIAL), 1564 const_iv (GL_COLOR_MATERIAL),
1304 const_iv (GL_SMOOTH), 1565 const_iv (GL_SMOOTH),
1305 const_iv (GL_FLAT), 1566 const_iv (GL_FLAT),
1567 const_iv (GL_DITHER),
1306 const_iv (GL_BLEND), 1568 const_iv (GL_BLEND),
1569 const_iv (GL_CULL_FACE),
1570 const_iv (GL_SCISSOR_TEST),
1571 const_iv (GL_DEPTH_TEST),
1572 const_iv (GL_ALPHA_TEST),
1573 const_iv (GL_NORMALIZE),
1574 const_iv (GL_RESCALE_NORMAL),
1307 const_iv (GL_AND), 1575 const_iv (GL_AND),
1576 const_iv (GL_ONE),
1577 const_iv (GL_ZERO),
1308 const_iv (GL_SRC_ALPHA), 1578 const_iv (GL_SRC_ALPHA),
1579 const_iv (GL_SRC_ALPHA_SATURATE),
1309 const_iv (GL_ONE_MINUS_SRC_ALPHA), 1580 const_iv (GL_ONE_MINUS_SRC_ALPHA),
1581 const_iv (GL_ONE_MINUS_DST_ALPHA),
1310 const_iv (GL_RGB), 1582 const_iv (GL_RGB),
1311 const_iv (GL_RGBA), 1583 const_iv (GL_RGBA),
1312 const_iv (GL_UNSIGNED_BYTE), 1584 const_iv (GL_UNSIGNED_BYTE),
1313 const_iv (GL_ALPHA4), 1585 const_iv (GL_UNSIGNED_SHORT),
1586 const_iv (GL_UNSIGNED_INT),
1314 const_iv (GL_ALPHA), 1587 const_iv (GL_ALPHA),
1588 const_iv (GL_INTENSITY),
1589 const_iv (GL_LUMINANCE),
1590 const_iv (GL_LUMINANCE_ALPHA),
1315 const_iv (GL_FLOAT), 1591 const_iv (GL_FLOAT),
1316 const_iv (GL_UNSIGNED_INT_8_8_8_8_REV), 1592 const_iv (GL_UNSIGNED_INT_8_8_8_8_REV),
1317 const_iv (GL_COMPILE), 1593 const_iv (GL_COMPILE),
1318 const_iv (GL_TEXTURE_1D), 1594 const_iv (GL_TEXTURE_1D),
1319 const_iv (GL_TEXTURE_2D), 1595 const_iv (GL_TEXTURE_2D),
1330 const_iv (GL_NEAREST_MIPMAP_NEAREST), 1606 const_iv (GL_NEAREST_MIPMAP_NEAREST),
1331 const_iv (GL_LINEAR_MIPMAP_NEAREST), 1607 const_iv (GL_LINEAR_MIPMAP_NEAREST),
1332 const_iv (GL_NEAREST_MIPMAP_LINEAR), 1608 const_iv (GL_NEAREST_MIPMAP_LINEAR),
1333 const_iv (GL_LINEAR_MIPMAP_LINEAR), 1609 const_iv (GL_LINEAR_MIPMAP_LINEAR),
1334 const_iv (GL_GENERATE_MIPMAP), 1610 const_iv (GL_GENERATE_MIPMAP),
1335 const_iv (GL_LINEAR),
1336 const_iv (GL_MODULATE), 1611 const_iv (GL_MODULATE),
1612 const_iv (GL_DECAL),
1337 const_iv (GL_REPLACE), 1613 const_iv (GL_REPLACE),
1614 const_iv (GL_DEPTH_BUFFER_BIT),
1338 const_iv (GL_COLOR_BUFFER_BIT), 1615 const_iv (GL_COLOR_BUFFER_BIT),
1339 const_iv (GL_PROJECTION), 1616 const_iv (GL_PROJECTION),
1340 const_iv (GL_MODELVIEW), 1617 const_iv (GL_MODELVIEW),
1341 const_iv (GL_COLOR_LOGIC_OP), 1618 const_iv (GL_COLOR_LOGIC_OP),
1619 const_iv (GL_SEPARABLE_2D),
1342 const_iv (GL_CONVOLUTION_2D), 1620 const_iv (GL_CONVOLUTION_2D),
1343 const_iv (GL_CONVOLUTION_BORDER_MODE), 1621 const_iv (GL_CONVOLUTION_BORDER_MODE),
1344 const_iv (GL_CONSTANT_BORDER), 1622 const_iv (GL_CONSTANT_BORDER),
1345 const_iv (GL_LINES), 1623 const_iv (GL_LINES),
1624 const_iv (GL_LINE_LOOP),
1346 const_iv (GL_QUADS), 1625 const_iv (GL_QUADS),
1347 const_iv (GL_LINE_LOOP), 1626 const_iv (GL_QUAD_STRIP),
1627 const_iv (GL_TRIANGLES),
1628 const_iv (GL_TRIANGLE_STRIP),
1629 const_iv (GL_TRIANGLE_FAN),
1348 const_iv (GL_PERSPECTIVE_CORRECTION_HINT), 1630 const_iv (GL_PERSPECTIVE_CORRECTION_HINT),
1349 const_iv (GL_FASTEST), 1631 const_iv (GL_FASTEST),
1632 const_iv (GL_V2F),
1633 const_iv (GL_V3F),
1634 const_iv (GL_T2F_V3F),
1635 const_iv (GL_T2F_N3F_V3F),
1350# undef const_iv 1636# undef const_iv
1351 }; 1637 };
1352 1638
1353 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 1639 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
1354 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 1640 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
1369 1655
1370void glHint (int target, int mode) 1656void glHint (int target, int mode)
1371 1657
1372void glBlendFunc (int sfactor, int dfactor) 1658void glBlendFunc (int sfactor, int dfactor)
1373 1659
1660void glDepthMask (int flag)
1661
1374void glLogicOp (int opcode) 1662void glLogicOp (int opcode)
1375 1663
1664void glColorMask (int red, int green, int blue, int alpha)
1665
1376void glMatrixMode (int mode) 1666void glMatrixMode (int mode)
1377 1667
1378void glPushMatrix () 1668void glPushMatrix ()
1379 1669
1380void glPopMatrix () 1670void glPopMatrix ()
1381 1671
1382void glLoadIdentity () 1672void glLoadIdentity ()
1383 1673
1674# near_ and far_ are due to microsofts buggy "c" compiler
1675void glFrustum (double left, double right, double bottom, double top, double near_, double far_)
1676
1677# near_ and far_ are due to microsofts buggy "c" compiler
1384void glOrtho (double left, double right, double bottom, double top, double near, double far) 1678void glOrtho (double left, double right, double bottom, double top, double near_, double far_)
1385 1679
1386void glViewport (int x, int y, int width, int height) 1680void glViewport (int x, int y, int width, int height)
1681
1682void glScissor (int x, int y, int width, int height)
1387 1683
1388void glTranslate (float x, float y, float z = 0.) 1684void glTranslate (float x, float y, float z = 0.)
1389 CODE: 1685 CODE:
1390 glTranslatef (x, y, z); 1686 glTranslatef (x, y, z);
1391 1687
1392void glScale (float x, float y, float z) 1688void glScale (float x, float y, float z = 1.)
1393 CODE: 1689 CODE:
1394 glScalef (x, y, z); 1690 glScalef (x, y, z);
1395 1691
1396void glRotate (float angle, float x, float y, float z) 1692void glRotate (float angle, float x, float y, float z)
1397 CODE: 1693 CODE:
1402void glEnd () 1698void glEnd ()
1403 1699
1404void glColor (float r, float g, float b, float a = 1.0) 1700void glColor (float r, float g, float b, float a = 1.0)
1405 PROTOTYPE: @ 1701 PROTOTYPE: @
1406 CODE: 1702 CODE:
1407 glColor4f (r, g, b, a); 1703 // microsoft visual "c" rounds instead of truncating...
1704 glColor4ub (MIN ((int)(r * 255.f), 255),
1705 MIN ((int)(g * 255.f), 255),
1706 MIN ((int)(b * 255.f), 255),
1707 MIN ((int)(a * 255.f), 255));
1708
1709void glInterleavedArrays (int format, int stride, char *data)
1710
1711void glDrawElements (int mode, int count, int type, char *indices)
1712
1713# 1.2 void glDrawRangeElements (int mode, int start, int end
1714
1715void glRasterPos (float x, float y, float z = 0.)
1716 CODE:
1717 glRasterPos3f (0, 0, z);
1718 glBitmap (0, 0, 0, 0, x, y, 0);
1408 1719
1409void glVertex (float x, float y, float z = 0.) 1720void glVertex (float x, float y, float z = 0.)
1410 CODE: 1721 CODE:
1411 glVertex3f (x, y, z); 1722 glVertex3f (x, y, z);
1412 1723
1424 1735
1425void glBindTexture (int target, int name) 1736void glBindTexture (int target, int name)
1426 1737
1427void glConvolutionParameter (int target, int pname, float params) 1738void glConvolutionParameter (int target, int pname, float params)
1428 CODE: 1739 CODE:
1429 glConvolutionParameterf (target, pname, params); 1740 GL_CALL (PFNGLCONVOLUTIONPARAMETERFEXTPROC, glConvolutionParameterf, (target, pname, params));
1430 1741
1431void glConvolutionFilter2D (int target, int internalformat, int width, int height, int format, int type, char *data) 1742void glConvolutionFilter2D (int target, int internalformat, int width, int height, int format, int type, char *data)
1743 CODE:
1744 GL_CALL (PFNGLCONVOLUTIONFILTER2DEXTPROC, glConvolutionFilter2D,
1745 (target, internalformat, width, height, format, type, data));
1746
1747void glSeparableFilter2D (int target, int internalformat, int width, int height, int format, int type, char *row, char *column)
1748 CODE:
1749 GL_CALL (PFNGLSEPARABLEFILTER2DEXTPROC, glSeparableFilter2D,
1750 (target, internalformat, width, height, format, type, row, column));
1432 1751
1433void glTexImage2D (int target, int level, int internalformat, int width, int height, int border, int format, int type, char *data) 1752void glTexImage2D (int target, int level, int internalformat, int width, int height, int border, int format, int type, char *data)
1434 1753
1435void glCopyTexImage2D (int target, int level, int internalformat, int x, int y, int width, int height, int border) 1754void glCopyTexImage2D (int target, int level, int internalformat, int x, int y, int width, int height, int border)
1755
1756void glDrawPixels (int width, int height, int format, int type, char *pixels)
1757
1758void glCopyPixels (int x, int y, int width, int height, int type = GL_COLOR)
1436 1759
1437int glGenTexture () 1760int glGenTexture ()
1438 CODE: 1761 CODE:
1439{ 1762{
1440 GLuint name; 1763 GLuint name;
1465 1788
1466void glEndList () 1789void glEndList ()
1467 1790
1468void glCallList (int list) 1791void glCallList (int list)
1469 1792
1793

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines