/*
 * ROTOR by CeDeROM
 */

//********************************************************************

#include <stdio.h>
#include <curses.h>
#include <math.h>

//definiujemy przydatne stale

#define	CDR_MAXPOINTS	10	/* maksymalna liczba wierzolkow wielokata */
#define CDR_MINSIZE	10	/* minimalna wielkosc wielokata w scenie skalowania */
#define CDR_MAXSIZE	500	/* maksymalna wielkosc wielokata w scenie skalowania */
#define CDR_DELAY	20000	/* domyslne opoznienie miedzy klatkami animacji */
#define PIX_BLANK	' '	/* definicja znaku pustego */
#define CDR_TXTTITLE	"ROTOR"	/* tytul programu */
#define CDR_TXTKEYS	"Kursory: ruch|Enter < >: obrot|Spacja: boki|W: wypelnienie|B: krawedz|T: tlo|+ -: skala|Q: wyjscie"



/*
 zmienne globalne przechowujace informacje o kolorach i rozmiarze ekranu
 PIX_WHITE - przechowuje domyslny znak dla piksla bialego
 PIX_BORDER - przechowuje domyslny znak dla pksli obwodki wielokata
 PIX_BG - przechowuje domyslny znak tla wielokata
*/

static char PIX_WHITE='#', PIX_BORDER='*', PIX_BG='.';


/*
 CDR_SCRWIDTH - domyslna szerokosc ekranu
 CDR_SCRHEIGHT - domyslna wysokosc ekranu
 CDR_X0 - domyslny poziomy srodek ekranu
 CDR_Y0 - domyslny pionowy srodek ekranu
 Zmienne te o ile to mozliwe sa aktualizowane w trakcie inicjalizacji
 wyswietlacza, oraz podczas skalowania okna terminala.
 Aktualizacja zamuje sie funkcja cd_display_setupsize()
*/

static int CDR_SCRWIDTH=80, CDR_SCRHEIGHT=25, CDR_X0=40, CDR_Y0=12;


/*
 definicja typu struktury	x "gwiazda"
 przechowuje wszystkie informacje o wielokacie
 points - ilosc wierzcholkow
 size - dlugosc ramienia
 fill, border, bg - znaki wypelnienia, obramowania i tla wielokata
 Xi, Yi - wspolrzedne punktow wewnatrznych (zalamania ramion)
 Xo, Yo - wspolrzedne punktow zewnetrznych (wierzcholki ramin)
*/	

struct	star_t {
    int points, size;
    float X0, Y0;
    char fill, border, bg;
    float Xi[CDR_MAXPOINTS];
    float Yi[CDR_MAXPOINTS];
    float Xo[CDR_MAXPOINTS];
    float Yo[CDR_MAXPOINTS];
};




/*
//********************************************************************
// FUNKCJE FUNKCJE FUKNCJE FUNKCJE FUNKCJE FUNKCJE FUNKCJE FUNKCJE
//********************************************************************
*/

/* Funkcja aktualizuje wymiary wyswietlacza */

int cdr_display_setupsize(){
    CDR_SCRWIDTH=COLS;
    CDR_SCRHEIGHT=LINES;
    CDR_X0=(int)(CDR_SCRWIDTH/2);
    CDR_Y0=(int)(CDR_SCRHEIGHT/2);
}


/*
// Funkcja inicjalizuje wyswietlacz
// Uzywamy biblioteki ncurses
*/

int cdr_display_init(){
    int ix;
    ix=(int)initscr();		/* uzywamy biblioteki ncurses */
    nonl();			/* nl bez nl,cr */
    cbreak();			/* przy skanowaniu znakow nie czekamy na \n */
    curs_set(0);		/* chowamy kursor */
    noecho();			/* bez echa */
    erase();			/* czyscimy ekran */
    nodelay(stdscr, TRUE);	/* nie czekamy na wciesniecie guzika (getch) */
    keypad(stdscr, TRUE);	/* zaawansowana obsluga klawiatury */
    return ix;			/* zwracamy status inicjalizacji ncurses */
}


/* Zamykamy wyswietlacz i biblioteke ncurses */

int cdr_display_close(){	
    return endwin();
}


//Czyscimy ekran.
//erase nalezy do ncurses

int cdr_clrscr(){
    erase();
}


//Aktualizujemy ekran (wypisujemy zawartosc z pamieci na monitor)
//refresh() nalezy do ncurses
//Sprawdzamy jednoczesnie czy terminal zmienil rozmiar, jesli tak
//to aktualizujemy dane wyswietlacza

int cdr_display_update(){
    refresh();
    if (is_term_resized(CDR_SCRHEIGHT, CDR_SCRWIDTH)==TRUE)	//comment these
	cdr_display_setupsize();    				//lines on SunOS
}	


//Wyswietlamy jeden pixel w pozucji x, y i kolorze RGB
//Poniewaz rysujemy w trybie tekstowym jako kolorow uzywamy znakow
//mvaddch() nalezy do ncurses

int cdr_putpixel(float x, float y, int R, int G, int B){
    if (R==0 && G==0 & B==0)
        mvaddch(y, x, PIX_WHITE);
    else if (R==1 && G==0 && B==0)
        mvaddch(y, x, PIX_BORDER);
    else if (R==0 && G==0 && B==1)
	mvaddch(y, x, PIX_BG);
}


//Aktualizujemy wyswietlacz i czekamy <seconds> sekund, pikajac co sekunde.

int cdr_update_sb(int seconds){
    int x=0;
    cdr_display_update();
    while (x!=seconds){
	beep();
	sleep(1);
	x++;
    }
}


// Wyswietlamy komunikat na dole ekranu
// Czekamy na nacisniecie spacji
// getch jest w petli poniewaz nie zatrzymuje wykonywania programu

cdr_waitforspace(){
    cdr_text_center(CDR_SCRHEIGHT-1, "[spacja]");
    cdr_display_update();
    while (getch()!=' '){}
}


// Wypisujemy tekst ze zmiennej <string> na pozycji x,y

int cdr_text(int x, int y, char string[]){
    mvaddstr(y, x, string);
}


// Wypisujemy tekst <string> na srodku ekranu, na wysokosci <y>

int cdr_text_center(int y, char string[]){
    mvaddstr(y, CDR_X0-(strlen(string)/2), string);
}


// Sprawdzamy czy nie ma za duzego przeskoku miedzy sasiednimi pikslami linii
// Jesli przeskok jest wiekszy niz 1, rysowana linia nie bedzie ciagla,
// dlatego trzeba ja poprawic

cdr_linevcheck(int x, int y1, int y2, int R, int G, int B){
    if ( (y1-y2>1)||(y1-y2<(-1)) ) cdr_vline(x, y1, y2, R, G, B);
}


// Rysujemy linie przechodzaca przez punkty x1,y1 i x2,y2 o kolorze RGB

int cdr_lineto(int x1, int y1, int x2, int y2, int R, int G, int B){
    int ix, iy, iyprev=0;
    
    if (x1<x2){								//ktory ponkt bardziej z lewej
        for (ix=x1;ix<=x2;ix+=1){					//zaczynamy kreslenie prostej po zmiennej x
	    iy=(int)((ix-x1)*(y1-y2)/(x1-x2))+y1;			//obliczamy zmienna y ze wzoru prostej
	    if (iyprev!=0) cdr_linevcheck(ix, iy, iyprev, R, G, B);	//jesli juz narysowalismy jakis punkt sprawdzmy czy linia jest ciagla
	    cdr_putpixel(ix, iy, R, G, B);				//rysujemy punkt
	    iyprev=iy;							//zapamietujemy wspolrzedne punktu do sprawdzenie ciaglosci
	}
    } else if (x2<x1){
        for (ix=x2;ix<=x1;ix+=1){
	    iy=(int)((ix-x2)*(y2-y1)/(x2-x1))+y2;
	    if (iyprev!=0) cdr_linevcheck(ix, iy, iyprev, R, G, B);
	    cdr_putpixel(ix, iy, R, G, B);
	    iyprev=iy;
	}
    } else cdr_vline(x1, y1, y2, R, G, B);
}


// Rysujemy linie pionowa od yh do yl o wspolrzednej x
// Funkcja jest duzo szybsza od poprzedniej, operuje na liczbach calkowitych
// i sluzy do wypelniania powierdzchni

int cdr_vline(int x, int yh, int yl, int R, int G, int B){
    int iy;
    for ( (yl<=yh)?(iy=yl):(iy=yh) ; (yl<=yh)?(iy<=yh):(iy<yl) ; iy++) cdr_putpixel(x, iy, R, G, B);
}


// Efektownie czyscimy ekran spacjami

int cdr_screen_wipe(){
    int x, y;
    for (y=0;y<=CDR_Y0;y++) {
	for (x=0;x<=CDR_SCRWIDTH;x++){
	    cdr_text(x, y, " ");
	    cdr_text(CDR_SCRWIDTH-x, CDR_SCRHEIGHT-y-1, " ");
	    cdr_display_update();
	}
    }
}


// Rysujemy wypelniony kolorem RGB trojkat o wierzcholkach A, B i C
// Funkcja ta jest podstawa to rysowania bardziej zlozonych figur

