components/prboom/d_deh.c
// ====================================================================
// deh_procThing
// Purpose: Handle DEH Thing block
// Args:    fpin  -- input file stream
//          fpout -- output file stream (DEHOUT.TXT)
//          line  -- current line in file to process
// Returns: void
//
// Ty 8/27/98 - revised to also allow mnemonics for
// bit masks for monster attributes
//


Ty 8/27/98 - revised to also allow mnemonics for
bit masks for monster attributes
Ty 8 / 27 / 98 - revised to also allow mnemonics for bit masks for monster attributes
static void deh_procThing(DEHFILE *fpin, FILE* fpout, char *line)
{
  char key[DEH_MAXKEYLEN];
  char inbuffer[DEH_BUFFERMAX];
  uint_64_t value;      
  int indexnum;
  int ix;
  char *strval;
  strncpy(inbuffer,line,DEH_BUFFERMAX);
  if (fpout) fprintf(fpout,"Thing line: '%s'\n",inbuffer);
  ix = sscanf(inbuffer,"%s %i",key, &indexnum);
  if (fpout) fprintf(fpout,"count=%d, Thing %d\n",ix, indexnum);
  --indexnum;
  while (!dehfeof(fpin) && *inbuffer && (*inbuffer != ' '))
    {
      int bGetData;
      if (!dehfgets(inbuffer, sizeof(inbuffer), fpin)) break;
      lfstrip(inbuffer);  
      if (!*inbuffer) break;  
      bGetData = deh_GetData(inbuffer,key,&value,&strval,fpout);
      if (!bGetData)
        {
          if (fpout) fprintf(fpout,"Bad data pair in '%s'\n",inbuffer);
          continue;
        }
      for (ix=0; ix<DEH_MOBJINFOMAX; ix++) {
        if (strcasecmp(key,deh_mobjinfo[ix])) continue;
        if (strcasecmp(key,"bits")) {
          setMobjInfoValue(indexnum, ix, value);
        }
        else {
          if (bGetData==1) { 
            value = getConvertedDEHBits(value);
            mobjinfo[indexnum].flags = value;
          }
          else {
            value = 0;
             Use OR logic instead of addition, to allow repetition
            for (;(strval = strtok(strval,",+| \t\f\r")); strval = NULL) {
              size_t iy;
              for (iy=0; iy < DEH_MOBJFLAGMAX; iy++) {
                if (strcasecmp(strval,deh_mobjflags[iy].name)) continue;
                if (fpout) {
                  fprintf(fpout, 
                    "ORed value 0x%08lX%08lX %s\n",
                    (unsigned long)(deh_mobjflags[iy].value>>32) & 0xffffffff, 
                    (unsigned long)deh_mobjflags[iy].value & 0xffffffff, strval
                  );
                }
                value |= deh_mobjflags[iy].value;
                break;
              }
              if (iy >= DEH_MOBJFLAGMAX && fpout) {
                fprintf(fpout, "Could not find bit mnemonic %s\n", strval);
              }
            }
             Don't worry about conversion -- simply print values
            if (fpout) {
              fprintf(fpout, 
                "Bits = 0x%08lX%08lX\n",
                (unsigned long)(value>>32) & 0xffffffff, 
                (unsigned long)value & 0xffffffff
              );
            }
            mobjinfo[indexnum].flags = value;  e6y
          }
        }
        if (fpout) {
          fprintf(fpout,
            "Assigned 0x%08lx%08lx to %s(%d) at index %d\n",
            (unsigned long)(value>>32) & 0xffffffff, 
            (unsigned long)value & 0xffffffff, key, indexnum, ix
          );
        }
      }
    }
  return;
}
static void deh_procThing ( DEHFILE * fpin , FILE * fpout , char * line ) { char key [ DEH_MAXKEYLEN ] ; char inbuffer [ DEH_BUFFERMAX ] ; uint_64_t value ; int indexnum ; int ix ; char * strval ; strncpy ( inbuffer , line , DEH_BUFFERMAX ) ; if ( fpout ) fprintf ( fpout , " \n " , inbuffer ) ; ix = sscanf ( inbuffer , " " , key , & indexnum ) ; if ( fpout ) fprintf ( fpout , " \n " , ix , indexnum ) ; -- indexnum ; while ( ! dehfeof ( fpin ) && * inbuffer && ( * inbuffer != ' ' ) ) { int bGetData ; if ( ! dehfgets ( inbuffer , sizeof ( inbuffer ) , fpin ) ) break ; lfstrip ( inbuffer ) ; if ( ! * inbuffer ) break ; bGetData = deh_GetData ( inbuffer , key , & value , & strval , fpout ) ; if ( ! bGetData ) { if ( fpout ) fprintf ( fpout , " \n " , inbuffer ) ; continue ; } for ( ix = 0 ; ix < DEH_MOBJINFOMAX ; ix ++ ) { if ( strcasecmp ( key , deh_mobjinfo [ ix ] ) ) continue ; if ( strcasecmp ( key , " " ) ) { setMobjInfoValue ( indexnum , ix , value ) ; } else { if ( bGetData == 1 ) { value = getConvertedDEHBits ( value ) ; mobjinfo [ indexnum ] . flags = value ; } else { value = 0 ; for ( ; ( strval = strtok ( strval , " \t \f \r " ) ) ; strval = NULL ) { size_t iy ; for ( iy = 0 ; iy < DEH_MOBJFLAGMAX ; iy ++ ) { if ( strcasecmp ( strval , deh_mobjflags [ iy ] . name ) ) continue ; if ( fpout ) { fprintf ( fpout , " \n " , ( unsigned long ) ( deh_mobjflags [ iy ] . value >> 32 ) & 0xffffffff , ( unsigned long ) deh_mobjflags [ iy ] . value & 0xffffffff , strval ) ; } value |= deh_mobjflags [ iy ] . value ; break ; } if ( iy >= DEH_MOBJFLAGMAX && fpout ) { fprintf ( fpout , " \n " , strval ) ; } } if ( fpout ) { fprintf ( fpout , " \n " , ( unsigned long ) ( value >> 32 ) & 0xffffffff , ( unsigned long ) value & 0xffffffff ) ; } mobjinfo [ indexnum ] . flags = value ; } } if ( fpout ) { fprintf ( fpout , " \n " , ( unsigned long ) ( value >> 32 ) & 0xffffffff , ( unsigned long ) value & 0xffffffff , key , indexnum , ix ) ; } } } return ; }
deh_procThing
Purpose: Handle DEH Thing block
Args:    fpin  -- input file stream
fpout -- output file stream (DEHOUT.TXT)
line  -- current line in file to process
Returns: void
deh_procThing Purpose : Handle DEH Thing block Args : fpin -- input file stream fpout -- output file stream ( DEHOUT . TXT ) line -- current line in file to process Returns : void
// All deh values are ints or longs // killough 8/98: allow hex numbers in input: // Note that the mobjinfo[] array is base zero, but object numbers // in the dehacked file start with one.  Grumble. // now process the stuff // Note that for Things we can look up the key and use its offset // in the array of key strings as an int offset in the structure // get a line until a blank or end of file--it's not // blank now because it has our incoming key in it // e6y: Correction of wrong processing of Bits parameter if its value is equal to zero // No more desync on HACX demos. // toss the end of line // killough 11/98: really bail out on blank lines (break != continue) // bail out with blank line between sections // e6y: Correction of wrong processing of Bits parameter if its value is equal to zero // No more desync on HACX demos. // Old code: if (!deh_GetData(inbuffer,key,&value,&strval,fpout)) // returns TRUE if ok // standard value set // The old code here was the cause of a DEH-related bug in prboom. // When the mobjinfo_t.flags member was graduated to an int64, this // code was caught unawares and was indexing each property of the // mobjinfo as if it were still an int32. This caused sets of the  // "raisestate" member to partially overwrite the "flags" member,  // thus screwing everything up and making most DEH patches result in  // unshootable enemy types. Moved to a separate function above // and stripped of all hairy struct address indexing. - POPE // bit set // e6y: Correction of wrong processing of Bits parameter if its value is equal to zero // No more desync on HACX demos. // proff // figure out what the bits are // killough 10/98: replace '+' kludge with strtok() loop // Fix error-handling case ('found' var wasn't being reset) // // Use OR logic instead of addition, to allow repetition // Don't worry about conversion -- simply print values // e6y