#include <allegro.h>
#include <string>
#include <fstream>
using namespace std;
//wymiary
const int WX = 640, WY = 480, SKALA = 8;
/////////////////////////
volatile long speed = 0;
void increment_speed()
{
speed++;
}
END_OF_FUNCTION(increment_speed);
LOCK_VARIABLE(speed);
LOCK_FUNCTION(increment_speed);
/////////////////////////
volatile int close_button_pressed = FALSE;
void close_button_handler(void)
{
close_button_pressed = TRUE;
}
END_OF_FUNCTION(close_button_handler)
//////////////////////////
int mx=0,my=0,mb=0;
void myszka();
void init();
void bounds(short unsigned int baza[WX/SKALA][WY/SKALA], int & maxX, int & minX, int & maxY, int & minY);
void zapis(short unsigned int baza[WX/SKALA][WY/SKALA], string, int minX, int maxX, int minY, int maxY, int, int);
void odczyt(short unsigned int baza[WX/SKALA][WY/SKALA], string nazwa, int, int);
/////////////////////////////////////////////////////////
int main()
{
allegro_init();
init();
srand(10);
BITMAP *bufor = NULL;
short unsigned int baza[WX/SKALA][WY/SKALA];
//czyszczenie
for(int x=0; x<WX/SKALA; x++) for(int y=0; y<WY/SKALA; y++) {baza[x][y] = 0;}
bool zapisywanie = false;
bool odczytywanie = false;
int licznik_klikniecia = 0, licznik_klawisza = 0;
int limit_klikniecia = 5, limit_klawisza = 15;
int centerX = WX/2, centerY = WY/2;
int maxX = 0, minX = WX/SKALA, maxY = 0, minY = WY/SKALA;
string edittext; // an empty string for editting
string::iterator iter = edittext.begin(); // string iterator
int caret = 0; // tracks the text caret
bufor = create_bitmap(WX,WY);
/////// glowna petla
while ( !close_button_pressed )
{
clear_to_color(bufor, makecol(200,200,200));
myszka();
if(licznik_klikniecia < limit_klikniecia){licznik_klikniecia++;}
if(licznik_klawisza < limit_klawisza){licznik_klawisza++;}
if( ! zapisywanie && ! odczytywanie)
{
if( key[KEY_S] && licznik_klawisza ) //zapisywanie
{
zapisywanie = true;
licznik_klawisza=0;
clear_keybuf();
}
if( key[KEY_O] && licznik_klawisza ) //odczytywanie
{
odczytywanie = true;
licznik_klawisza=0;
clear_keybuf();
}
if( key[KEY_Q] && licznik_klawisza) //kasowanie
{
for(int x=0; x<WX/SKALA; x++) for(int y=0; y<WY/SKALA; y++) {baza[x][y] = 0;}
licznik_klawisza=0;
}
if( key[KEY_B] && licznik_klawisza) //granice
{
bounds(baza, maxX, minX, maxY, minY);
licznik_klawisza=0;
}
if(mb == 1 && licznik_klikniecia == limit_klikniecia) //rysowanie
{
licznik_klikniecia = 0;
baza[mx/SKALA][my/SKALA] = 1;
}
if(mb == 2 && licznik_klikniecia == limit_klikniecia) //usuwanie
{
licznik_klikniecia = 0;
baza[mx/SKALA][my/SKALA] = 0;
}
if( key[KEY_C] && licznik_klawisza ) //centrowanie
{
centerX = mx, centerY = my;
licznik_klawisza=0;
}
if( key[KEY_V] && licznik_klawisza ) //centrowanie
{
centerX = (maxX + minX)*SKALA/2, centerY = (maxY + minY)*SKALA/2;
licznik_klawisza=0;
}
}
else
{
if( zapisywanie || odczytywanie)
{
while(keypressed())
{
int newkey = readkey();
char ASCII = newkey & 0xff;
char scancode = newkey >> 8;
// a character key was pressed; add it to the string
if(ASCII >= 32 && ASCII <= 126)
{
// add the new char, inserting or replacing as need be
iter = edittext.insert(iter, ASCII);
// increment both the caret and the iterator
caret++;
iter++;
}
// some other, "special" key was pressed; handle it here
else
switch(scancode)
{
case KEY_DEL:
if(iter != edittext.end()) iter = edittext.erase(iter);
break;
case KEY_BACKSPACE:
if(iter != edittext.begin())
{
caret--;
iter--;
iter = edittext.erase(iter);
}
break;
case KEY_RIGHT:
if(iter != edittext.end()) caret++, iter++;
break;
case KEY_LEFT:
if(iter != edittext.begin()) caret--, iter--;
break;
case KEY_ESC:
zapisywanie = false;
odczytywanie = false;
licznik_klawisza=0;
break;
case KEY_ENTER:
if( zapisywanie )
{
zapisywanie = false;
bounds(baza, maxX, minX, maxY, minY);
zapis(baza, edittext, minX, maxX, minY, maxY, centerX, centerY);
}
if( odczytywanie )
{
odczytywanie = false;
odczyt(baza, edittext, centerX, centerY);
bounds(baza, maxX, minX, maxY, minY);
}
licznik_klawisza=0;
break;
default:
break;
}
}
}
}
//prowadnice
//center
rectfill( bufor, centerX - centerX%SKALA, 0, centerX + SKALA - centerX%SKALA, WY, makecol(190,190,250) ); //pion
rectfill( bufor, 0, centerY - centerY%SKALA, WX, centerY + SKALA - centerY%SKALA, makecol(190,190,250) ); //poziom
//kursor
rectfill( bufor, mx - mx%SKALA, 0, mx + SKALA - mx%SKALA, WY, makecol(150,150,150) ); //pion
rectfill( bufor, 0, my - my%SKALA, WX, my + SKALA - my%SKALA, makecol(150,150,150) ); //poziom
//pozioma siatka
for(int y=0; y<WY/SKALA; y++)
{ hline(bufor, 0, y*SKALA, WX, makecol(150,150,150) );
if( ! ((y - centerY/SKALA)%5) )
textprintf_ex(bufor,font,1,y*SKALA,makecol(0,0,0),-1, "%d", y - centerY/SKALA);
//granice
hline(bufor, 0, minY*SKALA, WX, makecol(250,150,50) );
hline(bufor, 0, (maxY+1)*SKALA, WX, makecol(250,150,50) );
}
//pionowa siatka
for(int x=0; x<WX/SKALA; x++)
{ vline(bufor, x*SKALA, 0, WY, makecol(150,150,150) );
if( ( ! ((x - centerX/SKALA)%5)) && (x))
textprintf_ex(bufor,font,x*SKALA,1,makecol(0,0,0),-1, "%d", x - centerX/SKALA);
//granice
vline(bufor, minX*SKALA, 0, WY, makecol(250,150,50) );
vline(bufor, (maxX+1)*SKALA, 0, WY, makecol(250,150,50) );
}
//rysowanie punktow
for(int x=0; x<WX/SKALA; x++)
{
for(int y=0; y<WY/SKALA; y++)
{
if(baza[x][y]){rectfill(bufor, SKALA*x, SKALA*y, SKALA*(x+1), SKALA*(y+1), makecol(150,0,0));}
}
}
textprintf_ex(bufor,font,40,20,makecol(50,50,50),-1, "Q reset; C ustaw centrum; B oblicz granice; V oblicz centrum");
textprintf_ex(bufor,font,40,40,makecol(50,50,50),-1, "S zapisz, O otworz");
textprintf_ex(bufor,font,mx+5,my-10,makecol(50,50,50),-1, "x:%d y:%d", mx/SKALA - centerX/SKALA, my/SKALA - centerY/SKALA);
if ( zapisywanie || odczytywanie)
{
rectfill(bufor, 10, 10, WX-10, 30, makecol(255,255,255));
textprintf_ex(bufor,font,20,20,makecol(50,50,50),-1, "%s", edittext.c_str() );
}
blit(bufor,screen,0,0,0,0,WX,WY);
}
///////////
destroy_bitmap(bufor);
allegro_exit();
return 0;
}
END_OF_MAIN()
/////////////////////////////////////////////////////////
void myszka()
{
if( mx != mouse_x || my != mouse_y || mb != mouse_b)
{
mx = mouse_x;
my = mouse_y;
mb = mouse_b;
}
};
void init()
{
LOCK_FUNCTION(close_button_handler);
set_close_button_callback(close_button_handler);
install_keyboard();
set_color_depth(16);
set_gfx_mode(GFX_AUTODETECT_WINDOWED,WX,WY,0,0);
install_mouse();
set_mouse_speed(5,5);
show_mouse(screen);
unscare_mouse();
install_timer();
install_int_ex(increment_speed, BPS_TO_TIMER(200));
}
//////////////////////////////
void bounds(short unsigned int baza[WX/SKALA][WY/SKALA], int & maxX, int & minX, int & maxY, int & minY)
{
maxX = 0, minX = WX/SKALA, maxY = 0, minY = WY/SKALA;
for(int x=0; x<WX/SKALA; x++)
{
for(int y=0; y<WY/SKALA; y++)
{
if( baza[x][y] )
{
if( x < minX ){minX = x;}
if( x > maxX ){maxX = x;}
if( y < minY ){minY = y;}
if( y > maxY ){maxY = y;}
}
}
}
}
/////
void zapis( short unsigned int baza[WX/SKALA][WY/SKALA], string nazwa, int minX, int maxX, int minY, int maxY, int centerX, int centerY )
{
string nazwapliku = nazwa + ".ogl";
ofstream plik( nazwapliku.c_str(), ios::out );
int ilosc=0, i=0;
for(int x=minX; x<=maxX; x++)
{
for(int y=minY; y<=maxY; y++)
{
if( baza[x][y] )
{
ilosc+=2;
}
}
}
plik << ilosc << "\n";
for(int x=minX; x<=maxX; x++)
{
for(int y=minY; y<=maxY; y++)
{
if( baza[x][y] )
{
plik << x - centerX/SKALA << "\n" << y - centerY/SKALA << "\n";
}
}
}
}
/////
void odczyt(short unsigned int baza[WX/SKALA][WY/SKALA], string nazwa, int centerX, int centerY )
{
string nazwapliku = nazwa + ".ogl";
ifstream plik(nazwapliku.c_str());
int x,y, ilosc;
if( plik.good() )
{
plik >> ilosc;
while( ! plik.eof() )
{
plik >> x >> y;
baza[centerX/SKALA+x][centerY/SKALA+y] = 1;
}
}
}