am f437fb6b: (-s ours) Import translations for additional languages.

* commit 'f437fb6b3edc6a13ae2ba9bb14c5eac29808979c':
  Import translations for additional languages.
diff --git a/Android.mk b/Android.mk
index ef3f75e..c74206a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -14,12 +14,14 @@
 # limitations under the License.
 #
 
+ifneq ($(TARGET_SIMULATOR),true)
+
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_SRC_FILES := $(call all-subdir-java-files) $(call all-renderscript-files-under, src)
 
 LOCAL_PACKAGE_NAME := VisualizationWallpapers
 LOCAL_CERTIFICATE := shared
@@ -27,3 +29,5 @@
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
 include $(BUILD_PACKAGE)
+
+endif
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 3690dec..ea73ea2 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -35,7 +35,9 @@
         <service
             android:label="@string/wallpaper_vis1"
             android:name=".vis1.Visualization1"
-            android:permission="android.permission.BIND_WALLPAPER">
+            android:permission="android.permission.BIND_WALLPAPER"
+            android:enabled="@bool/config_enable_vis1"
+            >
             <intent-filter>
                 <action android:name="android.service.wallpaper.WallpaperService" />
             </intent-filter>
@@ -46,7 +48,9 @@
         <service
             android:label="@string/wallpaper_vis2"
             android:name=".vis2.Visualization2"
-            android:permission="android.permission.BIND_WALLPAPER">
+            android:permission="android.permission.BIND_WALLPAPER"
+            android:enabled="@bool/config_enable_vis2"
+            >
             <intent-filter>
                 <action android:name="android.service.wallpaper.WallpaperService" />
             </intent-filter>
@@ -56,7 +60,9 @@
         <service
             android:label="@string/wallpaper_vis3"
             android:name=".vis3.Visualization3"
-            android:permission="android.permission.BIND_WALLPAPER">
+            android:permission="android.permission.BIND_WALLPAPER"
+            android:enabled="@bool/config_enable_vis3"
+            >
             <intent-filter>
                 <action android:name="android.service.wallpaper.WallpaperService" />
             </intent-filter>
@@ -66,7 +72,9 @@
         <service
             android:label="@string/wallpaper_vis4"
             android:name=".vis4.Visualization4"
-            android:permission="android.permission.BIND_WALLPAPER">
+            android:permission="android.permission.BIND_WALLPAPER"
+            android:enabled="@bool/config_enable_vis4"
+            >
             <intent-filter>
                 <action android:name="android.service.wallpaper.WallpaperService" />
             </intent-filter>
@@ -76,14 +84,15 @@
         <service
             android:label="@string/wallpaper_vis5"
             android:name=".vis5.Visualization5"
-            android:permission="android.permission.BIND_WALLPAPER">
+            android:permission="android.permission.BIND_WALLPAPER"
+            android:enabled="@bool/config_enable_vis5"
+            >
             <intent-filter>
                 <action android:name="android.service.wallpaper.WallpaperService" />
             </intent-filter>
             <meta-data android:name="android.service.wallpaper" android:resource="@xml/vis5" />
         </service>
 
-
     </application>
 
 </manifest>
diff --git a/res/raw/many.rs b/res/raw/many.rs
deleted file mode 100644
index bfde7ca..0000000
--- a/res/raw/many.rs
+++ /dev/null
@@ -1,294 +0,0 @@
-// 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(PVBackground)
-#pragma stateRaster(parent)
-#pragma stateStore(PFSBackground)
-
-#define RSID_POINTS 1
-
-void dumpState() {
-
-//    debugF("@@@@@ yrot: ", State->yRotation);
-
-}
-
-
-void drawVU(float* ident) {
-
-    int i;
-
-    float mat1[16];
-    float scale = 0.0041;
-
-    matrixLoadMat(mat1,ident);
-    matrixRotate(mat1, 0.f, 0.f, 0.f, 1.f);
-    matrixScale(mat1, scale, scale, scale);
-    vpLoadModelMatrix(mat1);
-
-    bindProgramFragment(NAMED_PFBackgroundMip);
-
-    // draw the background image (416x233)
-    bindTexture(NAMED_PFBackgroundMip, 0, NAMED_Tvumeter_background);
-    drawQuadTexCoords(
-            -208.0f, -33.0f, 600.0f,        // space
-                0.09375f, 0.9551f,        // texture
-            208, -33.0f, 600.0f,            // space
-                0.90625, 0.9551f,         // texture
-            208, 200.0f, 600.0f,            // space
-                0.90625, 0.0449f,         // texture
-            -208.0f, 200.0f, 600.0f,        // space
-                0.09375f, 0.0449f);       // texture
-
-    // draw the peak indicator light (56x58)
-    if (State->mPeak > 0) {
-        bindTexture(NAMED_PFBackgroundMip, 0, NAMED_Tvumeter_peak_on);
-    } else {
-        bindTexture(NAMED_PFBackgroundMip, 0, NAMED_Tvumeter_peak_off);
-    }
-    drawQuadTexCoords(
-            140.0f, 70.0f, 600.0f,         // space
-                0.0625f, 0.953125,        // texture
-            196, 70.0f, 600.0f,            // space
-                0.9375f, 0.953125,        // texture
-            196, 128.0f, 600.0f,           // space
-                0.9375f, 0.046875,        // texture
-            140.0f, 128.0f, 600.0f,        // space
-                0.0625f, 0.046875);       // texture
-
-
-
-    // Draw the needle (88x262, center of rotation at 44,217 from top left)
-
-    // set matrix so point of rotation becomes origin
-    matrixLoadMat(mat1,ident);
-    matrixTranslate(mat1, 0.f, -57.0f * scale, 0.f);
-    matrixRotate(mat1, State->mAngle - 90.f, 0.f, 0.f, 1.f);
-    matrixScale(mat1, scale, scale, scale);
-    vpLoadModelMatrix(mat1);
-    bindTexture(NAMED_PFBackgroundMip, 0, NAMED_Tvumeter_needle);
-    drawQuadTexCoords(
-            -44.0f, -102.0f+57.f, 600.0f,         // space
-                .15625f, 0.755859375f,  // texture
-            44.0f, -102.0f+57.f, 600.0f,             // space
-                0.84375f, 0.755859375f,  // texture
-            44.0f, 160.0f+57.f, 600.0f,             // space
-                0.84375f, 0.244140625f,  // texture
-            -44.0f, 160.0f+57.f, 600.0f,         // space
-                0.15625f, 0.244140625f); // texture
-
-
-    // restore matrix
-    matrixLoadMat(mat1,ident);
-    matrixRotate(mat1, 0.f, 0.f, 0.f, 1.f);
-    matrixScale(mat1, scale, scale, scale);
-    vpLoadModelMatrix(mat1);
-
-    // erase the part of the needle we don't want to show
-    bindTexture(NAMED_PFBackgroundMip, 0, NAMED_Tvumeter_black);
-    drawQuad(-100.f, -55.f, 600.f,
-             -100.f, -105.f, 600.f,
-              100.f, -105.f, 600.f,
-              100.f, -55.f, 600.f);
-
-
-    // draw the frame (472x290)
-    bindTexture(NAMED_PFBackgroundMip, 0, NAMED_Tvumeter_frame);
-    drawQuadTexCoords(
-            -236.0f, -60.0f, 600.0f,           // space
-                0.0390625f, 0.783203125f,    // texture
-            236, -60.0f, 600.0f,               // space
-                0.9609375f, 0.783203125f,    // texture
-            236, 230.0f, 600.0f,               // space
-                0.9609375f, 0.216796875f,    // texture
-            -236.0f, 230.0f, 600.0f,           // space
-                0.0390625f, 0.216796875f);   // texture
-
-
-}
-
-int fadeoutcounter = 0;
-int fadeincounter = 0;
-int wave1pos = 0;
-int wave1amp = 0;
-int wave2pos = 0;
-int wave2amp= 0;
-int wave3pos = 0;
-int wave3amp= 0;
-int wave4pos = 0;
-int wave4amp= 0;
-float idle[4096];
-int waveCounter = 0;
-int lastuptime = 0;
-float autorotation = 0;
-
-#define FADEOUT_LENGTH 100
-#define FADEOUT_FACTOR 0.95f
-#define FADEIN_LENGTH 15
-
-void makeIdleWave(float *points) {
-    int i;
-    // show a number of superimposed moving sinewaves
-    float amp1 = sinf(0.007 * wave1amp) * 120 * 1024;
-    float amp2 = sinf(0.023 * wave2amp) * 80 * 1024;
-    float amp3 = sinf(0.011 * wave3amp) * 40 * 1024;
-    float amp4 = sinf(0.031 * wave4amp) * 20 * 1024;
-    for (i = 0; i < 256; i++) {
-        float val = sinf(0.013 * (wave1pos + i * 4)) * amp1
-                  + sinf(0.029 * (wave2pos + i * 4)) * amp2;
-        float off = sinf(0.005 * (wave3pos + i * 4)) * amp3
-                  + sinf(0.017 * (wave4pos + i * 4)) * amp4;
-        if (val < 2.f && val > -2.f) val = 2.f;
-        points[i*8+1] = val + off;
-        points[i*8+5] = -val + off;
-    }
-}
-
-
-void drawWave(float *ident) {
-    float scale = .008f;
-    float mat1[16];
-    matrixLoadMat(mat1, ident);
-    matrixScale(mat1, scale, scale / 2048.f, scale);
-    matrixTranslate(mat1, 0.f, 81920.f, 350.f);
-    vpLoadModelMatrix(mat1);
-    int i;
-
-    if (State->mIdle) {
-
-        // idle state animation
-        float *points = loadArrayF(RSID_POINTS, 0);
-        if (fadeoutcounter > 0) {
-            // fade waveform to 0
-            for (i = 0; i < 256; i++) {
-                float val = absf(points[i*8+1]);
-                val = val * FADEOUT_FACTOR;
-                if (val < 2.f) val = 2.f;
-                points[i*8+1] = val;
-                points[i*8+5] = -val;
-            }
-            fadeoutcounter--;
-            if (fadeoutcounter == 0) {
-                wave1amp = 0;
-                wave2amp = 0;
-                wave3amp = 0;
-                wave4amp = 0;
-            }
-        } else {
-            // idle animation
-            makeIdleWave(points);
-        }
-        fadeincounter = FADEIN_LENGTH;
-    } else {
-        if (fadeincounter > 0 && fadeoutcounter == 0) {
-            // morph from idle animation back to waveform
-            makeIdleWave(idle);
-            if (waveCounter != State->mWaveCounter) {
-                waveCounter = State->mWaveCounter;
-                float *points = loadArrayF(RSID_POINTS, 0);
-                for (i = 0; i < 256; i++) {
-                    float val = absf(points[i*8+1]);
-                    points[i*8+1] = (val * (FADEIN_LENGTH - fadeincounter) + idle[i*8+1] * fadeincounter) / FADEIN_LENGTH;
-                    points[i*8+5] = (-val * (FADEIN_LENGTH - fadeincounter) + idle[i*8+5] * fadeincounter) / FADEIN_LENGTH;
-                }
-            }
-            fadeincounter--;
-            if (fadeincounter == 0) {
-                fadeoutcounter = FADEOUT_LENGTH;
-            }
-        } else {
-            fadeoutcounter = FADEOUT_LENGTH;
-        }
-    }
-
-    uploadToBufferObject(NAMED_PointBuffer);
-    bindProgramFragment(NAMED_PFBackgroundNoMip);
-    bindTexture(NAMED_PFBackgroundNoMip, 0, NAMED_Tlinetexture);
-    drawSimpleMesh(NAMED_CubeMesh);
-}
-
-
-void drawVizLayer(float *ident) {
-
-    int i;
-
-    for (i = 0; i < 6; i++) {
-        if (i & 1) {
-            drawVU(ident);
-        } else {
-            drawWave(ident);
-        }
-
-        matrixRotate(ident, 60.f, 0.f, 1.f, 0.f);
-    }
-}
-
-
-int main(int launchID) {
-
-    int i;
-    float ident[16];
-    int now = uptimeMillis();
-    int delta = now - lastuptime;
-    lastuptime = now;
-    if (delta > 80) {
-        // Limit the delta to avoid jumps when coming back from sleep.
-        // A value of 80 will make the rotation keep the same speed
-        // until the frame rate drops to 12.5 fps, at which point it
-        // will start slowing down.
-        delta = 80;
-    }
-    autorotation += .3 * delta / 35;
-    while (autorotation > 360.f) autorotation -= 360.f;
-
-    matrixLoadIdentity(ident);
-    matrixRotate(ident, State->mTilt, 1.f, 0.f, 0.f);
-    matrixRotate(ident, autorotation + State->mRotate, 0.f, 1.f, 0.f);
-
-    // draw the reflections
-    matrixTranslate(ident, 0.f, -1.f, 0.f);
-    matrixScale(ident, 1.f, -1.f, 1.f);
-    drawVizLayer(ident);
-
-    // draw the reflecting plane
-    bindProgramFragment(NAMED_PFBackgroundMip);
-    bindTexture(NAMED_PFBackgroundMip, 0, NAMED_Tvumeter_album);
-    drawQuadTexCoords(
-            -1500.0f, -60.0f, 1500.0f,           // space
-                0.f, 1.f,    // texture
-            1500, -60.0f, 1500.0f,               // space
-                1.f, 1.f,    // texture
-            1500, -60.0f, -1500.0f,               // space
-                1.f, 0.f,    // texture
-            -1500.0f, -60.0f, -1500.0f,           // space
-                0.f, 0.f);   // texture
-
-    // draw the visualizer
-    matrixScale(ident, 1.f, -1.f, 1.f);
-    matrixTranslate(ident, 0.f, 1.f, 0.f);
-
-    drawVizLayer(ident);
-
-    wave1pos++;
-    wave1amp++;
-    wave2pos--;
-    wave2amp++;
-    wave3pos++;
-    wave3amp++;
-    wave4pos++;
-    wave4amp++;
-
-    return 1;
-}
diff --git a/res/raw/vu.rs b/res/raw/vu.rs
deleted file mode 100644
index cde4911..0000000
--- a/res/raw/vu.rs
+++ /dev/null
@@ -1,117 +0,0 @@
-// 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(PVBackground)
-#pragma stateRaster(parent)
-#pragma stateFragment(PFBackground)
-#pragma stateStore(PFSBackground)
-
-#define RSID_POINTS 1
-
-void dumpState() {
-
-//    debugF("@@@@@ yrot: ", State->yRotation);
-
-}
-
-
-int main(int launchID) {
-
-    int i;
-
-    float mat1[16];
-    float scale = 0.0041;
-    matrixLoadRotate(mat1, 0.f, 0.f, 0.f, 1.f);
-    matrixScale(mat1, scale, scale, scale);
-    vpLoadModelMatrix(mat1);
-
-    // draw the background image (416x233)
-    bindTexture(NAMED_PFBackground, 0, NAMED_Tvumeter_background);
-    drawQuadTexCoords(
-            -208.0f, -33.0f, 0.0f,        // space
-                0.09375f, 0.9551f,        // texture
-            208, -33.0f, 0.0f,            // space
-                0.90625, 0.9551f,         // texture
-            208, 200.0f, 0.0f,            // space
-                0.90625, 0.0449f,         // texture
-            -208.0f, 200.0f, 0.0f,        // space
-                0.09375f, 0.0449f);       // texture
-
-    // draw the peak indicator light (56x58)
-    if (State->mPeak > 0) {
-        bindTexture(NAMED_PFBackground, 0, NAMED_Tvumeter_peak_on);
-    } else {
-        bindTexture(NAMED_PFBackground, 0, NAMED_Tvumeter_peak_off);
-    }
-    drawQuadTexCoords(
-            140.0f, 70.0f, -1.0f,         // space
-                0.0625f, 0.953125,        // texture
-            196, 70.0f, -1.0f,            // space
-                0.9375f, 0.953125,        // texture
-            196, 128.0f, -1.0f,           // space
-                0.9375f, 0.046875,        // texture
-            140.0f, 128.0f, -1.0f,        // space
-                0.0625f, 0.046875);       // texture
-
-
-
-    // Draw the needle (88x262, center of rotation at 44,217 from top left)
-
-    // set matrix so point of rotation becomes origin
-    matrixLoadTranslate(mat1, 0.f, -57.0f * scale, 0.f);
-    matrixRotate(mat1, State->mAngle - 90.f, 0.f, 0.f, 1.f);
-    matrixScale(mat1, scale, scale, scale);
-    vpLoadModelMatrix(mat1);
-    bindTexture(NAMED_PFBackground, 0, NAMED_Tvumeter_needle);
-    drawQuadTexCoords(
-            -44.0f, -102.0f+57.f, 0.0f,         // space
-                .15625f, 0.755859375f,  // texture
-            44.0f, -102.0f+57.f, 0.0f,             // space
-                0.84375f, 0.755859375f,  // texture
-            44.0f, 160.0f+57.f, 0.0f,             // space
-                0.84375f, 0.244140625f,  // texture
-            -44.0f, 160.0f+57.f, 0.0f,         // space
-                0.15625f, 0.244140625f); // texture
-
-
-    // restore matrix
-    matrixLoadRotate(mat1, 0.f, 0.f, 0.f, 1.f);
-    matrixScale(mat1, scale, scale, scale);
-    vpLoadModelMatrix(mat1);
-
-    // erase the part of the needle we don't want to show
-    bindTexture(NAMED_PFBackground, 0, NAMED_Tvumeter_black);
-    drawQuad(-100.f, -55.f, 0.f,
-             -100.f, -105.f, 0.f,
-              100.f, -105.f, 0.f,
-              100.f, -55.f, 0.f);
-
-
-    // draw the frame (472x290)
-    bindTexture(NAMED_PFBackground, 0, NAMED_Tvumeter_frame);
-    drawQuadTexCoords(
-            -236.0f, -60.0f, 0.0f,           // space
-                0.0390625f, 0.783203125f,    // texture
-            236, -60.0f, 0.0f,               // space
-                0.9609375f, 0.783203125f,    // texture
-            236, 230.0f, 0.0f,               // space
-                0.9609375f, 0.216796875f,    // texture
-            -236.0f, 230.0f, 0.0f,           // space
-                0.0390625f, 0.216796875f);   // texture
-
-
-
-    return 1;
-}
diff --git a/res/raw/waveform.rs b/res/raw/waveform.rs
deleted file mode 100644
index dbe06d8..0000000
--- a/res/raw/waveform.rs
+++ /dev/null
@@ -1,140 +0,0 @@
-// 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(PVBackground)
-#pragma stateRaster(parent)
-#pragma stateFragment(PFBackground)
-
-#define RSID_POINTS 1
-
-#define FADEOUT_LENGTH 100
-#define FADEOUT_FACTOR 0.95f
-#define FADEIN_LENGTH 15
-
-int fadeoutcounter = 0;
-int fadeincounter = 0;
-int wave1pos = 0;
-int wave1amp = 0;
-int wave2pos = 0;
-int wave2amp= 0;
-int wave3pos = 0;
-int wave3amp= 0;
-int wave4pos = 0;
-int wave4amp= 0;
-float idle[8192];
-int waveCounter = 0;
-
-void makeIdleWave(float *points) {
-    int i;
-    // show a number of superimposed moving sinewaves
-    float amp1 = sinf(0.007 * wave1amp) * 120;
-    float amp2 = sinf(0.023 * wave2amp) * 80;
-    float amp3 = sinf(0.011 * wave3amp) * 40;
-    float amp4 = sinf(0.031 * wave4amp) * 20;
-    // calculate how many invisible lines there are on each side
-    int skip = (1024 - State->width) / 2;
-    int end = 1024 - skip;
-    for (i = skip; i < end; i++) {
-        float val = sinf(0.013 * (wave1pos + i)) * amp1
-                  + sinf(0.029 * (wave2pos + i)) * amp2;
-        float off = sinf(0.005 * (wave3pos + i)) * amp3
-                  + sinf(0.017 * (wave4pos + i)) * amp4;
-        if (val < 2.f && val > -2.f) val = 2.f;
-        points[i*8+1] = val + off;
-        points[i*8+5] = -val + off;
-    }
-    wave1pos++;
-    wave1amp++;
-    wave2pos--;
-    wave2amp++;
-    wave3pos++;
-    wave3amp++;
-    wave4pos++;
-    wave4amp++;
-}
-
-int main(int launchID) {
-
-    int i;
-
-    // calculate how many invisible lines there are on each side
-    int width = State->width;
-    int skip = (1024 - width) / 2;
-    int end = 1024 - skip;
-
-    if (State->idle) {
-
-        // idle state animation
-        float *points = loadArrayF(RSID_POINTS, 0);
-        if (fadeoutcounter > 0) {
-            // fade waveform to 0
-            for (i = skip; i < end; i++) {
-                float val = absf(points[i*8+1]);
-                val = val * FADEOUT_FACTOR;
-                if (val < 2.f) val = 2.f;
-                points[i*8+1] = val;
-                points[i*8+5] = -val;
-            }
-            fadeoutcounter--;
-            if (fadeoutcounter == 0) {
-                wave1amp = 0;
-                wave2amp = 0;
-                wave3amp = 0;
-                wave4amp = 0;
-            }
-        } else {
-            // idle animation
-            makeIdleWave(points);
-        }
-        fadeincounter = FADEIN_LENGTH;
-    } else {
-        if (fadeincounter > 0 && fadeoutcounter == 0) {
-            // morph from idle animation back to waveform
-            makeIdleWave(idle);
-            if (waveCounter != State->waveCounter) {
-                waveCounter = State->waveCounter;
-                float *points = loadArrayF(RSID_POINTS, 0);
-                for (i = skip; i < end; i++) {
-                    float val = absf(points[i*8+1]);
-                    points[i*8+1] = (val * (FADEIN_LENGTH - fadeincounter) + idle[i*8+1] * fadeincounter) / FADEIN_LENGTH;
-                    points[i*8+5] = (-val * (FADEIN_LENGTH - fadeincounter) + idle[i*8+5] * fadeincounter) / FADEIN_LENGTH;
-                }
-            }
-            fadeincounter--;
-            if (fadeincounter == 0) {
-                fadeoutcounter = FADEOUT_LENGTH;
-            }
-        } else {
-            fadeoutcounter = FADEOUT_LENGTH;
-        }
-    }
-
-    float mat1[16];
-    float yrot = State->yRotation;
-    float scale = 0.004165f * (1.0f + 2.f * absf(sinf(radf(yrot))));
-
-    // Change the model matrix to account for the large model
-    // and to do the necessary rotations.
-    matrixLoadRotate(mat1, yrot, 0.f, 0.f, 1.f);
-    matrixScale(mat1, scale, scale, scale);
-    vpLoadModelMatrix(mat1);
-
-    // Draw the visualizer.
-    uploadToBufferObject(NAMED_PointBuffer);
-    bindTexture(NAMED_PFBackground, 0, NAMED_Tlinetexture);
-    drawSimpleMeshRange(NAMED_CubeMesh, skip * 2, width * 2);
-
-    return 1;
-}
diff --git a/res/values-ar/cube.xml b/res/values-ar/cube.xml
index 3991382..1a26f1e 100644
--- a/res/values-ar/cube.xml
+++ b/res/values-ar/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-bg/cube.xml b/res/values-bg/cube.xml
index e111582..403d4f0 100644
--- a/res/values-bg/cube.xml
+++ b/res/values-bg/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-ca/cube.xml b/res/values-ca/cube.xml
index cfe7be6..f69f6d3 100644
--- a/res/values-ca/cube.xml
+++ b/res/values-ca/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-cs/cube.xml b/res/values-cs/cube.xml
index 4ffb04f..ab914b7 100644
--- a/res/values-cs/cube.xml
+++ b/res/values-cs/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-da/cube.xml b/res/values-da/cube.xml
index 162fa33..a44f1fd 100644
--- a/res/values-da/cube.xml
+++ b/res/values-da/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-de/cube.xml b/res/values-de/cube.xml
index ed0ecaa..92dab47 100644
--- a/res/values-de/cube.xml
+++ b/res/values-de/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-el/cube.xml b/res/values-el/cube.xml
index 38dc394..b1eb318 100644
--- a/res/values-el/cube.xml
+++ b/res/values-el/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-en-rGB/cube.xml b/res/values-en-rGB/cube.xml
index 0e520fe..f745481 100644
--- a/res/values-en-rGB/cube.xml
+++ b/res/values-en-rGB/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-es-rUS-xlarge/strings.xml b/res/values-es-rUS-xlarge/strings.xml
new file mode 100644
index 0000000..697b60b
--- /dev/null
+++ b/res/values-es-rUS-xlarge/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- XL -->
+    <string name="vis5_desc" msgid="2857970801072726523">"Toda la visualizaciones de música juntas, moviéndose suavemente en 3D."</string>
+</resources>
diff --git a/res/values-es-rUS/cube.xml b/res/values-es-rUS/cube.xml
index 9beafc7..e4f2469 100644
--- a/res/values-es-rUS/cube.xml
+++ b/res/values-es-rUS/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-es/cube.xml b/res/values-es/cube.xml
index 334087c..427393b 100644
--- a/res/values-es/cube.xml
+++ b/res/values-es/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-fa/cube.xml b/res/values-fa/cube.xml
index 44d2359..19b0e81 100644
--- a/res/values-fa/cube.xml
+++ b/res/values-fa/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-fi/cube.xml b/res/values-fi/cube.xml
index 9ecc9d9..9a52e05 100644
--- a/res/values-fi/cube.xml
+++ b/res/values-fi/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-fr/cube.xml b/res/values-fr/cube.xml
index 4d2d0a3..1ce73a5 100644
--- a/res/values-fr/cube.xml
+++ b/res/values-fr/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-hr/cube.xml b/res/values-hr/cube.xml
index d8938ce..a390ab7 100644
--- a/res/values-hr/cube.xml
+++ b/res/values-hr/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-hu/cube.xml b/res/values-hu/cube.xml
index 2972339..7a30a99 100644
--- a/res/values-hu/cube.xml
+++ b/res/values-hu/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-in/cube.xml b/res/values-in/cube.xml
index 16b977e..7790835 100644
--- a/res/values-in/cube.xml
+++ b/res/values-in/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-it/cube.xml b/res/values-it/cube.xml
index de6bec6..815d3fa 100644
--- a/res/values-it/cube.xml
+++ b/res/values-it/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-iw/cube.xml b/res/values-iw/cube.xml
index 3c59133..52b7486 100644
--- a/res/values-iw/cube.xml
+++ b/res/values-iw/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-ja/cube.xml b/res/values-ja/cube.xml
index 9fef285..980bb25 100644
--- a/res/values-ja/cube.xml
+++ b/res/values-ja/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-ko/cube.xml b/res/values-ko/cube.xml
index a28669e..24431fa 100644
--- a/res/values-ko/cube.xml
+++ b/res/values-ko/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-lt/cube.xml b/res/values-lt/cube.xml
index eb43a8e..94f2170 100644
--- a/res/values-lt/cube.xml
+++ b/res/values-lt/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-lv/cube.xml b/res/values-lv/cube.xml
index 8347e0f..aa602da 100644
--- a/res/values-lv/cube.xml
+++ b/res/values-lv/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-nb/cube.xml b/res/values-nb/cube.xml
index 162fa33..a44f1fd 100644
--- a/res/values-nb/cube.xml
+++ b/res/values-nb/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-nl/cube.xml b/res/values-nl/cube.xml
index 41856dc..ad25b76 100644
--- a/res/values-nl/cube.xml
+++ b/res/values-nl/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-pl/cube.xml b/res/values-pl/cube.xml
index b5e00e5..07efa8a 100644
--- a/res/values-pl/cube.xml
+++ b/res/values-pl/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-pt-rPT/cube.xml b/res/values-pt-rPT/cube.xml
index f85069d..c1954e0 100644
--- a/res/values-pt-rPT/cube.xml
+++ b/res/values-pt-rPT/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-pt/cube.xml b/res/values-pt/cube.xml
index b4572c0..fecd48d 100644
--- a/res/values-pt/cube.xml
+++ b/res/values-pt/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-rm/cube.xml b/res/values-rm/cube.xml
index 54ab08f..220cb90 100644
--- a/res/values-rm/cube.xml
+++ b/res/values-rm/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-ro/cube.xml b/res/values-ro/cube.xml
index a11e795..f560a9d 100644
--- a/res/values-ro/cube.xml
+++ b/res/values-ro/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-ru/cube.xml b/res/values-ru/cube.xml
index e0fbd2a..e988f4a 100644
--- a/res/values-ru/cube.xml
+++ b/res/values-ru/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-sk/cube.xml b/res/values-sk/cube.xml
index 8a58681..8d875b3 100644
--- a/res/values-sk/cube.xml
+++ b/res/values-sk/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-sl/cube.xml b/res/values-sl/cube.xml
index 3f28bb1..78bb773 100644
--- a/res/values-sl/cube.xml
+++ b/res/values-sl/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-sr/cube.xml b/res/values-sr/cube.xml
index 2078657..eabc056 100644
--- a/res/values-sr/cube.xml
+++ b/res/values-sr/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-sv/cube.xml b/res/values-sv/cube.xml
index d193493..1278cc0 100644
--- a/res/values-sv/cube.xml
+++ b/res/values-sv/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-th/cube.xml b/res/values-th/cube.xml
index b253a59..18b4cfe 100644
--- a/res/values-th/cube.xml
+++ b/res/values-th/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-tl/cube.xml b/res/values-tl/cube.xml
index fbb57db..a01102c 100644
--- a/res/values-tl/cube.xml
+++ b/res/values-tl/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-tr/cube.xml b/res/values-tr/cube.xml
index 7838ef6..f673fbf 100644
--- a/res/values-tr/cube.xml
+++ b/res/values-tr/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-uk/cube.xml b/res/values-uk/cube.xml
index 5d31402..0f5b11f 100644
--- a/res/values-uk/cube.xml
+++ b/res/values-uk/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-vi/cube.xml b/res/values-vi/cube.xml
index 486c38f..b4080f4 100644
--- a/res/values-vi/cube.xml
+++ b/res/values-vi/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-zh-rCN/cube.xml b/res/values-zh-rCN/cube.xml
index 071da65..d3468d3 100644
--- a/res/values-zh-rCN/cube.xml
+++ b/res/values-zh-rCN/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values-zh-rTW/cube.xml b/res/values-zh-rTW/cube.xml
index 1facbf2..ffe8705 100644
--- a/res/values-zh-rTW/cube.xml
+++ b/res/values-zh-rTW/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
diff --git a/res/values/config.xml b/res/values/config.xml
new file mode 100644
index 0000000..34c21c0
--- /dev/null
+++ b/res/values/config.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright (C) 2010 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <bool name="config_enable_vis1">true</bool>
+    <bool name="config_enable_vis2">true</bool>
+    <bool name="config_enable_vis3">true</bool>
+    <bool name="config_enable_vis4">true</bool>
+    <bool name="config_enable_vis5">true</bool>
+
+</resources>
+
diff --git a/res/values/cube.xml b/res/values/cube.xml
index 71d97f3..fe7afaa 100644
--- a/res/values/cube.xml
+++ b/res/values/cube.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 /*
-* Copyright (C) 4008 The Android Open Source Project
+* Copyright (C) 2008 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.
@@ -26,6 +26,7 @@
     <string name="wallpaper_vis4">VU meter</string>
     <string name="wallpaper_vis5">Many</string>
 
+
     <!-- x,y,z tuples for the points defining the object -->
     <!-- stored as strings for easier human readability -->
     <string-array name="points" translatable="false">
diff --git a/src/com/android/musicvis/GenericWaveRS.java b/src/com/android/musicvis/GenericWaveRS.java
index 60b9481..f34a4c0 100644
--- a/src/com/android/musicvis/GenericWaveRS.java
+++ b/src/com/android/musicvis/GenericWaveRS.java
@@ -22,15 +22,8 @@
 
 import android.os.Handler;
 import android.os.SystemClock;
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.Primitive;
-import android.renderscript.ProgramFragment;
-import android.renderscript.ProgramVertex;
-import android.renderscript.Sampler;
-import android.renderscript.ScriptC;
-import android.renderscript.SimpleMesh;
-import android.renderscript.Type;
+import android.renderscript.Mesh.Primitive;
+import android.renderscript.*;
 import android.renderscript.Element.Builder;
 import android.util.Log;
 
@@ -54,10 +47,12 @@
         public int width;
     }
     protected WorldState mWorldState = new WorldState();
-    private Type mStateType;
-    protected Allocation mState;
 
-    private SimpleMesh mCubeMesh;
+    ScriptC_waveform mScript;
+
+    private ScriptField_Vertex mVertexBuffer;
+
+    private Mesh mCubeMesh;
 
     protected Allocation mPointAlloc;
     // 1024 lines, with 4 points per line (2 space, 2 texture) each consisting of x and y,
@@ -69,7 +64,7 @@
     private short [] mIndexData = new short[1024*2];
 
     private ProgramVertex mPVBackground;
-    private ProgramVertex.MatrixAllocation mPVAlloc;
+    private ProgramVertexFixedFunction.Constants mPVAlloc;
 
     protected AudioCapture mAudioCapture = null;
     protected int [] mVizData = new int[1024];
@@ -106,140 +101,100 @@
         super.resize(width, height);
         mWorldState.width = width;
         if (mPVAlloc != null) {
-            mPVAlloc.setupProjectionNormalized(mWidth, mHeight);
+            Matrix4f proj = new Matrix4f();
+            proj.loadProjectionNormalized(mWidth, mHeight);
+            mPVAlloc.setProjection(proj);
         }
     }
 
     @Override
     protected ScriptC createScript() {
 
-        // Create a renderscript type from a java class. The specified name doesn't
-        // really matter; the name by which we refer to the object in RenderScript
-        // will be specified later.
-        mStateType = Type.createFromClass(mRS, WorldState.class, 1, "WorldState");
-        // Create an allocation from the type we just created.
-        mState = Allocation.createTyped(mRS, mStateType);
+        mScript = new ScriptC_waveform(mRS, mResources, R.raw.waveform);
+
         // set our java object as the data for the renderscript allocation
         mWorldState.yRotation = 0.0f;
         mWorldState.width = mWidth;
-        mState.data(mWorldState);
+        updateWorldState();
 
-        /*
-         *  Now put our model in to a form that renderscript can work with:
-         *  - create a buffer of floats that are the coordinates for the points that define the cube
-         *  - create a buffer of integers that are the indices of the points that form lines
-         *  - combine the two in to a mesh
-         */
+        //  Now put our model in to a form that renderscript can work with:
+        //  - create a buffer of floats that are the coordinates for the points that define the cube
+        //  - create a buffer of integers that are the indices of the points that form lines
+        //  - combine the two in to a mesh
 
         // First set up the coordinate system and such
-        ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null);
+        ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
         mPVBackground = pvb.create();
-        mPVBackground.setName("PVBackground");
-        mPVAlloc = new ProgramVertex.MatrixAllocation(mRS);
-        mPVBackground.bindAllocation(mPVAlloc);
-        mPVAlloc.setupProjectionNormalized(mWidth, mHeight);
+        mPVAlloc = new ProgramVertexFixedFunction.Constants(mRS);
+        ((ProgramVertexFixedFunction)mPVBackground).bindConstants(mPVAlloc);
+        Matrix4f proj = new Matrix4f();
+        proj.loadProjectionNormalized(mWidth, mHeight);
+        mPVAlloc.setProjection(proj);
+
+        mScript.set_gPVBackground(mPVBackground);
+
+        mVertexBuffer = new ScriptField_Vertex(mRS, mPointData.length / 4);
 
         // Start creating the mesh
-        final SimpleMesh.Builder meshBuilder = new SimpleMesh.Builder(mRS);
-
-        // Create the Element for the points
-        Builder elementBuilder = new Builder(mRS);
-        elementBuilder.add(Element.ATTRIB_POSITION_2(mRS), "position");
-        elementBuilder.add(Element.ATTRIB_TEXTURE_2(mRS), "texture");
-        final Element vertexElement = elementBuilder.create();
-        final int vertexSlot = meshBuilder.addVertexType(vertexElement, mPointData.length / 4);
-        // Specify the type and number of indices we need. We'll allocate them later.
-        meshBuilder.setIndexType(Element.INDEX_16(mRS), mIndexData.length);
+        final Mesh.AllocationBuilder meshBuilder = new Mesh.AllocationBuilder(mRS);
+        meshBuilder.addVertexAllocation(mVertexBuffer.getAllocation());
+        // Create the Allocation for the indices
+        mLineIdxAlloc = Allocation.createSized(mRS, Element.U16(mRS), mIndexData.length,
+                                               Allocation.USAGE_GRAPHICS_VERTEX |
+                                               Allocation.USAGE_SCRIPT);
         // This will be a line mesh
-        meshBuilder.setPrimitive(Primitive.LINE);
+        meshBuilder.addIndexSetAllocation(mLineIdxAlloc, Primitive.LINE);
 
         // Create the Allocation for the vertices
         mCubeMesh = meshBuilder.create();
-        mCubeMesh.setName("CubeMesh");
-        mPointAlloc = mCubeMesh.createVertexAllocation(vertexSlot);
-        mPointAlloc.setName("PointBuffer");
 
-        // Create the Allocation for the indices
-        mLineIdxAlloc = mCubeMesh.createIndexAllocation();
+        mPointAlloc = mVertexBuffer.getAllocation();
 
-        // Bind the allocations to the mesh
-        mCubeMesh.bindVertexAllocation(mPointAlloc, 0);
-        mCubeMesh.bindIndexAllocation(mLineIdxAlloc);
+        mScript.bind_gPoints(mVertexBuffer);
+        mScript.set_gPointBuffer(mPointAlloc);
+        mScript.set_gCubeMesh(mCubeMesh);
 
-        /*
-         *  put the vertex and index data in their respective buffers
-         */
+        //  put the vertex and index data in their respective buffers
         updateWave();
         for(int i = 0; i < mIndexData.length; i ++) {
             mIndexData[i] = (short) i;
         }
 
-        /*
-         *  upload the vertex and index data
-         */
-        mPointAlloc.data(mPointData);
-        mPointAlloc.uploadToBufferObject();
-        mLineIdxAlloc.data(mIndexData);
-        mLineIdxAlloc.uploadToBufferObject();
+        //  upload the vertex and index data
+        mPointAlloc.copyFromUnchecked(mPointData);
+        mLineIdxAlloc.copyFrom(mIndexData);
+        mLineIdxAlloc.syncAll(Allocation.USAGE_SCRIPT);
 
-        /*
-         * load the texture
-         */
-        mTexture = Allocation.createFromBitmapResourceBoxed(mRS, mResources, mTexId, RGB_565(mRS), false);
-        mTexture.setName("Tlinetexture");
-        mTexture.uploadToTexture(0);
+        // load the texture
+        mTexture = Allocation.createFromBitmapResource(mRS, mResources, mTexId);
+
+        mScript.set_gTlinetexture(mTexture);
 
         /*
          * create a program fragment to use the texture
          */
         Sampler.Builder samplerBuilder = new Sampler.Builder(mRS);
-        samplerBuilder.setMin(LINEAR);
-        samplerBuilder.setMag(LINEAR);
+        samplerBuilder.setMinification(LINEAR);
+        samplerBuilder.setMagnification(LINEAR);
         samplerBuilder.setWrapS(WRAP);
         samplerBuilder.setWrapT(WRAP);
         mSampler = samplerBuilder.create();
 
-        ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS);
-        builder.setTexture(ProgramFragment.Builder.EnvMode.REPLACE,
-                           ProgramFragment.Builder.Format.RGBA, 0);
+        ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS);
+        builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
+                           ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
         mPfBackground = builder.create();
-        mPfBackground.setName("PFBackground");
         mPfBackground.bindSampler(mSampler, 0);
 
-        // Time to create the script
-        ScriptC.Builder sb = new ScriptC.Builder(mRS);
-        // Specify the name by which to refer to the WorldState object in the
-        // renderscript.
-        sb.setType(mStateType, "State", RSID_STATE);
-        sb.setType(mCubeMesh.getVertexType(0), "Points", RSID_POINTS);
-        // this crashes when uncommented
-        //sb.setType(mCubeMesh.getIndexType(), "Lines", RSID_LINES);
-        sb.setScript(mResources, R.raw.waveform);
-        sb.setRoot(true);
+        mScript.set_gPFBackground(mPfBackground);
 
-        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(mPointAlloc, RSID_POINTS);
-        script.bindAllocation(mLineIdxAlloc, RSID_LINES);
-        script.bindAllocation(mPVAlloc.mAlloc, RSID_PROGRAMVERTEX);
-
-        return script;
+        return mScript;
     }
 
     @Override
-    public void setOffset(float xOffset, float yOffset,
-            float xStep, float yStep, int xPixels, int yPixels) {
-        // update our state, then push it to the renderscript
-
-        if (xStep <= 0.0f) {
-            xStep = xOffset / 2; // originator didn't set step size, assume we're halfway
-        }
-        // rotate 180 degrees per screen
-        mWorldState.yRotation = xStep == 0.f ? 0.f : (xOffset / xStep) * 180;
-        mState.data(mWorldState);
+    public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
+        mWorldState.yRotation = (xOffset * 4) * 180;
+        updateWorldState();
     }
 
     @Override
@@ -274,6 +229,13 @@
         mHandler.postDelayed(mDrawCube, 20);
         update();
         mWorldState.waveCounter++;
-        mState.data(mWorldState);
+        updateWorldState();
+    }
+
+    protected void updateWorldState() {
+        mScript.set_gYRotation(mWorldState.yRotation);
+        mScript.set_gIdle(mWorldState.idle);
+        mScript.set_gWaveCounter(mWorldState.waveCounter);
+        mScript.set_gWidth(mWorldState.width);
     }
 }
diff --git a/src/com/android/musicvis/RenderScriptScene.java b/src/com/android/musicvis/RenderScriptScene.java
index be5640d..d5456b4 100644
--- a/src/com/android/musicvis/RenderScriptScene.java
+++ b/src/com/android/musicvis/RenderScriptScene.java
@@ -18,9 +18,10 @@
 package com.android.musicvis;
 
 import android.content.res.Resources;
+import android.os.Bundle;
 import android.renderscript.RenderScriptGL;
 import android.renderscript.ScriptC;
-import android.view.MotionEvent;
+//import android.view.MotionEvent;
 
 public abstract class RenderScriptScene {
     protected int mWidth;
@@ -69,11 +70,11 @@
     protected abstract ScriptC createScript();
 
     public void stop() {
-        mRS.contextBindRootScript(null);
+        mRS.bindRootScript(null);
     }
 
     public void start() {
-        mRS.contextBindRootScript(mScript);
+        mRS.bindRootScript(mScript);
     }
 
     public void resize(int width, int height) {
@@ -82,10 +83,12 @@
     }
 
     @SuppressWarnings({"UnusedDeclaration"})
-    public void setOffset(float xOffset, float yOffset,
-            float xStep, float yStep, int xPixels, int yPixels) {
-    }
-    public void onTouchEvent(MotionEvent event) {
+    public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
     }
 
+    @SuppressWarnings({"UnusedDeclaration"})
+    public Bundle onCommand(String action, int x, int y, int z, Bundle extras,
+            boolean resultRequested) {
+        return null;
+    }
 }
diff --git a/src/com/android/musicvis/RenderScriptWallpaper.java b/src/com/android/musicvis/RenderScriptWallpaper.java
index 77f3ecd..fa6303f 100644
--- a/src/com/android/musicvis/RenderScriptWallpaper.java
+++ b/src/com/android/musicvis/RenderScriptWallpaper.java
@@ -17,9 +17,12 @@
 
 package com.android.musicvis;
 
+
 import android.service.wallpaper.WallpaperService;
+import android.os.Bundle;
 import android.renderscript.RenderScriptGL;
 import android.renderscript.RenderScript;
+import android.util.Log;
 import android.view.MotionEvent;
 import android.view.SurfaceHolder;
 import android.view.Surface;
@@ -38,7 +41,7 @@
         @Override
         public void onCreate(SurfaceHolder surfaceHolder) {
             super.onCreate(surfaceHolder);
-            setTouchEventsEnabled(true);
+            setTouchEventsEnabled(false);
             surfaceHolder.setSizeFromLayout();
         }
 
@@ -75,7 +78,7 @@
         public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
             super.onSurfaceChanged(holder, format, width, height);
             if (mRs != null) {
-                mRs.contextSetSurface(width, height, holder.getSurface());
+                mRs.setSurface(holder, width, height);
             }
             if (mRenderer == null) {
                 mRenderer = createScene(width, height);
@@ -86,31 +89,24 @@
             }
         }
 
-        @Override
+        /*@Override
         public void onTouchEvent(MotionEvent event) {
-            if (mRenderer != null) {
-                mRenderer.onTouchEvent(event);
-            }
-        }
+            mRenderer.onTouchEvent(event);
+        }*/
 
         @Override
         public void onOffsetsChanged(float xOffset, float yOffset,
                 float xStep, float yStep, int xPixels, int yPixels) {
-            if (mRenderer != null) {
-                mRenderer.setOffset(xOffset, yOffset, xStep, yStep, xPixels, yPixels);
-            }
+            mRenderer.setOffset(xOffset, yOffset, xPixels, yPixels);
         }
 
         @Override
         public void onSurfaceCreated(SurfaceHolder holder) {
             super.onSurfaceCreated(holder);
 
-            Surface surface = null;
-            while (surface == null) {
-                surface = holder.getSurface();
-            }
-            mRs = new RenderScriptGL(false, false);
-            mRs.contextSetPriority(RenderScript.Priority.LOW);
+            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
+            mRs = new RenderScriptGL(RenderScriptWallpaper.this, sc);
+            mRs.setPriority(RenderScript.Priority.LOW);
         }
 
         @Override
@@ -118,5 +114,12 @@
             super.onSurfaceDestroyed(holder);
             destroyRenderer();
         }
+
+        @Override
+        public Bundle onCommand(String action, int x, int y, int z,
+                Bundle extras, boolean resultRequested) {
+            return mRenderer.onCommand(action, x, y, z, extras, resultRequested);
+        }
+
     }
 }
diff --git a/src/com/android/musicvis/vis2/Visualization2RS.java b/src/com/android/musicvis/vis2/Visualization2RS.java
index 7dbe4af..b27ee91 100644
--- a/src/com/android/musicvis/vis2/Visualization2RS.java
+++ b/src/com/android/musicvis/vis2/Visualization2RS.java
@@ -57,7 +57,8 @@
         if (len == 0) {
             if (mWorldState.idle == 0) {
                 mWorldState.idle = 1;
-                mState.data(mWorldState);
+                //mState.data(mWorldState);
+                updateWorldState();
             }
             return;
         }
@@ -67,7 +68,8 @@
 
         if (mWorldState.idle != 0) {
             mWorldState.idle = 0;
-            mState.data(mWorldState);
+            //mState.data(mWorldState);
+            updateWorldState();
         }
         // TODO: might be more efficient to push this in to renderscript
         for(int i = 0; i < len; i++) {
@@ -75,7 +77,7 @@
             mPointData[i*8+1] = amp;
             mPointData[i*8+5] = -amp;
         }
-        mPointAlloc.data(mPointData);
+        mPointAlloc.copyFromUnchecked(mPointData);
     }
 
 }
