Login

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download | RSS feed

#include <evo.h>
#include "resources.h"

#define lcor 8
#define ucor 1
#define score_y 3 //2
#define score_x 33 //1
#define hiscore_y 8 //2
#define hiscore_x 33
#define n31 31
#define n32 32
#define nbig 96 //128
#define nsmall 160
#define wintile 10 //5 for "64", 10 for "2048"

//Єхъє∙шх ъююЁфшэрЄ√ т√тюфр ЄхъёЄр

static u8 key;
static u8 keys[40];
static u8 output_x,output_xt;
static u8 output_y,output_yt;
static u8 tile;
static u8 t_tile;
static u16 output_tile;
static u8 board[4][4]; //+(n*32) = new tile
static u8 oldboard[4][4];
static u8 screenboard[4][4];
static u8 oldscreenboard[4][4];
static u32 score,screenscore,oldscreenscore;
static u32 hiscore,screenhiscore,oldscreenhiscore;
static char i,j;
static u8 joy;
static u8 gameover;
static u8 win; //increases at each wintile
static u8 nmoves;
static u8 t;

static char tscore[7]="012345";

const u32 tilescore[]={
        2,4,8,16,32,64,
        128,256,512,1024,2048,4096,8192,16384,32768ul,65536ul,131072ul,262144ul
};


//т√тюф юфэюую ёшьтюыр эр ¤ъЁрэ ё ртЄюьрЄшўхёъшь шчьхэхэшхь
//яючшЎшш т√тюфр, Єръцх ёшьтюы '\n' яхЁхтюфшЄ ёЄЁюъє
void put_char(u8 n)
{
        if(n>=' '&&n<='Z')
        {
                draw_tile(output_x,output_y,n-' ');
                draw_tile(output_x,output_y+1,n-' '+64);
        }

        ++output_x;

        if(output_x==40||n=='\n')
        {
                output_x=1;
               
                ++output_y;
               
                if(output_y==24) output_y=1;
        }
}

void put_char_key(u8 n)
{
        if(n>=' '&&n<='Z')
        {
                draw_tile_key(output_x,output_y,n-' ');
                draw_tile_key(output_x,output_y+1,n-' '+64);
        }

        ++output_x;

        if(output_x==40||n=='\n')
        {
                output_x=1;
               
                ++output_y;
               
                if(output_y==24) output_y=1;
        }
}

//т√тюф ёЄЁюъш ёшьтюыют
void put_str(u8* str)
{
        u8 i;

        while(1)
        {
                i=*str++;

                if(!i) break;

                put_char(i);
        }
}

void put_str_key(u8* str)
{
        u8 i;

        while(1)
        {
                i=*str++;

                if(!i) break;

                put_char_key(i);
        }
}



void init_screen_board()
{
char i,j;
for(i=0;i<4;++i)
{
        for(j=0;j<4;++j)
        {
                screenboard[i][j]=255;
                oldscreenboard[i][j]=30;
        }
}
}

void init_board()
{
char i,j;
for(i=0;i<4;++i)
{
        for(j=0;j<4;++j)
        {
                board[i][j]=0;
        }
}
init_screen_board();
}

u8 spare_squares()
{
char i,j;
u8 nsq;
nsq=0;
for(i=0;i<4;++i)
        for(j=0;j<4;++j)
                if (board[i][j]==0)
                ++nsq;
return nsq;
}

void add_rnd()
{
u8 nsq;
//find number of spare squares
//find rnd
nsq=rand16()%spare_squares();
//put tile 2 or 4 in random square
for(i=0;i<4;++i)
        for(j=0;j<4;++j)
                if (board[i][j]==0)
                {
                        if (nsq==0) board[i][j]=(rand16()%10)?1+nsmall:2+nsmall;
                        --nsq;
                }
}

void put_tile()
{
        t_tile=0;
        if(tile&0xe0)
        {
                if(tile>=nsmall) t_tile=16;
                else t_tile=8;
        }
        tile=tile&n31;
        output_yt=output_y;
        for(i=0;i<6;++i)
        {
                output_tile=((u16)tile<<8) | t_tile;
                output_xt=output_x;
                //for(j=0;j<6;++j)
                {
                        //draw_tile(output_xt++,output_y,output_tile);
                        //output_tile++;
                        __asm
                        ld      hl,(_output_tile)
                        push    hl
                        ld      a,(_output_yt)
                        ld      b,a
                        ld      hl,#_output_xt
                        ld      c,(hl)
                        inc     (hl)
                        push    bc
                        call    _draw_tile
                        pop     af
                        pop     af
                        ld      hl,#_output_tile
                        inc     (hl)
                        ld      hl,(_output_tile)
                        push    hl
                        ld      a,(_output_yt)
                        ld      b,a
                        ld      hl,#_output_xt
                        ld      c,(hl)
                        inc     (hl)
                        push    bc
                        call    _draw_tile
                        pop     af
                        pop     af
                        ld      hl,#_output_tile
                        inc     (hl)
                        ld      hl,(_output_tile)
                        push    hl
                        ld      a,(_output_yt)
                        ld      b,a
                        ld      hl,#_output_xt
                        ld      c,(hl)
                        inc     (hl)
                        push    bc
                        call    _draw_tile
                        pop     af
                        pop     af
                        ld      hl,#_output_tile
                        inc     (hl)
                        ld      hl,(_output_tile)
                        push    hl
                        ld      a,(_output_yt)
                        ld      b,a
                        ld      hl,#_output_xt
                        ld      c,(hl)
                        inc     (hl)
                        push    bc
                        call    _draw_tile
                        pop     af
                        pop     af
                        ld      hl,#_output_tile
                        inc     (hl)
                        ld      hl,(_output_tile)
                        push    hl
                        ld      a,(_output_yt)
                        ld      b,a
                        ld      hl,#_output_xt
                        ld      c,(hl)
                        inc     (hl)
                        push    bc
                        call    _draw_tile
                        pop     af
                        pop     af
                        ld      hl,#_output_tile
                        inc     (hl)
                        ld      hl,(_output_tile)
                        push    hl
                        ld      a,(_output_yt)
                        ld      b,a
                        ld      hl,#_output_xt
                        ld      c,(hl)
                        //inc   (hl)
                        push    bc
                        call    _draw_tile
                        pop     af
                        pop     af
                        //ld    hl,#_output_tile
                        //inc   (hl)
                        __endasm;
                };
                ++output_yt;
                t_tile+=32;
        }
}


void clear_anim()
{
board[0][0]&=n31;
board[0][1]&=n31;
board[0][2]&=n31;
board[0][3]&=n31;
board[1][0]&=n31;
board[1][1]&=n31;
board[1][2]&=n31;
board[1][3]&=n31;
board[2][0]&=n31;
board[2][1]&=n31;
board[2][2]&=n31;
board[2][3]&=n31;
board[3][0]&=n31;
board[3][1]&=n31;
board[3][2]&=n31;
board[3][3]&=n31;
}

