IOS7: Change OSystem_iOS7 to be a ModularGraphicsBackend

Remove all pure virtual functions in OSystem_iOS7 since they are
implemented by ModularGraphicsBackend.

This commit will break the graphics implementation in the ios7
backend and crash due to no OpenGL context created for the
graphicsManager to use.
This commit is contained in:
Lars Sundström 2023-06-02 08:13:05 +02:00
parent e6232547d5
commit 580d8424ca
3 changed files with 8 additions and 414 deletions

View File

@ -44,6 +44,7 @@
#include "gui/gui-manager.h"
#include "backends/graphics/ios/ios-graphics.h"
#include "backends/saves/default/default-saves.h"
#include "backends/timer/default/default-timer.h"
#include "backends/mutex/pthread/pthread-mutex.h"
@ -120,6 +121,7 @@ OSystem_iOS7::~OSystem_iOS7() {
if (_framebuffer.getPixels() != _videoContext->screenTexture.getPixels())
_framebuffer.free();
_mouseBuffer.free();
delete _graphicsManager;
}
bool OSystem_iOS7::touchpadModeEnabled() const {
@ -145,6 +147,8 @@ void OSystem_iOS7::initBackend() {
_startTime = CACurrentMediaTime();
_graphicsManager = new iOSGraphicsManager();
setupMixer();
setTimerCallback(&OSystem_iOS7::timerHandler, 10);
@ -166,7 +170,7 @@ bool OSystem_iOS7::hasFeature(Feature f) {
return true;
default:
return false;
return ModularGraphicsBackend::hasFeature(f);
}
}
@ -190,6 +194,7 @@ void OSystem_iOS7::setFeatureState(Feature f, bool enable) {
break;
default:
ModularGraphicsBackend::setFeatureState(f, enable);
break;
}
}
@ -206,7 +211,7 @@ bool OSystem_iOS7::getFeatureState(Feature f) {
return isKeyboardShown();
default:
return false;
return ModularGraphicsBackend::getFeatureState(f);
}
}

View File

@ -50,7 +50,7 @@ struct AQCallbackStruct {
AudioStreamBasicDescription dataFormat;
};
class OSystem_iOS7 : public EventsBaseBackend, public PaletteManager {
class OSystem_iOS7 : public ModularGraphicsBackend, public EventsBaseBackend {
protected:
static AQCallbackStruct s_AudioQueue;
static SoundProc s_soundCallback;
@ -122,13 +122,6 @@ public:
bool hasFeature(Feature f) override;
void setFeatureState(Feature f, bool enable) override;
bool getFeatureState(Feature f) override;
void initSize(uint width, uint height, const Graphics::PixelFormat *format) override;
void beginGFXTransaction() override;
TransactionError endGFXTransaction() override;
int16 getHeight() override;
int16 getWidth() override;
bool touchpadModeEnabled() const;
@ -139,46 +132,11 @@ public:
int getScreenHeight() const;
float getSystemHiDPIScreenFactor() const;
#ifdef USE_RGB_COLOR
Graphics::PixelFormat getScreenFormat() const override { return _framebuffer.format; }
Common::List<Graphics::PixelFormat> getSupportedFormats() const override;
#endif
#if defined(USE_OPENGL) && defined(USE_GLAD)
void *getOpenGLProcAddress(const char *name) const override;
#endif
PaletteManager *getPaletteManager() override { return this; }
float getHiDPIScreenFactor() const override;
protected:
// PaletteManager API
void setPalette(const byte *colors, uint start, uint num) override;
void grabPalette(byte *colors, uint start, uint num) const override;
public:
void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) override;
void updateScreen() override;
Graphics::Surface *lockScreen() override;
void unlockScreen() override;
void setShakePos(int shakeXOffset, int shakeYOffset) override;
void showOverlay(bool inGUI) override;
void hideOverlay() override;
bool isOverlayVisible() const override { return _videoContext->overlayVisible; }
void clearOverlay() override;
void grabOverlay(Graphics::Surface &surface) override;
void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override;
int16 getOverlayHeight() override;
int16 getOverlayWidth() override;
Graphics::PixelFormat getOverlayFormat() const override;
bool showMouse(bool visible) override;
void warpMouse(int x, int y) override;
void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 255, bool dontScale = false, const Graphics::PixelFormat *format = NULL, const byte *mask = NULL) override;
void setCursorPalette(const byte *colors, uint start, uint num) override;
bool pollEvent(Common::Event &event) override;
uint32 getMillis(bool skipRecord = false) override;
void delayMillis(uint msecs) override;
@ -187,7 +145,6 @@ public:
static void mixCallback(void *sys, byte *samples, int len);
virtual void setupMixer(void);
virtual void setTimerCallback(TimerProc callback, int interval);
int getScreenChangeID() const override { return _screenChangeCount; }
void quit() override;
void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0) override;

