]> icculus.org git repositories - crow/jumpnbump.git/blob - modify/jnbpack.c
Fixed typo.
[crow/jumpnbump.git] / modify / jnbpack.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 #ifdef LINUX
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 #ifndef O_BINARY
52 #define O_BINARY 0
53 #endif
54
55 int main(int argc, char **argv)
56 {
57         int fd;
58         DirEntry *datafile;
59         int num_entries, i;
60         int c;
61         char *outfile = NULL;
62         int offset = 0;
63
64 #ifdef LINUX
65         while ((c = getopt(argc, argv, "o:")) != EOF) {
66                 switch (c) {
67                 case 'o':
68                         if (optarg) {
69                                 outfile = strdup(optarg);
70                         }
71                         break;
72                 }
73         }
74         argc -= optind;
75         argv += optind;
76 #else
77         c = 1;
78         while (c<argc) {
79                 if (argv[c][0]=='-') {
80                         if (argv[c][1]=='o') {
81                                 if ( ((c+1)<argc) && (argv[c+1]) ) {
82                                         outfile = strdup(argv[c+1]);
83                                         c++;
84                                 }
85                                 c++;
86                                 break;
87                         }
88                 }
89                 c++;
90         }
91         argc -= c;
92         argv += c;
93 #endif
94
95         if (outfile == NULL) {
96                 printf("You must specify output filename with -o\n");
97                 exit(1);
98         }
99         if (argc == 0) {
100                 printf("You must specify some files to pack, duh\n");
101                 exit(1);
102         }
103         num_entries = argc;
104
105         /* prepare to pack things - get sizes and calculate offsets */
106         printf("%u files to pack\n", num_entries);
107         datafile = calloc(num_entries, sizeof(DirEntry));
108
109         /* skip past the directory structure */
110         offset = 4 + (num_entries * 20);
111
112         for (i = 0; i < num_entries; i++) {
113                 struct stat dummy;
114                 if (stat(argv[i], &dummy)) {
115                         fprintf(stderr, "%s is not accessible: ", argv[i]);
116                         perror("");
117                         exit(1);
118                 }
119                 if (strlen(argv[i]) > 12) {
120                         fprintf(stderr, "filename %s is longer than 12 chars\n", argv[i]);
121                         exit(1);
122                 }
123                 strncpy(datafile[i].filename, argv[i], 12);
124                 datafile[i].size = dummy.st_size;
125                 /* num_entries * (12 + 8) */
126                 datafile[i].offset = offset;
127                 offset += datafile[i].size;
128         }
129
130         /* here, we checked that all files are ok, and ready to roll the packfile */
131         fd = open(outfile, O_RDWR | O_CREAT | O_BINARY, 0644);
132         if (fd == -1) {
133                 perror("opening packfile");
134                 exit(1);
135         }
136         printf("Opened %s\n", outfile);
137
138         /* write number of entries in this data file */
139         {
140                 char temp;
141
142                 temp = (num_entries >>  0) & 0xff;
143                 write(fd, &temp, 1);
144                 temp = (num_entries >>  8) & 0xff;
145                 write(fd, &temp, 1);
146                 temp = (num_entries >> 16) & 0xff;
147                 write(fd, &temp, 1);
148                 temp = (num_entries >> 24) & 0xff;
149                 write(fd, &temp, 1);
150         }
151
152         /* write the directory structure */
153         for (i = 0; i < num_entries; i++) {
154                 char temp;
155
156                 write(fd, &datafile[i].filename, 12);
157                 temp = (datafile[i].offset >>  0) & 0xff;
158                 write(fd, &temp, 1);
159                 temp = (datafile[i].offset >>  8) & 0xff;
160                 write(fd, &temp, 1);
161                 temp = (datafile[i].offset >> 16) & 0xff;
162                 write(fd, &temp, 1);
163                 temp = (datafile[i].offset >> 24) & 0xff;
164                 write(fd, &temp, 1);
165                 temp = (datafile[i].size >>  0) & 0xff;
166                 write(fd, &temp, 1);
167                 temp = (datafile[i].size >>  8) & 0xff;
168                 write(fd, &temp, 1);
169                 temp = (datafile[i].size >> 16) & 0xff;
170                 write(fd, &temp, 1);
171                 temp = (datafile[i].size >> 24) & 0xff;
172                 write(fd, &temp, 1);
173         }
174
175         /* write in the actual files */
176         for (i = 0; i < num_entries; i++) {
177                 int infd;
178                 char *buf;
179
180                 printf("adding %s ", argv[i]);
181
182                 infd = open(argv[i], O_RDONLY | O_BINARY);
183                 if (infd == -1) {
184                         perror("opening file");
185                         exit(1);
186                 }
187                 buf = malloc(datafile[i].size + 16);
188                 read(infd, buf, datafile[i].size);
189                 close(infd);
190                 write(fd, buf, datafile[i].size);
191                 free(buf);
192                 printf(" OK\n");
193         }
194         close(fd);
195         return 0;
196 }