diff --git a/src/driver/Makefile.am b/src/driver/Makefile.am
index cb2a5ef11..393a5bf8e 100644
--- a/src/driver/Makefile.am
+++ b/src/driver/Makefile.am
@@ -59,6 +59,7 @@ endif
if BOXTYPE_TRIPLE
libneutrino_driver_a_SOURCES += \
+ fb_accel_td.cpp \
newclock.cpp \
lcdd.cpp
endif
diff --git a/src/driver/fb_accel.h b/src/driver/fb_accel.h
index 148c9f591..d67dc75d0 100644
--- a/src/driver/fb_accel.h
+++ b/src/driver/fb_accel.h
@@ -150,4 +150,25 @@ class CFbAccelGLFB
fb_pixel_t * getBackBufferPointer() const;
};
+class CFbAccelTD
+ : public CFbAccel
+{
+ private:
+ fb_pixel_t lastcol;
+ void setColor(fb_pixel_t col);
+ fb_pixel_t *backbuffer;
+ public:
+ CFbAccelTD();
+ ~CFbAccelTD();
+ void init(const char * const);
+ int setMode(unsigned int xRes, unsigned int yRes, unsigned int bpp);
+ void paintPixel(int x, int y, const fb_pixel_t col);
+ void paintRect(const int x, const int y, const int dx, const int dy, const fb_pixel_t col);
+ void paintHLineRel(int x, int dx, int y, const fb_pixel_t col) { paintLine(x, y, x + dx, y, col); };
+ void paintVLineRel(int x, int y, int dy, const fb_pixel_t col) { paintLine(x, y, x, y + dy, col); };
+ void paintLine(int xa, int ya, int xb, int yb, const fb_pixel_t col);
+ void blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32_t xoff, uint32_t yoff, uint32_t xp, uint32_t yp, bool transp);
+ void waitForIdle(const char *func = NULL);
+};
+
#endif
diff --git a/src/driver/fb_accel_td.cpp b/src/driver/fb_accel_td.cpp
new file mode 100644
index 000000000..7cddcfa3c
--- /dev/null
+++ b/src/driver/fb_accel_td.cpp
@@ -0,0 +1,176 @@
+/*
+ Framebuffer acceleration hardware abstraction functions.
+ The hardware dependent framebuffer acceleration functions for the
+ TripleDragon are represented in this class using DirectFB.
+
+ License: GPL
+
+ (C) 2017 Stefan Seyfried
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifdef HAVE_CONFIG_H
+#include
+#endif
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+#include
+
+#define LOGTAG "[fb_accel_td] "
+
+#include
+#include
+extern IDirectFB *dfb;
+extern IDirectFBSurface *dfbdest;
+extern int gfxfd;
+void CFbAccelTD::waitForIdle(const char *)
+{
+#if 0
+ struct timeval ts, te;
+ gettimeofday(&ts, NULL);
+#endif
+ /* does not work: DFBResult r = dfb->WaitForSync(dfb); */
+ ioctl(gfxfd, STB04GFX_ENGINE_SYNC);
+#if 0
+ gettimeofday(&te, NULL);
+ printf("STB04GFX_ENGINE_SYNC took %lld us\n", (te.tv_sec * 1000000LL + te.tv_usec) - (ts.tv_sec * 1000000LL + ts.tv_usec));
+#endif
+}
+
+CFbAccelTD::CFbAccelTD()
+{
+ fb_name = "TripleDragon framebuffer";
+ lastcol = 0xffffffff;
+ lbb = lfb; /* the memory area to draw to... */
+};
+
+CFbAccelTD::~CFbAccelTD()
+{
+ if (lfb)
+ munmap(lfb, available);
+ if (fd > -1)
+ close(fd);
+}
+
+void CFbAccelTD::setColor(fb_pixel_t col)
+{
+ if (col == lastcol)
+ return;
+ char *c = (char *)&col;
+ dfbdest->SetColor(dfbdest, c[1], c[2], c[3], c[0]);
+ lastcol = col;
+}
+
+void CFbAccelTD::paintRect(const int x, const int y, const int dx, const int dy, const fb_pixel_t col)
+{
+ setColor(col);
+ dfbdest->FillRectangle(dfbdest, x, y, dx, dy);
+}
+
+void CFbAccelTD::paintPixel(const int x, const int y, const fb_pixel_t col)
+{
+ setColor(col);
+ dfbdest->DrawLine(dfbdest, x, y, x, y);
+}
+
+void CFbAccelTD::paintLine(int xa, int ya, int xb, int yb, const fb_pixel_t col)
+{
+ setColor(col);
+ dfbdest->DrawLine(dfbdest, xa, ya, xb, yb);
+}
+
+void CFbAccelTD::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32_t xoff, uint32_t yoff, uint32_t xp, uint32_t yp, bool transp)
+{
+ DFBRectangle src;
+ DFBResult err;
+ IDirectFBSurface *surf;
+ DFBSurfaceDescription dsc;
+
+ src.x = xp;
+ src.y = yp;
+ src.w = width - xp;
+ src.h = height - yp;
+
+ dsc.flags = (DFBSurfaceDescriptionFlags)(DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PREALLOCATED);
+ dsc.caps = DSCAPS_NONE;
+ dsc.width = width;
+ dsc.height = height;
+ dsc.preallocated[0].data = fbbuff;
+ dsc.preallocated[0].pitch = width * sizeof(fb_pixel_t);
+ err = dfb->CreateSurface(dfb, &dsc, &surf);
+ /* TODO: maybe we should not die if this fails? */
+ if (err != DFB_OK) {
+ fprintf(stderr, LOGTAG "blit2FB: ");
+ DirectFBErrorFatal("dfb->CreateSurface(dfb, &dsc, &surf)", err);
+ }
+
+ if (transp)
+ {
+ surf->SetSrcColorKey(surf, 0, 0, 0);
+ dfbdest->SetBlittingFlags(dfbdest, DSBLIT_SRC_COLORKEY);
+ }
+ else
+ dfbdest->SetBlittingFlags(dfbdest, DSBLIT_BLEND_ALPHACHANNEL);
+
+ dfbdest->Blit(dfbdest, surf, &src, xoff, yoff);
+ surf->Release(surf);
+ return;
+}
+
+void CFbAccelTD::init(const char *)
+{
+ CFrameBuffer::init();
+ if (lfb == NULL) {
+ printf(LOGTAG "CFrameBuffer::init() failed.\n");
+ return; /* too bad... */
+ }
+ available = fix.smem_len;
+ printf(LOGTAG "%dk video mem\n", available / 1024);
+ memset(lfb, 0, available);
+
+ lbb = lfb; /* the memory area to draw to... */
+ available = fix.smem_len;
+ stride = fix.line_length;
+ xRes = screeninfo.xres;
+ yRes = screeninfo.yres;
+ bpp = screeninfo.bits_per_pixel;
+
+ return;
+}
+
+/* wrong name... */
+int CFbAccelTD::setMode(unsigned int, unsigned int, unsigned int)
+{
+ int needmem = stride * yRes * 2;
+ if (available >= needmem)
+ {
+ backbuffer = lfb + stride / sizeof(fb_pixel_t) * yRes;
+ return 0;
+ }
+ fprintf(stderr, LOGTAG " not enough FB memory (have %d, need %d)\n", available, needmem);
+ backbuffer = lfb; /* will not work well, but avoid crashes */
+ return 0;
+}
diff --git a/src/driver/fb_generic.cpp b/src/driver/fb_generic.cpp
index 1ded80c78..3453fee1e 100644
--- a/src/driver/fb_generic.cpp
+++ b/src/driver/fb_generic.cpp
@@ -133,6 +133,9 @@ CFrameBuffer* CFrameBuffer::getInstance()
#endif
#if HAVE_GENERIC_HARDWARE
frameBuffer = new CFbAccelGLFB();
+#endif
+#if HAVE_TRIPLEDRAGON
+ frameBuffer = new CFbAccelTD();
#endif
if (!frameBuffer)
frameBuffer = new CFrameBuffer();