int cdr_polygon(int xa, int ya, int xb, int yb, int xc, int yc, int R, int G, int B){
    int ix, iyh, iyl;
    int xmin, ymin, xavr, yavr, xmax, ymax;
    
    if ((xa<=xb)&&(xa<=xc)){		//sprawdzamy ktory wierzcholek jest najbardziej z lewej
	xmin=xa; ymin=ya;		//ktory jest po srodku
	if (xb<xc) {			//i ktory najbardziej z prawej stony
	    xavr=xb; yavr=yb;		//bedzie to potrzebne to wyznaczenia prostych
	    xmax=xc; ymax=yc;		//i zamalowania figury
	} else {
	    xavr=xc; yavr=yc;
	    xmax=xb; ymax=yb;
	}
    } else if ((xb<=xa)&&(xb<=xc)) {
	xmin=xb; ymin=yb;
	if (xa<xc) {
	    xavr=xa; yavr=ya;
	    xmax=xc; ymax=yc;
	} else {
	    xavr=xc; yavr=yc;
	    xmax=xa; ymax=ya;
	}
    } else if ((xc<=xa)&&(xc<=xb)) { 
    	xmin=xc; ymin=yc;
	if (xa<xb) {
	    xavr=xa; yavr=ya;
	    xmax=xb; ymax=yb;
	} else {
	    xavr=xb; yavr=yb;
	    xmax=xa; ymax=ya;
	}
    }
    
    //wypelniamy polowy trojkata liniami pionowymi zawierajacymi sie miedzy prostymi
    //przechodzacymi przez lewy/prawy wierzcholek trojkata
    
    //pierwsza polowa trojkata - od lewej do srodkowego punktu
    for (ix=xmin;ix<xavr;ix++){
	((xmin-xavr)!=0) ? (iyl=(int)((ix-xmin)*(ymin-yavr)/(xmin-xavr))+ymin) : (iyl=(int)((ix-xmin)*(ymin-yavr))+ymin);	//pierwsza prosta
	((xmin-xmax)!=0) ? (iyh=(int)((ix-xmin)*(ymin-ymax)/(xmin-xmax))+ymin) : (iyh=(int)((ix-xmin)*(ymin-ymax))+ymin);	//druga prosta
	cdr_vline(ix, iyh, iyl, R, G, B);											//rysujemy pionowe linie
    }
    //druga polowa trojkata - od srodka do prawej
    for (ix=xavr;ix<xmax;ix++){
	((xavr-xmax)!=0) ? (iyl=(int)((ix-xavr)*(yavr-ymax)/(xavr-xmax))+yavr) : (iyl=(int)((ix-xavr)*(yavr-ymax))+yavr);
	((xmin-xmax)!=0) ? (iyh=(int)((ix-xmin)*(ymin-ymax)/(xmin-xmax))+ymin) : (iyh=(int)((ix-xmin)*(ymin-ymax))+ymin);
	cdr_vline(ix, iyh, iyl, R, G, B);
    }    
}


// Rysujemy wypelniony i obrysowany trojkat
// najpierw rysujac trojkat wypelniony a nastepnie go obrysowujac

int cdr_bpolygon(int xa, int ya, int xb, int yb, int xc, int yc, int R, int G, int B){
    cdr_polygon(xa, ya, xb, yb, xc, yc, R, G, B);
    cdr_lineto(xa, ya, xc, yc, 1, G, B);
    cdr_lineto(xb, yb, xc, yc, 1, G, B);
    cdr_lineto(xa, ya, xb, yb, 1, G, B);
}


// Zamienia radiany na stopnie

float cdr_rad2deg(int x){
    return (x*180)/M_PI;
}


// Zamienia stopnie na radiany

float cdr_deg2rad(int x){
    return ((x*M_PI)/180);
}


// Oblicza modul z liczby calkowitej x

float cdr_module(float x){
    if (x<0)
	return x*(-1);
    else
	return x;
}


// Oblicza odleglosc dwoch punktow w przestrzeni dwuwymiarowej

float cdr_distance(float X1, float Y1, float X2, float Y2){
    return sqrt( pow(cdr_module(X1-X2),2) + pow(cdr_module(Y1-Y2),2) );
}


// Zamienia wspolrzedne ekranu na wspolrzedne wzgledem srodka ekranu (CDR_X0, CDR_Y0)

int cdr_toaxisi(int *x, int *y){
    *x=CDR_X0+*x;
    *y=CDR_Y0-*y;
}


// Skaluje o wielkosc d  wektor o poczatku (x1,y1) zaczepiony w punkcie (x0,y0) 
// Funkcja operuje bezposrednio na zmiennej poprzez wskaznik

int cdr_scale(float x0, float y0, float *x1, float *y1, float d){
    float xnew, ynew;
    xnew=d*(*x1-x0);
    ynew=d*(*y1-y0);
    *x1=xnew+x0;
    *y1=ynew+y0;
}


// Obraca o kat angle punkt (px1,py1) wzlgedem punktu (x0,y0)
// Funkcja operuje bezposrenio na pamieci poprzez wskaznik

int cdr_rotate(float *px1, float *py1, int x0, int y0, float angle){
    float xold, yold, xnew, ynew;
    
    xold=*px1;
    yold=*py1;
    xnew=( (xold-x0)*cos(cdr_deg2rad(angle))) - ( (yold-y0)*sin(cdr_deg2rad(angle)));
    ynew=( (xold-x0)*sin(cdr_deg2rad(angle))) + ( (yold-y0)*cos(cdr_deg2rad(angle)));
    *px1=xnew+x0;
    *py1=ynew+y0;
}


// Funkcja generuje wpolrzedne gwiazdy na podstawie wskazanej struktury star.
// Struktura musi zawierac conajmniej ilosc wierzcholkow (pomiedzy 2 a 9),
// oraz wspolrzedne srodka figury.
// Operuje bezposrednio na wskazanej strukturze

int cdr_star_generate(struct star_t *star){
    float x, y;
    int current_point;
    
    for (current_point=0;current_point<=(star->points);current_point++){
	x=(star->X0)+star->size;
	y=(star->Y0);
	cdr_rotate(&x, &y, star->X0, star->Y0, (360/(star->points))*current_point);
	star->Xo[current_point]=x;
	star->Yo[current_point]=y;
    }

    for (current_point=0;current_point<=(star->points);current_point++){
	x=(star->X0)+(star->size/2);
	y=(star->Y0);
	cdr_rotate(&x, &y, star->X0, star->Y0, (current_point*(360/(star->points)))+(180/(star->points)	) );
	star->Xi[current_point]=x;
	star->Yi[current_point]=y;
    }
}


// Rysuje siatke gwiazdy/wielokatu na podstaiwe wskazanej struktury

int cdr_star_draw(struct star_t *star){
    int current_point;
    for (current_point=0;current_point<=star->points;current_point++){
        if (current_point!=0) cdr_lineto(star->Xi[current_point], star->Yi[current_point], star->Xo[current_point-1], star->Yo[current_point-1], 1,0,0);
        if (current_point!=star->points) cdr_lineto(star->Xi[current_point], star->Yi[current_point], star->Xo[current_point+1], star->Yo[current_point+1], 1,0,0);
    }
}


// Rysuje wypelniona gwiazde

int cdr_star_draw_filled(struct star_t *star){
    int current_point;
    for (current_point=0;current_point<=star->points;current_point++){
	if (current_point!=0) cdr_polygon(star->X0, star->Y0, star->Xi[current_point], star->Yi[current_point], star->Xo[current_point-1], star->Yo[current_point-1], 0,0,0);
        if (current_point!=star->points) cdr_polygon(star->X0, star->Y0, star->Xi[current_point], star->Yi[current_point], star->Xo[current_point+1], star->Yo[current_point+1], 0,0,0);
    }
}

// Rysuje wypalniona i obrysowana gwiazde

int cdr_star_draw_fb(struct star_t *star){
    int current_point;
    for (current_point=0;current_point<=star->points;current_point++){
	if (current_point!=0) cdr_polygon(star->X0, star->Y0, star->Xi[current_point], star->Yi[current_point], star->Xo[current_point-1], star->Yo[current_point-1], 0,0,0);
        if (current_point!=star->points) cdr_polygon(star->X0, star->Y0, star->Xi[current_point], star->Yi[current_point], star->Xo[current_point+1], star->Yo[current_point+1], 0,0,0);
        if (current_point!=0) cdr_lineto(star->Xi[current_point], star->Yi[current_point], star->Xo[current_point-1], star->Yo[current_point-1], 1,0,0);
        if (current_point!=star->points) cdr_lineto(star->Xi[current_point], star->Yi[current_point], star->Xo[current_point+1], star->Yo[current_point+1], 1,0,0);
    }
}


// Obraca wiazde ze wskazywanej struktury <star> o kat <angle>

int cdr_star_rotate(struct star_t *star, int angle){
    int current_point;
    for (current_point=0;current_point<=(star->points);current_point++){
        cdr_rotate(&star->Xo[current_point], &star->Yo[current_point], star->X0, star->Y0, angle);
        cdr_rotate(&star->Xi[current_point], &star->Yi[current_point], star->X0, star->Y0, angle);	    
    }
}


// Przesuwa gwiazde o wektor (Xn,Yn)

int cdr_star_move(struct star_t *star, float Xn, float Yn){
    int current_point;

    star->X0+=Xn;
    star->Y0+=Yn;
    for (current_point=0;current_point<=(star->points);current_point++){
	star->Xi[current_point]+=Xn;
	star->Yi[current_point]+=Yn;
	star->Xo[current_point]+=Xn;
	star->Yo[current_point]+=Yn;
    }
}


// Skaluje gwiazde <star> o wielkosc rzeczywista <scale>

int cdr_star_scale(struct star_t *star, float scale){
    int current_point;
    for (current_point=0;current_point<=(star->points);current_point++){
	cdr_scale(star->X0, star->Y0, &star->Xi[current_point], &star->Yi[current_point], scale);
	cdr_scale(star->X0, star->Y0, &star->Xo[current_point], &star->Yo[current_point], scale);
    }
}


// Wypelnia tlo kolorem RGB / odpowiednim znakiem

int cdr_bg_fill(int R, int G, int B){
    int  x;
    for (x=0;x<=CDR_SCRWIDTH;x++)
	cdr_vline(x, 0, CDR_SCRHEIGHT, R,G,B);
}


// Przerysowuje caly ekran - kasuje zawartosc, wypelnia tlo, rysuje wielokat, obramowanie
// i napisy opisujace poszczegolne klawisze

int cdr_screen_redraw(struct star_t *star){
    cdr_clrscr();
    cdr_bg_fill(0,0,1);
    cdr_star_draw_fb(star);
    box(stdscr, ACS_VLINE, ACS_HLINE);
    mvwprintw(stdscr, 0, (CDR_X0-strlen(CDR_TXTTITLE)), "| %s |", CDR_TXTTITLE);
    mvwprintw(stdscr, CDR_SCRHEIGHT-1, 1, "| %s |", CDR_TXTKEYS);
    cdr_display_update();
}


