[Scummvm-cvs-logs] scummvm master -> aa2a2e046b0a5979709c79deb84b6eea3c8f09d5
dhewg
dhewg at wiibrew.org
Sun Feb 27 10:17:45 CET 2011
This automated email contains information about 9 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
6b1c575d1d ANDROID: Remove another weird workaround
983e16b36a ANDROID: Formatting
25d895b859 ANDROID: Rework audio system
bea57f6950 AUDIO: Make mixCallback return the sample count
0e869a5cf0 ANDROID: Pause the AudioTrack when possible
d4c0501d1f ANDROID: Check audio buffer for silence
a73b2ec972 ANDROID: Remove unnecessary code
1c95d47cfa SWORD2: Respect screen pitch while postprocessing
aa2a2e046b SWORD2: Reduce overhead
Commit: 6b1c575d1d6471a922978559c69426b1f9856768
https://github.com/scummvm/scummvm/commit/6b1c575d1d6471a922978559c69426b1f9856768
Author: dhewg (dhewg at wiibrew.org)
Date: 2011-02-27T00:04:31-08:00
Commit Message:
ANDROID: Remove another weird workaround
Changed paths:
backends/platform/android/gfx.cpp
diff --git a/backends/platform/android/gfx.cpp b/backends/platform/android/gfx.cpp
index 35c91d7..8601a3b 100644
--- a/backends/platform/android/gfx.cpp
+++ b/backends/platform/android/gfx.cpp
@@ -401,7 +401,7 @@ void OSystem_Android::copyRectToOverlay(const OverlayColor *buf, int pitch,
_overlay_texture->updateBuffer(x, y, w, h, buf, pitch * sizeof(buf[0]));
// Shouldn't need this, but works around a 'blank screen' bug on Nexus1?
- updateScreen();
+ //updateScreen();
}
int16 OSystem_Android::getOverlayHeight() {
Commit: 983e16b36a68292021833aa9b69305a37ffe2f91
https://github.com/scummvm/scummvm/commit/983e16b36a68292021833aa9b69305a37ffe2f91
Author: dhewg (dhewg at wiibrew.org)
Date: 2011-02-27T00:04:31-08:00
Commit Message:
ANDROID: Formatting
Changed paths:
backends/platform/android/org/inodes/gus/scummvm/EditableSurfaceView.java
backends/platform/android/org/inodes/gus/scummvm/PluginProvider.java
backends/platform/android/org/inodes/gus/scummvm/ScummVM.java
backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java
backends/platform/android/org/inodes/gus/scummvm/ScummVMApplication.java
diff --git a/backends/platform/android/org/inodes/gus/scummvm/EditableSurfaceView.java b/backends/platform/android/org/inodes/gus/scummvm/EditableSurfaceView.java
index 1a0972d..cede7ee 100644
--- a/backends/platform/android/org/inodes/gus/scummvm/EditableSurfaceView.java
+++ b/backends/platform/android/org/inodes/gus/scummvm/EditableSurfaceView.java
@@ -19,7 +19,7 @@ public class EditableSurfaceView extends SurfaceView {
}
public EditableSurfaceView(Context context, AttributeSet attrs,
- int defStyle) {
+ int defStyle) {
super(context, attrs, defStyle);
}
@@ -40,7 +40,9 @@ public class EditableSurfaceView extends SurfaceView {
getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getWindowToken(), 0);
}
- return super.performEditorAction(actionCode); // Sends enter key
+
+ // Sends enter key
+ return super.performEditorAction(actionCode);
}
}
@@ -49,11 +51,12 @@ public class EditableSurfaceView extends SurfaceView {
outAttrs.initialCapsMode = 0;
outAttrs.initialSelEnd = outAttrs.initialSelStart = -1;
outAttrs.inputType = (InputType.TYPE_CLASS_TEXT |
- InputType.TYPE_TEXT_VARIATION_NORMAL |
- InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE);
+ InputType.TYPE_TEXT_VARIATION_NORMAL |
+ InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE);
outAttrs.imeOptions = (EditorInfo.IME_ACTION_DONE |
- EditorInfo.IME_FLAG_NO_EXTRACT_UI);
+ EditorInfo.IME_FLAG_NO_EXTRACT_UI);
return new MyInputConnection();
}
}
+
diff --git a/backends/platform/android/org/inodes/gus/scummvm/PluginProvider.java b/backends/platform/android/org/inodes/gus/scummvm/PluginProvider.java
index c94ab0a..3c91d9f 100644
--- a/backends/platform/android/org/inodes/gus/scummvm/PluginProvider.java
+++ b/backends/platform/android/org/inodes/gus/scummvm/PluginProvider.java
@@ -28,7 +28,7 @@ public class PluginProvider extends BroadcastReceiver {
try {
info = context.getPackageManager()
.getReceiverInfo(new ComponentName(context, this.getClass()),
- PackageManager.GET_META_DATA);
+ PackageManager.GET_META_DATA);
} catch (PackageManager.NameNotFoundException e) {
Log.e(LOG_TAG, "Error finding my own info?", e);
return;
@@ -38,17 +38,17 @@ public class PluginProvider extends BroadcastReceiver {
if (mylib != null) {
ArrayList<String> all_libs =
extras.getStringArrayList(ScummVMApplication.EXTRA_UNPACK_LIBS);
-
all_libs.add(new Uri.Builder()
- .scheme("plugin")
- .authority(context.getPackageName())
- .path(mylib)
- .toString());
+ .scheme("plugin")
+ .authority(context.getPackageName())
+ .path(mylib)
+ .toString());
extras.putStringArrayList(ScummVMApplication.EXTRA_UNPACK_LIBS,
- all_libs);
+ all_libs);
}
setResultExtras(extras);
}
}
+
diff --git a/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java b/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java
index 0e905f4..698e508 100644
--- a/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java
+++ b/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java
@@ -35,16 +35,19 @@ import java.util.LinkedHashMap;
public class ScummVM implements SurfaceHolder.Callback {
protected final static String LOG_TAG = "ScummVM";
- private final int AUDIO_FRAME_SIZE = 2 * 2; // bytes. 16bit audio * stereo
+ // bytes. 16bit audio * stereo
+ private final int AUDIO_FRAME_SIZE = 2 * 2;
public static class AudioSetupException extends Exception {}
- private long nativeScummVM; // native code hangs itself here
+ // native code hangs itself here
+ private long nativeScummVM;
boolean scummVMRunning = false;
private native void create(AssetManager am);
public ScummVM(Context context) {
- create(context.getAssets()); // Init C++ code, set nativeScummVM
+ // Init C++ code, set nativeScummVM
+ create(context.getAssets());
}
private native void nativeDestroy();
@@ -55,6 +58,7 @@ public class ScummVM implements SurfaceHolder.Callback {
nativeScummVM = 0;
}
}
+
protected void finalize() {
destroy();
}
@@ -62,17 +66,17 @@ public class ScummVM implements SurfaceHolder.Callback {
// Surface creation:
// GUI thread: create surface, release lock
// ScummVM thread: acquire lock (block), read surface
- //
+
// Surface deletion:
// GUI thread: post event, acquire lock (block), return
// ScummVM thread: read event, free surface, release lock
- //
+
// In other words, ScummVM thread does this:
// acquire lock
// setup surface
// when SCREEN_CHANGED arrives:
- // destroy surface
- // release lock
+ // destroy surface
+ // release lock
// back to acquire lock
static final int configSpec[] = {
EGL10.EGL_RED_SIZE, 5,
@@ -82,6 +86,7 @@ public class ScummVM implements SurfaceHolder.Callback {
EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT,
EGL10.EGL_NONE,
};
+
EGL10 egl;
EGLDisplay eglDisplay = EGL10.EGL_NO_DISPLAY;
EGLConfig eglConfig;
@@ -96,7 +101,7 @@ public class ScummVM implements SurfaceHolder.Callback {
}
public void surfaceChanged(SurfaceHolder holder, int format,
- int width, int height) {
+ int width, int height) {
// Disabled while I debug GL problems
pushEvent(new Event(Event.EVENT_SCREEN_CHANGED));
}
@@ -111,6 +116,7 @@ public class ScummVM implements SurfaceHolder.Callback {
// For debugging
private static final Map<String, Integer> attribs;
+
static {
attribs = new LinkedHashMap<String, Integer>();
attribs.put("CONFIG_ID", EGL10.EGL_CONFIG_ID);
@@ -141,11 +147,14 @@ public class ScummVM implements SurfaceHolder.Callback {
attribs.put("TRANSPARENT_GREEN_VALUE", EGL10.EGL_TRANSPARENT_GREEN_VALUE);
attribs.put("TRANSPARENT_BLUE_VALUE", EGL10.EGL_TRANSPARENT_BLUE_VALUE);
}
+
private void dumpEglConfig(EGLConfig config) {
int[] value = new int[1];
+
for (Map.Entry<String, Integer> entry : attribs.entrySet()) {
egl.eglGetConfigAttrib(eglDisplay, config,
- entry.getValue(), value);
+ entry.getValue(), value);
+
if (value[0] == EGL10.EGL_NONE)
Log.d(LOG_TAG, entry.getKey() + ": NONE");
else
@@ -157,12 +166,15 @@ public class ScummVM implements SurfaceHolder.Callback {
private void createScummVMGLContext() {
egl = (EGL10)EGLContext.getEGL();
eglDisplay = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+
int[] version = new int[2];
egl.eglInitialize(eglDisplay, version);
+
int[] num_config = new int[1];
egl.eglChooseConfig(eglDisplay, configSpec, null, 0, num_config);
final int numConfigs = num_config[0];
+
if (numConfigs <= 0)
throw new IllegalArgumentException("No configs match configSpec");
@@ -179,13 +191,15 @@ public class ScummVM implements SurfaceHolder.Callback {
// Android's eglChooseConfig is busted in several versions and
// devices so we have to filter/rank the configs again ourselves.
eglConfig = chooseEglConfig(configs);
+
if (false) {
Log.d(LOG_TAG, String.format("Chose EGL config from %d possibilities.", numConfigs));
dumpEglConfig(eglConfig);
}
eglContext = egl.eglCreateContext(eglDisplay, eglConfig,
- EGL10.EGL_NO_CONTEXT, null);
+ EGL10.EGL_NO_CONTEXT, null);
+
if (eglContext == EGL10.EGL_NO_CONTEXT)
throw new RuntimeException("Failed to create context");
}
@@ -198,32 +212,43 @@ public class ScummVM implements SurfaceHolder.Callback {
for (int i = 0; i < configs.length; i++) {
EGLConfig config = configs[i];
int score = 10000;
+
egl.eglGetConfigAttrib(eglDisplay, config,
- EGL10.EGL_SURFACE_TYPE, value);
+ EGL10.EGL_SURFACE_TYPE, value);
+
+ // must have
if ((value[0] & EGL10.EGL_WINDOW_BIT) == 0)
- continue; // must have
+ continue;
egl.eglGetConfigAttrib(eglDisplay, config,
- EGL10.EGL_CONFIG_CAVEAT, value);
+ EGL10.EGL_CONFIG_CAVEAT, value);
+
if (value[0] != EGL10.EGL_NONE)
score -= 1000;
// Must be at least 555, but then smaller is better
- final int[] colorBits = {EGL10.EGL_RED_SIZE,
- EGL10.EGL_GREEN_SIZE,
- EGL10.EGL_BLUE_SIZE,
- EGL10.EGL_ALPHA_SIZE};
+ final int[] colorBits = { EGL10.EGL_RED_SIZE,
+ EGL10.EGL_GREEN_SIZE,
+ EGL10.EGL_BLUE_SIZE,
+ EGL10.EGL_ALPHA_SIZE
+ };
+
for (int component : colorBits) {
- egl.eglGetConfigAttrib(eglDisplay, config,
- component, value);
+ egl.eglGetConfigAttrib(eglDisplay, config, component, value);
+
+ // boost if >5 bits accuracy
if (value[0] >= 5)
- score += 10; // boost if >5 bits accuracy
- score -= value[0]; // penalize for wasted bits
+ score += 10;
+
+ // penalize for wasted bits
+ score -= value[0];
}
egl.eglGetConfigAttrib(eglDisplay, config,
- EGL10.EGL_DEPTH_SIZE, value);
- score -= value[0]; // penalize for wasted bits
+ EGL10.EGL_DEPTH_SIZE, value);
+
+ // penalize for wasted bits
+ score -= value[0];
if (score > bestScore) {
best = i;
@@ -248,28 +273,35 @@ public class ScummVM implements SurfaceHolder.Callback {
Log.e(LOG_TAG, "Interrupted while waiting for surface lock", e);
return;
}
+
eglSurface = egl.eglCreateWindowSurface(eglDisplay, eglConfig,
nativeSurface, null);
+
if (eglSurface == EGL10.EGL_NO_SURFACE)
Log.e(LOG_TAG, "CreateWindowSurface failed!");
+
egl.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
GL10 gl = (GL10)eglContext.getGL();
if (_log_version) {
Log.i(LOG_TAG, String.format("Using EGL %s (%s); GL %s/%s (%s)",
- egl.eglQueryString(eglDisplay, EGL10.EGL_VERSION),
- egl.eglQueryString(eglDisplay, EGL10.EGL_VENDOR),
- gl.glGetString(GL10.GL_VERSION),
- gl.glGetString(GL10.GL_RENDERER),
- gl.glGetString(GL10.GL_VENDOR)));
- _log_version = false; // only log this once
+ egl.eglQueryString(eglDisplay, EGL10.EGL_VERSION),
+ egl.eglQueryString(eglDisplay, EGL10.EGL_VENDOR),
+ gl.glGetString(GL10.GL_VERSION),
+ gl.glGetString(GL10.GL_RENDERER),
+ gl.glGetString(GL10.GL_VENDOR)));
+
+ // only log this once
+ _log_version = false;
}
int[] value = new int[1];
egl.eglQuerySurface(eglDisplay, eglSurface, EGL10.EGL_WIDTH, value);
+
int width = value[0];
egl.eglQuerySurface(eglDisplay, eglSurface, EGL10.EGL_HEIGHT, value);
+
int height = value[0];
Log.i(LOG_TAG, String.format("New surface is %dx%d", width, height));
setSurfaceSize(width, height);
@@ -279,7 +311,8 @@ public class ScummVM implements SurfaceHolder.Callback {
protected void destroyScummVMSurface() {
if (eglSurface != null) {
egl.eglMakeCurrent(eglDisplay, EGL10.EGL_NO_SURFACE,
- EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
+ EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
+
egl.eglDestroySurface(eglDisplay, eglSurface);
eglSurface = EGL10.EGL_NO_SURFACE;
}
@@ -298,6 +331,7 @@ public class ScummVM implements SurfaceHolder.Callback {
if (error == EGL11.EGL_CONTEXT_LOST)
return false;
}
+
return true;
}
@@ -324,6 +358,7 @@ public class ScummVM implements SurfaceHolder.Callback {
protected void showVirtualKeyboard(boolean enable) {}
protected String[] getSysArchives() { return new String[0]; }
protected String[] getPluginDirectories() { return new String[0]; }
+
protected void initBackend() throws AudioSetupException {
createScummVMGLContext();
initAudio();
@@ -375,17 +410,19 @@ public class ScummVM implements SurfaceHolder.Callback {
scummvm.audioMixCallback(buf);
offset = 0;
}
+
int len = buf.length - offset;
int ret = audio_track.write(buf, offset, len);
if (ret < 0) {
Log.w(LOG_TAG, String.format(
- "AudioTrack.write(%dB) returned error %d",
- buf.length, ret));
+ "AudioTrack.write(%dB) returned error %d",
+ buf.length, ret));
break;
} else if (ret != len) {
Log.w(LOG_TAG, String.format(
- "Short audio write. Wrote %dB, not %dB",
- ret, buf.length));
+ "Short audio write. Wrote %dB, not %dB",
+ ret, buf.length));
+
// Buffer is full, so yield cpu for a while
Thread.sleep(100);
}
@@ -409,21 +446,27 @@ public class ScummVM implements SurfaceHolder.Callback {
AudioFormat.CHANNEL_CONFIGURATION_STEREO,
AudioFormat.ENCODING_PCM_16BIT);
if (buf_size < 0) {
- int guess = AUDIO_FRAME_SIZE * sample_rate / 100; // 10ms of audio
+ // 10ms of audio
+ int guess = AUDIO_FRAME_SIZE * sample_rate / 100;
+
Log.w(LOG_TAG, String.format(
"Unable to get min audio buffer size (error %d). Guessing %dB.",
buf_size, guess));
+
buf_size = guess;
}
+
Log.d(LOG_TAG, String.format("Using %dB buffer for %dHZ audio",
- buf_size, sample_rate));
+ buf_size, sample_rate));
+
AudioTrack audio_track =
new AudioTrack(AudioManager.STREAM_MUSIC,
- sample_rate,
- AudioFormat.CHANNEL_CONFIGURATION_STEREO,
- AudioFormat.ENCODING_PCM_16BIT,
- buf_size,
- AudioTrack.MODE_STREAM);
+ sample_rate,
+ AudioFormat.CHANNEL_CONFIGURATION_STEREO,
+ AudioFormat.ENCODING_PCM_16BIT,
+ buf_size,
+ AudioTrack.MODE_STREAM);
+
if (audio_track.getState() != AudioTrack.STATE_INITIALIZED) {
Log.e(LOG_TAG, "Error initialising Android audio system.");
throw new AudioSetupException();
@@ -448,7 +491,7 @@ public class ScummVM implements SurfaceHolder.Callback {
final boolean sleep_for_debugger = false;
if (sleep_for_debugger) {
try {
- Thread.sleep(20*1000);
+ Thread.sleep(20 * 1000);
} catch (InterruptedException e) {
}
}
@@ -460,3 +503,4 @@ public class ScummVM implements SurfaceHolder.Callback {
System.load(libpath.getPath());
}
}
+
diff --git a/backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java b/backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java
index 8929809..0dd1109 100644
--- a/backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java
@@ -38,6 +38,7 @@ public class ScummVMActivity extends Activity {
// 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);
@@ -63,6 +64,7 @@ public class ScummVMActivity extends Activity {
scummvmRunning = true;
notifyAll();
}
+
super.initBackend();
}
@@ -104,6 +106,7 @@ public class ScummVMActivity extends Activity {
});
}
}
+
private MyScummVM scummvm;
private Thread scummvm_thread;
@@ -125,18 +128,18 @@ public class ScummVMActivity extends Activity {
.setIcon(android.R.drawable.ic_dialog_alert)
.setMessage(R.string.no_sdcard)
.setNegativeButton(R.string.quit,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog,
- int which) {
- finish();
- }
- })
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog,
+ int which) {
+ finish();
+ }
+ })
.show();
+
return;
}
SurfaceView main_surface = (SurfaceView)findViewById(R.id.main_surface);
-
main_surface.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
return onTouchEvent(event);
@@ -151,6 +154,7 @@ public class ScummVMActivity extends Activity {
// Start ScummVM
scummvm = new MyScummVM();
+
scummvm_thread = new Thread(new Runnable() {
public void run() {
try {
@@ -166,6 +170,7 @@ public class ScummVMActivity extends Activity {
}
}
}, "ScummVM");
+
scummvm_thread.start();
// Block UI thread until ScummVM has started. In particular,
@@ -207,14 +212,17 @@ public class ScummVMActivity extends Activity {
was_paused = true;
scummvm.pause();
}
+
super.onPause();
}
@Override
public void onResume() {
super.onResume();
+
if (scummvm != null && was_paused)
scummvm.resume();
+
was_paused = false;
}
@@ -222,16 +230,20 @@ public class ScummVMActivity extends Activity {
public void onStop() {
if (scummvm != null) {
scummvm.pushEvent(new Event(Event.EVENT_QUIT));
+
try {
- scummvm_thread.join(1000); // 1s timeout
+ // 1s timeout
+ scummvm_thread.join(1000);
} catch (InterruptedException e) {
Log.i(ScummVM.LOG_TAG, "Error while joining ScummVM thread", e);
}
}
+
super.onStop();
}
static final int MSG_MENU_LONG_PRESS = 1;
+
private final Handler keycodeMenuTimeoutHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
@@ -251,7 +263,7 @@ public class ScummVMActivity extends Activity {
@Override
public boolean onKeyMultiple(int keyCode, int repeatCount,
- KeyEvent kevent) {
+ KeyEvent kevent) {
return onKeyDown(keyCode, kevent);
}
@@ -261,12 +273,12 @@ public class ScummVMActivity extends Activity {
switch (keyCode) {
case KeyEvent.KEYCODE_MENU:
// Have to reimplement hold-down-menu-brings-up-softkeybd
- // ourselves, since we are otherwise hijacking the menu
- // key :(
+ // ourselves, since we are otherwise hijacking the menu key :(
// See com.android.internal.policy.impl.PhoneWindow.onKeyDownPanel()
// for the usual Android implementation of this feature.
+
+ // Ignore keyrepeat for menu
if (kevent.getRepeatCount() > 0)
- // Ignore keyrepeat for menu
return false;
boolean timeout_fired = !keycodeMenuTimeoutHandler.hasMessages(MSG_MENU_LONG_PRESS);
@@ -274,20 +286,24 @@ public class ScummVMActivity extends Activity {
if (kevent.getAction() == KeyEvent.ACTION_DOWN) {
keycodeMenuTimeoutHandler.sendMessageDelayed(keycodeMenuTimeoutHandler.obtainMessage(MSG_MENU_LONG_PRESS),
- ViewConfiguration.getLongPressTimeout());
+ ViewConfiguration.getLongPressTimeout());
return true;
}
if (kevent.getAction() == KeyEvent.ACTION_UP) {
if (!timeout_fired)
scummvm.pushEvent(new Event(Event.EVENT_MAINMENU));
+
return true;
}
+
return false;
+
case KeyEvent.KEYCODE_CAMERA:
case KeyEvent.KEYCODE_SEARCH:
_do_right_click = (kevent.getAction() == KeyEvent.ACTION_DOWN);
return true;
+
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_DPAD_UP:
case KeyEvent.KEYCODE_DPAD_DOWN:
@@ -299,45 +315,59 @@ public class ScummVMActivity extends Activity {
// Some other handsets lack a trackball, so the DPAD is
// the only way of moving the cursor.
int motion_action;
+
// FIXME: this logic is a mess.
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
switch (kevent.getAction()) {
case KeyEvent.ACTION_DOWN:
motion_action = MotionEvent.ACTION_DOWN;
break;
+
case KeyEvent.ACTION_UP:
motion_action = MotionEvent.ACTION_UP;
break;
- default: // ACTION_MULTIPLE
+
+ // ACTION_MULTIPLE
+ default:
return false;
}
- } else
+ } else {
motion_action = MotionEvent.ACTION_MOVE;
+ }
Event e = new Event(getEventType(motion_action));
+
e.mouse_x = 0;
e.mouse_y = 0;
e.mouse_relative = true;
+
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_UP:
e.mouse_y = -TRACKBALL_SCALE;
break;
+
case KeyEvent.KEYCODE_DPAD_DOWN:
e.mouse_y = TRACKBALL_SCALE;
break;
+
case KeyEvent.KEYCODE_DPAD_LEFT:
e.mouse_x = -TRACKBALL_SCALE;
break;
+
case KeyEvent.KEYCODE_DPAD_RIGHT:
e.mouse_x = TRACKBALL_SCALE;
break;
}
+
scummvm.pushEvent(e);
+
return true;
}
+
case KeyEvent.KEYCODE_BACK:
// skip isSystem() check and fall through to main code
break;
+
default:
if (kevent.isSystem())
return false;
@@ -352,51 +382,63 @@ public class ScummVMActivity extends Activity {
e.type = Event.EVENT_KEYDOWN;
e.synthetic = false;
break;
+
case KeyEvent.ACTION_UP:
e.type = Event.EVENT_KEYUP;
e.synthetic = false;
break;
+
case KeyEvent.ACTION_MULTIPLE:
// e.type is handled below
e.synthetic = true;
break;
+
default:
return false;
}
e.kbd_keycode = Event.androidKeyMap.containsKey(keyCode) ?
Event.androidKeyMap.get(keyCode) : Event.KEYCODE_INVALID;
+
e.kbd_ascii = kevent.getUnicodeChar();
+
if (e.kbd_ascii == 0)
e.kbd_ascii = e.kbd_keycode; // scummvm keycodes are mostly ascii
-
e.kbd_flags = 0;
+
if (kevent.isAltPressed())
e.kbd_flags |= Event.KBD_ALT;
- if (kevent.isSymPressed()) // no ctrl key in android, so use sym (?)
+
+ // no ctrl key in android, so use sym (?)
+ if (kevent.isSymPressed())
e.kbd_flags |= Event.KBD_CTRL;
+
if (kevent.isShiftPressed()) {
if (keyCode >= KeyEvent.KEYCODE_0 &&
- keyCode <= KeyEvent.KEYCODE_9) {
+ keyCode <= KeyEvent.KEYCODE_9) {
// Shift+number -> convert to F* key
int offset = keyCode == KeyEvent.KEYCODE_0 ?
10 : keyCode - KeyEvent.KEYCODE_1; // turn 0 into 10
+
e.kbd_keycode = Event.KEYCODE_F1 + offset;
e.kbd_ascii = Event.ASCII_F1 + offset;
- } else
+ } else {
e.kbd_flags |= Event.KBD_SHIFT;
+ }
}
if (kevent.getAction() == KeyEvent.ACTION_MULTIPLE) {
for (int i = 0; i <= kevent.getRepeatCount(); i++) {
e.type = Event.EVENT_KEYDOWN;
scummvm.pushEvent(e);
+
e.type = Event.EVENT_KEYUP;
scummvm.pushEvent(e);
}
- } else
+ } else {
scummvm.pushEvent(e);
+ }
return true;
}
@@ -407,11 +449,14 @@ public class ScummVMActivity extends Activity {
_last_click_was_right = _do_right_click;
return _last_click_was_right ?
Event.EVENT_RBUTTONDOWN : Event.EVENT_LBUTTONDOWN;
+
case MotionEvent.ACTION_UP:
return _last_click_was_right ?
Event.EVENT_RBUTTONUP : Event.EVENT_LBUTTONUP;
+
case MotionEvent.ACTION_MOVE:
return Event.EVENT_MOUSEMOVE;
+
default:
return Event.EVENT_INVALID;
}
@@ -429,6 +474,7 @@ public class ScummVMActivity extends Activity {
e.mouse_y =
(int)(event.getY() * event.getYPrecision()) * TRACKBALL_SCALE;
e.mouse_relative = true;
+
scummvm.pushEvent(e);
return true;
@@ -437,6 +483,7 @@ public class ScummVMActivity extends Activity {
@Override
public boolean onTouchEvent(MotionEvent event) {
int type = getEventType(event.getAction());
+
if (type == Event.EVENT_INVALID)
return false;
@@ -444,6 +491,7 @@ public class ScummVMActivity extends Activity {
e.mouse_x = (int)event.getX();
e.mouse_y = (int)event.getY();
e.mouse_relative = false;
+
scummvm.pushEvent(e);
return true;
@@ -453,6 +501,7 @@ public class ScummVMActivity extends Activity {
SurfaceView main_surface = (SurfaceView)findViewById(R.id.main_surface);
InputMethodManager imm = (InputMethodManager)
getSystemService(INPUT_METHOD_SERVICE);
+
if (show)
imm.showSoftInput(main_surface, InputMethodManager.SHOW_IMPLICIT);
else
@@ -460,3 +509,4 @@ public class ScummVMActivity extends Activity {
InputMethodManager.HIDE_IMPLICIT_ONLY);
}
}
+
diff --git a/backends/platform/android/org/inodes/gus/scummvm/ScummVMApplication.java b/backends/platform/android/org/inodes/gus/scummvm/ScummVMApplication.java
index 37a9d09..80735e2 100644
--- a/backends/platform/android/org/inodes/gus/scummvm/ScummVMApplication.java
+++ b/backends/platform/android/org/inodes/gus/scummvm/ScummVMApplication.java
@@ -13,11 +13,12 @@ public class ScummVMApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
+
// This is still on /data :(
cache_dir = getCacheDir();
// This is mounted noexec :(
//cache_dir = new File(Environment.getExternalStorageDirectory(),
- // "/.ScummVM.tmp");
+ // "/.ScummVM.tmp");
// This is owned by download manager and requires special
// permissions to access :(
//cache_dir = Environment.getDownloadCacheDirectory();
@@ -27,3 +28,4 @@ public class ScummVMApplication extends Application {
return cache_dir;
}
}
+
Commit: 25d895b859af0df8ea6daa85ba6ec5a0acb81f9d
https://github.com/scummvm/scummvm/commit/25d895b859af0df8ea6daa85ba6ec5a0acb81f9d
Author: dhewg (dhewg at wiibrew.org)
Date: 2011-02-27T00:04:36-08:00
Commit Message:
ANDROID: Rework audio system
Move the audio thread to the bright side
Changed paths:
backends/platform/android/android.cpp
backends/platform/android/android.h
backends/platform/android/jni.cpp
backends/platform/android/jni.h
backends/platform/android/org/inodes/gus/scummvm/ScummVM.java
backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java
diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp
index 4968e4b..08b9579 100644
--- a/backends/platform/android/android.cpp
+++ b/backends/platform/android/android.cpp
@@ -26,6 +26,7 @@
#if defined(__ANDROID__)
#include <sys/time.h>
+#include <sys/resource.h>
#include <time.h>
#include <unistd.h>
@@ -98,7 +99,9 @@ static inline T scalef(T in, float numerator, float denominator) {
return static_cast<float>(in) * numerator / denominator;
}
-OSystem_Android::OSystem_Android() :
+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),
_force_redraw(false),
_game_texture(0),
@@ -137,6 +140,10 @@ void *OSystem_Android::timerThreadFunc(void *arg) {
OSystem_Android *system = (OSystem_Android *)arg;
DefaultTimerManager *timer = (DefaultTimerManager *)(system->_timer);
+ // renice this thread to boost the audio thread
+ if (setpriority(PRIO_PROCESS, 0, 19) < 0)
+ warning("couldn't renice the timer thread");
+
JNI::attachThread();
struct timespec tv;
@@ -153,6 +160,72 @@ void *OSystem_Android::timerThreadFunc(void *arg) {
return 0;
}
+void *OSystem_Android::audioThreadFunc(void *arg) {
+ JNI::attachThread();
+
+ JNI::setAudioPlay();
+
+ OSystem_Android *system = (OSystem_Android *)arg;
+ Audio::MixerImpl *mixer = system->_mixer;
+
+ uint buf_size = system->_audio_buffer_size;
+
+ JNIEnv *env = JNI::getEnv();
+
+ jbyteArray bufa = env->NewByteArray(buf_size);
+
+ byte *buf;
+ int offset, left, written;
+
+ struct timespec tv;
+ tv.tv_sec = 0;
+ tv.tv_nsec = 20 * 1000 * 1000;
+
+ while (!system->_audio_thread_exit) {
+ buf = (byte *)env->GetPrimitiveArrayCritical(bufa, 0);
+ assert(buf);
+
+ mixer->mixCallback(buf, buf_size);
+
+ env->ReleasePrimitiveArrayCritical(bufa, buf, 0);
+
+ offset = 0;
+ left = buf_size;
+ written = 0;
+
+ while (left > 0) {
+ written = JNI::writeAudio(env, bufa, offset, left);
+
+ if (written < 0) {
+ error("AudioTrack error: %d", written);
+ break;
+ }
+
+ // buffer full
+ if (written < left)
+ nanosleep(&tv, 0);
+
+ offset += written;
+ left -= written;
+ }
+
+ if (written < 0)
+ break;
+
+ // sleep a little, prepare the next buffer, and run into the
+ // blocking AudioTrack.write
+ nanosleep(&tv, 0);
+ }
+
+ JNI::setAudioStop();
+
+ env->DeleteLocalRef(bufa);
+
+ JNI::detachThread();
+
+ return 0;
+}
+
void OSystem_Android::initBackend() {
ENTER();
@@ -173,7 +246,7 @@ void OSystem_Android::initBackend() {
gettimeofday(&_startTime, 0);
- _mixer = new Audio::MixerImpl(this, JNI::getAudioSampleRate());
+ _mixer = new Audio::MixerImpl(this, _audio_sample_rate);
_mixer->setReady(true);
JNI::initBackend();
@@ -181,9 +254,16 @@ void OSystem_Android::initBackend() {
_timer_thread_exit = false;
pthread_create(&_timer_thread, 0, timerThreadFunc, this);
+ _audio_thread_exit = false;
+ pthread_create(&_audio_thread, 0, audioThreadFunc, this);
+
OSystem::initBackend();
setupSurface();
+
+ // renice this thread to boost the audio thread
+ if (setpriority(PRIO_PROCESS, 0, 19) < 0)
+ warning("couldn't renice the main thread");
}
void OSystem_Android::addPluginDirectories(Common::FSList &dirs) const {
@@ -391,6 +471,9 @@ void OSystem_Android::deleteMutex(MutexRef mutex) {
void OSystem_Android::quit() {
ENTER();
+ _audio_thread_exit = true;
+ pthread_join(_audio_thread, 0);
+
_timer_thread_exit = true;
pthread_join(_timer_thread, 0);
}
diff --git a/backends/platform/android/android.h b/backends/platform/android/android.h
index 23c1e85..f4e9d61 100644
--- a/backends/platform/android/android.h
+++ b/backends/platform/android/android.h
@@ -92,6 +92,10 @@ protected:
class OSystem_Android : public BaseBackend, public PaletteManager {
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;
@@ -123,6 +127,10 @@ private:
pthread_t _timer_thread;
static void *timerThreadFunc(void *arg);
+ bool _audio_thread_exit;
+ pthread_t _audio_thread;
+ static void *audioThreadFunc(void *arg);
+
bool _enable_zoning;
bool _virtkeybd_on;
@@ -137,7 +145,7 @@ private:
void _setCursorPalette(const byte *colors, uint start, uint num);
public:
- OSystem_Android();
+ OSystem_Android(int audio_sample_rate, int audio_buffer_size);
virtual ~OSystem_Android();
virtual void initBackend();
diff --git a/backends/platform/android/jni.cpp b/backends/platform/android/jni.cpp
index f24a60d..5e11203 100644
--- a/backends/platform/android/jni.cpp
+++ b/backends/platform/android/jni.cpp
@@ -39,6 +39,7 @@ jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
JavaVM *JNI::_vm = 0;
jobject JNI::_jobj = 0;
+jobject JNI::_jobj_audio_track = 0;
Common::Archive *JNI::_asset_archive = 0;
OSystem_Android *JNI::_system = 0;
@@ -56,7 +57,6 @@ jfieldID JNI::_FID_ScummVM_nativeScummVM = 0;
jmethodID JNI::_MID_displayMessageOnOSD = 0;
jmethodID JNI::_MID_setWindowCaption = 0;
jmethodID JNI::_MID_initBackend = 0;
-jmethodID JNI::_MID_audioSampleRate = 0;
jmethodID JNI::_MID_showVirtualKeyboard = 0;
jmethodID JNI::_MID_getSysArchives = 0;
jmethodID JNI::_MID_getPluginDirectories = 0;
@@ -64,8 +64,14 @@ jmethodID JNI::_MID_setupScummVMSurface = 0;
jmethodID JNI::_MID_destroyScummVMSurface = 0;
jmethodID JNI::_MID_swapBuffers = 0;
+jmethodID JNI::_MID_AudioTrack_pause = 0;
+jmethodID JNI::_MID_AudioTrack_play = 0;
+jmethodID JNI::_MID_AudioTrack_stop = 0;
+jmethodID JNI::_MID_AudioTrack_write = 0;
+
const JNINativeMethod JNI::_natives[] = {
- { "create", "(Landroid/content/res/AssetManager;)V",
+ { "create", "(Landroid/content/res/AssetManager;"
+ "Landroid/media/AudioTrack;II)V",
(void *)JNI::create },
{ "nativeDestroy", "()V",
(void *)JNI::destroy },
@@ -73,8 +79,6 @@ const JNINativeMethod JNI::_natives[] = {
(void *)JNI::main },
{ "pushEvent", "(Lorg/inodes/gus/scummvm/Event;)V",
(void *)JNI::pushEvent },
- { "audioMixCallback", "([B)V",
- (void *)JNI::audioMixCallback },
{ "setConfMan", "(Ljava/lang/String;I)V",
(void *)JNI::setConfManInt },
{ "setConfMan", "(Ljava/lang/String;Ljava/lang/String;)V",
@@ -194,23 +198,6 @@ void JNI::throwByName(JNIEnv *env, const char *name, const char *msg) {
// calls to the dark side
-int JNI::getAudioSampleRate() {
- JNIEnv *env = JNI::getEnv();
-
- jint sample_rate = env->CallIntMethod(_jobj, _MID_audioSampleRate);
-
- if (env->ExceptionCheck()) {
- warning("Error finding audio sample rate - assuming 11025HZ");
-
- env->ExceptionDescribe();
- env->ExceptionClear();
-
- return 11025;
- }
-
- return sample_rate;
-}
-
void JNI::initBackend() {
JNIEnv *env = JNI::getEnv();
@@ -342,15 +329,55 @@ void JNI::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
}
}
+void JNI::setAudioPause() {
+ JNIEnv *env = JNI::getEnv();
+
+ env->CallVoidMethod(_jobj_audio_track, _MID_AudioTrack_pause);
+
+ if (env->ExceptionCheck()) {
+ warning("Error setting AudioTrack: pause");
+
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
+}
+
+void JNI::setAudioPlay() {
+ JNIEnv *env = JNI::getEnv();
+
+ env->CallVoidMethod(_jobj_audio_track, _MID_AudioTrack_play);
+
+ if (env->ExceptionCheck()) {
+ warning("Error setting AudioTrack: play");
+
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
+}
+
+void JNI::setAudioStop() {
+ JNIEnv *env = JNI::getEnv();
+
+ env->CallVoidMethod(_jobj_audio_track, _MID_AudioTrack_stop);
+
+ if (env->ExceptionCheck()) {
+ warning("Error setting AudioTrack: stop");
+
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
+}
+
// natives for the dark side
-void JNI::create(JNIEnv *env, jobject self, jobject am) {
+void JNI::create(JNIEnv *env, jobject self, jobject am, jobject at,
+ jint audio_sample_rate, jint audio_buffer_size) {
assert(!_system);
_asset_archive = new AndroidAssetArchive(am);
assert(_asset_archive);
- _system = new OSystem_Android();
+ _system = new OSystem_Android(audio_sample_rate, audio_buffer_size);
assert(_system);
// weak global ref to allow class to be unloaded
@@ -369,7 +396,6 @@ void JNI::create(JNIEnv *env, jobject self, jobject am) {
FIND_METHOD(setWindowCaption, "(Ljava/lang/String;)V");
FIND_METHOD(displayMessageOnOSD, "(Ljava/lang/String;)V");
FIND_METHOD(initBackend, "()V");
- FIND_METHOD(audioSampleRate, "()I");
FIND_METHOD(showVirtualKeyboard, "(Z)V");
FIND_METHOD(getSysArchives, "()[Ljava/lang/String;");
FIND_METHOD(getPluginDirectories, "()[Ljava/lang/String;");
@@ -381,6 +407,23 @@ void JNI::create(JNIEnv *env, jobject self, jobject am) {
env->SetLongField(self, _FID_ScummVM_nativeScummVM, (jlong)_system);
+ _jobj_audio_track = env->NewGlobalRef(at);
+
+ cls = env->GetObjectClass(_jobj_audio_track);
+
+#define FIND_METHOD(name, signature) do { \
+ _MID_AudioTrack_ ## name = env->GetMethodID(cls, #name, signature); \
+ if (_MID_AudioTrack_ ## name == 0) \
+ return; \
+ } while (0)
+
+ FIND_METHOD(pause, "()V");
+ FIND_METHOD(play, "()V");
+ FIND_METHOD(stop, "()V");
+ FIND_METHOD(write, "([BII)I");
+
+#undef FIND_METHOD
+
g_system = _system;
}
@@ -397,6 +440,7 @@ void JNI::destroy(JNIEnv *env, jobject self) {
// see above
//JNI::getEnv()->DeleteWeakGlobalRef(_jobj);
+ JNI::getEnv()->DeleteGlobalRef(_jobj_audio_track);
JNI::getEnv()->DeleteGlobalRef(_jobj);
}
@@ -514,25 +558,6 @@ void JNI::pushEvent(JNIEnv *env, jobject self, jobject java_event) {
_system->pushEvent(event);
}
-void JNI::audioMixCallback(JNIEnv *env, jobject self, jbyteArray jbuf) {
- assert(_system);
-
- jsize len = env->GetArrayLength(jbuf);
- 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 *>(_system->getMixer());
- assert(mixer);
- mixer->mixCallback(reinterpret_cast<byte *>(buf), len);
-
- env->ReleaseByteArrayElements(jbuf, buf, 0);
-}
-
void JNI::setConfManInt(JNIEnv *env, jclass cls, jstring key_obj, jint value) {
ENTER("%p, %d", key_obj, (int)value);
diff --git a/backends/platform/android/jni.h b/backends/platform/android/jni.h
index 02eabba..a1fc3df 100644
--- a/backends/platform/android/jni.h
+++ b/backends/platform/android/jni.h
@@ -48,7 +48,6 @@ public:
static void attachThread();
static void detachThread();
- static int getAudioSampleRate();
static void initBackend();
static void getPluginDirectories(Common::FSList &dirs);
static void setWindowCaption(const char *caption);
@@ -60,10 +59,18 @@ public:
static inline void destroySurface();
static inline bool swapBuffers();
+ static void setAudioPause();
+ static void setAudioPlay();
+ static void setAudioStop();
+
+ static inline int writeAudio(JNIEnv *env, jbyteArray &data, int offset,
+ int size);
+
private:
static JavaVM *_vm;
// back pointer to (java) peer instance
static jobject _jobj;
+ static jobject _jobj_audio_track;
static Common::Archive *_asset_archive;
static OSystem_Android *_system;
@@ -81,7 +88,6 @@ private:
static jmethodID _MID_displayMessageOnOSD;
static jmethodID _MID_setWindowCaption;
static jmethodID _MID_initBackend;
- static jmethodID _MID_audioSampleRate;
static jmethodID _MID_showVirtualKeyboard;
static jmethodID _MID_getSysArchives;
static jmethodID _MID_getPluginDirectories;
@@ -89,16 +95,21 @@ private:
static jmethodID _MID_destroyScummVMSurface;
static jmethodID _MID_swapBuffers;
+ static jmethodID _MID_AudioTrack_pause;
+ static jmethodID _MID_AudioTrack_play;
+ static jmethodID _MID_AudioTrack_stop;
+ static jmethodID _MID_AudioTrack_write;
+
static const JNINativeMethod _natives[];
static void throwByName(JNIEnv *env, const char *name, const char *msg);
// natives for the dark side
- static void create(JNIEnv *env, jobject self, jobject am);
+ static void create(JNIEnv *env, jobject self, jobject am, jobject at,
+ jint sample_rate, jint buffer_size);
static void destroy(JNIEnv *env, jobject self);
static jint main(JNIEnv *env, jobject self, jobjectArray args);
static void pushEvent(JNIEnv *env, jobject self, jobject java_event);
- static void audioMixCallback(JNIEnv *env, jobject self, jbyteArray jbuf);
static void setConfManInt(JNIEnv *env, jclass cls, jstring key_obj,
jint value);
static void setConfManString(JNIEnv *env, jclass cls, jstring key_obj,
@@ -128,6 +139,10 @@ inline bool JNI::swapBuffers() {
return env->CallBooleanMethod(_jobj, _MID_swapBuffers);
}
+inline int JNI::writeAudio(JNIEnv *env, jbyteArray &data, int offset, int size) {
+ return env->CallIntMethod(_jobj_audio_track, _MID_AudioTrack_write, data, offset, size);
+}
+
#endif
#endif
diff --git a/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java b/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java
index 698e508..7a32645 100644
--- a/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java
+++ b/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java
@@ -35,19 +35,48 @@ import java.util.LinkedHashMap;
public class ScummVM implements SurfaceHolder.Callback {
protected final static String LOG_TAG = "ScummVM";
- // bytes. 16bit audio * stereo
- private final int AUDIO_FRAME_SIZE = 2 * 2;
- public static class AudioSetupException extends Exception {}
-
// native code hangs itself here
private long nativeScummVM;
boolean scummVMRunning = false;
- private native void create(AssetManager am);
+ private native void create(AssetManager am, AudioTrack audio_track,
+ int sample_rate, int buffer_size);
+
+ public ScummVM(Context context) throws Exception {
+ int sample_rate = AudioTrack.getNativeOutputSampleRate(
+ AudioManager.STREAM_MUSIC);
+ int buffer_size = AudioTrack.getMinBufferSize(sample_rate,
+ AudioFormat.CHANNEL_CONFIGURATION_STEREO,
+ AudioFormat.ENCODING_PCM_16BIT);
+
+ // ~100ms
+ int buffer_size_want = (sample_rate * 2 * 2 / 10) & ~1023;
+
+ if (buffer_size < buffer_size_want) {
+ Log.w(LOG_TAG, String.format(
+ "adjusting audio buffer size (was: %d)", buffer_size));
+
+ buffer_size = buffer_size_want;
+ }
+
+ Log.i(LOG_TAG, String.format("Using %d bytes buffer for %dHz audio",
+ buffer_size, sample_rate));
+
+ AudioTrack audio_track =
+ new AudioTrack(AudioManager.STREAM_MUSIC,
+ sample_rate,
+ AudioFormat.CHANNEL_CONFIGURATION_STEREO,
+ AudioFormat.ENCODING_PCM_16BIT,
+ buffer_size,
+ AudioTrack.MODE_STREAM);
+
+ if (audio_track.getState() != AudioTrack.STATE_INITIALIZED)
+ throw new Exception(
+ String.format("Error initialising AudioTrack: %d",
+ audio_track.getState()));
- public ScummVM(Context context) {
// Init C++ code, set nativeScummVM
- create(context.getAssets());
+ create(context.getAssets(), audio_track, sample_rate, buffer_size);
}
private native void nativeDestroy();
@@ -345,8 +374,6 @@ public class ScummVM implements SurfaceHolder.Callback {
// Feed an event to ScummVM. Safe to call from other threads.
final public native void pushEvent(Event e);
- final private native void audioMixCallback(byte[] buf);
-
// Runs the actual ScummVM program and returns when it does.
// This should not be called from multiple threads simultaneously...
final public native int scummVMMain(String[] argv);
@@ -359,131 +386,18 @@ public class ScummVM implements SurfaceHolder.Callback {
protected String[] getSysArchives() { return new String[0]; }
protected String[] getPluginDirectories() { return new String[0]; }
- protected void initBackend() throws AudioSetupException {
+ protected void initBackend() {
createScummVMGLContext();
- initAudio();
- }
-
- private static class AudioThread extends Thread {
- final private int buf_size;
- private boolean is_paused = false;
- final private ScummVM scummvm;
- final private AudioTrack audio_track;
-
- AudioThread(ScummVM scummvm, AudioTrack audio_track, int buf_size) {
- super("AudioThread");
- this.scummvm = scummvm;
- this.audio_track = audio_track;
- this.buf_size = buf_size;
- setPriority(Thread.MAX_PRIORITY);
- setDaemon(true);
- }
-
- public void pauseAudio() {
- synchronized (this) {
- is_paused = true;
- }
- audio_track.pause();
- }
-
- public void resumeAudio() {
- synchronized (this) {
- is_paused = false;
- notifyAll();
- }
- audio_track.play();
- }
-
- public void run() {
- byte[] buf = new byte[buf_size];
- audio_track.play();
- int offset = 0;
- try {
- while (true) {
- synchronized (this) {
- while (is_paused)
- wait();
- }
-
- if (offset == buf.length) {
- // Grab new audio data
- scummvm.audioMixCallback(buf);
- offset = 0;
- }
-
- int len = buf.length - offset;
- int ret = audio_track.write(buf, offset, len);
- if (ret < 0) {
- Log.w(LOG_TAG, String.format(
- "AudioTrack.write(%dB) returned error %d",
- buf.length, ret));
- break;
- } else if (ret != len) {
- Log.w(LOG_TAG, String.format(
- "Short audio write. Wrote %dB, not %dB",
- ret, buf.length));
-
- // Buffer is full, so yield cpu for a while
- Thread.sleep(100);
- }
- offset += ret;
- }
- } catch (InterruptedException e) {
- Log.e(LOG_TAG, "Audio thread interrupted", e);
- }
- }
- }
- private AudioThread audio_thread;
-
- final public int audioSampleRate() {
- return AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC);
- }
-
- private void initAudio() throws AudioSetupException {
- int sample_rate = audioSampleRate();
- int buf_size =
- AudioTrack.getMinBufferSize(sample_rate,
- AudioFormat.CHANNEL_CONFIGURATION_STEREO,
- AudioFormat.ENCODING_PCM_16BIT);
- if (buf_size < 0) {
- // 10ms of audio
- int guess = AUDIO_FRAME_SIZE * sample_rate / 100;
-
- Log.w(LOG_TAG, String.format(
- "Unable to get min audio buffer size (error %d). Guessing %dB.",
- buf_size, guess));
-
- buf_size = guess;
- }
-
- Log.d(LOG_TAG, String.format("Using %dB buffer for %dHZ audio",
- buf_size, sample_rate));
-
- AudioTrack audio_track =
- new AudioTrack(AudioManager.STREAM_MUSIC,
- sample_rate,
- AudioFormat.CHANNEL_CONFIGURATION_STEREO,
- AudioFormat.ENCODING_PCM_16BIT,
- buf_size,
- AudioTrack.MODE_STREAM);
-
- if (audio_track.getState() != AudioTrack.STATE_INITIALIZED) {
- Log.e(LOG_TAG, "Error initialising Android audio system.");
- throw new AudioSetupException();
- }
-
- audio_thread = new AudioThread(this, audio_track, buf_size);
- audio_thread.start();
}
public void pause() {
- audio_thread.pauseAudio();
- // TODO: need to pause engine too
+ // TODO: need to pause audio
+ // TODO: need to pause engine
}
public void resume() {
- // TODO: need to resume engine too
- audio_thread.resumeAudio();
+ // TODO: need to resume audio
+ // TODO: need to resume engine
}
static {
diff --git a/backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java b/backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java
index 0dd1109..fb6020c 100644
--- a/backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java
@@ -49,7 +49,7 @@ public class ScummVMActivity extends Activity {
}
}
- public MyScummVM() {
+ public MyScummVM() throws Exception {
super(ScummVMActivity.this);
// Enable ScummVM zoning on 'small' screens.
@@ -59,7 +59,7 @@ public class ScummVMActivity extends Activity {
}
@Override
- protected void initBackend() throws ScummVM.AudioSetupException {
+ protected void initBackend() {
synchronized (this) {
scummvmRunning = true;
notifyAll();
@@ -153,7 +153,13 @@ public class ScummVMActivity extends Activity {
main_surface.requestFocus();
// Start ScummVM
- scummvm = new MyScummVM();
+ try {
+ scummvm = new MyScummVM();
+ } catch (Exception e) {
+ Log.e(ScummVM.LOG_TAG, "Fatal error", e);
+ finish();
+ return;
+ }
scummvm_thread = new Thread(new Runnable() {
public void run() {
Commit: bea57f695064c6f084ff26405d91b812848fee33
https://github.com/scummvm/scummvm/commit/bea57f695064c6f084ff26405d91b812848fee33
Author: dhewg (dhewg at wiibrew.org)
Date: 2011-02-27T00:04:36-08:00
Commit Message:
AUDIO: Make mixCallback return the sample count
The RateConverter::flow result was never used, pipe it through
Channel::mix to MixerImpl::mixCallback, so backends can decide
if they want to waste cpu cycles while playing empty buffers.
Changed paths:
audio/mixer.cpp
audio/mixer_intern.h
diff --git a/audio/mixer.cpp b/audio/mixer.cpp
index c2271b1..dc0287e 100644
--- a/audio/mixer.cpp
+++ b/audio/mixer.cpp
@@ -54,8 +54,9 @@ public:
* @param len number of sample *pairs*. So a value of
* 10 means that the buffer contains twice 10 sample, each
* 16 bits, for a total of 40 bytes.
+ * @return number of sample pairs processed (which can still be silence!)
*/
- void mix(int16 *data, uint len);
+ int mix(int16 *data, uint len);
/**
* Queries whether the channel is still playing or not.
@@ -257,7 +258,7 @@ void MixerImpl::playStream(
insertChannel(handle, chan);
}
-void MixerImpl::mixCallback(byte *samples, uint len) {
+int MixerImpl::mixCallback(byte *samples, uint len) {
assert(samples);
Common::StackLock lock(_mutex);
@@ -272,14 +273,21 @@ void MixerImpl::mixCallback(byte *samples, uint len) {
memset(buf, 0, 2 * len * sizeof(int16));
// mix all channels
+ int res = 0, tmp;
for (int i = 0; i != NUM_CHANNELS; i++)
if (_channels[i]) {
if (_channels[i]->isFinished()) {
delete _channels[i];
_channels[i] = 0;
- } else if (!_channels[i]->isPaused())
- _channels[i]->mix(buf, len);
+ } else if (!_channels[i]->isPaused()) {
+ tmp = _channels[i]->mix(buf, len);
+
+ if (tmp > res)
+ res = tmp;
+ }
}
+
+ return res;
}
void MixerImpl::stopAll() {
@@ -538,19 +546,23 @@ Timestamp Channel::getElapsedTime() {
return ts;
}
-void Channel::mix(int16 *data, uint len) {
+int Channel::mix(int16 *data, uint len) {
assert(_stream);
+ int res = 0;
+
if (_stream->endOfData()) {
// TODO: call drain method
} else {
assert(_converter);
-
_samplesConsumed = _samplesDecoded;
_mixerTimeStamp = g_system->getMillis();
_pauseTime = 0;
- _samplesDecoded += _converter->flow(*_stream, data, len, _volL, _volR);
+ res = _converter->flow(*_stream, data, len, _volL, _volR);
+ _samplesDecoded += res;
}
+
+ return res;
}
} // End of namespace Audio
diff --git a/audio/mixer_intern.h b/audio/mixer_intern.h
index c8df9a5..dd2746e 100644
--- a/audio/mixer_intern.h
+++ b/audio/mixer_intern.h
@@ -118,8 +118,10 @@ public:
* The mixer callback function, to be called at regular intervals by
* the backend (e.g. from an audio mixing thread). All the actual mixing
* work is done from here.
+ *
+ * @return number of sample pairs processed (which can still be silence!)
*/
- void mixCallback(byte *samples, uint len);
+ int mixCallback(byte *samples, uint len);
/**
* Set the internal 'is ready' flag of the mixer.
Commit: 0e869a5cf0e455f7cd5ce5c39192f3433b931e97
https://github.com/scummvm/scummvm/commit/0e869a5cf0e455f7cd5ce5c39192f3433b931e97
Author: dhewg (dhewg at wiibrew.org)
Date: 2011-02-27T00:04:37-08:00
Commit Message:
ANDROID: Pause the AudioTrack when possible
Only works in situations without any registered channels (or all paused)
at the mixer (like on the launcher or GMM).
CPU usage before (Galaxy Tab):
~5% scummvm
~15% mediaserver
After:
~2% scummvm
0% mediaserver
;)
Changed paths:
backends/platform/android/android.cpp
backends/platform/android/jni.cpp
backends/platform/android/jni.h
diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp
index 08b9579..860ff1f 100644
--- a/backends/platform/android/android.cpp
+++ b/backends/platform/android/android.cpp
@@ -163,8 +163,6 @@ void *OSystem_Android::timerThreadFunc(void *arg) {
void *OSystem_Android::audioThreadFunc(void *arg) {
JNI::attachThread();
- JNI::setAudioPlay();
-
OSystem_Android *system = (OSystem_Android *)arg;
Audio::MixerImpl *mixer = system->_mixer;
@@ -174,21 +172,60 @@ void *OSystem_Android::audioThreadFunc(void *arg) {
jbyteArray bufa = env->NewByteArray(buf_size);
+ bool paused = true;
+
byte *buf;
int offset, left, written;
+ int samples;
- struct timespec tv;
- tv.tv_sec = 0;
- tv.tv_nsec = 20 * 1000 * 1000;
+ struct timespec tv_delay;
+ tv_delay.tv_sec = 0;
+ tv_delay.tv_nsec = 20 * 1000 * 1000;
+
+ uint msecs_full = buf_size * 1000 / (mixer->getOutputRate() * 2 * 2);
+
+ struct timespec tv_full;
+ tv_full.tv_sec = 0;
+ tv_full.tv_nsec = msecs_full * 1000 * 1000;
+
+ uint silence_count = 0;
while (!system->_audio_thread_exit) {
buf = (byte *)env->GetPrimitiveArrayCritical(bufa, 0);
assert(buf);
- mixer->mixCallback(buf, buf_size);
+ samples = mixer->mixCallback(buf, buf_size);
env->ReleasePrimitiveArrayCritical(bufa, buf, 0);
+ if (samples < 1) {
+ if (!paused)
+ silence_count++;
+
+ // only pause after a while to prevent toggle mania
+ if (silence_count > 32) {
+ if (!paused) {
+ LOGD("AudioTrack pause");
+
+ JNI::setAudioPause();
+ paused = true;
+ }
+
+ nanosleep(&tv_full, 0);
+
+ continue;
+ }
+ }
+
+ if (paused) {
+ LOGD("AudioTrack play");
+
+ JNI::setAudioPlay();
+ paused = false;
+
+ silence_count = 0;
+ }
+
offset = 0;
left = buf_size;
written = 0;
@@ -203,7 +240,7 @@ void *OSystem_Android::audioThreadFunc(void *arg) {
// buffer full
if (written < left)
- nanosleep(&tv, 0);
+ nanosleep(&tv_delay, 0);
offset += written;
left -= written;
@@ -214,7 +251,7 @@ void *OSystem_Android::audioThreadFunc(void *arg) {
// sleep a little, prepare the next buffer, and run into the
// blocking AudioTrack.write
- nanosleep(&tv, 0);
+ nanosleep(&tv_delay, 0);
}
JNI::setAudioStop();
diff --git a/backends/platform/android/jni.cpp b/backends/platform/android/jni.cpp
index 5e11203..8964fe6 100644
--- a/backends/platform/android/jni.cpp
+++ b/backends/platform/android/jni.cpp
@@ -64,6 +64,7 @@ jmethodID JNI::_MID_setupScummVMSurface = 0;
jmethodID JNI::_MID_destroyScummVMSurface = 0;
jmethodID JNI::_MID_swapBuffers = 0;
+jmethodID JNI::_MID_AudioTrack_flush = 0;
jmethodID JNI::_MID_AudioTrack_pause = 0;
jmethodID JNI::_MID_AudioTrack_play = 0;
jmethodID JNI::_MID_AudioTrack_stop = 0;
@@ -332,6 +333,15 @@ void JNI::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
void JNI::setAudioPause() {
JNIEnv *env = JNI::getEnv();
+ env->CallVoidMethod(_jobj_audio_track, _MID_AudioTrack_flush);
+
+ if (env->ExceptionCheck()) {
+ warning("Error flushing AudioTrack");
+
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
+
env->CallVoidMethod(_jobj_audio_track, _MID_AudioTrack_pause);
if (env->ExceptionCheck()) {
@@ -417,6 +427,7 @@ void JNI::create(JNIEnv *env, jobject self, jobject am, jobject at,
return; \
} while (0)
+ FIND_METHOD(flush, "()V");
FIND_METHOD(pause, "()V");
FIND_METHOD(play, "()V");
FIND_METHOD(stop, "()V");
diff --git a/backends/platform/android/jni.h b/backends/platform/android/jni.h
index a1fc3df..0bc6498 100644
--- a/backends/platform/android/jni.h
+++ b/backends/platform/android/jni.h
@@ -95,6 +95,7 @@ private:
static jmethodID _MID_destroyScummVMSurface;
static jmethodID _MID_swapBuffers;
+ static jmethodID _MID_AudioTrack_flush;
static jmethodID _MID_AudioTrack_pause;
static jmethodID _MID_AudioTrack_play;
static jmethodID _MID_AudioTrack_stop;
Commit: d4c0501d1fcc8c98d39b2b7ba627cccb29cbc476
https://github.com/scummvm/scummvm/commit/d4c0501d1fcc8c98d39b2b7ba627cccb29cbc476
Author: dhewg (dhewg at wiibrew.org)
Date: 2011-02-27T00:04:37-08:00
Commit Message:
ANDROID: Check audio buffer for silence
Most games register a music channel, and when there is no music,
they still stream silence (and run through all the Converter::flow
code!). Scan the buffer for that to pause the AudioTrack. Ugly, but
worth it - reduces CPU usage on many games and hence saves battery life.
Changed paths:
backends/platform/android/android.cpp
diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp
index 860ff1f..f20cf84 100644
--- a/backends/platform/android/android.cpp
+++ b/backends/platform/android/android.cpp
@@ -176,7 +176,7 @@ void *OSystem_Android::audioThreadFunc(void *arg) {
byte *buf;
int offset, left, written;
- int samples;
+ int samples, i;
struct timespec tv_delay;
tv_delay.tv_sec = 0;
@@ -188,6 +188,7 @@ void *OSystem_Android::audioThreadFunc(void *arg) {
tv_full.tv_sec = 0;
tv_full.tv_nsec = msecs_full * 1000 * 1000;
+ bool silence;
uint silence_count = 0;
while (!system->_audio_thread_exit) {
@@ -196,9 +197,24 @@ void *OSystem_Android::audioThreadFunc(void *arg) {
samples = mixer->mixCallback(buf, buf_size);
+ silence = samples < 1;
+
+ // looks stupid, and it is, but currently there's no way to detect
+ // silence-only buffers from the mixer
+ if (!silence) {
+ silence = true;
+
+ for (i = 0; i < samples; i += 2)
+ // SID streams constant crap
+ if (READ_UINT16(buf + i) > 32) {
+ silence = false;
+ break;
+ }
+ }
+
env->ReleasePrimitiveArrayCritical(bufa, buf, 0);
- if (samples < 1) {
+ if (silence) {
if (!paused)
silence_count++;
Commit: a73b2ec97279b1ef1562ece18c7905591e6a7cc4
https://github.com/scummvm/scummvm/commit/a73b2ec97279b1ef1562ece18c7905591e6a7cc4
Author: dhewg (dhewg at wiibrew.org)
Date: 2011-02-27T00:04:38-08:00
Commit Message:
ANDROID: Remove unnecessary code
Changed paths:
backends/platform/android/jni.cpp
backends/platform/android/org/inodes/gus/scummvm/ScummVM.java
diff --git a/backends/platform/android/jni.cpp b/backends/platform/android/jni.cpp
index 8964fe6..d8203e2 100644
--- a/backends/platform/android/jni.cpp
+++ b/backends/platform/android/jni.cpp
@@ -52,7 +52,6 @@ jfieldID JNI::_FID_Event_kbd_flags = 0;
jfieldID JNI::_FID_Event_mouse_x = 0;
jfieldID JNI::_FID_Event_mouse_y = 0;
jfieldID JNI::_FID_Event_mouse_relative = 0;
-jfieldID JNI::_FID_ScummVM_nativeScummVM = 0;
jmethodID JNI::_MID_displayMessageOnOSD = 0;
jmethodID JNI::_MID_setWindowCaption = 0;
@@ -111,10 +110,6 @@ jint JNI::onLoad(JavaVM *vm) {
if (env->RegisterNatives(cls, _natives, ARRAYSIZE(_natives)) < 0)
return JNI_ERR;
- _FID_ScummVM_nativeScummVM = env->GetFieldID(cls, "nativeScummVM", "J");
- if (_FID_ScummVM_nativeScummVM == 0)
- return JNI_ERR;
-
jclass event = env->FindClass("org/inodes/gus/scummvm/Event");
if (event == 0)
return JNI_ERR;
@@ -415,8 +410,6 @@ void JNI::create(JNIEnv *env, jobject self, jobject am, jobject at,
#undef FIND_METHOD
- env->SetLongField(self, _FID_ScummVM_nativeScummVM, (jlong)_system);
-
_jobj_audio_track = env->NewGlobalRef(at);
cls = env->GetObjectClass(_jobj_audio_track);
@@ -439,7 +432,8 @@ void JNI::create(JNIEnv *env, jobject self, jobject am, jobject at,
}
void JNI::destroy(JNIEnv *env, jobject self) {
- assert(_system);
+ if (!_system)
+ return;
OSystem_Android *tmp = _system;
g_system = 0;
diff --git a/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java b/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java
index 7a32645..a6bc5fa 100644
--- a/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java
+++ b/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java
@@ -35,10 +35,6 @@ import java.util.LinkedHashMap;
public class ScummVM implements SurfaceHolder.Callback {
protected final static String LOG_TAG = "ScummVM";
- // native code hangs itself here
- private long nativeScummVM;
- boolean scummVMRunning = false;
-
private native void create(AssetManager am, AudioTrack audio_track,
int sample_rate, int buffer_size);
@@ -75,17 +71,14 @@ public class ScummVM implements SurfaceHolder.Callback {
String.format("Error initialising AudioTrack: %d",
audio_track.getState()));
- // Init C++ code, set nativeScummVM
+ // Init C++ code
create(context.getAssets(), audio_track, sample_rate, buffer_size);
}
private native void nativeDestroy();
public synchronized void destroy() {
- if (nativeScummVM != 0) {
- nativeDestroy();
- nativeScummVM = 0;
- }
+ nativeDestroy();
}
protected void finalize() {
@@ -295,6 +288,7 @@ public class ScummVM implements SurfaceHolder.Callback {
// Called by ScummVM thread
static private boolean _log_version = true;
+
protected void setupScummVMSurface() {
try {
surfaceLock.acquire();
Commit: 1c95d47cfaf1f39b3c3012aa649ce3ced90ed147
https://github.com/scummvm/scummvm/commit/1c95d47cfaf1f39b3c3012aa649ce3ced90ed147
Author: dhewg (dhewg at wiibrew.org)
Date: 2011-02-27T01:10:44-08:00
Commit Message:
SWORD2: Respect screen pitch while postprocessing
Fixes subtitles on androids
Changed paths:
engines/sword2/animation.cpp
engines/sword2/animation.h
diff --git a/engines/sword2/animation.cpp b/engines/sword2/animation.cpp
index 3c506c0..8d0600a 100644
--- a/engines/sword2/animation.cpp
+++ b/engines/sword2/animation.cpp
@@ -110,7 +110,7 @@ void MoviePlayer::play(MovieText *movieTexts, uint32 numMovieTexts, uint32 leadI
terminated = !playVideo();
- closeTextObject(_currentMovieText, NULL);
+ closeTextObject(_currentMovieText, NULL, 0);
if (terminated) {
_snd->stopHandle(*_bgSoundHandle);
@@ -165,7 +165,7 @@ void MoviePlayer::openTextObject(uint32 index) {
}
}
-void MoviePlayer::closeTextObject(uint32 index, byte *screen) {
+void MoviePlayer::closeTextObject(uint32 index, byte *screen, uint16 pitch) {
if (index < _numMovieTexts) {
MovieText *text = &_movieTexts[index];
@@ -183,7 +183,7 @@ void MoviePlayer::closeTextObject(uint32 index, byte *screen) {
int frameX = (_system->getWidth() - frameWidth) / 2;
int frameY = (_system->getHeight() - frameHeight) / 2;
- byte *dst = screen + _textY * _system->getWidth();
+ byte *dst = screen + _textY * pitch;
for (int y = 0; y < text->_textSprite.h; y++) {
if (_textY + y < frameY || _textY + y >= frameY + frameHeight) {
@@ -195,7 +195,7 @@ void MoviePlayer::closeTextObject(uint32 index, byte *screen) {
memset(dst + frameX + frameWidth, findBlackPalIndex(), _textX + text->_textSprite.w - (frameX + frameWidth));
}
- dst += _system->getWidth();
+ dst += pitch;
}
}
@@ -205,7 +205,7 @@ void MoviePlayer::closeTextObject(uint32 index, byte *screen) {
}
}
-void MoviePlayer::drawTextObject(uint32 index, byte *screen) {
+void MoviePlayer::drawTextObject(uint32 index, byte *screen, uint16 pitch) {
MovieText *text = &_movieTexts[index];
byte white = findWhitePalIndex();
@@ -224,7 +224,7 @@ void MoviePlayer::drawTextObject(uint32 index, byte *screen) {
src = buffer;
}
- byte *dst = screen + _textY * RENDERWIDE + _textX;
+ byte *dst = screen + _textY * pitch + _textX;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
@@ -234,12 +234,12 @@ void MoviePlayer::drawTextObject(uint32 index, byte *screen) {
dst[x] = white;
}
src += width;
- dst += RENDERWIDE;
+ dst += pitch;
}
}
}
-void MoviePlayer::performPostProcessing(byte *screen) {
+void MoviePlayer::performPostProcessing(byte *screen, uint16 pitch) {
MovieText *text;
int frame = _decoder->getCurFrame();
@@ -261,9 +261,9 @@ void MoviePlayer::performPostProcessing(byte *screen) {
_vm->_sound->playCompSpeech(text->_speechId, 16, 0);
}
if (frame < text->_endFrame) {
- drawTextObject(_currentMovieText, screen);
+ drawTextObject(_currentMovieText, screen, pitch);
} else {
- closeTextObject(_currentMovieText, screen);
+ closeTextObject(_currentMovieText, screen, pitch);
_currentMovieText++;
}
}
@@ -313,7 +313,7 @@ bool MoviePlayer::playVideo() {
}
Graphics::Surface *screen = _vm->_system->lockScreen();
- performPostProcessing((byte *)screen->pixels);
+ performPostProcessing((byte *)screen->pixels, screen->pitch);
_vm->_system->unlockScreen();
_vm->_system->updateScreen();
}
diff --git a/engines/sword2/animation.h b/engines/sword2/animation.h
index 550ac0f..afe7dfc 100644
--- a/engines/sword2/animation.h
+++ b/engines/sword2/animation.h
@@ -96,12 +96,12 @@ protected:
uint32 _leadOut;
int _leadOutFrame;
- void performPostProcessing(byte *screen);
+ void performPostProcessing(byte *screen, uint16 pitch);
bool playVideo();
void openTextObject(uint32 index);
- void closeTextObject(uint32 index, byte *screen);
- void drawTextObject(uint32 index, byte *screen);
+ void closeTextObject(uint32 index, byte *screen, uint16 pitch);
+ void drawTextObject(uint32 index, byte *screen, uint16 pitch);
byte findBlackPalIndex();
byte findWhitePalIndex();
Commit: aa2a2e046b0a5979709c79deb84b6eea3c8f09d5
https://github.com/scummvm/scummvm/commit/aa2a2e046b0a5979709c79deb84b6eea3c8f09d5
Author: dhewg (dhewg at wiibrew.org)
Date: 2011-02-27T01:13:18-08:00
Commit Message:
SWORD2: Reduce overhead
Changed paths:
engines/sword2/animation.cpp
diff --git a/engines/sword2/animation.cpp b/engines/sword2/animation.cpp
index 8d0600a..2fafb70 100644
--- a/engines/sword2/animation.cpp
+++ b/engines/sword2/animation.cpp
@@ -182,17 +182,18 @@ void MoviePlayer::closeTextObject(uint32 index, byte *screen, uint16 pitch) {
int frameHeight = _decoder->getHeight();
int frameX = (_system->getWidth() - frameWidth) / 2;
int frameY = (_system->getHeight() - frameHeight) / 2;
+ byte black = findBlackPalIndex();
byte *dst = screen + _textY * pitch;
for (int y = 0; y < text->_textSprite.h; y++) {
if (_textY + y < frameY || _textY + y >= frameY + frameHeight) {
- memset(dst + _textX, findBlackPalIndex(), text->_textSprite.w);
+ memset(dst + _textX, black, text->_textSprite.w);
} else {
if (frameX > _textX)
- memset(dst + _textX, findBlackPalIndex(), frameX - _textX);
+ memset(dst + _textX, black, frameX - _textX);
if (frameX + frameWidth < _textX + text->_textSprite.w)
- memset(dst + frameX + frameWidth, findBlackPalIndex(), _textX + text->_textSprite.w - (frameX + frameWidth));
+ memset(dst + frameX + frameWidth, black, _textX + text->_textSprite.w - (frameX + frameWidth));
}
dst += pitch;
More information about the Scummvm-git-logs
mailing list