00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <ctype.h>
00039 #include <stdio.h>
00040 #include <string.h>
00041 #include <stdlib.h>
00042
00043 #include "toolkits/util/jed_wad.h"
00044 #include <lista.cc>
00045
00046
00047
00048
00049
00050 WAD_ENTITY::WAD_ENTITY(FILE *fd, int tipo)
00057 {
00058 int dummy = 0;
00059
00060 lea_DWORD_BE(&offset, fd);
00061 lea_DWORD_BE(&size, fd);
00062 if ( tipo == 1 ) {
00063 fread(name, sizeof(BYTE), 8, fd);
00064 name[8] = '\0';
00065 wad2_type = 0;
00066 }
00067 else {
00068 lea_DWORD_BE(&wad2_mem_size, fd);
00069 fread(&wad2_type, sizeof(BYTE), 1, fd);
00070 fread(&wad2_compression, sizeof(BYTE), 1, fd);
00071 printf(" - Tipo: %d\n", wad2_type); fflush(stdout);
00072 lea_WORD_BE(&dummy, fd);
00073 fread(name, sizeof(BYTE), 16, fd);
00074 name[16] = '\0';
00075 }
00076 }
00077
00078 int
00079 WAD_ENTITY::deme_tipo(void)
00085 {
00086 static BOOLEAN en_flats = FALSE;
00087
00088
00089
00090 if ( strcmp(name, "F_START") == 0 ) {
00091 en_flats = TRUE;
00092 return WAD_LABEL;
00093 }
00094
00095 if ( strcmp(name, "F_END") == 0 ) {
00096 en_flats = FALSE;
00097 return WAD_LABEL;
00098 }
00099
00100 if ( size <= 0 &&
00101 name[0]=='M' && name[1]=='A' && name[2]=='P' && isdigit(name[3]) ) {
00102 return WAD_GLEVEL;
00103 }
00104
00105 if ( size <= 0 ) {
00106 return WAD_LABEL;
00107 }
00108
00109 if ( strcmp(name, "PLAYPAL") == 0 ) {
00110 return WAD_PLAYPAL;
00111 }
00112 else if ( strcmp(name, "THINGS") == 0 ) {
00113 return WAD_THINGS;
00114 }
00115 else if ( strcmp(name, "LINEDEFS") == 0 ) {
00116 return WAD_LINEDEFS;
00117 }
00118 else if ( strcmp(name, "SIDEDEFS") == 0 ) {
00119 return WAD_SIDEDEFS;
00120 }
00121 else if ( strcmp(name, "VERTEXES") == 0 ) {
00122 return WAD_VERTEXES;
00123 }
00124 else if ( strcmp(name, "SEGS") == 0 ) {
00125 return WAD_SEGS;
00126 }
00127 else if ( strcmp(name, "SSECTORS") == 0 ) {
00128 return WAD_SSECTORS;
00129 }
00130 else if ( strcmp(name, "NODES") == 0 ) {
00131 return WAD_NODES;
00132 }
00133 else if ( strcmp(name, "SECTORS") == 0 ) {
00134 return WAD_SECTORS;
00135 }
00136 else if ( strcmp(name, "REJECT") == 0 ) {
00137 return WAD_REJECT;
00138 }
00139 else if ( strcmp(name, "BLOCKMAP") == 0 ) {
00140 return WAD_BLOCKMAP;
00141 }
00142 else if ( strcmp(name, "COLORMAP") == 0 ) {
00143 return WAD_COLORMAP;
00144 }
00145 else if ( strcmp(name, "ENDOOM") == 0 ) {
00146 return WAD_ENDOOM;
00147 }
00148 else if ( name[0] == 'D' &&
00149 name[1] == 'E' &&
00150 name[2] == 'M' &&
00151 name[3] == 'O' && isdigit(name[4]) ) {
00152 return WAD_DEMOx;
00153 }
00154 else if ( name[0] == 'E' && name [2] == 'M' &&
00155 isdigit(name[1]) && isdigit(name[3]) ) {
00156 return WAD_GLEVEL;
00157 }
00158 else if ( strcmp(name, "TEXTURE1") == 0 ) {
00159 return WAD_TEXTURE;
00160 }
00161 else if ( strcmp(name, "TEXTURE2") == 0 ) {
00162 return WAD_TEXTURE;
00163 }
00164 else if ( strcmp(name, "PNAMES") == 0 ) {
00165 return WAD_PNAMES;
00166 }
00167 else if ( strcmp(name, "GENMIDI") == 0 ) {
00168 return WAD_GENMIDI;
00169 }
00170 else if ( strcmp(name, "DMXGUS") == 0 || strcmp(name, "DMXGUSC") == 0 ) {
00171 return WAD_DMXGUS;
00172 }
00173 else if ( strcmp(name, "D_ExMy") == 0 ) {
00174 return WAD_D_ExMy;
00175 }
00176 else if ( strcmp(name, "D_INTER") == 0 ) {
00177 return WAD_D_INTER;
00178 }
00179 else if ( strcmp(name, "D_INTRO") == 0 ) {
00180 return WAD_D_INTRO;
00181 }
00182 else if ( strcmp(name, "D_INTROA") == 0 ) {
00183 return WAD_D_INTROA;
00184 }
00185 else if ( strcmp(name, "D_VICTOR") == 0 ) {
00186 return WAD_D_VICTOR;
00187 }
00188 else if ( strcmp(name, "D_BUNNY") == 0 ) {
00189 return WAD_D_BUNNY;
00190 }
00191 else if ( name[0] == 'D' && name[1] == '_' ) {
00192 return WAD_D_;
00193 }
00194 else if ( name[0] == 'D' && name[1] == 'P' ) {
00195 return WAD_DP_;
00196 }
00197 else if ( name[0] == 'D' && name[1] == 'S' ) {
00198 return WAD_DS_;
00199 }
00200 else if ( strcmp(name, "THINGS") == 0 ) {
00201 return WAD_UNKNOWN;
00202 }
00203 else if ( strcmp(name, "LINEDEFS") == 0 ) {
00204 return WAD_UNKNOWN;
00205 }
00206 else if ( strcmp(name, "SIDEDEFS") == 0 ) {
00207 return WAD_UNKNOWN;
00208 }
00209 else if ( strcmp(name, "VERTEXES") == 0 ) {
00210 return WAD_UNKNOWN;
00211 }
00212 else if ( strcmp(name, "SEGS") == 0 ) {
00213 return WAD_UNKNOWN;
00214 }
00215 else if ( strcmp(name, "SSECTORS") == 0 ) {
00216 return WAD_UNKNOWN;
00217 }
00218 else if ( strcmp(name, "NODES") == 0 ) {
00219 return WAD_UNKNOWN;
00220 }
00221 else if ( strcmp(name, "SECTORS") == 0 ) {
00222 return WAD_UNKNOWN;
00223 }
00224 else if ( strcmp(name, "REJECT") == 0 ) {
00225 return WAD_UNKNOWN;
00226 }
00227 else if ( strcmp(name, "BLOCKMAP") == 0 ) {
00228 return WAD_UNKNOWN;
00229 }
00230 ;
00231
00232 if ( !en_flats ) {
00233 return WAD_IMAGE;
00234 }
00235
00236 return WAD_FLAT;
00237 }
00238
00239
00240
00241
00242
00243 WAD_LEVEL::WAD_LEVEL(char *n)
00244 {
00245 strcpy(name, n);
00246
00247 Things = NULL;
00248 Linedefs = NULL;
00249 Sidedefs = NULL;
00250 Vertexes = NULL;
00251 Segs = NULL;
00252 Ssectors = NULL;
00253 Nodes = NULL;
00254 Sectors = NULL;
00255 Reject = NULL;
00256 Blockmap = NULL;
00257 }
00258
00259 WAD_LEVEL::~WAD_LEVEL()
00260 {
00261 if ( Things ) {
00262 delete Things;
00263 Things = NULL;
00264 }
00265 if ( Linedefs ) {
00266 delete Linedefs;
00267 Linedefs = NULL;
00268 }
00269 if ( Sidedefs ) {
00270 delete Sidedefs;
00271 Sidedefs = NULL;
00272 }
00273 if ( Vertexes ) {
00274 delete Vertexes;
00275 Vertexes = NULL;
00276 }
00277 if ( Segs ) {
00278 delete Segs;
00279 Segs = NULL;
00280 }
00281 if ( Ssectors ) {
00282 delete Ssectors;
00283 Ssectors = NULL;
00284 }
00285 if ( Nodes ) {
00286 delete Nodes;
00287 Nodes = NULL;
00288 }
00289 if ( Sectors ) {
00290 delete Sectors;
00291 Sectors = NULL;
00292 }
00293 if ( Reject ) {
00294 delete Reject;
00295 Reject = NULL;
00296 }
00297 if ( Blockmap ) {
00298 delete Blockmap;
00299 Blockmap = NULL;
00300 }
00301 }
00302
00303 void
00304 WAD_LEVEL::cargue(FILE *fd)
00310 {
00311 WAD_ENTITY *e;
00312 int i;
00313 wad_fd = fd;
00314 int c = 0;
00315
00316 for ( i = 0; i < 10; i++ ) {
00317 e = new WAD_ENTITY(wad_fd, 1);
00318 switch( e->deme_tipo() ) {
00319 case WAD_THINGS: c++; Things = e; break;
00320 case WAD_LINEDEFS: c++; Linedefs = e; break;
00321 case WAD_SIDEDEFS: c++; Sidedefs = e; break;
00322 case WAD_VERTEXES: c++; Vertexes = e; break;
00323 case WAD_SEGS: c++; Segs = e; break;
00324 case WAD_SSECTORS: c++; Ssectors = e; break;
00325 case WAD_NODES: c++; Nodes = e; break;
00326 case WAD_SECTORS: c++; Sectors = e; break;
00327 case WAD_REJECT: c++; Reject = e; break;
00328 case WAD_BLOCKMAP: c++; Blockmap = e; break;
00329 default:
00330 fprintf(stderr, "ERROR: Entidad \"%s\" inesperada como parte de un"
00331 "Nivel Doom-WAD.\n", e->name);
00332 fflush(stderr);
00333 return;
00334 }
00335 }
00336
00337 if ( c != 10 ) {
00338 fprintf(stderr, "Warning: Nivel con %d entidades, se esperaban 10.\n",
00339 c);
00340 fflush(stderr);
00341 }
00342 }
00343
00344
00345
00346
00347
00348 WAD_DATABASE::WAD_DATABASE(char *file)
00349 {
00350 ignorados = 0;
00351 etiquetas = 0;
00352 num_entidades = 0;
00353 strcpy(wadid_cad, "NULL");
00354
00355
00356 nombre_de_archivo = new char[strlen(file) +1];
00357 strcpy(nombre_de_archivo, file);
00358 fd = fopen(nombre_de_archivo, "rb");
00359 if ( !fd ) {
00360 fprintf(stderr,"ERROR FATAL: No se puede abrir la base de datos WAD:\n"
00361 " - \"%s\"", nombre_de_archivo);
00362 fflush(stdout);
00363 exit(1);
00364 }
00365
00366
00367 WORD i;
00368 DWORD index_base;
00369 WAD_ENTITY *e;
00370
00371 tipo_de_wad = 1;
00372 fread(wadid_cad, sizeof(BYTE), 4, fd);
00373 if ( strcmp(wadid_cad, "IWAD") && strcmp(wadid_cad, "PWAD") &&
00374 strcmp(wadid_cad, "WAD2") ) {
00375 fprintf(stderr,"ERROR FATAL: La base de datos no es ni I-WAD ni P-WAD:"
00376 "\n - \"%s\"", nombre_de_archivo);
00377 fflush(stdout);
00378 exit(1);
00379 }
00380 if ( strcmp(wadid_cad, "WAD2") == 0 ) {
00381 tipo_de_wad = 2;
00382 }
00383 printf("JEDILINK WAD_DATABASE: Inicializando %s ...", nombre_de_archivo);
00384 fflush(stdout);
00385 lea_DWORD_BE(&num_entidades, fd);
00386 lea_DWORD_BE(&index_base, fd);
00387 fseek(fd, index_base, SEEK_SET);
00388
00389
00390 WAD_LEVEL *n;
00391 char *pname;
00392
00393 for ( i = 0; i < num_entidades; i++ ) {
00394 e = new WAD_ENTITY(fd, tipo_de_wad);
00395 switch ( e->deme_tipo() ) {
00396 case WAD_IMAGE: imagenes.anx(e); break;
00397 case WAD_PLAYPAL: paletas.anx(e); break;
00398 case WAD_FLAT: flats.anx(e); break;
00399 case WAD_LABEL: etiquetas++; break;
00400 case WAD_PNAMES: tablas_pname.anx(e); break;
00401 case WAD_DS_: sonidos.anx(e); break;
00402 case WAD_DP_: efectos_speaker.anx(e); break;
00403 case WAD_D_: secuencias_midi.anx(e); break;
00404 case WAD_TEXTURE: texturas.anx(e); break;
00405 case WAD_GLEVEL:
00406 n = new WAD_LEVEL(e->name);
00407 n->cargue(fd);
00408 niveles.anx(n);
00409 delete e;
00410 n = NULL;
00411 i += 10;
00412 break;
00413 default:
00414 if ( strcmp("THINGS", e->name) == 0 ) {
00415 fseek(fd, -16, SEEK_CUR);
00416 n = new WAD_LEVEL(e->name);
00417 n->cargue(fd);
00418 niveles.anx(n);
00419 n = NULL;
00420 i += 10;
00421 }
00422 else {
00423
00424 ignorados++;
00425 }
00426 delete e;
00427 break;
00428 }
00429
00430 }
00431
00432
00433 DWORD num_pnames;
00434 DWORD num_texturas;
00435 DWORD ii, jj;
00436 DWORD *sub_offsets;
00437 WAD_TEXTURE_DATA *Textura;
00438 WORD dummy;
00439
00440 for ( ii = 0; ii < (DWORD)tablas_pname.tam(); ii++ ) {
00441 fseek(fd, tablas_pname[ii]->offset, SEEK_SET);
00442 lea_DWORD_BE(&num_pnames, fd);
00443
00444 fflush(stderr);
00445 for ( jj = 0; jj < num_pnames; jj++ ) {
00446 pname = new char[9];
00447 fread(pname, sizeof(char), 8, fd);
00448 pname[8] = '\0';
00449 tabla_pname.anx(pname);
00450
00451 }
00452 }
00453
00454 for ( ii = 0; ii < (DWORD)texturas.tam(); ii++ ) {
00455 fseek(fd, texturas[ii]->offset, SEEK_SET);
00456 lea_DWORD_BE(&num_texturas, fd);
00457 sub_offsets = new DWORD[num_texturas];
00458 if ( !sub_offsets ) exit(1);
00459 for ( jj = 0; jj < num_texturas; jj++ ) {
00460 lea_DWORD_BE(&sub_offsets[jj],fd);
00461 }
00462 for ( jj = 0; jj < num_texturas; jj++ ) {
00463 fseek(fd, texturas[ii]->offset + sub_offsets[jj], SEEK_SET);
00464 Textura = new WAD_TEXTURE_DATA;
00465 if ( !Textura ) exit(1);
00466 fread(Textura->name, sizeof(char), 8, fd);
00467 Textura->name[8] = '\0';
00468 for ( i = 0; i < 8; i++ ) {
00469 Textura->name[i] = (char)toupper(Textura->name[i]);
00470 }
00471 lea_WORD_BE(&dummy, fd);
00472 lea_WORD_BE(&dummy, fd);
00473 lea_WORD_BE(&Textura->width, fd);
00474 lea_WORD_BE(&Textura->height, fd);
00475 lea_WORD_BE(&dummy, fd);
00476 lea_WORD_BE(&dummy, fd);
00477 lea_WORD_BE(&(Textura->num_trocitos), fd);
00478 Textura->X_offsets = new WORD[Textura->num_trocitos];
00479 Textura->Y_offsets = new WORD[Textura->num_trocitos];
00480 Textura->Pname_indexes = new WORD[Textura->num_trocitos];
00481 for ( i = 0; i < Textura->num_trocitos; i++ ) {
00482 lea_WORD_BE(&(Textura->X_offsets[i]), fd);
00483 lea_WORD_BE(&(Textura->Y_offsets[i]), fd);
00484 lea_WORD_BE(&(Textura->Pname_indexes[i]), fd);
00485 lea_WORD_BE(&dummy, fd);
00486 lea_WORD_BE(&dummy, fd);
00487 }
00488
00489 datos_texturas.anx(Textura);
00490
00491 #ifdef DEBUG_WAD
00492 printf(" -\"%s\", \t (%d x %d) pixels, \t %d trozos.\n",
00493 Textura->name, Textura->width, Textura->height,
00494 Textura->num_trocitos);
00495 for ( i = 0; i < Textura->num_trocitos; i++ ) {
00496 printf(" --> Trozo %d: (+%d, +%d), \tPNAME %d.\n",
00497 i, Textura->X_offsets[i], Textura->Y_offsets[i],
00498 Textura->Pname_indexes[i]+1);
00499 if ( Textura->Pname_indexes[i] >= tabla_pname.tam() ) {
00500 printf("OJO: TROZO INVALIDO!\n");
00501 }
00502 }
00503 #endif
00504 }
00505 delete sub_offsets;
00506 }
00507
00508
00509 printf(" Ok!\n");
00510 fflush(stdout);
00511 }
00512
00513 WAD_DATABASE::~WAD_DATABASE()
00514 {
00515 fclose(fd);
00516 fd = 0;
00517 delete nombre_de_archivo;
00518 nombre_de_archivo = NULL;
00519
00520 #ifdef NONONO
00521 printf("===========================================================================\n");
00522 printf("Cerrando base de datos WAD.\n");
00523 printf("===========================================================================\n");
00524 fflush(stdout);
00525 #endif
00526
00527
00528 }
00529
00530 BOOLEAN
00531 WAD_DATABASE::localice_imagen(int busqueda)
00532
00533
00534
00535
00536 {
00537 rewind(fd);
00538
00539 if ( busqueda < 0 || busqueda >= imagenes.tam() ) return FALSE;
00540
00541 fseek(fd, imagenes[busqueda]->offset, SEEK_SET);
00542 return TRUE;
00543 }
00544
00545 BOOLEAN
00546 WAD_DATABASE::localice_flat(int busqueda)
00547
00548
00549
00550
00551 {
00552 rewind(fd);
00553
00554 if ( busqueda < 0 || busqueda >= flats.tam() ) return FALSE;
00555
00556 fseek(fd, flats[busqueda]->offset, SEEK_SET);
00557 return TRUE;
00558 }
00559
00560 BOOLEAN
00561 WAD_DATABASE::localice_flat_por_nombre(char *nombre)
00562 {
00563 WAD_ENTITY *f;
00564
00565 rewind(fd);
00566
00567 for ( flats.principio(); flats.ventana(); ++flats ) {
00568 f = flats.ventana();
00569 if ( strcmp(nombre, f->name ) == 0 ) {
00570 fseek(fd, f->offset, SEEK_SET);
00571 return TRUE;
00572 }
00573 }
00574 return FALSE;
00575 }
00576
00577 BOOLEAN
00578 WAD_DATABASE::localice_imagen_por_nombre(char *nombre)
00579 {
00580 int i;
00581 WAD_ENTITY *img;
00582
00583 rewind(fd);
00584 for( i = 0; i < 8; i++ ) nombre[i] = (char)toupper(nombre[i]);
00585
00586 for ( imagenes.principio(); imagenes.ventana(); ++imagenes ) {
00587 img = imagenes.ventana();
00588 if ( strcmp(nombre, img->name ) == 0 ) {
00589 fseek(fd, img->offset, SEEK_SET);
00590 return TRUE;
00591 }
00592 }
00593 return FALSE;
00594 }
00595
00596 BOOLEAN
00597 WAD_DATABASE::localice_textura_por_nombre(char *nombre,
00598 int *X_tam, int *Y_tam,
00599 int *Num_trozos, int **ARr_x, int **ARr_y, int **ARr_i)
00600 {
00601 int i, j;
00602 WAD_TEXTURE_DATA *Textura;
00603
00604 for( i = 0; i < 8; i++ ) nombre[i] = (char)toupper(nombre[i]);
00605
00606 for ( datos_texturas.principio(); datos_texturas.ventana();
00607 ++datos_texturas ) {
00608 Textura = datos_texturas.ventana();
00609 if ( strcmp(nombre, Textura->name ) == 0 ) {
00610 (*X_tam) = Textura->width;
00611 (*Y_tam) = Textura->height;
00612 (*Num_trozos) = (int)Textura->num_trocitos;
00613 (*ARr_x) = new int[*Num_trozos];
00614 (*ARr_y) = new int[*Num_trozos];
00615 (*ARr_i) = new int[*Num_trozos];
00616 for ( j = 0; j < *Num_trozos; j++ ) {
00617 (*ARr_x)[j] = (int)Textura->X_offsets[j];
00618 (*ARr_y)[j] = (int)Textura->Y_offsets[j];
00619 (*ARr_i)[j] = (int)Textura->Pname_indexes[j];
00620 }
00621 return TRUE;
00622 }
00623 }
00624
00625 return FALSE;
00626 }
00627
00628 BOOLEAN
00629 WAD_DATABASE::localice_sonido(int busqueda)
00630
00631
00632
00633
00634 {
00635 rewind(fd);
00636
00637 if ( busqueda < 0 || busqueda >= sonidos.tam() ) return FALSE;
00638
00639 fseek(fd, sonidos[busqueda]->offset, SEEK_SET);
00640
00641
00642
00643 return TRUE;
00644 }
00645
00646
00647 void
00648 WAD_DATABASE::localice_paleta(int busqueda)
00649
00650
00651
00652
00653
00654
00655
00656 {
00657 rewind(fd);
00658
00659
00660
00661 fseek(fd, paletas[0]->offset + busqueda * (256 * 3), SEEK_SET);
00662 return;
00663 }
00664
00665 void
00666 WAD_DATABASE::imprima(void)
00667 {
00668 printf("===========================================================================\n");
00669 printf("Base de datos WAD: \"%s\"\n", nombre_de_archivo);
00670 printf("===========================================================================\n");
00671
00672 printf(" - %s con %d entidades.\n", wadid_cad, num_entidades);
00673
00674 if ( paletas.tam() == 1 ) {
00675 printf(" - Un (1) grupo de paletas de colores.\n");
00676 }
00677 else if ( paletas.tam() > 1 ) {
00678 printf(" - %ld grupos de paletas de colores.\n", paletas.tam());
00679 }
00680
00681 if ( tablas_pname.tam() == 1 ) {
00682 printf(" - Una (1) tabla PNAME (%ld referencias a sprite).\n",
00683 tabla_pname.tam());
00684 }
00685 else {
00686 printf(" - %ld tablas PNAME (%ld referencias a sprite).\n",
00687 tablas_pname.tam(), tabla_pname.tam());
00688 }
00689
00690 if ( texturas.tam() == 1 ) {
00691 printf(" - Una (1) tabla de texturas multi-sprite (%ld texturas).\n",
00692 datos_texturas.tam());
00693 }
00694 else {
00695 printf(" - %ld tablas de texturas multi-sprite (%ld texturas).\n",
00696 texturas.tam(), datos_texturas.tam());
00697 }
00698
00699 printf(" - %ld demarcadores.\n", (unsigned long)etiquetas);
00700 printf(" - %ld efectos de sonido para speaker.\n", niveles.tam());
00701 printf(" - %ld secuencias MIDI.\n", niveles.tam());
00702 printf(" - %ld niveles con 11 entidades cada uno.\n", niveles.tam());
00703 printf(" - %ld muestras de sonido digitalizado.\n", sonidos.tam());
00704 printf(" - %ld imagenes de pisos y cielos razos.\n", flats.tam());
00705 printf(" - %ld imagenes de sprites y paredes.\n", imagenes.tam());
00706 printf(" - %ld entidades ignoradas.\n", (unsigned long)ignorados);
00707 fflush(stdout);
00708 printf("===========================================================================\n");
00709
00710 }
00711
00712
00713
00714
00715