// Wyswietla okienko dialogowe o tytule <title_text> z polem wpisowym
// operuje na pamiei poprzez wskaznik znakowy <text>.
// W okienko mozna wpisac maksymalnie <maxlen> znakow

int input_dialog(char title_text[], char *text, int maxlen) 
{
       WINDOW *w_input_dialog;
       w_input_dialog=newwin(3, 46, (CDR_Y0-2), (CDR_X0-23));
       box(w_input_dialog, ACS_VLINE, ACS_HLINE);
       mvwprintw(w_input_dialog, 0, 1, "| %s |", title_text);
       wrefresh(w_input_dialog);    
       beep();
       echo();
       mvwgetnstr(w_input_dialog, 1, 1, text, maxlen);	//use this in Linux/BSD
//       mvwgetstr(w_input_dialog, 1, 1, text);       	//use this line in SunOS
       noecho();
       touchwin(w_input_dialog);
       delwin(w_input_dialog);
       refresh();
}


// Rysuje katajacy trojkat na poczatku programu

int play_triangle(){
    float ix=1, iy=1, Xa, Ya, Xb, Yb, Xc, Yc, x;
    int x1=CDR_X0-5, y1=CDR_Y0-5, x2=CDR_X0-2, y2=CDR_Y0, x3=CDR_X0, y3=CDR_Y0-10;
    while (getch()!=' '){ 				//opuszczamy funkcje po nacisnieciu spacji
	x+=0.01;
	ix=sin(x)+1;					//sinus i kosinus jest wszedzie
	iy=cos(x)+1;
        cdr_clrscr();					//czysciemy ekran
	Xa=x1*ix-4;					//obliczamy wspolrzedne punktow A, B, C
	Ya=y1*ix;
	Xb=x2*ix+4;
	Yb=y2*iy;
	Xc=x3*iy-4;
	Yc=y3*ix;
        cdr_bpolygon(Xa, Ya, Xb, Yb, Xc, Yc, 0,0,0);	//rysujemy wypelniony i obrysowany trojkat
	cdr_text_center(1, "=========");		//wyipsujemy tytul programu
	cdr_text_center(2, "ROTOR");
	cdr_text_center(3, "=========");	
	cdr_text_center(CDR_SCRHEIGHT-1, "[Spacja]");	//i informacje o aktywnej spacji
	cdr_display_update();				//odswierzamy ekran
	usleep(CDR_DELAY);					//czekamy
    }
}





//*********************************************************************
//PROGRAM PROGRAM PROGRAM PROGRAM PROGRAM PROGRAM PGORAM PROGRAM
//*********************************************************************





int main(int argc){

    struct star_t star;		//deklarujemy stukture prechowujaca dane naszego wielokata
    int itemp;			//pomocnicza zmianna licbowa calkowita
    
    cdr_display_init();		//inicjujemy ekran (i biblioteke ncurses)
    cdr_clrscr();		//czyscimy ekran
    cdr_display_update();	//aktualizyujemy ekran
    play_triangle();		//wlaczamy animacje latajacego trojkata

    if (argc!=1) goto PROGRAM_GLOWNY;	//jesli podalismy jakikolwiek parametr - opuszczamy intro
    
    //**********
    // SCENA 1
    //**********
    
    cdr_clrscr();								//czyscimy ekran
    cdr_display_update();							//odswierzamy ekran
    cdr_putpixel(CDR_X0, CDR_Y0, 1,0,0);					//rysujemy pixel na srodku ekranu
    cdr_text_center(CDR_Y0-5, "WITAJ!");					//piszemy tekst
    cdr_text_center(CDR_Y0-3, "JESTEM PIXLEM. LUDZIE WYKORZYSTUJA MNIE");
    cdr_update_sb(2);								//odswierzamy ekran pikajac co sekunde
    cdr_text_center(CDR_Y0-2, "DO RYSOWANIA");
    cdr_update_sb(2);

    cdr_text_center(CDR_SCRHEIGHT-5, "CHCIALBYM CI POKAZAC KILA SZTUCZEK");
    cdr_waitforspace();								//zatrzymujemy odtwarzanie czekajac na nacisniecie <spacji>
    

    //**********
    // SCENA 2
    //**********

    cdr_clrscr();
    cdr_text_center(2, "LUBIE RYSOWAC LINIE");
    cdr_update_sb(1);
    cdr_lineto(5, 5, CDR_SCRWIDTH-5, CDR_SCRHEIGHT-5, 1,0,0);			//rysujemy 6 linii ktore beda wygladaly jak koperta
    cdr_update_sb(1);
    cdr_lineto(CDR_SCRWIDTH-5, 5, 5, CDR_SCRHEIGHT-5, 1,0,0);
    cdr_update_sb(1);
    cdr_lineto(5, 5, CDR_SCRWIDTH-5, 5, 1,0,0);
    cdr_update_sb(1);
    cdr_lineto(CDR_SCRWIDTH-5, 5, CDR_SCRWIDTH-5, CDR_SCRHEIGHT-5, 1,0,0);
    cdr_update_sb(1);
    cdr_lineto(5, 5, 5, CDR_SCRHEIGHT-5, 1,0,0);
    cdr_update_sb(1);
    cdr_lineto(5, CDR_SCRHEIGHT-5, CDR_SCRWIDTH-5, CDR_SCRHEIGHT-5,  1,0,0);
    cdr_update_sb(1);
    cdr_waitforspace();


    //**********
    // SCENA 3
    //**********
    
    float x=CDR_X0+10, y=CDR_Y0-2;					//deklarujemy wspolrzedne punktu
    while(getch()!=' '){						//petla z ktorej wychodzi nacisniecie <spacji>
	cdr_clrscr();							//czyscimy ekran			
	cdr_text_center(2, "ALBO BIEGAC DOOKOLA WLASNEGO OGONA");	//piszemy jakis tekst
        cdr_text_center(CDR_SCRHEIGHT-1, "[spacja]");
	cdr_rotate(&x, &y, CDR_X0, CDR_Y0, 5);				//obracamy wspolrzedne punktu (x, y) o kat 5 stopni
	cdr_putpixel(x, y, 1, 0, 0);					//rysujemy pixel w nowym miejscu
	cdr_display_update();						//odswierzamy ekran
	usleep(CDR_DELAY);						//opoznienie
    }


    //***********
    // SCENA 4
    //***********

    //tutaj nic nowego sie nie dzieje, znowu jakis tekst...
    cdr_clrscr();
    cdr_text_center(CDR_Y0-2, "PONIEWAZ OSTATNIO ZADKO MOGE ZROBIC COS FAJNEGO");
    cdr_update_sb(3);
    cdr_text_center(CDR_Y0, "POSTANOWILEM WYKORZYSTAC OKAZJE");
    cdr_update_sb(3);
    cdr_text_center(CDR_Y0+2, "I NAPISALEM COS TAKEIGO...");
    cdr_update_sb(3);


    //***********
    // SCENA 5
    //***********

    int point, points;		//zmienne przechowujaca nuerm aktualnego wierzcholka i ilosc wierzcholkow
    star.X0=CDR_X0;		//ustalamy wpolrzedna X srodka  gwiazdy na srodek ekranu
    star.Y0=CDR_Y0;		//ustalamy swpolrzedna Y srodka gwiazdy na srodek ekranu
    star.size=100;		//wielkosc gwiazdy (100 - bardzi duza)
    star.points=2;		//ilosc ramion
    x=CDR_X0+5; y=CDR_Y0;	//ustalamy wartosc zmiennyc x i y
    star.fill=PIX_WHITE;	//ustalamy znak wypelnienia figury
    star.border=PIX_BORDER;	//ustalamy znak obrysowania figury
    star.bg=PIX_BG;

    cdr_clrscr();		//czyscimy ekran

    //rysujemy animowane gwiazdy
    //zwiekszajac ilosc ramion od 2 do stalej CDR_MAXPOINTS

    for (points=2; points<CDR_MAXPOINTS;points++){					//zwiekszamy ilosc ramion rysowanych gwiazd od 2 do 9
	star.points=points;								//ustalamy ilosc ramion w strukturze
        cdr_star_generate(&star);							//generujemy zadana gwiazde
	beep();										//pikamy dwukrotnie
	usleep(CDR_DELAY*8);								//z krotka przerwa
	beep();


        while( cdr_distance(star.Xo[0], star.Yo[0], star.X0, star.Y0)>CDR_MINSIZE){	//petla 1 - najpierw zmniejszamy figure
    	    cdr_clrscr();								//czyscimy ekran
	    cdr_star_draw_filled(&star);						//rysujemy wypelniana gwiazde
	    cdr_star_rotate(&star, 5);							//przekrecamy gwiazde o 5 stopni
	    cdr_star_scale(&star, 0.97);						//zmniejszamy gwiazde
	    cdr_display_update();							//odswierzamy ekran
    	    usleep(CDR_DELAY);								//opoznienie
	 }
	beep();										//figura zmniejszona - pikamy! ;)
	
	while( cdr_distance(star.Xo[0], star.Yo[0], star.X0, star.Y0)<CDR_MAXSIZE){	//petla 2 - zwiekszamy figure
	    cdr_clrscr();								//czyscimy ekran
	    cdr_star_draw_filled(&star);						//rysujemy wypelniana gwiazde
	    cdr_star_rotate(&star, 5);							//przekrecamy ja o 5 stopni
	    cdr_star_scale(&star, 1.2);							//zwiekszamy gwiazde
    	    cdr_display_update();							//odsiwerzamy ekran
    	    usleep(CDR_DELAY);								//opoznienie
	}
    }


    //***********
    // SCENA 6
    //***********

    //ladnie czyscimy ekran
    cdr_screen_wipe();

    //teksci i opoznienie
    cdr_text_center(CDR_Y0, "PENTAGRAM POWERS!");
    cdr_update_sb(4);


    //***********
    // SCENA 7
    //***********

    star.points=5;									//pentagram ma 5 ramion
    star.size=15;									//rozmiar 15 (wejdzie na ekran)
    cdr_star_generate(&star);								//generujemy gwiazde
    while( cdr_distance(star.Xo[0], star.Yo[0], star.X0, star.Y0)>(CDR_MINSIZE-5)){	//petla - zmniejszamy gwiazde
        cdr_clrscr();									//czyscimy ekran
	cdr_star_draw(&star);								//rysujemy gwiazde
	cdr_star_rotate(&star, -5);							//przekrecamy ja o 5 stopni w lewo
	cdr_star_scale(&star, 0.995);							//i powoli zmniejszamy
    	cdr_display_update();								//odswierzamy ekran
    	usleep(CDR_DELAY);								//opoznienie
    }
    beep();										//gwiazde zmniejszona - pikamy!

    while( cdr_distance(star.Xo[0], star.Yo[0], star.X0, star.Y0)<CDR_MAXSIZE-10){	//kolejna petla - zwiekszamy znacznie gwiazde
        cdr_clrscr();
	cdr_star_draw_fb(&star);
	cdr_star_rotate(&star, 5);							//krecimy gwiazde w prawo
	cdr_star_scale(&star, 1.05);
    	cdr_display_update();
    	usleep(CDR_DELAY);
    }


    //***********
    // SCENA 8
    //***********

    cdr_screen_wipe();

    cdr_text_center(CDR_Y0, "ZA SLABE?");
    cdr_update_sb(4);


    //***********
    // SCENA 9
    //***********

    int timer1=400, timer2, current_point;	//tutaj bedziemy liczyc czas calkowity sceny (timer1) i poszczegolnych scen (timer2)
    star.points=5;				//chcemy petagram
    star.size=10;				//o rozmiarze 10
    cdr_star_generate(&star);			//generujemy gwiazde
    while (timer1>0){														//duza petla	
	beep();
	for (timer2=0;timer2<=50;timer2++){											//mniejsza petla
	    cdr_clrscr();													//czyscimy ekran
    	    cdr_star_draw(&star);												//rysujemy gwiazde
	    cdr_star_rotate(&star, -5);												//przekrecamy ja w leo p 5 stopni
	    for (current_point=0;current_point<=star.points;current_point++){							//efekt wybuchowy gwiazdy
		cdr_scale(star.X0, star.Y0, &star.Xi[current_point], &star.Yi[current_point], (1.0101+0.2*cos(timer2/2)) );	//wierzcholki wewnetrzne sie powiekszaja wg cosinusa
		cdr_scale(star.X0, star.Y0, &star.Xo[current_point], &star.Yo[current_point], (1.0101+0.2*sin(timer2/2)) );	//a wierzcholki zewnetrzne zmniejszaja
	    }
    	    cdr_display_update();		//odswierzamy ekran
    	    usleep(CDR_DELAY);			//opoznienie
	    timer1--;				//zmenijszamy timer1 - czas uplywa...
        }
	beep();					//koniec pierwszego efektu - pikamy!

	for (timer2=0;timer2<=50;timer2++){											//druga mniejsza petla
            cdr_clrscr();
	    cdr_star_draw_fb(&star);												//rysujemy gwiazdw wypelniana i obrysowana
	    cdr_star_rotate(&star, 2);												//obracamy ja o 2 stopnie w prawo
	    for (current_point=0;current_point<=star.points;current_point++){ 							//efekt 2 - szybki morphing
		cdr_scale(star.X0, star.Y0, &star.Xo[current_point], &star.Yo[current_point], (1.01+0.2*cos(timer2/2)));
		cdr_scale(star.X0, star.Y0, &star.Xi[current_point], &star.Yi[current_point], (1.01+0.2*sin(timer2/2)) );
	    }
    	    cdr_display_update();		//odswierzamy ekran
    	    usleep(CDR_DELAY);			//opoznienie
	    timer1--;				//a czas wciaz leci
	}
	beep();					//pikamy
    }


    //**********
    // SCENA 10
    //**********

    beep();										//koniec morphingu jednego i drugiego - pikamy
    while( cdr_distance(star.Xo[0], star.Yo[0], star.X0, star.Y0)<CDR_MAXSIZE-20){	// i ladnie wychodzimy z ujecia
        cdr_clrscr();
	cdr_star_draw_fb(&star);
	cdr_star_rotate(&star, 3);							//obracajac gwiazde
	cdr_star_scale(&star, 1.05);							//i powiekszajac az azpelni caly ekran
    	cdr_display_update();
    	usleep(CDR_DELAY);
    }


    //***********
    // SCENA 11
    //***********

    cdr_screen_wipe();
    cdr_text_center(CDR_Y0, "STEROWANIE RECZNE!");
    cdr_update_sb(4);
    

    //***********
    //SCENA 12
    //***********

PROGRAM_GLOWNY:

    //tutaj zaczyna sie petla pozwalajaca uzytkownikowi kontrolowac ruchy bryly

    star.X0=CDR_X0;			//ustalamy wspolrzedne X srodka gwiazdy
    star.Y0=CDR_Y0;			//ustalamy wspolrzedna Y srodka gwiazdy
    star.size=10;			//ustalamy wielkosc gdwiazdy
    star.points=5;			//i ilosc ramion
    cdr_star_generate(&star);		//generujemy gwiazde
    cdr_screen_redraw(&star);		//przerysowujemy ekran programu, wrac z tlem, ramka, tytulem i klawiszologia

    int button;									//zmienna przechowujaca numer wcisnietego klawisza klawiatury
    char input[5];								//tablica znakow przwchowujaca tekst wpisany w okno dialogowe
    while(button=getch()){
	if (button=='q')							//jesli nacisnieto Q - konczymy program
	    break;
	else if (button==46){							//nacisnieto '.' - obracamy figure o jeden stopien w prawo
	    cdr_star_rotate(&star, 1);
	    cdr_screen_redraw(&star);
	} else if (button==44){							//nacisnieto ',' - obracamy figure o jeden stopien w lewo
	    cdr_star_rotate(&star, -1);
	    cdr_screen_redraw(&star);
	} else if (button==62){							//nacisnieto '>' (Shift+.) - obracamy figure o dzisiec stopni w prawo
	    cdr_star_rotate(&star, 10);
	    cdr_screen_redraw(&star);
	} else if (button==60){							//nacisnieto '<' (Shift+,) - obracamy figure o dzisiec stopni w lewo
	    cdr_star_rotate(&star, -10);
	    cdr_screen_redraw(&star);
	} else if (button==KEY_LEFT){						//nacisnieto kursor <- - przesuwamy figure o jeden pixel w lewo
	    cdr_star_move(&star, -1, 0);
	    cdr_screen_redraw(&star);
	} else if (button==KEY_RIGHT){						//nacisnieto kursor -> - przesuwamy figure o jeden pixel w prawo
	    cdr_star_move(&star, 1, 0);
	    cdr_screen_redraw(&star);
	} else if (button==KEY_UP){						//nacisnieto kursor "do gory" - przesuwamy figure o jeden pixel do gory
	    cdr_star_move(&star, 0, -1);
	    cdr_screen_redraw(&star);
	} else if (button==KEY_DOWN){						//nacisnieto kursor "w dol" - przesuwamy figure o jeden pixel w dol
	    cdr_star_move(&star, 0, 1);
	    cdr_screen_redraw(&star);
	} else if (button==43){							//nacisnieto + - zwiekszamy figure
	    cdr_star_scale(&star, 1.1);
	    cdr_screen_redraw(&star);
	} else if (button==45){							//nacisnieto - - zmniejszamyy figure
	    cdr_star_scale(&star, 0.9);
	    cdr_screen_redraw(&star);
	} else if (button==13){							//nacisnieto <enter> - wyswietlamy pole diagogowe z prosba o podanie katu obrotu
	    input_dialog("Podaj kat w stopniach", input, 4);			//wyswietlamy okienko dialogowe
	    itemp=atoi(input);							//zamianiamy wprowadzony tekst na liczbe
	    if (itemp!=0)							//sprawdzamy czy wprowadzono poprawna liczbe
		cdr_star_rotate(&star, itemp);					//jesli tak, obracamy figure o zadany kat
	    else beep();							//jesli nie, pikamy
    	    cdr_screen_redraw(&star);						// przerysowujemy ekran	    
	} else if (button=='b'){						//wcisnieto B - wysiwetlamy okno dialogowe w ktore moze wprowadzic znak
	    input_dialog("Podaj znak wypelnienia brzegu", input, 1);		//ktorym bedzie obrysowana figura
	    PIX_BORDER=*input;
	    cdr_screen_redraw(&star);
	} else if (button=='w'){						//wcisnieto W - wyswietlamy okno dialogowe w ktore mozna wporwadzic znak
	    input_dialog("Podaj znak wypelnienia figury", input, 1);		//ktorym figura bedzie wypelniona
	    PIX_WHITE=*input;
	    cdr_screen_redraw(&star);
	} else if (button=='t'){						//wcisnieto T - wysiwetlamy okno dialogowe w ktore nalezy wprowadzic znak wypelnienia tla
	    input_dialog("Podaj znak wypelnienia tla", input, 1);
	    PIX_BG=*input;
	    cdr_screen_redraw(&star);
	} else if (button==' '){						//wcisnieto spacje - pokazujemy okno dialogowe w ktore nalezy wprowadzic zadana
	    input_dialog("Podaj liczbe wierzcholkow (2-9)", input, 2);		//liczbe wierzcholkow nowej figury
	    itemp=atoi(input);							//zamieniamy liczbe tekst na liczbe
	    if ((itemp>=2) && (itemp<=9)){					//uaktualniamy strukture gwiazdy
		star.points=itemp;						
		cdr_star_generate(&star);					//generujemy nowa gwiazde
	    } else beep();							//jesli nie wprowadzono lasciwej liczby - pikamy ostrzegawczo
    	    cdr_screen_redraw(&star);						//przerysowujemy ekran	    
	}
    }


    //**********
    // SCENA 13
    //**********

    //koncowa scena - informacje o autorze
    cdr_clrscr();
    cdr_text_center(CDR_Y0, "CeDeROM of KSZAK");
    cdr_text_center(CDR_Y0+1, "AC01122003");
    cdr_update_sb(4);
    
    
    //zamykamy biblioteke ncurses i wyswietlacz
    cdr_display_close();

    //poprawnie konczymy program
    exit(0);
}
/*
 * ROTOR by CeDeROM
 */

//********************************************************************

#include <stdio.h>
#include <curses.h>
#include <math.h>

//definiujemy przydatne stale

#define	CDR_MAXPOINTS	10	/* maksymalna liczba wierzolkow wielokata */
#define CDR_MINSIZE	10	/* minimalna wielkosc wielokata w scenie skalowania */
#define CDR_MAXSIZE	500	/* maksymalna wielkosc wielokata w scenie skalowania */
#define CDR_DELAY	20000	/* domyslne opoznienie miedzy klatkami animacji */
#define PIX_BLANK	' '	/* definicja znaku pustego */
#define CDR_TXTTITLE	"ROTOR"	/* tytul programu */
#define CDR_TXTKEYS	"Kursory: ruch|Enter < >: obrot|Spacja: boki|W: wypelnienie|B: krawedz|T: tlo|+ -: skala|Q: wyjscie"



/*
 zmienne globalne przechowujace informacje o kolorach i rozmiarze ekranu
 PIX_WHITE - przechowuje domyslny znak dla piksla bialego
 PIX_BORDER - przechowuje domyslny znak dla pksli obwodki wielokata
 PIX_BG - przechowuje domyslny znak tla wielokata
*/

static char PIX_WHITE='#', PIX_BORDER='*', PIX_BG='.';


/*
 CDR_SCRWIDTH - domyslna szerokosc ekranu
 CDR_SCRHEIGHT - domyslna wysokosc ekranu
 CDR_X0 - domyslny poziomy srodek ekranu
 CDR_Y0 - domyslny pionowy srodek ekranu
 Zmienne te o ile to mozliwe sa aktualizowane w trakcie inicjalizacji
 wyswietlacza, oraz podczas skalowania okna terminala.
 Aktualizacja zamuje sie funkcja cd_display_setupsize()
*/

static int CDR_SCRWIDTH=80, CDR_SCRHEIGHT=25, CDR_X0=40, CDR_Y0=12;


/*
 definicja typu struktury	x "gwiazda"
 przechowuje wszystkie informacje o wielokacie
 points - ilosc wierzcholkow
 size - dlugosc ramienia
 fill, border, bg - znaki wypelnienia, obramowania i tla wielokata
 Xi, Yi - wspolrzedne punktow wewnatrznych (zalamania ramion)
 Xo, Yo - wspolrzedne punktow zewnetrznych (wierzcholki ramin)
*/	

struct	star_t {
    int points, size;
    float X0, Y0;
    char fill, border, bg;
    float Xi[CDR_MAXPOINTS];
    float Yi[CDR_MAXPOINTS];
    float Xo[CDR_MAXPOINTS];
    float Yo[CDR_MAXPOINTS];
};




/*
//********************************************************************
// FUNKCJE FUNKCJE FUKNCJE FUNKCJE FUNKCJE FUNKCJE FUNKCJE FUNKCJE
//********************************************************************
*/

/* Funkcja aktualizuje wymiary wyswietlacza */

int cdr_display_setupsize(){
    CDR_SCRWIDTH=COLS;
    CDR_SCRHEIGHT=LINES;
    CDR_X0=(int)(CDR_SCRWIDTH/2);
    CDR_Y0=(int)(CDR_SCRHEIGHT/2);
}


/*
// Funkcja inicjalizuje wyswietlacz
// Uzywamy biblioteki ncurses
*/

int cdr_display_init(){
    int ix;
    ix=(int)initscr();		/* uzywamy biblioteki ncurses */
    nonl();			/* nl bez nl,cr */
    cbreak();			/* przy skanowaniu znakow nie czekamy na \n */
    curs_set(0);		/* chowamy kursor */
    noecho();			/* bez echa */
    erase();			/* czyscimy ekran */
    nodelay(stdscr, TRUE);	/* nie czekamy na wciesniecie guzika (getch) */
    keypad(stdscr, TRUE);	/* zaawansowana obsluga klawiatury */
    return ix;			/* zwracamy status inicjalizacji ncurses */
}


/* Zamykamy wyswietlacz i biblioteke ncurses */

int cdr_display_close(){	
    return endwin();
}


//Czyscimy ekran.
//erase nalezy do ncurses

int cdr_clrscr(){
    erase();
}


//Aktualizujemy ekran (wypisujemy zawartosc z pamieci na monitor)
//refresh() nalezy do ncurses
//Sprawdzamy jednoczesnie czy terminal zmienil rozmiar, jesli tak
//to aktualizujemy dane wyswietlacza

int cdr_display_update(){
    refresh();
    if (is_term_resized(CDR_SCRHEIGHT, CDR_SCRWIDTH)==TRUE)	//comment these
	cdr_display_setupsize();    				//lines on SunOS
}	


//Wyswietlamy jeden pixel w pozucji x, y i kolorze RGB
//Poniewaz rysujemy w trybie tekstowym jako kolorow uzywamy znakow
//mvaddch() nalezy do ncurses

int cdr_putpixel(float x, float y, int R, int G, int B){
    if (R==0 && G==0 & B==0)
        mvaddch(y, x, PIX_WHITE);
    else if (R==1 && G==0 && B==0)
        mvaddch(y, x, PIX_BORDER);
    else if (R==0 && G==0 && B==1)
	mvaddch(y, x, PIX_BG);
}


//Aktualizujemy wyswietlacz i czekamy <seconds> sekund, pikajac co sekunde.

int cdr_update_sb(int seconds){
    int x=0;
    cdr_display_update();
    while (x!=seconds){
	beep();
	sleep(1);
	x++;
    }
}


// Wyswietlamy komunikat na dole ekranu
// Czekamy na nacisniecie spacji
// getch jest w petli poniewaz nie zatrzymuje wykonywania programu

cdr_waitforspace(){
    cdr_text_center(CDR_SCRHEIGHT-1, "[spacja]");
    cdr_display_update();
    while (getch()!=' '){}
}


// Wypisujemy tekst ze zmiennej <string> na pozycji x,y

int cdr_text(int x, int y, char string[]){
    mvaddstr(y, x, string);
}


// Wypisujemy tekst <string> na srodku ekranu, na wysokosci <y>

int cdr_text_center(int y, char string[]){
    mvaddstr(y, CDR_X0-(strlen(string)/2), string);
}


// Sprawdzamy czy nie ma za duzego przeskoku miedzy sasiednimi pikslami linii
// Jesli przeskok jest wiekszy niz 1, rysowana linia nie bedzie ciagla,
// dlatego trzeba ja poprawic

cdr_linevcheck(int x, int y1, int y2, int R, int G, int B){
    if ( (y1-y2>1)||(y1-y2<(-1)) ) cdr_vline(x, y1, y2, R, G, B);
}


// Rysujemy linie przechodzaca przez punkty x1,y1 i x2,y2 o kolorze RGB

int cdr_lineto(int x1, int y1, int x2, int y2, int R, int G, int B){
    int ix, iy, iyprev=0;
    
    if (x1<x2){								//ktory ponkt bardziej z lewej
        for (ix=x1;ix<=x2;ix+=1){					//zaczynamy kreslenie prostej po zmiennej x
	    iy=(int)((ix-x1)*(y1-y2)/(x1-x2))+y1;			//obliczamy zmienna y ze wzoru prostej
	    if (iyprev!=0) cdr_linevcheck(ix, iy, iyprev, R, G, B);	//jesli juz narysowalismy jakis punkt sprawdzmy czy linia jest ciagla
	    cdr_putpixel(ix, iy, R, G, B);				//rysujemy punkt
	    iyprev=iy;							//zapamietujemy wspolrzedne punktu do sprawdzenie ciaglosci
	}
    } else if (x2<x1){
        for (ix=x2;ix<=x1;ix+=1){
	    iy=(int)((ix-x2)*(y2-y1)/(x2-x1))+y2;
	    if (iyprev!=0) cdr_linevcheck(ix, iy, iyprev, R, G, B);
	    cdr_putpixel(ix, iy, R, G, B);
	    iyprev=iy;
	}
    } else cdr_vline(x1, y1, y2, R, G, B);
}


// Rysujemy linie pionowa od yh do yl o wspolrzednej x
// Funkcja jest duzo szybsza od poprzedniej, operuje na liczbach calkowitych
// i sluzy do wypelniania powierdzchni

int cdr_vline(int x, int yh, int yl, int R, int G, int B){
    int iy;
    for ( (yl<=yh)?(iy=yl):(iy=yh) ; (yl<=yh)?(iy<=yh):(iy<yl) ; iy++) cdr_putpixel(x, iy, R, G, B);
}


// Efektownie czyscimy ekran spacjami

int cdr_screen_wipe(){
    int x, y;
    for (y=0;y<=CDR_Y0;y++) {
	for (x=0;x<=CDR_SCRWIDTH;x++){
	    cdr_text(x, y, " ");
	    cdr_text(CDR_SCRWIDTH-x, CDR_SCRHEIGHT-y-1, " ");
	    cdr_display_update();
	}
    }
}


// Rysujemy wypelniony kolorem RGB trojkat o wierzcholkach A, B i C
// Funkcja ta jest podstawa to rysowania bardziej zlozonych figur

int cdr_polygon(int xa, int ya, int xb, int yb, int xc, int yc, int R, int G, int B){
    int ix, iyh, iyl;
    int xmin, ymin, xavr, yavr, xmax, ymax;
    
    if ((xa<=xb)&&(xa<=xc)){		//sprawdzamy ktory wierzcholek jest najbardziej z lewej
	xmin=xa; ymin=ya;		//ktory jest po srodku
	if (xb<xc) {			//i ktory najbardziej z prawej stony
	    xavr=xb; yavr=yb;		//bedzie to potrzebne to wyznaczenia prostych
	    xmax=xc; ymax=yc;		//i zamalowania figury
	} else {
	    xavr=xc; yavr=yc;
	    xmax=xb; ymax=yb;
	}
    } else if ((xb<=xa)&&(xb<=xc)) {
	xmin=xb; ymin=yb;
	if (xa<xc) {
	    xavr=xa; yavr=ya;
	    xmax=xc; ymax=yc;
	} else {
	    xavr=xc; yavr=yc;
	    xmax=xa; ymax=ya;
	}
    } else if ((xc<=xa)&&(xc<=xb)) { 
    	xmin=xc; ymin=yc;
	if (xa<xb) {
	    xavr=xa; yavr=ya;
	    xmax=xb; ymax=yb;
	} else {
	    xavr=xb; yavr=yb;
	    xmax=xa; ymax=ya;
	}
    }
    
    //wypelniamy polowy trojkata liniami pionowymi zawierajacymi sie miedzy prostymi
    //przechodzacymi przez lewy/prawy wierzcholek trojkata
    
    //pierwsza polowa trojkata - od lewej do srodkowego punktu
    for (ix=xmin;ix<xavr;ix++){
	((xmin-xavr)!=0) ? (iyl=(int)((ix-xmin)*(ymin-yavr)/(xmin-xavr))+ymin) : (iyl=(int)((ix-xmin)*(ymin-yavr))+ymin);	//pierwsza prosta
	((xmin-xmax)!=0) ? (iyh=(int)((ix-xmin)*(ymin-ymax)/(xmin-xmax))+ymin) : (iyh=(int)((ix-xmin)*(ymin-ymax))+ymin);	//druga prosta
	cdr_vline(ix, iyh, iyl, R, G, B);											//rysujemy pionowe linie
    }
    //druga polowa trojkata - od srodka do prawej
    for (ix=xavr;ix<xmax;ix++){
	((xavr-xmax)!=0) ? (iyl=(int)((ix-xavr)*(yavr-ymax)/(xavr-xmax))+yavr) : (iyl=(int)((ix-xavr)*(yavr-ymax))+yavr);
	((xmin-xmax)!=0) ? (iyh=(int)((ix-xmin)*(ymin-ymax)/(xmin-xmax))+ymin) : (iyh=(int)((ix-xmin)*(ymin-ymax))+ymin);
	cdr_vline(ix, iyh, iyl, R, G, B);
    }    
}


// Rysujemy wypelniony i obrysowany trojkat
// najpierw rysujac trojkat wypelniony a nastepnie go obrysowujac

int cdr_bpolygon(int xa, int ya, int xb, int yb, int xc, int yc, int R, int G, int B){
    cdr_polygon(xa, ya, xb, yb, xc, yc, R, G, B);
    cdr_lineto(xa, ya, xc, yc, 1, G, B);
    cdr_lineto(xb, yb, xc, yc, 1, G, B);
    cdr_lineto(xa, ya, xb, yb, 1, G, B);
}


// Zamienia radiany na stopnie

float cdr_rad2deg(int x){
    return (x*180)/M_PI;
}


// Zamienia stopnie na radiany

float cdr_deg2rad(int x){
    return ((x*M_PI)/180);
}


// Oblicza modul z liczby calkowitej x

float cdr_module(float x){
    if (x<0)
	return x*(-1);
    else
	return x;
}


// Oblicza odleglosc dwoch punktow w przestrzeni dwuwymiarowej

float cdr_distance(float X1, float Y1, float X2, float Y2){
    return sqrt( pow(cdr_module(X1-X2),2) + pow(cdr_module(Y1-Y2),2) );
}


// Zamienia wspolrzedne ekranu na wspolrzedne wzgledem srodka ekranu (CDR_X0, CDR_Y0)

int cdr_toaxisi(int *x, int *y){
    *x=CDR_X0+*x;
    *y=CDR_Y0-*y;
}


// Skaluje o wielkosc d  wektor o poczatku (x1,y1) zaczepiony w punkcie (x0,y0) 
// Funkcja operuje bezposrednio na zmiennej poprzez wskaznik

int cdr_scale(float x0, float y0, float *x1, float *y1, float d){
    float xnew, ynew;
    xnew=d*(*x1-x0);
    ynew=d*(*y1-y0);
    *x1=xnew+x0;
    *y1=ynew+y0;
}


// Obraca o kat angle punkt (px1,py1) wzlgedem punktu (x0,y0)
// Funkcja operuje bezposrenio na pamieci poprzez wskaznik

int cdr_rotate(float *px1, float *py1, int x0, int y0, float angle){
    float xold, yold, xnew, ynew;
    
    xold=*px1;
    yold=*py1;
    xnew=( (xold-x0)*cos(cdr_deg2rad(angle))) - ( (yold-y0)*sin(cdr_deg2rad(angle)));
    ynew=( (xold-x0)*sin(cdr_deg2rad(angle))) + ( (yold-y0)*cos(cdr_deg2rad(angle)));
    *px1=xnew+x0;
    *py1=ynew+y0;
}


// Funkcja generuje wpolrzedne gwiazdy na podstawie wskazanej struktury star.
// Struktura musi zawierac conajmniej ilosc wierzcholkow (pomiedzy 2 a 9),
// oraz wspolrzedne srodka figury.
// Operuje bezposrednio na wskazanej strukturze

int cdr_star_generate(struct star_t *star){
    float x, y;
    int current_point;
    
    for (current_point=0;current_point<=(star->points);current_point++){
	x=(star->X0)+star->size;
	y=(star->Y0);
	cdr_rotate(&x, &y, star->X0, star->Y0, (360/(star->points))*current_point);
	star->Xo[current_point]=x;
	star->Yo[current_point]=y;
    }

    for (current_point=0;current_point<=(star->points);current_point++){
	x=(star->X0)+(star->size/2);
	y=(star->Y0);
	cdr_rotate(&x, &y, star->X0, star->Y0, (current_point*(360/(star->points)))+(180/(star->points)	) );
	star->Xi[current_point]=x;
	star->Yi[current_point]=y;
    }
}


// Rysuje siatke gwiazdy/wielokatu na podstaiwe wskazanej struktury

int cdr_star_draw(struct star_t *star){
    int current_point;
    for (current_point=0;current_point<=star->points;current_point++){
        if (current_point!=0) cdr_lineto(star->Xi[current_point], star->Yi[current_point], star->Xo[current_point-1], star->Yo[current_point-1], 1,0,0);
        if (current_point!=star->points) cdr_lineto(star->Xi[current_point], star->Yi[current_point], star->Xo[current_point+1], star->Yo[current_point+1], 1,0,0);
    }
}


// Rysuje wypelniona gwiazde

int cdr_star_draw_filled(struct star_t *star){
    int current_point;
    for (current_point=0;current_point<=star->points;current_point++){
	if (current_point!=0) cdr_polygon(star->X0, star->Y0, star->Xi[current_point], star->Yi[current_point], star->Xo[current_point-1], star->Yo[current_point-1], 0,0,0);
        if (current_point!=star->points) cdr_polygon(star->X0, star->Y0, star->Xi[current_point], star->Yi[current_point], star->Xo[current_point+1], star->Yo[current_point+1], 0,0,0);
    }
}

// Rysuje wypalniona i obrysowana gwiazde

int cdr_star_draw_fb(struct star_t *star){
    int current_point;
    for (current_point=0;current_point<=star->points;current_point++){
	if (current_point!=0) cdr_polygon(star->X0, star->Y0, star->Xi[current_point], star->Yi[current_point], star->Xo[current_point-1], star->Yo[current_point-1], 0,0,0);
        if (current_point!=star->points) cdr_polygon(star->X0, star->Y0, star->Xi[current_point], star->Yi[current_point], star->Xo[current_point+1], star->Yo[current_point+1], 0,0,0);
        if (current_point!=0) cdr_lineto(star->Xi[current_point], star->Yi[current_point], star->Xo[current_point-1], star->Yo[current_point-1], 1,0,0);
        if (current_point!=star->points) cdr_lineto(star->Xi[current_point], star->Yi[current_point], star->Xo[current_point+1], star->Yo[current_point+1], 1,0,0);
    }
}


// Obraca wiazde ze wskazywanej struktury <star> o kat <angle>

int cdr_star_rotate(struct star_t *star, int angle){
    int current_point;
    for (current_point=0;current_point<=(star->points);current_point++){
        cdr_rotate(&star->Xo[current_point], &star->Yo[current_point], star->X0, star->Y0, angle);
        cdr_rotate(&star->Xi[current_point], &star->Yi[current_point], star->X0, star->Y0, angle);	    
    }
}


// Przesuwa gwiazde o wektor (Xn,Yn)

int cdr_star_move(struct star_t *star, float Xn, float Yn){
    int current_point;

    star->X0+=Xn;
    star->Y0+=Yn;
    for (current_point=0;current_point<=(star->points);current_point++){
	star->Xi[current_point]+=Xn;
	star->Yi[current_point]+=Yn;
	star->Xo[current_point]+=Xn;
	star->Yo[current_point]+=Yn;
    }
}


// Skaluje gwiazde <star> o wielkosc rzeczywista <scale>

int cdr_star_scale(struct star_t *star, float scale){
    int current_point;
    for (current_point=0;current_point<=(star->points);current_point++){
	cdr_scale(star->X0, star->Y0, &star->Xi[current_point], &star->Yi[current_point], scale);
	cdr_scale(star->X0, star->Y0, &star->Xo[current_point], &star->Yo[current_point], scale);
    }
}


// Wypelnia tlo kolorem RGB / odpowiednim znakiem

int cdr_bg_fill(int R, int G, int B){
    int  x;
    for (x=0;x<=CDR_SCRWIDTH;x++)
	cdr_vline(x, 0, CDR_SCRHEIGHT, R,G,B);
}


// Przerysowuje caly ekran - kasuje zawartosc, wypelnia tlo, rysuje wielokat, obramowanie
// i napisy opisujace poszczegolne klawisze

int cdr_screen_redraw(struct star_t *star){
    cdr_clrscr();
    cdr_bg_fill(0,0,1);
    cdr_star_draw_fb(star);
    box(stdscr, ACS_VLINE, ACS_HLINE);
    mvwprintw(stdscr, 0, (CDR_X0-strlen(CDR_TXTTITLE)), "| %s |", CDR_TXTTITLE);
    mvwprintw(stdscr, CDR_SCRHEIGHT-1, 1, "| %s |", CDR_TXTKEYS);
    cdr_display_update();
}


