1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sciresource.h>
27 #include <resource.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #ifdef HAVE_UNISTD_H
31 # include <unistd.h>
32 #endif
33
34 #define COPY_BLOCK_SIZE 512
35
36 unsigned short *resource_ids = NULL;
37
38 void
help()39 help() {
40 printf("Usage:\n\tscipack <file_0> ... <file_n>\n"
41 "\nBuilds an uncompressed SCI0 resource.000 and a resource.map\n");
42 }
43
44 int /* Returns resource ID on success, -1 on error */
test_file(char * filename)45 test_file(char *filename) {
46 char *dot = strchr(filename, '.');
47 char *endptr;
48 FILE *f;
49 int res_type, res_index;
50
51 if (!dot) {
52 fprintf(stderr, "Must contain a period");
53 return -1;
54 }
55
56 *dot = 0;
57
58 for (res_type = 0; res_type < sci_invalid_resource
59 && scumm_stricmp(filename, sci_resource_types[res_type]); res_type++);
60
61 *dot = '.';
62
63 if (res_type == sci_invalid_resource) {
64 fprintf(stderr, "Invalid resource type");
65 return -1;
66 }
67
68 ++dot;
69 res_index = strtol(dot, &endptr, 10);
70
71 if (!*dot || *endptr) {
72 fprintf(stderr, "Invalid resource index");
73 return -1;
74 }
75
76 if (res_index < 0) {
77 fprintf(stderr, "Negative resource index");
78 return -1;
79 }
80
81 if (res_index >= 1000) {
82 fprintf(stderr, "Resource index too large");
83 return -1;
84 }
85
86 f = fopen(filename, "r");
87 if (!f) {
88 perror("While asserting file");
89 return -1;
90 }
91 fclose(f);
92
93 return (res_type << 11) | res_index;
94 }
95
96 int
build_file_ids(int count,char ** names)97 build_file_ids(int count, char **names) {
98 int i;
99 int error = 0;
100
101 resource_ids = (unsigned short*) malloc(sizeof(unsigned short) * count);
102
103 for (i = 0; i < count; i++) {
104 int id = test_file(names[i]);
105 if (id < 0) {
106 error = -1;
107 fprintf(stderr, ": %s\n", names[i]);
108 } else resource_ids[i] = id;
109 }
110
111 return error;
112 }
113
114
115 static inline void
write_uint16(int fd,unsigned int uint)116 write_uint16(int fd, unsigned int uint) {
117 unsigned char upper = (uint >> 8) & 0xff;
118 unsigned char lower = (uint) & 0xff;
119
120 if ((write(fd, &upper, 1) < 1)
121 || (write(fd, &lower, 1) < 1)) {
122 perror("While writing");
123 exit(1);
124 }
125 }
126
127 int
write_files(int count,char ** names)128 write_files(int count, char **names) {
129 int resource_000, resource_map;
130 int i;
131
132 resource_000 = creat("resource.000", 0644);
133 if (resource_000 < 0) {
134 perror("While creating 'resource.000'");
135 return -1;
136 }
137
138 resource_map = creat("resource.map", 0644);
139 if (resource_map < 0) {
140 perror("While creating 'resource.map'");
141 return -1;
142 }
143
144 for (i = 0; i < count; i++) {
145 int fd = open(names[i], O_RDONLY);
146 struct stat fdstat;
147 int fdsize;
148 unsigned char buf[512];
149 int j;
150 long offset = lseek(resource_000, SEEK_CUR, 0);
151 int top_offset = (offset >> 16) & 0xffff;
152 int bot_offset = offset & 0xffff;
153
154 if (fd < 0) {
155 perror(names[i]);
156 return -1;
157 }
158 fstat(fd, &fdstat);
159 fdsize = fdstat.st_size;
160
161 write_uint16(resource_000, resource_ids[i]);
162 write_uint16(resource_000, fdsize);
163 write_uint16(resource_000, fdsize);
164 write_uint16(resource_000, 0);
165
166 do {
167 j = read(fd, buf, COPY_BLOCK_SIZE);
168 write(resource_000, buf, j);
169 } while (j == COPY_BLOCK_SIZE);
170 close(fd);
171
172 write_uint16(resource_map, resource_ids[i]);
173 write_uint16(resource_map, bot_offset);
174 write_uint16(resource_map, top_offset);
175 }
176
177 /* Terminate resource 000 */
178 write_uint16(resource_000, 0);
179
180 /* Terminate resource map */
181 write_uint16(resource_map, 0xffff);
182 write_uint16(resource_map, 0xffff);
183
184 close(resource_000);
185 close(resource_map);
186 }
187
188
189 int
main(int argc,char ** argv)190 main(int argc, char **argv) {
191 printf("scipack.c Copyright (C) 2002 Christoph Reichenbach\n"
192 "This program is FREE SOFTWARE. You may copy it and/or re-distribute it\n"
193 "according to the terms of the GNU General Public License. See LICENSING\n"
194 "for details.\n");
195
196 if (argc < 1)
197 help();
198
199 if (build_file_ids(argc - 1, argv + 1))
200 return -1;
201
202 if (write_files(argc - 1, argv + 1))
203 return -1;
204 free(resource_ids);
205 }
206