.TIM File Format

From Final Fantasy Hacktics Wiki
Jump to navigation Jump to search

See the following links for information about .TIM's

http://wiki.qhimm.com/view/PSX/TIM_file

http://rewiki.regengedanken.de/wiki/.TIM


TIM Graphic Formats (PSX 2D Graphics) By Klarth (stevemonaco@hotmail.com) http://rpgd.emulationworld.com/klarth

Version 0.7 - January 1, 2001 -- Totally rewritten for extra clarity -- Removed Opinions/Ideas on Editing Utilities Section Version 0.5 - August 22, 2000 -- Initial Release


I. Table of Contents 

1. Introduction and Terminology
2. TIM Graphic Formats (4BPP, 8BPP, 16BPP, and 24BPP)
3. TIM Header Formats (4BPP, 8BPP, 16BPP, and 24BPP)
4. Color Conversion Algorithms (15bit BGR <-> 24bit RGB)

_______________________________________________________________________________________________


1. Introduction and Terminology


A. Introduction

    Hmm, I started this doc awhile ago when I first started to get interested in PSX hacking.
    I then concluded that many tools needed to be coded before the PSX translation "scene" 
    could really get started.  So I decided to finish it and release it so that all you 
    coders out there can start making some graphic tools to make PSX translations remotely 
    possible for anybody willing to try to tackle one.  These formats all have headers so I 
    decided to make a seperate document for them only since they're so different from other 
    console graphics formats.
    If you wish to put this document on your site, please contact me for authorization 
    *before* you post this file on your site.  If I seem to "magically" disappear from the 
    scene, you may post this document *only* in its original form.  If you use this doc 
    please credit me in a thanks section since I just like to see who reads and uses them.



B. Terminology

    CLUT - Color LookUp Table (The Sony term for Palette)
    Image Org - Sets the coordinate of an image zero point, used for TIM files
         in the VRAM of the Playstation.  Not particularly necessary from an editing point 
         but could be useful for a program that creates TIM images and their headers.
    Palette Org - Sets the coordinates of a CLUT image zero point.  Not particularly necessary 
    from an editing standpoint but could be useful for a program that creates TIM images and 
    their headers.
    BPP:  Bits per pixel.
    [pA-B rC]: pixels A-B (leftmost pixel 0), row number C (topmost row 0).
         This won't have a bitplane value because it's a linear format.
    [pX rX]: The last pixel of row X.  The last pixel's number is equal to the correct width 
         of the image as defined in the header.

_______________________________________________________________________________________________


2. TIM Graphics Data (A. 4BPP, B. 8BPP, C. 16BPP, D. 24BPP)

  All the graphics are stored in Big Endian order.



A. 4BPP PSX TIM

       Each pair represents one byte
       Format:
 [p0-1 r0], [p2-3 r0], [p4-5 r0], [p6-7 r0], ..., [pX r0]
 [p0-1 r1], [p2-3 r1], [p4-5 r1], [p6-7 r1], ..., [pX r1]
 ...
 And it continues until the row number equals the height (from the header).  It gets its
 colors from a 16 entry CLUT in the header of the file, there may be multiple CLUTs.



B. 8BPP PSX TIM

       Each pair represents one byte
       Format:
 [p0 r0], [p1 r0], [p2 r0], [p3, r0], [p4, r0], [p5, r0], [p6, r0], [p7, r0], ..., [pX r0]
 [p0 r0], [p1 r0], [p2 r0], [p3, r0], [p4, r0], [p5, r0], [p6, r0], [p7, r0], ..., [pX r0]
 ...
 And it continues until the row number equals the height (from the header).  It gets its
 colors from a 256 entry CLUT in the header of the file, there may be multiple CLUTs.



C. 16BPP PSX TIM

       Each pair represents two bytes
       Format:
 [p0 r0], [p1 r0], [p2 r0], [p3, r0], [p4, r0], [p5, r0], [p6, r0], [p7, r0], ..., [pX r0]
 [p0 r0], [p1 r0], [p2 r0], [p3, r0], [p4, r0], [p5, r0], [p6, r0], [p7, r0], ..., [pX r0]
 ...
 And it continues until the row number equals the height (from the header).  It doesn't need
 a CLUT because it's basically a type of 15bit color.



D. 24BPP PSX TIM

       Each pair represents three bytes
       Format:
 [p0 r0], [p1 r0], [p2 r0], [p3, r0], [p4, r0], [p5, r0], [p6, r0], [p7, r0], ..., [pX r0]
 [p0 r0], [p1 r0], [p2 r0], [p3, r0], [p4, r0], [p5, r0], [p6, r0], [p7, r0], ..., [pX r0]
 ...
 Continues until the row number equals the height (from the header).  It doesn't need a CLUT 
 since it's 24bit color.  I've never actually ripped a 24BPP TIM from a PSX game but I found 
 one 24BPP TIM image and took this info from it.  May or may not actually be used on the PSX.