// Wyswietla okienko dialogowe o tytule <title_text> z polem wpisowym
// operuje na pamiei poprzez wskaznik znakowy <text>.
// W okienko mozna wpisac maksymalnie <maxlen> znakow

int input_dialog(char title_text[], char *text, int maxlen) 
{
       WINDOW *w_input_dialog;
       w_input_dialog=newwin(3, 46, (CDR_Y0-2), (CDR_X0-23));
       box(w_input_dialog, ACS_VLINE, ACS_HLINE);
       mvwprintw(w_input_dialog, 0, 1, "| %s |", title_text);
       wrefresh(w_input_dialog);    
       beep();
       echo();
       mvwgetnstr(w_input_dialog, 1, 1, text, maxlen);	//use this in Linux/BSD
//       mvwgetstr(w_input_dialog, 1, 1, text);       	//use this line in SunOS
       noecho();
       touchwin(w_input_dialog);
       delwin(w_input_dialog);
       refresh();
}


// Rysuje katajacy trojkat na poczatku programu

int play_triangle(){
    float ix=1, iy=1, Xa, Ya, Xb, Yb, Xc, Yc, x;
    int x1=CDR_X0-5, y1=CDR_Y0-5, x2=CDR_X0-2, y2=CDR_Y0, x3=CDR_X0, y3=CDR_Y0-10;
    while (getch()!=' '){ 				//opuszczamy funkcje po nacisnieciu spacji
	x+=0.01;
	ix=sin(x)+1;					//sinus i kosinus jest wszedzie
	iy=cos(x)+1;
        cdr_clrscr();					//czysciemy ekran
	Xa=x1*ix-4;					//obliczamy wspolrzedne punktow A, B, C
	Ya=y1*ix;
	Xb=x2*ix+4;
	Yb=y2*iy;
	Xc=x3*iy-4;
	Yc=y3*ix;
        cdr_bpolygon(Xa, Ya, Xb, Yb, Xc, Yc, 0,0,0);	//rysujemy wypelniony i obrysowany trojkat
	cdr_text_center(1, "=========");		//wyipsujemy tytul programu
	cdr_text_center(2, "ROTOR");
	cdr_text_center(3, "=========");	
	cdr_text_center(CDR_SCRHEIGHT-1, "[Spacja]");	//i informacje o aktywnej spacji
	cdr_display_update();				//odswierzamy ekran
	usleep(CDR_DELAY);					//czekamy
    }
}





//*********************************************************************
//PROGRAM PROGRAM PROGRAM PROGRAM PROGRAM PROGRAM PGORAM PROGRAM
//*********************************************************************





