ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/Client.xs
(Generate patch)

Comparing deliantra/Deliantra-Client/Client.xs (file contents):
Revision 1.108 by root, Wed Jun 7 23:28:12 2006 UTC vs.
Revision 1.167 by root, Sat Dec 9 02:21:25 2006 UTC

1#ifdef _WIN32 1#ifdef _WIN32
2# define WIN32_LEAN_AND_MEAN
2# define _WIN32_WINNT 0x0500 // needed to get win2000 api calls 3# define _WIN32_WINNT 0x0500 // needed to get win2000 api calls
3# include <malloc.h> 4# include <malloc.h>
4# include <windows.h> 5# include <windows.h>
6# include <wininet.h>
5# pragma warning(disable:4244) 7# pragma warning(disable:4244)
8# pragma warning(disable:4761)
6#endif 9#endif
7 10
8#include "EXTERN.h" 11#include "EXTERN.h"
9#include "perl.h" 12#include "perl.h"
10#include "XSUB.h" 13#include "XSUB.h"
11 14
15#ifdef _WIN32
16# undef pipe
17#endif
18
12#include <math.h> 19#include <math.h>
13#include <string.h> 20#include <string.h>
14#include <stdio.h> 21#include <stdio.h>
22#include <stdlib.h>
15 23
16#include <SDL.h> 24#include <SDL.h>
17#include <SDL_endian.h> 25#include <SDL_endian.h>
18#include <SDL_image.h> 26#include <SDL_image.h>
19#include <SDL_mixer.h> 27#include <SDL_mixer.h>
20#include <SDL_opengl.h> 28#include <SDL_opengl.h>
21 29
30#define PANGO_ENABLE_BACKEND
31#define G_DISABLE_CAST_CHECKS
32
22#include <glib/gmacros.h> 33#include <glib/gmacros.h>
23 34
24#include <pango/pango.h> 35#include <pango/pango.h>
25#include <pango/pangofc-fontmap.h>
26#include <pango/pangoft2.h>
27#include <pango/pangocairo.h>
28 36
29#ifndef _WIN32 37#ifndef _WIN32
30# include <sys/types.h> 38# include <sys/types.h>
31# include <sys/socket.h> 39# include <sys/socket.h>
32# include <netinet/in.h> 40# include <netinet/in.h>
33# include <netinet/tcp.h> 41# include <netinet/tcp.h>
34# include <inttypes.h> 42# include <inttypes.h>
35#else
36 typedef unsigned char uint8_t;
37 typedef unsigned short uint16_t;
38 typedef unsigned int uint32_t;
39 typedef signed char int8_t;
40 typedef signed short int16_t;
41 typedef signed int int32_t;
42#endif 43#endif
43 44
44#include "glext.h" 45#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, object replacement character */
45 46
46#define FOW_DARKNESS 32 47#define FOW_DARKNESS 32
47 48
48#define MAP_EXTEND_X 32 49#define MAP_EXTEND_X 32
49#define MAP_EXTEND_Y 512 50#define MAP_EXTEND_Y 512
50 51
51#define MIN_FONT_HEIGHT 10 52#define MIN_FONT_HEIGHT 10
53
54#if 0
55# define PARACHUTE SDL_INIT_NOPARACHUTE
56#else
57# define PARACHUTE 0
58#endif
52 59
53static struct 60static struct
54{ 61{
55#define GL_FUNC(ptr,name) ptr name; 62#define GL_FUNC(ptr,name) ptr name;
56#include "glfunc.h" 63#include "glfunc.h"
65 gl.BlendFuncSeparateEXT (sa, da, saa, daa); 72 gl.BlendFuncSeparateEXT (sa, da, saa, daa);
66 else 73 else
67 glBlendFunc (sa, da); 74 glBlendFunc (sa, da);
68} 75}
69 76
77#include "texcache.c"
78
79#include "pango-font.c"
80#include "pango-fontmap.c"
81#include "pango-render.c"
82
70typedef Mix_Chunk *CFClient__MixChunk; 83typedef Mix_Chunk *CFPlus__MixChunk;
71typedef Mix_Music *CFClient__MixMusic; 84typedef Mix_Music *CFPlus__MixMusic;
72 85
73typedef PangoFontDescription *CFClient__Font; 86typedef PangoFontDescription *CFPlus__Font;
87
88static int
89shape_attr_p (PangoLayoutRun *run)
90{
91 GSList *attrs = run->item->analysis.extra_attrs;
92
93 while (attrs)
94 {
95 PangoAttribute *attr = attrs->data;
96
97 if (attr->klass->type == PANGO_ATTR_SHAPE)
98 return 1;
99
100 attrs = attrs->next;
101 }
102
103 return 0;
104}
74 105
75typedef struct cf_layout { 106typedef struct cf_layout {
76 PangoLayout *pl; // either derived from a cairo or ft2 context 107 PangoLayout *pl;
77 int rgba; // wether we use rgba (cairo) or grayscale (ft2)
78 float r, g, b, a; // default color for rgba mode 108 float r, g, b, a; // default color for rgba mode
79 int base_height; 109 int base_height;
80 CFClient__Font font; 110 CFPlus__Font font;
81} *CFClient__Layout; 111} *CFPlus__Layout;
82 112
83static CFClient__Font default_font; 113static CFPlus__Font default_font;
84static PangoContext *ft2_context, *cairo_context; 114static PangoContext *opengl_context;
85static PangoFontMap *ft2_fontmap, *cairo_fontmap; 115static PangoFontMap *opengl_fontmap;
86 116
87static void 117static void
88substitute_func (FcPattern *pattern, gpointer data) 118substitute_func (FcPattern *pattern, gpointer data)
89{ 119{
90 FcPatternAddBool (pattern, FC_HINTING, 1); 120 FcPatternAddBool (pattern, FC_HINTING, 1);
121#ifdef FC_HINT_STYLE
91 FcPatternAddBool (pattern, FC_HINTSTYLE, FC_HINT_FULL); 122 FcPatternAddBool (pattern, FC_HINT_STYLE, FC_HINT_FULL);
92#ifdef _WIN32 123#endif
93 FcPatternAddBool (pattern, FC_AUTOHINT, 1);
94#else
95 FcPatternAddBool (pattern, FC_AUTOHINT, 0); 124 FcPatternAddBool (pattern, FC_AUTOHINT, 0);
96#endif
97} 125}
98 126
99static void 127static void
100layout_update_font (CFClient__Layout self) 128layout_update_font (CFPlus__Layout self)
101{ 129{
102 /* use a random scale factor to account for unknown descenders, 0.8 works 130 /* use a random scale factor to account for unknown descenders, 0.8 works
103 * reasonably well with bitstream vera 131 * reasonably well with bitstream vera
104 */ 132 */
105 PangoFontDescription *font = self->font ? self->font : default_font; 133 PangoFontDescription *font = self->font ? self->font : default_font;
109 137
110 pango_layout_set_font_description (self->pl, font); 138 pango_layout_set_font_description (self->pl, font);
111} 139}
112 140
113static void 141static void
114layout_get_pixel_size (CFClient__Layout self, int *w, int *h) 142layout_get_pixel_size (CFPlus__Layout self, int *w, int *h)
115{ 143{
144 PangoRectangle rect;
145
146 // get_pixel_* wrongly rounds down
116 pango_layout_get_pixel_size (self->pl, w, h); 147 pango_layout_get_extents (self->pl, 0, &rect);
117 148
118 if (!*w) *w = 1; 149 rect.width = (rect.width + PANGO_SCALE - 1) / PANGO_SCALE;
119 if (!*h) *h = 1; 150 rect.height = (rect.height + PANGO_SCALE - 1) / PANGO_SCALE;
120 151
121 *w = (*w + 3) & ~3; 152 if (!rect.width) rect.width = 1;
153 if (!rect.height) rect.height = 1;
154
155 *w = rect.width;
156 *h = rect.height;
122} 157}
123 158
124typedef uint16_t mapface; 159typedef uint16_t mapface;
125 160
126typedef struct { 161typedef struct {
129 float s, t; 164 float s, t;
130 uint8_t r, g, b, a; 165 uint8_t r, g, b, a;
131} maptex; 166} maptex;
132 167
133typedef struct { 168typedef struct {
134 int16_t darkness; 169 uint32_t player;
135 mapface face[3]; 170 mapface face[3];
171 uint16_t darkness;
172 uint8_t stat_width, stat_hp, flags;
136} mapcell; 173} mapcell;
137 174
138typedef struct { 175typedef struct {
139 int32_t c0, c1; 176 int32_t c0, c1;
140 mapcell *col; 177 mapcell *col;
149 int texs; 186 int texs;
150 maptex *tex; 187 maptex *tex;
151 188
152 int32_t rows; 189 int32_t rows;
153 maprow *row; 190 maprow *row;
154} *CFClient__Map; 191} *CFPlus__Map;
155 192
156static char * 193static char *
157prepend (char *ptr, int sze, int inc) 194prepend (char *ptr, int sze, int inc)
158{ 195{
159 char *p; 196 char *p;
177 214
178#define Append(type,ptr,sze,inc) (ptr) = (type *)append ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type)) 215#define Append(type,ptr,sze,inc) (ptr) = (type *)append ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type))
179#define Prepend(type,ptr,sze,inc) (ptr) = (type *)prepend ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type)) 216#define Prepend(type,ptr,sze,inc) (ptr) = (type *)prepend ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type))
180 217
181static maprow * 218static maprow *
182map_get_row (CFClient__Map self, int y) 219map_get_row (CFPlus__Map self, int y)
183{ 220{
184 if (0 > y) 221 if (0 > y)
185 { 222 {
186 int extend = - y + MAP_EXTEND_Y; 223 int extend = - y + MAP_EXTEND_Y;
187 Prepend (maprow, self->row, self->rows, extend); 224 Prepend (maprow, self->row, self->rows, extend);
225 262
226 return row->col + (x - row->c0); 263 return row->col + (x - row->c0);
227} 264}
228 265
229static mapcell * 266static mapcell *
230map_get_cell (CFClient__Map self, int x, int y) 267map_get_cell (CFPlus__Map self, int x, int y)
231{ 268{
232 return row_get_cell (map_get_row (self, y), x); 269 return row_get_cell (map_get_row (self, y), x);
233} 270}
234 271
235static void 272static void
236map_clear (CFClient__Map self) 273map_clear (CFPlus__Map self)
237{ 274{
238 int r; 275 int r;
239 276
240 for (r = 0; r < self->rows; r++) 277 for (r = 0; r < self->rows; r++)
241 Safefree (self->row[r].col); 278 Safefree (self->row[r].col);
249 self->row = 0; 286 self->row = 0;
250 self->rows = 0; 287 self->rows = 0;
251} 288}
252 289
253static void 290static void
254map_blank (CFClient__Map self, int x0, int y0, int w, int h) 291map_blank (CFPlus__Map self, int x0, int y0, int w, int h)
255{ 292{
256 int x, y; 293 int x, y;
257 maprow *row; 294 maprow *row;
295 mapcell *cell;
258 296
259 for (y = y0; y < y0 + h; y++) 297 for (y = y0; y < y0 + h; y++)
260 if (y >= 0) 298 if (y >= 0)
261 { 299 {
262 if (y >= self->rows) 300 if (y >= self->rows)
268 if (x >= row->c0) 306 if (x >= row->c0)
269 { 307 {
270 if (x >= row->c1) 308 if (x >= row->c1)
271 break; 309 break;
272 310
273 row->col[x - row->c0].darkness = -1; 311 cell = row->col + x - row->c0;
312
313 cell->darkness = 0;
314 cell->stat_hp = 0;
315 cell->flags = 0;
316 cell->player = 0;
274 } 317 }
275 } 318 }
276} 319}
277 320
278static void 321static void
299 ev.data2 = 0; 342 ev.data2 = 0;
300 343
301 SDL_PushEvent ((SDL_Event *)&ev); 344 SDL_PushEvent ((SDL_Event *)&ev);
302} 345}
303 346
347static unsigned int
348minpot (unsigned int n)
349{
350 if (!n)
351 return 0;
352
353 --n;
354
355 n |= n >> 1;
356 n |= n >> 2;
357 n |= n >> 4;
358 n |= n >> 8;
359 n |= n >> 16;
360
361 return n + 1;
362}
363
364/* SDL should provide this, really. */
365#define SDLK_MODIFIER_MIN 300
366#define SDLK_MODIFIER_MAX 314
367
304MODULE = CFClient PACKAGE = CFClient 368MODULE = CFPlus PACKAGE = CFPlus
305 369
306PROTOTYPES: ENABLE 370PROTOTYPES: ENABLE
307 371
308BOOT: 372BOOT:
309{ 373{
310 HV *stash = gv_stashpv ("CFClient", 1); 374 HV *stash = gv_stashpv ("CFPlus", 1);
311 static const struct { 375 static const struct {
312 const char *name; 376 const char *name;
313 IV iv; 377 IV iv;
314 } *civ, const_iv[] = { 378 } *civ, const_iv[] = {
315# define const_iv(name) { # name, (IV)name } 379# define const_iv(name) { # name, (IV)name }
380 const_iv (SDLK_MODIFIER_MIN),
381 const_iv (SDLK_MODIFIER_MAX),
382
316 const_iv (SDL_ACTIVEEVENT), 383 const_iv (SDL_ACTIVEEVENT),
317 const_iv (SDL_KEYDOWN), 384 const_iv (SDL_KEYDOWN),
318 const_iv (SDL_KEYUP), 385 const_iv (SDL_KEYUP),
319 const_iv (SDL_MOUSEMOTION), 386 const_iv (SDL_MOUSEMOTION),
320 const_iv (SDL_MOUSEBUTTONDOWN), 387 const_iv (SDL_MOUSEBUTTONDOWN),
329 const_iv (SDL_EVENT_RESERVEDA), 396 const_iv (SDL_EVENT_RESERVEDA),
330 const_iv (SDL_EVENT_RESERVEDB), 397 const_iv (SDL_EVENT_RESERVEDB),
331 const_iv (SDL_VIDEORESIZE), 398 const_iv (SDL_VIDEORESIZE),
332 const_iv (SDL_VIDEOEXPOSE), 399 const_iv (SDL_VIDEOEXPOSE),
333 const_iv (SDL_USEREVENT), 400 const_iv (SDL_USEREVENT),
401
402 const_iv (SDL_APPINPUTFOCUS),
403 const_iv (SDL_APPMOUSEFOCUS),
404 const_iv (SDL_APPACTIVE),
405
334 const_iv (SDLK_KP0), 406 const_iv (SDLK_KP0),
335 const_iv (SDLK_KP1), 407 const_iv (SDLK_KP1),
336 const_iv (SDLK_KP2), 408 const_iv (SDLK_KP2),
337 const_iv (SDLK_KP3), 409 const_iv (SDLK_KP3),
338 const_iv (SDLK_KP4), 410 const_iv (SDLK_KP4),
393 const_iv (SDLK_BREAK), 465 const_iv (SDLK_BREAK),
394 const_iv (SDLK_MENU), 466 const_iv (SDLK_MENU),
395 const_iv (SDLK_POWER), 467 const_iv (SDLK_POWER),
396 const_iv (SDLK_EURO), 468 const_iv (SDLK_EURO),
397 const_iv (SDLK_UNDO), 469 const_iv (SDLK_UNDO),
470
398 const_iv (KMOD_NONE), 471 const_iv (KMOD_NONE),
472 const_iv (KMOD_SHIFT),
399 const_iv (KMOD_LSHIFT), 473 const_iv (KMOD_LSHIFT),
400 const_iv (KMOD_RSHIFT), 474 const_iv (KMOD_RSHIFT),
475 const_iv (KMOD_CTRL),
401 const_iv (KMOD_LCTRL), 476 const_iv (KMOD_LCTRL),
402 const_iv (KMOD_RCTRL), 477 const_iv (KMOD_RCTRL),
478 const_iv (KMOD_ALT),
403 const_iv (KMOD_LALT), 479 const_iv (KMOD_LALT),
404 const_iv (KMOD_RALT), 480 const_iv (KMOD_RALT),
481 const_iv (KMOD_META),
405 const_iv (KMOD_LMETA), 482 const_iv (KMOD_LMETA),
406 const_iv (KMOD_RMETA), 483 const_iv (KMOD_RMETA),
407 const_iv (KMOD_NUM), 484 const_iv (KMOD_NUM),
408 const_iv (KMOD_CAPS), 485 const_iv (KMOD_CAPS),
409 const_iv (KMOD_MODE), 486 const_iv (KMOD_MODE),
410 const_iv (KMOD_CTRL),
411 const_iv (KMOD_SHIFT),
412 const_iv (KMOD_ALT),
413 const_iv (KMOD_META)
414# undef const_iv 487# undef const_iv
415 }; 488 };
416 489
417 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 490 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
418 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 491 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
492
493 assert (SDLK_MODIFIER_MIN == SDLK_NUMLOCK);
494 assert (SDLK_MODIFIER_MAX == SDLK_COMPOSE);
419} 495}
496
497int
498in_destruct ()
499 CODE:
500 RETVAL = PL_main_cv == Nullcv;
501 OUTPUT:
502 RETVAL
503
504NV floor (NV x)
505
506NV ceil (NV x)
420 507
421void 508void
422pango_init () 509pango_init ()
423 CODE: 510 CODE:
424 // delayed, so it can pick up new fonts added by AddFontResourceEx
425{ 511{
426 {
427 ft2_fontmap = pango_ft2_font_map_new (); 512 opengl_fontmap = pango_opengl_font_map_new ();
428 pango_ft2_font_map_set_default_substitute ((PangoFT2FontMap *)ft2_fontmap, substitute_func, 0, 0); 513 pango_opengl_font_map_set_default_substitute ((PangoOpenGLFontMap *)opengl_fontmap, substitute_func, 0, 0);
429 ft2_context = pango_ft2_font_map_create_context ((PangoFT2FontMap *)ft2_fontmap); 514 opengl_context = pango_opengl_font_map_create_context ((PangoOpenGLFontMap *)opengl_fontmap);
430 }
431 {
432 cairo_font_options_t *fopt = cairo_font_options_create ();
433 cairo_fontmap = pango_cairo_font_map_get_default ();
434 cairo_context = pango_cairo_font_map_create_context ((PangoCairoFontMap *)cairo_fontmap);
435#ifdef _WIN32
436 // cairo looks like shit eaten twice on windows
437 cairo_font_options_set_antialias (fopt, CAIRO_ANTIALIAS_NONE);
438#else
439 cairo_font_options_set_antialias (fopt, CAIRO_ANTIALIAS_GRAY);
440#endif
441 cairo_font_options_set_hint_style (fopt, CAIRO_HINT_STYLE_FULL);
442 cairo_font_options_set_hint_metrics (fopt, CAIRO_HINT_METRICS_ON);
443 pango_cairo_context_set_font_options (cairo_context, fopt);
444 cairo_font_options_destroy (fopt);
445 }
446} 515}
447 516
448int 517int
449SDL_Init (U32 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO) 518SDL_Init (U32 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | PARACHUTE)
450 519
451void 520void
452SDL_Quit () 521SDL_Quit ()
453 522
454void 523void
461 SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 5); 530 SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 5);
462 SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5); 531 SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5);
463 SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, 1); 532 SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, 1);
464 533
465 SDL_GL_SetAttribute (SDL_GL_BUFFER_SIZE, 15); 534 SDL_GL_SetAttribute (SDL_GL_BUFFER_SIZE, 15);
466 SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 16); 535 SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 0);
467 536
468 SDL_GL_SetAttribute (SDL_GL_ACCUM_RED_SIZE, 0); 537 SDL_GL_SetAttribute (SDL_GL_ACCUM_RED_SIZE, 0);
469 SDL_GL_SetAttribute (SDL_GL_ACCUM_GREEN_SIZE, 0); 538 SDL_GL_SetAttribute (SDL_GL_ACCUM_GREEN_SIZE, 0);
470 SDL_GL_SetAttribute (SDL_GL_ACCUM_BLUE_SIZE, 0); 539 SDL_GL_SetAttribute (SDL_GL_ACCUM_BLUE_SIZE, 0);
471 SDL_GL_SetAttribute (SDL_GL_ACCUM_ALPHA_SIZE, 0); 540 SDL_GL_SetAttribute (SDL_GL_ACCUM_ALPHA_SIZE, 0);
472 541
473 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); 542 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
543#if SDL_VERSION_ATLEAST(1,2,10)
544 SDL_GL_SetAttribute (SDL_GL_ACCELERATED_VISUAL, 1);
545 SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 1);
546#endif
474 547
475 SDL_EnableUNICODE (1); 548 SDL_EnableUNICODE (1);
476 SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); 549 SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
477 550
478 m = SDL_ListModes (0, SDL_FULLSCREEN | SDL_OPENGL); 551 m = SDL_ListModes (0, SDL_FULLSCREEN | SDL_OPENGL);
530 case SDL_KEYDOWN: 603 case SDL_KEYDOWN:
531 case SDL_KEYUP: 604 case SDL_KEYUP:
532 hv_store (hv, "state", 5, newSViv (ev.key.state), 0); 605 hv_store (hv, "state", 5, newSViv (ev.key.state), 0);
533 hv_store (hv, "sym", 3, newSViv (ev.key.keysym.sym), 0); 606 hv_store (hv, "sym", 3, newSViv (ev.key.keysym.sym), 0);
534 hv_store (hv, "mod", 3, newSViv (ev.key.keysym.mod), 0); 607 hv_store (hv, "mod", 3, newSViv (ev.key.keysym.mod), 0);
608 hv_store (hv, "cmod", 4, newSViv (SDL_GetModState ()), 0); /* current mode */
535 hv_store (hv, "unicode", 7, newSViv (ev.key.keysym.unicode), 0); 609 hv_store (hv, "unicode", 7, newSViv (ev.key.keysym.unicode), 0);
536 break; 610 break;
537 611
538 case SDL_ACTIVEEVENT: 612 case SDL_ACTIVEEVENT:
539 hv_store (hv, "gain", 4, newSViv (ev.active.gain), 0); 613 hv_store (hv, "gain", 4, newSViv (ev.active.gain), 0);
565 hv_store (hv, "data1", 5, newSViv ((IV)ev.user.data1), 0); 639 hv_store (hv, "data1", 5, newSViv ((IV)ev.user.data1), 0);
566 hv_store (hv, "data2", 5, newSViv ((IV)ev.user.data2), 0); 640 hv_store (hv, "data2", 5, newSViv ((IV)ev.user.data2), 0);
567 break; 641 break;
568 } 642 }
569 643
570 XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv))); 644 XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("CFPlus::UI::Event", 1))));
571 } 645 }
572} 646}
573 647
574int 648int
575Mix_OpenAudio (int frequency = 48000, int format = MIX_DEFAULT_FORMAT, int channels = 1, int chunksize = 2048) 649Mix_OpenAudio (int frequency = 48000, int format = MIX_DEFAULT_FORMAT, int channels = 1, int chunksize = 2048)
589#ifndef _WIN32 663#ifndef _WIN32
590 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof (val)); 664 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof (val));
591#endif 665#endif
592 666
593void 667void
668win32_proxy_info ()
669 PPCODE:
670{
671#ifdef _WIN32
672 char buffer[2048];
673 DWORD buflen;
674
675 EXTEND (SP, 3);
676
677 buflen = sizeof (buffer);
678 if (InternetQueryOption (0, INTERNET_OPTION_PROXY, (void *)buffer, &buflen))
679 if (((INTERNET_PROXY_INFO *)buffer)->dwAccessType == INTERNET_OPEN_TYPE_PROXY)
680 {
681 PUSHs (newSVpv (((INTERNET_PROXY_INFO *)buffer)->lpszProxy, 0));
682
683 buflen = sizeof (buffer);
684 if (InternetQueryOption (0, INTERNET_OPTION_PROXY_USERNAME, (void *)buffer, &buflen))
685 {
686 PUSHs (newSVpv (buffer, 0));
687
688 buflen = sizeof (buffer);
689 if (InternetQueryOption (0, INTERNET_OPTION_PROXY_PASSWORD, (void *)buffer, &buflen))
690 PUSHs (newSVpv (buffer, 0));
691 }
692 }
693#endif
694}
695
696void
594add_font (char *file) 697add_font (char *file)
595 CODE: 698 CODE:
596 FcConfigAppFontAddFile (0, (const FcChar8 *)file); /* no idea wether this is required */ 699 FcConfigAppFontAddFile (0, (const FcChar8 *)file);
597#ifdef _WIN32
598 // cairo... sigh... requires win2000
599 AddFontResourceEx (file, FR_PRIVATE, 0);
600#endif
601 700
602void 701void
603load_image_inline (SV *image_) 702load_image_inline (SV *image_)
604 ALIAS: 703 ALIAS:
605 load_image_file = 1 704 load_image_file = 1
647 746
648 surface2 = SDL_ConvertSurface (surface, &fmt, SDL_SWSURFACE); 747 surface2 = SDL_ConvertSurface (surface, &fmt, SDL_SWSURFACE);
649 748
650 assert (surface2->pitch == surface2->w * 4); 749 assert (surface2->pitch == surface2->w * 4);
651 750
751 SDL_LockSurface (surface2);
652 EXTEND (SP, 5); 752 EXTEND (SP, 6);
653 PUSHs (sv_2mortal (newSViv (surface2->w))); 753 PUSHs (sv_2mortal (newSViv (surface2->w)));
654 PUSHs (sv_2mortal (newSViv (surface2->h))); 754 PUSHs (sv_2mortal (newSViv (surface2->h)));
655 SDL_LockSurface (surface2);
656 PUSHs (sv_2mortal (newSVpvn (surface2->pixels, surface2->h * surface2->pitch))); 755 PUSHs (sv_2mortal (newSVpvn (surface2->pixels, surface2->h * surface2->pitch)));
657 SDL_UnlockSurface (surface2);
658 PUSHs (sv_2mortal (newSViv (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA) ? GL_RGBA : GL_RGB))); 756 PUSHs (sv_2mortal (newSViv (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA) ? GL_RGBA : GL_RGB)));
659 PUSHs (sv_2mortal (newSViv (GL_RGBA))); 757 PUSHs (sv_2mortal (newSViv (GL_RGBA)));
660 PUSHs (sv_2mortal (newSViv (GL_UNSIGNED_BYTE))); 758 PUSHs (sv_2mortal (newSViv (GL_UNSIGNED_BYTE)));
759 SDL_UnlockSurface (surface2);
661 760
662 SDL_FreeSurface (surface); 761 SDL_FreeSurface (surface);
663 SDL_FreeSurface (surface2); 762 SDL_FreeSurface (surface2);
664} 763}
665 764
701 CODE: 800 CODE:
702 fprintf (stderr, "FATAL: %s\n", message); 801 fprintf (stderr, "FATAL: %s\n", message);
703#ifdef _WIN32 802#ifdef _WIN32
704 MessageBox (0, message, "Crossfire+ Fatal Error", MB_OK | MB_ICONERROR); 803 MessageBox (0, message, "Crossfire+ Fatal Error", MB_OK | MB_ICONERROR);
705#endif 804#endif
706 exit (1); 805 _exit (1);
707 806
807void
808_exit (int retval = 0)
809 CODE:
810#ifdef WIN32
811 ExitThread (retval); // unclean, please beam me up
812#else
813 _exit (retval);
814#endif
815
708MODULE = CFClient PACKAGE = CFClient::Font 816MODULE = CFPlus PACKAGE = CFPlus::Font
709 817
710CFClient::Font 818CFPlus::Font
711new_from_file (SV *class, char *path, int id = 0) 819new_from_file (SV *class, char *path, int id = 0)
712 CODE: 820 CODE:
713{ 821{
714 int count; 822 int count;
715 FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)path, id, 0, &count); 823 FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)path, id, 0, &count);
718} 826}
719 OUTPUT: 827 OUTPUT:
720 RETVAL 828 RETVAL
721 829
722void 830void
723DESTROY (CFClient::Font self) 831DESTROY (CFPlus::Font self)
724 CODE: 832 CODE:
725 pango_font_description_free (self); 833 pango_font_description_free (self);
726 834
727void 835void
728make_default (CFClient::Font self) 836make_default (CFPlus::Font self)
729 CODE: 837 CODE:
730 default_font = self; 838 default_font = self;
731 839
732MODULE = CFClient PACKAGE = CFClient::Layout 840MODULE = CFPlus PACKAGE = CFPlus::Layout
733 841
734CFClient::Layout 842void
735new (SV *class, int rgba = 0) 843reset_glyph_cache ()
844 CODE:
845 tc_clear ();
846
847CFPlus::Layout
848new (SV *class)
736 CODE: 849 CODE:
737 New (0, RETVAL, 1, struct cf_layout); 850 New (0, RETVAL, 1, struct cf_layout);
738 851
739 RETVAL->pl = pango_layout_new (rgba ? cairo_context : ft2_context); 852 RETVAL->pl = pango_layout_new (opengl_context);
740 RETVAL->rgba = rgba;
741 RETVAL->r = 1.; 853 RETVAL->r = 1.;
742 RETVAL->g = 1.; 854 RETVAL->g = 1.;
743 RETVAL->b = 1.; 855 RETVAL->b = 1.;
744 RETVAL->a = 1.; 856 RETVAL->a = 1.;
745 RETVAL->base_height = MIN_FONT_HEIGHT; 857 RETVAL->base_height = MIN_FONT_HEIGHT;
749 layout_update_font (RETVAL); 861 layout_update_font (RETVAL);
750 OUTPUT: 862 OUTPUT:
751 RETVAL 863 RETVAL
752 864
753void 865void
754DESTROY (CFClient::Layout self) 866DESTROY (CFPlus::Layout self)
755 CODE: 867 CODE:
756 g_object_unref (self->pl); 868 g_object_unref (self->pl);
757 Safefree (self); 869 Safefree (self);
758 870
759int
760is_rgba (CFClient::Layout self)
761 CODE:
762 RETVAL = self->rgba;
763 OUTPUT:
764 RETVAL
765
766void 871void
767set_text (CFClient::Layout self, SV *text_) 872set_text (CFPlus::Layout self, SV *text_)
768 CODE: 873 CODE:
769{ 874{
770 STRLEN textlen; 875 STRLEN textlen;
771 char *text = SvPVutf8 (text_, textlen); 876 char *text = SvPVutf8 (text_, textlen);
772 877
773 pango_layout_set_text (self->pl, text, textlen); 878 pango_layout_set_text (self->pl, text, textlen);
774} 879}
775 880
776void 881void
777set_markup (CFClient::Layout self, SV *text_) 882set_markup (CFPlus::Layout self, SV *text_)
778 CODE: 883 CODE:
779{ 884{
780 STRLEN textlen; 885 STRLEN textlen;
781 char *text = SvPVutf8 (text_, textlen); 886 char *text = SvPVutf8 (text_, textlen);
782 887
783 pango_layout_set_markup (self->pl, text, textlen); 888 pango_layout_set_markup (self->pl, text, textlen);
784} 889}
785 890
891void
892set_shapes (CFPlus::Layout self, ...)
893 CODE:
894{
895 PangoAttrList *attrs = 0;
896 const char *text = pango_layout_get_text (self->pl);
897 const char *pos = text;
898 int arg = 4;
899
900 while (arg < items && (pos = strstr (pos, OBJ_STR)))
901 {
902 PangoRectangle inkrect, rect;
903 PangoAttribute *attr;
904
905 int x = SvIV (ST (arg - 3));
906 int y = SvIV (ST (arg - 2));
907 int w = SvIV (ST (arg - 1));
908 int h = SvIV (ST (arg ));
909
910 inkrect.x = 0;
911 inkrect.y = 0;
912 inkrect.width = 0;
913 inkrect.height = 0;
914
915 rect.x = x * PANGO_SCALE;
916 rect.y = y * PANGO_SCALE;
917 rect.width = w * PANGO_SCALE;
918 rect.height = h * PANGO_SCALE;
919
920 if (!attrs)
921 attrs = pango_layout_get_attributes (self->pl);
922
923 attr = pango_attr_shape_new (&inkrect, &rect);
924 attr->start_index = pos - text;
925 attr->end_index = attr->start_index + sizeof (OBJ_STR) - 1;
926 pango_attr_list_insert (attrs, attr);
927
928 arg += 4;
929 pos += sizeof (OBJ_STR) - 1;
930 }
931
932 if (attrs)
933 pango_layout_set_attributes (self->pl, attrs);
934}
935
936void
937get_shapes (CFPlus::Layout self)
938 PPCODE:
939{
940 PangoLayoutIter *iter = pango_layout_get_iter (self->pl);
941
942 do
943 {
944 PangoLayoutRun *run = pango_layout_iter_get_run (iter);
945
946 if (run && shape_attr_p (run))
947 {
948 PangoRectangle extents;
949 pango_layout_iter_get_run_extents (iter, 0, &extents);
950
951 EXTEND (SP, 2);
952 PUSHs (sv_2mortal (newSViv (PANGO_PIXELS (extents.x))));
953 PUSHs (sv_2mortal (newSViv (PANGO_PIXELS (extents.y))));
954 }
955 }
956 while (pango_layout_iter_next_run (iter));
957
958 pango_layout_iter_free (iter);
959}
960
961int
962has_wrapped (CFPlus::Layout self)
963 CODE:
964{
965 int lines = 1;
966 const char *text = pango_layout_get_text (self->pl);
967
968 while (*text)
969 lines += *text++ == '\n';
970
971 RETVAL = lines < pango_layout_get_line_count (self->pl);
972}
973 OUTPUT:
974 RETVAL
975
786SV * 976SV *
787get_text (CFClient::Layout self) 977get_text (CFPlus::Layout self)
788 CODE: 978 CODE:
789 RETVAL = newSVpv (pango_layout_get_text (self->pl), 0); 979 RETVAL = newSVpv (pango_layout_get_text (self->pl), 0);
790 sv_utf8_decode (RETVAL); 980 sv_utf8_decode (RETVAL);
791 OUTPUT: 981 OUTPUT:
792 RETVAL 982 RETVAL
793 983
794void 984void
795set_foreground (CFClient::Layout self, float r, float g, float b, float a = 1.) 985set_foreground (CFPlus::Layout self, float r, float g, float b, float a = 1.)
796 CODE: 986 CODE:
797 self->r = r; 987 self->r = r;
798 self->g = g; 988 self->g = g;
799 self->b = b; 989 self->b = b;
800 self->a = a; 990 self->a = a;
801 991
802void 992void
803set_font (CFClient::Layout self, CFClient::Font font = 0) 993set_font (CFPlus::Layout self, CFPlus::Font font = 0)
804 CODE: 994 CODE:
805 if (self->font != font) 995 if (self->font != font)
806 { 996 {
807 self->font = font; 997 self->font = font;
808 layout_update_font (self); 998 layout_update_font (self);
809 } 999 }
810 1000
811void 1001void
812set_height (CFClient::Layout self, int base_height) 1002set_height (CFPlus::Layout self, int base_height)
813 CODE: 1003 CODE:
814 if (self->base_height != base_height) 1004 if (self->base_height != base_height)
815 { 1005 {
816 self->base_height = base_height; 1006 self->base_height = base_height;
817 layout_update_font (self); 1007 layout_update_font (self);
818 } 1008 }
819 1009
820void 1010void
821set_width (CFClient::Layout self, int max_width = -1) 1011set_width (CFPlus::Layout self, int max_width = -1)
822 CODE: 1012 CODE:
823 pango_layout_set_width (self->pl, max_width < 0 ? max_width : max_width * PANGO_SCALE); 1013 pango_layout_set_width (self->pl, max_width < 0 ? max_width : max_width * PANGO_SCALE);
824 1014
825void 1015void
826set_indent (CFClient::Layout self, int indent) 1016set_indent (CFPlus::Layout self, int indent)
827 CODE: 1017 CODE:
828 pango_layout_set_indent (self->pl, indent * PANGO_SCALE); 1018 pango_layout_set_indent (self->pl, indent * PANGO_SCALE);
829 1019
830void 1020void
831set_spacing (CFClient::Layout self, int spacing) 1021set_spacing (CFPlus::Layout self, int spacing)
832 CODE: 1022 CODE:
833 pango_layout_set_spacing (self->pl, spacing * PANGO_SCALE); 1023 pango_layout_set_spacing (self->pl, spacing * PANGO_SCALE);
834 1024
835void 1025void
836set_ellipsise (CFClient::Layout self, int ellipsise) 1026set_ellipsise (CFPlus::Layout self, int ellipsise)
837 CODE: 1027 CODE:
838 pango_layout_set_ellipsize (self->pl, 1028 pango_layout_set_ellipsize (self->pl,
839 ellipsise == 1 ? PANGO_ELLIPSIZE_START 1029 ellipsise == 1 ? PANGO_ELLIPSIZE_START
840 : ellipsise == 2 ? PANGO_ELLIPSIZE_MIDDLE 1030 : ellipsise == 2 ? PANGO_ELLIPSIZE_MIDDLE
841 : ellipsise == 3 ? PANGO_ELLIPSIZE_END 1031 : ellipsise == 3 ? PANGO_ELLIPSIZE_END
842 : PANGO_ELLIPSIZE_NONE 1032 : PANGO_ELLIPSIZE_NONE
843 ); 1033 );
844 1034
845void 1035void
846set_single_paragraph_mode (CFClient::Layout self, int spm) 1036set_single_paragraph_mode (CFPlus::Layout self, int spm)
847 CODE: 1037 CODE:
848 pango_layout_set_single_paragraph_mode (self->pl, !!spm); 1038 pango_layout_set_single_paragraph_mode (self->pl, !!spm);
849 1039
850void 1040void
851size (CFClient::Layout self) 1041size (CFPlus::Layout self)
852 PPCODE: 1042 PPCODE:
853{ 1043{
854 int w, h; 1044 int w, h;
855 1045
856 layout_get_pixel_size (self, &w, &h); 1046 layout_get_pixel_size (self, &w, &h);
859 PUSHs (sv_2mortal (newSViv (w))); 1049 PUSHs (sv_2mortal (newSViv (w)));
860 PUSHs (sv_2mortal (newSViv (h))); 1050 PUSHs (sv_2mortal (newSViv (h)));
861} 1051}
862 1052
863int 1053int
1054descent (CFPlus::Layout self)
1055 CODE:
1056{
1057 PangoRectangle rect;
1058 PangoLayoutLine *line = pango_layout_get_line (self->pl, 0);
1059 pango_layout_line_get_pixel_extents (line, 0, &rect);
1060 RETVAL = PANGO_DESCENT (rect);
1061}
1062 OUTPUT:
1063 RETVAL
1064
1065int
864xy_to_index (CFClient::Layout self, int x, int y) 1066xy_to_index (CFPlus::Layout self, int x, int y)
865 CODE: 1067 CODE:
866{ 1068{
867 int index, trailing; 1069 int index, trailing;
868 pango_layout_xy_to_index (self->pl, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing); 1070 pango_layout_xy_to_index (self->pl, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing);
869 RETVAL = index; 1071 RETVAL = index + trailing;
870} 1072}
871 OUTPUT: 1073 OUTPUT:
872 RETVAL 1074 RETVAL
873 1075
874void 1076void
875cursor_pos (CFClient::Layout self, int index) 1077cursor_pos (CFPlus::Layout self, int index)
876 PPCODE: 1078 PPCODE:
877{ 1079{
878 PangoRectangle strong_pos; 1080 PangoRectangle strong_pos;
879 pango_layout_get_cursor_pos (self->pl, index, &strong_pos, 0); 1081 pango_layout_get_cursor_pos (self->pl, index, &strong_pos, 0);
880 1082
883 PUSHs (sv_2mortal (newSViv (strong_pos.y / PANGO_SCALE))); 1085 PUSHs (sv_2mortal (newSViv (strong_pos.y / PANGO_SCALE)));
884 PUSHs (sv_2mortal (newSViv (strong_pos.height / PANGO_SCALE))); 1086 PUSHs (sv_2mortal (newSViv (strong_pos.height / PANGO_SCALE)));
885} 1087}
886 1088
887void 1089void
888render (CFClient::Layout self) 1090index_to_line_x (CFPlus::Layout self, int index, int trailing = 0)
889 PPCODE: 1091 PPCODE:
890{ 1092{
891 SV *retval; 1093 int line, x;
892 int w, h;
893 1094
894 layout_get_pixel_size (self, &w, &h); 1095 pango_layout_index_to_line_x (self->pl, index, trailing, &line, &x);
1096 /* pango bug: line is between 1..numlines, not 0..numlines-1 */
895 1097
896 if (self->rgba)
897 {
898 cairo_surface_t *surface;
899 cairo_t *cairo;
900
901 retval = newSV (w * h * 4);
902 SvPOK_only (retval);
903 SvCUR_set (retval, w * h * 4);
904
905 memset (SvPVX (retval), 0, w * h * 4);
906
907 surface = cairo_image_surface_create_for_data (
908 (void*)SvPVX (retval), CAIRO_FORMAT_ARGB32, w, h, w * 4);
909 cairo = cairo_create (surface);
910 cairo_set_source_rgba (cairo, self->r, self->g, self->b, self->a);
911
912 pango_cairo_show_layout (cairo, self->pl);
913
914 cairo_destroy (cairo);
915 cairo_surface_destroy (surface);
916
917 // what a mess, and its premultiplied, too :(
918 {
919 uint32_t *p = (uint32_t *)SvPVX (retval);
920 uint32_t *e = p + w * h;
921
922 while (p < e)
923 {
924 uint32_t rgba = *p;
925 rgba = (rgba >> 24) | (rgba << 8);
926#if 0
927#ifdef _WIN32
928 {//D
929 uint8_t r = rgba >> 24;
930 uint8_t g = rgba >> 16;
931 uint8_t b = rgba >> 8;
932 uint8_t a = rgba >> 0;
933
934 rgba = (rgba & 0xffffff00) | a;
935 }
936#endif
937#endif
938 rgba = SDL_SwapBE32 (rgba);
939 *p++ = rgba;
940 }
941 }
942
943 EXTEND (SP, 5); 1098 EXTEND (SP, 2);
944 PUSHs (sv_2mortal (newSViv (w))); 1099 PUSHs (sv_2mortal (newSViv (line - 1)));
1100 PUSHs (sv_2mortal (newSViv (x / PANGO_SCALE)));
1101}
1102
1103void
1104line_x_to_index (CFPlus::Layout self, int line, int x)
1105 PPCODE:
1106{
1107 PangoLayoutLine *lp;
1108 int index, trailing;
1109
1110 if (line < 0)
1111 XSRETURN_EMPTY;
1112
1113 if (!(lp = pango_layout_get_line (self->pl, line)))
1114 XSRETURN_EMPTY; /* do better */
1115
1116 pango_layout_line_x_to_index (lp, x * PANGO_SCALE, &index, &trailing);
1117
1118 EXTEND (SP, 2);
1119 if (GIMME_V == G_SCALAR)
945 PUSHs (sv_2mortal (newSViv (h))); 1120 PUSHs (sv_2mortal (newSViv (index + trailing)));
946 PUSHs (sv_2mortal (retval));
947 PUSHs (sv_2mortal (newSViv (GL_RGBA)));
948 PUSHs (sv_2mortal (newSViv (GL_RGBA)));
949 }
950 else 1121 else
951 { 1122 {
952 FT_Bitmap bitmap;
953
954 retval = newSV (w * h);
955 SvPOK_only (retval);
956 SvCUR_set (retval, w * h);
957
958 bitmap.rows = h;
959 bitmap.width = w;
960 bitmap.pitch = w;
961 bitmap.buffer = (unsigned char*)SvPVX (retval);
962 bitmap.num_grays = 256;
963 bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
964
965 memset (bitmap.buffer, 0, w * h);
966
967 pango_ft2_render_layout (&bitmap, self->pl, 0 * PANGO_SCALE, 0 * PANGO_SCALE);
968
969 EXTEND (SP, 5);
970 PUSHs (sv_2mortal (newSViv (w))); 1123 PUSHs (sv_2mortal (newSViv (index)));
971 PUSHs (sv_2mortal (newSViv (h))); 1124 PUSHs (sv_2mortal (newSViv (trailing)));
972 PUSHs (sv_2mortal (retval));
973 PUSHs (sv_2mortal (newSViv (GL_ALPHA)));
974 PUSHs (sv_2mortal (newSViv (GL_ALPHA)));
975 } 1125 }
976} 1126}
977 1127
1128void
1129render (CFPlus::Layout self, float x, float y, int flags = 0)
1130 PPCODE:
1131 pango_opengl_render_layout_subpixel (
1132 self->pl,
1133 x * PANGO_SCALE, y * PANGO_SCALE,
1134 self->r, self->g, self->b, self->a,
1135 flags
1136 );
1137
978MODULE = CFClient PACKAGE = CFClient::Texture 1138MODULE = CFPlus PACKAGE = CFPlus::Texture
979 1139
980void 1140void
1141pad2pot (SV *data_, SV *w_, SV *h_)
1142 CODE:
1143{
1144 int ow = SvIV (w_);
1145 int oh = SvIV (h_);
1146
1147 if (ow && oh)
1148 {
1149 int nw = minpot (ow);
1150 int nh = minpot (oh);
1151
1152 if (nw != ow || nh != oh)
1153 {
1154 if (SvOK (data_))
1155 {
1156 STRLEN datalen;
1157 char *data = SvPVbyte (data_, datalen);
1158 int bpp = datalen / (ow * oh);
1159 SV *result_ = sv_2mortal (newSV (nw * nh * bpp));
1160
1161 SvPOK_only (result_);
1162 SvCUR_set (result_, nw * nh * bpp);
1163
1164 memset (SvPVX (result_), 0, nw * nh * bpp);
1165 while (oh--)
1166 memcpy (SvPVX (result_) + oh * nw * bpp, data + oh * ow * bpp, ow * bpp);
1167
1168 sv_setsv (data_, result_);
1169 }
1170
1171 sv_setiv (w_, nw);
1172 sv_setiv (h_, nh);
1173 }
1174 }
1175}
1176
1177void
981draw_quad (SV *self, float x, float y, float w = 0, float h = 0) 1178draw_quad (SV *self, float x, float y, float w = 0., float h = 0.)
982 PROTOTYPE: $$$;$$ 1179 PROTOTYPE: $$$;$$
983 ALIAS: 1180 ALIAS:
984 draw_quad_alpha = 1 1181 draw_quad_alpha = 1
985 draw_quad_alpha_premultiplied = 2 1182 draw_quad_alpha_premultiplied = 2
986 CODE: 1183 CODE:
1024 glDisable (GL_ALPHA_TEST); 1221 glDisable (GL_ALPHA_TEST);
1025 glDisable (GL_BLEND); 1222 glDisable (GL_BLEND);
1026 } 1223 }
1027} 1224}
1028 1225
1029MODULE = CFClient PACKAGE = CFClient::Map 1226MODULE = CFPlus PACKAGE = CFPlus::Map
1030 1227
1031CFClient::Map 1228CFPlus::Map
1032new (SV *class, int map_width, int map_height) 1229new (SV *class)
1033 CODE: 1230 CODE:
1034 New (0, RETVAL, 1, struct map); 1231 New (0, RETVAL, 1, struct map);
1035 RETVAL->x = 0; 1232 RETVAL->x = 0;
1036 RETVAL->y = 0; 1233 RETVAL->y = 0;
1037 RETVAL->w = map_width; 1234 RETVAL->w = 0;
1038 RETVAL->h = map_height; 1235 RETVAL->h = 0;
1039 RETVAL->ox = 0; 1236 RETVAL->ox = 0;
1040 RETVAL->oy = 0; 1237 RETVAL->oy = 0;
1041 RETVAL->faces = 8192; 1238 RETVAL->faces = 8192;
1042 Newz (0, RETVAL->face, RETVAL->faces, mapface); 1239 Newz (0, RETVAL->face, RETVAL->faces, mapface);
1043 RETVAL->texs = 8192; 1240 RETVAL->texs = 8192;
1046 RETVAL->row = 0; 1243 RETVAL->row = 0;
1047 OUTPUT: 1244 OUTPUT:
1048 RETVAL 1245 RETVAL
1049 1246
1050void 1247void
1051DESTROY (CFClient::Map self) 1248DESTROY (CFPlus::Map self)
1052 CODE: 1249 CODE:
1053{ 1250{
1054 map_clear (self); 1251 map_clear (self);
1055 Safefree (self->face); 1252 Safefree (self->face);
1253 Safefree (self->tex);
1056 Safefree (self); 1254 Safefree (self);
1057} 1255}
1058 1256
1059void 1257void
1258resize (CFPlus::Map self, int map_width, int map_height)
1259 CODE:
1260 self->w = map_width;
1261 self->h = map_height;
1262
1263void
1060clear (CFClient::Map self) 1264clear (CFPlus::Map self)
1061 CODE: 1265 CODE:
1062 map_clear (self); 1266 map_clear (self);
1063 1267
1064void 1268void
1065set_face (CFClient::Map self, int face, int texid) 1269set_face (CFPlus::Map self, int face, int texid)
1066 CODE: 1270 CODE:
1067{ 1271{
1068 while (self->faces <= face) 1272 while (self->faces <= face)
1069 { 1273 {
1070 Append (mapface, self->face, self->faces, self->faces); 1274 Append (mapface, self->face, self->faces, self->faces);
1073 1277
1074 self->face [face] = texid; 1278 self->face [face] = texid;
1075} 1279}
1076 1280
1077void 1281void
1078set_texture (CFClient::Map self, int texid, int name, int w, int h, float s, float t, int r, int g, int b, int a) 1282set_texture (CFPlus::Map self, int texid, int name, int w, int h, float s, float t, int r, int g, int b, int a)
1079 CODE: 1283 CODE:
1080{ 1284{
1081 while (self->texs <= texid) 1285 while (self->texs <= texid)
1082 { 1286 {
1083 Append (maptex, self->tex, self->texs, self->texs); 1287 Append (maptex, self->tex, self->texs, self->texs);
1107 // from transparent color bleeding and ugly wrapping effects. 1311 // from transparent color bleeding and ugly wrapping effects.
1108 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1312 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1109} 1313}
1110 1314
1111int 1315int
1112ox (CFClient::Map self) 1316ox (CFPlus::Map self)
1113 ALIAS: 1317 ALIAS:
1114 oy = 1 1318 oy = 1
1115 x = 2 1319 x = 2
1116 y = 3 1320 y = 3
1117 w = 4 1321 w = 4
1128 } 1332 }
1129 OUTPUT: 1333 OUTPUT:
1130 RETVAL 1334 RETVAL
1131 1335
1132void 1336void
1133scroll (CFClient::Map self, int dx, int dy) 1337scroll (CFPlus::Map self, int dx, int dy)
1134 CODE: 1338 CODE:
1135{ 1339{
1136 if (dx > 0) 1340 if (dx > 0)
1137 map_blank (self, self->x, self->y, dx - 1, self->h); 1341 map_blank (self, self->x, self->y, dx, self->h);
1138 else if (dx < 0) 1342 else if (dx < 0)
1139 map_blank (self, self->x + self->w + dx + 1, self->y, 1 - dx, self->h); 1343 map_blank (self, self->x + self->w + dx + 1, self->y, -dx, self->h);
1140 1344
1141 if (dy > 0) 1345 if (dy > 0)
1142 map_blank (self, self->x, self->y, self->w, dy - 1); 1346 map_blank (self, self->x, self->y, self->w, dy);
1143 else if (dy < 0) 1347 else if (dy < 0)
1144 map_blank (self, self->x, self->y + self->h + dy + 1, self->w, 1 - dy); 1348 map_blank (self, self->x, self->y + self->h + dy + 1, self->w, -dy);
1145 1349
1146 self->ox += dx; self->x += dx; 1350 self->ox += dx; self->x += dx;
1147 self->oy += dy; self->y += dy; 1351 self->oy += dy; self->y += dy;
1148 1352
1149 while (self->y < 0) 1353 while (self->y < 0)
1154 self->y += MAP_EXTEND_Y; 1358 self->y += MAP_EXTEND_Y;
1155 } 1359 }
1156} 1360}
1157 1361
1158void 1362void
1159map1a_update (CFClient::Map self, SV *data_) 1363map1a_update (CFPlus::Map self, SV *data_, int extmap)
1160 CODE: 1364 CODE:
1161{ 1365{
1162 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_); 1366 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_);
1163 uint8_t *data_end = (uint8_t *)SvEND (data_); 1367 uint8_t *data_end = (uint8_t *)SvEND (data_);
1164 mapcell *cell; 1368 mapcell *cell;
1165 int x, y, flags; 1369 int x, y, flags;
1166 1370
1167 while (data < data_end) 1371 while (data < data_end - 1)
1168 { 1372 {
1169 flags = (data [0] << 8) + data [1]; data += 2; 1373 flags = (data [0] << 8) + data [1]; data += 2;
1170 1374
1171 x = ((flags >> 10) & 63) + self->x; 1375 x = self->x + ((flags >> 10) & 63);
1172 y = ((flags >> 4) & 63) + self->y; 1376 y = self->y + ((flags >> 4) & 63);
1173 1377
1174 cell = map_get_cell (self, x, y); 1378 cell = map_get_cell (self, x, y);
1175 1379
1176 if (flags & 15) 1380 if (flags & 15)
1177 { 1381 {
1178 if (cell->darkness < 0) 1382 if (!cell->darkness)
1179 { 1383 {
1384 memset (cell, 0, sizeof (*cell));
1180 cell->darkness = 0; 1385 cell->darkness = 256;
1181 cell->face [0] = 0;
1182 cell->face [1] = 0;
1183 cell->face [2] = 0;
1184 } 1386 }
1185 1387
1186 cell->darkness = flags & 8 ? *data++ : 255;
1187
1188 //TODO: don't trust server data to be in-range(!) 1388 //TODO: don't trust server data to be in-range(!)
1389
1390 if (flags & 8)
1391 {
1392 if (extmap)
1393 {
1394 uint8_t ext, cmd;
1395
1396 do
1397 {
1398 ext = *data++;
1399 cmd = ext & 0x3f;
1400
1401 if (cmd < 4)
1402 cell->darkness = 255 - ext * 64 + 1;
1403 else if (cmd == 5) // health
1404 {
1405 cell->stat_width = 1;
1406 cell->stat_hp = *data++;
1407 }
1408 else if (cmd == 6) // monster width
1409 cell->stat_width = *data++ + 1;
1410 else if (cmd == 0x47) // monster width
1411 {
1412 if (*data == 4)
1413 ; // decode player tag
1414
1415 data += *data + 1;
1416 }
1417 else if (cmd == 8) // cell flags
1418 cell->flags = *data++;
1419 else if (ext & 0x40) // unknown, multibyte => skip
1420 data += *data + 1;
1421 else
1422 data++;
1423 }
1424 while (ext & 0x80);
1425 }
1426 else
1427 cell->darkness = *data++ + 1;
1428 }
1189 1429
1190 if (flags & 4) 1430 if (flags & 4)
1191 { 1431 {
1192 cell->face [0] = self->face [(data [0] << 8) + data [1]]; data += 2; 1432 cell->face [0] = self->face [(data [0] << 8) + data [1]]; data += 2;
1193 } 1433 }
1201 { 1441 {
1202 cell->face [2] = self->face [(data [0] << 8) + data [1]]; data += 2; 1442 cell->face [2] = self->face [(data [0] << 8) + data [1]]; data += 2;
1203 } 1443 }
1204 } 1444 }
1205 else 1445 else
1206 cell->darkness = -1; 1446 cell->darkness = 0;
1207 } 1447 }
1208} 1448}
1209 1449
1210SV * 1450SV *
1211mapmap (CFClient::Map self, int x0, int y0, int w, int h) 1451mapmap (CFPlus::Map self, int x0, int y0, int w, int h)
1212 CODE: 1452 CODE:
1213{ 1453{
1214 int x1, x; 1454 int x1, x;
1215 int y1, y; 1455 int y1, y;
1216 int z; 1456 int z;
1266} 1506}
1267 OUTPUT: 1507 OUTPUT:
1268 RETVAL 1508 RETVAL
1269 1509
1270void 1510void
1271draw (CFClient::Map self, int shift_x, int shift_y, int x0, int y0, int sw, int sh) 1511draw (CFPlus::Map self, int mx, int my, int sw, int sh)
1272 PPCODE: 1512 CODE:
1273{ 1513{
1274 int vx, vy;
1275 int x, y, z; 1514 int x, y, z;
1276 int last_name; 1515 int last_name;
1277 mapface face; 1516 mapface face;
1278 int sw4 = (sw + 3) & ~3;
1279 SV *darkness_sv = sv_2mortal (newSV (sw4 * sh));
1280 uint8_t *darkness = (uint8_t *)SvPVX (darkness_sv);
1281
1282 memset (darkness, 255, sw4 * sh);
1283 SvPOK_only (darkness_sv);
1284 SvCUR_set (darkness_sv, sw4 * sh);
1285
1286 vx = self->x + (self->w - sw) / 2 - shift_x;
1287 vy = self->y + (self->h - sh) / 2 - shift_y;
1288
1289 /*
1290 int vx = self->vx = self->w >= sw
1291 ? self->x + (self->w - sw) / 2
1292 : MIN (self->x, MAX (self->x + self->w - sw + 1, self->vx));
1293
1294 int vy = self->vy = self->h >= sh
1295 ? self->y + (self->h - sh) / 2
1296 : MIN (self->y, MAX (self->y + self->h - sh + 1, self->vy));
1297 */
1298 1517
1299 glColor4ub (255, 255, 255, 255); 1518 glColor4ub (255, 255, 255, 255);
1300 1519
1520 glEnable (GL_BLEND);
1301 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1521 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1302 glEnable (GL_BLEND);
1303 glEnable (GL_TEXTURE_2D); 1522 glEnable (GL_TEXTURE_2D);
1304 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1523 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1305 1524
1306 glBegin (GL_QUADS); 1525 glBegin (GL_QUADS);
1307 1526
1308 last_name = 0; 1527 last_name = 0;
1309 1528
1529 mx += self->x;
1530 my += self->y;
1531
1310 for (z = 0; z < 3; z++) 1532 for (z = 0; z < 3; z++)
1311 for (y = 0; y < sh; y++) 1533 for (y = 0; y < sh; y++)
1312 if (0 <= y + vy && y + vy < self->rows) 1534 if (0 <= y + my && y + my < self->rows)
1313 { 1535 {
1314 maprow *row = self->row + (y + vy); 1536 maprow *row = self->row + (y + my);
1315 1537
1316 for (x = 0; x < sw; x++) 1538 for (x = 0; x < sw; x++)
1317 if (row->c0 <= x + vx && x + vx < row->c1) 1539 if (row->c0 <= x + mx && x + mx < row->c1)
1318 { 1540 {
1319 mapcell *cell = row->col + (x + vx - row->c0); 1541 mapcell *cell = row->col + (x + mx - row->c0);
1320
1321 darkness[y * sw4 + x] = cell->darkness < 0
1322 ? 255 - FOW_DARKNESS
1323 : 255 - cell->darkness;
1324 1542
1325 face = cell->face [z]; 1543 face = cell->face [z];
1326 1544
1327 if (face) 1545 if (face && face < self->texs)
1328 { 1546 {
1329 maptex tex = self->tex [face]; 1547 maptex tex = self->tex [face];
1330
1331 int px = (x + 1) * 32 - tex.w; 1548 int px = (x + 1) * 32 - tex.w;
1332 int py = (y + 1) * 32 - tex.h; 1549 int py = (y + 1) * 32 - tex.h;
1333 1550
1334 if (last_name != tex.name) 1551 if (last_name != tex.name)
1335 { 1552 {
1336 glEnd (); 1553 glEnd ();
1337 last_name = tex.name;
1338 glBindTexture (GL_TEXTURE_2D, last_name); 1554 glBindTexture (GL_TEXTURE_2D, last_name = tex.name);
1339 glBegin (GL_QUADS); 1555 glBegin (GL_QUADS);
1340 } 1556 }
1341 1557
1342 glTexCoord2f (0 , 0 ); glVertex2f (px , py ); 1558 glTexCoord2f (0 , 0 ); glVertex2f (px , py );
1343 glTexCoord2f (0 , tex.t); glVertex2f (px , py + tex.h); 1559 glTexCoord2f (0 , tex.t); glVertex2f (px , py + tex.h);
1344 glTexCoord2f (tex.s, tex.t); glVertex2f (px + tex.w, py + tex.h); 1560 glTexCoord2f (tex.s, tex.t); glVertex2f (px + tex.w, py + tex.h);
1345 glTexCoord2f (tex.s, 0 ); glVertex2f (px + tex.w, py ); 1561 glTexCoord2f (tex.s, 0 ); glVertex2f (px + tex.w, py );
1346 } 1562 }
1563
1564 if (cell->flags && z == 2)
1565 {
1566 if (cell->flags & 1)
1567 {
1568 maptex tex = self->tex [1];
1569 int px = (x + 1) * 32 - tex.w + 2;
1570 int py = (y + 1) * 32 - tex.h - 6;
1571
1572 glEnd ();
1573 glBindTexture (GL_TEXTURE_2D, last_name = tex.name);
1574 glBegin (GL_QUADS);
1575
1576 glTexCoord2f (0 , 0 ); glVertex2f (px , py );
1577 glTexCoord2f (0 , tex.t); glVertex2f (px , py + tex.h);
1578 glTexCoord2f (tex.s, tex.t); glVertex2f (px + tex.w, py + tex.h);
1579 glTexCoord2f (tex.s, 0 ); glVertex2f (px + tex.w, py );
1580 }
1581 }
1347 } 1582 }
1348 } 1583 }
1349 1584
1350 glEnd (); 1585 glEnd ();
1351 1586
1352 glDisable (GL_TEXTURE_2D); 1587 glDisable (GL_TEXTURE_2D);
1353 glDisable (GL_BLEND); 1588 glDisable (GL_BLEND);
1589
1590 // top layer: overlays such as the health bar
1591 for (y = 0; y < sh; y++)
1592 if (0 <= y + my && y + my < self->rows)
1593 {
1594 maprow *row = self->row + (y + my);
1595
1596 for (x = 0; x < sw; x++)
1597 if (row->c0 <= x + mx && x + mx < row->c1)
1598 {
1599 mapcell *cell = row->col + (x + mx - row->c0);
1600
1601 int px = x * 32;
1602 int py = y * 32;
1603
1604 if (cell->stat_hp)
1605 {
1606 int width = cell->stat_width * 32;
1607 int thick = sh / 28 + 1 + cell->stat_width;
1608
1609 glColor3ub (0, 0, 0);
1610 glRectf (px + 1, py - thick - 2,
1611 px + width - 1, py);
1612
1613 glColor3ub (cell->stat_hp, 255 - cell->stat_hp, 0);
1614 glRectf (px + 2,
1615 py - thick - 1,
1616 px + width - 2 - cell->stat_hp * (width - 4) / 255, py - 1);
1617 }
1618 }
1619 }
1620}
1621
1622void
1623draw_magicmap (CFPlus::Map self, int dx, int dy, int w, int h, unsigned char *data)
1624 CODE:
1625{
1626 static float color[16][3] = {
1627 { 0.00F, 0.00F, 0.00F },
1628 { 1.00F, 1.00F, 1.00F },
1629 { 0.00F, 0.00F, 0.55F },
1630 { 1.00F, 0.00F, 0.00F },
1631
1632 { 1.00F, 0.54F, 0.00F },
1633 { 0.11F, 0.56F, 1.00F },
1634 { 0.93F, 0.46F, 0.00F },
1635 { 0.18F, 0.54F, 0.34F },
1636
1637 { 0.56F, 0.73F, 0.56F },
1638 { 0.80F, 0.80F, 0.80F },
1639 { 0.55F, 0.41F, 0.13F },
1640 { 0.99F, 0.77F, 0.26F },
1641
1642 { 0.74F, 0.65F, 0.41F },
1643
1644 { 0.00F, 1.00F, 1.00F },
1645 { 1.00F, 0.00F, 1.00F },
1646 { 1.00F, 1.00F, 0.00F },
1647 };
1648
1649 int x, y;
1650
1651 glEnable (GL_TEXTURE_2D);
1652 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1653 glEnable (GL_BLEND);
1654 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1655 glBegin (GL_QUADS);
1656
1657 for (y = 0; y < h; y++)
1658 for (x = 0; x < w; x++)
1659 {
1660 unsigned char m = data [x + y * w];
1661
1662 if (m)
1663 {
1664 float *c = color [m & 15];
1665
1666 float tx1 = m & 0x40 ? 0.5 : 0.;
1667 float tx2 = tx1 + 0.5;
1668
1669 glColor4f (c[0], c[1], c[2], 0.75);
1670 glTexCoord2f (tx1, 0.); glVertex2i (x , y );
1671 glTexCoord2f (tx1, 1.); glVertex2i (x , y + 1);
1672 glTexCoord2f (tx2, 1.); glVertex2i (x + 1, y + 1);
1673 glTexCoord2f (tx2, 0.); glVertex2i (x + 1, y );
1674 }
1675 }
1676
1677 glEnd ();
1678 glDisable (GL_BLEND);
1679 glDisable (GL_TEXTURE_2D);
1680}
1681
1682void
1683fow_texture (CFPlus::Map self, int mx, int my, int sw, int sh)
1684 PPCODE:
1685{
1686 int x, y;
1687 int sw4 = (sw + 3) & ~3;
1688 SV *darkness_sv = sv_2mortal (newSV (sw4 * sh));
1689 uint8_t *darkness = (uint8_t *)SvPVX (darkness_sv);
1690
1691 memset (darkness, 255, sw4 * sh);
1692 SvPOK_only (darkness_sv);
1693 SvCUR_set (darkness_sv, sw4 * sh);
1694
1695 mx += self->x;
1696 my += self->y;
1697
1698 for (y = 0; y < sh; y++)
1699 if (0 <= y + my && y + my < self->rows)
1700 {
1701 maprow *row = self->row + (y + my);
1702
1703 for (x = 0; x < sw; x++)
1704 if (row->c0 <= x + mx && x + mx < row->c1)
1705 {
1706 mapcell *cell = row->col + (x + mx - row->c0);
1707
1708 darkness[y * sw4 + x] = cell->darkness
1709 ? 255 - (cell->darkness - 1)
1710 : 255 - FOW_DARKNESS;
1711 }
1712 }
1354 1713
1355 EXTEND (SP, 3); 1714 EXTEND (SP, 3);
1356 PUSHs (sv_2mortal (newSViv (sw4))); 1715 PUSHs (sv_2mortal (newSViv (sw4)));
1357 PUSHs (sv_2mortal (newSViv (sh))); 1716 PUSHs (sv_2mortal (newSViv (sh)));
1358 PUSHs (darkness_sv); 1717 PUSHs (darkness_sv);
1359} 1718}
1360 1719
1361SV * 1720SV *
1362get_rect (CFClient::Map self, int x0, int y0, int w, int h) 1721get_rect (CFPlus::Map self, int x0, int y0, int w, int h)
1363 CODE: 1722 CODE:
1364{ 1723{
1365 int x, y, x1, y1; 1724 int x, y, x1, y1;
1366 SV *data_sv = newSV (w * h * 7 + 5); 1725 SV *data_sv = newSV (w * h * 7 + 5);
1367 uint8_t *data = (uint8_t *)SvPVX (data_sv); 1726 uint8_t *data = (uint8_t *)SvPVX (data_sv);
1429} 1788}
1430 OUTPUT: 1789 OUTPUT:
1431 RETVAL 1790 RETVAL
1432 1791
1433void 1792void
1434set_rect (CFClient::Map self, int x0, int y0, uint8_t *data) 1793set_rect (CFPlus::Map self, int x0, int y0, uint8_t *data)
1435 PPCODE: 1794 PPCODE:
1436{ 1795{
1437 int x, y, z; 1796 int x, y, z;
1438 int w, h; 1797 int w, h;
1439 int x1, y1; 1798 int x1, y1;
1471 1830
1472 if (flags & 1) { face[0] = *data++ << 8; face[0] |= *data++; } 1831 if (flags & 1) { face[0] = *data++ << 8; face[0] |= *data++; }
1473 if (flags & 2) { face[1] = *data++ << 8; face[1] |= *data++; } 1832 if (flags & 2) { face[1] = *data++ << 8; face[1] |= *data++; }
1474 if (flags & 4) { face[2] = *data++ << 8; face[2] |= *data++; } 1833 if (flags & 4) { face[2] = *data++ << 8; face[2] |= *data++; }
1475 1834
1476 if (cell->darkness <= 0) 1835 if (cell->darkness == 0)
1477 { 1836 {
1478 cell->darkness = -1; 1837 cell->darkness = 0;
1479 1838
1480 for (z = 0; z <= 2; z++) 1839 for (z = 0; z <= 2; z++)
1481 { 1840 {
1482 cell->face[z] = face[z]; 1841 cell->face[z] = face[z];
1483 1842
1488 } 1847 }
1489 } 1848 }
1490 } 1849 }
1491} 1850}
1492 1851
1493MODULE = CFClient PACKAGE = CFClient::MixChunk 1852MODULE = CFPlus PACKAGE = CFPlus::MixChunk
1494 1853
1495CFClient::MixChunk 1854CFPlus::MixChunk
1496new_from_file (SV *class, char *path) 1855new_from_file (SV *class, char *path)
1497 CODE: 1856 CODE:
1498 RETVAL = Mix_LoadWAV (path); 1857 RETVAL = Mix_LoadWAV (path);
1499 OUTPUT: 1858 OUTPUT:
1500 RETVAL 1859 RETVAL
1501 1860
1502void 1861void
1503DESTROY (CFClient::MixChunk self) 1862DESTROY (CFPlus::MixChunk self)
1504 CODE: 1863 CODE:
1505 Mix_FreeChunk (self); 1864 Mix_FreeChunk (self);
1506 1865
1507int 1866int
1508volume (CFClient::MixChunk self, int volume = -1) 1867volume (CFPlus::MixChunk self, int volume = -1)
1509 CODE: 1868 CODE:
1510 RETVAL = Mix_VolumeChunk (self, volume); 1869 RETVAL = Mix_VolumeChunk (self, volume);
1511 OUTPUT: 1870 OUTPUT:
1512 RETVAL 1871 RETVAL
1513 1872
1514int 1873int
1515play (CFClient::MixChunk self, int channel = -1, int loops = 0, int ticks = -1) 1874play (CFPlus::MixChunk self, int channel = -1, int loops = 0, int ticks = -1)
1516 CODE: 1875 CODE:
1517 RETVAL = Mix_PlayChannelTimed (channel, self, loops, ticks); 1876 RETVAL = Mix_PlayChannelTimed (channel, self, loops, ticks);
1518 OUTPUT: 1877 OUTPUT:
1519 RETVAL 1878 RETVAL
1520 1879
1521MODULE = CFClient PACKAGE = CFClient::MixMusic 1880MODULE = CFPlus PACKAGE = CFPlus::MixMusic
1522 1881
1523int 1882int
1524volume (int volume = -1) 1883volume (int volume = -1)
1525 CODE: 1884 CODE:
1526 RETVAL = Mix_VolumeMusic (volume); 1885 RETVAL = Mix_VolumeMusic (volume);
1527 OUTPUT: 1886 OUTPUT:
1528 RETVAL 1887 RETVAL
1529 1888
1530CFClient::MixMusic 1889CFPlus::MixMusic
1531new_from_file (SV *class, char *path) 1890new_from_file (SV *class, char *path)
1532 CODE: 1891 CODE:
1533 RETVAL = Mix_LoadMUS (path); 1892 RETVAL = Mix_LoadMUS (path);
1534 OUTPUT: 1893 OUTPUT:
1535 RETVAL 1894 RETVAL
1536 1895
1537void 1896void
1538DESTROY (CFClient::MixMusic self) 1897DESTROY (CFPlus::MixMusic self)
1539 CODE: 1898 CODE:
1540 Mix_FreeMusic (self); 1899 Mix_FreeMusic (self);
1541 1900
1542int 1901int
1543play (CFClient::MixMusic self, int loops = -1) 1902play (CFPlus::MixMusic self, int loops = -1)
1544 CODE: 1903 CODE:
1545 RETVAL = Mix_PlayMusic (self, loops); 1904 RETVAL = Mix_PlayMusic (self, loops);
1546 OUTPUT: 1905 OUTPUT:
1547 RETVAL 1906 RETVAL
1548 1907
1549MODULE = CFClient PACKAGE = CFClient::OpenGL 1908MODULE = CFPlus PACKAGE = CFPlus::OpenGL
1550 1909
1551BOOT: 1910BOOT:
1552{ 1911{
1553 HV *stash = gv_stashpv ("CFClient::OpenGL", 1); 1912 HV *stash = gv_stashpv ("CFPlus::OpenGL", 1);
1554 static const struct { 1913 static const struct {
1555 const char *name; 1914 const char *name;
1556 IV iv; 1915 IV iv;
1557 } *civ, const_iv[] = { 1916 } *civ, const_iv[] = {
1558# define const_iv(name) { # name, (IV)name } 1917# define const_iv(name) { # name, (IV)name }
1565 const_iv (GL_SCISSOR_TEST), 1924 const_iv (GL_SCISSOR_TEST),
1566 const_iv (GL_DEPTH_TEST), 1925 const_iv (GL_DEPTH_TEST),
1567 const_iv (GL_ALPHA_TEST), 1926 const_iv (GL_ALPHA_TEST),
1568 const_iv (GL_NORMALIZE), 1927 const_iv (GL_NORMALIZE),
1569 const_iv (GL_RESCALE_NORMAL), 1928 const_iv (GL_RESCALE_NORMAL),
1929 const_iv (GL_FRONT),
1930 const_iv (GL_BACK),
1570 const_iv (GL_AND), 1931 const_iv (GL_AND),
1571 const_iv (GL_ONE), 1932 const_iv (GL_ONE),
1572 const_iv (GL_ZERO), 1933 const_iv (GL_ZERO),
1573 const_iv (GL_SRC_ALPHA), 1934 const_iv (GL_SRC_ALPHA),
1574 const_iv (GL_DST_ALPHA), 1935 const_iv (GL_DST_ALPHA),
1575 const_iv (GL_ONE_MINUS_SRC_ALPHA), 1936 const_iv (GL_ONE_MINUS_SRC_ALPHA),
1576 const_iv (GL_ONE_MINUS_DST_ALPHA), 1937 const_iv (GL_ONE_MINUS_DST_ALPHA),
1577 const_iv (GL_SRC_ALPHA_SATURATE), 1938 const_iv (GL_SRC_ALPHA_SATURATE),
1578 const_iv (GL_RGB), 1939 const_iv (GL_RGB),
1579 const_iv (GL_RGBA), 1940 const_iv (GL_RGBA),
1941 const_iv (GL_RGBA4),
1942 const_iv (GL_RGBA8),
1943 const_iv (GL_RGB5_A1),
1580 const_iv (GL_UNSIGNED_BYTE), 1944 const_iv (GL_UNSIGNED_BYTE),
1581 const_iv (GL_UNSIGNED_SHORT), 1945 const_iv (GL_UNSIGNED_SHORT),
1582 const_iv (GL_UNSIGNED_INT), 1946 const_iv (GL_UNSIGNED_INT),
1583 const_iv (GL_ALPHA), 1947 const_iv (GL_ALPHA),
1584 const_iv (GL_INTENSITY), 1948 const_iv (GL_INTENSITY),
1616 const_iv (GL_SEPARABLE_2D), 1980 const_iv (GL_SEPARABLE_2D),
1617 const_iv (GL_CONVOLUTION_2D), 1981 const_iv (GL_CONVOLUTION_2D),
1618 const_iv (GL_CONVOLUTION_BORDER_MODE), 1982 const_iv (GL_CONVOLUTION_BORDER_MODE),
1619 const_iv (GL_CONSTANT_BORDER), 1983 const_iv (GL_CONSTANT_BORDER),
1620 const_iv (GL_LINES), 1984 const_iv (GL_LINES),
1985 const_iv (GL_LINE_STRIP),
1621 const_iv (GL_LINE_LOOP), 1986 const_iv (GL_LINE_LOOP),
1622 const_iv (GL_QUADS), 1987 const_iv (GL_QUADS),
1623 const_iv (GL_QUAD_STRIP), 1988 const_iv (GL_QUAD_STRIP),
1624 const_iv (GL_TRIANGLES), 1989 const_iv (GL_TRIANGLES),
1625 const_iv (GL_TRIANGLE_STRIP), 1990 const_iv (GL_TRIANGLE_STRIP),
1658 OUTPUT: 2023 OUTPUT:
1659 RETVAL 2024 RETVAL
1660 2025
1661int glGetError () 2026int glGetError ()
1662 2027
2028void glFinish ()
2029
1663void glClear (int mask) 2030void glClear (int mask)
1664 2031
1665void glClearColor (float r, float g, float b, float a = 1.0) 2032void glClearColor (float r, float g, float b, float a = 1.0)
1666 PROTOTYPE: @ 2033 PROTOTYPE: @
1667 2034
1690void glPushMatrix () 2057void glPushMatrix ()
1691 2058
1692void glPopMatrix () 2059void glPopMatrix ()
1693 2060
1694void glLoadIdentity () 2061void glLoadIdentity ()
2062
2063void glDrawBuffer (int buffer)
2064
2065void glReadBuffer (int buffer)
1695 2066
1696# near_ and far_ are due to microsofts buggy "c" compiler 2067# near_ and far_ are due to microsofts buggy "c" compiler
1697void glFrustum (double left, double right, double bottom, double top, double near_, double far_) 2068void glFrustum (double left, double right, double bottom, double top, double near_, double far_)
1698 2069
1699# near_ and far_ are due to microsofts buggy "c" compiler 2070# near_ and far_ are due to microsofts buggy "c" compiler
1729 r *= a; 2100 r *= a;
1730 g *= a; 2101 g *= a;
1731 b *= a; 2102 b *= a;
1732 } 2103 }
1733 // microsoft visual "c" rounds instead of truncating... 2104 // microsoft visual "c" rounds instead of truncating...
1734 glColor4ub (MIN ((int)(r * 256.f), 255), 2105 glColor4f (r, g, b, a);
1735 MIN ((int)(g * 256.f), 255),
1736 MIN ((int)(b * 256.f), 255),
1737 MIN ((int)(a * 256.f), 255));
1738 2106
1739void glInterleavedArrays (int format, int stride, char *data) 2107void glInterleavedArrays (int format, int stride, char *data)
1740 2108
1741void glDrawElements (int mode, int count, int type, char *indices) 2109void glDrawElements (int mode, int count, int type, char *indices)
1742 2110
1819 2187
1820void glEndList () 2188void glEndList ()
1821 2189
1822void glCallList (int list) 2190void glCallList (int list)
1823 2191
1824

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines