home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / PHONG.ZIP / 3dsrdr.c next >
Text File  |  1998-07-03  |  11KB  |  349 lines

  1. /* --------------------------- 3DSRDR.C -------------------------------
  2.     .3DS file format exerciser. Written by Jare/Iguana. v1.0.
  3.     I compile this with Watcom/32, but I guess it should work with
  4.         any compiler and OS combination for which the typedefs are
  5.         valid i.e. any that I know for PCs... Try it and see.
  6.         Oh, and also check the #pragma pack() thing.
  7.  
  8.     Heavily based on info on the file 3DS_08.TXT by Jim Pitts
  9.       (jp5@ukc.ac.uk)
  10.  
  11.     Basic material-related stuff digged up by Jare.
  12.  
  13.     If you decide to work on this further, please make your findings
  14.         public like we have already done, ok? Upload it to
  15.         x2ftp.oulu.fi, THE place for programming info.
  16. */
  17.  
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include <string.h>
  21.  
  22. typedef unsigned char  byte;
  23. typedef unsigned short word;
  24. typedef unsigned long  dword;
  25.  
  26. #pragma pack(2)
  27.  
  28. typedef struct {
  29.     word    id;
  30.     dword   len;
  31. } TChunkHeader, *PChunkHeader;
  32.  
  33. #pragma pack()
  34.  
  35. enum {
  36.     CHUNK_RGBF      = 0x0010,
  37.     CHUNK_RGBB      = 0x0011,
  38. //    CHUNK_RBGB2     = 0x0012,       // ?? NOT HLS.
  39.  
  40.     CHUNK_MAIN      = 0x4D4D,
  41.         CHUNK_OBJMESH   = 0x3D3D,
  42.             CHUNK_BKGCOLOR  = 0x1200,
  43.             CHUNK_AMBCOLOR  = 0x2100,
  44.             CHUNK_OBJBLOCK  = 0x4000,
  45.                 CHUNK_TRIMESH   = 0x4100,
  46.                     CHUNK_VERTLIST  = 0x4110,
  47.                     CHUNK_FACELIST  = 0x4120,
  48.                     CHUNK_FACEMAT   = 0x4130,
  49.                     CHUNK_MAPLIST   = 0x4140,
  50.                     CHUNK_SMOOLIST  = 0x4150,
  51.                     CHUNK_TRMATRIX  = 0x4160,
  52.                 CHUNK_LIGHT     = 0x4600,
  53.                     CHUNK_SPOTLIGHT = 0x4610,
  54.                 CHUNK_CAMERA    = 0x4700,
  55.         CHUNK_MATERIAL  = 0xAFFF,
  56.             CHUNK_MATNAME   = 0xA000,
  57.             CHUNK_AMBIENT   = 0xA010,
  58.             CHUNK_DIFFUSE   = 0xA020,
  59.             CHUNK_SPECULAR  = 0xA030,
  60.             CHUNK_TEXTURE   = 0xA200,
  61.             CHUNK_BUMPMAP   = 0xA230,
  62.             CHUNK_MAPFILE   = 0xA300,
  63.         CHUNK_KEYFRAMER = 0xB000,
  64.             CHUNK_FRAMES    = 0xB008,
  65.  
  66. };
  67.  
  68. // ------------------------------------
  69.  
  70.     // Forward declaration.
  71. void ChunkReader(FILE *f, int ind, long p);
  72.  
  73. void SkipReader(FILE *f, int ind, long p) {
  74. }
  75.  
  76. void RGBFReader (FILE *f, int ind, long p) {
  77.     float c[3];
  78.     if (fread(&c, sizeof(c), 1, f) != 1) return;
  79.     printf("%*s    Red: %f, Green: %f, Blue: %f\n", ind, "", c[0], c[1], c[2]);
  80. }
  81.  
  82. void RGBBReader (FILE *f, int ind, long p) {
  83.     byte c[3];
  84.     if (fread(&c, sizeof(c), 1, f) != 1) return;
  85.     printf("%*s    Red: %d, Green: %d, Blue: %d\n", ind, "", c[0], c[1], c[2]);
  86. }
  87.  
  88. void ObjBlockReader (FILE *f, int ind, long p) {
  89.     int c;
  90.  
  91.         // Read ASCIIZ object name
  92.     printf("%*sObject name \"", ind, "");
  93.     while ( (c = fgetc(f)) != EOF && c != '\0')
  94.         putchar(c);
  95.     printf("\"\n");
  96.         // Read rest of chunks inside this one.
  97.     ChunkReader(f, ind, p);
  98. }
  99.  
  100. void VertListReader (FILE *f, int ind, long p) {
  101.     word nv;
  102.     float c[3];
  103.  
  104.     if (fread(&nv, sizeof(nv), 1, f) != 1) return;
  105.     printf("%*sVertices: %d\n", ind, "", nv);
  106.     while (nv-- > 0) {
  107.         if (fread(&c, sizeof(c), 1, f) != 1) return;
  108.         printf("%*s    X: %f, Y: %f, Z: %f\n", ind, "", c[0], c[1], c[2]);
  109.     }
  110. }
  111.  
  112. void FaceListReader (FILE *f, int ind, long p) {
  113.     word nv;
  114.     word c[4];
  115.  
  116.     if (fread(&nv, sizeof(nv), 1, f) != 1) return;
  117.     printf("%*sFaces: %d\n", ind, "", nv);
  118.     while (nv-- > 0) {
  119.         if (fread(&c, sizeof(c), 1, f) != 1) return;
  120.         printf("%*s    A: %d, B: %d, C: %d, Flags 0x%X\n",
  121.                ind, "", c[0], c[1], c[2], c[3]);
  122.     }
  123.         // Read rest of chunks inside this one.
  124.     ChunkReader(f, ind, p);
  125. }
  126.  
  127. void FaceMatReader (FILE *f, int ind, long p) {
  128.     int c;
  129.     word n, nf;
  130.  
  131.         // Read ASCIIZ material name
  132.     printf("%*sMaterial name for faces: \"", ind, "");
  133.     while ( (c = fgetc(f)) != EOF && c != '\0')
  134.         putchar(c);
  135.     printf("\"\n");
  136.  
  137.     if (fread(&n, sizeof(n), 1, f) != 1) return;
  138.     printf("%*sFaces with this material: %d\n", ind, "", n);
  139.     while (n-- > 0) {
  140.         if (fread(&nf, sizeof(nf), 1, f) != 1) return;
  141.         printf("%*s    Face %d\n",
  142.                ind, "", nf);
  143.     }
  144. }
  145.  
  146. void MapListReader (FILE *f, int ind, long p) {
  147.     word nv;
  148.     float c[2];
  149.  
  150.     if (fread(&nv, sizeof(nv), 1, f) != 1) return;
  151.     printf("%*sVertices: %d\n", ind, "", nv);
  152.     while (nv-- > 0) {
  153.         if (fread(&c, sizeof(c), 1, f) != 1) return;
  154.         printf("%*s    U: %f, V: %f\n", ind, "", c[0], c[1]);
  155.     }
  156. }
  157.  
  158. void SmooListReader (FILE *f, int ind, long p) {
  159.     dword s;
  160.     int i;
  161.  
  162.     while (ftell(f) < p) {
  163.         if (fread(&s, sizeof(s), 1, f) != 1) return;
  164.         printf("%*sSmoothing groups: ", ind, "");
  165.         for (i = 0; i < 32; i++)
  166.             if (s & (1 << i))
  167.                 printf("%d, ", i + 1);
  168.         printf("\n");
  169.     }
  170. }
  171.  
  172. void TrMatrixReader(FILE *f, int ind, long p) {
  173.     float rot[9];
  174.     float trans[3];
  175.     if (fread(&rot, sizeof(rot), 1, f) != 1) return;
  176.     printf("%*sRotation matrix:\n", ind, "");
  177.     printf("%*s    %f, %f, %f\n", ind, "", rot[0], rot[1], rot[2]);
  178.     printf("%*s    %f, %f, %f\n", ind, "", rot[3], rot[4], rot[5]);
  179.     printf("%*s    %f, %f, %f\n", ind, "", rot[6], rot[7], rot[8]);
  180.     if (fread(&trans, sizeof(trans), 1, f) != 1) return;
  181.     printf("%*sTranslation matrix: %f, %f, %f\n",
  182.            ind, "", trans[0], trans[1], trans[2]);
  183. }
  184.  
  185. void LightReader(FILE *f, int ind, long p) {
  186.     float c[3];
  187.     if (fread(&c, sizeof(c), 1, f) != 1) return;
  188.     printf("%*s    X: %f, Y: %f, Z: %f\n", ind, "", c[0], c[1], c[2]);
  189.         // Read rest of chunks inside this one.
  190.     ChunkReader(f, ind, p);
  191. }
  192.  
  193. void SpotLightReader(FILE *f, int ind, long p) {
  194.     float c[5];
  195.     if (fread(&c, sizeof(c), 1, f) != 1) return;
  196.     printf("%*s    Target X: %f, Y: %f, Z: %f; Hotspot %f, Falloff %f\n",
  197.            ind, "", c[0], c[1], c[2], c[3], c[4]);
  198. }
  199.  
  200. void CameraReader(FILE *f, int ind, long p) {
  201.     float c[8];
  202.     if (fread(&c, sizeof(c), 1, f) != 1) return;
  203.     printf("%*s    Position: X: %f, Y: %f, Z: %f\n", ind, "", c[0], c[1], c[2]);
  204.     printf("%*s    Target: X: %f, Y: %f, Z: %f\n", ind, "", c[3], c[4], c[5]);
  205.     printf("%*s    Bank: %f, Lens: %f\n", ind, "", c[6], c[7]);
  206. }
  207.  
  208. void MatNameReader (FILE *f, int ind, long p) {
  209.     int c;
  210.  
  211.         // Read ASCIIZ object name
  212.     printf("%*sMaterial name \"", ind, "");
  213.     while ( (c = fgetc(f)) != EOF && c != '\0')
  214.         putchar(c);
  215.     printf("\"\n");
  216. }
  217.  
  218. void MapFileReader (FILE *f, int ind, long p) {
  219.     int c;
  220.  
  221.         // Read ASCIIZ filename
  222.     printf("%*sMap filename \"", ind, "");
  223.     while ( (c = fgetc(f)) != EOF && c != '\0')
  224.         putchar(c);
  225.     printf("\"\n");
  226. }
  227.  
  228. void FramesReader(FILE *f, int ind, long p) {
  229.     dword c[2];
  230.     if (fread(&c, sizeof(c), 1, f) != 1) return;
  231.     printf("%*s    Start: %ld, End: %ld\n",
  232.            ind, "", c[0], c[1]);
  233. }
  234.  
  235. // ------------------------------------
  236.  
  237. struct {
  238.     word id;
  239.     const char *name;
  240.     void (*func)(FILE *f, int ind, long p);
  241. } ChunkNames[] = {
  242.     {CHUNK_RGBF,        "RGB float",        RGBFReader},
  243.     {CHUNK_RGBB,        "RGB byte",         RGBBReader},
  244.  
  245.     {CHUNK_MAIN,        "Main",             NULL},
  246.     {CHUNK_OBJMESH,     "Object Mesh",      NULL},
  247.     {CHUNK_BKGCOLOR,    "Background color", NULL},
  248.     {CHUNK_AMBCOLOR,    "Ambient color",    NULL},
  249.     {CHUNK_OBJBLOCK,    "Object Block",     ObjBlockReader},
  250.     {CHUNK_TRIMESH,     "Tri-Mesh",         NULL},
  251.     {CHUNK_VERTLIST,    "Vertex list",      VertListReader},
  252.     {CHUNK_FACELIST,    "Face list",        FaceListReader},
  253.     {CHUNK_FACEMAT,     "Face material",    FaceMatReader},
  254.     {CHUNK_MAPLIST,     "Mappings list",    MapListReader},
  255.     {CHUNK_SMOOLIST,    "Smoothings",       SmooListReader},
  256.     {CHUNK_TRMATRIX,    "Matrix",           TrMatrixReader},
  257.     {CHUNK_LIGHT,       "Light",            LightReader},
  258.     {CHUNK_SPOTLIGHT,   "Spotlight",        SpotLightReader},
  259.     {CHUNK_CAMERA,      "Camera",           CameraReader},
  260.  
  261.     {CHUNK_MATERIAL,    "Material",         NULL},
  262.     {CHUNK_MATNAME,     "Material name",    MatNameReader},
  263.     {CHUNK_AMBIENT,     "Ambient color",    NULL},
  264.     {CHUNK_DIFFUSE,     "Diffuse color",    NULL},
  265.     {CHUNK_SPECULAR,    "Specular color",   NULL},
  266.     {CHUNK_TEXTURE,     "Texture map",      NULL},
  267.     {CHUNK_BUMPMAP,     "Bump map",         NULL},
  268.     {CHUNK_MAPFILE,     "Map filename",     MapFileReader},
  269.  
  270.     {CHUNK_KEYFRAMER,   "Keyframer data",   NULL},
  271.     {CHUNK_FRAMES,      "Frames",           FramesReader},
  272.  
  273. };
  274.  
  275. int FindChunk(word id) {
  276.     int i;
  277.     for (i = 0; i < sizeof(ChunkNames)/sizeof(ChunkNames[0]); i++)
  278.         if (id == ChunkNames[i].id)
  279.             return i;
  280.     return -1;
  281. }
  282.  
  283. // ------------------------------------
  284.  
  285. int Verbose = 0;
  286.  
  287. void ChunkReader(FILE *f, int ind, long p) {
  288.     TChunkHeader h;
  289.     int n;
  290.     long pc;
  291.  
  292.     while (ftell(f) < p) {
  293.         pc = ftell(f);
  294.         if (fread(&h, sizeof(h), 1, f) != 1) return;
  295.         n = FindChunk(h.id);
  296.         if (n < 0) {
  297.             if (Verbose)
  298.                 printf("%*sUnknown chunk: 0x%04X, offset 0x%lX, size: %d bytes.\n",
  299.                        ind, "", h.id, pc, h.len);
  300.             fseek(f, pc + h.len, SEEK_SET);
  301.         } else {
  302.             printf("%*sChunk type \"%s\", offset 0x%lX, size %d bytes\n",
  303.                    ind, "", ChunkNames[n].name, pc, h.len);
  304.             pc = pc + h.len;
  305.             if (ChunkNames[n].func != NULL)
  306.                 ChunkNames[n].func(f, ind + 2, pc);
  307.             else
  308.                 ChunkReader(f, ind + 2, pc);
  309.             fseek(f, pc, SEEK_SET);
  310.         }
  311.         if (ferror(f))
  312.             break;
  313.     }
  314. }
  315.  
  316. // ------------------------------------
  317.  
  318. extern void FinishProgram(void) {
  319. }
  320.  
  321. void main(int argc, char *argv[]) {
  322.     FILE *f;
  323.     long p;
  324.  
  325.     if (argc < 2) {
  326.         printf("Usage: 3DSRDR file.3ds [-verbose]\n");
  327.         exit(1);
  328.     }
  329.  
  330.     f = fopen(argv[1], "rb");
  331.     if (f == NULL) {
  332.         printf("Can't open %s!\n", argv[1]);
  333.         exit(1);
  334.     }
  335.  
  336.     if (argc > 2 && strcmp(argv[2], "-verbose") == 0)
  337.         Verbose = 1;
  338.  
  339.         // Find file size.
  340.     fseek(f, 0, SEEK_END);
  341.     p = ftell(f);
  342.     fseek(f, 0, SEEK_SET);
  343.         // Go!
  344.     ChunkReader(f, 0, p);
  345.    
  346.     FinishProgram();
  347. }
  348.  
  349.