diff --git a/res/drawable-hdpi/glow.png b/res/drawable-hdpi/glow.png
new file mode 100644
index 0000000..613c45b
--- /dev/null
+++ b/res/drawable-hdpi/glow.png
Binary files differ
diff --git a/res/drawable-hdpi/pulse.png b/res/drawable-hdpi/pulse.png
new file mode 100644
index 0000000..4bdfc5f
--- /dev/null
+++ b/res/drawable-hdpi/pulse.png
Binary files differ
diff --git a/res/raw/nexus.rs b/res/raw/nexus.rs
new file mode 100644
index 0000000..43dde76
--- /dev/null
+++ b/res/raw/nexus.rs
@@ -0,0 +1,294 @@
+// Copyright (C) 2009 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma version(1)
+#pragma stateVertex(PVOrtho)
+#pragma stateFragment(PFTexture)
+#pragma stateStore(PSSolid)
+
+#define MAX_PULSES           20
+#define MAX_EXTRAS           40
+#define PULSE_SIZE           14 // Size in pixels of a cell
+#define HALF_PULSE_SIZE      7
+#define GLOW_SIZE            32 // Size of the leading glow in pixels
+#define HALF_GLOW_SIZE       16 
+#define SPEED                0.2f // (200 / 1000) Pixels per ms
+#define SPEED_VARIANCE       0.3f
+#define PULSE_NORMAL         0
+#define PULSE_EXTRA          1
+#define TRAIL_SIZE           40 // Number of cells in a trail
+#define MAX_DELAY	         2000 // Delay between a pulse going offscreen and restarting
+
+struct pulse_s {
+    int pulseType;
+    float originX;
+    float originY;
+    int color;
+    int startTime;
+    float dx;
+    float dy;
+    int active;
+};
+struct pulse_s gPulses[MAX_PULSES];
+
+struct pulse_s gExtras[MAX_EXTRAS];
+
+int gNow;
+
+
+void setColor(int c) {
+    if (c == 0) {
+        // red
+        color(1.0f, 0.0f, 0.0f, 1.0f);
+    } else if (c == 1) {
+        // green
+        color(0.0f, 0.6f, 0.0f, 1.0f);
+    } else if (c == 2) {
+        // blue
+        color(0.0f, 0.4f, 0.8f, 1.0f);
+    } else if (c == 3) {
+        // yellow
+        color(1.0f, 0.8f, 0.0f, 1.0f);
+    }
+}
+
+void initPulse(struct pulse_s * pulse, int pulseType) {
+    if (randf(1) > 0.5f) {
+        pulse->originX = (int)randf(State->width * 2 / PULSE_SIZE) * PULSE_SIZE;
+        pulse->dx = 0;
+        if (randf(1) > 0.5f) {
+            // Top
+            pulse->originY = 0;
+            pulse->dy = randf2(1.0f - SPEED_VARIANCE, 1.0 + SPEED_VARIANCE);
+        } else {
+            // Bottom
+            pulse->originY = State->height;
+            pulse->dy = -randf2(1.0f - SPEED_VARIANCE, 1.0 + SPEED_VARIANCE);
+        }
+    } else {
+        pulse->originY = (int)randf(State->height / PULSE_SIZE) * PULSE_SIZE;
+        pulse->dy = 0;
+        if (randf(1) > 0.5f) {
+            // Left
+            pulse->originX = 0;
+            pulse->dx = randf2(1.0f - SPEED_VARIANCE, 1.0 + SPEED_VARIANCE);
+        } else {
+            // Right
+            pulse->originX = State->width * 2;
+            pulse->dx = -randf2(1.0f - SPEED_VARIANCE, 1.0 + SPEED_VARIANCE);
+        }
+    }
+    pulse->startTime = gNow + (int)randf(MAX_DELAY);
+    
+    pulse->color = (int)randf(4.0f);
+    
+    pulse->pulseType = pulseType;
+    if (pulseType == PULSE_EXTRA) {
+        pulse->active = 0;
+    } else {
+        pulse->active = 1;
+    }
+}
+
+void initPulses() {
+    gNow = uptimeMillis();
+    int i;
+    for (i=0; i<MAX_PULSES; i++) {
+        initPulse(&gPulses[i], PULSE_NORMAL);
+    }
+    for (i=0; i<MAX_EXTRAS; i++) {
+        struct pulse_s * p = &gExtras[i];
+        p->pulseType = PULSE_EXTRA;
+        p->active = 0;
+    }
+}
+
+void drawBackground(int width, int height) {
+    bindTexture(NAMED_PFTexture, 0, NAMED_TBackground);
+    color(1.0f, 1.0f, 1.0f, 1.0f);
+    if (State->rotate) {
+        drawRect(0.0f, 0.0f, height*2, width, 0.0f);
+    } else {
+    	drawRect(0.0f, 0.0f, width*2, height, 0.0f);
+   	}
+}
+
+
+void drawPulses(struct pulse_s * pulseSet, int setSize) {
+	bindProgramFragment(NAMED_PFTexture);
+    bindProgramFragmentStore(NAMED_PSBlend);
+
+    float matrix[16];
+    
+    int i;
+    for (i=0; i<setSize; i++) {
+    	struct pulse_s * p = &pulseSet[i];
+    	
+ 	    int delta = gNow - p->startTime;
+    		        
+    	if (p->active != 0 && delta >= 0) {
+                
+	        float x = p->originX + (p->dx * SPEED * delta);
+	        float y = p->originY + (p->dy * SPEED * delta);
+	         
+	        matrixLoadIdentity(matrix);
+	        if (p->dx < 0) {
+	            vpLoadTextureMatrix(matrix);
+	            float xx = x + (TRAIL_SIZE * PULSE_SIZE);
+	            if (xx <= 0) {
+	                initPulse(p, p->pulseType);
+	            } else {
+	                setColor(p->color);
+	                bindTexture(NAMED_PFTexture, 0, NAMED_TPulse);            
+	                drawRect(x, y, xx, y + PULSE_SIZE, 0.0f);
+	                bindTexture(NAMED_PFTexture, 0, NAMED_TGlow);
+	                drawRect(x + HALF_PULSE_SIZE - HALF_GLOW_SIZE,
+	                    y + HALF_PULSE_SIZE - HALF_GLOW_SIZE,
+	                    x + HALF_PULSE_SIZE + HALF_GLOW_SIZE, 
+	                    y + HALF_PULSE_SIZE + HALF_GLOW_SIZE,
+	                    0.0f);
+	            }
+	        } else if (p->dx > 0) {
+	            matrixRotate(matrix, 180.0f, 0.0f, 0.0f, 1.0f);
+	            vpLoadTextureMatrix(matrix);
+	            float xx = x - (TRAIL_SIZE * PULSE_SIZE);
+	 	        if (xx >= State->width * 2) {
+	               initPulse(p, p->pulseType);
+	            } else {
+	                setColor(p->color);
+	                bindTexture(NAMED_PFTexture, 0, NAMED_TPulse);          
+	                drawRect(xx, y, x, y + PULSE_SIZE, 0.0f);
+	                bindTexture(NAMED_PFTexture, 0, NAMED_TGlow);
+	                drawRect(x - HALF_PULSE_SIZE - HALF_GLOW_SIZE,
+	                    y + HALF_PULSE_SIZE - HALF_GLOW_SIZE,
+	                    x - HALF_PULSE_SIZE + HALF_GLOW_SIZE, 
+	                    y + HALF_PULSE_SIZE + HALF_GLOW_SIZE,
+	                    0.0f);
+	            }
+	        } else if (p->dy < 0) {
+	            matrixRotate(matrix, -90.0f, 0.0f, 0.0f, 1.0f);
+	            vpLoadTextureMatrix(matrix);
+	            float yy = y + (TRAIL_SIZE * PULSE_SIZE);
+	            if (yy <= 0) {
+	               initPulse(p, p->pulseType);
+	            } else {
+	                setColor(p->color);
+	                bindTexture(NAMED_PFTexture, 0, NAMED_TPulse);
+	                drawRect(x, y, x + PULSE_SIZE, yy, 0.0f);
+	                bindTexture(NAMED_PFTexture, 0, NAMED_TGlow);
+	                drawRect(x + HALF_PULSE_SIZE - HALF_GLOW_SIZE,
+	                    y + HALF_PULSE_SIZE - HALF_GLOW_SIZE,
+	                    x + HALF_PULSE_SIZE + HALF_GLOW_SIZE, 
+	                    y + HALF_PULSE_SIZE + HALF_GLOW_SIZE,
+	                    0.0f);
+	            }
+	        } else if (p->dy > 0) {
+	            matrixRotate(matrix, 90.0f, 0.0f, 0.0f, 1.0f);
+	            vpLoadTextureMatrix(matrix);
+	            float yy = y - (TRAIL_SIZE * PULSE_SIZE);
+	            if (yy >= State->height) {
+	               initPulse(p, p->pulseType);
+	            } else {
+	                setColor(p->color);
+	                bindTexture(NAMED_PFTexture, 0, NAMED_TPulse);
+	                drawRect(x, yy, x + PULSE_SIZE, y, 0.0f);
+	                bindTexture(NAMED_PFTexture, 0, NAMED_TGlow);
+	                drawRect(x + HALF_PULSE_SIZE - HALF_GLOW_SIZE,
+	                    y - HALF_PULSE_SIZE - HALF_GLOW_SIZE,
+	                    x + HALF_PULSE_SIZE + HALF_GLOW_SIZE, 
+	                    y - HALF_PULSE_SIZE + HALF_GLOW_SIZE,
+	                    0.0f);
+	            }
+	        }
+	    }
+    }
+    
+    
+    matrixLoadIdentity(matrix);
+    vpLoadTextureMatrix(matrix);
+}
+
+void addTap(int x, int y) {
+    int i;
+    int count = 0;
+    int color = (int)randf(4.0f);
+    x = (int)(x / PULSE_SIZE) * PULSE_SIZE;
+    y = (int)(y / PULSE_SIZE) * PULSE_SIZE;   
+    for (i=0; i<MAX_EXTRAS; i++) {
+    	struct pulse_s * p = &gExtras[i];
+    	if (p->active == 0) {
+            p->originX = x;
+            p->originY = y;
+            
+            if (count == 0) { 
+                p->dx = 1.5f;
+                p->dy = 0.0f;
+            } else if (count == 1) {
+                p->dx = -1.5f;
+                p->dy = 0.0f;
+            } else if (count == 2) {
+                p->dx = 0.0f;
+                p->dy = 1.5f;
+            } else if (count == 3) {
+                p->dx = 0.0f;
+                p->dy = -1.5f;
+            }
+            
+            p->active = 1;
+            p->color = color;
+            color++;
+            if (color >= 4) {
+                color = 0;
+            }
+            p->startTime = gNow;
+            count++;
+            if (count == 4) {
+                break;
+            }
+        }
+    }
+}
+
+int main(int index) {
+
+    gNow = uptimeMillis();
+    
+    if (Command->command != 0) {
+        debugF("x", Command->x);
+        debugF("y", Command->y);
+        Command->command = 0;
+        addTap(Command->x, Command->y);
+    }
+    
+    int width = State->width;
+    int height = State->height;
+    
+    float matrix[16];
+    matrixLoadIdentity(matrix);
+    if (State->rotate) {
+        //matrixLoadRotate(matrix, 90.0f, 0.0f, 0.0f, 1.0f);
+        //matrixTranslate(matrix, 0.0f, -height, 1.0f);
+    } else {
+         matrixTranslate(matrix, -(State->xOffset * width), 0, 0);
+    }
+    
+    vpLoadModelMatrix(matrix);
+        
+    drawBackground(width, height);
+
+    drawPulses(gPulses, MAX_PULSES);
+    drawPulses(gExtras, MAX_EXTRAS);
+	    
+    return 1;
+}
diff --git a/src/com/android/wallpaper/nexus/NexusRS.java b/src/com/android/wallpaper/nexus/NexusRS.java
new file mode 100644
index 0000000..c93e875
--- /dev/null
+++ b/src/com/android/wallpaper/nexus/NexusRS.java
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wallpaper.nexus;
+
+import static android.renderscript.Element.RGBA_8888;
+import static android.renderscript.Element.RGB_565;
+import static android.renderscript.ProgramFragment.EnvMode.MODULATE;
+import static android.renderscript.ProgramFragment.EnvMode.REPLACE;
+import static android.renderscript.ProgramStore.DepthFunc.ALWAYS;
+import static android.renderscript.Sampler.Value.LINEAR;
+import static android.renderscript.Sampler.Value.WRAP;
+
+import com.android.wallpaper.R;
+import com.android.wallpaper.RenderScriptScene;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.renderscript.Allocation;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.renderscript.Sampler;
+import android.renderscript.Script;
+import android.renderscript.ScriptC;
+import android.renderscript.Type;
+import android.renderscript.ProgramStore.BlendDstFunc;
+import android.renderscript.ProgramStore.BlendSrcFunc;
+import android.view.SurfaceHolder;
+
+import java.util.TimeZone;
+
+class NexusRS extends RenderScriptScene {
+
+    private static final int RSID_STATE = 0;
+    
+    private static final int RSID_COMMAND = 1;
+
+    private static final int TEXTURES_COUNT = 3;
+
+    private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
+
+    private ProgramFragment mPfTexture;
+    
+    private ProgramFragment mPfColor;
+
+    private ProgramStore mPsSolid;
+    
+    private ProgramStore mPsBlend;
+    
+    private ProgramVertex mPvOrtho;
+    
+    private ProgramVertex.MatrixAllocation mPvOrthoAlloc;
+
+    private Sampler mSampler;
+
+    private Allocation mState;
+    
+    private Type mStateType;
+
+    private WorldState mWorldState;
+    
+    private Allocation mCommandAllocation;
+    
+    private Type mCommandType;
+
+    private CommandState mCommand;
+
+    public NexusRS(int width, int height) {
+        super(width, height);
+
+        mOptionsARGB.inScaled = false;
+        mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
+    }
+
+    @Override
+    public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
+        mWorldState.xOffset = xOffset;
+        mState.data(mWorldState);
+    }
+    
+    @Override
+    public void start() {
+        super.start();
+    }
+
+    @Override
+    public void resize(int width, int height) {
+        super.resize(width, height);
+
+        mWorldState.width = width;
+        mWorldState.height = height;
+        mWorldState.rotate = width > height ? 1 : 0;
+        mState.data(mWorldState);
+
+        mPvOrthoAlloc.setupOrthoWindow(mWidth, mHeight);
+    }
+
+    @Override
+    protected ScriptC createScript() {
+        createProgramVertex();
+        createProgramFragmentStore();
+        createProgramFragment();
+        createState();
+        loadTextures();
+
+        ScriptC.Builder sb = new ScriptC.Builder(mRS);
+        sb.setType(mStateType, "State", RSID_STATE);
+        sb.setType(mCommandType, "Command", RSID_COMMAND);
+        sb.setScript(mResources, R.raw.nexus);
+        Script.Invokable invokable = sb.addInvokable("initPulses");
+        sb.setRoot(true);
+
+        ScriptC script = sb.create();
+        script.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+        script.setTimeZone(TimeZone.getDefault().getID());
+
+        script.bindAllocation(mState, RSID_STATE);
+        script.bindAllocation(mCommandAllocation, RSID_COMMAND);
+        
+        invokable.execute();
+        
+        return script;
+    }
+
+    static class WorldState {
+        public int width;
+        public int height;
+        public float glWidth;
+        public float glHeight;
+        public int rotate;
+        public int isPreview;
+        public float xOffset;
+    }
+
+    static class CommandState {
+        public int x;
+        public int y;
+        public int command;
+    }
+
+    private void createState() {
+        mWorldState = new WorldState();
+        mWorldState.width = mWidth;
+        mWorldState.height = mHeight;
+        mWorldState.rotate = mWidth > mHeight ? 1 : 0;
+        mWorldState.isPreview = isPreview() ? 1 : 0;
+
+        mStateType = Type.createFromClass(mRS, WorldState.class, 1, "WorldState");
+        mState = Allocation.createTyped(mRS, mStateType);
+        mState.data(mWorldState);
+        
+        mCommand = new CommandState();
+        mCommand.x = -1;
+        mCommand.y = -1;
+        mCommand.command = 0;
+
+        mCommandType = Type.createFromClass(mRS, CommandState.class, 1, "DropState");
+        mCommandAllocation = Allocation.createTyped(mRS, mCommandType);
+        mCommandAllocation.data(mCommand);
+    }
+
+    private void loadTextures() {
+        final Allocation[] textures = new Allocation[TEXTURES_COUNT];
+        textures[0] = loadTexture(R.drawable.pyramid_background, "TBackground");
+        textures[1] = loadTextureARGB(R.drawable.pulse, "TPulse");        
+        textures[2] = loadTextureARGB(R.drawable.glow, "TGlow");   
+        
+        final int count = textures.length;
+        for (int i = 0; i < count; i++) {
+            textures[i].uploadToTexture(0);
+        }
+    }
+
+    private Allocation loadTexture(int id, String name) {
+        final Allocation allocation = Allocation.createFromBitmapResource(mRS, mResources,
+                id, RGB_565(mRS), false);
+        allocation.setName(name);
+        return allocation;
+    }
+
+    private Allocation loadTextureARGB(int id, String name) {
+        Bitmap b = BitmapFactory.decodeResource(mResources, id, mOptionsARGB);
+        final Allocation allocation = Allocation.createFromBitmap(mRS, b, RGBA_8888(mRS), false);
+        allocation.setName(name);
+        return allocation;
+    }
+
+    private void createProgramFragment() {
+        Sampler.Builder sampleBuilder = new Sampler.Builder(mRS);
+        sampleBuilder.setMin(LINEAR);
+        sampleBuilder.setMag(LINEAR);
+        sampleBuilder.setWrapS(WRAP);
+        sampleBuilder.setWrapT(WRAP);
+        mSampler = sampleBuilder.create();
+
+        ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS, null, null);
+        builder.setTexEnable(true, 0);
+        builder.setTexEnvMode(MODULATE, 0);
+        mPfTexture = builder.create();
+        mPfTexture.setName("PFTexture");
+        mPfTexture.bindSampler(mSampler, 0);
+        
+        builder = new ProgramFragment.Builder(mRS, null, null);
+        builder.setTexEnable(true, 0);
+        builder.setTexEnvMode(REPLACE, 0);
+        mPfColor = builder.create();
+        mPfColor.setName("PFColor");
+        mPfColor.bindSampler(mSampler, 0);
+    }
+
+    private void createProgramFragmentStore() {
+        ProgramStore.Builder builder = new ProgramStore.Builder(mRS, null, null);
+        builder.setDepthFunc(ALWAYS);
+        builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
+        builder.setDitherEnable(false);
+        builder.setDepthMask(true);
+        mPsSolid = builder.create();
+        mPsSolid.setName("PSSolid");
+        
+        builder = new ProgramStore.Builder(mRS, null, null);
+        builder.setDepthFunc(ALWAYS);
+       //  builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
+        builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE);
+
+        builder.setDitherEnable(false);
+        builder.setDepthMask(true);
+        mPsBlend = builder.create();
+        mPsBlend.setName("PSBlend");
+    }
+
+    private void createProgramVertex() {
+        mPvOrthoAlloc = new ProgramVertex.MatrixAllocation(mRS);
+        mPvOrthoAlloc.setupOrthoWindow(mWidth, mHeight);
+
+        ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null);
+        pvb.setTextureMatrixEnable(true);
+        mPvOrtho = pvb.create();
+        mPvOrtho.bindAllocation(mPvOrthoAlloc);
+        mPvOrtho.setName("PVOrtho");
+    }
+
+    @Override
+    public Bundle onCommand(String action, int x, int y, int z, Bundle extras,
+            boolean resultRequested) {
+
+        final int dw = mWorldState.width;
+        final int bw = 960;
+        x = (int) (x + mWorldState.xOffset * (bw-dw));
+        
+        if ("android.wallpaper.tap".equals(action)) {
+            sendCommand(1, x, y);
+        } else if ("android.home.drop".equals(action)) {
+            sendCommand(2, x, y);
+        }
+        return null;
+    }
+
+    private void sendCommand(int command, int x, int y) {
+        mCommand.x = x;
+        mCommand.y = y;
+        mCommand.command = command;
+        mCommandAllocation.data(mCommand);
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/wallpaper/nexus/NexusWallpaper.java b/src/com/android/wallpaper/nexus/NexusWallpaper.java
index b393616..ce84bf5 100644
--- a/src/com/android/wallpaper/nexus/NexusWallpaper.java
+++ b/src/com/android/wallpaper/nexus/NexusWallpaper.java
@@ -16,503 +16,11 @@
 
 package com.android.wallpaper.nexus;
 
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.BlurMaskFilter;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.LightingColorFilter;
-import android.graphics.Paint;
-import android.graphics.Point;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
-import android.graphics.PorterDuffXfermode;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.SystemClock;
-import android.service.wallpaper.WallpaperService;
-import android.util.MathUtils;
-import android.view.SurfaceHolder;
-import android.view.animation.AnimationUtils;
+import com.android.wallpaper.RenderScriptWallpaper;
+import com.android.wallpaper.RenderScriptScene;
 
-import java.util.Set;
-import java.util.HashSet;
-
-import com.android.wallpaper.R;
-
-public class NexusWallpaper extends WallpaperService {
-
-    private static final int NUM_PULSES = 12;
-    private static final int MAX_PULSES = 32;
-    private static final int PULSE_SIZE = 16;
-    private static final int MAX_ALPHA = 128; // 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/50; // in ms^-1
-
-    private static final int[] PULSE_COLORS = {
-        0xFF0066CC, 0xDDFF0000, 0xBBFFCC00, 0xEE009900,
-    };
-
-    private static final String LOG_TAG = "Nexus";
-
-    private final Handler mHandler = new Handler();
-
-    public Engine onCreateEngine() {
-        return new NexusEngine();
-    }
-
-    class NexusEngine extends Engine {
-
-        class Automaton {
-            public void step(long now) { }
-            public void draw(Canvas c) { }
-        }
-
-        class Pulse extends Automaton {
-            Point v;
-            Point[] pts;
-            int start, len; // pointers into pts
-            Paint paint;
-            Paint glowPaint;
-            long startTime;
-            boolean started;
-
-            public float zagProb = 0.007f;
-            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);
-                }
-                paint = new Paint(Paint.FILTER_BITMAP_FLAG|Paint.DITHER_FLAG);
-                paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
-
-                glowPaint = new Paint(paint);
-                glowPaint.setAlpha((int)(MAX_ALPHA*0.7f));
-
-                start = len = 0;
-            }
-            public Pulse(long now, int x, int y, int dx, int dy) {
-                this();
-                start(now, x, y, dx, dy);
-            }
-
-            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 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;
-                setColor(PULSE_COLORS[(int)Math.floor(Math.random()*PULSE_COLORS.length)]);
-                started = false;
-            }
-
-            public void setColor(int c) {
-                paint.setColor(c);
-                glowPaint.setColorFilter(new LightingColorFilter(paint.getColor(), 0));
-            }
-
-            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
-                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;
-
-                Point head = getHead();
-                c.drawBitmap(mGlow, (head.x-1)*mCellSize, (head.y-1)*mCellSize, glowPaint);
-
-                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);
-                }
-            }
-        }
-
-        private final Runnable mDrawNexus = new Runnable() {
-            public void run() {
-                drawFrame();
-                step();
-            }
-        };
-
-        private boolean mVisible;
-
-        private float mOffsetX;
-
-        private Bitmap mBackground;
-
-        private Bitmap mGreenLed;
-        
-        private Bitmap mGlow;
-
-        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() {
-        }
-
-        @Override
-        public void onCreate(SurfaceHolder surfaceHolder) {
-            super.onCreate(surfaceHolder);
-
-            Resources r = getResources();
-
-            mBackground = BitmapFactory.decodeResource(r, R.drawable.pyramid_background, null);
-
-            mBackgroundWidth = mBackground.getWidth();
-            mBackgroundHeight = mBackground.getHeight();
-
-            mGreenLed = BitmapFactory.decodeResource(r, R.drawable.led_green, null);
-
-            mCellSize = mGreenLed.getWidth();
-
-            mGlow = Bitmap.createBitmap(3*mCellSize, 3*mCellSize, Bitmap.Config.ARGB_8888);
-            Canvas c = new Canvas(mGlow);
-            Paint p = new Paint();
-            final int halfCell = mCellSize/2;
-            p.setMaskFilter(new BlurMaskFilter(halfCell, BlurMaskFilter.Blur.NORMAL));
-            p.setColor(Color.WHITE);
-            c.drawRect(halfCell, halfCell, 5*halfCell, 5*halfCell, p);
-
-            initializeState();
-
-            if (isPreview()) {
-                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;
-            }
-        }
-
-        @Override
-        public void onDestroy() {
-            super.onDestroy();
-            mHandler.removeCallbacks(mDrawNexus);
-        }
-
-        @Override
-        public void onVisibilityChanged(boolean visible) {
-            mVisible = visible;
-            if (!visible) {
-                mHandler.removeCallbacks(mDrawNexus);
-            }
-            drawFrame();
-        }
-
-        @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();
-        }
-
-        @Override
-        public void onSurfaceCreated(SurfaceHolder holder) {
-            super.onSurfaceCreated(holder);
-        }
-
-        @Override
-        public void onSurfaceDestroyed(SurfaceHolder holder) {
-            super.onSurfaceDestroyed(holder);
-            mVisible = false;
-            mHandler.removeCallbacks(mDrawNexus);
-        }
-
-        @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);
-                
-                int colorIdx = (int)(Math.random() * PULSE_COLORS.length);
-
-                Pulse p = new Pulse();
-                p.zagProb = 0;
-                p.start(0, cellX, cellY, 0, 1);
-                p.setColor(PULSE_COLORS[colorIdx]);
-                addPulse(p);
-                colorIdx = (colorIdx + 1) % PULSE_COLORS.length;
-
-                p = new Pulse();
-                p.zagProb = 0;
-                p.start(0, cellX, cellY, 1, 0);
-                p.setColor(PULSE_COLORS[colorIdx]);
-                addPulse(p);
-                colorIdx = (colorIdx + 1) % PULSE_COLORS.length;
-
-                p = new Pulse();
-                p.zagProb = 0;
-                p.start(0, cellX, cellY, -1, 0);
-                p.setColor(PULSE_COLORS[colorIdx]);
-                addPulse(p);
-                colorIdx = (colorIdx + 1) % PULSE_COLORS.length;
-
-                p = new Pulse();
-                p.zagProb = 0;
-                p.start(0, cellX, cellY, 0, -1);
-                p.setColor(PULSE_COLORS[colorIdx]);
-                addPulse(p);
-                colorIdx = (colorIdx + 1) % PULSE_COLORS.length;
-
-            } else if ("android.home.drop".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);
-
-                p = new Pulse();
-                p.zagProb = 0;
-                p.start(0, cellX, cellY, -1, -1);
-                addPulse(p);
-                p = new Pulse();
-                p.zagProb = 0;
-                p.start(0, cellX, cellY, 1, -1);
-                addPulse(p);
-                p = new Pulse();
-                p.zagProb = 0;
-                p.start(0, cellX, cellY, 1, 1);
-                addPulse(p);
-                p = new Pulse();
-                p.zagProb = 0;
-                p.start(0, cellX, cellY, -1, 1);
-                addPulse(p);
-            }
-            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();
-
-            Canvas c = null;
-            try {
-                c = holder.lockCanvas();
-                if (c != null) {
-                    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);
-                    for (Automaton p : mPulses) {
-                        p.draw(c);
-                    }
-                }
-            } finally {
-                if (c != null) holder.unlockCanvasAndPost(c);
-            }
-
-            mHandler.removeCallbacks(mDrawNexus);
-            if (mVisible) {
-                mHandler.postDelayed(mDrawNexus, ANIMATION_PERIOD);
-            }
-        }
+public class NexusWallpaper extends RenderScriptWallpaper {
+    protected RenderScriptScene createScene(int width, int height) {
+        return new NexusRS(width, height);
     }
 }
