ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/Client.xs
Revision: 1.125
Committed: Tue Jul 4 23:44:23 2006 UTC (17 years, 10 months ago) by root
Branch: MAIN
Changes since 1.124: +0 -4 lines
Log Message:
small fixed, ported to the language called microsoft c, which
superficially looks like ISO-C and is similar enough so you can write
programs in their common subset.

File Contents

# User Rev Content
1 root 1.48 #ifdef _WIN32
2 root 1.79 # define _WIN32_WINNT 0x0500 // needed to get win2000 api calls
3 root 1.48 # include <malloc.h>
4 root 1.79 # include <windows.h>
5 root 1.75 # pragma warning(disable:4244)
6 root 1.48 #endif
7    
8 root 1.1 #include "EXTERN.h"
9     #include "perl.h"
10     #include "XSUB.h"
11    
12 root 1.80 #include <math.h>
13 root 1.5 #include <string.h>
14 root 1.25 #include <stdio.h>
15 root 1.111 #include <stdlib.h>
16 root 1.5
17 root 1.2 #include <SDL.h>
18 root 1.76 #include <SDL_endian.h>
19 root 1.23 #include <SDL_image.h>
20 root 1.52 #include <SDL_mixer.h>
21 root 1.3 #include <SDL_opengl.h>
22 root 1.5
23 root 1.124 #define PANGO_ENABLE_BACKEND
24     #define G_DISABLE_CAST_CHECKS
25    
26 root 1.30 #include <glib/gmacros.h>
27    
28 root 1.5 #include <pango/pango.h>
29    
30 root 1.48 #ifndef _WIN32
31     # include <sys/types.h>
32     # include <sys/socket.h>
33     # include <netinet/in.h>
34     # include <netinet/tcp.h>
35     # include <inttypes.h>
36     #else
37     typedef unsigned char uint8_t;
38     typedef unsigned short uint16_t;
39     typedef unsigned int uint32_t;
40     typedef signed char int8_t;
41     typedef signed short int16_t;
42     typedef signed int int32_t;
43     #endif
44 root 1.28
45 root 1.57 #include "glext.h"
46    
47 root 1.121 #define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, objetc replacement character */
48    
49 root 1.29 #define FOW_DARKNESS 32
50    
51     #define MAP_EXTEND_X 32
52     #define MAP_EXTEND_Y 512
53    
54 root 1.63 #define MIN_FONT_HEIGHT 10
55 root 1.58
56 root 1.124 #if 1
57     # define PARACHUTE SDL_INIT_NOPARACHUTE
58     #else
59     # define PARACHUTE 0
60     #endif
61    
62 root 1.103 static struct
63     {
64     #define GL_FUNC(ptr,name) ptr name;
65     #include "glfunc.h"
66     #undef GL_FUNC
67     } gl;
68    
69     static void gl_BlendFuncSeparate (GLenum sa, GLenum da, GLenum saa, GLenum daa)
70     {
71     if (gl.BlendFuncSeparate)
72     gl.BlendFuncSeparate (sa, da, saa, daa);
73     else if (gl.BlendFuncSeparateEXT)
74     gl.BlendFuncSeparateEXT (sa, da, saa, daa);
75     else
76     glBlendFunc (sa, da);
77     }
78 root 1.64
79 root 1.124 #include "texcache.c"
80    
81     #include "pango-font.c"
82     #include "pango-fontmap.c"
83     #include "pango-render.c"
84    
85 root 1.52 typedef Mix_Chunk *CFClient__MixChunk;
86     typedef Mix_Music *CFClient__MixMusic;
87    
88 root 1.61 typedef PangoFontDescription *CFClient__Font;
89 root 1.2
90 root 1.121 static int
91     shape_attr_p (PangoLayoutRun *run)
92     {
93     GSList *attrs = run->item->analysis.extra_attrs;
94    
95     while (attrs)
96     {
97     PangoAttribute *attr = attrs->data;
98    
99     if (attr->klass->type == PANGO_ATTR_SHAPE)
100     return 1;
101    
102     attrs = attrs->next;
103     }
104    
105     return 0;
106     }
107    
108 root 1.14 typedef struct cf_layout {
109 root 1.124 PangoLayout *pl;
110 root 1.76 float r, g, b, a; // default color for rgba mode
111 root 1.14 int base_height;
112 root 1.61 CFClient__Font font;
113 root 1.15 } *CFClient__Layout;
114 root 1.14
115 root 1.61 static CFClient__Font default_font;
116 root 1.124 static PangoContext *opengl_context;
117     static PangoFontMap *opengl_fontmap;
118 root 1.61
119 root 1.14 static void
120 root 1.19 substitute_func (FcPattern *pattern, gpointer data)
121     {
122 root 1.108 FcPatternAddBool (pattern, FC_HINTING, 1);
123 root 1.110 #ifdef FC_HINT_STYLE
124 root 1.109 FcPatternAddBool (pattern, FC_HINT_STYLE, FC_HINT_FULL);
125 root 1.110 #endif
126 root 1.82 FcPatternAddBool (pattern, FC_AUTOHINT, 0);
127 root 1.19 }
128    
129     static void
130 root 1.61 layout_update_font (CFClient__Layout self)
131 root 1.17 {
132 root 1.19 /* use a random scale factor to account for unknown descenders, 0.8 works
133     * reasonably well with bitstream vera
134     */
135 root 1.61 PangoFontDescription *font = self->font ? self->font : default_font;
136 root 1.46
137 root 1.61 pango_font_description_set_absolute_size (font,
138     MAX (MIN_FONT_HEIGHT, self->base_height) * (PANGO_SCALE * 8 / 10));
139 root 1.58
140 root 1.61 pango_layout_set_font_description (self->pl, font);
141 root 1.17 }
142    
143     static void
144 root 1.15 layout_get_pixel_size (CFClient__Layout self, int *w, int *h)
145 root 1.14 {
146     pango_layout_get_pixel_size (self->pl, w, h);
147    
148     if (!*w) *w = 1;
149     if (!*h) *h = 1;
150 root 1.76
151     *w = (*w + 3) & ~3;
152 root 1.14 }
153    
154 root 1.42 typedef uint16_t mapface;
155    
156 root 1.28 typedef struct {
157 root 1.30 GLint name;
158     int w, h;
159     float s, t;
160 root 1.39 uint8_t r, g, b, a;
161 root 1.42 } maptex;
162 root 1.30
163     typedef struct {
164 root 1.29 int16_t darkness;
165 root 1.42 mapface face[3];
166 root 1.28 } mapcell;
167    
168     typedef struct {
169 root 1.30 int32_t c0, c1;
170 root 1.28 mapcell *col;
171     } maprow;
172    
173     typedef struct map {
174     int x, y, w, h;
175 root 1.42 int ox, oy; /* offset to virtual global coordinate system */
176 root 1.28 int faces;
177 root 1.30 mapface *face;
178 root 1.28
179 root 1.42 int texs;
180     maptex *tex;
181    
182 root 1.48 int32_t rows;
183 root 1.28 maprow *row;
184     } *CFClient__Map;
185    
186 root 1.30 static char *
187     prepend (char *ptr, int sze, int inc)
188     {
189     char *p;
190    
191     New (0, p, sze + inc, char);
192     Zero (p, inc, char);
193     Move (ptr, p + inc, sze, char);
194     Safefree (ptr);
195    
196     return p;
197     }
198    
199     static char *
200     append (char *ptr, int sze, int inc)
201     {
202     Renew (ptr, sze + inc, char);
203     Zero (ptr + sze, inc, char);
204    
205     return ptr;
206     }
207    
208     #define Append(type,ptr,sze,inc) (ptr) = (type *)append ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type))
209     #define Prepend(type,ptr,sze,inc) (ptr) = (type *)prepend ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type))
210    
211 root 1.42 static maprow *
212     map_get_row (CFClient__Map self, int y)
213     {
214     if (0 > y)
215     {
216     int extend = - y + MAP_EXTEND_Y;
217     Prepend (maprow, self->row, self->rows, extend);
218    
219     self->rows += extend;
220     self->y += extend;
221     y += extend;
222     }
223     else if (y >= self->rows)
224     {
225     int extend = y - self->rows + MAP_EXTEND_Y;
226     Append (maprow, self->row, self->rows, extend);
227     self->rows += extend;
228     }
229    
230     return self->row + y;
231     }
232    
233     static mapcell *
234     row_get_cell (maprow *row, int x)
235     {
236     if (!row->col)
237     {
238     Newz (0, row->col, MAP_EXTEND_X, mapcell);
239     row->c0 = x - MAP_EXTEND_X / 4;
240     row->c1 = row->c0 + MAP_EXTEND_X;
241     }
242    
243     if (row->c0 > x)
244     {
245     int extend = row->c0 - x + MAP_EXTEND_X;
246     Prepend (mapcell, row->col, row->c1 - row->c0, extend);
247     row->c0 -= extend;
248     }
249     else if (x >= row->c1)
250     {
251     int extend = x - row->c1 + MAP_EXTEND_X;
252     Append (mapcell, row->col, row->c1 - row->c0, extend);
253     row->c1 += extend;
254     }
255    
256     return row->col + (x - row->c0);
257     }
258    
259     static mapcell *
260     map_get_cell (CFClient__Map self, int x, int y)
261     {
262     return row_get_cell (map_get_row (self, y), x);
263     }
264    
265 root 1.30 static void
266     map_clear (CFClient__Map self)
267     {
268     int r;
269    
270     for (r = 0; r < self->rows; r++)
271     Safefree (self->row[r].col);
272    
273     Safefree (self->row);
274    
275     self->x = 0;
276     self->y = 0;
277 root 1.42 self->ox = 0;
278     self->oy = 0;
279 root 1.30 self->row = 0;
280     self->rows = 0;
281     }
282    
283 root 1.29 static void
284     map_blank (CFClient__Map self, int x0, int y0, int w, int h)
285     {
286     int x, y;
287 root 1.48 maprow *row;
288 root 1.29
289     for (y = y0; y < y0 + h; y++)
290 root 1.30 if (y >= 0)
291     {
292     if (y >= self->rows)
293     break;
294    
295 root 1.48 row = self->row + y;
296 root 1.30
297     for (x = x0; x < x0 + w; x++)
298     if (x >= row->c0)
299     {
300     if (x >= row->c1)
301     break;
302 root 1.29
303 root 1.31 row->col[x - row->c0].darkness = -1;
304 root 1.30 }
305     }
306 root 1.29 }
307    
308 root 1.56 static void
309 root 1.75 music_finished (void)
310 root 1.56 {
311     SDL_UserEvent ev;
312    
313     ev.type = SDL_USEREVENT;
314     ev.code = 0;
315     ev.data1 = 0;
316     ev.data2 = 0;
317    
318 root 1.57 SDL_PushEvent ((SDL_Event *)&ev);
319 root 1.56 }
320    
321 root 1.71 static void
322     channel_finished (int channel)
323     {
324     SDL_UserEvent ev;
325    
326     ev.type = SDL_USEREVENT;
327     ev.code = 1;
328 root 1.74 ev.data1 = (void *)(long)channel;
329 root 1.71 ev.data2 = 0;
330    
331     SDL_PushEvent ((SDL_Event *)&ev);
332     }
333    
334 root 1.113 static unsigned int
335     minpot (unsigned int n)
336     {
337     if (!n)
338     return 0;
339    
340     --n;
341    
342     n |= n >> 1;
343     n |= n >> 2;
344     n |= n >> 4;
345     n |= n >> 8;
346     n |= n >> 16;
347    
348     return n + 1;
349     }
350    
351 root 1.15 MODULE = CFClient PACKAGE = CFClient
352 root 1.1
353 root 1.11 PROTOTYPES: ENABLE
354    
355 root 1.5 BOOT:
356     {
357 root 1.51 HV *stash = gv_stashpv ("CFClient", 1);
358     static const struct {
359     const char *name;
360     IV iv;
361     } *civ, const_iv[] = {
362     # define const_iv(name) { # name, (IV)name }
363     const_iv (SDL_ACTIVEEVENT),
364     const_iv (SDL_KEYDOWN),
365     const_iv (SDL_KEYUP),
366     const_iv (SDL_MOUSEMOTION),
367     const_iv (SDL_MOUSEBUTTONDOWN),
368     const_iv (SDL_MOUSEBUTTONUP),
369     const_iv (SDL_JOYAXISMOTION),
370     const_iv (SDL_JOYBALLMOTION),
371     const_iv (SDL_JOYHATMOTION),
372     const_iv (SDL_JOYBUTTONDOWN),
373     const_iv (SDL_JOYBUTTONUP),
374     const_iv (SDL_QUIT),
375     const_iv (SDL_SYSWMEVENT),
376     const_iv (SDL_EVENT_RESERVEDA),
377     const_iv (SDL_EVENT_RESERVEDB),
378     const_iv (SDL_VIDEORESIZE),
379     const_iv (SDL_VIDEOEXPOSE),
380     const_iv (SDL_USEREVENT),
381     const_iv (SDLK_KP0),
382     const_iv (SDLK_KP1),
383     const_iv (SDLK_KP2),
384     const_iv (SDLK_KP3),
385     const_iv (SDLK_KP4),
386     const_iv (SDLK_KP5),
387     const_iv (SDLK_KP6),
388     const_iv (SDLK_KP7),
389     const_iv (SDLK_KP8),
390     const_iv (SDLK_KP9),
391     const_iv (SDLK_KP_PERIOD),
392     const_iv (SDLK_KP_DIVIDE),
393     const_iv (SDLK_KP_MULTIPLY),
394     const_iv (SDLK_KP_MINUS),
395     const_iv (SDLK_KP_PLUS),
396     const_iv (SDLK_KP_ENTER),
397     const_iv (SDLK_KP_EQUALS),
398     const_iv (SDLK_UP),
399     const_iv (SDLK_DOWN),
400     const_iv (SDLK_RIGHT),
401     const_iv (SDLK_LEFT),
402     const_iv (SDLK_INSERT),
403     const_iv (SDLK_HOME),
404     const_iv (SDLK_END),
405     const_iv (SDLK_PAGEUP),
406     const_iv (SDLK_PAGEDOWN),
407     const_iv (SDLK_F1),
408     const_iv (SDLK_F2),
409     const_iv (SDLK_F3),
410     const_iv (SDLK_F4),
411     const_iv (SDLK_F5),
412     const_iv (SDLK_F6),
413     const_iv (SDLK_F7),
414     const_iv (SDLK_F8),
415     const_iv (SDLK_F9),
416     const_iv (SDLK_F10),
417     const_iv (SDLK_F11),
418     const_iv (SDLK_F12),
419     const_iv (SDLK_F13),
420     const_iv (SDLK_F14),
421     const_iv (SDLK_F15),
422     const_iv (SDLK_NUMLOCK),
423     const_iv (SDLK_CAPSLOCK),
424     const_iv (SDLK_SCROLLOCK),
425     const_iv (SDLK_RSHIFT),
426     const_iv (SDLK_LSHIFT),
427     const_iv (SDLK_RCTRL),
428     const_iv (SDLK_LCTRL),
429     const_iv (SDLK_RALT),
430     const_iv (SDLK_LALT),
431     const_iv (SDLK_RMETA),
432     const_iv (SDLK_LMETA),
433     const_iv (SDLK_LSUPER),
434     const_iv (SDLK_RSUPER),
435     const_iv (SDLK_MODE),
436     const_iv (SDLK_COMPOSE),
437     const_iv (SDLK_HELP),
438     const_iv (SDLK_PRINT),
439     const_iv (SDLK_SYSREQ),
440     const_iv (SDLK_BREAK),
441     const_iv (SDLK_MENU),
442     const_iv (SDLK_POWER),
443     const_iv (SDLK_EURO),
444     const_iv (SDLK_UNDO),
445     const_iv (KMOD_NONE),
446     const_iv (KMOD_LSHIFT),
447     const_iv (KMOD_RSHIFT),
448     const_iv (KMOD_LCTRL),
449     const_iv (KMOD_RCTRL),
450     const_iv (KMOD_LALT),
451     const_iv (KMOD_RALT),
452     const_iv (KMOD_LMETA),
453     const_iv (KMOD_RMETA),
454     const_iv (KMOD_NUM),
455     const_iv (KMOD_CAPS),
456     const_iv (KMOD_MODE),
457     const_iv (KMOD_CTRL),
458     const_iv (KMOD_SHIFT),
459     const_iv (KMOD_ALT),
460     const_iv (KMOD_META)
461     # undef const_iv
462     };
463    
464     for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
465     newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
466 root 1.79 }
467 root 1.51
468 root 1.116 NV floor (NV x)
469    
470     NV ceil (NV x)
471    
472 root 1.79 void
473     pango_init ()
474     CODE:
475     {
476 root 1.124 opengl_fontmap = pango_opengl_font_map_new ();
477     pango_opengl_font_map_set_default_substitute ((PangoOpenGLFontMap *)opengl_fontmap, substitute_func, 0, 0);
478     opengl_context = pango_opengl_font_map_create_context ((PangoOpenGLFontMap *)opengl_fontmap);
479 root 1.5 }
480    
481 root 1.51 int
482 root 1.124 SDL_Init (U32 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | PARACHUTE)
483 root 1.51
484     void
485     SDL_Quit ()
486    
487     void
488     SDL_ListModes ()
489     PPCODE:
490     {
491     SDL_Rect **m;
492    
493     SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 5);
494     SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 5);
495     SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5);
496 root 1.88 SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, 1);
497 root 1.51
498 root 1.88 SDL_GL_SetAttribute (SDL_GL_BUFFER_SIZE, 15);
499 root 1.115 SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 0);
500 root 1.85
501 root 1.51 SDL_GL_SetAttribute (SDL_GL_ACCUM_RED_SIZE, 0);
502     SDL_GL_SetAttribute (SDL_GL_ACCUM_GREEN_SIZE, 0);
503     SDL_GL_SetAttribute (SDL_GL_ACCUM_BLUE_SIZE, 0);
504     SDL_GL_SetAttribute (SDL_GL_ACCUM_ALPHA_SIZE, 0);
505    
506     SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
507    
508 root 1.53 SDL_EnableUNICODE (1);
509     SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
510    
511 root 1.51 m = SDL_ListModes (0, SDL_FULLSCREEN | SDL_OPENGL);
512    
513     if (m && m != (SDL_Rect **)-1)
514     while (*m)
515     {
516     AV *av = newAV ();
517     av_push (av, newSViv ((*m)->w));
518     av_push (av, newSViv ((*m)->h));
519     XPUSHs (sv_2mortal (newRV_noinc ((SV *)av)));
520    
521     ++m;
522     }
523     }
524    
525 root 1.88 char *
526     SDL_GetError ()
527    
528 root 1.51 int
529     SDL_SetVideoMode (int w, int h, int fullscreen)
530     CODE:
531     RETVAL = !!SDL_SetVideoMode (
532     w, h, 0, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0)
533     );
534 root 1.103 if (RETVAL)
535     {
536     SDL_WM_SetCaption ("Crossfire+ Client " VERSION, "Crossfire+");
537     # define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name);
538     # include "glfunc.h"
539     # undef GL_FUNC
540     }
541 root 1.51 OUTPUT:
542     RETVAL
543    
544 root 1.53 void
545 root 1.54 SDL_GL_SwapBuffers ()
546    
547 root 1.94 char *
548     SDL_GetKeyName (int sym)
549    
550 root 1.54 void
551 root 1.53 SDL_PollEvent ()
552     PPCODE:
553     {
554     SDL_Event ev;
555    
556     while (SDL_PollEvent (&ev))
557     {
558     HV *hv = newHV ();
559     hv_store (hv, "type", 4, newSViv (ev.type), 0);
560 root 1.70
561 root 1.53 switch (ev.type)
562     {
563     case SDL_KEYDOWN:
564     case SDL_KEYUP:
565     hv_store (hv, "state", 5, newSViv (ev.key.state), 0);
566     hv_store (hv, "sym", 3, newSViv (ev.key.keysym.sym), 0);
567     hv_store (hv, "mod", 3, newSViv (ev.key.keysym.mod), 0);
568     hv_store (hv, "unicode", 7, newSViv (ev.key.keysym.unicode), 0);
569     break;
570    
571     case SDL_ACTIVEEVENT:
572     hv_store (hv, "gain", 4, newSViv (ev.active.gain), 0);
573     hv_store (hv, "state", 5, newSViv (ev.active.state), 0);
574     break;
575    
576     case SDL_MOUSEMOTION:
577 root 1.94 hv_store (hv, "mod", 3, newSViv (SDL_GetModState ()), 0);
578 root 1.93
579 root 1.53 hv_store (hv, "state", 5, newSViv (ev.motion.state), 0);
580     hv_store (hv, "x", 1, newSViv (ev.motion.x), 0);
581     hv_store (hv, "y", 1, newSViv (ev.motion.y), 0);
582     hv_store (hv, "xrel", 4, newSViv (ev.motion.xrel), 0);
583     hv_store (hv, "yrel", 4, newSViv (ev.motion.yrel), 0);
584     break;
585    
586     case SDL_MOUSEBUTTONDOWN:
587     case SDL_MOUSEBUTTONUP:
588 root 1.94 hv_store (hv, "mod", 3, newSViv (SDL_GetModState ()), 0);
589 root 1.93
590 root 1.53 hv_store (hv, "button", 6, newSViv (ev.button.button), 0);
591     hv_store (hv, "state", 5, newSViv (ev.button.state), 0);
592     hv_store (hv, "x", 1, newSViv (ev.button.x), 0);
593     hv_store (hv, "y", 1, newSViv (ev.button.y), 0);
594 root 1.70 break;
595 root 1.72
596     case SDL_USEREVENT:
597     hv_store (hv, "code", 4, newSViv (ev.user.code), 0);
598     hv_store (hv, "data1", 5, newSViv ((IV)ev.user.data1), 0);
599     hv_store (hv, "data2", 5, newSViv ((IV)ev.user.data2), 0);
600     break;
601 root 1.53 }
602    
603     XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv)));
604     }
605     }
606 root 1.52
607     int
608 root 1.73 Mix_OpenAudio (int frequency = 48000, int format = MIX_DEFAULT_FORMAT, int channels = 1, int chunksize = 2048)
609 root 1.56 POSTCALL:
610     Mix_HookMusicFinished (music_finished);
611 root 1.71 Mix_ChannelFinished (channel_finished);
612 root 1.52
613     void
614     Mix_CloseAudio ()
615    
616     int
617     Mix_AllocateChannels (int numchans = -1)
618    
619 root 1.10 void
620     lowdelay (int fd, int val = 1)
621     CODE:
622 root 1.48 #ifndef _WIN32
623 root 1.10 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof (val));
624 root 1.48 #endif
625 root 1.10
626 root 1.5 void
627 root 1.13 add_font (char *file)
628     CODE:
629     FcConfigAppFontAddFile (0, (const FcChar8 *)file); /* no idea wether this is required */
630    
631     void
632 root 1.23 load_image_inline (SV *image_)
633     ALIAS:
634     load_image_file = 1
635     PPCODE:
636     {
637     STRLEN image_len;
638     char *image = (char *)SvPVbyte (image_, image_len);
639     SDL_Surface *surface, *surface2;
640     SDL_PixelFormat fmt;
641     SDL_RWops *rw = ix
642     ? SDL_RWFromFile (image, "r")
643     : SDL_RWFromConstMem (image, image_len);
644    
645     if (!rw)
646 root 1.41 croak ("load_image: %s", SDL_GetError ());
647 root 1.23
648     surface = IMG_Load_RW (rw, 1);
649     if (!surface)
650 root 1.41 croak ("load_image: %s", SDL_GetError ());
651 root 1.23
652     fmt.palette = NULL;
653     fmt.BitsPerPixel = 32;
654     fmt.BytesPerPixel = 4;
655 root 1.49 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
656 root 1.23 fmt.Rmask = 0x000000ff;
657     fmt.Gmask = 0x0000ff00;
658     fmt.Bmask = 0x00ff0000;
659     fmt.Amask = 0xff000000;
660 root 1.49 #else
661     fmt.Rmask = 0xff000000;
662     fmt.Gmask = 0x00ff0000;
663     fmt.Bmask = 0x0000ff00;
664     fmt.Amask = 0x000000ff;
665     #endif
666 root 1.23 fmt.Rloss = 0;
667     fmt.Gloss = 0;
668     fmt.Bloss = 0;
669     fmt.Aloss = 0;
670     fmt.Rshift = 0;
671     fmt.Gshift = 8;
672     fmt.Bshift = 16;
673     fmt.Ashift = 24;
674     fmt.colorkey = 0;
675     fmt.alpha = 0;
676    
677     surface2 = SDL_ConvertSurface (surface, &fmt, SDL_SWSURFACE);
678    
679 root 1.39 assert (surface2->pitch == surface2->w * 4);
680    
681 root 1.23 EXTEND (SP, 5);
682     PUSHs (sv_2mortal (newSViv (surface2->w)));
683     PUSHs (sv_2mortal (newSViv (surface2->h)));
684     SDL_LockSurface (surface2);
685     PUSHs (sv_2mortal (newSVpvn (surface2->pixels, surface2->h * surface2->pitch)));
686     SDL_UnlockSurface (surface2);
687 root 1.116 PUSHs (sv_2mortal (newSViv (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA) ? GL_RGBA : GL_RGB)));
688 root 1.23 PUSHs (sv_2mortal (newSViv (GL_RGBA)));
689 root 1.49 PUSHs (sv_2mortal (newSViv (GL_UNSIGNED_BYTE)));
690 root 1.23
691     SDL_FreeSurface (surface);
692     SDL_FreeSurface (surface2);
693     }
694    
695 root 1.25 void
696 root 1.39 average (int x, int y, uint32_t *data)
697     PPCODE:
698     {
699     uint32_t r = 0, g = 0, b = 0, a = 0;
700    
701     x = y = x * y;
702    
703     while (x--)
704     {
705     uint32_t p = *data++;
706    
707     r += (p ) & 255;
708     g += (p >> 8) & 255;
709     b += (p >> 16) & 255;
710     a += (p >> 24) & 255;
711     }
712    
713     EXTEND (SP, 4);
714 root 1.40 PUSHs (sv_2mortal (newSViv (r / y)));
715     PUSHs (sv_2mortal (newSViv (g / y)));
716     PUSHs (sv_2mortal (newSViv (b / y)));
717     PUSHs (sv_2mortal (newSViv (a / y)));
718 root 1.39 }
719    
720     void
721 root 1.66 error (char *message)
722     CODE:
723 root 1.86 fprintf (stderr, "ERROR: %s\n", message);
724 root 1.66 #ifdef _WIN32
725 root 1.86 MessageBox (0, message, "Crossfire+ Error", MB_OK | MB_ICONERROR);
726 root 1.66 #endif
727    
728     void
729 root 1.25 fatal (char *message)
730     CODE:
731 root 1.86 fprintf (stderr, "FATAL: %s\n", message);
732 root 1.50 #ifdef _WIN32
733 root 1.86 MessageBox (0, message, "Crossfire+ Fatal Error", MB_OK | MB_ICONERROR);
734 root 1.25 #endif
735 root 1.112 _exit (1);
736 root 1.111
737     void
738     _exit (int retval)
739     CODE:
740 root 1.112 _exit (retval);
741 root 1.25
742 root 1.61 MODULE = CFClient PACKAGE = CFClient::Font
743    
744     CFClient::Font
745 root 1.70 new_from_file (SV *class, char *path, int id = 0)
746 root 1.61 CODE:
747     {
748     int count;
749 root 1.70 FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)path, id, 0, &count);
750 root 1.61 RETVAL = pango_fc_font_description_from_pattern (pattern, 0);
751     FcPatternDestroy (pattern);
752     }
753     OUTPUT:
754     RETVAL
755    
756     void
757     DESTROY (CFClient::Font self)
758     CODE:
759     pango_font_description_free (self);
760    
761     void
762     make_default (CFClient::Font self)
763     CODE:
764     default_font = self;
765    
766 root 1.15 MODULE = CFClient PACKAGE = CFClient::Layout
767 root 1.14
768 root 1.124 void
769     clear_font_cache ()
770     CODE:
771     pango_fc_font_map_cache_clear ((PangoFcFontMap *)opengl_fontmap);
772     tc_clear ();
773    
774 root 1.15 CFClient::Layout
775 root 1.124 new (SV *class, int type = 0)
776 root 1.14 CODE:
777     New (0, RETVAL, 1, struct cf_layout);
778 root 1.76
779 root 1.124 RETVAL->pl = pango_layout_new (opengl_context);
780 root 1.76 RETVAL->r = 1.;
781     RETVAL->g = 1.;
782     RETVAL->b = 1.;
783     RETVAL->a = 1.;
784     RETVAL->base_height = MIN_FONT_HEIGHT;
785     RETVAL->font = 0;
786    
787 root 1.14 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
788 root 1.76 layout_update_font (RETVAL);
789 root 1.14 OUTPUT:
790     RETVAL
791    
792     void
793 root 1.15 DESTROY (CFClient::Layout self)
794 root 1.14 CODE:
795     g_object_unref (self->pl);
796     Safefree (self);
797 root 1.13
798 root 1.8 void
799 root 1.35 set_text (CFClient::Layout self, SV *text_)
800     CODE:
801     {
802     STRLEN textlen;
803     char *text = SvPVutf8 (text_, textlen);
804    
805     pango_layout_set_text (self->pl, text, textlen);
806     }
807    
808     void
809 root 1.15 set_markup (CFClient::Layout self, SV *text_)
810 root 1.14 CODE:
811 root 1.5 {
812     STRLEN textlen;
813     char *text = SvPVutf8 (text_, textlen);
814 root 1.14
815     pango_layout_set_markup (self->pl, text, textlen);
816     }
817    
818 root 1.121 void
819     set_shapes (CFClient::Layout self, ...)
820     CODE:
821     {
822     PangoAttrList *attrs = 0;
823     const char *text = pango_layout_get_text (self->pl);
824     const char *pos = text;
825 root 1.122 int arg = 4;
826 root 1.121
827     while (arg < items && (pos = strstr (pos, OBJ_STR)))
828     {
829 root 1.122 PangoRectangle inkrect, rect;
830 root 1.121 PangoAttribute *attr;
831    
832 root 1.122 int x = SvIV (ST (arg - 3));
833     int y = SvIV (ST (arg - 2));
834 root 1.121 int w = SvIV (ST (arg - 1));
835 root 1.122 int h = SvIV (ST (arg ));
836 root 1.121
837 root 1.122 inkrect.x = 0;
838     inkrect.y = 0;
839     inkrect.width = 0;
840     inkrect.height = 0;
841    
842     rect.x = x * PANGO_SCALE;
843     rect.y = y * PANGO_SCALE;
844     rect.width = w * PANGO_SCALE;
845 root 1.121 rect.height = h * PANGO_SCALE;
846    
847     if (!attrs)
848     attrs = pango_layout_get_attributes (self->pl);
849    
850 root 1.122 attr = pango_attr_shape_new (&inkrect, &rect);
851 root 1.121 attr->start_index = pos - text;
852     attr->end_index = attr->start_index + sizeof (OBJ_STR) - 1;
853     pango_attr_list_insert (attrs, attr);
854    
855 root 1.122 arg += 4;
856 root 1.121 pos += sizeof (OBJ_STR) - 1;
857     }
858    
859     if (attrs)
860     pango_layout_set_attributes (self->pl, attrs);
861     }
862    
863     void
864     get_shapes (CFClient::Layout self)
865     PPCODE:
866     {
867     PangoLayoutIter *iter = pango_layout_get_iter (self->pl);
868    
869     do
870     {
871     PangoLayoutRun *run = pango_layout_iter_get_run (iter);
872    
873     if (run && shape_attr_p (run))
874     {
875     PangoRectangle extents;
876     pango_layout_iter_get_run_extents (iter, 0, &extents);
877    
878     PUSHs (sv_2mortal (newSViv (PANGO_PIXELS (extents.x))));
879     PUSHs (sv_2mortal (newSViv (PANGO_PIXELS (extents.y))));
880     }
881     }
882     while (pango_layout_iter_next_run (iter));
883    
884     pango_layout_iter_free (iter);
885     }
886    
887     int
888     has_wrapped (CFClient::Layout self)
889     CODE:
890     {
891     int lines = 1;
892     const char *text = pango_layout_get_text (self->pl);
893    
894     while (*text)
895     lines += *text++ == '\n';
896    
897     RETVAL = lines < pango_layout_get_line_count (self->pl);
898     }
899     OUTPUT:
900     RETVAL
901    
902 root 1.46 SV *
903     get_text (CFClient::Layout self)
904     CODE:
905 root 1.47 RETVAL = newSVpv (pango_layout_get_text (self->pl), 0);
906 root 1.107 sv_utf8_decode (RETVAL);
907 root 1.46 OUTPUT:
908     RETVAL
909    
910 root 1.14 void
911 root 1.76 set_foreground (CFClient::Layout self, float r, float g, float b, float a = 1.)
912     CODE:
913     self->r = r;
914     self->g = g;
915     self->b = b;
916     self->a = a;
917    
918     void
919 root 1.61 set_font (CFClient::Layout self, CFClient::Font font = 0)
920     CODE:
921     if (self->font != font)
922     {
923     self->font = font;
924     layout_update_font (self);
925     }
926    
927     void
928 root 1.16 set_height (CFClient::Layout self, int base_height)
929     CODE:
930 root 1.61 if (self->base_height != base_height)
931     {
932     self->base_height = base_height;
933     layout_update_font (self);
934     }
935 root 1.16
936     void
937 root 1.15 set_width (CFClient::Layout self, int max_width = -1)
938 root 1.14 CODE:
939     pango_layout_set_width (self->pl, max_width < 0 ? max_width : max_width * PANGO_SCALE);
940    
941     void
942 root 1.84 set_indent (CFClient::Layout self, int indent)
943     CODE:
944     pango_layout_set_indent (self->pl, indent * PANGO_SCALE);
945    
946     void
947     set_spacing (CFClient::Layout self, int spacing)
948     CODE:
949     pango_layout_set_spacing (self->pl, spacing * PANGO_SCALE);
950    
951     void
952     set_ellipsise (CFClient::Layout self, int ellipsise)
953     CODE:
954     pango_layout_set_ellipsize (self->pl,
955     ellipsise == 1 ? PANGO_ELLIPSIZE_START
956     : ellipsise == 2 ? PANGO_ELLIPSIZE_MIDDLE
957     : ellipsise == 3 ? PANGO_ELLIPSIZE_END
958     : PANGO_ELLIPSIZE_NONE
959     );
960    
961     void
962     set_single_paragraph_mode (CFClient::Layout self, int spm)
963     CODE:
964     pango_layout_set_single_paragraph_mode (self->pl, !!spm);
965    
966     void
967 root 1.15 size (CFClient::Layout self)
968 root 1.14 PPCODE:
969     {
970     int w, h;
971    
972     layout_get_pixel_size (self, &w, &h);
973    
974     EXTEND (SP, 2);
975     PUSHs (sv_2mortal (newSViv (w)));
976     PUSHs (sv_2mortal (newSViv (h)));
977     }
978    
979 root 1.17 int
980 root 1.122 descent (CFClient::Layout self)
981     CODE:
982     {
983     PangoRectangle rect;
984     PangoLayoutLine *line = pango_layout_get_line (self->pl, 0);
985     pango_layout_line_get_pixel_extents (line, 0, &rect);
986     RETVAL = PANGO_DESCENT (rect);
987     }
988     OUTPUT:
989     RETVAL
990    
991     int
992 root 1.17 xy_to_index (CFClient::Layout self, int x, int y)
993     CODE:
994     {
995     int index, trailing;
996     pango_layout_xy_to_index (self->pl, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing);
997     RETVAL = index;
998     }
999     OUTPUT:
1000     RETVAL
1001    
1002     void
1003     cursor_pos (CFClient::Layout self, int index)
1004     PPCODE:
1005     {
1006     PangoRectangle strong_pos;
1007     pango_layout_get_cursor_pos (self->pl, index, &strong_pos, 0);
1008 root 1.30
1009 root 1.17 EXTEND (SP, 3);
1010     PUSHs (sv_2mortal (newSViv (strong_pos.x / PANGO_SCALE)));
1011     PUSHs (sv_2mortal (newSViv (strong_pos.y / PANGO_SCALE)));
1012     PUSHs (sv_2mortal (newSViv (strong_pos.height / PANGO_SCALE)));
1013     }
1014    
1015 root 1.14 void
1016 root 1.124 render (CFClient::Layout self, float x, float y)
1017 root 1.14 PPCODE:
1018 root 1.124 pango_opengl_render_layout_subpixel (
1019     self->pl,
1020     x * PANGO_SCALE, y * PANGO_SCALE,
1021     self->r, self->g, self->b, self->a
1022     );
1023 root 1.11
1024 root 1.15 MODULE = CFClient PACKAGE = CFClient::Texture
1025 root 1.11
1026     void
1027 root 1.113 pad2pot (SV *data_, SV *w_, SV *h_)
1028     CODE:
1029     {
1030     int ow = SvIV (w_);
1031     int oh = SvIV (h_);
1032    
1033     if (ow && oh)
1034     {
1035     int nw = minpot (ow);
1036     int nh = minpot (oh);
1037    
1038     if (nw != ow || nh != oh)
1039     {
1040     if (SvOK (data_))
1041     {
1042     STRLEN datalen;
1043     char *data = SvPVbyte (data_, datalen);
1044     int bpp = datalen / (ow * oh);
1045     SV *result_ = sv_2mortal (newSV (nw * nh * bpp));
1046    
1047     SvPOK_only (result_);
1048     SvCUR_set (result_, nw * nh * bpp);
1049    
1050     memset (SvPVX (result_), 0, nw * nh * bpp);
1051     while (oh--)
1052     memcpy (SvPVX (result_) + oh * nw * bpp, data + oh * ow * bpp, ow * bpp);
1053    
1054     sv_setsv (data_, result_);
1055     }
1056    
1057     sv_setiv (w_, nw);
1058     sv_setiv (h_, nh);
1059     }
1060     }
1061     }
1062    
1063     void
1064 root 1.114 draw_quad (SV *self, float x, float y, float w = 0., float h = 0.)
1065 root 1.12 PROTOTYPE: $$$;$$
1066 root 1.76 ALIAS:
1067     draw_quad_alpha = 1
1068     draw_quad_alpha_premultiplied = 2
1069 root 1.11 CODE:
1070     {
1071 root 1.12 HV *hv = (HV *)SvRV (self);
1072 root 1.37 float s = SvNV (*hv_fetch (hv, "s", 1, 1));
1073     float t = SvNV (*hv_fetch (hv, "t", 1, 1));
1074 root 1.12 int name = SvIV (*hv_fetch (hv, "name", 4, 1));
1075    
1076     if (items < 5)
1077     {
1078 root 1.18 w = SvNV (*hv_fetch (hv, "w", 1, 1));
1079     h = SvNV (*hv_fetch (hv, "h", 1, 1));
1080 root 1.12 }
1081    
1082 root 1.76 if (ix)
1083     {
1084     glEnable (GL_BLEND);
1085 root 1.103
1086     if (ix == 2)
1087     glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1088     else
1089     gl_BlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
1090 root 1.104 GL_ONE , GL_ONE_MINUS_SRC_ALPHA);
1091 root 1.103
1092 root 1.86 glEnable (GL_ALPHA_TEST);
1093     glAlphaFunc (GL_GREATER, 0.01f);
1094 root 1.76 }
1095    
1096 root 1.12 glBindTexture (GL_TEXTURE_2D, name);
1097 root 1.76
1098 root 1.12 glBegin (GL_QUADS);
1099 root 1.37 glTexCoord2f (0, 0); glVertex2f (x , y );
1100     glTexCoord2f (0, t); glVertex2f (x , y + h);
1101     glTexCoord2f (s, t); glVertex2f (x + w, y + h);
1102     glTexCoord2f (s, 0); glVertex2f (x + w, y );
1103 root 1.12 glEnd ();
1104 root 1.76
1105     if (ix)
1106 root 1.86 {
1107     glDisable (GL_ALPHA_TEST);
1108     glDisable (GL_BLEND);
1109     }
1110 root 1.11 }
1111 root 1.28
1112     MODULE = CFClient PACKAGE = CFClient::Map
1113    
1114     CFClient::Map
1115     new (SV *class, int map_width, int map_height)
1116     CODE:
1117     New (0, RETVAL, 1, struct map);
1118 root 1.42 RETVAL->x = 0;
1119     RETVAL->y = 0;
1120     RETVAL->w = map_width;
1121     RETVAL->h = map_height;
1122     RETVAL->ox = 0;
1123     RETVAL->oy = 0;
1124 root 1.30 RETVAL->faces = 8192;
1125     Newz (0, RETVAL->face, RETVAL->faces, mapface);
1126 root 1.42 RETVAL->texs = 8192;
1127     Newz (0, RETVAL->tex, RETVAL->texs, maptex);
1128 root 1.28 RETVAL->rows = 0;
1129     RETVAL->row = 0;
1130     OUTPUT:
1131     RETVAL
1132    
1133     void
1134     DESTROY (CFClient::Map self)
1135     CODE:
1136     {
1137 root 1.30 map_clear (self);
1138 root 1.28 Safefree (self->face);
1139 root 1.111 Safefree (self->tex);
1140 root 1.29 Safefree (self);
1141     }
1142    
1143     void
1144 root 1.30 clear (CFClient::Map self)
1145     CODE:
1146     map_clear (self);
1147    
1148     void
1149 root 1.42 set_face (CFClient::Map self, int face, int texid)
1150 root 1.29 CODE:
1151     {
1152 root 1.42 while (self->faces <= face)
1153 root 1.28 {
1154 root 1.30 Append (mapface, self->face, self->faces, self->faces);
1155 root 1.29 self->faces *= 2;
1156     }
1157 root 1.28
1158 root 1.42 self->face [face] = texid;
1159     }
1160    
1161     void
1162     set_texture (CFClient::Map self, int texid, int name, int w, int h, float s, float t, int r, int g, int b, int a)
1163     CODE:
1164     {
1165     while (self->texs <= texid)
1166     {
1167     Append (maptex, self->tex, self->texs, self->texs);
1168     self->texs *= 2;
1169     }
1170    
1171 root 1.48 {
1172     maptex *tex = self->tex + texid;
1173 root 1.39
1174 root 1.48 tex->name = name;
1175     tex->w = w;
1176     tex->h = h;
1177     tex->s = s;
1178     tex->t = t;
1179     tex->r = r;
1180     tex->g = g;
1181     tex->b = b;
1182     tex->a = a;
1183     }
1184 root 1.95
1185     // somewhat hackish, but for textures that require it, it really
1186     // improves the look, and most others don't suffer.
1187     glBindTexture (GL_TEXTURE_2D, name);
1188 root 1.99 //glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1189     //glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1190     // use uglier nearest interpolation because linear suffers
1191     // from transparent color bleeding and ugly wrapping effects.
1192     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1193 root 1.29 }
1194    
1195 root 1.42 int
1196     ox (CFClient::Map self)
1197     ALIAS:
1198     oy = 1
1199 root 1.101 x = 2
1200     y = 3
1201 root 1.102 w = 4
1202     h = 5
1203 root 1.42 CODE:
1204     switch (ix)
1205     {
1206     case 0: RETVAL = self->ox; break;
1207     case 1: RETVAL = self->oy; break;
1208 root 1.101 case 2: RETVAL = self->x; break;
1209     case 3: RETVAL = self->y; break;
1210 root 1.102 case 4: RETVAL = self->w; break;
1211     case 5: RETVAL = self->h; break;
1212 root 1.42 }
1213     OUTPUT:
1214     RETVAL
1215    
1216 root 1.29 void
1217 root 1.43 scroll (CFClient::Map self, int dx, int dy)
1218     CODE:
1219     {
1220 root 1.44 if (dx > 0)
1221     map_blank (self, self->x, self->y, dx - 1, self->h);
1222     else if (dx < 0)
1223     map_blank (self, self->x + self->w + dx + 1, self->y, 1 - dx, self->h);
1224    
1225     if (dy > 0)
1226     map_blank (self, self->x, self->y, self->w, dy - 1);
1227     else if (dy < 0)
1228     map_blank (self, self->x, self->y + self->h + dy + 1, self->w, 1 - dy);
1229 root 1.43
1230 root 1.44 self->ox += dx; self->x += dx;
1231     self->oy += dy; self->y += dy;
1232 root 1.43
1233     while (self->y < 0)
1234     {
1235     Prepend (maprow, self->row, self->rows, MAP_EXTEND_Y);
1236    
1237     self->rows += MAP_EXTEND_Y;
1238     self->y += MAP_EXTEND_Y;
1239     }
1240 root 1.44 }
1241 root 1.43
1242 root 1.44 void
1243     map1a_update (CFClient::Map self, SV *data_)
1244     CODE:
1245     {
1246 root 1.30 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_);
1247     uint8_t *data_end = (uint8_t *)SvEND (data_);
1248 root 1.48 mapcell *cell;
1249     int x, y, flags;
1250 root 1.43
1251 root 1.29 while (data < data_end)
1252     {
1253 root 1.48 flags = (data [0] << 8) + data [1]; data += 2;
1254 root 1.30
1255 root 1.120 x = self->x + ((flags >> 10) & 63);
1256     y = self->y + ((flags >> 4) & 63);
1257 root 1.29
1258 root 1.48 cell = map_get_cell (self, x, y);
1259 root 1.29
1260     if (flags & 15)
1261     {
1262 root 1.45 if (cell->darkness < 0)
1263 root 1.29 {
1264     cell->darkness = 0;
1265     cell->face [0] = 0;
1266     cell->face [1] = 0;
1267     cell->face [2] = 0;
1268     }
1269 root 1.45
1270 root 1.29 cell->darkness = flags & 8 ? *data++ : 255;
1271    
1272 root 1.42 //TODO: don't trust server data to be in-range(!)
1273    
1274 root 1.29 if (flags & 4)
1275     {
1276 root 1.42 cell->face [0] = self->face [(data [0] << 8) + data [1]]; data += 2;
1277 root 1.29 }
1278    
1279     if (flags & 2)
1280     {
1281 root 1.42 cell->face [1] = self->face [(data [0] << 8) + data [1]]; data += 2;
1282 root 1.29 }
1283    
1284     if (flags & 1)
1285     {
1286 root 1.42 cell->face [2] = self->face [(data [0] << 8) + data [1]]; data += 2;
1287 root 1.29 }
1288     }
1289     else
1290 root 1.31 cell->darkness = -1;
1291 root 1.29 }
1292 root 1.28 }
1293    
1294 root 1.40 SV *
1295 root 1.55 mapmap (CFClient::Map self, int x0, int y0, int w, int h)
1296 root 1.40 CODE:
1297     {
1298 root 1.55 int x1, x;
1299     int y1, y;
1300 root 1.40 int z;
1301     SV *map_sv = newSV (w * h * sizeof (uint32_t));
1302     uint32_t *map = (uint32_t *)SvPVX (map_sv);
1303    
1304     SvPOK_only (map_sv);
1305     SvCUR_set (map_sv, w * h * sizeof (uint32_t));
1306    
1307 root 1.55 x0 += self->x; x1 = x0 + w;
1308     y0 += self->y; y1 = y0 + h;
1309 root 1.40
1310     for (y = y0; y < y1; y++)
1311     {
1312     maprow *row = 0 <= y && y < self->rows
1313     ? self->row + y
1314     : 0;
1315    
1316     for (x = x0; x < x1; x++)
1317     {
1318     int r = 32, g = 32, b = 32, a = 192;
1319    
1320     if (row && row->c0 <= x && x < row->c1)
1321     {
1322     mapcell *cell = row->col + (x - row->c0);
1323    
1324     for (z = 0; z <= 0; z++)
1325     {
1326 root 1.42 mapface face = cell->face [z];
1327 root 1.40
1328     if (face)
1329     {
1330 root 1.42 maptex tex = self->tex [face];
1331 root 1.40 int a0 = 255 - tex.a;
1332     int a1 = tex.a;
1333    
1334     r = (r * a0 + tex.r * a1) / 255;
1335     g = (g * a0 + tex.g * a1) / 255;
1336     b = (b * a0 + tex.b * a1) / 255;
1337     a = (a * a0 + tex.a * a1) / 255;
1338     }
1339     }
1340     }
1341    
1342     *map++ = (r )
1343     | (g << 8)
1344     | (b << 16)
1345     | (a << 24);
1346     }
1347     }
1348    
1349     RETVAL = map_sv;
1350     }
1351     OUTPUT:
1352     RETVAL
1353    
1354 root 1.30 void
1355 root 1.38 draw (CFClient::Map self, int shift_x, int shift_y, int x0, int y0, int sw, int sh)
1356 root 1.116 CODE:
1357 root 1.30 {
1358 root 1.48 int vx, vy;
1359     int x, y, z;
1360     int last_name;
1361     mapface face;
1362    
1363 root 1.120 vx = self->x + self->w / 2 - sw / 2 - shift_x;
1364     vy = self->y + self->h / 2 - sh / 2 - shift_y;
1365 root 1.38
1366 root 1.42 /*
1367     int vx = self->vx = self->w >= sw
1368     ? self->x + (self->w - sw) / 2
1369     : MIN (self->x, MAX (self->x + self->w - sw + 1, self->vx));
1370    
1371     int vy = self->vy = self->h >= sh
1372     ? self->y + (self->h - sh) / 2
1373     : MIN (self->y, MAX (self->y + self->h - sh + 1, self->vy));
1374     */
1375 root 1.30
1376     glColor4ub (255, 255, 255, 255);
1377    
1378 root 1.117 glEnable (GL_BLEND);
1379 root 1.30 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1380     glEnable (GL_TEXTURE_2D);
1381     glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1382    
1383 root 1.48 glBegin (GL_QUADS);
1384 root 1.30
1385 root 1.48 last_name = 0;
1386 root 1.30
1387     for (z = 0; z < 3; z++)
1388     for (y = 0; y < sh; y++)
1389     if (0 <= y + vy && y + vy < self->rows)
1390     {
1391     maprow *row = self->row + (y + vy);
1392    
1393     for (x = 0; x < sw; x++)
1394     if (row->c0 <= x + vx && x + vx < row->c1)
1395     {
1396     mapcell *cell = row->col + (x + vx - row->c0);
1397 root 1.32
1398 root 1.48 face = cell->face [z];
1399 root 1.30
1400     if (face)
1401     {
1402 root 1.42 maptex tex = self->tex [face];
1403 root 1.30
1404     int px = (x + 1) * 32 - tex.w;
1405     int py = (y + 1) * 32 - tex.h;
1406    
1407     if (last_name != tex.name)
1408     {
1409     glEnd ();
1410     last_name = tex.name;
1411     glBindTexture (GL_TEXTURE_2D, last_name);
1412     glBegin (GL_QUADS);
1413     }
1414    
1415     glTexCoord2f (0 , 0 ); glVertex2f (px , py );
1416     glTexCoord2f (0 , tex.t); glVertex2f (px , py + tex.h);
1417     glTexCoord2f (tex.s, tex.t); glVertex2f (px + tex.w, py + tex.h);
1418     glTexCoord2f (tex.s, 0 ); glVertex2f (px + tex.w, py );
1419     }
1420     }
1421     }
1422    
1423     glEnd ();
1424 root 1.32
1425 root 1.34 glDisable (GL_TEXTURE_2D);
1426     glDisable (GL_BLEND);
1427 root 1.116 }
1428    
1429     void
1430 root 1.117 draw_magicmap (CFClient::Map self, int dx, int dy, int w, int h, unsigned char *data)
1431     CODE:
1432     {
1433     static float color[16][3] = {
1434 root 1.123 { 0.00F, 0.00F, 0.00F },
1435     { 1.00F, 1.00F, 1.00F },
1436     { 0.00F, 0.00F, 0.55F },
1437     { 1.00F, 0.00F, 0.00F },
1438    
1439     { 1.00F, 0.54F, 0.00F },
1440     { 0.11F, 0.56F, 1.00F },
1441     { 0.93F, 0.46F, 0.00F },
1442     { 0.18F, 0.54F, 0.34F },
1443    
1444     { 0.56F, 0.73F, 0.56F },
1445     { 0.80F, 0.80F, 0.80F },
1446     { 0.55F, 0.41F, 0.13F },
1447     { 0.99F, 0.77F, 0.26F },
1448    
1449     { 0.74F, 0.65F, 0.41F },
1450    
1451     { 0.00F, 1.00F, 1.00F },
1452     { 1.00F, 0.00F, 1.00F },
1453     { 1.00F, 1.00F, 0.00F },
1454 root 1.117 };
1455    
1456     int x, y;
1457    
1458     glEnable (GL_TEXTURE_2D);
1459     glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1460     glEnable (GL_BLEND);
1461     glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1462     glBegin (GL_QUADS);
1463    
1464     for (y = 0; y < h; y++)
1465     for (x = 0; x < w; x++)
1466     {
1467     unsigned char m = data [x + y * w];
1468    
1469 root 1.118 if (m)
1470     {
1471     float *c = color [m & 15];
1472    
1473     float tx1 = m & 0x40 ? 0.5 : 0.;
1474     float tx2 = tx1 + 0.5;
1475    
1476     glColor4f (c[0], c[1], c[2], 0.75);
1477     glTexCoord2f (tx1, 0.); glVertex2i (x , y );
1478     glTexCoord2f (tx1, 1.); glVertex2i (x , y + 1);
1479     glTexCoord2f (tx2, 1.); glVertex2i (x + 1, y + 1);
1480     glTexCoord2f (tx2, 0.); glVertex2i (x + 1, y );
1481     }
1482 root 1.117 }
1483    
1484     glEnd ();
1485     glDisable (GL_BLEND);
1486     glDisable (GL_TEXTURE_2D);
1487     }
1488    
1489     void
1490 root 1.116 fow_texture (CFClient::Map self, int shift_x, int shift_y, int x0, int y0, int sw, int sh)
1491     PPCODE:
1492     {
1493     int vx, vy;
1494     int x, y;
1495     int sw4 = (sw + 3) & ~3;
1496     SV *darkness_sv = sv_2mortal (newSV (sw4 * sh));
1497     uint8_t *darkness = (uint8_t *)SvPVX (darkness_sv);
1498    
1499     memset (darkness, 255, sw4 * sh);
1500     SvPOK_only (darkness_sv);
1501     SvCUR_set (darkness_sv, sw4 * sh);
1502    
1503     vx = self->x + (self->w - sw + 1) / 2 - shift_x;
1504     vy = self->y + (self->h - sh + 1) / 2 - shift_y;
1505    
1506     for (y = 0; y < sh; y++)
1507     if (0 <= y + vy && y + vy < self->rows)
1508     {
1509     maprow *row = self->row + (y + vy);
1510    
1511     for (x = 0; x < sw; x++)
1512     if (row->c0 <= x + vx && x + vx < row->c1)
1513     {
1514     mapcell *cell = row->col + (x + vx - row->c0);
1515    
1516     darkness[y * sw4 + x] = cell->darkness < 0
1517     ? 255 - FOW_DARKNESS
1518     : 255 - cell->darkness;
1519     }
1520     }
1521 root 1.34
1522 root 1.32 EXTEND (SP, 3);
1523     PUSHs (sv_2mortal (newSViv (sw4)));
1524     PUSHs (sv_2mortal (newSViv (sh)));
1525     PUSHs (darkness_sv);
1526 root 1.30 }
1527    
1528 root 1.42 SV *
1529     get_rect (CFClient::Map self, int x0, int y0, int w, int h)
1530     CODE:
1531     {
1532     int x, y, x1, y1;
1533     SV *data_sv = newSV (w * h * 7 + 5);
1534     uint8_t *data = (uint8_t *)SvPVX (data_sv);
1535    
1536     *data++ = 0; /* version 0 format */
1537     *data++ = w >> 8; *data++ = w;
1538     *data++ = h >> 8; *data++ = h;
1539    
1540     // we need to do this 'cause we don't keep an absolute coord system for rows
1541 root 1.55 // TODO: treat rows as we treat columns
1542 root 1.42 map_get_row (self, y0 + self->y - self->oy);//D
1543     map_get_row (self, y0 + self->y - self->oy + h - 1);//D
1544    
1545     x0 += self->x - self->ox;
1546     y0 += self->y - self->oy;
1547    
1548     x1 = x0 + w;
1549     y1 = y0 + h;
1550    
1551     for (y = y0; y < y1; y++)
1552     {
1553     maprow *row = 0 <= y && y < self->rows
1554     ? self->row + y
1555     : 0;
1556    
1557     for (x = x0; x < x1; x++)
1558     {
1559     if (row && row->c0 <= x && x < row->c1)
1560     {
1561     mapcell *cell = row->col + (x - row->c0);
1562     uint8_t flags = 0;
1563    
1564     if (cell->face [0]) flags |= 1;
1565     if (cell->face [1]) flags |= 2;
1566     if (cell->face [2]) flags |= 4;
1567    
1568     *data++ = flags;
1569    
1570     if (flags & 1)
1571     {
1572     *data++ = cell->face [0] >> 8;
1573     *data++ = cell->face [0];
1574     }
1575    
1576     if (flags & 2)
1577     {
1578     *data++ = cell->face [1] >> 8;
1579     *data++ = cell->face [1];
1580     }
1581    
1582     if (flags & 4)
1583     {
1584     *data++ = cell->face [2] >> 8;
1585     *data++ = cell->face [2];
1586     }
1587     }
1588     else
1589     *data++ = 0;
1590     }
1591     }
1592    
1593     SvPOK_only (data_sv);
1594     SvCUR_set (data_sv, data - (uint8_t *)SvPVX (data_sv));
1595     RETVAL = data_sv;
1596     }
1597     OUTPUT:
1598     RETVAL
1599    
1600     void
1601     set_rect (CFClient::Map self, int x0, int y0, uint8_t *data)
1602     PPCODE:
1603     {
1604     int x, y, z;
1605 root 1.48 int w, h;
1606 root 1.42 int x1, y1;
1607    
1608     if (*data++ != 0)
1609     return; /* version mismatch */
1610    
1611 root 1.48 w = *data++ << 8; w |= *data++;
1612     h = *data++ << 8; h |= *data++;
1613 root 1.42
1614     // we need to do this 'cause we don't keep an absolute coord system for rows
1615 root 1.55 // TODO: treat rows as we treat columns
1616 root 1.42 map_get_row (self, y0 + self->y - self->oy);//D
1617     map_get_row (self, y0 + self->y - self->oy + h - 1);//D
1618    
1619     x0 += self->x - self->ox;
1620     y0 += self->y - self->oy;
1621    
1622     x1 = x0 + w;
1623     y1 = y0 + h;
1624    
1625     for (y = y0; y < y1; y++)
1626     {
1627     maprow *row = map_get_row (self, y);
1628    
1629     for (x = x0; x < x1; x++)
1630     {
1631     uint8_t flags = *data++;
1632    
1633     if (flags)
1634     {
1635     mapface face[3] = { 0, 0, 0 };
1636    
1637     mapcell *cell = row_get_cell (row, x);
1638    
1639     if (flags & 1) { face[0] = *data++ << 8; face[0] |= *data++; }
1640     if (flags & 2) { face[1] = *data++ << 8; face[1] |= *data++; }
1641     if (flags & 4) { face[2] = *data++ << 8; face[2] |= *data++; }
1642    
1643     if (cell->darkness <= 0)
1644     {
1645     cell->darkness = -1;
1646    
1647     for (z = 0; z <= 2; z++)
1648     {
1649     cell->face[z] = face[z];
1650    
1651     if (face[z] && (face[z] >= self->texs || !self->tex[face [z]].name))
1652     XPUSHs (sv_2mortal (newSViv (face[z])));
1653     }
1654     }
1655     }
1656     }
1657     }
1658     }
1659    
1660 root 1.52 MODULE = CFClient PACKAGE = CFClient::MixChunk
1661    
1662     CFClient::MixChunk
1663     new_from_file (SV *class, char *path)
1664     CODE:
1665     RETVAL = Mix_LoadWAV (path);
1666     OUTPUT:
1667     RETVAL
1668    
1669     void
1670     DESTROY (CFClient::MixChunk self)
1671     CODE:
1672     Mix_FreeChunk (self);
1673    
1674     int
1675     volume (CFClient::MixChunk self, int volume = -1)
1676     CODE:
1677     RETVAL = Mix_VolumeChunk (self, volume);
1678     OUTPUT:
1679     RETVAL
1680    
1681     int
1682     play (CFClient::MixChunk self, int channel = -1, int loops = 0, int ticks = -1)
1683     CODE:
1684     RETVAL = Mix_PlayChannelTimed (channel, self, loops, ticks);
1685     OUTPUT:
1686     RETVAL
1687    
1688     MODULE = CFClient PACKAGE = CFClient::MixMusic
1689    
1690     int
1691     volume (int volume = -1)
1692     CODE:
1693     RETVAL = Mix_VolumeMusic (volume);
1694     OUTPUT:
1695     RETVAL
1696    
1697     CFClient::MixMusic
1698     new_from_file (SV *class, char *path)
1699     CODE:
1700     RETVAL = Mix_LoadMUS (path);
1701     OUTPUT:
1702     RETVAL
1703    
1704     void
1705     DESTROY (CFClient::MixMusic self)
1706     CODE:
1707     Mix_FreeMusic (self);
1708    
1709     int
1710     play (CFClient::MixMusic self, int loops = -1)
1711     CODE:
1712     RETVAL = Mix_PlayMusic (self, loops);
1713     OUTPUT:
1714     RETVAL
1715    
1716 root 1.54 MODULE = CFClient PACKAGE = CFClient::OpenGL
1717    
1718     BOOT:
1719     {
1720     HV *stash = gv_stashpv ("CFClient::OpenGL", 1);
1721     static const struct {
1722     const char *name;
1723     IV iv;
1724     } *civ, const_iv[] = {
1725     # define const_iv(name) { # name, (IV)name }
1726     const_iv (GL_COLOR_MATERIAL),
1727     const_iv (GL_SMOOTH),
1728     const_iv (GL_FLAT),
1729 root 1.69 const_iv (GL_DITHER),
1730 root 1.54 const_iv (GL_BLEND),
1731 root 1.89 const_iv (GL_CULL_FACE),
1732 root 1.69 const_iv (GL_SCISSOR_TEST),
1733 root 1.89 const_iv (GL_DEPTH_TEST),
1734     const_iv (GL_ALPHA_TEST),
1735     const_iv (GL_NORMALIZE),
1736     const_iv (GL_RESCALE_NORMAL),
1737 root 1.119 const_iv (GL_FRONT),
1738     const_iv (GL_BACK),
1739 root 1.54 const_iv (GL_AND),
1740 root 1.67 const_iv (GL_ONE),
1741     const_iv (GL_ZERO),
1742 root 1.54 const_iv (GL_SRC_ALPHA),
1743 root 1.104 const_iv (GL_DST_ALPHA),
1744 root 1.54 const_iv (GL_ONE_MINUS_SRC_ALPHA),
1745 root 1.67 const_iv (GL_ONE_MINUS_DST_ALPHA),
1746 root 1.104 const_iv (GL_SRC_ALPHA_SATURATE),
1747 root 1.54 const_iv (GL_RGB),
1748     const_iv (GL_RGBA),
1749 root 1.115 const_iv (GL_RGBA4),
1750     const_iv (GL_RGBA8),
1751     const_iv (GL_RGB5_A1),
1752 root 1.54 const_iv (GL_UNSIGNED_BYTE),
1753 root 1.89 const_iv (GL_UNSIGNED_SHORT),
1754     const_iv (GL_UNSIGNED_INT),
1755 root 1.54 const_iv (GL_ALPHA),
1756 root 1.86 const_iv (GL_INTENSITY),
1757 root 1.76 const_iv (GL_LUMINANCE),
1758 root 1.86 const_iv (GL_LUMINANCE_ALPHA),
1759 root 1.54 const_iv (GL_FLOAT),
1760     const_iv (GL_UNSIGNED_INT_8_8_8_8_REV),
1761     const_iv (GL_COMPILE),
1762     const_iv (GL_TEXTURE_1D),
1763     const_iv (GL_TEXTURE_2D),
1764     const_iv (GL_TEXTURE_ENV),
1765     const_iv (GL_TEXTURE_MAG_FILTER),
1766     const_iv (GL_TEXTURE_MIN_FILTER),
1767     const_iv (GL_TEXTURE_ENV_MODE),
1768     const_iv (GL_TEXTURE_WRAP_S),
1769     const_iv (GL_TEXTURE_WRAP_T),
1770 root 1.98 const_iv (GL_REPEAT),
1771 root 1.54 const_iv (GL_CLAMP),
1772 root 1.98 const_iv (GL_CLAMP_TO_EDGE),
1773 root 1.54 const_iv (GL_NEAREST),
1774     const_iv (GL_LINEAR),
1775 root 1.57 const_iv (GL_NEAREST_MIPMAP_NEAREST),
1776     const_iv (GL_LINEAR_MIPMAP_NEAREST),
1777     const_iv (GL_NEAREST_MIPMAP_LINEAR),
1778     const_iv (GL_LINEAR_MIPMAP_LINEAR),
1779     const_iv (GL_GENERATE_MIPMAP),
1780 root 1.54 const_iv (GL_MODULATE),
1781 root 1.69 const_iv (GL_DECAL),
1782 root 1.54 const_iv (GL_REPLACE),
1783 root 1.89 const_iv (GL_DEPTH_BUFFER_BIT),
1784 root 1.54 const_iv (GL_COLOR_BUFFER_BIT),
1785     const_iv (GL_PROJECTION),
1786     const_iv (GL_MODELVIEW),
1787     const_iv (GL_COLOR_LOGIC_OP),
1788 root 1.69 const_iv (GL_SEPARABLE_2D),
1789 root 1.54 const_iv (GL_CONVOLUTION_2D),
1790     const_iv (GL_CONVOLUTION_BORDER_MODE),
1791     const_iv (GL_CONSTANT_BORDER),
1792     const_iv (GL_LINES),
1793 root 1.89 const_iv (GL_LINE_LOOP),
1794 root 1.54 const_iv (GL_QUADS),
1795 root 1.89 const_iv (GL_QUAD_STRIP),
1796     const_iv (GL_TRIANGLES),
1797     const_iv (GL_TRIANGLE_STRIP),
1798     const_iv (GL_TRIANGLE_FAN),
1799 root 1.54 const_iv (GL_PERSPECTIVE_CORRECTION_HINT),
1800     const_iv (GL_FASTEST),
1801 root 1.89 const_iv (GL_V2F),
1802     const_iv (GL_V3F),
1803     const_iv (GL_T2F_V3F),
1804     const_iv (GL_T2F_N3F_V3F),
1805 root 1.54 # undef const_iv
1806     };
1807    
1808     for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
1809     newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
1810     }
1811    
1812 root 1.97 char *
1813     gl_vendor ()
1814     CODE:
1815     RETVAL = (char *)glGetString (GL_VENDOR);
1816     OUTPUT:
1817     RETVAL
1818    
1819     char *
1820     gl_version ()
1821     CODE:
1822     RETVAL = (char *)glGetString (GL_VERSION);
1823     OUTPUT:
1824     RETVAL
1825    
1826     char *
1827     gl_extensions ()
1828     CODE:
1829     RETVAL = (char *)glGetString (GL_EXTENSIONS);
1830     OUTPUT:
1831     RETVAL
1832    
1833 root 1.54 int glGetError ()
1834    
1835 root 1.114 void glFinish ()
1836    
1837 root 1.54 void glClear (int mask)
1838    
1839     void glClearColor (float r, float g, float b, float a = 1.0)
1840     PROTOTYPE: @
1841    
1842     void glEnable (int cap)
1843    
1844     void glDisable (int cap)
1845    
1846     void glShadeModel (int mode)
1847    
1848     void glHint (int target, int mode)
1849    
1850     void glBlendFunc (int sfactor, int dfactor)
1851    
1852 root 1.103 void glBlendFuncSeparate (int sa, int da, int saa, int daa)
1853     CODE:
1854     gl_BlendFuncSeparate (sa, da, saa, daa);
1855    
1856 root 1.89 void glDepthMask (int flag)
1857    
1858 root 1.54 void glLogicOp (int opcode)
1859    
1860 root 1.68 void glColorMask (int red, int green, int blue, int alpha)
1861    
1862 root 1.54 void glMatrixMode (int mode)
1863    
1864     void glPushMatrix ()
1865    
1866     void glPopMatrix ()
1867    
1868     void glLoadIdentity ()
1869    
1870 root 1.119 void glDrawBuffer (int buffer)
1871    
1872     void glReadBuffer (int buffer)
1873    
1874 root 1.90 # near_ and far_ are due to microsofts buggy "c" compiler
1875     void glFrustum (double left, double right, double bottom, double top, double near_, double far_)
1876    
1877     # near_ and far_ are due to microsofts buggy "c" compiler
1878 root 1.64 void glOrtho (double left, double right, double bottom, double top, double near_, double far_)
1879 root 1.54
1880     void glViewport (int x, int y, int width, int height)
1881    
1882 root 1.69 void glScissor (int x, int y, int width, int height)
1883    
1884 root 1.54 void glTranslate (float x, float y, float z = 0.)
1885     CODE:
1886     glTranslatef (x, y, z);
1887    
1888 root 1.62 void glScale (float x, float y, float z = 1.)
1889 root 1.54 CODE:
1890     glScalef (x, y, z);
1891    
1892     void glRotate (float angle, float x, float y, float z)
1893     CODE:
1894     glRotatef (angle, x, y, z);
1895    
1896     void glBegin (int mode)
1897    
1898     void glEnd ()
1899    
1900     void glColor (float r, float g, float b, float a = 1.0)
1901     PROTOTYPE: @
1902 root 1.103 ALIAS:
1903     glColor_premultiply = 1
1904 root 1.54 CODE:
1905 root 1.103 if (ix)
1906     {
1907     r *= a;
1908     g *= a;
1909     b *= a;
1910     }
1911 root 1.90 // microsoft visual "c" rounds instead of truncating...
1912 root 1.100 glColor4ub (MIN ((int)(r * 256.f), 255),
1913     MIN ((int)(g * 256.f), 255),
1914     MIN ((int)(b * 256.f), 255),
1915     MIN ((int)(a * 256.f), 255));
1916 root 1.54
1917 root 1.89 void glInterleavedArrays (int format, int stride, char *data)
1918    
1919     void glDrawElements (int mode, int count, int type, char *indices)
1920    
1921     # 1.2 void glDrawRangeElements (int mode, int start, int end
1922    
1923 root 1.91 void glRasterPos (float x, float y, float z = 0.)
1924     CODE:
1925     glRasterPos3f (0, 0, z);
1926     glBitmap (0, 0, 0, 0, x, y, 0);
1927    
1928 root 1.54 void glVertex (float x, float y, float z = 0.)
1929     CODE:
1930     glVertex3f (x, y, z);
1931    
1932     void glTexCoord (float s, float t)
1933     CODE:
1934     glTexCoord2f (s, t);
1935    
1936     void glTexEnv (int target, int pname, float param)
1937     CODE:
1938     glTexEnvf (target, pname, param);
1939    
1940     void glTexParameter (int target, int pname, float param)
1941     CODE:
1942     glTexParameterf (target, pname, param);
1943    
1944     void glBindTexture (int target, int name)
1945    
1946     void glConvolutionParameter (int target, int pname, float params)
1947     CODE:
1948 root 1.103 if (gl.ConvolutionParameterf)
1949     gl.ConvolutionParameterf (target, pname, params);
1950 root 1.54
1951     void glConvolutionFilter2D (int target, int internalformat, int width, int height, int format, int type, char *data)
1952 root 1.64 CODE:
1953 root 1.103 if (gl.ConvolutionFilter2D)
1954     gl.ConvolutionFilter2D (target, internalformat, width, height, format, type, data);
1955 root 1.54
1956 root 1.69 void glSeparableFilter2D (int target, int internalformat, int width, int height, int format, int type, char *row, char *column)
1957     CODE:
1958 root 1.103 if (gl.SeparableFilter2D)
1959     gl.SeparableFilter2D (target, internalformat, width, height, format, type, row, column);
1960 root 1.69
1961 root 1.54 void glTexImage2D (int target, int level, int internalformat, int width, int height, int border, int format, int type, char *data)
1962    
1963     void glCopyTexImage2D (int target, int level, int internalformat, int x, int y, int width, int height, int border)
1964    
1965 root 1.91 void glDrawPixels (int width, int height, int format, int type, char *pixels)
1966 root 1.68
1967     void glCopyPixels (int x, int y, int width, int height, int type = GL_COLOR)
1968    
1969 root 1.54 int glGenTexture ()
1970     CODE:
1971     {
1972     GLuint name;
1973     glGenTextures (1, &name);
1974     RETVAL = name;
1975     }
1976     OUTPUT:
1977     RETVAL
1978    
1979     void glDeleteTexture (int name)
1980     CODE:
1981     {
1982     GLuint name_ = name;
1983     glDeleteTextures (1, &name_);
1984     }
1985    
1986     int glGenList ()
1987     CODE:
1988     RETVAL = glGenLists (1);
1989     OUTPUT:
1990     RETVAL
1991    
1992     void glDeleteList (int list)
1993     CODE:
1994     glDeleteLists (list, 1);
1995    
1996     void glNewList (int list, int mode = GL_COMPILE)
1997    
1998     void glEndList ()
1999    
2000     void glCallList (int list)
2001    
2002 root 1.89