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.43 by root, Mon Apr 17 06:50:26 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>
11 16
12#include <glib/gmacros.h> 17#include <glib/gmacros.h>
13 18
14#include <pango/pango.h> 19#include <pango/pango.h>
15#include <pango/pangofc-fontmap.h> 20#include <pango/pangofc-fontmap.h>
16#include <pango/pangoft2.h> 21#include <pango/pangoft2.h>
17 22
23#ifndef _WIN32
18#include <sys/types.h> 24# include <sys/types.h>
19#include <sys/socket.h> 25# include <sys/socket.h>
20#include <netinet/in.h> 26# include <netinet/in.h>
21#include <netinet/tcp.h> 27# include <netinet/tcp.h>
22
23#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"
24 39
25#define FOW_DARKNESS 32 40#define FOW_DARKNESS 32
26 41
27#define MAP_EXTEND_X 32 42#define MAP_EXTEND_X 32
28#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;
29 49
30static PangoContext *context; 50static PangoContext *context;
31static PangoFontMap *fontmap; 51static PangoFontMap *fontmap;
32 52
33typedef struct cf_layout { 53typedef struct cf_layout {
46layout_update (CFClient__Layout self) 66layout_update (CFClient__Layout self)
47{ 67{
48 /* 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
49 * reasonably well with bitstream vera 69 * reasonably well with bitstream vera
50 */ 70 */
51 PangoFontDescription *font = pango_context_get_font_description (context); 71 PangoFontDescription *font = pango_layout_get_font_description (self->pl);
52 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 }
53} 84}
54 85
55static void 86static void
56layout_get_pixel_size (CFClient__Layout self, int *w, int *h) 87layout_get_pixel_size (CFClient__Layout self, int *w, int *h)
57{ 88{
83 mapcell *col; 114 mapcell *col;
84} maprow; 115} maprow;
85 116
86typedef struct map { 117typedef struct map {
87 int x, y, w, h; 118 int x, y, w, h;
88 int dx, dy; /* delayed map scrolling */
89 int ox, oy; /* offset to virtual global coordinate system */ 119 int ox, oy; /* offset to virtual global coordinate system */
90 int faces; 120 int faces;
91 mapface *face; 121 mapface *face;
92 122
93 int texs; 123 int texs;
94 maptex *tex; 124 maptex *tex;
95 125
96 uint32_t rows; 126 int32_t rows;
97 maprow *row; 127 maprow *row;
98} *CFClient__Map; 128} *CFClient__Map;
99 129
100static char * 130static char *
101prepend (char *ptr, int sze, int inc) 131prepend (char *ptr, int sze, int inc)
196 226
197static void 227static void
198map_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)
199{ 229{
200 int x, y; 230 int x, y;
231 maprow *row;
201 232
202 for (y = y0; y < y0 + h; y++) 233 for (y = y0; y < y0 + h; y++)
203 if (y >= 0) 234 if (y >= 0)
204 { 235 {
205 if (y >= self->rows) 236 if (y >= self->rows)
206 break; 237 break;
207 238
208 maprow *row = self->row + y; 239 row = self->row + y;
209 240
210 for (x = x0; x < x0 + w; x++) 241 for (x = x0; x < x0 + w; x++)
211 if (x >= row->c0) 242 if (x >= row->c0)
212 { 243 {
213 if (x >= row->c1) 244 if (x >= row->c1)
216 row->col[x - row->c0].darkness = -1; 247 row->col[x - row->c0].darkness = -1;
217 } 248 }
218 } 249 }
219} 250}
220 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
221MODULE = CFClient PACKAGE = CFClient 265MODULE = CFClient PACKAGE = CFClient
222 266
223PROTOTYPES: ENABLE 267PROTOTYPES: ENABLE
224 268
225BOOT: 269BOOT:
226{ 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
227 fontmap = pango_ft2_font_map_new (); 381 fontmap = pango_ft2_font_map_new ();
228 pango_ft2_font_map_set_default_substitute ((PangoFT2FontMap *)fontmap, substitute_func, 0, 0); 382 pango_ft2_font_map_set_default_substitute ((PangoFT2FontMap *)fontmap, substitute_func, 0, 0);
229 context = pango_ft2_font_map_create_context ((PangoFT2FontMap *)fontmap); 383 context = pango_ft2_font_map_create_context ((PangoFT2FontMap *)fontmap);
230} 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))
449 {
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);
460 break;
461
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)));
484 }
485}
486
487int
488Mix_OpenAudio (int frequency = 22050, int format = MIX_DEFAULT_FORMAT, int channels = 1, int chunksize = 512)
489 POSTCALL:
490 Mix_HookMusicFinished (music_finished);
491
492void
493Mix_CloseAudio ()
494
495int
496Mix_AllocateChannels (int numchans = -1)
231 497
232void 498void
233lowdelay (int fd, int val = 1) 499lowdelay (int fd, int val = 1)
234 CODE: 500 CODE:
501#ifndef _WIN32
235 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof (val)); 502 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof (val));
503#endif
236 504
237char * 505char *
238gl_version () 506gl_version ()
239 CODE: 507 CODE:
240 RETVAL = (char *)glGetString (GL_VERSION); 508 RETVAL = (char *)glGetString (GL_VERSION);
259{ 527{
260 int count; 528 int count;
261 FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)file, 0, 0, &count); 529 FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)file, 0, 0, &count);
262 PangoFontDescription *font = pango_fc_font_description_from_pattern (pattern, 0); 530 PangoFontDescription *font = pango_fc_font_description_from_pattern (pattern, 0);
263 FcPatternDestroy (pattern); 531 FcPatternDestroy (pattern);
532 pango_font_description_set_absolute_size (font, MIN_FONT_HEIGHT);
264 pango_context_set_font_description (context, font); 533 pango_context_set_font_description (context, font);
265} 534}
266 535
267void 536void
268load_image_inline (SV *image_) 537load_image_inline (SV *image_)
286 croak ("load_image: %s", SDL_GetError ()); 555 croak ("load_image: %s", SDL_GetError ());
287 556
288 fmt.palette = NULL; 557 fmt.palette = NULL;
289 fmt.BitsPerPixel = 32; 558 fmt.BitsPerPixel = 32;
290 fmt.BytesPerPixel = 4; 559 fmt.BytesPerPixel = 4;
560#if SDL_BYTEORDER == SDL_LIL_ENDIAN
291 fmt.Rmask = 0x000000ff; 561 fmt.Rmask = 0x000000ff;
292 fmt.Gmask = 0x0000ff00; 562 fmt.Gmask = 0x0000ff00;
293 fmt.Bmask = 0x00ff0000; 563 fmt.Bmask = 0x00ff0000;
294 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
295 fmt.Rloss = 0; 571 fmt.Rloss = 0;
296 fmt.Gloss = 0; 572 fmt.Gloss = 0;
297 fmt.Bloss = 0; 573 fmt.Bloss = 0;
298 fmt.Aloss = 0; 574 fmt.Aloss = 0;
299 fmt.Rshift = 0; 575 fmt.Rshift = 0;
313 SDL_LockSurface (surface2); 589 SDL_LockSurface (surface2);
314 PUSHs (sv_2mortal (newSVpvn (surface2->pixels, surface2->h * surface2->pitch))); 590 PUSHs (sv_2mortal (newSVpvn (surface2->pixels, surface2->h * surface2->pitch)));
315 SDL_UnlockSurface (surface2); 591 SDL_UnlockSurface (surface2);
316 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)));
317 PUSHs (sv_2mortal (newSViv (GL_RGBA))); 593 PUSHs (sv_2mortal (newSViv (GL_RGBA)));
318 PUSHs (sv_2mortal (newSViv (GL_UNSIGNED_INT_8_8_8_8_REV))); 594 PUSHs (sv_2mortal (newSViv (GL_UNSIGNED_BYTE)));
319 595
320 SDL_FreeSurface (surface); 596 SDL_FreeSurface (surface);
321 SDL_FreeSurface (surface2); 597 SDL_FreeSurface (surface2);
322} 598}
323 599
347} 623}
348 624
349void 625void
350fatal (char *message) 626fatal (char *message)
351 CODE: 627 CODE:
352#ifdef WIN32 628#ifdef _WIN32
353 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);
354#else 630#else
355 fprintf (stderr, "FATAL: %s\n", message); 631 fprintf (stderr, "FATAL: %s\n", message);
356#endif 632#endif
357 exit (1); 633 exit (1);
363 CODE: 639 CODE:
364 New (0, RETVAL, 1, struct cf_layout); 640 New (0, RETVAL, 1, struct cf_layout);
365 RETVAL->base_height = base_height; 641 RETVAL->base_height = base_height;
366 RETVAL->pl = pango_layout_new (context); 642 RETVAL->pl = pango_layout_new (context);
367 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)));
368 OUTPUT: 647 OUTPUT:
369 RETVAL 648 RETVAL
370 649
371void 650void
372DESTROY (CFClient::Layout self) 651DESTROY (CFClient::Layout self)
391 STRLEN textlen; 670 STRLEN textlen;
392 char *text = SvPVutf8 (text_, textlen); 671 char *text = SvPVutf8 (text_, textlen);
393 672
394 pango_layout_set_markup (self->pl, text, textlen); 673 pango_layout_set_markup (self->pl, text, textlen);
395} 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
396 683
397void 684void
398set_height (CFClient::Layout self, int base_height) 685set_height (CFClient::Layout self, int base_height)
399 CODE: 686 CODE:
400 self->base_height = base_height; 687 self->base_height = base_height;
566 { 853 {
567 Append (maptex, self->tex, self->texs, self->texs); 854 Append (maptex, self->tex, self->texs, self->texs);
568 self->texs *= 2; 855 self->texs *= 2;
569 } 856 }
570 857
858 {
571 maptex *tex = self->tex + texid; 859 maptex *tex = self->tex + texid;
572 860
573 tex->name = name; 861 tex->name = name;
574 tex->w = w; 862 tex->w = w;
575 tex->h = h; 863 tex->h = h;
576 tex->s = s; 864 tex->s = s;
577 tex->t = t; 865 tex->t = t;
578 tex->r = r; 866 tex->r = r;
579 tex->g = g; 867 tex->g = g;
580 tex->b = b; 868 tex->b = b;
581 tex->a = a; 869 tex->a = a;
870 }
582} 871}
583 872
584int 873int
585ox (CFClient::Map self) 874ox (CFClient::Map self)
586 ALIAS: 875 ALIAS:
596 885
597void 886void
598scroll (CFClient::Map self, int dx, int dy) 887scroll (CFClient::Map self, int dx, int dy)
599 CODE: 888 CODE:
600{ 889{
601 self->dx += dx; self->ox += dx;
602 self->dy += dy; self->oy += dy;
603}
604
605void
606map1a_update (CFClient::Map self, SV *data_)
607 CODE:
608{
609 if (self->dx > 0) 890 if (dx > 0)
610 map_blank (self, self->x, self->y, self->dx - 1, self->h); 891 map_blank (self, self->x, self->y, dx - 1, self->h);
611 else if (self->dx < 0) 892 else if (dx < 0)
612 map_blank (self, self->x + self->w + self->dx + 1, self->y, 1 - self->dx, self->h); 893 map_blank (self, self->x + self->w + dx + 1, self->y, 1 - dx, self->h);
613 894
614 if (self->dy > 0) 895 if (dy > 0)
615 map_blank (self, self->x, self->y, self->w, self->dy - 1); 896 map_blank (self, self->x, self->y, self->w, dy - 1);
616 else if (self->dy < 0) 897 else if (dy < 0)
617 map_blank (self, self->x, self->y + self->h + self->dy + 1, self->w, 1 - self->dy); 898 map_blank (self, self->x, self->y + self->h + dy + 1, self->w, 1 - dy);
618 899
619 self->x += self->dx; self->dx = 0; 900 self->ox += dx; self->x += dx;
620 self->y += self->dy; self->dy = 0; 901 self->oy += dy; self->y += dy;
621 902
622 while (self->y < 0) 903 while (self->y < 0)
623 { 904 {
624 Prepend (maprow, self->row, self->rows, MAP_EXTEND_Y); 905 Prepend (maprow, self->row, self->rows, MAP_EXTEND_Y);
625 906
626 self->rows += MAP_EXTEND_Y; 907 self->rows += MAP_EXTEND_Y;
627 self->y += MAP_EXTEND_Y; 908 self->y += MAP_EXTEND_Y;
628 } 909 }
910}
629 911
912void
913map1a_update (CFClient::Map self, SV *data_)
914 CODE:
915{
630 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_); 916 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_);
631 uint8_t *data_end = (uint8_t *)SvEND (data_); 917 uint8_t *data_end = (uint8_t *)SvEND (data_);
918 mapcell *cell;
919 int x, y, flags;
632 920
633 while (data < data_end) 921 while (data < data_end)
634 { 922 {
635 int flags = (data [0] << 8) + data [1]; data += 2; 923 flags = (data [0] << 8) + data [1]; data += 2;
636 924
637 int x = ((flags >> 10) & 63) + self->x; 925 x = ((flags >> 10) & 63) + self->x;
638 int y = ((flags >> 4) & 63) + self->y; 926 y = ((flags >> 4) & 63) + self->y;
639 927
640 mapcell *cell = map_get_cell (self, x, y); 928 cell = map_get_cell (self, x, y);
641 929
642 if (flags & 15) 930 if (flags & 15)
643 { 931 {
644 if (cell->darkness < 0) // && x < self->w && y < self->h) 932 if (cell->darkness < 0)
645 { 933 {
646 cell->darkness = 0; 934 cell->darkness = 0;
647 cell->face [0] = 0; 935 cell->face [0] = 0;
648 cell->face [1] = 0; 936 cell->face [1] = 0;
649 cell->face [2] = 0; 937 cell->face [2] = 0;
650 } 938 }
651 939
652 cell->darkness = flags & 8 ? *data++ : 255; 940 cell->darkness = flags & 8 ? *data++ : 255;
653 941
654 //TODO: don't trust server data to be in-range(!) 942 //TODO: don't trust server data to be in-range(!)
655 943
656 if (flags & 4) 944 if (flags & 4)
672 cell->darkness = -1; 960 cell->darkness = -1;
673 } 961 }
674} 962}
675 963
676SV * 964SV *
677mapmap (CFClient::Map self, int w, int h) 965mapmap (CFClient::Map self, int x0, int y0, int w, int h)
678 CODE: 966 CODE:
679{ 967{
680 int x0, x1, x; 968 int x1, x;
681 int y0, y1, y; 969 int y1, y;
682 int z; 970 int z;
683 SV *map_sv = newSV (w * h * sizeof (uint32_t)); 971 SV *map_sv = newSV (w * h * sizeof (uint32_t));
684 uint32_t *map = (uint32_t *)SvPVX (map_sv); 972 uint32_t *map = (uint32_t *)SvPVX (map_sv);
685 973
686 SvPOK_only (map_sv); 974 SvPOK_only (map_sv);
687 SvCUR_set (map_sv, w * h * sizeof (uint32_t)); 975 SvCUR_set (map_sv, w * h * sizeof (uint32_t));
688 976
689 x0 = self->x - w / 2; x1 = x0 + w; 977 x0 += self->x; x1 = x0 + w;
690 y0 = self->y - h / 2; y1 = y0 + h; 978 y0 += self->y; y1 = y0 + h;
691 979
692 for (y = y0; y < y1; y++) 980 for (y = y0; y < y1; y++)
693 { 981 {
694 maprow *row = 0 <= y && y < self->rows 982 maprow *row = 0 <= y && y < self->rows
695 ? self->row + y 983 ? self->row + y
735 1023
736void 1024void
737draw (CFClient::Map self, int shift_x, int shift_y, int x0, int y0, int sw, int sh) 1025draw (CFClient::Map self, int shift_x, int shift_y, int x0, int y0, int sw, int sh)
738 PPCODE: 1026 PPCODE:
739{ 1027{
1028 int vx, vy;
1029 int x, y, z;
1030 int last_name;
1031 mapface face;
740 int sw4 = (sw + 3) & ~3; 1032 int sw4 = (sw + 3) & ~3;
741 SV *darkness_sv = sv_2mortal (newSV (sw4 * sh)); 1033 SV *darkness_sv = sv_2mortal (newSV (sw4 * sh));
742 uint8_t *darkness = (uint8_t *)SvPVX (darkness_sv); 1034 uint8_t *darkness = (uint8_t *)SvPVX (darkness_sv);
1035
743 memset (darkness, 255, sw4 * sh); 1036 memset (darkness, 255, sw4 * sh);
744 SvPOK_only (darkness_sv); 1037 SvPOK_only (darkness_sv);
745 SvCUR_set (darkness_sv, sw4 * sh); 1038 SvCUR_set (darkness_sv, sw4 * sh);
746 1039
747 int vx = self->x + (self->w - sw) / 2 - shift_x; 1040 vx = self->x + (self->w - sw) / 2 - shift_x;
748 int vy = self->y + (self->h - sh) / 2 - shift_y; 1041 vy = self->y + (self->h - sh) / 2 - shift_y;
749 1042
750 /* 1043 /*
751 int vx = self->vx = self->w >= sw 1044 int vx = self->vx = self->w >= sw
752 ? self->x + (self->w - sw) / 2 1045 ? self->x + (self->w - sw) / 2
753 : MIN (self->x, MAX (self->x + self->w - sw + 1, self->vx)); 1046 : MIN (self->x, MAX (self->x + self->w - sw + 1, self->vx));
762 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1055 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
763 glEnable (GL_BLEND); 1056 glEnable (GL_BLEND);
764 glEnable (GL_TEXTURE_2D); 1057 glEnable (GL_TEXTURE_2D);
765 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1058 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
766 1059
767 int x, y, z;
768
769 int last_name = 0;
770
771 glBegin (GL_QUADS); 1060 glBegin (GL_QUADS);
1061
1062 last_name = 0;
772 1063
773 for (z = 0; z < 3; z++) 1064 for (z = 0; z < 3; z++)
774 for (y = 0; y < sh; y++) 1065 for (y = 0; y < sh; y++)
775 if (0 <= y + vy && y + vy < self->rows) 1066 if (0 <= y + vy && y + vy < self->rows)
776 { 1067 {
783 1074
784 darkness[y * sw4 + x] = cell->darkness < 0 1075 darkness[y * sw4 + x] = cell->darkness < 0
785 ? 255 - FOW_DARKNESS 1076 ? 255 - FOW_DARKNESS
786 : 255 - cell->darkness; 1077 : 255 - cell->darkness;
787 1078
788 mapface face = cell->face [z]; 1079 face = cell->face [z];
789 1080
790 if (face) 1081 if (face)
791 { 1082 {
792 maptex tex = self->tex [face]; 1083 maptex tex = self->tex [face];
793 1084
832 *data++ = 0; /* version 0 format */ 1123 *data++ = 0; /* version 0 format */
833 *data++ = w >> 8; *data++ = w; 1124 *data++ = w >> 8; *data++ = w;
834 *data++ = h >> 8; *data++ = h; 1125 *data++ = h >> 8; *data++ = h;
835 1126
836 // we need to do this 'cause we don't keep an absolute coord system for rows 1127 // we need to do this 'cause we don't keep an absolute coord system for rows
837 // TODO: treat rows as we treat 1128 // TODO: treat rows as we treat columns
838 map_get_row (self, y0 + self->y - self->oy);//D 1129 map_get_row (self, y0 + self->y - self->oy);//D
839 map_get_row (self, y0 + self->y - self->oy + h - 1);//D 1130 map_get_row (self, y0 + self->y - self->oy + h - 1);//D
840 1131
841 x0 += self->x - self->ox; 1132 x0 += self->x - self->ox;
842 y0 += self->y - self->oy; 1133 y0 += self->y - self->oy;
853 for (x = x0; x < x1; x++) 1144 for (x = x0; x < x1; x++)
854 { 1145 {
855 if (row && row->c0 <= x && x < row->c1) 1146 if (row && row->c0 <= x && x < row->c1)
856 { 1147 {
857 mapcell *cell = row->col + (x - row->c0); 1148 mapcell *cell = row->col + (x - row->c0);
858
859 uint8_t flags = 0; 1149 uint8_t flags = 0;
860 1150
861 if (cell->face [0]) flags |= 1; 1151 if (cell->face [0]) flags |= 1;
862 if (cell->face [1]) flags |= 2; 1152 if (cell->face [1]) flags |= 2;
863 if (cell->face [2]) flags |= 4; 1153 if (cell->face [2]) flags |= 4;
897void 1187void
898set_rect (CFClient::Map self, int x0, int y0, uint8_t *data) 1188set_rect (CFClient::Map self, int x0, int y0, uint8_t *data)
899 PPCODE: 1189 PPCODE:
900{ 1190{
901 int x, y, z; 1191 int x, y, z;
1192 int w, h;
902 int x1, y1; 1193 int x1, y1;
903 1194
904 if (*data++ != 0) 1195 if (*data++ != 0)
905 return; /* version mismatch */ 1196 return; /* version mismatch */
906 1197
907 int w = *data++ << 8; w |= *data++; 1198 w = *data++ << 8; w |= *data++;
908 int h = *data++ << 8; h |= *data++; 1199 h = *data++ << 8; h |= *data++;
909 1200
910 // we need to do this 'cause we don't keep an absolute coord system for rows 1201 // we need to do this 'cause we don't keep an absolute coord system for rows
911 // TODO: treat rows as we treat 1202 // TODO: treat rows as we treat columns
912 map_get_row (self, y0 + self->y - self->oy);//D 1203 map_get_row (self, y0 + self->y - self->oy);//D
913 map_get_row (self, y0 + self->y - self->oy + h - 1);//D 1204 map_get_row (self, y0 + self->y - self->oy + h - 1);//D
914 1205
915 x0 += self->x - self->ox; 1206 x0 += self->x - self->ox;
916 y0 += self->y - self->oy; 1207 y0 += self->y - self->oy;
951 } 1242 }
952 } 1243 }
953 } 1244 }
954} 1245}
955 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