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.29 by root, Thu Apr 13 01:55:38 2006 UTC vs.
Revision 1.59 by root, Sun Apr 23 04:41:33 2006 UTC

1#ifdef _WIN32
2# include <malloc.h>
3#endif
4
1#include "EXTERN.h" 5#include "EXTERN.h"
2#include "perl.h" 6#include "perl.h"
3#include "XSUB.h" 7#include "XSUB.h"
4 8
5#include <string.h> 9#include <string.h>
6#include <stdio.h> 10#include <stdio.h>
7 11
8#include <SDL.h> 12#include <SDL.h>
9#include <SDL_image.h> 13#include <SDL_image.h>
14#include <SDL_mixer.h>
10#include <SDL_opengl.h> 15#include <SDL_opengl.h>
16
17#include <glib/gmacros.h>
11 18
12#include <pango/pango.h> 19#include <pango/pango.h>
13#include <pango/pangofc-fontmap.h> 20#include <pango/pangofc-fontmap.h>
14#include <pango/pangoft2.h> 21#include <pango/pangoft2.h>
15 22
23#ifndef _WIN32
16#include <sys/types.h> 24# include <sys/types.h>
17#include <sys/socket.h> 25# include <sys/socket.h>
18#include <netinet/in.h> 26# include <netinet/in.h>
19#include <netinet/tcp.h> 27# include <netinet/tcp.h>
20
21#include <inttypes.h> 28# include <inttypes.h>
29#else
30 typedef unsigned char uint8_t;
31 typedef unsigned short uint16_t;
32 typedef unsigned int uint32_t;
33 typedef signed char int8_t;
34 typedef signed short int16_t;
35 typedef signed int int32_t;
36#endif
37
38#include "glext.h"
22 39
23#define FOW_DARKNESS 32 40#define FOW_DARKNESS 32
24 41
25#define MAP_EXTEND_X 32 42#define MAP_EXTEND_X 32
26#define MAP_EXTEND_Y 512 43#define MAP_EXTEND_Y 512
44
45#define MIN_FONT_HEIGHT 8 * PANGO_SCALE
46
47typedef Mix_Chunk *CFClient__MixChunk;
48typedef Mix_Music *CFClient__MixMusic;
27 49
28static PangoContext *context; 50static PangoContext *context;
29static PangoFontMap *fontmap; 51static PangoFontMap *fontmap;
30 52
31typedef struct cf_layout { 53typedef struct cf_layout {
35 57
36static void 58static void
37substitute_func (FcPattern *pattern, gpointer data) 59substitute_func (FcPattern *pattern, gpointer data)
38{ 60{
39 FcPatternAddBool (pattern, FC_HINTING , 1); 61 FcPatternAddBool (pattern, FC_HINTING , 1);
40 FcPatternAddBool (pattern, FC_AUTOHINT, 1); 62 FcPatternAddBool (pattern, FC_AUTOHINT, 0);
41} 63}
42 64
43static void 65static void
44layout_update (CFClient__Layout self) 66layout_update (CFClient__Layout self)
45{ 67{
46 /* use a random scale factor to account for unknown descenders, 0.8 works 68 /* use a random scale factor to account for unknown descenders, 0.8 works
47 * reasonably well with bitstream vera 69 * reasonably well with bitstream vera
48 */ 70 */
49 PangoFontDescription *font = pango_context_get_font_description (context); 71 PangoFontDescription *font = pango_layout_get_font_description (self->pl);
50 pango_font_description_set_absolute_size (font, self->base_height * (PANGO_SCALE * 8 / 10)); 72
73 int height = self->base_height * (PANGO_SCALE * 8 / 10);
74
75 if (height < MIN_FONT_HEIGHT)
76 height = MIN_FONT_HEIGHT;
77
78 if (pango_font_description_get_size (font) != height)
79 {
80 font = pango_font_description_copy (font);
81 pango_font_description_set_absolute_size (font, height);
82 pango_layout_set_font_description (self->pl, font);
83 }
51} 84}
52 85
53static void 86static void
54layout_get_pixel_size (CFClient__Layout self, int *w, int *h) 87layout_get_pixel_size (CFClient__Layout self, int *w, int *h)
55{ 88{
60 *w = (*w + 3) & ~3; 93 *w = (*w + 3) & ~3;
61 if (!*w) *w = 1; 94 if (!*w) *w = 1;
62 if (!*h) *h = 1; 95 if (!*h) *h = 1;
63} 96}
64 97
98typedef uint16_t mapface;
99
100typedef struct {
101 GLint name;
102 int w, h;
103 float s, t;
104 uint8_t r, g, b, a;
105} maptex;
106
65typedef struct { 107typedef struct {
66 int16_t darkness; 108 int16_t darkness;
67 uint16_t face[3]; 109 mapface face[3];
68} mapcell; 110} mapcell;
69 111
70typedef struct { 112typedef struct {
71 uint32_t c0, c1; 113 int32_t c0, c1;
72 mapcell *col; 114 mapcell *col;
73} maprow; 115} maprow;
74 116
75typedef struct map { 117typedef struct map {
76 int x, y, w, h; 118 int x, y, w, h;
119 int ox, oy; /* offset to virtual global coordinate system */
77 int faces; 120 int faces;
78 GLint *face; 121 mapface *face;
79 122
123 int texs;
124 maptex *tex;
125
80 uint32_t rows; 126 int32_t rows;
81 maprow *row; 127 maprow *row;
82} *CFClient__Map; 128} *CFClient__Map;
83 129
130static char *
131prepend (char *ptr, int sze, int inc)
132{
133 char *p;
134
135 New (0, p, sze + inc, char);
136 Zero (p, inc, char);
137 Move (ptr, p + inc, sze, char);
138 Safefree (ptr);
139
140 return p;
141}
142
143static char *
144append (char *ptr, int sze, int inc)
145{
146 Renew (ptr, sze + inc, char);
147 Zero (ptr + sze, inc, char);
148
149 return ptr;
150}
151
152#define Append(type,ptr,sze,inc) (ptr) = (type *)append ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type))
153#define Prepend(type,ptr,sze,inc) (ptr) = (type *)prepend ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type))
154
155static maprow *
156map_get_row (CFClient__Map self, int y)
157{
158 if (0 > y)
159 {
160 int extend = - y + MAP_EXTEND_Y;
161 Prepend (maprow, self->row, self->rows, extend);
162
163 self->rows += extend;
164 self->y += extend;
165 y += extend;
166 }
167 else if (y >= self->rows)
168 {
169 int extend = y - self->rows + MAP_EXTEND_Y;
170 Append (maprow, self->row, self->rows, extend);
171 self->rows += extend;
172 }
173
174 return self->row + y;
175}
176
177static mapcell *
178row_get_cell (maprow *row, int x)
179{
180 if (!row->col)
181 {
182 Newz (0, row->col, MAP_EXTEND_X, mapcell);
183 row->c0 = x - MAP_EXTEND_X / 4;
184 row->c1 = row->c0 + MAP_EXTEND_X;
185 }
186
187 if (row->c0 > x)
188 {
189 int extend = row->c0 - x + MAP_EXTEND_X;
190 Prepend (mapcell, row->col, row->c1 - row->c0, extend);
191 row->c0 -= extend;
192 }
193 else if (x >= row->c1)
194 {
195 int extend = x - row->c1 + MAP_EXTEND_X;
196 Append (mapcell, row->col, row->c1 - row->c0, extend);
197 row->c1 += extend;
198 }
199
200 return row->col + (x - row->c0);
201}
202
203static mapcell *
204map_get_cell (CFClient__Map self, int x, int y)
205{
206 return row_get_cell (map_get_row (self, y), x);
207}
208
209static void
210map_clear (CFClient__Map self)
211{
212 int r;
213
214 for (r = 0; r < self->rows; r++)
215 Safefree (self->row[r].col);
216
217 Safefree (self->row);
218
219 self->x = 0;
220 self->y = 0;
221 self->ox = 0;
222 self->oy = 0;
223 self->row = 0;
224 self->rows = 0;
225}
226
84static void 227static void
85map_blank (CFClient__Map self, int x0, int y0, int w, int h) 228map_blank (CFClient__Map self, int x0, int y0, int w, int h)
86{ 229{
87 int x, y; 230 int x, y;
231 maprow *row;
88 232
89 for (y = y0; y < y0 + h; y++) 233 for (y = y0; y < y0 + h; y++)
234 if (y >= 0)
90 { 235 {
91 if (y >= self->rows) 236 if (y >= self->rows)
92 break; 237 break;
93 238
94 maprow *row = self->row + y; 239 row = self->row + y;
95 240
96 for (x = x0; x < x0 + w; x++) 241 for (x = x0; x < x0 + w; x++)
97 if (x >= row->c0) 242 if (x >= row->c0)
243 {
244 if (x >= row->c1)
245 break;
246
247 row->col[x - row->c0].darkness = -1;
248 }
249 }
250}
251
252static void
253music_finished ()
254{
255 SDL_UserEvent ev;
256
257 ev.type = SDL_USEREVENT;
258 ev.code = 0;
259 ev.data1 = 0;
260 ev.data2 = 0;
261
262 SDL_PushEvent ((SDL_Event *)&ev);
263}
264
265MODULE = CFClient PACKAGE = CFClient
266
267PROTOTYPES: ENABLE
268
269BOOT:
270{
271 HV *stash = gv_stashpv ("CFClient", 1);
272 static const struct {
273 const char *name;
274 IV iv;
275 } *civ, const_iv[] = {
276# define const_iv(name) { # name, (IV)name }
277 const_iv (SDL_ACTIVEEVENT),
278 const_iv (SDL_KEYDOWN),
279 const_iv (SDL_KEYUP),
280 const_iv (SDL_MOUSEMOTION),
281 const_iv (SDL_MOUSEBUTTONDOWN),
282 const_iv (SDL_MOUSEBUTTONUP),
283 const_iv (SDL_JOYAXISMOTION),
284 const_iv (SDL_JOYBALLMOTION),
285 const_iv (SDL_JOYHATMOTION),
286 const_iv (SDL_JOYBUTTONDOWN),
287 const_iv (SDL_JOYBUTTONUP),
288 const_iv (SDL_QUIT),
289 const_iv (SDL_SYSWMEVENT),
290 const_iv (SDL_EVENT_RESERVEDA),
291 const_iv (SDL_EVENT_RESERVEDB),
292 const_iv (SDL_VIDEORESIZE),
293 const_iv (SDL_VIDEOEXPOSE),
294 const_iv (SDL_USEREVENT),
295 const_iv (SDLK_KP0),
296 const_iv (SDLK_KP1),
297 const_iv (SDLK_KP2),
298 const_iv (SDLK_KP3),
299 const_iv (SDLK_KP4),
300 const_iv (SDLK_KP5),
301 const_iv (SDLK_KP6),
302 const_iv (SDLK_KP7),
303 const_iv (SDLK_KP8),
304 const_iv (SDLK_KP9),
305 const_iv (SDLK_KP_PERIOD),
306 const_iv (SDLK_KP_DIVIDE),
307 const_iv (SDLK_KP_MULTIPLY),
308 const_iv (SDLK_KP_MINUS),
309 const_iv (SDLK_KP_PLUS),
310 const_iv (SDLK_KP_ENTER),
311 const_iv (SDLK_KP_EQUALS),
312 const_iv (SDLK_UP),
313 const_iv (SDLK_DOWN),
314 const_iv (SDLK_RIGHT),
315 const_iv (SDLK_LEFT),
316 const_iv (SDLK_INSERT),
317 const_iv (SDLK_HOME),
318 const_iv (SDLK_END),
319 const_iv (SDLK_PAGEUP),
320 const_iv (SDLK_PAGEDOWN),
321 const_iv (SDLK_F1),
322 const_iv (SDLK_F2),
323 const_iv (SDLK_F3),
324 const_iv (SDLK_F4),
325 const_iv (SDLK_F5),
326 const_iv (SDLK_F6),
327 const_iv (SDLK_F7),
328 const_iv (SDLK_F8),
329 const_iv (SDLK_F9),
330 const_iv (SDLK_F10),
331 const_iv (SDLK_F11),
332 const_iv (SDLK_F12),
333 const_iv (SDLK_F13),
334 const_iv (SDLK_F14),
335 const_iv (SDLK_F15),
336 const_iv (SDLK_NUMLOCK),
337 const_iv (SDLK_CAPSLOCK),
338 const_iv (SDLK_SCROLLOCK),
339 const_iv (SDLK_RSHIFT),
340 const_iv (SDLK_LSHIFT),
341 const_iv (SDLK_RCTRL),
342 const_iv (SDLK_LCTRL),
343 const_iv (SDLK_RALT),
344 const_iv (SDLK_LALT),
345 const_iv (SDLK_RMETA),
346 const_iv (SDLK_LMETA),
347 const_iv (SDLK_LSUPER),
348 const_iv (SDLK_RSUPER),
349 const_iv (SDLK_MODE),
350 const_iv (SDLK_COMPOSE),
351 const_iv (SDLK_HELP),
352 const_iv (SDLK_PRINT),
353 const_iv (SDLK_SYSREQ),
354 const_iv (SDLK_BREAK),
355 const_iv (SDLK_MENU),
356 const_iv (SDLK_POWER),
357 const_iv (SDLK_EURO),
358 const_iv (SDLK_UNDO),
359 const_iv (KMOD_NONE),
360 const_iv (KMOD_LSHIFT),
361 const_iv (KMOD_RSHIFT),
362 const_iv (KMOD_LCTRL),
363 const_iv (KMOD_RCTRL),
364 const_iv (KMOD_LALT),
365 const_iv (KMOD_RALT),
366 const_iv (KMOD_LMETA),
367 const_iv (KMOD_RMETA),
368 const_iv (KMOD_NUM),
369 const_iv (KMOD_CAPS),
370 const_iv (KMOD_MODE),
371 const_iv (KMOD_CTRL),
372 const_iv (KMOD_SHIFT),
373 const_iv (KMOD_ALT),
374 const_iv (KMOD_META)
375# undef const_iv
376 };
377
378 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
379 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
380
381 fontmap = pango_ft2_font_map_new ();
382 pango_ft2_font_map_set_default_substitute ((PangoFT2FontMap *)fontmap, substitute_func, 0, 0);
383 context = pango_ft2_font_map_create_context ((PangoFT2FontMap *)fontmap);
384}
385
386int
387SDL_Init (U32 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO)
388
389void
390SDL_Quit ()
391
392void
393SDL_ListModes ()
394 PPCODE:
395{
396 SDL_Rect **m;
397
398 SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 5);
399 SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 5);
400 SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5);
401 SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, 1);
402
403 SDL_GL_SetAttribute (SDL_GL_ACCUM_RED_SIZE, 0);
404 SDL_GL_SetAttribute (SDL_GL_ACCUM_GREEN_SIZE, 0);
405 SDL_GL_SetAttribute (SDL_GL_ACCUM_BLUE_SIZE, 0);
406 SDL_GL_SetAttribute (SDL_GL_ACCUM_ALPHA_SIZE, 0);
407
408 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
409 SDL_GL_SetAttribute (SDL_GL_BUFFER_SIZE, 15);
410 SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 0);
411
412 SDL_EnableUNICODE (1);
413 SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
414
415 m = SDL_ListModes (0, SDL_FULLSCREEN | SDL_OPENGL);
416
417 if (m && m != (SDL_Rect **)-1)
418 while (*m)
419 {
420 AV *av = newAV ();
421 av_push (av, newSViv ((*m)->w));
422 av_push (av, newSViv ((*m)->h));
423 XPUSHs (sv_2mortal (newRV_noinc ((SV *)av)));
424
425 ++m;
426 }
427}
428
429int
430SDL_SetVideoMode (int w, int h, int fullscreen)
431 CODE:
432 RETVAL = !!SDL_SetVideoMode (
433 w, h, 0, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0)
434 );
435 SDL_WM_SetCaption ("Crossfire+ Client " VERSION, "Crossfire+");
436 OUTPUT:
437 RETVAL
438
439void
440SDL_GL_SwapBuffers ()
441
442void
443SDL_PollEvent ()
444 PPCODE:
445{
446 SDL_Event ev;
447
448 while (SDL_PollEvent (&ev))
98 { 449 {
99 if (x >= row->c1) 450 HV *hv = newHV ();
451 hv_store (hv, "type", 4, newSViv (ev.type), 0);
452 switch (ev.type)
453 {
454 case SDL_KEYDOWN:
455 case SDL_KEYUP:
456 hv_store (hv, "state", 5, newSViv (ev.key.state), 0);
457 hv_store (hv, "sym", 3, newSViv (ev.key.keysym.sym), 0);
458 hv_store (hv, "mod", 3, newSViv (ev.key.keysym.mod), 0);
459 hv_store (hv, "unicode", 7, newSViv (ev.key.keysym.unicode), 0);
100 break; 460 break;
101 461
102 row->col[x].darkness = -1; 462 case SDL_ACTIVEEVENT:
463 hv_store (hv, "gain", 4, newSViv (ev.active.gain), 0);
464 hv_store (hv, "state", 5, newSViv (ev.active.state), 0);
465 break;
466
467 case SDL_MOUSEMOTION:
468 hv_store (hv, "state", 5, newSViv (ev.motion.state), 0);
469 hv_store (hv, "x", 1, newSViv (ev.motion.x), 0);
470 hv_store (hv, "y", 1, newSViv (ev.motion.y), 0);
471 hv_store (hv, "xrel", 4, newSViv (ev.motion.xrel), 0);
472 hv_store (hv, "yrel", 4, newSViv (ev.motion.yrel), 0);
473 break;
474
475 case SDL_MOUSEBUTTONDOWN:
476 case SDL_MOUSEBUTTONUP:
477 hv_store (hv, "button", 6, newSViv (ev.button.button), 0);
478 hv_store (hv, "state", 5, newSViv (ev.button.state), 0);
479 hv_store (hv, "x", 1, newSViv (ev.button.x), 0);
480 hv_store (hv, "y", 1, newSViv (ev.button.y), 0);
481 }
482
483 XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv)));
103 } 484 }
104 }
105} 485}
106 486
107MODULE = CFClient PACKAGE = CFClient 487int
488Mix_OpenAudio (int frequency = 22050, int format = MIX_DEFAULT_FORMAT, int channels = 1, int chunksize = 512)
489 POSTCALL:
490 Mix_HookMusicFinished (music_finished);
108 491
109PROTOTYPES: ENABLE 492void
493Mix_CloseAudio ()
110 494
111BOOT: 495int
112{ 496Mix_AllocateChannels (int numchans = -1)
113 fontmap = pango_ft2_font_map_new ();
114 pango_ft2_font_map_set_default_substitute ((PangoFT2FontMap *)fontmap, substitute_func, 0, 0);
115 context = pango_ft2_font_map_create_context ((PangoFT2FontMap *)fontmap);
116}
117 497
118void 498void
119lowdelay (int fd, int val = 1) 499lowdelay (int fd, int val = 1)
120 CODE: 500 CODE:
501#ifndef _WIN32
121 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof (val)); 502 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof (val));
503#endif
122 504
123char * 505char *
124gl_version () 506gl_version ()
125 CODE: 507 CODE:
126 RETVAL = (char *)glGetString (GL_VERSION); 508 RETVAL = (char *)glGetString (GL_VERSION);
145{ 527{
146 int count; 528 int count;
147 FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)file, 0, 0, &count); 529 FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)file, 0, 0, &count);
148 PangoFontDescription *font = pango_fc_font_description_from_pattern (pattern, 0); 530 PangoFontDescription *font = pango_fc_font_description_from_pattern (pattern, 0);
149 FcPatternDestroy (pattern); 531 FcPatternDestroy (pattern);
532 pango_font_description_set_absolute_size (font, MIN_FONT_HEIGHT);
150 pango_context_set_font_description (context, font); 533 pango_context_set_font_description (context, font);
151} 534}
152 535
153void 536void
154load_image_inline (SV *image_) 537load_image_inline (SV *image_)
163 SDL_RWops *rw = ix 546 SDL_RWops *rw = ix
164 ? SDL_RWFromFile (image, "r") 547 ? SDL_RWFromFile (image, "r")
165 : SDL_RWFromConstMem (image, image_len); 548 : SDL_RWFromConstMem (image, image_len);
166 549
167 if (!rw) 550 if (!rw)
168 croak ("load_image: unable to open file"); 551 croak ("load_image: %s", SDL_GetError ());
169 552
170 surface = IMG_Load_RW (rw, 1); 553 surface = IMG_Load_RW (rw, 1);
171 if (!surface) 554 if (!surface)
172 croak ("load_image: unable to read file"); 555 croak ("load_image: %s", SDL_GetError ());
173 556
174 fmt.palette = NULL; 557 fmt.palette = NULL;
175 fmt.BitsPerPixel = 32; 558 fmt.BitsPerPixel = 32;
176 fmt.BytesPerPixel = 4; 559 fmt.BytesPerPixel = 4;
560#if SDL_BYTEORDER == SDL_LIL_ENDIAN
177 fmt.Rmask = 0x000000ff; 561 fmt.Rmask = 0x000000ff;
178 fmt.Gmask = 0x0000ff00; 562 fmt.Gmask = 0x0000ff00;
179 fmt.Bmask = 0x00ff0000; 563 fmt.Bmask = 0x00ff0000;
180 fmt.Amask = 0xff000000; 564 fmt.Amask = 0xff000000;
565#else
566 fmt.Rmask = 0xff000000;
567 fmt.Gmask = 0x00ff0000;
568 fmt.Bmask = 0x0000ff00;
569 fmt.Amask = 0x000000ff;
570#endif
181 fmt.Rloss = 0; 571 fmt.Rloss = 0;
182 fmt.Gloss = 0; 572 fmt.Gloss = 0;
183 fmt.Bloss = 0; 573 fmt.Bloss = 0;
184 fmt.Aloss = 0; 574 fmt.Aloss = 0;
185 fmt.Rshift = 0; 575 fmt.Rshift = 0;
189 fmt.colorkey = 0; 579 fmt.colorkey = 0;
190 fmt.alpha = 0; 580 fmt.alpha = 0;
191 581
192 surface2 = SDL_ConvertSurface (surface, &fmt, SDL_SWSURFACE); 582 surface2 = SDL_ConvertSurface (surface, &fmt, SDL_SWSURFACE);
193 583
584 assert (surface2->pitch == surface2->w * 4);
585
194 EXTEND (SP, 5); 586 EXTEND (SP, 5);
195 PUSHs (sv_2mortal (newSViv (surface2->w))); 587 PUSHs (sv_2mortal (newSViv (surface2->w)));
196 PUSHs (sv_2mortal (newSViv (surface2->h))); 588 PUSHs (sv_2mortal (newSViv (surface2->h)));
197 SDL_LockSurface (surface2); 589 SDL_LockSurface (surface2);
198 PUSHs (sv_2mortal (newSVpvn (surface2->pixels, surface2->h * surface2->pitch))); 590 PUSHs (sv_2mortal (newSVpvn (surface2->pixels, surface2->h * surface2->pitch)));
199 SDL_UnlockSurface (surface2); 591 SDL_UnlockSurface (surface2);
200 PUSHs (sv_2mortal (newSViv (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA) ? GL_RGBA : GL_RGB))); 592 PUSHs (sv_2mortal (newSViv (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA) ? GL_RGBA : GL_RGB)));
201 PUSHs (sv_2mortal (newSViv (GL_RGBA))); 593 PUSHs (sv_2mortal (newSViv (GL_RGBA)));
202 PUSHs (sv_2mortal (newSViv (GL_UNSIGNED_INT_8_8_8_8_REV))); 594 PUSHs (sv_2mortal (newSViv (GL_UNSIGNED_BYTE)));
203 595
204 SDL_FreeSurface (surface); 596 SDL_FreeSurface (surface);
205 SDL_FreeSurface (surface2); 597 SDL_FreeSurface (surface2);
206} 598}
207 599
208void 600void
601average (int x, int y, uint32_t *data)
602 PPCODE:
603{
604 uint32_t r = 0, g = 0, b = 0, a = 0;
605
606 x = y = x * y;
607
608 while (x--)
609 {
610 uint32_t p = *data++;
611
612 r += (p ) & 255;
613 g += (p >> 8) & 255;
614 b += (p >> 16) & 255;
615 a += (p >> 24) & 255;
616 }
617
618 EXTEND (SP, 4);
619 PUSHs (sv_2mortal (newSViv (r / y)));
620 PUSHs (sv_2mortal (newSViv (g / y)));
621 PUSHs (sv_2mortal (newSViv (b / y)));
622 PUSHs (sv_2mortal (newSViv (a / y)));
623}
624
625void
209fatal (char *message) 626fatal (char *message)
210 CODE: 627 CODE:
211#ifdef WIN32 628#ifdef _WIN32
212 MessageBox (0, message, "Crossfire+ Fatal Error", MB_OK | MB_ICONERROR | MB_SETFOREGROUND); 629 MessageBox (0, message, "Crossfire+ Fatal Error", MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
213#else 630#else
214 fprintf (stderr, "%s\n", message); 631 fprintf (stderr, "FATAL: %s\n", message);
215#endif 632#endif
216 exit (1); 633 exit (1);
217 634
218MODULE = CFClient PACKAGE = CFClient::Layout 635MODULE = CFClient PACKAGE = CFClient::Layout
219 636
222 CODE: 639 CODE:
223 New (0, RETVAL, 1, struct cf_layout); 640 New (0, RETVAL, 1, struct cf_layout);
224 RETVAL->base_height = base_height; 641 RETVAL->base_height = base_height;
225 RETVAL->pl = pango_layout_new (context); 642 RETVAL->pl = pango_layout_new (context);
226 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR); 643 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
644 pango_layout_set_font_description (RETVAL->pl,
645 pango_font_description_copy (
646 pango_context_get_font_description (context)));
227 OUTPUT: 647 OUTPUT:
228 RETVAL 648 RETVAL
229 649
230void 650void
231DESTROY (CFClient::Layout self) 651DESTROY (CFClient::Layout self)
232 CODE: 652 CODE:
233 g_object_unref (self->pl); 653 g_object_unref (self->pl);
234 Safefree (self); 654 Safefree (self);
235 655
236void 656void
237set_markup (CFClient::Layout self, SV *text_) 657set_text (CFClient::Layout self, SV *text_)
238 CODE: 658 CODE:
239{ 659{
240 STRLEN textlen; 660 STRLEN textlen;
241 char *text = SvPVutf8 (text_, textlen); 661 char *text = SvPVutf8 (text_, textlen);
242 662
663 pango_layout_set_text (self->pl, text, textlen);
664}
665
666void
667set_markup (CFClient::Layout self, SV *text_)
668 CODE:
669{
670 STRLEN textlen;
671 char *text = SvPVutf8 (text_, textlen);
672
243 pango_layout_set_markup (self->pl, text, textlen); 673 pango_layout_set_markup (self->pl, text, textlen);
244} 674}
675
676SV *
677get_text (CFClient::Layout self)
678 CODE:
679 RETVAL = newSVpv (pango_layout_get_text (self->pl), 0);
680 SvUTF8_on (RETVAL);
681 OUTPUT:
682 RETVAL
245 683
246void 684void
247set_height (CFClient::Layout self, int base_height) 685set_height (CFClient::Layout self, int base_height)
248 CODE: 686 CODE:
249 self->base_height = base_height; 687 self->base_height = base_height;
286 PPCODE: 724 PPCODE:
287{ 725{
288 PangoRectangle strong_pos; 726 PangoRectangle strong_pos;
289 layout_update (self); 727 layout_update (self);
290 pango_layout_get_cursor_pos (self->pl, index, &strong_pos, 0); 728 pango_layout_get_cursor_pos (self->pl, index, &strong_pos, 0);
729
291 EXTEND (SP, 3); 730 EXTEND (SP, 3);
292 PUSHs (sv_2mortal (newSViv (strong_pos.x / PANGO_SCALE))); 731 PUSHs (sv_2mortal (newSViv (strong_pos.x / PANGO_SCALE)));
293 PUSHs (sv_2mortal (newSViv (strong_pos.y / PANGO_SCALE))); 732 PUSHs (sv_2mortal (newSViv (strong_pos.y / PANGO_SCALE)));
294 PUSHs (sv_2mortal (newSViv (strong_pos.height / PANGO_SCALE))); 733 PUSHs (sv_2mortal (newSViv (strong_pos.height / PANGO_SCALE)));
295} 734}
327} 766}
328 767
329MODULE = CFClient PACKAGE = CFClient::Texture 768MODULE = CFClient PACKAGE = CFClient::Texture
330 769
331void 770void
332draw_quad (SV *self, double x, double y, double w = 0, double h = 0) 771draw_quad (SV *self, float x, float y, float w = 0, float h = 0)
333 PROTOTYPE: $$$;$$ 772 PROTOTYPE: $$$;$$
334 CODE: 773 CODE:
335{ 774{
336 HV *hv = (HV *)SvRV (self); 775 HV *hv = (HV *)SvRV (self);
337 double s = SvNV (*hv_fetch (hv, "s", 1, 1)); 776 float s = SvNV (*hv_fetch (hv, "s", 1, 1));
338 double t = SvNV (*hv_fetch (hv, "t", 1, 1)); 777 float t = SvNV (*hv_fetch (hv, "t", 1, 1));
339 int name = SvIV (*hv_fetch (hv, "name", 4, 1)); 778 int name = SvIV (*hv_fetch (hv, "name", 4, 1));
779 int wrap_mode = SvIV (*hv_fetch (hv, "wrap_mode", 9, 1));
340 780
341 if (items < 5) 781 if (items < 5)
342 { 782 {
343 w = SvNV (*hv_fetch (hv, "w", 1, 1)); 783 w = SvNV (*hv_fetch (hv, "w", 1, 1));
344 h = SvNV (*hv_fetch (hv, "h", 1, 1)); 784 h = SvNV (*hv_fetch (hv, "h", 1, 1));
345 } 785 }
346 786
347 glBindTexture (GL_TEXTURE_2D, name); 787 glBindTexture (GL_TEXTURE_2D, name);
788 if (wrap_mode) {
789 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
790 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
791 }
348 glBegin (GL_QUADS); 792 glBegin (GL_QUADS);
349 glTexCoord2d (0, 0); glVertex2d (x , y ); 793 glTexCoord2f (0, 0); glVertex2f (x , y );
350 glTexCoord2d (0, t); glVertex2d (x , y + h); 794 glTexCoord2f (0, t); glVertex2f (x , y + h);
351 glTexCoord2d (s, t); glVertex2d (x + w, y + h); 795 glTexCoord2f (s, t); glVertex2f (x + w, y + h);
352 glTexCoord2d (s, 0); glVertex2d (x + w, y ); 796 glTexCoord2f (s, 0); glVertex2f (x + w, y );
353 glEnd (); 797 glEnd ();
354} 798}
355 799
356MODULE = CFClient PACKAGE = CFClient::Map 800MODULE = CFClient PACKAGE = CFClient::Map
357 801
358CFClient::Map 802CFClient::Map
359new (SV *class, int map_width, int map_height) 803new (SV *class, int map_width, int map_height)
360 CODE: 804 CODE:
361 New (0, RETVAL, 1, struct map); 805 New (0, RETVAL, 1, struct map);
362 RETVAL->x = 0; 806 RETVAL->x = 0;
363 RETVAL->y = 0; 807 RETVAL->y = 0;
364 RETVAL->w = map_width; 808 RETVAL->w = map_width;
365 RETVAL->h = map_height; 809 RETVAL->h = map_height;
810 RETVAL->ox = 0;
811 RETVAL->oy = 0;
366 RETVAL->faces = 1; 812 RETVAL->faces = 8192;
367 Newz (0, RETVAL->face, 1, GLint); 813 Newz (0, RETVAL->face, RETVAL->faces, mapface);
814 RETVAL->texs = 8192;
815 Newz (0, RETVAL->tex, RETVAL->texs, maptex);
368 RETVAL->rows = 0; 816 RETVAL->rows = 0;
369 RETVAL->row = 0; 817 RETVAL->row = 0;
370 printf ("new map %d,%d\n", map_width, map_height);//D
371 OUTPUT: 818 OUTPUT:
372 RETVAL 819 RETVAL
373 820
374void 821void
375DESTROY (CFClient::Map self) 822DESTROY (CFClient::Map self)
376 CODE: 823 CODE:
377{ 824{
378 int r, c; 825 map_clear (self);
379
380 printf ("detroy map\n");//D
381 Safefree (self->face); 826 Safefree (self->face);
382
383 for (r = 0; r < self->rows; r++)
384 Safefree (self->row[r].col);
385
386 Safefree (self->row);
387 Safefree (self); 827 Safefree (self);
388} 828}
389 829
390void 830void
831clear (CFClient::Map self)
832 CODE:
833 map_clear (self);
834
835void
391set_face (CFClient::Map self, int facenum, int face) 836set_face (CFClient::Map self, int face, int texid)
392 CODE: 837 CODE:
393{ 838{
394 while (self->faces < facenum) 839 while (self->faces <= face)
395 { 840 {
396 printf ("setface %d (%d) = %d\n",facenum, self->faces, face);//D
397 Renew (self->face, self->faces * 2, GLint);
398 Zero (self->face + self->faces, self->faces, GLint); 841 Append (mapface, self->face, self->faces, self->faces);
399 self->faces *= 2; 842 self->faces *= 2;
400 } 843 }
401 844
402 self->face [facenum] = face; 845 self->face [face] = texid;
403} 846}
847
848void
849set_texture (CFClient::Map self, int texid, int name, int w, int h, float s, float t, int r, int g, int b, int a)
850 CODE:
851{
852 while (self->texs <= texid)
853 {
854 Append (maptex, self->tex, self->texs, self->texs);
855 self->texs *= 2;
856 }
857
858 {
859 maptex *tex = self->tex + texid;
860
861 tex->name = name;
862 tex->w = w;
863 tex->h = h;
864 tex->s = s;
865 tex->t = t;
866 tex->r = r;
867 tex->g = g;
868 tex->b = b;
869 tex->a = a;
870 }
871}
872
873int
874ox (CFClient::Map self)
875 ALIAS:
876 oy = 1
877 CODE:
878 switch (ix)
879 {
880 case 0: RETVAL = self->ox; break;
881 case 1: RETVAL = self->oy; break;
882 }
883 OUTPUT:
884 RETVAL
404 885
405void 886void
406scroll (CFClient::Map self, int dx, int dy) 887scroll (CFClient::Map self, int dx, int dy)
407 CODE: 888 CODE:
408{ 889{
409 printf ("map_scroll %d,%d\n", dx, dy);//D
410 if (dx > 0) 890 if (dx > 0)
411 map_blank (self, self->x, self->y, dx - 1, self->h); 891 map_blank (self, self->x, self->y, dx - 1, self->h);
412 else if (dx < 0) 892 else if (dx < 0)
413 map_blank (self, self->x + self->w + dx + 1, self->y, 1 - dx, self->h); 893 map_blank (self, self->x + self->w + dx + 1, self->y, 1 - dx, self->h);
414 894
415 if (dy > 0) 895 if (dy > 0)
416 map_blank (self, self->x, self->y, self->w, dy - 1); 896 map_blank (self, self->x, self->y, self->w, dy - 1);
417 else if (dy < 0) 897 else if (dy < 0)
418 map_blank (self, self->x, self->y + self->h + dy + 1, self->w, 1 - dy); 898 map_blank (self, self->x, self->y + self->h + dy + 1, self->w, 1 - dy);
419 899
420 self->x += dx; 900 self->ox += dx; self->x += dx;
421 self->y += dy; 901 self->oy += dy; self->y += dy;
422 902
423 while (self->y < 0) 903 while (self->y < 0)
424 { 904 {
425 maprow *row; 905 Prepend (maprow, self->row, self->rows, MAP_EXTEND_Y);
426
427 New (0, row, self->rows + MAP_EXTEND_Y, maprow);
428 Move (self->row, row + MAP_EXTEND_Y, self->rows, maprow);
429 Zero (row, MAP_EXTEND_Y, maprow);
430 906
431 self->rows += MAP_EXTEND_Y; 907 self->rows += MAP_EXTEND_Y;
432 self->y += MAP_EXTEND_Y; 908 self->y += MAP_EXTEND_Y;
433 self->row = row;
434 } 909 }
435
436 if (self->x < 0)
437 {
438 int y;
439 for (y = 0; y < self->rows; y++)
440 {
441 self->row[y].c0 += self->x;
442 self->row[y].c1 += self->x;
443 }
444
445 self->x = 0;
446 }
447} 910}
448 911
449void 912void
450map1a_update (CFClient::Map self, SV *data_) 913map1a_update (CFClient::Map self, SV *data_)
451 CODE: 914 CODE:
452{ 915{
453 uint8_t *data = (uint8_t *)SvPVbytes_nolen (data_); 916 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_);
454 uint8_t *data_end = (uint8_t *)SvEND (data_) + 1; 917 uint8_t *data_end = (uint8_t *)SvEND (data_);
455 918 mapcell *cell;
919 int x, y, flags;
920
456 while (data < data_end) 921 while (data < data_end)
457 { 922 {
458 int flags = (data [0] << 8) + data [1]; data += 2; 923 flags = (data [0] << 8) + data [1]; data += 2;
924
459 int x = ((flags >> 10) & 63) + self->x; 925 x = ((flags >> 10) & 63) + self->x;
460 int y = ((flags >> 4) & 63) + self->y; 926 y = ((flags >> 4) & 63) + self->y;
461 927
462 while (y >= self->rows) 928 cell = map_get_cell (self, x, y);
463 {
464 Renew (self->row, self->rows + MAP_EXTEND_Y, maprow);
465 Zero (self->row + self->rows, MAP_EXTEND_Y, maprow);
466
467 self->rows += MAP_EXTEND_Y;
468 }
469
470 assert (y < self->rows);//D
471
472 maprow *row = self->row + y;
473
474 if (!row->col)
475 {
476 Newz (0, row->col, MAP_EXTEND_X, mapcell);
477 row->c0 = self->x - MAP_EXTEND_X / 4;
478 row->c1 = row->c0 + MAP_EXTEND_X;
479 }
480
481 if (row->c0 > x)
482 {
483 int extend = row->c0 - x + MAP_EXTEND_X;
484 mapcell *col;
485
486 New (0, col, row->c1 - row->c0 + extend, mapcell);
487 Move (row->col, col + extend, row->c1 - row->c0, mapcell);
488 Zero (col, extend, mapcell);
489
490 row->col = col;
491 row->c0 -= extend;
492 }
493 else if (x >= row->c1)
494 {
495 int extend = x - row->c1 + MAP_EXTEND_X;
496
497 Renew (row->col, row->c1 - row->c0 + extend, mapcell);
498 Zero (row->col + row->c1 - row->c0, extend, mapcell);
499
500 row->c1 += extend;
501 }
502
503 assert (x >= row->c0);//D
504 assert (x < row->c1);//D
505 mapcell *cell = row->col + (x - row->c0);
506 929
507 if (flags & 15) 930 if (flags & 15)
508 { 931 {
509 if (cell->darkness < 0) 932 if (cell->darkness < 0)
510 { 933 {
511 cell->darkness = 0; 934 cell->darkness = 0;
512 cell->face [0] = 0; 935 cell->face [0] = 0;
513 cell->face [1] = 0; 936 cell->face [1] = 0;
514 cell->face [2] = 0; 937 cell->face [2] = 0;
515 } 938 }
516 939
517 cell->darkness = flags & 8 ? *data++ : 255; 940 cell->darkness = flags & 8 ? *data++ : 255;
941
942 //TODO: don't trust server data to be in-range(!)
518 943
519 if (flags & 4) 944 if (flags & 4)
520 { 945 {
521 cell->face [0] = (data [0] << 8) + data [1]; data += 2; 946 cell->face [0] = self->face [(data [0] << 8) + data [1]]; data += 2;
522 } 947 }
523 948
524 if (flags & 2) 949 if (flags & 2)
525 { 950 {
526 cell->face [1] = (data [0] << 8) + data [1]; data += 2; 951 cell->face [1] = self->face [(data [0] << 8) + data [1]]; data += 2;
527 } 952 }
528 953
529 if (flags & 1) 954 if (flags & 1)
530 { 955 {
531 cell->face [2] = (data [0] << 8) + data [1]; data += 2; 956 cell->face [2] = self->face [(data [0] << 8) + data [1]]; data += 2;
532 } 957 }
533 } 958 }
534 else 959 else
535 cell->darkness = -1; 960 cell->darkness = -1;
536 } 961 }
537} 962}
538 963
964SV *
965mapmap (CFClient::Map self, int x0, int y0, int w, int h)
966 CODE:
967{
968 int x1, x;
969 int y1, y;
970 int z;
971 SV *map_sv = newSV (w * h * sizeof (uint32_t));
972 uint32_t *map = (uint32_t *)SvPVX (map_sv);
973
974 SvPOK_only (map_sv);
975 SvCUR_set (map_sv, w * h * sizeof (uint32_t));
976
977 x0 += self->x; x1 = x0 + w;
978 y0 += self->y; y1 = y0 + h;
979
980 for (y = y0; y < y1; y++)
981 {
982 maprow *row = 0 <= y && y < self->rows
983 ? self->row + y
984 : 0;
985
986 for (x = x0; x < x1; x++)
987 {
988 int r = 32, g = 32, b = 32, a = 192;
989
990 if (row && row->c0 <= x && x < row->c1)
991 {
992 mapcell *cell = row->col + (x - row->c0);
993
994 for (z = 0; z <= 0; z++)
995 {
996 mapface face = cell->face [z];
997
998 if (face)
999 {
1000 maptex tex = self->tex [face];
1001 int a0 = 255 - tex.a;
1002 int a1 = tex.a;
1003
1004 r = (r * a0 + tex.r * a1) / 255;
1005 g = (g * a0 + tex.g * a1) / 255;
1006 b = (b * a0 + tex.b * a1) / 255;
1007 a = (a * a0 + tex.a * a1) / 255;
1008 }
1009 }
1010 }
1011
1012 *map++ = (r )
1013 | (g << 8)
1014 | (b << 16)
1015 | (a << 24);
1016 }
1017 }
1018
1019 RETVAL = map_sv;
1020}
1021 OUTPUT:
1022 RETVAL
1023
1024void
1025draw (CFClient::Map self, int shift_x, int shift_y, int x0, int y0, int sw, int sh)
1026 PPCODE:
1027{
1028 int vx, vy;
1029 int x, y, z;
1030 int last_name;
1031 mapface face;
1032 int sw4 = (sw + 3) & ~3;
1033 SV *darkness_sv = sv_2mortal (newSV (sw4 * sh));
1034 uint8_t *darkness = (uint8_t *)SvPVX (darkness_sv);
1035
1036 memset (darkness, 255, sw4 * sh);
1037 SvPOK_only (darkness_sv);
1038 SvCUR_set (darkness_sv, sw4 * sh);
1039
1040 vx = self->x + (self->w - sw) / 2 - shift_x;
1041 vy = self->y + (self->h - sh) / 2 - shift_y;
1042
1043 /*
1044 int vx = self->vx = self->w >= sw
1045 ? self->x + (self->w - sw) / 2
1046 : MIN (self->x, MAX (self->x + self->w - sw + 1, self->vx));
1047
1048 int vy = self->vy = self->h >= sh
1049 ? self->y + (self->h - sh) / 2
1050 : MIN (self->y, MAX (self->y + self->h - sh + 1, self->vy));
1051 */
1052
1053 glColor4ub (255, 255, 255, 255);
1054
1055 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1056 glEnable (GL_BLEND);
1057 glEnable (GL_TEXTURE_2D);
1058 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1059
1060 glBegin (GL_QUADS);
1061
1062 last_name = 0;
1063
1064 for (z = 0; z < 3; z++)
1065 for (y = 0; y < sh; y++)
1066 if (0 <= y + vy && y + vy < self->rows)
1067 {
1068 maprow *row = self->row + (y + vy);
1069
1070 for (x = 0; x < sw; x++)
1071 if (row->c0 <= x + vx && x + vx < row->c1)
1072 {
1073 mapcell *cell = row->col + (x + vx - row->c0);
1074
1075 darkness[y * sw4 + x] = cell->darkness < 0
1076 ? 255 - FOW_DARKNESS
1077 : 255 - cell->darkness;
1078
1079 face = cell->face [z];
1080
1081 if (face)
1082 {
1083 maptex tex = self->tex [face];
1084
1085 int px = (x + 1) * 32 - tex.w;
1086 int py = (y + 1) * 32 - tex.h;
1087
1088 if (last_name != tex.name)
1089 {
1090 glEnd ();
1091 last_name = tex.name;
1092 glBindTexture (GL_TEXTURE_2D, last_name);
1093 glBegin (GL_QUADS);
1094 }
1095
1096 glTexCoord2f (0 , 0 ); glVertex2f (px , py );
1097 glTexCoord2f (0 , tex.t); glVertex2f (px , py + tex.h);
1098 glTexCoord2f (tex.s, tex.t); glVertex2f (px + tex.w, py + tex.h);
1099 glTexCoord2f (tex.s, 0 ); glVertex2f (px + tex.w, py );
1100 }
1101 }
1102 }
1103
1104 glEnd ();
1105
1106 glDisable (GL_TEXTURE_2D);
1107 glDisable (GL_BLEND);
1108
1109 EXTEND (SP, 3);
1110 PUSHs (sv_2mortal (newSViv (sw4)));
1111 PUSHs (sv_2mortal (newSViv (sh)));
1112 PUSHs (darkness_sv);
1113}
1114
1115SV *
1116get_rect (CFClient::Map self, int x0, int y0, int w, int h)
1117 CODE:
1118{
1119 int x, y, x1, y1;
1120 SV *data_sv = newSV (w * h * 7 + 5);
1121 uint8_t *data = (uint8_t *)SvPVX (data_sv);
1122
1123 *data++ = 0; /* version 0 format */
1124 *data++ = w >> 8; *data++ = w;
1125 *data++ = h >> 8; *data++ = h;
1126
1127 // we need to do this 'cause we don't keep an absolute coord system for rows
1128 // TODO: treat rows as we treat columns
1129 map_get_row (self, y0 + self->y - self->oy);//D
1130 map_get_row (self, y0 + self->y - self->oy + h - 1);//D
1131
1132 x0 += self->x - self->ox;
1133 y0 += self->y - self->oy;
1134
1135 x1 = x0 + w;
1136 y1 = y0 + h;
1137
1138 for (y = y0; y < y1; y++)
1139 {
1140 maprow *row = 0 <= y && y < self->rows
1141 ? self->row + y
1142 : 0;
1143
1144 for (x = x0; x < x1; x++)
1145 {
1146 if (row && row->c0 <= x && x < row->c1)
1147 {
1148 mapcell *cell = row->col + (x - row->c0);
1149 uint8_t flags = 0;
1150
1151 if (cell->face [0]) flags |= 1;
1152 if (cell->face [1]) flags |= 2;
1153 if (cell->face [2]) flags |= 4;
1154
1155 *data++ = flags;
1156
1157 if (flags & 1)
1158 {
1159 *data++ = cell->face [0] >> 8;
1160 *data++ = cell->face [0];
1161 }
1162
1163 if (flags & 2)
1164 {
1165 *data++ = cell->face [1] >> 8;
1166 *data++ = cell->face [1];
1167 }
1168
1169 if (flags & 4)
1170 {
1171 *data++ = cell->face [2] >> 8;
1172 *data++ = cell->face [2];
1173 }
1174 }
1175 else
1176 *data++ = 0;
1177 }
1178 }
1179
1180 SvPOK_only (data_sv);
1181 SvCUR_set (data_sv, data - (uint8_t *)SvPVX (data_sv));
1182 RETVAL = data_sv;
1183}
1184 OUTPUT:
1185 RETVAL
1186
1187void
1188set_rect (CFClient::Map self, int x0, int y0, uint8_t *data)
1189 PPCODE:
1190{
1191 int x, y, z;
1192 int w, h;
1193 int x1, y1;
1194
1195 if (*data++ != 0)
1196 return; /* version mismatch */
1197
1198 w = *data++ << 8; w |= *data++;
1199 h = *data++ << 8; h |= *data++;
1200
1201 // we need to do this 'cause we don't keep an absolute coord system for rows
1202 // TODO: treat rows as we treat columns
1203 map_get_row (self, y0 + self->y - self->oy);//D
1204 map_get_row (self, y0 + self->y - self->oy + h - 1);//D
1205
1206 x0 += self->x - self->ox;
1207 y0 += self->y - self->oy;
1208
1209 x1 = x0 + w;
1210 y1 = y0 + h;
1211
1212 for (y = y0; y < y1; y++)
1213 {
1214 maprow *row = map_get_row (self, y);
1215
1216 for (x = x0; x < x1; x++)
1217 {
1218 uint8_t flags = *data++;
1219
1220 if (flags)
1221 {
1222 mapface face[3] = { 0, 0, 0 };
1223
1224 mapcell *cell = row_get_cell (row, x);
1225
1226 if (flags & 1) { face[0] = *data++ << 8; face[0] |= *data++; }
1227 if (flags & 2) { face[1] = *data++ << 8; face[1] |= *data++; }
1228 if (flags & 4) { face[2] = *data++ << 8; face[2] |= *data++; }
1229
1230 if (cell->darkness <= 0)
1231 {
1232 cell->darkness = -1;
1233
1234 for (z = 0; z <= 2; z++)
1235 {
1236 cell->face[z] = face[z];
1237
1238 if (face[z] && (face[z] >= self->texs || !self->tex[face [z]].name))
1239 XPUSHs (sv_2mortal (newSViv (face[z])));
1240 }
1241 }
1242 }
1243 }
1244 }
1245}
1246
1247MODULE = CFClient PACKAGE = CFClient::MixChunk
1248
1249CFClient::MixChunk
1250new_from_file (SV *class, char *path)
1251 CODE:
1252 RETVAL = Mix_LoadWAV (path);
1253 OUTPUT:
1254 RETVAL
1255
1256void
1257DESTROY (CFClient::MixChunk self)
1258 CODE:
1259 Mix_FreeChunk (self);
1260
1261int
1262volume (CFClient::MixChunk self, int volume = -1)
1263 CODE:
1264 RETVAL = Mix_VolumeChunk (self, volume);
1265 OUTPUT:
1266 RETVAL
1267
1268int
1269play (CFClient::MixChunk self, int channel = -1, int loops = 0, int ticks = -1)
1270 CODE:
1271 RETVAL = Mix_PlayChannelTimed (channel, self, loops, ticks);
1272 OUTPUT:
1273 RETVAL
1274
1275MODULE = CFClient PACKAGE = CFClient::MixMusic
1276
1277int
1278volume (int volume = -1)
1279 CODE:
1280 RETVAL = Mix_VolumeMusic (volume);
1281 OUTPUT:
1282 RETVAL
1283
1284CFClient::MixMusic
1285new_from_file (SV *class, char *path)
1286 CODE:
1287 RETVAL = Mix_LoadMUS (path);
1288 OUTPUT:
1289 RETVAL
1290
1291void
1292DESTROY (CFClient::MixMusic self)
1293 CODE:
1294 Mix_FreeMusic (self);
1295
1296int
1297play (CFClient::MixMusic self, int loops = -1)
1298 CODE:
1299 RETVAL = Mix_PlayMusic (self, loops);
1300 OUTPUT:
1301 RETVAL
1302
1303MODULE = CFClient PACKAGE = CFClient::OpenGL
1304
1305BOOT:
1306{
1307 HV *stash = gv_stashpv ("CFClient::OpenGL", 1);
1308 static const struct {
1309 const char *name;
1310 IV iv;
1311 } *civ, const_iv[] = {
1312# define const_iv(name) { # name, (IV)name }
1313 const_iv (GL_COLOR_MATERIAL),
1314 const_iv (GL_SMOOTH),
1315 const_iv (GL_FLAT),
1316 const_iv (GL_BLEND),
1317 const_iv (GL_AND),
1318 const_iv (GL_SRC_ALPHA),
1319 const_iv (GL_ONE_MINUS_SRC_ALPHA),
1320 const_iv (GL_RGB),
1321 const_iv (GL_RGBA),
1322 const_iv (GL_UNSIGNED_BYTE),
1323 const_iv (GL_ALPHA4),
1324 const_iv (GL_ALPHA),
1325 const_iv (GL_FLOAT),
1326 const_iv (GL_UNSIGNED_INT_8_8_8_8_REV),
1327 const_iv (GL_COMPILE),
1328 const_iv (GL_TEXTURE_1D),
1329 const_iv (GL_TEXTURE_2D),
1330 const_iv (GL_TEXTURE_ENV),
1331 const_iv (GL_TEXTURE_MAG_FILTER),
1332 const_iv (GL_TEXTURE_MIN_FILTER),
1333 const_iv (GL_TEXTURE_ENV_MODE),
1334 const_iv (GL_TEXTURE_WRAP_S),
1335 const_iv (GL_TEXTURE_WRAP_T),
1336 const_iv (GL_CLAMP),
1337 const_iv (GL_REPEAT),
1338 const_iv (GL_NEAREST),
1339 const_iv (GL_LINEAR),
1340 const_iv (GL_NEAREST_MIPMAP_NEAREST),
1341 const_iv (GL_LINEAR_MIPMAP_NEAREST),
1342 const_iv (GL_NEAREST_MIPMAP_LINEAR),
1343 const_iv (GL_LINEAR_MIPMAP_LINEAR),
1344 const_iv (GL_GENERATE_MIPMAP),
1345 const_iv (GL_LINEAR),
1346 const_iv (GL_MODULATE),
1347 const_iv (GL_REPLACE),
1348 const_iv (GL_COLOR_BUFFER_BIT),
1349 const_iv (GL_PROJECTION),
1350 const_iv (GL_MODELVIEW),
1351 const_iv (GL_COLOR_LOGIC_OP),
1352 const_iv (GL_CONVOLUTION_2D),
1353 const_iv (GL_CONVOLUTION_BORDER_MODE),
1354 const_iv (GL_CONSTANT_BORDER),
1355 const_iv (GL_LINES),
1356 const_iv (GL_QUADS),
1357 const_iv (GL_LINE_LOOP),
1358 const_iv (GL_PERSPECTIVE_CORRECTION_HINT),
1359 const_iv (GL_FASTEST),
1360# undef const_iv
1361 };
1362
1363 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
1364 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
1365}
1366
1367int glGetError ()
1368
1369void glClear (int mask)
1370
1371void glClearColor (float r, float g, float b, float a = 1.0)
1372 PROTOTYPE: @
1373
1374void glEnable (int cap)
1375
1376void glDisable (int cap)
1377
1378void glShadeModel (int mode)
1379
1380void glHint (int target, int mode)
1381
1382void glBlendFunc (int sfactor, int dfactor)
1383
1384void glLogicOp (int opcode)
1385
1386void glMatrixMode (int mode)
1387
1388void glPushMatrix ()
1389
1390void glPopMatrix ()
1391
1392void glLoadIdentity ()
1393
1394void glOrtho (double left, double right, double bottom, double top, double near, double far)
1395
1396void glViewport (int x, int y, int width, int height)
1397
1398void glTranslate (float x, float y, float z = 0.)
1399 CODE:
1400 glTranslatef (x, y, z);
1401
1402void glScale (float x, float y, float z)
1403 CODE:
1404 glScalef (x, y, z);
1405
1406void glRotate (float angle, float x, float y, float z)
1407 CODE:
1408 glRotatef (angle, x, y, z);
1409
1410void glBegin (int mode)
1411
1412void glEnd ()
1413
1414void glColor (float r, float g, float b, float a = 1.0)
1415 PROTOTYPE: @
1416 CODE:
1417 glColor4f (r, g, b, a);
1418
1419void glVertex (float x, float y, float z = 0.)
1420 CODE:
1421 glVertex3f (x, y, z);
1422
1423void glTexCoord (float s, float t)
1424 CODE:
1425 glTexCoord2f (s, t);
1426
1427void glTexEnv (int target, int pname, float param)
1428 CODE:
1429 glTexEnvf (target, pname, param);
1430
1431void glTexParameter (int target, int pname, float param)
1432 CODE:
1433 glTexParameterf (target, pname, param);
1434
1435void glBindTexture (int target, int name)
1436
1437void glConvolutionParameter (int target, int pname, float params)
1438 CODE:
1439 glConvolutionParameterf (target, pname, params);
1440
1441void glConvolutionFilter2D (int target, int internalformat, int width, int height, int format, int type, char *data)
1442
1443void glTexImage2D (int target, int level, int internalformat, int width, int height, int border, int format, int type, char *data)
1444
1445void glCopyTexImage2D (int target, int level, int internalformat, int x, int y, int width, int height, int border)
1446
1447int glGenTexture ()
1448 CODE:
1449{
1450 GLuint name;
1451 glGenTextures (1, &name);
1452 RETVAL = name;
1453}
1454 OUTPUT:
1455 RETVAL
1456
1457void glDeleteTexture (int name)
1458 CODE:
1459{
1460 GLuint name_ = name;
1461 glDeleteTextures (1, &name_);
1462}
1463
1464int glGenList ()
1465 CODE:
1466 RETVAL = glGenLists (1);
1467 OUTPUT:
1468 RETVAL
1469
1470void glDeleteList (int list)
1471 CODE:
1472 glDeleteLists (list, 1);
1473
1474void glNewList (int list, int mode = GL_COMPILE)
1475
1476void glEndList ()
1477
1478void glCallList (int list)
1479

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines