Skip to content

Instantly share code, notes, and snippets.

@Jamie0
Last active May 15, 2016 20:05
Show Gist options
  • Save Jamie0/bc7db57e316fdf80ef26c016ba9e2777 to your computer and use it in GitHub Desktop.
Save Jamie0/bc7db57e316fdf80ef26c016ba9e2777 to your computer and use it in GitHub Desktop.
Ruby script to read IC3 (Myriad InstantCart) files, and format description.
#!/usr/bin/env ruby
=begin
A quick and simple script to read "ic3" (Myriad) InstantCart files.
Brief overview of the really simple InstantCart file format:
Essentially a linear array of IC titles followed by 20 spaces for carts.
A block represents a bit of data (e.g. title, cart, blank). Each "block"
is 256 bytes long. Technically, due to the InstantCart format, each IC
should only have 20 carts to it. However, we're ignoring that below.
The "title" block starts with 4 null bytes, then is followed by the ASCII
name of the IC, right padded with spaces (\x20). Overall this is 64 bytes.
The last 192 bytes of the block are just null bytes.
The "cart" block starts goes straight in, with the ASCII representation of
the AudioWall cart ID ( for example, 2933 being 32 39 33 33 ). This is
padded out for 256 bytes.
An empty block can either be all NULL bytes, or all spaces. This is still
256 bytes in length overall. This represents an empty space in the list.
I'm not really sure why it's either spaces or nuls, but it doesn't seem to
matter much.
(C) 2016 Jamie W, Insanity Radio, BSD licence
=end
file = "PersonalICs.ic3"
contents = File.read(file).split("")
@sets = {}
current_set = nil
contents.each_slice(256) do | block |
block = block.join "" # make it into a string
# Check for "empty" or the start of a new section
if block[0..3] == ("\0" * 4)
# If it's 4 NUL bytes followed by non-NUL bytes, it's a name
if block[4] != "\0"
current_set = block[4..255].strip
end
next # jump over it
end
# We should *always* start with a title set.
abort "Corrupt..?" if current_set == nil
# Comment this line out to include blank spaces in the output.
next if block == ("\x20" * 256) # All spaces = empty
@sets[current_set] = [] if !@sets[current_set]
@sets[current_set] << block.strip
end
p @sets
output = ""
# Example of encoding
@sets.each do | name, value |
abort "Too many entries in the InstantCart!" if value.length > 20
# Print the IC's name
output << "\0" * 4
output << name.ljust(60)
output << "\0" * 192
# This also works if cart is the empty string
value.each do | cart |
output << cart.ljust(256)
end
# Pad the remaining/empty carts with spaces to make Myriad happy
(1..(20 - value.length)).each do
output << "\x20" * 256
end
end
File.write("test.ic3", output)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment