]> icculus.org git repositories - crow/jumpnbump.git/blob - modify/gobpack.c
da5dc783d40c461272ae55ec9d9b8075e51f1a3f
[crow/jumpnbump.git] / modify / gobpack.c
1 #include <stdio.h>
2 #include <malloc.h>
3 #include <string.h>
4
5 typedef struct {
6         int num_images;
7         int *width;
8         int *height;
9         int *hs_x;
10         int *hs_y;
11         void **data;
12         void **orig_data;
13 } gob_t;
14
15 //
16 // WritePCXfile
17 //
18
19 static void write_pcx(FILE *pcxfile, unsigned char *data, int width, int height, unsigned char *palette)
20 {
21         int    i;
22
23         fputc(0x0a, pcxfile); // manufacturer
24         fputc(5, pcxfile); // version
25         fputc(1, pcxfile); // encoding
26         fputc(8, pcxfile); // bits_per_pixel
27         fputc(0, pcxfile); // xmin
28         fputc(0, pcxfile);
29         fputc(0, pcxfile); // ymin
30         fputc(0, pcxfile);
31         fputc((width - 1) & 0xff, pcxfile); // xmax
32         fputc(((width - 1) >> 8) & 0xff, pcxfile);
33         fputc((height - 1) & 0xff, pcxfile); // ymax
34         fputc(((height - 1) >> 8) & 0xff, pcxfile);
35         fputc(width & 0xff, pcxfile); // hres
36         fputc((width >> 8) & 0xff, pcxfile);
37         fputc(height & 0xff, pcxfile); // vres
38         fputc((height >> 8) & 0xff, pcxfile);
39         for (i = 0; i < 48; i++) // palette
40                 fputc(0, pcxfile);
41         fputc(0, pcxfile); // reserved
42         fputc(1, pcxfile); // color_planes
43         fputc(width & 0xff, pcxfile); // bytes_per_line
44         fputc((width >> 8) & 0xff, pcxfile);
45         fputc(1 & 0xff, pcxfile); // palette_type
46         fputc((1 >> 8) & 0xff, pcxfile);
47         for (i = 0; i < 58; i++) // filler
48                 fputc(0, pcxfile);
49
50         // pack the image
51
52         for (i = 0 ; i < width*height ; i++)
53                 if ( (*data & 0xc0) != 0xc0)
54                         fputc(*data++, pcxfile);
55                 else
56                 {
57                         fputc(0xc1, pcxfile);
58                         fputc(*data++, pcxfile);
59                 }
60
61         // write the palette
62
63         fputc(0x0c, pcxfile); // palette ID byte
64         if (palette)
65                 for (i = 0 ; i < 768 ; i++)
66                         fputc(*palette++, pcxfile);
67         else
68                 for (i = 0 ; i < 768 ; i++)
69                         fputc(i / 3, pcxfile);
70 }
71
72 int read_gob(FILE *handle, gob_t *gob, int len)
73 {
74         unsigned char *gob_data;
75         int i;
76
77         gob_data = malloc(len);
78         fread(gob_data, 1, len, handle);
79
80         gob->num_images = (short)((gob_data[0]) + (gob_data[1] << 8));
81
82         gob->width = malloc(gob->num_images*sizeof(int));
83         gob->height = malloc(gob->num_images*sizeof(int));
84         gob->hs_x = malloc(gob->num_images*sizeof(int));
85         gob->hs_y = malloc(gob->num_images*sizeof(int));
86         gob->data = malloc(gob->num_images*sizeof(void *));
87         gob->orig_data = malloc(gob->num_images*sizeof(void *));
88         for (i=0; i<gob->num_images; i++) {
89                 int image_size;
90                 int offset;
91
92                 offset = (gob_data[i*4+2]) + (gob_data[i*4+3] << 8) + (gob_data[i*4+4] << 16) + (gob_data[i*4+5] << 24);
93
94                 gob->width[i]  = (short)((gob_data[offset]) + (gob_data[offset+1] << 8)); offset += 2;
95                 gob->height[i] = (short)((gob_data[offset]) + (gob_data[offset+1] << 8)); offset += 2;
96                 gob->hs_x[i]   = (short)((gob_data[offset]) + (gob_data[offset+1] << 8)); offset += 2;
97                 gob->hs_y[i]   = (short)((gob_data[offset]) + (gob_data[offset+1] << 8)); offset += 2;
98
99                 image_size = gob->width[i] * gob->height[i];
100                 gob->orig_data[i] = malloc(image_size);
101                 memcpy(gob->orig_data[i], &gob_data[offset], image_size);
102                 gob->data[i] = (unsigned short *)gob->orig_data[i];
103         }
104         free(gob_data);
105         return 0;
106 }
107
108 int main(int argc, char **argv)
109 {
110         int usage = 0;
111         int unpack = 0;
112         FILE *f;
113         int len;
114         gob_t gob;
115
116         if (argc < 4) {
117                 usage = 1;
118         } else if (argc == 5) {
119                 unpack = 1;
120                 if ((argv[1][0] != '-') || (argv[1][1] != 'u'))
121                         usage = 1;
122         }
123         
124         if (usage) {
125                 printf("Usage: gobpack [-u] <file.gob> <file.pcx> <filedefs.txt>\n\t-u to unpack the gob\n");
126                 return 1;
127         }
128
129         if (unpack) {
130                 int width, height;
131                 int i;
132                 unsigned char *data;
133                 unsigned char *dst;
134
135                 f = fopen(argv[2], "rb");
136                 if (!f) {
137                         printf("Couldn't open file %s\n", argv[2]);
138                         return -1;
139                 }
140                 fseek(f, 0, SEEK_END);
141                 len = ftell(f);
142                 fseek(f, 0, SEEK_SET);
143
144                 read_gob(f, &gob, len);
145
146                 fclose(f);
147
148                 width = 0;
149                 height = 0;
150                 for (i = 0; i < gob.num_images; i++) {
151                         height += gob.height[i];
152                         if (gob.width[i] > width)
153                                 width = gob.width[i];
154                 }
155
156                 data = malloc(width*height);
157                 memset(data, 0, width*height);
158                 dst = data;
159
160                 for (i = 0; i < gob.num_images; i++) {
161                         int x,y;
162                         unsigned char *src;
163
164                         src = gob.data[i];
165                         for (y = 0; y < gob.height[i]; y++) {
166                                 for (x = 0; x < gob.width[i]; x++) {
167                                         dst[y * width + x] = src[y * gob.width[i] + x];
168                                 }
169                         }
170                         dst += gob.height[i] * width;
171                 }
172                 
173                 f = fopen(argv[3], "wb");
174                 if (!f) {
175                         printf("Couldn't open file %s\n", argv[3]);
176                         return -1;
177                 }
178
179                 write_pcx(f, data, width, height, NULL);
180
181                 fclose(f);
182
183                 f = fopen(argv[4], "w");
184                 if (!f) {
185                         printf("Couldn't open file %s\n", argv[4]);
186                         return -1;
187                 }
188
189                 fprintf(f, "num_images: %i\n\n", gob.num_images);
190                 for (i = 0; i < gob.num_images; i++) {
191                         fprintf(f, "width: %i\n", gob.width[i]);
192                         fprintf(f, "height: %i\n", gob.height[i]);
193                         fprintf(f, "hotspot_x: %i\n", -gob.hs_x[i]);
194                         fprintf(f, "hotspot_y: %i\n", -gob.hs_y[i]);
195                         fprintf(f, "\n");
196                 }
197
198                 fclose(f);
199         } else {
200         }
201
202         return 0;
203 }