Пример #1
0
void ResourceManager::readCluIndex(uint16 fileNum, Common::File *file) {
	if (_resFiles[fileNum].entryTab == NULL) {
		// we didn't read from this file before, get its index table
		if (file == NULL)
			file = openCluFile(fileNum);
		else
			file->incRef();

		// 1st DWORD of a cluster is an offset to the look-up table
		uint32 table_offset = file->readUint32LE();
		debug(6, "table offset = %d", table_offset);
		uint32 tableSize = file->size() - table_offset; // the table is stored at the end of the file
		file->seek(table_offset);

		assert((tableSize % 8) == 0);
		_resFiles[fileNum].entryTab = (uint32*)malloc(tableSize);
		_resFiles[fileNum].numEntries = tableSize / 8;
		file->read(_resFiles[fileNum].entryTab, tableSize);
		if (file->ioFailed())
			error("unable to read index table from file %s\n", _resFiles[fileNum].fileName);
#ifdef SCUMM_BIG_ENDIAN
		for (int tabCnt = 0; tabCnt < _resFiles[fileNum].numEntries * 2; tabCnt++)
			_resFiles[fileNum].entryTab[tabCnt] = FROM_LE_32(_resFiles[fileNum].entryTab[tabCnt]);
#endif
		file->decRef();
	}
}
Пример #2
0
uint32 ResourceManager::fetchLen(uint32 res) {
    if (_resList[res].ptr)
        return _resList[res].size;

    // Does this ever happen?
    warning("fetchLen: Resource %u is not loaded; reading length from file", res);

    // Points to the number of the ascii filename
    uint16 parent_res_file = _resConvTable[res * 2];

    // relative resource within the file
    uint16 actual_res = _resConvTable[(res * 2) + 1];

    // first we have to find the file via the _resConvTable
    // open the cluster file

    if (_resFiles[parent_res_file].entryTab == NULL) {
        Common::File *file = openCluFile(parent_res_file);
        readCluIndex(parent_res_file, file);
        delete file;
    }
    return _resFiles[parent_res_file].entryTab[actual_res * 2 + 1];
}
Пример #3
0
/**
 * Returns the address of a resource. Loads if not in memory. Retains a count.
 */
byte *ResourceManager::openResource(uint32 res, bool dump) {
    assert(res < _totalResFiles);


    // FIXME: In PSX edition, not all top menu icons are present (TOP menu is not used).
    // Though, at present state, the engine still ask for the resources.
    if (Sword2Engine::isPsx()) { // We need to "rewire" missing icons
        if (res == 342) res = 364; // Rewire RESTORE ICON to SAVE ICON
    }

    // Is the resource in memory already? If not, load it.

    if (!_resList[res].ptr) {
        // Fetch the correct file and read in the correct portion.
        uint16 cluFileNum = _resConvTable[res * 2]; // points to the number of the ascii filename

        assert(cluFileNum != 0xffff);

        // Relative resource within the file
        // First we have to find the file via the _resConvTable
        uint16 actual_res = _resConvTable[(res * 2) + 1];

        debug(5, "openResource %s res %d", _resFiles[cluFileNum].fileName, res);

        // If we're loading a cluster that's only available from one
        // of the CDs, remember which one so that we can play the
        // correct speech and music.

        if (Sword2Engine::isPsx()) // We have only one disk in PSX version
            setCD(CD1);
        else
            setCD(_resFiles[cluFileNum].cd);

        // Actually, as long as the file can be found we don't really
        // care which CD it's on. But if we can't find it, keep asking
        // for the CD until we do.

        Common::File *file = openCluFile(cluFileNum);

        if (_resFiles[cluFileNum].entryTab == NULL) {
            // we didn't read from this file before, get its index table
            readCluIndex(cluFileNum, file);
        }

        assert(_resFiles[cluFileNum].entryTab);

        uint32 pos = _resFiles[cluFileNum].entryTab[actual_res * 2 + 0];
        uint32 len = _resFiles[cluFileNum].entryTab[actual_res * 2 + 1];

        file->seek(pos, SEEK_SET);

        debug(6, "res len %d", len);

        // Ok, we know the length so try and allocate the memory.
        _resList[res].ptr = _vm->_memory->memAlloc(len, res);
        _resList[res].size = len;
        _resList[res].refCount = 0;

        file->read(_resList[res].ptr, len);

        debug(3, "Loaded resource '%s' (%d) from '%s' on CD %d (%d)", fetchName(_resList[res].ptr), res, _resFiles[cluFileNum].fileName, getCD(), _resFiles[cluFileNum].cd);

        if (dump) {
            char buf[256];
            const char *tag;

            switch (fetchType(_resList[res].ptr)) {
            case ANIMATION_FILE:
                tag = "anim";
                break;
            case SCREEN_FILE:
                tag = "layer";
                break;
            case GAME_OBJECT:
                tag = "object";
                break;
            case WALK_GRID_FILE:
                tag = "walkgrid";
                break;
            case GLOBAL_VAR_FILE:
                tag = "globals";
                break;
            case PARALLAX_FILE_null:
                tag = "parallax";	// Not used!
                break;
            case RUN_LIST:
                tag = "runlist";
                break;
            case TEXT_FILE:
                tag = "text";
                break;
            case SCREEN_MANAGER:
                tag = "screen";
                break;
            case MOUSE_FILE:
                tag = "mouse";
                break;
            case WAV_FILE:
                tag = "wav";
                break;
            case ICON_FILE:
                tag = "icon";
                break;
            case PALETTE_FILE:
                tag = "palette";
                break;
            default:
                tag = "unknown";
                break;
            }

            sprintf(buf, "dumps/%s-%d.dmp", tag, res);

            if (!Common::File::exists(buf)) {
                Common::DumpFile out;
                if (out.open(buf))
                    out.write(_resList[res].ptr, len);
            }
        }

        // close the cluster
        file->close();
        delete file;

        _usedMem += len;
        checkMemUsage();
    } else if (_resList[res].refCount == 0)
        removeFromCacheList(_resList + res);

    _resList[res].refCount++;

    return _resList[res].ptr;
}