#include <stdio.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <dirent.h>
#include <cstdlib>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"
#include "SDL/SDL_mixer.h"
#include "brikx.h"
#include "button.h"

char tileset [256];
bool fullscreen=false,verbose=false,autonormal=false,autoreload=true,nosound=false;
#ifdef	WIZ
int GRAVITY=120;
#else
int GRAVITY=100;
#endif
int difficulty=1,bgalpha=128,CURSOR=0;
SDL_Surface *screen=NULL;
const char *mode_name[MODES]={"Normal","Build","Clear","Undo","Reload","Save","Push","Swap",""};
char FILE_CONFIG[1024];
#define DIFFICULTY_MAX  3
const char *diffstr[DIFFICULTY_MAX+1]={"Easy","Normal","Hard","Sucks"};
const char *diffchar[DIFFICULTY_MAX+1]={"E","N","H","S"};
enum modes {MODE_NORMAL,MODE_BUILD,MODE_CLEAR,MODE_UNDO,MODE_RELOAD,MODE_SAVE,MODE_PUSH,MODE_SWAP,MODE_END};
enum directions {NONE=0,UP,DOWN,LEFT,RIGHT,PUSHLEFT,PUSHRIGHT,SWAPTOLEFT,SWAPTORIGHT};
int cost[MODES]=     {0,      100,       200,      200,        500,      500,      300,       300,      0};
Mix_Music   *music_play=NULL;
int volume_music=112;

#ifdef	WIZ

#define WIZSPEED	160

#define	WIZ_A		(20)
#define	WIZ_B		(21)
#define	WIZ_X		(22)
#define	WIZ_Y		(23)
#define	WIZ_L		(7)
#define	WIZ_R		(6)
#define	WIZ_MENU	(9)
#define	WIZ_SELECT	(8)
#define	WIZ_LEFT	(16)
#define	WIZ_RIGHT	(17)
#define	WIZ_UP		(18)
#define	WIZ_DOWN	(19)
#define	WIZ_VOLUP	(10)
#define	WIZ_VOLDOWN	(11)

volatile uint32_t *mem32 = NULL;
volatile uint16_t *mem16 = NULL;
int memhandle;

int wiz_init()
{
	memhandle = open("/dev/mem", O_RDWR);
	if(memhandle < 0) {
		fprintf(stderr,"ERROR: Cannot access /dev/mem\n");
		return -1;
	}
	mem32 = (volatile uint32_t*)mmap(0, 0x20000, PROT_READ|PROT_WRITE, MAP_SHARED, memhandle, 0xC0000000);
	if(mem32 == (volatile uint32_t*)0xFFFFFFFF) {
		fprintf(stderr,"ERROR: Wrong address\n");
		return -1;
	}
	mem16 = (volatile uint16_t*)mem32;
	return 0;
}

uint32_t wiz_getkeys()
{
	return ~((mem16[0xa098>>1]<<16) | mem16[0xa058>>1]);
}

void wiz_close()
{
	close(memhandle);
}

#endif

void TimeOut()
{
     SDL_Event event;
     int quit=0;
	 SDL_FillRect(screen,NULL,0);
	 SDL_Surface *text = NULL;
    SDL_Color color={200,255,220};
    TTF_Font *font=TTF_OpenFont(FONTNAME_SCORE,FONTSIZE_SCORE),*smallfont=TTF_OpenFont(FONTNAME_SCORE,FONTSIZE_SCORE);
	 text = TTF_RenderText_Solid(font,"Out of time!",color);
#ifdef	WIZRES
         PutSurface(text,screen,135,60);
#else
         PutSurface(text,screen,270,120);
#endif
	 SDL_Flip(screen);
     while (!quit)
       {
		   SDL_Delay(DELAY);
			   while (SDL_PollEvent(&event))
				   if (event.type==SDL_KEYDOWN || event.type==SDL_MOUSEBUTTONDOWN
#ifdef	WIZ
						   ||   (wiz_getkeys() & (
			   (1<<WIZ_LEFT)	|
			   (1<<WIZ_RIGHT)	|
			   (1<<WIZ_DOWN)	|
			   (1<<WIZ_UP)		|
			   (1<<WIZ_SELECT)	|
			   (1<<WIZ_L)		|
			   (1<<WIZ_R)		|
			   (1<<WIZ_X)		|
			   (1<<WIZ_Y)		|
			   (1<<WIZ_A)		|
			   (1<<WIZ_B)		|
			   (1<<WIZ_MENU)   ))
#endif
						   )   quit=1;
       }
#ifdef	WIZ
	 while((wiz_getkeys() & (
			   (1<<WIZ_LEFT)	|
			   (1<<WIZ_RIGHT)	|
			   (1<<WIZ_DOWN)	|
			   (1<<WIZ_UP)		|
			   (1<<WIZ_SELECT)	|
			   (1<<WIZ_L)		|
			   (1<<WIZ_R)		|
			   (1<<WIZ_X)		|
			   (1<<WIZ_Y)		|
			   (1<<WIZ_A)		|
			   (1<<WIZ_B)		|
			   (1<<WIZ_MENU)   )))
		 ;
#endif
     SDL_FreeSurface(text);
    TTF_CloseFont(font);
}

void Help(long &timer,char *type="play")
{
    SDL_Surface *help=NULL,*back=NULL,*save=NULL;
    bool quit=false,next;
    int page=0;
    char s[1024];
    long t0=SDL_GetTicks();
    SDL_Event event;
    if (!(back=SDL_CreateRGBSurface(SDL_SRCALPHA | SDL_SWSURFACE | SDL_RLEACCEL,WIDTH-80,HEIGHT-80,BPP,rmask,gmask,bmask,amask))) return;
    save=SDL_CreateRGBSurface(SDL_SRCALPHA | SDL_SWSURFACE | SDL_RLEACCEL,WIDTH,HEIGHT,BPP,rmask,gmask,bmask,amask);
    if (save)
      {
        SDL_LockSurface(save);
        SDL_LockSurface(screen);
        memcpy(save->pixels,screen->pixels,WIDTH*HEIGHT*BPP/8);
        SDL_UnlockSurface(save);
        SDL_UnlockSurface(screen);
      }
    //SDL_FillRect(back,NULL,100*amask);
    SDL_FillRect(back,NULL,0);
    while (!quit)
      {
        sprintf(s,"%s%s/%d.png",DIR_HELP,type,page++);
        if (help) SDL_FreeSurface(help);
#ifdef	WIZ
        if (!(help=LoadImage(s)))
#else
        if (!(help=LoadImage(s,0,0,0)))
#endif

          {
            quit=next=true;
            if (verbose) fprintf(stderr,"INFO: loading help image %s\n",s);
          }
        else
          {
            if (save)
              {
                SDL_LockSurface(save);
                SDL_LockSurface(screen);
                memcpy(screen->pixels,save->pixels,WIDTH*HEIGHT*BPP/8);
                SDL_UnlockSurface(save);
                SDL_UnlockSurface(screen);
              }
#ifdef	WIZRES
            PutSurface(back,screen,20,20);
#else
            PutSurface(back,screen,40,40);
#endif
            PutSurface(help,screen);
            SDL_Flip(screen);
            next=false;
          }
        while (!next)
          {
            SDL_Delay(DELAY);
            while (SDL_PollEvent(&event))
            {
              switch (event.type)
                {
                   case SDL_QUIT:
                     quit=next=true;
                   break;
                   case SDL_MOUSEBUTTONDOWN:
                        if (event.button.button==SDL_BUTTON_MIDDLE)page-=2;
                        next=true;
                   break;
#ifndef	WIZ
                   case SDL_KEYDOWN:
                     switch (event.key.keysym.sym)
                       {
                         case SDLK_PAGEUP:
                         case SDLK_BACKSPACE:
                         case SDLK_LEFT:
                         case SDLK_MINUS:
                                  page-=2;
                                  next=true;
                                break;
                         case SDLK_ESCAPE:
                         case SDLK_q:
                         case SDLK_x:
                         case SDLK_F10:
                                quit=next=true;
                              break;
                         default:next=true;
                       }
                   break;
#endif
            }
          }
       }
      }
    if (timer>=0) timer+=SDL_GetTicks()-t0;
    if (save) SDL_FreeSurface(save);
    SDL_FreeSurface(back);
    if (help) SDL_FreeSurface(help);
}

bool Escape(long &timer)
{
#ifdef	WIZRES
     Button *yes=new Button(135,100,50,20,IMAGE_YES),
             *no=new Button(135,140,50,20,IMAGE_NO);
#else
     Button *yes=new Button(270,200,100,40,IMAGE_YES),
             *no=new Button(270,280,100,40,IMAGE_NO);
#endif
     SDL_Surface *text=LoadImage(IMAGE_ASKQUIT),*back=NULL;
     SDL_Event event;
     if (!(back=SDL_CreateRGBSurface(SDL_SRCALPHA | SDL_SWSURFACE | SDL_RLEACCEL,WIDTH,HEIGHT,BPP,rmask,gmask,bmask,amask))) return true;
     SDL_LockSurface(back);
     SDL_LockSurface(screen);
     memcpy(back->pixels,screen->pixels,WIDTH*HEIGHT*BPP/8);
     SDL_UnlockSurface(back);
     SDL_UnlockSurface(screen);
     long t0=SDL_GetTicks();
     int quit=0;
     while (!quit)
       {
		   SDL_Delay(DELAY);
         SDL_FillRect(screen,NULL,1);
#ifdef	WIZRES
         PutSurface(text,screen,135,60);
#else
         PutSurface(text,screen,270,120);
#endif
         yes->Show(screen,yes->Inside(event)*127+128);
         no->Show(screen,no->Inside(event)*127+128);
         SDL_Flip(screen);
         while (SDL_PollEvent(&event))
           switch (event.type)
             {
               case SDL_MOUSEBUTTONDOWN:
                      if (yes->Inside(event)) quit=2;
                      if (no->Inside(event)) quit=1;
                    break;
               case SDL_KEYDOWN:
                      switch (event.key.keysym.sym)
                         {
                          case SDLK_ESCAPE:
                          case SDLK_n:
                          case SDLK_p:
                                 quit=1;
                               break;
                          case SDLK_RETURN:
                          case SDLK_z:
                          case SDLK_y:
                                 quit=2;
                               break;
                         }
                   break;
             }
       }
     SDL_LockSurface(back);
     SDL_LockSurface(screen);
     memcpy(screen->pixels,back->pixels,WIDTH*HEIGHT*BPP/8);
     SDL_UnlockSurface(back);
     SDL_UnlockSurface(screen);
     SDL_FreeSurface(text);
     SDL_FreeSurface(back);
     delete yes;
     delete no;
     if (timer>=0) timer+=SDL_GetTicks()-t0;
     return quit==2;
}

void PutTile(SDL_Surface *tile,int x,int y)
{
    PutSurface(tile,screen,WINDOWX+x*TILE_WIDTH,WINDOWY+y*TILE_HEIGHT);
}

void PutEmpty(int x,int y)
{
    SDL_Rect p;
    p.x=WINDOWX+x*TILE_WIDTH;
    p.y=WINDOWY+y*TILE_HEIGHT;
    p.w=TILE_WIDTH;
    p.h=TILE_HEIGHT;
    SDL_FillRect(screen,&p,0);
}

bool IsPushed(level l,int x,int y)
{
    return (l[x][y]==PUSHLEFT || l[x][y]==PUSHRIGHT);
}

bool IsPushedLine(level l,int n)
{
    int i;
    bool p=false;
    for (i=0; i<7; i++)
	if (IsPushed(l,i,n)) p=true;
    return p;
}

