rsScriptC_Lib.cpp revision af07b591bbb39df30f6018c5a64791552a06ed00
1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "rsContext.h"
18#include "rsScriptC.h"
19#include "rsMatrix.h"
20#include "rsNoise.h"
21
22#include "acc/acc.h"
23#include "utils/Timers.h"
24
25#define GL_GLEXT_PROTOTYPES
26
27#include <GLES/gl.h>
28#include <GLES/glext.h>
29#include <GLES2/gl2.h>
30#include <GLES2/gl2ext.h>
31
32#include <time.h>
33
34using namespace android;
35using namespace android::renderscript;
36
37#define GET_TLS()  Context::ScriptTLSStruct * tls = \
38    (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \
39    Context * rsc = tls->mContext; \
40    ScriptC * sc = (ScriptC *) tls->mScript
41
42typedef struct {
43    float x;
44    float y;
45    float z;
46} vec3_t;
47
48typedef struct {
49    float x;
50    float y;
51    float z;
52    float w;
53} vec4_t;
54
55typedef struct {
56    float x;
57    float y;
58} vec2_t;
59
60//////////////////////////////////////////////////////////////////////////////
61// IO routines
62//////////////////////////////////////////////////////////////////////////////
63
64static float SC_loadF(uint32_t bank, uint32_t offset)
65{
66    GET_TLS();
67    const void *vp = sc->mSlots[bank]->getPtr();
68    const float *f = static_cast<const float *>(vp);
69    //LOGE("loadF %i %i = %f %x", bank, offset, f, ((int *)&f)[0]);
70    return f[offset];
71}
72
73static int32_t SC_loadI32(uint32_t bank, uint32_t offset)
74{
75    GET_TLS();
76    const void *vp = sc->mSlots[bank]->getPtr();
77    const int32_t *i = static_cast<const int32_t *>(vp);
78    //LOGE("loadI32 %i %i = %i", bank, offset, t);
79    return i[offset];
80}
81
82static float* SC_loadArrayF(uint32_t bank, uint32_t offset)
83{
84    GET_TLS();
85    void *vp = sc->mSlots[bank]->getPtr();
86    float *f = static_cast<float *>(vp);
87    return f + offset;
88}
89
90static int32_t* SC_loadArrayI32(uint32_t bank, uint32_t offset)
91{
92    GET_TLS();
93    void *vp = sc->mSlots[bank]->getPtr();
94    int32_t *i = static_cast<int32_t *>(vp);
95    return i + offset;
96}
97
98static float* SC_loadSimpleMeshVerticesF(RsSimpleMesh mesh, uint32_t idx)
99{
100    SimpleMesh *tm = static_cast<SimpleMesh *>(mesh);
101    void *vp = tm->mVertexBuffers[idx]->getPtr();;
102    return static_cast<float *>(vp);
103}
104
105static void SC_updateSimpleMesh(RsSimpleMesh mesh)
106{
107    GET_TLS();
108    SimpleMesh *sm = static_cast<SimpleMesh *>(mesh);
109    sm->uploadAll(rsc);
110}
111
112static uint32_t SC_loadU32(uint32_t bank, uint32_t offset)
113{
114    GET_TLS();
115    const void *vp = sc->mSlots[bank]->getPtr();
116    const uint32_t *i = static_cast<const uint32_t *>(vp);
117    return i[offset];
118}
119
120static void SC_loadVec4(uint32_t bank, uint32_t offset, rsc_Vector4 *v)
121{
122    GET_TLS();
123    const void *vp = sc->mSlots[bank]->getPtr();
124    const float *f = static_cast<const float *>(vp);
125    memcpy(v, &f[offset], sizeof(rsc_Vector4));
126}
127
128static void SC_loadMatrix(uint32_t bank, uint32_t offset, rsc_Matrix *m)
129{
130    GET_TLS();
131    const void *vp = sc->mSlots[bank]->getPtr();
132    const float *f = static_cast<const float *>(vp);
133    memcpy(m, &f[offset], sizeof(rsc_Matrix));
134}
135
136
137static void SC_storeF(uint32_t bank, uint32_t offset, float v)
138{
139    //LOGE("storeF %i %i %f", bank, offset, v);
140    GET_TLS();
141    void *vp = sc->mSlots[bank]->getPtr();
142    float *f = static_cast<float *>(vp);
143    f[offset] = v;
144}
145
146static void SC_storeI32(uint32_t bank, uint32_t offset, int32_t v)
147{
148    GET_TLS();
149    void *vp = sc->mSlots[bank]->getPtr();
150    int32_t *f = static_cast<int32_t *>(vp);
151    static_cast<int32_t *>(sc->mSlots[bank]->getPtr())[offset] = v;
152}
153
154static void SC_storeU32(uint32_t bank, uint32_t offset, uint32_t v)
155{
156    GET_TLS();
157    void *vp = sc->mSlots[bank]->getPtr();
158    uint32_t *f = static_cast<uint32_t *>(vp);
159    static_cast<uint32_t *>(sc->mSlots[bank]->getPtr())[offset] = v;
160}
161
162static void SC_storeVec4(uint32_t bank, uint32_t offset, const rsc_Vector4 *v)
163{
164    GET_TLS();
165    void *vp = sc->mSlots[bank]->getPtr();
166    float *f = static_cast<float *>(vp);
167    memcpy(&f[offset], v, sizeof(rsc_Vector4));
168}
169
170static void SC_storeMatrix(uint32_t bank, uint32_t offset, const rsc_Matrix *m)
171{
172    GET_TLS();
173    void *vp = sc->mSlots[bank]->getPtr();
174    float *f = static_cast<float *>(vp);
175    memcpy(&f[offset], m, sizeof(rsc_Matrix));
176}
177
178//////////////////////////////////////////////////////////////////////////////
179// Vec3 routines
180//////////////////////////////////////////////////////////////////////////////
181
182static void SC_vec3Norm(vec3_t *v)
183{
184    float len = sqrtf(v->x * v->x + v->y * v->y + v->z * v->z);
185    len = 1 / len;
186    v->x *= len;
187    v->y *= len;
188    v->z *= len;
189}
190
191static float SC_vec3Length(const vec3_t *v)
192{
193    return sqrtf(v->x * v->x + v->y * v->y + v->z * v->z);
194}
195
196static void SC_vec3Add(vec3_t *dest, const vec3_t *lhs, const vec3_t *rhs)
197{
198    dest->x = lhs->x + rhs->x;
199    dest->y = lhs->y + rhs->y;
200    dest->z = lhs->z + rhs->z;
201}
202
203static void SC_vec3Sub(vec3_t *dest, const vec3_t *lhs, const vec3_t *rhs)
204{
205    dest->x = lhs->x - rhs->x;
206    dest->y = lhs->y - rhs->y;
207    dest->z = lhs->z - rhs->z;
208}
209
210static void SC_vec3Cross(vec3_t *dest, const vec3_t *lhs, const vec3_t *rhs)
211{
212    float x = lhs->y * rhs->z  - lhs->z * rhs->y;
213    float y = lhs->z * rhs->x  - lhs->x * rhs->z;
214    float z = lhs->x * rhs->y  - lhs->y * rhs->x;
215    dest->x = x;
216    dest->y = y;
217    dest->z = z;
218}
219
220static float SC_vec3Dot(const vec3_t *lhs, const vec3_t *rhs)
221{
222    return lhs->x * rhs->x + lhs->y * rhs->y + lhs->z * rhs->z;
223}
224
225static void SC_vec3Scale(vec3_t *lhs, float scale)
226{
227    lhs->x *= scale;
228    lhs->y *= scale;
229    lhs->z *= scale;
230}
231
232//////////////////////////////////////////////////////////////////////////////
233// Vec4 routines
234//////////////////////////////////////////////////////////////////////////////
235
236static void SC_vec4Norm(vec4_t *v)
237{
238    float len = sqrtf(v->x * v->x + v->y * v->y + v->z * v->z + v->w * v->w);
239    len = 1 / len;
240    v->x *= len;
241    v->y *= len;
242    v->z *= len;
243    v->w *= len;
244}
245
246static float SC_vec4Length(const vec4_t *v)
247{
248    return sqrtf(v->x * v->x + v->y * v->y + v->z * v->z + v->w * v->w);
249}
250
251static void SC_vec4Add(vec4_t *dest, const vec4_t *lhs, const vec4_t *rhs)
252{
253    dest->x = lhs->x + rhs->x;
254    dest->y = lhs->y + rhs->y;
255    dest->z = lhs->z + rhs->z;
256    dest->w = lhs->w + rhs->w;
257}
258
259static void SC_vec4Sub(vec4_t *dest, const vec4_t *lhs, const vec4_t *rhs)
260{
261    dest->x = lhs->x - rhs->x;
262    dest->y = lhs->y - rhs->y;
263    dest->z = lhs->z - rhs->z;
264    dest->w = lhs->w - rhs->w;
265}
266
267static float SC_vec4Dot(const vec4_t *lhs, const vec4_t *rhs)
268{
269    return lhs->x * rhs->x + lhs->y * rhs->y + lhs->z * rhs->z + lhs->w * rhs->w;
270}
271
272static void SC_vec4Scale(vec4_t *lhs, float scale)
273{
274    lhs->x *= scale;
275    lhs->y *= scale;
276    lhs->z *= scale;
277    lhs->w *= scale;
278}
279
280//////////////////////////////////////////////////////////////////////////////
281// Math routines
282//////////////////////////////////////////////////////////////////////////////
283
284#define PI 3.1415926f
285#define DEG_TO_RAD PI / 180.0f
286#define RAD_TO_DEG 180.0f / PI
287
288static float SC_sinf_fast(float x)
289{
290    const float A =   1.0f / (2.0f * M_PI);
291    const float B = -16.0f;
292    const float C =   8.0f;
293
294    // scale angle for easy argument reduction
295    x *= A;
296
297    if (fabsf(x) >= 0.5f) {
298        // argument reduction
299        x = x - ceilf(x + 0.5f) + 1.0f;
300    }
301
302    const float y = B * x * fabsf(x) + C * x;
303    return 0.2215f * (y * fabsf(y) - y) + y;
304}
305
306static float SC_cosf_fast(float x)
307{
308    x += float(M_PI / 2);
309
310    const float A =   1.0f / (2.0f * M_PI);
311    const float B = -16.0f;
312    const float C =   8.0f;
313
314    // scale angle for easy argument reduction
315    x *= A;
316
317    if (fabsf(x) >= 0.5f) {
318        // argument reduction
319        x = x - ceilf(x + 0.5f) + 1.0f;
320    }
321
322    const float y = B * x * fabsf(x) + C * x;
323    return 0.2215f * (y * fabsf(y) - y) + y;
324}
325
326static float SC_randf(float max)
327{
328    float r = (float)rand();
329    return r / RAND_MAX * max;
330}
331
332static float SC_randf2(float min, float max)
333{
334    float r = (float)rand();
335    return r / RAND_MAX * (max - min) + min;
336}
337
338static int SC_sign(int value)
339{
340    return (value > 0) - (value < 0);
341}
342
343static float SC_signf(float value)
344{
345    return (value > 0) - (value < 0);
346}
347
348static float SC_clampf(float amount, float low, float high)
349{
350    return amount < low ? low : (amount > high ? high : amount);
351}
352
353static int SC_clamp(int amount, int low, int high)
354{
355    return amount < low ? low : (amount > high ? high : amount);
356}
357
358static float SC_maxf(float a, float b)
359{
360    return a > b ? a : b;
361}
362
363static float SC_minf(float a, float b)
364{
365    return a < b ? a : b;
366}
367
368static float SC_sqrf(float v)
369{
370    return v * v;
371}
372
373static int SC_sqr(int v)
374{
375    return v * v;
376}
377
378static float SC_fracf(float v)
379{
380    return v - floorf(v);
381}
382
383static float SC_roundf(float v)
384{
385    return floorf(v + 0.4999999999);
386}
387
388static float SC_distf2(float x1, float y1, float x2, float y2)
389{
390    float x = x2 - x1;
391    float y = y2 - y1;
392    return sqrtf(x * x + y * y);
393}
394
395static float SC_distf3(float x1, float y1, float z1, float x2, float y2, float z2)
396{
397    float x = x2 - x1;
398    float y = y2 - y1;
399    float z = z2 - z1;
400    return sqrtf(x * x + y * y + z * z);
401}
402
403static float SC_magf2(float a, float b)
404{
405    return sqrtf(a * a + b * b);
406}
407
408static float SC_magf3(float a, float b, float c)
409{
410    return sqrtf(a * a + b * b + c * c);
411}
412
413static float SC_radf(float degrees)
414{
415    return degrees * DEG_TO_RAD;
416}
417
418static float SC_degf(float radians)
419{
420    return radians * RAD_TO_DEG;
421}
422
423static float SC_lerpf(float start, float stop, float amount)
424{
425    return start + (stop - start) * amount;
426}
427
428static float SC_normf(float start, float stop, float value)
429{
430    return (value - start) / (stop - start);
431}
432
433static float SC_mapf(float minStart, float minStop, float maxStart, float maxStop, float value)
434{
435    return maxStart + (maxStart - maxStop) * ((value - minStart) / (minStop - minStart));
436}
437
438//////////////////////////////////////////////////////////////////////////////
439// Time routines
440//////////////////////////////////////////////////////////////////////////////
441
442static int32_t SC_second()
443{
444    GET_TLS();
445
446    time_t rawtime;
447    time(&rawtime);
448
449    struct tm *timeinfo;
450    timeinfo = localtime(&rawtime);
451    return timeinfo->tm_sec;
452}
453
454static int32_t SC_minute()
455{
456    GET_TLS();
457
458    time_t rawtime;
459    time(&rawtime);
460
461    struct tm *timeinfo;
462    timeinfo = localtime(&rawtime);
463    return timeinfo->tm_min;
464}
465
466static int32_t SC_hour()
467{
468    GET_TLS();
469
470    time_t rawtime;
471    time(&rawtime);
472
473    struct tm *timeinfo;
474    timeinfo = localtime(&rawtime);
475    return timeinfo->tm_hour;
476}
477
478static int32_t SC_day()
479{
480    GET_TLS();
481
482    time_t rawtime;
483    time(&rawtime);
484
485    struct tm *timeinfo;
486    timeinfo = localtime(&rawtime);
487    return timeinfo->tm_mday;
488}
489
490static int32_t SC_month()
491{
492    GET_TLS();
493
494    time_t rawtime;
495    time(&rawtime);
496
497    struct tm *timeinfo;
498    timeinfo = localtime(&rawtime);
499    return timeinfo->tm_mon;
500}
501
502static int32_t SC_year()
503{
504    GET_TLS();
505
506    time_t rawtime;
507    time(&rawtime);
508
509    struct tm *timeinfo;
510    timeinfo = localtime(&rawtime);
511    return timeinfo->tm_year;
512}
513
514static int32_t SC_uptimeMillis()
515{
516    return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC));
517}
518
519static int32_t SC_startTimeMillis()
520{
521    GET_TLS();
522    return sc->mEnviroment.mStartTimeMillis;
523}
524
525static int32_t SC_elapsedTimeMillis()
526{
527    GET_TLS();
528    return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC))
529            - sc->mEnviroment.mStartTimeMillis;
530}
531
532//////////////////////////////////////////////////////////////////////////////
533// Matrix routines
534//////////////////////////////////////////////////////////////////////////////
535
536
537static void SC_matrixLoadIdentity(rsc_Matrix *mat)
538{
539    Matrix *m = reinterpret_cast<Matrix *>(mat);
540    m->loadIdentity();
541}
542
543static void SC_matrixLoadFloat(rsc_Matrix *mat, const float *f)
544{
545    Matrix *m = reinterpret_cast<Matrix *>(mat);
546    m->load(f);
547}
548
549static void SC_matrixLoadMat(rsc_Matrix *mat, const rsc_Matrix *newmat)
550{
551    Matrix *m = reinterpret_cast<Matrix *>(mat);
552    m->load(reinterpret_cast<const Matrix *>(newmat));
553}
554
555static void SC_matrixLoadRotate(rsc_Matrix *mat, float rot, float x, float y, float z)
556{
557    Matrix *m = reinterpret_cast<Matrix *>(mat);
558    m->loadRotate(rot, x, y, z);
559}
560
561static void SC_matrixLoadScale(rsc_Matrix *mat, float x, float y, float z)
562{
563    Matrix *m = reinterpret_cast<Matrix *>(mat);
564    m->loadScale(x, y, z);
565}
566
567static void SC_matrixLoadTranslate(rsc_Matrix *mat, float x, float y, float z)
568{
569    Matrix *m = reinterpret_cast<Matrix *>(mat);
570    m->loadTranslate(x, y, z);
571}
572
573static void SC_matrixLoadMultiply(rsc_Matrix *mat, const rsc_Matrix *lhs, const rsc_Matrix *rhs)
574{
575    Matrix *m = reinterpret_cast<Matrix *>(mat);
576    m->loadMultiply(reinterpret_cast<const Matrix *>(lhs),
577                    reinterpret_cast<const Matrix *>(rhs));
578}
579
580static void SC_matrixMultiply(rsc_Matrix *mat, const rsc_Matrix *rhs)
581{
582    Matrix *m = reinterpret_cast<Matrix *>(mat);
583    m->multiply(reinterpret_cast<const Matrix *>(rhs));
584}
585
586static void SC_matrixRotate(rsc_Matrix *mat, float rot, float x, float y, float z)
587{
588    Matrix *m = reinterpret_cast<Matrix *>(mat);
589    m->rotate(rot, x, y, z);
590}
591
592static void SC_matrixScale(rsc_Matrix *mat, float x, float y, float z)
593{
594    Matrix *m = reinterpret_cast<Matrix *>(mat);
595    m->scale(x, y, z);
596}
597
598static void SC_matrixTranslate(rsc_Matrix *mat, float x, float y, float z)
599{
600    Matrix *m = reinterpret_cast<Matrix *>(mat);
601    m->translate(x, y, z);
602}
603
604
605static void SC_vec2Rand(float *vec, float maxLen)
606{
607    float angle = SC_randf(PI * 2);
608    float len = SC_randf(maxLen);
609    vec[0] = len * sinf(angle);
610    vec[1] = len * cosf(angle);
611}
612
613
614
615//////////////////////////////////////////////////////////////////////////////
616// Context
617//////////////////////////////////////////////////////////////////////////////
618
619static void SC_bindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va)
620{
621    GET_TLS();
622    rsi_ProgramBindTexture(rsc,
623                           static_cast<ProgramFragment *>(vpf),
624                           slot,
625                           static_cast<Allocation *>(va));
626
627}
628
629static void SC_bindSampler(RsProgramFragment vpf, uint32_t slot, RsSampler vs)
630{
631    GET_TLS();
632    rsi_ProgramBindSampler(rsc,
633                           static_cast<ProgramFragment *>(vpf),
634                           slot,
635                           static_cast<Sampler *>(vs));
636
637}
638
639static void SC_bindProgramFragmentStore(RsProgramFragmentStore pfs)
640{
641    GET_TLS();
642    rsi_ContextBindProgramFragmentStore(rsc, pfs);
643
644}
645
646static void SC_bindProgramFragment(RsProgramFragment pf)
647{
648    GET_TLS();
649    rsi_ContextBindProgramFragment(rsc, pf);
650
651}
652
653static void SC_bindProgramVertex(RsProgramVertex pv)
654{
655    GET_TLS();
656    rsi_ContextBindProgramVertex(rsc, pv);
657
658}
659
660//////////////////////////////////////////////////////////////////////////////
661// VP
662//////////////////////////////////////////////////////////////////////////////
663
664static void SC_vpLoadModelMatrix(const rsc_Matrix *m)
665{
666    GET_TLS();
667    rsc->getVertex()->setModelviewMatrix(m);
668}
669
670static void SC_vpLoadTextureMatrix(const rsc_Matrix *m)
671{
672    GET_TLS();
673    rsc->getVertex()->setTextureMatrix(m);
674}
675
676
677
678//////////////////////////////////////////////////////////////////////////////
679// Drawing
680//////////////////////////////////////////////////////////////////////////////
681
682static void SC_drawLine(float x1, float y1, float z1,
683                        float x2, float y2, float z2)
684{
685    GET_TLS();
686    rsc->setupCheck();
687
688    float vtx[] = { x1, y1, z1, x2, y2, z2 };
689    VertexArray va;
690    va.setPosition(2, GL_FLOAT, 12, (uint32_t)&vtx);
691    if (rsc->checkVersion2_0()) {
692        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
693    } else {
694        va.setupGL(rsc, &rsc->mStateVertexArray);
695    }
696
697    glDrawArrays(GL_LINES, 0, 2);
698}
699
700static void SC_drawPoint(float x, float y, float z)
701{
702    GET_TLS();
703    rsc->setupCheck();
704
705    float vtx[] = { x, y, z };
706
707    VertexArray va;
708    va.setPosition(1, GL_FLOAT, 12, (uint32_t)&vtx);
709    if (rsc->checkVersion2_0()) {
710        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
711    } else {
712        va.setupGL(rsc, &rsc->mStateVertexArray);
713    }
714
715    glDrawArrays(GL_POINTS, 0, 1);
716}
717
718static void SC_drawQuadTexCoords(float x1, float y1, float z1,
719                                 float u1, float v1,
720                                 float x2, float y2, float z2,
721                                 float u2, float v2,
722                                 float x3, float y3, float z3,
723                                 float u3, float v3,
724                                 float x4, float y4, float z4,
725                                 float u4, float v4)
726{
727    GET_TLS();
728    rsc->setupCheck();
729
730    //LOGE("Quad");
731    //LOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1);
732    //LOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2);
733    //LOGE("%4.2f, %4.2f, %4.2f", x3, y3, z3);
734    //LOGE("%4.2f, %4.2f, %4.2f", x4, y4, z4);
735
736    float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
737    const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
738
739    VertexArray va;
740    va.setPosition(3, GL_FLOAT, 12, (uint32_t)&vtx);
741    va.setTexture(2, GL_FLOAT, 8, (uint32_t)&tex);
742    if (rsc->checkVersion2_0()) {
743        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
744    } else {
745        va.setupGL(rsc, &rsc->mStateVertexArray);
746    }
747
748
749    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
750}
751
752static void SC_drawQuad(float x1, float y1, float z1,
753                        float x2, float y2, float z2,
754                        float x3, float y3, float z3,
755                        float x4, float y4, float z4)
756{
757    SC_drawQuadTexCoords(x1, y1, z1, 0, 1,
758                         x2, y2, z2, 1, 1,
759                         x3, y3, z3, 1, 0,
760                         x4, y4, z4, 0, 0);
761}
762
763static void SC_drawSpriteScreenspace(float x, float y, float z, float w, float h)
764{
765    GET_TLS();
766    ObjectBaseRef<const ProgramVertex> tmp(rsc->getVertex());
767    rsc->setVertex(rsc->getDefaultProgramVertex());
768    //rsc->setupCheck();
769
770    //GLint crop[4] = {0, h, w, -h};
771
772    float sh = rsc->getHeight();
773
774    SC_drawQuad(x,   sh - y,     z,
775                x+w, sh - y,     z,
776                x+w, sh - (y+h), z,
777                x,   sh - (y+h), z);
778    rsc->setVertex((ProgramVertex *)tmp.get());
779}
780
781static void SC_drawSpriteScreenspaceCropped(float x, float y, float z, float w, float h,
782        float cx0, float cy0, float cx1, float cy1)
783{
784    GET_TLS();
785    rsc->setupCheck();
786
787    GLint crop[4] = {cx0, cy0, cx1, cy1};
788    glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
789    glDrawTexfOES(x, y, z, w, h);
790}
791
792static void SC_drawSprite(float x, float y, float z, float w, float h)
793{
794    GET_TLS();
795    float vin[3] = {x, y, z};
796    float vout[4];
797
798    //LOGE("ds  in %f %f %f", x, y, z);
799    rsc->getVertex()->transformToScreen(rsc, vout, vin);
800    //LOGE("ds  out %f %f %f %f", vout[0], vout[1], vout[2], vout[3]);
801    vout[0] /= vout[3];
802    vout[1] /= vout[3];
803    vout[2] /= vout[3];
804
805    vout[0] *= rsc->getWidth() / 2;
806    vout[1] *= rsc->getHeight() / 2;
807    vout[0] += rsc->getWidth() / 2;
808    vout[1] += rsc->getHeight() / 2;
809
810    vout[0] -= w/2;
811    vout[1] -= h/2;
812
813    //LOGE("ds  out2 %f %f %f", vout[0], vout[1], vout[2]);
814
815    // U, V, W, H
816    SC_drawSpriteScreenspace(vout[0], vout[1], z, h, w);
817    //rsc->setupCheck();
818}
819
820
821static void SC_drawRect(float x1, float y1,
822                        float x2, float y2, float z)
823{
824    SC_drawQuad(x1, y2, z,
825                x2, y2, z,
826                x2, y1, z,
827                x1, y1, z);
828}
829
830static void SC_drawSimpleMesh(RsSimpleMesh vsm)
831{
832    GET_TLS();
833    SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
834    rsc->setupCheck();
835    sm->render(rsc);
836}
837
838static void SC_drawSimpleMeshRange(RsSimpleMesh vsm, uint32_t start, uint32_t len)
839{
840    GET_TLS();
841    SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
842    rsc->setupCheck();
843    sm->renderRange(rsc, start, len);
844}
845
846
847//////////////////////////////////////////////////////////////////////////////
848//
849//////////////////////////////////////////////////////////////////////////////
850
851static void SC_color(float r, float g, float b, float a)
852{
853    GET_TLS();
854    rsc->mStateVertex.color[0] = r;
855    rsc->mStateVertex.color[1] = g;
856    rsc->mStateVertex.color[2] = b;
857    rsc->mStateVertex.color[3] = a;
858    if (!rsc->checkVersion2_0()) {
859        glColor4f(r, g, b, a);
860    }
861}
862
863static void SC_ambient(float r, float g, float b, float a)
864{
865    GLfloat params[] = { r, g, b, a };
866    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, params);
867}
868
869static void SC_diffuse(float r, float g, float b, float a)
870{
871    GLfloat params[] = { r, g, b, a };
872    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, params);
873}
874
875static void SC_specular(float r, float g, float b, float a)
876{
877    GLfloat params[] = { r, g, b, a };
878    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, params);
879}
880
881static void SC_emission(float r, float g, float b, float a)
882{
883    GLfloat params[] = { r, g, b, a };
884    glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, params);
885}
886
887static void SC_shininess(float s)
888{
889    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, s);
890}
891
892static void SC_pointAttenuation(float a, float b, float c)
893{
894    GLfloat params[] = { a, b, c };
895    glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, params);
896}
897
898static void SC_hsbToRgb(float h, float s, float b, float* rgb)
899{
900    float red = 0.0f;
901    float green = 0.0f;
902    float blue = 0.0f;
903
904    float x = h;
905    float y = s;
906    float z = b;
907
908    float hf = (x - (int) x) * 6.0f;
909    int ihf = (int) hf;
910    float f = hf - ihf;
911    float pv = z * (1.0f - y);
912    float qv = z * (1.0f - y * f);
913    float tv = z * (1.0f - y * (1.0f - f));
914
915    switch (ihf) {
916        case 0:         // Red is the dominant color
917            red = z;
918            green = tv;
919            blue = pv;
920            break;
921        case 1:         // Green is the dominant color
922            red = qv;
923            green = z;
924            blue = pv;
925            break;
926        case 2:
927            red = pv;
928            green = z;
929            blue = tv;
930            break;
931        case 3:         // Blue is the dominant color
932            red = pv;
933            green = qv;
934            blue = z;
935            break;
936        case 4:
937            red = tv;
938            green = pv;
939            blue = z;
940            break;
941        case 5:         // Red is the dominant color
942            red = z;
943            green = pv;
944            blue = qv;
945            break;
946    }
947
948    rgb[0] = red;
949    rgb[1] = green;
950    rgb[2] = blue;
951}
952
953static int SC_hsbToAbgr(float h, float s, float b, float a)
954{
955    float rgb[3];
956    SC_hsbToRgb(h, s, b, rgb);
957    return int(a      * 255.0f) << 24 |
958           int(rgb[2] * 255.0f) << 16 |
959           int(rgb[1] * 255.0f) <<  8 |
960           int(rgb[0] * 255.0f);
961}
962
963static void SC_hsb(float h, float s, float b, float a)
964{
965    GET_TLS();
966    float rgb[3];
967    SC_hsbToRgb(h, s, b, rgb);
968    if (rsc->checkVersion2_0()) {
969        glVertexAttrib4f(1, rgb[0], rgb[1], rgb[2], a);
970    } else {
971        glColor4f(rgb[0], rgb[1], rgb[2], a);
972    }
973}
974
975static void SC_uploadToTexture(RsAllocation va, uint32_t baseMipLevel)
976{
977    GET_TLS();
978    rsi_AllocationUploadToTexture(rsc, va, baseMipLevel);
979}
980
981static void SC_uploadToBufferObject(RsAllocation va)
982{
983    GET_TLS();
984    rsi_AllocationUploadToBufferObject(rsc, va);
985}
986
987static void SC_syncToGL(RsAllocation va)
988{
989    GET_TLS();
990    Allocation *a = static_cast<Allocation *>(va);
991
992}
993
994static void SC_ClearColor(float r, float g, float b, float a)
995{
996    //LOGE("c %f %f %f %f", r, g, b, a);
997    GET_TLS();
998    sc->mEnviroment.mClearColor[0] = r;
999    sc->mEnviroment.mClearColor[1] = g;
1000    sc->mEnviroment.mClearColor[2] = b;
1001    sc->mEnviroment.mClearColor[3] = a;
1002}
1003
1004static void SC_debugF(const char *s, float f)
1005{
1006    LOGE("%s %f", s, f);
1007}
1008
1009static void SC_debugHexF(const char *s, float f)
1010{
1011    LOGE("%s 0x%x", s, *((int *) (&f)));
1012}
1013
1014static void SC_debugI32(const char *s, int32_t i)
1015{
1016    LOGE("%s %i", s, i);
1017}
1018
1019static void SC_debugHexI32(const char *s, int32_t i)
1020{
1021    LOGE("%s 0x%x", s, i);
1022}
1023
1024static uint32_t SC_getWidth()
1025{
1026    GET_TLS();
1027    return rsc->getWidth();
1028}
1029
1030static uint32_t SC_getHeight()
1031{
1032    GET_TLS();
1033    return rsc->getHeight();
1034}
1035
1036static uint32_t SC_colorFloatRGBAtoUNorm8(float r, float g, float b, float a)
1037{
1038    uint32_t c = 0;
1039    c |= (uint32_t)(r * 255.f + 0.5f);
1040    c |= ((uint32_t)(g * 255.f + 0.5f)) << 8;
1041    c |= ((uint32_t)(b * 255.f + 0.5f)) << 16;
1042    c |= ((uint32_t)(a * 255.f + 0.5f)) << 24;
1043    return c;
1044}
1045
1046static uint32_t SC_colorFloatRGBAto565(float r, float g, float b)
1047{
1048    uint32_t ir = (uint32_t)(r * 255.f + 0.5f);
1049    uint32_t ig = (uint32_t)(g * 255.f + 0.5f);
1050    uint32_t ib = (uint32_t)(b * 255.f + 0.5f);
1051    return rs888to565(ir, ig, ib);
1052}
1053
1054static uint32_t SC_toClient(void *data, int cmdID, int len, int waitForSpace)
1055{
1056    GET_TLS();
1057    return rsc->sendMessageToClient(data, cmdID, len, waitForSpace != 0);
1058}
1059
1060static void SC_scriptCall(int scriptID)
1061{
1062    GET_TLS();
1063    rsc->runScript((Script *)scriptID, 0);
1064}
1065
1066
1067//////////////////////////////////////////////////////////////////////////////
1068// Class implementation
1069//////////////////////////////////////////////////////////////////////////////
1070
1071ScriptCState::SymbolTable_t ScriptCState::gSyms[] = {
1072    // IO
1073    { "loadI32", (void *)&SC_loadI32,
1074        "int", "(int, int)" },
1075    //{ "loadU32", (void *)&SC_loadU32, "unsigned int", "(int, int)" },
1076    { "loadF", (void *)&SC_loadF,
1077        "float", "(int, int)" },
1078    { "loadArrayF", (void *)&SC_loadArrayF,
1079        "float*", "(int, int)" },
1080    { "loadArrayI32", (void *)&SC_loadArrayI32,
1081        "int*", "(int, int)" },
1082    { "loadVec4", (void *)&SC_loadVec4,
1083        "void", "(int, int, float *)" },
1084    { "loadMatrix", (void *)&SC_loadMatrix,
1085        "void", "(int, int, float *)" },
1086    { "storeI32", (void *)&SC_storeI32,
1087        "void", "(int, int, int)" },
1088    //{ "storeU32", (void *)&SC_storeU32, "void", "(int, int, unsigned int)" },
1089    { "storeF", (void *)&SC_storeF,
1090        "void", "(int, int, float)" },
1091    { "storeVec4", (void *)&SC_storeVec4,
1092        "void", "(int, int, float *)" },
1093    { "storeMatrix", (void *)&SC_storeMatrix,
1094        "void", "(int, int, float *)" },
1095    { "loadSimpleMeshVerticesF", (void *)&SC_loadSimpleMeshVerticesF,
1096        "float*", "(int, int)" },
1097    { "updateSimpleMesh", (void *)&SC_updateSimpleMesh,
1098        "void", "(int)" },
1099
1100    // math
1101    { "modf", (void *)&fmod,
1102        "float", "(float, float)" },
1103    { "abs", (void *)&abs,
1104        "int", "(int)" },
1105    { "absf", (void *)&fabsf,
1106        "float", "(float)" },
1107    { "sinf_fast", (void *)&SC_sinf_fast,
1108        "float", "(float)" },
1109    { "cosf_fast", (void *)&SC_cosf_fast,
1110        "float", "(float)" },
1111    { "sinf", (void *)&sinf,
1112        "float", "(float)" },
1113    { "cosf", (void *)&cosf,
1114        "float", "(float)" },
1115    { "asinf", (void *)&asinf,
1116        "float", "(float)" },
1117    { "acosf", (void *)&acosf,
1118        "float", "(float)" },
1119    { "atanf", (void *)&atanf,
1120        "float", "(float)" },
1121    { "atan2f", (void *)&atan2f,
1122        "float", "(float, float)" },
1123    { "fabsf", (void *)&fabsf,
1124        "float", "(float)" },
1125    { "randf", (void *)&SC_randf,
1126        "float", "(float)" },
1127    { "randf2", (void *)&SC_randf2,
1128        "float", "(float, float)" },
1129    { "floorf", (void *)&floorf,
1130        "float", "(float)" },
1131    { "fracf", (void *)&SC_fracf,
1132        "float", "(float)" },
1133    { "ceilf", (void *)&ceilf,
1134        "float", "(float)" },
1135    { "roundf", (void *)&SC_roundf,
1136        "float", "(float)" },
1137    { "expf", (void *)&expf,
1138        "float", "(float)" },
1139    { "logf", (void *)&logf,
1140        "float", "(float)" },
1141    { "powf", (void *)&powf,
1142        "float", "(float, float)" },
1143    { "maxf", (void *)&SC_maxf,
1144        "float", "(float, float)" },
1145    { "minf", (void *)&SC_minf,
1146        "float", "(float, float)" },
1147    { "sqrt", (void *)&sqrt,
1148        "int", "(int)" },
1149    { "sqrtf", (void *)&sqrtf,
1150        "float", "(float)" },
1151    { "sqr", (void *)&SC_sqr,
1152        "int", "(int)" },
1153    { "sqrf", (void *)&SC_sqrf,
1154        "float", "(float)" },
1155    { "sign", (void *)&SC_sign,
1156        "int", "(int)" },
1157    { "signf", (void *)&SC_signf,
1158        "float", "(float)" },
1159    { "clamp", (void *)&SC_clamp,
1160        "int", "(int, int, int)" },
1161    { "clampf", (void *)&SC_clampf,
1162        "float", "(float, float, float)" },
1163    { "distf2", (void *)&SC_distf2,
1164        "float", "(float, float, float, float)" },
1165    { "distf3", (void *)&SC_distf3,
1166        "float", "(float, float, float, float, float, float)" },
1167    { "magf2", (void *)&SC_magf2,
1168        "float", "(float, float)" },
1169    { "magf3", (void *)&SC_magf3,
1170        "float", "(float, float, float)" },
1171    { "radf", (void *)&SC_radf,
1172        "float", "(float)" },
1173    { "degf", (void *)&SC_degf,
1174        "float", "(float)" },
1175    { "lerpf", (void *)&SC_lerpf,
1176        "float", "(float, float, float)" },
1177    { "normf", (void *)&SC_normf,
1178        "float", "(float, float, float)" },
1179    { "mapf", (void *)&SC_mapf,
1180        "float", "(float, float, float, float, float)" },
1181    { "noisef", (void *)&SC_noisef,
1182        "float", "(float)" },
1183    { "noisef2", (void *)&SC_noisef2,
1184        "float", "(float, float)" },
1185    { "noisef3", (void *)&SC_noisef3,
1186        "float", "(float, float, float)" },
1187    { "turbulencef2", (void *)&SC_turbulencef2,
1188        "float", "(float, float, float)" },
1189    { "turbulencef3", (void *)&SC_turbulencef3,
1190        "float", "(float, float, float, float)" },
1191
1192    // time
1193    { "second", (void *)&SC_second,
1194        "int", "()" },
1195    { "minute", (void *)&SC_minute,
1196        "int", "()" },
1197    { "hour", (void *)&SC_hour,
1198        "int", "()" },
1199    { "day", (void *)&SC_day,
1200        "int", "()" },
1201    { "month", (void *)&SC_month,
1202        "int", "()" },
1203    { "year", (void *)&SC_year,
1204        "int", "()" },
1205    { "uptimeMillis", (void*)&SC_uptimeMillis,
1206        "int", "()" },      // TODO: use long instead
1207    { "startTimeMillis", (void*)&SC_startTimeMillis,
1208        "int", "()" },      // TODO: use long instead
1209    { "elapsedTimeMillis", (void*)&SC_elapsedTimeMillis,
1210        "int", "()" },      // TODO: use long instead
1211
1212    // matrix
1213    { "matrixLoadIdentity", (void *)&SC_matrixLoadIdentity,
1214        "void", "(float *mat)" },
1215    { "matrixLoadFloat", (void *)&SC_matrixLoadFloat,
1216        "void", "(float *mat, float *f)" },
1217    { "matrixLoadMat", (void *)&SC_matrixLoadMat,
1218        "void", "(float *mat, float *newmat)" },
1219    { "matrixLoadRotate", (void *)&SC_matrixLoadRotate,
1220        "void", "(float *mat, float rot, float x, float y, float z)" },
1221    { "matrixLoadScale", (void *)&SC_matrixLoadScale,
1222        "void", "(float *mat, float x, float y, float z)" },
1223    { "matrixLoadTranslate", (void *)&SC_matrixLoadTranslate,
1224        "void", "(float *mat, float x, float y, float z)" },
1225    { "matrixLoadMultiply", (void *)&SC_matrixLoadMultiply,
1226        "void", "(float *mat, float *lhs, float *rhs)" },
1227    { "matrixMultiply", (void *)&SC_matrixMultiply,
1228        "void", "(float *mat, float *rhs)" },
1229    { "matrixRotate", (void *)&SC_matrixRotate,
1230        "void", "(float *mat, float rot, float x, float y, float z)" },
1231    { "matrixScale", (void *)&SC_matrixScale,
1232        "void", "(float *mat, float x, float y, float z)" },
1233    { "matrixTranslate", (void *)&SC_matrixTranslate,
1234        "void", "(float *mat, float x, float y, float z)" },
1235
1236    // vector
1237    { "vec2Rand", (void *)&SC_vec2Rand,
1238        "void", "(float *vec, float maxLen)" },
1239
1240    // vec3
1241    { "vec3Norm", (void *)&SC_vec3Norm,
1242        "void", "(struct vecF32_3_s *)" },
1243    { "vec3Length", (void *)&SC_vec3Length,
1244        "float", "(struct vecF32_3_s *)" },
1245    { "vec3Add", (void *)&SC_vec3Add,
1246        "void", "(struct vecF32_3_s *dest, struct vecF32_3_s *lhs, struct vecF32_3_s *rhs)" },
1247    { "vec3Sub", (void *)&SC_vec3Sub,
1248        "void", "(struct vecF32_3_s *dest, struct vecF32_3_s *lhs, struct vecF32_3_s *rhs)" },
1249    { "vec3Cross", (void *)&SC_vec3Cross,
1250        "void", "(struct vecF32_3_s *dest, struct vecF32_3_s *lhs, struct vecF32_3_s *rhs)" },
1251    { "vec3Dot", (void *)&SC_vec3Dot,
1252        "float", "(struct vecF32_3_s *lhs, struct vecF32_3_s *rhs)" },
1253    { "vec3Scale", (void *)&SC_vec3Scale,
1254        "void", "(struct vecF32_3_s *lhs, float scale)" },
1255
1256    // vec4
1257    { "vec4Norm", (void *)&SC_vec4Norm,
1258        "void", "(struct vecF32_4_s *)" },
1259    { "vec4Length", (void *)&SC_vec4Length,
1260        "float", "(struct vecF32_4_s *)" },
1261    { "vec4Add", (void *)&SC_vec4Add,
1262        "void", "(struct vecF32_4_s *dest, struct vecF32_4_s *lhs, struct vecF32_4_s *rhs)" },
1263    { "vec4Sub", (void *)&SC_vec4Sub,
1264        "void", "(struct vecF32_4_s *dest, struct vecF32_4_s *lhs, struct vecF32_4_s *rhs)" },
1265    { "vec4Dot", (void *)&SC_vec4Dot,
1266        "float", "(struct vecF32_4_s *lhs, struct vecF32_4_s *rhs)" },
1267    { "vec4Scale", (void *)&SC_vec4Scale,
1268        "void", "(struct vecF32_4_s *lhs, float scale)" },
1269
1270    // context
1271    { "bindProgramFragment", (void *)&SC_bindProgramFragment,
1272        "void", "(int)" },
1273    { "bindProgramFragmentStore", (void *)&SC_bindProgramFragmentStore,
1274        "void", "(int)" },
1275    { "bindProgramStore", (void *)&SC_bindProgramFragmentStore,
1276        "void", "(int)" },
1277    { "bindProgramVertex", (void *)&SC_bindProgramVertex,
1278        "void", "(int)" },
1279    { "bindSampler", (void *)&SC_bindSampler,
1280        "void", "(int, int, int)" },
1281    { "bindTexture", (void *)&SC_bindTexture,
1282        "void", "(int, int, int)" },
1283
1284    // vp
1285    { "vpLoadModelMatrix", (void *)&SC_vpLoadModelMatrix,
1286        "void", "(void *)" },
1287    { "vpLoadTextureMatrix", (void *)&SC_vpLoadTextureMatrix,
1288        "void", "(void *)" },
1289
1290
1291
1292    // drawing
1293    { "drawRect", (void *)&SC_drawRect,
1294        "void", "(float x1, float y1, float x2, float y2, float z)" },
1295    { "drawQuad", (void *)&SC_drawQuad,
1296        "void", "(float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4)" },
1297    { "drawQuadTexCoords", (void *)&SC_drawQuadTexCoords,
1298        "void", "(float x1, float y1, float z1, float u1, float v1, float x2, float y2, float z2, float u2, float v2, float x3, float y3, float z3, float u3, float v3, float x4, float y4, float z4, float u4, float v4)" },
1299    { "drawSprite", (void *)&SC_drawSprite,
1300        "void", "(float x, float y, float z, float w, float h)" },
1301    { "drawSpriteScreenspace", (void *)&SC_drawSpriteScreenspace,
1302        "void", "(float x, float y, float z, float w, float h)" },
1303    { "drawSpriteScreenspaceCropped", (void *)&SC_drawSpriteScreenspaceCropped,
1304        "void", "(float x, float y, float z, float w, float h, float cx0, float cy0, float cx1, float cy1)" },
1305    { "drawLine", (void *)&SC_drawLine,
1306        "void", "(float x1, float y1, float z1, float x2, float y2, float z2)" },
1307    { "drawPoint", (void *)&SC_drawPoint,
1308        "void", "(float x1, float y1, float z1)" },
1309    { "drawSimpleMesh", (void *)&SC_drawSimpleMesh,
1310        "void", "(int ism)" },
1311    { "drawSimpleMeshRange", (void *)&SC_drawSimpleMeshRange,
1312        "void", "(int ism, int start, int len)" },
1313
1314
1315    // misc
1316    { "pfClearColor", (void *)&SC_ClearColor,
1317        "void", "(float, float, float, float)" },
1318    { "color", (void *)&SC_color,
1319        "void", "(float, float, float, float)" },
1320    { "hsb", (void *)&SC_hsb,
1321        "void", "(float, float, float, float)" },
1322    { "hsbToRgb", (void *)&SC_hsbToRgb,
1323        "void", "(float, float, float, float*)" },
1324    { "hsbToAbgr", (void *)&SC_hsbToAbgr,
1325        "int", "(float, float, float, float)" },
1326    { "ambient", (void *)&SC_ambient,
1327        "void", "(float, float, float, float)" },
1328    { "diffuse", (void *)&SC_diffuse,
1329        "void", "(float, float, float, float)" },
1330    { "specular", (void *)&SC_specular,
1331        "void", "(float, float, float, float)" },
1332    { "emission", (void *)&SC_emission,
1333        "void", "(float, float, float, float)" },
1334    { "shininess", (void *)&SC_shininess,
1335        "void", "(float)" },
1336    { "pointAttenuation", (void *)&SC_pointAttenuation,
1337        "void", "(float, float, float)" },
1338
1339    { "uploadToTexture", (void *)&SC_uploadToTexture,
1340        "void", "(int, int)" },
1341    { "uploadToBufferObject", (void *)&SC_uploadToBufferObject,
1342        "void", "(int)" },
1343
1344    { "syncToGL", (void *)&SC_syncToGL,
1345        "void", "(int)" },
1346
1347    { "colorFloatRGBAtoUNorm8", (void *)&SC_colorFloatRGBAtoUNorm8,
1348        "int", "(float, float, float, float)" },
1349    { "colorFloatRGBto565", (void *)&SC_colorFloatRGBAto565,
1350        "int", "(float, float, float)" },
1351
1352
1353    { "getWidth", (void *)&SC_getWidth,
1354        "int", "()" },
1355    { "getHeight", (void *)&SC_getHeight,
1356        "int", "()" },
1357
1358    { "sendToClient", (void *)&SC_toClient,
1359        "int", "(void *data, int cmdID, int len, int waitForSpace)" },
1360
1361
1362    { "debugF", (void *)&SC_debugF,
1363        "void", "(void *, float)" },
1364    { "debugI32", (void *)&SC_debugI32,
1365        "void", "(void *, int)" },
1366    { "debugHexF", (void *)&SC_debugHexF,
1367        "void", "(void *, float)" },
1368    { "debugHexI32", (void *)&SC_debugHexI32,
1369        "void", "(void *, int)" },
1370
1371    { "scriptCall", (void *)&SC_scriptCall,
1372        "void", "(int)" },
1373
1374
1375    { NULL, NULL, NULL, NULL }
1376};
1377
1378const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbol(const char *sym)
1379{
1380    ScriptCState::SymbolTable_t *syms = gSyms;
1381
1382    while (syms->mPtr) {
1383        if (!strcmp(syms->mName, sym)) {
1384            return syms;
1385        }
1386        syms++;
1387    }
1388    return NULL;
1389}
1390
1391void ScriptCState::appendDecls(String8 *str)
1392{
1393    ScriptCState::SymbolTable_t *syms = gSyms;
1394    while (syms->mPtr) {
1395        str->append(syms->mRet);
1396        str->append(" ");
1397        str->append(syms->mName);
1398        str->append(syms->mParam);
1399        str->append(";\n");
1400        syms++;
1401    }
1402}
1403
1404
1405