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.176 by root, Tue Apr 10 09:39:48 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{
1295 need_facenum (self, face); self->face2tile [face] = tile; 1313 need_facenum (self, face); self->face2tile [face] = tile;
1296 need_texid (self, tile); 1314 need_texid (self, tile);
1297} 1315}
1298 1316
1299void 1317void
1318set_smooth (CFPlus::Map self, int face, int smooth, int level)
1319 CODE:
1320{
1321 tileid texid;
1322 maptex *tex;
1323
1324 if (face < 0 || face >= self->faces)
1325 return;
1326
1327 if (smooth < 0 || smooth >= self->faces)
1328 return;
1329
1330 texid = self->face2tile [face];
1331
1332 if (!texid)
1333 return;
1334
1335 tex = self->tex + texid;
1336 tex->smoothtile = self->face2tile [smooth];
1337 tex->smoothlevel = level;
1338}
1339
1340void
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) 1341set_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: 1342 CODE:
1302{ 1343{
1303 need_texid (self, texid); 1344 need_texid (self, texid);
1304 1345
1524 1565
1525void 1566void
1526draw (CFPlus::Map self, int mx, int my, int sw, int sh, int T) 1567draw (CFPlus::Map self, int mx, int my, int sw, int sh, int T)
1527 CODE: 1568 CODE:
1528{ 1569{
1570 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
1571 uint32_t smooth_level[256 / 32]; // one bit for every possible smooth level
1572 uint8_t smooth_max[256][256];
1573 smooth_key skey;
1529 int x, y, z; 1574 int x, y, z;
1530 int last_name; 1575 int last_name;
1576
1577 // thats current max. sorry.
1578 if (sw > 255) sw = 255;
1579 if (sh > 255) sh = 255;
1580
1581 // clear key, in case of extra padding
1582 memset (&skey, 0, sizeof (skey));
1531 1583
1532 glColor4ub (255, 255, 255, 255); 1584 glColor4ub (255, 255, 255, 255);
1533 1585
1534 glEnable (GL_BLEND); 1586 glEnable (GL_BLEND);
1535 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1587 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1541 last_name = 0; 1593 last_name = 0;
1542 1594
1543 mx += self->x; 1595 mx += self->x;
1544 my += self->y; 1596 my += self->y;
1545 1597
1598 // first pass: determine smooth_max
1599 // rather ugly, if you ask me
1600 // could also be stored inside mapcell and updated on change
1601 memset (smooth_max, 0, sizeof (smooth_max));
1602
1603 for (y = 0; y < sh; y++)
1604 if (0 <= y + my && y + my < self->rows)
1605 {
1606 maprow *row = self->row + (y + my);
1607
1608 for (x = 0; x < sw; x++)
1609 if (row->c0 <= x + mx && x + mx < row->c1)
1610 {
1611 mapcell *cell = row->col + (x + mx - row->c0);
1612
1613 for (z = 0; z <= 2; z++)
1614 {
1615 uint8_t level = self->tex [cell->tile [z]].smoothlevel;
1616 if (level > smooth_max [x + 1][y + 1])
1617 smooth_max [x + 1][y + 1] = level;
1618 }
1619 }
1620 }
1621
1546 for (z = 0; z < 3; z++) 1622 for (z = 0; z <= 2; z++)
1623 {
1624 memset (smooth_level, 0, sizeof (smooth_level));
1625
1547 for (y = 0; y < sh; y++) 1626 for (y = 0; y < sh; y++)
1548 if (0 <= y + my && y + my < self->rows) 1627 if (0 <= y + my && y + my < self->rows)
1549 { 1628 {
1550 maprow *row = self->row + (y + my); 1629 maprow *row = self->row + (y + my);
1551 1630
1552 for (x = 0; x < sw; x++) 1631 for (x = 0; x < sw; x++)
1553 if (row->c0 <= x + mx && x + mx < row->c1) 1632 if (row->c0 <= x + mx && x + mx < row->c1)
1554 { 1633 {
1555 mapcell *cell = row->col + (x + mx - row->c0); 1634 mapcell *cell = row->col + (x + mx - row->c0);
1556 tileid tile = cell->tile [z]; 1635 tileid tile = cell->tile [z];
1636
1637 if (tile)
1638 {
1639 maptex tex = self->tex [tile];
1640 int px = (x + 1) * T - tex.w;
1641 int py = (y + 1) * T - tex.h;
1642
1643 // suppressing texture state switches here
1644 // is only moderately effective, but worth the extra effort
1645 if (last_name != tex.name)
1646 {
1647 if (!tex.name)
1648 tex = self->tex [2]; /* missing, replace by noface */
1649
1650 glEnd ();
1651 glBindTexture (GL_TEXTURE_2D, last_name = tex.name);
1652 glBegin (GL_QUADS);
1653 }
1654
1655 glTexCoord2f (0 , 0 ); glVertex2f (px , py );
1656 glTexCoord2f (0 , tex.t); glVertex2f (px , py + tex.h);
1657 glTexCoord2f (tex.s, tex.t); glVertex2f (px + tex.w, py + tex.h);
1658 glTexCoord2f (tex.s, 0 ); glVertex2f (px + tex.w, py );
1659
1660 if (cell->flags && z == 2)
1661 {
1662 if (cell->flags & 1)
1663 {
1664 maptex tex = self->tex [1];
1665 int px = x * T + T * 2 / 32;
1666 int py = y * T - T * 6 / 32;
1667
1668 glEnd ();
1669 glBindTexture (GL_TEXTURE_2D, last_name = tex.name);
1670 glBegin (GL_QUADS);
1671
1672 glTexCoord2f (0 , 0 ); glVertex2f (px , py );
1673 glTexCoord2f (0 , tex.t); glVertex2f (px , py + T);
1674 glTexCoord2f (tex.s, tex.t); glVertex2f (px + T, py + T);
1675 glTexCoord2f (tex.s, 0 ); glVertex2f (px + T, py );
1676 }
1677 }
1678
1679 // update smooth hash
1680 if (tex.smoothtile)
1681 {
1682 skey.tile = tex.smoothtile;
1683 skey.level = tex.smoothlevel;
1684
1685 smooth_level [tex.smoothlevel >> 5] |= ((uint32_t)1) << (tex.smoothlevel & 31);
1686
1687 // add bits to current tile and all neighbours. skey.x|y is
1688 // shifted +1|+1 so we always stay positive.
1689
1690 // full tile
1691 skey.x = x + 1; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x1000);
1692
1693 // borders
1694 skey.x = x + 2; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x0031);
1695 skey.x = x + 1; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0092);
1696 skey.x = x ; skey.y = y + 1; smooth_or_bits (smooth, &skey, 0x0064);
1697 skey.x = x + 1; skey.y = y ; smooth_or_bits (smooth, &skey, 0x00c8);
1698
1699 // corners
1700 skey.x = x + 2; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0100);
1701 skey.x = x ; skey.y = y + 2; smooth_or_bits (smooth, &skey, 0x0200);
1702 skey.x = x ; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0400);
1703 skey.x = x + 2; skey.y = y ; smooth_or_bits (smooth, &skey, 0x0800);
1704 }
1705 }
1557 1706 }
1707 }
1708
1709 // go through all smoothlevels, lowest to highest, then draw
1710 // this is basically counting sort
1711 {
1712 int w, b;
1713
1714 for (w = 0; w < 256 / 32; ++w)
1715 {
1716 uint32_t smask = smooth_level [w];
1558 if (tile) 1717 if (smask)
1718 for (b = 0; b < 32; ++b)
1719 if (smask & (((uint32_t)1) << b))
1559 { 1720 {
1560 maptex tex = self->tex [tile]; 1721 int level = (w << 5) | b;
1561 int px = (x + 1) * T - tex.w; 1722 HE *he;
1562 int py = (y + 1) * T - tex.h;
1563 1723
1564 if (last_name != tex.name) 1724 hv_iterinit (smooth);
1725 while ((he = hv_iternext (smooth)))
1565 { 1726 {
1727 smooth_key *skey = (smooth_key *)HeKEY (he);
1728 IV bits = SvIVX (HeVAL (he));
1729
1730 // bits is ___n cccc CCCC bbbb
1731 // n do not draw borders&corners
1732 // c draw these corners, but...
1733 // C ... not these
1734 // b draw these borders
1735
1566 if (!tex.name) 1736 if (!(bits & 0x1000)
1567 tex = self->tex [2]; /* missing, replace by noface */ 1737 && skey->level == level
1568 1738 && 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 { 1739 {
1583 maptex tex = self->tex [1]; 1740 maptex tex = self->tex [skey->tile];
1584 int px = x * T + T * 2 / 32; 1741 int px = (((int)skey->x) - 1) * T;
1585 int py = y * T - T * 6 / 32; 1742 int py = (((int)skey->y) - 1) * T;
1743 int border = bits & 15;
1744 int corner = (bits >> 8) & ~(bits >> 4) & 15;
1745 float dx = tex.s * .0625f; // 16 images/row
1746 float dy = tex.t * .5f ; // 2 images/column
1586 1747
1748 // this time naively avoiding texture state changes
1749 // save gobs of state changes.
1750 if (last_name != tex.name)
1751 {
1752 if (!tex.name)
1753 continue; // smoothing not yet available
1754
1587 glEnd (); 1755 glEnd ();
1588 glBindTexture (GL_TEXTURE_2D, last_name = tex.name); 1756 glBindTexture (GL_TEXTURE_2D, last_name = tex.name);
1589 glBegin (GL_QUADS); 1757 glBegin (GL_QUADS);
1758 }
1590 1759
1760 if (border)
1761 {
1762 float ox = border * dx;
1763
1764 glTexCoord2f (ox , 0.f ); glVertex2f (px , py );
1765 glTexCoord2f (ox , dy ); glVertex2f (px , py + T);
1766 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py + T);
1767 glTexCoord2f (ox + dx, 0.f ); glVertex2f (px + T, py );
1768 }
1769
1770 if (corner)
1771 {
1772 float ox = corner * dx;
1773
1591 glTexCoord2f (0 , 0 ); glVertex2f (px , py ); 1774 glTexCoord2f (ox , dy ); glVertex2f (px , py );
1592 glTexCoord2f (0 , tex.t); glVertex2f (px , py + T); 1775 glTexCoord2f (ox , dy * 2.f); glVertex2f (px , py + T);
1593 glTexCoord2f (tex.s, tex.t); glVertex2f (px + T, py + T); 1776 glTexCoord2f (ox + dx, dy * 2.f); glVertex2f (px + T, py + T);
1594 glTexCoord2f (tex.s, 0 ); glVertex2f (px + T, py ); 1777 glTexCoord2f (ox + dx, dy ); glVertex2f (px + T, py );
1778 }
1595 } 1779 }
1596 } 1780 }
1597 } 1781 }
1598 }
1599 } 1782 }
1783 }
1784
1785 hv_clear (smooth);
1786 }
1600 1787
1601 glEnd (); 1788 glEnd ();
1602 1789
1603 glDisable (GL_TEXTURE_2D); 1790 glDisable (GL_TEXTURE_2D);
1604 glDisable (GL_BLEND); 1791 glDisable (GL_BLEND);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines