summaryrefslogtreecommitdiff
path: root/apps/plugins/lua/ldo.h
blob: 4c9713480557ad0e1a351d43b531cefb70a6bea2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*
** $Id$
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/

#ifndef ldo_h
#define ldo_h


#include "lobject.h"
#include "lstate.h"
#include "lzio.h"


#define luaD_checkstack(L,n)	\
  if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \
    luaD_growstack(L, n); \
  else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1));


#define incr_top(L) {luaD_checkstack(L,1); L->top++;}

#define savestack(L,p)		((char *)(p) - (char *)L->stack)
#define restorestack(L,n)	((TValue *)((char *)L->stack + (n)))

#define saveci(L,p)		((char *)(p) - (char *)L->base_ci)
#define restoreci(L,n)		((CallInfo *)((char *)L->base_ci + (n)))


/* results from luaD_precall */
#define PCRLUA		0	/* initiated a call to a Lua function */
#define PCRC		1	/* did a call to a C function */
#define PCRYIELD	2	/* C funtion yielded */


/* type of protected functions, to be ran by `runprotected' */
typedef void (*Pfunc) (lua_State *L, void *ud);

LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name);
LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line);
LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
                                        ptrdiff_t oldtop, ptrdiff_t ef);
LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize);
LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
LUAI_FUNC void luaD_growstack (lua_State *L, int n);

LUAI_FUNC void luaD_throw (lua_State *L, int errcode);
LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);

LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop);

#endif

248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
/***************************************************************************
*             __________               __   ___.
*   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
*   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
*   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
*   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
*                     \/            \/     \/    \/            \/
* $Id$
*
* Copyright (C) 2002 Damien Teney
* modified to use int instead of float math by Andreas Zwirtes
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "plugin.h"

#ifdef HAVE_LCD_BITMAP

/* Loops that the values are displayed */
#define DISP_TIME 30

struct point_3D {
    long x, y, z;
};

struct point_2D {
    long x, y;
};

static struct point_3D sommet[8];
static struct point_3D point3D[8];
static struct point_2D point2D[8];

static long matrice[3][3];

static int nb_points = 8;

static int x_off = 56;
static int y_off = 31;
static int z_off = 600;

/* Precalculated sine and cosine * 10000 (four digit fixed point math) */
static int sin_table[91] = 
{
    0, 174, 348, 523, 697,
    871,1045,1218,1391,1564,
    1736,1908,2079,2249,2419,
    2588,2756,2923,3090,3255,
    3420,3583,3746,3907,4067,
    4226,4383,4539,4694,4848,
    5000,5150,5299,5446,5591,
    5735,5877,6018,6156,6293,
    6427,6560,6691,6819,6946,
    7071,7193,7313,7431,7547,
    7660,7771,7880,7986,8090,
    8191,8290,8386,8480,8571,
    8660,8746,8829,8910,8987,
    9063,9135,9205,9271,9335,
    9396,9455,9510,9563,9612,
    9659,9702,9743,9781,9816,
    9848,9876,9902,9925,9945,
    9961,9975,9986,9993,9998,
    10000
};

static struct plugin_api* rb;

static long sin(int val)
{
    /* Speed improvement through sukzessive lookup */
    if (val<181)
    {
        if (val<91)
        {
            /* phase 0-90 degree */
            return (long)sin_table[val];
        }
        else
        {
            /* phase 91-180 degree */
            return (long)sin_table[180-val];
        }
    }
    else
    {
        if (val<271)
        {
            /* phase 181-270 degree */
            return (-1L)*(long)sin_table[val-180];
        }
        else
        {
            /* phase 270-359 degree */
            return (-1L)*(long)sin_table[360-val];
        }
    }
    return 0;
}

static long cos(int val)
{
    /* Speed improvement through sukzessive lookup */
    if (val<181)
    {
        if (val<91)
        {
            /* phase 0-90 degree */
            return (long)sin_table[90-val];
        }
        else
        {
            /* phase 91-180 degree */
            return (-1L)*(long)sin_table[val-90];
        }
    }
    else
    {
        if (val<271)
        {
            /* phase 181-270 degree */
            return (-1L)*(long)sin_table[270-val];
        }
        else
        {
            /* phase 270-359 degree */
            return (long)sin_table[val-270];
        }
    }
    return 0;
}


