#include "global/stdinc.h"
#include "engine/media.h"
#include "engine/mediaSDL.h"
#include "engine/animation.h"
#include "engine/font.h"
#include "engine/tile.h"
#include "SDL_audio.h"
#include "SDL.h"
#include <stdarg.h>
#include "engine/chiptune.h"
#include "engine/kau.h"
#include <windows.h>
#include "global/fileParse.h"
#include<map>
#undef main

struct map;

#define File(a) a


std::map<int, int> defs;
std::map<int, int> defs_rev;

std::map<int, map> maps;

struct map{
    struct trigger{
        /*enum dtypes{
            splash = 0;
            player_rise,
        };*/
        int type;
        Animation* image;
        int rettype;
        int len;
        KAU* sound;
        union{
            struct{
                int time;
            }del;
            struct{
                int color;
            }col;
        } args;
    };
    struct actives{ int x, y; };
    std::vector<actives> walls;
    std::vector<actives> meanwalls;
    std::vector<actives> boulders;
    std::vector<actives> greenswitch;
    std::vector<trigger> triggers;
    std::vector<int> triggertrack;

    int wallshide;
    int mwallshide;


    int bgcolor;
    int* data;
    int wid, hig;
    int spawn_x, spawn_y;
    int link, link2;
    char fnametmp[1000];
    void* fileloc;
    Context* cont;
    Context::Color spawncolor;
    void add_trigger( int type, KAU* sound, Animation* img, int arg, int rettype, int len ){
        trigger a;
        a.type = type;
        a.image = img;
        a.rettype = rettype;
        a.sound = sound;
        a.len = len;
        switch( type ){
            case 0:
                a.args.del.time = arg; break;
            case 1:
                a.args.col.color = arg; break;
        }
        triggers.push_back( a );
        triggertrack.push_back( 0 );
    }
    int load_from_bmp( char* fname ){
        fileloc = 0;
        walls.clear();
        meanwalls.clear();
        boulders.clear();
        greenswitch.clear();
        for( int i = 0; i < triggers.size(); i ++ ){
            if( triggers[i].type == 0 )
                triggertrack[i] = triggers[i].args.del.time;
        }
        wallshide = 0;
        mwallshide = 1;
        strncpy( fnametmp, fname, 999 );
        FILE* f = fopen( fname, "rb" );
        if( f <= 0 ) return -1;
        unsigned char head [26];
        fread( head, 26, 1, f );
        if( head[0] != 0x42 || head[1] != 0x4D ) return -2;
        wid = head[18] + ( head[19] << 8 ) + ( head[20] << 16 ) + ( head[21] << 24 );
        hig = head[22] + ( head[23] << 8 ) + ( head[24] << 16 ) + ( head[25] << 24 );
        int off = head[10] + ( head[11] << 8 ) + ( head[12] << 16 ) + ( head[13] << 24 );
        data = (int*) malloc( wid * hig * sizeof( int ) );
        fseek( f, off, SEEK_SET );

        for( int j = hig-1; j >= 0; j -- ){
            for( int i = 0; i < wid; i ++ ){
                data[ i + j * wid ] = ( fgetc( f ) << 16 ) + ( fgetc( f ) << 8 ) + fgetc( f );
                switch( defs[data[ i + j * wid ]] ){
                    case 1: spawn_x = i; spawn_y = j;
                            spawncolor.r = data[ i + j * wid ] & 0xFF;
                            spawncolor.g = ( data[ i + j * wid ] & 0xFF00 ) >> 8;
                            spawncolor.b = ( data[ i + j * wid ] & 0xFF0000 ) >> 16;
                            spawncolor.a = 0xFF;
                            //data[ i + j * wid ] = data[0];
                            break;
                    case 4: walls.push_back( { i, j } ); data[ i + j * wid ] = data[wid*hig - wid]; break;
                    case 8: boulders.push_back( { i, j } ); data[ i + j * wid ] = data[wid*hig - wid]; break;
                    case 11: meanwalls.push_back( { i, j } ); data[ i + j * wid ] = data[wid*hig - wid]; break;
                    case 6: greenswitch.push_back( { i, j } ); break;
                }
            }
            fseek( f, (4 - ((wid * 3) % 4))%4, SEEK_CUR );

        }
        bgcolor = data[wid*hig - wid];
        data[ spawn_x + spawn_y * wid ] = bgcolor;
        fclose( f );
        return 1;
    }
    /*int load_from_bmp( void* file ){
        fileloc = file;
        unsigned char* f = (unsigned char*) file;
        walls.clear();
        meanwalls.clear();
        boulders.clear();
        greenswitch.clear();
        for( int i = 0; i < triggers.size(); i ++ ){
            if( triggers[i].type == 0 )
                triggertrack[i] = triggers[i].args.del.time;
        }
        wallshide = 0;
        mwallshide = 1;
        //strncpy( fnametmp, fname, 999 );

        if( f[0] != 0x42 || f[1] != 0x4D ) return -2;
        wid = f[18] + ( f[19] << 8 ) + ( f[20] << 16 ) + ( f[21] << 24 );
        hig = f[22] + ( f[23] << 8 ) + ( f[24] << 16 ) + ( f[25] << 24 );
        int off = f[10] + ( f[11] << 8 ) + ( f[12] << 16 ) + ( f[13] << 24 );
        data = (int*) malloc( wid * hig * sizeof( int ) );

        int fpos = off;


        for( int j = hig-1; j >= 0; j -- ){
            for( int i = 0; i < wid; i ++ ){
                data[ i + j * wid ] = ( f[fpos++] << 16 ) + ( f[fpos++] << 8 ) + f[fpos++];
                switch( defs[data[ i + j * wid ]] ){
                    case 1: spawn_x = i; spawn_y = j;
                            spawncolor.r = data[ i + j * wid ] & 0xFF;
                            spawncolor.g = ( data[ i + j * wid ] & 0xFF00 ) >> 8;
                            spawncolor.b = ( data[ i + j * wid ] & 0xFF0000 ) >> 16;
                            spawncolor.a = 0xFF;
                            //data[ i + j * wid ] = data[0];
                            break;
                    case 4: walls.push_back( { i, j } ); data[ i + j * wid ] = data[wid*hig - wid]; break;
                    case 8: boulders.push_back( { i, j } ); data[ i + j * wid ] = data[wid*hig - wid]; break;
                    case 11: meanwalls.push_back( { i, j } ); data[ i + j * wid ] = data[wid*hig - wid]; break;
                    case 6: greenswitch.push_back( { i, j } ); break;
                }
            }
            fpos += (4 - ((wid * 3) % 4))%4;

        }
        bgcolor = data[0];
        data[ spawn_x + spawn_y * wid ] = bgcolor;
        return 1;
    }*/
    int gettype( int x, int y ){
        if( x >= 0 && x < wid && y >= 0 && y < hig ){
            if( wallshide == 0)
                for( int i = 0; i < walls.size(); i ++ )
                    if( walls[i].x == x && walls[i].y == y ) return 4;
            if( mwallshide == 0)
                for( int i = 0; i < meanwalls.size(); i ++ )
                    if( meanwalls[i].x == x && meanwalls[i].y == y ) return 11;
            for( int i = 0; i < boulders.size(); i ++ )
                if( boulders[i].x == x && boulders[i].y == y ) return 8;
            return defs[ data[x + y * wid] ];
        }
        return 0;
    }
    int gettyperear( int x, int y ){
        if( x >= 0 && x < wid && y >= 0 && y < hig ){
            return defs[ data[x + y * wid] ];
        }
        return 0;
    }

