home *** CD-ROM | disk | FTP | other *** search
/ Ultimate DOOM Companion / PowersourceMultimedia-UltimateDOOMCompanion.iso / doomhack / dhdiff.zip / DHDIFF.C next >
C/C++ Source or Header  |  1994-09-25  |  14KB  |  562 lines

  1. /* dhdiff.c 2.0 by Paul Falstad
  2.  * warning: this code is a real hack
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7.  
  8. int new = 0;
  9.  
  10. char *tattr[] = {
  11.     "thing no", "first frame", "toughness", "moving frame",
  12.     "alert sound", "reaction time", "attack sound", "injury frame",
  13.     "pain chance", "pain sound", "close attack frame", "distance attack frame",
  14.     "death frame", "explode frame", "death sound", "speed",
  15.     "hsize", "height", "mass", "missile damage",
  16.     "act sound", "bits", "respawn frame"
  17. };
  18.  
  19. char *ammo1[] = {
  20.     "pistol", "shotgun", "launcher", "plasma"
  21. };
  22.  
  23. char *ammo2[] = {
  24.     "punch", "pistol", "shotgun", "chaingun", "launcher",
  25.     "plasma", "bfg", "chainsaw", "super-shotgun"
  26. };
  27.  
  28. char *ammoattr[] = {
  29.     "ammo type", "bob frame 1", "bob frame 2", "bob frame 3",
  30.     "shoot frame", "firing frame"
  31. };
  32.  
  33. char *fattr[] = {
  34.     "sprite no", "sprite subno", "duration", "code ptr",
  35.     "next frame", "?2", "?3"
  36. };
  37.  
  38. char *tnames[103] = {
  39.     "Player",
  40.     "Imp",
  41.     "Trooper",
  42.     "Sargeant",
  43.     "Demon",
  44.     "Spector",
  45.     "Cacodemon",
  46.     "Lost Soul",
  47.     "Baron",
  48.     "Spider Boss",
  49.     "Cyberdemon",
  50.     "Barrel",
  51.     "Imp Fireball",
  52.     "Caco Fireball",
  53.     "Baron Fireball",
  54.     "Rocket",
  55.     "Plasma Bullet",
  56.     "BFG Shot",
  57.     "Bullet Puffs",
  58.     "Blood Splats",
  59.     "Teleport Flash",
  60.     "Teleport Exit",
  61.     "BFG Hit",
  62.     "Green Armor",
  63.     "Blue Armor",
  64.     "Health Potion",
  65.     "Armor Helmet",
  66.     "Blue Keycard",
  67.     "Red Keycard",
  68.     "Yellow Keycard",
  69.     "Yellow Skull Key",
  70.     "Red Skull Key",
  71.     "Blue Skull Key",
  72.     "Stim Pack",
  73.     "Medical Kit",
  74.     "Soul Sphere",
  75.     "Invulnerability",
  76.     "Berserk Sphere",
  77.     "Blur Sphere",
  78.     "Radiation Suit",
  79.     "Computer Map",
  80.     "Lite Amp. Goggles",
  81.     "Ammo Clip",
  82.     "Box of Ammo",
  83.     "Rocket",
  84.     "Box of Rockets",
  85.     "Energy Cell",
  86.     "Energy Pack",
  87.     "Shells",
  88.     "Box of Shells",
  89.     "Backpack",
  90.     "BFG9000",
  91.     "Chaingun",
  92.     "Chainsaw",
  93.     "Rocket Launcher",
  94.     "Plasma Gun",
  95.     "Shotgun",
  96.     "Lamp",
  97.     "Tall Green Pillar",
  98.     "Short Green Pillar",
  99.     "Tall Red Pillar",
  100.     "Short Red Pillar",
  101.     "Red Pillar w/Skull",
  102.     "Pillar w/Heart",
  103.     "Eye in Symbol",
  104.     "Flaming Skulls",
  105.     "Grey Tree",
  106.     "Tall Blue Torch",
  107.     "Tall Green Torch",
  108.     "Tall Red Torch",
  109.     "Short Blue Torch",
  110.     "Short Green Torch",
  111.     "Short Red Torch",
  112.     "Brown Stub",
  113.     "Technical Column",
  114.     "Candle",
  115.     "Candelabra",
  116.     "Swaying Body",
  117.     "Hanging Arms Out",
  118.     "One-legged Body",
  119.     "Hanging Torso",
  120.     "Hanging Leg",
  121.     "Hanging Arms Out 2",
  122.     "Hanging Torso 2",
  123.     "One-legged Body 2",
  124.     "Hanging Leg 2",
  125.     "Swaying Body 2",
  126.     "Dead Cacodemon",
  127.     "Dead Marine",
  128.     "Dead Trooper",
  129.     "Dead Demon",
  130.     "Dead Lost Soul",
  131.     "Dead Imp",
  132.     "Dead Sargeant",
  133.     "Guts and Bones",
  134.     "Guts and Bones 2",
  135.     "Skewered Heads",
  136.     "Pool of Blood",
  137.     "Pole with Skull",
  138.     "Pile of Skulls",
  139.     "Impaled Body",
  140.     "Twitching Body",
  141.     "Large Tree",
  142. };
  143.  
  144. char *tnames2[137] = {
  145.     "Player",
  146.     "Trooper",
  147.     "Sargeant",
  148.     "Archvile",
  149.     "Vile Attack",
  150.     "Revenant",
  151.     "Revenant Fireball",
  152.     "Fireball Trail",
  153.     "Mancubus",
  154.     "Mancubus Fireball",
  155.     "Chaingun Sargeant",
  156.     "Imp",
  157.     "Demon",
  158.     "Spectre",
  159.     "Cacodemon",
  160.     "Baron of Hell",
  161.     "Baron Fireball",
  162.     "Hell Knight",
  163.     "Lost Soul",
  164.     "Spiderdemon",
  165.     "Arachnotron",
  166.     "Cyberdemon",
  167.     "Pain Elemental",
  168.     "SS Nazi",
  169.     "Commander Keen",
  170.     "Big Brain",
  171.     "SS Nazi",
  172.     "Demon Spawn Spot",
  173.     "Demon Spawn Cube",
  174.     "Demon Spawn Fire",
  175.     "Barrel",
  176.     "Imp Fireball",
  177.     "Caco Fireball",
  178.     "Rocket (in air)",
  179.     "Plasma Bullet",
  180.     "BFG Shot",
  181.     "Arach. Fireball",
  182.     "Bullet Puff",
  183.     "Blood Splat",
  184.     "Teleport Flash",
  185.     "Item Respawn Fog",
  186.     "Teleport Exit",
  187.     "BFG Hit",
  188.     "Green Armor",
  189.     "Blue Armor",
  190.     "Health Potion",
  191.     "Armor Helmet",
  192.     "Blue Keycard",
  193.     "Red Keycard",
  194.     "Yellow Keycard",
  195.     "Yellow Skull Key",
  196.     "Red Skull Key",
  197.     "Blue Skull Key",
  198.     "Stim Pack",
  199.     "Medical Kit",
  200.     "Soul Sphere",
  201.     "Invulnerability",
  202.     "Berserk Sphere",
  203.     "Blur Sphere",
  204.     "Radiation Suit",
  205.     "Computer Map",
  206.     "Lite Amp. Visor",
  207.     "Mega Sphere",
  208.     "Ammo Clip",
  209.     "Box of Ammo",
  210.     "Rocket",
  211.     "Box of Rockets",
  212.     "Energy Cell",
  213.     "Energy Pack",
  214.     "Shells",
  215.     "Box of Shells",
  216.     "Backpack",
  217.     "BFG9000",
  218.     "Chaingun",
  219.     "Chainsaw",
  220.     "Rocket Launcher",
  221.     "Plasma Gun",
  222.     "Shotgun",
  223.     "Super Shotgun",
  224.     "Tall Lamp",
  225.     "Tall Lamp 2",
  226.     "Short Lamp",
  227.     "Tall Gr. Pillar",
  228.     "Short Gr. Pillar",
  229.     "Tall Red Pillar",
  230.     "Short Red Pillar",
  231.     "Pillar w/Skull",
  232.     "Pillar w/Heart",
  233.     "Eye in Symbol",
  234.     "Flaming Skulls",
  235.     "Grey Tree",
  236.     "Tall Blue Torch",
  237.     "Tall Green Torch",
  238.     "Tall Red Torch",
  239.     "Small Blue Torch",
  240.     "Small Gr. Torch",
  241.     "Small Red Torch",
  242.     "Brown Stub",
  243.     "Technical Column",
  244.     "Candle",
  245.     "Candelabra",
  246.     "Swaying Body",
  247.     "Hanging Arms Out",
  248.     "One-legged Body",
  249.     "Hanging Torso",
  250.     "Hanging Leg",
  251.     "Hanging Arms Out2",
  252.     "Hanging Torso 2",
  253.     "One-legged Body 2",
  254.     "Hanging Leg 2",
  255.     "Swaying Body 2",
  256.     "Dead Cacodemon",
  257.     "Dead Marine",
  258.     "Dead Trooper",
  259.     "Dead Demon",
  260.     "Dead Lost Soul",
  261.     "Dead Imp",
  262.     "Dead Sargeant",
  263.     "Guts and Bones",
  264.     "Guts and Bones 2",
  265.     "Skewered Heads",
  266.     "Pool of Blood",
  267.     "Pole with Skull",
  268.     "Pile of Skulls",
  269.     "Impaled Body",
  270.     "Twitching Body",
  271.     "Large Tree",
  272.     "Fuel Can",
  273.     "Hanging Body 1",
  274.     "Hanging Body 2",
  275.     "Hanging Body 3",
  276.     "Hanging Body 4",
  277.     "Hanging Body 5",
  278.     "Hanging Body 6",
  279.     "Pool Of Blood 1",
  280.     "Pool Of Blood 2",
  281.     "Pool Of Brains"
  282. };
  283.  
  284. char *bitattr[] = {
  285.     "Gettable Thing",
  286.     "Obstacle",
  287.     "Shootable Thing",
  288.     "Total Invis.",
  289.     "Automatics",
  290.     "Unknown",
  291.     "In Pain",
  292.     "Unknown",
  293.     "Hangs from ceil",
  294.     "Not-on-ground",
  295.     "Proj/players",
  296.     "Can get stuff",
  297.     "No Clipping",
  298.     "Unknown",
  299.     "Float Monsters",
  300.     "Semi-No Clip.",
  301.     "Projectiles",
  302.     "Disappearing Weapon",
  303.     "Partial Invis.",
  304.     "Bleeds (vs. puffs)",
  305.     "Sliding Helpless",
  306.     "Unknown",
  307.     "Counts for Kill %",
  308.     "Counts for Item %",
  309.     "Running",
  310.     "Not in DMatch",
  311.     "Color 1",
  312.     "Color 2",
  313.     "Unknown",
  314.     "Unknown",
  315.     "Unknown",
  316.     "Unknown",
  317. };
  318.  
  319. char *old_sprs[] = {
  320.     "TROO", "SHTG", "PUNG", "PISG", "PISF", "SHTF", "CHGG", "CHGF",
  321.     "MISG", "MISF", "SAWG", "PLSG", "PLSF", "BFGG", "BFGF", "BLUD",
  322.     "PUFF", "BAL1", "BAL2", "BAL7", "PLSS", "PLSE", "MISL", "BFS1",
  323.     "BFE1", "BFE2", "PLAY", "POSS", "SPOS", "SARG", "HEAD", "BOSS",
  324.     "SKUL", "SPID", "CYBR", "TFOG", "ARM1", "ARM2", "BAR1", "BEXP",
  325.     "BON1", "BON2", "BKEY", "RKEY", "YKEY", "BSKU", "RSKU", "YSKU",
  326.     "STIM", "MEDI", "SOUL", "PINV", "PSTR", "PINS", "SUIT", "PMAP",
  327.     "PVIS", "CLIP", "AMMO", "ROCK", "BROK", "CELL", "CELP", "SHEL",
  328.     "SBOX", "BPAK", "BFUG", "MGUN", "CSAW", "LAUN", "PLAS", "SHOT",
  329.     "COLU", "SMT2", "GOR1", "POL2", "POL5", "POL4", "POL3", "POL1",
  330.     "POL6", "GOR2", "GOR3", "GOR4", "GOR5", "SMIT", "COL1", "COL2",
  331.     "COL3", "COL4", "CAND", "CBRA", "COL6", "TRE1", "TRE2", "ELEC",
  332.     "CEYE", "FSKU", "COL5", "TBLU", "TGRN", "TRED", "SMBT", "SMGT",
  333.     "SMRT"
  334. };
  335.  
  336. #define HEADER_2_0 ('P'|('a'<<8))
  337.  
  338. #define THING_VAL_COUNT ((new) ? 23 : 22)
  339. #define THING_COUNT ((new) ? 137 : 103)
  340. #define TNAMES ((new) ? tnames2 : tnames)
  341. #define FRAME_COUNT ((new) ? 966 : 512)
  342.  
  343. struct sstate {
  344.     char *str;
  345.     int size;
  346. };
  347. typedef struct sstate sstate;
  348.  
  349. void
  350. sstate_init(sstate *ss)
  351. {
  352.     ss->str = malloc(ss->size = 100);
  353. }
  354.  
  355. int
  356. getstr(sstate *ss, FILE *in)
  357. {
  358.     int len = 0;
  359.  
  360.     while (fread(ss->str+len, 1, 4, in)) {
  361.     char *p = ss->str+len;
  362.     if (!(p[0] && p[1] && p[2] && p[3]))
  363.         return 1;
  364.     len += 4;
  365.     if (len >= ss->size)
  366.         ss->str = realloc(ss->str, ss->size *= 2);
  367.     }
  368.     return 0;
  369. }
  370.  
  371. void
  372. get_str_by_ptr(char *buf, long *off, FILE *in)
  373. {
  374.     long foff = ftell(in);
  375.  
  376.     *off -= 0x1f814;
  377.     fseek(in, *off+0xad2e, SEEK_SET);
  378.     fread(buf, 12, 1, in);
  379.     fseek(in, foff, SEEK_SET);
  380. }
  381.  
  382. char *
  383. get_spr_name(char *buf, int spr, FILE *in)
  384. {
  385.     long foff = ftell(in);
  386.     long soff;
  387.  
  388.     if (!new)
  389.     return old_sprs[spr];
  390.     fseek(in, spr*4+0xab06, SEEK_SET);
  391.     fread(&soff, sizeof soff, 1, in);
  392.     fseek(in, foff, SEEK_SET);
  393.     get_str_by_ptr(buf, &soff, in);
  394.     return buf;
  395. }
  396.  
  397. main(ac, av)
  398. int ac;
  399. char **av;
  400. {
  401.     FILE *in1, *in2;
  402.     short x;
  403.     long tbuf1[23], tbuf2[23];
  404.     long fbuf1[7], fbuf2[7];
  405.     int i, j;
  406.     sstate sstate1;
  407.     sstate sstate2;
  408.  
  409.     if (ac < 3) {
  410.     fprintf(stderr, "dhdiff v2.0 by Paul Falstad\nusage: dhdiff file1.deh file2.deh\n");
  411.     exit(1);
  412.     }
  413.     memset(tbuf1, 0, sizeof tbuf1);
  414.     memset(tbuf2, 0, sizeof tbuf2);
  415.     sstate_init(&sstate1);
  416.     sstate_init(&sstate2);
  417.     in1 = fopen(av[1], "rb");
  418.     if (!in1) {
  419.     fprintf(stderr, "dhdiff: can't open %s: %s\n", av[1],
  420.         strerror(errno));
  421.     exit(1);
  422.     }
  423.     in2 = fopen(av[2], "rb");
  424.     if (!in2) {
  425.     fprintf(stderr, "dhdiff: can't open %s: %s\n", av[2],
  426.         strerror(errno));
  427.     exit(1);
  428.     }
  429.     fread(&x, 1, sizeof x, in1);
  430.     if (x == HEADER_2_0) {
  431.     /* this is a DEH 2.0 header... skip it. */
  432.     char buf[28-2];
  433.     int c;
  434.     
  435.     fread(buf, 1, sizeof buf, in1);
  436.     c = getc(in1);
  437.     c = getc(in1);
  438.     if (c != 4) {
  439.         fprintf(stderr, "don't understand format of %s\n", av[1]);
  440.         exit(1);
  441.     }
  442.     new = 1;
  443.     }
  444.     fread(&x, 1, sizeof x, in2);
  445.     if (new) {
  446.     char buf[28-2+2];
  447.     if (x != HEADER_2_0) {
  448.         fprintf(stderr, "patch files are from different versions of dehacked\n");
  449.         exit(1);
  450.     }
  451.     fread(buf, 1, sizeof buf, in2);
  452.     } else if (x == HEADER_2_0) {
  453.     fprintf(stderr,
  454.         "patch files are from different versions of dehacked\n");
  455.     exit(1);
  456.     }
  457.     for (i = 0; i != THING_COUNT; i++) {
  458.     fread(tbuf1, THING_VAL_COUNT, sizeof *tbuf1, in1);
  459.     fread(tbuf2, THING_VAL_COUNT, sizeof *tbuf2, in2);
  460.     if (memcmp(tbuf1, tbuf2, sizeof tbuf1)) {
  461.         printf("%s (thing %d) differences:\n", TNAMES[i], i+1);
  462.         for (j = 0; j != THING_VAL_COUNT; j++) {
  463.         if (j == 21) {
  464.             int k;
  465.             long o1, o2;
  466.             long b1 = tbuf1[21];
  467.             long b2 = tbuf2[21];
  468.             unsigned long b = 1;
  469.             for (k = 0; k != 32; k++, b<<=1) {
  470.             if ((o1 = (b1 & b)) != (o2 = (b2 & b)))
  471.                 printf("  %s (bit %d) (%d -> %d)\n",
  472.                 bitattr[k], k, !!o1, !!o2);
  473.             }
  474.         } else if (tbuf1[j] != tbuf2[j])
  475.             printf("  %s (%ld -> %ld)\n", tattr[j],
  476.             tbuf1[j], tbuf2[j]);
  477.         }
  478.     }
  479.     }
  480.     for (i = 0; i != 8+6*(new ? 9 : 8); i++) {
  481.     long x1, x2;
  482.     fread(&x1, 4, 1, in1);
  483.     fread(&x2, 4, 1, in2);
  484.     if (x1 != x2) {
  485.         if (i < 4)
  486.         printf("%s ammo capacity differs: (%ld -> %ld)\n", ammo1[i&3],
  487.             x1, x2);
  488.         else if (i < 8)
  489.         printf("%s ammo item size differs: (%ld -> %ld)\n", ammo1[i&3],
  490.             x1, x2);
  491.         else
  492.         printf("%s %s differs: (%ld -> %ld)\n",
  493.             ammo2[(i-8)/6], ammoattr[(i-8)%6],
  494.             x1, x2);
  495.     }
  496.     }
  497.     for (i = 0; i != FRAME_COUNT; i++) {
  498.     fread(fbuf1, 1, sizeof fbuf1, in1);
  499.     fread(fbuf2, 1, sizeof fbuf2, in2);
  500.     if (feof(in1) || feof(in2))
  501.         break;
  502.     if (memcmp(fbuf1, fbuf2, sizeof fbuf1)) {
  503.         char spname1[12], spname2[12];
  504.         printf("frame %d differences:\n", i);
  505.         if ((fbuf1[1] & 0x8000) != (fbuf2[1] & 0x8000))     
  506.         printf("  full brightness (%d -> %d)\n",
  507.             (fbuf1[1] & 0x8000) != 0,
  508.             (fbuf2[1] & 0x8000) != 0);
  509.         fbuf1[1] &= ~0x8000;
  510.         fbuf2[1] &= ~0x8000;
  511.         for (j = 0; j != 7; j++) {
  512.         if (fbuf1[j] != fbuf2[j]) {
  513.             if (!j)
  514.             printf("  %s (%s -> %s)\n",
  515.                 fattr[j], get_spr_name(spname1, fbuf1[j], in1),
  516.                 get_spr_name(spname2, fbuf2[j], in2));
  517.             else
  518.             printf("  %s (%ld -> %ld)\n", fattr[j],
  519.                 fbuf1[j], fbuf2[j]);
  520.         }
  521.         }
  522.     }
  523.     }
  524.     if (!new)
  525.     exit(0);
  526.     for (i = 0; i != 107; i++) {
  527.     long sbuf1[9], sbuf2[9];
  528.     fread(sbuf1, 1, sizeof sbuf1, in1);
  529.     fread(sbuf2, 1, sizeof sbuf2, in2);
  530.     if (!memcmp(sbuf1, sbuf2, sizeof sbuf1))
  531.         continue;
  532.     printf("sound %d differences:\n", i+1);
  533.     if (sbuf1[0] != sbuf2[0]) {
  534.         char snbuf1[12], snbuf2[12];
  535.         get_str_by_ptr(snbuf1, &sbuf1[0], in1);
  536.         get_str_by_ptr(snbuf2, &sbuf2[0], in2);
  537.         printf("  name (%ld (%s) -> %ld (%s))\n",
  538.         sbuf1[0], snbuf1, sbuf2[0], snbuf2);
  539.     }
  540.     if (sbuf1[1] != sbuf2[1])
  541.         printf("  0/1 (%ld -> %ld)\n", sbuf1[1], sbuf2[1]);
  542.     if (sbuf1[2] != sbuf2[2])
  543.         printf("  value (%ld -> %ld)\n", sbuf1[2], sbuf2[2]);
  544.     }
  545.     for (i = 0; i != 138; i++) {
  546.     long s1, s2;
  547.     char sbuf1[12], sbuf2[12];
  548.     fread(&s1, 1, sizeof s1, in1);
  549.     fread(&s2, 1, sizeof s2, in2);
  550.     if (s1 == s2) continue;
  551.     get_str_by_ptr(sbuf1, &s1, in1);
  552.     get_str_by_ptr(sbuf2, &s2, in2);
  553.     printf("sprite pointer %d differs (%ld (%s) -> %ld (%s))\n",
  554.         i, s1, sbuf1, s2, sbuf2);
  555.     }
  556.     while (getstr(&sstate1, in1) && getstr(&sstate2, in2)) {
  557.     if (strcmp(sstate1.str, sstate2.str))
  558.         printf("string differs:\n  \"%s\" ->\n  \"%s\"\n",
  559.         sstate1.str, sstate2.str);
  560.     }
  561. }
  562.