Add solutions for part 1
This commit is contained in:
178
projects/12/ScreenTest/Screen.jack
Normal file
178
projects/12/ScreenTest/Screen.jack
Normal file
@@ -0,0 +1,178 @@
|
||||
// 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 boolean color;
|
||||
|
||||
/** Initializes the Screen. */
|
||||
function void init() {
|
||||
let color = true;
|
||||
return;
|
||||
}
|
||||
|
||||
/** Erases the entire screen. */
|
||||
function void clearScreen() {
|
||||
var int i;
|
||||
var Array a;
|
||||
|
||||
let i = 0;
|
||||
let a = 16384;
|
||||
|
||||
while (i < 8192) {
|
||||
let a[i] = 0;
|
||||
let i = i + 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
function int modulo(int a, int b) {
|
||||
var int d;
|
||||
let d = a / b;
|
||||
return a - (d * b);
|
||||
}
|
||||
|
||||
/** 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 address;
|
||||
var int value;
|
||||
var int i;
|
||||
var int mask;
|
||||
var int inverseMask;
|
||||
var int pixel;
|
||||
|
||||
let pixel = Screen.modulo(x, 16);
|
||||
|
||||
let i = 0;
|
||||
let mask = 1;
|
||||
while (~(i = pixel)) {
|
||||
let mask = mask + mask;
|
||||
let i = i + 1;
|
||||
}
|
||||
let inverseMask = ~mask;
|
||||
|
||||
let address = 16384 + (32 * y) + (x / 16);
|
||||
let value = Memory.peek(address);
|
||||
|
||||
if (color) {
|
||||
let value = ((value & inverseMask) | ((-1) & mask)); // pixel gets set to 1
|
||||
} else {
|
||||
let value = (value & inverseMask); // pixel gets set to 0
|
||||
}
|
||||
do Memory.poke(address, value);
|
||||
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 a, b, diff, dx, dy, xinc, yinc;
|
||||
var boolean continue;
|
||||
|
||||
let a = 0;
|
||||
let b = 0;
|
||||
let diff = 0;
|
||||
let dx = Math.abs(x2 - x1);
|
||||
let dy = Math.abs(y2 - y1);
|
||||
let continue = true;
|
||||
|
||||
if (x2 > x1) {
|
||||
let xinc = 1; // going from left to right;
|
||||
} else {
|
||||
let xinc = -1; // going from right to left;
|
||||
}
|
||||
|
||||
if (y2 > y1) {
|
||||
let yinc = 1; // going from top to bottom
|
||||
} else {
|
||||
let yinc = -1; // going from bottom to top
|
||||
}
|
||||
|
||||
// vertical line
|
||||
if (dx = 0) {
|
||||
while (~(y1 = y2)) {
|
||||
do Screen.drawPixel(x1, y1);
|
||||
let y1 = y1 + yinc;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// horizontal line
|
||||
if (dy = 0) {
|
||||
while (~(x1 = x2)) {
|
||||
do Screen.drawPixel(x1, y1);
|
||||
let x1 = x1 + xinc;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
while (continue) {
|
||||
do Screen.drawPixel(x1 + a, y1 + b);
|
||||
if (diff < 0) {
|
||||
let a = a + xinc;
|
||||
let diff = diff + dy;
|
||||
} else {
|
||||
let b = b + yinc;
|
||||
let diff = diff - dx;
|
||||
}
|
||||
|
||||
if ((x1 + a) = x2) {
|
||||
if ((y1 + b) = y2) {
|
||||
let continue = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 yinc;
|
||||
if (y2 > y1) {
|
||||
let yinc = 1;
|
||||
} else {
|
||||
let yinc = -1;
|
||||
}
|
||||
|
||||
while (~(y1 = y2)) {
|
||||
do Screen.drawLine(x1, y1, x2, y1);
|
||||
let y1 = y1 + yinc;
|
||||
}
|
||||
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 dy;
|
||||
var int halfSegment;
|
||||
let dy = -r;
|
||||
|
||||
if (r > 181) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (dy < (r + 1)) {
|
||||
let halfSegment = Math.sqrt((r * r) - (dy * dy));
|
||||
do Screen.drawLine(x - halfSegment, y + dy, x + halfSegment, y + dy);
|
||||
let dy = dy + 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user