Пример #1
0
//--------------------------------------------------------------------------------------------
wawalite_data_t *wawalite_data_read(const std::string& filename, wawalite_data_t *profile)
{
    /**
     * @brief
     *  Read environmental data for the current module.
     */
    if (!profile)
    {
        throw std::invalid_argument("nullptr == profile");
    }
    // Reset to defaults.
    *profile = wawalite_data_t::getDefaults();

    ReadContext ctxt(filename);
    if (!ctxt.ensureOpen())
    {
		Log::get().warn("unable to read water and weather file `%s`\n", filename.c_str());
        return nullptr;
    }

    //First figure out what version of wawalite this is, so that we know what data we
    //should expect to load
    profile->version = vfs_get_version(ctxt);

    //  Random map...
    //  If someone else wants to handle this, here are some thoughts for approaching
    //  it.  The .MPD file for the level should give the basic size of the map.  Use
    //  a standard tile set like the Palace modules.  Only use objects that are in
    //  the module's object directory, and only use some of them.  Imagine several Rock
    //  Moles eating through a stone filled level to make a path from the entrance to
    //  the exit.  Door placement will be difficult.
    profile->seed = vfs_get_next_bool(ctxt);

    wawalite_water_t::read(ctxt, &(profile->water));
    wawalite_light_t::read(ctxt, &(profile->light));
    wawalite_physics_t::read(ctxt, &(profile->phys));
    wawalite_animtile_t::read(ctxt, &(profile->animtile));
    wawalite_damagetile_t::read(ctxt, &(profile->damagetile));
    wawalite_weather_t::read(ctxt, profile, &(profile->weather));
    wawalite_graphics_t::read(ctxt, &(profile->graphics));
    wawalite_camera_t::read(ctxt, &(profile->camera));
    wawalite_fog_t::read(ctxt, &(profile->fog));
    if (profile->fog.found)
    {
        // Read extra stuff for damage tile particles...
        if (ctxt.skipToColon(true))
        {
            profile->damagetile.part_gpip = vfs_get_local_particle_profile_ref(ctxt);
            profile->damagetile.partand = vfs_get_next_int(ctxt);
            profile->damagetile.sound_index = vfs_get_next_int(ctxt);
        }
    }

    return profile;
}
Пример #2
0
//--------------------------------------------------------------------------------------------
void wawalite_animtile_t::read(ReadContext& ctxt, wawalite_animtile_t *profile)
{
    if (!profile)
    {
        throw std::invalid_argument("nullptr == profile");
    }
    // Reset to defaults.
    *profile = wawalite_animtile_t::getDefaults();

    profile->update_and = vfs_get_next_int(ctxt);
    profile->frame_and = vfs_get_next_int(ctxt);
}
Пример #3
0
//--------------------------------------------------------------------------------------------
void wawalite_damagetile_t::read(ReadContext& ctxt, wawalite_damagetile_t *profile)
{
    if (!profile)
    {
        throw std::invalid_argument("nullptr == profile");
    }
    // Reset to defaults.
    *profile = wawalite_damagetile_t::getDefaults();

    // damage tile
    profile->amount = vfs_get_next_int(ctxt);
    /// @todo pass the load name
    profile->damagetype = vfs_get_next_damage_type(ctxt);
}
Пример #4
0
//--------------------------------------------------------------------------------------------
void wawalite_weather_t::read(ReadContext& ctxt, wawalite_data_t *enclosing, wawalite_weather_t *profile)
{
    if (!profile)
    {
        throw std::invalid_argument("nullptr == profile");
    }
    // Reset to defaults.
    *profile = wawalite_weather_t::getDefaults();

    // weather data
    profile->part_gpip = LocalParticleProfileRef(PIP_WEATHER);
    if (enclosing->version >= WAWALITE_FILE_VERSION)
    {
        STRING line;

        //Parse the weather type line
        vfs_get_next_string_lit(ctxt, line, SDL_arraysize(line));
        profile->weather_name = line;
        Ego::toupper(profile->weather_name);
    }

    profile->over_water = vfs_get_next_bool(ctxt);
    profile->timer_reset = vfs_get_next_int(ctxt);
}
Пример #5
0
std::shared_ptr<EnchantProfile> EnchantProfile::readFromFile(const std::string& pathname)
{
    std::shared_ptr<EnchantProfile> profile = std::make_shared<EnchantProfile>();

    ReadContext ctxt(pathname);
    if (!ctxt.ensureOpen())
    {
        return nullptr;
    }

    // true/false values
    profile->retarget = vfs_get_next_bool(ctxt);
    profile->_override = vfs_get_next_bool(ctxt);
    profile->remove_overridden = vfs_get_next_bool(ctxt);
    profile->killtargetonend = vfs_get_next_bool(ctxt);

    profile->poofonend = vfs_get_next_bool(ctxt);

    // More stuff
    profile->lifetime = vfs_get_next_int(ctxt);
    profile->endmessage = vfs_get_next_int(ctxt);

    // Drain stuff
    profile->_owner._manaDrain = vfs_get_next_float(ctxt);
    profile->_target._manaDrain = vfs_get_next_float(ctxt);
    profile->endIfCannotPay = vfs_get_next_bool(ctxt);
    profile->_owner._lifeDrain = vfs_get_next_float(ctxt);
    profile->_target._lifeDrain = vfs_get_next_float(ctxt);

    // Specifics
    profile->required_damagetype = vfs_get_next_damage_type(ctxt);
    profile->require_damagetarget_damagetype = vfs_get_next_damage_type(ctxt);
    profile->removedByIDSZ = vfs_get_next_idsz(ctxt);

    // Now the set values
    profile->_set[EnchantProfile::SETDAMAGETYPE].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETDAMAGETYPE].value = vfs_get_damage_type(ctxt);

    profile->_set[EnchantProfile::SETNUMBEROFJUMPS].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETNUMBEROFJUMPS].value = ctxt.readIntegerLiteral();

    profile->_set[EnchantProfile::SETLIFEBARCOLOR].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETLIFEBARCOLOR].value = ctxt.readIntegerLiteral();

    profile->_set[EnchantProfile::SETMANABARCOLOR].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETMANABARCOLOR].value = ctxt.readIntegerLiteral();

    profile->_set[EnchantProfile::SETSLASHMODIFIER].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETSLASHMODIFIER].value = vfs_get_damage_modifier(ctxt);
    profile->_add[EnchantProfile::ADDSLASHRESIST].value = ctxt.readRealLiteral();

    profile->_set[EnchantProfile::SETCRUSHMODIFIER].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETCRUSHMODIFIER].value = vfs_get_damage_modifier(ctxt);
    profile->_add[EnchantProfile::ADDCRUSHRESIST].value = ctxt.readRealLiteral();

    profile->_set[EnchantProfile::SETPOKEMODIFIER].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETPOKEMODIFIER].value = vfs_get_damage_modifier(ctxt);
    profile->_add[EnchantProfile::ADDPOKERESIST].value = ctxt.readRealLiteral();

    profile->_set[EnchantProfile::SETHOLYMODIFIER].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETHOLYMODIFIER].value = vfs_get_damage_modifier(ctxt);
    profile->_add[EnchantProfile::ADDHOLYRESIST].value = ctxt.readRealLiteral();

    profile->_set[EnchantProfile::SETEVILMODIFIER].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETEVILMODIFIER].value = vfs_get_damage_modifier(ctxt);
    profile->_add[EnchantProfile::ADDEVILRESIST].value = ctxt.readRealLiteral();

    profile->_set[EnchantProfile::SETFIREMODIFIER].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETFIREMODIFIER].value = vfs_get_damage_modifier(ctxt);
    profile->_add[EnchantProfile::ADDFIRERESIST].value = ctxt.readRealLiteral();

    profile->_set[EnchantProfile::SETICEMODIFIER].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETICEMODIFIER].value = vfs_get_damage_modifier(ctxt);
    profile->_add[EnchantProfile::ADDICERESIST].value = ctxt.readRealLiteral();

    profile->_set[EnchantProfile::SETZAPMODIFIER].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETZAPMODIFIER].value = vfs_get_damage_modifier(ctxt);
    profile->_add[EnchantProfile::ADDZAPRESIST].value = ctxt.readRealLiteral();

    profile->_set[EnchantProfile::SETFLASHINGAND].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETFLASHINGAND].value = ctxt.readIntegerLiteral();

    profile->_set[EnchantProfile::SETLIGHTBLEND].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETLIGHTBLEND].value = ctxt.readIntegerLiteral();

    profile->_set[EnchantProfile::SETALPHABLEND].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETALPHABLEND].value = ctxt.readIntegerLiteral();

    profile->_set[EnchantProfile::SETSHEEN].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETSHEEN].value = ctxt.readIntegerLiteral();

    profile->_set[EnchantProfile::SETFLYTOHEIGHT].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETFLYTOHEIGHT].value = ctxt.readIntegerLiteral();

    profile->_set[EnchantProfile::SETWALKONWATER].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETWALKONWATER].value = ctxt.readBool();

    profile->_set[EnchantProfile::SETCANSEEINVISIBLE].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETCANSEEINVISIBLE].value = ctxt.readBool();

    Ego::Script::EnumDescriptor<MissileTreatment> enumDescriptor
        (
            "MissileTreatment",
            {
                // Normal.
                {"Normal", MissileTreatment_Normal},
                {"NORMAL", MissileTreatment_Normal},
                {"N", MissileTreatment_Normal},
            // Reflect.
                {"Reflect", MissileTreatment_Reflect},
                {"REFLECT", MissileTreatment_Reflect},
                {"R", MissileTreatment_Reflect},
            // Deflect.
                {"Deflect", MissileTreatment_Deflect},
                {"DEFLECT", MissileTreatment_Deflect},
                {"D", MissileTreatment_Deflect},
            }
    );

    profile->_set[EnchantProfile::SETMISSILETREATMENT].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETMISSILETREATMENT].value = ctxt.readEnum(enumDescriptor);

    profile->_set[EnchantProfile::SETCOSTFOREACHMISSILE].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETCOSTFOREACHMISSILE].value = ctxt.readRealLiteral();

    profile->_set[EnchantProfile::SETMORPH].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETMORPH].value = true;  // vfs_get_bool( fileread );        //ZF> huh? why always channel and morph?

    profile->_set[EnchantProfile::SETCHANNEL].apply = vfs_get_next_bool(ctxt);
    profile->_set[EnchantProfile::SETCHANNEL].value = true;  // vfs_get_bool( fileread );

    // Now read in the add values
    profile->_add[EnchantProfile::ADDJUMPPOWER].value = vfs_get_next_float(ctxt);
    profile->_add[EnchantProfile::ADDBUMPDAMPEN].value = vfs_get_next_int(ctxt) / 256.0f;    // Stored as 8.8-fixed, used as float
    profile->_add[EnchantProfile::ADDBOUNCINESS].value = vfs_get_next_int(ctxt) / 256.0f;    // Stored as 8.8-fixed, used as float
    profile->_add[EnchantProfile::ADDDAMAGE].value = vfs_get_next_float(ctxt);            // Stored as float, used as 8.8-fixed
    profile->_add[EnchantProfile::ADDSIZE].value = vfs_get_next_float(ctxt);           // Stored as float, used as float
    profile->_add[EnchantProfile::ADDACCEL].value = vfs_get_next_int(ctxt) / 80.0f;   // Stored as int, used as float
    profile->_add[EnchantProfile::ADDRED].value = vfs_get_next_int(ctxt);
    profile->_add[EnchantProfile::ADDGRN].value = vfs_get_next_int(ctxt);
    profile->_add[EnchantProfile::ADDBLU].value = vfs_get_next_int(ctxt);
    profile->_add[EnchantProfile::ADDDEFENSE].value = -vfs_get_next_int(ctxt);    // Defense is backwards
    profile->_add[EnchantProfile::ADDMANA].value = vfs_get_next_float(ctxt);    // Stored as float, used as 8.8-fixed
    profile->_add[EnchantProfile::ADDLIFE].value = vfs_get_next_float(ctxt);    // Stored as float, used as 8.8-fixed
    profile->_add[EnchantProfile::ADDSTRENGTH].value = vfs_get_next_float(ctxt);    // Stored as float, used as 8.8-fixed
    profile->_add[EnchantProfile::ADDWISDOM].value = vfs_get_next_float(ctxt);    // Deprecated (not used)
    profile->_add[EnchantProfile::ADDINTELLIGENCE].value = vfs_get_next_float(ctxt);    // Stored as float, used as 8.8-fixed
    profile->_add[EnchantProfile::ADDDEXTERITY].value = vfs_get_next_float(ctxt);    // Stored as float, used as 8.8-fixed

    // Determine which entries are not important
    for (size_t cnt = 0; cnt < EnchantProfile::MAX_ENCHANT_ADD; cnt++)
    {
        profile->_add[cnt].apply = (0.0f != profile->_add[cnt].value);
    }
    profile->_add[EnchantProfile::ADDFIRERESIST].apply = profile->_set[EnchantProfile::SETFIREMODIFIER].apply;
    profile->_add[EnchantProfile::ADDEVILRESIST].apply = profile->_set[EnchantProfile::SETEVILMODIFIER].apply;
    profile->_add[EnchantProfile::ADDZAPRESIST].apply = profile->_set[EnchantProfile::SETZAPMODIFIER].apply;
    profile->_add[EnchantProfile::ADDICERESIST].apply = profile->_set[EnchantProfile::SETICEMODIFIER].apply;
    profile->_add[EnchantProfile::ADDHOLYRESIST].apply = profile->_set[EnchantProfile::SETHOLYMODIFIER].apply;
    profile->_add[EnchantProfile::ADDPOKERESIST].apply = profile->_set[EnchantProfile::SETPOKEMODIFIER].apply;
    profile->_add[EnchantProfile::ADDSLASHRESIST].apply = profile->_set[EnchantProfile::SETSLASHMODIFIER].apply;
    profile->_add[EnchantProfile::ADDCRUSHRESIST].apply = profile->_set[EnchantProfile::SETCRUSHMODIFIER].apply;

    // Read expansions
    while (ctxt.skipToColon(true))
    {
        switch(ctxt.readIDSZ().toUint32())
        {
            case IDSZ2::caseLabel('A', 'M', 'O', 'U'): profile->contspawn._amount = ctxt.readIntegerLiteral(); break;
            case IDSZ2::caseLabel('T', 'Y', 'P', 'E'): profile->contspawn._lpip = vfs_get_local_particle_profile_ref(ctxt); break;
            case IDSZ2::caseLabel('T', 'I', 'M', 'E'): profile->contspawn._delay = ctxt.readIntegerLiteral(); break;
            case IDSZ2::caseLabel('F', 'A', 'C', 'E'): profile->contspawn._facingAdd = ctxt.readIntegerLiteral(); break;
            case IDSZ2::caseLabel('S', 'E', 'N', 'D'): profile->endsound_index = ctxt.readIntegerLiteral(); break;
            case IDSZ2::caseLabel('S', 'T', 'A', 'Y'): profile->_owner._stay = (0 != ctxt.readIntegerLiteral()); break;
            case IDSZ2::caseLabel('O', 'V', 'E', 'R'): profile->spawn_overlay = (0 != ctxt.readIntegerLiteral()); break;
            case IDSZ2::caseLabel('D', 'E', 'A', 'D'): profile->_target._stay = (0 != ctxt.readIntegerLiteral()); break;
            case IDSZ2::caseLabel('C', 'K', 'U', 'R'): profile->seeKurses = ctxt.readIntegerLiteral(); break;
            case IDSZ2::caseLabel('D', 'A', 'R', 'K'): profile->darkvision = ctxt.readIntegerLiteral(); break;
            case IDSZ2::caseLabel('N', 'A', 'M', 'E'): profile->setEnchantName(ctxt.readName()); break;
            default: /*TODO: log error*/ break;
        }
    }

    profile->_name = pathname;

    // Limit the endsound_index.
    profile->endsound_index = Ego::Math::constrain<Sint16>(profile->endsound_index, INVALID_SOUND_ID, MAX_WAVE);

    return profile;
}
Пример #6
0
void font_bmp_load_vfs( const std::string& szBitmap, const char* szSpacing )
{
    /// @author ZZ
    /// @details This function loads the font bitmap and sets up the coordinates
    ///    of each font on that bitmap...  Bitmap must have 16x6 fonts
    font_bmp_init();

    const std::shared_ptr<Ego::Texture> &fontTexture = Ego::TextureManager::get().getTexture(szBitmap);
	if (fontTexture->isDefault())
    {
		std::ostringstream os;
		os << "load_font() - unable to load file `" << szBitmap << "`" << std::endl;
		Log::get().error("%s", os.str().c_str());
		throw std::runtime_error(os.str());
    }

    // Get the size of the bitmap
    int xsize = fontTexture->getSourceWidth();
    int ysize = fontTexture->getSourceHeight();
    if ( 0 == xsize || 0 == ysize )
    {
		std::ostringstream os;
		os << "bad font size (" << xsize << ", " << ysize << ")" << std::endl;
		Log::get().error("%s", os.str().c_str());
		throw std::runtime_error(os.str());
    }

    // Figure out where each font is and its spacing
    ReadContext ctxt(szSpacing);

    uint32_t stt_x = 0;
    uint32_t stt_y = 0;

    // Uniform font height is at the top
    uint32_t yspacing = vfs_get_next_int(ctxt);
    fontoffset = yspacing;
    for (size_t cnt = 0; cnt < NUMFONT && ctxt.skipToColon(true); ++cnt)
    {
        uint8_t chr = static_cast<uint8_t>(ctxt.readCharacterLiteral());
        uint32_t xspacing = ctxt.readIntegerLiteral();
        
        if (asciitofont[chr] == 255) {
            asciitofont[chr] = static_cast<uint8_t>(cnt);
        }

        if (stt_x + xspacing + 1 > 255)
        {
            stt_x = 0;
            stt_y += yspacing;
        }

        fontrect[cnt].x = stt_x;
        fontrect[cnt].w = xspacing;
        fontrect[cnt].y = stt_y;
        fontrect[cnt].h = yspacing - 2;
        fontxspacing[cnt] = xspacing + 1;

        stt_x += xspacing + 1;
    }

    // Space between lines
    fontyspacing = (yspacing / 2) + FONTADD;
}
Пример #7
0
//--------------------------------------------------------------------------------------------
void wawalite_water_t::read(ReadContext& ctxt, wawalite_water_t *profile)
{
    if (!profile)
    {
        throw std::invalid_argument("nullptr == profile");
    }

    // Reset to defaults.
    *profile = wawalite_water_t::getDefaults();

    // Read the water data.
    profile->layer_count = vfs_get_next_int(ctxt);
    profile->spek_start = vfs_get_next_int(ctxt);
    profile->spek_level = vfs_get_next_int(ctxt);
    profile->douse_level = vfs_get_next_float(ctxt);
    profile->surface_level = vfs_get_next_float(ctxt);
    profile->light = vfs_get_next_bool(ctxt);
    profile->is_water = vfs_get_next_bool(ctxt);
    profile->overlay_req = vfs_get_next_bool(ctxt);
    profile->background_req = vfs_get_next_bool(ctxt);

    // General data info
    profile->layer[0].dist[XX] = vfs_get_next_float(ctxt);
    profile->layer[0].dist[YY] = vfs_get_next_float(ctxt);
    profile->layer[1].dist[XX] = vfs_get_next_float(ctxt);
    profile->layer[1].dist[YY] = vfs_get_next_float(ctxt);
    profile->foregroundrepeat = vfs_get_next_float(ctxt);
    profile->backgroundrepeat = vfs_get_next_float(ctxt);

    // Read the first water layer.
    profile->layer[0].z = vfs_get_next_float(ctxt);
    profile->layer[0].alpha = vfs_get_next_int(ctxt);
    profile->layer[0].frame_add = vfs_get_next_int(ctxt);
    profile->layer[0].light_dir = vfs_get_next_int(ctxt);
    profile->layer[0].light_add = vfs_get_next_int(ctxt);
    profile->layer[0].amp = vfs_get_next_float(ctxt);
    profile->layer[0].tx_add[SS] = vfs_get_next_float(ctxt);
    profile->layer[0].tx_add[TT] = vfs_get_next_float(ctxt);

    // Read the second water layer.
    profile->layer[1].z = vfs_get_next_int(ctxt);
    profile->layer[1].alpha = vfs_get_next_int(ctxt);
    profile->layer[1].frame_add = vfs_get_next_int(ctxt);
    profile->layer[1].light_dir = vfs_get_next_int(ctxt);
    profile->layer[1].light_add = vfs_get_next_int(ctxt);
    profile->layer[1].amp = vfs_get_next_float(ctxt);
    profile->layer[1].tx_add[SS] = vfs_get_next_float(ctxt);
    profile->layer[1].tx_add[TT] = vfs_get_next_float(ctxt);
}
Пример #8
0
//--------------------------------------------------------------------------------------------
bool tile_dictionary_load_vfs( const char * filename, tile_dictionary_t * pdict, int max_dict_size )
{
    /// @author ZZ
    /// @details This function loads fan types for the terrain

    Uint32 cnt, entry, vertices, commandsize;
    int fantype_count, fantype_offset, fantype;
    int command_count, command;
    int definition_count;
    int itmp;
    float ftmp;

    if ( NULL == pdict ) return false;

    // "delete" the old list
    *pdict = tile_dictionary_t();

    if ( !VALID_CSTR( filename ) ) return false;

    // handle default parameters
    if ( max_dict_size < 0 )
    {
        max_dict_size = MAP_FAN_TYPE_MAX;
    }

    // Try to open a context.
    ReadContext ctxt(filename);
    if (!ctxt.ensureOpen()) {
		Log::get().error("unable to load tile definitions file `%s`\n", filename);
        return false;
    }

    fantype_count    = vfs_get_next_int(ctxt);
    fantype_offset   = 2 * std::pow( 2.0f, std::floor( std::log( fantype_count ) / std::log( 2.0f ) ) );
    definition_count = 2 * fantype_offset;

    if ( definition_count > MAP_FAN_TYPE_MAX )
    {
		Log::get().error( "%s - tile dictionary has too many tile definitions (%d/%d).\n", __FUNCTION__, definition_count, MAP_FAN_TYPE_MAX );
        return false;
    }
    else if ( definition_count > max_dict_size )
    {
		Log::get().error( "%s - the number of tile difinitions has exceeded the requested number (%d/%d).\n", __FUNCTION__, definition_count, max_dict_size );
        return false;
    }

    pdict->offset    = fantype_offset;
    pdict->def_count = definition_count;

    for ( fantype = 0; fantype < fantype_count; fantype++ )
    {
        tile_definition_t& pdef_sml = pdict->def_lst[fantype];
        tile_definition_t& pdef_big = pdict->def_lst[fantype + fantype_offset];

        vertices = vfs_get_next_int(ctxt);

        pdef_sml.numvertices = vertices;
        pdef_big.numvertices = vertices;  // Dupe

        for ( cnt = 0; cnt < vertices; cnt++ )
        {
            itmp = vfs_get_next_int(ctxt);
            pdef_sml.ref[cnt]    = itmp;
            pdef_sml.grid_ix[cnt] = itmp & 3;
            pdef_sml.grid_iy[cnt] = ( itmp >> 2 ) & 3;

            ftmp = vfs_get_next_float(ctxt);
            pdef_sml.u[cnt] = ftmp;

            ftmp = vfs_get_next_float(ctxt);
            pdef_sml.v[cnt] = ftmp;

            // Dupe
            pdef_big.ref[cnt]    = pdef_sml.ref[cnt];
            pdef_big.grid_ix[cnt] = pdef_sml.grid_ix[cnt];
            pdef_big.grid_iy[cnt] = pdef_sml.grid_iy[cnt];
            pdef_big.u[cnt]      = pdef_sml.u[cnt];
            pdef_big.v[cnt]      = pdef_sml.v[cnt];
        }

        command_count = vfs_get_next_int(ctxt);
        pdef_sml.command_count = command_count;
        pdef_big.command_count = command_count;  // Dupe

        for ( entry = 0, command = 0; command < command_count; command++ )
        {
            commandsize = vfs_get_next_int(ctxt);
            pdef_sml.command_entries[command] = commandsize;
            pdef_big.command_entries[command] = commandsize;  // Dupe

            for ( cnt = 0; cnt < commandsize; cnt++ )
            {
                itmp = vfs_get_next_int(ctxt);
                pdef_sml.command_verts[entry] = itmp;
                pdef_big.command_verts[entry] = itmp;  // Dupe

                entry++;
            }
        }
    }

    pdict->loaded = true;

    tile_dictionary_finalize( pdict );

    return true;
}