[Scummvm-git-logs] scummvm master -> 6078586aecf2a14314dd54891aef1c2915d83704
larsamannen
noreply at scummvm.org
Mon Jul 3 19:50:42 UTC 2023
This automated email contains information about 17 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
f337abae70 BACKENDS: SDL: Remove superfluous ifdef
10714db6f0 BACKENDS: OPENGL: Make setSize a Framebuffer function
adda0dc063 BACKENDS: OPENGL: Allow the backend to specify the render target
e6232547d5 IOS7: Add iOSGraphicsManager class
580d8424ca IOS7: Change OSystem_iOS7 to be a ModularGraphicsBackend
208aa43d5b IOS7: Render openGLContext
e0ae1a1d47 IOS7: Rework mouse movements to use iOSGraphicsManager
d36074773b IOS7: Add internal event for signalling screen changes
fb4f7d6de2 IOS7: Remove old IOS7 graphic handling
6a74f7b32b IOS7: Implement iOSGraphics3dManager
b324c70748 IOS7: Implement switching of 2D/3D graphics managers
598bc231ab IOS7: Cancel pending button if touch is moved within 250 ms
5d5564fceb IOS7: Hide word suggestion list in newer iOS versions
d8bc349b37 IOS7: Resize main frame depending on keyboard size and orientation
3ee048d922 IOS7: Update logic for touch events for Apple TV remote
06e231a649 IOS7: Show keyboard automatically when in game and portrait mode
6078586aec CREATE_PROJECT: Correct spelling of definition and shader file name
Commit: f337abae703dc1fa211283862013359b55a742a0
https://github.com/scummvm/scummvm/commit/f337abae703dc1fa211283862013359b55a742a0
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-07-03T21:50:32+02:00
Commit Message:
BACKENDS: SDL: Remove superfluous ifdef
This block is already dedicated to SDL_BACKEND
Changed paths:
backends/module.mk
diff --git a/backends/module.mk b/backends/module.mk
index 534b876edec..9b3e5c090ac 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -195,16 +195,13 @@ endif
ifdef USE_OPENGL
MODULE_OBJS += \
+ graphics/openglsdl/openglsdl-graphics.o \
graphics3d/opengl/framebuffer.o \
graphics3d/opengl/surfacerenderer.o \
graphics3d/opengl/texture.o \
- graphics3d/opengl/tiledsurface.o
-ifdef SDL_BACKEND
-MODULE_OBJS += \
- graphics/openglsdl/openglsdl-graphics.o \
+ graphics3d/opengl/tiledsurface.o \
graphics3d/openglsdl/openglsdl-graphics3d.o
endif
-endif
ifdef USE_DISCORD
MODULE_OBJS += \
Commit: 10714db6f031dbb38a24e78caff288399758d7d9
https://github.com/scummvm/scummvm/commit/10714db6f031dbb38a24e78caff288399758d7d9
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-07-03T21:50:32+02:00
Commit Message:
BACKENDS: OPENGL: Make setSize a Framebuffer function
Changed paths:
backends/graphics/opengl/framebuffer.cpp
backends/graphics/opengl/framebuffer.h
backends/graphics/opengl/opengl-graphics.cpp
diff --git a/backends/graphics/opengl/framebuffer.cpp b/backends/graphics/opengl/framebuffer.cpp
index e3be0ed990b..c74ee60ef79 100644
--- a/backends/graphics/opengl/framebuffer.cpp
+++ b/backends/graphics/opengl/framebuffer.cpp
@@ -178,7 +178,7 @@ void Backbuffer::activateInternal() {
#endif
}
-void Backbuffer::setDimensions(uint width, uint height) {
+bool Backbuffer::setSize(uint width, uint height) {
// Set viewport dimensions.
_viewport[0] = 0;
_viewport[1] = 0;
@@ -211,6 +211,7 @@ void Backbuffer::setDimensions(uint width, uint height) {
applyViewport();
applyProjectionMatrix();
}
+ return true;
}
//
diff --git a/backends/graphics/opengl/framebuffer.h b/backends/graphics/opengl/framebuffer.h
index 3d3b7909bf8..a38663107b1 100644
--- a/backends/graphics/opengl/framebuffer.h
+++ b/backends/graphics/opengl/framebuffer.h
@@ -138,6 +138,11 @@ protected:
virtual void deactivateInternal() {}
public:
+ /**
+ * Set the size of the target buffer.
+ */
+ virtual bool setSize(uint width, uint height) = 0;
+
/**
* Accessor to activate framebuffer for pipeline.
*/
@@ -170,9 +175,9 @@ private:
class Backbuffer : public Framebuffer {
public:
/**
- * Set the dimensions (a.k.a. size) of the back buffer.
+ * Set the size of the back buffer.
*/
- void setDimensions(uint width, uint height);
+ bool setSize(uint width, uint height) override;
protected:
void activateInternal() override;
@@ -205,7 +210,7 @@ public:
/**
* Set size of the texture target.
*/
- bool setSize(uint width, uint height);
+ bool setSize(uint width, uint height) override;
/**
* Query pointer to underlying GL texture.
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 7e4177ce221..d93d00c5112 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -1261,7 +1261,7 @@ void OpenGLGraphicsManager::grabPalette(byte *colors, uint start, uint num) cons
void OpenGLGraphicsManager::handleResizeImpl(const int width, const int height) {
// Setup backbuffer size.
- _backBuffer.setDimensions(width, height);
+ _backBuffer.setSize(width, height);
uint overlayWidth = width;
uint overlayHeight = height;
Commit: adda0dc063ed4a348a0b11e4eeed7598fc35aea7
https://github.com/scummvm/scummvm/commit/adda0dc063ed4a348a0b11e4eeed7598fc35aea7
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-07-03T21:50:32+02:00
Commit Message:
BACKENDS: OPENGL: Allow the backend to specify the render target
For now only backbuffer is used.
Changed paths:
backends/graphics/android/android-graphics.cpp
backends/graphics/opengl/opengl-graphics.cpp
backends/graphics/opengl/opengl-graphics.h
backends/graphics/openglsdl/openglsdl-graphics.cpp
diff --git a/backends/graphics/android/android-graphics.cpp b/backends/graphics/android/android-graphics.cpp
index a545bfa5836..28d73d490a2 100644
--- a/backends/graphics/android/android-graphics.cpp
+++ b/backends/graphics/android/android-graphics.cpp
@@ -96,11 +96,13 @@ void AndroidGraphicsManager::initSurface() {
if (JNI::egl_bits_per_pixel == 16) {
// We default to RGB565 and RGBA5551 which is closest to what we setup in Java side
notifyContextCreate(OpenGL::kContextGLES2,
+ new OpenGL::Backbuffer(),
Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0),
Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
} else {
// If not 16, this must be 24 or 32 bpp so make use of them
notifyContextCreate(OpenGL::kContextGLES2,
+ new OpenGL::Backbuffer(),
#ifdef SCUMM_BIG_ENDIAN
Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0),
Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)
@@ -234,7 +236,7 @@ void AndroidGraphicsManager::refreshScreen() {
}
void AndroidGraphicsManager::touchControlDraw(int16 x, int16 y, int16 w, int16 h, const Common::Rect &clip) {
- _backBuffer.enableBlend(OpenGL::Framebuffer::kBlendModeTraditionalTransparency);
+ _targetBuffer->enableBlend(OpenGL::Framebuffer::kBlendModeTraditionalTransparency);
OpenGL::Pipeline *pipeline = getPipeline();
pipeline->activate();
pipeline->drawTexture(_touchcontrols->getGLTexture(),
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index d93d00c5112..b537522ace6 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -71,7 +71,7 @@ namespace OpenGL {
OpenGLGraphicsManager::OpenGLGraphicsManager()
: _currentState(), _oldState(), _transactionMode(kTransactionNone), _screenChangeID(1 << (sizeof(int) * 8 - 2)),
_pipeline(nullptr), _stretchMode(STRETCH_FIT),
- _defaultFormat(), _defaultFormatAlpha(),
+ _defaultFormat(), _defaultFormatAlpha(), _targetBuffer(nullptr),
_gameScreen(nullptr), _overlay(nullptr),
_cursor(nullptr), _cursorMask(nullptr),
_cursorHotspotX(0), _cursorHotspotY(0),
@@ -105,6 +105,7 @@ OpenGLGraphicsManager::~OpenGLGraphicsManager() {
ShaderManager::destroy();
#endif
delete _pipeline;
+ delete _targetBuffer;
}
bool OpenGLGraphicsManager::hasFeature(OSystem::Feature f) const {
@@ -609,16 +610,16 @@ void OpenGLGraphicsManager::renderCursor() {
the inversion and opacity mask at once. We use 1-srcAlpha instead of srcAlpha so zero-fill is transparent.
*/
if (_cursorMask) {
- _backBuffer.enableBlend(Framebuffer::kBlendModeMaskAlphaAndInvertByColor);
+ _targetBuffer->enableBlend(Framebuffer::kBlendModeMaskAlphaAndInvertByColor);
_pipeline->drawTexture(_cursorMask->getGLTexture(),
_cursorX - _cursorHotspotXScaled + _shakeOffsetScaled.x,
_cursorY - _cursorHotspotYScaled + _shakeOffsetScaled.y,
_cursorWidthScaled, _cursorHeightScaled);
- _backBuffer.enableBlend(Framebuffer::kBlendModeAdditive);
+ _targetBuffer->enableBlend(Framebuffer::kBlendModeAdditive);
} else
- _backBuffer.enableBlend(Framebuffer::kBlendModePremultipliedTransparency);
+ _targetBuffer->enableBlend(Framebuffer::kBlendModePremultipliedTransparency);
_pipeline->drawTexture(_cursor->getGLTexture(),
_cursorX - _cursorHotspotXScaled + _shakeOffsetScaled.x,
@@ -687,14 +688,14 @@ void OpenGLGraphicsManager::updateScreen() {
// The scissor test is enabled to:
// - Clip the cursor to the game screen
// - Clip the game screen when the shake offset is non-zero
- _backBuffer.enableScissorTest(true);
+ _targetBuffer->enableScissorTest(true);
}
// Don't draw cursor if it's not visible or there is none
bool drawCursor = _cursorVisible && _cursor;
// Alpha blending is disabled when drawing the screen
- _backBuffer.enableBlend(Framebuffer::kBlendModeDisabled);
+ _targetBuffer->enableBlend(Framebuffer::kBlendModeDisabled);
// First step: Draw the (virtual) game screen.
_pipeline->drawTexture(_gameScreen->getGLTexture(), _gameDrawRect.left, _gameDrawRect.top, _gameDrawRect.width(), _gameDrawRect.height());
@@ -710,7 +711,7 @@ void OpenGLGraphicsManager::updateScreen() {
drawCursor = false;
// Everything we need to clip has been clipped
- _backBuffer.enableScissorTest(false);
+ _targetBuffer->enableScissorTest(false);
}
// Overlay must not be scaled and its cursor won't be either
@@ -722,7 +723,7 @@ void OpenGLGraphicsManager::updateScreen() {
if (_overlayVisible) {
int dstX = (_windowWidth - _overlayDrawRect.width()) / 2;
int dstY = (_windowHeight - _overlayDrawRect.height()) / 2;
- _backBuffer.enableBlend(Framebuffer::kBlendModeTraditionalTransparency);
+ _targetBuffer->enableBlend(Framebuffer::kBlendModeTraditionalTransparency);
_pipeline->drawTexture(_overlay->getGLTexture(), dstX, dstY, _overlayDrawRect.width(), _overlayDrawRect.height());
}
@@ -731,13 +732,13 @@ void OpenGLGraphicsManager::updateScreen() {
renderCursor();
if (!_overlayVisible) {
- _backBuffer.enableScissorTest(false);
+ _targetBuffer->enableScissorTest(false);
}
#ifdef USE_OSD
// Fourth step: Draw the OSD.
if (_osdMessageSurface || _osdIconSurface) {
- _backBuffer.enableBlend(Framebuffer::kBlendModeTraditionalTransparency);
+ _targetBuffer->enableBlend(Framebuffer::kBlendModeTraditionalTransparency);
}
if (_osdMessageSurface) {
@@ -1261,7 +1262,7 @@ void OpenGLGraphicsManager::grabPalette(byte *colors, uint start, uint num) cons
void OpenGLGraphicsManager::handleResizeImpl(const int width, const int height) {
// Setup backbuffer size.
- _backBuffer.setSize(width, height);
+ _targetBuffer->setSize(width, height);
uint overlayWidth = width;
uint overlayHeight = height;
@@ -1312,8 +1313,13 @@ void OpenGLGraphicsManager::handleResizeImpl(const int width, const int height)
}
void OpenGLGraphicsManager::notifyContextCreate(ContextType type,
+ Framebuffer *target,
const Graphics::PixelFormat &defaultFormat,
const Graphics::PixelFormat &defaultFormatAlpha) {
+ // Set up the target: backbuffer usually
+ delete _targetBuffer;
+ _targetBuffer = target;
+
// Initialize pipeline.
delete _pipeline;
_pipeline = nullptr;
@@ -1361,9 +1367,9 @@ void OpenGLGraphicsManager::notifyContextCreate(ContextType type,
// Setup backbuffer state.
// Default to opaque black as clear color.
- _backBuffer.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ _targetBuffer->setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- _pipeline->setFramebuffer(&_backBuffer);
+ _pipeline->setFramebuffer(_targetBuffer);
// We use a "pack" alignment (when reading from textures) to 4 here,
// since the only place where we really use it is the BMP screenshot
@@ -1450,6 +1456,10 @@ void OpenGLGraphicsManager::notifyContextDestroy() {
_libretroPipeline = nullptr;
#endif
+ // Destroy the target
+ delete _targetBuffer;
+ _targetBuffer = nullptr;
+
// Rest our context description since the context is gone soon.
OpenGLContext.reset();
}
@@ -1632,7 +1642,7 @@ void OpenGLGraphicsManager::recalculateDisplayAreas() {
// Setup drawing limitation for game graphics.
// This involves some trickery because OpenGL's viewport coordinate system
// is upside down compared to ours.
- _backBuffer.setScissorBox(_gameDrawRect.left,
+ _targetBuffer->setScissorBox(_gameDrawRect.left,
_windowHeight - _gameDrawRect.height() - _gameDrawRect.top,
_gameDrawRect.width(),
_gameDrawRect.height());
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index e60146df718..5532559da37 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -149,6 +149,7 @@ protected:
*/
void notifyContextCreate(
ContextType type,
+ Framebuffer *target,
const Graphics::PixelFormat &defaultFormat,
const Graphics::PixelFormat &defaultFormatAlpha);
@@ -339,9 +340,9 @@ protected:
Graphics::PixelFormat _defaultFormatAlpha;
/**
- * Render back buffer.
+ * Render target.
*/
- Backbuffer _backBuffer;
+ Framebuffer *_targetBuffer;
/**
* The rendering surface for the virtual game screen.
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index 9f7a30950f4..bebd7b9ff21 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -547,7 +547,7 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
warning("Unable to %s VSync: %s", _vsync ? "enable" : "disable", SDL_GetError());
}
- notifyContextCreate(_glContextType, rgba8888, rgba8888);
+ notifyContextCreate(_glContextType, new OpenGL::Backbuffer(), rgba8888, rgba8888);
int actualWidth, actualHeight;
getWindowSizeFromSdl(&actualWidth, &actualHeight);
@@ -616,7 +616,7 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
_lastVideoModeLoad = SDL_GetTicks();
if (_hwScreen) {
- notifyContextCreate(_glContextType, rgba8888, rgba8888);
+ notifyContextCreate(_glContextType, new OpenGL::Backbuffer(), rgba8888, rgba8888);
handleResize(_hwScreen->w, _hwScreen->h);
}
Commit: e6232547d5353fffcaccf34f86b220b9fcddee60
https://github.com/scummvm/scummvm/commit/e6232547d5353fffcaccf34f86b220b9fcddee60
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-07-03T21:50:32+02:00
Commit Message:
IOS7: Add iOSGraphicsManager class
The ios7 backend implements the graphic handling in the backend code.
iOS supports OpenGL through the OpenGL Framework since iOS 2.0. It's
marked as deprecated but is still shipped with the SDKs for iPhoneOS
and tvOS and will hopefully be so for some time.
The ios7 backend can therefore utilize the OpenGLGraphicsManager to
handle all graphics.
Implement an iOSGraphicsManager class that can be used in the ios7
backend. The iOSGraphicsManager will require some callback functions
in the ios7 backend. createOpenGLContext() will be called to ask the
backend to create an OpenGL context in which the graphic manager can
draw. The function returns the ID of the renderbuffer which shall be
used when creating the framebuffer object this differ iOS from other
platforms). A custom RenderBufferTarget class is added to address
this.
destroyOpenGLContext() will be called to make sure that the old GLES
context is not reused. notifyContextDestroy() does call the function
OpenGLContext.reset() but that will not destroy the context.
refreshScreen() will be called to ask the backend to present the
drawn graphics on the screen. getSystemHiDPIScreenFactor() is called
to get the screen scaling factor. getScreenWidth() and
getScreenHeight() are called to get the width and height of the
surface to draw on.
This commit adds the class but the ios7 backend doesn't make use of
it quite yet. To use it require the ios7 to be a child class of the
ModularGraphicsBackend. That change requires a lot of changes which
will be targeted in separate commits.
Update docportal and github ci worker to only disable the feature
opengl_classic_game since opengl and opengl_shaders are required to
compile the OpenGLGraphicsManager.
Changed paths:
A backends/graphics/ios/ios-graphics.cpp
A backends/graphics/ios/ios-graphics.h
A backends/graphics/ios/renderbuffer.cpp
A backends/graphics/ios/renderbuffer.h
.github/workflows/ci.yml
backends/module.mk
backends/platform/ios7/ios7_osys_main.h
backends/platform/ios7/ios7_osys_video.mm
configure
devtools/create_project/xcode.cpp
doc/docportal/other_platforms/ios.rst
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 33c0222b944..22bb6bd4490 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -105,7 +105,7 @@ jobs:
brewPackages: a52dec faad2 flac fluid-synth freetype fribidi giflib jpeg mad libmikmod libmpeg2 libogg libpng libvorbis libvpx sdl2 sdl2_net theora
- platform: ios7
buildFlags: -scheme ScummVM-iOS CODE_SIGN_IDENTITY="" CODE_SIGNING_ALLOWED=NO
- configFlags: --use-xcframework --enable-faad --enable-gif --enable-mikmod --enable-mpeg2 --enable-vpx --disable-nasm --disable-opengl --disable-taskbar --disable-tts
+ configFlags: --use-xcframework --enable-faad --enable-gif --enable-mikmod --enable-mpeg2 --enable-vpx --disable-nasm --disable-opengl_game_classic --disable-taskbar --disable-tts
packagesUrl: https://downloads.scummvm.org/frs/build/scummvm-ios7-libs-v3.zip
env:
BUILDCACHE_MAX_CACHE_SIZE: 2000000000
diff --git a/backends/graphics/ios/ios-graphics.cpp b/backends/graphics/ios/ios-graphics.cpp
new file mode 100644
index 00000000000..d1a6e75b4d3
--- /dev/null
+++ b/backends/graphics/ios/ios-graphics.cpp
@@ -0,0 +1,114 @@
+/* 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 3 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "backends/graphics/ios/ios-graphics.h"
+#include "backends/graphics/ios/renderbuffer.h"
+#include "backends/graphics/opengl/pipelines/pipeline.h"
+#include "backends/platform/ios7/ios7_osys_main.h"
+
+iOSGraphicsManager::iOSGraphicsManager() {
+ initSurface();
+}
+
+iOSGraphicsManager::~iOSGraphicsManager() {
+ deinitSurface();
+}
+
+void iOSGraphicsManager::initSurface() {
+ OSystem_iOS7 *sys = dynamic_cast<OSystem_iOS7 *>(g_system);
+
+ // Create OpenGL context
+ GLuint rbo = sys->createOpenGLContext();
+
+ notifyContextCreate(OpenGL::kContextGLES2,
+ new OpenGL::RenderbufferTarget(rbo),
+ // Currently iOS runs the ARMs in little-endian mode but prepare if
+ // that is changed in the future.
+#ifdef SCUMM_LITTLE_ENDIAN
+ Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24),
+ Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
+#else
+ Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0),
+ Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
+#endif
+ handleResize(sys->getScreenWidth(), sys->getScreenHeight());
+}
+
+void iOSGraphicsManager::deinitSurface() {
+ notifyContextDestroy();
+ dynamic_cast<OSystem_iOS7 *>(g_system)->destroyOpenGLContext();
+}
+
+void iOSGraphicsManager::notifyResize(const int width, const int height) {
+ handleResize(width, height);
+}
+
+iOSCommonGraphics::State iOSGraphicsManager::getState() const {
+ State state;
+
+ state.screenWidth = getWidth();
+ state.screenHeight = getHeight();
+ state.aspectRatio = getFeatureState(OSystem::kFeatureAspectRatioCorrection);
+ state.cursorPalette = getFeatureState(OSystem::kFeatureCursorPalette);
+#ifdef USE_RGB_COLOR
+ state.pixelFormat = getScreenFormat();
+#endif
+ return state;
+}
+
+bool iOSGraphicsManager::setState(const iOSCommonGraphics::State &state) {
+ beginGFXTransaction();
+
+#ifdef USE_RGB_COLOR
+ initSize(state.screenWidth, state.screenHeight, &state.pixelFormat);
+#else
+ initSize(state.screenWidth, state.screenHeight, nullptr);
+#endif
+ setFeatureState(OSystem::kFeatureAspectRatioCorrection, state.aspectRatio);
+ setFeatureState(OSystem::kFeatureCursorPalette, state.cursorPalette);
+
+ return endGFXTransaction() == OSystem::kTransactionSuccess;
+}
+
+
+bool iOSGraphicsManager::loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format) {
+ /* The iOS and tvOS video modes are always full screen */
+ return true;
+}
+
+float iOSGraphicsManager::getHiDPIScreenFactor() const {
+ return dynamic_cast<OSystem_iOS7 *>(g_system)->getSystemHiDPIScreenFactor();
+}
+
+void iOSGraphicsManager::refreshScreen() {
+ dynamic_cast<OSystem_iOS7 *>(g_system)->refreshScreen();
+}
+
+bool iOSGraphicsManager::notifyMousePosition(Common::Point &mouse) {
+ mouse.x = CLIP<int16>(mouse.x, _activeArea.drawRect.left, _activeArea.drawRect.right);
+ mouse.y = CLIP<int16>(mouse.y, _activeArea.drawRect.top, _activeArea.drawRect.bottom);
+
+ setMousePosition(mouse.x, mouse.y);
+ mouse = convertWindowToVirtual(mouse.x, mouse.y);
+
+ return true;
+}
diff --git a/backends/graphics/ios/ios-graphics.h b/backends/graphics/ios/ios-graphics.h
new file mode 100644
index 00000000000..a0de4136d10
--- /dev/null
+++ b/backends/graphics/ios/ios-graphics.h
@@ -0,0 +1,98 @@
+/* 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 3 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef BACKENDS_GRAPHICS_IOS_IOS_GRAPHICS_H
+#define BACKENDS_GRAPHICS_IOS_IOS_GRAPHICS_H
+
+#include "common/scummsys.h"
+#include <OpenGLES/ES2/gl.h>
+
+#include "backends/graphics/opengl/opengl-graphics.h"
+
+class iOSCommonGraphics {
+public:
+ virtual ~iOSCommonGraphics() {}
+
+ virtual void initSurface() = 0;
+ virtual void deinitSurface() = 0;
+
+ /**
+ * Notify the graphics manager about a resize event. This happens on
+ * iDevices when switching to portrait mode or landscape mode.
+ */
+ virtual void notifyResize(const int width, const int height) = 0;
+
+ virtual Common::Point getMousePosition() = 0;
+ virtual bool notifyMousePosition(Common::Point &mouse) = 0;
+
+ /**
+ * A (subset) of the graphic manager's state. This is used when switching
+ * between 2D and 3D graphic managers at runtime.
+ */
+ struct State {
+ int screenWidth, screenHeight;
+ bool aspectRatio;
+ bool cursorPalette;
+
+#ifdef USE_RGB_COLOR
+ Graphics::PixelFormat pixelFormat;
+#endif
+ };
+
+ /**
+ * Gets the current state of the graphics manager.
+ */
+ virtual State getState() const = 0;
+
+ /**
+ * Sets up a basic state of the graphics manager.
+ */
+ virtual bool setState(const State &state) = 0;
+};
+
+class iOSGraphicsManager :
+ public OpenGL::OpenGLGraphicsManager, public iOSCommonGraphics {
+public:
+ iOSGraphicsManager();
+ virtual ~iOSGraphicsManager();
+
+ void initSurface() override;
+ void deinitSurface() override;
+
+ void notifyResize(const int width, const int height) override;
+
+ virtual iOSCommonGraphics::State getState() const override;
+ virtual bool setState(const iOSCommonGraphics::State &state) override;
+
+ bool notifyMousePosition(Common::Point &mouse) override;
+ Common::Point getMousePosition() override { return Common::Point(_cursorX, _cursorY); }
+
+ float getHiDPIScreenFactor() const override;
+
+protected:
+ void setSystemMousePosition(const int x, const int y) override {}
+
+ bool loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format) override;
+
+ void refreshScreen() override;
+};
+
+#endif
diff --git a/backends/graphics/ios/renderbuffer.cpp b/backends/graphics/ios/renderbuffer.cpp
new file mode 100644
index 00000000000..9e568ad358f
--- /dev/null
+++ b/backends/graphics/ios/renderbuffer.cpp
@@ -0,0 +1,92 @@
+/* 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 3 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "backends/graphics/ios/renderbuffer.h"
+#include "graphics/opengl/debug.h"
+
+namespace OpenGL {
+
+//
+// Render to backbuffer target implementation
+//
+RenderbufferTarget::RenderbufferTarget(GLuint renderbufferID)
+ : _glRBO(renderbufferID), _glFBO(0) {
+}
+
+RenderbufferTarget::~RenderbufferTarget() {
+ GL_CALL_SAFE(glDeleteFramebuffers, (1, &_glFBO));
+}
+
+void RenderbufferTarget::activateInternal() {
+ bool needUpdate = false;
+
+ // Allocate framebuffer object if necessary.
+ if (!_glFBO) {
+ GL_CALL(glGenFramebuffers(1, &_glFBO));
+ needUpdate = true;
+ }
+
+ // Attach FBO to rendering context.
+ GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, _glFBO));
+
+ // Attach render buffer to newly created FBO.
+ if (needUpdate) {
+ GL_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _glRBO));
+ }
+}
+
+bool RenderbufferTarget::setSize(uint width, uint height) {
+ // Set viewport dimensions.
+ _viewport[0] = 0;
+ _viewport[1] = 0;
+ _viewport[2] = width;
+ _viewport[3] = height;
+
+ // Setup orthogonal projection matrix.
+ _projectionMatrix(0, 0) = 2.0f / width;
+ _projectionMatrix(0, 1) = 0.0f;
+ _projectionMatrix(0, 2) = 0.0f;
+ _projectionMatrix(0, 3) = 0.0f;
+
+ _projectionMatrix(1, 0) = 0.0f;
+ _projectionMatrix(1, 1) = -2.0f / height;
+ _projectionMatrix(1, 2) = 0.0f;
+ _projectionMatrix(1, 3) = 0.0f;
+
+ _projectionMatrix(2, 0) = 0.0f;
+ _projectionMatrix(2, 1) = 0.0f;
+ _projectionMatrix(2, 2) = 0.0f;
+ _projectionMatrix(2, 3) = 0.0f;
+
+ _projectionMatrix(3, 0) = -1.0f;
+ _projectionMatrix(3, 1) = 1.0f;
+ _projectionMatrix(3, 2) = 0.0f;
+ _projectionMatrix(3, 3) = 1.0f;
+
+ // Directly apply changes when we are active.
+ if (isActive()) {
+ applyViewport();
+ applyProjectionMatrix();
+ }
+ return true;
+}
+
+} // End of namespace OpenGL
diff --git a/backends/graphics/ios/renderbuffer.h b/backends/graphics/ios/renderbuffer.h
new file mode 100644
index 00000000000..0047f9c2f1c
--- /dev/null
+++ b/backends/graphics/ios/renderbuffer.h
@@ -0,0 +1,55 @@
+/* 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 3 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef BACKENDS_GRAPHICS_IOS_RENDERBUFFER_H
+#define BACKENDS_GRAPHICS_IOS_RENDERBUFFER_H
+
+#include "backends/graphics/opengl/framebuffer.h"
+
+namespace OpenGL {
+
+/**
+ * Render to renderbuffer framebuffer implementation.
+ *
+ * This target allows to render to a renderbuffer, which can then be used as
+ * a rendering source like expected on iOS.
+ */
+class RenderbufferTarget : public Framebuffer {
+public:
+ RenderbufferTarget(GLuint renderbufferID);
+ ~RenderbufferTarget() override;
+
+ /**
+ * Set size of the render target.
+ */
+ bool setSize(uint width, uint height) override;
+
+protected:
+ void activateInternal() override;
+
+private:
+ GLuint _glRBO;
+ GLuint _glFBO;
+};
+
+} // End of namespace OpenGL
+
+#endif
diff --git a/backends/module.mk b/backends/module.mk
index 9b3e5c090ac..72dddcc0b32 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -387,7 +387,9 @@ endif
ifdef IPHONE
MODULE_OBJS += \
- mutex/pthread/pthread-mutex.o
+ mutex/pthread/pthread-mutex.o \
+ graphics/ios/ios-graphics.o \
+ graphics/ios/renderbuffer.o
endif
ifeq ($(BACKEND),maemo)
diff --git a/backends/platform/ios7/ios7_osys_main.h b/backends/platform/ios7/ios7_osys_main.h
index affd73a123b..0bf81ab2076 100644
--- a/backends/platform/ios7/ios7_osys_main.h
+++ b/backends/platform/ios7/ios7_osys_main.h
@@ -132,6 +132,13 @@ public:
bool touchpadModeEnabled() const;
+ uint createOpenGLContext();
+ void destroyOpenGLContext();
+ void refreshScreen() const;
+ int getScreenWidth() const;
+ 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;
diff --git a/backends/platform/ios7/ios7_osys_video.mm b/backends/platform/ios7/ios7_osys_video.mm
index 3c8340b7f1d..3e1ce5a572b 100644
--- a/backends/platform/ios7/ios7_osys_video.mm
+++ b/backends/platform/ios7/ios7_osys_video.mm
@@ -642,3 +642,35 @@ bool OSystem_iOS7::isKeyboardShown() const {
});
return isShown;
}
+
+uint OSystem_iOS7::createOpenGLContext() {
+ // TODO: Implement creation of OpenGL context
+ // The context will be used by scummvm system running on
+ // background thread.
+ return 0;
+}
+
+void OSystem_iOS7::destroyOpenGLContext() {
+ // TODO: Implement destroy of OpenGL context
+}
+
+void OSystem_iOS7::refreshScreen() const {
+ // TODO: Implement presentation of the renderBuffer
+ // Present the renderBuffer on the openGLContext
+}
+
+int OSystem_iOS7::getScreenWidth() const {
+ // TODO: Return width of screen buffer
+ return 0;
+}
+
+int OSystem_iOS7::getScreenHeight() const {
+ // TODO: Return height of screen buffer
+ return 0;
+}
+
+float OSystem_iOS7::getSystemHiDPIScreenFactor() const {
+ // TODO: Return HiDPI screen factor
+ return 0.0;
+}
+
diff --git a/configure b/configure
index 62016fb685f..8ae3bd09a42 100755
--- a/configure
+++ b/configure
@@ -6127,6 +6127,10 @@ if test "$_opengl_mode" != none ; then
_opengl_mode=gles2
_opengl_glad=yes
;;
+ ios7)
+ _opengl_mode=gles2
+ _opengl_glad=yes
+ ;;
openpandora)
# Enable GLES only if user explicitely requested it
# Backend is SDL based so GLAD is supported
diff --git a/devtools/create_project/xcode.cpp b/devtools/create_project/xcode.cpp
index a644c5bb6e3..59d75789fe4 100644
--- a/devtools/create_project/xcode.cpp
+++ b/devtools/create_project/xcode.cpp
@@ -163,6 +163,10 @@ bool shouldSkipFileForTarget(const std::string &fileID, const std::string &targe
if (name.length() > 5 && name.substr(0, 5) == "ios7_") {
return true;
}
+ // macOS target: we skip all files with the "ios-" prefix
+ if (name.length() > 4 && name.substr(0, 4) == "ios-") {
+ return true;
+ }
// parent directory
const std::string directory = fileID.substr(0, fileID.length() - fileName.length());
static const std::string iphone_directory = "backends/platform/ios7";
diff --git a/doc/docportal/other_platforms/ios.rst b/doc/docportal/other_platforms/ios.rst
index ca860290a3f..6aa4ea864a9 100644
--- a/doc/docportal/other_platforms/ios.rst
+++ b/doc/docportal/other_platforms/ios.rst
@@ -76,7 +76,7 @@ It's time to generate the Xcode project. Run the following on the command line:
.. code::
- ../scummvm/devtools/create_project/xcode/build/Release/create_project ../scummvm --xcode --use-xcframework --enable-faad --enable-fluidsynth --enable-gif --enable-mikmod --enable-mpeg2 --enable-vpx --disable-nasm --disable-opengl --disable-taskbar --disable-tts
+ ../scummvm/devtools/create_project/xcode/build/Release/create_project ../scummvm --xcode --use-xcframework --enable-faad --enable-fluidsynth --enable-gif --enable-mikmod --enable-mpeg2 --enable-vpx --disable-nasm --disable-opengl_game_classic --disable-taskbar --disable-tts
The resulting directory structure looks like this:
Commit: 580d8424ca46c2c454ae23f62f95fcd3c407aab9
https://github.com/scummvm/scummvm/commit/580d8424ca46c2c454ae23f62f95fcd3c407aab9
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-07-03T21:50:32+02:00
Commit Message:
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.
Changed paths:
backends/platform/ios7/ios7_osys_main.cpp
backends/platform/ios7/ios7_osys_main.h
backends/platform/ios7/ios7_osys_video.mm
diff --git a/backends/platform/ios7/ios7_osys_main.cpp b/backends/platform/ios7/ios7_osys_main.cpp
index a3d397989e2..284b8048f99 100644
--- a/backends/platform/ios7/ios7_osys_main.cpp
+++ b/backends/platform/ios7/ios7_osys_main.cpp
@@ -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);
}
}
diff --git a/backends/platform/ios7/ios7_osys_main.h b/backends/platform/ios7/ios7_osys_main.h
index 0bf81ab2076..1760fe229fb 100644
--- a/backends/platform/ios7/ios7_osys_main.h
+++ b/backends/platform/ios7/ios7_osys_main.h
@@ -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;
diff --git a/backends/platform/ios7/ios7_osys_video.mm b/backends/platform/ios7/ios7_osys_video.mm
index 3e1ce5a572b..ef1040c8457 100644
--- a/backends/platform/ios7/ios7_osys_video.mm
+++ b/backends/platform/ios7/ios7_osys_video.mm
@@ -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);
Commit: 208aa43d5be8176e93d0e10dbc79297027f0384b
https://github.com/scummvm/scummvm/commit/208aa43d5be8176e93d0e10dbc79297027f0384b
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-07-03T21:50:32+02:00
Commit Message:
IOS7: Render openGLContext
Implement callbacks to set up OpenGL context, destroy context, get
scale factor and screen sizes. Implement rendering of graphics drawn
by the iOS graphicsManager.
This commit will enable graphics to be shown again. Screen rotation
and mouse movements are still to be adapted.
Changed paths:
backends/platform/ios7/ios7_osys_video.mm
backends/platform/ios7/ios7_video.h
backends/platform/ios7/ios7_video.mm
diff --git a/backends/platform/ios7/ios7_osys_video.mm b/backends/platform/ios7/ios7_osys_video.mm
index ef1040c8457..8d10bcf0de7 100644
--- a/backends/platform/ios7/ios7_osys_video.mm
+++ b/backends/platform/ios7/ios7_osys_video.mm
@@ -276,33 +276,26 @@ bool OSystem_iOS7::isKeyboardShown() const {
}
uint OSystem_iOS7::createOpenGLContext() {
- // TODO: Implement creation of OpenGL context
- // The context will be used by scummvm system running on
- // background thread.
- return 0;
+ return [[iOS7AppDelegate iPhoneView] createOpenGLContext];
}
void OSystem_iOS7::destroyOpenGLContext() {
- // TODO: Implement destroy of OpenGL context
+ [[iOS7AppDelegate iPhoneView] destroyOpenGLContext];
}
void OSystem_iOS7::refreshScreen() const {
- // TODO: Implement presentation of the renderBuffer
- // Present the renderBuffer on the openGLContext
+ [[iOS7AppDelegate iPhoneView] refreshScreen];
}
int OSystem_iOS7::getScreenWidth() const {
- // TODO: Return width of screen buffer
- return 0;
+ return [[iOS7AppDelegate iPhoneView] getScreenWidth];
}
int OSystem_iOS7::getScreenHeight() const {
- // TODO: Return height of screen buffer
- return 0;
+ return [[iOS7AppDelegate iPhoneView] getScreenHeight];
}
float OSystem_iOS7::getSystemHiDPIScreenFactor() const {
- // TODO: Return HiDPI screen factor
- return 0.0;
+ return [[UIScreen mainScreen] scale];
}
diff --git a/backends/platform/ios7/ios7_video.h b/backends/platform/ios7/ios7_video.h
index f790110a0cd..d36a97320de 100644
--- a/backends/platform/ios7/ios7_video.h
+++ b/backends/platform/ios7/ios7_video.h
@@ -54,7 +54,8 @@ uint getSizeNextPOT(uint size);
UIBackgroundTaskIdentifier _backgroundSaveStateTask;
- EAGLContext *_context;
+ EAGLContext *_mainContext;
+ EAGLContext *_openGLContext;
GLuint _viewRenderbuffer;
GLuint _viewFramebuffer;
GLuint _screenTexture;
@@ -100,6 +101,12 @@ uint getSizeNextPOT(uint size);
- (VideoContext *)getVideoContext;
+- (uint)createOpenGLContext;
+- (void)destroyOpenGLContext;
+- (void)refreshScreen;
+- (int)getScreenWidth;
+- (int)getScreenHeight;
+
- (void)setGameScreenCoords;
- (void)initSurface;
- (void)setViewTransformation;
diff --git a/backends/platform/ios7/ios7_video.mm b/backends/platform/ios7/ios7_video.mm
index 6d12886efd5..6c57d2823be 100644
--- a/backends/platform/ios7/ios7_video.mm
+++ b/backends/platform/ios7/ios7_video.mm
@@ -123,22 +123,56 @@ uint getSizeNextPOT(uint size) {
kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8,
};
- _context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+ _mainContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
// In case creating the OpenGL ES context failed, we will error out here.
- if (_context == nil) {
+ if (_mainContext == nil) {
printError("Could not create OpenGL ES context.");
abort();
}
- if ([EAGLContext setCurrentContext:_context]) {
- // glEnableClientState(GL_TEXTURE_COORD_ARRAY); printOpenGLError();
- // glEnableClientState(GL_VERTEX_ARRAY); printOpenGLError();
- [self setupOpenGL];
+ // main thread will always use _mainContext
+ [EAGLContext setCurrentContext:_mainContext];
+}
+
+- (uint)createOpenGLContext {
+ // Create OpenGL context with the sharegroup from the context
+ // connected to the Apple Core Animation layer
+ if (!_openGLContext && _mainContext) {
+ _openGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:_mainContext.sharegroup];
+
+ if (_openGLContext == nil) {
+ printError("Could not create OpenGL ES context using sharegroup");
+ abort();
+ }
+ // background thread will always use _openGLContext
+ if ([EAGLContext setCurrentContext:_openGLContext]) {
+ [self setupRenderBuffer];
+ }
}
+ return _viewRenderbuffer;
+}
+
+- (void)destroyOpenGLContext {
+ [_openGLContext release];
+ _openGLContext = nil;
+}
+
+- (void)refreshScreen {
+ glBindRenderbuffer(GL_RENDERBUFFER, _viewRenderbuffer);
+ [_openGLContext presentRenderbuffer:GL_RENDERBUFFER];
+}
+
+- (int)getScreenWidth {
+ return _renderBufferWidth;
+}
+
+- (int)getScreenHeight {
+ return _renderBufferHeight;
}
- (void)setupOpenGL {
+ [self setupRenderBuffer];
[self setupFramebuffer];
[self createOverlaySurface];
[self compileShaders];
@@ -163,6 +197,7 @@ uint getSizeNextPOT(uint size) {
[self deleteVBOs];
[self deleteShaders];
[self deleteFramebuffer];
+ [self deleteRenderbuffer];
}
- (void)rebuildFrameBuffer {
@@ -172,32 +207,41 @@ uint getSizeNextPOT(uint size) {
}
- (void)setupFramebuffer {
- glGenRenderbuffers(1, &_viewRenderbuffer);
- printOpenGLError();
- glBindRenderbuffer(GL_RENDERBUFFER, _viewRenderbuffer);
- printOpenGLError();
- [_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(id <EAGLDrawable>) self.layer];
-
- glGenFramebuffers(1, &_viewFramebuffer);
- printOpenGLError();
+ if (!_viewFramebuffer) {
+ glGenFramebuffers(1, &_viewFramebuffer);
+ printOpenGLError();
+ }
glBindFramebuffer(GL_FRAMEBUFFER, _viewFramebuffer);
printOpenGLError();
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _viewRenderbuffer);
printOpenGLError();
- // Retrieve the render buffer size. This *should* match the frame size,
- // i.e. g_fullWidth and g_fullHeight.
- glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &_renderBufferWidth);
- printOpenGLError();
- glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &_renderBufferHeight);
- printOpenGLError();
-
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
NSLog(@"Failed to make complete framebuffer object %x.", glCheckFramebufferStatus(GL_FRAMEBUFFER));
return;
}
}
+- (void)setupRenderBuffer {
+ execute_on_main_thread(^{
+ if (!_viewRenderbuffer) {
+ glGenRenderbuffers(1, &_viewRenderbuffer);
+ printOpenGLError();
+ }
+ glBindRenderbuffer(GL_RENDERBUFFER, _viewRenderbuffer);
+ printOpenGLError();
+ if (![_mainContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:(id <EAGLDrawable>) self.layer]) {
+ printError("Failed renderbufferStorage");
+ }
+ // Retrieve the render buffer size. This *should* match the frame size,
+ // i.e. g_fullWidth and g_fullHeight.
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &_renderBufferWidth);
+ printOpenGLError();
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &_renderBufferHeight);
+ printOpenGLError();
+ });
+}
+
- (void)createOverlaySurface {
uint overlayWidth = (uint) MAX(_renderBufferWidth, _renderBufferHeight);
uint overlayHeight = (uint) MIN(_renderBufferWidth, _renderBufferHeight);
@@ -221,8 +265,11 @@ uint getSizeNextPOT(uint size) {
_videoContext.overlayTexture.create((uint16) overlayTextureWidthPOT, (uint16) overlayTextureHeightPOT, Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
}
-- (void)deleteFramebuffer {
+- (void)deleteRenderbuffer {
glDeleteRenderbuffers(1, &_viewRenderbuffer);
+}
+
+- (void)deleteFramebuffer {
glDeleteFramebuffers(1, &_viewFramebuffer);
}
@@ -538,7 +585,7 @@ uint getSizeNextPOT(uint size) {
if (_videoContext.mouseIsVisible)
[self updateMouseSurface];
- [_context presentRenderbuffer:GL_RENDERBUFFER];
+ [_mainContext presentRenderbuffer:GL_RENDERBUFFER];
glFinish();
}
@@ -682,9 +729,7 @@ uint getSizeNextPOT(uint size) {
}
- (void)initSurface {
- if (_context) {
- [self rebuildFrameBuffer];
- }
+ [self setupRenderBuffer];
#if TARGET_OS_IOS
UIInterfaceOrientation interfaceOrientation = UIInterfaceOrientationUnknown;
@@ -715,10 +760,6 @@ uint getSizeNextPOT(uint size) {
[self showKeyboard];
}
- glBindRenderbuffer(GL_RENDERBUFFER, _viewRenderbuffer); printOpenGLError();
-
- [self clearColorBuffer];
-
GLfloat adjustedWidth = _videoContext.screenWidth;
GLfloat adjustedHeight = _videoContext.screenHeight;
if (_videoContext.asprectRatioCorrection) {
@@ -842,7 +883,7 @@ uint getSizeNextPOT(uint size) {
int clearCount = 5;
while (clearCount-- > 0) {
glClear(GL_COLOR_BUFFER_BIT); printOpenGLError();
- [_context presentRenderbuffer:GL_RENDERBUFFER];
+ [_mainContext presentRenderbuffer:GL_RENDERBUFFER];
glFinish();
}
}
Commit: e0ae1a1d47c1036bc50d0d6483ca460922d242d3
https://github.com/scummvm/scummvm/commit/e0ae1a1d47c1036bc50d0d6483ca460922d242d3
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-07-03T21:50:32+02:00
Commit Message:
IOS7: Rework mouse movements to use iOSGraphicsManager
Previously the mouse position in the view was tracked using the
pointerPosition property. Scaling and relative mosue movements
were calculated in the view using screen properties stored in the
videoContext structure. Now when moving to iOSGraphicsManager all
that handling will be handled by the WindowedGraphicsManager,
which the iOSGraphicsManager inherit.
Rework the input code to send down pure x and y position values,
scaled according to the view content scale factor.
Remove code related to mouse movement that is no longer needed.
Changed paths:
backends/platform/ios7/ios7_game_controller.h
backends/platform/ios7/ios7_game_controller.mm
backends/platform/ios7/ios7_osys_events.cpp
backends/platform/ios7/ios7_osys_main.cpp
backends/platform/ios7/ios7_osys_main.h
backends/platform/ios7/ios7_touch_controller.mm
backends/platform/ios7/ios7_video.h
backends/platform/ios7/ios7_video.mm
diff --git a/backends/platform/ios7/ios7_game_controller.h b/backends/platform/ios7/ios7_game_controller.h
index 21d03b04ebb..e8bb5019397 100644
--- a/backends/platform/ios7/ios7_game_controller.h
+++ b/backends/platform/ios7/ios7_game_controller.h
@@ -28,12 +28,6 @@
@interface GameController : NSObject
-typedef enum {
- kGameControllerMouseButtonLeft = 0,
- kGameControllerMouseButtonRight,
- kGameControllerMouseButtonMiddle,
-} GameControllerMouseButton;
-
typedef enum {
kGameControllerJoystickLeft = 0,
kGameControllerJoystickRight
@@ -45,8 +39,7 @@ typedef enum {
- (id)initWithView:(iPhoneView *)v;
-- (void)handlePointerMoveTo:(CGPoint)point;
-- (void)handleMouseButtonAction:(GameControllerMouseButton)button isPressed:(bool)pressed at:(CGPoint)point;
+- (CGPoint)getLocationInView:(UITouch *)touch;
- (void)handleJoystickAxisMotionX:(int)x andY:(int)y forJoystick:(GameControllerJoystick)joystick;
- (void)handleJoystickButtonAction:(int)button isPressed:(bool)pressed;
diff --git a/backends/platform/ios7/ios7_game_controller.mm b/backends/platform/ios7/ios7_game_controller.mm
index cff3b745cff..d3b82cd24ea 100644
--- a/backends/platform/ios7/ios7_game_controller.mm
+++ b/backends/platform/ios7/ios7_game_controller.mm
@@ -51,59 +51,11 @@
[view addEvent:InternalEvent(kInputChanged, 0, 0)];
}
-- (void)handlePointerMoveTo:(CGPoint)point {
- int x, y;
-
- // Only set valid mouse coordinates in games
- if (![view getMouseCoords:point eventX:&x eventY:&y]) {
- return;
- }
-
- [view setPointerPosition:point];
-
- if (_firstButtonPressed) {
- [view addEvent:InternalEvent(kInputTouchFirstDragged, x, y)];
- } else if (_secondButtonPressed) {
- [view addEvent:InternalEvent(kInputTouchSecondDragged, x, y)];
- } else {
- [view addEvent:InternalEvent(kInputTouchFirstDragged, x, y)];
- }
-}
-
-- (void)handleMouseButtonAction:(GameControllerMouseButton)button isPressed:(bool)pressed at:(CGPoint)point{
- int x, y;
-
- // Only set valid mouse coordinates in games
- if (![view getMouseCoords:[view pointerPosition] eventX:&x eventY:&y]) {
- return;
- }
-
- [view setPointerPosition:point];
-
- switch (button) {
- case kGameControllerMouseButtonLeft:
- if (pressed) {
- _firstButtonPressed = YES;
- [view addEvent:InternalEvent(kInputTouchFirstDown, x, y)];
- } else {
- _firstButtonPressed = NO;
- [view addEvent:InternalEvent(kInputTouchFirstUp, x, y)];
- }
- break;
-
- case kGameControllerMouseButtonRight:
- if (pressed) {
- _secondButtonPressed = YES;
- [view addEvent:InternalEvent(kInputTouchSecondDown, x, y)];
- } else {
- _secondButtonPressed = NO;
- [view addEvent:InternalEvent(kInputTouchSecondUp, x, y)];
- }
- break;
-
- default:
- break;
- }
+- (CGPoint)getLocationInView:(UITouch *)touch; {
+ CGPoint p = [touch locationInView:[self view]];
+ p.x *= [[self view] contentScaleFactor];
+ p.y *= [[self view] contentScaleFactor];
+ return p;
}
- (void)handleJoystickAxisMotionX:(int)x andY:(int)y forJoystick:(GameControllerJoystick)joystick {
diff --git a/backends/platform/ios7/ios7_osys_events.cpp b/backends/platform/ios7/ios7_osys_events.cpp
index 79ee8bf5733..1b8cc92896f 100644
--- a/backends/platform/ios7/ios7_osys_events.cpp
+++ b/backends/platform/ios7/ios7_osys_events.cpp
@@ -25,7 +25,7 @@
#include "gui/message.h"
#include "common/translation.h"
#include "common/config-manager.h"
-
+#include "backends/graphics/ios/ios-graphics.h"
#include "backends/platform/ios7/ios7_osys_main.h"
static const int kQueuedInputEventDelay = 50;
@@ -181,13 +181,13 @@ bool OSystem_iOS7::handleEvent_touchFirstDown(Common::Event &event, int x, int y
_lastPadY = y;
if (!_touchpadModeEnabled) {
- warpMouse(x, y);
+ Common::Point mouse(x, y);
+ dynamic_cast<iOSCommonGraphics *>(_graphicsManager)->notifyMousePosition(mouse);
}
if (_mouseClickAndDragEnabled) {
event.type = Common::EVENT_LBUTTONDOWN;
- event.mouse.x = _videoContext->mouseX;
- event.mouse.y = _videoContext->mouseY;
+ handleEvent_mouseEvent(event, 0, 0);
return true;
} else {
_lastMouseDown = getMillis();
@@ -204,17 +204,14 @@ bool OSystem_iOS7::handleEvent_touchFirstUp(Common::Event &event, int x, int y)
return false;
} else if (_mouseClickAndDragEnabled) {
event.type = Common::EVENT_LBUTTONUP;
- event.mouse.x = _videoContext->mouseX;
- event.mouse.y = _videoContext->mouseY;
+ handleEvent_mouseEvent(event, 0, 0);
} else {
if (getMillis() - _lastMouseDown < 250) {
event.type = Common::EVENT_LBUTTONDOWN;
- event.mouse.x = _videoContext->mouseX;
- event.mouse.y = _videoContext->mouseY;
+ handleEvent_mouseEvent(event, 0, 0);
_queuedInputEvent.type = Common::EVENT_LBUTTONUP;
- _queuedInputEvent.mouse.x = _videoContext->mouseX;
- _queuedInputEvent.mouse.y = _videoContext->mouseY;
+ handleEvent_mouseEvent(_queuedInputEvent, 0, 0);
_lastMouseTap = getMillis();
_queuedEventTime = _lastMouseTap + kQueuedInputEventDelay;
} else
@@ -229,12 +226,10 @@ bool OSystem_iOS7::handleEvent_touchSecondDown(Common::Event &event, int x, int
if (_mouseClickAndDragEnabled) {
event.type = Common::EVENT_LBUTTONUP;
- event.mouse.x = _videoContext->mouseX;
- event.mouse.y = _videoContext->mouseY;
+ handleEvent_mouseEvent(event, 0, 0);
_queuedInputEvent.type = Common::EVENT_RBUTTONDOWN;
- _queuedInputEvent.mouse.x = _videoContext->mouseX;
- _queuedInputEvent.mouse.y = _videoContext->mouseY;
+ handleEvent_mouseEvent(_queuedInputEvent, 0, 0);
} else
return false;
@@ -259,11 +254,9 @@ bool OSystem_iOS7::handleEvent_touchSecondUp(Common::Event &event, int x, int y)
} else if (!_mouseClickAndDragEnabled) {
//printf("Rightclick!\n");
event.type = Common::EVENT_RBUTTONDOWN;
- event.mouse.x = _videoContext->mouseX;
- event.mouse.y = _videoContext->mouseY;
+ handleEvent_mouseEvent(event, 0, 0);
_queuedInputEvent.type = Common::EVENT_RBUTTONUP;
- _queuedInputEvent.mouse.x = _videoContext->mouseX;
- _queuedInputEvent.mouse.y = _videoContext->mouseY;
+ handleEvent_mouseEvent(_queuedInputEvent, 0, 0);
_lastSecondaryTap = curTime;
_queuedEventTime = curTime + kQueuedInputEventDelay;
} else {
@@ -273,20 +266,13 @@ bool OSystem_iOS7::handleEvent_touchSecondUp(Common::Event &event, int x, int y)
}
if (_mouseClickAndDragEnabled) {
event.type = Common::EVENT_RBUTTONUP;
- event.mouse.x = _videoContext->mouseX;
- event.mouse.y = _videoContext->mouseY;
+ handleEvent_mouseEvent(event, 0, 0);
}
return true;
}
bool OSystem_iOS7::handleEvent_touchFirstDragged(Common::Event &event, int x, int y) {
- if (_lastDragPosX == x && _lastDragPosY == y)
- return false;
-
- _lastDragPosX = x;
- _lastDragPosY = y;
-
//printf("Mouse dragged at (%u, %u)\n", x, y);
int deltaX = _lastPadX - x;
int deltaY = _lastPadY - y;
@@ -296,13 +282,11 @@ bool OSystem_iOS7::handleEvent_touchFirstDragged(Common::Event &event, int x, in
if (_touchpadModeEnabled) {
handleEvent_mouseDelta(event, deltaX, deltaY);
} else {
+ // Update mouse position
+ Common::Point mousePos(x, y);
+ dynamic_cast<iOSCommonGraphics *>(_graphicsManager)->notifyMousePosition(mousePos);
event.type = Common::EVENT_MOUSEMOVE;
- event.relMouse.x = deltaX;
- event.relMouse.y = deltaY;
- event.mouse.x = x;
- event.mouse.y = y;
- warpMouse(x, y);
-
+ handleEvent_mouseEvent(event, deltaX, deltaY);
}
return true;
}
@@ -313,55 +297,46 @@ bool OSystem_iOS7::handleEvent_touchSecondDragged(Common::Event &event, int x, i
void OSystem_iOS7::handleEvent_mouseLeftButtonDown(Common::Event &event, int x, int y) {
event.type = Common::EVENT_LBUTTONDOWN;
- event.mouse.x = _videoContext->mouseX;
- event.mouse.y = _videoContext->mouseY;
+ handleEvent_mouseEvent(event, 0, 0);
}
void OSystem_iOS7::handleEvent_mouseLeftButtonUp(Common::Event &event, int x, int y) {
event.type = Common::EVENT_LBUTTONUP;
- event.mouse.x = _videoContext->mouseX;
- event.mouse.y = _videoContext->mouseY;
+ handleEvent_mouseEvent(event, 0, 0);
}
void OSystem_iOS7::handleEvent_mouseRightButtonDown(Common::Event &event, int x, int y) {
event.type = Common::EVENT_RBUTTONDOWN;
- event.mouse.x = _videoContext->mouseX;
- event.mouse.y = _videoContext->mouseY;
+ handleEvent_mouseEvent(event, 0, 0);
}
void OSystem_iOS7::handleEvent_mouseRightButtonUp(Common::Event &event, int x, int y) {
event.type = Common::EVENT_RBUTTONUP;
- event.mouse.x = _videoContext->mouseX;
- event.mouse.y = _videoContext->mouseY;
+ handleEvent_mouseEvent(event, 0, 0);
}
void OSystem_iOS7::handleEvent_mouseDelta(Common::Event &event, int deltaX, int deltaY) {
- int mouseNewPosX = (int)(_videoContext->mouseX - (int)((float)deltaX * getMouseSpeed()));
- int mouseNewPosY = (int)(_videoContext->mouseY - (int)((float)deltaY * getMouseSpeed()));
-
- int widthCap = _videoContext->overlayInGUI ? _videoContext->overlayWidth : _videoContext->screenWidth;
- int heightCap = _videoContext->overlayInGUI ? _videoContext->overlayHeight : _videoContext->screenHeight;
-
- // Make sure the mouse position is valid
- if (mouseNewPosX < 0)
- mouseNewPosX = 0;
- else if (mouseNewPosX > widthCap)
- mouseNewPosX = widthCap;
- if (mouseNewPosY < 0)
- mouseNewPosY = 0;
- else if (mouseNewPosY > heightCap)
- mouseNewPosY = heightCap;
+ Common::Point mouseOldPos = dynamic_cast<iOSCommonGraphics *>(_graphicsManager)->getMousePosition();
+
+ Common::Point newMousePos((int)(mouseOldPos.x - (int)((float)deltaX * getMouseSpeed())), (int)(mouseOldPos.y - (int)((float)deltaY * getMouseSpeed())));
+
+ // Update mouse position
+ dynamic_cast<iOSCommonGraphics *>(_graphicsManager)->notifyMousePosition(newMousePos);
event.type = Common::EVENT_MOUSEMOVE;
- event.relMouse.x = deltaX;
- event.relMouse.y = deltaY;
- event.mouse.x = mouseNewPosX;
- event.mouse.y = mouseNewPosY;
+ handleEvent_mouseEvent(event, deltaX, deltaY);
+}
- // Move the mouse on screen
- warpMouse(mouseNewPosX, mouseNewPosY);
+void OSystem_iOS7::handleEvent_mouseEvent(Common::Event &event, int relX, int relY) {
+ Common::Point mouse = dynamic_cast<iOSCommonGraphics *>(_graphicsManager)->getMousePosition();
+ dynamic_cast<iOSCommonGraphics *>(_graphicsManager)->notifyMousePosition(mouse);
+
+ event.relMouse.x = relX;
+ event.relMouse.y = relY;
+ event.mouse = mouse;
}
+
void OSystem_iOS7::handleEvent_orientationChanged(int orientation) {
//printf("Orientation: %i\n", orientation);
diff --git a/backends/platform/ios7/ios7_osys_main.cpp b/backends/platform/ios7/ios7_osys_main.cpp
index 284b8048f99..203d7a43ce0 100644
--- a/backends/platform/ios7/ios7_osys_main.cpp
+++ b/backends/platform/ios7/ios7_osys_main.cpp
@@ -90,7 +90,7 @@ OSystem_iOS7::OSystem_iOS7() :
_mouseNeedTextureUpdate(false), _secondaryTapped(false), _lastSecondaryTap(0),
_screenOrientation(kScreenOrientationFlippedLandscape),
_fullScreenIsDirty(false), _fullScreenOverlayIsDirty(false),
- _mouseDirty(false), _timeSuspended(0), _lastDragPosX(-1), _lastDragPosY(-1), _screenChangeCount(0),
+ _mouseDirty(false), _timeSuspended(0), _screenChangeCount(0),
_mouseCursorPaletteEnabled(false), _gfxTransactionError(kTransactionSuccess) {
_queuedInputEvent.type = Common::EVENT_INVALID;
_touchpadModeEnabled = ConfMan.getBool("touchpad_mode");
diff --git a/backends/platform/ios7/ios7_osys_main.h b/backends/platform/ios7/ios7_osys_main.h
index 1760fe229fb..2eae191715e 100644
--- a/backends/platform/ios7/ios7_osys_main.h
+++ b/backends/platform/ios7/ios7_osys_main.h
@@ -91,8 +91,6 @@ protected:
bool _touchpadModeEnabled;
int _lastPadX;
int _lastPadY;
- int _lastDragPosX;
- int _lastDragPosY;
Common::Array<Common::Rect> _dirtyRects;
Common::Array<Common::Rect> _dirtyOverlayRects;
@@ -221,6 +219,7 @@ protected:
void handleEvent_mouseRightButtonDown(Common::Event &event, int x, int y);
void handleEvent_mouseRightButtonUp(Common::Event &event, int x, int y);
void handleEvent_mouseDelta(Common::Event &event, int deltaX, int deltaY);
+ void handleEvent_mouseEvent(Common::Event &event, int relX, int relY);
void rebuildSurface();
float getMouseSpeed();
diff --git a/backends/platform/ios7/ios7_touch_controller.mm b/backends/platform/ios7/ios7_touch_controller.mm
index e68fbe4d2e8..feb97f616aa 100644
--- a/backends/platform/ios7/ios7_touch_controller.mm
+++ b/backends/platform/ios7/ios7_touch_controller.mm
@@ -57,44 +57,38 @@
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSSet *allTouches = [event allTouches];
- if (allTouches.count == 1) {
+ switch (allTouches.count) {
+ case 1: {
_firstTouch = [allTouches anyObject];
- if (iOS7_touchpadModeEnabled()) {
- // In touchpad mode the action should occur on the current pointer position
- [self handleMouseButtonAction:kGameControllerMouseButtonLeft isPressed:YES at:[[self view] pointerPosition]];
- } else if (_firstTouch.type == UITouchTypeDirect) {
- // Only move the pointer to the new position if not in touchpadMode else it's very hard to click on items
- [self handlePointerMoveTo:[_firstTouch locationInView: [self view]]];
- [self handleMouseButtonAction:kGameControllerMouseButtonLeft isPressed:YES at:[_firstTouch locationInView:[self view]]];
+ if (_firstTouch.type == UITouchTypeDirect) {
+ CGPoint p = [self getLocationInView:_firstTouch];
+ [[self view] addEvent:InternalEvent(kInputTouchFirstDown, p.x, p.y)];
}
- } else if (allTouches.count == 2) {
+ break;
+ }
+ case 2: {
_secondTouch = [self secondTouchOtherTouchThan:_firstTouch in:allTouches];
- if (_secondTouch) {
- if (iOS7_touchpadModeEnabled()) {
- // In touchpad mode the action should occur on the current pointer position
- [self handleMouseButtonAction:kGameControllerMouseButtonRight isPressed:YES at:[[self view] pointerPosition]];
- } else if (_secondTouch.type == UITouchTypeDirect) {
- [self handleMouseButtonAction:kGameControllerMouseButtonRight isPressed:YES at:[_secondTouch locationInView:[self view]]];
- }
+ if (_secondTouch && _secondTouch.type == UITouchTypeDirect) {
+ CGPoint p = [self getLocationInView:_firstTouch];
+ [[self view] addEvent:InternalEvent(kInputTouchSecondDown, p.x, p.y)];
}
+ break;
+ }
+ default:
+ break;
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
NSSet *allTouches = [event allTouches];
for (UITouch *touch in allTouches) {
- if (touch == _firstTouch ||
- touch == _secondTouch) {
- if (iOS7_touchpadModeEnabled() || _firstTouch.type == UITouchTypeIndirect) {
- // Calculate new position for the pointer based on delta of the current and previous location of the touch
- CGPoint pointerLocation = [[self view] pointerPosition];
- CGPoint touchLocation = [touch locationInView:[self view]];
- CGPoint previousTouchLocation = [touch previousLocationInView:[self view]];
- pointerLocation.y += touchLocation.y - previousTouchLocation.y;
- pointerLocation.x += touchLocation.x - previousTouchLocation.x;
- [self handlePointerMoveTo:pointerLocation];
- } else if (_firstTouch.type == UITouchTypeDirect) {
- [self handlePointerMoveTo:[touch locationInView: [self view]]];
+ if (touch.type == UITouchTypeDirect) {
+ if (touch == _firstTouch) {
+ CGPoint p = [self getLocationInView:touch];
+ [[self view] addEvent:InternalEvent(kInputTouchFirstDragged , p.x, p.y)];
+ } else if (touch == _secondTouch) {
+ CGPoint p = [self getLocationInView:touch];
+ [[self view] addEvent:InternalEvent(kInputTouchSecondDragged , p.x, p.y)];
}
}
}
@@ -102,20 +96,25 @@
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSSet *allTouches = [event allTouches];
- if (allTouches.count == 1) {
- UITouch *touch = [allTouches anyObject];
- if (iOS7_touchpadModeEnabled()) {
- [self handleMouseButtonAction:kGameControllerMouseButtonLeft isPressed:NO at:[[self view] pointerPosition]];
- } else if (touch.type == UITouchTypeDirect) {
- [self handleMouseButtonAction:kGameControllerMouseButtonLeft isPressed:NO at:[touch locationInView:[self view]]];
+ switch (allTouches.count) {
+ case 1: {
+ _firstTouch = [allTouches anyObject];
+ if (_firstTouch.type == UITouchTypeDirect) {
+ CGPoint p = [self getLocationInView:_firstTouch];
+ [[self view] addEvent:InternalEvent(kInputTouchFirstUp, p.x, p.y)];
}
- } else if (allTouches.count == 2) {
- UITouch *touch = [[allTouches allObjects] objectAtIndex:1];
- if (iOS7_touchpadModeEnabled()) {
- [self handleMouseButtonAction:kGameControllerMouseButtonRight isPressed:NO at:[[self view] pointerPosition]];
- } else if (touch.type == UITouchTypeDirect) {
- [self handleMouseButtonAction:kGameControllerMouseButtonRight isPressed:NO at:[touch locationInView:[self view]]];
+ break;
+ }
+ case 2: {
+ _secondTouch = [self secondTouchOtherTouchThan:_firstTouch in:allTouches];
+ if (_secondTouch && _secondTouch.type == UITouchTypeDirect) {
+ CGPoint p = [self getLocationInView:_firstTouch];
+ [[self view] addEvent:InternalEvent(kInputTouchSecondUp, p.x, p.y)];
}
+ break;
+ }
+ default:
+ break;
}
_firstTouch = nil;
_secondTouch = nil;
diff --git a/backends/platform/ios7/ios7_video.h b/backends/platform/ios7/ios7_video.h
index d36a97320de..f04a99107ef 100644
--- a/backends/platform/ios7/ios7_video.h
+++ b/backends/platform/ios7/ios7_video.h
@@ -94,7 +94,6 @@ uint getSizeNextPOT(uint size);
int _scaledShakeYOffset;
}
- at property (nonatomic, assign) CGPoint pointerPosition;
@property (nonatomic, assign) BOOL isInGame;
- (id)initWithFrame:(struct CGRect)frame;
diff --git a/backends/platform/ios7/ios7_video.mm b/backends/platform/ios7/ios7_video.mm
index 6c57d2823be..2b44e8b772a 100644
--- a/backends/platform/ios7/ios7_video.mm
+++ b/backends/platform/ios7/ios7_video.mm
@@ -104,8 +104,6 @@ uint getSizeNextPOT(uint size) {
@implementation iPhoneView
- at synthesize pointerPosition;
-
+ (Class)layerClass {
return [CAEAGLLayer class];
}
Commit: d36074773b474660c31e398c86179326e035741e
https://github.com/scummvm/scummvm/commit/d36074773b474660c31e398c86179326e035741e
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-07-03T21:50:32+02:00
Commit Message:
IOS7: Add internal event for signalling screen changes
When the screen dimension changes, e.g. on rotation of the device,
the graphic manager has to be informed of the new dimension to be
able to resize the surfaces.
To quickly redraw the entire screen, Common::EVENT_SCREEN_CHANGED
event is passed to the event handler.
Changed paths:
backends/platform/ios7/ios7_common.h
backends/platform/ios7/ios7_osys_events.cpp
backends/platform/ios7/ios7_video.mm
diff --git a/backends/platform/ios7/ios7_common.h b/backends/platform/ios7/ios7_common.h
index 57d1a979e2b..9039e480601 100644
--- a/backends/platform/ios7/ios7_common.h
+++ b/backends/platform/ios7/ios7_common.h
@@ -50,7 +50,8 @@ enum InputEvent {
kInputJoystickAxisMotion,
kInputJoystickButtonDown,
kInputJoystickButtonUp,
- kInputChanged
+ kInputChanged,
+ kInputScreenChanged
};
enum ScreenOrientation {
diff --git a/backends/platform/ios7/ios7_osys_events.cpp b/backends/platform/ios7/ios7_osys_events.cpp
index 1b8cc92896f..b2f816a18d1 100644
--- a/backends/platform/ios7/ios7_osys_events.cpp
+++ b/backends/platform/ios7/ios7_osys_events.cpp
@@ -161,6 +161,12 @@ bool OSystem_iOS7::pollEvent(Common::Event &event) {
_queuedEventTime = getMillis() + kQueuedInputEventDelay;
break;
+ case kInputScreenChanged:
+ rebuildSurface();
+ dynamic_cast<iOSCommonGraphics *>(_graphicsManager)->notifyResize(getScreenWidth(), getScreenHeight());
+ event.type = Common::EVENT_SCREEN_CHANGED;
+ break;
+
default:
break;
}
diff --git a/backends/platform/ios7/ios7_video.mm b/backends/platform/ios7/ios7_video.mm
index 2b44e8b772a..f18a2f1153f 100644
--- a/backends/platform/ios7/ios7_video.mm
+++ b/backends/platform/ios7/ios7_video.mm
@@ -112,6 +112,18 @@ uint getSizeNextPOT(uint size) {
return &_videoContext;
}
+// According to Apple doc layoutSublayersOfLayer: is supported from iOS 10.0.
+// This doesn't seem to be correct since the instance method layoutSublayers,
+// supported from iOS 2.0, default calls the layoutSublayersOfLayer: method
+// of the layerâs delegate object. It's been verified that this function is
+// called in at least iOS 9.3.5.
+- (void)layoutSublayersOfLayer:(CAEAGLLayer *)layer {
+ if (layer == self.layer) {
+ [self addEvent:InternalEvent(kInputScreenChanged, 0, 0)];
+ }
+ [super layoutSublayersOfLayer:layer];
+}
+
- (void)createContext {
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
@@ -1172,6 +1184,9 @@ uint getSizeNextPOT(uint size) {
- (void)applicationResume {
[self addEvent:InternalEvent(kInputApplicationResumed, 0, 0)];
+ // The device may have changed orientation. Make sure to update
+ // the screen size to the graphic manager.
+ [self addEvent:InternalEvent(kInputScreenChanged, 0, 0)];
}
- (void)saveApplicationState {
Commit: fb4f7d6de243195d39f330968bbff7d93eff2a3c
https://github.com/scummvm/scummvm/commit/fb4f7d6de243195d39f330968bbff7d93eff2a3c
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-07-03T21:50:32+02:00
Commit Message:
IOS7: Remove old IOS7 graphic handling
Delete the old graphic handling in the IOS7 backend which is not
used anymore after implementing iOSGraphicsManager.
The Accelerate framework is not used anymore. The OpenGLGraphics
manager handles the different color formats.
Changed paths:
backends/platform/ios7/ios7_common.h
backends/platform/ios7/ios7_mouse_controller.mm
backends/platform/ios7/ios7_osys_events.cpp
backends/platform/ios7/ios7_osys_main.cpp
backends/platform/ios7/ios7_osys_main.h
backends/platform/ios7/ios7_osys_video.mm
backends/platform/ios7/ios7_video.h
backends/platform/ios7/ios7_video.mm
configure
devtools/create_project/xcode.cpp
ports.mk
diff --git a/backends/platform/ios7/ios7_common.h b/backends/platform/ios7/ios7_common.h
index 9039e480601..8f1ba8380ec 100644
--- a/backends/platform/ios7/ios7_common.h
+++ b/backends/platform/ios7/ios7_common.h
@@ -73,37 +73,6 @@ enum UIViewTapDescription {
kUIViewTapDouble = 2
};
-struct VideoContext {
- VideoContext() : asprectRatioCorrection(), screenWidth(), screenHeight(), overlayVisible(false),
- overlayInGUI(false), overlayWidth(), overlayHeight(), mouseX(), mouseY(),
- mouseHotspotX(), mouseHotspotY(), mouseWidth(), mouseHeight(),
- mouseIsVisible(), filtering(false), shakeXOffset(), shakeYOffset() {
- }
-
- // Game screen state
- bool asprectRatioCorrection;
- uint screenWidth, screenHeight;
- Graphics::Surface screenTexture;
-
- // Overlay state
- bool overlayVisible;
- bool overlayInGUI;
- uint overlayWidth, overlayHeight;
- Graphics::Surface overlayTexture;
-
- // Mouse cursor state
- uint mouseX, mouseY;
- int mouseHotspotX, mouseHotspotY;
- uint mouseWidth, mouseHeight;
- bool mouseIsVisible;
- Graphics::Surface mouseTexture;
-
- // Misc state
- bool filtering;
- int shakeXOffset;
- int shakeYOffset;
-};
-
struct InternalEvent {
InternalEvent() : type(), value1(), value2() {}
InternalEvent(InputEvent t, int v1, int v2) : type(t), value1(v1), value2(v2) {}
@@ -117,7 +86,6 @@ struct InternalEvent {
extern int iOS7_argc;
extern char **iOS7_argv;
-void iOS7_updateScreen();
bool iOS7_fetchEvent(InternalEvent *event);
bool iOS7_isBigDevice();
@@ -127,6 +95,4 @@ Common::String iOS7_getDocumentsDir();
Common::String iOS7_getAppBundleDir();
bool iOS7_touchpadModeEnabled();
-uint getSizeNextPOT(uint size);
-
#endif
diff --git a/backends/platform/ios7/ios7_mouse_controller.mm b/backends/platform/ios7/ios7_mouse_controller.mm
index e59f0cb98d2..6772d6db932 100644
--- a/backends/platform/ios7/ios7_mouse_controller.mm
+++ b/backends/platform/ios7/ios7_mouse_controller.mm
@@ -58,10 +58,8 @@
_mouse = (GCMouse*)notification.object;
_mouse.mouseInput.mouseMovedHandler = ^(GCMouseInput * _Nonnull mouse, float deltaX, float deltaY) {
- CGFloat scaleX, scaleY;
- [[self view] getMouseScaleFactorX:&scaleX andY:&scaleY];
- CGFloat scaledDeltaX = deltaX * scaleX + _dxReminder;
- CGFloat scaledDeltaY = deltaY * scaleY + _dyReminder;
+ CGFloat scaledDeltaX = deltaX * [[self view] contentScaleFactor] + _dxReminder;
+ CGFloat scaledDeltaY = deltaY * [[self view] contentScaleFactor] + _dyReminder;
// Add any reminding delta values to be summed up and get the integer part of the delta
int dx = (int)(scaledDeltaX);
int dy = (int)(scaledDeltaY);
diff --git a/backends/platform/ios7/ios7_osys_events.cpp b/backends/platform/ios7/ios7_osys_events.cpp
index b2f816a18d1..fd7c08d2ab3 100644
--- a/backends/platform/ios7/ios7_osys_events.cpp
+++ b/backends/platform/ios7/ios7_osys_events.cpp
@@ -247,7 +247,7 @@ bool OSystem_iOS7::handleEvent_touchSecondUp(Common::Event &event, int x, int y)
if (curTime - _lastSecondaryDown < 400) {
//printf("Right tap!\n");
- if (curTime - _lastSecondaryTap < 400 && !_videoContext->overlayInGUI) {
+ if (curTime - _lastSecondaryTap < 400) {
//printf("Right escape!\n");
event.type = Common::EVENT_KEYDOWN;
_queuedInputEvent.type = Common::EVENT_KEYUP;
@@ -372,12 +372,6 @@ void OSystem_iOS7::handleEvent_orientationChanged(int orientation) {
void OSystem_iOS7::rebuildSurface() {
updateOutputSurface();
-
- dirtyFullScreen();
- if (_videoContext->overlayVisible) {
- dirtyFullOverlayScreen();
- }
- updateScreen();
}
void OSystem_iOS7::handleEvent_applicationSuspended() {
diff --git a/backends/platform/ios7/ios7_osys_main.cpp b/backends/platform/ios7/ios7_osys_main.cpp
index 203d7a43ce0..d222d1e2277 100644
--- a/backends/platform/ios7/ios7_osys_main.cpp
+++ b/backends/platform/ios7/ios7_osys_main.cpp
@@ -87,11 +87,9 @@ public:
OSystem_iOS7::OSystem_iOS7() :
_mixer(NULL), _lastMouseTap(0), _queuedEventTime(0),
- _mouseNeedTextureUpdate(false), _secondaryTapped(false), _lastSecondaryTap(0),
+ _secondaryTapped(false), _lastSecondaryTap(0),
_screenOrientation(kScreenOrientationFlippedLandscape),
- _fullScreenIsDirty(false), _fullScreenOverlayIsDirty(false),
- _mouseDirty(false), _timeSuspended(0), _screenChangeCount(0),
- _mouseCursorPaletteEnabled(false), _gfxTransactionError(kTransactionSuccess) {
+ _timeSuspended(0) {
_queuedInputEvent.type = Common::EVENT_INVALID;
_touchpadModeEnabled = ConfMan.getBool("touchpad_mode");
_mouseClickAndDragEnabled = ConfMan.getBool("clickanddrag_mode");
@@ -103,24 +101,12 @@ OSystem_iOS7::OSystem_iOS7() :
Common::String appBubdlePath = iOS7_getAppBundleDir();
if (!appBubdlePath.empty())
chFsFactory->addVirtualDrive("appbundle:", appBubdlePath);
-
- initVideoContext();
-
- memset(_gamePalette, 0, sizeof(_gamePalette));
- memset(_gamePaletteRGBA5551, 0, sizeof(_gamePaletteRGBA5551));
- memset(_mouseCursorPalette, 0, sizeof(_mouseCursorPalette));
}
OSystem_iOS7::~OSystem_iOS7() {
AudioQueueDispose(s_AudioQueue.queue, true);
delete _mixer;
- // Prevent accidental freeing of the screen texture here. This needs to be
- // checked since we might use the screen texture as framebuffer in the case
- // of hi-color games for example. Otherwise this can lead to a double free.
- if (_framebuffer.getPixels() != _videoContext->screenTexture.getPixels())
- _framebuffer.free();
- _mouseBuffer.free();
delete _graphicsManager;
}
@@ -176,19 +162,6 @@ bool OSystem_iOS7::hasFeature(Feature f) {
void OSystem_iOS7::setFeatureState(Feature f, bool enable) {
switch (f) {
- case kFeatureCursorPalette:
- if (_mouseCursorPaletteEnabled != enable) {
- _mouseNeedTextureUpdate = true;
- _mouseDirty = true;
- _mouseCursorPaletteEnabled = enable;
- }
- break;
- case kFeatureFilteringMode:
- _videoContext->filtering = enable;
- break;
- case kFeatureAspectRatioCorrection:
- _videoContext->asprectRatioCorrection = enable;
- break;
case kFeatureVirtualKeyboard:
setShowKeyboard(enable);
break;
@@ -201,12 +174,6 @@ void OSystem_iOS7::setFeatureState(Feature f, bool enable) {
bool OSystem_iOS7::getFeatureState(Feature f) {
switch (f) {
- case kFeatureCursorPalette:
- return _mouseCursorPaletteEnabled;
- case kFeatureFilteringMode:
- return _videoContext->filtering;
- case kFeatureAspectRatioCorrection:
- return _videoContext->asprectRatioCorrection;
case kFeatureVirtualKeyboard:
return isKeyboardShown();
diff --git a/backends/platform/ios7/ios7_osys_main.h b/backends/platform/ios7/ios7_osys_main.h
index 2eae191715e..f94e052e334 100644
--- a/backends/platform/ios7/ios7_osys_main.h
+++ b/backends/platform/ios7/ios7_osys_main.h
@@ -58,28 +58,9 @@ protected:
Audio::MixerImpl *_mixer;
- VideoContext *_videoContext;
-
- Graphics::Surface _framebuffer;
-
- // For signaling that screen format set up might have failed.
- TransactionError _gfxTransactionError;
-
- // For use with the game texture
- uint16 _gamePalette[256];
- // For use with the mouse texture
- uint16 _gamePaletteRGBA5551[256];
-
CFTimeInterval _startTime;
uint32 _timeSuspended;
- bool _mouseCursorPaletteEnabled;
- uint16 _mouseCursorPalette[256];
- Graphics::Surface _mouseBuffer;
- uint16 _mouseKeyColor;
- bool _mouseDirty;
- bool _mouseNeedTextureUpdate;
-
long _lastMouseDown;
long _lastMouseTap;
long _queuedEventTime;
@@ -92,12 +73,7 @@ protected:
int _lastPadX;
int _lastPadY;
- Common::Array<Common::Rect> _dirtyRects;
- Common::Array<Common::Rect> _dirtyOverlayRects;
ScreenOrientation _screenOrientation;
- bool _fullScreenIsDirty;
- bool _fullScreenOverlayIsDirty;
- int _screenChangeCount;
Common::String _lastErrorMessage;
@@ -178,20 +154,14 @@ public:
virtual void registerDefaultSettings(const Common::String &target) const override;
protected:
- void initVideoContext();
void updateOutputSurface();
void setShowKeyboard(bool);
bool isKeyboardShown() const;
- void internUpdateScreen();
- void dirtyFullScreen();
- void dirtyFullOverlayScreen();
void suspendLoop();
void saveState();
void restoreState();
void clearState();
- void drawDirtyRect(const Common::Rect &dirtyRect);
- void updateMouseTexture();
static void AQBufferCallback(void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB);
static int timerHandler(int t);
diff --git a/backends/platform/ios7/ios7_osys_video.mm b/backends/platform/ios7/ios7_osys_video.mm
index 8d10bcf0de7..32b3908f988 100644
--- a/backends/platform/ios7/ios7_osys_video.mm
+++ b/backends/platform/ios7/ios7_osys_video.mm
@@ -25,7 +25,6 @@
#include "backends/platform/ios7/ios7_osys_main.h"
#include "backends/platform/ios7/ios7_video.h"
-#include "graphics/blit.h"
#include "backends/platform/ios7/ios7_app_delegate.h"
#define UIViewParentController(__view) ({ \
@@ -96,10 +95,6 @@ void OSystem_iOS7::engineDone() {
[[iOS7AppDelegate iPhoneView] setIsInGame:NO];
}
-void OSystem_iOS7::initVideoContext() {
- _videoContext = [[iOS7AppDelegate iPhoneView] getVideoContext];
-}
-
static inline void execute_on_main_thread(void (^block)(void)) {
if ([NSThread currentThread] == [NSThread mainThread]) {
block();
@@ -115,133 +110,12 @@ void OSystem_iOS7::updateOutputSurface() {
});
}
-void OSystem_iOS7::internUpdateScreen() {
- if (_mouseNeedTextureUpdate) {
- updateMouseTexture();
- _mouseNeedTextureUpdate = false;
- }
-
- while (_dirtyRects.size()) {
- Common::Rect dirtyRect = _dirtyRects.remove_at(_dirtyRects.size() - 1);
-
- //printf("Drawing: (%i, %i) -> (%i, %i)\n", dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom);
- drawDirtyRect(dirtyRect);
- // TODO: Implement dirty rect code
- //updateHardwareSurfaceForRect(dirtyRect);
- }
-
- if (_videoContext->overlayVisible) {
- // TODO: Implement dirty rect code
- _dirtyOverlayRects.clear();
- /*while (_dirtyOverlayRects.size()) {
- Common::Rect dirtyRect = _dirtyOverlayRects.remove_at(_dirtyOverlayRects.size() - 1);
-
- //printf("Drawing: (%i, %i) -> (%i, %i)\n", dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom);
- drawDirtyOverlayRect(dirtyRect);
- }*/
- }
-}
-
-void OSystem_iOS7::drawDirtyRect(const Common::Rect &dirtyRect) {
- // We only need to do a color look up for CLUT8
- if (_framebuffer.format.bytesPerPixel != 1)
- return;
-
- int h = dirtyRect.bottom - dirtyRect.top;
- int w = dirtyRect.right - dirtyRect.left;
-
- const byte *src = (const byte *)_framebuffer.getBasePtr(dirtyRect.left, dirtyRect.top);
- byte *dstRaw = (byte *)_videoContext->screenTexture.getBasePtr(dirtyRect.left, dirtyRect.top);
-
- // When we use CLUT8 do a color look up
- for (int y = h; y > 0; y--) {
- uint16 *dst = (uint16 *)dstRaw;
- for (int x = w; x > 0; x--)
- *dst++ = _gamePalette[*src++];
-
- dstRaw += _videoContext->screenTexture.pitch;
- src += _framebuffer.pitch - w;
- }
-}
-
void OSystem_iOS7::virtualController(bool connect) {
execute_on_main_thread(^ {
[[iOS7AppDelegate iPhoneView] virtualController:connect];
});
}
-void OSystem_iOS7::dirtyFullScreen() {
- if (!_fullScreenIsDirty) {
- _dirtyRects.clear();
- _dirtyRects.push_back(Common::Rect(0, 0, _videoContext->screenWidth, _videoContext->screenHeight));
- _fullScreenIsDirty = true;
- }
-}
-
-void OSystem_iOS7::dirtyFullOverlayScreen() {
- if (!_fullScreenOverlayIsDirty) {
- _dirtyOverlayRects.clear();
- _dirtyOverlayRects.push_back(Common::Rect(0, 0, _videoContext->overlayWidth, _videoContext->overlayHeight));
- _fullScreenOverlayIsDirty = true;
- }
-}
-
-void OSystem_iOS7::updateMouseTexture() {
- int texWidth = getSizeNextPOT(_videoContext->mouseWidth);
- int texHeight = getSizeNextPOT(_videoContext->mouseHeight);
-
- Graphics::Surface &mouseTexture = _videoContext->mouseTexture;
- if (mouseTexture.w != texWidth || mouseTexture.h != texHeight)
- mouseTexture.create(texWidth, texHeight, Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
-
- if (_mouseBuffer.format.bytesPerPixel == 1) {
- const uint16 *palette;
- if (_mouseCursorPaletteEnabled)
- palette = _mouseCursorPalette;
- else
- palette = _gamePaletteRGBA5551;
-
- uint16 *mouseBuf = (uint16 *)mouseTexture.getPixels();
- for (uint x = 0; x < _videoContext->mouseWidth; ++x) {
- for (uint y = 0; y < _videoContext->mouseHeight; ++y) {
- const byte color = *(const byte *)_mouseBuffer.getBasePtr(x, y);
- if (color != _mouseKeyColor)
- mouseBuf[y * texWidth + x] = palette[color] | 0x1;
- else
- mouseBuf[y * texWidth + x] = 0x0;
- }
- }
- } else {
- if (crossBlit((byte *)mouseTexture.getPixels(), (const byte *)_mouseBuffer.getPixels(), mouseTexture.pitch,
- _mouseBuffer.pitch, _mouseBuffer.w, _mouseBuffer.h, mouseTexture.format, _mouseBuffer.format)) {
- // Apply color keying
- const uint8 * src = (const uint8 *)_mouseBuffer.getPixels();
- int srcBpp = _mouseBuffer.format.bytesPerPixel;
-
- uint8 *dstRaw = (uint8 *)mouseTexture.getPixels();
-
- for (int y = 0; y < _mouseBuffer.h; ++y, dstRaw += mouseTexture.pitch) {
- uint16 *dst = (uint16 *)dstRaw;
- for (int x = 0; x < _mouseBuffer.w; ++x, ++dst, src += srcBpp) {
- if (
- (srcBpp == 2 && *((const uint16*)src) == _mouseKeyColor) ||
- (srcBpp == 4 && *((const uint32*)src) == _mouseKeyColor)
- )
- *dst &= ~1;
- }
- }
- } else {
- // TODO: Log this!
- // Make the cursor all transparent... we really need a better fallback ;-).
- memset(mouseTexture.getPixels(), 0, mouseTexture.h * mouseTexture.pitch);
- }
- }
-
- execute_on_main_thread(^ {
- [[iOS7AppDelegate iPhoneView] updateMouseCursor];
- });
-}
-
void OSystem_iOS7::setShowKeyboard(bool show) {
if (show) {
#if TARGET_OS_IOS
diff --git a/backends/platform/ios7/ios7_video.h b/backends/platform/ios7/ios7_video.h
index f04a99107ef..8ca321395a1 100644
--- a/backends/platform/ios7/ios7_video.h
+++ b/backends/platform/ios7/ios7_video.h
@@ -25,7 +25,6 @@
#include <UIKit/UIKit.h>
#include <Foundation/Foundation.h>
#include <QuartzCore/QuartzCore.h>
-#include <Accelerate/Accelerate.h>
#include <OpenGLES/EAGL.h>
#include <OpenGLES/ES2/gl.h>
@@ -45,8 +44,6 @@ typedef struct {
uint getSizeNextPOT(uint size);
@interface iPhoneView : UIView {
- VideoContext _videoContext;
-
Common::List<InternalEvent> _events;
NSLock *_eventLock;
SoftKeyboard *_keyboardView;
@@ -57,70 +54,22 @@ uint getSizeNextPOT(uint size);
EAGLContext *_mainContext;
EAGLContext *_openGLContext;
GLuint _viewRenderbuffer;
- GLuint _viewFramebuffer;
- GLuint _screenTexture;
- GLuint _overlayTexture;
- GLuint _mouseCursorTexture;
-
- GLuint _vertexShader;
- GLuint _fragmentShader;
-
- GLuint _vertexBuffer;
-
- GLuint _screenSizeSlot;
- GLuint _textureSlot;
- GLuint _shakeXSlot;
- GLuint _shakeYSlot;
-
- GLuint _positionSlot;
- GLuint _textureCoordSlot;
GLint _renderBufferWidth;
GLint _renderBufferHeight;
-
- GLVertex _gameScreenCoords[4];
- CGRect _gameScreenRect;
-
- GLVertex _overlayCoords[4];
- CGRect _overlayRect;
-
- GLVertex _mouseCoords[4];
-
- GLint _mouseHotspotX, _mouseHotspotY;
- GLint _mouseWidth, _mouseHeight;
- GLfloat _mouseScaleX, _mouseScaleY;
-
- int _scaledShakeXOffset;
- int _scaledShakeYOffset;
}
@property (nonatomic, assign) BOOL isInGame;
- (id)initWithFrame:(struct CGRect)frame;
-- (VideoContext *)getVideoContext;
-
- (uint)createOpenGLContext;
- (void)destroyOpenGLContext;
- (void)refreshScreen;
- (int)getScreenWidth;
- (int)getScreenHeight;
-- (void)setGameScreenCoords;
- (void)initSurface;
-- (void)setViewTransformation;
-
-- (void)setGraphicsMode;
-
-- (void)updateSurface;
-- (void)updateMainSurface;
-- (void)updateOverlaySurface;
-- (void)updateMouseSurface;
-- (void)clearColorBuffer;
-
-- (void)notifyMouseMove;
-- (void)updateMouseCursorScaling;
-- (void)updateMouseCursor;
#if TARGET_OS_IOS
- (void)interfaceOrientationChanged:(UIInterfaceOrientation)orientation;
@@ -145,8 +94,6 @@ uint getSizeNextPOT(uint size);
- (void)addEvent:(InternalEvent)event;
- (bool)fetchEvent:(InternalEvent *)event;
-- (void)getMouseScaleFactorX:(CGFloat *)x andY:(CGFloat *)y;
-- (bool)getMouseCoords:(CGPoint)point eventX:(int *)x eventY:(int *)y;
- (BOOL)isTouchControllerConnected;
- (BOOL)isMouseControllerConnected;
- (BOOL)isGamepadControllerConnected;
diff --git a/backends/platform/ios7/ios7_video.mm b/backends/platform/ios7/ios7_video.mm
index f18a2f1153f..e501f5cdfae 100644
--- a/backends/platform/ios7/ios7_video.mm
+++ b/backends/platform/ios7/ios7_video.mm
@@ -30,8 +30,6 @@
#include "backends/platform/ios7/ios7_app_delegate.h"
-static int g_needsScreenUpdate = 0;
-
#if 0
static long g_lastTick = 0;
static int g_frames = 0;
@@ -71,16 +69,6 @@ static inline void execute_on_main_thread(void (^block)(void)) {
}
}
-void iOS7_updateScreen() {
- //printf("Mouse: (%i, %i)\n", mouseX, mouseY);
- if (!g_needsScreenUpdate) {
- g_needsScreenUpdate = 1;
- execute_on_main_thread(^{
- [[iOS7AppDelegate iPhoneView] updateSurface];
- });
- }
-}
-
bool iOS7_fetchEvent(InternalEvent *event) {
__block bool fetched;
execute_on_main_thread(^{
@@ -89,29 +77,12 @@ bool iOS7_fetchEvent(InternalEvent *event) {
return fetched;
}
-uint getSizeNextPOT(uint size) {
- if ((size & (size - 1)) || !size) {
- int log = 0;
-
- while (size >>= 1)
- ++log;
-
- size = (2 << log);
- }
-
- return size;
-}
-
@implementation iPhoneView
+ (Class)layerClass {
return [CAEAGLLayer class];
}
-- (VideoContext *)getVideoContext {
- return &_videoContext;
-}
-
// According to Apple doc layoutSublayersOfLayer: is supported from iOS 10.0.
// This doesn't seem to be correct since the instance method layoutSublayers,
// supported from iOS 2.0, default calls the layoutSublayersOfLayer: method
@@ -181,57 +152,6 @@ uint getSizeNextPOT(uint size) {
return _renderBufferHeight;
}
-- (void)setupOpenGL {
- [self setupRenderBuffer];
- [self setupFramebuffer];
- [self createOverlaySurface];
- [self compileShaders];
- [self setupVBOs];
- [self setupTextures];
-
- [self finishGLSetup];
-}
-
-- (void)finishGLSetup {
- glViewport(0, 0, _renderBufferWidth, _renderBufferHeight); printOpenGLError();
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f); printOpenGLError();
-
- glUniform2f(_screenSizeSlot, _renderBufferWidth, _renderBufferHeight);
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-}
-
-- (void)freeOpenGL {
- [self deleteTextures];
- [self deleteVBOs];
- [self deleteShaders];
- [self deleteFramebuffer];
- [self deleteRenderbuffer];
-}
-
-- (void)rebuildFrameBuffer {
- [self deleteFramebuffer];
- [self setupFramebuffer];
- [self finishGLSetup];
-}
-
-- (void)setupFramebuffer {
- if (!_viewFramebuffer) {
- glGenFramebuffers(1, &_viewFramebuffer);
- printOpenGLError();
- }
- glBindFramebuffer(GL_FRAMEBUFFER, _viewFramebuffer);
- printOpenGLError();
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _viewRenderbuffer);
- printOpenGLError();
-
- if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
- NSLog(@"Failed to make complete framebuffer object %x.", glCheckFramebufferStatus(GL_FRAMEBUFFER));
- return;
- }
-}
-
- (void)setupRenderBuffer {
execute_on_main_thread(^{
if (!_viewRenderbuffer) {
@@ -252,153 +172,10 @@ uint getSizeNextPOT(uint size) {
});
}
-- (void)createOverlaySurface {
- uint overlayWidth = (uint) MAX(_renderBufferWidth, _renderBufferHeight);
- uint overlayHeight = (uint) MIN(_renderBufferWidth, _renderBufferHeight);
-
- _videoContext.overlayWidth = overlayWidth;
- _videoContext.overlayHeight = overlayHeight;
-
- uint overlayTextureWidthPOT = getSizeNextPOT(overlayWidth);
- uint overlayTextureHeightPOT = getSizeNextPOT(overlayHeight);
-
- // Since the overlay size won't change the whole run, we can
- // precalculate the texture coordinates for the overlay texture here
- // and just use it later on.
- GLfloat u = _videoContext.overlayWidth / (GLfloat) overlayTextureWidthPOT;
- GLfloat v = _videoContext.overlayHeight / (GLfloat) overlayTextureHeightPOT;
- _overlayCoords[0].x = 0; _overlayCoords[0].y = 0; _overlayCoords[0].u = 0; _overlayCoords[0].v = 0;
- _overlayCoords[1].x = 0; _overlayCoords[1].y = 0; _overlayCoords[1].u = u; _overlayCoords[1].v = 0;
- _overlayCoords[2].x = 0; _overlayCoords[2].y = 0; _overlayCoords[2].u = 0; _overlayCoords[2].v = v;
- _overlayCoords[3].x = 0; _overlayCoords[3].y = 0; _overlayCoords[3].u = u; _overlayCoords[3].v = v;
-
- _videoContext.overlayTexture.create((uint16) overlayTextureWidthPOT, (uint16) overlayTextureHeightPOT, Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
-}
-
- (void)deleteRenderbuffer {
glDeleteRenderbuffers(1, &_viewRenderbuffer);
}
-- (void)deleteFramebuffer {
- glDeleteFramebuffers(1, &_viewFramebuffer);
-}
-
-- (void)setupVBOs {
- glGenBuffers(1, &_vertexBuffer);
- glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
-}
-
-- (void)deleteVBOs {
- glDeleteBuffers(1, &_vertexBuffer);
-}
-
-- (GLuint)compileShader:(const char*)shaderPrg withType:(GLenum)shaderType {
- GLuint shaderHandle = glCreateShader(shaderType);
-
- int shaderPrgLength = strlen(shaderPrg);
- glShaderSource(shaderHandle, 1, &shaderPrg, &shaderPrgLength);
-
- glCompileShader(shaderHandle);
-
- GLint compileSuccess;
- glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &compileSuccess);
- if (compileSuccess == GL_FALSE) {
- GLchar messages[256];
- glGetShaderInfoLog(shaderHandle, sizeof(messages), 0, &messages[0]);
- printError(messages);
- abort();
- }
-
- return shaderHandle;
-}
-
-- (void)compileShaders {
- const char *vertexPrg =
- "uniform vec2 ScreenSize;"
- "uniform float ShakeX;"
- "uniform float ShakeY;"
- ""
- "attribute vec2 Position;"
- "attribute vec2 TexCoord;"
- ""
- "varying vec4 DestColor;"
- "varying vec2 o_TexCoord;"
- ""
- "void main(void) {"
- " DestColor = vec4(Position.x, Position.y, 0, 1);"
- " o_TexCoord = TexCoord;"
- " gl_Position = vec4(((Position.x + ShakeX) / ScreenSize.x) * 2.0 - 1.0, (1.0 - (Position.y + ShakeY) / ScreenSize.y) * 2.0 - 1.0, 0, 1);"
- "}";
-
- const char *fragmentPrg =
- "uniform sampler2D Texture;"
- ""
- "varying lowp vec4 DestColor;"
- "varying lowp vec2 o_TexCoord;"
- ""
- "void main(void) {"
- " gl_FragColor = texture2D(Texture, o_TexCoord);"
- "}";
-
- _vertexShader = [self compileShader:vertexPrg withType:GL_VERTEX_SHADER];
- _fragmentShader = [self compileShader:fragmentPrg withType:GL_FRAGMENT_SHADER];
-
- GLuint programHandle = glCreateProgram();
- glAttachShader(programHandle, _vertexShader);
- glAttachShader(programHandle, _fragmentShader);
- glLinkProgram(programHandle);
-
- GLint linkSuccess;
- glGetProgramiv(programHandle, GL_LINK_STATUS, &linkSuccess);
- if (linkSuccess == GL_FALSE) {
- printOpenGLError();
- abort();
- }
-
- glUseProgram(programHandle);
-
- _screenSizeSlot = (GLuint) glGetUniformLocation(programHandle, "ScreenSize");
- _textureSlot = (GLuint) glGetUniformLocation(programHandle, "Texture");
- _shakeXSlot = (GLuint) glGetUniformLocation(programHandle, "ShakeX");
- _shakeYSlot = (GLuint) glGetUniformLocation(programHandle, "ShakeY");
-
- _positionSlot = (GLuint) glGetAttribLocation(programHandle, "Position");
- _textureCoordSlot = (GLuint) glGetAttribLocation(programHandle, "TexCoord");
-
- glEnableVertexAttribArray(_positionSlot);
- glEnableVertexAttribArray(_textureCoordSlot);
-
- glUniform1i(_textureSlot, 0); printOpenGLError();
-}
-
-- (void)deleteShaders {
- glDeleteShader(_vertexShader);
- glDeleteShader(_fragmentShader);
-}
-
-- (void)setupTextures {
- glGenTextures(1, &_screenTexture); printOpenGLError();
- glGenTextures(1, &_overlayTexture); printOpenGLError();
- glGenTextures(1, &_mouseCursorTexture); printOpenGLError();
-
- [self setGraphicsMode];
-}
-
-- (void)deleteTextures {
- if (_screenTexture) {
- glDeleteTextures(1, &_screenTexture); printOpenGLError();
- _screenTexture = 0;
- }
- if (_overlayTexture) {
- glDeleteTextures(1, &_overlayTexture); printOpenGLError();
- _overlayTexture = 0;
- }
- if (_mouseCursorTexture) {
- glDeleteTextures(1, &_mouseCursorTexture); printOpenGLError();
- _mouseCursorTexture = 0;
- }
-}
-
- (void)setupGestureRecognizers {
#if TARGET_OS_IOS
UIPinchGestureRecognizer *pinchKeyboard = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(keyboardPinch:)];
@@ -525,19 +302,8 @@ uint getSizeNextPOT(uint size) {
[self setContentScaleFactor:[[UIScreen mainScreen] scale]];
_keyboardView = nil;
- _screenTexture = 0;
- _overlayTexture = 0;
- _mouseCursorTexture = 0;
-
- _scaledShakeXOffset = 0;
- _scaledShakeYOffset = 0;
-
_eventLock = [[NSLock alloc] init];
- memset(_gameScreenCoords, 0, sizeof(GLVertex) * 4);
- memset(_overlayCoords, 0, sizeof(GLVertex) * 4);
- memset(_mouseCoords, 0, sizeof(GLVertex) * 4);
-
// Initialize the OpenGL ES context
[self createContext];
@@ -547,221 +313,13 @@ uint getSizeNextPOT(uint size) {
- (void)dealloc {
[_keyboardView release];
- _videoContext.screenTexture.free();
- _videoContext.overlayTexture.free();
- _videoContext.mouseTexture.free();
-
[_eventLock release];
[super dealloc];
}
-- (void)setFilterModeForTexture:(GLuint)tex {
- if (!tex)
- return;
-
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, tex); printOpenGLError();
-
- GLint filter = _videoContext.filtering ? GL_LINEAR : GL_NEAREST;
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); printOpenGLError();
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); printOpenGLError();
- // We use GL_CLAMP_TO_EDGE here to avoid artifacts when linear filtering
- // is used. If we would not use this for example the cursor in Loom would
- // have a line/border artifact on the right side of the covered rect.
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); printOpenGLError();
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); printOpenGLError();
-}
-
-- (void)setGraphicsMode {
- [self setFilterModeForTexture:_screenTexture];
- [self setFilterModeForTexture:_overlayTexture];
- [self setFilterModeForTexture:_mouseCursorTexture];
-}
-
-- (void)updateSurface {
- if (!g_needsScreenUpdate) {
- return;
- }
- g_needsScreenUpdate = 0;
-
- glClear(GL_COLOR_BUFFER_BIT); printOpenGLError();
-
- [self updateMainSurface];
-
- if (_videoContext.overlayVisible)
- [self updateOverlaySurface];
-
- if (_videoContext.mouseIsVisible)
- [self updateMouseSurface];
-
- [_mainContext presentRenderbuffer:GL_RENDERBUFFER];
- glFinish();
-}
-
-- (void)notifyMouseMove {
- const GLint mouseX = (GLint)(_videoContext.mouseX * _mouseScaleX) - _mouseHotspotX;
- const GLint mouseY = (GLint)(_videoContext.mouseY * _mouseScaleY) - _mouseHotspotY;
-
- _mouseCoords[0].x = _mouseCoords[2].x = mouseX;
- _mouseCoords[0].y = _mouseCoords[1].y = mouseY;
- _mouseCoords[1].x = _mouseCoords[3].x = mouseX + _mouseWidth;
- _mouseCoords[2].y = _mouseCoords[3].y = mouseY + _mouseHeight;
-}
-
-- (void)updateMouseCursorScaling {
- CGRect *rect;
- int maxWidth, maxHeight;
-
- if (!_videoContext.overlayInGUI) {
- rect = &_gameScreenRect;
- maxWidth = _videoContext.screenWidth;
- maxHeight = _videoContext.screenHeight;
- } else {
- rect = &_overlayRect;
- maxWidth = _videoContext.overlayWidth;
- maxHeight = _videoContext.overlayHeight;
- }
-
- if (!maxWidth || !maxHeight) {
- printf("WARNING: updateMouseCursorScaling called when screen was not ready (%d)!\n", _videoContext.overlayInGUI);
- return;
- }
-
- _mouseScaleX = CGRectGetWidth(*rect) / (GLfloat)maxWidth;
- _mouseScaleY = CGRectGetHeight(*rect) / (GLfloat)maxHeight;
-
- _mouseWidth = (GLint)(_videoContext.mouseWidth * _mouseScaleX);
- _mouseHeight = (GLint)(_videoContext.mouseHeight * _mouseScaleY);
-
- _mouseHotspotX = (GLint)(_videoContext.mouseHotspotX * _mouseScaleX);
- _mouseHotspotY = (GLint)(_videoContext.mouseHotspotY * _mouseScaleY);
-
- // We subtract the screen offset to the hotspot here to simplify the
- // screen offset handling in the mouse code. Note the subtraction here
- // makes sure that the offset actually gets added to the mouse position,
- // since the hotspot offset is substracted from the position.
- _mouseHotspotX -= (GLint)CGRectGetMinX(*rect);
- _mouseHotspotY -= (GLint)CGRectGetMinY(*rect);
-
- // FIXME: For now we also adapt the mouse position here. In reality we
- // would be better off to also adjust the event position when switching
- // from overlay to game screen or vica versa.
- [self notifyMouseMove];
-}
-
-- (void)updateMouseCursor {
- [self updateMouseCursorScaling];
-
- _mouseCoords[1].u = _mouseCoords[3].u = (_videoContext.mouseWidth - 1) / (GLfloat)_videoContext.mouseTexture.w;
- _mouseCoords[2].v = _mouseCoords[3].v = (_videoContext.mouseHeight - 1) / (GLfloat)_videoContext.mouseTexture.h;
-
- [self setFilterModeForTexture:_mouseCursorTexture];
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _videoContext.mouseTexture.w, _videoContext.mouseTexture.h, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, _videoContext.mouseTexture.getPixels()); printOpenGLError();
-}
-
-- (void *)getTextureInRGBA8888BE_AsRGBA8888LE {
- // Allocate a pixel buffer with 32 bits per pixel
- void *pixelBuffer = malloc(_videoContext.screenTexture.h * _videoContext.screenTexture.w * sizeof(uint32_t));
- // Copy the texture pixels as we don't want to operate on the
- memcpy(pixelBuffer, _videoContext.screenTexture.getPixels(), _videoContext.screenTexture.h * _videoContext.screenTexture.w * sizeof(uint32_t));
-
- // Utilize the Accelerator Framwork to do some byte swapping
- vImage_Buffer src;
- src.height = _videoContext.screenTexture.h;
- src.width = _videoContext.screenTexture.w;
- src.rowBytes = _videoContext.screenTexture.pitch;
- src.data = _videoContext.screenTexture.getPixels();
-
- // Initialise dst with src, change data pointer to pixelBuffer
- vImage_Buffer dst = src;
- dst.data = pixelBuffer;
-
- // Swap pixel channels from RGBA BE to RGBA LE (ABGR)
- const uint8_t map[4] = { 3, 2, 1, 0 };
- vImagePermuteChannels_ARGB8888(&src, &dst, map, kvImageNoFlags);
-
- return pixelBuffer;
-}
-
-- (void)updateMainSurface {
- glBufferData(GL_ARRAY_BUFFER, sizeof(GLVertex) * 4, _gameScreenCoords, GL_STATIC_DRAW);
- glVertexAttribPointer(_positionSlot, 2, GL_FLOAT, GL_FALSE, sizeof(GLVertex), 0);
- glVertexAttribPointer(_textureCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(GLVertex), (GLvoid *) (sizeof(GLfloat) * 2));
-
- [self setFilterModeForTexture:_screenTexture];
-
- // Unfortunately we have to update the whole texture every frame, since glTexSubImage2D is actually slower in all cases
- // due to the iPhone internals having to convert the whole texture back from its internal format when used.
- // In the future we could use several tiled textures instead.
- if (_videoContext.screenTexture.format == Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)) {
- // ABGR8888 in big endian which in little endian is RBGA8888 -> no convertion needed
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _videoContext.screenTexture.w, _videoContext.screenTexture.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, _videoContext.screenTexture.getPixels()); printOpenGLError();
- } else if (_videoContext.screenTexture.format == Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)) {
- // RGBA8888 (big endian) = ABGR8888 (little endian) -> needs convertion
- void* pixelBuffer = [self getTextureInRGBA8888BE_AsRGBA8888LE];
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _videoContext.screenTexture.w, _videoContext.screenTexture.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelBuffer); printOpenGLError();
- free(pixelBuffer);
- } else {
- // Assuming RGB565
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _videoContext.screenTexture.w, _videoContext.screenTexture.h, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, _videoContext.screenTexture.getPixels()); printOpenGLError();
- }
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); printOpenGLError();
-}
-
-- (void)updateOverlaySurface {
- glBufferData(GL_ARRAY_BUFFER, sizeof(GLVertex) * 4, _overlayCoords, GL_STATIC_DRAW);
- glVertexAttribPointer(_positionSlot, 2, GL_FLOAT, GL_FALSE, sizeof(GLVertex), 0);
- glVertexAttribPointer(_textureCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(GLVertex), (GLvoid *) (sizeof(GLfloat) * 2));
-
- [self setFilterModeForTexture:_overlayTexture];
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _videoContext.overlayTexture.w, _videoContext.overlayTexture.h, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, _videoContext.overlayTexture.getPixels()); printOpenGLError();
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); printOpenGLError();
-}
-
-- (void)updateMouseSurface {
- glBufferData(GL_ARRAY_BUFFER, sizeof(GLVertex) * 4, _mouseCoords, GL_STATIC_DRAW);
- glVertexAttribPointer(_positionSlot, 2, GL_FLOAT, GL_FALSE, sizeof(GLVertex), 0);
- glVertexAttribPointer(_textureCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(GLVertex), (GLvoid *) (sizeof(GLfloat) * 2));
-
- glBindTexture(GL_TEXTURE_2D, _mouseCursorTexture); printOpenGLError();
-
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); printOpenGLError();
-}
-
-- (void)setGameScreenCoords{
- const uint screenTexWidth = getSizeNextPOT(_videoContext.screenWidth);
- const uint screenTexHeight = getSizeNextPOT(_videoContext.screenHeight);
-
- _gameScreenCoords[1].u = _gameScreenCoords[3].u = _videoContext.screenWidth / (GLfloat)screenTexWidth;
- _gameScreenCoords[2].v = _gameScreenCoords[3].v = _videoContext.screenHeight / (GLfloat)screenTexHeight;
-}
-
- (void)initSurface {
[self setupRenderBuffer];
-#if TARGET_OS_IOS
- UIInterfaceOrientation interfaceOrientation = UIInterfaceOrientationUnknown;
- if (@available(iOS 13.0, *)) {
- interfaceOrientation = [[[self window] windowScene] interfaceOrientation];
- } else {
- interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
- }
- BOOL isLandscape = UIInterfaceOrientationIsLandscape(interfaceOrientation);
-#else // TVOS
- BOOL isLandscape = YES;
-#endif
-
- int screenWidth, screenHeight;
- if (isLandscape) {
- screenWidth = MAX(_renderBufferWidth, _renderBufferHeight);
- screenHeight = MIN(_renderBufferWidth, _renderBufferHeight);
- } else {
- screenWidth = MIN(_renderBufferWidth, _renderBufferHeight);
- screenHeight = MAX(_renderBufferWidth, _renderBufferHeight);
- }
-
if (_keyboardView == nil) {
_keyboardView = [[SoftKeyboard alloc] initWithFrame:CGRectZero];
[_keyboardView setInputDelegate:self];
@@ -770,67 +328,6 @@ uint getSizeNextPOT(uint size) {
[self showKeyboard];
}
- GLfloat adjustedWidth = _videoContext.screenWidth;
- GLfloat adjustedHeight = _videoContext.screenHeight;
- if (_videoContext.asprectRatioCorrection) {
- if (_videoContext.screenWidth == 320 && _videoContext.screenHeight == 200)
- adjustedHeight = 240;
- else if (_videoContext.screenWidth == 640 && _videoContext.screenHeight == 400)
- adjustedHeight = 480;
- }
-
- float overlayPortraitRatio;
-
- if (isLandscape) {
- GLfloat gameScreenRatio = adjustedWidth / adjustedHeight;
- GLfloat screenRatio = (GLfloat)screenWidth / (GLfloat)screenHeight;
-
- // These are the width/height according to the portrait layout!
- int rectWidth, rectHeight;
- int xOffset, yOffset;
-
- if (gameScreenRatio < screenRatio) {
- // When the game screen ratio is less than the screen ratio
- // we need to scale the width, since the game screen was higher
- // compared to the width than our output screen is.
- rectWidth = (int)(screenHeight * gameScreenRatio);
- rectHeight = screenHeight;
- xOffset = (screenWidth - rectWidth) / 2;
- yOffset = 0;
- } else {
- // When the game screen ratio is bigger than the screen ratio
- // we need to scale the height, since the game screen was wider
- // compared to the height than our output screen is.
- rectWidth = screenWidth;
- rectHeight = (int)(screenWidth / gameScreenRatio);
- xOffset = 0;
- yOffset = (screenHeight - rectHeight) / 2;
- }
-
- //printf("Rect: %i, %i, %i, %i\n", xOffset, yOffset, rectWidth, rectHeight);
- _gameScreenRect = CGRectMake(xOffset, yOffset, rectWidth, rectHeight);
- overlayPortraitRatio = 1.0f;
- } else {
- GLfloat ratio = adjustedHeight / adjustedWidth;
- int height = (int)(screenWidth * ratio);
- //printf("Making rect (%u, %u)\n", screenWidth, height);
-
- _gameScreenRect = CGRectMake(0, 0, screenWidth, height);
-
- overlayPortraitRatio = (_videoContext.overlayHeight * ratio) / _videoContext.overlayWidth;
- }
- _overlayRect = CGRectMake(0, 0, screenWidth, screenHeight * overlayPortraitRatio);
-
- _gameScreenCoords[0].x = _gameScreenCoords[2].x = CGRectGetMinX(_gameScreenRect);
- _gameScreenCoords[0].y = _gameScreenCoords[1].y = CGRectGetMinY(_gameScreenRect);
- _gameScreenCoords[1].x = _gameScreenCoords[3].x = CGRectGetMaxX(_gameScreenRect);
- _gameScreenCoords[2].y = _gameScreenCoords[3].y = CGRectGetMaxY(_gameScreenRect);
-
- _overlayCoords[1].x = _overlayCoords[3].x = CGRectGetMaxX(_overlayRect);
- _overlayCoords[2].y = _overlayCoords[3].y = CGRectGetMaxY(_overlayRect);
-
- [self setViewTransformation];
- [self updateMouseCursorScaling];
[self adjustViewFrameForSafeArea];
}
@@ -878,26 +375,6 @@ uint getSizeNextPOT(uint size) {
}
#endif
-- (void)setViewTransformation {
- // Scale the shake offset according to the overlay size. We need this to
- // adjust the overlay mouse click coordinates when an offset is set.
- _scaledShakeXOffset = (int)(_videoContext.shakeXOffset / (GLfloat)_videoContext.screenWidth * CGRectGetWidth(_overlayRect));
- _scaledShakeYOffset = (int)(_videoContext.shakeYOffset / (GLfloat)_videoContext.screenHeight * CGRectGetHeight(_overlayRect));
-
- glUniform1f(_shakeXSlot, _scaledShakeXOffset);
- glUniform1f(_shakeYSlot, _scaledShakeYOffset);
-}
-
-- (void)clearColorBuffer {
- // The color buffer is triple-buffered, so we clear it multiple times right away to avid doing any glClears later.
- int clearCount = 5;
- while (clearCount-- > 0) {
- glClear(GL_COLOR_BUFFER_BIT); printOpenGLError();
- [_mainContext presentRenderbuffer:GL_RENDERBUFFER];
- glFinish();
- }
-}
-
- (void)addEvent:(InternalEvent)event {
[_eventLock lock];
_events.push_back(event);
@@ -917,56 +394,6 @@ uint getSizeNextPOT(uint size) {
return true;
}
-- (void)getMouseScaleFactorX:(CGFloat *)x andY:(CGFloat *)y {
- if (_videoContext.overlayInGUI) {
- // No scaling in overlay
- *x = (CGFloat)_videoContext.overlayWidth / self.bounds.size.width;
- *y = (CGFloat)_videoContext.overlayHeight / self.bounds.size.height;
- } else {
- *x = (CGFloat)_videoContext.screenWidth / self.bounds.size.width;
- *y = (CGFloat)_videoContext.screenHeight / self.bounds.size.height;
- }
-}
-
-- (bool)getMouseCoords:(CGPoint)point eventX:(int *)x eventY:(int *)y {
- // We scale the input according to our scale factor to get actual screen
- // coordinates.
- point.x *= self.contentScaleFactor;
- point.y *= self.contentScaleFactor;
-
- CGRect *area;
- int width, height, offsetX, offsetY;
- if (_videoContext.overlayInGUI) {
- area = &_overlayRect;
- width = _videoContext.overlayWidth;
- height = _videoContext.overlayHeight;
- offsetX = _scaledShakeXOffset;
- offsetY = _scaledShakeYOffset;
- } else {
- area = &_gameScreenRect;
- width = _videoContext.screenWidth;
- height = _videoContext.screenHeight;
- offsetX = _videoContext.shakeXOffset;
- offsetY = _videoContext.shakeYOffset;
- }
-
- point.x = (point.x - CGRectGetMinX(*area)) / CGRectGetWidth(*area);
- point.y = (point.y - CGRectGetMinY(*area)) / CGRectGetHeight(*area);
-
- *x = (int)(point.x * width + offsetX);
- // offsetY describes the translation of the screen in the upward direction,
- // thus we need to add it here.
- *y = (int)(point.y * height + offsetY);
-
- if (!iOS7_touchpadModeEnabled()) {
- // Clip coordinates
- if (*x < 0 || *x > width || *y < 0 || *y > height)
- return false;
- }
-
- return true;
-}
-
- (BOOL)isControllerTypeConnected:(Class)controller {
for (GameController *c : _controllers) {
if ([c isConnected]) {
diff --git a/configure b/configure
index 8ae3bd09a42..758ce398b7b 100755
--- a/configure
+++ b/configure
@@ -4002,7 +4002,7 @@ case $_backend in
append_var LIBS "-lobjc -framework UIKit -framework CoreGraphics -framework OpenGLES"
append_var LIBS "-framework QuartzCore -framework CoreFoundation -framework Foundation"
append_var LIBS "-framework AudioToolbox -framework CoreAudio -framework SystemConfiguration "
- append_var LIBS "-framework GameController -framework Accelerate"
+ append_var LIBS "-framework GameController"
if test "$_host" = 'tvos'; then
append_var LDFLAGS "-mtvos-version-min=9 -arch arm64"
append_var CFLAGS "-mtvos-version-min=9 -arch arm64"
diff --git a/devtools/create_project/xcode.cpp b/devtools/create_project/xcode.cpp
index 59d75789fe4..5b51d154979 100644
--- a/devtools/create_project/xcode.cpp
+++ b/devtools/create_project/xcode.cpp
@@ -467,7 +467,6 @@ void XcodeProvider::setupFrameworksBuildPhase(const BuildSetup &setup) {
std::map<std::string, FileProperty> properties;
int fwOrder = 0;
// Frameworks
- DEF_SYSFRAMEWORK("Accelerate");
DEF_SYSFRAMEWORK("ApplicationServices");
DEF_SYSFRAMEWORK("AudioToolbox");
DEF_SYSFRAMEWORK("AudioUnit");
@@ -624,7 +623,6 @@ void XcodeProvider::setupFrameworksBuildPhase(const BuildSetup &setup) {
frameworks_iOS.push_back("AudioToolbox.framework");
frameworks_iOS.push_back("QuartzCore.framework");
frameworks_iOS.push_back("OpenGLES.framework");
- frameworks_iOS.push_back("Accelerate.framework");
if (CONTAINS_DEFINE(setup.defines, "USE_FAAD")) {
frameworks_iOS.push_back(getLibString("faad", setup.useXCFramework));
@@ -853,7 +851,6 @@ void XcodeProvider::setupFrameworksBuildPhase(const BuildSetup &setup) {
frameworks_tvOS.push_back("AudioToolbox.framework");
frameworks_tvOS.push_back("QuartzCore.framework");
frameworks_tvOS.push_back("OpenGLES.framework");
- frameworks_tvOS.push_back("Accelerate.framework");
if (CONTAINS_DEFINE(setup.defines, "USE_FAAD")) {
frameworks_tvOS.push_back(getLibString("faad", setup.useXCFramework));
diff --git a/ports.mk b/ports.mk
index d9486112ccc..ac6b486eafe 100644
--- a/ports.mk
+++ b/ports.mk
@@ -539,7 +539,7 @@ scummvm-static-ios: $(DETECT_OBJS) $(OBJS)
+$(LD) $(LDFLAGS) -o scummvm $(DETECT_OBJS) $(OBJS) \
$(OSX_STATIC_LIBS) \
-framework UIKit -framework CoreGraphics -framework OpenGLES -framework GameController \
- -framework CoreFoundation -framework QuartzCore -framework Foundation -framework Accelerate \
+ -framework CoreFoundation -framework QuartzCore -framework Foundation \
-framework AudioToolbox -framework CoreAudio -framework SystemConfiguration -lobjc -lz
# Special target to create a snapshot disk image for macOS
Commit: 6a74f7b32b147a9352a56b20c00277cd8257fa12
https://github.com/scummvm/scummvm/commit/6a74f7b32b147a9352a56b20c00277cd8257fa12
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-07-03T21:50:32+02:00
Commit Message:
IOS7: Implement iOSGraphics3dManager
Add a graphic manager rendering 3D graphics for engines supporting
3D games. The manager is implemented using the 3D graphic managers
for Android and SDL as models.
Most probably Android and iOS can share much more of the code, but
that will be a separate work to refactor.
The iOSGraphics3dManager handles resize since the screen dimension
changes on rotation.
Games not supporting arbitary resolutions, e.g. Grim, are rendered
on an intermediate framebuffer with the size requested by the
engine and then rendered to the backbuffer (a framebuffer bound to
the renderbuffer) and stretched to the screen resolution off the
device.
This commit just adds the manager. It will be utilised in next
commit.
Update gitlab ci worker and update documentation.
Changed paths:
A backends/graphics3d/ios/ios-graphics3d.cpp
A backends/graphics3d/ios/ios-graphics3d.h
.github/workflows/ci.yml
backends/module.mk
doc/docportal/other_platforms/ios.rst
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 22bb6bd4490..5cbeb092d34 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -105,7 +105,7 @@ jobs:
brewPackages: a52dec faad2 flac fluid-synth freetype fribidi giflib jpeg mad libmikmod libmpeg2 libogg libpng libvorbis libvpx sdl2 sdl2_net theora
- platform: ios7
buildFlags: -scheme ScummVM-iOS CODE_SIGN_IDENTITY="" CODE_SIGNING_ALLOWED=NO
- configFlags: --use-xcframework --enable-faad --enable-gif --enable-mikmod --enable-mpeg2 --enable-vpx --disable-nasm --disable-opengl_game_classic --disable-taskbar --disable-tts
+ configFlags: --use-xcframework --enable-faad --enable-gif --enable-mikmod --enable-mpeg2 --enable-vpx --disable-nasm --disable-taskbar --disable-tts
packagesUrl: https://downloads.scummvm.org/frs/build/scummvm-ios7-libs-v3.zip
env:
BUILDCACHE_MAX_CACHE_SIZE: 2000000000
diff --git a/backends/graphics3d/ios/ios-graphics3d.cpp b/backends/graphics3d/ios/ios-graphics3d.cpp
new file mode 100644
index 00000000000..84d1f21de5a
--- /dev/null
+++ b/backends/graphics3d/ios/ios-graphics3d.cpp
@@ -0,0 +1,494 @@
+/* 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 3 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "common/scummsys.h"
+
+#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+
+#include "backends/graphics3d/ios/ios-graphics3d.h"
+#include "backends/platform/ios7/ios7_osys_main.h"
+#include "graphics/opengl/context.h"
+#include "backends/graphics3d/opengl/texture.h"
+#include "graphics/blit.h"
+#include "common/translation.h"
+
+#include "engines/engine.h"
+
+iOSGraphics3dManager::iOSGraphics3dManager() :
+ _screenChangeCount(0),
+ _stretchMode(STRETCH_FIT),
+ _mouseDontScale(false),
+ _aspectRatioCorrection(true),
+ _overlayScreen(nullptr),
+ _overlayBackground(nullptr),
+ _mouseSurface(nullptr),
+ _surfaceRenderer(nullptr),
+ _frameBuffer(nullptr),
+ _glFBO(0) {
+
+ ConfMan.registerDefault("aspect_ratio", true);
+
+ memset(_glRBOs, 0, sizeof(_glRBOs));
+
+ initSurface();
+}
+
+iOSGraphics3dManager::~iOSGraphics3dManager() {
+ delete _overlayScreen;
+ delete _overlayBackground;
+ delete _mouseSurface;
+ delete _surfaceRenderer;
+ delete _frameBuffer;
+}
+
+void iOSGraphics3dManager::initSurface() {
+ OSystem_iOS7 *sys = dynamic_cast<OSystem_iOS7 *>(g_system);
+
+ // Create OpenGL context if not existing
+ GLuint glRBO = sys->createOpenGLContext();
+
+ OpenGLContext.initialize(OpenGL::kContextGLES2);
+
+ // Create the framebuffer attached to ObjC provided RBO
+ glGenFramebuffers(1, &_glFBO);
+ glBindFramebuffer(GL_FRAMEBUFFER, _glFBO);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, glRBO);
+
+ // Attach a depth and stencil buffer
+ createDepthAndStencilBuffer(sys->getScreenWidth(), sys->getScreenHeight());
+
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE)
+ error("Framebuffer is not complete! status: %d", status);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ //initSize will be called to set the size
+}
+
+void iOSGraphics3dManager::deinitSurface() {
+ glDeleteFramebuffers(1, &_glFBO);
+ glDeleteRenderbuffers(2, _glRBOs);
+
+ OpenGLContext.destroy();
+ dynamic_cast<OSystem_iOS7 *>(g_system)->destroyOpenGLContext();
+}
+
+void iOSGraphics3dManager::createDepthAndStencilBuffer(int width, int height) {
+ glGenRenderbuffers(2, _glRBOs);
+ glBindRenderbuffer(GL_RENDERBUFFER, _glRBOs[0]);
+
+ if (OpenGLContext.packedDepthStencilSupported) {
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _glRBOs[0]);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _glRBOs[0]);
+ } else {
+ glRenderbufferStorage(GL_RENDERBUFFER, OpenGLContext.OESDepth24 ? GL_DEPTH_COMPONENT24 : GL_DEPTH_COMPONENT16,
+ width, height);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _glRBOs[0]);
+
+ glBindRenderbuffer(GL_RENDERBUFFER, _glRBOs[1]);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8,
+ width, height);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _glRBOs[1]);
+ }
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
+}
+
+void iOSGraphics3dManager::updateDepthAndStencilBuffer(int width, int height) {
+ glBindRenderbuffer(GL_RENDERBUFFER, _glRBOs[0]);
+ if (OpenGLContext.packedDepthStencilSupported) {
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
+ } else {
+ glRenderbufferStorage(GL_RENDERBUFFER, OpenGLContext.OESDepth24 ? GL_DEPTH_COMPONENT24 : GL_DEPTH_COMPONENT16,
+ width, height);
+ glBindRenderbuffer(GL_RENDERBUFFER, _glRBOs[1]);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8,
+ width, height);
+ }
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
+}
+
+void iOSGraphics3dManager::notifyResize(const int width, const int height) {
+ updateDepthAndStencilBuffer(width, height);
+ handleResize(width, height);
+}
+
+iOSCommonGraphics::State iOSGraphics3dManager::getState() const {
+ State state;
+
+ state.screenWidth = getWidth();
+ state.screenHeight = getHeight();
+ state.aspectRatio = getFeatureState(OSystem::kFeatureAspectRatioCorrection);
+ state.cursorPalette = getFeatureState(OSystem::kFeatureCursorPalette);
+#ifdef USE_RGB_COLOR
+ state.pixelFormat = getScreenFormat();
+#endif
+ return state;
+}
+
+bool iOSGraphics3dManager::setState(const iOSCommonGraphics::State &state) {
+ initSize(state.screenWidth, state.screenHeight, nullptr);
+ setFeatureState(OSystem::kFeatureAspectRatioCorrection, state.aspectRatio);
+ setFeatureState(OSystem::kFeatureCursorPalette, state.cursorPalette);
+
+ return true;
+}
+
+bool iOSGraphics3dManager::gameNeedsAspectRatioCorrection() const {
+ if (_aspectRatioCorrection) {
+ const uint width = getWidth();
+ const uint height = getHeight();
+ // In case we enable aspect ratio correction we force a 4/3 ratio.
+ // But just for 320x200 and 640x400 games, since other games do not need
+ // this.
+ return (width == 320 && height == 200) || (width == 640 && height == 400);
+ }
+ return false;
+}
+
+bool iOSGraphics3dManager::hasFeature(OSystem::Feature f) const {
+ if ((f == OSystem::kFeatureOpenGLForGame) ||
+ (f == OSystem::kFeatureAspectRatioCorrection) ||
+ (f == OSystem::kFeatureStretchMode) ||
+ (f == OSystem::kFeatureOverlaySupportsAlpha && _overlayFormat.aBits() > 3)) {
+ return true;
+ }
+ return false;
+}
+
+bool iOSGraphics3dManager::getFeatureState(OSystem::Feature f) const {
+ switch (f) {
+ case OSystem::kFeatureAspectRatioCorrection:
+ return _aspectRatioCorrection;
+ default:
+ return false;
+ }
+}
+
+void iOSGraphics3dManager::setFeatureState(OSystem::Feature f, bool enable) {
+ switch (f) {
+ case OSystem::kFeatureAspectRatioCorrection:
+ _aspectRatioCorrection = enable;
+ break;
+ default:
+ break;
+ }
+}
+
+const OSystem::GraphicsMode *iOSGraphics3dManager::getSupportedGraphicsModes() const {
+ static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
+ { "default", "Default", 0 },
+ { 0, 0, 0 },
+ };
+
+ return s_supportedGraphicsModes;
+}
+
+int iOSGraphics3dManager::getDefaultGraphicsMode() const {
+ return 0;
+}
+
+bool iOSGraphics3dManager::setGraphicsMode(int mode, uint flags) {
+ assert(flags & OSystem::kGfxModeRender3d);
+ return true;
+}
+
+int iOSGraphics3dManager::getGraphicsMode() const {
+ return 0;
+}
+
+void iOSGraphics3dManager::initSize(uint w, uint h, const Graphics::PixelFormat *format) {
+ OSystem_iOS7 *sys = dynamic_cast<OSystem_iOS7 *>(g_system);
+
+ bool engineSupportsArbitraryResolutions = !g_engine ||
+ g_engine->hasFeature(Engine::kSupportsArbitraryResolutions);
+ if (!engineSupportsArbitraryResolutions) {
+ // If the game can't adapt to any resolution, render it to a framebuffer
+ // so it can be scaled to fill the available space.
+ _frameBuffer = new OpenGL::FrameBuffer(w, h);
+ _frameBuffer->attach();
+ }
+
+ _surfaceRenderer = OpenGL::createBestSurfaceRenderer();
+ _overlayFormat = OpenGL::TextureGL::getRGBAPixelFormat();
+
+ handleResize(sys->getScreenWidth(), sys->getScreenHeight());
+}
+
+int16 iOSGraphics3dManager::getHeight() const {
+ if (_frameBuffer)
+ return _frameBuffer->getHeight();
+ else
+ return _overlayScreen->getHeight();
+}
+
+int16 iOSGraphics3dManager::getWidth() const {
+ if (_frameBuffer)
+ return _frameBuffer->getWidth();
+ else
+ return _overlayScreen->getWidth();
+}
+
+float iOSGraphics3dManager::getHiDPIScreenFactor() const {
+ return dynamic_cast<OSystem_iOS7 *>(g_system)->getSystemHiDPIScreenFactor();
+}
+
+void iOSGraphics3dManager::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format, const byte *mask) {
+
+ if (w == 0 || h == 0)
+ return;
+
+ const Graphics::PixelFormat pixelFormat = format ? *format : Graphics::PixelFormat::createFormatCLUT8();
+
+ if (_mouseSurface == nullptr)
+ _mouseSurface = new OpenGL::TiledSurface(w, h, pixelFormat);
+
+ _mouseHotspot = Common::Point(hotspotX, hotspotY);
+ _mouseDontScale = dontScale;
+
+ _mouseSurface->copyRectToSurface(buf, _mouseSurface->getBackingSurface()->pitch, hotspotX, hotspotY, w, h);
+
+ updateCursorScaling();
+}
+
+void iOSGraphics3dManager::handleResizeImpl(const int width, const int height) {
+ // Update the overlay
+ delete _overlayScreen;
+ _overlayScreen = new OpenGL::TiledSurface(width, height, _overlayFormat);
+
+ delete _mouseSurface;
+ _mouseSurface = nullptr;
+
+ // Clear the overlay background so it is not displayed distorted while resizing
+ delete _overlayBackground;
+ _overlayBackground = nullptr;
+
+ // Re-setup the scaling for the screen
+ recalculateDisplayAreas();
+
+ // Something changed, so update the screen change ID.
+ _screenChangeCount++;
+}
+
+void iOSGraphics3dManager::updateScreen() {
+ GLint prevStateViewport[4];
+ glGetIntegerv(GL_VIEWPORT, prevStateViewport);
+
+ // Make sure our framebuffer is still bound
+ glBindFramebuffer(GL_FRAMEBUFFER, _glFBO);
+
+ if (_frameBuffer) {
+ _surfaceRenderer->prepareState();
+ glViewport(_gameDrawRect.left, _windowHeight - _gameDrawRect.top - _gameDrawRect.height(), _gameDrawRect.width(), _gameDrawRect.height());
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ _surfaceRenderer->render(_frameBuffer, Math::Rect2d(Math::Vector2d(0, 0), Math::Vector2d(1, 1)));
+ _surfaceRenderer->restorePreviousState();
+ }
+
+ if (_overlayVisible) {
+ _overlayScreen->update();
+
+ // If the overlay is in game we expect the game to continue calling OpenGL
+ if (_overlayBackground && _overlayInGUI) {
+ _overlayBackground->update();
+ }
+
+ if (_cursorVisible && _mouseSurface) {
+ _mouseSurface->update();
+ }
+
+ _surfaceRenderer->prepareState();
+
+ glViewport(_overlayDrawRect.left, _windowHeight - _overlayDrawRect.top - _overlayDrawRect.height(), getOverlayWidth(), getOverlayHeight());
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ if (_overlayBackground) {
+ _overlayBackground->draw(_surfaceRenderer);
+ }
+
+ _surfaceRenderer->enableAlphaBlending(true);
+ _surfaceRenderer->setFlipY(true);
+
+ _overlayScreen->draw(_surfaceRenderer);
+
+ if (_cursorVisible && _mouseSurface) {
+ glViewport(_cursorX - _mouseHotspotScaled.x, _overlayScreen->getHeight() - _cursorY - _mouseHeightScaled - _mouseHotspotScaled.y, _mouseWidthScaled, _mouseHeightScaled);
+ _mouseSurface->draw(_surfaceRenderer);
+ }
+ _surfaceRenderer->restorePreviousState();
+ }
+
+ if (_frameBuffer) {
+ _frameBuffer->attach();
+ }
+
+ dynamic_cast<OSystem_iOS7 *>(g_system)->refreshScreen();
+ glViewport(prevStateViewport[0], prevStateViewport[1], prevStateViewport[2], prevStateViewport[3]);
+}
+
+const OSystem::GraphicsMode glStretchModes[] = {
+ {"center", _s("Center"), STRETCH_CENTER},
+ {"pixel-perfect", _s("Pixel-perfect scaling"), STRETCH_INTEGRAL},
+ {"even-pixels", _s("Even pixels scaling"), STRETCH_INTEGRAL_AR},
+ {"fit", _s("Fit to window"), STRETCH_FIT},
+ {"stretch", _s("Stretch to window"), STRETCH_STRETCH},
+ {"fit_force_aspect", _s("Fit to window (4:3)"), STRETCH_FIT_FORCE_ASPECT},
+ {nullptr, nullptr, 0}
+};
+
+const OSystem::GraphicsMode *iOSGraphics3dManager::getSupportedStretchModes() const {
+ return glStretchModes;
+}
+
+int iOSGraphics3dManager::getDefaultStretchMode() const {
+ return STRETCH_FIT;
+}
+
+bool iOSGraphics3dManager::setStretchMode(int mode) {
+ if (mode == _stretchMode)
+ return true;
+
+ // Check this is a valid mode
+ const OSystem::GraphicsMode *sm = getSupportedStretchModes();
+ bool found = false;
+ while (sm->name) {
+ if (sm->id == mode) {
+ found = true;
+ break;
+ }
+ sm++;
+ }
+ if (!found) {
+ warning("unknown stretch mode %d", mode);
+ return false;
+ }
+
+ _stretchMode = mode;
+ return true;
+}
+
+int iOSGraphics3dManager::getStretchMode() const {
+ return _stretchMode;
+}
+
+void iOSGraphics3dManager::clearOverlay() {
+ _overlayScreen->fill(0);
+}
+
+void iOSGraphics3dManager::grabOverlay(Graphics::Surface &surface) const {
+ const Graphics::Surface *overlayData = _overlayScreen->getBackingSurface();
+
+ assert(surface.w >= overlayData->w);
+ assert(surface.h >= overlayData->h);
+ assert(surface.format.bytesPerPixel == overlayData->format.bytesPerPixel);
+
+ const byte *src = (const byte *)overlayData->getPixels();
+ byte *dst = (byte *)surface.getPixels();
+ Graphics::copyBlit(dst, src, surface.pitch, overlayData->pitch, overlayData->w, overlayData->h, overlayData->format.bytesPerPixel);
+}
+
+void iOSGraphics3dManager::copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) {
+ _overlayScreen->copyRectToSurface(buf, pitch, x, y, w, h);
+}
+
+int16 iOSGraphics3dManager::getOverlayHeight() const {
+ return _overlayScreen->getHeight();
+}
+
+int16 iOSGraphics3dManager::getOverlayWidth() const {
+ return _overlayScreen->getWidth();
+}
+
+void iOSGraphics3dManager::showOverlay(bool inGUI) {
+ if (_overlayVisible && _overlayInGUI == inGUI) {
+ return;
+ }
+
+ WindowedGraphicsManager::showOverlay(inGUI);
+
+ delete _overlayBackground;
+ _overlayBackground = nullptr;
+
+ if (g_engine) {
+ if (_frameBuffer)
+ _frameBuffer->detach();
+
+ // If there is a game running capture the screen, so that it can be shown "below" the overlay.
+ _overlayBackground = new OpenGL::TiledSurface(_overlayScreen->getWidth(), _overlayScreen->getHeight(), _overlayFormat);
+ Graphics::Surface *background = _overlayBackground->getBackingSurface();
+ glReadPixels(0, 0, background->w, background->h, GL_RGBA, GL_UNSIGNED_BYTE, background->getPixels());
+
+ if (_frameBuffer)
+ _frameBuffer->attach();
+ }
+}
+
+void iOSGraphics3dManager::hideOverlay() {
+ if (!_overlayVisible) {
+ return;
+ }
+ WindowedGraphicsManager::hideOverlay();
+
+ delete _overlayBackground;
+ _overlayBackground = nullptr;
+}
+
+bool iOSGraphics3dManager::showMouse(bool visible) {
+ return WindowedGraphicsManager::showMouse(visible);
+}
+
+bool iOSGraphics3dManager::notifyMousePosition(Common::Point &mouse) {
+ mouse.x = CLIP<int16>(mouse.x, _activeArea.drawRect.left, _activeArea.drawRect.right);
+ mouse.y = CLIP<int16>(mouse.y, _activeArea.drawRect.top, _activeArea.drawRect.bottom);
+
+ setMousePosition(mouse.x, mouse.y);
+ mouse = convertWindowToVirtual(mouse.x, mouse.y);
+
+ return true;
+}
+
+void iOSGraphics3dManager::updateCursorScaling() {
+ // By default we use the unscaled versions.
+ _mouseHotspotScaled = _mouseHotspot;
+ _mouseWidthScaled = _mouseSurface->getWidth();
+ _mouseHeightScaled = _mouseSurface->getHeight();
+
+ // In case scaling is actually enabled we will scale the cursor according
+ // to the game screen.
+ uint16 w = getWidth();
+ uint16 h = getHeight();
+
+ if (!_mouseDontScale && w && h) {
+ const frac_t screen_scale_factor_x = intToFrac(_gameDrawRect.width()) / w;
+ const frac_t screen_scale_factor_y = intToFrac(_gameDrawRect.height()) / h;
+
+ _mouseHotspotScaled = Common::Point(
+ fracToInt(_mouseHotspotScaled.x * screen_scale_factor_x),
+ fracToInt(_mouseHotspotScaled.y * screen_scale_factor_y));
+
+ _mouseWidthScaled = fracToInt(_mouseWidthScaled * screen_scale_factor_x);
+ _mouseHeightScaled = fracToInt(_mouseHeightScaled * screen_scale_factor_y);
+ }
+}
+
+#endif
diff --git a/backends/graphics3d/ios/ios-graphics3d.h b/backends/graphics3d/ios/ios-graphics3d.h
new file mode 100644
index 00000000000..2b323bbe034
--- /dev/null
+++ b/backends/graphics3d/ios/ios-graphics3d.h
@@ -0,0 +1,147 @@
+/* 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 3 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef BACKENDS_GRAPHICS3D_IOS_IOS_GRAPHICS3D_H
+#define BACKENDS_GRAPHICS3D_IOS_IOS_GRAPHICS3D_H
+
+#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+
+#include "common/scummsys.h"
+
+#include "backends/graphics/windowed.h"
+#include "backends/graphics/ios/ios-graphics.h"
+#include "backends/graphics3d/opengl/framebuffer.h"
+#include "backends/graphics3d/opengl/tiledsurface.h"
+#include "backends/graphics3d/opengl/surfacerenderer.h"
+
+class iOSGraphics3dManager : virtual public WindowedGraphicsManager, public iOSCommonGraphics {
+public:
+ iOSGraphics3dManager();
+ virtual ~iOSGraphics3dManager();
+
+ //WindowedGraphicsManager
+ bool gameNeedsAspectRatioCorrection() const override;
+ void handleResizeImpl(const int width, const int height) override;
+ virtual void setSystemMousePosition(const int x, const int y) override {};
+
+ //iOSCommonGraphics
+ void initSurface() override;
+ void deinitSurface() override;
+
+ void notifyResize(const int width, const int height) override;
+
+ virtual iOSCommonGraphics::State getState() const override;
+ virtual bool setState(const iOSCommonGraphics::State &state) override;
+
+ bool notifyMousePosition(Common::Point &mouse) override;
+ Common::Point getMousePosition() override { return Common::Point(_cursorX, _cursorY); }
+
+ // GraphicsManager API - Features
+ bool hasFeature(OSystem::Feature f) const override;
+ bool getFeatureState(OSystem::Feature f) const override;
+ void setFeatureState(OSystem::Feature f, bool enable) override;
+
+ const OSystem::GraphicsMode *getSupportedGraphicsModes() const override;
+ int getDefaultGraphicsMode() const override;
+ bool setGraphicsMode(int mode, uint flags = OSystem::kGfxModeNoFlags) override;
+ int getGraphicsMode() const override;
+
+ void beginGFXTransaction() override {}
+ OSystem::TransactionError endGFXTransaction() override {
+ return OSystem::kTransactionSuccess;
+ }
+
+ // GraphicsManager API - Graphics mode
+#ifdef USE_RGB_COLOR
+ Graphics::PixelFormat getScreenFormat() const override { return _overlayFormat; }
+ Common::List<Graphics::PixelFormat> getSupportedFormats() const override {
+ Common::List<Graphics::PixelFormat> supportedFormats;
+ return supportedFormats;
+ }
+#endif
+ int getScreenChangeID() const override { return _screenChangeCount; }
+ void initSize(uint w, uint h, const Graphics::PixelFormat *format) override;
+ int16 getHeight() const override;
+ int16 getWidth() const override;
+
+ float getHiDPIScreenFactor() const override;
+
+ // GraphicsManager API - Draw methods
+ void updateScreen() override;
+ // Following methods are not used by 3D graphics managers
+ void setPalette(const byte *colors, uint start, uint num) override {}
+ void grabPalette(byte *colors, uint start, uint num) const override {}
+ void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) override {}
+ Graphics::Surface *lockScreen() override { return nullptr; }
+ void unlockScreen() override {}
+ void fillScreen(uint32 col) override {}
+ void setShakePos(int shakeXOffset, int shakeYOffset) override {};
+ void setFocusRectangle(const Common::Rect& rect) override {}
+ void clearFocusRectangle() override {}
+
+ // GraphicsManager API - Overlay
+ const OSystem::GraphicsMode *getSupportedStretchModes() const override;
+ int getDefaultStretchMode() const override;
+ bool setStretchMode(int mode) override;
+ int getStretchMode() const override;
+ void showOverlay(bool inGUI) override;
+ void hideOverlay() override;
+ Graphics::PixelFormat getOverlayFormat() const override { return _overlayFormat; }
+ void clearOverlay() override;
+ void grabOverlay(Graphics::Surface &surface) const override;
+ void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override;
+ int16 getOverlayWidth() const override;
+ int16 getOverlayHeight() const override;
+
+ // GraphicsManager API - Mouse
+ bool showMouse(bool visible) override;
+ void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL, const byte *mask = NULL) override;
+ void setCursorPalette(const byte *colors, uint start, uint num) override {}
+
+protected:
+ void updateCursorScaling();
+ void createDepthAndStencilBuffer(int width, int height);
+ void updateDepthAndStencilBuffer(int width, int height);
+
+ int _screenChangeCount;
+ int _stretchMode;
+ bool _aspectRatioCorrection;
+ bool _mouseDontScale;
+ Common::Point _mouseHotspot;
+ Common::Point _mouseHotspotScaled;
+ int _mouseWidthScaled, _mouseHeightScaled;
+
+ Graphics::PixelFormat _overlayFormat;
+ OpenGL::TiledSurface *_overlayScreen;
+ OpenGL::TiledSurface *_overlayBackground;
+ OpenGL::TiledSurface *_mouseSurface;
+ OpenGL::SurfaceRenderer *_surfaceRenderer;
+
+ // FBO used to render games not supporting arbitary resolutions
+ OpenGL::FrameBuffer *_frameBuffer;
+ // FBO used as a backbuffer for Apple API
+ GLuint _glFBO;
+ // RBOs used for depth and stencil buffer only
+ GLuint _glRBOs[2];
+};
+
+#endif
+#endif
diff --git a/backends/module.mk b/backends/module.mk
index 72dddcc0b32..3f16068855c 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -389,7 +389,11 @@ ifdef IPHONE
MODULE_OBJS += \
mutex/pthread/pthread-mutex.o \
graphics/ios/ios-graphics.o \
- graphics/ios/renderbuffer.o
+ graphics/ios/renderbuffer.o \
+ graphics3d/ios/ios-graphics3d.o \
+ graphics3d/opengl/surfacerenderer.o \
+ graphics3d/opengl/texture.o \
+ graphics3d/opengl/tiledsurface.o
endif
ifeq ($(BACKEND),maemo)
diff --git a/doc/docportal/other_platforms/ios.rst b/doc/docportal/other_platforms/ios.rst
index 6aa4ea864a9..65e4e45989d 100644
--- a/doc/docportal/other_platforms/ios.rst
+++ b/doc/docportal/other_platforms/ios.rst
@@ -76,7 +76,7 @@ It's time to generate the Xcode project. Run the following on the command line:
.. code::
- ../scummvm/devtools/create_project/xcode/build/Release/create_project ../scummvm --xcode --use-xcframework --enable-faad --enable-fluidsynth --enable-gif --enable-mikmod --enable-mpeg2 --enable-vpx --disable-nasm --disable-opengl_game_classic --disable-taskbar --disable-tts
+ ../scummvm/devtools/create_project/xcode/build/Release/create_project ../scummvm --xcode --use-xcframework --enable-faad --enable-fluidsynth --enable-gif --enable-mikmod --enable-mpeg2 --enable-vpx --disable-nasm --disable-taskbar --disable-tts
The resulting directory structure looks like this:
Commit: b324c7074814bec43c4eb01259b2c83d6e470f00
https://github.com/scummvm/scummvm/commit/b324c7074814bec43c4eb01259b2c83d6e470f00
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-07-03T21:50:32+02:00
Commit Message:
IOS7: Implement switching of 2D/3D graphics managers
Implement the same "hacky" way to switch between the 2D and 3D
iOSGraphicsManagers as the Android and SDL backends.
This commit enables 3D capable games to utilise the horse powers
in the GPU to render graohic. Older iPhones and iPads (iPhone 6,
iPad Mini v1) are able to run quite advanced games without any
stuttering if run in Release mode.
Changed paths:
backends/platform/ios7/ios7_osys_main.cpp
backends/platform/ios7/ios7_osys_main.h
diff --git a/backends/platform/ios7/ios7_osys_main.cpp b/backends/platform/ios7/ios7_osys_main.cpp
index d222d1e2277..d4163e2e5e9 100644
--- a/backends/platform/ios7/ios7_osys_main.cpp
+++ b/backends/platform/ios7/ios7_osys_main.cpp
@@ -42,9 +42,11 @@
#include "engines/engine.h"
#include "engines/metaengine.h"
+#include "graphics/cursorman.h"
#include "gui/gui-manager.h"
#include "backends/graphics/ios/ios-graphics.h"
+#include "backends/graphics3d/ios/ios-graphics3d.h"
#include "backends/saves/default/default-saves.h"
#include "backends/timer/default/default-timer.h"
#include "backends/mutex/pthread/pthread-mutex.h"
@@ -153,6 +155,8 @@ bool OSystem_iOS7::hasFeature(Feature f) {
case kFeatureOpenUrl:
case kFeatureNoQuit:
case kFeatureKbdMouseSpeed:
+ case kFeatureOpenGLForGame:
+ case kFeatureShadersForGame:
return true;
default:
@@ -182,6 +186,65 @@ bool OSystem_iOS7::getFeatureState(Feature f) {
}
}
+bool OSystem_iOS7::setGraphicsMode(int mode, uint flags) {
+ bool render3d = flags & OSystem::kGfxModeRender3d;
+
+ // Utilize the same way to switch between 2D and 3D graphics manager as
+ // in SDL based backends and Android.
+ iOSCommonGraphics *commonGraphics = dynamic_cast<iOSCommonGraphics *>(_graphicsManager);
+ iOSCommonGraphics::State gfxManagerState = commonGraphics->getState();
+
+ bool supports3D = _graphicsManager->hasFeature(kFeatureOpenGLForGame);
+ bool switchedManager = false;
+
+ // If the new mode and the current mode are not from the same graphics
+ // manager, delete and create the new mode graphics manager
+ if (render3d && !supports3D) {
+ delete _graphicsManager;
+ iOSGraphics3dManager *manager = new iOSGraphics3dManager();
+ _graphicsManager = manager;
+ commonGraphics = manager;
+ switchedManager = true;
+ } else if (!render3d && supports3D) {
+ delete _graphicsManager;
+ iOSGraphicsManager *manager = new iOSGraphicsManager();
+ _graphicsManager = manager;
+ commonGraphics = manager;
+ switchedManager = true;
+ }
+
+ if (switchedManager) {
+ // Setup the graphics mode and size first
+ // This is needed so that we can check the supported pixel formats when
+ // restoring the state.
+ _graphicsManager->beginGFXTransaction();
+ if (!_graphicsManager->setGraphicsMode(mode, flags))
+ return false;
+ _graphicsManager->initSize(gfxManagerState.screenWidth, gfxManagerState.screenHeight);
+ _graphicsManager->endGFXTransaction();
+
+ // This failing will probably have bad consequences...
+ //if (!androidGraphicsManager->setState(gfxManagerState)) {
+ // return false;
+ //}
+
+ // Next setup the cursor again
+ CursorMan.pushCursor(0, 0, 0, 0, 0, 0);
+ CursorMan.popCursor();
+
+ // Next setup cursor palette if needed
+ if (_graphicsManager->getFeatureState(kFeatureCursorPalette)) {
+ CursorMan.pushCursorPalette(0, 0, 0);
+ CursorMan.popCursorPalette();
+ }
+
+ _graphicsManager->beginGFXTransaction();
+ return true;
+ } else {
+ return _graphicsManager->setGraphicsMode(mode, flags);
+ }
+ }
+
void OSystem_iOS7::suspendLoop() {
bool done = false;
uint32 startTime = getMillis();
diff --git a/backends/platform/ios7/ios7_osys_main.h b/backends/platform/ios7/ios7_osys_main.h
index f94e052e334..34da661f311 100644
--- a/backends/platform/ios7/ios7_osys_main.h
+++ b/backends/platform/ios7/ios7_osys_main.h
@@ -97,6 +97,8 @@ public:
void setFeatureState(Feature f, bool enable) override;
bool getFeatureState(Feature f) override;
+ bool setGraphicsMode(int mode, uint flags) override;
+
bool touchpadModeEnabled() const;
uint createOpenGLContext();
@@ -109,6 +111,9 @@ public:
#if defined(USE_OPENGL) && defined(USE_GLAD)
void *getOpenGLProcAddress(const char *name) const override;
#endif
+#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
+ OpenGL::ContextType getOpenGLType() const override { return OpenGL::kContextGLES2; }
+#endif
public:
bool pollEvent(Common::Event &event) override;
Commit: 598bc231abe40dc26b09845d78bc4945cec060ba
https://github.com/scummvm/scummvm/commit/598bc231abe40dc26b09845d78bc4945cec060ba
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-07-03T21:50:32+02:00
Commit Message:
IOS7: Cancel pending button if touch is moved within 250 ms
If not in "click-and-drag" mode, left mouse button down and up
events are sent on touches ended if the touch lasted less than
250 ms. If the touch lasted longer it was considered as a move
and no button events are sent.
This commit mimic that behaviour in touchpad mode when "click-
and-drag" mode is enabled. The left mouse button down event is
queued for 250 ms. If the touch is dragged within 250 ms it is
considered as a move and the queued mouse button down event is
cacelled. If no movement is made withing 250 ms the queued
mouse button event is processed.
Changed paths:
backends/platform/ios7/ios7_osys_events.cpp
diff --git a/backends/platform/ios7/ios7_osys_events.cpp b/backends/platform/ios7/ios7_osys_events.cpp
index fd7c08d2ab3..6fafc200f94 100644
--- a/backends/platform/ios7/ios7_osys_events.cpp
+++ b/backends/platform/ios7/ios7_osys_events.cpp
@@ -192,8 +192,14 @@ bool OSystem_iOS7::handleEvent_touchFirstDown(Common::Event &event, int x, int y
}
if (_mouseClickAndDragEnabled) {
- event.type = Common::EVENT_LBUTTONDOWN;
- handleEvent_mouseEvent(event, 0, 0);
+ if (_touchpadModeEnabled) {
+ _queuedInputEvent.type = Common::EVENT_LBUTTONDOWN;
+ _queuedEventTime = getMillis() + 250;
+ handleEvent_mouseEvent(_queuedInputEvent, 0, 0);
+ } else {
+ event.type = Common::EVENT_LBUTTONDOWN;
+ handleEvent_mouseEvent(event, 0, 0);
+ }
return true;
} else {
_lastMouseDown = getMillis();
@@ -209,8 +215,16 @@ bool OSystem_iOS7::handleEvent_touchFirstUp(Common::Event &event, int x, int y)
if (!handleEvent_touchSecondUp(event, x, y))
return false;
} else if (_mouseClickAndDragEnabled) {
- event.type = Common::EVENT_LBUTTONUP;
- handleEvent_mouseEvent(event, 0, 0);
+ if (_touchpadModeEnabled && _queuedInputEvent.type == Common::EVENT_LBUTTONDOWN) {
+ // This has not been sent yet, send it right away
+ event = _queuedInputEvent;
+ _queuedInputEvent.type = Common::EVENT_LBUTTONUP;
+ _queuedEventTime = getMillis() + kQueuedInputEventDelay;
+ handleEvent_mouseEvent(_queuedInputEvent, 0, 0);
+ } else {
+ event.type = Common::EVENT_LBUTTONUP;
+ handleEvent_mouseEvent(event, 0, 0);
+ }
} else {
if (getMillis() - _lastMouseDown < 250) {
event.type = Common::EVENT_LBUTTONDOWN;
@@ -286,6 +300,10 @@ bool OSystem_iOS7::handleEvent_touchFirstDragged(Common::Event &event, int x, in
_lastPadY = y;
if (_touchpadModeEnabled) {
+ if (_mouseClickAndDragEnabled && _queuedInputEvent.type == Common::EVENT_LBUTTONDOWN) {
+ // Cancel the button down event since this was a pure mouse move
+ _queuedInputEvent.type = Common::EVENT_INVALID;
+ }
handleEvent_mouseDelta(event, deltaX, deltaY);
} else {
// Update mouse position
Commit: 5d5564fcebe8236988a1c14f77402212262284b6
https://github.com/scummvm/scummvm/commit/5d5564fcebe8236988a1c14f77402212262284b6
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-07-03T21:50:32+02:00
Commit Message:
IOS7: Hide word suggestion list in newer iOS versions
Since iOS 15 or 16 both auto correction and spelling check have to
be disabled to hide the word suggestion list above the keyboard.
Changed paths:
backends/platform/ios7/ios7_keyboard.mm
diff --git a/backends/platform/ios7/ios7_keyboard.mm b/backends/platform/ios7/ios7_keyboard.mm
index 49382008b5d..51e84b2bd87 100644
--- a/backends/platform/ios7/ios7_keyboard.mm
+++ b/backends/platform/ios7/ios7_keyboard.mm
@@ -50,6 +50,7 @@
softKeyboard = keyboard;
[self setAutocorrectionType:UITextAutocorrectionTypeNo];
+ [self setSpellCheckingType:UITextSpellCheckingTypeNo];
[self setAutocapitalizationType:UITextAutocapitalizationTypeNone];
[self setEnablesReturnKeyAutomatically:NO];
#if TARGET_OS_IOS
Commit: d8bc349b37375dd1663f90c2792e13171aa9bc0a
https://github.com/scummvm/scummvm/commit/d8bc349b37375dd1663f90c2792e13171aa9bc0a
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-07-03T21:50:32+02:00
Commit Message:
IOS7: Resize main frame depending on keyboard size and orientation
It's important that the main frame, displaying the OpenGL rendered
graphics, has the proper dimensions and depending on the device
orientation. It's also important that the frame is not covered by
the iOS keyboard.
This commit calculates the frame size depening on the orientation
and the keyboard status. The keyboard knows its parent view and
can resize it when the keyboard becomes visible or hidden.
There are multiple scenarios where the frame size is changed.
- When the keyboard is hidden/shown which can be automatically
change depending on the device orientation
- If the system demands the keyboard to get visible or hidden
- When rotating the device
- When suspending/resuming the application
There can also be combination of the scenarios above, e.g. if
suspending the application in landscape mode and resume it in
portrait mode.
A lot of effort has been put into testing different scenarios to
verify that the screen size becomes correct. However there might
be some scenario which has not been covered.
Changed paths:
backends/platform/ios7/ios7_keyboard.mm
backends/platform/ios7/ios7_video.h
backends/platform/ios7/ios7_video.mm
diff --git a/backends/platform/ios7/ios7_keyboard.mm b/backends/platform/ios7/ios7_keyboard.mm
index 51e84b2bd87..989c313f3cb 100644
--- a/backends/platform/ios7/ios7_keyboard.mm
+++ b/backends/platform/ios7/ios7_keyboard.mm
@@ -393,16 +393,72 @@
@end
- at implementation SoftKeyboard
+ at implementation SoftKeyboard {
+ BOOL _keyboardVisible;
+}
+
+#if TARGET_OS_IOS
+- (void)resizeParentFrame:(NSNotification*)notification keyboardDidShow:(BOOL)didShow
+{
+ NSDictionary* userInfo = [notification userInfo];
+ CGRect keyboardFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
+ keyboardFrame = [self.superview convertRect:keyboardFrame fromView:nil];
+
+ // Base the new frame size on the current parent frame size
+ CGRect newFrame = self.superview.frame;
+ newFrame.size.height += (keyboardFrame.size.height) * (didShow ? -1 : 1);
+
+ // Resize with a fancy animation
+ NSNumber *rate = notification.userInfo[UIKeyboardAnimationDurationUserInfoKey];
+ [UIView animateWithDuration:rate.floatValue animations:^{
+ self.superview.frame = newFrame;
+ }];
+}
+
+- (void)keyboardDidShow:(NSNotification*)notification
+{
+ // NotificationCenter might notify multiple times
+ // when keyboard did show because the accessoryView
+ // affect the keyboard height. However since we use
+ // UIKeyboardFrameEndUserInfoKey to get the keyboard
+ // it will always have the same value. Make sure to
+ // only handle one notification.
+ if (!_keyboardVisible) {
+ [self resizeParentFrame:notification keyboardDidShow:YES];
+ _keyboardVisible = YES;
+ }
+}
+
+- (void)keyboardDidHide:(NSNotification*)notification
+{
+ // NotificationCenter will only call this once
+ // when keyboard did hide.
+ [self resizeParentFrame:notification keyboardDidShow:NO];
+ _keyboardVisible = NO;
+}
+#endif
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
+
+#if TARGET_OS_IOS
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(keyboardDidShow:)
+ name:UIKeyboardDidShowNotification
+ object:nil];
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(keyboardDidHide:)
+ name:UIKeyboardDidHideNotification
+ object:nil];
+#endif
+
inputDelegate = nil;
inputView = [[TextInputHandler alloc] initWithKeyboard:self];
inputView.delegate = self;
inputView.clearsOnBeginEditing = YES;
[inputView layoutIfNeeded];
-
+ _keyboardVisible = NO;
return self;
}
diff --git a/backends/platform/ios7/ios7_video.h b/backends/platform/ios7/ios7_video.h
index 8ca321395a1..807460fb954 100644
--- a/backends/platform/ios7/ios7_video.h
+++ b/backends/platform/ios7/ios7_video.h
@@ -48,7 +48,9 @@ uint getSizeNextPOT(uint size);
NSLock *_eventLock;
SoftKeyboard *_keyboardView;
Common::List<GameController*> _controllers;
-
+#if TARGET_OS_IOS
+ UIInterfaceOrientation _currentOrientation;
+#endif
UIBackgroundTaskIdentifier _backgroundSaveStateTask;
EAGLContext *_mainContext;
diff --git a/backends/platform/ios7/ios7_video.mm b/backends/platform/ios7/ios7_video.mm
index e501f5cdfae..32b9e7a4215 100644
--- a/backends/platform/ios7/ios7_video.mm
+++ b/backends/platform/ios7/ios7_video.mm
@@ -290,6 +290,9 @@ bool iOS7_fetchEvent(InternalEvent *event) {
self = [super initWithFrame: frame];
_backgroundSaveStateTask = UIBackgroundTaskInvalid;
+#if TARGET_OS_IOS
+ _currentOrientation = UIInterfaceOrientationUnknown;
+#endif
[self setupGestureRecognizers];
@@ -325,7 +328,12 @@ bool iOS7_fetchEvent(InternalEvent *event) {
[_keyboardView setInputDelegate:self];
[self addSubview:[_keyboardView inputView]];
[self addSubview: _keyboardView];
- [self showKeyboard];
+ if ([self getScreenHeight] > [self getScreenWidth]) {
+ // This will make sure the keyboard is shown in portrait
+ // mode on start of the application since the orientation
+ // handling is performed before the view finish its setup
+ [self showKeyboard];
+ }
}
[self adjustViewFrameForSafeArea];
@@ -344,7 +352,7 @@ bool iOS7_fetchEvent(InternalEvent *event) {
#ifdef __IPHONE_11_0
if ( @available(iOS 11, tvOS 11, *) ) {
CGRect screenSize = [[UIScreen mainScreen] bounds];
- CGRect newFrame = screenSize;
+ CGRect newFrame = self.frame;
#if TARGET_OS_IOS
UIEdgeInsets inset = [[[UIApplication sharedApplication] keyWindow] safeAreaInsets];
UIInterfaceOrientation orientation = UIInterfaceOrientationUnknown;
@@ -353,14 +361,32 @@ bool iOS7_fetchEvent(InternalEvent *event) {
} else {
orientation = [[UIApplication sharedApplication] statusBarOrientation];
}
+
+ // The code below adjust the screen size according to what Apple calls
+ // the "safe area". It also cover the cases when the software keyboard
+ // is visible and has changed the frame height so the keyboard doesn't
+ // cover any part of the game screen.
+ if (orientation != _currentOrientation) {
+ // If the orientation is changed the keyboard will hide or show
+ // depending on the current orientation. The frame size must be
+ // "reset" again to "full" screen size dimension. The keyboard
+ // will then calculate the approriate height when becoming visible.
+ newFrame = screenSize;
+ _currentOrientation = orientation;
+ }
+ // Make sure the frame height (either full screen or resized due to
+ // visible keyboard) is within the safe area.
+ CGFloat safeAreaHeight = screenSize.size.height - inset.top;
+ CGFloat height = newFrame.size.height < safeAreaHeight ? newFrame.size.height : safeAreaHeight;
+
if ( orientation == UIInterfaceOrientationPortrait ) {
- newFrame = CGRectMake(screenSize.origin.x, screenSize.origin.y + inset.top, screenSize.size.width, screenSize.size.height - inset.top);
+ newFrame = CGRectMake(screenSize.origin.x, screenSize.origin.y + inset.top, screenSize.size.width, height);
} else if ( orientation == UIInterfaceOrientationPortraitUpsideDown ) {
- newFrame = CGRectMake(screenSize.origin.x, screenSize.origin.y, screenSize.size.width, screenSize.size.height - inset.top);
+ newFrame = CGRectMake(screenSize.origin.x, screenSize.origin.y, screenSize.size.width, height);
} else if ( orientation == UIInterfaceOrientationLandscapeLeft ) {
- newFrame = CGRectMake(screenSize.origin.x, screenSize.origin.y, screenSize.size.width - inset.right, screenSize.size.height);
+ newFrame = CGRectMake(screenSize.origin.x, screenSize.origin.y, screenSize.size.width - inset.right, height);
} else if ( orientation == UIInterfaceOrientationLandscapeRight ) {
- newFrame = CGRectMake(screenSize.origin.x + inset.left, screenSize.origin.y, screenSize.size.width - inset.left, screenSize.size.height);
+ newFrame = CGRectMake(screenSize.origin.x + inset.left, screenSize.origin.y, screenSize.size.width - inset.left, height);
}
#endif
self.frame = newFrame;
@@ -371,6 +397,8 @@ bool iOS7_fetchEvent(InternalEvent *event) {
#ifdef __IPHONE_11_0
// This delegate method is called when the safe area of the view changes
-(void)safeAreaInsetsDidChange {
+ [super safeAreaInsetsDidChange];
+
[self adjustViewFrameForSafeArea];
}
#endif
@@ -606,6 +634,10 @@ bool iOS7_fetchEvent(InternalEvent *event) {
}
- (void)applicationSuspend {
+ // Make sure to hide the keyboard when suspended. Else the frame
+ // sizing might become incorrect because the NotificationCenter
+ // sends keyboard notifications on resume.
+ [self hideKeyboard];
[self addEvent:InternalEvent(kInputApplicationSuspended, 0, 0)];
}
Commit: 3ee048d922601645f2f6c6f9141394749dab4a7d
https://github.com/scummvm/scummvm/commit/3ee048d922601645f2f6c6f9141394749dab4a7d
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-07-03T21:50:32+02:00
Commit Message:
IOS7: Update logic for touch events for Apple TV remote
The Apple TV remote sends touch events of type UITouchTypeIndirect
since it's not touches made on the screen. In iOS touchpads might
send UITouchTypeIndirect touch events as well as mouse move events.
So in iOS we want to block touches of type UITouchTypeIndirect
while in TV OS we want them to be handled.
Touchpad mode for touch events is also required for the Apple TV
remote to work properly. Make sure to disable the possibility to
disable touchpad mode in TV OS.
Changed paths:
backends/platform/ios7/ios7_options.mm
backends/platform/ios7/ios7_touch_controller.mm
backends/platform/ios7/ios7_video.mm
diff --git a/backends/platform/ios7/ios7_options.mm b/backends/platform/ios7/ios7_options.mm
index 0fe3e33b11b..15a40648e1f 100644
--- a/backends/platform/ios7/ios7_options.mm
+++ b/backends/platform/ios7/ios7_options.mm
@@ -180,7 +180,11 @@ void IOS7OptionsWidget::setEnabled(bool e) {
#else
_onscreenCheckbox->setEnabled(false);
#endif
+#if TARGET_OS_IOS
_touchpadCheckbox->setEnabled(e);
+#else
+ _touchpadCheckbox->setEnabled(false);
+#endif
_clickAndDragCheckbox->setEnabled(e);
_keyboardFnBarCheckbox->setEnabled(e);
}
diff --git a/backends/platform/ios7/ios7_touch_controller.mm b/backends/platform/ios7/ios7_touch_controller.mm
index feb97f616aa..926a71274f5 100644
--- a/backends/platform/ios7/ios7_touch_controller.mm
+++ b/backends/platform/ios7/ios7_touch_controller.mm
@@ -45,6 +45,19 @@
return self;
}
+- (BOOL)shouldHandleTouch:(UITouch *)touch {
+ // In iOS touchpads will trigger UITouchTypeIndirect events
+ // However, they will also send mose events. Make sure to
+ // block the UITouchTypeIndirect but not in Apple TV OS where
+ // they are required as the Apple TV remote sends touh events
+ // but no mouse events.
+#if TARGET_OS_IOS
+ return touch.type == UITouchTypeDirect;
+#else
+ return YES;
+#endif
+}
+
- (UITouch *)secondTouchOtherTouchThan:(UITouch *)touch in:(NSSet *)set {
NSArray *all = [set allObjects];
for (UITouch *t in all) {
@@ -60,7 +73,7 @@
switch (allTouches.count) {
case 1: {
_firstTouch = [allTouches anyObject];
- if (_firstTouch.type == UITouchTypeDirect) {
+ if ([self shouldHandleTouch:_firstTouch]) {
CGPoint p = [self getLocationInView:_firstTouch];
[[self view] addEvent:InternalEvent(kInputTouchFirstDown, p.x, p.y)];
}
@@ -68,7 +81,7 @@
}
case 2: {
_secondTouch = [self secondTouchOtherTouchThan:_firstTouch in:allTouches];
- if (_secondTouch && _secondTouch.type == UITouchTypeDirect) {
+ if (_secondTouch && [self shouldHandleTouch:_secondTouch]) {
CGPoint p = [self getLocationInView:_firstTouch];
[[self view] addEvent:InternalEvent(kInputTouchSecondDown, p.x, p.y)];
}
@@ -82,7 +95,7 @@
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
NSSet *allTouches = [event allTouches];
for (UITouch *touch in allTouches) {
- if (touch.type == UITouchTypeDirect) {
+ if ([self shouldHandleTouch:touch]) {
if (touch == _firstTouch) {
CGPoint p = [self getLocationInView:touch];
[[self view] addEvent:InternalEvent(kInputTouchFirstDragged , p.x, p.y)];
@@ -99,7 +112,7 @@
switch (allTouches.count) {
case 1: {
_firstTouch = [allTouches anyObject];
- if (_firstTouch.type == UITouchTypeDirect) {
+ if ([self shouldHandleTouch:_firstTouch]) {
CGPoint p = [self getLocationInView:_firstTouch];
[[self view] addEvent:InternalEvent(kInputTouchFirstUp, p.x, p.y)];
}
@@ -107,7 +120,7 @@
}
case 2: {
_secondTouch = [self secondTouchOtherTouchThan:_firstTouch in:allTouches];
- if (_secondTouch && _secondTouch.type == UITouchTypeDirect) {
+ if (_secondTouch && [self shouldHandleTouch:_secondTouch]) {
CGPoint p = [self getLocationInView:_firstTouch];
[[self view] addEvent:InternalEvent(kInputTouchSecondUp, p.x, p.y)];
}
diff --git a/backends/platform/ios7/ios7_video.mm b/backends/platform/ios7/ios7_video.mm
index 32b9e7a4215..c55d975d107 100644
--- a/backends/platform/ios7/ios7_video.mm
+++ b/backends/platform/ios7/ios7_video.mm
@@ -56,7 +56,7 @@ bool iOS7_isBigDevice() {
#if TARGET_OS_IOS
return UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad;
#elif TARGET_OS_TV
- return true;
+ return false;
#endif
}
Commit: 06e231a649ee2060fe16dd96bed47a9fd4c80f96
https://github.com/scummvm/scummvm/commit/06e231a649ee2060fe16dd96bed47a9fd4c80f96
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-07-03T21:50:32+02:00
Commit Message:
IOS7: Show keyboard automatically when in game and portrait mode
Open the iOS system keyboard automatically when starting a game and
screen orientation is portrait. If orientation changes to portrait,
open the keyboard automatically only if game is running.
Changed paths:
backends/platform/ios7/ios7_osys_video.mm
backends/platform/ios7/ios7_video.mm
diff --git a/backends/platform/ios7/ios7_osys_video.mm b/backends/platform/ios7/ios7_osys_video.mm
index 32b3908f988..6fe64e4c7fe 100644
--- a/backends/platform/ios7/ios7_osys_video.mm
+++ b/backends/platform/ios7/ios7_osys_video.mm
@@ -77,6 +77,15 @@ void OSystem_iOS7::logMessage(LogMessageType::Type type, const char *message) {
fflush(output);
}
+static inline void execute_on_main_thread(void (^block)(void)) {
+ if ([NSThread currentThread] == [NSThread mainThread]) {
+ block();
+ }
+ else {
+ dispatch_sync(dispatch_get_main_queue(), block);
+ }
+}
+
void OSystem_iOS7::engineInit() {
EventsBaseBackend::engineInit();
// Prevent the device going to sleep during game play (and in particular cut scenes)
@@ -84,6 +93,18 @@ void OSystem_iOS7::engineInit() {
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
});
[[iOS7AppDelegate iPhoneView] setIsInGame:YES];
+
+#if TARGET_OS_IOS
+ // Automatically open the keyboard when starting a game and in portrait mode.
+ // This is preferred for text input games and there's a lot of screen space to
+ // utilize for the keyboard anyway.
+ if (_screenOrientation == kScreenOrientationPortrait ||
+ _screenOrientation == kScreenOrientationFlippedPortrait) {
+ execute_on_main_thread(^ {
+ [[iOS7AppDelegate iPhoneView] showKeyboard];
+ });
+ }
+#endif
}
void OSystem_iOS7::engineDone() {
@@ -93,15 +114,13 @@ void OSystem_iOS7::engineDone() {
[[UIApplication sharedApplication] setIdleTimerDisabled:NO];
});
[[iOS7AppDelegate iPhoneView] setIsInGame:NO];
-}
-static inline void execute_on_main_thread(void (^block)(void)) {
- if ([NSThread currentThread] == [NSThread mainThread]) {
- block();
- }
- else {
- dispatch_sync(dispatch_get_main_queue(), block);
- }
+#if TARGET_OS_IOS
+ // Hide keyboard when going back to launcher
+ execute_on_main_thread(^ {
+ [[iOS7AppDelegate iPhoneView] hideKeyboard];
+ });
+#endif
}
void OSystem_iOS7::updateOutputSurface() {
diff --git a/backends/platform/ios7/ios7_video.mm b/backends/platform/ios7/ios7_video.mm
index c55d975d107..e1b9db7ca78 100644
--- a/backends/platform/ios7/ios7_video.mm
+++ b/backends/platform/ios7/ios7_video.mm
@@ -328,12 +328,6 @@ bool iOS7_fetchEvent(InternalEvent *event) {
[_keyboardView setInputDelegate:self];
[self addSubview:[_keyboardView inputView]];
[self addSubview: _keyboardView];
- if ([self getScreenHeight] > [self getScreenWidth]) {
- // This will make sure the keyboard is shown in portrait
- // mode on start of the application since the orientation
- // handling is performed before the view finish its setup
- [self showKeyboard];
- }
}
[self adjustViewFrameForSafeArea];
@@ -471,7 +465,9 @@ bool iOS7_fetchEvent(InternalEvent *event) {
if (UIInterfaceOrientationIsLandscape(orientation)) {
[self hideKeyboard];
} else {
- [self showKeyboard];
+ // Automatically open the keyboard if changing orientation in a game
+ if ([self isInGame])
+ [self showKeyboard];
}
}
#endif
Commit: 6078586aecf2a14314dd54891aef1c2915d83704
https://github.com/scummvm/scummvm/commit/6078586aecf2a14314dd54891aef1c2915d83704
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-07-03T21:50:32+02:00
Commit Message:
CREATE_PROJECT: Correct spelling of definition and shader file name
The GRIM define was incorrectly spelled GRIME which cause no shader
files to be included to the project preventing the game to start.
The freescape shader file freescape_triange.vertex also contained
a spelling error preventing the game to start.
Changed paths:
devtools/create_project/xcode.cpp
diff --git a/devtools/create_project/xcode.cpp b/devtools/create_project/xcode.cpp
index 5b51d154979..d8c540ccd56 100644
--- a/devtools/create_project/xcode.cpp
+++ b/devtools/create_project/xcode.cpp
@@ -1057,7 +1057,7 @@ XcodeProvider::ValueList& XcodeProvider::getResourceFiles(const BuildSetup &setu
files.push_back("dists/tvos/LaunchScreen_tvos.storyboard");
files.push_back("dists/pred.dic");
files.push_back("dists/networking/wwwroot.zip");
- if (CONTAINS_DEFINE(setup.defines, "ENABLE_GRIME")) {
+ if (CONTAINS_DEFINE(setup.defines, "ENABLE_GRIM")) {
files.push_back("engines/grim/shaders/grim_dim.fragment");
files.push_back("engines/grim/shaders/grim_dim.vertex");
files.push_back("engines/grim/shaders/grim_emerg.fragment");
@@ -1141,7 +1141,7 @@ XcodeProvider::ValueList& XcodeProvider::getResourceFiles(const BuildSetup &setu
files.push_back("engines/freescape/shaders/freescape_bitmap.fragment");
files.push_back("engines/freescape/shaders/freescape_bitmap.vertex");
files.push_back("engines/freescape/shaders/freescape_triangle.fragment");
- files.push_back("engines/freescape/shaders/freescape_triange.vertex");
+ files.push_back("engines/freescape/shaders/freescape_triangle.vertex");
}
files.push_back("icons/scummvm.icns");
files.push_back("AUTHORS");
More information about the Scummvm-git-logs
mailing list