Implemented -scaleup and -nosound options. Some fixes for first release.
[crow/jumpnbump.git] / modify / pack.c
1 /*
2  * pack.c
3  * Copyright (C) 1998 Brainchild Design - http://brainchilddesign.com/
4  * 
5  * Copyright (C) 2001 tarzeau@space.ch
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 _MSC_VER
37 #include <getopt.h>
38 #include <unistd.h>
39 #else
40 #include <io.h>
41 typedef unsigned int u_int32_t;
42 #endif
43
44 typedef struct {
45         char filename[12];
46         u_int32_t offset;
47         u_int32_t size;
48 } DirEntry;
49
50 int main(int argc, char **argv)
51 {
52         int fd;
53         DirEntry *datafile;
54         int num_entries, i;
55         int c;
56         char *outfile = NULL;
57         int offset = 0;
58
59 #ifndef _MSC_VER
60         while ((c = getopt(argc, argv, "o:")) != EOF) {
61                 switch (c) {
62                 case 'o':
63                         if (optarg) {
64                                 outfile = strdup(optarg);
65                         }
66                         break;
67                 }
68         }
69         argc -= optind;
70         argv += optind;
71 #else
72         c = 1;
73         while (c<argc) {
74                 if (argv[c][0]=='-') {
75                         if (argv[c][1]=='o') {
76                                 if ( ((c+1)<argc) && (argv[c+1]) ) {
77                                         outfile = strdup(argv[c+1]);
78                                         c++;
79                                 }
80                                 c++;
81                                 break;
82                         }
83                 }
84                 c++;
85         }
86         argc -= c;
87         argv += c;
88 #endif
89
90         if (outfile == NULL) {
91                 printf("You must specify output filename with -o\n");
92                 exit(1);
93         }
94         if (argc == 0) {
95                 printf("You must specify some files to pack, duh\n");
96                 exit(1);
97         }
98         num_entries = argc;
99
100         /* prepare to pack things - get sizes and calculate offsets */
101         printf("%u files to pack\n", num_entries);
102         datafile = calloc(num_entries, sizeof(DirEntry));
103
104         /* skip past the directory structure */
105         offset = 4 + (num_entries * 20);
106
107         for (i = 0; i < num_entries; i++) {
108                 struct stat dummy;
109                 if (stat(argv[i], &dummy)) {
110                         fprintf(stderr, "%s is not accessible: ", argv[i]);
111                         perror("");
112                         exit(1);
113                 }
114                 if (strlen(argv[i]) > 12) {
115                         fprintf(stderr, "filename %s is longer than 12 chars\n", argv[i]);
116                         exit(1);
117                 }
118                 strncpy(datafile[i].filename, argv[i], 12);
119                 datafile[i].size = dummy.st_size;
120                 /* num_entries * (12 + 8) */
121                 datafile[i].offset = offset;
122                 offset += datafile[i].size;
123         }
124
125         /* here, we checked that all files are ok, and ready to roll the packfile */
126         fd = open(outfile, O_RDWR | O_CREAT | O_BINARY, 0644);
127         if (fd == -1) {
128                 perror("opening packfile");
129                 exit(1);
130         }
131         printf("Opened %s\n", outfile);
132
133         /* write number of entries in this data file */
134         write(fd, &num_entries, 4);
135
136         /* write the directory structure */
137         for (i = 0; i < num_entries; i++) {
138                 write(fd, &datafile[i], 20);
139         }
140
141         /* write in the actual files */
142         for (i = 0; i < num_entries; i++) {
143                 int infd;
144                 char *buf;
145
146                 printf("adding %s ", argv[i]);
147
148                 infd = open(argv[i], O_RDONLY | O_BINARY);
149                 if (infd == -1) {
150                         perror("opening file");
151                         exit(1);
152                 }
153                 buf = malloc(datafile[i].size + 16);
154                 read(infd, buf, datafile[i].size);
155                 close(infd);
156                 write(fd, buf, datafile[i].size);
157                 free(buf);
158                 printf(" OK\n");
159         }
160         close(fd);
161         return 0;
162 }