从GBA时代就知道,从卡带dump下来的rom并不是器实际容量,而是闪存芯片的容量。例如rom的实际用了20M,但生产卡带也需要使用32MB的闪存芯片,这样就有12MB是没用的填充空白数据。那时候烧录卡内置的容量也就128MB,256MB,当然寸M必争了。
到NDS的时候基本上rom都会有几MB到几十MB的盈余,那个时候烧录卡所用的micro sd卡普遍容量还是比较吃紧的,把这个空白部分去掉能省出多装几个rom的容量。
到3DS的rom,更夸张了,大多能有几百MB到上G的空白数据,所以就算现在的micro sd容量很富裕了,但是裁减一下还是能省出很大一块空间。
GBA的时代,有的烧录卡的烧录工具自带这个功能。
NDS的时候,好不容易找到了Linux下的裁减工具,既不好用也不支持批量处理。
3DS的时候,那时它还没破解所以耍了一段时间卖了。最近买了个二手3DS,配上gateway烧录卡,又把rom裁减这回事想起来了,不过跟小时候的区别是,现在直接自己写一个就好了。时间真是快啊……
从前向后扫:
#!/usr/bin/env python2.7
import sys, os
chunksize = 1024 * 200
def trunc_tail(infile):
with open(infile, 'r') as fh:
currentByte = fh.read(chunksize)
position = fh.tell()
while True:
nextbyte = fh.read(chunksize)
if nextbyte == "":
break
elif currentByte != nextbyte:
if len(currentByte) != len(nextbyte):
if currentByte[-len(nextbyte):] == nextbyte:
continue
position = fh.tell()
currentByte = nextbyte
sys.stdout.write('\r{0}'.format(position))
sys.stdout.flush()
sys.stdout.write('\n')
if os.stat(infile).st_size != position:
with open(infile, 'ab') as wh:
wh.truncate(position)
if __name__ == '__main__':
for f in sys.argv[1:]:
trunc_tail(f)
从后向前扫:
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 | #!/usr/bin/env python2.7
import sys, os
chunksize = 1024
def trunk_tail(infile):
filesize = os.stat(infile).st_size
blank = ' ' * (len(str(filesize)) + 1)
sys.stdout.write('{0}'.format(filesize))
sys.stdout.flush()
with open(infile, 'rb') as fh:
finalpos = filesize
for cks in (chunksize*500, chunksize*50, chunksize, chunksize/50, 10):
if finalpos < cks*2:
continue
fh.seek(finalpos-cks)
preblock = fh.read(cks)
for pos in xrange(finalpos-cks*2, -1, -cks):
fh.seek(pos)
currblock = fh.read(cks)
if preblock != currblock:
if pos != finalpos - cks * 2:
finalpos = pos + cks
break
sys.stdout.write('\r{0}\r{1}'.format(blank,pos))
sys.stdout.flush()
sys.stdout.write('\r{0}\r{1}'.format(blank,finalpos))
sys.stdout.write('\n')
if finalpos < filesize:
with open(infile, 'ab') as wh:
wh.truncate(finalpos)
if __name__ == '__main__':
for f in sys.argv[1:]:
trunk_tail(f)
|
一般来说从后向前速度应该会更快。