ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/Client.xs
Revision: 1.26
Committed: Wed Apr 12 23:15:38 2006 UTC (18 years, 1 month ago) by root
Branch: MAIN
Changes since 1.25: +6 -0 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #include "EXTERN.h"
2     #include "perl.h"
3     #include "XSUB.h"
4    
5 root 1.5 #include <string.h>
6 root 1.25 #include <stdio.h>
7 root 1.5
8 root 1.2 #include <SDL.h>
9 root 1.23 #include <SDL_image.h>
10 root 1.3 #include <SDL_opengl.h>
11 root 1.5
12     #include <pango/pango.h>
13 root 1.10 #include <pango/pangofc-fontmap.h>
14 root 1.5 #include <pango/pangoft2.h>
15    
16 root 1.10 #include <sys/types.h>
17     #include <sys/socket.h>
18     #include <netinet/in.h>
19     #include <netinet/tcp.h>
20    
21 root 1.5 static PangoContext *context;
22     static PangoFontMap *fontmap;
23 root 1.2
24 root 1.14 typedef struct cf_layout {
25     PangoLayout *pl;
26     int base_height;
27 root 1.15 } *CFClient__Layout;
28 root 1.14
29     static void
30 root 1.19 substitute_func (FcPattern *pattern, gpointer data)
31     {
32 root 1.20 FcPatternAddBool (pattern, FC_HINTING , 1);
33     FcPatternAddBool (pattern, FC_AUTOHINT, 1);
34 root 1.19 }
35    
36     static void
37 root 1.17 layout_update (CFClient__Layout self)
38     {
39 root 1.19 /* use a random scale factor to account for unknown descenders, 0.8 works
40     * reasonably well with bitstream vera
41     */
42 root 1.17 PangoFontDescription *font = pango_context_get_font_description (context);
43 root 1.19 pango_font_description_set_absolute_size (font, self->base_height * (PANGO_SCALE * 8 / 10));
44 root 1.17 }
45    
46     static void
47 root 1.15 layout_get_pixel_size (CFClient__Layout self, int *w, int *h)
48 root 1.14 {
49 root 1.19 layout_update (self);
50 root 1.16
51 root 1.14 pango_layout_get_pixel_size (self->pl, w, h);
52    
53     *w = (*w + 3) & ~3;
54     if (!*w) *w = 1;
55     if (!*h) *h = 1;
56     }
57    
58 root 1.15 MODULE = CFClient PACKAGE = CFClient
59 root 1.1
60 root 1.11 PROTOTYPES: ENABLE
61    
62 root 1.5 BOOT:
63     {
64     fontmap = pango_ft2_font_map_new ();
65 root 1.19 pango_ft2_font_map_set_default_substitute ((PangoFT2FontMap *)fontmap, substitute_func, 0, 0);
66 root 1.8 context = pango_ft2_font_map_create_context ((PangoFT2FontMap *)fontmap);
67 root 1.5 }
68    
69 root 1.10 void
70     lowdelay (int fd, int val = 1)
71     CODE:
72     setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof (val));
73    
74 root 1.3 char *
75 root 1.4 gl_version ()
76     CODE:
77 root 1.5 RETVAL = (char *)glGetString (GL_VERSION);
78 root 1.4 OUTPUT:
79     RETVAL
80    
81     char *
82 root 1.3 gl_extensions ()
83     CODE:
84 root 1.5 RETVAL = (char *)glGetString (GL_EXTENSIONS);
85 root 1.3 OUTPUT:
86     RETVAL
87    
88 root 1.5 void
89 root 1.26 glConvolutionParameteri (U32 target, U32 name, I32 value)
90    
91     void
92     glConvolutionFilter2D (U32 target, U32 internalformat, I32 width, I32 height, U32 format, U32 type, char *image)
93    
94     void
95 root 1.13 add_font (char *file)
96     CODE:
97     FcConfigAppFontAddFile (0, (const FcChar8 *)file); /* no idea wether this is required */
98    
99     void
100 root 1.9 set_font (char *file)
101 root 1.8 CODE:
102     {
103 root 1.9 int count;
104     FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)file, 0, 0, &count);
105 root 1.10 PangoFontDescription *font = pango_fc_font_description_from_pattern (pattern, 0);
106 root 1.9 FcPatternDestroy (pattern);
107 root 1.8 pango_context_set_font_description (context, font);
108     }
109    
110 root 1.23 void
111     load_image_inline (SV *image_)
112     ALIAS:
113     load_image_file = 1
114     PPCODE:
115     {
116     STRLEN image_len;
117     char *image = (char *)SvPVbyte (image_, image_len);
118     SDL_Surface *surface, *surface2;
119     SDL_PixelFormat fmt;
120     SDL_RWops *rw = ix
121     ? SDL_RWFromFile (image, "r")
122     : SDL_RWFromConstMem (image, image_len);
123    
124     if (!rw)
125     croak ("load_image: unable to open file");
126    
127     surface = IMG_Load_RW (rw, 1);
128     if (!surface)
129     croak ("load_image: unable to read file");
130    
131     fmt.palette = NULL;
132     fmt.BitsPerPixel = 32;
133     fmt.BytesPerPixel = 4;
134     fmt.Rmask = 0x000000ff;
135     fmt.Gmask = 0x0000ff00;
136     fmt.Bmask = 0x00ff0000;
137     fmt.Amask = 0xff000000;
138     fmt.Rloss = 0;
139     fmt.Gloss = 0;
140     fmt.Bloss = 0;
141     fmt.Aloss = 0;
142     fmt.Rshift = 0;
143     fmt.Gshift = 8;
144     fmt.Bshift = 16;
145     fmt.Ashift = 24;
146     fmt.colorkey = 0;
147     fmt.alpha = 0;
148    
149     surface2 = SDL_ConvertSurface (surface, &fmt, SDL_SWSURFACE);
150    
151     EXTEND (SP, 5);
152     PUSHs (sv_2mortal (newSViv (surface2->w)));
153     PUSHs (sv_2mortal (newSViv (surface2->h)));
154     SDL_LockSurface (surface2);
155     PUSHs (sv_2mortal (newSVpvn (surface2->pixels, surface2->h * surface2->pitch)));
156     SDL_UnlockSurface (surface2);
157 root 1.24 PUSHs (sv_2mortal (newSViv (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA) ? GL_RGBA : GL_RGB)));
158 root 1.23 PUSHs (sv_2mortal (newSViv (GL_RGBA)));
159     PUSHs (sv_2mortal (newSViv (GL_UNSIGNED_INT_8_8_8_8_REV)));
160    
161     SDL_FreeSurface (surface);
162     SDL_FreeSurface (surface2);
163     }
164    
165 root 1.25 void
166     fatal (char *message)
167     CODE:
168     #ifdef WIN32
169     MessageBox (0, message, "Crossfire+ Fatal Error", MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
170     #else
171     fprintf (stderr, "%s\n", message);
172     #endif
173     exit (1);
174    
175 root 1.15 MODULE = CFClient PACKAGE = CFClient::Layout
176 root 1.14
177 root 1.15 CFClient::Layout
178 root 1.14 new (SV *class, int base_height = 10)
179     CODE:
180     New (0, RETVAL, 1, struct cf_layout);
181     RETVAL->base_height = base_height;
182     RETVAL->pl = pango_layout_new (context);
183     pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
184     OUTPUT:
185     RETVAL
186    
187     void
188 root 1.15 DESTROY (CFClient::Layout self)
189 root 1.14 CODE:
190     g_object_unref (self->pl);
191     Safefree (self);
192 root 1.13
193 root 1.8 void
194 root 1.15 set_markup (CFClient::Layout self, SV *text_)
195 root 1.14 CODE:
196 root 1.5 {
197     STRLEN textlen;
198     char *text = SvPVutf8 (text_, textlen);
199 root 1.14
200     pango_layout_set_markup (self->pl, text, textlen);
201     }
202    
203     void
204 root 1.16 set_height (CFClient::Layout self, int base_height)
205     CODE:
206     self->base_height = base_height;
207    
208     void
209 root 1.15 set_width (CFClient::Layout self, int max_width = -1)
210 root 1.14 CODE:
211     pango_layout_set_width (self->pl, max_width < 0 ? max_width : max_width * PANGO_SCALE);
212    
213     void
214 root 1.15 size (CFClient::Layout self)
215 root 1.14 PPCODE:
216     {
217     int w, h;
218    
219 root 1.17 layout_update (self);
220 root 1.14 layout_get_pixel_size (self, &w, &h);
221    
222     EXTEND (SP, 2);
223     PUSHs (sv_2mortal (newSViv (w)));
224     PUSHs (sv_2mortal (newSViv (h)));
225     }
226    
227 root 1.17 int
228     xy_to_index (CFClient::Layout self, int x, int y)
229     CODE:
230     {
231     int index, trailing;
232    
233     layout_update (self);
234     pango_layout_xy_to_index (self->pl, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing);
235    
236     RETVAL = index;
237     }
238     OUTPUT:
239     RETVAL
240    
241     void
242     cursor_pos (CFClient::Layout self, int index)
243     PPCODE:
244     {
245     PangoRectangle strong_pos;
246     layout_update (self);
247     pango_layout_get_cursor_pos (self->pl, index, &strong_pos, 0);
248     EXTEND (SP, 3);
249     PUSHs (sv_2mortal (newSViv (strong_pos.x / PANGO_SCALE)));
250     PUSHs (sv_2mortal (newSViv (strong_pos.y / PANGO_SCALE)));
251     PUSHs (sv_2mortal (newSViv (strong_pos.height / PANGO_SCALE)));
252     }
253    
254 root 1.14 void
255 root 1.15 render (CFClient::Layout self)
256 root 1.14 PPCODE:
257     {
258 root 1.5 SV *retval;
259     int w, h;
260     FT_Bitmap bitmap;
261    
262 root 1.17 layout_update (self);
263 root 1.14 layout_get_pixel_size (self, &w, &h);
264 root 1.5
265     retval = newSV (w * h);
266     SvPOK_only (retval);
267     SvCUR_set (retval, w * h);
268    
269     bitmap.rows = h;
270     bitmap.width = w;
271     bitmap.pitch = w;
272     bitmap.buffer = (unsigned char*)SvPVX (retval);
273     bitmap.num_grays = 256;
274     bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
275    
276     memset (bitmap.buffer, 0, w * h);
277    
278 root 1.14 pango_ft2_render_layout (&bitmap, self->pl, 0 * PANGO_SCALE, 0 * PANGO_SCALE);
279 root 1.1
280 root 1.5 EXTEND (SP, 3);
281     PUSHs (sv_2mortal (newSViv (w)));
282     PUSHs (sv_2mortal (newSViv (h)));
283     PUSHs (sv_2mortal (retval));
284     }
285 root 1.11
286 root 1.15 MODULE = CFClient PACKAGE = CFClient::Texture
287 root 1.11
288     void
289 root 1.12 draw_quad (SV *self, double x, double y, double w = 0, double h = 0)
290     PROTOTYPE: $$$;$$
291 root 1.11 CODE:
292     {
293 root 1.12 HV *hv = (HV *)SvRV (self);
294     double s = SvNV (*hv_fetch (hv, "s", 1, 1));
295     double t = SvNV (*hv_fetch (hv, "t", 1, 1));
296     int name = SvIV (*hv_fetch (hv, "name", 4, 1));
297    
298     if (items < 5)
299     {
300 root 1.18 w = SvNV (*hv_fetch (hv, "w", 1, 1));
301     h = SvNV (*hv_fetch (hv, "h", 1, 1));
302 root 1.12 }
303    
304     glBindTexture (GL_TEXTURE_2D, name);
305     glBegin (GL_QUADS);
306     glTexCoord2d (0, 0); glVertex2d (x , y );
307     glTexCoord2d (0, t); glVertex2d (x , y + h);
308     glTexCoord2d (s, t); glVertex2d (x + w, y + h);
309     glTexCoord2d (s, 0); glVertex2d (x + w, y );
310     glEnd ();
311 root 1.11 }