-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
122 lines (112 loc) · 3.76 KB
/
main.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#!/usr/bin/python
# -*- coding: utf-8 -*-
import argparse
import sys
import textwrap
from os import SEEK_CUR, SEEK_END, SEEK_SET
from romhacking.common import TBL
from sms.common import ROM
from sms.data_compression import *
from utils.common import *
cmd = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description=textwrap.dedent('''\
[SMS] SIMS Compressor / Decompressor
----------------------------------------------
Tool for decompress and recompress graphics
from games developed by SIMS using LZ+RLE
algorithm.
----------------------------------------------
List of know compatible games;
- [SMS] Disney's Alladin
- [SMS] Master of Darkness
- [SMS] Masters of Combat
- [SMS] Ninja Gaiden
----------------------------------------------
For decompress:
python main.py D rom decompressed_file offset
For compress:
python main.py C rom decompressed_file offset_to_be_inserted_in_rom
''')
)
def decompress(rom_path, decompressed_data_path, codec=None, *args):
rom = ROM(rom_path, 'msb')
algorithm = None
for compression in FindAllSubclasses(Compression):
if compression[1] == codec:
algorithm = compression[0](rom)
if algorithm:
out = open(decompressed_data_path, 'wb')
data = algorithm.decompress(*args)
data_len = len(data)
print('[INFO] Decompressed Size: {:08x}'.format(data_len))
out.seek(0, 0)
out.write(data)
out.close()
print('[INFO] Finished!')
def compress(rom_path, decompressed_data_path, codec=None, *args):
offset = args[0]
rom = open(rom_path, 'r+b')
input = ROM(decompressed_data_path, 'msb')
algorithm = None
for compression in FindAllSubclasses(Compression):
if compression[1] == codec:
algorithm = compression[0](input)
if algorithm:
data = algorithm.compress()
data_len = len(data)
print('[INFO] Compressed Size: {:08x}'.format(data_len))
rom.seek(offset, 0)
rom.write(data)
rom.close()
input.close()
print('[INFO] Finished!')
if __name__ == "__main__":
cmd.add_argument(
'option',
nargs='?',
type=str,
default=None,
help='"C" for Compression / "D" for Decompression'
)
cmd.add_argument(
'rom',
nargs='?',
type=argparse.FileType('rb'),
default=sys.stdin,
help='Sega Master System / Sega Mark III ROM'
)
cmd.add_argument(
'output',
nargs='?',
type=str,
default=None,
help='Decompressed file.'
)
cmd.add_argument(
'offset',
nargs='?',
type=lambda x: int(x, 0),
default=None,
help='Offset'
)
args = cmd.parse_args()
print(cmd.description)
if args.option not in ['C','D']:
print('[ERROR] Option must be "C" for Compression or "D" for Decompression')
sys.exit(0)
if args.rom.name == '<stdin>':
print('[ERROR] An Sega Master System / Sega Mark III must be specified')
sys.exit(0)
if args.output == None:
print('[ERROR] An Output File must be specified')
sys.exit(0)
if args.offset == None:
print('[ERROR] An Offset must be specified')
sys.exit(0)
if (args.option == 'D'):
print('[INFO] Decompressing at {:08x}...'.format(args.offset))
decompress(args.rom.name, args.output, 'LZSIMS', args.offset)
else:
print('[INFO] Compressing and inserting at {:08x}...'.format(args.offset))
compress(args.rom.name, args.output, 'LZSIMS', args.offset)