From 80afba232a30b7d80d9331f597aee208d80cd2e1 Mon Sep 17 00:00:00 2001 From: Vincent Bénony Date: Wed, 9 Dec 2015 17:49:54 +0100 Subject: IOS: Implements scalers --- backends/platform/ios7/ios7_common.h | 14 +++- backends/platform/ios7/ios7_osys_main.cpp | 20 +++++- backends/platform/ios7/ios7_osys_video.mm | 9 +++ backends/platform/ios7/ios7_video.h | 8 +++ backends/platform/ios7/ios7_video.mm | 108 +++++++++++++++++++++++++++++- 5 files changed, 155 insertions(+), 4 deletions(-) (limited to 'backends/platform') diff --git a/backends/platform/ios7/ios7_common.h b/backends/platform/ios7/ios7_common.h index 73db72a068..b7a47eda8a 100644 --- a/backends/platform/ios7/ios7_common.h +++ b/backends/platform/ios7/ios7_common.h @@ -60,14 +60,24 @@ enum UIViewTapDescription { enum GraphicsModes { kGraphicsModeLinear = 0, - kGraphicsModeNone = 1 + kGraphicsModeNone = 1, + + kGraphicsMode2xSaI, + kGraphicsModeSuper2xSaI, + kGraphicsModeSuperEagle, + kGraphicsModeAdvMame2x, + kGraphicsModeAdvMame3x, + kGraphicsModeHQ2x, + kGraphicsModeHQ3x, + kGraphicsModeTV2x, + kGraphicsModeDotMatrix }; struct VideoContext { VideoContext() : asprectRatioCorrection(), screenWidth(), screenHeight(), overlayVisible(false), overlayWidth(), overlayHeight(), mouseX(), mouseY(), mouseHotspotX(), mouseHotspotY(), mouseWidth(), mouseHeight(), - mouseIsVisible(), graphicsMode(kGraphicsModeLinear), shakeOffsetY() { + mouseIsVisible(), graphicsMode(kGraphicsModeNone), shakeOffsetY() { } // Game screen state diff --git a/backends/platform/ios7/ios7_osys_main.cpp b/backends/platform/ios7/ios7_osys_main.cpp index d8eb84e214..76739423c1 100644 --- a/backends/platform/ios7/ios7_osys_main.cpp +++ b/backends/platform/ios7/ios7_osys_main.cpp @@ -43,12 +43,30 @@ #include "audio/mixer.h" #include "audio/mixer_intern.h" +#include "graphics/scaler.h" +#include "graphics/scaler/aspect.h" + #include "ios7_osys_main.h" const OSystem::GraphicsMode OSystem_iOS7::s_supportedGraphicsModes[] = { - { "linear", "Linear filtering", kGraphicsModeLinear }, { "none", "No filtering", kGraphicsModeNone }, + { "linear", "Linear filtering", kGraphicsModeLinear }, +#ifdef USE_SCALERS +// {"2x", "2x", GFX_DOUBLESIZE}, +// {"3x", "3x", GFX_TRIPLESIZE}, + { "2xsai", "2xSAI", kGraphicsMode2xSaI}, + {"super2xsai", "Super2xSAI", kGraphicsModeSuper2xSaI}, + {"supereagle", "SuperEagle", kGraphicsModeSuperEagle}, + {"advmame2x", "AdvMAME2x", kGraphicsModeAdvMame2x}, + {"advmame3x", "AdvMAME3x", kGraphicsModeAdvMame3x}, +#ifdef USE_HQ_SCALERS + {"hq2x", "HQ2x", kGraphicsModeHQ2x}, + {"hq3x", "HQ3x", kGraphicsModeHQ3x}, +#endif + {"tv2x", "TV2x", kGraphicsModeTV2x}, + {"dotmatrix", "DotMatrix", kGraphicsModeDotMatrix}, +#endif { 0, 0, 0 } }; diff --git a/backends/platform/ios7/ios7_osys_video.mm b/backends/platform/ios7/ios7_osys_video.mm index f2f00069f9..7cce56c800 100644 --- a/backends/platform/ios7/ios7_osys_video.mm +++ b/backends/platform/ios7/ios7_osys_video.mm @@ -45,6 +45,15 @@ bool OSystem_iOS7::setGraphicsMode(int mode) { switch (mode) { case kGraphicsModeNone: case kGraphicsModeLinear: + case kGraphicsMode2xSaI: + case kGraphicsModeSuper2xSaI: + case kGraphicsModeSuperEagle: + case kGraphicsModeAdvMame2x: + case kGraphicsModeAdvMame3x: + case kGraphicsModeHQ2x: + case kGraphicsModeHQ3x: + case kGraphicsModeTV2x: + case kGraphicsModeDotMatrix: _videoContext->graphicsMode = (GraphicsModes)mode; return true; diff --git a/backends/platform/ios7/ios7_video.h b/backends/platform/ios7/ios7_video.h index 09a84b5498..96a0984882 100644 --- a/backends/platform/ios7/ios7_video.h +++ b/backends/platform/ios7/ios7_video.h @@ -35,6 +35,7 @@ #include "ios7_common.h" #include "common/list.h" +#import "graphics/scaler.h" @interface iPhoneView : UIView { VideoContext _videoContext; @@ -72,6 +73,13 @@ UITouch *_firstTouch; UITouch *_secondTouch; + + uint8_t *_scalerMemorySrc; + uint8_t *_scalerMemoryDst; + size_t _scalerMemorySrcSize; + size_t _scalerMemoryDstSize; + int _scalerScale; + ScalerProc *_scaler; } - (id)initWithFrame:(struct CGRect)frame; diff --git a/backends/platform/ios7/ios7_video.mm b/backends/platform/ios7/ios7_video.mm index 235f8f28f1..1660dd4612 100644 --- a/backends/platform/ios7/ios7_video.mm +++ b/backends/platform/ios7/ios7_video.mm @@ -211,6 +211,10 @@ uint getSizeNextPOT(uint size) { - (id)initWithFrame:(struct CGRect)frame { self = [super initWithFrame: frame]; +#if defined(USE_SCALERS) || defined(USE_HQ_SCALERS) + InitScalers(565); +#endif + [self setupGestureRecognizers]; g_fullWidth = (int)MAX(frame.size.width, frame.size.height); @@ -219,6 +223,13 @@ uint getSizeNextPOT(uint size) { _contentScaleFactor = [[UIScreen mainScreen] scale]; [self setContentScaleFactor:_contentScaleFactor]; + _scalerMemorySrc = NULL; + _scalerMemoryDst = NULL; + _scalerMemorySrcSize = 0; + _scalerMemoryDstSize = 0; + _scaler = NULL; + _scalerScale = 1; + _keyboardView = nil; _screenTexture = 0; _overlayTexture = 0; @@ -274,6 +285,9 @@ uint getSizeNextPOT(uint size) { _videoContext.overlayTexture.free(); _videoContext.mouseTexture.free(); + free(_scalerMemorySrc); + free(_scalerMemoryDst); + [_eventLock release]; [super dealloc]; } @@ -300,6 +314,8 @@ uint getSizeNextPOT(uint size) { glBindTexture(GL_TEXTURE_2D, tex); printOpenGLError(); GLint filter = GL_LINEAR; + ScalerProc *scaler = NULL; + int scalerScale = 1; switch (_videoContext.graphicsMode) { case kGraphicsModeLinear: @@ -309,6 +325,64 @@ uint getSizeNextPOT(uint size) { case kGraphicsModeNone: filter = GL_NEAREST; break; +#ifdef USE_SCALERS + case kGraphicsMode2xSaI: + filter = GL_LINEAR; + scaler = _2xSaI; + scalerScale = 2; + break; + + case kGraphicsModeSuper2xSaI: + filter = GL_LINEAR; + scaler = Super2xSaI; + scalerScale = 2; + break; + + case kGraphicsModeSuperEagle: + filter = GL_LINEAR; + scaler = SuperEagle; + scalerScale = 2; + break; + + case kGraphicsModeAdvMame2x: + filter = GL_LINEAR; + scaler = AdvMame2x; + scalerScale = 2; + break; + + case kGraphicsModeAdvMame3x: + filter = GL_LINEAR; + scaler = AdvMame3x; + scalerScale = 3; + break; + +#ifdef USE_HQ_SCALERS + case kGraphicsModeHQ2x: + filter = GL_LINEAR; + scaler = HQ2x; + scalerScale = 2; + break; + + case kGraphicsModeHQ3x: + filter = GL_LINEAR; + scaler = HQ3x; + scalerScale = 3; + break; +#endif + + case kGraphicsModeTV2x: + filter = GL_LINEAR; + scaler = TV2x; + scalerScale = 2; + break; + + case kGraphicsModeDotMatrix: + filter = GL_LINEAR; + scaler = DotMatrix; + scalerScale = 2; + break; + +#endif } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); printOpenGLError(); @@ -318,6 +392,9 @@ uint getSizeNextPOT(uint size) { // 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(); + + _scaler = scaler; + _scalerScale = scalerScale; } - (void)setGraphicsMode { @@ -422,7 +499,36 @@ uint getSizeNextPOT(uint size) { // 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. - 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(); + if (_scaler) { + size_t neededSrcMemorySize = (size_t) (_videoContext.screenTexture.pitch * (_videoContext.screenTexture.h + 4)); + size_t neededDstMemorySize = (size_t) (_videoContext.screenTexture.pitch * (_videoContext.screenTexture.h + 4) * _scalerScale * _scalerScale); + if (neededSrcMemorySize != _scalerMemorySrcSize) { + _scalerMemorySrc = (uint8_t *) realloc(_scalerMemorySrc, neededSrcMemorySize); + _scalerMemorySrcSize = neededSrcMemorySize; + } + if (neededDstMemorySize != _scalerMemoryDstSize) { + _scalerMemoryDst = (uint8_t *) realloc(_scalerMemoryDst, neededDstMemorySize); + _scalerMemoryDstSize = neededDstMemorySize; + } + + // Clear two lines before + memset(_scalerMemorySrc, 0, _videoContext.screenTexture.pitch * 2); + // Copy original buffer + memcpy(_scalerMemorySrc + _videoContext.screenTexture.pitch * 2, _videoContext.screenTexture.getPixels(), _videoContext.screenTexture.pitch * _videoContext.screenTexture.h); + // Clear two linex after + memset(_scalerMemorySrc + _videoContext.screenTexture.pitch * (2 + _videoContext.screenTexture.h), 0, _videoContext.screenTexture.pitch * 2); + // Apply scaler + _scaler(_scalerMemorySrc + _videoContext.screenTexture.pitch * 2, + _videoContext.screenTexture.pitch, + _scalerMemoryDst, + (uint32) (_videoContext.screenTexture.pitch * _scalerScale), + _videoContext.screenTexture.w, + _videoContext.screenTexture.h); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _videoContext.screenTexture.w * _scalerScale, _videoContext.screenTexture.h * _scalerScale, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, _scalerMemoryDst); printOpenGLError(); + } + else { + 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(); } -- cgit v1.2.3