OSDN Git Service

change potion un-id desc
[jnethack/source.git] / win / gem / load_img.c
1 /*
2  * $NHDT-Date: 1432512809 2015/05/25 00:13:29 $  $NHDT-Branch: master $:$NHDT-Revision: 1.5 $
3  */
4 #define __TCC_COMPAT__
5 #include <stdio.h>
6 #include <string.h>
7 #include <osbind.h>
8 #include <memory.h>
9 #include <aesbind.h>
10 #include <vdibind.h>
11 #include <gemfast.h>
12 #include <e_gem.h>
13 #include "load_img.h"
14
15 #ifndef FALSE
16 #define FALSE 0
17 #define TRUE !FALSE
18 #endif
19
20 /* VDI <-> Device palette order conversion matrixes: */
21 /* Four-plane vdi-device */
22 int vdi2dev4[] = { 0, 15, 1, 2, 4, 6, 3, 5, 7, 8, 9, 10, 12, 14, 11, 13 };
23 /* Two-plane vdi-device */
24 int vdi2dev2[] = { 0, 3, 1, 2 };
25
26 void
27 get_colors(int handle, short *palette, int col)
28 {
29     int i, idx;
30
31     /* get current color palette */
32     for (i = 0; i < col; i++) {
33         /* device->vdi->device palette order */
34         switch (planes) {
35         case 1:
36             idx = i;
37             break;
38         case 2:
39             idx = vdi2dev2[i];
40             break;
41         case 4:
42             idx = vdi2dev4[i];
43             break;
44         default:
45             if (i < 16)
46                 idx = vdi2dev4[i];
47             else
48                 idx = i == 255 ? 1 : i;
49         }
50         vq_color(handle, i, 0, (int *) palette + idx * 3);
51     }
52 }
53
54 void
55 img_set_colors(int handle, short *palette, int col)
56 {
57     int i, idx, end;
58
59     /* set color palette */
60     end = min(1 << col, 1 << planes);
61     for (i = 0; i < end; i++) {
62         switch (planes) { /* MAR -- war col 10.01.2001 */
63         case 1:
64             idx = i;
65             break;
66         case 2:
67             idx = vdi2dev2[i];
68             break;
69         case 4:
70             idx = vdi2dev4[i];
71             break;
72         default:
73             if (i < 16)
74                 idx = vdi2dev4[i];
75             else
76                 idx = i == 255 ? 1 : i;
77         }
78         vs_color(handle, i, (int *) palette + idx * 3);
79     }
80 }
81
82 int
83 convert(MFDB *image, long size)
84 {
85     int plane, mplanes;
86     char *line_addr, *buf_addr, *new_addr, *new1_addr, *image_addr,
87         *screen_addr;
88     MFDB dev_form, tmp;
89     long new_size;
90
91     /* convert size from words to bytes */
92     size <<= 1;
93
94     /* memory for the device raster */
95     new_size = size * (long) planes;
96     if ((new_addr = (char *) calloc(1, new_size)) == NULL)
97         return (FALSE);
98
99     /* initialize MFDBs */
100     tmp = *image;
101     tmp.fd_nplanes = planes;
102     tmp.fd_addr = new_addr;
103     tmp.fd_stand = 1; /* standard format */
104     dev_form = tmp;
105     screen_addr = new_addr;
106     dev_form.fd_stand = 0; /* device format */
107     image_addr = (char *) image->fd_addr;
108
109     /* initialize some variables and zero temp. line buffer */
110     mplanes = min(image->fd_nplanes, planes);
111     /* convert image */
112     line_addr = image_addr;
113     buf_addr = screen_addr;
114     if (mplanes > 1) {
115         /* cut/pad color planes into temp buf */
116         for (plane = 0; plane < mplanes; plane++) {
117             memcpy(buf_addr, line_addr, size);
118             line_addr += size;
119             buf_addr += size;
120         }
121     } else {
122         /* fill temp line bitplanes with a b&w line */
123         for (plane = 0; plane < planes; plane++) {
124             memcpy(buf_addr, line_addr, size);
125             buf_addr += size;
126         }
127     }
128     free(image->fd_addr);
129     /* convert image line in temp into current device raster format */
130     if ((new1_addr = (char *) calloc(1, new_size)) == NULL)
131         return (FALSE);
132     dev_form.fd_addr = new1_addr;
133     vr_trnfm(x_handle, &tmp, &dev_form);
134     free(new_addr);
135
136     /* change image description */
137     image->fd_stand = 0; /* device format */
138     image->fd_addr = new1_addr;
139     image->fd_nplanes = planes;
140     return (TRUE);
141 }
142
143 int
144 transform_img(MFDB *image)
145 { /* return FALSE if transform_img fails */
146     int success;
147     long size;
148
149     if (!image->fd_addr)
150         return (FALSE);
151
152     size = (long) ((long) image->fd_wdwidth * (long) image->fd_h);
153     success = convert(
154         image, size); /* Use vr_trfm(), which needs quite a lot memory. */
155     if (success)
156         return (TRUE);
157     /*  else                            show_error(ERR_ALLOC);  */
158     return (FALSE);
159 }
160
161 /* Loads & depacks IMG (0 if succeded, else error). */
162 /* Bitplanes are one after another in address IMG_HEADER.addr. */
163 int
164 depack_img(char *name, IMG_header *pic)
165 {
166     int b, line, plane, width, word_aligned, opcode, patt_len, pal_size,
167         byte_repeat, patt_repeat, scan_repeat, error = FALSE;
168     char *pattern, *to, *endline, *puffer, sol_pat;
169     long size;
170     FILE *fp;
171
172     if ((fp = fopen(name, "rb")) == NULL)
173         return (ERR_FILE);
174
175     setvbuf(fp, NULL, _IOLBF, BUFSIZ);
176
177     /* read header info (bw & ximg) into image structure */
178     fread((char *) &(pic->version), 2, 8 + 3, fp);
179
180     /* only 2-256 color imgs */
181     if (pic->planes < 1 || pic->planes > 8) {
182         error = ERR_COLOR;
183         goto end_depack;
184     }
185
186     /* if XIMG, read info */
187     if (pic->magic == XIMG && pic->paltype == 0) {
188         pal_size = (1 << pic->planes) * 3 * 2;
189         if ((pic->palette = (short *) calloc(1, pal_size))) {
190             fread((char *) pic->palette, 1, pal_size, fp);
191         }
192     } else {
193         pic->palette = NULL;
194     }
195
196     /* width in bytes word aliged */
197     word_aligned = (pic->img_w + 15) >> 4;
198     word_aligned <<= 1;
199
200     /* width byte aligned */
201     width = (pic->img_w + 7) >> 3;
202
203     /* allocate memory for the picture */
204     free(pic->addr);
205     size = (long) ((long) word_aligned * (long) pic->img_h
206                    * (long) pic->planes); /*MAR*/
207
208     /* check for header validity & malloc long... */
209     if (pic->length > 7 && pic->planes < 33 && pic->img_w > 0
210         && pic->img_h > 0) {
211         if (!(pic->addr = (char *) calloc(1, size))) {
212             error = ERR_ALLOC;
213             goto end_depack;
214         }
215     } else {
216         error = ERR_HEADER;
217         goto end_depack;
218     }
219
220     patt_len = pic->pat_len;
221
222     /* jump over the header and possible (XIMG) info */
223     fseek(fp, (long) pic->length * 2L, SEEK_SET);
224
225     for (line = 0, to = pic->addr; line < pic->img_h;
226          line += scan_repeat) { /* depack whole img */
227         for (plane = 0, scan_repeat = 1; plane < pic->planes;
228              plane++) { /* depack one scan line */
229             puffer = to =
230                 pic->addr
231                 + (long) (line + plane * pic->img_h) * (long) word_aligned;
232             endline = puffer + width;
233             do { /* depack one line in one bitplane */
234                 switch ((opcode = fgetc(fp))) {
235                 case 0: /* pattern or scan repeat */
236                     if ((patt_repeat = fgetc(fp))) { /* repeat a pattern */
237                         fread(to, patt_len, 1, fp);
238                         pattern = to;
239                         to += patt_len;
240                         while (--patt_repeat) { /* copy pattern */
241                             memcpy(to, pattern, patt_len);
242                             to += patt_len;
243                         }
244                     } else { /* repeat a line */
245                         if (fgetc(fp) == 0xFF)
246                             scan_repeat = fgetc(fp);
247                         else {
248                             error = ERR_DEPACK;
249                             goto end_depack;
250                         }
251                     }
252                     break;
253                 case 0x80: /* Literal */
254                     byte_repeat = fgetc(fp);
255                     fread(to, byte_repeat, 1, fp);
256                     to += byte_repeat;
257                     break;
258                 default: /* Solid run */
259                     byte_repeat = opcode & 0x7F;
260                     sol_pat = opcode & 0x80 ? 0xFF : 0x00;
261                     while (byte_repeat--)
262                         *to++ = sol_pat;
263                 }
264             } while (to < endline);
265
266             if (to == endline) {
267                 /* ensure that lines aren't repeated past the end of the img
268                  */
269                 if (line + scan_repeat > pic->img_h)
270                     scan_repeat = pic->img_h - line;
271                 /* copy line to image buffer */
272                 if (scan_repeat > 1) {
273                     /* calculate address of a current line in a current
274                      * bitplane */
275                     /*                                  to=pic->addr+(long)(line+1+plane*pic->img_h)*(long)word_aligned;*/
276                     for (b = scan_repeat - 1; b; --b) {
277                         memcpy(to, puffer, width);
278                         to += word_aligned;
279                     }
280                 }
281             } else {
282                 error = ERR_DEPACK;
283                 goto end_depack;
284             }
285         }
286     }
287
288 end_depack:
289     fclose(fp);
290     return (error);
291 }
292
293 int
294 half_img(MFDB *s, MFDB *d)
295 {
296     int pxy[8], i, j;
297     MFDB tmp;
298
299     mfdb(&tmp, NULL, s->fd_w / 2, s->fd_h, s->fd_stand, s->fd_nplanes);
300     tmp.fd_w = s->fd_w / 2;
301     tmp.fd_addr = calloc(1, mfdb_size(&tmp));
302     if (!tmp.fd_addr)
303         return (FALSE);
304
305     pxy[1] = pxy[5] = 0;
306     pxy[3] = pxy[7] = s->fd_h - 1;
307     for (i = 0; i < s->fd_w / 2; i++) {
308         pxy[0] = pxy[2] = 2 * i;
309         pxy[4] = pxy[6] = i;
310         vro_cpyfm(x_handle, S_ONLY, pxy, s, &tmp);
311     }
312     pxy[0] = pxy[4] = 0;
313     pxy[2] = pxy[6] = s->fd_w / 2 - 1;
314     for (j = 0; j < s->fd_h / 2; j++) {
315         pxy[1] = pxy[3] = 2 * j;
316         pxy[5] = pxy[7] = j;
317         vro_cpyfm(x_handle, S_ONLY, pxy, &tmp, d);
318     }
319     free(tmp.fd_addr);
320     return (TRUE);
321 }