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