Ejemplo n.º 1
0
dd_bool B_ParseKeyId(const char* desc, int* id)
{
    LOG_AS("B_ParseKeyId");

    // The possibilies: symbolic key name, or "codeNNN".
    if(!strncasecmp(desc, "code", 4) && strlen(desc) == 7)
    {
        if(desc[4] == 'x' || desc[4] == 'X')
        {
            // Hexadecimal.
            *id = strtoul(desc + 5, NULL, 16);
        }
        else
        {
            // Decimal.
            *id = strtoul(desc + 4, NULL, 10);
            if(*id <= 0 || *id > 255)
            {
                LOGDEV_INPUT_WARNING("Key code %i out of range") << *id;
                return false;
            }
        }
    }
    else
    {
        // Symbolic key name.
        *id = B_KeyForShortName(desc);
        if(!*id)
        {
            LOG_INPUT_WARNING("Unknown key \"%s\"") << desc;
            return false;
        }
    }
    return true;
}
Ejemplo n.º 2
0
uint8_t const* Zip::cacheLump(int lumpIdx)
{
    LOG_AS("Zip::cacheLump");

    if(!isValidIndex(lumpIdx)) throw NotFoundError("Zip::cacheLump", invalidIndexMessage(lumpIdx, lastIndex()));

    ZipFile& file = reinterpret_cast<ZipFile&>(lump(lumpIdx));
    LOG_TRACE("\"%s:%s\" (%u bytes%s)")
            << de::NativePath(composePath()).pretty()
            << de::NativePath(file.composePath()).pretty()
            << (unsigned long) file.info().size
            << (file.info().isCompressed()? ", compressed" : "");

    // Time to create the cache?
    if(!d->lumpCache)
    {
        d->lumpCache = new LumpCache(lumpCount());
    }

    uint8_t const* data = d->lumpCache->data(lumpIdx);
    if(data) return data;

    uint8_t* region = (uint8_t*) Z_Malloc(file.info().size, PU_APPSTATIC, 0);
    if(!region) throw Error("Zip::cacheLump", QString("Failed on allocation of %1 bytes for cache copy of lump #%2").arg(file.info().size).arg(lumpIdx));

    readLump(lumpIdx, region, false);
    d->lumpCache->insert(lumpIdx, region);

    return region;
}
Ejemplo n.º 3
0
void AbstractLink::socketDisconnected()
{
    LOG_AS("AbstractLink");

    if (d->status == Connecting)
    {
        if (d->startedTryingAt.since() < d->timeout)
        {
            // Let's try again a bit later.
            QTimer::singleShot(500, d->socket.get(), SLOT(reconnect()));
            return;
        }
        d->socket->setQuiet(false);
    }
    else
    {
        if (!d->peerAddress.isNull())
        {
            LOG_NET_NOTE("Disconnected from %s") << d->peerAddress;
        }
        else
        {
            LOG_NET_NOTE("Disconnected");
        }
    }

    d->status = Disconnected;

    emit disconnected();

    // Slots have now had an opportunity to observe the total
    // duration of the connection that has just ended.
    d->connectedAt = Time::invalidTime();
}
Ejemplo n.º 4
0
File1& Zip::lump(int lumpIdx)
{
    LOG_AS("Zip");
    if(!isValidIndex(lumpIdx)) throw NotFoundError("Zip::lump", invalidIndexMessage(lumpIdx, lastIndex()));
    d->buildLumpNodeLut();
    return *reinterpret_cast<ZipFile*>((*d->lumpNodeLut)[lumpIdx]->userPointer());
}
Ejemplo n.º 5
0
 QVariant parse()
 {
     LOG_AS("JSONParser");
     if(atEnd()) return QVariant();
     QChar c = peek();
     if(c == '{')
     {
         return parseObject();
     }
     else if(c == '[')
     {
         return parseArray();
     }
     else if(c == '\"')
     {
         return parseString();
     }
     else if(c == '-' || c.isDigit())
     {
         return parseNumber();
     }
     else
     {
         return parseKeyword();
     }
 }
