Advertisement
Guest User

JungleBookScript

a guest
Oct 19th, 2011
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.83 KB | None | 0 0
  1. import Image
  2. import os.path
  3. import itertools
  4. import binascii
  5.  
  6. #------------------------------------------------------------------------------
  7. class PpuSprite:
  8.    def __init__(self, im):
  9.      self.image = im
  10.      self.imageData = im.getdata()
  11.      self.colorTable = im.getcolors()
  12.      self.colorTable.sort()
  13.      self.firstColorsPos = []
  14.      self.calcFirstColorsPoses()
  15.      self.indexedData = []
  16.      self.prepareIndexedData()
  17.      
  18.    def calcFirstColorsPoses(self):        
  19.      for _,colorInPalette in self.colorTable:
  20.        firstColorPos = -1
  21.        for color in self.imageData:
  22.          firstColorPos+=1
  23.          if color == colorInPalette:
  24.            break
  25.        self.firstColorsPos.append((firstColorPos,colorInPalette))
  26.      self.firstColorsPos.sort()
  27.      
  28.    def prepareIndexedData(self):
  29.      def calcColorHash(c):
  30.        return c[0]<<16 | c[1]<<8 | c[2]
  31.      colorHashes = map (lambda colorRec : calcColorHash(colorRec[1]), self.firstColorsPos)
  32.      for pixel in self.imageData:
  33.        pixelHash = calcColorHash(pixel)
  34.        colorIndex = -1
  35.        for colorHash in colorHashes:
  36.          colorIndex +=1
  37.          if pixelHash == colorHash:
  38.            break
  39.        self.indexedData.append(colorIndex)
  40.        
  41.    def isEqual(self, otherPpuSprite):
  42.      if len(self.firstColorsPos) != len(otherPpuSprite.firstColorsPos):
  43.        return False
  44.      for fcp1, fcp2 in zip(self.firstColorsPos, otherPpuSprite.firstColorsPos):
  45.        if  fcp1[0]!= fcp2[0]:
  46.          return False
  47.      if len(self.colorTable) != len(otherPpuSprite.colorTable):
  48.        return False
  49.      for colorTableRec1, colorTableRec2 in zip(self.colorTable, otherPpuSprite.colorTable):
  50.        if colorTableRec1[0] != colorTableRec2[0]:
  51.          return False
  52.      for pixel1, pixel2 in zip(self.indexedData, otherPpuSprite.indexedData):
  53.        if pixel1!=pixel2:
  54.          return False
  55.      return True
  56.      
  57. #------------------------------------------------------------------------------
  58.  
  59. def findFirstPicIndex(sprite, ppuSpriteTable):
  60.   index = -1
  61.   for ppuSprite in ppuSpriteTable:
  62.     index+=1
  63.     if ppuSprite.isEqual(sprite):
  64.       return index
  65.   return -1
  66.      
  67. def findUniquePicIndex(sprite, ppuSpriteTable):
  68.   index = -1
  69.   firstIndex = -1
  70.   for ppuSprite in ppuSpriteTable:
  71.     index+=1
  72.     if ppuSprite.isEqual(sprite):
  73.       if firstIndex!=-1:
  74.         return -1
  75.       else:
  76.         firstIndex = index
  77.   return firstIndex
  78.  
  79.  
  80. def makeLevelMap(mem, lev):
  81.   levTable = []
  82.   for l in lev:
  83.     levTable.append(findFirstPicIndex(l, mem))
  84.   return levTable
  85.  
  86. def drawLevelFromData(levelArray, ppuSpriteTable, size, vertical = False):
  87.   w,h = size
  88.   im = Image.new("RGBA", (w*8,h*8))
  89.   for i in xrange(len(levelArray)):
  90.     if vertical:
  91.       x,y = i/h, i%h
  92.     else:
  93.       x,y = i%w, i/w
  94.     ind = levelArray[i]
  95.     if (ind!=-1):
  96.       im.paste(ppuSpriteTable[ind].image, (x*8,y*8,x*8+8,y*8+8))
  97.   return im
  98.  
  99. #------------------------------------------------------------------------------
  100. def parseLevelData(fname):
  101.   f = open(fname)
  102.   lines = f.readlines()
  103.   f.close()
  104.   def parseLine(line):
  105.     ind = line.find(".BYTE")
  106.     num = line[ind+5:ind+9].lstrip(" $")
  107.     return int(num,16)
  108.   return map(parseLine, lines)
  109.  
  110. #------------------------------------------------------------------------------
  111. # levelSetNames = [
  112.     # "A139", "A739", "DDC8", "DDC8",
  113.     # "DBF4", "DC59", "AA49", "AAC0",
  114.     # "DCBE", "DD23", "AB37", "ABAE",
  115.     # "D974", "D9F4", "A7C9", "A849",
  116.     # "DA74", "DAF4", "A8C9", "A949",
  117.     # "DB74", "A9C9", "BBF3", "A825",
  118.     # "A795", "A765", "A764", "A766",
  119.     # "A7F5", "A7C5"]
  120.  
  121. #------------------------------------------------------------------------------------------------
  122. #helpers
  123. def prepareBinaries(binaryDump, levelSetNames):
  124.   f = open(binaryDump,"rb")
  125.   byt = f.read()
  126.   f.close()
  127.   for name in levelSetNames:
  128.     ptr = int(name,16)
  129.     bb = byt[ptr:ptr+256]
  130.     p = os.path.expanduser("~/desktop/jungleBook/set1_"+name+".bin")
  131.     f =open(p,"wb")
  132.     f.write(bb)
  133.     f.close()
  134. #prepareBinaries("os.path.expanduser("~/desktop/jungleBook/jungleBook2.bin", levelSetNames)
  135.  
  136. def prepareBinary(binaryDump, addrBegin, addrLen, outName):
  137.   f = open(binaryDump,"rb")
  138.   byt = f.read()
  139.   f.close()
  140.   bb = byt[addrBegin:addrBegin+addrLen]
  141.   f =open(outName,"wb")
  142.   f.write(bb)
  143.   f.close()
  144. #------------------------------------------------------------------------------------------------
  145. def parseBinData256(fname):
  146.   f = open(fname, "rb")
  147.   b = f.read()
  148.   f.close()  
  149.   return map(ord, b)
  150.  
  151. #a3a4 = parseBinData256("a3a4_1test.bin")
  152.  
  153. def loadLevelSetElement(levelSetElemName):
  154.   return parseBinData256(os.path.expanduser("~/desktop/jungleBook/set1_"+levelSetElemName+".bin"))
  155.  
  156. ##levelSet = map(loadLevelSetElement, levelSetNames)
  157.  
  158. ###b8x_inds 4F4F5151 4F4F5151 57575959 57575959
  159. ####b8x_inds = [[4,4,5,5], [4,4,5,5], [8,8,9,9], [8,8,9,9]]
  160. b8x_inds = [[5,5,4,4], [7,7,6,6], [9,9,8,8], [11,11,10,10]]
  161. ###b9x_inds = 615F615F 69676967 615F615F 69676967
  162. ###b9x_inds = [[13,12,13,12], [17,16,17,16], [13,12,13,12], [17,16,17,16]]
  163. b9x_inds = [[12,13,12,13], [14,15,14,15], [16,17,16,17], [18,19,18,19]]
  164.  
  165. def getLevelSetForCycle(levelSet,indsConst,loop):
  166.   inds = map (lambda v: v[loop], indsConst)
  167.   return map (lambda i: levelSet[i], inds)
  168.  
  169. #a3a4 = parseBinData256(os.path.expanduser("~/desktop/jungleBook/set1x_A2A3.bin"))
  170. def get4Lines(begin,end, levelSet, a3a4, step, vertCount):
  171.   cycleBegin = begin
  172.   cycleEnd   = end
  173.   a3a4ind = begin/4
  174.   line4 = []
  175.   for x in xrange(cycleBegin,cycleEnd):
  176.     if x%4==0:
  177.       a3a4ind += 1
  178.     b83,b85,b87,b89 = getLevelSetForCycle(levelSet, b8x_inds,(x+2)%4)
  179.     b93,b95,b97,b99 = getLevelSetForCycle(levelSet, b9x_inds,(x+2)%4)
  180.     line4.extend(makeLine(a3a4, a3a4ind, b83,b85,b87,b89, b93,b95,b97,b99, step, vertCount))
  181.   return line4
  182.    
  183.  
  184. def makeLine(a3a4, a3a4BaseInd, b83,b85,b87,b89, b93,b95,b97,b99, step, vertCount):
  185.   a3a4ind = a3a4BaseInd
  186.   lines = []
  187.   for globalRepeat in xrange(vertCount): ##5(screen size)
  188.     predInd = a3a4[a3a4ind]
  189.     ind2a,ind2b = -1,-1
  190.     if predInd<128:
  191.       ind2a = b83[predInd]
  192.       ind2b = b87[predInd]
  193.     else:
  194.       ind2a = b85[predInd]
  195.       ind2b = b89[predInd]
  196.      
  197.     res = [-1]*4
  198.     if ind2a<128:
  199.       res[0],res[1] = b93[ind2a], b97[ind2a]
  200.     else:
  201.       res[0],res[1] = b95[ind2a], b99[ind2a]
  202.     if ind2b<128:
  203.       res[2],res[3] = b93[ind2b], b97[ind2b]
  204.     else:
  205.       res[2],res[3] = b95[ind2b], b99[ind2b]
  206.     lines.extend(res)
  207.     a3a4ind+=step
  208.   return lines
  209.  
  210. #>>> prepareBinary(binPath, 0xA138, 0x2000, outPath) #level 1 start address
  211. #>>> a3a4 = parseBinData256(outPath)
  212. #>>> ll = get4Lines(0,96*4)
  213. #>>> drawLevelFromData(ll, sprites,(96*4,16*4),True).show()
  214.  
  215. #---
  216. #helpers
  217. def txt2bin(inname,outname):
  218.   f = open(inname,"rt")
  219.   l = f.readlines()
  220.   l = l[0]
  221.   f.close()
  222.   bb = binascii.a2b_hex(l)
  223.   f = open(outname,"wb")
  224.   f.write(bb)
  225.   f.close()
  226.  
  227. def str2SetAddr(trr):
  228.       res = []
  229.       while trr!="":
  230.         res.append(trr[:4])
  231.         trr = trr[4:]
  232.       res2 = map (lambda v: v[2:]+v[:2], res)
  233.       return res2
  234. #---
  235. def colorReplace(im, cmap):
  236.   d = im.getdata()
  237.   nd = []
  238.   for pix in d:
  239.     for c,r in cmap:
  240.       if pix == c:
  241.         nd.append(r)
  242.   imgb = Image.new("RGB", im.size)
  243.   imgb.putdata(nd)
  244.   return imgb
  245. #---
  246.  
  247. def makeJob (binaryName, spritesName, addr, baseAddrSet, w,h, levelNo):
  248.   tempName1 = binaryName+".a2a3."+str(levelNo)+".bin"
  249.  
  250.   imNameTable = Image.open(spritesName)
  251.   nameSize = imNameTable.size
  252.   nameTable = [imNameTable.crop((x,y,x+8,y+8)) for y,x in itertools.product(xrange(0,nameSize[1],8),xrange(0,nameSize[0],8))]
  253.   sprites = map (lambda im: PpuSprite(im),nameTable)
  254.  
  255.   prepareBinary(binaryName, addr, 0x2000, tempName1)
  256.   a3a4 = parseBinData256(tempName1)
  257.  
  258.   prepareBinaries(binaryName, baseAddrSet)
  259.   levelSet = map(loadLevelSetElement, baseAddrSet)
  260.   ##print baseAddrSet
  261.   ##print a3a4[0:50]
  262.   ll = get4Lines(0,w*4, levelSet, a3a4, w,h)
  263.   drawLevelFromData(ll, sprites,(w*4,h*4),True).show()
  264.  
  265.  
  266. #------------------------------------------------------------------------------
  267. ##def main():
  268. imNameTable = Image.open(os.path.expanduser("~/desktop/jungleBook/jungleBookTable1.png"))
  269. imLevelTable = Image.open(os.path.expanduser("~/desktop/jungleBook/jungleBookLevel1.png"))
  270.  
  271. nameSize = imNameTable.size
  272. levelSize = imLevelTable.size
  273. nameTable = [imNameTable.crop((x,y,x+8,y+8)) for y,x in itertools.product(xrange(0,nameSize[1],8),xrange(0,nameSize[0],8))]
  274. levelTable = [imLevelTable.crop((x,y,x+8,y+8)) for y,x in itertools.product(xrange(0,levelSize[1],8),xrange(0,levelSize[0],8))]
  275. ppuSpriteMemTable = map (lambda im: PpuSprite(im),nameTable)
  276. ppuSpriteLvlTable = map (lambda im: PpuSprite(im),levelTable)
  277. #mapLevel = makeLevelMap(ppuSpriteMemTable, ppuSpriteLvlTable)
  278. #return mapLevel
  279.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement