From 7a05624e1b3371a2823a46749083fe4bc9eb4a60 Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Sun, 8 Sep 2019 19:37:48 +0100 Subject: ANDROID: Rewrite to make use of OpenGLGraphicsManager (#1695) * ANDROID: Rewrite to make use of OpenGLGraphicsManager * ANDROID: Fix emulated mouse button up events --- backends/platform/android/android.cpp | 149 +--- backends/platform/android/android.h | 173 +---- backends/platform/android/events.cpp | 181 ++--- backends/platform/android/gfx.cpp | 814 --------------------- backends/platform/android/graphics.cpp | 134 ++++ backends/platform/android/graphics.h | 55 ++ backends/platform/android/jni.cpp | 8 - backends/platform/android/jni.h | 2 - backends/platform/android/module.mk | 3 +- .../android/org/scummvm/scummvm/ScummVM.java | 1 - .../org/scummvm/scummvm/ScummVMActivity.java | 22 - backends/platform/android/texture.cpp | 476 ------------ backends/platform/android/texture.h | 285 -------- 13 files changed, 264 insertions(+), 2039 deletions(-) delete mode 100644 backends/platform/android/gfx.cpp create mode 100644 backends/platform/android/graphics.cpp create mode 100644 backends/platform/android/graphics.h delete mode 100644 backends/platform/android/texture.cpp delete mode 100644 backends/platform/android/texture.h (limited to 'backends/platform') diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp index 2ae36c8073..67657b732e 100644 --- a/backends/platform/android/android.cpp +++ b/backends/platform/android/android.cpp @@ -60,6 +60,7 @@ #include "backends/platform/android/jni.h" #include "backends/platform/android/android.h" +#include "backends/platform/android/graphics.h" const char *android_log_tag = "ScummVM"; @@ -80,62 +81,11 @@ extern "C" { } } -#ifdef ANDROID_DEBUG_GL -static const char *getGlErrStr(GLenum error) { - switch (error) { - case GL_INVALID_ENUM: - return "GL_INVALID_ENUM"; - case GL_INVALID_VALUE: - return "GL_INVALID_VALUE"; - case GL_INVALID_OPERATION: - return "GL_INVALID_OPERATION"; - case GL_STACK_OVERFLOW: - return "GL_STACK_OVERFLOW"; - case GL_STACK_UNDERFLOW: - return "GL_STACK_UNDERFLOW"; - case GL_OUT_OF_MEMORY: - return "GL_OUT_OF_MEMORY"; - } - - static char buf[40]; - snprintf(buf, sizeof(buf), "(Unknown GL error code 0x%x)", error); - - return buf; -} - -void checkGlError(const char *expr, const char *file, int line) { - GLenum error = glGetError(); - - if (error != GL_NO_ERROR) - LOGE("GL ERROR: %s on %s (%s:%d)", getGlErrStr(error), expr, file, line); -} -#endif - OSystem_Android::OSystem_Android(int audio_sample_rate, int audio_buffer_size) : _audio_sample_rate(audio_sample_rate), _audio_buffer_size(audio_buffer_size), _screen_changeid(0), - _egl_surface_width(0), - _egl_surface_height(0), - _htc_fail(true), - _force_redraw(false), - _game_texture(0), - _overlay_texture(0), - _mouse_texture(0), - _mouse_texture_palette(0), - _mouse_texture_rgb(0), - _mouse_hotspot(), - _mouse_keycolor(0), - _use_mouse_palette(false), - _graphicsMode(0), - _fullscreen(true), - _ar_correction(true), - _show_mouse(false), - _show_overlay(false), - _enable_zoning(false), - _mutexManager(0), _mixer(0), - _shake_offset(0), _queuedEventTime(0), _event_queue_lock(0), _touch_pt_down(), @@ -153,22 +103,14 @@ OSystem_Android::OSystem_Android(int audio_sample_rate, int audio_buffer_size) : _fsFactory = new POSIXFilesystemFactory(); - Common::String mf = getSystemProperty("ro.product.manufacturer"); - LOGI("Running on: [%s] [%s] [%s] [%s] [%s] SDK:%s ABI:%s", - mf.c_str(), + getSystemProperty("ro.product.manufacturer").c_str(), getSystemProperty("ro.product.model").c_str(), getSystemProperty("ro.product.brand").c_str(), getSystemProperty("ro.build.fingerprint").c_str(), getSystemProperty("ro.build.display.id").c_str(), getSystemProperty("ro.build.version.sdk").c_str(), getSystemProperty("ro.product.cpu.abi").c_str()); - - mf.toLowercase(); - /*_htc_fail = mf.contains("htc"); - - if (_htc_fail) - LOGI("Enabling HTC workaround");*/ } OSystem_Android::~OSystem_Android() { @@ -182,9 +124,6 @@ OSystem_Android::~OSystem_Android() { _timerManager = 0; deleteMutex(_event_queue_lock); - - delete _mutexManager; - _mutexManager = 0; } void *OSystem_Android::timerThreadFunc(void *arg) { @@ -390,15 +329,7 @@ void OSystem_Android::initBackend() { _audio_thread_exit = false; pthread_create(&_audio_thread, 0, audioThreadFunc, this); - initSurface(); - initViewport(); - - _game_texture = new GLESFakePalette565Texture(); - _overlay_texture = new GLES4444Texture(); - _mouse_texture_palette = new GLESFakePalette5551Texture(); - _mouse_texture = _mouse_texture_palette; - - initOverlay(); + _graphicsManager = new AndroidGraphicsManager(); // renice this thread to boost the audio thread if (setpriority(PRIO_PROCESS, 0, 19) < 0) @@ -406,42 +337,28 @@ void OSystem_Android::initBackend() { JNI::setReadyForEvents(true); - EventsBaseBackend::initBackend(); + ModularBackend::initBackend(); } bool OSystem_Android::hasFeature(Feature f) { - return (f == kFeatureFullscreenMode || - f == kFeatureAspectRatioCorrection || - f == kFeatureCursorPalette || - f == kFeatureVirtualKeyboard || - f == kFeatureOverlaySupportsAlpha || + if (f == kFeatureVirtualKeyboard || f == kFeatureOpenUrl || f == kFeatureTouchpadMode || f == kFeatureOnScreenControl || - f == kFeatureClipboardSupport); + f == kFeatureClipboardSupport) { + return true; + } + return ModularBackend::hasFeature(f); } void OSystem_Android::setFeatureState(Feature f, bool enable) { ENTER("%d, %d", f, enable); switch (f) { - case kFeatureFullscreenMode: - _fullscreen = enable; - updateScreenRect(); - break; - case kFeatureAspectRatioCorrection: - _ar_correction = enable; - updateScreenRect(); - break; case kFeatureVirtualKeyboard: _virtkeybd_on = enable; showVirtualKeyboard(enable); break; - case kFeatureCursorPalette: - _use_mouse_palette = enable; - if (!enable) - disableCursorPalette(); - break; case kFeatureTouchpadMode: ConfMan.setBool("touchpad_mouse_mode", enable); _touchpad_mode = enable; @@ -451,26 +368,21 @@ void OSystem_Android::setFeatureState(Feature f, bool enable) { JNI::showKeyboardControl(enable); break; default: + ModularBackend::setFeatureState(f, enable); break; } } bool OSystem_Android::getFeatureState(Feature f) { switch (f) { - case kFeatureFullscreenMode: - return _fullscreen; - case kFeatureAspectRatioCorrection: - return _ar_correction; case kFeatureVirtualKeyboard: return _virtkeybd_on; - case kFeatureCursorPalette: - return _use_mouse_palette; case kFeatureTouchpadMode: return ConfMan.getBool("touchpad_mouse_mode"); case kFeatureOnScreenControl: return ConfMan.getBool("onscreen_control"); default: - return false; + return ModularBackend::getFeatureState(f); } } @@ -487,26 +399,6 @@ void OSystem_Android::delayMillis(uint msecs) { usleep(msecs * 1000); } -OSystem::MutexRef OSystem_Android::createMutex() { - assert(_mutexManager); - return _mutexManager->createMutex(); -} - -void OSystem_Android::lockMutex(MutexRef mutex) { - assert(_mutexManager); - _mutexManager->lockMutex(mutex); -} - -void OSystem_Android::unlockMutex(MutexRef mutex) { - assert(_mutexManager); - _mutexManager->unlockMutex(mutex); -} - -void OSystem_Android::deleteMutex(MutexRef mutex) { - assert(_mutexManager); - _mutexManager->deleteMutex(mutex); -} - void OSystem_Android::quit() { ENTER(); @@ -517,13 +409,6 @@ void OSystem_Android::quit() { _timer_thread_exit = true; pthread_join(_timer_thread, 0); - - delete _game_texture; - delete _overlay_texture; - delete _mouse_texture_palette; - delete _mouse_texture_rgb; - - deinitSurface(); } void OSystem_Android::setWindowCaption(const char *caption) { @@ -532,12 +417,6 @@ void OSystem_Android::setWindowCaption(const char *caption) { JNI::setWindowCaption(caption); } -void OSystem_Android::displayMessageOnOSD(const char *msg) { - ENTER("%s", msg); - - JNI::displayMessageOnOSD(msg); -} - void OSystem_Android::showVirtualKeyboard(bool enable) { ENTER("%d", enable); @@ -563,15 +442,13 @@ void OSystem_Android::getTimeAndDate(TimeDate &td) const { td.tm_wday = tm.tm_wday; } -void OSystem_Android::addSysArchivesToSearchSet(Common::SearchSet &s, - int priority) { +void OSystem_Android::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) { ENTER(""); JNI::addSysArchivesToSearchSet(s, priority); } -void OSystem_Android::logMessage(LogMessageType::Type type, - const char *message) { +void OSystem_Android::logMessage(LogMessageType::Type type, const char *message) { switch (type) { case LogMessageType::kInfo: __android_log_write(ANDROID_LOG_INFO, android_log_tag, message); diff --git a/backends/platform/android/android.h b/backends/platform/android/android.h index d88df6b15f..96219c28de 100644 --- a/backends/platform/android/android.h +++ b/backends/platform/android/android.h @@ -28,25 +28,16 @@ #include "common/fs.h" #include "common/archive.h" #include "audio/mixer_intern.h" -#include "graphics/palette.h" -#include "graphics/surface.h" -#include "backends/base-backend.h" +#include "backends/modular-backend.h" #include "backends/plugins/posix/posix-provider.h" #include "backends/fs/posix/posix-fs-factory.h" -#include "backends/platform/android/texture.h" - #include #include -#include -#include - // toggles start //#define ANDROID_DEBUG_ENTER -//#define ANDROID_DEBUG_GL -//#define ANDROID_DEBUG_GL_CALLS // toggles end extern const char *android_log_tag; @@ -63,76 +54,13 @@ extern const char *android_log_tag; #define ENTER(fmt, args...) do { } while (false) #endif -#ifdef ANDROID_DEBUG_GL -extern void checkGlError(const char *expr, const char *file, int line); - -#ifdef ANDROID_DEBUG_GL_CALLS -#define GLCALLLOG(x, before) \ - do { \ - if (before) \ - LOGD("calling '%s' (%s:%d)", x, __FILE__, __LINE__); \ - else \ - LOGD("returned from '%s' (%s:%d)", x, __FILE__, __LINE__); \ - } while (false) -#else -#define GLCALLLOG(x, before) do { } while (false) -#endif - -#define GLCALL(x) \ - do { \ - GLCALLLOG(#x, true); \ - (x); \ - GLCALLLOG(#x, false); \ - checkGlError(#x, __FILE__, __LINE__); \ - } while (false) - -#define GLTHREADCHECK \ - do { \ - assert(pthread_self() == _main_thread); \ - } while (false) - -#else -#define GLCALL(x) do { (x); } while (false) -#define GLTHREADCHECK do { } while (false) -#endif - -class MutexManager; - -class OSystem_Android : public EventsBaseBackend, public PaletteManager { +class OSystem_Android : public ModularBackend, Common::EventSource { private: // passed from the dark side int _audio_sample_rate; int _audio_buffer_size; int _screen_changeid; - int _egl_surface_width; - int _egl_surface_height; - bool _htc_fail; - - bool _force_redraw; - - // Game layer - GLESBaseTexture *_game_texture; - int _shake_offset; - Common::Rect _focus_rect; - - // Overlay layer - GLES4444Texture *_overlay_texture; - bool _show_overlay; - - // Mouse layer - GLESBaseTexture *_mouse_texture; - GLESBaseTexture *_mouse_texture_palette; - GLES5551Texture *_mouse_texture_rgb; - Common::Point _mouse_hotspot; - uint32 _mouse_keycolor; - int _mouse_targetscale; - bool _show_mouse; - bool _use_mouse_palette; - - int _graphicsMode; - bool _fullscreen; - bool _ar_correction; pthread_t _main_thread; @@ -144,70 +72,27 @@ private: pthread_t _audio_thread; static void *audioThreadFunc(void *arg); - bool _enable_zoning; bool _virtkeybd_on; - MutexManager *_mutexManager; Audio::MixerImpl *_mixer; timeval _startTime; Common::String getSystemProperty(const char *name) const; - void initSurface(); - void deinitSurface(); - void initViewport(); - - void initOverlay(); - -#ifdef USE_RGB_COLOR - void initTexture(GLESBaseTexture **texture, uint width, uint height, - const Graphics::PixelFormat *format); -#endif - void setupKeymapper(); - void setCursorPaletteInternal(const byte *colors, uint start, uint num); + +protected: + virtual Common::EventSource *getDefaultEventSource() { return this; } public: OSystem_Android(int audio_sample_rate, int audio_buffer_size); virtual ~OSystem_Android(); virtual void initBackend(); - void enableZoning(bool enable) { _enable_zoning = enable; } - - virtual bool hasFeature(Feature f); - virtual void setFeatureState(Feature f, bool enable); - virtual bool getFeatureState(Feature f); - - virtual const GraphicsMode *getSupportedGraphicsModes() const; - virtual int getDefaultGraphicsMode() const; - virtual bool setGraphicsMode(int mode); - virtual int getGraphicsMode() const; - -#ifdef USE_RGB_COLOR - virtual Graphics::PixelFormat getScreenFormat() const; - virtual Common::List getSupportedFormats() const; -#endif - - virtual void initSize(uint width, uint height, - const Graphics::PixelFormat *format); - - enum FixupType { - kClear = 0, // glClear - kClearSwap, // glClear + swapBuffers - kClearUpdate // glClear + updateScreen - }; - - void clearScreen(FixupType type, byte count = 1); - void updateScreenRect(); - virtual int getScreenChangeID() const; - - virtual int16 getHeight(); - virtual int16 getWidth(); - - virtual PaletteManager *getPaletteManager() { - return this; - } + virtual bool hasFeature(OSystem::Feature f); + virtual void setFeatureState(OSystem::Feature f, bool enable); + virtual bool getFeatureState(OSystem::Feature f); public: void pushEvent(int type, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6); @@ -230,58 +115,16 @@ private: void clipMouse(Common::Point &p); void scaleMouse(Common::Point &p, int x, int y, bool deductDrawRect = true, bool touchpadMode = false); - void updateEventScale(); - void disableCursorPalette(); - -protected: - // PaletteManager API - virtual void setPalette(const byte *colors, uint start, uint num); - virtual void grabPalette(byte *colors, uint start, uint num) const; public: - virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, - int w, int h); - virtual void updateScreen(); - virtual Graphics::Surface *lockScreen(); - virtual void unlockScreen(); - virtual void setShakePos(int shakeOffset); - virtual void fillScreen(uint32 col); - virtual void setFocusRectangle(const Common::Rect& rect); - virtual void clearFocusRectangle(); - - virtual void showOverlay(); - virtual void hideOverlay(); - virtual void clearOverlay(); - virtual void grabOverlay(void *buf, int pitch); - virtual void copyRectToOverlay(const void *buf, int pitch, - int x, int y, int w, int h); - virtual int16 getOverlayHeight(); - virtual int16 getOverlayWidth(); - virtual Graphics::PixelFormat getOverlayFormat() const; - - virtual bool showMouse(bool visible); - - virtual void warpMouse(int x, int y); - virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, - int hotspotY, uint32 keycolor, - bool dontScale, - const Graphics::PixelFormat *format); - virtual void setCursorPalette(const byte *colors, uint start, uint num); - virtual void pushEvent(const Common::Event &event); virtual bool pollEvent(Common::Event &event); virtual uint32 getMillis(bool skipRecord = false); virtual void delayMillis(uint msecs); - virtual MutexRef createMutex(void); - virtual void lockMutex(MutexRef mutex); - virtual void unlockMutex(MutexRef mutex); - virtual void deleteMutex(MutexRef mutex); - virtual void quit(); virtual void setWindowCaption(const char *caption); - virtual void displayMessageOnOSD(const char *msg); virtual void showVirtualKeyboard(bool enable); virtual Audio::Mixer *getMixer(); diff --git a/backends/platform/android/events.cpp b/backends/platform/android/events.cpp index 634a84002f..465c6a1531 100644 --- a/backends/platform/android/events.cpp +++ b/backends/platform/android/events.cpp @@ -40,6 +40,7 @@ #define FORBIDDEN_SYMBOL_EXCEPTION_printf #include "backends/platform/android/android.h" +#include "backends/platform/android/graphics.h" #include "backends/platform/android/events.h" #include "backends/platform/android/jni.h" @@ -76,69 +77,6 @@ void OSystem_Android::setupKeymapper() { #endif } -void OSystem_Android::warpMouse(int x, int y) { - ENTER("%d, %d", x, y); - - Common::Event e; - - e.type = Common::EVENT_MOUSEMOVE; - e.mouse.x = x; - e.mouse.y = y; - - clipMouse(e.mouse); - - pushEvent(e); -} - -void OSystem_Android::clipMouse(Common::Point &p) { - const GLESBaseTexture *tex; - - if (_show_overlay) - tex = _overlay_texture; - else - tex = _game_texture; - - p.x = CLIP(p.x, int16(0), int16(tex->width() - 1)); - p.y = CLIP(p.y, int16(0), int16(tex->height() - 1)); -} - -void OSystem_Android::scaleMouse(Common::Point &p, int x, int y, - bool deductDrawRect, bool touchpadMode) { - const GLESBaseTexture *tex; - - if (_show_overlay) - tex = _overlay_texture; - else - tex = _game_texture; - - const Common::Rect &r = tex->getDrawRect(); - - if (touchpadMode) { - x = x * 100 / _touchpad_scale; - y = y * 100 / _touchpad_scale; - } - - if (deductDrawRect) { - x -= r.left; - y -= r.top; - } - - p.x = scalef(x, tex->width(), r.width()); - p.y = scalef(y, tex->height(), r.height()); -} - -void OSystem_Android::updateEventScale() { - const GLESBaseTexture *tex; - - if (_show_overlay) - tex = _overlay_texture; - else - tex = _game_texture; - - _eventScaleY = 100 * 480 / tex->height(); - _eventScaleX = 100 * 640 / tex->width(); -} - void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6) { Common::Event e; @@ -199,7 +137,7 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3, else e.type = Common::EVENT_RBUTTONUP; - e.mouse = getEventManager()->getMousePos(); + e.mouse = dynamic_cast(_graphicsManager)->getMousePosition(); pushEvent(e); @@ -324,7 +262,7 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3, e.type = Common::EVENT_MOUSEMOVE; - e.mouse = getEventManager()->getMousePos(); + e.mouse = dynamic_cast(_graphicsManager)->getMousePosition(); { int16 *c; @@ -348,8 +286,6 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3, *c += f; } - clipMouse(e.mouse); - pushEvent(e); return; @@ -367,7 +303,7 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3, return; } - e.mouse = getEventManager()->getMousePos(); + e.mouse = dynamic_cast(_graphicsManager)->getMousePosition(); pushEvent(e); @@ -375,7 +311,7 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3, } case JE_DOWN: - _touch_pt_down = getEventManager()->getMousePos(); + _touch_pt_down = dynamic_cast(_graphicsManager)->getMousePosition(); _touch_pt_scroll.x = -1; _touch_pt_scroll.y = -1; break; @@ -390,13 +326,13 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3, return; } - scaleMouse(e.mouse, arg3 - _touch_pt_scroll.x, - arg4 - _touch_pt_scroll.y, false, true); + e.mouse.x = (arg3 - _touch_pt_scroll.x) * 100 / _touchpad_scale; + e.mouse.y = (arg4 - _touch_pt_scroll.y) * 100 / _touchpad_scale; e.mouse += _touch_pt_down; - clipMouse(e.mouse); + } else { - scaleMouse(e.mouse, arg3, arg4); - clipMouse(e.mouse); + e.mouse.x = arg3; + e.mouse.y = arg4; } pushEvent(e); @@ -412,10 +348,10 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3, e.type = Common::EVENT_MOUSEMOVE; if (_touchpad_mode) { - e.mouse = getEventManager()->getMousePos(); + e.mouse = dynamic_cast(_graphicsManager)->getMousePosition(); } else { - scaleMouse(e.mouse, arg1, arg2); - clipMouse(e.mouse); + e.mouse.x = arg1; + e.mouse.y = arg2; } { @@ -457,10 +393,10 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3, e.type = Common::EVENT_MOUSEMOVE; if (_touchpad_mode) { - e.mouse = getEventManager()->getMousePos(); + e.mouse = dynamic_cast(_graphicsManager)->getMousePosition(); } else { - scaleMouse(e.mouse, arg1, arg2); - clipMouse(e.mouse); + e.mouse.x = arg1; + e.mouse.y = arg2; } { @@ -486,11 +422,9 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3, dptype = Common::EVENT_MOUSEMOVE; if (_touchpad_mode) { - scaleMouse(e.mouse, arg1 - _touch_pt_dt.x, - arg2 - _touch_pt_dt.y, false, true); + e.mouse.x = (arg1 - _touch_pt_dt.x) * 100 / _touchpad_scale; + e.mouse.y = (arg2 - _touch_pt_dt.y) * 100 / _touchpad_scale; e.mouse += _touch_pt_down; - - clipMouse(e.mouse); } break; @@ -537,7 +471,7 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3, return; } - e.mouse = getEventManager()->getMousePos(); + e.mouse = dynamic_cast(_graphicsManager)->getMousePosition(); lockMutex(_event_queue_lock); @@ -562,7 +496,7 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3, return; case JE_BALL: - e.mouse = getEventManager()->getMousePos(); + e.mouse = dynamic_cast(_graphicsManager)->getMousePosition(); switch (arg1) { case JACTION_DOWN: @@ -578,8 +512,6 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3, e.mouse.x += arg2 * _trackball_scale / _eventScaleX; e.mouse.y += arg3 * _trackball_scale / _eventScaleY; - clipMouse(e.mouse); - break; default: LOGE("unhandled jaction on system key: %d", arg1); @@ -592,9 +524,8 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3, case JE_MOUSE_MOVE: e.type = Common::EVENT_MOUSEMOVE; - - scaleMouse(e.mouse, arg1, arg2); - clipMouse(e.mouse); + e.mouse.x = arg1; + e.mouse.y = arg2; pushEvent(e); @@ -602,9 +533,8 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3, case JE_LMB_DOWN: e.type = Common::EVENT_LBUTTONDOWN; - - scaleMouse(e.mouse, arg1, arg2); - clipMouse(e.mouse); + e.mouse.x = arg1; + e.mouse.y = arg2; pushEvent(e); @@ -612,9 +542,8 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3, case JE_LMB_UP: e.type = Common::EVENT_LBUTTONUP; - - scaleMouse(e.mouse, arg1, arg2); - clipMouse(e.mouse); + e.mouse.x = arg1; + e.mouse.y = arg2; pushEvent(e); @@ -622,9 +551,8 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3, case JE_RMB_DOWN: e.type = Common::EVENT_RBUTTONDOWN; - - scaleMouse(e.mouse, arg1, arg2); - clipMouse(e.mouse); + e.mouse.x = arg1; + e.mouse.y = arg2; pushEvent(e); @@ -632,9 +560,8 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3, case JE_RMB_UP: e.type = Common::EVENT_RBUTTONUP; - - scaleMouse(e.mouse, arg1, arg2); - clipMouse(e.mouse); + e.mouse.x = arg1; + e.mouse.y = arg2; pushEvent(e); @@ -669,7 +596,7 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3, break; } - e.mouse = getEventManager()->getMousePos(); + e.mouse = dynamic_cast(_graphicsManager)->getMousePosition(); break; @@ -692,7 +619,7 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3, break; case JE_JOYSTICK: - e.mouse = getEventManager()->getMousePos(); + e.mouse = dynamic_cast(_graphicsManager)->getMousePosition(); switch (arg1) { case JACTION_MULTIPLE: @@ -702,8 +629,6 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3, e.mouse.x += arg2 * _joystick_scale / _eventScaleX; e.mouse.y += arg3 * _joystick_scale / _eventScaleY; - clipMouse(e.mouse); - break; default: LOGE("unhandled jaction on joystick: %d", arg1); @@ -745,23 +670,19 @@ bool OSystem_Android::pollEvent(Common::Event &event) { if (pthread_self() == _main_thread) { if (_screen_changeid != JNI::surface_changeid) { + _screen_changeid = JNI::surface_changeid; + if (JNI::egl_surface_width > 0 && JNI::egl_surface_height > 0) { // surface changed - JNI::deinitSurface(); - initSurface(); - initViewport(); - updateScreenRect(); - updateEventScale(); - - // double buffered, flip twice - clearScreen(kClearUpdate, 2); + dynamic_cast(_graphicsManager)->deinitSurface(); + dynamic_cast(_graphicsManager)->initSurface(); event.type = Common::EVENT_SCREEN_CHANGED; return true; } else { // surface lost - deinitSurface(); + dynamic_cast(_graphicsManager)->deinitSurface(); } } @@ -777,24 +698,28 @@ bool OSystem_Android::pollEvent(Common::Event &event) { if (_queuedEventTime && (getMillis() > _queuedEventTime)) { event = _queuedEvent; _queuedEventTime = 0; - unlockMutex(_event_queue_lock); - return true; - } - - if (_event_queue.empty()) { + // unlockMutex(_event_queue_lock); + // return true; + } else if (_event_queue.empty()) { unlockMutex(_event_queue_lock); return false; + } else { + event = _event_queue.pop(); } - event = _event_queue.pop(); - unlockMutex(_event_queue_lock); - if (event.type == Common::EVENT_MOUSEMOVE) { - const Common::Point &m = getEventManager()->getMousePos(); - - if (m != event.mouse) - _force_redraw = true; + switch (event.type) { + case Common::EVENT_MOUSEMOVE: + case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_LBUTTONUP: + case Common::EVENT_RBUTTONDOWN: + case Common::EVENT_RBUTTONUP: + if (_graphicsManager) + return dynamic_cast(_graphicsManager)->notifyMousePosition(event.mouse); + break; + default: + break; } return true; diff --git a/backends/platform/android/gfx.cpp b/backends/platform/android/gfx.cpp deleted file mode 100644 index 58c92adbdf..0000000000 --- a/backends/platform/android/gfx.cpp +++ /dev/null @@ -1,814 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#if defined(__ANDROID__) - -// Allow use of stuff in -#define FORBIDDEN_SYMBOL_EXCEPTION_time_h - -// Disable printf override in common/forbidden.h to avoid -// clashes with log.h from the Android SDK. -// That header file uses -// __attribute__ ((format(printf, 3, 4))) -// which gets messed up by our override mechanism; this could -// be avoided by either changing the Android SDK to use the equally -// legal and valid -// __attribute__ ((format(printf, 3, 4))) -// or by refining our printf override to use a varadic macro -// (which then wouldn't be portable, though). -// Anyway, for now we just disable the printf override globally -// for the Android port -#define FORBIDDEN_SYMBOL_EXCEPTION_printf - -#include "common/endian.h" -#include "graphics/conversion.h" - -#include "backends/platform/android/android.h" -#include "backends/platform/android/jni.h" - -static inline GLfixed xdiv(int numerator, int denominator) { - assert(numerator < (1 << 16)); - return (numerator << 16) / denominator; -} - -const OSystem::GraphicsMode *OSystem_Android::getSupportedGraphicsModes() const { - static const OSystem::GraphicsMode s_supportedGraphicsModes[] = { - { "default", "Default", 0 }, - { "filter", "Linear filtering", 1 }, - { 0, 0, 0 }, - }; - - return s_supportedGraphicsModes; -} - -int OSystem_Android::getDefaultGraphicsMode() const { - return 0; -} - -bool OSystem_Android::setGraphicsMode(int mode) { - ENTER("%d", mode); - - if (_game_texture) - _game_texture->setLinearFilter(mode == 1); - - if (_overlay_texture) - _overlay_texture->setLinearFilter(mode == 1); - - if (_mouse_texture) - _mouse_texture->setLinearFilter(mode == 1); - - _graphicsMode = mode; - - return true; -} - -int OSystem_Android::getGraphicsMode() const { - return _graphicsMode; -} - -#ifdef USE_RGB_COLOR -Graphics::PixelFormat OSystem_Android::getScreenFormat() const { - return _game_texture->getPixelFormat(); -} - -Common::List OSystem_Android::getSupportedFormats() const { - Common::List res; - res.push_back(GLES565Texture::pixelFormat()); - res.push_back(GLES5551Texture::pixelFormat()); - res.push_back(GLES8888Texture::pixelFormat()); - res.push_back(GLES4444Texture::pixelFormat()); - res.push_back(Graphics::PixelFormat::createFormatCLUT8()); - - return res; -} - -void OSystem_Android::initTexture(GLESBaseTexture **texture, - uint width, uint height, - const Graphics::PixelFormat *format) { - assert(texture); - Graphics::PixelFormat format_clut8 = - Graphics::PixelFormat::createFormatCLUT8(); - Graphics::PixelFormat format_current; - Graphics::PixelFormat format_new; - - if (*texture) - format_current = (*texture)->getPixelFormat(); - else - format_current = Graphics::PixelFormat(); - - if (format) - format_new = *format; - else - format_new = format_clut8; - - if (format_current != format_new) { - if (*texture) - LOGD("switching pixel format from: %s", - (*texture)->getPixelFormat().toString().c_str()); - - delete *texture; - - if (format_new == GLES565Texture::pixelFormat()) - *texture = new GLES565Texture(); - else if (format_new == GLES5551Texture::pixelFormat()) - *texture = new GLES5551Texture(); - else if (format_new == GLES8888Texture::pixelFormat()) - *texture = new GLES8888Texture(); - else if (format_new == GLES4444Texture::pixelFormat()) - *texture = new GLES4444Texture(); - else { - // TODO what now? - if (format_new != format_clut8) - LOGE("unsupported pixel format: %s", - format_new.toString().c_str()); - - *texture = new GLESFakePalette565Texture; - } - - LOGD("new pixel format: %s", - (*texture)->getPixelFormat().toString().c_str()); - } - - (*texture)->allocBuffer(width, height); -} -#endif - -void OSystem_Android::initSurface() { - LOGD("initializing surface"); - - assert(!JNI::haveSurface()); - - _screen_changeid = JNI::surface_changeid; - _egl_surface_width = JNI::egl_surface_width; - _egl_surface_height = JNI::egl_surface_height; - - assert(_egl_surface_width > 0 && _egl_surface_height > 0); - - JNI::initSurface(); - - // Initialize OpenGLES context. - GLESTexture::initGLExtensions(); - - if (_game_texture) - _game_texture->reinit(); - - if (_overlay_texture) { - _overlay_texture->reinit(); - initOverlay(); - } - - if (_mouse_texture) - _mouse_texture->reinit(); -} - -void OSystem_Android::deinitSurface() { - if (!JNI::haveSurface()) - return; - - LOGD("deinitializing surface"); - - _screen_changeid = JNI::surface_changeid; - _egl_surface_width = 0; - _egl_surface_height = 0; - - // release texture resources - if (_game_texture) - _game_texture->release(); - - if (_overlay_texture) - _overlay_texture->release(); - - if (_mouse_texture) - _mouse_texture->release(); - - JNI::deinitSurface(); -} - -void OSystem_Android::initViewport() { - LOGD("initializing viewport"); - - assert(JNI::haveSurface()); - - // Turn off anything that looks like 3D ;) - GLCALL(glDisable(GL_CULL_FACE)); - GLCALL(glDisable(GL_DEPTH_TEST)); - GLCALL(glDisable(GL_LIGHTING)); - GLCALL(glDisable(GL_FOG)); - GLCALL(glDisable(GL_DITHER)); - - GLCALL(glShadeModel(GL_FLAT)); - GLCALL(glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)); - - GLCALL(glEnable(GL_BLEND)); - GLCALL(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); - - GLCALL(glEnableClientState(GL_VERTEX_ARRAY)); - GLCALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY)); - - GLCALL(glEnable(GL_TEXTURE_2D)); - - GLCALL(glViewport(0, 0, _egl_surface_width, _egl_surface_height)); - - GLCALL(glMatrixMode(GL_PROJECTION)); - GLCALL(glLoadIdentity()); - GLCALL(glOrthof(0, _egl_surface_width, _egl_surface_height, 0, -1, 1)); - GLCALL(glMatrixMode(GL_MODELVIEW)); - GLCALL(glLoadIdentity()); - - clearFocusRectangle(); -} - -void OSystem_Android::initOverlay() { - // minimum of 320x200 - // (surface can get smaller when opening the virtual keyboard on *QVGA*) - int overlay_width = MAX(_egl_surface_width, 320); - int overlay_height = MAX(_egl_surface_height, 200); - - // the 'normal' theme layout uses a max height of 400 pixels. if the - // surface is too big we use only a quarter of the size so that the widgets - // don't get too small. if the surface height has less than 800 pixels, this - // enforces the 'lowres' layout, which will be scaled back up by factor 2x, - // but this looks way better than the 'normal' layout scaled by some - // calculated factors - while (overlay_height > 480) { - overlay_width /= 2; - overlay_height /= 2; - } - - LOGI("overlay size is %ux%u", overlay_width, overlay_height); - - _overlay_texture->allocBuffer(overlay_width, overlay_height); - _overlay_texture->setDrawRect(0, 0, - _egl_surface_width, _egl_surface_height); -} - -void OSystem_Android::initSize(uint width, uint height, - const Graphics::PixelFormat *format) { - ENTER("%d, %d, %p", width, height, format); - - GLTHREADCHECK; - -#ifdef USE_RGB_COLOR - initTexture(&_game_texture, width, height, format); -#else - _game_texture->allocBuffer(width, height); -#endif - - updateScreenRect(); - updateEventScale(); - - // Don't know mouse size yet - it gets reallocated in - // setMouseCursor. We need the palette allocated before - // setMouseCursor however, so just take a guess at the desired - // size (it's small). - _mouse_texture_palette->allocBuffer(20, 20); - - clearScreen(kClear); -} - -void OSystem_Android::clearScreen(FixupType type, byte count) { - assert(count > 0); - - bool sm = _show_mouse; - _show_mouse = false; - - GLCALL(glDisable(GL_SCISSOR_TEST)); - - for (byte i = 0; i < count; ++i) { - // clear screen - GLCALL(glClearColorx(0, 0, 0, 1 << 16)); - GLCALL(glClear(GL_COLOR_BUFFER_BIT)); - - switch (type) { - case kClear: - break; - - case kClearSwap: - JNI::swapBuffers(); - break; - - case kClearUpdate: - _force_redraw = true; - updateScreen(); - break; - } - } - - if (!_show_overlay) - GLCALL(glEnable(GL_SCISSOR_TEST)); - - _show_mouse = sm; - _force_redraw = true; -} - -void OSystem_Android::updateScreenRect() { - Common::Rect rect(0, 0, _egl_surface_width, _egl_surface_height); - - _overlay_texture->setDrawRect(rect); - - uint16 w = _game_texture->width(); - uint16 h = _game_texture->height(); - - if (w && h && !_fullscreen) { - if (_ar_correction && w == 320 && h == 200) - h = 240; - - float dpi[2]; - JNI::getDPI(dpi); - - float screen_ar; - if (dpi[0] != 0.0 && dpi[1] != 0.0) { - // horizontal orientation - screen_ar = (dpi[1] * _egl_surface_width) / - (dpi[0] * _egl_surface_height); - } else { - screen_ar = float(_egl_surface_width) / float(_egl_surface_height); - } - - float game_ar = float(w) / float(h); - - if (screen_ar > game_ar) { - rect.setWidth(round(_egl_surface_height * game_ar)); - rect.moveTo((_egl_surface_width - rect.width()) / 2, 0); - } else { - rect.setHeight(round(_egl_surface_width / game_ar)); - rect.moveTo((_egl_surface_height - rect.height()) / 2, 0); - } - } - - glScissor(rect.left, rect.top, rect.width(), rect.height()); - - _game_texture->setDrawRect(rect); -} - -int OSystem_Android::getScreenChangeID() const { - return _screen_changeid; -} - -int16 OSystem_Android::getHeight() { - return _game_texture->height(); -} - -int16 OSystem_Android::getWidth() { - return _game_texture->width(); -} - -void OSystem_Android::setPalette(const byte *colors, uint start, uint num) { - ENTER("%p, %u, %u", colors, start, num); - -#ifdef USE_RGB_COLOR - assert(_game_texture->hasPalette()); -#endif - - GLTHREADCHECK; - - if (!_use_mouse_palette) - setCursorPaletteInternal(colors, start, num); - - const Graphics::PixelFormat &pf = _game_texture->getPalettePixelFormat(); - byte *p = _game_texture->palette() + start * 2; - - for (uint i = 0; i < num; ++i, colors += 3, p += 2) - WRITE_UINT16(p, pf.RGBToColor(colors[0], colors[1], colors[2])); -} - -void OSystem_Android::grabPalette(byte *colors, uint start, uint num) const { - ENTER("%p, %u, %u", colors, start, num); - -#ifdef USE_RGB_COLOR - assert(_game_texture->hasPalette()); -#endif - - GLTHREADCHECK; - - const Graphics::PixelFormat &pf = _game_texture->getPalettePixelFormat(); - const byte *p = _game_texture->palette_const() + start * 2; - - for (uint i = 0; i < num; ++i, colors += 3, p += 2) - pf.colorToRGB(READ_UINT16(p), colors[0], colors[1], colors[2]); -} - -void OSystem_Android::copyRectToScreen(const void *buf, int pitch, - int x, int y, int w, int h) { - ENTER("%p, %d, %d, %d, %d, %d", buf, pitch, x, y, w, h); - - GLTHREADCHECK; - - _game_texture->updateBuffer(x, y, w, h, buf, pitch); -} - -void OSystem_Android::updateScreen() { - //ENTER(); - - GLTHREADCHECK; - - if (!JNI::haveSurface()) - return; - - if (!_force_redraw && - !_game_texture->dirty() && - !_overlay_texture->dirty() && - !_mouse_texture->dirty()) - return; - - _force_redraw = false; - - // clear pointer leftovers in dead areas - // also, HTC's GLES drivers are made of fail and don't preserve the buffer - // ( http://www.khronos.org/registry/egl/specs/EGLTechNote0001.html ) - if ((_show_overlay || _htc_fail) && !_fullscreen) - clearScreen(kClear); - - GLCALL(glPushMatrix()); - - if (_shake_offset != 0 || - (!_focus_rect.isEmpty() && - !Common::Rect(_game_texture->width(), - _game_texture->height()).contains(_focus_rect))) { - // These are the only cases where _game_texture doesn't - // cover the entire screen. - clearScreen(kClear); - - // Move everything up by _shake_offset (game) pixels - GLCALL(glTranslatex(0, -_shake_offset << 16, 0)); - } - -// TODO this doesn't work on those sucky drivers, do it differently -// if (_show_overlay) -// GLCALL(glColor4ub(0x9f, 0x9f, 0x9f, 0x9f)); - - if (_focus_rect.isEmpty()) { - _game_texture->drawTextureRect(); - } else { - GLCALL(glPushMatrix()); - - GLCALL(glScalex(xdiv(_egl_surface_width, _focus_rect.width()), - xdiv(_egl_surface_height, _focus_rect.height()), - 1 << 16)); - GLCALL(glTranslatex(-_focus_rect.left << 16, - -_focus_rect.top << 16, 0)); - GLCALL(glScalex(xdiv(_game_texture->width(), _egl_surface_width), - xdiv(_game_texture->height(), _egl_surface_height), - 1 << 16)); - - _game_texture->drawTextureRect(); - - GLCALL(glPopMatrix()); - } - - int cs = _mouse_targetscale; - - if (_show_overlay) { -// TODO see above -// GLCALL(glColor4ub(0xff, 0xff, 0xff, 0xff)); - - // ugly, but the modern theme sets a wacko factor, only god knows why - cs = 1; - - GLCALL(_overlay_texture->drawTextureRect()); - } - - if (_show_mouse && !_mouse_texture->isEmpty()) { - GLCALL(glPushMatrix()); - - const Common::Point &mouse = getEventManager()->getMousePos(); - - // Scale up ScummVM -> OpenGL (pixel) coordinates - if (_show_overlay) { - GLCALL(glScalex(xdiv(_egl_surface_width, - _overlay_texture->width()), - xdiv(_egl_surface_height, - _overlay_texture->height()), - 1 << 16)); - } else { - const Common::Rect &r = _game_texture->getDrawRect(); - - GLCALL(glTranslatex(r.left << 16, - r.top << 16, - 0)); - GLCALL(glScalex(xdiv(r.width(), _game_texture->width()), - xdiv(r.height(), _game_texture->height()), - 1 << 16)); - } - - GLCALL(glTranslatex((-_mouse_hotspot.x * cs) << 16, - (-_mouse_hotspot.y * cs) << 16, - 0)); - - // Note the extra half texel to position the mouse in - // the middle of the x,y square: - GLCALL(glTranslatex((mouse.x << 16) | 1 << 15, - (mouse.y << 16) | 1 << 15, 0)); - - GLCALL(glScalex(cs << 16, cs << 16, 1 << 16)); - - _mouse_texture->drawTextureOrigin(); - - GLCALL(glPopMatrix()); - } - - GLCALL(glPopMatrix()); - - if (!JNI::swapBuffers()) - LOGW("swapBuffers failed: 0x%x", glGetError()); -} - -Graphics::Surface *OSystem_Android::lockScreen() { - ENTER(); - - GLTHREADCHECK; - - Graphics::Surface *surface = _game_texture->surface(); - assert(surface->getPixels()); - - return surface; -} - -void OSystem_Android::unlockScreen() { - ENTER(); - - GLTHREADCHECK; - - assert(_game_texture->dirty()); -} - -void OSystem_Android::setShakePos(int shake_offset) { - ENTER("%d", shake_offset); - - if (_shake_offset != shake_offset) { - _shake_offset = shake_offset; - _force_redraw = true; - } -} - -void OSystem_Android::fillScreen(uint32 col) { - ENTER("%u", col); - - GLTHREADCHECK; - - _game_texture->fillBuffer(col); -} - -void OSystem_Android::setFocusRectangle(const Common::Rect& rect) { - ENTER("%d, %d, %d, %d", rect.left, rect.top, rect.right, rect.bottom); - - if (_enable_zoning) { - _focus_rect = rect; - _force_redraw = true; - } -} - -void OSystem_Android::clearFocusRectangle() { - ENTER(); - - if (_enable_zoning) { - _focus_rect = Common::Rect(); - _force_redraw = true; - } -} - -void OSystem_Android::showOverlay() { - ENTER(); - - _show_overlay = true; - _force_redraw = true; - - updateEventScale(); - - warpMouse(_overlay_texture->width() / 2, _overlay_texture->height() / 2); - - GLCALL(glDisable(GL_SCISSOR_TEST)); -} - -void OSystem_Android::hideOverlay() { - ENTER(); - - _show_overlay = false; - - updateEventScale(); - - warpMouse(_game_texture->width() / 2, _game_texture->height() / 2); - - // double buffered, flip twice - clearScreen(kClearUpdate, 2); - - GLCALL(glEnable(GL_SCISSOR_TEST)); -} - -void OSystem_Android::clearOverlay() { - ENTER(); - - GLTHREADCHECK; - - _overlay_texture->fillBuffer(0); -} - -void OSystem_Android::grabOverlay(void *buf, int pitch) { - ENTER("%p, %d", buf, pitch); - - GLTHREADCHECK; - - const Graphics::Surface *surface = _overlay_texture->surface_const(); - assert(surface->format.bytesPerPixel == sizeof(uint16)); - - byte *dst = (byte *)buf; - const byte *src = (const byte *)surface->getPixels(); - uint h = surface->h; - - do { - memcpy(dst, src, surface->w * surface->format.bytesPerPixel); - src += surface->pitch; - dst += pitch; - } while (--h); -} - -void OSystem_Android::copyRectToOverlay(const void *buf, int pitch, - int x, int y, int w, int h) { - ENTER("%p, %d, %d, %d, %d, %d", buf, pitch, x, y, w, h); - - GLTHREADCHECK; - - _overlay_texture->updateBuffer(x, y, w, h, buf, pitch); -} - -int16 OSystem_Android::getOverlayHeight() { - return _overlay_texture->height(); -} - -int16 OSystem_Android::getOverlayWidth() { - return _overlay_texture->width(); -} - -Graphics::PixelFormat OSystem_Android::getOverlayFormat() const { - return _overlay_texture->getPixelFormat(); -} - -bool OSystem_Android::showMouse(bool visible) { - ENTER("%d", visible); - - _show_mouse = visible; - - return true; -} - -void OSystem_Android::setMouseCursor(const void *buf, uint w, uint h, - int hotspotX, int hotspotY, - uint32 keycolor, bool dontScale, - const Graphics::PixelFormat *format) { - ENTER("%p, %u, %u, %d, %d, %u, %d, %p", buf, w, h, hotspotX, hotspotY, - keycolor, dontScale, format); - - GLTHREADCHECK; - -#ifdef USE_RGB_COLOR - if (format && format->bytesPerPixel > 1) { - if (_mouse_texture != _mouse_texture_rgb) { - LOGD("switching to rgb mouse cursor"); - - assert(!_mouse_texture_rgb); - _mouse_texture_rgb = new GLES5551Texture(); - _mouse_texture_rgb->setLinearFilter(_graphicsMode == 1); - } - - _mouse_texture = _mouse_texture_rgb; - } else { - if (_mouse_texture != _mouse_texture_palette) - LOGD("switching to paletted mouse cursor"); - - _mouse_texture = _mouse_texture_palette; - - delete _mouse_texture_rgb; - _mouse_texture_rgb = 0; - } -#endif - - _mouse_texture->allocBuffer(w, h); - - if (_mouse_texture == _mouse_texture_palette) { - assert(keycolor < 256); - - byte *p = _mouse_texture_palette->palette() + _mouse_keycolor * 2; - WRITE_UINT16(p, READ_UINT16(p) | 1); - - _mouse_keycolor = keycolor; - - p = _mouse_texture_palette->palette() + _mouse_keycolor * 2; - WRITE_UINT16(p, 0); - } - - if (w == 0 || h == 0) - return; - - if (_mouse_texture == _mouse_texture_palette) { - _mouse_texture->updateBuffer(0, 0, w, h, buf, w); - } else { - uint16 pitch = _mouse_texture->pitch(); - - byte *tmp = new byte[pitch * h]; - - // meh, a 16bit cursor without alpha bits... this is so silly - if (!crossBlit(tmp, (const byte *)buf, pitch, w * 2, w, h, - _mouse_texture->getPixelFormat(), - *format)) { - LOGE("crossblit failed"); - - delete[] tmp; - - _mouse_texture->allocBuffer(0, 0); - - return; - } - - const uint16 *s = (const uint16 *)buf; - uint16 *d = (uint16 *)tmp; - for (uint16 y = 0; y < h; ++y, d += pitch / 2 - w) - for (uint16 x = 0; x < w; ++x, d++) - if (*s++ == (keycolor & 0xffff)) - *d = 0; - - _mouse_texture->updateBuffer(0, 0, w, h, tmp, pitch); - - delete[] tmp; - } - - _mouse_hotspot = Common::Point(hotspotX, hotspotY); - // TODO: Adapt to the new "do not scale" cursor logic. - _mouse_targetscale = 1; -} - -void OSystem_Android::setCursorPaletteInternal(const byte *colors, - uint start, uint num) { - const Graphics::PixelFormat &pf = - _mouse_texture_palette->getPalettePixelFormat(); - byte *p = _mouse_texture_palette->palette() + start * 2; - - for (uint i = 0; i < num; ++i, colors += 3, p += 2) - WRITE_UINT16(p, pf.RGBToColor(colors[0], colors[1], colors[2])); - - p = _mouse_texture_palette->palette() + _mouse_keycolor * 2; - WRITE_UINT16(p, 0); -} - -void OSystem_Android::setCursorPalette(const byte *colors, - uint start, uint num) { - ENTER("%p, %u, %u", colors, start, num); - - GLTHREADCHECK; - - if (!_mouse_texture->hasPalette()) { - LOGD("switching to paletted mouse cursor"); - - _mouse_texture = _mouse_texture_palette; - - delete _mouse_texture_rgb; - _mouse_texture_rgb = 0; - } - - setCursorPaletteInternal(colors, start, num); - _use_mouse_palette = true; -} - -void OSystem_Android::disableCursorPalette() { - // when disabling the cursor palette, and we're running a clut8 game, - // it expects the game palette to be used for the cursor - if (_game_texture->hasPalette()) { - const byte *src = _game_texture->palette_const(); - byte *dst = _mouse_texture_palette->palette(); - - const Graphics::PixelFormat &pf_src = - _game_texture->getPalettePixelFormat(); - const Graphics::PixelFormat &pf_dst = - _mouse_texture_palette->getPalettePixelFormat(); - - uint8 r, g, b; - - for (uint i = 0; i < 256; ++i, src += 2, dst += 2) { - pf_src.colorToRGB(READ_UINT16(src), r, g, b); - WRITE_UINT16(dst, pf_dst.RGBToColor(r, g, b)); - } - - byte *p = _mouse_texture_palette->palette() + _mouse_keycolor * 2; - WRITE_UINT16(p, 0); - } -} - -#endif diff --git a/backends/platform/android/graphics.cpp b/backends/platform/android/graphics.cpp new file mode 100644 index 0000000000..c22e9bf326 --- /dev/null +++ b/backends/platform/android/graphics.cpp @@ -0,0 +1,134 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +// Allow use of stuff in +#define FORBIDDEN_SYMBOL_EXCEPTION_time_h + +// Disable printf override in common/forbidden.h to avoid +// clashes with log.h from the Android SDK. +// That header file uses +// __attribute__ ((format(printf, 3, 4))) +// which gets messed up by our override mechanism; this could +// be avoided by either changing the Android SDK to use the equally +// legal and valid +// __attribute__ ((format(printf, 3, 4))) +// or by refining our printf override to use a varadic macro +// (which then wouldn't be portable, though). +// Anyway, for now we just disable the printf override globally +// for the Android port +#define FORBIDDEN_SYMBOL_EXCEPTION_printf + +#include "backends/platform/android/android.h" +#include "backends/platform/android/graphics.h" +#include "backends/platform/android/jni.h" + +// +// AndroidGraphicsManager +// +AndroidGraphicsManager::AndroidGraphicsManager() { + ENTER(); + + // Initialize our OpenGL ES context. + initSurface(); + +} + +AndroidGraphicsManager::~AndroidGraphicsManager() { + ENTER(); + + deinitSurface(); +} + +void AndroidGraphicsManager::initSurface() { + LOGD("initializing surface"); + + assert(!JNI::haveSurface()); + JNI::initSurface(); + + // Notify the OpenGL code about our context. + // FIXME: Support OpenGL ES 2 contexts + setContextType(OpenGL::kContextGLES); + + // We default to RGB565 and RGBA5551 which is closest to the actual output + // mode we setup. + notifyContextCreate(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0)); + + handleResize(JNI::egl_surface_width, JNI::egl_surface_height); +} + +void AndroidGraphicsManager::deinitSurface() { + if (!JNI::haveSurface()) + return; + + LOGD("deinitializing surface"); + + notifyContextDestroy(); + + JNI::deinitSurface(); +} + +void AndroidGraphicsManager::updateScreen() { + //ENTER(); + + if (!JNI::haveSurface()) + return; + + OpenGLGraphicsManager::updateScreen(); +} + +void AndroidGraphicsManager::displayMessageOnOSD(const char *msg) { + ENTER("%s", msg); + + JNI::displayMessageOnOSD(msg); +} + +bool AndroidGraphicsManager::loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format) { + ENTER("%d, %d, %s", requestedWidth, requestedHeight, format.toString().c_str()); + + // We get this whenever a new resolution is requested. Since Android is + // using a fixed output size we do nothing like that here. + // TODO: Support screen rotation + return true; +} + +void AndroidGraphicsManager::refreshScreen() { + //ENTER(); + + JNI::swapBuffers(); +} + +void *AndroidGraphicsManager::getProcAddress(const char *name) const { + ENTER("%s", name); + + // TODO: Support dynamically loaded OpenGL + return nullptr; +} + +bool AndroidGraphicsManager::notifyMousePosition(Common::Point &mouse) { + mouse.x = CLIP(mouse.x, _activeArea.drawRect.left, _activeArea.drawRect.right); + mouse.y = CLIP(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/platform/android/graphics.h b/backends/platform/android/graphics.h new file mode 100644 index 0000000000..1b29b036b1 --- /dev/null +++ b/backends/platform/android/graphics.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 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef ANDROID_GRAPHICS_H +#define ANDROID_GRAPHICS_H + +#include "common/scummsys.h" +#include "backends/graphics/opengl/opengl-graphics.h" + +class AndroidGraphicsManager : public OpenGL::OpenGLGraphicsManager { +public: + AndroidGraphicsManager(); + virtual ~AndroidGraphicsManager(); + + void initSurface(); + void deinitSurface(); + + void updateScreen(); + + void displayMessageOnOSD(const char *msg); + + bool notifyMousePosition(Common::Point &mouse); + Common::Point getMousePosition() { return Common::Point(_cursorX, _cursorY); } + +protected: + void setSystemMousePosition(int x, int y) {} + + bool loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format); + + void refreshScreen(); + + void *getProcAddress(const char *name) const; + +}; + +#endif diff --git a/backends/platform/android/jni.cpp b/backends/platform/android/jni.cpp index 905423a5a6..5e4c116c82 100644 --- a/backends/platform/android/jni.cpp +++ b/backends/platform/android/jni.cpp @@ -111,8 +111,6 @@ const JNINativeMethod JNI::_natives[] = { (void *)JNI::main }, { "pushEvent", "(IIIIIII)V", (void *)JNI::pushEvent }, - { "enableZoning", "(Z)V", - (void *)JNI::enableZoning }, { "setPause", "(Z)V", (void *)JNI::setPause }, { "getCurrentCharset", "()Ljava/lang/String;", @@ -662,12 +660,6 @@ void JNI::pushEvent(JNIEnv *env, jobject self, int type, int arg1, int arg2, _system->pushEvent(type, arg1, arg2, arg3, arg4, arg5, arg6); } -void JNI::enableZoning(JNIEnv *env, jobject self, jboolean enable) { - assert(_system); - - _system->enableZoning(enable); -} - void JNI::setPause(JNIEnv *env, jobject self, jboolean value) { if (!_system) return; diff --git a/backends/platform/android/jni.h b/backends/platform/android/jni.h index aa89174dfc..b6e5df819e 100644 --- a/backends/platform/android/jni.h +++ b/backends/platform/android/jni.h @@ -132,8 +132,6 @@ private: static void pushEvent(JNIEnv *env, jobject self, int type, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6); - static void enableZoning(JNIEnv *env, jobject self, jboolean enable); - static void setPause(JNIEnv *env, jobject self, jboolean value); static jstring getCurrentCharset(JNIEnv *env, jobject self); diff --git a/backends/platform/android/module.mk b/backends/platform/android/module.mk index de5fe98a53..6a0721b4a9 100644 --- a/backends/platform/android/module.mk +++ b/backends/platform/android/module.mk @@ -2,10 +2,9 @@ MODULE := backends/platform/android MODULE_OBJS := \ jni.o \ - texture.o \ asset-archive.o \ android.o \ - gfx.o \ + graphics.o \ events.o # We don't use rules.mk but rather manually update OBJS and MODULE_DIRS. diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVM.java b/backends/platform/android/org/scummvm/scummvm/ScummVM.java index 37fe76ebda..2784623449 100644 --- a/backends/platform/android/org/scummvm/scummvm/ScummVM.java +++ b/backends/platform/android/org/scummvm/scummvm/ScummVM.java @@ -45,7 +45,6 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable { // pause the engine and all native threads final public native void setPause(boolean pause); - final public native void enableZoning(boolean enable); // Feed an event to ScummVM. Safe to call from other threads. final public native void pushEvent(int type, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6); diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java index 7bb0fe8057..f353ceab27 100644 --- a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java +++ b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java @@ -53,30 +53,8 @@ public class ScummVMActivity extends Activity { }; private class MyScummVM extends ScummVM { - private boolean usingSmallScreen() { - // Multiple screen sizes came in with Android 1.6. Have - // to use reflection in order to continue supporting 1.5 - // devices :( - DisplayMetrics metrics = new DisplayMetrics(); - getWindowManager().getDefaultDisplay().getMetrics(metrics); - - try { - // This 'density' term is very confusing. - int DENSITY_LOW = metrics.getClass().getField("DENSITY_LOW").getInt(null); - int densityDpi = metrics.getClass().getField("densityDpi").getInt(metrics); - return densityDpi <= DENSITY_LOW; - } catch (Exception e) { - return false; - } - } - public MyScummVM(SurfaceHolder holder) { super(ScummVMActivity.this.getAssets(), holder); - - // Enable ScummVM zoning on 'small' screens. - // FIXME make this optional for the user - // disabled for now since it crops too much - //enableZoning(usingSmallScreen()); } @Override diff --git a/backends/platform/android/texture.cpp b/backends/platform/android/texture.cpp deleted file mode 100644 index f8c09bfb43..0000000000 --- a/backends/platform/android/texture.cpp +++ /dev/null @@ -1,476 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#if defined(__ANDROID__) - -// Allow use of stuff in -#define FORBIDDEN_SYMBOL_EXCEPTION_time_h - -// Disable printf override in common/forbidden.h to avoid -// clashes with log.h from the Android SDK. -// That header file uses -// __attribute__ ((format(printf, 3, 4))) -// which gets messed up by our override mechanism; this could -// be avoided by either changing the Android SDK to use the equally -// legal and valid -// __attribute__ ((format(printf, 3, 4))) -// or by refining our printf override to use a varadic macro -// (which then wouldn't be portable, though). -// Anyway, for now we just disable the printf override globally -// for the Android port -#define FORBIDDEN_SYMBOL_EXCEPTION_printf - -#include "base/main.h" -#include "graphics/surface.h" - -#include "common/rect.h" -#include "common/array.h" -#include "common/util.h" -#include "common/tokenizer.h" - -#include "backends/platform/android/texture.h" -#include "backends/platform/android/android.h" - -// Supported GL extensions -static bool npot_supported = false; - -static inline GLfixed xdiv(int numerator, int denominator) { - assert(numerator < (1 << 16)); - return (numerator << 16) / denominator; -} - -template -static T nextHigher2(T k) { - if (k == 0) - return 1; - --k; - - for (uint i = 1; i < sizeof(T) * CHAR_BIT; i <<= 1) - k = k | k >> i; - - return k + 1; -} - -void GLESBaseTexture::initGLExtensions() { - const char *ext_string = - reinterpret_cast(glGetString(GL_EXTENSIONS)); - - LOGI("Extensions: %s", ext_string); - - Common::StringTokenizer tokenizer(ext_string, " "); - while (!tokenizer.empty()) { - Common::String token = tokenizer.nextToken(); - - if (token == "GL_ARB_texture_non_power_of_two") - npot_supported = true; - } -} - -GLESBaseTexture::GLESBaseTexture(GLenum glFormat, GLenum glType, - Graphics::PixelFormat pixelFormat) : - _glFormat(glFormat), - _glType(glType), - _glFilter(GL_NEAREST), - _texture_name(0), - _surface(), - _texture_width(0), - _texture_height(0), - _draw_rect(), - _all_dirty(false), - _dirty_rect(), - _pixelFormat(pixelFormat), - _palettePixelFormat() -{ - GLCALL(glGenTextures(1, &_texture_name)); -} - -GLESBaseTexture::~GLESBaseTexture() { - release(); -} - -void GLESBaseTexture::release() { - if (_texture_name) { - LOGD("Destroying texture %u", _texture_name); - - GLCALL(glDeleteTextures(1, &_texture_name)); - _texture_name = 0; - } -} - -void GLESBaseTexture::reinit() { - GLCALL(glGenTextures(1, &_texture_name)); - - initSize(); - - setDirty(); -} - -void GLESBaseTexture::initSize() { - // Allocate room for the texture now, but pixel data gets uploaded - // later (perhaps with multiple TexSubImage2D operations). - GLCALL(glBindTexture(GL_TEXTURE_2D, _texture_name)); - GLCALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); - GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _glFilter)); - GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _glFilter)); - GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); - GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); - GLCALL(glTexImage2D(GL_TEXTURE_2D, 0, _glFormat, - _texture_width, _texture_height, - 0, _glFormat, _glType, 0)); -} - -void GLESBaseTexture::setLinearFilter(bool value) { - if (value) - _glFilter = GL_LINEAR; - else - _glFilter = GL_NEAREST; - - GLCALL(glBindTexture(GL_TEXTURE_2D, _texture_name)); - - GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _glFilter)); - GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _glFilter)); -} - -void GLESBaseTexture::allocBuffer(GLuint w, GLuint h) { - _surface.w = w; - _surface.h = h; - _surface.format = _pixelFormat; - - if (w == _texture_width && h == _texture_height) - return; - - if (npot_supported) { - _texture_width = _surface.w; - _texture_height = _surface.h; - } else { - _texture_width = nextHigher2(_surface.w); - _texture_height = nextHigher2(_surface.h); - } - - initSize(); -} - -void GLESBaseTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) { - GLCALL(glBindTexture(GL_TEXTURE_2D, _texture_name)); - - const GLfixed tex_width = xdiv(_surface.w, _texture_width); - const GLfixed tex_height = xdiv(_surface.h, _texture_height); - const GLfixed texcoords[] = { - 0, 0, - tex_width, 0, - 0, tex_height, - tex_width, tex_height, - }; - - GLCALL(glTexCoordPointer(2, GL_FIXED, 0, texcoords)); - - const GLshort vertices[] = { - x, y, - GLshort(x + w), y, - x, GLshort(y + h), - GLshort(x + w), GLshort(y + h) - }; - - GLCALL(glVertexPointer(2, GL_SHORT, 0, vertices)); - - assert(ARRAYSIZE(vertices) == ARRAYSIZE(texcoords)); - GLCALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, ARRAYSIZE(vertices) / 2)); - - clearDirty(); -} - -const Graphics::PixelFormat &GLESBaseTexture::getPixelFormat() const { - return _pixelFormat; -} - -GLESTexture::GLESTexture(GLenum glFormat, GLenum glType, - Graphics::PixelFormat pixelFormat) : - GLESBaseTexture(glFormat, glType, pixelFormat), - _pixels(0), - _buf(0) { -} - -GLESTexture::~GLESTexture() { - delete[] _buf; - delete[] _pixels; -} - -void GLESTexture::allocBuffer(GLuint w, GLuint h) { - GLuint oldw = _surface.w; - GLuint oldh = _surface.h; - - GLESBaseTexture::allocBuffer(w, h); - - _surface.pitch = w * _pixelFormat.bytesPerPixel; - - if (_surface.w == oldw && _surface.h == oldh) { - fillBuffer(0); - return; - } - - delete[] _buf; - delete[] _pixels; - - _pixels = new byte[w * h * _surface.format.bytesPerPixel]; - assert(_pixels); - - _surface.setPixels(_pixels); - - fillBuffer(0); - - _buf = new byte[w * h * _surface.format.bytesPerPixel]; - assert(_buf); -} - -void GLESTexture::updateBuffer(GLuint x, GLuint y, GLuint w, GLuint h, - const void *buf, int pitch_buf) { - setDirtyRect(Common::Rect(x, y, x + w, y + h)); - - const byte *src = (const byte *)buf; - byte *dst = _pixels + y * _surface.pitch + x * _surface.format.bytesPerPixel; - - do { - memcpy(dst, src, w * _surface.format.bytesPerPixel); - dst += _surface.pitch; - src += pitch_buf; - } while (--h); -} - -void GLESTexture::fillBuffer(uint32 color) { - assert(_surface.getPixels()); - - if (_pixelFormat.bytesPerPixel == 1 || - (_pixelFormat.bytesPerPixel == 2 && - ((color & 0xff) == ((color >> 8) & 0xff)))) - memset(_pixels, color & 0xff, _surface.pitch * _surface.h); - else if (_pixelFormat.bytesPerPixel == 2) - Common::fill((uint16 *)_pixels, (uint16 *)(_pixels + _surface.pitch * _surface.h), - (uint16)color); - else - Common::fill((uint32 *)_pixels, (uint32 *)(_pixels + _surface.pitch * _surface.h), - color); - - setDirty(); -} - -void GLESTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) { - if (_all_dirty) { - _dirty_rect.top = 0; - _dirty_rect.left = 0; - _dirty_rect.bottom = _surface.h; - _dirty_rect.right = _surface.w; - - _all_dirty = false; - } - - if (!_dirty_rect.isEmpty()) { - byte *_tex; - - int16 dwidth = _dirty_rect.width(); - int16 dheight = _dirty_rect.height(); - - if (dwidth == _surface.w) { - _tex = _pixels + _dirty_rect.top * _surface.pitch; - } else { - _tex = _buf; - - byte *src = _pixels + _dirty_rect.top * _surface.pitch + - _dirty_rect.left * _surface.format.bytesPerPixel; - byte *dst = _buf; - - uint16 l = dwidth * _surface.format.bytesPerPixel; - - for (uint16 i = 0; i < dheight; ++i) { - memcpy(dst, src, l); - src += _surface.pitch; - dst += l; - } - } - - GLCALL(glBindTexture(GL_TEXTURE_2D, _texture_name)); - GLCALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); - - GLCALL(glTexSubImage2D(GL_TEXTURE_2D, 0, - _dirty_rect.left, _dirty_rect.top, - dwidth, dheight, _glFormat, _glType, _tex)); - } - - GLESBaseTexture::drawTexture(x, y, w, h); -} - -GLES4444Texture::GLES4444Texture() : - GLESTexture(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixelFormat()) { -} - -GLES4444Texture::~GLES4444Texture() { -} - -GLES5551Texture::GLES5551Texture() : - GLESTexture(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, pixelFormat()) { -} - -GLES5551Texture::~GLES5551Texture() { -} - -GLES565Texture::GLES565Texture() : - GLESTexture(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixelFormat()) { -} - -GLES565Texture::~GLES565Texture() { -} - -GLES8888Texture::GLES8888Texture() : - GLESTexture(GL_RGBA, GL_UNSIGNED_BYTE, pixelFormat()) { -} - -GLES8888Texture::~GLES8888Texture() { -} - -GLESFakePaletteTexture::GLESFakePaletteTexture(GLenum glFormat, GLenum glType, - Graphics::PixelFormat pixelFormat) : - GLESBaseTexture(glFormat, glType, pixelFormat), - _palette(0), - _pixels(0), - _buf(0) -{ - _palettePixelFormat = pixelFormat; - _fake_format = Graphics::PixelFormat::createFormatCLUT8(); - - _palette = new uint16[256]; - assert(_palette); - - memset(_palette, 0, 256 * 2); -} - -GLESFakePaletteTexture::~GLESFakePaletteTexture() { - delete[] _buf; - delete[] _pixels; - delete[] _palette; -} - -void GLESFakePaletteTexture::allocBuffer(GLuint w, GLuint h) { - GLuint oldw = _surface.w; - GLuint oldh = _surface.h; - - GLESBaseTexture::allocBuffer(w, h); - - _surface.format = Graphics::PixelFormat::createFormatCLUT8(); - _surface.pitch = w; - - if (_surface.w == oldw && _surface.h == oldh) { - fillBuffer(0); - return; - } - - delete[] _buf; - delete[] _pixels; - - _pixels = new byte[w * h]; - assert(_pixels); - - // fixup surface, for the outside this is a CLUT8 surface - _surface.setPixels(_pixels); - - fillBuffer(0); - - _buf = new uint16[w * h]; - assert(_buf); -} - -void GLESFakePaletteTexture::fillBuffer(uint32 color) { - assert(_surface.getPixels()); - memset(_surface.getPixels(), color & 0xff, _surface.pitch * _surface.h); - setDirty(); -} - -void GLESFakePaletteTexture::updateBuffer(GLuint x, GLuint y, GLuint w, - GLuint h, const void *buf, - int pitch_buf) { - setDirtyRect(Common::Rect(x, y, x + w, y + h)); - - const byte *src = (const byte *)buf; - byte *dst = _pixels + y * _surface.pitch + x; - - do { - memcpy(dst, src, w); - dst += _surface.pitch; - src += pitch_buf; - } while (--h); -} - -void GLESFakePaletteTexture::drawTexture(GLshort x, GLshort y, GLshort w, - GLshort h) { - if (_all_dirty) { - _dirty_rect.top = 0; - _dirty_rect.left = 0; - _dirty_rect.bottom = _surface.h; - _dirty_rect.right = _surface.w; - - _all_dirty = false; - } - - if (!_dirty_rect.isEmpty()) { - int16 dwidth = _dirty_rect.width(); - int16 dheight = _dirty_rect.height(); - - byte *src = _pixels + _dirty_rect.top * _surface.pitch + - _dirty_rect.left; - uint16 *dst = _buf; - uint pitch_delta = _surface.pitch - dwidth; - - for (uint16 j = 0; j < dheight; ++j) { - for (uint16 i = 0; i < dwidth; ++i) - *dst++ = _palette[*src++]; - src += pitch_delta; - } - - GLCALL(glBindTexture(GL_TEXTURE_2D, _texture_name)); - - GLCALL(glTexSubImage2D(GL_TEXTURE_2D, 0, - _dirty_rect.left, _dirty_rect.top, - dwidth, dheight, _glFormat, _glType, _buf)); - } - - GLESBaseTexture::drawTexture(x, y, w, h); -} - -const Graphics::PixelFormat &GLESFakePaletteTexture::getPixelFormat() const { - return _fake_format; -} - -GLESFakePalette565Texture::GLESFakePalette565Texture() : - GLESFakePaletteTexture(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, - GLES565Texture::pixelFormat()) { -} - -GLESFakePalette565Texture::~GLESFakePalette565Texture() { -} - -GLESFakePalette5551Texture::GLESFakePalette5551Texture() : - GLESFakePaletteTexture(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, - GLES5551Texture::pixelFormat()) { -} - -GLESFakePalette5551Texture::~GLESFakePalette5551Texture() { -} - -#endif diff --git a/backends/platform/android/texture.h b/backends/platform/android/texture.h deleted file mode 100644 index 4b05dfd5d4..0000000000 --- a/backends/platform/android/texture.h +++ /dev/null @@ -1,285 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef _ANDROID_TEXTURE_H_ -#define _ANDROID_TEXTURE_H_ - -#if defined(__ANDROID__) - -#include - -#include "graphics/surface.h" -#include "graphics/pixelformat.h" - -#include "common/rect.h" -#include "common/array.h" - -class GLESBaseTexture { -public: - static void initGLExtensions(); - -protected: - GLESBaseTexture(GLenum glFormat, GLenum glType, - Graphics::PixelFormat pixelFormat); - -public: - virtual ~GLESBaseTexture(); - - void release(); - void reinit(); - void initSize(); - - void setLinearFilter(bool value); - - virtual void allocBuffer(GLuint w, GLuint h); - - virtual void updateBuffer(GLuint x, GLuint y, GLuint width, GLuint height, - const void *buf, int pitch_buf) = 0; - virtual void fillBuffer(uint32 color) = 0; - - virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h); - - inline void setDrawRect(const Common::Rect &rect) { - _draw_rect = rect; - } - - inline void setDrawRect(int16 w, int16 h) { - _draw_rect = Common::Rect(w, h); - } - - inline void setDrawRect(int16 x1, int16 y1, int16 x2, int16 y2) { - _draw_rect = Common::Rect(x1, y1, x2, y2); - } - - inline const Common::Rect &getDrawRect() const { - return _draw_rect; - } - - inline void drawTextureRect() { - drawTexture(_draw_rect.left, _draw_rect.top, - _draw_rect.width(), _draw_rect.height()); - } - - inline void drawTextureOrigin() { - drawTexture(0, 0, _surface.w, _surface.h); - } - - inline GLuint width() const { - return _surface.w; - } - - inline GLuint height() const { - return _surface.h; - } - - inline uint16 pitch() const { - return _surface.pitch; - } - - inline bool isEmpty() const { - return _surface.w == 0 || _surface.h == 0; - } - - inline const Graphics::Surface *surface_const() const { - return &_surface; - } - - inline Graphics::Surface *surface() { - setDirty(); - return &_surface; - } - - virtual const byte *palette_const() const { - return 0; - }; - - virtual byte *palette() { - return 0; - }; - - inline bool hasPalette() const { - return _palettePixelFormat.bytesPerPixel > 0; - } - - inline bool dirty() const { - return _all_dirty || !_dirty_rect.isEmpty(); - } - - virtual const Graphics::PixelFormat &getPixelFormat() const; - - inline const Graphics::PixelFormat &getPalettePixelFormat() const { - return _palettePixelFormat; - } - -protected: - inline void setDirty() { - _all_dirty = true; - } - - inline void clearDirty() { - _all_dirty = false; - _dirty_rect.top = 0; - _dirty_rect.left = 0; - _dirty_rect.bottom = 0; - _dirty_rect.right = 0; - } - - inline void setDirtyRect(const Common::Rect& r) { - if (!_all_dirty) { - if (_dirty_rect.isEmpty()) - _dirty_rect = r; - else - _dirty_rect.extend(r); - } - } - - GLenum _glFormat; - GLenum _glType; - GLint _glFilter; - - GLuint _texture_name; - Graphics::Surface _surface; - GLuint _texture_width; - GLuint _texture_height; - - Common::Rect _draw_rect; - - bool _all_dirty; - Common::Rect _dirty_rect; - - Graphics::PixelFormat _pixelFormat; - Graphics::PixelFormat _palettePixelFormat; -}; - -class GLESTexture : public GLESBaseTexture { -protected: - GLESTexture(GLenum glFormat, GLenum glType, - Graphics::PixelFormat pixelFormat); - -public: - virtual ~GLESTexture(); - - virtual void allocBuffer(GLuint w, GLuint h); - - virtual void updateBuffer(GLuint x, GLuint y, GLuint width, GLuint height, - const void *buf, int pitch_buf); - virtual void fillBuffer(uint32 color); - - virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h); - -protected: - byte *_pixels; - byte *_buf; -}; - -// RGBA4444 texture -class GLES4444Texture : public GLESTexture { -public: - GLES4444Texture(); - virtual ~GLES4444Texture(); - - static Graphics::PixelFormat pixelFormat() { - return Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0); - } -}; - -// RGBA5551 texture -class GLES5551Texture : public GLESTexture { -public: - GLES5551Texture(); - virtual ~GLES5551Texture(); - - static inline Graphics::PixelFormat pixelFormat() { - return Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0); - } -}; - -// RGB565 texture -class GLES565Texture : public GLESTexture { -public: - GLES565Texture(); - virtual ~GLES565Texture(); - - static inline Graphics::PixelFormat pixelFormat() { - return Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); - } -}; - -// RGBA8888 texture -class GLES8888Texture : public GLESTexture { -public: - GLES8888Texture(); - virtual ~GLES8888Texture(); - - static inline Graphics::PixelFormat pixelFormat() { - // We assume LE since all Android platforms are LE. - return Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24); - } -}; - -class GLESFakePaletteTexture : public GLESBaseTexture { -protected: - GLESFakePaletteTexture(GLenum glFormat, GLenum glType, - Graphics::PixelFormat pixelFormat); - -public: - virtual ~GLESFakePaletteTexture(); - - virtual void allocBuffer(GLuint w, GLuint h); - virtual void updateBuffer(GLuint x, GLuint y, GLuint width, GLuint height, - const void *buf, int pitch_buf); - virtual void fillBuffer(uint32 color); - - virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h); - - virtual const byte *palette_const() const { - return (byte *)_palette; - }; - - virtual byte *palette() { - setDirty(); - return (byte *)_palette; - }; - - virtual const Graphics::PixelFormat &getPixelFormat() const; - -protected: - Graphics::PixelFormat _fake_format; - uint16 *_palette; - byte *_pixels; - uint16 *_buf; -}; - -class GLESFakePalette565Texture : public GLESFakePaletteTexture { -public: - GLESFakePalette565Texture(); - virtual ~GLESFakePalette565Texture(); -}; - -class GLESFakePalette5551Texture : public GLESFakePaletteTexture { -public: - GLESFakePalette5551Texture(); - virtual ~GLESFakePalette5551Texture(); -}; - -#endif -#endif -- cgit v1.2.3