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.262 by root, Wed Jul 16 20:12:27 2008 UTC vs.
Revision 1.327 by root, Sun Nov 18 12:01:50 2018 UTC

15 15
16#include "EXTERN.h" 16#include "EXTERN.h"
17#include "perl.h" 17#include "perl.h"
18#include "XSUB.h" 18#include "XSUB.h"
19 19
20#include "flat_hash_map.hpp"
21
20#ifdef _WIN32 22#ifdef _WIN32
21# undef pipe 23# undef pipe
22// microsoft vs. C 24// microsoft vs. C
23# define sqrtf(x) sqrt(x) 25# define sqrtf(x) sqrt(x)
24# define roundf(x) (int)(x)
25# define atan2f(x,y) atan2(x,y) 26# define atan2f(x,y) atan2(x,y)
26# define M_PI 3.14159265f 27# define M_PI 3.14159265f
27#endif 28#endif
28 29
29#include <assert.h> 30#include <cassert>
30#include <math.h> 31#include <cmath>
31#include <string.h> 32#include <cstring>
32#include <stdio.h> 33#include <cstdio>
33#include <stdlib.h> 34#include <cstdlib>
35
36#include <utility>
37#include <bitset>
34 38
35#define USE_RWOPS 1 // for SDL_mixer:LoadMUS_RW 39#define USE_RWOPS 1 // for SDL_mixer:LoadMUS_RW
36 40
37#include <SDL.h> 41#include <SDL.h>
38#include <SDL_thread.h> 42#include <SDL_thread.h>
39#include <SDL_endian.h> 43#include <SDL_endian.h>
40#include <SDL_image.h> 44#include <SDL_image.h>
41#include <SDL_mixer.h> 45#include <SDL_mixer.h>
42#include <SDL_opengl.h> 46#include <SDL_opengl.h>
43 47
48/* work around os x broken headers */
49#ifdef __MACOSX__
50typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
51typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
52typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t);
53#endif
54
44#define PANGO_ENABLE_BACKEND 55#define PANGO_ENABLE_BACKEND
45#define G_DISABLE_CAST_CHECKS 56#define G_DISABLE_CAST_CHECKS
46 57
47#include <glib/gmacros.h> 58#include <glib.h>
48 59
49#include <pango/pango.h> 60#include <pango/pango.h>
50 61
51#ifndef PANGO_VERSION_CHECK 62#ifndef PANGO_VERSION_CHECK
52# define PANGO_VERSION_CHECK(a,b,c) 0 63# define PANGO_VERSION_CHECK(a,b,c) 0
76#define expect_false(expr) expect ((expr) != 0, 0) 87#define expect_false(expr) expect ((expr) != 0, 0)
77#define expect_true(expr) expect ((expr) != 0, 1) 88#define expect_true(expr) expect ((expr) != 0, 1)
78 89
79#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, object replacement character */ 90#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, object replacement character */
80 91
92/* this is used as fow flag as well, so has to have a different value */
93/* then anything that is computed by incoming darkness */
81#define FOW_DARKNESS 32 94#define FOW_DARKNESS 50
95#define DARKNESS_ADJUST(n) (n)
82 96
83#define MAP_EXTEND_X 32 97#define MAP_EXTEND_X 32
84#define MAP_EXTEND_Y 512 98#define MAP_EXTEND_Y 512
85 99
86#define MIN_FONT_HEIGHT 10 100#define MIN_FONT_HEIGHT 10
87 101
88/* mask out modifiers we are not interested in */ 102/* mask out modifiers we are not interested in */
89#define MOD_MASK (KMOD_CTRL | KMOD_SHIFT | KMOD_ALT | KMOD_META) 103#define MOD_MASK (KMOD_CTRL | KMOD_SHIFT | KMOD_ALT | KMOD_META)
90 104
91#if 1 105#define KMOD_LRAM 0x10000 // our extension
92# define PARACHUTE SDL_INIT_NOPARACHUTE 106
93#else 107#define TEXID_SPEECH 1
94# define PARACHUTE 0 108#define TEXID_NOFACE 2
95#endif 109
110static char *
111fast_sv_grow (SV *sv, STRLEN need)
112{
113 STRLEN len = SvLEN (sv);
114 STRLEN want = SvCUR (sv) + need;
115
116 if (expect_false (len < want))
117 {
118 do
119 len *= 2;
120 while (len < want);
121
122 sv_grow (sv, len);
123 }
124
125 SvCUR_set (sv, want);
126 return SvEND (sv) - need;
127}
96 128
97static AV *texture_av; 129static AV *texture_av;
98 130
99static struct 131static struct
100{ 132{
157{ 189{
158 GSList *attrs = run->item->analysis.extra_attrs; 190 GSList *attrs = run->item->analysis.extra_attrs;
159 191
160 while (attrs) 192 while (attrs)
161 { 193 {
162 PangoAttribute *attr = attrs->data; 194 PangoAttribute *attr = (PangoAttribute *)attrs->data;
163 195
164 if (attr->klass->type == PANGO_ATTR_SHAPE) 196 if (attr->klass->type == PANGO_ATTR_SHAPE)
165 return 1; 197 return 1;
166 198
167 attrs = attrs->next; 199 attrs = attrs->next;
168 } 200 }
169 201
170 return 0; 202 return 0;
171} 203}
172 204
173typedef struct cf_layout { 205struct cf_layout {
174 PangoLayout *pl; 206 PangoLayout *pl;
175 float r, g, b, a; // default color for rgba mode 207 float r, g, b, a; // default color for rgba mode
176 int base_height; 208 int base_height;
177 DC__Font font; 209 DC__Font font;
178 rc_t *rc; 210 rc_t rc;
179} *DC__Layout; 211};
212
213typedef cf_layout *DC__Layout;
180 214
181static DC__Font default_font; 215static DC__Font default_font;
182static PangoContext *opengl_context; 216static PangoContext *opengl_context;
183static PangoFontMap *opengl_fontmap; 217static PangoFontMap *opengl_fontmap;
184 218
185static void 219static void
186substitute_func (FcPattern *pattern, gpointer data) 220substitute_func (FcPattern *pattern, gpointer data)
187{ 221{
188 FcPatternAddBool (pattern, FC_HINTING, 1); 222 FcPatternAddBool (pattern, FC_HINTING, 1);
189#ifdef FC_HINT_STYLE 223#ifdef FC_HINT_STYLE
190 FcPatternAddBool (pattern, FC_HINT_STYLE, FC_HINT_FULL); 224 FcPatternAddInteger (pattern, FC_HINT_STYLE, FC_HINT_FULL);
191#endif 225#endif
192 FcPatternAddBool (pattern, FC_AUTOHINT, 0); 226 FcPatternAddBool (pattern, FC_AUTOHINT, 0);
193} 227}
194 228
195static void 229static void
225} 259}
226 260
227typedef uint16_t tileid; 261typedef uint16_t tileid;
228typedef uint16_t faceid; 262typedef uint16_t faceid;
229 263
230typedef struct { 264struct maptex
265{
231 GLuint name; 266 GLuint name;
232 int w, h; 267 int w, h;
233 float s, t; 268 float s, t;
234 uint8_t r, g, b, a; 269 uint8_t r, g, b, a;
235 tileid smoothtile; 270 tileid smoothtile;
236 uint8_t smoothlevel; 271 uint8_t smoothlevel;
237} maptex; 272 uint8_t unused; /* set to zero on use */
273};
238 274
239typedef struct { 275struct mapcell
276{
240 uint32_t player; 277 uint32_t player;
241 tileid tile[3]; 278 tileid tile[3];
242 uint16_t darkness; 279 uint16_t darkness;
243 uint8_t stat_width, stat_hp, flags, smoothmax; 280 uint8_t stat_width, stat_hp, flags, smoothmax;
244} mapcell; 281};
245 282
246typedef struct { 283struct maprow
284{
247 int32_t c0, c1; 285 int32_t c0, c1;
248 mapcell *col; 286 mapcell *col;
249} maprow; 287};
250 288
251typedef struct map { 289struct mapgrid {
252 int x, y, w, h; 290 int x, y, w, h;
253 int ox, oy; /* offset to virtual global coordinate system */ 291 int ox, oy; /* offset to virtual global coordinate system */
254 int faces; tileid *face2tile; // [faceid] 292 std::vector<tileid> tile;
255 int texs; maptex *tex; // [tileid] 293 std::vector<maptex> tex;
256 294
257 int32_t rows; 295 int32_t rows;
258 maprow *row; 296 maprow *row;
259} *DC__Map; 297
298 ~mapgrid ()
299 {
300 clear_cells ();
301 }
302
303 void clear_cells ();
304};
305
306typedef mapgrid *DC__Map;
260 307
261static char * 308static char *
262prepend (char *ptr, int sze, int inc) 309prepend (char *ptr, int sze, int inc)
263{ 310{
264 char *p; 311 char *p;
281} 328}
282 329
283#define Append(type,ptr,sze,inc) (ptr) = (type *)append ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type)) 330#define Append(type,ptr,sze,inc) (ptr) = (type *)append ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type))
284#define Prepend(type,ptr,sze,inc) (ptr) = (type *)prepend ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type)) 331#define Prepend(type,ptr,sze,inc) (ptr) = (type *)prepend ((char *)ptr, (sze) * sizeof (type), (inc) * sizeof (type))
285 332
286static void
287need_facenum (struct map *self, faceid face)
288{
289 while (self->faces <= face)
290 {
291 Append (tileid, self->face2tile, self->faces, self->faces);
292 self->faces *= 2;
293 }
294}
295
296static void
297need_texid (struct map *self, int texid)
298{
299 while (self->texs <= texid)
300 {
301 Append (maptex, self->tex, self->texs, self->texs);
302 self->texs *= 2;
303 }
304}
305
306static maprow * 333static maprow *
307map_get_row (DC__Map self, int y) 334map_get_row (mapgrid *self, int y)
308{ 335{
309 if (0 > y) 336 if (0 > y)
310 { 337 {
311 int extend = - y + MAP_EXTEND_Y; 338 int extend = - y + MAP_EXTEND_Y;
312 Prepend (maprow, self->row, self->rows, extend); 339 Prepend (maprow, self->row, self->rows, extend);
350 377
351 return row->col + (x - row->c0); 378 return row->col + (x - row->c0);
352} 379}
353 380
354static mapcell * 381static mapcell *
355map_get_cell (DC__Map self, int x, int y) 382map_get_cell (mapgrid *self, int x, int y)
356{ 383{
357 return row_get_cell (map_get_row (self, y), x); 384 return row_get_cell (map_get_row (self, y), x);
358} 385}
359 386
387void mapgrid::clear_cells ()
388{
389 int r;
390
391 for (r = 0; r < rows; r++)
392 Safefree (row[r].col);
393
394 Safefree (row);
395
396 x = 0;
397 y = 0;
398 ox = 0;
399 oy = 0;
400 row = 0;
401 rows = 0;
402}
403
404#define CELL_CLEAR(cell) \
405 do { \
406 if ((cell)->player) \
407 (cell)->tile [2] = 0; \
408 (cell)->darkness = 0; \
409 (cell)->stat_hp = 0; \
410 (cell)->flags = 0; \
411 (cell)->player = 0; \
412 } while (0)
413
360static void 414static void
361map_clear (DC__Map self)
362{
363 int r;
364
365 for (r = 0; r < self->rows; r++)
366 Safefree (self->row[r].col);
367
368 Safefree (self->row);
369
370 self->x = 0;
371 self->y = 0;
372 self->ox = 0;
373 self->oy = 0;
374 self->row = 0;
375 self->rows = 0;
376}
377
378static void
379map_blank (DC__Map self, int x0, int y0, int w, int h) 415map_blank (mapgrid *self, int x0, int y0, int w, int h)
380{ 416{
381 int x, y; 417 int x, y;
382 maprow *row; 418 maprow *row;
383 mapcell *cell; 419 mapcell *cell;
384 420
396 if (x >= row->c1) 432 if (x >= row->c1)
397 break; 433 break;
398 434
399 cell = row->col + x - row->c0; 435 cell = row->col + x - row->c0;
400 436
401 cell->darkness = 0; 437 CELL_CLEAR (cell);
402 cell->stat_hp = 0;
403 cell->flags = 0;
404 cell->player = 0;
405 } 438 }
406 } 439 }
407} 440}
408 441
409typedef struct { 442struct smooth_key
443{
410 tileid tile; 444 tileid tile;
411 uint8_t x, y, level; 445 uint8_t x, y, level;
412} smooth_key; 446
447 bool operator == (const smooth_key &o) const
448 {
449 return tile == o.tile && x == o.x && y == o.y && level == o.level;
450 }
451};
452
453typedef ska::flat_hash_map<smooth_key, IV> smooth_hash;
454
455namespace std {
456 template <>
457 struct hash<smooth_key>
458 {
459 size_t operator () (const smooth_key &v) const
460 {
461 return v.tile + (v.x << 8) + (v.y << 16) + (v.level << 24);
462 }
463 };
464}
413 465
414static void 466static void
415smooth_or_bits (HV *hv, smooth_key *key, IV bits) 467smooth_or_bits (smooth_hash &h, smooth_key &key, IV bits)
416{ 468{
417 SV **sv = hv_fetch (hv, (char *)key, sizeof (*key), 1); 469 auto &&it = h.find (key);
418 470
419 if (SvIOK (*sv)) 471 if (it == h.end ())
420 SvIV_set (*sv, SvIVX (*sv) | bits); 472 h.insert (std::make_pair (key, bits));
421 else 473 else
422 sv_setiv (*sv, bits); 474 it->second |= bits;
423} 475}
424 476
425static void 477static void
426music_finished (void) 478music_finished (void)
427{ 479{
444 ev.code = 1; 496 ev.code = 1;
445 ev.data1 = (void *)(long)channel; 497 ev.data1 = (void *)(long)channel;
446 ev.data2 = 0; 498 ev.data2 = 0;
447 499
448 SDL_PushEvent ((SDL_Event *)&ev); 500 SDL_PushEvent ((SDL_Event *)&ev);
501}
502
503// approximately divide by 255
504static unsigned int
505div255 (unsigned int n)
506{
507 return (n + (n >> 8)) >> 8;
449} 508}
450 509
451static unsigned int 510static unsigned int
452minpot (unsigned int n) 511minpot (unsigned int n)
453{ 512{
520 if (!svp || !SvTRUE (*svp)) 579 if (!svp || !SvTRUE (*svp))
521 return 0; 580 return 0;
522 581
523 return 1; 582 return 1;
524} 583}
584
585/******************************************************************************/
586
587/* process keyboard modifiers */
588static int
589mod_munge (int mod)
590{
591 mod &= MOD_MASK;
592
593 if (mod & (KMOD_META | KMOD_ALT))
594 mod |= KMOD_LRAM;
595
596 return mod;
597}
598
599static void
600deliantra_main (SV *real_main)
601{
602 dSP;
603
604 PUSHMARK (SP);
605 call_sv (real_main, G_DISCARD | G_VOID);
606}
607
608#ifdef __MACOSX__
609 static SV *real_main;
610
611 /* to due surprising braindamage on the side of SDL design, we
612 * do some mind-boggling hack here: SDL requires a custom main()
613 * on OS X, so... we provide one and call the original main(), which,
614 * due to shared library magic, calls -lSDLmain's main, not perl's main,
615 * and which calls our main (== SDL_main) back.
616 */
617 extern C_LINKAGE int
618 main (int argc, char *argv[])
619 {
620 deliantra_main (real_main);
621 }
622
623 #undef main
624
625 extern C_LINKAGE int main (int argc, char *argv[]);
626
627 static void
628 SDL_main_hack (SV *real_main_)
629 {
630 real_main = real_main_;
631
632 char *argv[] = { "deliantra client", 0 };
633 (main) (1, argv);
634 }
635#else
636 static void
637 SDL_main_hack (SV *real_main)
638 {
639 deliantra_main (real_main);
640 }
641#endif
525 642
526MODULE = Deliantra::Client PACKAGE = DC 643MODULE = Deliantra::Client PACKAGE = DC
527 644
528PROTOTYPES: ENABLE 645PROTOTYPES: ENABLE
529 646
558 const_iv (SDL_USEREVENT), 675 const_iv (SDL_USEREVENT),
559 676
560 const_iv (SDL_APPINPUTFOCUS), 677 const_iv (SDL_APPINPUTFOCUS),
561 const_iv (SDL_APPMOUSEFOCUS), 678 const_iv (SDL_APPMOUSEFOCUS),
562 const_iv (SDL_APPACTIVE), 679 const_iv (SDL_APPACTIVE),
680
681
682 const_iv (SDLK_UNKNOWN),
683 const_iv (SDLK_FIRST),
684 const_iv (SDLK_BACKSPACE),
685 const_iv (SDLK_TAB),
686 const_iv (SDLK_CLEAR),
687 const_iv (SDLK_RETURN),
688 const_iv (SDLK_PAUSE),
689 const_iv (SDLK_ESCAPE),
690 const_iv (SDLK_SPACE),
691 const_iv (SDLK_EXCLAIM),
692 const_iv (SDLK_QUOTEDBL),
693 const_iv (SDLK_HASH),
694 const_iv (SDLK_DOLLAR),
695 const_iv (SDLK_AMPERSAND),
696 const_iv (SDLK_QUOTE),
697 const_iv (SDLK_LEFTPAREN),
698 const_iv (SDLK_RIGHTPAREN),
699 const_iv (SDLK_ASTERISK),
700 const_iv (SDLK_PLUS),
701 const_iv (SDLK_COMMA),
702 const_iv (SDLK_MINUS),
703 const_iv (SDLK_PERIOD),
704 const_iv (SDLK_SLASH),
705 const_iv (SDLK_0),
706 const_iv (SDLK_1),
707 const_iv (SDLK_2),
708 const_iv (SDLK_3),
709 const_iv (SDLK_4),
710 const_iv (SDLK_5),
711 const_iv (SDLK_6),
712 const_iv (SDLK_7),
713 const_iv (SDLK_8),
714 const_iv (SDLK_9),
715 const_iv (SDLK_COLON),
716 const_iv (SDLK_SEMICOLON),
717 const_iv (SDLK_LESS),
718 const_iv (SDLK_EQUALS),
719 const_iv (SDLK_GREATER),
720 const_iv (SDLK_QUESTION),
721 const_iv (SDLK_AT),
722
723 const_iv (SDLK_LEFTBRACKET),
724 const_iv (SDLK_BACKSLASH),
725 const_iv (SDLK_RIGHTBRACKET),
726 const_iv (SDLK_CARET),
727 const_iv (SDLK_UNDERSCORE),
728 const_iv (SDLK_BACKQUOTE),
729 const_iv (SDLK_DELETE),
563 730
564 const_iv (SDLK_FIRST), 731 const_iv (SDLK_FIRST),
565 const_iv (SDLK_LAST), 732 const_iv (SDLK_LAST),
566 const_iv (SDLK_KP0), 733 const_iv (SDLK_KP0),
567 const_iv (SDLK_KP1), 734 const_iv (SDLK_KP1),
643 const_iv (KMOD_RMETA), 810 const_iv (KMOD_RMETA),
644 const_iv (KMOD_NUM), 811 const_iv (KMOD_NUM),
645 const_iv (KMOD_CAPS), 812 const_iv (KMOD_CAPS),
646 const_iv (KMOD_MODE), 813 const_iv (KMOD_MODE),
647 814
815 const_iv (KMOD_LRAM),
816
648 const_iv (MIX_DEFAULT_FORMAT), 817 const_iv (MIX_DEFAULT_FORMAT),
818
819 const_iv (SDL_INIT_TIMER),
820 const_iv (SDL_INIT_AUDIO),
821 const_iv (SDL_INIT_VIDEO),
822 const_iv (SDL_INIT_CDROM),
823 const_iv (SDL_INIT_JOYSTICK),
824 const_iv (SDL_INIT_EVERYTHING),
825 const_iv (SDL_INIT_NOPARACHUTE),
826 const_iv (SDL_INIT_EVENTTHREAD),
827
828 const_iv (SDL_GL_RED_SIZE),
829 const_iv (SDL_GL_GREEN_SIZE),
830 const_iv (SDL_GL_BLUE_SIZE),
831 const_iv (SDL_GL_ALPHA_SIZE),
832 const_iv (SDL_GL_DOUBLEBUFFER),
833 const_iv (SDL_GL_BUFFER_SIZE),
834 const_iv (SDL_GL_DEPTH_SIZE),
835 const_iv (SDL_GL_STENCIL_SIZE),
836 const_iv (SDL_GL_ACCUM_RED_SIZE),
837 const_iv (SDL_GL_ACCUM_GREEN_SIZE),
838 const_iv (SDL_GL_ACCUM_BLUE_SIZE),
839 const_iv (SDL_GL_ACCUM_ALPHA_SIZE),
840 const_iv (SDL_GL_STEREO),
841 const_iv (SDL_GL_MULTISAMPLEBUFFERS),
842 const_iv (SDL_GL_MULTISAMPLESAMPLES),
843 const_iv (SDL_GL_ACCELERATED_VISUAL),
844 const_iv (SDL_GL_SWAP_CONTROL),
845
846 const_iv (FOW_DARKNESS)
649# undef const_iv 847# undef const_iv
650 }; 848 };
651 849
652 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 850 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
653 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 851 newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
654 852
655 assert (SDLK_MODIFIER_MIN == SDLK_NUMLOCK); 853 assert (SDLK_MODIFIER_MIN == SDLK_NUMLOCK);
656 assert (SDLK_MODIFIER_MAX == SDLK_COMPOSE); 854 assert (SDLK_MODIFIER_MAX == SDLK_COMPOSE);
657} 855}
658 856
674NV ceil (NV x) 872NV ceil (NV x)
675 873
676IV minpot (UV n) 874IV minpot (UV n)
677 875
678IV popcount (UV n) 876IV popcount (UV n)
877
878NV distance (NV dx, NV dy)
879 CODE:
880 RETVAL = pow (dx * dx + dy * dy, 0.5);
881 OUTPUT:
882 RETVAL
679 883
680void 884void
681pango_init () 885pango_init ()
682 CODE: 886 CODE:
683{ 887{
689 pango_context_set_language (opengl_context, pango_language_from_string ("en")); 893 pango_context_set_language (opengl_context, pango_language_from_string ("en"));
690 /*pango_context_set_base_dir (opengl_context, PANGO_DIRECTION_WEAK_LTR);*/ 894 /*pango_context_set_base_dir (opengl_context, PANGO_DIRECTION_WEAK_LTR);*/
691#endif 895#endif
692} 896}
693 897
694char *
695SDL_GetError () 898char *SDL_GetError ()
696 899
697int 900void SDL_main_hack (SV *real_main)
698SDL_Init (U32 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | PARACHUTE) 901 PROTOTYPE: &
699 902
700void 903int SDL_Init (U32 flags)
904
905int SDL_InitSubSystem (U32 flags)
906
907void SDL_QuitSubSystem (U32 flags)
908
701SDL_Quit () 909void SDL_Quit ()
910
911int SDL_GL_SetAttribute (int attr, int value)
912 C_ARGS: (SDL_GLattr)attr, value
913
914int SDL_GL_GetAttribute (int attr)
915 CODE:
916 if (SDL_GL_GetAttribute ((SDL_GLattr)attr, &RETVAL))
917 XSRETURN_UNDEF;
918 OUTPUT:
919 RETVAL
702 920
703void 921void
704SDL_ListModes (int rgb, int alpha) 922SDL_ListModes (int rgb, int alpha)
705 PPCODE: 923 PPCODE:
706{ 924{
718 SDL_GL_SetAttribute (SDL_GL_ACCUM_GREEN_SIZE, 0); 936 SDL_GL_SetAttribute (SDL_GL_ACCUM_GREEN_SIZE, 0);
719 SDL_GL_SetAttribute (SDL_GL_ACCUM_BLUE_SIZE , 0); 937 SDL_GL_SetAttribute (SDL_GL_ACCUM_BLUE_SIZE , 0);
720 SDL_GL_SetAttribute (SDL_GL_ACCUM_ALPHA_SIZE, 0); 938 SDL_GL_SetAttribute (SDL_GL_ACCUM_ALPHA_SIZE, 0);
721 939
722 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); 940 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
723#if SDL_VERSION_ATLEAST(1,2,10)
724 SDL_GL_SetAttribute (SDL_GL_ACCELERATED_VISUAL, 1);
725 SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 1); 941 SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 1);
726#endif
727 942
728 m = SDL_ListModes (0, SDL_FULLSCREEN | SDL_OPENGL); 943 m = SDL_ListModes (0, SDL_FULLSCREEN | SDL_OPENGL);
729 944
730 if (m && m != (SDL_Rect **)-1) 945 if (m && m != (SDL_Rect **)-1)
731 while (*m) 946 while (*m)
732 { 947 {
733 if ((*m)->w >= 800 && (*m)->h >= 480) 948 if ((*m)->w >= 400 && (*m)->h >= 300)
734 { 949 {
735 AV *av = newAV (); 950 AV *av = newAV ();
736 av_push (av, newSViv ((*m)->w)); 951 av_push (av, newSViv ((*m)->w));
737 av_push (av, newSViv ((*m)->h)); 952 av_push (av, newSViv ((*m)->h));
738 av_push (av, newSViv (rgb)); 953 av_push (av, newSViv (rgb));
761 ); 976 );
762 977
763 if (RETVAL) 978 if (RETVAL)
764 { 979 {
765 av_clear (texture_av); 980 av_clear (texture_av);
766
767 SDL_WM_SetCaption ("Deliantra MORPG Client " VERSION, "Deliantra");
768#define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name); 981#define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name);
769#include "glfunc.h" 982#include "glfunc.h"
770#undef GL_FUNC 983#undef GL_FUNC
984 if (!gl.ActiveTexture ) gl.ActiveTexture = gl.ActiveTextureARB;
985 if (!gl.MultiTexCoord2f) gl.MultiTexCoord2f = gl.MultiTexCoord2fARB;
771 } 986 }
772} 987}
773 OUTPUT: 988 OUTPUT:
774 RETVAL 989 RETVAL
990
991void
992SDL_WM_SetCaption (const char *title, const char *icon)
775 993
776void 994void
777SDL_GL_SwapBuffers () 995SDL_GL_SwapBuffers ()
778 996
779char * 997char *
780SDL_GetKeyName (int sym) 998SDL_GetKeyName (int sym)
999 C_ARGS: (SDLKey)sym
781 1000
782int 1001int
783SDL_GetAppState () 1002SDL_GetAppState ()
784 1003
785int 1004int
786SDL_GetModState () 1005SDL_GetModState ()
787 1006
1007int
1008SDL_WaitEvent ()
1009 C_ARGS: 0
1010
788void 1011void
1012SDL_PumpEvents ()
1013
1014void
789poll_events () 1015peep_events ()
790 PPCODE: 1016 PPCODE:
791{ 1017{
792 SDL_Event ev; 1018 SDL_Event ev;
793 1019
794 SDL_PumpEvents (); 1020 SDL_PumpEvents ();
801 { 1027 {
802 case SDL_KEYDOWN: 1028 case SDL_KEYDOWN:
803 case SDL_KEYUP: 1029 case SDL_KEYUP:
804 hv_store (hv, "state", 5, newSViv (ev.key.state), 0); 1030 hv_store (hv, "state", 5, newSViv (ev.key.state), 0);
805 hv_store (hv, "sym", 3, newSViv (ev.key.keysym.sym), 0); 1031 hv_store (hv, "sym", 3, newSViv (ev.key.keysym.sym), 0);
806 hv_store (hv, "mod", 3, newSViv (ev.key.keysym.mod & MOD_MASK), 0); 1032 hv_store (hv, "mod", 3, newSViv (mod_munge (ev.key.keysym.mod)), 0);
807 hv_store (hv, "cmod", 4, newSViv (SDL_GetModState () & MOD_MASK), 0); /* current mode */ 1033 hv_store (hv, "cmod", 4, newSViv (mod_munge (SDL_GetModState ())), 0); /* current mode */
808 hv_store (hv, "unicode", 7, newSViv (ev.key.keysym.unicode), 0); 1034 hv_store (hv, "unicode", 7, newSViv (ev.key.keysym.unicode), 0);
809 break; 1035 break;
810 1036
811 case SDL_ACTIVEEVENT: 1037 case SDL_ACTIVEEVENT:
812 hv_store (hv, "gain", 4, newSViv (ev.active.gain), 0); 1038 hv_store (hv, "gain", 4, newSViv (ev.active.gain), 0);
830 x = ev.motion.x; 1056 x = ev.motion.x;
831 y = ev.motion.y; 1057 y = ev.motion.y;
832 SDL_PeepEvents (&ev, 1, SDL_GETEVENT, SDL_EVENTMASK (SDL_MOUSEMOTION)); 1058 SDL_PeepEvents (&ev, 1, SDL_GETEVENT, SDL_EVENTMASK (SDL_MOUSEMOTION));
833 } 1059 }
834 1060
835 hv_store (hv, "mod", 3, newSViv (SDL_GetModState () & MOD_MASK), 0); 1061 hv_store (hv, "mod", 3, newSViv (mod_munge (SDL_GetModState ())), 0);
836 hv_store (hv, "state", 5, newSViv (state), 0); 1062 hv_store (hv, "state", 5, newSViv (state), 0);
837 hv_store (hv, "x", 1, newSViv (x), 0); 1063 hv_store (hv, "x", 1, newSViv (x), 0);
838 hv_store (hv, "y", 1, newSViv (y), 0); 1064 hv_store (hv, "y", 1, newSViv (y), 0);
839 hv_store (hv, "xrel", 4, newSViv (xrel), 0); 1065 hv_store (hv, "xrel", 4, newSViv (xrel), 0);
840 hv_store (hv, "yrel", 4, newSViv (yrel), 0); 1066 hv_store (hv, "yrel", 4, newSViv (yrel), 0);
860 1086
861 XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("DC::UI::Event", 1)))); 1087 XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("DC::UI::Event", 1))));
862 } 1088 }
863} 1089}
864 1090
1091char *
1092SDL_AudioDriverName ()
1093 CODE:
1094{
1095 char buf [256];
1096 if (!SDL_AudioDriverName (buf, sizeof (buf)))
1097 XSRETURN_UNDEF;
1098
1099 RETVAL = buf;
1100}
1101 OUTPUT:
1102 RETVAL
1103
865int 1104int
866Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 4096) 1105Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 4096)
867 POSTCALL: 1106 POSTCALL:
868 Mix_HookMusicFinished (music_finished); 1107 Mix_HookMusicFinished (music_finished);
869 Mix_ChannelFinished (channel_finished); 1108 Mix_ChannelFinished (channel_finished);
870 1109
871void 1110void
872Mix_QuerySpec () 1111Mix_QuerySpec ()
931add_font (char *file) 1170add_font (char *file)
932 CODE: 1171 CODE:
933 RETVAL = FcConfigAppFontAddFile (0, (const FcChar8 *)file); 1172 RETVAL = FcConfigAppFontAddFile (0, (const FcChar8 *)file);
934 OUTPUT: 1173 OUTPUT:
935 RETVAL 1174 RETVAL
1175
1176void
1177IMG_Init (int flags = IMG_INIT_JPG | IMG_INIT_PNG)
1178
1179# MIX_INIT_MP3 gives smpeg + libstdc++ + libgcc_s
1180void
1181Mix_Init (int flags = MIX_INIT_MOD | MIX_INIT_OGG)
936 1182
937void 1183void
938load_image_inline (SV *image_) 1184load_image_inline (SV *image_)
939 ALIAS: 1185 ALIAS:
940 load_image_file = 1 1186 load_image_file = 1
986 1232
987 SDL_LockSurface (surface2); 1233 SDL_LockSurface (surface2);
988 EXTEND (SP, 6); 1234 EXTEND (SP, 6);
989 PUSHs (sv_2mortal (newSViv (surface2->w))); 1235 PUSHs (sv_2mortal (newSViv (surface2->w)));
990 PUSHs (sv_2mortal (newSViv (surface2->h))); 1236 PUSHs (sv_2mortal (newSViv (surface2->h)));
991 PUSHs (sv_2mortal (newSVpvn (surface2->pixels, surface2->h * surface2->pitch))); 1237 PUSHs (sv_2mortal (newSVpvn ((const char *)surface2->pixels, surface2->h * surface2->pitch)));
992 PUSHs (sv_2mortal (newSViv (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA) ? GL_RGBA : GL_RGB))); 1238 PUSHs (sv_2mortal (newSViv (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA) ? GL_RGBA : GL_RGB)));
993 PUSHs (sv_2mortal (newSViv (GL_RGBA))); 1239 PUSHs (sv_2mortal (newSViv (GL_RGBA)));
994 PUSHs (sv_2mortal (newSViv (GL_UNSIGNED_BYTE))); 1240 PUSHs (sv_2mortal (newSViv (GL_UNSIGNED_BYTE)));
995 SDL_UnlockSurface (surface2); 1241 SDL_UnlockSurface (surface2);
996 1242
1056#if DEBUG 1302#if DEBUG
1057 VALGRIND_DO_LEAK_CHECK; 1303 VALGRIND_DO_LEAK_CHECK;
1058#endif 1304#endif
1059} 1305}
1060 1306
1307int
1308SvREFCNT (SV *sv)
1309 CODE:
1310 RETVAL = SvREFCNT (sv);
1311 OUTPUT:
1312 RETVAL
1313
1061MODULE = Deliantra::Client PACKAGE = DC::Font 1314MODULE = Deliantra::Client PACKAGE = DC::Font
1062 1315
1063PROTOTYPES: DISABLE 1316PROTOTYPES: DISABLE
1064 1317
1065DC::Font 1318DC::Font
1066new_from_file (SV *class, char *path, int id = 0) 1319new_from_file (SV *klass, char *path, int id = 0)
1067 CODE: 1320 CODE:
1068{ 1321{
1069 int count; 1322 int count;
1070 FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)path, id, 0, &count); 1323 FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)path, id, 0, &count);
1071 RETVAL = pango_fc_font_description_from_pattern (pattern, 0); 1324 RETVAL = pango_fc_font_description_from_pattern (pattern, 0);
1100 PROTOTYPE: 1353 PROTOTYPE:
1101 CODE: 1354 CODE:
1102 tc_restore (); 1355 tc_restore ();
1103 1356
1104DC::Layout 1357DC::Layout
1105new (SV *class) 1358new (SV *klass)
1106 CODE: 1359 CODE:
1107 New (0, RETVAL, 1, struct cf_layout); 1360 RETVAL = new cf_layout;
1108 1361
1109 RETVAL->pl = pango_layout_new (opengl_context); 1362 RETVAL->pl = pango_layout_new (opengl_context);
1110 RETVAL->r = 1.; 1363 RETVAL->r = 1.;
1111 RETVAL->g = 1.; 1364 RETVAL->g = 1.;
1112 RETVAL->b = 1.; 1365 RETVAL->b = 1.;
1113 RETVAL->a = 1.; 1366 RETVAL->a = 1.;
1114 RETVAL->base_height = MIN_FONT_HEIGHT; 1367 RETVAL->base_height = MIN_FONT_HEIGHT;
1115 RETVAL->font = 0; 1368 RETVAL->font = 0;
1116 RETVAL->rc = rc_alloc ();
1117 1369
1118 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR); 1370 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
1119 layout_update_font (RETVAL); 1371 layout_update_font (RETVAL);
1120 OUTPUT: 1372 OUTPUT:
1121 RETVAL 1373 RETVAL
1122 1374
1123void 1375void
1124DESTROY (DC::Layout self) 1376DESTROY (DC::Layout self)
1125 CODE: 1377 CODE:
1126 g_object_unref (self->pl); 1378 g_object_unref (self->pl);
1127 rc_free (self->rc);
1128 Safefree (self); 1379 delete self;
1129 1380
1130void 1381void
1131set_text (DC::Layout self, SV *text_) 1382set_text (DC::Layout self, SV *text_)
1132 CODE: 1383 CODE:
1133{ 1384{
1259 1510
1260void 1511void
1261set_height (DC::Layout self, int base_height) 1512set_height (DC::Layout self, int base_height)
1262 CODE: 1513 CODE:
1263 if (self->base_height != base_height) 1514 if (self->base_height != base_height)
1264 { 1515 {
1265 self->base_height = base_height; 1516 self->base_height = base_height;
1266 layout_update_font (self); 1517 layout_update_font (self);
1267 } 1518 }
1268 1519
1269void 1520void
1387} 1638}
1388 1639
1389void 1640void
1390render (DC::Layout self, float x, float y, int flags = 0) 1641render (DC::Layout self, float x, float y, int flags = 0)
1391 CODE: 1642 CODE:
1392 rc_clear (self->rc); 1643 self->rc.clear ();
1393 pango_opengl_render_layout_subpixel ( 1644 pango_opengl_render_layout_subpixel (
1394 self->pl, 1645 self->pl,
1395 self->rc, 1646 &self->rc,
1396 x * PANGO_SCALE, y * PANGO_SCALE, 1647 x * PANGO_SCALE, y * PANGO_SCALE,
1397 self->r, self->g, self->b, self->a, 1648 self->r, self->g, self->b, self->a,
1398 flags 1649 flags
1399 ); 1650 );
1400 // we assume that context_change actually clears/frees stuff 1651 // we assume that context_change actually clears/frees stuff
1411 gl_BlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 1662 gl_BlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
1412 GL_ONE , GL_ONE_MINUS_SRC_ALPHA); 1663 GL_ONE , GL_ONE_MINUS_SRC_ALPHA);
1413 glEnable (GL_ALPHA_TEST); 1664 glEnable (GL_ALPHA_TEST);
1414 glAlphaFunc (GL_GREATER, 7.f / 255.f); 1665 glAlphaFunc (GL_GREATER, 7.f / 255.f);
1415 1666
1416 rc_draw (self->rc); 1667 self->rc.draw ();
1417 1668
1418 glDisable (GL_ALPHA_TEST); 1669 glDisable (GL_ALPHA_TEST);
1419 glDisable (GL_BLEND); 1670 glDisable (GL_BLEND);
1420 glDisable (GL_TEXTURE_2D); 1671 glDisable (GL_TEXTURE_2D);
1421} 1672}
1496 glDisable (GL_ALPHA_TEST); 1747 glDisable (GL_ALPHA_TEST);
1497 glDisable (GL_BLEND); 1748 glDisable (GL_BLEND);
1498 } 1749 }
1499} 1750}
1500 1751
1752void
1753draw_fow_texture (float intensity, int hidden_tex, int name1, uint8_t *data1, float s, float t, int w, int h, float blend = 0.f, int dx = 0, int dy = 0, int name2 = 0, uint8_t *data2 = data1)
1754 PROTOTYPE: @
1755 CODE:
1756{
1757 glEnable (GL_BLEND);
1758 glBlendFunc (intensity ? GL_SRC_ALPHA : GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1759 glEnable (GL_TEXTURE_2D);
1760 glBindTexture (GL_TEXTURE_2D, name1);
1761
1762 glColor3f (intensity, intensity, intensity);
1763 glPushMatrix ();
1764 glScalef (1./3, 1./3, 1.);
1765
1766 if (blend > 0.f)
1767 {
1768 float dx3 = dx * -3.f / w;
1769 float dy3 = dy * -3.f / h;
1770 GLfloat env_color[4] = { 0., 0., 0., blend };
1771
1772 /* interpolate the two shadow textures */
1773 /* stage 0 == rgb(glcolor) + alpha(t0) */
1774 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1775
1776 /* stage 1 == rgb(glcolor) + alpha(interpolate t0, t1, texenv) */
1777 gl.ActiveTexture (GL_TEXTURE1);
1778 glEnable (GL_TEXTURE_2D);
1779 glBindTexture (GL_TEXTURE_2D, name2);
1780 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
1781
1782 /* rgb == rgb(glcolor) */
1783 glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
1784 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
1785 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
1786
1787 /* alpha = interpolate t0, t1 by env_alpha */
1788 glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, env_color);
1789
1790 glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE);
1791 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
1792 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
1793
1794 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PREVIOUS);
1795 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
1796
1797 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_CONSTANT);
1798 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
1799
1800 glBegin (GL_QUADS);
1801 gl.MultiTexCoord2f (GL_TEXTURE0, 0, 0); gl.MultiTexCoord2f (GL_TEXTURE1, dx3 , dy3 ); glVertex2i (0, 0);
1802 gl.MultiTexCoord2f (GL_TEXTURE0, 0, t); gl.MultiTexCoord2f (GL_TEXTURE1, dx3 , dy3 + t); glVertex2i (0, h);
1803 gl.MultiTexCoord2f (GL_TEXTURE0, s, t); gl.MultiTexCoord2f (GL_TEXTURE1, dx3 + s, dy3 + t); glVertex2i (w, h);
1804 gl.MultiTexCoord2f (GL_TEXTURE0, s, 0); gl.MultiTexCoord2f (GL_TEXTURE1, dx3 + s, dy3 ); glVertex2i (w, 0);
1805 glEnd ();
1806
1807 glDisable (GL_TEXTURE_2D);
1808 gl.ActiveTexture (GL_TEXTURE0);
1809 }
1810 else
1811 {
1812 /* simple blending of one texture, also opengl <1.3 path */
1813 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1814
1815 glBegin (GL_QUADS);
1816 glTexCoord2f (0, 0); glVertex2f (0, 0);
1817 glTexCoord2f (0, t); glVertex2f (0, h);
1818 glTexCoord2f (s, t); glVertex2f (w, h);
1819 glTexCoord2f (s, 0); glVertex2f (w, 0);
1820 glEnd ();
1821 }
1822
1823 /* draw ?-marks or equivalent, this is very clumsy code :/ */
1824 {
1825 int x, y;
1826 int dx3 = dx * 3;
1827 int dy3 = dy * 3;
1828
1829 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1830 glBindTexture (GL_TEXTURE_2D, hidden_tex);
1831 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1832 glTranslatef (-1., -1., 0);
1833 glBegin (GL_QUADS);
1834
1835 for (y = 1; y < h; y += 3)
1836 {
1837 int y1 = y - dy3;
1838 int y1valid = y1 >= 0 && y1 < h;
1839
1840 for (x = 1; x < w; x += 3)
1841 {
1842 int x1 = x - dx3;
1843 uint8_t h1 = data1 [x + y * w] == DARKNESS_ADJUST (255 - FOW_DARKNESS);
1844 uint8_t h2;
1845
1846 if (y1valid && x1 >= 0 && x1 < w)
1847 h2 = data2 [x1 + y1 * w] == DARKNESS_ADJUST (255 - FOW_DARKNESS);
1848 else
1849 h2 = 1; /* out of range == invisible */
1850
1851 if (h1 || h2)
1852 {
1853 float alpha = h1 == h2 ? 1.f : h1 ? 1.f - blend : blend;
1854 glColor4f (1., 1., 1., alpha);
1855
1856 glTexCoord2f (0, 0.); glVertex2i (x , y );
1857 glTexCoord2f (0, 1.); glVertex2i (x , y + 3);
1858 glTexCoord2f (1, 1.); glVertex2i (x + 3, y + 3);
1859 glTexCoord2f (1, 0.); glVertex2i (x + 3, y );
1860 }
1861 }
1862 }
1863 }
1864
1865 glEnd ();
1866
1867 glPopMatrix ();
1868
1869 glDisable (GL_TEXTURE_2D);
1870 glDisable (GL_BLEND);
1871}
1872
1501IV texture_valid_2d (GLint internalformat, GLsizei w, GLsizei h, GLenum format, GLenum type) 1873IV texture_valid_2d (GLint internalformat, GLsizei w, GLsizei h, GLenum format, GLenum type)
1502 CODE: 1874 CODE:
1503{ 1875{
1504 GLint width; 1876 GLint width;
1505 glTexImage2D (GL_PROXY_TEXTURE_2D, 0, internalformat, w, h, 0, format, type, 0); 1877 glTexImage2D (GL_PROXY_TEXTURE_2D, 0, internalformat, w, h, 0, format, type, 0);
1512MODULE = Deliantra::Client PACKAGE = DC::Map 1884MODULE = Deliantra::Client PACKAGE = DC::Map
1513 1885
1514PROTOTYPES: DISABLE 1886PROTOTYPES: DISABLE
1515 1887
1516DC::Map 1888DC::Map
1517new (SV *class) 1889new (SV *klass)
1518 CODE: 1890 CODE:
1519 New (0, RETVAL, 1, struct map); 1891 RETVAL = new mapgrid;
1520 RETVAL->x = 0; 1892 RETVAL->x = 0;
1521 RETVAL->y = 0; 1893 RETVAL->y = 0;
1522 RETVAL->w = 0; 1894 RETVAL->w = 0;
1523 RETVAL->h = 0; 1895 RETVAL->h = 0;
1524 RETVAL->ox = 0; 1896 RETVAL->ox = 0;
1525 RETVAL->oy = 0; 1897 RETVAL->oy = 0;
1526 RETVAL->faces = 8192; Newz (0, RETVAL->face2tile, RETVAL->faces, tileid);
1527 RETVAL->texs = 8192; Newz (0, RETVAL->tex , RETVAL->texs , maptex);
1528 RETVAL->rows = 0; 1898 RETVAL->rows = 0;
1529 RETVAL->row = 0; 1899 RETVAL->row = 0;
1530 OUTPUT: 1900 OUTPUT:
1531 RETVAL 1901 RETVAL
1532 1902
1533void 1903void
1534DESTROY (DC::Map self) 1904DESTROY (DC::Map self)
1535 CODE: 1905 CODE:
1536{ 1906{
1537 map_clear (self);
1538 Safefree (self->face2tile);
1539 Safefree (self->tex);
1540 Safefree (self); 1907 delete self;
1541} 1908}
1542 1909
1543void 1910void
1544resize (DC::Map self, int map_width, int map_height) 1911resize (DC::Map self, int map_width, int map_height)
1545 CODE: 1912 CODE:
1547 self->h = map_height; 1914 self->h = map_height;
1548 1915
1549void 1916void
1550clear (DC::Map self) 1917clear (DC::Map self)
1551 CODE: 1918 CODE:
1552 map_clear (self); 1919 self->clear_cells ();
1553 1920
1554void 1921void
1555set_tileid (DC::Map self, int face, int tile) 1922set_tileid (DC::Map self, int face, int tile)
1556 CODE: 1923 CODE:
1557{ 1924{
1558 need_facenum (self, face); self->face2tile [face] = tile; 1925 if (self->tile.size () <= face) self->tile.resize (face + 1);
1559 need_texid (self, tile); 1926 self->tile[face] = tile;
1927 if (self->tex.size () <= tile) self->tex .resize (tile + 1);
1560} 1928}
1561 1929
1562void 1930void
1563set_smooth (DC::Map self, int face, int smooth, int level) 1931set_smooth (DC::Map self, int face, int smooth, int level)
1564 CODE: 1932 CODE:
1565{ 1933{
1566 tileid texid;
1567 maptex *tex;
1568
1569 if (face < 0 || face >= self->faces) 1934 if (face < 0 || face >= self->tile.size ())
1570 return; 1935 return;
1571 1936
1572 if (smooth < 0 || smooth >= self->faces) 1937 if (smooth < 0 || smooth >= self->tile.size ())
1573 return; 1938 return;
1574 1939
1575 texid = self->face2tile [face]; 1940 tileid texid = self->tile[face];
1576 1941
1577 if (!texid) 1942 if (!texid)
1578 return; 1943 return;
1579 1944
1580 tex = self->tex + texid; 1945 maptex &tex = self->tex[texid];
1581 tex->smoothtile = self->face2tile [smooth]; 1946 tex.smoothtile = self->tile[smooth];
1582 tex->smoothlevel = level; 1947 tex.smoothlevel = level;
1583} 1948}
1584 1949
1585void 1950void
1586set_texture (DC::Map self, int texid, int name, int w, int h, float s, float t, int r, int g, int b, int a) 1951set_texture (DC::Map self, int texid, int name, int w, int h, float s, float t, int r, int g, int b, int a)
1587 CODE: 1952 CODE:
1588{ 1953{
1589 need_texid (self, texid); 1954 if (self->tex.size () < texid) self->tex.resize (texid + 1);
1590 1955
1591 { 1956 {
1592 maptex *tex = self->tex + texid; 1957 maptex &tex = self->tex[texid];
1593 1958
1594 tex->name = name; 1959 tex.name = name;
1595 tex->w = w; 1960 tex.w = w;
1596 tex->h = h; 1961 tex.h = h;
1597 tex->s = s; 1962 tex.s = s;
1598 tex->t = t; 1963 tex.t = t;
1599 tex->r = r; 1964 tex.r = r;
1600 tex->g = g; 1965 tex.g = g;
1601 tex->b = b; 1966 tex.b = b;
1602 tex->a = a; 1967 tex.a = a;
1603 } 1968 }
1604 1969
1605 // somewhat hackish, but for textures that require it, it really 1970 // somewhat hackish, but for textures that require it, it really
1606 // improves the look, and most others don't suffer. 1971 // improves the look, and most others don't suffer.
1607 glBindTexture (GL_TEXTURE_2D, name); 1972 glBindTexture (GL_TEXTURE_2D, name);
1609 //glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 1974 //glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1610 // use uglier nearest interpolation because linear suffers 1975 // use uglier nearest interpolation because linear suffers
1611 // from transparent color bleeding and ugly wrapping effects. 1976 // from transparent color bleeding and ugly wrapping effects.
1612 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1977 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1613} 1978}
1979
1980void
1981expire_textures (DC::Map self, int texid, int count)
1982 PPCODE:
1983 for (; texid < self->tex.size () && count; ++texid, --count)
1984 {
1985 maptex &tex = self->tex[texid];
1986
1987 if (tex.name)
1988 {
1989 if (tex.unused)
1990 {
1991 tex.name = 0;
1992 tex.unused = 0;
1993 XPUSHs (sv_2mortal (newSViv (texid)));
1994 }
1995 else
1996 tex.unused = 1;
1997 }
1998 }
1614 1999
1615int 2000int
1616ox (DC::Map self) 2001ox (DC::Map self)
1617 ALIAS: 2002 ALIAS:
1618 oy = 1 2003 oy = 1
1658 self->y += MAP_EXTEND_Y; 2043 self->y += MAP_EXTEND_Y;
1659 } 2044 }
1660} 2045}
1661 2046
1662SV * 2047SV *
1663map1a_update (DC::Map self, SV *data_, int extmap) 2048map1a_update (DC::Map self, SV *data_)
1664 CODE: 2049 CODE:
1665{ 2050{
1666 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_); 2051 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_);
1667 uint8_t *data_end = (uint8_t *)SvEND (data_); 2052 uint8_t *data_end = (uint8_t *)SvEND (data_);
1668 mapcell *cell; 2053 mapcell *cell;
1689 2074
1690 //TODO: don't trust server data to be in-range(!) 2075 //TODO: don't trust server data to be in-range(!)
1691 2076
1692 if (flags & 8) 2077 if (flags & 8)
1693 { 2078 {
2079 uint8_t ext, cmd;
2080
1694 if (extmap) 2081 do
1695 { 2082 {
1696 uint8_t ext, cmd; 2083 ext = *data++;
2084 cmd = ext & 0x7f;
1697 2085
1698 do 2086 if (cmd < 4)
2087 cell->darkness = 255 - ext * 64 + 1; /* make sure this doesn't collide with FOW_DARKNESS */
2088 else if (cmd == 5) // health
1699 { 2089 {
1700 ext = *data++;
1701 cmd = ext & 0x7f;
1702
1703 if (cmd < 4)
1704 cell->darkness = 255 - ext * 64 + 1;
1705 else if (cmd == 5) // health
1706 {
1707 cell->stat_width = 1; 2090 cell->stat_width = 1;
1708 cell->stat_hp = *data++; 2091 cell->stat_hp = *data++;
1709 }
1710 else if (cmd == 6) // monster width
1711 cell->stat_width = *data++ + 1;
1712 else if (cmd == 0x47)
1713 {
1714 if (*data == 1) cell->player = data [1];
1715 else if (*data == 2) cell->player = data [2] + (data [1] << 8);
1716 else if (*data == 3) cell->player = data [3] + (data [2] << 8) + (data [1] << 16);
1717 else if (*data == 4) cell->player = data [4] + (data [3] << 8) + (data [2] << 16) + (data [1] << 24);
1718
1719 data += *data + 1;
1720 }
1721 else if (cmd == 8) // cell flags
1722 cell->flags = *data++;
1723 else if (ext & 0x40) // unknown, multibyte => skip
1724 data += *data + 1;
1725 else
1726 data++;
1727 } 2092 }
1728 while (ext & 0x80); 2093 else if (cmd == 6) // monster width
2094 cell->stat_width = *data++ + 1;
2095 else if (cmd == 0x47)
2096 {
2097 if (*data == 1) cell->player = data [1];
2098 else if (*data == 2) cell->player = data [2] + (data [1] << 8);
2099 else if (*data == 3) cell->player = data [3] + (data [2] << 8) + (data [1] << 16);
2100 else if (*data == 4) cell->player = data [4] + (data [3] << 8) + (data [2] << 16) + (data [1] << 24);
2101
2102 data += *data + 1;
2103 }
2104 else if (cmd == 8) // cell flags
2105 cell->flags = *data++;
2106 else if (ext & 0x40) // unknown, multibyte => skip
2107 data += *data + 1;
2108 else
2109 data++;
1729 } 2110 }
1730 else 2111 while (ext & 0x80);
1731 cell->darkness = *data++ + 1;
1732 } 2112 }
1733 2113
1734 for (z = 0; z <= 2; ++z) 2114 for (z = 0; z <= 2; ++z)
1735 if (flags & (4 >> z)) 2115 if (flags & (4 >> z))
1736 { 2116 {
1737 faceid face = (data [0] << 8) + data [1]; data += 2; 2117 faceid face = (data[0] << 8) + data[1]; data += 2;
1738 need_facenum (self, face); 2118 if (self->tile.size () <= face) self->tile.resize (face + 1);
1739 cell->tile [z] = self->face2tile [face]; 2119 cell->tile[z] = self->tile[face];
1740 2120
1741 if (cell->tile [z]) 2121 if (cell->tile[z])
1742 { 2122 {
1743 maptex *tex = self->tex + cell->tile [z]; 2123 maptex &tex = self->tex[cell->tile[z]];
2124 tex.unused = 0;
1744 if (!tex->name) 2125 if (!tex.name)
1745 av_push (missing, newSViv (cell->tile [z])); 2126 av_push (missing, newSViv (cell->tile [z]));
1746 2127
1747 if (tex->smoothtile) 2128 if (tex.smoothtile)
1748 { 2129 {
1749 maptex *smooth = self->tex + tex->smoothtile; 2130 maptex &smooth = self->tex[tex.smoothtile];
2131 smooth.unused = 0;
1750 if (!smooth->name) 2132 if (!smooth.name)
1751 av_push (missing, newSViv (tex->smoothtile)); 2133 av_push (missing, newSViv (tex.smoothtile));
1752 } 2134 }
1753 } 2135 }
1754 } 2136 }
1755 } 2137 }
1756 else 2138 else
1757 cell->darkness = 0; 2139 CELL_CLEAR (cell);
1758 } 2140 }
1759} 2141}
1760 OUTPUT: 2142 OUTPUT:
1761 RETVAL 2143 RETVAL
1762 2144
1782 ? self->row + y 2164 ? self->row + y
1783 : 0; 2165 : 0;
1784 2166
1785 for (x = x0; x < x1; x++) 2167 for (x = x0; x < x1; x++)
1786 { 2168 {
1787 int r = 32, g = 32, b = 32, a = 192; 2169 unsigned int r = 32, g = 32, b = 32, a = 192;
1788 2170
1789 if (row && row->c0 <= x && x < row->c1) 2171 if (row && row->c0 <= x && x < row->c1)
1790 { 2172 {
1791 mapcell *cell = row->col + (x - row->c0); 2173 mapcell *cell = row->col + (x - row->c0);
1792 2174
1794 { 2176 {
1795 maptex tex = self->tex [cell->tile [z]]; 2177 maptex tex = self->tex [cell->tile [z]];
1796 int a0 = 255 - tex.a; 2178 int a0 = 255 - tex.a;
1797 int a1 = tex.a; 2179 int a1 = tex.a;
1798 2180
1799 r = (r * a0 + tex.r * a1) / 255; 2181 r = div255 (r * a0 + tex.r * a1);
1800 g = (g * a0 + tex.g * a1) / 255; 2182 g = div255 (g * a0 + tex.g * a1);
1801 b = (b * a0 + tex.b * a1) / 255; 2183 b = div255 (b * a0 + tex.b * a1);
1802 a = (a * a0 + tex.a * a1) / 255; 2184 a = div255 (a * a0 + tex.a * a1);
1803 } 2185 }
1804 } 2186 }
1805 2187
1806 *map++ = (r ) 2188 *map++ = (r )
1807 | (g << 8) 2189 | (g << 8)
1808 | (b << 16) 2190 | (b << 16)
1809 | (a << 24); 2191 | (a << 24);
1810 } 2192 }
1811 } 2193 }
1812 2194
1813 RETVAL = map_sv; 2195 RETVAL = map_sv;
1814} 2196}
1815 OUTPUT: 2197 OUTPUT:
1816 RETVAL 2198 RETVAL
1817 2199
1818void 2200void
1819draw (DC::Map self, int mx, int my, int sw, int sh, int T, U32 player = 0xffffffff, int pdx = 0, int pdy = 0) 2201draw (DC::Map self, int mx, int my, int sw, int sh, int Tw, int Th, U32 player = 0xffffffff, int sdx = 0, int sdy = 0)
1820 CODE: 2202 CODE:
1821{ 2203{
1822 int x, y, z; 2204 int x, y, z;
1823 2205
1824 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
1825 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level
1826 static uint8_t smooth_max[256][256]; // egad, fast and wasteful on memory (64k) 2206 static uint8_t smooth_max[256][256]; // egad, fast and wasteful on memory (64k), also, static!
1827 smooth_key skey;
1828 int pl_x, pl_y; 2207 int pl_x, pl_y;
1829 maptex pl_tex; 2208 maptex pl_tex;
1830 rc_t *rc = rc_alloc (); 2209 rc_t rc;
2210 rc_t rc_ov;
1831 rc_key_t key; 2211 rc_key_t key;
1832 rc_array_t *arr; 2212 rc_t::array_t *arr;
1833 2213
1834 pl_tex.name = 0; 2214 pl_tex.name = 0;
1835 2215
1836 // thats current max. sorry. 2216 // that's current max. sorry.
1837 if (sw > 255) sw = 255; 2217 if (sw > 255) sw = 255;
1838 if (sh > 255) sh = 255; 2218 if (sh > 255) sh = 255;
1839
1840 // clear key, in case of extra padding
1841 memset (&skey, 0, sizeof (skey));
1842 2219
1843 memset (&key, 0, sizeof (key)); 2220 memset (&key, 0, sizeof (key));
1844 key.r = 255; 2221 key.r = 255;
1845 key.g = 255; 2222 key.g = 255;
1846 key.b = 255; 2223 key.b = 255;
1847 key.a = 255; 2224 key.a = 255;
1848 key.mode = GL_QUADS; 2225 key.mode = GL_QUADS;
1849 key.format = GL_T2F_V3F; 2226 key.format = GL_T2F_V3F;
1850 key.texname = -1;
1851 2227
1852 mx += self->x; 2228 mx += self->x;
1853 my += self->y; 2229 my += self->y;
1854 2230
1855 // first pass: determine smooth_max 2231 // first pass: determine smooth_max
1856 // rather ugly, if you ask me 2232 // rather ugly, if you ask me
1857 // could also be stored inside mapcell and updated on change 2233 // could also be stored inside mapcell and updated on change
1858 memset (smooth_max, 0, sizeof (smooth_max)); 2234 memset (smooth_max, 0, sizeof (smooth_max[0]) * (sh + 1));
1859 2235
1860 for (y = 0; y < sh; y++) 2236 for (y = 0; y < sh; y++)
1861 if (0 <= y + my && y + my < self->rows) 2237 if (0 <= y + my && y + my < self->rows)
1862 { 2238 {
1863 maprow *row = self->row + (y + my); 2239 maprow *row = self->row + (y + my);
1878 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2254 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1879 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 2255 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1880 2256
1881 for (z = 0; z <= 2; z++) 2257 for (z = 0; z <= 2; z++)
1882 { 2258 {
1883 memset (smooth_level, 0, sizeof (smooth_level)); 2259 std::bitset<256> smooth_level; // one bit for every possible smooth level
2260 smooth_key skey;
2261 smooth_hash smooth;
2262 key.texname = -1;
1884 2263
1885 for (y = 0; y < sh; y++) 2264 for (y = 0; y < sh; y++)
1886 if (0 <= y + my && y + my < self->rows) 2265 if (0 <= y + my && y + my < self->rows)
1887 { 2266 {
1888 maprow *row = self->row + (y + my); 2267 maprow *row = self->row + (y + my);
1894 tileid tile = cell->tile [z]; 2273 tileid tile = cell->tile [z];
1895 2274
1896 if (tile) 2275 if (tile)
1897 { 2276 {
1898 maptex tex = self->tex [tile]; 2277 maptex tex = self->tex [tile];
1899 int px = (x + 1) * T - tex.w; 2278 int px, py;
1900 int py = (y + 1) * T - tex.h;
1901 2279
1902 if (key.texname != tex.name) 2280 if (key.texname != tex.name)
1903 { 2281 {
2282 self->tex [tile].unused = 0;
2283
1904 if (!tex.name) 2284 if (!tex.name)
1905 tex = self->tex [2]; /* missing, replace by noface */ 2285 tex = self->tex [TEXID_NOFACE]; /* missing, replace by noface */
1906 2286
1907 key.texname = tex.name; 2287 key.texname = tex.name;
1908 arr = rc_array (rc, &key); 2288 arr = &rc.array (key);
1909 } 2289 }
2290
2291 px = (x + 1) * Th - tex.w;
2292 py = (y + 1) * Tw - tex.h;
1910 2293
1911 if (expect_false (cell->player == player) && expect_false (z == 2)) 2294 if (expect_false (cell->player == player) && expect_false (z == 2))
1912 { 2295 {
1913 pl_x = px; 2296 pl_x = px;
1914 pl_y = py; 2297 pl_y = py;
1915 pl_tex = tex; 2298 pl_tex = tex;
1916 continue; 2299 continue;
1917 } 2300 }
1918 2301
1919 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2302 arr->t2f_v3f (0 , 0 , px , py , 0);
1920 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0); 2303 arr->t2f_v3f (0 , tex.t, px , py + tex.h, 0);
1921 rc_t2f_v3f (arr, tex.s, tex.t, px + tex.w, py + tex.h, 0); 2304 arr->t2f_v3f (tex.s, tex.t, px + tex.w, py + tex.h, 0);
1922 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0); 2305 arr->t2f_v3f (tex.s, 0 , px + tex.w, py , 0);
1923
1924 if (expect_false (cell->flags) && expect_false (z == 2))
1925 {
1926 // overlays such as the speech bubble, probably more to come
1927 if (cell->flags & 1)
1928 {
1929 maptex tex = self->tex [1];
1930 int px = x * T + T * 2 / 32;
1931 int py = y * T - T * 6 / 32;
1932
1933 if (tex.name)
1934 {
1935 if (key.texname != tex.name)
1936 {
1937 key.texname = tex.name;
1938 arr = rc_array (rc, &key);
1939 }
1940
1941 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
1942 rc_t2f_v3f (arr, 0 , tex.t, px , py + T, 0);
1943 rc_t2f_v3f (arr, tex.s, tex.t, px + T, py + T, 0);
1944 rc_t2f_v3f (arr, tex.s, 0 , px + T, py , 0);
1945 }
1946 }
1947 }
1948 2306
1949 // update smooth hash 2307 // update smooth hash
1950 if (tex.smoothtile) 2308 if (tex.smoothtile)
1951 { 2309 {
1952 skey.tile = tex.smoothtile; 2310 skey.tile = tex.smoothtile;
1953 skey.level = tex.smoothlevel; 2311 skey.level = tex.smoothlevel;
1954 2312
1955 smooth_level [tex.smoothlevel >> 5] |= ((uint32_t)1) << (tex.smoothlevel & 31); 2313 smooth_level[tex.smoothlevel] = 1;
1956 2314
1957 // add bits to current tile and all neighbours. skey.x|y is 2315 // add bits to current tile and all neighbours. skey.x|y is
1958 // shifted +1|+1 so we always stay positive. 2316 // shifted +1|+1 so we always stay positive.
1959 2317
1960 // bits is ___n cccc CCCC bbbb 2318 // bits is ___n cccc CCCC bbbb
1968 2326
1969 // corners: 1 ┛· 2 ·┗ 4 ·· 8 ·· 2327 // corners: 1 ┛· 2 ·┗ 4 ·· 8 ··
1970 // ·· ·· ·┏ ┓· 2328 // ·· ·· ·┏ ┓·
1971 2329
1972 // full tile 2330 // full tile
1973 skey.x = x + 1; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x1000); 2331 skey.x = x + 1; skey.y = y + 1; smooth_or_bits (smooth, skey, 0x1000);
1974 2332
1975 // borders 2333 // borders
1976 skey.x = x + 2; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x0091); 2334 skey.x = x + 2; skey.y = y + 1; smooth_or_bits (smooth, skey, 0x0091);
1977 skey.x = x + 1; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0032); 2335 skey.x = x + 1; skey.y = y + 2; smooth_or_bits (smooth, skey, 0x0032);
1978 skey.x = x ; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x0064); 2336 skey.x = x ; skey.y = y + 1; smooth_or_bits (smooth, skey, 0x0064);
1979 skey.x = x + 1; skey.y = y ; smooth_or_bits (smooth, &skey, 0x00c8); 2337 skey.x = x + 1; skey.y = y ; smooth_or_bits (smooth, skey, 0x00c8);
1980 2338
1981 // corners 2339 // corners
1982 skey.x = x + 2; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0100); 2340 skey.x = x + 2; skey.y = y + 2; smooth_or_bits (smooth, skey, 0x0100);
1983 skey.x = x ; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0200); 2341 skey.x = x ; skey.y = y + 2; smooth_or_bits (smooth, skey, 0x0200);
1984 skey.x = x ; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0400); 2342 skey.x = x ; skey.y = y ; smooth_or_bits (smooth, skey, 0x0400);
1985 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0800); 2343 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, skey, 0x0800);
2344 }
2345 }
2346
2347 if (expect_false (z == 2) && expect_false (cell->flags))
2348 {
2349 // overlays such as the speech bubble, probably more to come
2350 if (cell->flags & 1)
2351 {
2352 rc_key_t key_ov = key;
2353 maptex tex = self->tex[TEXID_SPEECH];
2354 int px = x * Tw + Tw * 2 / 32;
2355 int py = y * Th - Th * 6 / 32;
2356
2357 key_ov.texname = tex.name;
2358 rc_t::array_t &arr = rc_ov.array (key_ov);
2359
2360 arr.t2f_v3f (0 , 0 , px , py , 0);
2361 arr.t2f_v3f (0 , tex.t, px , py + Th, 0);
2362 arr.t2f_v3f (tex.s, tex.t, px + Tw, py + Th, 0);
2363 arr.t2f_v3f (tex.s, 0 , px + Tw, py , 0);
1986 } 2364 }
1987 } 2365 }
1988 } 2366 }
1989 } 2367 }
1990 2368
1991 rc_draw (rc); 2369 rc.draw ();
1992 rc_clear (rc); 2370 rc.clear ();
1993 2371
1994 // go through all smoothlevels, lowest to highest, then draw. 2372 // go through all smoothlevels, lowest to highest, then draw.
1995 // this is basically counting sort 2373 // this is basically counting sort
1996 { 2374 {
1997 int w, b; 2375 int w, b;
1998 2376
1999 glEnable (GL_TEXTURE_2D); 2377 glEnable (GL_TEXTURE_2D);
2000 glBegin (GL_QUADS); 2378 glBegin (GL_QUADS);
2001 for (w = 0; w < 256 / 32; ++w) 2379 for (int level = 0; level < smooth_level.size (); ++level)
2380 if (smooth_level[level])
2381 for (auto &&it = smooth.begin (); it != smooth.end (); ++it)
2002 { 2382 {
2003 uint32_t smask = smooth_level [w]; 2383 smooth_key &skey = it->first;
2004 if (smask) 2384 IV bits = it->second;
2005 for (b = 0; b < 32; ++b) 2385
2006 if (smask & (((uint32_t)1) << b)) 2386 if (!(bits & 0x1000)
2387 && skey.level == level
2388 && level > smooth_max [skey.x][skey.y])
2007 { 2389 {
2008 int level = (w << 5) | b; 2390 maptex tex = self->tex [skey.tile];
2391 int px = (((int)skey.x) - 1) * Tw;
2392 int py = (((int)skey.y) - 1) * Th;
2393 int border = bits & 15;
2394 int corner = (bits >> 8) & ~(bits >> 4) & 15;
2395 float dx = tex.s * .0625f; // 16 images/row
2396 float dy = tex.t * .5f ; // 2 images/column
2397
2009 HE *he; 2398 if (tex.name)
2010
2011 hv_iterinit (smooth);
2012 while ((he = hv_iternext (smooth)))
2013 { 2399 {
2014 smooth_key *skey = (smooth_key *)HeKEY (he); 2400 // this time avoiding texture state changes
2015 IV bits = SvIVX (HeVAL (he)); 2401 // save gobs of state changes.
2016 2402 if (key.texname != tex.name)
2017 if (!(bits & 0x1000)
2018 && skey->level == level
2019 && level > smooth_max [skey->x][skey->y])
2020 { 2403 {
2021 maptex tex = self->tex [skey->tile]; 2404 self->tex [skey.tile].unused = 0;
2022 int px = (((int)skey->x) - 1) * T;
2023 int py = (((int)skey->y) - 1) * T;
2024 int border = bits & 15;
2025 int corner = (bits >> 8) & ~(bits >> 4) & 15;
2026 float dx = tex.s * .0625f; // 16 images/row
2027 float dy = tex.t * .5f ; // 2 images/column
2028 2405
2029 if (tex.name)
2030 {
2031 // this time avoiding texture state changes
2032 // save gobs of state changes.
2033 if (key.texname != tex.name)
2034 {
2035 glEnd (); 2406 glEnd ();
2036 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name); 2407 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name);
2037 glBegin (GL_QUADS); 2408 glBegin (GL_QUADS);
2038 } 2409 }
2039 2410
2040 if (border) 2411 if (border)
2041 { 2412 {
2042 float ox = border * dx; 2413 float ox = border * dx;
2043 2414
2044 glTexCoord2f (ox , 0.f ); glVertex2i (px , py ); 2415 glTexCoord2f (ox , 0.f ); glVertex2i (px , py );
2045 glTexCoord2f (ox , dy ); glVertex2i (px , py + T); 2416 glTexCoord2f (ox , dy ); glVertex2i (px , py + Th);
2046 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py + T); 2417 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py + Th);
2047 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + T, py ); 2418 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + Tw, py );
2048 } 2419 }
2049 2420
2050 if (corner) 2421 if (corner)
2051 { 2422 {
2052 float ox = corner * dx; 2423 float ox = corner * dx;
2053 2424
2054 glTexCoord2f (ox , dy ); glVertex2i (px , py ); 2425 glTexCoord2f (ox , dy ); glVertex2i (px , py );
2055 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + T); 2426 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + Th);
2056 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + T, py + T); 2427 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + Tw, py + Th);
2057 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py ); 2428 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py );
2058 }
2059 }
2060 } 2429 }
2061 } 2430 }
2062 } 2431 }
2063 } 2432 }
2064 2433
2065 glEnd (); 2434 glEnd ();
2066 glDisable (GL_TEXTURE_2D); 2435 glDisable (GL_TEXTURE_2D);
2067 key.texname = -1; 2436 key.texname = -1;
2068 } 2437 }
2069
2070 hv_clear (smooth);
2071 } 2438 }
2072 2439
2073 if (pl_tex.name) 2440 if (pl_tex.name)
2074 { 2441 {
2075 maptex tex = pl_tex; 2442 maptex tex = pl_tex;
2076 int px = pl_x + pdx; 2443 int px = pl_x + sdx;
2077 int py = pl_y + pdy; 2444 int py = pl_y + sdy;
2078 2445
2079 key.texname = tex.name; 2446 key.texname = tex.name;
2080 arr = rc_array (rc, &key); 2447 rc_t::array_t &arr = rc.array (key);
2081 2448
2082 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2449 arr.t2f_v3f (0 , 0 , px , py , 0);
2083 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0); 2450 arr.t2f_v3f (0 , tex.t, px , py + tex.h, 0);
2084 rc_t2f_v3f (arr, tex.s, tex.t, px + tex.w, py + tex.h, 0); 2451 arr.t2f_v3f (tex.s, tex.t, px + tex.w, py + tex.h, 0);
2085 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0); 2452 arr.t2f_v3f (tex.s, 0 , px + tex.w, py , 0);
2086 2453
2087 rc_draw (rc); 2454 rc.draw ();
2088 } 2455 }
2089 2456
2457 rc_ov.draw ();
2458 rc_ov.clear ();
2459
2090 glDisable (GL_BLEND); 2460 glDisable (GL_BLEND);
2091 rc_free (rc);
2092 2461
2093 // top layer: overlays such as the health bar 2462 // top layer: overlays such as the health bar
2094 for (y = 0; y < sh; y++) 2463 for (y = 0; y < sh; y++)
2095 if (0 <= y + my && y + my < self->rows) 2464 if (0 <= y + my && y + my < self->rows)
2096 { 2465 {
2099 for (x = 0; x < sw; x++) 2468 for (x = 0; x < sw; x++)
2100 if (row->c0 <= x + mx && x + mx < row->c1) 2469 if (row->c0 <= x + mx && x + mx < row->c1)
2101 { 2470 {
2102 mapcell *cell = row->col + (x + mx - row->c0); 2471 mapcell *cell = row->col + (x + mx - row->c0);
2103 2472
2104 int px = x * T; 2473 int px = x * Tw;
2105 int py = y * T; 2474 int py = y * Th;
2475
2476 if (expect_false (cell->player == player))
2477 {
2478 px += sdx;
2479 py += sdy;
2480 }
2106 2481
2107 if (cell->stat_hp) 2482 if (cell->stat_hp)
2108 { 2483 {
2109 int width = cell->stat_width * T; 2484 int width = cell->stat_width * Tw;
2110 int thick = (sh * T / 32 + 27) / 28 + 1 + cell->stat_width; 2485 int thick = (sh * Th / 32 + 27) / 28 + 1 + cell->stat_width;
2111 2486
2112 glColor3ub (0, 0, 0); 2487 glColor3ub (0, 0, 0);
2113 glRectf (px + 1, py - thick - 2, 2488 glRectf (px + 1, py - thick - 2,
2114 px + width - 1, py); 2489 px + width - 1, py);
2115 2490
2121 } 2496 }
2122 } 2497 }
2123} 2498}
2124 2499
2125void 2500void
2126draw_magicmap (DC::Map self, int dx, int dy, int w, int h, unsigned char *data) 2501draw_magicmap (DC::Map self, int w, int h, unsigned char *data)
2127 CODE: 2502 CODE:
2128{ 2503{
2129 static float color[16][3] = { 2504 static float color[16][3] = {
2130 { 0.00F, 0.00F, 0.00F }, 2505 { 0.00f, 0.00f, 0.00f },
2131 { 1.00F, 1.00F, 1.00F }, 2506 { 1.00f, 1.00f, 1.00f },
2132 { 0.00F, 0.00F, 0.55F }, 2507 { 0.00f, 0.00f, 0.55f },
2133 { 1.00F, 0.00F, 0.00F }, 2508 { 1.00f, 0.00f, 0.00f },
2134 2509
2135 { 1.00F, 0.54F, 0.00F }, 2510 { 1.00f, 0.54f, 0.00f },
2136 { 0.11F, 0.56F, 1.00F }, 2511 { 0.11f, 0.56f, 1.00f },
2137 { 0.93F, 0.46F, 0.00F }, 2512 { 0.93f, 0.46f, 0.00f },
2138 { 0.18F, 0.54F, 0.34F }, 2513 { 0.18f, 0.54f, 0.34f },
2139 2514
2140 { 0.56F, 0.73F, 0.56F }, 2515 { 0.56f, 0.73f, 0.56f },
2141 { 0.80F, 0.80F, 0.80F }, 2516 { 0.80f, 0.80f, 0.80f },
2142 { 0.55F, 0.41F, 0.13F }, 2517 { 0.55f, 0.41f, 0.13f },
2143 { 0.99F, 0.77F, 0.26F }, 2518 { 0.99f, 0.77f, 0.26f },
2144 2519
2145 { 0.74F, 0.65F, 0.41F }, 2520 { 0.74f, 0.65f, 0.41f },
2146 2521
2147 { 0.00F, 1.00F, 1.00F }, 2522 { 0.00f, 1.00f, 1.00f },
2148 { 1.00F, 0.00F, 1.00F }, 2523 { 1.00f, 0.00f, 1.00f },
2149 { 1.00F, 1.00F, 0.00F }, 2524 { 1.00f, 1.00f, 0.00f },
2150 }; 2525 };
2151 2526
2152 int x, y; 2527 int x, y;
2153 2528
2154 glEnable (GL_TEXTURE_2D); 2529 glEnable (GL_TEXTURE_2D);
2530 /* GL_REPLACE would be correct, as we don't need to modulate alpha,
2531 * but the nvidia driver (185.18.14) mishandles alpha textures
2532 * and takes the colour from god knows where instead of using
2533 * Cp. MODULATE results in the same colour, but slightly different
2534 * alpha, but atcually gives us the correct colour with nvidia.
2535 */
2155 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 2536 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
2156 glEnable (GL_BLEND); 2537 glEnable (GL_BLEND);
2157 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2538 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2158 glBegin (GL_QUADS); 2539 glBegin (GL_QUADS);
2159 2540
2160 for (y = 0; y < h; y++) 2541 for (y = 0; y < h; y++)
2164 2545
2165 if (m) 2546 if (m)
2166 { 2547 {
2167 float *c = color [m & 15]; 2548 float *c = color [m & 15];
2168 2549
2169 float tx1 = m & 0x40 ? 0.5 : 0.; 2550 float tx1 = m & 0x40 ? 0.5f : 0.f;
2170 float tx2 = tx1 + 0.5; 2551 float tx2 = tx1 + 0.5f;
2171 2552
2172 glColor4f (c[0], c[1], c[2], 0.75); 2553 glColor4f (c[0], c[1], c[2], 1);
2173 glTexCoord2f (tx1, 0.); glVertex2i (x , y ); 2554 glTexCoord2f (tx1, 0.); glVertex2i (x , y );
2174 glTexCoord2f (tx1, 1.); glVertex2i (x , y + 1); 2555 glTexCoord2f (tx1, 1.); glVertex2i (x , y + 1);
2175 glTexCoord2f (tx2, 1.); glVertex2i (x + 1, y + 1); 2556 glTexCoord2f (tx2, 1.); glVertex2i (x + 1, y + 1);
2176 glTexCoord2f (tx2, 0.); glVertex2i (x + 1, y ); 2557 glTexCoord2f (tx2, 0.); glVertex2i (x + 1, y );
2177 } 2558 }
2185void 2566void
2186fow_texture (DC::Map self, int mx, int my, int sw, int sh) 2567fow_texture (DC::Map self, int mx, int my, int sw, int sh)
2187 PPCODE: 2568 PPCODE:
2188{ 2569{
2189 int x, y; 2570 int x, y;
2190 int sw1 = sw + 2; 2571 int sw1 = sw + 2;
2191 int sh1 = sh + 2; 2572 int sh1 = sh + 2;
2192 int sh3 = sh * 3; 2573 int sh3 = sh * 3;
2193 int sw34 = (sw * 3 + 3) & ~3; 2574 int sw3 = sw * 3;
2575 SV *darkness3_sv = sv_2mortal (newSV (sw3 * sh3));
2576 uint8_t *darkness3 = (uint8_t *)SvPVX (darkness3_sv);
2194 uint8_t *darkness1 = (uint8_t *)malloc (sw1 * sh1); 2577 uint8_t *darkness1 = (uint8_t *)malloc (sw1 * sh1);
2195 SV *darkness3_sv = sv_2mortal (newSV (sw34 * sh3)); 2578 memset (darkness1, 0, sw1*sh1);
2196 uint8_t *darkness3 = (uint8_t *)SvPVX (darkness3_sv);
2197 2579
2198 SvPOK_only (darkness3_sv); 2580 SvPOK_only (darkness3_sv);
2199 SvCUR_set (darkness3_sv, sw34 * sh3); 2581 SvCUR_set (darkness3_sv, sw3 * sh3);
2200 2582
2201 mx += self->x - 1; 2583 mx += self->x - 1;
2202 my += self->y - 1; 2584 my += self->y - 1;
2203
2204 memset (darkness1, 255, sw1 * sh1);
2205 2585
2206 for (y = 0; y < sh1; y++) 2586 for (y = 0; y < sh1; y++)
2207 if (0 <= y + my && y + my < self->rows) 2587 if (0 <= y + my && y + my < self->rows)
2208 { 2588 {
2209 maprow *row = self->row + (y + my); 2589 maprow *row = self->row + (y + my);
2212 if (row->c0 <= x + mx && x + mx < row->c1) 2592 if (row->c0 <= x + mx && x + mx < row->c1)
2213 { 2593 {
2214 mapcell *cell = row->col + (x + mx - row->c0); 2594 mapcell *cell = row->col + (x + mx - row->c0);
2215 2595
2216 darkness1 [y * sw1 + x] = cell->darkness 2596 darkness1 [y * sw1 + x] = cell->darkness
2217 ? 255 - (cell->darkness - 1) 2597 ? DARKNESS_ADJUST (255 - (cell->darkness - 1))
2218 : 255 - FOW_DARKNESS; 2598 : DARKNESS_ADJUST (255 - FOW_DARKNESS);
2219 } 2599 }
2220 } 2600 }
2221 2601
2222 for (y = 0; y < sh; ++y) 2602 for (y = 0; y < sh; ++y)
2223 for (x = 0; x < sw; ++x) 2603 for (x = 0; x < sw; ++x)
2242 2622
2243 uint8_t r13 = (d13 + d23 + d12) / 3; 2623 uint8_t r13 = (d13 + d23 + d12) / 3;
2244 uint8_t r23 = d23; 2624 uint8_t r23 = d23;
2245 uint8_t r33 = (d23 + d33 + d32) / 3; 2625 uint8_t r33 = (d23 + d33 + d32) / 3;
2246 2626
2247 darkness3 [(y * 3 ) * sw34 + (x * 3 )] = MAX (d22, r11); 2627 darkness3 [(y * 3 ) * sw3 + (x * 3 )] = MAX (d22, r11);
2248 darkness3 [(y * 3 ) * sw34 + (x * 3 + 1)] = MAX (d22, r21); 2628 darkness3 [(y * 3 ) * sw3 + (x * 3 + 1)] = MAX (d22, r21);
2249 darkness3 [(y * 3 ) * sw34 + (x * 3 + 2)] = MAX (d22, r31); 2629 darkness3 [(y * 3 ) * sw3 + (x * 3 + 2)] = MAX (d22, r31);
2250 darkness3 [(y * 3 + 1) * sw34 + (x * 3 )] = MAX (d22, r12); 2630 darkness3 [(y * 3 + 1) * sw3 + (x * 3 )] = MAX (d22, r12);
2251 darkness3 [(y * 3 + 1) * sw34 + (x * 3 + 1)] = MAX (d22, r22); 2631 darkness3 [(y * 3 + 1) * sw3 + (x * 3 + 1)] = MAX (d22, r22); /* this MUST be == d22 */
2252 darkness3 [(y * 3 + 1) * sw34 + (x * 3 + 2)] = MAX (d22, r32); 2632 darkness3 [(y * 3 + 1) * sw3 + (x * 3 + 2)] = MAX (d22, r32);
2253 darkness3 [(y * 3 + 2) * sw34 + (x * 3 )] = MAX (d22, r13); 2633 darkness3 [(y * 3 + 2) * sw3 + (x * 3 )] = MAX (d22, r13);
2254 darkness3 [(y * 3 + 2) * sw34 + (x * 3 + 1)] = MAX (d22, r23); 2634 darkness3 [(y * 3 + 2) * sw3 + (x * 3 + 1)] = MAX (d22, r23);
2255 darkness3 [(y * 3 + 2) * sw34 + (x * 3 + 2)] = MAX (d22, r33); 2635 darkness3 [(y * 3 + 2) * sw3 + (x * 3 + 2)] = MAX (d22, r33);
2256 } 2636 }
2257 2637
2258 free (darkness1); 2638 free (darkness1);
2259 2639
2260 EXTEND (SP, 3); 2640 EXTEND (SP, 3);
2261 PUSHs (sv_2mortal (newSViv (sw34))); 2641 PUSHs (sv_2mortal (newSViv (sw3)));
2262 PUSHs (sv_2mortal (newSViv (sh3))); 2642 PUSHs (sv_2mortal (newSViv (sh3)));
2263 PUSHs (darkness3_sv); 2643 PUSHs (darkness3_sv);
2264} 2644}
2265 2645
2266SV * 2646SV *
2329 else 2709 else
2330 *data++ = 0; 2710 *data++ = 0;
2331 } 2711 }
2332 } 2712 }
2333 2713
2334 /* if size is w*h + 5 then no data has been found */ 2714 /* if size is w*h + 5 then no data has been found */
2335 if (data - (uint8_t *)SvPVX (data_sv) != w * h + 5) 2715 if (data - (uint8_t *)SvPVX (data_sv) != w * h + 5)
2336 { 2716 {
2337 SvPOK_only (data_sv); 2717 SvPOK_only (data_sv);
2338 SvCUR_set (data_sv, data - (uint8_t *)SvPVX (data_sv)); 2718 SvCUR_set (data_sv, data - (uint8_t *)SvPVX (data_sv));
2339 } 2719 }
2340 2720
2341 RETVAL = data_sv; 2721 RETVAL = data_sv;
2342} 2722}
2343 OUTPUT: 2723 OUTPUT:
2344 RETVAL 2724 RETVAL
2345 2725
2346void 2726void
2353 STRLEN len; 2733 STRLEN len;
2354 uint8_t *data, *end; 2734 uint8_t *data, *end;
2355 2735
2356 len = SvLEN (data_sv); 2736 len = SvLEN (data_sv);
2357 SvGROW (data_sv, len + 8); // reserve at least 7+ bytes more 2737 SvGROW (data_sv, len + 8); // reserve at least 7+ bytes more
2358 data = SvPVbyte_nolen (data_sv); 2738 data = (uint8_t *)SvPVbyte_nolen (data_sv);
2359 end = data + len + 8; 2739 end = data + len + 8;
2360 2740
2361 if (len < 5) 2741 if (len < 5)
2362 XSRETURN_EMPTY; 2742 XSRETURN_EMPTY;
2363 2743
2407 2787
2408 for (z = 0; z <= 2; z++) 2788 for (z = 0; z <= 2; z++)
2409 { 2789 {
2410 tileid t = tile [z]; 2790 tileid t = tile [z];
2411 2791
2412 if (t >= self->texs || (t && !self->tex [t].name)) 2792 if (t >= self->tex.size () || (t && !self->tex[t].name))
2413 { 2793 {
2414 PUSHs (sv_2mortal (newSViv (t))); 2794 PUSHs (sv_2mortal (newSViv (t)));
2415 need_texid (self, t); 2795 if (self->tex.size () <= t) self->tex.resize (t + 1);
2416 } 2796 }
2417 2797
2418 cell->tile [z] = t; 2798 cell->tile[z] = t;
2419 } 2799 }
2420 } 2800 }
2421 } 2801 }
2422 } 2802 }
2423 } 2803 }
2424} 2804}
2425 2805
2426MODULE = Deliantra::Client PACKAGE = DC::RW 2806MODULE = Deliantra::Client PACKAGE = DC::RW
2427 2807
2428DC::RW 2808DC::RW
2429new (SV *class, SV *data_sv) 2809new (SV *klass, SV *data_sv)
2430 CODE: 2810 CODE:
2431{ 2811{
2432 STRLEN datalen; 2812 STRLEN datalen;
2433 char *data = SvPVbyte (data_sv, datalen); 2813 char *data = SvPVbyte (data_sv, datalen);
2434 2814
2436} 2816}
2437 OUTPUT: 2817 OUTPUT:
2438 RETVAL 2818 RETVAL
2439 2819
2440DC::RW 2820DC::RW
2441new_from_file (SV *class, const char *path, const char *mode = "rb") 2821new_from_file (SV *klass, const char *path, const char *mode = "rb")
2442 CODE: 2822 CODE:
2443 RETVAL = SDL_RWFromFile (path, mode); 2823 RETVAL = SDL_RWFromFile (path, mode);
2444 OUTPUT: 2824 OUTPUT:
2445 RETVAL 2825 RETVAL
2446 2826
2464 if (RETVAL < 0) 2844 if (RETVAL < 0)
2465 { 2845 {
2466 RETVAL = Mix_GroupOldest (-1); 2846 RETVAL = Mix_GroupOldest (-1);
2467 2847
2468 if (RETVAL < 0) 2848 if (RETVAL < 0)
2849 {
2850 // happens sometimes, maybe it just stopped playing(?)
2851 RETVAL = Mix_GroupAvailable (-1);
2852
2853 if (RETVAL < 0)
2469 XSRETURN_UNDEF; 2854 XSRETURN_UNDEF;
2470 2855 }
2856 else
2471 Mix_HaltChannel (RETVAL); 2857 Mix_HaltChannel (RETVAL);
2472 } 2858 }
2473 2859
2474 Mix_UnregisterAllEffects (RETVAL); 2860 Mix_UnregisterAllEffects (RETVAL);
2475 Mix_Volume (RETVAL, 128); 2861 Mix_Volume (RETVAL, 128);
2476} 2862}
2523void 2909void
2524set_position_r (DC::Channel self, int dx, int dy, int maxdistance) 2910set_position_r (DC::Channel self, int dx, int dy, int maxdistance)
2525 CODE: 2911 CODE:
2526{ 2912{
2527 int distance = sqrtf (dx * dx + dy * dy) * (255.f / sqrtf (maxdistance * maxdistance)); 2913 int distance = sqrtf (dx * dx + dy * dy) * (255.f / sqrtf (maxdistance * maxdistance));
2528 int angle = 360 + (int)roundf (atan2f (dx, -dy) * 180.f / (float)M_PI); 2914 int angle = atan2f (dx, -dy) * 180.f / (float)M_PI + 360.f;
2529 Mix_SetPosition (self, angle, CLAMP (distance, 0, 255)); 2915 Mix_SetPosition (self, angle, CLAMP (distance, 0, 255));
2530} 2916}
2531 2917
2532void 2918void
2533set_reverse_stereo (DC::Channel self, int flip) 2919set_reverse_stereo (DC::Channel self, int flip)
2536 2922
2537MODULE = Deliantra::Client PACKAGE = DC::MixChunk 2923MODULE = Deliantra::Client PACKAGE = DC::MixChunk
2538 2924
2539PROTOTYPES: DISABLE 2925PROTOTYPES: DISABLE
2540 2926
2927void
2928decoders ()
2929 PPCODE:
2930#if SDL_MIXER_MAJOR_VERSION > 1 || SDL_MIXER_MINOR_VERSION > 2 || SDL_MIXER_PATCHLEVEL >= 10
2931 int i, num = Mix_GetNumChunkDecoders ();
2932 EXTEND (SP, num);
2933 for (i = 0; i < num; ++i)
2934 PUSHs (sv_2mortal (newSVpv (Mix_GetChunkDecoder (i), 0)));
2935#else
2936 XPUSHs (sv_2mortal (newSVpv ("(sdl mixer too old)", 0)));
2937#endif
2938
2541DC::MixChunk 2939DC::MixChunk
2542new (SV *class, DC::RW rwops) 2940new (SV *klass, DC::RW rwops)
2543 CODE: 2941 CODE:
2544 RETVAL = Mix_LoadWAV_RW (rwops, 1); 2942 RETVAL = Mix_LoadWAV_RW (rwops, 1);
2545 OUTPUT: 2943 OUTPUT:
2546 RETVAL 2944 RETVAL
2547 2945
2577 OUTPUT: 2975 OUTPUT:
2578 RETVAL 2976 RETVAL
2579 2977
2580MODULE = Deliantra::Client PACKAGE = DC::MixMusic 2978MODULE = Deliantra::Client PACKAGE = DC::MixMusic
2581 2979
2980void
2981decoders ()
2982 PPCODE:
2983#if SDL_MIXER_MAJOR_VERSION > 1 || SDL_MIXER_MINOR_VERSION > 2 || SDL_MIXER_PATCHLEVEL >= 10
2984 int i, num = Mix_GetNumMusicDecoders ();
2985 EXTEND (SP, num);
2986 for (i = 0; i < num; ++i)
2987 PUSHs (sv_2mortal (newSVpv (Mix_GetMusicDecoder (i), 0)));
2988#else
2989 XPUSHs (sv_2mortal (newSVpv ("(sdl mixer too old)", 0)));
2990#endif
2991
2582int 2992int
2583volume (int volume = -1) 2993volume (int volume = -1)
2584 PROTOTYPE: ;$ 2994 PROTOTYPE: ;$
2585 CODE: 2995 CODE:
2586 if (items > 0) 2996 if (items > 0)
2597void 3007void
2598halt () 3008halt ()
2599 CODE: 3009 CODE:
2600 Mix_HaltMusic (); 3010 Mix_HaltMusic ();
2601 3011
3012int
3013playing ()
3014 CODE:
3015 RETVAL = Mix_PlayingMusic ();
3016 OUTPUT:
3017 RETVAL
3018
2602DC::MixMusic 3019DC::MixMusic
2603new (SV *class, DC::RW rwops) 3020new (SV *klass, DC::RW rwops)
2604 CODE: 3021 CODE:
2605 RETVAL = Mix_LoadMUS_RW (rwops); 3022 RETVAL = Mix_LoadMUS_RW (rwops);
2606 OUTPUT: 3023 OUTPUT:
2607 RETVAL 3024 RETVAL
2608 3025
2636 } *civ, const_iv[] = { 3053 } *civ, const_iv[] = {
2637# define const_iv(name) { # name, (IV)name } 3054# define const_iv(name) { # name, (IV)name }
2638 const_iv (GL_VENDOR), 3055 const_iv (GL_VENDOR),
2639 const_iv (GL_VERSION), 3056 const_iv (GL_VERSION),
2640 const_iv (GL_EXTENSIONS), 3057 const_iv (GL_EXTENSIONS),
3058 const_iv (GL_MAX_TEXTURE_UNITS),
2641 const_iv (GL_COLOR_MATERIAL), 3059 const_iv (GL_COLOR_MATERIAL),
2642 const_iv (GL_SMOOTH), 3060 const_iv (GL_SMOOTH),
2643 const_iv (GL_FLAT), 3061 const_iv (GL_FLAT),
2644 const_iv (GL_DITHER), 3062 const_iv (GL_DITHER),
2645 const_iv (GL_BLEND), 3063 const_iv (GL_BLEND),
2657 const_iv (GL_ZERO), 3075 const_iv (GL_ZERO),
2658 const_iv (GL_SRC_ALPHA), 3076 const_iv (GL_SRC_ALPHA),
2659 const_iv (GL_DST_ALPHA), 3077 const_iv (GL_DST_ALPHA),
2660 const_iv (GL_ONE_MINUS_SRC_ALPHA), 3078 const_iv (GL_ONE_MINUS_SRC_ALPHA),
2661 const_iv (GL_ONE_MINUS_DST_ALPHA), 3079 const_iv (GL_ONE_MINUS_DST_ALPHA),
3080 const_iv (GL_SRC_COLOR),
3081 const_iv (GL_DST_COLOR),
3082 const_iv (GL_ONE_MINUS_SRC_COLOR),
3083 const_iv (GL_ONE_MINUS_DST_COLOR),
2662 const_iv (GL_SRC_ALPHA_SATURATE), 3084 const_iv (GL_SRC_ALPHA_SATURATE),
2663 const_iv (GL_RGB), 3085 const_iv (GL_RGB),
2664 const_iv (GL_RGBA), 3086 const_iv (GL_RGBA),
2665 const_iv (GL_RGBA4), 3087 const_iv (GL_RGBA4),
2666 const_iv (GL_RGBA8), 3088 const_iv (GL_RGBA8),
2734 const_iv (GL_NICEST), 3156 const_iv (GL_NICEST),
2735 const_iv (GL_V2F), 3157 const_iv (GL_V2F),
2736 const_iv (GL_V3F), 3158 const_iv (GL_V3F),
2737 const_iv (GL_T2F_V3F), 3159 const_iv (GL_T2F_V3F),
2738 const_iv (GL_T2F_N3F_V3F), 3160 const_iv (GL_T2F_N3F_V3F),
3161 const_iv (GL_FUNC_ADD),
3162 const_iv (GL_FUNC_SUBTRACT),
3163 const_iv (GL_FUNC_REVERSE_SUBTRACT),
2739# undef const_iv 3164# undef const_iv
2740 }; 3165 };
2741 3166
2742 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 3167 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
2743 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 3168 newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
2744 3169
2745 texture_av = newAV (); 3170 texture_av = newAV ();
2746 AvREAL_off (texture_av); 3171 AvREAL_off (texture_av);
2747} 3172}
2748 3173
2750disable_GL_EXT_blend_func_separate () 3175disable_GL_EXT_blend_func_separate ()
2751 CODE: 3176 CODE:
2752 gl.BlendFuncSeparate = 0; 3177 gl.BlendFuncSeparate = 0;
2753 gl.BlendFuncSeparateEXT = 0; 3178 gl.BlendFuncSeparateEXT = 0;
2754 3179
2755char * 3180void
3181apple_nvidia_bug (int enable)
3182
3183const char *
2756gl_vendor () 3184gl_vendor ()
2757 CODE: 3185 CODE:
2758 RETVAL = (char *)glGetString (GL_VENDOR); 3186 RETVAL = (const char *)glGetString (GL_VENDOR);
2759 OUTPUT: 3187 OUTPUT:
2760 RETVAL 3188 RETVAL
2761 3189
2762char * 3190const char *
2763gl_version () 3191gl_version ()
2764 CODE: 3192 CODE:
2765 RETVAL = (char *)glGetString (GL_VERSION); 3193 RETVAL = (const char *)glGetString (GL_VERSION);
2766 OUTPUT: 3194 OUTPUT:
2767 RETVAL 3195 RETVAL
2768 3196
2769char * 3197const char *
2770gl_extensions () 3198gl_extensions ()
2771 CODE: 3199 CODE:
2772 RETVAL = (char *)glGetString (GL_EXTENSIONS); 3200 RETVAL = (const char *)glGetString (GL_EXTENSIONS);
2773 OUTPUT: 3201 OUTPUT:
2774 RETVAL 3202 RETVAL
2775 3203
2776const char *glGetString (GLenum pname) 3204const char *glGetString (GLenum pname)
3205 CODE:
3206 RETVAL = (const char *)glGetString (pname);
3207 OUTPUT:
3208 RETVAL
2777 3209
2778GLint glGetInteger (GLenum pname) 3210GLint glGetInteger (GLenum pname)
2779 CODE: 3211 CODE:
2780 glGetIntegerv (pname, &RETVAL); 3212 glGetIntegerv (pname, &RETVAL);
2781 OUTPUT: 3213 OUTPUT:
2789 3221
2790int glGetError () 3222int glGetError ()
2791 3223
2792void glFinish () 3224void glFinish ()
2793 3225
3226void glFlush ()
3227
2794void glClear (int mask) 3228void glClear (int mask)
2795 3229
2796void glClearColor (float r, float g, float b, float a = 1.0) 3230void glClearColor (float r, float g, float b, float a = 1.0)
2797 PROTOTYPE: @ 3231 PROTOTYPE: @
2798 3232
2807void glBlendFunc (int sfactor, int dfactor) 3241void glBlendFunc (int sfactor, int dfactor)
2808 3242
2809void glBlendFuncSeparate (int sa, int da, int saa, int daa) 3243void glBlendFuncSeparate (int sa, int da, int saa, int daa)
2810 CODE: 3244 CODE:
2811 gl_BlendFuncSeparate (sa, da, saa, daa); 3245 gl_BlendFuncSeparate (sa, da, saa, daa);
3246
3247# void glBlendEquation (int se)
2812 3248
2813void glDepthMask (int flag) 3249void glDepthMask (int flag)
2814 3250
2815void glLogicOp (int opcode) 3251void glLogicOp (int opcode)
2816 3252
2851void glRotate (float angle, float x, float y, float z) 3287void glRotate (float angle, float x, float y, float z)
2852 CODE: 3288 CODE:
2853 glRotatef (angle, x, y, z); 3289 glRotatef (angle, x, y, z);
2854 3290
2855void glColor (float r, float g, float b, float a = 1.0) 3291void glColor (float r, float g, float b, float a = 1.0)
3292 PROTOTYPE: @
2856 ALIAS: 3293 ALIAS:
2857 glColor_premultiply = 1 3294 glColor_premultiply = 1
2858 CODE: 3295 CODE:
2859 if (ix) 3296 if (ix)
2860 { 3297 {
2966 3403
2967void glEndList () 3404void glEndList ()
2968 3405
2969void glCallList (int list) 3406void glCallList (int list)
2970 3407
3408void c_init ()
3409 CODE:
3410 glPixelStorei (GL_PACK_ALIGNMENT , 1);
3411 glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
3412
2971MODULE = Deliantra::Client PACKAGE = DC::UI::Base 3413MODULE = Deliantra::Client PACKAGE = DC::UI::Base
2972 3414
2973PROTOTYPES: DISABLE 3415PROTOTYPES: DISABLE
2974 3416
2975void 3417void
2976find_widget (SV *self, NV x, NV y) 3418find_widget (SV *self, NV x, NV y)
2977 PPCODE: 3419 PPCODE:
2978{ 3420{
2979 if (within_widget (self, x, y)) 3421 if (within_widget (self, x, y))
2980 XPUSHs (self); 3422 XPUSHs (self);
2981} 3423}
2982 3424
2983BOOT: 3425BOOT:
2984{ 3426{
2992 3434
2993void 3435void
2994draw (SV *self) 3436draw (SV *self)
2995 CODE: 3437 CODE:
2996{ 3438{
2997 HV *hv; 3439 HV *hv;
2998 SV **svp; 3440 SV **svp;
2999 NV x, y, w, h; 3441 NV x, y, w, h;
3000 SV *draw_x_sv = GvSV (draw_x_gv); 3442 SV *draw_x_sv = GvSV (draw_x_gv);
3001 SV *draw_y_sv = GvSV (draw_y_gv); 3443 SV *draw_y_sv = GvSV (draw_y_gv);
3002 SV *draw_w_sv = GvSV (draw_w_gv); 3444 SV *draw_w_sv = GvSV (draw_w_gv);
3003 SV *draw_h_sv = GvSV (draw_h_gv); 3445 SV *draw_h_sv = GvSV (draw_h_gv);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines