TIM Resource Format

From ModdingWiki
Jump to navigation Jump to search
TIM Resource Format
Format typeArchive
Max files65,535
File Allocation Table (FAT)External + embedded
Filenames?Yes, 8.3
Metadata?None
Supports compression?No
Supports encryption?No
Supports subdirectories?No
Hidden data?No
Games

The TIM Resource Format is used by The Incredible Machine to store much of the game data.

File format

The format comprised of multiple files. The index file is a .MAP file which stores the offsets of each subfile. The subfile data is split between a number of real files, and the .MAP file also provides the filenames of these real files. In The Incredible Machine, the index file is called RESOURCE.MAP and the data files are RESOURCE.001 to RESOURCE.004.

In theory data can be read from the data files alone (without the .MAP file) however if the data is to be modified then the .MAP file will have to be updated with the new offsets.

Signature

There is no known signature, other than carefully reading the file structure and verifying it seems correct (e.g. offsets don't go past the end of the file.) The data filenames can also be read from the .MAP file and checked to see whether they exist in the current directory.

Structure

The .MAP file begins with a header:

Data type Name Description
BYTE[4] hash_idx Hash string indexes
UINT16LE fileCount Number of data files

Note that hash indexes are hardcoded in the game execuatable file as sequences 0, 1, 6, 7, but the actual .MAP file uses 0, 1, 5, 7 so the internal table will be overwritten with these new values.

This is then followed by a file structure, repeated fileCount times:

Data type Name Description
char[13] filename Filename of real data file (DOS 8.3, null terminated)
UINT16LE count Number of file entries
FILE_ENTRY[count] entry Actual file entries

A single FILE_ENTRY is defined as:

Data type Name Description
INT32LE hash Filename hash (see below)
UINT32LE offset Offset of file from start of data

To read the subfile data, the filename must be read from the .MAP file (the filename field above) along with the offset. The file identified by filename must then be opened. It should be in the same directory as the .MAP file. Seeking to offset in this newly opened file will result in the file pointer being at the start of the subfile header:

Data type Name Description
char[13] filename Filename of subfile (DOS 8.3, null terminated)
UINT32LE len Length of subfile data, in bytes
BYTE[len] content Subfile content

If the .MAP file is not being used, the data files simply consist of the above subfile header and data concatenated one after the other. Subfiles aren't split between real files, so each data file can be considered independent (with the exception that the .MAP file contains the offsets for all the subfiles across all the data files.)

The game search for required file (like VM.OVL) in the current folder and if it didn't there then it calc a hash from filename (0x564CF4C0 in this example) and search inside the .MAP file index.

Here is a hash routine for the filenames:

/*
  input:
    s - pointer to ASCIIZ filename string
    idx - pointer to an array of 4 bytes (hash indexes)
  return:
    hash - filename hash
*/
int32_t tim_hash(char *s, uint8_t *idx) {
int32_t i, c;
int16_t isum, ixor;
  isum = 0;
  ixor = 0;
  for (i = 0; s[i]; i++) {
    c = toupper(s[i]);
    isum += c;
    ixor ^= c;
  }
  /* both types here MUST be int16_t */
  isum *= ixor;
  c = 0;
  for (ixor = 0; ixor < 4; ixor++) {
    c <<= 8;
    /* can use only existing characters
      ("i" holds the string length now) */
    if (i > idx[ixor]) {
      c |= toupper(s[idx[ixor]]);
    }
  }
  c += isum;
  return(c);
}

/*
// this MUST be overwritten with the correct one from the .MAP file!
uint8_t idx[4] = {0, 1, 6, 7}; // 0, 1, 5, 7
// example of usage
printf("%08X\n", tim_hash("vm.ovl", idx));
*/

Bitmap Subfiles

See The Incredible Machine Image Format.

This is an example of PART23.BMP which is the smalles of the bitmap files. It contains one sprite which is 16x16 pixels in size.

If anyone knows the compression used in the SCN section, please let me know. The length of the compressed data is 127: https://cloud.githubusercontent.com/assets/1974959/25874475/03651bf0-3513-11e7-98bb-b3640c20fb6f.png

PART28.BMP, the second largest bitmap and only 16x15 px in size, contains 137 compressed bytes: https://cloud.githubusercontent.com/assets/1974959/25874624/9f622b10-3513-11e7-8f24-d66877c0ad84.png

Tools

The following tools are able to work with files in this format.

Name PlatformExtract files? Decompress on extract? Create new? Modify? Compress on insert? Access hidden data? Edit metadata? Notes
Camoto Linux/WindowsYesN/AYesYesN/AN/AN/A

Credits

This file format was reverse engineered by Malvineous. If you find this information helpful in a project you're working on, please give credit where credit is due. (A link back to this wiki would be nice too!)