void put_board()
{
select_image(IMG_TILES2);
pal_select(PAL_TILES2);
output_y=ucor+ 0;
tile=board[0][0]; if (tile!=oldscreenboard[0][0]) {output_x=lcor+ 0; put_tile();};
tile=board[0][1]; if (tile!=oldscreenboard[0][1]) {output_x=lcor+ 6; put_tile();};
tile=board[0][2]; if (tile!=oldscreenboard[0][2]) {output_x=lcor+12; put_tile();};
tile=board[0][3]; if (tile!=oldscreenboard[0][3]) {output_x=lcor+18; put_tile();};
output_y=ucor+ 6;
tile=board[1][0]; if (tile!=oldscreenboard[1][0]) {output_x=lcor+ 0; put_tile();};
tile=board[1][1]; if (tile!=oldscreenboard[1][1]) {output_x=lcor+ 6; put_tile();};
tile=board[1][2]; if (tile!=oldscreenboard[1][2]) {output_x=lcor+12; put_tile();};
tile=board[1][3]; if (tile!=oldscreenboard[1][3]) {output_x=lcor+18; put_tile();};
output_y=ucor+ 12;
tile=board[2][0]; if (tile!=oldscreenboard[2][0]) {output_x=lcor+ 0; put_tile();};
tile=board[2][1]; if (tile!=oldscreenboard[2][1]) {output_x=lcor+ 6; put_tile();};
tile=board[2][2]; if (tile!=oldscreenboard[2][2]) {output_x=lcor+12; put_tile();};
tile=board[2][3]; if (tile!=oldscreenboard[2][3]) {output_x=lcor+18; put_tile();};
output_y=ucor+ 18;
tile=board[3][0]; if (tile!=oldscreenboard[3][0]) {output_x=lcor+ 0; put_tile();};
tile=board[3][1]; if (tile!=oldscreenboard[3][1]) {output_x=lcor+ 6; put_tile();};
tile=board[3][2]; if (tile!=oldscreenboard[3][2]) {output_x=lcor+12; put_tile();};
tile=board[3][3]; if (tile!=oldscreenboard[3][3]) {output_x=lcor+18; put_tile();};
memcpy(oldscreenboard,screenboard,16);
memcpy(screenboard,board,16);
//clear_anim();
for(i=0;i<4;++i)
{
        for(j=0;j<4;++j)
        {
                t=board[i][j];
                if(t&0xe0)
                {
                        if(t>=nsmall) board[i][j]=t&31;
                        else board[i][j]-=n32;
                }
        }
}
if(score!=oldscreenscore)
{
        select_image(IMG_FONT);
        tscore[0]='0'+score/100000;
        tscore[1]='0'+(score%100000)/10000;
        tscore[2]='0'+(score%10000)/1000;
        tscore[3]='0'+(score%1000)/100;
        tscore[4]='0'+(score%100)/10;
        tscore[5]='0'+(score%10);
        output_x=score_x;
        output_y=score_y;
        put_str(tscore);
        oldscreenscore=screenscore;
        screenscore=score;
}
if(hiscore!=oldscreenhiscore)
{
        select_image(IMG_FONT);
        tscore[0]='0'+hiscore/100000;
        tscore[1]='0'+(hiscore%100000)/10000;
        tscore[2]='0'+(hiscore%10000)/1000;
        tscore[3]='0'+(hiscore%1000)/100;
        tscore[4]='0'+(hiscore%100)/10;
        tscore[5]='0'+(hiscore%10);
        output_x=hiscore_x;
        output_y=hiscore_y;
        put_str(tscore);
        oldscreenhiscore=screenhiscore;
        screenhiscore=hiscore;
}
swap_screen();
}

void store_oldboard()
{
memcpy(oldboard,board,16);
//for(i=0;i<4;++i)
//      for(j=0;j<4;++j)
//              oldboard[i][j]=board[i][j];
}

//returns !=0 if comething changed
u8 compare_boards()
{
//t=0;
//for(i=0;i<4;++i)
//      for(j=0;j<4;++j)
//              if((board[i][j]&31)!=(oldboard[i][j]&31))
//              ++nsq;
__asm //max tile=15, 4x4 times never overflow
        ld      c,#31
        ld      hl,#_board
        ld      de,#_oldboard
        ld      a,(de) ;0
        xor     (hl)
        and     c
        //add   a,b
        ld      b,a
        inc     hl
        inc     de
        ld      a,(de)
        xor     (hl)
        and     c
        add     a,b
        ld      b,a
        inc     hl
        inc     de
        ld      a,(de)
        xor     (hl)
        and     c
        add     a,b
        ld      b,a
        inc     hl
        inc     de
        ld      a,(de)
        xor     (hl)
        and     c
        add     a,b
        ld      b,a
        inc     hl
        inc     de
        ld      a,(de) ;4
        xor     (hl)
        and     c
        add     a,b
        ld      b,a
        inc     hl
        inc     de
        ld      a,(de)
        xor     (hl)
        and     c
        add     a,b
        ld      b,a
        inc     hl
        inc     de
        ld      a,(de)
        xor     (hl)
        and     c
        add     a,b
        ld      b,a
        inc     hl
        inc     de
        ld      a,(de)
        xor     (hl)
        and     c
        add     a,b
        ld      b,a
        inc     hl
        inc     de
        ld      a,(de) ;8
        xor     (hl)
        and     c
        add     a,b
        ld      b,a
        inc     hl
        inc     de
        ld      a,(de)
        xor     (hl)
        and     c
        add     a,b
        ld      b,a
        inc     hl
        inc     de
        ld      a,(de)
        xor     (hl)
        and     c
        add     a,b
        ld      b,a
        inc     hl
        inc     de
        ld      a,(de)
        xor     (hl)
        and     c
        add     a,b
        ld      b,a
        inc     hl
        inc     de
        ld      a,(de) ;12
        xor     (hl)
        and     c
        add     a,b
        ld      b,a
        inc     hl
        inc     de
        ld      a,(de)
        xor     (hl)
        and     c
        add     a,b
        ld      b,a
        inc     hl
        inc     de
        ld      a,(de)
        xor     (hl)
        and     c
        add     a,b
        ld      b,a
        inc     hl
        inc     de
        ld      a,(de)
        xor     (hl)
        and     c
        add     a,b
        ld      b,a
        //inc   hl
        //inc   de
        ld      hl,#_t
        ld      (hl),b
__endasm;
return t;
}

void move_end()
{
        if (score>hiscore) hiscore=score;
        //add tile
        add_rnd();
        put_board();
        put_board();
        do {
                vsync();
        } while(joystick()&joy); //for joystick
}


void move_left_move()
{
for(i=0;i<4;++i)
        for(j=0;j<3;++j)
                if(board[i][j]==0)
                {
                        board[i][j]=board[i][j+1];
                        board[i][j+1]=0;
                };
}

void move_right_move()
{
for(i=0;i<4;++i)
        for(j=3;j>0;--j)
                if(board[i][j]==0)
                {
                        board[i][j]=board[i][j-1];
                        board[i][j-1]=0;
                };
}

void move_up_move()
{
for(i=0;i<4;++i)
        for(j=0;j<3;++j)
                if(board[j][i]==0)
                {
                        board[j][i]=board[j+1][i];
                        board[j+1][i]=0;
                };
}

void move_down_move()
{
for(i=0;i<4;++i)
        for(j=3;j>0;--j)
                if(board[j][i]==0)
                {
                        board[j][i]=board[j-1][i];
                        board[j-1][i]=0;
                };
}

u8 compare_boards_put_board()
{
u8 nsq;
        nsq=compare_boards();
        if(nsq)
        {
                put_board();
                nmoves++;
        }
return nsq;
}

void move_left()
{
char i,j;
u8 dest;
u8 t;
nmoves=0;
clear_anim();
//move everything to the leftmost position
do {
        store_oldboard();
        move_left_move();
} while (compare_boards_put_board()); //nmoves++
//join tiles from the left
store_oldboard();
for(i=0;i<4;++i)
{
        dest=0;
        for(j=0;j<3;++j)
        {
                t=board[i][j];
                if(t&&(board[i][j+1]==t))
                {
                        board[i][j]+=nbig+1;
                        board[i][j+1]=0;
                        score+=tilescore[t&n31];
                        if((t&n31)==wintile)win++;
                };
        }
}
compare_boards_put_board(); //nmoves++
//move everything to the leftmost position
do {
        store_oldboard();
        move_left_move();
} while (compare_boards_put_board()); //nmoves++
if(nmoves) move_end();
}

void move_right()
{
char i,j;
u8 dest;
u8 t;
nmoves=0;
clear_anim();
//move everything to the rightmost position
do {
        store_oldboard();
        move_right_move();
} while (compare_boards_put_board()); //nmoves++
//join tiles from the right
store_oldboard();
for(i=0;i<4;++i)
{
        dest=0;
        for(j=3;j>0;--j)
        {
                t=board[i][j];
                if(t&&(board[i][j-1]==t))
                {
                        board[i][j]+=nbig+1;
                        board[i][j-1]=0;
                        score+=tilescore[t&n31];
                        if((t&n31)==wintile)win++;
                };
        }
}
compare_boards_put_board(); //nmoves++
//move everything to the rightmost position
do {
        store_oldboard();
        move_right_move();
} while (compare_boards_put_board()); //nmoves++
if(nmoves) move_end();
}

void move_up()
{
char i,j;
u8 dest;
u8 t;
nmoves=0;
clear_anim();
//move everything to the topmost position
do {
        store_oldboard();
        move_up_move();
} while (compare_boards_put_board()); //nmoves++
//join tiles from the top
store_oldboard();
for(i=0;i<4;++i)
{
        dest=0;
        for(j=0;j<3;++j)
        {
                t=board[j][i];
                if(t&&(board[j+1][i]==t))
                {
                        board[j][i]+=nbig+1;
                        board[j+1][i]=0;
                        score+=tilescore[t&n31];
                        if((t&n31)==wintile)win++;
                };
        }
}
compare_boards_put_board(); //nmoves++
//move everything to the topmost position
do {
        store_oldboard();
        move_up_move();
} while (compare_boards_put_board()); //nmoves++
if(nmoves) move_end();
}

void move_down()
{
char i,j;
u8 dest;
u8 t;
nmoves=0;
clear_anim();
//move everything to the bottommost position
do {
        store_oldboard();
        move_down_move();
} while (compare_boards_put_board()); //nmoves++
//join tiles from the bottom
store_oldboard();
for(i=0;i<4;++i)
{
        dest=0;
        for(j=3;j>0;--j)
        {
                t=board[j][i];
                if(t&&(board[j-1][i]==t))
                {
                        board[j][i]+=nbig+1;
                        board[j-1][i]=0;
                        score+=tilescore[t&n31];
                        if((t&n31)==wintile)win++;
                };
        }
}
compare_boards_put_board(); //nmoves++
//move everything to the bottommost position
do {
        store_oldboard();
        move_down_move();
} while (compare_boards_put_board()); //nmoves++
if(nmoves) move_end();
}


u8 hor_moves()
{
u8 nsq;
nsq=0;
for(i=0;i<4;++i)
        for(j=0;j<3;++j)
                if((board[i][j+1]&31)==(board[i][j]&31))
                ++nsq;
return nsq;
}

u8 ver_moves()
{
u8 nsq;
nsq=0;
for(i=0;i<4;++i)
        for(j=0;j<3;++j)
                if((board[j+1][i]&31)==(board[j][i]&31))
                ++nsq;
return nsq;
}


u8 check_gameover()
{
u8 c_gameover;
c_gameover=0;
//check no free space
if (spare_squares()==0)
        //check no tiles to combine horizontally
        if (hor_moves()==0)
                //check no tiles to combine vertically
                if (ver_moves()==0)
                c_gameover=1;
return c_gameover;
}


void do_gameover()
{
u8 i;
gameover=1;
for(i=0;i<2;i++)
{
        select_image(IMG_FONT);
        output_x=15;
        output_y=10;
        put_str_key("GAME OVER!");
        output_x=14;
        output_y=12;
        put_str_key("R TO RESTART");
        swap_screen();
}
music_stop();
sample_play(1);
}

void do_win()
{
u8 i;
for(i=0;i<2;i++)
{
        select_image(IMG_FONT);
        output_x=16;
        output_y=10;
        put_str_key("YOU WIN!");
        output_x=14;
        output_y=12;
        put_str_key("C TO CONTINUE");
        swap_screen();
};
music_stop();
sample_play(0);
do {
        keyboard(keys);
        vsync(); //for joystick
} while ((keys[KEY_C]&KEY_PRESS) == 0);
init_screen_board();
music_play(MUS_2ATSTSTR);
}

void draw_bg()
{
        select_image(IMG_TILES2);
        for(i=8;i<(40-8);i++)
                        draw_tile(i,0,31);
        for(j=0;j<25;j++)
        {
                for(i=0;i<8;i++)
                        draw_tile(i,j,((256/8)*32)+16+(j<<5)+i);
                for(i=0;i<8;i++)
                        draw_tile(i+(40-8),j,((256/8)*32)+24+(j<<5)+i);
        };
        swap_screen();
}


void new_game()
{
u8 i;
music_play(MUS_2ATSTSTR);
if (score>hiscore) hiscore=score;

//шэшЎшрышчрЎш  яхЁхьхээ√ї
score=0;
screenscore=65535;
oldscreenscore=65533;
screenhiscore=65535;
oldscreenhiscore=65533;
gameover=0;
win=0;

init_board();
draw_bg();
draw_bg();
add_rnd();
add_rnd();

for(i=0;i<2;i++)
{
        put_board();
        //т√сюЁ шчюсЁрцхэш  фы  т√тюфр Єрщыют
/*
        select_image(IMG_FONT);
        output_x=score_x;
        output_y=0;
        put_str("SCORE");
        output_x=hiscore_x;
        output_y=0;
        put_str(" BEST");
*/

        //tscore[0]='0'+hiscore/100000;
        //tscore[1]='0'+(hiscore%100000)/10000;
        //tscore[2]='0'+(hiscore%10000)/1000;
        //tscore[3]='0'+(hiscore%1000)/100;
        //tscore[4]='0'+(hiscore%100)/10;
        //tscore[5]='0'+(hiscore%10);
        //output_x=hiscore_x;
        //output_y=2;
        //put_str(tscore);
}
}


void main(void)
{
//sample_play(1);
        color_key(15);

        //ў╕Ёэ√щ ¤ъЁрэ эр тЁхь  яюфуюЄютъш

        pal_select(PAL_TILES2);
        pal_bright(BRIGHT_MIN);

        //юўшёЄър Єхэхтюую ¤ъЁрэр ш єёЄрэютър ярышЄЁ√

        clear_screen(12);
        border(12);

        //яхЁхъы■ўхэшх ¤ъЁрэют, ЄхяхЁ№ Їюэ эр тшфшьюь ¤ъЁрэх

        swap_screen();
        clear_screen(12);
        swap_screen();

        //єёЄрэютър эюЁьры№эющ  ЁъюёЄш

        pal_bright(BRIGHT_MID);


        //ёяЁрщЄ√ т ¤Єюь яЁшьхЁх эх шёяюы№чє■Єё , эю яЁш ЁрчЁх°╕ээ√ї ёяЁрщЄрї
        //ртЄюьрЄшўхёъш т√яюыэ хЄё  ъюяшЁютрэшх т√тюфшьющ уЁрЇшъш т фтр ¤ъЁрэр,
        //ўЄю яючтюы хЄ єяЁюёЄшЄ№ ¤ЄюЄ яЁшьхЁ

        //sprites_start();

        hiscore=0;

        //т√сюЁ шчюсЁрцхэш  фы  т√тюфр Єрщыют
        select_image(IMG_FONT);
        output_x=13;
        output_y=10;
        put_str_key("USE THE ARROWS");
        output_x=14;
        output_y=12;
        put_str_key("R TO RESTART");
        swap_screen();

        while(joystick()==0) {vsync();rand16();} //for joystick
        while(joystick()) {vsync();rand16();} //for joystick

        new_game();


        //уыртэ√щ Ўшъы
        while(1)
        {
                //яюыєўхэшх ёюёЄю эш  ъыртш°

                keyboard(keys);
                vsync(); //for joystick
                joy=joystick();

                if(gameover==0)
                {
                        if(joy&JOY_LEFT) { joy=JOY_LEFT; move_left();}
                        if(joy&JOY_RIGHT) { joy=JOY_RIGHT; move_right();}
                        if(joy&JOY_UP) { joy=JOY_UP; move_up();}
                        if(joy&JOY_DOWN) { joy=JOY_DOWN; move_down();}

                        //юсэютыхэшх ¤ъЁрэр
                        if(joy==0) put_board();

                        if (check_gameover()!=0) do_gameover();

                        if (win==1) {win++; do_win();};

                }

                if(keys[KEY_R]&KEY_PRESS) new_game();

                //if(keys[KEY_LEFTARROW]&KEY_PRESS) move_left();
                //if(keys[KEY_RIGHTARROW]&KEY_PRESS) move_right();
                //if(keys[KEY_UPARROW]&KEY_PRESS) move_up();
                //if(keys[KEY_DOWNARROW]&KEY_PRESS) move_down();

        }

}