_______________________________________________________________________________________________


3. TIM Headers (A. 4BPP, B. 8BPP, C. 16BPP, D. 24BPP)

  All two byte values are in Little Endian.  The rest are in Big Endian.



A. 4BPP TIM Header:

 [1-4]   - 10 00 00 00: ID Tag for TIM Format
 [5-8]   - 08 00 00 00: ID Tag for 4BPP
 [9-10]  - ?
 [11-12] - ?
 [13-14] - Palette Org X
 [15-16] - Palette Org Y
 [17-18] - ?
 [19-20] - Number of CLUTs
 [??-??] - CLUT Data.  16 Colors per CLUT, 32 bytes per CLUT.
 [21-22] - ?
 [23-24] - ?
 [25-26] - Image Org X
 [27-28] - Image Org Y
 [29-30] - Image Width (Multiply by 4 to get actual width)
 [31-32] - Image Height



B. 8BPP TIM Header:

 [1-4]   - 10 00 00 00: ID Tag for TIM
 [5-8]   - 09 00 00 00: ID Tag for 8BPP
 [9-10]  - ?
 [11-12] - ?
 [13-14] - Palette Org X
 [15-16] - Palette Org Y
 [17-18] - ?
 [19-20] - Number of CLUTs
 [??-??] - CLUT Data.  256 Colors per CLUT, 512 bytes per CLUT.
 [21-22] - ?
 [23-24] - ?
 [25-26] - Image Org X
 [27-28] - Image Org Y
 [29-30] - Image Width (Multiply by 2 to get actual width)
 [31-32] - Image Height



C. 16BPP TIM Header:

 [1-4]   - 10 00 00 00: ID Tag for TIM
 [5-8]   - 02 00 00 00: ID Tag for 16BPP
 [9-10]  - ?
 [11-12] - ?
 [13-14] - Image Org X
 [15-16] - Image Org Y
 [17-18] - Image Width (Stored as actual width)
 [19-20] - Image Height
 There is no CLUT data.



D. 24BPP TIM Header:

 [1-4]   - 10 00 00 00: ID Tag for TIM
 [5-8]   - 03 00 00 00: ID Tag for 24BPP
 [9-10]  - ?
 [11-12] - ?
 [13-14] - Image Org X
 [15-16] - Image Org Y
 [17-18] - Image Width (Divide by 1.5 to get actual height)
 [19-20] - Image Height
 There is no CLUT data.

_______________________________________________________________________________________________


4. Color Conversion Algorithms (15bit BGR <-> 24bit RGB)


A. 15bit BGR to 24bit RGB Color Conversion Algorithm

       Two bytes per 15bit BGR color, stored in Little Endian.
       Miscellaneous Note - Same as a SNES Palette Color.
 Initial 15bit BGR color in Little Endian:
 {ggg{rrrrr}  {0}{bbbbb}gg}
 Swap the two bytes to change to Big Endian from Little Endian.
 The color order will look like this now: (b-Blue, g-Green, r-Red, 0-mystery bit)
 {0}{bbbbb}{gg  ggg}{rrrrr}
 Take each of the color pairings and multiply by 8 to get a 24bit BGR color:
 {bbbbbbbb}  {gggggggg}  {rrrrrrrr}
 Rearrange from 15bit BGR to 24bit RGB:
 {rrrrrrrr}  {gggggggg}  {bbbbbbbb}
 This algorithm expands the color to 3 bytes instead of the original 2 bytes.



B. 24bit to 15bit Color Conversion Algorithm

       Three bytes per 24bit RGB color, stored in Big Endian.
 {rrrrrrrr}  {gggggggg}  {bbbbbbbb}
 Integer Divide (DIV) each color by 8
 {rrrrr}{ggg  gg}{bbbbb}{0}
 Rearrange into 15bit BRG
 {0}{bbbbb}{gg  ggg}{rrrrr}
 Swap the bytes to change from Big Endian to Little Endian (so the PSX can read it properly)
 {ggg{rrrrr}  {0}{bbbbb}{gg}



C. Notes on PSX 15bit BGR Colors

 These are the same as the SNES 15bit BGR Colors.  There is a color loss whenever converting 
 from 24bit RGB <-> 15bit BRG.  Also, there's probably a more advanced and quicker algorithm 
 to convert the colors, however this is explaining the basic idea behind the algorithm.