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)
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)
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)