Merge change Ib1424474 into eclair
* changes:
Fix orientation change in the See Through wallpaper.
diff --git a/res/drawable-hdpi/pond.jpg b/res/drawable-hdpi/pond.jpg
new file mode 100644
index 0000000..39b1f8f
--- /dev/null
+++ b/res/drawable-hdpi/pond.jpg
Binary files differ
diff --git a/res/drawable-hdpi/water_thumb.jpg b/res/drawable-hdpi/water_thumb.jpg
index 56be4bc..90def45 100644
--- a/res/drawable-hdpi/water_thumb.jpg
+++ b/res/drawable-hdpi/water_thumb.jpg
Binary files differ
diff --git a/res/raw/fall.rs b/res/raw/fall.rs
index b094962..1d7eba8 100644
--- a/res/raw/fall.rs
+++ b/res/raw/fall.rs
@@ -119,44 +119,37 @@
float fw = 1.0f / width;
float fh = 1.0f / height;
- {
- int x, y, ct;
- struct vert_s *vtx = vert;
- for (y=0; y < height; y++) {
- for (x=0; x < width; x++) {
- struct drop_s * d = &gDrops[0];
- float z = 0;
+ int x, y, ct;
+ struct vert_s *v = vert;
+ for (y=0; y < height; y++) {
+ for (x=0; x < width; x++) {
+ struct drop_s * d = &gDrops[0];
+ float z = 0;
- for (ct = 0; ct < gMaxDrops; ct++) {
- if (d->ampE > 0.01f) {
- float dx = (d->x - xShift) - x;
- float dy = d->y - y;
- float dist2 = dx*dx + dy*dy;
- if (dist2 < d->spread2) {
- float dist = sqrtf(dist2);
- float a = d->ampE * (dist * d->invSpread);
- z += sinf(d->spread - dist) * a;
- }
+ for (ct = 0; ct < gMaxDrops; ct++) {
+ if (d->ampE > 0.01f) {
+ float dx = (d->x - xShift) - x;
+ float dy = d->y - y;
+ float dist2 = dx*dx + dy*dy;
+ if (dist2 < d->spread2) {
+ float dist = sqrtf(dist2);
+ float a = d->ampE * (dist * d->invSpread);
+ z += sinf(d->spread - dist) * a;
}
- d++;
}
- vtx->z = z;
- vtx ++;
+ d++;
}
- }
- for (ct = 0; ct < gMaxDrops; ct++) {
- updateDrop(ct);
+ v->z = z;
+ v ++;
}
}
+ for (ct = 0; ct < gMaxDrops; ct++) {
+ updateDrop(ct);
+ }
- int y = 0;
- for ( ; y < (height-1); y += 1) {
- int x = 0;
- int yOffset = y * width;
- struct vert_s *v = vert;
- v += y * width;
-
- for ( ; x < (width-1); x += 1) {
+ v = vert;
+ for (y = 0; y < height; y += 1) {
+ for (x = 0; x < width; x += 1) {
struct vec3_s n1, n2, n3;
vec3Sub(&n1, (struct vec3_s *)&(v+1)->x, (struct vec3_s *)&v->x);
vec3Sub(&n2, (struct vec3_s *)&(v+width)->x, (struct vec3_s *)&v->x);
@@ -168,8 +161,9 @@
vec3Add(&n3, &n3, &n2);
//vec3Norm(&n3); // Not necessary for our constrained mesh.
- v->s = (float)x * fw + n3.x * 0.005;
- v->t = (float)y * fh + n3.y * 0.005;
+ v->s = (float)x * fw + n3.x;// * 0.2;
+ v->t = (float)y * fh + n3.y;// * 0.2;
+ v->z = 0;
v += 1;
}
}
@@ -201,14 +195,21 @@
float matrix[16];
if (a > 0.0f) {
- color(0.0f, 0.0f, 0.0f, 0.15f);
+
+ float alpha = 1.0f;
+ if (a >= 0.4f) alpha = 1.0f - (a - 0.4f) / 0.1f;
+
+ color(0.0f, 0.0f, 0.0f, alpha * 0.15f);
if (State->rotate) {
matrixLoadRotate(matrix, 90.0f, 0.0f, 0.0f, 1.0f);
} else {
matrixLoadIdentity(matrix);
}
- matrixTranslate(matrix, x - State->xOffset * 2, y, 0.0f);
+
+ float shadowOffet = a / 5;
+
+ matrixTranslate(matrix, (x - State->xOffset * 2) + (shadowOffet / 2), y - shadowOffet, tz);
matrixScale(matrix, s, s, 1.0f);
matrixRotate(matrix, r, 0.0f, 0.0f, 1.0f);
vpLoadModelMatrix(matrix);
@@ -218,8 +219,6 @@
LEAF_SIZE, LEAF_SIZE, 0, u2, 0.0f,
-LEAF_SIZE, LEAF_SIZE, 0, u1, 0.0f);
- float alpha = 1.0f;
- if (a >= 0.4f) alpha = 1.0f - (a - 0.5f) / 0.1f;
color(1.0f, 1.0f, 1.0f, alpha);
} else {
color(1.0f, 1.0f, 1.0f, 1.0f);
@@ -314,6 +313,7 @@
vpLoadTextureMatrix(matrix);
}
+/*
void drawSky() {
color(1.0f, 1.0f, 1.0f, 0.5f);
@@ -340,10 +340,11 @@
matrixLoadIdentity(matrix);
vpLoadTextureMatrix(matrix);
}
+*/
int main(int index) {
if (Drop->dropX != -1) {
- drop(Drop->dropX, Drop->dropY, 1);
+ drop(Drop->dropX, Drop->dropY, 2);
Drop->dropX = -1;
Drop->dropY = -1;
}
@@ -371,7 +372,7 @@
}
drawRiverbed();
- drawSky();
+ // drawSky();
drawLeaves();
return 1;
diff --git a/src/com/android/wallpaper/fall/FallRS.java b/src/com/android/wallpaper/fall/FallRS.java
index dc785fe..fbd341f 100644
--- a/src/com/android/wallpaper/fall/FallRS.java
+++ b/src/com/android/wallpaper/fall/FallRS.java
@@ -48,7 +48,7 @@
private static final int RSID_STATE = 0;
- private static final int TEXTURES_COUNT = 3;
+ private static final int TEXTURES_COUNT = 2;
private static final int RSID_TEXTURE_RIVERBED = 0;
private static final int RSID_TEXTURE_LEAVES = 1;
private static final int RSID_TEXTURE_SKY = 2;
@@ -181,16 +181,11 @@
hResolution += 2;
for (int y = 0; y <= hResolution; y++) {
- final boolean shift = (y & 0x1) == 0;
final float yOffset = y * quadHeight - glHeight / 2.0f - quadHeight;
final float t = 1.0f - y / (float) hResolution;
for (int x = 0; x <= wResolution; x++) {
tmb.setTexture(x / (float) wResolution, t);
- if (shift) {
- tmb.addVertex(-1.0f + x * quadWidth - quadWidth, yOffset, 0.0f);
- } else {
- tmb.addVertex(-1.0f + x * quadWidth - quadWidth * 0.5f, yOffset, 0.0f);
- }
+ tmb.addVertex(-1.0f + x * quadWidth - quadWidth, yOffset, 0.0f);
}
}
@@ -304,9 +299,9 @@
private void loadTextures() {
final Allocation[] textures = new Allocation[TEXTURES_COUNT];
- textures[RSID_TEXTURE_RIVERBED] = loadTexture(R.drawable.riverbed, "TRiverbed");
+ textures[RSID_TEXTURE_RIVERBED] = loadTexture(R.drawable.pond, "TRiverbed");
textures[RSID_TEXTURE_LEAVES] = loadTextureARGB(R.drawable.leaves, "TLeaves");
- textures[RSID_TEXTURE_SKY] = loadTextureARGB(R.drawable.clouds, "TSky");
+ // textures[RSID_TEXTURE_SKY] = loadTextureARGB(R.drawable.clouds, "TSky");
final int count = textures.length;
for (int i = 0; i < count; i++) {
diff --git a/src/com/android/wallpaper/grass/GrassRS.java b/src/com/android/wallpaper/grass/GrassRS.java
index 7ce391b..1fa8ec5 100644
--- a/src/com/android/wallpaper/grass/GrassRS.java
+++ b/src/com/android/wallpaper/grass/GrassRS.java
@@ -50,8 +50,12 @@
import java.util.Calendar;
class GrassRS extends RenderScriptScene {
- private static final int LOCATION_UPDATE_MIN_TIME = 60 * 60 * 1000; // 1 hour
- private static final int LOCATION_UPDATE_MIN_DISTANCE = 150 * 1000; // 150 km
+ @SuppressWarnings({"UnusedDeclaration"})
+ private static final String LOG_TAG = "Grass";
+ private static final boolean DEBUG = false;
+
+ private static final int LOCATION_UPDATE_MIN_TIME = DEBUG ? 5 * 60 * 1000 : 60 * 60 * 1000; // 1 hour
+ private static final int LOCATION_UPDATE_MIN_DISTANCE = DEBUG ? 10 : 150 * 1000; // 150 km
private static final float TESSELATION = 0.5f;
private static final int TEXTURES_COUNT = 5;
@@ -125,6 +129,7 @@
if (mTimezoneTracker == null) {
mTimezoneTracker = new TimezoneTracker();
IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_DATE_CHANGED);
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
diff --git a/src/com/android/wallpaper/nexus/NexusWallpaper.java b/src/com/android/wallpaper/nexus/NexusWallpaper.java
index 1fc4d84..01059eb 100644
--- a/src/com/android/wallpaper/nexus/NexusWallpaper.java
+++ b/src/com/android/wallpaper/nexus/NexusWallpaper.java
@@ -16,147 +16,234 @@
package com.android.wallpaper.nexus;
-import android.service.wallpaper.WallpaperService;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.Paint;
import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Point;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
import android.graphics.RectF;
-import android.view.SurfaceHolder;
-import android.view.animation.AnimationUtils;
-import android.content.IntentFilter;
-import android.content.Intent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.res.Resources;
-import android.content.res.XmlResourceParser;
-
+import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
-import android.text.format.Time;
+import android.service.wallpaper.WallpaperService;
import android.util.MathUtils;
-import android.util.Log;
+import android.view.SurfaceHolder;
+import android.view.animation.AnimationUtils;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.TimeZone;
-import java.io.IOException;
-
-import org.apache.harmony.misc.SystemUtils;
-import org.xmlpull.v1.XmlPullParserException;
-import static org.xmlpull.v1.XmlPullParser.*;
+import java.util.Set;
+import java.util.HashSet;
import com.android.wallpaper.R;
public class NexusWallpaper extends WallpaperService {
-
- private static final int NUM_PULSES = 20;
- private static final int PULSE_SIZE_MIN = 30;
- private static final int PULSE_SIZE_EXTRA = 20;
- private static final int PULSE_SPEED = 20; // Pulse travels at 1000 / PULSE_SPEED cells/sec
- private static final int MAX_ALPHA = 80; // 0..255
- private static final int PULSE_DELAY = 4000;
- private static final float ALPHA_DECAY = 0.97f;
-
+
+ private static final int NUM_PULSES = 18;
+ private static final int MAX_PULSES = 42;
+ private static final int PULSE_SIZE = 16;
+ private static final int MAX_ALPHA = 192; // 0..255
+ private static final int PULSE_DELAY = 5000; // random restart time, in ms
+ private static final float ALPHA_DECAY = 0.85f;
+
+ private static final boolean ACCEPTS_TAP = true;
+
+ private static final int ANIMATION_PERIOD = 1000/30; // in ms^-1
+
+ private static final int[] PULSE_COLORS = {
+ 0xFF0066CC, 0xFFFF0000, 0xFFFFCC00, 0xFF009900,
+ };
+
private static final String LOG_TAG = "Nexus";
private final Handler mHandler = new Handler();
public Engine onCreateEngine() {
return new NexusEngine();
- }
-
+ }
+
class NexusEngine extends Engine {
- class Collision {
- int x;
- int y;
- long startTime;
- public Bitmap led;
+ class Automaton {
+ public void step(long now) { }
+ public void draw(Canvas c) { }
}
-
- class Pulse {
- boolean vertical;
- boolean reverse;
- int x;
- int y;
+
+ class Pulse extends Automaton {
+ Point v;
+ Point[] pts;
+ int start, len; // pointers into pts
+ Paint paint;
long startTime;
- int length;
- Bitmap led;
-
- public void reset(long now, int width, int height) {
- vertical = Math.random() > 0.5;
- reverse = Math.random() > 0.5;
-
- startTime = now + (long)(Math.random() * PULSE_DELAY);
- if (vertical) {
- x = (int) (Math.random() * (width / mCellSize));
- } else {
- y = (int) (Math.random() * (height / mCellSize));
+ boolean started;
+
+ public float zagProb = 0.01f;
+ public int speed = 1;
+
+ public Pulse() {
+ v = new Point(0,0);
+ pts = new Point[PULSE_SIZE];
+ for (int i=0; i<pts.length; i++) {
+ pts[i] = new Point(0,0);
}
- length = PULSE_SIZE_MIN + (int)(Math.random() * PULSE_SIZE_EXTRA);
- final double color = Math.random();
- if (color < 0.25) {
- led = mBlueLed;
- } else if (color < 0.5) {
- led = mRedLed;
- } else if (color < 0.75) {
- led = mGreenLed;
- } else {
- led = mYellowLed;
- }
-
+ paint = new Paint(Paint.FILTER_BITMAP_FLAG|Paint.DITHER_FLAG);
+ paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
+
+ start = len = 0;
+ }
+ public Pulse(long now, int x, int y, int dx, int dy) {
+ this();
+ start(now, x, y, dx, dy);
}
- public void clearState(int[][] state) {
- if (vertical) {
- int rowCount = state[0].length;
- for (int row = 0; row < rowCount; row++) {
- state[x][row] = 0;
+ boolean isDiagonal() {
+ return v.x != 0 && v.y != 0;
+ }
+
+ public void zag() {
+ // take a random 90-degree turn
+ if (isDiagonal()) {
+ if (Math.random() < 0.5) {
+ v.x *= -1;
+ } else {
+ v.y *= -1;
}
} else {
- int colCount = state.length;
- for (int col = 0; col < colCount; col++) {
- state[col][y] = 0;
+ int t = v.x; v.x = v.y; v.y = t;
+ if (Math.random() < 0.5) {
+ v.negate();
}
}
}
+
+ public void start(long now, int x, int y, int dx, int dy) {
+ start = 0;
+ len = 1;
+ pts[start].set(x, y);
+ v.x = dx;
+ v.y = dy;
+ startTime = now;
+ paint.setColor(PULSE_COLORS[(int)Math.floor(Math.random()*PULSE_COLORS.length)]);
+ started = false;
+ }
+
+ public void startRandomEdge(long now, boolean diag) {
+ int x, y;
+ if (Math.random() < 0.5) {
+ // top or bottom edge
+ x = (int)(Math.random() * mColumnCount);
+ if (Math.random() < 0.5) {
+ v.y = 1;
+ y = 0;
+ } else {
+ v.y = -1;
+ y = mRowCount;
+ }
+ v.x = diag ? ((Math.random() < 0.5) ? 1 : -1) : 0;
+ } else {
+ // left or right edge
+ y = (int)(Math.random() * mRowCount);
+ if (Math.random() < 0.5) {
+ v.set(1, 1);
+ x = 0;
+ } else {
+ v.set(-1, 1);
+ x = mColumnCount;
+ }
+ v.y = diag ? ((Math.random() < 0.5) ? 1 : -1) : 0;
+ }
+ start = 0;
+ len = 1;
+ pts[start].set(x, y);
+
+ startTime = now + (long)(Math.random() * PULSE_DELAY);
+
+ /* random colors
+ final float hsv[] = {(float)Math.random()*360, 0.75f, 1.0f};
+ int color = Color.HSVToColor(hsv);
+ */
+ // select colors
+ paint.setColor(PULSE_COLORS[(int)Math.floor(Math.random()*PULSE_COLORS.length)]);
+ started = false;
+ }
+
+ public Point getHead() {
+ return pts[(start+len-1)%PULSE_SIZE];
+ }
+ public Point getTail() {
+ return pts[start];
+ }
+
+ public void step(long now) {
+ if (now < startTime) return;
+ started = true;
+
+ for (int i=0; i<speed; i++) {
+ final Point neck = getHead();
+ if (len < PULSE_SIZE) len++;
+ else start = (start+1)%PULSE_SIZE;
+
+ getHead().set(neck.x + v.x,
+ neck.y + v.y);
+ }
+
+ if (Math.random() < zagProb) {
+ zag();
+ }
+ }
+
+ public void draw(Canvas c) {
+ if (!started) return;
+ boolean onScreen = false;
+ int a = MAX_ALPHA;
+ final Rect r = new Rect(0, 0, mCellSize, mCellSize);
+ for (int i=len-1; i>=0; i--) {
+ paint.setAlpha(a);
+ a *= ALPHA_DECAY;
+ if (a < 0.05f) break; // note: you should decrease PULSE_SIZE
+ Point p = pts[(start+i)%PULSE_SIZE];
+ r.offsetTo(p.x * mCellSize, p.y * mCellSize);
+ c.drawRect(r, paint);
+ if (!onScreen)
+ onScreen = !(p.x < 0 || p.x > mColumnCount || p.y < 0 || p.y > mRowCount);
+ }
+
+ if (!onScreen) {
+ // Time to die.
+ recycleOrRemovePulse(this);
+ }
+ }
}
-
- Paint mPaint = new Paint();
private final Runnable mDrawNexus = new Runnable() {
public void run() {
drawFrame();
+ step();
}
};
private boolean mVisible;
private float mOffsetX;
-
- private Bitmap mBackground;
-
- private Bitmap mBlueLed;
- private Bitmap mRedLed;
- private Bitmap mYellowLed;
- private Bitmap mGreenLed;
-
- private ArrayList<Pulse> mPulses = new ArrayList<Pulse>();
-
- private ArrayList<Collision> mCollisions = new ArrayList<Collision>();
- private int[][] mState = null;
+ private Bitmap mBackground;
+
+ private Bitmap mGreenLed;
+
+ private Set<Automaton> mPulses = new HashSet<Automaton>();
+ private Set<Automaton> mDeadPulses = new HashSet<Automaton>();
private int mColumnCount;
-
private int mRowCount;
private int mCellSize;
-
+
+ private int mBackgroundWidth;
+ private int mBackgroundHeight;
+
NexusEngine() {
}
@@ -164,25 +251,34 @@
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
- final Paint paint = mPaint;
-
Resources r = getResources();
-
+
mBackground = BitmapFactory.decodeResource(r, R.drawable.pyramid_background, null);
- mBlueLed = BitmapFactory.decodeResource(r, R.drawable.led_blue, null);
- mRedLed = BitmapFactory.decodeResource(r, R.drawable.led_red, null);
- mYellowLed = BitmapFactory.decodeResource(r, R.drawable.led_yellow, null);
+
+ mBackgroundWidth = mBackground.getWidth();
+ mBackgroundHeight = mBackground.getHeight();
+
mGreenLed = BitmapFactory.decodeResource(r, R.drawable.led_green, null);
-
+
mCellSize = mGreenLed.getWidth();
-
- for (int i=0; i<NUM_PULSES; i++) {
- Pulse p = new Pulse();
- mPulses.add(p);
- }
-
+
+ initializeState();
+
if (isPreview()) {
- mOffsetX = 0.5f;
+ mOffsetX = 0.5f;
+ }
+ }
+
+ private void initializeState() {
+ mColumnCount = mBackgroundWidth / mCellSize;
+ mRowCount = mBackgroundHeight / mCellSize;
+ mPulses.clear();
+ mDeadPulses.clear();
+
+ final long now = AnimationUtils.currentAnimationTimeMillis();
+
+ if (isPreview()) {
+ mOffsetX = 0.5f;
}
}
@@ -195,7 +291,7 @@
@Override
public void onVisibilityChanged(boolean visible) {
mVisible = visible;
- if (!visible) {
+ if (!visible) {
mHandler.removeCallbacks(mDrawNexus);
}
drawFrame();
@@ -204,6 +300,14 @@
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
+ initializeState();
+ drawFrame();
+ }
+
+ @Override
+ public void onDesiredSizeChanged(int desiredWidth, int desiredHeight) {
+ super.onDesiredSizeChanged(desiredWidth, desiredHeight);
+ initializeState();
drawFrame();
}
@@ -222,32 +326,103 @@
@Override
public void onOffsetsChanged(float xOffset, float yOffset,
float xStep, float yStep, int xPixels, int yPixels) {
+ super.onOffsetsChanged(xOffset, yOffset, xStep, yStep, xPixels, yPixels);
mOffsetX = xOffset;
drawFrame();
}
-
+
+
+ @Override
+ public Bundle onCommand(String action, int x, int y, int z, Bundle extras,
+ boolean resultRequested) {
+ if (ACCEPTS_TAP && "android.wallpaper.tap".equals(action)) {
+
+ final SurfaceHolder holder = getSurfaceHolder();
+ final Rect frame = holder.getSurfaceFrame();
+
+ final int dw = frame.width();
+ final int bw = mBackgroundWidth;
+ final int cellX = (int)((x + mOffsetX * (bw-dw)) / mCellSize);
+ final int cellY = (int)(y / mCellSize);
+ Pulse p = new Pulse();
+ p.zagProb = 0;
+ p.start(0, cellX, cellY, 0, 1);
+ addPulse(p);
+ p = new Pulse();
+ p.zagProb = 0;
+ p.start(0, cellX, cellY, 1, 0);
+ addPulse(p);
+ p = new Pulse();
+ p.zagProb = 0;
+ p.start(0, cellX, cellY, -1, 0);
+ addPulse(p);
+ p = new Pulse();
+ p.zagProb = 0;
+ p.start(0, cellX, cellY, 0, -1);
+ addPulse(p);
+ } else if ("android.home.drop".equals(action)) {
+ // TODO: something awesome
+ }
+ return null;
+ }
+
+ void addPulse(Pulse p) {
+ if (mPulses.size() > MAX_PULSES) return;
+ mPulses.add(p);
+ }
+
+ void removePulse(Pulse p) {
+ mDeadPulses.add(p);
+ }
+
+ void recycleOrRemovePulse(Pulse p) {
+ if (mPulses.size() < NUM_PULSES) {
+ p.startRandomEdge(AnimationUtils.currentAnimationTimeMillis(), false);
+ } else {
+ removePulse(p);
+ }
+ }
+
+ void step() {
+ final long now = AnimationUtils.currentAnimationTimeMillis();
+
+ // not enough pulses? add some
+ for (int i=mPulses.size(); i<NUM_PULSES; i++) {
+ Pulse p = new Pulse();
+ p.startRandomEdge(now, false);
+ mPulses.add(p);
+ }
+
+ for (Automaton p : mDeadPulses) {
+ mPulses.remove(p);
+ }
+ mDeadPulses.clear();
+
+ // update state
+ for (Automaton p : mPulses) {
+ p.step(now);
+ }
+ }
+
void drawFrame() {
final SurfaceHolder holder = getSurfaceHolder();
final Rect frame = holder.getSurfaceFrame();
- final int width = frame.width();
- final int height = frame.height();
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
- if (mState == null && width > 0 && height > 0) {
- mColumnCount = (width * 2) / mCellSize;
- mRowCount = height / mCellSize;
- mState = new int[mColumnCount][mRowCount];
- }
-
- c.translate(-MathUtils.lerp(0, width, mOffsetX), 0);
+ final int dw = frame.width();
+ final int bw = mBackgroundWidth;
+ final int availw = dw-bw;
+ final int xPixels = availw < 0 ? (int)(availw*mOffsetX+.5f) : (availw/2);
+
+ c.translate(xPixels, 0);
+
c.drawBitmap(mBackground, 0, 0, null);
- final long now = AnimationUtils.currentAnimationTimeMillis();
- drawPulses(c, now, width, height);
- drawCollisions(c, now);
- clearState();
+ for (Automaton p : mPulses) {
+ p.draw(c);
+ }
}
} finally {
if (c != null) holder.unlockCanvasAndPost(c);
@@ -255,142 +430,8 @@
mHandler.removeCallbacks(mDrawNexus);
if (mVisible) {
- mHandler.postDelayed(mDrawNexus, 1000 / 25);
+ mHandler.postDelayed(mDrawNexus, ANIMATION_PERIOD);
}
}
-
-
- private void drawCollisions(Canvas c, final long now) {
- final int count = mCollisions.size();
- for (int i=count - 1; i > 0; i--) {
- Collision collision = mCollisions.get(i);
- final long age = now - collision.startTime;
- if (age > 1000) {
- mCollisions.remove(i);
- } else {
- mPaint.setAlpha(MAX_ALPHA*2 - (int)(MAX_ALPHA*2*((float)age/1000)));
- c.drawBitmap(collision.led, collision.x * mCellSize, collision.y * mCellSize, mPaint);
- }
- }
- }
-
- private void drawPulses(Canvas c, final long now, final int width,
- final int height) {
- for (int i=0; i<NUM_PULSES; i++) {
- Pulse p = mPulses.get(i);
- final long startTime = p.startTime;
- final Bitmap led = p.led;
-
- if (startTime > 0 && now > startTime) {
- final int x = p.x;
- final int y = p.y;
- final int length = p.length;
- int alpha = MAX_ALPHA;
- int lastOffset;
-
- int offset = (int) ((AnimationUtils.currentAnimationTimeMillis() - startTime) / PULSE_SPEED);
-
- if (p.vertical) {
-
- if (p.reverse) {
- offset = mRowCount - offset;
- }
- lastOffset = offset;
-
- for (int j = 0; j < length; j++) {
- mPaint.setAlpha(alpha);
- if (p.reverse) {
- lastOffset = offset + j;
- } else {
- lastOffset = offset - j;
- }
- c.drawBitmap(led, x * mCellSize, lastOffset * mCellSize, mPaint);
- detectCollision(now, led, x, lastOffset, alpha);
- alpha *= ALPHA_DECAY;
- }
- if (p.reverse) {
- if (lastOffset < 0) {
- p.reset(now, width, height);
- }
- } else {
- if (lastOffset > mRowCount) {
- p.reset(now, width, height);
- }
- }
-
- } else {
-
- if (p.reverse) {
- offset = mColumnCount - offset;
- }
- lastOffset = offset;
-
- for (int j=0; j<length; j++) {
- mPaint.setAlpha(alpha);
- if (p.reverse) {
- lastOffset = offset + j;
- } else {
- lastOffset = offset - j;
- }
- c.drawBitmap(led, lastOffset * mCellSize, y * mCellSize, mPaint);
- alpha *= ALPHA_DECAY;
- detectCollision(now, led, lastOffset, y, alpha);
- }
- if (p.reverse) {
- if (lastOffset < 0) {
- p.reset(now, width * 2, height);
- }
- } else {
- if (lastOffset > mColumnCount) {
- p.reset(now, width * 2, height);
- }
- }
- }
- } else if (startTime == 0) {
- p.reset(now, width * 2, height);
- }
- }
- }
-
- private void detectCollision(long now, Bitmap led, int x, int y, int alpha) {
- final int[][] state = mState;
- if (x >= 0 && y >= 0 && x < state.length && y < state[x].length) {
-
- if ((alpha > MAX_ALPHA / 2) && (state[x][y] > MAX_ALPHA / 2)) {
-
- boolean found = false;
- final int count = mCollisions.size();
- for (int i=count - 1; i > 0; i--) {
- Collision collision = mCollisions.get(i);
- if (x == collision.x && y == collision.y) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- Collision c = new Collision();
- c.startTime = now;
- c.x = x;
- c.y = y;
- c.led = led;
- mCollisions.add(c);
- }
- } else {
- state[x][y] = alpha;
- }
- }
-
- }
-
- private void clearState() {
- if (mState != null) {
- for (int i = 0; i < NUM_PULSES; i++) {
- Pulse p = mPulses.get(i);
- p.clearState(mState);
- }
- }
-
- }
}
}