ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/Client.xs
Revision: 1.141
Committed: Fri Aug 18 01:01:00 2006 UTC (17 years, 8 months ago) by root
Branch: MAIN
Changes since 1.140: +24 -2 lines
Log Message:
*** empty log message ***

File Contents

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