# Python tool to convert an image to map for the Anarch game. The input image # has to be in gif format. # # by drummyfish # released under CC0 1.0. import sys from PIL import Image elementTypes = [ "NONE", "BARREL", "HEALTH", "BULLETS", "ROCKETS", "PLASMA", "TREE", "FINISH", "TELEPORT", "TERMINAL", "COLUMN", "CARD0", "CARD1", "CARD2", "LOCK0" ] propertyTypes = [ "ELEVATOR", "SQUEEZER", "DOOR" ] image = Image.open(sys.argv[1]) pixels = image.load() palette = [] paletteInverse = [0 for i in range(256)] x = 5 y = 69 i = 0 # load the palette/sca for i in range(256): if i % 64 == 0: x = 5 y += 1 palette.append(pixels[(x,y)]) paletteInverse[pixels[(x,y)]] = i x += 1 def getPixel(x,y): return paletteInverse[pixels[(x,y)]] def loadTileDict(x,y): result = [] for i in range(64): texture = getPixel(x + i,y + 31) if texture > 6: raise(Exception("Texture index can't be higher than 6.")) height = 0 for j in range(31): if getPixel(x + i,y + 30 - j) == 7: break height += 1 result.append((texture,height)) return result def defineName(n): c = chr(ord("A") + n) return c + c floorDict = loadTileDict(5,37) ceilDict = loadTileDict(5,5) floorColor = getPixel(41,122) ceilColor = getPixel(41,118) backgroundTex = getPixel(41,126) doorTex = getPixel(41,130) playerStart = [0,0,0] textures = [] elements = [] defines = [] levelMap = [[(0,False) for i in range(64)] for j in range(64)] # load the map for y in range(64): for x in range(64): n = getPixel(70 + x,5 + y) if n < 64: levelMap[x][y] = (n,False) else: # tile with special property, create a define for it prop = n / 64 - 1 tile = n % 64 defNum = -1 for i in range(len(defines)): if defines[i] == (tile,prop): defNum = i break if defNum == -1: # not found: defNum = len(defines) defines.append((tile,prop)) levelMap[x][y] = (defNum,True) # load elements playerFound = False for y in range(64): for x in range(64): n = getPixel(x + 70, y + 70) if n < len(elementTypes): elements.append((n,x,y)) elif n >= 240: if playerFound: raise(Exception("Multiple player starting positions specified.")) playerStart = [x,y,(n - 240) * 16] playerFound = True if not playerFound: raise(Exception("Player starting position not specified.")) if len(elements) > 128: raise(Exception("More than 128 level elements.")) for i in range(128 - len(elements)): elements.append((0,0,0)) # load textures x = 41 y = 114 for i in range(6): textures.append(getPixel(x,y)) x += 4 def numAlign(n): return str(n) + "," + (" " if n < 10 else "") def mapXScale(): r = " // " for i in range(64): r += str(i).ljust(2) + " " return r + "\n" def printC(): result = "" result += " { // level\n" result += " { // mapArray\n" result += " #define o 0\n" for i in range(len(defines)): result += " #define " + defineName(i) + " (" + str(defines[i][0]) + " | SFG_TILE_PROPERTY_" + propertyTypes[defines[i][1]] + ")\n" result += mapXScale() for y in range(64): result += "/*" + str(y).ljust(2) + "*/ " for x in range(64): item = levelMap[x][y] if not item[1]: result += ("o " if item[0] == 0 else str(item[0]).ljust(2)) else: result += defineName(item[0]) result += "," if y < 63 or x < 63 else " " result += " /*" + str(y).ljust(2) + "*/ \n" result += mapXScale() for i in range(len(defines)): result += " #undef " + defineName(i) + "\n" result += " #undef o\n" result += " },\n" result += " { // tileDictionary\n " for i in range(64): result += "SFG_TD(" + str(floorDict[i][1]).rjust(2) + "," + str(ceilDict[i][1]).rjust(2) + "," + str(floorDict[i][0]) + "," + str(ceilDict[i][0]) + ")" result += "," if i != 63 else " " if (i + 1) % 4 == 0: result += " // " + str(i - 3) + " \n " result += "}, // tileDictionary\n" s = "" first = True for t in textures: if first: first = False else: s += "," s += str(t).ljust(2) result += " {" + s + "}, // textureIndices\n" result += " " + numAlign(doorTex) + " // doorTextureIndex\n" result += " " + numAlign(floorColor) + " // floorColor\n" result += " " + numAlign(ceilColor) + " // ceilingColor\n" result += " {" + str(playerStart[0]).ljust(2) + ", " + str(playerStart[1]).ljust(2) + ", " + str(playerStart[2]).ljust(3) + "}, // player start: x, y, direction\n" result += " " + numAlign(backgroundTex) + " // backgroundImage\n" result += " { // elements\n" even = True i = 0 for e in elements: if even: result += " " result += "{SFG_LEVEL_ELEMENT_" + elementTypes[e[0]] + ", {" + str(e[1]) + "," + str(e[2]) + "}}" if i < 127: result += "," if not even: result += "\n" even = not even i += 1 result += " }, // elements\n" result += " } // level\n" print(result) printC()