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