static char sccsid[] = "@(#)xengine.c 1.10 10/2/90";
/*
* xengine - reciprocating engine for X :-)
*
* Author: Kazuhiko Shutoh, 1990.
*
* Permission to use, copy, modify and distribute without charge this software,
* documentation, images, etc. is granted, provided that this comment and the
* author's name is retained. The author assumes no responsibility for lost
* sleep as a consequence of use of this software.
*
* Send any comments, bug reports, etc. to: shutoh@isl.yamaha.JUNET or, for
* oversea: shutoh%isl.yamaha.JUNET%kddlab@uunet.uu.net
*
*/
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Xaw/Box.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/AsciiText.h>
#include <X11/Xaw/Cardinals.h>
#include <X11/Xos.h>
#include <stdio.h>
#include <math.h>
#include "patchlevel.h"
#define PI 3.141592654
XtCallbackProc redraw_callback();
XtTimerCallbackProc Cylcle();
Widget toplevel, base, rpm_info, engine;
GC gcPiston, gcShaft, gcCylinder, gcRoter, gcBack, gcDep, gcPre, gcEngine;
Pixmap enginePixmap;
int width, height;
String colors[] = {"gray", "lightseagreen", "dimgrey", "forestgreen", "black", "red", "cyan", "firebrick"};
main(argc, argv)
int argc;
char **argv;
{
Arg args[10];
XtTranslations newTranslations;
static XtActionsRec redrawActions[] = {
{"expose", (XtCallbackProc) redraw_callback},
};
static char *overrideTranslations =
"<Expose>: expose() \n\
<ResReq>: expose()";
XColor srcColor, dummyColor;
int i;
int count;
XtTimerCallbackProc Cycle();
toplevel = XtInitialize("xengine", "XEngine", NULL, 0, &argc, argv);
for (count = 1; count < argc; count++) {
if ((strcmp("-piston", argv[count]) == 0) && (count + 1 <= argc))
strcpy(colors[0], argv[++count]);
else if ((strcmp("-shaft", argv[count]) == 0) && (count + 1 <= argc))
strcpy(colors[1], argv[++count]);
else if ((strcmp("-cylinder", argv[count]) == 0) && (count + 1 <= argc))
strcpy(colors[2], argv[++count]);
else if ((strcmp("-roter", argv[count]) == 0) && (count + 1 <= argc))
strcpy(colors[3], argv[++count]);
else if ((strcmp("-back", argv[count]) == 0) && (count + 1 <= argc))
strcpy(colors[4], argv[++count]);
else if ((strcmp("-dep", argv[count]) == 0) && (count + 1 <= argc))
strcpy(colors[5], argv[++count]);
else if ((strcmp("-pre", argv[count]) == 0) && (count + 1 <= argc))
strcpy(colors[6], argv[++count]);
else if ((strcmp("-patchlevel", argv[count]) == 0) && (count + 1 <= argc))
{
printf("xengine - written by Kazuhiko Shutoh\nSCCS ID : %s\nPatchlevel : %d\n", sccsid, PATCHLEVEL);
exit(0);
}
else if ((strcmp("-mono", argv[count]) == 0) && (count + 1 <= argc)) {
for (i = 0; i < 8; i++)
strcpy(colors[i], "white");
strcpy(colors[4], "black");
} else {
fprintf(stderr, "Usage : xengine [Toolkit-Options][-piston piston_color][-shaft shaft_color][-cylinder cylinder_color][-roter roter_color][-back background_color][-dep depression_colore][-pre pression color][-mono][-patchlevel]\n");
exit(0);
}
}
base = XtCreateManagedWidget("base", formWidgetClass, toplevel, NULL, 0);
i = 0;
XtSetArg(args[i], XtNwidth, 200);
i++;
XtSetArg(args[i], XtNheight, 200);
i++;
engine = XtCreateManagedWidget("engine", boxWidgetClass, base, args, i);
width = height = 200;
i = 0;
XtSetArg(args[i], XtNfromHoriz, engine);
i++;
XtSetArg(args[i], XtNheight, 200);
i++;
rpm_info = XtCreateManagedWidget("rpm_info", asciiTextWidgetClass, base, args, i);
XtAddActions(redrawActions, XtNumber(redrawActions));
newTranslations = XtParseTranslationTable(overrideTranslations);
XtOverrideTranslations(engine, newTranslations);
XtRealizeWidget(toplevel);
/* Get graphic context */
gcPiston = XCreateGC(XtDisplay(engine), XtWindow(engine), (unsigned long) 0, NULL);
XAllocNamedColor(XtDisplay(engine), DefaultColormapOfScreen(XtScreen(engine)), colors[0], &srcColor, &dummyColor);
XSetForeground(XtDisplay(engine), gcPiston, srcColor.pixel);
gcShaft = XCreateGC(XtDisplay(engine), XtWindow(engine), (unsigned long) 0, NULL);
XAllocNamedColor(XtDisplay(engine), DefaultColormapOfScreen(XtScreen(engine)), colors[1], &srcColor, &dummyColor);
XSetForeground(XtDisplay(engine), gcShaft, srcColor.pixel);
XSetLineAttributes(XtDisplay(engine), gcShaft, 2, LineSolid, CapButt, JoinMiter);
gcCylinder = XCreateGC(XtDisplay(engine), XtWindow(engine), (unsigned long) 0, NULL);
XSetGraphicsExposures(XtDisplay(engine), gcCylinder, False);
XAllocNamedColor(XtDisplay(engine), DefaultColormapOfScreen(XtScreen(engine)), colors[2], &srcColor, &dummyColor);
XSetForeground(XtDisplay(engine), gcCylinder, srcColor.pixel);
gcRoter = XCreateGC(XtDisplay(engine), XtWindow(engine), (unsigned long) 0, NULL);
XAllocNamedColor(XtDisplay(engine), DefaultColormapOfScreen(XtScreen(engine)), colors[3], &srcColor, &dummyColor);
XSetForeground(XtDisplay(engine), gcRoter, srcColor.pixel);
gcBack = XCreateGC(XtDisplay(engine), XtWindow(engine), (unsigned long) 0, NULL);
XAllocNamedColor(XtDisplay(engine), DefaultColormapOfScreen(XtScreen(engine)), colors[4], &srcColor, &dummyColor);
XSetForeground(XtDisplay(engine), gcBack, srcColor.pixel);
gcDep = XCreateGC(XtDisplay(engine), XtWindow(engine), (unsigned long) 0, NULL);
XAllocNamedColor(XtDisplay(engine), DefaultColormapOfScreen(XtScreen(engine)), colors[5], &srcColor, &dummyColor);
XSetForeground(XtDisplay(engine), gcDep, srcColor.pixel);
gcPre = XCreateGC(XtDisplay(engine), XtWindow(engine), (unsigned long) 0, NULL);
XAllocNamedColor(XtDisplay(engine), DefaultColormapOfScreen(XtScreen(engine)), colors[6], &srcColor, &dummyColor);
XSetForeground(XtDisplay(engine), gcPre, srcColor.pixel);
gcEngine = XCreateGC(XtDisplay(engine), XtWindow(engine), (unsigned long) 0, NULL);
XAllocNamedColor(XtDisplay(engine), DefaultColormapOfScreen(XtScreen(engine)), colors[7], &srcColor, &dummyColor);
XSetForeground(XtDisplay(engine), gcEngine, srcColor.pixel);
/* Create engine Pixmap */
enginePixmap = XCreatePixmap(XtDisplay(engine), XtWindow(engine), width, height, DefaultDepthOfScreen(XtScreen(engine)));
/* Interval timer start */
XtAddTimeOut(1, Cycle, NULL);
XtMainLoop();
}
XtCallbackProc
redraw_callback(w, event, params, nparams)
Widget w;
XEvent *event;
String *params;
Cardinal *nparams;
{
Arg args[10];
XtSetArg(args[0], XtNwidth, &width);
XtSetArg(args[1], XtNheight, &height);
XtGetValues(w, args, 2);
XFreePixmap(XtDisplay(engine), enginePixmap);
enginePixmap = XCreatePixmap(XtDisplay(engine), XtWindow(engine), width, height, DefaultDepthOfScreen(XtScreen(engine)));
}
XtTimerCallbackProc
Cycle(client_data, id)
caddr_t client_data;
XtIntervalId id;
{
Arg args[10];
static char label[256];
char tmp_str[16];
static int i = 0;
static int sample_count = 0;
static double mean = 0.0;
double DrawEngine();
if (i++ > 10) {
sprintf(tmp_str, "%4.1f rpm\n", mean / 10.0);
if (sample_count++ > 14) {
strcpy(label, "");
sample_count = 0;
}
strcat(label, tmp_str);
XtSetArg(args[0], XtNstring, label);
XtSetValues(rpm_info, args, 1);
i = 0;
mean = 0.0;
}
mean += DrawEngine();
XtAddTimeOut(1, Cycle, NULL);
}
double
DrawEngine()
{
double cycle;
static int sw = 1;
double angle, theta;
double piston_x1, piston_y1;
double piston_x2, piston_y2;
struct timeval start, end;
struct timezone dummy;
sw ^= 1;
XSync(XtDisplay(engine), 0);
gettimeofday(&start, &dummy);
for (angle = -180; angle < 180; angle += 18) {
theta = angle * (PI / 180.0);
piston_x1 = sin(theta) * (width * 0.1) + (width / 2);
piston_y1 = cos(theta) * (height * 0.1) + (height * 0.7);
piston_x2 = width / 2;
piston_y2 = piston_y1 - (height * 0.3);
/* Crear Window */
XFillRectangle(XtDisplay(engine), enginePixmap, gcBack, 0, 0, width, height);
/* Draw heat sink */
XFillRectangle(XtDisplay(engine), enginePixmap, gcEngine,
(int) (width * 0.35), (int) (height * 0.3),
(int) (width * 0.3), (int) (height * 0.02));
XFillRectangle(XtDisplay(engine), enginePixmap, gcEngine,
(int) (width * 0.35), (int) (height * 0.35),
(int) (width * 0.3), (int) (height * 0.02));
XFillRectangle(XtDisplay(engine), enginePixmap, gcEngine,
(int) (width * 0.35), (int) (height * 0.4),
(int) (width * 0.3), (int) (height * 0.02));
/* Draw Cylinder */
XFillRectangle(XtDisplay(engine), enginePixmap, gcEngine,
(int) (width * 0.42), (int) (height * 0.24),
(int) (width * 0.16), (int) (height * 0.5));
XFillArc(XtDisplay(engine), enginePixmap, gcEngine,
(int) (piston_x2 - (width * 0.15)), (int) ((height * 0.7) - (height * 0.15)), (int) (width * 0.3), (int) (height * 0.3), 0 * 64, 360 * 64);
XFillArc(XtDisplay(engine), enginePixmap, gcBack,
(int) (piston_x2 - (width * 0.14)), (int) ((height * 0.7) - (height * 0.14)), (int) (width * 0.28), (int) (height * 0.28), 0 * 64, 360 * 64);
XFillRectangle(XtDisplay(engine), enginePixmap, gcBack,
(int) (width * 0.43), (int) (height * 0.25),
(int) (width * 0.14), (int) (height * 0.5));
/* Draw Gas */
if (sw != 0) {
XFillRectangle(XtDisplay(engine), enginePixmap, gcPre,
(int) (width * 0.435), (int) (height * 0.25),
(int) (width * 0.13), (int) (piston_y2 - (height * 0.05) - (height * 0.26) + (height * 0.1)));
} else {
XFillRectangle(XtDisplay(engine), enginePixmap, gcDep,
(int) (width * 0.435), (int) (height * 0.25),
(int) (width * 0.13), (int) (piston_y2 - (height * 0.05) - (height * 0.26) + (height * 0.1)));
}
/* Draw Piston arm */
XDrawLine(XtDisplay(engine), enginePixmap, gcShaft,
(int) piston_x1, (int) piston_y1, (int) piston_x2, (int) piston_y2);
XDrawLine(XtDisplay(engine), enginePixmap, gcShaft,
(int) piston_x1, (int) piston_y1, (int) piston_x2, (int) (height * 0.7));
/* Draw Piston & ring */
XFillRectangle(XtDisplay(engine), enginePixmap, gcPiston,
(int) (width * 0.435), (int) (piston_y2 - (height * 0.05)),
(int) (width * 0.13), (int) (height * 0.1));
XFillRectangle(XtDisplay(engine), enginePixmap, gcShaft,
(int) (width * 0.435), (int) (piston_y2 - (height * 0.045)),
(int) (width * 0.13), (int) (height * 0.01));
XFillArc(XtDisplay(engine), enginePixmap, gcShaft,
(int) (piston_x2 - (width * 0.015)), (int) (piston_y2 - (height * 0.015)), (int) (width * 0.03), (int) (height * 0.03), 0, 360 * 64);
/* Draw Roter */
XFillArc(XtDisplay(engine), enginePixmap, gcRoter,
(int) (piston_x2 - (width * 0.1)), (int) ((height * 0.7) - (height * 0.1)), (int) (width * 0.2), (int) (height * 0.2), (int) (angle + 30) * 64, 120 * 64);
XFillArc(XtDisplay(engine), enginePixmap, gcPiston,
(int) (piston_x2 - (width * 0.025)), (int) ((height * 0.7) - (height * 0.025)), (int) (width * 0.05), (int) (height * 0.05), 0, 360 * 64);
XCopyArea(XtDisplay(engine), enginePixmap, XtWindow(engine), gcCylinder, 0, 0, width, height, 0, 0);
}
XSync(XtDisplay(engine), 0);
gettimeofday(&end, &dummy);
cycle = 60 / ((double) ((end.tv_sec * 1000000 + end.tv_usec) - (start.tv_sec * 1000000 + start.tv_usec)) / 1000000);
return (cycle);
}
syntax highlighted by Code2HTML, v. 0.9.1