Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
139 lines (123 sloc) 3.8 KB
# メモリーカードを改竄するか
$MODIFY_MEMCARD = false
# メモリーカードのバイナリの場所
MEMCARD = "C:/NO$PSX/MEMCARD/_01_2_A_.mcd"
module DQ7
# from https://ja.wikipedia.org/wiki/%E5%B7%A1%E5%9B%9E%E5%86%97%E9%95%B7%E6%A4%9C%E6%9F%BB#CRC-32
@@checksum_poly = 0x04c11db7
@@checksum_table = []
# チェックサムのテーブルの構築
def self.init_checksum_table
@@checksum_table = (0...256).map{|i|
8.times.inject(i << 24){|c, _|
((c << 1) & 0xffffffff) ^ (c & 0x80000000 != 0 ? @@checksum_poly : 0)
}
}
end
# バイナリの先頭から124バイト目までのチェックサムを返す
def self.checksum(bin, limit124 = true)
bin2 = limit124 ? bin[0...124] : bin
c = bin2.bytes.inject(0xffffffff){|c, b|
((c << 8) & 0xffffffff) ^ @@checksum_table[((c >> 24) ^ b) & 0xff]
}
~c & 0xffffffff
end
# バイナリの先頭から124バイトに4バイトのチェックサムを追加する。元のバイナリの125バイト目以降は無視される。
def self.append_checksum(bin, limit124 = true)
bin2 = limit124 ? bin[0...124] : bin
checksum = self.checksum(bin2)
bin2 + [checksum].pack("l*")
end
self.init_checksum_table
end
AnimeMakerGap = 0x2300
def mods2AnimeMakers(mods)
res = []
mods.each{|region, hex|
bin = hex2bin(hex)
bin = DQ7.append_checksum(bin)
bin.bytes.each_with_index{|b, i|
next if b == 0
y, x = (region.first + i - AnimeMakerGap).divmod(288)
res << [x, y, b]
}
}
res
end
def AnimeMakers2mods(ams)
h = {}
ams.each{|x, y, b|
addr = first = x + 288 * y + AnimeMakerGap
first = addr - addr % 128
h[first] ||= "\x00" * 128
h[first][addr % 128] = b.chr
}
h.map{|first, bin|
[first..first+127, bin2hex(bin)]
}.sort_by{|region, _| region.first }.to_h
end
def hex2bin(hex)
[hex.tr("^0-9a-fA-F","")].pack("H*")
end
def bin2hex(bin)
hex = bin.unpack("H*")[0]
hex.scan(/.{,32}/).map{|s|
s.scan(/../) * " "
} * "\n"
end
MOD_DEFS = {
0x4180..0x41ff => "
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
D0 07 08 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 24 07
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00
",
# こっち、THEENDから直接再開するとチェックサム計算されてない?
# 0x4e00...0x4e7f => "
# 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
# 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
# 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
# 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
# 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
# 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
# 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
# 00 00 00 00 00 00 00 00 00 00 00 00
# ",
}
# チェックサムをちゃんとする
MOD_DEFS.transform_values!{|hex|
bin = hex2bin(hex)
bin = DQ7.append_checksum(bin)
bin2hex(bin)
}
# メモリーカード改竄
def modify_memcard
memcard = IO.binread(MEMCARD)
MOD_DEFS.each{|region, hex|
memcard[region] = hex2bin(hex)
}
IO.binwrite(MEMCARD, memcard)
end
def main
# チェックサム
puts"Checksum:"
MOD_DEFS.each{|region, hex|
bin = hex2bin(hex)
checksum = DQ7.checksum(bin[0...124])
puts " %x..%x: %s"%[region.first, region.last, bin2hex([checksum].pack("l*"))]
}
# アニメティカの入力形式
ams = mods2AnimeMakers(MOD_DEFS)
puts "AnimeMaker:"
ams.each{|x, y, b|
puts" %02X: (%3d,%3d)" % [b, x, y]
}
if $MODIFY_MEMCARD
modify_memcard()
end
end
main()
You can’t perform that action at this time.