diff --git a/src/com/android/musicvis/vis3/Visualization3RS.java b/src/com/android/musicvis/vis3/Visualization3RS.java
index f19ba36..27ea910 100644
--- a/src/com/android/musicvis/vis3/Visualization3RS.java
+++ b/src/com/android/musicvis/vis3/Visualization3RS.java
@@ -26,10 +26,9 @@
 import android.os.Handler;
 import android.renderscript.Allocation;
 import android.renderscript.Element;
-import android.renderscript.Primitive;
+import android.renderscript.Mesh.Primitive;
 import android.renderscript.ProgramVertex;
 import android.renderscript.ScriptC;
-import android.renderscript.SimpleMesh;
 import android.renderscript.Type;
 import android.renderscript.Element.Builder;
 import android.util.Log;
@@ -41,20 +40,17 @@
 
     private short [] mAnalyzer = new short[512];
 
+    float lastOffset;
+
     Visualization3RS(int width, int height) {
         super(width, height, R.drawable.ice);
+        lastOffset = 0;
     }
 
     @Override
-    public void setOffset(float xOffset, float yOffset,
-            float xStep, float yStep, int xPixels, int yPixels) {
-        // update our state, then push it to the renderscript
-        if (xStep <= 0.0f) {
-            xStep = xOffset / 2; // originator didn't set step size, assume we're halfway
-        }
-        // rotate 360 degrees per screen
-        mWorldState.yRotation = xStep == 0.f ? 0.f : (xOffset / xStep) * 360;
-        mState.data(mWorldState);
+    public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
+        mWorldState.yRotation = (xOffset * 4) * 360;
+        updateWorldState();
     }
 
     @Override
@@ -85,7 +81,7 @@
         if (len == 0) {
             if (mWorldState.idle == 0) {
                 mWorldState.idle = 1;
-                mState.data(mWorldState);
+                updateWorldState();
             }
             return;
         }
@@ -94,7 +90,7 @@
 
         if (mWorldState.idle != 0) {
             mWorldState.idle = 0;
-            mState.data(mWorldState);
+            updateWorldState();
         }
 
         for (int i = 0; i < len; i++) {
@@ -110,8 +106,8 @@
 
         // distribute the data over mWidth samples in the middle of the mPointData array
         final int outlen = mPointData.length / 8;
-        final int width = mWidth;
-        final int skip = (outlen - mWidth) / 2;
+        final int width = mWidth > outlen ? outlen : mWidth;
+        final int skip = (outlen - width) / 2;
 
         int srcidx = 0;
         int cnt = 0;
@@ -126,7 +122,7 @@
                 cnt -= width;
             }
         }
-        mPointAlloc.data(mPointData);
+        mPointAlloc.copyFromUnchecked(mPointData);
     }
 
 }
diff --git a/src/com/android/musicvis/vis4/Visualization4RS.java b/src/com/android/musicvis/vis4/Visualization4RS.java
index 88a44d3..94c794c 100644
--- a/src/com/android/musicvis/vis4/Visualization4RS.java
+++ b/src/com/android/musicvis/vis4/Visualization4RS.java
@@ -25,14 +25,7 @@
 import com.android.musicvis.AudioCapture;
 
 import android.os.Handler;
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.ProgramFragment;
-import android.renderscript.ProgramStore;
-import android.renderscript.ProgramVertex;
-import android.renderscript.Sampler;
-import android.renderscript.ScriptC;
-import android.renderscript.Type;
+import android.renderscript.*;
 import android.renderscript.ProgramStore.BlendDstFunc;
 import android.renderscript.ProgramStore.BlendSrcFunc;
 
@@ -60,8 +53,8 @@
         public int   mPeak;
     }
     WorldState mWorldState = new WorldState();
-    private Type mStateType;
-    private Allocation mState;
+
+    ScriptC_vu mScript;
 
     private ProgramStore mPfsBackground;
     private ProgramFragment mPfBackground;
@@ -69,7 +62,7 @@
     private Allocation[] mTextures;
 
     private ProgramVertex mPVBackground;
-    private ProgramVertex.MatrixAllocation mPVAlloc;
+    private ProgramVertexFixedFunction.Constants mPVAlloc;
 
     private AudioCapture mAudioCapture = null;
     private int [] mVizData = new int[1024];
@@ -90,92 +83,76 @@
     public void resize(int width, int height) {
         super.resize(width, height);
         if (mPVAlloc != null) {
-            mPVAlloc.setupProjectionNormalized(width, height);
+            Matrix4f proj = new Matrix4f();
+            proj.loadProjectionNormalized(width, height);
+            mPVAlloc.setProjection(proj);
         }
     }
 
     @Override
     protected ScriptC createScript() {
 
-        // Create a renderscript type from a java class. The specified name doesn't
-        // really matter; the name by which we refer to the object in RenderScript
-        // will be specified later.
-        mStateType = Type.createFromClass(mRS, WorldState.class, 1, "WorldState");
-        // Create an allocation from the type we just created.
-        mState = Allocation.createTyped(mRS, mStateType);
+        mScript = new ScriptC_vu(mRS, mResources, R.raw.vu);
 
         // First set up the coordinate system and such
-        ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null);
+        ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
         mPVBackground = pvb.create();
-        mPVBackground.setName("PVBackground");
-        mPVAlloc = new ProgramVertex.MatrixAllocation(mRS);
-        mPVBackground.bindAllocation(mPVAlloc);
-        mPVAlloc.setupProjectionNormalized(mWidth, mHeight);
+        mPVAlloc = new ProgramVertexFixedFunction.Constants(mRS);
+        ((ProgramVertexFixedFunction)mPVBackground).bindConstants(mPVAlloc);
+        Matrix4f proj = new Matrix4f();
+        proj.loadProjectionNormalized(mWidth, mHeight);
+        mPVAlloc.setProjection(proj);
+
+        mScript.set_gPVBackground(mPVBackground);
 
         updateWave();
 
         mTextures = new Allocation[6];
-        mTextures[0] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.background, Element.RGBA_8888(mRS), false);
-        mTextures[0].setName("Tvumeter_background");
-        mTextures[1] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.frame, Element.RGBA_8888(mRS), false);
-        mTextures[1].setName("Tvumeter_frame");
-        mTextures[2] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.peak_on, Element.RGBA_8888(mRS), false);
-        mTextures[2].setName("Tvumeter_peak_on");
-        mTextures[3] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.peak_off, Element.RGBA_8888(mRS), false);
-        mTextures[3].setName("Tvumeter_peak_off");
-        mTextures[4] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.needle, Element.RGBA_8888(mRS), false);
-        mTextures[4].setName("Tvumeter_needle");
-        mTextures[5] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.black, Element.RGB_565(mRS), false);
-        mTextures[5].setName("Tvumeter_black");
-
-        final int count = mTextures.length;
-        for (int i = 0; i < count; i++) {
-            mTextures[i].uploadToTexture(0);
-        }
+        mTextures[0] = Allocation.createFromBitmapResource(mRS, mResources, R.drawable.background);
+        mScript.set_gTvumeter_background(mTextures[0]);
+        mTextures[1] = Allocation.createFromBitmapResource(mRS, mResources, R.drawable.frame);
+        mScript.set_gTvumeter_frame(mTextures[1]);
+        mTextures[2] = Allocation.createFromBitmapResource(mRS, mResources, R.drawable.peak_on);
+        mScript.set_gTvumeter_peak_on(mTextures[2]);
+        mTextures[3] = Allocation.createFromBitmapResource(mRS, mResources, R.drawable.peak_off);
+        mScript.set_gTvumeter_peak_off(mTextures[3]);
+        mTextures[4] = Allocation.createFromBitmapResource(mRS, mResources, R.drawable.needle);
+        mScript.set_gTvumeter_needle(mTextures[4]);
+        mTextures[5] = Allocation.createFromBitmapResource(mRS, mResources, R.drawable.black);
+        mScript.set_gTvumeter_black(mTextures[5]);
 
         Sampler.Builder samplerBuilder = new Sampler.Builder(mRS);
-        samplerBuilder.setMin(LINEAR);
-        samplerBuilder.setMag(LINEAR);
+        samplerBuilder.setMinification(LINEAR);
+        samplerBuilder.setMagnification(LINEAR);
         samplerBuilder.setWrapS(WRAP);
         samplerBuilder.setWrapT(WRAP);
         mSampler = samplerBuilder.create();
 
         {
-            ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS);
-            builder.setTexture(ProgramFragment.Builder.EnvMode.REPLACE,
-                               ProgramFragment.Builder.Format.RGBA, 0);
+            ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS);
+            builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
+                               ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
             mPfBackground = builder.create();
-            mPfBackground.setName("PFBackground");
             mPfBackground.bindSampler(mSampler, 0);
+
+            mScript.set_gPFBackground(mPfBackground);
         }
 
         {
-            ProgramStore.Builder builder = new ProgramStore.Builder(mRS, null, null);
+            ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
             builder.setDepthFunc(ALWAYS);
             //builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
             builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
-            builder.setDitherEnable(true); // without dithering there is severe banding
-            builder.setDepthMask(false);
+            builder.setDitherEnabled(true); // without dithering there is severe banding
+            builder.setDepthMaskEnabled(false);
             mPfsBackground = builder.create();
-            mPfsBackground.setName("PFSBackground");
+
+            mScript.set_gPFSBackground(mPfsBackground);
         }
 
-        // Time to create the script
-        ScriptC.Builder sb = new ScriptC.Builder(mRS);
-        // Specify the name by which to refer to the WorldState object in the
-        // renderscript.
-        sb.setType(mStateType, "State", RSID_STATE);
-        sb.setScript(mResources, R.raw.vu);
-        sb.setRoot(true);
+        mScript.setTimeZone(TimeZone.getDefault().getID());
 
-        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(mPVAlloc.mAlloc, RSID_PROGRAMVERTEX);
-
-        return script;
+        return mScript;
     }
 
     @Override
@@ -265,6 +242,7 @@
         }
 
         mWorldState.mAngle = 131f - (mNeedlePos / 410f); // ~80 degree range
-        mState.data(mWorldState);
+        mScript.set_gAngle(mWorldState.mAngle);
+        mScript.set_gPeak(mWorldState.mPeak);
     }
 }
diff --git a/src/com/android/musicvis/vis4/vu.rs b/src/com/android/musicvis/vis4/vu.rs
new file mode 100644
index 0000000..816c846
--- /dev/null
+++ b/src/com/android/musicvis/vis4/vu.rs
@@ -0,0 +1,128 @@
+// 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 rs java_package_name(com.android.musicvis.vis4)
+
+#include "rs_graphics.rsh"
+
+// State
+float gAngle;
+int   gPeak;
+
+rs_program_vertex gPVBackground;
+rs_program_fragment gPFBackground;
+
+rs_allocation gTvumeter_background;
+rs_allocation gTvumeter_peak_on;
+rs_allocation gTvumeter_peak_off;
+rs_allocation gTvumeter_needle;
+rs_allocation gTvumeter_black;
+rs_allocation gTvumeter_frame;
+
+rs_program_store gPFSBackground;
+
+#define RSID_POINTS 1
+
+int root(int launchID) {
+    rsgClearColor(0.f, 0.f, 0.f, 1.f);
+
+    // Draw the visualizer.
+    rsgBindProgramVertex(gPVBackground);
+    rsgBindProgramFragment(gPFBackground);
+    rsgBindProgramStore(gPFSBackground);
+
+    rs_matrix4x4 mat1;
+    float scale = 0.0041;
+    rsMatrixLoadTranslate(&mat1, 0.f, -90.0f * scale, 0.f);
+    rsMatrixScale(&mat1, scale, scale, scale);
+    rsgProgramVertexLoadModelMatrix(&mat1);
+
+    // draw the background image (416x233)
+    rsgBindTexture(gPFBackground, 0, gTvumeter_background);
+    rsgDrawQuadTexCoords(
+            -208.0f, -33.0f, 0.0f,        // space
+                0.0f, 1.0f,               // texture
+            208, -33.0f, 0.0f,            // space
+                1.0f, 1.0f,               // texture
+            208, 200.0f, 0.0f,            // space
+                1.0f, 0.0f,               // texture
+            -208.0f, 200.0f, 0.0f,        // space
+                0.0f, 0.0f);              // texture
+
+    // draw the peak indicator light (56x58)
+    if (gPeak > 0) {
+        rsgBindTexture(gPFBackground, 0, gTvumeter_peak_on);
+    } else {
+        rsgBindTexture(gPFBackground, 0, gTvumeter_peak_off);
+    }
+    rsgDrawQuadTexCoords(
+            140.0f, 70.0f, -1.0f,         // space
+                0.0, 1.0f,                // texture
+            196, 70.0f, -1.0f,            // space
+                1.0f, 1.0f,               // texture
+            196, 128.0f, -1.0f,           // space
+                1.0f, 0.0f,               // texture
+            140.0f, 128.0f, -1.0f,        // space
+                0.0f, 0.0f);              // texture
+
+
+
+    // Draw the needle (88x262, center of rotation at 44,217 from top left)
+
+    // set matrix so point of rotation becomes origin
+    rsMatrixLoadTranslate(&mat1, 0.f, -147.0f * scale, 0.f);
+    rsMatrixRotate(&mat1, gAngle - 90.f, 0.f, 0.f, 1.f);
+    rsMatrixScale(&mat1, scale, scale, scale);
+    rsgProgramVertexLoadModelMatrix(&mat1);
+    rsgBindTexture(gPFBackground, 0, gTvumeter_needle);
+    rsgDrawQuadTexCoords(
+            -44.0f, -102.0f+57.f, 0.0f,    // space
+                0.0f, 1.0f,                // texture
+            44.0f, -102.0f+57.f, 0.0f,     // space
+                1.0f, 1.0f,                // texture
+            44.0f, 160.0f+57.f, 0.0f,      // space
+                1.0f, 0.0f,                // texture
+            -44.0f, 160.0f+57.f, 0.0f,     // space
+                0.0f, 0.0f);               // texture
+
+
+    // restore matrix
+    rsMatrixLoadTranslate(&mat1, 0.f, -90.0f * scale, 0.f);
+    rsMatrixScale(&mat1, scale, scale, scale);
+    rsgProgramVertexLoadModelMatrix(&mat1);
+
+    // erase the part of the needle we don't want to show
+    rsgBindTexture(gPFBackground, 0, gTvumeter_black);
+    rsgDrawQuad(-100.f, -55.f, 0.f,
+             -100.f, -105.f, 0.f,
+              100.f, -105.f, 0.f,
+              100.f, -55.f, 0.f);
+
+
+    // draw the frame (472x290)
+    rsgBindTexture(gPFBackground, 0, gTvumeter_frame);
+    rsgDrawQuadTexCoords(
+            -236.0f, -60.0f, 0.0f,           // space
+                0.0f, 1.0f,                  // texture
+            236, -60.0f, 0.0f,               // space
+                1.0f, 1.0f,                  // texture
+            236, 230.0f, 0.0f,               // space
+                1.0f, 0.0f,                  // texture
+            -236.0f, 230.0f, 0.0f,           // space
+                0.0f, 0.0f);                 // texture
+
+    return 1;
+}
diff --git a/src/com/android/musicvis/vis5/Visualization5RS.java b/src/com/android/musicvis/vis5/Visualization5RS.java
index fed8017..e0ef87c 100644
--- a/src/com/android/musicvis/vis5/Visualization5RS.java
+++ b/src/com/android/musicvis/vis5/Visualization5RS.java
@@ -18,19 +18,11 @@
 
 import com.android.musicvis.R;
 import com.android.musicvis.RenderScriptScene;
+import com.android.musicvis.ScriptField_Vertex;
 import com.android.musicvis.AudioCapture;
 
 import android.os.Handler;
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.Primitive;
-import android.renderscript.ProgramFragment;
-import android.renderscript.ProgramStore;
-import android.renderscript.ProgramVertex;
-import android.renderscript.Sampler;
-import android.renderscript.ScriptC;
-import android.renderscript.SimpleMesh;
-import android.renderscript.Type;
+import android.renderscript.*;
 import android.renderscript.Element.Builder;
 import android.renderscript.ProgramStore.BlendDstFunc;
 import android.renderscript.ProgramStore.BlendSrcFunc;
@@ -65,20 +57,22 @@
         public int   mWaveCounter;
     }
     WorldState mWorldState = new WorldState();
-    private Type mStateType;
-    private Allocation mState;
+
+    ScriptC_many mScript;
+    private com.android.musicvis.vis5.ScriptField_Vertex mVertexBuffer;
 
     private ProgramStore mPfsBackground;
     private ProgramFragment mPfBackgroundMip;
     private ProgramFragment mPfBackgroundNoMip;
+    private ProgramRaster mPr;
     private Sampler mSamplerMip;
     private Sampler mSamplerNoMip;
     private Allocation[] mTextures;
 
     private ProgramVertex mPVBackground;
-    private ProgramVertex.MatrixAllocation mPVAlloc;
+    private ProgramVertexFixedFunction.Constants mPVAlloc;
 
-    private SimpleMesh mCubeMesh;
+    private Mesh mCubeMesh;
 
     protected Allocation mPointAlloc;
     // 256 lines, with 4 points per line (2 space, 2 texture) each consisting of x and y,
@@ -120,12 +114,14 @@
     public void resize(int width, int height) {
         super.resize(width, height);
         if (mPVAlloc != null) {
-            mPVAlloc.setupProjectionNormalized(width, height);
+            Matrix4f proj = new Matrix4f();
+            proj.loadProjectionNormalized(width, height);
+            mPVAlloc.setProjection(proj);
         }
         mWorldState.mTilt = -20;
     }
 
-    @Override
+    /*@Override
     public void onTouchEvent(MotionEvent event) {
         switch(event.getAction()) {
             case MotionEvent.ACTION_DOWN:
@@ -143,62 +139,70 @@
                 }
                 mWorldState.mTilt = dy;
                 mState.data(mWorldState);
+                //updateWorldState();
         }
-    }
+    }*/
 
     @Override
-    public void setOffset(float xOffset, float yOffset,
-            float xStep, float yStep, int xPixels, int yPixels) {
+    public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
         // update our state, then push it to the renderscript
         mWorldState.mRotate = (xOffset - 0.5f) * 90;
-        mState.data(mWorldState);
+        updateWorldState();
     }
 
     @Override
     protected ScriptC createScript() {
-
-        // Create a renderscript type from a java class. The specified name doesn't
-        // really matter; the name by which we refer to the object in RenderScript
-        // will be specified later.
-        mStateType = Type.createFromClass(mRS, WorldState.class, 1, "WorldState");
-        // Create an allocation from the type we just created.
-        mState = Allocation.createTyped(mRS, mStateType);
+        mScript = new ScriptC_many(mRS, mResources, R.raw.many);
 
         // First set up the coordinate system and such
-        ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null);
+        ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
         mPVBackground = pvb.create();
-        mPVBackground.setName("PVBackground");
-        mPVAlloc = new ProgramVertex.MatrixAllocation(mRS);
-        mPVBackground.bindAllocation(mPVAlloc);
-        mPVAlloc.setupProjectionNormalized(mWidth, mHeight);
+        mPVAlloc = new ProgramVertexFixedFunction.Constants(mRS);
+        ((ProgramVertexFixedFunction)mPVBackground).bindConstants(mPVAlloc);
+        Matrix4f proj = new Matrix4f();
+        proj.loadProjectionNormalized(mWidth, mHeight);
+        mPVAlloc.setProjection(proj);
+
+        mScript.set_gPVBackground(mPVBackground);
 
         mTextures = new Allocation[8];
-        mTextures[0] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.background, Element.RGBA_8888(mRS), true);
-        mTextures[0].setName("Tvumeter_background");
-        mTextures[1] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.frame, Element.RGBA_8888(mRS), true);
-        mTextures[1].setName("Tvumeter_frame");
-        mTextures[2] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.peak_on, Element.RGBA_8888(mRS), true);
-        mTextures[2].setName("Tvumeter_peak_on");
-        mTextures[3] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.peak_off, Element.RGBA_8888(mRS), true);
-        mTextures[3].setName("Tvumeter_peak_off");
-        mTextures[4] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.needle, Element.RGBA_8888(mRS), true);
-        mTextures[4].setName("Tvumeter_needle");
-        mTextures[5] = Allocation.createFromBitmapResourceBoxed(mRS, mResources, R.drawable.black, Element.RGB_565(mRS), false);
-        mTextures[5].setName("Tvumeter_black");
-        mTextures[6] = Allocation.createFromBitmapResource(mRS, mResources, R.drawable.albumart, Element.RGBA_8888(mRS), true);
-        mTextures[6].setName("Tvumeter_album");
-        mTextures[7] = Allocation.createFromBitmapResource(mRS, mResources, R.drawable.fire, Element.RGB_565(mRS), false);
-        mTextures[7].setName("Tlinetexture");
-
-        final int count = mTextures.length;
-        for (int i = 0; i < count; i++) {
-            mTextures[i].uploadToTexture(0);
-        }
+        mTextures[0] = Allocation.createFromBitmapResource(mRS, mResources, R.drawable.background,
+                                                           Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+                                                           Allocation.USAGE_GRAPHICS_TEXTURE);
+        mScript.set_gTvumeter_background(mTextures[0]);
+        mTextures[1] = Allocation.createFromBitmapResource(mRS, mResources, R.drawable.frame,
+                                                           Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+                                                           Allocation.USAGE_GRAPHICS_TEXTURE);
+        mScript.set_gTvumeter_frame(mTextures[1]);
+        mTextures[2] = Allocation.createFromBitmapResource(mRS, mResources, R.drawable.peak_on,
+                                                           Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+                                                           Allocation.USAGE_GRAPHICS_TEXTURE);
+        mScript.set_gTvumeter_peak_on(mTextures[2]);
+        mTextures[3] = Allocation.createFromBitmapResource(mRS, mResources, R.drawable.peak_off,
+                                                           Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+                                                           Allocation.USAGE_GRAPHICS_TEXTURE);
+        mScript.set_gTvumeter_peak_off(mTextures[3]);
+        mTextures[4] = Allocation.createFromBitmapResource(mRS, mResources, R.drawable.needle,
+                                                           Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+                                                           Allocation.USAGE_GRAPHICS_TEXTURE);
+        mScript.set_gTvumeter_needle(mTextures[4]);
+        mTextures[5] = Allocation.createFromBitmapResource(mRS, mResources, R.drawable.black,
+                                                           Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+                                                           Allocation.USAGE_GRAPHICS_TEXTURE);
+        mScript.set_gTvumeter_black(mTextures[5]);
+        mTextures[6] = Allocation.createFromBitmapResource(mRS, mResources, R.drawable.albumart,
+                                                           Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+                                                           Allocation.USAGE_GRAPHICS_TEXTURE);
+        mScript.set_gTvumeter_album(mTextures[6]);
+        mTextures[7] = Allocation.createFromBitmapResource(mRS, mResources, R.drawable.fire,
+                                                           Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+                                                           Allocation.USAGE_GRAPHICS_TEXTURE);
+        mScript.set_gTlinetexture(mTextures[7]);
 
         {
             Sampler.Builder builder = new Sampler.Builder(mRS);
-            builder.setMin(Value.LINEAR);
-            builder.setMag(Value.LINEAR);
+            builder.setMinification(Value.LINEAR);
+            builder.setMagnification(Value.LINEAR);
             builder.setWrapS(Value.WRAP);
             builder.setWrapT(Value.WRAP);
             mSamplerNoMip = builder.create();
@@ -206,103 +210,83 @@
 
         {
             Sampler.Builder builder = new Sampler.Builder(mRS);
-            builder.setMin(Value.LINEAR_MIP_LINEAR);
-            builder.setMag(Value.LINEAR);
+            builder.setMinification(Value.LINEAR_MIP_LINEAR);
+            builder.setMagnification(Value.LINEAR);
             builder.setWrapS(Value.WRAP);
             builder.setWrapT(Value.WRAP);
             mSamplerMip = builder.create();
         }
 
         {
-            ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS);
-            builder.setTexture(ProgramFragment.Builder.EnvMode.REPLACE,
-                               ProgramFragment.Builder.Format.RGBA, 0);
+            ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS);
+            builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
+                               ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
             mPfBackgroundNoMip = builder.create();
-            mPfBackgroundNoMip.setName("PFBackgroundNoMip");
             mPfBackgroundNoMip.bindSampler(mSamplerNoMip, 0);
+            mScript.set_gPFBackgroundNoMip(mPfBackgroundNoMip);
         }
 
         {
-            ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS);
-            builder.setTexture(ProgramFragment.Builder.EnvMode.REPLACE,
-                               ProgramFragment.Builder.Format.RGBA, 0);
+            ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS);
+            builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
+                               ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
             mPfBackgroundMip = builder.create();
-            mPfBackgroundMip.setName("PFBackgroundMip");
             mPfBackgroundMip.bindSampler(mSamplerMip, 0);
+            mScript.set_gPFBackgroundMip(mPfBackgroundMip);
         }
 
         {
-            ProgramStore.Builder builder = new ProgramStore.Builder(mRS, null, null);
+            ProgramRaster.Builder builder = new ProgramRaster.Builder(mRS);
+            builder.setCullMode(ProgramRaster.CullMode.NONE);
+            mPr = builder.create();
+            mScript.set_gPR(mPr);
+        }
+
+        {
+            ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
             builder.setDepthFunc(ProgramStore.DepthFunc.EQUAL);
             //builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
             builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
-            builder.setDitherEnable(true); // without dithering there is severe banding
-            builder.setDepthMask(false);
+            builder.setDitherEnabled(true); // without dithering there is severe banding
+            builder.setDepthMaskEnabled(false);
             mPfsBackground = builder.create();
-            mPfsBackground.setName("PFSBackground");
+
+            mScript.set_gPFSBackground(mPfsBackground);
         }
 
         // Start creating the mesh
-        final SimpleMesh.Builder meshBuilder = new SimpleMesh.Builder(mRS);
+        mVertexBuffer = new com.android.musicvis.vis5.ScriptField_Vertex(mRS, mPointData.length / 4);
 
-        // Create the Element for the points
-        Builder elementBuilder = new Builder(mRS);
-        elementBuilder.add(Element.ATTRIB_POSITION_2(mRS), "position");
-        elementBuilder.add(Element.ATTRIB_TEXTURE_2(mRS), "texture");
-        final Element vertexElement = elementBuilder.create();
-        final int vertexSlot = meshBuilder.addVertexType(vertexElement, mPointData.length / 4);
-        // Specify the type and number of indices we need. We'll allocate them later.
-        meshBuilder.setIndexType(Element.INDEX_16(mRS), mIndexData.length);
+        final Mesh.AllocationBuilder meshBuilder = new Mesh.AllocationBuilder(mRS);
+        meshBuilder.addVertexAllocation(mVertexBuffer.getAllocation());
+        // Create the Allocation for the indices
+        mLineIdxAlloc = Allocation.createSized(mRS, Element.U16(mRS), mIndexData.length,
+                                               Allocation.USAGE_SCRIPT |
+                                               Allocation.USAGE_GRAPHICS_VERTEX);
         // This will be a line mesh
-        meshBuilder.setPrimitive(Primitive.LINE);
+        meshBuilder.addIndexSetAllocation(mLineIdxAlloc, Mesh.Primitive.LINE);
 
         // Create the Allocation for the vertices
         mCubeMesh = meshBuilder.create();
-        mCubeMesh.setName("CubeMesh");
-        mPointAlloc = mCubeMesh.createVertexAllocation(vertexSlot);
-        mPointAlloc.setName("PointBuffer");
 
-        // Create the Allocation for the indices
-        mLineIdxAlloc = mCubeMesh.createIndexAllocation();
+        mPointAlloc = mVertexBuffer.getAllocation();
 
-        // Bind the allocations to the mesh
-        mCubeMesh.bindVertexAllocation(mPointAlloc, 0);
-        mCubeMesh.bindIndexAllocation(mLineIdxAlloc);
+        mScript.bind_gPoints(mVertexBuffer);
+        mScript.set_gPointBuffer(mPointAlloc);
+        mScript.set_gCubeMesh(mCubeMesh);
 
-        /*
-         *  put the vertex and index data in their respective buffers
-         */
+        // put the vertex and index data in their respective buffers
         updateWave();
         for(int i = 0; i < mIndexData.length; i ++) {
             mIndexData[i] = (short) i;
         }
 
-        /*
-         *  upload the vertex and index data
-         */
-        mPointAlloc.data(mPointData);
-        mPointAlloc.uploadToBufferObject();
-        mLineIdxAlloc.data(mIndexData);
-        mLineIdxAlloc.uploadToBufferObject();
+        //  upload the vertex and index data
+        mPointAlloc.copyFromUnchecked(mPointData);
+        mLineIdxAlloc.copyFrom(mIndexData);
+        mLineIdxAlloc.syncAll(Allocation.USAGE_SCRIPT);
 
-        // Time to create the script
-        ScriptC.Builder sb = new ScriptC.Builder(mRS);
-        // Specify the name by which to refer to the WorldState object in the
-        // renderscript.
-        sb.setType(mStateType, "State", RSID_STATE);
-        sb.setScript(mResources, R.raw.many);
-        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(mPointAlloc, RSID_POINTS);
-        script.bindAllocation(mLineIdxAlloc, RSID_LINES);
-        script.bindAllocation(mPVAlloc.mAlloc, RSID_PROGRAMVERTEX);
-
-        return script;
+        return mScript;
     }
 
     @Override
@@ -413,10 +397,19 @@
                 mPointData[i*8+1] = amp;
                 mPointData[i*8+5] = -amp;
             }
-            mPointAlloc.data(mPointData);
+            mPointAlloc.copyFromUnchecked(mPointData);
             mWorldState.mWaveCounter++;
         }
 
-        mState.data(mWorldState);
+        updateWorldState();
+    }
+
+    protected void updateWorldState() {
+        mScript.set_gAngle(mWorldState.mAngle);
+        mScript.set_gPeak(mWorldState.mPeak);
+        mScript.set_gRotate(mWorldState.mRotate);
+        mScript.set_gTilt(mWorldState.mTilt);
+        mScript.set_gIdle(mWorldState.mIdle);
+        mScript.set_gWaveCounter(mWorldState.mWaveCounter);
     }
 }
diff --git a/src/com/android/musicvis/vis5/many.rs b/src/com/android/musicvis/vis5/many.rs
new file mode 100644
index 0000000..80920f2
--- /dev/null
+++ b/src/com/android/musicvis/vis5/many.rs
@@ -0,0 +1,319 @@
+// 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 rs java_package_name(com.android.musicvis.vis5)
+
+#include "rs_graphics.rsh"
+
+float gAngle;
+int   gPeak;
+float gRotate;
+float gTilt;
+int   gIdle;
+int   gWaveCounter;
+
+rs_program_vertex gPVBackground;
+rs_program_fragment gPFBackgroundMip;
+rs_program_fragment gPFBackgroundNoMip;
+rs_program_raster gPR;
+
+rs_allocation gTvumeter_background;
+rs_allocation gTvumeter_peak_on;
+rs_allocation gTvumeter_peak_off;
+rs_allocation gTvumeter_needle;
+rs_allocation gTvumeter_black;
+rs_allocation gTvumeter_frame;
+rs_allocation gTvumeter_album;
+
+rs_program_store gPFSBackground;
+
+typedef struct Vertex {
+    float2 position;
+    float2 texture0;
+} Vertex_t;
+Vertex_t *gPoints;
+
+
+rs_allocation gPointBuffer;
+rs_allocation gTlinetexture;
+rs_mesh gCubeMesh;
+
+#define RSID_POINTS 1
+
+static void drawVU(rs_matrix4x4 *ident) {
+    rs_matrix4x4 mat1;
+    float scale = 0.0041;
+
+    rsMatrixLoad(&mat1,ident);
+    rsMatrixRotate(&mat1, 0.f, 0.f, 0.f, 1.f);
+    rsMatrixScale(&mat1, scale, scale, scale);
+    rsgProgramVertexLoadModelMatrix(&mat1);
+
+    rsgBindProgramFragment(gPFBackgroundMip);
+    rsgBindProgramStore(gPFSBackground);
+
+    // draw the background image (416x233)
+    rsgBindTexture(gPFBackgroundMip, 0, gTvumeter_background);
+    rsgDrawQuadTexCoords(
+            -208.0f, -33.0f, 600.0f,       // space
+                0.0f, 1.0f,               // texture
+            208, -33.0f, 600.0f,           // space
+                1.0f, 1.0f,               // texture
+            208, 200.0f, 600.0f,           // space
+                1.0f, 0.0f,               // texture
+            -208.0f, 200.0f, 600.0f,       // space
+                0.0f, 0.0f);              // texture
+
+    // draw the peak indicator light (56x58)
+    if (gPeak > 0) {
+        rsgBindTexture(gPFBackgroundMip, 0, gTvumeter_peak_on);
+    } else {
+        rsgBindTexture(gPFBackgroundMip, 0, gTvumeter_peak_off);
+    }
+    rsgDrawQuadTexCoords(
+            140.0f, 70.0f, 600.0f,         // space
+                0.0f, 1.0f,               // texture
+            196, 70.0f, 600.0f,            // space
+                1.0f, 1.0f,               // texture
+            196, 128.0f, 600.0f,           // space
+                1.0f, 0.0f,               // texture
+            140.0f, 128.0f, 600.0f,        // space
+                0.0f, 0.0f);              // texture
+
+
+
+    // Draw the needle (88x262, center of rotation at 44,217 from top left)
+
+    // set matrix so point of rotation becomes origin
+    rsMatrixLoad(&mat1,ident);
+    rsMatrixTranslate(&mat1, 0.f, -57.0f * scale, 0.f);
+    rsMatrixRotate(&mat1, gAngle - 90.f, 0.f, 0.f, 1.f);
+    rsMatrixScale(&mat1, scale, scale, scale);
+    rsgProgramVertexLoadModelMatrix(&mat1);
+    rsgBindTexture(gPFBackgroundMip, 0, gTvumeter_needle);
+    rsgDrawQuadTexCoords(
+            -44.0f, -102.0f+57.f, 600.0f,         // space
+                0.0f, 1.0f,             // texture
+            44.0f, -102.0f+57.f, 600.0f,             // space
+                1.0f, 1.0f,              // texture
+            44.0f, 160.0f+57.f, 600.0f,             // space
+                1.0f, 0.0f,              // texture
+            -44.0f, 160.0f+57.f, 600.0f,         // space
+                0.0f, 0.0f);             // texture
+
+
+    // restore matrix
+    rsMatrixLoad(&mat1,ident);
+    rsMatrixRotate(&mat1, 0.f, 0.f, 0.f, 1.f);
+    rsMatrixScale(&mat1, scale, scale, scale);
+    rsgProgramVertexLoadModelMatrix(&mat1);
+
+    // erase the part of the needle we don't want to show
+    rsgBindTexture(gPFBackgroundMip, 0, gTvumeter_black);
+    rsgDrawQuad(-100.f, -55.f, 600.f,
+             -100.f, -105.f, 600.f,
+              100.f, -105.f, 600.f,
+              100.f, -55.f, 600.f);
+
+
+    // draw the frame (472x290)
+    rsgBindTexture(gPFBackgroundMip, 0, gTvumeter_frame);
+    rsgDrawQuadTexCoords(
+            -236.0f, -60.0f, 600.0f,           // space
+                0.0f, 1.0f,                  // texture
+            236, -60.0f, 600.0f,               // space
+                1.0f, 1.0f,                  // texture
+            236, 230.0f, 600.0f,               // space
+                1.0f, 0.0f,                  // texture
+            -236.0f, 230.0f, 600.0f,           // space
+                0.0f, 0.0f);                 // texture
+
+
+}
+
+int fadeoutcounter = 0;
+int fadeincounter = 0;
+int wave1pos = 0;
+int wave1amp = 0;
+int wave2pos = 0;
+int wave2amp= 0;
+int wave3pos = 0;
+int wave3amp= 0;
+int wave4pos = 0;
+int wave4amp= 0;
+float idle[4096];
+int waveCounter = 0;
+int lastuptime = 0;
+float autorotation = 0;
+
+#define FADEOUT_LENGTH 100
+#define FADEOUT_FACTOR 0.95f
+#define FADEIN_LENGTH 15
+
+static void makeIdleWave(float *points) {
+    int i;
+    // show a number of superimposed moving sinewaves
+    float amp1 = sin(0.007f * wave1amp) * 120 * 1024;
+    float amp2 = sin(0.023f * wave2amp) * 80 * 1024;
+    float amp3 = sin(0.011f * wave3amp) * 40 * 1024;
+    float amp4 = sin(0.031f * wave4amp) * 20 * 1024;
+    for (i = 0; i < 256; i++) {
+        float val = sin(0.013f * (wave1pos + i * 4)) * amp1
+                  + sin(0.029f * (wave2pos + i * 4)) * amp2;
+        float off = sin(0.005f * (wave3pos + i * 4)) * amp3
+                  + sin(0.017f * (wave4pos + i * 4)) * amp4;
+        if (val < 2.f && val > -2.f) val = 2.f;
+        points[i*8+1] = val + off;
+        points[i*8+5] = -val + off;
+    }
+}
+
+
+static void drawWave(rs_matrix4x4 *ident) {
+    float scale = .008f;
+    rs_matrix4x4 mat1;
+    rsMatrixLoad(&mat1, ident);
+    rsMatrixScale(&mat1, scale, scale / 2048.f, scale);
+    rsMatrixTranslate(&mat1, 0.f, 81920.f, 350.f);
+    rsgProgramVertexLoadModelMatrix(&mat1);
+    int i;
+
+    if (gIdle) {
+
+        // idle state animation
+        float *points = (float*)gPoints;
+        if (fadeoutcounter > 0) {
+            // fade waveform to 0
+            for (i = 0; i < 256; i++) {
+                float val = fabs(points[i*8+1]);
+                val = val * FADEOUT_FACTOR;
+                if (val < 2.f) val = 2.f;
+                points[i*8+1] = val;
+                points[i*8+5] = -val;
+            }
+            fadeoutcounter--;
+            if (fadeoutcounter == 0) {
+                wave1amp = 0;
+                wave2amp = 0;
+                wave3amp = 0;
+                wave4amp = 0;
+            }
+        } else {
+            // idle animation
+            makeIdleWave(points);
+        }
+        fadeincounter = FADEIN_LENGTH;
+    } else {
+        if (fadeincounter > 0 && fadeoutcounter == 0) {
+            // morph from idle animation back to waveform
+            makeIdleWave(idle);
+            if (waveCounter != gWaveCounter) {
+                waveCounter = gWaveCounter;
+                float *points = (float*)gPoints;
+                for (i = 0; i < 256; i++) {
+                    float val = fabs(points[i*8+1]);
+                    points[i*8+1] = (val * (FADEIN_LENGTH - fadeincounter) + idle[i*8+1] * fadeincounter) / FADEIN_LENGTH;
+                    points[i*8+5] = (-val * (FADEIN_LENGTH - fadeincounter) + idle[i*8+5] * fadeincounter) / FADEIN_LENGTH;
+                }
+            }
+            fadeincounter--;
+            if (fadeincounter == 0) {
+                fadeoutcounter = FADEOUT_LENGTH;
+            }
+        } else {
+            fadeoutcounter = FADEOUT_LENGTH;
+        }
+    }
+
+    rsgBindProgramRaster(gPR);
+    rsgBindProgramFragment(gPFBackgroundNoMip);
+    rsgBindTexture(gPFBackgroundNoMip, 0, gTlinetexture);
+    rsgDrawMesh(gCubeMesh);
+}
+
+
+static void drawVizLayer(rs_matrix4x4 *ident) {
+    for (int i = 0; i < 6; i++) {
+        if (i & 1) {
+            drawVU(ident);
+        } else {
+            drawWave(ident);
+        }
+
+        rsMatrixRotate(ident, 60.f, 0.f, 1.f, 0.f);
+    }
+}
+
+
+int root(int launchID) {
+    rsgClearColor(0.f, 0.f, 0.f, 1.f);
+
+    rsgBindProgramVertex(gPVBackground);
+
+    int i;
+    rs_matrix4x4 ident;
+    int now = (int)rsUptimeMillis();
+    int delta = now - lastuptime;
+    lastuptime = now;
+    if (delta > 80) {
+        // Limit the delta to avoid jumps when coming back from sleep.
+        // A value of 80 will make the rotation keep the same speed
+        // until the frame rate drops to 12.5 fps, at which point it
+        // will start slowing down.
+        delta = 80;
+    }
+    autorotation += .3 * delta / 35;
+    while (autorotation > 360.f) autorotation -= 360.f;
+
+    rsMatrixLoadIdentity(&ident);
+    rsMatrixRotate(&ident, gTilt, 1.f, 0.f, 0.f);
+    rsMatrixRotate(&ident, autorotation + gRotate, 0.f, 1.f, 0.f);
+
+    // draw the reflections
+    rsMatrixTranslate(&ident, 0.f, -1.f, 0.f);
+    rsMatrixScale(&ident, 1.f, -1.f, 1.f);
+    drawVizLayer(&ident);
+
+    // draw the reflecting plane
+    rsgBindProgramFragment(gPFBackgroundMip);
+    rsgBindTexture(gPFBackgroundMip, 0, gTvumeter_album);
+    rsgDrawQuadTexCoords(
+            -1500.0f, -60.0f, 1500.0f,           // space
+                0.f, 1.f,    // texture
+            1500, -60.0f, 1500.0f,               // space
+                1.f, 1.f,    // texture
+            1500, -60.0f, -1500.0f,               // space
+                1.f, 0.f,    // texture
+            -1500.0f, -60.0f, -1500.0f,           // space
+                0.f, 0.f);   // texture
+
+    // draw the visualizer
+    rsMatrixScale(&ident, 1.f, -1.f, 1.f);
+    rsMatrixTranslate(&ident, 0.f, 1.f, 0.f);
+
+    drawVizLayer(&ident);
+
+    wave1pos++;
+    wave1amp++;
+    wave2pos--;
+    wave2amp++;
+    wave3pos++;
+    wave3amp++;
+    wave4pos++;
+    wave4amp++;
+
+    return 1;
+}
diff --git a/src/com/android/musicvis/waveform.rs b/src/com/android/musicvis/waveform.rs
new file mode 100644
index 0000000..a23a709
--- /dev/null
+++ b/src/com/android/musicvis/waveform.rs
@@ -0,0 +1,165 @@
+// 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 rs java_package_name(com.android.musicvis)
+
+#include "rs_graphics.rsh"
+
+float gYRotation;
+int gIdle;
+int gWaveCounter;
+int gWidth;
+
+rs_program_vertex gPVBackground;
+rs_program_fragment gPFBackground;
+
+typedef struct Vertex {
+    float2 position;
+    float2 texture0;
+} Vertex_t;
+Vertex_t *gPoints;
+
+rs_allocation gPointBuffer;
+rs_allocation gTlinetexture;
+rs_mesh gCubeMesh;
+
+#define RSID_POINTS 1
+
+#define FADEOUT_LENGTH 100
+#define FADEOUT_FACTOR 0.95f
+#define FADEIN_LENGTH 15
+
+static int fadeoutcounter = 0;
+static int fadeincounter = 0;
+static int wave1pos = 0;
+static int wave1amp = 0;
+static int wave2pos = 0;
+static int wave2amp= 0;
+static int wave3pos = 0;
+static int wave3amp= 0;
+static int wave4pos = 0;
+static int wave4amp= 0;
+static float idle[8192];
+static int waveCounter = 0;
+
+static void makeIdleWave(float *points) {
+    // show a number of superimposed moving sinewaves
+    float amp1 = sin(0.007f * wave1amp) * 120;
+    float amp2 = sin(0.023f * wave2amp) * 80;
+    float amp3 = sin(0.011f * wave3amp) * 40;
+    float amp4 = sin(0.031f * wave4amp) * 20;
+    // calculate how many invisible lines there are on each side
+    int skip = (1024 - gWidth) / 2;
+    if (skip < 0) skip = 0;
+    int end = 1024 - skip;
+    for (int i = skip; i < end; i++) {
+        float val = sin(0.013f * (wave1pos + i)) * amp1
+                  + sin(0.029f * (wave2pos + i)) * amp2;
+        float off = sin(0.005f * (wave3pos + i)) * amp3
+                  + sin(0.017f * (wave4pos + i)) * amp4;
+        if (val < 2.f && val > -2.f) val = 2.f;
+        points[i*8+1] = val + off;
+        points[i*8+5] = -val + off;
+    }
+    wave1pos++;
+    wave1amp++;
+    wave2pos--;
+    wave2amp++;
+    wave3pos++;
+    wave3amp++;
+    wave4pos++;
+    wave4amp++;
+}
+
+int root(int launchID) {
+    rsgClearColor(0.f, 0.f, 0.f, 1.f);
+
+    int i;
+
+    // calculate how many invisible lines there are on each side
+    int width = gWidth;
+    if (width > 1024) width = 1024;
+    int skip = (1024 - width) / 2;
+    int end = 1024 - skip;
+
+    if (gIdle) {
+
+        // idle state animation
+        float *points = (float*)gPoints;
+        if (fadeoutcounter > 0) {
+            // fade waveform to 0
+            for (i = skip; i < end; i++) {
+                float val = fabs(points[i*8+1]);
+                val = val * FADEOUT_FACTOR;
+                if (val < 2.f) val = 2.f;
+                points[i*8+1] = val;
+                points[i*8+5] = -val;
+            }
+            fadeoutcounter--;
+            if (fadeoutcounter == 0) {
+                wave1amp = 0;
+                wave2amp = 0;
+                wave3amp = 0;
+                wave4amp = 0;
+            }
+        } else {
+            // idle animation
+            makeIdleWave(points);
+        }
+        fadeincounter = FADEIN_LENGTH;
+    } else {
+        if (fadeincounter > 0 && fadeoutcounter == 0) {
+            // morph from idle animation back to waveform
+            makeIdleWave(idle);
+            if (waveCounter != gWaveCounter) {
+                waveCounter = gWaveCounter;
+                float *points = (float*)gPoints;
+                for (i = skip; i < end; i++) {
+                    float val = fabs(points[i*8+1]);
+                    points[i*8+1] = (val * (FADEIN_LENGTH - fadeincounter) + idle[i*8+1] * fadeincounter) / FADEIN_LENGTH;
+                    points[i*8+5] = (-val * (FADEIN_LENGTH - fadeincounter) + idle[i*8+5] * fadeincounter) / FADEIN_LENGTH;
+                }
+            }
+            fadeincounter--;
+            if (fadeincounter == 0) {
+                fadeoutcounter = FADEOUT_LENGTH;
+            }
+        } else {
+            fadeoutcounter = FADEOUT_LENGTH;
+        }
+    }
+
+    rs_matrix4x4 mat1;
+    float yrot = gYRotation;
+    float scale = 0.004165f * (1.0f + 2.f * fabs(sin(radians(yrot))));
+
+    // Draw the visualizer.
+    rsgBindProgramVertex(gPVBackground);
+    rsgBindProgramFragment(gPFBackground);
+    rsgBindTexture(gPFBackground, 0, gTlinetexture);
+
+    // Change the model matrix to account for the large model
+    // and to do the necessary rotations.
+    rsMatrixLoadIdentity(&mat1);
+    rsMatrixRotate(&mat1, yrot, 0.f, 0.f, 1.f);
+    rsMatrixScale(&mat1, scale, scale, scale);
+    rsgProgramVertexLoadModelMatrix(&mat1);
+
+    rsgDrawMesh(gCubeMesh, 0, skip * 2, width * 2);
+
+    return 1;
+}
+