-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtmx2ea.py
177 lines (157 loc) · 6.34 KB
/
tmx2ea.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
import six, tmx, sys, os, lzss, glob
import tkinter as tk
from tkinter import filedialog, messagebox
import argparse
# TODO: Update macros, and don't overwrite existing maps
def show_exception_and_exit(exc_type, exc_value, tb):
import traceback
traceback.print_exception(exc_type, exc_value, tb)
input("Press Enter key to exit.")
sys.exit(-1)
def makedmp(tmap,layer,fname):
ary = [tmap.width+(tmap.height<<8)]
for tile in layer.tiles:
ary.append((tile.gid - 1) * 4)
result = b''.join([(x).to_bytes(2,'little') for x in ary])
with open(os.path.splitext(fname)[0]+"_data.dmp", 'wb') as myfile:
lzss.compress(result, myfile)
def getTileChange(layer,x,y,w,h):
tilemap = [hex((tile.gid-1)*4) for tile in layer.tiles if tile.gid is not 0]
result = layer.name.replace(" ", "_") + ":\nSHORT "
for t in tilemap:
result += (t + " ")
result += "\nALIGN 4\n\n"
return result
def process(tmap,fname):
"""
Let's see. Need to get layers.
<property name="Height" value ="3"/>
<property name="ID" value ="1"/>
<property name="Width" value ="3"/>
<property name="X" value ="6"/>
<property name="Y" value ="0"/>
"""
output = """//Map Installer generated by TMX2EA.exe
#include eastdlib.event
"""
chapterdata = "SetChapterData({ChapterID},{ObjectType},{ObjectType2},{PaletteID},{TileConfig},{MapID},Map,{Anims1},{Anims2},{MapChangesID})\nEventPointerTable({MapChangesID}, MapChanges)\n"
macros = ""
changes = ""
#map properties
ChapterID = "ChapterID"
ObjectType = "ObjectType"
ObjectType2 = "0"
PaletteID = "PaletteID"
TileConfig = "TileConfig"
MapID = "map_id"
Anims1 = "0"
Anims2 = "0"
MapChangesID = "map_changes"
if (tmap.tilewidth == tmap.tileheight == 16)==False:
print("WARNING:\n" + os.path.split(fname)[1] + " does not have 16x16 tiles, skipping")
return None
mainlayer = False
for layer in tmap.layers:
isMain = False
for p in layer.properties:
if (p.name.lower() == "main"):
assert mainlayer==False, "More than one layer marked as Main in "+os.path.split(fname)[1]
isMain = True
mainlayer = True
makedmp(tmap,layer,fname) #turn this layer into tiles and output a dmp
elif p.name.lower() == "id":
layerID = p.value
elif p.name.lower() == "height":
height = p.value
elif p.name.lower() == "width":
width = p.value
elif p.name.lower() == "x":
layerX = p.value
elif p.name.lower() == "y":
layerY = p.value
elif p.name.lower() == "chapterid":
ChapterID = p.value
elif p.name.lower() == "objecttype":
ObjectType = p.value
elif p.name.lower() == "objecttype1":
ObjectType = p.value
elif p.name.lower() == "objecttype2":
ObjectType2 = p.value
elif p.name.lower() == "paletteid":
PaletteID = p.value
elif p.name.lower() == "tileconfig":
TileConfig = p.value
elif p.name.lower() == "mapid":
MapID = p.value
elif p.name.lower() == "mapchangesid":
MapChangesID = p.value
elif p.name.lower() == "anims":
Anims1 = p.value
elif p.name.lower() == "anims1":
Anims1 = p.value
elif p.name.lower() == "anims2":
Anims2 = p.value
if len(tmap.layers)==1: #for the case of no properties and one layer
mainlayer = True
makedmp(tmap,layer,fname) #turn this layer into tiles and output a dmp
if (isMain==False) and len(tmap.layers)!=1: #write any tile change layers
macro = "TileMap(" + str(layerID) + "," + str(layerX) + "," + str(layerY) + "," + str(width) + "," + str(height) + "," + layer.name.replace(" ", "_") + ")\n"
tileChangeData = getTileChange(layer,layerX,layerY,width,height)
macros += macro
changes += tileChangeData
if mainlayer==False: #handle the case of no main and multiple layers
print("WARNING:\n" + os.path.split(fname)[1] + " has no layer marked as Main, skipping")
return None
output += chapterdata.format(**locals())
output += ("Map:\n#incbin \"" + os.path.splitext(os.path.split(fname)[1])[0]+"_data.dmp\"\n\nMapChanges:\n")
if macros == "": #no map changes
output = output.replace("EventPointerTable(map_changes, MapChanges)\n",'').replace("\nMapChanges:\n",'').replace("map_changes","0")
else:
output += (macros + "TileMapEnd\n\n" + changes)
return output
def main():
sys.excepthook = show_exception_and_exit
create_installer = False
parser = argparse.ArgumentParser()
parser.add_argument("tmxpath", nargs='*', help="path to tmx file to process") #all arguments are tmx files
parser.add_argument("-s", "--scanfolders", action="store_true", help="scan all subfolders and generate master installer") #optional scan
args = parser.parse_args()
if (not args.tmxpath) and (not args.scanfolders): #no arguments given and scanfolders is not true
root = tk.Tk()
root.withdraw()
if messagebox.askyesno("Folder Scan","Scan all subfolders for .tmx files?"):
args.scanfolders = True
else:
tmxmap = (filedialog.askopenfilename(filetypes=[("TMX files",".tmx"),("All files",".*")],initialdir=os.getcwd(),title="Select TMX file to process"))
if tmxmap=="":
input("No file given.\nPress Enter key to exit.")
sys.exit(-1)
else:
args.tmxpath = [tmxmap]
if args.scanfolders:
args.tmxpath = glob.glob('**/*.tmx',recursive=True)
create_installer = True
installer = """//Master Map Installer generated by TMX2EA.exe
#ifndef ChapterDataTable
#ifdef _FE8_
#define ChapterDataTable 0x8B0890
#endif
#ifdef _FE7_
#define ChapterDataTable 0xC9A200
#endif
#endif
#define SetChapterData(ChapterID,ObjectType1,ObjectType2,PaletteID,TileConfig,MapID,MapPointer,Anims1,Anims2,MapChanges) "PUSH; ORG ChapterDataTable+(ChapterID*148)+4; BYTE ObjectType1 ObjectType2 PaletteID TileConfig MapID Anims1 Anims2 MapChanges; EventPointerTable(MapID,MapPointer); POP"
"""
for fname in args.tmxpath:
tmap = tmx.TileMap.load(fname)
eventfile = process(tmap,fname)
if eventfile:
with open(os.path.splitext(fname)[0]+".event", 'w') as myfile:
myfile.write(eventfile)
installer += "{\n#include \""+os.path.splitext(fname)[0]+".event\"\n}\n"
if create_installer:
with open("Master Map Installer.event", 'w') as f:
f.write(installer)
input("....done!\nPress Enter key to exit.")
if __name__ == '__main__':
main()