    void hidewalls( bool nosound = 0 ){
        if( wallshide == 0 && nosound == 0 ){
        kau_get_by_id( "dooropen" )->stop();
        kau_get_by_id( "dooropen" )->play();
        }
        wallshide = 1;
        for( int i = 0; i < walls.size(); i ++ ){
            if( gettype( walls[i].x, walls[i].y ) == 4 )
            data[ walls[i].x, walls[i].y ] = bgcolor;
        }
    }
    void showwalls(bool nosound = 0 ){
        if( wallshide == 1 && nosound == 0){
        kau_get_by_id( "doorclose" )->stop();
        kau_get_by_id( "doorclose" )->play();
        }
        wallshide = 0;
        for( int i = 0; i < walls.size(); i ++ ){
            if( gettype( walls[i].x, walls[i].y ) == 0 )
                data[ walls[i].x, walls[i].y ] = defs_rev[4];
        }
    }
    void hidemeanwalls(){
        mwallshide = 1;
        for( int i = 0; i < meanwalls.size(); i ++ ){
            if( gettype( meanwalls[i].x, meanwalls[i].y ) == 11 )
            data[ meanwalls[i].x, meanwalls[i].y ] = bgcolor;
        }
    }
    void showmeanwalls(){
        mwallshide = 0;
        for( int i = 0; i < meanwalls.size(); i ++ ){
            if( gettype( meanwalls[i].x, meanwalls[i].y ) == 0 )
                data[ meanwalls[i].x, meanwalls[i].y ] = defs_rev[11];
        }
    }
    int greensheld( int omit_x, int omit_y ){
        if( greenswitch.size() == 0 ) return 0;
        for( int i = 0; i < greenswitch.size(); i ++ )
        {
            if( greenswitch[i].x != omit_x || greenswitch[i].y != omit_y ){
                if( boulders.size() == 0 ) return 0;
                for( int k = 0; k < boulders.size(); k ++ )
                {
                    if( greenswitch[i].x == boulders[k].x && greenswitch[i].y == boulders[k].y )
                        continue;
                    return 0;
                }
            }
        }
        return 1;
    }
    void load(){

    }
    void unload(){

    }
    int movecrate( int x, int y, int dir ){
        for( int i = 0; i < boulders.size(); i ++ ){
            if( boulders[i].x == x && boulders[i].y == y ){
                switch( gettype( x + dir, y )  ){
                    case 0: case 1: case 3: case 5: case 6: case 9: case 10:
                        boulders[i].x += dir;
                        kau_get_by_id( "crate" )->stop();
                        kau_get_by_id( "crate" )->play();
                        return 1;
                    default:
                        break;
                }
            }
        }
        return 0;
    }
    int crategrav(){
        int ret = 0;
        int tmp = 0;
        for( int i = 0; i < boulders.size(); i ++ ){
            switch( gettype( boulders[i].x, boulders[i].y + 1 )  ){
                case 0: case 1: case 3: case 5: case 6: case 9: case 10:
                        boulders[i].y += 1;
                    default:
                        break;
            }
            switch( gettyperear( boulders[i].x, boulders[i].y )  ){
                case 3: case 9:
                        hidewalls();
                        ret = 1;
                        break;
                    case 6:
                        tmp++;

                    default:
                        break;
            }
        }
        if( tmp == greenswitch.size() && greenswitch.size() > 0 ){
            hidewalls( );
            ret = 2;
        }
        return ret;
    }
    void reload(){
        free( data );
        load_from_bmp( fnametmp );
        //load_from_bmp( fileloc );

    }
    Context::Color getcolor( int x, int y ){
        int t = gettype( x, y );
        if( t != 0 ){
            t = defs_rev[t];
        }
        else if( x >= 0 && x < wid && y >= 0 && y < hig ){
            t = data[ x + y * wid ];
        } else {
            t = 0;
        }
        Context::Color a;
        a.r = t & 0xFF;
        a.g = ( t & 0xFF00 ) >> 8;
        a.b = ( t & 0xFF0000 ) >> 16;
        a.a = 0xFF;
        return a;
    }
    int getbcolor( int x, int y ){
        int t = gettype( x, y );
        if( t != 0 ){
            t = defs_rev[t];
        }
        else if( x >= 0 && x < wid && y >= 0 && y < hig ){
            t = data[ x + y * wid ];
        } else {
            t = 0;
        }
        return t;
    }
    int triggercheck( int px, int py ){
        //printf(" triggers: %i\n", triggers.size());
        int ret = 0;
        for( int i = 0; i < triggers.size(); i ++ )
        {
            int dotrig = 0;
            switch( triggers[i].type ){
                case 0:{

                    if( triggertrack[i] > 0){
                        //printf( "triged0\n");
                        triggertrack[i] --;
                        if( triggertrack[i] == 0 ){
                            dotrig = 1;
                            //printf( "triged1\n");
                        }
                    }

                }break;
                case 1:{
                    if( getbcolor( px, py ) == triggers[i].args.col.color )
                        dotrig = 1;
                }
                break;
            }
            if( dotrig == 1 ){
                //printf( "triged2\n");
                if( triggers[i].sound != 0 ){
                    triggers[i].sound->stop();
                    triggers[i].sound->play();
                }
                if( triggers[i].image != 0 ){
                    triggers[i].image->draw( 0, 0, 0 );
                    cont->repaint();
                }
                Sleep( triggers[i].len );
                switch( triggers[i].rettype ){
                    case 1: exit(0); break;
                    default:
                        if( triggers[i].rettype >= 1000 && triggers[i].rettype < 2000 )
                            ret = -(triggers[i].rettype - 1000);
                    //case 2: while( true )
                }
            }
        }
        return ret;
    }
    int checkifopen(){
        for( int i = 0; i < boulders.size(); i ++ ){
            switch( defs[getbcolor( boulders[i].x, boulders[i].y )] )
            {
                case 9: case 3: return true; break;
                case 6: if( greensheld(-1, -1) == 1 ) return true; break;
            }
        }
        return false;
    }

};

struct player{
    int x, y;
    int goinh, goinv;
    int onground;
    int curmap;
    int walltimer;
    int dead;
    int greened;
    int btnd;
    int closin;
    Context* cont;
    Context::EventListener *list;
    player( Context* c ){
        x = y = goinh = goinv = onground = curmap = walltimer = dead = btnd = closin = 0;
        cont = c;
        list = c->listener_add( -1 );
        x = maps[ curmap ].spawn_x;
        y = maps[ curmap ].spawn_y;
        greened = 0;
    }
    void step(){
        int xp = x;
        int yp = y;
        if( dead > 0 ){
            dead --;
            if( dead == 0 ){
                maps[curmap].reload();
                x = maps[curmap].spawn_x;
                y = maps[curmap].spawn_y;
                greened = 0;
                walltimer = 0;
            }
            return;
        }
        while( list->events() > 0 ){

                Context::Event t = list->pop();
                if( t.Type == cont->EventInfo.Type.Keyboard ){
                        if( t.EventID == cont->EventInfo.Keyboard.Type.KeyDown ){
                                if( t.EventData[0] == cont->EventInfo.Keyboard.Key.Up ){
                                    if( onground != 0 )
                                        goinv = -3;
                                    onground = 0;
                                }
                                if( t.EventData[0] == cont->EventInfo.Keyboard.Key.K_0 ){
                                    maps[ curmap ].unload();
                                    curmap = maps[ curmap ].link;
                                    maps[ curmap ].reload();
                                    x = maps[ curmap ].spawn_x;
                                    y = maps[ curmap ].spawn_y;
                                    walltimer = 0;
                                    greened = 0;
                                    maps[ curmap ].hidemeanwalls();
                                    maps[ curmap ].showwalls();
                                }
                                if( t.EventData[0] == cont->EventInfo.Keyboard.Key.Left ){
                                    goinh = -1;
                                }
                                if( t.EventData[0] == cont->EventInfo.Keyboard.Key.Right ){
                                    goinh = 1;
                                }
                                if( t.EventData[0] == cont->EventInfo.Keyboard.Key.R ){
                                    maps[curmap].reload();
                                    x = maps[curmap].spawn_x;
                                    y = maps[curmap].spawn_y;
                                    greened = 0;
                                    walltimer = 0;
                                    maps[ curmap ].hidemeanwalls();
                                    maps[ curmap ].showwalls();
                                }
                                if( t.EventData[0] == cont->EventInfo.Keyboard.Key.Escape ){
                                    exit(0);
                                }


                            }
                        else if( t.EventID == cont->EventInfo.Keyboard.Type.KeyUp){
                                if( t.EventData[0] == cont->EventInfo.Keyboard.Key.Left ||
                                    t.EventData[0] == cont->EventInfo.Keyboard.Key.Right ){
                                    goinh = 0;
                                }
                        }
                }
                else if( t.Type == cont->EventInfo.Type.System ){
                    if( t.EventID == cont->EventInfo.System.Type.Quit ){
                        exit(0);
                    }
                }
        }
        switch( maps[ curmap ].gettype( x + goinh, y )  ){
            case 0: case 1: case 3: case 5: case 6: case 7: case 8: case 9: case 10:
                x+= goinh;
            default:
                break;
        }
        goinv ++;
        int t = 0;
        if( goinv == -2 ){ goinv = -1; t = 1; }
        if( goinv > 1 ) goinv = 1;
        switch( maps[ curmap ].gettype( x, y + goinv )  ){
            case 0: case 1: case 3: case 5: case 6: case 7: case 9: case 10:
                y += goinv;
                onground = 0;
                break;
            default:
                goinv = 0;
                onground = 1;
                break;
        }
        if( t == 1 ) goinv = -2;
        if( walltimer > 0 ) {walltimer --; maps[ curmap ].showmeanwalls(); }
        if( closin == 1 ) maps[ curmap ].showwalls();
        closin = 0;
        if( walltimer <= 0 && greened == 0  ) closin = 1;
        if( maps[curmap].greensheld( x, y ) == 1 ){ maps[ curmap ].hidewalls(); greened = 1;}
        if( btnd == 1 && (x != xp || y != yp) ){
                kau_get_by_id( "buttonup" )->stop();
                kau_get_by_id( "buttonup" )->play();
                btnd = 0;
        }

        switch( maps[ curmap ].gettype( x, y ) ){
            case 3:
                walltimer = 16;
                maps[ curmap ].hidewalls();
                closin = 0;
                if( x != xp || yp != y){
                    kau_get_by_id( "buttondown" )->stop();
                    kau_get_by_id( "buttondown" )->play();
                    btnd = 1;
                }
            break;
            case 6:
                if( x != xp || yp != y){
                    kau_get_by_id( "buttondown" )->stop();
                    kau_get_by_id( "buttondown" )->play();
                    btnd = 1;
                }
                if( maps[ curmap ].greensheld( x, y ) == 1 ){
                    maps[ curmap ].hidewalls();
                    closin = 0;
                    greened = 1;
                }
            break;
            case 9:
                if( x != xp || yp != y){
                    kau_get_by_id( "buttondown" )->stop();
                    kau_get_by_id( "buttondown" )->play();
                    btnd = 1;
                }
                maps[ curmap ].hidewalls();
                closin = 0;
            break;
            case 7:
                kau_get_by_id( "death" )->stop();
                kau_get_by_id( "death" )->play();
                dead = 20;
                return;
            break;
            case 5:
                maps[ curmap ].unload();
                curmap = maps[ curmap ].link;
                maps[ curmap ].reload();
                x = maps[ curmap ].spawn_x;
                y = maps[ curmap ].spawn_y;
                walltimer = 0;
                greened = 0;
                maps[ curmap ].hidemeanwalls();
                maps[ curmap ].showwalls();
                kau_get_by_id( "leveldone" )->stop();
                kau_get_by_id( "leveldone" )->play();
            break;
            case 10:
                maps[ curmap ].unload();
                curmap = maps[ curmap ].link2;
                maps[ curmap ].reload();
                x = maps[ curmap ].spawn_x;
                y = maps[ curmap ].spawn_y;
                walltimer = 0;
                greened = 0;
                maps[ curmap ].hidemeanwalls();
                maps[ curmap ].showwalls();
                kau_get_by_id( "leveldone" )->stop();
                kau_get_by_id( "leveldone" )->play();

            break;
            case 8:
                if( maps[ curmap ].movecrate( x, y, goinh ) == 0 )
                    x = xp;
            break;
        }
        int tmp = maps[ curmap ].crategrav();
        if( tmp != 0 ){
            closin = 0;
            if( tmp == 2 )
                greened = 1;
        }
        tmp = maps[ curmap ].triggercheck( x, y );
        if( tmp < 0 ){
                maps[ curmap ].unload();
                curmap = -tmp;
                maps[ curmap ].reload();
                x = maps[ curmap ].spawn_x;
                y = maps[ curmap ].spawn_y;
                walltimer = 0;
                greened = 0;
                maps[ curmap ].hidemeanwalls();
                maps[ curmap ].showwalls();
        }
        //printf("\n%i\n", curmap );

    }
    void draw(){
        int xpos = x / 22 * 22;
        int ypos = y / 17 * 17;

        for( int j = 0; j < 17; j ++ )
            for( int i = 0; i < 22; i ++ )
                cont->draw_rectangle( i * 26, j * 26, 26, 26, maps[curmap].getcolor(i+xpos, j+ypos ), 0 );
        cont->draw_rectangle( ( x - xpos ) * 26 , ( y - ypos ) * 26, 26, 26, maps[curmap].spawncolor, 0 );

    }
};
#define File(a) ((_aslai_file_handle*)format)->handle(((_aslai_file_handle*)format)->get_file( a ))->getdata()
#define Filel(a) ((_aslai_file_handle*)format)->handle(((_aslai_file_handle*)format)->get_file( a ))->getdata(), ((_aslai_file_handle*)format)->handle(((_aslai_file_handle*)format)->get_file( a ))->length()
#define File(a) a
#define Filel(a) a

