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.175 by root, Fri Apr 6 08:09:42 2007 UTC vs.
Revision 1.181 by root, Mon Apr 16 21:06:36 2007 UTC

163typedef struct { 163typedef struct {
164 int name; 164 int name;
165 int w, h; 165 int w, h;
166 float s, t; 166 float s, t;
167 uint8_t r, g, b, a; 167 uint8_t r, g, b, a;
168 tileid smoothtile;
169 uint8_t smoothlevel;
168} maptex; 170} maptex;
169 171
170typedef struct { 172typedef struct {
171 uint32_t player; 173 uint32_t player;
172 tileid tile[3]; 174 tileid tile[3];
173 uint16_t darkness; 175 uint16_t darkness;
174 uint8_t stat_width, stat_hp, flags; 176 uint8_t stat_width, stat_hp, flags, smoothmax;
175} mapcell; 177} mapcell;
176 178
177typedef struct { 179typedef struct {
178 int32_t c0, c1; 180 int32_t c0, c1;
179 mapcell *col; 181 mapcell *col;
333 cell->stat_hp = 0; 335 cell->stat_hp = 0;
334 cell->flags = 0; 336 cell->flags = 0;
335 cell->player = 0; 337 cell->player = 0;
336 } 338 }
337 } 339 }
340}
341
342typedef struct {
343 tileid tile;
344 uint8_t x, y, level;
345} smooth_key;
346
347static void
348smooth_or_bits (HV *hv, smooth_key *key, IV bits)
349{
350 SV **sv = hv_fetch (hv, (char *)key, sizeof (*key), 1);
351
352 if (SvIOK (*sv))
353 SvIV_set (*sv, SvIVX (*sv) | bits);
354 else
355 sv_setiv (*sv, bits);
338} 356}
339 357
340static void 358static void
341music_finished (void) 359music_finished (void)
342{ 360{
683Mix_AllocateChannels (int numchans = -1) 701Mix_AllocateChannels (int numchans = -1)
684 702
685void 703void
686lowdelay (int fd, int val = 1) 704lowdelay (int fd, int val = 1)
687 CODE: 705 CODE:
688#ifndef _WIN32
689 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof (val)); 706 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&val, sizeof (val));
690#endif
691 707
692void 708void
693win32_proxy_info () 709win32_proxy_info ()
694 PPCODE: 710 PPCODE:
695{ 711{
1295 need_facenum (self, face); self->face2tile [face] = tile; 1311 need_facenum (self, face); self->face2tile [face] = tile;
1296 need_texid (self, tile); 1312 need_texid (self, tile);
1297} 1313}
1298 1314
1299void 1315void
1316set_smooth (CFPlus::Map self, int face, int smooth, int level)
1317 CODE:
1318{
1319 tileid texid;
1320 maptex *tex;
1321
1322 if (face < 0 || face >= self->faces)
1323 return;
1324
1325 if (smooth < 0 || smooth >= self->faces)
1326 return;
1327
1328 texid = self->face2tile [face];
1329
1330 if (!texid)
1331 return;
1332
1333 tex = self->tex + texid;
1334 tex->smoothtile = self->face2tile [smooth];
1335 tex->smoothlevel = level;
1336}
1337
1338void
1300set_texture (CFPlus::Map self, int texid, int name, int w, int h, float s, float t, int r, int g, int b, int a) 1339set_texture (CFPlus::Map self, int texid, int name, int w, int h, float s, float t, int r, int g, int b, int a)
1301 CODE: 1340 CODE:
1302{ 1341{
1303 need_texid (self, texid); 1342 need_texid (self, texid);
1304 1343
1524 1563
1525void 1564void
1526draw (CFPlus::Map self, int mx, int my, int sw, int sh, int T) 1565draw (CFPlus::Map self, int mx, int my, int sw, int sh, int T)
1527 CODE: 1566 CODE:
1528{ 1567{
1568 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
1569 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level
1570 static uint8_t smooth_max[256][256]; // egad, fats and wasteful on memory (64k)
1571 smooth_key skey;
1529 int x, y, z; 1572 int x, y, z;
1530 int last_name; 1573 int last_name;
1574
1575 // thats current max. sorry.
1576 if (sw > 255) sw = 255;
1577 if (sh > 255) sh = 255;
1578
1579 // clear key, in case of extra padding
1580 memset (&skey, 0, sizeof (skey));
1531 1581
1532 glColor4ub (255, 255, 255, 255); 1582 glColor4ub (255, 255, 255, 255);
1533 1583
1534 glEnable (GL_BLEND); 1584 glEnable (GL_BLEND);
1535 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1585 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1541 last_name = 0; 1591 last_name = 0;
1542 1592
1543 mx += self->x; 1593 mx += self->x;
1544 my += self->y; 1594 my += self->y;
1545 1595
1596 // first pass: determine smooth_max
1597 // rather ugly, if you ask me
1598 // could also be stored inside mapcell and updated on change
1599 memset (smooth_max, 0, sizeof (smooth_max));
1600
1601 for (y = 0; y < sh; y++)
1602 if (0 <= y + my && y + my < self->rows)
1603 {
1604 maprow *row = self->row + (y + my);
1605
1606 for (x = 0; x < sw; x++)
1607 if (row->c0 <= x + mx && x + mx < row->c1)
1608 {
1609 mapcell *cell = row->col + (x + mx - row->c0);
1610
1611 smooth_max[x + 1][y + 1] =
1612 MAX (self->tex [cell->tile [0]].smoothlevel,
1613 MAX (self->tex [cell->tile [1]].smoothlevel,
1614 self->tex [cell->tile [2]].smoothlevel));
1615 }
1616 }
1617
1546 for (z = 0; z < 3; z++) 1618 for (z = 0; z <= 2; z++)
1619 {
1620 memset (smooth_level, 0, sizeof (smooth_level));
1621
1547 for (y = 0; y < sh; y++) 1622 for (y = 0; y < sh; y++)
1548 if (0 <= y + my && y + my < self->rows) 1623 if (0 <= y + my && y + my < self->rows)
1549 { 1624 {
1550 maprow *row = self->row + (y + my); 1625 maprow *row = self->row + (y + my);
1551 1626
1552 for (x = 0; x < sw; x++) 1627 for (x = 0; x < sw; x++)
1553 if (row->c0 <= x + mx && x + mx < row->c1) 1628 if (row->c0 <= x + mx && x + mx < row->c1)
1554 { 1629 {
1555 mapcell *cell = row->col + (x + mx - row->c0); 1630 mapcell *cell = row->col + (x + mx - row->c0);
1556 tileid tile = cell->tile [z]; 1631 tileid tile = cell->tile [z];
1632
1633 if (tile)
1634 {
1635 maptex tex = self->tex [tile];
1636 int px = (x + 1) * T - tex.w;
1637 int py = (y + 1) * T - tex.h;
1638
1639 // suppressing texture state switches here
1640 // is only moderately effective, but worth the extra effort
1641 if (last_name != tex.name)
1642 {
1643 if (!tex.name)
1644 tex = self->tex [2]; /* missing, replace by noface */
1645
1646 glEnd ();
1647 glBindTexture (GL_TEXTURE_2D, last_name = tex.name);
1648 glBegin (GL_QUADS);
1649 }
1650
1651 glTexCoord2f (0 , 0 ); glVertex2f (px , py );
1652 glTexCoord2f (0 , tex.t); glVertex2f (px , py + tex.h);
1653 glTexCoord2f (tex.s, tex.t); glVertex2f (px + tex.w, py + tex.h);
1654 glTexCoord2f (tex.s, 0 ); glVertex2f (px + tex.w, py );
1655
1656 if (cell->flags && z == 2)
1657 {
1658 if (cell->flags & 1)
1659 {
1660 maptex tex = self->tex [1];
1661 int px = x * T + T * 2 / 32;
1662 int py = y * T - T * 6 / 32;
1663
1664 glEnd ();
1665 glBindTexture (GL_TEXTURE_2D, last_name = tex.name);
1666 glBegin (GL_QUADS);
1667
1668 glTexCoord2f (0 , 0 ); glVertex2f (px , py );
1669 glTexCoord2f (0 , tex.t); glVertex2f (px , py + T);
1670 glTexCoord2f (tex.s, tex.t); glVertex2f (px + T, py + T);
1671 glTexCoord2f (tex.s, 0 ); glVertex2f (px + T, py );
1672 }
1673 }
1674
1675 // update smooth hash
1676 if (tex.smoothtile)
1677 {
1678 skey.tile = tex.smoothtile;
1679 skey.level = tex.smoothlevel;
1680
1681 smooth_level [tex.smoothlevel >> 5] |= ((uint32_t)1) << (tex.smoothlevel & 31);
1682
1683 // add bits to current tile and all neighbours. skey.x|y is
1684 // shifted +1|+1 so we always stay positive.
1685
1686 // bits is ___n cccc CCCC bbbb
1687 // n do not draw borders&corners
1688 // c draw these corners, but...
1689 // C ... not these
1690 // b draw these borders
1691
1692 // borders: 1 ┃· 2 ━━ 4 ·┃ 8 ··
1693 // ┃· ·· ·┃ ━━
1694
1695 // corners: 1 ┛· 2 ·┗ 4 ·· 8 ··
1696 // ·· ·· ·┏ ┓·
1697
1698 // full tile
1699 skey.x = x + 1; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x1000);
1700
1701 // borders
1702 skey.x = x + 2; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x0091);
1703 skey.x = x + 1; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0032);
1704 skey.x = x ; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x0064);
1705 skey.x = x + 1; skey.y = y ; smooth_or_bits (smooth, &skey, 0x00c8);
1706
1707 // corners
1708 skey.x = x + 2; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0100);
1709 skey.x = x ; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0200);
1710 skey.x = x ; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0400);
1711 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0800);
1712 }
1713 }
1557 1714 }
1715 }
1716
1717 // go through all smoothlevels, lowest to highest, then draw.
1718 // this is basically counting sort
1719 {
1720 int w, b;
1721
1722 for (w = 0; w < 256 / 32; ++w)
1723 {
1724 uint32_t smask = smooth_level [w];
1558 if (tile) 1725 if (smask)
1726 for (b = 0; b < 32; ++b)
1727 if (smask & (((uint32_t)1) << b))
1559 { 1728 {
1560 maptex tex = self->tex [tile]; 1729 int level = (w << 5) | b;
1561 int px = (x + 1) * T - tex.w; 1730 HE *he;
1562 int py = (y + 1) * T - tex.h;
1563 1731
1564 if (last_name != tex.name) 1732 hv_iterinit (smooth);
1733 while ((he = hv_iternext (smooth)))
1565 { 1734 {
1735 smooth_key *skey = (smooth_key *)HeKEY (he);
1736 IV bits = SvIVX (HeVAL (he));
1737
1566 if (!tex.name) 1738 if (!(bits & 0x1000)
1567 tex = self->tex [2]; /* missing, replace by noface */ 1739 && skey->level == level
1568 1740 && level >= smooth_max [skey->x][skey->y])
1569 glEnd ();
1570 glBindTexture (GL_TEXTURE_2D, last_name = tex.name);
1571 glBegin (GL_QUADS);
1572 }
1573
1574 glTexCoord2f (0 , 0 ); glVertex2f (px , py );
1575 glTexCoord2f (0 , tex.t); glVertex2f (px , py + tex.h);
1576 glTexCoord2f (tex.s, tex.t); glVertex2f (px + tex.w, py + tex.h);
1577 glTexCoord2f (tex.s, 0 ); glVertex2f (px + tex.w, py );
1578
1579 if (cell->flags && z == 2)
1580 {
1581 if (cell->flags & 1)
1582 { 1741 {
1583 maptex tex = self->tex [1]; 1742 maptex tex = self->tex [skey->tile];
1584 int px = x * T + T * 2 / 32; 1743 int px = (((int)skey->x) - 1) * T;
1585 int py = y * T - T * 6 / 32; 1744 int py = (((int)skey->y) - 1) * T;
1745 int border = bits & 15;
1746 int corner = (bits >> 8) & ~(bits >> 4) & 15;
1747 float dx = tex.s * .0625f; // 16 images/row
1748 float dy = tex.t * .5f ; // 2 images/column
1586 1749
1750 // this time naively avoiding texture state changes
1751 // save gobs of state changes.
1752 if (last_name != tex.name)
1753 {
1754 if (!tex.name)
1755 continue; // smoothing not yet available
1756
1587 glEnd (); 1757 glEnd ();
1588 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1758 glBindTexture (GL_TEXTURE_2D, last_name = tex.name);
1589 glBegin (GL_QUADS); 1759 glBegin (GL_QUADS);
1760 }
1590 1761
1762 if (border)
1763 {
1764 float ox = border * dx;
1765
1766 glTexCoord2f (ox , 0.f ); glVertex2f (px , py );
1767 glTexCoord2f (ox , dy ); glVertex2f (px , py + T);
1768 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py + T);
1769 glTexCoord2f (ox + dx, 0.f ); glVertex2f (px + T, py );
1770 }
1771
1772 if (corner)
1773 {
1774 float ox = corner * dx;
1775
1591 glTexCoord2f (0 , 0 ); glVertex2f (px , py ); 1776 glTexCoord2f (ox , dy ); glVertex2f (px , py );
1592 glTexCoord2f (0 , tex.t); glVertex2f (px , py + T); 1777 glTexCoord2f (ox , dy * 2.f); glVertex2f (px , py + T);
1593 glTexCoord2f (tex.s, tex.t); glVertex2f (px + T, py + T); 1778 glTexCoord2f (ox + dx, dy * 2.f); glVertex2f (px + T, py + T);
1594 glTexCoord2f (tex.s, 0 ); glVertex2f (px + T, py ); 1779 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py );
1780 }
1595 } 1781 }
1596 } 1782 }
1597 } 1783 }
1598 }
1599 } 1784 }
1785 }
1786
1787 hv_clear (smooth);
1788 }
1600 1789
1601 glEnd (); 1790 glEnd ();
1602 1791
1603 glDisable (GL_TEXTURE_2D); 1792 glDisable (GL_TEXTURE_2D);
1604 glDisable (GL_BLEND); 1793 glDisable (GL_BLEND);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines