mirror of
https://github.com/soconnor0919/eceg431.git
synced 2025-12-11 22:54:43 -05:00
project12 - complete
This commit is contained in:
143
12/Screen.jack
143
12/Screen.jack
@@ -9,34 +9,175 @@
|
||||
* the screen is indexed (0,0).
|
||||
*/
|
||||
class Screen {
|
||||
|
||||
static boolean color;
|
||||
static Array powersOfTwo; // Helper for bit manipulation
|
||||
|
||||
/** Initializes the Screen. */
|
||||
function void init() {
|
||||
let color = true; // Default black
|
||||
let powersOfTwo = Array.new(16);
|
||||
let powersOfTwo[0] = 1;
|
||||
let powersOfTwo[1] = 2;
|
||||
let powersOfTwo[2] = 4;
|
||||
let powersOfTwo[3] = 8;
|
||||
let powersOfTwo[4] = 16;
|
||||
let powersOfTwo[5] = 32;
|
||||
let powersOfTwo[6] = 64;
|
||||
let powersOfTwo[7] = 128;
|
||||
let powersOfTwo[8] = 256;
|
||||
let powersOfTwo[9] = 512;
|
||||
let powersOfTwo[10] = 1024;
|
||||
let powersOfTwo[11] = 2048;
|
||||
let powersOfTwo[12] = 4096;
|
||||
let powersOfTwo[13] = 8192;
|
||||
let powersOfTwo[14] = 16384;
|
||||
let powersOfTwo[15] = 16384 + 16384; // 32768 (negative in 16-bit)
|
||||
return;
|
||||
}
|
||||
|
||||
/** Erases the entire screen. */
|
||||
function void clearScreen() {
|
||||
var int i;
|
||||
let i = 16384;
|
||||
while(i < 24576) {
|
||||
do Memory.poke(i, 0);
|
||||
let i = i + 1;
|
||||
}
|
||||
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 address, value;
|
||||
var int mask;
|
||||
|
||||
let address = 16384 + (y * 32) + (x / 16);
|
||||
let value = Memory.peek(address);
|
||||
|
||||
// Calculate 2^(x%16) logic inline or helper?
|
||||
// x & 15 is x % 16
|
||||
let mask = powersOfTwo[x & 15];
|
||||
|
||||
if (color) {
|
||||
let value = value | mask;
|
||||
} else {
|
||||
let value = value & ~mask;
|
||||
}
|
||||
|
||||
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 dx, dy;
|
||||
var int a, b;
|
||||
var int diff;
|
||||
var int temp;
|
||||
|
||||
if (x1 > x2) {
|
||||
let temp = x1;
|
||||
let x1 = x2;
|
||||
let x2 = temp;
|
||||
let temp = y1;
|
||||
let y1 = y2;
|
||||
let y2 = temp;
|
||||
}
|
||||
|
||||
let dx = x2 - x1;
|
||||
let dy = y2 - y1;
|
||||
let a = 0;
|
||||
let b = 0;
|
||||
let diff = 0;
|
||||
|
||||
// Vertical line
|
||||
if (dx = 0) {
|
||||
if (y1 > y2) {
|
||||
let temp = y1;
|
||||
let y1 = y2;
|
||||
let y2 = temp;
|
||||
}
|
||||
while (~(y1 > y2)) {
|
||||
do Screen.drawPixel(x1, y1);
|
||||
let y1 = y1 + 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Horizontal line
|
||||
if (dy = 0) {
|
||||
while (~(x1 > x2)) {
|
||||
do Screen.drawPixel(x1, y1);
|
||||
let x1 = x1 + 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Diagonal
|
||||
if (dy > 0) {
|
||||
while ((~(a > dx)) & (~(b > dy))) {
|
||||
do Screen.drawPixel(x1 + a, y1 + b);
|
||||
if (diff < 0) {
|
||||
let a = a + 1;
|
||||
let diff = diff + dy;
|
||||
} else {
|
||||
let b = b + 1;
|
||||
let diff = diff - dx;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while ((~(a > dx)) & (~(b < dy))) {
|
||||
do Screen.drawPixel(x1 + a, y1 + b);
|
||||
if (diff < 0) {
|
||||
let a = a + 1;
|
||||
let diff = diff - dy; // dy is negative
|
||||
} else {
|
||||
let b = b - 1;
|
||||
let diff = diff - dx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 r;
|
||||
let r = y1;
|
||||
while (~(r > y2)) {
|
||||
do Screen.drawLine(x1, r, x2, r); // reuse line for now for simplicity
|
||||
let r = r + 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 dy;
|
||||
var int r2;
|
||||
var int halfWidth;
|
||||
|
||||
if (r > 181) {
|
||||
return; // overflow check
|
||||
}
|
||||
|
||||
let dy = -r;
|
||||
let r2 = r*r;
|
||||
|
||||
while (~(dy > r)) {
|
||||
let halfWidth = Math.sqrt(r2 - (dy*dy));
|
||||
do Screen.drawLine(x - halfWidth, y + dy, x + halfWidth, y + dy);
|
||||
let dy = dy + 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user