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.333 by root, Mon Nov 19 01:23:01 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
69# include <netinet/in.h> 76# include <netinet/in.h>
70# include <netinet/tcp.h> 77# include <netinet/tcp.h>
71# include <inttypes.h> 78# include <inttypes.h>
72#endif 79#endif
73 80
74#if __GNUC__ >= 4 81#include "ecb.h"
75# define expect(expr,value) __builtin_expect ((expr),(value)) 82#include "salloc.h"
76#else
77# define expect(expr,value) (expr)
78#endif
79
80#define expect_false(expr) expect ((expr) != 0, 0)
81#define expect_true(expr) expect ((expr) != 0, 1)
82 83
83#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, object replacement character */ 84#define OBJ_STR "\xef\xbf\xbc" /* U+FFFC, object replacement character */
84 85
85/* this is used as fow flag as well, so has to have a different value */ 86/* this is used as fow flag as well, so has to have a different value */
86/* then anything that is computed by incoming darkness */ 87/* then anything that is computed by incoming darkness */
97 98
98#define KMOD_LRAM 0x10000 // our extension 99#define KMOD_LRAM 0x10000 // our extension
99 100
100#define TEXID_SPEECH 1 101#define TEXID_SPEECH 1
101#define TEXID_NOFACE 2 102#define TEXID_NOFACE 2
103
104static char *
105fast_sv_grow (SV *sv, STRLEN need)
106{
107 STRLEN len = SvLEN (sv);
108 STRLEN want = SvCUR (sv) + need;
109
110 if (ecb_expect_false (len < want))
111 {
112 do
113 len *= 2;
114 while (len < want);
115
116 sv_grow (sv, len);
117 }
118
119 SvCUR_set (sv, want);
120 return SvEND (sv) - need;
121}
102 122
103static AV *texture_av; 123static AV *texture_av;
104 124
105static struct 125static struct
106{ 126{
163{ 183{
164 GSList *attrs = run->item->analysis.extra_attrs; 184 GSList *attrs = run->item->analysis.extra_attrs;
165 185
166 while (attrs) 186 while (attrs)
167 { 187 {
168 PangoAttribute *attr = attrs->data; 188 PangoAttribute *attr = (PangoAttribute *)attrs->data;
169 189
170 if (attr->klass->type == PANGO_ATTR_SHAPE) 190 if (attr->klass->type == PANGO_ATTR_SHAPE)
171 return 1; 191 return 1;
172 192
173 attrs = attrs->next; 193 attrs = attrs->next;
174 } 194 }
175 195
176 return 0; 196 return 0;
177} 197}
178 198
179typedef struct cf_layout { 199struct cf_layout {
180 PangoLayout *pl; 200 PangoLayout *pl;
181 float r, g, b, a; // default color for rgba mode 201 float r, g, b, a; // default color for rgba mode
182 int base_height; 202 int base_height;
183 DC__Font font; 203 DC__Font font;
184 rc_t *rc; 204 rc_t rc;
185} *DC__Layout; 205};
206
207typedef cf_layout *DC__Layout;
186 208
187static DC__Font default_font; 209static DC__Font default_font;
188static PangoContext *opengl_context; 210static PangoContext *opengl_context;
189static PangoFontMap *opengl_fontmap; 211static PangoFontMap *opengl_fontmap;
190 212
191static void 213static void
192substitute_func (FcPattern *pattern, gpointer data) 214substitute_func (FcPattern *pattern, gpointer data)
193{ 215{
194 FcPatternAddBool (pattern, FC_HINTING, 1); 216 FcPatternAddBool (pattern, FC_HINTING, 1);
195#ifdef FC_HINT_STYLE 217#ifdef FC_HINT_STYLE
196 FcPatternAddBool (pattern, FC_HINT_STYLE, FC_HINT_FULL); 218 FcPatternAddInteger (pattern, FC_HINT_STYLE, FC_HINT_FULL);
197#endif 219#endif
198 FcPatternAddBool (pattern, FC_AUTOHINT, 0); 220 FcPatternAddBool (pattern, FC_AUTOHINT, 0);
199} 221}
200 222
201static void 223static void
228 250
229 *w = rect.width; 251 *w = rect.width;
230 *h = rect.height; 252 *h = rect.height;
231} 253}
232 254
255/////////////////////////////////////////////////////////////////////////////
256
233typedef uint16_t tileid; 257typedef uint16_t tileid;
234typedef uint16_t faceid; 258typedef uint16_t faceid;
235 259
236typedef struct { 260struct maptex
261{
237 GLuint name; 262 GLuint name;
238 int w, h; 263 int w, h;
239 float s, t; 264 float s, t;
240 uint8_t r, g, b, a; 265 uint8_t r, g, b, a;
241 tileid smoothtile; 266 tileid smoothtile;
242 uint8_t smoothlevel; 267 uint8_t smoothlevel;
243 uint8_t unused; /* set to zero on use */ 268 uint8_t unused; /* set to zero on use */
244} maptex; 269};
245 270
246typedef struct { 271struct mapcell
272{
247 uint32_t player; 273 uint32_t player;
248 tileid tile[3]; 274 tileid tile[3];
249 uint16_t darkness; 275 uint16_t darkness;
250 uint8_t stat_width, stat_hp, flags, smoothmax; 276 uint8_t stat_width, stat_hp, flags, smoothmax;
251} mapcell; 277};
252 278
253typedef struct { 279struct maprow
280{
254 int32_t c0, c1; 281 int32_t c0, c1;
255 mapcell *col; 282 mapcell *col;
256} maprow; 283};
257 284
258typedef struct map { 285struct mapgrid {
259 int x, y, w, h; 286 int x, y, w, h;
260 int ox, oy; /* offset to virtual global coordinate system */ 287 int ox, oy; /* offset to virtual global coordinate system */
261 int faces; tileid *face2tile; // [faceid] 288 int faces; tileid *face2tile; // [faceid]
262 int texs; maptex *tex; // [tileid] 289 int texs; maptex *tex; // [tileid]
263 290
264 int32_t rows; 291 int32_t rows;
265 maprow *row; 292 maprow *row;
266} *DC__Map; 293};
267 294
268static char * 295typedef mapgrid *DC__Map;
296
297template<typename T>
298static void
269prepend (char *ptr, int sze, int inc) 299prepend (T *&ptr, int sze, int inc)
270{ 300{
271 char *p; 301 T *p;
272 302
273 New (0, p, sze + inc, char); 303 Newx (p, inc + sze, T);
274 Zero (p, inc, char); 304 Zero (p, inc, T);
275 Move (ptr, p + inc, sze, char); 305 Move (ptr, p + inc, sze, T);
276 Safefree (ptr); 306 Safefree (ptr);
277 307
278 return p; 308 ptr = p;
279} 309}
280 310
281static char * 311template<typename T>
282append (char *ptr, int sze, int inc)
283{
284 Renew (ptr, sze + inc, char);
285 Zero (ptr + sze, inc, char);
286
287 return ptr;
288}
289
290#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))
292
293static void 312static void
313append (T *&ptr, int sze, int inc)
314{
315 Renew (ptr, sze + inc, T);
316 Zero (ptr + sze, inc, T);
317}
318
319static void
294need_facenum (struct map *self, faceid face) 320need_facenum (struct mapgrid *self, faceid face)
295{ 321{
296 while (self->faces <= face) 322 while (self->faces <= face)
297 { 323 {
298 Append (tileid, self->face2tile, self->faces, self->faces); 324 append (self->face2tile, self->faces, self->faces);
299 self->faces *= 2; 325 self->faces *= 2;
300 } 326 }
301} 327}
302 328
303static void 329static void
304need_texid (struct map *self, int texid) 330need_texid (struct mapgrid *self, int texid)
305{ 331{
306 while (self->texs <= texid) 332 while (self->texs <= texid)
307 { 333 {
308 Append (maptex, self->tex, self->texs, self->texs); 334 append (self->tex, self->texs, self->texs);
309 self->texs *= 2; 335 self->texs *= 2;
310 } 336 }
311} 337}
312 338
313static maprow * 339static maprow *
314map_get_row (DC__Map self, int y) 340map_get_row (mapgrid *self, int y)
315{ 341{
316 if (0 > y) 342 if (0 > y)
317 { 343 {
318 int extend = - y + MAP_EXTEND_Y; 344 int extend = - y + MAP_EXTEND_Y;
319 Prepend (maprow, self->row, self->rows, extend); 345 prepend (self->row, self->rows, extend);
320 346
321 self->rows += extend; 347 self->rows += extend;
322 self->y += extend; 348 self->y += extend;
323 y += extend; 349 y += extend;
324 } 350 }
325 else if (y >= self->rows) 351 else if (y >= self->rows)
326 { 352 {
327 int extend = y - self->rows + MAP_EXTEND_Y; 353 int extend = y - self->rows + MAP_EXTEND_Y;
328 Append (maprow, self->row, self->rows, extend); 354 append (self->row, self->rows, extend);
329 self->rows += extend; 355 self->rows += extend;
330 } 356 }
331 357
332 return self->row + y; 358 return self->row + y;
333} 359}
343 } 369 }
344 370
345 if (row->c0 > x) 371 if (row->c0 > x)
346 { 372 {
347 int extend = row->c0 - x + MAP_EXTEND_X; 373 int extend = row->c0 - x + MAP_EXTEND_X;
348 Prepend (mapcell, row->col, row->c1 - row->c0, extend); 374 prepend (row->col, row->c1 - row->c0, extend);
349 row->c0 -= extend; 375 row->c0 -= extend;
350 } 376 }
351 else if (x >= row->c1) 377 else if (x >= row->c1)
352 { 378 {
353 int extend = x - row->c1 + MAP_EXTEND_X; 379 int extend = x - row->c1 + MAP_EXTEND_X;
354 Append (mapcell, row->col, row->c1 - row->c0, extend); 380 append (row->col, row->c1 - row->c0, extend);
355 row->c1 += extend; 381 row->c1 += extend;
356 } 382 }
357 383
358 return row->col + (x - row->c0); 384 return row->col + (x - row->c0);
359} 385}
360 386
361static mapcell * 387static mapcell *
362map_get_cell (DC__Map self, int x, int y) 388map_get_cell (mapgrid *self, int x, int y)
363{ 389{
364 return row_get_cell (map_get_row (self, y), x); 390 return row_get_cell (map_get_row (self, y), x);
365} 391}
366 392
367static void 393static void
368map_clear (DC__Map self) 394map_clear (mapgrid *self)
369{ 395{
370 int r; 396 int r;
371 397
372 for (r = 0; r < self->rows; r++) 398 for (r = 0; r < self->rows; r++)
373 Safefree (self->row[r].col); 399 Safefree (self->row[r].col);
391 (cell)->flags = 0; \ 417 (cell)->flags = 0; \
392 (cell)->player = 0; \ 418 (cell)->player = 0; \
393 } while (0) 419 } while (0)
394 420
395static void 421static void
396map_blank (DC__Map self, int x0, int y0, int w, int h) 422map_blank (mapgrid *self, int x0, int y0, int w, int h)
397{ 423{
398 int x, y; 424 int x, y;
399 maprow *row; 425 maprow *row;
400 mapcell *cell; 426 mapcell *cell;
401 427
418 CELL_CLEAR (cell); 444 CELL_CLEAR (cell);
419 } 445 }
420 } 446 }
421} 447}
422 448
423typedef struct { 449struct smooth_key
450{
424 tileid tile; 451 tileid tile;
425 uint8_t x, y, level; 452 uint8_t x, y, level;
426} smooth_key; 453
454 bool operator == (const smooth_key &o) const
455 {
456 return tile == o.tile && x == o.x && y == o.y && level == o.level;
457 }
458};
459
460typedef ska::flat_hash_map<smooth_key, IV> smooth_hash;
461
462namespace std {
463 template <>
464 struct hash<smooth_key>
465 {
466 size_t operator () (const smooth_key &v) const
467 {
468 return v.tile + (v.x << 8) + (v.y << 16) + (v.level << 24);
469 }
470 };
471}
427 472
428static void 473static void
429smooth_or_bits (HV *hv, smooth_key *key, IV bits) 474smooth_or_bits (smooth_hash &h, smooth_key &key, IV bits)
430{ 475{
431 SV **sv = hv_fetch (hv, (char *)key, sizeof (*key), 1); 476 auto &&it = h.find (key);
432 477
433 if (SvIOK (*sv)) 478 if (it == h.end ())
434 SvIV_set (*sv, SvIVX (*sv) | bits); 479 h.insert (std::make_pair (key, bits));
435 else 480 else
436 sv_setiv (*sv, bits); 481 it->second |= bits;
437} 482}
438 483
439static void 484static void
440music_finished (void) 485music_finished (void)
441{ 486{
458 ev.code = 1; 503 ev.code = 1;
459 ev.data1 = (void *)(long)channel; 504 ev.data1 = (void *)(long)channel;
460 ev.data2 = 0; 505 ev.data2 = 0;
461 506
462 SDL_PushEvent ((SDL_Event *)&ev); 507 SDL_PushEvent ((SDL_Event *)&ev);
508}
509
510// approximately divide by 255
511static unsigned int
512div255 (unsigned int n)
513{
514 return (n + (n >> 8)) >> 8;
463} 515}
464 516
465static unsigned int 517static unsigned int
466minpot (unsigned int n) 518minpot (unsigned int n)
467{ 519{
477 n |= n >> 16; 529 n |= n >> 16;
478 530
479 return n + 1; 531 return n + 1;
480} 532}
481 533
482static unsigned int
483popcount (unsigned int n)
484{
485 n -= (n >> 1) & 0x55555555U;
486 n = ((n >> 2) & 0x33333333U) + (n & 0x33333333U);
487 n = ((n >> 4) + n) & 0x0f0f0f0fU;
488 n *= 0x01010101U;
489
490 return n >> 24;
491}
492
493/* SDL should provide this, really. */ 534/* SDL should provide this, really. */
494#define SDLK_MODIFIER_MIN 300 535#define SDLK_MODIFIER_MIN 300
495#define SDLK_MODIFIER_MAX 314 536#define SDLK_MODIFIER_MAX 314
496 537
497/******************************************************************************/ 538/******************************************************************************/
550 591
551 return mod; 592 return mod;
552} 593}
553 594
554static void 595static void
555deliantra_main () 596deliantra_main (SV *real_main)
556{ 597{
557 char *argv[] = { 0 }; 598 dSP;
558 call_argv ("::main", G_DISCARD | G_VOID, argv); 599
600 PUSHMARK (SP);
601 call_sv (real_main, G_DISCARD | G_VOID);
559} 602}
560 603
561#ifdef __MACOSX__ 604#ifdef __MACOSX__
605 static SV *real_main;
606
562 /* to due surprising braindamage on the side of SDL design, we 607 /* to due surprising braindamage on the side of SDL design, we
563 * do some mind-boggling hack here: SDL requires a custom main() 608 * 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, 609 * 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, 610 * due to shared library magic, calls -lSDLmain's main, not perl's main,
566 * and which calls our main (== SDL_main) back. 611 * and which calls our main (== SDL_main) back.
567 */ 612 */
568 extern C_LINKAGE int 613 extern C_LINKAGE int
569 main (int argc, char *argv[]) 614 main (int argc, char *argv[])
570 { 615 {
571 deliantra_main (); 616 deliantra_main (real_main);
572 } 617 }
573 618
574 #undef main 619 #undef main
575 620
576 extern C_LINKAGE int main (int argc, char *argv[]); 621 extern C_LINKAGE int main (int argc, char *argv[]);
577 622
578 static void 623 static void
579 SDL_braino (void) 624 SDL_main_hack (SV *real_main_)
580 { 625 {
626 real_main = real_main_;
627
581 char *argv[] = { "deliantra client", 0 }; 628 char *argv[] = { "deliantra client", 0 };
582 (main) (1, argv); 629 (main) (1, argv);
583 } 630 }
584#else 631#else
585 static void 632 static void
586 SDL_braino (void) 633 SDL_main_hack (SV *real_main)
587 { 634 {
588 deliantra_main (); 635 deliantra_main (real_main);
589 } 636 }
590#endif 637#endif
591 638
592MODULE = Deliantra::Client PACKAGE = DC 639MODULE = Deliantra::Client PACKAGE = DC
593 640
794 841
795 const_iv (FOW_DARKNESS) 842 const_iv (FOW_DARKNESS)
796# undef const_iv 843# undef const_iv
797 }; 844 };
798 845
799 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 846 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
800 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 847 newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
801 848
802 assert (SDLK_MODIFIER_MIN == SDLK_NUMLOCK); 849 assert (SDLK_MODIFIER_MIN == SDLK_NUMLOCK);
803 assert (SDLK_MODIFIER_MAX == SDLK_COMPOSE); 850 assert (SDLK_MODIFIER_MAX == SDLK_COMPOSE);
804} 851}
805 852
820 867
821NV ceil (NV x) 868NV ceil (NV x)
822 869
823IV minpot (UV n) 870IV minpot (UV n)
824 871
872UV ld32 (UV n)
873 CODE:
874 RETVAL = ecb_ld32 (n);
875 OUTPUT:
876 RETVAL
877
825IV popcount (UV n) 878IV popcount (UV n)
879 CODE:
880 RETVAL = ecb_popcount32 (n);
881 OUTPUT:
882 RETVAL
826 883
827NV distance (NV dx, NV dy) 884NV distance (NV dx, NV dy)
828 CODE: 885 CODE:
829 RETVAL = pow (dx * dx + dy * dy, 0.5); 886 RETVAL = pow (dx * dx + dy * dy, 0.5);
830 OUTPUT: 887 OUTPUT:
844#endif 901#endif
845} 902}
846 903
847char *SDL_GetError () 904char *SDL_GetError ()
848 905
849void SDL_braino () 906void SDL_main_hack (SV *real_main)
907 PROTOTYPE: &
850 908
851int SDL_Init (U32 flags) 909int SDL_Init (U32 flags)
852 910
853int SDL_InitSubSystem (U32 flags) 911int SDL_InitSubSystem (U32 flags)
854 912
855void SDL_QuitSubSystem (U32 flags) 913void SDL_QuitSubSystem (U32 flags)
856 914
857void SDL_Quit () 915void SDL_Quit ()
858 916
859int SDL_GL_SetAttribute (int attr, int value) 917int SDL_GL_SetAttribute (int attr, int value)
918 C_ARGS: (SDL_GLattr)attr, value
860 919
861int SDL_GL_GetAttribute (int attr) 920int SDL_GL_GetAttribute (int attr)
862 CODE: 921 CODE:
863 if (SDL_GL_GetAttribute (attr, &RETVAL)) 922 if (SDL_GL_GetAttribute ((SDL_GLattr)attr, &RETVAL))
864 XSRETURN_UNDEF; 923 XSRETURN_UNDEF;
865 OUTPUT: 924 OUTPUT:
866 RETVAL 925 RETVAL
867 926
868void 927void
923 ); 982 );
924 983
925 if (RETVAL) 984 if (RETVAL)
926 { 985 {
927 av_clear (texture_av); 986 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); 987#define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name);
931#include "glfunc.h" 988#include "glfunc.h"
932#undef GL_FUNC 989#undef GL_FUNC
990 if (!gl.ActiveTexture ) gl.ActiveTexture = gl.ActiveTextureARB;
991 if (!gl.MultiTexCoord2f) gl.MultiTexCoord2f = gl.MultiTexCoord2fARB;
933 } 992 }
934} 993}
935 OUTPUT: 994 OUTPUT:
936 RETVAL 995 RETVAL
996
997void
998SDL_WM_SetCaption (const char *title, const char *icon)
937 999
938void 1000void
939SDL_GL_SwapBuffers () 1001SDL_GL_SwapBuffers ()
940 1002
941char * 1003char *
942SDL_GetKeyName (int sym) 1004SDL_GetKeyName (int sym)
1005 C_ARGS: (SDLKey)sym
943 1006
944int 1007int
945SDL_GetAppState () 1008SDL_GetAppState ()
946 1009
947int 1010int
948SDL_GetModState () 1011SDL_GetModState ()
949 1012
1013int
1014SDL_WaitEvent ()
1015 C_ARGS: 0
1016
950void 1017void
1018SDL_PumpEvents ()
1019
1020void
951poll_events () 1021peep_events ()
952 PPCODE: 1022 PPCODE:
953{ 1023{
954 SDL_Event ev; 1024 SDL_Event ev;
955 1025
956 SDL_PumpEvents (); 1026 SDL_PumpEvents ();
1022 1092
1023 XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("DC::UI::Event", 1)))); 1093 XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("DC::UI::Event", 1))));
1024 } 1094 }
1025} 1095}
1026 1096
1097char *
1098SDL_AudioDriverName ()
1099 CODE:
1100{
1101 char buf [256];
1102 if (!SDL_AudioDriverName (buf, sizeof (buf)))
1103 XSRETURN_UNDEF;
1104
1105 RETVAL = buf;
1106}
1107 OUTPUT:
1108 RETVAL
1109
1027int 1110int
1028Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 4096) 1111Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 4096)
1029 POSTCALL: 1112 POSTCALL:
1030 Mix_HookMusicFinished (music_finished); 1113 Mix_HookMusicFinished (music_finished);
1031 Mix_ChannelFinished (channel_finished); 1114 Mix_ChannelFinished (channel_finished);
1032 1115
1033void 1116void
1034Mix_QuerySpec () 1117Mix_QuerySpec ()
1093add_font (char *file) 1176add_font (char *file)
1094 CODE: 1177 CODE:
1095 RETVAL = FcConfigAppFontAddFile (0, (const FcChar8 *)file); 1178 RETVAL = FcConfigAppFontAddFile (0, (const FcChar8 *)file);
1096 OUTPUT: 1179 OUTPUT:
1097 RETVAL 1180 RETVAL
1181
1182void
1183IMG_Init (int flags = IMG_INIT_JPG | IMG_INIT_PNG)
1184
1185# MIX_INIT_MP3 gives smpeg + libstdc++ + libgcc_s
1186void
1187Mix_Init (int flags = MIX_INIT_MOD | MIX_INIT_OGG)
1098 1188
1099void 1189void
1100load_image_inline (SV *image_) 1190load_image_inline (SV *image_)
1101 ALIAS: 1191 ALIAS:
1102 load_image_file = 1 1192 load_image_file = 1
1148 1238
1149 SDL_LockSurface (surface2); 1239 SDL_LockSurface (surface2);
1150 EXTEND (SP, 6); 1240 EXTEND (SP, 6);
1151 PUSHs (sv_2mortal (newSViv (surface2->w))); 1241 PUSHs (sv_2mortal (newSViv (surface2->w)));
1152 PUSHs (sv_2mortal (newSViv (surface2->h))); 1242 PUSHs (sv_2mortal (newSViv (surface2->h)));
1153 PUSHs (sv_2mortal (newSVpvn (surface2->pixels, surface2->h * surface2->pitch))); 1243 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))); 1244 PUSHs (sv_2mortal (newSViv (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA) ? GL_RGBA : GL_RGB)));
1155 PUSHs (sv_2mortal (newSViv (GL_RGBA))); 1245 PUSHs (sv_2mortal (newSViv (GL_RGBA)));
1156 PUSHs (sv_2mortal (newSViv (GL_UNSIGNED_BYTE))); 1246 PUSHs (sv_2mortal (newSViv (GL_UNSIGNED_BYTE)));
1157 SDL_UnlockSurface (surface2); 1247 SDL_UnlockSurface (surface2);
1158 1248
1230MODULE = Deliantra::Client PACKAGE = DC::Font 1320MODULE = Deliantra::Client PACKAGE = DC::Font
1231 1321
1232PROTOTYPES: DISABLE 1322PROTOTYPES: DISABLE
1233 1323
1234DC::Font 1324DC::Font
1235new_from_file (SV *class, char *path, int id = 0) 1325new_from_file (SV *klass, char *path, int id = 0)
1236 CODE: 1326 CODE:
1237{ 1327{
1238 int count; 1328 int count;
1239 FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)path, id, 0, &count); 1329 FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)path, id, 0, &count);
1240 RETVAL = pango_fc_font_description_from_pattern (pattern, 0); 1330 RETVAL = pango_fc_font_description_from_pattern (pattern, 0);
1269 PROTOTYPE: 1359 PROTOTYPE:
1270 CODE: 1360 CODE:
1271 tc_restore (); 1361 tc_restore ();
1272 1362
1273DC::Layout 1363DC::Layout
1274new (SV *class) 1364new (SV *klass)
1275 CODE: 1365 CODE:
1276 New (0, RETVAL, 1, struct cf_layout); 1366 RETVAL = new cf_layout;
1277 1367
1278 RETVAL->pl = pango_layout_new (opengl_context); 1368 RETVAL->pl = pango_layout_new (opengl_context);
1279 RETVAL->r = 1.; 1369 RETVAL->r = 1.;
1280 RETVAL->g = 1.; 1370 RETVAL->g = 1.;
1281 RETVAL->b = 1.; 1371 RETVAL->b = 1.;
1282 RETVAL->a = 1.; 1372 RETVAL->a = 1.;
1283 RETVAL->base_height = MIN_FONT_HEIGHT; 1373 RETVAL->base_height = MIN_FONT_HEIGHT;
1284 RETVAL->font = 0; 1374 RETVAL->font = 0;
1285 RETVAL->rc = rc_alloc ();
1286 1375
1287 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR); 1376 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
1288 layout_update_font (RETVAL); 1377 layout_update_font (RETVAL);
1289 OUTPUT: 1378 OUTPUT:
1290 RETVAL 1379 RETVAL
1291 1380
1292void 1381void
1293DESTROY (DC::Layout self) 1382DESTROY (DC::Layout self)
1294 CODE: 1383 CODE:
1295 g_object_unref (self->pl); 1384 g_object_unref (self->pl);
1296 rc_free (self->rc);
1297 Safefree (self); 1385 delete self;
1298 1386
1299void 1387void
1300set_text (DC::Layout self, SV *text_) 1388set_text (DC::Layout self, SV *text_)
1301 CODE: 1389 CODE:
1302{ 1390{
1428 1516
1429void 1517void
1430set_height (DC::Layout self, int base_height) 1518set_height (DC::Layout self, int base_height)
1431 CODE: 1519 CODE:
1432 if (self->base_height != base_height) 1520 if (self->base_height != base_height)
1433 { 1521 {
1434 self->base_height = base_height; 1522 self->base_height = base_height;
1435 layout_update_font (self); 1523 layout_update_font (self);
1436 } 1524 }
1437 1525
1438void 1526void
1556} 1644}
1557 1645
1558void 1646void
1559render (DC::Layout self, float x, float y, int flags = 0) 1647render (DC::Layout self, float x, float y, int flags = 0)
1560 CODE: 1648 CODE:
1561 rc_clear (self->rc); 1649 self->rc.clear ();
1562 pango_opengl_render_layout_subpixel ( 1650 pango_opengl_render_layout_subpixel (
1563 self->pl, 1651 self->pl,
1564 self->rc, 1652 &self->rc,
1565 x * PANGO_SCALE, y * PANGO_SCALE, 1653 x * PANGO_SCALE, y * PANGO_SCALE,
1566 self->r, self->g, self->b, self->a, 1654 self->r, self->g, self->b, self->a,
1567 flags 1655 flags
1568 ); 1656 );
1569 // we assume that context_change actually clears/frees stuff 1657 // we assume that context_change actually clears/frees stuff
1580 gl_BlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 1668 gl_BlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
1581 GL_ONE , GL_ONE_MINUS_SRC_ALPHA); 1669 GL_ONE , GL_ONE_MINUS_SRC_ALPHA);
1582 glEnable (GL_ALPHA_TEST); 1670 glEnable (GL_ALPHA_TEST);
1583 glAlphaFunc (GL_GREATER, 7.f / 255.f); 1671 glAlphaFunc (GL_GREATER, 7.f / 255.f);
1584 1672
1585 rc_draw (self->rc); 1673 self->rc.draw ();
1586 1674
1587 glDisable (GL_ALPHA_TEST); 1675 glDisable (GL_ALPHA_TEST);
1588 glDisable (GL_BLEND); 1676 glDisable (GL_BLEND);
1589 glDisable (GL_TEXTURE_2D); 1677 glDisable (GL_TEXTURE_2D);
1590} 1678}
1670void 1758void
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) 1759draw_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: @ 1760 PROTOTYPE: @
1673 CODE: 1761 CODE:
1674{ 1762{
1763 glEnable (GL_BLEND);
1764 glBlendFunc (intensity ? GL_SRC_ALPHA : GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1675 glEnable (GL_TEXTURE_2D); 1765 glEnable (GL_TEXTURE_2D);
1676 glEnable (GL_BLEND);
1677 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1678 glBindTexture (GL_TEXTURE_2D, name1); 1766 glBindTexture (GL_TEXTURE_2D, name1);
1679 1767
1680 glColor3f (intensity, intensity, intensity); 1768 glColor3f (intensity, intensity, intensity);
1681 glPushMatrix (); 1769 glPushMatrix ();
1682 glScalef (1./3, 1./3, 1.); 1770 glScalef (1./3, 1./3, 1.);
1697 glBindTexture (GL_TEXTURE_2D, name2); 1785 glBindTexture (GL_TEXTURE_2D, name2);
1698 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 1786 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
1699 1787
1700 /* rgb == rgb(glcolor) */ 1788 /* rgb == rgb(glcolor) */
1701 glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); 1789 glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
1702 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_CONSTANT); 1790 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
1703 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); 1791 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
1704 1792
1705 /* alpha = interpolate t0, t1 by env_alpha */ 1793 /* alpha = interpolate t0, t1 by env_alpha */
1706 glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, env_color); 1794 glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, env_color);
1707 1795
1802MODULE = Deliantra::Client PACKAGE = DC::Map 1890MODULE = Deliantra::Client PACKAGE = DC::Map
1803 1891
1804PROTOTYPES: DISABLE 1892PROTOTYPES: DISABLE
1805 1893
1806DC::Map 1894DC::Map
1807new (SV *class) 1895new (SV *klass)
1808 CODE: 1896 CODE:
1809 New (0, RETVAL, 1, struct map); 1897 New (0, RETVAL, 1, mapgrid);
1810 RETVAL->x = 0; 1898 RETVAL->x = 0;
1811 RETVAL->y = 0; 1899 RETVAL->y = 0;
1812 RETVAL->w = 0; 1900 RETVAL->w = 0;
1813 RETVAL->h = 0; 1901 RETVAL->h = 0;
1814 RETVAL->ox = 0; 1902 RETVAL->ox = 0;
1851 1939
1852void 1940void
1853set_smooth (DC::Map self, int face, int smooth, int level) 1941set_smooth (DC::Map self, int face, int smooth, int level)
1854 CODE: 1942 CODE:
1855{ 1943{
1856 tileid texid; 1944 tileid texid;
1857 maptex *tex; 1945 maptex *tex;
1858 1946
1859 if (face < 0 || face >= self->faces) 1947 if (face < 0 || face >= self->faces)
1860 return; 1948 return;
1861 1949
1862 if (smooth < 0 || smooth >= self->faces) 1950 if (smooth < 0 || smooth >= self->faces)
1863 return; 1951 return;
1864 1952
1865 texid = self->face2tile [face]; 1953 texid = self->face2tile [face];
1866 1954
1867 if (!texid) 1955 if (!texid)
1868 return; 1956 return;
1869 1957
1870 tex = self->tex + texid; 1958 tex = self->tex + texid;
1903} 1991}
1904 1992
1905void 1993void
1906expire_textures (DC::Map self, int texid, int count) 1994expire_textures (DC::Map self, int texid, int count)
1907 PPCODE: 1995 PPCODE:
1908 for (; texid < self->texs && count; ++texid, --count) 1996 for (; texid < self->texs && count; ++texid, --count)
1909 { 1997 {
1910 maptex *tex = self->tex + texid; 1998 maptex *tex = self->tex + texid;
1911 1999
1912 if (tex->name) 2000 if (tex->name)
1913 { 2001 {
1960 self->ox += dx; self->x += dx; 2048 self->ox += dx; self->x += dx;
1961 self->oy += dy; self->y += dy; 2049 self->oy += dy; self->y += dy;
1962 2050
1963 while (self->y < 0) 2051 while (self->y < 0)
1964 { 2052 {
1965 Prepend (maprow, self->row, self->rows, MAP_EXTEND_Y); 2053 prepend (self->row, self->rows, MAP_EXTEND_Y);
1966 2054
1967 self->rows += MAP_EXTEND_Y; 2055 self->rows += MAP_EXTEND_Y;
1968 self->y += MAP_EXTEND_Y; 2056 self->y += MAP_EXTEND_Y;
1969 } 2057 }
1970} 2058}
1971 2059
1972SV * 2060SV *
1973map1a_update (DC::Map self, SV *data_, int extmap) 2061map1a_update (DC::Map self, SV *data_)
1974 CODE: 2062 CODE:
1975{ 2063{
1976 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_); 2064 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_);
1977 uint8_t *data_end = (uint8_t *)SvEND (data_); 2065 uint8_t *data_end = (uint8_t *)SvEND (data_);
1978 mapcell *cell; 2066 mapcell *cell;
1999 2087
2000 //TODO: don't trust server data to be in-range(!) 2088 //TODO: don't trust server data to be in-range(!)
2001 2089
2002 if (flags & 8) 2090 if (flags & 8)
2003 { 2091 {
2092 uint8_t ext, cmd;
2093
2004 if (extmap) 2094 do
2005 { 2095 {
2006 uint8_t ext, cmd; 2096 ext = *data++;
2097 cmd = ext & 0x7f;
2007 2098
2008 do 2099 if (cmd < 4)
2100 cell->darkness = 255 - ext * 64 + 1; /* make sure this doesn't collide with FOW_DARKNESS */
2101 else if (cmd == 5) // health
2009 { 2102 {
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; 2103 cell->stat_width = 1;
2018 cell->stat_hp = *data++; 2104 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 } 2105 }
2038 while (ext & 0x80); 2106 else if (cmd == 6) // monster width
2107 cell->stat_width = *data++ + 1;
2108 else if (cmd == 0x47)
2109 {
2110 if (*data == 1) cell->player = data [1];
2111 else if (*data == 2) cell->player = data [2] + (data [1] << 8);
2112 else if (*data == 3) cell->player = data [3] + (data [2] << 8) + (data [1] << 16);
2113 else if (*data == 4) cell->player = data [4] + (data [3] << 8) + (data [2] << 16) + (data [1] << 24);
2114
2115 data += *data + 1;
2116 }
2117 else if (cmd == 8) // cell flags
2118 cell->flags = *data++;
2119 else if (ext & 0x40) // unknown, multibyte => skip
2120 data += *data + 1;
2121 else
2122 data++;
2039 } 2123 }
2040 else 2124 while (ext & 0x80);
2041 cell->darkness = *data++ + 1;
2042 } 2125 }
2043 2126
2044 for (z = 0; z <= 2; ++z) 2127 for (z = 0; z <= 2; ++z)
2045 if (flags & (4 >> z)) 2128 if (flags & (4 >> z))
2046 { 2129 {
2094 ? self->row + y 2177 ? self->row + y
2095 : 0; 2178 : 0;
2096 2179
2097 for (x = x0; x < x1; x++) 2180 for (x = x0; x < x1; x++)
2098 { 2181 {
2099 int r = 32, g = 32, b = 32, a = 192; 2182 unsigned int r = 32, g = 32, b = 32, a = 192;
2100 2183
2101 if (row && row->c0 <= x && x < row->c1) 2184 if (row && row->c0 <= x && x < row->c1)
2102 { 2185 {
2103 mapcell *cell = row->col + (x - row->c0); 2186 mapcell *cell = row->col + (x - row->c0);
2104 2187
2106 { 2189 {
2107 maptex tex = self->tex [cell->tile [z]]; 2190 maptex tex = self->tex [cell->tile [z]];
2108 int a0 = 255 - tex.a; 2191 int a0 = 255 - tex.a;
2109 int a1 = tex.a; 2192 int a1 = tex.a;
2110 2193
2111 r = (r * a0 + tex.r * a1) / 255; 2194 r = div255 (r * a0 + tex.r * a1);
2112 g = (g * a0 + tex.g * a1) / 255; 2195 g = div255 (g * a0 + tex.g * a1);
2113 b = (b * a0 + tex.b * a1) / 255; 2196 b = div255 (b * a0 + tex.b * a1);
2114 a = (a * a0 + tex.a * a1) / 255; 2197 a = div255 (a * a0 + tex.a * a1);
2115 } 2198 }
2116 } 2199 }
2117 2200
2118 *map++ = (r ) 2201 *map++ = (r )
2119 | (g << 8) 2202 | (g << 8)
2120 | (b << 16) 2203 | (b << 16)
2121 | (a << 24); 2204 | (a << 24);
2122 } 2205 }
2123 } 2206 }
2124 2207
2125 RETVAL = map_sv; 2208 RETVAL = map_sv;
2126} 2209}
2127 OUTPUT: 2210 OUTPUT:
2128 RETVAL 2211 RETVAL
2129 2212
2130void 2213void
2131draw (DC::Map self, int mx, int my, int sw, int sh, int T, U32 player = 0xffffffff, int sdx = 0, int sdy = 0) 2214draw (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: 2215 CODE:
2133{ 2216{
2134 int x, y, z; 2217 int x, y, z;
2135 2218
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) 2219 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; 2220 int pl_x, pl_y;
2141 maptex pl_tex; 2221 maptex pl_tex;
2142 rc_t *rc = rc_alloc (); 2222 rc_t rc;
2143 rc_t *rc_ov = rc_alloc (); 2223 rc_t rc_ov;
2144 rc_key_t key; 2224 rc_key_t key;
2145 rc_array_t *arr; 2225 rc_t::array_t *arr;
2146 2226
2147 pl_tex.name = 0; 2227 pl_tex.name = 0;
2148 2228
2149 // that's current max. sorry. 2229 // that's current max. sorry.
2150 if (sw > 255) sw = 255; 2230 if (sw > 255) sw = 255;
2151 if (sh > 255) sh = 255; 2231 if (sh > 255) sh = 255;
2152
2153 // clear key, in case of extra padding
2154 memset (&skey, 0, sizeof (skey));
2155 2232
2156 memset (&key, 0, sizeof (key)); 2233 memset (&key, 0, sizeof (key));
2157 key.r = 255; 2234 key.r = 255;
2158 key.g = 255; 2235 key.g = 255;
2159 key.b = 255; 2236 key.b = 255;
2165 my += self->y; 2242 my += self->y;
2166 2243
2167 // first pass: determine smooth_max 2244 // first pass: determine smooth_max
2168 // rather ugly, if you ask me 2245 // rather ugly, if you ask me
2169 // could also be stored inside mapcell and updated on change 2246 // could also be stored inside mapcell and updated on change
2170 memset (smooth_max, 0, sizeof (smooth_max)); 2247 memset (smooth_max, 0, sizeof (smooth_max[0]) * (sh + 1));
2171 2248
2172 for (y = 0; y < sh; y++) 2249 for (y = 0; y < sh; y++)
2173 if (0 <= y + my && y + my < self->rows) 2250 if (0 <= y + my && y + my < self->rows)
2174 { 2251 {
2175 maprow *row = self->row + (y + my); 2252 maprow *row = self->row + (y + my);
2190 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2267 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2191 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 2268 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
2192 2269
2193 for (z = 0; z <= 2; z++) 2270 for (z = 0; z <= 2; z++)
2194 { 2271 {
2195 memset (smooth_level, 0, sizeof (smooth_level)); 2272 std::bitset<256> smooth_level; // one bit for every possible smooth level
2273 smooth_key skey;
2274 smooth_hash smooth;
2196 key.texname = -1; 2275 key.texname = -1;
2197 2276
2198 for (y = 0; y < sh; y++) 2277 for (y = 0; y < sh; y++)
2199 if (0 <= y + my && y + my < self->rows) 2278 if (0 <= y + my && y + my < self->rows)
2200 { 2279 {
2217 2296
2218 if (!tex.name) 2297 if (!tex.name)
2219 tex = self->tex [TEXID_NOFACE]; /* missing, replace by noface */ 2298 tex = self->tex [TEXID_NOFACE]; /* missing, replace by noface */
2220 2299
2221 key.texname = tex.name; 2300 key.texname = tex.name;
2222 arr = rc_array (rc, &key); 2301 arr = &rc.array (key);
2223 } 2302 }
2224 2303
2225 px = (x + 1) * T - tex.w; 2304 px = (x + 1) * Th - tex.w;
2226 py = (y + 1) * T - tex.h; 2305 py = (y + 1) * Tw - tex.h;
2227 2306
2228 if (expect_false (cell->player == player) && expect_false (z == 2)) 2307 if (ecb_expect_false (cell->player == player) && ecb_expect_false (z == 2))
2229 { 2308 {
2230 pl_x = px; 2309 pl_x = px;
2231 pl_y = py; 2310 pl_y = py;
2232 pl_tex = tex; 2311 pl_tex = tex;
2233 continue; 2312 continue;
2234 } 2313 }
2235 2314
2236 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2315 arr->t2f_v3f (0 , 0 , px , py , 0);
2237 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0); 2316 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); 2317 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); 2318 arr->t2f_v3f (tex.s, 0 , px + tex.w, py , 0);
2240 2319
2241 // update smooth hash 2320 // update smooth hash
2242 if (tex.smoothtile) 2321 if (tex.smoothtile)
2243 { 2322 {
2244 skey.tile = tex.smoothtile; 2323 skey.tile = tex.smoothtile;
2245 skey.level = tex.smoothlevel; 2324 skey.level = tex.smoothlevel;
2246 2325
2247 smooth_level [tex.smoothlevel >> 5] |= ((uint32_t)1) << (tex.smoothlevel & 31); 2326 smooth_level[tex.smoothlevel] = 1;
2248 2327
2249 // add bits to current tile and all neighbours. skey.x|y is 2328 // add bits to current tile and all neighbours. skey.x|y is
2250 // shifted +1|+1 so we always stay positive. 2329 // shifted +1|+1 so we always stay positive.
2251 2330
2252 // bits is ___n cccc CCCC bbbb 2331 // bits is ___n cccc CCCC bbbb
2260 2339
2261 // corners: 1 ┛· 2 ·┗ 4 ·· 8 ·· 2340 // corners: 1 ┛· 2 ·┗ 4 ·· 8 ··
2262 // ·· ·· ·┏ ┓· 2341 // ·· ·· ·┏ ┓·
2263 2342
2264 // full tile 2343 // full tile
2265 skey.x = x + 1; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x1000); 2344 skey.x = x + 1; skey.y = y + 1; smooth_or_bits (smooth, skey, 0x1000);
2266 2345
2267 // borders 2346 // borders
2268 skey.x = x + 2; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x0091); 2347 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); 2348 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); 2349 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); 2350 skey.x = x + 1; skey.y = y ; smooth_or_bits (smooth, skey, 0x00c8);
2272 2351
2273 // corners 2352 // corners
2274 skey.x = x + 2; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0100); 2353 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); 2354 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); 2355 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); 2356 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, skey, 0x0800);
2278 } 2357 }
2279 } 2358 }
2280 2359
2281 if (expect_false (z == 2) && expect_false (cell->flags)) 2360 if (ecb_expect_false (z == 2) && ecb_expect_false (cell->flags))
2282 { 2361 {
2283 // overlays such as the speech bubble, probably more to come 2362 // overlays such as the speech bubble, probably more to come
2284 if (cell->flags & 1) 2363 if (cell->flags & 1)
2285 { 2364 {
2286 rc_key_t key_ov = key; 2365 rc_key_t key_ov = key;
2287 maptex tex = self->tex [TEXID_SPEECH]; 2366 maptex tex = self->tex[TEXID_SPEECH];
2288 rc_array_t *arr;
2289 int px = x * T + T * 2 / 32; 2367 int px = x * Tw + Tw * 2 / 32;
2290 int py = y * T - T * 6 / 32; 2368 int py = y * Th - Th * 6 / 32;
2291 2369
2292 key_ov.texname = tex.name; 2370 key_ov.texname = tex.name;
2293 arr = rc_array (rc_ov, &key_ov); 2371 rc_t::array_t &arr = rc_ov.array (key_ov);
2294 2372
2295 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2373 arr.t2f_v3f (0 , 0 , px , py , 0);
2296 rc_t2f_v3f (arr, 0 , tex.t, px , py + T, 0); 2374 arr.t2f_v3f (0 , tex.t, px , py + Th, 0);
2297 rc_t2f_v3f (arr, tex.s, tex.t, px + T, py + T, 0); 2375 arr.t2f_v3f (tex.s, tex.t, px + Tw, py + Th, 0);
2298 rc_t2f_v3f (arr, tex.s, 0 , px + T, py , 0); 2376 arr.t2f_v3f (tex.s, 0 , px + Tw, py , 0);
2299 } 2377 }
2300 } 2378 }
2301 } 2379 }
2302 } 2380 }
2303 2381
2304 rc_draw (rc); 2382 rc.draw ();
2305 rc_clear (rc); 2383 rc.clear ();
2306 2384
2307 // go through all smoothlevels, lowest to highest, then draw. 2385 // go through all smoothlevels, lowest to highest, then draw.
2308 // this is basically counting sort 2386 // this is basically counting sort
2309 { 2387 {
2310 int w, b; 2388 int w, b;
2311 2389
2312 glEnable (GL_TEXTURE_2D); 2390 glEnable (GL_TEXTURE_2D);
2313 glBegin (GL_QUADS); 2391 glBegin (GL_QUADS);
2314 for (w = 0; w < 256 / 32; ++w) 2392 for (int level = 0; level < smooth_level.size (); ++level)
2393 if (smooth_level[level])
2394 for (auto &&it = smooth.begin (); it != smooth.end (); ++it)
2315 { 2395 {
2316 uint32_t smask = smooth_level [w]; 2396 smooth_key &skey = it->first;
2317 if (smask) 2397 IV bits = it->second;
2318 for (b = 0; b < 32; ++b) 2398
2319 if (smask & (((uint32_t)1) << b)) 2399 if (!(bits & 0x1000)
2400 && skey.level == level
2401 && level > smooth_max [skey.x][skey.y])
2320 { 2402 {
2321 int level = (w << 5) | b; 2403 maptex tex = self->tex [skey.tile];
2404 int px = (((int)skey.x) - 1) * Tw;
2405 int py = (((int)skey.y) - 1) * Th;
2406 int border = bits & 15;
2407 int corner = (bits >> 8) & ~(bits >> 4) & 15;
2408 float dx = tex.s * .0625f; // 16 images/row
2409 float dy = tex.t * .5f ; // 2 images/column
2410
2322 HE *he; 2411 if (tex.name)
2323
2324 hv_iterinit (smooth);
2325 while ((he = hv_iternext (smooth)))
2326 { 2412 {
2327 smooth_key *skey = (smooth_key *)HeKEY (he); 2413 // this time avoiding texture state changes
2328 IV bits = SvIVX (HeVAL (he)); 2414 // save gobs of state changes.
2329 2415 if (key.texname != tex.name)
2330 if (!(bits & 0x1000)
2331 && skey->level == level
2332 && level > smooth_max [skey->x][skey->y])
2333 { 2416 {
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; 2417 self->tex [skey.tile].unused = 0;
2349 2418
2350 glEnd (); 2419 glEnd ();
2351 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name); 2420 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name);
2352 glBegin (GL_QUADS); 2421 glBegin (GL_QUADS);
2353 } 2422 }
2354 2423
2355 if (border) 2424 if (border)
2356 { 2425 {
2357 float ox = border * dx; 2426 float ox = border * dx;
2358 2427
2359 glTexCoord2f (ox , 0.f ); glVertex2i (px , py ); 2428 glTexCoord2f (ox , 0.f ); glVertex2i (px , py );
2360 glTexCoord2f (ox , dy ); glVertex2i (px , py + T); 2429 glTexCoord2f (ox , dy ); glVertex2i (px , py + Th);
2361 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py + T); 2430 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py + Th);
2362 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + T, py ); 2431 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + Tw, py );
2363 } 2432 }
2364 2433
2365 if (corner) 2434 if (corner)
2366 { 2435 {
2367 float ox = corner * dx; 2436 float ox = corner * dx;
2368 2437
2369 glTexCoord2f (ox , dy ); glVertex2i (px , py ); 2438 glTexCoord2f (ox , dy ); glVertex2i (px , py );
2370 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + T); 2439 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + Th);
2371 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + T, py + T); 2440 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + Tw, py + Th);
2372 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py ); 2441 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py );
2373 }
2374 }
2375 } 2442 }
2376 } 2443 }
2377 } 2444 }
2378 } 2445 }
2379 2446
2380 glEnd (); 2447 glEnd ();
2381 glDisable (GL_TEXTURE_2D); 2448 glDisable (GL_TEXTURE_2D);
2382 key.texname = -1; 2449 key.texname = -1;
2383 } 2450 }
2384
2385 hv_clear (smooth);
2386 } 2451 }
2387 2452
2388 if (pl_tex.name) 2453 if (pl_tex.name)
2389 { 2454 {
2390 maptex tex = pl_tex; 2455 maptex tex = pl_tex;
2391 int px = pl_x + sdx; 2456 int px = pl_x + sdx;
2392 int py = pl_y + sdy; 2457 int py = pl_y + sdy;
2393 2458
2394 key.texname = tex.name; 2459 key.texname = tex.name;
2395 arr = rc_array (rc, &key); 2460 rc_t::array_t &arr = rc.array (key);
2396 2461
2397 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2462 arr.t2f_v3f (0 , 0 , px , py , 0);
2398 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0); 2463 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); 2464 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); 2465 arr.t2f_v3f (tex.s, 0 , px + tex.w, py , 0);
2401 2466
2402 rc_draw (rc); 2467 rc.draw ();
2403 } 2468 }
2404 2469
2405 rc_draw (rc_ov); 2470 rc_ov.draw ();
2406 rc_clear (rc_ov); 2471 rc_ov.clear ();
2407 2472
2408 glDisable (GL_BLEND); 2473 glDisable (GL_BLEND);
2409 rc_free (rc);
2410 rc_free (rc_ov);
2411 2474
2412 // top layer: overlays such as the health bar 2475 // top layer: overlays such as the health bar
2413 for (y = 0; y < sh; y++) 2476 for (y = 0; y < sh; y++)
2414 if (0 <= y + my && y + my < self->rows) 2477 if (0 <= y + my && y + my < self->rows)
2415 { 2478 {
2418 for (x = 0; x < sw; x++) 2481 for (x = 0; x < sw; x++)
2419 if (row->c0 <= x + mx && x + mx < row->c1) 2482 if (row->c0 <= x + mx && x + mx < row->c1)
2420 { 2483 {
2421 mapcell *cell = row->col + (x + mx - row->c0); 2484 mapcell *cell = row->col + (x + mx - row->c0);
2422 2485
2423 int px = x * T; 2486 int px = x * Tw;
2424 int py = y * T; 2487 int py = y * Th;
2425 2488
2426 if (expect_false (cell->player == player)) 2489 if (ecb_expect_false (cell->player == player))
2427 { 2490 {
2428 px += sdx; 2491 px += sdx;
2429 py += sdy; 2492 py += sdy;
2430 } 2493 }
2431 2494
2432 if (cell->stat_hp) 2495 if (cell->stat_hp)
2433 { 2496 {
2434 int width = cell->stat_width * T; 2497 int width = cell->stat_width * Tw;
2435 int thick = (sh * T / 32 + 27) / 28 + 1 + cell->stat_width; 2498 int thick = (sh * Th / 32 + 27) / 28 + 1 + cell->stat_width;
2436 2499
2437 glColor3ub (0, 0, 0); 2500 glColor3ub (0, 0, 0);
2438 glRectf (px + 1, py - thick - 2, 2501 glRectf (px + 1, py - thick - 2,
2439 px + width - 1, py); 2502 px + width - 1, py);
2440 2503
2520 int x, y; 2583 int x, y;
2521 int sw1 = sw + 2; 2584 int sw1 = sw + 2;
2522 int sh1 = sh + 2; 2585 int sh1 = sh + 2;
2523 int sh3 = sh * 3; 2586 int sh3 = sh * 3;
2524 int sw3 = sw * 3; 2587 int sw3 = sw * 3;
2525 uint8_t *darkness1 = (uint8_t *)malloc (sw1 * sh1);
2526 SV *darkness3_sv = sv_2mortal (newSV (sw3 * sh3)); 2588 SV *darkness3_sv = sv_2mortal (newSV (sw3 * sh3));
2527 uint8_t *darkness3 = (uint8_t *)SvPVX (darkness3_sv); 2589 uint8_t *darkness3 = (uint8_t *)SvPVX (darkness3_sv);
2590 uint8_t *darkness1 = (uint8_t *)malloc (sw1 * sh1);
2591 memset (darkness1, 0, sw1*sh1);
2528 2592
2529 SvPOK_only (darkness3_sv); 2593 SvPOK_only (darkness3_sv);
2530 SvCUR_set (darkness3_sv, sw3 * sh3); 2594 SvCUR_set (darkness3_sv, sw3 * sh3);
2531 2595
2532 mx += self->x - 1; 2596 mx += self->x - 1;
2658 else 2722 else
2659 *data++ = 0; 2723 *data++ = 0;
2660 } 2724 }
2661 } 2725 }
2662 2726
2663 /* if size is w*h + 5 then no data has been found */ 2727 /* if size is w*h + 5 then no data has been found */
2664 if (data - (uint8_t *)SvPVX (data_sv) != w * h + 5) 2728 if (data - (uint8_t *)SvPVX (data_sv) != w * h + 5)
2665 { 2729 {
2666 SvPOK_only (data_sv); 2730 SvPOK_only (data_sv);
2667 SvCUR_set (data_sv, data - (uint8_t *)SvPVX (data_sv)); 2731 SvCUR_set (data_sv, data - (uint8_t *)SvPVX (data_sv));
2668 } 2732 }
2669 2733
2670 RETVAL = data_sv; 2734 RETVAL = data_sv;
2671} 2735}
2672 OUTPUT: 2736 OUTPUT:
2673 RETVAL 2737 RETVAL
2674 2738
2675void 2739void
2682 STRLEN len; 2746 STRLEN len;
2683 uint8_t *data, *end; 2747 uint8_t *data, *end;
2684 2748
2685 len = SvLEN (data_sv); 2749 len = SvLEN (data_sv);
2686 SvGROW (data_sv, len + 8); // reserve at least 7+ bytes more 2750 SvGROW (data_sv, len + 8); // reserve at least 7+ bytes more
2687 data = SvPVbyte_nolen (data_sv); 2751 data = (uint8_t *)SvPVbyte_nolen (data_sv);
2688 end = data + len + 8; 2752 end = data + len + 8;
2689 2753
2690 if (len < 5) 2754 if (len < 5)
2691 XSRETURN_EMPTY; 2755 XSRETURN_EMPTY;
2692 2756
2753} 2817}
2754 2818
2755MODULE = Deliantra::Client PACKAGE = DC::RW 2819MODULE = Deliantra::Client PACKAGE = DC::RW
2756 2820
2757DC::RW 2821DC::RW
2758new (SV *class, SV *data_sv) 2822new (SV *klass, SV *data_sv)
2759 CODE: 2823 CODE:
2760{ 2824{
2761 STRLEN datalen; 2825 STRLEN datalen;
2762 char *data = SvPVbyte (data_sv, datalen); 2826 char *data = SvPVbyte (data_sv, datalen);
2763 2827
2765} 2829}
2766 OUTPUT: 2830 OUTPUT:
2767 RETVAL 2831 RETVAL
2768 2832
2769DC::RW 2833DC::RW
2770new_from_file (SV *class, const char *path, const char *mode = "rb") 2834new_from_file (SV *klass, const char *path, const char *mode = "rb")
2771 CODE: 2835 CODE:
2772 RETVAL = SDL_RWFromFile (path, mode); 2836 RETVAL = SDL_RWFromFile (path, mode);
2773 OUTPUT: 2837 OUTPUT:
2774 RETVAL 2838 RETVAL
2775 2839
2793 if (RETVAL < 0) 2857 if (RETVAL < 0)
2794 { 2858 {
2795 RETVAL = Mix_GroupOldest (-1); 2859 RETVAL = Mix_GroupOldest (-1);
2796 2860
2797 if (RETVAL < 0) 2861 if (RETVAL < 0)
2862 {
2863 // happens sometimes, maybe it just stopped playing(?)
2864 RETVAL = Mix_GroupAvailable (-1);
2865
2866 if (RETVAL < 0)
2798 XSRETURN_UNDEF; 2867 XSRETURN_UNDEF;
2799 2868 }
2869 else
2800 Mix_HaltChannel (RETVAL); 2870 Mix_HaltChannel (RETVAL);
2801 } 2871 }
2802 2872
2803 Mix_UnregisterAllEffects (RETVAL); 2873 Mix_UnregisterAllEffects (RETVAL);
2804 Mix_Volume (RETVAL, 128); 2874 Mix_Volume (RETVAL, 128);
2805} 2875}
2865 2935
2866MODULE = Deliantra::Client PACKAGE = DC::MixChunk 2936MODULE = Deliantra::Client PACKAGE = DC::MixChunk
2867 2937
2868PROTOTYPES: DISABLE 2938PROTOTYPES: DISABLE
2869 2939
2940void
2941decoders ()
2942 PPCODE:
2943#if SDL_MIXER_MAJOR_VERSION > 1 || SDL_MIXER_MINOR_VERSION > 2 || SDL_MIXER_PATCHLEVEL >= 10
2944 int i, num = Mix_GetNumChunkDecoders ();
2945 EXTEND (SP, num);
2946 for (i = 0; i < num; ++i)
2947 PUSHs (sv_2mortal (newSVpv (Mix_GetChunkDecoder (i), 0)));
2948#else
2949 XPUSHs (sv_2mortal (newSVpv ("(sdl mixer too old)", 0)));
2950#endif
2951
2870DC::MixChunk 2952DC::MixChunk
2871new (SV *class, DC::RW rwops) 2953new (SV *klass, DC::RW rwops)
2872 CODE: 2954 CODE:
2873 RETVAL = Mix_LoadWAV_RW (rwops, 1); 2955 RETVAL = Mix_LoadWAV_RW (rwops, 1);
2874 OUTPUT: 2956 OUTPUT:
2875 RETVAL 2957 RETVAL
2876 2958
2906 OUTPUT: 2988 OUTPUT:
2907 RETVAL 2989 RETVAL
2908 2990
2909MODULE = Deliantra::Client PACKAGE = DC::MixMusic 2991MODULE = Deliantra::Client PACKAGE = DC::MixMusic
2910 2992
2993void
2994decoders ()
2995 PPCODE:
2996#if SDL_MIXER_MAJOR_VERSION > 1 || SDL_MIXER_MINOR_VERSION > 2 || SDL_MIXER_PATCHLEVEL >= 10
2997 int i, num = Mix_GetNumMusicDecoders ();
2998 EXTEND (SP, num);
2999 for (i = 0; i < num; ++i)
3000 PUSHs (sv_2mortal (newSVpv (Mix_GetMusicDecoder (i), 0)));
3001#else
3002 XPUSHs (sv_2mortal (newSVpv ("(sdl mixer too old)", 0)));
3003#endif
3004
2911int 3005int
2912volume (int volume = -1) 3006volume (int volume = -1)
2913 PROTOTYPE: ;$ 3007 PROTOTYPE: ;$
2914 CODE: 3008 CODE:
2915 if (items > 0) 3009 if (items > 0)
2926void 3020void
2927halt () 3021halt ()
2928 CODE: 3022 CODE:
2929 Mix_HaltMusic (); 3023 Mix_HaltMusic ();
2930 3024
3025int
3026playing ()
3027 CODE:
3028 RETVAL = Mix_PlayingMusic ();
3029 OUTPUT:
3030 RETVAL
3031
2931DC::MixMusic 3032DC::MixMusic
2932new (SV *class, DC::RW rwops) 3033new (SV *klass, DC::RW rwops)
2933 CODE: 3034 CODE:
2934 RETVAL = Mix_LoadMUS_RW (rwops); 3035 RETVAL = Mix_LoadMUS_RW (rwops);
2935 OUTPUT: 3036 OUTPUT:
2936 RETVAL 3037 RETVAL
2937 3038
3074 const_iv (GL_FUNC_SUBTRACT), 3175 const_iv (GL_FUNC_SUBTRACT),
3075 const_iv (GL_FUNC_REVERSE_SUBTRACT), 3176 const_iv (GL_FUNC_REVERSE_SUBTRACT),
3076# undef const_iv 3177# undef const_iv
3077 }; 3178 };
3078 3179
3079 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 3180 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
3080 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 3181 newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
3081 3182
3082 texture_av = newAV (); 3183 texture_av = newAV ();
3083 AvREAL_off (texture_av); 3184 AvREAL_off (texture_av);
3084} 3185}
3085 3186
3090 gl.BlendFuncSeparateEXT = 0; 3191 gl.BlendFuncSeparateEXT = 0;
3091 3192
3092void 3193void
3093apple_nvidia_bug (int enable) 3194apple_nvidia_bug (int enable)
3094 3195
3095char * 3196const char *
3096gl_vendor () 3197gl_vendor ()
3097 CODE: 3198 CODE:
3098 RETVAL = (char *)glGetString (GL_VENDOR); 3199 RETVAL = (const char *)glGetString (GL_VENDOR);
3099 OUTPUT: 3200 OUTPUT:
3100 RETVAL 3201 RETVAL
3101 3202
3102char * 3203const char *
3103gl_version () 3204gl_version ()
3104 CODE: 3205 CODE:
3105 RETVAL = (char *)glGetString (GL_VERSION); 3206 RETVAL = (const char *)glGetString (GL_VERSION);
3106 OUTPUT: 3207 OUTPUT:
3107 RETVAL 3208 RETVAL
3108 3209
3109char * 3210const char *
3110gl_extensions () 3211gl_extensions ()
3111 CODE: 3212 CODE:
3112 RETVAL = (char *)glGetString (GL_EXTENSIONS); 3213 RETVAL = (const char *)glGetString (GL_EXTENSIONS);
3113 OUTPUT: 3214 OUTPUT:
3114 RETVAL 3215 RETVAL
3115 3216
3116const char *glGetString (GLenum pname) 3217const char *glGetString (GLenum pname)
3218 CODE:
3219 RETVAL = (const char *)glGetString (pname);
3220 OUTPUT:
3221 RETVAL
3117 3222
3118GLint glGetInteger (GLenum pname) 3223GLint glGetInteger (GLenum pname)
3119 CODE: 3224 CODE:
3120 glGetIntegerv (pname, &RETVAL); 3225 glGetIntegerv (pname, &RETVAL);
3121 OUTPUT: 3226 OUTPUT:
3128 RETVAL 3233 RETVAL
3129 3234
3130int glGetError () 3235int glGetError ()
3131 3236
3132void glFinish () 3237void glFinish ()
3238
3239void glFlush ()
3133 3240
3134void glClear (int mask) 3241void glClear (int mask)
3135 3242
3136void glClearColor (float r, float g, float b, float a = 1.0) 3243void glClearColor (float r, float g, float b, float a = 1.0)
3137 PROTOTYPE: @ 3244 PROTOTYPE: @
3322 3429
3323void 3430void
3324find_widget (SV *self, NV x, NV y) 3431find_widget (SV *self, NV x, NV y)
3325 PPCODE: 3432 PPCODE:
3326{ 3433{
3327 if (within_widget (self, x, y)) 3434 if (within_widget (self, x, y))
3328 XPUSHs (self); 3435 XPUSHs (self);
3329} 3436}
3330 3437
3331BOOT: 3438BOOT:
3332{ 3439{
3340 3447
3341void 3448void
3342draw (SV *self) 3449draw (SV *self)
3343 CODE: 3450 CODE:
3344{ 3451{
3345 HV *hv; 3452 HV *hv;
3346 SV **svp; 3453 SV **svp;
3347 NV x, y, w, h; 3454 NV x, y, w, h;
3348 SV *draw_x_sv = GvSV (draw_x_gv); 3455 SV *draw_x_sv = GvSV (draw_x_gv);
3349 SV *draw_y_sv = GvSV (draw_y_gv); 3456 SV *draw_y_sv = GvSV (draw_y_gv);
3350 SV *draw_w_sv = GvSV (draw_w_gv); 3457 SV *draw_w_sv = GvSV (draw_w_gv);
3351 SV *draw_h_sv = GvSV (draw_h_gv); 3458 SV *draw_h_sv = GvSV (draw_h_gv);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines