home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / vifs / edtrans.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-08-23  |  9.2 KB  |  459 lines

  1. /*
  2.  *    edtrans.c  --  edit transformations of an ifs.
  3.  *
  4.  *    The mouse driver has to be initialized.
  5.  *    Return value is 0 for quit, 1 for run (i.e. show the ifs and
  6.  *    then continue editing).
  7.  *
  8.  *    29 june 1989  Olle Olsson.
  9.  */
  10.  
  11. #include "edtrans.h"
  12. #include "stdlib.h"        /* for rand() prototype */
  13.  
  14. /* local variables */
  15.  
  16. static menudescr emenu =        /* the menu */
  17.     {
  18.     "quit",
  19. /*    "one", */
  20.     "go ",
  21.     "unit", "im-mode",
  22.     "color", "prob.",
  23.         "add", "del",
  24.     "zoom-in", "back-out",
  25.     "redraw ",
  26.     "load", "save", "0"
  27.     };
  28.  
  29. /* local functions (see also edtrans.h) */
  30. void resifsdes( ifsdes *dp );
  31. void restransf( transform *tp, area *ap, int colorindex, rgb *pal );
  32. void zoom( ifsdes *dp, int color, int zoomin );
  33. void loadfile( ifsdes *dp, menudescr *mp, int trace );
  34. void savefile( ifsdes *dp, menudescr *mp, int trace );
  35. void seltransf( ifsdes *dp, struct gm_status *gp );
  36. void addtransf( ifsdes *dp );
  37. void deltransf( ifsdes *dp, menudescr *mp );
  38.  
  39.  
  40. int edtrans( dp, trace )
  41. ifsdes *dp;            /* descriptor */
  42. int trace;            /* trace flag */
  43. {
  44. /*int i;                /* tmp */
  45. /*int c;                /* input char */
  46. /*transform *tp;            /* tmp */
  47. int running;            /* flag */
  48. int comeback;            /* return value */
  49. struct gm_status gs;        /* mouse status */
  50.  
  51. /* display */
  52. edispall( dp, &emenu, 0, 0 );
  53.  
  54. /* there are a little bit too much edispall() here, but its the easy way... */
  55.  
  56. for (running = 1; running;) switch (wbup(), getkey( &gs ))
  57.     {
  58.     case 'q':    /* quit */
  59.         comeback = running = 0;
  60.         break;
  61.  
  62.     case 'g':    /* go */
  63.         comeback = 1;
  64.         running = 0;
  65.         break;
  66.  
  67.     case 'r':    /* redraw */
  68.         edispall( dp, &emenu, 1, 1 );
  69.         break;
  70.  
  71.     case 'p':    /* edit probabilities */
  72.         gm_hide();
  73.         nomenu();
  74.         gm_show();
  75.  
  76.         edprob( dp );
  77.  
  78.         edispall( dp, &emenu, 1, 1 );
  79.         break;
  80.  
  81.     case 'c':    /* edit colors */
  82.         gm_hide();
  83.         nomenu();
  84.         gm_show();
  85.  
  86.         edcolors( dp );
  87.  
  88.         edispall( dp, &emenu, 1, 1 );
  89.         break;
  90.  
  91.     case 'l':    /* load from file */
  92.         loadfile( dp, &emenu, trace );
  93.         break;
  94.  
  95.     case 's':    /* save to file */
  96.         savefile( dp, &emenu, trace );
  97.         break;
  98.  
  99.     case '0':    /* reset */
  100.         resifsdes( dp );
  101.  
  102.         /* show */
  103.         edispall( dp, &emenu, 1, 1 );
  104.  
  105.         break;
  106.  
  107.     case 'u':    /* unit square */
  108.         unitsquare( dp, dp -> textcolor, &emenu );
  109.         break;
  110.  
  111.     case 'a':    /* add a transform */
  112.         addtransf( dp );
  113.         break;
  114.  
  115.     case 'd':    /* delete a transform */
  116.         deltransf( dp, &emenu );
  117.         break;
  118.  
  119.     case 'z':    /* zoom-in */
  120.         gm_hide();
  121.         zoom( dp, dp -> textcolor, 1 );
  122.  
  123.         /* redraw */
  124.         edispall( dp, &emenu, 1, 0 );
  125.         break;
  126.  
  127.     case 'b':    /* back-out (zoom out) */
  128.         gm_hide();
  129.         zoom( dp, dp -> textcolor, 0 );
  130.  
  131.         /* redraw */
  132.         edispall( dp, &emenu, 1, 0 );
  133.         break;
  134.  
  135.     case 'i':    /* im mode flip */
  136.         if (dp -> im)
  137.             {
  138.             /* im mode was on, turn off */
  139.  
  140.             /* keep the old value */
  141.             dp -> im_prev = dp -> im;
  142.             dp -> im = 0;
  143.                         }
  144.         else
  145.             {
  146.             /* im mode was off, turn on */
  147.             /* use previous value, but only if it is > 0 */
  148.             if ((dp -> im = dp -> im_prev) <= 0)
  149.                 dp -> im = 1;
  150.             }
  151.  
  152.         /* set up the palette */
  153.         palsetup( dp );
  154.  
  155.                 break;
  156.  
  157.     case 0:        /* a mouse key */
  158.                 seltransf( dp, &gs );
  159.         break;
  160.  
  161.     default:    /* ?? */
  162.             /* continue editing */
  163.         break;
  164.     }
  165.  
  166. gm_hide();
  167.  
  168. return (comeback);
  169. }
  170.  
  171.  
  172.  
  173. /* local functions */
  174.  
  175. static void resifsdes( dp )
  176. ifsdes *dp;        /* descriptor */
  177. {
  178. transform *tp;
  179.  
  180. /* "reset" the descriptor */
  181.  
  182. /* turn off im mode (keep the old value just in case..) */
  183. if (dp -> im)
  184.     {
  185.     dp -> im_prev = dp -> im;
  186.     dp -> im = 0;
  187.     }
  188.  
  189. /* set the area */
  190. dp -> area.xlow = dp -> area.ylow = 0;
  191. dp -> area.xlen = dp -> area.ylen = 1;
  192.  
  193. /* leave two transforms */
  194. dp -> size = 2;
  195.  
  196. /* reset the transforms */
  197. restransf( tp = dp -> tp, &dp -> area, 1, &dp -> colors[1] );
  198. restransf( ++tp, &dp -> area, 2, &dp -> colors[2] );
  199. }
  200.  
  201. static void restransf( tp, ap, color, palval )
  202. transform *tp;        /* transform to reset */
  203. area *ap;        /* limiting area */
  204. int color;        /* color index */
  205. rgb *palval;        /* color */
  206. {
  207. int n = color;        /* index for separating locations */
  208.  
  209. /* put it inside the limiting area */
  210. tp -> a11 = tp -> a22 = .5;
  211. tp -> a12 = tp -> a21 = 0;
  212. tp -> b1 = ap -> xlow + ap -> xlen / (n + 2);
  213. tp -> b2 = ap -> ylow + ap -> ylen / (n + 2);
  214. tp -> prob = .5;
  215.  
  216. /* select a color */
  217. tp -> color = color;
  218.  
  219. /* check that it isn't black */
  220. while ((palval -> r == 0) && (palval -> g == 0) && (palval -> b == 0))
  221.     randrgb( palval );
  222. }
  223.  
  224. static void zoom( dp, color, zoomin )
  225. ifsdes *dp;            /* descriptor */
  226. int color;            /* color to use */
  227. int zoomin;            /* zoom in/out flag */
  228. {
  229. double zlowlim = 1e-4;        /* lower limit for zoom (< one pixel) */
  230. transform ztr;            /* for zooming */
  231. double scl;            /* scale factor */
  232.  
  233. /* make a fake transform to modify (move and/or scale) */
  234. ztr.a11 = dp -> area.xlen;
  235. ztr.a22 = dp -> area.ylen;
  236. ztr.b1 = dp -> area.xlow;
  237. ztr.b2 = dp -> area.ylow;
  238. ztr.a12 = ztr.a21 = 0;
  239.  
  240. /* display it once before modifying it */
  241. setcolor( color );
  242. xdistrans( &ztr, &dp -> area );
  243.  
  244. /* move or scale */
  245. modtrans( &ztr, &dp -> area, 1 );
  246.  
  247. /* not too small! */
  248. if (ztr.a11 < zlowlim) ztr.a11 = zlowlim;
  249. if (ztr.a22 < zlowlim) ztr.a22 = zlowlim;
  250.  
  251. /* set the new area */
  252. if (zoomin)
  253.     {
  254.     /* the new area is the area of the fake transform */
  255.     dp -> area.xlow = ztr.b1;
  256.     dp -> area.xlen = ztr.a11;
  257.  
  258.     dp -> area.ylow = ztr.b2;
  259.     dp -> area.ylen = ztr.a22;
  260.         }
  261. else
  262.     {
  263.     /* the old area is the area of the fake transform */
  264.     scl = dp -> area.xlen / ztr.a11;
  265.     dp -> area.xlow += scl * (dp -> area.xlow - ztr.b1);
  266.     dp -> area.xlen *= scl;
  267.  
  268.     scl = dp -> area.ylen / ztr.a22;
  269.     dp -> area.ylow += scl * (dp -> area.ylow - ztr.b2);
  270.     dp -> area.ylen *= scl;
  271.     }
  272. }
  273.  
  274. static void loadfile( dp, menu, trace )
  275. ifsdes *dp;            /* descriptor */
  276. menudescr *menu;        /* menu to show when redrawing */
  277. int trace;            /* trace flag */
  278. {
  279. FILE *filep;            /* input file */
  280. char buf[100];            /* tmp */
  281.  
  282. /* remove the menu and ask for file name */
  283. gm_hide();
  284. nomenu();
  285. setcolor( dp -> textcolor );
  286. moveto( 0, 0 );
  287. gputs( "File to load: " );
  288. ggets( buf );
  289.  
  290. if ((filep = fopen( buf, "r" )) == NULL)
  291.     {
  292.     gputs( "  Not found!! " );
  293.     sleep( 2 );
  294.     }
  295. else
  296.     {
  297.     /* read the description */
  298.     rdescr( filep, dp, trace );
  299.     fclose( filep );
  300.     }
  301.  
  302. /* redraw */
  303. edispall( dp, menu, 1, 0 );
  304. }
  305.  
  306. static void savefile( dp, menu, trace )
  307. ifsdes *dp;            /* descriptor */
  308. menudescr *menu;        /* menu to show when redrawing */
  309. int trace;            /* trace flag */
  310. {
  311. FILE *filep;            /* output file */
  312. char buf[100];            /* tmp */
  313.  
  314. /* remove the menu and ask for file name */
  315. gm_hide();
  316. nomenu();
  317. setcolor( dp -> textcolor );
  318. moveto( 0, 0 );
  319. gputs( "File to write: " );
  320. ggets( buf );
  321.  
  322. if ((filep = fopen( buf, "w" )) == NULL)
  323.     {
  324.     gputs( "  Can't create!! " );
  325.     sleep( 2 );
  326.     }
  327. else
  328.     {
  329.     /* write the description */
  330.     wdescr( filep, dp, buf, trace );
  331.     fclose( filep );
  332.     }
  333.  
  334. /* redraw */
  335. edispall( dp, menu, 1, 0 );
  336. }
  337.  
  338. static void seltransf( dp, gp )
  339. ifsdes *dp;            /* descriptor */
  340. struct gm_status *gp;        /* mouse status */
  341. {
  342. int i;                /* tmp */
  343. transform *tp;            /* tmp */
  344.  
  345. gm_hide();
  346.  
  347. /* a transform is selected, find out which one! */
  348. i = findtrans( dp -> tp, dp -> size, &dp -> area,
  349.                  gp -> gm_xpos, gp -> gm_ypos );
  350.  
  351. /* found it? */
  352. if (i < 0)
  353.     return;    /* no */
  354.  
  355. tp = dp -> tp + i;
  356.  
  357. /* set color, use textcolor for prev color */
  358. setcolor( (tp -> color >= 0) ? tp -> color : dp -> textcolor );
  359.  
  360. /* modify it */
  361. if (gp -> gm_pbutton & GM_PLEFT)
  362.     {
  363.     /* move or scale */
  364.     modtrans( tp, &dp -> area, 1 );
  365.     }
  366. else if (gp -> gm_pbutton & GM_PRIGHT)
  367.     {
  368.     /* rotate or skew */
  369.     modtrans( tp, &dp -> area, 0 );
  370.     }
  371.  
  372. setcolor( dp -> textcolor );
  373. gm_show();
  374. }
  375.  
  376. static void addtransf( dp )
  377. ifsdes *dp;            /* descriptor */
  378. {
  379. transform *tp;            /* tmp */
  380. int i;
  381.  
  382. if (dp -> size >= dp -> maxsize)
  383.     {
  384.     /* no more space */
  385.     beep();
  386.     return;
  387.     }
  388.  
  389. /* add it */
  390. tp = &dp -> tp[dp -> size++];
  391. /* select a color index */
  392. i = dp -> size % (dp -> clrsize - 2) + 1;
  393. restransf( tp, &dp -> area, i, &dp -> colors[i] );
  394.  
  395. /* show it */
  396. gm_hide();
  397. setcolor( tp -> color );
  398. xdistrans( tp, &dp -> area );
  399.  
  400. setcolor( dp -> textcolor );
  401. gm_show();
  402.  
  403. /* get the color in place */
  404. /* (set up the palette) */
  405. palsetup( dp );
  406. }
  407.  
  408. static void deltransf( dp, menu )
  409. ifsdes *dp;            /* descriptor */
  410. menudescr *menu;        /* menu to show when redrawing */
  411. {
  412. int i;                /* tmp */
  413. transform *tp;            /* tmp */
  414. struct gm_status gs;        /* mouse status */
  415.  
  416. if (dp -> size < 3)
  417.     {
  418.     /* two is minimum, beep and abort */
  419.     beep();
  420.     return;
  421.     }
  422.  
  423. /* remove the menu and ask for identification */
  424. gm_hide();
  425. nomenu();
  426.  
  427. setcolor( dp -> textcolor );
  428. moveto( 0, 0 );
  429. gputs( "Delele which one?      (hit keyboard to abort)" );
  430.  
  431. /* wait for a button */
  432. gm_show();
  433. wbup();
  434. if (getkey( &gs ))
  435.     {
  436.     /* a (keyboard) key, redraw and abort */
  437.     edispall( dp, menu, 1, 1 );
  438.  
  439.     return;
  440.     }
  441.  
  442. gm_hide();
  443.  
  444. /* a transform is selected, find out which one! */
  445. i = findtrans( dp -> tp, dp -> size, &dp -> area, gs.gm_xpos, gs.gm_ypos );
  446.  
  447. /* found it? */
  448. if (i >= 0)
  449.     {
  450.     /* delete it */
  451.     --dp -> size;
  452.         for (tp = &dp -> tp[i]; i < dp -> size; ++tp, ++i)
  453.         *tp = *(tp + 1);
  454.     }
  455.  
  456. /* redraw */
  457. edispall( dp, menu, 1, 0 );
  458. }
  459.