[Scummvm-cvs-logs] SF.net SVN: scummvm:[53295] scummvm/trunk/engines/sword25

sev at users.sourceforge.net sev at users.sourceforge.net
Wed Oct 13 01:20:33 CEST 2010


Revision: 53295
          http://scummvm.svn.sourceforge.net/scummvm/?rev=53295&view=rev
Author:   sev
Date:     2010-10-12 23:20:33 +0000 (Tue, 12 Oct 2010)

Log Message:
-----------
SWORD25: Commit of in-progress MoviePlayer code

Frames aren't being corrected decoded yet; still trying to locate the cause

Modified Paths:
--------------
    scummvm/trunk/engines/sword25/fmv/movieplayer.cpp
    scummvm/trunk/engines/sword25/fmv/movieplayer.h
    scummvm/trunk/engines/sword25/fmv/oggtheora/audiobuffer.cpp
    scummvm/trunk/engines/sword25/fmv/oggtheora/audiobuffer.h
    scummvm/trunk/engines/sword25/fmv/oggtheora/moviefile.cpp
    scummvm/trunk/engines/sword25/fmv/oggtheora/moviefile.h
    scummvm/trunk/engines/sword25/fmv/oggtheora/oggstate.cpp
    scummvm/trunk/engines/sword25/fmv/oggtheora/oggstate.h
    scummvm/trunk/engines/sword25/fmv/oggtheora/oggstreamstate.cpp
    scummvm/trunk/engines/sword25/fmv/oggtheora/oggstreamstate.h
    scummvm/trunk/engines/sword25/fmv/oggtheora/theorastate.cpp
    scummvm/trunk/engines/sword25/fmv/oggtheora/theorastate.h
    scummvm/trunk/engines/sword25/fmv/oggtheora/vorbisstate.cpp
    scummvm/trunk/engines/sword25/fmv/oggtheora/vorbisstate.h
    scummvm/trunk/engines/sword25/fmv/oggtheora/yuvtorgba.cpp
    scummvm/trunk/engines/sword25/fmv/oggtheora/yuvtorgba.h
    scummvm/trunk/engines/sword25/module.mk

Removed Paths:
-------------
    scummvm/trunk/engines/sword25/fmv/oggtheora/oggtheora.cpp
    scummvm/trunk/engines/sword25/fmv/oggtheora/oggtheora.h

Modified: scummvm/trunk/engines/sword25/fmv/movieplayer.cpp
===================================================================
--- scummvm/trunk/engines/sword25/fmv/movieplayer.cpp	2010-10-12 23:19:41 UTC (rev 53294)
+++ scummvm/trunk/engines/sword25/fmv/movieplayer.cpp	2010-10-12 23:20:33 UTC (rev 53295)
@@ -33,59 +33,524 @@
  */
 
 #include "sword25/fmv/movieplayer.h"
+#include "sword25/fmv/oggtheora/oggstate.h"
+#include "sword25/fmv/oggtheora/oggstreamstate.h"
+#include "sword25/fmv/oggtheora/vorbisstate.h"
+#include "sword25/fmv/oggtheora/yuvtorgba.h"
+#include "sword25/gfx/graphicengine.h"
+#include "sword25/gfx/panel.h"
+#include "sword25/kernel/kernel.h"
+#include "sword25/sfx/soundengine.h"
 
