Home | Forums — Login |
BCSV
BCSV is a data format that is used a lot in SMG games. It is used to store all the level data, collision data, and lots of other things. BCSV files can be seen like database tables. They define a number of fields, and then entries (rows) that contain values for the fields defined. Given their important usage in SMG games, modifying BCSV files is a key part in SMG hacking. Something to note is that data is not necessarily in sequential order. In certain PA files (collision flag data, which also uses the BCSV format), data is reused a multitude of times, so when parsing it's best to use the offsets from the fields instead of incrementing every time you read a field. 1. The headerBCSV files start with a header which is laid out as such:
2. The fieldsThey are located right after the header. Each field is laid out as such:
2.1. Name hashesThe names of the fields are hashed for faster lookups. Here is C# code to calculate the hash of a given field name: public static uint FieldNameToHash(string field)
{ uint ret = 0; foreach (char ch in field) { ret *= 0x1F; ret += ch; } return ret; } A list of known field name hashes can be found here. 2.2. Field typesValid field types are the following: • 0 and 3: 32-bit integer, ANDed with the bitmask and shifted right by the shift amount • 4: 16-bit integer, ANDed with the bitmask's lower 16 bits and shifted right by the shift amount • 5: 8-bit integer, ANDed with the bitmask's lower 8 bits and shifted right by the shift amount • 6: 32-bit offset to a string within the strings section • 2: 32-bit (single precision) floating point number (according to Treeki, floats aren't specific to type 2 -- to be checked) 3. The entriesThey are located right after the fields. The section is a blob of data. Each entry must be parsed accordingly to the fields defined. 4. The strings sectionIt is located right after the entries. Each string is a NULL-terminated Shift-JIS string. This section should be padded with 0x40 bytes until the file's size is aligned to a 32-bytes boundary. |
Page rendered in 0.009 seconds. (2048KB of memory used) MySQL - queries: 17, rows: 67/67, time: 0.007 seconds. |