]> icculus.org git repositories - crow/jumpnbump.git/blob - modify/pack.c
ff0b130d25a0a124cd2ed2032a8a0ccd011428fc
[crow/jumpnbump.git] / modify / pack.c
1 /*
2  * pack.c
3  * Copyright (C) 1998 Brainchild Design - http://brainchilddesign.com/
4  * 
5  * Copyright (C) 2001 "timecop" <timecop@japan.co.jp>
6  *
7  * Copyright (C) 2002 Florian Schulze <crow@icculus.org>
8  *
9  * Portions of this code are from the MPEG software simulation group
10  * idct implementation. This code will be replaced with a new
11  * implementation soon.
12  *
13  * This file is part of Jump'n'Bump.
14  *
15  * Jump'n'Bump is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 2 of the License, or
18  * (at your option) any later version.
19  *
20  * Jump'n'Bump is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  */
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <fcntl.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <string.h>
36 #ifndef _WIN32
37 #include <getopt.h>
38 #endif
39 #ifndef _MSC_VER
40 #include <unistd.h>
41 #else
42 #include <io.h>
43 #endif
44
45 typedef struct {
46         char filename[12];
47         unsigned int offset;
48         unsigned int size;
49 } DirEntry;
50
51 int main(int argc, char **argv)
52 {
53         int fd;
54         DirEntry *datafile;
55         int num_entries, i;
56         int c;
57         char *outfile = NULL;
58         int offset = 0;
59
60 #ifndef _WIN32
61         while ((c = getopt(argc, argv, "o:")) != EOF) {
62                 switch (c) {
63                 case 'o':
64                         if (optarg) {
65                                 outfile = strdup(optarg);
66                         }
67                         break;
68                 }
69         }
70         argc -= optind;
71         argv += optind;
72 #else
73         c = 1;
74         while (c<argc) {
75                 if (argv[c][0]=='-') {
76                         if (argv[c][1]=='o') {
77                                 if ( ((c+1)<argc) && (argv[c+1]) ) {
78                                         outfile = strdup(argv[c+1]);
79                                         c++;
80                                 }
81                                 c++;
82                                 break;
83                         }
84                 }
85                 c++;
86         }
87         argc -= c;
88         argv += c;
89 #endif
90
91         if (outfile == NULL) {
92                 printf("You must specify output filename with -o\n");
93                 exit(1);
94         }
95         if (argc == 0) {
96                 printf("You must specify some files to pack, duh\n");
97                 exit(1);
98         }
99         num_entries = argc;
100
101         /* prepare to pack things - get sizes and calculate offsets */
102         printf("%u files to pack\n", num_entries);
103         datafile = calloc(num_entries, sizeof(DirEntry));
104
105         /* skip past the directory structure */
106         offset = 4 + (num_entries * 20);
107
108         for (i = 0; i < num_entries; i++) {
109                 struct stat dummy;
110                 if (stat(argv[i], &dummy)) {
111                         fprintf(stderr, "%s is not accessible: ", argv[i]);
112                         perror("");
113                         exit(1);
114                 }
115                 if (strlen(argv[i]) > 12) {
116                         fprintf(stderr, "filename %s is longer than 12 chars\n", argv[i]);
117                         exit(1);
118                 }
119                 strncpy(datafile[i].filename, argv[i], 12);
120                 datafile[i].size = dummy.st_size;
121                 /* num_entries * (12 + 8) */
122                 datafile[i].offset = offset;
123                 offset += datafile[i].size;
124         }
125
126         /* here, we checked that all files are ok, and ready to roll the packfile */
127         fd = open(outfile, O_RDWR | O_CREAT | O_BINARY, 0644);
128         if (fd == -1) {
129                 perror("opening packfile");
130                 exit(1);
131         }
132         printf("Opened %s\n", outfile);
133
134         /* write number of entries in this data file */
135         write(fd, &num_entries, 4);
136
137         /* write the directory structure */
138         for (i = 0; i < num_entries; i++) {
139                 write(fd, &datafile[i], 20);
140         }
141
142         /* write in the actual files */
143         for (i = 0; i < num_entries; i++) {
144                 int infd;
145                 char *buf;
146
147                 printf("adding %s ", argv[i]);
148
149                 infd = open(argv[i], O_RDONLY | O_BINARY);
150                 if (infd == -1) {
151                         perror("opening file");
152                         exit(1);
153                 }
154                 buf = malloc(datafile[i].size + 16);
155                 read(infd, buf, datafile[i].size);
156                 close(infd);
157                 write(fd, buf, datafile[i].size);
158                 free(buf);
159                 printf(" OK\n");
160         }
161         close(fd);
162         return 0;
163 }