ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/Client.xs
Revision: 1.25
Committed: Wed Apr 12 21:20:42 2006 UTC (18 years, 1 month ago) by root
Branch: MAIN
Changes since 1.24: +11 -4 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.13 add_font (char *file)
90     CODE:
91     FcConfigAppFontAddFile (0, (const FcChar8 *)file); /* no idea wether this is required */
92    
93     void
94 root 1.9 set_font (char *file)
95 root 1.8 CODE:
96     {
97 root 1.9 int count;
98     FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)file, 0, 0, &count);
99 root 1.10 PangoFontDescription *font = pango_fc_font_description_from_pattern (pattern, 0);
100 root 1.9 FcPatternDestroy (pattern);
101 root 1.8 pango_context_set_font_description (context, font);
102     }
103    
104 root 1.23 void
105     load_image_inline (SV *image_)
106     ALIAS:
107     load_image_file = 1
108     PPCODE:
109     {
110     STRLEN image_len;
111     char *image = (char *)SvPVbyte (image_, image_len);
112     SDL_Surface *surface, *surface2;
113     SDL_PixelFormat fmt;
114     SDL_RWops *rw = ix
115     ? SDL_RWFromFile (image, "r")
116     : SDL_RWFromConstMem (image, image_len);
117    
118     if (!rw)
119     croak ("load_image: unable to open file");
120    
121     surface = IMG_Load_RW (rw, 1);
122     if (!surface)
123     croak ("load_image: unable to read file");
124    
125     fmt.palette = NULL;
126     fmt.BitsPerPixel = 32;
127     fmt.BytesPerPixel = 4;
128     fmt.Rmask = 0x000000ff;
129     fmt.Gmask = 0x0000ff00;
130     fmt.Bmask = 0x00ff0000;
131     fmt.Amask = 0xff000000;
132     fmt.Rloss = 0;
133     fmt.Gloss = 0;
134     fmt.Bloss = 0;
135     fmt.Aloss = 0;
136     fmt.Rshift = 0;
137     fmt.Gshift = 8;
138     fmt.Bshift = 16;
139     fmt.Ashift = 24;
140     fmt.colorkey = 0;
141     fmt.alpha = 0;
142    
143     surface2 = SDL_ConvertSurface (surface, &fmt, SDL_SWSURFACE);
144    
145     EXTEND (SP, 5);
146     PUSHs (sv_2mortal (newSViv (surface2->w)));
147     PUSHs (sv_2mortal (newSViv (surface2->h)));
148     SDL_LockSurface (surface2);
149     PUSHs (sv_2mortal (newSVpvn (surface2->pixels, surface2->h * surface2->pitch)));
150     SDL_UnlockSurface (surface2);
151 root 1.24 PUSHs (sv_2mortal (newSViv (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA) ? GL_RGBA : GL_RGB)));
152 root 1.23 PUSHs (sv_2mortal (newSViv (GL_RGBA)));
153     PUSHs (sv_2mortal (newSViv (GL_UNSIGNED_INT_8_8_8_8_REV)));
154    
155     SDL_FreeSurface (surface);
156     SDL_FreeSurface (surface2);
157     }
158    
159 root 1.25 void
160     fatal (char *message)
161     CODE:
162     #ifdef WIN32
163     MessageBox (0, message, "Crossfire+ Fatal Error", MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
164     #else
165     fprintf (stderr, "%s\n", message);
166     #endif
167     exit (1);
168    
169 root 1.15 MODULE = CFClient PACKAGE = CFClient::Layout
170 root 1.14
171 root 1.15 CFClient::Layout
172 root 1.14 new (SV *class, int base_height = 10)
173     CODE:
174     New (0, RETVAL, 1, struct cf_layout);
175     RETVAL->base_height = base_height;
176     RETVAL->pl = pango_layout_new (context);
177     pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
178     OUTPUT:
179     RETVAL
180    
181     void
182 root 1.15 DESTROY (CFClient::Layout self)
183 root 1.14 CODE:
184     g_object_unref (self->pl);
185     Safefree (self);
186 root 1.13
187 root 1.8 void
188 root 1.15 set_markup (CFClient::Layout self, SV *text_)
189 root 1.14 CODE:
190 root 1.5 {
191     STRLEN textlen;
192     char *text = SvPVutf8 (text_, textlen);
193 root 1.14
194     pango_layout_set_markup (self->pl, text, textlen);
195     }
196    
197     void
198 root 1.16 set_height (CFClient::Layout self, int base_height)
199     CODE:
200     self->base_height = base_height;
201    
202     void
203 root 1.15 set_width (CFClient::Layout self, int max_width = -1)
204 root 1.14 CODE:
205     pango_layout_set_width (self->pl, max_width < 0 ? max_width : max_width * PANGO_SCALE);
206    
207     void
208 root 1.15 size (CFClient::Layout self)
209 root 1.14 PPCODE:
210     {
211     int w, h;
212    
213 root 1.17 layout_update (self);
214 root 1.14 layout_get_pixel_size (self, &w, &h);
215    
216     EXTEND (SP, 2);
217     PUSHs (sv_2mortal (newSViv (w)));
218     PUSHs (sv_2mortal (newSViv (h)));
219     }
220    
221 root 1.17 int
222     xy_to_index (CFClient::Layout self, int x, int y)
223     CODE:
224     {
225     int index, trailing;
226    
227     layout_update (self);
228     pango_layout_xy_to_index (self->pl, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing);
229    
230     RETVAL = index;
231     }
232     OUTPUT:
233     RETVAL
234    
235     void
236     cursor_pos (CFClient::Layout self, int index)
237     PPCODE:
238     {
239     PangoRectangle strong_pos;
240     layout_update (self);
241     pango_layout_get_cursor_pos (self->pl, index, &strong_pos, 0);
242     EXTEND (SP, 3);
243     PUSHs (sv_2mortal (newSViv (strong_pos.x / PANGO_SCALE)));
244     PUSHs (sv_2mortal (newSViv (strong_pos.y / PANGO_SCALE)));
245     PUSHs (sv_2mortal (newSViv (strong_pos.height / PANGO_SCALE)));
246     }
247    
248 root 1.14 void
249 root 1.15 render (CFClient::Layout self)
250 root 1.14 PPCODE:
251     {
252 root 1.5 SV *retval;
253     int w, h;
254     FT_Bitmap bitmap;
255    
256 root 1.17 layout_update (self);
257 root 1.14 layout_get_pixel_size (self, &w, &h);
258 root 1.5
259     retval = newSV (w * h);
260     SvPOK_only (retval);
261     SvCUR_set (retval, w * h);
262    
263     bitmap.rows = h;
264     bitmap.width = w;
265     bitmap.pitch = w;
266     bitmap.buffer = (unsigned char*)SvPVX (retval);
267     bitmap.num_grays = 256;
268     bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
269    
270     memset (bitmap.buffer, 0, w * h);
271    
272 root 1.14 pango_ft2_render_layout (&bitmap, self->pl, 0 * PANGO_SCALE, 0 * PANGO_SCALE);
273 root 1.1
274 root 1.5 EXTEND (SP, 3);
275     PUSHs (sv_2mortal (newSViv (w)));
276     PUSHs (sv_2mortal (newSViv (h)));
277     PUSHs (sv_2mortal (retval));
278     }
279 root 1.11
280 root 1.15 MODULE = CFClient PACKAGE = CFClient::Texture
281 root 1.11
282     void
283 root 1.12 draw_quad (SV *self, double x, double y, double w = 0, double h = 0)
284     PROTOTYPE: $$$;$$
285 root 1.11 CODE:
286     {
287 root 1.12 HV *hv = (HV *)SvRV (self);
288     double s = SvNV (*hv_fetch (hv, "s", 1, 1));
289     double t = SvNV (*hv_fetch (hv, "t", 1, 1));
290     int name = SvIV (*hv_fetch (hv, "name", 4, 1));
291    
292     if (items < 5)
293     {
294 root 1.18 w = SvNV (*hv_fetch (hv, "w", 1, 1));
295     h = SvNV (*hv_fetch (hv, "h", 1, 1));
296 root 1.12 }
297    
298     glBindTexture (GL_TEXTURE_2D, name);
299     glBegin (GL_QUADS);
300     glTexCoord2d (0, 0); glVertex2d (x , y );
301     glTexCoord2d (0, t); glVertex2d (x , y + h);
302     glTexCoord2d (s, t); glVertex2d (x + w, y + h);
303     glTexCoord2d (s, 0); glVertex2d (x + w, y );
304     glEnd ();
305 root 1.11 }