00001 #include <stdio.h> 00002 #include <unistd.h> 00003 #include <stdlib.h> 00004 #include <string.h> 00005 00006 void 00007 dump (void *buf, int n) 00008 { 00009 int i; 00010 int j; 00011 int c; 00012 00013 for (i = 0; i < n; i += 16) { 00014 printf ("%04x: ", i); 00015 for (j = 0; j < 16; j++) { 00016 if (i+j < n) 00017 printf ("%02x ", ((unsigned char *)buf)[i+j]); 00018 else 00019 printf (" "); 00020 } 00021 printf (" "); 00022 for (j = 0; j < 16; j++) { 00023 c = ((unsigned char *)buf)[i+j] & 0x7f; 00024 if (i+j >= n) 00025 putchar (' '); 00026 else if (c < ' ' || c == 0x7f) 00027 putchar ('.'); 00028 else 00029 putchar (c); 00030 } 00031 printf ("\n"); 00032 00033 } 00034 } 00035 00036 00037 #pragma pack(1) 00038 struct TM { 00039 char ID[6]; 00040 long offset; 00041 long size; 00042 }; 00043 00044 00045 struct music_dir { 00046 struct TM dir; 00047 int nfiles; 00048 struct TM *files; 00049 }; 00050 00051 FILE *musicf; 00052 #define MDIRS 4 00053 struct music_dir dirs[MDIRS]; 00054 00055 int 00056 open_music_cat (char *filename) 00057 { 00058 int i; 00059 struct music_dir *dp; 00060 00061 if ((musicf = fopen (filename, "rb")) == NULL) 00062 return (-1); 00063 00064 for (i = 0, dp = dirs; i < MDIRS; i++, dp++) 00065 fread (&dp->dir, 1, sizeof dp->dir, musicf); 00066 00067 for (i = 0, dp = dirs; i < MDIRS; i++, dp++) { 00068 printf ("%6.6s 0x%08lx %8ld\n", dp->dir.ID, 00069 dp->dir.offset, dp->dir.size); 00070 00071 dp->nfiles = 32; 00072 dp->files = calloc (dp->nfiles, sizeof *dp->files); 00073 fseek (musicf, dp->dir.offset, SEEK_SET); 00074 fread (dp->files, dp->nfiles, sizeof *dp->files, musicf); 00075 } 00076 00077 return (0); 00078 } 00079 00080 int 00081 get_music (char *filetype, int idx, void *buf, int bufsize) 00082 { 00083 int len; 00084 int i; 00085 struct music_dir *dp; 00086 int n; 00087 00088 len = strlen (filetype); 00089 00090 for (i = 0, dp = dirs; i < MDIRS; i++, dp++) { 00091 if (xstrncasecmp (dp->dir.ID, filetype, len) == 0) 00092 break; 00093 } 00094 00095 if (i == MDIRS) 00096 return (-1); 00097 00098 if (idx < 0 || idx >= dp->nfiles) 00099 return (-1); 00100 00101 n = dp->files[idx].size; 00102 if (n > bufsize) 00103 n = bufsize; 00104 00105 fseek (musicf, dp->dir.offset + dp->files[idx].offset, SEEK_SET); 00106 n = fread (buf, 1, n, musicf); 00107 return (n); 00108 } 00109 00110 void 00111 do_display_cat (void) 00112 { 00113 int i, j; 00114 struct music_dir *dp; 00115 struct TM *fp; 00116 long base, offset; 00117 00118 base = 0; 00119 for (i = 0, dp = dirs; i < MDIRS; i++, dp++) { 00120 for (j = 0, fp = dp->files; j < dp->nfiles; j++, fp++) { 00121 offset = dp->dir.offset + fp->offset; 00122 00123 printf ("0x%08lx %8ld %.6s/%.6s\n", 00124 offset, fp->size, 00125 dp->dir.ID, fp->ID); 00126 } 00127 } 00128 } 00129 00130 int display_cat; 00131 00132 void 00133 usage (void) 00134 { 00135 fprintf (stderr, "usage: mtest\n"); 00136 exit (1); 00137 } 00138 00139 int 00140 main (int argc, char **argv) 00141 { 00142 int c; 00143 char *type = NULL; 00144 int idx = 0; 00145 int n; 00146 char buf[1000 * 1000]; 00147 00148 while ((c = getopt (argc, argv, "c")) != EOF) { 00149 switch (c) { 00150 case 'c': 00151 display_cat = 1; 00152 break; 00153 default: 00154 usage (); 00155 } 00156 } 00157 00158 if (optind < argc) 00159 type = argv[optind++]; 00160 00161 if (optind < argc) 00162 idx = atoi (argv[optind++]); 00163 00164 if (optind != argc) 00165 usage (); 00166 00167 open_music_cat ("/l/baris/gamedat/music.cat"); 00168 00169 if (display_cat) { 00170 do_display_cat (); 00171 exit (0); 00172 } 00173 00174 if (type) { 00175 n = get_music (type, idx, buf, sizeof buf); 00176 dump (buf, n); 00177 } 00178 00179 return (0); 00180 } 00181 00182