void Play(char *load="",int playlevel=0)
{
    bool quit,endgame=false,undoable,loadgame=*load;
    float time=0;
    int i,j,k,l,levnum=1,timelimit,mode=MODE_NORMAL,count,shinex,shiney,shineframe,shinedx,shinedy,channel;
    long timer,nulltime,step,paused,score=0;
    SDL_Rect pos;
    char s[1024],leveltext[1024];
#ifdef	WIZRES
    Button *button_build=new Button(250,130,30,30,IMAGE_BUILD),*button_clear=new Button(280,130,30,30,IMAGE_CLEAR),
	   *button_undo=new Button(250,165,30,30,IMAGE_UNDO),*button_normal=new Button(250,200,30,30,IMAGE_NORMAL),
	   *button_reload=new Button(280,165,30,30,IMAGE_RELOAD),*button_save=new Button(280,200,30,30,IMAGE_SAVEBUTTON),
       *button_push=new Button(250,95,30,30,IMAGE_PUSH),*button_swap=new Button(280,95,30,30,IMAGE_SWAP),
       *help=new Button(290,65,20,20,IMAGE_HELPBUTTON);
#else
    Button *button_build=new Button(500,260,60,60,IMAGE_BUILD),*button_clear=new Button(560,260,60,60,IMAGE_CLEAR),
	   *button_undo=new Button(500,330,60,60,IMAGE_UNDO),*button_normal=new Button(500,400,60,60,IMAGE_NORMAL),
	   *button_reload=new Button(560,330,60,60,IMAGE_RELOAD),*button_save=new Button(560,400,60,60,IMAGE_SAVEBUTTON),
       *button_push=new Button(500,190,60,60,IMAGE_PUSH),*button_swap=new Button(560,190,60,60,IMAGE_SWAP),
       *help=new Button(580,130,40,40,IMAGE_HELPBUTTON);
#endif
    level table,del,undo,levity,dpos,direction;
    maxes max;
    SDL_Color color={200,255,220};
    SDL_Event event;
    TTF_Font *font=TTF_OpenFont(FONTNAME_SCORE,FONTSIZE_SCORE),*smallfont=TTF_OpenFont(FONTNAME_SCORE,FONTSIZE_SMALL);
    SDL_Surface *base=LoadImage(BACKGROUND_BASE),*tile[MAX_TILES+1],
		        *clock=LoadImage(IMAGE_TIMER,0,0,0),*sand=LoadImage(IMAGE_SAND),
                *text=NULL,*back=NULL,*cursor=NULL,*shine[SHINE_FRAMES],*toolcursor=LoadImage(IMAGE_TOOLCURSOR,0,0,0);
    
#ifdef	WIZRES
	sprintf(s,IMAGE_GAMECURSOR);
	cursor=LoadImage(s,0,0,0);
#else
    if (cursor=SDL_CreateRGBSurface(SDL_SRCALPHA | SDL_SWSURFACE | SDL_RLEACCEL,TILE_WIDTH,TILE_HEIGHT,BPP,rmask,gmask,bmask,amask))
       {
	   SDL_FillRect(cursor,NULL,200+200*256+200*256*256L+220*amask);
	   SDL_SetAlpha(cursor,SDL_SRCALPHA | SDL_RLEACCEL,220);
       }
#endif
    sprintf(s,"%s%s/shine.pos",DIR_TILESET,tileset);
    if (!LoadShinePos(s,shinedx,shinedy))
        for (i=0; i<SHINE_FRAMES; i++)
        {
          sprintf(s,"%s%d.png",IMAGE_SHINE,i+1);
          if (shine[i]=LoadImage(s,0))
            SDL_SetAlpha(shine[i],SDL_RLEACCEL | SDL_SRCALPHA,128);
          else shine[i]=NULL;
        }
    else
    {
	fprintf(stderr,"INFO: no shine (%s)\n",s);
        for (i=0; i<SHINE_FRAMES; i++)
          shine[i]=NULL;
    }
    if (!font || !smallfont)
      {
        fprintf(stderr,"ERROR: Font file %s not found\n",FONTNAME_SCORE);
        return;
      }
    if (!base)
      {
        fprintf(stderr,"ERROR: Image file %s not found\n",BACKGROUND_BASE);
        return;
      }
    if (!clock)
      {
        fprintf(stderr,"ERROR: Image file %s not found\n",IMAGE_TIMER);
        return;
      }
    for (i=0; i<=MAX_TILES; i++)
      {
	    sprintf(s,"%s%s/%d.png",DIR_TILESET,tileset,i);
	    if (!(tile[i]=LoadImage(s,0)))
	    {
          if (verbose) fprintf(stderr,"WARNING: %s not found, using default tile\n",s);
	      sprintf(s,"%s%s/%d.png",DIR_TILESET,TILESET_DEFAULT,i);
          if (!(tile[i]=LoadImage(s,0)))
            if (verbose) fprintf(stderr,"WARNING: %s not found!\n",s,i);
        }
      }
	int timeout = 0;
   while (!endgame)
   {
	   *leveltext=0;
	   if (playlevel)
	   {
		   levnum=playlevel;
		   endgame=true;
		   score=99999;
	   }
	   quit=false;
	   paused=0;
	   if (timeout || (time>1 && autoreload && score>=cost[MODE_RELOAD]))
	   {
		   time=0;
		   score-=cost[MODE_RELOAD];
	   } 
	   sprintf(s,"%s%d.lvl",DIR_LEVEL,levnum);
	   if (!timeout && (time>1.0 || !(timelimit=LoadLevel(s,table,max,leveltext))))
	   {
		   printf("DEBUG 1\ttime: %.2f\ttimelimit: %d\tfilename:%s\n",time,timelimit,s);
		   if (verbose) fprintf(stderr,"INFO: Level file %s not found!\n",s);
		   endgame=true;
		   if (score)
		   {
			   SDL_FillRect(screen,NULL,0);
			   if (back) SDL_FreeSurface(back);
			   back=NULL;
			   back=LoadImage(BACKGROUND_BYE);
			   if (!back) fprintf(stderr,"ERROR loading BYE\n");
			   if (back)
			   {
				   SDL_SetAlpha(back,SDL_RLEACCEL | SDL_SRCALPHA,128);
				   PutSurface(back,screen);
			   }
			   if (time<=1)
			   {
				   if (text) SDL_FreeSurface(text);
				   text=TTF_RenderText_Solid(font,"Game completed!",color);
				   if (text) PutSurface(text,screen,(WIDTH-text->w)/2,0);
				   else fprintf(stderr,"WARNING: unsuccesful text render\n");
			   }
			   if (text) SDL_FreeSurface(text);
			   sprintf(s,"Difficulty: %s",diffstr[difficulty]);
			   text=TTF_RenderText_Solid(font,s,color);
#ifdef	WIZRES
			   if (text) PutSurface(text,screen,(WIDTH-text->w)/2,25);
#else
			   if (text) PutSurface(text,screen,(WIDTH-text->w)/2,50);
#endif
			   else fprintf(stderr,"WARNING: unsuccesful text render\n");
			   if (time<=1 && difficulty<DIFFICULTY_MAX)
			   {
				   if (text) SDL_FreeSurface(text);
				   text=TTF_RenderText_Solid(font,"Default difficulty level increased",color);
#ifdef	WIZRES
				   if (text) PutSurface(text,screen,(WIDTH-text->w)/2,50);
#else
				   if (text) PutSurface(text,screen,(WIDTH-text->w)/2,100);
#endif
				   else fprintf(stderr,"WARNING: unsuccesful text render\n");
				   difficulty++;
			   }
			   score += (levnum-1)*500;
			   sprintf(s,"End score: %ld",score);
			   if (text) SDL_FreeSurface(text);
			   text=TTF_RenderText_Solid(font,s,color);
#ifdef WIZRES
			   if (text) PutSurface(text,screen,(WIDTH-text->w)/2,100);
#else
			   if (text) PutSurface(text,screen,(WIDTH-text->w)/2,200);
#endif
			   else fprintf(stderr,"WARNING: unsuccesful text render\n");
			   if (text) SDL_FreeSurface(text);
			   sprintf(s,"Level: %d",levnum-1);
			   text=TTF_RenderText_Solid(font,s,color);
#ifdef WIZRES
			   if (text) PutSurface(text,screen,(WIDTH-text->w)/2,150);
#else
			   if (text) PutSurface(text,screen,(WIDTH-text->w)/2,300);
#endif
			   else fprintf(stderr,"WARNING: unsuccesful text render\n");
#ifdef	WIZRES
			   SDL_Flip(screen);
			   SDL_Event event;
			   while (!SDL_PollEvent(&event))
			   {
				   SDL_Delay(100);
			   }
#else
			   strcpy(s,"Enter your name: ");
			   Input(screen,font,color,10,200+2*FONTSIZE_SCORE,s,NAME_MAXLEN);
			   SaveHigh(score,levnum-1,difficulty,s);
#endif
		   }
	   }
	   else
	   {
		   timeout = 0;
		   printf("DEBUG 2\ttime: %.2f\n",time);
		   if (loadgame)
		   {
			   LoadGame(table,score,levnum,timer,timelimit,difficulty,max,load,leveltext);
			   nulltime-=timer;
			   loadgame=false;
		   }
		   for (i=0; i<=7; i++)
			   for (j=0; j<=7; j++)
			   {
				   del[j][i]=levity[j][i]=dpos[j][i]=direction[j][i]=0;
				   undo[j][i]=table[j][i];
				   for (k=i; k<=7; k++)
					   levity[j][i]=levity[j][i] | (table[j][k]==TILE_LEVITATOR);
			   }
		   undoable=false;
		   SDL_SetAlpha(clock,SDL_RLEACCEL | SDL_SRCALPHA,200);
		   max[MODE_UNDO]=1;
		   max[MODE_RELOAD]=1;
		   max[MODE_SAVE]=1;
		   switch (difficulty)
		   {
			   case 3:
				   timelimit=(int)round(timelimit*0.5);
				   max[MODE_RELOAD]=0;
			   case 2:
				   timelimit=(int)round(timelimit*0.6);
				   max[MODE_UNDO]=0;
				   max[MODE_SAVE]=0;
			   case 1:
				   timelimit=(int)round(timelimit*0.8);
		   }
		   max[MODE_SAVE]=1;
		   cost[MODE_RELOAD]=cost[MODE_SAVE]=levnum*100;
		   cost[MODE_UNDO]=levnum*50;
		   if (back)
		   {
			   SDL_FreeSurface(back);
			   back=NULL;
		   }
		   sprintf(s,"%s%d.jpg",DIR_BACKGROUND,levnum);
		   if (bgalpha && !(back=LoadImage(s)))
			   for (i=0; i<BACKGROUND_MAX && !back; i++)
			   {
				   sprintf(s,"%s%d.jpg",DIR_BACKGROUND,rand()%BACKGROUND_MAX);
				   back=LoadImage(s);
			   }
		   if (back) SDL_SetAlpha(back,SDL_RLEACCEL | SDL_SRCALPHA,160);
		   if (text) SDL_FreeSurface(text);
		   SDL_FillRect(screen,NULL,0);
		   sprintf(s,"Level %d",levnum);
		   text=TTF_RenderText_Solid(font,s,color);
#ifdef WIZRES
		   if (text) PutSurface(text,screen,(240-text->w)/2,100);
#else
		   if (text) PutSurface(text,screen,(480-text->w)/2,200);
#endif
		   else fprintf(stderr,"WARNING: unsuccesful text render\n");
		   SDL_Flip(screen);
		   if (*leveltext)
		   {
			   if (text) SDL_FreeSurface(text);
			   text=TTF_RenderText_Solid(font,leveltext,color);
			   if (back) PutSurface(back,screen);
#ifdef	WIZRES
			   if (text) PutSurface(text,screen,(240-text->w)/2,(240-text->h)/2);
#else
			   if (text) PutSurface(text,screen,(480-text->w)/2,(480-text->h)/2);
#endif
			   else fprintf(stderr,"WARNING: unsuccesful text render\n");
			   SDL_Flip(screen);
			   for (i=0; !i; )
			   {
				   SDL_Delay(100);
				   while (SDL_PollEvent(&event))
					   if (event.type==SDL_KEYDOWN || event.type==SDL_MOUSEBUTTONDOWN
#ifdef	WIZ
							   ||   (wiz_getkeys() & (
				   (1<<WIZ_LEFT)	|
				   (1<<WIZ_RIGHT)	|
				   (1<<WIZ_DOWN)	|
				   (1<<WIZ_UP)		|
				   (1<<WIZ_SELECT)	|
				   (1<<WIZ_L)		|
				   (1<<WIZ_R)		|
				   (1<<WIZ_X)		|
				   (1<<WIZ_Y)		|
				   (1<<WIZ_A)		|
				   (1<<WIZ_B)		|
				   (1<<WIZ_MENU)   ))
#endif
							   )   i=1;
			   }
		   }
		   if (back) SDL_SetAlpha(back,SDL_RLEACCEL | SDL_SRCALPHA,bgalpha);
		   mode=MODE_NORMAL;
		   timer=nulltime=SDL_GetTicks();
		   shinex=shiney=0;
		   int cursorx=4, cursory=4, toolx=0, tooly=3;
		   modes modearr[4][2]={
			   {MODE_PUSH,   MODE_SWAP  },
			   {MODE_BUILD,  MODE_CLEAR },
			   {MODE_UNDO,   MODE_RELOAD},
			   {MODE_NORMAL, MODE_SAVE}  
		   };
#define	MOUSEPRESS_NONE	0
#define	MOUSEPRESS_LEFT	1
#define	MOUSEPRESS_RIGHT	2
#define	MOUSEPRESS_MIDDLE	3
#define	MOUSEPRESS_SELECT	9
		   int mousepressed = MOUSEPRESS_NONE;
		   uint32_t last=0;
#ifdef	WIZ
		   Uint32  wizticks[32];
		   for (int ii=0; ii<32; ++ii)
			   wizticks[ii] = 0;
#endif
		   while (!quit)           //START LEVEL
		   {
			   int cal = round(SDL_GetTicks()%2000/5);
			   SDL_SetAlpha(cursor,SDL_SRCALPHA | SDL_RLEACCEL,40+(cal>200?400-cal:cal));
			   mousepressed = MOUSEPRESS_NONE;;
			   shineframe=((timer-nulltime)/SHINE_SPEED)%SHINE_FRAMES;
			   if (!shineframe)
				   while (!(IsTile(table[shinex=rand()%8][shiney=rand()%8]) && IsLivingTile(table[shinex][shiney])))
					   ;
			   SDL_Delay(DELAY);
			   step=SDL_GetTicks()-timer;
			   timer=SDL_GetTicks();
			   time=(timer-nulltime-paused)/1000.0/timelimit;
			   sprintf(s,"%ld",score);
			   if (text) SDL_FreeSurface(text);
			   text=TTF_RenderText_Solid(font,s,color);
			   pos.x=pos.y=0;
#ifdef	WIZRES
			   pos.w=pos.h=240;
#else
			   pos.w=pos.h=480;
#endif
			   SDL_FillRect(screen,&pos,0);
			   if (back) PutSurface(back,screen);

#ifdef	WIZRES
			   PutSurface(base,screen,240,0);
#else
			   PutSurface(base,screen,480,0);
#endif
			   pos.h=(Uint16)round(sand->h/2.0*(1-time));
			   pos.y=sand->h/2-pos.h;
#ifdef	WIZRES
			   if (text) PutSurface(text,screen,314-text->w,34);
#else
			   if (text) PutSurface(text,screen,628-text->w,68);
#endif
			   else fprintf(stderr,"WARNING: unsuccesful text render\n");
#ifdef	WIZRES
			   PutSurface(sand,screen,252,11+pos.y,0,pos.y,sand->w,(int)round(sand->h/2*(1-time)));
			   PutSurface(sand,screen,252,11+sand->h-pos.y,0,sand->h-pos.y,sand->w,(int)round(sand->h/2*time));
			   PutSurface(clock,screen,249,8);
#else
			   PutSurface(sand,screen,504,22+pos.y,0,pos.y,sand->w,(int)round(sand->h/2*(1-time)));
			   PutSurface(sand,screen,504,22+sand->h-pos.y,0,sand->h-pos.y,sand->w,(int)round(sand->h/2*time));
			   PutSurface(clock,screen,499,16);
#endif
			   button_build->Show(screen,mode==MODE_BUILD?255:score>=cost[MODE_BUILD]&&!(difficulty&&!max[MODE_BUILD])?ALPHA2:ALPHA1);
			   button_clear->Show(screen,mode==MODE_CLEAR?255:score>=cost[MODE_CLEAR]&&!(difficulty&&!max[MODE_CLEAR])?ALPHA2:ALPHA1);
			   button_undo->Show(screen,(undoable && score>=cost[MODE_UNDO]&&!(difficulty&&!max[MODE_UNDO]))?ALPHA2:ALPHA1);
			   button_save->Show(screen,(score>=cost[MODE_SAVE]&&!(difficulty&&!max[MODE_SAVE]))?ALPHA2:ALPHA1);
			   button_reload->Show(screen,mode==MODE_RELOAD?255:score>=cost[MODE_RELOAD]&&!(difficulty&&!max[MODE_RELOAD])?ALPHA2:ALPHA1);
			   button_normal->Show(screen,mode==MODE_NORMAL?255:ALPHA2);
			   button_push->Show(screen,mode==MODE_PUSH?255:score>=cost[MODE_PUSH]&&!(difficulty&&!max[MODE_PUSH])?ALPHA2:ALPHA1);
			   button_swap->Show(screen,mode==MODE_SWAP?255:score>=cost[MODE_SWAP]&&!(difficulty&&!max[MODE_SWAP])?ALPHA2:ALPHA1);
			   //switch (mode)
			   //{
			   //    case MODE_PUSH:  toolx=0; tooly=0;break;
			   //    case MODE_SWAP:  toolx=1; tooly=0;break;
			   //    case MODE_BUILD: toolx=0; tooly=1;break;
			   //    case MODE_CLEAR: toolx=1; tooly=1;break;
			   //    case MODE_UNDO:  toolx=0; tooly=2;break;
			   //    case MODE_RELOAD:toolx=1; tooly=2;break;
			   //    case MODE_NORMAL:toolx=0; tooly=3;break;
			   //    case MODE_SAVE:  toolx=1; tooly=3;break;
			   //}
#ifdef	WIZRES
			   PutSurface(toolcursor,screen,250+toolx*30,95+tooly*35);
#endif
			   help->Show(screen);
			   sprintf(s,"%d",cost[MODE_BUILD]);
			   if (difficulty && max[MODE_BUILD]>-1) sprintf(s,"%s(%d)",s,max[MODE_BUILD]);
			   if (text) SDL_FreeSurface(text);
			   text=TTF_RenderText_Solid(smallfont,s,color);
			   if (text)
			   {
				   SDL_SetAlpha(text,SDL_SRCALPHA | SDL_RLEACCEL,mode==MODE_BUILD?255:score>=cost[MODE_BUILD]?ALPHA2:ALPHA1);
#ifdef	WIZRES
				   PutSurface(text,screen,252,154);
#else
				   PutSurface(text,screen,505,308);
#endif
			   }
			   else fprintf(stderr,"WARNING: unsuccesful text render\n");
			   sprintf(s,"%d",cost[MODE_PUSH]);
			   if (difficulty && max[MODE_PUSH]>-1) sprintf(s,"%s(%d)",s,max[MODE_PUSH]);
			   if (text) SDL_FreeSurface(text);
			   text=TTF_RenderText_Solid(smallfont,s,color);
			   if (text)
			   {
				   SDL_SetAlpha(text,SDL_SRCALPHA | SDL_RLEACCEL,mode==MODE_PUSH?255:score>=cost[MODE_PUSH]?ALPHA2:ALPHA1);
#ifdef	WIZRES
				   PutSurface(text,screen,252,119);
#else
				   PutSurface(text,screen,505,238);
#endif
			   }
			   else fprintf(stderr,"WARNING: unsuccesful text render\n");
			   sprintf(s,"%d",cost[MODE_SWAP]);
			   if (difficulty && max[MODE_SWAP]>-1) sprintf(s,"%s(%d)",s,max[MODE_SWAP]);
			   if (text) SDL_FreeSurface(text);
			   text=TTF_RenderText_Solid(smallfont,s,color);
			   if (text)
			   {
				   SDL_SetAlpha(text,SDL_SRCALPHA | SDL_RLEACCEL,mode==MODE_SWAP?255:score>=cost[MODE_SWAP]?ALPHA2:ALPHA1);
#ifdef	WIZRES
				   PutSurface(text,screen,282,119);
#else
				   PutSurface(text,screen,565,238);
#endif
			   }
			   else fprintf(stderr,"WARNING: unsuccesful text render\n");
			   sprintf(s,"%d",cost[MODE_CLEAR]);
			   if (difficulty && max[MODE_CLEAR]>-1) sprintf(s,"%s(%d)",s,max[MODE_CLEAR]);
			   if (text) SDL_FreeSurface(text);
			   text=TTF_RenderText_Solid(smallfont,s,color);
			   if (text)
			   {
				   SDL_SetAlpha(text,SDL_SRCALPHA | SDL_RLEACCEL,mode==MODE_CLEAR?255:score>=cost[MODE_CLEAR]?ALPHA2:ALPHA1);
#ifdef	WIZRES
				   PutSurface(text,screen,282,154);
#else
				   PutSurface(text,screen,565,308);
#endif
			   }
			   else fprintf(stderr,"WARNING: unsuccesful text render\n");
			   sprintf(s,"%d",cost[MODE_UNDO]);
			   if (difficulty && max[MODE_UNDO]>-1) sprintf(s,"%s(%d)",s,max[MODE_UNDO]);
			   if (text) SDL_FreeSurface(text);
			   text=TTF_RenderText_Solid(smallfont,s,color);
			   if (text)
			   {
				   SDL_SetAlpha(text,SDL_SRCALPHA | SDL_RLEACCEL,(undoable && score>=cost[MODE_UNDO])?ALPHA2:ALPHA1);
#ifdef	WIZRES
				   PutSurface(text,screen,252,189);
#else
				   PutSurface(text,screen,505,378);
#endif
			   }
			   else fprintf(stderr,"WARNING: unsuccesful text render\n");
			   sprintf(s,"%d",cost[MODE_RELOAD]);
			   if (difficulty && max[MODE_RELOAD]>-1) sprintf(s,"%s(%d)",s,max[MODE_RELOAD]);
			   if (text) SDL_FreeSurface(text);
			   text=TTF_RenderText_Solid(smallfont,s,color);
			   if (text)
			   {
				   SDL_SetAlpha(text,SDL_SRCALPHA | SDL_RLEACCEL,mode==MODE_RELOAD?255:score>=cost[MODE_RELOAD]?ALPHA2:ALPHA1);
#ifdef	WIZRES
				   PutSurface(text,screen,282,189);
#else
				   PutSurface(text,screen,565,378);
#endif
			   }
			   else fprintf(stderr,"WARNING: unsuccesful text render\n");
			   sprintf(s,"%d",cost[MODE_SAVE]);
			   if (difficulty && max[MODE_SAVE]>-1) sprintf(s,"%s(%d)",s,max[MODE_SAVE]);
			   if (text) SDL_FreeSurface(text);
			   text=TTF_RenderText_Solid(smallfont,s,color);
			   if (text)
			   {
				   SDL_SetAlpha(text,SDL_SRCALPHA | SDL_RLEACCEL,score>=cost[MODE_SAVE]?ALPHA2:ALPHA1);
#ifdef	WIZRES
				   PutSurface(text,screen,282,224);
#else
				   PutSurface(text,screen,565,448);
#endif
			   }
			   else fprintf(stderr,"WARNING: unsuccesful text render\n");
			   sprintf(s,"%d",levnum);
			   if (text) SDL_FreeSurface(text);
			   text=TTF_RenderText_Solid(font,s,color);
#ifdef	WIZRES
			   if (text) PutSurface(text,screen,312-text->w,9);
#else
			   if (text) PutSurface(text,screen,624-text->w,19);
#endif
			   else fprintf(stderr,"WARNING: unsuccesful text render\n");
#ifndef	WIZ
			   if (CURSOR && event.button.x<=TILE_WIDTH*7 && cursor)
				   PutSurface(cursor,screen,event.button.x/TILE_WIDTH*TILE_WIDTH,event.button.y/TILE_HEIGHT*TILE_HEIGHT);
#endif
			   for (count=i=0; i<=7; i++)
				   for (j=0; j<=7; j++)
					   if (IsTile(table[j][i]))
					   {
						   count++;
						   if (i && !IsPushed(direction,j,i) && levity[j][i]  && IsEmpty(table[j][i-1])) direction[j][i]=UP;
						   else
							   if (i<7 && direction[j][i]==NONE && !levity[j][i])
								   switch (table[j][i+1])
								   {
									   case TILE_EMPTY:
										   if (!IsPushedLine(direction,i) && !(i<7 && IsPushedLine(direction,i+1)))
											   direction[j][i]=DOWN;
										   break;
									   case TILE_LEFT:
										   if (j)
										   {
											   table[j-1][i+1]=table[j][i];
											   table[j][i]=TILE_EMPTY;
										   }
										   break;
									   case TILE_RIGHT:
										   if (j<7)
										   {
											   table[j+1][i+1]=table[j][i];
											   table[j][i]=TILE_EMPTY;
										   }
										   break;
									   case TILE_PEAK:
									   case TILE_STRONGRANDOM:
										   if (rand()%2 && j && IsEmpty(table[j-1][i+1]))
										   {
											   table[j-1][i+1]=table[j][i];
											   table[j][i]=TILE_EMPTY;
										   }
										   else if (j<7 && IsEmpty(table[j+1][i+1]))
										   {
											   table[j+1][i+1]=table[j][i];
											   table[j][i]=TILE_EMPTY;
										   }
										   break;
									   case TILE_STRONGPRIORLEFT:
									   case TILE_PRIORLEFT:
										   if (i<7)
										   {
											   if (j && IsEmpty(table[j-1][i+1]))
											   {
												   table[j-1][i+1]=table[j][i];
												   table[j][i]=TILE_EMPTY;
											   }
											   else if (j<7 && IsEmpty(table[j+1][i+1]))
											   {
												   table[j+1][i+1]=table[j][i];
												   table[j][i]=TILE_EMPTY;
											   }
										   }
										   break;
									   case TILE_STRONGPRIORRIGHT:
									   case TILE_PRIORRIGHT:
										   if (i<7)
										   {
											   if (j<7 && IsEmpty(table[j+1][i+1]))
											   {
												   table[j+1][i+1]=table[j][i];
												   table[j][i]=TILE_EMPTY;
											   }
											   else if (j && IsEmpty(table[j-1][i+1]))
											   {
												   table[j-1][i+1]=table[j][i];
												   table[j][i]=TILE_EMPTY;
											   }
										   }
										   break;
								   }
						   if (direction[j][i])
						   {
							   if ((dpos[j][i]+=step)>=GRAVITY)
							   {
								   dpos[j][i]=0;
								   switch (direction[j][i])
								   {
									   case UP:  
										   if (i)
										   {
											   table[j][i-1]=table[j][i];
											   if (shinex==j && shiney==i) shiney--;
										   }
										   if (i>1 && IsEmpty(table[j][i-2])) direction[j][i-1]=UP;
										   direction[j][i]=NONE;
										   table[j][i]=TILE_EMPTY;
										   break;
									   case DOWN:
										   if (i<7)
										   {
											   table[j][i+1]=table[j][i];
											   if (shinex==j && shiney==i) shiney++;
										   }
										   direction[j][i]=NONE;
										   table[j][i]=TILE_EMPTY;
										   if (i<6 && IsEmpty(table[j][i+2])) direction[j][i+1]=DOWN;
										   break;
									   case SWAPTORIGHT:
										   k=table[j+1][i];
										   table[j+1][i]=table[j][i];
										   table[j][i]=k;
										   direction[j][i]=direction[j+1][i]=NONE;
										   dpos[j][i]=dpos[j+1][i]=0;
										   if (shinex==j && shiney==i) shinex++;
										   else if (shinex==j+1 && shiney==i) shinex--;
										   break;
									   case LEFT:
										   if (j)
										   {
											   table[j-1][i]=table[j][i];
											   if (shinex==j && shiney==i) shinex--;
										   }
										   if (i<7 && IsEmpty(table[j-1][i+1]) && !levity[j-1][i]) direction[j-1][i]=DOWN;
										   direction[j][i]=NONE;
										   table[j][i]=TILE_EMPTY;
										   break;
									   case RIGHT:
										   if (j<7)
										   {
											   table[j+1][i]=table[j][i];
											   if (shinex==j && shiney==i) shinex++;
										   }
										   if (i<7 && IsEmpty(table[j+1][i+1]) && !levity[j+1][i]) direction[j+1][i]=DOWN;
										   direction[j][i]=NONE;
										   table[j][i]=TILE_EMPTY;
										   break;
									   case PUSHLEFT:
										   for (k=0; k<=j && k<7; k++)
										   {
											   if (!k && direction[k][i]==PUSHLEFT) direction[k][i]=NONE;
											   if (direction[k+1][i]==PUSHLEFT && IsEmpty(table[k][i]))
											   {
												   table[k][i]=table[k+1][i];
												   if (shinex==k+1 && shiney==i) shinex--;
												   table[k+1][i]=TILE_EMPTY;
												   if (IsTile(table[k-1][i]) && direction[k-1][i]==NONE) direction[k][i]=NONE;
												   else direction[k][i]=PUSHLEFT;
												   direction[k+1][i]=NONE;
											   }   
											   if (!k) direction[k][i]=NONE;
											   if (direction[k+1][i]==PUSHLEFT && !direction[k][i]) direction[k+1][i]=NONE;
										   }
										   break;
									   case PUSHRIGHT:
										   for (k=7; k>=j && k; k--)
										   {
											   if (k==7 && direction[k][i]==PUSHRIGHT) direction[k][i]=NONE;
											   if (direction[k-1][i]==PUSHRIGHT && IsEmpty(table[k][i]))
											   {
												   table[k][i]=table[k-1][i];
												   if (shinex==k-1 && shiney==i) shinex++;
												   table[k-1][i]=TILE_EMPTY;
												   if (IsTile(table[k+1][i]) && direction[k+1][i]==NONE) direction[k][i]=NONE;
												   else direction[k][i]=PUSHRIGHT;
												   direction[k-1][i]=NONE;
											   }   
											   if (k==7) direction[k][i]=NONE;
											   if (direction[k-1][i]==PUSHRIGHT && !direction[k][i]) direction[k-1][i]=NONE;
										   }
										   break;
								   }
							   }
							   else 
								   switch (direction[j][i])
								   {
									   case UP:   PutSurface(tile[table[j][i]],screen,j*TILE_WIDTH+WINDOWX,(int)round((i-dpos[j][i]/float(GRAVITY))*TILE_HEIGHT+WINDOWY));break;
									   case DOWN: PutSurface(tile[table[j][i]],screen,j*TILE_WIDTH+WINDOWX,(int)round((i+dpos[j][i]/float(GRAVITY))*TILE_HEIGHT+WINDOWY));break;
									   case PUSHLEFT:
												  for (k=0; k<7; k++)
													  if (IsTile(table[k-1][i]) && !direction[k-1][i])
													  {
														  direction[k][i]=NONE;
														  dpos[k][i]=0;
													  }
									   case SWAPTOLEFT:
									   case LEFT: PutSurface(tile[table[j][i]],screen,(int)round((j-dpos[j][i]/float(GRAVITY))*TILE_WIDTH)+WINDOWX,i*TILE_HEIGHT+WINDOWY);break;
									   case PUSHRIGHT:
												  for (k=7; k; k--)
													  if (IsTile(table[k+1][i]) && !direction[k+1][i])
													  {
														  direction[k][i]=NONE;
														  dpos[k][i]=0;
													  }
									   case SWAPTORIGHT:
									   case RIGHT:PutSurface(tile[table[j][i]],screen,(int)round((j+dpos[j][i]/float(GRAVITY))*TILE_WIDTH)+WINDOWX,i*TILE_HEIGHT+WINDOWY);break;
								   }
						   }
					   }
					   else
						   if (table[j][i]==TILE_PAINTER)
						   {
							   if (j && IsRYB(table[j-1][i]) && !direction[j-1][i]) table[j-1][i]=TILE_FIRST+((timer-nulltime)/500)%3;
							   if (j<7 && IsRYB(table[j+1][i]) && !direction[j+1][i]) table[j+1][i]=TILE_FIRST+((timer-nulltime)/500)%3;
							   if (i && IsRYB(table[j][i-1]) && !direction[j][i-1]) table[j][i-1]=TILE_FIRST+((timer-nulltime)/500)%3;
							   if (i<7 && IsRYB(table[j][i+1]) && !direction[j][i+1]) table[j][i+1]=TILE_FIRST+((timer-nulltime)/500)%3;
						   }
			   for (i=0; i<=7; i++)
			   {
				   for (l=j=0; j<7; j++)
				   {
					   if (IsPushed(direction,j,i)) l=1;
					   del[j][i]=0;
				   }
				   if (!l)
					   for (j=0; j<=7; j++)
						   del[j][i]=(IsLivingTile(table[j][i]) && !direction[j][i]  && (
									   (j && !direction[j-1][i] && table[j-1][i]==table[j][i] && !(i && levity[j-1][i] && IsEmpty(table[j-1][i-1])) ) ||
									   (i && !direction[j][i-1] && table[j][i-1]==table[j][i]) ||
									   (j<7 && !direction[j+1][i] && table[j+1][i]==table[j][i] && !(i && levity[j+1][i] && IsEmpty(table[j+1][i-1]))) ||
									   (i<7 && !direction[j][i+1] && table[j][i+1]==table[j][i])));
			   }
			   for (i=0; i<=7; i++)
				   for (j=0; j<=7; j++)
					   if (table[j][i]==TILE_DESTRUCTOR)
					   {
						   if (j && IsTile(table[j-1][i]) && !IsPushed(direction,j-1,i)) table[j-1][i]=TILE_DEAD;
						   if (j<7 && IsTile(table[j+1][i]) && !IsPushed(direction,j+1,i)) table[j+1][i]=TILE_DEAD;
						   if (i && IsTile(table[j][i-1]) && !IsPushed(direction,j,i-1)) table[j][i-1]=TILE_DEAD;
						   if (i<7 && IsTile(table[j][i+1]) && !IsPushed(direction,j,i+1)) table[j][i+1]=TILE_DEAD;
					   }
			   for (i=0; i<=7; i++)
				   for (j=0; j<=7; j++)
					   if (del[j][i])
					   {
						   del[j][i]=0;
						   table[j][i]=TILE_EMPTY;
					   }
			   for (i=0; i<=7; i++)
				   for (j=0; j<=7; j++)
					   if (!IsEmpty(table[j][i]) && direction[j][i]==NONE) PutTile(tile[table[j][i]],j,i);
			   if (shineframe>=0 && shineframe<SHINE_FRAMES && (((timer-nulltime)/SHINE_SPEED)%(SHINE_FRAMES*2)<SHINE_FRAMES) && IsLivingTile(table[shinex][shiney]))
			   {
				   if (shine[shineframe] && !direction[shinex][shiney])
					   PutSurface(shine[shineframe],screen,shinedx-shine[shineframe]->w/2+WINDOWX+shinex*TILE_WIDTH,shinedy-shine[shineframe]->h/2+WINDOWY+shiney*TILE_HEIGHT);
				   else
					   if (shine[shineframe])
						   switch (direction[shinex][shiney])
						   {

							   case UP:   PutSurface(shine[shineframe],screen,shinedx-shine[shineframe]->w/2+shinex*TILE_WIDTH+WINDOWX,shinedy-shine[shineframe]->h/2+(int)round((shiney-dpos[shinex][shiney]/float(GRAVITY))*TILE_HEIGHT+WINDOWY));break;
							   case DOWN: PutSurface(shine[shineframe],screen,shinedx-shine[shineframe]->w/2+shinex*TILE_WIDTH+WINDOWX,shinedy-shine[shineframe]->h/2+(int)round((shiney+dpos[shinex][shiney]/float(GRAVITY))*TILE_HEIGHT+WINDOWY));break;
							   case PUSHLEFT:
							   case SWAPTOLEFT:
							   case LEFT: PutSurface(shine[shineframe],screen,shinedx-shine[shineframe]->w/2+(int)round((shinex-dpos[shinex][shiney]/float(GRAVITY))*TILE_WIDTH)+WINDOWX,shinedy-shine[shineframe]->h/2+shiney*TILE_HEIGHT+WINDOWY);break;
							   case PUSHRIGHT:
							   case SWAPTORIGHT:
							   case RIGHT:PutSurface(shine[shineframe],screen,shinedx-shine[shineframe]->w/2+(int)round((shinex+dpos[shinex][shiney]/float(GRAVITY))*TILE_WIDTH)+WINDOWX,shinedy-shine[shineframe]->h/2+shiney*TILE_HEIGHT+WINDOWY);break;
						   }
			   }
			   quit=!count || time>1;
#ifdef	WIZRES
			   PutSurface(cursor,screen,cursorx*TILE_WIDTH,cursory*TILE_HEIGHT);
#endif
			   SDL_Flip(screen);
#ifdef	WIZ
			   if (wiz_getkeys() & (1<<WIZ_LEFT))   {if (wizticks[WIZ_LEFT]  +WIZSPEED<SDL_GetTicks()) { wizticks[WIZ_LEFT]  =SDL_GetTicks(); cursorx = (--cursorx+8)%8;}} else wizticks[WIZ_LEFT]=0;
			   if (wiz_getkeys() & (1<<WIZ_RIGHT))  {if (wizticks[WIZ_RIGHT] +WIZSPEED<SDL_GetTicks()) { wizticks[WIZ_RIGHT] =SDL_GetTicks(); cursorx = (++cursorx+8)%8;}} else wizticks[WIZ_RIGHT]=0;
			   if (wiz_getkeys() & (1<<WIZ_DOWN))   {if (wizticks[WIZ_DOWN]  +WIZSPEED<SDL_GetTicks()) { wizticks[WIZ_DOWN]  =SDL_GetTicks(); cursory = (++cursory+8)%8;}} else wizticks[WIZ_DOWN]=0;
			   if (wiz_getkeys() & (1<<WIZ_UP))     {if (wizticks[WIZ_UP]    +WIZSPEED<SDL_GetTicks()) { wizticks[WIZ_UP]    =SDL_GetTicks(); cursory = (--cursory+8)%8;}} else wizticks[WIZ_UP]=0;
			   if (wiz_getkeys() & (1<<WIZ_SELECT)) {if (wizticks[WIZ_SELECT]+WIZSPEED<SDL_GetTicks()) { wizticks[WIZ_SELECT]=SDL_GetTicks(); mousepressed = MOUSEPRESS_SELECT;}} else wizticks[WIZ_SELECT]=0;
			   if (wiz_getkeys() & (1<<WIZ_L))      {if (wizticks[WIZ_L]     +WIZSPEED<SDL_GetTicks()) { wizticks[WIZ_L]     =SDL_GetTicks(); mousepressed = MOUSEPRESS_LEFT;}} else wizticks[WIZ_L]=0;
			   if (wiz_getkeys() & (1<<WIZ_R))      {if (wizticks[WIZ_R]     +WIZSPEED<SDL_GetTicks()) { wizticks[WIZ_R]     =SDL_GetTicks(); mousepressed = MOUSEPRESS_RIGHT;}} else wizticks[WIZ_R]=0;
			   if (wiz_getkeys() & (1<<WIZ_X))      {if (wizticks[WIZ_X]     +WIZSPEED<SDL_GetTicks()) { wizticks[WIZ_X]     =SDL_GetTicks(); tooly=(++tooly)%4;}} else wizticks[WIZ_X]=0;
			   if (wiz_getkeys() & (1<<WIZ_Y))      {if (wizticks[WIZ_Y]     +WIZSPEED<SDL_GetTicks()) { wizticks[WIZ_Y]     =SDL_GetTicks(); tooly=(--tooly+4)%4;}} else wizticks[WIZ_Y]=0;
			   if (wiz_getkeys() & (1<<WIZ_A))      {if (wizticks[WIZ_A]     +WIZSPEED<SDL_GetTicks()) { wizticks[WIZ_A]     =SDL_GetTicks(); toolx=0;}} else wizticks[WIZ_A]=0;
			   if (wiz_getkeys() & (1<<WIZ_B))      {if (wizticks[WIZ_B]     +WIZSPEED<SDL_GetTicks()) { wizticks[WIZ_B]     =SDL_GetTicks(); toolx=1;}} else wizticks[WIZ_B]=0;
			   if (wiz_getkeys() & (1<<WIZ_MENU))   quit=endgame=Escape(paused);
#endif
			   while (SDL_PollEvent(&event))
			   {
				   switch (event.type)
				   {
					   case SDL_QUIT:
						   quit=endgame=Escape(paused);
						   break;
#ifndef	WIZ
					   case SDL_KEYDOWN:
						   switch (event.key.keysym.sym)
						   {
							   case ' ':
								   mode=MODE_NORMAL;
								   break;
							   case SDLK_f:
								   screen=SDL_SetVideoMode(WIDTH,HEIGHT,BPP,SDL_SWSURFACE | (fullscreen=!fullscreen)?SDL_FULLSCREEN:0);
								   for (i=0; i<=7; i++)
									   for (j=0; j<=7; j++)
										   PutTile(tile[table[j][i]],j,i);
								   break;
							   case SDLK_c:
								   CURSOR=!CURSOR;
								   break;
							   case SDLK_F1:
							   case SDLK_h:
								   SDL_FillRect(screen,NULL,1);
								   Help(paused,"play");
							   case SDLK_r:
								   for (i=0; i<=7; i++)
									   for (j=0; j<=7; j++)
										   PutTile(tile[table[j][i]],j,i);
								   break;
							   case SDLK_TAB:
								   while (score<cost[++mode] || mode==MODE_UNDO || mode==MODE_SAVE || mode==MODE_RELOAD)
									   ;
								   if (mode==MODE_END) mode=0;
								   break;
							   case SDLK_p:
							   case SDLK_ESCAPE:
							   case SDLK_q:
							   case SDLK_F10:
								   /*
								   SDL_FillRect(screen,NULL,0);
								   for (int si=0; si<SHINE_FRAMES; si++)
									   PutSurface(shine[si],screen,(si%10)*60, (si/10)*60);
								   SDL_Flip(screen);
								   while (!SDL_PollEvent(&event))
									   ;
									   **********************************/
								   if (SDL_GetModState() & KMOD_RCTRL)
									   for (i=0; i<MODES; i++) max[i]=-1;  // WILL BE REMOVED
								   else
									   quit=endgame=Escape(paused);
								   break;
							   case SDLK_F12: // WILL BE REMOVED
								   if (SDL_GetModState() & KMOD_RCTRL)
									   for (i=0; i<=7; i++)
										   for (j=0; j<=7; j++)
											   table[j][i]=TILE_EMPTY;
								   break;
							   case SDLK_F11:  // WILL BE REMOVED
								   if (SDL_GetModState() & KMOD_RCTRL) nulltime=timer;
								   break;
						   }
						   break;
#endif
					   case SDL_MOUSEBUTTONDOWN:
						   switch (event.button.button)
						   {
							   case SDL_BUTTON_LEFT:
								   mousepressed  = MOUSEPRESS_LEFT;
								   break;
							   case SDL_BUTTON_RIGHT:
								   mousepressed  = MOUSEPRESS_RIGHT;
								   break;
							   case SDL_BUTTON_MIDDLE:
								   mousepressed  = MOUSEPRESS_MIDDLE;
								   break;
						   }
						   break;
				   }
			   }
			   if (mousepressed)
			   {
						   //	MOUSEBUTTON
				   if (event.type == SDL_MOUSEBUTTONDOWN || mousepressed == MOUSEPRESS_SELECT)
				   {
							if (event.type!= SDL_MOUSEBUTTONDOWN)
								event.button.x=event.button.y=9999;
						   j=(event.button.x-WINDOWX)/TILE_WIDTH;
						   i=(event.button.y-WINDOWY)/TILE_HEIGHT;
						   if (((mousepressed == MOUSEPRESS_SELECT && modearr[tooly][toolx] == MODE_BUILD) || button_build->Inside(event)) && score>=cost[MODE_BUILD] && !(difficulty && !max[MODE_BUILD])) mode=MODE_BUILD;
						   else if (help->Inside(event))
						   {
							   SDL_FillRect(screen,NULL,1);
							   Help(paused,"play");
						   }			    
						   else if (((mousepressed == MOUSEPRESS_SELECT && modearr[tooly][toolx] == MODE_CLEAR) || button_clear->Inside(event)) && score>=cost[MODE_CLEAR] && !(difficulty && !max[MODE_CLEAR])) mode=MODE_CLEAR;
						   else if (((mousepressed == MOUSEPRESS_SELECT && modearr[tooly][toolx] == MODE_PUSH) || button_push->Inside(event)) && score>=cost[MODE_PUSH] && !(difficulty && !max[MODE_PUSH])) mode=MODE_PUSH;
						   else if (((mousepressed == MOUSEPRESS_SELECT && modearr[tooly][toolx] == MODE_SWAP) || button_swap->Inside(event)) && score>=cost[MODE_SWAP] && !(difficulty && !max[MODE_SWAP])) mode=MODE_SWAP;
						   else if (((mousepressed == MOUSEPRESS_SELECT && modearr[tooly][toolx] == MODE_SAVE) || button_save->Inside(event)) && score>=cost[MODE_SAVE] && !(difficulty && !max[MODE_SAVE]))
						   {
							   if (!SaveGame(table,score-cost[MODE_SAVE],levnum,step=timer-nulltime,timelimit,difficulty,max,"0",leveltext))
								   score-=cost[MODE_SAVE];
							   if (difficulty) max[MODE_SAVE]--;
						   }
						   else if (((mousepressed == MOUSEPRESS_SELECT && modearr[tooly][toolx] == MODE_NORMAL) || button_normal->Inside(event))) mode=MODE_NORMAL;
						   else if (((mousepressed == MOUSEPRESS_SELECT && modearr[tooly][toolx] == MODE_UNDO) || button_undo->Inside(event)) && score>=cost[MODE_UNDO] && !(difficulty && !max[MODE_UNDO])) 
						   {
							   if (difficulty) max[MODE_UNDO]--;
							   undoable=false;
							   score-=cost[MODE_UNDO];
							   for (i=0; i<=7; i++)
								   for (j=0; j<=7; j++)
									   PutTile(tile[table[j][i]=undo[j][i]],j,i);
						   }
						   else if (((mousepressed == MOUSEPRESS_SELECT && modearr[tooly][toolx] == MODE_RELOAD) || button_reload->Inside(event)) && score>=cost[MODE_RELOAD] && !(difficulty && !max[MODE_RELOAD]))
						   {
							   quit=true;
							   if (difficulty) max[MODE_RELOAD]--;
							   score-=cost[MODE_RELOAD];
						   }
				   }
				   else
				   {
					   j=cursorx;
					   i=cursory;
				   }
						   if (mousepressed==MOUSEPRESS_MIDDLE) mode=MODE_NORMAL;
						   else if (j<=7 && i<=7)
							   switch (mode)
							   {
								   case MODE_NORMAL:
									   switch (mousepressed)
									   {
										   case MOUSEPRESS_LEFT:
											   if (IsLivingTile(table[j][i]) && j && IsEmpty(table[j-1][i]) && !(!levity[j-1][i] && i && IsTile(table[j-1][i-1])) && !(levity[j-1][i] && i<7 && IsTile(table[j-1][i+1])))
											   {
												   undoable=true;
												   memcpy(undo,table,sizeof(level));
												   direction[j][i]=LEFT;
#ifdef	WIZ
												   cursorx = (--cursorx+8)%8;
#endif
											   }
											   break;
										   case MOUSEPRESS_RIGHT:
											   if (IsLivingTile(table[j][i]) && j<7 && IsEmpty(table[j+1][i])  && !(!levity[j+1][i] && i && IsTile(table[j+1][i-1])) && !(levity[j+1][i] && i<7 && IsTile(table[j+1][i+1])))
											   {
												   undoable=true;
												   memcpy(undo,table,sizeof(level));
												   direction[j][i]=RIGHT;
#ifdef	WIZ
												   cursorx = (++cursorx)%8;
#endif
											   }
											   break;
									   }
									   break;
								   case MODE_SWAP:
									   int X,Y;
									   if (event.type = SDL_MOUSEBUTTONDOWN)
									   {
										   X = event.button.x;
										   Y = event.button.y;
									   }
									   else
									   {
										   X = cursorx + TILE_WIDTH/2;
										   Y = cursory + TILE_HEIGHT/2;
									   }
									   if (score>=cost[MODE_SWAP] && !(difficulty && !max[MODE_SWAP]) && X>TILE_WIDTH/2 && X<TILE_WIDTH*7.5)
									   {
										   k=(X-TILE_WIDTH/2)/TILE_WIDTH;
										   if (IsLivingTile(table[k][i]) && IsLivingTile(table[k+1][i]))
										   {
											   score-=cost[MODE_SWAP];
											   if (difficulty) if (!--max[MODE_SWAP]) 
											   {
												   mode=MODE_NORMAL;
												   toolx = 0;
												   tooly = 3;
											   }
											   direction[k][i]=SWAPTORIGHT;
											   direction[k+1][i]=SWAPTOLEFT;
										   }
									   }
									   break;
								   case MODE_PUSH:
									   if (score>=cost[MODE_PUSH] && !(difficulty && !max[MODE_PUSH]))
									   {
										   if (difficulty) if (!--max[MODE_PUSH])
										   {
											   toolx = 0;
											   tooly = 3;
											   mode=MODE_NORMAL;
										   }
										   score-=cost[MODE_PUSH];
										   undoable=true;
										   memcpy(undo,table,sizeof(level));
										   if (autonormal) 
										   {
											   toolx = 0;
											   tooly = 3;
											   mode=MODE_NORMAL;
										   }
										   switch (mousepressed)
										   {
											   case MOUSEPRESS_RIGHT:
												   for (k=j; k<7 && (IsTile(table[k][i]) || IsEmpty(table[k][i])); k++)
													   if (IsTile(table[k][i]) && (IsTile(table[k+1][i]) || IsEmpty(table[k+1][i]))) direction[k][i]=PUSHRIGHT;
												   break;
											   case MOUSEPRESS_LEFT:
												   for (k=j; k && (IsTile(table[k][i]) || IsEmpty(table[k][i])); k--)
													   if (IsTile(table[k][i]) && (IsTile(table[k-1][i]) || IsEmpty(table[k-1][i]))) direction[k][i]=PUSHLEFT;
												   break;
										   }
									   }
									   break;
								   case MODE_BUILD:
									   if (IsEmpty(table[j][i]) && score>=cost[MODE_BUILD] && !(difficulty && !max[MODE_BUILD]))
									   {
										   if (difficulty) if (!--max[MODE_BUILD]) 
										   {
											   toolx = 0;
											   tooly = 3;
											   mode=MODE_NORMAL;
										   }
										   score-=cost[MODE_BUILD];
										   table[j][i]=TILE_WALL;
										   PutTile(tile[TILE_WALL],j,i);
										   if (autonormal) 
										   {
											   toolx = 0;
											   tooly = 3;
											   mode=MODE_NORMAL;
										   }
									   }
									   break;
								   case MODE_CLEAR:
									   if (IsWeak(table[j][i]) && score>=cost[MODE_CLEAR] && !(difficulty && !max[MODE_CLEAR]))
									   {
										   if (difficulty) if (!--max[MODE_CLEAR])
										   {
											   toolx = 0;
											   tooly = 3;
											   mode=MODE_NORMAL;
										   }
										   score-=cost[MODE_CLEAR];
										   table[j][i]=TILE_EMPTY;
										   PutEmpty(j,i);
										   if (autonormal)
										   {
											   toolx = 0;
											   tooly = 3;
											   mode=MODE_NORMAL;
										   }
									   }
									   break;
							   }
						   //	END MOUSEBUTTON
			   }
		   }
		   if (time<=1 && !count) score+=(long)round((1-time)*levnum*100)+levnum*(10+50L*difficulty*difficulty);
		   if
			   (!count) levnum++;
		   else if (time>=1.0)
		   {
			   timeout = 1;
			   TimeOut();
		   }
		   printf("DEBUG 3\ttime: %.2f\n",time);
	   }
   }
    if (base) SDL_FreeSurface(base);
    if (text) SDL_FreeSurface(text);
    if (clock) SDL_FreeSurface(clock);
    if (toolcursor) SDL_FreeSurface(toolcursor);
    if (sand) SDL_FreeSurface(sand);
    if (back) SDL_FreeSurface(back);
    if (cursor) SDL_FreeSurface(cursor);
    TTF_CloseFont(font);
    TTF_CloseFont(smallfont);
    delete button_build;
    delete button_clear;
    delete button_push;
    delete button_swap;
    delete button_undo;
    delete button_save;
    delete button_normal;
    delete button_reload;
    delete help;
    for (i=0; i<MAX_TILES; i++) if (tile[i]) SDL_FreeSurface(tile[i]);
    for (i=0; i<SHINE_FRAMES; i++) if (shine[i]) SDL_FreeSurface(shine[i]);
}