static void cube_rotate(int xa, int ya, int za)
{
    int i;

    /* Just to prevent unnecessary lookups */
    long sxa,cxa,sya,cya,sza,cza;
    sxa=sin(xa);
    cxa=cos(xa);
    sya=sin(ya);
    cya=cos(ya);
    sza=sin(za);
    cza=cos(za);

    /* calculate overall translation matrix */
    matrice[0][0] = cza*cya/10000L;
    matrice[1][0] = sza*cya/10000L;
    matrice[2][0] = -sya;

    matrice[0][1] = cza*sya/10000L*sxa/10000L - sza*cxa/10000L;
    matrice[1][1] = sza*sya/10000L*sxa/10000L + cxa*cza/10000L;
    matrice[2][1] = sxa*cya/10000L;

    matrice[0][2] = cza*sya/10000L*cxa/10000L + sza*sxa/10000L;
    matrice[1][2] = sza*sya/10000L*cxa/10000L - cza*sxa/10000L;
    matrice[2][2] = cxa*cya/10000L;

    /* apply translation matrix to all points */
    for(i=0;i<nb_points;i++)
    {
        point3D[i].x = matrice[0][0]*sommet[i].x + matrice[1][0]*sommet[i].y
            + matrice[2][0]*sommet[i].z;
        
        point3D[i].y = matrice[0][1]*sommet[i].x + matrice[1][1]*sommet[i].y
            + matrice[2][1]*sommet[i].z;
        
        point3D[i].z = matrice[0][2]*sommet[i].x + matrice[1][2]*sommet[i].y
            + matrice[2][2]*sommet[i].z;
    }
}

static void cube_viewport(void)
{
    int i;

    /* Do viewport transformation for all points */
    for(i=0;i<nb_points;i++)
    {
        point2D[i].x=(((point3D[i].x)<<8)/10000L)/
          (point3D[i].z/10000L+z_off)+x_off;
        point2D[i].y=(((point3D[i].y)<<8)/10000L)/
          (point3D[i].z/10000L+z_off)+y_off;
    }
}

static void cube_init(void)
{
    /* Original 3D-position of cube's corners */
    sommet[0].x = -40;  sommet[0].y = -40;  sommet[0].z = -40;
    sommet[1].x =  40;  sommet[1].y = -40;  sommet[1].z = -40;
    sommet[2].x =  40;  sommet[2].y =  40;  sommet[2].z = -40;
    sommet[3].x = -40;  sommet[3].y =  40;  sommet[3].z = -40;
    sommet[4].x =  40;  sommet[4].y = -40;  sommet[4].z =  40;
    sommet[5].x = -40;  sommet[5].y = -40;  sommet[5].z =  40;
    sommet[6].x = -40;  sommet[6].y =  40;  sommet[6].z =  40;
    sommet[7].x =  40;  sommet[7].y =  40;  sommet[7].z =  40;
}

static void line(int a, int b)
{
    rb->lcd_drawline(point2D[a].x, point2D[a].y, point2D[b].x, point2D[b].y);
}

static void cube_draw(void)
{
    /* Draws front face */
    line(0,1); line(1,2);
    line(2,3); line(3,0);

    /* Draws rear face */
    line(4,5); line(5,6);
    line(6,7); line(7,4);

    /* Draws  the other edges */
    line(0,5);
    line(1,4);
    line(2,7);
    line(3,6);
}


enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
{
    int t_disp=0;
    char buffer[30];

    int xa=0;
    int ya=0;
    int za=0;
    int xs=1;
    int ys=3;
    int zs=1;
    bool highspeed=0;
    bool exit=0;

    TEST_PLUGIN_API(api);
    (void)(parameter);
    rb = api;

    rb->lcd_setfont(FONT_SYSFIXED);

    cube_init();

    while(!exit)
    {
        if (highspeed) 
            rb->yield();
        else
            rb->sleep(4);
        
        rb->lcd_clear_display();
        cube_rotate(xa,ya,za);
        cube_viewport();
        cube_draw();
        if (t_disp>0)
        {
            t_disp--;
            rb->snprintf(buffer, 30, "x:%d y:%d z:%d h:%d",xs,ys,zs,highspeed);
            rb->lcd_putsxy(0, 56, buffer);
        }
        rb->lcd_update();
        
        xa+=xs;
        if (xa>359)
            xa-=360;
        if (xa<0)
            xa+=360;
        ya+=ys;
        if (ya>359)
            ya-=360;
        if (ya<0)
            ya+=360;
        za+=zs;
        if (za>359)
            za-=360;
        if (za<0)
            za+=360;

        switch(rb->button_get(false)) 
        {
            case BUTTON_RIGHT:
                xs+=1;
                if (xs>10)
                    xs=10;
                t_disp=DISP_TIME;
                break;
            case BUTTON_LEFT:
                xs-=1;
                if (xs<-10)
                    xs=-10;
                t_disp=DISP_TIME;
                break;
            case BUTTON_UP:
                ys+=1;
                if (ys>10)
                    ys=10;
                t_disp=DISP_TIME;
                break;
            case BUTTON_DOWN:
                ys-=1;
                if (ys<-10)
                    ys=-10;
                t_disp=DISP_TIME;
                break;
            case BUTTON_F2:
                zs+=1;
                if (zs>10)
                    zs=10;
                t_disp=DISP_TIME;
                break;
            case BUTTON_F1:
                zs-=1;
                if (zs<-10)
                    zs=-10;
                t_disp=DISP_TIME;
                break;
            case BUTTON_PLAY:
                highspeed=!highspeed;
                t_disp=DISP_TIME;
                break;
            case BUTTON_OFF|BUTTON_REL:
                exit=1;
                break;

            case SYS_USB_CONNECTED:
                rb->usb_screen();
                return PLUGIN_USB_CONNECTED;
        }
    }

    return PLUGIN_OK;
}

#endif