+#define BS_LOG_PREFIX "MOVIEPLAYER"
+
+#define FLT_EPSILON     1.192092896e-07F        /* smallest such that 1.0+FLT_EPSILON != 1.0 */
+
 namespace Sword25 {
 
-#define BS_LOG_PREFIX "MOVIEPLAYER"
+const int MAX_FRAMES_PER_TICK = 10;
+const int READ_BLOCK_SIZE = 1024 * 40;
+const float MAX_AUDIO_BUFFER_LENGTH = 1.0f;
 
 Service *OggTheora_CreateObject(Kernel *pKernel) {
 	return new MoviePlayer(pKernel);
 }
 
-MoviePlayer::MoviePlayer(Kernel *pKernel) : Service(pKernel) {
+// -----------------------------------------------------------------------------
+
+inline bool VerifyRequiredServiceAvailability() {
+	char *RequiredServices[] = { "gfx", "sfx", "package" };
+	for (size_t i = 0; i < sizeof(RequiredServices) / sizeof(RequiredServices[0]); ++i) {
+		if (!Kernel::GetInstance()->GetService(RequiredServices[i])) {
+			BS_LOG_ERRORLN("Required service \"%s\" is not active.", RequiredServices[i]);
+			return false;
+		}
+	}
+
+	return true;
+}
+
+bool ParseStreamHeaders(Common::SharedPtr<MovieFile> &File,
+						Common::SharedPtr<OggState> &OggState,
+						Common::SharedPtr<OggStreamState> &TheoraStreamState,
+						Common::SharedPtr<OggStreamState> &VorbisStreamState,
+						Common::SharedPtr<TheoraState> &TheoraState,
+						Common::SharedPtr<VorbisState> &VorbisState,
+						bool &TheoraPresent,
+						bool &VorbisPresent,
+						const Common::String &Filename) {
+	TheoraPresent = false;
+	VorbisPresent = false;
+
+	// Ogg file open; parse the headers
+	// Only interested in Vorbis/Theora streams
+	bool FinishedHeaderParsing = false;
+	while (!FinishedHeaderParsing) {
+		if (File->BufferData(*OggState.get()) == 0) return false;
+
+		ogg_page Page;
+		while(OggState->SyncPageout(&Page) > 0) {
+			// is this a mandated initial header? If not, stop parsing
+			if (!ogg_page_bos(&Page)) {
+				// don't leak the page; get it into the appropriate stream
+				if (TheoraPresent) TheoraStreamState->PageIn(&Page);
+				if (VorbisPresent) VorbisStreamState->PageIn(&Page);
+
+				FinishedHeaderParsing = true;
+				break;
+			}
+
+			Common::SharedPtr<OggStreamState> streamState(new OggStreamState(ogg_page_serialno(&Page)));
+
+			streamState->PageIn(&Page);
+
+			ogg_packet Packet;
+			streamState->PacketOut(&Packet);
+
+			// identify the codec: try theora
+			if (!TheoraPresent && TheoraState->DecodeHeader(&Packet) >= 0) {
+				// it is theora
+				TheoraStreamState = streamState;
+				TheoraPresent = true;
+			} else if (!VorbisPresent && VorbisState->SynthesisHeaderIn(&Packet) >=0) {
+				// it is vorbis
+				VorbisStreamState = streamState;
+				VorbisPresent = true;
+			}
+		}
+		// fall through to non-bos page parsing
+	}
+
+	// we're expecting more header packets.
+	unsigned int TheoraPacketsRead = TheoraPresent ? 1 : 0;
+	unsigned int VorbisPacketsRead = VorbisPresent ? 1 : 0;
+	while ((TheoraPresent && TheoraPacketsRead < 3) || (VorbisPresent && VorbisPacketsRead < 3)) {
+		int ret;
+		ogg_packet Packet;
+
+		// look for further theora headers
+		while(TheoraPresent && (TheoraPacketsRead < 3) && (ret = TheoraStreamState->PacketOut(&Packet))) {
+			if (ret < 0 || TheoraState->DecodeHeader(&Packet)) {
+				BS_LOG_ERRORLN("Error parsing Theora stream headers. Stream is possibly corrupt. (%s)", Filename.c_str());
+				return false;
+			}
+
+			++TheoraPacketsRead;
+			if (TheoraPacketsRead == 3) break;
+		}
+
+		// look for more vorbis header packets
+		while(VorbisPresent && (VorbisPacketsRead < 3) && (ret = VorbisStreamState->PacketOut(&Packet))) {
+			if (ret < 0 || VorbisState->SynthesisHeaderIn(&Packet)) {
+				BS_LOG_ERRORLN("Error parsing Vorbis stream headers. Stream is possibly corrupt. (%s)", Filename.c_str());
+				return false;
+			}
+
+			++VorbisPacketsRead;
+			if (VorbisPacketsRead == 3) break;
+		}
+
+		// The header pages/packets will arrive before anything else we care about, or the stream is not obeying spec
+		ogg_page Page;
+		if (OggState->SyncPageout(&Page) > 0) {
+			// demux into the appropriate stream
+			if (TheoraPresent) TheoraStreamState->PageIn(&Page);
+			if (VorbisPresent) VorbisStreamState->PageIn(&Page);
+		} else {
+			if (File->BufferData(*OggState.get()) == 0) {
+				BS_LOG_ERRORLN("End of file while searching for codec headers. (%s)", Filename.c_str());
+				return false;
+			}
+		}
+	}
+
+	return true;
+}
+
+// -----------------------------------------------------------------------------
+
+MoviePlayer::MoviePlayer(Kernel *pKernel) : Service(pKernel),
+			m_SoundHandle(0), _pixels(NULL) {
 	if (!_RegisterScriptBindings())
 		BS_LOG_ERRORLN("Script bindings could not be registered.");
 	else
 		BS_LOGLN("Script bindings registered.");
+
+	UnloadMovie();
 }
 
+MoviePlayer::~MoviePlayer() {
+	delete _pixels;
+}
+
 bool MoviePlayer::LoadMovie(const Common::String &Filename, unsigned int Z) {
+	if (!VerifyRequiredServiceAvailability()) return false;
+
+	UnloadMovie();
+
+	// Alle Objekte die in dieser Funktion erzeugt werden, werden in zun\xE4chst lokalen Auto-Pointern gehalten.
+	// Bei erfolgreicher Beendigung dieser Funktion werden sie den objektlokalen Auto-Pointern zugewiesen.
+	// So wird sichergestellt, dass sie korrekt deinitialisiert werden, wenn in dieser Funktion ein Fehler auftritt, denn beim Zerst\xF6ren der
+	// lokalen Auto-Pointer werden die entsprechenden Destruktoren aufgerufen.
+
+	// Film laden
+	// F\xFCr Filmdateien wird das Cachingsystem nicht benutzt, da Filme in der Regel nur ein Mal abgespielt werden.
+	bool Success = false;
+	Common::SharedPtr<MovieFile> File(new MovieFile(Filename, READ_BLOCK_SIZE, Success));
+	if (!Success) return false;
+
+	// States erzeugen f\xFCr Ogg, Vorbis und Theora, sowie die Ogg und Theora Streams
+	Common::SharedPtr<OggState> OggState(new OggState());
+	Common::SharedPtr<VorbisState> VorbisState(new VorbisState());
+	Common::SharedPtr<TheoraState> TheoraState(new TheoraState());
+
+	Common::SharedPtr<OggStreamState> TheoraStreamState;
+	Common::SharedPtr<OggStreamState> VorbisStreamState;
+
+	if (!ParseStreamHeaders(File, OggState, TheoraStreamState, VorbisStreamState, TheoraState, VorbisState, m_TheoraPresent, m_VorbisPresent, Filename)) return false;
+
+	// Theora-Decoder Initialisieren
+	if (m_TheoraPresent) {
+		TheoraState->DecodeInit();
+
+		const theora_info & TheoraInfo = TheoraState->GetInfo();
+
+		if (TheoraInfo.pixelformat != OC_PF_444 &&
+			TheoraInfo.pixelformat != OC_PF_422 &&
+			TheoraInfo.pixelformat != OC_PF_420) {
+			BS_LOG_ERRORLN("Unknown chroma sampling. (%s)", Filename.c_str());
+			return false;
+		}
+
+		// Ausgabebitmap erstellen
+		GraphicEngine *pGfx = Kernel::GetInstance()->GetGfx();
+		m_OutputBitmap = pGfx->GetMainPanel()->AddDynamicBitmap(TheoraInfo.frame_width, TheoraInfo.frame_height);
+		if (!m_OutputBitmap.IsValid()) {
+			BS_LOG_ERRORLN("Output bitmap for movie playback could not be created.");
+			return false;
+		}
+
+		// Skalierung des Ausgabebitmaps berechnen, so dass es m\xF6glichst viel Bildschirmfl\xE4che einnimmt.
+		float ScreenToVideoWidth = (float) pGfx->GetDisplayWidth() / (float) m_OutputBitmap->GetWidth();
+		float ScreenToVideoHeight = (float) pGfx->GetDisplayHeight() / (float) m_OutputBitmap->GetHeight();
+		float ScaleFactor = MIN(ScreenToVideoWidth, ScreenToVideoHeight);
+		if (abs(ScaleFactor - 1.0f) < FLT_EPSILON) ScaleFactor = 1.0f;
+		m_OutputBitmap->SetScaleFactor(ScaleFactor);
+
+		// Z-Wert setzen
+		m_OutputBitmap->SetZ(Z);
+
+		// Ausgabebitmap auf dem Bildschirm zentrieren
+		m_OutputBitmap->SetX((pGfx->GetDisplayWidth() - m_OutputBitmap->GetWidth()) / 2);
+		m_OutputBitmap->SetY((pGfx->GetDisplayHeight() - m_OutputBitmap->GetHeight()) / 2);
+
+		// Buffer f\xFCr die Pixeldaten erstellen
+		delete _pixels;
+		_pixelsSize = TheoraInfo.width * TheoraInfo.height * 4;
+		_pixels = (byte *)malloc(_pixelsSize);
+		assert(_pixels);
+
+		m_VideoEnded = false;
+	}
+
+	// Vorbis-Decoder initialisieren
+	if (m_VorbisPresent) {
+		VorbisState->SynthesisInit();
+		VorbisState->BlockInit();
+		m_AudioBuffer = Common::SharedPtr<AudioBuffer>(new AudioBuffer());
+
+		m_AudioEnded = false;
+	}
+
+	// Keine Kopie, \xFCbertr\xE4gt Besitz der erzeugten Objekte von der Funktion auf das Objekt.
+	m_File = File;
+	m_OggState = OggState;
+	m_TheoraState = TheoraState;
+	m_TheoraStreamState = TheoraStreamState;
+	m_VorbisState = VorbisState;
+	m_VorbisStreamState = VorbisStreamState;
+	m_MovieLoaded = true;
+	m_Timer = 0;
+
 	return true;
 }
 
 bool MoviePlayer::UnloadMovie() {
+	m_MovieLoaded = false;
+	m_Paused = true;
+
+	m_VorbisStreamState.reset();
+	m_VorbisPresent = false;
+	m_VorbisState.reset();
+	if (m_SoundHandle) {
+		Kernel::GetInstance()->GetSfx()->StopSound(m_SoundHandle);
+		m_SoundHandle = 0;
+	}
+	m_AudioEnded = true;
+	m_AudioBuffer.reset();
+
+	m_TheoraStreamState.reset();
+	m_TheoraPresent = false;
+	m_TheoraState.reset();
+	m_VideoEnded = true;
+
+	m_OggState.reset();
+
+	m_File.reset();
+
+	m_StartTime = 0;
+	m_LastFrameTime = 0;
+	m_Timer = 0.0f;
+
+//	Common::Array<unsigned char>().swap(m_Pixels);
+	m_OutputBitmap.Erase();
+
 	return true;
 }
 
 bool MoviePlayer::Play() {
-	return true;
+	if (m_MovieLoaded) {
+		if (m_Paused) {
+			if (m_SoundHandle) {
+				SoundEngine * SfxPtr = Kernel::GetInstance()->GetSfx();
+				SfxPtr->ResumeSound(m_SoundHandle);
+			}
+			m_Paused = false;
+		}
+
+		return true;
+	} else {
+		BS_LOG_WARNINGLN("Cannot play movie, when no movie is loaded.");
+		return false;
+	}
 }
 
 bool MoviePlayer::Pause() {
-	return true;
+	if (m_MovieLoaded) {
+		if (m_SoundHandle) {
+			SoundEngine *SfxPtr = Kernel::GetInstance()->GetSfx();
+			SfxPtr->PauseSound(m_SoundHandle);
+		}
+
+		m_Paused = true;
+		return true;
+	} else {
+		BS_LOG_WARNINGLN("Cannot pause movie, when no movie is loaded.");
+		return false;
+	}
 }
 
 void MoviePlayer::Update() {
+	if (m_AudioEnded && m_VideoEnded) {
+		m_Paused = true;
+
+		// Falls der Sound noch l\xE4uft, muss er jetzt beendet werden.
+		if (m_SoundHandle) {
+			SoundEngine *SfxPtr = Kernel::GetInstance()->GetSfx();
+			SfxPtr->StopSound(m_SoundHandle);
+			m_SoundHandle = 0;
+		}
+	}
+
+	if (m_Paused) return;
+
+	// Timer aktualisieren.
+	// Wird nur genutzt, wenn keine Audiodaten vorhanden sind.
+	m_Timer += Kernel::GetInstance()->GetGfx()->GetSecondaryFrameDuration();
+
+	// Audiodaten dekodieren
+	if (m_VorbisPresent && !m_AudioEnded) DecodeVorbis();
+
+
+	// Videodaten dekodieren
+	if (m_TheoraPresent && !m_VideoEnded) {
+		bool Result = DecodeTheora();
+
+		if (Result) {
+			// YUV Framebuffer holen
+			yuv_buffer YUVBuffer;
+			m_TheoraState->DecodeYUVOut(&YUVBuffer);
+
+			// YUV Bilddaten nach RGBA konvertieren
+			BS_YUVtoRGBA::YUVtoRGBA(YUVBuffer, m_TheoraState->GetInfo(), _pixels, _pixelsSize);
+
+			// RGBA Bilddaten auf das Ausgabebild kopieren, dabei die Postion des Theoraframes innerhalb des dekodierten Frames beachten.
+			const theora_info &TheoraInfo = m_TheoraState->GetInfo();
+			m_OutputBitmap->SetContent(_pixels, _pixelsSize, 
+				(TheoraInfo.offset_x + TheoraInfo.width * TheoraInfo.offset_y) * 4, 
+				(TheoraInfo.width - TheoraInfo.frame_width) * 4);
+		}
+	}
 }
 
 bool MoviePlayer::IsMovieLoaded() {
-	return true;
+	return m_MovieLoaded;
 }
 
 bool MoviePlayer::IsPaused() {
-	return true;
+	return m_Paused;	
 }
 
 float MoviePlayer::GetScaleFactor() {
-	return 1.0f;
+	if (m_MovieLoaded)
+		return m_OutputBitmap->GetScaleFactorX();
+	else
+		return 0;
 }
 
 void MoviePlayer::SetScaleFactor(float ScaleFactor) {
+	if (m_MovieLoaded) {
+		m_OutputBitmap->SetScaleFactor(ScaleFactor);
+
+		// Ausgabebitmap auf dem Bildschirm zentrieren
+		GraphicEngine *gfxPtr = Kernel::GetInstance()->GetGfx();
+		m_OutputBitmap->SetX((gfxPtr->GetDisplayWidth() - m_OutputBitmap->GetWidth()) / 2);
+		m_OutputBitmap->SetY((gfxPtr->GetDisplayHeight() - m_OutputBitmap->GetHeight()) / 2);
+	}
 }
 
 double MoviePlayer::GetTime() {
-	return 1.0;
+	if (m_VorbisPresent) {
+		if (m_SoundHandle) {
+			float time = Kernel::GetInstance()->GetSfx()->GetSoundTime(m_SoundHandle);
+			return time;
+		} else
+			return 0.0f;
+	} else
+		return m_Timer;
 }
 
+// -----------------------------------------------------------------------------
 
+bool MoviePlayer::DecodeTheora() {
+	double MovieTime = GetTime();
+
+	// Check if this frame time has not passed yet. If the frame is late we need
+	// to decode additonal ones and keep looping, since theora at this stage
+	// needs to decode all frames (due to keyframing)
+	// Getting the current time once at the beginning of the function rather than
+	// every time at the beginning of the loop produces the smoothest framerate
+
+	unsigned int FramesDecoded = 0;
+	bool FrameReady = false;
+	while (m_TheoraState->GranuleTime() < MovieTime) {
+		// theora is one in, one out...
+		ogg_packet Packet;
+		if (m_TheoraStreamState->PacketOut(&Packet) > 0) {
+			if (FramesDecoded < MAX_FRAMES_PER_TICK || Packet.granulepos >= MovieTime) {
+				m_TheoraState->DecodePacketIn(&Packet);
+				FrameReady = true;
+				++FramesDecoded;
+			}
+		} else {
+			if (m_TheoraStreamState->GetPageBufferSize() > 0)
+				m_TheoraStreamState->PageInBufferedPage();
+			else {
+				if (m_File->IsEOF()) {
+					m_VideoEnded = true;
+					break;
+				} else
+					ReadData();
+			}
+		}
+	}
+	m_LastFrameTime = MovieTime;
+
+	return FrameReady;
+}
+
+void MoviePlayer::DecodeVorbis() {
+	// Vorbis-Stream Infos holen.
+	const vorbis_info &Info = m_VorbisState->GetInfo();
+
+	// Maximalgr\xF6\xDFe des Audiobuffers berechnen.
+	size_t MaxAudioBufferSamples = static_cast<size_t>(Info.channels * Info.rate * MAX_AUDIO_BUFFER_LENGTH);
+
+	// Zwischenspeicher f\xFCr die Samples.
+	Common::Array<signed short> Samples;
+
+	// Audiobuffer bis zur Maximalgr\xF6\xDFe f\xFCllen, wenn m\xF6glich.
+	while (m_AudioBuffer->Size() < MaxAudioBufferSamples) {
+		// Vorhandene Audiodaten auslesen
+		float **PCM;
+		int SampleCount = m_VorbisState->SynthesisPCMout(&PCM);
+
+		// Wenn Audiodaten gelesen werden konnten, werden diese in 16-Bit Sample umgewandelt und in den Audiobuffer geschrieben.
+		if (SampleCount > 0) {
+			// Im Samplezwischenspeicher leeren und gen\xFCgend Platz f\xFCr die kommenden Samples reservieren.
+			Samples.reserve(SampleCount);
+			Samples.clear();
+
+			// Samples konvertieren und in die Samplezwischenspeicher schreiben.
+			for (int i = 0; i < SampleCount; ++i) {
+				for (int j = 0; j < Info.channels; ++j) {
+					int SampleValue = static_cast<int>(PCM[j][i] * 32767.0f);
+					Samples.push_back(CLIP(SampleValue, -32700, 32700));
+				}
+			}
+
+			// Daten aus dem Samplezwischenspeicher in den Audiobuffer schreiben.
+			m_AudioBuffer->Push(&Samples[0], Samples.size());
+
+			// Vorbis mitteilen, dass wir alle Samples gelesen haben.
+			m_VorbisState->SynthesisRead(SampleCount);
+		} else {        
+			// Wir konnten, keine Audiodaten auslesen, versuchen ein neues Paket zu dekodieren.
+			ogg_packet Packet;
+			if (m_VorbisStreamState->PacketOut(&Packet) > 0) {
+				if (m_VorbisState->Synthesis(&Packet) == 0) m_VorbisState->SynthesisBlockIn();
+			} else {
+				// Gepufferte Daten in den Stream einf\xFCgen.
+				if (m_VorbisStreamState->GetPageBufferSize() > 0)
+					m_VorbisStreamState->PageInBufferedPage();
+				else {
+					// Nicht genug Daten vorhanden. Wenn die Datei leer ist und bereits alle Audiodaten gelesen wurden, ist der Audiostream am Ende.
+					// Ansonsten Daten nachladen.
+					if (m_File->IsEOF()) {
+						if (m_AudioBuffer->Size() == 0) {
+							m_AudioEnded = true;
+						}
+
+						break;
+					} else
+						ReadData();
+				}
+			}
+		}
+	}
+
+	// Soundkanal abspielen, wenn er noch nicht spielt und Audiodaten vorhanden sind.
+	if (m_SoundHandle == 0 && m_AudioBuffer->Size()) {
+		SoundEngine *SfxPtr = Kernel::GetInstance()->GetSfx();
+		m_SoundHandle = SfxPtr->PlayDynamicSoundEx(&DynamicSoundCallBack, this, SoundEngine::SFX, Info.rate, 16, Info.channels);
+	}
+}
+
+void MoviePlayer::ReadData() {
+	if (!m_File->IsEOF()) m_File->BufferData(*m_OggState.get());
+
+	ogg_page Page;
+	while(m_OggState->SyncPageout(&Page) > 0) {
+		if (m_TheoraPresent) m_TheoraStreamState->BufferPage(&Page);
+		if (m_VorbisPresent) m_VorbisStreamState->BufferPage(&Page);
+	}
+}
+
+void MoviePlayer::DynamicSoundCallBack(void *UserData, void *Data, unsigned int DataLength) {
+	MoviePlayer &t = *reinterpret_cast<MoviePlayer *>(UserData);
+
+	signed short *Buffer = reinterpret_cast<signed short *>(Data);
+
+	// Audiodaten in den Soundbuffer schreiben.
+	DataLength -= t.m_AudioBuffer->Pop(Buffer, DataLength / 2) * 2;
+
+	// Falls nicht genug Audiodaten vorhanden waren, wird der Rest mit Stille \xFCberschrieben.
+	if (DataLength) {
+		char *ByteBuffer = reinterpret_cast<char *>(Buffer);
+		while (DataLength--) {
+			*ByteBuffer++ = 0;
+		}
+	}
+}
+
 } // End of namespace Sword25

Modified: scummvm/trunk/engines/sword25/fmv/movieplayer.h
===================================================================
--- scummvm/trunk/engines/sword25/fmv/movieplayer.h	2010-10-12 23:19:41 UTC (rev 53294)
+++ scummvm/trunk/engines/sword25/fmv/movieplayer.h	2010-10-12 23:20:33 UTC (rev 53295)
@@ -39,11 +39,38 @@
 // Includes
 // -----------------------------------------------------------------------------
 
+#include "common/ptr.h"
 #include "sword25/kernel/common.h"
 #include "sword25/kernel/service.h"
+#include "sword25/fmv/oggtheora/audiobuffer.h"
+#include "sword25/fmv/oggtheora/moviefile.h"
+#include "sword25/fmv/oggtheora/oggstreamstate.h"
+#include "sword25/fmv/oggtheora/theorastate.h"
+#include "sword25/fmv/oggtheora/vorbisstate.h"
+#include "sword25/gfx/bitmap.h"
 
 namespace Sword25 {
 
+/* FIXME: Audio stubs
+class OggStreamState {
+public:
+	OggStreamState(int v) {}
+	void PageIn(void *v) {}
+	bool PacketOut(void *v) { return true; }
+};
+class VorbisState {
+public:
+	void BlockInit() {}
+	void SynthesisInit() {}
+	bool SynthesisHeaderIn(void *v) { return false; }
+};
+class OggState {
+public:
+	bool SyncPageout(void *v) { return false; }
+	char *SyncBuffer(int v) { return NULL; }
+};
+*/
+
 // -----------------------------------------------------------------------------
 // Class definitions
 // -----------------------------------------------------------------------------
@@ -55,10 +82,10 @@
 	// -----------------------------------------------------------------------------
 
 	MoviePlayer(Kernel *pKernel);
-	~MoviePlayer() {};
+	~MoviePlayer();
 
 	// -----------------------------------------------------------------------------
-	// Abstract interface must be implemented by each Movie Player
+	// Player interface must be implemented by a Movie Player
 	// -----------------------------------------------------------------------------
 
 	/**
@@ -137,9 +164,44 @@
 	 * @remark              This method can only be called when IsMovieLoaded() returns true.
 	 */
 	double GetTime();
+private:
+	// -----------------------------------------------------------------------------
+	// Internal support methods
+	// -----------------------------------------------------------------------------
+	bool _RegisterScriptBindings();
+	bool DecodeTheora();
+	void DecodeVorbis();
+	void ReadData();
+	static void DynamicSoundCallBack(void *UserData, void *Data, unsigned int DataLength);
 
 private:
-	bool _RegisterScriptBindings();
+	bool								m_MovieLoaded;
+	bool								m_Paused;
+
+	Common::SharedPtr<OggStreamState>	m_VorbisStreamState;
+	bool								m_VorbisPresent;
+	Common::SharedPtr<VorbisState>		m_VorbisState;
+	unsigned int						m_SoundHandle;
+	bool								m_AudioEnded;
+	Common::SharedPtr<AudioBuffer>		m_AudioBuffer;
+
+	Common::SharedPtr<OggStreamState>	m_TheoraStreamState;
+	bool								m_TheoraPresent;
+	Common::SharedPtr<TheoraState>		m_TheoraState;
+	bool								m_VideoEnded;
+
+	Common::SharedPtr<OggState>			m_OggState;
+
+	Common::SharedPtr<MovieFile>		m_File;
+
+	uint64_t							m_StartTime;
+	double								m_LastFrameTime;
+
+	float								m_Timer;
+
+	byte *								_pixels;
+	int									_pixelsSize;
+	RenderObjectPtr<Bitmap>				m_OutputBitmap;
 };
 
 } // End of namespace Sword25

Modified: scummvm/trunk/engines/sword25/fmv/oggtheora/audiobuffer.cpp
===================================================================
--- scummvm/trunk/engines/sword25/fmv/oggtheora/audiobuffer.cpp	2010-10-12 23:19:41 UTC (rev 53294)
+++ scummvm/trunk/engines/sword25/fmv/oggtheora/audiobuffer.cpp	2010-10-12 23:20:33 UTC (rev 53295)
@@ -37,72 +37,46 @@
 // -----------------------------------------------------------------------------
 
 #include "sword25/fmv/oggtheora/audiobuffer.h"