//Context* Global_Context;
struct passinargs{
    Context* c;
    Chiptunes* chip;
};
void parse_animation( void* format, int* args )
{
    //printf("mai");
    //char* fname = getString(1);
    animation_add(
                  ((passinargs*)format)->c->image_load(Filel(getString(1))),
                  ((passinargs*)format)->c,
                  getInt(2), getInt(3), getInt(4), getInt(5), getInt(6), getString(0) );
}
void parse_tile( void* format, int* args )
{
    tile_add( ((passinargs*)format)->c->image_load(Filel(getString(1))), ((passinargs*)format)->c, getInt(2), getInt(3), getInt(4), getInt(5), getString(0) );
}
void parse_font( void* format, int* args )
{
    font_add( ((passinargs*)format)->c->image_load(Filel(getString(1))), ((passinargs*)format)->c, getInt(2), getInt(3), getInt(4), getInt(6), getInt(7), getString(0), (unsigned char*) getString(5) );
}
void parse_kau( void* format, int* args ) //kau id fname
{
    kau_add( Filel(getString(1)), ((passinargs*)format)->c, ((passinargs*)format)->chip, getString(0) );
}

void parse_color( void* format, int* args ) //kau id fname
{
    long long color = getInt(1) + ( getInt(2) << 8 ) + ( getInt(3) << 16 );
    defs[ color ] = getInt(0);
    defs_rev[ getInt(0) ] = color;
}

void parse_map( void* format, int* args ) //map id file link1 link2
{
    struct map a;
    a.load_from_bmp( File(getString( 1 )) );
    a.link = getInt( 2 );
    a.link2 = getInt( 3 );
    a.cont = ((passinargs*)format)->c;

    maps[ getInt( 0 ) ] = a;

}

void parse_triggert( void* format, int* args ) //triggert mapid soundid imageid wait rettype len
{
    maps[getInt(0)].add_trigger( 0, kau_get_by_id( getString( 1 ) ), animation_get_by_id( getString( 2 ) ), getInt(3), getInt(4), getInt(5) );

}

void parse_triggerc( void* format, int* args ) //triggerc mapid soundid imageid r g b rettype len
{
    long long color = getInt(3) + ( getInt(4) << 8 ) + ( getInt(5) << 16 );
    maps[getInt(0)].add_trigger( 1, kau_get_by_id( getString( 1 ) ), animation_get_by_id( getString( 2 ) ), color, getInt(6), getInt(7) );

}


void mixaudio(void* data, Uint8 *stream, int len){
    ((Chiptunes*)data)->get_samples( len, stream );
}


void playgame( Context* c ){
        putchar( '\n' );
    putchar( '\n' );

    player p( c );
        putchar( 'a' );
    putchar( 's' );
    putchar( 'l' );
    putchar( 'a' );
    putchar( 'i' );
    putchar( 'i' );
    putchar( '@' );
    putchar( 'h' );
    putchar( 'o' );
    putchar( 't' );
    putchar( 'm' );
    putchar( 'a' );
    putchar( 'i' );
    putchar( 'l' );
    putchar( '.' );
    putchar( 'c' );
    putchar( 'o' );
    putchar( 'm' );

    while( true ){
        c->handle_io();
        p.step();
        p.draw();
        c->repaint();
        Sleep( 100 );
    }

}
#define File(a) resc->handle(resc->get_file( a ))->getdata()
#define Filel(a) resc->handle(resc->get_file( a ))->getdata(), resc->handle(resc->get_file( a ))->length()
#define File(a) a
#define Filel(a) a