void Options()
{
#define DIVIDE   8.3 
#define TILES    8

#ifdef	WIZRES
#define TOP      5
#define LEFT     30
#define BORDERX  40
#define BORDERY  10
    Button //*b_full=new Button(LEFT,(int)round((HEIGHT-BORDERY*2)/DIVIDE*0+TOP),79,20,IMAGE_FULLSCREEN),
           *b_autoreload=new Button(LEFT,(int)round((HEIGHT-BORDERY*2)/DIVIDE*1+TOP),79,20,IMAGE_AUTORELOAD),
           *b_autonormal=new Button(LEFT,(int)round((HEIGHT-BORDERY*2)/DIVIDE*2+TOP),79,20,IMAGE_AUTONORMAL),
           *b_tileset=new Button(LEFT,(int)round((HEIGHT-BORDERY*2)/DIVIDE*3+TOP),79,20,IMAGE_TILESET),
           *b_difficulty=new Button(LEFT,(int)round((HEIGHT-BORDERY*2)/DIVIDE*4+TOP),79,20,IMAGE_DIFFICULTY),
           *b_bgalpha=new Button(LEFT,(int)round((HEIGHT-BORDERY*2)/DIVIDE*5+TOP),79,20,IMAGE_BGALPHA),
           *b_cursor=new Button(LEFT,(int)round((HEIGHT-BORDERY*2)/DIVIDE*6+TOP),79,20,IMAGE_CURSOR),
           *b_back=new Button(LEFT,(int)round((HEIGHT-BORDERY*2)/DIVIDE*7+TOP),79,20,IMAGE_BACK);
#else
#define TOP      10
#define LEFT     60
#define BORDERX  80
#define BORDERY  20
    Button *b_full=new Button(LEFT,(int)round((HEIGHT-BORDERY*2)/DIVIDE*0+TOP),158,40,IMAGE_FULLSCREEN),
           *b_autoreload=new Button(LEFT,(int)round((HEIGHT-BORDERY*2)/DIVIDE*1+TOP),158,40,IMAGE_AUTORELOAD),
           *b_autonormal=new Button(LEFT,(int)round((HEIGHT-BORDERY*2)/DIVIDE*2+TOP),158,40,IMAGE_AUTONORMAL),
           *b_tileset=new Button(LEFT,(int)round((HEIGHT-BORDERY*2)/DIVIDE*3+TOP),158,40,IMAGE_TILESET),
           *b_difficulty=new Button(LEFT,(int)round((HEIGHT-BORDERY*2)/DIVIDE*4+TOP),158,40,IMAGE_DIFFICULTY),
           *b_bgalpha=new Button(LEFT,(int)round((HEIGHT-BORDERY*2)/DIVIDE*5+TOP),158,40,IMAGE_BGALPHA),
           *b_cursor=new Button(LEFT,(int)round((HEIGHT-BORDERY*2)/DIVIDE*6+TOP),158,40,IMAGE_CURSOR),
           *b_back=new Button(LEFT,(int)round((HEIGHT-BORDERY*2)/DIVIDE*7+TOP),158,40,IMAGE_BACK);
#endif
    TTF_Font *font=NULL;
    SDL_Surface *text=NULL,*back=NULL,*save=NULL,*tick=LoadImage(IMAGE_TICK,0),*cross=LoadImage(IMAGE_CROSS,0),
                *tile[TILES];
    SDL_Event event;
    char s[1024];
    int i;
    SDL_Color color={100,200,255};
    font=TTF_OpenFont(FONTNAME_NORMAL,FONTSIZE_SMALL);
    if (!font) return;
    if (!(save=SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_RLEACCEL,WIDTH,HEIGHT,BPP,rmask,gmask,bmask,amask))) return;
#ifdef	WIZRES
    if (!(back=SDL_CreateRGBSurface(SDL_SWSURFACE,WIDTH-BORDERX*2,HEIGHT-BORDERY*2,BPP,rmask,gmask,bmask,amask))) return;
#else
    if (!(back=SDL_CreateRGBSurface(SDL_SRCALPHA | SDL_SWSURFACE | SDL_RLEACCEL,WIDTH-BORDERX*2,HEIGHT-BORDERY*2,BPP,rmask,gmask,bmask,amask))) return;
#endif
    bool quit=false;
    srand(time(NULL));
    SDL_LockSurface(screen);
    SDL_LockSurface(save);
    memcpy(save->pixels,screen->pixels,WIDTH*HEIGHT*BPP/8);
    SDL_UnlockSurface(screen);
    SDL_UnlockSurface(save);
    for (i=0; i<TILES; i++)
      {
	    sprintf(s,"%s%s/small/%d.png",DIR_TILESET,tileset,i+TILE_FIRST);
	    if (!(tile[i]=LoadImage(s,0,0,0)))
	      {
   	        sprintf(s,"%s%s/small/%d.png",DIR_TILESET,TILESET_DEFAULT,i+TILE_FIRST);
	        tile[i]=LoadImage(s,0,0,0);
          }
      }
	printf("options loop starting\n");
    while (!quit)
      {
        SDL_Delay(DELAY);
#ifdef	WIZ
	    SDL_SetAlpha(back,0,255);
        SDL_FillRect(back,NULL,0);
#else
        SDL_FillRect(back,NULL,100*amask);
#endif
        SDL_LockSurface(screen);
        SDL_LockSurface(save);
        memcpy(screen->pixels,save->pixels,WIDTH*HEIGHT*BPP/8);
        SDL_UnlockSurface(screen);
        SDL_UnlockSurface(save);
#ifndef	WIZRES
		b_full->Show(back,b_full->Inside(event.button.x-BORDERX,event.button.y-BORDERY)?255:ALPHA2);
#endif
#ifndef	WIZ
        PutSurface(fullscreen?tick:cross,back,LEFT+180,(int)round((HEIGHT-BORDERY*2)/DIVIDE*0+TOP));
#endif
        b_autoreload->Show(back,b_autoreload->Inside(event.button.x-BORDERX,event.button.y-BORDERY)?255:ALPHA2);
#ifdef	WIZRES
        PutSurface(autoreload?tick:cross,back,LEFT+90,(int)round((HEIGHT-BORDERY*2)/DIVIDE*1+TOP));
#else
        PutSurface(autoreload?tick:cross,back,LEFT+180,(int)round((HEIGHT-BORDERY*2)/DIVIDE*1+TOP));
#endif
        b_autonormal->Show(back,b_autonormal->Inside(event.button.x-BORDERX,event.button.y-BORDERY)?255:ALPHA2);
#ifdef	WIZRES
        PutSurface(autonormal?tick:cross,back,LEFT+90,(int)round((HEIGHT-BORDERY*2)/DIVIDE*2+TOP));
#else
        PutSurface(autonormal?tick:cross,back,LEFT+180,(int)round((HEIGHT-BORDERY*2)/DIVIDE*2+TOP));
#endif
        b_tileset->Show(back,b_tileset->Inside(event.button.x-BORDERX,event.button.y-BORDERY)?255:ALPHA2);
        b_bgalpha->Show(back,b_bgalpha->Inside(event.button.x-BORDERX,event.button.y-BORDERY)?255:ALPHA2);
        b_cursor->Show(back,b_cursor->Inside(event.button.x-BORDERX,event.button.y-BORDERY)?255:ALPHA2);
#ifdef	WIZRES
        PutSurface(CURSOR?tick:cross,back,LEFT+90,(int)round((HEIGHT-BORDERY*2)/DIVIDE*6+TOP));
#else
        PutSurface(CURSOR?tick:cross,back,LEFT+180,(int)round((HEIGHT-BORDERY*2)/DIVIDE*6+TOP));
#endif
        b_difficulty->Show(back,b_difficulty->Inside(event.button.x-BORDERX,event.button.y-BORDERY)?255:ALPHA2);
        if (font)
          {
            if (text) SDL_FreeSurface(text);
            text=TTF_RenderText_Solid(font,tileset,color);
#ifdef	WIZRES
            PutSurface(text,back,LEFT+90,(int)round((HEIGHT-BORDERY*2)/DIVIDE*3+TOP-3));
#else
            PutSurface(text,back,LEFT+180,(int)round((HEIGHT-BORDERY*2)/DIVIDE*3+TOP-3));
#endif
            if (text) SDL_FreeSurface(text);
            text=TTF_RenderText_Solid(font,diffstr[difficulty],color);
#ifdef	WIZRES
            if (text) PutSurface(text,back,LEFT+90,(int)round((HEIGHT-BORDERY*2)/DIVIDE*4+TOP+5));
#else
            if (text) PutSurface(text,back,LEFT+180,(int)round((HEIGHT-BORDERY*2)/DIVIDE*4+TOP+10));
#endif
            else fprintf(stderr,"WARNING: unsuccesful text render\n");
            switch (bgalpha)
              {
                    case 0:strcpy(s,"disabled");break;
                    case 64:strcpy(s,"75 % transparent");break;
                    case 128:strcpy(s,"50 % transparent");break;
                    case 192:strcpy(s,"25 % transparent");break;
                    default:bgalpha=128;strcpy(s,"50 % transparent");break;
              }
            if (text) SDL_FreeSurface(text);
            text=TTF_RenderText_Solid(font,s,color);
#ifdef	WIZRES
            if (text) PutSurface(text,back,LEFT+90,(int)round((HEIGHT-BORDERY*2)/DIVIDE*5+TOP+5));
#else
            if (text) PutSurface(text,back,LEFT+180,(int)round((HEIGHT-BORDERY*2)/DIVIDE*5+TOP+10));
#endif
            else fprintf(stderr,"WARNING: unsuccesful text render\n");
          }
        for (i=0; i<TILES; i++)
#ifdef	WIZRES
          if (tile[i]) PutSurface(tile[i],back,LEFT+90+i*TILE_WIDTH/2,(int)round((HEIGHT-BORDERY*2)/DIVIDE*3+TOP-3+(text?text->h:FONTSIZE_SMALL)));
#else
          if (tile[i]) PutSurface(tile[i],back,LEFT+180+i*TILE_WIDTH/2,(int)round((HEIGHT-BORDERY*2)/DIVIDE*3+TOP-3+(text?text->h:FONTSIZE_SMALL)));
#endif
        b_back->Show(back,b_back->Inside(event.button.x-BORDERX,event.button.y-BORDERY)?255:ALPHA2);
        *s=0;
#ifndef	WIZRES
        if (b_full->Inside(event.button.x-BORDERX,event.button.y-BORDERY)) strcpy(s,"Fullscreen on/off");
        else
#endif
			if (b_autoreload->Inside(event.button.x-BORDERX,event.button.y-BORDERY)) strcpy(s,"When time is up, automatically reload level");
        else if (b_autonormal->Inside(event.button.x-BORDERX,event.button.y-BORDERY)) strcpy(s,"After using a function, change back to normal mode");
        else if (b_tileset->Inside(event.button.x-BORDERX,event.button.y-BORDERY)) strcpy(s,"Change tileset");
        else if (b_back->Inside(event.button.x-BORDERX,event.button.y-BORDERY)) strcpy(s,"Back to main menu");
        else if (b_difficulty->Inside(event.button.x-BORDERX,event.button.y-BORDERY)) strcpy(s,"Difficulty level");
        else if (b_cursor->Inside(event.button.x-BORDERX,event.button.y-BORDERY)) strcpy(s,"Turn on/off cursor");
        else if (b_bgalpha->Inside(event.button.x-BORDERX,event.button.y-BORDERY)) strcpy(s,"Background visibility");
        if (*s && font)
          {
            if (text) SDL_FreeSurface(text);
            text=TTF_RenderText_Solid(font,s,color);
            if (text) PutSurface(text,back,(back->w-text->w)/2,back->h-text->h);
            else fprintf(stderr,"WARNING: unsuccesful text render\n");
          }
#ifdef	WIZ
	    //SDL_SetAlpha(back,0,255);
#endif
        PutSurface(back,screen,(screen->w-back->w)/2,(screen->h-back->h)/2);
        SDL_Flip(screen);
#ifdef	WIZ
		if (wiz_getkeys() & (1<<WIZ_MENU))
		{
			while (wiz_getkeys() & (1<<WIZ_MENU))
				SDL_Delay(DELAY);
			quit = true;
		}
#endif
        while (SDL_PollEvent(&event))
        {
          switch (event.type)
            {
              case SDL_QUIT:
                     quit=true;
                   break;
              case SDL_MOUSEBUTTONDOWN:
#ifndef	WIZRES
                     if (b_full->Inside(event.button.x-BORDERX,event.button.y-BORDERY))
                          screen=SDL_SetVideoMode(WIDTH,HEIGHT,BPP,SDL_SWSURFACE | (fullscreen=!fullscreen)?SDL_FULLSCREEN:0);
                     else
#endif
						 if (b_autoreload->Inside(event.button.x-BORDERX,event.button.y-BORDERY)) autoreload=!autoreload;
                     else if (b_autonormal->Inside(event.button.x-BORDERX,event.button.y-BORDERY)) autonormal=!autonormal;
                     else if (b_bgalpha->Inside(event.button.x-BORDERX,event.button.y-BORDERY)) bgalpha=(bgalpha+64)%256;
#ifndef	WIZ
                     else if (b_cursor->Inside(event.button.x-BORDERX,event.button.y-BORDERY)) CURSOR=!CURSOR;
#endif
                     else if (b_tileset->Inside(event.button.x-BORDERX,event.button.y-BORDERY))
                       {
                         GetNextSet(tileset);
                         for (i=0; i<TILES; i++)
                           {
                             if (tile[i]) SDL_FreeSurface(tile[i]);
	                         sprintf(s,"%s%s/small/%d.png",DIR_TILESET,tileset,i+TILE_FIRST);
	                         if (!(tile[i]=LoadImage(s,0,0,0)))
	                          {
   	                            sprintf(s,"%s%s/small/%d.png",DIR_TILESET,TILESET_DEFAULT,i+TILE_FIRST);
	                             tile[i]=LoadImage(s,0,0,0);
                              }
                           }
                       }
                     else if (b_difficulty->Inside(event.button.x-BORDERX,event.button.y-BORDERY))
                             difficulty=++difficulty%(DIFFICULTY_MAX+1);
                     else if (b_back->Inside(event.button.x-BORDERX,event.button.y-BORDERY)) quit=true;
                   break;
#ifndef	WIZ
              case SDL_KEYDOWN:
                     switch (event.key.keysym.sym)
                       {
         				 case SDLK_f:
                                screen=SDL_SetVideoMode(WIDTH,HEIGHT,BPP,SDL_SWSURFACE | (fullscreen=!fullscreen)?SDL_FULLSCREEN:0);
                                SDL_LockSurface(screen);
                                SDL_LockSurface(save);
                                memcpy(screen->pixels,save->pixels,WIDTH*HEIGHT*BPP/8);
                                SDL_UnlockSurface(screen);
                                SDL_UnlockSurface(save);                                
                                PutSurface(back,screen,(screen->w-back->w)/2,(screen->h-back->h)/2);
                                SDL_Flip(screen);
                              break;
                         case SDLK_ESCAPE:
                         case SDLK_q:
                         case SDLK_x:
                         case SDLK_F10:
                                quit=true;
                              break;
                       }
                   break;
#endif
            }
          }
      }
    for (i=0; i<TILES; i++)
      if (tile[i]) SDL_FreeSurface(tile[i]);
    if (font) TTF_CloseFont(font);
    if (text) SDL_FreeSurface(text);
    if (back) SDL_FreeSurface(back);
    if (save) SDL_FreeSurface(save);
    if (tick) SDL_FreeSurface(tick);
    if (cross) SDL_FreeSurface(cross);
#ifndef	WIZRES
    delete b_full;
#endif
    delete b_back;
    delete b_difficulty;
    delete b_cursor;
    delete b_tileset;
    delete b_bgalpha;
    delete b_autonormal;
    delete b_autoreload;
}

#ifndef	WIZ
void Edit()
{
    bool quit=false;
    long i;
    int j,levnum=1,timelimit,active=TILE_FIRST;
    char s[1024],t[1024],leveltext[1024];
    level table;
    maxes max;
    SDL_Color color={200,255,220};
    SDL_Event event;
    TTF_Font *font=TTF_OpenFont(FONTNAME_NORMAL,FONTSIZE_SCORE),*smallfont=TTF_OpenFont(FONTNAME_NORMAL,FONTSIZE_SMALL);
    SDL_Surface *base=LoadImage(BACKGROUND_EDIT),*tile[MAX_TILES],*tile_small[MAX_TILES],*text=NULL;
    Button *load=new Button(WINDOWX+TILE_WIDTH*8+TILE_WIDTH/2,WINDOWY+TILE_HEIGHT*7,32,32,IMAGE_LOAD),
           *save=new Button(WINDOWX+TILE_WIDTH*9+4,WINDOWY+TILE_HEIGHT*7+4,24,24,IMAGE_SAVE),
           *clock=new Button(WINDOWX+TILE_WIDTH*9+TILE_WIDTH/2,WINDOWY+TILE_HEIGHT*7,32,32,IMAGE_CLOCK),
           *play=new Button(WINDOWX+TILE_WIDTH*8+TILE_WIDTH/2,WINDOWY+TILE_HEIGHT*6+TILE_HEIGHT/2,32,32,IMAGE_EDITPLAY),
           *maxbutt=new Button(WINDOWX+TILE_WIDTH*9+TILE_WIDTH/2,WINDOWY+TILE_HEIGHT*6+TILE_HEIGHT/2,32,32,IMAGE_MAXIMUMS);
    if (!font || !smallfont)
      {
        fprintf(stderr,"ERROR: Font file %s not found\n",FONTNAME_SCORE);
        return;
      }
    if (!base)
      {
        fprintf(stderr,"ERROR: Image file %s not found\n",BACKGROUND_BASE);
        return;
      }
    for (i=0; i<MAX_TILES; i++)
      {
	    sprintf(s,"%s%s/%ld.png",DIR_TILESET,tileset,i);
	    if (!(tile[i]=LoadImage(s,0,0,0)))
	      {
   	        sprintf(s,"%s%s/%ld.png",DIR_TILESET,TILESET_DEFAULT,i);
	        if (!(tile[i]=LoadImage(s,0,0,0)))
              if (verbose) fprintf(stderr,"WARNING: %s%s/%d.png not found!\n",DIR_TILESET,tileset,i);
          }
	    sprintf(s,"%s%s/small/%ld.png",DIR_TILESET,tileset,i);
	    if (!(tile_small[i]=LoadImage(s,0,0,0)))
	      {
   	        sprintf(s,"%s%s/small/%ld.png",DIR_TILESET,TILESET_DEFAULT,i);
	        if (!(tile_small[i]=LoadImage(s,0,0,0)))
             if (verbose) fprintf(stderr,"WARNING: %s%s/small/%d.png not found!\n",DIR_TILESET,tileset,i);
          }
      }
    for (i=0; i<MODES; i++)
      max[i]=-1;
    SDL_FillRect(screen,NULL,1);
    sprintf(s,"%s%d.lvl",DIR_LEVEL,levnum);
    if ((timelimit=LoadLevel(s,table,max,leveltext))>=0)
    *leveltext=0;
    while (!quit)
    {
        SDL_Delay(DELAY);
        PutSurface(base,screen);
#define COLOUMNH   6        
#define COLOUMNH2  5
	for (i=0; i<=3; i++)
	  for (j=0; j<=COLOUMNH-1; j++)
	    if (tile_small[TILE_FIRST+i*COLOUMNH+j])
	    {
	      SDL_SetAlpha(tile_small[TILE_FIRST+i*COLOUMNH+j],SDL_SRCALPHA | SDL_RLEACCEL,TILE_FIRST+i*COLOUMNH+j==active?255:ALPHA2);
	      PutSurface(tile_small[TILE_FIRST+i*COLOUMNH+j],screen,WINDOWX+TILE_WIDTH*8+TILE_WIDTH*(i+1)/2,WINDOWY+TILE_HEIGHT*(j+1)/2);
	    }
	for (i=0; i<=2; i++)
	  for (j=0; j<=COLOUMNH2-1;j++)
	    if (tile_small[i*COLOUMNH2+j+1])
	    {
	      SDL_SetAlpha(tile_small[i*COLOUMNH2+j+1],SDL_SRCALPHA | SDL_RLEACCEL,i*COLOUMNH2+j+1==active?255:ALPHA2);
	      PutSurface(tile_small[i*COLOUMNH2+j+1],screen,WINDOWX+TILE_WIDTH*8+TILE_WIDTH*(i+1)/2,WINDOWY+TILE_HEIGHT*(j+COLOUMNH+1)/2);
	    }
	for (i=0; i<=7; i++)
	  for (j=0; j<=7; j++)
	      PutSurface(tile[table[j][i]],screen,j*TILE_WIDTH+WINDOWX,i*TILE_HEIGHT+WINDOWY);
	load->Show(screen);
	save->Show(screen);
	clock->Show(screen);
	play->Show(screen);
	maxbutt->Show(screen);
	SDL_Flip(screen);
        while (SDL_PollEvent(&event))
        {
          switch (event.type)
            {
              case SDL_QUIT:
                     quit=Escape(i);
                   break;
              case SDL_MOUSEBUTTONDOWN:
                     if (play->Inside(event)) Play("",levnum);
                     else if (maxbutt->Inside(event))
                       {
                         SDL_FillRect(screen,NULL,0);
                         SDL_Flip(screen);
                         for (i=j=1; i<MODE_END; i++)
                           if (i!=MODE_UNDO && i!=MODE_RELOAD && i!=MODE_SAVE)
                           {
                             sprintf(s,"Enter amount of '%s' function (%d) -1 for unlimited: ",mode_name[i],max[i]);
#ifdef	WIZRES
                             Input(screen,smallfont,color,10,(int)round(FONTSIZE_SMALL*j++*1.5),s,10);
#else
                             Input(screen,smallfont,color,20,(int)round(FONTSIZE_SMALL*j++*1.5),s,10);
#endif
                             if (*s) max[i]=atoi(s);
                           }
                         sprintf(s,"Enter level description (%s): ",leveltext);
#ifdef	WIZRES
                         Input(screen,smallfont,color,10,(int)round(FONTSIZE_SMALL*j*1.5),s,80);
#else
                         Input(screen,smallfont,color,20,(int)round(FONTSIZE_SMALL*j*1.5),s,80);
#endif
                         if (*s) strcpy(leveltext,s);
                       }
                     else
                     if (load->Inside(event))
                       {
                         sprintf(s,"Load level (current:%d):",levnum);
#ifdef	WIZRES
                         if (Input(screen,font,color,50,100,s,100) && atoi(s)>0)
#else
                         if (Input(screen,font,color,10,200,s,100) && atoi(s)>0)
#endif
                           {
				             levnum=atoi(s);
             				 sprintf(t,"%s%s.lvl",DIR_LEVEL,s);
				             fprintf(stderr,"Loading: %s\n",t);
				             if (!(timelimit=LoadLevel(t,table,max,leveltext)))
				             fprintf(stderr,"Error loading level %s",t);
                           }
                       }
                     else if (save->Inside(event)) 
                       {
                         sprintf(s,"Save as level number (current:%d):",levnum);
#ifdef	WIZRES
                         if (Input(screen,font,color,5,100,s,100) && atoi(s)>0)
#else
                         if (Input(screen,font,color,10,200,s,100) && atoi(s)>0)
#endif
                           {
                             levnum=atoi(s);
                             sprintf(t,"%s%s.lvl",DIR_LEVEL,s);
                             SaveLevel(t,table,timelimit,max,leveltext);
                           }
                       }
                     else if (clock->Inside(event))
                       {
                         sprintf(s,"Enter timelimit (current:%d):",timelimit);
#ifdef	WIZRES
                         if (Input(screen,font,color,5,100,s,100) && atoi(s)>0) timelimit=atoi(s);
#else
                         if (Input(screen,font,color,10,200,s,100) && atoi(s)>0) timelimit=atoi(s);
#endif
                       }
                     else 
                     if (event.button.x<TILE_WIDTH*8+WINDOWX)
                       {
                         j=(event.button.x-WINDOWX)/TILE_WIDTH;
		                 i=(event.button.y-WINDOWY)/TILE_HEIGHT;
		                 switch (event.button.button)
		                   {
		                     case SDL_BUTTON_LEFT:
		                            table[j][i]=active;
		                     break;
		                     case SDL_BUTTON_RIGHT:
		                            table[j][i]=TILE_EMPTY;
		                     break;
		           }
		       }
		     else
		       {
                         j=(event.button.x-TILE_WIDTH*8-WINDOWX-TILE_WIDTH/2)/(TILE_WIDTH/2);
                         i=(event.button.y-WINDOWY-TILE_HEIGHT/2)/(TILE_HEIGHT/2);
                         if (i<=COLOUMNH-1 && tile[TILE_FIRST+j*COLOUMNH+i]) active=TILE_FIRST+j*COLOUMNH+i;
                         else if (tile[(i-COLOUMNH)+j*COLOUMNH2+1]) active=(i-COLOUMNH)+j*COLOUMNH2+1;
		       }
                   break;
              case SDL_KEYDOWN:
                     switch (event.key.keysym.sym)
                       {
         				 case SDLK_f:
                                screen=SDL_SetVideoMode(WIDTH,HEIGHT,BPP,SDL_SWSURFACE | (fullscreen=!fullscreen)?SDL_FULLSCREEN:0);
                              break;
                         case SDLK_p:
                                Play("",levnum);
                              break;
                         case SDLK_c:
                                for (i=0; i<=7; i++)
                                  for (j=0; j<=7; j++)
                                    {
                                      table[j][i]=TILE_EMPTY;
                                      PutEmpty(j,i);
                                    }
                              break;
                         case SDLK_F1:
                         case SDLK_h:
                                Help(i,"edit");
                              break;
                         case SDLK_ESCAPE:
                         case SDLK_q:
                         case SDLK_x:
                         case SDLK_F10:
                                quit=Escape(i);
                              break;
                       }
                   break;
            }
          }
    }
    for (i=0; i<MAX_TILES; i++)
      {
        if (tile[i]) SDL_FreeSurface(tile[i]);
        if (tile_small[i]) SDL_FreeSurface(tile_small[i]);
      }
    TTF_CloseFont(font);
    delete load;
    delete save;
    delete play;
    delete clock;
    delete maxbutt;
    TTF_CloseFont(smallfont);
    SDL_FreeSurface(base);
    if (text) SDL_FreeSurface(text);
}
#endif

void Highs()
{
    TTF_Font *font=NULL;
    SDL_Surface *text=NULL,*back=NULL;
    SDL_Event event;
    SDL_Color color={100,200,255};
    font=TTF_OpenFont(FONTNAME_NORMAL,FONTSIZE_SMALL);
    if (!font) return;
    if (!(back=SDL_CreateRGBSurface(SDL_SRCALPHA | SDL_SWSURFACE | SDL_RLEACCEL,FONTSIZE_SMALL*(NAME_MAXLEN+7),MAX_HIGHENTRIES*FONTSIZE_SMALL,BPP,rmask,gmask,bmask,amask))) return;
#ifdef	WIZ
	SDL_FillRect(back,NULL,255*amask);
#else
    SDL_FillRect(back,NULL,100*amask);
#endif
    bool quit=false;
    int i,j;
    char s[4][NAME_MAXLEN+1];
    FILE *f=fopen(FILE_HIGH,"r");
    if (!f) return;
    for (i=0; !feof(f); i++)
      {
        for (j=0; j<4; j++)
          {
            fgets(s[j],NAME_MAXLEN,f);
            while (s[j][strlen(s[j])-1]=='\n' || s[j][strlen(s[j])-1]=='\r') s[j][strlen(s[j])-1]=0;
          }
	if (*s[3])
	{
	    if (text) SDL_FreeSurface(text);
	    text=TTF_RenderText_Solid(font,diffchar[atoi(s[2])],color);
	    PutSurface(text,back,0,i*FONTSIZE_SMALL);
	    if (text) SDL_FreeSurface(text);
	    text=TTF_RenderText_Solid(font,s[1],color);
	    PutSurface(text,back,20,i*FONTSIZE_SMALL);
	    if (text) SDL_FreeSurface(text);
	    text=TTF_RenderText_Solid(font,s[3],color);
	    PutSurface(text,back,60,i*FONTSIZE_SMALL);
	    if (text) SDL_FreeSurface(text);
	    text=TTF_RenderText_Solid(font,s[0],color);
	    PutSurface(text,back,back->w-text->w,i*FONTSIZE_SMALL);
	}
      }
    fclose(f);
    PutSurface(back,screen,(screen->w-back->w)/2,(screen->h-back->h)/2);
    SDL_Flip(screen);
    while (!quit)
      {
        SDL_Delay(DELAY);
        while (SDL_PollEvent(&event))
        {
          switch (event.type)
            {
              case SDL_QUIT:
                     quit=true;
                   break;
              case SDL_MOUSEBUTTONDOWN:
                     quit=true;
                   break;
              case SDL_KEYDOWN:
                     switch (event.key.keysym.sym)
                       {
                         case SDLK_ESCAPE:
                         case SDLK_q:
                         case SDLK_x:
                         case SDLK_F10:
                                quit=true;
                              break;
                       }
                   break;
            }
          }
      }
    TTF_CloseFont(font);
    SDL_FreeSurface(text);
    SDL_FreeSurface(back);
}

int main(int argc,char *argv[])
{
    bool quit=false;
    long int temp;
    int i;
    SDL_Surface *menu=NULL,*text=NULL,*text2=NULL,*musician=NULL;
    SDL_Event   event;
    char s[1024];
    strcpy(tileset,TILESET_DEFAULT);
#if defined(WIN32) || defined(_WIN32) || defined(WINDOWS)                                                                     
	char *conftemp=getenv("USERPROFILE");                                                                                     
	if (conftemp) strcpy(FILE_CONFIG,conftemp);                                                                                        
	else strcpy(FILE_CONFIG,"c:\\windows");                                                                                    
	strcat(FILE_CONFIG,"\\brikx.cfg");                                                                                      
#else                                                                                                                         
	char *conftemp=getenv("HOME");                                                                                            
	if (conftemp) strcpy(FILE_CONFIG,conftemp);                                                                                        
	else strcpy(FILE_CONFIG,"~");                                                                                              
	strcat(FILE_CONFIG,"/.brikx");                                                                                          
	mkdir(FILE_CONFIG,0755);
	strcat(FILE_CONFIG,"/config");                                                                                          
#endif 
    FILE *f=fopen(FILE_CONFIG,"r");
    if (f)
      {
        while (!feof(f))
        {
          fgets(s,1023,f);
          if (s[strlen(s)-1]=='\n') s[strlen(s)-1]=0;
          if (s[0]!=';')
            {
#define STRFS "fullscreen="                
              if (!strncmp(s,STRFS,strlen(STRFS))) fullscreen=(!strcmpi(s+strlen(STRFS),"yes") || !strcmpi(s+strlen(STRFS),"true") || !strcmpi(s+strlen(STRFS),"on") || !strcmpi(s+strlen(STRFS),"1"));
#define STRCU "cursor="                
              if (!strncmp(s,STRFS,strlen(STRCU))) CURSOR=(!strcmpi(s+strlen(STRCU),"yes") || !strcmpi(s+strlen(STRCU),"true") || !strcmpi(s+strlen(STRCU),"on") || !strcmpi(s+strlen(STRCU),"1"));
#define STRAR "autoreload="
              if (!strncmp(s,STRAR,strlen(STRAR))) autoreload=(!strcmpi(s+strlen(STRAR),"yes") || !strcmpi(s+strlen(STRAR),"true") || !strcmpi(s+strlen(STRAR),"on") || !strcmpi(s+strlen(STRAR),"1"));
#define STRAN "autonormal="
              if (!strncmp(s,STRAN,strlen(STRAN))) autonormal=(!strcmpi(s+strlen(STRAN),"yes") || !strcmpi(s+strlen(STRAN),"true") || !strcmpi(s+strlen(STRAN),"on") || !strcmpi(s+strlen(STRAN),"1"));
#define STRGR "gravity="
              if (!strncmp(s,STRGR,strlen(STRGR))) if (atoi(s+strlen(STRGR))) GRAVITY=atoi(s+strlen(STRGR));
#define STRDI "difficulty="
              if (!strncmp(s,STRDI,strlen(STRDI))) difficulty=atoi(s+strlen(STRDI));
#define STRTS "tileset="
              if (!strncmp(s,STRTS,strlen(STRTS))) strcpy(tileset,s+strlen(STRTS));
#define STRBG "bgalpha="
              if (!strncmp(s,STRBG,strlen(STRBG))) bgalpha=atoi(s+strlen(STRBG));
            }
        }
        fclose(f);
      }
    if (argc>1)
      {
        for (i=1; i<argc; i++)
          {
            while (argv[i][0]=='-')
              strcpy(argv[i],argv[i]+1);
            if (!strcmp(argv[i],"help"))
              {
                puts("Brikx version "VERSION);
                puts("Known parameters:");               
                puts("noautoreload   when time is over, don't reload the level but end game");
                puts("autonormal     after using a function, return to normal mode");
                puts("verbose or v   display more warnings");
                puts("fullscreen     Start in fullscreen");
                puts("tileset=name   Uses tileset 'name'");
                puts("gravity=value  Power of gravity (default: 100)");
                return 0;
              } 
            if (!strcmp(argv[i],"noautoreload")) autoreload=false;
            if (!strcmp(argv[i],"fullscreen")) fullscreen=true;
            if (!strcmp(argv[i],"autonormal")) autonormal=true;
            if (!strcmp(argv[i],"verbose") || !strcmp(argv[i],"v")) verbose=true;
            if (!strncmp(argv[i],"tileset=",8))
                printf("Using tileset %s\n",strcpy(tileset,argv[i]+8));
            if (!strncmp(argv[i],"gravity=",8) && atoi(argv[i]+8))
                printf("Gravity set to %d\n",GRAVITY=10000/atoi(argv[i]+8));
          }
      }
    DIR *D;
    if (D=opendir(DIR_DATA))  closedir(D);
    else
      {
        fprintf(stderr,"ERROR: data directory not found!");
        return -1;
      }
#ifdef	WIZ
	if (wiz_init()<0)
	{
		fprintf(stderr,"WIZ initialization failed\n");
		return 2;
	}
#endif
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)==-1)
      if (SDL_Init(SDL_INIT_VIDEO)==-1)
      {
        fprintf(stderr,"SDL initialization failed!\n");
        return -1;
      }
    if (TTF_Init()==-1) fprintf(stderr,"ERROR: SDL_ttf initialization failed!\n");
    TTF_Font *font=NULL;
    if (!(font=TTF_OpenFont(FONTNAME_NORMAL,FONTSIZE_SMALL))) fprintf(stderr,"ERROR: Font open error ('%s')\n",s);
    screen=SDL_SetVideoMode(WIDTH,HEIGHT,BPP,SDL_SWSURFACE | (fullscreen?SDL_FULLSCREEN:0));
    SDL_Color color={200,255,255};
	SDL_FillRect(screen,NULL,0);
	text=TTF_RenderText_Solid(font,"LOADING...",color);
	PutSurface(text,screen,100,HEIGHT/2-20);
	SDL_Flip(screen);
#ifdef	WIZRES
#define BUTTONSPACE  30
#define BUTTONTOP    15
    Button *button_play=new Button(225,BUTTONTOP+BUTTONSPACE*0,79,20,IMAGE_PLAY),
           *button_continue=new Button(225,BUTTONTOP+BUTTONSPACE*1,79,20,IMAGE_CONTINUE),
           //*button_edit=new Button(225,BUTTONTOP+BUTTONSPACE*2,79,20,IMAGE_EDIT),
           *button_options=new Button(225,BUTTONTOP+BUTTONSPACE*3,79,20,IMAGE_OPTIONS),
           *button_help=new Button(225,BUTTONTOP+BUTTONSPACE*4,79,20,IMAGE_HELP),
           *button_highs=new Button(225,BUTTONTOP+BUTTONSPACE*5,79,20,IMAGE_HIGHS),
           *button_quit=new Button(225,BUTTONTOP+BUTTONSPACE*6,79,20,IMAGE_QUIT);
#else
#define BUTTONSPACE  60
#define BUTTONTOP    30
    Button *button_play=new Button(450,BUTTONTOP+BUTTONSPACE*0,158,40,IMAGE_PLAY),
           *button_continue=new Button(450,BUTTONTOP+BUTTONSPACE*1,158,40,IMAGE_CONTINUE),
           *button_edit=new Button(450,BUTTONTOP+BUTTONSPACE*2,158,40,IMAGE_EDIT),
           *button_options=new Button(450,BUTTONTOP+BUTTONSPACE*3,158,40,IMAGE_OPTIONS),
           *button_help=new Button(450,BUTTONTOP+BUTTONSPACE*4,158,40,IMAGE_HELP),
           *button_highs=new Button(450,BUTTONTOP+BUTTONSPACE*5,158,40,IMAGE_HIGHS),
           *button_quit=new Button(450,BUTTONTOP+BUTTONSPACE*6,158,40,IMAGE_QUIT);
#endif
    if (!screen)
      {
        SDL_Quit();
        return -2;
      }
    if (Mix_OpenAudio(AUDIO_RATE,AUDIO_FORMAT,AUDIO_CHANNELS,AUDIO_BUFFERS))
		fprintf(stderr,"WARNING: Cannon open audio\n");
	music_play=Mix_LoadMUS(MUSIC_PLAY);
	Mix_VolumeMusic(volume_music);
	if (music_play)
        Mix_FadeInMusic(music_play,-1,1000);	
    SDL_WM_SetCaption("Brikx by glezmen","madness.ico");
    menu=LoadImage(BACKGROUND_MENU);
    if (font)
    {
        text=TTF_RenderText_Solid(font,"Brikx by glezmen (bokorn@tvn.hu)     Version: "VERSION,color);
        musician=TTF_RenderText_Solid(font,"Music by prazo (prazo.@freemail.hu)",color);
    }
	printf("main loop started\n");
	SDL_FillRect(screen,NULL,0);
#ifdef	WIZ
	SDL_ShowCursor(0);
#endif
    while (!quit)
      {
        SDL_Delay(DELAY);
        //SDL_FillRect(screen,NULL,0);
        PutSurface(menu,screen);
        button_quit->Show(screen,button_quit->Inside(event)?255:ALPHA2);
        button_options->Show(screen,button_options->Inside(event)?255:ALPHA2);
        button_play->Show(screen,button_play->Inside(event)?255:ALPHA2);
        button_help->Show(screen,button_help->Inside(event)?255:ALPHA2);
        button_continue->Show(screen,button_continue->Inside(event)?255:ALPHA2);
        button_highs->Show(screen,button_highs->Inside(event)?255:ALPHA2);
#ifndef	WIZRES
        button_edit->Show(screen,button_edit->Inside(event)?255:ALPHA2);
#endif
        if (text) PutSurface(text,screen,10,10);
        if (musician) PutSurface(musician,screen,10,26);
        *s=0;
        if (button_quit->Inside(event)) strcpy(s,"Exit to OS");
        else if (button_options->Inside(event)) strcpy(s,"Game settings");
        else if (button_play->Inside(event)) strcpy(s,"Start game");
        else if (button_help->Inside(event)) strcpy(s,"How to play");
        else if (button_continue->Inside(event)) strcpy(s,"Play previously saved game");
        else if (button_highs->Inside(event)) strcpy(s,"Show top scores");
#ifndef	WIZRES
        else if (button_edit->Inside(event)) strcpy(s,"Edit existing level or create a new one");
#endif
        if (*s && font)
          {
            if (text2) SDL_FreeSurface(text2);
            text2=TTF_RenderText_Solid(font,s,color);
            if (text2) PutSurface(text2,screen,(screen->w-text2->w)/2,screen->h-text->h);
            else fprintf(stderr,"WARNING: unsuccesful text render\n");
          }
        SDL_Flip(screen);
#ifdef	WIZ
		if (wiz_getkeys() & (1<<WIZ_MENU))
			quit = true;
#endif
        while (SDL_PollEvent(&event))
          switch (event.type)
            {
              case SDL_QUIT:
                     quit=true;
                   break;
              case SDL_MOUSEBUTTONDOWN:
                     if (button_quit->Inside(event)) quit=true;
                     if (button_play->Inside(event)) Play();
                     if (button_options->Inside(event)) Options();
                     if (button_help->Inside(event)) Help(temp);
                     if (button_highs->Inside(event)) Highs();
                     if (button_continue->Inside(event)) Play("0");
#ifndef	WIZRES
                     if (button_edit->Inside(event)) Edit();
#endif
                   break;
#ifndef	WIZ
              case SDL_KEYDOWN:
                     switch (event.key.keysym.sym)
                       {
                         case SDLK_o:
                                Options();
                              break;
                         case SDLK_p:
                         case SDLK_RETURN:
                                Play();
                              break;
                         case SDLK_h:
                                Help(temp);
                              break;
         				 case SDLK_f:
                                screen=SDL_SetVideoMode(WIDTH,HEIGHT,BPP,SDL_SWSURFACE | (fullscreen=!fullscreen)?SDL_FULLSCREEN:0);
                              break;
                         case SDLK_ESCAPE:
                         case SDLK_q:
                         case SDLK_x:
                         case SDLK_F10:
                                quit=true;
                              break;
                         case SDLK_e:
                                Edit();
                              break;
                       }
                   break;
#endif
            }
      } 
    delete button_quit;
    delete button_play;
    delete button_options;
#ifndef	WIZRES
    delete button_edit;
#endif
    delete button_highs;
    delete button_continue;
    delete button_help;
    SDL_FreeSurface(menu);
    SDL_FreeSurface(text);
    SDL_FreeSurface(musician);
    SDL_FreeSurface(text2);
    TTF_CloseFont(font);
    TTF_Quit();
    Mix_FadeOutMusic(500);
    while (Mix_PlayingMusic())
        ;
    Mix_FreeMusic(music_play);
    Mix_CloseAudio();
    SDL_Quit();
#ifdef	WIZ
	wiz_close();
#endif
    f=fopen(FILE_CONFIG,"w+");
    if (f)
      {
        fprintf(f,"fullscreen=%s\n",fullscreen?"yes":"no");
        fprintf(f,"cursor=%s\n",CURSOR?"yes":"no");
        fprintf(f,"autoreload=%s\n",autoreload?"yes":"no");
        fprintf(f,"autonormal=%s\n",autonormal?"yes":"no");
        fprintf(f,"gravity=%d\n",GRAVITY);
        fprintf(f,"difficulty=%d\n",difficulty);
        fprintf(f,"tileset=%s\n",tileset);
        fprintf(f,"bgalpha=%d\n",bgalpha);
        fclose(f);
      }
    return 0;
}
