Added AI by Ricardo Cruz. This also adds mouse controls.
[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  * This file is part of Jump'n'Bump.
10  *
11  * Jump'n'Bump is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * Jump'n'Bump is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  */
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <fcntl.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <string.h>
32 #ifdef LINUX
33 #include <getopt.h>
34 #endif
35 #ifndef _MSC_VER
36 #include <unistd.h>
37 #else
38 #include <io.h>
39 #endif
40
41 typedef struct {
42         char filename[12];
43         unsigned int offset;
44         unsigned int size;
45 } DirEntry;
46
47 #ifndef O_BINARY
48 #define O_BINARY 0
49 #endif
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 #ifdef LINUX
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         {
136                 char temp;
137
138                 temp = (num_entries >>  0) & 0xff;
139                 write(fd, &temp, 1);
140                 temp = (num_entries >>  8) & 0xff;
141                 write(fd, &temp, 1);
142                 temp = (num_entries >> 16) & 0xff;
143                 write(fd, &temp, 1);
144                 temp = (num_entries >> 24) & 0xff;
145                 write(fd, &temp, 1);
146         }
147
148         /* write the directory structure */
149         for (i = 0; i < num_entries; i++) {
150                 char temp;
151
152                 write(fd, &datafile[i].filename, 12);
153                 temp = (datafile[i].offset >>  0) & 0xff;
154                 write(fd, &temp, 1);
155                 temp = (datafile[i].offset >>  8) & 0xff;
156                 write(fd, &temp, 1);
157                 temp = (datafile[i].offset >> 16) & 0xff;
158                 write(fd, &temp, 1);
159                 temp = (datafile[i].offset >> 24) & 0xff;
160                 write(fd, &temp, 1);
161                 temp = (datafile[i].size >>  0) & 0xff;
162                 write(fd, &temp, 1);
163                 temp = (datafile[i].size >>  8) & 0xff;
164                 write(fd, &temp, 1);
165                 temp = (datafile[i].size >> 16) & 0xff;
166                 write(fd, &temp, 1);
167                 temp = (datafile[i].size >> 24) & 0xff;
168                 write(fd, &temp, 1);
169         }
170
171         /* write in the actual files */
172         for (i = 0; i < num_entries; i++) {
173                 int infd;
174                 char *buf;
175
176                 printf("adding %s ", argv[i]);
177
178                 infd = open(argv[i], O_RDONLY | O_BINARY);
179                 if (infd == -1) {
180                         perror("opening file");
181                         exit(1);
182                 }
183                 buf = malloc(datafile[i].size + 16);
184                 read(infd, buf, datafile[i].size);
185                 close(infd);
186                 write(fd, buf, datafile[i].size);
187                 free(buf);
188                 printf(" OK\n");
189         }
190         close(fd);
191         return 0;
192 }