00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #if (defined(MAIN_XTABDAT8)||defined(MAIN_XTABJTY))
00022 #include <stdio.h>
00023 #endif
00024
00025 #include <stdlib.h>
00026 #include <string.h>
00027
00028 #include "bulcommn.h"
00029 #include "memfile.h"
00030 #include "xtabjty.h"
00031 #include "xtabdat8.h"
00032
00033
00034 #ifdef MAIN_XTABJTY
00035
00036 int main (int argc, char **argv)
00037 {
00038 printf("\nBullfrog Engine JTY/TAB Pair Extractor");
00039 printf("\n-------------------------------\n");
00040 if (argc<3)
00041 {
00042 printf("Not enought parameters.\n");
00043 printf("Usage:\n");
00044 printf(" %s <datafile> <palfile>\n","xtabjty");
00045 printf("Output: pic????.bmp\n");
00046 return 1;
00047 }
00048
00049 printf("Loading palette ...");
00050
00051 char *palette=malloc(768);
00052 {
00053 char fname[255];
00054 sprintf (fname, "%s.pal", argv[2]);
00055 int retcode=read_palette_rgb(palette,fname,256);
00056 if (retcode!=0)
00057 switch (retcode)
00058 {
00059 case 1:
00060 printf("\nError - Cannot open PAL file: %s\n",fname);
00061 return 11;
00062 case 2:
00063 printf("\nError - Cannot read %d colors from PAL file: %s\n",256,fname);
00064 return 12;
00065 default:
00066 printf("\nError - Loading palette file %s returned fail code %d\n",fname,retcode);
00067 return 19;
00068 }
00069 }
00070 printf("Done.\n");
00071
00072
00073 struct IMAGELIST images;
00074 {
00075 char tabfname[255];
00076 sprintf (tabfname, "%s.tab", argv[1]);
00077 char jtyfname[255];
00078 sprintf (jtyfname, "%s.jty", argv[1]);
00079 int retcode=create_images_jtytab_idx(&images,jtyfname,tabfname,1);
00080 if (retcode!=0) return retcode;
00081 }
00082
00083
00084 printf("Extracting images into bitmaps...");
00085 unsigned long picnum;
00086 for (picnum=0;picnum<images.count;picnum++)
00087 {
00088
00089 char fname[20];
00090 sprintf (fname, "pic%0*d.bmp", 4, picnum);
00091 IMAGEITEM *item=&(images.items[picnum]);
00092 if ((item->width*item->height)>0)
00093 write_bmp_idx(fname, item->width, item->height, palette, item->data, 0, 1, 2, 4);
00094 }
00095 printf("completed.\n");
00096
00097 free_dattab_images(&images);
00098
00099 free(palette);
00100 return 0;
00101 }
00102
00103 #endif
00104
00105
00106
00107
00108 short create_images_jtytab_enc(struct ENCIMAGELIST *images,const char *jtyfname,
00109 const char *tabfname,const int verbose)
00110 {
00111 if (verbose) msgprintf("Reading TAB file ...");
00112
00113 struct JTYTABFILE jtabf;
00114 {
00115 int retcode=read_jtytabfile_data(&jtabf,tabfname);
00116 switch (retcode)
00117 {
00118 case ERR_NONE:
00119 break;
00120 case JTYTB_CANNOT_OPEN:
00121 if (verbose) msgprintf(" Error\nCannot open TAB file \"%s\"\n",tabfname);
00122 return JTYTB_CANNOT_OPEN;
00123 default:
00124 if (verbose) msgprintf(" Error\nLoading TAB file \"%s\" returned fail code %d\n",tabfname,retcode);
00125 return retcode;
00126 }
00127 }
00128 if (verbose) msgprintf(" Done.\n");
00129
00130 if (verbose) msgprintf("Reading JTY file ...");
00131
00132 struct DATFILE jtyf;
00133 {
00134 int retcode=read_datfile_data(&jtyf,jtyfname);
00135 switch (retcode)
00136 {
00137 case ERR_NONE:
00138 break;
00139 case JTYTB_CANNOT_OPEN:
00140 if (verbose) msgprintf(" Error\nCannot open JTY file \"%s\"\n",jtyfname);
00141 return JTYTB_CANNOT_OPEN;
00142 default:
00143 if (verbose) msgprintf(" Error\nLoading JTY file \"%s\" returned fail code %d\n",jtyfname,retcode);
00144 return retcode;
00145 }
00146 }
00147 if (verbose) msgprintf(" Done.\n");
00148
00149 if (verbose)
00150 {
00151 msgprintf("\n");
00152 msgprintf ("The TAB file informs of %lu pictures.\n", jtabf.count);
00153 if (jtabf.filelength!=jtabf.count*JTYTAB_ENTRY_SIZE)
00154 {
00155 msgprintf("Warning - the TAB file contains incomplete entry at end.\n");
00156 msgprintf(" The truncated entry will be skipped.\n");
00157 }
00158 if (jtyf.count==-1)
00159 {
00160 msgprintf ("The JTY file informs of 4bpp content.\n");
00161 msgprintf ("Warning - this is 8bpp extractor!\n");
00162 }
00163 }
00164 unsigned long readcount=0;
00165 read_jtytab_encimages(images,&readcount,&jtabf,&jtyf,verbose);
00166
00167 if (verbose)
00168 {
00169 msgprintf("Processed %lu of %lu bytes of JTY file.\n",readcount,jtyf.filelength);
00170 long unused=jtyf.filelength-readcount;
00171 if (unused>0)
00172 {
00173 msgprintf("Bytes skipped: %ld\n",unused);
00174 } else
00175 if (unused<0)
00176 {
00177 msgprintf("Bytes overlapping: %ld\n",-unused);
00178 }
00179 }
00180
00181 free_jtytabfile_data(&jtabf);
00182 free_datfile_data(&jtyf);
00183 return ERR_NONE;
00184 }
00185
00186
00187
00188
00189 short write_jtytab_images_enc(const struct ENCIMAGELIST *images,const char *jtyfname,
00190 const char *tabfname,const int verbose)
00191 {
00192 struct JTYTABFILE jtabf;
00193 struct DATFILE jtyf;
00194 unsigned long writecount=0;
00195 write_encimages_jtytab(images,&writecount,&jtabf,&jtyf);
00196 if (verbose) msgprintf("Writing TAB file ...");
00197 write_jtytabfile_data(&jtabf,tabfname);
00198 if (verbose) msgprintf(" Done.\n");
00199 if (verbose) msgprintf("Writing DAT file ...");
00200 write_datfile_data(&jtyf,jtyfname);
00201 if (verbose) msgprintf(" Done.\n");
00202 free_jtytabfile_data(&jtabf);
00203 free_datfile_data(&jtyf);
00204 return ERR_NONE;
00205 }
00206
00207 short create_images_jtytab_idx(struct IMAGELIST *images,const char *jtyfname,
00208 const char *tabfname,int verbose)
00209 {
00210 if (verbose) msgprintf("Reading TAB file ...");
00211
00212 struct JTYTABFILE jtabf;
00213 {
00214 int retcode=read_jtytabfile_data(&jtabf,tabfname);
00215 switch (retcode)
00216 {
00217 case ERR_NONE:
00218 break;
00219 case 1:
00220 if (verbose) msgprintf(" Error\nCannot open TAB file \"%s\"\n",tabfname);
00221 return JTYTB_CANNOT_OPEN;
00222 default:
00223 if (verbose) msgprintf(" Error\nLoading TAB file \"%s\" returned fail code %d\n",tabfname,retcode);
00224 return retcode;
00225 }
00226 }
00227 if (verbose) msgprintf(" Done.\n");
00228
00229 if (verbose) msgprintf("Reading JTY file ...");
00230
00231 struct DATFILE jtyf;
00232 {
00233 int retcode=read_datfile_data(&jtyf,jtyfname);
00234 switch (retcode)
00235 {
00236 case ERR_NONE:
00237 break;
00238 case JTYTB_CANNOT_OPEN:
00239 if (verbose) msgprintf(" Error\nCannot open JTY file \"%s\"\n",jtyfname);
00240 return JTYTB_CANNOT_OPEN;
00241 default:
00242 if (verbose) msgprintf(" Error\nLoading JTY file \"%s\" returned fail code %d\n",jtyfname,retcode);
00243 return retcode;
00244 }
00245 }
00246 if (verbose) msgprintf(" Done.\n");
00247
00248 if (verbose)
00249 {
00250 msgprintf("\n");
00251 msgprintf ("The TAB file informs of %lu pictures.\n", jtabf.count);
00252 if (jtabf.filelength!=(jtabf.count+1)*6)
00253 {
00254 msgprintf("Warning - the TAB file contains incomplete entry at end.\n");
00255 msgprintf(" The truncated entry will be skipped.\n");
00256 }
00257 if (jtyf.count==-1)
00258 {
00259 msgprintf ("The JTY file informs of 4bpp content.\n");
00260 msgprintf ("Warning - this is 8bpp extractor!\n");
00261 }
00262 else
00263 msgprintf ("The JTY file informs of %ld pictures.\n", jtyf.count);
00264 }
00265 if (verbose) msgprintf("Decoding images ...");
00266 unsigned long readcount=2;
00267 read_jtytab_images(images,&readcount,&jtabf,&jtyf,verbose);
00268 if (verbose) msgprintf(" Done.\n");
00269
00270 if (verbose)
00271 {
00272 msgprintf("Processed %lu of %lu bytes of JTY file.\n",readcount,jtyf.filelength);
00273 long unused=jtyf.filelength-readcount;
00274 if (unused>=0)
00275 msgprintf("Bytes skipped: %ld\n",unused);
00276 else
00277 msgprintf("Bytes overlapping: %ld\n",-unused);
00278 }
00279
00280 free_jtytabfile_data(&jtabf);
00281 free_datfile_data(&jtyf);
00282 return ERR_NONE;
00283 }
00284
00285 short read_jtytabfile_data(struct JTYTABFILE *jtabf,const char *srcfname)
00286 {
00287 FILE *tabfp;
00288 tabfp = fopen (srcfname, "rb");
00289 if (!tabfp)
00290 return JTYTB_CANNOT_OPEN;
00291 jtabf->filelength=file_length_opened(tabfp);
00292 if (alloc_jtytabfile_data(jtabf,jtabf->filelength/JTYTAB_ENTRY_SIZE)!=ERR_NONE)
00293 {
00294 fclose(tabfp);
00295 return JTYTB_MALLOC_ERR;
00296 }
00297 unsigned char tabitm[JTYTAB_ENTRY_SIZE];
00298 int entrynum;
00299 for (entrynum=0;entrynum<jtabf->count;entrynum++)
00300 {
00301 struct JTYTAB_ITEM *curitm=&(jtabf->items[entrynum]);
00302 unsigned long readed=fread (tabitm, 1, JTYTAB_ENTRY_SIZE, tabfp);
00303 curitm->offset=read_int32_le_buf(tabitm);
00304 curitm->width=tabitm[4];
00305 curitm->height=tabitm[5];
00306 memcpy(curitm->attrib.unkn,tabitm+6,10);
00307 if (readed < JTYTAB_ENTRY_SIZE) return JTYTB_CANNOT_READ;
00308 }
00309 fclose(tabfp);
00310 return ERR_NONE;
00311 }
00312
00313 short write_jtytabfile_data(const struct JTYTABFILE *jtabf,const char *dstfname)
00314 {
00315 FILE *tabfp;
00316 tabfp = fopen (dstfname, "wb");
00317 if (tabfp==NULL)
00318 return JTYTB_CANNOT_OPEN;
00319 int entrynum;
00320 for (entrynum=0;entrynum<jtabf->count;entrynum++)
00321 {
00322 struct JTYTAB_ITEM *curitm=&(jtabf->items[entrynum]);
00323 write_int32_le_file(tabfp,curitm->offset);
00324 fputc(curitm->width,tabfp);
00325 fputc(curitm->height,tabfp);
00326 fwrite (curitm->attrib.unkn, 10, 1, tabfp);
00327 }
00328 fclose(tabfp);
00329 return ERR_NONE;
00330 }
00331
00332
00333
00334
00335 short alloc_jtytabfile_data(struct JTYTABFILE *jtabf,long count)
00336 {
00337 jtabf->count=count;
00338 jtabf->items=malloc(jtabf->count*sizeof(struct JTYTAB_ITEM));
00339 if (jtabf->items==NULL)
00340 {
00341 jtabf->count=0;
00342 return JTYTB_MALLOC_ERR;
00343 }
00344 return ERR_NONE;
00345 }
00346
00347
00348
00349
00350
00351 short free_jtytabfile_data(struct JTYTABFILE *jtabf)
00352 {
00353 free(jtabf->items);
00354 jtabf->items=NULL;
00355 jtabf->filelength=0;
00356 jtabf->count=0;
00357 return ERR_NONE;
00358 }
00359
00360
00361
00362
00363 int read_jtytab_encimages(struct ENCIMAGELIST *images,unsigned long *readcount,
00364 const struct JTYTABFILE *jtabf,const struct DATFILE *jtyf,const int verbose)
00365 {
00366 images->count=jtabf->count;
00367 unsigned long all_items_size=sizeof(struct ENCIMAGEITEM)*(images->count);
00368 images->items=malloc(all_items_size);
00369 if (images->items==NULL)
00370 {
00371 if (verbose) msgprintf(" Error\nReason - cannot allocate %lu bytes of memory.\n",all_items_size);
00372 return JTYTB_MALLOC_ERR;
00373 }
00374
00375 unsigned long picnum;
00376 unsigned long errnum=0;
00377 unsigned long skipnum=0;
00378 for (picnum=0;picnum<images->count;picnum++)
00379 {
00380 struct JTYTAB_ITEM *jtabitem=&(jtabf->items[picnum]);
00381 struct ENCIMAGEITEM *item=&(images->items[picnum]);
00382 item->width=jtabitem->width;
00383 item->height=jtabitem->height;
00384 item->data=NULL;
00385 item->datsize=0;
00386 memcpy(&(item->attrib),&(jtabitem->attrib),sizeof(struct IMGTAB_ATTRIB));
00387 if (verbose) msgprintf("\rPreparing picture%6lu from %06lx, %ux%u...",picnum,jtabitem->offset,jtabitem->width,jtabitem->height);
00388 if (jtabitem->offset > jtyf->filelength)
00389 {
00390 if (verbose) msgprintf(" Skipped\nReason - Picture offset out of JTY filesize.\n");
00391 skipnum++;
00392 continue;
00393 }
00394
00395 unsigned long endoffs=jtyf->filelength;
00396 if (picnum+1<images->count)
00397 {
00398 unsigned long nendoffs=jtabf->items[picnum+1].offset;
00399 if ((nendoffs<=endoffs)&&(nendoffs>=jtabitem->offset))
00400 {
00401 endoffs=nendoffs;
00402 } else
00403 {
00404 if (verbose)
00405 msgprintf(" Truncated\nReason - Entry size exceeds JTY filesize.\n");
00406 }
00407 }
00408 item->datsize=endoffs-jtabitem->offset;
00409 if (item->datsize>0)
00410 {
00411 item->data=malloc(item->datsize+1);
00412 if (item->data==NULL)
00413 {
00414 if (verbose) msgprintf(" Error - cannot allocate %lu bytes of memory.\n",(unsigned long)(item->datsize));
00415 return JTYTB_MALLOC_ERR;
00416 }
00417 memcpy(item->data,jtyf->data+jtabitem->offset,item->datsize);
00418 }
00419 (*readcount)+=(item->datsize);
00420 }
00421 if (verbose) msgprintf("\rImages stored; %lu skipped, %lu errors. \n",skipnum,errnum);
00422 return errnum;
00423 }
00424
00425
00426
00427
00428 int write_encimages_jtytab(const struct ENCIMAGELIST *images,unsigned long *writecount,
00429 struct JTYTABFILE *jtabf,struct DATFILE *jtyf)
00430 {
00431 short retcode;
00432
00433 jtabf->filelength=(images->count*JTYTAB_ENTRY_SIZE);
00434 retcode=alloc_jtytabfile_data(jtabf,images->count);
00435 if (retcode!=ERR_NONE) return retcode;
00436
00437 unsigned long datlength=0;
00438 int entrynum;
00439 for (entrynum=0;entrynum<images->count;entrynum++)
00440 datlength+=(images->items[entrynum].datsize);
00441 retcode=alloc_datfile_data(jtyf,datlength);
00442 if (retcode!=ERR_NONE) return retcode;
00443
00444 unsigned long datoffs=0;
00445 for (entrynum=0;entrynum<images->count;entrynum++)
00446 {
00447 struct JTYTAB_ITEM *cjtab=&(jtabf->items[entrynum]);
00448 struct ENCIMAGEITEM *img=&(images->items[entrynum]);
00449 memcpy(jtyf->data+datoffs,img->data,img->datsize);
00450 cjtab->offset=datoffs;
00451 cjtab->width=img->width;
00452 cjtab->height=img->height;
00453 memcpy(&(cjtab->attrib),&(img->attrib),sizeof(struct IMGTAB_ATTRIB));
00454 datoffs+=img->datsize;
00455 }
00456 (*writecount)=datoffs;
00457 return ERR_NONE;
00458 }
00459
00460
00461
00462
00463 short free_dattab_encimages(struct ENCIMAGELIST *images)
00464 {
00465 unsigned long picnum;
00466 for (picnum=0;picnum<images->count;picnum++)
00467 {
00468 struct ENCIMAGEITEM *item=&(images->items[picnum]);
00469 free(item->data);
00470 }
00471 free(images->items);
00472 images->items=NULL;
00473 images->count=0;
00474 return ERR_NONE;
00475 }
00476
00477
00478
00479
00480 short switch_encimage_entries(struct ENCIMAGELIST *images,unsigned long idx1,unsigned long idx2)
00481 {
00482 if ((idx1>=images->count)||(idx2>=images->count))
00483 return JTYTB_INTERNAL;
00484 struct ENCIMAGEITEM item;
00485 memcpy(&item,&(images->items[idx1]),sizeof(struct ENCIMAGEITEM));
00486 memcpy(&(images->items[idx1]),&(images->items[idx2]),sizeof(struct ENCIMAGEITEM));
00487 memcpy(&(images->items[idx2]),&item,sizeof(struct ENCIMAGEITEM));
00488 return ERR_NONE;
00489 }
00490
00491 int read_jtytab_images(struct IMAGELIST *images,unsigned long *readcount,
00492 const struct JTYTABFILE *jtabf,const struct DATFILE *jtyf,const int verbose)
00493 {
00494 images->count=jtabf->count;
00495 images->items=malloc(sizeof(struct IMAGEITEM)*(images->count));
00496 if (images->items==NULL)
00497 {
00498 if (verbose) msgprintf(" Error - cannot allocate %lu bytes of memory.\n",(unsigned long)(sizeof(struct IMAGEITEM)*images->count));
00499 return 1;
00500 }
00501
00502 unsigned long picnum;
00503 unsigned long errnum=0;
00504 unsigned long skipnum=0;
00505 for (picnum=0;picnum<images->count;picnum++)
00506 {
00507 struct JTYTAB_ITEM *jtabitem=&(jtabf->items[picnum]);
00508 struct IMAGEITEM *item=&(images->items[picnum]);
00509 item->width=0;
00510 item->height=0;
00511 item->data=NULL;
00512 item->alpha=NULL;
00513 if (verbose) msgprintf("\rPreparing picture%6lu from %06lx, %ux%u...",picnum,jtabitem->offset,jtabitem->width,jtabitem->height);
00514 if (jtabitem->offset >= jtyf->filelength)
00515 {
00516 if (verbose) msgprintf(" Skipped - Picture offset out of JTY filesize.\n");
00517 skipnum++;
00518 continue;
00519 }
00520 if ((jtabitem->width*jtabitem->height) < 1)
00521 {
00522 if (verbose) msgprintf(" Skipped - Picture dimensions are invalid.\n");
00523 skipnum++;
00524 continue;
00525 }
00526 unsigned long readedsize;
00527 int retcode;
00528 retcode=read_dat_image_idx(item,&readedsize,jtyf,jtabitem->offset,jtabitem->width,jtabitem->height);
00529 *readcount+=readedsize;
00530 if ((retcode&XTABDAT8_COLOUR_LEAK))
00531 {
00532 if (verbose) msgprintf (" Error - colour leak out of picture size.\n");
00533 errnum++;
00534 }
00535 else if ((retcode&XTABDAT8_ENDOFBUFFER))
00536 {
00537 if (verbose) msgprintf (" Error - end of DAT buffer, picture truncated.\n");
00538 errnum++;
00539 }
00540 }
00541 if (verbose) msgprintf("\rImages decoded, %lu skipped, %lu errors.\n",skipnum,errnum);
00542 return errnum;
00543 }
00544
00545
00546
00547
00548 short switch_jtytabfile_entries(struct JTYTABFILE *jtabf,unsigned long idx1,unsigned long idx2)
00549 {
00550 if ((idx1>=jtabf->count)||(idx2>=jtabf->count))
00551 return JTYTB_INTERNAL;
00552 struct JTYTAB_ITEM item;
00553 memcpy(&item,&(jtabf->items[idx1]),sizeof(struct JTYTAB_ITEM));
00554 memcpy(&(jtabf->items[idx1]),&(jtabf->items[idx2]),sizeof(struct JTYTAB_ITEM));
00555 memcpy(&(jtabf->items[idx2]),&item,sizeof(struct JTYTAB_ITEM));
00556 return ERR_NONE;
00557 }