home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-04-27 | 43.2 KB | 1,628 lines |
- Newsgroups: comp.sources.x
- From: dmd@gradient.cis.upenn.edu (Douglas DeCarlo)
- Subject: v19i054: xspringies - it's a spring simulator...no, it's a game, Part02/16
- Message-ID: <1993Mar26.161149.9541@sparky.imd.sterling.com>
- X-Md4-Signature: 45f7042fdd357f684ce5d40f870b2a70
- Date: Fri, 26 Mar 1993 16:11:49 GMT
- Approved: chris@sparky.imd.sterling.com
-
- Submitted-by: dmd@gradient.cis.upenn.edu (Douglas DeCarlo)
- Posting-number: Volume 19, Issue 54
- Archive-name: xspringies/part02
- Environment: X11
- Supersedes: xspringies: Volume 14, Issue 25-30
-
- #!/bin/sh
- # to extract, remove the header and type "sh filename"
- if `test ! -s ./xdisp.c`
- then
- echo "writting ./xdisp.c"
- cat > ./xdisp.c << '\BARFOO\'
- /* xdisp.c -- Xlib display code for xspringies
- * Copyright (C) 1991,1992 Douglas M. DeCarlo
- *
- * This file is part of XSpringies, a mass and spring simulation system for X
- *
- * XSpringies is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
- *
- * XSpringies is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with XSpringies; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
- #include "defs.h"
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <X11/keysym.h>
- #include <X11/cursorfont.h>
- #include <X11/Xos.h>
- #include "obj.h"
- #include "bitmap.h"
- #include "title.h"
- #include "bfbm.h"
-
- /* Mode values */
- #define M_EDIT 0
- #define M_MASS 1
- #define M_SPRING 2
-
- #define M_ACTION 3
-
- /* Behavior function modes */
- #define M_BF 4
-
- /* Button values */
- #define B_CENTER 0
- #define B_RESTLEN 1
- #define B_SELECTALL 2
- #define B_DELETE 3
- #define B_SAVESTATE 4
- #define B_RESSTATE 5
- #define B_DUPLICATE 6
- #define B_INSERTFILE 7
- #define B_LOADFILE 8
- #define B_SAVEFILE 9
- #define B_RESET 10
- #define B_QUIT 11
-
- #define C_FIXEDMASS 0
- #define C_GRIDSNAP 1
- #define C_ADAPTIVE_STEP 2
- #define C_WTOP 4
- #define C_WLEFT 5
- #define C_WRIGHT 6
- #define C_WBOTTOM 7
- #define C_SHOWSPRING 8
-
- #define S_MASS 0
- #define S_ELAS 1
- #define S_KSPR 2
- #define S_KDAMP 3
- #define S_GRAV 4
- #define S_GDIR 5
- #define S_VISC 6
- #define S_STICK 7
- #define S_TIMESTEP 8
- #define S_GRIDSNAP 9
- #define S_PRECISION 10
-
- /* Number of previous mouse state saves */
- #define MOUSE_PREV 4
-
- #define NAIL_SIZE 4
-
- /* Number of milliseconds that each drawing takes (to prevent stops) */
- #define MIN_DIFFT 100
-
- /* Default highlight color for color screen */
- #define HLCOLOR "green"
-
- /* Just in case someone has a 4.2 BSD system (you have my sympathy) */
- #ifndef FD_SET
- #define fd_set int
- #define FD_SET(fd,fdset) (*(fdset) |= (1 << (fd)))
- #define FD_CLR(fd,fdset) (*(fdset) &= ~(1 << (fd)))
- #define FD_ISSET(fd, fdset) (*(fdset) & (1 << (fd)))
- #define FD_ZERO(fdset) (*(fdset) = 0)
- #endif
-
- /* X globals */
- Display *dpy;
- Window main_win, text_win, acts_win, draw_win;
- GC fggc, bggc, revgc, hlgc, selectboxgc;
- GC sdrawgc, drawgc, erasegc, selectgc, selectlinegc;
- Pixmap draw_pm, acts_pm, startup_pm;
- int fcolor, bcolor, hcolor;
- int main_wid, main_ht, draw_wid, draw_ht, planes, xfd;
-
- /* Other globals */
- static int mode = M_EDIT, slid_dt_num, cur_force = 0, action = -1;
- static boolean quitting = FALSE;
- int cursor_pos = 0, spthick = 0;
-
- /* Current and previous bounding box */
- int bb_ulx, bb_uly, bb_lrx, bb_lry;
- int bbo_ulx, bbo_uly, bbo_lrx, bbo_lry;
- boolean bboxing = TRUE;
-
- /* Current mouse grab for spring */
- int static_spring = FALSE;
- int startx = 0, prevx = 0, starty = 0, prevy = 0;
-
- t_state mst = {
- 1.0, 1.0,
- 1.0, 1.0,
- FALSE, TRUE,
- -1,
- { -1, -1, -1, -1 },
- { 10.0, 5.0, 10.0, 10000.0 },
- { 0.0, 2.0, 0.0, 1.0 },
- 0.0, 0.0,
- DEF_TSTEP, 1.0,
- FALSE, FALSE,
- 20.0,
- TRUE, TRUE, TRUE, TRUE
- }, initst, sst;
-
- static double cur_grav_max[BF_NUM] = { 10000000.0, 10000000.0, 10000000.0, 10000000.0 };
- static double cur_grav_min[BF_NUM] = { 0.0, -10000000.0, -10000000.0, -10000000.0 };
- static double cur_misc_max[BF_NUM] = { 360.0, 10000000.0, 1000.0, 1000.0 };
- static double cur_misc_min[BF_NUM] = { -360.0, 0.0, 0.0, -0.0 };
-
- /* Position of Gravity/Direction sliders */
- int force_liney, grav_slidx, grav_slidy, dir_slidx, dir_slidy;
-
- /* Mouse recording */
- typedef struct {
- int x, y;
- unsigned long t;
- } mouse_info;
-
- static mouse_info mprev[MOUSE_PREV];
- static int moffset = 0;
- static void mouse_event();
-
- /* File operations globals */
- int file_op = F_NONE;
- char filename[MAXPATH];
-
- /* clean_up: free all of the X objects created
- like pixmaps and gcs
- */
- static void clean_up()
- {
- /* Free up X objects */
- XFreePixmap(dpy, draw_pm);
- XFreePixmap(dpy, acts_pm);
- XFreePixmap(dpy, startup_pm);
-
- XFreeGC(dpy, fggc);
- XFreeGC(dpy, bggc);
- XFreeGC(dpy, revgc);
- XFreeGC(dpy, hlgc);
- XFreeGC(dpy, selectboxgc);
-
- XFreeGC(dpy, drawgc);
- XFreeGC(dpy, sdrawgc);
- XFreeGC(dpy, erasegc);
- XFreeGC(dpy, selectgc);
- XFreeGC(dpy, selectlinegc);
- XCloseDisplay(dpy);
- }
-
- /* fatal(msg): print out the message msg, clean up,
- and exit
- */
- void fatal(msg)
- char *msg;
- {
- if (msg != NULL)
- fprintf(stderr, msg);
- clean_up();
- exit(-1);
- }
-
- void disp_filename(cur_reset)
- boolean cur_reset;
- {
- char fbuff[MAXPATH + 256];
- int offset;
-
- if (cur_reset)
- cursor_pos = strlen(filename);
-
- switch (file_op) {
- case F_NONE:
- break;
- case F_LOAD:
- strcpy(fbuff, "Load file: ");
- break;
- case F_INSERT:
- strcpy(fbuff, "Insert file: ");
- break;
- case F_SAVE:
- strcpy(fbuff, "Save file: ");
- break;
- }
-
- XFillRectangle(dpy, text_win, bggc, 0, 0, draw_wid, T_HT);
- if (file_op != F_NONE) {
- int cur_offset;
-
- strncat(fbuff, filename, cursor_pos);
-
- if ((offset = strlen(fbuff) + 1 - (draw_wid - F_WID) / F_WID) < 0)
- offset = 0;
-
- cur_offset = strlen(fbuff) - offset;
-
- strcat(fbuff, filename + cursor_pos);
- XFillRectangle(dpy, text_win, hlgc, cur_offset * F_WID + F_WID/2, 1, F_WID, F_HT);
- XDrawString(dpy, text_win, fggc, F_WID/2, F_HT, fbuff + offset, strlen(fbuff + offset));
- }
- XFlush(dpy);
- }
-
- void file_error()
- {
- XBell(dpy, 50);
- }
-
- void reset_bbox()
- {
- bb_ulx = bbo_ulx = bb_uly = bbo_uly = 0;
- bb_lrx = bbo_lrx = draw_wid - 1;
- bb_lry = bbo_lry = draw_ht - 1;
- }
-
- void calc_bbox()
- {
- int i, rad, bb_temp;
- boolean first = TRUE, fixed;
-
- if (bboxing) {
- if (static_spring) {
- first = FALSE;
- bb_ulx = MIN(startx, prevx);
- bb_uly = MIN(starty, prevy);
- bb_lrx = MAX(startx, prevx);
- bb_lry = MAX(starty, prevy);
- }
- for (i = 0; i < num_mass; i++) {
- if ((masses[i].status & S_ALIVE) || (i == 0 && springs[0].status & S_ALIVE)) {
- fixed = (masses[i].status & S_FIXED) && !(masses[i].status & S_TEMPFIXED);
- rad = fixed ? NAIL_SIZE : masses[i].radius;
-
- if (i == mst.center_id)
- rad += 1;
-
- /* Make sure bounding box includes mass */
- if (first) {
- bb_ulx = COORD_X(masses[i].x - rad);
- bb_uly = COORD_Y(masses[i].y + rad);
- bb_lrx = COORD_X(masses[i].x + rad);
- bb_lry = COORD_Y(masses[i].y - rad);
- first = FALSE;
- } else {
- if ((bb_temp = COORD_X(masses[i].x - rad)) < bb_ulx)
- bb_ulx = bb_temp;
- if ((bb_temp = COORD_Y(masses[i].y + rad)) < bb_uly)
- bb_uly = bb_temp;
- if ((bb_temp = COORD_X(masses[i].x + rad)) > bb_lrx)
- bb_lrx = bb_temp;
- if ((bb_temp = COORD_Y(masses[i].y - rad)) > bb_lry)
- bb_lry = bb_temp;
- }
- }
- }
-
- /* Add bounding strip */
- bb_ulx -= spthick + 1;
- bb_uly -= spthick + 1;
- bb_lrx += spthick + 1;
- bb_lry += spthick + 1;
-
- /* Bound within screen */
- if (bb_ulx < 0)
- bb_ulx = 0;
- if (bb_lrx < 0)
- bb_lrx = 0;
-
- if (bb_uly < 0)
- bb_uly = 0;
- if (bb_lry < 0)
- bb_lry = 0;
-
- if (bb_ulx >= draw_wid)
- bb_ulx = draw_wid - 1;
- if (bb_lrx >= draw_wid)
- bb_lrx = draw_wid - 1;
-
- if (bb_uly >= draw_ht)
- bb_uly = draw_ht - 1;
- if (bb_lry >= draw_ht)
- bb_lry = draw_ht - 1;
-
- /* Intersect with previous bbox, and set old box to new */
- if (bbo_ulx < (bb_temp = bb_ulx))
- bb_ulx = bbo_ulx;
- bbo_ulx = bb_temp;
-
- if (bbo_uly < (bb_temp = bb_uly))
- bb_uly = bbo_uly;
- bbo_uly = bb_temp;
-
- if (bbo_lrx > (bb_temp = bb_lrx))
- bb_lrx = bbo_lrx;
- bbo_lrx = bb_temp;
-
- if (bbo_lry > (bb_temp = bb_lry))
- bb_lry = bbo_lry;
- bbo_lry = bb_temp;
- }
- }
-
- void draw_startup_picture()
- {
- reset_bbox();
-
- /* Set up draw pixmap with startup picture */
- XFillRectangle(dpy, draw_pm, erasegc, 0, 0, draw_wid, draw_ht);
-
- XCopyArea(dpy, startup_pm, draw_pm, drawgc, 0, 0, startup_width, startup_height, (draw_wid - startup_width) / 2, (draw_ht - startup_height) / 2);
- }
-
- void redraw_system()
- {
- static XArc *arcs = NULL, *selarcs = NULL, *circs = NULL, *selcircs = NULL;
- static XSegment *segs = NULL, *selsegs = NULL;
- static num_mass_alloc = 0, num_spring_alloc = 0;
- XArc *cur_arc;
- XSegment *cur_seg;
- int numarcs, numselarcs, numcircs, numselcircs, numsegs, numselsegs;
- int i, rad, num_spr;
- boolean fixed;
-
- /* Draw springs */
- numsegs = numselsegs = 0;
- if (num_spring_alloc < num_spring) {
- num_spring_alloc = num_spring;
- segs = (XSegment *)xrealloc(segs, num_spring_alloc * sizeof(XSegment));
- selsegs = (XSegment *)xrealloc(selsegs, num_spring_alloc * sizeof(XSegment));
- }
- num_spr = (mst.show_spring) ? num_spring : 1;
-
- for (i = 0; i < num_spr; i++) {
- if (springs[i].status & S_ALIVE) {
- if (springs[i].status & S_SELECTED) {
- cur_seg = selsegs + numselsegs++;
- } else {
- cur_seg = segs + numsegs++;
- }
-
- cur_seg->x1 = COORD_X(masses[springs[i].m1].x);
- cur_seg->y1 = COORD_Y(masses[springs[i].m1].y);
- cur_seg->x2 = COORD_X(masses[springs[i].m2].x);
- cur_seg->y2 = COORD_Y(masses[springs[i].m2].y);
- }
- }
- if (numsegs) {
- XDrawSegments(dpy, draw_pm, sdrawgc, segs, numsegs);
- }
- if (numselsegs) {
- XDrawSegments(dpy, draw_pm, erasegc, selsegs, numselsegs);
- XDrawSegments(dpy, draw_pm, selectlinegc, selsegs, numselsegs);
- }
-
- /* Draw masses */
- numarcs = numselarcs = numcircs = numselcircs = 0;
- if (num_mass_alloc < num_mass) {
- num_mass_alloc = num_mass;
- arcs = (XArc *)xrealloc(arcs, num_mass_alloc * sizeof(XArc));
- selarcs = (XArc *)xrealloc(selarcs, num_mass_alloc * sizeof(XArc));
- circs = (XArc *)xrealloc(circs, num_mass_alloc * sizeof(XArc));
- selcircs = (XArc *)xrealloc(selcircs, num_mass_alloc * sizeof(XArc));
- }
-
- for (i = 0; i < num_mass; i++) {
- if (masses[i].status & S_ALIVE) {
- /* Check if within bounds */
- fixed = (masses[i].status & S_FIXED) && !(masses[i].status & S_TEMPFIXED);
- rad = fixed ? NAIL_SIZE : masses[i].radius;
-
- if (COORD_X(masses[i].x + rad) >= 0 && COORD_X(masses[i].x - rad) <= draw_wid &&
- COORD_Y(masses[i].y - rad) >= 0 && COORD_Y(masses[i].y + rad) <= draw_ht) {
- /* Get cur_arc value based on if FIXED or SELECTED */
- if (masses[i].status & S_SELECTED) {
- if (fixed) {
- cur_arc = selcircs + numselcircs++;
- } else {
- cur_arc = selarcs + numselarcs++;
- }
- } else {
- if (fixed) {
- cur_arc = circs + numcircs++;
- } else {
- cur_arc = arcs + numarcs++;
- }
- }
-
- cur_arc->x = COORD_X(masses[i].x) - rad;
- cur_arc->y = COORD_Y(masses[i].y) - rad;
- cur_arc->width = cur_arc->height = rad * 2 + 1;
- cur_arc->angle1 = 0;
- cur_arc->angle2 = 64 * 360;
- }
- }
- }
- /* Draw masses and nails */
- if (numarcs) {
- XFillArcs(dpy, draw_pm, drawgc, arcs, numarcs);
- }
- if (numselarcs) {
- XFillArcs(dpy, draw_pm, erasegc, selarcs, numselarcs);
- XFillArcs(dpy, draw_pm, selectgc, selarcs, numselarcs);
- }
- if (numcircs) {
- XFillArcs(dpy, draw_pm, erasegc, circs, numcircs);
- XDrawArcs(dpy, draw_pm, drawgc, circs, numcircs);
- }
- if (numselcircs) {
- XFillArcs(dpy, draw_pm, erasegc, selcircs, numselcircs);
- XDrawArcs(dpy, draw_pm, selectgc, selcircs, numselcircs);
- }
-
- if (mst.center_id != -1) {
- i = mst.center_id;
-
- rad = ((masses[i].status & S_FIXED) && !(masses[i].status & S_TEMPFIXED)) ? NAIL_SIZE : masses[i].radius;
-
- XDrawRectangle(dpy, draw_pm, drawgc, (int)(COORD_X(masses[i].x) - rad), (int)(COORD_Y(masses[i].y) - rad),
- 2 * rad + 1, 2 * rad + 1);
- }
- }
-
- void view_system()
- {
- XCopyPlane(dpy, draw_pm, draw_win, fggc, bb_ulx, bb_uly, bb_lrx - bb_ulx + 1, bb_lry - bb_uly + 1, bb_ulx, bb_uly, 0x1);
- }
-
- void view_subsystem(ulx, uly, wid, ht)
- int ulx, uly, wid, ht;
- {
- if (ulx < 0) {
- wid += ulx;
- ulx = 0;
- }
- if (uly < 0) {
- ht += uly;
- uly = 0;
- }
- if (wid < 0 || ht < 0)
- return;
-
- if (ulx + wid >= draw_wid)
- wid -= (ulx + wid - draw_wid);
- if (uly + ht >= draw_ht)
- ht -= (uly + ht - draw_ht);
-
- if (wid < 0 || ht < 0)
- return;
-
- XCopyPlane(dpy, draw_pm, draw_win, fggc, ulx, uly, wid, ht, ulx, uly, 0x1);
- }
-
- void review_system(reset)
- boolean reset;
- {
- if (reset) {
- reset_bbox();
- } else {
- calc_bbox();
- }
-
- /* Clear the old pixmap */
- XFillRectangle(dpy, draw_pm, erasegc, bb_ulx, bb_uly, bb_lrx - bb_ulx + 1, bb_lry - bb_uly + 1);
-
- redraw_system();
-
- view_system();
-
- mouse_event(M_REDISPLAY, 0, 0, AnyButton, FALSE);
- if (mst.adaptive_step) {
- update_slider(slid_dt_num);
- }
- XFlush(dpy);
- }
-
- void update_slidnum(w)
- int w;
- {
- change_slider_parms(S_GRAV, &(mst.cur_grav_val[w]), cur_grav_max[w], cur_grav_min[w]);
- change_slider_parms(S_GDIR, &(mst.cur_misc_val[w]), cur_misc_max[w], cur_misc_min[w]);
-
- update_slider(S_GRAV);
- update_slider(S_GDIR);
- }
-
- void redraw_names(w)
- int w;
- {
- static char *grav_nam[] = { "Gravity", "Magnitude", "Magnitude", "Magnitude" };
- static char *misc_nam[] = { "Direction", "Damping", "Exponent", "Exponent" };
- int offset = 120;
-
- XDrawLine(dpy, acts_win, bggc, 4, force_liney-1, (BF_NUM)*(BF_SIZ+4)+5, force_liney-1);
- XDrawLine(dpy, acts_win, bggc, 4, force_liney+BF_SIZ+6, (BF_NUM)*(BF_SIZ+4)+5, force_liney+BF_SIZ+6);
- XFillRectangle(dpy, acts_win, bggc, grav_slidx + offset, grav_slidy - F_HT, B_WID - 1 - grav_slidx - offset,
- dir_slidy + F_HT + 3 - grav_slidy);
-
- XDrawLine(dpy, acts_win, fggc, w*(BF_SIZ+4)+4, force_liney-1, (w+1)*(BF_SIZ+4)+5, force_liney-1);
- XDrawLine(dpy, acts_win, fggc, w*(BF_SIZ+4)+4, force_liney+BF_SIZ+6, (w+1)*(BF_SIZ+4)+5, force_liney+BF_SIZ+6);
- XDrawString(dpy, acts_win, fggc, grav_slidx + offset, grav_slidy, grav_nam[w], strlen(grav_nam[w]));
- XDrawString(dpy, acts_win, fggc, dir_slidx + offset, dir_slidy, misc_nam[w], strlen(misc_nam[w]));
- }
-
- void redisplay_widgets()
- {
- XCopyPlane(dpy, acts_pm, acts_win, fggc, 0, 0, B_WID, B_HT, 0, 0, 0x1);
-
- redraw_names(cur_force);
-
- redraw_widgets(TRUE);
- }
-
- int mass_radius(m)
- double m;
- {
- int rad;
-
- rad = (int)(2 * log(4.0 * m + 1.0));
-
- if (rad < 1) rad = 1;
- if (rad > 64) rad = 64;
-
- return rad + spthick/2;
- }
-
- static void draw_mass(w, mx, my, m)
- Window w;
- int mx, my;
- double m;
- {
- int rad;
-
- rad = mass_radius(m);
-
- XFillArc(dpy, w, fggc, mx - rad, my - rad, rad * 2 + 1, rad * 2 + 1, 0, 64 * 360);
- }
-
- static void draw_spring(w, x1, y1, x2, y2)
- Window w;
- int x1, y1, x2, y2;
- {
- XDrawLine(dpy, w, fggc, x1, y1, x2, y2);
- }
-
- static void mouse_vel(mx, my)
- int *mx, *my;
- {
- int i, totalx = 0, totaly = 0, scale = 0, dx, dy, dt;
- int fudge = 256;
-
- for (i = 0; i < MOUSE_PREV - 1; i++) {
- dx = mprev[(moffset + 2 + i) % MOUSE_PREV].x - mprev[(moffset + 1 + i) % MOUSE_PREV].x;
- dy = mprev[(moffset + 2 + i) % MOUSE_PREV].y - mprev[(moffset + 1 + i) % MOUSE_PREV].y;
- dt = mprev[(moffset + 2 + i) % MOUSE_PREV].t - mprev[(moffset + 1 + i) % MOUSE_PREV].t;
-
- if (dt) {
- scale += 64 * i * i;
- totalx += 64 * i * i * fudge * dx / dt;
- totaly += 64 * i * i * fudge * dy / dt;
- }
- }
-
- if (scale) {
- totalx /= scale;
- totaly /= scale;
- }
-
- *mx = totalx;
- *my = totaly;
- }
-
- void widget_notify(type, idno)
- int type, idno;
- {
- int i;
-
- switch (type) {
-
- case O_BUTTON:
- switch (idno) {
- case B_CENTER:
- set_center();
- review_system(TRUE);
- break;
- case B_RESTLEN:
- set_sel_restlen();
- break;
- case B_DELETE:
- delete_selected();
- review_system(TRUE);
- break;
- case B_SELECTALL:
- select_all();
- eval_selection();
- review_system(TRUE);
- break;
- case B_SAVESTATE:
- save_state();
- sst = mst;
- break;
- case B_RESSTATE:
- restore_state();
- mst = sst;
-
- redisplay_widgets();
- review_system(TRUE);
- mouse_event(M_REDISPLAY, 0, 0, AnyButton, FALSE);
- break;
- case B_DUPLICATE:
- duplicate_selected();
- review_system(TRUE);
- break;
- case B_INSERTFILE:
- file_op = F_INSERT;
- disp_filename(TRUE);
- break;
- case B_LOADFILE:
- file_op = F_LOAD;
- disp_filename(TRUE);
- break;
- case B_SAVEFILE:
- file_op = F_SAVE;
- disp_filename(TRUE);
- break;
- case B_RESET:
- delete_all();
- mst = initst;
- init_objects();
-
- redisplay_widgets();
- review_system(TRUE);
- mouse_event(M_REDISPLAY, 0, 0, AnyButton, FALSE);
- break;
- case B_QUIT:
- quitting = TRUE;
- break;
- }
- break;
-
- case O_MBUTTON:
- if (idno >= M_BF && idno < M_BF + BF_NUM && mst.bf_mode[idno - M_BF] > 0) {
- cur_force = idno - M_BF;
- update_slidnum(cur_force);
- redraw_names(cur_force);
- }
- break;
-
- case O_CHECKBOX:
- switch (idno) {
- case C_FIXEDMASS:
- for (i = 0; i < num_mass; i++) {
- if (masses[i].status & S_SELECTED) {
- if (mst.fix_mass) {
- masses[i].status |= S_FIXED;
- masses[i].status &= ~S_TEMPFIXED;
- } else {
- masses[i].status &= ~(S_FIXED | S_TEMPFIXED);
- }
- }
- }
- review_system(TRUE);
- break;
- case C_SHOWSPRING:
- review_system(TRUE);
- break;
- }
- break;
-
- case O_SLIDER:
- switch (idno) {
- case S_MASS:
- for (i = 0; i < num_mass; i++) {
- if (masses[i].status & S_SELECTED) {
- masses[i].mass = mst.cur_mass;
- masses[i].radius = mass_radius(mst.cur_mass);
- }
- }
- review_system(TRUE);
- break;
- case S_ELAS:
- for (i = 0; i < num_mass; i++) {
- if (masses[i].status & S_SELECTED)
- masses[i].elastic = mst.cur_rest;
- }
- break;
- case S_KSPR:
- for (i = 0; i < num_spring; i++) {
- if (springs[i].status & S_SELECTED)
- springs[i].ks = mst.cur_ks;
- }
- break;
- case S_KDAMP:
- for (i = 0; i < num_spring; i++) {
- if (springs[i].status & S_SELECTED)
- springs[i].kd = mst.cur_kd;
- }
- break;
- }
- }
- }
-
- static void mouse_event(type, mx, my, mbutton, shifted)
- int type;
- int mx, my, mbutton;
- int shifted;
- {
- static int selection = -1, cur_button = 0;
- static boolean active = FALSE, cur_shift = FALSE;
-
- /* Skip restarts when active or continuations when inactive */
- if ((type != M_DOWN && !active) || (type == M_DOWN && active))
- return;
-
- /* Do grid snapping operation */
- if (mst.grid_snap && mode != M_EDIT) {
- mx = ((mx + (int)mst.cur_gsnap / 2) / (int)mst.cur_gsnap) * (int)mst.cur_gsnap;
- my = ((my + (int)mst.cur_gsnap / 2) / (int)mst.cur_gsnap) * (int)mst.cur_gsnap;
- }
-
- switch (type) {
- case M_REDISPLAY:
- switch (mode) {
- case M_EDIT:
- switch (cur_button) {
- case Button1:
- if (selection < 0) {
- XDrawRectangle(dpy, draw_win, selectboxgc, MIN(startx, prevx), MIN(starty, prevy),
- ABS(prevx - startx), ABS(prevy - starty));
- }
- break;
- case Button2:
- break;
- case Button3:
- break;
- }
- break;
- case M_MASS:
- draw_mass(draw_win, prevx, prevy, mst.cur_mass);
- break;
- case M_SPRING:
- if (static_spring) {
- startx = COORD_X(masses[selection].x);
- starty = COORD_Y(masses[selection].y);
- draw_spring(draw_win, startx, starty, prevx, prevy);
- }
- break;
- }
- break;
-
- case M_DOWN:
- review_system(TRUE);
- startx = prevx = mx;
- starty = prevy = my;
- cur_button = mbutton;
- active = TRUE;
- cur_shift = shifted;
-
- switch (mode) {
- case M_EDIT:
- switch (cur_button) {
- case Button1:
- {
- boolean is_mass = FALSE;
- selection = nearest_object(COORD_X(mx), COORD_Y(my), &is_mass);
-
- /* If not shift clicking, unselect all currently selected items */
- if (!shifted) {
- unselect_all();
- review_system(TRUE);
- }
- }
- break;
- case Button2:
- case Button3:
- tempfixed_obj(TRUE);
- break;
- }
- break;
- case M_MASS:
- draw_mass(draw_win, mx, my, mst.cur_mass);
- break;
- case M_SPRING:
- {
- boolean is_mass = TRUE;
-
- static_spring = (action == -1 || cur_button == Button3);
-
- selection = nearest_object(COORD_X(mx), COORD_Y(my), &is_mass);
- if (selection >= 0 && is_mass) {
- startx = COORD_X(masses[selection].x);
- starty = COORD_Y(masses[selection].y);
- if (static_spring) {
- draw_spring(draw_win, startx, starty, prevx, prevy);
- } else {
- attach_fake_spring(selection);
- move_fake_mass(COORD_X(mx), COORD_Y(my));
- review_system(TRUE);
- }
- } else {
- active = FALSE;
- }
- }
- break;
- }
- break;
-
- case M_DRAG:
- switch (mode) {
- case M_EDIT:
- switch (cur_button) {
- case Button1:
- if (selection < 0) {
- view_subsystem(MIN(startx, prevx), MIN(starty, prevy), ABS(prevx - startx) + 1, ABS(prevy - starty) + 1);
- prevx = mx;
- prevy = my;
- XDrawRectangle(dpy, draw_win, selectboxgc, MIN(startx, prevx), MIN(starty, prevy),
- ABS(prevx - startx), ABS(prevy - starty));
- }
- break;
- case Button2:
- case Button3:
- /* Move objects relative to mouse */
- translate_selobj(COORD_DX(mx - prevx), COORD_DY(my - prevy));
- review_system(TRUE);
- prevx = mx;
- prevy = my;
- break;
- }
- break;
- case M_MASS:
- {
- int rad = mass_radius(mst.cur_mass);
- view_subsystem(prevx - rad, prevy - rad, rad * 2 + 1, rad * 2 + 1);
- }
- prevx = mx;
- prevy = my;
- draw_mass(draw_win, prevx, prevy, mst.cur_mass);
- break;
- case M_SPRING:
- if (static_spring) {
- view_subsystem(MIN(startx, prevx), MIN(starty, prevy), ABS(prevx - startx) + 1, ABS(prevy - starty) + 1);
- prevx = mx;
- prevy = my;
- startx = COORD_X(masses[selection].x);
- starty = COORD_Y(masses[selection].y);
- draw_spring(draw_win, startx, starty, prevx, prevy);
- } else {
- move_fake_mass(COORD_X(mx), COORD_Y(my));
- }
- break;
- }
- break;
-
- case M_UP:
- active = FALSE;
- switch (mode) {
- case M_EDIT:
- switch (cur_button) {
- case Button1:
- if (selection < 0) {
- select_objects(MIN(COORD_X(startx), COORD_X(mx)), MIN(COORD_Y(starty), COORD_Y(my)),
- MAX(COORD_X(startx), COORD_X(mx)), MAX(COORD_Y(starty), COORD_Y(my)), cur_shift);
- eval_selection();
- review_system(TRUE);
- } else {
- boolean is_mass = FALSE;
-
- if ((selection = nearest_object(COORD_X(mx), COORD_Y(my), &is_mass)) >= 0) {
- select_object(selection, is_mass, cur_shift);
- eval_selection();
- review_system(TRUE);
- }
- }
- break;
- case Button2:
- tempfixed_obj(FALSE);
- review_system(TRUE);
- break;
- case Button3:
- {
- int mvx, mvy;
-
- mouse_vel(&mvx, &mvy);
-
- changevel_selobj(COORD_DX(mvx), COORD_DY(mvy), FALSE);
- tempfixed_obj(FALSE);
- review_system(TRUE);
- }
- break;
- }
- break;
- case M_MASS:
- {
- int newm;
-
- newm = create_mass();
-
- masses[newm].x = COORD_X((double)mx);
- masses[newm].y = COORD_Y((double)my);
- masses[newm].mass = mst.cur_mass;
- masses[newm].radius = mass_radius(mst.cur_mass);
- masses[newm].elastic = mst.cur_rest;
- if (mst.fix_mass) masses[newm].status |= S_FIXED;
-
- review_system(TRUE);
- }
- break;
-
- case M_SPRING:
- {
- boolean is_mass = TRUE;
- int start_sel = selection, newsel, endx, endy;
-
- if (!static_spring) {
- kill_fake_spring();
- }
-
- selection = nearest_object(COORD_X(mx), COORD_Y(my), &is_mass);
- if ((static_spring || action == -1 || cur_button == Button1) && selection >= 0 && is_mass && selection != start_sel) {
- startx = COORD_X(masses[start_sel].x);
- starty = COORD_Y(masses[start_sel].y);
- endx = COORD_X(masses[selection].x);
- endy = COORD_Y(masses[selection].y);
-
- newsel = create_spring();
- springs[newsel].m1 = start_sel;
- springs[newsel].m2 = selection;
- springs[newsel].ks = mst.cur_ks;
- springs[newsel].kd = mst.cur_kd;
- springs[newsel].restlen = sqrt((double)SQR(startx - endx) + (double)SQR(starty - endy));
-
- add_massparent(start_sel, newsel);
- add_massparent(selection, newsel);
- }
-
- review_system(TRUE);
- }
- break;
- }
- break;
- }
- XFlush(dpy);
- }
-
- static boolean x_event()
- {
- XEvent event, peek;
- KeySym ks;
- char keybuf[1];
-
- if (quitting)
- return FALSE;
-
- XFlush(dpy);
-
- /* Get next event */
- if (XPending(dpy)) {
- XNextEvent(dpy, &event);
-
- switch (event.type) {
- case ButtonPress:
- if (!check_widgets(event.xbutton.window, event.xbutton.x, event.xbutton.y, event.xbutton.button, M_DOWN)) {
- /* Process button press event */
- if (event.xbutton.window == draw_win) {
- bzero(mprev, sizeof(mprev));
- mouse_event(M_DOWN, event.xbutton.x, event.xbutton.y, event.xbutton.button, event.xbutton.state & ShiftMask);
- } else if (event.xbutton.window == acts_win) {
- /* Show startup picture if clicked on xspringies logo */
- if (event.xbutton.x >= 4 && event.xbutton.x < 4 + title_width && event.xbutton.y >= 4 && event.xbutton.y < 4 + title_height) {
- draw_startup_picture();
- view_system();
- }
- }
- }
- break;
- case ButtonRelease:
- if (!check_widgets(event.xbutton.window, event.xbutton.x, event.xbutton.y, event.xbutton.button, M_UP)) {
- /* Process button release event */
- if (event.xbutton.window == draw_win) {
- mouse_event(M_UP, event.xbutton.x, event.xbutton.y, event.xbutton.button, FALSE);
- }
- }
- break;
- case MotionNotify:
- {
- Window mw = event.xmotion.window;
-
- /* Skip over other motion notify events for this window */
- while (XCheckWindowEvent(dpy, mw, PointerMotionMask, &event));
-
- if (event.xmotion.state & (Button1Mask | Button2Mask | Button3Mask)) {
- if (!check_widgets(event.xmotion.window, event.xmotion.x, event.xmotion.y, 0, M_DRAG)) {
- /* Record mouse info */
- mprev[moffset].x = event.xmotion.x;
- mprev[moffset].y = event.xmotion.y;
- mprev[moffset].t = (unsigned long)(event.xmotion.time);
- moffset = (moffset + 1) % MOUSE_PREV;
-
- /* Process motion notify event */
- if (event.xbutton.window == draw_win) {
- mouse_event(M_DRAG, event.xbutton.x, event.xbutton.y, AnyButton, FALSE);
- }
- }
- }
- }
- break;
-
- case KeyPress:
- keybuf[0] = '\0';
- XLookupString (&event.xkey, keybuf, sizeof(keybuf), &ks, NULL);
-
- /* Skip modifier key */
- if (IsModifierKey(ks) || ks == XK_Multi_key)
- break;
-
- key_press((int)(keybuf[0]), ks, event.xkey.window);
- break;
-
- case ConfigureNotify:
- {
- static boolean created = FALSE;
- int new_wid, new_ht;
-
- new_wid = event.xconfigure.width;
- new_ht = event.xconfigure.height;
-
- if (new_wid == main_wid && new_ht == main_ht)
- break;
-
- main_wid = new_wid;
- main_ht = new_ht;
-
- draw_wid = main_wid - B_WID - 1;
- draw_ht = main_ht - T_HT - 1;
-
- reset_bbox();
-
- if (created) {
- XFreePixmap(dpy, draw_pm);
- created = TRUE;
- }
- draw_pm = XCreatePixmap(dpy, draw_win, draw_wid, draw_ht, 1);
- review_system(TRUE);
-
- XMoveResizeWindow(dpy, text_win, B_WID + 1, draw_ht + 1, draw_wid, T_HT);
- XMoveResizeWindow(dpy, draw_win, B_WID + 1, 0, draw_wid, draw_ht);
- }
- break;
-
- case Expose:
- /* Skip over additional expose events */
- while (XCheckTypedEvent(dpy, Expose, &peek))
- event = peek;
-
- /* Generic expose event (redraw everything) */
- redisplay_widgets();
-
- view_system();
- mouse_event(M_REDISPLAY, 0, 0, AnyButton, FALSE);
-
- disp_filename(FALSE);
- break;
-
- default:
- break;
- }
- XFlush(dpy);
- } else {
- /* No events waiting */
- if (scan_flag) {
- static struct timeval tp, tpo;
- static struct timezone tzp;
- int difft;
-
- if (tpo.tv_sec == 0)
- gettimeofday(&tpo, &tzp);
-
- gettimeofday(&tp, &tzp);
- difft = (tp.tv_sec - tpo.tv_sec) * 1000000 + (tp.tv_usec - tpo.tv_usec);
-
- /* Do widget scanning buttons about 30 times / sec */
- if (difft > 30000) {
- tpo = tp;
- (void)check_widgets(acts_win, 0, 0, 0, M_HOLD);
- }
- } else if (action == -1) {
- /* Sleep until next X event */
- fd_set readfds;
-
- FD_ZERO(&readfds);
- FD_SET(xfd, &readfds);
-
- (void)select(xfd+1, &readfds, NULL, NULL, NULL);
- }
-
- if (action != -1 && animate_obj()) {
- static struct timeval tp, tpo;
- static struct timezone tzp;
- static int totaldiff = 0;
- static boolean started = FALSE;
- int difft;
-
- /* Get time the first time through */
- if (!started) {
- gettimeofday(&tp, &tzp);
- started = TRUE;
- }
- tpo = tp;
-
- gettimeofday(&tp, &tzp);
-
- difft = (tp.tv_sec - tpo.tv_sec) * 1000000 + (tp.tv_usec - tpo.tv_usec);
-
- if (difft < MIN_DIFFT)
- difft = MIN_DIFFT;
-
- if (difft > 0) {
- totaldiff += difft;
-
- /* Do updates over 30 frames per second (to make it smooth) */
- if (totaldiff > 20000) {
- totaldiff = 0;
- review_system(FALSE);
- XSync(dpy, False);
- }
- }
- }
- }
-
- return TRUE;
- }
-
- Pixmap get_pixmap(bits, width, height, inv)
- char *bits;
- int width, height;
- boolean inv;
- {
- int black, white;
-
- black = inv ? 1 : 0;
- white = inv ? 0 : 1;
-
- return XCreatePixmapFromBitmapData(dpy, main_win, bits, width, height, white, black, 1);
- }
-
- unsigned long GetColor(cname, cmap)
- char *cname;
- Colormap cmap;
- {
- /* Color stuff */
- XColor xc;
-
- if (XParseColor(dpy, cmap, cname, &xc) == 0) {
- fprintf(stderr, "Unknown color: %s\n", cname);
- exit(-1);
- } else {
- if (XAllocColor(dpy, cmap, &xc) == 0) {
- fprintf(stderr, "Cannot allocate color: %s\n", cname);
- exit(-1);
- }
- }
-
- return xc.pixel;
- }
-
- static void init_x(argc, argv, displayname, geometry, fgcolor, bgcolor, hlcolor)
- int argc;
- char *argv[];
- char *displayname, *geometry, *fgcolor, *bgcolor, *hlcolor;
- {
- XGCValues gcv, gcmv;
- XSetWindowAttributes xswa;
- XSizeHints hints;
- XFontStruct *font;
- Cursor cross;
- Colormap cmap;
- Pixmap icon_p;
- Visual *vis;
- int scn;
- int mask = 0;
-
- /* Open display */
- if ((dpy = XOpenDisplay(displayname)) == NULL) {
- fprintf(stderr, "Could not open display\n");
- exit(-1);
- }
-
- /* Get screen and colors */
- scn = DefaultScreen(dpy);
- planes = DisplayPlanes(dpy, scn);
- cmap = DefaultColormap(dpy, scn);
- vis = DefaultVisual(dpy, scn);
- xfd = ConnectionNumber(dpy);
-
- if (hlcolor == NULL) {
- if (vis->class == StaticGray || vis->class == GrayScale) {
- hlcolor = fgcolor;
- } else {
- XColor xc;
-
- if (XParseColor(dpy, cmap, HLCOLOR, &xc) == 0) {
- hlcolor = fgcolor;
- } else {
- hlcolor = HLCOLOR;
- }
- }
- }
-
- fcolor = GetColor(fgcolor, cmap);
- bcolor = GetColor(bgcolor, cmap);
- hcolor = GetColor(hlcolor, cmap);
-
- /* Set up main window */
- main_wid = hints.width = M_WID + 2;
- hints.min_width = B_WID * 2;
- main_ht = hints.height = hints.min_height = M_HT + 2;
- hints.flags = PSize | PMinSize;
-
- /* Get geometry info */
- if (geometry != NULL) {
- hints.x = hints.y = 0;
-
- if (mask = XParseGeometry(geometry, &(hints.x), &(hints.y), &(hints.width), &(hints.height))) {
- hints.flags |= ((mask & (XValue | YValue)) ? USPosition: PPosition) |
- ((mask & (WidthValue | HeightValue)) ? USSize : PSize);
-
- if (hints.width < hints.min_width)
- hints.width = hints.min_width;
- if (hints.height < hints.min_height)
- hints.height = hints.min_height;
- }
- }
-
- /* Create main window */
- main_win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), hints.x, hints.y, hints.width, hints.height, 1, fcolor, bcolor);
-
- /* Fix for open-look wm (thanks to Brian.Warkentine@Eng.Sun.COM) */
- {
- XWMHints wmhints;
- XWindowAttributes xwa;
-
- wmhints.flags = InputHint;
- wmhints.input = True;
- (void) XGetWindowAttributes(dpy, main_win, &xwa);
- XSelectInput(dpy, main_win, xwa.all_event_masks | KeyPressMask);
- XSetWMHints(dpy, main_win, &wmhints);
- }
-
- icon_p = XCreatePixmapFromBitmapData(dpy, DefaultRootWindow(dpy), icon_bits, icon_width, icon_height, 1, 0, planes);
- XSetStandardProperties(dpy, main_win, "XSpringies", "XSpringies", icon_p, argv, argc, &hints);
-
- if (mask)
- XSetNormalHints(dpy, main_win, &hints);
-
- /* Map main window to display */
- XMapWindow(dpy, main_win);
-
- XFlush(dpy);
- XSync(dpy, False);
-
- {
- Window tmp_win;
- int xpos, ypos;
- unsigned int bw, dep;
-
- XGetGeometry(dpy, main_win, &tmp_win, &xpos, &ypos, &main_wid, &main_ht, &bw, &dep);
- }
-
- /* Make subwindows */
- acts_win = XCreateSimpleWindow(dpy, main_win, 0, 0, B_WID, B_HT, 1, fcolor, bcolor);
-
- draw_wid = main_wid - B_WID - 1;
- draw_ht = main_ht - T_HT - 1;
- draw_win = XCreateSimpleWindow(dpy, main_win, B_WID + 1, 0, draw_wid, draw_ht, 1, fcolor, bcolor);
- text_win = XCreateSimpleWindow(dpy, main_win, B_WID + 1, draw_ht + 1, draw_wid, T_HT, 1, fcolor, bcolor);
-
- /* Make pixmaps for drawing and actions areas (to make redraw trivial) */
- draw_pm = XCreatePixmap(dpy, draw_win, draw_wid, draw_ht, 1);
-
- acts_pm = XCreatePixmap(dpy, acts_win, B_WID, B_HT, 1);
-
- /* Get a font */
- if ((font = XLoadQueryFont(dpy, F_NAME)) == NULL) {
- fprintf(stderr, "Could not load font: %s\n", F_NAME);
- exit(-1);
- }
-
- /* Create GCs */
- gcmv.font = gcv.font = font->fid;
- gcmv.plane_mask = gcv.plane_mask = 1;
- gcmv.line_width = spthick;
-
- gcmv.foreground = 1;
- gcmv.background = 0;
-
- gcv.foreground = bcolor;
- gcv.background = hcolor;
- revgc = XCreateGC(dpy, main_win, GCForeground | GCBackground | GCFont, &gcv);
-
- gcv.foreground = hcolor;
- gcv.background = bcolor;
- hlgc = XCreateGC(dpy, main_win, GCForeground | GCBackground | GCFont, &gcv);
-
- gcv.foreground = fcolor;
- drawgc = XCreateGC(dpy, draw_pm, GCForeground | GCBackground | GCFont, &gcmv);
- sdrawgc = XCreateGC(dpy, draw_pm, GCForeground | GCBackground | GCFont | GCLineWidth, &gcmv);
- fggc = XCreateGC(dpy, main_win, GCForeground | GCBackground | GCFont, &gcv);
-
- {
- static char stipple_bits[] = { 0x01, 0x02 };
- static char dot_line[2] = { 1, 1 };
- Pixmap stip;
-
- stip = XCreateBitmapFromData(dpy, main_win, stipple_bits, 2, 2);
- gcmv.stipple = gcv.stipple = stip;
- gcmv.fill_style = gcv.fill_style = FillStippled;
-
- gcmv.line_style = gcv.line_style = LineOnOffDash;
- selectgc = XCreateGC(dpy, draw_pm, GCForeground | GCBackground | GCFont | GCFillStyle | GCStipple, &gcmv);
- selectlinegc = XCreateGC(dpy, draw_pm, GCForeground | GCBackground | GCFont | GCLineStyle | GCLineWidth, &gcmv);
-
- gcv.foreground = hcolor;
-
- if (hcolor != fcolor && hcolor != bcolor) {
- selectboxgc = XCreateGC(dpy, main_win, GCForeground | GCBackground | GCFont, &gcv);
- } else {
- selectboxgc = XCreateGC(dpy, main_win, GCForeground | GCBackground | GCFont | GCLineStyle, &gcv);
- XSetDashes(dpy, selectboxgc, 0, dot_line, 2);
- }
-
- XSetDashes(dpy, selectlinegc, 0, dot_line, 2);
- }
-
- gcv.foreground = gcv.background = bcolor;
- gcmv.foreground = gcmv.background = 0;
- erasegc = XCreateGC(dpy, draw_pm, GCForeground | GCBackground | GCFont, &gcmv);
- bggc = XCreateGC(dpy, main_win, GCForeground | GCBackground | GCFont, &gcv);
-
- /* Clear out action pixmap */
- XFillRectangle(dpy, acts_pm, erasegc, 0, 0, B_WID, B_HT);
-
- startup_pm = get_pixmap(startup_bits, startup_width, startup_height, FALSE);
- draw_startup_picture();
-
- /* Use a cross cursor for the draw window */
- cross = XCreateFontCursor(dpy, XC_tcross);
-
- /* Set window event masks and other attributes */
- xswa.event_mask = ExposureMask | StructureNotifyMask;
- XChangeWindowAttributes(dpy, main_win, CWEventMask, &xswa);
-
- xswa.event_mask = KeyPressMask | ExposureMask;
- XChangeWindowAttributes(dpy, text_win, CWEventMask, &xswa);
-
- xswa.event_mask = ButtonPressMask | ButtonReleaseMask | Button1MotionMask | Button2MotionMask | Button3MotionMask | KeyPressMask | ExposureMask;
- XChangeWindowAttributes(dpy, acts_win, CWEventMask, &xswa);
- xswa.cursor = cross;
- XChangeWindowAttributes(dpy, draw_win, CWEventMask | CWCursor, &xswa);
-
- XMapWindow(dpy, draw_win);
- XMapWindow(dpy, text_win);
- XMapWindow(dpy, acts_win);
-
- XFlush(dpy);
- }
-
- static void make_widgets()
- {
- int i, y;
-
- {
- Pixmap title_pm = get_pixmap(title_bits, title_width, title_height, FALSE);
- XCopyArea(dpy, title_pm, acts_pm, drawgc, 0, 0, title_width, title_height, 4, 4);
- XFreePixmap(dpy, title_pm);
- }
-
- add_modebutton(acts_pm, acts_win, B_WID/2, 4, B_WID-6, 54, "Edit", edit_bits, edit_width, edit_height, M_EDIT, &mode, FALSE);
- add_modebutton(acts_pm, acts_win, 4, 54, B_WID/2, 104, "Mass", mass_bits, mass_width, mass_height, M_MASS, &mode, FALSE);
- add_modebutton(acts_pm, acts_win, B_WID/2, 54, B_WID-6, 104, "Spring", spring_bits, spring_width, spring_height, M_SPRING, &mode, FALSE);
-
- add_slider(acts_pm, acts_win, 4, 110, B_WID-6, 125, "Mass", "%10.2lf", S_MASS, &(mst.cur_mass), 10000000.0, 0.01, 0.01);
- add_slider(acts_pm, acts_win, 4, 127, B_WID-6, 142, "Elasticity", "%10.3lf", S_ELAS, &(mst.cur_rest), 1.0, 0.0, 0.001);
- add_slider(acts_pm, acts_win, 4, 144, B_WID-6, 159, "Kspring", "%10.2lf", S_KSPR, &(mst.cur_ks), 10000000.0, 0.01, 0.01);
- add_slider(acts_pm, acts_win, 4, 161, B_WID-6, 176, "Kdamp", "%10.2lf", S_KDAMP, &(mst.cur_kd), 10000000.0, 0.0, 0.01);
-
- add_checkbox(acts_pm, acts_win, 4, 178, B_WID/2-16, 194, "Fixed Mass", C_FIXEDMASS, &(mst.fix_mass));
- add_checkbox(acts_pm, acts_win, B_WID/2, 178, B_WID-6, 194, "Show Springs", C_SHOWSPRING, &(mst.show_spring));
-
- add_button(acts_pm, acts_win, 4, 197, B_WID/2 + 10, 217, "Set Rest Length", B_RESTLEN);
- add_button(acts_pm, acts_win, B_WID/2 + 16, 197, B_WID-6, 217, "Set Center", B_CENTER);
-
- y = 228;
- XDrawLine(dpy, acts_pm, drawgc, 0, y-4, B_WID-1, y-4);
- y++;
-
- for (i = 0; i < BF_NUM; i++) {
- mst.bf_mode[i] = -1;
- add_modebutton(acts_pm, acts_win, i*(BF_SIZ+4)+4, y, 4+(i+1)*(BF_SIZ+4),y+BF_SIZ+4,"", b_bits[i], BF_SIZ, BF_SIZ, M_BF + i, &(mst.bf_mode[i]), TRUE);
- }
- force_liney = y;
-
- add_modebutton(acts_pm, acts_win, 132, y, 136+go_width, y+4+go_height, "", go_bits, go_width, go_height, M_ACTION, &action, TRUE);
-
- y += 36;
- add_slider(acts_pm, acts_win, 4, y, B_WID-6, y+15, "", "%10.2lf", S_GRAV, &(mst.cur_grav_val[0]), cur_grav_max[0], cur_grav_min[0], 0.01);
- grav_slidx = 4;
- grav_slidy = (y + y+15 + F_HT) / 2 - 2;
-
- add_slider(acts_pm, acts_win, 4, y+17, B_WID-6, y+32, "", "%10.2lf", S_GDIR, &(mst.cur_grav_val[0]), cur_misc_max[0], cur_misc_min[0], 0.05);
-
- dir_slidx = 4;
- dir_slidy = (y+17 + y+32 + F_HT) / 2 - 2;
- update_slidnum(0);
-
- y += 38;
- XDrawLine(dpy, acts_pm, drawgc, 0, y - 4, B_WID-1, y - 4);
-
- add_slider(acts_pm, acts_win, 4, y, B_WID-6, y+15, "Viscosity", "%10.2lf", S_VISC, &(mst.cur_visc), 10000000.0, 0.0, 0.01);
- add_slider(acts_pm, acts_win, 4, y+17, B_WID-6, y+32, "Stickiness", "%10.2lf", S_STICK, &(mst.cur_stick), 10000000.0, 0.0, 0.01);
-
- y = y + 37;
-
- XDrawLine(dpy, acts_pm, drawgc, 0, y - 4, B_WID-1, y - 4);
-
- add_slider(acts_pm, acts_win, 4, y, B_WID-6, y+15, "Time Step", "%10.4lf", S_TIMESTEP, &(mst.cur_dt), 1.0, 0.0001, 0.0001);
- add_slider(acts_pm, acts_win, 4, y+17, B_WID-6, y+32, "Precision", "%10.4lf", S_PRECISION, &(mst.cur_prec), 1000.0, 0.0001, 0.0001);
- add_checkbox(acts_pm, acts_win, 4, y+33, B_WID/2+32, y+49, "Adaptive Time Step", C_ADAPTIVE_STEP, &(mst.adaptive_step));
-
- y = y + 54;
- XDrawLine(dpy, acts_pm, drawgc, 0, y-4, B_WID-1, y-4);
-
- add_slider(acts_pm, acts_win, 4, y, B_WID/2 + 20, y+16, "", "%10.0lf", S_GRIDSNAP, &(mst.cur_gsnap), 200.0, 1.0, 1.0);
- add_checkbox(acts_pm, acts_win, B_WID/2 + 24, y, B_WID - 4, y+16, "Grid Snap", C_GRIDSNAP, &(mst.grid_snap));
-
- y = y + 2;
- XDrawRectangle(dpy, acts_pm, drawgc, 16, y+24, 64, 30);
- add_checkbox(acts_pm, acts_win, 40, y+18, 56, y+33, "", C_WTOP, &(mst.w_top));
- add_checkbox(acts_pm, acts_win, 8, y+33, 24, y+48, " Walls", C_WLEFT, &(mst.w_left));
- add_checkbox(acts_pm, acts_win, 72, y+33, 88, y+48, "", C_WRIGHT, &(mst.w_right));
- add_checkbox(acts_pm, acts_win, 40, y+48, 56, y+63, "", C_WBOTTOM, &(mst.w_bottom));
-
- y = y + 16;
- add_button(acts_pm, acts_win, B_WID/2+3, y, B_WID-6, y+20, "Delete", B_DELETE);
- add_button(acts_pm, acts_win, B_WID/2+3, y+25, B_WID-6, y+45, "Select all", B_SELECTALL);
-
- y = y + 52;
- XDrawLine(dpy, acts_pm, drawgc, 0, y-3, B_WID-1, y-3);
-
- add_button(acts_pm, acts_win, 4, y, B_WID/2-5, y+20, "Save State", B_SAVESTATE);
- add_button(acts_pm, acts_win, B_WID/2+3, y, B_WID-6, y+20, "Restore State", B_RESSTATE);
- add_button(acts_pm, acts_win, 4, y+25, B_WID/2-5, y+45, "Duplicate", B_DUPLICATE);
- add_button(acts_pm, acts_win, B_WID/2+3, y+25, B_WID-6, y+45, "Insert File", B_INSERTFILE);
-
- add_button(acts_pm, acts_win, 4, y+50, B_WID/2-5, y+70, "Load File", B_LOADFILE);
- add_button(acts_pm, acts_win, B_WID/2+3, y+50, B_WID-6, y+70, "Save File", B_SAVEFILE);
- add_button(acts_pm, acts_win, 4, y+75, B_WID/2-5, y+95, "Reset", B_RESET);
- add_button(acts_pm, acts_win, B_WID/2+3, y+75, B_WID-6, y+95, "Quit", B_QUIT);
-
- slid_dt_num = slider_valno(S_TIMESTEP);
- }
-
- void usage()
- {
- static char *msg1 = "Usage: xspringies [-d|display displayname] [-geometry geom] [-rv]\n";
- static char *msg2 = " [-bg color] [-fg color] [-hl color] [-st int] [-nbb]\n";
-
- fprintf(stderr, msg1);
- fprintf(stderr, msg2);
- exit(-1);
- }
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char *swch, *displayname = NULL, *geometry = NULL, *bgcolor = "black", *fgcolor = "white", *hlcolor = NULL;
- boolean rev_vid = FALSE;
- extern char *getenv();
- char *path;
-
- initst = sst = mst;
-
- if ((path = getenv("SPRINGDIR")) != NULL) {
- strcpy(filename, path);
- } else {
- strcpy(filename, DEF_PATH);
- }
-
- while (--argc > 0) {
- if (**++argv == '-') {
- swch = (*argv) + 1;
-
- if (!strcmp(swch, "display") || !strcmp(swch, "d")) {
- if (--argc > 0) {
- displayname = *++argv;
- } else {
- usage();
- }
- } else if (!strcmp(swch, "geometry")) {
- if (--argc > 0) {
- geometry = *++argv;
- } else {
- usage();
- }
- } else if (!strcmp(swch, "rv")) {
- rev_vid = TRUE;
- } else if (!strcmp(swch, "bg")) {
- if (--argc > 0) {
- bgcolor = *++argv;
- } else {
- usage();
- }
- } else if (!strcmp(swch, "fg")) {
- if (--argc > 0) {
- fgcolor = *++argv;
- } else {
- usage();
- }
- } else if (!strcmp(swch, "hl")) {
- if (--argc > 0) {
- hlcolor = *++argv;
- } else {
- usage();
- }
- } else if (!strcmp(swch, "st")) {
- if (--argc > 0) {
- spthick = atoi(*++argv);
- if (spthick < 0) {
- fprintf(stderr, "String thickness value must be non-negative\n");
- exit(-1);
- }
- } else {
- usage();
- }
- } else if (!strcmp(swch, "nbb")) {
- bboxing = FALSE;
- } else {
- usage();
- }
- } else {
- usage();
- }
- }
-
- if (rev_vid) {
- char *swap = fgcolor;
-
- fgcolor = bgcolor;
- bgcolor = swap;
- }
-
- init_x(argc, argv, displayname, geometry, fgcolor, bgcolor, hlcolor);
-
- init_widgets(widget_notify);
- make_widgets();
-
- init_objects();
-
- while (x_event());
-
- clean_up();
- return 0;
- }
- \BARFOO\
- else
- echo "will not over write ./xdisp.c"
- fi
- echo "Finished archive 2 of 16"
- exit
-
- exit 0 # Just in case...
- --
- // chris@IMD.Sterling.COM | Send comp.sources.x submissions to:
- \X/ Amiga - The only way to fly! |
- "It's intuitively obvious to the most | sources-x@imd.sterling.com
- casual observer..." |
-