Advertisement
BrawlRefined

Untitled

Jul 25th, 2017
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.65 KB | None | 0 0
  1. import os
  2. import sys
  3. import platform
  4. import struct
  5. import pprint
  6. import re
  7. import copy
  8. import math
  9. import zipfile
  10. import tempfile
  11. import Tkinter as tk
  12. import tkFileDialog as tkfd
  13.  
  14. try:
  15. from PIL import Image, ImageTk
  16. except:
  17. print "PIL not found!"
  18. print "Install PIL or Pillow as such:"
  19. print "pip install python-PIL"
  20. print "pip install Pillow"
  21. print "Note that this code was not tested with Pillow; if PIL is unavailable it should work fine with Pillow, but if not, contact the script author"
  22.  
  23. try:
  24. import png
  25. except:
  26. print "PyPNG not found!"
  27. print "If you're running this program to pack files you should be fine. Otherwise, install PyPNG as such:"
  28. print "pip install pypng"
  29.  
  30. try:
  31. from colorama import Fore, Back, Style
  32. import colorama
  33. colorama.init()
  34. except:
  35. print "Colorama not found!"
  36. print "Colorama is completely unnecessary, but the console output for packing files might be ugly."
  37. # Defining Fore, Back, and Style, so they don't crash without Colorama
  38. # We need to make getters for the functions so that they work as Fore.BLACK and not just Fore.BLACK()
  39. def constant(f):
  40. def fset(self, value):
  41. raise TypeError
  42. def fget(self):
  43. return f()
  44. return property(fget, fset)
  45. # Define everything as returning "" so we can just append an empty string
  46. class coloramaFunc():
  47. @constant
  48. def GREEN():
  49. return ""
  50. @constant
  51. def RED():
  52. return ""
  53. @constant
  54. def BLACK():
  55. return ""
  56. @constant
  57. def RESET_ALL():
  58. return ""
  59. # Since Fore, Back, and Style are all just going to append empty strings, we don't need different functions for different ones
  60. Fore = coloramaFunc()
  61. Back = coloramaFunc()
  62. Style = coloramaFunc()
  63.  
  64. pp = pprint.PrettyPrinter(depth=6)
  65.  
  66. def LoadBaseFile():
  67. root = tk.Tk()
  68. root.withdraw()
  69. baseFieldPath = tkfd.askopenfilename(parent=root)
  70.  
  71. baseFieldInfo = os.stat(baseFieldPath)
  72. baseFieldSize = baseFieldInfo.st_size
  73.  
  74. fieldSizeTable = {
  75. 968: 88,
  76. 1040: 104,
  77. 1056: 88,
  78. 1152: 96,
  79. 1352: 104,
  80. 1568: 112,
  81. 1800: 120
  82. }
  83.  
  84. return baseFieldPath, fieldSizeTable[baseFieldSize], baseFieldSize
  85.  
  86. def LoadPNG():
  87. root = tk.Tk()
  88. root.withdraw()
  89. path = tkfd.askopenfilename(parent=root)
  90.  
  91. r = png.Reader(filename=path)
  92. read = r.asRGB()
  93. pixelArray = list(read[2])
  94. width = read[0]
  95. height = read[1]
  96.  
  97. return path, width, height, pixelArray
  98.  
  99. def LoadFLDs():
  100. root = tk.Tk()
  101. root.withdraw()
  102. fieldList = tkfd.askopenfilenames(parent=root)
  103.  
  104. # On Windows Python 2.6-2.7.6, askopenfilenames returns a Unicode string instead of a tuple >:I
  105. if type(fieldList) != tuple:
  106. if type(fieldList) is unicode or type(fieldList) is str:
  107. fieldList = root.tk.splitlist(fieldList)
  108. else:
  109. # As far as I know, this should never trigger, but computers are wily ones. Information is ordered from least to most likely to crash the program
  110. print "Unknown variable type for fieldList!"
  111. print "Please report this error and the following info to the script author :)"
  112. print type(fieldList), type(type(fieldList))
  113. print platform.platform(), platform.system(), platform.python_version()
  114. print platform.python_implementation(), platform.python_build()
  115.  
  116. fieldSlotTable = {
  117. 968: ["field_clover.fld", "field_nightflight.fld", "field_practice.fld", "field_pudding.fld", "field_tomomo.fld", "field_vortex.fld", "field_wander.fld", "field_war.fld"],
  118. 1040: ["field_shipyard.fld"],
  119. 1056: [],
  120. 1152: ["field_starship.fld"],
  121. 1352: ["field_christmas.fld", "field_frost.fld", "field_island.fld", "field_islandnight.fld", "field_lagoon.fld"],
  122. 1568: ["field_winter.fld"],
  123. 1800: ["field_farm.fld", "field_highway.fld", "field_planet.fld", "field_seal.fld", "field_starcircuit.fld", "field_sunset.fld", "field_sweetheaven.fld", "field_training.fld"]
  124. }
  125.  
  126. customMapTable = {
  127. 968: [1,2,3,4,5,6,7,8],
  128. 1040: [1,],
  129. 1056: [],
  130. 1152: [1,],
  131. 1352: [1,2,3,4,5],
  132. 1568: [1,],
  133. 1800: [1,2,3,4,5,6,7,8]
  134. }
  135.  
  136. listOfMapsThatNeedAutoPadding = []
  137. correspondingListOfSizesToBePaddedTo = []
  138.  
  139. # Iterating over the list of custom apps that were selected by the user; we insert the map in the first slot that's big enough
  140. for customMap in fieldList:
  141. foundMatch = 0
  142. info = os.stat(customMap)
  143. fieldSize = info.st_size
  144. for size,slotList in sorted(customMapTable.iteritems()):
  145. if size > fieldSize:
  146. if customMap not in listOfMapsThatNeedAutoPadding:
  147. listOfMapsThatNeedAutoPadding.append(customMap)
  148. correspondingListOfSizesToBePaddedTo.append(size)
  149. if fieldSize > size:
  150. pass
  151. else:
  152. for position in xrange(len(slotList)):
  153. #print size,fieldSize,position
  154. if type(slotList[position]) is int:
  155. slotList[position] = customMap
  156. foundMatch = 1
  157. break
  158. if foundMatch == 1:
  159. break
  160.  
  161. # Padding out the rest of the map with default maps
  162. for size,cMapList in sorted(customMapTable.iteritems()):
  163. for slot in xrange(len(cMapList)):
  164. try:
  165. if type(cMapList[slot]) is int:
  166. cMapList[slot] = fieldSlotTable[size][slot]
  167. except:
  168. pass
  169.  
  170. paddedMaps = {}
  171. for i in xrange(len(listOfMapsThatNeedAutoPadding)):
  172. paddedMaps[listOfMapsThatNeedAutoPadding[i]] = AutoPadMap(listOfMapsThatNeedAutoPadding[i],correspondingListOfSizesToBePaddedTo[i])
  173.  
  174. return fieldList,customMapTable,fieldSlotTable, listOfMapsThatNeedAutoPadding, paddedMaps
  175.  
  176. def AutoPadMap(cMap,necessarySize):
  177. # If a map is originally a smaller size than the size it's being imported as, we need to pad to make sure the width of the map matches the width of the slot it's going into
  178. mapSize = os.stat(cMap).st_size
  179. # fileSize: width in bytes
  180. fieldSizeTable = {
  181. 968: 88,
  182. 1040: 104,
  183. 1056: 88,
  184. 1152: 96,
  185. 1352: 104,
  186. 1568: 112,
  187. 1800: 120
  188. }
  189. # We need to increase the width of the map to match the new size, so every row should gain (nWidth - oWidth) bytes, where one tile is 8 bytes
  190. widthIncrement = fieldSizeTable[necessarySize] - fieldSizeTable[mapSize]
  191.  
  192. # This next bit is very similar to CreateFieldArray, but for technical reasons it's probably best to have them separate
  193. smallFieldArray = []
  194. smallField = open(cMap,"rb")
  195.  
  196. try:
  197. bytes = smallField.read(2)
  198. while bytes != "":
  199. smallFieldArray.append(struct.unpack("h", bytes)[0])
  200. bytes = smallField.read(2)
  201. finally:
  202. smallField.close()
  203.  
  204. bigField = {0: []}
  205.  
  206. count = 0
  207. pFARow = 0
  208. for i in smallFieldArray:
  209. if count%2 == 0:
  210. bigField[pFARow].append(hex(i)[2:])
  211.  
  212. count += 1
  213.  
  214. if count == fieldSizeTable[mapSize]/2:
  215. for i in xrange(widthIncrement/4): # Padding
  216. bigField[pFARow].append("0")
  217. count = 0
  218. pFARow += 1
  219. bigField[pFARow] = []
  220.  
  221. tempMapFile = tempfile.NamedTemporaryFile(delete=False,dir=os.path.dirname(os.path.abspath(__file__)))
  222.  
  223. for rowIdx in bigField:
  224. for i in bigField[rowIdx]:
  225. tempMapFile.write(struct.pack("h",int(i,16)))
  226. tempMapFile.write(buffer("\x00\x00"))
  227.  
  228. tempMapFile.close()
  229. return tempMapFile
  230.  
  231. def DEBUGPrintCustomMapTable(cmt):
  232. # Can't believe I'm writing for the Connecticut Mastery Test
  233. for key,value in sorted(cmt.iteritems()):
  234. print key,value
  235.  
  236. def CreateFieldArray(path,size):
  237. fieldArray = []
  238. baseField = open(path, "rb")
  239.  
  240. try:
  241. bytes = baseField.read(2)
  242. while bytes != "":
  243. fieldArray.append(struct.unpack("h", bytes)[0])
  244. bytes = baseField.read(2)
  245. finally:
  246. baseField.close()
  247.  
  248. prettyFieldArray = {0: []}
  249.  
  250. count = 0
  251. pFARow = 0
  252. for i in fieldArray:
  253. if count%2 == 0:
  254. #print hex(i)[2:],
  255. prettyFieldArray[pFARow].append(hex(i)[2:])
  256.  
  257. count += 1
  258.  
  259. if count == size/2:
  260. #print "\n"
  261. count = 0
  262. pFARow += 1
  263. prettyFieldArray[pFARow] = []
  264.  
  265. return prettyFieldArray
  266.  
  267. def TurnArrayIntoPixels(array):
  268. palette = {
  269. 0: (0x00,0x00,0x00),
  270. 1: (0x7f,0x7f,0x7f),
  271. 2: (0xff,0x7f,0x27),
  272. 3: (0xed,0x1c,0x24),
  273. 4: (0x22,0xb1,0x4c),
  274. 5: (0xff,0xc9,0x0e),
  275. 6: (0x3f,0x48,0xcc),
  276. 7: (0xa3,0x49,0xa4),
  277. 8: (0x0b,0x62,0x0f),
  278. 9: (0xae,0x87,0x00),
  279. 10: (0x1c,0x21,0x66),
  280. 11: (0xff,0xff,0xff),
  281. 12: (0xff,0xff,0xff),
  282. 13: (0xff,0xff,0xff),
  283. 14: (0xff,0xff,0xff),
  284. 15: (0xff,0xff,0xff),
  285. 16: (0xff,0xff,0xff),
  286. 17: (0xff,0xff,0xff),
  287. 18: (0x98,0x47,0x0c),
  288. 19: (0xff,0xff,0xff),
  289. 20: (0x88,0x00,0x15),
  290. 21: (0x00,0xa2,0xe8),
  291. 22: (0x00,0x83,0xbb),
  292. 23: (0xe2,0x38,0x9a),
  293. 24: (0xa2,0x17,0x67),
  294. 25: (0x99,0xd9,0xea)
  295. }
  296.  
  297. pixelList = [[]]
  298.  
  299. rowCount = 0
  300. colCount = 0
  301. for row in array:
  302. for i in array[row]:
  303. if colCount == 0:
  304. pixel = palette[int(i, 16)]
  305. pixelList[rowCount].append(pixel[0])
  306. pixelList[rowCount].append(pixel[1])
  307. pixelList[rowCount].append(pixel[2])
  308. colCount = 1
  309. else:
  310. colCount = 0
  311. pixelList.append([])
  312. rowCount += 1
  313.  
  314. pixelList.pop()
  315. pixelList.pop()
  316.  
  317. return pixelList
  318.  
  319. def CreateImageFromPixels(pixelList, fileSize, size, path):
  320. m = re.search("([^/]+)/?$", path)
  321. newPath = m.group(0)[0:-4] + ".png"
  322.  
  323. outputImage = open(newPath, "wb")
  324. height = fileSize/size
  325. width = size/8
  326.  
  327. writer = png.Writer(width, height)
  328. writer.write(outputImage, pixelList)
  329. outputImage.close()
  330. return os.path.realpath(outputImage.name)
  331.  
  332. def generateArrayFromPicture(pixels):
  333. tileArray = []
  334. for i in pixels:
  335. numberOfPixels = len(i)/3
  336. for j in range(0,numberOfPixels):
  337. nextPixel = (i.pop(0), i.pop(0), i.pop(0))
  338. pixelID = checkIfPixelInPalette(nextPixel)
  339. tileArray.append(pixelID)
  340.  
  341. return tileArray
  342.  
  343.  
  344. def checkIfPixelInPalette(pixel):
  345. palette = {
  346. 0: (0x00,0x00,0x00),
  347. 1: (0x7f,0x7f,0x7f),
  348. 2: (0xff,0x7f,0x27),
  349. 3: (0xed,0x1c,0x24),
  350. 4: (0x22,0xb1,0x4c),
  351. 5: (0xff,0xc9,0x0e),
  352. 6: (0x3f,0x48,0xcc),
  353. 7: (0xa3,0x49,0xa4),
  354. 8: (0x0b,0x62,0x0f),
  355. 9: (0xae,0x87,0x00),
  356. 10: (0x1c,0x21,0x66),
  357. 11: (0xf0,0xf0,0xf0),
  358. 12: (0xf0,0xf0,0xf0),
  359. 13: (0xf0,0xf0,0xf0),
  360. 14: (0xf0,0xf0,0xf0),
  361. 15: (0xf0,0xf0,0xf0),
  362. 16: (0xf0,0xf0,0xf0),
  363. 17: (0xf0,0xf0,0xf0),
  364. 18: (0x98,0x47,0x0c),
  365. 19: (0xf0,0xf0,0xf0),
  366. 20: (0x88,0x00,0x15),
  367. 21: (0x00,0xa2,0xe8),
  368. 22: (0x00,0x83,0xbb),
  369. 23: (0xe2,0x38,0x9a),
  370. 24: (0xa2,0x17,0x67),
  371. 25: (0x99,0xd9,0xea)
  372. }
  373.  
  374. for i in palette:
  375. if pixel[0] == palette[i][0]:
  376. if pixel[1] == palette[i][1]:
  377. if pixel[2] == palette[i][2]:
  378. return i
  379. return 99
  380.  
  381. def downsizePixelArray(pixelArray):
  382. # Downsizes the pixel array, saving every third pixel
  383. # This effectively removes movement data, leaving only tile data
  384. downsizedPixelArray = []
  385. # Iterate over each row of pixels
  386. rowCount = 0
  387. for row in pixelArray:
  388. downsizedPixelArray.append([])
  389. colCount = 0
  390. for j in row:
  391. if colCount <3: #<3
  392. # If this is the first pixel, take all three RGB channels and insert them into the downsized array
  393. downsizedPixelArray[rowCount].append(j)
  394. colCount += 1
  395. elif colCount <8:
  396. # If this isn't the first pixel, ignore it
  397. colCount += 1
  398. else:
  399. # If this is the 9th byte, loop the counter and ignore it
  400. colCount = 0
  401. colCount = 0
  402. rowCount += 1
  403.  
  404. #Only every third row is relevant to us, so we'll make a new list that only has the rows we want
  405. downsizedArrayFixed = []
  406. for i in range(len(downsizedPixelArray)):
  407. if (i+1)%3 == 1:
  408. downsizedArrayFixed.append(copy.deepcopy(downsizedPixelArray[i]))
  409.  
  410. return downsizedArrayFixed
  411.  
  412. def generateMovementPixelArray(pixelArray):
  413. """
  414. We need to check the colour of each pixel. If it's #404040 (64 64 64) it's an entrance;
  415. if it's pure white (255 255 255) it's an exit. For any pixel,
  416. we immediately disregard it.
  417. """
  418. movementArray = []
  419. count = 0
  420. for i in pixelArray:
  421. movementArray.append([])
  422. for j in xrange(0,len(i),3):
  423. if i[j] == 255: # Check if the R value is 255
  424. if i[j+1] == 255: # Check G
  425. if i[j+2] == 255: # Check B
  426. movementArray[count].append(255)
  427. else:
  428. movementArray[count].append(0)
  429. else:
  430. movementArray[count].append(0)
  431. elif i[j] == 64: # Check if the R value is 64
  432. if i[j+1] == 64: # Check G
  433. if i[j+2] == 64: # Check B
  434. movementArray[count].append(64)
  435. else:
  436. movementArray[count].append(0)
  437. else:
  438. movementArray[count].append(0)
  439. else: # Not a movement tile!
  440. movementArray[count].append(0)
  441. count += 1
  442.  
  443. #DEBUGPrintTilePixelArray(movementArray)
  444.  
  445. # Now we want to turn the pixel array into an array of bitflags
  446. bitflagArray = []
  447. for rowIdx in xrange(0,len(movementArray)):
  448. # Set up movementArray to be clearer for later
  449. for pxIdx in xrange(0,len(movementArray[rowIdx])):
  450. if movementArray[rowIdx][pxIdx] == 64:
  451. movementArray[rowIdx][pxIdx] = "N"
  452. elif movementArray[rowIdx][pxIdx] == 255:
  453. movementArray[rowIdx][pxIdx] = "X"
  454. else:
  455. movementArray[rowIdx][pxIdx] = "0"
  456. tileLength = len(movementArray[0])/3
  457. colCount = 0
  458. bitflagArray.append([])
  459. for i in xrange(0,tileLength):
  460. bitflagArray[rowIdx].append([])
  461.  
  462. # Depending on which row we're in, we care about different pixels
  463. if rowIdx % 3 == 0: # We care about every other pixel starting at 1
  464. for pxIdx in xrange(1,tileLength*3,3): # If we're on an odd row, we only care about the second pixel of every tile (every third pixel, starting at 1)
  465. flag = movementArray[rowIdx][pxIdx]
  466. # Append the flag to the current tile's (row one) flag list
  467. bitflagArray[rowIdx][colCount].append(flag)
  468. colCount += 1
  469. elif rowIdx % 3 == 1: # If we're on an even row, we care about the first and third pixel of every tile (every other, starting at 0)
  470. pxIdxList = range(0,tileLength*3)
  471. del pxIdxList[1::3]
  472. for pxIdx in pxIdxList:
  473. flag = movementArray[rowIdx][pxIdx]
  474. # We append both left and right flags to the same tile's list here. Later, we'll combine the three lists for each tile into one
  475. if pxIdx % 3 == 0:
  476. bitflagArray[rowIdx][int(math.floor(colCount/2))].append(flag)
  477. elif pxIdx % 3 == 2:
  478. bitflagArray[rowIdx][int(math.floor(colCount/2))].append(flag)
  479. colCount += 1
  480.  
  481. else:
  482. for pxIdx in xrange(1,tileLength*3,3):
  483. flag = movementArray[rowIdx][pxIdx]
  484.  
  485. bitflagArray[rowIdx][colCount].append(flag)
  486. colCount += 1
  487.  
  488. #for i in bitflagArray:
  489. # print i
  490.  
  491. # Next, we need to condense our rows, as currently we have the information for each tile split across three rows
  492. condensedBitflagArray = []
  493. for rowIdx in xrange(0,len(bitflagArray),3):
  494. condensedBitflagArray.append([])
  495. for tileIdx in xrange(0,len(bitflagArray[rowIdx])):
  496. condensedTile = [bitflagArray[rowIdx][tileIdx][0],
  497. bitflagArray[rowIdx+1][tileIdx][0],
  498. bitflagArray[rowIdx+1][tileIdx][1],
  499. bitflagArray[rowIdx+2][tileIdx][0]]
  500. condensedBitflagArray[rowIdx/3].append(condensedTile)
  501.  
  502. # Finally, for each tile, we compile the movement info into a single bitflag
  503. finalBitflagArray = []
  504. for rowIdx in xrange(0,len(condensedBitflagArray)):
  505. finalBitflagArray.append([])
  506. for tileIdx in xrange(0,len(condensedBitflagArray[rowIdx])):
  507. bitflag = 0
  508. tileData = condensedBitflagArray[rowIdx][tileIdx]
  509. if tileData[0] == "X":
  510. bitflag += 2
  511. elif tileData[0] == "N":
  512. bitflag += 32
  513.  
  514. if tileData[1] == "X":
  515. bitflag += 1
  516. elif tileData[1] == "N":
  517. bitflag += 16
  518.  
  519. if tileData[2] == "X":
  520. bitflag += 4
  521. elif tileData[2] == "N":
  522. bitflag += 64
  523.  
  524. if tileData[3] == "X":
  525. bitflag += 8
  526. elif tileData[3] == "N":
  527. bitflag += 128
  528. finalBitflagArray[rowIdx].append(bitflag)
  529.  
  530. return finalBitflagArray
  531.  
  532. def CreateMapFromTileAndBitflags(tileArray,bitflagArray,path):
  533. m = re.search("([^/]+)/?$", path)
  534. newPath = m.group(0)[0:-4] + ".fld"
  535.  
  536. outputFile = open(newPath, "wb")
  537. oneDBitflagTable = []
  538. for i in xrange(0,len(bitflagArray)):
  539. for j in xrange(0,len(bitflagArray[i])):
  540. oneDBitflagTable.append(bitflagArray[i][j])
  541.  
  542.  
  543. #print len(tileArray),len(oneDBitflagTable)
  544. for i in xrange(len(tileArray)):
  545. outputFile.write(struct.pack("h",tileArray[i]))
  546. outputFile.write(buffer("\x00\x00"))
  547. outputFile.write(struct.pack("h",oneDBitflagTable[i]))
  548. outputFile.write(buffer("\x00\x00"))
  549.  
  550. def DEBUGPrintTilePixelArray(tilePixelArray):
  551. for i in tilePixelArray:
  552. for num in i:
  553. if num == 0:
  554. print " .",
  555. else:
  556. print "%3d" % num,
  557. print "\n",
  558.  
  559. def DEBUGPrintBitflagArray(bitflagArray):
  560. for row in bitflagArray:
  561. for px in row:
  562. if px == 0:
  563. print ".\t",
  564. else:
  565. print hex(px)[2::] + "\t",
  566. print ""
  567.  
  568. def DEBUGPrintTileArray(tileArray,width):
  569. tileWidth = width/3
  570. count = 0
  571. for i in tileArray:
  572. if i == 0:
  573. print " .\t",
  574. else:
  575. print "%2d\t" % i,
  576. count += 1
  577. if count >= tileWidth:
  578. print "\n",
  579. count = 0
  580.  
  581. def DEBUGPrintMapPadding(tileArray):
  582. for rowIdx in tileArray:
  583. for i in tileArray[rowIdx]:
  584. print i,"\t",
  585. print ""
  586.  
  587. def FLDtoPNG():
  588. # Converts a FLD to a PNG file
  589. # Here we load the FLD file, create an array from it, convert the tile IDs into appropriate pixels, and save an image of it
  590. path, size, fileSize = LoadBaseFile()
  591. FieldArray = CreateFieldArray(path, size)
  592. pixelVer = TurnArrayIntoPixels(FieldArray)
  593. imageName = CreateImageFromPixels(pixelVer, fileSize, size, path)
  594.  
  595. # Next we draw the image to the program window for the user to see
  596. # First, label the globals that we need for our GUI
  597. global canvas
  598. global currentImage1
  599. global currentName
  600. global currentSize
  601. global currentHeight
  602. global currentWidth
  603.  
  604. # Next we print the relevant text for this map
  605. m = re.search("([^/]+)/?$", path)
  606. currentName.set("Field Name:\n" + m.group(0)[0:-4])
  607. currentSize.set("Size:\n" + str(fileSize) + " bytes")
  608. currentHeight.set("Height:\n" + str(fileSize/size) + " tiles")
  609. currentWidth.set("Width:\n" + str(size/8) + " tiles")
  610.  
  611. # Finally, we display the image to the screen
  612. pilImage = Image.open(imageName)
  613. pilImage = pilImage.transform((pilImage.width*10,pilImage.height*10),Image.EXTENT,(0,0,pilImage.width,pilImage.height))
  614. currentImage1 = ImageTk.PhotoImage(pilImage)
  615. tilePreview = canvas.create_image(77,77,image=currentImage1)
  616.  
  617.  
  618. def PNGtoFLD():
  619. path, width, height, fullPixelArray = LoadPNG()
  620. for i in range(height):
  621. fullPixelArray[i] = list(fullPixelArray[i])
  622.  
  623. # Cut out all the movement pixels so that we can process just the tiles
  624. tilePixelArray = copy.deepcopy(fullPixelArray)
  625. tilePixelArray = downsizePixelArray(tilePixelArray)
  626.  
  627. # Label our globals
  628. global canvas
  629. global currentImage1
  630. global currentImage2
  631. global currentName
  632. global currentSize
  633. global currentHeight
  634. global currentWidth
  635.  
  636. # Print the relevant text for this map
  637. m = re.search("([^/]+)/?$", path)
  638. currentName.set("Field Name:\n" + m.group(0)[0:-4])
  639. fileSize = (width/3)*(height/3)*8
  640. currentSize.set("Size:\n" + str(fileSize) + " bytes")
  641. currentHeight.set("Height:\n" + str(height/3) + " tiles")
  642. currentWidth.set("Width:\n" + str(width/3) + " tiles")
  643.  
  644. # Create an image out of just the tile pixels, so we can draw it to the canvas
  645. tpaCopy = copy.deepcopy(tilePixelArray)
  646. data = ""
  647. for row in tpaCopy:
  648. for col in row:
  649. data = data + struct.pack("B",col)
  650. tileImage = Image.frombytes("RGB",((width/3),(height/3)),data)
  651. tileImage = tileImage.transform((tileImage.width*10,tileImage.height*10),Image.EXTENT,(0,0,tileImage.width,tileImage.height))
  652. # Next, we have to convert the image to a form Tkinter can use
  653. currentImage1 = ImageTk.PhotoImage(tileImage)
  654. tilePreview = canvas.create_image(77,77,image=currentImage1)
  655.  
  656.  
  657. tileArray = generateArrayFromPicture(tilePixelArray)
  658. #DEBUGPrintTileArray(tileArray,width)
  659. print ""
  660.  
  661. movementArray = generateMovementPixelArray(fullPixelArray)
  662. #DEBUGPrintBitflagArray(movementArray)
  663. print ""
  664.  
  665. CreateMapFromTileAndBitflags(tileArray,movementArray,path)
  666.  
  667. def FLDtoPAK():
  668. fieldList,cMapTable,officialFieldList,listOfPaddedMaps,paddedMaps = LoadFLDs()
  669. outputFile = zipfile.ZipFile("fields.pak",mode="w")
  670.  
  671. for size,mapList in sorted(cMapTable.iteritems()):
  672. for index in xrange(len(mapList)):
  673. # C'e la luna, mezzo mare...
  674. # First we clip out the part of the math that's just path, so that it looks pretty when printed to the console
  675. m = re.search("([^/]+)/?$", mapList[index])
  676. newPath = m.group(0)
  677. # Now we check if the map is one of the user-supplied maps, and if it is, we print it brighter
  678. if mapList[index] in fieldList:
  679. print Back.GREEN + Fore.BLACK + newPath + Style.RESET_ALL + " will be exported as ",
  680. # We also change newPath to mapList[index], so that we can reference the proper file from newPath later
  681. # If we don't do this, we'd have to do another check to see if the map is official when writing it to the archive
  682. newPath = mapList[index]
  683. else:
  684. print Fore.GREEN + newPath + Style.RESET_ALL + " will be exported as ",
  685. # We also need to change the path to the path to the official file
  686. newPath = "OfficialFiles\\" + newPath
  687. # ...and if the file had to be padded, we print the red brighter and use the temp file
  688. if mapList[index] in listOfPaddedMaps:
  689. print Back.RED + Fore.BLACK + officialFieldList[size][index] + Style.RESET_ALL
  690. outputFile.write(paddedMaps[mapList[index]].name, arcname=officialFieldList[size][index])
  691. else:
  692. print Fore.RED + officialFieldList[size][index] + Style.RESET_ALL
  693. outputFile.write(newPath, arcname=officialFieldList[size][index])
  694.  
  695.  
  696. graphicsList = [
  697. "aurora.dat",
  698. "christmas_h.dat", "christmas_l.dat", "christmas_o.dat",
  699. "clover_l.dat",
  700. "empty.dat",
  701. "farm_h.dat", "farm_l.dat",
  702. "frost_l.dat",
  703. "highway_l.dat", "highway_o.dat",
  704. "island_h.dat", "island_l.dat",
  705. "islandnight_h.dat", "islandnight_l.dat",
  706. "lagoon_h.dat", "lagoon_l.dat",
  707. "nightflight_h.dat", "nightflight_l.dat", "nightflight_o.dat",
  708. "planet_h.dat", "planet_l.dat",
  709. "practice_l.dat",
  710. "pudding_l.dat",
  711. "seal_h.dat", "seal_l.dat", "seal_o.dat",
  712. "shipyard_h.dat", "shipyard_l.dat",
  713. "starcircuit_l.dat", "starcircuit_h.dat",
  714. "starship_h.dat", "starship_l.dat", "starship_o.dat",
  715. "sunset_h.dat", "sunset_l.dat", "sunset_o.dat",
  716. "sweet_h.dat", "sweet_l.dat",
  717. "tomomo_h.dat", "tomomo_l.dat", "tomomo_o.dat",
  718. "training_e.dat", "training_h.dat", "training_l.dat",
  719. "vortex_h.dat", "vortex_l.dat",
  720. "wander_h.dat", "wander_l.dat",
  721. "war_h.dat", "war_l.dat", "war_o.dat",
  722. "winter_l.dat"
  723. ]
  724.  
  725. for i in graphicsList:
  726. newPath = "OfficialFiles\\" + i
  727. outputFile.write(newPath,arcname=i)
  728.  
  729. outputFile.close()
  730. for i in paddedMaps:
  731. paddedMaps[i].close()
  732. os.unlink(paddedMaps[i].name)
  733.  
  734. def FLDtoPAK_GUI():
  735. root = tk.Tk()
  736. menu = tk.Menu(root)
  737. root.config(menu=menu)
  738. root.geometry("308x300")
  739. root.wm_title("100% Orange Juice Field Editing Tool")
  740. root.iconbitmap('favicon.ico')
  741.  
  742. filemenu = tk.Menu(menu)
  743. menu.add_cascade(label="File", menu=filemenu)
  744. filemenu.add_command(label="FLD to PNG", command=FLDtoPNG)
  745. filemenu.add_command(label="PNG to FLD", command=PNGtoFLD)
  746. filemenu.add_command(label="FLDs to PAK", command=FLDtoPAK)
  747. filemenu.add_command(label="DEBUG", command=DEBUGPrintImageData)
  748. filemenu.add_command(label="Exit", command=exitProgram)
  749.  
  750. # Because we're referencing these GUI elements in other functions, we need to make them globals
  751. # Names are deliberately chosen such that they'd be unlikely to come up in other places outside of GUI stuff
  752. global canvas
  753. global currentImage1
  754. global currentImage2
  755. global topPane
  756. global rightPane
  757. global currentName
  758. global currentSize
  759. global currentHeight
  760. global currentWidth
  761. # In order to have the names auto-update later, they need to be converted from string vars to StringVars
  762. currentName = tk.StringVar()
  763. currentSize = tk.StringVar()
  764. currentHeight = tk.StringVar()
  765. currentWidth = tk.StringVar()
  766.  
  767. topPane = tk.Frame(root, width=300, height=150)
  768. topPane.grid(row=0,column=0,sticky="w")
  769.  
  770. leftPane = tk.Frame(root, width=150, height=150, bg="black")
  771. leftPane.grid(row=1,column=0,sticky="w")
  772. rightPane = tk.Frame(root, width=150, height=150, bg="black")
  773. rightPane.grid(row=1,column=1,sticky="w")
  774.  
  775. canvas = tk.Canvas(leftPane, width=150, height=150, bg="dark slate gray")
  776. canvas.pack()
  777. canvas2 = tk.Canvas(rightPane, width=150, height=150, bg="dark slate gray")
  778. canvas2.pack()
  779.  
  780. currentName.set("Field Name:\n")
  781. currentSize.set("Size:\n")
  782. currentHeight.set("Height:\n")
  783. currentWidth.set("Width:\n")
  784. nameLbl = tk.Label(topPane, textvariable=currentName, anchor="w", justify="left")
  785. sizeLbl = tk.Label(topPane, textvariable=currentSize, anchor="w", justify="left")
  786. heightLbl = tk.Label(topPane, textvariable=currentHeight, anchor="w", justify="left")
  787. widthLbl = tk.Label(topPane, textvariable=currentWidth, anchor="w", justify="left")
  788. nameLbl.pack(fill="x")
  789. sizeLbl.pack(fill="x")
  790. heightLbl.pack(fill="x")
  791. widthLbl.pack(fill="x")
  792.  
  793. root.protocol("WM_DELETE_WINDOW", exitProgram)
  794. root.mainloop()
  795. sys.exit()
  796.  
  797. def DEBUGPrintImageData():
  798. print currentImage.height()
  799. print currentImage.width()
  800.  
  801. def exitProgram():
  802. sys.exit()
  803.  
  804. FLDtoPAK_GUI()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement