Ejemplo n.º 1
0
boolean DEH_SetStringMapping(deh_context_t *context, deh_mapping_t *mapping,
                             void *structptr, char *name, char *value)
{
    deh_mapping_entry_t *entry;
    void *location;

    entry = GetMappingEntryByName(context, mapping, name);

    if (entry == NULL)
    {
        return false;
    }

    // Sanity check:

    if (!entry->is_string)
    {
        DEH_Error(context, "Tried to set '%s' as string (BUG)", name);
        return false;
    }

    location = GetStructField(structptr, mapping, entry);

    // Copy value into field:

    M_StringCopy(location, value, entry->size);

    return true;
}
Ejemplo n.º 2
0
static void DEH_FrameOverflow(deh_context_t *context, char *varname, int value)
{
    if (!strcasecmp(varname, "Duration"))
    {
        weaponinfo[0].ammo = value;
    }
    else if (!strcasecmp(varname, "Codep frame")) 
    {
        weaponinfo[0].upstate = value;
    }
    else if (!strcasecmp(varname, "Next frame")) 
    {
        weaponinfo[0].downstate = value;
    }
    else if (!strcasecmp(varname, "Unknown 1"))
    {
        weaponinfo[0].readystate = value;
    }
    else if (!strcasecmp(varname, "Unknown 2"))
    {
        weaponinfo[0].atkstate = value;
    }
    else
    {
        DEH_Error(context, "Unable to simulate frame overflow: field '%s'",
                  varname);
    }
}
Ejemplo n.º 3
0
boolean DEH_SetMapping(deh_context_t *context, deh_mapping_t *mapping,
                       void *structptr, char *name, int value)
{
    deh_mapping_entry_t *entry;
    void *location;

    entry = GetMappingEntryByName(context, mapping, name);

    if (entry == NULL)
    {
        return false;
    }

    // Sanity check:

    if (entry->is_string)
    {
        DEH_Error(context, "Tried to set '%s' as integer (BUG)", name);
        return false;
    }

    location = GetStructField(structptr, mapping, entry);

    //       printf("Setting %p::%s to %i (%i bytes)\n",
    //               structptr, name, value, entry->size);

    // Set field content based on its type:

    switch (entry->size)
    {
        case 1:
            * ((uint8_t *) location) = value;
            break;
        case 2:
            * ((uint16_t *) location) = value;
            break;
        case 4:
            * ((uint32_t *) location) = value;
            break;
        default:
            DEH_Error(context, "Unknown field type for '%s' (BUG)", name);
            return false;
    }

    return true;
}
Ejemplo n.º 4
0
static void DEH_FrameParseLine(deh_context_t *context, char *line, void *tag)
{
    state_t *state;
    char *variable_name, *value;
    int ivalue;

    if (tag == NULL)
       return;

    state = (state_t *) tag;

    // Parse the assignment

    if (!DEH_ParseAssignment(line, &variable_name, &value))
    {
        // Failed to parse

        DEH_Warning(context, "Failed to parse assignment");
        return;
    }

    // all values are integers

    ivalue = atoi(value);

    // Action pointer field is a special case:

    if (!strcasecmp(variable_name, "Action pointer"))
    {
        void *func;

        if (!GetActionPointerForOffset(ivalue, &func))
        {
            SuggestOtherVersions(ivalue);
            DEH_Error(context, "Unknown action pointer: %i", ivalue);
            return;
        }

        state->action = func;
    }
    else
    {
        // "Next frame" numbers need to undergo mapping.

        if (!strcasecmp(variable_name, "Next frame"))
        {
            ivalue = DEH_MapHereticFrameNumber(ivalue);
        }

        DEH_SetMapping(context, &state_mapping, state, variable_name, ivalue);
    }
}
Ejemplo n.º 5
0
static void DEH_CheatParseLine(deh_context_t *context, char *line, void *tag)
{
    deh_cheat_t *cheat;
    char *variable_name;
    char *value;
    unsigned char *unsvalue;
    unsigned int i;

    if (!DEH_ParseAssignment(line, &variable_name, &value))
    {
        // Failed to parse

        DEH_Warning(context, "Failed to parse assignment");
        return;
    }

    unsvalue = (unsigned char *) value;

    cheat = FindCheatByName(variable_name);

    if (cheat == NULL)
    {
        DEH_Warning(context, "Unknown cheat '%s'", variable_name);
        return;
    }

    // write the value into the cheat sequence

    i = 0;

    while (unsvalue[i] != 0 && unsvalue[i] != 0xff)
    {
        // If the cheat length exceeds the Vanilla limit, stop.  This
        // does not apply if we have the limit turned off.

        if (!deh_allow_long_cheats && i >= cheat->seq->sequence_len)
        {
            DEH_Warning(context, "Cheat sequence longer than supported by "
                                 "Vanilla dehacked");
            break;
        }

	if (deh_apply_cheats)
	{
	    cheat->seq->sequence[i] = unsvalue[i];
	}
        ++i;

        // Absolute limit - don't exceed

        if (i >= MAX_CHEAT_LEN - cheat->seq->parameter_chars)
        {
            DEH_Error(context, "Cheat sequence too long!");
            return;
        }
    }

    if (deh_apply_cheats)
    {
        cheat->seq->sequence[i] = '\0';
    }
}
Ejemplo n.º 6
0
static void DEH_ParseContext(deh_context_t *context)
{
    deh_section_t *current_section = NULL;
    char section_name[20];
    void *tag = NULL;
    boolean extended;
    char *line;

    // Read the header and check it matches the signature

    if (!CheckSignatures(context))
    {
        DEH_Error(context, "This is not a valid dehacked patch file!");
    }

    // Read the file

    while (!DEH_HadError(context))
    {
        // Read the next line. We only allow the special extended parsing
        // for the BEX [STRINGS] section.
        extended = current_section != NULL
                && !strcasecmp(current_section->name, "[STRINGS]");
        line = DEH_ReadLine(context, extended);

        // end of file?

        if (line == NULL)
        {
            return;
        }

        while (line[0] != '\0' && isspace(line[0]))
            ++line;

        if (line[0] == '#')
        {
            // comment

            DEH_ParseComment(line);
            continue;
        }

        if (IsWhitespace(line))
        {
            if (current_section != NULL)
            {
                // end of section

                if (current_section->end != NULL)
                {
                    current_section->end(context, tag);
                }

                //printf("end %s tag\n", current_section->name);
                current_section = NULL;
            }
        }
        else
        {
            if (current_section != NULL)
            {
                // parse this line

                current_section->line_parser(context, line, tag);
            }
            else
            {
                // possibly the start of a new section

                sscanf(line, "%19s", section_name);

                current_section = GetSectionByName(section_name);

                if (current_section != NULL)
                {
                    tag = current_section->start(context, line);
                    //printf("started %s tag\n", section_name);
                }
                else
                {
                    //printf("unknown section name %s\n", section_name);
                }
            }
        }
    }
}
Ejemplo n.º 7
0
static void *DEH_TextStart(deh_context_t *context, char *line)
{
    char *repl_text;
    char *orig_text;
    int orig_offset, repl_len;
    int i;

    if (sscanf(line, "Text %i %i", &orig_offset, &repl_len) != 2)
    {
        DEH_Warning(context, "Parse error on section start");
        return NULL;
    }

    repl_text = malloc(repl_len + 1);

    // read in the "to" text

    for (i=0; i<repl_len; ++i)
    {
        int c;

        c = DEH_GetChar(context);

        repl_text[i] = c;
    }
    repl_text[repl_len] = '\0';

    // We don't support all strings, but at least recognise them:

    if (StringIsUnsupported(orig_offset))
    {
        DEH_Warning(context, "Unsupported string replacement: %i", orig_offset);
    }

    // Find the string to replace:

    else if (!GetStringByOffset(orig_offset, &orig_text))
    {
        SuggestOtherVersions(orig_offset);
        DEH_Error(context, "Unknown string offset: %i", orig_offset);
    }

    // Only allow string replacements that are possible in Vanilla Doom.  
    // Chocolate Doom is unforgiving!

    else if (!deh_allow_long_strings
          && repl_len > MaxStringLength(strlen(orig_text)))
    {
        DEH_Error(context, "Replacement string is longer than the maximum "
                           "possible in heretic.exe");
    }
    else
    {
        // Success.

        DEH_AddStringReplacement(orig_text, repl_text);
    }

    // We must always free the replacement text.
    free(repl_text);

    return NULL;
}