From: adam Date: Sun, 25 Jun 2006 12:50:32 +0000 (+0100) Subject: checkpoint X-Git-Tag: mpar_demo_release~114 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=c468f7da697dbc1024f1b9e9e2037e8d6cdd93f0;p=slipway.git checkpoint --- diff --git a/Makefile b/Makefile index 4891adf..9d16e29 100644 --- a/Makefile +++ b/Makefile @@ -1,21 +1,17 @@ -led0: obits.jar - java -Djava.library.path=/usr/lib \ - -cp /usr/share/java/RXTXcomm.jar:obits.jar \ - edu.berkeley.obits.AtmelSerial < bitstreams/led0.md4 +java = java -Djava.library.path=$(shell pwd)/lib/ -cp lib/RXTXcomm.jar:obits.jar + +led0: obits.jar + $(java) edu.berkeley.obits.AtmelSerial < bitstreams/led0.md4 led1: obits.jar - java -Djava.library.path=/usr/lib \ - -cp /usr/share/java/RXTXcomm.jar:obits.jar \ - edu.berkeley.obits.AtmelSerial < bitstreams/led1.md4 + $(java) edu.berkeley.obits.AtmelSerial < bitstreams/led1.md4 run: obits.jar - java -Djava.library.path=/usr/lib \ - -cp /usr/share/java/RXTXcomm.jar:obits.jar \ - edu.berkeley.obits.AtmelSerial + $(java) edu.berkeley.obits.AtmelSerial < stupid.md4 obits.jar: $(shell find src -name \*.java) - javac -cp /usr/share/java/RXTXcomm.jar -d build $(shell find src -name \*.java) + javac -cp lib/RXTXcomm.jar -d build $(shell find src -name \*.java) cd build; jar cvf ../$@ . # -O3 is required; otherwise the poor AVR can't keep up with us! diff --git a/lib/RXTXcomm.jar b/lib/RXTXcomm.jar new file mode 100644 index 0000000..84e5f01 Binary files /dev/null and b/lib/RXTXcomm.jar differ diff --git a/lib/librxtxSerial.jnilib b/lib/librxtxSerial.jnilib new file mode 100644 index 0000000..2d3f20d Binary files /dev/null and b/lib/librxtxSerial.jnilib differ diff --git a/lib/librxtxSerial.so b/lib/librxtxSerial.so new file mode 100644 index 0000000..e60c5e6 Binary files /dev/null and b/lib/librxtxSerial.so differ diff --git a/lib/rxtxSerial.dll b/lib/rxtxSerial.dll new file mode 100644 index 0000000..c0e6b58 Binary files /dev/null and b/lib/rxtxSerial.dll differ diff --git a/src/edu/berkeley/obits/AtmelSerial.java b/src/edu/berkeley/obits/AtmelSerial.java index 444c944..cffe6c7 100644 --- a/src/edu/berkeley/obits/AtmelSerial.java +++ b/src/edu/berkeley/obits/AtmelSerial.java @@ -3,6 +3,7 @@ package edu.berkeley.obits; import static edu.berkeley.obits.device.atmel.AtmelDevice.Constants.*; import static edu.berkeley.obits.device.atmel.AtmelDevice.Util.*; import edu.berkeley.obits.device.atmel.*; +import edu.berkeley.obits.gui.*; import java.awt.*; import java.awt.event.*; import java.awt.color.*; @@ -346,7 +347,6 @@ public class AtmelSerial { c.h(L2, true); - // catch a rising transition /* c = c.west(); @@ -361,6 +361,49 @@ public class AtmelSerial { c.hwire(L2).west().drives(c.hwire(L2), false); c.hwire(L2).east().drives(c.hwire(L2), false); + + + ////// + + c = at40k.cell(20,20); + c.yi(WEST); + c.ylut(LUT_SELF); + c.c(YLUT); + c.oe(H4); + c.h(L4, true); + c.b(false); + c.f(false); + c.out(L4); + + c = at40k.cell(21,20); + c.c(YLUT); + c.oe(NONE); + c.h(L4, true); + c.b(false); + c.f(false); + + + c = at40k.cell(8,8); + c.f(true); + c.b(true); + c.xo(true); + c.xi(NE); + c.zi(L3); + c.wi(L0); + c.yi(NORTH); + c.oe(H4); + c.h(L0, true); + c.h(L2, true); + c.h(L4, true); + c.v(L1, true); + c.v(L3, true); + c.out(L0, true); + c.out(L1, true); + c.out(L2, true); + c.out(L3, true); + c.out(L4, true); + c.c(ZMUX); + //for(int x=5; xi) return s; return "0"+pad((i-1),s); } - private static String bin8(byte b) { + public static String bin8(byte b) { int n = b & 0xff; String ret = ""; for(int i=7; i>=0; i--) diff --git a/src/edu/berkeley/obits/Visual.java b/src/edu/berkeley/obits/Visual.java deleted file mode 100644 index 9e20da0..0000000 --- a/src/edu/berkeley/obits/Visual.java +++ /dev/null @@ -1,396 +0,0 @@ -package edu.berkeley.obits; - -import static edu.berkeley.obits.device.atmel.AtmelDevice.Constants.*; -import static edu.berkeley.obits.device.atmel.AtmelDevice.Util.*; -import edu.berkeley.obits.device.atmel.*; -import java.awt.*; -import java.awt.geom.*; -import java.awt.event.*; -import java.awt.color.*; -import org.ibex.util.*; -import java.io.*; -import java.util.*; -import javax.swing.*; - -public class Visual extends JFrame implements KeyListener { - - public static int SIZE = 92; - public static int RINGS = 3; - public static int BEVEL = 5; - public static int CORE_SIZE = 64; - public static int CORE_OFFSET = 10; - - public static int HOFF = 52; - - /* - public static void main(String[] s) { - Visual v = new Visual(); - v.show(); - v.setSize(400, 400); - } - */ - - At40k at40k; - - public Visual(At40k at40k) { - this.at40k = at40k; - for(int x=0; x<7; x++) - for(int y=0; y<7; y++) - new Cell(x,y, at40k.cell(x+7, y+7)); - addKeyListener(this); - } - - private HashSet cells = new HashSet(); - - public class Cell { - Graphics2D g; - At40k.Cell cell; - int _x, _y; - public Cell(int x, int y, At40k.Cell cell) { - _x = x; - _y = y; - this.cell = cell; - cells.add(this); - } - public void draw() { - drawHwires(); - drawVwires(); - drawInternalRouting(); - drawLocal(); - drawGates(); - drawMux(); - drawRegister(); - drawBorder(); - } - public void drawHwires() { - g.setColor(Color.magenta); - for(int i=0; i<5; i++) - if (cell.hwire(i).isDriven()) - g.drawLine(0, SIZE-(2*(1+RINGS)+2*i), SIZE, SIZE-(2*(1+RINGS)+2*i)); - } - public void drawVwires() { - g.setColor(Color.magenta); - for(int i=0; i<5; i++) - if (cell.vwire(i).isDriven()) - g.drawLine(2*(1+RINGS)+2*i, 0, 2*(1+RINGS)+2*i, SIZE); - } - public void drawInternalRouting() { - } - - public void drawLocal() { - if (!cell.ylut_relevant() && !cell.ylut_relevant()) return; - Point2D in = new Point2D.Double(HOFF, 0); - Point2D join = new Point2D.Double(HOFF, CORE_OFFSET); - rotateOuter(in); - rotateInner(join); - int rot = rot(); - switch(rot) { - case 0: case 2: - join.setLocation(in.getX(), join.getY()); - break; - case 1: case 3: - join.setLocation(join.getX(), in.getY()); - break; - } - - Point2D xi = null; - g.setColor(new Color(0xff, 0x00, 0x00)); - int xring = 4; - switch(cell.xi()) { - case NW: - xi = new Point2D.Double(0+2*xring, SIZE-2*xring); - g.draw(new Line2D.Double(new Point2D.Double(0, SIZE), xi)); - break; - - case SW: - xi = new Point2D.Double(0+2*xring, 0+2*xring); - g.draw(new Line2D.Double(new Point2D.Double(0, 0), xi)); - break; - - case NE: - xi = new Point2D.Double(SIZE-2*xring, SIZE-2*xring); - g.draw(new Line2D.Double(new Point2D.Double(SIZE, SIZE), xi)); - break; - - case SE: - xi = new Point2D.Double(SIZE-2*xring, 0+2*xring); - g.draw(new Line2D.Double(new Point2D.Double(SIZE, 0), xi)); - break; - - } - - if (cell.xlut_relevant()) { - g.setColor(new Color(0x00, 0x00, 0xff)); - Point2D c = new Point2D.Double(SIZE - CORE_OFFSET - CORE_SIZE/2 - CORE_SIZE / 6, 20); - rotateInner(c); - route(in, c, 5); - - g.setColor(new Color(0xff, 0x00, 0x00)); - c = new Point2D.Double(SIZE - CORE_OFFSET - CORE_SIZE/2 - CORE_SIZE / 3, 20); - rotateInner(c); - if (xi != null) - route(xi, c, 4); - - Point2D xo = new Point2D.Double(SIZE-CORE_OFFSET-CORE_SIZE+17 - 2, CORE_OFFSET + 41 - 3); - Point2D xout = new Point2D.Double(SIZE-CORE_OFFSET-CORE_SIZE+17 - 2, CORE_OFFSET + CORE_SIZE - 3); - rotateInner(xo); - rotateInner(xout); - g.setColor(new Color(0xff, 0xcc, 0xcc)); - g.draw(new Line2D.Double(xo, xout)); - if (cell.ne() != null && cell.ne().xi()==SW) { - Point2D xoo = new Point2D.Double(SIZE-2*xring, SIZE-2*xring); - g.draw(new Line2D.Double(new Point2D.Double(SIZE, SIZE), xoo)); - route(xout, xoo, xring); - } - if (cell.nw() != null && cell.nw().xi()==SE) { - Point2D xoo = new Point2D.Double(0+2*xring, SIZE-2*xring); - g.draw(new Line2D.Double(new Point2D.Double(0, SIZE), xoo)); - route(xout, xoo, xring); - } - if (cell.se() != null && cell.se().xi()==NW) { - Point2D xoo = new Point2D.Double(SIZE-2*xring, 0+2*xring); - g.draw(new Line2D.Double(new Point2D.Double(SIZE, 0), xoo)); - route(xout, xoo, xring); - } - if (cell.sw() != null && cell.sw().xi()==NE) { - Point2D xoo = new Point2D.Double(0+2*xring, 0+2*xring); - g.draw(new Line2D.Double(new Point2D.Double(0, 0), xoo)); - route(xout, xoo, xring); - } - } - - if (cell.ylut_relevant()) { - g.setColor(new Color(0x00, 0x00, 0xff)); - Point2D c = new Point2D.Double(SIZE - CORE_OFFSET - CORE_SIZE/2 + CORE_SIZE / 6, 20); - rotateInner(c); - route(in, c, 5); - - g.setColor(new Color(0xff, 0x00, 0x00)); - c = new Point2D.Double(SIZE - CORE_OFFSET - CORE_SIZE/2 + CORE_SIZE / 3, 20); - rotateInner(c); - if (xi != null) - route(xi, c, 4); - - Point2D yo = new Point2D.Double(SIZE-CORE_OFFSET-CORE_SIZE+51 - 2, CORE_OFFSET + 41 - 3); - Point2D yout = new Point2D.Double(SIZE-CORE_OFFSET-CORE_SIZE+51 - 2, CORE_OFFSET + CORE_SIZE - 3); - rotateInner(yo); - rotateInner(yout); - g.setColor(new Color(0xbb, 0xbb, 0xff)); - //g.setColor(new Color(0x00, 0x00, 0xff)); - g.draw(new Line2D.Double(yo, yout)); - if (cell.north() != null && cell.north().yi()==SOUTH) route(yout, new Point2D.Double(SIZE-40, SIZE+ 0), 2); - if (cell.east() != null && cell.east().yi()==WEST) route(yout, new Point2D.Double(SIZE+ 0, 40), 2); - if (cell.south() != null && cell.south().yi()==NORTH) route(yout, new Point2D.Double( 40, 0), 2); - if (cell.west() != null && cell.west().yi()==EAST) route(yout, new Point2D.Double( 0, SIZE-40), 2); - } - - } - - private void rotateOuter(Point2D p) { - int rot = rot(); - AffineTransform a = new AffineTransform(); - a.rotate((Math.PI/2) * rot); - switch(rot) { - case 0: break; - case 1: a.translate(0, -SIZE); break; - case 2: a.translate(-SIZE, -SIZE); break; - case 3: a.translate(-SIZE, 0); break; - } - a.transform(p, p); - } - - private void rotateInner(Point2D p) { - int rot = rot(); - AffineTransform a = new AffineTransform(); - a.translate(SIZE-CORE_SIZE-CORE_OFFSET, CORE_OFFSET); - a.rotate((Math.PI/2) * rot); - switch(rot) { - case 0: break; - case 1: a.translate(0, -CORE_SIZE); break; - case 2: a.translate(-CORE_SIZE, -CORE_SIZE); break; - case 3: a.translate(-CORE_SIZE, 0); break; - } - a.translate(-1 * (SIZE-CORE_SIZE-CORE_OFFSET), -CORE_OFFSET); - a.transform(p, p); - } - - private Point2D project(Point2D p1, int ring) { - double north = Math.abs( (SIZE-(ring*2)) - p1.getY() ); - double south = Math.abs( ( (ring*2)) - p1.getY() ); - double east = Math.abs( (SIZE-(ring*2)) - p1.getX() ); - double west = Math.abs( ( (ring*2)) - p1.getX() ); - if (north < south && north < east && north < west) { - return new Point2D.Double(p1.getX(), SIZE-ring*2); - } else if (south < east && south < west) { - return new Point2D.Double(p1.getX(), ring*2); - } else if (east < west) { - return new Point2D.Double(SIZE-ring*2, p1.getY()); - } else { - return new Point2D.Double(ring*2, p1.getY()); - } - } - - private void route(Point2D p1, Point2D p2, int ring) { - int ringpos = ring * 2; - Point2D projected = project(p1, ring); - g.draw(new Line2D.Double(p1, projected)); - p1 = projected; - - projected = project(p2, ring); - g.draw(new Line2D.Double(p2, projected)); - p2 = projected; - - double x1 = p1.getX(); - double y1 = p1.getY(); - double x2 = p2.getX(); - double y2 = p2.getY(); - - if (x1==x2 || y1==y2) { - g.draw(new Line2D.Double(p1, p2)); - return; - } - - if ((x1==SIZE-ring*2 || x1==ring*2) && !(y1==SIZE-ring*2 || y1==ring*2)) { - Point2D p3 = new Point2D.Double(x1, y2 > SIZE/2 ? SIZE-ring*2 : ring*2); - g.draw(new Line2D.Double(p1, p3)); - route(p3, p2, ring); - } - - if (y1==SIZE-ring*2 || y1==ring*2) { - Point2D p3 = new Point2D.Double(x2 > SIZE/2 ? SIZE-ring*2 : ring*2, y1); - g.draw(new Line2D.Double(p1, p3)); - route(p3, p2, ring); - } - - } - - private int rot() { - int rot = 0; - switch(cell.yi()) { - case SOUTH: rot = 0; break; - case NORTH: rot = 2; break; - case EAST: rot = 1; break; - case WEST: rot = 3; break; - default: { - // FIXME: choose based on xin - if (cell.north() != null && cell.north().yi()==SOUTH) { rot = 0; break; } - if (cell.south() != null && cell.south().yi()==NORTH) { rot = 2; break; } - if (cell.east() != null && cell.east().yi()==WEST) { rot = 3; break; } - if (cell.west() != null && cell.west().yi()==EAST) { rot = 1; break; } - } - } - return rot; - } - - public void drawGates() { - AffineTransform t = g.getTransform(); - try { - g.translate(SIZE-CORE_SIZE-CORE_OFFSET, CORE_OFFSET); - - int rot = rot(); - g.rotate((Math.PI/2) * rot); - switch(rot) { - case 0: break; - case 1: g.translate(0, -CORE_SIZE); break; - case 2: g.translate(-CORE_SIZE, -CORE_SIZE); break; - case 3: g.translate(-CORE_SIZE, 0); break; - } - - //g.setColor(Color.gray); - //g.drawRect(0, 0, CORE_SIZE, CORE_SIZE); - g.scale(1, -1); - - GeneralPath p = new GeneralPath(); - p.moveTo(29.141f, 36.301f); - p.lineTo(29.141f, 36.301f-7.161f); - p.curveTo(27.71f, 11.24f, 23.413f, 9.45f, 14.82f, 0.5f); - p.curveTo(6.229f, 9.45f, 1.932f, 11.24f, 0.5f, 29.141f); - p.lineTo(0.5f, 29.141f+7.161f); - float x = 0.5f; - float y = 29.141f+7.161f; - p.curveTo(5.729f+x, -1.789f+y, - 6.444f+x, -2.686f+y, - 14.32f+x, -3.58f+y); - p.curveTo(22.697f, 33.616f, 23.413f, 34.512f, 29.141f, 36.301f); - g.translate(0, -40f); - if (cell.xlut_relevant()) { - g.setColor(Color.white); - g.fill(p); - g.setColor(Color.red); - g.draw(p); - } - g.translate(34f, 0f); - if (cell.ylut_relevant()) { - g.setColor(Color.white); - g.fill(p); - g.setColor(Color.blue); - g.draw(p); - } - } finally { - g.setTransform(t); - } - } - public void drawMux() { - if (cell.c() != ZMUX) return; - g.setColor(Color.black); - g.drawLine(46, 54, 46+2, 54+5); - g.drawLine(46+2, 54+5, 60-2, 54+5); - g.drawLine(60-2, 54+5, 60, 54); - g.drawLine(60, 54, 46, 54); - } - public void drawRegister() { - } - public void drawBorder() { - g.setColor(Color.gray); - //g.drawLine(0, BEVEL, BEVEL, 0); - g.drawLine(BEVEL, 0, SIZE-BEVEL, 0); - //g.drawLine(SIZE-BEVEL, 0, SIZE, BEVEL); - g.drawLine(SIZE, BEVEL, SIZE, SIZE-BEVEL); - //g.drawLine(SIZE, SIZE-BEVEL, SIZE-BEVEL, SIZE); - g.drawLine(SIZE-BEVEL, SIZE, BEVEL, SIZE); - //g.drawLine(BEVEL, SIZE, 0, SIZE-BEVEL); - g.drawLine(0, SIZE-BEVEL, 0, BEVEL); - } - } - - public void paint(Graphics _g) { - Graphics2D g = (Graphics2D)_g; - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); - g.setStroke(new BasicStroke((float)0.5)); - g.translate(10, 0); - g.scale(1, -1); - g.translate(5, -1 * getHeight() + 10); - g.scale(scale,scale); - for(Cell c : cells) { - AffineTransform t = g.getTransform(); - g.translate( c._x * SIZE/* + (10 * (c._x/4))*/, c._y * SIZE/* + (10 * (c._y/4))*/); - c.g = g; - c.draw(); - c.g = null; - g.setTransform(t); - } - } - - double scale = 1.0; - - public void clear() { - Graphics2D g = (Graphics2D)getGraphics(); - //g.setColor(Color.black); - //g.setColor(Color.lightGray); - g.clearRect(0, 0, getWidth(), getHeight()); - } - - public void keyTyped(KeyEvent k) { - } - public void keyReleased(KeyEvent k) { - } - public void keyPressed(KeyEvent keyevent) { - char c = keyevent.getKeyChar(); - switch(c) { - case '+': scale += 0.1; clear(); paint(getGraphics()); return; - case '-': scale -= 0.1; clear(); paint(getGraphics()); return; - } - } - -} diff --git a/src/edu/berkeley/obits/device/atmel/At40k.java b/src/edu/berkeley/obits/device/atmel/At40k.java index 828ad3e..5398ec3 100644 --- a/src/edu/berkeley/obits/device/atmel/At40k.java +++ b/src/edu/berkeley/obits/device/atmel/At40k.java @@ -282,12 +282,15 @@ public class At40k { case TMUX_Z: throw new Error("not implemented, but should be possible"); case TMUX_W_AND_Z: result = 0x20; break; - case TMUX_FB: result = 0x04; break; /* I think this is actually W_AND_FB, sadly */ + case TMUX_FB: result = 0x34; break; /* I think this is actually W_AND_FB, sadly */ case TMUX_W_AND_FB: result = 0x14; break; case TMUX_W: result = 0x00; break; } dev.mode4(1, row, col, result, 0x34); } + public int t() { + return dev.mode4(1, row, col) & 0x34; + } public void t(boolean ignore_z_and_fb, boolean zm_drives_fb, boolean fb_drives_wm) { // still not totally satisfied... // how to we distinguish between z&w vs z or w&fb vs fb? ==> you can't! this is a false connection in my diagram @@ -297,31 +300,64 @@ public class At40k { // ZM->FB = 0x04 // FB->WM = 0x10 // WZ->WM = 0x20 - - // tff => w&z - // fff => w - // ttt => fb&w - // ftt => fb&w - // fft => fb&w - - // ttf => w&z - // ftf => w - // tft => fb&w + + // tff => w&z [0x20] + // fff => w [0x00] + // ttt => fb&w [0x34] + // ftt => fb&w [0x14] + // fft => fb&w [0x10] + + // ttf => w&z [0x24] + // ftf => w [0x04] + // tft => fb&w [0x30] if (ignore_z_and_fb) result |= 0x20; if (zm_drives_fb) result |= 0x04; if (fb_drives_wm) result |= 0x10; dev.mode4(1, row, col, result, 0x34); } - public boolean xlut_relevant() { + public boolean xlut_relevant() { return xlut_relevant(true); } + public boolean xlut_relevant(boolean recurse) { if ((c()==XLUT || c()==ZMUX) && c_relevant()) return true; if (xo()) return false; - if (nw() != null && nw().xi()==SE) return true; - if (ne() != null && ne().xi()==SW) return true; - if (sw() != null && sw().xi()==NE) return true; - if (se() != null && se().xi()==NW) return true; + if (nw() != null && nw().xi()==SE && nw().xi_relevant() && (recurse || nw().xlut_relevant())) return true; + if (ne() != null && ne().xi()==SW && ne().xi_relevant() && (recurse || ne().xlut_relevant())) return true; + if (sw() != null && sw().xi()==NE && sw().xi_relevant() && (recurse || sw().xlut_relevant())) return true; + if (se() != null && se().xi()==NW && se().xi_relevant() && (recurse || se().xlut_relevant())) return true; return false; } + public boolean xi_to_ylut_relevant() { + int lut = ylut(); + if (((lut & 0xcc) >> 2) == (lut & 0x33)) return false; + return true; + } + public boolean yi_to_xlut_relevant() { + int lut = xlut(); + if (((lut & 0xcc) >> 2) == (lut & 0x33)) return false; + return true; + } + public boolean xi_relevant() { return xi_to_xlut_relevant() || xi_to_ylut_relevant(); } + public boolean yi_relevant() { return yi_to_xlut_relevant() || yi_to_ylut_relevant(); } + public boolean zi_to_xlut_relevant() { + int lut = xlut(); + if (((lut & LUT_Z) >> 4) == (lut & LUT_Z)) return false; + return true; + } + public boolean zi_to_ylut_relevant() { + int lut = ylut(); + if (((lut & LUT_Z) >> 4) == (lut & LUT_Z)) return false; + return true; + } + public boolean xi_to_xlut_relevant() { + int lut = xlut(); + if (((lut & LUT_SELF) >> 1) == (lut & (LUT_SELF >> 1))) return false; + return true; + } + public boolean yi_to_ylut_relevant() { + int lut = ylut(); + if (((lut & LUT_SELF) >> 1) == (lut & (LUT_SELF >> 1))) return false; + return true; + } public boolean ylut_relevant() { if ((c()==YLUT || c()==ZMUX) && c_relevant()) return true; if (yo()) return false; @@ -339,6 +375,37 @@ public class At40k { return false; } + public boolean register_relevant() { + if (!c_relevant() && !fb_relevant()) return false; + if (f() && out_relevant()) return true; + if (f() && fb_relevant()) return true; + if (b() && xo()) return true; + if (b() && yo()) return true; + return false; + } + public boolean out_relevant() { + boolean out = false; + boolean connect = false; + for(int i=0; i<4; i++) { + if (out(L0+i)) out = true; + if (hx(L0+i)) connect = true; + if (vx(L0+i)) connect = true; + } + return out && connect; + } + public boolean fb_relevant() { + //if (!c_relevant()) return false; + if (!(zi_to_xlut_relevant() && xlut_relevant()) || + !(zi_to_ylut_relevant() && ylut_relevant())) return false; + switch(t()) { + case 0x34: return true; + case 0x14: return true; + case 0x10: return true; + case 0x30: return true; + } + return false; + } + public void c(int source) { switch(source) { case XLUT: dev.mode4(1, row, col, 0x00, 0xc0); break; @@ -348,12 +415,13 @@ public class At40k { } } public int c() { - switch (dev.mode4(1, row, col) >> 6) { + int cval = dev.mode4(1, row, col) & 0xc0; + switch (cval) { case 0x00: return XLUT; - case 0x01: return YLUT; - case 0x02: return ZMUX; + case 0x40: return YLUT; + case 0x80: return ZMUX; } - throw new Error(); + throw new Error("c() => " + cval); } public void b(boolean registered) { dev.mode4(1, row, col, 3, !registered); } public void f(boolean registered) { dev.mode4(1, row, col, 2, !registered); } @@ -361,10 +429,10 @@ public class At40k { public boolean yo() { return (dev.mode4(1, row, col) & 0x02) != 0; } public void xo(boolean center) { dev.mode4(1, row, col, 1, center); } public void yo(boolean center) { dev.mode4(1, row, col, 0, center); } - public boolean b() { return (dev.mode4(1, row, col) >> 3)!=1; } - public boolean f() { return (dev.mode4(1, row, col) >> 2)!=1; } - public boolean x() { return (dev.mode4(1, row, col) >> 1)==1; } - public boolean y() { return (dev.mode4(1, row, col) >> 0)==1; } + public boolean b() { return (dev.mode4(1, row, col) & (1 << 3)) == 0; } + public boolean f() { return (dev.mode4(1, row, col) & (1 << 2)) == 0; } + public boolean x() { return (dev.mode4(1, row, col) & (1 << 1)) != 0; } + public boolean y() { return (dev.mode4(1, row, col) & (1 << 0)) != 0; } public int oe() { switch (dev.mode4(0x02, row, col) & 0x3) { @@ -458,13 +526,14 @@ public class At40k { } public int wi() { - int who = dev.mode4(0x03, row, col) & 0xff; + int who = dev.mode4(0x03, row, col) & 0xEC; switch(who) { case (1<<5): return L4; case (1<<6): return L3; case (1<<7): return L2; case (1<<3): return L1; case (1<<2): return L0; + case (1<<0): return NONE; /* huh? */ case (0): return NONE; default: throw new RuntimeException("invalid argument: " + who); } @@ -482,14 +551,15 @@ public class At40k { } public int zi() { - switch(dev.mode4(0x02, row, col) & 0xff) { + switch(dev.mode4(0x02, row, col) & 0xDB) { case (1<<7): return L4; case (1<<5): return L3; case (1<<4): return L2; case (1<<3): return L1; case (1<<2): return L0; + case (1<<0): return NONE; /* huh? */ case 0: return NONE; - default: throw new RuntimeException("invalid argument"); + default: throw new RuntimeException("invalid argument: zi=="+(dev.mode4(0x02, row, col) & 0xDB)); } } diff --git a/src/edu/berkeley/obits/gui/G.java b/src/edu/berkeley/obits/gui/G.java new file mode 100644 index 0000000..095b958 --- /dev/null +++ b/src/edu/berkeley/obits/gui/G.java @@ -0,0 +1,41 @@ +package edu.berkeley.obits.gui; + +import static edu.berkeley.obits.device.atmel.AtmelDevice.Constants.*; +import static edu.berkeley.obits.device.atmel.AtmelDevice.Util.*; +import edu.berkeley.obits.*; +import edu.berkeley.obits.device.atmel.*; +import java.awt.*; +import java.awt.geom.*; +import java.awt.event.*; +import java.awt.color.*; +import org.ibex.util.*; +import java.io.*; +import java.util.*; +import javax.swing.*; + +/** Graphics */ +public class G { + + public final Graphics2D g; + + public G(Graphics2D g) { this.g = g; } + public G(Graphics g) { this((Graphics2D)g); } + + public void line(Point2D p1, Point2D p2) { line(new P(p1), new P(p2)); } + + public void line(P p1, P p2) { line(p1.x, p1.y, p2.x, p2.y); } + public void line(double x, double y, P p2) { line(x, y, p2.x, p2.y); } + public void line(P p1, double x, double y) { line(p1.x, p1.y, x, y); } + public void line(double x1, double y1, double x2, double y2) { + g.draw(new Line2D.Double(x1, y1, x2, y2)); + } + + public void color(Color c) { g.setColor(c); } + public void color(int color) { + g.setColor(new Color((color >> 16) & 0xff, + (color >> 8) & 0xff, + (color >> 0) & 0xff + )); + } + +} diff --git a/src/edu/berkeley/obits/gui/Gui.java b/src/edu/berkeley/obits/gui/Gui.java new file mode 100644 index 0000000..e3ba3d8 --- /dev/null +++ b/src/edu/berkeley/obits/gui/Gui.java @@ -0,0 +1,596 @@ +package edu.berkeley.obits.gui; + +import static edu.berkeley.obits.device.atmel.AtmelDevice.Constants.*; +import static edu.berkeley.obits.device.atmel.AtmelDevice.Util.*; +import edu.berkeley.obits.*; +import edu.berkeley.obits.device.atmel.*; +import java.awt.*; +import java.awt.geom.*; +import java.awt.event.*; +import java.awt.color.*; +import org.ibex.util.*; +import java.io.*; +import java.util.*; +import javax.swing.*; + +public class Gui extends ZoomingPanel implements KeyListener, MouseMotionListener { + + Graphics2D g; + G gg; + + public static int SIZE = 92; + public static int RINGS = 3; + public static int BEVEL = 5; + public static int CORE_SIZE = 64; + public static int CORE_OFFSET = 10; + public static int HOFF = 52; + + public static int RED = 0xff0000; + public static int BLUE = 0x0000ff; + + public static final P YLUT_OUTPUT_POINT = new P(SIZE-CORE_OFFSET-CORE_SIZE+51 - 2, CORE_OFFSET + 41 - 3); + public static final P XLUT_OUTPUT_POINT = new P(SIZE-CORE_OFFSET-CORE_SIZE+17 - 2, CORE_OFFSET + 41 - 3); + + At40k at40k; + + private HashSet cells = new HashSet(); + private Cell[][] ca = new Cell[128][]; + + public static final Color nonselectedcell = new Color(0xcc, 0xcc, 0xcc); + public static final Color selectedcell = new Color(0x44, 0x44, 0xff); + + public Gui(At40k at40k) { + this.at40k = at40k; + for(int i=0; i= L0 && plane <= L4 && cell.hx(plane)) { + P p1 = new P(38, 18); + p1 = rotateInner(p1); + if (cell.zi_to_xlut_relevant() && cell.xlut_relevant()) + route(new P(84, 84 - 2*(plane-L0)), p1, 3); + p1 = new P(64, 18); + p1 = rotateInner(p1); + if (cell.zi_to_ylut_relevant() && cell.ylut_relevant()) + route(new P(84, 84 - 2*(plane-L0)), p1, 3); + } + plane = cell.wi(); + if (plane >= L0 && plane <= L4 && cell.hx(plane)) { + P p1 = new P(38, 18); + p1 = rotateInner(p1); + if (cell.zi_to_xlut_relevant() && cell.xlut_relevant()) + route(new P(84, 84 - 2*(plane-L0)), p1, 3); + p1 = rotateInner(new P(64, 18)); + if (cell.zi_to_ylut_relevant() && cell.ylut_relevant()) + route(new P(84, 84 - 2*(plane-L0)), p1, 3); + } + } + public void drawVwires() { + gg.color(Color.magenta); + for(int i=0; i<5; i++) + if (cell.vwire(i).isDriven()) + gg.line(2*(1+RINGS)+2*i, 0, 2*(1+RINGS)+2*i, SIZE); + int plane = cell.zi(); + if (plane >= L0 && plane <= L4 && cell.vx(plane)) { + P p1 = new P(38, 18); + p1 = rotateInner(p1); + if (cell.zi_to_xlut_relevant() && cell.xlut_relevant()) + route(new P(17 - 2*(plane-L0), 8), p1, 3); + p1 = new P(64, 18); + p1 = rotateInner(p1); + if (cell.zi_to_ylut_relevant() && cell.ylut_relevant()) + route(new P(17 - 2*(plane-L0), 8), p1, 3); + } + plane = cell.wi(); + if (plane >= L0 && plane <= L4 && cell.vx(plane)) { + P p1 = new P(38, 18); + p1 = rotateInner(p1); + if (cell.zi_to_xlut_relevant() && cell.xlut_relevant()) + route(new P(17 - 2*(plane-L0), 8), p1, 3); + p1 = new P(64, 18); + p1 = rotateInner(p1); + if (cell.zi_to_ylut_relevant() && cell.ylut_relevant()) + route(new P(17 - 2*(plane-L0), 8), p1, 3); + } + } + public void drawInternalRouting() { + gg.color(new Color(0, 107, 51)); + if (cell.fb_relevant()) { + if (cell.f()) { + gg.line(51, 74, 37, 74); + gg.line(37, 74, 50, 12); + } else if (cell.c() == XLUT) { + gg.line(32, 52, 50, 52); + gg.line(50, 52, 50, 12); + } else if (cell.c() == YLUT) { + gg.line(68, 52, 50, 52); + gg.line(50, 52, 50, 12); + } else { + gg.line(50, 56, 41, 56); + gg.line(41, 56, 50, 12); + } + if (cell.xlut_relevant()) { + gg.line(52, 12, XLUT_OUTPUT_POINT.getX(), 12); + gg.line(XLUT_OUTPUT_POINT.getX(), 12, XLUT_OUTPUT_POINT.getX(), 32); + } + if (cell.ylut_relevant()) { + gg.line(52, 12, YLUT_OUTPUT_POINT.getX(), 12); + gg.line(YLUT_OUTPUT_POINT.getX(), 12, YLUT_OUTPUT_POINT.getX(), 32); + } + } + } + + public void drawLocal() { + if (!cell.ylut_relevant() && !cell.xlut_relevant()) return; + P in = new P(HOFF, 0); + P join = new P(HOFF, CORE_OFFSET); + in = rotateOuter(in); + join = rotateInner(join); + int rot = rot(); + switch(rot) { + case 0: case 2: + join = new P(in.getX(), join.getY()); + break; + case 1: case 3: + join = new P(join.getX(), in.getY()); + break; + } + + P xi = null; + P xi2 = null; + gg.color(new Color(0xff, 0x00, 0x00)); + int xring = 4; + if (cell.xi_relevant() && cell.xlut_relevant()) + switch(cell.xi()) { + case NW: + xi = new P(0+2*xring, SIZE-2*xring); + xi2 = new P(-BEVEL, SIZE+BEVEL); + xi = translate(xi, 0, -3); + xi2 = translate(xi2, 0, -3); + gg.line(xi2, xi); + break; + + case SW: + xi = new P(0+2*xring, 0+2*xring); + xi2 = new P(-BEVEL, -BEVEL); + xi = translate(xi, 0, 3); + xi2 = translate(xi2, 0, 3); + gg.line(xi2, xi); + break; + + case NE: + xi = new P(SIZE-2*xring, SIZE-2*xring); + xi2 = new P(SIZE+BEVEL, SIZE+BEVEL); + xi = translate(xi, 0, -3); + xi2 = translate(xi2, 0, -3); + gg.line(xi2, xi); + break; + + case SE: + xi = new P(SIZE-2*xring, 0+2*xring); + xi2 = new P(SIZE+BEVEL, -BEVEL); + xi = translate(xi, 0, 3); + xi2 = translate(xi2, 0, 3); + gg.line(xi2, xi); + break; + } + + if (cell.xlut_relevant()) { + P c; + gg.color(BLUE); + if (cell.yi_to_xlut_relevant()) + route(in, rotateInner(new P(SIZE - CORE_OFFSET - CORE_SIZE/2 - CORE_SIZE / 6, 20)), 5); + + gg.color(RED); + if (cell.xi_to_xlut_relevant() && xi != null) + route(xi, rotateInner(new P(SIZE - CORE_OFFSET - CORE_SIZE/2 - CORE_SIZE / 3, 20)), 4); + + P xo = XLUT_OUTPUT_POINT; + P xout = new P(SIZE-CORE_OFFSET-CORE_SIZE+17 - 2, CORE_OFFSET + CORE_SIZE - 3); + xo = rotateInner(xo); + xout = rotateInner(xout); + gg.color(new Color(0xff, 0xcc, 0xcc)); + xring = 6; + if (cell.ne() != null && cell.ne().xi()==SW && cell.ne().xi_relevant() && cell.ne().xlut_relevant()) { + gg.line(xo, xout); + P xoo = new P(SIZE-2*xring, SIZE-2*xring); + P xoo2 = new P(SIZE, SIZE); + xoo = translate(xoo, -3, 0); + xoo2 = translate(xoo2, -3, 0); + gg.line(xoo2, xoo); + route(xout, xoo, xring); + } + if (cell.nw() != null && cell.nw().xi()==SE && cell.nw().xi_relevant() && cell.nw().xlut_relevant()) { + gg.line(xo, xout); + P xoo = new P(0+2*xring, SIZE-2*xring); + P xoo2 = new P(0, SIZE); + xoo = translate(xoo, 3, 0); + xoo2 = translate(xoo2, 3, 0); + gg.line(xoo2, xoo); + route(xout, xoo, xring); + } + if (cell.se() != null && cell.se().xi()==NW && cell.se().xi_relevant() && cell.se().xlut_relevant()) { + gg.line(xo, xout); + P xoo = new P(SIZE-2*xring, 0+2*xring); + P xoo2 = new P(SIZE, 0); + xoo = translate(xoo, -3, 0); + xoo2 = translate(xoo2, -3, 0); + gg.line(xoo2, xoo); + route(xout, xoo, xring); + } + if (cell.sw() != null && cell.sw().xi()==NE && cell.sw().xi_relevant() && cell.sw().xlut_relevant()) { + gg.line(xo, xout); + P xoo = new P(0+2*xring, 0+2*xring); + P xoo2 = new P(0, 0); + xoo = translate(xoo, 3, 0); + xoo2 = translate(xoo2, 3, 0); + gg.line(xoo2, xoo); + route(xout, xoo, xring); + } + } + + if (cell.ylut_relevant()) { + gg.color(new Color(0x00, 0x00, 0xff)); + P c; + if (cell.yi_to_ylut_relevant()) { + c = new P(SIZE - CORE_OFFSET - CORE_SIZE/2 + CORE_SIZE / 6, 20); + c = rotateInner(c); + route(in, c, 5); + } + gg.color(new Color(0xff, 0x00, 0x00)); + if (cell.xi_to_ylut_relevant()) { + c = rotateInner(new P(SIZE - CORE_OFFSET - CORE_SIZE/2 + CORE_SIZE / 3, 20)); + if (xi != null) + route(xi, c, 4); + } + + P yo = rotateInner(YLUT_OUTPUT_POINT); + P yout = rotateInner(new P(SIZE-CORE_OFFSET-CORE_SIZE+51 - 2, CORE_OFFSET + CORE_SIZE - 3)); + gg.color(0xbbbbff); + if (cell.north() != null && cell.north().yi()==SOUTH && cell.north().yi_relevant() && cell.north().ylut_relevant()) { + gg.line(yo, yout); + route(yout, new P(SIZE-40, SIZE+ 0), 2); + } + if (cell.east() != null && cell.east().yi()==WEST && cell.east().yi_relevant() && cell.east().ylut_relevant()) { + gg.line(yo, yout); + route(yout, new P(SIZE+ 0, 40), 2); + } + if (cell.south() != null && cell.south().yi()==NORTH && cell.south().yi_relevant() && cell.south().ylut_relevant()) { + gg.line(yo, yout); + route(yout, new P( 40, 0), 2); + } + if (cell.west() != null && cell.west().yi()==EAST && cell.west().yi_relevant() && cell.west().ylut_relevant()) { + gg.line(yo, yout); + route(yout, new P( 0, SIZE-40), 2); + } + } + + } + + + private AffineTransform rotateOuterTransform() { + int rot = rot(); + AffineTransform a = new AffineTransform(); + a.rotate((Math.PI/2) * rot); + switch(rot) { + case 0: break; + case 1: a.translate(0, -SIZE); break; + case 2: a.translate(-SIZE, -SIZE); break; + case 3: a.translate(-SIZE, 0); break; + } + return a; + } + + private P rotateOuter(P p) { return p.transform(rotateOuterTransform()); } + private P rotateInner(P p) { return p.transform(rotateInnerTransform()); } + + private AffineTransform rotateInnerTransform() { + int rot = rot(); + AffineTransform a = new AffineTransform(); + a.translate(SIZE-CORE_SIZE-CORE_OFFSET, CORE_OFFSET); + a.rotate((Math.PI/2) * rot); + switch(rot) { + case 0: break; + case 1: a.translate(0, -CORE_SIZE); break; + case 2: a.translate(-CORE_SIZE, -CORE_SIZE); break; + case 3: a.translate(-CORE_SIZE, 0); break; + } + a.translate(-1 * (SIZE-CORE_SIZE-CORE_OFFSET), -CORE_OFFSET); + return a; + } + + + private P project(P p1, int ring) { + double north = Math.abs( (SIZE-(ring*2)) - p1.getY() ); + double south = Math.abs( ( (ring*2)) - p1.getY() ); + double east = Math.abs( (SIZE-(ring*2)) - p1.getX() ); + double west = Math.abs( ( (ring*2)) - p1.getX() ); + if (north < south && north < east && north < west) return new P(p1.x, SIZE-ring*2); + else if (south < east && south < west) return new P(p1.x, ring*2); + else if (east < west) return new P(SIZE-ring*2, p1.y); + else return new P(ring*2, p1.y); + + } + + private void route(P p1, P p2, int ring) { + int ringpos = ring * 2; + P projected = project(p1, ring); + gg.line(p1, projected); + p1 = projected; + + projected = project(p2, ring); + gg.line(p2, projected); + p2 = projected; + + double x1 = p1.getX(); + double y1 = p1.getY(); + double x2 = p2.getX(); + double y2 = p2.getY(); + + if (x1==x2 || y1==y2) { + gg.line(p1, p2); + return; + } + + if ((x1==SIZE-ring*2 || x1==ring*2) && !(y1==SIZE-ring*2 || y1==ring*2)) { + P p3 = new P(x1, y2 > SIZE/2 ? SIZE-ring*2 : ring*2); + gg.line(p1, p3); + route(p3, p2, ring); + } else if ((y1==SIZE-ring*2 || y1==ring*2) && !(x1==SIZE-ring*2 || x1==ring*2)) { + P p3 = new P(x2 > SIZE/2 ? SIZE-ring*2 : ring*2, y1); + gg.line(p1, p3); + route(p3, p2, ring); + } else + route(p2, p1, ring); + + } + + private int rot() { + int rot = 0; + switch(cell.yi()) { + case SOUTH: rot = 0; break; + case NORTH: rot = 2; break; + case EAST: rot = 1; break; + case WEST: rot = 3; break; + default: { + // FIXME: choose based on xin + if (cell.north() != null && cell.north().yi()==SOUTH) { rot = 0; break; } + if (cell.south() != null && cell.south().yi()==NORTH) { rot = 2; break; } + if (cell.east() != null && cell.east().yi()==WEST) { rot = 3; break; } + if (cell.west() != null && cell.west().yi()==EAST) { rot = 1; break; } + } + } + return rot; + } + + public void drawGates() { + AffineTransform t = g.getTransform(); + try { + g.translate(SIZE-CORE_SIZE-CORE_OFFSET, CORE_OFFSET); + + int rot = rot(); + g.rotate((Math.PI/2) * rot); + switch(rot) { + case 0: break; + case 1: g.translate(0, -CORE_SIZE); break; + case 2: g.translate(-CORE_SIZE, -CORE_SIZE); break; + case 3: g.translate(-CORE_SIZE, 0); break; + } + + //gg.color(Color.gray); + //g.drawRect(0, 0, CORE_SIZE, CORE_SIZE); + g.scale(1, -1); + + GeneralPath p = new GeneralPath(); + p.moveTo(29.141f, 36.301f); + p.lineTo(29.141f, 36.301f-7.161f); + p.curveTo(27.71f, 11.24f, 23.413f, 9.45f, 14.82f, 0.5f); + p.curveTo(6.229f, 9.45f, 1.932f, 11.24f, 0.5f, 29.141f); + p.lineTo(0.5f, 29.141f+7.161f); + float x = 0.5f; + float y = 29.141f+7.161f; + p.curveTo(5.729f+x, -1.789f+y, + 6.444f+x, -2.686f+y, + 14.32f+x, -3.58f+y); + p.curveTo(22.697f, 33.616f, 23.413f, 34.512f, 29.141f, 36.301f); + g.translate(0, -40f); + if (cell.xlut_relevant()) { + gg.color(Color.white); + g.fill(p); + gg.color(Color.red); + g.draw(p); + } + g.translate(34f, 0f); + if (cell.ylut_relevant()) { + gg.color(Color.white); + g.fill(p); + gg.color(Color.blue); + g.draw(p); + } + } finally { + g.setTransform(t); + } + } + public void drawMux() { + if (!cell.c_relevant()) return; + gg.color(Color.black); + if (cell.xlut_relevant() && (cell.c() == ZMUX || cell.c() == XLUT)) { + gg.color(new Color(0xff, 0xbb, 0xbb)); + gg.line(XLUT_OUTPUT_POINT, new P(XLUT_OUTPUT_POINT.getX(), 52)); + gg.line(new P(XLUT_OUTPUT_POINT.getX(), 52), new P(51, 52)); + } + if (cell.ylut_relevant() && (cell.c() == ZMUX || cell.c() == YLUT)) { + gg.color(new Color(0xbb, 0xbb, 0xff)); + gg.line(YLUT_OUTPUT_POINT, new P(YLUT_OUTPUT_POINT.getX(), 52)); + gg.line(new P(YLUT_OUTPUT_POINT.getX(), 52), new P(51, 52)); + } + gg.line(51, 52, 51, 51+25); + if (cell.c() == ZMUX) { + gg.color(Color.black); + gg.line(51, 52, 51, 51+25); + gg.line(46, 54, 46+2, 54+5); + gg.line(46+2, 54+5, 60-2, 54+5); + gg.line(60-2, 54+5, 60, 54); + gg.line(60, 54, 46, 54); + } + } + public void drawRegister() { + if (!cell.register_relevant()) return; + gg.color(Color.white); + g.fillRect(48, 58, 10, 14); + gg.color(Color.black); + g.drawRect(48, 58, 10, 14); + gg.line(57, 70, 54, 68); + gg.line(54, 68, 57, 66); + } + public void drawBorder() { + gg.color(Color.gray); + //gg.line(0, BEVEL, BEVEL, 0); + gg.line(BEVEL, 0, SIZE-BEVEL, 0); + //gg.line(SIZE-BEVEL, 0, SIZE, BEVEL); + gg.line(SIZE, BEVEL, SIZE, SIZE-BEVEL); + //gg.line(SIZE, SIZE-BEVEL, SIZE-BEVEL, SIZE); + gg.line(SIZE-BEVEL, SIZE, BEVEL, SIZE); + //gg.line(BEVEL, SIZE, 0, SIZE-BEVEL); + gg.line(0, SIZE-BEVEL, 0, BEVEL); + } + } + + public void _paint(Graphics2D g) { + + this.g = g; + this.gg = new G(g); + g.setStroke(new BasicStroke((float)0.5)); + + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + + AffineTransform t = g.getTransform(); + for(Cell c : cells) { + g.setTransform(t); + g.translate( c._x * SIZE/* + (10 * (c._x/4))*/, c._y * SIZE/* + (10 * (c._y/4))*/); + c.draw(); + } + g.setTransform(t); + + g.setTransform(new AffineTransform()); + + gg.color(selectedcell); + g.fillRect(getWidth() - 200, 0, 200, 100); + gg.color(Color.white); + g.drawRect(getWidth() - 200, 0, 200, 100); + + Cell newcell = whichCell(mousex, mousey); + int line = 10; + if (newcell != null && newcell.cell != null) { + g.drawString("selected: " + newcell._x + ","+newcell._y, + getWidth() - 200 + 10, (line += 15)); + g.drawString(" xlut: " + AtmelSerial.bin8(newcell.cell.xlut()), + getWidth() - 200 + 10, (line += 15)); + g.drawString(" ylut: " + AtmelSerial.bin8(newcell.cell.ylut()), + getWidth() - 200 + 10, (line += 15)); + String xi = "??"; + switch(newcell.cell.xi()) { + case NW : xi = "NW"; break; + case NE : xi = "NE"; break; + case SW : xi = "SW"; break; + case SE : xi = "SE"; break; + } + g.drawString(" xi: " + xi, getWidth() - 200 + 10, (line += 15)); + String yi = "??"; + switch(newcell.cell.yi()) { + case NORTH : yi = "NORTH"; break; + case SOUTH : yi = "SOUTH"; break; + case EAST : yi = "EAST"; break; + case WEST : yi = "WEST"; break; + } + g.drawString(" yi: " + yi, getWidth() - 200 + 10, (line += 15)); + } + this.g = null; + this.gg = null; + } + + + public void clear() { + Graphics2D g = (Graphics2D)getGraphics(); + //gg.color(Color.black); + //gg.color(Color.lightGray); + g.clearRect(0, 0, getWidth(), getHeight()); + } + + public static final P translate(P p, int dx, int dy) { + return new P(p.getX()+dx, p.getY()+dy); + } + + public Cell whichCell(int x, int y) { + P p = new P(x,y); + try { + p = p.inverseTransform(transform); + } catch (Exception e) { + e.printStackTrace(); + } + int col = ((int)p.getX()) / (SIZE + BEVEL); + int row = ((int)p.getY()) / (SIZE + BEVEL); + for(Cell c : cells) + if (c._x == col && c._y == row) + return c; + return null; + } +} diff --git a/src/edu/berkeley/obits/gui/P.java b/src/edu/berkeley/obits/gui/P.java new file mode 100644 index 0000000..3adac06 --- /dev/null +++ b/src/edu/berkeley/obits/gui/P.java @@ -0,0 +1,40 @@ +package edu.berkeley.obits.gui; + +import static edu.berkeley.obits.device.atmel.AtmelDevice.Constants.*; +import static edu.berkeley.obits.device.atmel.AtmelDevice.Util.*; +import edu.berkeley.obits.*; +import edu.berkeley.obits.device.atmel.*; +import java.awt.*; +import java.awt.geom.*; +import java.awt.event.*; +import java.awt.color.*; +import org.ibex.util.*; +import java.io.*; +import java.util.*; +import javax.swing.*; + +/** a point, since Java2D's Point2D class sucks rocks */ +public class P { + + public final double x; + public final double y; + + public P(double x, double y) { this.x = x; this.y = y; } + public P(Point2D p) { this(p.getX(), p.getY()); } + public double getX() { return x; } + public double getY() { return y; } + + public P transform(AffineTransform a) { + Point2D me = new Point2D.Double(x, y); + return new P(a.transform(me, me)); + } + public P inverseTransform(AffineTransform a) { + try { + Point2D me = new Point2D.Double(x, y); + return new P(a.inverseTransform(me, me)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + +} diff --git a/src/edu/berkeley/obits/gui/ZoomingPanel.java b/src/edu/berkeley/obits/gui/ZoomingPanel.java new file mode 100644 index 0000000..a36bbcb --- /dev/null +++ b/src/edu/berkeley/obits/gui/ZoomingPanel.java @@ -0,0 +1,146 @@ +package edu.berkeley.obits.gui; + +import static edu.berkeley.obits.device.atmel.AtmelDevice.Constants.*; +import static edu.berkeley.obits.device.atmel.AtmelDevice.Util.*; +import edu.berkeley.obits.*; +import edu.berkeley.obits.device.atmel.*; +import java.awt.*; +import java.awt.geom.*; +import java.awt.event.*; +import java.awt.color.*; +import org.ibex.util.*; +import java.io.*; +import java.util.*; +import javax.swing.*; + +public abstract class ZoomingPanel extends JComponent implements KeyListener, MouseMotionListener { + + double scale = 1.0; + double oscale = 1.0; + public int dragx = 0; + public int dragy = 0; + public boolean drag = false; + protected int mousex; + protected int mousey; + protected AffineTransform transform = new AffineTransform(); + private Point2D recenter; + private Point2D recenter2; + + public ZoomingPanel() { + setDoubleBuffered(true); + addKeyListener(this); + addMouseMotionListener(this); + } + + public abstract void _paint(Graphics2D g); + + public final void paint(Graphics _g) { + Graphics2D g = (Graphics2D)_g; + g.scale(scale,scale); + g.translate(10, 0); + g.scale(1, -1); + g.translate(5, -1 * getHeight() + 10); + + transform = g.getTransform(); + + Point2D p = new Point2D.Float(); + if (recenter != null) { + transform.transform(recenter, p); + transform.preConcatenate(AffineTransform.getTranslateInstance(dragx - p.getX(), + dragy - p.getY())); + } + g.setTransform(transform); + + if (drag) { + g.setColor(Color.blue); + g.drawLine((int)(recenter.getX() - 10), + (int)(recenter.getY() - 10), + (int)(recenter.getX() + 10), + (int)(recenter.getY() + 10)); + g.drawLine((int)(recenter.getX() + 10), + (int)(recenter.getY() - 10), + (int)(recenter.getX() - 10), + (int)(recenter.getY() + 10)); + } + _paint(g); + } + + + public void keyTyped(KeyEvent k) { + } + public void keyReleased(KeyEvent k) { + if (k.getKeyCode() == k.VK_ALT) { + if (drag) { + drag = false; + oscale = scale; + repaint(); + } + } + } + public void keyPressed(KeyEvent k) { + if (k.getKeyCode() == k.VK_ALT) { + drag = true; + dragx = mousex; + dragy = mousey; + recenter = new Point2D.Float(dragx, dragy); + try { + transform.inverseTransform(recenter, recenter); + } catch (Exception e) { + e.printStackTrace(); + } + } + char c = k.getKeyChar(); + switch(c) { + case '+': scale += 0.1; repaint(); return; + case '-': scale -= 0.1; repaint(); return; + case 'z': scale = 1.0; recenter = null; repaint(); return; + } + } + public void mouseMoved(MouseEvent m) { + /* + Cell oldcell = whichCell(mousex, mousey); + Cell newcell = whichCell(m.getX(), m.getY()); + System.out.println((oldcell==null ? "old=null" : ("old=" + oldcell._x+","+oldcell._y+" "))+ + (newcell==null ? "new=null" : ("new=" + newcell._x+","+newcell._y+" "))); + if (oldcell != newcell) { + if (oldcell != null) oldcell.in = false; + if (newcell != null) newcell.in = true; + repaint(); + } + */ + mousex = m.getX(); + mousey = m.getY(); + if (drag) { + if (mousey > dragy + 5) { + scale = 1 / ((1 / oscale) + ((mousey - dragy) / 50.0)); + } else if (mousey < dragy - 5) { + scale = oscale + ((dragy - mousey) / 50.0); + } else { + scale = oscale; + } + repaint(); + } + } + + + public boolean isFocusable() { return true; } + + public void mouseDragged(MouseEvent m) { + mouseMoved(m); + dragx = m.getX(); + dragy = m.getY(); + } + public void mousePressed(MouseEvent m) { + recenter = new Point2D.Float(m.getX(), m.getY()); + try { + transform.transform(recenter, recenter); + } catch (Exception e) { + e.printStackTrace(); + } + repaint(); + } + public void mouseEntered(MouseEvent e) { } + public void mouseExited(MouseEvent e) { } + public void mouseClicked(MouseEvent e) { } + public void mouseReleased(MouseEvent e) { } +}