forked from DevRubicate/smb3
-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgenerate_roms.py
107 lines (85 loc) · 3.81 KB
/
generate_roms.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import os
import subprocess
from shutil import move
import argparse
import hashlib
def read_original_config():
original_content = ""
with open("config.asm", "r") as f:
original_content = f.read()
return original_content
def write_updated_config(config, original_content: str):
updated_content = original_content
for key, value in config.items():
prefix = f"{key} ="
new_line = f"{prefix} {value}"
updated_content = "\n".join([
new_line if line.startswith(prefix) else line
for line in updated_content.split("\n")
])
with open("config.asm", "w") as f:
f.write(updated_content)
def extract_include_options(original_content):
include_options = {}
for line in original_content.split("\n"):
if line.startswith("INCLUDE"):
key, value = line.strip().split("=")
include_options[key.strip()] = int(value.strip())
return include_options
def generate_configurations(include_test_levels, include_demo_levels):
original_content = read_original_config()
include_options = extract_include_options(original_content)
# Do not consider additional levels as options.
options = list(include_options.keys())
options.remove('INCLUDE_TEST_LEVELS')
options.remove('INCLUDE_DEMO_LEVELS')
for i in range(2 ** len(options)):
configuration = {option: (i >> j) & 1 for j, option in enumerate(options)}
configuration['INCLUDE_TEST_LEVELS'] = include_test_levels
configuration['INCLUDE_DEMO_LEVELS'] = include_demo_levels
# Write the updated content to the file
write_updated_config(configuration, original_content)
yield configuration
def create_rom_filename(config):
enabled_options = [key[8:].lower() for key, value in config.items() if value]
return "_".join(enabled_options) + ".nes" if enabled_options else "smb3.nes"
def parse_command_line_args():
parser = argparse.ArgumentParser(description="Generate ROM files with different configurations.")
parser.add_argument('--include_test_levels', type=int, help="Set INCLUDE_TEST_LEVELS (0 or 1)")
parser.add_argument('--include_demo_levels', type=int, help="Set INCLUDE_DEMO_LEVELS (0 or 1)")
return parser.parse_args()
def compute_file_hash(file_path):
hasher = hashlib.sha256()
with open(file_path, 'rb') as f:
while chunk := f.read(8192):
hasher.update(chunk)
return hasher.hexdigest()
def check_for_duplicates(file_path, existing_hashes):
file_hash = compute_file_hash(file_path)
if file_hash in existing_hashes:
return True
existing_hashes.add(file_hash)
return False
def main():
args = parse_command_line_args()
# Set INCLUDE_TEST_LEVELS and INCLUDE_DEMO_LEVELS based on command line arguments
include_test_levels = args.include_test_levels if args.include_test_levels is not None else 0
include_demo_levels = args.include_demo_levels if args.include_demo_levels is not None else 0
existing_hashes = set()
for config in generate_configurations(include_test_levels, include_demo_levels):
# Run the 'make' command with the working directory set to './'
try:
subprocess.run(["make"], check=True, cwd="./")
except subprocess.CalledProcessError as e:
print(f"Error: {e}")
break # Stop the script if 'make' command returns an error
# Move the generated smb3.nes file to the ROMS folder
if os.path.exists("smb3.nes"):
filename = create_rom_filename(config)
if check_for_duplicates("smb3.nes", existing_hashes):
print(f"Warning: Duplicate file found, skipping {filename}")
continue
move("smb3.nes", os.path.join("ROMS", filename))
print("Finished!")
if __name__ == "__main__":
main()