*********************** TMD Format FAQ *********************** Version: 1.00 Last Modified: 27/3/97 Authors: -> James Pitts sigill@geocities.com http://www.playstation.co.uk/~Sig1LL -> Alex Amsel alex@teeth.demon.co.uk http://www.playstation.co.uk/~IBEYOND Short: This document briefly describes the .tmd file format as used by the Sony Playstation Yaroze/gslib to store 3D object information. This document is not intended to be distributed outside of the Net Yaroze community. The tmd.h include file is at the bottom of this document. If you have any comments or additions to make please contact us. **************************************************** -====- HEADER -====- A .tmd file has a header starting at the very first byte of the file. offset type 0 ID 4 Flags 8 Num ID - Always 0x00000041 Flags - Set to 1 if processed by GsMapModelingData(), else 0 Num - Number Objects in tmd This structure only appears once and is directly followed by the first Object Header. **************************************************** -===========- Object Header -===========- This header describes each object in the tmd file. All file offsets within this object are taken from this point. offset type 0 Vertices Table 4 Number Vertices 8 Normal list Offset 12 Number Normals 16 Polygon Primitives Offset 20 Number Primitives 24 scaling (apparently unused) The "Vertices Table" points to a table of vectors (see below for detail) with "Number Vertices" elements. This is the x,y,z coord for each point in the object. Normals are stored identically to the Vertices but obviously contain normal vectors. The Polygon Primitives describe each polygon in the scene (3 and 4 sided) these records have varying sizes. **************************************************** -==================- Vertices and Normals -==================- To read the Vertices and Normal Data just seek to the offset specified in the Object Header structure. Remember to add the tmd header size to the offsets. NormalTab = ObjHead->NormalOffset + sizeof (tmdheader); The Vertices and Normal are just vectors. offset type 0 x 2 y 4 z 6 filler filler is just for alignment padding and has no use. **************************************************** -========- Primitives -========- This is where the fun starts. :-) This is a table of all the polygons in this object. Each polygon has a header, which is followed by a variable size data block. ->HEADER<- offset type 0 olen 1 ilen 2 flag 3 mode olen - output data block length (dwords) ilen - input data block length (dwords) The output data block length is fixed according to internal PS-X primitive formats and is the size of the primitive within the order table. The values are listed with each primitive below. The input data block length reports how much data is to follow. If your reader does not understand the following data or wishes to ignore it. It can just skip 'length * 4' bytes. The data to follow can be determined by the mode and flags fields. The Mode and Flags fields are both split into bitfields. ->MODE<- bits hex type 0 1 Brightness 1 2 Transparency 2 4 Texture 3 8 Quad 4 10 Gouraud 5 20 1 Bit 5 of the mode field is always 1. bit 0 == 1 No flat shading [No Light] bit 1 == 1 Transparency On bit 2 == 1 Polygon Textured bit 3 == 1 4 sided polygon bit 4 == 1 Polygon is Gouraud shaded (or gradated for lines) bit 5 == 1 Always 1 for polys, 0 for lines ->FLAG<- bits hex type 0 1 Light Source 1 2 2 Sided 2 4 Gradation bit 0 == 1 Do not calculate light sourcing bit 1 == 1 Polygon is double sided bit 2 == 1 Gradated **************************************************** The structure that follow below are the data blocks for each polygon mode. N.B. mode2 is a copy of mode, and is used as a filler Flag == 1 is a bit of a guess for "No Light Polygons". Try it and see... * Mode == 0x20 && Flag == 0 (Flat Shaded Triangle) ilen == 3 olen == 4 offset type 0 red 1 green 2 blue 3 mode2 4 index into normal table 6 first point 8 second point 10 third point The rgb fields specify the ambient colour of the poly. Next is the offset in to the normal table for this polygons Normal Vector. Followed by three indexes into the vertex table for each point of the poly. * Mode == 0x20 && Flag == 4 (Gradated Triangle) ilen == 5 olen == 6 offset type 0 red0 1 green0 2 blue0 3 mode2 4 red1 5 green1 6 blue1 7 pad0 8 red2 9 green2 10 blue2 11 pad1 12 index into normal table 14 first point 16 second point 18 third point This time we have RGB data for each vertex. * Mode == 0x24 && Flag == 0 (Textured Triangle) ilen == 5 olen == 7 offset type 0 u0 1 v0 2 cba 4 u1 5 v1 6 tsb 8 u2 9 v2 10 pad 12 index into normal table 14 first point 16 second point 18 third point u and v are the texture page coordinates cba is the clut number (CBA clutY * 64 + clutX / 16) tsb is the Texture Page + Semitransparency Rate (0..3) << 5 + Colour Mode (0..2) << 7 * Mode == 0x30 && Flag == 0 (Gouraud Shaded Triangle) ilen == 4 olen == 6 offset type 0 red 1 green 2 blue 3 mode2 4 index into normal table 6 first point 8 index into normal table 10 second point 12 index into normal table 14 third point This is similar to the flat shaded polygon primitives except each vertice has an associated normal. * Mode == 0x30 && Flag == 4 (Gouraud Gradated Triangle) ilen == 6 olen == 6 offset type 0 red0 1 green0 2 blue0 3 mode2 4 red1 5 green1 6 blue1 7 pad0 8 red2 9 green2 10 blue2 11 pad1 12 index into normal table 14 first point 16 index into normal table 18 second point 20 index into normal table 22 third point * Mode == 0x34 && Flag == 0 (Goraud Textured Triangle) ilen == 6 olen == 9 offset type 0 u0 1 v0 2 cba 4 u1 5 v1 6 tsb 8 u2 9 v2 10 pad 12 index into normal table 14 first point 16 index into normal table 18 second point 20 index into normal table 22 third point * Mode == 0x21 && Flag == 1 (Triangle No Light) ilen == 3 olen == 4 offset type 0 red 1 green 2 blue 3 mode2 4 first point 6 second point 8 third point 10 pad * Mode == 0x25 && Flag == 1 (Textured Triangle No Light) ilen == 6 olen == 7 offset type 0 u0 1 v0 2 cba 4 u1 5 v1 6 tsb 8 u2 9 v2 10 pad0 12 red 13 green 14 blue 15 pad1 16 first point 18 second point 20 third point 22 pad2 * Mode == 0x31 && Flag == 1 (Gouraud Shaded Triangle No Light) ilen == 5 olen == 6 offset type 0 red0 1 green0 2 blue0 3 mode2 4 red1 5 green1 6 blue1 7 pad0 8 red2 9 green2 10 blue2 11 pad1 12 first point 14 second point 16 third point 18 pad2 * Mode == 0x35 && Flag == 1 (Goraud Textured Triangle No Light) ilen == 8 olen == 9 offset type 0 u0 1 v0 2 cba 4 u1 5 v1 6 tsb 8 u2 9 v2 10 pad0 12 red0 13 green0 14 blue0 15 pad1 16 red1 17 green1 18 blue1 19 pad2 20 red2 21 green2 22 blue2 23 pad3 24 first point 26 second point 28 third point 30 pad4 **************************************************** Quadrangle structures are identical other than there are 4 entires where Triangle structures had 3 (e.g. points, normals, rgb, uv). A Padding word is added to the end of the structure where it needs to be made up to a multiple of dwords in size. This is siginified below with a (P). * Mode == 0x28 && Flag == 0 (Flat Shaded Quad) ilen == 4 olen == 5 (P) * Mode == 0x28 && Flag == 4 (Gradated Quad) ilen == 7 olen == 8 (P) * Mode == 0x2c && Flag == 0 (Textured Quad) ilen == 7 olen == 9 (P) * Mode == 0x38 && Flag == 0 (Goraud Shaded Quad) ilen == 5 olen == 8 * Mode == 0x38 && Flag == 4 (Goraud Gradated Quad) ilen == 8 olen == 8 * Mode == 0x3c && Flag == 0 (Goraud Textured Quad) ilen == 8 olen == 12 * Mode == 0x29 && Flag == 1 (Quad No Light) ilen == 3 olen == 5 * Mode == 0x2d && Flag == 1 (Quad No Light) ilen == 7 olen == 9 * Mode == 0x39 && Flag == 1 (Quad No Light) ilen == 6 olen == 8 * Mode == 0x3d && Flag == 1 (Quad No Light) ilen == 10 olen == 12 **************************************************** * Mode == 0x40 && Flag == 0 (Straight Line) ilen == 2 olen == 3 offset type 0 red 1 green 2 blue 3 mode2 4 first point 6 second point * Mode == 0x50 && Flag == 4(?) (Gradated Straight Line) ilen == 3 olen == 4 offset type 0 red0 1 green0 2 blue0 3 mode2 4 red1 5 green1 6 blue1 7 pad 8 first point 10 second point **************************************************** File tmd.h from the 'clone' demo follows :- /*************************************************************** * * * Copyright (C) 1997 by Sony Computer Entertainment * * All rights Reserved * * * * S. Ashley 9th Jan 97 * * * ***************************************************************/ #ifndef _tmd_h #define _tmd_h #include // for decoding primative mode #define IIP 0x10 // gouraud shading #define QUAD 0x08 // 4 sided #define TME 0x04 // textured #define ABE 0x02 // semi transparency on #define TGE 0x01 // brightness calculation off // flags for primatives #define GRD 0x04 // gradation #define FCE 0x02 // 2 sided #define LGT 0x01 // no light source calculation // primative modes #define F_3 0x20 // Triangle No-texture #define F_3G 0x20 // Triangle No-texture gradation #define F_3T 0x24 // Triangle Texture #define G_3 0x30 // triangle gouraud #define G_3G 0x30 // triangle gouraud gradation #define G_3T 0x34 // triangle gouraud texture #define F_3_NL 0x21 // triangle no texture no light #define F_3T_NL 0x25 // triangle texture no light #define G_3_NL 0x31 // triangle gouraud no texture no light #define G_3T_NL 0x35 // triangle gouraud texture no light #define F_4 0x28 // Quadangle No-texture #define F_4G 0x28 // Quadangle No-texture gradation #define F_4T 0x2c // Quadangle Texture #define G_4 0x38 // quad gouraud #define G_4G 0x38 // quad gouraud gradation #define G_4T 0x3c // quad gouraud texture #define F_4_NL 0x29 // quad no texture no light #define F_4T_NL 0x2d // quad texture no light #define G_4_NL 0x39 // quad gouraud no texture no light #define G_4T_NL 0x3d // quad gouraud texture no light #define SL 0x40 // straight line no gradation #define SL_G 0x50 // straight line gradation // TMD is made up of header, object tables (one for each object), // primative table, vertices table and normals table typedef struct { u_long id; // 0x00000041 u_long flag; // 1 if addresses real, 0 if offset u_long nobjs; // number of objects in TMD } TMD_HDR; #define setTMD_HDR(t,_i,_f,_n) \ (t)->id = (_i), (t)->flag = (_f), (t)->nobjs = (_n) typedef struct { u_long *vert_top; // vertices table u_long n_vert; // number of vertices u_long *norm_top; // normal table u_long n_norm; // number of normals u_long *prim_top; // primatives table u_long n_prim; // number of primatives long scale; // not used } TMD_OBJ; #define setTMD_OBJ(t,_vt,_vn,_nt,_nn,_pt,_pn,_s) \ (t)->vert_top = (_vt), (t)->n_vert = (_vn), \ (t)->norm_top = (_nt), (t)->n_norm = (_nn), \ (t)->prim_top = (_pt), (t)->n_prim = (_pn), \ (t)->scale = (_s) // primative table is made up of a collection of primatives headers, with there // primative data typedef struct { u_char olen, ilen, flag, mode; } PRIM_HDR; #define setPRIM_HDR(p,_m,_f,_i,_o) \ (p)->mode = (_m), (p)->flag = (_f), (p)->ilen = (_i), (p)->olen = (_o) typedef struct { short vx, vy; short vz, pad; } TMD_VERT; #define setTMD_VERT(t,_x,_y,_z) \ (t)->vx = (_x), (t)->vy = (_y), (t)->vz = (_z) typedef struct { short nx, ny; short nz, pad; } TMD_NORM; #define setTMD_NORM(t,_x,_y,_z) \ (t)->nx = (_x), (t)->ny = (_y), (t)->nz = (_z) // normals and vertices are indices for the normal and vertex tables // r0, g0, b0 are colour values // mode2 is just a repetition of the mode data used as a filler typedef struct // ilen 3 olen 4 { u_char r0, g0, b0, mode2; u_short norm0, vert0; u_short vert1, vert2; } TMD_F_3; #define setTMD_F_3(t,_r,_g,_b,_norm,_vert0,_vert1,_vert2) \ (t)->r0 = (_r), (t)->g0 = (_g), (t)->b0 = (_b), \ (t)->norm0 = (_norm), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1), (t)->vert2 = (_vert2) // pad0, pad1 are just padding typedef struct // ilen 5 olen 6 { u_char r0, g0, b0, mode2; u_char r1, g1, b1, pad0; u_char r2, g2, b2, pad1; u_short norm0, vert0; u_short vert1, vert2; } TMD_F_3G; #define setTMD_F_3G(t,_r0,_g0,_b0,_r1,_g1,_b1,_r2,_g2,_b2,_norm,_vert0,_vert1,_vert2) \ (t)->r0 = (_r0), (t)->g0 = (_g0), (t)->b0 = (_b0), \ (t)->r1 = (_r1), (t)->g1 = (_g1), (t)->b1 = (_b1), \ (t)->r2 = (_r2), (t)->g2 = (_g2), (t)->b2 = (_b2), \ (t)->norm0 = (_norm), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1), (t)->vert2 = (_vert2) // CBA clutY * 64 + clutX / 16 // TSB texture page + semitrans rate (0..3) << 5 + colour mode (0..2) << 7 // u, v are texture page coordinates typedef struct // ilen 5 olen 7 { u_char u0, v0; u_short cba; u_char u1, v1; u_short tsb; u_char u2, v2; u_short pad; u_short norm0, vert0; u_short vert1, vert2; } TMD_F_3T; #define setTMD_F_3T(t,_cba,_tsb,_u0,_v0,_u1,_v1,_u2,_v2,_norm,_vert0,_vert1,_vert2) \ (t)->cba = (_cba), (t)->tsb = (_tsb), \ (t)->u0 = (_u0), (t)->v0 = (_v0), \ (t)->u1 = (_u1), (t)->v1 = (_v1), \ (t)->u2 = (_u2), (t)->v2 = (_v2), \ (t)->norm0 = (_norm), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1), (t)->vert2 = (_vert2) typedef struct // ilen 4 olen 5 { u_char r0, g0, b0, mode2; u_short norm0, vert0; u_short vert1, vert2; u_short vert3, pad; } TMD_F_4; #define setTMD_F_4(t,_r,_g,_b,_norm,_vert0,_vert1,_vert2,_vert3) \ (t)->r0 = (_r), (t)->g0 = (_g), (t)->b0 = (_b), \ (t)->norm0 = (_norm), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1), \ (t)->vert2 = (_vert2), (t)->vert3 = (_vert3) typedef struct // ilen 7 olen 8 { u_char r0, g0, b0, mode2; u_char r1, g1, b1, pad0; u_char r2, g2, b2, pad1; u_char r3, g3, b3, pad2; u_short norm0, vert0; u_short vert1, vert2; u_short vert3, pad3; } TMD_F_4G; #define setTMD_F_4G(t,_r0,_g0,_b0,_r1,_g1,_b1,_r2,_g2,_b2,_r3,_g3,_b3,_norm,_vert0,_vert1,_vert2,_vert3) \ (t)->r0 = (_r0), (t)->g0 = (_g0), (t)->b0 = (_b0), \ (t)->r1 = (_r1), (t)->g1 = (_g1), (t)->b1 = (_b1), \ (t)->r2 = (_r2), (t)->g2 = (_g2), (t)->b2 = (_b2), \ (t)->r3 = (_r3), (t)->g3 = (_g3), (t)->b3 = (_b3), \ (t)->norm0 = (_norm), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1), \ (t)->vert2 = (_vert2), (t)->vert3 = (_vert3) typedef struct // ilen 7 olen 9 { u_char u0, v0; u_short cba; u_char u1, v1; u_short tsb; u_char u2, v2; u_short pad0; u_char u3, v3; u_short pad1; u_short norm0, vert0; u_short vert1, vert2; u_short vert3, pad2; } TMD_F_4T; #define setTMD_F_4T(t,_cba,_tsb,_u0,_v0,_u1,_v1,_u2,_v2,_u3,_v3,_norm,_vert0,_vert1,_vert2,_vert3) \ (t)->cba = (_cba), (t)->tsb = (_tsb), \ (t)->u0 = (_u0), (t)->v0 = (_v0), \ (t)->u1 = (_u1), (t)->v1 = (_v1), \ (t)->u2 = (_u2), (t)->v2 = (_v2), \ (t)->u3 = (_u3), (t)->v3 = (_v3), \ (t)->norm0 = (_norm), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1), \ (t)->vert2 = (_vert2), (t)->vert3 = (_vert3) typedef struct // ilen 4 olen 6 { u_char r0, g0, b0, mode2; u_short norm0, vert0; u_short norm1, vert1; u_short norm2, vert2; } TMD_G_3; #define setTMD_G_3(t,_r,_g,_b,_norm0,_norm1,_norm2,_vert0,_vert1,_vert2) \ (t)->r0 = (_r), (t)->g0 = (_g), (t)->b0 = (_b), \ (t)->norm0 = (_norm0), (t)->norm1 = (_norm1), (t)->norm2 = (_norm2), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1), (t)->vert2 = (_vert2) typedef struct // ilen 6 olen 6 { u_char r0, g0, b0, mode2; u_char r1, g1, b1, pad0; u_char r2, g2, b2, pad1; u_short norm0, vert0; u_short norm1, vert1; u_short norm2, vert2; } TMD_G_3G; #define setTMD_G_3G(t,_r0,_g0,_b0,_r1,_g1,_b1,_r2,_g2,_b2,_norm0,_norm1,_norm2,_vert0,_vert1,_vert2) \ (t)->r0 = (_r0), (t)->g0 = (_g0), (t)->b0 = (_b0), \ (t)->r1 = (_r1), (t)->g1 = (_g1), (t)->b1 = (_b1), \ (t)->r2 = (_r2), (t)->g2 = (_g2), (t)->b2 = (_b2), \ (t)->norm0 = (_norm0), (t)->norm1 = (_norm1), (t)->norm2 = (_norm2), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1), (t)->vert2 = (_vert2) typedef struct // ilen 6 olen 9 { u_char u0, v0; u_short cba; u_char u1, v1; u_short tsb; u_char u2, v2; u_short pad; u_short norm0, vert0; u_short norm1, vert1; u_short norm2, vert2; } TMD_G_3T; #define setTMD_G_3T(t,_cba,_tsb,_u0,_v0,_u1,_v1,_u2,_v2,_norm0,_norm1,_norm2,_vert0,_vert1,_vert2) \ (t)->cba = (_cba), (t)->tsb = (_tsb), \ (t)->u0 = (_u0), (t)->v0 = (_v0), \ (t)->u1 = (_u1), (t)->v1 = (_v1), \ (t)->u2 = (_u2), (t)->v2 = (_v2), \ (t)->norm0 = (_norm0), (t)->norm0 = (_norm1), (t)->norm0 = (_norm2), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1), (t)->vert2 = (_vert2) typedef struct // ilen 5 olen 8 { u_char r0, g0, b0, mode2; u_short norm0, vert0; u_short norm1, vert1; u_short norm2, vert2; u_short norm3, vert3; } TMD_G_4; #define setTMD_G_4(t,_r,_g,_b,_norm0,_norm1,_norm2,_norm3,_vert0,_vert1,_vert2,_vert3) \ (t)->r0 = (_r), (t)->g0 = (_g), (t)->b0 = (_b), \ (t)->norm0 = (_norm0), (t)->norm1 = (_norm1), \ (t)->norm2 = (_norm2), (t)->norm3 = (_norm3), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1), \ (t)->vert2 = (_vert2), (t)->vert3 = (_vert3) typedef struct // ilen 8 olen 8 { u_char r0, g0, b0, mode2; u_char r1, g1, b1, pad0; u_char r2, g2, b2, pad1; u_char r3, g3, b3, pad2; u_short norm0, vert0; u_short norm1, vert1; u_short norm2, vert2; u_short norm3, vert3; } TMD_G_4G; #define setTMD_G_4G(t,_r0,_g0,_b0,_r1,_g1,_b1,_r2,_g2,_b2,_r3,_g3,_b3,_norm0,_norm1,_norm2,_norm3,_vert0,_vert1,_vert2,_vert3) \ (t)->r0 = (_r0), (t)->g0 = (_g0), (t)->b0 = (_b0), \ (t)->r1 = (_r1), (t)->g1 = (_g1), (t)->b1 = (_b1), \ (t)->r2 = (_r2), (t)->g2 = (_g2), (t)->b2 = (_b2), \ (t)->r3 = (_r3), (t)->g3 = (_g3), (t)->b3 = (_b3), \ (t)->norm0 = (_norm0), (t)->norm1 = (_norm1), \ (t)->norm2 = (_norm2), (t)->norm3 = (_norm3), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1), \ (t)->vert2 = (_vert2), (t)->vert3 = (_vert3) typedef struct // ilen 8 olen 12 { u_char u0, v0; u_short cba; u_char u1, v1; u_short tsb; u_char u2, v2; u_short pad0; u_char u3, v3; u_short pad1; u_short norm0, vert0; u_short norm1, vert1; u_short norm2, vert2; u_short norm3, vert3; } TMD_G_4T; #define setTMD_G_4T(t,_cba,_tsb,_u0,_v0,_u1,_v1,_u2,_v2,_u3,_v3,_norm0,_norm1,_norm2,_norm3,_vert0,_vert1,_vert2,_vert3) \ (t)->cba = (_cba), (t)->tsb = (_tsb), \ (t)->u0 = (_u0), (t)->v0 = (_v0), \ (t)->u1 = (_u1), (t)->v1 = (_v1), \ (t)->u2 = (_u2), (t)->v2 = (_v2), \ (t)->u3 = (_u3), (t)->v3 = (_v3), \ (t)->norm0 = (_norm0), (t)->norm1 = (_norm1), \ (t)->norm2 = (_norm2), (t)->norm3 = (_norm3), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1), \ (t)->vert2 = (_vert2), (t)->vert3 = (_vert3) typedef struct // ilen 3 olen 4 { u_char r0, g0, b0, mode2; u_short vert0, vert1; u_short vert2, pad; } TMD_F_3_NL; #define setTMD_F_3_NL(t,_r,_g,_b,_vert0,_vert1,_vert2) \ (t)->r0 = (_r), (t)->g0 = (_g), (t)->b0 = (_b), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1), (t)->vert2 = (_vert2) typedef struct // ilen 6 olen 7 { u_char u0, v0; u_short cba; u_char u1, v1; u_short tsb; u_char u2, v2; u_short pad0; u_char r0, g0, b0, pad1; u_short vert0, vert1; u_short vert2, pad2; } TMD_F_3T_NL; #define setTMD_F_3T_NL(t,_cba,_tsb,_u0,_v0,_u1,_v1,_u2,_v2,_r,_g,_b,_vert0,_vert1,_vert2) \ (t)->cba = (_cba), (t)->tsb = (_tsb), \ (t)->u0 = (_u0), (t)->v0 = (_v0), \ (t)->u1 = (_u1), (t)->v1 = (_v1), \ (t)->u2 = (_u2), (t)->v2 = (_v2), \ (t)->r0 = (_r), (t)->g0 = (_g), (t)->b0 = (_b), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1), (t)->vert2 = (_vert2) typedef struct // ilen 5 olen 6 { u_char r0, g0, b0, mode2; u_char r1, g1, b1, pad0; u_char r2, g2, b2, pad1; u_short vert0, vert1; u_short vert2, pad2; } TMD_G_3_NL; #define setTMD_G_3_NL(t,_r0,_g0,_b0,_r1,_g1,_b1,_r2,_g2,_b2,_vert0,_vert1,_vert2) \ (t)->r0 = (_r0), (t)->g0 = (_g0), (t)->b0 = (_b0), \ (t)->r1 = (_r1), (t)->g1 = (_g1), (t)->b1 = (_b1), \ (t)->r2 = (_r2), (t)->g2 = (_g2), (t)->b2 = (_b2), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1), (t)->vert2 = (_vert2) typedef struct // ilen 8 olen 9 { u_char u0, v0; u_short cba; u_char u1, v1; u_short tsb; u_char u2, v2; u_short pad0; u_char r0, g0, b0, pad1; u_char r1, g1, b1, pad2; u_char r2, g2, b2, pad3; u_short vert0, vert1; u_short vert2, pad4; } TMD_G_3T_NL; #define setTMD_G_3T_NL(t,_cba,_tsb,_u0,_v0,_u1,_v1,_u2,_v2,_r0,_g0,_b0,_r1,_g1,_b1,_r2,_g2,_b2,_vert0,_vert1,_vert2) \ (t)->cba = (_cba), (t)->tsb = (_tsb), \ (t)->u0 = (_u0), (t)->v0 = (_v0), \ (t)->u1 = (_u1), (t)->v1 = (_v1), \ (t)->u2 = (_u2), (t)->v2 = (_v2), \ (t)->r0 = (_r0), (t)->g0 = (_g0), (t)->b0 = (_b0), \ (t)->r1 = (_r1), (t)->g1 = (_g1), (t)->b1 = (_b1), \ (t)->r2 = (_r2), (t)->g2 = (_g2), (t)->b2 = (_b2), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1), (t)->vert2 = (_vert2) typedef struct // ilen 3 olen 5 { u_char r0, g0, b0, mode2; u_short vert0, vert1; u_short vert2, vert3; } TMD_F_4_NL; #define setTMD_F_4_NL(t,_r,_g,_b,_vert0,_vert1,_vert2,_vert3) \ (t)->r0 = (_r), (t)->g0 = (_g), (t)->b0 = (_b), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1), \ (t)->vert2 = (_vert2), (t)->vert3 = (_vert3) typedef struct // ilen 7 olen 9 { u_char u0, v0; u_short cba; u_char u1, v1; u_short tsb; u_char u2, v2; u_short pad0; u_char u3, v3; u_short pad1; u_char r0, g0, b0, pad2; u_short vert0, vert1; u_short vert2, vert3; } TMD_F_4T_NL; #define setTMD_F_4T_NL(t,_cba,_tsb,_u0,_v0,_u1,_v1,_u2,_v2,_u3,_v3,_r,_g,_b,_vert0,_vert1,_vert2,_vert3) \ (t)->cba = (_cba), (t)->tsb = (_tsb), \ (t)->u0 = (_u0), (t)->v0 = (_v0), \ (t)->u1 = (_u1), (t)->v1 = (_v1), \ (t)->u2 = (_u2), (t)->v2 = (_v2), \ (t)->u3 = (_u3), (t)->v3 = (_v3), \ (t)->r0 = (_r), (t)->g0 = (_g), (t)->b0 = (_b), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1), \ (t)->vert2 = (_vert2), (t)->vert3 = (_vert3) typedef struct // ilen 6 olen 8 { u_char r0, g0, b0, mode2; u_char r1, g1, b1, pad0; u_char r2, g2, b2, pad1; u_char r3, g3, b3, pad2; u_short vert0, vert1; u_short vert2, vert3; } TMD_G_4_NL; #define setTMD_G_4_NL(t,_r0,_g0,_b0,_r1,_g1,_b1,_r2,_g2,_b2,_r3,_g3,_b3,_vert0,_vert1,_vert2,_vert3) \ (t)->r0 = (_r0), (t)->g0 = (_g0), (t)->b0 = (_b0), \ (t)->r1 = (_r1), (t)->g1 = (_g1), (t)->b1 = (_b1), \ (t)->r2 = (_r2), (t)->g2 = (_g2), (t)->b2 = (_b2), \ (t)->r3 = (_r3), (t)->g3 = (_g3), (t)->b3 = (_b3), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1), \ (t)->vert2 = (_vert2), (t)->vert3 = (_vert3) typedef struct // ilen 10 olen 12 { u_char u0, v0; u_short cba; u_char u1, v1; u_short tsb; u_char u2, v2; u_short pad0; u_char u3, v3; u_short pad1; u_char r0, g0, b0, pad2; u_char r1, g1, b1, pad3; u_char r2, g2, b2, pad4; u_char r3, g3, b3, pad5; u_short vert0, vert1; u_short vert2, vert3; } TMD_G_4T_NL; #define setTMD_G_4T_NL(t,_cba,_tsb,_u0,_v0,_u1,_v1,_u2,_v2,_u3,_v3,_r0,_g0,_b0,_r1,_g1,_b1,_r2,_g2,_b2,_r3,_g3,_b3,_vert0,_vert1,_vert2,_vert3) \ (t)->cba = (_cba), (t)->tsb = (_tsb), \ (t)->u0 = (_u0), (t)->v0 = (_v0), \ (t)->u1 = (_u1), (t)->v1 = (_v1), \ (t)->u2 = (_u2), (t)->v2 = (_v2), \ (t)->u3 = (_u3), (t)->v3 = (_v3), \ (t)->r0 = (_r0), (t)->g0 = (_g0), (t)->b0 = (_b0), \ (t)->r1 = (_r1), (t)->g1 = (_g1), (t)->b1 = (_b1), \ (t)->r2 = (_r2), (t)->g2 = (_g2), (t)->b2 = (_b2), \ (t)->r3 = (_r3), (t)->g3 = (_g3), (t)->b3 = (_b3), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1), \ (t)->vert2 = (_vert2), (t)->vert3 = (_vert3) typedef struct // ilen 2 olen 3 { u_char r0, g0, b0, mode2; u_short vert0, vert1; } TMD_SL; #define setTMD_SL(t,_r,_g,_b,_vert0,_vert1) \ (t)->r0 = (_r), (t)->g0 = (_g), (t)->b0 = (_b), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1) typedef struct // ilen 3 olen 4 { u_char r0, g0, b0, mode2; u_char r1, g1, b1, pad; u_short vert0, vert1; } TMD_SL_G; #define setTMD_SL_G(t,_r0,_g0,_b0,_r1,_g1,_b1,_vert0,_vert1) \ (t)->r0 = (_r0), (t)->g0 = (_g0), (t)->b0 = (_b0), \ (t)->r1 = (_r1), (t)->g1 = (_g1), (t)->b1 = (_b1), \ (t)->vert0 = (_vert0), (t)->vert1 = (_vert1) #endif