]> git.lizzy.rs Git - dragonfireclient.git/blob - minetestmapper/minetestmapper2.py
Merge branch 'master' of https://github.com/erlehmann/minetest-delta.git into upstrea...
[dragonfireclient.git] / minetestmapper / minetestmapper2.py
1 #!/usr/bin/env python\r
2 # -*- coding: utf-8 -*-\r
3 \r
4 # Made by j0gge, modified by celeron55\r
5 \r
6 # This program is free software. It comes without any warranty, to\r
7 # the extent permitted by applicable law. You can redistribute it\r
8 # and/or modify it under the terms of the Do What The Fuck You Want\r
9 # To Public License, Version 2, as published by Sam Hocevar. See\r
10 # http://sam.zoy.org/wtfpl/COPYING for more details.\r
11 \r
12 # Requires Python Imaging Library: http://www.pythonware.com/products/pil/\r
13 \r
14 # Some speed-up: ...lol, actually it slows it down.\r
15 #import psyco ; psyco.full()\r
16 #from psyco.classes import *\r
17 \r
18 import zlib\r
19 import Image, ImageDraw\r
20 import os\r
21 import string\r
22 import time\r
23 \r
24 def hex_to_int(h):\r
25     i = int(h,16)\r
26     if(i > 2047):\r
27         i-=4096\r
28     return i\r
29 \r
30 def hex4_to_int(h):\r
31     i = int(h,16)\r
32     if(i > 32767):\r
33         i-=65536\r
34     return i\r
35 \r
36 def int_to_hex3(i):\r
37     if(i < 0):\r
38         return "%03X" % (i + 4096)\r
39     else:\r
40         return "%03X" % i\r
41 \r
42 def int_to_hex4(i):\r
43     if(i < 0):\r
44         return "%04X" % (i + 65536)\r
45     else:\r
46         return "%04X" % i\r
47 \r
48 def limit(i,l,h):\r
49     if(i>h):\r
50         i=h\r
51     if(i<l):\r
52         i=l\r
53     return i\r
54 \r
55 # Fix these!\r
56 path="../map/"\r
57 output="map.png"\r
58 \r
59 sector_xmin = -1000/16\r
60 sector_xmax = 1000/16\r
61 sector_zmin = -1000/16\r
62 sector_zmax = 1000/16\r
63 \r
64 # Load color information for the blocks.\r
65 colors = {}\r
66 f = file("colors.txt")\r
67 for line in f:\r
68     values = string.split(line)\r
69     colors[int(values[0])] = (int(values[1]), int(values[2]), int(values[3]))\r
70 f.close()\r
71 \r
72 xlist = []\r
73 zlist = []\r
74 \r
75 # List all sectors to memory and calculate the width and heigth of the resulting picture.\r
76 if os.path.exists(path + "sectors2"):\r
77     for filename in os.listdir(path + "sectors2"):\r
78         for filename2 in os.listdir(path + "sectors2/" + filename):\r
79             x = hex_to_int(filename)\r
80             z = hex_to_int(filename2)\r
81             if x < sector_xmin or x > sector_xmax:\r
82                 continue\r
83             if z < sector_zmin or z > sector_zmax:\r
84                 continue\r
85             xlist.append(x)\r
86             zlist.append(z)\r
87 \r
88 if os.path.exists(path + "sectors"):\r
89     for filename in os.listdir(path + "sectors"):\r
90         x = hex4_to_int(filename[:4])\r
91         z = hex4_to_int(filename[-4:])\r
92         if x < sector_xmin or x > sector_xmax:\r
93             continue\r
94         if z < sector_zmin or z > sector_zmax:\r
95             continue\r
96         xlist.append(x)\r
97         zlist.append(z)\r
98 \r
99 w = (max(xlist) - min(xlist)) * 16 + 16\r
100 h = (max(zlist) - min(zlist)) * 16 + 16\r
101 \r
102 print "w="+str(w)+" h="+str(h)\r
103 \r
104 im = Image.new("RGB", (w, h), "white")\r
105 impix = im.load()\r
106 \r
107 stuff={}\r
108 \r
109 starttime = time.time()\r
110 \r
111 # Go through all sectors.\r
112 for n in range(len(xlist)):\r
113     #if n > 500:\r
114     #   break\r
115     if n % 200 == 0:\r
116         nowtime = time.time()\r
117         dtime = nowtime - starttime\r
118         n_per_second = 1.0 * n / dtime\r
119         if n_per_second != 0:\r
120             seconds_per_n = 1.0 / n_per_second\r
121             time_guess = seconds_per_n * len(xlist)\r
122             remaining_s = time_guess - dtime\r
123             remaining_minutes = int(remaining_s / 60)\r
124             remaining_s -= remaining_minutes * 60;\r
125             print("Processing sector "+str(n)+" of "+str(len(xlist))\r
126                     +" ("+str(round(100.0*n/len(xlist), 1))+"%)"\r
127                     +" (ETA: "+str(remaining_minutes)+"m "\r
128                     +str(int(remaining_s))+"s)")\r
129 \r
130     xpos = xlist[n]\r
131     zpos = zlist[n]\r
132 \r
133     xhex = int_to_hex3(xpos)\r
134     zhex = int_to_hex3(zpos)\r
135     xhex4 = int_to_hex4(xpos)\r
136     zhex4 = int_to_hex4(zpos)\r
137 \r
138     sector1 = xhex4.lower() + zhex4.lower()\r
139     sector2 = xhex.lower() + "/" + zhex.lower()\r
140 \r
141     ylist=[]\r
142 \r
143     sectortype = ""\r
144 \r
145     try:\r
146         for filename in os.listdir(path + "sectors/" + sector1):\r
147             if(filename != "meta"):\r
148                 pos = int(filename,16)\r
149                 if(pos > 32767):\r
150                     pos-=65536\r
151                 ylist.append(pos)\r
152                 sectortype = "old"\r
153     except OSError:\r
154         pass\r
155 \r
156     if sectortype != "old":\r
157         try:\r
158             for filename in os.listdir(path + "sectors2/" + sector2):\r
159                 if(filename != "meta"):\r
160                     pos = int(filename,16)\r
161                     if(pos > 32767):\r
162                         pos-=65536\r
163                     ylist.append(pos)\r
164                     sectortype = "new"\r
165         except OSError:\r
166             pass\r
167 \r
168     if sectortype == "":\r
169         continue\r
170 \r
171     ylist.sort()\r
172 \r
173     # Make a list of pixels of the sector that are to be looked for.\r
174     pixellist = []\r
175     for x in range(16):\r
176         for y in range(16):\r
177             pixellist.append((x,y))\r
178 \r
179     # Go through the Y axis from top to bottom.\r
180     for ypos in reversed(ylist):\r
181 \r
182         yhex = int_to_hex4(ypos)\r
183 \r
184         filename = ""\r
185         if sectortype == "old":\r
186             filename = path + "sectors/" + sector1 + "/" + yhex.lower()\r
187         else:\r
188             filename = path + "sectors2/" + sector2 + "/" + yhex.lower()\r
189 \r
190         f = file(filename, "rb")\r
191 \r
192         # Let's just memorize these even though it's not really necessary.\r
193         version = f.read(1)\r
194         flags = f.read(1)\r
195 \r
196         dec_o = zlib.decompressobj()\r
197         try:\r
198             mapdata = dec_o.decompress(f.read())\r
199         except:\r
200             mapdata = []\r
201 \r
202         f.close()\r
203 \r
204         if(len(mapdata)<4096):\r
205             print "bad: " + xhex+zhex+"/"+yhex + " " + len(mapdata)\r
206         else:\r
207             chunkxpos=xpos*16\r
208             chunkypos=ypos*16\r
209             chunkzpos=zpos*16\r
210             for (x,z) in reversed(pixellist):\r
211                 for y in reversed(range(16)):\r
212                     datapos=x+y*16+z*256\r
213                     if(ord(mapdata[datapos])!=254):\r
214                         try:\r
215                             pixellist.remove((x,z))\r
216                             # Memorize information on the type and height of the block and for drawing the picture.\r
217                             stuff[(chunkxpos+x,chunkzpos+z)]=(chunkypos+y,ord(mapdata[datapos]))\r
218                             break\r
219                         except:\r
220                             print "strange block: " + xhex+zhex+"/"+yhex + " x: " + str(x) + " y: " + str(y) + " z: " + str(z) + " block: " + str(ord(mapdata[datapos]))\r
221 \r
222         # After finding all the pixeld in the sector, we can move on to the next sector without having to continue the Y axis.\r
223         if(len(pixellist)==0):\r
224             break\r
225 \r
226 print "Drawing image"\r
227 # Drawing the picture\r
228 starttime = time.time()\r
229 n = 0\r
230 minx = min(xlist)\r
231 minz = min(zlist)\r
232 for (x,z) in stuff.iterkeys():\r
233     if n % 500000 == 0:\r
234         nowtime = time.time()\r
235         dtime = nowtime - starttime\r
236         n_per_second = 1.0 * n / dtime\r
237         if n_per_second != 0:\r
238             listlen = len(stuff)\r
239             seconds_per_n = 1.0 / n_per_second\r
240             time_guess = seconds_per_n * listlen\r
241             remaining_s = time_guess - dtime\r
242             remaining_minutes = int(remaining_s / 60)\r
243             remaining_s -= remaining_minutes * 60;\r
244             print("Drawing pixel "+str(n)+" of "+str(listlen)\r
245                     +" ("+str(round(100.0*n/listlen, 1))+"%)"\r
246                     +" (ETA: "+str(remaining_minutes)+"m "\r
247                     +str(int(remaining_s))+"s)")\r
248     n += 1\r
249 \r
250     (r,g,b)=colors[stuff[(x,z)][1]]\r
251 \r
252     # Comparing heights of a couple of adjacent blocks and changing brightness accordingly.\r
253     try:\r
254         y1=stuff[(x-1,z)][0]\r
255         y2=stuff[(x,z-1)][0]\r
256         y=stuff[(x,z)][0]\r
257 \r
258         d=(y-y1+y-y2)*12\r
259 \r
260         if(d>36):\r
261             d=36\r
262 \r
263         r=limit(r+d,0,255)\r
264         g=limit(g+d,0,255)\r
265         b=limit(b+d,0,255)\r
266     except:\r
267         pass\r
268     #impix[w-1-(x-minx*16),h-1-(z-minz*16)]=(r,g,b)\r
269     impix[x-minx*16,h-1-(z-minz*16)]=(r,g,b)\r
270 \r
271 # Flip the picture to make it right and save.\r
272 #print "Transposing"\r
273 #im=im.transpose(Image.FLIP_TOP_BOTTOM)\r
274 print "Saving"\r
275 im.save(output)\r