home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD2.bin / bbs / misc / aspringies-1.0.lha / ASpringies / src / file.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-24  |  7.4 KB  |  268 lines

  1. /* file.c -- file loading and saving for ASpringies
  2.  * Copyright (C) 1991  Douglas M. DeCarlo
  3.  *
  4.  * Modifications for the Amiga port Copyright (C) 1994  Torsten Klein
  5.  *
  6.  * This file is part of ASpringies, a mass and spring simulation system for the Amiga
  7.  *
  8.  * ASpringies is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 1, or (at your option)
  11.  * any later version.
  12.  *
  13.  * ASpringies is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with ASpringies; see the file COPYING.  If not, write to
  20.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  *
  22.  * $Id: file.c,v 1.6 1994/08/19 11:46:17 Torsten_Klein Exp $
  23.  */
  24.  
  25. #include <strings.h>
  26. #include <stdio.h>
  27. #include "defs.h"
  28. #include "obj.h"
  29.  
  30. #define MAGIC_CMD    "#1.0"
  31.  
  32.  
  33. void skip_to_eol(FILE *f)
  34. {
  35.   int ch;
  36.  
  37.   while ((ch = fgetc(f)) != EOF && ch != '\n');
  38. }
  39.  
  40.  
  41. #define IS_CMD(s)    (!strncmp(cmd, s, 4))
  42.  
  43. boolean file_command(char *file, int command)
  44. {
  45.   FILE *f;
  46.   char cmd[5];
  47.   int i, which, spring_start, temp;
  48.   int *mapfrom, *mapto, num_map, num_map_alloc;
  49.   boolean selectnew = FALSE;
  50.   
  51.   if (strlen(file) == 0)
  52.     return FALSE;
  53.  
  54.   switch (command) 
  55.     {
  56.     case F_INSERT:
  57.     case F_LOAD:
  58.       if ((f = fopen(file, "r")) == NULL) {
  59.     return FALSE;
  60.       }
  61.  
  62.       /* Check first line */
  63.       if (fgets(cmd, 5, f) != NULL && IS_CMD(MAGIC_CMD)) {
  64.     skip_to_eol(f);
  65.  
  66.     if (command == F_LOAD) {
  67.       delete_all();
  68.       init_objects();
  69.     } else {
  70.       if (!anything_selected())
  71.         selectnew = TRUE;
  72.     }
  73.     spring_start = num_spring;
  74.  
  75.     num_map = 0;
  76.     num_map_alloc = ALLOC_SIZE;
  77.     mapfrom = (int *)xmalloc(sizeof(int) * num_map_alloc);
  78.     mapto = (int *)xmalloc(sizeof(int) * num_map_alloc);
  79.  
  80.     while (fgets(cmd, 5, f) != NULL) {
  81.       if (IS_CMD("mass")) {
  82.         if (num_map >= num_map_alloc) {
  83.           num_map_alloc += ALLOC_SIZE;
  84.           mapfrom = (int *)xrealloc((char *)mapfrom,
  85.                     sizeof(int) * num_map_alloc);
  86.           mapto =   (int *)xrealloc((char *)mapto, 
  87.                     sizeof(int) * num_map_alloc);
  88.         }
  89.  
  90.         which = create_mass();
  91.         mapto[num_map] = which;
  92.         fscanf(f, "%d %lf %lf %lf %lf %lf %lf\n", &mapfrom[num_map],
  93.            &masses[which].x, &masses[which].y,
  94.            &masses[which].vx, &masses[which].vy, 
  95.            &masses[which].mass,
  96.            &masses[which].elastic);
  97.         num_map++;
  98.         if (masses[which].mass < 0) {
  99.           masses[which].mass = -masses[which].mass;
  100.           masses[which].status |= S_FIXED;
  101.         }
  102.         masses[which].radius = mass_radius(masses[which].mass);
  103.         if (selectnew) {
  104.           select_object(which, TRUE, FALSE);
  105.         }
  106.       } else if (IS_CMD("spng")) {
  107.         int bogus;
  108.  
  109.         which = create_spring();
  110.         fscanf(f, "%d %d %d %lf %lf %lf\n", 
  111.            &bogus, &springs[which].m1, &springs[which].m2,
  112.            &springs[which].ks, &springs[which].kd, 
  113.            &springs[which].restlen);
  114.         if (selectnew) {
  115.           select_object(which, FALSE, FALSE);
  116.         }
  117.  
  118.       } else if (command == F_INSERT) {
  119.         /* skip non mass/spring commands if in insert mode */
  120.       } else if (IS_CMD("cmas")) {
  121.         fscanf(f, "%lf\n", &(mst.cur_mass));
  122.       } else if (IS_CMD("elas")) {
  123.         fscanf(f, "%lf\n", &(mst.cur_rest));
  124.       } else if (IS_CMD("kspr")) {
  125.         fscanf(f, "%lf\n", &(mst.cur_ks));
  126.       } else if (IS_CMD("kdmp")) {
  127.         fscanf(f, "%lf\n", &(mst.cur_kd));
  128.       } else if (IS_CMD("fixm")) {
  129.         fscanf(f, "%d\n", &temp);
  130.         mst.fix_mass = temp ? TRUE : FALSE;
  131.       } else if (IS_CMD("shws")) {
  132.         fscanf(f, "%d\n", &temp);
  133.         mst.show_spring = temp ? TRUE : FALSE;
  134.       } else if (IS_CMD("cent")) {
  135.         fscanf(f, "%d\n", &(mst.center_id));
  136.  
  137.       } else if (IS_CMD("frce")) {
  138.         int which;
  139.  
  140.         fscanf(f, "%d", &which);
  141.         if (which >= 0 && which < BF_NUM) {
  142.           fscanf(f, "%d %lf %lf\n", &(mst.bf_mode[which]),
  143.              &(mst.cur_grav_val[which]), &(mst.cur_misc_val[which]));
  144.         }
  145.       } else if (IS_CMD("visc")) {
  146.         fscanf(f, "%lf\n", &(mst.cur_visc));
  147.       } else if (IS_CMD("stck")) {
  148.         fscanf(f, "%lf\n", &(mst.cur_stick));
  149.       } else if (IS_CMD("step")) {
  150.         fscanf(f, "%lf\n", &(mst.cur_dt));
  151.       } else if (IS_CMD("prec")) {
  152.         fscanf(f, "%lf\n", &(mst.cur_prec));
  153.       } else if (IS_CMD("adpt")) {
  154.         fscanf(f, "%d\n", &temp);
  155.         mst.adaptive_step = temp ? TRUE : FALSE;
  156.  
  157.       } else if (IS_CMD("gsnp")) {
  158.         fscanf(f, "%lf %d\n", &(mst.cur_gsnap), &temp);
  159.         mst.grid_snap = temp ? TRUE : FALSE;
  160.       } else if (IS_CMD("wall")) {
  161.         int wt, wl, wr, wb;
  162.         fscanf(f, "%d %d %d %d\n", &wt, &wl, &wr, &wb);
  163.         mst.w_top = (boolean)wt;
  164.         mst.w_left = (boolean)wl;
  165.         mst.w_right = (boolean)wr;
  166.         mst.w_bottom = (boolean)wb;
  167.       } else {
  168.         /* unknown command */
  169. /*        fprintf(stderr, "Unknown command: %4.4s\n", cmd); */
  170.         skip_to_eol(f);
  171.       }
  172.     }
  173.  
  174.     /* Connect springs to masses */
  175.     for (i = spring_start; i < num_spring; i++) {
  176.       int j;
  177.       boolean m1done, m2done;
  178.       
  179.       m1done = m2done = FALSE;
  180.       
  181.       if (i == fake_spring)
  182.         continue;
  183.  
  184.       for (j = 0; (!m1done || !m2done) && j < num_map; j++) {
  185.         if (!m1done && springs[i].m1 == mapfrom[j]) {
  186.           springs[i].m1 = mapto[j];
  187.           m1done = TRUE;
  188.         }
  189.         if (!m2done && springs[i].m2 == mapfrom[j]) {
  190.           springs[i].m2 = mapto[j];
  191.           m2done = TRUE;
  192.         }
  193.       }
  194.       if (!m1done && !m2done) {
  195.         /* delete spring */
  196.         delete_spring(i);
  197.         fprintf(stderr, "Spring %d not connected to existing mass\n", i);
  198.       }
  199.     }
  200.  
  201.     free(mapfrom);
  202.     free(mapto);
  203.     reconnect_masses();
  204.     review_system();
  205.     redisplay_widgets();
  206.       } else {
  207.     return FALSE;
  208.       }
  209.  
  210.       (void)fclose(f);
  211.       
  212.       break;
  213.  
  214.     case F_SAVEAS:
  215.     case F_SAVE:
  216.       if ((f = fopen(file, "w")) == NULL) {
  217.     return FALSE;
  218.       }
  219.       fprintf(f, "%s *** ASpringies data file\n", MAGIC_CMD);
  220.       /* Settings */
  221.       fprintf(f, "cmas %lf\n", mst.cur_mass);
  222.       fprintf(f, "elas %lf\n", mst.cur_rest);
  223.       fprintf(f, "kspr %lf\n", mst.cur_ks);
  224.       fprintf(f, "kdmp %lf\n", mst.cur_kd);
  225.       fprintf(f, "fixm %d\n", mst.fix_mass);
  226.       fprintf(f, "shws %d\n", mst.show_spring);
  227.       fprintf(f, "cent %d\n", mst.center_id);
  228.  
  229.       for (i = 0; i < BF_NUM; i++)
  230.     fprintf(f, "frce %d %d %lf %lf\n", i, (mst.bf_mode[i] > 0) ? 1 : 0, 
  231.         mst.cur_grav_val[i], mst.cur_misc_val[i]);
  232.  
  233.       fprintf(f, "visc %lf\n", mst.cur_visc);
  234.       fprintf(f, "stck %lf\n", mst.cur_stick);
  235.       fprintf(f, "step %lf\n", mst.cur_dt);
  236.       fprintf(f, "prec %lf\n", mst.cur_prec);
  237.       fprintf(f, "adpt %d\n", mst.adaptive_step);
  238.       
  239.       fprintf(f, "gsnp %lf %d\n", mst.cur_gsnap, mst.grid_snap);
  240.       fprintf(f, "wall %d %d %d %d\n", (int)mst.w_top, (int)mst.w_left,
  241.           (int)mst.w_right, (int)mst.w_bottom);
  242.  
  243.       /* Masses and springs */
  244.       for (i = 0; i < num_mass; i++) {
  245.     if (masses[i].status & S_ALIVE) {
  246.       fprintf(f, "mass %d %lf %lf %lf %lf %lf %lf\n", 
  247.           i, masses[i].x, masses[i].y, masses[i].vx, masses[i].vy,
  248.           (masses[i].status & S_FIXED) 
  249.           ? -masses[i].mass : masses[i].mass,
  250.           masses[i].elastic);
  251.     }
  252.       }
  253.       for (i = 0; i < num_spring; i++) {
  254.     if (springs[i].status & S_ALIVE) {
  255.       fprintf(f, "spng %d %d %d %lf %lf %lf\n", i, springs[i].m1, 
  256.           springs[i].m2,
  257.           springs[i].ks, springs[i].kd, springs[i].restlen);
  258.     }
  259.       }
  260.  
  261.       if (fclose(f) == EOF)
  262.     return FALSE;
  263.       break;
  264.     }
  265.  
  266.   return(TRUE);
  267. }
  268.