rsScriptC_Lib.cpp revision ce92d4baf7a5bce097228fdd4498601764cd4014
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
42
43static float SC_acospi(float v) {
44    return acosf(v)/ M_PI;
45}
46
47static float SC_asinpi(float v) {
48    return asinf(v) / M_PI;
49}
50
51static float SC_atanpi(float v) {
52    return atanf(v) / M_PI;
53}
54
55static float SC_atan2pi(float y, float x) {
56    return atan2f(y, x) / M_PI;
57}
58
59static float SC_cospi(float v) {
60    return cosf(v * M_PI);
61}
62
63static float SC_exp10(float v) {
64    return pow(10.f, v);
65
66}
67
68static float SC_fract(float v, int *iptr) {
69    int i = (int)floor(v);
70    iptr[0] = i;
71    return fmin(v - i, 0x1.fffffep-1f);
72}
73
74static float SC_log2(float v) {
75    return log10(v) / log10(2.f);
76}
77
78static float SC_pown(float v, int p) {
79    return powf(v, (float)p);
80}
81
82static float SC_powr(float v, float p) {
83    return powf(v, p);
84}
85
86float SC_rootn(float v, int r) {
87    return pow(v, 1.f / r);
88}
89
90float SC_rsqrt(float v) {
91    return 1.f / sqrtf(v);
92}
93
94float SC_sincos(float v, float *cosptr) {
95    *cosptr = cosf(v);
96    return sinf(v);
97}
98
99static float SC_sinpi(float v) {
100    return sinf(v * M_PI);
101}
102
103static float SC_tanpi(float v) {
104    return tanf(v * M_PI);
105}
106
107    //{ "logb", (void *)& },
108    //{ "mad", (void *)& },
109    //{ "nan", (void *)& },
110    //{ "tgamma", (void *)& },
111
112//////////////////////////////////////////////////////////////////////////////
113// Integer
114//////////////////////////////////////////////////////////////////////////////
115
116
117static uint32_t SC_abs_i32(int32_t v) {return abs(v);}
118static uint16_t SC_abs_i16(int16_t v) {return (uint16_t)abs(v);}
119static uint8_t SC_abs_i8(int8_t v) {return (uint8_t)abs(v);}
120
121static uint32_t SC_clz_u32(uint32_t v) {return __builtin_clz(v);}
122static uint16_t SC_clz_u16(uint16_t v) {return (uint16_t)__builtin_clz(v);}
123static uint8_t SC_clz_u8(uint8_t v) {return (uint8_t)__builtin_clz(v);}
124static int32_t SC_clz_i32(int32_t v) {return (int32_t)__builtin_clz((uint32_t)v);}
125static int16_t SC_clz_i16(int16_t v) {return (int16_t)__builtin_clz(v);}
126static int8_t SC_clz_i8(int8_t v) {return (int8_t)__builtin_clz(v);}
127
128static uint32_t SC_max_u32(uint32_t v, uint32_t v2) {return rsMax(v, v2);}
129static uint16_t SC_max_u16(uint16_t v, uint16_t v2) {return rsMax(v, v2);}
130static uint8_t SC_max_u8(uint8_t v, uint8_t v2) {return rsMax(v, v2);}
131static int32_t SC_max_i32(int32_t v, int32_t v2) {return rsMax(v, v2);}
132static int16_t SC_max_i16(int16_t v, int16_t v2) {return rsMax(v, v2);}
133static int8_t SC_max_i8(int8_t v, int8_t v2) {return rsMax(v, v2);}
134
135static uint32_t SC_min_u32(uint32_t v, uint32_t v2) {return rsMin(v, v2);}
136static uint16_t SC_min_u16(uint16_t v, uint16_t v2) {return rsMin(v, v2);}
137static uint8_t SC_min_u8(uint8_t v, uint8_t v2) {return rsMin(v, v2);}
138static int32_t SC_min_i32(int32_t v, int32_t v2) {return rsMin(v, v2);}
139static int16_t SC_min_i16(int16_t v, int16_t v2) {return rsMin(v, v2);}
140static int8_t SC_min_i8(int8_t v, int8_t v2) {return rsMin(v, v2);}
141
142//////////////////////////////////////////////////////////////////////////////
143// Float util
144//////////////////////////////////////////////////////////////////////////////
145
146static float SC_clamp_f32(float amount, float low, float high)
147{
148    return amount < low ? low : (amount > high ? high : amount);
149}
150
151static float SC_degrees(float radians)
152{
153    return radians * (180.f / M_PI);
154}
155
156static float SC_max_f32(float v, float v2)
157{
158    return rsMax(v, v2);
159}
160
161static float SC_min_f32(float v, float v2)
162{
163    return rsMin(v, v2);
164}
165
166static float SC_mix_f32(float start, float stop, float amount)
167{
168    //LOGE("lerpf %f  %f  %f", start, stop, amount);
169    return start + (stop - start) * amount;
170}
171
172static float SC_radians(float degrees)
173{
174    return degrees * (M_PI / 180.f);
175}
176
177static float SC_step_f32(float edge, float v)
178{
179    if (v < edge) return 0.f;
180    return 1.f;
181}
182
183static float SC_sign_f32(float value)
184{
185    if (value > 0) return 1.f;
186    if (value < 0) return -1.f;
187    return value;
188}
189
190
191
192//////////////////////////////////////////////////////////////////////////////
193// Non-Updated code below
194//////////////////////////////////////////////////////////////////////////////
195
196typedef struct {
197    float x;
198    float y;
199    float z;
200} vec3_t;
201
202typedef struct {
203    float x;
204    float y;
205    float z;
206    float w;
207} vec4_t;
208
209typedef struct {
210    float x;
211    float y;
212} vec2_t;
213
214//////////////////////////////////////////////////////////////////////////////
215// IO routines
216//////////////////////////////////////////////////////////////////////////////
217
218static void SC_updateSimpleMesh(RsSimpleMesh mesh)
219{
220    GET_TLS();
221    SimpleMesh *sm = static_cast<SimpleMesh *>(mesh);
222    sm->uploadAll(rsc);
223}
224
225//////////////////////////////////////////////////////////////////////////////
226// Vec3 routines
227//////////////////////////////////////////////////////////////////////////////
228
229static void SC_vec3Norm(vec3_t *v)
230{
231    float len = sqrtf(v->x * v->x + v->y * v->y + v->z * v->z);
232    len = 1 / len;
233    v->x *= len;
234    v->y *= len;
235    v->z *= len;
236}
237
238static float SC_vec3Length(const vec3_t *v)
239{
240    return sqrtf(v->x * v->x + v->y * v->y + v->z * v->z);
241}
242
243static void SC_vec3Add(vec3_t *dest, const vec3_t *lhs, const vec3_t *rhs)
244{
245    dest->x = lhs->x + rhs->x;
246    dest->y = lhs->y + rhs->y;
247    dest->z = lhs->z + rhs->z;
248}
249
250static void SC_vec3Sub(vec3_t *dest, const vec3_t *lhs, const vec3_t *rhs)
251{
252    dest->x = lhs->x - rhs->x;
253    dest->y = lhs->y - rhs->y;
254    dest->z = lhs->z - rhs->z;
255}
256
257static void SC_vec3Cross(vec3_t *dest, const vec3_t *lhs, const vec3_t *rhs)
258{
259    float x = lhs->y * rhs->z  - lhs->z * rhs->y;
260    float y = lhs->z * rhs->x  - lhs->x * rhs->z;
261    float z = lhs->x * rhs->y  - lhs->y * rhs->x;
262    dest->x = x;
263    dest->y = y;
264    dest->z = z;
265}
266
267static float SC_vec3Dot(const vec3_t *lhs, const vec3_t *rhs)
268{
269    return lhs->x * rhs->x + lhs->y * rhs->y + lhs->z * rhs->z;
270}
271
272static void SC_vec3Scale(vec3_t *lhs, float scale)
273{
274    lhs->x *= scale;
275    lhs->y *= scale;
276    lhs->z *= scale;
277}
278
279//////////////////////////////////////////////////////////////////////////////
280// Vec4 routines
281//////////////////////////////////////////////////////////////////////////////
282
283static void SC_vec4Norm(vec4_t *v)
284{
285    float len = sqrtf(v->x * v->x + v->y * v->y + v->z * v->z + v->w * v->w);
286    len = 1 / len;
287    v->x *= len;
288    v->y *= len;
289    v->z *= len;
290    v->w *= len;
291}
292
293static float SC_vec4Length(const vec4_t *v)
294{
295    return sqrtf(v->x * v->x + v->y * v->y + v->z * v->z + v->w * v->w);
296}
297
298static void SC_vec4Add(vec4_t *dest, const vec4_t *lhs, const vec4_t *rhs)
299{
300    dest->x = lhs->x + rhs->x;
301    dest->y = lhs->y + rhs->y;
302    dest->z = lhs->z + rhs->z;
303    dest->w = lhs->w + rhs->w;
304}
305
306static void SC_vec4Sub(vec4_t *dest, const vec4_t *lhs, const vec4_t *rhs)
307{
308    dest->x = lhs->x - rhs->x;
309    dest->y = lhs->y - rhs->y;
310    dest->z = lhs->z - rhs->z;
311    dest->w = lhs->w - rhs->w;
312}
313
314static float SC_vec4Dot(const vec4_t *lhs, const vec4_t *rhs)
315{
316    return lhs->x * rhs->x + lhs->y * rhs->y + lhs->z * rhs->z + lhs->w * rhs->w;
317}
318
319static void SC_vec4Scale(vec4_t *lhs, float scale)
320{
321    lhs->x *= scale;
322    lhs->y *= scale;
323    lhs->z *= scale;
324    lhs->w *= scale;
325}
326
327//////////////////////////////////////////////////////////////////////////////
328// Math routines
329//////////////////////////////////////////////////////////////////////////////
330
331static float SC_sinf_fast(float x)
332{
333    const float A =   1.0f / (2.0f * M_PI);
334    const float B = -16.0f;
335    const float C =   8.0f;
336
337    // scale angle for easy argument reduction
338    x *= A;
339
340    if (fabsf(x) >= 0.5f) {
341        // argument reduction
342        x = x - ceilf(x + 0.5f) + 1.0f;
343    }
344
345    const float y = B * x * fabsf(x) + C * x;
346    return 0.2215f * (y * fabsf(y) - y) + y;
347}
348
349static float SC_cosf_fast(float x)
350{
351    x += float(M_PI / 2);
352
353    const float A =   1.0f / (2.0f * M_PI);
354    const float B = -16.0f;
355    const float C =   8.0f;
356
357    // scale angle for easy argument reduction
358    x *= A;
359
360    if (fabsf(x) >= 0.5f) {
361        // argument reduction
362        x = x - ceilf(x + 0.5f) + 1.0f;
363    }
364
365    const float y = B * x * fabsf(x) + C * x;
366    return 0.2215f * (y * fabsf(y) - y) + y;
367}
368
369static float SC_randf(float max)
370{
371    //LOGE("max %f", max);
372    float r = (float)rand();
373    return r / RAND_MAX * max;
374}
375
376static float SC_randf2(float min, float max)
377{
378    float r = (float)rand();
379    return r / RAND_MAX * (max - min) + min;
380}
381
382static int SC_sign(int value)
383{
384    return (value > 0) - (value < 0);
385}
386
387static int SC_clamp(int amount, int low, int high)
388{
389    return amount < low ? low : (amount > high ? high : amount);
390}
391
392static float SC_roundf(float v)
393{
394    return floorf(v + 0.4999999999);
395}
396
397static float SC_distf2(float x1, float y1, float x2, float y2)
398{
399    float x = x2 - x1;
400    float y = y2 - y1;
401    return sqrtf(x * x + y * y);
402}
403
404static float SC_distf3(float x1, float y1, float z1, float x2, float y2, float z2)
405{
406    float x = x2 - x1;
407    float y = y2 - y1;
408    float z = z2 - z1;
409    return sqrtf(x * x + y * y + z * z);
410}
411
412static float SC_magf2(float a, float b)
413{
414    return sqrtf(a * a + b * b);
415}
416
417static float SC_magf3(float a, float b, float c)
418{
419    return sqrtf(a * a + b * b + c * c);
420}
421
422static float SC_normf(float start, float stop, float value)
423{
424    return (value - start) / (stop - start);
425}
426
427static float SC_mapf(float minStart, float minStop, float maxStart, float maxStop, float value)
428{
429    return maxStart + (maxStart - maxStop) * ((value - minStart) / (minStop - minStart));
430}
431
432static float SC_frac(float v)
433{
434    int i = (int)floor(v);
435    return fmin(v - i, 0x1.fffffep-1f);
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 rsvF_2 SC_vec2Rand(float maxLen)
606{
607    float2 t;
608    float angle = SC_randf(M_PI * 2);
609    float len = SC_randf(maxLen);
610    t.f[0] = len * sinf(angle);
611    t.f[1] = len * cosf(angle);
612    return t.v;
613}
614
615
616
617//////////////////////////////////////////////////////////////////////////////
618// Context
619//////////////////////////////////////////////////////////////////////////////
620
621static void SC_bindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va)
622{
623    GET_TLS();
624    rsi_ProgramBindTexture(rsc,
625                           static_cast<ProgramFragment *>(vpf),
626                           slot,
627                           static_cast<Allocation *>(va));
628
629}
630
631static void SC_bindSampler(RsProgramFragment vpf, uint32_t slot, RsSampler vs)
632{
633    GET_TLS();
634    rsi_ProgramBindSampler(rsc,
635                           static_cast<ProgramFragment *>(vpf),
636                           slot,
637                           static_cast<Sampler *>(vs));
638
639}
640
641static void SC_bindProgramStore(RsProgramStore pfs)
642{
643    GET_TLS();
644    rsi_ContextBindProgramStore(rsc, pfs);
645}
646
647static void SC_bindProgramFragment(RsProgramFragment pf)
648{
649    GET_TLS();
650    rsi_ContextBindProgramFragment(rsc, pf);
651}
652
653static void SC_bindProgramVertex(RsProgramVertex pv)
654{
655    GET_TLS();
656    rsi_ContextBindProgramVertex(rsc, pv);
657}
658
659static void SC_bindProgramRaster(RsProgramRaster pv)
660{
661    GET_TLS();
662    rsi_ContextBindProgramRaster(rsc, pv);
663}
664
665//////////////////////////////////////////////////////////////////////////////
666// VP
667//////////////////////////////////////////////////////////////////////////////
668
669static void SC_vpLoadModelMatrix(const rsc_Matrix *m)
670{
671    GET_TLS();
672    rsc->getVertex()->setModelviewMatrix(m);
673}
674
675static void SC_vpLoadTextureMatrix(const rsc_Matrix *m)
676{
677    GET_TLS();
678    rsc->getVertex()->setTextureMatrix(m);
679}
680
681
682
683//////////////////////////////////////////////////////////////////////////////
684// Drawing
685//////////////////////////////////////////////////////////////////////////////
686
687static void SC_drawLine(float x1, float y1, float z1,
688                        float x2, float y2, float z2)
689{
690    GET_TLS();
691    if (!rsc->setupCheck()) {
692        return;
693    }
694
695    float vtx[] = { x1, y1, z1, x2, y2, z2 };
696    VertexArray va;
697    va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx);
698    if (rsc->checkVersion2_0()) {
699        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
700    } else {
701        va.setupGL(rsc, &rsc->mStateVertexArray);
702    }
703
704    glDrawArrays(GL_LINES, 0, 2);
705}
706
707static void SC_drawPoint(float x, float y, float z)
708{
709    GET_TLS();
710    if (!rsc->setupCheck()) {
711        return;
712    }
713
714    float vtx[] = { x, y, z };
715
716    VertexArray va;
717    va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx);
718    if (rsc->checkVersion2_0()) {
719        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
720    } else {
721        va.setupGL(rsc, &rsc->mStateVertexArray);
722    }
723
724    glDrawArrays(GL_POINTS, 0, 1);
725}
726
727static void SC_drawQuadTexCoords(float x1, float y1, float z1,
728                                 float u1, float v1,
729                                 float x2, float y2, float z2,
730                                 float u2, float v2,
731                                 float x3, float y3, float z3,
732                                 float u3, float v3,
733                                 float x4, float y4, float z4,
734                                 float u4, float v4)
735{
736    GET_TLS();
737    if (!rsc->setupCheck()) {
738        return;
739    }
740
741    //LOGE("Quad");
742    //LOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1);
743    //LOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2);
744    //LOGE("%4.2f, %4.2f, %4.2f", x3, y3, z3);
745    //LOGE("%4.2f, %4.2f, %4.2f", x4, y4, z4);
746
747    float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
748    const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
749
750    VertexArray va;
751    va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx);
752    va.addLegacy(GL_FLOAT, 2, 8, RS_KIND_TEXTURE, false, (uint32_t)tex);
753    if (rsc->checkVersion2_0()) {
754        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
755    } else {
756        va.setupGL(rsc, &rsc->mStateVertexArray);
757    }
758
759
760    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
761}
762
763static void SC_drawQuad(float x1, float y1, float z1,
764                        float x2, float y2, float z2,
765                        float x3, float y3, float z3,
766                        float x4, float y4, float z4)
767{
768    SC_drawQuadTexCoords(x1, y1, z1, 0, 1,
769                         x2, y2, z2, 1, 1,
770                         x3, y3, z3, 1, 0,
771                         x4, y4, z4, 0, 0);
772}
773
774static void SC_drawSpriteScreenspace(float x, float y, float z, float w, float h)
775{
776    GET_TLS();
777    ObjectBaseRef<const ProgramVertex> tmp(rsc->getVertex());
778    rsc->setVertex(rsc->getDefaultProgramVertex());
779    //rsc->setupCheck();
780
781    //GLint crop[4] = {0, h, w, -h};
782
783    float sh = rsc->getHeight();
784
785    SC_drawQuad(x,   sh - y,     z,
786                x+w, sh - y,     z,
787                x+w, sh - (y+h), z,
788                x,   sh - (y+h), z);
789    rsc->setVertex((ProgramVertex *)tmp.get());
790}
791
792static void SC_drawSpriteScreenspaceCropped(float x, float y, float z, float w, float h,
793        float cx0, float cy0, float cx1, float cy1)
794{
795    GET_TLS();
796    if (!rsc->setupCheck()) {
797        return;
798    }
799
800    GLint crop[4] = {cx0, cy0, cx1, cy1};
801    glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
802    glDrawTexfOES(x, y, z, w, h);
803}
804
805static void SC_drawSprite(float x, float y, float z, float w, float h)
806{
807    GET_TLS();
808    float vin[3] = {x, y, z};
809    float vout[4];
810
811    //LOGE("ds  in %f %f %f", x, y, z);
812    rsc->getVertex()->transformToScreen(rsc, vout, vin);
813    //LOGE("ds  out %f %f %f %f", vout[0], vout[1], vout[2], vout[3]);
814    vout[0] /= vout[3];
815    vout[1] /= vout[3];
816    vout[2] /= vout[3];
817
818    vout[0] *= rsc->getWidth() / 2;
819    vout[1] *= rsc->getHeight() / 2;
820    vout[0] += rsc->getWidth() / 2;
821    vout[1] += rsc->getHeight() / 2;
822
823    vout[0] -= w/2;
824    vout[1] -= h/2;
825
826    //LOGE("ds  out2 %f %f %f", vout[0], vout[1], vout[2]);
827
828    // U, V, W, H
829    SC_drawSpriteScreenspace(vout[0], vout[1], z, h, w);
830    //rsc->setupCheck();
831}
832
833
834static void SC_drawRect(float x1, float y1,
835                        float x2, float y2, float z)
836{
837    //LOGE("SC_drawRect %f,%f  %f,%f  %f", x1, y1, x2, y2, z);
838    SC_drawQuad(x1, y2, z,
839                x2, y2, z,
840                x2, y1, z,
841                x1, y1, z);
842}
843
844static void SC_drawSimpleMesh(RsSimpleMesh vsm)
845{
846    GET_TLS();
847    SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
848    if (!rsc->setupCheck()) {
849        return;
850    }
851    sm->render(rsc);
852}
853
854static void SC_drawSimpleMeshRange(RsSimpleMesh vsm, uint32_t start, uint32_t len)
855{
856    GET_TLS();
857    SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
858    if (!rsc->setupCheck()) {
859        return;
860    }
861    sm->renderRange(rsc, start, len);
862}
863
864
865//////////////////////////////////////////////////////////////////////////////
866//
867//////////////////////////////////////////////////////////////////////////////
868
869static uint32_t SC_allocGetDimX(RsAllocation va)
870{
871    GET_TLS();
872    const Allocation *a = static_cast<const Allocation *>(va);
873    //LOGE("SC_allocGetDimX a=%p", a);
874    //LOGE(" type=%p", a->getType());
875    return a->getType()->getDimX();
876}
877
878static uint32_t SC_allocGetDimY(RsAllocation va)
879{
880    GET_TLS();
881    const Allocation *a = static_cast<const Allocation *>(va);
882    return a->getType()->getDimY();
883}
884
885static uint32_t SC_allocGetDimZ(RsAllocation va)
886{
887    GET_TLS();
888    const Allocation *a = static_cast<const Allocation *>(va);
889    return a->getType()->getDimZ();
890}
891
892static uint32_t SC_allocGetDimLOD(RsAllocation va)
893{
894    GET_TLS();
895    const Allocation *a = static_cast<const Allocation *>(va);
896    return a->getType()->getDimLOD();
897}
898
899static uint32_t SC_allocGetDimFaces(RsAllocation va)
900{
901    GET_TLS();
902    const Allocation *a = static_cast<const Allocation *>(va);
903    return a->getType()->getDimFaces();
904}
905
906
907static void SC_color(float r, float g, float b, float a)
908{
909    GET_TLS();
910    rsc->mStateVertex.color[0] = r;
911    rsc->mStateVertex.color[1] = g;
912    rsc->mStateVertex.color[2] = b;
913    rsc->mStateVertex.color[3] = a;
914    if (!rsc->checkVersion2_0()) {
915        glColor4f(r, g, b, a);
916    }
917}
918
919static void SC_pointAttenuation(float a, float b, float c)
920{
921    GLfloat params[] = { a, b, c };
922    glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, params);
923}
924
925static void SC_hsbToRgb(float h, float s, float b, float* rgb)
926{
927    float red = 0.0f;
928    float green = 0.0f;
929    float blue = 0.0f;
930
931    float x = h;
932    float y = s;
933    float z = b;
934
935    float hf = (x - (int) x) * 6.0f;
936    int ihf = (int) hf;
937    float f = hf - ihf;
938    float pv = z * (1.0f - y);
939    float qv = z * (1.0f - y * f);
940    float tv = z * (1.0f - y * (1.0f - f));
941
942    switch (ihf) {
943        case 0:         // Red is the dominant color
944            red = z;
945            green = tv;
946            blue = pv;
947            break;
948        case 1:         // Green is the dominant color
949            red = qv;
950            green = z;
951            blue = pv;
952            break;
953        case 2:
954            red = pv;
955            green = z;
956            blue = tv;
957            break;
958        case 3:         // Blue is the dominant color
959            red = pv;
960            green = qv;
961            blue = z;
962            break;
963        case 4:
964            red = tv;
965            green = pv;
966            blue = z;
967            break;
968        case 5:         // Red is the dominant color
969            red = z;
970            green = pv;
971            blue = qv;
972            break;
973    }
974
975    rgb[0] = red;
976    rgb[1] = green;
977    rgb[2] = blue;
978}
979
980static int SC_hsbToAbgr(float h, float s, float b, float a)
981{
982    //LOGE("hsb a %f, %f, %f    %f", h, s, b, a);
983    float rgb[3];
984    SC_hsbToRgb(h, s, b, rgb);
985    //LOGE("rgb  %f, %f, %f ", rgb[0], rgb[1], rgb[2]);
986    return int(a      * 255.0f) << 24 |
987           int(rgb[2] * 255.0f) << 16 |
988           int(rgb[1] * 255.0f) <<  8 |
989           int(rgb[0] * 255.0f);
990}
991
992static void SC_hsb(float h, float s, float b, float a)
993{
994    GET_TLS();
995    float rgb[3];
996    SC_hsbToRgb(h, s, b, rgb);
997    if (rsc->checkVersion2_0()) {
998        glVertexAttrib4f(1, rgb[0], rgb[1], rgb[2], a);
999    } else {
1000        glColor4f(rgb[0], rgb[1], rgb[2], a);
1001    }
1002}
1003
1004static void SC_uploadToTexture(RsAllocation va, uint32_t baseMipLevel)
1005{
1006    GET_TLS();
1007    rsi_AllocationUploadToTexture(rsc, va, false, baseMipLevel);
1008}
1009
1010static void SC_uploadToBufferObject(RsAllocation va)
1011{
1012    GET_TLS();
1013    rsi_AllocationUploadToBufferObject(rsc, va);
1014}
1015
1016static void SC_syncToGL(RsAllocation va)
1017{
1018    GET_TLS();
1019    Allocation *a = static_cast<Allocation *>(va);
1020
1021}
1022
1023static void SC_ClearColor(float r, float g, float b, float a)
1024{
1025    //LOGE("c %f %f %f %f", r, g, b, a);
1026    GET_TLS();
1027    sc->mEnviroment.mClearColor[0] = r;
1028    sc->mEnviroment.mClearColor[1] = g;
1029    sc->mEnviroment.mClearColor[2] = b;
1030    sc->mEnviroment.mClearColor[3] = a;
1031}
1032
1033static void SC_debugF(const char *s, float f)
1034{
1035    LOGE("%s %f", s, f);
1036}
1037
1038static void SC_debugHexF(const char *s, float f)
1039{
1040    LOGE("%s 0x%x", s, *((int *) (&f)));
1041}
1042
1043static void SC_debugI32(const char *s, int32_t i)
1044{
1045    LOGE("%s %i", s, i);
1046}
1047
1048static void SC_debugHexI32(const char *s, int32_t i)
1049{
1050    LOGE("%s 0x%x", s, i);
1051}
1052
1053static uint32_t SC_getWidth()
1054{
1055    GET_TLS();
1056    return rsc->getWidth();
1057}
1058
1059static uint32_t SC_getHeight()
1060{
1061    GET_TLS();
1062    return rsc->getHeight();
1063}
1064
1065static uchar4 SC_convertColorTo8888_f3(float r, float g, float b) {
1066    uchar4 t;
1067    t.f[0] = (uint8_t)(r * 255.f);
1068    t.f[1] = (uint8_t)(g * 255.f);
1069    t.f[2] = (uint8_t)(b * 255.f);
1070    t.f[3] = 0xff;
1071    return t;
1072}
1073
1074static uchar4 SC_convertColorTo8888_f4(float r, float g, float b, float a) {
1075    uchar4 t;
1076    t.f[0] = (uint8_t)(r * 255.f);
1077    t.f[1] = (uint8_t)(g * 255.f);
1078    t.f[2] = (uint8_t)(b * 255.f);
1079    t.f[3] = (uint8_t)(a * 255.f);
1080    return t;
1081}
1082
1083static uint32_t SC_toClient(void *data, int cmdID, int len, int waitForSpace)
1084{
1085    GET_TLS();
1086    //LOGE("SC_toClient %i %i %i", cmdID, len, waitForSpace);
1087    return rsc->sendMessageToClient(data, cmdID, len, waitForSpace != 0);
1088}
1089
1090static void SC_scriptCall(int scriptID)
1091{
1092    GET_TLS();
1093    rsc->runScript((Script *)scriptID, 0);
1094}
1095
1096static void SC_debugP(int i, void *p)
1097{
1098    LOGE("debug P  %i  %p, %i", i, p, (int)p);
1099}
1100
1101static void SC_debugPi(int i, int p)
1102{
1103    LOGE("debug Pi %i  0x%08x, %i", i, p, (int)p);
1104}
1105
1106static void SC_debugPf(int i, float p)
1107{
1108    LOGE("debug Pf  %i  %f,   0x%08x", i, p, reinterpret_cast<uint32_t *>(&p)[0]);
1109}
1110
1111int SC_divsi3(int a, int b)
1112{
1113    return a / b;
1114}
1115
1116int SC_getAllocation(const void *ptr)
1117{
1118    GET_TLS();
1119    const Allocation *alloc = sc->ptrToAllocation(ptr);
1120    return (int)alloc;
1121}
1122
1123
1124//////////////////////////////////////////////////////////////////////////////
1125// Class implementation
1126//////////////////////////////////////////////////////////////////////////////
1127
1128// llvm name mangling ref
1129//  <builtin-type> ::= v  # void
1130//                 ::= b  # bool
1131//                 ::= c  # char
1132//                 ::= a  # signed char
1133//                 ::= h  # unsigned char
1134//                 ::= s  # short
1135//                 ::= t  # unsigned short
1136//                 ::= i  # int
1137//                 ::= j  # unsigned int
1138//                 ::= l  # long
1139//                 ::= m  # unsigned long
1140//                 ::= x  # long long, __int64
1141//                 ::= y  # unsigned long long, __int64
1142//                 ::= f  # float
1143//                 ::= d  # double
1144
1145ScriptCState::SymbolTable_t ScriptCState::gSyms[] = {
1146    { "__divsi3", (void *)&SC_divsi3 },
1147
1148    // IO
1149    { "updateSimpleMesh", (void *)&SC_updateSimpleMesh },
1150
1151    // OpenCL math
1152    { "_Z4acosf", (void *)&acosf },
1153    { "_Z5acoshf", (void *)&acoshf },
1154    { "_Z6acospif", (void *)&SC_acospi },
1155    { "_Z4asinf", (void *)&asinf },
1156    { "_Z5asinhf", (void *)&asinhf },
1157    { "_Z6asinpif", (void *)&SC_asinpi },
1158    { "_Z4atanf", (void *)&atanf },
1159    { "_Z5atan2f", (void *)&atan2f },
1160    { "_Z6atanpif", (void *)&SC_atanpi },
1161    { "_Z7atan2pif", (void *)&SC_atan2pi },
1162    { "_Z4cbrtf", (void *)&cbrtf },
1163    { "_Z4ceilf", (void *)&ceilf },
1164    { "_Z8copysignff", (void *)&copysignf },
1165    { "_Z3cosf", (void *)&cosf },
1166    { "_Z4coshf", (void *)&coshf },
1167    { "_Z5cospif", (void *)&SC_cospi },
1168    { "_Z4erfcf", (void *)&erfcf },
1169    { "_Z3erff", (void *)&erff },
1170    { "_Z3expf", (void *)&expf },
1171    { "_Z4exp2f", (void *)&exp2f },
1172    { "_Z5exp10f", (void *)&SC_exp10 },
1173    { "_Z5expm1f", (void *)&expm1f },
1174    { "_Z4fabsf", (void *)&fabsf },
1175    { "_Z4fdimff", (void *)&fdimf },
1176    { "_Z5floorf", (void *)&floorf },
1177    { "_Z3fmafff", (void *)&fmaf },
1178    { "_Z4fmaxff", (void *)&fmaxf },
1179    { "_Z4fminff", (void *)&fminf },  // float fmin(float, float)
1180    { "_Z4fmodff", (void *)&fmodf },
1181    { "_Z5fractfPf", (void *)&SC_fract },
1182    { "_Z5frexpfPi", (void *)&frexpf },
1183    { "_Z5hypotff", (void *)&hypotf },
1184    { "_Z5ilogbf", (void *)&ilogbf },
1185    { "_Z5ldexpfi", (void *)&ldexpf },
1186    { "_Z6lgammaf", (void *)&lgammaf },
1187    { "_Z3logf", (void *)&logf },
1188    { "_Z4log2f", (void *)&SC_log2 },
1189    { "_Z5log10f", (void *)&log10f },
1190    { "_Z5log1pf", (void *)&log1pf },
1191    //{ "logb", (void *)& },
1192    //{ "mad", (void *)& },
1193    { "modf", (void *)&modff },
1194    //{ "nan", (void *)& },
1195    { "_Z9nextafterff", (void *)&nextafterf },
1196    { "_Z3powff", (void *)&powf },
1197    { "_Z4pownfi", (void *)&SC_pown },
1198    { "_Z4powrff", (void *)&SC_powr },
1199    { "_Z9remainderff", (void *)&remainderf },
1200    { "remquo", (void *)&remquof },
1201    { "_Z4rintf", (void *)&rintf },
1202    { "_Z5rootnfi", (void *)&SC_rootn },
1203    { "_Z5roundf", (void *)&roundf },
1204    { "_Z5rsqrtf", (void *)&SC_rsqrt },
1205    { "_Z3sinf", (void *)&sinf },
1206    { "sincos", (void *)&SC_sincos },
1207    { "_Z4sinhf", (void *)&sinhf },
1208    { "_Z5sinpif", (void *)&SC_sinpi },
1209    { "_Z4sqrtf", (void *)&sqrtf },
1210    { "_Z3tanf", (void *)&tanf },
1211    { "_Z4tanhf", (void *)&tanhf },
1212    { "_Z5tanpif", (void *)&SC_tanpi },
1213    //{ "tgamma", (void *)& },
1214    { "_Z5truncf", (void *)&truncf },
1215
1216    // OpenCL Int
1217    { "_Z3absi", (void *)&SC_abs_i32 },
1218    { "_Z3abss", (void *)&SC_abs_i16 },
1219    { "_Z3absc", (void *)&SC_abs_i8 },
1220    { "_Z3clzj", (void *)&SC_clz_u32 },
1221    { "_Z3clzt", (void *)&SC_clz_u16 },
1222    { "_Z3clzh", (void *)&SC_clz_u8 },
1223    { "_Z3clzi", (void *)&SC_clz_i32 },
1224    { "_Z3clzs", (void *)&SC_clz_i16 },
1225    { "_Z3clzc", (void *)&SC_clz_i8 },
1226    { "_Z3maxjj", (void *)&SC_max_u32 },
1227    { "_Z3maxtt", (void *)&SC_max_u16 },
1228    { "_Z3maxhh", (void *)&SC_max_u8 },
1229    { "_Z3maxii", (void *)&SC_max_i32 },
1230    { "_Z3maxss", (void *)&SC_max_i16 },
1231    { "_Z3maxcc", (void *)&SC_max_i8 },
1232    { "_Z3minjj", (void *)&SC_min_u32 },
1233    { "_Z3mintt", (void *)&SC_min_u16 },
1234    { "_Z3minhh", (void *)&SC_min_u8 },
1235    { "_Z3minii", (void *)&SC_min_i32 },
1236    { "_Z3minss", (void *)&SC_min_i16 },
1237    { "_Z3mincc", (void *)&SC_min_i8 },
1238
1239    // OpenCL 6.11.4
1240    { "_Z5clampfff", (void *)&SC_clamp_f32 },
1241    { "_Z7degreesf", (void *)&SC_degrees },
1242    { "_Z3maxff", (void *)&SC_max_f32 },
1243    { "_Z3minff", (void *)&SC_min_f32 },
1244    { "_Z3mixfff", (void *)&SC_mix_f32 },
1245    { "_Z7radiansf", (void *)&SC_radians },
1246    { "_Z4stepff", (void *)&SC_step_f32 },
1247    //{ "smoothstep", (void *)& },
1248    { "_Z4signf", (void *)&SC_sign_f32 },
1249
1250
1251
1252
1253    { "modf", (void *)&fmod },
1254    { "_Z4fracf", (void *)&SC_frac },
1255    //{ "sinf_fast", (void *)&SC_sinf_fast },
1256    //{ "cosf_fast", (void *)&SC_cosf_fast },
1257    { "randf", (void *)&SC_randf },
1258    { "randf2", (void *)&SC_randf2 },
1259    { "sign", (void *)&SC_sign },
1260    { "clamp", (void *)&SC_clamp },
1261    { "distf2", (void *)&SC_distf2 },
1262    { "distf3", (void *)&SC_distf3 },
1263    { "magf2", (void *)&SC_magf2 },
1264    { "magf3", (void *)&SC_magf3 },
1265    { "normf", (void *)&SC_normf },
1266    { "mapf", (void *)&SC_mapf },
1267    { "noisef", (void *)&SC_noisef },
1268    { "noisef2", (void *)&SC_noisef2 },
1269    { "noisef3", (void *)&SC_noisef3 },
1270    { "turbulencef2", (void *)&SC_turbulencef2 },
1271    { "turbulencef3", (void *)&SC_turbulencef3 },
1272
1273    // time
1274    { "second", (void *)&SC_second },
1275    { "minute", (void *)&SC_minute },
1276    { "hour", (void *)&SC_hour },
1277    { "day", (void *)&SC_day },
1278    { "month", (void *)&SC_month },
1279    { "year", (void *)&SC_year },
1280    { "uptimeMillis", (void*)&SC_uptimeMillis },      // TODO: use long instead
1281    { "startTimeMillis", (void*)&SC_startTimeMillis },      // TODO: use long instead
1282    { "elapsedTimeMillis", (void*)&SC_elapsedTimeMillis },      // TODO: use long instead
1283
1284    // matrix
1285    { "matrixLoadIdentity", (void *)&SC_matrixLoadIdentity },
1286    { "matrixLoadFloat", (void *)&SC_matrixLoadFloat },
1287    { "matrixLoadMat", (void *)&SC_matrixLoadMat },
1288    { "matrixLoadRotate", (void *)&SC_matrixLoadRotate },
1289    { "matrixLoadScale", (void *)&SC_matrixLoadScale },
1290    { "matrixLoadTranslate", (void *)&SC_matrixLoadTranslate },
1291    { "matrixLoadMultiply", (void *)&SC_matrixLoadMultiply },
1292    { "matrixMultiply", (void *)&SC_matrixMultiply },
1293    { "matrixRotate", (void *)&SC_matrixRotate },
1294    { "matrixScale", (void *)&SC_matrixScale },
1295    { "matrixTranslate", (void *)&SC_matrixTranslate },
1296
1297    // vector
1298    { "vec2Rand", (void *)&SC_vec2Rand },
1299
1300    // vec3
1301    { "vec3Norm", (void *)&SC_vec3Norm },
1302    { "vec3Length", (void *)&SC_vec3Length },
1303    { "vec3Add", (void *)&SC_vec3Add },
1304    { "vec3Sub", (void *)&SC_vec3Sub },
1305    { "vec3Cross", (void *)&SC_vec3Cross },
1306    { "vec3Dot", (void *)&SC_vec3Dot },
1307    { "vec3Scale", (void *)&SC_vec3Scale },
1308
1309    // vec4
1310    { "vec4Norm", (void *)&SC_vec4Norm },
1311    { "vec4Length", (void *)&SC_vec4Length },
1312    { "vec4Add", (void *)&SC_vec4Add },
1313    { "vec4Sub", (void *)&SC_vec4Sub },
1314    { "vec4Dot", (void *)&SC_vec4Dot },
1315    { "vec4Scale", (void *)&SC_vec4Scale },
1316
1317    // context
1318    { "bindProgramFragment", (void *)&SC_bindProgramFragment },
1319    { "bindProgramStore", (void *)&SC_bindProgramStore },
1320    { "bindProgramVertex", (void *)&SC_bindProgramVertex },
1321    { "bindProgramRaster", (void *)&SC_bindProgramRaster },
1322    { "bindSampler", (void *)&SC_bindSampler },
1323    { "bindTexture", (void *)&SC_bindTexture },
1324
1325    // vp
1326    { "vpLoadModelMatrix", (void *)&SC_vpLoadModelMatrix },
1327    { "vpLoadTextureMatrix", (void *)&SC_vpLoadTextureMatrix },
1328
1329    // allocation
1330    { "allocGetDimX", (void *)&SC_allocGetDimX },
1331    { "allocGetDimY", (void *)&SC_allocGetDimY },
1332    { "allocGetDimZ", (void *)&SC_allocGetDimZ },
1333    { "allocGetDimLOD", (void *)&SC_allocGetDimLOD },
1334    { "allocGetDimFaces", (void *)&SC_allocGetDimFaces },
1335
1336    // drawing
1337    { "drawRect", (void *)&SC_drawRect },
1338    { "drawQuad", (void *)&SC_drawQuad },
1339    { "drawQuadTexCoords", (void *)&SC_drawQuadTexCoords },
1340    { "drawSprite", (void *)&SC_drawSprite },
1341    { "drawSpriteScreenspace", (void *)&SC_drawSpriteScreenspace },
1342    { "drawSpriteScreenspaceCropped", (void *)&SC_drawSpriteScreenspaceCropped },
1343    { "drawLine", (void *)&SC_drawLine },
1344    { "drawPoint", (void *)&SC_drawPoint },
1345    { "drawSimpleMesh", (void *)&SC_drawSimpleMesh },
1346    { "drawSimpleMeshRange", (void *)&SC_drawSimpleMeshRange },
1347
1348
1349    // misc
1350    { "pfClearColor", (void *)&SC_ClearColor },
1351    { "color", (void *)&SC_color },
1352    { "hsb", (void *)&SC_hsb },
1353    { "hsbToRgb", (void *)&SC_hsbToRgb },
1354    { "hsbToAbgr", (void *)&SC_hsbToAbgr },
1355    { "pointAttenuation", (void *)&SC_pointAttenuation },
1356
1357    { "uploadToTexture", (void *)&SC_uploadToTexture },
1358    { "uploadToBufferObject", (void *)&SC_uploadToBufferObject },
1359
1360    { "syncToGL", (void *)&SC_syncToGL },
1361
1362    { "getWidth", (void *)&SC_getWidth },
1363    { "getHeight", (void *)&SC_getHeight },
1364
1365    { "sendToClient", (void *)&SC_toClient },
1366
1367    { "_Z18convertColorTo8888fff", (void *)&SC_convertColorTo8888_f3 },
1368    { "_Z18convertColorTo8888ffff", (void *)&SC_convertColorTo8888_f4 },
1369
1370    { "debugF", (void *)&SC_debugF },
1371    { "debugI32", (void *)&SC_debugI32 },
1372    { "debugHexF", (void *)&SC_debugHexF },
1373    { "debugHexI32", (void *)&SC_debugHexI32 },
1374    { "debugP", (void *)&SC_debugP },
1375    { "debugPf", (void *)&SC_debugPf },
1376    { "debugPi", (void *)&SC_debugPi },
1377
1378    { "scriptCall", (void *)&SC_scriptCall },
1379    { "rsGetAllocation", (void *)&SC_getAllocation },
1380
1381
1382    { NULL, NULL }
1383};
1384
1385const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbol(const char *sym)
1386{
1387    ScriptCState::SymbolTable_t *syms = gSyms;
1388
1389    while (syms->mPtr) {
1390        if (!strcmp(syms->mName, sym)) {
1391            return syms;
1392        }
1393        syms++;
1394    }
1395    return NULL;
1396}
1397
1398