initial commit

main
josch 10 years ago
commit e21880d804

@ -0,0 +1,400 @@
hr.py
setup.py
data/cursors/default.png
data/tiles/grass/0.png
data/tiles/water/0 watrtl01.pcx/0.png
data/tiles/water/0 watrtl01.pcx/1.png
data/tiles/water/0 watrtl01.pcx/10.png
data/tiles/water/0 watrtl01.pcx/11.png
data/tiles/water/0 watrtl01.pcx/2.png
data/tiles/water/0 watrtl01.pcx/3.png
data/tiles/water/0 watrtl01.pcx/4.png
data/tiles/water/0 watrtl01.pcx/5.png
data/tiles/water/0 watrtl01.pcx/6.png
data/tiles/water/0 watrtl01.pcx/7.png
data/tiles/water/0 watrtl01.pcx/8.png
data/tiles/water/0 watrtl01.pcx/9.png
data/tiles/water/1 watrtl02.pcx/0.png
data/tiles/water/1 watrtl02.pcx/1.png
data/tiles/water/1 watrtl02.pcx/10.png
data/tiles/water/1 watrtl02.pcx/11.png
data/tiles/water/1 watrtl02.pcx/2.png
data/tiles/water/1 watrtl02.pcx/3.png
data/tiles/water/1 watrtl02.pcx/4.png
data/tiles/water/1 watrtl02.pcx/5.png
data/tiles/water/1 watrtl02.pcx/6.png
data/tiles/water/1 watrtl02.pcx/7.png
data/tiles/water/1 watrtl02.pcx/8.png
data/tiles/water/1 watrtl02.pcx/9.png
data/tiles/water/10 watrtl11.pcx/0.png
data/tiles/water/10 watrtl11.pcx/1.png
data/tiles/water/10 watrtl11.pcx/10.png
data/tiles/water/10 watrtl11.pcx/11.png
data/tiles/water/10 watrtl11.pcx/2.png
data/tiles/water/10 watrtl11.pcx/3.png
data/tiles/water/10 watrtl11.pcx/4.png
data/tiles/water/10 watrtl11.pcx/5.png
data/tiles/water/10 watrtl11.pcx/6.png
data/tiles/water/10 watrtl11.pcx/7.png
data/tiles/water/10 watrtl11.pcx/8.png
data/tiles/water/10 watrtl11.pcx/9.png
data/tiles/water/11 watrtl12.pcx/0.png
data/tiles/water/11 watrtl12.pcx/1.png
data/tiles/water/11 watrtl12.pcx/10.png
data/tiles/water/11 watrtl12.pcx/11.png
data/tiles/water/11 watrtl12.pcx/2.png
data/tiles/water/11 watrtl12.pcx/3.png
data/tiles/water/11 watrtl12.pcx/4.png
data/tiles/water/11 watrtl12.pcx/5.png
data/tiles/water/11 watrtl12.pcx/6.png
data/tiles/water/11 watrtl12.pcx/7.png
data/tiles/water/11 watrtl12.pcx/8.png
data/tiles/water/11 watrtl12.pcx/9.png
data/tiles/water/12 watrtl13.pcx/0.png
data/tiles/water/12 watrtl13.pcx/1.png
data/tiles/water/12 watrtl13.pcx/10.png
data/tiles/water/12 watrtl13.pcx/11.png
data/tiles/water/12 watrtl13.pcx/2.png
data/tiles/water/12 watrtl13.pcx/3.png
data/tiles/water/12 watrtl13.pcx/4.png
data/tiles/water/12 watrtl13.pcx/5.png
data/tiles/water/12 watrtl13.pcx/6.png
data/tiles/water/12 watrtl13.pcx/7.png
data/tiles/water/12 watrtl13.pcx/8.png
data/tiles/water/12 watrtl13.pcx/9.png
data/tiles/water/13 watrtl14.pcx/0.png
data/tiles/water/13 watrtl14.pcx/1.png
data/tiles/water/13 watrtl14.pcx/10.png
data/tiles/water/13 watrtl14.pcx/11.png
data/tiles/water/13 watrtl14.pcx/2.png
data/tiles/water/13 watrtl14.pcx/3.png
data/tiles/water/13 watrtl14.pcx/4.png
data/tiles/water/13 watrtl14.pcx/5.png
data/tiles/water/13 watrtl14.pcx/6.png
data/tiles/water/13 watrtl14.pcx/7.png
data/tiles/water/13 watrtl14.pcx/8.png
data/tiles/water/13 watrtl14.pcx/9.png
data/tiles/water/14 watrtl15.pcx/0.png
data/tiles/water/14 watrtl15.pcx/1.png
data/tiles/water/14 watrtl15.pcx/10.png
data/tiles/water/14 watrtl15.pcx/11.png
data/tiles/water/14 watrtl15.pcx/2.png
data/tiles/water/14 watrtl15.pcx/3.png
data/tiles/water/14 watrtl15.pcx/4.png
data/tiles/water/14 watrtl15.pcx/5.png
data/tiles/water/14 watrtl15.pcx/6.png
data/tiles/water/14 watrtl15.pcx/7.png
data/tiles/water/14 watrtl15.pcx/8.png
data/tiles/water/14 watrtl15.pcx/9.png
data/tiles/water/15 watrtl16.pcx/0.png
data/tiles/water/15 watrtl16.pcx/1.png
data/tiles/water/15 watrtl16.pcx/10.png
data/tiles/water/15 watrtl16.pcx/11.png
data/tiles/water/15 watrtl16.pcx/2.png
data/tiles/water/15 watrtl16.pcx/3.png
data/tiles/water/15 watrtl16.pcx/4.png
data/tiles/water/15 watrtl16.pcx/5.png
data/tiles/water/15 watrtl16.pcx/6.png
data/tiles/water/15 watrtl16.pcx/7.png
data/tiles/water/15 watrtl16.pcx/8.png
data/tiles/water/15 watrtl16.pcx/9.png
data/tiles/water/16 watrtl17.pcx/0.png
data/tiles/water/16 watrtl17.pcx/1.png
data/tiles/water/16 watrtl17.pcx/10.png
data/tiles/water/16 watrtl17.pcx/11.png
data/tiles/water/16 watrtl17.pcx/2.png
data/tiles/water/16 watrtl17.pcx/3.png
data/tiles/water/16 watrtl17.pcx/4.png
data/tiles/water/16 watrtl17.pcx/5.png
data/tiles/water/16 watrtl17.pcx/6.png
data/tiles/water/16 watrtl17.pcx/7.png
data/tiles/water/16 watrtl17.pcx/8.png
data/tiles/water/16 watrtl17.pcx/9.png
data/tiles/water/17 watrtl18.pcx/0.png
data/tiles/water/17 watrtl18.pcx/1.png
data/tiles/water/17 watrtl18.pcx/10.png
data/tiles/water/17 watrtl18.pcx/11.png
data/tiles/water/17 watrtl18.pcx/2.png
data/tiles/water/17 watrtl18.pcx/3.png
data/tiles/water/17 watrtl18.pcx/4.png
data/tiles/water/17 watrtl18.pcx/5.png
data/tiles/water/17 watrtl18.pcx/6.png
data/tiles/water/17 watrtl18.pcx/7.png
data/tiles/water/17 watrtl18.pcx/8.png
data/tiles/water/17 watrtl18.pcx/9.png
data/tiles/water/18 watrtl19.pcx/0.png
data/tiles/water/18 watrtl19.pcx/1.png
data/tiles/water/18 watrtl19.pcx/10.png
data/tiles/water/18 watrtl19.pcx/11.png
data/tiles/water/18 watrtl19.pcx/2.png
data/tiles/water/18 watrtl19.pcx/3.png
data/tiles/water/18 watrtl19.pcx/4.png
data/tiles/water/18 watrtl19.pcx/5.png
data/tiles/water/18 watrtl19.pcx/6.png
data/tiles/water/18 watrtl19.pcx/7.png
data/tiles/water/18 watrtl19.pcx/8.png
data/tiles/water/18 watrtl19.pcx/9.png
data/tiles/water/19 watrtl20.pcx/0.png
data/tiles/water/19 watrtl20.pcx/1.png
data/tiles/water/19 watrtl20.pcx/10.png
data/tiles/water/19 watrtl20.pcx/11.png
data/tiles/water/19 watrtl20.pcx/2.png
data/tiles/water/19 watrtl20.pcx/3.png
data/tiles/water/19 watrtl20.pcx/4.png
data/tiles/water/19 watrtl20.pcx/5.png
data/tiles/water/19 watrtl20.pcx/6.png
data/tiles/water/19 watrtl20.pcx/7.png
data/tiles/water/19 watrtl20.pcx/8.png
data/tiles/water/19 watrtl20.pcx/9.png
data/tiles/water/2 watrtl03.pcx/0.png
data/tiles/water/2 watrtl03.pcx/1.png
data/tiles/water/2 watrtl03.pcx/10.png
data/tiles/water/2 watrtl03.pcx/11.png
data/tiles/water/2 watrtl03.pcx/2.png
data/tiles/water/2 watrtl03.pcx/3.png
data/tiles/water/2 watrtl03.pcx/4.png
data/tiles/water/2 watrtl03.pcx/5.png
data/tiles/water/2 watrtl03.pcx/6.png
data/tiles/water/2 watrtl03.pcx/7.png
data/tiles/water/2 watrtl03.pcx/8.png
data/tiles/water/2 watrtl03.pcx/9.png
data/tiles/water/20 watrtl21.pcx/0.png
data/tiles/water/20 watrtl21.pcx/1.png
data/tiles/water/20 watrtl21.pcx/10.png
data/tiles/water/20 watrtl21.pcx/11.png
data/tiles/water/20 watrtl21.pcx/2.png
data/tiles/water/20 watrtl21.pcx/3.png
data/tiles/water/20 watrtl21.pcx/4.png
data/tiles/water/20 watrtl21.pcx/5.png
data/tiles/water/20 watrtl21.pcx/6.png
data/tiles/water/20 watrtl21.pcx/7.png
data/tiles/water/20 watrtl21.pcx/8.png
data/tiles/water/20 watrtl21.pcx/9.png
data/tiles/water/21 watrtl22.pcx/0.png
data/tiles/water/21 watrtl22.pcx/1.png
data/tiles/water/21 watrtl22.pcx/10.png
data/tiles/water/21 watrtl22.pcx/11.png
data/tiles/water/21 watrtl22.pcx/2.png
data/tiles/water/21 watrtl22.pcx/3.png
data/tiles/water/21 watrtl22.pcx/4.png
data/tiles/water/21 watrtl22.pcx/5.png
data/tiles/water/21 watrtl22.pcx/6.png
data/tiles/water/21 watrtl22.pcx/7.png
data/tiles/water/21 watrtl22.pcx/8.png
data/tiles/water/21 watrtl22.pcx/9.png
data/tiles/water/22 watrtl23.pcx/0.png
data/tiles/water/22 watrtl23.pcx/1.png
data/tiles/water/22 watrtl23.pcx/10.png
data/tiles/water/22 watrtl23.pcx/11.png
data/tiles/water/22 watrtl23.pcx/2.png
data/tiles/water/22 watrtl23.pcx/3.png
data/tiles/water/22 watrtl23.pcx/4.png
data/tiles/water/22 watrtl23.pcx/5.png
data/tiles/water/22 watrtl23.pcx/6.png
data/tiles/water/22 watrtl23.pcx/7.png
data/tiles/water/22 watrtl23.pcx/8.png
data/tiles/water/22 watrtl23.pcx/9.png
data/tiles/water/23 watrtl24.pcx/0.png
data/tiles/water/23 watrtl24.pcx/1.png
data/tiles/water/23 watrtl24.pcx/10.png
data/tiles/water/23 watrtl24.pcx/11.png
data/tiles/water/23 watrtl24.pcx/2.png
data/tiles/water/23 watrtl24.pcx/3.png
data/tiles/water/23 watrtl24.pcx/4.png
data/tiles/water/23 watrtl24.pcx/5.png
data/tiles/water/23 watrtl24.pcx/6.png
data/tiles/water/23 watrtl24.pcx/7.png
data/tiles/water/23 watrtl24.pcx/8.png
data/tiles/water/23 watrtl24.pcx/9.png
data/tiles/water/24 watrtl25.pcx/0.png
data/tiles/water/24 watrtl25.pcx/1.png
data/tiles/water/24 watrtl25.pcx/10.png
data/tiles/water/24 watrtl25.pcx/11.png
data/tiles/water/24 watrtl25.pcx/2.png
data/tiles/water/24 watrtl25.pcx/3.png
data/tiles/water/24 watrtl25.pcx/4.png
data/tiles/water/24 watrtl25.pcx/5.png
data/tiles/water/24 watrtl25.pcx/6.png
data/tiles/water/24 watrtl25.pcx/7.png
data/tiles/water/24 watrtl25.pcx/8.png
data/tiles/water/24 watrtl25.pcx/9.png
data/tiles/water/25 watrtl26.pcx/0.png
data/tiles/water/25 watrtl26.pcx/1.png
data/tiles/water/25 watrtl26.pcx/10.png
data/tiles/water/25 watrtl26.pcx/11.png
data/tiles/water/25 watrtl26.pcx/2.png
data/tiles/water/25 watrtl26.pcx/3.png
data/tiles/water/25 watrtl26.pcx/4.png
data/tiles/water/25 watrtl26.pcx/5.png
data/tiles/water/25 watrtl26.pcx/6.png
data/tiles/water/25 watrtl26.pcx/7.png
data/tiles/water/25 watrtl26.pcx/8.png
data/tiles/water/25 watrtl26.pcx/9.png
data/tiles/water/26 watrtl27.pcx/0.png
data/tiles/water/26 watrtl27.pcx/1.png
data/tiles/water/26 watrtl27.pcx/10.png
data/tiles/water/26 watrtl27.pcx/11.png
data/tiles/water/26 watrtl27.pcx/2.png
data/tiles/water/26 watrtl27.pcx/3.png
data/tiles/water/26 watrtl27.pcx/4.png
data/tiles/water/26 watrtl27.pcx/5.png
data/tiles/water/26 watrtl27.pcx/6.png
data/tiles/water/26 watrtl27.pcx/7.png
data/tiles/water/26 watrtl27.pcx/8.png
data/tiles/water/26 watrtl27.pcx/9.png
data/tiles/water/27 watrtl28.pcx/0.png
data/tiles/water/27 watrtl28.pcx/1.png
data/tiles/water/27 watrtl28.pcx/10.png
data/tiles/water/27 watrtl28.pcx/11.png
data/tiles/water/27 watrtl28.pcx/2.png
data/tiles/water/27 watrtl28.pcx/3.png
data/tiles/water/27 watrtl28.pcx/4.png
data/tiles/water/27 watrtl28.pcx/5.png
data/tiles/water/27 watrtl28.pcx/6.png
data/tiles/water/27 watrtl28.pcx/7.png
data/tiles/water/27 watrtl28.pcx/8.png
data/tiles/water/27 watrtl28.pcx/9.png
data/tiles/water/28 watrtl29.pcx/0.png
data/tiles/water/28 watrtl29.pcx/1.png
data/tiles/water/28 watrtl29.pcx/10.png
data/tiles/water/28 watrtl29.pcx/11.png
data/tiles/water/28 watrtl29.pcx/2.png
data/tiles/water/28 watrtl29.pcx/3.png
data/tiles/water/28 watrtl29.pcx/4.png
data/tiles/water/28 watrtl29.pcx/5.png
data/tiles/water/28 watrtl29.pcx/6.png
data/tiles/water/28 watrtl29.pcx/7.png
data/tiles/water/28 watrtl29.pcx/8.png
data/tiles/water/28 watrtl29.pcx/9.png
data/tiles/water/29 watrtl30.pcx/0.png
data/tiles/water/29 watrtl30.pcx/1.png
data/tiles/water/29 watrtl30.pcx/10.png
data/tiles/water/29 watrtl30.pcx/11.png
data/tiles/water/29 watrtl30.pcx/2.png
data/tiles/water/29 watrtl30.pcx/3.png
data/tiles/water/29 watrtl30.pcx/4.png
data/tiles/water/29 watrtl30.pcx/5.png
data/tiles/water/29 watrtl30.pcx/6.png
data/tiles/water/29 watrtl30.pcx/7.png
data/tiles/water/29 watrtl30.pcx/8.png
data/tiles/water/29 watrtl30.pcx/9.png
data/tiles/water/3 watrtl04.pcx/0.png
data/tiles/water/3 watrtl04.pcx/1.png
data/tiles/water/3 watrtl04.pcx/10.png
data/tiles/water/3 watrtl04.pcx/11.png
data/tiles/water/3 watrtl04.pcx/2.png
data/tiles/water/3 watrtl04.pcx/3.png
data/tiles/water/3 watrtl04.pcx/4.png
data/tiles/water/3 watrtl04.pcx/5.png
data/tiles/water/3 watrtl04.pcx/6.png
data/tiles/water/3 watrtl04.pcx/7.png
data/tiles/water/3 watrtl04.pcx/8.png
data/tiles/water/3 watrtl04.pcx/9.png
data/tiles/water/30 watrtl31.pcx/0.png
data/tiles/water/30 watrtl31.pcx/1.png
data/tiles/water/30 watrtl31.pcx/10.png
data/tiles/water/30 watrtl31.pcx/11.png
data/tiles/water/30 watrtl31.pcx/2.png
data/tiles/water/30 watrtl31.pcx/3.png
data/tiles/water/30 watrtl31.pcx/4.png
data/tiles/water/30 watrtl31.pcx/5.png
data/tiles/water/30 watrtl31.pcx/6.png
data/tiles/water/30 watrtl31.pcx/7.png
data/tiles/water/30 watrtl31.pcx/8.png
data/tiles/water/30 watrtl31.pcx/9.png
data/tiles/water/31 watrtl32.pcx/0.png
data/tiles/water/31 watrtl32.pcx/1.png
data/tiles/water/31 watrtl32.pcx/10.png
data/tiles/water/31 watrtl32.pcx/11.png
data/tiles/water/31 watrtl32.pcx/2.png
data/tiles/water/31 watrtl32.pcx/3.png
data/tiles/water/31 watrtl32.pcx/4.png
data/tiles/water/31 watrtl32.pcx/5.png
data/tiles/water/31 watrtl32.pcx/6.png
data/tiles/water/31 watrtl32.pcx/7.png
data/tiles/water/31 watrtl32.pcx/8.png
data/tiles/water/31 watrtl32.pcx/9.png
data/tiles/water/32 watrtl33.pcx/0.png
data/tiles/water/32 watrtl33.pcx/1.png
data/tiles/water/32 watrtl33.pcx/10.png
data/tiles/water/32 watrtl33.pcx/11.png
data/tiles/water/32 watrtl33.pcx/2.png
data/tiles/water/32 watrtl33.pcx/3.png
data/tiles/water/32 watrtl33.pcx/4.png
data/tiles/water/32 watrtl33.pcx/5.png
data/tiles/water/32 watrtl33.pcx/6.png
data/tiles/water/32 watrtl33.pcx/7.png
data/tiles/water/32 watrtl33.pcx/8.png
data/tiles/water/32 watrtl33.pcx/9.png
data/tiles/water/4 watrtl05.pcx/0.png
data/tiles/water/4 watrtl05.pcx/1.png
data/tiles/water/4 watrtl05.pcx/10.png
data/tiles/water/4 watrtl05.pcx/11.png
data/tiles/water/4 watrtl05.pcx/2.png
data/tiles/water/4 watrtl05.pcx/3.png
data/tiles/water/4 watrtl05.pcx/4.png
data/tiles/water/4 watrtl05.pcx/5.png
data/tiles/water/4 watrtl05.pcx/6.png
data/tiles/water/4 watrtl05.pcx/7.png
data/tiles/water/4 watrtl05.pcx/8.png
data/tiles/water/4 watrtl05.pcx/9.png
data/tiles/water/5 watrtl06.pcx/0.png
data/tiles/water/5 watrtl06.pcx/1.png
data/tiles/water/5 watrtl06.pcx/10.png
data/tiles/water/5 watrtl06.pcx/11.png
data/tiles/water/5 watrtl06.pcx/2.png
data/tiles/water/5 watrtl06.pcx/3.png
data/tiles/water/5 watrtl06.pcx/4.png
data/tiles/water/5 watrtl06.pcx/5.png
data/tiles/water/5 watrtl06.pcx/6.png
data/tiles/water/5 watrtl06.pcx/7.png
data/tiles/water/5 watrtl06.pcx/8.png
data/tiles/water/5 watrtl06.pcx/9.png
data/tiles/water/6 watrtl07.pcx/0.png
data/tiles/water/6 watrtl07.pcx/1.png
data/tiles/water/6 watrtl07.pcx/10.png
data/tiles/water/6 watrtl07.pcx/11.png
data/tiles/water/6 watrtl07.pcx/2.png
data/tiles/water/6 watrtl07.pcx/3.png
data/tiles/water/6 watrtl07.pcx/4.png
data/tiles/water/6 watrtl07.pcx/5.png
data/tiles/water/6 watrtl07.pcx/6.png
data/tiles/water/6 watrtl07.pcx/7.png
data/tiles/water/6 watrtl07.pcx/8.png
data/tiles/water/6 watrtl07.pcx/9.png
data/tiles/water/7 watrtl08.pcx/0.png
data/tiles/water/7 watrtl08.pcx/1.png
data/tiles/water/7 watrtl08.pcx/10.png
data/tiles/water/7 watrtl08.pcx/11.png
data/tiles/water/7 watrtl08.pcx/2.png
data/tiles/water/7 watrtl08.pcx/3.png
data/tiles/water/7 watrtl08.pcx/4.png
data/tiles/water/7 watrtl08.pcx/5.png
data/tiles/water/7 watrtl08.pcx/6.png
data/tiles/water/7 watrtl08.pcx/7.png
data/tiles/water/7 watrtl08.pcx/8.png
data/tiles/water/7 watrtl08.pcx/9.png
data/tiles/water/8 watrtl09.pcx/0.png
data/tiles/water/8 watrtl09.pcx/1.png
data/tiles/water/8 watrtl09.pcx/10.png
data/tiles/water/8 watrtl09.pcx/11.png
data/tiles/water/8 watrtl09.pcx/2.png
data/tiles/water/8 watrtl09.pcx/3.png
data/tiles/water/8 watrtl09.pcx/4.png
data/tiles/water/8 watrtl09.pcx/5.png
data/tiles/water/8 watrtl09.pcx/6.png
data/tiles/water/8 watrtl09.pcx/7.png
data/tiles/water/8 watrtl09.pcx/8.png
data/tiles/water/8 watrtl09.pcx/9.png
data/tiles/water/9 watrtl10.pcx/0.png
data/tiles/water/9 watrtl10.pcx/1.png
data/tiles/water/9 watrtl10.pcx/10.png
data/tiles/water/9 watrtl10.pcx/11.png
data/tiles/water/9 watrtl10.pcx/2.png
data/tiles/water/9 watrtl10.pcx/3.png
data/tiles/water/9 watrtl10.pcx/4.png
data/tiles/water/9 watrtl10.pcx/5.png
data/tiles/water/9 watrtl10.pcx/6.png
data/tiles/water/9 watrtl10.pcx/7.png
data/tiles/water/9 watrtl10.pcx/8.png
data/tiles/water/9 watrtl10.pcx/9.png

@ -0,0 +1,2 @@
include hr.py
recursive-include data/ *

@ -0,0 +1,260 @@
#!/usr/bin/python
"""
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pyglet
import random
class Animation(object):
def __init__(self, frames):
self.frames = frames
self.animation = 0
def get_current_frame(self):
return self.frames[self.animation]
def get_next_frame(self):
self.animation = (self.animation+1)%len(self.frames)
return self.frames[self.animation]
class WaterTile(Animation):
def __init__(self, tiles, group):
super(WaterTile, self).__init__(tiles)
self.tiles = tiles
self.group = group
def get_group(self):
return self.group
def get_tex_coords(self):
return self.get_current_frame().tex_coords
def get_next_tex_coords(self):
return self.get_next_frame().tex_coords
class GrassTile(object):
def __init__(self, tile, group):
self.tile = tile
self.group = group
def get_group(self):
return self.group
def get_tex_coords(self):
return self.tile.tex_coords
class MapSet(object):
def __init__(self, loaded_map):
self.width = len(loaded_map[0])
self.height = len(loaded_map)
self.water_tiles = self._load_water_tiles()
self.grass_tiles = self._load_grass_tiles()
self.tiles = [[None for i in xrange(self.width)] for j in xrange(self.height)]
for y, line in enumerate(loaded_map):
for x, tile in enumerate(line):
if tile[0] == 2: #grass
self.tiles[y][x] = GrassTile(self.grass_tiles[tile[1]], self.grass_group)
elif tile[0] == 8: #water
self.tiles[y][x] = WaterTile(self.water_tiles[tile[1]], self.water_group)
def _load_grass_tiles(self):
atlas = pyglet.image.atlas.TextureAtlas()
self.grass_texture = atlas.texture
self.grass_group = pyglet.graphics.TextureGroup(atlas.texture)
return [atlas.add(pyglet.image.load('data/tiles/grass/0.png'))]
def _load_water_tiles(self):
atlas = pyglet.image.atlas.TextureAtlas(width=384, height=416)
self.water_texture = atlas.texture
self.water_group = pyglet.graphics.TextureGroup(atlas.texture)
return [[atlas.add(pyglet.image.load('data/tiles/water/%d watrtl%d.pcx/%d.png'%(j,j+1,i))) for i in xrange(12)] for j in xrange(20, 32)]
def get_tile(self, x, y):
assert x >= 0 and y >= 0
return self.tiles[y][x]
class MapView(object):
def __init__(self, mapset, window):
self.window = window
self.mapset = mapset
self.batch = pyglet.graphics.Batch()
self.x = 0
self.y = 0
self.dx = 0
self.dy = 0
self.vertex_lists = {}
self._init_view()
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
pyglet.clock.schedule_interval(self.update, 1/60.0)
def _init_view(self):
for vlist in self.vertex_lists.values():
vlist.delete()
self.vertex_lists = {}
coords = {}
textures = {}
div_y, mod_y = divmod(self.y, 32)
div_x, mod_x = divmod(self.x, 32)
for y in xrange((self.window.height-48)//32):
y1 = mod_y+y*32+48
y2 = y1+32
for x in xrange((self.window.width-192)//32):
x1 = mod_x+x*32
x2 = x1+32
tile = self.mapset.get_tile(x-div_x, y-div_y)
group = tile.get_group()
if group not in coords.keys():
coords[group] = []
textures[group] = []
coords[group].extend([x1, y1, x2, y1, x2, y2, x1, y2])
textures[group].extend(tile.get_tex_coords())
for group in coords.keys():
self.vertex_lists[group] = self.batch.add((len(coords[group])//8)*4, pyglet.gl.GL_QUADS, group,
('v2i', coords[group]),
('t3f', textures[group]),
('c4B', (255,255,255,255) * (len(coords[group])//8)*4))
def on_draw(self):
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT | pyglet.gl.GL_DEPTH_BUFFER_BIT)
self.batch.draw()
def _move(self, dx, dy):
div_y, mod_y = divmod(self.y+dy, 32)
div_x, mod_x = divmod(self.x+dx, 32)
if div_x != self.x//32 or div_y != self.y//32:
update_texture = True
else:
update_texture = False
self.x += dx
self.y += dy
if update_texture:
self._init_view()
else:
coords = {}
for y in xrange((self.window.height-48)//32):
y1 = mod_y+y*32+48
y2 = y1+32
for x in xrange((self.window.width-192)//32):
x1 = mod_x+x*32
x2 = x1+32
tile = self.mapset.get_tile(x-div_x, y-div_y)
group = tile.get_group()
if group not in coords.keys():
coords[group] = []
coords[group].extend([x1, y1, x2, y1, x2, y2, x1, y2])
for group in coords.keys():
self.vertex_lists[group].vertices = coords[group]
def update(self, dt):
try:
if self.window.keys[pyglet.window.key.LCTRL] and \
any([self.window.keys[pyglet.window.key.UP],
self.window.keys[pyglet.window.key.DOWN],
self.window.keys[pyglet.window.key.LEFT],
self.window.keys[pyglet.window.key.RIGHT]]):
if self.window.keys[pyglet.window.key.LEFT]:
x = 1
elif self.window.keys[pyglet.window.key.RIGHT]:
x = -1
else:
x = 0
if self.window.keys[pyglet.window.key.UP]:
y = -1
elif self.window.keys[pyglet.window.key.DOWN]:
y = 1
else:
y = 0
self.dx += x*8
self.dy += y*8
except KeyError:
pass
if self.dx or self.dy:
self._move(self.dx, self.dy)
self.dx = 0
self.dy = 0
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
self.dx += dx
self.dy += dy
return pyglet.event.EVENT_HANDLED
def on_resize(self, width, height):
self._init_view()
def animate_water(self, dt):
water_texture = []
for y in xrange((self.window.height-48)//32):
for x in xrange((self.window.width-192)//32):
tile = self.mapset.get_tile(x-self.x//32, y-self.y//32)
if tile.get_group() is self.mapset.water_group:
water_texture.extend(tile.get_next_tex_coords())
self.vertex_lists[self.mapset.water_group].tex_coords = water_texture
class Window(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(800, 600, resizable=True, vsync=False )
img = pyglet.resource.image("data/cursors/default.png")
self.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
self.keys = pyglet.window.key.KeyStateHandler()
self.push_handlers(self.keys)
self.fps = pyglet.clock.ClockDisplay()
def on_draw(self):
self.fps.draw()
def on_key_press(self, symbol, modifiers):
if symbol == pyglet.window.key.F11:
self.set_fullscreen(fullscreen=not self.fullscreen)
def empty(self, dt):
pass
def main():
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
window = Window()
loaded_map = [[[8,random.randint(0,11)] for x in xrange(128)] for y in xrange(128)]
loaded_map[10][10] = [2, 0]
loaded_map[0] = [[2,0] for y in xrange(128)]
for x in xrange(128):
loaded_map[x][32] = [2,0]
mapset = MapSet(loaded_map)
mapview = MapView(mapset, window)
window.push_handlers(mapview)
pyglet.clock.schedule(window.empty)
pyglet.app.run()
if __name__ == '__main__':
main()

@ -0,0 +1,154 @@
#!/usr/bin/python
import pyglet
import random
class Map(object):
def __init__(self, window):
self.window = window
#generate map
self.water_map = [[random.randint(0,11) for x in xrange(128)] for y in xrange(128)]
self.batch = pyglet.graphics.Batch()
self.animate = 0
self.x = 0
self.y = 0
self.dx = 0
self.dy = 0
self.vertex_lists = [[] for x in xrange((self.window.height-48)//32)]
self._load_resources()
self._init_map()
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
pyglet.clock.schedule_interval(self.update, 1/60.0)
def _load_resources(self):
atlas = pyglet.image.atlas.TextureAtlas(width=384, height=416)
self.tiles = [[atlas.add(pyglet.image.load('data/tiles/water/%d watrtl%d.pcx/%d.png'%(j,j+1,i))) for i in xrange(12)] for j in xrange(20, 32)]
self.water_texture = atlas.texture
def _init_map(self):
try:
for row in self.vertex_lists:
for vlist in row:
vlist.delete()
except:
raise
self.vertex_lists = [[] for x in xrange((self.window.height-48)//32)]
group = pyglet.graphics.TextureGroup(self.water_texture)
for y in xrange((self.window.height-48)//32):
y1 = y*32+48
y2 = y1+32
for x in xrange((self.window.width-192)//32):
x1 = x*32
x2 = x1+32
tile = self.tiles[self.water_map[y][x]][self.animate]
self.vertex_lists[y].append(self.batch.add(4, pyglet.gl.GL_QUADS, group,
('v2i', [x1, y1, x2, y1, x2, y2, x1, y2]),
('t3f', tile.tex_coords),
('c4B', (255,255,255,255) * 4)))
def on_draw(self):
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT | pyglet.gl.GL_DEPTH_BUFFER_BIT)
self.batch.draw()
def _move(self, dx, dy):
div_y, mod_y = divmod(self.y+dy, 32)
div_x, mod_x = divmod(self.x+dx, 32)
if div_x != self.x//32 or div_y != self.y//32:
update_texture = True
else:
update_texture = False
self.x += dx
self.y += dy
for y in xrange((self.window.height-48)//32):
y1 = mod_y+y*32+48
y2 = y1+32
for x in xrange((self.window.width-192)//32):
x1 = mod_x+x*32
x2 = x1+32
self.vertex_lists[y][x].vertices = [x1, y1, x2, y1, x2, y2, x1, y2]
if update_texture:
tile = self.tiles[self.water_map[y-div_y][x-div_x]][self.animate]
self.vertex_lists[y][x].tex_coords=tile.tex_coords
def update(self, dt):
try:
if self.window.keys[pyglet.window.key.LCTRL] and \
any([self.window.keys[pyglet.window.key.UP],
self.window.keys[pyglet.window.key.DOWN],
self.window.keys[pyglet.window.key.LEFT],
self.window.keys[pyglet.window.key.RIGHT]]):
if self.window.keys[pyglet.window.key.LEFT]:
x = 1
elif self.window.keys[pyglet.window.key.RIGHT]:
x = -1
else:
x = 0
if self.window.keys[pyglet.window.key.UP]:
y = -1
elif self.window.keys[pyglet.window.key.DOWN]:
y = 1
else:
y = 0
self.dx += x*8
self.dy += y*8
except KeyError:
pass
if self.dx or self.dy:
self._move(self.dx, self.dy)
self.dx = 0
self.dy = 0
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
self.dx += dx
self.dy += dy
return pyglet.event.EVENT_HANDLED
def on_resize(self, width, height):
self._init_map()
def animate_water(self, dt):
for y in xrange((self.window.height-48)//32):
for x in xrange((self.window.width-192)//32):
tile = self.tiles[self.water_map[y-self.y//32][x-self.x//32]][self.animate]
self.vertex_lists[y][x].tex_coords=tile.tex_coords
self.animate = (self.animate+1)%12
class Window(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(800, 600, resizable=True, vsync=False )
img = pyglet.resource.image("data/cursors/default.png")
self.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 4, 28))
self.keys = pyglet.window.key.KeyStateHandler()
self.push_handlers(self.keys)
self.fps = pyglet.clock.ClockDisplay()
def on_draw(self):
self.fps.draw()
def empty(self, dt):
pass
def main():
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
window = Window()
map = Map(window)
window.push_handlers(map)
pyglet.clock.schedule(window.empty)
pyglet.app.run()
if __name__ == '__main__':
main()

@ -0,0 +1,120 @@
#!/usr/bin/python
"""
homm3h3mview
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import gzip, os
import struct
import sys
import pygame
from pygame.locals import *
class Tile(pygame.sprite.Sprite):
def __init__(self, tile_type, tile_seq, x, y, flip_x, flip_y):
pygame.sprite.Sprite.__init__(self) #call Sprite initializer
try:
if tile_type == 8: #water
image = pygame.image.load("/home/josch/fheroes3/tests/69 tiles/3229 Watrtl.def/watrtl%02d.pcx"%(tile_seq+1))
elif tile_type == 2: #grass
print tile_seq,
path = "/home/josch/fheroes3/tests/69 tiles/3221 GRASTL.def/tgrs%03d.pcx"
if tile_seq == 20:
image = pygame.image.load(path%0)
elif tile_seq == 21:
image = pygame.image.load(path%1)
elif tile_seq == 22:
image = pygame.image.load(path%2)
elif tile_seq == 23:
image = pygame.image.load(path%3)
elif tile_seq == 24:
image = pygame.image.load(path%10)
elif tile_seq == 25:
image = pygame.image.load(path%11)
elif tile_seq == 26:
image = pygame.image.load(path%12)
elif tile_seq == 27:
image = pygame.image.load(path%13)
elif tile_seq == 28:
image = pygame.image.load(path%20)
elif tile_seq == 29:
image = pygame.image.load(path%21)
elif tile_seq == 30:
image = pygame.image.load(path%22)
elif tile_seq == 31:
image = pygame.image.load(path%23)
elif tile_seq == 32:
image = pygame.image.load(path%30)
elif tile_seq == 33:
image = pygame.image.load(path%31)
elif tile_seq == 34:
image = pygame.image.load(path%32)
elif tile_seq == 35:
image = pygame.image.load(path%33)
else:
raise Exception
except:
image = pygame.image.load("/home/josch/fheroes3/tests/69 tiles/3999 Tshre.def/Tshre10.pcx")
image = image.convert()
if flip_x or flip_y:
image = pygame.transform.flip(image, flip_x, flip_y)
self.image = image
self.rect = image.get_rect()
self.rect.topleft = (32*x,32*y)
def extract(filename):
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption('Heroes Rebirth')
pygame.mouse.set_visible(1)
clock = pygame.time.Clock()
h3m_data = gzip.open(filename)
h3m_data.seek(5)
(map_size,) = struct.unpack("i", h3m_data.read(4))
h3m_data.seek(390)
tiles = []
for i in xrange(map_size*map_size):
x = i%map_size
y = (i-x)/map_size
tile = struct.unpack("7B", h3m_data.read(7))
flip_x = tile[6] & 0x1
flip_y = tile[6] & 0x2
tile = Tile(tile[0], tile[1], x, y, flip_x, flip_y)
tiles.append(tile)
allsprites = pygame.sprite.RenderPlain(tiles)
while 1:
for event in pygame.event.get():
if event.type == QUIT:
return
elif event.type == KEYDOWN and event.key == K_ESCAPE:
return
allsprites.draw(screen)
pygame.display.flip()
clock.tick(25)
def main(args):
if len(args) != 2:
print 'usage: %s file' % args[0]
return 2
extract(args[1])
if __name__ == '__main__':
sys.exit(main(sys.argv))

