Created
January 6, 2017 08:26
-
-
Save taotao54321/5eee07e35499dfa9dcfbfd8ebcf65a11 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# -*- coding: utf-8 -*- | |
"""AD&D プールオブレイディアンス (FC) マップデータ画像化 | |
マップデータ(0x400 Byte)から画像を生成する。 | |
TODO: | |
データの意味が完全にわかってない。扉でないところが扉になったりする。 | |
""" | |
import argparse | |
from PIL import Image, ImageDraw | |
MAP_COLS = 16 | |
MAP_ROWS = 16 | |
IMG_CELL_SIZE = (24, 24) | |
IMG_GRID_THICK = 1 | |
IMG_WALL_THICK = 3 | |
IMG_DOOR_WIDTH = 12 | |
IMG_SIZE = ( | |
MAP_COLS * IMG_CELL_SIZE[0] + (MAP_COLS-1) * IMG_GRID_THICK, | |
MAP_ROWS * IMG_CELL_SIZE[1] + (MAP_ROWS-1) * IMG_GRID_THICK | |
) | |
COLOR_CELL = (0x00, 0xA0, 0x00) | |
COLOR_GRID = (0x00, 0x00, 0x00) | |
COLOR_WALL = (0xFF, 0xFF, 0xFF) | |
COLOR_DOOR = (0xFF, 0x00, 0x00) | |
COLOR_EVENT = (0xFF, 0xFF, 0x00) | |
class Border: | |
def __init__(self, exists, passable): | |
self.exists = bool(exists) | |
self.passable = bool(passable) | |
class Cell: | |
def __init__(self, event, north, east, south, west): | |
self.event = event | |
self.north = north | |
self.east = east | |
self.south = south | |
self.west = west | |
class Map: | |
def __init__(self, cells): | |
self.cells = cells | |
def cell(self, col, row): | |
return self.cells[MAP_COLS*row + col] | |
def parse_map(buf): | |
size = MAP_COLS * MAP_ROWS | |
cells = [None] * size | |
for i in range(size): | |
b = buf[i::0x100] | |
# TODO: b[3] の各方角の2bitはそれぞれ別の役割があると思われるが未解析 | |
# TODO: 壁がなくても b[3] で通過可能フラグが立ってる箇所もあるが詳細不明 | |
event = b[2] | |
north = Border(b[0]&0xF0, b[3]&0b00000011) | |
east = Border(b[0]&0x0F, b[3]&0b00001100) | |
south = Border(b[1]&0xF0, b[3]&0b00110000) | |
west = Border(b[1]&0x0F, b[3]&0b11000000) | |
cells[i] = Cell(event, north, east, south, west) | |
return Map(cells) | |
def generate_img_hwall(border): | |
if not border.exists and not border.passable: return None | |
img_hwall = Image.new("RGB", (IMG_CELL_SIZE[0], IMG_WALL_THICK), COLOR_CELL) | |
draw = ImageDraw.Draw(img_hwall) | |
if border.exists: | |
draw.rectangle(((0,0), img_hwall.size), fill=COLOR_WALL) | |
if border.passable: | |
center_x = img_hwall.width // 2 | |
door_w_half = IMG_DOOR_WIDTH // 2 | |
draw.rectangle(( | |
(center_x - door_w_half, 0), | |
(center_x + door_w_half, img_hwall.height) | |
), fill=COLOR_DOOR) | |
return img_hwall | |
def generate_img_vwall(border): | |
if not border.exists and not border.passable: return None | |
img_vwall = Image.new("RGB", (IMG_WALL_THICK, IMG_CELL_SIZE[1]), COLOR_CELL) | |
draw = ImageDraw.Draw(img_vwall) | |
if border.exists: | |
draw.rectangle(((0,0), img_vwall.size), fill=COLOR_WALL) | |
if border.passable: | |
center_y = img_vwall.height // 2 | |
door_w_half = IMG_DOOR_WIDTH // 2 | |
draw.rectangle(( | |
(0, center_y - door_w_half), | |
(img_vwall.width, center_y + door_w_half) | |
), fill=COLOR_DOOR) | |
return img_vwall | |
def generate_img_cell(cell): | |
img_cell = Image.new("RGB", IMG_CELL_SIZE, COLOR_CELL) | |
draw = ImageDraw.Draw(img_cell) | |
img_north, img_south = map(generate_img_hwall, (cell.north, cell.south)) | |
img_east, img_west = map(generate_img_vwall, (cell.east, cell.west)) | |
if img_north: | |
img_cell.paste(img_north, (0, 0)) | |
if img_south: | |
img_cell.paste(img_south, (0, img_cell.height - img_south.height)) | |
if img_east: | |
img_cell.paste(img_east, (img_cell.width - img_east.width, 0)) | |
if img_west: | |
img_cell.paste(img_west, (0, 0)) | |
if cell.event: | |
center_x = img_cell.width // 2 | |
center_y = img_cell.height // 2 | |
str_event = "{:02x}".format(cell.event) | |
draw.text((center_x-6, center_y-5), str_event, fill=COLOR_EVENT) | |
return img_cell | |
def generate_img(map_): | |
img = Image.new("RGB", IMG_SIZE, COLOR_GRID) | |
for row in range(MAP_ROWS): | |
for col in range(MAP_COLS): | |
img_cell = generate_img_cell(map_.cell(col, row)) | |
img.paste(img_cell, ( | |
(IMG_CELL_SIZE[0] + IMG_GRID_THICK) * col, | |
(IMG_CELL_SIZE[1] + IMG_GRID_THICK) * row | |
)) | |
return img | |
def parse_args(): | |
ap = argparse.ArgumentParser() | |
ap.add_argument("in_", type=argparse.FileType("rb")) | |
ap.add_argument("out", type=argparse.FileType("xb")) | |
return ap.parse_args() | |
def main(): | |
args = parse_args() | |
map_ = parse_map(args.in_.read()) | |
img = generate_img(map_) | |
img.save(args.out) | |
if __name__ == "__main__": main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment