home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CICA 1995 May
/
cica_0595_4.zip
/
cica_0595_4
/
UTIL
/
MSWSRC35
/
GRAPHICS.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-25
|
28KB
|
1,314 lines
/*
* graphics.c logo graphics module mak
*
* Copyright (C) 1989 The Regents of the University of California
* This Software may be copied and distributed for educational,
* research, and not for profit purposes provided that this
* copyright and statement are included in all such copies.
*
*/
#include "logo.h"
/* #include "globals.h" has been moved further down */
#include <math.h>
#ifdef mac
#include "macterm.h"
#else
#ifdef ibm
#ifdef __ZTC__
#include <fg.h>
#include "ztcterm.h"
#else
//ggm#include "ibmterm.h"
#endif
#else
#ifdef x_window
#include "xgraphics.h"
#else
#include "nographics.h"
#endif
#endif
#endif
#include "globals.h"
#ifdef __ZTC__
#define total_turtle_bottom_max (-(MaxY/2))
#else
#define total_turtle_bottom_max turtle_bottom_max
#endif
extern int status_flag;
/* NOTE: See the files (macterm.c and macterm.h) or (ibmterm.c and ibmterm.h)
for examples of the functions and macros that this file assumes exist. */
mode_type current_mode = wrapmode;
FLONUM turtle_x = 0.0, turtle_y = 0.0, turtle_heading = 0.0;
BOOLEAN turtle_shown = TRUE;
FLONUM x_scale = 1.0, y_scale = 1.0;
FLONUM wanna_x = 0.0, wanna_y = 0.0;
BOOLEAN out_of_bounds = FALSE;
//char record[GR_SIZE];
int record_index = 0;
pen_info orig_pen;
int forward_count = 0;
BOOLEAN record_next_move = FALSE, refresh_p = TRUE;
/************************************************************/
double pfmod(double x, double y) {
double temp = fmod(x,y);
if (temp < 0) return temp+y;
return temp;
}
FLONUM cut_error(FLONUM n)
{
n *= 1000000.0;
n = (n > 0.0 ? floor(n) : ceil(n));
n /= 1000000.0;
if (n == -0.0) n = 0.0;
return(n);
}
FIXNUM g_round(FLONUM n)
{
n += (n < 0.0 ? -0.5 : 0.5);
if (n < 0.0)
return((FIXNUM)ceil(n));
return((FIXNUM)floor(n));
}
/************************************************************/
void draw_turtle()
{
if (turtle_shown) ibmturt(0);
return;
draw_turtle_helper();
/* all that follows is for "turtle wrap" effect */
if ((turtle_y > turtle_top_max - turtle_height) &&
(current_mode == wrapmode)) {
turtle_y -= (screen_height + 1);
draw_turtle_helper();
check_x_high();
check_x_low();
turtle_y += (screen_height + 1);
}
if ((turtle_y < turtle_bottom_max + turtle_height) &&
(current_mode == wrapmode)) {
turtle_y += (screen_height + 1);
draw_turtle_helper();
check_x_high();
check_x_low();
turtle_y -= (screen_height + 1);
}
check_x_high();
check_x_low();
}
void check_x_high()
{
if ((turtle_x > turtle_right_max - turtle_height) &&
(current_mode == wrapmode)) {
turtle_x -= (screen_width + 1);
draw_turtle_helper();
turtle_x += (screen_width + 1);
}
}
void check_x_low()
{
if ((turtle_x < turtle_left_max + turtle_height) &&
(current_mode == wrapmode)) {
turtle_x += (screen_width + 1);
draw_turtle_helper();
turtle_x -= (screen_width + 1);
}
}
void draw_turtle_helper()
{
ibmturt(0);
}
/*
draw_turtle_helper()
{
pen_info saved_pen;
FLONUM real_heading;
int left_x, left_y, right_x, right_y, top_x, top_y, center_x, center_y;
prepare_to_draw;
prepare_to_draw_turtle;
save_pen(&saved_pen);
plain_xor_pen();
pen_vis = 0;
real_heading = -turtle_heading + 90.0;
center_x = screen_right/2;
#ifdef __ZTC__
center_y = MaxY/2;
#else
center_y = screen_bottom/2;
#endif
left_x = g_round(turtle_x + x_scale*(FLONUM)(cos((FLONUM)((real_heading + 90.0)*degrad))*turtle_half_bottom));
left_y = g_round(turtle_y + y_scale*(FLONUM)(sin((FLONUM)((real_heading + 90.0)*degrad))*turtle_half_bottom));
right_x = g_round(turtle_x + x_scale*(FLONUM)(cos((FLONUM)((real_heading - 90.0)*degrad))*turtle_half_bottom));
right_y = g_round(turtle_y + y_scale*(FLONUM)(sin((FLONUM)((real_heading - 90.0)*degrad))*turtle_half_bottom));
top_x = g_round(turtle_x + x_scale*(FLONUM)(cos((FLONUM)(real_heading*degrad))*turtle_side));
top_y = g_round(turtle_y + y_scale*(FLONUM)(sin((FLONUM)(real_heading*degrad))*turtle_side));
move_to(center_x + left_x, center_y - left_y);
line_to(center_x + top_x, center_y - top_y);
move_to(center_x + right_x, center_y - right_y);
line_to(center_x + top_x, center_y - top_y);
move_to(center_x + left_x, center_y - left_y);
line_to(center_x + right_x, center_y - right_y);
restore_pen(&saved_pen);
done_drawing_turtle;
done_drawing;
}
*/
/************************************************************/
void right(FLONUM a)
{
draw_turtle();
turtle_heading += a;
turtle_heading = pfmod(turtle_heading,360.0);
if (status_flag) update_status_turtleheading();
draw_turtle();
}
NODE *numeric_arg(NODE *args)
{
NODE *arg = car(args), *val;
val = cnv_node_to_numnode(arg);
while (val == UNBOUND && NOT_THROWING) {
gcref(val);
setcar(args, err_logo(BAD_DATA, arg));
arg = car(args);
val = cnv_node_to_numnode(arg);
}
setcar(args,val);
return(val);
}
NODE *lright(NODE *arg)
{
NODE *val;
FLONUM a;
val = numeric_arg(arg);
if (NOT_THROWING) {
if (nodetype(val) == INT)
a = (FLONUM)getint(val);
else
a = getfloat(val);
right(a);
}
return(UNBOUND);
}
NODE *lleft(NODE *arg)
{
NODE *val;
FLONUM a;
val = numeric_arg(arg);
if (NOT_THROWING) {
if (nodetype(val) == INT)
a = (FLONUM)getint(val);
else
a = getfloat(val);
right(-a);
}
return(UNBOUND);
}
NODE *larc(NODE *arg)
{
NODE *val1;
NODE *val2;
FLONUM angle;
FLONUM radius;
FLONUM ang;
FLONUM tx;
FLONUM ty;
// FLONUM oldx;
// FLONUM oldy;
FLONUM x;
FLONUM y;
FLONUM count;
FLONUM delta;
FLONUM i;
int turtle_state;
int pen_state;
/* get args */
val1 = numeric_arg(arg);
val2 = numeric_arg(cdr(arg));
if (NOT_THROWING) {
if (nodetype(val1) == INT)
angle = (FLONUM)getint(val1);
else
angle = getfloat(val1);
if (nodetype(val2) == INT)
radius = (FLONUM)getint(val2);
else
radius = getfloat(val2);
prepare_to_draw;
draw_turtle();
/* save and force turle state */
turtle_state = turtle_shown;
turtle_shown = 0;
/* grab things before they change and use for restore */
ang = turtle_heading;
tx = turtle_x;
ty = turtle_y;
/* calculate resolution parameters */
count = abs(angle*radius/200.0);
delta = angle/count;
/* draw each line segment of arc (will do wrap) */
for (i=0.0;i<=count;i=i+1.0)
{
/* calc x y */
x = -sin(ang*3.141592654/180.0)*radius;
y = -cos(ang*3.141592654/180.0)*radius;
/* jump to begin of first line segment without drawing */
if (i==0.0)
{
pen_state = pen_vis;
pen_vis = 1;
setpos_helper(make_floatnode(tx+x), make_floatnode(ty+y));
pen_vis = pen_state;
}
/* else do segment */
else
{
setpos_helper(make_floatnode(tx+x), make_floatnode(ty+y));
}
ang = ang + delta;
}
/* assure we draw something and end in the exact right place */
x = -sin((turtle_heading+angle)*3.141592654/180.0)*radius;
y = -cos((turtle_heading+angle)*3.141592654/180.0)*radius;
setpos_helper(make_floatnode(tx+x), make_floatnode(ty+y));
/* restore state */
turtle_shown = turtle_state;
turtle_x = tx;
turtle_y = ty;
draw_turtle();
done_drawing;
wanna_x = turtle_x;
wanna_y = turtle_y;
out_of_bounds = FALSE;
}
return(UNBOUND);
}
void forward(FLONUM d)
{
prepare_to_draw;
draw_turtle();
forward_helper(d);
draw_turtle();
done_drawing;
wanna_x = turtle_x;
wanna_y = turtle_y;
out_of_bounds = FALSE;
}
void forward_helper(FLONUM d)
{
FLONUM real_heading, dx, dy, x1, y1, x2, y2;
// FLONUM intercept;
if (forward_count++ > 32) return;
real_heading = -turtle_heading + 90.0;
x1 = screen_x_coord;
y1 = screen_y_coord;
dx = (FLONUM)(cos((FLONUM)(real_heading*degrad))*d*x_scale);
dy = (FLONUM)(sin((FLONUM)(real_heading*degrad))*d*y_scale);
x2 = x1 + dx;
y2 = y1 - dy;
move_to(g_round(x1), g_round(y1));
if (record_next_move) {
save_move();
record_next_move = FALSE;
}
if (check_throwing) return;
if (current_mode == windowmode ||
(x2 >= screen_left && x2 <= screen_right &&
y2 >= screen_top && y2 <= screen_bottom)) {
turtle_x = turtle_x + dx;
turtle_y = turtle_y + dy;
line_to(g_round(x2), g_round(y2));
save_line();
}
else
if (!wrap_right(d, x1, y1, x2, y2))
if (!wrap_left(d, x1, y1, x2, y2))
if (!wrap_up(d, x1, y1, x2, y2))
wrap_down(d, x1, y1, x2, y2);
forward_count--;
}
int wrap_right(FLONUM d, FLONUM x1, FLONUM y1, FLONUM x2, FLONUM y2)
{
FLONUM yi;
if (x2 > screen_right) {
yi = ((y2 - y1)/(x2 - x1)) * (screen_right - x1) + y1;
if (yi >= screen_top && yi <= screen_bottom) {
line_to(screen_right, g_round(yi));
save_line();
record_next_move = TRUE;
turtle_x = turtle_left_max;
turtle_y = -yi;
if (current_mode == wrapmode) {
forward_helper(d * ((x2 - screen_right)/(x2 - x1)));
return(1);
}
turtle_x = turtle_right_max;
err_logo(TURTLE_OUT_OF_BOUNDS, NIL);
}
}
return(0);
}
int wrap_left(FLONUM d, FLONUM x1, FLONUM y1, FLONUM x2, FLONUM y2)
{
FLONUM yi;
if (x2 < screen_left) {
yi = ((y2 - y1)/(x1 - x2)) * (x1 - screen_left) + y1;
if (yi >= screen_top && yi <= screen_bottom) {
line_to(screen_left, g_round(yi));
save_line();
record_next_move = TRUE;
turtle_x = turtle_right_max;
turtle_y = -yi;
if (current_mode == wrapmode) {
forward_helper(d * ((screen_left - x2)/(x1 - x2)));
return(1);
}
turtle_x = turtle_left_max;
err_logo(TURTLE_OUT_OF_BOUNDS, NIL);
}
}
return(0);
}
int wrap_up(FLONUM d, FLONUM x1, FLONUM y1, FLONUM x2, FLONUM y2)
{
FLONUM xi;
if (y2 < screen_top) {
xi = ((x2 - x1)/(y1 - y2)) * (y1 - screen_top) + x1;
if (xi >= screen_left && xi <= screen_right) {
line_to(g_round(xi), screen_top);
save_line();
record_next_move = TRUE;
turtle_x = xi;
turtle_y = -turtle_bottom_max;
if (current_mode == wrapmode) {
forward_helper(d * ((screen_top - y2)/(y1 - y2)));
return(1);
}
turtle_y = -turtle_top_max;
err_logo(TURTLE_OUT_OF_BOUNDS, NIL);
}
}
return(0);
}
int wrap_down(FLONUM d, FLONUM x1, FLONUM y1, FLONUM x2, FLONUM y2)
{
FLONUM xi;
if (y2 > screen_bottom) {
xi = ((x2 - x1)/(y2 - y1)) * (screen_bottom - y1) + x1;
if (xi >= screen_left && xi <= screen_right) {
line_to(g_round(xi), screen_bottom);
save_line();
record_next_move = TRUE;
turtle_x = xi;
turtle_y = -turtle_top_max;
if (current_mode == wrapmode) {
forward_helper(d * ((y2 - screen_bottom)/(y2 - y1)));
return(1);
}
turtle_y = -turtle_bottom_max;
err_logo(TURTLE_OUT_OF_BOUNDS, NIL);
}
}
return(0);
}
NODE *lforward(NODE *arg)
{
NODE *val;
FLONUM d;
val = numeric_arg(arg);
if (NOT_THROWING) {
if (nodetype(val) == INT)
d = (FLONUM)getint(val);
else
d = getfloat(val);
forward(d);
}
return(UNBOUND);
}
NODE *lback(NODE *arg)
{
NODE *val;
FLONUM d;
val = numeric_arg(arg);
if (NOT_THROWING) {
if (nodetype(val) == INT)
d = (FLONUM)getint(val);
else
d = getfloat(val);
forward(-d);
}
return(UNBOUND);
}
NODE *lshowturtle()
{
prepare_to_draw;
if (!turtle_shown) {
turtle_shown = TRUE;
if (status_flag) update_status_turtlevisability();
draw_turtle();
}
done_drawing;
return(UNBOUND);
}
NODE *lhideturtle()
{
prepare_to_draw;
if (turtle_shown) {
draw_turtle();
turtle_shown = FALSE;
if (status_flag) update_status_turtlevisability();
}
done_drawing;
return(UNBOUND);
}
NODE *lshownp()
{
return(turtle_shown ? Truex : Falsex);
}
NODE *lsetheading(NODE *arg)
{
NODE *val;
val = numeric_arg(arg);
if (NOT_THROWING) {
draw_turtle();
if (nodetype(val) == INT)
turtle_heading = (FLONUM)getint(val);
else
turtle_heading = getfloat(val);
turtle_heading = pfmod(turtle_heading,360.0);
if (status_flag) update_status_turtleheading();
draw_turtle();
}
return(UNBOUND);
}
NODE *lheading()
{
return(make_floatnode(turtle_heading));
}
NODE *vec_arg_helper(NODE *args, BOOLEAN floatok)
{
NODE *arg = car(args), *val1, *val2;
while (NOT_THROWING) {
if (arg != NIL &&
is_list(arg) &&
cdr(arg) != NIL &&
cddr(arg) == NIL) {
val1 = cnv_node_to_numnode(car(arg));
val2 = cnv_node_to_numnode(cadr(arg));
if (val1 != UNBOUND && val2 != UNBOUND &&
(floatok || (nodetype(val1) == INT && getint(val1) >= 0 &&
nodetype(val2) == INT && getint(val2) >= 0))) {
setcar(arg, val1);
setcar(cdr(arg), val2);
return(arg);
}
gcref(val1);
gcref(val2);
}
setcar(args, err_logo(BAD_DATA, arg));
arg = car(args);
}
return(UNBOUND);
}
NODE *vec_3_arg_helper(NODE *args, BOOLEAN floatok)
{
NODE *arg = car(args), *val1, *val2, *val3;
while (NOT_THROWING) {
if (arg != NIL &&
is_list(arg) &&
cdr(arg) != NIL &&
cddr(arg) != NIL &&
cddr(cdr(arg)) == NIL) {
val1 = cnv_node_to_numnode(car(arg));
val2 = cnv_node_to_numnode(cadr(arg));
val3 = cnv_node_to_numnode(cadr(cdr(arg)));
if (val1 != UNBOUND && val2 != UNBOUND && val3 != UNBOUND &&
(floatok || (nodetype(val1) == INT && getint(val1) >= 0 &&
nodetype(val2) == INT && getint(val2) >= 0 &&
nodetype(val3) == INT && getint(val3) >= 0))) {
setcar(arg, val1);
setcar(cdr(arg), val2);
setcar(cddr(arg), val3);
return(arg);
}
gcref(val1);
gcref(val2);
gcref(val3);
}
setcar(args, err_logo(BAD_DATA, arg));
arg = car(args);
}
return(UNBOUND);
}
NODE *vector_arg(NODE *args) {
return vec_arg_helper(args,TRUE);
}
NODE *pos_int_vector_arg(NODE *args) {
return vec_arg_helper(args,FALSE);
}
NODE *pos_int_vector_3_arg(NODE *args) {
return vec_3_arg_helper(args,FALSE);
}
FLONUM towards_helper(FLONUM x, FLONUM y, FLONUM from_x, FLONUM from_y)
{
FLONUM m, a, tx, ty;
tx = from_x/x_scale;
ty = from_y/y_scale;
if (x != tx || y != ty) {
if (x == tx)
a = (y < ty) ? -90 : 90;
else {
m = (y - ty)/(x - tx);
a = atan(m)/degrad;
if (x < tx) a = fmod(a + 180.0,360.0);
}
return -(a - 90.0);
}
return(0.0);
}
NODE *ltowards(NODE *args)
{
NODE *xnode, *ynode = UNBOUND, *arg;
FLONUM x, y;
arg = vector_arg(args);
if (NOT_THROWING) {
xnode = car(arg);
ynode = cadr(arg);
x = ((nodetype(xnode) == FLOAT) ? getfloat(xnode) :
(FLONUM)getint(xnode));
y = ((nodetype(ynode) == FLOAT) ? getfloat(ynode) :
(FLONUM)getint(ynode));
return make_floatnode(towards_helper(x, y, turtle_x, turtle_y));
}
return(UNBOUND);
}
NODE *lpos()
{
return(cons(make_floatnode(cut_error(turtle_x/x_scale)),
cons(make_floatnode(cut_error(turtle_y/y_scale)), NIL)));
}
NODE *lscrunch()
{
return(cons(make_floatnode(x_scale), cons(make_floatnode(y_scale), NIL)));
}
NODE *lhome()
{
out_of_bounds = FALSE;
setpos_helper(make_intnode((FIXNUM)0), make_intnode((FIXNUM)0));
draw_turtle();
turtle_heading = 0.0;
draw_turtle();
return(UNBOUND);
}
void cs_helper(int centerp)
{
prepare_to_draw;
clear_screen;
if (centerp) {
wanna_x = wanna_y = turtle_x = turtle_y = turtle_heading = 0.0;
if (status_flag)
{
update_status_turtleheading();
update_status_turtleposition();
}
out_of_bounds = FALSE;
}
draw_turtle();
save_pen(&orig_pen);
p_info_x(orig_pen) = g_round(screen_x_coord);
p_info_y(orig_pen) = g_round(screen_y_coord);
record_index = 0;
done_drawing;
}
NODE *lclearscreen()
{
cs_helper(TRUE);
return(UNBOUND);
}
NODE *lclean()
{
cs_helper(FALSE);
return(UNBOUND);
}
void setpos_helper(NODE *xnode, NODE *ynode)
{
FLONUM target_x, target_y, scaled_x, scaled_y, tx, ty, save_heading;
BOOLEAN wrapping = FALSE;
if (NOT_THROWING) {
prepare_to_draw;
draw_turtle();
move_to(g_round(screen_x_coord), g_round(screen_y_coord));
target_x = ((xnode == NIL) ?
turtle_x :
((nodetype(xnode) == FLOAT) ? getfloat(xnode) :
(FLONUM)getint(xnode)));
target_y = ((ynode == NIL) ?
turtle_y :
((nodetype(ynode) == FLOAT) ? getfloat(ynode) :
(FLONUM)getint(ynode)));
scaled_x = target_x * x_scale;
scaled_y = target_y * y_scale;
wrapping = scaled_x > turtle_right_max || scaled_x < turtle_left_max ||
scaled_y < turtle_top_max || scaled_y > turtle_bottom_max;
if (current_mode == fencemode && wrapping)
err_logo(TURTLE_OUT_OF_BOUNDS, NIL);
else if (current_mode == wrapmode && (wrapping || out_of_bounds)) {
save_heading = turtle_heading;
turtle_heading = towards_helper(target_x, target_y,
wanna_x, wanna_y);
tx = wanna_x/x_scale;
ty = wanna_y/y_scale;
#define sq(z) ((z)*(z))
forward_helper(sqrt(sq(target_x - tx) + sq(target_y - ty)));
turtle_heading = save_heading;
wanna_x = scaled_x;
wanna_y = scaled_y;
out_of_bounds = wrapping;
}
else {
wanna_x = turtle_x = scaled_x;
wanna_y = turtle_y = scaled_y;
out_of_bounds = FALSE;
line_to(g_round(screen_x_coord), g_round(screen_y_coord));
save_line();
}
done_drawing;
draw_turtle();
}
}
NODE *lsetpos(NODE *args)
{
NODE *arg = vector_arg(args);
if (NOT_THROWING) {
setpos_helper(car(arg), cadr(arg));
}
return(UNBOUND);
}
NODE *lsetxy(NODE *args)
{
NODE *xnode, *ynode;
xnode = numeric_arg(args);
ynode = numeric_arg(cdr(args));
if (NOT_THROWING) {
setpos_helper(xnode, ynode);
}
return(UNBOUND);
}
NODE *lsetx(NODE *args)
{
NODE *xnode;
xnode = numeric_arg(args);
if (NOT_THROWING) {
setpos_helper(xnode, NIL);
}
return(UNBOUND);
}
NODE *lsety(NODE *args)
{
NODE *ynode;
ynode = numeric_arg(args);
if (NOT_THROWING) {
setpos_helper(NIL, ynode);
}
return(UNBOUND);
}
NODE *lwrap()
{
if (turtle_shown) draw_turtle();
current_mode = wrapmode;
if (turtle_shown) draw_turtle();
return(UNBOUND);
}
NODE *lfence()
{
if (turtle_shown) draw_turtle();
current_mode = fencemode;
if (turtle_shown) draw_turtle();
return(UNBOUND);
}
NODE *lwindow()
{
if (turtle_shown) draw_turtle();
current_mode = windowmode;
if (turtle_shown) draw_turtle();
return(UNBOUND);
}
NODE *lfill()
{
if (turtle_shown) draw_turtle();
logofill();
if (turtle_shown) draw_turtle();
return(UNBOUND);
}
NODE *llabel(NODE *arg)
{
char textbuf[MAX_BUFFER_SIZE];
// short theLength;
print_stringptr = textbuf;
print_stringlen = MAX_BUFFER_SIZE;
ndprintf((FILE *)NULL,"%p",car(arg));
*print_stringptr = '\0';
if (NOT_THROWING) {
draw_turtle();
#ifdef x_window
label(textbuf, strlen(textbuf));
#else
#ifdef mac
theLength = strlen(textbuf);
c_to_pascal_string(textbuf, theLength);
#endif
label(textbuf);
save_string(textbuf);
record_next_move = TRUE;
#endif
draw_turtle();
}
return(UNBOUND);
}
NODE *ltextscreen()
{
text_screen;
return(UNBOUND);
}
NODE *lsplitscreen()
{
split_screen;
return(UNBOUND);
}
NODE *lfullscreen()
{
full_screen;
return(UNBOUND);
}
NODE *lpendownp()
{
return(pen_vis == 0 ? Truex : Falsex);
}
NODE *lpenmode()
{
return(get_node_pen_mode);
}
NODE *lpensize()
{
return(cons(make_intnode((FIXNUM)pen_width),
cons(make_intnode((FIXNUM)pen_height), NIL)));
}
NODE *lpenpattern()
{
return(get_node_pen_pattern);
}
NODE *lpendown()
{
pen_vis = 0;
save_vis();
return(UNBOUND);
}
NODE *lpenup()
{
if (pen_vis == 0)
pen_vis--;
save_vis();
return(UNBOUND);
}
NODE *lpenpaint()
{
pen_down;
save_mode();
return(lpendown());
}
NODE *lpenerase()
{
pen_erase;
save_mode();
return(lpendown());
}
NODE *lpenreverse()
{
pen_reverse;
save_mode();
return(lpendown());
}
NODE *lsetpencolor(NODE *args)
{
NODE *arg = pos_int_vector_3_arg(args);
if (NOT_THROWING) {
prepare_to_draw;
set_pen_color(getint(car(arg)),getint(cadr(arg)),getint(cadr(cdr(arg))));
save_color_pen();
}
return(UNBOUND);
}
NODE *lsetfloodcolor(NODE *args)
{
NODE *arg = pos_int_vector_3_arg(args);
if (NOT_THROWING) {
set_flood_color(getint(car(arg)),getint(cadr(arg)),getint(cadr(cdr(arg))));
save_color_flood();
}
return(UNBOUND);
}
NODE *lsetscreencolor(NODE *args)
{
NODE *arg = pos_int_vector_3_arg(args);
if (NOT_THROWING) {
set_screen_color(getint(car(arg)),getint(cadr(arg)),getint(cadr(cdr(arg))));
save_color_screen();
}
return(UNBOUND);
}
NODE *lsetpensize(NODE *args)
{
NODE *arg = pos_int_vector_arg(args);
if (NOT_THROWING) {
prepare_to_draw;
set_pen_width((int)getint(car(arg)));
set_pen_height((int)getint(cadr(arg)));
save_size();
}
return(UNBOUND);
}
NODE *lsetpenpattern(NODE *args)
{
NODE *arg;
arg = car(args);
ref(arg);
while ((arg == NIL || !is_list(arg)) && NOT_THROWING)
arg = reref(arg, err_logo(BAD_DATA, arg));
if (NOT_THROWING) {
prepare_to_draw;
set_list_pen_pattern(arg);
save_pattern();
}
deref(arg);
return(UNBOUND);
}
NODE *lsetscrunch(NODE *args)
{
NODE *xnode, *ynode;
xnode = numeric_arg(args);
ynode = numeric_arg(cdr(args));
if (NOT_THROWING) {
prepare_to_draw;
if (turtle_shown) {
draw_turtle();
}
x_scale = (nodetype(xnode) == FLOAT) ? getfloat(xnode) :
(FLONUM)getint(xnode);
y_scale = (nodetype(ynode) == FLOAT) ? getfloat(ynode) :
(FLONUM)getint(ynode);
if (turtle_shown) {
draw_turtle();
}
done_drawing;
#ifdef __ZTC__
{
FILE *fp = fopen("scrunch.dat","w");
if (fp != NULL) {
fwrite(&x_scale, sizeof(FLONUM), 1, fp);
fwrite(&y_scale, sizeof(FLONUM), 1, fp);
fclose(fp);
}
}
#endif
}
return(UNBOUND);
}
//NODE *lmousepos()
//{
// return(cons(make_intnode(mouse_x), cons(make_intnode(mouse_y), NIL)));
//}
NODE *lbuttonp()
{
if (button)
return(Truex);
return(Falsex);
}
NODE *ltone(NODE *args)
{
NODE *p, *d;
FIXNUM pitch, duration;
p = numeric_arg(args);
d = numeric_arg(cdr(args));
if (NOT_THROWING) {
pitch = (nodetype(p) == FLOAT) ? (FIXNUM)getfloat(p) : getint(p);
duration = (nodetype(d) == FLOAT) ? (FIXNUM)getfloat(d) : getint(d);
tone(pitch, duration);
}
return(UNBOUND);
}
/************************************************************/
/* The rest of this file implements the recording of moves in
the graphics window and the playing back of those moves. It's
needed on machines like the Macintosh where the contents of the
graphics window can get erased and need to be redrawn. On
machines where no graphics redrawing is necessary, set the size
of the recording buffer to 1 in logo.h. */
BOOLEAN safe_to_save()
{
/*
return(refresh_p && record_index < (GR_SIZE - 300));
*/
return(1);
}
void save_lm_helper ()
{
/*
*(int *)(record + record_index + 2) = pen_x;
*(int *)(record + record_index + 4) = pen_y;
record_index += 6;
*/
}
void save_line()
{
if (status_flag) update_status_turtleposition();
/*
if (safe_to_save()) {
record[record_index] = LINEXY;
save_lm_helper();
}
*/
}
void save_move()
{
if (status_flag) update_status_turtleposition();
/*
if (safe_to_save()) {
record[record_index] = MOVEXY;
save_lm_helper();
}
*/
}
void save_vis()
{
if (status_flag) update_status_pencontact();
/*
if (safe_to_save()) {
record[record_index] = SETPENVIS;
record[record_index + 1] = (char)pen_vis;
record_index += 2;
}
*/
}
void save_mode()
{
if (status_flag) update_status_penstyle();
/*
if (safe_to_save()) {
record[record_index] = SETPENMODE;
#ifdef x_window
*(GC *)(record + record_index + 2) = pen_mode;
#else
*(int *)(record + record_index + 2) = pen_mode;
#endif
record_index += 4;
}
*/
}
void save_color_pen()
{
if (status_flag) update_status_pencolor();
/*
if (safe_to_save()) {
record[record_index] = SETPENCOLOR;
*(long *)(record + record_index + 2) = pen_color;
record_index += 6;
}
*/
}
void save_color_screen()
{
if (status_flag) update_status_screencolor();
/*
if (safe_to_save()) {
record[record_index] = SETPENCOLOR;
*(long *)(record + record_index + 2) = pen_color;
record_index += 6;
}
*/
}
void save_color_flood()
{
if (status_flag) update_status_floodcolor();
/*
if (safe_to_save()) {
record[record_index] = SETPENCOLOR;
*(long *)(record + record_index + 2) = pen_color;
record_index += 6;
}
*/
}
void save_size()
{
if (status_flag) update_status_penwidth();
/*
if (safe_to_save()) {
record[record_index] = SETPENSIZE;
*(int *)(record + record_index + 2) = pen_width;
*(int *)(record + record_index + 4) = pen_height;
record_index += 6;
}
*/
}
void save_pattern()
{
// if (status_flag) update_status(SETPENPATTERN);
/*
int count;
if (safe_to_save()) {
record[record_index] = SETPENPATTERN;
get_pen_pattern(&record[record_index + 2]);
record_index += 10;
}
*/
}
void save_string(char s[])
{
/*
int count;
if (safe_to_save()) {
record[record_index] = LABEL;
record[record_index + 2] = s[0];
for (count = 0; count < s[0]; count++)
record[record_index + 3 + count] = s[1 + count];
record_index += 3 + s[0] + even_p(s[0]);
}
*/
}
NODE *lrefresh()
{
refresh_p = TRUE;
return(UNBOUND);
}
NODE *lnorefresh()
{
refresh_p = FALSE;
return(UNBOUND);
}
void redraw_graphics()
{
}
/* This is called when the graphics coordinate system has been shifted.
It adds a constant amount to each x and y coordinate in the record. */
void resize_record(int dh, int dv)
{
/*
int r_index = 0;
p_info_x(orig_pen) += dh;
p_info_y(orig_pen) += dv;
while (r_index < record_index)
switch (record[r_index]) {
case (LINEXY) :
*(int *)(record + r_index + 2) += dh;
*(int *)(record + r_index + 4) += dv;
r_index += 6;
break;
case (MOVEXY) :
*(int *)(record + r_index + 2) += dh;
*(int *)(record + r_index + 4) += dv;
r_index += 6;
break;
case (LABEL) :
r_index += 3 + record[r_index + 2] + even_p(record[r_index + 2]);
break;
case (SETPENVIS) :
r_index += 2;
break;
case (SETPENMODE) :
r_index += 4;
break;
case (SETPENCOLOR) :
r_index += 6;
break;
case (SETPENSIZE) :
r_index += 6;
break;
case (SETPENPATTERN) :
r_index += 10;
break;
}
*/
}