Ejemplo n.º 6
0
void getAllOpenGLEntryPoints()
{
    static bool haveProcs = false;
    if(haveProcs) return;

#define GET_PROC(name) *((void**)&name) = wglGetProcAddress(#name); DENG2_ASSERT(name != 0)

    LOG_AS("getAllOpenGLEntryPoints");

    LOG_VERBOSE("GL_VERSION: ") << (char const *) glGetString(GL_VERSION);

    GET_PROC(glActiveTexture);
    GET_PROC(glAttachShader);
    GET_PROC(glBindAttribLocation);
    GET_PROC(glBindBuffer);
    GET_PROC(glBindFramebuffer);
    GET_PROC(glBindRenderbuffer);
    GET_PROC(glBlendEquation);
    GET_PROC(glBufferData);
    GET_PROC(glCheckFramebufferStatus);
    GET_PROC(glCompileShader);
    GET_PROC(glCreateProgram);
    GET_PROC(glCreateShader);
    GET_PROC(glDeleteBuffers);
    GET_PROC(glDeleteFramebuffers);
    GET_PROC(glDeleteProgram);
    GET_PROC(glDeleteRenderbuffers);
    GET_PROC(glDeleteShader);
    GET_PROC(glDetachShader);
    GET_PROC(glDisableVertexAttribArray);
    GET_PROC(glEnableVertexAttribArray);
    GET_PROC(glFramebufferRenderbuffer);
    GET_PROC(glFramebufferTexture2D);
    GET_PROC(glGenBuffers);
    GET_PROC(glGenFramebuffers);
    GET_PROC(glGenerateMipmap);
    GET_PROC(glGenRenderbuffers);
    GET_PROC(glGetAttribLocation);
    GET_PROC(glGetProgramInfoLog);
    GET_PROC(glGetProgramiv);
    GET_PROC(glGetShaderInfoLog);
    GET_PROC(glGetShaderiv);
    GET_PROC(glGetShaderSource);
    GET_PROC(glGetUniformLocation);
    GET_PROC(glIsBuffer);
    GET_PROC(glLinkProgram);
    GET_PROC(glRenderbufferStorage);
    GET_PROC(glShaderSource);
    GET_PROC(glUniform1f);
    GET_PROC(glUniform1i);
    GET_PROC(glUniform2f);
    GET_PROC(glUniform3f);
    GET_PROC(glUniform4f);
    GET_PROC(glUniformMatrix3fv);
    GET_PROC(glUniformMatrix4fv);
    GET_PROC(glUseProgram);
    GET_PROC(glVertexAttribPointer);

    haveProcs = true;
}
Ejemplo n.º 7
0
    void parseRawUri(String rawUri, QChar sep, resourceclassid_t defaultResourceClass)
    {
        LOG_AS("Uri::parseRawUri");

        clearCachedResolved();

        scheme = extractScheme(rawUri); // scheme removed
        if(sep != '/') rawUri.replace(sep, '/'); // force slashes as separator
        path = rawUri;
        strPath = path.toString(); // for legacy code

        if(!scheme.isEmpty())
        {
            if(defaultResourceClass == RC_NULL || App_FileSystem().knownScheme(scheme))
            {
                // Scheme is accepted as is.
                return;
            }
            LOG_RES_WARNING("Unknown scheme \"%s\" for path \"%s\", using default scheme instead") << scheme << strPath;
        }

        // Attempt to guess the scheme by interpreting the path?
        if(defaultResourceClass == RC_UNKNOWN)
        {
            defaultResourceClass = DD_GuessFileTypeFromFileName(strPath).defaultClass();
        }

        if(VALID_RESOURCECLASSID(defaultResourceClass))
        {
            FS1::Scheme &fsScheme = App_FileSystem().scheme(ResourceClass::classForId(defaultResourceClass).defaultScheme());
            scheme = fsScheme.name();
        }
    }
Ejemplo n.º 8
0
bool Zip::uncompressRaw(uint8_t* in, size_t inSize, uint8_t* out, size_t outSize)
{
    LOG_AS("Zip::uncompressRaw");
    z_stream stream;
    int result;

    memset(&stream, 0, sizeof(stream));
    stream.next_in = (Bytef*) in;
    stream.avail_in = (uInt) inSize;
    stream.zalloc = Z_NULL;
    stream.zfree = Z_NULL;
    stream.next_out = (Bytef*) out;
    stream.avail_out = (uInt) outSize;

    if(inflateInit2(&stream, -MAX_WBITS) != Z_OK)
        return false;

    // Do the inflation in one call.
    result = inflate(&stream, Z_FINISH);

    if(stream.total_out != outSize)
    {
        inflateEnd(&stream);
        LOG_WARNING("Failure due to %s (result code %i).")
                << (result == Z_DATA_ERROR ? "corrupt data" : "zlib error")
                << result;
        return false;
    }

    // We're done.
    inflateEnd(&stream);
    return true;
}
Ejemplo n.º 9
0
res::AnimGroup &AnimGroups::newAnimGroup(dint flags)
{
    LOG_AS("AnimGroups");
    dint const uniqueId = d->animGroups.count() + 1; // 1-based.
    // Allocating one by one is inefficient but it doesn't really matter.
    d->animGroups.append(new res::AnimGroup(uniqueId, flags));
    return *d->animGroups.last();
}
Ejemplo n.º 10
0
void CanvasWindow::hideEvent(QHideEvent *ev)
{
    LOG_AS("CanvasWindow");

    QMainWindow::hideEvent(ev);

    LOG_DEBUG("Hide event (hidden:%b)") << isHidden();
}
Ejemplo n.º 11
0
size_t Zip::readLump(int lumpIdx, uint8_t* buffer, size_t startOffset,
                     size_t length, bool tryCache)
{
    LOG_AS("Zip::readLump");
    ZipFile const& file = reinterpret_cast<ZipFile&>(lump(lumpIdx));

    LOG_TRACE("\"%s:%s\" (%u bytes%s) [%u +%u]")
            << de::NativePath(composePath()).pretty()
            << de::NativePath(file.composePath()).pretty()
            << (unsigned long) file.size()
            << (file.isCompressed()? ", compressed" : "")
            << startOffset
            << length;

    // Try to avoid a file system read by checking for a cached copy.
    if(tryCache)
    {
        uint8_t const* data = d->lumpCache? d->lumpCache->data(lumpIdx) : 0;
        LOG_TRACE("Cache %s on #%i") << (data? "hit" : "miss") << lumpIdx;
        if(data)
        {
            size_t readBytes = MIN_OF(file.size(), length);
            memcpy(buffer, data + startOffset, readBytes);
            return readBytes;
        }
    }

    size_t readBytes;
    if(!startOffset && length == file.size())
    {
        // Read it straight to the caller's data buffer.
        readBytes = d->bufferLump(file, buffer);
    }
    else
    {
        // Allocate a temporary buffer and read the whole lump into it(!).
        uint8_t* lumpData = (uint8_t*) M_Malloc(file.size());
        if(!lumpData) throw Error("Zip::readLumpSection", QString("Failed on allocation of %1 bytes for work buffer").arg(file.size()));

        if(d->bufferLump(file, lumpData))
        {
            readBytes = MIN_OF(file.size(), length);
            memcpy(buffer, lumpData + startOffset, readBytes);
        }
        else
        {
            readBytes = 0;
        }
        M_Free(lumpData);
    }

    /// @todo Do not check the read length here.
    if(readBytes < MIN_OF(file.size(), length))
        throw Error("Zip::readLumpSection", QString("Only read %1 of %2 bytes of lump #%3").arg(readBytes).arg(length).arg(lumpIdx));

    return readBytes;
}
Ejemplo n.º 12
0
res::AnimGroup *AnimGroups::animGroup(dint uniqueId)
{
    LOG_AS("AnimGroups::animGroup");
    if (uniqueId > 0 && uniqueId <= d->animGroups.count())
    {
        return d->animGroups.at(uniqueId - 1);
    }
    LOGDEV_RES_WARNING("Invalid group #%i, returning NULL") << uniqueId;
    return nullptr;
}
Ejemplo n.º 13
0
void AbstractLink::socketConnected()
{
    LOG_AS("AbstractLink");
    LOG_NET_VERBOSE("Successfully connected to server %s") << d->socket->peerAddress();

    initiateCommunications();

    d->status = Connected;
    d->connectedAt = Time();
    d->peerAddress = d->socket->peerAddress();

    emit connected();
}
Ejemplo n.º 14
0
static void Mouse_Init(void)
{
    if(CommandLine_Check("-nomouse") || novideo)
        return;

    LOG_AS("Mouse_Init");

    DENG_ASSERT(iMouse);
    iMouse->init();

    // Init was successful.
    useMouse = true;
}
Ejemplo n.º 15
0
    String resolve() const
    {
        LOG_AS("Uri::resolve");

        String result;

        // Keep scanning the path for embedded expressions.
        QStringRef expression;
        int expEnd = 0, expBegin;
        while((expBegin = strPath.indexOf('$', expEnd)) >= 0)
        {
            // Is the next char the start-of-expression character?
            if(strPath.at(expBegin + 1) == '(')
            {
                // Copy everything up to the '$'.
                result += strPath.mid(expEnd, expBegin - expEnd);

                // Skip over the '$'.
                ++expBegin;

                // Find the end-of-expression character.
                expEnd = strPath.indexOf(')', expBegin);
                if(expEnd < 0)
                {
                    LOG_RES_WARNING("Ignoring expression \"" + strPath + "\": "
                                    "missing a closing ')'");
                    expEnd = strPath.length();
                }

                // Skip over the '('.
                ++expBegin;

                // The range of the expression substring is now known.
                expression = strPath.midRef(expBegin, expEnd - expBegin);

                result += parseExpression(expression);
            }
            else
            {
                // No - copy the '$' and continue.
                result += '$';
            }

            ++expEnd;
        }

        // Copy anything remaining.
        result += strPath.mid(expEnd);

        return result;
    }
Ejemplo n.º 16
0
void Task::run()
{
    try
    {
        runTask();
    }
    catch (Error const &er)
    {
        LOG_AS("Task");
        LOG_WARNING("Aborted due to exception: ") << er.asText();
    }

    // Cleanup.
    if (_pool) _pool->taskFinishedRunning(*this);
    Log::disposeThreadLog();
}
Ejemplo n.º 17
0
static void Mouse_Win32_Trap(dd_bool enabled)
{
    LOG_AS("Mouse_Win32");
    DENG_ASSERT(didMouse);

    mouseTrapped = (enabled != 0);
    if(enabled)
    {
        LOG_INPUT_VERBOSE("Acquiring the mouse");
        didMouse->Acquire();
    }
    else
    {
        LOG_INPUT_VERBOSE("Unacquiring the mouse");
        didMouse->Unacquire();
    }
}
Ejemplo n.º 18
0
void Loop::nextLoopIteration()
{
    try
    {
        if (d->running)
        {
            DENG2_FOR_AUDIENCE2(Iteration, i) i->loopIteration();
        }
    }
    catch (Error const &er)
    {
        LOG_AS("Loop");

        // This is called from Qt's event loop, we mustn't let exceptions
        // out of here uncaught.
        App::app().handleUncaughtException("Uncaught exception during loop iteration:\n" + er.asText());
    }
}
Ejemplo n.º 19
0
    /**
     * Given a package identifier, pick one of the available versions of the package
     * based on predefined criteria.
     *
     * @param packageId  Package identifier.
     *
     * @return Selected package, or @c NULL if a version could not be selected.
     */
    File const *selectPackage(String const &packageId) const
    {
        LOG_AS("selectPackage");

        FS::FoundFiles found;
        if(!findAllVariants(packageId, found))
        {
            // None found.
            return 0;
        }

        // Each must have a version specified.
        DENG2_FOR_EACH_CONST(FS::FoundFiles, i, found)
        {
            File *pkg = *i;
            Package::parseMetadata(*pkg);
            Package::validateMetadata(pkg->info().subrecord("package"));
        }
Ejemplo n.º 20
0
FileHandle* FileHandleBuilder::fromLump(File1& lump, bool dontBuffer)
{
    LOG_AS("FileHandle::fromLump");

    de::FileHandle* hndl = new de::FileHandle();
    // Init and load in the lump data.
    hndl->d->file = &lump;
    hndl->d->flags.open = true;
    if(!dontBuffer)
    {
        hndl->d->size = lump.size();
        hndl->d->pos = hndl->d->data = (uint8_t*) M_Malloc(hndl->d->size);
        if(!hndl->d->data) Con_Error("FileHandleBuilder::fromFileLump: Failed on allocation of %lu bytes for data buffer.", (unsigned long) hndl->d->size);

        LOG_DEV_TRACE("[%p] Buffering \"%s:%s\"...",
            dintptr(hndl) << NativePath(lump.container().composePath()).pretty() << NativePath(lump.composePath()).pretty());

        lump.read((uint8_t*)hndl->d->data, 0, lump.size());
    }
    return hndl;
}
Ejemplo n.º 21
0
void Zip::unlockLump(int lumpIdx)
{
    LOG_AS("Zip::unlockLump");
    LOG_TRACE("\"%s:%s\"") << de::NativePath(composePath()).pretty() << lump(lumpIdx).composePath();

    if(isValidIndex(lumpIdx))
    {
        if(d->lumpCache)
        {
            d->lumpCache->unlock(lumpIdx);
        }
        else
        {
            LOG_DEBUG("LumpCache not in use, ignoring.");
        }
    }
    else
    {
        QString msg = invalidIndexMessage(lumpIdx, lastIndex());
        LOG_DEBUG(msg + ", ignoring.");
    }
}
Ejemplo n.º 22
0
void Zip::clearCachedLump(int lumpIdx, bool* retCleared)
{
    LOG_AS("Zip::clearCachedLump");

    if(retCleared) *retCleared = false;

    if(isValidIndex(lumpIdx))
    {
        if(d->lumpCache)
        {
            d->lumpCache->remove(lumpIdx, retCleared);
        }
        else
        {
            LOG_DEBUG("LumpCache not in use, ignoring.");
        }
    }
    else
    {
        QString msg = invalidIndexMessage(lumpIdx, lastIndex());
        LOG_DEBUG(msg + ", ignoring.");
    }
}
Ejemplo n.º 23
0
void *WAV_Load(char const *filename, int *bits, int *rate, int *samples)
{
    try
    {
        // Relative paths are relative to the native working directory.
        de::String path = (de::NativePath::workPath() / de::NativePath(filename).expand()).withSeparators('/');
        QScopedPointer<de::FileHandle> hndl(&App_FileSystem().openFile(path, "rb"));

        // Read in the whole thing.
        size_t size = hndl->length();

        LOG_AS("WAV_Load");
        LOGDEV_RES_XVERBOSE("Loading from \"%s\" (size %i, fpos %i)")
                << de::NativePath(hndl->file().composePath()).pretty()
                << size
                << hndl->tell();

        uint8_t *data = (uint8_t *) M_Malloc(size);

        hndl->read(data, size);
        App_FileSystem().releaseFile(hndl->file());

        // Parse the RIFF data.
        void *sampledata = WAV_MemoryLoad((byte const *) data, size, bits, rate, samples);
        if(!sampledata)
        {
            LOG_RES_WARNING("Failed to load \"%s\"") << filename;
        }

        M_Free(data);
        return sampledata;
    }
    catch(de::FS1::NotFoundError const &)
    {} // Ignore.
    return 0;
}
Ejemplo n.º 24
0
uint8_t* Zip::uncompress(uint8_t* in, size_t inSize, size_t* outSize)
{
#define INF_CHUNK_SIZE 4096 // Uncompress in 4KB chunks.

    LOG_AS("Zip::uncompress");

    z_stream stream;
    uint8_t chunk[INF_CHUNK_SIZE];
    size_t allocSize = INF_CHUNK_SIZE;
    uint8_t* output = (uint8_t*) M_Malloc(allocSize); // some initial space
    int result;
    int have;

    DENG2_ASSERT(outSize);
    *outSize = 0;

    memset(&stream, 0, sizeof(stream));
    stream.next_in = (Bytef*) in;
    stream.avail_in = (uInt) inSize;

    result = inflateInit(&stream);
    if(result != Z_OK)
    {
        M_Free(output);
        return 0;
    }

    // Uncompress until all the input data has been exhausted.
    do
    {
        stream.next_out = chunk;
        stream.avail_out = INF_CHUNK_SIZE;
        result = inflate(&stream, Z_FINISH);
        if(result == Z_STREAM_ERROR)
        {
            M_Free(output);
            *outSize = 0;
            return 0;
        }
        have = INF_CHUNK_SIZE - stream.avail_out;
        if(have)
        {
            // Need more memory?
            if(*outSize + have > allocSize)
            {
                // Need more memory.
                allocSize *= 2;
                output = (uint8_t*) M_Realloc(output, allocSize);
            }
            // Append.
            memcpy(output + *outSize, chunk, have);
            *outSize += have;
        }
    } while(!stream.avail_out); // output chunk full, more data may follow

    // We should now be at the end.
    DENG2_ASSERT(result == Z_STREAM_END);

    inflateEnd(&stream);
    return output;

#undef INF_CHUNK_SIZE
}
Ejemplo n.º 25
0
size_t Zip::readLump(int lumpIdx, uint8_t* buffer, bool tryCache)
{
    LOG_AS("Zip::readLump");
    if(!isValidIndex(lumpIdx)) return 0;
    return readLump(lumpIdx, buffer, 0, lump(lumpIdx).size(), tryCache);
}
Ejemplo n.º 26
0
void FontBank::addFromInfo(File const &file)
{
    LOG_AS("FontBank");
    parse(file);
    addFromInfoBlocks("font");
}
Ejemplo n.º 27
0
void Config::read()
{
    if (d->configPath.isEmpty()) return;

    LOG_AS("Config::read");

    // Current version.
    Version verInfo = Version::currentBuild();
    QScopedPointer<ArrayValue> version(new ArrayValue);
    *version << NumberValue(verInfo.major)
             << NumberValue(verInfo.minor)
             << NumberValue(verInfo.patch)
             << NumberValue(verInfo.build);

    File &scriptFile = App::rootFolder().locate<File>(d->configPath);
    bool shouldRunScript = App::commandLine().has("-reconfig");

    try
    {
        // If we already have a saved copy of the config, read it.
        d->refuge.read();

        LOG_DEBUG("Found serialized Config:\n") << objectNamespace();

        // If the saved config is from a different version, rerun the script.
        if (objectNamespace().has("__version__"))
        {
            Value const &oldVersion = objectNamespace()["__version__"].value();
            d->setOldVersion(oldVersion);
            if (oldVersion.compare(*version))
            {
                // Version mismatch: store the old version in a separate variable.
                d->config.globals().add(new Variable("__oldversion__", oldVersion.duplicate(),
                                                 Variable::AllowArray | Variable::ReadOnly));
                shouldRunScript = true;
            }
            else
            {
                // Versions match.
                LOG_MSG("") << d->refuge.path() << " matches version " << version->asText();
            }
        }
        else
        {
            // Don't know what version this is, run script to be sure.
            shouldRunScript = true;
        }

        // Also check the timestamp of written config vs. the config script.
        // If script is newer, it should be rerun.
        if (scriptFile.status().modifiedAt > d->refuge.lastWrittenAt())
        {
            LOG_MSG("%s is newer than %s, rerunning the script")
                    << d->configPath << d->refuge.path();
            shouldRunScript = true;
        }

        // Check the container, too.
        if (!shouldRunScript &&
            Package::containerOfFileModifiedAt(scriptFile) > d->refuge.lastWrittenAt())
        {
            LOG_MSG("Package '%s' is newer than %s, rerunning the script")
                    << Package::identifierForContainerOfFile(scriptFile)
                    << d->refuge.path();
            shouldRunScript = true;
        }
    }
    catch (Archive::NotFoundError const &)
    {
        // It is missing from persist.pack if the config hasn't been written yet.
        shouldRunScript = true;
    }
    catch (IByteArray::OffsetError const &)
    {
        // Empty or missing serialization?
        shouldRunScript = true;
    }
    catch (Error const &error)
    {
        LOG_WARNING(error.what());

        // Something is wrong, maybe rerunning will fix it.
        shouldRunScript = true;
    }

    // The version of libcore is automatically included in the namespace.
    d->config.globals().add(new Variable("__version__", version.take(),
                                         Variable::AllowArray | Variable::ReadOnly));

    if (shouldRunScript)
    {
        // Read the main configuration.
        Script script(scriptFile);
        d->config.run(script);
        d->config.execute();
    }
}
Ejemplo n.º 28
0
void* WAV_MemoryLoad(const byte* data, size_t datalength, int* bits, int* rate, int* samples)
{
    const byte* end = data + datalength;
    byte* sampledata = NULL;
    chunk_hdr_t riff_chunk;
    wav_format_t wave_format;

    LOG_AS("WAV_MemoryLoad");

    if(!WAV_CheckFormat((const char*)data))
    {
        LOG_RES_WARNING("Not WAV format data");
        return NULL;
    }

    // Read the RIFF header.
    data += sizeof(riff_hdr_t);
    data += 4; // "WAVE" already verified above

#ifdef _DEBUG
    assert(sizeof(wave_format) == 16);
    assert(sizeof(riff_chunk) == 8);
#endif

    // Start readin' the chunks, baby!
    while(data < end)
    {
        // Read next chunk header.
        WReadAndAdvance(data, &riff_chunk, sizeof(riff_chunk));

        // Correct endianness.
        riff_chunk.len = DD_ULONG(riff_chunk.len);

        // What have we got here?
        if(!strncmp(riff_chunk.id, "fmt ", 4))
        {
            // Read format chunk.
            WReadAndAdvance(data, &wave_format, sizeof(wave_format));

            // Correct endianness.
            wave_format.wFormatTag       = DD_USHORT(wave_format.wFormatTag      );
            wave_format.wChannels        = DD_USHORT(wave_format.wChannels       );
            wave_format.dwSamplesPerSec  = DD_ULONG (wave_format.dwSamplesPerSec );
            wave_format.dwAvgBytesPerSec = DD_ULONG (wave_format.dwAvgBytesPerSec);
            wave_format.wBlockAlign      = DD_USHORT(wave_format.wBlockAlign     );
            wave_format.wBitsPerSample   = DD_USHORT(wave_format.wBitsPerSample  );

            assert(wave_format.wFormatTag == WAVE_FORMAT_PCM); // linear PCM

            // Check that it's a format we know how to read.
            if(wave_format.wFormatTag != WAVE_FORMAT_PCM)
            {
                LOG_RES_WARNING("Unsupported format (%i)") << wave_format.wFormatTag;
                return NULL;
            }
            if(wave_format.wChannels != 1)
            {
                LOG_RES_WARNING("Too many channels (only mono supported)");
                return NULL;
            }
            // Read the extra format information.
            //WReadAndAdvance(&data, &wave_format2, sizeof(*wave_format2));
            /*if(wave_format->wBitsPerSample == 0)
               {
               // We'll have to guess...
               *bits = 8*wave_format->dwAvgBytesPerSec/
               wave_format->dwSamplesPerSec;
               }
               else
               { */
            if(wave_format.wBitsPerSample != 8 &&
               wave_format.wBitsPerSample != 16)
            {
                LOG_RES_WARNING("Must have 8 or 16 bits per sample");
                return NULL;
            }
            // Now we know some information about the sample.
            *bits = wave_format.wBitsPerSample;
            *rate = wave_format.dwSamplesPerSec;
        }
        else if(!strncmp(riff_chunk.id, "data", 4))
        {
            if(!wave_format.wFormatTag)
            {
                LOG_RES_WARNING("Malformed WAV data");
                return NULL;
            }
            // Read data chunk.
            *samples = riff_chunk.len / wave_format.wBlockAlign;
            // Allocate the sample buffer.
            sampledata = (byte *) Z_Malloc(riff_chunk.len, PU_APPSTATIC, 0);
            memcpy(sampledata, data, riff_chunk.len);
#ifdef __BIG_ENDIAN__
            // Correct endianness.
            /*if(wave_format->wBitsPerSample == 16)
            {
                ushort* sample = sampledata;
                for(; sample < ((short*)sampledata) + *samples; ++sample)
                    *sample = DD_USHORT(*sample);
            }*/
#endif
            // We're satisfied with this! Let's get out of here.
            break;
        }
        else
        {
            // Unknown chunk, just skip it.
            data += riff_chunk.len;
        }
    }

    return sampledata;
}
Ejemplo n.º 29
0
uint8_t* Zip::compressAtLevel(uint8_t* in, size_t inSize, size_t* outSize, int level)
{
#define CHUNK_SIZE 32768

    LOG_AS("Zip::compressAtLevel");

    z_stream stream;
    uint8_t chunk[CHUNK_SIZE];
    size_t allocSize = CHUNK_SIZE;
    uint8_t* output = (uint8_t*) M_Malloc(allocSize); // some initial space
    int result;
    int have;

    DENG2_ASSERT(outSize);
    *outSize = 0;

    memset(&stream, 0, sizeof(stream));
    stream.next_in = (Bytef*) in;
    stream.avail_in = (uInt) inSize;
    stream.zalloc = Z_NULL;
    stream.zfree = Z_NULL;
    stream.opaque = Z_NULL;

    if(level < Z_NO_COMPRESSION)
    {
        level = Z_NO_COMPRESSION;
    }
    if(level > Z_BEST_COMPRESSION)
    {
        level = Z_BEST_COMPRESSION;
    }
    result = deflateInit(&stream, level);
    if(result != Z_OK)
    {
        M_Free(output);
        return 0;
    }

    // Compress until all the data has been exhausted.
    do
    {
        stream.next_out = chunk;
        stream.avail_out = CHUNK_SIZE;
        result = deflate(&stream, Z_FINISH);
        if(result == Z_STREAM_ERROR)
        {
            M_Free(output);
            *outSize = 0;
            return 0;
        }
        have = CHUNK_SIZE - stream.avail_out;
        if(have)
        {
            // Need more memory?
            if(*outSize + have > allocSize)
            {
                // Need more memory.
                allocSize *= 2;
                output = (uint8_t*) M_Realloc(output, allocSize);
            }
            // Append.
            memcpy(output + *outSize, chunk, have);
            *outSize += have;
        }
    } while(!stream.avail_out); // output chunk full, more data may follow

    DENG2_ASSERT(result == Z_STREAM_END);
    DENG2_ASSERT(stream.total_out == *outSize);

    deflateEnd(&stream);
    return output;

#undef CHUNK_SIZE
}
Ejemplo n.º 30
0
    void init()
    {
        LOG_AS("GLInfo");

        if (inited) return;

        if (!initializeOpenGLFunctions())
        {
            throw InitError("GLInfo::init", "Failed to initialize OpenGL");
        }

        // Extensions.
        ext.ARB_draw_instanced             = query("GL_ARB_draw_instanced");
        ext.ARB_instanced_arrays           = query("GL_ARB_instanced_arrays");
        ext.ARB_texture_env_combine        = query("GL_ARB_texture_env_combine") || query("GL_EXT_texture_env_combine");
        ext.ARB_texture_non_power_of_two   = query("GL_ARB_texture_non_power_of_two");

        ext.EXT_blend_subtract             = query("GL_EXT_blend_subtract");
        ext.EXT_framebuffer_blit           = query("GL_EXT_framebuffer_blit");
        ext.EXT_framebuffer_multisample    = query("GL_EXT_framebuffer_multisample");
        ext.EXT_framebuffer_object         = query("GL_EXT_framebuffer_object");
        ext.EXT_packed_depth_stencil       = query("GL_EXT_packed_depth_stencil");
        ext.EXT_texture_compression_s3tc   = query("GL_EXT_texture_compression_s3tc");
        ext.EXT_texture_filter_anisotropic = query("GL_EXT_texture_filter_anisotropic");
        ext.EXT_timer_query                = query("GL_EXT_timer_query");

        ext.ATI_texture_env_combine3       = query("GL_ATI_texture_env_combine3");
        ext.NV_framebuffer_multisample_coverage
                                           = query("GL_NV_framebuffer_multisample_coverage");
        ext.NV_texture_env_combine4        = query("GL_NV_texture_env_combine4");
        ext.SGIS_generate_mipmap           = query("GL_SGIS_generate_mipmap");

#ifdef WIN32
        ext.Windows_ARB_multisample        = query("WGL_ARB_multisample");
        ext.Windows_EXT_swap_control       = query("WGL_EXT_swap_control");

        if (ext.Windows_EXT_swap_control)
        {
            wglSwapIntervalEXT = de::function_cast<decltype(wglSwapIntervalEXT)>
                (QOpenGLContext::currentContext()->getProcAddress("wglSwapIntervalEXT"));
        }
#endif

#ifdef DENG_X11
        ext.X11_EXT_swap_control           = query("GLX_EXT_swap_control");
        ext.X11_SGI_swap_control           = query("GLX_SGI_swap_control");
        ext.X11_MESA_swap_control          = query("GLX_MESA_swap_control");

        if (ext.X11_EXT_swap_control)
        {
            glXSwapIntervalEXT = de::function_cast<decltype(glXSwapIntervalEXT)>
                    (glXGetProcAddress(reinterpret_cast<GLubyte const *>("glXSwapIntervalEXT")));
        }
        if (ext.X11_SGI_swap_control)
        {
            glXSwapIntervalSGI = de::function_cast<decltype(glXSwapIntervalSGI)>
                    (glXGetProcAddress(reinterpret_cast<GLubyte const *>("glXSwapIntervalSGI")));
        }
        if (ext.X11_MESA_swap_control)
        {
            glXSwapIntervalMESA = de::function_cast<decltype(glXSwapIntervalMESA)>
                    (glXGetProcAddress(reinterpret_cast<GLubyte const *>("glXSwapIntervalMESA")));
        }
#endif

        if (ext.ARB_draw_instanced)
        {
            ARB_draw_instanced.reset(new QOpenGLExtension_ARB_draw_instanced);
            ARB_draw_instanced->initializeOpenGLFunctions();
        }
        if (ext.ARB_instanced_arrays)
        {
            ARB_instanced_arrays.reset(new QOpenGLExtension_ARB_instanced_arrays);
            ARB_instanced_arrays->initializeOpenGLFunctions();
        }
        if (ext.EXT_framebuffer_blit)
        {
            EXT_framebuffer_blit.reset(new QOpenGLExtension_EXT_framebuffer_blit);
            EXT_framebuffer_blit->initializeOpenGLFunctions();
        }
        if (ext.EXT_framebuffer_multisample)
        {
            EXT_framebuffer_multisample.reset(new QOpenGLExtension_EXT_framebuffer_multisample);
            EXT_framebuffer_multisample->initializeOpenGLFunctions();
        }
        if (ext.EXT_framebuffer_object)
        {
            EXT_framebuffer_object.reset(new QOpenGLExtension_EXT_framebuffer_object);
            EXT_framebuffer_object->initializeOpenGLFunctions();
        }
        if (ext.NV_framebuffer_multisample_coverage)
        {
            NV_framebuffer_multisample_coverage.reset(new QOpenGLExtension_NV_framebuffer_multisample_coverage);
            NV_framebuffer_multisample_coverage->initializeOpenGLFunctions();
        }

        // Limits.
        glGetIntegerv(GL_MAX_TEXTURE_SIZE,  (GLint *) &lim.maxTexSize);
        glGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint *) &lim.maxTexUnits);

        if (ext.EXT_texture_filter_anisotropic)
        {
            glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, (GLint *) &lim.maxTexFilterAniso);
        }

        // Set a custom maximum size?
        if (CommandLine_CheckWith("-maxtex", 1))
        {
            lim.maxTexSize = min(ceilPow2(String(CommandLine_Next()).toInt()),
                                 lim.maxTexSize);

            LOG_GL_NOTE("Using requested maximum texture size of %i x %i") << lim.maxTexSize << lim.maxTexSize;
        }

        // Check default OpenGL format attributes.
        QOpenGLContext const *ctx = QOpenGLContext::currentContext();
        QSurfaceFormat form = ctx->format();

        LOGDEV_GL_MSG("Initial OpenGL format:");
        LOGDEV_GL_MSG(" - version: %i.%i") << form.majorVersion() << form.minorVersion();
        LOGDEV_GL_MSG(" - profile: %s") << (form.profile() == QSurfaceFormat::CompatibilityProfile? "Compatibility" : "Core");
        LOGDEV_GL_MSG(" - color: R%i G%i B%i A%i bits") << form.redBufferSize() << form.greenBufferSize() << form.blueBufferSize() << form.alphaBufferSize();
        LOGDEV_GL_MSG(" - depth: %i bits") << form.depthBufferSize();
        LOGDEV_GL_MSG(" - stencil: %i bits") << form.stencilBufferSize();
        LOGDEV_GL_MSG(" - samples: %i") << form.samples();
        LOGDEV_GL_MSG(" - swap behavior: %i") << form.swapBehavior();

        inited = true;
    }