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.208 by root, Sat Jul 21 16:07:53 2007 UTC vs.
Revision 1.235 by root, Tue Aug 28 01:23:47 2007 UTC

17#include "perl.h" 17#include "perl.h"
18#include "XSUB.h" 18#include "XSUB.h"
19 19
20#ifdef _WIN32 20#ifdef _WIN32
21# undef pipe 21# undef pipe
22// microsoft vs. C
23# define sqrtf(x) sqrt(x)
24# define roundf(x) (int)(x)
25# define atan2f(x,y) atan2(x,y)
26# define M_PI 3.14159265f
22#endif 27#endif
23 28
24#include <assert.h> 29#include <assert.h>
25#include <math.h> 30#include <math.h>
26#include <string.h> 31#include <string.h>
27#include <stdio.h> 32#include <stdio.h>
28#include <stdlib.h> 33#include <stdlib.h>
34
35#define USE_RWOPS 1 // for SDL_mixer:LoadMUS_RW
29 36
30#include <SDL.h> 37#include <SDL.h>
31#include <SDL_thread.h> 38#include <SDL_thread.h>
32#include <SDL_endian.h> 39#include <SDL_endian.h>
33#include <SDL_image.h> 40#include <SDL_image.h>
107 av_push (texture_av, (SV *)(size_t)name); 114 av_push (texture_av, (SV *)(size_t)name);
108 glDeleteTextures (1, &name); 115 glDeleteTextures (1, &name);
109} 116}
110 117
111#include "texcache.c" 118#include "texcache.c"
119#include "rendercache.c"
112 120
113#include "pango-font.c" 121#include "pango-font.c"
114#include "pango-fontmap.c" 122#include "pango-fontmap.c"
115#include "pango-render.c" 123#include "pango-render.c"
116 124
125typedef IV CFPlus__Channel;
126typedef SDL_RWops *CFPlus__RW;
117typedef Mix_Chunk *CFPlus__MixChunk; 127typedef Mix_Chunk *CFPlus__MixChunk;
118typedef Mix_Music *CFPlus__MixMusic; 128typedef Mix_Music *CFPlus__MixMusic;
119 129
120typedef PangoFontDescription *CFPlus__Font; 130typedef PangoFontDescription *CFPlus__Font;
121 131
140typedef struct cf_layout { 150typedef struct cf_layout {
141 PangoLayout *pl; 151 PangoLayout *pl;
142 float r, g, b, a; // default color for rgba mode 152 float r, g, b, a; // default color for rgba mode
143 int base_height; 153 int base_height;
144 CFPlus__Font font; 154 CFPlus__Font font;
155 rc_t *rc;
145} *CFPlus__Layout; 156} *CFPlus__Layout;
146 157
147static CFPlus__Font default_font; 158static CFPlus__Font default_font;
148static PangoContext *opengl_context; 159static PangoContext *opengl_context;
149static PangoFontMap *opengl_fontmap; 160static PangoFontMap *opengl_fontmap;
192 203
193typedef uint16_t tileid; 204typedef uint16_t tileid;
194typedef uint16_t faceid; 205typedef uint16_t faceid;
195 206
196typedef struct { 207typedef struct {
197 int name; 208 GLuint name;
198 int w, h; 209 int w, h;
199 float s, t; 210 float s, t;
200 uint8_t r, g, b, a; 211 uint8_t r, g, b, a;
201 tileid smoothtile; 212 tileid smoothtile;
202 uint8_t smoothlevel; 213 uint8_t smoothlevel;
429 n |= n >> 16; 440 n |= n >> 16;
430 441
431 return n + 1; 442 return n + 1;
432} 443}
433 444
445static unsigned int
446popcount (unsigned int n)
447{
448 n -= (n >> 1) & 0x55555555U;
449 n = ((n >> 2) & 0x33333333U) + (n & 0x33333333U);
450 n = ((n >> 4) + n) & 0x0f0f0f0fU;
451 n *= 0x01010101U;
452
453 return n >> 24;
454}
455
434/* SDL should provide this, really. */ 456/* SDL should provide this, really. */
435#define SDLK_MODIFIER_MIN 300 457#define SDLK_MODIFIER_MIN 300
436#define SDLK_MODIFIER_MAX 314 458#define SDLK_MODIFIER_MAX 314
437 459
438/******************************************************************************/ 460/******************************************************************************/
461
462static GV *draw_x_gv, *draw_y_gv, *draw_w_gv, *draw_h_gv;
463static GV *hover_gv;
439 464
440static int 465static int
441within_widget (SV *widget, NV x, NV y) 466within_widget (SV *widget, NV x, NV y)
442{ 467{
443 HV *self; 468 HV *self;
511 536
512 const_iv (SDL_APPINPUTFOCUS), 537 const_iv (SDL_APPINPUTFOCUS),
513 const_iv (SDL_APPMOUSEFOCUS), 538 const_iv (SDL_APPMOUSEFOCUS),
514 const_iv (SDL_APPACTIVE), 539 const_iv (SDL_APPACTIVE),
515 540
541 const_iv (SDLK_FIRST),
542 const_iv (SDLK_LAST),
516 const_iv (SDLK_KP0), 543 const_iv (SDLK_KP0),
517 const_iv (SDLK_KP1), 544 const_iv (SDLK_KP1),
518 const_iv (SDLK_KP2), 545 const_iv (SDLK_KP2),
519 const_iv (SDLK_KP3), 546 const_iv (SDLK_KP3),
520 const_iv (SDLK_KP4), 547 const_iv (SDLK_KP4),
619 646
620NV floor (NV x) 647NV floor (NV x)
621 648
622NV ceil (NV x) 649NV ceil (NV x)
623 650
651IV minpot (UV n)
652
653IV popcount (UV n)
654
624void 655void
625pango_init () 656pango_init ()
626 CODE: 657 CODE:
627{ 658{
628 opengl_fontmap = pango_opengl_font_map_new (); 659 opengl_fontmap = pango_opengl_font_map_new ();
701 732
702 if (RETVAL) 733 if (RETVAL)
703 { 734 {
704 av_clear (texture_av); 735 av_clear (texture_av);
705 736
706 SDL_WM_SetCaption ("Crossfire+ Client " VERSION, "Crossfire+"); 737 SDL_WM_SetCaption ("Crossfire TRT Client " VERSION, "Crossfire TRT");
707#define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name); 738#define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name);
708#include "glfunc.h" 739#include "glfunc.h"
709#undef GL_FUNC 740#undef GL_FUNC
710 } 741 }
711} 742}
797 XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("CFPlus::UI::Event", 1)))); 828 XPUSHs (sv_2mortal (sv_bless (newRV_noinc ((SV *)hv), gv_stashpv ("CFPlus::UI::Event", 1))));
798 } 829 }
799} 830}
800 831
801int 832int
802Mix_OpenAudio (int frequency = 48000, int format = MIX_DEFAULT_FORMAT, int channels = 1, int chunksize = 2048) 833Mix_OpenAudio (int frequency = 44100, int format = MIX_DEFAULT_FORMAT, int channels = 2, int chunksize = 1024)
803 POSTCALL: 834 POSTCALL:
804 Mix_HookMusicFinished (music_finished); 835 Mix_HookMusicFinished (music_finished);
805 Mix_ChannelFinished (channel_finished); 836 Mix_ChannelFinished (channel_finished);
806 837
807void 838void
808Mix_CloseAudio () 839Mix_CloseAudio ()
809 840
810int 841int
811Mix_AllocateChannels (int numchans = -1) 842Mix_AllocateChannels (int numchans = -1)
843
844const char *
845Mix_GetError ()
812 846
813void 847void
814lowdelay (int fd, int val = 1) 848lowdelay (int fd, int val = 1)
815 CODE: 849 CODE:
816 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&val, sizeof (val)); 850 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&val, sizeof (val));
858 STRLEN image_len; 892 STRLEN image_len;
859 char *image = (char *)SvPVbyte (image_, image_len); 893 char *image = (char *)SvPVbyte (image_, image_len);
860 SDL_Surface *surface, *surface2; 894 SDL_Surface *surface, *surface2;
861 SDL_PixelFormat fmt; 895 SDL_PixelFormat fmt;
862 SDL_RWops *rw = ix 896 SDL_RWops *rw = ix
863 ? SDL_RWFromFile (image, "r") 897 ? SDL_RWFromFile (image, "rb")
864 : SDL_RWFromConstMem (image, image_len); 898 : SDL_RWFromConstMem (image, image_len);
865 899
866 if (!rw) 900 if (!rw)
867 croak ("load_image: %s", SDL_GetError ()); 901 croak ("load_image: %s", SDL_GetError ());
868 902
1020 RETVAL->g = 1.; 1054 RETVAL->g = 1.;
1021 RETVAL->b = 1.; 1055 RETVAL->b = 1.;
1022 RETVAL->a = 1.; 1056 RETVAL->a = 1.;
1023 RETVAL->base_height = MIN_FONT_HEIGHT; 1057 RETVAL->base_height = MIN_FONT_HEIGHT;
1024 RETVAL->font = 0; 1058 RETVAL->font = 0;
1059 RETVAL->rc = rc_alloc ();
1025 1060
1026 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR); 1061 pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR);
1027 layout_update_font (RETVAL); 1062 layout_update_font (RETVAL);
1028 OUTPUT: 1063 OUTPUT:
1029 RETVAL 1064 RETVAL
1030 1065
1031void 1066void
1032DESTROY (CFPlus::Layout self) 1067DESTROY (CFPlus::Layout self)
1033 CODE: 1068 CODE:
1034 g_object_unref (self->pl); 1069 g_object_unref (self->pl);
1070 rc_free (self->rc);
1035 Safefree (self); 1071 Safefree (self);
1036 1072
1037void 1073void
1038set_text (CFPlus::Layout self, SV *text_) 1074set_text (CFPlus::Layout self, SV *text_)
1039 CODE: 1075 CODE:
1291 } 1327 }
1292} 1328}
1293 1329
1294void 1330void
1295render (CFPlus::Layout self, float x, float y, int flags = 0) 1331render (CFPlus::Layout self, float x, float y, int flags = 0)
1296 PPCODE: 1332 CODE:
1333 rc_clear (self->rc);
1297 pango_opengl_render_layout_subpixel ( 1334 pango_opengl_render_layout_subpixel (
1298 self->pl, 1335 self->pl,
1336 self->rc,
1299 x * PANGO_SCALE, y * PANGO_SCALE, 1337 x * PANGO_SCALE, y * PANGO_SCALE,
1300 self->r, self->g, self->b, self->a, 1338 self->r, self->g, self->b, self->a,
1301 flags 1339 flags
1302 ); 1340 );
1341 // we assume that context_change actually clears/frees stuff
1342 // and does not do any recomputation...
1343 pango_layout_context_changed (self->pl);
1344
1345void
1346draw (CFPlus::Layout self)
1347 CODE:
1348{
1349 glEnable (GL_TEXTURE_2D);
1350 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1351 glEnable (GL_BLEND);
1352 gl_BlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
1353 GL_ONE , GL_ONE_MINUS_SRC_ALPHA);
1354 glEnable (GL_ALPHA_TEST);
1355 glAlphaFunc (GL_GREATER, 7.f / 255.f);
1356
1357 rc_draw (self->rc);
1358
1359 glDisable (GL_ALPHA_TEST);
1360 glDisable (GL_BLEND);
1361 glDisable (GL_TEXTURE_2D);
1362}
1303 1363
1304MODULE = CFPlus PACKAGE = CFPlus::Texture 1364MODULE = CFPlus PACKAGE = CFPlus::Texture
1305 1365
1306PROTOTYPES: ENABLE 1366PROTOTYPES: ENABLE
1307
1308int minpot (int n)
1309 1367
1310void 1368void
1311pad (SV *data_, int ow, int oh, int nw, int nh) 1369pad (SV *data_, int ow, int oh, int nw, int nh)
1312 CODE: 1370 CODE:
1313{ 1371{
1339{ 1397{
1340 HV *hv = (HV *)SvRV (self); 1398 HV *hv = (HV *)SvRV (self);
1341 float s = SvNV (*hv_fetch (hv, "s", 1, 1)); 1399 float s = SvNV (*hv_fetch (hv, "s", 1, 1));
1342 float t = SvNV (*hv_fetch (hv, "t", 1, 1)); 1400 float t = SvNV (*hv_fetch (hv, "t", 1, 1));
1343 int name = SvIV (*hv_fetch (hv, "name", 4, 1)); 1401 int name = SvIV (*hv_fetch (hv, "name", 4, 1));
1402
1403 if (name <= 0)
1404 XSRETURN_EMPTY;
1344 1405
1345 if (items < 5) 1406 if (items < 5)
1346 { 1407 {
1347 w = SvNV (*hv_fetch (hv, "w", 1, 1)); 1408 w = SvNV (*hv_fetch (hv, "w", 1, 1));
1348 h = SvNV (*hv_fetch (hv, "h", 1, 1)); 1409 h = SvNV (*hv_fetch (hv, "h", 1, 1));
1537 self->rows += MAP_EXTEND_Y; 1598 self->rows += MAP_EXTEND_Y;
1538 self->y += MAP_EXTEND_Y; 1599 self->y += MAP_EXTEND_Y;
1539 } 1600 }
1540} 1601}
1541 1602
1542void 1603SV *
1543map1a_update (CFPlus::Map self, SV *data_, int extmap) 1604map1a_update (CFPlus::Map self, SV *data_, int extmap)
1544 CODE: 1605 CODE:
1545{ 1606{
1546 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_); 1607 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_);
1547 uint8_t *data_end = (uint8_t *)SvEND (data_); 1608 uint8_t *data_end = (uint8_t *)SvEND (data_);
1548 mapcell *cell; 1609 mapcell *cell;
1549 int x, y, flags; 1610 int x, y, z, flags;
1611 AV *missing = newAV ();
1612 RETVAL = newRV_noinc ((SV *)missing);
1550 1613
1551 while (data < data_end - 1) 1614 while (data < data_end - 1)
1552 { 1615 {
1553 flags = (data [0] << 8) + data [1]; data += 2; 1616 flags = (data [0] << 8) + data [1]; data += 2;
1554 1617
1605 } 1668 }
1606 else 1669 else
1607 cell->darkness = *data++ + 1; 1670 cell->darkness = *data++ + 1;
1608 } 1671 }
1609 1672
1673 for (z = 0; z <= 2; ++z)
1610 if (flags & 4) 1674 if (flags & (4 >> z))
1611 { 1675 {
1612 faceid face = (data [0] << 8) + data [1]; data += 2; 1676 faceid face = (data [0] << 8) + data [1]; data += 2;
1613 need_facenum (self, face); 1677 need_facenum (self, face);
1614 cell->tile [0] = self->face2tile [face]; 1678 cell->tile [z] = self->face2tile [face];
1679
1680 if (cell->tile [z])
1681 {
1682 maptex *tex = self->tex + cell->tile [z];
1683 if (!tex->name)
1684 av_push (missing, newSViv (cell->tile [z]));
1685
1686 if (tex->smoothtile)
1687 {
1688 maptex *smooth = self->tex + tex->smoothtile;
1689 if (!smooth->name)
1690 av_push (missing, newSViv (tex->smoothtile));
1691 }
1692 }
1615 } 1693 }
1616
1617 if (flags & 2)
1618 {
1619 faceid face = (data [0] << 8) + data [1]; data += 2;
1620 need_facenum (self, face);
1621 cell->tile [1] = self->face2tile [face];
1622 }
1623
1624 if (flags & 1)
1625 {
1626 faceid face = (data [0] << 8) + data [1]; data += 2;
1627 need_facenum (self, face);
1628 cell->tile [2] = self->face2tile [face];
1629 }
1630 } 1694 }
1631 else 1695 else
1632 cell->darkness = 0; 1696 cell->darkness = 0;
1633 } 1697 }
1634} 1698}
1699 OUTPUT:
1700 RETVAL
1635 1701
1636SV * 1702SV *
1637mapmap (CFPlus::Map self, int x0, int y0, int w, int h) 1703mapmap (CFPlus::Map self, int x0, int y0, int w, int h)
1638 CODE: 1704 CODE:
1639{ 1705{
1690 1756
1691void 1757void
1692draw (CFPlus::Map self, int mx, int my, int sw, int sh, int T) 1758draw (CFPlus::Map self, int mx, int my, int sw, int sh, int T)
1693 CODE: 1759 CODE:
1694{ 1760{
1761 int x, y, z;
1762
1695 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ()); 1763 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
1696 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level 1764 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level
1697 static uint8_t smooth_max[256][256]; // egad, fats and wasteful on memory (64k) 1765 static uint8_t smooth_max[256][256]; // egad, fast and wasteful on memory (64k)
1698 smooth_key skey; 1766 smooth_key skey;
1699 int x, y, z; 1767
1700 int last_name; 1768 rc_t *rc = rc_alloc ();
1769 rc_key_t key;
1770 rc_array_t *arr;
1701 1771
1702 // thats current max. sorry. 1772 // thats current max. sorry.
1703 if (sw > 255) sw = 255; 1773 if (sw > 255) sw = 255;
1704 if (sh > 255) sh = 255; 1774 if (sh > 255) sh = 255;
1705 1775
1706 // clear key, in case of extra padding 1776 // clear key, in case of extra padding
1707 memset (&skey, 0, sizeof (skey)); 1777 memset (&skey, 0, sizeof (skey));
1708 1778
1709 glColor4ub (255, 255, 255, 255); 1779 memset (&key, 0, sizeof (key));
1710 1780 key.r = 255;
1711 glEnable (GL_BLEND); 1781 key.g = 255;
1712 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1782 key.b = 255;
1713 glEnable (GL_TEXTURE_2D); 1783 key.a = 255;
1714 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1784 key.mode = GL_QUADS;
1715 1785 key.format = GL_T2F_V3F;
1716 glBegin (GL_QUADS); 1786 key.texname = -1;
1717
1718 last_name = 0;
1719 1787
1720 mx += self->x; 1788 mx += self->x;
1721 my += self->y; 1789 my += self->y;
1722 1790
1723 // first pass: determine smooth_max 1791 // first pass: determine smooth_max
1739 MAX (self->tex [cell->tile [0]].smoothlevel, 1807 MAX (self->tex [cell->tile [0]].smoothlevel,
1740 MAX (self->tex [cell->tile [1]].smoothlevel, 1808 MAX (self->tex [cell->tile [1]].smoothlevel,
1741 self->tex [cell->tile [2]].smoothlevel)); 1809 self->tex [cell->tile [2]].smoothlevel));
1742 } 1810 }
1743 } 1811 }
1812
1813 glEnable (GL_BLEND);
1814 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1815 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1744 1816
1745 for (z = 0; z <= 2; z++) 1817 for (z = 0; z <= 2; z++)
1746 { 1818 {
1747 memset (smooth_level, 0, sizeof (smooth_level)); 1819 memset (smooth_level, 0, sizeof (smooth_level));
1748 1820
1758 tileid tile = cell->tile [z]; 1830 tileid tile = cell->tile [z];
1759 1831
1760 if (tile) 1832 if (tile)
1761 { 1833 {
1762 maptex tex = self->tex [tile]; 1834 maptex tex = self->tex [tile];
1763 int px = (x + 1) * T - tex.w; 1835 int px, py;
1764 int py = (y + 1) * T - tex.h;
1765 1836
1766 // suppressing texture state switches here
1767 // is only moderately effective, but worth the extra effort
1768 if (last_name != tex.name) 1837 if (key.texname != tex.name)
1769 { 1838 {
1770 if (!tex.name) 1839 if (!tex.name)
1771 tex = self->tex [2]; /* missing, replace by noface */ 1840 tex = self->tex [2]; /* missing, replace by noface */
1772 1841
1773 glEnd (); 1842 key.texname = tex.name;
1774 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1843 arr = rc_array (rc, &key);
1775 glBegin (GL_QUADS);
1776 } 1844 }
1777 1845
1778 glTexCoord2f (0 , 0 ); glVertex2f (px , py ); 1846 px = (x + 1) * T - tex.w;
1847 py = (y + 1) * T - tex.h;
1848
1849 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
1779 glTexCoord2f (0 , tex.t); glVertex2f (px , py + tex.h); 1850 rc_t2f_v3f (arr, 0 , tex.t, px , py + tex.h, 0);
1780 glTexCoord2f (tex.s, tex.t); glVertex2f (px + tex.w, py + tex.h); 1851 rc_t2f_v3f (arr, tex.s, tex.t, px + tex.w, py + tex.h, 0);
1781 glTexCoord2f (tex.s, 0 ); glVertex2f (px + tex.w, py ); 1852 rc_t2f_v3f (arr, tex.s, 0 , px + tex.w, py , 0);
1782 1853
1783 if (cell->flags && z == 2) 1854 if (cell->flags && z == 2)
1784 { 1855 {
1856 // overlays such as the speech bubble, probably more to come
1785 if (cell->flags & 1) 1857 if (cell->flags & 1)
1786 { 1858 {
1787 maptex tex = self->tex [1]; 1859 maptex tex = self->tex [1];
1788 int px = x * T + T * 2 / 32; 1860 int px = x * T + T * 2 / 32;
1789 int py = y * T - T * 6 / 32; 1861 int py = y * T - T * 6 / 32;
1790 1862
1863 if (tex.name)
1791 glEnd (); 1864 {
1792 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1865 if (key.texname != tex.name)
1866 {
1867 key.texname = tex.name;
1868 arr = rc_array (rc, &key);
1869 }
1870
1871 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
1872 rc_t2f_v3f (arr, 0 , tex.t, px , py + T, 0);
1873 rc_t2f_v3f (arr, tex.s, tex.t, px + T, py + T, 0);
1874 rc_t2f_v3f (arr, tex.s, 0 , px + T, py , 0);
1793 glBegin (GL_QUADS); 1875 }
1794
1795 glTexCoord2f (0 , 0 ); glVertex2f (px , py );
1796 glTexCoord2f (0 , tex.t); glVertex2f (px , py + T);
1797 glTexCoord2f (tex.s, tex.t); glVertex2f (px + T, py + T);
1798 glTexCoord2f (tex.s, 0 ); glVertex2f (px + T, py );
1799 } 1876 }
1800 } 1877 }
1801 1878
1802 // update smooth hash 1879 // update smooth hash
1803 if (tex.smoothtile) 1880 if (tex.smoothtile)
1839 } 1916 }
1840 } 1917 }
1841 } 1918 }
1842 } 1919 }
1843 1920
1921 rc_draw (rc);
1922 rc_clear (rc);
1923
1844 // go through all smoothlevels, lowest to highest, then draw. 1924 // go through all smoothlevels, lowest to highest, then draw.
1845 // this is basically counting sort 1925 // this is basically counting sort
1846 { 1926 {
1847 int w, b; 1927 int w, b;
1848 1928
1929 glEnable (GL_TEXTURE_2D);
1930 glBegin (GL_QUADS);
1849 for (w = 0; w < 256 / 32; ++w) 1931 for (w = 0; w < 256 / 32; ++w)
1850 { 1932 {
1851 uint32_t smask = smooth_level [w]; 1933 uint32_t smask = smooth_level [w];
1852 if (smask) 1934 if (smask)
1853 for (b = 0; b < 32; ++b) 1935 for (b = 0; b < 32; ++b)
1872 int border = bits & 15; 1954 int border = bits & 15;
1873 int corner = (bits >> 8) & ~(bits >> 4) & 15; 1955 int corner = (bits >> 8) & ~(bits >> 4) & 15;
1874 float dx = tex.s * .0625f; // 16 images/row 1956 float dx = tex.s * .0625f; // 16 images/row
1875 float dy = tex.t * .5f ; // 2 images/column 1957 float dy = tex.t * .5f ; // 2 images/column
1876 1958
1877 // this time naively avoiding texture state changes
1878 // save gobs of state changes.
1879 if (last_name != tex.name) 1959 if (tex.name)
1880 { 1960 {
1961 // this time avoiding texture state changes
1962 // save gobs of state changes.
1881 if (!tex.name) 1963 if (key.texname != tex.name)
1882 continue; // smoothing not yet available 1964 {
1883
1884 glEnd (); 1965 glEnd ();
1885 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1966 glBindTexture (GL_TEXTURE_2D, key.texname = tex.name);
1886 glBegin (GL_QUADS); 1967 glBegin (GL_QUADS);
1887 } 1968 }
1888 1969
1889 if (border) 1970 if (border)
1890 { 1971 {
1891 float ox = border * dx; 1972 float ox = border * dx;
1892 1973
1893 glTexCoord2f (ox , 0.f ); glVertex2f (px , py ); 1974 glTexCoord2f (ox , 0.f ); glVertex2i (px , py );
1894 glTexCoord2f (ox , dy ); glVertex2f (px , py + T); 1975 glTexCoord2f (ox , dy ); glVertex2i (px , py + T);
1895 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py + T); 1976 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py + T);
1896 glTexCoord2f (ox + dx, 0.f ); glVertex2f (px + T, py ); 1977 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + T, py );
1897 } 1978 }
1898 1979
1899 if (corner) 1980 if (corner)
1900 { 1981 {
1901 float ox = corner * dx; 1982 float ox = corner * dx;
1902 1983
1903 glTexCoord2f (ox , dy ); glVertex2f (px , py ); 1984 glTexCoord2f (ox , dy ); glVertex2i (px , py );
1904 glTexCoord2f (ox , dy * 2.f); glVertex2f (px , py + T); 1985 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + T);
1905 glTexCoord2f (ox + dx, dy * 2.f); glVertex2f (px + T, py + T); 1986 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + T, py + T);
1906 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py ); 1987 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py );
1988 }
1907 } 1989 }
1908 } 1990 }
1909 } 1991 }
1910 } 1992 }
1911 } 1993 }
1994
1995 glEnd ();
1996 glDisable (GL_TEXTURE_2D);
1997 key.texname = -1;
1912 } 1998 }
1913 1999
1914 hv_clear (smooth); 2000 hv_clear (smooth);
1915 } 2001 }
1916 2002
1917 glEnd ();
1918
1919 glDisable (GL_TEXTURE_2D);
1920 glDisable (GL_BLEND); 2003 glDisable (GL_BLEND);
2004 rc_free (rc);
1921 2005
1922 // top layer: overlays such as the health bar 2006 // top layer: overlays such as the health bar
1923 for (y = 0; y < sh; y++) 2007 for (y = 0; y < sh; y++)
1924 if (0 <= y + my && y + my < self->rows) 2008 if (0 <= y + my && y + my < self->rows)
1925 { 2009 {
2174 int x, y, z; 2258 int x, y, z;
2175 int w, h; 2259 int w, h;
2176 int x1, y1; 2260 int x1, y1;
2177 2261
2178 if (*data++ != 0) 2262 if (*data++ != 0)
2179 return; /* version mismatch */ 2263 XSRETURN_EMPTY; /* version mismatch */
2180 2264
2181 w = *data++ << 8; w |= *data++; 2265 w = *data++ << 8; w |= *data++;
2182 h = *data++ << 8; h |= *data++; 2266 h = *data++ << 8; h |= *data++;
2183 2267
2184 // we need to do this 'cause we don't keep an absolute coord system for rows 2268 // we need to do this 'cause we don't keep an absolute coord system for rows
2229 } 2313 }
2230 } 2314 }
2231 } 2315 }
2232} 2316}
2233 2317
2318MODULE = CFPlus PACKAGE = CFPlus::RW
2319
2320CFPlus::RW
2321new (SV *class, SV *data_sv)
2322 CODE:
2323{
2324 STRLEN datalen;
2325 char *data = SvPVbyte (data_sv, datalen);
2326
2327 RETVAL = SDL_RWFromConstMem (data, datalen);
2328}
2329 OUTPUT:
2330 RETVAL
2331
2332CFPlus::RW
2333new_from_file (SV *class, const char *path, const char *mode = "rb")
2334 CODE:
2335 RETVAL = SDL_RWFromFile (path, mode);
2336 OUTPUT:
2337 RETVAL
2338
2339# fails on win32:
2340# CFPlus.xs(2268) : error C2059: syntax error : '('
2341#void
2342#close (CFPlus::RW self)
2343# CODE:
2344# (self->(close)) (self);
2345
2346MODULE = CFPlus PACKAGE = CFPlus::Channel
2347
2348PROTOTYPES: DISABLE
2349
2350CFPlus::Channel
2351find ()
2352 CODE:
2353{
2354 RETVAL = Mix_GroupAvailable (-1);
2355
2356 if (RETVAL < 0)
2357 {
2358 RETVAL = Mix_GroupOldest (-1);
2359
2360 if (RETVAL < 0)
2361 XSRETURN_UNDEF;
2362
2363 Mix_HaltChannel (RETVAL);
2364 }
2365
2366 Mix_UnregisterAllEffects (RETVAL);
2367 Mix_Volume (RETVAL, 128);
2368}
2369 OUTPUT:
2370 RETVAL
2371
2372void
2373halt (CFPlus::Channel self)
2374 CODE:
2375 Mix_HaltChannel (self);
2376
2377void
2378expire (CFPlus::Channel self, int ticks = -1)
2379 CODE:
2380 Mix_ExpireChannel (self, ticks);
2381
2382void
2383fade_out (CFPlus::Channel self, int ticks = -1)
2384 CODE:
2385 Mix_FadeOutChannel (self, ticks);
2386
2387int
2388volume (CFPlus::Channel self, int volume)
2389 CODE:
2390 RETVAL = Mix_Volume (self, CLAMP (volume, 0, 128));
2391 OUTPUT:
2392 RETVAL
2393
2394void
2395unregister_all_effects (CFPlus::Channel self)
2396 CODE:
2397 Mix_UnregisterAllEffects (self);
2398
2399void
2400set_panning (CFPlus::Channel self, int left, int right)
2401 CODE:
2402 left = CLAMP (left , 0, 255);
2403 right = CLAMP (right, 0, 255);
2404 Mix_SetPanning (self, left, right);
2405
2406void
2407set_distance (CFPlus::Channel self, int distance)
2408 CODE:
2409 Mix_SetDistance (self, CLAMP (distance, 0, 255));
2410
2411void
2412set_position (CFPlus::Channel self, int angle, int distance)
2413 CODE:
2414
2415void
2416set_position_r (CFPlus::Channel self, int dx, int dy, int maxdistance)
2417 CODE:
2418{
2419 int distance = sqrtf (dx * dx + dy * dy) * (255.f / sqrtf (maxdistance * maxdistance));
2420 int angle = 360 + (int)roundf (atan2f (dx, -dy) * 180.f / (float)M_PI);
2421 Mix_SetPosition (self, angle, CLAMP (distance, 0, 255));
2422}
2423
2424void
2425set_reverse_stereo (CFPlus::Channel self, int flip)
2426 CODE:
2427 Mix_SetReverseStereo (self, flip);
2428
2234MODULE = CFPlus PACKAGE = CFPlus::MixChunk 2429MODULE = CFPlus PACKAGE = CFPlus::MixChunk
2235 2430
2236PROTOTYPES: DISABLE 2431PROTOTYPES: DISABLE
2237 2432
2238CFPlus::MixChunk 2433CFPlus::MixChunk
2239new_from_file (SV *class, char *path) 2434new (SV *class, CFPlus::RW rwops)
2240 CODE: 2435 CODE:
2241 RETVAL = Mix_LoadWAV (path); 2436 RETVAL = Mix_LoadWAV_RW (rwops, 1);
2242 OUTPUT: 2437 OUTPUT:
2243 RETVAL 2438 RETVAL
2244 2439
2245void 2440void
2246DESTROY (CFPlus::MixChunk self) 2441DESTROY (CFPlus::MixChunk self)
2248 Mix_FreeChunk (self); 2443 Mix_FreeChunk (self);
2249 2444
2250int 2445int
2251volume (CFPlus::MixChunk self, int volume = -1) 2446volume (CFPlus::MixChunk self, int volume = -1)
2252 CODE: 2447 CODE:
2448 if (items > 1)
2449 volume = CLAMP (volume, 0, 128);
2253 RETVAL = Mix_VolumeChunk (self, volume); 2450 RETVAL = Mix_VolumeChunk (self, volume);
2254 OUTPUT: 2451 OUTPUT:
2255 RETVAL 2452 RETVAL
2256 2453
2257int 2454CFPlus::Channel
2258play (CFPlus::MixChunk self, int channel = -1, int loops = 0, int ticks = -1) 2455play (CFPlus::MixChunk self, CFPlus::Channel channel = -1, int loops = 0, int ticks = -1)
2259 CODE: 2456 CODE:
2457{
2260 RETVAL = Mix_PlayChannelTimed (channel, self, loops, ticks); 2458 RETVAL = Mix_PlayChannelTimed (channel, self, loops, ticks);
2459
2460 if (RETVAL < 0)
2461 XSRETURN_UNDEF;
2462
2463 if (channel < 0)
2464 {
2465 Mix_UnregisterAllEffects (RETVAL);
2466 Mix_Volume (RETVAL, 128);
2467 }
2468}
2261 OUTPUT: 2469 OUTPUT:
2262 RETVAL 2470 RETVAL
2263 2471
2264MODULE = CFPlus PACKAGE = CFPlus::MixMusic 2472MODULE = CFPlus PACKAGE = CFPlus::MixMusic
2265 2473
2266int 2474int
2267volume (int volume = -1) 2475volume (int volume = -1)
2268 PROTOTYPE: ;$ 2476 PROTOTYPE: ;$
2269 CODE: 2477 CODE:
2478 if (items > 0)
2479 volume = CLAMP (volume, 0, 128);
2270 RETVAL = Mix_VolumeMusic (volume); 2480 RETVAL = Mix_VolumeMusic (volume);
2271 OUTPUT: 2481 OUTPUT:
2272 RETVAL 2482 RETVAL
2273 2483
2274int 2484void
2275fade_out (int ms) 2485fade_out (int ms)
2276 CODE: 2486 CODE:
2277 RETVAL = Mix_FadeOutMusic (ms); 2487 Mix_FadeOutMusic (ms);
2278 OUTPUT: 2488
2279 RETVAL 2489void
2490halt ()
2491 CODE:
2492 Mix_HaltMusic ();
2280 2493
2281CFPlus::MixMusic 2494CFPlus::MixMusic
2282new_from_file (SV *class, char *path) 2495new (SV *class, CFPlus::RW rwops)
2283 CODE: 2496 CODE:
2284 RETVAL = Mix_LoadMUS (path); 2497 RETVAL = Mix_LoadMUS_RW (rwops);
2285 OUTPUT: 2498 OUTPUT:
2286 RETVAL 2499 RETVAL
2287 2500
2288void 2501void
2289DESTROY (CFPlus::MixMusic self) 2502DESTROY (CFPlus::MixMusic self)
2295 CODE: 2508 CODE:
2296 RETVAL = Mix_PlayMusic (self, loops); 2509 RETVAL = Mix_PlayMusic (self, loops);
2297 OUTPUT: 2510 OUTPUT:
2298 RETVAL 2511 RETVAL
2299 2512
2300int 2513void
2301fade_in_pos (CFPlus::MixMusic self, int loops, int ms, double position) 2514fade_in_pos (CFPlus::MixMusic self, int loops, int ms, double position)
2302 CODE: 2515 CODE:
2303 RETVAL = Mix_FadeInMusicPos (self, loops, ms, position); 2516 Mix_FadeInMusicPos (self, loops, ms, position);
2304 OUTPUT:
2305 RETVAL
2306 2517
2307MODULE = CFPlus PACKAGE = CFPlus::OpenGL 2518MODULE = CFPlus PACKAGE = CFPlus::OpenGL
2308 2519
2309PROTOTYPES: ENABLE 2520PROTOTYPES: ENABLE
2310 2521
2353 const_iv (GL_INTENSITY), 2564 const_iv (GL_INTENSITY),
2354 const_iv (GL_LUMINANCE), 2565 const_iv (GL_LUMINANCE),
2355 const_iv (GL_LUMINANCE_ALPHA), 2566 const_iv (GL_LUMINANCE_ALPHA),
2356 const_iv (GL_FLOAT), 2567 const_iv (GL_FLOAT),
2357 const_iv (GL_UNSIGNED_INT_8_8_8_8_REV), 2568 const_iv (GL_UNSIGNED_INT_8_8_8_8_REV),
2569 const_iv (GL_COMPRESSED_ALPHA_ARB),
2570 const_iv (GL_COMPRESSED_LUMINANCE_ARB),
2571 const_iv (GL_COMPRESSED_LUMINANCE_ALPHA_ARB),
2572 const_iv (GL_COMPRESSED_INTENSITY_ARB),
2573 const_iv (GL_COMPRESSED_RGB_ARB),
2574 const_iv (GL_COMPRESSED_RGBA_ARB),
2358 const_iv (GL_COMPILE), 2575 const_iv (GL_COMPILE),
2359 const_iv (GL_PROXY_TEXTURE_1D), 2576 const_iv (GL_PROXY_TEXTURE_1D),
2360 const_iv (GL_PROXY_TEXTURE_2D), 2577 const_iv (GL_PROXY_TEXTURE_2D),
2361 const_iv (GL_TEXTURE_1D), 2578 const_iv (GL_TEXTURE_1D),
2362 const_iv (GL_TEXTURE_2D), 2579 const_iv (GL_TEXTURE_2D),
2401 const_iv (GL_PERSPECTIVE_CORRECTION_HINT), 2618 const_iv (GL_PERSPECTIVE_CORRECTION_HINT),
2402 const_iv (GL_POINT_SMOOTH_HINT), 2619 const_iv (GL_POINT_SMOOTH_HINT),
2403 const_iv (GL_LINE_SMOOTH_HINT), 2620 const_iv (GL_LINE_SMOOTH_HINT),
2404 const_iv (GL_POLYGON_SMOOTH_HINT), 2621 const_iv (GL_POLYGON_SMOOTH_HINT),
2405 const_iv (GL_GENERATE_MIPMAP_HINT), 2622 const_iv (GL_GENERATE_MIPMAP_HINT),
2623 const_iv (GL_TEXTURE_COMPRESSION_HINT),
2406 const_iv (GL_FASTEST), 2624 const_iv (GL_FASTEST),
2407 const_iv (GL_DONT_CARE), 2625 const_iv (GL_DONT_CARE),
2408 const_iv (GL_NICEST), 2626 const_iv (GL_NICEST),
2409 const_iv (GL_V2F), 2627 const_iv (GL_V2F),
2410 const_iv (GL_V3F), 2628 const_iv (GL_V3F),
2418 2636
2419 texture_av = newAV (); 2637 texture_av = newAV ();
2420 AvREAL_off (texture_av); 2638 AvREAL_off (texture_av);
2421} 2639}
2422 2640
2641void
2642disable_GL_EXT_blend_func_separate ()
2643 CODE:
2644 gl.BlendFuncSeparate = 0;
2645 gl.BlendFuncSeparateEXT = 0;
2646
2423char * 2647char *
2424gl_vendor () 2648gl_vendor ()
2425 CODE: 2649 CODE:
2426 RETVAL = (char *)glGetString (GL_VENDOR); 2650 RETVAL = (char *)glGetString (GL_VENDOR);
2427 OUTPUT: 2651 OUTPUT:
2544 2768
2545void glTexCoord (float s, float t) 2769void glTexCoord (float s, float t)
2546 CODE: 2770 CODE:
2547 glTexCoord2f (s, t); 2771 glTexCoord2f (s, t);
2548 2772
2773void glRect (float x1, float y1, float x2, float y2)
2774 CODE:
2775 glRectf (x1, y1, x2, y2);
2776
2777void glRect_lineloop (float x1, float y1, float x2, float y2)
2778 CODE:
2779 glBegin (GL_LINE_LOOP);
2780 glVertex2f (x1, y1);
2781 glVertex2f (x2, y1);
2782 glVertex2f (x2, y2);
2783 glVertex2f (x1, y2);
2784 glEnd ();
2785
2549PROTOTYPES: ENABLE 2786PROTOTYPES: ENABLE
2550 2787
2551void glBegin (int mode) 2788void glBegin (int mode)
2552 2789
2553void glEnd () 2790void glEnd ()
2626MODULE = CFPlus PACKAGE = CFPlus::UI::Base 2863MODULE = CFPlus PACKAGE = CFPlus::UI::Base
2627 2864
2628PROTOTYPES: DISABLE 2865PROTOTYPES: DISABLE
2629 2866
2630void 2867void
2631find_widget (SV *widget, NV x, NV y) 2868find_widget (SV *self, NV x, NV y)
2632 PPCODE: 2869 PPCODE:
2633{ 2870{
2634 if (within_widget (widget, x, y)) 2871 if (within_widget (self, x, y))
2635 XPUSHs (widget); 2872 XPUSHs (self);
2636} 2873}
2637 2874
2875BOOT:
2876{
2877 hover_gv = gv_fetchpv ("CFPlus::UI::HOVER", 1, SVt_NV);
2878
2879 draw_x_gv = gv_fetchpv ("CFPlus::UI::Base::draw_x", 1, SVt_NV);
2880 draw_y_gv = gv_fetchpv ("CFPlus::UI::Base::draw_y", 1, SVt_NV);
2881 draw_w_gv = gv_fetchpv ("CFPlus::UI::Base::draw_w", 1, SVt_NV);
2882 draw_h_gv = gv_fetchpv ("CFPlus::UI::Base::draw_h", 1, SVt_NV);
2883}
2884
2885void
2886draw (SV *self)
2887 CODE:
2888{
2889 HV *hv;
2890 SV **svp;
2891 NV x, y, w, h;
2892 SV *draw_x_sv = GvSV (draw_x_gv);
2893 SV *draw_y_sv = GvSV (draw_y_gv);
2894 SV *draw_w_sv = GvSV (draw_w_gv);
2895 SV *draw_h_sv = GvSV (draw_h_gv);
2896 double draw_x, draw_y;
2897
2898 if (!SvROK (self))
2899 croak ("CFPlus::Base::draw: %s not a reference", SvPV_nolen (self));
2900
2901 hv = (HV *)SvRV (self);
2902
2903 if (SvTYPE (hv) != SVt_PVHV)
2904 croak ("CFPlus::Base::draw: %s not a hashref", SvPV_nolen (self));
2905
2906 svp = hv_fetch (hv, "w", 1, 0); w = svp ? SvNV (*svp) : 0.;
2907 svp = hv_fetch (hv, "h", 1, 0); h = svp ? SvNV (*svp) : 0.;
2908
2909 if (!h || !w)
2910 XSRETURN_EMPTY;
2911
2912 svp = hv_fetch (hv, "x", 1, 0); x = svp ? SvNV (*svp) : 0.;
2913 svp = hv_fetch (hv, "y", 1, 0); y = svp ? SvNV (*svp) : 0.;
2914
2915 draw_x = SvNV (draw_x_sv) + x;
2916 draw_y = SvNV (draw_y_sv) + y;
2917
2918 if (draw_x + w < 0 || draw_x >= SvNV (draw_w_sv)
2919 || draw_y + h < 0 || draw_y >= SvNV (draw_h_sv))
2920 XSRETURN_EMPTY;
2921
2922 sv_setnv (draw_x_sv, draw_x);
2923 sv_setnv (draw_y_sv, draw_y);
2924
2925 glPushMatrix ();
2926 glTranslated (x, y, 0);
2927
2928 if (SvROK (GvSV (hover_gv)) && SvRV (GvSV (hover_gv)) == (SV *)hv)
2929 {
2930 svp = hv_fetch (hv, "can_hover", sizeof ("can_hover") - 1, 0);
2931
2932 if (svp && SvTRUE (*svp))
2933 {
2934 glColor4f (1.0f * 0.2f, 0.8f * 0.2f, 0.5f * 0.2f, 0.2f);
2935 glEnable (GL_BLEND);
2936 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
2937 glBegin (GL_QUADS);
2938 glVertex2f (0, 0);
2939 glVertex2f (w, 0);
2940 glVertex2f (w, h);
2941 glVertex2f (0, h);
2942 glEnd ();
2943 glDisable (GL_BLEND);
2944 }
2945 }
2946#if 0
2947 // draw borders, for debugging
2948 glPushMatrix ();
2949 glColor4f (1., 1., 0., 1.);
2950 glTranslatef (.5, .5, 0.);
2951 glBegin (GL_LINE_LOOP);
2952 glVertex2f (0 , 0);
2953 glVertex2f (w - 1, 0);
2954 glVertex2f (w - 1, h - 1);
2955 glVertex2f (0 , h - 1);
2956 glEnd ();
2957 glPopMatrix ();
2958#endif
2959 PUSHMARK (SP);
2960 XPUSHs (self);
2961 PUTBACK;
2962 call_method ("_draw", G_VOID | G_DISCARD);
2963 SPAGAIN;
2964
2965 glPopMatrix ();
2966
2967 draw_x = draw_x - x; sv_setnv (draw_x_sv, draw_x);
2968 draw_y = draw_y - y; sv_setnv (draw_y_sv, draw_y);
2969}
2970

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines