コード例 #1
0
ファイル: cli.py プロジェクト: Sickelmo83/quake-cli-tools
def main():
    parser = Parser(
        prog='bsp2wad',
        description='Default action is to create a wad archive from '
        'miptextures extracted from the given bsp file.'
        '\nIf list is omitted, pak will use stdin.',
        epilog='example: bsp2wad e1m1.bsp => creates the wad file e1m1.wad')

    parser.add_argument('list',
                        nargs='*',
                        action=ResolvePathAction,
                        default=read_from_stdin())

    parser.add_argument('-d',
                        metavar='file.wad',
                        dest='dest',
                        default=os.getcwd(),
                        action=ResolvePathAction,
                        help='wad file to create')

    parser.add_argument('-q',
                        dest='quiet',
                        action='store_true',
                        help='quiet mode')

    parser.add_argument(
        '-v',
        '--version',
        dest='version',
        action='version',
        help=argparse.SUPPRESS,
        version=f'{parser.prog} version {qcli.bsp2wad.__version__}')

    args = parser.parse_args()

    if not args.list:
        parser.error('the following arguments are required: list')

    miptextures = []

    for file in args.list:
        if not bsp.is_bspfile(file):
            print('{0}: cannot find or open {1}'.format(parser.prog, file),
                  file=sys.stderr)
            continue

        bsp_file = bsp.Bsp.open(file)
        miptextures += [
            mip for mip in bsp_file.miptextures
            if mip and mip.name not in [n.name for n in miptextures]
        ]

    if args.dest == os.getcwd():
        wad_path = os.path.dirname(file)

        if len(args.list) == 1:
            wad_name = f'{os.path.basename(file).split(".")[0]}.wad'

        else:
            wad_name = 'out.wad'

        args.dest = os.path.join(wad_path, wad_name)

    dir = os.path.dirname(args.dest) or '.'
    if not os.path.exists(dir):
        os.makedirs(dir)

    with wad.WadFile(args.dest, mode='w') as wad_file:
        if not args.quiet:
            print(f'Archive: {os.path.basename(args.dest)}')

        for miptex in miptextures:
            if not miptex:
                continue

            buff = io.BytesIO()
            wad.Miptexture.write(buff, miptex)
            buff.seek(0)

            info = wad.WadInfo(miptex.name)
            info.file_size = 40 + len(miptex.pixels)
            info.disk_size = info.file_size
            info.compression = wad.CompressionType.NONE
            info.type = wad.LumpType.MIPTEX

            if not args.quiet:
                print(f' adding: {info.filename}')

            wad_file.writestr(info, buff)

    sys.exit(0)
コード例 #2
0
def main():
    parser = Parser(
        prog='pak',
        description='Default action is to add or replace pak files '
                    'entries from list.\nIf list is omitted, pak will '
                    'use stdin.',
        epilog='example: pak tex.pak image.png => adds image.png to tex.pak'
    )

    parser.add_argument(
        'file',
        metavar='file.pak',
        action=ResolvePathAction,
        help='pak file to create'
    )

    parser.add_argument(
        'list',
        nargs='*',
        action=ResolvePathAction,
        default=read_from_stdin()
    )

    parser.add_argument(
        '-q',
        dest='quiet',
        action='store_true',
        help='quiet mode'
    )

    parser.add_argument(
        '-v', '--version',
        dest='version',
        action='version',
        help=argparse.SUPPRESS,
        version='{} version {}'.format(parser.prog, qcli.__version__)
    )

    args = parser.parse_args()

    if not args.list:
        parser.error('the following arguments are required: list')

    dir = os.path.dirname(args.file) or '.'
    if not os.path.exists(dir):
        os.makedirs(dir)

    filemode = 'a'
    if not os.path.isfile(args.file):
        filemode = 'w'

    with pak.PakFile(args.file, filemode) as pak_file:
        if not args.quiet:
            print(f'Archive: {os.path.basename(args.file)}')

        # Process input files
        for file in args.list:
            # Walk directories
            if os.path.isdir(file):
                for root, dirs, files in os.walk(file):
                    for name in [f for f in files if not f.startswith('.')]:
                        fullpath = os.path.join(root, name)
                        relpath = os.path.relpath(fullpath, os.getcwd())

                        if not args.quiet:
                            print(f'  adding: {relpath}')

                        pak_file.write(relpath)

            else:
                relpath = os.path.relpath(file, os.getcwd())

                if not args.quiet:
                    print(f'  adding: {relpath}')

                pak_file.write(relpath)

    sys.exit(0)
コード例 #3
0
ファイル: cli.py プロジェクト: onlyquake/quake-cli-tools
def main():
    """CLI entrypoint"""

    # Create and configure argument parser
    parser = Parser(
        prog='wad',
        description='Default action is to add or replace wad file entries from'
        ' list.\nIf list is omitted, wad will use stdin.',
        formatter_class=argparse.RawTextHelpFormatter,
        epilog='example:\n  wad tex.wad image.png => adds image.png to tex.wad'
    )

    parser.add_argument('file',
                        metavar='file.wad',
                        action=ResolvePathAction,
                        help='wad file to add entries to')

    parser.add_argument('list',
                        nargs='*',
                        action=ResolvePathAction,
                        default=read_from_stdin())

    parser.add_argument('-t',
                        dest='type',
                        default='MIPTEX',
                        choices=['LUMP', 'QPIC', 'MIPTEX'],
                        help='list data type [default: MIPTEX]')

    parser.add_argument('-q',
                        dest='quiet',
                        action='store_true',
                        help='quiet mode')

    parser.add_argument('-v',
                        '--version',
                        dest='version',
                        action='version',
                        version='{} version {}'.format(parser.prog,
                                                       qcli.__version__))

    # Parse the arguments
    args = parser.parse_args()

    if not args.list:
        parser.error('the following arguments are required: list')

    if args.quiet:

        def log(message):
            pass

    else:

        def log(message):
            print(message)

    # Ensure directory structure
    dir = os.path.dirname(args.file) or '.'
    os.makedirs(dir, exist_ok=True)

    filemode = 'a'
    if not os.path.isfile(args.file):
        filemode = 'w'

    with wad.WadFile(args.file, filemode) as wad_file:
        log(f'Archive: {os.path.basename(args.file)}')

        # Flatten out palette
        palette = []
        for p in quake.palette:
            palette += p

        # Create palette image for Image.quantize()
        palette_image = Image.frombytes('P', (16, 16), bytes(palette))
        palette_image.putpalette(palette)

        # Process input files
        for file in args.list:
            if args.type == 'LUMP':
                log(f'  adding: {file}')
                wad_file.write(file)

            elif args.type == 'QPIC':
                img = Image.open(file).convert(mode='RGB')
                img = img.quantize(palette=palette_image)
                pixels = img.tobytes()
                name = os.path.basename(file).split('.')[0]

                qpic = lmp.Lmp()
                qpic.width = img.width
                qpic.height = img.height
                qpic.pixels = pixels

                buff = io.BytesIO()
                lmp.Lmp.write(buff, qpic)
                file_size = buff.tell()
                buff.seek(0)

                info = wad.WadInfo(name)
                info.file_size = file_size
                info.disk_size = info.file_size
                info.compression = wad.CompressionType.NONE
                info.type = wad.LumpType.QPIC

                log(f'  adding: {file}')

                wad_file.writestr(info, buff)

            else:
                try:
                    img = Image.open(file).convert(mode='RGB')
                    img = img.quantize(palette=palette_image)

                    name = os.path.basename(file).split('.')[0]

                    mip = wad.Miptexture()
                    mip.name = name
                    mip.width = img.width
                    mip.height = img.height
                    mip.offsets = [40]
                    mip.pixels = []

                    # Build mip maps
                    for i in range(4):
                        resized_image = img.resize(
                            (img.width // pow(2, i), img.height // pow(2, i)))
                        data = resized_image.tobytes()
                        mip.pixels += struct.unpack(f'<{len(data)}B', data)
                        if i < 3:
                            mip.offsets += [mip.offsets[-1] + len(data)]

                    buff = io.BytesIO()
                    wad.Miptexture.write(buff, mip)
                    buff.seek(0)

                    info = wad.WadInfo(name)
                    info.file_size = 40 + len(mip.pixels)
                    info.disk_size = info.file_size
                    info.compression = wad.CompressionType.NONE
                    info.type = wad.LumpType.MIPTEX

                    log(f'  adding: {file}')

                    wad_file.writestr(info, buff)

                except:
                    parser.error(sys.exc_info()[1])

    sys.exit(0)