Skip to content

Instantly share code, notes, and snippets.

@grindars
Created October 9, 2012 19:50
Show Gist options
  • Save grindars/3861013 to your computer and use it in GitHub Desktop.
Save grindars/3861013 to your computer and use it in GitHub Desktop.
FON file splitter
#!/usr/bin/env ruby
require "fileutils"
module MachineIO
def read_word
read(2).unpack("v")[0]
end
def read_dword
read(4).unpack("V")[0]
end
end
def parse_ne(io)
contents = []
raise "Bad MZ signature" if io.read(2) != "MZ"
io.seek 0x3C
ne_offset = io.read_dword
io.seek ne_offset
raise "Bad NE signature" if io.read(2) != "NE"
io.seek ne_offset + 0x24
res_offset = ne_offset + io.read_word
io.seek res_offset
shift = io.read_word
loop do
type = io.read_word
break if type == 0
count = io.read_word
io.seek 4, IO::SEEK_CUR
for i in 0...count
start = io.read_word << shift
size = io.read_word << shift
flags = io.read_word
id = io.read_word
handle = io.read_word
usage = io.read_word
if type == 0x8008
contents << [ start, size ]
end
end
end
contents
end
Dir.mkdir "expanded" unless File.exists? "expanded"
Dir.mkdir "fonts" unless File.exists? "fonts"
for file in Dir.entries "compressed"
next unless File.file? File.join("compressed", file)
expanded = nil
compressed = nil
begin
expanded = File.open File.join("expanded", file), "wb"
compressed = File.open File.join("compressed", file), "rb"
child = Process.spawn "msexpand", in: compressed, out: expanded, err: :err
status = Process.wait child
raise "Expanding of #{file} failed" unless $?.exitstatus == 0
ensure
expanded.close unless expanded.nil?
compressed.close unless compressed.nil?
end
end
for filename in Dir.entries "expanded"
file = File.join "expanded", filename
next unless File.file? file
File.open(file, "rb") do |io|
io.extend MachineIO
contents = parse_ne io
split = File.join "fonts", filename.split('.')[0...-1]
contents.each_with_index do |(offset, size), idx|
File.open("#{split}_#{idx}.fnt", "wb") do |dest|
io.seek offset
IO.copy_stream io, dest, size
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment