Browse files

SWORD25: Importing original sources

svn-id: r53171
  • Loading branch information...
1 parent 7723d91 commit a683a420a9e43705c972b5e74d55e319729e1a81 @sev- sev- committed Jul 29, 2010
Showing with 19,776 additions and 0 deletions.
  1. +36 −0 engines/sword25/fmv/movieplayer.cpp
  2. +138 −0 engines/sword25/fmv/movieplayer.h
  3. +187 −0 engines/sword25/fmv/movieplayer_script.cpp
  4. +93 −0 engines/sword25/fmv/oggtheora/audiobuffer.cpp
  5. +53 −0 engines/sword25/fmv/oggtheora/audiobuffer.h
  6. +90 −0 engines/sword25/fmv/oggtheora/moviefile.cpp
  7. +57 −0 engines/sword25/fmv/oggtheora/moviefile.h
  8. +59 −0 engines/sword25/fmv/oggtheora/oggstate.cpp
  9. +63 −0 engines/sword25/fmv/oggtheora/oggstate.h
  10. +118 −0 engines/sword25/fmv/oggtheora/oggstreamstate.cpp
  11. +74 −0 engines/sword25/fmv/oggtheora/oggstreamstate.h
  12. +709 −0 engines/sword25/fmv/oggtheora/oggtheora.cpp
  13. +109 −0 engines/sword25/fmv/oggtheora/oggtheora.h
  14. +79 −0 engines/sword25/fmv/oggtheora/theorastate.cpp
  15. +55 −0 engines/sword25/fmv/oggtheora/theorastate.h
  16. +97 −0 engines/sword25/fmv/oggtheora/vorbisstate.cpp
  17. +59 −0 engines/sword25/fmv/oggtheora/vorbisstate.h
  18. +416 −0 engines/sword25/fmv/oggtheora/yuvtorgba.cpp
  19. +44 −0 engines/sword25/fmv/oggtheora/yuvtorgba.h
  20. +878 −0 engines/sword25/gfx/animation.cpp
  21. +209 −0 engines/sword25/gfx/animation.h
  22. +58 −0 engines/sword25/gfx/animationdescription.cpp
  23. +90 −0 engines/sword25/gfx/animationdescription.h
  24. +323 −0 engines/sword25/gfx/animationresource.cpp
  25. +83 −0 engines/sword25/gfx/animationresource.h
  26. +293 −0 engines/sword25/gfx/animationtemplate.cpp
  27. +108 −0 engines/sword25/gfx/animationtemplate.h
  28. +111 −0 engines/sword25/gfx/animationtemplateregistry.cpp
  29. +64 −0 engines/sword25/gfx/animationtemplateregistry.h
  30. +214 −0 engines/sword25/gfx/bitmap.cpp
  31. +167 −0 engines/sword25/gfx/bitmap.h
  32. +54 −0 engines/sword25/gfx/bitmapresource.cpp
  33. +177 −0 engines/sword25/gfx/bitmapresource.h
  34. +191 −0 engines/sword25/gfx/dynamicbitmap.cpp
  35. +71 −0 engines/sword25/gfx/dynamicbitmap.h
  36. +243 −0 engines/sword25/gfx/fontresource.cpp
  37. +104 −0 engines/sword25/gfx/fontresource.h
  38. +53 −0 engines/sword25/gfx/framecounter.cpp
  39. +76 −0 engines/sword25/gfx/framecounter.h
  40. +218 −0 engines/sword25/gfx/graphicengine.cpp
  41. +401 −0 engines/sword25/gfx/graphicengine.h
  42. +1,722 −0 engines/sword25/gfx/graphicengine_script.cpp
  43. +101 −0 engines/sword25/gfx/image/b25sloader.cpp
  44. +52 −0 engines/sword25/gfx/image/b25sloader.h
  45. +208 −0 engines/sword25/gfx/image/image.h
  46. +120 −0 engines/sword25/gfx/image/imageloader.cpp
  47. +358 −0 engines/sword25/gfx/image/imageloader.h
  48. +44 −0 engines/sword25/gfx/image/imageloader_ids.h
  49. +389 −0 engines/sword25/gfx/image/pngloader.cpp
  50. +64 −0 engines/sword25/gfx/image/pngloader.h
  51. +571 −0 engines/sword25/gfx/image/vectorimage.cpp
  52. +167 −0 engines/sword25/gfx/image/vectorimage.h
  53. +198 −0 engines/sword25/gfx/image/vectorimagerenderer.cpp
  54. +76 −0 engines/sword25/gfx/image/vectorimagerenderer.h
  55. +208 −0 engines/sword25/gfx/opengl/glimage.cpp
  56. +85 −0 engines/sword25/gfx/opengl/glimage.h
  57. +133 −0 engines/sword25/gfx/opengl/glvectorimageblit.cpp
  58. +505 −0 engines/sword25/gfx/opengl/openglgfx.cpp
  59. +114 −0 engines/sword25/gfx/opengl/openglgfx.h
  60. +125 −0 engines/sword25/gfx/opengl/swimage.cpp
  61. +69 −0 engines/sword25/gfx/opengl/swimage.h
  62. +123 −0 engines/sword25/gfx/panel.cpp
  63. +58 −0 engines/sword25/gfx/panel.h
  64. +571 −0 engines/sword25/gfx/renderobject.cpp
  65. +477 −0 engines/sword25/gfx/renderobject.h
  66. +163 −0 engines/sword25/gfx/renderobjectmanager.cpp
  67. +115 −0 engines/sword25/gfx/renderobjectmanager.h
  68. +80 −0 engines/sword25/gfx/renderobjectptr.h
  69. +50 −0 engines/sword25/gfx/renderobjectregistry.cpp
  70. +60 −0 engines/sword25/gfx/renderobjectregistry.h
  71. +53 −0 engines/sword25/gfx/rootrenderobject.h
  72. +202 −0 engines/sword25/gfx/screenshot.cpp
  73. +44 −0 engines/sword25/gfx/screenshot.h
  74. +218 −0 engines/sword25/gfx/staticbitmap.cpp
  75. +69 −0 engines/sword25/gfx/staticbitmap.h
  76. +404 −0 engines/sword25/gfx/text.cpp
  77. +156 −0 engines/sword25/gfx/text.h
  78. +39 −0 engines/sword25/gfx/timedrenderobject.cpp
  79. +57 −0 engines/sword25/gfx/timedrenderobject.h
  80. +36 −0 engines/sword25/input/inputengine.cpp
  81. +291 −0 engines/sword25/input/inputengine.h
  82. +364 −0 engines/sword25/input/inputengine_script.cpp
  83. +401 −0 engines/sword25/input/stdwininput.cpp
  84. +88 −0 engines/sword25/input/stdwininput.h
  85. +17 −0 engines/sword25/kernel/bs_stdint.h
  86. +123 −0 engines/sword25/kernel/callbackregistry.cpp
  87. +62 −0 engines/sword25/kernel/callbackregistry.h
  88. +55 −0 engines/sword25/kernel/common.h
  89. +260 −0 engines/sword25/kernel/cpuinfo.cpp
  90. +128 −0 engines/sword25/kernel/cpuinfo.h
  91. +156 −0 engines/sword25/kernel/debug/debugtools.cpp
  92. +52 −0 engines/sword25/kernel/debug/debugtools.h
  93. +184 −0 engines/sword25/kernel/debug/memorydumper.cpp
  94. +57 −0 engines/sword25/kernel/debug/memorydumper.h
  95. +102 −0 engines/sword25/kernel/filesystemutil.h
  96. +256 −0 engines/sword25/kernel/filesystemutil_win32.cpp
  97. +34 −0 engines/sword25/kernel/hashmap.h
  98. +191 −0 engines/sword25/kernel/inputpersistenceblock.cpp
  99. +71 −0 engines/sword25/kernel/inputpersistenceblock.h
  100. +412 −0 engines/sword25/kernel/kernel.cpp
  101. +344 −0 engines/sword25/kernel/kernel.h
  102. +775 −0 engines/sword25/kernel/kernel_script.cpp
  103. +224 −0 engines/sword25/kernel/log.cpp
  104. +123 −0 engines/sword25/kernel/log.h
Sorry, we could not display the entire diff because too many files (321) changed.
View
36 engines/sword25/fmv/movieplayer.cpp
@@ -0,0 +1,36 @@
+// -----------------------------------------------------------------------------
+// This file is part of Broken Sword 2.5
+// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer
+//
+// Broken Sword 2.5 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.
+//
+// Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "movieplayer.h"
+
+#define BS_LOG_PREFIX "MOVIEPLAYER"
+
+// -----------------------------------------------------------------------------
+
+BS_MoviePlayer::BS_MoviePlayer(BS_Kernel * pKernel) : BS_Service(pKernel)
+{
+ if (!_RegisterScriptBindings())
+ BS_LOG_ERRORLN("Script bindings could not be registered.");
+ else
+ BS_LOGLN("Script bindings registered.");
+}
View
138 engines/sword25/fmv/movieplayer.h
@@ -0,0 +1,138 @@
+// -----------------------------------------------------------------------------
+// This file is part of Broken Sword 2.5
+// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer
+//
+// Broken Sword 2.5 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.
+//
+// Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+// -----------------------------------------------------------------------------
+
+#ifndef BS_MOVIEPLAYER_H
+#define BS_MOVIEPLAYER_H
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "kernel/common.h"
+#include "kernel/service.h"
+
+#include "kernel/memlog_off.h"
+#include <string>
+#include "kernel/memlog_on.h"
+
+// -----------------------------------------------------------------------------
+// Klassendefinition
+// -----------------------------------------------------------------------------
+
+class BS_MoviePlayer : public BS_Service
+{
+public:
+ // -----------------------------------------------------------------------------
+ // Konstruktion / Destruktion
+ // -----------------------------------------------------------------------------
+
+ BS_MoviePlayer(BS_Kernel * pKernel);
+ virtual ~BS_MoviePlayer() {};
+
+ // -----------------------------------------------------------------------------
+ // Abstraktes Interface, muss von jedem MoviePlayer implementiert werden
+ // -----------------------------------------------------------------------------
+
+ /**
+ @brief Lädt eine Filmdatei
+
+ Diese Methode lädt eine Filmdatei und bereitet sie zur Wiedergabe vor.
+ Es kann immer nur eine Filmdatei zur Zeit geladen sein. Falls bereits eine Filmdatei geladen
+ ist, wird diese entladen und nötigenfalls die Wiedergabe gestoppt.
+
+ @param Filename der Dateiname der zu ladenden Filmdatei
+ @param Z gibt die Z Position des Films auf dem Graphik-Hauptlayer an
+ @return Gibt false zurück, wenn beim Laden ein Fehler aufgetreten ist, ansonsten true.
+ */
+ virtual bool LoadMovie(const std::string & Filename, unsigned int Z) = 0;
+
+ /**
+ @brief Entlädt die gerade geladene Filmdatei
+
+ @return Gibt false zurück, wenn beim Entladen ein Fehler aufgetreten ist, ansonsten true.
+ @remark Diese Methode darf nur aufgerufen werden, wenn IsMovieLoaded() true zurückgibt.
+ */
+ virtual bool UnloadMovie() = 0;
+
+ /**
+ @brief Spielt den Film ab.
+
+ Der Film wird unter Beibehaltung der Seitenverhältnisse auf Bildschirmgröße skaliert.<br>
+ Falls der Film mit einem Aufruf von Pause() pausiert wurde, fährt der Film an dieser Stelle fort.
+
+ @return Gibt false zurück, wenn ein Fehler aufgetreten ist, ansonsten true.
+ @remark Diese Methode darf nur aufgerufen werden, wenn IsMovieLoaded() true zurückgibt.
+ */
+ virtual bool Play() = 0;
+
+ /**
+ @brief Pausiert die Filmwiedergabe.
+
+ Bei einem späteren Aufruf von Play() fährt die Wiedergabe an der Stelle fort an der der Film Pausiert wurde.
+
+ @return Gibt false zurück, wenn ein Fehler aufgetreten ist, ansonsten true.
+ @remark Diese Methode darf nur aufgerufen werden, wenn IsMovieLoaded() true zurückgibt.
+ */
+ virtual bool Pause() = 0;
+
+ /**
+ @brief Diese Funktion muss ein mal pro Frame aufgerufen werden.
+ */
+ virtual void Update() = 0;
+
+ /**
+ @brief Gibt zurück, ob ein Film zur Wiedergabe geladen wurde.
+ */
+ virtual bool IsMovieLoaded() = 0;
+
+ /**
+ @brief Gibt zurück, ob die Filmwiedergabe pausiert wurde.
+ @remark Diese Methode darf nur aufgerufen werden, wenn IsMovieLoaded() true zurückgibt.
+ */
+ virtual bool IsPaused() = 0;
+
+ /**
+ @brief Gibt den Faktor zurück um den der geladene Film skaliert wird.
+
+ Beim Laden wird der Skalierungsfaktor automatisch so gewählt, dass der Film die maximal mögliche Bildschirmfläche einnimmt, ohne dass der
+ Film verzerrt wird.
+
+ @return Gibt den Skalierungsfaktor des Filmes zurück.
+ @remark Diese Methode darf nur aufgerufen werden, wenn IsMovieLoaded() true zurückgibt.
+ */
+ virtual float GetScaleFactor() = 0;
+
+ /**
+ @brief Legt den Faktor fest um den der geladene Film skaliert werden soll.
+ @param ScaleFactor der gewünschte Skalierungsfaktor.
+ @remark Diese Methode darf nur aufgerufen werden, wenn IsMovieLoaded() true zurückgibt.
+ */
+ virtual void SetScaleFactor(float ScaleFactor) = 0;
+
+ /**
+ @brief Gibt die aktuelle Abspielposition in Sekunden zurück.
+ @remark Diese Methode darf nur aufgerufen werden, wenn IsMovieLoaded() true zurückgibt.
+ */
+ virtual double GetTime() = 0;
+
+private:
+ bool _RegisterScriptBindings();
+};
+
+#endif
View
187 engines/sword25/fmv/movieplayer_script.cpp
@@ -0,0 +1,187 @@
+// -----------------------------------------------------------------------------
+// This file is part of Broken Sword 2.5
+// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer
+//
+// Broken Sword 2.5 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.
+//
+// Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "kernel/common.h"
+#include "kernel/kernel.h"
+#include "script/script.h"
+#include "script/luabindhelper.h"
+
+#include "movieplayer.h"
+
+namespace
+{
+ // -------------------------------------------------------------------------
+
+ int LoadMovie(lua_State * L)
+ {
+ BS_MoviePlayer * FMVPtr = BS_Kernel::GetInstance()->GetFMV();
+ BS_ASSERT(FMVPtr);
+
+ lua_pushbooleancpp(L, FMVPtr->LoadMovie(luaL_checkstring(L, 1), lua_gettop(L) == 2 ? static_cast<unsigned int>(luaL_checknumber(L, 2)) : 10));
+
+ return 1;
+ }
+
+ // -------------------------------------------------------------------------
+
+ int UnloadMovie(lua_State * L)
+ {
+ BS_MoviePlayer * FMVPtr = BS_Kernel::GetInstance()->GetFMV();
+ BS_ASSERT(FMVPtr);
+
+ lua_pushbooleancpp(L, FMVPtr->UnloadMovie());
+
+ return 1;
+ }
+
+ // -------------------------------------------------------------------------
+
+ int Play(lua_State * L)
+ {
+ BS_MoviePlayer * FMVPtr = BS_Kernel::GetInstance()->GetFMV();
+ BS_ASSERT(FMVPtr);
+
+ lua_pushbooleancpp(L, FMVPtr->Play());
+
+ return 1;
+ }
+
+ // -------------------------------------------------------------------------
+
+ int Pause(lua_State * L)
+ {
+ BS_MoviePlayer * FMVPtr = BS_Kernel::GetInstance()->GetFMV();
+ BS_ASSERT(FMVPtr);
+
+ lua_pushbooleancpp(L, FMVPtr->Pause());
+
+ return 1;
+ }
+
+ // -------------------------------------------------------------------------
+
+ int Update(lua_State * L)
+ {
+ BS_MoviePlayer * FMVPtr = BS_Kernel::GetInstance()->GetFMV();
+ BS_ASSERT(FMVPtr);
+
+ FMVPtr->Update();
+
+ return 0;
+ }
+
+ // -------------------------------------------------------------------------
+
+ int IsMovieLoaded(lua_State * L)
+ {
+ BS_MoviePlayer * FMVPtr = BS_Kernel::GetInstance()->GetFMV();
+ BS_ASSERT(FMVPtr);
+
+ lua_pushbooleancpp(L, FMVPtr->IsMovieLoaded());
+
+ return 1;
+ }
+
+ // -------------------------------------------------------------------------
+
+ int IsPaused(lua_State * L)
+ {
+ BS_MoviePlayer * FMVPtr = BS_Kernel::GetInstance()->GetFMV();
+ BS_ASSERT(FMVPtr);
+
+ lua_pushbooleancpp(L, FMVPtr->IsPaused());
+
+ return 1;
+ }
+
+ // -------------------------------------------------------------------------
+
+ int GetScaleFactor(lua_State * L)
+ {
+ BS_MoviePlayer * FMVPtr = BS_Kernel::GetInstance()->GetFMV();
+ BS_ASSERT(FMVPtr);
+
+ lua_pushnumber(L, FMVPtr->GetScaleFactor());
+
+ return 1;
+ }
+
+ // -------------------------------------------------------------------------
+
+ int SetScaleFactor(lua_State * L)
+ {
+ BS_MoviePlayer * FMVPtr = BS_Kernel::GetInstance()->GetFMV();
+ BS_ASSERT(FMVPtr);
+
+ FMVPtr->SetScaleFactor(static_cast<float>(luaL_checknumber(L, 1)));
+
+ return 0;
+ }
+
+ // -------------------------------------------------------------------------
+
+ int GetTime(lua_State * L)
+ {
+ BS_MoviePlayer * FMVPtr = BS_Kernel::GetInstance()->GetFMV();
+ BS_ASSERT(FMVPtr);
+
+ lua_pushnumber(L, FMVPtr->GetTime());
+
+ return 1;
+ }
+
+ // -------------------------------------------------------------------------
+
+ const char * LIBRARY_NAME = "Movieplayer";
+
+ const luaL_reg LIBRARY_FUNCTIONS[] =
+ {
+ "LoadMovie", LoadMovie,
+ "UnloadMovie", UnloadMovie,
+ "Play", Play,
+ "Pause", Pause,
+ "Update", Update,
+ "IsMovieLoaded", IsMovieLoaded,
+ "IsPaused", IsPaused,
+ "GetScaleFactor", GetScaleFactor,
+ "SetScaleFactor", SetScaleFactor,
+ "GetTime", GetTime,
+ 0, 0,
+ };
+}
+
+// -----------------------------------------------------------------------------
+
+bool BS_MoviePlayer::_RegisterScriptBindings()
+{
+ BS_Kernel * pKernel = BS_Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ BS_ScriptEngine * pScript = static_cast<BS_ScriptEngine *>(pKernel->GetService("script"));
+ BS_ASSERT(pScript);
+ lua_State * L = static_cast<lua_State *>(pScript->GetScriptObject());
+ BS_ASSERT(L);
+
+ if (!BS_LuaBindhelper::AddFunctionsToLib(L, LIBRARY_NAME, LIBRARY_FUNCTIONS)) return false;
+
+ return true;
+}
View
93 engines/sword25/fmv/oggtheora/audiobuffer.cpp
@@ -0,0 +1,93 @@
+// -----------------------------------------------------------------------------
+// This file is part of Broken Sword 2.5
+// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer
+//
+// Broken Sword 2.5 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.
+//
+// Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "audiobuffer.h"
+#include <windows.h>
+#include <queue>
+
+using namespace std;
+
+// -----------------------------------------------------------------------------
+
+struct BS_AudioBuffer::Impl
+{
+ CRITICAL_SECTION CS;
+ queue<signed short> Buffer;
+};
+
+// -----------------------------------------------------------------------------
+
+BS_AudioBuffer::BS_AudioBuffer() : t(new Impl())
+{
+ InitializeCriticalSection(&t->CS);
+}
+
+// -----------------------------------------------------------------------------
+
+BS_AudioBuffer::~BS_AudioBuffer()
+{
+ DeleteCriticalSection(&t->CS);
+
+ delete t;
+}
+
+// -----------------------------------------------------------------------------
+
+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);
+}
+
+// -----------------------------------------------------------------------------
+
+unsigned int BS_AudioBuffer::Pop(signed short * SamplePtr, unsigned int SampleCount)
+{
+ EnterCriticalSection(&t->CS);
+
+ unsigned int i = 0;
+ for (; i < SampleCount && !t->Buffer.empty(); ++i)
+ {
+ SamplePtr[i] = t->Buffer.front();
+ t->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);
+
+ return result;
+}
View
53 engines/sword25/fmv/oggtheora/audiobuffer.h
@@ -0,0 +1,53 @@
+// -----------------------------------------------------------------------------
+// This file is part of Broken Sword 2.5
+// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer
+//
+// Broken Sword 2.5 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.
+//
+// Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+// -----------------------------------------------------------------------------
+
+#ifndef BS_AUDIOBUFFER_H
+#define BS_AUDIOBUFFER_H
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "kernel/common.h"
+
+// -----------------------------------------------------------------------------
+// Klassendefinition
+// -----------------------------------------------------------------------------
+
+class BS_AudioBuffer
+{
+public:
+ BS_AudioBuffer();
+ virtual ~BS_AudioBuffer();
+
+ 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;
+
+ // Kopie verbieten
+ BS_AudioBuffer(const BS_AudioBuffer &);
+ const BS_AudioBuffer & operator=(const BS_AudioBuffer &);
+};
+
+#endif
View
90 engines/sword25/fmv/oggtheora/moviefile.cpp
@@ -0,0 +1,90 @@
+// -----------------------------------------------------------------------------
+// This file is part of Broken Sword 2.5
+// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer
+//
+// Broken Sword 2.5 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.
+//
+// Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// Logging
+// -----------------------------------------------------------------------------
+
+#define BS_LOG_PREFIX "MOVIEFILE"
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "kernel/kernel.h"
+#include "package/packagemanager.h"
+#include "oggstate.h"
+#include "moviefile.h"
+
+// -----------------------------------------------------------------------------
+
+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)
+ {
+ BS_LOG_ERRORLN("Could not load movie file \"%s\".", Filename.c_str());
+ Success = false;
+ }
+ else
+ Success = true;
+}
+
+// -----------------------------------------------------------------------------
+
+BS_MovieFile::~BS_MovieFile()
+{
+ if (m_Data) delete [] m_Data;
+}
+
+// -----------------------------------------------------------------------------
+
+int BS_MovieFile::BufferData(BS_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)
+ {
+ BS_LOG_ERRORLN("ogg_sync_buffer() failed.");
+ return 0;
+ }
+
+ // Feststellen wie viele Bytes kopiert werden sollen, maximal READ_BLOCK_SIZE, weniger falls das Ende der Daten erreicht ist.
+ int Bytes = (m_Size - m_ReadPos) > m_ReadBlockSize ? m_ReadBlockSize : m_Size - m_ReadPos;
+ memcpy(Buffer, &m_Data[m_ReadPos], Bytes);
+ m_ReadPos += Bytes;
+
+ OggState.SyncWrote(Bytes);
+
+ return Bytes;
+}
+
+// -----------------------------------------------------------------------------
+
+bool BS_MovieFile::IsEOF() const
+{
+ return m_ReadPos >= m_Size;
+}
View
57 engines/sword25/fmv/oggtheora/moviefile.h
@@ -0,0 +1,57 @@
+// -----------------------------------------------------------------------------
+// This file is part of Broken Sword 2.5
+// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer
+//
+// Broken Sword 2.5 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.
+//
+// Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+// -----------------------------------------------------------------------------
+
+#ifndef BS_MOVIEFILE_H
+#define BS_MOVIEFILE_H
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "kernel/common.h"
+
+#include "kernel/memlog_off.h"
+#include <string>
+#include "kernel/memlog_on.h"
+
+// -----------------------------------------------------------------------------
+
+class BS_OggState;
+
+// -----------------------------------------------------------------------------
+// Klassendefinition
+// -----------------------------------------------------------------------------
+
+class BS_MovieFile
+{
+public:
+ BS_MovieFile(const std::string & Filename, unsigned int ReadBlockSize, bool & Success);
+ virtual ~BS_MovieFile();
+
+ int BufferData(BS_OggState & OggState);
+ bool IsEOF() const;
+
+private:
+ char * m_Data;
+ unsigned int m_Size;
+ unsigned int m_ReadPos;
+ unsigned int m_ReadBlockSize;
+};
+
+#endif
View
59 engines/sword25/fmv/oggtheora/oggstate.cpp
@@ -0,0 +1,59 @@
+// -----------------------------------------------------------------------------
+// This file is part of Broken Sword 2.5
+// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer
+//
+// Broken Sword 2.5 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.
+//
+// Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "oggstate.h"
+
+// -----------------------------------------------------------------------------
+
+BS_OggState::BS_OggState()
+{
+ ogg_sync_init(&m_SyncState);
+}
+
+// -----------------------------------------------------------------------------
+
+BS_OggState::~BS_OggState()
+{
+ ogg_sync_clear(&m_SyncState);
+}
+
+// -----------------------------------------------------------------------------
+
+int BS_OggState::SyncPageout(ogg_page * OggPage)
+{
+ return ogg_sync_pageout(&m_SyncState, OggPage);
+}
+
+// -----------------------------------------------------------------------------
+
+char * BS_OggState::SyncBuffer(long Size)
+{
+ return ogg_sync_buffer(&m_SyncState, Size);
+}
+
+// -----------------------------------------------------------------------------
+
+int BS_OggState::SyncWrote(long Bytes)
+{
+ return ogg_sync_wrote(&m_SyncState, Bytes);
+}
View
63 engines/sword25/fmv/oggtheora/oggstate.h
@@ -0,0 +1,63 @@
+// -----------------------------------------------------------------------------
+// This file is part of Broken Sword 2.5
+// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer
+//
+// Broken Sword 2.5 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.
+//
+// Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+// -----------------------------------------------------------------------------
+
+#ifndef BS_OGGSTATE_H
+#define BS_OGGSTATE_H
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "kernel/common.h"
+#include "ogg/ogg.h"
+// XXX
+#include <iostream>
+// XXX
+
+// -----------------------------------------------------------------------------
+// Klassendefinition
+// -----------------------------------------------------------------------------
+
+class BS_OggState
+{
+public:
+ BS_OggState();
+ virtual ~BS_OggState();
+
+ 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;
+ }
+ // XXX
+private:
+ ogg_sync_state m_SyncState;
+};
+
+#endif
View
118 engines/sword25/fmv/oggtheora/oggstreamstate.cpp
@@ -0,0 +1,118 @@
+// -----------------------------------------------------------------------------
+// This file is part of Broken Sword 2.5
+// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer
+//
+// Broken Sword 2.5 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.
+//
+// Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "oggstreamstate.h"
+
+// -----------------------------------------------------------------------------
+
+BS_OggStreamState::BS_OggStreamState(int SerialNo)
+{
+ ogg_stream_init(&m_State, SerialNo);
+}
+
+// -----------------------------------------------------------------------------
+
+BS_OggStreamState::~BS_OggStreamState()
+{
+ ogg_stream_clear(&m_State);
+
+ // Alle gepufferten Pages löschen.
+ while (!m_PageBuffer.empty())
+ {
+ delete [] m_PageBuffer.front().header;
+ delete [] m_PageBuffer.front().body;
+ m_PageBuffer.pop();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+int BS_OggStreamState::PageIn(ogg_page * PagePtr)
+{
+ return ogg_stream_pagein(&m_State, PagePtr);
+}
+
+// -----------------------------------------------------------------------------
+
+int BS_OggStreamState::PacketOut(ogg_packet * PacketPtr)
+{
+ return ogg_stream_packetout(&m_State, PacketPtr);
+}
+
+// -----------------------------------------------------------------------------
+
+void BS_OggStreamState::BufferPage(ogg_page * PagePtr)
+{
+ if (PageBelongsToStream(PagePtr))
+ {
+ // Pages können nicht direkt gespeichert werden, da die Pointer im Laufe der Zeit ungültig werden.
+ // Daher wird an dieser Stelle eine tiefe Kopie der Page im erzeugt und im Pagebuffer angelegt.
+ ogg_page PageCopy;
+ PageCopy.header_len = PagePtr->header_len;
+ PageCopy.header = new unsigned char[PageCopy.header_len];
+ memcpy(PageCopy.header, PagePtr->header, PageCopy.header_len);
+ PageCopy.body_len = PagePtr->body_len;
+ PageCopy.body = new unsigned char[PageCopy.body_len];
+ memcpy(PageCopy.body, PagePtr->body, PageCopy.body_len);
+
+ m_PageBuffer.push(PageCopy);
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+int BS_OggStreamState::PageInBufferedPage()
+{
+ if (GetPageBufferSize() > 0)
+ {
+ // Page in den Stream einfügen, löschen und aus dem Puffer entfernen.
+ int Result = PageIn(&m_PageBuffer.front());
+ delete [] m_PageBuffer.front().header;
+ delete [] m_PageBuffer.front().body;
+ m_PageBuffer.pop();
+ return Result;
+ }
+
+ return -1;
+}
+
+// -----------------------------------------------------------------------------
+
+unsigned int BS_OggStreamState::GetPageBufferSize() const
+{
+ return m_PageBuffer.size();
+}
+
+// -----------------------------------------------------------------------------
+
+unsigned int BS_OggStreamState::GetUnprocessedBytes() const
+{
+ return m_State.body_fill - m_State.body_returned;
+}
+
+// -----------------------------------------------------------------------------
+
+bool BS_OggStreamState::PageBelongsToStream(ogg_page * PagePtr) const
+{
+ return m_State.serialno == ogg_page_serialno(PagePtr);
+}
View
74 engines/sword25/fmv/oggtheora/oggstreamstate.h
@@ -0,0 +1,74 @@
+// -----------------------------------------------------------------------------
+// This file is part of Broken Sword 2.5
+// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer
+//
+// Broken Sword 2.5 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.
+//
+// Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+// -----------------------------------------------------------------------------
+
+#ifndef BS_OGGSTREAMSTATE_H
+#define BS_OGGSTREAMSTATE_H
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "kernel/common.h"
+#include "ogg/ogg.h"
+#include <queue>
+// XXX
+#include <iostream>
+// XXX
+
+// -----------------------------------------------------------------------------
+// Klassendefinition
+// -----------------------------------------------------------------------------
+
+class BS_OggStreamState
+{
+public:
+ BS_OggStreamState(int SerialNo);
+ virtual ~BS_OggStreamState();
+
+ int PageIn(ogg_page * PagePtr);
+ int PacketOut(ogg_packet * PacketPtr);
+
+ void BufferPage(ogg_page * PagePtr);
+ int PageInBufferedPage();
+ unsigned int GetPageBufferSize() const;
+
+ unsigned int GetUnprocessedBytes() 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;
+ }
+ // XXX
+
+private:
+ ogg_stream_state m_State;
+ std::queue<ogg_page> m_PageBuffer;
+};
+
+#endif
View
709 engines/sword25/fmv/oggtheora/oggtheora.cpp
@@ -0,0 +1,709 @@
+// -----------------------------------------------------------------------------
+// This file is part of Broken Sword 2.5
+// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer
+//
+// Broken Sword 2.5 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.
+//
+// Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+// -----------------------------------------------------------------------------
+
+// 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 "kernel/memlog_off.h"
+#include <algorithm>
+#include "kernel/memlog_on.h"
+#include <float.h>
+
+#include "package/packagemanager.h"
+#include "kernel/cpuinfo.h"
+#include "sfx/soundengine.h"
+#include "gfx/graphicengine.h"
+#include "gfx/panel.h"
+#include "oggtheora.h"
+#include "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ächst 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ören der
+ // lokalen Auto-Pointer werden die entsprechenden Destruktoren aufgerufen.
+
+ // Film laden
+ // Für 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ür 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öglichst viel Bildschirmfläche 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ür 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, überträgt 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äuft, 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 überschrieben.
+ 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öße des Audiobuffers berechnen.
+ size_t MaxAudioBufferSamples = static_cast<size_t>(Info.channels * Info.rate * MAX_AUDIO_BUFFER_LENGTH);
+
+ // Zwischenspeicher für die Samples.
+ vector<signed short> Samples;
+
+ // Audiobuffer bis zur Maximalgröße füllen, wenn möglich.
+ 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ügend Platz für 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ügen.
+ 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);
+ }
+}
View
109 engines/sword25/fmv/oggtheora/oggtheora.h
@@ -0,0 +1,109 @@
+// -----------------------------------------------------------------------------
+// This file is part of Broken Sword 2.5
+// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer
+//
+// Broken Sword 2.5 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.
+//
+// Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+// -----------------------------------------------------------------------------
+
+#ifndef BS_OGGTHEORA_H
+#define BS_OGGTHEORA_H
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "kernel/memlog_off.h"
+#include <vector>
+#include <memory>
+#include <queue>
+#include "kernel/memlog_on.h"
+
+#include "kernel/common.h"
+#include "kernel/bs_stdint.h"
+#include "gfx/bitmap.h"
+#include "gfx/renderobjectptr.h"
+#include "fmv/movieplayer.h"
+#include "vorbisstate.h"
+#include "theorastate.h"
+#include "oggstate.h"
+#include "oggstreamstate.h"
+#include "moviefile.h"
+#include "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
View
79 engines/sword25/fmv/oggtheora/theorastate.cpp
@@ -0,0 +1,79 @@
+// -----------------------------------------------------------------------------
+// This file is part of Broken Sword 2.5
+// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer
+//
+// Broken Sword 2.5 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.
+//
+// Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "theorastate.h"
+
+// -----------------------------------------------------------------------------
+
+BS_TheoraState::BS_TheoraState() :
+ m_StateInitialized(false)
+{
+ theora_comment_init(&m_Comment);
+ theora_info_init(&m_Info);
+}
+
+// -----------------------------------------------------------------------------
+
+BS_TheoraState::~BS_TheoraState()
+{
+ if (m_StateInitialized) theora_clear(&m_State);
+ theora_info_clear(&m_Info);
+ theora_comment_clear(&m_Comment);
+}
+
+// -----------------------------------------------------------------------------
+
+int BS_TheoraState::DecodeHeader(ogg_packet * OggPacketPtr)
+{
+ return theora_decode_header(&m_Info, &m_Comment, OggPacketPtr);
+}
+
+// -----------------------------------------------------------------------------
+
+int BS_TheoraState::DecodeInit()
+{
+ int Result = theora_decode_init(&m_State, &m_Info);
+ m_StateInitialized = (Result == 0);
+ return Result;
+}
+
+// -----------------------------------------------------------------------------
+
+double BS_TheoraState::GranuleTime()
+{
+ return theora_granule_time(&m_State, m_State.granulepos);
+}
+
+// -----------------------------------------------------------------------------
+
+int BS_TheoraState::DecodePacketIn(ogg_packet * OggPacketPtr)
+{
+ return theora_decode_packetin(&m_State, OggPacketPtr);
+}
+
+// -----------------------------------------------------------------------------
+
+int BS_TheoraState::DecodeYUVOut(yuv_buffer * YUV)
+{
+ return theora_decode_YUVout(&m_State, YUV);
+}
View
55 engines/sword25/fmv/oggtheora/theorastate.h
@@ -0,0 +1,55 @@
+// -----------------------------------------------------------------------------
+// This file is part of Broken Sword 2.5
+// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer
+//
+// Broken Sword 2.5 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.
+//
+// Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+// -----------------------------------------------------------------------------
+
+#ifndef BS_THEORASTATE_H
+#define BS_THEORASTATE_H
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "kernel/common.h"
+#include "theora/theora.h"
+
+// -----------------------------------------------------------------------------
+// Klassendefinition
+// -----------------------------------------------------------------------------
+
+class BS_TheoraState
+{
+public:
+ BS_TheoraState();
+ virtual ~BS_TheoraState();
+
+ int DecodeHeader(ogg_packet * OggPacketPtr);
+ int DecodeInit();
+ int DecodePacketIn(ogg_packet * OggPacketPtr);
+ int DecodeYUVOut(yuv_buffer * YUV);
+ double GranuleTime();
+
+ const theora_info & GetInfo() const { return m_Info; }
+
+private:
+ theora_info m_Info;
+ theora_comment m_Comment;
+ bool m_StateInitialized;
+ theora_state m_State;
+};
+
+#endif
View
97 engines/sword25/fmv/oggtheora/vorbisstate.cpp
@@ -0,0 +1,97 @@
+// -----------------------------------------------------------------------------
+// This file is part of Broken Sword 2.5
+// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer
+//
+// Broken Sword 2.5 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.
+//
+// Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "vorbisstate.h"
+
+// -----------------------------------------------------------------------------
+
+BS_VorbisState::BS_VorbisState() :
+ m_DSPStateInitialized(false),
+ m_BlockInitialized(false)
+{
+ vorbis_info_init(&m_Info);
+ vorbis_comment_init(&m_Comment);
+}
+
+// -----------------------------------------------------------------------------
+
+BS_VorbisState::~BS_VorbisState()
+{
+ if (m_BlockInitialized) vorbis_block_clear(&m_Block);
+ if (m_DSPStateInitialized) vorbis_dsp_clear(&m_DSPState);
+ vorbis_comment_clear(&m_Comment);
+ vorbis_info_clear(&m_Info);
+}
+
+// -----------------------------------------------------------------------------
+
+int BS_VorbisState::SynthesisHeaderIn(ogg_packet * OggPacketPtr)
+{
+ return vorbis_synthesis_headerin(&m_Info, &m_Comment, OggPacketPtr);
+}
+
+// -----------------------------------------------------------------------------
+
+int BS_VorbisState::SynthesisInit()
+{
+ int Result = vorbis_synthesis_init(&m_DSPState, &m_Info);
+ m_DSPStateInitialized = (Result == 0);
+ return Result;
+}
+
+// -----------------------------------------------------------------------------
+
+int BS_VorbisState::BlockInit()
+{
+ int Result = vorbis_block_init(&m_DSPState, &m_Block);
+ m_BlockInitialized = (Result == 0);
+ return Result;
+}
+
+// -----------------------------------------------------------------------------
+
+int BS_VorbisState::SynthesisPCMout(float *** PCM)
+{
+ return vorbis_synthesis_pcmout(&m_DSPState, PCM);
+}
+
+// -----------------------------------------------------------------------------
+
+int BS_VorbisState::SynthesisRead(int Samples)
+{
+ return vorbis_synthesis_read(&m_DSPState, Samples);
+}
+
+// -----------------------------------------------------------------------------
+
+int BS_VorbisState::Synthesis(ogg_packet * OggPacketPtr)
+{
+ return vorbis_synthesis(&m_Block, OggPacketPtr);
+}
+
+// -----------------------------------------------------------------------------
+
+int BS_VorbisState::SynthesisBlockIn()
+{
+ return vorbis_synthesis_blockin(&m_DSPState, &m_Block);
+}
View
59 engines/sword25/fmv/oggtheora/vorbisstate.h
@@ -0,0 +1,59 @@
+// -----------------------------------------------------------------------------
+// This file is part of Broken Sword 2.5
+// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer
+//
+// Broken Sword 2.5 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.
+//
+// Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+// -----------------------------------------------------------------------------
+
+#ifndef BS_VORBISSTATE_H
+#define BS_VORBISSTATE_H
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "kernel/common.h"
+#include "vorbis/codec.h"
+
+// -----------------------------------------------------------------------------
+// Klassendefinition
+// -----------------------------------------------------------------------------
+
+class BS_VorbisState
+{
+public:
+ BS_VorbisState();
+ virtual ~BS_VorbisState();
+
+ int SynthesisHeaderIn(ogg_packet * OggPacketPtr);
+ int SynthesisInit();
+ int BlockInit();
+ int SynthesisPCMout(float *** PCM);
+ int SynthesisRead(int Samples);
+ int Synthesis(ogg_packet * OggPacketPtr);
+ int SynthesisBlockIn();
+
+ const vorbis_info & GetInfo() const { return m_Info; }
+
+private:
+ vorbis_info m_Info;
+ bool m_DSPStateInitialized;
+ vorbis_dsp_state m_DSPState;
+ bool m_BlockInitialized;
+ vorbis_block m_Block;
+ vorbis_comment m_Comment;
+};
+
+#endif
View
416 engines/sword25/fmv/oggtheora/yuvtorgba.cpp
@@ -0,0 +1,416 @@
+// -----------------------------------------------------------------------------
+// This file is part of Broken Sword 2.5
+// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer
+//
+// Broken Sword 2.5 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.
+//
+// Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "kernel/cpuinfo.h"
+#include "yuvtorgba.h"
+
+#include <mmintrin.h>
+
+using namespace std;
+
+// -----------------------------------------------------------------------------
+
+namespace
+{
+
+ 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