#!/bin/sh # This is a shar archive. # The rest of this file is a shell script which will extract: # # gslist.h line.h main.c makefile myshape.c myshape.h put_line.c rectangle.h screen.c screen.h shape.c shape.h slist.c slist.h # # To extract the files from this shell archive file simply # create a directory for this file, move the archive file # to it and enter the command # # sh filename # # The files will be extracted automatically. # Note: Do not use csh. # # Archive created: Mon Jul 30 23:09:55 EDT 1990 # echo x - gslist.h sed 's/^X//' > gslist.h << '!EOF!' #ifndef GSLIST_H #define GSLIST_H #include "slist.h" #include #define gslist(type) name2(type,gslist) #define gslist_iterator(type) name2(type,gslist_iterator) #define gslistdeclare(type) \ struct gslist(type) : slist { \ int insert(type a) \ { return slist::insert(ent(a)); } \ int append(type a) \ { return slist::append(ent(a)); } \ type get() { return type(slist::get()); } \ gslist(type)() { } \ gslist(type)(type a) : (ent(a)) {} \ ~gslist(type)() { clear(); } \ }; \ \ struct gslist_iterator(type) : slist_iterator { \ gslist_iterator(type)(gslist(type)& s) \ : ((slist&)s) {} \ type operator()() \ { return type(slist_iterator::operator()()); } \ }; #endif !EOF! ls -l gslist.h echo x - line.h sed 's/^X//' > line.h << '!EOF!' #ifndef LINE_H #define LINE_H class line : public shape { /* line from "w" to "e" north() is defined as `above the middle as far north as the northernmost point' nw ---- n ---- ne nw ---- n ---- ne | * | | * | | * | | * | w m e w m e | * | | * | | * | | * | sw ---- s ---- se sw ---- s ---- se */ point w, e; public: point north() { return point((w.x+e.x)/2, e.y= 0) { w = point(a.x+len-1,a.y); e = a; } else { w = a; e = point(a.x+len-1,a.y); } } }; #endif !EOF! ls -l line.h echo x - main.c sed 's/^X//' > main.c << '!EOF!' #include "myshape.h" main() { screen_init(); shape* p1 = new rectangle(point(0,0),point(10,10)); shape* p2 = new line(point(0,15),17); shape* p3 = new myshape(point(15,10),point(27,18)); shape_refresh(); p3->move(-10,-10); stack(p2, p3); stack(p1, p2); shape_refresh(); screen_end(); return 0; } !EOF! ls -l main.c echo x - makefile sed 's/^X//' > makefile << '!EOF!' CC= CC -I. -I../../CC CFLAGS= +i -g OBJ= screen.o shape.o myshape.o slist.o put_line.o main.o all: shape.a shape.a: $(OBJ) rm -f shape.a ar qc shape.a $(OBJ) screen.o: screen.c screen.h $(CC) $(CFLAGS) -c screen.c shape.o: shape.c shape.h line.h rectangle.h screen.h slist.h gslist.h $(CC) $(CFLAGS) -c shape.c myshape.o: myshape.c myshape.h shape.h line.h rectangle.h screen.h slist.h gslist.h $(CC) $(CFLAGS) -c myshape.c slist.o: slist.c slist.h $(CC) $(CFLAGS) -c slist.c put_line.o: put_line.c screen.h $(CC) $(CFLAGS) -c put_line.c main.o: main.c myshape.h shape.h line.h rectangle.h screen.h gslist.h slist.h $(CC) $(CFLAGS) -c main.c !EOF! ls -l makefile echo x - myshape.c sed 's/^X//' > myshape.c << '!EOF!' #include "myshape.h" myshape::myshape(point a, point b) : (a,b) { int ll = neast().x - swest().x + 1; int hh = neast().y - swest().y + 1; l_eye = new line(point(swest().x + 2, swest().y + hh * 3 / 4) , 2); r_eye = new line(point(swest().x + ll - 4, swest().y + hh * 3 / 4), 2); mouth = new line(point(swest().x + 2, swest().y + hh / 4) , ll - 4); } void myshape:: draw() { rectangle::draw(); put_point(point((swest().x + neast().x) / 2, (swest().y + neast().y) / 2)); } void myshape:: move(int a, int b) { rectangle::move(a,b); l_eye->move(a,b); r_eye->move(a,b); mouth->move(a,b); } !EOF! ls -l myshape.c echo x - myshape.h sed 's/^X//' > myshape.h << '!EOF!' #ifndef MYSHAPE_H #define MYSHAPE_H #include "shape.h" class myshape : public rectangle { line* l_eye; line* r_eye; line* mouth; public: myshape(point, point); void draw(); void move(int, int); }; #endif !EOF! ls -l myshape.h echo x - put_line.c sed 's/^X//' > put_line.c << '!EOF!' #include "screen.h" void put_line(point a, point b) { put_line(a.x, a.y, b.x, b.y); } void put_line(int x0, int y0, int x1, int y1) { register dx = 1; int a = x1 - x0; if (a < 0) dx = -1, a = -a; register dy = 1; int b = y1 - y0; if (b < 0) dy = -1, b = -b; int two_a = 2 * a; int two_b = 2 * b; int xcrit = -b + two_a; register eps = 0; for (;;) { put_point(x0, y0); if (x0 == x1 && y0 == y1) break; if (eps <= xcrit) x0 += dx, eps += two_b; if (eps>= a || a <= b) y0 += dy, eps -= two_a; } } !EOF! ls -l put_line.c echo x - rectangle.h sed 's/^X//' > rectangle.h << '!EOF!' #ifndef RECTANGLE_H #define RECTANGLE_H class rectangle : public shape { /* nw ---- n ---- ne | | | | w m e | | | | sw ---- s ---- se */ point sw, ne; public: point north() { return point((sw.x+ne.x)/2, ne.y); } point neast() { return ne; } point east() { return point(ne.x, (sw.y+ne.y)/2); } point seast() { return point(ne.x, sw.y); } point south() { return point((sw.x+ne.x)/2, sw.y); } point swest() { return sw; } point west() { return point(sw.x, (sw.y+ne.y)/2); } point nwest() { return point(sw.x, ne.y); } point middle(){ return point((sw.x+ne.x)/2, (sw.y+ne.y)/2); } void move(int a, int b) { sw.x += a; sw.y += b; ne.x += a; ne.y += b; } void draw(); rectangle(point, point); }; #endif !EOF! ls -l rectangle.h echo x - screen.c sed 's/^X//' > screen.c << '!EOF!' #include "screen.h" char screen[XMAX][YMAX]; void screen_init() { for (int y = 0; y < YMAX; y++) for (int x=0; x < XMAX; x++) screen[x][y] = white; } inline int on_screen(int a, int b) { return 0 <= a && a < XMAX && 0 <= b && b < YMAX; } void put_point(int a, int b) { if (on_screen(a,b)) screen[a][b] = black; } void screen_clear() { screen_init(); } void screen_refresh() { for (int y=YMAX-1; 0<= y; y--) { for (int x = 0; x < XMAX; x++) cout.put(screen[x][y]); cout.put('\n'); } } void screen_end() { } !EOF! ls -l screen.c echo x - screen.h sed 's/^X//' > screen.h << '!EOF!' #ifndef SCREEN_H #define SCREEN_H // file screen.h const XMAX = 80, YMAX = 60; struct point { int x, y; point() {} point(int a, int b) { x = a; y = b; } }; overload put_point; extern void put_point(int a, int b); inline void put_point(point p) { put_point(p.x, p.y); } overload put_line; extern void put_line(int, int, int, int); extern void put_line(point a, point b); extern void screen_init(); extern void screen_refresh(); extern void screen_clear(); extern void screen_end(); enum color { black = '*', white = ' ' }; #include #endif !EOF! ls -l screen.h echo x - shape.c sed 's/^X//' > shape.c << '!EOF!' #include "shape.h" #include "screen.h" shape_lst shape_list; rectangle::rectangle(point a, point b) { if (a.x <= b.x) { if (a.y <= b.y) { sw = a; ne = b; } else { sw = point(a.x, b.y); ne = point(b.x, a.y); } } else { if (a.y <= b.y) { sw = point(b.x, a.y); ne = point(a.x, b.y); } else { sw = b; ne = a; } } } void rectangle::draw() { point nw(sw.x, ne.y); point se(ne.x, sw.y); put_line(nw,ne); put_line(ne,se); put_line(se,sw); put_line(sw,nw); } void shape_refresh() { screen_clear(); sl_iterator next(shape_list); shape* p; while (p = next() ) p->draw(); screen_refresh(); } void stack(shape* q, shape* p) // put p on top of q { point n = p->north(); point s = q->south(); q->move(n.x-s.x, n.y-s.y+1); } !EOF! ls -l shape.c echo x - shape.h sed 's/^X//' > shape.h << '!EOF!' #ifndef SHAPE_H #define SHAPE_H #include "screen.h" #include "gslist.h" struct shape; typedef shape* sp; declare(gslist,sp); typedef gslist(sp) shape_lst; typedef gslist_iterator(sp) sl_iterator; extern shape_lst shape_list; struct shape { shape() { shape_list.append(this); } virtual point north() { return point(0,0); } virtual point neast() { return point(0,0); } virtual point east() { return point(0,0); } virtual point seast() { return point(0,0); } virtual point south() { return point(0,0); } virtual point swest() { return point(0,0); } virtual point west() { return point(0,0); } virtual point nwest() { return point(0,0); } virtual point middle(){ return point(0,0); } virtual void draw() {}; virtual void move(int, int) {}; friend void shape_refresh(); friend void stack(shape*, shape*); }; extern void shape_refresh(); extern void stack(shape*, shape*); #ifdef RECTFIRST # include # include #else # include # include #endif #endif !EOF! ls -l shape.h echo x - slist.c sed 's/^X//' > slist.c << '!EOF!' #include "slist.h" #include #include int slist::insert(ent a) { if (last) { last->next = new slink(a, last->next); } else { last = new slink(a, 0); last->next = last; } return 0; } int slist::append(ent a) { if (last) { last = last->next = new slink(a, last->next); } else { last = new slink(a, 0); last->next = last; } return 0; } ent slist::get() { if (last == 0) slist_handler("get from empty slist"); slink *f = last->next; ent r = f->e; if (f == last) { last = 0; } else { last->next = f->next; } delete f; return r; } void slist::clear() { slink *l = last; if (l == 0) return; do { slink *ll = last; l = l->next; delete ll; } while (l != last); last = 0; } static void default_error(char *s) { cerr << s << "\n"; exit(1); } PFC slist_handler = default_error; PFC set_slist_handler(PFC handler) { PFC rr = slist_handler; slist_handler = handler; return rr; } !EOF! ls -l slist.c echo x - slist.h sed 's/^X//' > slist.h << '!EOF!' #ifndef SLIST_H #define SLIST_H typedef void* ent; class slink { friend class slist; friend class slist_iterator; slink *next; ent e; slink(ent a, slink *p) { e = a; next = p; } }; class slist { friend class slist_iterator; slink *last; public: int insert(ent a); int append(ent a); ent get(); void clear(); slist() { last = 0; } slist(ent a) { last = new slink(a, 0); last->next = last; } ~slist() { clear(); } }; class slist_iterator { slink *ce; slist *cs; public: slist_iterator(slist &s) { cs = &s; ce = cs->last; } ent operator()() { ent ret = ce ? (ce = ce->next)->e : 0; if (ce == cs->last) ce = 0; return ret; } }; typedef void (*PFC)(char*); extern PFC slist_handler; extern PFC set_slist_handler(PFC); #endif !EOF! ls -l slist.h # The following exit is to ensure that extra garbage # after the end of the shar file will be ignored. exit 0