Last active
May 15, 2016 20:05
-
-
Save Jamie0/bc7db57e316fdf80ef26c016ba9e2777 to your computer and use it in GitHub Desktop.
Ruby script to read IC3 (Myriad InstantCart) files, and format description.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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