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.
This commit is contained in:
parent
d36074773b
commit
fb4f7d6de2
11 changed files with 7 additions and 867 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]) {
|
||||
|
|
2
configure
vendored
2
configure
vendored
|
@ -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"
|
||||
|
|
|
@ -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));
|
||||
|
|
2
ports.mk
2
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue