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