/* Enhanced Be-Guiled version of the program */
#include <unistd.h>
#include <X11/Xlib.h>
#define WINDOW_SIZE 500
#include <libguile.h>
Display *theDisplay;
Window theWindow;
Screen *theScreen;
GC theGC;
double currentX;
double currentY;
double currentDirection;
int penDown;
#include <math.h>
#define DEGREES_TO_RADIANS (3.1415926535897932384626433832795029L/180.0)
SCM tortoise_reset()
{
currentX = currentY = WINDOW_SIZE/2;
currentDirection = 0;
penDown = 1;
return SCM_UNSPECIFIED;
}
SCM tortoise_pendown()
{
int prevValue = penDown;
penDown = 1;
return (prevValue ? SCM_BOOL_T: SCM_BOOL_F);
}
SCM tortoise_penup()
{
int prevValue = penDown;
penDown = 0;
return (prevValue ? SCM_BOOL_T: SCM_BOOL_F);
}
SCM tortoise_turn(SCM s_degrees)
{
int prevValue = (int)currentDirection;
double degrees;
degrees = scm_num2dbl(s_degrees, "tortoise-turn");
currentDirection += degrees;
return SCM_MAKINUM(prevValue);
}
SCM tortoise_move(SCM s_steps)
{
double oldX = currentX;
double oldY = currentY;
double newX, newY;
double steps;
steps = scm_num2dbl(s_steps, "tortoise-move");
/* first work out the new endpoint */
newX = currentX + sin(currentDirection*DEGREES_TO_RADIANS)*steps;
newY = currentY - cos(currentDirection*DEGREES_TO_RADIANS)*steps;
/* if the pen is down, draw a line */
if (penDown) XDrawLine(theDisplay, theWindow, theGC,
(int)currentX, (int)currentY, (int)newX, (int)newY);
/* in either case, move the tortoise */
currentX = newX;
currentY = newY;
return scm_cons(scm_make_real(oldX) , scm_cons(scm_make_real(oldY), SCM_EOL));
}
void register_procs(void)
{
scm_c_define_gsubr("tortoise-reset", 0, 0, 0, tortoise_reset);
scm_c_define_gsubr("tortoise-pendown", 0, 0, 0, tortoise_pendown);
scm_c_define_gsubr("tortoise-penup", 0, 0, 0, tortoise_penup);
scm_c_define_gsubr("tortoise-turn", 1, 0, 0, tortoise_turn);
scm_c_define_gsubr("tortoise-move", 1, 0, 0, tortoise_move);
}
void inner_main(void *closure, int argc, char **argv)
{
register_procs();
scm_shell(argc, argv);
}
int main(int argc, char *argv[])
{
theDisplay = XOpenDisplay(NULL);
XSynchronize(theDisplay, True);
theScreen = DefaultScreenOfDisplay(theDisplay);
theWindow = XCreateSimpleWindow(theDisplay, RootWindowOfScreen(theScreen),
0, 0,
WINDOW_SIZE, WINDOW_SIZE, 0,
BlackPixelOfScreen(theScreen),
WhitePixelOfScreen(theScreen));
theGC = XCreateGC(theDisplay, theWindow, 0L, NULL);
XSetForeground(theDisplay, theGC, BlackPixelOfScreen(theScreen));
XMapWindow(theDisplay,theWindow);
/* more stuff to come here . . */
tortoise_reset();
scm_boot_guile(argc, argv, inner_main, 0);
return(0); /* never reached */
return 0;
}