@ -0,0 +1,212 @@
#!/usr/bin/python
"""
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pyglet
import random
class Animation(object):
def __init__(self, frames):
self.frames = frames
self.animation = 0
@property
def current_frame(self):
return self.frames[self.animation]
@property
def next_frame(self):
self.animation = (self.animation+1)%len(self.frames)
return self.frames[self.animation]
class WaterTile(Animation):
def __init__(self, tiles):
super(WaterTile, self).__init__(tiles)
self.tiles = tiles
@property
def current_tex_coords(self):
return self.current_frame.tex_coords
@property
def next_tex_coords(self):
return self.next_frame.tex_coords
class MapSet(object):
def __init__(self, loaded_map):
self.width = len(loaded_map[0])
self.height = len(loaded_map)
self.alt_water = pyglet.image.TextureGrid(pyglet.image.ImageGrid(pyglet.image.load("water.png"), 20, 16))
self.water_texture = self.alt_water
self.tiles = [[None for i in xrange(self.width)] for j in xrange(self.height)]
for y, line in enumerate(loaded_map):
for x, tile in enumerate(line):
#self.tiles[y][x] = WaterTile(self.water_tiles[tile])
self.tiles[y][x] = WaterTile(self.alt_water[(0, tile):(19, tile+1)])
def __getitem__(self, coords):
x, y = coords
return self.tiles[y][x]
class MapView(object):
def __init__(self, mapset, window):
self.window = window
self.mapset = mapset
self.batch = pyglet.graphics.Batch()
self.x = 0
self.y = 0
self.dx = 0
self.dy = 0
self.vertex_lists = [[] for x in xrange((self.window.height-48)//32)]
self._init_view()
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
pyglet.clock.schedule_interval(self.update, 1/60.0)
def _init_view(self):
try:
for row in self.vertex_lists:
for vlist in row:
vlist.delete()
except:
raise
self.vertex_lists = [[] for x in xrange((self.window.height-48)//32)]
group = pyglet.graphics.TextureGroup(self.mapset.water_texture)
for y in xrange((self.window.height-48)//32):
y1 = y*32+48
y2 = y1+32
for x in xrange((self.window.width-192)//32):
x1 = x*32
x2 = x1+32
tile = self.mapset[x, y]
self.vertex_lists[y].append(self.batch.add(4, pyglet.gl.GL_QUADS, group,
('v2i', [x1, y1, x2, y1, x2, y2, x1, y2]),
('t3f', tile.current_tex_coords),
('c4B', (255,255,255,255) * 4)))
def on_draw(self):
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT | pyglet.gl.GL_DEPTH_BUFFER_BIT)
self.batch.draw()
def _move(self, dx, dy):
div_y, mod_y = divmod(self.y+dy, 32)
div_x, mod_x = divmod(self.x+dx, 32)
if div_x != self.x//32 or div_y != self.y//32:
update_texture = True
else:
update_texture = False
self.x += dx
self.y += dy
for y in xrange((self.window.height-48)//32):
y1 = mod_y+y*32+48
y2 = y1+32
for x in xrange((self.window.width-192)//32):
x1 = mod_x+x*32
x2 = x1+32
self.vertex_lists[y][x].vertices = [x1, y1, x2, y1, x2, y2, x1, y2]
if update_texture:
tile = self.mapset[x-div_x, y-div_y]
self.vertex_lists[y][x].tex_coords=tile.current_tex_coords
def update(self, dt):
try:
if self.window.keys[pyglet.window.key.LCTRL] and \
any([self.window.keys[pyglet.window.key.UP],
self.window.keys[pyglet.window.key.DOWN],
self.window.keys[pyglet.window.key.LEFT],
self.window.keys[pyglet.window.key.RIGHT]]):
if self.window.keys[pyglet.window.key.LEFT]:
x = 1
elif self.window.keys[pyglet.window.key.RIGHT]:
x = -1
else:
x = 0
if self.window.keys[pyglet.window.key.UP]:
y = -1
elif self.window.keys[pyglet.window.key.DOWN]:
y = 1
else:
y = 0
self.dx += x*8
self.dy += y*8
except KeyError:
pass
if self.dx or self.dy:
self._move(self.dx, self.dy)
self.dx = 0
self.dy = 0
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
self.dx += dx
self.dy += dy
return pyglet.event.EVENT_HANDLED
def on_resize(self, width, height):
self._init_view()
def animate_water(self, dt):
for y in xrange((self.window.height-48)//32):
for x in xrange((self.window.width-192)//32):
tile = self.mapset[x-self.x//32, y-self.y//32]
self.vertex_lists[y][x].tex_coords=tile.next_tex_coords
class Window(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(800, 600, resizable=True, vsync=False )
#img = pyglet.resource.image("cursor.png")
#self.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
self.keys = pyglet.window.key.KeyStateHandler()
self.push_handlers(self.keys)
self.fps = pyglet.clock.ClockDisplay()
def on_draw(self):
self.fps.draw()
def on_key_press(self, symbol, modifiers):
if symbol == pyglet.window.key.F11:
self.set_fullscreen(fullscreen=not self.fullscreen)
def empty(self, dt):
pass
def main():
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
window = Window()
loaded_map = [[random.randint(0,11) for x in xrange(128)] for y in xrange(128)]
mapset = MapSet(loaded_map)
mapview = MapView(mapset, window)
window.push_handlers(mapview)
pyglet.clock.schedule(window.empty)
pyglet.app.run()
if __name__ == '__main__':
main()

@ -0,0 +1,237 @@
#!/usr/bin/python
"""
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pyglet
import random
class Animation(object):
def __init__(self, frames):
self.frames = frames
self.animation = 0
def get_current_frame(self):
return self.frames[self.animation]
def get_next_frame(self):
self.animation = (self.animation+1)%len(self.frames)
return self.frames[self.animation]
class WaterTile(Animation):
def __init__(self, tiles, group):
super(WaterTile, self).__init__(tiles)
self.tiles = tiles
self.group = group
def get_group(self):
return self.group
def get_tex_coords(self):
return self.get_current_frame().tex_coords
def get_next_tex_coords(self):
return self.get_next_frame().tex_coords
class GrassTile(object):
def __init__(self, tile, group):
self.tile = tile
self.group = group
def get_group(self):
return self.group
def get_tex_coords(self):
return self.tile.tex_coords
class MapSet(object):
def __init__(self, loaded_map):
self.width = len(loaded_map[0])
self.height = len(loaded_map)
self.water_tiles = self._load_water_tiles()
self.grass_tiles = self._load_grass_tiles()
self.tiles = [[None for i in xrange(self.width)] for j in xrange(self.height)]
for y, line in enumerate(loaded_map):
for x, tile in enumerate(line):
if tile[0] == 2: #grass
self.tiles[y][x] = GrassTile(self.grass_tiles[tile[1]], self.grass_group)
elif tile[0] == 8: #water
self.tiles[y][x] = WaterTile(self.water_tiles[tile[1]], self.water_group)
def _load_grass_tiles(self):
atlas = pyglet.image.atlas.TextureAtlas()
self.grass_texture = atlas.texture
self.grass_group = pyglet.graphics.TextureGroup(atlas.texture)
return [atlas.add(pyglet.image.load('data/tiles/grass/0.png'))]
def _load_water_tiles(self):
atlas = pyglet.image.atlas.TextureAtlas(width=384, height=416)
self.water_texture = atlas.texture
self.water_group = pyglet.graphics.TextureGroup(atlas.texture)
return [[atlas.add(pyglet.image.load('data/tiles/water/%d watrtl%d.pcx/%d.png'%(j,j+1,i))) for i in xrange(12)] for j in xrange(20, 32)]
def get_tile(self, x, y):
return self.tiles[y][x]
class MapView(object):
def __init__(self, mapset, window):
self.window = window
self.mapset = mapset
self.batch = pyglet.graphics.Batch()
self.x = 0
self.y = 0
self.dx = 0
self.dy = 0
self.vertex_lists = [[] for x in xrange((self.window.height-48)//32)]
self._init_view()
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
pyglet.clock.schedule_interval(self.update, 1/60.0)
def _init_view(self):
try:
for row in self.vertex_lists:
for vlist in row:
vlist.delete()
except:
raise
self.vertex_lists = [[] for x in xrange((self.window.height-48)//32)]
for y in xrange((self.window.height-48)//32):
y1 = y*32+48
y2 = y1+32
for x in xrange((self.window.width-192)//32):
x1 = x*32
x2 = x1+32
tile = self.mapset.get_tile(x, y)
self.vertex_lists[y].append(self.batch.add(4, pyglet.gl.GL_QUADS, tile.get_group(),
('v2i', [x1, y1, x2, y1, x2, y2, x1, y2]),
('t3f', tile.get_tex_coords()),
('c4B', (255,255,255,255) * 4)))
def on_draw(self):
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT | pyglet.gl.GL_DEPTH_BUFFER_BIT)
self.batch.draw()
def _move(self, dx, dy):
div_y, mod_y = divmod(self.y+dy, 32)
div_x, mod_x = divmod(self.x+dx, 32)
if div_x != self.x//32 or div_y != self.y//32:
update_texture = True
else:
update_texture = False
self.x += dx
self.y += dy
for y in xrange((self.window.height-48)//32):
y1 = mod_y+y*32+48
y2 = y1+32
for x in xrange((self.window.width-192)//32):
x1 = mod_x+x*32
x2 = x1+32
self.vertex_lists[y][x].vertices = [x1, y1, x2, y1, x2, y2, x1, y2]
if update_texture:
tile = self.mapset.get_tile(x-div_x, y-div_y)
self.vertex_lists[y][x].tex_coords=tile.get_tex_coords()
def update(self, dt):
try:
if self.window.keys[pyglet.window.key.LCTRL] and \
any([self.window.keys[pyglet.window.key.UP],
self.window.keys[pyglet.window.key.DOWN],
self.window.keys[pyglet.window.key.LEFT],
self.window.keys[pyglet.window.key.RIGHT]]):
if self.window.keys[pyglet.window.key.LEFT]:
x = 1
elif self.window.keys[pyglet.window.key.RIGHT]:
x = -1
else:
x = 0
if self.window.keys[pyglet.window.key.UP]:
y = -1
elif self.window.keys[pyglet.window.key.DOWN]:
y = 1
else:
y = 0
self.dx += x*8
self.dy += y*8
except KeyError:
pass
if self.dx or self.dy:
self._move(self.dx, self.dy)
self.dx = 0
self.dy = 0
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
self.dx += dx
self.dy += dy
return pyglet.event.EVENT_HANDLED
def on_resize(self, width, height):
self._init_view()
def animate_water(self, dt):
for y in xrange((self.window.height-48)//32):
for x in xrange((self.window.width-192)//32):
tile = self.mapset.get_tile(x-self.x//32, y-self.y//32)
if isinstance(tile, WaterTile):
self.vertex_lists[y][x].tex_coords=tile.get_next_tex_coords()
class Window(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(800, 600, resizable=True, vsync=False )
img = pyglet.resource.image("data/cursors/default.png")
self.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
self.keys = pyglet.window.key.KeyStateHandler()
self.push_handlers(self.keys)
self.fps = pyglet.clock.ClockDisplay()
def on_draw(self):
self.fps.draw()
def on_key_press(self, symbol, modifiers):
if symbol == pyglet.window.key.F11:
self.set_fullscreen(fullscreen=not self.fullscreen)
def empty(self, dt):
pass
def main():
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
window = Window()
loaded_map = [[[8,random.randint(0,11)] for x in xrange(128)] for y in xrange(128)]
loaded_map[64][64] = [2, 0]
mapset = MapSet(loaded_map)
mapview = MapView(mapset, window)
window.push_handlers(mapview)
pyglet.clock.schedule(window.empty)
pyglet.app.run()
if __name__ == '__main__':
main()

@ -0,0 +1,409 @@
#!/usr/bin/python
"""
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pyglet
import random
import itertools
import demjson
IF_BOTTOM = 48
IF_RIGHT = 200
IF_TOP = IF_LEFT = 8
class Animation(object):
def __init__(self, frames):
self.frames = frames
self.animation = 0
def get_current_frame(self):
return self.frames[self.animation]
def get_next_frame(self):
self.animation = (self.animation+1)%len(self.frames)
return self.frames[self.animation]
class WaterTile(Animation):
def __init__(self, tiles):
super(WaterTile, self).__init__(tiles)
self.tiles = tiles
def get_tex_coords(self):
return self.get_current_frame().tex_coords
def get_next_tex_coords(self):
return self.get_next_frame().tex_coords
class Tile(object):
def __init__(self, tile):
self.tile = tile
def get_tex_coords(self):
return self.tile.tex_coords
def get_next_tex_coords(self):
return self.tile.tex_coords
class MapSet(object):
def __init__(self, loaded_map):
self.width = len(loaded_map[0])
self.height = len(loaded_map)
atlas = pyglet.image.atlas.TextureAtlas(width=2048, height=2048)
self.group = pyglet.graphics.TextureGroup(atlas.texture)
self.grass_tiles = [atlas.add(pyglet.image.load('data/tiles/grass/%d.png'%i)) for i in xrange(79)]
self.dirt_tiles = [atlas.add(pyglet.image.load('data/tiles/dirt/%d.png'%i)) for i in xrange(46)]
self.water_tiles = [[atlas.add(pyglet.image.load('data/tiles/water/%d watrtl%02d.pcx/%d.png'%(j,j+1,i))) for i in xrange(12)] for j in xrange(33)]
self.edge_tiles = [atlas.add(pyglet.image.load('data/tiles/edge/%d EDG%d.PCX'%(i, i+1))) for i in xrange(36)]
self.tiles = [[Tile(self.grass_tiles[0]) for i in xrange(self.width)] for j in xrange(self.height)]
for y, line in enumerate(loaded_map):
for x, tile in enumerate(line):
if tile[0] == -1: #edge
self.tiles[y][x] = Tile(self.edge_tiles[tile[1]])
elif tile[0] == 0: #dirt
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
self.tiles[y][x] = Tile(self.dirt_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
else:
self.tiles[y][x] = Tile(self.dirt_tiles[tile[1]])
elif tile[0] == 2: #grass
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
self.tiles[y][x] = Tile(self.grass_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
else:
self.tiles[y][x] = Tile(self.grass_tiles[tile[1]])
elif tile[0] == 8: #water
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
tiles = []
for tile in self.water_tiles[tile[1]]:
tiles.append(tile.get_transform(flip_x=flip_x, flip_y=flip_y))
self.tiles[y][x] = WaterTile(tiles)
else:
self.tiles[y][x] = WaterTile(self.water_tiles[tile[1]])
else:
self.tiles[y][x] = GrassTile(self.grass_tiles[0])
def get_tile(self, x, y):
assert x >= 0 and y >= 0
return self.tiles[y][x]
class MapView(object):
def __init__(self, mapset, window):
self.window = window
self.mapset = mapset
self.vertex_list = None
self._init_view()
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
pyglet.clock.schedule_interval(self.update, 1/60.0)
def _init_view(self):
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
#drawn tiles
self.tiles_x = min((self.viewport_x//32)+2, self.mapset.width)
self.tiles_y = min((self.viewport_y//32)+2, self.mapset.height)
self.center_x = False
if self.mapset.width*32 < self.viewport_x:
self.center_x = True
self.global_x = (self.mapset.width*32)//2-(self.viewport_x//2)
self.center_y = False
if self.mapset.height*32 < self.viewport_y:
self.center_y = True
self.global_y = (self.mapset.height*32)//2-(self.viewport_y//2)
#step half the drawn tiles (minus one tile)
self.steps = 32
#undrawn map size
self.undrawn_x = 32*(self.mapset.width-self.tiles_x)
self.undrawn_y = 32*(self.mapset.height-self.tiles_y)
#size of full undrawn steps
self.undrawn_steps_x = self.steps*(self.undrawn_x//self.steps)
self.undrawn_steps_y = self.steps*(self.undrawn_y//self.steps)
if self.vertex_list is not None:
self.vertex_list.delete()
else:
#do some first time init stuff
self.batch = pyglet.graphics.Batch()
self.view_x = 0
self.view_y = 0
self.global_x = (self.mapset.width*32)//2-(self.viewport_x//2)
self.global_y = (self.mapset.height*32)//2-(self.viewport_y//2)
self.dx = 0
self.dy = 0
#here we translate the global map position so we can draw with it
trans_global_x = self.steps-self.global_x
trans_global_y = self.steps-self.global_y
if trans_global_x < -self.undrawn_steps_x:
mod_x = trans_global_x+self.undrawn_x
elif trans_global_x < self.steps:
mod_x = trans_global_x%self.steps
else:
mod_x = trans_global_x
if trans_global_y < -self.undrawn_steps_y:
mod_y = trans_global_y+self.undrawn_y
elif trans_global_y < self.steps:
mod_y = trans_global_y%self.steps
else:
mod_y = trans_global_y
div_x = (trans_global_x-mod_x)//32
div_y = (trans_global_y-mod_y)//32+self.mapset.height-1
vertices = []
tex_coords = []
count = 0
for y in xrange(self.tiles_y):
y1 = y*32+IF_BOTTOM
y2 = y1+32
for x in xrange(self.tiles_x):
x1 = x*32+IF_LEFT
x2 = x1+32
tile = self.mapset.get_tile(x-div_x, div_y-y)
vertices.extend([x1, y1, x2, y1, x2, y2, x1, y2])
tex_coords.extend(tile.get_tex_coords())
count+=1
self.vertex_list = self.batch.add(4*count, pyglet.gl.GL_QUADS, self.mapset.group,
('v2i', vertices),
('t3f', tex_coords),
('c4B', (255,255,255,255)*4*count))
self.view_x = mod_x-self.steps
self.view_y = mod_y-self.steps
def on_draw(self):
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
pyglet.gl.glPushMatrix()
pyglet.gl.glTranslatef(self.view_x, self.view_y, 0)
self.batch.draw()
pyglet.gl.glPopMatrix()
pyglet.gl.glLoadIdentity()
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glColor4f(1, 0, 1, 1)
pyglet.gl.glRectf(0, 0, self.window.width, IF_BOTTOM)
pyglet.gl.glRectf(self.window.width-IF_RIGHT, 0, self.window.width, self.window.height)
pyglet.gl.glRectf(0, self.window.height-IF_TOP, self.window.width, self.window.height)
pyglet.gl.glRectf(0, 0, IF_LEFT, self.window.height)
def _move(self, dx, dy):
retex = False
#here we translate the global map position so we can draw with it
trans_global_x = self.steps-self.global_x
trans_global_y = self.steps-self.global_y
new_global_x = trans_global_x+dx
new_global_y = trans_global_y+dy
if self.global_x-dx < 0:
new_global_x = self.steps
if self.global_y-dy < 0:
new_global_y = self.steps
if dx-self.global_x < -32*self.mapset.width+self.viewport_x:
new_global_x = -32*self.mapset.width+self.viewport_x+self.steps
if dy-self.global_y < -32*self.mapset.height+self.viewport_y:
new_global_y = -32*self.mapset.height+self.viewport_y+self.steps
if new_global_x < -self.undrawn_steps_x:
mod_x = new_global_x+self.undrawn_x
if trans_global_x >= -self.undrawn_steps_x:
retex = True
elif new_global_x < self.steps:
div_x, mod_x = divmod(new_global_x, self.steps)
retex = div_x != trans_global_x//self.steps or retex
else:
mod_x = new_global_x
if new_global_y < -self.undrawn_steps_y:
mod_y = new_global_y+self.undrawn_y
if trans_global_y >= -self.undrawn_steps_y:
retex = True
elif new_global_y < self.steps:
div_y, mod_y = divmod(new_global_y, self.steps)
retex = div_y != trans_global_y//self.steps or retex
else:
mod_y = new_global_y
if retex:
div_x = (new_global_x-mod_x)//32
div_y = (new_global_y-mod_y)//32+self.mapset.height-1
tex_coords = []
for y in xrange(self.tiles_y):
for x in xrange(self.tiles_x):
tile = self.mapset.get_tile(x-div_x, div_y-y)
tex_coords.extend(tile.get_tex_coords())
self.vertex_list.tex_coords = tex_coords
if not self.center_x:
self.view_x = mod_x-self.steps
self.global_x = self.steps-new_global_x
if not self.center_y:
self.view_y = mod_y-self.steps
self.global_y = self.steps-new_global_y
def update(self, dt):
try:
if self.window.keys[pyglet.window.key.LCTRL] and \
any([self.window.keys[pyglet.window.key.UP],
self.window.keys[pyglet.window.key.DOWN],
self.window.keys[pyglet.window.key.LEFT],
self.window.keys[pyglet.window.key.RIGHT]]):
if self.window.keys[pyglet.window.key.LEFT]:
x = 1
elif self.window.keys[pyglet.window.key.RIGHT]:
x = -1
else:
x = 0
if self.window.keys[pyglet.window.key.UP]:
y = -1
elif self.window.keys[pyglet.window.key.DOWN]:
y = 1
else:
y = 0
self.dx += x*8
self.dy += y*8
except KeyError:
pass
if self.dx or self.dy:
self._move(self.dx, self.dy)
self.dx = 0
self.dy = 0
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
self.dx += dx
self.dy += dy
return pyglet.event.EVENT_HANDLED
def on_resize(self, width, height):
self._init_view()
def animate_water(self, dt):
#here we translate the global map position so we can draw with it
trans_global_x = self.steps-self.global_x
trans_global_y = self.steps-self.global_y
if trans_global_x < -self.undrawn_steps_x:
mod_x = trans_global_x+self.undrawn_x
elif trans_global_x < self.steps:
mod_x = trans_global_x%self.steps
else:
mod_x = trans_global_x
if trans_global_y < -self.undrawn_steps_y:
mod_y = trans_global_y+self.undrawn_y
elif trans_global_y < self.steps:
mod_y = trans_global_y%self.steps
else:
mod_y = trans_global_y
div_x = (trans_global_x-mod_x)//32
div_y = (trans_global_y-mod_y)//32+self.mapset.height-1
tex_coords = []
for y in xrange(self.tiles_y):
for x in xrange(self.tiles_x):
tile = self.mapset.get_tile(x-div_x, div_y-y)
tex_coords.extend(tile.get_next_tex_coords())
self.vertex_list.tex_coords = tex_coords
class Window(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(800, 600, resizable=True, vsync=False )
img = pyglet.resource.image("data/cursors/default.png")
self.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
self.keys = pyglet.window.key.KeyStateHandler()
self.push_handlers(self.keys)
self.fps = pyglet.clock.ClockDisplay()
def on_draw(self):
self.fps.draw()
def on_key_press(self, symbol, modifiers):
if symbol == pyglet.window.key.F11:
self.set_fullscreen(fullscreen=not self.fullscreen)
def empty(self, dt):
pass
def main():
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
window = Window()
# loaded_map = [[[8,random.randint(0,11)] for x in xrange(32)] for y in xrange(12)]
# loaded_map[0] = [[2,0] for y in xrange(32)]
# loaded_map[11] = [[2,0] for y in xrange(32)]
# for x in xrange(12):
# loaded_map[x][0] = [2,0]
# for x in xrange(12):
# loaded_map[x][31] = [2,0]
h3m = demjson.decode(open("test.h3m").read())
loaded_map = h3m["upper_terrain"]
edge_map = [[] for i in xrange(len(loaded_map)+16)]
for num in xrange(len(edge_map)):
if num < 7 or num > len(edge_map)-8:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0])+18)])
elif num == 7:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 16, 0, 0, 0, 0, 0])
line.extend([[-1, 20+i%4, 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0]))])
line.append([-1, 17, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
elif num == len(edge_map)-8:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 19, 0, 0, 0, 0, 0])
line.extend([[-1, 28+i%4, 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0]))])
line.append([-1, 18, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
else:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 32+num%4, 0, 0, 0, 0, 0])
line.extend(loaded_map[num-8])
line.append([-1, 24+num%4, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
edge_map[num] = line
mapset = MapSet(edge_map)
mapview = MapView(mapset, window)
window.push_handlers(mapview)
pyglet.clock.schedule(window.empty)
pyglet.app.run()
if __name__ == '__main__':
main()

@ -0,0 +1,420 @@
#!/usr/bin/python
"""
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pyglet
import random
import itertools
import sys
if sys.version_info[:2] >= (2,6):
import json
else:
try:
import simplejson as json
except ImportError:
import demjson as json
json.loads = json.decode
IF_BOTTOM = 48
IF_RIGHT = 200
IF_TOP = IF_LEFT = 8
class Animation(object):
def __init__(self, frames):
self.frames = frames
self.animation = 0
def get_current_frame(self):
return self.frames[self.animation]
def get_next_frame(self):
self.animation = (self.animation+1)%len(self.frames)
return self.frames[self.animation]
class WaterTile(Animation):
def __init__(self, tiles):
super(WaterTile, self).__init__(tiles)
self.tiles = tiles
def get_tex_coords(self):
return self.get_current_frame().tex_coords
def get_next_tex_coords(self):
return self.get_next_frame().tex_coords
class Tile(object):
def __init__(self, tile):
self.tile = tile
def get_tex_coords(self):
return self.tile.tex_coords
def get_next_tex_coords(self):
return self.tile.tex_coords
class MapSet(object):
def __init__(self, loaded_map):
self.width = len(loaded_map[0])
self.height = len(loaded_map)
atlas = pyglet.image.atlas.TextureAtlas(width=2048, height=2048)
self.group = pyglet.graphics.TextureGroup(atlas.texture)
self.grass_tiles = [atlas.add(pyglet.image.load('data/tiles/grass/%d.png'%i)) for i in xrange(79)]
self.snow_tiles = [atlas.add(pyglet.image.load('data/tiles/snow/%d.png'%i)) for i in xrange(79)]
self.lava_tiles = [atlas.add(pyglet.image.load('data/tiles/lava/%d.png'%i)) for i in xrange(79)]
self.swamp_tiles = [atlas.add(pyglet.image.load('data/tiles/swamp/%d.png'%i)) for i in xrange(79)]
self.rough_tiles = [atlas.add(pyglet.image.load('data/tiles/rough/%d.png'%i)) for i in xrange(79)]
self.dirt_tiles = [atlas.add(pyglet.image.load('data/tiles/dirt/%d.png'%i)) for i in xrange(46)]
self.rock_tiles = [atlas.add(pyglet.image.load('data/tiles/rock/%d.png'%i)) for i in xrange(48)]
self.sand_tiles = [atlas.add(pyglet.image.load('data/tiles/sand/%d.png'%i)) for i in xrange(24)]
self.water_tiles = [[atlas.add(pyglet.image.load('data/tiles/water/%d watrtl%02d.pcx/%d.png'%(j,j+1,i))) for i in xrange(12)] for j in xrange(33)]
self.edge_tiles = [atlas.add(pyglet.image.load('data/tiles/edge/%d EDG%d.PCX'%(i, i+1))) for i in xrange(36)]
self.tiles = [[Tile(self.grass_tiles[0]) for i in xrange(self.width)] for j in xrange(self.height)]
for y, line in enumerate(loaded_map):
for x, tile in enumerate(line):
if tile[0] == -1: #edge
self.tiles[y][x] = Tile(self.edge_tiles[tile[1]])
elif tile[0] == 0: #dirt
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
self.tiles[y][x] = Tile(self.dirt_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
else:
self.tiles[y][x] = Tile(self.dirt_tiles[tile[1]])
elif tile[0] == 1: #sand
self.tiles[y][x] = Tile(self.sand_tiles[tile[1]])
elif tile[0] == 2: #grass
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
self.tiles[y][x] = Tile(self.grass_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
else:
self.tiles[y][x] = Tile(self.grass_tiles[tile[1]])
elif tile[0] == 3: #snow
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
self.tiles[y][x] = Tile(self.snow_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
else:
self.tiles[y][x] = Tile(self.snow_tiles[tile[1]])
elif tile[0] == 4: #swamp
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
self.tiles[y][x] = Tile(self.swamp_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
else:
self.tiles[y][x] = Tile(self.swamp_tiles[tile[1]])
elif tile[0] == 5: #rough
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
self.tiles[y][x] = Tile(self.rough_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
else:
self.tiles[y][x] = Tile(self.rough_tiles[tile[1]])
elif tile[0] == 7: #lava
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
self.tiles[y][x] = Tile(self.lava_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
else:
self.tiles[y][x] = Tile(self.lava_tiles[tile[1]])
elif tile[0] == 8: #water
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
tiles = []
for tile in self.water_tiles[tile[1]]:
tiles.append(tile.get_transform(flip_x=flip_x, flip_y=flip_y))
self.tiles[y][x] = WaterTile(tiles)
else:
self.tiles[y][x] = WaterTile(self.water_tiles[tile[1]])
elif tile[0] == 9: #rock
self.tiles[y][x] = Tile(self.rock_tiles[tile[1]])
else:
print tile[0]
self.tiles[y][x] = GrassTile(self.grass_tiles[0])
def get_tile(self, x, y):
assert x >= 0 and y >= 0
return self.tiles[y][x]
class MapView(object):
def __init__(self, mapset, window):
self.window = window
self.mapset = mapset
self._init_view()
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
pyglet.clock.schedule_interval(self.update, 1/60.0)
def _init_view(self):
self.tile_size = 32
#step one tile
self.steps = self.tile_size
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
#drawn tiles
self.tiles_x = min((self.viewport_x//self.tile_size)+2, self.mapset.width)
self.tiles_y = min((self.viewport_y//self.tile_size)+2, self.mapset.height)
self.center_x = False
if self.mapset.width*self.tile_size < self.viewport_x:
self.center_x = True
self.global_x = (self.mapset.width*self.tile_size)//2-(self.viewport_x//2)
self.center_y = False
if self.mapset.height*self.tile_size < self.viewport_y:
self.center_y = True
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)
#undrawn map size
self.undrawn_x = self.tile_size*(self.mapset.width-self.tiles_x)
self.undrawn_y = self.tile_size*(self.mapset.height-self.tiles_y)
#size of full undrawn steps
self.undrawn_steps_x = self.steps*(self.undrawn_x//self.steps)
self.undrawn_steps_y = self.steps*(self.undrawn_y//self.steps)
self.vertex_list = [[] for i in xrange(self.tiles_y)]
self.batch = pyglet.graphics.Batch()
self.view_x = 0
self.view_y = 0
self.global_x = (self.mapset.width*self.tile_size)//2-(self.viewport_x//2)
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)
self.dx = 0
self.dy = 0
#here we translate the global map position so we can draw with it
trans_global_x = self.steps-self.global_x
trans_global_y = self.steps-self.global_y
if trans_global_x < -self.undrawn_steps_x:
mod_x = trans_global_x+self.undrawn_x
elif trans_global_x < self.steps:
mod_x = trans_global_x%self.steps
else:
mod_x = trans_global_x
if trans_global_y < -self.undrawn_steps_y:
mod_y = trans_global_y+self.undrawn_y
elif trans_global_y < self.steps:
mod_y = trans_global_y%self.steps
else:
mod_y = trans_global_y
self.div_x = (trans_global_x-mod_x)//self.tile_size
self.div_y = (trans_global_y-mod_y)//self.tile_size+self.mapset.height-1
vertices = []
tex_coords = []
count = 0
for y in xrange(self.tiles_y):
y1 = y*32+IF_BOTTOM
y2 = y1+32
for x in xrange(self.tiles_x):
x1 = x*32+IF_LEFT
x2 = x1+32
tile = self.mapset.get_tile(x-self.div_x, self.div_y-y)
self.vertex_list[y].append(self.batch.add(4, pyglet.gl.GL_QUADS, self.mapset.group,
('v2i', [x1, y1, x2, y1, x2, y2, x1, y2]),
('t3f', tile.get_tex_coords()),
('c4B', (255,255,255,255)*4)))
self.view_x = mod_x-self.steps
self.view_y = mod_y-self.steps
def on_draw(self):
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
pyglet.gl.glPushMatrix()
pyglet.gl.glTranslatef(self.view_x, self.view_y, 0)
pyglet.gl.glScalef(self.tile_size/32.0, self.tile_size/32.0, 0.0)
self.batch.draw()
pyglet.gl.glPopMatrix()
pyglet.gl.glLoadIdentity()
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glColor4f(1, 0, 1, 1)
pyglet.gl.glRectf(0, 0, self.window.width, IF_BOTTOM)
pyglet.gl.glRectf(self.window.width-IF_RIGHT, 0, self.window.width, self.window.height)
pyglet.gl.glRectf(0, self.window.height-IF_TOP, self.window.width, self.window.height)
pyglet.gl.glRectf(0, 0, IF_LEFT, self.window.height)
def _move(self, dx, dy):
retex = False
#here we translate the global map position so we can draw with it
trans_global_x = self.steps-self.global_x
trans_global_y = self.steps-self.global_y
new_global_x = trans_global_x+dx
new_global_y = trans_global_y+dy
if self.global_x-dx < 0:
new_global_x = self.steps
if self.global_y-dy < 0:
new_global_y = self.steps
if dx-self.global_x < -self.tile_size*self.mapset.width+self.viewport_x:
new_global_x = -self.tile_size*self.mapset.width+self.viewport_x+self.steps
if dy-self.global_y < -self.tile_size*self.mapset.height+self.viewport_y:
new_global_y = -self.tile_size*self.mapset.height+self.viewport_y+self.steps
if new_global_x < -self.undrawn_steps_x:
mod_x = new_global_x+self.undrawn_x
if trans_global_x >= -self.undrawn_steps_x:
retex = True
elif new_global_x < self.steps:
div_x, mod_x = divmod(new_global_x, self.steps)
retex = div_x != trans_global_x//self.steps or retex
else:
mod_x = new_global_x
if new_global_y < -self.undrawn_steps_y:
mod_y = new_global_y+self.undrawn_y
if trans_global_y >= -self.undrawn_steps_y:
retex = True
elif new_global_y < self.steps:
div_y, mod_y = divmod(new_global_y, self.steps)
retex = div_y != trans_global_y//self.steps or retex
else:
mod_y = new_global_y
if retex:
self.div_x = (new_global_x-mod_x)//self.tile_size
self.div_y = (new_global_y-mod_y)//self.tile_size+self.mapset.height-1
for y in xrange(self.tiles_y):
for x in xrange(self.tiles_x):
tile = self.mapset.get_tile(x-self.div_x, self.div_y-y)
self.vertex_list[y][x].tex_coords = tile.get_tex_coords()
if not self.center_x:
self.view_x = mod_x-self.steps
self.global_x = self.steps-new_global_x
if not self.center_y:
self.view_y = mod_y-self.steps
self.global_y = self.steps-new_global_y
def update(self, dt):
try:
if self.window.keys[pyglet.window.key.LCTRL] and \
any([self.window.keys[pyglet.window.key.UP],
self.window.keys[pyglet.window.key.DOWN],
self.window.keys[pyglet.window.key.LEFT],
self.window.keys[pyglet.window.key.RIGHT]]):
if self.window.keys[pyglet.window.key.LEFT]:
x = 1
elif self.window.keys[pyglet.window.key.RIGHT]:
x = -1
else:
x = 0
if self.window.keys[pyglet.window.key.UP]:
y = -1
elif self.window.keys[pyglet.window.key.DOWN]:
y = 1
else:
y = 0
self.dx += x*8
self.dy += y*8
except KeyError:
pass
if self.dx or self.dy:
self._move(self.dx, self.dy)
self.dx = 0
self.dy = 0
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
self.dx += dx
self.dy += dy
return pyglet.event.EVENT_HANDLED
def on_resize(self, width, height):
self._init_view()
def animate_water(self, dt):
for y in xrange(self.tiles_y):
for x in xrange(self.tiles_x):
tile = self.mapset.get_tile(x-self.div_x, self.div_y-y)
if isinstance(tile, WaterTile):
self.vertex_list[y][x].tex_coords = tile.get_next_tex_coords()
class Window(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(800, 600, resizable=True, vsync=False )
img = pyglet.resource.image("data/cursors/default.png")
self.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
self.keys = pyglet.window.key.KeyStateHandler()
self.push_handlers(self.keys)
self.fps = pyglet.clock.ClockDisplay()
def on_draw(self):
self.fps.draw()
def on_key_press(self, symbol, modifiers):
if symbol == pyglet.window.key.F11:
self.set_fullscreen(fullscreen=not self.fullscreen)
def empty(self, dt):
pass
def main():
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
window = Window()
h3m = json.loads(open("test.h3m").read())
loaded_map = h3m["upper_terrain"]
edge_map = [[] for i in xrange(len(loaded_map)+16)]
for num in xrange(len(edge_map)):
if num < 7 or num > len(edge_map)-8:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0])+18)])
elif num == 7:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 16, 0, 0, 0, 0, 0])
line.extend([[-1, 20+i%4, 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0]))])
line.append([-1, 17, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
elif num == len(edge_map)-8:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 19, 0, 0, 0, 0, 0])
line.extend([[-1, 28+i%4, 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0]))])
line.append([-1, 18, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
else:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 32+num%4, 0, 0, 0, 0, 0])
line.extend(loaded_map[num-8])
line.append([-1, 24+num%4, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
edge_map[num] = line
mapset = MapSet(edge_map)
mapview = MapView(mapset, window)
window.push_handlers(mapview)
pyglet.clock.schedule(window.empty)
pyglet.app.run()
if __name__ == '__main__':
main()

@ -0,0 +1,516 @@
#!/usr/bin/python
"""
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pyglet
try:
import json
except ImportError:
try:
import simplejson as json
except ImportError:
import demjson as json
json.loads = json.decode
json.dumps = json.encode
IF_BOTTOM = 48
IF_RIGHT = 200
IF_TOP = IF_LEFT = 8
class Animation(object):
def __init__(self, frames):
self.frames = frames
self.animation = 0
def get_current_frame(self):
return self.frames[self.animation]
def get_next_frame(self):
self.animation = (self.animation+1)%len(self.frames)
return self.frames[self.animation]
class WaterTile(Animation):
def __init__(self, tiles):
super(WaterTile, self).__init__(tiles)
self.tiles = tiles
def get_tex_coords(self):
return self.get_current_frame().tex_coords
def get_next_tex_coords(self):
return self.get_next_frame().tex_coords
class Tile(object):
def __init__(self, tile):
self.tile = tile
def get_tex_coords(self):
return self.tile.tex_coords
def get_next_tex_coords(self):
return self.tile.tex_coords
class MapSet(object):
def __init__(self, loaded_map):
self.width = len(loaded_map[0])
self.height = len(loaded_map)
atlas = pyglet.image.atlas.TextureAtlas(width=2048, height=2048)
self.group = pyglet.graphics.TextureGroup(atlas.texture)
self.grass_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/grass/%d.png'%i))) for i in xrange(79)]
self.snow_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/snow/%d.png'%i))) for i in xrange(79)]
self.lava_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/lava/%d.png'%i))) for i in xrange(79)]
self.swamp_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/swamp/%d.png'%i))) for i in xrange(79)]
self.rough_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/rough/%d.png'%i))) for i in xrange(79)]
self.dirt_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/dirt/%d.png'%i))) for i in xrange(46)]
self.rock_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/rock/%d.png'%i))) for i in xrange(48)]
self.sand_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/sand/%d.png'%i))) for i in xrange(24)]
self.water_tiles = [[atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/water/%d watrtl%02d.pcx/%d.png'%(j,j+1,i)))) for i in xrange(12)] for j in xrange(33)]
self.edge_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/edge/%d EDG%d.PCX'%(i, i+1)))) for i in xrange(36)]
self.tiles = [[Tile(self.grass_tiles[0]) for i in xrange(self.width)] for j in xrange(self.height)]
for y, line in enumerate(loaded_map):
for x, tile in enumerate(line):
if tile[0] == -1: #edge
self.tiles[y][x] = Tile(self.edge_tiles[tile[1]])
elif tile[0] == 0: #dirt
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
self.tiles[y][x] = Tile(self.dirt_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
else:
self.tiles[y][x] = Tile(self.dirt_tiles[tile[1]])
elif tile[0] == 1: #sand
self.tiles[y][x] = Tile(self.sand_tiles[tile[1]])
elif tile[0] == 2: #grass
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
self.tiles[y][x] = Tile(self.grass_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
else:
self.tiles[y][x] = Tile(self.grass_tiles[tile[1]])
elif tile[0] == 3: #snow
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
self.tiles[y][x] = Tile(self.snow_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
else:
self.tiles[y][x] = Tile(self.snow_tiles[tile[1]])
elif tile[0] == 4: #swamp
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
self.tiles[y][x] = Tile(self.swamp_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
else:
self.tiles[y][x] = Tile(self.swamp_tiles[tile[1]])
elif tile[0] == 5: #rough
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
self.tiles[y][x] = Tile(self.rough_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
else:
self.tiles[y][x] = Tile(self.rough_tiles[tile[1]])
elif tile[0] == 7: #lava
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
self.tiles[y][x] = Tile(self.lava_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
else:
self.tiles[y][x] = Tile(self.lava_tiles[tile[1]])
elif tile[0] == 8: #water
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
tiles = []
for tile in self.water_tiles[tile[1]]:
tiles.append(tile.get_transform(flip_x=flip_x, flip_y=flip_y))
self.tiles[y][x] = WaterTile(tiles)
else:
self.tiles[y][x] = WaterTile(self.water_tiles[tile[1]])
elif tile[0] == 9: #rock
self.tiles[y][x] = Tile(self.rock_tiles[tile[1]])
else:
print tile[0]
self.tiles[y][x] = GrassTile(self.grass_tiles[0])
def get_tile(self, x, y):
assert x >= 0 and y >= 0
return self.tiles[y][x]
class MapView(object):
def __init__(self, mapset, window):
self.window = window
self.mapset = mapset
self._first_time_init()
self._init_view()
#mouse position
self.label = pyglet.text.Label('',
font_name="",
font_size=36,
bold=True,
color=(128, 128, 128, 128),
x=self.window.width-10, y=0,
anchor_x='right', anchor_y='bottom')
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
pyglet.clock.schedule_interval(self.update, 1/60.0)
def _first_time_init(self):
self.tile_size = 32
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
#center map
self.global_x = (self.mapset.width*self.tile_size-self.viewport_x+self.tile_size)//2
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)+(self.tile_size//2)
self.mouse_x = self.mouse_dx = 0
self.mouse_y = self.mouse_dy = 0
def _init_view(self):
#step one tile
self.steps = self.tile_size
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
#center map when viewport is too large, else check if map still fills
#whole viewport and if not adjust position accordingly
self.center_x = False
if self.mapset.width*self.tile_size < self.viewport_x:
self.center_x = True
self.global_x = (self.mapset.width*self.tile_size)//2-(self.viewport_x//2)
elif self.global_x > self.tile_size*self.mapset.width-self.viewport_x:
self.global_x = self.tile_size*self.mapset.width-self.viewport_x
elif self.global_x < 0:
self.global_x = 0
self.center_y = False
if self.mapset.height*self.tile_size < self.viewport_y:
self.center_y = True
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)
elif self.global_y > self.tile_size*self.mapset.height-self.viewport_y:
self.global_y = self.tile_size*self.mapset.height-self.viewport_y
elif self.global_y < 0:
self.global_y = 0
#drawn tiles
self.tiles_x = min((self.viewport_x//self.tile_size)+2, self.mapset.width)
self.tiles_y = min((self.viewport_y//self.tile_size)+2, self.mapset.height)
#undrawn map size
self.undrawn_x = self.tile_size*(self.mapset.width-self.tiles_x)
self.undrawn_y = self.tile_size*(self.mapset.height-self.tiles_y)
#size of full undrawn steps
self.undrawn_steps_x = self.steps*(self.undrawn_x//self.steps)
self.undrawn_steps_y = self.steps*(self.undrawn_y//self.steps)
self.vertex_list = [[] for i in xrange(self.tiles_y)]
self.batch = pyglet.graphics.Batch()
self.view_x = 0
self.view_y = 0
self.dx = 0
self.dy = 0
#here we translate the global map position so we can draw with it
trans_global_x = self.steps-self.global_x
trans_global_y = self.steps-self.global_y
if trans_global_x < -self.undrawn_steps_x:
mod_x = trans_global_x+self.undrawn_x
elif trans_global_x < self.steps:
mod_x = trans_global_x%self.steps
else:
mod_x = trans_global_x
if trans_global_y < -self.undrawn_steps_y:
mod_y = trans_global_y+self.undrawn_y
elif trans_global_y < self.steps:
mod_y = trans_global_y%self.steps
else:
mod_y = trans_global_y
self.div_x = (trans_global_x-mod_x)//self.tile_size
self.div_y = (trans_global_y-mod_y)//self.tile_size+self.mapset.height-1
vertices = []
tex_coords = []
count = 0
for y in xrange(self.tiles_y):
y1 = y*32+IF_BOTTOM
y2 = y1+32
for x in xrange(self.tiles_x):
x1 = x*32+IF_LEFT
x2 = x1+32
tile = self.mapset.get_tile(x-self.div_x, self.div_y-y)
self.vertex_list[y].append(self.batch.add(4, pyglet.gl.GL_QUADS, self.mapset.group,
('v2i', [x1, y1, x2, y1, x2, y2, x1, y2]),
('t3f', tile.get_tex_coords()),
('c4B', (255,255,255,255)*4)))
self.view_x = mod_x-self.steps-(self.tile_size-32)//4
self.view_y = mod_y-self.steps-((self.tile_size-32)*3)//2
def on_draw(self):
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
pyglet.gl.glPushMatrix()
pyglet.gl.glTranslatef(self.view_x, self.view_y, 0)
pyglet.gl.glScalef(self.tile_size/32.0, self.tile_size/32.0, 0.0)
self.batch.draw()
pyglet.gl.glPopMatrix()
pyglet.gl.glLoadIdentity()
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glColor4f(1, 0, 1, 1)
pyglet.gl.glRectf(0, 0, self.window.width, IF_BOTTOM)
pyglet.gl.glRectf(self.window.width-IF_RIGHT, 0, self.window.width, self.window.height)
pyglet.gl.glRectf(0, self.window.height-IF_TOP, self.window.width, self.window.height)
pyglet.gl.glRectf(0, 0, IF_LEFT, self.window.height)
self.label.draw()
def _move(self, dx, dy):
#here we translate the global map position so we can draw with it
trans_global_x = self.steps-self.global_x
trans_global_y = self.steps-self.global_y
new_global_x = trans_global_x+dx
new_global_y = trans_global_y+dy
if self.global_x-dx < 0:
new_global_x = self.steps
if self.global_y-dy < 0:
new_global_y = self.steps
if dx-self.global_x < -self.tile_size*self.mapset.width+self.viewport_x:
new_global_x = -self.tile_size*self.mapset.width+self.viewport_x+self.steps
if dy-self.global_y < -self.tile_size*self.mapset.height+self.viewport_y:
new_global_y = -self.tile_size*self.mapset.height+self.viewport_y+self.steps
retex = False
if new_global_x < -self.undrawn_steps_x:
mod_x = new_global_x+self.undrawn_x
if trans_global_x >= -self.undrawn_steps_x:
retex = True
elif new_global_x < self.steps:
div_x, mod_x = divmod(new_global_x, self.steps)
retex = div_x != trans_global_x//self.steps or retex
else:
mod_x = new_global_x
if new_global_y < -self.undrawn_steps_y:
mod_y = new_global_y+self.undrawn_y
if trans_global_y >= -self.undrawn_steps_y:
retex = True
elif new_global_y < self.steps:
div_y, mod_y = divmod(new_global_y, self.steps)
retex = div_y != trans_global_y//self.steps or retex
else:
mod_y = new_global_y
if retex:
self.div_x = (new_global_x-mod_x)//self.tile_size
self.div_y = (new_global_y-mod_y)//self.tile_size+self.mapset.height-1
for y in xrange(self.tiles_y):
for x in xrange(self.tiles_x):
tile = self.mapset.get_tile(x-self.div_x, self.div_y-y)
self.vertex_list[y][x].tex_coords = tile.get_tex_coords()
if not self.center_x:
self.view_x = mod_x-self.steps-(self.tile_size-32)//4
self.global_x = self.steps-new_global_x
if not self.center_y:
self.view_y = mod_y-self.steps-((self.tile_size-32)*3)//2
self.global_y = self.steps-new_global_y
def update(self, dt):
try:
if self.window.keys[pyglet.window.key.LCTRL] and \
any([self.window.keys[pyglet.window.key.UP],
self.window.keys[pyglet.window.key.DOWN],
self.window.keys[pyglet.window.key.LEFT],
self.window.keys[pyglet.window.key.RIGHT]]):
if self.window.keys[pyglet.window.key.LEFT]:
x = 1
elif self.window.keys[pyglet.window.key.RIGHT]:
x = -1
else:
x = 0
if self.window.keys[pyglet.window.key.UP]:
y = -1
elif self.window.keys[pyglet.window.key.DOWN]:
y = 1
else:
y = 0
self.dx += x*8
self.dy += y*8
elif self.window.keys[pyglet.window.key.PLUS] and \
self.tile_size < 32:
self.tile_size+=8
self._init_view()
elif self.window.keys[pyglet.window.key.MINUS] and \
self.tile_size > 16:
self.tile_size-=8
self._init_view()
except KeyError:
pass
if self.dx or self.dy:
self._move(self.dx, self.dy)
self.dx = 0
self.dy = 0
#mouse position:
if self.mouse_x != self.mouse_dx or self.mouse_y != self.mouse_dy:
self.mouse_x = self.mouse_dx
self.mouse_y = self.mouse_dy
x = (self.mouse_x-IF_LEFT-self.view_x
-(self.tile_size-32)//4)//self.tile_size
y = (self.mouse_y-IF_BOTTOM-self.view_y
-((self.tile_size-32)*3)//2)//self.tile_size
self.label.text = "%03d %03d"%(x-self.div_x, self.div_y-y)
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
self.dx += dx
self.dy += dy
self.mouse_dx = x
self.mouse_dy = y
return pyglet.event.EVENT_HANDLED
def on_mouse_motion(self, x, y, dx, dy):
self.mouse_dx = x
self.mouse_dy = y
return pyglet.event.EVENT_HANDLED
def on_resize(self, width, height):
self._init_view()
def animate_water(self, dt):
for y in xrange(self.tiles_y):
for x in xrange(self.tiles_x):
tile = self.mapset.get_tile(x-self.div_x, self.div_y-y)
if isinstance(tile, WaterTile):
self.vertex_list[y][x].tex_coords = tile.get_next_tex_coords()
class Window(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(800, 600, resizable=True, vsync=False )
self.keys = pyglet.window.key.KeyStateHandler()
self.push_handlers(self.keys)
self.fps = pyglet.clock.ClockDisplay()
pyglet.clock.schedule(lambda dt: None)
def on_draw(self):
self.fps.draw()
def on_key_press(self, symbol, modifiers):
if symbol == pyglet.window.key.F11:
self.set_fullscreen(fullscreen=not self.fullscreen)
elif symbol == pyglet.window.key.P:
pyglet.image.get_buffer_manager().get_color_buffer().save('screenshot.png')
class Interface(object):
def __init__(self, window):
self.window = window
def on_mouse_motion(self, x, y, dx, dy):
if IF_LEFT < x < (self.window.width-IF_RIGHT):
pass
else:
return pyglet.event.EVENT_HANDLED
if IF_BOTTOM < y < (self.window.height-IF_TOP):
pass
else:
return pyglet.event.EVENT_HANDLED
class LoadScreen(object):
def __init__(self, window):
self.window = window
self.label = pyglet.text.Label('',
font_name="Linux Libertine",
font_size=28,
x=self.window.width-10, y=10,
anchor_x='right', anchor_y='bottom')
backgroundimg = pyglet.image.load("data/interface/gamselb1.pcx")
self.background = pyglet.sprite.Sprite(backgroundimg)
self.label.text = "PARSING MAP FILE..."
pyglet.clock.schedule_once(self.jsonloader, 0.0)
def on_draw(self):
self.background.draw()
self.label.draw()
def jsonloader(self, dt):
h3m = json.loads(open("test.h3m").read())
self.label.text = "PARSING MAP FILE..."
pyglet.clock.schedule_once(self.loader2, 0.0, h3m["upper_terrain"])
def loader2(self, dt, loaded_map):
edge_map = loaded_map
# edge_map = [[] for i in xrange(len(loaded_map)+16)]
# for num in xrange(len(edge_map)):
# if num < 7 or num > len(edge_map)-8:
# line = []
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0])+18)])
# elif num == 7:
# line = []
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
# line.append([-1, 16, 0, 0, 0, 0, 0])
# line.extend([[-1, 20+i%4, 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0]))])
# line.append([-1, 17, 0, 0, 0, 0, 0])
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
# elif num == len(edge_map)-8:
# line = []
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
# line.append([-1, 19, 0, 0, 0, 0, 0])
# line.extend([[-1, 28+i%4, 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0]))])
# line.append([-1, 18, 0, 0, 0, 0, 0])
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
# else:
# line = []
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
# line.append([-1, 32+num%4, 0, 0, 0, 0, 0])
# line.extend(loaded_map[num-8])
# line.append([-1, 24+num%4, 0, 0, 0, 0, 0])
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
# edge_map[num] = line
self.label.text = "INITIATING MAPSET..."
pyglet.clock.schedule_once(self.loader3, 0.0, edge_map)
def loader3(self, dt, edge_map):
mapset = MapSet(edge_map)
self.label.text = "INITIATING MAPVIEW..."
pyglet.clock.schedule_once(self.loader4, 0.0, mapset)
def loader4(self, dt, mapset):
mapview = MapView(mapset, self.window)
interface = Interface(self.window)
self.window.pop_handlers()
self.window.push_handlers(mapview)
self.window.push_handlers(interface)
img = pyglet.resource.image("data/cursors/0.png")
self.window.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
if __name__ == '__main__':
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
window = Window()
window.push_handlers(LoadScreen(window))
img = pyglet.resource.image("data/cursors/1.png")
window.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
pyglet.app.run()

@ -0,0 +1,619 @@
#!/usr/bin/python
"""
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pyglet
try:
import json
except ImportError:
try:
import simplejson as json
except ImportError:
import demjson as json
json.loads = json.decode
json.dumps = json.encode
IF_BOTTOM = 48
IF_RIGHT = 200
IF_TOP = IF_LEFT = 8
class OrderedTextureGroup(pyglet.graphics.Group):
def __init__(self, order, texture, parent=None):
super(OrderedTextureGroup, self).__init__(parent)
self.texture = texture
self.order = order
def set_state(self):
pyglet.gl.glEnable(self.texture.target)
pyglet.gl.glBindTexture(self.texture.target, self.texture.id)
def unset_state(self):
pyglet.gl.glDisable(self.texture.target)
def __hash__(self):
return hash((self.order, self.texture.target, self.texture.id, self.parent))
def __eq__(self, other):
return (self.__class__ is other.__class__ and
self.order == other.order and
self.texture.target == other.texture.target and
self.texture.id == other.texture.id and
self.parent == self.parent)
def __repr__(self):
return '%s(id=%d)' % (self.__class__.__name__, self.order, self.texture.id)
def __cmp__(self, other):
if isinstance(other, OrderedTextureGroup):
return cmp(self.order, other.order)
return -1
class Animation(object):
def __init__(self, frames):
self.__frames = frames
self.__animation = 0
def get_tex_coords(self):
return self.__frames[self.__animation].tex_coords
tex_coords = property(get_tex_coords)
def get_next_tex_coords(self):
self.__animation = (self.__animation+1)%len(self.__frames)
return self.__frames[self.__animation].tex_coords
next_tex_coords = property(get_next_tex_coords)
class MapSet(object):
def __init__(self, loaded_map, objects, tunedobj):
self.width = len(loaded_map[0])
self.height = len(loaded_map)
#print len(pyglet.resource._default_loader._index)
atlas = pyglet.image.atlas.TextureAtlas(width=1024, height=1024)
atlas2 = pyglet.image.atlas.TextureAtlas(width=2048, height=2048)
self.texture_group = pyglet.graphics.TextureGroup(atlas.texture)
self.group = pyglet.graphics.OrderedGroup(0, self.texture_group)
self.texture_group2 = pyglet.graphics.TextureGroup(atlas2.texture)
self.group_obj = pyglet.graphics.OrderedGroup(1, self.texture_group2)
self.grass_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/grastl.def/%d.png'%i))) for i in xrange(79)]
self.snow_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/snowtl.def/%d.png'%i))) for i in xrange(79)]
self.lava_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/lavatl.def/%d.png'%i))) for i in xrange(79)]
self.swamp_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/swmptl.def/%d.png'%i))) for i in xrange(79)]
self.rough_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/rougtl.def/%d.png'%i))) for i in xrange(79)]
self.dirt_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/dirttl.def/%d.png'%i))) for i in xrange(46)]
self.rock_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/rocktl.def/%d.png'%i))) for i in xrange(48)]
self.sand_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/sandtl.def/%d.png'%i))) for i in xrange(24)]
self.water_tiles = [[atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/watrtl.def/%d/%d.png'%(j,i)))) for i in xrange(12)] for j in xrange(33)]
self.edge_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/edg.def/%d.png'%i))) for i in xrange(36)]
self.tiles = {}
for y, line in enumerate(loaded_map):
for x, tile in enumerate(line):
if tile[0] == -1: #edge
self.tiles[x,y] = Tile(self.edge_tiles[tile[1]])
elif tile[0] == 0: #dirt
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
self.tiles[x,y] = self.dirt_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
else:
self.tiles[x,y] = self.dirt_tiles[tile[1]]
elif tile[0] == 1: #sand
self.tiles[x,y] = self.sand_tiles[tile[1]]
elif tile[0] == 2: #grass
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
self.tiles[x,y] = self.grass_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
else:
self.tiles[x,y] = self.grass_tiles[tile[1]]
elif tile[0] == 3: #snow
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
self.tiles[x,y] = self.snow_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
else:
self.tiles[x,y] = self.snow_tiles[tile[1]]
elif tile[0] == 4: #swamp
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
self.tiles[x,y] = self.swamp_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
else:
self.tiles[x,y] = self.swamp_tiles[tile[1]]
elif tile[0] == 5: #rough
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
self.tiles[x,y] = self.rough_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
else:
self.tiles[x,y] = self.rough_tiles[tile[1]]
elif tile[0] == 7: #lava
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
self.tiles[x,y] = self.lava_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
else:
self.tiles[x,y] = self.lava_tiles[tile[1]]
elif tile[0] == 8: #water
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
tiles = []
for tile in self.water_tiles[tile[1]]:
tiles.append(tile.get_transform(flip_x=flip_x, flip_y=flip_y))
self.tiles[x,y] = Animation(tiles)
else:
self.tiles[x,y] = Animation(self.water_tiles[tile[1]])
elif tile[0] == 9: #rock
self.tiles[x,y] = self.rock_tiles[tile[1]]
else:
raise NotImplementedError
images = [(pyglet.image.load(None, file=pyglet.resource.file("data/map_objects/"+obj["filename"]+"/0.png")), i) for i,obj in enumerate(objects)]
self.objects = [(atlas2.add(image[0]), image[1]) for image in sorted(images, key=lambda i:i[0].height, reverse=True)]
self.objects = [i[0] for i in sorted(self.objects, key=lambda i:i[1])]
self.tunedobj = {}
for obj in [i for i in tunedobj if i["z"]==0]:
if self.tunedobj.get((obj["x"], obj["y"]), None) is not None:
self.tunedobj[obj["x"],obj["y"]].append(self.objects[obj["id"]])
else:
self.tunedobj[obj["x"],obj["y"]] = [self.objects[obj["id"]]]
self.clrrvr = [atlas2.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/clrrvr.def/%d/0.png'%i))) for i in xrange(13)]
for y, line in enumerate(loaded_map):
for x, tile in enumerate(line):
if tile[2] == 1: #clrrvr
flip_x = bool(tile[6] & 4)
flip_y = bool(tile[6] & 8)
if flip_x or flip_y:
c = self.clrrvr[tile[3]].get_transform(flip_x=flip_x, flip_y=flip_y)
else:
c = self.clrrvr[tile[3]]
if self.tunedobj.get((x, y), None) is not None:
self.tunedobj[x, y].append(c)
else:
self.tunedobj[x, y] = [c]
self.dirtrd = [atlas2.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/dirtrd.def/%d.png'%i))) for i in xrange(17)]
self.gravrd = [atlas2.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/gravrd.def/%d.png'%i))) for i in xrange(17)]
self.cobbrd = [atlas2.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/cobbrd.def/%d.png'%i))) for i in xrange(17)]
for y, line in enumerate(loaded_map):
for x, tile in enumerate(line):
if tile[4] == 1: #dirtrd
flip_x = bool(tile[6] & 16)
flip_y = bool(tile[6] & 32)
if flip_x or flip_y:
c = self.dirtrd[tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
else:
c = self.dirtrd[tile[5]]
if self.tunedobj.get((x, y), None) is not None:
self.tunedobj[x, y].append(c)
else:
self.tunedobj[x, y] = [c]
elif tile[4] == 2: #gravrd
flip_x = bool(tile[6] & 16)
flip_y = bool(tile[6] & 32)
if flip_x or flip_y:
c = self.gravrd[tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
else:
c = self.gravrd[tile[5]]
if self.tunedobj.get((x, y), None) is not None:
self.tunedobj[x, y].append(c)
else:
self.tunedobj[x, y] = [c]
elif tile[4] == 3: #cobbrd
flip_x = bool(tile[6] & 16)
flip_y = bool(tile[6] & 32)
if flip_x or flip_y:
c = self.cobbrd[tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
else:
c = self.cobbrd[tile[5]]
if self.tunedobj.get((x, y), None) is not None:
self.tunedobj[x, y].append(c)
else:
self.tunedobj[x, y] = [c]
class MapView(object):
def __init__(self, mapset, window):
self.window = window
self.mapset = mapset
self._first_time_init()
self._init_view()
#mouse position
self.label = pyglet.text.Label('',
font_name="",
font_size=36,
bold=True,
color=(128, 128, 128, 128),
x=self.window.width-10, y=0,
anchor_x='right', anchor_y='bottom')
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
pyglet.clock.schedule_interval(self.update, 1/60.0)
def _first_time_init(self):
self.tile_size = 32
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
#center map
self.global_x = (self.mapset.width*self.tile_size-self.viewport_x+self.tile_size)//2
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)+(self.tile_size//2)
self.mouse_x = self.mouse_dx = 0
self.mouse_y = self.mouse_dy = 0
def _init_view(self):
#step one tile
self.steps = self.tile_size
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
#center map when viewport is too large, else check if map still fills
#whole viewport and if not adjust position accordingly
self.center_x = False
if self.mapset.width*self.tile_size < self.viewport_x:
self.center_x = True
self.global_x = (self.mapset.width*self.tile_size)//2-(self.viewport_x//2)
elif self.global_x > self.tile_size*self.mapset.width-self.viewport_x:
self.global_x = self.tile_size*self.mapset.width-self.viewport_x
elif self.global_x < 0:
self.global_x = 0
self.center_y = False
if self.mapset.height*self.tile_size < self.viewport_y:
self.center_y = True
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)
elif self.global_y > self.tile_size*self.mapset.height-self.viewport_y:
self.global_y = self.tile_size*self.mapset.height-self.viewport_y
elif self.global_y < 0:
self.global_y = 0
#drawn tiles
self.tiles_x = min((self.viewport_x//self.tile_size)+2, self.mapset.width)
self.tiles_y = min((self.viewport_y//self.tile_size)+2, self.mapset.height)
#undrawn map size
self.undrawn_x = self.tile_size*(self.mapset.width-self.tiles_x)
self.undrawn_y = self.tile_size*(self.mapset.height-self.tiles_y)
#size of full undrawn steps
self.undrawn_steps_x = self.steps*(self.undrawn_x//self.steps)
self.undrawn_steps_y = self.steps*(self.undrawn_y//self.steps)
self.vertex_list = [[] for i in xrange(self.tiles_y)]
self.vl_objects = [[] for i in xrange(self.tiles_y+4)]
self.batch = pyglet.graphics.Batch()
self.view_x = 0
self.view_y = 0
self.dx = 0
self.dy = 0
#here we translate the global map position so we can draw with it
trans_global_x = self.steps-self.global_x
trans_global_y = self.steps-self.global_y
if trans_global_x < -self.undrawn_steps_x:
mod_x = trans_global_x+self.undrawn_x
elif trans_global_x < self.steps:
mod_x = trans_global_x%self.steps
else:
mod_x = trans_global_x
if trans_global_y < -self.undrawn_steps_y:
mod_y = trans_global_y+self.undrawn_y
elif trans_global_y < self.steps:
mod_y = trans_global_y%self.steps
else:
mod_y = trans_global_y
self.div_x = (trans_global_x-mod_x)//self.tile_size
self.div_y = (trans_global_y-mod_y)//self.tile_size+self.mapset.height-1
for y in xrange(self.tiles_y-1, -1, -1):
y1 = y*32+IF_BOTTOM
y2 = y1+32
for x in xrange(self.tiles_x-1, -1, -1):
x1 = x*32+IF_LEFT
x2 = x1+32
tile = self.mapset.tiles[x-self.div_x, self.div_y-y]
self.vertex_list[y].insert(0, self.batch.add(4, pyglet.gl.GL_QUADS, self.mapset.group,
('v2i', [x1, y1, x2, y1, x2, y2, x1, y2]),
('t3f', tile.tex_coords),
('c4B', (255,255,255,255)*4)))
vertices = []
tex_coords = []
count = 0
for y in xrange(self.tiles_y-1, -6, -1):
y1 = y*32+IF_BOTTOM
for x in xrange(self.tiles_x+5-1, -1, -1):
o = self.mapset.tunedobj.get((x-self.div_x, self.div_y-y), None)
if(o is not None):
for obj in o:
x1 = x*32+IF_LEFT-obj.width+32
x2 = x1+obj.width
y2 = y1+obj.height
vertices.extend([x1, y1, x2, y1, x2, y2, x1, y2])
tex_coords.extend(obj.tex_coords)
count+=4
self.vl_objects = self.batch.add(count, pyglet.gl.GL_QUADS,
self.mapset.group_obj,
('v2i', vertices),
('t3f', tex_coords),
('c4B', (255,255,255,255)*count))
self.view_x = mod_x-self.steps-(self.tile_size-32)//4
self.view_y = mod_y-self.steps-((self.tile_size-32)*3)//2
def on_draw(self):
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
pyglet.gl.glPushMatrix()
pyglet.gl.glTranslatef(self.view_x, self.view_y, 0)
pyglet.gl.glScalef(self.tile_size/32.0, self.tile_size/32.0, 0.0)
self.batch.draw()
pyglet.gl.glPopMatrix()
pyglet.gl.glLoadIdentity()
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glColor4f(1, 0, 1, 1)
pyglet.gl.glRectf(0, 0, self.window.width, IF_BOTTOM)
pyglet.gl.glRectf(self.window.width-IF_RIGHT, 0, self.window.width, self.window.height)
pyglet.gl.glRectf(0, self.window.height-IF_TOP, self.window.width, self.window.height)
pyglet.gl.glRectf(0, 0, IF_LEFT, self.window.height)
self.label.draw()
def _move(self, dx, dy):
#here we translate the global map position so we can draw with it
trans_global_x = self.steps-self.global_x
trans_global_y = self.steps-self.global_y
new_global_x = trans_global_x+dx
new_global_y = trans_global_y+dy
if self.global_x-dx < 0:
new_global_x = self.steps
if self.global_y-dy < 0:
new_global_y = self.steps
if dx-self.global_x < -self.tile_size*self.mapset.width+self.viewport_x:
new_global_x = -self.tile_size*self.mapset.width+self.viewport_x+self.steps
if dy-self.global_y < -self.tile_size*self.mapset.height+self.viewport_y:
new_global_y = -self.tile_size*self.mapset.height+self.viewport_y+self.steps
retex = False
if new_global_x < -self.undrawn_steps_x:
mod_x = new_global_x+self.undrawn_x
if trans_global_x >= -self.undrawn_steps_x:
retex = True
elif new_global_x < self.steps:
div_x, mod_x = divmod(new_global_x, self.steps)
retex = div_x != trans_global_x//self.steps or retex
else:
mod_x = new_global_x
if new_global_y < -self.undrawn_steps_y:
mod_y = new_global_y+self.undrawn_y
if trans_global_y >= -self.undrawn_steps_y:
retex = True
elif new_global_y < self.steps:
div_y, mod_y = divmod(new_global_y, self.steps)
retex = div_y != trans_global_y//self.steps or retex
else:
mod_y = new_global_y
if retex:
self.div_x = (new_global_x-mod_x)//self.tile_size
self.div_y = (new_global_y-mod_y)//self.tile_size+self.mapset.height-1
for y in xrange(self.tiles_y-1, -1, -1):
for x in xrange(self.tiles_x-1, -1, -1):
tile = self.mapset.tiles[x-self.div_x, self.div_y-y]
self.vertex_list[y][x].tex_coords = tile.tex_coords
vertices = []
tex_coords = []
count = 0
for y in xrange(self.tiles_y-1, -6, -1):
y1 = y*32+IF_BOTTOM
for x in xrange(self.tiles_x+5-1, -1, -1):
o = self.mapset.tunedobj.get((x-self.div_x, self.div_y-y), None)
if(o is not None):
for obj in o:
x1 = x*32+IF_LEFT-obj.width+32
x2 = x1+obj.width
y2 = y1+obj.height
tex_coords.extend(obj.tex_coords)
vertices.extend([x1, y1, x2, y1, x2, y2, x1, y2])
count+=4
self.vl_objects.resize(count)
self.vl_objects.tex_coords = tex_coords
self.vl_objects.vertices = vertices
self.vl_objects.colors = (255,255,255,255)*count
if not self.center_x:
self.view_x = mod_x-self.steps-(self.tile_size-32)//4
self.global_x = self.steps-new_global_x
if not self.center_y:
self.view_y = mod_y-self.steps-((self.tile_size-32)*3)//2
self.global_y = self.steps-new_global_y
def update(self, dt):
try:
if self.window.keys[pyglet.window.key.LCTRL] and \
any([self.window.keys[pyglet.window.key.UP],
self.window.keys[pyglet.window.key.DOWN],
self.window.keys[pyglet.window.key.LEFT],
self.window.keys[pyglet.window.key.RIGHT]]):
if self.window.keys[pyglet.window.key.LEFT]:
x = 1
elif self.window.keys[pyglet.window.key.RIGHT]:
x = -1
else:
x = 0
if self.window.keys[pyglet.window.key.UP]:
y = -1
elif self.window.keys[pyglet.window.key.DOWN]:
y = 1
else:
y = 0
self.dx += x*8
self.dy += y*8
elif self.window.keys[pyglet.window.key.PLUS] and \
self.tile_size < 32:
self.tile_size+=8
self._init_view()
elif self.window.keys[pyglet.window.key.MINUS] and \
self.tile_size > 16:
self.tile_size-=8
self._init_view()
except KeyError:
pass
if self.dx or self.dy:
self._move(self.dx, self.dy)
self.dx = 0
self.dy = 0
#mouse position:
if self.mouse_x != self.mouse_dx or self.mouse_y != self.mouse_dy:
self.mouse_x = self.mouse_dx
self.mouse_y = self.mouse_dy
x = (self.mouse_x-IF_LEFT-self.view_x
-(self.tile_size-32)//4)//self.tile_size
y = (self.mouse_y-IF_BOTTOM-self.view_y
-((self.tile_size-32)*3)//2)//self.tile_size
self.label.text = "%03d %03d"%(x-self.div_x, self.div_y-y)
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
self.dx += dx
self.dy += dy
self.mouse_dx = x
self.mouse_dy = y
return pyglet.event.EVENT_HANDLED
def on_mouse_motion(self, x, y, dx, dy):
self.mouse_dx = x
self.mouse_dy = y
return pyglet.event.EVENT_HANDLED
def on_resize(self, width, height):
self._init_view()
def animate_water(self, dt):
for y in xrange(self.tiles_y):
for x in xrange(self.tiles_x):
tile = self.mapset.tiles[x-self.div_x, self.div_y-y]
if isinstance(tile, Animation):
self.vertex_list[y][x].tex_coords = tile.next_tex_coords
class Window(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(1024, 768, resizable=True, vsync=False )
self.keys = pyglet.window.key.KeyStateHandler()
self.push_handlers(self.keys)
self.fps = pyglet.clock.ClockDisplay()
pyglet.clock.schedule(lambda dt: None)
def on_draw(self):
self.fps.draw()
def on_key_press(self, symbol, modifiers):
if symbol == pyglet.window.key.F11:
self.set_fullscreen(fullscreen=not self.fullscreen)
elif symbol == pyglet.window.key.P:
pyglet.image.get_buffer_manager().get_color_buffer().save('screenshot.png')
class Interface(object):
def __init__(self, window):
self.window = window
def on_mouse_motion(self, x, y, dx, dy):
if IF_LEFT < x < (self.window.width-IF_RIGHT):
pass
else:
return pyglet.event.EVENT_HANDLED
if IF_BOTTOM < y < (self.window.height-IF_TOP):
pass
else:
return pyglet.event.EVENT_HANDLED
class LoadScreen(object):
def __init__(self, window):
self.window = window
self.label = pyglet.text.Label('',
font_name="Linux Libertine",
font_size=28,
x=self.window.width-10, y=10,
anchor_x='right', anchor_y='bottom')
self.label.text = "PARSING MAP FILE..."
h3m = json.loads(pyglet.resource.file("test.h3m").read())
self.label.text = "PARSING MAP FILE..."
# edge_map = [[] for i in xrange(len(loaded_map)+16)]
# for num in xrange(len(edge_map)):
# if num < 7 or num > len(edge_map)-8:
# line = []
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0])+18)])
# elif num == 7:
# line = []
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
# line.append([-1, 16, 0, 0, 0, 0, 0])
# line.extend([[-1, 20+i%4, 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0]))])
# line.append([-1, 17, 0, 0, 0, 0, 0])
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
# elif num == len(edge_map)-8:
# line = []
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
# line.append([-1, 19, 0, 0, 0, 0, 0])
# line.extend([[-1, 28+i%4, 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0]))])
# line.append([-1, 18, 0, 0, 0, 0, 0])
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
# else:
# line = []
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
# line.append([-1, 32+num%4, 0, 0, 0, 0, 0])
# line.extend(loaded_map[num-8])
# line.append([-1, 24+num%4, 0, 0, 0, 0, 0])
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
# edge_map[num] = line
self.label.text = "INITIATING MAPSET..."
mapset = MapSet(h3m["upper_terrain"], h3m["objects"], h3m["tunedobj"])
self.label.text = "INITIATING MAPVIEW..."
mapview = MapView(mapset, self.window)
interface = Interface(self.window)
self.window.pop_handlers()
self.window.push_handlers(mapview)
self.window.push_handlers(interface)
self.window.push_handlers(self.window.keys)
if __name__ == '__main__':
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
window = Window()
window.push_handlers(LoadScreen(window))
img = pyglet.resource.image("data/cursors/cradvntr.def/0.png")
window.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
pyglet.app.run()

@ -0,0 +1,718 @@
#!/usr/bin/python
"""
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pyglet
try:
import json
except ImportError:
try:
import simplejson as json
except ImportError:
import demjson as json
json.loads = json.decode
json.dumps = json.encode
IF_BOTTOM = 48
IF_RIGHT = 200
IF_TOP = IF_LEFT = 8
class Animation(object):
def __init__(self, frames):
self.__frames = frames
self.__animation = 0
self.width = frames[0].width
self.height = frames[0].height
def next_frame(self):
self.__animation = (self.__animation+1)%len(self.__frames)
def get_tex_coords(self):
return self.__frames[self.__animation].tex_coords
tex_coords = property(get_tex_coords)
def get_group(self):
return self.__frames[self.__animation].group
group = property(get_group)
class MapSet(object):
def load_map_object(self, file, order=0):
image = pyglet.image.load(None, file=pyglet.resource.file(file))
try:
texture_region = self.current_atlas.add(image)
except pyglet.image.atlas.AllocatorException:
self.current_atlas = pyglet.image.atlas.TextureAtlas(2048, 2048)
print "atlas"
texture_region = self.current_atlas.add(image)
ordered_group = pyglet.graphics.OrderedGroup(order)
group = pyglet.graphics.TextureGroup(self.current_atlas.texture, ordered_group)
if group not in self.groups:
self.groups.append(group)
texture_region.group = self.groups.index(group)
return texture_region
def __init__(self, loaded_map, objects, tunedobj):
self.width = len(loaded_map[0])
self.height = len(loaded_map)
self.current_atlas = pyglet.image.atlas.TextureAtlas(2048, 2048)
print "atlas"
self.groups = []
self.tiles = {}
tile_textures = {}
for y, line in enumerate(loaded_map):
for x, tile in enumerate(line):
if tile[0] == -1: #edge
if "edg" not in tile_textures.keys():
tile_textures["edg"] = [self.load_map_object('data/tiles/edg.def/%d.png'%i, 100) for i in xrange(36)]
self.tiles[x,y] = [tile_textures["edg"][tile[1]]]
elif tile[0] == 0: #dirt
if "dirttl" not in tile_textures.keys():
tile_textures["dirttl"] = [self.load_map_object('data/tiles/dirttl.def/%d.png'%i, 0) for i in xrange(46)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["dirttl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["dirttl"][tile[1]].group
self.tiles[x,y] = [new]
else:
self.tiles[x,y] = [tile_textures["dirttl"][tile[1]]]
elif tile[0] == 1: #sand
if "sandtl" not in tile_textures.keys():
tile_textures["sandtl"] = [self.load_map_object('data/tiles/sandtl.def/%d.png'%i, 0) for i in xrange(24)]
self.tiles[x,y] = [tile_textures["sandtl"][tile[1]]]
elif tile[0] == 2: #grass
if "grastl" not in tile_textures.keys():
tile_textures["grastl"] = [self.load_map_object('data/tiles/grastl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["grastl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["grastl"][tile[1]].group
self.tiles[x,y] = [new]
else:
self.tiles[x,y] = [tile_textures["grastl"][tile[1]]]
elif tile[0] == 3: #snow
if "snowtl" not in tile_textures.keys():
tile_textures["snowtl"] = [self.load_map_object('data/tiles/snowtl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["snowtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["snowtl"][tile[1]].group
self.tiles[x,y] = [new]
else:
self.tiles[x,y] = [tile_textures["snowtl"][tile[1]]]
elif tile[0] == 4: #swamp
if "swmptl" not in tile_textures.keys():
tile_textures["swmptl"] = [self.load_map_object('data/tiles/swmptl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["swmptl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["swmptl"][tile[1]].group
self.tiles[x,y] = [new]
else:
self.tiles[x,y] = [tile_textures["swmptl"][tile[1]]]
elif tile[0] == 5: #rough
if "rougtl" not in tile_textures.keys():
tile_textures["rougtl"] = [self.load_map_object('data/tiles/rougtl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["rougtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["rougtl"][tile[1]].group
self.tiles[x,y] = [new]
else:
self.tiles[x,y] = [tile_textures["rougtl"][tile[1]]]
elif tile[0] == 7: #lava
if "lavatl" not in tile_textures.keys():
tile_textures["lavatl"] = [self.load_map_object('data/tiles/lavatl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["lavatl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["lavatl"][tile[1]].group
self.tiles[x,y] = [new]
else:
self.tiles[x,y] = [tile_textures["lavatl"][tile[1]]]
elif tile[0] == 8: #water
if "watrtl" not in tile_textures.keys():
tile_textures["watrtl"] = []
for j in xrange(33):
tile_textures["watrtl"].append([self.load_map_object('data/tiles/watrtl.def/%d/%d.png'%(j,i), 0) for i in xrange(12)])
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
tiles = []
for watrtl in tile_textures["watrtl"][tile[1]]:
new = watrtl.get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = watrtl.group
tiles.append(new)
self.tiles[x,y] = [Animation(tiles)]
else:
self.tiles[x,y] = [Animation(tile_textures["watrtl"][tile[1]])]
elif tile[0] == 9: #rock
if "rocktl" not in tile_textures.keys():
tile_textures["rocktl"] = [self.load_map_object('data/tiles/rocktl.def/%d.png'%i, 0) for i in xrange(48)]
self.tiles[x,y] = [tile_textures["rocktl"][tile[1]]]
else:
raise NotImplementedError
if tile[2] == 0: #no river
pass
elif tile[2] == 1: #clrrvr
if "clrrvr" not in tile_textures.keys():
tile_textures["clrrvr"] = [[self.load_map_object('data/tiles/clrrvr.def/%d/%d.png'%(i, j), 1) for j in xrange(12)] for i in xrange(13)]
flip_x = bool(tile[6] & 4)
flip_y = bool(tile[6] & 8)
if flip_x or flip_y:
tiles = []
for clrrvr in tile_textures["clrrvr"][tile[3]]:
new = clrrvr.get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = clrrvr.group
tiles.append(new)
self.tiles[x, y].append(Animation(tiles))
else:
self.tiles[x, y].append(Animation(tile_textures["clrrvr"][tile[3]]))
elif tile[2] == 2: #icyrvr
if "icyrvr" not in tile_textures.keys():
tile_textures["icyrvr"] = [self.load_map_object('data/tiles/icyrvr.def/%d.png'%i, 1) for i in xrange(13)]
flip_x = bool(tile[6] & 4)
flip_y = bool(tile[6] & 8)
if flip_x or flip_y:
new = tile_textures["icyrvr"][tile[3]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["icyrvr"][tile[3]].group
self.tiles[x, y].append(new)
else:
self.tiles[x, y].append(tile_textures["icyrvr"][tile[3]])
elif tile[2] == 3: #mudrvr
if "mudrvr" not in tile_textures.keys():
tile_textures["mudrvr"] = [[self.load_map_object('data/tiles/mudrvr.def/%d/%d.png'%(i, j), 1) for j in xrange(12)] for i in xrange(13)]
flip_x = bool(tile[6] & 4)
flip_y = bool(tile[6] & 8)
if flip_x or flip_y:
tiles = []
for mudrvr in tile_textures["mudrvr"][tile[3]]:
new = mudrvr.get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = mudrvr.group
tiles.append(new)
self.tiles[x, y].append(Animation(tiles))
else:
self.tiles[x, y].append(Animation(tile_textures["mudrvr"][tile[3]]))
elif tile[2] == 4: #lavrvr
if "lavrvr" not in tile_textures.keys():
tile_textures["lavrvr"] = [[self.load_map_object('data/tiles/lavrvr.def/%d/%d.png'%(i, j), 1) for j in xrange(9)] for i in xrange(13)]
flip_x = bool(tile[6] & 4)
flip_y = bool(tile[6] & 8)
if flip_x or flip_y:
tiles = []
for lavrvr in tile_textures["lavrvr"][tile[3]]:
new = lavrvr.get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = lavrvr.group
tiles.append(new)
self.tiles[x, y].append(Animation(tiles))
else:
self.tiles[x, y].append(Animation(tile_textures["lavrvr"][tile[3]]))
else:
raise NotImplementedError, tile[2]
if tile[4] == 0: #no road
pass
elif tile[4] == 1: #dirtrd
if "dirtrd" not in tile_textures.keys():
tile_textures["dirtrd"] = [self.load_map_object('data/tiles/dirtrd.def/%d.png'%i, 1) for i in xrange(17)]
flip_x = bool(tile[6] & 16)
flip_y = bool(tile[6] & 32)
if flip_x or flip_y:
new = tile_textures["dirtrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["dirtrd"][tile[5]].group
self.tiles[x, y].append(new)
else:
self.tiles[x, y].append(tile_textures["dirtrd"][tile[5]])
elif tile[4] == 2: #gravrd
if "gravrd" not in tile_textures.keys():
tile_textures["gravrd"] = [self.load_map_object('data/tiles/gravrd.def/%d.png'%i, 1) for i in xrange(17)]
flip_x = bool(tile[6] & 16)
flip_y = bool(tile[6] & 32)
if flip_x or flip_y:
new = tile_textures["gravrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["gravrd"][tile[5]].group
self.tiles[x, y].append(new)
else:
self.tiles[x, y].append(tile_textures["gravrd"][tile[5]])
elif tile[4] == 3: #cobbrd
if "cobbrd" not in tile_textures.keys():
tile_textures["cobbrd"] = [self.load_map_object('data/tiles/cobbrd.def/%d.png'%i, 1) for i in xrange(17)]
flip_x = bool(tile[6] & 16)
flip_y = bool(tile[6] & 32)
if flip_x or flip_y:
new = tile_textures["cobbrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["cobbrd"][tile[5]].group
self.tiles[x, y].append(new)
else:
self.tiles[x, y].append(tile_textures["cobbrd"][tile[5]])
else:
raise NotImplementedError, tile[4]
images = []
for order, obj in enumerate(objects):
imgs = []
i = 0
while 1:
imgs.append(pyglet.image.load(None, file=pyglet.resource.file("data/map_objects/"+obj["filename"]+"/%d.png"%i)))
i+=1
if "data/map_objects/"+obj["filename"]+"/%d.png"%i not in pyglet.resource._default_loader._index.keys():
break;
images.append((imgs, order))
self.objects = []
for imgs in sorted(images, key=lambda i:i[0][0].height, reverse=True):
textures = []
try:
textures = [self.current_atlas.add(img) for img in imgs[0]]
except pyglet.image.atlas.AllocatorException:
self.current_atlas = pyglet.image.atlas.TextureAtlas(2048, 2048)
print "atlas"
textures = [self.current_atlas.add(img) for img in imgs[0]]
ordered_group = pyglet.graphics.OrderedGroup(2)
group = pyglet.graphics.TextureGroup(self.current_atlas.texture, ordered_group)
if group not in self.groups:
self.groups.append(group)
group = self.groups.index(group)
for texture in textures:
texture.group = group
self.objects.append((textures, imgs[1]))
self.objects = [i[0] for i in sorted(self.objects, key=lambda i:i[1])]
self.tunedobj = {}
for obj in [i for i in tunedobj if i["z"]==0]:
if len(self.objects[obj["id"]]) == 1:
self.tiles[obj["x"]+9,obj["y"]+8].append(self.objects[obj["id"]][0])
else:
self.tiles[obj["x"]+9,obj["y"]+8].append(Animation(self.objects[obj["id"]]))
class MapView(object):
def __init__(self, mapset, window):
self.window = window
self.mapset = mapset
self._first_time_init()
self._init_view()
#mouse position
self.label = pyglet.text.Label('',
font_name="",
font_size=36,
bold=True,
color=(128, 128, 128, 128),
x=self.window.width-10, y=0,
anchor_x='right', anchor_y='bottom')
#pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
pyglet.clock.schedule_interval(self.update, 1/60.0)
def _first_time_init(self):
self.tile_size = 32
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
#center map
self.global_x = (self.mapset.width*self.tile_size-self.viewport_x+self.tile_size)//2
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)+(self.tile_size//2)
self.mouse_x = self.mouse_dx = 0
self.mouse_y = self.mouse_dy = 0
def _init_view(self):
#step one tile
self.steps = self.tile_size
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
#center map when viewport is too large, else check if map still fills
#whole viewport and if not adjust position accordingly
self.center_x = False
if self.mapset.width*self.tile_size < self.viewport_x:
self.center_x = True
self.global_x = (self.mapset.width*self.tile_size)//2-(self.viewport_x//2)
elif self.global_x > self.tile_size*self.mapset.width-self.viewport_x:
self.global_x = self.tile_size*self.mapset.width-self.viewport_x
elif self.global_x < 0:
self.global_x = 0
self.center_y = False
if self.mapset.height*self.tile_size < self.viewport_y:
self.center_y = True
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)
elif self.global_y > self.tile_size*self.mapset.height-self.viewport_y:
self.global_y = self.tile_size*self.mapset.height-self.viewport_y
elif self.global_y < 0:
self.global_y = 0
#drawn tiles
self.tiles_x = min((self.viewport_x//self.tile_size)+2, self.mapset.width)
self.tiles_y = min((self.viewport_y//self.tile_size)+2, self.mapset.height)
#undrawn map size
self.undrawn_x = self.tile_size*(self.mapset.width-self.tiles_x)
self.undrawn_y = self.tile_size*(self.mapset.height-self.tiles_y)
#size of full undrawn steps
self.undrawn_steps_x = self.steps*(self.undrawn_x//self.steps)
self.undrawn_steps_y = self.steps*(self.undrawn_y//self.steps)
self.batch = pyglet.graphics.Batch()
self.view_x = 0
self.view_y = 0
self.dx = 0
self.dy = 0
#here we translate the global map position so we can draw with it
trans_global_x = self.steps-self.global_x
trans_global_y = self.steps-self.global_y
if trans_global_x < -self.undrawn_steps_x:
mod_x = trans_global_x+self.undrawn_x
elif trans_global_x < self.steps:
mod_x = trans_global_x%self.steps
else:
mod_x = trans_global_x
if trans_global_y < -self.undrawn_steps_y:
mod_y = trans_global_y+self.undrawn_y
elif trans_global_y < self.steps:
mod_y = trans_global_y%self.steps
else:
mod_y = trans_global_y
self.div_x = (trans_global_x-mod_x)//self.tile_size
self.div_y = (trans_global_y-mod_y)//self.tile_size+self.mapset.height-1
self.vl_objects = [None for i, value in enumerate(self.mapset.groups)]
vertices = [[] for i, value in enumerate(self.mapset.groups)]
tex_coords = [[] for i, value in enumerate(self.mapset.groups)]
count = [0 for i, value in enumerate(self.mapset.groups)]
for y in xrange(self.tiles_y-1, -6, -1):
y1 = y*32+IF_BOTTOM
for x in xrange(self.tiles_x+5-1, -1, -1):
for obj in self.mapset.tiles.get((x-self.div_x, self.div_y-y), []):
x1 = x*32+IF_LEFT-obj.width+32
x2 = x1+obj.width
y2 = y1+obj.height
vertices[obj.group].extend([x1, y1, x2, y1, x2, y2, x1, y2])
tex_coords[obj.group].extend(obj.tex_coords)
count[obj.group]+=4
for i, group in enumerate(self.mapset.groups):
if count[i] != 0:
self.vl_objects[i] = self.batch.add(count[i], pyglet.gl.GL_QUADS,
group,
('v2i', vertices[i]),
('t3f', tex_coords[i]),
('c4B', (255,255,255,255)*count[i]))
self.view_x = mod_x-self.steps-(self.tile_size-32)//4
self.view_y = mod_y-self.steps-((self.tile_size-32)*3)//2
def on_draw(self):
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
pyglet.gl.glPushMatrix()
pyglet.gl.glTranslatef(self.view_x, self.view_y, 0)
pyglet.gl.glScalef(self.tile_size/32.0, self.tile_size/32.0, 0.0)
self.batch.draw()
pyglet.gl.glPopMatrix()
pyglet.gl.glLoadIdentity()
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glColor4f(1, 0, 1, 1)
pyglet.gl.glRectf(0, 0, self.window.width, IF_BOTTOM)
pyglet.gl.glRectf(self.window.width-IF_RIGHT, 0, self.window.width, self.window.height)
pyglet.gl.glRectf(0, self.window.height-IF_TOP, self.window.width, self.window.height)
pyglet.gl.glRectf(0, 0, IF_LEFT, self.window.height)
self.label.draw()
def _move(self, dx, dy):
#here we translate the global map position so we can draw with it
trans_global_x = self.steps-self.global_x
trans_global_y = self.steps-self.global_y
new_global_x = trans_global_x+dx
new_global_y = trans_global_y+dy
if self.global_x-dx < 0:
new_global_x = self.steps
if self.global_y-dy < 0:
new_global_y = self.steps
if dx-self.global_x < -self.tile_size*self.mapset.width+self.viewport_x:
new_global_x = -self.tile_size*self.mapset.width+self.viewport_x+self.steps
if dy-self.global_y < -self.tile_size*self.mapset.height+self.viewport_y:
new_global_y = -self.tile_size*self.mapset.height+self.viewport_y+self.steps
retex = False
if new_global_x < -self.undrawn_steps_x:
mod_x = new_global_x+self.undrawn_x
if trans_global_x >= -self.undrawn_steps_x:
retex = True
elif new_global_x < self.steps:
div_x, mod_x = divmod(new_global_x, self.steps)
retex = div_x != trans_global_x//self.steps or retex
else:
mod_x = new_global_x
if new_global_y < -self.undrawn_steps_y:
mod_y = new_global_y+self.undrawn_y
if trans_global_y >= -self.undrawn_steps_y:
retex = True
elif new_global_y < self.steps:
div_y, mod_y = divmod(new_global_y, self.steps)
retex = div_y != trans_global_y//self.steps or retex
else:
mod_y = new_global_y
if retex:
self.div_x = (new_global_x-mod_x)//self.tile_size
self.div_y = (new_global_y-mod_y)//self.tile_size+self.mapset.height-1
vertices = [[] for i, value in enumerate(self.mapset.groups)]
tex_coords = [[] for i, value in enumerate(self.mapset.groups)]
count = [0 for i, value in enumerate(self.mapset.groups)]
for y in xrange(self.tiles_y-1, -6, -1):
y1 = y*32+IF_BOTTOM
for x in xrange(self.tiles_x+5-1, -1, -1):
for obj in self.mapset.tiles.get((x-self.div_x, self.div_y-y), []):
x1 = x*32+IF_LEFT-obj.width+32
x2 = x1+obj.width
y2 = y1+obj.height
tex_coords[obj.group].extend(obj.tex_coords)
vertices[obj.group].extend([x1, y1, x2, y1, x2, y2, x1, y2])
count[obj.group]+=4
for i, group in enumerate(self.mapset.groups):
if count[i] == 0:
if self.vl_objects[i] is None:
pass
else:
self.vl_objects[i].delete()
self.vl_objects[i] = None
else:
if self.vl_objects[i] is None:
self.vl_objects[i] = self.batch.add(count[i], pyglet.gl.GL_QUADS,
group,
('v2i', vertices[i]),
('t3f', tex_coords[i]),
('c4B', (255,255,255,255)*count[i]))
else:
self.vl_objects[i].resize(count[i])
self.vl_objects[i].tex_coords = tex_coords[i]
self.vl_objects[i].vertices = vertices[i]
self.vl_objects[i].colors = (255,255,255,255)*count[i]
if not self.center_x:
self.view_x = mod_x-self.steps-(self.tile_size-32)//4
self.global_x = self.steps-new_global_x
if not self.center_y:
self.view_y = mod_y-self.steps-((self.tile_size-32)*3)//2
self.global_y = self.steps-new_global_y
def update(self, dt):
try:
if self.window.keys[pyglet.window.key.LCTRL] and \
any([self.window.keys[pyglet.window.key.UP],
self.window.keys[pyglet.window.key.DOWN],
self.window.keys[pyglet.window.key.LEFT],
self.window.keys[pyglet.window.key.RIGHT]]):
if self.window.keys[pyglet.window.key.LEFT]:
x = 1
elif self.window.keys[pyglet.window.key.RIGHT]:
x = -1
else:
x = 0
if self.window.keys[pyglet.window.key.UP]:
y = -1
elif self.window.keys[pyglet.window.key.DOWN]:
y = 1
else:
y = 0
self.dx += x*8
self.dy += y*8
elif self.window.keys[pyglet.window.key.PLUS] and \
self.tile_size < 32:
self.tile_size+=8
self._init_view()
elif self.window.keys[pyglet.window.key.MINUS] and \
self.tile_size > 16:
self.tile_size-=8
self._init_view()
except KeyError:
pass
if self.dx or self.dy:
self._move(self.dx, self.dy)
self.dx = 0
self.dy = 0
#mouse position:
if self.mouse_x != self.mouse_dx or self.mouse_y != self.mouse_dy:
self.mouse_x = self.mouse_dx
self.mouse_y = self.mouse_dy
x = (self.mouse_x-IF_LEFT-self.view_x
-(self.tile_size-32)//4)//self.tile_size
y = (self.mouse_y-IF_BOTTOM-self.view_y
-((self.tile_size-32)*3)//2)//self.tile_size
self.label.text = "%03d %03d"%(x-self.div_x, self.div_y-y)
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
self.dx += dx
self.dy += dy
self.mouse_dx = x
self.mouse_dy = y
return pyglet.event.EVENT_HANDLED
def on_mouse_motion(self, x, y, dx, dy):
self.mouse_dx = x
self.mouse_dy = y
return pyglet.event.EVENT_HANDLED
def on_resize(self, width, height):
self._init_view()
def animate_water(self, dt):
tex_coords = [[] for i, value in enumerate(self.mapset.groups)]
for y in xrange(self.tiles_y-1, -6, -1):
for x in xrange(self.tiles_x+5-1, -1, -1):
for obj in self.mapset.tiles.get((x-self.div_x, self.div_y-y), []):
if isinstance(obj, Animation):
obj.next_frame()
tex_coords[obj.group].extend(obj.tex_coords)
for i, group in enumerate(self.mapset.groups):
if len(tex_coords[i]) != 0:
self.vl_objects[i].tex_coords = tex_coords[i]
class Window(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(1280, 1024, resizable=True, vsync=False)
self.keys = pyglet.window.key.KeyStateHandler()
self.push_handlers(self.keys)
self.fps = pyglet.clock.ClockDisplay()
pyglet.clock.schedule(lambda dt: None)
def on_draw(self):
self.fps.draw()
def on_key_press(self, symbol, modifiers):
if symbol == pyglet.window.key.F11:
self.set_fullscreen(fullscreen=not self.fullscreen)
elif symbol == pyglet.window.key.P:
pyglet.image.get_buffer_manager().get_color_buffer().save('screenshot.png', encoder=PNGRGBEncoder())
class PNGRGBEncoder(pyglet.image.codecs.ImageEncoder):
def encode(self, image, file, filename):
import Image
image = image.get_image_data()
format = image.format
pitch = -(image.width * len(format))
pil_image = Image.fromstring(
format, (image.width, image.height), image.get_data(format, pitch))
try:
#.convert('P', palette=Image.WEB)
pil_image.convert("RGB").save(file)
except Exception, e:
raise ImageEncodeException(e)
class Interface(object):
def __init__(self, window):
self.window = window
def on_mouse_motion(self, x, y, dx, dy):
if IF_LEFT < x < (self.window.width-IF_RIGHT):
pass
else:
return pyglet.event.EVENT_HANDLED
if IF_BOTTOM < y < (self.window.height-IF_TOP):
pass
else:
return pyglet.event.EVENT_HANDLED
class LoadScreen(object):
def __init__(self, window):
self.window = window
self.label = pyglet.text.Label('',
font_name="Linux Libertine",
font_size=28,
x=self.window.width-10, y=10,
anchor_x='right', anchor_y='bottom')
self.label.text = "PARSING MAP FILE..."
h3m = json.loads(pyglet.resource.file("test.h3m").read())
self.label.text = "PARSING MAP FILE..."
edge_map = [[] for i in xrange(len(h3m["upper_terrain"])+16)]
for num in xrange(len(edge_map)):
if num < 7 or num > len(edge_map)-8:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0])+18)])
elif num == 7:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 16, 0, 0, 0, 0, 0])
line.extend([[-1, 20+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0]))])
line.append([-1, 17, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
elif num == len(edge_map)-8:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 19, 0, 0, 0, 0, 0])
line.extend([[-1, 28+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0]))])
line.append([-1, 18, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
else:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 32+num%4, 0, 0, 0, 0, 0])
line.extend(h3m["upper_terrain"][num-8])
line.append([-1, 24+num%4, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
edge_map[num] = line
h3m["upper_terrain"] = edge_map
self.label.text = "INITIATING MAPSET..."
mapset = MapSet(h3m["upper_terrain"], h3m["objects"], h3m["tunedobj"])
self.label.text = "INITIATING MAPVIEW..."
mapview = MapView(mapset, self.window)
interface = Interface(self.window)
self.window.pop_handlers()
self.window.push_handlers(mapview)
self.window.push_handlers(interface)
self.window.push_handlers(self.window.keys)
if __name__ == '__main__':
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
window = Window()
window.push_handlers(LoadScreen(window))
img = pyglet.resource.image("data/cursors/cradvntr.def/0.png")
window.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
pyglet.app.run()

@ -0,0 +1,735 @@
#!/usr/bin/python
"""
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pyglet
try:
import json
except ImportError:
try:
import simplejson as json
except ImportError:
import demjson as json
json.loads = json.decode
json.dumps = json.encode
IF_BOTTOM = 48
IF_RIGHT = 200
IF_TOP = IF_LEFT = 8
class Animation(object):
def __init__(self, frames):
self.__frames = frames
self.__animation = 0
self.width = frames[0].width
self.height = frames[0].height
def next_frame(self):
self.__animation = (self.__animation+1)%len(self.__frames)
def get_tex_coords(self):
return self.__frames[self.__animation].tex_coords
tex_coords = property(get_tex_coords)
def get_group(self):
return self.__frames[self.__animation].group
group = property(get_group)
class MapSet(object):
def load_map_object(self, file, order=0):
image = pyglet.image.load(None, file=pyglet.resource.file(file))
try:
texture_region = self.current_atlas.add(image)
except pyglet.image.atlas.AllocatorException:
self.current_atlas = pyglet.image.atlas.TextureAtlas(512, 512)
print "atlas"
texture_region = self.current_atlas.add(image)
ordered_group = pyglet.graphics.OrderedGroup(order)
group = pyglet.graphics.TextureGroup(self.current_atlas.texture, ordered_group)
if group not in self.groups:
self.groups.append(group)
texture_region.group = self.groups.index(group)
return texture_region
def __init__(self, loaded_map, objects, tunedobj):
self.width = len(loaded_map[0])
self.height = len(loaded_map)
self.current_atlas = pyglet.image.atlas.TextureAtlas(512, 512)
print "atlas"
self.groups = []
self.tiles = {}
tile_textures = {}
for y, line in enumerate(loaded_map):
for x, tile in enumerate(line):
if tile[0] == -1: #edge
if "edg" not in tile_textures.keys():
tile_textures["edg"] = [self.load_map_object('data/tiles/edg.def/%d.png'%i, 100) for i in xrange(36)]
self.tiles[x,y] = [tile_textures["edg"][tile[1]]]
elif tile[0] == 0: #dirt
if "dirttl" not in tile_textures.keys():
tile_textures["dirttl"] = [self.load_map_object('data/tiles/dirttl.def/%d.png'%i, 0) for i in xrange(46)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["dirttl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["dirttl"][tile[1]].group
self.tiles[x,y] = [new]
else:
self.tiles[x,y] = [tile_textures["dirttl"][tile[1]]]
elif tile[0] == 1: #sand
if "sandtl" not in tile_textures.keys():
tile_textures["sandtl"] = [self.load_map_object('data/tiles/sandtl.def/%d.png'%i, 0) for i in xrange(24)]
self.tiles[x,y] = [tile_textures["sandtl"][tile[1]]]
elif tile[0] == 2: #grass
if "grastl" not in tile_textures.keys():
tile_textures["grastl"] = [self.load_map_object('data/tiles/grastl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["grastl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["grastl"][tile[1]].group
self.tiles[x,y] = [new]
else:
self.tiles[x,y] = [tile_textures["grastl"][tile[1]]]
elif tile[0] == 3: #snow
if "snowtl" not in tile_textures.keys():
tile_textures["snowtl"] = [self.load_map_object('data/tiles/snowtl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["snowtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["snowtl"][tile[1]].group
self.tiles[x,y] = [new]
else:
self.tiles[x,y] = [tile_textures["snowtl"][tile[1]]]
elif tile[0] == 4: #swamp
if "swmptl" not in tile_textures.keys():
tile_textures["swmptl"] = [self.load_map_object('data/tiles/swmptl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["swmptl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["swmptl"][tile[1]].group
self.tiles[x,y] = [new]
else:
self.tiles[x,y] = [tile_textures["swmptl"][tile[1]]]
elif tile[0] == 5: #rough
if "rougtl" not in tile_textures.keys():
tile_textures["rougtl"] = [self.load_map_object('data/tiles/rougtl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["rougtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["rougtl"][tile[1]].group
self.tiles[x,y] = [new]
else:
self.tiles[x,y] = [tile_textures["rougtl"][tile[1]]]
elif tile[0] == 7: #lava
if "lavatl" not in tile_textures.keys():
tile_textures["lavatl"] = [self.load_map_object('data/tiles/lavatl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["lavatl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["lavatl"][tile[1]].group
self.tiles[x,y] = [new]
else:
self.tiles[x,y] = [tile_textures["lavatl"][tile[1]]]
elif tile[0] == 8: #water
if "watrtl" not in tile_textures.keys():
tile_textures["watrtl"] = []
for j in xrange(33):
tile_textures["watrtl"].append([self.load_map_object('data/tiles/watrtl.def/%d/%d.png'%(j,i), 0) for i in xrange(12)])
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
tiles = []
for watrtl in tile_textures["watrtl"][tile[1]]:
new = watrtl.get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = watrtl.group
tiles.append(new)
self.tiles[x,y] = [Animation(tiles)]
else:
self.tiles[x,y] = [Animation(tile_textures["watrtl"][tile[1]])]
elif tile[0] == 9: #rock
if "rocktl" not in tile_textures.keys():
tile_textures["rocktl"] = [self.load_map_object('data/tiles/rocktl.def/%d.png'%i, 0) for i in xrange(48)]
self.tiles[x,y] = [tile_textures["rocktl"][tile[1]]]
else:
raise NotImplementedError
if tile[2] == 0: #no river
pass
elif tile[2] == 1: #clrrvr
if "clrrvr" not in tile_textures.keys():
tile_textures["clrrvr"] = [[self.load_map_object('data/tiles/clrrvr.def/%d/%d.png'%(i, j), 1) for j in xrange(12)] for i in xrange(13)]
flip_x = bool(tile[6] & 4)
flip_y = bool(tile[6] & 8)
if flip_x or flip_y:
tiles = []
for clrrvr in tile_textures["clrrvr"][tile[3]]:
new = clrrvr.get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = clrrvr.group
tiles.append(new)
self.tiles[x, y].append(Animation(tiles))
else:
self.tiles[x, y].append(Animation(tile_textures["clrrvr"][tile[3]]))
elif tile[2] == 2: #icyrvr
if "icyrvr" not in tile_textures.keys():
tile_textures["icyrvr"] = [self.load_map_object('data/tiles/icyrvr.def/%d.png'%i, 1) for i in xrange(13)]
flip_x = bool(tile[6] & 4)
flip_y = bool(tile[6] & 8)
if flip_x or flip_y:
new = tile_textures["icyrvr"][tile[3]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["icyrvr"][tile[3]].group
self.tiles[x, y].append(new)
else:
self.tiles[x, y].append(tile_textures["icyrvr"][tile[3]])
elif tile[2] == 3: #mudrvr
if "mudrvr" not in tile_textures.keys():
tile_textures["mudrvr"] = [[self.load_map_object('data/tiles/mudrvr.def/%d/%d.png'%(i, j), 1) for j in xrange(12)] for i in xrange(13)]
flip_x = bool(tile[6] & 4)
flip_y = bool(tile[6] & 8)
if flip_x or flip_y:
tiles = []
for mudrvr in tile_textures["mudrvr"][tile[3]]:
new = mudrvr.get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = mudrvr.group
tiles.append(new)
self.tiles[x, y].append(Animation(tiles))
else:
self.tiles[x, y].append(Animation(tile_textures["mudrvr"][tile[3]]))
elif tile[2] == 4: #lavrvr
if "lavrvr" not in tile_textures.keys():
tile_textures["lavrvr"] = [[self.load_map_object('data/tiles/lavrvr.def/%d/%d.png'%(i, j), 1) for j in xrange(9)] for i in xrange(13)]
flip_x = bool(tile[6] & 4)
flip_y = bool(tile[6] & 8)
if flip_x or flip_y:
tiles = []
for lavrvr in tile_textures["lavrvr"][tile[3]]:
new = lavrvr.get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = lavrvr.group
tiles.append(new)
self.tiles[x, y].append(Animation(tiles))
else:
self.tiles[x, y].append(Animation(tile_textures["lavrvr"][tile[3]]))
else:
raise NotImplementedError, tile[2]
if tile[4] == 0: #no road
pass
elif tile[4] == 1: #dirtrd
if "dirtrd" not in tile_textures.keys():
tile_textures["dirtrd"] = [self.load_map_object('data/tiles/dirtrd.def/%d.png'%i, 1) for i in xrange(17)]
flip_x = bool(tile[6] & 16)
flip_y = bool(tile[6] & 32)
if flip_x or flip_y:
new = tile_textures["dirtrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["dirtrd"][tile[5]].group
self.tiles[x, y].append(new)
else:
self.tiles[x, y].append(tile_textures["dirtrd"][tile[5]])
elif tile[4] == 2: #gravrd
if "gravrd" not in tile_textures.keys():
tile_textures["gravrd"] = [self.load_map_object('data/tiles/gravrd.def/%d.png'%i, 1) for i in xrange(17)]
flip_x = bool(tile[6] & 16)
flip_y = bool(tile[6] & 32)
if flip_x or flip_y:
new = tile_textures["gravrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["gravrd"][tile[5]].group
self.tiles[x, y].append(new)
else:
self.tiles[x, y].append(tile_textures["gravrd"][tile[5]])
elif tile[4] == 3: #cobbrd
if "cobbrd" not in tile_textures.keys():
tile_textures["cobbrd"] = [self.load_map_object('data/tiles/cobbrd.def/%d.png'%i, 1) for i in xrange(17)]
flip_x = bool(tile[6] & 16)
flip_y = bool(tile[6] & 32)
if flip_x or flip_y:
new = tile_textures["cobbrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["cobbrd"][tile[5]].group
self.tiles[x, y].append(new)
else:
self.tiles[x, y].append(tile_textures["cobbrd"][tile[5]])
else:
raise NotImplementedError, tile[4]
images = []
for order, obj in enumerate(objects):
imgs = []
i = 0
while 1:
imgs.append(pyglet.image.load(None, file=pyglet.resource.file("data/map_objects/"+obj["filename"]+"/%d.png"%i)))
i+=1
if "data/map_objects/"+obj["filename"]+"/%d.png"%i not in pyglet.resource._default_loader._index.keys():
break;
images.append((imgs, order))
self.objects = []
for imgs in sorted(images, key=lambda i:i[0][0].height, reverse=True):
textures = []
for img in imgs[0]:
try:
textures.append(self.current_atlas.add(img))
except pyglet.image.atlas.AllocatorException:
self.current_atlas = pyglet.image.atlas.TextureAtlas(512, 512)
print "atlas"
textures.append(self.current_atlas.add(img))
ordered_group = pyglet.graphics.OrderedGroup(2)
group = pyglet.graphics.TextureGroup(self.current_atlas.texture, ordered_group)
if group not in self.groups:
self.groups.append(group)
group = self.groups.index(group)
textures[-1].group = group
self.objects.append((textures, imgs[1]))
self.objects = [i[0] for i in sorted(self.objects, key=lambda i:i[1])]
self.tunedobj = {}
for obj in [i for i in tunedobj if i["z"]==0]:
if len(self.objects[obj["id"]]) == 1:
self.tiles[obj["x"]+9,obj["y"]+8].append(self.objects[obj["id"]][0])
else:
self.tiles[obj["x"]+9,obj["y"]+8].append(Animation(self.objects[obj["id"]]))
class MapView(object):
def __init__(self, mapset, window):
self.window = window
self.mapset = mapset
self._first_time_init()
self._init_view()
#mouse position
self.label = pyglet.text.Label('',
font_name="",
font_size=36,
bold=True,
color=(128, 128, 128, 128),
x=self.window.width-10, y=0,
anchor_x='right', anchor_y='bottom')
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
pyglet.clock.schedule_interval(self.update, 1/60.0)
def _first_time_init(self):
self.tile_size = 32
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
#center map
self.global_x = (self.mapset.width*self.tile_size-self.viewport_x+self.tile_size)//2
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)+(self.tile_size//2)
self.mouse_x = self.mouse_dx = 0
self.mouse_y = self.mouse_dy = 0
def _init_view(self):
#step one tile
self.steps = self.tile_size
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
#center map when viewport is too large, else check if map still fills
#whole viewport and if not adjust position accordingly
self.center_x = False
if self.mapset.width*self.tile_size < self.viewport_x:
self.center_x = True
self.global_x = (self.mapset.width*self.tile_size)//2-(self.viewport_x//2)
elif self.global_x > self.tile_size*self.mapset.width-self.viewport_x:
self.global_x = self.tile_size*self.mapset.width-self.viewport_x
elif self.global_x < 0:
self.global_x = 0
self.center_y = False
if self.mapset.height*self.tile_size < self.viewport_y:
self.center_y = True
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)
elif self.global_y > self.tile_size*self.mapset.height-self.viewport_y:
self.global_y = self.tile_size*self.mapset.height-self.viewport_y
elif self.global_y < 0:
self.global_y = 0
#drawn tiles
self.tiles_x = min((self.viewport_x//self.tile_size)+2, self.mapset.width)
self.tiles_y = min((self.viewport_y//self.tile_size)+2, self.mapset.height)
#undrawn map size
self.undrawn_x = self.tile_size*(self.mapset.width-self.tiles_x)
self.undrawn_y = self.tile_size*(self.mapset.height-self.tiles_y)
#size of full undrawn steps
self.undrawn_steps_x = self.steps*(self.undrawn_x//self.steps)
self.undrawn_steps_y = self.steps*(self.undrawn_y//self.steps)
self.batch = pyglet.graphics.Batch()
self.view_x = 0
self.view_y = 0
self.dx = 0
self.dy = 0
#here we translate the global map position so we can draw with it
trans_global_x = self.steps-self.global_x
trans_global_y = self.steps-self.global_y
if trans_global_x < -self.undrawn_steps_x:
mod_x = trans_global_x+self.undrawn_x
elif trans_global_x < self.steps:
mod_x = trans_global_x%self.steps
else:
mod_x = trans_global_x
if trans_global_y < -self.undrawn_steps_y:
mod_y = trans_global_y+self.undrawn_y
elif trans_global_y < self.steps:
mod_y = trans_global_y%self.steps
else:
mod_y = trans_global_y
self.div_x = (trans_global_x-mod_x)//self.tile_size
self.div_y = (trans_global_y-mod_y)//self.tile_size+self.mapset.height-1
self.vl_objects = [None for i, value in enumerate(self.mapset.groups)]
vertices = [[] for i, value in enumerate(self.mapset.groups)]
tex_coords = [[] for i, value in enumerate(self.mapset.groups)]
count = [0 for i, value in enumerate(self.mapset.groups)]
for y in xrange(self.tiles_y-1, -6, -1):
y1 = y*32+IF_BOTTOM
for x in xrange(self.tiles_x+5-1, -1, -1):
for obj in self.mapset.tiles.get((x-self.div_x, self.div_y-y), []):
x1 = x*32+IF_LEFT-obj.width+32
x2 = x1+obj.width
y2 = y1+obj.height
vertices[obj.group].extend([x1, y1, x2, y1, x2, y2, x1, y2])
tex_coords[obj.group].extend(obj.tex_coords)
count[obj.group]+=4
for i, group in enumerate(self.mapset.groups):
if count[i] != 0:
self.vl_objects[i] = self.batch.add(count[i], pyglet.gl.GL_QUADS,
group,
('v2i', vertices[i]),
('t3f', tex_coords[i]),
('c4B', (255,255,255,255)*count[i]))
self.view_x = mod_x-self.steps-(self.tile_size-32)//4
self.view_y = mod_y-self.steps-((self.tile_size-32)*3)//2
def on_draw(self):
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
pyglet.gl.glPushMatrix()
pyglet.gl.glTranslatef(self.view_x, self.view_y, 0)
pyglet.gl.glScalef(self.tile_size/32.0, self.tile_size/32.0, 0.0)
self.batch.draw()
pyglet.gl.glPopMatrix()
pyglet.gl.glLoadIdentity()
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glColor4f(1, 0, 1, 1)
pyglet.gl.glRectf(0, 0, self.window.width, IF_BOTTOM)
pyglet.gl.glRectf(self.window.width-IF_RIGHT, 0, self.window.width, self.window.height)
pyglet.gl.glRectf(0, self.window.height-IF_TOP, self.window.width, self.window.height)
pyglet.gl.glRectf(0, 0, IF_LEFT, self.window.height)
self.label.draw()
def _move(self, dx, dy):
#here we translate the global map position so we can draw with it
trans_global_x = self.steps-self.global_x
trans_global_y = self.steps-self.global_y
new_global_x = trans_global_x+dx
new_global_y = trans_global_y+dy
if self.global_x-dx < 0:
new_global_x = self.steps
if self.global_y-dy < 0:
new_global_y = self.steps
if dx-self.global_x < -self.tile_size*self.mapset.width+self.viewport_x:
new_global_x = -self.tile_size*self.mapset.width+self.viewport_x+self.steps
if dy-self.global_y < -self.tile_size*self.mapset.height+self.viewport_y:
new_global_y = -self.tile_size*self.mapset.height+self.viewport_y+self.steps
retex = False
if new_global_x < -self.undrawn_steps_x:
mod_x = new_global_x+self.undrawn_x
if trans_global_x >= -self.undrawn_steps_x:
retex = True
elif new_global_x < self.steps:
div_x, mod_x = divmod(new_global_x, self.steps)
retex = div_x != trans_global_x//self.steps or retex
else:
mod_x = new_global_x
if new_global_y < -self.undrawn_steps_y:
mod_y = new_global_y+self.undrawn_y
if trans_global_y >= -self.undrawn_steps_y:
retex = True
elif new_global_y < self.steps:
div_y, mod_y = divmod(new_global_y, self.steps)
retex = div_y != trans_global_y//self.steps or retex
else:
mod_y = new_global_y
if retex:
self.div_x = (new_global_x-mod_x)//self.tile_size
self.div_y = (new_global_y-mod_y)//self.tile_size+self.mapset.height-1
vertices = [[] for i, value in enumerate(self.mapset.groups)]
tex_coords = [[] for i, value in enumerate(self.mapset.groups)]
count = [0 for i, value in enumerate(self.mapset.groups)]
for y in xrange(self.tiles_y-1, -6, -1):
y1 = y*32+IF_BOTTOM
for x in xrange(self.tiles_x+5-1, -1, -1):
for obj in self.mapset.tiles.get((x-self.div_x, self.div_y-y), []):
x1 = x*32+IF_LEFT-obj.width+32
x2 = x1+obj.width
y2 = y1+obj.height
tex_coords[obj.group].extend(obj.tex_coords)
vertices[obj.group].extend([x1, y1, x2, y1, x2, y2, x1, y2])
count[obj.group]+=4
for i, group in enumerate(self.mapset.groups):
if count[i] == 0:
if self.vl_objects[i] is not None:
self.vl_objects[i].delete()
self.vl_objects[i] = None
elif count[i] != 0 and self.vl_objects[i] is None:
self.vl_objects[i] = self.batch.add(count[i], pyglet.gl.GL_QUADS,
group,
('v2i', vertices[i]),
('t3f', tex_coords[i]),
('c4B', (255,255,255,255)*count[i]))
else:
self.vl_objects[i].resize(count[i])
self.vl_objects[i].tex_coords = tex_coords[i]
self.vl_objects[i].vertices = vertices[i]
self.vl_objects[i].colors = (255,255,255,255)*count[i]
if not self.center_x:
self.view_x = mod_x-self.steps-(self.tile_size-32)//4
self.global_x = self.steps-new_global_x
if not self.center_y:
self.view_y = mod_y-self.steps-((self.tile_size-32)*3)//2
self.global_y = self.steps-new_global_y
def update(self, dt):
try:
if self.window.keys[pyglet.window.key.LCTRL] and \
any([self.window.keys[pyglet.window.key.UP],
self.window.keys[pyglet.window.key.DOWN],
self.window.keys[pyglet.window.key.LEFT],
self.window.keys[pyglet.window.key.RIGHT]]):
if self.window.keys[pyglet.window.key.LEFT]:
x = 1
elif self.window.keys[pyglet.window.key.RIGHT]:
x = -1
else:
x = 0
if self.window.keys[pyglet.window.key.UP]:
y = -1
elif self.window.keys[pyglet.window.key.DOWN]:
y = 1
else:
y = 0
self.dx += x*8
self.dy += y*8
elif self.window.keys[pyglet.window.key.PLUS] and \
self.tile_size < 32:
self.tile_size+=8
self._init_view()
elif self.window.keys[pyglet.window.key.MINUS] and \
self.tile_size > 16:
self.tile_size-=8
self._init_view()
except KeyError:
pass
if self.dx or self.dy:
self._move(self.dx, self.dy)
self.dx = 0
self.dy = 0
#mouse position:
if self.mouse_x != self.mouse_dx or self.mouse_y != self.mouse_dy:
self.mouse_x = self.mouse_dx
self.mouse_y = self.mouse_dy
x = (self.mouse_x-IF_LEFT-self.view_x
-(self.tile_size-32)//4)//self.tile_size
y = (self.mouse_y-IF_BOTTOM-self.view_y
-((self.tile_size-32)*3)//2)//self.tile_size
self.label.text = "%03d %03d"%(x-self.div_x, self.div_y-y)
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
self.dx += dx
self.dy += dy
self.mouse_dx = x
self.mouse_dy = y
return pyglet.event.EVENT_HANDLED
def on_mouse_motion(self, x, y, dx, dy):
self.mouse_dx = x
self.mouse_dy = y
return pyglet.event.EVENT_HANDLED
def on_resize(self, width, height):
self._init_view()
def animate_water(self, dt):
tex_coords = [[] for i, value in enumerate(self.mapset.groups)]
count = [0 for i, value in enumerate(self.mapset.groups)]
vertices = [[] for i, value in enumerate(self.mapset.groups)]
for y in xrange(self.tiles_y-1, -6, -1):
y1 = y*32+IF_BOTTOM
for x in xrange(self.tiles_x+5-1, -1, -1):
for obj in self.mapset.tiles.get((x-self.div_x, self.div_y-y), []):
x1 = x*32+IF_LEFT-obj.width+32
x2 = x1+obj.width
y2 = y1+obj.height
if isinstance(obj, Animation):
obj.next_frame()
tex_coords[obj.group].extend(obj.tex_coords)
vertices[obj.group].extend([x1, y1, x2, y1, x2, y2, x1, y2])
count[obj.group]+=4
for i, group in enumerate(self.mapset.groups):
if count[i] == 0:
if self.vl_objects[i] is not None:
self.vl_objects[i].delete()
self.vl_objects[i] = None
elif count[i] != 0 and self.vl_objects[i] is None:
self.vl_objects[i] = self.batch.add(count[i], pyglet.gl.GL_QUADS,
group,
('v2i', vertices[i]),
('t3f', tex_coords[i]),
('c4B', (255,255,255,255)*count[i]))
else:
self.vl_objects[i].resize(count[i])
self.vl_objects[i].tex_coords = tex_coords[i]
self.vl_objects[i].vertices = vertices[i]
self.vl_objects[i].colors = (255,255,255,255)*count[i]
class Window(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(1280, 1024, resizable=True, vsync=False)
self.keys = pyglet.window.key.KeyStateHandler()
self.push_handlers(self.keys)
self.fps = pyglet.clock.ClockDisplay()
pyglet.clock.schedule(lambda dt: None)
def on_draw(self):
self.fps.draw()
def on_key_press(self, symbol, modifiers):
if symbol == pyglet.window.key.F11:
self.set_fullscreen(fullscreen=not self.fullscreen)
elif symbol == pyglet.window.key.P:
pyglet.image.get_buffer_manager().get_color_buffer().save('screenshot.png', encoder=PNGRGBEncoder())
class PNGRGBEncoder(pyglet.image.codecs.ImageEncoder):
def encode(self, image, file, filename):
import Image
image = image.get_image_data()
format = image.format
pitch = -(image.width * len(format))
pil_image = Image.fromstring(
format, (image.width, image.height), image.get_data(format, pitch))
try:
#.convert('P', palette=Image.WEB)
pil_image.convert("RGB").save(file)
except Exception, e:
raise ImageEncodeException(e)
class Interface(object):
def __init__(self, window):
self.window = window
def on_mouse_motion(self, x, y, dx, dy):
if IF_LEFT < x < (self.window.width-IF_RIGHT):
pass
else:
return pyglet.event.EVENT_HANDLED
if IF_BOTTOM < y < (self.window.height-IF_TOP):
pass
else:
return pyglet.event.EVENT_HANDLED
class LoadScreen(object):
def __init__(self, window):
self.window = window
self.label = pyglet.text.Label('',
font_name="Linux Libertine",
font_size=28,
x=self.window.width-10, y=10,
anchor_x='right', anchor_y='bottom')
self.label.text = "PARSING MAP FILE..."
h3m = json.loads(pyglet.resource.file("test.h3m").read())
self.label.text = "PARSING MAP FILE..."
edge_map = [[] for i in xrange(len(h3m["upper_terrain"])+16)]
for num in xrange(len(edge_map)):
if num < 7 or num > len(edge_map)-8:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0])+18)])
elif num == 7:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 16, 0, 0, 0, 0, 0])
line.extend([[-1, 20+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0]))])
line.append([-1, 17, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
elif num == len(edge_map)-8:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 19, 0, 0, 0, 0, 0])
line.extend([[-1, 28+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0]))])
line.append([-1, 18, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
else:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 32+num%4, 0, 0, 0, 0, 0])
line.extend(h3m["upper_terrain"][num-8])
line.append([-1, 24+num%4, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
edge_map[num] = line
h3m["upper_terrain"] = edge_map
self.label.text = "INITIATING MAPSET..."
mapset = MapSet(h3m["upper_terrain"], h3m["objects"], h3m["tunedobj"])
self.label.text = "INITIATING MAPVIEW..."
mapview = MapView(mapset, self.window)
interface = Interface(self.window)
self.window.pop_handlers()
self.window.push_handlers(mapview)
self.window.push_handlers(interface)
self.window.push_handlers(self.window.keys)
if __name__ == '__main__':
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
window = Window()
window.push_handlers(LoadScreen(window))
img = pyglet.resource.image("data/cursors/cradvntr.def/0.png")
window.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
pyglet.app.run()

@ -0,0 +1,775 @@
#!/usr/bin/python
"""
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pyglet, re
from ctypes import create_string_buffer, memmove
import itertools
try:
import json
except ImportError:
try:
import simplejson as json
except ImportError:
import demjson as json
json.loads = json.decode
json.dumps = json.encode
IF_BOTTOM = 48
IF_RIGHT = 200
IF_TOP = IF_LEFT = 8
class OrderedTextureGroup(pyglet.graphics.Group):
def __init__(self, order, texture, parent=None):
super(OrderedTextureGroup, self).__init__(parent)
self.texture = texture
self.order = order
def set_state(self):
pyglet.gl.glEnable(self.texture.target)
pyglet.gl.glBindTexture(self.texture.target, self.texture.id)
def unset_state(self):
pyglet.gl.glDisable(self.texture.target)
def __hash__(self):
return hash((self.order, self.texture.target, self.texture.id,
self.parent))
def __eq__(self, other):
return (self.__class__ is other.__class__ and
self.order == other.order and
self.texture.target == other.texture.target and
self.texture.id == other.texture.id and
self.parent == self.parent)
def __repr__(self):
return '%s(id=%d)' % (self.__class__.__name__, self.order,
self.texture.id)
def __cmp__(self, other):
if isinstance(other, OrderedTextureGroup):
return cmp(self.order, other.order)
return -1
class Animation(object):
def __init__(self, tex_region, frames, flip_x=False, flip_y=False):
self.texgroup = tex_region.group
if flip_x or flip_y:
self.tex = tex_region.get_transform(flip_x=flip_x, flip_y=flip_y)
else:
self.tex = tex_region
self.__frames = []
for img in frames:
data_pitch = abs(img._current_pitch)
buf = create_string_buffer(len(img._current_data))
memmove(buf, img._current_data, len(img._current_data))
data = buf.raw
rows = [data[i:i+abs(data_pitch)] for i in
xrange(len(img._current_data)-abs(data_pitch),
-1, -abs(data_pitch))]
self.__frames.append(''.join(rows))
self.__animation = 0
self.width = self.tex.width
self.height = self.tex.height
self.__hash = hash(self.__frames[0])
def next_frame(self):
self.__animation = (self.__animation+1)%len(self.__frames)
return self.__frames[self.__animation]
def get_tex_coords(self):
return self.tex.tex_coords
tex_coords = property(get_tex_coords)
def get_group(self):
return self.texgroup
group = property(get_group)
def __hash__(self):
return self.__hash
def __eq__(self, other):
return self.__hash == other.__hash
class MapSet(object):
def load_map_object(self, file, order=0):
image = pyglet.image.load(None, file=pyglet.resource.file(file))
try:
texture_region = self.current_atlas.add(image)
except pyglet.image.atlas.AllocatorException:
self.current_atlas = pyglet.image.atlas.TextureAtlas(1024, 1024)
texture_region = self.current_atlas.add(image)
group = OrderedTextureGroup(order, self.current_atlas.texture)
if group not in self.groups:
self.groups.append(group)
texture_region.group = self.groups.index(group)
return texture_region
def __init__(self, loaded_map, objects, tunedobj):
self.width = len(loaded_map[0])
self.height = len(loaded_map)
self.current_atlas = pyglet.image.atlas.TextureAtlas(1024, 1024)
self.groups = []
self.tiles = {}
tile_textures = {}
for y, line in enumerate(loaded_map):
for x, tile in enumerate(line):
if tile[0] == -1: #edge
if "edg" not in tile_textures.keys():
tile_textures["edg"] = [self.load_map_object('data/tiles/edg.def/%d.png'%i, 100) for i in xrange(36)]
self.tiles[x,y] = [tile_textures["edg"][tile[1]]]
elif tile[0] == 0: #dirt
if "dirttl" not in tile_textures.keys():
tile_textures["dirttl"] = [self.load_map_object('data/tiles/dirttl.def/%d.png'%i, 0) for i in xrange(46)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["dirttl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["dirttl"][tile[1]].group
self.tiles[x,y] = [new]
else:
self.tiles[x,y] = [tile_textures["dirttl"][tile[1]]]
elif tile[0] == 1: #sand
if "sandtl" not in tile_textures.keys():
tile_textures["sandtl"] = [self.load_map_object('data/tiles/sandtl.def/%d.png'%i, 0) for i in xrange(24)]
self.tiles[x,y] = [tile_textures["sandtl"][tile[1]]]
elif tile[0] == 2: #grass
if "grastl" not in tile_textures.keys():
tile_textures["grastl"] = [self.load_map_object('data/tiles/grastl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["grastl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["grastl"][tile[1]].group
self.tiles[x,y] = [new]
else:
self.tiles[x,y] = [tile_textures["grastl"][tile[1]]]
elif tile[0] == 3: #snow
if "snowtl" not in tile_textures.keys():
tile_textures["snowtl"] = [self.load_map_object('data/tiles/snowtl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["snowtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["snowtl"][tile[1]].group
self.tiles[x,y] = [new]
else:
self.tiles[x,y] = [tile_textures["snowtl"][tile[1]]]
elif tile[0] == 4: #swamp
if "swmptl" not in tile_textures.keys():
tile_textures["swmptl"] = [self.load_map_object('data/tiles/swmptl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["swmptl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["swmptl"][tile[1]].group
self.tiles[x,y] = [new]
else:
self.tiles[x,y] = [tile_textures["swmptl"][tile[1]]]
elif tile[0] == 5: #rough
if "rougtl" not in tile_textures.keys():
tile_textures["rougtl"] = [self.load_map_object('data/tiles/rougtl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["rougtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["rougtl"][tile[1]].group
self.tiles[x,y] = [new]
else:
self.tiles[x,y] = [tile_textures["rougtl"][tile[1]]]
elif tile[0] == 7: #lava
if "lavatl" not in tile_textures.keys():
tile_textures["lavatl"] = [self.load_map_object('data/tiles/lavatl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["lavatl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["lavatl"][tile[1]].group
self.tiles[x,y] = [new]
else:
self.tiles[x,y] = [tile_textures["lavatl"][tile[1]]]
elif tile[0] == 8: #water 12 anims
if "watrtl" not in tile_textures.keys():
textures = [self.load_map_object('data/tiles/watrtl.def/%d/0.png'%i, 0) for i in xrange(33)]
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/tiles/watrtl.def/%d/%d.png'%(i,j))) for j in xrange(12)] for i in xrange(33)]
tile_textures["watrtl"] = {
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
}
flip_x = (tile[6]>>0)&1
flip_y = (tile[6]>>1)&1
self.tiles[x,y] = [tile_textures["watrtl"][flip_x, flip_y][tile[1]]]
elif tile[0] == 9: #rock
if "rocktl" not in tile_textures.keys():
tile_textures["rocktl"] = [self.load_map_object('data/tiles/rocktl.def/%d.png'%i, 0) for i in xrange(48)]
self.tiles[x,y] = [tile_textures["rocktl"][tile[1]]]
else:
raise NotImplementedError
if tile[2] == 0: #no river
pass
elif tile[2] == 1: #clrrvr 12 anims
if "clrrvr" not in tile_textures.keys():
textures = [self.load_map_object('data/tiles/clrrvr.def/%d/0.png'%i, 1) for i in xrange(13)]
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/tiles/clrrvr.def/%d/%d.png'%(i,j))) for j in xrange(12)] for i in xrange(13)]
tile_textures["clrrvr"] = {
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
}
flip_x = (tile[6]>>2)&1
flip_y = (tile[6]>>3)&1
self.tiles[x,y].append(tile_textures["clrrvr"][flip_x, flip_y][tile[3]])
elif tile[2] == 2: #icyrvr
if "icyrvr" not in tile_textures.keys():
tile_textures["icyrvr"] = [self.load_map_object('data/tiles/icyrvr.def/%d.png'%i, 1) for i in xrange(13)]
flip_x = bool(tile[6] & 4)
flip_y = bool(tile[6] & 8)
if flip_x or flip_y:
new = tile_textures["icyrvr"][tile[3]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["icyrvr"][tile[3]].group
self.tiles[x, y].append(new)
else:
self.tiles[x, y].append(tile_textures["icyrvr"][tile[3]])
elif tile[2] == 3: #mudrvr
if "mudrvr" not in tile_textures.keys():
textures = [self.load_map_object('data/tiles/mudrvr.def/%d/0.png'%i, 1) for i in xrange(13)]
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/tiles/clrrvr.def/%d/%d.png'%(i,j))) for j in xrange(12)] for i in xrange(13)]
tile_textures["mudrvr"] = {
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
}
flip_x = (tile[6]>>2)&1
flip_y = (tile[6]>>3)&1
self.tiles[x,y].append(tile_textures["mudrvr"][flip_x, flip_y][tile[3]])
elif tile[2] == 4: #lavrvr
if "lavrvr" not in tile_textures.keys():
textures = [self.load_map_object('data/tiles/lavrvr.def/%d/0.png'%i, 1) for i in xrange(13)]
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/tiles/clrrvr.def/%d/%d.png'%(i,j))) for j in xrange(9)] for i in xrange(13)]
tile_textures["lavrvr"] = {
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
}
flip_x = (tile[6]>>2)&1
flip_y = (tile[6]>>3)&1
self.tiles[x,y].append(tile_textures["lavrvr"][flip_x, flip_y][tile[3]])
else:
raise NotImplementedError, tile[2]
if tile[4] == 0: #no road
pass
elif tile[4] == 1: #dirtrd
if "dirtrd" not in tile_textures.keys():
tile_textures["dirtrd"] = [self.load_map_object('data/tiles/dirtrd.def/%d.png'%i, 1) for i in xrange(17)]
flip_x = bool(tile[6] & 16)
flip_y = bool(tile[6] & 32)
if flip_x or flip_y:
new = tile_textures["dirtrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["dirtrd"][tile[5]].group
self.tiles[x, y].append(new)
else:
self.tiles[x, y].append(tile_textures["dirtrd"][tile[5]])
elif tile[4] == 2: #gravrd
if "gravrd" not in tile_textures.keys():
tile_textures["gravrd"] = [self.load_map_object('data/tiles/gravrd.def/%d.png'%i, 1) for i in xrange(17)]
flip_x = bool(tile[6] & 16)
flip_y = bool(tile[6] & 32)
if flip_x or flip_y:
new = tile_textures["gravrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["gravrd"][tile[5]].group
self.tiles[x, y].append(new)
else:
self.tiles[x, y].append(tile_textures["gravrd"][tile[5]])
elif tile[4] == 3: #cobbrd
if "cobbrd" not in tile_textures.keys():
tile_textures["cobbrd"] = [self.load_map_object('data/tiles/cobbrd.def/%d.png'%i, 1) for i in xrange(17)]
flip_x = bool(tile[6] & 16)
flip_y = bool(tile[6] & 32)
if flip_x or flip_y:
new = tile_textures["cobbrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["cobbrd"][tile[5]].group
self.tiles[x, y].append(new)
else:
self.tiles[x, y].append(tile_textures["cobbrd"][tile[5]])
else:
raise NotImplementedError, tile[4]
images = []
for order, obj in enumerate(objects):
imgs = []
i = 0
while 1:
imgs.append(pyglet.image.load(None, file=pyglet.resource.file("data/map_objects/"+obj["filename"]+"/%d.png"%i)))
i+=1
if "data/map_objects/"+obj["filename"]+"/%d.png"%i not in pyglet.resource._default_loader._index.keys():
break;
images.append((imgs, order))
self.objects = []
for imgs in sorted(images, key=lambda i:i[0][0].height, reverse=True):
try:
texture = self.current_atlas.add(imgs[0][0])
except pyglet.image.atlas.AllocatorException:
self.current_atlas = pyglet.image.atlas.TextureAtlas(1024, 1024)
print "atlas"
texture = self.current_atlas.add(imgs[0][0])
group = OrderedTextureGroup(2, self.current_atlas.texture)
if group not in self.groups:
self.groups.append(group)
group = self.groups.index(group)
texture.group = group
self.objects.append((Animation(texture, imgs[0]), imgs[1]))
self.objects = [i[0] for i in sorted(self.objects, key=lambda i:i[1])]
self.tunedobj = {}
for obj in [i for i in tunedobj if i["z"]==0]:
self.tiles[obj["x"]+9,obj["y"]+8].append(self.objects[obj["id"]])
class MapView(object):
def __init__(self, mapset, window):
self.window = window
self.mapset = mapset
self._first_time_init()
self._init_view()
#mouse position
self.label = pyglet.text.Label('',
font_name="",
font_size=36,
bold=True,
color=(128, 128, 128, 128),
x=self.window.width-10, y=0,
anchor_x='right', anchor_y='bottom')
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
pyglet.clock.schedule_interval(self.update, 1/60.0)
def _first_time_init(self):
self.tile_size = 32
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
#center map
self.global_x = (self.mapset.width*self.tile_size-self.viewport_x
+self.tile_size)//2
self.global_y = (self.mapset.height*self.tile_size-self.viewport_y
+self.tile_size)//2
self.mouse_x = self.mouse_dx = 0
self.mouse_y = self.mouse_dy = 0
def _init_view(self):
#step one tile
self.steps = self.tile_size
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
#center map when viewport is too large, else check if map still fills
#whole viewport and if not adjust position accordingly
self.center_x = False
if self.mapset.width*self.tile_size < self.viewport_x:
self.center_x = True
self.global_x = (self.mapset.width*self.tile_size)//2-(self.viewport_x//2)
elif self.global_x > self.tile_size*self.mapset.width-self.viewport_x:
self.global_x = self.tile_size*self.mapset.width-self.viewport_x
elif self.global_x < 0:
self.global_x = 0
self.center_y = False
if self.mapset.height*self.tile_size < self.viewport_y:
self.center_y = True
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)
elif self.global_y > self.tile_size*self.mapset.height-self.viewport_y:
self.global_y = self.tile_size*self.mapset.height-self.viewport_y
elif self.global_y < 0:
self.global_y = 0
#drawn tiles
self.tiles_x = min((self.viewport_x//self.tile_size)+2, self.mapset.width)
self.tiles_y = min((self.viewport_y//self.tile_size)+2, self.mapset.height)
#undrawn map size
self.undrawn_x = self.tile_size*(self.mapset.width-self.tiles_x)
self.undrawn_y = self.tile_size*(self.mapset.height-self.tiles_y)
#size of full undrawn steps
self.undrawn_steps_x = self.steps*(self.undrawn_x//self.steps)
self.undrawn_steps_y = self.steps*(self.undrawn_y//self.steps)
self.batch = pyglet.graphics.Batch()
self.view_x = 0
self.view_y = 0
self.dx = 0
self.dy = 0
#here we translate the global map position so we can draw with it
trans_global_x = self.steps-self.global_x
trans_global_y = self.steps-self.global_y
if trans_global_x < -self.undrawn_steps_x:
mod_x = trans_global_x+self.undrawn_x
elif trans_global_x < self.steps:
mod_x = trans_global_x%self.steps
else:
mod_x = trans_global_x
if trans_global_y < -self.undrawn_steps_y:
mod_y = trans_global_y+self.undrawn_y
elif trans_global_y < self.steps:
mod_y = trans_global_y%self.steps
else:
mod_y = trans_global_y
self.div_x = (trans_global_x-mod_x)//self.tile_size
self.div_y = (trans_global_y-mod_y)//self.tile_size+self.mapset.height-1
self.vl_objects = [None for i, value in enumerate(self.mapset.groups)]
vertices = [[] for i, value in enumerate(self.mapset.groups)]
tex_coords = [[] for i, value in enumerate(self.mapset.groups)]
count = [0 for i, value in enumerate(self.mapset.groups)]
self.cur_objects = [[] for i, value in enumerate(self.mapset.groups)]
for y in xrange(self.tiles_y-1, -6, -1):
y1 = y*32+IF_BOTTOM
for x in xrange(self.tiles_x+5-1, -1, -1):
for obj in self.mapset.tiles.get((x-self.div_x, self.div_y-y), []):
x1 = x*32+IF_LEFT-obj.width+32
x2 = x1+obj.width
y2 = y1+obj.height
vertices[obj.group].extend([x1, y1, x2, y1, x2, y2, x1, y2])
tex_coords[obj.group].extend(obj.tex_coords)
count[obj.group]+=4
if isinstance(obj, Animation):
self.cur_objects[obj.group].append(obj)
for i, group in enumerate(self.mapset.groups):
if count[i] != 0:
self.vl_objects[i] = self.batch.add(count[i], pyglet.gl.GL_QUADS,
group,
('v2i', vertices[i]),
('t3f', tex_coords[i]),
('c4B', (255,255,255,255)*count[i]))
self.cur_objects[i] = list(set(self.cur_objects[i]))
self.view_x = mod_x-self.steps-(self.tile_size-32)//4
self.view_y = mod_y-self.steps-((self.tile_size-32)*3)//2
def on_draw(self):
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
pyglet.gl.glPushMatrix()
pyglet.gl.glTranslatef(self.view_x, self.view_y, 0)
pyglet.gl.glScalef(self.tile_size/32.0, self.tile_size/32.0, 0.0)
self.batch.draw()
pyglet.gl.glPopMatrix()
pyglet.gl.glLoadIdentity()
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glColor4f(1, 0, 1, 1)
pyglet.gl.glRectf(0, 0, self.window.width, IF_BOTTOM)
pyglet.gl.glRectf(self.window.width-IF_RIGHT, 0, self.window.width, self.window.height)
pyglet.gl.glRectf(0, self.window.height-IF_TOP, self.window.width, self.window.height)
pyglet.gl.glRectf(0, 0, IF_LEFT, self.window.height)
self.label.draw()
def _move(self, dx, dy):
#here we translate the global map position so we can draw with it
trans_global_x = self.steps-self.global_x
trans_global_y = self.steps-self.global_y
new_global_x = trans_global_x+dx
new_global_y = trans_global_y+dy
if self.global_x-dx < 0:
new_global_x = self.steps
if self.global_y-dy < 0:
new_global_y = self.steps
if dx-self.global_x < -self.tile_size*self.mapset.width+self.viewport_x:
new_global_x = -self.tile_size*self.mapset.width+self.viewport_x+self.steps
if dy-self.global_y < -self.tile_size*self.mapset.height+self.viewport_y:
new_global_y = -self.tile_size*self.mapset.height+self.viewport_y+self.steps
retex = False
if new_global_x < -self.undrawn_steps_x:
mod_x = new_global_x+self.undrawn_x
if trans_global_x >= -self.undrawn_steps_x:
retex = True
elif new_global_x < self.steps:
div_x, mod_x = divmod(new_global_x, self.steps)
retex = div_x != trans_global_x//self.steps or retex
else:
mod_x = new_global_x
if new_global_y < -self.undrawn_steps_y:
mod_y = new_global_y+self.undrawn_y
if trans_global_y >= -self.undrawn_steps_y:
retex = True
elif new_global_y < self.steps:
div_y, mod_y = divmod(new_global_y, self.steps)
retex = div_y != trans_global_y//self.steps or retex
else:
mod_y = new_global_y
if retex:
self.div_x = (new_global_x-mod_x)//self.tile_size
self.div_y = (new_global_y-mod_y)//self.tile_size+self.mapset.height-1
vertices = [[] for i, value in enumerate(self.mapset.groups)]
tex_coords = [[] for i, value in enumerate(self.mapset.groups)]
count = [0 for i, value in enumerate(self.mapset.groups)]
self.cur_objects = [[] for i, value in enumerate(self.mapset.groups)]
for y in xrange(self.tiles_y-1, -6, -1):
y1 = y*32+IF_BOTTOM
for x in xrange(self.tiles_x+5-1, -1, -1):
for obj in self.mapset.tiles.get((x-self.div_x, self.div_y-y), []):
x1 = x*32+IF_LEFT-obj.width+32
x2 = x1+obj.width
y2 = y1+obj.height
tex_coords[obj.group].extend(obj.tex_coords)
vertices[obj.group].extend([x1, y1, x2, y1, x2, y2, x1, y2])
count[obj.group]+=4
if isinstance(obj, Animation):
self.cur_objects[obj.group].append(obj)
for i, group in enumerate(self.mapset.groups):
if count[i] == 0:
if self.vl_objects[i] is None:
pass
else:
self.vl_objects[i].delete()
self.vl_objects[i] = None
else:
if self.vl_objects[i] is None:
self.vl_objects[i] = self.batch.add(count[i],
pyglet.gl.GL_QUADS,
group,
('v2i', vertices[i]),
('t3f', tex_coords[i]),
('c4B', (255,255,255,255)*count[i]))
else:
self.vl_objects[i].resize(count[i])
self.vl_objects[i].tex_coords = tex_coords[i]
self.vl_objects[i].vertices = vertices[i]
self.vl_objects[i].colors = (255,255,255,255)*count[i]
self.cur_objects[i] = list(set(self.cur_objects[i]))
if not self.center_x:
self.view_x = mod_x-self.steps-(self.tile_size-32)//4
self.global_x = self.steps-new_global_x
if not self.center_y:
self.view_y = mod_y-self.steps-((self.tile_size-32)*3)//2
self.global_y = self.steps-new_global_y
def update(self, dt):
try:
if self.window.keys[pyglet.window.key.LCTRL] and \
any([self.window.keys[pyglet.window.key.UP],
self.window.keys[pyglet.window.key.DOWN],
self.window.keys[pyglet.window.key.LEFT],
self.window.keys[pyglet.window.key.RIGHT]]):
if self.window.keys[pyglet.window.key.LEFT]:
x = 1
elif self.window.keys[pyglet.window.key.RIGHT]:
x = -1
else:
x = 0
if self.window.keys[pyglet.window.key.UP]:
y = -1
elif self.window.keys[pyglet.window.key.DOWN]:
y = 1
else:
y = 0
self.dx += x*8
self.dy += y*8
elif self.window.keys[pyglet.window.key.PLUS] and \
self.tile_size < 32:
self.tile_size+=8
self._init_view()
elif self.window.keys[pyglet.window.key.MINUS] and \
self.tile_size > 16:
self.tile_size-=8
self._init_view()
except KeyError:
pass
if self.dx or self.dy:
self._move(self.dx, self.dy)
self.dx = 0
self.dy = 0
#mouse position:
if self.mouse_x != self.mouse_dx or self.mouse_y != self.mouse_dy:
self.mouse_x = self.mouse_dx
self.mouse_y = self.mouse_dy
x = (self.mouse_x-IF_LEFT-self.view_x
-(self.tile_size-32)//4)//self.tile_size
y = (self.mouse_y-IF_BOTTOM-self.view_y
-((self.tile_size-32)*3)//2)//self.tile_size
self.label.text = "%03d %03d"%(x-self.div_x, self.div_y-y)
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
self.dx += dx
self.dy += dy
self.mouse_dx = x
self.mouse_dy = y
return pyglet.event.EVENT_HANDLED
def on_mouse_motion(self, x, y, dx, dy):
self.mouse_dx = x
self.mouse_dy = y
return pyglet.event.EVENT_HANDLED
def on_resize(self, width, height):
self._init_view()
def animate_water(self, dt):
for i, group in enumerate(self.mapset.groups):
if len(self.cur_objects[i]) > 0:
pyglet.gl.glBindTexture(self.cur_objects[i][0].tex.target,
self.cur_objects[i][0].tex.id)
for obj in self.cur_objects[i]:
pyglet.gl.glTexSubImage2D(obj.tex.owner.target,
obj.tex.owner.level,
obj.tex.x, obj.tex.y,
obj.tex.width, obj.tex.height,
pyglet.gl.GL_RGBA, pyglet.gl.GL_UNSIGNED_BYTE,
obj.next_frame())
class Window(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(1280, 1024, resizable=True, vsync=False)
self.keys = pyglet.window.key.KeyStateHandler()
self.push_handlers(self.keys)
self.fps = pyglet.clock.ClockDisplay()
pyglet.clock.schedule(lambda dt: None)
def on_draw(self):
self.fps.draw()
def on_key_press(self, symbol, modifiers):
if symbol == pyglet.window.key.F11:
self.set_fullscreen(fullscreen=not self.fullscreen)
elif symbol == pyglet.window.key.P:
pyglet.image.get_buffer_manager().get_color_buffer().save(
'screenshot.png', encoder=PNGRGBEncoder())
class PNGRGBEncoder(pyglet.image.codecs.ImageEncoder):
def encode(self, image, file, filename):
import Image
image = image.get_image_data()
format = image.format
pitch = -(image.width * len(format))
pil_image = Image.fromstring(
format, (image.width, image.height), image.get_data(format, pitch))
try:
#.convert('P', palette=Image.WEB)
pil_image.convert("RGB").save(file)
except Exception, e:
raise ImageEncodeException(e)
class Interface(object):
def __init__(self, window):
self.window = window
def on_mouse_motion(self, x, y, dx, dy):
if IF_LEFT < x < (self.window.width-IF_RIGHT):
pass
else:
return pyglet.event.EVENT_HANDLED
if IF_BOTTOM < y < (self.window.height-IF_TOP):
pass
else:
return pyglet.event.EVENT_HANDLED
class LoadScreen(object):
def __init__(self, window):
self.window = window
self.label = pyglet.text.Label('',
font_name="Linux Libertine",
font_size=28,
x=self.window.width-10, y=10,
anchor_x='right', anchor_y='bottom')
self.label.text = "PARSING MAP FILE..."
h3m = json.loads(pyglet.resource.file("test.h3m").read())
self.label.text = "PARSING MAP FILE..."
edge_map = [[] for i in xrange(len(h3m["upper_terrain"])+16)]
for num in xrange(len(edge_map)):
if num < 7 or num > len(edge_map)-8:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0])+18)])
elif num == 7:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 16, 0, 0, 0, 0, 0])
line.extend([[-1, 20+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0]))])
line.append([-1, 17, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
elif num == len(edge_map)-8:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 19, 0, 0, 0, 0, 0])
line.extend([[-1, 28+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0]))])
line.append([-1, 18, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
else:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 32+num%4, 0, 0, 0, 0, 0])
line.extend(h3m["upper_terrain"][num-8])
line.append([-1, 24+num%4, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
edge_map[num] = line
h3m["upper_terrain"] = edge_map
self.label.text = "INITIATING MAPSET..."
mapset = MapSet(h3m["upper_terrain"], h3m["objects"], h3m["tunedobj"])
self.label.text = "INITIATING MAPVIEW..."
mapview = MapView(mapset, self.window)
interface = Interface(self.window)
self.window.pop_handlers()
self.window.push_handlers(mapview)
self.window.push_handlers(interface)
self.window.push_handlers(self.window.keys)
if __name__ == '__main__':
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA,
pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
window = Window()
window.push_handlers(LoadScreen(window))
img = pyglet.resource.image("data/cursors/cradvntr.def/0.png")
window.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
pyglet.app.run()

@ -0,0 +1,787 @@
#!/usr/bin/python
"""
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pyglet, re
from ctypes import create_string_buffer, memmove
import itertools
try:
import json
except ImportError:
try:
import simplejson as json
except ImportError:
import demjson as json
json.loads = json.decode
json.dumps = json.encode
IF_BOTTOM = 0#48
IF_RIGHT = 0#200
IF_TOP = IF_LEFT = 0#8
class OrderedTextureGroup(pyglet.graphics.Group):
def __init__(self, order, texture, parent=None):
super(OrderedTextureGroup, self).__init__(parent)
self.texture = texture
self.order = order
def set_state(self):
pyglet.gl.glEnable(self.texture.target)
pyglet.gl.glBindTexture(self.texture.target, self.texture.id)
def unset_state(self):
pyglet.gl.glDisable(self.texture.target)
def __hash__(self):
return hash((self.order, self.texture.target, self.texture.id,
self.parent))
def __eq__(self, other):
return (self.__class__ is other.__class__ and
self.order == other.order and
self.texture.target == other.texture.target and
self.texture.id == other.texture.id and
self.parent == self.parent)
def __repr__(self):
return '%s(id=%d)' % (self.__class__.__name__, self.order,
self.texture.id)
def __cmp__(self, other):
if isinstance(other, OrderedTextureGroup):
return cmp(self.order, other.order)
return -1
class Animation(object):
def __init__(self, tex_region, frames, flip_x=False, flip_y=False):
self.texgroup = tex_region.group
if flip_x or flip_y:
self.tex = tex_region.get_transform(flip_x=flip_x, flip_y=flip_y)
else:
self.tex = tex_region
self.__frames = []
for img in frames:
data_pitch = abs(img._current_pitch)
buf = create_string_buffer(len(img._current_data))
memmove(buf, img._current_data, len(img._current_data))
data = buf.raw
rows = [data[i:i + abs(data_pitch)] for i in
xrange(len(img._current_data)-abs(data_pitch),
-1, -abs(data_pitch))]
self.__frames.append(''.join(rows))
self.__animation = 0
self.width = self.tex.width
self.height = self.tex.height
self.__hash = hash(self.__frames[0])
def next_frame(self):
self.__animation = (self.__animation + 1) % len(self.__frames)
return self.__frames[self.__animation]
@property
def tex_coords(self):
return self.tex.tex_coords
@property
def group(self):
return self.texgroup
def __hash__(self):
return self.__hash
def __eq__(self, other):
return self.__hash == other.__hash
class MapSet(object):
def load_map_object(self, file, order=0):
image = pyglet.image.load(None, file=pyglet.resource.file(file))
try:
texture_region = self.current_atlas.add(image)
except pyglet.image.atlas.AllocatorException:
self.current_atlas = pyglet.image.atlas.TextureAtlas(1024, 1024)
texture_region = self.current_atlas.add(image)
group = OrderedTextureGroup(order, self.current_atlas.texture)
if group not in self.groups:
self.groups.append(group)
texture_region.group = self.groups.index(group)
return texture_region
def __init__(self, loaded_map, objects, tunedobj):
self.width = len(loaded_map[0])
self.height = len(loaded_map)
self.current_atlas = pyglet.image.atlas.TextureAtlas(1024, 1024)
self.groups = []
self.__tiles = {}
tile_textures = {}
for y, line in enumerate(loaded_map):
for x, tile in enumerate(line):
if tile[0] == -1: #edge
if "edg" not in tile_textures.keys():
tile_textures["edg"] = [self.load_map_object('data/tiles/edg.def/%d.png'%i, 100) for i in xrange(36)]
self.__tiles[x,y] = [tile_textures["edg"][tile[1]]]
elif tile[0] == 0: #dirt
if "dirttl" not in tile_textures.keys():
tile_textures["dirttl"] = [self.load_map_object('data/tiles/dirttl.def/%d.png'%i, 0) for i in xrange(46)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["dirttl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["dirttl"][tile[1]].group
self.__tiles[x,y] = [new]
else:
self.__tiles[x,y] = [tile_textures["dirttl"][tile[1]]]
elif tile[0] == 1: #sand
if "sandtl" not in tile_textures.keys():
tile_textures["sandtl"] = [self.load_map_object('data/tiles/sandtl.def/%d.png'%i, 0) for i in xrange(24)]
self.__tiles[x,y] = [tile_textures["sandtl"][tile[1]]]
elif tile[0] == 2: #grass
if "grastl" not in tile_textures.keys():
tile_textures["grastl"] = [self.load_map_object('data/tiles/grastl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["grastl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["grastl"][tile[1]].group
self.__tiles[x,y] = [new]
else:
self.__tiles[x,y] = [tile_textures["grastl"][tile[1]]]
elif tile[0] == 3: #snow
if "snowtl" not in tile_textures.keys():
tile_textures["snowtl"] = [self.load_map_object('data/tiles/snowtl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["snowtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["snowtl"][tile[1]].group
self.__tiles[x,y] = [new]
else:
self.__tiles[x,y] = [tile_textures["snowtl"][tile[1]]]
elif tile[0] == 4: #swamp
if "swmptl" not in tile_textures.keys():
tile_textures["swmptl"] = [self.load_map_object('data/tiles/swmptl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["swmptl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["swmptl"][tile[1]].group
self.__tiles[x,y] = [new]
else:
self.__tiles[x,y] = [tile_textures["swmptl"][tile[1]]]
elif tile[0] == 5: #rough
if "rougtl" not in tile_textures.keys():
tile_textures["rougtl"] = [self.load_map_object('data/tiles/rougtl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["rougtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["rougtl"][tile[1]].group
self.__tiles[x,y] = [new]
else:
self.__tiles[x,y] = [tile_textures["rougtl"][tile[1]]]
elif tile[0] == 7: #lava
if "lavatl" not in tile_textures.keys():
tile_textures["lavatl"] = [self.load_map_object('data/tiles/lavatl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["lavatl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["lavatl"][tile[1]].group
self.__tiles[x,y] = [new]
else:
self.__tiles[x,y] = [tile_textures["lavatl"][tile[1]]]
elif tile[0] == 8: #water 12 anims
if "watrtl" not in tile_textures.keys():
textures = [self.load_map_object('data/tiles/watrtl.def/%d/0.png'%i, 0) for i in xrange(33)]
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/tiles/watrtl.def/%d/%d.png'%(i,j))) for j in xrange(12)] for i in xrange(33)]
tile_textures["watrtl"] = {
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
}
flip_x = (tile[6]>>0)&1
flip_y = (tile[6]>>1)&1
self.__tiles[x,y] = [tile_textures["watrtl"][flip_x, flip_y][tile[1]]]
elif tile[0] == 9: #rock
if "rocktl" not in tile_textures.keys():
tile_textures["rocktl"] = [self.load_map_object('data/tiles/rocktl.def/%d.png'%i, 0) for i in xrange(48)]
self.__tiles[x,y] = [tile_textures["rocktl"][tile[1]]]
else:
raise NotImplementedError
if tile[2] == 0: #no river
pass
elif tile[2] == 1: #clrrvr 12 anims
if "clrrvr" not in tile_textures.keys():
textures = [self.load_map_object('data/tiles/clrrvr.def/%d/0.png'%i, 1) for i in xrange(13)]
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/tiles/clrrvr.def/%d/%d.png'%(i,j))) for j in xrange(12)] for i in xrange(13)]
tile_textures["clrrvr"] = {
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
}
flip_x = (tile[6]>>2)&1
flip_y = (tile[6]>>3)&1
self.__tiles[x,y].append(tile_textures["clrrvr"][flip_x, flip_y][tile[3]])
elif tile[2] == 2: #icyrvr
if "icyrvr" not in tile_textures.keys():
tile_textures["icyrvr"] = [self.load_map_object('data/tiles/icyrvr.def/%d.png'%i, 1) for i in xrange(13)]
flip_x = bool(tile[6] & 4)
flip_y = bool(tile[6] & 8)
if flip_x or flip_y:
new = tile_textures["icyrvr"][tile[3]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["icyrvr"][tile[3]].group
self.__tiles[x, y].append(new)
else:
self.__tiles[x, y].append(tile_textures["icyrvr"][tile[3]])
elif tile[2] == 3: #mudrvr
if "mudrvr" not in tile_textures.keys():
textures = [self.load_map_object('data/tiles/mudrvr.def/%d/0.png'%i, 1) for i in xrange(13)]
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/tiles/clrrvr.def/%d/%d.png'%(i,j))) for j in xrange(12)] for i in xrange(13)]
tile_textures["mudrvr"] = {
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
}
flip_x = (tile[6]>>2)&1
flip_y = (tile[6]>>3)&1
self.__tiles[x,y].append(tile_textures["mudrvr"][flip_x, flip_y][tile[3]])
elif tile[2] == 4: #lavrvr
if "lavrvr" not in tile_textures.keys():
textures = [self.load_map_object('data/tiles/lavrvr.def/%d/0.png'%i, 1) for i in xrange(13)]
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/tiles/clrrvr.def/%d/%d.png'%(i,j))) for j in xrange(9)] for i in xrange(13)]
tile_textures["lavrvr"] = {
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
}
flip_x = (tile[6]>>2)&1
flip_y = (tile[6]>>3)&1
self.__tiles[x,y].append(tile_textures["lavrvr"][flip_x, flip_y][tile[3]])
else:
raise NotImplementedError, tile[2]
if tile[4] == 0: #no road
pass
elif tile[4] == 1: #dirtrd
if "dirtrd" not in tile_textures.keys():
tile_textures["dirtrd"] = [self.load_map_object('data/tiles/dirtrd.def/%d.png'%i, 1) for i in xrange(17)]
flip_x = bool(tile[6] & 16)
flip_y = bool(tile[6] & 32)
if flip_x or flip_y:
new = tile_textures["dirtrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["dirtrd"][tile[5]].group
self.__tiles[x, y].append(new)
else:
self.__tiles[x, y].append(tile_textures["dirtrd"][tile[5]])
elif tile[4] == 2: #gravrd
if "gravrd" not in tile_textures.keys():
tile_textures["gravrd"] = [self.load_map_object('data/tiles/gravrd.def/%d.png'%i, 1) for i in xrange(17)]
flip_x = bool(tile[6] & 16)
flip_y = bool(tile[6] & 32)
if flip_x or flip_y:
new = tile_textures["gravrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["gravrd"][tile[5]].group
self.__tiles[x, y].append(new)
else:
self.__tiles[x, y].append(tile_textures["gravrd"][tile[5]])
elif tile[4] == 3: #cobbrd
if "cobbrd" not in tile_textures.keys():
tile_textures["cobbrd"] = [self.load_map_object('data/tiles/cobbrd.def/%d.png'%i, 1) for i in xrange(17)]
flip_x = bool(tile[6] & 16)
flip_y = bool(tile[6] & 32)
if flip_x or flip_y:
new = tile_textures["cobbrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["cobbrd"][tile[5]].group
self.__tiles[x, y].append(new)
else:
self.__tiles[x, y].append(tile_textures["cobbrd"][tile[5]])
else:
raise NotImplementedError, tile[4]
images = []
for order, obj in enumerate(objects):
imgs = []
i = 0
while 1:
imgs.append(pyglet.image.load(None, file=pyglet.resource.file("data/map_objects/" + obj["filename"] + "/%d.png"%i)))
i += 1
if "data/map_objects/" + obj["filename"] + "/%d.png" % i not in pyglet.resource._default_loader._index.keys():
break;
images.append((imgs, order))
self.objects = []
for imgs in sorted(images, key=lambda i:i[0][0].height, reverse=True):
try:
texture = self.current_atlas.add(imgs[0][0])
except pyglet.image.atlas.AllocatorException:
self.current_atlas = pyglet.image.atlas.TextureAtlas(1024, 1024)
print "atlas"
texture = self.current_atlas.add(imgs[0][0])
group = OrderedTextureGroup(2, self.current_atlas.texture)
if group not in self.groups:
self.groups.append(group)
group = self.groups.index(group)
texture.group = group
self.objects.append((Animation(texture, imgs[0]), imgs[1]))
self.objects = [i[0] for i in sorted(self.objects, key=lambda i:i[1])]
self.tunedobj = {}
for obj in [i for i in tunedobj if i["z"]==0]:
self.__tiles[obj["x"] + 9,obj["y"] + 8].append(self.objects[obj["id"]])
def get_tiles(self, tiles_x, tiles_y, div_x, div_y):
for y in xrange(tiles_y - 1, -6, -1):
y1 = y * 32 + IF_BOTTOM
for x in xrange(tiles_x + 5 - 1, -1, -1):
for obj in self.__tiles.get((x - div_x, div_y - y), []):
x1 = x * 32 + IF_LEFT - obj.width + 32
x2 = x1 + obj.width
y2 = y1 + obj.height
yield obj, [x1, y1, x2, y1, x2, y2, x1, y2]
class MapView(object):
def __init__(self, mapset, window):
self.window = window
self.mapset = mapset
self._first_time_init()
self._init_view()
# mouse position
self.label = pyglet.text.Label('',
font_name="",
font_size=36,
bold=True,
color=(128, 128, 128, 128),
x=self.window.width - 10, y=0,
anchor_x='right', anchor_y='bottom')
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
pyglet.clock.schedule_interval(self.update, 1/60.0)
def _first_time_init(self):
self.tile_size = 32
# size of the viewport
self.vp_width = self.window.width-IF_RIGHT-IF_LEFT
self.vp_height = self.window.height-IF_BOTTOM-IF_TOP
# center map
self.x = (self.mapset.width * self.tile_size - self.vp_width +
self.tile_size) // 2
self.y = (self.mapset.height * self.tile_size - self.vp_height +
self.tile_size) // 2
self.mouse_x = self.mouse_dx = 0
self.mouse_y = self.mouse_dy = 0
def _init_view(self):
# initiate new batch
self.batch = pyglet.graphics.Batch()
# initiate new vertex list
self.vl_objects = [None for value in self.mapset.groups]
# size of the viewport
self.vp_width = self.window.width - IF_RIGHT - IF_LEFT
self.vp_height = self.window.height - IF_BOTTOM - IF_TOP
# center map when viewport is too large, else check if map still fills
# whole viewport and if not adjust position accordingly
self.center_x = False
if self.mapset.width * self.tile_size < self.vp_width:
# center the map in x direction
self.center_x = True
self.x = (self.mapset.width * self.tile_size - self.vp_width) // 2
elif self.x > self.tile_size * self.mapset.width - self.vp_width:
# move map back to the right
self.x = self.tile_size * self.mapset.width - self.vp_width
elif self.x < 0:
# move map to the left
self.x = 0
self.center_y = False
if self.mapset.height * self.tile_size < self.vp_height:
# center the map in y direction
self.center_y = True
self.y = (self.mapset.height * self.tile_size -
self.vp_height) // 2
elif self.y > self.tile_size * self.mapset.height - self.vp_height:
# move map up
self.y = self.tile_size * self.mapset.height - self.vp_height
elif self.y < 0:
# move map down
self.y = 0
# tiles to be drawn with the current viewport size
self.tiles_x = min((self.vp_width // self.tile_size) + 2,
self.mapset.width)
self.tiles_y = min((self.vp_height // self.tile_size) + 2,
self.mapset.height)
# undrawn map size in pixels
self.undrawn_x = self.tile_size * (self.mapset.width - self.tiles_x)
self.undrawn_y = self.tile_size * (self.mapset.height - self.tiles_y)
# reset mouse or keyboard movement
self.dx = 0
self.dy = 0
# calculate modulo pixel position of the map
if self.x - self.tile_size > self.undrawn_x:
# dont go right beyond map borders
mod_x = self.tile_size - self.x + self.undrawn_x
elif self.x > 0:
# calculate modulo of current position and tile_size
mod_x = (self.tile_size - self.x) % self.tile_size
else:
# dont go left beyond map borders
mod_x = self.tile_size - self.x
if self.y - self.tile_size > self.undrawn_y:
# dont go up beyond map borders
mod_y = self.tile_size - self.y + self.undrawn_y
elif self.y > 0:
# calculate modulo of current position and tile_size
mod_y = (self.tile_size - self.y) % self.tile_size
else:
# dont go down beyond map borders
mod_y = self.tile_size - self.y
# calculate tile position of the map, turn y coordinates upside down
self.div_x = (self.tile_size - self.x - mod_x) // self.tile_size
self.div_y = (self.tile_size - self.y - mod_y) // self.tile_size + \
self.mapset.height - 1
# update vertex lists with the gathered information
self.update_vertex_lists()
# update current current position that is to be glTranslated
# XXX: dont ask me why i have to add 1/4 and 3/2 but when i do not
# there are black borders when zooming out
# plz explain wtf is going on there
self.view_x = mod_x - self.tile_size - (self.tile_size - 32) // 4
self.view_y = mod_y - self.tile_size - ((self.tile_size - 32) * 3) // 2
def on_draw(self):
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
pyglet.gl.glPushMatrix()
pyglet.gl.glTranslatef(self.view_x, self.view_y, 0)
pyglet.gl.glScalef(self.tile_size/32.0, self.tile_size/32.0, 0.0)
self.batch.draw()
pyglet.gl.glPopMatrix()
pyglet.gl.glLoadIdentity()
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glColor4f(1, 0, 1, 1)
pyglet.gl.glRectf(0, 0, self.window.width, IF_BOTTOM)
pyglet.gl.glRectf(self.window.width-IF_RIGHT, 0, self.window.width, self.window.height)
pyglet.gl.glRectf(0, self.window.height-IF_TOP, self.window.width, self.window.height)
pyglet.gl.glRectf(0, 0, IF_LEFT, self.window.height)
self.label.draw()
def _move(self, dx, dy):
# new map position
new_x = self.x - dx
new_y = self.y - dy
# only update textures and vertices when necessary
retex = False
# if x or y jump is too big, adjust new position accordingly
if new_x < 0:
# move map to the left
new_x = 0
retex = True
if new_x > self.tile_size * self.mapset.width - self.vp_width:
# move map to the right
new_x = self.tile_size * self.mapset.width - self.vp_width
retex = True
if new_y < 0:
# move map down
new_y = 0
retex = True
if new_y > self.tile_size * self.mapset.height - self.vp_height:
# move map up
new_y = self.tile_size * self.mapset.height - self.vp_height
retex = True
# find out how many steps and pixels we have to move and wether we have
# to retex
if new_x - self.tile_size > self.undrawn_x:
# we are at the right border
mod_x = self.tile_size - new_x + self.undrawn_x
# only retex if the last position was not at the border
if self.x - self.tile_size <= self.undrawn_x:
retex = True
elif new_x > 0:
# normal movement: calculate the amount of steps and the modulo
div_x, mod_x = divmod(self.tile_size - new_x, self.tile_size)
# only retex if the number of moved steps is not equal to last
if div_x != (self.tile_size - self.x) // self.tile_size:
retex = True
else:
# we are at the left border
mod_x = self.tile_size - new_x
if new_y - self.tile_size > self.undrawn_y:
# we are at the top
mod_y = self.tile_size - new_y + self.undrawn_y
# only retex if the last position was not at the border
if self.y - self.tile_size <= self.undrawn_y:
retex = True
elif new_y > 0:
# normal movement: calculate the amount of steps and the modulo
div_y, mod_y = divmod(self.tile_size - new_y, self.tile_size)
# only retex if the number of moved steps is not equal to last
if div_y != (self.tile_size - self.y) // self.tile_size:
retex = True
else:
# we are at the bottom
mod_y = self.tile_size - new_y
# if we have to update vertices and textures
if retex:
# calculate the current position on the tilemap
self.div_x = (self.tile_size - new_x - mod_x) // \
self.tile_size
self.div_y = (self.tile_size - new_y - mod_y) // \
self.tile_size + self.mapset.height - 1
self.update_vertex_lists()
# update position if not centered
# XXX: dont ask me why i have to add 1/4 and 3/2 but when i do not
# there are black borders when zooming out
# plz explain wtf is going on there
if not self.center_x:
self.view_x = mod_x-self.tile_size-(self.tile_size-32)//4
self.x = new_x
if not self.center_y:
self.view_y = mod_y-self.tile_size-((self.tile_size-32)*3)//2
self.y = new_y
def update_vertex_lists(self):
# initiate lists of vertex lists, vertices, texture coords, vertices
# counts and map objects for each group
vertices = [[] for value in self.mapset.groups]
tex_coords = [[] for value in self.mapset.groups]
count = [0 for value in self.mapset.groups]
self.cur_objects = [[] for value in self.mapset.groups]
# for each tile in the viewport, update the list of the specific group
for obj, coords in self.mapset.get_tiles(self.tiles_x, self.tiles_y,
self.div_x, self.div_y):
tex_coords[obj.group].extend(obj.tex_coords)
vertices[obj.group].extend(coords)
count[obj.group]+=4
if isinstance(obj, Animation):
self.cur_objects[obj.group].append(obj)
for i, group in enumerate(self.mapset.groups):
if count[i] == 0:
if self.vl_objects[i] is None:
# let the vertex list be None
pass
else:
# there was a vertex list but now no more - delete it
self.vl_objects[i].delete()
self.vl_objects[i] = None
else:
if self.vl_objects[i] is None:
# there was no vertex list but ther now is one - create it
self.vl_objects[i] = self.batch.add(count[i],
pyglet.gl.GL_QUADS,
group,
('v2i', vertices[i]),
('t3f', tex_coords[i]),
('c4B', (255,255,255,255)*count[i]))
else:
# there already is a vertex list - resize and refill
self.vl_objects[i].resize(count[i])
self.vl_objects[i].tex_coords = tex_coords[i]
self.vl_objects[i].vertices = vertices[i]
self.vl_objects[i].colors = (255,255,255,255)*count[i]
# make object list unique
self.cur_objects[i] = list(set(self.cur_objects[i]))
def update(self, dt):
try:
if self.window.keys[pyglet.window.key.LCTRL] and \
any([self.window.keys[pyglet.window.key.UP],
self.window.keys[pyglet.window.key.DOWN],
self.window.keys[pyglet.window.key.LEFT],
self.window.keys[pyglet.window.key.RIGHT]]):
if self.window.keys[pyglet.window.key.LEFT]:
x = 1
elif self.window.keys[pyglet.window.key.RIGHT]:
x = -1
else:
x = 0
if self.window.keys[pyglet.window.key.UP]:
y = -1
elif self.window.keys[pyglet.window.key.DOWN]:
y = 1
else:
y = 0
self.dx += x*8
self.dy += y*8
elif self.window.keys[pyglet.window.key.PLUS] and \
self.tile_size < 32:
self.tile_size+=8
self._init_view()
elif self.window.keys[pyglet.window.key.MINUS] and \
self.tile_size > 16:
self.tile_size-=8
self._init_view()
except KeyError:
pass
if self.dx or self.dy:
self._move(self.dx, self.dy)
self.dx = 0
self.dy = 0
# mouse position:
if self.mouse_x != self.mouse_dx or self.mouse_y != self.mouse_dy:
self.mouse_x = self.mouse_dx
self.mouse_y = self.mouse_dy
x = (self.mouse_x-IF_LEFT-self.view_x
-(self.tile_size-32)//4)//self.tile_size
y = (self.mouse_y-IF_BOTTOM-self.view_y
-((self.tile_size-32)*3)//2)//self.tile_size
self.label.text = "%03d %03d"%(x-self.div_x, self.div_y-y)
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
self.dx += dx
self.dy += dy
self.mouse_dx = x
self.mouse_dy = y
return pyglet.event.EVENT_HANDLED
def on_mouse_motion(self, x, y, dx, dy):
self.mouse_dx = x
self.mouse_dy = y
return pyglet.event.EVENT_HANDLED
def on_resize(self, width, height):
self._init_view()
def animate_water(self, dt):
for i, group in enumerate(self.mapset.groups):
if len(self.cur_objects[i]) > 0:
pyglet.gl.glBindTexture(self.cur_objects[i][0].tex.target,
self.cur_objects[i][0].tex.id)
for obj in self.cur_objects[i]:
pyglet.gl.glTexSubImage2D(obj.tex.owner.target,
obj.tex.owner.level,
obj.tex.x, obj.tex.y,
obj.tex.width, obj.tex.height,
pyglet.gl.GL_RGBA, pyglet.gl.GL_UNSIGNED_BYTE,
obj.next_frame())
class Window(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(1280, 1024, resizable=True, vsync=False)
self.keys = pyglet.window.key.KeyStateHandler()
self.push_handlers(self.keys)
self.fps = pyglet.clock.ClockDisplay()
pyglet.clock.schedule(lambda dt: None)
def on_draw(self):
self.fps.draw()
def on_key_press(self, symbol, modifiers):
if symbol == pyglet.window.key.F11:
self.set_fullscreen(fullscreen=not self.fullscreen)
elif symbol == pyglet.window.key.P:
pyglet.image.get_buffer_manager().get_color_buffer().save(
'screenshot.png', encoder=PNGRGBEncoder())
class PNGRGBEncoder(pyglet.image.codecs.ImageEncoder):
def encode(self, image, file, filename):
import Image
image = image.get_image_data()
format = image.format
pitch = -(image.width * len(format))
pil_image = Image.fromstring(
format, (image.width, image.height), image.get_data(format, pitch))
try:
#.convert('P', palette=Image.WEB)
pil_image.convert("RGB").save(file)
except Exception, e:
raise ImageEncodeException(e)
class Interface(object):
def __init__(self, window):
self.window = window
def on_mouse_motion(self, x, y, dx, dy):
if IF_LEFT < x < (self.window.width-IF_RIGHT):
pass
else:
return pyglet.event.EVENT_HANDLED
if IF_BOTTOM < y < (self.window.height-IF_TOP):
pass
else:
return pyglet.event.EVENT_HANDLED
class LoadScreen(object):
def __init__(self, window):
self.window = window
self.label = pyglet.text.Label('',
font_name="Linux Libertine",
font_size=28,
x=self.window.width-10, y=10,
anchor_x='right', anchor_y='bottom')
self.label.text = "PARSING MAP FILE..."
h3m = json.loads(pyglet.resource.file("test.h3m").read())
self.label.text = "PARSING MAP FILE..."
edge_map = [[] for i in xrange(len(h3m["upper_terrain"])+16)]
for num in xrange(len(edge_map)):
if num < 7 or num > len(edge_map)-8:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0])+18)])
elif num == 7:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 16, 0, 0, 0, 0, 0])
line.extend([[-1, 20+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0]))])
line.append([-1, 17, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
elif num == len(edge_map)-8:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 19, 0, 0, 0, 0, 0])
line.extend([[-1, 28+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0]))])
line.append([-1, 18, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
else:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 32+num%4, 0, 0, 0, 0, 0])
line.extend(h3m["upper_terrain"][num-8])
line.append([-1, 24+num%4, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
edge_map[num] = line
h3m["upper_terrain"] = edge_map
self.label.text = "INITIATING MAPSET..."
mapset = MapSet(h3m["upper_terrain"], h3m["objects"], h3m["tunedobj"])
self.label.text = "INITIATING MAPVIEW..."
mapview = MapView(mapset, self.window)
interface = Interface(self.window)
self.window.pop_handlers()
self.window.push_handlers(mapview)
self.window.push_handlers(interface)
self.window.push_handlers(self.window.keys)
if __name__ == '__main__':
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA,
pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
window = Window()
window.push_handlers(LoadScreen(window))
img = pyglet.resource.image("data/cursors/cradvntr.def/0.png")
window.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
pyglet.app.run()

File diff suppressed because it is too large Load Diff

Binary file not shown.

@ -0,0 +1,40 @@
#!/usr/bin/python
"""
homm3hmtest
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import gzip, os
import struct
import sys
def extract(filename):
h3m_data = gzip.open(filename)
map_data = {}
#read general info
(map_data["version"], ) = struct.unpack("<I", h3m_data.read(4))
if map_data["version"] == 0x1C:
h3m_data.read(1)
(size,) = struct.unpack("<I", h3m_data.read(4))
print filename, size
def main(args):
for arg in args[1:]:
extract(arg)
if __name__ == '__main__':
sys.exit(main(sys.argv))

51
hr.py

@ -0,0 +1,51 @@
#!/usr/bin/env python
"""
heroes renaissance
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pyglet
from lib.mapset import *
from lib.interface import *
from lib.mapview import *
from lib.window import Window
class LoadScreen(object):
def __init__(self, window):
self.window = window
self.label = pyglet.text.Label('',
font_name="Linux Libertine",
font_size=28,
x=self.window.width-10, y=10,
anchor_x='right', anchor_y='bottom')
self.label.text = "INITIATING MAPSET..."
mapset = MapSet("Deluge")
self.label.text = "INITIATING MAPVIEW..."
mapview = MapView(mapset, self.window)
interface = Interface(self.window)
self.window.pop_handlers()
self.window.push_handlers(mapview)
self.window.push_handlers(interface)
self.window.push_handlers(self.window.keys)
if __name__ == '__main__':
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA,
pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
window = Window()
window.push_handlers(LoadScreen(window))
img = pyglet.resource.image("data/cursors/cradvntr.def/0.png")
window.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
pyglet.app.run()

@ -0,0 +1,596 @@
#!/usr/bin/env python
"""
heroes renaissance
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import gzip
import struct
import pyglet
def extract(filename):
h3m_data = gzip.open(filename)
map_data = {}
#read general info
(map_data["version"], ) = struct.unpack("<I", h3m_data.read(4))
if map_data["version"] != 0x1C:
return
(map_data["hero_present"], map_data["map_size"], map_data["underworld"],
) = struct.unpack("<BIB", h3m_data.read(6))
(name_length, ) = struct.unpack("<I", h3m_data.read(4))
map_data["map_name"] = h3m_data.read(name_length)
(desc_length, ) = struct.unpack("<I", h3m_data.read(4))
map_data["map_desc"] = h3m_data.read(desc_length)
(map_data["difficulty"], map_data["level_limit"],
) = struct.unpack("<BB", h3m_data.read(2))
#player info
for color in ("Red", "Blue", "Tan", "Green", "Orange", "Purple", "Teal", "Pink"):
map_data[color] = {}
(map_data[color]["is_human"], map_data[color]["is_computer"],
map_data[color]["behaviour"], map_data[color]["isCityTypesOpt"],
map_data[color]["cityTypes"], map_data[color]["randomCity"],
) = struct.unpack("<BBBBHB", h3m_data.read(7))
(main_city, ) = struct.unpack("<B", h3m_data.read(1))
if main_city:
map_data[color]["main_city"] = {}
(map_data[color]["main_city"]["generate_hero"],
map_data[color]["main_city"]["type"],
) = struct.unpack("<BB", h3m_data.read(2))
map_data[color]["main_city"]["coords"] = struct.unpack("<BBB", h3m_data.read(3))
(map_data[color]["random_hero"], map_data[color]["hero_type"],
) = struct.unpack("<BB", h3m_data.read(2))
if map_data[color]["hero_type"] != 0xFF:
(map_data[color]["hero_portrait"], ) = struct.unpack("<B", h3m_data.read(1))
(name_length, ) = struct.unpack("<I", h3m_data.read(4))
map_data[color]["hero_name"] = h3m_data.read(name_length)
h3m_data.read(1) #junk
(map_data[color]["heroes_count"], ) = struct.unpack("<I", h3m_data.read(4))
if map_data[color]["heroes_count"] > 0:
map_data[color]["heroes"] = {}
for i in xrange(map_data[color]["heroes_count"]):
(map_data[color]["heroes"]["portrait"], ) = struct.unpack("<B", h3m_data.read(1))
(name_length, ) = struct.unpack("<I", h3m_data.read(4))
map_data[color]["heroes"]["name"] = h3m_data.read(name_length)
#special victory condition
(map_data["victory_conditions"], ) = struct.unpack("<B", h3m_data.read(1))
if map_data["victory_conditions"] != 0xFF:
map_data["victory_conditions"] = {"id":map_data["victory_conditions"]}
(map_data["victory_conditions"]["canStandardEnd"], ) = struct.unpack("<B", h3m_data.read(1))
(map_data["victory_conditions"]["canComputer"], ) = struct.unpack("<B", h3m_data.read(1))
if map_data["victory_conditions"]["id"] == 0x00:
(map_data["victory_conditions"]["artID"], ) = struct.unpack("<B", h3m_data.read(1))
elif map_data["victory_conditions"]["id"] == 0x01:
(map_data["victory_conditions"]["creatureID"], ) = struct.unpack("<B", h3m_data.read(1))
(map_data["victory_conditions"]["creatureCount"], ) = struct.unpack("<H", h3m_data.read(2))
elif map_data["victory_conditions"]["id"] == 0x02:
(map_data["victory_conditions"]["resID"], ) = struct.unpack("<B", h3m_data.read(1))
(map_data["victory_conditions"]["resCount"], ) = struct.unpack("<I", h3m_data.read(4))
elif map_data["victory_conditions"]["id"] == 0x03:
raise NotImplementedError
elif map_data["victory_conditions"]["id"] in (0x04, 0x05, 0x06, 0x07):
(map_data["victory_conditions"]["x"], ) = struct.unpack("<B", h3m_data.read(1))
(map_data["victory_conditions"]["y"], ) = struct.unpack("<B", h3m_data.read(1))
(map_data["victory_conditions"]["z"], ) = struct.unpack("<B", h3m_data.read(1))
elif map_data["victory_conditions"]["id"] in (0x08, 0x09):
pass
elif map_data["victory_conditions"]["id"] == 0x0A:
raise NotImplementedError
else:
raise NotImplementedError
#special loss condition
(map_data["loss_conditions"], ) = struct.unpack("<B", h3m_data.read(1))
if map_data["loss_conditions"] != 0xFF:
map_data["loss_conditions"] = {"id":map_data["loss_conditions"]}
if map_data["loss_conditions"]["id"] in (0x00, 0x01):
(map_data["loss_conditions"]["x"], ) = struct.unpack("<B", h3m_data.read(1))
(map_data["loss_conditions"]["y"], ) = struct.unpack("<B", h3m_data.read(1))
(map_data["loss_conditions"]["z"], ) = struct.unpack("<B", h3m_data.read(1))
elif map_data["loss_conditions"]["id"] == 0x02:
#to be researched
struct.unpack("<B", h3m_data.read(1))
struct.unpack("<B", h3m_data.read(1))
elif map_data["loss_conditions"]["id"] == 0x03:
(map_data["loss_conditions"]["days"], ) = struct.unpack("<H", h3m_data.read(1))
else:
raise NotImplementedError
#Teams
(map_data["commands_count"], ) = struct.unpack("<B", h3m_data.read(1))
if map_data["commands_count"] > 0:
map_data["commands"] = struct.unpack("<8B", h3m_data.read(8))
#Free Heroes
h3m_data.read(20) #free heroes
h3m_data.read(4) #junk
(map_data["heroes_count"], ) = struct.unpack("<B", h3m_data.read(1))
if map_data["heroes_count"] > 0:
map_data["free_heroes"] = []
for i in xrange(map_data["heroes_count"]):
(hero_id, ) = struct.unpack("<B", h3m_data.read(1))
(hero_portrait, ) = struct.unpack("<B", h3m_data.read(1))
(name_length, ) = struct.unpack("<I", h3m_data.read(4))
hero_name = h3m_data.read(name_length)
(hero_players, ) = struct.unpack("<B", h3m_data.read(1))
map_data["free_heroes"].append({"id": hero_id, "portrait":hero_portrait, "name":hero_name, "players":hero_players})
h3m_data.read(31) #junk
#artefacts
h3m_data.read(18)
#spells
h3m_data.read(9)
#sec skillz
h3m_data.read(4)
#rumors
(map_data["rumor_count"], ) = struct.unpack("<I", h3m_data.read(4))
if map_data["rumor_count"] > 0:
map_data["rumors"] = []
for i in xrange(map_data["rumor_count"]):
(name_length, ) = struct.unpack("<I", h3m_data.read(4))
rumor_name = h3m_data.read(name_length)
(text_length, ) = struct.unpack("<I", h3m_data.read(4))
rumor_text = h3m_data.read(text_length)
map_data["rumors"].append({"name":rumor_name, "text":rumor_text})
#hero options
for i in xrange(156):
(hero_enable, ) = struct.unpack("<B", h3m_data.read(1))
if hero_enable == 1:
(isExp, ) = struct.unpack("<B", h3m_data.read(1))
if isExp == 0x01:
(exp, ) = struct.unpack("<I", h3m_data.read(4))
(isSecSkill, ) = struct.unpack("<B", h3m_data.read(1))
if isSecSkill == 0x01:
(skills_count) = struct.unpack("<I", h3m_data.read(4))
for i in xrange(skills_count):
(skill_id, ) = struct.unpack("<B", h3m_data.read(1))
(skill_lvl, ) = struct.unpack("<B", h3m_data.read(1))
(isArtifact, ) = struct.unpack("<B", h3m_data.read(1))
if isArtifact == 0x01:
raise NotImplementedError
(isBiography, ) = struct.unpack("<B", h3m_data.read(1))
if isBiography == 0x01:
(length, ) = struct.unpack("<I", h3m_data.read(4))
biography = h3m_data.read(length)
(gender, ) = struct.unpack("<B", h3m_data.read(1))
(isSpells, ) = struct.unpack("<B", h3m_data.read(1))
if isSpells == 0x01:
spells = struct.unpack("<9B", h3m_data.read(9))
(isPrimarySkills, ) = struct.unpack("<B", h3m_data.read(1))
if isPrimarySkills == 0x01:
(attack, defense, power, knowledge) = struct.unpack("<4B", h3m_data.read(4))
map_data["upper_terrain"] = [[] for i in xrange(map_data["map_size"])]
#read upper world
for i in xrange(map_data["map_size"]**2):
x = i%map_data["map_size"]
y = (i-x)/map_data["map_size"]
map_data["upper_terrain"][y].append(struct.unpack("<7B", h3m_data.read(7)))
#read underworld
if map_data["underworld"]:
map_data["lower_terrain"] = [[] for i in xrange(map_data["map_size"])]
for i in xrange(map_data["map_size"]**2):
x = i%map_data["map_size"]
y = (i-x)/map_data["map_size"]
map_data["lower_terrain"][y].append(struct.unpack("<7B", h3m_data.read(7)))
(map_data["object_count"], ) = struct.unpack("<I", h3m_data.read(4))
map_data["objects"] = []
for i in xrange(map_data["object_count"]):
(length, ) = struct.unpack("<I", h3m_data.read(4))
filename = h3m_data.read(length)
h3m_data.read(6) #passability
h3m_data.read(6) #actions
h3m_data.read(2) #landscape
h3m_data.read(2) #land_edit_groups
(obj_class, ) = struct.unpack("<I", h3m_data.read(4)) #class
(obj_number, ) = struct.unpack("<I", h3m_data.read(4)) #number
(obj_group, ) = struct.unpack("<B", h3m_data.read(1)) #group
h3m_data.read(1) #isOverlay
h3m_data.read(16) #junk
map_data["objects"].append({"filename":filename.lower(), "class":obj_class,
"number":obj_number, "group":obj_group})
(map_data["tunedobj_count"], ) = struct.unpack("<I", h3m_data.read(4))
map_data["tunedobj"] = []
for i in xrange(map_data["tunedobj_count"]):
(x, y, z) = struct.unpack("<3B", h3m_data.read(3))
(object_id, ) = struct.unpack("<I", h3m_data.read(4))
#print x,y,z,object_id,
junk = h3m_data.read(5) #junk
if junk != "\x00\x00\x00\x00\x00":
for c in junk:
print "%02d"%ord(c),
break
#print i, map_data["objects"][object_id]["filename"],
#print map_data["objects"][object_id]["class"]
map_data["tunedobj"].append({"id":object_id, "x":x, "y":y, "z":z})
if object_id in (0,1):
pass
elif map_data["objects"][object_id]["class"] == 53:
if map_data["objects"][object_id]["number"] == 7:
h3m_data.read(4)
else:
h3m_data.read(4)
elif map_data["objects"][object_id]["class"] in (76, 79):
(isText, ) = struct.unpack("<B", h3m_data.read(1))
if isText == 0x01:
(length, ) = struct.unpack("<I", h3m_data.read(4))
text = h3m_data.read(length)
(isGuards, ) = struct.unpack("<B", h3m_data.read(1))
if isGuards == 0x01:
for i in xrange(7):
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
h3m_data.read(4) #junk
(quantity, ) = struct.unpack("<I", h3m_data.read(4))
h3m_data.read(4) #junk
elif map_data["objects"][object_id]["class"] in (34, 70, 62):
(hero_id, color, hero) = struct.unpack("<IBB", h3m_data.read(6))
(isName, ) = struct.unpack("<B", h3m_data.read(1))
if isName == 0x01:
(length, ) = struct.unpack("<I", h3m_data.read(4))
name = h3m_data.read(length)
(isExp, ) = struct.unpack("<B", h3m_data.read(1))
if isExp == 0x01:
(exp, ) = struct.unpack("<I", h3m_data.read(4))
(isPortrait, ) = struct.unpack("<B", h3m_data.read(1))
if isPortrait == 0x01:
(portrait, ) = struct.unpack("<B", h3m_data.read(1))
(isSecSkill, ) = struct.unpack("<B", h3m_data.read(1))
if isSecSkill == 0x01:
(skills_count, ) = struct.unpack("<I", h3m_data.read(4))
for i in xrange(skills_count):
(skill_id, ) = struct.unpack("<B", h3m_data.read(1))
(skill_lvl, ) = struct.unpack("<B", h3m_data.read(1))
(isCreature, ) = struct.unpack("<B", h3m_data.read(1))
if isCreature == 0x01:
for i in xrange(7):
(guard_id, ) = struct.unpack("<H", h3m_data.read(2))
(guard_count, ) = struct.unpack("<H", h3m_data.read(2))
(creaturesFormation, ) = struct.unpack("<B", h3m_data.read(1))
(isArtifact, ) = struct.unpack("<B", h3m_data.read(1))
if isArtifact == 0x01:
(headID, shouldersID, neckID, rightHandID, leftHandID,
trunkID, rightRingID, leftRingID, legsID, misc1ID, misc2ID,
misc3ID, misc4ID, machine1ID, machine2ID, machine3ID,
machine4ID, magicbook, misc5ID) \
= struct.unpack("<19H", h3m_data.read(38))
(knapsack_count, ) = struct.unpack("<H", h3m_data.read(2))
if knapsack_count > 0:
for i in xrange(knapsack_count):
(knapsackID, ) = struct.unpack("<H", h3m_data.read(2))
(zoneRadius, ) = struct.unpack("<B", h3m_data.read(1))
(isBiography, ) = struct.unpack("<B", h3m_data.read(1))
if isBiography == 0x01:
(length, ) = struct.unpack("<I", h3m_data.read(4))
biography = h3m_data.read(length)
(gender, ) = struct.unpack("<B", h3m_data.read(1))
(isSpells, ) = struct.unpack("<B", h3m_data.read(1))
if isSpells == 0x01:
spells = struct.unpack("<9B", h3m_data.read(9))
(isPrimarySkills, ) = struct.unpack("<B", h3m_data.read(1))
if isPrimarySkills == 0x01:
(attack, defense, power, knowledge) = struct.unpack("<4B", h3m_data.read(4))
h3m_data.read(16) #unknown
elif map_data["objects"][object_id]["class"] in (17, 20, 42):
(owner, ) = struct.unpack("<I", h3m_data.read(4))
elif map_data["objects"][object_id]["class"] == 93:
(isText, ) = struct.unpack("<B", h3m_data.read(1))
if isText == 0x01:
(length, ) = struct.unpack("<I", h3m_data.read(4))
text = h3m_data.read(length)
(isGuards, ) = struct.unpack("<B", h3m_data.read(1))
if isGuards == 0x01:
for i in xrange(7):
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
h3m_data.read(4) #junk
(spell_id, ) = struct.unpack("<I", h3m_data.read(4))
elif map_data["objects"][object_id]["class"] == 216:
(owner, ) = struct.unpack("<I", h3m_data.read(4))
(junk, ) = struct.unpack("<I", h3m_data.read(4))
if junk == 0x00:
(towns, ) = struct.unpack("<H", h3m_data.read(2))
(minlevel, maxlevel, ) = struct.unpack("<2B", h3m_data.read(2))
elif map_data["objects"][object_id]["class"] in (54, 71, 72, 73, 74, 75, 162, 163, 164):
(monster_id, ) = struct.unpack("<I", h3m_data.read(4))
(monster_count, ) = struct.unpack("<H", h3m_data.read(2))
(mood, ) = struct.unpack("<B", h3m_data.read(1))
(isTreasureOrText, ) = struct.unpack("<B", h3m_data.read(1))
if isTreasureOrText == 0x01:
(length, ) = struct.unpack("<I", h3m_data.read(4))
text = h3m_data.read(length)
(wood, mercury, ore, sulfur, crystal, gem, gold, artefactID) \
= struct.unpack("<7IH", h3m_data.read(30))
(mosterNeverRunAway, ) = struct.unpack("<B", h3m_data.read(1))
(monsterDontGrowUp, ) = struct.unpack("<B", h3m_data.read(1))
h3m_data.read(2) #junk
elif map_data["objects"][object_id]["class"] in (98, 77):
h3m_data.read(4) #junk
(owner, ) = struct.unpack("<B", h3m_data.read(1))
(isName, ) = struct.unpack("<B", h3m_data.read(1))
if isName == 0x01:
(length, ) = struct.unpack("<I", h3m_data.read(4))
name = h3m_data.read(length)
(isGuard, ) = struct.unpack("<B", h3m_data.read(1))
if isGuard == 0x01:
for i in xrange(7):
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
(formation, ) = struct.unpack("<B", h3m_data.read(1))
(isBuildings, ) = struct.unpack("<B", h3m_data.read(1))
if isBuildings == 0x01:
build = struct.unpack("6B", h3m_data.read(6))
active = struct.unpack("6B", h3m_data.read(6))
else:
(isFort, ) = struct.unpack("<B", h3m_data.read(1))
mustSpells = struct.unpack("<9B", h3m_data.read(9))
canSpells = struct.unpack("<9B", h3m_data.read(9))
(eventQuantity, ) = struct.unpack("<I", h3m_data.read(4))
if eventQuantity > 0:
for i in xrange(eventQuantity):
(length, ) = struct.unpack("<I", h3m_data.read(4))
event_name = h3m_data.read(length)
(length, ) = struct.unpack("<I", h3m_data.read(4))
event_text = h3m_data.read(length)
(wood, mercury, ore, sulfur, crystal, gem, gold,
players_affected, human_affected, ai_affected,
day_of_first_event, event_iteration) \
= struct.unpack("<7I3B2H", h3m_data.read(35))
h3m_data.read(16) #junk
buildings = struct.unpack("<6B", h3m_data.read(6))
creatures = struct.unpack("<7H", h3m_data.read(14))
h3m_data.read(4) #junk
h3m_data.read(4) #junk
elif map_data["objects"][object_id]["class"] in (5, 65, 66, 67, 68, 69):
(isText, ) = struct.unpack("<B", h3m_data.read(1))
if isText == 0x01:
(length, ) = struct.unpack("<I", h3m_data.read(4))
text = h3m_data.read(length)
(isGuards, ) = struct.unpack("<B", h3m_data.read(1))
if isGuards == 0x01:
for i in xrange(7):
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
h3m_data.read(4) #junk
elif map_data["objects"][object_id]["class"] in (33, 219):
(color, ) = struct.unpack("<I", h3m_data.read(4))
for i in xrange(7):
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
(undeleteSoldiers, ) = struct.unpack("<B", h3m_data.read(1))
h3m_data.read(8)
elif map_data["objects"][object_id]["class"] == 87:
(owner, ) = struct.unpack("<I", h3m_data.read(4))
elif map_data["objects"][object_id]["class"] == 83:
(quest, ) = struct.unpack("<B", h3m_data.read(1))
if quest == 0x00:
pass
elif quest == 0x01:
(level, ) = struct.unpack("<I", h3m_data.read(4))
elif quest == 0x02:
(offence, defence, power, knowledge) = struct.unpack("4B", h3m_data.read(4))
elif quest == 0x03:
(hero_id, ) = struct.unpack("<I", h3m_data.read(4))
elif quest == 0x04:
(monster_id, ) = struct.unpack("<I", h3m_data.read(4))
elif quest == 0x05:
(art_quantity, ) = struct.unpack("<B", h3m_data.read(1))
for i in xrange(art_quantity):
(art, ) = struct.unpack("<H", h3m_data.read(2))
elif quest == 0x06:
(creatures_quantity, ) = struct.unpack("<B", h3m_data.read(1))
for i in xrange(creatures_quantity):
(guard_id, ) = struct.unpack("<H", h3m_data.read(2))
(guard_count, ) = struct.unpack("<H", h3m_data.read(2))
elif quest == 0x07:
resources = struct.unpack("7I", h3m_data.read(28))
elif quest == 0x08:
(hero_id, ) = struct.unpack("<B", h3m_data.read(1))
elif quest == 0x09:
(player, ) = struct.unpack("<B", h3m_data.read(1))
else:
raise NotImplementedError
(time_limit, ) = struct.unpack("<I", h3m_data.read(4))
(length, ) = struct.unpack("<I", h3m_data.read(4))
quest_begin = h3m_data.read(length)
(length, ) = struct.unpack("<I", h3m_data.read(4))
quest_running = h3m_data.read(length)
(length, ) = struct.unpack("<I", h3m_data.read(4))
quest_end = h3m_data.read(length)
(reward, ) = struct.unpack("<B", h3m_data.read(1))
if reward == 0x00:
pass
elif reward == 0x01:
(exp, ) = struct.unpack("<I", h3m_data.read(4))
elif reward == 0x02:
(spell_points, ) = struct.unpack("<I", h3m_data.read(4))
elif reward == 0x03:
(morale, ) = struct.unpack("<B", h3m_data.read(1))
elif reward == 0x04:
(lucky, ) = struct.unpack("<B", h3m_data.read(1))
elif reward == 0x05:
(resID, ) = struct.unpack("<B", h3m_data.read(1))
(res_quantity, ) = struct.unpack("<I", h3m_data.read(4))
elif reward == 0x06:
(priSkillID, ) = struct.unpack("<B", h3m_data.read(1))
(priSkillBonus, ) = struct.unpack("<B", h3m_data.read(1))
elif reward == 0x07:
(secSkillID, ) = struct.unpack("<B", h3m_data.read(1))
(secSkillBonus, ) = struct.unpack("<B", h3m_data.read(1))
elif reward == 0x08:
(artID, ) = struct.unpack("<H", h3m_data.read(2))
elif reward == 0x09:
(spellID, ) = struct.unpack("<B", h3m_data.read(1))
elif reward == 0x0A:
(creatureID, ) = struct.unpack("<H", h3m_data.read(2))
(creatureQuantity, ) = struct.unpack("<H", h3m_data.read(2))
else:
raise NotImplementedError
h3m_data.read(2) #junk
elif map_data["objects"][object_id]["class"] in (91, 59):
(length, ) = struct.unpack("<I", h3m_data.read(4))
text = h3m_data.read(length)
h3m_data.read(4) #junk
elif map_data["objects"][object_id]["class"] == 113:
(secSkills, ) = struct.unpack("<I", h3m_data.read(4))
elif map_data["objects"][object_id]["class"] in (88, 89, 90):
(spellID, ) = struct.unpack("<I", h3m_data.read(4))
elif map_data["objects"][object_id]["class"] == 215:
(quest, ) = struct.unpack("<B", h3m_data.read(1))
if quest == 0x00:
pass
elif quest == 0x01:
(level, ) = struct.unpack("<I", h3m_data.read(4))
elif quest == 0x02:
(offence, defence, power, knowledge) = struct.unpack("4B", h3m_data.read(4))
elif quest == 0x03:
(hero_id, ) = struct.unpack("<I", h3m_data.read(4))
elif quest == 0x04:
(monster_id, ) = struct.unpack("<I", h3m_data.read(4))
elif quest == 0x05:
(art_quantity, ) = struct.unpack("<B", h3m_data.read(1))
for i in xrange(art_quantity):
(art, ) = struct.unpack("<H", h3m_data.read(2))
elif quest == 0x06:
(creatures_quantity, ) = struct.unpack("<B", h3m_data.read(1))
for i in xrange(creatures_quantity):
(guard_id, ) = struct.unpack("<H", h3m_data.read(2))
(guard_count, ) = struct.unpack("<H", h3m_data.read(2))
elif quest == 0x07:
resources = struct.unpack("7I", h3m_data.read(28))
elif quest == 0x08:
(hero_id, ) = struct.unpack("<B", h3m_data.read(1))
elif quest == 0x09:
(player, ) = struct.unpack("<B", h3m_data.read(1))
else:
raise NotImplementedError
(time_limit, ) = struct.unpack("<I", h3m_data.read(4))
(length, ) = struct.unpack("<I", h3m_data.read(4))
quest_begin = h3m_data.read(length)
(length, ) = struct.unpack("<I", h3m_data.read(4))
quest_running = h3m_data.read(length)
(length, ) = struct.unpack("<I", h3m_data.read(4))
quest_end = h3m_data.read(length)
elif map_data["objects"][object_id]["class"] == 36:
(radius, ) = struct.unpack("<B", h3m_data.read(1))
h3m_data.read(3) #junk
elif map_data["objects"][object_id]["class"] == 220:
(resources, ) = struct.unpack("<B", h3m_data.read(1))
h3m_data.read(3) #junk
elif map_data["objects"][object_id]["class"] == 217:
(owner, towns) = struct.unpack("<II", h3m_data.read(8))
if towns==0x00:
(towns,) = struct.unpack("<H", h3m_data.read(2))
elif map_data["objects"][object_id]["class"] == 218:
(owner, minlvl, maxlvl) = struct.unpack("<IBB", h3m_data.read(6))
elif map_data["objects"][object_id]["class"] == 81:
(bonus_type, primaryID) = struct.unpack("<BI", h3m_data.read(5))
h3m_data.read(3) #junk
elif map_data["objects"][object_id]["class"] == 6:
(isText, ) = struct.unpack("<B", h3m_data.read(1))
if isText == 0x01:
(length, ) = struct.unpack("<I", h3m_data.read(4))
text = h3m_data.read(length)
(isGuards, ) = struct.unpack("<B", h3m_data.read(1))
if isGuards == 0x01:
for i in xrange(7):
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
h3m_data.read(4) #junk
(exp, spell_points, morals, luck, wood, mercury, ore, sulfur,
crystal, gem, gold, offence, defence, power, knowledge) = \
struct.unpack("<IIBBIIIIIIIBBBB", h3m_data.read(42))
(secSkills, ) = struct.unpack("<B", h3m_data.read(1))
if secSkills > 0:
for i in xrange(secSkills):
(skill_id, skill_lvl) = struct.unpack("<BB", h3m_data.read(2))
(artefacts, ) = struct.unpack("<B", h3m_data.read(1))
if artefacts > 0:
for i in xrange(artefacts):
(artID, ) = struct.unpack("<H", h3m_data.read(2))
(spells, ) = struct.unpack("<B", h3m_data.read(1))
if spells > 0:
for i in xrange(spells):
(spellID, ) = struct.unpack("<B", h3m_data.read(1))
(monsters, ) = struct.unpack("<B", h3m_data.read(1))
if monsters > 0:
for i in xrange(monsters):
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
h3m_data.read(8) #junk
elif map_data["objects"][object_id]["class"] == 26:
(isText, ) = struct.unpack("<B", h3m_data.read(1))
if isText == 0x01:
(length, ) = struct.unpack("<I", h3m_data.read(4))
text = h3m_data.read(length)
(isGuards, ) = struct.unpack("<B", h3m_data.read(1))
if isGuards == 0x01:
for i in xrange(7):
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
h3m_data.read(4) #junk
(exp, spell_points, morals, luck, wood, mercury, ore, sulfur,
crystal, gem, gold, offence, defence, power, knowledge) = \
struct.unpack("<IIBBIIIIIIIBBBB", h3m_data.read(42))
(secSkills, ) = struct.unpack("<B", h3m_data.read(1))
if secSkills > 0:
for i in xrange(secSkills):
(skill_id, skill_lvl) = struct.unpack("<BB", h3m_data.read(2))
(artefacts, ) = struct.unpack("<B", h3m_data.read(1))
if artefacts > 0:
for i in xrange(artefacts):
(artID, ) = struct.unpack("<H", h3m_data.read(2))
(spells, ) = struct.unpack("<B", h3m_data.read(1))
if spells > 0:
for i in xrange(spells):
(spellID, ) = struct.unpack("<B", h3m_data.read(1))
(monsters, ) = struct.unpack("<B", h3m_data.read(1))
if monsters > 0:
for i in xrange(monsters):
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
h3m_data.read(8) #junk
(players, isAICan, disableAfterFirstDay) = struct.unpack("<BBB", h3m_data.read(3))
h3m_data.read(4) #junk
try:
(gevents_count, ) = struct.unpack("<I", h3m_data.read(4))
for i in xrange(gevents_count):
(length, ) = struct.unpack("<I", h3m_data.read(4))
name = h3m_data.read(length)
(length, ) = struct.unpack("<I", h3m_data.read(4))
text = h3m_data.read(length)
h3m_data.read(7*4) #resources
(players_affected, ) = struct.unpack("<B", h3m_data.read(1))
(human_affected, ) = struct.unpack("<B", h3m_data.read(1))
(ai_affected, ) = struct.unpack("<B", h3m_data.read(1))
(day_of_first_event,) = struct.unpack("<H", h3m_data.read(2))
(event_iteration,) = struct.unpack("<H", h3m_data.read(2))
h3m_data.read(16) #junk
except:
print "d'ough...'"
h3m_data.read(124) #junk
return map_data

@ -0,0 +1,38 @@
#!/usr/bin/env python
"""
heroes renaissance
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pyglet
IF_BOTTOM = 48
IF_RIGHT = 200
IF_TOP = IF_LEFT = 8
class Interface(object):
def __init__(self, window):
self.window = window
def on_mouse_motion(self, x, y, dx, dy):
if IF_LEFT < x < (self.window.width-IF_RIGHT):
pass
else:
return pyglet.event.EVENT_HANDLED
if IF_BOTTOM < y < (self.window.height-IF_TOP):
pass
else:
return pyglet.event.EVENT_HANDLED

@ -0,0 +1,382 @@
#!/usr/bin/env python
"""
heroes renaissance
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pyglet
from ctypes import create_string_buffer, memmove
from lib import h3m
import os
class OrderedTextureGroup(pyglet.graphics.Group):
def __init__(self, order, texture, parent=None):
super(OrderedTextureGroup, self).__init__(parent)
self.texture = texture
self.order = order
def set_state(self):
pyglet.gl.glEnable(self.texture.target)
pyglet.gl.glBindTexture(self.texture.target, self.texture.id)
def unset_state(self):
pyglet.gl.glDisable(self.texture.target)
def __hash__(self):
return hash((self.order, self.texture.target, self.texture.id,
self.parent))
def __eq__(self, other):
return (self.__class__ is other.__class__ and
self.order == other.order and
self.texture.target == other.texture.target and
self.texture.id == other.texture.id and
self.parent == self.parent)
def __repr__(self):
return '%s(id=%d)' % (self.__class__.__name__, self.order,
self.texture.id)
def __cmp__(self, other):
if isinstance(other, OrderedTextureGroup):
return cmp(self.order, other.order)
return -1
class Animation(object):
def __init__(self, tex_region, frames, flip_x=False, flip_y=False):
self.texgroup = tex_region.group
if flip_x or flip_y:
self.tex = tex_region.get_transform(flip_x=flip_x, flip_y=flip_y)
else:
self.tex = tex_region
self.__frames = []
for img in frames:
data_pitch = abs(img._current_pitch)
buf = create_string_buffer(len(img._current_data))
memmove(buf, img._current_data, len(img._current_data))
data = buf.raw
rows = [data[i:i + abs(data_pitch)] for i in
xrange(len(img._current_data)-abs(data_pitch),
-1, -abs(data_pitch))]
self.__frames.append(''.join(rows))
self.__animation = 0
self.width = self.tex.width
self.height = self.tex.height
self.__hash = hash(self.__frames[0])
def next_frame(self):
self.__animation = (self.__animation + 1) % len(self.__frames)
return self.__frames[self.__animation]
@property
def tex_coords(self):
return self.tex.tex_coords
@property
def group(self):
return self.texgroup
def __hash__(self):
return self.__hash
def __eq__(self, other):
return self.__hash == other.__hash
class MapSet(object):
def load_map_object(self, file, order=0):
image = pyglet.image.load(None, file=pyglet.resource.file(file))
try:
texture_region = self.current_atlas.add(image)
except pyglet.image.atlas.AllocatorException:
self.current_atlas = pyglet.image.atlas.TextureAtlas(1024, 1024)
texture_region = self.current_atlas.add(image)
group = OrderedTextureGroup(order, self.current_atlas.texture)
if group not in self.groups:
self.groups.append(group)
texture_region.group = self.groups.index(group)
return texture_region
def __init__(self, map_name):
h3m_data = h3m.extract(os.path.join(pyglet.resource._default_loader._script_home,"maps","%s.h3m" % map_name))
edge_map = [[] for i in xrange(len(h3m_data["upper_terrain"])+16)]
for num in xrange(len(edge_map)):
if num < 7 or num > len(edge_map)-8:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(len(h3m_data["upper_terrain"][0])+18)])
elif num == 7:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 16, 0, 0, 0, 0, 0])
line.extend([[-1, 20+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m_data["upper_terrain"][0]))])
line.append([-1, 17, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
elif num == len(edge_map)-8:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 19, 0, 0, 0, 0, 0])
line.extend([[-1, 28+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m_data["upper_terrain"][0]))])
line.append([-1, 18, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
else:
line = []
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
line.append([-1, 32+num%4, 0, 0, 0, 0, 0])
line.extend(h3m_data["upper_terrain"][num-8])
line.append([-1, 24+num%4, 0, 0, 0, 0, 0])
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
edge_map[num] = line
h3m_data["upper_terrain"] = edge_map
self.width = len(h3m_data["upper_terrain"][0])
self.height = len(h3m_data["upper_terrain"])
self.current_atlas = pyglet.image.atlas.TextureAtlas(1024, 1024)
self.groups = []
self.__tiles = {}
tile_textures = {}
for y, line in enumerate(h3m_data["upper_terrain"]):
for x, tile in enumerate(line):
if tile[0] == -1: #edge
if "edg" not in tile_textures.keys():
tile_textures["edg"] = [self.load_map_object('data/advmap_tiles/edg.def/%d.png'%i, 100) for i in xrange(36)]
self.__tiles[x,y] = [tile_textures["edg"][tile[1]]]
elif tile[0] == 0: #dirt
if "dirttl" not in tile_textures.keys():
tile_textures["dirttl"] = [self.load_map_object('data/advmap_tiles/dirttl.def/%d.png'%i, 0) for i in xrange(46)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["dirttl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["dirttl"][tile[1]].group
self.__tiles[x,y] = [new]
else:
self.__tiles[x,y] = [tile_textures["dirttl"][tile[1]]]
elif tile[0] == 1: #sand
if "sandtl" not in tile_textures.keys():
tile_textures["sandtl"] = [self.load_map_object('data/advmap_tiles/sandtl.def/%d.png'%i, 0) for i in xrange(24)]
self.__tiles[x,y] = [tile_textures["sandtl"][tile[1]]]
elif tile[0] == 2: #grass
if "grastl" not in tile_textures.keys():
tile_textures["grastl"] = [self.load_map_object('data/advmap_tiles/grastl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["grastl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["grastl"][tile[1]].group
self.__tiles[x,y] = [new]
else:
self.__tiles[x,y] = [tile_textures["grastl"][tile[1]]]
elif tile[0] == 3: #snow
if "snowtl" not in tile_textures.keys():
tile_textures["snowtl"] = [self.load_map_object('data/advmap_tiles/snowtl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["snowtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["snowtl"][tile[1]].group
self.__tiles[x,y] = [new]
else:
self.__tiles[x,y] = [tile_textures["snowtl"][tile[1]]]
elif tile[0] == 4: #swamp
if "swmptl" not in tile_textures.keys():
tile_textures["swmptl"] = [self.load_map_object('data/advmap_tiles/swmptl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["swmptl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["swmptl"][tile[1]].group
self.__tiles[x,y] = [new]
else:
self.__tiles[x,y] = [tile_textures["swmptl"][tile[1]]]
elif tile[0] == 5: #rough
if "rougtl" not in tile_textures.keys():
tile_textures["rougtl"] = [self.load_map_object('data/advmap_tiles/rougtl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["rougtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["rougtl"][tile[1]].group
self.__tiles[x,y] = [new]
else:
self.__tiles[x,y] = [tile_textures["rougtl"][tile[1]]]
elif tile[0] == 7: #lava
if "lavatl" not in tile_textures.keys():
tile_textures["lavatl"] = [self.load_map_object('data/advmap_tiles/lavatl.def/%d.png'%i, 0) for i in xrange(79)]
flip_x = bool(tile[6] & 1)
flip_y = bool(tile[6] & 2)
if flip_x or flip_y:
new = tile_textures["lavatl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["lavatl"][tile[1]].group
self.__tiles[x,y] = [new]
else:
self.__tiles[x,y] = [tile_textures["lavatl"][tile[1]]]
elif tile[0] == 8: #water 12 anims
if "watrtl" not in tile_textures.keys():
textures = [self.load_map_object('data/advmap_tiles/watrtl.def/%d/0.png'%i, 0) for i in xrange(33)]
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/advmap_tiles/watrtl.def/%d/%d.png'%(i,j))) for j in xrange(12)] for i in xrange(33)]
tile_textures["watrtl"] = {
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
}
flip_x = (tile[6]>>0)&1
flip_y = (tile[6]>>1)&1
self.__tiles[x,y] = [tile_textures["watrtl"][flip_x, flip_y][tile[1]]]
elif tile[0] == 9: #rock
if "rocktl" not in tile_textures.keys():
tile_textures["rocktl"] = [self.load_map_object('data/advmap_tiles/rocktl.def/%d.png'%i, 0) for i in xrange(48)]
self.__tiles[x,y] = [tile_textures["rocktl"][tile[1]]]
else:
raise NotImplementedError
if tile[2] == 0: #no river
pass
elif tile[2] == 1: #clrrvr 12 anims
if "clrrvr" not in tile_textures.keys():
textures = [self.load_map_object('data/advmap_tiles/clrrvr.def/%d/0.png'%i, 1) for i in xrange(13)]
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/advmap_tiles/clrrvr.def/%d/%d.png'%(i,j))) for j in xrange(12)] for i in xrange(13)]
tile_textures["clrrvr"] = {
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
}
flip_x = (tile[6]>>2)&1
flip_y = (tile[6]>>3)&1
self.__tiles[x,y].append(tile_textures["clrrvr"][flip_x, flip_y][tile[3]])
elif tile[2] == 2: #icyrvr
if "icyrvr" not in tile_textures.keys():
tile_textures["icyrvr"] = [self.load_map_object('data/advmap_tiles/icyrvr.def/%d.png'%i, 1) for i in xrange(13)]
flip_x = bool(tile[6] & 4)
flip_y = bool(tile[6] & 8)
if flip_x or flip_y:
new = tile_textures["icyrvr"][tile[3]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["icyrvr"][tile[3]].group
self.__tiles[x, y].append(new)
else:
self.__tiles[x, y].append(tile_textures["icyrvr"][tile[3]])
elif tile[2] == 3: #mudrvr
if "mudrvr" not in tile_textures.keys():
textures = [self.load_map_object('data/advmap_tiles/mudrvr.def/%d/0.png'%i, 1) for i in xrange(13)]
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/advmap_tiles/clrrvr.def/%d/%d.png'%(i,j))) for j in xrange(12)] for i in xrange(13)]
tile_textures["mudrvr"] = {
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
}
flip_x = (tile[6]>>2)&1
flip_y = (tile[6]>>3)&1
self.__tiles[x,y].append(tile_textures["mudrvr"][flip_x, flip_y][tile[3]])
elif tile[2] == 4: #lavrvr
if "lavrvr" not in tile_textures.keys():
textures = [self.load_map_object('data/advmap_tiles/lavrvr.def/%d/0.png'%i, 1) for i in xrange(13)]
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/advmap_tiles/clrrvr.def/%d/%d.png'%(i,j))) for j in xrange(9)] for i in xrange(13)]
tile_textures["lavrvr"] = {
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
}
flip_x = (tile[6]>>2)&1
flip_y = (tile[6]>>3)&1
self.__tiles[x,y].append(tile_textures["lavrvr"][flip_x, flip_y][tile[3]])
else:
raise NotImplementedError, tile[2]
if tile[4] == 0: #no road
pass
elif tile[4] == 1: #dirtrd
if "dirtrd" not in tile_textures.keys():
tile_textures["dirtrd"] = [self.load_map_object('data/advmap_tiles/dirtrd.def/%d.png'%i, 1) for i in xrange(17)]
flip_x = bool(tile[6] & 16)
flip_y = bool(tile[6] & 32)
if flip_x or flip_y:
new = tile_textures["dirtrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["dirtrd"][tile[5]].group
self.__tiles[x, y].append(new)
else:
self.__tiles[x, y].append(tile_textures["dirtrd"][tile[5]])
elif tile[4] == 2: #gravrd
if "gravrd" not in tile_textures.keys():
tile_textures["gravrd"] = [self.load_map_object('data/advmap_tiles/gravrd.def/%d.png'%i, 1) for i in xrange(17)]
flip_x = bool(tile[6] & 16)
flip_y = bool(tile[6] & 32)
if flip_x or flip_y:
new = tile_textures["gravrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["gravrd"][tile[5]].group
self.__tiles[x, y].append(new)
else:
self.__tiles[x, y].append(tile_textures["gravrd"][tile[5]])
elif tile[4] == 3: #cobbrd
if "cobbrd" not in tile_textures.keys():
tile_textures["cobbrd"] = [self.load_map_object('data/advmap_tiles/cobbrd.def/%d.png'%i, 1) for i in xrange(17)]
flip_x = bool(tile[6] & 16)
flip_y = bool(tile[6] & 32)
if flip_x or flip_y:
new = tile_textures["cobbrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
new.group = tile_textures["cobbrd"][tile[5]].group
self.__tiles[x, y].append(new)
else:
self.__tiles[x, y].append(tile_textures["cobbrd"][tile[5]])
else:
raise NotImplementedError, tile[4]
images = []
for order, obj in enumerate(h3m_data["objects"]):
imgs = []
i = 0
while 1:
imgs.append(pyglet.image.load(None, file=pyglet.resource.file("data/advmap_objects/" + obj["filename"] + "/%d.png"%i)))
i += 1
if "data/advmap_objects/" + obj["filename"] + "/%d.png" % i not in pyglet.resource._default_loader._index.keys():
break;
images.append((imgs, order))
self.objects = []
for imgs in sorted(images, key=lambda i:i[0][0].height, reverse=True):
try:
texture = self.current_atlas.add(imgs[0][0])
except pyglet.image.atlas.AllocatorException:
self.current_atlas = pyglet.image.atlas.TextureAtlas(1024, 1024)
texture = self.current_atlas.add(imgs[0][0])
group = OrderedTextureGroup(2, self.current_atlas.texture)
if group not in self.groups:
self.groups.append(group)
group = self.groups.index(group)
texture.group = group
self.objects.append((Animation(texture, imgs[0]), imgs[1]))
self.objects = [i[0] for i in sorted(self.objects, key=lambda i:i[1])]
self.tunedobj = {}
for obj in [i for i in h3m_data["tunedobj"] if i["z"]==0]:
self.__tiles[obj["x"] + 9,obj["y"] + 8].append(self.objects[obj["id"]])
def get_tiles(self, tiles_x, tiles_y, div_x, div_y):
for y in xrange(tiles_y - 1, -6, -1):
y1 = y * 32
for x in xrange(tiles_x + 5 - 1, -1, -1):
for obj in self.__tiles.get((x - div_x, div_y - y), []):
x1 = x * 32 - obj.width + 32
x2 = x1 + obj.width
y2 = y1 + obj.height
yield obj, [x1, y1, x2, y1, x2, y2, x1, y2]

@ -0,0 +1,335 @@
#!/usr/bin/env python
"""
heroes renaissance
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pyglet
from lib.interface import *
from lib.mapset import *
class MapView(object):
def __init__(self, mapset, window):
self.window = window
self.mapset = mapset
self._first_time_init()
self._init_view()
# mouse position
self.label = pyglet.text.Label('',
font_name="",
font_size=36,
bold=True,
color=(128, 128, 128, 128),
x=self.window.width - 10, y=0,
anchor_x='right', anchor_y='bottom')
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
pyglet.clock.schedule_interval(self.update, 1/60.0)
def _first_time_init(self):
self.tile_size = 32
# size of the viewport
self.vp_width = self.window.width-IF_RIGHT-IF_LEFT
self.vp_height = self.window.height-IF_BOTTOM-IF_TOP
# center map
self.x = (self.mapset.width * self.tile_size - self.vp_width +
self.tile_size) // 2
self.y = (self.mapset.height * self.tile_size - self.vp_height +
self.tile_size) // 2
self.mouse_x = self.mouse_dx = 0
self.mouse_y = self.mouse_dy = 0
def _init_view(self):
# initiate new batch
self.batch = pyglet.graphics.Batch()
# initiate new vertex list
self.vl_objects = [None for value in self.mapset.groups]
# size of the viewport
self.vp_width = self.window.width - IF_RIGHT - IF_LEFT
self.vp_height = self.window.height - IF_BOTTOM - IF_TOP
# center map when viewport is too large, else check if map still fills
# whole viewport and if not adjust position accordingly
self.center_x = False
if self.mapset.width * self.tile_size < self.vp_width:
# center the map in x direction
self.center_x = True
self.x = (self.mapset.width * self.tile_size - self.vp_width) // 2
elif self.x > self.tile_size * self.mapset.width - self.vp_width:
# move map back to the right
self.x = self.tile_size * self.mapset.width - self.vp_width
elif self.x < 0:
# move map to the left
self.x = 0
self.center_y = False
if self.mapset.height * self.tile_size < self.vp_height:
# center the map in y direction
self.center_y = True
self.y = (self.mapset.height * self.tile_size -
self.vp_height) // 2
elif self.y > self.tile_size * self.mapset.height - self.vp_height:
# move map up
self.y = self.tile_size * self.mapset.height - self.vp_height
elif self.y < 0:
# move map down
self.y = 0
# tiles to be drawn with the current viewport size
self.tiles_x = min((self.vp_width // self.tile_size) + 2,
self.mapset.width)
self.tiles_y = min((self.vp_height // self.tile_size) + 2,
self.mapset.height)
# undrawn map size in pixels
self.undrawn_x = self.tile_size * (self.mapset.width - self.tiles_x)
self.undrawn_y = self.tile_size * (self.mapset.height - self.tiles_y)
# reset mouse or keyboard movement
self.dx = 0
self.dy = 0
# calculate modulo pixel position of the map
if self.x - self.tile_size > self.undrawn_x:
# dont go right beyond map borders
mod_x = self.tile_size - self.x + self.undrawn_x
elif self.x > 0:
# calculate modulo of current position and tile_size
mod_x = (self.tile_size - self.x) % self.tile_size
else:
# dont go left beyond map borders
mod_x = self.tile_size - self.x
if self.y - self.tile_size > self.undrawn_y:
# dont go up beyond map borders
mod_y = self.tile_size - self.y + self.undrawn_y
elif self.y > 0:
# calculate modulo of current position and tile_size
mod_y = (self.tile_size - self.y) % self.tile_size
else:
# dont go down beyond map borders
mod_y = self.tile_size - self.y
# calculate tile position of the map, turn y coordinates upside down
self.div_x = (self.tile_size - self.x - mod_x) // self.tile_size
self.div_y = (self.tile_size - self.y - mod_y) // self.tile_size + \
self.mapset.height - 1
# update vertex lists with the gathered information
self.update_vertex_lists()
# update current current position that is to be glTranslated
# XXX: dont ask me why i have to add 1/4 and 3/2 but when i do not
# there are black borders when zooming out
# plz explain wtf is going on there
self.view_x = mod_x - self.tile_size - (self.tile_size - 32) // 4
self.view_y = mod_y - self.tile_size - ((self.tile_size - 32) * 3) // 2
def on_draw(self):
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
pyglet.gl.glPushMatrix()
pyglet.gl.glTranslatef(self.view_x+IF_LEFT, self.view_y+IF_BOTTOM, 0)
pyglet.gl.glScalef(self.tile_size/32.0, self.tile_size/32.0, 0.0)
self.batch.draw()
pyglet.gl.glPopMatrix()
pyglet.gl.glLoadIdentity()
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glColor4f(1, 0, 1, 1)
pyglet.gl.glRectf(0, 0, self.window.width, IF_BOTTOM)
pyglet.gl.glRectf(self.window.width-IF_RIGHT, 0, self.window.width, self.window.height)
pyglet.gl.glRectf(0, self.window.height-IF_TOP, self.window.width, self.window.height)
pyglet.gl.glRectf(0, 0, IF_LEFT, self.window.height)
self.label.draw()
def _move(self, dx, dy):
# new map position
new_x = self.x - dx
new_y = self.y - dy
# only update textures and vertices when necessary
retex = False
# if x or y jump is too big, adjust new position accordingly
if new_x < 0:
# move map to the left
new_x = 0
retex = True
if new_x > self.tile_size * self.mapset.width - self.vp_width:
# move map to the right
new_x = self.tile_size * self.mapset.width - self.vp_width
retex = True
if new_y < 0:
# move map down
new_y = 0
retex = True
if new_y > self.tile_size * self.mapset.height - self.vp_height:
# move map up
new_y = self.tile_size * self.mapset.height - self.vp_height
retex = True
# find out how many steps and pixels we have to move and wether we have
# to retex
if new_x - self.tile_size > self.undrawn_x:
# we are at the right border
mod_x = self.tile_size - new_x + self.undrawn_x
# only retex if the last position was not at the border
if self.x - self.tile_size <= self.undrawn_x:
retex = True
elif new_x > 0:
# normal movement: calculate the amount of steps and the modulo
div_x, mod_x = divmod(self.tile_size - new_x, self.tile_size)
# only retex if the number of moved steps is not equal to last
if div_x != (self.tile_size - self.x) // self.tile_size:
retex = True
else:
# we are at the left border
mod_x = self.tile_size - new_x
if new_y - self.tile_size > self.undrawn_y:
# we are at the top
mod_y = self.tile_size - new_y + self.undrawn_y
# only retex if the last position was not at the border
if self.y - self.tile_size <= self.undrawn_y:
retex = True
elif new_y > 0:
# normal movement: calculate the amount of steps and the modulo
div_y, mod_y = divmod(self.tile_size - new_y, self.tile_size)
# only retex if the number of moved steps is not equal to last
if div_y != (self.tile_size - self.y) // self.tile_size:
retex = True
else:
# we are at the bottom
mod_y = self.tile_size - new_y
# if we have to update vertices and textures
if retex:
# calculate the current position on the tilemap
self.div_x = (self.tile_size - new_x - mod_x) // \
self.tile_size
self.div_y = (self.tile_size - new_y - mod_y) // \
self.tile_size + self.mapset.height - 1
self.update_vertex_lists()
# update position if not centered
# XXX: dont ask me why i have to add 1/4 and 3/2 but when i do not
# there are black borders when zooming out
# plz explain wtf is going on there
if not self.center_x:
self.view_x = mod_x-self.tile_size-(self.tile_size-32)//4
self.x = new_x
if not self.center_y:
self.view_y = mod_y-self.tile_size-((self.tile_size-32)*3)//2
self.y = new_y
def update_vertex_lists(self):
# initiate lists of vertex lists, vertices, texture coords, vertices
# counts and map objects for each group
vertices = [[] for value in self.mapset.groups]
tex_coords = [[] for value in self.mapset.groups]
count = [0 for value in self.mapset.groups]
self.cur_objects = [[] for value in self.mapset.groups]
# for each tile in the viewport, update the list of the specific group
for obj, coords in self.mapset.get_tiles(self.tiles_x, self.tiles_y,
self.div_x, self.div_y):
tex_coords[obj.group].extend(obj.tex_coords)
vertices[obj.group].extend(coords)
count[obj.group]+=4
if isinstance(obj, Animation):
self.cur_objects[obj.group].append(obj)
for i, group in enumerate(self.mapset.groups):
if count[i] == 0:
if self.vl_objects[i] is None:
# let the vertex list be None
pass
else:
# there was a vertex list but now no more - delete it
self.vl_objects[i].delete()
self.vl_objects[i] = None
else:
if self.vl_objects[i] is None:
# there was no vertex list but ther now is one - create it
self.vl_objects[i] = self.batch.add(count[i],
pyglet.gl.GL_QUADS,
group,
('v2i', vertices[i]),
('t3f', tex_coords[i]),
('c4B', (255,255,255,255)*count[i]))
else:
# there already is a vertex list - resize and refill
self.vl_objects[i].resize(count[i])
self.vl_objects[i].tex_coords = tex_coords[i]
self.vl_objects[i].vertices = vertices[i]
self.vl_objects[i].colors = (255,255,255,255)*count[i]
# make object list unique
self.cur_objects[i] = list(set(self.cur_objects[i]))
def update(self, dt):
try:
if self.window.keys[pyglet.window.key.LCTRL] and \
any([self.window.keys[pyglet.window.key.UP],
self.window.keys[pyglet.window.key.DOWN],
self.window.keys[pyglet.window.key.LEFT],
self.window.keys[pyglet.window.key.RIGHT]]):
if self.window.keys[pyglet.window.key.LEFT]:
x = 1
elif self.window.keys[pyglet.window.key.RIGHT]:
x = -1
else:
x = 0
if self.window.keys[pyglet.window.key.UP]:
y = -1
elif self.window.keys[pyglet.window.key.DOWN]:
y = 1
else:
y = 0
self.dx += x*8
self.dy += y*8
elif self.window.keys[pyglet.window.key.PLUS] and \
self.tile_size < 32:
self.tile_size+=8
self._init_view()
elif self.window.keys[pyglet.window.key.MINUS] and \
self.tile_size > 16:
self.tile_size-=8
self._init_view()
except KeyError:
pass
if self.dx or self.dy:
self._move(self.dx, self.dy)
self.dx = 0
self.dy = 0
# mouse position:
if self.mouse_x != self.mouse_dx or self.mouse_y != self.mouse_dy:
self.mouse_x = self.mouse_dx
self.mouse_y = self.mouse_dy
x = (self.mouse_x-IF_LEFT-self.view_x
-(self.tile_size-32)//4)//self.tile_size
y = (self.mouse_y-IF_BOTTOM-self.view_y
-((self.tile_size-32)*3)//2)//self.tile_size
self.label.text = "%03d %03d"%(x-self.div_x, self.div_y-y)
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
self.dx += dx
self.dy += dy
self.mouse_dx = x
self.mouse_dy = y
return pyglet.event.EVENT_HANDLED
def on_mouse_motion(self, x, y, dx, dy):
self.mouse_dx = x
self.mouse_dy = y
return pyglet.event.EVENT_HANDLED
def on_resize(self, width, height):
self._init_view()
def animate_water(self, dt):
for i, group in enumerate(self.mapset.groups):
if len(self.cur_objects[i]) > 0:
pyglet.gl.glBindTexture(self.cur_objects[i][0].tex.target,
self.cur_objects[i][0].tex.id)
for obj in self.cur_objects[i]:
pyglet.gl.glTexSubImage2D(obj.tex.owner.target,
obj.tex.owner.level,
obj.tex.x, obj.tex.y,
obj.tex.width, obj.tex.height,
pyglet.gl.GL_RGBA, pyglet.gl.GL_UNSIGNED_BYTE,
obj.next_frame())

@ -0,0 +1,52 @@
#!/usr/bin/env python
"""
heroes renaissance
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pyglet
class Window(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(1280, 1024, resizable=True, vsync=False)
self.keys = pyglet.window.key.KeyStateHandler()
self.push_handlers(self.keys)
self.fps = pyglet.clock.ClockDisplay()
pyglet.clock.schedule(lambda dt: None)
def on_draw(self):
self.fps.draw()
def on_key_press(self, symbol, modifiers):
if symbol == pyglet.window.key.F11:
self.set_fullscreen(fullscreen=not self.fullscreen)
elif symbol == pyglet.window.key.P:
pyglet.image.get_buffer_manager().get_color_buffer().save(
'screenshot.png', encoder=PNGRGBEncoder())
class PNGRGBEncoder(pyglet.image.codecs.ImageEncoder):
def encode(self, image, file, filename):
import Image
image = image.get_image_data()
format = image.format
pitch = -(image.width * len(format))
pil_image = Image.fromstring(
format, (image.width, image.height), image.get_data(format, pitch))
try:
#.convert('P', palette=Image.WEB)
pil_image.convert("RGB").save(file)
except Exception, e:
raise ImageEncodeException(e)

@ -0,0 +1,65 @@
#!/usr/bin/env python
# An example setup.py that can be used to create both standalone Windows
# executables (requires py2exe) and Mac OS X applications (requires py2app).
#
# On Windows::
#
# python setup.py py2exe
#
# On Mac OS X::
#
# python setup.py py2app
#
from distutils.core import setup
import os
# The main entry point of the program
script_file = 'hr.py'
# Setup args that apply to all setups, including ordinary distutils.
setup_args = dict(
data_files=[]
)
# py2exe options
try:
import py2exe
setup_args.update(dict(
windows=[dict(
script=script_file,
icon_resources=[(1, 'assets/app.ico')],
)],
))
except ImportError:
pass
# py2app options
try:
import py2app
setup_args.update(dict(
app=[script_file],
options=dict(py2app=dict(
argv_emulation=True,
iconfile='assets/app.icns',
)),
))
except ImportError:
pass
setup(**setup_args)
"""
Metadata-Version: 1.0
Name: UNKNOWN
Version: 0.0.0
Summary: UNKNOWN
Home-page: UNKNOWN
Author: UNKNOWN
Author-email: UNKNOWN
License: UNKNOWN
Description: UNKNOWN
Platform: UNKNOWN
"""

BIN
test

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 B

@ -0,0 +1,55 @@
#!/usr/bin/env python
import pyglet
atlas1 = pyglet.image.atlas.TextureAtlas(1024, 1024)
atlas2 = pyglet.image.atlas.TextureAtlas(1024, 1024)
atlas3 = pyglet.image.atlas.TextureAtlas(1024, 1024)
texture_group1 = pyglet.graphics.TextureGroup(atlas1.texture)
texture_group2 = pyglet.graphics.TextureGroup(atlas2.texture)
texture_group3 = pyglet.graphics.TextureGroup(atlas3.texture)
tile1 = atlas1.add(pyglet.image.load(None, file=pyglet.resource.file('test.png')))
tile2 = atlas2.add(pyglet.image.load(None, file=pyglet.resource.file('test.png')))
tile3 = atlas3.add(pyglet.image.load(None, file=pyglet.resource.file('test.png')))
tile2.blit_into(pyglet.image.load(None, file=pyglet.resource.file('test2.png')), 0, 0, 0)
batch = pyglet.graphics.Batch()
vertex_list = []
window = pyglet.window.Window(800, 600, vsync=False)
fps = pyglet.clock.ClockDisplay()
@window.event
def on_draw():
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
batch.draw()
fps.draw()
pyglet.clock.schedule(lambda dt: None)
def add_one(dt):
vertex_list.append(batch.add(4, pyglet.gl.GL_QUADS, texture_group1,
('v2i', [0, 0, 32, 0, 32, 32, 0, 32]),
('t3f', tile1.tex_coords),
('c4B', (255,255,255,255)*4)))
def add_two(dt):
vertex_list.append(batch.add(4, pyglet.gl.GL_QUADS, texture_group2,
('v2i', [8, 8, 40, 8, 40, 40, 8, 40]),
('t3f', tile2.tex_coords),
('c4B', (255,255,255,255)*4)))
def add_three(dt):
vertex_list.append(batch.add(4, pyglet.gl.GL_QUADS, texture_group3,
('v2i', [16, 16, 48, 16, 48, 48, 16, 48]),
('t3f', tile3.tex_coords),
('c4B', (255,255,255,255)*4)))
pyglet.clock.schedule_once(add_one, 4.0)
pyglet.clock.schedule_once(add_two, 8.0)
pyglet.clock.schedule_once(add_three, 12.0)
pyglet.app.run()

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 B

@ -0,0 +1,272 @@
from __future__ import division
from random import randint, choice
from itertools import chain, repeat
from logging import getLogger
from pyglet import gl
from pyglet import clock
from pyglet.event import EventDispatcher
from pyglet.resource import Loader
from pyglet.image import ImageGrid, TextureGrid, Animation
from pyglet.sprite import Sprite
from pyglet.graphics import Batch, TextureGroup
LOGGER = getLogger("defence.tilemap")
TILE_LOADER = Loader(["graphics/tiles"])
class TileLayerGroup(TextureGroup):
def __init__(self, texture, translation=(0, 0), rotation=0):
super(TileLayerGroup, self).__init__(texture)
self.translation = translation
self.rotation = rotation
def set_state(self):
super(TileLayerGroup, self).set_state()
gl.glPushAttrib(gl.GL_COLOR_BUFFER_BIT)
gl.glEnable(gl.GL_BLEND)
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
x, y = self.translation
gl.glPushMatrix()
gl.glTranslatef(x, y, 0)
gl.glRotatef(self.rotation, 0, 0, 1)
#gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST)
#gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST)
#gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP)
#gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP)
#gl.glTexParameterfv(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_BORDER_COLOR, (1, 1, 1, 1))
def unset_state(self):
super(TileLayerGroup, self).unset_state()
gl.glPopMatrix()
gl.glPopAttrib()
def __eq__(self, other):
return (super(TileLayerGroup, self).__eq__(other)
and self.translation == other.translation
and self.rotation == other.rotation)
def __repr__(self):
return '%s(id=%d, transformation=%s, rotation=%d)' % (
self.__class__.__name__,
self.texture.id,
self.translation,
self.rotation)
class Animator(object):
def __init__(self, delay):
self.delay = delay
self.paused = False
self.tiles = set()
def animate(self, dt):
for tile in self.tiles:
pass
class Tileset(object):
def __init__(self, graphic, tilesize=16, framedelay=1):
rows, columns = graphic.height // tilesize, graphic.width // tilesize
grid = TextureGrid(ImageGrid(graphic, rows, columns))
self.texture = grid.texture
self.frames = rows
self.animated = self.frames > 1
self.framedelay = framedelay
self.subtiles = [grid[(0, x):(grid.rows, x+1)] for x in xrange(grid.columns)]
self.texcoords = [[frame.tex_coords for frame in subtile] for subtile in self.subtiles]
def __getitem__(self, index):
return self.subtiles[index]
class Tile(object):
def __init__(self, tileset, frame=0):
self.tileset = tileset
self.frame = frame
#self.subtiles = (2, 3, 0, 1)
self.subtiles = [randint(0, 3) for x in xrange(4)]
self.subtiles = [randint(12, 15) for x in xrange(4)]
def vertices(self, offset=(0, 0)):
"""x, y = offset
vertices = (
x, y, x+1, y, x+1, y+1, x, y+1,
x+1, y, x+2, y, x+2, y+1, x+1, y+1,
x, y+1, x+1, y+1, x+1, y+2, x, y+2,
x+1, y+1, x+2, y+1, x+2, y+2, x+1, y+2)"""
vertices = (
0, 0, 1, 0, 1, 1, 0, 1,
1, 0, 2, 0, 2, 1, 1, 1,
0, 1, 1, 1, 1, 2, 0, 2,
1, 1, 2, 1, 2, 2, 1, 2)
"""vertices = (
0, 0, 0, 1, 0, 3, 1, 1, 5, 0, 1, 0,
1, 0, 1, 2, 0, 5, 2, 1, 2, 1, 1, 4,
0, 1, 9, 1, 1, 0, 1, 2, 1, 0, 2, 5,
1, 1, 4, 2, 1, 3, 2, 2, 0, 1, 2, 1)
offset = list(offset)
offset.append(0)"""
return ((coord * 16) + offset[i%2] for i, coord in enumerate(vertices))
@property
def texcoords(self):
for subtile in self.subtiles:
for coord in self.tileset.texcoords[subtile][self.frame]:
yield coord
@property
def colours(self):
return repeat(255, 4*4*4)
tilesets = {
"#": Tileset(TILE_LOADER.image("grass.png")),
"~": Tileset(TILE_LOADER.image("water.png"))}
class TileLayer(EventDispatcher):
def __init__(self, tileset, tiles):
self.tileset = tileset
self._tiles = tiles
def __getitem__(self, coords):
x, y = coords
return self._tiles[y][x]
def __len__(self):
return len(list(self.tiles))
def animate(self, dt):
for tile in self.tiles:
tile.frame += 1# random.randint(0, 2)
if tile.frame >= tile.tileset.frames:
tile.frame = 0
self.dispatch_event("on_animate")
"""return
start = index*(3*4*4)
end = (index+1)*(3*4*4)
self.tempcoords[start:end]=tile.texcoords
#self.vlists[0].tex_coords[start:end]=tile.texcoords
self.vlists[0].tex_coords=self.tempcoords"""
@property
def tiles(self):
for row in self._tiles:
for tile in row:
if tile is not None:
yield tile
def coordtiles(self):
for y, row in enumerate(self.tilelayer):
for x, tile in enumerate(row):
yield (x, y), tile
TileLayer.register_event_type('on_animate')
class LayerView(object):
def __init__(self, mapview, tilelayer):
self.tilelayer = tilelayer
self.group = TileLayerGroup(self.tilelayer.tileset.texture)
self.mapview = mapview
self.vlist = None
def rotate(dt):
self.group.rotation += 0.5
self.tilelayer.push_handlers(self)
#clock.schedule_interval(rotate, 0.01)
def refresh(self):
if self.vlist is not None:
self.vlist.delete()
vertices = []
for y, row in enumerate(self.tilelayer._tiles):
for x, tile in enumerate(row):
if tile is not None:
vertices.extend(tile.vertices((x*32, y*32)))
texcoords = list(chain(*(tile.texcoords for tile in self.tilelayer.tiles)))
colours = list(chain(*(tile.colours for tile in self.tilelayer.tiles)))
self.vlist = self.mapview.batch.add(
len(self.tilelayer)*16, gl.GL_QUADS, self.group,
('v2i', vertices),
('t3f', texcoords),
('c4B', colours))
def on_animate(self):
def tex():
for tile in self.tilelayer.tiles:
for texcoord in tile.texcoords:
yield texcoord
self.vlist.tex_coords = list(tex())
class TileMap(object):
def __init__(self, layers):
self.layers = [
TileLayer(tilesets["#"], [[Tile(tilesets["#"]) for x in xrange(20)] for y in xrange(15)]),
TileLayer(tilesets["~"], [[choice((Tile(tilesets["~"]), None)) for x in xrange(20)] for y in xrange(15)])]
def animate(self, dt):
for layer in self.layers:
if layer.tileset.animated:
layer.animate(dt)
class MapView(object):
def __init__(self, tilemap):
self.tilemap = tilemap
self.batch = Batch()
self.layerviews = [LayerView(self, layer) for layer in tilemap.layers]
self.refresh()
def refresh(self):
for layerview in self.layerviews:
layerview.refresh()
def draw(self):
self.batch.draw()
def move(self, movement):
dx, dy = movement
for layerview in self.layerviews:
x, y = layerview.group.translation
layerview.group.translation = (x+dx, y+dy)
if __name__ == "__main__":
import pyglet
window = pyglet.window.Window(640, 480, "Defence", vsync=False)
tmap = TileMap(None)
view = MapView(tmap)
fps = pyglet.clock.ClockDisplay()
@window.event
def on_draw():
window.clear()
view.draw()
fps.draw()
@window.event
def on_mouse_drag(x, y, dx, dy, buttons, modifiers):
view.move((dx, dy))
pyglet.clock.schedule_interval(tmap.animate, 1/10.0)
pyglet.clock.schedule(lambda dt: None)
pyglet.app.run()
Loading…
Cancel
Save