Created
September 30, 2017 23:20
-
-
Save trysdyn/134f890a9fa4426c2616f2ae4f496865 to your computer and use it in GitHub Desktop.
A simplified version of my retro roulette script
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 | |
import os | |
import random | |
import subprocess | |
# The path to the emu, configured for single instance mode | |
# So each invocation just opens the rom in the current instance | |
launch = "D:/Emulators/Bizhawk/EmuHawk.exe" | |
# Roms dir. This assumes a specific dir layout such as: | |
# D:/ROMs/SNES/Cool Spot/Cool Spot.sfc | |
roms_dir = "D:/ROMs/" | |
# List of systems to peruse. Must be sub-dirs of roms_dir | |
systems = ["SNES", "GBA", "NES", "FDS", "TG16", "GB", "GEN", "GG", | |
"SWAN", "SMS"] | |
def get_dir_list(d): | |
"""Gets a list of sub-dirs in the given dir. | |
This is used to get a list of systems in roms_dir and to get a list of | |
rom dirs within each system sub-dir.""" | |
# This is a list comprehension. The logic breaks down to... | |
# For every item in dir 'd', check if that item is not a file (a dir) | |
# if it is, add it to a list that gets returned. | |
return [f for f in os.listdir(d) | |
if not os.path.isfile(os.path.join(d, f))] | |
# These functions that only do random.choice() are broken out because they | |
# used to be more complicated before I refactored things. I keep them broken | |
# out in case these calls end up becoming more complicated again in the future | |
def choose_game(l): | |
"""Returns a random rom from a given list of roms. This is called to pick | |
a random surviving candidate from a list of ROMs pared down by | |
choose_file()""" | |
return random.choice(l) | |
def choose_system(l): | |
"""Returns a random system from a given list of systems. This is called to | |
pick a system from the list provided in 'systems' global above.""" | |
return random.choice(l) | |
def format_filename(n): | |
"""Some light cleanup to remove leading "A" and "The" from titles, and | |
also strip dumper tags like [!], [o0], etc. Makes a printable, clean game | |
name we inject into our output.""" | |
# Strip floating "The" and "A" | |
n = n.replace(', The', '') | |
n = n.replace(', A', '') | |
# Strip file extension | |
# We have to do this despite the next strip making it redundant because | |
# sometimes on badly formatted dump filenames the next strip fails | |
n = n.rsplit('.', 1)[0] | |
# Strip parenthetical and dumper tags by splitting at the first ( | |
n = n.split('(', 1)[0] | |
return n | |
def launch_emu(rom): | |
"""Calls choose_file() on the system and directory chosen by do_choice() | |
then calls Bizhawk with the given ROM filename.""" | |
if launch: | |
# Get our full filename | |
filename = choose_file(rom) | |
# And call Bizhawk with it | |
subprocess.Popen([launch, filename]) | |
def choose_file(rom): | |
"""Given a directory of ROMs, attempts to pick the ROM most likely to be | |
playable. This follows this specific order of preference: | |
1.) Any file with [!] which means "canonical good room" | |
2.) Any file with (U) which means "NA port/English" | |
3.) Any file with T+Eng or T-Eng which means "English Translated" | |
4.) Any file with (E) which means "EU port, likely to be English" | |
5.) Any file | |
This compiles a list of valid candidates, then one is randomly chosen. | |
""" | |
# Piece together the full path for the ROM dir in question | |
d = roms_dir + rom[0] + "/" + rom[1] | |
# Get a list of all files in the dir (each file should be a ROM) | |
files = os.listdir(d) | |
# Define the strings we want to search for, in order of preference | |
matches = ["[!]", "(u)", "(ue)", "t+eng", "t-eng", "(e)"] | |
# Loop through the list and make a list of ROM candidates for selection | |
for m in matches: | |
candidates = [] | |
# If our search string is in the filename, add the ROM to the | |
# candidate list | |
for f in files: | |
if m in f.lower(): | |
candidates.append(f) | |
# If we scored any candidates, discard all non-candidates by replacing | |
# our list of files with our list of candidates. | |
if len(candidates): | |
files = candidates[:] | |
# Pick a random ROM from candidates and return the full absolute path of it | |
return d + "/" + random.choice(files) | |
def do_choice(): | |
"""Chooses a system, then chooses a game from that system. Returns the | |
system and dirname of the game.""" | |
# Choose a system | |
system = choose_system(systems) | |
# Choose a game | |
f = choose_game(get_dir_list("D:/ROMs/%s" % system)) | |
# Return the choice and the system it runs on | |
return (system, f) | |
if __name__ == "__main__": | |
print("Retro Roulette, scaled down version. Press return for a new game. ^C to quit") | |
while True: | |
input() | |
# Call do_choice() and get back (system, ROM) frex | |
# ("SNES", "D:/ROMs/SNES/Cool Spot/Cool Spot (U).sfc") | |
selection = do_choice() | |
# Format our print string for the game | |
game = format_filename("[%s] %s" % selection) | |
# Print our selection frex "[SNES] Cool Spot" | |
print(game, end="") | |
# Launch emu with the given ROM | |
launch_emu(selection) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment