Improve structure support using symbol lookup of named structures in scripts to allow them to appear as just pointers to structs.
diff --git a/java/Fall/res/raw/fall.c b/java/Fall/res/raw/fall.c
index f348a62..c09f43c 100644
--- a/java/Fall/res/raw/fall.c
+++ b/java/Fall/res/raw/fall.c
@@ -52,8 +52,8 @@
 }
 
 void dropWithStrength(int x, int y, int r, int s) {
-    int width = State_meshWidth;
-    int height = State_meshHeight;
+    int width = State->meshWidth;
+    int height = State->meshHeight;
 
     if (x < r) x = r;
     if (y < r) y = r;
@@ -62,8 +62,8 @@
 
     x = width - x;
 
-    int rippleMapSize = State_rippleMapSize;
-    int index = State_rippleIndex;
+    int rippleMapSize = State->rippleMapSize;
+    int index = State->rippleIndex;
     int origin = offset(0, 0, width);
 
     int* current = loadArrayI32(RSID_RIPPLE_MAP, index * rippleMapSize + origin);
@@ -94,10 +94,10 @@
 }
 
 void updateRipples() {
-    int rippleMapSize = State_rippleMapSize;
-    int width = State_meshWidth;
-    int height = State_meshHeight;
-    int index = State_rippleIndex;
+    int rippleMapSize = State->rippleMapSize;
+    int width = State->meshWidth;
+    int height = State->meshHeight;
+    int index = State->rippleIndex;
     int origin = offset(0, 0, width);
 
     int* current = loadArrayI32(RSID_RIPPLE_MAP, index * rippleMapSize + origin);
@@ -139,9 +139,9 @@
 
 void generateRipples() {
     int rippleMapSize = loadI32(RSID_STATE, OFFSETOF_WorldState_rippleMapSize);
-    int width = State_meshWidth;
-    int height = State_meshHeight;
-    int index = State_rippleIndex;
+    int width = State->meshWidth;
+    int height = State->meshHeight;
+    int index = State->rippleIndex;
     int origin = offset(0, 0, width);
 
     int b = width + 2;
@@ -180,7 +180,7 @@
 
             // Update Z coordinate of the vertex
             vertices[index + 7] = dy * fy;
-            
+
             w -= 1;
             current += 1;
             wave = nextWave;
@@ -210,7 +210,7 @@
             float v2x = vertices[o1 + 5];
             float v2y = vertices[o1 + 6];
             float v2z = vertices[o1 + 7];
-            
+
             // V3
             float v3x = vertices[ow + 5];
             float v3y = vertices[ow + 6];
@@ -236,7 +236,7 @@
             n3x *= len;
             n3y *= len;
             n3z *= len;
-            
+
             // V2
             v2x = vertices[ow1 + 5];
             v2y = vertices[ow1 + 6];
@@ -266,7 +266,7 @@
             vertices[o + 0] = n3x;
             vertices[o + 1] = n3y;
             vertices[o + 2] = -n3z;
-            
+
             // reset Z
             //vertices[(yOffset + x) << 3 + 7] = 0.0f;
         }
@@ -322,7 +322,7 @@
     float z2 = 0.0f;
     float z3 = 0.0f;
     float z4 = 0.0f;
-    
+
     float a = leafStruct[LEAF_STRUCT_ALTITUDE];
     float s = leafStruct[LEAF_STRUCT_SCALE];
     float r = leafStruct[LEAF_STRUCT_ANGLE];
@@ -384,7 +384,7 @@
         LEAF_SIZE * s + y < -glHeight / 2.0f) {
 
         int sprite = randf(LEAVES_TEXTURES_COUNT);
-        leafStruct[LEAF_STRUCT_X] = randf2(-1.0f, 1.0f);   
+        leafStruct[LEAF_STRUCT_X] = randf2(-1.0f, 1.0f);
         leafStruct[LEAF_STRUCT_Y] = glHeight / 2.0f + LEAF_SIZE * 2 * randf(1.0f);
         leafStruct[LEAF_STRUCT_SCALE] = randf2(0.4f, 0.5f);
         leafStruct[LEAF_STRUCT_SPIN] = degf(randf2(-0.02f, 0.02f)) / 4.0f;
@@ -401,20 +401,20 @@
     bindProgramVertex(NAMED_PVSky);
     bindTexture(NAMED_PFBackground, 0, NAMED_TLeaves);
 
-    int leavesCount = State_leavesCount;
+    int leavesCount = State->leavesCount;
     int count = leavesCount * LEAF_STRUCT_FIELDS_COUNT;
-    int width = State_meshWidth;
-    int height = State_meshHeight;    
-    float glWidth = State_glWidth;
-    float glHeight = State_glHeight;
+    int width = State->meshWidth;
+    int height = State->meshHeight;
+    float glWidth = State->glWidth;
+    float glHeight = State->glHeight;
 
-    float *vertices = loadTriangleMeshVerticesF(NAMED_WaterMesh);    
+    float *vertices = loadTriangleMeshVerticesF(NAMED_WaterMesh);
 
     int i = 0;
     for ( ; i < count; i += LEAF_STRUCT_FIELDS_COUNT) {
         drawLeaf(i, vertices, width, height, glWidth, glHeight);
     }
-    
+
     float matrix[16];
     matrixLoadIdentity(matrix);
     vpLoadModelMatrix(matrix);
@@ -433,8 +433,8 @@
     bindProgramFragmentStore(NAMED_PFSLeaf);
     bindTexture(NAMED_PFSky, 0, NAMED_TSky);
 
-    float x = State_skyOffsetX + State_skySpeedX;
-    float y = State_skyOffsetY + State_skySpeedY;
+    float x = State->skyOffsetX + State->skySpeedX;
+    float y = State->skyOffsetY + State->skySpeedY;
 
     if (x > 1.0f) x = 0.0f;
     if (x < -1.0f) x = 0.0f;
@@ -467,8 +467,8 @@
 }
 
 void drawNormals() {
-    int width = State_meshWidth;
-    int height = State_meshHeight;
+    int width = State->meshWidth;
+    int height = State->meshHeight;
 
     float *vertices = loadTriangleMeshVerticesF(NAMED_WaterMesh);
 
@@ -496,12 +496,10 @@
 }
 
 int main(int index) {
-    int dropX = Drop_dropX;
-    if (dropX != -1) {
-        int dropY = Drop_dropY;
-        drop(dropX, dropY, DROP_RADIUS);
-        storeI32(RSID_DROP, OFFSETOF_DropState_dropX, -1);
-        storeI32(RSID_DROP, OFFSETOF_DropState_dropY, -1);
+    if (Drop->dropX != -1) {
+        drop(Drop->dropX, Drop->dropY, DROP_RADIUS);
+        Drop->dropX = -1;
+        Drop->dropY = -1;
     }
 
     updateRipples();
diff --git a/java/Film/res/raw/filmstrip.c b/java/Film/res/raw/filmstrip.c
index 8f3d930..8fbfee1 100644
--- a/java/Film/res/raw/filmstrip.c
+++ b/java/Film/res/raw/filmstrip.c
@@ -5,10 +5,6 @@
 #pragma stateFragment(PFBackground)
 #pragma stateFragmentStore(PSBackground)
 
-#define POS_TRANSLATE 0
-#define POS_ROTATE 1
-#define POS_FOCUS 2
-
 #define STATE_TRIANGLE_OFFSET_COUNT 0
 #define STATE_LAST_FOCUS 1
 
@@ -18,12 +14,14 @@
 // bank1: (r) The position information
 // bank2: (rw) The temporary texture state
 
+int lastFocus;
+
 int main(int index)
 {
     float mat1[16];
 
-    float trans = Pos_translate;
-    float rot = Pos_rotate;
+    float trans = Pos->translate;
+    float rot = Pos->rotate;
 
     matrixLoadScale(mat1, 2.f, 2.f, 2.f);
     matrixTranslate(mat1, 0.f, 0.f, trans);
@@ -39,7 +37,7 @@
     bindProgramFragment(NAMED_PFImages);
     bindProgramVertex(NAMED_PVImages);
 
-    float focusPos = Pos_focus;
+    float focusPos = Pos->focus;
     int focusID = 0;
     int lastFocusID = loadI32(2, STATE_LAST_FOCUS);
     int imgCount = 13;
@@ -63,9 +61,9 @@
         }
     }
     */
-    storeI32(2, STATE_LAST_FOCUS, focusID);
+    lastFocus = focusID;
 
-    int triangleOffsetsCount = Pos_triangleOffsetCount;
+    int triangleOffsetsCount = Pos->triangleOffsetCount;
 
     int imgId = 0;
     for (imgId=1; imgId <= imgCount; imgId++) {
diff --git a/java/Fountain/res/raw/fountain.c b/java/Fountain/res/raw/fountain.c
index 99f4048..36516c2 100644
--- a/java/Fountain/res/raw/fountain.c
+++ b/java/Fountain/res/raw/fountain.c
@@ -4,27 +4,32 @@
 #pragma stateFragment(default)
 #pragma stateFragmentStore(default)
 
-struct PartStruct {float dx; float dy; float x; float y; int c;};
 int newPart = 0;
 
 int main(int launchID) {
     int ct;
-    int count = Control_count - 1;
-    int rate = Control_rate;
+    int count = Control->count;
+    int rate = Control->rate;
     float height = getHeight();
-    struct PartStruct * p = (struct PartStruct *)loadArrayF(1, 0);
+    struct point_s * p = (struct point_s *)point;
 
     if (rate) {
         float rMax = ((float)rate) * 0.005f;
-        int x = Control_x;
-        int y = Control_y;
-        int c = colorFloatRGBAtoUNorm8(Control_r, Control_g, Control_b, 0.99f);
+        int x = Control->x;
+        int y = Control->y;
+        char r = Control->r * 255.f;
+        char g = Control->g * 255.f;
+        char b = Control->b * 255.f;
+        char a = 0xf0;
 
         while (rate--) {
             vec2Rand((float *)(p + newPart), rMax);
             p[newPart].x = x;
             p[newPart].y = y;
-            p[newPart].c = c;
+            p[newPart].r = r;
+            p[newPart].g = g;
+            p[newPart].b = b;
+            p[newPart].a = a;
             newPart++;
             if (newPart >= count) {
                 newPart = 0;
@@ -45,6 +50,6 @@
     }
 
     uploadToBufferObject(NAMED_PartBuffer);
-    drawSimpleMeshRange(NAMED_PartMesh, 0, count);
+    drawSimpleMesh(NAMED_PartMesh);
     return 1;
 }
diff --git a/java/Fountain/src/com/android/fountain/FountainRS.java b/java/Fountain/src/com/android/fountain/FountainRS.java
index 6d400c5..f4f9b0c 100644
--- a/java/Fountain/src/com/android/fountain/FountainRS.java
+++ b/java/Fountain/src/com/android/fountain/FountainRS.java
@@ -79,10 +79,10 @@
         mIntAlloc.data(mSD);
 
         Element.Builder eb = new Element.Builder(mRS);
-        eb.addFloat(Element.DataKind.USER); //dx
-        eb.addFloat(Element.DataKind.USER); //dy
-        eb.addFloatXY();
-        eb.addUNorm8RGBA();
+        eb.addFloat(Element.DataKind.USER, "dx");
+        eb.addFloat(Element.DataKind.USER, "dy");
+        eb.addFloatXY("");
+        eb.addUNorm8RGBA("");
         Element primElement = eb.create();
 
 
@@ -102,6 +102,7 @@
         sb.setScript(mRes, R.raw.fountain);
         sb.setRoot(true);
         sb.setType(mSDType, "Control", 0);
+        sb.setType(mSM.getVertexType(0), "point", 1);
         Script script = sb.create();
         script.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
 
diff --git a/rsContext.cpp b/rsContext.cpp
index c28bd02..c132915 100644
--- a/rsContext.cpp
+++ b/rsContext.cpp
@@ -116,6 +116,7 @@
     //glEnable(GL_LIGHT0);
     glViewport(0, 0, mEGL.mWidth, mEGL.mHeight);
     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+    glEnable(GL_POINT_SMOOTH);
 
     glClearColor(mRootScript->mEnviroment.mClearColor[0],
                  mRootScript->mEnviroment.mClearColor[1],
@@ -153,10 +154,18 @@
 void Context::timerInit()
 {
     mTimeLast = getTime();
+    mTimeFrame = mTimeLast;
+    mTimeLastFrame = mTimeLast;
     mTimerActive = RS_TIMER_INTERNAL;
     timerReset();
 }
 
+void Context::timerFrame()
+{
+    mTimeLastFrame = mTimeFrame;
+    mTimeFrame = getTime();
+}
+
 void Context::timerSet(Timers tm)
 {
     uint64_t last = mTimeLast;
@@ -171,8 +180,10 @@
     for (int ct = 0; ct < _RS_TIMER_TOTAL; ct++) {
         total += mTimers[ct];
     }
+    uint64_t frame = mTimeFrame - mTimeLastFrame;
 
-    LOGV("RS Time Data: Idle %2.1f (%lli),  Internal %2.1f (%lli),  Script %2.1f (%lli),  Clear & Swap %2.1f (%lli)",
+    LOGV("RS: Frame (%lli),   Script %2.1f (%lli),  Clear & Swap %2.1f (%lli),  Idle %2.1f (%lli),  Internal %2.1f (%lli)",
+         frame / 1000000,
          100.0 * mTimers[RS_TIMER_IDLE] / total, mTimers[RS_TIMER_IDLE] / 1000000,
          100.0 * mTimers[RS_TIMER_INTERNAL] / total, mTimers[RS_TIMER_INTERNAL] / 1000000,
          100.0 * mTimers[RS_TIMER_SCRIPT] / total, mTimers[RS_TIMER_SCRIPT] / 1000000,
@@ -232,6 +243,7 @@
 #endif
              eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface);
 #if RS_LOG_TIMES
+             rsc->timerFrame();
              rsc->timerSet(RS_TIMER_INTERNAL);
              rsc->timerPrint();
              rsc->timerReset();
diff --git a/rsContext.h b/rsContext.h
index c58a88c..634416b 100644
--- a/rsContext.h
+++ b/rsContext.h
@@ -131,6 +131,7 @@
     void timerReset();
     void timerSet(Timers);
     void timerPrint();
+    void timerFrame();
 
     bool checkVersion1_1() const {return (mGL.mMajorVersion > 1) || (mGL.mMinorVersion >= 1); }
     bool checkVersion2_0() const {return mGL.mMajorVersion >= 2; }
@@ -202,6 +203,8 @@
     uint64_t mTimers[_RS_TIMER_TOTAL];
     Timers mTimerActive;
     uint64_t mTimeLast;
+    uint64_t mTimeFrame;
+    uint64_t mTimeLastFrame;
 };
 
 
diff --git a/rsScriptC.cpp b/rsScriptC.cpp
index 0c7ac18..9d9eb1b 100644
--- a/rsScriptC.cpp
+++ b/rsScriptC.cpp
@@ -67,6 +67,12 @@
                 = nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC));
     }
 
+    for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
+        if (mProgram.mSlotPointers[ct]) {
+            *mProgram.mSlotPointers[ct] = mSlots[ct]->getPtr();
+        }
+    }
+
     bool ret = false;
     tls->mScript = this;
     ret = mProgram.mScript(launchIndex) != 0;
@@ -139,6 +145,7 @@
     accRegisterSymbolCallback(mAccScript, symbolLookup, NULL);
     accCompileScript(mAccScript);
     accGetScriptLabel(mAccScript, "main", (ACCvoid**) &mProgram.mScript);
+    accGetScriptLabel(mAccScript, "init", (ACCvoid**) &mProgram.mInit);
     rsAssert(mProgram.mScript);
 
     if (!mProgram.mScript) {
@@ -148,6 +155,19 @@
         LOGE(buf);
     }
 
+    if (mProgram.mInit) {
+        mProgram.mInit();
+    }
+
+    for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
+        if (mSlotNames[ct].length() > 0) {
+            accGetScriptLabel(mAccScript,
+                              mSlotNames[ct].string(),
+                              (ACCvoid**) &mProgram.mSlotPointers[ct]);
+            LOGE("var  %s  %p", mSlotNames[ct].string(), mProgram.mSlotPointers[ct]);
+        }
+    }
+
     mEnviroment.mFragment.set(rsc->getDefaultProgramFragment());
     mEnviroment.mVertex.set(rsc->getDefaultProgramVertex());
     mEnviroment.mFragmentStore.set(rsc->getDefaultProgramFragmentStore());
@@ -224,6 +244,19 @@
     }
 }
 
+static void appendElementBody(String8 *s, const Element *e)
+{
+    s->append(" {\n");
+    for (size_t ct2=0; ct2 < e->getComponentCount(); ct2++) {
+        const Component *c = e->getComponent(ct2);
+        s->append("    ");
+        s->append(c->getCType());
+        s->append(" ");
+        s->append(c->getComponentName());
+        s->append(";\n");
+    }
+    s->append("}");
+}
 
 void ScriptCState::appendVarDefines(String8 *str)
 {
@@ -246,6 +279,8 @@
     }
 }
 
+
+
 void ScriptCState::appendTypes(String8 *str)
 {
     char buf[256];
@@ -257,6 +292,19 @@
             continue;
         }
         const Element *e = t->getElement();
+        if (e->getName() && (e->getComponentCount() > 1)) {
+            String8 s("struct struct_");
+            s.append(e->getName());
+            appendElementBody(&s, e);
+            s.append(";\n");
+            s.append("#define ");
+            s.append(e->getName());
+            s.append("_t struct struct_");
+            s.append(e->getName());
+            s.append("\n\n");
+            LOGD(s);
+            str->append(s);
+        }
 
         if (t->getName()) {
             for (size_t ct2=0; ct2 < e->getComponentCount(); ct2++) {
@@ -267,12 +315,39 @@
                 tmp.append(c->getComponentName());
                 sprintf(buf, " %i\n", ct2);
                 tmp.append(buf);
-                //LOGD(tmp);
+                LOGD(tmp);
                 str->append(tmp);
             }
         }
 
         if (mSlotNames[ct].length() > 0) {
+            String8 s;
+            if (e->getComponentCount() > 1) {
+                if (e->getName()) {
+                    // Use the named struct
+                    s.setTo(e->getName());
+                    s.append("_t *");
+                } else {
+                    // create an struct named from the slot.
+                    s.setTo("struct ");
+                    s.append(mSlotNames[ct]);
+                    s.append("_s");
+                    appendElementBody(&s, e);
+                    s.append(";\n");
+                    s.append("struct ");
+                    s.append(mSlotNames[ct]);
+                    s.append("_s * ");
+                }
+            } else {
+                // Just make an array
+                s.setTo(e->getComponent(0)->getCType());
+                s.append("_t *");
+            }
+            s.append(mSlotNames[ct]);
+            s.append(";\n");
+            LOGD(s);
+            str->append(s);
+#if 0
             for (size_t ct2=0; ct2 < e->getComponentCount(); ct2++) {
                 const Component *c = e->getComponent(ct2);
                 tmp.setTo("#define ");
@@ -295,12 +370,12 @@
                 sprintf(buf, "%i, %i)\n", ct, ct2);
                 tmp.append(buf);
 
-                //LOGD(tmp);
+                LOGD(tmp);
                 str->append(tmp);
             }
+#endif
         }
     }
-
 }
 
 
diff --git a/rsScriptC.h b/rsScriptC.h
index 302515e..8aa99ef 100644
--- a/rsScriptC.h
+++ b/rsScriptC.h
@@ -35,6 +35,7 @@
 {
 public:
     typedef int (*RunScript_t)(uint32_t launchIndex);
+    typedef void (*VoidFunc_t)();
 
     ScriptC();
     virtual ~ScriptC();
@@ -48,6 +49,9 @@
         int mVersionMinor;
 
         RunScript_t mScript;
+        VoidFunc_t mInit;
+
+        void ** mSlotPointers[MAX_SCRIPT_BANKS];
     };
 
     Program_t mProgram;