aboutsummaryrefslogtreecommitdiff
path: root/backends/platform
diff options
context:
space:
mode:
Diffstat (limited to 'backends/platform')
-rw-r--r--backends/platform/android/android.cpp596
-rw-r--r--backends/platform/android/android.mk18
-rw-r--r--backends/platform/android/asset-archive.cpp166
-rw-r--r--backends/platform/android/video.cpp85
-rw-r--r--backends/platform/android/video.h128
5 files changed, 663 insertions, 330 deletions
diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp
index 125fd629d3..6566146313 100644
--- a/backends/platform/android/android.cpp
+++ b/backends/platform/android/android.cpp
@@ -78,14 +78,14 @@
extern "C" {
void __assert(const char *file, int line, const char *expr) {
__android_log_assert(expr, LOG_TAG,
- "Assertion failure: '%s' in %s:%d",
- expr, file, line);
+ "Assertion failure: '%s' in %s:%d",
+ expr, file, line);
}
void __assert2(const char *file, int line, const char *func, const char *expr) {
__android_log_assert(expr, LOG_TAG,
- "Assertion failure: '%s' in %s:%d (%s)",
- expr, file, line, func);
+ "Assertion failure: '%s' in %s:%d (%s)",
+ expr, file, line, func);
}
}
@@ -105,6 +105,7 @@ JNIEnv *JNU_GetEnv() {
JNIEnv *env = 0;
jint res = cached_jvm->GetEnv((void **)&env, JNI_VERSION_1_2);
+
if (res != JNI_OK) {
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "GetEnv() failed: %d", res);
abort();
@@ -113,15 +114,17 @@ JNIEnv *JNU_GetEnv() {
return env;
}
-static void JNU_ThrowByName(JNIEnv* env, const char* name, const char* msg) {
+static void JNU_ThrowByName(JNIEnv *env, const char *name, const char *msg) {
jclass cls = env->FindClass(name);
- // if cls is NULL, an exception has already been thrown
- if (cls != NULL)
+
+ // if cls is 0, an exception has already been thrown
+ if (cls != 0)
env->ThrowNew(cls, msg);
+
env->DeleteLocalRef(cls);
}
-// floating point. use sparingly.
+// floating point. use sparingly
template <class T>
static inline T scalef(T in, float numerator, float denominator) {
return static_cast<float>(in) * numerator / denominator;
@@ -139,10 +142,9 @@ protected:
};
#endif
-
#if 0
#define CHECK_GL_ERROR() checkGlError(__FILE__, __LINE__)
-static const char* getGlErrStr(GLenum error) {
+static const char *getGlErrStr(GLenum error) {
switch (error) {
case GL_NO_ERROR: return "GL_NO_ERROR";
case GL_INVALID_ENUM: return "GL_INVALID_ENUM";
@@ -156,7 +158,7 @@ static const char* getGlErrStr(GLenum error) {
snprintf(buf, sizeof(buf), "(Unknown GL error code 0x%x)", error);
return buf;
}
-static void checkGlError(const char* file, int line) {
+static void checkGlError(const char *file, int line) {
GLenum error = glGetError();
if (error != GL_NO_ERROR)
warning("%s:%d: GL error: %s", file, line, getGlErrStr(error));
@@ -167,7 +169,9 @@ static void checkGlError(const char* file, int line) {
class OSystem_Android : public BaseBackend, public PaletteManager {
private:
- jobject _back_ptr; // back pointer to (java) peer instance
+ // back pointer to (java) peer instance
+ jobject _back_ptr;
+
jmethodID MID_displayMessageOnOSD;
jmethodID MID_setWindowCaption;
jmethodID MID_initBackend;
@@ -186,16 +190,16 @@ private:
bool _force_redraw;
// Game layer
- GLESPaletteTexture* _game_texture;
+ GLESPaletteTexture *_game_texture;
int _shake_offset;
Common::Rect _focus_rect;
// Overlay layer
- GLES4444Texture* _overlay_texture;
+ GLES4444Texture *_overlay_texture;
bool _show_overlay;
// Mouse layer
- GLESPaletteATexture* _mouse_texture;
+ GLESPaletteATexture *_mouse_texture;
Common::Point _mouse_hotspot;
int _mouse_targetscale;
bool _show_mouse;
@@ -206,7 +210,7 @@ private:
bool _timer_thread_exit;
pthread_t _timer_thread;
- static void* timerThreadFunc(void* arg);
+ static void *timerThreadFunc(void *arg);
bool _enable_zoning;
bool _virtkeybd_on;
@@ -226,9 +230,9 @@ private:
public:
OSystem_Android(jobject am);
virtual ~OSystem_Android();
- bool initJavaHooks(JNIEnv* env, jobject self);
+ bool initJavaHooks(JNIEnv *env, jobject self);
- static OSystem_Android* fromJavaObject(JNIEnv* env, jobject obj);
+ static OSystem_Android *fromJavaObject(JNIEnv *env, jobject obj);
virtual void initBackend();
void addPluginDirectories(Common::FSList &dirs) const;
void enableZoning(bool enable) { _enable_zoning = enable; }
@@ -246,12 +250,19 @@ public:
virtual bool setGraphicsMode(int mode);
virtual int getGraphicsMode() const;
virtual void initSize(uint width, uint height,
- const Graphics::PixelFormat *format);
- virtual int getScreenChangeID() const { return _screen_changeid; }
+ const Graphics::PixelFormat *format);
+
+ virtual int getScreenChangeID() const {
+ return _screen_changeid;
+ }
+
virtual int16 getHeight();
virtual int16 getWidth();
- virtual PaletteManager *getPaletteManager() { return this; }
+ virtual PaletteManager *getPaletteManager() {
+ return this;
+ }
+
protected:
// PaletteManager API
virtual void setPalette(const byte *colors, uint start, uint num);
@@ -274,18 +285,21 @@ public:
virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
virtual int16 getOverlayHeight();
virtual int16 getOverlayWidth();
+
+ // RGBA 4444
virtual Graphics::PixelFormat getOverlayFormat() const {
- // RGBA 4444
Graphics::PixelFormat format;
+
format.bytesPerPixel = 2;
format.rLoss = 8 - 4;
format.gLoss = 8 - 4;
format.bLoss = 8 - 4;
format.aLoss = 8 - 4;
- format.rShift = 3*4;
- format.gShift = 2*4;
- format.bShift = 1*4;
- format.aShift = 0*4;
+ format.rShift = 3 * 4;
+ format.gShift = 2 * 4;
+ format.bShift = 1 * 4;
+ format.aShift = 0 * 4;
+
return format;
}
@@ -321,49 +335,54 @@ public:
virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0);
};
-OSystem_Android::OSystem_Android(jobject am)
- : _back_ptr(0),
- _screen_changeid(0),
- _force_redraw(false),
- _game_texture(NULL),
- _overlay_texture(NULL),
- _mouse_texture(NULL),
- _use_mouse_palette(false),
- _show_mouse(false),
- _show_overlay(false),
- _enable_zoning(false),
- _savefile(0),
- _mixer(0),
- _timer(0),
- _fsFactory(new POSIXFilesystemFactory()),
- _asset_archive(new AndroidAssetArchive(am)),
- _shake_offset(0),
- _event_queue_lock(createMutex()) {
+OSystem_Android::OSystem_Android(jobject am) :
+ _back_ptr(0),
+ _screen_changeid(0),
+ _force_redraw(false),
+ _game_texture(0),
+ _overlay_texture(0),
+ _mouse_texture(0),
+ _use_mouse_palette(false),
+ _show_mouse(false),
+ _show_overlay(false),
+ _enable_zoning(false),
+ _savefile(0),
+ _mixer(0),
+ _timer(0),
+ _fsFactory(new POSIXFilesystemFactory()),
+ _asset_archive(new AndroidAssetArchive(am)),
+ _shake_offset(0),
+ _event_queue_lock(createMutex()) {
}
OSystem_Android::~OSystem_Android() {
ENTER("~OSystem_Android()");
+
delete _game_texture;
delete _overlay_texture;
delete _mouse_texture;
+
destroyScummVMSurface();
- JNIEnv* env = JNU_GetEnv();
+
+ JNIEnv *env = JNU_GetEnv();
//env->DeleteWeakGlobalRef(_back_ptr);
env->DeleteGlobalRef(_back_ptr);
+
delete _savefile;
delete _mixer;
delete _timer;
delete _fsFactory;
delete _asset_archive;
+
deleteMutex(_event_queue_lock);
}
-OSystem_Android* OSystem_Android::fromJavaObject(JNIEnv* env, jobject obj) {
+OSystem_Android *OSystem_Android::fromJavaObject(JNIEnv *env, jobject obj) {
jlong peer = env->GetLongField(obj, FID_ScummVM_nativeScummVM);
- return (OSystem_Android*)peer;
+ return (OSystem_Android *)peer;
}
-bool OSystem_Android::initJavaHooks(JNIEnv* env, jobject self) {
+bool OSystem_Android::initJavaHooks(JNIEnv *env, jobject self) {
// weak global ref to allow class to be unloaded
// ... except dalvik doesn't implement NewWeakGlobalRef (yet)
//_back_ptr = env->NewWeakGlobalRef(self);
@@ -373,7 +392,7 @@ bool OSystem_Android::initJavaHooks(JNIEnv* env, jobject self) {
#define FIND_METHOD(name, signature) do { \
MID_ ## name = env->GetMethodID(cls, #name, signature); \
- if (MID_ ## name == NULL) \
+ if (MID_ ## name == 0) \
return false; \
} while (0)
@@ -393,10 +412,11 @@ bool OSystem_Android::initJavaHooks(JNIEnv* env, jobject self) {
return true;
}
-static void ScummVM_create(JNIEnv* env, jobject self, jobject am) {
- OSystem_Android* cpp_obj = new OSystem_Android(am);
+static void ScummVM_create(JNIEnv *env, jobject self, jobject am) {
+ OSystem_Android *cpp_obj = new OSystem_Android(am);
+
+ // Exception already thrown by initJavaHooks?
if (!cpp_obj->initJavaHooks(env, self))
- // Exception already thrown by initJavaHooks
return;
env->SetLongField(self, FID_ScummVM_nativeScummVM, (jlong)cpp_obj);
@@ -406,56 +426,69 @@ static void ScummVM_create(JNIEnv* env, jobject self, jobject am) {
#endif
}
-static void ScummVM_nativeDestroy(JNIEnv* env, jobject self) {
- OSystem_Android* cpp_obj = OSystem_Android::fromJavaObject(env, self);
+static void ScummVM_nativeDestroy(JNIEnv *env, jobject self) {
+ OSystem_Android *cpp_obj = OSystem_Android::fromJavaObject(env, self);
delete cpp_obj;
}
-static void ScummVM_audioMixCallback(JNIEnv* env, jobject self,
- jbyteArray jbuf) {
- OSystem_Android* cpp_obj = OSystem_Android::fromJavaObject(env, self);
+static void ScummVM_audioMixCallback(JNIEnv *env, jobject self,
+ jbyteArray jbuf) {
+ OSystem_Android *cpp_obj = OSystem_Android::fromJavaObject(env, self);
jsize len = env->GetArrayLength(jbuf);
- jbyte* buf = env->GetByteArrayElements(jbuf, NULL);
- if (buf == NULL) {
+ jbyte *buf = env->GetByteArrayElements(jbuf, 0);
+
+ if (buf == 0) {
warning("Unable to get Java audio byte array. Skipping");
return;
}
- Audio::MixerImpl* mixer =
- static_cast<Audio::MixerImpl*>(cpp_obj->getMixer());
+
+ Audio::MixerImpl *mixer =
+ static_cast<Audio::MixerImpl *>(cpp_obj->getMixer());
assert(mixer);
- mixer->mixCallback(reinterpret_cast<byte*>(buf), len);
+ mixer->mixCallback(reinterpret_cast<byte *>(buf), len);
+
env->ReleaseByteArrayElements(jbuf, buf, 0);
}
-static void ScummVM_setConfManInt(JNIEnv* env, jclass cls,
- jstring key_obj, jint value) {
+static void ScummVM_setConfManInt(JNIEnv *env, jclass cls,
+ jstring key_obj, jint value) {
ENTER("setConfManInt(%p, %d)", key_obj, (int)value);
- const char* key = env->GetStringUTFChars(key_obj, NULL);
- if (key == NULL)
+
+ const char *key = env->GetStringUTFChars(key_obj, 0);
+
+ if (key == 0)
return;
+
ConfMan.setInt(key, value);
+
env->ReleaseStringUTFChars(key_obj, key);
}
-static void ScummVM_setConfManString(JNIEnv* env, jclass cls, jstring key_obj,
- jstring value_obj) {
+static void ScummVM_setConfManString(JNIEnv *env, jclass cls, jstring key_obj,
+ jstring value_obj) {
ENTER("setConfManStr(%p, %p)", key_obj, value_obj);
- const char* key = env->GetStringUTFChars(key_obj, NULL);
- if (key == NULL)
+
+ const char *key = env->GetStringUTFChars(key_obj, 0);
+
+ if (key == 0)
return;
- const char* value = env->GetStringUTFChars(value_obj, NULL);
- if (value == NULL) {
+
+ const char *value = env->GetStringUTFChars(value_obj, 0);
+
+ if (value == 0) {
env->ReleaseStringUTFChars(key_obj, key);
return;
}
+
ConfMan.set(key, value);
+
env->ReleaseStringUTFChars(value_obj, value);
env->ReleaseStringUTFChars(key_obj, key);
}
-void* OSystem_Android::timerThreadFunc(void* arg) {
- OSystem_Android* system = (OSystem_Android*)arg;
- DefaultTimerManager* timer = (DefaultTimerManager*)(system->_timer);
+void *OSystem_Android::timerThreadFunc(void *arg) {
+ OSystem_Android *system = (OSystem_Android *)arg;
+ DefaultTimerManager *timer = (DefaultTimerManager *)(system->_timer);
JNIEnv *env = 0;
jint res = cached_jvm->AttachCurrentThread(&env, 0);
@@ -471,7 +504,7 @@ void* OSystem_Android::timerThreadFunc(void* arg) {
while (!system->_timer_thread_exit) {
timer->handler();
- nanosleep(&tv, NULL);
+ nanosleep(&tv, 0);
}
res = cached_jvm->DetachCurrentThread();
@@ -481,12 +514,13 @@ void* OSystem_Android::timerThreadFunc(void* arg) {
abort();
}
- return NULL;
+ return 0;
}
void OSystem_Android::initBackend() {
ENTER("initBackend()");
- JNIEnv* env = JNU_GetEnv();
+
+ JNIEnv *env = JNU_GetEnv();
ConfMan.setInt("autosave_period", 0);
ConfMan.setInt("FM_medium_quality", true);
@@ -496,32 +530,37 @@ void OSystem_Android::initBackend() {
setupKeymapper();
// BUG: "transient" ConfMan settings get nuked by the options
- // screen. Passing the savepath in this way makes it stick
+ // screen. Passing the savepath in this way makes it stick
// (via ConfMan.registerDefault)
_savefile = new DefaultSaveFileManager(ConfMan.get("savepath"));
_timer = new DefaultTimerManager();
- gettimeofday(&_startTime, NULL);
+ gettimeofday(&_startTime, 0);
jint sample_rate = env->CallIntMethod(_back_ptr, MID_audioSampleRate);
if (env->ExceptionCheck()) {
warning("Error finding audio sample rate - assuming 11025HZ");
+
env->ExceptionDescribe();
env->ExceptionClear();
+
sample_rate = 11025;
}
+
_mixer = new Audio::MixerImpl(this, sample_rate);
_mixer->setReady(true);
env->CallVoidMethod(_back_ptr, MID_initBackend);
+
if (env->ExceptionCheck()) {
error("Error in Java initBackend");
+
env->ExceptionDescribe();
env->ExceptionClear();
}
_timer_thread_exit = false;
- pthread_create(&_timer_thread, NULL, timerThreadFunc, this);
+ pthread_create(&_timer_thread, 0, timerThreadFunc, this);
OSystem::initBackend();
@@ -530,30 +569,39 @@ void OSystem_Android::initBackend() {
void OSystem_Android::addPluginDirectories(Common::FSList &dirs) const {
ENTER("OSystem_Android::addPluginDirectories()");
- JNIEnv* env = JNU_GetEnv();
+
+ JNIEnv *env = JNU_GetEnv();
jobjectArray array =
(jobjectArray)env->CallObjectMethod(_back_ptr, MID_getPluginDirectories);
if (env->ExceptionCheck()) {
warning("Error finding plugin directories");
+
env->ExceptionDescribe();
env->ExceptionClear();
+
return;
}
jsize size = env->GetArrayLength(array);
for (jsize i = 0; i < size; ++i) {
jstring path_obj = (jstring)env->GetObjectArrayElement(array, i);
- if (path_obj == NULL)
+
+ if (path_obj == 0)
continue;
- const char* path = env->GetStringUTFChars(path_obj, NULL);
- if (path == NULL) {
+
+ const char *path = env->GetStringUTFChars(path_obj, 0);
+ if (path == 0) {
warning("Error getting string characters from plugin directory");
+
env->ExceptionClear();
env->DeleteLocalRef(path_obj);
+
continue;
}
+
dirs.push_back(Common::FSNode(path));
+
env->ReleaseStringUTFChars(path_obj, path);
env->DeleteLocalRef(path_obj);
}
@@ -561,12 +609,13 @@ void OSystem_Android::addPluginDirectories(Common::FSList &dirs) const {
bool OSystem_Android::hasFeature(Feature f) {
return (f == kFeatureCursorHasPalette ||
- f == kFeatureVirtualKeyboard ||
- f == kFeatureOverlaySupportsAlpha);
+ f == kFeatureVirtualKeyboard ||
+ f == kFeatureOverlaySupportsAlpha);
}
void OSystem_Android::setFeatureState(Feature f, bool enable) {
ENTER("setFeatureState(%d, %d)", f, enable);
+
switch (f) {
case kFeatureVirtualKeyboard:
_virtkeybd_on = enable;
@@ -586,11 +635,12 @@ bool OSystem_Android::getFeatureState(Feature f) {
}
}
-const OSystem::GraphicsMode* OSystem_Android::getSupportedGraphicsModes() const {
+const OSystem::GraphicsMode *OSystem_Android::getSupportedGraphicsModes() const {
static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
- {"default", "Default", 1},
- {0, 0, 0},
+ { "default", "Default", 1 },
+ { 0, 0, 0 },
};
+
return s_supportedGraphicsModes;
}
@@ -615,13 +665,14 @@ int OSystem_Android::getGraphicsMode() const {
void OSystem_Android::setupScummVMSurface() {
ENTER("setupScummVMSurface");
- JNIEnv* env = JNU_GetEnv();
+
+ JNIEnv *env = JNU_GetEnv();
env->CallVoidMethod(_back_ptr, MID_setupScummVMSurface);
+
if (env->ExceptionCheck())
return;
// EGL set up with a new surface. Initialise OpenGLES context.
-
GLESTexture::initGLExtensions();
// Turn off anything that looks like 3D ;)
@@ -630,6 +681,7 @@ void OSystem_Android::setupScummVMSurface() {
glDisable(GL_LIGHTING);
glDisable(GL_FOG);
glDisable(GL_DITHER);
+
glShadeModel(GL_FLAT);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
@@ -669,13 +721,13 @@ void OSystem_Android::setupScummVMSurface() {
}
void OSystem_Android::destroyScummVMSurface() {
- JNIEnv* env = JNU_GetEnv();
+ JNIEnv *env = JNU_GetEnv();
env->CallVoidMethod(_back_ptr, MID_destroyScummVMSurface);
// Can't use OpenGLES functions after this
}
void OSystem_Android::initSize(uint width, uint height,
- const Graphics::PixelFormat *format) {
+ const Graphics::PixelFormat *format) {
ENTER("initSize(%d,%d,%p)", width, height, format);
_game_texture->allocBuffer(width, height);
@@ -700,16 +752,18 @@ int16 OSystem_Android::getWidth() {
return _game_texture->width();
}
-void OSystem_Android::setPalette(const byte* colors, uint start, uint num) {
+void OSystem_Android::setPalette(const byte *colors, uint start, uint num) {
ENTER("setPalette(%p, %u, %u)", colors, start, num);
if (!_use_mouse_palette)
_setCursorPalette(colors, start, num);
- byte* palette = _game_texture->palette() + start*3;
+ byte *palette = _game_texture->palette() + start * 3;
+
do {
for (int i = 0; i < 3; ++i)
palette[i] = colors[i];
+
palette += 3;
colors += 4;
} while (--num);
@@ -717,11 +771,15 @@ void OSystem_Android::setPalette(const byte* colors, uint start, uint num) {
void OSystem_Android::grabPalette(byte *colors, uint start, uint num) {
ENTER("grabPalette(%p, %u, %u)", colors, start, num);
- const byte* palette = _game_texture->palette_const() + start*3;
+
+ const byte *palette = _game_texture->palette_const() + start * 3;
+
do {
for (int i = 0; i < 3; ++i)
colors[i] = palette[i];
- colors[3] = 0xff; // alpha
+
+ // alpha
+ colors[3] = 0xff;
palette += 3;
colors += 4;
@@ -729,9 +787,9 @@ void OSystem_Android::grabPalette(byte *colors, uint start, uint num) {
}
void OSystem_Android::copyRectToScreen(const byte *buf, int pitch,
- int x, int y, int w, int h) {
+ int x, int y, int w, int h) {
ENTER("copyRectToScreen(%p, %d, %d, %d, %d, %d)",
- buf, pitch, x, y, w, h);
+ buf, pitch, x, y, w, h);
_game_texture->updateBuffer(x, y, w, h, buf, pitch);
}
@@ -740,9 +798,9 @@ void OSystem_Android::updateScreen() {
//ENTER("updateScreen()");
if (!_force_redraw &&
- !_game_texture->dirty() &&
- !_overlay_texture->dirty() &&
- !_mouse_texture->dirty())
+ !_game_texture->dirty() &&
+ !_overlay_texture->dirty() &&
+ !_mouse_texture->dirty())
return;
_force_redraw = false;
@@ -750,9 +808,9 @@ void OSystem_Android::updateScreen() {
glPushMatrix();
if (_shake_offset != 0 ||
- (!_focus_rect.isEmpty() &&
- !Common::Rect(_game_texture->width(),
- _game_texture->height()).contains(_focus_rect))) {
+ (!_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.
glClearColorx(0, 0, 0, 1 << 16);
@@ -764,18 +822,19 @@ void OSystem_Android::updateScreen() {
if (_focus_rect.isEmpty()) {
_game_texture->drawTexture(0, 0,
- _egl_surface_width, _egl_surface_height);
+ _egl_surface_width, _egl_surface_height);
} else {
glPushMatrix();
glScalex(xdiv(_egl_surface_width, _focus_rect.width()),
- xdiv(_egl_surface_height, _focus_rect.height()),
- 1 << 16);
+ xdiv(_egl_surface_height, _focus_rect.height()),
+ 1 << 16);
glTranslatex(-_focus_rect.left << 16, -_focus_rect.top << 16, 0);
glScalex(xdiv(_game_texture->width(), _egl_surface_width),
- xdiv(_game_texture->height(), _egl_surface_height),
- 1 << 16);
+ xdiv(_game_texture->height(), _egl_surface_height),
+ 1 << 16);
+
_game_texture->drawTexture(0, 0,
- _egl_surface_width, _egl_surface_height);
+ _egl_surface_width, _egl_surface_height);
glPopMatrix();
}
@@ -783,8 +842,8 @@ void OSystem_Android::updateScreen() {
if (_show_overlay) {
_overlay_texture->drawTexture(0, 0,
- _egl_surface_width,
- _egl_surface_height);
+ _egl_surface_width,
+ _egl_surface_height);
CHECK_GL_ERROR();
}
@@ -792,11 +851,12 @@ void OSystem_Android::updateScreen() {
glPushMatrix();
glTranslatex(-_mouse_hotspot.x << 16,
- -_mouse_hotspot.y << 16,
- 0);
+ -_mouse_hotspot.y << 16,
+ 0);
// Scale up ScummVM -> OpenGL (pixel) coordinates
int texwidth, texheight;
+
if (_show_overlay) {
texwidth = getOverlayWidth();
texheight = getOverlayHeight();
@@ -804,15 +864,16 @@ void OSystem_Android::updateScreen() {
texwidth = getWidth();
texheight = getHeight();
}
+
glScalex(xdiv(_egl_surface_width, texwidth),
- xdiv(_egl_surface_height, texheight),
- 1 << 16);
+ xdiv(_egl_surface_height, texheight),
+ 1 << 16);
// Note the extra half texel to position the mouse in
// the middle of the x,y square:
const Common::Point& mouse = getEventManager()->getMousePos();
glTranslatex((mouse.x << 16) | 1 << 15,
- (mouse.y << 16) | 1 << 15, 0);
+ (mouse.y << 16) | 1 << 15, 0);
// Mouse targetscale just seems to make the cursor way
// too big :/
@@ -828,7 +889,7 @@ void OSystem_Android::updateScreen() {
CHECK_GL_ERROR();
- JNIEnv* env = JNU_GetEnv();
+ JNIEnv *env = JNU_GetEnv();
if (!env->CallBooleanMethod(_back_ptr, MID_swapBuffers)) {
// Context lost -> need to reinit GL
destroyScummVMSurface();
@@ -838,18 +899,22 @@ void OSystem_Android::updateScreen() {
Graphics::Surface *OSystem_Android::lockScreen() {
ENTER("lockScreen()");
- Graphics::Surface* surface = _game_texture->surface();
+
+ Graphics::Surface *surface = _game_texture->surface();
assert(surface->pixels);
+
return surface;
}
void OSystem_Android::unlockScreen() {
ENTER("unlockScreen()");
+
assert(_game_texture->dirty());
}
void OSystem_Android::setShakePos(int shake_offset) {
ENTER("setShakePos(%d)", shake_offset);
+
if (_shake_offset != shake_offset) {
_shake_offset = shake_offset;
_force_redraw = true;
@@ -858,13 +923,15 @@ void OSystem_Android::setShakePos(int shake_offset) {
void OSystem_Android::fillScreen(uint32 col) {
ENTER("fillScreen(%u)", col);
+
assert(col < 256);
_game_texture->fillBuffer(col);
}
void OSystem_Android::setFocusRectangle(const Common::Rect& rect) {
ENTER("setFocusRectangle(%d,%d,%d,%d)",
- rect.left, rect.top, rect.right, rect.bottom);
+ rect.left, rect.top, rect.right, rect.bottom);
+
if (_enable_zoning) {
_focus_rect = rect;
_force_redraw = true;
@@ -873,6 +940,7 @@ void OSystem_Android::setFocusRectangle(const Common::Rect& rect) {
void OSystem_Android::clearFocusRectangle() {
ENTER("clearFocusRectangle()");
+
if (_enable_zoning) {
_focus_rect = Common::Rect();
_force_redraw = true;
@@ -881,18 +949,21 @@ void OSystem_Android::clearFocusRectangle() {
void OSystem_Android::showOverlay() {
ENTER("showOverlay()");
+
_show_overlay = true;
_force_redraw = true;
}
void OSystem_Android::hideOverlay() {
ENTER("hideOverlay()");
+
_show_overlay = false;
_force_redraw = true;
}
void OSystem_Android::clearOverlay() {
ENTER("clearOverlay()");
+
_overlay_texture->fillBuffer(0);
// Shouldn't need this, but works around a 'blank screen' bug on Nexus1
@@ -901,23 +972,29 @@ void OSystem_Android::clearOverlay() {
void OSystem_Android::grabOverlay(OverlayColor *buf, int pitch) {
ENTER("grabOverlay(%p, %d)", buf, pitch);
+
// We support overlay alpha blending, so the pixel data here
// shouldn't actually be used. Let's fill it with zeros, I'm sure
// it will be fine...
- const Graphics::Surface* surface = _overlay_texture->surface_const();
+ const Graphics::Surface *surface = _overlay_texture->surface_const();
assert(surface->bytesPerPixel == sizeof(buf[0]));
+
int h = surface->h;
+
do {
memset(buf, 0, surface->w * sizeof(buf[0]));
- buf += pitch; // This 'pitch' is pixels not bytes
+
+ // This 'pitch' is pixels not bytes
+ buf += pitch;
} while (--h);
}
void OSystem_Android::copyRectToOverlay(const OverlayColor *buf, int pitch,
- int x, int y, int w, int h) {
+ int x, int y, int w, int h) {
ENTER("copyRectToOverlay(%p, %d, %d, %d, %d, %d)",
- buf, pitch, x, y, w, h);
- const Graphics::Surface* surface = _overlay_texture->surface_const();
+ buf, pitch, x, y, w, h);
+
+ const Graphics::Surface *surface = _overlay_texture->surface_const();
assert(surface->bytesPerPixel == sizeof(buf[0]));
// This 'pitch' is pixels not bytes
@@ -937,37 +1014,43 @@ int16 OSystem_Android::getOverlayWidth() {
bool OSystem_Android::showMouse(bool visible) {
ENTER("showMouse(%d)", visible);
+
_show_mouse = visible;
+
return true;
}
void OSystem_Android::warpMouse(int x, int y) {
ENTER("warpMouse(%d, %d)", x, y);
+
// We use only the eventmanager's idea of the current mouse
// position, so there is nothing extra to do here.
}
void OSystem_Android::setMouseCursor(const byte *buf, uint w, uint h,
- int hotspotX, int hotspotY,
- uint32 keycolor, int cursorTargetScale,
- const Graphics::PixelFormat *format) {
+ int hotspotX, int hotspotY,
+ uint32 keycolor, int cursorTargetScale,
+ const Graphics::PixelFormat *format) {
ENTER("setMouseCursor(%p, %u, %u, %d, %d, %d, %d, %p)",
- buf, w, h, hotspotX, hotspotY, (int)keycolor, cursorTargetScale,
- format);
+ buf, w, h, hotspotX, hotspotY, (int)keycolor, cursorTargetScale,
+ format);
assert(keycolor < 256);
_mouse_texture->allocBuffer(w, h);
// Update palette alpha based on keycolor
- byte* palette = _mouse_texture->palette();
+ byte *palette = _mouse_texture->palette();
int i = 256;
+
do {
palette[3] = 0xff;
palette += 4;
} while (--i);
+
palette = _mouse_texture->palette();
- palette[keycolor*4 + 3] = 0x00;
+ palette[keycolor * 4 + 3] = 0x00;
+
_mouse_texture->updateBuffer(0, 0, w, h, buf, w);
_mouse_hotspot = Common::Point(hotspotX, hotspotY);
@@ -975,11 +1058,13 @@ void OSystem_Android::setMouseCursor(const byte *buf, uint w, uint h,
}
void OSystem_Android::_setCursorPalette(const byte *colors,
- uint start, uint num) {
- byte* palette = _mouse_texture->palette() + start*4;
+ uint start, uint num) {
+ byte *palette = _mouse_texture->palette() + start * 4;
+
do {
for (int i = 0; i < 3; ++i)
palette[i] = colors[i];
+
// Leave alpha untouched to preserve keycolor
palette += 4;
@@ -988,14 +1073,16 @@ void OSystem_Android::_setCursorPalette(const byte *colors,
}
void OSystem_Android::setCursorPalette(const byte *colors,
- uint start, uint num) {
+ uint start, uint num) {
ENTER("setCursorPalette(%p, %u, %u)", colors, start, num);
+
_setCursorPalette(colors, start, num);
_use_mouse_palette = true;
}
void OSystem_Android::disableCursorPalette(bool disable) {
ENTER("disableCursorPalette(%d)", disable);
+
_use_mouse_palette = !disable;
}
@@ -1006,17 +1093,19 @@ void OSystem_Android::setupKeymapper() {
Keymapper *mapper = getEventManager()->getKeymapper();
HardwareKeySet *keySet = new HardwareKeySet();
+
keySet->addHardwareKey(
new HardwareKey("n", KeyState(KEYCODE_n), "n (vk)",
kTriggerLeftKeyType,
kVirtualKeyboardActionType));
+
mapper->registerHardwareKeySet(keySet);
Keymap *globalMap = new Keymap("global");
Action *act;
act = new Action(globalMap, "VIRT", "Display keyboard",
- kVirtualKeyboardActionType);
+ kVirtualKeyboardActionType);
act->addKeyEvent(KeyState(KEYCODE_F7, ASCII_F7, 0));
mapper->addGlobalKeymap(globalMap);
@@ -1027,11 +1116,14 @@ void OSystem_Android::setupKeymapper() {
bool OSystem_Android::pollEvent(Common::Event &event) {
//ENTER("pollEvent()");
+
lockMutex(_event_queue_lock);
+
if (_event_queue.empty()) {
unlockMutex(_event_queue_lock);
return false;
}
+
event = _event_queue.pop();
unlockMutex(_event_queue_lock);
@@ -1048,26 +1140,27 @@ bool OSystem_Android::pollEvent(Common::Event &event) {
case Common::EVENT_WHEELDOWN:
case Common::EVENT_MBUTTONDOWN:
case Common::EVENT_MBUTTONUP: {
- if (event.kbd.flags == 1) { // relative mouse hack
+ // relative mouse hack
+ if (event.kbd.flags == 1) {
// Relative (trackball) mouse hack.
const Common::Point& mouse_pos =
getEventManager()->getMousePos();
event.mouse.x += mouse_pos.x;
event.mouse.y += mouse_pos.y;
event.mouse.x = CLIP(event.mouse.x, (int16)0, _show_overlay ?
- getOverlayWidth() : getWidth());
+ getOverlayWidth() : getWidth());
event.mouse.y = CLIP(event.mouse.y, (int16)0, _show_overlay ?
- getOverlayHeight() : getHeight());
+ getOverlayHeight() : getHeight());
} else {
// Touchscreen events need to be converted
// from device to game coords first.
- const GLESTexture* tex = _show_overlay
- ? static_cast<GLESTexture*>(_overlay_texture)
- : static_cast<GLESTexture*>(_game_texture);
+ const GLESTexture *tex = _show_overlay
+ ? static_cast<GLESTexture *>(_overlay_texture)
+ : static_cast<GLESTexture *>(_game_texture);
event.mouse.x = scalef(event.mouse.x, tex->width(),
- _egl_surface_width);
+ _egl_surface_width);
event.mouse.y = scalef(event.mouse.y, tex->height(),
- _egl_surface_height);
+ _egl_surface_height);
event.mouse.x -= _shake_offset;
}
break;
@@ -1090,32 +1183,33 @@ void OSystem_Android::pushEvent(const Common::Event& event) {
// Try to combine multiple queued mouse move events
if (event.type == Common::EVENT_MOUSEMOVE &&
- !_event_queue.empty() &&
- _event_queue.back().type == Common::EVENT_MOUSEMOVE) {
- Common::Event tail = _event_queue.back();
- if (event.kbd.flags) {
- // relative movement hack
- tail.mouse.x += event.mouse.x;
- tail.mouse.y += event.mouse.y;
- } else {
- // absolute position
- tail.kbd.flags = 0; // clear relative flag
- tail.mouse.x = event.mouse.x;
- tail.mouse.y = event.mouse.y;
- }
- }
- else
+ !_event_queue.empty() &&
+ _event_queue.back().type == Common::EVENT_MOUSEMOVE) {
+ Common::Event tail = _event_queue.back();
+ if (event.kbd.flags) {
+ // relative movement hack
+ tail.mouse.x += event.mouse.x;
+ tail.mouse.y += event.mouse.y;
+ } else {
+ // absolute position, clear relative flag
+ tail.kbd.flags = 0;
+ tail.mouse.x = event.mouse.x;
+ tail.mouse.y = event.mouse.y;
+ }
+ } else {
_event_queue.push(event);
+ }
unlockMutex(_event_queue_lock);
}
-static void ScummVM_pushEvent(JNIEnv* env, jobject self, jobject java_event) {
- OSystem_Android* cpp_obj = OSystem_Android::fromJavaObject(env, self);
+static void ScummVM_pushEvent(JNIEnv *env, jobject self, jobject java_event) {
+ OSystem_Android *cpp_obj = OSystem_Android::fromJavaObject(env, self);
Common::Event event;
event.type = (Common::EventType)env->GetIntField(java_event,
- FID_Event_type);
+ FID_Event_type);
+
event.synthetic =
env->GetBooleanField(java_event, FID_Event_synthetic);
@@ -1157,7 +1251,9 @@ static void ScummVM_pushEvent(JNIEnv* env, jobject self, jobject java_event) {
uint32 OSystem_Android::getMillis() {
timeval curTime;
- gettimeofday(&curTime, NULL);
+
+ gettimeofday(&curTime, 0);
+
return (uint32)(((curTime.tv_sec - _startTime.tv_sec) * 1000) + \
((curTime.tv_usec - _startTime.tv_usec) / 1000));
}
@@ -1172,26 +1268,31 @@ OSystem::MutexRef OSystem_Android::createMutex() {
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_t *mutex = new pthread_mutex_t;
+
if (pthread_mutex_init(mutex, &attr) != 0) {
warning("pthread_mutex_init() failed");
+
delete mutex;
- return NULL;
+
+ return 0;
}
+
return (MutexRef)mutex;
}
void OSystem_Android::lockMutex(MutexRef mutex) {
- if (pthread_mutex_lock((pthread_mutex_t*)mutex) != 0)
+ if (pthread_mutex_lock((pthread_mutex_t *)mutex) != 0)
warning("pthread_mutex_lock() failed");
}
void OSystem_Android::unlockMutex(MutexRef mutex) {
- if (pthread_mutex_unlock((pthread_mutex_t*)mutex) != 0)
+ if (pthread_mutex_unlock((pthread_mutex_t *)mutex) != 0)
warning("pthread_mutex_unlock() failed");
}
void OSystem_Android::deleteMutex(MutexRef mutex) {
- pthread_mutex_t* m = (pthread_mutex_t*)mutex;
+ pthread_mutex_t *m = (pthread_mutex_t *)mutex;
+
if (pthread_mutex_destroy(m) != 0)
warning("pthread_mutex_destroy() failed");
else
@@ -1202,41 +1303,54 @@ void OSystem_Android::quit() {
ENTER("quit()");
_timer_thread_exit = true;
- pthread_join(_timer_thread, NULL);
+ pthread_join(_timer_thread, 0);
}
void OSystem_Android::setWindowCaption(const char *caption) {
ENTER("setWindowCaption(%s)", caption);
- JNIEnv* env = JNU_GetEnv();
+
+ JNIEnv *env = JNU_GetEnv();
jstring java_caption = env->NewStringUTF(caption);
env->CallVoidMethod(_back_ptr, MID_setWindowCaption, java_caption);
+
if (env->ExceptionCheck()) {
warning("Failed to set window caption");
+
env->ExceptionDescribe();
env->ExceptionClear();
}
+
env->DeleteLocalRef(java_caption);
}
void OSystem_Android::displayMessageOnOSD(const char *msg) {
ENTER("displayMessageOnOSD(%s)", msg);
- JNIEnv* env = JNU_GetEnv();
+
+ JNIEnv *env = JNU_GetEnv();
jstring java_msg = env->NewStringUTF(msg);
+
env->CallVoidMethod(_back_ptr, MID_displayMessageOnOSD, java_msg);
+
if (env->ExceptionCheck()) {
warning("Failed to display OSD message");
+
env->ExceptionDescribe();
env->ExceptionClear();
}
+
env->DeleteLocalRef(java_msg);
}
void OSystem_Android::showVirtualKeyboard(bool enable) {
ENTER("showVirtualKeyboard(%d)", enable);
- JNIEnv* env = JNU_GetEnv();
+
+ JNIEnv *env = JNU_GetEnv();
+
env->CallVoidMethod(_back_ptr, MID_showVirtualKeyboard, enable);
+
if (env->ExceptionCheck()) {
error("Error trying to show virtual keyboard");
+
env->ExceptionDescribe();
env->ExceptionClear();
}
@@ -1259,7 +1373,8 @@ Common::TimerManager *OSystem_Android::getTimerManager() {
void OSystem_Android::getTimeAndDate(TimeDate &td) const {
struct tm tm;
- const time_t curTime = time(NULL);
+ const time_t curTime = time(0);
+
localtime_r(&curTime, &tm);
td.tm_sec = tm.tm_sec;
td.tm_min = tm.tm_min;
@@ -1274,28 +1389,33 @@ FilesystemFactory *OSystem_Android::getFilesystemFactory() {
}
void OSystem_Android::addSysArchivesToSearchSet(Common::SearchSet &s,
- int priority) {
+ int priority) {
s.add("ASSET", _asset_archive, priority, false);
- JNIEnv* env = JNU_GetEnv();
+ JNIEnv *env = JNU_GetEnv();
jobjectArray array =
(jobjectArray)env->CallObjectMethod(_back_ptr, MID_getSysArchives);
+
if (env->ExceptionCheck()) {
warning("Error finding system archive path");
+
env->ExceptionDescribe();
env->ExceptionClear();
+
return;
}
jsize size = env->GetArrayLength(array);
for (jsize i = 0; i < size; ++i) {
jstring path_obj = (jstring)env->GetObjectArrayElement(array, i);
- const char* path = env->GetStringUTFChars(path_obj, NULL);
- if (path != NULL) {
+ const char *path = env->GetStringUTFChars(path_obj, 0);
+
+ if (path != 0) {
s.addDirectory(path, path, priority);
env->ReleaseStringUTFChars(path_obj, path);
}
+
env->DeleteLocalRef(path_obj);
}
}
@@ -1316,8 +1436,8 @@ void OSystem_Android::logMessage(LogMessageType::Type type, const char *message)
}
}
-static jint ScummVM_scummVMMain(JNIEnv* env, jobject self, jobjectArray args) {
- OSystem_Android* cpp_obj = OSystem_Android::fromJavaObject(env, self);
+static jint ScummVM_scummVMMain(JNIEnv *env, jobject self, jobjectArray args) {
+ OSystem_Android *cpp_obj = OSystem_Android::fromJavaObject(env, self);
const int MAX_NARGS = 32;
int res = -1;
@@ -1325,42 +1445,58 @@ static jint ScummVM_scummVMMain(JNIEnv* env, jobject self, jobjectArray args) {
int argc = env->GetArrayLength(args);
if (argc > MAX_NARGS) {
JNU_ThrowByName(env, "java/lang/IllegalArgumentException",
- "too many arguments");
+ "too many arguments");
return 0;
}
- char* argv[MAX_NARGS];
- int nargs; // note use in cleanup loop below
+ char *argv[MAX_NARGS];
+
+ // note use in cleanup loop below
+ int nargs;
+
for (nargs = 0; nargs < argc; ++nargs) {
jstring arg = (jstring)env->GetObjectArrayElement(args, nargs);
- if (arg == NULL) {
- argv[nargs] = NULL;
+
+ if (arg == 0) {
+ argv[nargs] = 0;
} else {
- const char* cstr = env->GetStringUTFChars(arg, NULL);
- argv[nargs] = const_cast<char*>(cstr);
- if (cstr == NULL)
- goto cleanup; // exception already thrown
+ const char *cstr = env->GetStringUTFChars(arg, 0);
+
+ argv[nargs] = const_cast<char *>(cstr);
+
+ // exception already thrown?
+ if (cstr == 0)
+ goto cleanup;
}
+
env->DeleteLocalRef(arg);
}
g_system = cpp_obj;
assert(g_system);
+
__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,
- "Entering scummvm_main with %d args", argc);
+ "Entering scummvm_main with %d args", argc);
+
res = scummvm_main(argc, argv);
+
__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "Exiting scummvm_main");
+
g_system->quit();
cleanup:
nargs--;
+
for (int i = 0; i < nargs; ++i) {
- if (argv[i] == NULL)
+ if (argv[i] == 0)
continue;
+
jstring arg = (jstring)env->GetObjectArrayElement(args, nargs);
- if (arg == NULL)
- // Exception already thrown
+
+ // Exception already thrown?
+ if (arg == 0)
return res;
+
env->ReleaseStringUTFChars(arg, argv[i]);
env->DeleteLocalRef(arg);
}
@@ -1370,93 +1506,105 @@ cleanup:
#ifdef DYNAMIC_MODULES
void AndroidPluginProvider::addCustomDirectories(Common::FSList &dirs) const {
- OSystem_Android* g_system_android = (OSystem_Android*)g_system;
+ OSystem_Android *g_system_android = (OSystem_Android *)g_system;
g_system_android->addPluginDirectories(dirs);
}
#endif
-static void ScummVM_enableZoning(JNIEnv* env, jobject self, jboolean enable) {
- OSystem_Android* cpp_obj = OSystem_Android::fromJavaObject(env, self);
+static void ScummVM_enableZoning(JNIEnv *env, jobject self, jboolean enable) {
+ OSystem_Android *cpp_obj = OSystem_Android::fromJavaObject(env, self);
cpp_obj->enableZoning(enable);
}
-static void ScummVM_setSurfaceSize(JNIEnv* env, jobject self,
- jint width, jint height) {
- OSystem_Android* cpp_obj = OSystem_Android::fromJavaObject(env, self);
+static void ScummVM_setSurfaceSize(JNIEnv *env, jobject self,
+ jint width, jint height) {
+ OSystem_Android *cpp_obj = OSystem_Android::fromJavaObject(env, self);
cpp_obj->setSurfaceSize(width, height);
}
const static JNINativeMethod gMethods[] = {
{ "create", "(Landroid/content/res/AssetManager;)V",
- (void*)ScummVM_create },
- { "nativeDestroy", "()V", (void*)ScummVM_nativeDestroy },
+ (void *)ScummVM_create },
+ { "nativeDestroy", "()V",
+ (void *)ScummVM_nativeDestroy },
{ "scummVMMain", "([Ljava/lang/String;)I",
- (void*)ScummVM_scummVMMain },
+ (void *)ScummVM_scummVMMain },
{ "pushEvent", "(Lorg/inodes/gus/scummvm/Event;)V",
- (void*)ScummVM_pushEvent },
+ (void *)ScummVM_pushEvent },
{ "audioMixCallback", "([B)V",
- (void*)ScummVM_audioMixCallback },
+ (void *)ScummVM_audioMixCallback },
{ "setConfMan", "(Ljava/lang/String;I)V",
- (void*)ScummVM_setConfManInt },
+ (void *)ScummVM_setConfManInt },
{ "setConfMan", "(Ljava/lang/String;Ljava/lang/String;)V",
- (void*)ScummVM_setConfManString },
+ (void *)ScummVM_setConfManString },
{ "enableZoning", "(Z)V",
- (void*)ScummVM_enableZoning },
+ (void *)ScummVM_enableZoning },
{ "setSurfaceSize", "(II)V",
- (void*)ScummVM_setSurfaceSize },
+ (void *)ScummVM_setSurfaceSize },
};
JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM* jvm, void* reserved) {
+JNI_OnLoad(JavaVM *jvm, void *reserved) {
cached_jvm = jvm;
- JNIEnv* env;
- if (jvm->GetEnv((void**)&env, JNI_VERSION_1_2))
+ JNIEnv *env;
+
+ if (jvm->GetEnv((void **)&env, JNI_VERSION_1_2))
return JNI_ERR;
jclass cls = env->FindClass("org/inodes/gus/scummvm/ScummVM");
- if (cls == NULL)
+ if (cls == 0)
return JNI_ERR;
+
if (env->RegisterNatives(cls, gMethods, ARRAYSIZE(gMethods)) < 0)
return JNI_ERR;
FID_ScummVM_nativeScummVM = env->GetFieldID(cls, "nativeScummVM", "J");
- if (FID_ScummVM_nativeScummVM == NULL)
+ if (FID_ScummVM_nativeScummVM == 0)
return JNI_ERR;
jclass event = env->FindClass("org/inodes/gus/scummvm/Event");
- if (event == NULL)
+ if (event == 0)
return JNI_ERR;
+
FID_Event_type = env->GetFieldID(event, "type", "I");
- if (FID_Event_type == NULL)
+ if (FID_Event_type == 0)
return JNI_ERR;
+
FID_Event_synthetic = env->GetFieldID(event, "synthetic", "Z");
- if (FID_Event_synthetic == NULL)
+ if (FID_Event_synthetic == 0)
return JNI_ERR;
+
FID_Event_kbd_keycode = env->GetFieldID(event, "kbd_keycode", "I");
- if (FID_Event_kbd_keycode == NULL)
+ if (FID_Event_kbd_keycode == 0)
return JNI_ERR;
+
FID_Event_kbd_ascii = env->GetFieldID(event, "kbd_ascii", "I");
- if (FID_Event_kbd_ascii == NULL)
+ if (FID_Event_kbd_ascii == 0)
return JNI_ERR;
+
FID_Event_kbd_flags = env->GetFieldID(event, "kbd_flags", "I");
- if (FID_Event_kbd_flags == NULL)
+ if (FID_Event_kbd_flags == 0)
return JNI_ERR;
+
FID_Event_mouse_x = env->GetFieldID(event, "mouse_x", "I");
- if (FID_Event_mouse_x == NULL)
+ if (FID_Event_mouse_x == 0)
return JNI_ERR;
+
FID_Event_mouse_y = env->GetFieldID(event, "mouse_y", "I");
- if (FID_Event_mouse_y == NULL)
+ if (FID_Event_mouse_y == 0)
return JNI_ERR;
+
FID_Event_mouse_relative = env->GetFieldID(event, "mouse_relative", "Z");
- if (FID_Event_mouse_relative == NULL)
+ if (FID_Event_mouse_relative == 0)
return JNI_ERR;
cls = env->FindClass("java/lang/Object");
- if (cls == NULL)
+ if (cls == 0)
return JNI_ERR;
+
MID_Object_wait = env->GetMethodID(cls, "wait", "()V");
- if (MID_Object_wait == NULL)
+ if (MID_Object_wait == 0)
return JNI_ERR;
return JNI_VERSION_1_2;
diff --git a/backends/platform/android/android.mk b/backends/platform/android/android.mk
index a99078581e..1bc3c3d21a 100644
--- a/backends/platform/android/android.mk
+++ b/backends/platform/android/android.mk
@@ -109,12 +109,12 @@ $(FILE_DEX_PLUGIN): $(CLASSES_PLUGIN)
$(PATH_BUILD)/%/AndroidManifest.xml $(PATH_STAGE_PREFIX).%/res/values/strings.xml: $(PATH_DIST)/mkmanifest.pl $(srcdir)/configure $(PATH_DIST)/AndroidManifest.xml
$(PATH_DIST)/mkmanifest.pl --id=$* --configure=$(srcdir)/configure \
- --version-name=$(VERSION) \
- --version-code=$(ANDROID_PLUGIN_VERSIONCODE) \
- --stringres=$(PATH_STAGE_PREFIX).$*/res/values/strings.xml \
- --manifest=$(PATH_BUILD)/$*/AndroidManifest.xml \
- --master-manifest=$(PATH_DIST)/AndroidManifest.xml \
- --unpacklib=mylib/armeabi/lib$*.so
+ --version-name=$(VERSION) \
+ --version-code=$(ANDROID_PLUGIN_VERSIONCODE) \
+ --stringres=$(PATH_STAGE_PREFIX).$*/res/values/strings.xml \
+ --manifest=$(PATH_BUILD)/$*/AndroidManifest.xml \
+ --master-manifest=$(PATH_DIST)/AndroidManifest.xml \
+ --unpacklib=mylib/armeabi/lib$*.so
$(PATH_STAGE_PREFIX).%/res/drawable/scummvm.png: $(PATH_RESOURCES)/drawable/scummvm.png
@$(MKDIR) -p $(@D)
@@ -165,7 +165,7 @@ androidrelease: $(addprefix release/, $(APK_MAIN) $(APK_PLUGINS))
androidtest: $(APK_MAIN) $(APK_PLUGINS)
@set -e; for apk in $^; do \
- $(ADB) install -r $$apk; \
+ $(ADB) install -r $$apk; \
done
$(ADB) shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -n org.inodes.gus.scummvm/.Unpacker
@@ -173,7 +173,9 @@ androidtest: $(APK_MAIN) $(APK_PLUGINS)
androiddistdebug: all
$(MKDIR) debug
$(CP) $(APK_MAIN) $(APK_PLUGINS) debug/
- for i in $(DIST_FILES_DOCS); do sed 's/$$/\r/' < $$i > debug/`basename $$i`.txt; done
+ for i in $(DIST_FILES_DOCS); do \
+ sed 's/$$/\r/' < $$i > debug/`basename $$i`.txt; \
+ done
.PHONY: androidrelease androidtest
diff --git a/backends/platform/android/asset-archive.cpp b/backends/platform/android/asset-archive.cpp
index bd32847f6a..3197c75b82 100644
--- a/backends/platform/android/asset-archive.cpp
+++ b/backends/platform/android/asset-archive.cpp
@@ -38,7 +38,7 @@
#include "backends/platform/android/asset-archive.h"
-extern JNIEnv* JNU_GetEnv();
+extern JNIEnv *JNU_GetEnv();
// Must match android.content.res.AssetManager.ACCESS_*
const jint ACCESS_UNKNOWN = 0;
@@ -47,23 +47,43 @@ const jint ACCESS_RANDOM = 1;
// This might be useful to someone else. Assumes markSupported() == true.
class JavaInputStream : public Common::SeekableReadStream {
public:
- JavaInputStream(JNIEnv* env, jobject is);
+ JavaInputStream(JNIEnv *env, jobject is);
virtual ~JavaInputStream();
- virtual bool eos() const { return _eos; }
- virtual bool err() const { return _err; }
- virtual void clearErr() { _eos = _err = false; }
+
+ virtual bool eos() const {
+ return _eos;
+ }
+
+ virtual bool err() const {
+ return _err;
+ }
+
+ virtual void clearErr() {
+ _eos = _err = false;
+ }
+
virtual uint32 read(void *dataPtr, uint32 dataSize);
- virtual int32 pos() const { return _pos; }
- virtual int32 size() const { return _len; }
+
+ virtual int32 pos() const {
+ return _pos;
+ }
+
+ virtual int32 size() const {
+ return _len;
+ }
+
virtual bool seek(int32 offset, int whence = SEEK_SET);
+
private:
- void close(JNIEnv* env);
+ void close(JNIEnv *env);
+
jmethodID MID_mark;
jmethodID MID_available;
jmethodID MID_close;
jmethodID MID_read;
jmethodID MID_reset;
jmethodID MID_skip;
+
jobject _input_stream;
jsize _buflen;
jbyteArray _buf;
@@ -73,8 +93,10 @@ private:
bool _err;
};
-JavaInputStream::JavaInputStream(JNIEnv* env, jobject is) :
- _eos(false), _err(false), _pos(0)
+JavaInputStream::JavaInputStream(JNIEnv *env, jobject is) :
+ _eos(false),
+ _err(false),
+ _pos(0)
{
_input_stream = env->NewGlobalRef(is);
_buflen = 8192;
@@ -97,53 +119,61 @@ JavaInputStream::JavaInputStream(JNIEnv* env, jobject is) :
// Mark start of stream, so we can reset back to it.
// readlimit is set to something bigger than anything we might
// want to seek within.
- env->CallVoidMethod(_input_stream, MID_mark, 10*1024*1024);
+ env->CallVoidMethod(_input_stream, MID_mark, 10 * 1024 * 1024);
_len = env->CallIntMethod(_input_stream, MID_available);
}
JavaInputStream::~JavaInputStream() {
- JNIEnv* env = JNU_GetEnv();
+ JNIEnv *env = JNU_GetEnv();
close(env);
+
env->DeleteGlobalRef(_buf);
env->DeleteGlobalRef(_input_stream);
}
-void JavaInputStream::close(JNIEnv* env) {
+void JavaInputStream::close(JNIEnv *env) {
env->CallVoidMethod(_input_stream, MID_close);
+
if (env->ExceptionCheck())
env->ExceptionClear();
}
uint32 JavaInputStream::read(void *dataPtr, uint32 dataSize) {
- JNIEnv* env = JNU_GetEnv();
+ JNIEnv *env = JNU_GetEnv();
if (_buflen < dataSize) {
_buflen = dataSize;
+
env->DeleteGlobalRef(_buf);
_buf = static_cast<jbyteArray>(env->NewGlobalRef(env->NewByteArray(_buflen)));
}
jint ret = env->CallIntMethod(_input_stream, MID_read, _buf, 0, dataSize);
+
if (env->ExceptionCheck()) {
warning("Exception during JavaInputStream::read(%p, %d)",
dataPtr, dataSize);
+
env->ExceptionDescribe();
env->ExceptionClear();
+
_err = true;
ret = -1;
} else if (ret == -1) {
_eos = true;
ret = 0;
} else {
- env->GetByteArrayRegion(_buf, 0, ret, static_cast<jbyte*>(dataPtr));
+ env->GetByteArrayRegion(_buf, 0, ret, static_cast<jbyte *>(dataPtr));
_pos += ret;
}
+
return ret;
}
bool JavaInputStream::seek(int32 offset, int whence) {
- JNIEnv* env = JNU_GetEnv();
+ JNIEnv *env = JNU_GetEnv();
uint32 newpos;
+
switch (whence) {
case SEEK_SET:
newpos = offset;
@@ -165,37 +195,47 @@ bool JavaInputStream::seek(int32 offset, int whence) {
} else {
// Can't skip backwards, so jump back to start and skip from there.
env->CallVoidMethod(_input_stream, MID_reset);
+
if (env->ExceptionCheck()) {
warning("Failed to rewind to start of asset stream");
+
env->ExceptionDescribe();
env->ExceptionClear();
+
return false;
}
+
_pos = 0;
skip_bytes = newpos;
}
while (skip_bytes > 0) {
jlong ret = env->CallLongMethod(_input_stream, MID_skip, skip_bytes);
+
if (env->ExceptionCheck()) {
warning("Failed to skip %ld bytes into asset stream",
static_cast<long>(skip_bytes));
+
env->ExceptionDescribe();
env->ExceptionClear();
+
return false;
} else if (ret == 0) {
warning("InputStream->skip(%ld) didn't skip any bytes. Aborting seek.",
static_cast<long>(skip_bytes));
- return false; // No point looping forever...
+
+ // No point looping forever...
+ return false;
}
+
_pos += ret;
skip_bytes -= ret;
}
+
_eos = false;
return true;
}
-
// Must match android.content.res.AssetFileDescriptor.UNKNOWN_LENGTH
const jlong UNKNOWN_LENGTH = -1;
@@ -203,17 +243,36 @@ const jlong UNKNOWN_LENGTH = -1;
// worth optimising for.
class AssetFdReadStream : public Common::SeekableReadStream {
public:
- AssetFdReadStream(JNIEnv* env, jobject assetfd);
+ AssetFdReadStream(JNIEnv *env, jobject assetfd);
virtual ~AssetFdReadStream();
- virtual bool eos() const { return _eos; }
- virtual bool err() const { return _err; }
- virtual void clearErr() { _eos = _err = false; }
+
+ virtual bool eos() const {
+ return _eos;
+ }
+
+ virtual bool err() const {
+ return _err;
+ }
+
+ virtual void clearErr() {
+ _eos = _err = false;
+ }
+
virtual uint32 read(void *dataPtr, uint32 dataSize);
- virtual int32 pos() const { return _pos; }
- virtual int32 size() const { return _declared_len; }
+
+ virtual int32 pos() const {
+ return _pos;
+ }
+
+ virtual int32 size() const {
+ return _declared_len;
+ }
+
virtual bool seek(int32 offset, int whence = SEEK_SET);
+
private:
- void close(JNIEnv* env);
+ void close(JNIEnv *env);
+
int _fd;
jmethodID MID_close;
jobject _assetfd;
@@ -224,8 +283,10 @@ private:
bool _err;
};
-AssetFdReadStream::AssetFdReadStream(JNIEnv* env, jobject assetfd) :
- _eos(false), _err(false), _pos(0)
+AssetFdReadStream::AssetFdReadStream(JNIEnv *env, jobject assetfd) :
+ _eos(false),
+ _err(false),
+ _pos(0)
{
_assetfd = env->NewGlobalRef(assetfd);
@@ -248,17 +309,21 @@ AssetFdReadStream::AssetFdReadStream(JNIEnv* env, jobject assetfd) :
assert(MID_getFileDescriptor);
jobject javafd = env->CallObjectMethod(_assetfd, MID_getFileDescriptor);
assert(javafd);
+
jclass fd_cls = env->GetObjectClass(javafd);
jfieldID FID_descriptor = env->GetFieldID(fd_cls, "descriptor", "I");
assert(FID_descriptor);
+
_fd = env->GetIntField(javafd, FID_descriptor);
}
AssetFdReadStream::~AssetFdReadStream() {
- JNIEnv* env = JNU_GetEnv();
+ JNIEnv *env = JNU_GetEnv();
env->CallVoidMethod(_assetfd, MID_close);
+
if (env->ExceptionCheck())
env->ExceptionClear();
+
env->DeleteGlobalRef(_assetfd);
}
@@ -268,13 +333,16 @@ uint32 AssetFdReadStream::read(void *dataPtr, uint32 dataSize) {
if (dataSize > cap)
dataSize = cap;
}
+
int ret = ::read(_fd, dataPtr, dataSize);
+
if (ret == 0)
_eos = true;
else if (ret == -1)
_err = true;
else
_pos += ret;
+
return ret;
}
@@ -282,42 +350,49 @@ bool AssetFdReadStream::seek(int32 offset, int whence) {
if (whence == SEEK_SET) {
if (_declared_len != UNKNOWN_LENGTH && offset > _declared_len)
offset = _declared_len;
+
offset += _start_off;
} else if (whence == SEEK_END && _declared_len != UNKNOWN_LENGTH) {
whence = SEEK_SET;
offset = _start_off + _declared_len + offset;
}
+
int ret = lseek(_fd, offset, whence);
+
if (ret == -1)
return false;
+
_pos = ret - _start_off;
_eos = false;
+
return true;
}
AndroidAssetArchive::AndroidAssetArchive(jobject am) {
- JNIEnv* env = JNU_GetEnv();
+ JNIEnv *env = JNU_GetEnv();
_am = env->NewGlobalRef(am);
jclass cls = env->GetObjectClass(_am);
MID_open = env->GetMethodID(cls, "open",
"(Ljava/lang/String;I)Ljava/io/InputStream;");
assert(MID_open);
+
MID_openFd = env->GetMethodID(cls, "openFd",
- "(Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;");
+ "(Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;");
assert(MID_openFd);
+
MID_list = env->GetMethodID(cls, "list",
"(Ljava/lang/String;)[Ljava/lang/String;");
assert(MID_list);
}
AndroidAssetArchive::~AndroidAssetArchive() {
- JNIEnv* env = JNU_GetEnv();
+ JNIEnv *env = JNU_GetEnv();
env->DeleteGlobalRef(_am);
}
bool AndroidAssetArchive::hasFile(const Common::String &name) {
- JNIEnv* env = JNU_GetEnv();
+ JNIEnv *env = JNU_GetEnv();
jstring path = env->NewStringUTF(name.c_str());
jobject result = env->CallObjectMethod(_am, MID_open, path, ACCESS_UNKNOWN);
if (env->ExceptionCheck()) {
@@ -326,15 +401,18 @@ bool AndroidAssetArchive::hasFile(const Common::String &name) {
//env->ExceptionDescribe();
env->ExceptionClear();
env->DeleteLocalRef(path);
+
return false;
}
+
env->DeleteLocalRef(result);
env->DeleteLocalRef(path);
+
return true;
}
int AndroidAssetArchive::listMembers(Common::ArchiveMemberList &member_list) {
- JNIEnv* env = JNU_GetEnv();
+ JNIEnv *env = JNU_GetEnv();
Common::List<Common::String> dirlist;
dirlist.push_back("");
@@ -345,29 +423,36 @@ int AndroidAssetArchive::listMembers(Common::ArchiveMemberList &member_list) {
jstring jpath = env->NewStringUTF(dir.c_str());
jobjectArray jpathlist = static_cast<jobjectArray>(env->CallObjectMethod(_am, MID_list, jpath));
+
if (env->ExceptionCheck()) {
warning("Error while calling AssetManager->list(%s). Ignoring.",
dir.c_str());
env->ExceptionDescribe();
env->ExceptionClear();
- continue; // May as well keep going ...
+
+ // May as well keep going ...
+ continue;
}
+
env->DeleteLocalRef(jpath);
for (jsize i = 0; i < env->GetArrayLength(jpathlist); ++i) {
jstring elem = (jstring)env->GetObjectArrayElement(jpathlist, i);
- const char* p = env->GetStringUTFChars(elem, NULL);
+ const char *p = env->GetStringUTFChars(elem, 0);
Common::String thispath = dir;
+
if (!thispath.empty())
thispath += "/";
+
thispath += p;
// Assume files have a . in them, and directories don't
if (strchr(p, '.')) {
member_list.push_back(getMember(thispath));
++count;
- } else
+ } else {
dirlist.push_back(thispath);
+ }
env->ReleaseStringUTFChars(elem, p);
env->DeleteLocalRef(elem);
@@ -384,14 +469,15 @@ Common::ArchiveMemberPtr AndroidAssetArchive::getMember(const Common::String &na
}
Common::SeekableReadStream *AndroidAssetArchive::createReadStreamForMember(const Common::String &path) const {
- JNIEnv* env = JNU_GetEnv();
+ JNIEnv *env = JNU_GetEnv();
jstring jpath = env->NewStringUTF(path.c_str());
// Try openFd() first ...
jobject afd = env->CallObjectMethod(_am, MID_openFd, jpath);
+
if (env->ExceptionCheck())
env->ExceptionClear();
- else if (afd != NULL) {
+ else if (afd != 0) {
// success :)
env->DeleteLocalRef(jpath);
return new AssetFdReadStream(env, afd);
@@ -399,13 +485,15 @@ Common::SeekableReadStream *AndroidAssetArchive::createReadStreamForMember(const
// ... and fallback to normal open() if that doesn't work
jobject is = env->CallObjectMethod(_am, MID_open, jpath, ACCESS_RANDOM);
+
if (env->ExceptionCheck()) {
// Assume FileNotFoundException
//warning("Error opening %s", path.c_str());
//env->ExceptionDescribe();
env->ExceptionClear();
env->DeleteLocalRef(jpath);
- return NULL;
+
+ return 0;
}
return new JavaInputStream(env, is);
diff --git a/backends/platform/android/video.cpp b/backends/platform/android/video.cpp
index b9c3f9a1f8..f5ec0b45d9 100644
--- a/backends/platform/android/video.cpp
+++ b/backends/platform/android/video.cpp
@@ -54,7 +54,7 @@
#if 0
#define CHECK_GL_ERROR() checkGlError(__FILE__, __LINE__)
-static const char* getGlErrStr(GLenum error) {
+static const char *getGlErrStr(GLenum error) {
switch (error) {
case GL_NO_ERROR: return "GL_NO_ERROR";
case GL_INVALID_ENUM: return "GL_INVALID_ENUM";
@@ -68,7 +68,7 @@ static const char* getGlErrStr(GLenum error) {
snprintf(buf, sizeof(buf), "(Unknown GL error code 0x%x)", error);
return buf;
}
-static void checkGlError(const char* file, int line) {
+static void checkGlError(const char *file, int line) {
GLenum error = glGetError();
if (error != GL_NO_ERROR)
warning("%s:%d: GL error: %s", file, line, getGlErrStr(error));
@@ -84,7 +84,7 @@ static bool draw_tex_supported = false;
#endif
static inline GLfixed xdiv(int numerator, int denominator) {
- assert(numerator < (1<<16));
+ assert(numerator < (1 << 16));
return (numerator << 16) / denominator;
}
@@ -93,21 +93,27 @@ static T nextHigher2(T k) {
if (k == 0)
return 1;
--k;
- for (uint i = 1; i < sizeof(T)*CHAR_BIT; i <<= 1)
+
+ for (uint i = 1; i < sizeof(T) * CHAR_BIT; i <<= 1)
k = k | k >> i;
+
return k + 1;
}
void GLESTexture::initGLExtensions() {
- const char* ext_string =
- reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
+ const char *ext_string =
+ reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
+
__android_log_print(ANDROID_LOG_INFO, LOG_TAG,
- "Extensions: %s", ext_string);
+ "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;
+
#ifdef GL_OES_draw_texture
if (token == "GL_OES_draw_texture")
draw_tex_supported = true;
@@ -121,11 +127,12 @@ GLESTexture::GLESTexture() :
_all_dirty(true)
{
glGenTextures(1, &_texture_name);
+
// This all gets reset later in allocBuffer:
_surface.w = 0;
_surface.h = 0;
_surface.pitch = _texture_width;
- _surface.pixels = NULL;
+ _surface.pixels = 0;
_surface.bytesPerPixel = 0;
}
@@ -153,8 +160,8 @@ void GLESTexture::allocBuffer(GLuint w, GLuint h) {
_surface.h = h;
_surface.bytesPerPixel = bpp;
+ // Already allocated a sufficiently large buffer?
if (w <= _texture_width && h <= _texture_height)
- // Already allocated a sufficiently large buffer
return;
if (npot_supported) {
@@ -164,6 +171,7 @@ void GLESTexture::allocBuffer(GLuint w, GLuint h) {
_texture_width = nextHigher2(_surface.w);
_texture_height = nextHigher2(_surface.h);
}
+
_surface.pitch = _texture_width * bpp;
// Allocate room for the texture now, but pixel data gets uploaded
@@ -178,14 +186,15 @@ void GLESTexture::allocBuffer(GLuint w, GLuint h) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
CHECK_GL_ERROR();
glTexImage2D(GL_TEXTURE_2D, 0, glFormat(),
- _texture_width, _texture_height,
- 0, glFormat(), glType(), NULL);
+ _texture_width, _texture_height,
+ 0, glFormat(), glType(), 0);
CHECK_GL_ERROR();
}
void GLESTexture::updateBuffer(GLuint x, GLuint y, GLuint w, GLuint h,
- const void* buf, int pitch) {
+ const void *buf, int pitch) {
ENTER("updateBuffer(%u, %u, %u, %u, %p, %d)", x, y, w, h, buf, pitch);
+
glBindTexture(GL_TEXTURE_2D, _texture_name);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@@ -202,20 +211,22 @@ void GLESTexture::updateBuffer(GLuint x, GLuint y, GLuint w, GLuint h,
#if TEXSUBIMAGE_IS_EXPENSIVE
byte tmpbuf[w * h * bytesPerPixel()];
- const byte* src = static_cast<const byte*>(buf);
- byte* dst = tmpbuf;
+ const byte *src = static_cast<const byte *>(buf);
+ byte *dst = tmpbuf;
GLuint count = h;
+
do {
memcpy(dst, src, w * bytesPerPixel());
dst += w * bytesPerPixel();
src += pitch;
} while (--count);
+
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h,
glFormat(), glType(), tmpbuf);
#else
// This version avoids the intermediate copy at the expense of
// repeat glTexSubImage2D calls. On some devices this is worse.
- const byte* src = static_cast<const byte*>(buf);
+ const byte *src = static_cast<const byte *>(buf);
do {
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y,
w, 1, glFormat(), glType(), src);
@@ -241,9 +252,13 @@ void GLESTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
// Still a work-in-progress - disabled for now.
if (false && draw_tex_supported && paletteSize() == 0) {
//glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- const GLint crop[4] = {0, _surface.h, _surface.w, -_surface.h};
+ const GLint crop[4] = { 0, _surface.h, _surface.w, -_surface.h };
+
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
- glColor4ub(0xff, 0xff, 0xff, 0xff); // Android GLES bug?
+
+ // Android GLES bug?
+ glColor4ub(0xff, 0xff, 0xff, 0xff);
+
glDrawTexiOES(x, y, 0, w, h);
} else
#endif
@@ -256,18 +271,20 @@ void GLESTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
0, tex_height,
tex_width, tex_height,
};
+
glTexCoordPointer(2, GL_FIXED, 0, texcoords);
const GLshort vertices[] = {
- x, y,
- x+w, y,
- x, y+h,
- x+w, y+h,
+ x, y,
+ x + w, y,
+ x, y + h,
+ x + w, y + h,
};
+
glVertexPointer(2, GL_SHORT, 0, vertices);
assert(ARRAYSIZE(vertices) == ARRAYSIZE(texcoords));
- glDrawArrays(GL_TRIANGLE_STRIP, 0, ARRAYSIZE(vertices)/2);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, ARRAYSIZE(vertices) / 2);
}
_all_dirty = false;
@@ -276,7 +293,7 @@ void GLESTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
GLESPaletteTexture::GLESPaletteTexture() :
GLESTexture(),
- _texture(NULL)
+ _texture(0)
{
}
@@ -291,8 +308,8 @@ void GLESPaletteTexture::allocBuffer(GLuint w, GLuint h) {
_surface.h = h;
_surface.bytesPerPixel = bpp;
+ // Already allocated a sufficiently large buffer?
if (w <= _texture_width && h <= _texture_height)
- // Already allocated a sufficiently large buffer
return;
if (npot_supported) {
@@ -306,12 +323,14 @@ void GLESPaletteTexture::allocBuffer(GLuint w, GLuint h) {
// Texture gets uploaded later (from drawTexture())
- byte* new_buffer = new byte[paletteSize() +
+ byte *new_buffer = new byte[paletteSize() +
_texture_width * _texture_height * bytesPerPixel()];
if (_texture) {
- memcpy(new_buffer, _texture, paletteSize()); // preserve palette
+ // preserve palette
+ memcpy(new_buffer, _texture, paletteSize());
delete[] _texture;
}
+
_texture = new_buffer;
_surface.pixels = _texture + paletteSize();
}
@@ -323,12 +342,13 @@ void GLESPaletteTexture::fillBuffer(byte x) {
}
void GLESPaletteTexture::updateBuffer(GLuint x, GLuint y,
- GLuint w, GLuint h,
- const void* buf, int pitch) {
+ GLuint w, GLuint h,
+ const void *buf, int pitch) {
_all_dirty = true;
- const byte* src = static_cast<const byte*>(buf);
- byte* dst = static_cast<byte*>(_surface.getBasePtr(x, y));
+ const byte * src = static_cast<const byte *>(buf);
+ byte *dst = static_cast<byte *>(_surface.getBasePtr(x, y));
+
do {
memcpy(dst, src, w * bytesPerPixel());
dst += _surface.pitch;
@@ -339,9 +359,10 @@ void GLESPaletteTexture::updateBuffer(GLuint x, GLuint y,
void GLESPaletteTexture::uploadTexture() const {
const size_t texture_size =
paletteSize() + _texture_width * _texture_height * bytesPerPixel();
+
glCompressedTexImage2D(GL_TEXTURE_2D, 0, glType(),
- _texture_width, _texture_height,
- 0, texture_size, _texture);
+ _texture_width, _texture_height,
+ 0, texture_size, _texture);
CHECK_GL_ERROR();
}
diff --git a/backends/platform/android/video.h b/backends/platform/android/video.h
index 4b73508907..1e00f9bd57 100644
--- a/backends/platform/android/video.h
+++ b/backends/platform/android/video.h
@@ -38,30 +38,54 @@ public:
GLESTexture();
virtual ~GLESTexture();
+
virtual void reinitGL();
virtual void allocBuffer(GLuint width, GLuint height);
- const Graphics::Surface* surface_const() const { return &_surface; }
- GLuint width() const { return _surface.w; }
- GLuint height() const { return _surface.h; }
- GLuint texture_name() const { return _texture_name; }
- bool dirty() const { return _all_dirty || !_dirty_rect.isEmpty(); }
+
+ const Graphics::Surface *surface_const() const {
+ return &_surface;
+ }
+
+ GLuint width() const {
+ return _surface.w;
+ }
+
+ GLuint height() const {
+ return _surface.h;
+ }
+
+ GLuint texture_name() const {
+ return _texture_name;
+ }
+
+ bool dirty() const {
+ return _all_dirty || !_dirty_rect.isEmpty();
+ }
+
virtual void updateBuffer(GLuint x, GLuint y, GLuint width, GLuint height,
- const void* buf, int pitch);
+ const void *buf, int pitch);
virtual void fillBuffer(byte x);
+
virtual void drawTexture() {
drawTexture(0, 0, _surface.w, _surface.h);
}
+
virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h);
protected:
virtual byte bytesPerPixel() const = 0;
virtual GLenum glFormat() const = 0;
virtual GLenum glType() const = 0;
- virtual size_t paletteSize() const { return 0; };
+
+ virtual size_t paletteSize() const {
+ return 0;
+ }
+
void setDirty() {
_all_dirty = true;
_dirty_rect = Common::Rect();
}
+
void setDirtyRect(const Common::Rect& r) {
if (!_all_dirty) {
if (_dirty_rect.isEmpty())
@@ -70,28 +94,47 @@ protected:
_dirty_rect.extend(r);
}
}
+
GLuint _texture_name;
Graphics::Surface _surface;
GLuint _texture_width;
GLuint _texture_height;
bool _all_dirty;
- Common::Rect _dirty_rect; // Covers dirty area
+
+ // Covers dirty area
+ Common::Rect _dirty_rect;
};
// RGBA4444 texture
class GLES4444Texture : public GLESTexture {
protected:
- virtual byte bytesPerPixel() const { return 2; }
- virtual GLenum glFormat() const { return GL_RGBA; }
- virtual GLenum glType() const { return GL_UNSIGNED_SHORT_4_4_4_4; }
+ virtual byte bytesPerPixel() const {
+ return 2;
+ }
+
+ virtual GLenum glFormat() const {
+ return GL_RGBA;
+ }
+
+ virtual GLenum glType() const {
+ return GL_UNSIGNED_SHORT_4_4_4_4;
+ }
};
// RGB565 texture
class GLES565Texture : public GLESTexture {
protected:
- virtual byte bytesPerPixel() const { return 2; }
- virtual GLenum glFormat() const { return GL_RGB; }
- virtual GLenum glType() const { return GL_UNSIGNED_SHORT_5_6_5; }
+ virtual byte bytesPerPixel() const {
+ return 2;
+ }
+
+ virtual GLenum glFormat() const {
+ return GL_RGB;
+ }
+
+ virtual GLenum glType() const {
+ return GL_UNSIGNED_SHORT_5_6_5;
+ }
};
// RGB888 256-entry paletted texture
@@ -99,42 +142,73 @@ class GLESPaletteTexture : public GLESTexture {
public:
GLESPaletteTexture();
virtual ~GLESPaletteTexture();
+
virtual void allocBuffer(GLuint width, GLuint height);
virtual void updateBuffer(GLuint x, GLuint y, GLuint width, GLuint height,
- const void* buf, int pitch);
- Graphics::Surface* surface() {
+ const void *buf, int pitch);
+
+ Graphics::Surface *surface() {
setDirty();
return &_surface;
}
- void* pixels() {
+
+ void *pixels() {
setDirty();
return _surface.pixels;
}
- const byte* palette_const() const { return _texture; };
- byte* palette() {
+
+ const byte *palette_const() const {
+ return _texture;
+ };
+
+ byte *palette() {
setDirty();
return _texture;
};
+
virtual void drawTexture() {
drawTexture(0, 0, _surface.w, _surface.h);
}
+
virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h);
virtual void fillBuffer(byte x);
+
protected:
- virtual byte bytesPerPixel() const { return 1; }
- virtual GLenum glFormat() const { return GL_RGB; }
- virtual GLenum glType() const { return GL_PALETTE8_RGB8_OES; }
- virtual size_t paletteSize() const { return 256 * 3; };
+ virtual byte bytesPerPixel() const {
+ return 1;
+ }
+
+ virtual GLenum glFormat() const {
+ return GL_RGB;
+ }
+
+ virtual GLenum glType() const {
+ return GL_PALETTE8_RGB8_OES;
+ }
+
+ virtual size_t paletteSize() const {
+ return 256 * 3;
+ }
+
virtual void uploadTexture() const;
- byte* _texture;
+
+ byte *_texture;
};
// RGBA8888 256-entry paletted texture
class GLESPaletteATexture : public GLESPaletteTexture {
protected:
- virtual GLenum glFormat() const { return GL_RGBA; }
- virtual GLenum glType() const { return GL_PALETTE8_RGBA8_OES; }
- virtual size_t paletteSize() const { return 256 * 4; };
+ virtual GLenum glFormat() const {
+ return GL_RGBA;
+ }
+
+ virtual GLenum glType() const {
+ return GL_PALETTE8_RGBA8_OES;
+ }
+
+ virtual size_t paletteSize() const {
+ return 256 * 4;
+ }
};
#endif