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.52 by root, Wed Apr 19 21:17:15 2006 UTC vs.
Revision 1.85 by root, Fri May 19 03:49:47 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>
33 typedef signed char int8_t; 39 typedef signed char int8_t;
34 typedef signed short int16_t; 40 typedef signed short int16_t;
35 typedef signed int int32_t; 41 typedef signed int int32_t;
36#endif 42#endif
37 43
44#include "glext.h"
45
38#define FOW_DARKNESS 32 46#define FOW_DARKNESS 32
39 47
40#define MAP_EXTEND_X 32 48#define MAP_EXTEND_X 32
41#define MAP_EXTEND_Y 512 49#define MAP_EXTEND_Y 512
42 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
43typedef Mix_Chunk *CFClient__MixChunk; 68typedef Mix_Chunk *CFClient__MixChunk;
44typedef Mix_Music *CFClient__MixMusic; 69typedef Mix_Music *CFClient__MixMusic;
45 70
46static PangoContext *context; 71typedef PangoFontDescription *CFClient__Font;
47static PangoFontMap *fontmap;
48 72
49typedef struct cf_layout { 73typedef struct cf_layout {
50 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
51 int base_height; 77 int base_height;
78 CFClient__Font font;
52} *CFClient__Layout; 79} *CFClient__Layout;
80
81static CFClient__Font default_font;
82static PangoContext *ft2_context, *cairo_context;
83static PangoFontMap *ft2_fontmap, *cairo_fontmap;
53 84
54static void 85static void
55substitute_func (FcPattern *pattern, gpointer data) 86substitute_func (FcPattern *pattern, gpointer data)
56{ 87{
57 FcPatternAddBool (pattern, FC_HINTING , 1); 88 FcPatternAddBool (pattern, FC_HINTING , 1);
89#ifdef _WIN32
90 FcPatternAddBool (pattern, FC_AUTOHINT, 1);
91#else
58 FcPatternAddBool (pattern, FC_AUTOHINT, 0); 92 FcPatternAddBool (pattern, FC_AUTOHINT, 0);
93#endif
59} 94}
60 95
61static void 96static void
62layout_update (CFClient__Layout self) 97layout_update_font (CFClient__Layout self)
63{ 98{
64 /* 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
65 * reasonably well with bitstream vera 100 * reasonably well with bitstream vera
66 */ 101 */
67 PangoFontDescription *font = pango_context_get_font_description (context); 102 PangoFontDescription *font = self->font ? self->font : default_font;
68 103
69 int height = self->base_height * (PANGO_SCALE * 8 / 10);
70
71 if (pango_font_description_get_size (font) != height)
72 {
73 pango_font_description_set_absolute_size (font, height); 104 pango_font_description_set_absolute_size (font,
74 pango_layout_context_changed (self->pl); 105 MAX (MIN_FONT_HEIGHT, self->base_height) * (PANGO_SCALE * 8 / 10));
75 } 106
107 pango_layout_set_font_description (self->pl, font);
76} 108}
77 109
78static void 110static void
79layout_get_pixel_size (CFClient__Layout self, int *w, int *h) 111layout_get_pixel_size (CFClient__Layout self, int *w, int *h)
80{ 112{
81 layout_update (self);
82
83 pango_layout_get_pixel_size (self->pl, w, h); 113 pango_layout_get_pixel_size (self->pl, w, h);
84 114
85 *w = (*w + 3) & ~3;
86 if (!*w) *w = 1; 115 if (!*w) *w = 1;
87 if (!*h) *h = 1; 116 if (!*h) *h = 1;
117
118 *w = (*w + 3) & ~3;
88} 119}
89 120
90typedef uint16_t mapface; 121typedef uint16_t mapface;
91 122
92typedef struct { 123typedef struct {
237 break; 268 break;
238 269
239 row->col[x - row->c0].darkness = -1; 270 row->col[x - row->c0].darkness = -1;
240 } 271 }
241 } 272 }
273}
274
275static void
276music_finished (void)
277{
278 SDL_UserEvent ev;
279
280 ev.type = SDL_USEREVENT;
281 ev.code = 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;
296 ev.data2 = 0;
297
298 SDL_PushEvent ((SDL_Event *)&ev);
242} 299}
243 300
244MODULE = CFClient PACKAGE = CFClient 301MODULE = CFClient PACKAGE = CFClient
245 302
246PROTOTYPES: ENABLE 303PROTOTYPES: ENABLE
354# undef const_iv 411# undef const_iv
355 }; 412 };
356 413
357 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; )
358 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 415 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
416}
359 417
418void
419pango_init ()
420 CODE:
421{
422 // delayed, so it can pick up new fonts added by AddFontResourceEx
360 fontmap = pango_ft2_font_map_new (); 423 ft2_fontmap = pango_ft2_font_map_new ();
361 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);
362 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);
363} 429}
364 430
365int 431int
366SDL_Init (U32 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO) 432SDL_Init (U32 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO)
367 433
377 SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 5); 443 SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 5);
378 SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 5); 444 SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 5);
379 SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5); 445 SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5);
380 SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, 1); 446 SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, 1);
381 447
448 SDL_GL_SetAttribute (SDL_GL_BUFFER_SIZE, 15);
449 SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 0);
450
382 SDL_GL_SetAttribute (SDL_GL_ACCUM_RED_SIZE, 0); 451 SDL_GL_SetAttribute (SDL_GL_ACCUM_RED_SIZE, 0);
383 SDL_GL_SetAttribute (SDL_GL_ACCUM_GREEN_SIZE, 0); 452 SDL_GL_SetAttribute (SDL_GL_ACCUM_GREEN_SIZE, 0);
384 SDL_GL_SetAttribute (SDL_GL_ACCUM_BLUE_SIZE, 0); 453 SDL_GL_SetAttribute (SDL_GL_ACCUM_BLUE_SIZE, 0);
385 SDL_GL_SetAttribute (SDL_GL_ACCUM_ALPHA_SIZE, 0); 454 SDL_GL_SetAttribute (SDL_GL_ACCUM_ALPHA_SIZE, 0);
386 455
387 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); 456 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
388 SDL_GL_SetAttribute (SDL_GL_BUFFER_SIZE, 15); 457
389 SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 0); 458 SDL_EnableUNICODE (1);
459 SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
390 460
391 m = SDL_ListModes (0, SDL_FULLSCREEN | SDL_OPENGL); 461 m = SDL_ListModes (0, SDL_FULLSCREEN | SDL_OPENGL);
392 462
393 if (m && m != (SDL_Rect **)-1) 463 if (m && m != (SDL_Rect **)-1)
394 while (*m) 464 while (*m)
410 ); 480 );
411 SDL_WM_SetCaption ("Crossfire+ Client " VERSION, "Crossfire+"); 481 SDL_WM_SetCaption ("Crossfire+ Client " VERSION, "Crossfire+");
412 OUTPUT: 482 OUTPUT:
413 RETVAL 483 RETVAL
414 484
485void
486SDL_GL_SwapBuffers ()
487
488void
489SDL_PollEvent ()
490 PPCODE:
491{
492 SDL_Event ev;
493
494 while (SDL_PollEvent (&ev))
495 {
496 HV *hv = newHV ();
497 hv_store (hv, "type", 4, newSViv (ev.type), 0);
498
499 switch (ev.type)
500 {
501 case SDL_KEYDOWN:
502 case SDL_KEYUP:
503 hv_store (hv, "state", 5, newSViv (ev.key.state), 0);
504 hv_store (hv, "sym", 3, newSViv (ev.key.keysym.sym), 0);
505 hv_store (hv, "mod", 3, newSViv (ev.key.keysym.mod), 0);
506 hv_store (hv, "unicode", 7, newSViv (ev.key.keysym.unicode), 0);
507 break;
508
509 case SDL_ACTIVEEVENT:
510 hv_store (hv, "gain", 4, newSViv (ev.active.gain), 0);
511 hv_store (hv, "state", 5, newSViv (ev.active.state), 0);
512 break;
513
514 case SDL_MOUSEMOTION:
515 hv_store (hv, "state", 5, newSViv (ev.motion.state), 0);
516 hv_store (hv, "x", 1, newSViv (ev.motion.x), 0);
517 hv_store (hv, "y", 1, newSViv (ev.motion.y), 0);
518 hv_store (hv, "xrel", 4, newSViv (ev.motion.xrel), 0);
519 hv_store (hv, "yrel", 4, newSViv (ev.motion.yrel), 0);
520 break;
521
522 case SDL_MOUSEBUTTONDOWN:
523 case SDL_MOUSEBUTTONUP:
524 hv_store (hv, "button", 6, newSViv (ev.button.button), 0);
525 hv_store (hv, "state", 5, newSViv (ev.button.state), 0);
526 hv_store (hv, "x", 1, newSViv (ev.button.x), 0);
527 hv_store (hv, "y", 1, newSViv (ev.button.y), 0);
528 break;
529
530 case SDL_USEREVENT:
531 hv_store (hv, "code", 4, newSViv (ev.user.code), 0);
532 hv_store (hv, "data1", 5, newSViv ((IV)ev.user.data1), 0);
533 hv_store (hv, "data2", 5, newSViv ((IV)ev.user.data2), 0);
534 break;
535 }
536
537 XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv)));
538 }
539}
540
415int 541int
416Mix_VolumeMusic (int newvol = -1)
417
418int
419Mix_OpenAudio (int frequency = 22050, int format = MIX_DEFAULT_FORMAT, int channels = 1, int chunksize = 512) 542Mix_OpenAudio (int frequency = 48000, int format = MIX_DEFAULT_FORMAT, int channels = 1, int chunksize = 2048)
543 POSTCALL:
544 Mix_HookMusicFinished (music_finished);
545 Mix_ChannelFinished (channel_finished);
420 546
421void 547void
422Mix_CloseAudio () 548Mix_CloseAudio ()
423 549
424int 550int
447 573
448void 574void
449add_font (char *file) 575add_font (char *file)
450 CODE: 576 CODE:
451 FcConfigAppFontAddFile (0, (const FcChar8 *)file); /* no idea wether this is required */ 577 FcConfigAppFontAddFile (0, (const FcChar8 *)file); /* no idea wether this is required */
452 578#ifdef _WIN32
453void 579 // cairo... sigh... requires win2000
454set_font (char *file) 580 AddFontResourceEx (file, FR_PRIVATE, 0);
455 CODE: 581#endif
456{
457 int count;
458 FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)file, 0, 0, &count);
459 PangoFontDescription *font = pango_fc_font_description_from_pattern (pattern, 0);
460 FcPatternDestroy (pattern);
461 pango_context_set_font_description (context, font);
462}
463 582
464void 583void
465load_image_inline (SV *image_) 584load_image_inline (SV *image_)
466 ALIAS: 585 ALIAS:
467 load_image_file = 1 586 load_image_file = 1
549 PUSHs (sv_2mortal (newSViv (b / y))); 668 PUSHs (sv_2mortal (newSViv (b / y)));
550 PUSHs (sv_2mortal (newSViv (a / y))); 669 PUSHs (sv_2mortal (newSViv (a / y)));
551} 670}
552 671
553void 672void
673error (char *message)
674 CODE:
675#ifdef _WIN32
676 MessageBox (0, message, "Crossfire+ Error", MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
677#else
678 fprintf (stderr, "ERROR: %s\n", message);
679#endif
680
681void
554fatal (char *message) 682fatal (char *message)
555 CODE: 683 CODE:
556#ifdef _WIN32 684#ifdef _WIN32
557 MessageBox (0, message, "Crossfire+ Fatal Error", MB_OK | MB_ICONERROR | MB_SETFOREGROUND); 685 MessageBox (0, message, "Crossfire+ Fatal Error", MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
558#else 686#else
559 fprintf (stderr, "FATAL: %s\n", message); 687 fprintf (stderr, "FATAL: %s\n", message);
560#endif 688#endif
561 exit (1); 689 exit (1);
562 690
691MODULE = CFClient PACKAGE = CFClient::Font
692
693CFClient::Font
694new_from_file (SV *class, char *path, int id = 0)
695 CODE:
696{
697 int count;
698 FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)path, id, 0, &count);
699 RETVAL = pango_fc_font_description_from_pattern (pattern, 0);
700 FcPatternDestroy (pattern);
701}
702 OUTPUT:
703 RETVAL
704
705void
706DESTROY (CFClient::Font self)
707 CODE:
708 pango_font_description_free (self);
709
710void
711make_default (CFClient::Font self)
712 CODE:
713 default_font = self;
714
563MODULE = CFClient PACKAGE = CFClient::Layout 715MODULE = CFClient PACKAGE = CFClient::Layout
564 716
565CFClient::Layout 717CFClient::Layout
566new (SV *class, int base_height = 10) 718new (SV *class, int rgba = 0)
567 CODE: 719 CODE:
568 New (0, RETVAL, 1, struct cf_layout); 720 New (0, RETVAL, 1, struct cf_layout);
569 RETVAL->base_height = base_height; 721
570 RETVAL->pl = pango_layout_new (context); 722 RETVAL->pl = pango_layout_new (rgba ? cairo_context : ft2_context);
723 RETVAL->rgba = rgba;
724 RETVAL->r = 1.;
725 RETVAL->g = 1.;
726 RETVAL->b = 1.;
727 RETVAL->a = 1.;
728 RETVAL->base_height = MIN_FONT_HEIGHT;
729 RETVAL->font = 0;
730
571 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR); 731 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
732 layout_update_font (RETVAL);
572 OUTPUT: 733 OUTPUT:
573 RETVAL 734 RETVAL
574 735
575void 736void
576DESTROY (CFClient::Layout self) 737DESTROY (CFClient::Layout self)
577 CODE: 738 CODE:
578 g_object_unref (self->pl); 739 g_object_unref (self->pl);
579 Safefree (self); 740 Safefree (self);
580 741
742int
743is_rgba (CFClient::Layout self)
744 CODE:
745 RETVAL = self->rgba;
746 OUTPUT:
747 RETVAL
748
581void 749void
582set_text (CFClient::Layout self, SV *text_) 750set_text (CFClient::Layout self, SV *text_)
583 CODE: 751 CODE:
584{ 752{
585 STRLEN textlen; 753 STRLEN textlen;
605 SvUTF8_on (RETVAL); 773 SvUTF8_on (RETVAL);
606 OUTPUT: 774 OUTPUT:
607 RETVAL 775 RETVAL
608 776
609void 777void
778set_foreground (CFClient::Layout self, float r, float g, float b, float a = 1.)
779 CODE:
780 self->r = r;
781 self->g = g;
782 self->b = b;
783 self->a = a;
784
785void
786set_font (CFClient::Layout self, CFClient::Font font = 0)
787 CODE:
788 if (self->font != font)
789 {
790 self->font = font;
791 layout_update_font (self);
792 }
793
794void
610set_height (CFClient::Layout self, int base_height) 795set_height (CFClient::Layout self, int base_height)
611 CODE: 796 CODE:
797 if (self->base_height != base_height)
798 {
612 self->base_height = base_height; 799 self->base_height = base_height;
800 layout_update_font (self);
801 }
613 802
614void 803void
615set_width (CFClient::Layout self, int max_width = -1) 804set_width (CFClient::Layout self, int max_width = -1)
616 CODE: 805 CODE:
617 pango_layout_set_width (self->pl, max_width < 0 ? max_width : max_width * PANGO_SCALE); 806 pango_layout_set_width (self->pl, max_width < 0 ? max_width : max_width * PANGO_SCALE);
807
808void
809set_indent (CFClient::Layout self, int indent)
810 CODE:
811 pango_layout_set_indent (self->pl, indent * PANGO_SCALE);
812
813void
814set_spacing (CFClient::Layout self, int spacing)
815 CODE:
816 pango_layout_set_spacing (self->pl, spacing * PANGO_SCALE);
817
818void
819set_ellipsise (CFClient::Layout self, int ellipsise)
820 CODE:
821 pango_layout_set_ellipsize (self->pl,
822 ellipsise == 1 ? PANGO_ELLIPSIZE_START
823 : ellipsise == 2 ? PANGO_ELLIPSIZE_MIDDLE
824 : ellipsise == 3 ? PANGO_ELLIPSIZE_END
825 : PANGO_ELLIPSIZE_NONE
826 );
827
828void
829set_single_paragraph_mode (CFClient::Layout self, int spm)
830 CODE:
831 pango_layout_set_single_paragraph_mode (self->pl, !!spm);
618 832
619void 833void
620size (CFClient::Layout self) 834size (CFClient::Layout self)
621 PPCODE: 835 PPCODE:
622{ 836{
623 int w, h; 837 int w, h;
624 838
625 layout_update (self);
626 layout_get_pixel_size (self, &w, &h); 839 layout_get_pixel_size (self, &w, &h);
627 840
628 EXTEND (SP, 2); 841 EXTEND (SP, 2);
629 PUSHs (sv_2mortal (newSViv (w))); 842 PUSHs (sv_2mortal (newSViv (w)));
630 PUSHs (sv_2mortal (newSViv (h))); 843 PUSHs (sv_2mortal (newSViv (h)));
633int 846int
634xy_to_index (CFClient::Layout self, int x, int y) 847xy_to_index (CFClient::Layout self, int x, int y)
635 CODE: 848 CODE:
636{ 849{
637 int index, trailing; 850 int index, trailing;
638
639 layout_update (self);
640 pango_layout_xy_to_index (self->pl, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing); 851 pango_layout_xy_to_index (self->pl, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing);
641
642 RETVAL = index; 852 RETVAL = index;
643} 853}
644 OUTPUT: 854 OUTPUT:
645 RETVAL 855 RETVAL
646 856
647void 857void
648cursor_pos (CFClient::Layout self, int index) 858cursor_pos (CFClient::Layout self, int index)
649 PPCODE: 859 PPCODE:
650{ 860{
651 PangoRectangle strong_pos; 861 PangoRectangle strong_pos;
652 layout_update (self);
653 pango_layout_get_cursor_pos (self->pl, index, &strong_pos, 0); 862 pango_layout_get_cursor_pos (self->pl, index, &strong_pos, 0);
654 863
655 EXTEND (SP, 3); 864 EXTEND (SP, 3);
656 PUSHs (sv_2mortal (newSViv (strong_pos.x / PANGO_SCALE))); 865 PUSHs (sv_2mortal (newSViv (strong_pos.x / PANGO_SCALE)));
657 PUSHs (sv_2mortal (newSViv (strong_pos.y / PANGO_SCALE))); 866 PUSHs (sv_2mortal (newSViv (strong_pos.y / PANGO_SCALE)));
662render (CFClient::Layout self) 871render (CFClient::Layout self)
663 PPCODE: 872 PPCODE:
664{ 873{
665 SV *retval; 874 SV *retval;
666 int w, h; 875 int w, h;
667 FT_Bitmap bitmap;
668 876
669 layout_update (self);
670 layout_get_pixel_size (self, &w, &h); 877 layout_get_pixel_size (self, &w, &h);
671 878
879 if (self->rgba)
880 {
881 cairo_surface_t *surface;
882 cairo_t *cairo;
883
884 retval = newSV (w * h * 4);
885 SvPOK_only (retval);
886 SvCUR_set (retval, w * h * 4);
887
888 memset (SvPVX (retval), 0, w * h * 4);
889
890 surface = cairo_image_surface_create_for_data (
891 (void*)SvPVX (retval), CAIRO_FORMAT_ARGB32, w, h, w * 4);
892 cairo = cairo_create (surface);
893 cairo_set_source_rgba (cairo, self->r, self->g, self->b, self->a);
894
895 pango_cairo_show_layout (cairo, self->pl);
896
897 cairo_destroy (cairo);
898 cairo_surface_destroy (surface);
899
900 // what a mess, and its premultiplied, too :(
901 {
902 uint32_t *p = (uint32_t *)SvPVX (retval);
903 uint32_t *e = p + w * h;
904
905 while (p < e)
906 {
907 uint32_t rgba = *p;
908 rgba = (rgba >> 24) | (rgba << 8);
909 rgba = SDL_SwapBE32 (rgba);
910 *p++ = rgba;
911 }
912 }
913
914 EXTEND (SP, 5);
915 PUSHs (sv_2mortal (newSViv (w)));
916 PUSHs (sv_2mortal (newSViv (h)));
917 PUSHs (sv_2mortal (retval));
918 PUSHs (sv_2mortal (newSViv (GL_RGBA)));
919 PUSHs (sv_2mortal (newSViv (GL_RGBA)));
920 }
921 else
922 {
923 FT_Bitmap bitmap;
924
672 retval = newSV (w * h); 925 retval = newSV (w * h);
673 SvPOK_only (retval); 926 SvPOK_only (retval);
674 SvCUR_set (retval, w * h); 927 SvCUR_set (retval, w * h);
675 928
676 bitmap.rows = h; 929 bitmap.rows = h;
677 bitmap.width = w; 930 bitmap.width = w;
678 bitmap.pitch = w; 931 bitmap.pitch = w;
679 bitmap.buffer = (unsigned char*)SvPVX (retval); 932 bitmap.buffer = (unsigned char*)SvPVX (retval);
680 bitmap.num_grays = 256; 933 bitmap.num_grays = 256;
681 bitmap.pixel_mode = FT_PIXEL_MODE_GRAY; 934 bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
682 935
683 memset (bitmap.buffer, 0, w * h); 936 memset (bitmap.buffer, 0, w * h);
684 937
685 pango_ft2_render_layout (&bitmap, self->pl, 0 * PANGO_SCALE, 0 * PANGO_SCALE); 938 pango_ft2_render_layout (&bitmap, self->pl, 0 * PANGO_SCALE, 0 * PANGO_SCALE);
686 939
687 EXTEND (SP, 3); 940 EXTEND (SP, 5);
688 PUSHs (sv_2mortal (newSViv (w))); 941 PUSHs (sv_2mortal (newSViv (w)));
689 PUSHs (sv_2mortal (newSViv (h))); 942 PUSHs (sv_2mortal (newSViv (h)));
690 PUSHs (sv_2mortal (retval)); 943 PUSHs (sv_2mortal (retval));
944 PUSHs (sv_2mortal (newSViv (GL_ALPHA)));
945 PUSHs (sv_2mortal (newSViv (GL_ALPHA)));
946 }
691} 947}
692 948
693MODULE = CFClient PACKAGE = CFClient::Texture 949MODULE = CFClient PACKAGE = CFClient::Texture
694 950
695void 951void
696draw_quad (SV *self, float x, float y, float w = 0, float h = 0) 952draw_quad (SV *self, float x, float y, float w = 0, float h = 0)
697 PROTOTYPE: $$$;$$ 953 PROTOTYPE: $$$;$$
954 ALIAS:
955 draw_quad_alpha = 1
956 draw_quad_alpha_premultiplied = 2
698 CODE: 957 CODE:
699{ 958{
700 HV *hv = (HV *)SvRV (self); 959 HV *hv = (HV *)SvRV (self);
701 float s = SvNV (*hv_fetch (hv, "s", 1, 1)); 960 float s = SvNV (*hv_fetch (hv, "s", 1, 1));
702 float t = SvNV (*hv_fetch (hv, "t", 1, 1)); 961 float t = SvNV (*hv_fetch (hv, "t", 1, 1));
707 { 966 {
708 w = SvNV (*hv_fetch (hv, "w", 1, 1)); 967 w = SvNV (*hv_fetch (hv, "w", 1, 1));
709 h = SvNV (*hv_fetch (hv, "h", 1, 1)); 968 h = SvNV (*hv_fetch (hv, "h", 1, 1));
710 } 969 }
711 970
971 if (ix)
972 {
973 glEnable (GL_BLEND);
974 glBlendFunc (ix == 1 ? GL_SRC_ALPHA : GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
975 }
976
712 glBindTexture (GL_TEXTURE_2D, name); 977 glBindTexture (GL_TEXTURE_2D, name);
978
713 if (wrap_mode) { 979 if (wrap_mode)
980 {
714 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 981 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
715 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 982 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
716 } 983 }
984
717 glBegin (GL_QUADS); 985 glBegin (GL_QUADS);
718 glTexCoord2f (0, 0); glVertex2f (x , y ); 986 glTexCoord2f (0, 0); glVertex2f (x , y );
719 glTexCoord2f (0, t); glVertex2f (x , y + h); 987 glTexCoord2f (0, t); glVertex2f (x , y + h);
720 glTexCoord2f (s, t); glVertex2f (x + w, y + h); 988 glTexCoord2f (s, t); glVertex2f (x + w, y + h);
721 glTexCoord2f (s, 0); glVertex2f (x + w, y ); 989 glTexCoord2f (s, 0); glVertex2f (x + w, y );
722 glEnd (); 990 glEnd ();
991
992 if (ix)
993 glDisable (GL_BLEND);
723} 994}
724 995
725MODULE = CFClient PACKAGE = CFClient::Map 996MODULE = CFClient PACKAGE = CFClient::Map
726 997
727CFClient::Map 998CFClient::Map
885 cell->darkness = -1; 1156 cell->darkness = -1;
886 } 1157 }
887} 1158}
888 1159
889SV * 1160SV *
890mapmap (CFClient::Map self, int w, int h) 1161mapmap (CFClient::Map self, int x0, int y0, int w, int h)
891 CODE: 1162 CODE:
892{ 1163{
893 int x0, x1, x; 1164 int x1, x;
894 int y0, y1, y; 1165 int y1, y;
895 int z; 1166 int z;
896 SV *map_sv = newSV (w * h * sizeof (uint32_t)); 1167 SV *map_sv = newSV (w * h * sizeof (uint32_t));
897 uint32_t *map = (uint32_t *)SvPVX (map_sv); 1168 uint32_t *map = (uint32_t *)SvPVX (map_sv);
898 1169
899 SvPOK_only (map_sv); 1170 SvPOK_only (map_sv);
900 SvCUR_set (map_sv, w * h * sizeof (uint32_t)); 1171 SvCUR_set (map_sv, w * h * sizeof (uint32_t));
901 1172
902 x0 = self->x - w / 2; x1 = x0 + w; 1173 x0 += self->x; x1 = x0 + w;
903 y0 = self->y - h / 2; y1 = y0 + h; 1174 y0 += self->y; y1 = y0 + h;
904 1175
905 for (y = y0; y < y1; y++) 1176 for (y = y0; y < y1; y++)
906 { 1177 {
907 maprow *row = 0 <= y && y < self->rows 1178 maprow *row = 0 <= y && y < self->rows
908 ? self->row + y 1179 ? self->row + y
1048 *data++ = 0; /* version 0 format */ 1319 *data++ = 0; /* version 0 format */
1049 *data++ = w >> 8; *data++ = w; 1320 *data++ = w >> 8; *data++ = w;
1050 *data++ = h >> 8; *data++ = h; 1321 *data++ = h >> 8; *data++ = h;
1051 1322
1052 // we need to do this 'cause we don't keep an absolute coord system for rows 1323 // we need to do this 'cause we don't keep an absolute coord system for rows
1053 // TODO: treat rows as we treat 1324 // TODO: treat rows as we treat columns
1054 map_get_row (self, y0 + self->y - self->oy);//D 1325 map_get_row (self, y0 + self->y - self->oy);//D
1055 map_get_row (self, y0 + self->y - self->oy + h - 1);//D 1326 map_get_row (self, y0 + self->y - self->oy + h - 1);//D
1056 1327
1057 x0 += self->x - self->ox; 1328 x0 += self->x - self->ox;
1058 y0 += self->y - self->oy; 1329 y0 += self->y - self->oy;
1122 1393
1123 w = *data++ << 8; w |= *data++; 1394 w = *data++ << 8; w |= *data++;
1124 h = *data++ << 8; h |= *data++; 1395 h = *data++ << 8; h |= *data++;
1125 1396
1126 // we need to do this 'cause we don't keep an absolute coord system for rows 1397 // we need to do this 'cause we don't keep an absolute coord system for rows
1127 // TODO: treat rows as we treat 1398 // TODO: treat rows as we treat columns
1128 map_get_row (self, y0 + self->y - self->oy);//D 1399 map_get_row (self, y0 + self->y - self->oy);//D
1129 map_get_row (self, y0 + self->y - self->oy + h - 1);//D 1400 map_get_row (self, y0 + self->y - self->oy + h - 1);//D
1130 1401
1131 x0 += self->x - self->ox; 1402 x0 += self->x - self->ox;
1132 y0 += self->y - self->oy; 1403 y0 += self->y - self->oy;
1223 CODE: 1494 CODE:
1224 RETVAL = Mix_PlayMusic (self, loops); 1495 RETVAL = Mix_PlayMusic (self, loops);
1225 OUTPUT: 1496 OUTPUT:
1226 RETVAL 1497 RETVAL
1227 1498
1499MODULE = CFClient PACKAGE = CFClient::OpenGL
1500
1501BOOT:
1502{
1503 HV *stash = gv_stashpv ("CFClient::OpenGL", 1);
1504 static const struct {
1505 const char *name;
1506 IV iv;
1507 } *civ, const_iv[] = {
1508# define const_iv(name) { # name, (IV)name }
1509 const_iv (GL_COLOR_MATERIAL),
1510 const_iv (GL_SMOOTH),
1511 const_iv (GL_FLAT),
1512 const_iv (GL_DITHER),
1513 const_iv (GL_BLEND),
1514 const_iv (GL_SCISSOR_TEST),
1515 const_iv (GL_AND),
1516 const_iv (GL_ONE),
1517 const_iv (GL_ZERO),
1518 const_iv (GL_SRC_ALPHA),
1519 const_iv (GL_SRC_ALPHA_SATURATE),
1520 const_iv (GL_ONE_MINUS_SRC_ALPHA),
1521 const_iv (GL_ONE_MINUS_DST_ALPHA),
1522 const_iv (GL_RGB),
1523 const_iv (GL_RGBA),
1524 const_iv (GL_UNSIGNED_BYTE),
1525 const_iv (GL_ALPHA),
1526 const_iv (GL_LUMINANCE),
1527 const_iv (GL_FLOAT),
1528 const_iv (GL_UNSIGNED_INT_8_8_8_8_REV),
1529 const_iv (GL_COMPILE),
1530 const_iv (GL_TEXTURE_1D),
1531 const_iv (GL_TEXTURE_2D),
1532 const_iv (GL_TEXTURE_ENV),
1533 const_iv (GL_TEXTURE_MAG_FILTER),
1534 const_iv (GL_TEXTURE_MIN_FILTER),
1535 const_iv (GL_TEXTURE_ENV_MODE),
1536 const_iv (GL_TEXTURE_WRAP_S),
1537 const_iv (GL_TEXTURE_WRAP_T),
1538 const_iv (GL_CLAMP),
1539 const_iv (GL_REPEAT),
1540 const_iv (GL_NEAREST),
1541 const_iv (GL_LINEAR),
1542 const_iv (GL_NEAREST_MIPMAP_NEAREST),
1543 const_iv (GL_LINEAR_MIPMAP_NEAREST),
1544 const_iv (GL_NEAREST_MIPMAP_LINEAR),
1545 const_iv (GL_LINEAR_MIPMAP_LINEAR),
1546 const_iv (GL_GENERATE_MIPMAP),
1547 const_iv (GL_MODULATE),
1548 const_iv (GL_DECAL),
1549 const_iv (GL_REPLACE),
1550 const_iv (GL_COLOR_BUFFER_BIT),
1551 const_iv (GL_PROJECTION),
1552 const_iv (GL_MODELVIEW),
1553 const_iv (GL_COLOR_LOGIC_OP),
1554 const_iv (GL_SEPARABLE_2D),
1555 const_iv (GL_CONVOLUTION_2D),
1556 const_iv (GL_CONVOLUTION_BORDER_MODE),
1557 const_iv (GL_CONSTANT_BORDER),
1558 const_iv (GL_LINES),
1559 const_iv (GL_QUADS),
1560 const_iv (GL_LINE_LOOP),
1561 const_iv (GL_PERSPECTIVE_CORRECTION_HINT),
1562 const_iv (GL_FASTEST),
1563# undef const_iv
1564 };
1565
1566 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
1567 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
1568}
1569
1570int glGetError ()
1571
1572void glClear (int mask)
1573
1574void glClearColor (float r, float g, float b, float a = 1.0)
1575 PROTOTYPE: @
1576
1577void glEnable (int cap)
1578
1579void glDisable (int cap)
1580
1581void glShadeModel (int mode)
1582
1583void glHint (int target, int mode)
1584
1585void glBlendFunc (int sfactor, int dfactor)
1586
1587void glLogicOp (int opcode)
1588
1589void glColorMask (int red, int green, int blue, int alpha)
1590
1591void glMatrixMode (int mode)
1592
1593void glPushMatrix ()
1594
1595void glPopMatrix ()
1596
1597void glLoadIdentity ()
1598
1599# near and far are due to microsofts buggy c compiler
1600void glOrtho (double left, double right, double bottom, double top, double near_, double far_)
1601
1602void glViewport (int x, int y, int width, int height)
1603
1604void glScissor (int x, int y, int width, int height)
1605
1606void glTranslate (float x, float y, float z = 0.)
1607 CODE:
1608 glTranslatef (x, y, z);
1609
1610void glScale (float x, float y, float z = 1.)
1611 CODE:
1612 glScalef (x, y, z);
1613
1614void glRotate (float angle, float x, float y, float z)
1615 CODE:
1616 glRotatef (angle, x, y, z);
1617
1618void glBegin (int mode)
1619
1620void glEnd ()
1621
1622void glColor (float r, float g, float b, float a = 1.0)
1623 PROTOTYPE: @
1624 CODE:
1625 glColor4ub (MIN ((int)(r * 255.f), 255),
1626 MIN ((int)(g * 255.f), 255),
1627 MIN ((int)(b * 255.f), 255),
1628 MIN ((int)(a * 255.f), 255));
1629
1630void glVertex (float x, float y, float z = 0.)
1631 CODE:
1632 glVertex3f (x, y, z);
1633
1634void glTexCoord (float s, float t)
1635 CODE:
1636 glTexCoord2f (s, t);
1637
1638void glTexEnv (int target, int pname, float param)
1639 CODE:
1640 glTexEnvf (target, pname, param);
1641
1642void glTexParameter (int target, int pname, float param)
1643 CODE:
1644 glTexParameterf (target, pname, param);
1645
1646void glBindTexture (int target, int name)
1647
1648void glConvolutionParameter (int target, int pname, float params)
1649 CODE:
1650 GL_CALL (PFNGLCONVOLUTIONPARAMETERFEXTPROC, glConvolutionParameterf, (target, pname, params));
1651
1652void glConvolutionFilter2D (int target, int internalformat, int width, int height, int format, int type, char *data)
1653 CODE:
1654 GL_CALL (PFNGLCONVOLUTIONFILTER2DEXTPROC, glConvolutionFilter2D,
1655 (target, internalformat, width, height, format, type, data));
1656
1657void glSeparableFilter2D (int target, int internalformat, int width, int height, int format, int type, char *row, char *column)
1658 CODE:
1659 GL_CALL (PFNGLSEPARABLEFILTER2DEXTPROC, glSeparableFilter2D,
1660 (target, internalformat, width, height, format, type, row, column));
1661
1662void glTexImage2D (int target, int level, int internalformat, int width, int height, int border, int format, int type, char *data)
1663
1664void glCopyTexImage2D (int target, int level, int internalformat, int x, int y, int width, int height, int border)
1665
1666void glRasterPos (int x, int y)
1667 CODE:
1668 glRasterPos2i (x, y);
1669
1670void glCopyPixels (int x, int y, int width, int height, int type = GL_COLOR)
1671
1672int glGenTexture ()
1673 CODE:
1674{
1675 GLuint name;
1676 glGenTextures (1, &name);
1677 RETVAL = name;
1678}
1679 OUTPUT:
1680 RETVAL
1681
1682void glDeleteTexture (int name)
1683 CODE:
1684{
1685 GLuint name_ = name;
1686 glDeleteTextures (1, &name_);
1687}
1688
1689int glGenList ()
1690 CODE:
1691 RETVAL = glGenLists (1);
1692 OUTPUT:
1693 RETVAL
1694
1695void glDeleteList (int list)
1696 CODE:
1697 glDeleteLists (list, 1);
1698
1699void glNewList (int list, int mode = GL_COMPILE)
1700
1701void glEndList ()
1702
1703void glCallList (int list)
1704

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines