aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvanfanel2015-01-27 17:58:08 +0100
committervanfanel2015-03-29 21:52:53 +0200
commit08a3376ba7bdcd262131eafa5ae5e4e8a4ecf18d (patch)
tree4192497ebe80372c18c192222e3e88f8019eb84e
parent79b92fe04698d3336f1d5232d4701133ff3ac10c (diff)
downloadscummvm-rg350-08a3376ba7bdcd262131eafa5ae5e4e8a4ecf18d.tar.gz
scummvm-rg350-08a3376ba7bdcd262131eafa5ae5e4e8a4ecf18d.tar.bz2
scummvm-rg350-08a3376ba7bdcd262131eafa5ae5e4e8a4ecf18d.zip
RASPBERRYPI: Added Raspberry Pi native 2D API support (dispmanx)
-rw-r--r--backends/graphics/dispmanxsdl/dispmanxsdl-graphics.cpp505
-rw-r--r--backends/graphics/dispmanxsdl/dispmanxsdl-graphics.h49
-rw-r--r--backends/module.mk5
-rw-r--r--backends/platform/sdl/module.mk6
-rw-r--r--backends/platform/sdl/posix/posix-main.cpp2
-rw-r--r--backends/platform/sdl/raspberrypi/raspberrypi-main.cpp51
-rw-r--r--backends/platform/sdl/raspberrypi/raspberrypi.cpp42
-rw-r--r--backends/platform/sdl/raspberrypi/raspberrypi.h35
-rwxr-xr-xconfigure31
9 files changed, 723 insertions, 3 deletions
diff --git a/backends/graphics/dispmanxsdl/dispmanxsdl-graphics.cpp b/backends/graphics/dispmanxsdl/dispmanxsdl-graphics.cpp
new file mode 100644
index 0000000000..03a10f1a0f
--- /dev/null
+++ b/backends/graphics/dispmanxsdl/dispmanxsdl-graphics.cpp
@@ -0,0 +1,505 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+//Needed for Raspberry Pi header incussion
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "common/scummsys.h"
+
+#if defined(RASPBERRYPI)
+
+#include "backends/graphics/dispmanxsdl/dispmanxsdl-graphics.h"
+#include "graphics/scaler/aspect.h"
+#include "common/mutex.h"
+#include "common/textconsole.h"
+
+#include <bcm_host.h>
+
+struct dispvarsStruct {
+ DISPMANX_DISPLAY_HANDLE_T display;
+ DISPMANX_MODEINFO_T amode;
+ DISPMANX_UPDATE_HANDLE_T update;
+ DISPMANX_RESOURCE_HANDLE_T resources[2];
+ DISPMANX_ELEMENT_HANDLE_T element;
+ VC_IMAGE_TYPE_T pixFormat;
+ VC_DISPMANX_ALPHA_T *alpha;
+ VC_RECT_T srcRect;
+ VC_RECT_T dstRect;
+ VC_RECT_T bmpRect;
+ uint vcImagePtr;
+ uint screen;
+ uint pitch;
+ uint flipPage;
+ bool aspectRatioCorrection;
+ void *pixmem;
+};
+
+DispmanXSdlGraphicsManager::DispmanXSdlGraphicsManager(SdlEventSource *sdlEventSource)
+ : SurfaceSdlGraphicsManager(sdlEventSource) {
+ _dispvars = new dispvarsStruct;
+ DispmanXInit();
+}
+
+DispmanXSdlGraphicsManager::~DispmanXSdlGraphicsManager()
+{
+ DispmanXVideoQuit();
+ delete _dispvars;
+}
+
+void DispmanXSdlGraphicsManager::DispmanXInit () {
+ _dispvars->screen = 0;
+ _dispvars->flipPage = 0;
+ _dispvars->vcImagePtr = 0;
+
+ // Before we call any vc_* function, we need to call this one.
+ bcm_host_init();
+
+ _dispvars->display = vc_dispmanx_display_open(_dispvars->screen);
+}
+
+void DispmanXSdlGraphicsManager::DispmanXSetup (int width, int height, int bpp) {
+ DispmanXFreeResources();
+ vc_dispmanx_display_get_info(_dispvars->display, &(_dispvars->amode));
+
+ _dispvars->pitch = width * (bpp/8);
+ _dispvars->pixFormat = VC_IMAGE_RGB565;
+
+ // Transparency disabled
+ VC_DISPMANX_ALPHA_T layerAlpha;
+ layerAlpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
+ layerAlpha.opacity = 255;
+ layerAlpha.mask = 0;
+ _dispvars->alpha = &layerAlpha;
+
+ if (_dispvars->aspectRatioCorrection) {
+ float orig_ratio = ((float)width / (float)height);
+ int dst_width = _dispvars->amode.height * orig_ratio;
+
+ // If we obtain an scaled image width that is bigger than the physical screen width,
+ // then we keep the physical screen width as our maximun width.
+ if (dst_width > _dispvars->amode.width)
+ dst_width = _dispvars->amode.width;
+ int dst_ypos = (_dispvars->amode.width - dst_width) / 2;
+ vc_dispmanx_rect_set(&(_dispvars->dstRect), dst_ypos, 0,
+ dst_width, _dispvars->amode.height);
+ } else {
+ vc_dispmanx_rect_set(&(_dispvars->dstRect), 0, 0,
+ _dispvars->amode.width, _dispvars->amode.height);
+ }
+
+ // We configure the rects now
+ vc_dispmanx_rect_set(&(_dispvars->bmpRect), 0, 0, width, height);
+ vc_dispmanx_rect_set(&(_dispvars->srcRect), 0, 0, width << 16, height << 16);
+
+ // We create two resources for double buffering
+ _dispvars->resources[0] = vc_dispmanx_resource_create(_dispvars->pixFormat, width, height,
+ &(_dispvars->vcImagePtr));
+
+ _dispvars->resources[1] = vc_dispmanx_resource_create(_dispvars->pixFormat, width, height,
+ &(_dispvars->vcImagePtr));
+
+ // Add element
+ _dispvars->update = vc_dispmanx_update_start(0);
+
+ _dispvars->element = vc_dispmanx_element_add(_dispvars->update, _dispvars->display, 0,
+ &(_dispvars->dstRect), _dispvars->resources[_dispvars->flipPage], &(_dispvars->srcRect),
+ DISPMANX_PROTECTION_NONE, _dispvars->alpha, 0, (DISPMANX_TRANSFORM_T)0);
+
+ vc_dispmanx_update_submit_sync(_dispvars->update);
+}
+
+void DispmanXSdlGraphicsManager::DispmanXUpdate() {
+ vc_dispmanx_resource_write_data(_dispvars->resources[_dispvars->flipPage], _dispvars->pixFormat,
+ _dispvars->pitch, _dispvars->pixmem, &(_dispvars->bmpRect));
+
+ // Update starts
+ _dispvars->update = vc_dispmanx_update_start(0);
+
+ vc_dispmanx_element_change_source(_dispvars->update, _dispvars->element,
+ _dispvars->resources[_dispvars->flipPage]);
+
+ vc_dispmanx_update_submit_sync(_dispvars->update);
+ // Update ends
+
+ _dispvars->flipPage = !_dispvars->flipPage;
+ return;
+}
+
+void DispmanXSdlGraphicsManager::DispmanXFreeResources(void) {
+ _dispvars->update = vc_dispmanx_update_start(0);
+
+ vc_dispmanx_resource_delete(_dispvars->resources[0]);
+ vc_dispmanx_resource_delete(_dispvars->resources[1]);
+ vc_dispmanx_element_remove(_dispvars->update, _dispvars->element);
+
+ vc_dispmanx_update_submit_sync(_dispvars->update);
+}
+
+void DispmanXSdlGraphicsManager::DispmanXVideoQuit() {
+ DispmanXFreeResources();
+ vc_dispmanx_display_close(_dispvars->display);
+ bcm_host_deinit();
+}
+
+bool DispmanXSdlGraphicsManager::loadGFXMode() {
+ _forceFull = true;
+
+ // In DispmanX, we manage aspect ratio correction, so for scummvm it's always disabled.
+ _videoMode.aspectRatioCorrection = false;
+
+ _videoMode.overlayWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
+ _videoMode.overlayHeight = _videoMode.screenHeight * _videoMode.scaleFactor;
+ _videoMode.hardwareWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
+ _videoMode.hardwareHeight = _videoMode.screenHeight * _videoMode.scaleFactor;
+
+ //
+ // Create the surface that contains the 8 bit game data
+ //
+#ifdef USE_RGB_COLOR
+ _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight,
+ _screenFormat.bytesPerPixel << 3,
+ ((1 << _screenFormat.rBits()) - 1) << _screenFormat.rShift ,
+ ((1 << _screenFormat.gBits()) - 1) << _screenFormat.gShift ,
+ ((1 << _screenFormat.bBits()) - 1) << _screenFormat.bShift ,
+ ((1 << _screenFormat.aBits()) - 1) << _screenFormat.aShift );
+ if (_screen == NULL)
+ error("allocating _screen failed");
+
+ // Avoid having SDL_SRCALPHA set even if we supplied an alpha-channel in the format.
+ SDL_SetAlpha(_screen, 0, 255);
+#else
+ _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, 8, 0, 0, 0, 0);
+ if (_screen == NULL)
+ error("allocating _screen failed");
+#endif
+
+ // SDL 1.2 palettes default to all black,
+ // SDL 1.3 palettes default to all white,
+ // Thus set our own default palette to all black.
+ // SDL_SetColors does nothing for non indexed surfaces.
+ SDL_SetColors(_screen, _currentPalette, 0, 256);
+
+ //
+ // Create the surface that contains the scaled graphics in 16 bit mode
+ //
+
+ // We call DispmanXSetup() before SDL_SetVideoMode() because we use _hwscreen == null
+ // to know inside DispmanXSetup() if we've been there before and need to free resources.
+ DispmanXSetup(_videoMode.screenWidth, _videoMode.screenHeight, 16);
+ // _hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 16, SDL_FULLSCREEN);
+ _hwscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.hardwareWidth, _videoMode.hardwareHeight, 16,
+ 0, 0, 0, 0);
+
+ _dispvars->pixmem = _hwscreen->pixels;
+
+ // We draw on a RAM surface, but we make this call just to get SDL input initialized.
+ // Even if we don't use the returned SDL_Surface *, we still need to use the right dimensions
+ // for mouse pointer adjustment to work correctly.
+ SDL_SetVideoMode(_videoMode.screenWidth, _videoMode.screenHeight, 16, SDL_FULLSCREEN);
+
+#ifdef USE_RGB_COLOR
+ detectSupportedFormats();
+#endif
+
+ if (_hwscreen == NULL) {
+ // DON'T use error(), as this tries to bring up the debug
+ // console, which WON'T WORK now that _hwscreen is hosed.
+
+ if (!_oldVideoMode.setup) {
+ warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError());
+ g_system->quit();
+ } else {
+ return false;
+ }
+ }
+
+ //
+ // Create the surface used for the graphics in 16 bit before scaling, and also the overlay
+ //
+
+ // Need some extra bytes around when using 2xSaI
+ _tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth + 3, _videoMode.screenHeight + 3,
+ 16,
+ _hwscreen->format->Rmask,
+ _hwscreen->format->Gmask,
+ _hwscreen->format->Bmask,
+ _hwscreen->format->Amask);
+
+ if (_tmpscreen == NULL)
+ error("allocating _tmpscreen failed");
+
+ _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth, _videoMode.overlayHeight,
+ 16,
+ _hwscreen->format->Rmask,
+ _hwscreen->format->Gmask,
+ _hwscreen->format->Bmask,
+ _hwscreen->format->Amask);
+
+ if (_overlayscreen == NULL)
+ error("allocating _overlayscreen failed");
+
+ _overlayFormat.bytesPerPixel = _overlayscreen->format->BytesPerPixel;
+
+ _overlayFormat.rLoss = _overlayscreen->format->Rloss;
+ _overlayFormat.gLoss = _overlayscreen->format->Gloss;
+ _overlayFormat.bLoss = _overlayscreen->format->Bloss;
+ _overlayFormat.aLoss = _overlayscreen->format->Aloss;
+
+ _overlayFormat.rShift = _overlayscreen->format->Rshift;
+ _overlayFormat.gShift = _overlayscreen->format->Gshift;
+ _overlayFormat.bShift = _overlayscreen->format->Bshift;
+ _overlayFormat.aShift = _overlayscreen->format->Ashift;
+
+ _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth + 3, _videoMode.overlayHeight + 3,
+ 16,
+ _hwscreen->format->Rmask,
+ _hwscreen->format->Gmask,
+ _hwscreen->format->Bmask,
+ _hwscreen->format->Amask);
+
+ if (_tmpscreen2 == NULL)
+ error("allocating _tmpscreen2 failed");
+
+#ifdef USE_OSD
+ _osdSurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA,
+ _hwscreen->w,
+ _hwscreen->h,
+ 16,
+ _hwscreen->format->Rmask,
+ _hwscreen->format->Gmask,
+ _hwscreen->format->Bmask,
+ _hwscreen->format->Amask);
+ if (_osdSurface == NULL)
+ error("allocating _osdSurface failed");
+ SDL_SetColorKey(_osdSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, kOSDColorKey);
+#endif
+
+ _eventSource->resetKeyboadEmulation(
+ _videoMode.screenWidth * _videoMode.scaleFactor - 1,
+ effectiveScreenHeight() - 1);
+
+ // Distinguish 555 and 565 mode
+ if (_hwscreen->format->Rmask == 0x7C00)
+ InitScalers(555);
+ else
+ InitScalers(565);
+
+ return true;
+}
+
+void DispmanXSdlGraphicsManager::internUpdateScreen() {
+ SDL_Surface *srcSurf, *origSurf;
+ int height, width;
+ ScalerProc *scalerProc;
+ int scale1;
+
+ // If the shake position changed, fill the dirty area with blackness
+ if (_currentShakePos != _newShakePos ||
+ (_mouseNeedsRedraw && _mouseBackup.y <= _currentShakePos)) {
+ SDL_Rect blackrect = {0, 0, (Uint16)(_videoMode.screenWidth * _videoMode.scaleFactor), (Uint16)(_newShakePos * _videoMode.scaleFactor)};
+
+ SDL_FillRect(_hwscreen, &blackrect, 0);
+
+ _currentShakePos = _newShakePos;
+
+ _forceFull = true;
+ }
+
+ // Check whether the palette was changed in the meantime and update the
+ // screen surface accordingly.
+ if (_screen && _paletteDirtyEnd != 0) {
+ SDL_SetColors(_screen, _currentPalette + _paletteDirtyStart,
+ _paletteDirtyStart,
+ _paletteDirtyEnd - _paletteDirtyStart);
+
+ _paletteDirtyEnd = 0;
+
+ _forceFull = true;
+ }
+
+#ifdef USE_OSD
+ // OSD visible (i.e. non-transparent)?
+ if (_osdAlpha != SDL_ALPHA_TRANSPARENT) {
+ // Updated alpha value
+ const int diff = SDL_GetTicks() - _osdFadeStartTime;
+ if (diff > 0) {
+ if (diff >= kOSDFadeOutDuration) {
+ // Back to full transparency
+ _osdAlpha = SDL_ALPHA_TRANSPARENT;
+ } else {
+ // Do a linear fade out...
+ const int startAlpha = SDL_ALPHA_TRANSPARENT + kOSDInitialAlpha * (SDL_ALPHA_OPAQUE - SDL_ALPHA_TRANSPARENT) / 100;
+ _osdAlpha = startAlpha + diff * (SDL_ALPHA_TRANSPARENT - startAlpha) / kOSDFadeOutDuration;
+ }
+ SDL_SetAlpha(_osdSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, _osdAlpha);
+ _forceFull = true;
+ }
+ }
+#endif
+
+ if (!_overlayVisible) {
+ origSurf = _screen;
+ srcSurf = _tmpscreen;
+ width = _videoMode.screenWidth;
+ height = _videoMode.screenHeight;
+ scalerProc = _scalerProc;
+ scale1 = _videoMode.scaleFactor;
+ } else {
+ origSurf = _overlayscreen;
+ srcSurf = _tmpscreen2;
+ width = _videoMode.overlayWidth;
+ height = _videoMode.overlayHeight;
+ scalerProc = Normal1x;
+
+ scale1 = 1;
+ }
+
+ // Add the area covered by the mouse cursor to the list of dirty rects if
+ // we have to redraw the mouse.
+ if (_mouseNeedsRedraw)
+ undrawMouse();
+
+ // Force a full redraw if requested
+ if (_forceFull) {
+ _numDirtyRects = 1;
+ _dirtyRectList[0].x = 0;
+ _dirtyRectList[0].y = 0;
+ _dirtyRectList[0].w = width;
+ _dirtyRectList[0].h = height;
+ }
+
+ // Only draw anything if necessary
+ if (_numDirtyRects > 0 || _mouseNeedsRedraw) {
+ SDL_Rect *r;
+ SDL_Rect dst;
+ uint32 srcPitch, dstPitch;
+ SDL_Rect *lastRect = _dirtyRectList + _numDirtyRects;
+
+ for (r = _dirtyRectList; r != lastRect; ++r) {
+ dst = *r;
+ dst.x++; // Shift rect by one since 2xSai needs to access the data around
+ dst.y++; // any pixel to scale it, and we want to avoid mem access crashes.
+
+ if (SDL_BlitSurface(origSurf, r, srcSurf, &dst) != 0)
+ error("SDL_BlitSurface failed: %s", SDL_GetError());
+ }
+
+ SDL_LockSurface(srcSurf);
+ SDL_LockSurface(_hwscreen);
+
+ srcPitch = srcSurf->pitch;
+ dstPitch = _hwscreen->pitch;
+
+ for (r = _dirtyRectList; r != lastRect; ++r) {
+ register int dst_y = r->y + _currentShakePos;
+ register int dst_h = 0;
+ register int rx1 = r->x * scale1;
+
+ if (dst_y < height) {
+ dst_h = r->h;
+ if (dst_h > height - dst_y)
+ dst_h = height - dst_y;
+
+ dst_y = dst_y * scale1;
+
+ assert(scalerProc != NULL);
+ scalerProc((byte *)srcSurf->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch,
+ (byte *)_hwscreen->pixels + rx1 * 2 + dst_y * dstPitch, dstPitch, r->w, dst_h);
+ }
+
+ r->x = rx1;
+ r->y = dst_y;
+ r->w = r->w * scale1;
+ r->h = dst_h * scale1;
+
+ }
+ SDL_UnlockSurface(srcSurf);
+ SDL_UnlockSurface(_hwscreen);
+
+ // Readjust the dirty rect list in case we are doing a full update.
+ // This is necessary if shaking is active.
+ if (_forceFull) {
+ _dirtyRectList[0].y = 0;
+ _dirtyRectList[0].h = effectiveScreenHeight();
+ }
+
+ drawMouse();
+
+#ifdef USE_OSD
+ if (_osdAlpha != SDL_ALPHA_TRANSPARENT) {
+ SDL_BlitSurface(_osdSurface, 0, _hwscreen, 0);
+ }
+#endif
+ // Finally, blit all our changes to the screen
+ if (!_displayDisabled) {
+ SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList);
+ DispmanXUpdate();
+ }
+ }
+
+ _numDirtyRects = 0;
+ _forceFull = false;
+ _mouseNeedsRedraw = false;
+}
+
+bool DispmanXSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
+
+ // Ctrl-Alt-a toggles aspect ratio correction
+ if (key == 'a') {
+ beginGFXTransaction();
+ setFeatureState(OSystem::kFeatureAspectRatioCorrection, !_dispvars->aspectRatioCorrection);
+ endGFXTransaction();
+#ifdef USE_OSD
+ char buffer[128];
+ if (_dispvars->aspectRatioCorrection)
+ sprintf(buffer, "%s", ("Enabled aspect ratio correction"));
+ else
+ sprintf(buffer, "%s", ("Disabled aspect ratio correction"));
+ displayMessageOnOSD(buffer);
+#endif
+ internUpdateScreen();
+ return true;
+ }
+
+ return true;
+}
+
+void DispmanXSdlGraphicsManager::setFullscreenMode(bool enable) {
+ _videoMode.fullscreen = enable;
+ return;
+}
+
+void DispmanXSdlGraphicsManager::setAspectRatioCorrection(bool enable) {
+ Common::StackLock lock(_graphicsMutex);
+ // Ratio correction is managed externally by dispmanx, so we disable it at the SDL level but take note,
+ // so it's effectively taken into account at the dispmanx level in DispmanXSetup().
+ if (_oldVideoMode.setup && _dispvars->aspectRatioCorrection == enable)
+ return;
+
+ if (_transactionMode == kTransactionActive) {
+ _dispvars->aspectRatioCorrection = enable;
+ _transactionDetails.needHotswap = false;
+ DispmanXSetup(_videoMode.screenWidth, _videoMode.screenHeight, 16);
+ }
+}
+
+#endif
diff --git a/backends/graphics/dispmanxsdl/dispmanxsdl-graphics.h b/backends/graphics/dispmanxsdl/dispmanxsdl-graphics.h
new file mode 100644
index 0000000000..ff38283195
--- /dev/null
+++ b/backends/graphics/dispmanxsdl/dispmanxsdl-graphics.h
@@ -0,0 +1,49 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BACKENDS_GRAPHICS_SDL_DISPMANX_H
+#define BACKENDS_GRAPHICS_SDL_DISPMANX_H
+
+#include "backends/graphics/surfacesdl/surfacesdl-graphics.h"
+
+struct dispvarsStruct;
+
+class DispmanXSdlGraphicsManager : public SurfaceSdlGraphicsManager {
+public:
+ DispmanXSdlGraphicsManager(SdlEventSource *sdlEventSource);
+ ~DispmanXSdlGraphicsManager();
+ bool loadGFXMode();
+ void internUpdateScreen();
+ bool handleScalerHotkeys(Common::KeyCode key);
+ void setFullscreenMode(bool enable);
+ void setAspectRatioCorrection(bool enable);
+protected:
+ // Raspberry Pi Dispmanx API
+ void DispmanXSetup(int width, int height, int bpp);
+ void DispmanXInit();
+ void DispmanXUpdate();
+ void DispmanXFreeResources(void);
+ void DispmanXVideoQuit();
+ struct dispvarsStruct *_dispvars;
+};
+
+#endif /* BACKENDS_GRAPHICS_SDL_DISPMANX_H */
diff --git a/backends/module.mk b/backends/module.mk
index 34e2928419..645b5eda78 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -193,6 +193,11 @@ MODULE_OBJS += \
timer/psp/timer.o
endif
+ifeq ($(BACKEND),raspberrypi)
+MODULE_OBJS += \
+ graphics/dispmanxsdl/dispmanxsdl-graphics.o
+endif
+
ifeq ($(BACKEND),samsungtv)
MODULE_OBJS += \
events/samsungtvsdl/samsungtvsdl-events.o \
diff --git a/backends/platform/sdl/module.mk b/backends/platform/sdl/module.mk
index a17a326889..d87ec6b0d3 100644
--- a/backends/platform/sdl/module.mk
+++ b/backends/platform/sdl/module.mk
@@ -34,6 +34,12 @@ MODULE_OBJS += \
ps3/ps3.o
endif
+ifdef RASPBERRYPI
+MODULE_OBJS += \
+ raspberrypi/raspberrypi-main.o \
+ raspberrypi/raspberrypi.o
+endif
+
# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))
OBJS := $(MODULE_OBJS) $(OBJS)
diff --git a/backends/platform/sdl/posix/posix-main.cpp b/backends/platform/sdl/posix/posix-main.cpp
index d07db11b0c..0785f36df7 100644
--- a/backends/platform/sdl/posix/posix-main.cpp
+++ b/backends/platform/sdl/posix/posix-main.cpp
@@ -22,7 +22,7 @@
#include "common/scummsys.h"
-#if defined(POSIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(MAEMO) && !defined(WEBOS) && !defined(LINUXMOTO) && !defined(GPH_DEVICE) && !defined(GP2X) && !defined(DINGUX) && !defined(OPENPANDORA) && !defined(PLAYSTATION3)
+#if defined(POSIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(MAEMO) && !defined(WEBOS) && !defined(LINUXMOTO) && !defined(GPH_DEVICE) && !defined(GP2X) && !defined(DINGUX) && !defined(OPENPANDORA) && !defined(PLAYSTATION3) && !defined(RASPBERRYPI)
#include "backends/platform/sdl/posix/posix.h"
#include "backends/plugins/sdl/sdl-provider.h"
diff --git a/backends/platform/sdl/raspberrypi/raspberrypi-main.cpp b/backends/platform/sdl/raspberrypi/raspberrypi-main.cpp
new file mode 100644
index 0000000000..7d2eff916d
--- /dev/null
+++ b/backends/platform/sdl/raspberrypi/raspberrypi-main.cpp
@@ -0,0 +1,51 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "backends/platform/sdl/raspberrypi/raspberrypi.h"
+#include "backends/plugins/sdl/sdl-provider.h"
+#include "common/scummsys.h"
+#include "base/main.h"
+
+#if defined(RASPBERRYPI)
+int main(int argc, char* argv[]) {
+
+ // Create our OSystem instance
+ g_system = new OSystem_SDL_RaspberryPi();
+ assert(g_system);
+
+ // Pre initialize the backend
+ ((OSystem_SDL_RaspberryPi *)g_system)->init();
+
+#ifdef DYNAMIC_MODULES
+ PluginManager::instance().addPluginProvider(new SDLPluginProvider());
+#endif
+
+ // Invoke the actual ScummVM main entry point:
+ int res = scummvm_main(argc, argv);
+
+ // Free OSystem
+ delete (OSystem_SDL_RaspberryPi *)g_system;
+
+ return res;
+}
+
+#endif
diff --git a/backends/platform/sdl/raspberrypi/raspberrypi.cpp b/backends/platform/sdl/raspberrypi/raspberrypi.cpp
new file mode 100644
index 0000000000..2405dfaf43
--- /dev/null
+++ b/backends/platform/sdl/raspberrypi/raspberrypi.cpp
@@ -0,0 +1,42 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#if defined(RASPBERRYPI)
+
+#include "backends/platform/sdl/raspberrypi/raspberrypi.h"
+#include "backends/graphics/dispmanxsdl/dispmanxsdl-graphics.h"
+
+void OSystem_SDL_RaspberryPi::initBackend() {
+ // Create the events manager
+ if (_eventSource == 0)
+ _eventSource = new SdlEventSource();
+
+ // Create the graphics manager
+ if (_graphicsManager == 0) {
+ _graphicsManager = new DispmanXSdlGraphicsManager(_eventSource);
+ }
+
+ // Call parent implementation of this method
+ OSystem_POSIX::initBackend();
+}
+
+#endif
diff --git a/backends/platform/sdl/raspberrypi/raspberrypi.h b/backends/platform/sdl/raspberrypi/raspberrypi.h
new file mode 100644
index 0000000000..b8070e8b5a
--- /dev/null
+++ b/backends/platform/sdl/raspberrypi/raspberrypi.h
@@ -0,0 +1,35 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SDL_RASPBERRYPI_COMMON_H
+#define SDL_RASPBERRYPI_COMMON_H
+
+#if defined(RASPBERRYPI)
+#include "backends/platform/sdl/posix/posix.h"
+
+class OSystem_SDL_RaspberryPi : public OSystem_POSIX {
+public:
+ void initBackend();
+};
+
+#endif /* RASPBERRYPI */
+#endif /* SDL_RASPBERRYPI_COMMON_H */
diff --git a/configure b/configure
index 7c4c87e3af..a5bb1e6e93 100755
--- a/configure
+++ b/configure
@@ -824,7 +824,7 @@ Configuration:
-h, --help display this help and exit
--backend=BACKEND backend to build (android, tizen, dc, dingux, ds, gcw0,
gph, iphone, linuxmoto, maemo, n64, null, openpandora,
- ps2, psp, samsungtv, sdl, webos, wii, wince) [sdl]
+ ps2, psp, raspberrypi, samsungtv, sdl, webos, wii, wince) [sdl]
Installation directories:
--prefix=PREFIX install architecture-independent files in PREFIX
@@ -2980,6 +2980,33 @@ case $_backend in
LIBS="$LIBS -lpng"
LIBS="$LIBS -Wl,-Map,mapfile.txt"
;;
+ raspberrypi)
+ _use_dispmanx=no
+ DISPMANX_CXXFLAGS="-I/opt/vc/include -I/opt/vc/include/interface/vmcs_host/linux/ -I/opt/vc/include/interface/vcos/pthreads -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s"
+ DISPMANX_LIBS="-L/opt/vc/lib -lbcm_host -lvcos -lvchiq_arm"
+ cat > $TMPC << EOF
+#include <bcm_host.h>
+
+ int main(int argc, char *argv[]) {
+ bcm_host_init();
+}
+EOF
+ cc_check $DISPMANX_CXXFLAGS $DISPMANX_LIBS && _use_dispmanx=yes
+ if test "$_use_dispmanx" = "yes"; then
+ echo "Activating Raspberry Pi DispmanX graphics backend"
+ CXXFLAGS="$CXXFLAGS $DISPMANX_CXXFLAGS"
+ LIBS="$LIBS $DISPMANX_LIBS"
+ MODULES="$MODULES backends/platform/sdl"
+ DEFINES="$DEFINES -DRASPBERRYPI"
+ add_line_to_config_mk 'RASPBERRYPI = 1'
+ _build_scalers=no
+ _build_hq_scalers=no
+ _opengl=no
+ _default_optimization_level=-O3
+ else
+ echo "Can't activate DispmanX context (missing headers?)."
+ fi
+ ;;
samsungtv)
DEFINES="$DEFINES -DSAMSUNGTV"
LDFLAGS="$LDFLAGS -shared"
@@ -3046,7 +3073,7 @@ MODULES="$MODULES backends/platform/$_backend"
# Setup SDL specifics for SDL based backends
#
case $_backend in
- dingux | gph | linuxmoto | maemo | openpandora | samsungtv | sdl)
+ dingux | gph | linuxmoto | maemo | openpandora | raspberrypi | samsungtv | sdl)
find_sdlconfig
INCLUDES="$INCLUDES `$_sdlconfig --prefix="$_sdlpath" --cflags`"
LIBS="$LIBS `$_sdlconfig --prefix="$_sdlpath" --libs`"