128 lines
4.4 KiB
Python
128 lines
4.4 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
import os
|
|
import random
|
|
import sys
|
|
import time
|
|
from pathlib import Path
|
|
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
|
if str(PROJECT_ROOT) not in sys.path:
|
|
sys.path.insert(0, str(PROJECT_ROOT))
|
|
|
|
|
|
def parse_args():
|
|
parser = argparse.ArgumentParser(description="Render a real Mice menu screen to a PNG preview")
|
|
parser.add_argument("--output", default="/tmp/mice_menu_preview.png", help="Output PNG path")
|
|
parser.add_argument("--screen", choices=("start", "pause", "level_intro"), default="start")
|
|
parser.add_argument("--difficulty", choices=("easy", "normal", "hard", "medium"), default="hard")
|
|
parser.add_argument("--level", type=int, default=0, help="0-based level index")
|
|
parser.add_argument("--resolution", default="1280x720", help="Preview resolution, for example 1280x720")
|
|
parser.add_argument("--seed", type=int, default=1337, help="Random seed for deterministic previews")
|
|
parser.add_argument("--animation-ms", type=int, default=1200, help="Start-menu GIF timestamp in milliseconds")
|
|
return parser.parse_args()
|
|
|
|
|
|
def configure_environment(args):
|
|
os.environ.setdefault("MICE_PROJECT_ROOT", str(PROJECT_ROOT))
|
|
os.environ.setdefault("SDL_VIDEODRIVER", "dummy")
|
|
os.environ.setdefault("SDL_AUDIODRIVER", "dummy")
|
|
os.environ.setdefault("SDL_RENDER_DRIVER", "software")
|
|
os.environ.setdefault("MICE_DISABLE_JOYSTICK", "1")
|
|
os.environ["RESOLUTION"] = args.resolution
|
|
|
|
|
|
def build_game(args):
|
|
from engine import maze, sdl2 as engine
|
|
from rats import MiceMaze
|
|
|
|
original_show_intro = engine.GameWindow.show_intro
|
|
original_load_joystick = engine.GameWindow.load_joystick
|
|
original_start_game = MiceMaze.start_game
|
|
|
|
def preview_start_game(self):
|
|
self.start_menu_animation_started_at = time.monotonic()
|
|
self.current_level_music = self._resolve_level_music(self.current_level)
|
|
self._valid_positions = None
|
|
self.run_recorded = False
|
|
self.ammo = {
|
|
"bomb": {"count": 2, "max": 8},
|
|
"nuclear": {"count": 1, "max": 1},
|
|
"mine": {"count": 2, "max": 4},
|
|
"gas": {"count": 2, "max": 4},
|
|
}
|
|
self.blood_stains = {}
|
|
self.background_texture = None
|
|
self.blood_layer_sprites.clear()
|
|
self.cave_foreground_tiles.clear()
|
|
self.game_end = (False, None)
|
|
self.game_status = "start_menu"
|
|
self.menu_screen = "start"
|
|
self.units.clear()
|
|
self.unit_positions.clear()
|
|
self.unit_positions_before.clear()
|
|
self.points = 0
|
|
self.pointer = (self.map.width // 2, self.map.height // 2)
|
|
self.scroll_cursor()
|
|
|
|
engine.GameWindow.show_intro = lambda self, *a, **k: None
|
|
engine.GameWindow.load_joystick = lambda self: None
|
|
MiceMaze.start_game = preview_start_game
|
|
try:
|
|
game = MiceMaze(maze.get_default_map_source(), level_index=args.level)
|
|
finally:
|
|
engine.GameWindow.show_intro = original_show_intro
|
|
engine.GameWindow.load_joystick = original_load_joystick
|
|
MiceMaze.start_game = original_start_game
|
|
|
|
game.render_engine.audio = False
|
|
game._apply_difficulty(args.difficulty, persist=False)
|
|
game.start_menu_animation_started_at = time.monotonic() - args.animation_ms / 1000
|
|
return game
|
|
|
|
|
|
def render_screen(game, screen_name):
|
|
renderer = game.render_engine.renderer
|
|
renderer.clear()
|
|
game.draw_maze()
|
|
|
|
if screen_name == "start":
|
|
game.game_status = "start_menu"
|
|
game.menu_screen = "start"
|
|
game.render_start_menu()
|
|
elif screen_name == "pause":
|
|
game.game_status = "paused"
|
|
game.menu_screen = None
|
|
game.render_pause_menu()
|
|
else:
|
|
game.game_status = "start_menu"
|
|
game.menu_screen = "level_intro"
|
|
game.render_engine.dialog(
|
|
f"Level {game.current_level + 1}",
|
|
subtitle=f"Points: {game.points}\nPress Return to begin",
|
|
image=game.assets["BMP_WEWIN"],
|
|
)
|
|
|
|
renderer.present()
|
|
|
|
|
|
def main():
|
|
args = parse_args()
|
|
configure_environment(args)
|
|
random.seed(args.seed)
|
|
|
|
game = build_game(args)
|
|
output_path = Path(args.output).expanduser()
|
|
|
|
try:
|
|
render_screen(game, args.screen)
|
|
saved_path = game.render_engine.save_frame(output_path)
|
|
print(saved_path)
|
|
finally:
|
|
game.render_engine.close()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main()) |