From d3a0cc3a8ba6dfeb64d3faeffdeb6845b60e5840 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Sat, 20 Jan 2018 15:41:49 +0100 Subject: rearranged the dir for github - removed tools and pdfs - rearranged the projects dirs - added md files - other minor changes --- jackos/Screen.jack | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 jackos/Screen.jack (limited to 'jackos/Screen.jack') diff --git a/jackos/Screen.jack b/jackos/Screen.jack new file mode 100644 index 0000000..a370ab9 --- /dev/null +++ b/jackos/Screen.jack @@ -0,0 +1,138 @@ +// This file is part of www.nand2tetris.org +// and the book "The Elements of Computing Systems" +// by Nisan and Schocken, MIT Press. +// File name: projects/12/Screen.jack + +/** + * A library of functions for displaying graphics on the screen. + * The Hack physical screen consists of 512 rows (indexed 0..511, top to bottom) + * of 256 pixels each (indexed 0..255, left to right). The top left pixel on + * the screen is indexed (0,0). + */ +class Screen { + static Array twoToThe; + static Array screen; + static boolean color; + + /** Initializes the Screen. */ + function void init() { + var int i, x; + let x = 1; + let i = 0; + let twoToThe = Array.new(16); + while (i < 16){ + let twoToThe[i] = x; + let x = x + x; + let i = i + 1; + } + let screen = 16384; + let color = true; + return; + } + + /** Erases the entire screen. */ + function void clearScreen() { + var boolean c; + let c = color; + let color = false; + do Screen.drawRectangle(0, 0, 511, 255); + let color = c; + return; + } + + /** Sets the current color, to be used for all subsequent drawXXX commands. + * Black is represented by true, white by false. */ + function void setColor(boolean b) { + let color = b; + return; + } + + /** Draws the (x,y) pixel, using the current color. */ + function void drawPixel(int x, int y) { + var int addr, t; + if ((x < 0) | (y < 0) | (x > 511) | (y > 255)) { + //String.println("drawPixel: coordinates out of range!"); + //Sys.error(2); + return; + } + let t = x / 16; + let addr = 32 * y + t; + if (color) { + let screen[addr] = screen[addr] | twoToThe[x - (t * 16)]; + } else { + let screen[addr] = screen[addr] & (- (twoToThe[x - (t * 16)] + 1)); + } + return; + } + + /** Draws a line from pixel (x1,y1) to pixel (x2,y2), using the current color. */ + function void drawLine(int x1, int y1, int x2, int y2) { + var int dx, dy, x, y, a, b, diff; + let x = x1; + let y = y1; + do Screen.drawPixel(x, y); + if (x1 = x2) { + if (y1 = y2) { + return; + } else { + let diff = 1; + } + } else { + if (y1 = y2) { + let diff = -1; + } else { + let diff = 0; + } + } + let dx = x2 - x1; + let dy = y2 - y1; + let a = Math.sign(dx); + let b = Math.sign(dy); + let dx = Math.abs(dx); + let dy = Math.abs(dy); + while (~((x = x2) & (y = y2))) { + if (diff < 0){ + let x = x + a; + let diff = diff + dy; + } else { + let y = y + b; + let diff = diff - dx; + } + do Screen.drawPixel(x, y); + } + return; + } + + /** Draws a filled rectangle whose top left corner is (x1, y1) + * and bottom right corner is (x2,y2), using the current color. */ + function void drawRectangle(int x1, int y1, int x2, int y2) { + var int x; + if ((x1 > x2) | (y1 > y2)) { + return; + } + let x = x1; + while (~(x > x2)) { + do Screen.drawLine(x, y1, x, y2); + let x = x + 1; + } + return; + } + + /** Draws a filled circle of radius r<=181 around (x,y), using the current color. */ + function void drawCircle(int x, int y, int r) { + var int dx, dy, r2; + if (r > 181) { + do String.println("drawCircle: radius too big!"); + do Sys.error(2); + return; + } + let dy = -r; + let r2 = r * r; + while (~(dy > r)) { + let dx = Math.sqrt(r2 - (dy * dy)); + do Screen.drawLine(x - dx, y + dy, x + dx, y + dy); + let dy = dy + 1; + } + return; + } +} -- cgit v1.2.3