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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines