/*
** Falling Tower KAI
**	Copyright (c) 2000	ROYALPANDA	All rights reserved
**
**	May 25, 2000 Ver 1.0
*/

#include<stdio.h>
#include<X11/Xlib.h>

#include"xjump.h"
#include"xjump_xlib.h"

static floor_t Floor[HEIGHT];
static int Map_index;
static int Floor_top;

static int Floor_top;
static int Floor_current;

static int Fpos;
 

void FLOOR_draw( floor_t *fp )
{
	int len;


	len = fp->right - fp->left + 1;
	if( len > 0 )
		XCopyArea(Disp,Floor_p[fp->graphic],Scr_d,Gc_nomask,
					fp->phase,0,len,16,fp->left,fp->y);
	if( fp->erase_width )
		XClearArea(Disp,Scr_d,fp->erase_x,fp->erase_y,
					fp->erase_width,16,False);
}


void FLOOR_refresh( void )
{
	int y;
	floor_t *fp;

	for( y = 0, fp = Floor ; y < HEIGHT ; y++, fp++ )
		FLOOR_draw(fp);
}


void FLOOR_create( int y, int level )
{
	int f,x1,x2,l,fvec;
	floor_t *fp;
	int prob;

	f = Floor_top - y;
	fp = Floor + (y + Map_index) % HEIGHT;
	fp->y = y*16;
	fp->phase = 0;	


	if( f % 250 == 0 ){
		fp->floor = Floor_current++;

		fp->left_src = fp->left = 16;
		fp->right_src = fp->right = WIDTH*16-17;
		fp->mu = 1;
		fp->move_vector = 0;
		fp->blink_interval = 0;
		fp->force_vector = 0;
		fp->blink_count = 0;
		fp->graphic = FLOOR_NORMAL;
		return;
	}

	if( f % FLOOR_HEIGHT == 0 ){
		fp->floor = Floor_current;
		level = (Floor_current+100) << level;
		Floor_current++;

		prob = 100 - 10000 / level;

		fvec = (rnd(2)*2-1) * ( rnd( (WIDTH-11)/4 ) + (WIDTH-11)/4 );
		Fpos = ( Fpos + fvec +WIDTH-11 ) % (WIDTH-11);
		
		x1 = ( Fpos+5 - rnd( 3 ) - 2)*16;
		x2 = ( Fpos+5 + rnd( 3 ) + 2)*16+15;

		fp->left_src = fp->left = x1;
		fp->right_src = fp->right = x2;

		if( rnd(120)+20 > prob ){
			fp->graphic = FLOOR_NORMAL;
			fp->mu = 1;
			fp->force_vector = 0;
		}else if( rnd(100) > 50 ){
			fp->graphic = FLOOR_ICE;
			fp->mu = 0;
			fp->force_vector = 0;
		}else{
			fp->graphic = FLOOR_FORCE;
			fp->force_vector = (rnd(2)*3-1)*(rnd(4)+1);
			fp->mu = 1;
		}

		fp->graphic_base = fp->graphic;

		if( rnd(100)+50 < prob ){
			fp->blink_interval = rnd(76)+25;
			fp->blink_count = fp->blink_interval
						- rnd(fp->blink_interval/4);
		}else{
			fp->blink_interval = 0;
			fp->blink_count = 0;
		}

		if( rnd(100) + 10 < prob )
			fp->move_vector = rnd(9)-4;
		else
			fp->move_vector = 0;
	}else{
		fp->left = WIDTH*16;
		fp->right = 0;
		fp->blink_interval = 0;
		fp->blink_count = 0;
	}
}


void FLOOR_move( floor_t *fp, int scroll )
{
	int left,right,left2,right2,tmp;

	fp->erase_y = fp->y;
	fp->erase_width = 0;

	if( fp->left > fp->right )
		return;

	left2 = left = fp->left;
	right2 = right = fp->right;

	if( fp->move_vector ){
		left += fp->move_vector;
		right += fp->move_vector;
		if( left < 16 || right >= (WIDTH-1)*16 ){
			left = left2;
			right = right2;
			fp->move_vector = -fp->move_vector;
		}else{
			if( fp->move_vector > 0 ){
				fp->erase_x = left2;
				fp->erase_width = fp->move_vector;
			}else{
				fp->erase_x = right2 + fp->move_vector + 1;
				fp->erase_width = -fp->move_vector;
			}
		}
	}

	if( scroll ){
		fp->y += 16;
		fp->erase_x = left2;
		fp->erase_width = right2 - left2 + 1;
	}

	if( fp->blink_interval ){
		fp->blink_count--;
		if( fp->blink_count <= 0 ){
			fp->blink_count = fp->blink_interval;
			if( fp->graphic == fp->graphic_base ){
				fp->graphic = FLOOR_CLEAR;
			}else{
				fp->graphic = fp->graphic_base;
				fp->phase = 0;
			}
		}
	}

	fp->left = left;
	fp->right = right;
	if( fp->graphic == FLOOR_CLEAR )
		fp->phase = left & 31;
	else
		fp->phase = (fp->phase - fp->force_vector + 32) & 31;
}


void FLOOR_move_all( int scroll, int level )
{
	int y;
	floor_t *fp;

	for( y = 0, fp = Floor ; y < HEIGHT ; y++, fp++ )
		FLOOR_move(fp,scroll);

	if( scroll ){
		Floor_top++;
		if( --Map_index < 0 )
			Map_index = HEIGHT - 1;
		FLOOR_create( 0,level );
	}
}


floor_t *FLOOR_check(int hx, int hy)
{
	int y;
	floor_t *fp;

	y = ( (hy + 64) / 16 );
	if( y < 0 || y >= HEIGHT )
		return NULL;

	fp = Floor + (y + Map_index) % HEIGHT;

	if( fp->left < hx+28 && hx+4 < fp->right )
		return fp;
	else
		return NULL;
}


void FLOOR_init( void )
{
	int x,y;
	int fvec;

	fvec = (rnd(2)*2-1) * ( rnd( (WIDTH-11)/4 ) + (WIDTH-11)/4 );
	Fpos = ( WIDTH/2 + fvec +WIDTH-11 ) % (WIDTH-11);
	Floor_top = HEIGHT - 4;
	Floor_current = 1;
	Map_index = 0;

	XClearWindow(Disp,Scr_d);

	for ( y = 0 ; y < HEIGHT ; y++ )
		Floor[y].erase_width = 0;

	for ( y = HEIGHT-1 ; y >= 0 ; y-- )
		FLOOR_create(y,0);

	for ( y = 0 ; y < HEIGHT ; y++ )
		FLOOR_draw(Floor+y);
}
