source: trunk/PARPG/utilities/gfxsplit.py @ 196

Revision 147, 6.9 KB checked in by barra_parpg, 10 years ago (diff)
  • SVN EOL style fixes
  • Property svn:eol-style set to native
  • Property svn:executable set to *
Line 
1#!/usr/bin/env python
2
3#   This file is part of PARPG.
4
5#   PARPG is free software: you can redistribute it and/or modify
6#   it under the terms of the GNU General Public License as published by
7#   the Free Software Foundation, either version 3 of the License, or
8#   (at your option) any later version.
9
10#   PARPG is distributed in the hope that it will be useful,
11#   but WITHOUT ANY WARRANTY; without even the implied warranty of
12#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13#   GNU General Public License for more details.
14
15#   You should have received a copy of the GNU General Public License
16#   along with PARPG.  If not, see <http://www.gnu.org/licenses/>
17
18import sys, pygame
19
20# place defines here
21
22TILE_WIDTH  =   72
23TILE_HEIGHT =   36
24# is this is true, output a file of the pics together in the current folder
25STITCH      =   False
26
27# this is very much a simple routine, but we still have a simple class
28
29class TileImage:
30    def __init__(self, picture, name, yoff):
31        self.image = picture
32        self.filename = name
33        self.y_offset = yoff
34
35def writeXML(name, yoff):
36    """Write the XML file as well
37       Always the same small file so we do it automatically"""
38    # we need to strip off the entire path up to the last
39    # TODO: this code will not work on windows
40    # strip off the png part and replace with the XML
41    filename = name.split('/')[-1]
42    if(filename == name):
43        filename = name.split('\\')[-1]
44    x_file = open(name[:-4]+".xml","wt")
45    x_file.write('''<?fife type="object"?>\n''')
46    x_file.write('''<object id="''')
47    x_file.write(filename[:-4])
48    x_file.write('''" namespace="PARPG" blocking="1" static="1">\n''')
49    x_file.write('''    <image source="''')
50    x_file.write(filename)
51    x_file.write('''" direction="0"''')
52    x_file.write(''' y_offset="''')
53    x_file.write(yoff)
54    x_file.write('''" />\n''')
55    # the \n\n is ESSENTIAL otherwise the XML parser in FIFE craps out!
56    x_file.write('''</object>\n\n''')
57    x_file.close
58
59def stitchImages(files, width, height):
60    """Put the images together and output them to stitched.png"""
61    new_image=pygame.Surface((width, height), pygame.SRCALPHA, 32)
62    xpos = 0
63    for i in files:
64        new_image.blit(i.image, (xpos, 0))
65        xpos += i.image.get_width()
66    pygame.image.save(new_image,"stitched.png")
67   
68def saveFiles(files):
69    """Given a list of TileImages, output them as seperate files
70       Returns True if it worked"""
71    # files is a list of TileImages
72    complete = []
73    width = 0
74    height = 0
75    for i in files:
76        width += i.image.get_width()
77        if(i.image.get_height() > height):
78            height = i.image.get_height()
79        try:
80            pygame.image.save(i.image, i.filename)
81            # output the XML file as well
82            writeXML(i.filename, str(i.y_offset))
83        except:
84            print "Error: Failed to save",i.filename
85            # if we saved some anyway, then tell the user
86            if(complete != []):
87                print "  Managed to save",
88                for name in complete:
89                    print name,
90                print "\n"
91            return False
92        complete.append(i.filename)
93    # seems like all was ok
94    if(STITCH == True):
95        stitchImages(files, width, height)
96    return True
97           
98def splitImage(image, filename, data):
99    """Quite complex this, as there are many differing layouts on the
100       hexes that we could be dealing with. We blit from left to right
101       data holds the hex position changes in [x,y] format.
102       by one and the y value staying the same (on the grid map)"""
103    # the starting point for the grab is always the middle of the image
104    height = (image.get_height() / 2) + (TILE_HEIGHT / 2)
105    xpos = 0
106    file_counter = 0
107    tiles = []
108    height_adjust = 0
109    yoff_next = -((height - TILE_HEIGHT) / 2)
110    for t in data:
111        yoff = yoff_next
112        if(t == 'm'):
113            # switchback, so this tile must fill the whole width
114            width += TILE_WIDTH / 2
115            height_adjust = TILE_HEIGHT / 2
116            yoff_next += (TILE_HEIGHT / 4) + (TILE_HEIGHT / 2)
117            xoff = 0
118        elif(t == 'r'):
119            # moving forward on the y axis
120            width = TILE_WIDTH / 2
121            height_adjust = - (TILE_HEIGHT / 2)
122            yoff_next += TILE_HEIGHT / 4
123            xoff = TILE_WIDTH / 2
124        elif(t == 'l'):
125            # moving forward on the x axis
126            width = TILE_WIDTH / 2
127            height_adjust = TILE_HEIGHT / 2
128            yoff_next -= TILE_HEIGHT / 4
129            xoff = 0
130        else:
131            # TODO: Handle integer moves (i.e. > 1 tile up down)
132            print "Error: Can't handle integer tile moves yet"
133            sys.exit(False)
134        # if the image is 256, then adjust
135        # bug in the FIFE OpenGL code
136        if(height == 256):
137            height += 1
138        # build the new surface
139        new_surface = pygame.Surface((TILE_WIDTH, height), pygame.SRCALPHA, 32)
140        # now blit a strip of the image across
141        new_surface.blit(image, (0+xoff, 0), pygame.Rect(xpos, 0, width, height))
142        # store the image for later
143        tiles.append(TileImage(new_surface,
144            filename + chr(ord('a')+file_counter) + ".png",yoff))
145        file_counter += 1
146        # amend variables
147        xpos += width
148        height += height_adjust
149    return tiles
150           
151def convertFiles(filename, txt_data):
152    """Take a file, slice into seperate images and then save these new images
153       as filename0, filename1 ... filenameN
154       Returns True if everything worked
155       The second string gives the offsets from left to right. The first tile
156       on the LHS MUST be in the centre of the image"""
157    # first we need to ensure that the data sent is correct. split it up first
158    data=[]
159    for i in txt_data:
160        data.append(i)
161    if(len(data) < 2):
162        print "Error: Invalid tile data layout"
163        return False
164    # validate each data statement
165    for i in data:
166        if((i != 'l')and(i != 'r')and(i != 'm')and(i.isdigit()==False)):
167            # some issue
168            print "Error: Can't decode tile string structure"
169            return False
170    # then load the file
171    try:
172        image = pygame.image.load(filename)
173    except(pygame.error):
174        print "Error: Couldn't load",filename
175        return False       
176    # split into seperate files
177    # the [:-4] is used to split off the .png from the filename
178    images = splitImage(image, filename[:-4], data)
179    # save it and we are done
180    if(images == []):
181        # something funny happened
182        print "Error: Couldn't splice given image file"
183        return False
184    return(saveFiles(images))
185
186if __name__=="__main__":
187    # check we have some options
188    if(len(sys.argv) < 3):
189        sys.stderr.write("Error: Not enough data given\n")
190        sys.exit(False)
191    # ok, so init pygame and do it
192    pygame.init()
193    sys.exit(convertFiles(sys.argv[1], sys.argv[2]))
194
Note: See TracBrowser for help on using the repository browser.