/* "WOL", an integrated circuit layout tool, Copyright (C) 1983, 1990 California Institute of Technology. Author: Massimo Sivilotti Thanks to: Glenn Gribble, Marty Sirkin, Sylvie Rychebusch Maryann Mayer, Carver Mead, Rick Koshi, Torre Lande Maintainer: John Lazzaro Maintainers's address: lazzaro@hobiecat.cs.caltech.edu; CB 425/ CU Boulder/Boulder CO 91125. Send questions, bug fixes, to this address. This program 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 (Version 1, 1989). This program 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 this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Output from p2c, the Pascal-to-C translator */ /* p2c: wolopt.text, line 9: Note: Range checking is OFF [216] */ /* p2c: wolopt.text, line 10: Note: Stack checking is OFF [217] */ /* p2c: wolopt.text, line 16: Note: Range checking is ON [216] */ /* From input file "wol_route.text" */ /* Change these for testing */ #include "global.h" #define WOL_ROUTE_G #include "wol_route.h" Static boolean point_in(routing *rt, point pt) { boolean temp; temp = false; if (rt == NULL) return temp; if (rt->pt1.x == pt.x && rt->pt1.y == pt.y || rt->pt2.x == pt.x && rt->pt2.y == pt.y) temp = true; else temp = point_in(rt->to_point, pt); return temp; } Local point get_newpoint(point pt, short layer) { /* draws a little line from pt to pen; when pen is depressed. That point is returned. */ point Result, lam_pt, old_point, screen_start; tablet_info tp_d, old_tp_d; lam_pt = pt; screen_start = scale_up(lam_pt); old_point = screen_start; old_tp_d.x = INFIN; old_tp_d.y = INFIN; do { tp_d = check_pen(); tp_d = scale(tp_d, 3); if (tp_d.x != old_tp_d.x || tp_d.y != old_tp_d.y) { old_tp_d = tp_d; xor_on(); /* next two set_layers used to be set_layer (layer) */ set_layer(layer); m_move(screen_start.x, screen_start.y); /* erase old wire segment */ m_draw(old_point.x, old_point.y); old_point = scale_up(scale_down(change_to_point(tp_d.x, tp_d.y))); set_layer(layer); m_move(screen_start.x, screen_start.y); /* draw new wire segment */ m_draw(old_point.x, old_point.y); } } while (!tp_d.depressed); Result = scale_down(change_to_point(tp_d.x, tp_d.y)); /* set_layer (old_layer); */ debounce(); xor_off(); return Result; } Local boolean point_on_segment(point pt, routing *seg) { boolean Result; Result = false; if (seg->pt1.x == seg->pt2.x && seg->pt1.x == pt.x && (seg->pt1.y >= pt.y && pt.y >= seg->pt2.y || seg->pt1.y <= pt.y && pt.y <= seg->pt2.y)) Result = true; if (seg->pt1.y == seg->pt2.y && seg->pt1.y == pt.y && (seg->pt1.x >= pt.x && pt.x >= seg->pt2.x || seg->pt1.x <= pt.x && pt.x <= seg->pt2.x)) return true; return Result; } Local boolean pt_equals(point pt1, point pt2) { return (pt1.x == pt2.x && pt1.y == pt2.y); } void edit_routing_wire(point pt) { point lam_pt, newpoint; routing *rt, *seg, *last_seg; long layer, old_layer; boolean done; lam_pt = scale_down(pt); rt = comp_cells->routing_; if (manhattan_routing) { done = false; while (rt != NULL && !done) { /* Search all the wires. */ if (pt_equals(lam_pt, rt->pt1)) { /* Special case: end point */ done = true; newpoint = get_newpoint(lam_pt, rt->layer); if (rt->pt1.x == rt->pt2.x) { rt->pt2.x = newpoint.x; if (rt->to_point != NULL) rt->to_point->pt1.x = newpoint.x; } else if (rt->pt1.y == rt->pt2.y) { rt->pt2.y = newpoint.y; if (rt->to_point != NULL) rt->to_point->pt1.y = newpoint.y; } rt->pt1 = newpoint; } else { last_seg = NULL; seg = rt; while (seg != NULL && !done) { /* Search the segments. */ if (seg->to_point == NULL && pt_equals(lam_pt, seg->pt2)) { /* Special case: end point */ done = true; newpoint = get_newpoint(lam_pt, seg->layer); if (seg->pt1.x == seg->pt2.x) { seg->pt1.x = newpoint.x; if (last_seg != NULL) last_seg->pt2.x = newpoint.x; } else if (seg->pt1.y == seg->pt2.y) { seg->pt1.y = newpoint.y; if (last_seg != NULL) last_seg->pt2.y = newpoint.y; } seg->pt2 = newpoint; } else if (point_on_segment(lam_pt, seg)) { done = true; newpoint = get_newpoint(lam_pt, rt->layer); if (seg->pt1.x == seg->pt2.x) { if (last_seg != NULL) last_seg->pt2.x = newpoint.x; seg->pt1.x = newpoint.x; seg->pt2.x = newpoint.x; if (seg->to_point != NULL) seg->to_point->pt1.x = newpoint.x; } else if (seg->pt1.y == seg->pt2.y) { if (last_seg != NULL) last_seg->pt2.y = newpoint.y; seg->pt1.y = newpoint.y; seg->pt2.y = newpoint.y; if (seg->to_point != NULL) seg->to_point->pt1.y = newpoint.y; } } last_seg = seg; seg = seg->to_point; } } rt = rt->next; } if (done && auto_refresh) show_comp(); return; } /* Old non-manhattan editing. */ while (rt != NULL && !point_in(rt, lam_pt)) rt = rt->next; if (!point_in(rt, lam_pt)) /* now go down the wire segment list */ return; old_layer = curr_layer; layer = curr_layer; /* so that the edited line is drawn correctly */ if (rt->pt1.x == lam_pt.x && rt->pt1.y == lam_pt.y) { /* the point is the first in the line */ newpoint = get_newpoint(lam_pt, rt->layer); rt->pt1 = newpoint; if (auto_refresh) show_comp(); } else { while (rt->pt2.x != lam_pt.x || rt->pt2.y != lam_pt.y) /* until we find the point */ rt = rt->to_point; newpoint = get_newpoint(lam_pt, rt->layer); if (rt->to_point == NULL) { /* it is the last point in line */ rt->pt2 = newpoint; if (auto_refresh) show_comp(); } else { /* update two segments */ rt->pt2 = newpoint; rt->to_point->pt1 = newpoint; if (auto_refresh) show_comp(); } } comp_cells->modified = true; } /* Local variables for draw_routing_wire: */ struct LOC_draw_routing_wire { point lambda_start; } ; Local void new_wire(point endpt, struct LOC_draw_routing_wire *LINK) { /* add a new line segment to the routing list */ routing *old_rt, *WITH; /* endpt := scale_down (endpt); */ old_rt = comp_cells->routing_; comp_cells->routing_ = get_routing_node(); WITH = comp_cells->routing_; WITH->pt1 = LINK->lambda_start; WITH->pt2 = endpt; WITH->layer = curr_layer; WITH->width = wire_width; WITH->to_point = NULL; WITH->next = old_rt; comp_cells->modified = true; } Local void addline(point endpt, struct LOC_draw_routing_wire *LINK) { /* add a new segment to the wire hanging off of comp_cells^.data^.routing */ routing *rt, *WITH; /* endpt := scale_down (endpt); */ rt = comp_cells->routing_; while (rt->to_point != NULL) rt = rt->to_point; rt->to_point = get_routing_node(); WITH = rt->to_point; WITH->pt1 = LINK->lambda_start; WITH->pt2 = endpt; WITH->layer = curr_layer; WITH->width = wire_width; WITH->to_point = NULL; WITH->next = NULL; comp_cells->modified = true; } /*******************************************************************************/ void draw_routing_wire(point start) { struct LOC_draw_routing_wire V; point lambda_old_point, old_point, screen_start, tp_lam; tablet_info tp_d, old_tp_d; boolean first_segment; V.lambda_start = scale_down(start); lambda_old_point = V.lambda_start; screen_start = scale_up(V.lambda_start); old_point = screen_start; first_segment = true; old_tp_d.x = INFIN; old_tp_d.y = INFIN; /* writeln ('wire started: ',lambda_start.x:1,' ', lambda_start.y:1); */ do { tp_d = check_pen(); screen_start = scale_up(V.lambda_start); /*$if false$ if manhattan_routing then begin if (abs (tp_d.x - screen_start.x) - abs(tp_d.y - screen_start.y)) > 0 then { preserve y-coord } tp_d.y := screen_start.y else { preserve x-coord } tp_d.x := screen_start.x; end; tp_d := scale(tp_d,3); $end$*/ tp_lam = scale_down(change_to_point(tp_d.x, tp_d.y)); tp_d.x = scale_up(tp_lam).x; tp_d.y = scale_up(tp_lam).y; if (manhattan_routing) { if (labs(tp_d.x - screen_start.x) - labs(tp_d.y - screen_start.y) > 0) { /* preserve y-coord */ tp_d.y = screen_start.y; } else /* preserve x-coord */ tp_d.x = screen_start.x; } if (tp_d.x != old_tp_d.x || tp_d.y != old_tp_d.y) { xor_on(); set_layer(curr_layer); screen_start = scale_up(V.lambda_start); m_move(screen_start.x, screen_start.y); /* erase old wire segment */ old_point = scale_up(lambda_old_point); m_draw(old_point.x, old_point.y); lambda_old_point = scale_down(change_to_point(tp_d.x, tp_d.y)); /* writeln ('Pen pos: ',lambda_old_point.x:1,' ', lambda_old_point.y:1); */ old_point = scale_up(lambda_old_point); old_tp_d = tp_d; set_layer(curr_layer); m_move(screen_start.x, screen_start.y); /* draw new wire segment */ m_draw(old_point.x, old_point.y); } if (tp_d.depressed) { /* tp_d now in lambda coordinates */ tp_d.x = scale_down(change_to_point(tp_d.x, tp_d.y)).x; tp_d.y = scale_down(change_to_point(tp_d.x, tp_d.y)).y; if (manhattan_routing) { if (labs(tp_d.x - V.lambda_start.x) - labs(tp_d.y - V.lambda_start.y) > 0) { /* preserve y-coord */ tp_d.y = V.lambda_start.y; } else /* preserve x-coord */ tp_d.x = V.lambda_start.x; } if (first_segment) { new_wire(change_to_point(tp_d.x, tp_d.y), &V); first_segment = false; } else addline(change_to_point(tp_d.x, tp_d.y), &V); V.lambda_start = change_to_point(tp_d.x, tp_d.y); lambda_old_point = V.lambda_start; screen_start = scale_up(V.lambda_start); old_point = screen_start; debounce(); } } while (tp_d.near_); if (!tp_d.near_) { xor_on(); set_layer(curr_layer); screen_start = scale_up(V.lambda_start); m_move(screen_start.x, screen_start.y); old_point = scale_up(lambda_old_point); m_draw(old_point.x, old_point.y); } xor_off(); } /*******************************************************************************/ void delete_routing_wire(point pt) { /* searches all wires to find one that ends on the specified point, then deletes all segments that belong to it */ routing *rt, *rt2; boolean done; rt = comp_cells->routing_; /* rt runs down segment lists */ rt2 = rt; /* rt2 points one back from rt */ pt = scale_down(pt); if (point_in(rt, pt)) { /* segment is in first wire */ comp_cells->routing_ = comp_cells->routing_->next; recl_routing_node(&rt); comp_cells->modified = true; if (auto_refresh) /* refresh the screen */ show_comp(); return; } done = false; rt = rt->next; while (rt != NULL && !done) { if (!point_in(rt, pt)) { rt2 = rt; rt = rt->next; continue; } rt2->next = rt->next; recl_routing_node(&rt); comp_cells->modified = true; if (auto_refresh) /* refresh the screen */ show_comp(); done = true; } /* segment may be in subsequent wire */ /* consider next wire */ } /*******************************************************************************/ /*$if false$ pending correction by John T PROCEDURE edit_routing_wire (pt : point); var lambda_start, newpoint : point; rt : routing_ptr; layer, old_layer : integer; function get_newpoint (pt : point) : point; { draws a little line from pt to pen; when pen is depressed, that point is returned } var lambda_start, old_point, screen_start : point; tp_d, old_tp_d : tablet_info; begin lambda_start := pt; screen_start := scale_up (lambda_start); old_point := screen_start; old_tp_d.x := INFIN; old_tp_d.y := INFIN; repeat tp_d := check_pen; tp_d := scale(tp_d,3); if (tp_d.x <> old_tp_d.x) or (tp_d.y <> old_tp_d.y) then begin old_tp_d := tp_d; xor_on; { next two set_layers used to be set_layer (layer) } set_layer (BR_WHITE); m_move (screen_start.x, screen_start.y); { erase old wire segment } m_draw (old_point.x, old_point.y); old_point := scale_up (scale_down (change_to_point (tp_d.x, tp_d.y))); set_layer (BR_WHITE); m_move (screen_start.x, screen_start.y); { draw new wire segment } m_draw (old_point.x, old_point.y); end; until tp_d.depressed; get_newpoint := scale_down (change_to_point (tp_d.x, tp_d.y)); set_layer (old_layer); debounce; xor_off; end; begin lambda_start := scale_down (pt); rt := comp_cells^.routing; while (rt <> nil) and not point_in (rt, lambda_start) do rt := rt^.next; if point_in (rt, lambda_start) then { now go down the wire segment list } begin old_layer := curr_layer; layer := curr_layer; { so that the edited line is drawn correctly } if (rt^.pt1.x = lambda_start.x) and (rt^.pt1.y = lambda_start.y) then begin { the point is the first in the line } newpoint := get_newpoint (lambda_start); rt^.pt1 := newpoint; if auto_refresh then show_comp; end else begin while (rt^.pt2.x <> lambda_start.x) or (rt^.pt2.y <> lambda_start.y) do rt := rt^.to_point; { until we find the point } newpoint := get_newpoint (lambda_start); if rt^.to_point = nil then begin { it is the last point in line } rt^.pt2 := newpoint; if auto_refresh then show_comp; end else begin { update two segments } rt^.pt2 := newpoint; rt^.to_point^.pt1 := newpoint; if auto_refresh then show_comp; end; end; comp_cells^.modified := true; end; end; $end$*/ /*******************************************************************************/ /* module wol_route*/ /* End. */