aboutsummaryrefslogtreecommitdiff
path: root/engines/sword25/gfx/graphicengine.h
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sword25/gfx/graphicengine.h')
-rwxr-xr-xengines/sword25/gfx/graphicengine.h401
1 files changed, 401 insertions, 0 deletions
diff --git a/engines/sword25/gfx/graphicengine.h b/engines/sword25/gfx/graphicengine.h
new file mode 100755
index 0000000000..9fe8fd93fd
--- /dev/null
+++ b/engines/sword25/gfx/graphicengine.h
@@ -0,0 +1,401 @@
+// -----------------------------------------------------------------------------
+// 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
+// -----------------------------------------------------------------------------
+
+/*
+ BS_GraphicEngine
+ ----------------
+ Dies ist das Graphik-Engine Interface, dass alle Methoden und Klassen enthält, die eine
+ Graphik-Engine implementieren muss.
+
+ Autor: Malte Thiesen
+*/
+
+#ifndef _BS_GRAPHICENGINE_H
+#define _BS_GRAPHICENGINE_H
+
+// Includes
+#include "kernel/memlog_off.h"
+#include <vector>
+#include "kernel/memlog_on.h"
+
+#include "kernel/common.h"
+#include "kernel/bs_stdint.h"
+#include "kernel/resservice.h"
+#include "kernel/persistable.h"
+#include "math/rect.h"
+#include "framecounter.h"
+#include "renderobjectptr.h"
+
+class BS_Kernel;
+class BS_Image;
+class BS_Panel;
+class BS_Screenshot;
+
+// Typen
+typedef unsigned int BS_COLOR;
+
+// Makros
+#define BS_RGB(R,G,B) (0xFF000000 | ((R) << 16) | ((G) << 8) | (B))
+#define BS_ARGB(A,R,G,B) (((A) << 24) | ((R) << 16) | ((G) << 8) | (B))
+
+/**
+ @brief Dies ist das Graphik-Engine Interface, dass alle Methoden und Klassen enthält, die eine Graphik-Engine implementieren muss.
+
+ Hier sind nur wenige Rumpffunktionen realisiert, wie z.B. das Abfragen der Parameter des Ausgabepuffers.
+ Die Hauptfunktionen muss eine Implementation dieses Inferfaces stellen.<br>
+ Die bisher einzige Implementation ist BS_DDrawGfx.
+*/
+
+class BS_GraphicEngine : public BS_ResourceService, public BS_Persistable
+{
+public:
+ // Enums
+ // -----
+
+ // Farbformate
+ /**
+ @brief Die von der Engine benutzten Farbformate
+ */
+ enum COLOR_FORMATS
+ {
+ /// Undefiniertes/unbekanntes Farbformat
+ CF_UNKNOWN = 0,
+ /// 16 Bit Farbformat (5 Bit Rot, 5 Bit Grün, 5 Bit Blau)
+ CF_RGB15,
+ /// 16 Bit Farbformat (5 Bit Rot, 6 Bit Grün, 5 Bit Blau)
+ CF_RGB16,
+ /**
+ Spezielles Alpha-Farbformat der Engine, welches besonders schnelles Darstellen unter Benutzung von MMX-Befehlen unterstützt.<br>
+ Die Pixel sind 16 Bit breit und haben das selbe Format wie #CF_RGB15. Zusätzlich besitzt jeder Pixel noch einen 8 Bit Alphawert.<br>
+ Es werden jeweils 4 Pixel und 4 Alphawerte zu einem 12 Byte großen Datenblock zusammengefasst.<br>
+ Dabei werden die Daten in folgender Reihenfolge abgelegt:
+ Alpha0 Alpha1 Alpha2 Alpha3 Pixel0 Pixel1 Pixel2 Pixel3
+ Falls die Pixelanzahl einer Zeile nicht durch 4 teilbar ist, wird der letzte Pixelblock trotzdem komplett abgespeichert, die
+ nicht verwendeten Pixel- und Alphawerte können beliebige Werte haben.
+ */
+ CF_RGB15_INTERLEAVED,
+ /**
+ Spezielles Alpha-Farbformat der Engine, welches besonders schnelles Darstellen unter Benutzung von MMX-Befehlen unterstützt.<br>
+ Die Pixel sind 16 Bit breit und haben das selbe Format wie #CF_RGB16. Zusätzlich besitzt jeder Pixel noch einen 8 Bit Alphawert.<br>
+ Es werden jeweils 4 Pixel und 4 Alphawerte zu einem 12 Byte großen Datenblock zusammengefasst.<br>
+ Dabei werden die Daten in folgender Reihenfolge abgelegt:
+ Alpha0 Alpha1 Alpha2 Alpha3 Pixel0 Pixel1 Pixel2 Pixel3
+ Falls die Pixelanzahl einer Zeile nicht durch 4 teilbar ist, wird der letzte Pixelblock trotzdem komplett abgespeichert, die
+ nicht verwendeten Pixel- und Alphawerte können beliebige Werte haben.
+ */
+ CF_RGB16_INTERLEAVED,
+ /**
+ 24 Bit Farbformat (8 Bit Rot, 8 Bit Grün, 8 Bit Blau)
+ */
+ CF_RGB24,
+ /**
+ 32 Bit Farbformat (8 Bit Alpha, 8 Bit Rot, 8 Bit Grün, 8 Bit Blau) (little endian)
+ */
+ CF_ARGB32,
+ /**
+ 32 Bit Farbformat (8 Bit Alpha, 8 Bit Blau, 8 Bit Grün, 8 Bit Rot) (little endian)
+ */
+ CF_ABGR32,
+ };
+
+ // Interface
+ // ---------
+
+ /**
+ @brief Initialisiert die Graphikengine und setzt den Bildschirmmodus.
+ @param Width die Breite des Ausgabepuffers in Pixeln.<br>Der Standardwert ist 800.
+ @param Height die Höhe des Ausgabepuffers in Pixeln.<br>Der Standardwert ist 600.
+ @param BitDepth die Bittiefe des gewünschten Ausgabepuffers in Bit.<br>Der Standardwert ist 16.
+ @param BackbufferCount die Anzahl an Backbuffern die erzeugt werden soll.<br>Der Standardwert ist 2.
+ @param Windowed gibt an, ob die Engine im Fenstermodus laufen soll. Falls true angegeben wird, wird ein Fenster geöffnet in das
+ die Ausgaben gerendert werden. Ansonsten wird ein Vollbildmodus gesetzt der den Parametern das Ausgabepuffers
+ entspricht.
+ @return Gibt false zurück, falls die Initialisierung fehlgeschlagen ist.
+ @remark Der Fenstermodus sollte nur zu Debuggingzwecken benutzt werden und ist nicht dafür gedacht im endgültigen Produkt benutzt
+ zu werden.
+ @remark Diese Methode sollte direkt nach der Initialisierung aller Services aufgerufen werden.
+ */
+ virtual bool Init(int Width = 800, int Height = 600, int BitDepth = 16, int BackbufferCount = 2, bool Windowed = false) = 0;
+
+ //@{
+ /** @name Frame-Methoden */
+ /**
+ @brief Beginnt das Rendern eines neuen Frames.
+ @param UpdateAll gibt an, ob der Renderer im nächsten Frame alles neu zeichnen soll.<br>
+ Diese Funktion kann nützlich sein, wenn der Renderer mit Dirty-Rectangles arbeitet, der Benutzer aber gelegentlich
+ darauf angewiesen ist, dass der gesamte Bildschirminhalt neu gezeichnet werden soll.<br>
+ Der Standardwert ist false.
+ Diese Methode muss am Anfang das Main-Loops aufgerufen werden und vor dem Aufruf jeglicher Rendermethoden.
+ @return Gibt false zurück, falls ein Fehler aufgetreten ist.
+ @remark Implementationen dieser Methode müssen _UpdateLastFrameDuration() aufrufen.
+ */
+ virtual bool StartFrame(bool UpdateAll = false) = 0;
+
+ /**
+ @brief Beendet das Rendern des Frames und stellt diesen auf dem Bildschirm dar.
+
+ Diese Methode muss am Ende des Main-Loops aufgerufen werden. Nach dem Aufruf dürfen keine weiteren Rendermethoden mehr aufgerufen
+ werden. Dafür muss erst wieder ein Aufruf von #StartFrame erfolgen.
+ @return Gibt false zurück, falls ein Fehler aufgetreten ist:
+ */
+ virtual bool EndFrame() = 0;
+
+ //@}
+
+ //@{
+ /** @name Debug-Methoden */
+
+ /**
+ @brief Zeichnet eine Line in den Framebuffer.
+
+ Diese Methode muss zwischen StartFrame() und EndFrame() aufgerufen werden und ist nur für Debugzwecke gedacht.
+ Die Linie erscheint nur für einen Frame. Wenn die Linie dauerhaft zu sehen sein soll, muss sie jeden Frame neu
+ gezeichnet werden.
+
+ @param Start der Startpunkt der Linie
+ @param End der Endpunkt der Linie
+ @param Color die Farbe der Linie. Der Standardwert ist BS_RGB(255, 255, 255) (Weiß).
+ */
+ virtual void DrawDebugLine(const BS_Vertex & Start, const BS_Vertex & End, unsigned int Color = BS_RGB(255, 255, 255)) = 0;
+
+ /**
+ @brief Erstellt einen Screenshot.
+
+ Erstellt einen Screenshot vom aktuellen Framebuffer und schreibt ihn in eine Grafikdatei.<br>
+ Das verwendete Dateiformat ist PNG.
+
+ @param Der Dateiname des Screenshots.
+ @return Gibt true zurück, wenn der Screenshot gespeichert werden konnte, ansonsten false.
+ @remark Diese Methode darf erst nach einem Aufruf von EndFrame() und vor dem nächsten Aufruf von StartFrame() aufgerufen werden.
+ */
+ bool SaveScreenshot(const std::string & Filename);
+
+ /**
+ @Brief Erstellt einen kleinen Screenshot.
+
+ Erstellt einen Screenshot mit den Maßen 200x125. Hierfür werden am oberen und unteren Bildschirmrand die Interfaceleisten abgeschnitten und
+ das Bild auf ein 16tel seiner Ursprungsgröße verkleinert.
+
+ @param Der Dateiname des Screenshots.
+ @return Gibt true zurück, wenn der Screenshot gespeichert werden konnte, ansonsten false.
+ @remark Diese Methode darf erst nach einem Aufruf von EndFrame() und vor dem nächsten Aufruf von StartFrame() aufgerufen werden.
+ @remark Der Framebuffer muss eine Auflösung von 800x600 haben.
+ */
+ bool SaveThumbnailScreenshot(const std::string & Filename);
+
+ /**
+ @brief Liest den aktuellen Inhalt des Framebuffer aus.
+ @param Width enthält nach einem erfolgreichen Aufruf die Breite des Framebuffers.
+ @param Height enthält nach einem erfolgreichen Aufruf die Höhe des Framebuffers.
+ @param Data enthält nach einem erfolgreichen Aufruf den Inhalt des Framebuffers als 32-Bit Farbwerte.
+ @return Gibt true zurück, wenn der Aufruf erfolgreich war, ansonsten false.
+ @remark Diese Methode ist für das Erstellen von Screenshots gedacht. Sie muss also nicht sehr effizient sein.
+ @remark Diese Methode darf erst nach einem Aufruf von EndFrame() und vor dem nächsten Aufruf von StartFrame() aufgerufen werden.
+ */
+ virtual bool GetScreenshot(unsigned int & Width, unsigned int & Height, std::vector<unsigned int> & Data) = 0;
+
+ //@}
+
+ virtual BS_RenderObjectPtr<BS_Panel> GetMainPanel() = 0;
+
+ /**
+ @brief Gibt die Zeit (in Microsekunden) zurück die seit dem letzten Frame vergangen ist.
+ */
+ int GetLastFrameDurationMicro() { if (m_TimerActive) return m_LastFrameDuration; else return 0; }
+
+ /**
+ @brief Gibt die Zeit (in Sekunden) zurück die seit dem letzten Frame vergangen ist.
+ */
+ float GetLastFrameDuration() { if (m_TimerActive) return static_cast<float>(m_LastFrameDuration) / 1000000.0f; else return 0; }
+
+ void StopMainTimer() { m_TimerActive = false; }
+ void ResumeMainTimer() { m_TimerActive = true; }
+ float GetSecondaryFrameDuration() { return static_cast<float>(m_LastFrameDuration) / 1000000.0f; }
+
+ //@{
+ /** @name Accessor-Methoden */
+
+ /**
+ @brief Gibt die Breite des Ausgabepuffers in Pixeln zurück.
+ */
+ int GetDisplayWidth() { return m_Width; }
+
+ /**
+ @brief Gibt die Höhe des Ausgabepuffers in Pixeln zurück.
+ */
+ int GetDisplayHeight() { return m_Height; }
+
+ /**
+ @brief Gibt die Bounding-Box des Ausgabepuffers zurück. (0, 0, Width, Height)
+ */
+ BS_Rect& GetDisplayRect() { return m_ScreenRect; }
+
+ /**
+ @brief Gibt die Bittiefe des Ausgabepuffers zurück.
+ */
+ int GetBitDepth() { return m_BitDepth; }
+
+ /**
+ @brief Legt fest ob der Framebufferwechsel mit dem vertikalen Strahlenrücklauf synchronisiert werden soll.<br>
+ Vsync ist standardmäßig eingeschaltet.
+ @param Vsync gibt an, ob der Framebufferwechsel mit dem vertikalen Strahlenrücklauf synchronisiert werden soll.
+ @remark Im Fenstermodus hat diese Einstellung keine Auswirkung.
+ */
+ virtual void SetVsync(bool Vsync) = 0;
+
+ /**
+ @brief Gibt true zurück, wenn V-Sync an ist.
+ @remark Im Fenstermodus hat diese Einstellung keine Auswirkung.
+ */
+ virtual bool GetVsync() const = 0;
+
+ /**
+ @brief Gibt true zurück, falls die Engine im Fenstermodus läuft.
+ */
+ bool IsWindowed() { return m_Windowed; }
+
+ /**
+ @brief Füllt einen Rechteckigen Bereich des Framebuffers mit einer Farbe.
+ @param FillRectPtr Pointer auf ein BS_Rect, welches den Ausschnitt des Framebuffers spezifiziert, der gefüllt
+ werden soll oder 0, falls das gesamte Bild gefüllt werden soll.<br>
+ Der Standardwert ist 0.
+ @param Color der 32 Bit Farbwert mit dem der Bildbereich gefüllt werden soll.<br>
+ Der Standardwert ist BS_RGB(0, 0, 0) (Schwarz).
+ @return Gibt true zurück, wenn der Aufruf erfolgreich war, ansonsten false.
+ @remark Es ist möglich über die Methode transparente Rechtecke darzustellen, indem man eine Farbe mit einem
+ Alphawert ungleich 255 angibt.
+ @remark Falls das Rechteck nicht völlig innerhalb des Bildschirms ist, wird es automatisch zurechtgestutzt.
+ */
+ virtual bool Fill(const BS_Rect * FillRectPtr = 0, unsigned int Color = BS_RGB(0, 0, 0)) = 0;
+
+ //@}
+
+ //@{
+ /** @name Debugging-Methoden */
+
+ int GetFPSCount() const { return m_FPSCounter.GetFPS(); }
+ int GetRepaintedPixels() const { return m_RepaintedPixels; }
+
+ //@}
+
+ //@{
+ /** @name Auskunfts-Methoden */
+
+ /**
+ @brief Gibt die Größe eines Pixeleintrages in Byte für ein bestimmtes Farbformat zurück
+ @param ColorFormat das gewünschte Farbformat. Der Parameter muss vom Typ COLOR_FORMATS sein.
+ @return Gibt die Größe eines Pixeleintrages in Byte des Farbsformates ColorFormat zurück.<br>
+ Falls das Farbformat unbekannt ist, wird -1 zurückgegeben.
+ */
+ static int GetPixelSize(BS_GraphicEngine::COLOR_FORMATS ColorFormat)
+ {
+ switch (ColorFormat)
+ {
+ case BS_GraphicEngine::CF_RGB16:
+ case BS_GraphicEngine::CF_RGB15:
+ return 2;
+
+ case BS_GraphicEngine::CF_RGB16_INTERLEAVED:
+ case BS_GraphicEngine::CF_RGB15_INTERLEAVED:
+ return 3;
+
+ case BS_GraphicEngine::CF_ARGB32:
+ return 4;
+ }
+
+ return -1;
+ }
+
+ /**
+ @brief Berechnet die Länge einer Bildzeile eines Bilder in Byte, abhängig vom Farbformat.
+ @param ColorFormat das Farbformat des Bildes.
+ @param Width die Länge einer Bildzeile in Pixel.
+ @return Gibt die Länge einer Bildzeile in Byte wieder.<br>
+ Falls das Farbformat unbekannt ist, wird -1 zurückgegeben.
+ */
+ static int CalcPitch(BS_GraphicEngine::COLOR_FORMATS ColorFormat, int Width)
+ {
+ switch (ColorFormat)
+ {
+ case BS_GraphicEngine::CF_RGB16:
+ case BS_GraphicEngine::CF_RGB15:
+ return Width * 2;
+
+ case BS_GraphicEngine::CF_RGB16_INTERLEAVED:
+ case BS_GraphicEngine::CF_RGB15_INTERLEAVED:
+ return (Width + 3) / 4 * 12;
+
+ case BS_GraphicEngine::CF_ARGB32:
+ case BS_GraphicEngine::CF_ABGR32:
+ return Width * 4;
+
+ default:
+ BS_ASSERT(false);
+ }
+
+ return -1;
+ }
+
+ //@}
+
+ // Persistenz Methoden
+ // -------------------
+ virtual bool Persist(BS_OutputPersistenceBlock & Writer);
+ virtual bool Unpersist(BS_InputPersistenceBlock & Reader);
+
+ static void ARGBColorToLuaColor(lua_State * L, unsigned int Color);
+ static unsigned int LuaColorToARGBColor(lua_State * L, int StackIndex);
+
+protected:
+ // Konstruktor
+ // -----------
+ BS_GraphicEngine(BS_Kernel* pKernel);
+
+ // Display Variablen
+ // -----------------
+ int m_Width;
+ int m_Height;
+ BS_Rect m_ScreenRect;
+ int m_BitDepth;
+ bool m_Windowed;
+
+ // Debugging-Variablen
+ // -------------------
+ BS_Framecounter m_FPSCounter;
+
+ unsigned int m_RepaintedPixels;
+
+ /**
+ @brief Berechnet die Zeit die seit dem letzten Framebeginn vergangen ist.
+ */
+ void UpdateLastFrameDuration();
+
+private:
+ bool RegisterScriptBindings();
+
+ // LastFrameDuration-Variablen
+ // ---------------------------
+ uint64_t m_LastTimeStamp;
+ unsigned int m_LastFrameDuration;
+ bool m_TimerActive;
+ std::vector<unsigned int> m_FrameTimeSamples;
+ unsigned int m_FrameTimeSampleSlot;
+};
+
+#endif