/**************/ /* nappula2.c */ /****************************************************************************/ /* ** Aliohjelmakirjasto nappuloiden ja laskureiden piirt„miseksi n„yt”lle. ** ** Kutsuvassa ohjelmassa m„„ritell„„n taulukko n„pp„imist„ ja ** taulukko laskureista. ** ** N„pp„imen painamista joko n„pp„imist”lt„ tai hiirelt„ odotetaan ** aliohjelmalla 'lue_komento'. Aliohjelma palauttaa valittua ** komentoa vastaavan tunnuksen. Tunnukset on m„„ritelty ** k„ytt„j„n ohjelmassa. Negatiiviset tunnukset on varattu ** systeemik„ytt””n ja k„ytt„j„n ohjelman on reagoitava my”s niihin. ** Esim. mik„li palautetaan komento PIIRRA, pit„„ k„ytt„j„n piirt„„ ** koko n„ytt” uudelleen (koska joku on sen sotkenut). ** ** Nappulan tai laskurin vasenpaan yl„kulmaan tarttumalla voidaan ** laatikon paikkaa n„yt”ll„ siirt„„. ** Oikeasta alakulmasta voidaan laatikon kokoa muuttaa. */ /****************************************************************************/ #include #include #include #include #include #include "hiiru.h" #include "nappula2.h" /****************************************************************************/ #define SKAALAA_XY \ x = (int)(((long int)x - MIN_H_X) * ( MAX_X - MIN_X + 1) /\ ( MAX_H_X - MIN_H_X +1 ) + MIN_X);\ y = (int)(((long int)y - MIN_H_Y) * ( MAX_Y - MIN_Y + 1) /\ ( MAX_H_Y - MIN_H_Y +1 ) + MIN_Y); /****************************************************************************/ /* Globaali muuttuja hiiren olemassaololle: */ static int HIIRI = 0; typedef struct { int lev; int kork; int *tavara; } varasto_tyyppi; static HIIRI_NAKYVISSA = 0; /****************************************************************************/ void nayta_hiiri(void) { if ( !HIIRI || HIIRI_NAKYVISSA ) return; naytahiirikursori(); HIIRI_NAKYVISSA = 1; } /****************************************************************************/ void katke_hiiri(void) { if ( !HIIRI || !HIIRI_NAKYVISSA ) return; katkehiirikursori(); HIIRI_NAKYVISSA = 0; } /****************************************************************************/ varasto_tyyppi /* NULL jollei tilaa saada */ *varaa_tila( /* Osoitin saatuun tilaan */ laatikko_tyyppi *tila ) { varasto_tyyppi *p; p = malloc(sizeof(varasto_tyyppi)); if ( !p ) return NULL; p->lev = tila->koko.x + 2; p->kork = tila->koko.y + 2; p->tavara = malloc( 2 * p->lev * p->kork ); if ( !p->tavara ) { free(p); return NULL; } return p; } /****************************************************************************/ void /* */ vapauta_tila( /* */ varasto_tyyppi *p ) { if ( !p ) return; free(p->tavara); free(p); } /****************************************************************************/ void /* */ lue_tila( /* */ varasto_tyyppi *p, int x, int y ) { if ( !p ) return; if ( HIIRI_NAKYVISSA ) katkehiirikursori(); gettext(x,y,x+p->lev-1,y+p->kork-1,p->tavara); if ( HIIRI_NAKYVISSA ) naytahiirikursori(); } /****************************************************************************/ void /* */ piirra_tila( /* */ varasto_tyyppi *p, int x, int y ) { if ( !p ) return; if ( HIIRI_NAKYVISSA ) katkehiirikursori(); puttext(x,y,x+p->lev-1,y+p->kork-1,p->tavara); if ( HIIRI_NAKYVISSA ) naytahiirikursori(); } /****************************************************************************/ int /* -1 n„ytt”„ ei tarvitse p„iv. */ siirra_laatikkoa( /* PIIRRA jos n„ytt” t„ytyy korjata */ laatikko_tyyppi *tila /* Laatikon ala jota siirret„„n. */ ) { int ax,ay,ex,ey,x,y,nap1,nap2; varasto_tyyppi *jemma,*nap; ax = tila->vasen_yla.x - 1; ay = tila->vasen_yla.y - 1; ex = ax; ey = ay; jemma = varaa_tila(tila); if ( !jemma ) goto pois; nap = varaa_tila(tila); if ( !nap ) goto pois; katke_hiiri(); lue_tila(nap,ax,ay); lue_tila(jemma,ax,ay); nayta_hiiri(); do { hiirentila(&x,&y,&nap1,&nap2); SKAALAA_XY; if ( ex != x || ey != y ) { katke_hiiri(); piirra_tila(jemma,ex,ey); lue_tila(jemma,x,y); piirra_tila(nap,x,y); nayta_hiiri(); ex = x; ey = y; } } while ( nap1 ); pois: vapauta_tila(nap); vapauta_tila(jemma); tila->vasen_yla.x = ex + 1; tila->vasen_yla.y = ey + 1; if ( ax != ex || ay != ey ) return PIIRRA; return -1; } /****************************************************************************/ int /* -1 n„ytt”„ ei tarvitse p„iv. */ muuta_laatikkoa( /* PIIRRA jos n„ytt” t„ytyy korjata */ laatikko_tyyppi *tila /* Laatikon ala jota siirret„„n. */ ) { int lx,ly,ax,ay,ex,ey,x,y,nap1,nap2; int lev,kork; varasto_tyyppi *jemma; ax = tila->vasen_yla.x - 1; ay = tila->vasen_yla.y - 1; lev = tila->koko.x; kork = tila->koko.y; lx = ex = ax + lev + 1; ly = ey = ay + kork + 1; katke_hiiri(); jemma = varaa_tila(tila); lue_tila(jemma,ax,ay); nayta_hiiri(); do { hiirentila(&x,&y,&nap1,&nap2); SKAALAA_XY; if ( ex != x || ey != y ) { katke_hiiri(); piirra_tila(jemma,ax,ay); vapauta_tila(jemma); tila->koko.x = max(1,x-ax-1); tila->koko.y = max(1,y-ay-1); jemma = varaa_tila(tila); lue_tila(jemma,ax,ay); piirra_laatikko(tila,1); nayta_hiiri(); ex = x; ey = y; } } while ( nap1 ); pois: katke_hiiri(); piirra_tila(jemma,ax,ay); vapauta_tila(jemma); nayta_hiiri(); if ( lx != ex || ly != ay ) return PIIRRA; return -1; } /****************************************************************************/ int /* 0 koord. ei kulmassa */ siirtokulmassa( /* 1 koord on kulmassa */ laatikko_tyyppi *tila, int x, int y ) { if ( ( tila->vasen_yla.x - 1 == x ) && ( tila->vasen_yla.y - 1 == y ) )return 1; return 0; } /****************************************************************************/ int /* 0 koord. ei kulmassa */ muutoskulmassa( /* 1 koord on kulmassa */ laatikko_tyyppi *tila, int x, int y ) { if ( ( tila->vasen_yla.x + tila->koko.x == x ) && ( tila->vasen_yla.y + tila->koko.y == y ) )return 1; return 0; } /****************************************************************************/ int /* 0 koord. ei laatikossa */ laatikossa( /* 1 koord on laatikossa */ laatikko_tyyppi *tila, int x, int y ) { if ( tila->vasen_yla.x > x ) return 0; if ( tila->vasen_yla.y > y ) return 0; if ( tila->vasen_yla.x + tila->koko.x <= x ) return 0; if ( tila->vasen_yla.y + tila->koko.y <= y ) return 0; return 1; } /****************************************************************************/ int /* -1 jollei hiiri mink„„n napin koh */ tutki_hiiri( /* napin numero, jonka kohdalla hiiri*/ nappain_tyyppi *nappaimet, laskuri_tyyppi *laskurit ) { int i,nappi1,nappi2,montako,x,y,dx,dy; if ( laskurit ); /* H„m„yst„, jottei k„„nt„j„ valita */ if ( !HIIRI ) return -1; hiirenpainallukset(0,&nappi1,&nappi2,&montako,&x,&y); SKAALAA_XY; if ( !montako ) return -1; do { /* Koska napp1 ei muuten ole p„„ll„ seur. keralla ??? */ hiirentila(&dx,&dy,&nappi1,&nappi2); } while (!nappi1); for (i=0; nappaimet[i].valinta_kirjain; i++) { if ( laatikossa(&nappaimet[i].nappain,x,y) ) return i; if ( siirtokulmassa(&nappaimet[i].nappain,x,y) ) { piirra_nappula(&nappaimet[i]); return siirra_laatikkoa(&nappaimet[i].nappain); } if ( muutoskulmassa(&nappaimet[i].nappain,x,y) ) { piirra_nappula(&nappaimet[i]); return muuta_laatikkoa(&nappaimet[i].nappain); } } for (i=0; laskurit[i].tunnus; i++) { if ( siirtokulmassa(&laskurit[i].tila,x,y) ) { piirra_laskuri(&laskurit[i]); return siirra_laatikkoa(&laskurit[i].tila); } if ( muutoskulmassa(&laskurit[i].tila,x,y) ) { piirra_laskuri(&laskurit[i]); return muuta_laatikkoa(&laskurit[i].tila); } } return -1; } /****************************************************************************/ int lue_komento( /* */ nappain_tyyppi *nappaimet, laskuri_tyyppi *laskurit, int *lisa ) /* ** Funktio palauttaa valitun komennon tunnuksen ja mahdollisen lis„viestin. ** Funktiosta palataan vasta kun oikeata n„pp„int„ on painettu. ** Mik„li n„pp„int„ ei ole painettu, tutkitaan onko hiirikursori jonkin ** n„pp„imen kuvan p„„ll„. Jos on, palautetaan t„m„ tieto. ** T„m„ aliohjelma sytytt„„ ja sammuttaa hiirikursorin, joten muualla ** ohjelmassa hiirest„ ei tarvitse tiet„„ muutakuin alustaa se kerran. */ { /* Seuraava toimii mm. Turbo C:ss„: */ char c; int i; *lisa = 0; nayta_hiiri(); while (1) { if ( kbhit() ) { c = toupper(getch()); for (i=0; nappaimet[i].valinta_kirjain; i++) if ( nappaimet[i].valinta_kirjain == c ) goto palauta; } if ( ( i = tutki_hiiri(nappaimet,laskurit) ) != EI_KOMENTOA ) goto palauta; } palauta: katke_hiiri(); if ( i < 0 ) return i; /* Systeemikomento! */ *lisa = nappaimet[i].lisa_viesti; return nappaimet[i].komento; } #include "piirra.c" /****************************************************************************/ void nollaa_laskurit(laskuri_tyyppi *laskurit) { int i; for (i=0; laskurit[i].tunnus; i++) { laskurit[i].arvo=0; nayta_laskuri(&laskurit[i]); } } /****************************************************************************/ void lisaa_laskuria(laskuri_tyyppi *laskurit,int tunnus) { int i; for (i=0; laskurit[i].tunnus; i++) { /* Ets. laskuri */ if ( laskurit[i].tunnus == tunnus ) { laskurit[i].arvo++; nayta_laskuri(&laskurit[i]); return; } } } /****************************************************************************/ void alusta_nappulat(void) { HIIRI = alustahiiri(); } /****************************************************************************/ void tyhjenna_ruutu(void) { textcolor(WHITE); textbackground(WHITE); clrscr(); }