/Users/petercappello/NetBeansProjects/56-2014/56-2014-2-GraphicsVM/src/GVM.java |
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
Graphics Virtual Machine
@author
public class GVM
{
private final static int DATA_MEMORY_SIZE = 100;
private final static int OPCODE = 0;
private final static int OPERAND = 1;
private final static int STOP = 0;
private final static int SET = 1;
private final static int LOAD = 2;
private final static int STORE = 3;
private final static int ADD = 4;
private final static int ZERO = 5;
private final static int GOTO = 6;
private final static int SETCOLOR = 7;
private final static int DRAWLINE = 8;
private final static int DRAWRECT = 9;
private final static int FILLRECT = 10;
private final static int DRAWOVAL = 11;
private final static int FILLOVAL = 12;
private final static int ACC = 0;
private final static int X = 1;
private final static int Y = 2;
private final static int WIDTH = 3;
private final static int HEIGHT = 4;
private final static int RED = 5;
private final static int GREEN = 6;
private final static int BLUE = 7;
final static int IMAGE_SIZE = 800;
private final Image image;
private final Graphics graphics;
private final int[] dataMemory = new int[ DATA_MEMORY_SIZE ];
private int[][] programMemory;
private int instructionAddress = 0;
private Color color;
GVM()
{
image = new BufferedImage( IMAGE_SIZE, IMAGE_SIZE, BufferedImage.TYPE_INT_RGB );
graphics = image.getGraphics();
graphics.setColor( Color.white );
graphics.fillRect( 0, 0, IMAGE_SIZE, IMAGE_SIZE );
color = Color.black;
graphics.setColor( color );
}
public Image getImage() { return image; }
void load()
{
int DECREMENT = 20;
int ROW_COUNTER = 21;
int COLUMN_COUNTER = 22;
int DELTA = 23;
int FILL_SQUARE_OVAL_BLOCK = 9;
int IS_RED = 16;
int IF_ADVANCE_COLUMN = 20;
int ADVANCE_COLUMN = 29;
int ADVANCE_ROW = 33;
int N = 17;
int DELTA_VALUE = 40;
programMemory = new int[][]
{
{ SET, -1 },
{ STORE, DECREMENT },
{ SET, DELTA_VALUE },
{ STORE, DELTA },
{ STORE, WIDTH },
{ STORE, HEIGHT },
{ SET, N },
{ STORE, ROW_COUNTER },
{ STORE, COLUMN_COUNTER },
{ LOAD, RED },
{ ZERO, IS_RED },
{ SET, 255 },
{ STORE, RED },
{ SETCOLOR },
{ FILLOVAL },
{ GOTO, IF_ADVANCE_COLUMN },
{ SET, 0 },
{ STORE, RED },
{ SETCOLOR },
{ FILLRECT },
{ LOAD, COLUMN_COUNTER },
{ ADD, DECREMENT },
{ STORE, COLUMN_COUNTER },
{ ZERO, ADVANCE_COLUMN },
{ LOAD, ROW_COUNTER },
{ ADD, DECREMENT },
{ STORE, ROW_COUNTER },
{ ZERO, ADVANCE_ROW },
{ STOP },
{ LOAD, X },
{ ADD, DELTA },
{ STORE, X },
{ GOTO, FILL_SQUARE_OVAL_BLOCK },
{ LOAD, Y },
{ ADD, DELTA },
{ STORE, Y },
{ SET, 0 },
{ STORE, X },
{ SET, N },
{ STORE, COLUMN_COUNTER },
{ GOTO, FILL_SQUARE_OVAL_BLOCK }
};
}
void step()
{
if ( programMemory[ instructionAddress ][ OPCODE] != STOP )
{
executeInstruction( programMemory[ instructionAddress ] );
}
else
{
System.out.print(" STOP. " );
}
}
void run()
{
while ( programMemory[ instructionAddress ][ OPCODE] != STOP )
{
executeInstruction( programMemory[ instructionAddress ] );
}
System.out.println(" Program has executed a STOP instruction. " );
}
private void executeInstruction( int[] instruction )
{
System.out.println( "instruction address: " + instructionAddress
+ " OPCODE: " + instruction[ OPCODE ]
+ " "
+ instructionToString( instruction ) );
int nextInstructionAddress = instructionAddress + 1;
switch ( instruction[ OPCODE ] )
{
case SET:
dataMemory[ ACC ] = instruction[ OPERAND ];
break;
case LOAD:
dataMemory[ ACC ] = dataMemory[ instruction[ OPERAND ] ];
break;
case STORE:
dataMemory[ instruction[ OPERAND ] ] = dataMemory[ ACC ];
break;
case ADD:
dataMemory[ ACC ] += dataMemory[ instruction[ OPERAND ] ];
break;
case ZERO:
if ( dataMemory[ ACC ] != 0 )
{
nextInstructionAddress = instruction[ OPERAND ];
}
break;
case GOTO:
nextInstructionAddress = instruction[ OPERAND ];
break;
case SETCOLOR:
color = new Color( dataMemory[ RED ], dataMemory[ GREEN ], dataMemory[ BLUE ] );
graphics.setColor( color );
break;
case DRAWLINE:
graphics.drawLine( dataMemory[ X ], dataMemory[ Y ], dataMemory[ X ] + dataMemory[ WIDTH ], dataMemory[ Y ] + dataMemory[ HEIGHT ] );
break;
case DRAWRECT:
graphics.drawRect( dataMemory[ X ], dataMemory[ Y ], dataMemory[ WIDTH ], dataMemory[ HEIGHT ] );
break;
case FILLRECT:
graphics.fillRect( dataMemory[ X ], dataMemory[ Y ], dataMemory[ WIDTH ], dataMemory[ HEIGHT ] );
break;
case DRAWOVAL:
graphics.drawOval( dataMemory[ X ], dataMemory[ Y ], dataMemory[ WIDTH ], dataMemory[ HEIGHT ] );
break;
case FILLOVAL:
graphics.fillOval( dataMemory[ X ], dataMemory[ Y ], dataMemory[ WIDTH ], dataMemory[ HEIGHT ] );
break;
default :
assert false : "Invalid operation code: " + instruction[ OPCODE ];
}
instructionAddress = nextInstructionAddress;
}
private String instructionToString( int[] instruction )
{
StringBuilder string = new StringBuilder();
string.append( opcodeMneumonics[ instruction[ OPCODE ] ] ).append( ' ');
switch ( instruction[ OPCODE ] )
{
case SET: case GOTO:
string.append( instruction[ OPERAND ] );
break;
case LOAD:
string.append(instruction[ OPERAND ]).append(" memory cell value: ").append( dataMemory[ instruction[ OPERAND ] ]);
break;
case STORE:
string.append(dataMemory[ ACC ]).append(" in memory cell ").append(instruction[ OPERAND ]).append(" cell: ").append( dataMemory[ ACC ]);
break;
case ADD:
string.append("datamemory[ ").append(instruction[ OPERAND ]).append(" ] of value: ").append( instruction[ OPERAND ] ).append(" to ACC: ").append( dataMemory[ ACC ]);
break;
case ZERO:
string.append("ACC: [ ").append( dataMemory[ ACC ]).append( " ] ");
if ( dataMemory[ ACC ] != 0 )
{
string.append(" branching to ").append( instruction[ OPERAND ]);
}
break;
case SETCOLOR:
string.append( color );
break;
case DRAWLINE: case DRAWRECT: case FILLRECT: case DRAWOVAL: case FILLOVAL:
string.append(" X: ").append(dataMemory[ X ]).append(" Y: ").append(dataMemory[ Y ]).append(" W: ").append(dataMemory[ WIDTH ]).append(" H: ").append(dataMemory[ HEIGHT ]);
break;
default :
assert false : "Invalid operation code: " + instruction[ OPCODE ];
}
return string.toString();
}
private final String[] opcodeMneumonics =
{
"stop",
"set",
"load",
"store",
"add",
"zero",
"goto",
"setcColor",
"drawLine",
"drawRect",
"fillRect",
"drawOval",
"fillOval"
};
}