View File

@ -100,21 +100,6 @@ void OSystem_iOS7::initVideoContext() {
_videoContext = [[iOS7AppDelegate iPhoneView] getVideoContext];
}
#ifdef USE_RGB_COLOR
Common::List<Graphics::PixelFormat> OSystem_iOS7::getSupportedFormats() const {
Common::List<Graphics::PixelFormat> list;
// ABGR8888 (big endian)
list.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
// RGBA8888 (big endian)
list.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
// RGB565
list.push_back(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
// CLUT8
list.push_back(Graphics::PixelFormat::createFormatCLUT8());
return list;
}
#endif
static inline void execute_on_main_thread(void (^block)(void)) {
if ([NSThread currentThread] == [NSThread mainThread]) {
block();
@ -124,187 +109,12 @@ static inline void execute_on_main_thread(void (^block)(void)) {
}
}
float OSystem_iOS7::getHiDPIScreenFactor() const {
return [UIScreen mainScreen].scale;
}
void OSystem_iOS7::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
//printf("initSize(%u, %u, %p)\n", width, height, (const void *)format);
_videoContext->screenWidth = width;
_videoContext->screenHeight = height;
_videoContext->shakeXOffset = 0;
_videoContext->shakeYOffset = 0;
// In case we use the screen texture as frame buffer we reset the pixels
// pointer here to avoid freeing the screen texture.
if (_framebuffer.getPixels() == _videoContext->screenTexture.getPixels())
_framebuffer.setPixels(0);
// Create the screen texture right here. We need to do this here, since
// when a game requests hi-color mode, we actually set the framebuffer
// to the texture buffer to avoid an additional copy step.
// Free any previous screen texture and create new to handle format changes
_videoContext->screenTexture.free();
if (format && *format == Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)) {
// ABGR8888 (big endian)
_videoContext->screenTexture.create((uint16) getSizeNextPOT(_videoContext->screenWidth), (uint16) getSizeNextPOT(_videoContext->screenHeight), Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
} else if (format && *format == Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)) {
// RGBA8888 (big endian)
_videoContext->screenTexture.create((uint16) getSizeNextPOT(_videoContext->screenWidth), (uint16) getSizeNextPOT(_videoContext->screenHeight), Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
} else {
// Assume RGB565
_videoContext->screenTexture.create((uint16) getSizeNextPOT(_videoContext->screenWidth), (uint16) getSizeNextPOT(_videoContext->screenHeight), Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
}
// In case the client code tries to set up a non supported mode, we will
// fall back to CLUT8 and set the transaction error accordingly.
if (format && format->bytesPerPixel != 1 && *format != _videoContext->screenTexture.format) {
format = 0;
_gfxTransactionError = kTransactionFormatNotSupported;
}
execute_on_main_thread(^{
[[iOS7AppDelegate iPhoneView] setGameScreenCoords];
});
if (!format || format->bytesPerPixel == 1) {
_framebuffer.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
} else {
#if 0
printf("bytesPerPixel: %u RGBAlosses: %u,%u,%u,%u RGBAshifts: %u,%u,%u,%u\n", format->bytesPerPixel,
format->rLoss, format->gLoss, format->bLoss, format->aLoss,
format->rShift, format->gShift, format->bShift, format->aShift);
#endif
// We directly draw on the screen texture in hi-color mode. Thus
// we copy over its settings here and just replace the width and
// height to avoid any problems.
_framebuffer = _videoContext->screenTexture;
_framebuffer.w = width;
_framebuffer.h = height;
}
_fullScreenIsDirty = false;
dirtyFullScreen();
_mouseCursorPaletteEnabled = false;
}
void OSystem_iOS7::beginGFXTransaction() {
_gfxTransactionError = kTransactionSuccess;
}
OSystem::TransactionError OSystem_iOS7::endGFXTransaction() {
_screenChangeCount++;
updateOutputSurface();
execute_on_main_thread(^ {
[[iOS7AppDelegate iPhoneView] setGraphicsMode];
});
return _gfxTransactionError;
}
void OSystem_iOS7::updateOutputSurface() {
execute_on_main_thread(^ {
[[iOS7AppDelegate iPhoneView] initSurface];
});
}
int16 OSystem_iOS7::getHeight() {
return _videoContext->screenHeight;
}
int16 OSystem_iOS7::getWidth() {
return _videoContext->screenWidth;
}
void OSystem_iOS7::setPalette(const byte *colors, uint start, uint num) {
//printf("setPalette(%p, %u, %u)\n", colors, start, num);
assert(start + num <= 256);
const byte *b = colors;
for (uint i = start; i < start + num; ++i) {
_gamePalette[i] = _videoContext->screenTexture.format.RGBToColor(b[0], b[1], b[2]);
_gamePaletteRGBA5551[i] = _videoContext->mouseTexture.format.RGBToColor(b[0], b[1], b[2]);
b += 3;
}
dirtyFullScreen();
// Automatically update the mouse texture when the palette changes while the
// cursor palette is disabled.
if (!_mouseCursorPaletteEnabled && _mouseBuffer.format.bytesPerPixel == 1)
_mouseDirty = _mouseNeedTextureUpdate = true;
}
void OSystem_iOS7::grabPalette(byte *colors, uint start, uint num) const {
//printf("grabPalette(%p, %u, %u)\n", colors, start, num);
assert(start + num <= 256);
byte *b = colors;
for (uint i = start; i < start + num; ++i) {
_videoContext->screenTexture.format.colorToRGB(_gamePalette[i], b[0], b[1], b[2]);
b += 3;
}
}
void OSystem_iOS7::copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) {
//printf("copyRectToScreen(%p, %d, %i, %i, %i, %i)\n", buf, pitch, x, y, w, h);
//Clip the coordinates
const byte *src = (const byte *)buf;
if (x < 0) {
w += x;
src -= x;
x = 0;
}
if (y < 0) {
h += y;
src -= y * pitch;
y = 0;
}
if (w > (int)_framebuffer.w - x) {
w = _framebuffer.w - x;
}
if (h > (int)_framebuffer.h - y) {
h = _framebuffer.h - y;
}
if (w <= 0 || h <= 0)
return;
if (!_fullScreenIsDirty) {
_dirtyRects.push_back(Common::Rect(x, y, x + w, y + h));
}
byte *dst = (byte *)_framebuffer.getBasePtr(x, y);
if (_framebuffer.pitch == pitch && _framebuffer.w == w) {
memcpy(dst, src, h * pitch);
} else {
do {
memcpy(dst, src, w * _framebuffer.format.bytesPerPixel);
src += pitch;
dst += _framebuffer.pitch;
} while (--h);
}
}
void OSystem_iOS7::updateScreen() {
if (_dirtyRects.size() == 0 && _dirtyOverlayRects.size() == 0 && !_mouseDirty)
return;
//printf("updateScreen(): %i dirty rects.\n", _dirtyRects.size());
internUpdateScreen();
_mouseDirty = false;
_fullScreenIsDirty = false;
_fullScreenOverlayIsDirty = false;
iOS7_updateScreen();
}
void OSystem_iOS7::internUpdateScreen() {
if (_mouseNeedTextureUpdate) {
updateMouseTexture();
@ -354,138 +164,6 @@ void OSystem_iOS7::drawDirtyRect(const Common::Rect &dirtyRect) {
}
}
Graphics::Surface *OSystem_iOS7::lockScreen() {
//printf("lockScreen()\n");
return &_framebuffer;
}
void OSystem_iOS7::unlockScreen() {
//printf("unlockScreen()\n");
dirtyFullScreen();
}
void OSystem_iOS7::setShakePos(int shakeXOffset, int shakeYOffset) {
//printf("setShakePos(%i, %i)\n", shakeXOffset, shakeYOffset);
_videoContext->shakeXOffset = shakeXOffset;
_videoContext->shakeYOffset = shakeYOffset;
execute_on_main_thread(^ {
[[iOS7AppDelegate iPhoneView] setViewTransformation];
});
// HACK: We use this to force a redraw.
_mouseDirty = true;
}
void OSystem_iOS7::showOverlay(bool inGUI) {
//printf("showOverlay()\n");
_videoContext->overlayVisible = true;
_videoContext->overlayInGUI = inGUI;
dirtyFullOverlayScreen();
updateScreen();
execute_on_main_thread(^ {
[[iOS7AppDelegate iPhoneView] updateMouseCursorScaling];
[[iOS7AppDelegate iPhoneView] clearColorBuffer];
});
}
void OSystem_iOS7::hideOverlay() {
//printf("hideOverlay()\n");
_videoContext->overlayVisible = false;
_videoContext->overlayInGUI = false;
_dirtyOverlayRects.clear();
dirtyFullScreen();
execute_on_main_thread(^ {
[[iOS7AppDelegate iPhoneView] updateMouseCursorScaling];
[[iOS7AppDelegate iPhoneView] clearColorBuffer];
});
}
void OSystem_iOS7::clearOverlay() {
//printf("clearOverlay()\n");
memset(_videoContext->overlayTexture.getPixels(), 0, _videoContext->overlayTexture.h * _videoContext->overlayTexture.pitch);
dirtyFullOverlayScreen();
}
void OSystem_iOS7::grabOverlay(Graphics::Surface &surface) {
//printf("grabOverlay()\n");
assert(surface.w >= (int16)_videoContext->overlayWidth);
assert(surface.h >= (int16)_videoContext->overlayHeight);
assert(surface.format.bytesPerPixel == sizeof(uint16));
const byte *src = (const byte *)_videoContext->overlayTexture.getPixels();
byte *dst = (byte *)surface.getPixels();
Graphics::copyBlit(dst, src, surface.pitch, _videoContext->overlayTexture.pitch,
_videoContext->overlayWidth, _videoContext->overlayHeight, sizeof(uint16));
}
void OSystem_iOS7::copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) {
//printf("copyRectToOverlay(%p, pitch=%i, x=%i, y=%i, w=%i, h=%i)\n", (const void *)buf, pitch, x, y, w, h);
const byte *src = (const byte *)buf;
//Clip the coordinates
if (x < 0) {
w += x;
src -= x * sizeof(uint16);
x = 0;
}
if (y < 0) {
h += y;
src -= y * pitch;
y = 0;
}
if (w > (int)_videoContext->overlayWidth - x)
w = _videoContext->overlayWidth - x;
if (h > (int)_videoContext->overlayHeight - y)
h = _videoContext->overlayHeight - y;
if (w <= 0 || h <= 0)
return;
if (!_fullScreenOverlayIsDirty) {
_dirtyOverlayRects.push_back(Common::Rect(x, y, x + w, y + h));
}
byte *dst = (byte *)_videoContext->overlayTexture.getBasePtr(x, y);
do {
memcpy(dst, src, w * sizeof(uint16));
src += pitch;
dst += _videoContext->overlayTexture.pitch;
} while (--h);
}
int16 OSystem_iOS7::getOverlayHeight() {
return _videoContext->overlayHeight;
}
int16 OSystem_iOS7::getOverlayWidth() {
return _videoContext->overlayWidth;
}
Graphics::PixelFormat OSystem_iOS7::getOverlayFormat() const {
return _videoContext->overlayTexture.format;
}
bool OSystem_iOS7::showMouse(bool visible) {
//printf("showMouse(%d)\n", visible);
bool last = _videoContext->mouseIsVisible;
_videoContext->mouseIsVisible = visible;
_mouseDirty = true;
return last;
}
void OSystem_iOS7::warpMouse(int x, int y) {
//printf("warpMouse(%d, %d)\n", x, y);
_videoContext->mouseX = x;
_videoContext->mouseY = y;
execute_on_main_thread(^ {
[[iOS7AppDelegate iPhoneView] notifyMouseMove];
});
_mouseDirty = true;
}
void OSystem_iOS7::virtualController(bool connect) {
execute_on_main_thread(^ {
[[iOS7AppDelegate iPhoneView] virtualController:connect];
@ -508,52 +186,6 @@ void OSystem_iOS7::dirtyFullOverlayScreen() {
}
}
void OSystem_iOS7::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format, const byte *mask) {
//printf("setMouseCursor(%p, %u, %u, %i, %i, %u, %d, %p)\n", (const void *)buf, w, h, hotspotX, hotspotY, keycolor, dontScale, (const void *)format);
if (mask)
printf("OSystem_iOS7::setMouseCursor: Masks are not supported");
const Graphics::PixelFormat pixelFormat = format ? *format : Graphics::PixelFormat::createFormatCLUT8();
#if 0
printf("bytesPerPixel: %u RGBAlosses: %u,%u,%u,%u RGBAshifts: %u,%u,%u,%u\n", pixelFormat.bytesPerPixel,
pixelFormat.rLoss, pixelFormat.gLoss, pixelFormat.bLoss, pixelFormat.aLoss,
pixelFormat.rShift, pixelFormat.gShift, pixelFormat.bShift, pixelFormat.aShift);
#endif
assert(pixelFormat.bytesPerPixel == 1 || pixelFormat.bytesPerPixel == 2 || pixelFormat.bytesPerPixel == 4);
if (_mouseBuffer.w != (int16)w || _mouseBuffer.h != (int16)h || _mouseBuffer.format != pixelFormat || !_mouseBuffer.getPixels())
_mouseBuffer.create(w, h, pixelFormat);
_videoContext->mouseWidth = w;
_videoContext->mouseHeight = h;
_videoContext->mouseHotspotX = hotspotX;
_videoContext->mouseHotspotY = hotspotY;
_mouseKeyColor = keycolor;
memcpy(_mouseBuffer.getPixels(), buf, h * _mouseBuffer.pitch);
_mouseDirty = true;
_mouseNeedTextureUpdate = true;
}
void OSystem_iOS7::setCursorPalette(const byte *colors, uint start, uint num) {
//printf("setCursorPalette(%p, %u, %u)\n", (const void *)colors, start, num);
assert(start + num <= 256);
for (uint i = start; i < start + num; ++i, colors += 3)
_mouseCursorPalette[i] = _videoContext->mouseTexture.format.RGBToColor(colors[0], colors[1], colors[2]);
// FIXME: This is just stupid, our client code seems to assume that this
// automatically enables the cursor palette.
_mouseCursorPaletteEnabled = true;
if (_mouseCursorPaletteEnabled)
_mouseDirty = _mouseNeedTextureUpdate = true;
}
void OSystem_iOS7::updateMouseTexture() {
int texWidth = getSizeNextPOT(_videoContext->mouseWidth);
int texHeight = getSizeNextPOT(_videoContext->mouseHeight);