From e78453d6bd0bbe47f919d6e6e64c5606f0a11c26 Mon Sep 17 00:00:00 2001 From: yrriban Date: Mon, 7 Apr 2025 02:19:25 -0400 Subject: [PATCH] Initial checkin for dcc v2. Includes support for play/record/fabricate. --- dcc/__init__.py | 0 dcc/__main__.py | 5 +++++ dcc/config.py | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ dcc/fabricate.py | 16 +++++++++++++ dcc/main.py | 29 ++++++++++++++++++++++++ dcc/play.py | 13 +++++++++++ dcc/record.py | 15 +++++++++++++ setup.py | 30 +++++++++++++++++++++++++ 8 files changed, 166 insertions(+) create mode 100644 dcc/__init__.py create mode 100644 dcc/__main__.py create mode 100644 dcc/config.py create mode 100644 dcc/fabricate.py create mode 100644 dcc/main.py create mode 100644 dcc/play.py create mode 100644 dcc/record.py create mode 100644 setup.py diff --git a/dcc/__init__.py b/dcc/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dcc/__main__.py b/dcc/__main__.py new file mode 100644 index 0000000..6383388 --- /dev/null +++ b/dcc/__main__.py @@ -0,0 +1,5 @@ +import sys +from dcc.main import main + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) diff --git a/dcc/config.py b/dcc/config.py new file mode 100644 index 0000000..1cf6612 --- /dev/null +++ b/dcc/config.py @@ -0,0 +1,58 @@ +import io +import pathlib +import os +import re + +DOOM=pathlib.Path.home().joinpath("doom") +DSDA_DIR=DOOM.joinpath("dsda-doom") +DSDA_VER='0.28.3' +DSDA=DSDA_DIR.joinpath('dsda-doom-{}-Linux.appimage'.format(DSDA_VER)) +IWADS=DOOM.joinpath("iwads") +PWADS=DOOM.joinpath("pwads") +DEMOS=DOOM.joinpath("demos") +OUTPUT=DOOM.joinpath("fabricate") + +DEFAULT_IWAD=IWADS.joinpath("DOOM2.WAD") + +def DsdaPreamble(wad, mapstr): + args = [] + pwadpath = PWADS.joinpath(wad) + iwad = DEFAULT_IWAD + iwadpath = pwadpath.joinpath("iwad") + if iwadpath.exists(): + with io.open(iwadpath) as f: + iwad = f.read().strip() + ".WAD" + args = args + ["-iwad", iwad] + + wads = sorted(pwadpath.glob('*.wad', case_sensitive=False)) + if len(wads) > 0: + args = args + ["-file"] + wads + + dehs = sorted(pwadpath.glob('*.deh', case_sensitive=False)) + if len(dehs) > 0: + args = args + ["-deh"] + dehs + + complevel = pwadpath.joinpath("complevel") + if not complevel.exists(): + raise Exception("No complevel set in PWAD dir {}.".format(pwadpath)) + + with io.open(complevel) as f: + args = args + ["-complevel", f.read().strip()] + + args = args + ["-skill", "4"] + args = args + ["-warp", mapstr] # TODO: UDoom + return args + +def DemoInPath(wad, mapstr): + candidates = [x for x in DEMOS.joinpath(wad).glob("{}_map{}*.lmp".format(wad, mapstr))] + if len(candidates) == 0: + raise Exception("no suitable demo candidates for WAD {} MAP {}.", wad, mapstr) + if len(candidates) == 1: + return candidates[0] + return sorted(filter(lambda s : re.search("-", str(s)), candidates))[-1] + +def DemoOutPath(wad, mapstr): + return DEMOS.joinpath(wad).joinpath("{}_map{}.lmp".format(wad, mapstr)) + +def VideoPath(wad, mapstr): + return OUTPUT.joinpath(wad).joinpath("{}_map{}.mp4".format(wad, mapstr)) diff --git a/dcc/fabricate.py b/dcc/fabricate.py new file mode 100644 index 0000000..31f3ac7 --- /dev/null +++ b/dcc/fabricate.py @@ -0,0 +1,16 @@ +from cliff.command import Command +import dcc.config +import subprocess + +class Fabricate(Command): + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + parser.add_argument('wad') + parser.add_argument('map') + return parser + + def take_action(self, parsed_args): + subprocess.run([dcc.config.DSDA] + + dcc.config.DsdaPreamble(parsed_args.wad, parsed_args.map) + + ["-timedemo", dcc.config.DemoInPath(parsed_args.wad, parsed_args.map)] + + ["-viddump", dcc.config.VideoPath(parsed_args.wad, parsed_args.map)]) diff --git a/dcc/main.py b/dcc/main.py new file mode 100644 index 0000000..877ec9d --- /dev/null +++ b/dcc/main.py @@ -0,0 +1,29 @@ +import sys + +from cliff.app import App +from cliff.commandmanager import CommandManager + +class DCC(App): + def __init__(self): + super().__init__( + description="Doom Command Center", + version="0.0.1", + command_manager=CommandManager("dcc"), + deferred_help=True, + ) + + def initialize_app(self, argv): + pass + + def prepare_to_run_command(self, cmd): + pass + + def clean_up(self, cmd, result, err): + pass + +def main(argv=sys.argv[1:]): + dcc = DCC() + return dcc.run(argv) + +if __name__ == '__main__': + sys.exit(main()) diff --git a/dcc/play.py b/dcc/play.py new file mode 100644 index 0000000..2f272f6 --- /dev/null +++ b/dcc/play.py @@ -0,0 +1,13 @@ +from cliff.command import Command +import dcc.config +import subprocess + +class Play(Command): + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + parser.add_argument('wad') + parser.add_argument('map') + return parser + + def take_action(self, parsed_args): + subprocess.run([dcc.config.DSDA] + dcc.config.DsdaPreamble(parsed_args.wad, parsed_args.map)) diff --git a/dcc/record.py b/dcc/record.py new file mode 100644 index 0000000..98ea3ae --- /dev/null +++ b/dcc/record.py @@ -0,0 +1,15 @@ +from cliff.command import Command +import dcc.config +import subprocess + +class Record(Command): + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + parser.add_argument('wad') + parser.add_argument('map') + return parser + + def take_action(self, parsed_args): + subprocess.run([dcc.config.DSDA] + + dcc.config.DsdaPreamble(parsed_args.wad, parsed_args.map) + + ["-record", dcc.config.DemoOutPath(parsed_args.wad, parsed_args.map)]) diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..53584b1 --- /dev/null +++ b/setup.py @@ -0,0 +1,30 @@ +from setuptools import find_packages +from setuptools import setup + +PROJECT = 'dcc' + +VERSION = '0.0.1' + +long_description = '' + +setup( + name=PROJECT, + version=VERSION, + description='Doom Command Center', + long_description=long_description, + author='yrriban', + author_email='yrriban@gmail.com', + platforms=['Any'], + install_requires=['cliff'], + packages=find_packages(), + include_package_data=True, + entry_points={ + 'console_scripts': ['dcc=dcc.main:main'], + 'dcc': [ + 'play = dcc.play:Play', + 'record = dcc.record:Record', + 'fabricate = dcc.fabricate:Fabricate', + ], + }, + zip_safe=False, +)