-#include <windows.h>
-#include <queue>
 
-using namespace std;
-
 // -----------------------------------------------------------------------------
 
-struct BS_AudioBuffer::Impl
-{
-	CRITICAL_SECTION CS;
-	queue<signed short> Buffer;
-};
+namespace Sword25 {
 
 // -----------------------------------------------------------------------------
 
-BS_AudioBuffer::BS_AudioBuffer() : t(new Impl())
-{
-	InitializeCriticalSection(&t->CS);
+AudioBuffer::AudioBuffer() {
 }
 
 // -----------------------------------------------------------------------------
 
-BS_AudioBuffer::~BS_AudioBuffer()
-{
-	DeleteCriticalSection(&t->CS);
-
-	delete t;
+AudioBuffer::~AudioBuffer() {
 }
 
 // -----------------------------------------------------------------------------
 
-void BS_AudioBuffer::Push(signed short * SamplePtr, unsigned int SampleCount)
-{
-	EnterCriticalSection(&t->CS);
-
-	signed short * SampleEndPtr = SamplePtr + SampleCount;
-	while (SamplePtr != SampleEndPtr) t->Buffer.push(*SamplePtr++);
-
-	LeaveCriticalSection(&t->CS);
+void AudioBuffer::Push(signed short *SamplePtr, unsigned int SampleCount) {
+	signed short *SampleEndPtr = SamplePtr + SampleCount;
+	while (SamplePtr != SampleEndPtr) _buffer.push(*SamplePtr++);
 }
 
 // -----------------------------------------------------------------------------
 
-unsigned int BS_AudioBuffer::Pop(signed short * SamplePtr, unsigned int SampleCount)
-{
-	EnterCriticalSection(&t->CS);
-
+unsigned int AudioBuffer::Pop(signed short *SamplePtr, unsigned int SampleCount) {
 	unsigned int i = 0;
-	for (; i < SampleCount && !t->Buffer.empty(); ++i)
-	{
-		SamplePtr[i] = t->Buffer.front();
-		t->Buffer.pop();
+	for (; i < SampleCount && !_buffer.empty(); ++i) {
+		SamplePtr[i] = _buffer.front();
+		_buffer.pop();
 	}
 
-	LeaveCriticalSection(&t->CS);
-
 	return i;
 }
 
 // -----------------------------------------------------------------------------
 
-unsigned int BS_AudioBuffer::Size() const
-{
-	EnterCriticalSection(&t->CS);
-	unsigned int result = t->Buffer.size();
-	LeaveCriticalSection(&t->CS);
+unsigned int AudioBuffer::Size() const {
+	unsigned int result = _buffer.size();
 
 	return result;
 }
+
+} // End of namespace Sword25

Modified: scummvm/trunk/engines/sword25/fmv/oggtheora/audiobuffer.h
===================================================================
--- scummvm/trunk/engines/sword25/fmv/oggtheora/audiobuffer.h	2010-10-12 23:19:41 UTC (rev 53294)
+++ scummvm/trunk/engines/sword25/fmv/oggtheora/audiobuffer.h	2010-10-12 23:20:33 UTC (rev 53295)
@@ -39,30 +39,32 @@
 // Includes
 // -----------------------------------------------------------------------------
 
+#include "common/queue.h"
 #include "sword25/kernel/common.h"
 
+namespace Sword25 {
+
 // -----------------------------------------------------------------------------
-// Klassendefinition
+// Class definitions
 // -----------------------------------------------------------------------------
 
-class BS_AudioBuffer
-{
+class AudioBuffer {
 public:
-	BS_AudioBuffer();
-	virtual ~BS_AudioBuffer();
+	AudioBuffer();
+	virtual ~AudioBuffer();
 
-	void Push(signed short * SamplePtr, unsigned int SampleCount);
-	unsigned int Pop(signed short * SamplePtr, unsigned int SampleCount);
+	void Push(signed short *SamplePtr, unsigned int SampleCount);
+	unsigned int Pop(signed short *SamplePtr, unsigned int SampleCount);
 	unsigned int Size() const;
 
 private:
-	// PIMPL Pattern
-	struct Impl;
-	Impl * t;
+	Common::Queue<unsigned short> _buffer;
 
 	// Kopie verbieten
-	BS_AudioBuffer(const BS_AudioBuffer &);
-	const BS_AudioBuffer & operator=(const BS_AudioBuffer &);
+	AudioBuffer(const AudioBuffer &);
+	const AudioBuffer & operator=(const AudioBuffer &);
 };
 
+} // End of namespace Sword25
+
 #endif

Modified: scummvm/trunk/engines/sword25/fmv/oggtheora/moviefile.cpp
===================================================================
--- scummvm/trunk/engines/sword25/fmv/oggtheora/moviefile.cpp	2010-10-12 23:19:41 UTC (rev 53294)
+++ scummvm/trunk/engines/sword25/fmv/oggtheora/moviefile.cpp	2010-10-12 23:20:33 UTC (rev 53295)
@@ -47,42 +47,37 @@
 #include "sword25/fmv/oggtheora/oggstate.h"
 #include "sword25/fmv/oggtheora/moviefile.h"
 
+namespace Sword25 {
+
 // -----------------------------------------------------------------------------
 
-BS_MovieFile::BS_MovieFile(const std::string & Filename, unsigned int ReadBlockSize, bool & Success) :
-	m_Data(0), m_Size(0), m_ReadPos(0), m_ReadBlockSize(ReadBlockSize)
-{
-	m_Data = reinterpret_cast<char *>(BS_Kernel::GetInstance()->GetPackage()->GetFile(Filename, &m_Size));
-	if (!m_Data)
-	{
+MovieFile::MovieFile(const Common::String &Filename, unsigned int ReadBlockSize, bool &Success) :
+	m_Data(0), m_Size(0), m_ReadPos(0), m_ReadBlockSize(ReadBlockSize) {
+	m_Data = reinterpret_cast<char *>(Kernel::GetInstance()->GetPackage()->GetFile(Filename, &m_Size));
+	if (!m_Data) {
 		BS_LOG_ERRORLN("Could not load movie file \"%s\".", Filename.c_str());
 		Success = false;
-	}
-	else
+	} else
 		Success = true;
 }
 
 // -----------------------------------------------------------------------------
 
-BS_MovieFile::~BS_MovieFile()
-{
+MovieFile::~MovieFile() {
 	if (m_Data) delete [] m_Data;
 }
 
 // -----------------------------------------------------------------------------
 
-int BS_MovieFile::BufferData(BS_OggState & OggState)
-{
-	if (!m_Data || !m_Size || m_ReadPos >= m_Size)
-	{
+int MovieFile::BufferData(OggState &OggState) {
+	if (!m_Data || !m_Size || m_ReadPos >= m_Size) {
 		BS_LOG_ERRORLN("Tried to read past the movie buffer's end.");
 		return 0;
 	}
 
 	// just grab some more compressed bitstream and sync it for page extraction 
-	char * Buffer = OggState.SyncBuffer(m_ReadBlockSize);
-	if (!Buffer)
-	{
+	char *Buffer = OggState.SyncBuffer(m_ReadBlockSize);
+	if (!Buffer) {
 		BS_LOG_ERRORLN("ogg_sync_buffer() failed.");
 		return 0;
 	}
@@ -99,7 +94,8 @@
 
 // -----------------------------------------------------------------------------
 
-bool BS_MovieFile::IsEOF() const
-{
+bool MovieFile::IsEOF() const {
 	return m_ReadPos >= m_Size;
 }
+
+} // End of namespace Sword25

Modified: scummvm/trunk/engines/sword25/fmv/oggtheora/moviefile.h
===================================================================
--- scummvm/trunk/engines/sword25/fmv/oggtheora/moviefile.h	2010-10-12 23:19:41 UTC (rev 53294)
+++ scummvm/trunk/engines/sword25/fmv/oggtheora/moviefile.h	2010-10-12 23:20:33 UTC (rev 53295)
@@ -41,25 +41,22 @@
 
 #include "sword25/kernel/common.h"
 
-#include "sword25/kernel/memlog_off.h"
-#include <string>
-#include "sword25/kernel/memlog_on.h"
+namespace Sword25 {
 
 // -----------------------------------------------------------------------------
 
-class BS_OggState;
+class OggState;
 
 // -----------------------------------------------------------------------------
 // Klassendefinition
 // -----------------------------------------------------------------------------
 
-class BS_MovieFile
-{
+class MovieFile {
 public:
-  BS_MovieFile(const std::string & Filename, unsigned int ReadBlockSize, bool & Success);
-	virtual ~BS_MovieFile();
+	MovieFile(const Common::String &Filename, unsigned int ReadBlockSize, bool &Success);
+	virtual ~MovieFile();
 
-	int		BufferData(BS_OggState & OggState);
+	int		BufferData(OggState &OggState);
 	bool	IsEOF() const;
 
 private:
@@ -69,4 +66,6 @@
 	unsigned int	m_ReadBlockSize;
 };
 
+} // End of namespace Sword25
+
 #endif

Modified: scummvm/trunk/engines/sword25/fmv/oggtheora/oggstate.cpp
===================================================================
--- scummvm/trunk/engines/sword25/fmv/oggtheora/oggstate.cpp	2010-10-12 23:19:41 UTC (rev 53294)
+++ scummvm/trunk/engines/sword25/fmv/oggtheora/oggstate.cpp	2010-10-12 23:20:33 UTC (rev 53295)
@@ -38,37 +38,36 @@
 
 #include "sword25/fmv/oggtheora/oggstate.h"
 
+namespace Sword25 {
+
 // -----------------------------------------------------------------------------
 
-BS_OggState::BS_OggState()
-{
+OggState::OggState() {
 	ogg_sync_init(&m_SyncState);
 }
 
 // -----------------------------------------------------------------------------
 
-BS_OggState::~BS_OggState()
-{
+OggState::~OggState() {
 	ogg_sync_clear(&m_SyncState);
 }
 
 // -----------------------------------------------------------------------------
 
-int BS_OggState::SyncPageout(ogg_page * OggPage)
-{
+int OggState::SyncPageout(ogg_page *OggPage) {
 	return ogg_sync_pageout(&m_SyncState, OggPage);
 }
 
 // -----------------------------------------------------------------------------
 
-char * BS_OggState::SyncBuffer(long Size)
-{
+char *OggState::SyncBuffer(long Size) {
 	return ogg_sync_buffer(&m_SyncState, Size);
 }
 
 // -----------------------------------------------------------------------------
 
-int BS_OggState::SyncWrote(long Bytes)
-{
+int OggState::SyncWrote(long Bytes) {
 	return ogg_sync_wrote(&m_SyncState, Bytes);
 }
+
+} // End of namespace Sword25

Modified: scummvm/trunk/engines/sword25/fmv/oggtheora/oggstate.h
===================================================================
--- scummvm/trunk/engines/sword25/fmv/oggtheora/oggstate.h	2010-10-12 23:19:41 UTC (rev 53294)
+++ scummvm/trunk/engines/sword25/fmv/oggtheora/oggstate.h	2010-10-12 23:20:33 UTC (rev 53295)
@@ -40,39 +40,37 @@
 // -----------------------------------------------------------------------------
 
 #include "sword25/kernel/common.h"
-#include "ogg/ogg.h"
-// XXX
-#include <iostream>
-// XXX
+#include <ogg/ogg.h>
 
+namespace Sword25 {
+
 // -----------------------------------------------------------------------------
-// Klassendefinition
+// Class definitions
 // -----------------------------------------------------------------------------
 
-class BS_OggState
-{
+class OggState {
 public:
-	BS_OggState();
-	virtual ~BS_OggState();
+	OggState();
+	virtual ~OggState();
 
-	int		SyncPageout(ogg_page * OggPage);
+	int		SyncPageout(ogg_page *OggPage);
 	char *	SyncBuffer(long Size);
 	int		SyncWrote(long Bytes);
 
 	// XXX
-	void DumpInternals()
-	{
-		std::cout << "bodybytes: " << m_SyncState.bodybytes << std::endl;
-		std::cout << "fill: " << m_SyncState.fill << std::endl;
-		std::cout << "headerbytes: " << m_SyncState.headerbytes << std::endl;
-		std::cout << "returned: " << m_SyncState.returned << std::endl;
-		std::cout << "storage: " << m_SyncState.storage << std::endl;
-		std::cout << "unsynched: " << m_SyncState.unsynced << std::endl;
-		std::cout << std::endl;
+	void DumpInternals() {
+		warning("bodybytes: %d", m_SyncState.bodybytes);
+		warning("fill: %d", m_SyncState.fill);
+		warning("headerbytes: %d", m_SyncState.headerbytes );
+		warning("returned: %d", m_SyncState.returned );
+		warning("storage: %d", m_SyncState.storage );
+		warning("unsynched: %d", m_SyncState.unsynced );
 	}
 	// XXX
 private:
 	ogg_sync_state				m_SyncState;
 };
 
+} // End of namespace Sword25
+
 #endif

Modified: scummvm/trunk/engines/sword25/fmv/oggtheora/oggstreamstate.cpp
===================================================================
--- scummvm/trunk/engines/sword25/fmv/oggtheora/oggstreamstate.cpp	2010-10-12 23:19:41 UTC (rev 53294)
+++ scummvm/trunk/engines/sword25/fmv/oggtheora/oggstreamstate.cpp	2010-10-12 23:20:33 UTC (rev 53295)
@@ -38,22 +38,21 @@
 
 #include "sword25/fmv/oggtheora/oggstreamstate.h"
 
+namespace Sword25 {
+
 // -----------------------------------------------------------------------------
 
-BS_OggStreamState::BS_OggStreamState(int SerialNo)
-{
+OggStreamState::OggStreamState(int SerialNo) {
 	ogg_stream_init(&m_State, SerialNo);
 }
 
 // -----------------------------------------------------------------------------
 
-BS_OggStreamState::~BS_OggStreamState()
-{
+OggStreamState::~OggStreamState() {
 	ogg_stream_clear(&m_State);
 
 	// Alle gepufferten Pages l\xF6schen.
-	while (!m_PageBuffer.empty())
-	{
+	while (!m_PageBuffer.empty()) {
 		delete [] m_PageBuffer.front().header;
 		delete [] m_PageBuffer.front().body;
 		m_PageBuffer.pop();
@@ -62,24 +61,20 @@
 
 // -----------------------------------------------------------------------------
 
-int BS_OggStreamState::PageIn(ogg_page * PagePtr)
-{
+int OggStreamState::PageIn(ogg_page *PagePtr) {
 	return ogg_stream_pagein(&m_State, PagePtr);
 }
 
 // -----------------------------------------------------------------------------
 
-int BS_OggStreamState::PacketOut(ogg_packet * PacketPtr)
-{
+int OggStreamState::PacketOut(ogg_packet *PacketPtr) {
 	return ogg_stream_packetout(&m_State, PacketPtr);
 }
 
 // -----------------------------------------------------------------------------
 
-void BS_OggStreamState::BufferPage(ogg_page * PagePtr)
-{
-	if (PageBelongsToStream(PagePtr))
-	{
+void OggStreamState::BufferPage(ogg_page *PagePtr) {
+	if (PageBelongsToStream(PagePtr)) {
 		// Pages k\xF6nnen nicht direkt gespeichert werden, da die Pointer im Laufe der Zeit ung\xFCltig werden.
 		// Daher wird an dieser Stelle eine tiefe Kopie der Page im erzeugt und im Pagebuffer angelegt.
 		ogg_page PageCopy;
@@ -96,10 +91,8 @@
 
 // -----------------------------------------------------------------------------
 
-int BS_OggStreamState::PageInBufferedPage()
-{
-	if (GetPageBufferSize() > 0)
-	{
+int OggStreamState::PageInBufferedPage() {
+	if (GetPageBufferSize() > 0) {
 		// Page in den Stream einf\xFCgen, l\xF6schen und aus dem Puffer entfernen.
 		int Result = PageIn(&m_PageBuffer.front());
 		delete [] m_PageBuffer.front().header;
@@ -113,21 +106,20 @@
 
 // -----------------------------------------------------------------------------
 
-unsigned int BS_OggStreamState::GetPageBufferSize() const
-{
+unsigned int OggStreamState::GetPageBufferSize() const {
 	return m_PageBuffer.size();
 }
 
 // -----------------------------------------------------------------------------
 
-unsigned int BS_OggStreamState::GetUnprocessedBytes() const
-{
+unsigned int OggStreamState::GetUnprocessedBytes() const {
 	return m_State.body_fill - m_State.body_returned;
 }
 
 // -----------------------------------------------------------------------------
 
-bool BS_OggStreamState::PageBelongsToStream(ogg_page * PagePtr) const
-{
+bool OggStreamState::PageBelongsToStream(ogg_page *PagePtr) const {
 	return m_State.serialno == ogg_page_serialno(PagePtr);
 }
+
+} // End of namespace Sword25

Modified: scummvm/trunk/engines/sword25/fmv/oggtheora/oggstreamstate.h
===================================================================
--- scummvm/trunk/engines/sword25/fmv/oggtheora/oggstreamstate.h	2010-10-12 23:19:41 UTC (rev 53294)
+++ scummvm/trunk/engines/sword25/fmv/oggtheora/oggstreamstate.h	2010-10-12 23:20:33 UTC (rev 53295)
@@ -40,50 +40,46 @@
 // -----------------------------------------------------------------------------
 
 #include "sword25/kernel/common.h"
-#include "ogg/ogg.h"
-#include <queue>
-// XXX
-#include <iostream>
-// XXX
+#include <ogg/ogg.h>
+#include "common/queue.h"
 
+namespace Sword25 {
+
 // -----------------------------------------------------------------------------
-// Klassendefinition
+// Class definitions
 // -----------------------------------------------------------------------------
 
-class BS_OggStreamState
-{
+class OggStreamState {
 public:
-	BS_OggStreamState(int SerialNo);
-	virtual ~BS_OggStreamState();
+	OggStreamState(int SerialNo);
+	virtual ~OggStreamState();
 
-	int PageIn(ogg_page * PagePtr);
-	int PacketOut(ogg_packet * PacketPtr);
+	int PageIn(ogg_page *PagePtr);
+	int PacketOut(ogg_packet *PacketPtr);
 
-	void BufferPage(ogg_page * PagePtr);
+	void BufferPage(ogg_page *PagePtr);
 	int PageInBufferedPage();
 	unsigned int GetPageBufferSize() const;
 
 	unsigned int GetUnprocessedBytes() const;
-	bool PageBelongsToStream(ogg_page * PagePtr) const;
+	bool PageBelongsToStream(ogg_page *PagePtr) const;
 
 	// XXX
-	void DumpInternals()
-	{
-		using namespace std;
-
-		cout << "body_storage: " << m_State.body_storage << endl;
-		cout << "body_fill: " << m_State.body_fill << endl;
-		cout << "body_returned: " << m_State.body_returned << endl;
-		cout << "lacing_storage: " << m_State.lacing_storage << endl;
-		cout << "lacing_fill: " << m_State.lacing_fill << endl;
-		cout << "lacing_returned: " << m_State.lacing_returned << endl;
-		cout << endl;
+	void DumpInternals() {
+		warning("body_storage: %d", m_State.body_storage);
+		warning("body_fill: %d", m_State.body_fill);
+		warning("body_returned: %d", m_State.body_returned);
+		warning("lacing_storage: %d", m_State.lacing_storage);
+		warning("lacing_fill: %d", m_State.lacing_fill);
+		warning("lacing_returned: %d", m_State.lacing_returned);
 	}
 	// XXX
 
 private:
 	ogg_stream_state		m_State;
-	std::queue<ogg_page>	m_PageBuffer;
+	Common::Queue<ogg_page>	m_PageBuffer;
 };
 
+} // End of namespace Sword25
+
 #endif

Deleted: scummvm/trunk/engines/sword25/fmv/oggtheora/oggtheora.cpp
===================================================================
--- scummvm/trunk/engines/sword25/fmv/oggtheora/oggtheora.cpp	2010-10-12 23:19:41 UTC (rev 53294)
+++ scummvm/trunk/engines/sword25/fmv/oggtheora/oggtheora.cpp	2010-10-12 23:20:33 UTC (rev 53295)
@@ -1,723 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-/* 
- * This code is based on Broken Sword 2.5 engine
- *
- * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
- *
- * Licensed under GNU GPL v2
- *
- */
-
-// The code in this file is based in part on code from the OggTheora Software
-// codec source released under the following terms:
-//
-// Copyright (C) 2002-2007 Xiph.org Foundation
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// - Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// - Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-//
-// - Neither the name of the Xiph.org Foundation nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION
-// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// -----------------------------------------------------------------------------
-// Logging
-// -----------------------------------------------------------------------------
-
-#define BS_LOG_PREFIX "OGGTHEORA"
-
-// -----------------------------------------------------------------------------
-// Includes
-// -----------------------------------------------------------------------------
-
-#include "sword25/kernel/memlog_off.h"
-#include <algorithm>
-#include "sword25/kernel/memlog_on.h"
-#include <float.h>
-
-#include "sword25/package/packagemanager.h"
-#include "sword25/sfx/soundengine.h"
-#include "sword25/gfx/graphicengine.h"
-#include "sword25/gfx/panel.h"
-#include "sword25/fmv/oggtheora/oggtheora.h"
-#include "sword25/fmv/oggtheora/yuvtorgba.h"
-
-using namespace std;
-
-// -----------------------------------------------------------------------------
-// Konstanten und Hilfsfunktionen
-// -----------------------------------------------------------------------------
-
-namespace
-{
-	// --------------------------------------------------------------------------
-
-	const int MAX_FRAMES_PER_TICK = 10;
-	const int READ_BLOCK_SIZE = 1024 * 40;
-	const float MAX_AUDIO_BUFFER_LENGTH = 1.0f;
-
-	// --------------------------------------------------------------------------
-
-	template<typename T>
-	inline T Clamp(T x, T low, T high)
-	{
-		return ((x > high) ? high : (( x < low) ? low : x));
-	}
-}
-
-// -----------------------------------------------------------------------------
-// Konstruktion / Destruktion
-// -----------------------------------------------------------------------------
-
-BS_OggTheora::BS_OggTheora(BS_Kernel * pKernel) : BS_MoviePlayer(pKernel), m_SoundHandle(0)
-{
-	UnloadMovie();
-}
-
-// -----------------------------------------------------------------------------
-
-BS_OggTheora::~BS_OggTheora()
-{
-	UnloadMovie();
-}
-
-// -----------------------------------------------------------------------------
-
-BS_Service * BS_OggTheora_CreateObject(BS_Kernel* pKernel) { return new BS_OggTheora(pKernel); }
-
-// -----------------------------------------------------------------------------
-// BS_MoviePlayer Interface
-// -----------------------------------------------------------------------------
-
-
-// -----------------------------------------------------------------------------
-// LoadMovie() mit Hilfsfunktionen
-// -----------------------------------------------------------------------------
-
-namespace
-{
-	inline bool VerifyRequiredServiceAvailability()
-	{
-		char * RequiredServices[] = { "gfx", "sfx", "package" };
-		for (size_t i = 0; i < sizeof(RequiredServices) / sizeof(RequiredServices[0]); ++i)
-		{
-			if (!BS_Kernel::GetInstance()->GetService(RequiredServices[i]))
-			{
-				BS_LOG_ERRORLN("Required service \"%s\" is not active.", RequiredServices[i]);
-				return false;
-			}
-		}
-
-		return true;
-	}
-
-	// -------------------------------------------------------------------------
-
-	bool ParseStreamHeaders(auto_ptr<BS_MovieFile> & File,
-							auto_ptr<BS_OggState> & OggState,
-							auto_ptr<BS_OggStreamState> & TheoraStreamState,
-							auto_ptr<BS_OggStreamState> & VorbisStreamState,
-							auto_ptr<BS_TheoraState> & TheoraState,
-							auto_ptr<BS_VorbisState> & VorbisState,
-							bool & TheoraPresent,
-							bool & VorbisPresent,
-							const std::string & Filename)
-	{
-		TheoraPresent = false;
-		VorbisPresent = false;
-
-		// Ogg file open; parse the headers
-		// Only interested in Vorbis/Theora streams
-		bool FinishedHeaderParsing = false;
-		while (!FinishedHeaderParsing)
-		{
-			if (File->BufferData(*OggState.get()) == 0) return false;
-
-			ogg_page Page;
-			while(OggState->SyncPageout(&Page) > 0)
-			{
-				// is this a mandated initial header? If not, stop parsing
-				if(!ogg_page_bos(&Page))
-				{
-					// don't leak the page; get it into the appropriate stream
-					if (TheoraPresent) TheoraStreamState->PageIn(&Page);
-					if (VorbisPresent) VorbisStreamState->PageIn(&Page);
-
-					FinishedHeaderParsing = true;
-					break;
-				}
-
-				auto_ptr<BS_OggStreamState> streamState(new BS_OggStreamState(ogg_page_serialno(&Page)));
-
-				streamState->PageIn(&Page);
-
-				ogg_packet Packet;
-				streamState->PacketOut(&Packet);
-
-				// identify the codec: try theora
-				if(!TheoraPresent && TheoraState->DecodeHeader(&Packet) >= 0)
-				{
-					// it is theora
-					TheoraStreamState = streamState;
-					TheoraPresent = true;
-				}
-				else if(!VorbisPresent && VorbisState->SynthesisHeaderIn(&Packet) >=0)
-				{
-					// it is vorbis
-					VorbisStreamState = streamState;
-					VorbisPresent = true;
-				}
-			}
-			// fall through to non-bos page parsing
-		}
-
-		// we're expecting more header packets.
-		unsigned int TheoraPacketsRead = TheoraPresent ? 1 : 0;
-		unsigned int VorbisPacketsRead = VorbisPresent ? 1 : 0;
-		while((TheoraPresent && TheoraPacketsRead < 3) || (VorbisPresent && VorbisPacketsRead < 3))
-		{
-			int ret;
-			ogg_packet Packet;
-
-			// look for further theora headers
-			while(TheoraPresent && (TheoraPacketsRead < 3) && (ret = TheoraStreamState->PacketOut(&Packet)))
-			{
-				if(ret < 0 || TheoraState->DecodeHeader(&Packet))
-				{
-					BS_LOG_ERRORLN("Error parsing Theora stream headers. Stream is possibly corrupt. (%s)", Filename.c_str());
-					return false;
-				}
-
-				++TheoraPacketsRead;
-				if (TheoraPacketsRead == 3) break;
-			}
-
-			// look for more vorbis header packets
-			while(VorbisPresent && (VorbisPacketsRead < 3) && (ret = VorbisStreamState->PacketOut(&Packet)))
-			{
-				if(ret < 0 || VorbisState->SynthesisHeaderIn(&Packet))
-				{
-					BS_LOG_ERRORLN("Error parsing Vorbis stream headers. Stream is possibly corrupt. (%s)", Filename.c_str());
-					return false;
-				}
-
-				++VorbisPacketsRead;
-				if (VorbisPacketsRead == 3) break;
-			}
-
-			// The header pages/packets will arrive before anything else we care about, or the stream is not obeying spec
-			ogg_page Page;
-			if(OggState->SyncPageout(&Page) > 0)
-			{
-				// demux into the appropriate stream
-				if(TheoraPresent) TheoraStreamState->PageIn(&Page);
-				if(VorbisPresent) VorbisStreamState->PageIn(&Page);
-			}
-			else
-			{
-				if(File->BufferData(*OggState.get()) == 0)
-				{
-					BS_LOG_ERRORLN("End of file while searching for codec headers. (%s)", Filename.c_str());
-					return false;
-				}
-			}
-		}
-
-		return true;
-	}
-}
-
-// -----------------------------------------------------------------------------
-
-bool BS_OggTheora::LoadMovie(const std::string & Filename, unsigned int Z)
-{
-	if (!VerifyRequiredServiceAvailability()) return false;
-
-	UnloadMovie();
-
-	// Alle Objekte die in dieser Funktion erzeugt werden, werden in zun\xE4chst lokalen Auto-Pointern gehalten.
-	// Bei erfolgreicher Beendigung dieser Funktion werden sie den objektlokalen Auto-Pointern zugewiesen.
-	// So wird sichergestellt, dass sie korrekt deinitialisiert werden, wenn in dieser Funktion ein Fehler auftritt, denn beim Zerst\xF6ren der
-	// lokalen Auto-Pointer werden die entsprechenden Destruktoren aufgerufen.
-
-	// Film laden
-	// F\xFCr Filmdateien wird das Cachingsystem nicht benutzt, da Filme in der Regel nur ein Mal abgespielt werden.
-	bool Success;
-	auto_ptr<BS_MovieFile> File(new BS_MovieFile(Filename, READ_BLOCK_SIZE, Success));
-	if (!Success) return false;
-
-	// States erzeugen f\xFCr Ogg, Vorbis und Theora, sowie die Ogg und Theora Streams
-	auto_ptr<BS_OggState> OggState(new BS_OggState());
-	auto_ptr<BS_VorbisState> VorbisState(new BS_VorbisState());
-	auto_ptr<BS_TheoraState> TheoraState(new BS_TheoraState());
-
-	auto_ptr<BS_OggStreamState> TheoraStreamState;
-	auto_ptr<BS_OggStreamState> VorbisStreamState;
-
-	if (!ParseStreamHeaders(File, OggState, TheoraStreamState, VorbisStreamState, TheoraState, VorbisState, m_TheoraPresent, m_VorbisPresent, Filename)) return false;
-
-	// Theora-Decoder Initialisieren
-	if(m_TheoraPresent)
-	{
-		TheoraState->DecodeInit();
-
-		const theora_info & TheoraInfo = TheoraState->GetInfo();
-
-		if (TheoraInfo.pixelformat != OC_PF_444 &&
-			TheoraInfo.pixelformat != OC_PF_422 &&
-			TheoraInfo.pixelformat != OC_PF_420)
-		{
-			BS_LOG_ERRORLN("Unknown chroma sampling. (%s)", Filename.c_str());
-			return false;
-		}
-
-		// Ausgabebitmap erstellen
-		BS_GraphicEngine * pGfx = BS_Kernel::GetInstance()->GetGfx();
-		m_OutputBitmap = pGfx->GetMainPanel()->AddDynamicBitmap(TheoraInfo.frame_width, TheoraInfo.frame_height);
-		if (!m_OutputBitmap.IsValid())
-		{
-			BS_LOG_ERRORLN("Output bitmap for movie playback could not be created.");
-			return false;
-		}
-
-		// Skalierung des Ausgabebitmaps berechnen, so dass es m\xF6glichst viel Bildschirmfl\xE4che einnimmt.
-		float ScreenToVideoWidth = (float) pGfx->GetDisplayWidth() / (float) m_OutputBitmap->GetWidth();
-		float ScreenToVideoHeight = (float) pGfx->GetDisplayHeight() / (float) m_OutputBitmap->GetHeight();
-		float ScaleFactor = std::min(ScreenToVideoWidth, ScreenToVideoHeight);
-		if (ABS(ScaleFactor - 1.0f) < FLT_EPSILON) ScaleFactor = 1.0f;
-		m_OutputBitmap->SetScaleFactor(ScaleFactor);
-
-		// Z-Wert setzen
-		m_OutputBitmap->SetZ(Z);
-
-		// Ausgabebitmap auf dem Bildschirm zentrieren
-		m_OutputBitmap->SetX((pGfx->GetDisplayWidth() - m_OutputBitmap->GetWidth()) / 2);
-		m_OutputBitmap->SetY((pGfx->GetDisplayHeight() - m_OutputBitmap->GetHeight()) / 2);
-
-		// Buffer f\xFCr die Pixeldaten erstellen
-		m_Pixels.resize(TheoraInfo.width * TheoraInfo.height * 4);
-
-		m_VideoEnded = false;
-	}
-
-	// Vorbis-Decoder initialisieren
-	if(m_VorbisPresent)
-	{
-		VorbisState->SynthesisInit();
-		VorbisState->BlockInit();
-		m_AudioBuffer.reset(new BS_AudioBuffer());
-
-		m_AudioEnded = false;
-	}
-
-	// Keine Kopie, \xFCbertr\xE4gt Besitz der erzeugten Objekte von der Funktion auf das Objekt.
-	m_File = File;
-	m_OggState = OggState;
-	m_TheoraState = TheoraState;
-	m_TheoraStreamState = TheoraStreamState;
-	m_VorbisState = VorbisState;
-	m_VorbisStreamState = VorbisStreamState;
-	m_MovieLoaded = true;
-	m_Timer = 0;
-
-	return true;
-}
-
-// -----------------------------------------------------------------------------
-
-bool BS_OggTheora::UnloadMovie()
-{
-	m_MovieLoaded = false;
-	m_Paused = true;
-
-	m_VorbisStreamState.reset();
-	m_VorbisPresent = false;
-	m_VorbisState.reset();
-	if (m_SoundHandle)
-	{
-		BS_Kernel::GetInstance()->GetSfx()->StopSound(m_SoundHandle);
-		m_SoundHandle = 0;
-	}
-	m_AudioEnded = true;
-	m_AudioBuffer.reset();
-
-	m_TheoraStreamState.reset();
-	m_TheoraPresent = false;
-	m_TheoraState.reset();
-	m_VideoEnded = true;
-
-	m_OggState.reset();
-
-	m_File.reset();
-
-	m_StartTime = 0;
-	m_LastFrameTime = 0;
-	m_Timer = 0.0f;
-
-	vector<unsigned char>().swap(m_Pixels);
-	m_OutputBitmap.Erase();
-
-	return true;
-}
-
-// -----------------------------------------------------------------------------
-
-bool BS_OggTheora::Play()
-{
-	if (m_MovieLoaded)
-	{
-		if (m_Paused)
-		{
-			if (m_SoundHandle)
-			{
-				BS_SoundEngine * SfxPtr = BS_Kernel::GetInstance()->GetSfx();
-				SfxPtr->ResumeSound(m_SoundHandle);
-			}
-			m_Paused = false;
-		}
-
-		return true;
-	}
-	else
-	{
-		BS_LOG_WARNINGLN("Cannot play movie, when no movie is loaded.");
-		return false;
-	}
-}
-
-// -----------------------------------------------------------------------------
-
-bool BS_OggTheora::Pause()
-{
-	if (m_MovieLoaded)
-	{
-		if (m_SoundHandle)
-		{
-			BS_SoundEngine * SfxPtr = BS_Kernel::GetInstance()->GetSfx();
-			SfxPtr->PauseSound(m_SoundHandle);
-		}
-
-		m_Paused = true;
-		return true;
-	}
-	else
-	{
-		BS_LOG_WARNINGLN("Cannot pause movie, when no movie is loaded.");
-		return false;
-	}
-}
-
-// -----------------------------------------------------------------------------
-
-void BS_OggTheora::ReadData()
-{
-	if (!m_File->IsEOF()) m_File->BufferData(*m_OggState.get());
-
-	ogg_page Page;
-	while(m_OggState->SyncPageout(&Page) > 0)
-	{
-		if(m_TheoraPresent) m_TheoraStreamState->BufferPage(&Page);
-		if(m_VorbisPresent) m_VorbisStreamState->BufferPage(&Page);
-	}
-}
-
-void BS_OggTheora::Update()
-{
-	if (m_AudioEnded && m_VideoEnded)
-	{
-		m_Paused = true;
-
-		// Falls der Sound noch l\xE4uft, muss er jetzt beendet werden.
-		if (m_SoundHandle)
-		{
-			BS_SoundEngine * SfxPtr = BS_Kernel::GetInstance()->GetSfx();
-			SfxPtr->StopSound(m_SoundHandle);
-			m_SoundHandle = 0;
-		}
-	}
-
-	if (m_Paused) return;
-
-	// Timer aktualisieren.
-	// Wird nur genutzt, wenn keine Audiodaten vorhanden sind.
-	m_Timer += BS_Kernel::GetInstance()->GetGfx()->GetSecondaryFrameDuration();
-
-	// Audiodaten dekodieren
-	if (m_VorbisPresent && !m_AudioEnded) DecodeVorbis();
-
-
-	// Videodaten dekodieren
-	if (m_TheoraPresent && !m_VideoEnded)
-	{
-		bool Result = DecodeTheora();
-
-		if (Result)
-		{
-			// YUV Framebuffer holen
-			yuv_buffer YUVBuffer;
-			m_TheoraState->DecodeYUVOut(&YUVBuffer);
-
-			// YUV Bilddaten nach RGBA konvertieren
-			BS_YUVtoRGBA::YUVtoRGBA(YUVBuffer, m_TheoraState->GetInfo(), m_Pixels);
-
-			// RGBA Bilddaten auf das Ausgabebild kopieren, dabei die Postion des Theoraframes innerhalb des dekodierten Frames beachten.
-			const theora_info & TheoraInfo = m_TheoraState->GetInfo();
-			m_OutputBitmap->SetContent(m_Pixels, (TheoraInfo.offset_x + TheoraInfo.width * TheoraInfo.offset_y) * 4, (TheoraInfo.width - TheoraInfo.frame_width) * 4);
-		}
-	}
-}
-
-// -----------------------------------------------------------------------------
-
-bool BS_OggTheora::DecodeTheora()
-{
-	double MovieTime = GetTime();
-
-	// Check if this frame time has not passed yet. If the frame is late we need
-	// to decode additonal ones and keep looping, since theora at this stage
-	// needs to decode all frames (due to keyframing)
-	// Getting the current time once at the beginning of the function rather than
-	// every time at the beginning of the loop produces the smoothest framerate
-
-	unsigned int FramesDecoded = 0;
-	bool FrameReady = false;
-	while (m_TheoraState->GranuleTime() < MovieTime)
-	{
-		// theora is one in, one out...
-		ogg_packet Packet;
-		if(m_TheoraStreamState->PacketOut(&Packet) > 0)
-		{
-			if (FramesDecoded < MAX_FRAMES_PER_TICK || Packet.granulepos >= MovieTime)
-			{
-				m_TheoraState->DecodePacketIn(&Packet);
-				FrameReady = true;
-				++FramesDecoded;
-			}
-		}
-		else
-		{
-			if (m_TheoraStreamState->GetPageBufferSize() > 0)
-				m_TheoraStreamState->PageInBufferedPage();
-			else
-			{
-				if(m_File->IsEOF())
-				{
-					m_VideoEnded = true;
-					break;
-				}
-				else
-					ReadData();
-			}
-		}
-	}
-	m_LastFrameTime = MovieTime;
-
-	return FrameReady;
-}
-
-// -----------------------------------------------------------------------------
-
-void BS_OggTheora::DynamicSoundCallBack(void * UserData, void * Data, unsigned int DataLength)
-{
-	BS_OggTheora & t = *reinterpret_cast<BS_OggTheora *>(UserData);
-
-	signed short * Buffer = reinterpret_cast<signed short *>(Data);
-
-	// Audiodaten in den Soundbuffer schreiben.
-	DataLength -= t.m_AudioBuffer->Pop(Buffer, DataLength / 2) * 2;
-
-	// Falls nicht genug Audiodaten vorhanden waren, wird der Rest mit Stille \xFCberschrieben.
-	if (DataLength)
-	{
-		char * ByteBuffer = reinterpret_cast<char *>(Buffer);
-		while (DataLength--)
-		{
-			*ByteBuffer++ = 0;
-		}
-	}
-}
-
-// -----------------------------------------------------------------------------
-
-void BS_OggTheora::DecodeVorbis()
-{
-	// Vorbis-Stream Infos holen.
-	const vorbis_info & Info = m_VorbisState->GetInfo();
-
-	// Maximalgr\xF6\xDFe des Audiobuffers berechnen.
-	size_t MaxAudioBufferSamples = static_cast<size_t>(Info.channels * Info.rate * MAX_AUDIO_BUFFER_LENGTH);
-
-	// Zwischenspeicher f\xFCr die Samples.
-	vector<signed short> Samples;
-
-	// Audiobuffer bis zur Maximalgr\xF6\xDFe f\xFCllen, wenn m\xF6glich.
-	while (m_AudioBuffer->Size() < MaxAudioBufferSamples)
-	{
-		// Vorhandene Audiodaten auslesen
-		float ** PCM;
-		int SampleCount = m_VorbisState->SynthesisPCMout(&PCM);
-
-		// Wenn Audiodaten gelesen werden konnten, werden diese in 16-Bit Sample umgewandelt und in den Audiobuffer geschrieben.
-		if(SampleCount > 0)
-		{
-			// Im Samplezwischenspeicher leeren und gen\xFCgend Platz f\xFCr die kommenden Samples reservieren.
-			Samples.reserve(SampleCount);
-			Samples.clear();
-
-			// Samples konvertieren und in die Samplezwischenspeicher schreiben.
-			for (int i = 0; i < SampleCount; ++i)
-			{
-				for(int j = 0; j < Info.channels; ++j)
-				{
-					int SampleValue = static_cast<int>(PCM[j][i] * 32767.0f);
-					Samples.push_back(Clamp(SampleValue, -32700, 32700));
-				}
-			}
-
-			// Daten aus dem Samplezwischenspeicher in den Audiobuffer schreiben.
-			m_AudioBuffer->Push(&Samples[0], Samples.size());
-
-			// Vorbis mitteilen, dass wir alle Samples gelesen haben.
-			m_VorbisState->SynthesisRead(SampleCount);
-		}
-		else
-		{        
-			// Wir konnten, keine Audiodaten auslesen, versuchen ein neues Paket zu dekodieren.
-			ogg_packet Packet;
-			if(m_VorbisStreamState->PacketOut(&Packet) > 0)
-			{
-				if (m_VorbisState->Synthesis(&Packet) == 0) m_VorbisState->SynthesisBlockIn();
-			}
-			else
-			{
-				// Gepufferte Daten in den Stream einf\xFCgen.
-				if (m_VorbisStreamState->GetPageBufferSize() > 0)
-					m_VorbisStreamState->PageInBufferedPage();
-				else
-				{
-					// Nicht genug Daten vorhanden. Wenn die Datei leer ist und bereits alle Audiodaten gelesen wurden, ist der Audiostream am Ende.
-					// Ansonsten Daten nachladen.
-					if(m_File->IsEOF())
-					{
-						if (m_AudioBuffer->Size() == 0)
-						{
-							m_AudioEnded = true;
-						}
-
-						break;
-					}
-					else
-						ReadData();
-				}
-			}
-		}
-	}
-
-	// Soundkanal abspielen, wenn er noch nicht spielt und Audiodaten vorhanden sind.
-	if (m_SoundHandle == 0 && m_AudioBuffer->Size())
-	{
-		BS_SoundEngine * SfxPtr = BS_Kernel::GetInstance()->GetSfx();
-		m_SoundHandle = SfxPtr->PlayDynamicSoundEx(&DynamicSoundCallBack, this, BS_SoundEngine::SFX, Info.rate, 16, Info.channels);
-	}
-}
-
-// -----------------------------------------------------------------------------
-
-double BS_OggTheora::GetTime()
-{
-	if(m_VorbisPresent)
-	{
-		if (m_SoundHandle)
-		{
-			float time = BS_Kernel::GetInstance()->GetSfx()->GetSoundTime(m_SoundHandle);
-			return time;
-		}
-		else
-			return 0.0f;
-	}
-	else
-		return m_Timer;
-}
-
-// -----------------------------------------------------------------------------
-
-bool BS_OggTheora::IsMovieLoaded()
-{
-	return m_MovieLoaded;
-}
-
-// -----------------------------------------------------------------------------
-
-bool BS_OggTheora::IsPaused()
-{
-	return m_Paused;
-}
-
-// -----------------------------------------------------------------------------
-
-float BS_OggTheora::GetScaleFactor()
-{
-	if (m_MovieLoaded)
-		return m_OutputBitmap->GetScaleFactorX();
-	else
-		return 0;
-}
-
-// -----------------------------------------------------------------------------
-
-void BS_OggTheora::SetScaleFactor(float ScaleFactor)
-{
-	if (m_MovieLoaded)
-	{
-		m_OutputBitmap->SetScaleFactor(ScaleFactor);
-
-		// Ausgabebitmap auf dem Bildschirm zentrieren
-		BS_GraphicEngine * GfxPtr = BS_Kernel::GetInstance()->GetGfx();
-		m_OutputBitmap->SetX((GfxPtr->GetDisplayWidth() - m_OutputBitmap->GetWidth()) / 2);
-		m_OutputBitmap->SetY((GfxPtr->GetDisplayHeight() - m_OutputBitmap->GetHeight()) / 2);
-	}
-}

Deleted: scummvm/trunk/engines/sword25/fmv/oggtheora/oggtheora.h
===================================================================
--- scummvm/trunk/engines/sword25/fmv/oggtheora/oggtheora.h	2010-10-12 23:19:41 UTC (rev 53294)
+++ scummvm/trunk/engines/sword25/fmv/oggtheora/oggtheora.h	2010-10-12 23:20:33 UTC (rev 53295)
@@ -1,124 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-/* 
- * This code is based on Broken Sword 2.5 engine
- *
- * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
- *
- * Licensed under GNU GPL v2
- *
- */
-
-#ifndef SWORD25_OGGTHEORA_H
-#define SWORD25_OGGTHEORA_H
-
-// -----------------------------------------------------------------------------
-// Includes
-// -----------------------------------------------------------------------------
-
-#include "sword25/kernel/memlog_off.h"
-#include <vector>
-#include <memory>
-#include <queue>
-#include "sword25/kernel/memlog_on.h"
-
-#include "sword25/kernel/common.h"
-#include "sword25/kernel/bs_stdint.h"
-#include "sword25/gfx/bitmap.h"
-#include "sword25/gfx/renderobjectptr.h"
-#include "sword25/fmv/movieplayer.h"
-#include "sword25/fmv/oggtheora/vorbisstate.h"
-#include "sword25/fmv/oggtheora/theorastate.h"
-#include "sword25/fmv/oggtheora/oggstate.h"
-#include "sword25/fmv/oggtheora/oggstreamstate.h"
-#include "sword25/fmv/oggtheora/moviefile.h"
-#include "sword25/fmv/oggtheora/audiobuffer.h"
-
-// -----------------------------------------------------------------------------
-// Klassendefinition
-// -----------------------------------------------------------------------------
-
-class BS_OggTheora : public BS_MoviePlayer
-{
-public:
-	// -----------------------------------------------------------------------------
-	// Konstruktion / Destruktion
-	// -----------------------------------------------------------------------------
-
-	BS_OggTheora(BS_Kernel * pKernel);
-	virtual ~BS_OggTheora();
-
-	// -----------------------------------------------------------------------------
-	// BS_MoviePlayer Interface
-	// -----------------------------------------------------------------------------
-
-	virtual bool LoadMovie(const std::string & Filename, unsigned int Z);
-	virtual bool UnloadMovie();
-	virtual bool Play();
-	virtual bool Pause();
-	virtual void Update();
-	virtual bool IsMovieLoaded();
-	virtual bool IsPaused();
-	virtual float GetScaleFactor();
-	virtual void SetScaleFactor(float ScaleFactor);
-	virtual double GetTime();
-
-private:
-	bool	DecodeTheora();
-	void	DecodeVorbis();
-	void	RefillOggBuffer();
-	void	ReadData();
-	static	void DynamicSoundCallBack(void * UserData, void * Data, unsigned int DataLength);
-
-	bool								m_MovieLoaded;
-	bool								m_Paused;
-
-	std::auto_ptr<BS_OggStreamState>	m_VorbisStreamState;
-	bool								m_VorbisPresent;
-	std::auto_ptr<BS_VorbisState>		m_VorbisState;
-	unsigned int						m_SoundHandle;
-	bool								m_AudioEnded;
-	std::auto_ptr<BS_AudioBuffer>		m_AudioBuffer;
-
-	std::auto_ptr<BS_OggStreamState>	m_TheoraStreamState;
-	bool								m_TheoraPresent;
-	std::auto_ptr<BS_TheoraState>		m_TheoraState;
-	bool								m_VideoEnded;
-
-	std::auto_ptr<BS_OggState>			m_OggState;
-
-	std::auto_ptr<BS_MovieFile>			m_File;
-
-	uint64_t							m_StartTime;
-	double								m_LastFrameTime;
-
-	float								m_Timer;
-
-	std::vector<unsigned char>			m_Pixels;
-	BS_RenderObjectPtr<BS_Bitmap>		m_OutputBitmap;
-};
-
-#endif

Modified: scummvm/trunk/engines/sword25/fmv/oggtheora/theorastate.cpp
===================================================================
--- scummvm/trunk/engines/sword25/fmv/oggtheora/theorastate.cpp	2010-10-12 23:19:41 UTC (rev 53294)
+++ scummvm/trunk/engines/sword25/fmv/oggtheora/theorastate.cpp	2010-10-12 23:20:33 UTC (rev 53295)
@@ -38,19 +38,19 @@
 
 #include "sword25/fmv/oggtheora/theorastate.h"
 
+namespace Sword25 {
+
 // -----------------------------------------------------------------------------
 
-BS_TheoraState::BS_TheoraState() :
-	m_StateInitialized(false)
-{
+TheoraState::TheoraState() :
+		m_StateInitialized(false) {
 	theora_comment_init(&m_Comment);
 	theora_info_init(&m_Info);
 }
 
 // -----------------------------------------------------------------------------
 
-BS_TheoraState::~BS_TheoraState()
-{
+TheoraState::~TheoraState() {
 	if (m_StateInitialized) theora_clear(&m_State);
 	theora_info_clear(&m_Info);
 	theora_comment_clear(&m_Comment);
@@ -58,15 +58,13 @@
 
 // -----------------------------------------------------------------------------
 
-int BS_TheoraState::DecodeHeader(ogg_packet * OggPacketPtr)
-{
+int TheoraState::DecodeHeader(ogg_packet *OggPacketPtr) {
 	return theora_decode_header(&m_Info, &m_Comment, OggPacketPtr);
 }
 
 // -----------------------------------------------------------------------------
 
-int BS_TheoraState::DecodeInit()
-{
+int TheoraState::DecodeInit() {
 	int Result = theora_decode_init(&m_State, &m_Info);
 	m_StateInitialized = (Result == 0);
 	return Result;
@@ -74,21 +72,20 @@
 
 // -----------------------------------------------------------------------------
 
-double BS_TheoraState::GranuleTime()
-{
+double TheoraState::GranuleTime() {
 	return theora_granule_time(&m_State, m_State.granulepos);
 }
 
 // -----------------------------------------------------------------------------
 
-int BS_TheoraState::DecodePacketIn(ogg_packet * OggPacketPtr)
-{
+int TheoraState::DecodePacketIn(ogg_packet *OggPacketPtr) {
 	return theora_decode_packetin(&m_State, OggPacketPtr);
 }
 
 // -----------------------------------------------------------------------------
 
-int BS_TheoraState::DecodeYUVOut(yuv_buffer * YUV)
-{
+int TheoraState::DecodeYUVOut(yuv_buffer *YUV) {
 	return theora_decode_YUVout(&m_State, YUV);
 }
+
+} // End of namespace Sword25

Modified: scummvm/trunk/engines/sword25/fmv/oggtheora/theorastate.h
===================================================================
--- scummvm/trunk/engines/sword25/fmv/oggtheora/theorastate.h	2010-10-12 23:19:41 UTC (rev 53294)
+++ scummvm/trunk/engines/sword25/fmv/oggtheora/theorastate.h	2010-10-12 23:20:33 UTC (rev 53295)
@@ -42,20 +42,21 @@
 #include "sword25/kernel/common.h"
 #include <theora/theora.h>
 
+namespace Sword25 {
+
 // -----------------------------------------------------------------------------
-// Klassendefinition
+// Class definitions
 // -----------------------------------------------------------------------------
 
-class BS_TheoraState
-{
+class TheoraState {
 public:
-	BS_TheoraState();
-	virtual ~BS_TheoraState();
+	TheoraState();
+	virtual ~TheoraState();
 
-	int		DecodeHeader(ogg_packet * OggPacketPtr);
+	int		DecodeHeader(ogg_packet *OggPacketPtr);
 	int		DecodeInit();
-	int		DecodePacketIn(ogg_packet * OggPacketPtr);
-	int		DecodeYUVOut(yuv_buffer * YUV);
+	int		DecodePacketIn(ogg_packet *OggPacketPtr);
+	int		DecodeYUVOut(yuv_buffer *YUV);
 	double	GranuleTime();
 
 	const theora_info & GetInfo() const { return m_Info; }
@@ -67,4 +68,6 @@
 	theora_state				m_State;
 };
 
+} // End of namespace Sword25
+
 #endif

Modified: scummvm/trunk/engines/sword25/fmv/oggtheora/vorbisstate.cpp
===================================================================
--- scummvm/trunk/engines/sword25/fmv/oggtheora/vorbisstate.cpp	2010-10-12 23:19:41 UTC (rev 53294)
+++ scummvm/trunk/engines/sword25/fmv/oggtheora/vorbisstate.cpp	2010-10-12 23:20:33 UTC (rev 53295)
@@ -38,20 +38,20 @@
 
 #include "sword25/fmv/oggtheora/vorbisstate.h"
 
+namespace Sword25 {
+
 // -----------------------------------------------------------------------------
 
-BS_VorbisState::BS_VorbisState() :
-	m_DSPStateInitialized(false),
-	m_BlockInitialized(false)
-{
+VorbisState::VorbisState() :
+		m_DSPStateInitialized(false),
+		m_BlockInitialized(false) {
 	vorbis_info_init(&m_Info);
 	vorbis_comment_init(&m_Comment);
 }
 
 // -----------------------------------------------------------------------------
 
-BS_VorbisState::~BS_VorbisState()
-{
+VorbisState::~VorbisState() {
 	if (m_BlockInitialized) vorbis_block_clear(&m_Block);
 	if (m_DSPStateInitialized) vorbis_dsp_clear(&m_DSPState);
 	vorbis_comment_clear(&m_Comment);
@@ -60,15 +60,13 @@
 
 // -----------------------------------------------------------------------------
 
-int BS_VorbisState::SynthesisHeaderIn(ogg_packet * OggPacketPtr)
-{
+int VorbisState::SynthesisHeaderIn(ogg_packet *OggPacketPtr) {
 	return vorbis_synthesis_headerin(&m_Info, &m_Comment, OggPacketPtr);
 }
 
 // -----------------------------------------------------------------------------
 
-int BS_VorbisState::SynthesisInit()
-{
+int VorbisState::SynthesisInit() {
 	int Result = vorbis_synthesis_init(&m_DSPState, &m_Info);
 	m_DSPStateInitialized = (Result == 0);
 	return Result;
@@ -76,8 +74,7 @@
 
 // -----------------------------------------------------------------------------
 
-int BS_VorbisState::BlockInit()
-{
+int VorbisState::BlockInit() {
 	int Result = vorbis_block_init(&m_DSPState, &m_Block);
 	m_BlockInitialized = (Result == 0);
 	return Result;
@@ -85,28 +82,26 @@
 
 // -----------------------------------------------------------------------------
 
-int BS_VorbisState::SynthesisPCMout(float *** PCM)
-{
+int VorbisState::SynthesisPCMout(float ***PCM) {
 	return vorbis_synthesis_pcmout(&m_DSPState, PCM);
 }
 
 // -----------------------------------------------------------------------------
 
-int BS_VorbisState::SynthesisRead(int Samples)
-{
+int VorbisState::SynthesisRead(int Samples) {
 	return vorbis_synthesis_read(&m_DSPState, Samples);
 }
 
 // -----------------------------------------------------------------------------
 
-int BS_VorbisState::Synthesis(ogg_packet * OggPacketPtr)
-{
+int VorbisState::Synthesis(ogg_packet *OggPacketPtr) {
 	return vorbis_synthesis(&m_Block, OggPacketPtr);
 }
 
 // -----------------------------------------------------------------------------
 
-int BS_VorbisState::SynthesisBlockIn()
-{
+int VorbisState::SynthesisBlockIn() {
 	return vorbis_synthesis_blockin(&m_DSPState, &m_Block);
 }
+
+} // End of namespace Sword25

Modified: scummvm/trunk/engines/sword25/fmv/oggtheora/vorbisstate.h
===================================================================
--- scummvm/trunk/engines/sword25/fmv/oggtheora/vorbisstate.h	2010-10-12 23:19:41 UTC (rev 53294)
+++ scummvm/trunk/engines/sword25/fmv/oggtheora/vorbisstate.h	2010-10-12 23:20:33 UTC (rev 53295)
@@ -42,25 +42,26 @@
 #include "sword25/kernel/common.h"
 #include <vorbis/codec.h>
 
+namespace Sword25 {
+
 // -----------------------------------------------------------------------------
-// Klassendefinition
+// Class definitions
 // -----------------------------------------------------------------------------
 
-class BS_VorbisState
-{
+class VorbisState {
 public:
-	BS_VorbisState();
-	virtual ~BS_VorbisState();
+	VorbisState();
+	virtual ~VorbisState();
 
-	int	SynthesisHeaderIn(ogg_packet * OggPacketPtr);
+	int	SynthesisHeaderIn(ogg_packet *OggPacketPtr);
 	int SynthesisInit();
 	int BlockInit();
-	int SynthesisPCMout(float *** PCM);
+	int SynthesisPCMout(float ***PCM);
 	int SynthesisRead(int Samples);
-	int Synthesis(ogg_packet * OggPacketPtr);
+	int Synthesis(ogg_packet *OggPacketPtr);
 	int SynthesisBlockIn();
 
-	const vorbis_info & GetInfo() const { return m_Info; }
+	const vorbis_info &GetInfo() const { return m_Info; }
 
 private:
 	vorbis_info					m_Info;
@@ -71,4 +72,6 @@
 	vorbis_comment				m_Comment;
 };
 
+} // End of namespace Sword25
+
 #endif

Modified: scummvm/trunk/engines/sword25/fmv/oggtheora/yuvtorgba.cpp
===================================================================
--- scummvm/trunk/engines/sword25/fmv/oggtheora/yuvtorgba.cpp	2010-10-12 23:19:41 UTC (rev 53294)
+++ scummvm/trunk/engines/sword25/fmv/oggtheora/yuvtorgba.cpp	2010-10-12 23:20:33 UTC (rev 53295)
@@ -36,396 +36,213 @@
 // Includes
 // -----------------------------------------------------------------------------
 
-#include "sword25/kernel/cpuinfo.h"
-#include "sword25/fmv/ogghteora/yuvtorgba.h"
+#include "sword25/fmv/oggtheora/yuvtorgba.h"
 
-#include <mmintrin.h>
-
-using namespace std;
-
 // -----------------------------------------------------------------------------
 
-namespace 
-{
+namespace Sword25 {
 
-	static const int PRECISION = 32768;
-	static const int COEFFS_Y[256] = {
-		-593888, -555746, -517604, -479462, -441320, -403178, -365036, -326894, -288752, -250610, -212468, -174326, -136184,  -98042,  -59900,  -21758, 
-		  16384,   54526,   92668,  130810,  168952,  207094,  245236,  283378,  321520,  359662,  397804,  435946,  474088,  512230,  550372,  588514, 
-		 626656,  664798,  702940,  741082,  779224,  817366,  855508,  893650,  931792,  969934, 1008076, 1046218, 1084360, 1122502, 1160644, 1198786, 
-		1236928, 1275070, 1313212, 1351354, 1389496, 1427638, 1465780, 1503922, 1542064, 1580206, 1618348, 1656490, 1694632, 1732774, 1770916, 1809058, 
-		1847200, 1885342, 1923484, 1961626, 1999768, 2037910, 2076052, 2114194, 2152336, 2190478, 2228620, 2266762, 2304904, 2343046, 2381188, 2419330, 
-		2457472, 2495614, 2533756, 2571898, 2610040, 2648182, 2686324, 2724466, 2762608, 2800750, 2838892, 2877034, 2915176, 2953318, 2991460, 3029602, 
-		3067744, 3105886, 3144028, 3182170, 3220312, 3258454, 3296596, 3334738, 3372880, 3411022, 3449164, 3487306, 3525448, 3563590, 3601732, 3639874, 
-		3678016, 3716158, 3754300, 3792442, 3830584, 3868726, 3906868, 3945010, 3983152, 4021294, 4059436, 4097578, 4135720, 4173862, 4212004, 4250146, 
-		4288288, 4326430, 4364572, 4402714, 4440856, 4478998, 4517140, 4555282, 4593424, 4631566, 4669708, 4707850, 4745992, 4784134, 4822276, 4860418, 
-		4898560, 4936702, 4974844, 5012986, 5051128, 5089270, 5127412, 5165554, 5203696, 5241838, 5279980, 5318122, 5356264, 5394406, 5432548, 5470690, 
-		5508832, 5546974, 5585116, 5623258, 5661400, 5699542, 5737684, 5775826, 5813968, 5852110, 5890252, 5928394, 5966536, 6004678, 6042820, 6080962, 
-		6119104, 6157246, 6195388, 6233530, 6271672, 6309814, 6347956, 6386098, 6424240, 6462382, 6500524, 6538666, 6576808, 6614950, 6653092, 6691234, 
-		6729376, 6767518, 6805660, 6843802, 6881944, 6920086, 6958228, 6996370, 7034512, 7072654, 7110796, 7148938, 7187080, 7225222, 7263364, 7301506, 
-		7339648, 7377790, 7415932, 7454074, 7492216, 7530358, 7568500, 7606642, 7644784, 7682926, 7721068, 7759210, 7797352, 7835494, 7873636, 7911778, 
-		7949920, 7988062, 8026204, 8064346, 8102488, 8140630, 8178772, 8216914, 8255056, 8293198, 8331340, 8369482, 8407624, 8445766, 8483908, 8522050, 
-		8560192, 8598334, 8636476, 8674618, 8712760, 8750902, 8789044, 8827186, 8865328, 8903470, 8941612, 8979754, 9017896, 9056038, 9094180, 9132322, 
-	};
-	static const int COEFFS_RV[256] = {
-		-6694144, -6641846, -6589548, -6537250, -6484952, -6432654, -6380356, -6328058, -6275760, -6223462, -6171164, -6118866, -6066568, -6014270, -5961972, -5909674, 
-		-5857376, -5805078, -5752780, -5700482, -5648184, -5595886, -5543588, -5491290, -5438992, -5386694, -5334396, -5282098, -5229800, -5177502, -5125204, -5072906, 
-		-5020608, -4968310, -4916012, -4863714, -4811416, -4759118, -4706820, -4654522, -4602224, -4549926, -4497628, -4445330, -4393032, -4340734, -4288436, -4236138, 
-		-4183840, -4131542, -4079244, -4026946, -3974648, -3922350, -3870052, -3817754, -3765456, -3713158, -3660860, -3608562, -3556264, -3503966, -3451668, -3399370, 
-		-3347072, -3294774, -3242476, -3190178, -3137880, -3085582, -3033284, -2980986, -2928688, -2876390, -2824092, -2771794, -2719496, -2667198, -2614900, -2562602, 
-		-2510304, -2458006, -2405708, -2353410, -2301112, -2248814, -2196516, -2144218, -2091920, -2039622, -1987324, -1935026, -1882728, -1830430, -1778132, -1725834, 
-		-1673536, -1621238, -1568940, -1516642, -1464344, -1412046, -1359748, -1307450, -1255152, -1202854, -1150556, -1098258, -1045960,  -993662,  -941364,  -889066, 
-		 -836768,  -784470,  -732172,  -679874,  -627576,  -575278,  -522980,  -470682,  -418384,  -366086,  -313788,  -261490,  -209192,  -156894,  -104596,   -52298, 
-			   0,    52298,   104596,   156894,   209192,   261490,   313788,   366086,   418384,   470682,   522980,   575278,   627576,   679874,   732172,   784470, 
-		  836768,   889066,   941364,   993662,  1045960,  1098258,  1150556,  1202854,  1255152,  1307450,  1359748,  1412046,  1464344,  1516642,  1568940,  1621238, 
-		 1673536,  1725834,  1778132,  1830430,  1882728,  1935026,  1987324,  2039622,  2091920,  2144218,  2196516,  2248814,  2301112,  2353410,  2405708,  2458006, 
-		 2510304,  2562602,  2614900,  2667198,  2719496,  2771794,  2824092,  2876390,  2928688,  2980986,  3033284,  3085582,  3137880,  3190178,  3242476,  3294774, 
-		 3347072,  3399370,  3451668,  3503966,  3556264,  3608562,  3660860,  3713158,  3765456,  3817754,  3870052,  3922350,  3974648,  4026946,  4079244,  4131542, 
-		 4183840,  4236138,  4288436,  4340734,  4393032,  4445330,  4497628,  4549926,  4602224,  4654522,  4706820,  4759118,  4811416,  4863714,  4916012,  4968310, 
-		 5020608,  5072906,  5125204,  5177502,  5229800,  5282098,  5334396,  5386694,  5438992,  5491290,  5543588,  5595886,  5648184,  5700482,  5752780,  5805078, 
-		 5857376,  5909674,  5961972,  6014270,  6066568,  6118866,  6171164,  6223462,  6275760,  6328058,  6380356,  6432654,  6484952,  6537250,  6589548,  6641846, 
-	};
-	static const int COEFFS_GU[256] = {
-		 1639936,  1627124,  1614312,  1601500,  1588688,  1575876,  1563064,  1550252,  1537440,  1524628,  1511816,  1499004,  1486192,  1473380,  1460568,  1447756, 
-		 1434944,  1422132,  1409320,  1396508,  1383696,  1370884,  1358072,  1345260,  1332448,  1319636,  1306824,  1294012,  1281200,  1268388,  1255576,  1242764, 
-		 1229952,  1217140,  1204328,  1191516,  1178704,  1165892,  1153080,  1140268,  1127456,  1114644,  1101832,  1089020,  1076208,  1063396,  1050584,  1037772, 
-		 1024960,  1012148,   999336,   986524,   973712,   960900,   948088,   935276,   922464,   909652,   896840,   884028,   871216,   858404,   845592,   832780, 
-		  819968,   807156,   794344,   781532,   768720,   755908,   743096,   730284,   717472,   704660,   691848,   679036,   666224,   653412,   640600,   627788, 
-		  614976,   602164,   589352,   576540,   563728,   550916,   538104,   525292,   512480,   499668,   486856,   474044,   461232,   448420,   435608,   422796, 
-		  409984,   397172,   384360,   371548,   358736,   345924,   333112,   320300,   307488,   294676,   281864,   269052,   256240,   243428,   230616,   217804, 
-		  204992,   192180,   179368,   166556,   153744,   140932,   128120,   115308,   102496,    89684,    76872,    64060,    51248,    38436,    25624,    12812, 
-			   0,   -12812,   -25624,   -38436,   -51248,   -64060,   -76872,   -89684,  -102496,  -115308,  -128120,  -140932,  -153744,  -166556,  -179368,  -192180, 
-		 -204992,  -217804,  -230616,  -243428,  -256240,  -269052,  -281864,  -294676,  -307488,  -320300,  -333112,  -345924,  -358736,  -371548,  -384360,  -397172, 
-		 -409984,  -422796,  -435608,  -448420,  -461232,  -474044,  -486856,  -499668,  -512480,  -525292,  -538104,  -550916,  -563728,  -576540,  -589352,  -602164, 
-		 -614976,  -627788,  -640600,  -653412,  -666224,  -679036,  -691848,  -704660,  -717472,  -730284,  -743096,  -755908,  -768720,  -781532,  -794344,  -807156, 
-		 -819968,  -832780,  -845592,  -858404,  -871216,  -884028,  -896840,  -909652,  -922464,  -935276,  -948088,  -960900,  -973712,  -986524,  -999336, -1012148, 
-		-1024960, -1037772, -1050584, -1063396, -1076208, -1089020, -1101832, -1114644, -1127456, -1140268, -1153080, -1165892, -1178704, -1191516, -1204328, -1217140, 
-		-1229952, -1242764, -1255576, -1268388, -1281200, -1294012, -1306824, -1319636, -1332448, -1345260, -1358072, -1370884, -1383696, -1396508, -1409320, -1422132, 
-		-1434944, -1447756, -1460568, -1473380, -1486192, -1499004, -1511816, -1524628, -1537440, -1550252, -1563064, -1575876, -1588688, -1601500, -1614312, -1627124, 
-	};
-	static const int COEFFS_GV[256] = {
-		 3409920,  3383280,  3356640,  3330000,  3303360,  3276720,  3250080,  3223440,  3196800,  3170160,  3143520,  3116880,  3090240,  3063600,  3036960,  3010320, 
-		 2983680,  2957040,  2930400,  2903760,  2877120,  2850480,  2823840,  2797200,  2770560,  2743920,  2717280,  2690640,  2664000,  2637360,  2610720,  2584080, 
-		 2557440,  2530800,  2504160,  2477520,  2450880,  2424240,  2397600,  2370960,  2344320,  2317680,  2291040,  2264400,  2237760,  2211120,  2184480,  2157840, 
-		 2131200,  2104560,  2077920,  2051280,  2024640,  1998000,  1971360,  1944720,  1918080,  1891440,  1864800,  1838160,  1811520,  1784880,  1758240,  1731600, 
-		 1704960,  1678320,  1651680,  1625040,  1598400,  1571760,  1545120,  1518480,  1491840,  1465200,  1438560,  1411920,  1385280,  1358640,  1332000,  1305360, 
-		 1278720,  1252080,  1225440,  1198800,  1172160,  1145520,  1118880,  1092240,  1065600,  1038960,  1012320,   985680,   959040,   932400,   905760,   879120, 
-		  852480,   825840,   799200,   772560,   745920,   719280,   692640,   666000,   639360,   612720,   586080,   559440,   532800,   506160,   479520,   452880, 
-		  426240,   399600,   372960,   346320,   319680,   293040,   266400,   239760,   213120,   186480,   159840,   133200,   106560,    79920,    53280,    26640, 
-			   0,   -26640,   -53280,   -79920,  -106560,  -133200,  -159840,  -186480,  -213120,  -239760,  -266400,  -293040,  -319680,  -346320,  -372960,  -399600, 
-		 -426240,  -452880,  -479520,  -506160,  -532800,  -559440,  -586080,  -612720,  -639360,  -666000,  -692640,  -719280,  -745920,  -772560,  -799200,  -825840, 
-		 -852480,  -879120,  -905760,  -932400,  -959040,  -985680, -1012320, -1038960, -1065600, -1092240, -1118880, -1145520, -1172160, -1198800, -1225440, -1252080, 
-		-1278720, -1305360, -1332000, -1358640, -1385280, -1411920, -1438560, -1465200, -1491840, -1518480, -1545120, -1571760, -1598400, -1625040, -1651680, -1678320, 
-		-1704960, -1731600, -1758240, -1784880, -1811520, -1838160, -1864800, -1891440, -1918080, -1944720, -1971360, -1998000, -2024640, -2051280, -2077920, -2104560, 
-		-2131200, -2157840, -2184480, -2211120, -2237760, -2264400, -2291040, -2317680, -2344320, -2370960, -2397600, -2424240, -2450880, -2477520, -2504160, -2530800, 
-		-2557440, -2584080, -2610720, -2637360, -2664000, -2690640, -2717280, -2743920, -2770560, -2797200, -2823840, -2850480, -2877120, -2903760, -2930400, -2957040, 
-		-2983680, -3010320, -3036960, -3063600, -3090240, -3116880, -3143520, -3170160, -3196800, -3223440, -3250080, -3276720, -3303360, -3330000, -3356640, -3383280, 
-	};
-	static const int COEFFS_BU[256] = {
-		-8464128, -8398002, -8331876, -8265750, -8199624, -8133498, -8067372, -8001246, -7935120, -7868994, -7802868, -7736742, -7670616, -7604490, -7538364, -7472238, 
-		-7406112, -7339986, -7273860, -7207734, -7141608, -7075482, -7009356, -6943230, -6877104, -6810978, -6744852, -6678726, -6612600, -6546474, -6480348, -6414222, 
-		-6348096, -6281970, -6215844, -6149718, -6083592, -6017466, -5951340, -5885214, -5819088, -5752962, -5686836, -5620710, -5554584, -5488458, -5422332, -5356206, 
-		-5290080, -5223954, -5157828, -5091702, -5025576, -4959450, -4893324, -4827198, -4761072, -4694946, -4628820, -4562694, -4496568, -4430442, -4364316, -4298190, 
-		-4232064, -4165938, -4099812, -4033686, -3967560, -3901434, -3835308, -3769182, -3703056, -3636930, -3570804, -3504678, -3438552, -3372426, -3306300, -3240174, 
-		-3174048, -3107922, -3041796, -2975670, -2909544, -2843418, -2777292, -2711166, -2645040, -2578914, -2512788, -2446662, -2380536, -2314410, -2248284, -2182158, 
-		-2116032, -2049906, -1983780, -1917654, -1851528, -1785402, -1719276, -1653150, -1587024, -1520898, -1454772, -1388646, -1322520, -1256394, -1190268, -1124142, 
-		-1058016,  -991890,  -925764,  -859638,  -793512,  -727386,  -661260,  -595134,  -529008,  -462882,  -396756,  -330630,  -264504,  -198378,  -132252,   -66126, 
-			   0,    66126,   132252,   198378,   264504,   330630,   396756,   462882,   529008,   595134,   661260,   727386,   793512,   859638,   925764,   991890, 
-		 1058016,  1124142,  1190268,  1256394,  1322520,  1388646,  1454772,  1520898,  1587024,  1653150,  1719276,  1785402,  1851528,  1917654,  1983780,  2049906, 
-		 2116032,  2182158,  2248284,  2314410,  2380536,  2446662,  2512788,  2578914,  2645040,  2711166,  2777292,  2843418,  2909544,  2975670,  3041796,  3107922, 
-		 3174048,  3240174,  3306300,  3372426,  3438552,  3504678,  3570804,  3636930,  3703056,  3769182,  3835308,  3901434,  3967560,  4033686,  4099812,  4165938, 
-		 4232064,  4298190,  4364316,  4430442,  4496568,  4562694,  4628820,  4694946,  4761072,  4827198,  4893324,  4959450,  5025576,  5091702,  5157828,  5223954, 
-		 5290080,  5356206,  5422332,  5488458,  5554584,  5620710,  5686836,  5752962,  5819088,  5885214,  5951340,  6017466,  6083592,  6149718,  6215844,  6281970, 
-		 6348096,  6414222,  6480348,  6546474,  6612600,  6678726,  6744852,  6810978,  6877104,  6943230,  7009356,  7075482,  7141608,  7207734,  7273860,  7339986, 
-		 7406112,  7472238,  7538364,  7604490,  7670616,  7736742,  7802868,  7868994,  7935120,  8001246,  8067372,  8133498,  8199624,  8265750,  8331876,  8398002, 
-	};
-	static const int CLAMP_TAB[1024] = {
-		  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 
-		  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 
-		  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 
-		  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 
-		  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 
-		  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 
-		  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 
-		  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 
-		  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 
-		  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 
-		  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31, 
-		 32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63, 
-		 64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95, 
-		 96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 
-		128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 
-		160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 
-		192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 
-		224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 
-		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
-		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
-		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
-		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
-		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
-		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
-		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
-		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
-		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
-		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
-		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
-		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
-		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
-		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
-	};
+static const int PRECISION = 32768;
+static const int COEFFS_Y[256] = {
+	-593888, -555746, -517604, -479462, -441320, -403178, -365036, -326894, -288752, -250610, -212468, -174326, -136184,  -98042,  -59900,  -21758, 
+	  16384,   54526,   92668,  130810,  168952,  207094,  245236,  283378,  321520,  359662,  397804,  435946,  474088,  512230,  550372,  588514, 
+	 626656,  664798,  702940,  741082,  779224,  817366,  855508,  893650,  931792,  969934, 1008076, 1046218, 1084360, 1122502, 1160644, 1198786, 
+	1236928, 1275070, 1313212, 1351354, 1389496, 1427638, 1465780, 1503922, 1542064, 1580206, 1618348, 1656490, 1694632, 1732774, 1770916, 1809058, 
+	1847200, 1885342, 1923484, 1961626, 1999768, 2037910, 2076052, 2114194, 2152336, 2190478, 2228620, 2266762, 2304904, 2343046, 2381188, 2419330, 
+	2457472, 2495614, 2533756, 2571898, 2610040, 2648182, 2686324, 2724466, 2762608, 2800750, 2838892, 2877034, 2915176, 2953318, 2991460, 3029602, 
+	3067744, 3105886, 3144028, 3182170, 3220312, 3258454, 3296596, 3334738, 3372880, 3411022, 3449164, 3487306, 3525448, 3563590, 3601732, 3639874, 
+	3678016, 3716158, 3754300, 3792442, 3830584, 3868726, 3906868, 3945010, 3983152, 4021294, 4059436, 4097578, 4135720, 4173862, 4212004, 4250146, 
+	4288288, 4326430, 4364572, 4402714, 4440856, 4478998, 4517140, 4555282, 4593424, 4631566, 4669708, 4707850, 4745992, 4784134, 4822276, 4860418, 
+	4898560, 4936702, 4974844, 5012986, 5051128, 5089270, 5127412, 5165554, 5203696, 5241838, 5279980, 5318122, 5356264, 5394406, 5432548, 5470690, 
+	5508832, 5546974, 5585116, 5623258, 5661400, 5699542, 5737684, 5775826, 5813968, 5852110, 5890252, 5928394, 5966536, 6004678, 6042820, 6080962, 
+	6119104, 6157246, 6195388, 6233530, 6271672, 6309814, 6347956, 6386098, 6424240, 6462382, 6500524, 6538666, 6576808, 6614950, 6653092, 6691234, 
+	6729376, 6767518, 6805660, 6843802, 6881944, 6920086, 6958228, 6996370, 7034512, 7072654, 7110796, 7148938, 7187080, 7225222, 7263364, 7301506, 
+	7339648, 7377790, 7415932, 7454074, 7492216, 7530358, 7568500, 7606642, 7644784, 7682926, 7721068, 7759210, 7797352, 7835494, 7873636, 7911778, 
+	7949920, 7988062, 8026204, 8064346, 8102488, 8140630, 8178772, 8216914, 8255056, 8293198, 8331340, 8369482, 8407624, 8445766, 8483908, 8522050, 
+	8560192, 8598334, 8636476, 8674618, 8712760, 8750902, 8789044, 8827186, 8865328, 8903470, 8941612, 8979754, 9017896, 9056038, 9094180, 9132322, 
+};
+static const int COEFFS_RV[256] = {
+	-6694144, -6641846, -6589548, -6537250, -6484952, -6432654, -6380356, -6328058, -6275760, -6223462, -6171164, -6118866, -6066568, -6014270, -5961972, -5909674, 
+	-5857376, -5805078, -5752780, -5700482, -5648184, -5595886, -5543588, -5491290, -5438992, -5386694, -5334396, -5282098, -5229800, -5177502, -5125204, -5072906, 
+	-5020608, -4968310, -4916012, -4863714, -4811416, -4759118, -4706820, -4654522, -4602224, -4549926, -4497628, -4445330, -4393032, -4340734, -4288436, -4236138, 
+	-4183840, -4131542, -4079244, -4026946, -3974648, -3922350, -3870052, -3817754, -3765456, -3713158, -3660860, -3608562, -3556264, -3503966, -3451668, -3399370, 
+	-3347072, -3294774, -3242476, -3190178, -3137880, -3085582, -3033284, -2980986, -2928688, -2876390, -2824092, -2771794, -2719496, -2667198, -2614900, -2562602, 
+	-2510304, -2458006, -2405708, -2353410, -2301112, -2248814, -2196516, -2144218, -2091920, -2039622, -1987324, -1935026, -1882728, -1830430, -1778132, -1725834, 
+	-1673536, -1621238, -1568940, -1516642, -1464344, -1412046, -1359748, -1307450, -1255152, -1202854, -1150556, -1098258, -1045960,  -993662,  -941364,  -889066, 
+	 -836768,  -784470,  -732172,  -679874,  -627576,  -575278,  -522980,  -470682,  -418384,  -366086,  -313788,  -261490,  -209192,  -156894,  -104596,   -52298, 
+		   0,    52298,   104596,   156894,   209192,   261490,   313788,   366086,   418384,   470682,   522980,   575278,   627576,   679874,   732172,   784470, 
+	  836768,   889066,   941364,   993662,  1045960,  1098258,  1150556,  1202854,  1255152,  1307450,  1359748,  1412046,  1464344,  1516642,  1568940,  1621238, 
+	 1673536,  1725834,  1778132,  1830430,  1882728,  1935026,  1987324,  2039622,  2091920,  2144218,  2196516,  2248814,  2301112,  2353410,  2405708,  2458006, 
+	 2510304,  2562602,  2614900,  2667198,  2719496,  2771794,  2824092,  2876390,  2928688,  2980986,  3033284,  3085582,  3137880,  3190178,  3242476,  3294774, 
+	 3347072,  3399370,  3451668,  3503966,  3556264,  3608562,  3660860,  3713158,  3765456,  3817754,  3870052,  3922350,  3974648,  4026946,  4079244,  4131542, 
+	 4183840,  4236138,  4288436,  4340734,  4393032,  4445330,  4497628,  4549926,  4602224,  4654522,  4706820,  4759118,  4811416,  4863714,  4916012,  4968310, 
+	 5020608,  5072906,  5125204,  5177502,  5229800,  5282098,  5334396,  5386694,  5438992,  5491290,  5543588,  5595886,  5648184,  5700482,  5752780,  5805078, 
+	 5857376,  5909674,  5961972,  6014270,  6066568,  6118866,  6171164,  6223462,  6275760,  6328058,  6380356,  6432654,  6484952,  6537250,  6589548,  6641846, 
+};
+static const int COEFFS_GU[256] = {
+	 1639936,  1627124,  1614312,  1601500,  1588688,  1575876,  1563064,  1550252,  1537440,  1524628,  1511816,  1499004,  1486192,  1473380,  1460568,  1447756, 
+	 1434944,  1422132,  1409320,  1396508,  1383696,  1370884,  1358072,  1345260,  1332448,  1319636,  1306824,  1294012,  1281200,  1268388,  1255576,  1242764, 
+	 1229952,  1217140,  1204328,  1191516,  1178704,  1165892,  1153080,  1140268,  1127456,  1114644,  1101832,  1089020,  1076208,  1063396,  1050584,  1037772, 
+	 1024960,  1012148,   999336,   986524,   973712,   960900,   948088,   935276,   922464,   909652,   896840,   884028,   871216,   858404,   845592,   832780, 
+	  819968,   807156,   794344,   781532,   768720,   755908,   743096,   730284,   717472,   704660,   691848,   679036,   666224,   653412,   640600,   627788, 
+	  614976,   602164,   589352,   576540,   563728,   550916,   538104,   525292,   512480,   499668,   486856,   474044,   461232,   448420,   435608,   422796, 
+	  409984,   397172,   384360,   371548,   358736,   345924,   333112,   320300,   307488,   294676,   281864,   269052,   256240,   243428,   230616,   217804, 
+	  204992,   192180,   179368,   166556,   153744,   140932,   128120,   115308,   102496,    89684,    76872,    64060,    51248,    38436,    25624,    12812, 
+		   0,   -12812,   -25624,   -38436,   -51248,   -64060,   -76872,   -89684,  -102496,  -115308,  -128120,  -140932,  -153744,  -166556,  -179368,  -192180, 
+	 -204992,  -217804,  -230616,  -243428,  -256240,  -269052,  -281864,  -294676,  -307488,  -320300,  -333112,  -345924,  -358736,  -371548,  -384360,  -397172, 
+	 -409984,  -422796,  -435608,  -448420,  -461232,  -474044,  -486856,  -499668,  -512480,  -525292,  -538104,  -550916,  -563728,  -576540,  -589352,  -602164, 
+	 -614976,  -627788,  -640600,  -653412,  -666224,  -679036,  -691848,  -704660,  -717472,  -730284,  -743096,  -755908,  -768720,  -781532,  -794344,  -807156, 
+	 -819968,  -832780,  -845592,  -858404,  -871216,  -884028,  -896840,  -909652,  -922464,  -935276,  -948088,  -960900,  -973712,  -986524,  -999336, -1012148, 
+	-1024960, -1037772, -1050584, -1063396, -1076208, -1089020, -1101832, -1114644, -1127456, -1140268, -1153080, -1165892, -1178704, -1191516, -1204328, -1217140, 
+	-1229952, -1242764, -1255576, -1268388, -1281200, -1294012, -1306824, -1319636, -1332448, -1345260, -1358072, -1370884, -1383696, -1396508, -1409320, -1422132, 
+	-1434944, -1447756, -1460568, -1473380, -1486192, -1499004, -1511816, -1524628, -1537440, -1550252, -1563064, -1575876, -1588688, -1601500, -1614312, -1627124, 
+};
+static const int COEFFS_GV[256] = {
+	 3409920,  3383280,  3356640,  3330000,  3303360,  3276720,  3250080,  3223440,  3196800,  3170160,  3143520,  3116880,  3090240,  3063600,  3036960,  3010320, 
+	 2983680,  2957040,  2930400,  2903760,  2877120,  2850480,  2823840,  2797200,  2770560,  2743920,  2717280,  2690640,  2664000,  2637360,  2610720,  2584080, 
+	 2557440,  2530800,  2504160,  2477520,  2450880,  2424240,  2397600,  2370960,  2344320,  2317680,  2291040,  2264400,  2237760,  2211120,  2184480,  2157840, 
+	 2131200,  2104560,  2077920,  2051280,  2024640,  1998000,  1971360,  1944720,  1918080,  1891440,  1864800,  1838160,  1811520,  1784880,  1758240,  1731600, 
+	 1704960,  1678320,  1651680,  1625040,  1598400,  1571760,  1545120,  1518480,  1491840,  1465200,  1438560,  1411920,  1385280,  1358640,  1332000,  1305360, 
+	 1278720,  1252080,  1225440,  1198800,  1172160,  1145520,  1118880,  1092240,  1065600,  1038960,  1012320,   985680,   959040,   932400,   905760,   879120, 
+	  852480,   825840,   799200,   772560,   745920,   719280,   692640,   666000,   639360,   612720,   586080,   559440,   532800,   506160,   479520,   452880, 
+	  426240,   399600,   372960,   346320,   319680,   293040,   266400,   239760,   213120,   186480,   159840,   133200,   106560,    79920,    53280,    26640, 
+		   0,   -26640,   -53280,   -79920,  -106560,  -133200,  -159840,  -186480,  -213120,  -239760,  -266400,  -293040,  -319680,  -346320,  -372960,  -399600, 
+	 -426240,  -452880,  -479520,  -506160,  -532800,  -559440,  -586080,  -612720,  -639360,  -666000,  -692640,  -719280,  -745920,  -772560,  -799200,  -825840, 
+	 -852480,  -879120,  -905760,  -932400,  -959040,  -985680, -1012320, -1038960, -1065600, -1092240, -1118880, -1145520, -1172160, -1198800, -1225440, -1252080, 
+	-1278720, -1305360, -1332000, -1358640, -1385280, -1411920, -1438560, -1465200, -1491840, -1518480, -1545120, -1571760, -1598400, -1625040, -1651680, -1678320, 
+	-1704960, -1731600, -1758240, -1784880, -1811520, -1838160, -1864800, -1891440, -1918080, -1944720, -1971360, -1998000, -2024640, -2051280, -2077920, -2104560, 
+	-2131200, -2157840, -2184480, -2211120, -2237760, -2264400, -2291040, -2317680, -2344320, -2370960, -2397600, -2424240, -2450880, -2477520, -2504160, -2530800, 
+	-2557440, -2584080, -2610720, -2637360, -2664000, -2690640, -2717280, -2743920, -2770560, -2797200, -2823840, -2850480, -2877120, -2903760, -2930400, -2957040, 

@@ Diff output truncated at 100000 characters. @@

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list