int main(int argc){

    struct star_t star;		//deklarujemy stukture prechowujaca dane naszego wielokata
    int itemp;			//pomocnicza zmianna licbowa calkowita
    
    cdr_display_init();		//inicjujemy ekran (i biblioteke ncurses)
    cdr_clrscr();		//czyscimy ekran
    cdr_display_update();	//aktualizyujemy ekran
    play_triangle();		//wlaczamy animacje latajacego trojkata

    if (argc!=1) goto PROGRAM_GLOWNY;	//jesli podalismy jakikolwiek parametr - opuszczamy intro
    
    //**********
    // SCENA 1
    //**********
    
    cdr_clrscr();								//czyscimy ekran
    cdr_display_update();							//odswierzamy ekran
    cdr_putpixel(CDR_X0, CDR_Y0, 1,0,0);					//rysujemy pixel na srodku ekranu
    cdr_text_center(CDR_Y0-5, "WITAJ!");					//piszemy tekst
    cdr_text_center(CDR_Y0-3, "JESTEM PIXLEM. LUDZIE WYKORZYSTUJA MNIE");
    cdr_update_sb(2);								//odswierzamy ekran pikajac co sekunde
    cdr_text_center(CDR_Y0-2, "DO RYSOWANIA");
    cdr_update_sb(2);

    cdr_text_center(CDR_SCRHEIGHT-5, "CHCIALBYM CI POKAZAC KILA SZTUCZEK");
    cdr_waitforspace();								//zatrzymujemy odtwarzanie czekajac na nacisniecie <spacji>
    

    //**********
    // SCENA 2
    //**********

    cdr_clrscr();
    cdr_text_center(2, "LUBIE RYSOWAC LINIE");
    cdr_update_sb(1);
    cdr_lineto(5, 5, CDR_SCRWIDTH-5, CDR_SCRHEIGHT-5, 1,0,0);			//rysujemy 6 linii ktore beda wygladaly jak koperta
    cdr_update_sb(1);
    cdr_lineto(CDR_SCRWIDTH-5, 5, 5, CDR_SCRHEIGHT-5, 1,0,0);
    cdr_update_sb(1);
    cdr_lineto(5, 5, CDR_SCRWIDTH-5, 5, 1,0,0);
    cdr_update_sb(1);
    cdr_lineto(CDR_SCRWIDTH-5, 5, CDR_SCRWIDTH-5, CDR_SCRHEIGHT-5, 1,0,0);
    cdr_update_sb(1);
    cdr_lineto(5, 5, 5, CDR_SCRHEIGHT-5, 1,0,0);
    cdr_update_sb(1);
    cdr_lineto(5, CDR_SCRHEIGHT-5, CDR_SCRWIDTH-5, CDR_SCRHEIGHT-5,  1,0,0);
    cdr_update_sb(1);
    cdr_waitforspace();


    //**********
    // SCENA 3
    //**********
    
    float x=CDR_X0+10, y=CDR_Y0-2;					//deklarujemy wspolrzedne punktu
    while(getch()!=' '){						//petla z ktorej wychodzi nacisniecie <spacji>
	cdr_clrscr();							//czyscimy ekran			
	cdr_text_center(2, "ALBO BIEGAC DOOKOLA WLASNEGO OGONA");	//piszemy jakis tekst
        cdr_text_center(CDR_SCRHEIGHT-1, "[spacja]");
	cdr_rotate(&x, &y, CDR_X0, CDR_Y0, 5);				//obracamy wspolrzedne punktu (x, y) o kat 5 stopni
	cdr_putpixel(x, y, 1, 0, 0);					//rysujemy pixel w nowym miejscu
	cdr_display_update();						//odswierzamy ekran
	usleep(CDR_DELAY);						//opoznienie
    }


    //***********
    // SCENA 4
    //***********

    //tutaj nic nowego sie nie dzieje, znowu jakis tekst...
    cdr_clrscr();
    cdr_text_center(CDR_Y0-2, "PONIEWAZ OSTATNIO ZADKO MOGE ZROBIC COS FAJNEGO");
    cdr_update_sb(3);
    cdr_text_center(CDR_Y0, "POSTANOWILEM WYKORZYSTAC OKAZJE");
    cdr_update_sb(3);
    cdr_text_center(CDR_Y0+2, "I NAPISALEM COS TAKEIGO...");
    cdr_update_sb(3);


    //***********
    // SCENA 5
    //***********

    int point, points;		//zmienne przechowujaca nuerm aktualnego wierzcholka i ilosc wierzcholkow
    star.X0=CDR_X0;		//ustalamy wpolrzedna X srodka  gwiazdy na srodek ekranu
    star.Y0=CDR_Y0;		//ustalamy swpolrzedna Y srodka gwiazdy na srodek ekranu
    star.size=100;		//wielkosc gwiazdy (100 - bardzi duza)
    star.points=2;		//ilosc ramion
    x=CDR_X0+5; y=CDR_Y0;	//ustalamy wartosc zmiennyc x i y
    star.fill=PIX_WHITE;	//ustalamy znak wypelnienia figury
    star.border=PIX_BORDER;	//ustalamy znak obrysowania figury
    star.bg=PIX_BG;

    cdr_clrscr();		//czyscimy ekran

    //rysujemy animowane gwiazdy
    //zwiekszajac ilosc ramion od 2 do stalej CDR_MAXPOINTS

    for (points=2; points<CDR_MAXPOINTS;points++){					//zwiekszamy ilosc ramion rysowanych gwiazd od 2 do 9
	star.points=points;								//ustalamy ilosc ramion w strukturze
        cdr_star_generate(&star);							//generujemy zadana gwiazde
	beep();										//pikamy dwukrotnie
	usleep(CDR_DELAY*8);								//z krotka przerwa
	beep();


        while( cdr_distance(star.Xo[0], star.Yo[0], star.X0, star.Y0)>CDR_MINSIZE){	//petla 1 - najpierw zmniejszamy figure
    	    cdr_clrscr();								//czyscimy ekran
	    cdr_star_draw_filled(&star);						//rysujemy wypelniana gwiazde
	    cdr_star_rotate(&star, 5);							//przekrecamy gwiazde o 5 stopni
	    cdr_star_scale(&star, 0.97);						//zmniejszamy gwiazde
	    cdr_display_update();							//odswierzamy ekran
    	    usleep(CDR_DELAY);								//opoznienie
	 }
	beep();										//figura zmniejszona - pikamy! ;)
	
	while( cdr_distance(star.Xo[0], star.Yo[0], star.X0, star.Y0)<CDR_MAXSIZE){	//petla 2 - zwiekszamy figure
	    cdr_clrscr();								//czyscimy ekran
	    cdr_star_draw_filled(&star);						//rysujemy wypelniana gwiazde
	    cdr_star_rotate(&star, 5);							//przekrecamy ja o 5 stopni
	    cdr_star_scale(&star, 1.2);							//zwiekszamy gwiazde
    	    cdr_display_update();							//odsiwerzamy ekran
    	    usleep(CDR_DELAY);								//opoznienie
	}
    }


    //***********
    // SCENA 6
    //***********

    //ladnie czyscimy ekran
    cdr_screen_wipe();

    //teksci i opoznienie
    cdr_text_center(CDR_Y0, "PENTAGRAM POWERS!");
    cdr_update_sb(4);


    //***********
    // SCENA 7
    //***********

    star.points=5;									//pentagram ma 5 ramion
    star.size=15;									//rozmiar 15 (wejdzie na ekran)
    cdr_star_generate(&star);								//generujemy gwiazde
    while( cdr_distance(star.Xo[0], star.Yo[0], star.X0, star.Y0)>(CDR_MINSIZE-5)){	//petla - zmniejszamy gwiazde
        cdr_clrscr();									//czyscimy ekran
	cdr_star_draw(&star);								//rysujemy gwiazde
	cdr_star_rotate(&star, -5);							//przekrecamy ja o 5 stopni w lewo
	cdr_star_scale(&star, 0.995);							//i powoli zmniejszamy
    	cdr_display_update();								//odswierzamy ekran
    	usleep(CDR_DELAY);								//opoznienie
    }
    beep();										//gwiazde zmniejszona - pikamy!

    while( cdr_distance(star.Xo[0], star.Yo[0], star.X0, star.Y0)<CDR_MAXSIZE-10){	//kolejna petla - zwiekszamy znacznie gwiazde
        cdr_clrscr();
	cdr_star_draw_fb(&star);
	cdr_star_rotate(&star, 5);							//krecimy gwiazde w prawo
	cdr_star_scale(&star, 1.05);
    	cdr_display_update();
    	usleep(CDR_DELAY);
    }


    //***********
    // SCENA 8
    //***********

    cdr_screen_wipe();

    cdr_text_center(CDR_Y0, "ZA SLABE?");
    cdr_update_sb(4);


    //***********
    // SCENA 9
    //***********

    int timer1=400, timer2, current_point;	//tutaj bedziemy liczyc czas calkowity sceny (timer1) i poszczegolnych scen (timer2)
    star.points=5;				//chcemy petagram
    star.size=10;				//o rozmiarze 10
    cdr_star_generate(&star);			//generujemy gwiazde
    while (timer1>0){														//duza petla	
	beep();
	for (timer2=0;timer2<=50;timer2++){											//mniejsza petla
	    cdr_clrscr();													//czyscimy ekran
    	    cdr_star_draw(&star);												//rysujemy gwiazde
	    cdr_star_rotate(&star, -5);												//przekrecamy ja w leo p 5 stopni
	    for (current_point=0;current_point<=star.points;current_point++){							//efekt wybuchowy gwiazdy
		cdr_scale(star.X0, star.Y0, &star.Xi[current_point], &star.Yi[current_point], (1.0101+0.2*cos(timer2/2)) );	//wierzcholki wewnetrzne sie powiekszaja wg cosinusa
		cdr_scale(star.X0, star.Y0, &star.Xo[current_point], &star.Yo[current_point], (1.0101+0.2*sin(timer2/2)) );	//a wierzcholki zewnetrzne zmniejszaja
	    }
    	    cdr_display_update();		//odswierzamy ekran
    	    usleep(CDR_DELAY);			//opoznienie
	    timer1--;				//zmenijszamy timer1 - czas uplywa...
        }
	beep();					//koniec pierwszego efektu - pikamy!

	for (timer2=0;timer2<=50;timer2++){											//druga mniejsza petla
            cdr_clrscr();
	    cdr_star_draw_fb(&star);												//rysujemy gwiazdw wypelniana i obrysowana
	    cdr_star_rotate(&star, 2);												//obracamy ja o 2 stopnie w prawo
	    for (current_point=0;current_point<=star.points;current_point++){ 							//efekt 2 - szybki morphing
		cdr_scale(star.X0, star.Y0, &star.Xo[current_point], &star.Yo[current_point], (1.01+0.2*cos(timer2/2)));
		cdr_scale(star.X0, star.Y0, &star.Xi[current_point], &star.Yi[current_point], (1.01+0.2*sin(timer2/2)) );
	    }
    	    cdr_display_update();		//odswierzamy ekran
    	    usleep(CDR_DELAY);			//opoznienie
	    timer1--;				//a czas wciaz leci
	}
	beep();					//pikamy
    }


    //**********
    // SCENA 10
    //**********

    beep();										//koniec morphingu jednego i drugiego - pikamy
    while( cdr_distance(star.Xo[0], star.Yo[0], star.X0, star.Y0)<CDR_MAXSIZE-20){	// i ladnie wychodzimy z ujecia
        cdr_clrscr();
	cdr_star_draw_fb(&star);
	cdr_star_rotate(&star, 3);							//obracajac gwiazde
	cdr_star_scale(&star, 1.05);							//i powiekszajac az azpelni caly ekran
    	cdr_display_update();
    	usleep(CDR_DELAY);
    }


    //***********
    // SCENA 11
    //***********

    cdr_screen_wipe();
    cdr_text_center(CDR_Y0, "STEROWANIE RECZNE!");
    cdr_update_sb(4);
    

    //***********
    //SCENA 12
    //***********

PROGRAM_GLOWNY:

    //tutaj zaczyna sie petla pozwalajaca uzytkownikowi kontrolowac ruchy bryly

    star.X0=CDR_X0;			//ustalamy wspolrzedne X srodka gwiazdy
    star.Y0=CDR_Y0;			//ustalamy wspolrzedna Y srodka gwiazdy
    star.size=10;			//ustalamy wielkosc gdwiazdy
    star.points=5;			//i ilosc ramion
    cdr_star_generate(&star);		//generujemy gwiazde
    cdr_screen_redraw(&star);		//przerysowujemy ekran programu, wrac z tlem, ramka, tytulem i klawiszologia

    int button;									//zmienna przechowujaca numer wcisnietego klawisza klawiatury
    char input[5];								//tablica znakow przwchowujaca tekst wpisany w okno dialogowe
    while(button=getch()){
	if (button=='q')							//jesli nacisnieto Q - konczymy program
	    break;
	else if (button==46){							//nacisnieto '.' - obracamy figure o jeden stopien w prawo
	    cdr_star_rotate(&star, 1);
	    cdr_screen_redraw(&star);
	} else if (button==44){							//nacisnieto ',' - obracamy figure o jeden stopien w lewo
	    cdr_star_rotate(&star, -1);
	    cdr_screen_redraw(&star);
	} else if (button==62){							//nacisnieto '>' (Shift+.) - obracamy figure o dzisiec stopni w prawo
	    cdr_star_rotate(&star, 10);
	    cdr_screen_redraw(&star);
	} else if (button==60){							//nacisnieto '<' (Shift+,) - obracamy figure o dzisiec stopni w lewo
	    cdr_star_rotate(&star, -10);
	    cdr_screen_redraw(&star);
	} else if (button==KEY_LEFT){						//nacisnieto kursor <- - przesuwamy figure o jeden pixel w lewo
	    cdr_star_move(&star, -1, 0);
	    cdr_screen_redraw(&star);
	} else if (button==KEY_RIGHT){						//nacisnieto kursor -> - przesuwamy figure o jeden pixel w prawo
	    cdr_star_move(&star, 1, 0);
	    cdr_screen_redraw(&star);
	} else if (button==KEY_UP){						//nacisnieto kursor "do gory" - przesuwamy figure o jeden pixel do gory
	    cdr_star_move(&star, 0, -1);
	    cdr_screen_redraw(&star);
	} else if (button==KEY_DOWN){						//nacisnieto kursor "w dol" - przesuwamy figure o jeden pixel w dol
	    cdr_star_move(&star, 0, 1);
	    cdr_screen_redraw(&star);
	} else if (button==43){							//nacisnieto + - zwiekszamy figure
	    cdr_star_scale(&star, 1.1);
	    cdr_screen_redraw(&star);
	} else if (button==45){							//nacisnieto - - zmniejszamyy figure
	    cdr_star_scale(&star, 0.9);
	    cdr_screen_redraw(&star);
	} else if (button==13){							//nacisnieto <enter> - wyswietlamy pole diagogowe z prosba o podanie katu obrotu
	    input_dialog("Podaj kat w stopniach", input, 4);			//wyswietlamy okienko dialogowe
	    itemp=atoi(input);							//zamianiamy wprowadzony tekst na liczbe
	    if (itemp!=0)							//sprawdzamy czy wprowadzono poprawna liczbe
		cdr_star_rotate(&star, itemp);					//jesli tak, obracamy figure o zadany kat
	    else beep();							//jesli nie, pikamy
    	    cdr_screen_redraw(&star);						// przerysowujemy ekran	    
	} else if (button=='b'){						//wcisnieto B - wysiwetlamy okno dialogowe w ktore moze wprowadzic znak
	    input_dialog("Podaj znak wypelnienia brzegu", input, 1);		//ktorym bedzie obrysowana figura
	    PIX_BORDER=*input;
	    cdr_screen_redraw(&star);
	} else if (button=='w'){						//wcisnieto W - wyswietlamy okno dialogowe w ktore mozna wporwadzic znak
	    input_dialog("Podaj znak wypelnienia figury", input, 1);		//ktorym figura bedzie wypelniona
	    PIX_WHITE=*input;
	    cdr_screen_redraw(&star);
	} else if (button=='t'){						//wcisnieto T - wysiwetlamy okno dialogowe w ktore nalezy wprowadzic znak wypelnienia tla
	    input_dialog("Podaj znak wypelnienia tla", input, 1);
	    PIX_BG=*input;
	    cdr_screen_redraw(&star);
	} else if (button==' '){						//wcisnieto spacje - pokazujemy okno dialogowe w ktore nalezy wprowadzic zadana
	    input_dialog("Podaj liczbe wierzcholkow (2-9)", input, 2);		//liczbe wierzcholkow nowej figury
	    itemp=atoi(input);							//zamieniamy liczbe tekst na liczbe
	    if ((itemp>=2) && (itemp<=9)){					//uaktualniamy strukture gwiazdy
		star.points=itemp;						
		cdr_star_generate(&star);					//generujemy nowa gwiazde
	    } else beep();							//jesli nie wprowadzono lasciwej liczby - pikamy ostrzegawczo
    	    cdr_screen_redraw(&star);						//przerysowujemy ekran	    
	}
    }


    //**********
    // SCENA 13
    //**********

    //koncowa scena - informacje o autorze
    cdr_clrscr();
    cdr_text_center(CDR_Y0, "CeDeROM of KSZAK");
    cdr_text_center(CDR_Y0+1, "AC01122003");
    cdr_update_sb(4);
    
    
    //zamykamy biblioteke ncurses i wyswietlacz
    cdr_display_close();

    //poprawnie konczymy program
    exit(0);
}
