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.296 by root, Mon Dec 21 23:52:34 2009 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 atan2f(x,y) atan2(x,y) 26# define atan2f(x,y) atan2(x,y)
25# define M_PI 3.14159265f 27# define M_PI 3.14159265f
26#endif 28#endif
27 29
28#include <assert.h> 30#include <cassert>
29#include <math.h> 31#include <cmath>
30#include <string.h> 32#include <cstring>
31#include <stdio.h> 33#include <cstdio>
32#include <stdlib.h> 34#include <cstdlib>
35
36#include <utility>
37#include <bitset>
33 38
34#define USE_RWOPS 1 // for SDL_mixer:LoadMUS_RW 39#define USE_RWOPS 1 // for SDL_mixer:LoadMUS_RW
35 40
36#include <SDL.h> 41#include <SDL.h>
37#include <SDL_thread.h> 42#include <SDL_thread.h>
41#include <SDL_opengl.h> 46#include <SDL_opengl.h>
42 47
43/* work around os x broken headers */ 48/* work around os x broken headers */
44#ifdef __MACOSX__ 49#ifdef __MACOSX__
45typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); 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);
46#endif 53#endif
47 54
48#define PANGO_ENABLE_BACKEND 55#define PANGO_ENABLE_BACKEND
49#define G_DISABLE_CAST_CHECKS 56#define G_DISABLE_CAST_CHECKS
50 57
51#include <glib/gmacros.h> 58#include <glib.h>
52 59
53#include <pango/pango.h> 60#include <pango/pango.h>
54 61
55#ifndef PANGO_VERSION_CHECK 62#ifndef PANGO_VERSION_CHECK
56# define PANGO_VERSION_CHECK(a,b,c) 0 63# define PANGO_VERSION_CHECK(a,b,c) 0
97 104
98#define KMOD_LRAM 0x10000 // our extension 105#define KMOD_LRAM 0x10000 // our extension
99 106
100#define TEXID_SPEECH 1 107#define TEXID_SPEECH 1
101#define TEXID_NOFACE 2 108#define TEXID_NOFACE 2
102#define TEXID_HIDDEN 3 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}
103 128
104static AV *texture_av; 129static AV *texture_av;
105 130
106static struct 131static struct
107{ 132{
164{ 189{
165 GSList *attrs = run->item->analysis.extra_attrs; 190 GSList *attrs = run->item->analysis.extra_attrs;
166 191
167 while (attrs) 192 while (attrs)
168 { 193 {
169 PangoAttribute *attr = attrs->data; 194 PangoAttribute *attr = (PangoAttribute *)attrs->data;
170 195
171 if (attr->klass->type == PANGO_ATTR_SHAPE) 196 if (attr->klass->type == PANGO_ATTR_SHAPE)
172 return 1; 197 return 1;
173 198
174 attrs = attrs->next; 199 attrs = attrs->next;
175 } 200 }
176 201
177 return 0; 202 return 0;
178} 203}
179 204
180typedef struct cf_layout { 205struct cf_layout {
181 PangoLayout *pl; 206 PangoLayout *pl;
182 float r, g, b, a; // default color for rgba mode 207 float r, g, b, a; // default color for rgba mode
183 int base_height; 208 int base_height;
184 DC__Font font; 209 DC__Font font;
185 rc_t *rc; 210 rc_t rc;
186} *DC__Layout; 211};
212
213typedef cf_layout *DC__Layout;
187 214
188static DC__Font default_font; 215static DC__Font default_font;
189static PangoContext *opengl_context; 216static PangoContext *opengl_context;
190static PangoFontMap *opengl_fontmap; 217static PangoFontMap *opengl_fontmap;
191 218
192static void 219static void
193substitute_func (FcPattern *pattern, gpointer data) 220substitute_func (FcPattern *pattern, gpointer data)
194{ 221{
195 FcPatternAddBool (pattern, FC_HINTING, 1); 222 FcPatternAddBool (pattern, FC_HINTING, 1);
196#ifdef FC_HINT_STYLE 223#ifdef FC_HINT_STYLE
197 FcPatternAddBool (pattern, FC_HINT_STYLE, FC_HINT_FULL); 224 FcPatternAddInteger (pattern, FC_HINT_STYLE, FC_HINT_FULL);
198#endif 225#endif
199 FcPatternAddBool (pattern, FC_AUTOHINT, 0); 226 FcPatternAddBool (pattern, FC_AUTOHINT, 0);
200} 227}
201 228
202static void 229static void
232} 259}
233 260
234typedef uint16_t tileid; 261typedef uint16_t tileid;
235typedef uint16_t faceid; 262typedef uint16_t faceid;
236 263
237typedef struct { 264struct maptex
265{
238 GLuint name; 266 GLuint name;
239 int w, h; 267 int w, h;
240 float s, t; 268 float s, t;
241 uint8_t r, g, b, a; 269 uint8_t r, g, b, a;
242 tileid smoothtile; 270 tileid smoothtile;
243 uint8_t smoothlevel; 271 uint8_t smoothlevel;
244 uint8_t unused; /* set to zero on use */ 272 uint8_t unused; /* set to zero on use */
245} maptex; 273};
246 274
247typedef struct { 275struct mapcell
276{
248 uint32_t player; 277 uint32_t player;
249 tileid tile[3]; 278 tileid tile[3];
250 uint16_t darkness; 279 uint16_t darkness;
251 uint8_t stat_width, stat_hp, flags, smoothmax; 280 uint8_t stat_width, stat_hp, flags, smoothmax;
252} mapcell; 281};
253 282
254typedef struct { 283struct maprow
284{
255 int32_t c0, c1; 285 int32_t c0, c1;
256 mapcell *col; 286 mapcell *col;
257} maprow; 287};
258 288
259typedef struct map { 289struct mapgrid {
260 int x, y, w, h; 290 int x, y, w, h;
261 int ox, oy; /* offset to virtual global coordinate system */ 291 int ox, oy; /* offset to virtual global coordinate system */
262 int faces; tileid *face2tile; // [faceid] 292 std::vector<tileid> tile;
263 int texs; maptex *tex; // [tileid] 293 std::vector<maptex> tex;
264 294
265 int32_t rows; 295 int32_t rows;
266 maprow *row; 296 maprow *row;
267} *DC__Map; 297
298 ~mapgrid ()
299 {
300 clear_cells ();
301 }
302
303 void clear_cells ();
304};
305
306typedef mapgrid *DC__Map;
268 307
269static char * 308static char *
270prepend (char *ptr, int sze, int inc) 309prepend (char *ptr, int sze, int inc)
271{ 310{
272 char *p; 311 char *p;
289} 328}
290 329
291#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))
292#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))
293 332
294static void
295need_facenum (struct map *self, faceid face)
296{
297 while (self->faces <= face)
298 {
299 Append (tileid, self->face2tile, self->faces, self->faces);
300 self->faces *= 2;
301 }
302}
303
304static void
305need_texid (struct map *self, int texid)
306{
307 while (self->texs <= texid)
308 {
309 Append (maptex, self->tex, self->texs, self->texs);
310 self->texs *= 2;
311 }
312}
313
314static maprow * 333static maprow *
315map_get_row (DC__Map self, int y) 334map_get_row (mapgrid *self, int y)
316{ 335{
317 if (0 > y) 336 if (0 > y)
318 { 337 {
319 int extend = - y + MAP_EXTEND_Y; 338 int extend = - y + MAP_EXTEND_Y;
320 Prepend (maprow, self->row, self->rows, extend); 339 Prepend (maprow, self->row, self->rows, extend);
358 377
359 return row->col + (x - row->c0); 378 return row->col + (x - row->c0);
360} 379}
361 380
362static mapcell * 381static mapcell *
363map_get_cell (DC__Map self, int x, int y) 382map_get_cell (mapgrid *self, int x, int y)
364{ 383{
365 return row_get_cell (map_get_row (self, y), x); 384 return row_get_cell (map_get_row (self, y), x);
366} 385}
367 386
368static void 387void mapgrid::clear_cells ()
369map_clear (DC__Map self)
370{ 388{
371 int r; 389 int r;
372 390
373 for (r = 0; r < self->rows; r++) 391 for (r = 0; r < rows; r++)
374 Safefree (self->row[r].col); 392 Safefree (row[r].col);
375 393
376 Safefree (self->row); 394 Safefree (row);
377 395
378 self->x = 0; 396 x = 0;
379 self->y = 0; 397 y = 0;
380 self->ox = 0; 398 ox = 0;
381 self->oy = 0; 399 oy = 0;
382 self->row = 0; 400 row = 0;
383 self->rows = 0; 401 rows = 0;
384} 402}
385 403
386#define CELL_CLEAR(cell) \ 404#define CELL_CLEAR(cell) \
387 do { \ 405 do { \
388 if ((cell)->player) \ 406 if ((cell)->player) \
392 (cell)->flags = 0; \ 410 (cell)->flags = 0; \
393 (cell)->player = 0; \ 411 (cell)->player = 0; \
394 } while (0) 412 } while (0)
395 413
396static void 414static void
397map_blank (DC__Map self, int x0, int y0, int w, int h) 415map_blank (mapgrid *self, int x0, int y0, int w, int h)
398{ 416{
399 int x, y; 417 int x, y;
400 maprow *row; 418 maprow *row;
401 mapcell *cell; 419 mapcell *cell;
402 420
419 CELL_CLEAR (cell); 437 CELL_CLEAR (cell);
420 } 438 }
421 } 439 }
422} 440}
423 441
424typedef struct { 442struct smooth_key
443{
425 tileid tile; 444 tileid tile;
426 uint8_t x, y, level; 445 uint8_t x, y, level;
427} 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}
428 465
429static void 466static void
430smooth_or_bits (HV *hv, smooth_key *key, IV bits) 467smooth_or_bits (smooth_hash &h, smooth_key &key, IV bits)
431{ 468{
432 SV **sv = hv_fetch (hv, (char *)key, sizeof (*key), 1); 469 auto &&it = h.find (key);
433 470
434 if (SvIOK (*sv)) 471 if (it == h.end ())
435 SvIV_set (*sv, SvIVX (*sv) | bits); 472 h.insert (std::make_pair (key, bits));
436 else 473 else
437 sv_setiv (*sv, bits); 474 it->second |= bits;
438} 475}
439 476
440static void 477static void
441music_finished (void) 478music_finished (void)
442{ 479{
459 ev.code = 1; 496 ev.code = 1;
460 ev.data1 = (void *)(long)channel; 497 ev.data1 = (void *)(long)channel;
461 ev.data2 = 0; 498 ev.data2 = 0;
462 499
463 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;
464} 508}
465 509
466static unsigned int 510static unsigned int
467minpot (unsigned int n) 511minpot (unsigned int n)
468{ 512{
551 595
552 return mod; 596 return mod;
553} 597}
554 598
555static void 599static void
556deliantra_main () 600deliantra_main (SV *real_main)
557{ 601{
558 char *argv[] = { 0 }; 602 dSP;
559 call_argv ("::main", G_DISCARD | G_VOID, argv); 603
604 PUSHMARK (SP);
605 call_sv (real_main, G_DISCARD | G_VOID);
560} 606}
561 607
562#ifdef __MACOSX__ 608#ifdef __MACOSX__
609 static SV *real_main;
610
563 /* to due surprising braindamage on the side of SDL design, we 611 /* to due surprising braindamage on the side of SDL design, we
564 * do some mind-boggling hack here: SDL requires a custom main() 612 * do some mind-boggling hack here: SDL requires a custom main()
565 * on OS X, so... we provide one and call the original main(), which, 613 * on OS X, so... we provide one and call the original main(), which,
566 * due to share dlibrary magic, calls -lSDLmain's main, not perl's main, 614 * due to shared library magic, calls -lSDLmain's main, not perl's main,
567 * and which calls our main (== SDL_main) back. 615 * and which calls our main (== SDL_main) back.
568 */ 616 */
569 extern C_LINKAGE int 617 extern C_LINKAGE int
570 main (int argc, char *argv[]) 618 main (int argc, char *argv[])
571 { 619 {
572 deliantra_main (); 620 deliantra_main (real_main);
573 } 621 }
574 622
575 #undef main 623 #undef main
576 624
577 extern C_LINKAGE int main (int argc, char *argv[]); 625 extern C_LINKAGE int main (int argc, char *argv[]);
578 626
579 static void 627 static void
580 SDL_braino (void) 628 SDL_main_hack (SV *real_main_)
581 { 629 {
630 real_main = real_main_;
631
582 char *argv[] = { "deliantra client", 0 }; 632 char *argv[] = { "deliantra client", 0 };
583 (main) (1, argv); 633 (main) (1, argv);
584 } 634 }
585#else 635#else
586 static void 636 static void
587 SDL_braino (void) 637 SDL_main_hack (SV *real_main)
588 { 638 {
589 deliantra_main (); 639 deliantra_main (real_main);
590 } 640 }
591#endif 641#endif
592 642
593MODULE = Deliantra::Client PACKAGE = DC 643MODULE = Deliantra::Client PACKAGE = DC
594 644
795 845
796 const_iv (FOW_DARKNESS) 846 const_iv (FOW_DARKNESS)
797# undef const_iv 847# undef const_iv
798 }; 848 };
799 849
800 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--)
801 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 851 newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
802 852
803 assert (SDLK_MODIFIER_MIN == SDLK_NUMLOCK); 853 assert (SDLK_MODIFIER_MIN == SDLK_NUMLOCK);
804 assert (SDLK_MODIFIER_MAX == SDLK_COMPOSE); 854 assert (SDLK_MODIFIER_MAX == SDLK_COMPOSE);
805} 855}
806 856
845#endif 895#endif
846} 896}
847 897
848char *SDL_GetError () 898char *SDL_GetError ()
849 899
850void SDL_braino () 900void SDL_main_hack (SV *real_main)
901 PROTOTYPE: &
851 902
852int SDL_Init (U32 flags) 903int SDL_Init (U32 flags)
853 904
854int SDL_InitSubSystem (U32 flags) 905int SDL_InitSubSystem (U32 flags)
855 906
856void SDL_QuitSubSystem (U32 flags) 907void SDL_QuitSubSystem (U32 flags)
857 908
858void SDL_Quit () 909void SDL_Quit ()
859 910
860int SDL_GL_SetAttribute (int attr, int value) 911int SDL_GL_SetAttribute (int attr, int value)
912 C_ARGS: (SDL_GLattr)attr, value
861 913
862int SDL_GL_GetAttribute (int attr) 914int SDL_GL_GetAttribute (int attr)
863 CODE: 915 CODE:
864 if (SDL_GL_GetAttribute (attr, &RETVAL)) 916 if (SDL_GL_GetAttribute ((SDL_GLattr)attr, &RETVAL))
865 XSRETURN_UNDEF; 917 XSRETURN_UNDEF;
866 OUTPUT: 918 OUTPUT:
867 RETVAL 919 RETVAL
868 920
869void 921void
924 ); 976 );
925 977
926 if (RETVAL) 978 if (RETVAL)
927 { 979 {
928 av_clear (texture_av); 980 av_clear (texture_av);
929
930 SDL_WM_SetCaption ("Deliantra MORPG Client " VERSION, "Deliantra");
931#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);
932#include "glfunc.h" 982#include "glfunc.h"
933#undef GL_FUNC 983#undef GL_FUNC
984 if (!gl.ActiveTexture ) gl.ActiveTexture = gl.ActiveTextureARB;
985 if (!gl.MultiTexCoord2f) gl.MultiTexCoord2f = gl.MultiTexCoord2fARB;
934 } 986 }
935} 987}
936 OUTPUT: 988 OUTPUT:
937 RETVAL 989 RETVAL
990
991void
992SDL_WM_SetCaption (const char *title, const char *icon)
938 993
939void 994void
940SDL_GL_SwapBuffers () 995SDL_GL_SwapBuffers ()
941 996
942char * 997char *
943SDL_GetKeyName (int sym) 998SDL_GetKeyName (int sym)
999 C_ARGS: (SDLKey)sym
944 1000
945int 1001int
946SDL_GetAppState () 1002SDL_GetAppState ()
947 1003
948int 1004int
949SDL_GetModState () 1005SDL_GetModState ()
950 1006
1007int
1008SDL_WaitEvent ()
1009 C_ARGS: 0
1010
951void 1011void
1012SDL_PumpEvents ()
1013
1014void
952poll_events () 1015peep_events ()
953 PPCODE: 1016 PPCODE:
954{ 1017{
955 SDL_Event ev; 1018 SDL_Event ev;
956 1019
957 SDL_PumpEvents (); 1020 SDL_PumpEvents ();
1023 1086
1024 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))));
1025 } 1088 }
1026} 1089}
1027 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
1028int 1104int
1029Mix_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)
1030 POSTCALL: 1106 POSTCALL:
1031 Mix_HookMusicFinished (music_finished); 1107 Mix_HookMusicFinished (music_finished);
1032 Mix_ChannelFinished (channel_finished); 1108 Mix_ChannelFinished (channel_finished);
1033 1109
1034void 1110void
1035Mix_QuerySpec () 1111Mix_QuerySpec ()
1094add_font (char *file) 1170add_font (char *file)
1095 CODE: 1171 CODE:
1096 RETVAL = FcConfigAppFontAddFile (0, (const FcChar8 *)file); 1172 RETVAL = FcConfigAppFontAddFile (0, (const FcChar8 *)file);
1097 OUTPUT: 1173 OUTPUT:
1098 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)
1099 1182
1100void 1183void
1101load_image_inline (SV *image_) 1184load_image_inline (SV *image_)
1102 ALIAS: 1185 ALIAS:
1103 load_image_file = 1 1186 load_image_file = 1
1149 1232
1150 SDL_LockSurface (surface2); 1233 SDL_LockSurface (surface2);
1151 EXTEND (SP, 6); 1234 EXTEND (SP, 6);
1152 PUSHs (sv_2mortal (newSViv (surface2->w))); 1235 PUSHs (sv_2mortal (newSViv (surface2->w)));
1153 PUSHs (sv_2mortal (newSViv (surface2->h))); 1236 PUSHs (sv_2mortal (newSViv (surface2->h)));
1154 PUSHs (sv_2mortal (newSVpvn (surface2->pixels, surface2->h * surface2->pitch))); 1237 PUSHs (sv_2mortal (newSVpvn ((const char *)surface2->pixels, surface2->h * surface2->pitch)));
1155 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)));
1156 PUSHs (sv_2mortal (newSViv (GL_RGBA))); 1239 PUSHs (sv_2mortal (newSViv (GL_RGBA)));
1157 PUSHs (sv_2mortal (newSViv (GL_UNSIGNED_BYTE))); 1240 PUSHs (sv_2mortal (newSViv (GL_UNSIGNED_BYTE)));
1158 SDL_UnlockSurface (surface2); 1241 SDL_UnlockSurface (surface2);
1159 1242
1231MODULE = Deliantra::Client PACKAGE = DC::Font 1314MODULE = Deliantra::Client PACKAGE = DC::Font
1232 1315
1233PROTOTYPES: DISABLE 1316PROTOTYPES: DISABLE
1234 1317
1235DC::Font 1318DC::Font
1236new_from_file (SV *class, char *path, int id = 0) 1319new_from_file (SV *klass, char *path, int id = 0)
1237 CODE: 1320 CODE:
1238{ 1321{
1239 int count; 1322 int count;
1240 FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)path, id, 0, &count); 1323 FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)path, id, 0, &count);
1241 RETVAL = pango_fc_font_description_from_pattern (pattern, 0); 1324 RETVAL = pango_fc_font_description_from_pattern (pattern, 0);
1270 PROTOTYPE: 1353 PROTOTYPE:
1271 CODE: 1354 CODE:
1272 tc_restore (); 1355 tc_restore ();
1273 1356
1274DC::Layout 1357DC::Layout
1275new (SV *class) 1358new (SV *klass)
1276 CODE: 1359 CODE:
1277 New (0, RETVAL, 1, struct cf_layout); 1360 RETVAL = new cf_layout;
1278 1361
1279 RETVAL->pl = pango_layout_new (opengl_context); 1362 RETVAL->pl = pango_layout_new (opengl_context);
1280 RETVAL->r = 1.; 1363 RETVAL->r = 1.;
1281 RETVAL->g = 1.; 1364 RETVAL->g = 1.;
1282 RETVAL->b = 1.; 1365 RETVAL->b = 1.;
1283 RETVAL->a = 1.; 1366 RETVAL->a = 1.;
1284 RETVAL->base_height = MIN_FONT_HEIGHT; 1367 RETVAL->base_height = MIN_FONT_HEIGHT;
1285 RETVAL->font = 0; 1368 RETVAL->font = 0;
1286 RETVAL->rc = rc_alloc ();
1287 1369
1288 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR); 1370 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
1289 layout_update_font (RETVAL); 1371 layout_update_font (RETVAL);
1290 OUTPUT: 1372 OUTPUT:
1291 RETVAL 1373 RETVAL
1292 1374
1293void 1375void
1294DESTROY (DC::Layout self) 1376DESTROY (DC::Layout self)
1295 CODE: 1377 CODE:
1296 g_object_unref (self->pl); 1378 g_object_unref (self->pl);
1297 rc_free (self->rc);
1298 Safefree (self); 1379 delete self;
1299 1380
1300void 1381void
1301set_text (DC::Layout self, SV *text_) 1382set_text (DC::Layout self, SV *text_)
1302 CODE: 1383 CODE:
1303{ 1384{
1429 1510
1430void 1511void
1431set_height (DC::Layout self, int base_height) 1512set_height (DC::Layout self, int base_height)
1432 CODE: 1513 CODE:
1433 if (self->base_height != base_height) 1514 if (self->base_height != base_height)
1434 { 1515 {
1435 self->base_height = base_height; 1516 self->base_height = base_height;
1436 layout_update_font (self); 1517 layout_update_font (self);
1437 } 1518 }
1438 1519
1439void 1520void
1557} 1638}
1558 1639
1559void 1640void
1560render (DC::Layout self, float x, float y, int flags = 0) 1641render (DC::Layout self, float x, float y, int flags = 0)
1561 CODE: 1642 CODE:
1562 rc_clear (self->rc); 1643 self->rc.clear ();
1563 pango_opengl_render_layout_subpixel ( 1644 pango_opengl_render_layout_subpixel (
1564 self->pl, 1645 self->pl,
1565 self->rc, 1646 &self->rc,
1566 x * PANGO_SCALE, y * PANGO_SCALE, 1647 x * PANGO_SCALE, y * PANGO_SCALE,
1567 self->r, self->g, self->b, self->a, 1648 self->r, self->g, self->b, self->a,
1568 flags 1649 flags
1569 ); 1650 );
1570 // we assume that context_change actually clears/frees stuff 1651 // we assume that context_change actually clears/frees stuff
1581 gl_BlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 1662 gl_BlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
1582 GL_ONE , GL_ONE_MINUS_SRC_ALPHA); 1663 GL_ONE , GL_ONE_MINUS_SRC_ALPHA);
1583 glEnable (GL_ALPHA_TEST); 1664 glEnable (GL_ALPHA_TEST);
1584 glAlphaFunc (GL_GREATER, 7.f / 255.f); 1665 glAlphaFunc (GL_GREATER, 7.f / 255.f);
1585 1666
1586 rc_draw (self->rc); 1667 self->rc.draw ();
1587 1668
1588 glDisable (GL_ALPHA_TEST); 1669 glDisable (GL_ALPHA_TEST);
1589 glDisable (GL_BLEND); 1670 glDisable (GL_BLEND);
1590 glDisable (GL_TEXTURE_2D); 1671 glDisable (GL_TEXTURE_2D);
1591} 1672}
1671void 1752void
1672draw_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) 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)
1673 PROTOTYPE: @ 1754 PROTOTYPE: @
1674 CODE: 1755 CODE:
1675{ 1756{
1757 glEnable (GL_BLEND);
1758 glBlendFunc (intensity ? GL_SRC_ALPHA : GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1676 glEnable (GL_TEXTURE_2D); 1759 glEnable (GL_TEXTURE_2D);
1677 glEnable (GL_BLEND);
1678 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1679 glBindTexture (GL_TEXTURE_2D, name1); 1760 glBindTexture (GL_TEXTURE_2D, name1);
1680 1761
1681 glColor3f (intensity, intensity, intensity); 1762 glColor3f (intensity, intensity, intensity);
1682 glPushMatrix (); 1763 glPushMatrix ();
1683 glScalef (1./3, 1./3, 1.); 1764 glScalef (1./3, 1./3, 1.);
1698 glBindTexture (GL_TEXTURE_2D, name2); 1779 glBindTexture (GL_TEXTURE_2D, name2);
1699 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 1780 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
1700 1781
1701 /* rgb == rgb(glcolor) */ 1782 /* rgb == rgb(glcolor) */
1702 glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); 1783 glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
1703 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_CONSTANT); 1784 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
1704 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); 1785 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
1705 1786
1706 /* alpha = interpolate t0, t1 by env_alpha */ 1787 /* alpha = interpolate t0, t1 by env_alpha */
1707 glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, env_color); 1788 glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, env_color);
1708 1789
1803MODULE = Deliantra::Client PACKAGE = DC::Map 1884MODULE = Deliantra::Client PACKAGE = DC::Map
1804 1885
1805PROTOTYPES: DISABLE 1886PROTOTYPES: DISABLE
1806 1887
1807DC::Map 1888DC::Map
1808new (SV *class) 1889new (SV *klass)
1809 CODE: 1890 CODE:
1810 New (0, RETVAL, 1, struct map); 1891 RETVAL = new mapgrid;
1811 RETVAL->x = 0; 1892 RETVAL->x = 0;
1812 RETVAL->y = 0; 1893 RETVAL->y = 0;
1813 RETVAL->w = 0; 1894 RETVAL->w = 0;
1814 RETVAL->h = 0; 1895 RETVAL->h = 0;
1815 RETVAL->ox = 0; 1896 RETVAL->ox = 0;
1816 RETVAL->oy = 0; 1897 RETVAL->oy = 0;
1817 RETVAL->faces = 8192; Newz (0, RETVAL->face2tile, RETVAL->faces, tileid);
1818 RETVAL->texs = 8192; Newz (0, RETVAL->tex , RETVAL->texs , maptex);
1819 RETVAL->rows = 0; 1898 RETVAL->rows = 0;
1820 RETVAL->row = 0; 1899 RETVAL->row = 0;
1821 OUTPUT: 1900 OUTPUT:
1822 RETVAL 1901 RETVAL
1823 1902
1824void 1903void
1825DESTROY (DC::Map self) 1904DESTROY (DC::Map self)
1826 CODE: 1905 CODE:
1827{ 1906{
1828 map_clear (self);
1829 Safefree (self->face2tile);
1830 Safefree (self->tex);
1831 Safefree (self); 1907 delete self;
1832} 1908}
1833 1909
1834void 1910void
1835resize (DC::Map self, int map_width, int map_height) 1911resize (DC::Map self, int map_width, int map_height)
1836 CODE: 1912 CODE:
1838 self->h = map_height; 1914 self->h = map_height;
1839 1915
1840void 1916void
1841clear (DC::Map self) 1917clear (DC::Map self)
1842 CODE: 1918 CODE:
1843 map_clear (self); 1919 self->clear_cells ();
1844 1920
1845void 1921void
1846set_tileid (DC::Map self, int face, int tile) 1922set_tileid (DC::Map self, int face, int tile)
1847 CODE: 1923 CODE:
1848{ 1924{
1849 need_facenum (self, face); self->face2tile [face] = tile; 1925 if (self->tile.size () <= face) self->tile.resize (face + 1);
1850 need_texid (self, tile); 1926 self->tile[face] = tile;
1927 if (self->tex.size () <= tile) self->tex .resize (tile + 1);
1851} 1928}
1852 1929
1853void 1930void
1854set_smooth (DC::Map self, int face, int smooth, int level) 1931set_smooth (DC::Map self, int face, int smooth, int level)
1855 CODE: 1932 CODE:
1856{ 1933{
1857 tileid texid;
1858 maptex *tex;
1859
1860 if (face < 0 || face >= self->faces) 1934 if (face < 0 || face >= self->tile.size ())
1861 return; 1935 return;
1862 1936
1863 if (smooth < 0 || smooth >= self->faces) 1937 if (smooth < 0 || smooth >= self->tile.size ())
1864 return; 1938 return;
1865 1939
1866 texid = self->face2tile [face]; 1940 tileid texid = self->tile[face];
1867 1941
1868 if (!texid) 1942 if (!texid)
1869 return; 1943 return;
1870 1944
1871 tex = self->tex + texid; 1945 maptex &tex = self->tex[texid];
1872 tex->smoothtile = self->face2tile [smooth]; 1946 tex.smoothtile = self->tile[smooth];
1873 tex->smoothlevel = level; 1947 tex.smoothlevel = level;
1874} 1948}
1875 1949
1876void 1950void
1877set_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)
1878 CODE: 1952 CODE:
1879{ 1953{
1880 need_texid (self, texid); 1954 if (self->tex.size () < texid) self->tex.resize (texid + 1);
1881 1955
1882 { 1956 {
1883 maptex *tex = self->tex + texid; 1957 maptex &tex = self->tex[texid];
1884 1958
1885 tex->name = name; 1959 tex.name = name;
1886 tex->w = w; 1960 tex.w = w;
1887 tex->h = h; 1961 tex.h = h;
1888 tex->s = s; 1962 tex.s = s;
1889 tex->t = t; 1963 tex.t = t;
1890 tex->r = r; 1964 tex.r = r;
1891 tex->g = g; 1965 tex.g = g;
1892 tex->b = b; 1966 tex.b = b;
1893 tex->a = a; 1967 tex.a = a;
1894 } 1968 }
1895 1969
1896 // somewhat hackish, but for textures that require it, it really 1970 // somewhat hackish, but for textures that require it, it really
1897 // improves the look, and most others don't suffer. 1971 // improves the look, and most others don't suffer.
1898 glBindTexture (GL_TEXTURE_2D, name); 1972 glBindTexture (GL_TEXTURE_2D, name);
1904} 1978}
1905 1979
1906void 1980void
1907expire_textures (DC::Map self, int texid, int count) 1981expire_textures (DC::Map self, int texid, int count)
1908 PPCODE: 1982 PPCODE:
1909 for (; texid < self->texs && count; ++texid, --count) 1983 for (; texid < self->tex.size () && count; ++texid, --count)
1910 { 1984 {
1911 maptex *tex = self->tex + texid; 1985 maptex &tex = self->tex[texid];
1912 1986
1913 if (tex->name) 1987 if (tex.name)
1914 { 1988 {
1915 if (tex->unused) 1989 if (tex.unused)
1916 { 1990 {
1917 tex->name = 0; 1991 tex.name = 0;
1918 tex->unused = 0; 1992 tex.unused = 0;
1919 XPUSHs (sv_2mortal (newSViv (texid))); 1993 XPUSHs (sv_2mortal (newSViv (texid)));
1920 } 1994 }
1921 else 1995 else
1922 tex->unused = 1; 1996 tex.unused = 1;
1923 } 1997 }
1924 } 1998 }
1925 1999
1926int 2000int
1927ox (DC::Map self) 2001ox (DC::Map self)
1969 self->y += MAP_EXTEND_Y; 2043 self->y += MAP_EXTEND_Y;
1970 } 2044 }
1971} 2045}
1972 2046
1973SV * 2047SV *
1974map1a_update (DC::Map self, SV *data_, int extmap) 2048map1a_update (DC::Map self, SV *data_)
1975 CODE: 2049 CODE:
1976{ 2050{
1977 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_); 2051 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_);
1978 uint8_t *data_end = (uint8_t *)SvEND (data_); 2052 uint8_t *data_end = (uint8_t *)SvEND (data_);
1979 mapcell *cell; 2053 mapcell *cell;
2000 2074
2001 //TODO: don't trust server data to be in-range(!) 2075 //TODO: don't trust server data to be in-range(!)
2002 2076
2003 if (flags & 8) 2077 if (flags & 8)
2004 { 2078 {
2079 uint8_t ext, cmd;
2080
2005 if (extmap) 2081 do
2006 { 2082 {
2007 uint8_t ext, cmd; 2083 ext = *data++;
2084 cmd = ext & 0x7f;
2008 2085
2009 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
2010 { 2089 {
2011 ext = *data++;
2012 cmd = ext & 0x7f;
2013
2014 if (cmd < 4)
2015 cell->darkness = 255 - ext * 64 + 1; /* make sure this doesn't collide with FOW_DARKNESS */
2016 else if (cmd == 5) // health
2017 {
2018 cell->stat_width = 1; 2090 cell->stat_width = 1;
2019 cell->stat_hp = *data++; 2091 cell->stat_hp = *data++;
2020 }
2021 else if (cmd == 6) // monster width
2022 cell->stat_width = *data++ + 1;
2023 else if (cmd == 0x47)
2024 {
2025 if (*data == 1) cell->player = data [1];
2026 else if (*data == 2) cell->player = data [2] + (data [1] << 8);
2027 else if (*data == 3) cell->player = data [3] + (data [2] << 8) + (data [1] << 16);
2028 else if (*data == 4) cell->player = data [4] + (data [3] << 8) + (data [2] << 16) + (data [1] << 24);
2029
2030 data += *data + 1;
2031 }
2032 else if (cmd == 8) // cell flags
2033 cell->flags = *data++;
2034 else if (ext & 0x40) // unknown, multibyte => skip
2035 data += *data + 1;
2036 else
2037 data++;
2038 } 2092 }
2039 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++;
2040 } 2110 }
2041 else 2111 while (ext & 0x80);
2042 cell->darkness = *data++ + 1;
2043 } 2112 }
2044 2113
2045 for (z = 0; z <= 2; ++z) 2114 for (z = 0; z <= 2; ++z)
2046 if (flags & (4 >> z)) 2115 if (flags & (4 >> z))
2047 { 2116 {
2048 faceid face = (data [0] << 8) + data [1]; data += 2; 2117 faceid face = (data[0] << 8) + data[1]; data += 2;
2049 need_facenum (self, face); 2118 if (self->tile.size () <= face) self->tile.resize (face + 1);
2050 cell->tile [z] = self->face2tile [face]; 2119 cell->tile[z] = self->tile[face];
2051 2120
2052 if (cell->tile [z]) 2121 if (cell->tile[z])
2053 { 2122 {
2054 maptex *tex = self->tex + cell->tile [z]; 2123 maptex &tex = self->tex[cell->tile[z]];
2055 tex->unused = 0; 2124 tex.unused = 0;
2056 if (!tex->name) 2125 if (!tex.name)
2057 av_push (missing, newSViv (cell->tile [z])); 2126 av_push (missing, newSViv (cell->tile [z]));
2058 2127
2059 if (tex->smoothtile) 2128 if (tex.smoothtile)
2060 { 2129 {
2061 maptex *smooth = self->tex + tex->smoothtile; 2130 maptex &smooth = self->tex[tex.smoothtile];
2062 smooth->unused = 0; 2131 smooth.unused = 0;
2063 if (!smooth->name) 2132 if (!smooth.name)
2064 av_push (missing, newSViv (tex->smoothtile)); 2133 av_push (missing, newSViv (tex.smoothtile));
2065 } 2134 }
2066 } 2135 }
2067 } 2136 }
2068 } 2137 }
2069 else 2138 else
2095 ? self->row + y 2164 ? self->row + y
2096 : 0; 2165 : 0;
2097 2166
2098 for (x = x0; x < x1; x++) 2167 for (x = x0; x < x1; x++)
2099 { 2168 {
2100 int r = 32, g = 32, b = 32, a = 192; 2169 unsigned int r = 32, g = 32, b = 32, a = 192;
2101 2170
2102 if (row && row->c0 <= x && x < row->c1) 2171 if (row && row->c0 <= x && x < row->c1)
2103 { 2172 {
2104 mapcell *cell = row->col + (x - row->c0); 2173 mapcell *cell = row->col + (x - row->c0);
2105 2174
2107 { 2176 {
2108 maptex tex = self->tex [cell->tile [z]]; 2177 maptex tex = self->tex [cell->tile [z]];
2109 int a0 = 255 - tex.a; 2178 int a0 = 255 - tex.a;
2110 int a1 = tex.a; 2179 int a1 = tex.a;
2111 2180
2112 r = (r * a0 + tex.r * a1) / 255; 2181 r = div255 (r * a0 + tex.r * a1);
2113 g = (g * a0 + tex.g * a1) / 255; 2182 g = div255 (g * a0 + tex.g * a1);
2114 b = (b * a0 + tex.b * a1) / 255; 2183 b = div255 (b * a0 + tex.b * a1);
2115 a = (a * a0 + tex.a * a1) / 255; 2184 a = div255 (a * a0 + tex.a * a1);
2116 } 2185 }
2117 } 2186 }
2118 2187
2119 *map++ = (r ) 2188 *map++ = (r )
2120 | (g << 8) 2189 | (g << 8)
2121 | (b << 16) 2190 | (b << 16)
2122 | (a << 24); 2191 | (a << 24);
2123 } 2192 }
2124 } 2193 }
2125 2194
2126 RETVAL = map_sv; 2195 RETVAL = map_sv;
2127} 2196}
2128 OUTPUT: 2197 OUTPUT:
2129 RETVAL 2198 RETVAL
2130 2199
2131void 2200void
2132draw (DC::Map self, int mx, int my, int sw, int sh, int T, U32 player = 0xffffffff, int sdx = 0, int sdy = 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)
2133 CODE: 2202 CODE:
2134{ 2203{
2135 int x, y, z; 2204 int x, y, z;
2136 2205
2137 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
2138 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level
2139 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!
2140 smooth_key skey;
2141 int pl_x, pl_y; 2207 int pl_x, pl_y;
2142 maptex pl_tex; 2208 maptex pl_tex;
2143 rc_t *rc = rc_alloc (); 2209 rc_t rc;
2144 rc_t *rc_ov = rc_alloc (); 2210 rc_t rc_ov;
2145 rc_key_t key; 2211 rc_key_t key;
2146 rc_array_t *arr, *arr_hidden; 2212 rc_t::array_t *arr;
2147 2213
2148 pl_tex.name = 0; 2214 pl_tex.name = 0;
2149 2215
2150 // that's current max. sorry. 2216 // that's current max. sorry.
2151 if (sw > 255) sw = 255; 2217 if (sw > 255) sw = 255;
2152 if (sh > 255) sh = 255; 2218 if (sh > 255) sh = 255;
2153
2154 // clear key, in case of extra padding
2155 memset (&skey, 0, sizeof (skey));
2156 2219
2157 memset (&key, 0, sizeof (key)); 2220 memset (&key, 0, sizeof (key));
2158 key.r = 255; 2221 key.r = 255;
2159 key.g = 255; 2222 key.g = 255;
2160 key.b = 255; 2223 key.b = 255;
2166 my += self->y; 2229 my += self->y;
2167 2230
2168 // first pass: determine smooth_max 2231 // first pass: determine smooth_max
2169 // rather ugly, if you ask me 2232 // rather ugly, if you ask me
2170 // could also be stored inside mapcell and updated on change 2233 // could also be stored inside mapcell and updated on change
2171 memset (smooth_max, 0, sizeof (smooth_max)); 2234 memset (smooth_max, 0, sizeof (smooth_max[0]) * (sh + 1));
2172 2235
2173 for (y = 0; y < sh; y++) 2236 for (y = 0; y < sh; y++)
2174 if (0 <= y + my && y + my < self->rows) 2237 if (0 <= y + my && y + my < self->rows)
2175 { 2238 {
2176 maprow *row = self->row + (y + my); 2239 maprow *row = self->row + (y + my);
2189 2252
2190 glEnable (GL_BLEND); 2253 glEnable (GL_BLEND);
2191 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2254 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2192 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 2255 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
2193 2256
2194 key.texname = self->tex [TEXID_HIDDEN].name;
2195 arr_hidden = rc_array (rc_ov, &key);
2196
2197 for (z = 0; z <= 2; z++) 2257 for (z = 0; z <= 2; z++)
2198 { 2258 {
2199 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;
2200 key.texname = -1; 2262 key.texname = -1;
2201 2263
2202 for (y = 0; y < sh; y++) 2264 for (y = 0; y < sh; y++)
2203 if (0 <= y + my && y + my < self->rows) 2265 if (0 <= y + my && y + my < self->rows)
2204 { 2266 {
2221 2283
2222 if (!tex.name) 2284 if (!tex.name)
2223 tex = self->tex [TEXID_NOFACE]; /* missing, replace by noface */ 2285 tex = self->tex [TEXID_NOFACE]; /* missing, replace by noface */
2224 2286
2225 key.texname = tex.name; 2287 key.texname = tex.name;
2226 arr = rc_array (rc, &key); 2288 arr = &rc.array (key);
2227 } 2289 }
2228 2290
2229 px = (x + 1) * T - tex.w; 2291 px = (x + 1) * Th - tex.w;
2230 py = (y + 1) * T - tex.h; 2292 py = (y + 1) * Tw - tex.h;
2231 2293
2232 if (expect_false (cell->player == player) && expect_false (z == 2)) 2294 if (expect_false (cell->player == player) && expect_false (z == 2))
2233 { 2295 {
2234 pl_x = px; 2296 pl_x = px;
2235 pl_y = py; 2297 pl_y = py;
2236 pl_tex = tex; 2298 pl_tex = tex;
2237 continue; 2299 continue;
2238 } 2300 }
2239 2301
2240 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2302 arr->t2f_v3f (0 , 0 , px , py , 0);
2241 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0); 2303 arr->t2f_v3f (0 , tex.t, px , py + tex.h, 0);
2242 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);
2243 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0); 2305 arr->t2f_v3f (tex.s, 0 , px + tex.w, py , 0);
2244 2306
2245 // update smooth hash 2307 // update smooth hash
2246 if (tex.smoothtile) 2308 if (tex.smoothtile)
2247 { 2309 {
2248 skey.tile = tex.smoothtile; 2310 skey.tile = tex.smoothtile;
2249 skey.level = tex.smoothlevel; 2311 skey.level = tex.smoothlevel;
2250 2312
2251 smooth_level [tex.smoothlevel >> 5] |= ((uint32_t)1) << (tex.smoothlevel & 31); 2313 smooth_level[tex.smoothlevel] = 1;
2252 2314
2253 // 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
2254 // shifted +1|+1 so we always stay positive. 2316 // shifted +1|+1 so we always stay positive.
2255 2317
2256 // bits is ___n cccc CCCC bbbb 2318 // bits is ___n cccc CCCC bbbb
2264 2326
2265 // corners: 1 ┛· 2 ·┗ 4 ·· 8 ·· 2327 // corners: 1 ┛· 2 ·┗ 4 ·· 8 ··
2266 // ·· ·· ·┏ ┓· 2328 // ·· ·· ·┏ ┓·
2267 2329
2268 // full tile 2330 // full tile
2269 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);
2270 2332
2271 // borders 2333 // borders
2272 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);
2273 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);
2274 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);
2275 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);
2276 2338
2277 // corners 2339 // corners
2278 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);
2279 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);
2280 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);
2281 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);
2282 } 2344 }
2283 } 2345 }
2284 2346
2285 if (expect_false (z == 2) && expect_false (cell->flags)) 2347 if (expect_false (z == 2) && expect_false (cell->flags))
2286 { 2348 {
2287 // overlays such as the speech bubble, probably more to come 2349 // overlays such as the speech bubble, probably more to come
2288 if (cell->flags & 1) 2350 if (cell->flags & 1)
2289 { 2351 {
2290 rc_key_t key_ov = key; 2352 rc_key_t key_ov = key;
2291 maptex tex = self->tex [TEXID_SPEECH]; 2353 maptex tex = self->tex[TEXID_SPEECH];
2292 rc_array_t *arr;
2293 int px = x * T + T * 2 / 32; 2354 int px = x * Tw + Tw * 2 / 32;
2294 int py = y * T - T * 6 / 32; 2355 int py = y * Th - Th * 6 / 32;
2295 2356
2296 key_ov.texname = tex.name; 2357 key_ov.texname = tex.name;
2297 arr = rc_array (rc_ov, &key_ov); 2358 rc_t::array_t &arr = rc_ov.array (key_ov);
2298 2359
2299 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2360 arr.t2f_v3f (0 , 0 , px , py , 0);
2300 rc_t2f_v3f (arr, 0 , tex.t, px , py + T, 0); 2361 arr.t2f_v3f (0 , tex.t, px , py + Th, 0);
2301 rc_t2f_v3f (arr, tex.s, tex.t, px + T, py + T, 0); 2362 arr.t2f_v3f (tex.s, tex.t, px + Tw, py + Th, 0);
2302 rc_t2f_v3f (arr, tex.s, 0 , px + T, py , 0); 2363 arr.t2f_v3f (tex.s, 0 , px + Tw, py , 0);
2303 } 2364 }
2304 } 2365 }
2305 } 2366 }
2306 } 2367 }
2307 2368
2308 rc_draw (rc); 2369 rc.draw ();
2309 rc_clear (rc); 2370 rc.clear ();
2310 2371
2311 // go through all smoothlevels, lowest to highest, then draw. 2372 // go through all smoothlevels, lowest to highest, then draw.
2312 // this is basically counting sort 2373 // this is basically counting sort
2313 { 2374 {
2314 int w, b; 2375 int w, b;
2315 2376
2316 glEnable (GL_TEXTURE_2D); 2377 glEnable (GL_TEXTURE_2D);
2317 glBegin (GL_QUADS); 2378 glBegin (GL_QUADS);
2318 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)
2319 { 2382 {
2320 uint32_t smask = smooth_level [w]; 2383 smooth_key &skey = it->first;
2321 if (smask) 2384 IV bits = it->second;
2322 for (b = 0; b < 32; ++b) 2385
2323 if (smask & (((uint32_t)1) << b)) 2386 if (!(bits & 0x1000)
2387 && skey.level == level
2388 && level > smooth_max [skey.x][skey.y])
2324 { 2389 {
2325 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
2326 HE *he; 2398 if (tex.name)
2327
2328 hv_iterinit (smooth);
2329 while ((he = hv_iternext (smooth)))
2330 { 2399 {
2331 smooth_key *skey = (smooth_key *)HeKEY (he); 2400 // this time avoiding texture state changes
2332 IV bits = SvIVX (HeVAL (he)); 2401 // save gobs of state changes.
2333 2402 if (key.texname != tex.name)
2334 if (!(bits & 0x1000)
2335 && skey->level == level
2336 && level > smooth_max [skey->x][skey->y])
2337 { 2403 {
2338 maptex tex = self->tex [skey->tile];
2339 int px = (((int)skey->x) - 1) * T;
2340 int py = (((int)skey->y) - 1) * T;
2341 int border = bits & 15;
2342 int corner = (bits >> 8) & ~(bits >> 4) & 15;
2343 float dx = tex.s * .0625f; // 16 images/row
2344 float dy = tex.t * .5f ; // 2 images/column
2345
2346 if (tex.name)
2347 {
2348 // this time avoiding texture state changes
2349 // save gobs of state changes.
2350 if (key.texname != tex.name)
2351 {
2352 self->tex [skey->tile].unused = 0; 2404 self->tex [skey.tile].unused = 0;
2353 2405
2354 glEnd (); 2406 glEnd ();
2355 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name); 2407 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name);
2356 glBegin (GL_QUADS); 2408 glBegin (GL_QUADS);
2357 } 2409 }
2358 2410
2359 if (border) 2411 if (border)
2360 { 2412 {
2361 float ox = border * dx; 2413 float ox = border * dx;
2362 2414
2363 glTexCoord2f (ox , 0.f ); glVertex2i (px , py ); 2415 glTexCoord2f (ox , 0.f ); glVertex2i (px , py );
2364 glTexCoord2f (ox , dy ); glVertex2i (px , py + T); 2416 glTexCoord2f (ox , dy ); glVertex2i (px , py + Th);
2365 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py + T); 2417 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py + Th);
2366 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + T, py ); 2418 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + Tw, py );
2367 } 2419 }
2368 2420
2369 if (corner) 2421 if (corner)
2370 { 2422 {
2371 float ox = corner * dx; 2423 float ox = corner * dx;
2372 2424
2373 glTexCoord2f (ox , dy ); glVertex2i (px , py ); 2425 glTexCoord2f (ox , dy ); glVertex2i (px , py );
2374 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + T); 2426 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + Th);
2375 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + T, py + T); 2427 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + Tw, py + Th);
2376 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py ); 2428 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py );
2377 }
2378 }
2379 } 2429 }
2380 } 2430 }
2381 } 2431 }
2382 } 2432 }
2383 2433
2384 glEnd (); 2434 glEnd ();
2385 glDisable (GL_TEXTURE_2D); 2435 glDisable (GL_TEXTURE_2D);
2386 key.texname = -1; 2436 key.texname = -1;
2387 } 2437 }
2388
2389 hv_clear (smooth);
2390 } 2438 }
2391 2439
2392 if (pl_tex.name) 2440 if (pl_tex.name)
2393 { 2441 {
2394 maptex tex = pl_tex; 2442 maptex tex = pl_tex;
2395 int px = pl_x + sdx; 2443 int px = pl_x + sdx;
2396 int py = pl_y + sdy; 2444 int py = pl_y + sdy;
2397 2445
2398 key.texname = tex.name; 2446 key.texname = tex.name;
2399 arr = rc_array (rc, &key); 2447 rc_t::array_t &arr = rc.array (key);
2400 2448
2401 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2449 arr.t2f_v3f (0 , 0 , px , py , 0);
2402 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0); 2450 arr.t2f_v3f (0 , tex.t, px , py + tex.h, 0);
2403 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);
2404 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0); 2452 arr.t2f_v3f (tex.s, 0 , px + tex.w, py , 0);
2405 2453
2406 rc_draw (rc); 2454 rc.draw ();
2407 } 2455 }
2408 2456
2409 rc_draw (rc_ov); 2457 rc_ov.draw ();
2410 rc_clear (rc_ov); 2458 rc_ov.clear ();
2411 2459
2412 glDisable (GL_BLEND); 2460 glDisable (GL_BLEND);
2413 rc_free (rc);
2414 rc_free (rc_ov);
2415 2461
2416 // top layer: overlays such as the health bar 2462 // top layer: overlays such as the health bar
2417 for (y = 0; y < sh; y++) 2463 for (y = 0; y < sh; y++)
2418 if (0 <= y + my && y + my < self->rows) 2464 if (0 <= y + my && y + my < self->rows)
2419 { 2465 {
2422 for (x = 0; x < sw; x++) 2468 for (x = 0; x < sw; x++)
2423 if (row->c0 <= x + mx && x + mx < row->c1) 2469 if (row->c0 <= x + mx && x + mx < row->c1)
2424 { 2470 {
2425 mapcell *cell = row->col + (x + mx - row->c0); 2471 mapcell *cell = row->col + (x + mx - row->c0);
2426 2472
2427 int px = x * T; 2473 int px = x * Tw;
2428 int py = y * T; 2474 int py = y * Th;
2429 2475
2430 if (expect_false (cell->player == player)) 2476 if (expect_false (cell->player == player))
2431 { 2477 {
2432 px += sdx; 2478 px += sdx;
2433 py += sdy; 2479 py += sdy;
2434 } 2480 }
2435 2481
2436 if (cell->stat_hp) 2482 if (cell->stat_hp)
2437 { 2483 {
2438 int width = cell->stat_width * T; 2484 int width = cell->stat_width * Tw;
2439 int thick = (sh * T / 32 + 27) / 28 + 1 + cell->stat_width; 2485 int thick = (sh * Th / 32 + 27) / 28 + 1 + cell->stat_width;
2440 2486
2441 glColor3ub (0, 0, 0); 2487 glColor3ub (0, 0, 0);
2442 glRectf (px + 1, py - thick - 2, 2488 glRectf (px + 1, py - thick - 2,
2443 px + width - 1, py); 2489 px + width - 1, py);
2444 2490
2524 int x, y; 2570 int x, y;
2525 int sw1 = sw + 2; 2571 int sw1 = sw + 2;
2526 int sh1 = sh + 2; 2572 int sh1 = sh + 2;
2527 int sh3 = sh * 3; 2573 int sh3 = sh * 3;
2528 int sw3 = sw * 3; 2574 int sw3 = sw * 3;
2529 uint8_t *darkness1 = (uint8_t *)malloc (sw1 * sh1);
2530 SV *darkness3_sv = sv_2mortal (newSV (sw3 * sh3)); 2575 SV *darkness3_sv = sv_2mortal (newSV (sw3 * sh3));
2531 uint8_t *darkness3 = (uint8_t *)SvPVX (darkness3_sv); 2576 uint8_t *darkness3 = (uint8_t *)SvPVX (darkness3_sv);
2577 uint8_t *darkness1 = (uint8_t *)malloc (sw1 * sh1);
2578 memset (darkness1, 0, sw1*sh1);
2532 2579
2533 SvPOK_only (darkness3_sv); 2580 SvPOK_only (darkness3_sv);
2534 SvCUR_set (darkness3_sv, sw3 * sh3); 2581 SvCUR_set (darkness3_sv, sw3 * sh3);
2535 2582
2536 mx += self->x - 1; 2583 mx += self->x - 1;
2662 else 2709 else
2663 *data++ = 0; 2710 *data++ = 0;
2664 } 2711 }
2665 } 2712 }
2666 2713
2667 /* 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 */
2668 if (data - (uint8_t *)SvPVX (data_sv) != w * h + 5) 2715 if (data - (uint8_t *)SvPVX (data_sv) != w * h + 5)
2669 { 2716 {
2670 SvPOK_only (data_sv); 2717 SvPOK_only (data_sv);
2671 SvCUR_set (data_sv, data - (uint8_t *)SvPVX (data_sv)); 2718 SvCUR_set (data_sv, data - (uint8_t *)SvPVX (data_sv));
2672 } 2719 }
2673 2720
2674 RETVAL = data_sv; 2721 RETVAL = data_sv;
2675} 2722}
2676 OUTPUT: 2723 OUTPUT:
2677 RETVAL 2724 RETVAL
2678 2725
2679void 2726void
2686 STRLEN len; 2733 STRLEN len;
2687 uint8_t *data, *end; 2734 uint8_t *data, *end;
2688 2735
2689 len = SvLEN (data_sv); 2736 len = SvLEN (data_sv);
2690 SvGROW (data_sv, len + 8); // reserve at least 7+ bytes more 2737 SvGROW (data_sv, len + 8); // reserve at least 7+ bytes more
2691 data = SvPVbyte_nolen (data_sv); 2738 data = (uint8_t *)SvPVbyte_nolen (data_sv);
2692 end = data + len + 8; 2739 end = data + len + 8;
2693 2740
2694 if (len < 5) 2741 if (len < 5)
2695 XSRETURN_EMPTY; 2742 XSRETURN_EMPTY;
2696 2743
2740 2787
2741 for (z = 0; z <= 2; z++) 2788 for (z = 0; z <= 2; z++)
2742 { 2789 {
2743 tileid t = tile [z]; 2790 tileid t = tile [z];
2744 2791
2745 if (t >= self->texs || (t && !self->tex [t].name)) 2792 if (t >= self->tex.size () || (t && !self->tex[t].name))
2746 { 2793 {
2747 PUSHs (sv_2mortal (newSViv (t))); 2794 PUSHs (sv_2mortal (newSViv (t)));
2748 need_texid (self, t); 2795 if (self->tex.size () <= t) self->tex.resize (t + 1);
2749 } 2796 }
2750 2797
2751 cell->tile [z] = t; 2798 cell->tile[z] = t;
2752 } 2799 }
2753 } 2800 }
2754 } 2801 }
2755 } 2802 }
2756 } 2803 }
2757} 2804}
2758 2805
2759MODULE = Deliantra::Client PACKAGE = DC::RW 2806MODULE = Deliantra::Client PACKAGE = DC::RW
2760 2807
2761DC::RW 2808DC::RW
2762new (SV *class, SV *data_sv) 2809new (SV *klass, SV *data_sv)
2763 CODE: 2810 CODE:
2764{ 2811{
2765 STRLEN datalen; 2812 STRLEN datalen;
2766 char *data = SvPVbyte (data_sv, datalen); 2813 char *data = SvPVbyte (data_sv, datalen);
2767 2814
2769} 2816}
2770 OUTPUT: 2817 OUTPUT:
2771 RETVAL 2818 RETVAL
2772 2819
2773DC::RW 2820DC::RW
2774new_from_file (SV *class, const char *path, const char *mode = "rb") 2821new_from_file (SV *klass, const char *path, const char *mode = "rb")
2775 CODE: 2822 CODE:
2776 RETVAL = SDL_RWFromFile (path, mode); 2823 RETVAL = SDL_RWFromFile (path, mode);
2777 OUTPUT: 2824 OUTPUT:
2778 RETVAL 2825 RETVAL
2779 2826
2797 if (RETVAL < 0) 2844 if (RETVAL < 0)
2798 { 2845 {
2799 RETVAL = Mix_GroupOldest (-1); 2846 RETVAL = Mix_GroupOldest (-1);
2800 2847
2801 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)
2802 XSRETURN_UNDEF; 2854 XSRETURN_UNDEF;
2803 2855 }
2856 else
2804 Mix_HaltChannel (RETVAL); 2857 Mix_HaltChannel (RETVAL);
2805 } 2858 }
2806 2859
2807 Mix_UnregisterAllEffects (RETVAL); 2860 Mix_UnregisterAllEffects (RETVAL);
2808 Mix_Volume (RETVAL, 128); 2861 Mix_Volume (RETVAL, 128);
2809} 2862}
2869 2922
2870MODULE = Deliantra::Client PACKAGE = DC::MixChunk 2923MODULE = Deliantra::Client PACKAGE = DC::MixChunk
2871 2924
2872PROTOTYPES: DISABLE 2925PROTOTYPES: DISABLE
2873 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
2874DC::MixChunk 2939DC::MixChunk
2875new (SV *class, DC::RW rwops) 2940new (SV *klass, DC::RW rwops)
2876 CODE: 2941 CODE:
2877 RETVAL = Mix_LoadWAV_RW (rwops, 1); 2942 RETVAL = Mix_LoadWAV_RW (rwops, 1);
2878 OUTPUT: 2943 OUTPUT:
2879 RETVAL 2944 RETVAL
2880 2945
2910 OUTPUT: 2975 OUTPUT:
2911 RETVAL 2976 RETVAL
2912 2977
2913MODULE = Deliantra::Client PACKAGE = DC::MixMusic 2978MODULE = Deliantra::Client PACKAGE = DC::MixMusic
2914 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
2915int 2992int
2916volume (int volume = -1) 2993volume (int volume = -1)
2917 PROTOTYPE: ;$ 2994 PROTOTYPE: ;$
2918 CODE: 2995 CODE:
2919 if (items > 0) 2996 if (items > 0)
2930void 3007void
2931halt () 3008halt ()
2932 CODE: 3009 CODE:
2933 Mix_HaltMusic (); 3010 Mix_HaltMusic ();
2934 3011
3012int
3013playing ()
3014 CODE:
3015 RETVAL = Mix_PlayingMusic ();
3016 OUTPUT:
3017 RETVAL
3018
2935DC::MixMusic 3019DC::MixMusic
2936new (SV *class, DC::RW rwops) 3020new (SV *klass, DC::RW rwops)
2937 CODE: 3021 CODE:
2938 RETVAL = Mix_LoadMUS_RW (rwops); 3022 RETVAL = Mix_LoadMUS_RW (rwops);
2939 OUTPUT: 3023 OUTPUT:
2940 RETVAL 3024 RETVAL
2941 3025
3078 const_iv (GL_FUNC_SUBTRACT), 3162 const_iv (GL_FUNC_SUBTRACT),
3079 const_iv (GL_FUNC_REVERSE_SUBTRACT), 3163 const_iv (GL_FUNC_REVERSE_SUBTRACT),
3080# undef const_iv 3164# undef const_iv
3081 }; 3165 };
3082 3166
3083 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--)
3084 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 3168 newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
3085 3169
3086 texture_av = newAV (); 3170 texture_av = newAV ();
3087 AvREAL_off (texture_av); 3171 AvREAL_off (texture_av);
3088} 3172}
3089 3173
3094 gl.BlendFuncSeparateEXT = 0; 3178 gl.BlendFuncSeparateEXT = 0;
3095 3179
3096void 3180void
3097apple_nvidia_bug (int enable) 3181apple_nvidia_bug (int enable)
3098 3182
3099char * 3183const char *
3100gl_vendor () 3184gl_vendor ()
3101 CODE: 3185 CODE:
3102 RETVAL = (char *)glGetString (GL_VENDOR); 3186 RETVAL = (const char *)glGetString (GL_VENDOR);
3103 OUTPUT: 3187 OUTPUT:
3104 RETVAL 3188 RETVAL
3105 3189
3106char * 3190const char *
3107gl_version () 3191gl_version ()
3108 CODE: 3192 CODE:
3109 RETVAL = (char *)glGetString (GL_VERSION); 3193 RETVAL = (const char *)glGetString (GL_VERSION);
3110 OUTPUT: 3194 OUTPUT:
3111 RETVAL 3195 RETVAL
3112 3196
3113char * 3197const char *
3114gl_extensions () 3198gl_extensions ()
3115 CODE: 3199 CODE:
3116 RETVAL = (char *)glGetString (GL_EXTENSIONS); 3200 RETVAL = (const char *)glGetString (GL_EXTENSIONS);
3117 OUTPUT: 3201 OUTPUT:
3118 RETVAL 3202 RETVAL
3119 3203
3120const char *glGetString (GLenum pname) 3204const char *glGetString (GLenum pname)
3205 CODE:
3206 RETVAL = (const char *)glGetString (pname);
3207 OUTPUT:
3208 RETVAL
3121 3209
3122GLint glGetInteger (GLenum pname) 3210GLint glGetInteger (GLenum pname)
3123 CODE: 3211 CODE:
3124 glGetIntegerv (pname, &RETVAL); 3212 glGetIntegerv (pname, &RETVAL);
3125 OUTPUT: 3213 OUTPUT:
3132 RETVAL 3220 RETVAL
3133 3221
3134int glGetError () 3222int glGetError ()
3135 3223
3136void glFinish () 3224void glFinish ()
3225
3226void glFlush ()
3137 3227
3138void glClear (int mask) 3228void glClear (int mask)
3139 3229
3140void glClearColor (float r, float g, float b, float a = 1.0) 3230void glClearColor (float r, float g, float b, float a = 1.0)
3141 PROTOTYPE: @ 3231 PROTOTYPE: @
3326 3416
3327void 3417void
3328find_widget (SV *self, NV x, NV y) 3418find_widget (SV *self, NV x, NV y)
3329 PPCODE: 3419 PPCODE:
3330{ 3420{
3331 if (within_widget (self, x, y)) 3421 if (within_widget (self, x, y))
3332 XPUSHs (self); 3422 XPUSHs (self);
3333} 3423}
3334 3424
3335BOOT: 3425BOOT:
3336{ 3426{
3344 3434
3345void 3435void
3346draw (SV *self) 3436draw (SV *self)
3347 CODE: 3437 CODE:
3348{ 3438{
3349 HV *hv; 3439 HV *hv;
3350 SV **svp; 3440 SV **svp;
3351 NV x, y, w, h; 3441 NV x, y, w, h;
3352 SV *draw_x_sv = GvSV (draw_x_gv); 3442 SV *draw_x_sv = GvSV (draw_x_gv);
3353 SV *draw_y_sv = GvSV (draw_y_gv); 3443 SV *draw_y_sv = GvSV (draw_y_gv);
3354 SV *draw_w_sv = GvSV (draw_w_gv); 3444 SV *draw_w_sv = GvSV (draw_w_gv);
3355 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