#include "../_sdk/evo.h"
#include "resources.h"
#include "functions.h"
#include "mouse.h"
#define SIZE_EASY_LEVEL 3
#define SIZE_MEDIUM_LEVEL 4
#define SIZE_HARD_LEVEL 5
#define TIME_EASY_LEVEL 6000
#define TIME_MEDIUM_LEVEL 12000
#define TIME_HARD_LEVEL 24000
#define OFFSET_EASY_X 60
#define OFFSET_EASY_Y 56
#define OFFSET_MEDIUM_X 52
#define OFFSET_MEDIUM_Y 40
#define OFFSET_HARD_X 44
#define OFFSET_HARD_Y 24
static u32 t, t_old, t_level, t_total;
static i8 level;
static u16 summ_score=0;
static i8 map_x,map_y;
static i8 size_level;
static u8 offset_x,offset_y;
static u8 scr_map[SIZE_HARD_LEVEL][SIZE_HARD_LEVEL];
static u8 dot_map[SIZE_HARD_LEVEL][SIZE_HARD_LEVEL];
static u8 num_map[SIZE_HARD_LEVEL-1][SIZE_HARD_LEVEL-1];
//experts list
static struct
{
u16 scoreboard;
u8 name[9];
} bestlist[9];
#include "saveload.h"
// reset experts list
void bestlist_init()
{
u8 i,j;
for (i=0;i<9;i++)
{
bestlist[i].scoreboard=0;
for (j=0;j<8;j++)
bestlist[i].name[j]='.';
}
}
//exit to os
void quit()__naked
{
__asm
jp _EXIT_TO_OS
__endasm;
}
// output score on screen
void output_score()
{
u8 i;
u16 score;
score=summ_score;
select_image(IMG_FONT);
color_key(15);
for (i=0;i<=4;i++)
{
draw_tile(36-i,15,16+(score%10));
score/=10;
}
}
// output strings on coord
void put_string(u8 output_x, u8 output_y, u8* str)
{
u8 n;
while(1)
{
n=*str++;
if(!n) break;
draw_tile(output_x,output_y,n-' ');
++output_x;
}
}
// waiting for a key
void press_start()
{
while (TRUE)
{
if(joystick()||mouse_position()==MOUSE_LBTN)
{
sfx_play(SFX_DOTDEL,8);
return;
}
}
}
// increasing screen brightness
void bright_up()
{
u8 i;
for (i=BRIGHT_MIN;i<=BRIGHT_MID;i++)
{
pal_bright(i);
delay(3);
}
}
// decreased screen brightness
void bright_down()
{
i8 i;
for (i=BRIGHT_MID;i>=BRIGHT_MIN;i--)
{
pal_bright(i);
delay(3);
}
clear_screen(0);
swap_screen();
}
// intro
void start_screen()
{
pal_bright(BRIGHT_MIN);
pal_select(PAL_PIPBOY);
border(0);
clear_screen(0);
draw_image(0,0,IMG_PIPBOY);
swap_screen();
bright_up();
sample_play(SMP_START);
press_start();
bright_down();
}
// output list of experts
void output_expertlist()
{
u8 output_name_x=17;
u8 output_score_x=30;
u8 output_y=5;
u16 tmp;
u8 i, j;
draw_image(0,0,IMG_LIST_EXPERTS);
select_image(IMG_FONT);
color_key (15);
for (i=0;i<9;i++)
{
tmp=bestlist[i].scoreboard;
for (j=0;j<=4;j++)
{
draw_tile(output_score_x-j,output_y,16+(tmp%10));
tmp/=10;
}
put_string (output_name_x,output_y,bestlist[i].name);
output_y+=2;
}
swap_screen();
bright_up();
press_start();
bright_down();
}
// menu switch lewel
void switch_level()
{
switch (level)
{
case 1:
draw_image(17,4,IMG_EASY_ENABLE);
draw_image(17,8,IMG_MEDIUM_DISABLE);
draw_image(17,12,IMG_HARD_DISABLE);
draw_image(14,16,IMG_LIST_DISABLE);
draw_image(17,20,IMG_EXIT_DISABLE);
t_level=TIME_EASY_LEVEL;
break;
case 2:
draw_image(17,4,IMG_EASY_DISABLE);
draw_image(17,8,IMG_MEDIUM_ENABLE);
draw_image(17,12,IMG_HARD_DISABLE);
draw_image(14,16,IMG_LIST_DISABLE);
draw_image(17,20,IMG_EXIT_DISABLE);
t_level=TIME_MEDIUM_LEVEL;
break;
case 3:
draw_image(17,4,IMG_EASY_DISABLE);
draw_image(17,8,IMG_MEDIUM_DISABLE);
draw_image(17,12,IMG_HARD_ENABLE);
draw_image(14,16,IMG_LIST_DISABLE);
draw_image(17,20,IMG_EXIT_DISABLE);
t_level=TIME_HARD_LEVEL;
break;
case 4:
draw_image(17,4,IMG_EASY_DISABLE);
draw_image(17,8,IMG_MEDIUM_DISABLE);
draw_image(17,12,IMG_HARD_DISABLE);
draw_image(14,16,IMG_LIST_ENABLE);
draw_image(17,20,IMG_EXIT_DISABLE);
break;
case 5:
draw_image(17,4,IMG_EASY_DISABLE);
draw_image(17,8,IMG_MEDIUM_DISABLE);
draw_image(17,12,IMG_HARD_DISABLE);
draw_image(14,16,IMG_LIST_DISABLE);
draw_image(17,20,IMG_EXIT_ENABLE);
break;
}
swap_screen();
sfx_play(SFX_MOVE,8);
}
// menu
void menu_screen()
{
u8 key, i;
i8 level_temp;
level=1;
t_level=TIME_EASY_LEVEL;
clear_screen(0);
draw_image(0,0,IMG_MENU);
draw_image(17,4,IMG_EASY_ENABLE);
swap_screen();
bright_up();
while (TRUE)
{
//mouse
i=mouse_position();
if (i==MOUSE_LBTN)
{
sfx_play(SFX_DOTDEL,8);
if (level==5) quit();
if (level==4)
{
bright_down();
set_sprite(0,0,0,SPRITE_END);
swap_screen();
set_sprite(0,0,0,SPRITE_END);
output_expertlist();
menu_screen();
}
summ_score=0;
while(mouse_position()==MOUSE_LBTN);
return;
}
mouse_setup(mouse_x,mouse_y);
set_sprite(0,mouse_x,mouse_y,6);
level_temp=level;
if (mouse_x>56&&mouse_x<108)
{
if(mouse_y>24&&mouse_y<48) level=1;
if(mouse_y>56&&mouse_y<80) level=2;
if(mouse_y>88&&mouse_y<112) level=3;
if(mouse_y>120&&mouse_y<144) level=4;
if(mouse_y>152&&mouse_y<176) level=5;
}
if (level_temp!=level) switch_level();
swap_screen();
//keyboard
key=joystick();
if(key!=FALSE)
{
mouse_x=152;
mouse_y=184;
mouse_setup(152,184);
if(key&JOY_FIRE)
{
sfx_play(SFX_DOTDEL,8);
if (level==5) quit();
if (level==4)
{
bright_down();
output_expertlist();
menu_screen();
}
summ_score=0;
return;
}
if(key&JOY_UP)
{
level_temp=level;
level--;
if (level<1) level=1;
if (level_temp!=level) switch_level();
}
if(key&JOY_DOWN)
{
level_temp=level;
level++;
if (level>5) level=5;
if (level_temp!=level) switch_level();
}
while (joystick());
}
t=t_level;
}
}
// level generation
void level_gen()
{
u8 n;
u8 summ_dot=0;
switch (level)
{
case 1:
draw_image(0,0,IMG_EASY);
swap_screen();
size_level=SIZE_EASY_LEVEL;
offset_x=OFFSET_EASY_X;
offset_y=OFFSET_EASY_Y;
break;
case 2:
draw_image(0,0,IMG_MEDIUM);
swap_screen();
size_level=SIZE_MEDIUM_LEVEL;
offset_x=OFFSET_MEDIUM_X;
offset_y=OFFSET_MEDIUM_Y;
break;
case 3:
draw_image(0,0,IMG_HARD);
swap_screen();
size_level=SIZE_HARD_LEVEL;
offset_x=OFFSET_HARD_X;
offset_y=OFFSET_HARD_Y;
break;
}
for (map_y=0;map_y<size_level;map_y++)
for (map_x=0;map_x<size_level;map_x++)
{
n=rand16()%100;
if (n<45) dot_map[map_x][map_y]=0; // balance
else
{
dot_map[map_x][map_y]=1;
}
summ_dot+=dot_map[map_x][map_y];
scr_map[map_x][map_y]=0;
}
if (level==1&&summ_dot==9||level==2&&summ_dot==16||summ_dot==25) level_gen();
output_score();
select_image(IMG_NUM);
color_key(15);
for (map_y=0;map_y<size_level-1;map_y++)
for (map_x=0;map_x<size_level-1;map_x++)
{
num_map[map_x][map_y]=dot_map[map_x][map_y]+dot_map[map_x+1][map_y]+dot_map[map_x][map_y+1]+dot_map[map_x+1][map_y+1];
draw_tile_key(map_x*4+(offset_x/4+2),map_y*4+(offset_y/8+2),num_map[map_x][map_y]*4);
draw_tile_key(map_x*4+(offset_x/4+3),map_y*4+(offset_y/8+2),num_map[map_x][map_y]*4+1);
draw_tile_key(map_x*4+(offset_x/4+2),map_y*4+(offset_y/8+3),num_map[map_x][map_y]*4+2);
draw_tile_key(map_x*4+(offset_x/4+3),map_y*4+(offset_y/8+3),num_map[map_x][map_y]*4+3);
}
swap_screen();
map_x=0;
map_y=0;
}
// init new game
void new_game()
{
menu_screen();
level_gen();
}
//checking leader and input name
void enter_name()
{
u8 i,j,n;
u8 n_list=0;
u8 input_x=25;
u8 input_y=19;
u8 key;
u8 keys[40];
u8 check=FALSE;
for (j=0;j<9;j++)
{
if (summ_score>bestlist[j].scoreboard)
{
for (i=8;i>j;i--)
{
bestlist[i].scoreboard=bestlist[i-1].scoreboard;
for (n=0;n<8;n++) bestlist[i].name[n]=bestlist[i-1].name[n];
}
bestlist[j].scoreboard=summ_score;
for (i=0;i<8;i++) bestlist[j].name[i]='.';
check=TRUE;
n_list=j;
break;
}
}
if (check==FALSE) return;
draw_image(0,0,IMG_ENTER_NAME);
swap_screen();
bright_up();
sfx_play(SFX_WIN,8);
vsync();
select_image(IMG_FONT);
while(1)
{
keyboard(keys);
key=255;
if(keys[KEY_0]&KEY_PRESS) key='0';
if(keys[KEY_1]&KEY_PRESS) key='1';
if(keys[KEY_2]&KEY_PRESS) key='2';
if(keys[KEY_3]&KEY_PRESS) key='3';
if(keys[KEY_4]&KEY_PRESS) key='4';
if(keys[KEY_5]&KEY_PRESS) key='5';
if(keys[KEY_6]&KEY_PRESS) key='6';
if(keys[KEY_7]&KEY_PRESS) key='7';
if(keys[KEY_8]&KEY_PRESS) key='8';
if(keys[KEY_9]&KEY_PRESS) key='9';
if(keys[KEY_A]&KEY_PRESS) key='A';
if(keys[KEY_B]&KEY_PRESS) key='B';
if(keys[KEY_C]&KEY_PRESS) key='C';
if(keys[KEY_D]&KEY_PRESS) key='D';
if(keys[KEY_E]&KEY_PRESS) key='E';
if(keys[KEY_F]&KEY_PRESS) key='F';
if(keys[KEY_G]&KEY_PRESS) key='G';
if(keys[KEY_H]&KEY_PRESS) key='H';
if(keys[KEY_I]&KEY_PRESS) key='I';
if(keys[KEY_J]&KEY_PRESS) key='J';
if(keys[KEY_K]&KEY_PRESS) key='K';
if(keys[KEY_L]&KEY_PRESS) key='L';
if(keys[KEY_M]&KEY_PRESS) key='M';
if(keys[KEY_N]&KEY_PRESS) key='N';
if(keys[KEY_O]&KEY_PRESS) key='O';
if(keys[KEY_P]&KEY_PRESS) key='P';
if(keys[KEY_Q]&KEY_PRESS) key='Q';
if(keys[KEY_R]&KEY_PRESS) key='R';
if(keys[KEY_S]&KEY_PRESS) key='S';
if(keys[KEY_T]&KEY_PRESS) key='T';
if(keys[KEY_U]&KEY_PRESS) key='U';
if(keys[KEY_V]&KEY_PRESS) key='V';
if(keys[KEY_W]&KEY_PRESS) key='W';
if(keys[KEY_X]&KEY_PRESS) key='X';
if(keys[KEY_Y]&KEY_PRESS) key='Y';
if(keys[KEY_Z]&KEY_PRESS) key='Z';
if(keys[KEY_SPACE]&KEY_PRESS) key=' ';
if(keys[KEY_ENTER]&KEY_PRESS) key='\n';
if(key!=255)
{
if(key>=' '&&key<='Z')
{
draw_tile(input_x,input_y,key-' ');
}
if(input_x==33)
{
input_x=32;
}
if(key=='\n')
{
swap_screen();
set_sprite(0,input_x*4,input_y*8-5,SPRITE_END);
swap_screen();
set_sprite(0,input_x*4,input_y*8-5,SPRITE_END);
bright_down();
save_best();
save_to_file("savelist.bin");
output_expertlist();
return;
}
if(key=='0'||joystick()&JOY_LEFT)
{
for (i=0;i<8;i++) bestlist[n_list].name[i]='.';
put_string (25,input_y,bestlist[n_list].name);
input_x=24;
}
bestlist[n_list].name[(input_x-25)]=key;
input_x++;
if(input_x==33)
{
input_x=32;
}
}
// cursor
{
set_sprite(0,input_x*4,input_y*8-5,5);
swap_screen();
}
{
set_sprite(0,input_x*4,input_y*8-5,4);
swap_screen();
}
else
{
sfx_play(SFX_MOVE,8);
}
}
}
// game over
void time_over()
{
sfx_play(SFX_TIMEOVER,8);
bright_down();
set_sprite(0,0,0,SPRITE_END);
set_sprite(1,0,0,SPRITE_END);
swap_screen();
set_sprite(0,0,0,SPRITE_END);
set_sprite(1,0,0,SPRITE_END);
draw_image(0,0,IMG_TIME_OVER);
swap_screen();
bright_up();
press_start();
bright_down();
enter_name();
new_game();
}
// output time on screen
void output_time()
{
u8 i;
u8 sec, min;
select_image(IMG_FONT);
color_key(15);
t_total
=t
-(time()-t_old
);
min=(t_total/50)/60;
sec=(t_total/50)%60;
for (i=0;i<=1;i++)
{
draw_tile_key(4-i,15,16+(min%10));
min/=10;
draw_tile_key(6-i,15,16+(sec%10));
sec/=10;
}
if (t_total<=0) time_over();
}
// setup dot
void dot_set()
{
select_image(IMG_TILES);
color_key(15);
if (scr_map[map_x][map_y]==0)
{
sfx_play(SFX_DOTSET,8);
scr_map[map_x][map_y]=1;
draw_tile_key(map_x*4+(offset_x/4),map_y*4+(offset_y/8),12);
draw_tile_key(map_x*4+(offset_x/4+1),map_y*4+(offset_y/8),13);
draw_tile_key(map_x*4+(offset_x/4),map_y*4+(offset_y/8+1),14);
draw_tile_key(map_x*4+(offset_x/4+1),map_y*4+(offset_y/8+1),15);
swap_screen();
}
else
{
sfx_play(SFX_DOTDEL,8);
scr_map[map_x][map_y]=0;
draw_tile_key(map_x*4+(offset_x/4),map_y*4+(offset_y/8),4);
draw_tile_key(map_x*4+(offset_x/4+1),map_y*4+(offset_y/8),5);
draw_tile_key(map_x*4+(offset_x/4),map_y*4+(offset_y/8+1),6);
draw_tile_key(map_x*4+(offset_x/4+1),map_y*4+(offset_y/8+1),7);
swap_screen();
}
}
//calculation score
void win()
{
u16 score=0;
u16 time_bonus;
u8 multiplier=0;
u8 i;
u8 sec, min;
switch (level)
{
case 2:
multiplier=5;
break;
case 3:
multiplier=10;
break;
}
if ((time()-t_old
)<t_level
/20)
{
score=10*multiplier;
time_bonus=t_level/10;
t=t_total+time_bonus;
}
else if ((time()-t_old
)<t_level
/10)
{
score=5*multiplier;
time_bonus=t_level/20;
t=t_total+time_bonus;
}
else if ((time()-t_old
)<t_level
/5)
{
score=2*multiplier;
time_bonus=50;
t=t_total+time_bonus;
}
else
{
score=1*multiplier;
time_bonus=0;
t=t_total;
}
if (score==0) score=1;
summ_score+=score;
sfx_play(SFX_COMPLETED,8);
while(joystick()||mouse_position()==MOUSE_LBTN);
set_sprite(0,0,0,SPRITE_END);
set_sprite(1,0,0,SPRITE_END);
swap_screen();
set_sprite(0,0,0,SPRITE_END);
set_sprite(1,0,0,SPRITE_END);
draw_image(11,9,IMG_LEVEL_COMPLETED);
select_image(IMG_FONT);
color_key(15);
min=(time_bonus/50)/60;
sec=(time_bonus/50)%60;
for (i=0;i<=1;i++)
{
draw_tile_key(24-i,13,16+(min%10));
min/=10;
draw_tile_key(26-i,13,16+(sec%10));
sec/=10;
}
swap_screen();
press_start();
level_gen();
}
// checking map
void checking()
{
i8 x,y;
u8 chk=TRUE;
for (y=0;y<size_level-1;y++)
for (x=0;x<size_level-1;x++)
{
if(num_map[x][y]!=scr_map[x][y]+scr_map[x+1][y]+scr_map[x][y+1]+scr_map[x+1][y+1]) chk=FALSE;
}
if (chk==TRUE) win();
}
// update screen cursor sprites
void animation()
{
set_sprite(0,map_x*16+offset_x,map_y*32+offset_y,1);
set_sprite(1,mouse_x,mouse_y,6);
swap_screen();
}
////////////////////////////////////////////////////////////
void main(void)
{
u8 key,i;
u8 mouse_en=TRUE;
sprites_start();
start_screen();
bestlist_init();
save_best();
load_from_file("savelist.bin");
load_best();
mouse_clipping(4,8,152,184);
//mouse_setup(152,184);
new_game();
while (TRUE)
{
output_time();
mouse_position();
key=joystick();
// keyboard control
if(key!=FALSE)
{
mouse_en=FALSE;
mouse_x=152;
mouse_y=184;
mouse_setup(152,184);
if(key&JOY_FIRE)
{
dot_set();
checking();
}
if(key&JOY_UP)
{
map_y--;
if (map_y<0) map_y=0;
}
if(key&JOY_DOWN)
{
map_y++;
if (map_y>size_level-1) map_y=size_level-1;
}
if(key&JOY_LEFT)
{
map_x--;
if (map_x<0) map_x=0;
}
if(key&JOY_RIGHT)
{
map_x++;
if (map_x>size_level-1)
{
while (TRUE)
{
output_time();
set_sprite(0,132,32,0);
set_sprite(1,mouse_x,mouse_y,6);
swap_screen();
if(joystick()&JOY_LEFT)
{
map_x=size_level-1;
break;
}
if(joystick()&JOY_FIRE)
{
sfx_play(SFX_DOTDEL,8);
bright_down();
set_sprite(0,0,0,SPRITE_END);
set_sprite(1,0,0,SPRITE_END);
swap_screen();
set_sprite(0,0,0,SPRITE_END);
set_sprite(1,0,0,SPRITE_END);
enter_name();
new_game();
break;
}
}
}
}
while (joystick())
{
output_time();
animation();
}
}
// mouse control
if (mouse_x<150 || mouse_y<180) mouse_en=TRUE;
if (mouse_en==TRUE)
{
mouse_setup(mouse_x,mouse_y);
map_x=(mouse_x-offset_x+4)/16;
if (map_x<0) map_x=0;
if (map_x>size_level-1) map_x=size_level-1;
map_y=(mouse_y-offset_y+8)/32;
if (map_y<0) map_y=0;
if (map_y>size_level-1) map_y=size_level-1;
if (mouse_x>128&&mouse_y<56)
{
while (mouse_x>128&&mouse_y<56)
{
i=mouse_position();
output_time();
set_sprite(0,132,32,0);
set_sprite(1,mouse_x,mouse_y,6);
swap_screen();
if(i==MOUSE_LBTN)
{
sfx_play(SFX_DOTDEL,8);
bright_down();
set_sprite(0,0,0,SPRITE_END);
set_sprite(1,0,0,SPRITE_END);
swap_screen();
set_sprite(0,0,0,SPRITE_END);
set_sprite(1,0,0,SPRITE_END);
enter_name();
new_game();
break;
}
}
}
i=mouse_position();
if (i==MOUSE_LBTN)
{
dot_set();
checking();
while(mouse_position()==MOUSE_LBTN)
{
output_time();
animation();
}
}
}
animation();
}
}