int main(){

    Context a;
    AParse myparse;
    putchar( 'B' );
    putchar( 'Y' );


    _SDL_init( &a );
    a.set_caption( "The Lonesome Pixel", "resc/icon.ico" );
    char ii[10];
    putchar( ' ' );
    putchar( 'A' );
    putchar( 'S' );


    a.create_screen( 22*26, 17*26, 0, 0, 0 );
    a.init_sound( 22050, 512, 8+0x80 );
    putchar( 'L' );
    putchar( 'A' );


    //_aslai_file_handle* resc = new _aslai_file_handle("resc.kas");

    Chiptunes chip;
    a.sound_set_callback( &chip, mixaudio );
    passinargs parserargs;
    parserargs.c = &a;
    parserargs.chip = &chip;
    putchar( 'I' );
    putchar( ' ' );
    putchar( 'F' );
    putchar( 'O' );
    putchar( 'R' );

    //parserargs.af = resc;

    myparse.addFunc( "animation", "ssiiiii", parse_animation, (void*) &parserargs );
    myparse.addFunc( "tile", "ssiiii", parse_tile, (void*) &parserargs );
    myparse.addFunc( "font", "ssiiisii", parse_font, (void*) &parserargs );
    myparse.addFunc( "kau", "ss", parse_kau, (void*) &parserargs );
    putchar( ' ' );
    putchar( 'L' );
    putchar( 'U' );
    putchar( 'D' );
    myparse.addFunc( "color", "iiii", parse_color, (void*) &parserargs );
    myparse.addFunc( "map", "isii", parse_map, (void*) &parserargs );
    myparse.addFunc( "triggert", "issiii", parse_triggert, (void*) &parserargs );
    myparse.addFunc( "triggerc", "issiiiii", parse_triggerc, (void*) &parserargs );

    putchar( 'U' );
    putchar( 'M' );
    putchar( ' ' );


    myparse.parseScipt( Filel("resc/load.txt")  );
    putchar( 'D' );
    putchar( 'A' );
    putchar( 'R' );
    putchar( 'E' );

    playgame( &a );

    a.cleanup();
}