1 | #include <allegro.h> |
---|
2 | |
---|
3 | #include <stdio.h> |
---|
4 | #include <stdlib.h> |
---|
5 | #include <math.h> |
---|
6 | #include <libgen.h> |
---|
7 | |
---|
8 | /* |
---|
9 | |
---|
10 | Thomson vitamotion devkit |
---|
11 | |
---|
12 | TGA to RAW image converter with palette editing |
---|
13 | |
---|
14 | b tga converter to various formats: |
---|
15 | |
---|
16 | */ |
---|
17 | |
---|
18 | #define SIZEX (8+320+8+64+8+320+8) |
---|
19 | #define SIZEY (8+200+8+16*4+8) |
---|
20 | |
---|
21 | /* |
---|
22 | * palette tables 8bit <> 4bit with gamma (thomson specific) |
---|
23 | */ |
---|
24 | static int my_gamma[16]={0,100,127,147,163,179,191,203,215,223,231,239,243,247,251,255}; |
---|
25 | static int seuils[17]={0,50,114,137,155,171,185,197,209,219,227,235,241,245,249,253,257}; |
---|
26 | |
---|
27 | char error_str[1024]; |
---|
28 | |
---|
29 | enum {MODE160x16,MODE320x4,MODE640x2,MODE_TO7} to8_mode; |
---|
30 | |
---|
31 | int |
---|
32 | pal_conv(int v) { |
---|
33 | int i; |
---|
34 | for (i=0;i<16;i++) { |
---|
35 | if (v<seuils[i+1]) break; |
---|
36 | } |
---|
37 | return i; |
---|
38 | } |
---|
39 | |
---|
40 | |
---|
41 | int |
---|
42 | pal_conv2(int v) { |
---|
43 | int i; |
---|
44 | for (i=0;i<16;i++) { |
---|
45 | if (v<seuils[i+1]) break; |
---|
46 | } |
---|
47 | return my_gamma[i]; |
---|
48 | } |
---|
49 | |
---|
50 | |
---|
51 | /* |
---|
52 | * ============================================================================================ |
---|
53 | * TGA stuff |
---|
54 | * ============================================================================================ |
---|
55 | */ |
---|
56 | |
---|
57 | typedef struct { |
---|
58 | char idlength; |
---|
59 | char colourmaptype; |
---|
60 | char datatypecode; |
---|
61 | short int colourmaporigin; |
---|
62 | short int colourmaplength; |
---|
63 | char colourmapdepth; |
---|
64 | short int x_origin; |
---|
65 | short int y_origin; |
---|
66 | short width; |
---|
67 | short height; |
---|
68 | char bitsperpixel; |
---|
69 | char imagedescriptor; |
---|
70 | } HEADER; |
---|
71 | |
---|
72 | typedef struct { |
---|
73 | unsigned char r,g,b,a; |
---|
74 | } PIXEL; |
---|
75 | |
---|
76 | void MergeBytes(PIXEL *,unsigned char *,int); |
---|
77 | |
---|
78 | PIXEL *pixels; |
---|
79 | HEADER header; |
---|
80 | |
---|
81 | int palette_24b[256]; |
---|
82 | int palette_24b_limited[256]; |
---|
83 | int palette_to[16]; |
---|
84 | int col_num=1; |
---|
85 | int val; |
---|
86 | |
---|
87 | |
---|
88 | int my_load_tga(char * fname) |
---|
89 | { |
---|
90 | int n=0,i,j; |
---|
91 | int bytes2read,skipover = 0; |
---|
92 | unsigned char p[5]; |
---|
93 | FILE *fptr; |
---|
94 | |
---|
95 | col_num=1; |
---|
96 | /* Open the file */ |
---|
97 | if ((fptr = fopen(fname,"r")) == NULL) { |
---|
98 | sprintf(error_str,"File open failed\n"); |
---|
99 | return -1; |
---|
100 | } |
---|
101 | |
---|
102 | /* Display the header fields */ |
---|
103 | header.idlength = fgetc(fptr); |
---|
104 | fprintf(stderr,"ID length: %d\n",header.idlength); |
---|
105 | header.colourmaptype = fgetc(fptr); |
---|
106 | fprintf(stderr,"Colourmap type: %d\n",header.colourmaptype); |
---|
107 | header.datatypecode = fgetc(fptr); |
---|
108 | fprintf(stderr,"Image type: %d\n",header.datatypecode); |
---|
109 | fread(&header.colourmaporigin,2,1,fptr); |
---|
110 | fprintf(stderr,"Colour map offset: %d\n",header.colourmaporigin); |
---|
111 | fread(&header.colourmaplength,2,1,fptr); |
---|
112 | fprintf(stderr,"Colour map length: %d\n",header.colourmaplength); |
---|
113 | header.colourmapdepth = fgetc(fptr); |
---|
114 | fprintf(stderr,"Colour map depth: %d\n",header.colourmapdepth); |
---|
115 | fread(&header.x_origin,2,1,fptr); |
---|
116 | fprintf(stderr,"X origin: %d\n",header.x_origin); |
---|
117 | fread(&header.y_origin,2,1,fptr); |
---|
118 | fprintf(stderr,"Y origin: %d\n",header.y_origin); |
---|
119 | fread(&header.width,2,1,fptr); |
---|
120 | fprintf(stderr,"Width: %d\n",header.width); |
---|
121 | fread(&header.height,2,1,fptr); |
---|
122 | fprintf(stderr,"Height: %d\n",header.height); |
---|
123 | header.bitsperpixel = fgetc(fptr); |
---|
124 | fprintf(stderr,"Bits per pixel: %d\n",header.bitsperpixel); |
---|
125 | header.imagedescriptor = fgetc(fptr); |
---|
126 | fprintf(stderr,"Descriptor: %d\n",header.imagedescriptor); |
---|
127 | |
---|
128 | /* Allocate space for the image */ |
---|
129 | if ((pixels = malloc(header.width*header.height*sizeof(PIXEL))) == NULL) { |
---|
130 | sprintf(error_str,"malloc of image failed\n"); |
---|
131 | return -1; |
---|
132 | } |
---|
133 | for (i=0;i<header.width*header.height;i++) { |
---|
134 | pixels[i].r = 0; |
---|
135 | pixels[i].g = 0; |
---|
136 | pixels[i].b = 0; |
---|
137 | pixels[i].a = 0; |
---|
138 | } |
---|
139 | |
---|
140 | /* What can we handle */ |
---|
141 | if (header.datatypecode != 2 && header.datatypecode != 10) { |
---|
142 | sprintf(error_str,"Can only handle image type 2 and 10"); |
---|
143 | return -1; |
---|
144 | } |
---|
145 | if (header.bitsperpixel != 16 && |
---|
146 | header.bitsperpixel != 24 && header.bitsperpixel != 32) { |
---|
147 | sprintf(error_str,"Can only handle pixel depths of 16, 24, and 32"); |
---|
148 | return -1; |
---|
149 | } |
---|
150 | if (header.colourmaptype != 0 && header.colourmaptype != 1) { |
---|
151 | fprintf(stderr,"Can only handle colour map types of 0 and 1"); |
---|
152 | return -1; |
---|
153 | } |
---|
154 | |
---|
155 | /* Skip over unnecessary stuff */ |
---|
156 | skipover += header.idlength; |
---|
157 | skipover += header.colourmaptype * header.colourmaplength; |
---|
158 | fprintf(stderr,"Skip over %d bytes\n",skipover); |
---|
159 | fseek(fptr,skipover,SEEK_CUR); |
---|
160 | |
---|
161 | /* Read the image */ |
---|
162 | bytes2read = header.bitsperpixel / 8; |
---|
163 | while (n < header.width * header.height) { |
---|
164 | if (header.datatypecode == 2) { /* Uncompressed */ |
---|
165 | if (fread(p,1,bytes2read,fptr) != bytes2read) { |
---|
166 | sprintf(error_str,"Unexpected end of file at pixel %d\n",i); |
---|
167 | return -1; |
---|
168 | } |
---|
169 | MergeBytes(&(pixels[n]),p,bytes2read); |
---|
170 | n++; |
---|
171 | } else if (header.datatypecode == 10) { /* Compressed */ |
---|
172 | if (fread(p,1,bytes2read+1,fptr) != bytes2read+1) { |
---|
173 | sprintf(error_str,"Unexpected end of file at pixel %d\n",i); |
---|
174 | return -1; |
---|
175 | } |
---|
176 | j = p[0] & 0x7f; |
---|
177 | MergeBytes(&(pixels[n]),&(p[1]),bytes2read); |
---|
178 | n++; |
---|
179 | if (p[0] & 0x80) { /* RLE chunk */ |
---|
180 | for (i=0;i<j;i++) { |
---|
181 | MergeBytes(&(pixels[n]),&(p[1]),bytes2read); |
---|
182 | n++; |
---|
183 | } |
---|
184 | } else { /* Normal chunk */ |
---|
185 | for (i=0;i<j;i++) { |
---|
186 | if (fread(p,1,bytes2read,fptr) != bytes2read) { |
---|
187 | sprintf(error_str,"Unexpected end of file at pixel %d\n",i); |
---|
188 | return -1; |
---|
189 | } |
---|
190 | MergeBytes(&(pixels[n]),p,bytes2read); |
---|
191 | n++; |
---|
192 | } |
---|
193 | } |
---|
194 | } |
---|
195 | } |
---|
196 | fclose(fptr); |
---|
197 | |
---|
198 | |
---|
199 | fprintf(stderr,"[INFO] now in vm part ;) \n"); |
---|
200 | /* now count colors used */ |
---|
201 | palette_24b[0]=(pixels[0].b<<16)|(pixels[0].g<<8)|(pixels[0].r); |
---|
202 | for (i=1;i<header.height*header.width;i++) { |
---|
203 | val=(pixels[i].b<<16)|(pixels[i].g<<8)|(pixels[i].r); |
---|
204 | // does this color exists in palette |
---|
205 | for (j=0;j<col_num;j++) { |
---|
206 | if (palette_24b[j]==val) break; |
---|
207 | } |
---|
208 | if (j==col_num) { |
---|
209 | if (col_num==255) { |
---|
210 | col_num=256; |
---|
211 | sprintf(error_str,"[ERROR] too many colors (+256) !!!\n"); |
---|
212 | return -1; |
---|
213 | } |
---|
214 | palette_24b[col_num]=val; |
---|
215 | col_num++; |
---|
216 | } |
---|
217 | } |
---|
218 | fprintf(stderr,"[INFO] Number of unique colors %d\n",col_num); |
---|
219 | if (header.width==160) { |
---|
220 | if (col_num>16) { |
---|
221 | sprintf(error_str,"[ERROR] too many colors %d max 16\n",col_num); |
---|
222 | return -1; |
---|
223 | } |
---|
224 | to8_mode=MODE160x16; |
---|
225 | } |
---|
226 | |
---|
227 | if (header.width==320) { |
---|
228 | if (col_num>16) { |
---|
229 | sprintf(error_str,"[ERROR] too many colors %d max 4\n",col_num); |
---|
230 | return -1; |
---|
231 | } |
---|
232 | if (col_num>4) { |
---|
233 | to8_mode=MODE_TO7; |
---|
234 | } else { |
---|
235 | to8_mode=MODE320x4; |
---|
236 | } |
---|
237 | } |
---|
238 | |
---|
239 | if (header.width==640) { |
---|
240 | if (col_num>2) { |
---|
241 | sprintf(error_str,"[ERROR] too many colors %d max 2\n",col_num); |
---|
242 | return -1; |
---|
243 | } |
---|
244 | to8_mode=MODE640x2; |
---|
245 | } |
---|
246 | |
---|
247 | |
---|
248 | for (i=0;i<16;i++) palette_to[i]=0; |
---|
249 | |
---|
250 | for (i=0;i<col_num;i++) { |
---|
251 | palette_to[i]=pal_conv((palette_24b[i]&0xFF0000)>>16)<<8; |
---|
252 | palette_to[i]|=pal_conv((palette_24b[i]&0xFF00)>>8)<<4; |
---|
253 | palette_to[i]|=pal_conv((palette_24b[i]&0xFF)); |
---|
254 | |
---|
255 | palette_24b_limited[i]=pal_conv2((palette_24b[i]&0xFF0000)>>16)<<16; |
---|
256 | palette_24b_limited[i]|=pal_conv2((palette_24b[i]&0xFF00)>>8)<<8; |
---|
257 | palette_24b_limited[i]|=pal_conv2((palette_24b[i]&0xFF)); |
---|
258 | |
---|
259 | fprintf(stderr,"[INFO] palette[%d]=%03x\n",i,palette_to[i]); |
---|
260 | } |
---|
261 | |
---|
262 | } |
---|
263 | |
---|
264 | |
---|
265 | int output_to8(char *colname,char *ptname) { |
---|
266 | int n=0,i,j; |
---|
267 | |
---|
268 | |
---|
269 | /* ouput in 2 files raw data 8kb each (palette at end) */ |
---|
270 | FILE *COL; |
---|
271 | FILE *PT; |
---|
272 | |
---|
273 | COL=fopen(colname,"wb"); |
---|
274 | PT=fopen(ptname,"wb"); |
---|
275 | |
---|
276 | if ((COL==NULL) || (PT==NULL)) return -1; |
---|
277 | switch (to8_mode) { |
---|
278 | case MODE160x16: |
---|
279 | // on modifie les pixels 2 par 2 |
---|
280 | for (i=0;i<header.height*header.width;i++) { |
---|
281 | int mem; |
---|
282 | val=(pixels[i].b<<16)|(pixels[i].g<<8)|(pixels[i].r); |
---|
283 | // on retrouve l'index dans la palette dans j |
---|
284 | for (j=0;j<16;j++) { |
---|
285 | if (val==palette_24b[j]) break; |
---|
286 | } |
---|
287 | switch (i%4) { |
---|
288 | case 0 : mem=j<<4; |
---|
289 | break; |
---|
290 | case 1 : fputc(mem|j,PT); |
---|
291 | break; |
---|
292 | case 2 : mem=j<<4; |
---|
293 | break; |
---|
294 | case 3 : fputc(mem|j,COL); |
---|
295 | break; |
---|
296 | } |
---|
297 | } |
---|
298 | for (i=0;i<16;i++) { |
---|
299 | fputc((palette_to[i]&0xFF00)>>8,PT); |
---|
300 | fputc((palette_to[i]&0xFF),PT); |
---|
301 | fputc((palette_to[i]&0xFF00)>>8,COL); |
---|
302 | fputc((palette_to[i]&0xFF),COL); |
---|
303 | } |
---|
304 | break; |
---|
305 | case MODE320x4: |
---|
306 | { |
---|
307 | int ptval=0; |
---|
308 | int colval=0; |
---|
309 | for (i=0;i<header.height*header.width;i++) { |
---|
310 | val=(pixels[i].b<<16)|(pixels[i].g<<8)|(pixels[i].r); |
---|
311 | // on retrouve l'index dans la palette dans j |
---|
312 | for (j=0;j<4;j++) { |
---|
313 | if (val==palette_24b[j]) break; |
---|
314 | } |
---|
315 | ptval=(ptval<<1)|((j&0x02)>>1); |
---|
316 | colval=(colval<<1)|(j&0x01); |
---|
317 | |
---|
318 | if (i%8==7) { |
---|
319 | fputc(ptval&0xFF,PT); |
---|
320 | fputc(colval&0xFF,COL); |
---|
321 | } |
---|
322 | } |
---|
323 | for (i=0;i<4;i++) { |
---|
324 | fputc((palette_to[i]&0xFF00)>>8,PT); |
---|
325 | fputc((palette_to[i]&0xFF),PT); |
---|
326 | fputc((palette_to[i]&0xFF00)>>8,COL); |
---|
327 | fputc((palette_to[i]&0xFF),COL); |
---|
328 | } |
---|
329 | } |
---|
330 | break; |
---|
331 | case MODE_TO7: |
---|
332 | { |
---|
333 | int ptval=0; |
---|
334 | int colval=0; |
---|
335 | int fondrgb; |
---|
336 | int seg[8]; |
---|
337 | int forme_val=0; |
---|
338 | |
---|
339 | /* pour chaque segment de 8 on recherche les 2 couleurs et on reconstruit forme et color */ |
---|
340 | |
---|
341 | for (i=0;i<header.height*header.width;i+=8) { |
---|
342 | for (j=0;j<8;j++) { |
---|
343 | seg[j]=(pixels[i+j].b<<16)|(pixels[i+j].g<<8)|(pixels[i+j].r); |
---|
344 | if (j==0) { |
---|
345 | ptval=0x01; |
---|
346 | fondrgb=seg[j]; |
---|
347 | } |
---|
348 | else |
---|
349 | { |
---|
350 | if (seg[j]==seg[0]) ptval=(ptval<<1)|1; |
---|
351 | else { |
---|
352 | ptval=(ptval<<1); |
---|
353 | fondrgb=seg[j]; |
---|
354 | } |
---|
355 | } |
---|
356 | } |
---|
357 | |
---|
358 | // on retrouve l'index dans la palette dans j |
---|
359 | |
---|
360 | // !2 !1 2 2 2 1 1 1 |
---|
361 | for (j=0;j<16;j++) { |
---|
362 | if (seg[0]==palette_24b[j]) break; |
---|
363 | } |
---|
364 | // fprintf(stderr,"Found %d\n",j); |
---|
365 | |
---|
366 | colval=(((~j)&0x8)<<3)|((j&0x7)<<3); |
---|
367 | for (j=0;j<16;j++) { |
---|
368 | if (fondrgb==palette_24b[j]) break; |
---|
369 | } |
---|
370 | // fprintf(stderr,"Found %d\n",j); |
---|
371 | |
---|
372 | colval|=(((~j)&0x8)<<4)|(j&0x7); |
---|
373 | // fprintf(stderr,"colval %x\n",colval); |
---|
374 | |
---|
375 | // if (i>16) break; |
---|
376 | |
---|
377 | fputc(ptval&0xFF,PT); |
---|
378 | fputc(colval&0xFF,COL); |
---|
379 | } |
---|
380 | |
---|
381 | for (i=0;i<16;i++) { |
---|
382 | fputc((palette_to[i]&0xFF00)>>8,PT); |
---|
383 | fputc((palette_to[i]&0xFF),PT); |
---|
384 | fputc((palette_to[i]&0xFF00)>>8,COL); |
---|
385 | fputc((palette_to[i]&0xFF),COL); |
---|
386 | } |
---|
387 | } |
---|
388 | break; |
---|
389 | } |
---|
390 | fclose(PT); |
---|
391 | fclose(COL); |
---|
392 | |
---|
393 | return 0; |
---|
394 | } |
---|
395 | |
---|
396 | |
---|
397 | |
---|
398 | |
---|
399 | |
---|
400 | int |
---|
401 | output_tga(char *fname) { |
---|
402 | FILE *fptr; |
---|
403 | int i; |
---|
404 | int j; |
---|
405 | int col; |
---|
406 | |
---|
407 | /* Write the result as a uncompressed TGA */ |
---|
408 | if ((fptr = fopen(fname,"w")) == NULL) { |
---|
409 | fprintf(stderr,"Failed to open outputfile\n"); |
---|
410 | return -1; |
---|
411 | } |
---|
412 | putc(0,fptr); |
---|
413 | putc(0,fptr); |
---|
414 | putc(2,fptr); /* uncompressed RGB */ |
---|
415 | putc(0,fptr); putc(0,fptr); |
---|
416 | putc(0,fptr); putc(0,fptr); |
---|
417 | putc(0,fptr); |
---|
418 | putc(0,fptr); putc(0,fptr); /* X origin */ |
---|
419 | putc(0,fptr); putc(0,fptr); /* y origin */ |
---|
420 | putc((header.width & 0x00FF),fptr); |
---|
421 | putc((header.width & 0xFF00) / 256,fptr); |
---|
422 | putc((header.height & 0x00FF),fptr); |
---|
423 | putc((header.height & 0xFF00) / 256,fptr); |
---|
424 | putc(32,fptr); /* 24 bit bitmap */ |
---|
425 | putc(0,fptr); |
---|
426 | for (i=0;i<header.height*header.width;i++) { |
---|
427 | /* putc(pixels[i].b,fptr); |
---|
428 | putc(pixels[i].g,fptr); |
---|
429 | putc(pixels[i].r,fptr); */ |
---|
430 | |
---|
431 | col=((pixels[i].b)<<16)|(pixels[i].g<<8)|pixels[i].r; |
---|
432 | |
---|
433 | for (j=0;j<16;j++) { |
---|
434 | if (col==palette_24b[j]) break; |
---|
435 | } |
---|
436 | |
---|
437 | putc(((palette_24b_limited[j]&0xFF0000)>>16 ),fptr); |
---|
438 | putc(((palette_24b_limited[j]&0xFF00)>>8 ),fptr); |
---|
439 | putc(((palette_24b_limited[j]&0xFF) ),fptr); |
---|
440 | putc(pixels[i].a,fptr); |
---|
441 | } |
---|
442 | fclose(fptr); |
---|
443 | return 0; |
---|
444 | } |
---|
445 | |
---|
446 | void MergeBytes(PIXEL *pixel,unsigned char *p,int bytes) |
---|
447 | { |
---|
448 | if (bytes == 4) { |
---|
449 | pixel->r = p[2]; |
---|
450 | pixel->b = p[0]; |
---|
451 | pixel->g = p[1]; |
---|
452 | pixel->a = p[3]; |
---|
453 | } else if (bytes == 3) { |
---|
454 | pixel->r = p[2]; |
---|
455 | pixel->g = p[1]; |
---|
456 | pixel->b = p[0]; |
---|
457 | pixel->a = 0; |
---|
458 | } else if (bytes == 2) { |
---|
459 | pixel->r = (p[1] & 0x7c) << 1; |
---|
460 | pixel->g = ((p[1] & 0x03) << 6) | ((p[0] & 0xe0) >> 2); |
---|
461 | pixel->b = (p[0] & 0x1f) << 3; |
---|
462 | pixel->a = (p[1] & 0x80); |
---|
463 | } |
---|
464 | } |
---|
465 | |
---|
466 | |
---|
467 | |
---|
468 | |
---|
469 | /* |
---|
470 | * ============================================================================================ |
---|
471 | * allegro GUI stuff :) |
---|
472 | * ============================================================================================ |
---|
473 | */ |
---|
474 | |
---|
475 | static BITMAP *left_image,* right_image, *left_pal,*right_pal; |
---|
476 | |
---|
477 | |
---|
478 | void init() { |
---|
479 | int depth, res; |
---|
480 | FONT *myfont; |
---|
481 | allegro_init(); |
---|
482 | myfont = load_font("8x14t.pcx", NULL, NULL); |
---|
483 | |
---|
484 | install_keyboard(); |
---|
485 | install_sound(DIGI_AUTODETECT,MIDI_AUTODETECT,NULL); |
---|
486 | depth = desktop_color_depth(); |
---|
487 | |
---|
488 | if (depth == 0) depth = 16; |
---|
489 | set_color_depth(depth); |
---|
490 | #ifdef WIN32 |
---|
491 | res = set_gfx_mode(GFX_DIRECTX_WIN, SIZEX, SIZEY, 0, 0); |
---|
492 | #else |
---|
493 | res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, SIZEX, SIZEY, 0, 0); |
---|
494 | #endif |
---|
495 | if (res != 0) { |
---|
496 | allegro_message(allegro_error); |
---|
497 | exit(-1); |
---|
498 | } |
---|
499 | |
---|
500 | if (myfont) { |
---|
501 | font=myfont; |
---|
502 | } |
---|
503 | |
---|
504 | |
---|
505 | install_timer(); |
---|
506 | install_mouse(); |
---|
507 | |
---|
508 | left_image=create_bitmap(320,200); |
---|
509 | right_image=create_bitmap(320,200); |
---|
510 | |
---|
511 | left_pal=create_bitmap(16,256); |
---|
512 | right_pal=create_bitmap(16,256); |
---|
513 | |
---|
514 | } |
---|
515 | |
---|
516 | int |
---|
517 | redraw_right(void) { |
---|
518 | int i,val,j; |
---|
519 | for (i=0;i<header.height*header.width;i++) { |
---|
520 | int mem; |
---|
521 | val=(pixels[i].b<<16)|(pixels[i].g<<8)|(pixels[i].r); |
---|
522 | // on retrouve l'index dans la palette dans j |
---|
523 | for (j=0;j<16;j++) { |
---|
524 | if (val==palette_24b[j]) break; |
---|
525 | } |
---|
526 | switch (to8_mode) { |
---|
527 | case MODE160x16: |
---|
528 | putpixel(right_image,(i%160)*2,i/160,makecol((palette_24b_limited[j]&0xFF), |
---|
529 | (palette_24b_limited[j]&0xFF00)>>8, |
---|
530 | (palette_24b_limited[j]&0xFF0000)>>16 ) ); |
---|
531 | putpixel(right_image,(i%160)*2+1,i/160,makecol((palette_24b_limited[j]&0xFF), |
---|
532 | (palette_24b_limited[j]&0xFF00)>>8, |
---|
533 | (palette_24b_limited[j]&0xFF0000)>>16 ) ); |
---|
534 | break; |
---|
535 | case MODE320x4: |
---|
536 | case MODE_TO7: |
---|
537 | putpixel(right_image,i%320,i/320,makecol((palette_24b_limited[j]&0xFF), |
---|
538 | (palette_24b_limited[j]&0xFF00)>>8, |
---|
539 | (palette_24b_limited[j]&0xFF0000)>>16 ) ); |
---|
540 | break; |
---|
541 | case MODE640x2: |
---|
542 | { |
---|
543 | int j2,val2; |
---|
544 | int r,g,b; |
---|
545 | val2=(pixels[i+1].b<<16)|(pixels[i+1].g<<8)|(pixels[i+1].r); |
---|
546 | // on retrouve l'index dans la palette dans j |
---|
547 | for (j2=0;j2<16;j2++) { |
---|
548 | if (val2==palette_24b[j2]) break; |
---|
549 | } |
---|
550 | r=((palette_24b_limited[j]&0xFF)+(palette_24b_limited[j2]&0xFF))/2; |
---|
551 | g=((palette_24b_limited[j]&0xFF00)+(palette_24b_limited[j2]&0xFF00))/2; |
---|
552 | b=((palette_24b_limited[j]&0xFF0000)+(palette_24b_limited[j2]&0xFF0000))/2; |
---|
553 | putpixel(right_image,(i%640)/2,i/640,makecol(r,g>>8,b>>16 ) ); |
---|
554 | } |
---|
555 | i++; |
---|
556 | break; |
---|
557 | } |
---|
558 | } |
---|
559 | } |
---|
560 | |
---|
561 | |
---|
562 | /* |
---|
563 | * The COLOR dialog |
---|
564 | */ |
---|
565 | |
---|
566 | BITMAP *colors[16]; |
---|
567 | |
---|
568 | #define COLOR0 1 |
---|
569 | #define COLOR15 (1+15) |
---|
570 | #define SLIDER_R 18 |
---|
571 | #define SLIDER_G 19 |
---|
572 | #define SLIDER_B 20 |
---|
573 | #define EXIT_BUTTON 23 |
---|
574 | #define PREVIEW 21 |
---|
575 | |
---|
576 | char info[256]="index:0 val:000"; |
---|
577 | |
---|
578 | int slider_cb(void *dp3, int d2); |
---|
579 | |
---|
580 | DIALOG color_dialog[] = |
---|
581 | { |
---|
582 | /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3) */ |
---|
583 | { d_shadow_box_proc, 0, 0, SIZEX, SIZEY, 0, 0, 0, D_DISABLED, 0, 0, (void*)NULL, NULL, NULL }, |
---|
584 | |
---|
585 | { d_icon_proc, 8, 8, 16, 16, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL }, |
---|
586 | { d_icon_proc, 8, 8+1*16, 16, 16, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL }, |
---|
587 | { d_icon_proc, 8, 8+2*16, 16, 16, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL }, |
---|
588 | { d_icon_proc, 8, 8+3*16, 16, 16, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL }, |
---|
589 | |
---|
590 | { d_icon_proc, 8, 8+4*16, 16, 16, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL }, |
---|
591 | { d_icon_proc, 8, 8+5*16, 16, 16, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL }, |
---|
592 | { d_icon_proc, 8, 8+6*16, 16, 16, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL }, |
---|
593 | { d_icon_proc, 8, 8+7*16, 16, 16, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL }, |
---|
594 | |
---|
595 | { d_icon_proc, 8, 8+8*16, 16, 16, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL }, |
---|
596 | { d_icon_proc, 8, 8+9*16, 16, 16, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL }, |
---|
597 | { d_icon_proc, 8, 8+10*16, 16, 16, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL }, |
---|
598 | { d_icon_proc, 8, 8+11*16, 16, 16, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL }, |
---|
599 | |
---|
600 | { d_icon_proc, 8, 8+12*16, 16, 16, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL }, |
---|
601 | { d_icon_proc, 8, 8+13*16, 16, 16, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL }, |
---|
602 | { d_icon_proc, 8, 8+14*16, 16, 16, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL }, |
---|
603 | { d_icon_proc, 8, 8+15*16, 16, 16, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL }, |
---|
604 | |
---|
605 | { d_icon_proc, 8+16+8, 8, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }, // current col |
---|
606 | |
---|
607 | { d_slider_proc, 8+16+8, 8+16+8, 16*16, 16, 0, 0, 0, 0, 15, 0, NULL ,&slider_cb,NULL}, |
---|
608 | { d_slider_proc, 8+16+8, 8+16+8+16+8, 16*16, 16, 0, 0, 0, 0, 15, 0, NULL,&slider_cb,NULL }, |
---|
609 | { d_slider_proc, 8+16+8, 8+16+8+16+8+16+8, 16*16, 16, 0, 0, 0, 0, 15, 0, NULL,&slider_cb,NULL }, |
---|
610 | |
---|
611 | { d_icon_proc, 8+320+8+64+8, 8, 320, 200, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL }, |
---|
612 | |
---|
613 | { d_text_proc, 8+16+8+16+8, 8, 8*20, 8, 0, 0, 0, 0, 0, 0, info, NULL, NULL }, |
---|
614 | |
---|
615 | { d_button_proc, 8+16+8, 8+16+8+16+8+16+8+16+8, 8*16, 16, 0, 0, 0, D_EXIT, 0, 0, "RETURN", NULL, NULL }, |
---|
616 | |
---|
617 | { d_text_proc, 8+16+8+256+8, 8+16+8, 8*8, 16, 0, 0, 0, D_EXIT, 0, 0, "Red" ,NULL,NULL}, |
---|
618 | { d_text_proc, 8+16+8+256+8, 8+16+8+16+8, 8*8, 16, 0, 0, D_EXIT, 0, 0, 0, "Green",NULL,NULL }, |
---|
619 | { d_text_proc, 8+16+8+256+8, 8+16+8+16+8+16+8, 8*8, 16, 0, D_EXIT, 0, 0, 0, 0, "Blue",NULL,NULL }, |
---|
620 | |
---|
621 | |
---|
622 | { d_yield_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }, |
---|
623 | { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL } |
---|
624 | }; |
---|
625 | |
---|
626 | static current_col=0; |
---|
627 | |
---|
628 | void |
---|
629 | info_rebuild(int current_col) { |
---|
630 | sprintf(info,"index:%02d val:%01X%01X%01X", |
---|
631 | current_col, |
---|
632 | pal_conv(palette_24b_limited[current_col]&0xFF), |
---|
633 | pal_conv((palette_24b_limited[current_col]&0xFF00)>>8), |
---|
634 | pal_conv((palette_24b_limited[current_col]&0xFF0000)>>16)); |
---|
635 | } |
---|
636 | |
---|
637 | int slider_cb(void *dp3, int d2) { |
---|
638 | int red,green,blue; |
---|
639 | int x,y; |
---|
640 | red=my_gamma[color_dialog[SLIDER_R].d2]; |
---|
641 | green=my_gamma[color_dialog[SLIDER_G].d2]; |
---|
642 | blue=my_gamma[color_dialog[SLIDER_B].d2]; |
---|
643 | |
---|
644 | palette_24b_limited[current_col]=red|(green<<8)|(blue<<16); |
---|
645 | |
---|
646 | int col=makecol((palette_24b_limited[current_col]&0xFF),(palette_24b_limited[current_col]&0xFF00)>>8,(palette_24b_limited[current_col]&0xFF0000)>>16); |
---|
647 | for (y=0;y<16;y++) |
---|
648 | for (x=0;x<16;x++) { |
---|
649 | putpixel(colors[current_col],x,y,col); |
---|
650 | } |
---|
651 | |
---|
652 | redraw_right(); |
---|
653 | info_rebuild(current_col); |
---|
654 | |
---|
655 | return D_REDRAW; |
---|
656 | } |
---|
657 | |
---|
658 | |
---|
659 | int color_dialog_do(void) { |
---|
660 | int ret; |
---|
661 | int i,x,y; |
---|
662 | static int first=1; |
---|
663 | int end=0; |
---|
664 | |
---|
665 | if (first) { |
---|
666 | for (i=0;i<16;i++) { |
---|
667 | colors[i]=create_bitmap(16,16); |
---|
668 | color_dialog[i+1].dp = colors[i]; |
---|
669 | } |
---|
670 | first=0; |
---|
671 | } |
---|
672 | |
---|
673 | do { |
---|
674 | |
---|
675 | // couleur courante |
---|
676 | color_dialog[16+1].dp = colors[current_col]; |
---|
677 | redraw_right(); |
---|
678 | color_dialog[PREVIEW].dp = right_image; |
---|
679 | |
---|
680 | for (i=0;i<16;i++) { |
---|
681 | int col=makecol((palette_24b_limited[i]&0xFF),(palette_24b_limited[i]&0xFF00)>>8,(palette_24b_limited[i]&0xFF0000)>>16); |
---|
682 | for (y=0;y<16;y++) |
---|
683 | for (x=0;x<16;x++) { |
---|
684 | putpixel(colors[i],x,y,col); |
---|
685 | } |
---|
686 | } |
---|
687 | |
---|
688 | color_dialog[SLIDER_R].d2=pal_conv(palette_24b_limited[current_col]&0xFF); |
---|
689 | color_dialog[SLIDER_G].d2=pal_conv((palette_24b_limited[current_col]&0xFF00)>>8); |
---|
690 | color_dialog[SLIDER_B].d2=pal_conv((palette_24b_limited[current_col]&0xFF0000)>>16); |
---|
691 | info_rebuild(current_col); |
---|
692 | |
---|
693 | /* set up colors */ |
---|
694 | gui_fg_color = makecol(0, 0, 0); |
---|
695 | gui_mg_color = makecol(128, 128, 128); |
---|
696 | gui_bg_color = makecol(200, 200, 200); |
---|
697 | set_dialog_color (color_dialog, gui_fg_color, gui_bg_color); |
---|
698 | |
---|
699 | clear_keybuf(); |
---|
700 | ret=popup_dialog(color_dialog,-1); |
---|
701 | |
---|
702 | if ((ret>=COLOR0) && (ret<=COLOR15)) { |
---|
703 | current_col=ret-COLOR0; |
---|
704 | } |
---|
705 | |
---|
706 | if (ret==EXIT_BUTTON) { |
---|
707 | end=1; |
---|
708 | } |
---|
709 | |
---|
710 | } while (!end); |
---|
711 | return 0; |
---|
712 | } |
---|
713 | |
---|
714 | /* |
---|
715 | * The Main dialog |
---|
716 | */ |
---|
717 | |
---|
718 | |
---|
719 | |
---|
720 | |
---|
721 | #define LEFT_ICON 1 |
---|
722 | #define RIGHT_ICON 2 |
---|
723 | #define LEFT_PAL 3 |
---|
724 | #define RIGHT_PAL 4 |
---|
725 | |
---|
726 | #define MAIN_LOAD 5 |
---|
727 | #define MAIN_EXIT 6 |
---|
728 | #define MAIN_SAVE_TGA 7 |
---|
729 | #define MAIN_SAVE_TO8 8 |
---|
730 | #define MAIN_EDIT_PALETTE 9 |
---|
731 | |
---|
732 | DIALOG main_dialog[] = |
---|
733 | { |
---|
734 | /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3) */ |
---|
735 | { d_shadow_box_proc, 0, 0, SIZEX, SIZEY, 0, 0, 0, D_DISABLED, 0, 0, (void*)NULL, NULL, NULL }, |
---|
736 | { d_icon_proc, 8, 8, 320, 200, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL }, |
---|
737 | { d_icon_proc, 8+320+8+64+8, 8, 320, 200, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL }, |
---|
738 | { d_icon_proc, 8+320+8, 8, 16, 256, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL }, |
---|
739 | { d_icon_proc, 8+320+8+48, 8, 16, 256, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL }, |
---|
740 | |
---|
741 | { d_button_proc, 8, 8+200+8, 8*16, 16, 0, 0, 0, D_EXIT, 0, 0, "LOAD TGA", NULL, NULL }, |
---|
742 | { d_button_proc, 8, 8+200+8+16+8, 8*16, 16, 0, 0, 0, D_EXIT, 0, 0, "EXIT", NULL, NULL }, |
---|
743 | |
---|
744 | { d_button_proc, 8+320+8+64+8, 8+200+8, 8*16, 16, 0, 0, 0, D_EXIT, 0, 0, "SAVE TGA", NULL, NULL }, |
---|
745 | { d_button_proc, 8+320+8+64+8, 8+200+8+16+8, 8*16, 16, 0, 0, 0, D_EXIT, 0, 0, "SAVE TO8", NULL, NULL }, |
---|
746 | { d_button_proc, 8+320+8+64+8, 8+200+8+16+8+16+8, 8*16, 16, 0, 0, 0, D_EXIT, 0, 0, "EDIT PALETTE", NULL, NULL }, |
---|
747 | |
---|
748 | { d_yield_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }, |
---|
749 | { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL } |
---|
750 | }; |
---|
751 | |
---|
752 | char memo_path[6*1024]="\0"; |
---|
753 | |
---|
754 | int main_dialog_do(void) { |
---|
755 | int ret; |
---|
756 | int i,x,y; |
---|
757 | |
---|
758 | /* set up colors */ |
---|
759 | gui_fg_color = makecol(0, 0, 0); |
---|
760 | gui_mg_color = makecol(128, 128, 128); |
---|
761 | gui_bg_color = makecol(200, 200, 200); |
---|
762 | set_dialog_color (main_dialog, gui_fg_color, gui_bg_color); |
---|
763 | |
---|
764 | main_dialog[LEFT_ICON].dp = left_image; |
---|
765 | main_dialog[RIGHT_ICON].dp = right_image; |
---|
766 | main_dialog[LEFT_PAL].dp = left_pal; |
---|
767 | main_dialog[RIGHT_PAL].dp = right_pal; |
---|
768 | |
---|
769 | clear_keybuf(); |
---|
770 | ret=do_dialog(main_dialog,-1); |
---|
771 | |
---|
772 | /* action on left click */ |
---|
773 | if ((ret==LEFT_ICON) || (ret==MAIN_LOAD)) { |
---|
774 | char path[6*1024]; |
---|
775 | strcpy(path,memo_path); |
---|
776 | file_select_ex("Load a TGA 320x200 image", |
---|
777 | path, |
---|
778 | NULL, |
---|
779 | 1024, |
---|
780 | 512, |
---|
781 | 256); |
---|
782 | if (my_load_tga(path)!=-1) { |
---|
783 | i=0; |
---|
784 | for (y=0;y<200;y++) |
---|
785 | for (x=0;x<320;x++) { |
---|
786 | switch (to8_mode) { |
---|
787 | case MODE160x16: |
---|
788 | putpixel(left_image,x,y,makecol(pixels[i].r,pixels[i].g,pixels[i].b)); |
---|
789 | putpixel(left_image,x+1,y,makecol(pixels[i].r,pixels[i].g,pixels[i].b)); |
---|
790 | x++; // note this ;) ok, not very nice... |
---|
791 | i++; |
---|
792 | break; |
---|
793 | case MODE_TO7: |
---|
794 | case MODE320x4: |
---|
795 | putpixel(left_image,x,y,makecol(pixels[i].r,pixels[i].g,pixels[i].b)); |
---|
796 | i++; |
---|
797 | break; |
---|
798 | case MODE640x2: |
---|
799 | putpixel(left_image,x,y,makecol((pixels[i].r+pixels[i+1].r)/2, |
---|
800 | (pixels[i].g+pixels[i+1].g)/2, |
---|
801 | (pixels[i].b+pixels[i+1].b)/2)); |
---|
802 | i+=2; |
---|
803 | break; |
---|
804 | } |
---|
805 | } |
---|
806 | for (i=0;i<16;i++) |
---|
807 | for (y=0;y<16;y++) |
---|
808 | for (x=0;x<16;x++) { |
---|
809 | putpixel(left_pal,x,y+16*i,makecol((palette_24b[i]&0xFF),(palette_24b[i]&0xFF00)>>8,(palette_24b[i]&0xFF0000)>>16 ) ); |
---|
810 | |
---|
811 | putpixel(right_pal,x,y+16*i,makecol((palette_24b_limited[i]&0xFF),(palette_24b_limited[i]&0xFF00)>>8,(palette_24b_limited[i]&0xFF0000)>>16 ) ); |
---|
812 | } |
---|
813 | redraw_right(); |
---|
814 | } else { |
---|
815 | alert(error_str,"" , NULL, "OK", NULL, 0, 0); |
---|
816 | } |
---|
817 | strcpy(memo_path,dirname(path)); /* after use of path ;) */ |
---|
818 | strcat(memo_path,"/"); |
---|
819 | |
---|
820 | } // of if ret==LEFT_ICON |
---|
821 | |
---|
822 | if ((ret==RIGHT_PAL) || (ret==MAIN_EDIT_PALETTE)) { |
---|
823 | color_dialog_do(); |
---|
824 | redraw_right(); |
---|
825 | for (i=0;i<16;i++) |
---|
826 | for (y=0;y<16;y++) |
---|
827 | for (x=0;x<16;x++) { |
---|
828 | putpixel(left_pal,x,y+16*i,makecol((palette_24b[i]&0xFF),(palette_24b[i]&0xFF00)>>8,(palette_24b[i]&0xFF0000)>>16 ) ); |
---|
829 | |
---|
830 | putpixel(right_pal,x,y+16*i,makecol((palette_24b_limited[i]&0xFF),(palette_24b_limited[i]&0xFF00)>>8,(palette_24b_limited[i]&0xFF0000)>>16 ) ); |
---|
831 | } |
---|
832 | for (i=0;i<16;i++) { |
---|
833 | palette_to[i]=pal_conv((palette_24b_limited[i]&0xFF0000)>>16)<<8; |
---|
834 | palette_to[i]|=pal_conv((palette_24b_limited[i]&0xFF00)>>8)<<4; |
---|
835 | palette_to[i]|=pal_conv((palette_24b_limited[i]&0xFF)); |
---|
836 | } |
---|
837 | } |
---|
838 | |
---|
839 | if ((ret==MAIN_EXIT) && (alert("Quit?","" , NULL, "OK", "NO", 0, 0)==1)) { |
---|
840 | return -1; |
---|
841 | } |
---|
842 | |
---|
843 | if (ret==MAIN_SAVE_TGA) { |
---|
844 | char path[6*1024]; |
---|
845 | strcpy(path,memo_path); |
---|
846 | file_select_ex("Save a TGA 320x200 image", |
---|
847 | path, |
---|
848 | NULL, |
---|
849 | 1024, |
---|
850 | 512, |
---|
851 | 256); |
---|
852 | if ((access(path,F_OK)!=-1) && (alert("Replace file?","",NULL,"Yes","No",0,0)==2) ) return 0; |
---|
853 | if (output_tga(path)!=0) alert("Save TGA failed !","",NULL,"Ok",NULL,0,0); |
---|
854 | strcpy(memo_path,dirname(path)); /* after use of path ;) */ |
---|
855 | strcat(memo_path,"/"); |
---|
856 | } |
---|
857 | |
---|
858 | if (ret==MAIN_SAVE_TO8) { |
---|
859 | char path[6*1024]; |
---|
860 | strcpy(path,memo_path); |
---|
861 | char path2[6*1024]; |
---|
862 | |
---|
863 | file_select_ex("Save first COLOR file", |
---|
864 | path, |
---|
865 | NULL, |
---|
866 | 1024, |
---|
867 | 512, |
---|
868 | 256); |
---|
869 | if ((access(path,F_OK)!=-1) && (alert("Replace file?","",NULL,"Yes","No",0,0)==2) ) return 0; |
---|
870 | |
---|
871 | strcpy(path2,memo_path); |
---|
872 | |
---|
873 | file_select_ex("Save second POINT file", |
---|
874 | path2, |
---|
875 | NULL, |
---|
876 | 1024, |
---|
877 | 512, |
---|
878 | 256); |
---|
879 | if ((access(path2,F_OK)!=-1) && (alert("Replace file?","",NULL,"Yes","No",0,0)==2) ) return 0; |
---|
880 | |
---|
881 | |
---|
882 | if (output_to8(path,path2)!=0) alert("Save TO8 failed !","",NULL,"Ok",NULL,0,0); |
---|
883 | strcpy(memo_path,dirname(path)); /* after use of path ;) */ |
---|
884 | strcat(memo_path,"/"); |
---|
885 | |
---|
886 | } |
---|
887 | |
---|
888 | return 0; |
---|
889 | } |
---|
890 | |
---|
891 | |
---|
892 | main(int argc,char **argv) { |
---|
893 | init(); |
---|
894 | while (main_dialog_do()!=-1) { |
---|
895 | } |
---|
896 | } |
---|
897 | END_OF_MAIN() |
---|
898 | |
---|
899 | |
---|