source: branches/active/character_customization/game/utilities/gfxsplit.py @ 722

Revision 553, 7.0 KB checked in by beliar, 10 years ago (diff)

Merged changes from code-cleanup-and-refactoring back into the trunk.

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