DBool sfShader_loadFromStream(sfShader* shader, DStream* vertexShaderStream, DStream* fragmentShaderStream) { bool success = false; if (vertexShaderStream || fragmentShaderStream) { if (!vertexShaderStream) { // fragment shader only sfmlStream stream(fragmentShaderStream); success = shader->This.loadFromStream(stream, sf::Shader::Fragment); } else if (!fragmentShaderStream) { // vertex shader only sfmlStream stream(vertexShaderStream); success = shader->This.loadFromStream(stream, sf::Shader::Vertex); } else { // vertex + fragment shaders sfmlStream vertexStream(vertexShaderStream); sfmlStream fragmentStream(fragmentShaderStream); success = shader->This.loadFromStream(vertexStream, fragmentStream); } } return success?DTrue:DFalse; }
sfShader* sfShader_createFromStream(sfInputStream* vertexShaderStream, sfInputStream* geometryShaderStream, sfInputStream* fragmentShaderStream) { bool success = false; sfShader* shader = new sfShader; if (vertexShaderStream || geometryShaderStream || fragmentShaderStream) { if (!geometryShaderStream) { if (!vertexShaderStream) { // fragment shader only CallbackStream stream(fragmentShaderStream); success = shader->This.loadFromStream(stream, sf::Shader::Fragment); } else if (!fragmentShaderStream) { // vertex shader only CallbackStream stream(vertexShaderStream); success = shader->This.loadFromStream(stream, sf::Shader::Vertex); } else { // vertex + fragment shaders CallbackStream vertexStream(vertexShaderStream); CallbackStream fragmentStream(fragmentShaderStream); success = shader->This.loadFromStream(vertexStream, fragmentStream); } } else { // vertex + geometry + fragment shaders CallbackStream vertexStream(vertexShaderStream); CallbackStream geometryStream(geometryShaderStream); CallbackStream fragmentStream(fragmentShaderStream); success = shader->This.loadFromStream(vertexStream, geometryStream, fragmentStream); } } if (!success) { delete shader; shader = NULL; } return shader; }
const Graphics::Surface *RobotDecoder::decodeNextFrame() { // Read frame image header (24 bytes) _fileStream->skip(3); byte frameScale = _fileStream->readByte(); uint16 frameWidth = _fileStream->readUint16(); uint16 frameHeight = _fileStream->readUint16(); _fileStream->skip(4); // unknown, almost always 0 uint16 frameX = _fileStream->readUint16(); uint16 frameY = _fileStream->readUint16(); // TODO: In v4 robot files, frameX and frameY have a different meaning. // Set them both to 0 for v4 for now, so that robots in PQ:SWAT show up // correctly. if (_header.version == 4) frameX = frameY = 0; uint16 compressedSize = _fileStream->readUint16(); uint16 frameFragments = _fileStream->readUint16(); _fileStream->skip(4); // unknown uint32 decompressedSize = frameWidth * frameHeight * frameScale / 100; // FIXME: A frame's height + position can go off limits... why? With the // following, we cut the contents to fit the frame uint16 scaledHeight = CLIP<uint16>(decompressedSize / frameWidth, 0, _height - frameY); // FIXME: Same goes for the frame's width + position. In this case, we // modify the position to fit the contents on screen. if (frameWidth + frameX > _width) frameX = _width - frameWidth; assert (frameWidth + frameX <= _width && scaledHeight + frameY <= _height); DecompressorLZS lzs; byte *decompressedFrame = new byte[decompressedSize]; byte *outPtr = decompressedFrame; if (_header.version == 4) { // v4 has just the one fragment, it seems, and ignores the fragment count Common::SeekableSubReadStream fragmentStream(_fileStream, _fileStream->pos(), _fileStream->pos() + compressedSize); lzs.unpack(&fragmentStream, outPtr, compressedSize, decompressedSize); } else { for (uint16 i = 0; i < frameFragments; ++i) { uint32 compressedFragmentSize = _fileStream->readUint32(); uint32 decompressedFragmentSize = _fileStream->readUint32(); uint16 compressionType = _fileStream->readUint16(); if (compressionType == 0) { Common::SeekableSubReadStream fragmentStream(_fileStream, _fileStream->pos(), _fileStream->pos() + compressedFragmentSize); lzs.unpack(&fragmentStream, outPtr, compressedFragmentSize, decompressedFragmentSize); } else if (compressionType == 2) { // untested _fileStream->read(outPtr, compressedFragmentSize); } else { error("Unknown frame compression found: %d", compressionType); } outPtr += decompressedFragmentSize; } } // Copy over the decompressed frame byte *inFrame = decompressedFrame; byte *outFrame = (byte *)_surface->pixels; // Black out the surface memset(outFrame, 0, _width * _height); // Move to the correct y coordinate outFrame += _width * frameY; for (uint16 y = 0; y < scaledHeight; y++) { memcpy(outFrame + frameX, inFrame, frameWidth); inFrame += frameWidth; outFrame += _width; } delete[] decompressedFrame; // +1 because we start with frame number -1 uint32 audioChunkSize = _frameTotalSize[_curFrame + 1] - (24 + compressedSize); // TODO: The audio chunk size below is usually correct, but there are some // exceptions (e.g. robot 4902 in Phantasmagoria, towards its end) #if 0 // Read frame audio header (14 bytes) _fileStream->skip(2); // buffer position _fileStream->skip(2); // unknown (usually 1) _fileStream->skip(2); /*uint16 audioChunkSize = _fileStream->readUint16() + 8;*/ _fileStream->skip(2); #endif // Queue the next audio frame // FIXME: For some reason, there are audio hiccups/gaps if (_header.hasSound) { _fileStream->skip(8); // header _audioStream->queueBuffer(g_sci->_audio->getDecodedRobotAudioFrame(_fileStream, audioChunkSize - 8), (audioChunkSize - 8) * 2, DisposeAfterUse::NO, Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN); } else { _fileStream->skip(audioChunkSize); } if (_curFrame == -1) _startTime = g_system->getMillis(); _curFrame++; return _surface; }