[O] BitmapDisplay > Kt
This commit is contained in:
@@ -1,647 +0,0 @@
|
||||
package mars.tools;
|
||||
|
||||
import mars.mips.hardware.AccessNotice;
|
||||
import mars.mips.hardware.Memory;
|
||||
import mars.mips.hardware.MemoryAccessNotice;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Observable;
|
||||
|
||||
/*
|
||||
Copyright (c) 2010-2011, Pete Sanderson and Kenneth Vollmar
|
||||
|
||||
Developed by Pete Sanderson (psanderson@otterbein.edu)
|
||||
and Kenneth Vollmar (kenvollmar@missouristate.edu)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject
|
||||
to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
(MIT license, http://www.opensource.org/licenses/mit-license.html)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bitmapp display simulator. It can be run either as a stand-alone Java application having access to the mars package,
|
||||
* or through MARS as an item in its Tools menu. It makes maximum use of methods inherited from its abstract superclass
|
||||
* AbstractMarsToolAndApplication. Pete Sanderson, verison 1.0, 23 December 2010.
|
||||
*/
|
||||
public class BitmapDisplay extends AbstractMarsToolAndApplication
|
||||
{
|
||||
|
||||
private static final String version = "Version 1.0";
|
||||
|
||||
private static final String heading = "Bitmap Display";
|
||||
|
||||
private final String[] visualizationUnitPixelWidthChoices = {"1", "2", "4", "8", "16", "32"};
|
||||
|
||||
private final int defaultVisualizationUnitPixelWidthIndex = 0;
|
||||
|
||||
private final String[] visualizationUnitPixelHeightChoices = {"1", "2", "4", "8", "16", "32"};
|
||||
|
||||
private final int defaultVisualizationUnitPixelHeightIndex = 0;
|
||||
|
||||
private final String[] displayAreaPixelWidthChoices = {"64", "128", "256", "512", "1024"};
|
||||
|
||||
private final int defaultDisplayWidthIndex = 3;
|
||||
|
||||
private final String[] displayAreaPixelHeightChoices = {"64", "128", "256", "512", "1024"};
|
||||
|
||||
// Values for Combo Boxes
|
||||
|
||||
private final int defaultDisplayHeightIndex = 2;
|
||||
|
||||
// Major GUI components
|
||||
private JComboBox visualizationUnitPixelWidthSelector, visualizationUnitPixelHeightSelector,
|
||||
visualizationPixelWidthSelector, visualizationPixelHeightSelector, displayBaseAddressSelector;
|
||||
|
||||
private Graphics drawingArea;
|
||||
|
||||
private JPanel canvas;
|
||||
|
||||
private JPanel results;
|
||||
|
||||
// Some GUI settings
|
||||
private final EmptyBorder emptyBorder = new EmptyBorder(4, 4, 4, 4);
|
||||
|
||||
private final Font countFonts = new Font("Times", Font.BOLD, 12);
|
||||
|
||||
private final Color backgroundColor = Color.WHITE;
|
||||
|
||||
// Values for display canvas. Note their initialization uses the identifiers just above.
|
||||
|
||||
private int unitPixelWidth = Integer.parseInt(visualizationUnitPixelWidthChoices[defaultVisualizationUnitPixelWidthIndex]);
|
||||
|
||||
private int unitPixelHeight = Integer.parseInt(visualizationUnitPixelHeightChoices[defaultVisualizationUnitPixelHeightIndex]);
|
||||
|
||||
private int displayAreaWidthInPixels = Integer.parseInt(displayAreaPixelWidthChoices[defaultDisplayWidthIndex]);
|
||||
|
||||
private int displayAreaHeightInPixels = Integer.parseInt(displayAreaPixelHeightChoices[defaultDisplayHeightIndex]);
|
||||
|
||||
|
||||
// The next four are initialized dynamically in initializeDisplayBaseChoices()
|
||||
private String[] displayBaseAddressChoices;
|
||||
|
||||
private int[] displayBaseAddresses;
|
||||
|
||||
private int defaultBaseAddressIndex;
|
||||
|
||||
private int baseAddress;
|
||||
|
||||
private Grid theGrid;
|
||||
|
||||
/**
|
||||
* Simple constructor, likely used to run a stand-alone bitmap display tool.
|
||||
*
|
||||
* @param title String containing title for title bar
|
||||
* @param heading String containing text for heading shown in upper part of window.
|
||||
*/
|
||||
public BitmapDisplay(String title, String heading)
|
||||
{
|
||||
super(title, heading);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple constructor, likely used by the MARS Tools menu mechanism
|
||||
*/
|
||||
public BitmapDisplay()
|
||||
{
|
||||
super("Bitmap Display, " + version, heading);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Main provided for pure stand-alone use. Recommended stand-alone use is to write a driver program that
|
||||
* instantiates a Bitmap object then invokes its go() method. "stand-alone" means it is not invoked from the MARS
|
||||
* Tools menu. "Pure" means there is no driver program to invoke the application.
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new BitmapDisplay("Bitmap Display stand-alone, " + version, heading).go();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Required MarsTool method to return Tool name.
|
||||
*
|
||||
* @return Tool name. MARS will display this in menu item.
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return "Bitmap Display";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Override the inherited method, which registers us as an Observer over the static data segment (starting address
|
||||
* 0x10010000) only. This version will register us as observer over the the memory range as selected by the base
|
||||
* address combo box and capacity of the visualization display (number of visualization elements times the number of
|
||||
* memory words each one represents). It does so by calling the inherited 2-parameter overload of this method. If
|
||||
* you use the inherited GUI buttons, this method is invoked when you click "Connect" button on MarsTool or the
|
||||
* "Assemble and Run" button on a Mars-based app.
|
||||
*/
|
||||
protected void addAsObserver()
|
||||
{
|
||||
int highAddress = baseAddress + theGrid.getRows() * theGrid.getColumns() * Memory.WORD_LENGTH_BYTES;
|
||||
// Special case: baseAddress<0 means we're in kernel memory (0x80000000 and up) and most likely
|
||||
// in memory map address space (0xffff0000 and up). In this case, we need to make sure the high address
|
||||
// does not drop off the high end of 32 bit address space. Highest allowable word address is 0xfffffffc,
|
||||
// which is interpreted in Java int as -4.
|
||||
if (baseAddress < 0 && highAddress > -4)
|
||||
{
|
||||
highAddress = -4;
|
||||
}
|
||||
addAsObserver(baseAddress, highAddress);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method that constructs the main display area. It is organized vertically into two major components: the display
|
||||
* configuration which an be modified using combo boxes, and the visualization display which is updated as the
|
||||
* attached MIPS program executes.
|
||||
*
|
||||
* @return the GUI component containing these two areas
|
||||
*/
|
||||
protected JComponent buildMainDisplayArea()
|
||||
{
|
||||
results = new JPanel();
|
||||
results.add(buildOrganizationArea());
|
||||
results.add(buildVisualizationArea());
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Rest of the protected methods. These override do-nothing methods inherited from
|
||||
// the abstract superclass.
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Update display when connected MIPS program accesses (data) memory.
|
||||
*
|
||||
* @param memory the attached memory
|
||||
* @param accessNotice information provided by memory in MemoryAccessNotice object
|
||||
*/
|
||||
protected void processMIPSUpdate(Observable memory, AccessNotice accessNotice)
|
||||
{
|
||||
if (accessNotice.getAccessType() == AccessNotice.WRITE)
|
||||
{
|
||||
updateColorForAddress((MemoryAccessNotice) accessNotice);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize all JComboBox choice structures not already initialized at declaration. Overrides inherited method
|
||||
* that does nothing.
|
||||
*/
|
||||
protected void initializePreGUI()
|
||||
{
|
||||
initializeDisplayBaseChoices();
|
||||
// NOTE: Can't call "createNewGrid()" here because it uses settings from
|
||||
// several combo boxes that have not been created yet. But a default grid
|
||||
// needs to be allocated for initial canvas display.
|
||||
theGrid = new Grid(displayAreaHeightInPixels / unitPixelHeight,
|
||||
displayAreaWidthInPixels / unitPixelWidth);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The only post-GUI initialization is to create the initial Grid object based on the default settings of the
|
||||
* various combo boxes. Overrides inherited method that does nothing.
|
||||
*/
|
||||
|
||||
protected void initializePostGUI()
|
||||
{
|
||||
theGrid = createNewGrid();
|
||||
updateBaseAddress();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method to reset counters and display when the Reset button selected. Overrides inherited method that does
|
||||
* nothing.
|
||||
*/
|
||||
protected void reset()
|
||||
{
|
||||
resetCounts();
|
||||
updateDisplay();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates display immediately after each update (AccessNotice) is processed, after display configuration changes as
|
||||
* needed, and after each execution step when Mars is running in timed mode. Overrides inherited method that does
|
||||
* nothing.
|
||||
*/
|
||||
protected void updateDisplay()
|
||||
{
|
||||
canvas.repaint();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overrides default method, to provide a Help button for this tool/app.
|
||||
*/
|
||||
protected JComponent getHelpComponent()
|
||||
{
|
||||
final String helpContent =
|
||||
"Use this program to simulate a basic bitmap display where\n" +
|
||||
"each memory word in a specified address space corresponds to\n" +
|
||||
"one display pixel in row-major order starting at the upper left\n" +
|
||||
"corner of the display. This tool may be run either from the\n" +
|
||||
"MARS Tools menu or as a stand-alone application.\n" +
|
||||
"\n" +
|
||||
"You can easily learn to use this small program by playing with\n" +
|
||||
"it! Each rectangular unit on the display represents one memory\n" +
|
||||
"word in a contiguous address space starting with the specified\n" +
|
||||
"base address. The value stored in that word will be interpreted\n" +
|
||||
"as a 24-bit RGB color value with the red component in bits 16-23,\n" +
|
||||
"the green component in bits 8-15, and the blue component in bits 0-7.\n" +
|
||||
"Each time a memory word within the display address space is written\n" +
|
||||
"by the MIPS program, its position in the display will be rendered\n" +
|
||||
"in the color that its value represents.\n" +
|
||||
"\n" +
|
||||
"Version 1.0 is very basic and was constructed from the Memory\n" +
|
||||
"Reference Visualization tool's code. Feel free to improve it and\n" +
|
||||
"send me your code for consideration in the next MARS release.\n" +
|
||||
"\n" +
|
||||
"Contact Pete Sanderson at psanderson@otterbein.edu with\n" +
|
||||
"questions or comments.\n";
|
||||
JButton help = new JButton("Help");
|
||||
help.addActionListener(
|
||||
new ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
JOptionPane.showMessageDialog(theWindow, helpContent);
|
||||
}
|
||||
});
|
||||
return help;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private methods defined to support the above.
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// UI components and layout for left half of GUI, where settings are specified.
|
||||
private JComponent buildOrganizationArea()
|
||||
{
|
||||
JPanel organization = new JPanel(new GridLayout(8, 1));
|
||||
|
||||
visualizationUnitPixelWidthSelector = new JComboBox(visualizationUnitPixelWidthChoices);
|
||||
visualizationUnitPixelWidthSelector.setEditable(false);
|
||||
visualizationUnitPixelWidthSelector.setBackground(backgroundColor);
|
||||
visualizationUnitPixelWidthSelector.setSelectedIndex(defaultVisualizationUnitPixelWidthIndex);
|
||||
visualizationUnitPixelWidthSelector.setToolTipText("Width in pixels of rectangle representing memory word");
|
||||
visualizationUnitPixelWidthSelector.addActionListener(
|
||||
new ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
unitPixelWidth = getIntComboBoxSelection(visualizationUnitPixelWidthSelector);
|
||||
theGrid = createNewGrid();
|
||||
updateDisplay();
|
||||
}
|
||||
});
|
||||
visualizationUnitPixelHeightSelector = new JComboBox(visualizationUnitPixelHeightChoices);
|
||||
visualizationUnitPixelHeightSelector.setEditable(false);
|
||||
visualizationUnitPixelHeightSelector.setBackground(backgroundColor);
|
||||
visualizationUnitPixelHeightSelector.setSelectedIndex(defaultVisualizationUnitPixelHeightIndex);
|
||||
visualizationUnitPixelHeightSelector.setToolTipText("Height in pixels of rectangle representing memory word");
|
||||
visualizationUnitPixelHeightSelector.addActionListener(
|
||||
new ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
unitPixelHeight = getIntComboBoxSelection(visualizationUnitPixelHeightSelector);
|
||||
theGrid = createNewGrid();
|
||||
updateDisplay();
|
||||
}
|
||||
});
|
||||
visualizationPixelWidthSelector = new JComboBox(displayAreaPixelWidthChoices);
|
||||
visualizationPixelWidthSelector.setEditable(false);
|
||||
visualizationPixelWidthSelector.setBackground(backgroundColor);
|
||||
visualizationPixelWidthSelector.setSelectedIndex(defaultDisplayWidthIndex);
|
||||
visualizationPixelWidthSelector.setToolTipText("Total width in pixels of display area");
|
||||
visualizationPixelWidthSelector.addActionListener(
|
||||
new ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
displayAreaWidthInPixels = getIntComboBoxSelection(visualizationPixelWidthSelector);
|
||||
canvas.setPreferredSize(getDisplayAreaDimension());
|
||||
canvas.setSize(getDisplayAreaDimension());
|
||||
theGrid = createNewGrid();
|
||||
updateDisplay();
|
||||
}
|
||||
});
|
||||
visualizationPixelHeightSelector = new JComboBox(displayAreaPixelHeightChoices);
|
||||
visualizationPixelHeightSelector.setEditable(false);
|
||||
visualizationPixelHeightSelector.setBackground(backgroundColor);
|
||||
visualizationPixelHeightSelector.setSelectedIndex(defaultDisplayHeightIndex);
|
||||
visualizationPixelHeightSelector.setToolTipText("Total height in pixels of display area");
|
||||
visualizationPixelHeightSelector.addActionListener(
|
||||
new ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
displayAreaHeightInPixels = getIntComboBoxSelection(visualizationPixelHeightSelector);
|
||||
canvas.setPreferredSize(getDisplayAreaDimension());
|
||||
canvas.setSize(getDisplayAreaDimension());
|
||||
theGrid = createNewGrid();
|
||||
updateDisplay();
|
||||
}
|
||||
});
|
||||
displayBaseAddressSelector = new JComboBox(displayBaseAddressChoices);
|
||||
displayBaseAddressSelector.setEditable(false);
|
||||
displayBaseAddressSelector.setBackground(backgroundColor);
|
||||
displayBaseAddressSelector.setSelectedIndex(defaultBaseAddressIndex);
|
||||
displayBaseAddressSelector.setToolTipText("Base address for display area (upper left corner)");
|
||||
displayBaseAddressSelector.addActionListener(
|
||||
new ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
// This may also affect what address range we should be registered as an Observer
|
||||
// for. The default (inherited) address range is the MIPS static data segment
|
||||
// starting at 0x10010000. To change this requires override of
|
||||
// AbstractMarsToolAndApplication.addAsObserver(). The no-argument version of
|
||||
// that method is called automatically when "Connect" button is clicked for MarsTool
|
||||
// and when "Assemble and Run" button is clicked for Mars application.
|
||||
updateBaseAddress();
|
||||
// If display base address is changed while connected to MIPS (this can only occur
|
||||
// when being used as a MarsTool), we have to delete ourselves as an observer and re-register.
|
||||
if (connectButton != null && connectButton.isConnected())
|
||||
{
|
||||
deleteAsObserver();
|
||||
addAsObserver();
|
||||
}
|
||||
theGrid = createNewGrid();
|
||||
updateDisplay();
|
||||
}
|
||||
});
|
||||
|
||||
// ALL COMPONENTS FOR "ORGANIZATION" SECTION
|
||||
|
||||
JPanel unitWidthInPixelsRow = getPanelWithBorderLayout();
|
||||
unitWidthInPixelsRow.setBorder(emptyBorder);
|
||||
unitWidthInPixelsRow.add(new JLabel("Unit Width in Pixels "), BorderLayout.WEST);
|
||||
unitWidthInPixelsRow.add(visualizationUnitPixelWidthSelector, BorderLayout.EAST);
|
||||
|
||||
JPanel unitHeightInPixelsRow = getPanelWithBorderLayout();
|
||||
unitHeightInPixelsRow.setBorder(emptyBorder);
|
||||
unitHeightInPixelsRow.add(new JLabel("Unit Height in Pixels "), BorderLayout.WEST);
|
||||
unitHeightInPixelsRow.add(visualizationUnitPixelHeightSelector, BorderLayout.EAST);
|
||||
|
||||
JPanel widthInPixelsRow = getPanelWithBorderLayout();
|
||||
widthInPixelsRow.setBorder(emptyBorder);
|
||||
widthInPixelsRow.add(new JLabel("Display Width in Pixels "), BorderLayout.WEST);
|
||||
widthInPixelsRow.add(visualizationPixelWidthSelector, BorderLayout.EAST);
|
||||
|
||||
JPanel heightInPixelsRow = getPanelWithBorderLayout();
|
||||
heightInPixelsRow.setBorder(emptyBorder);
|
||||
heightInPixelsRow.add(new JLabel("Display Height in Pixels "), BorderLayout.WEST);
|
||||
heightInPixelsRow.add(visualizationPixelHeightSelector, BorderLayout.EAST);
|
||||
|
||||
JPanel baseAddressRow = getPanelWithBorderLayout();
|
||||
baseAddressRow.setBorder(emptyBorder);
|
||||
baseAddressRow.add(new JLabel("Base address for display "), BorderLayout.WEST);
|
||||
baseAddressRow.add(displayBaseAddressSelector, BorderLayout.EAST);
|
||||
|
||||
|
||||
// Lay 'em out in the grid...
|
||||
organization.add(unitWidthInPixelsRow);
|
||||
organization.add(unitHeightInPixelsRow);
|
||||
organization.add(widthInPixelsRow);
|
||||
organization.add(heightInPixelsRow);
|
||||
organization.add(baseAddressRow);
|
||||
return organization;
|
||||
}
|
||||
|
||||
// UI components and layout for right half of GUI, the visualization display area.
|
||||
private JComponent buildVisualizationArea()
|
||||
{
|
||||
canvas = new GraphicsPanel();
|
||||
canvas.setPreferredSize(getDisplayAreaDimension());
|
||||
canvas.setToolTipText("Bitmap display area");
|
||||
return canvas;
|
||||
}
|
||||
|
||||
// For greatest flexibility, initialize the display base choices directly from
|
||||
// the constants defined in the Memory class. This method called prior to
|
||||
// building the GUI. Here are current values from Memory.java:
|
||||
//dataSegmentBaseAddress=0x10000000, globalPointer=0x10008000
|
||||
//dataBaseAddress=0x10010000, heapBaseAddress=0x10040000, memoryMapBaseAddress=0xffff0000
|
||||
private void initializeDisplayBaseChoices()
|
||||
{
|
||||
int[] displayBaseAddressArray = {Memory.dataSegmentBaseAddress, Memory.globalPointer, Memory.dataBaseAddress,
|
||||
Memory.heapBaseAddress, Memory.memoryMapBaseAddress};
|
||||
// Must agree with above in number and order...
|
||||
String[] descriptions = {" (global data)", " ($gp)", " (static data)", " (heap)", " (memory map)"};
|
||||
displayBaseAddresses = displayBaseAddressArray;
|
||||
displayBaseAddressChoices = new String[displayBaseAddressArray.length];
|
||||
for (int i = 0; i < displayBaseAddressChoices.length; i++)
|
||||
{
|
||||
displayBaseAddressChoices[i] = mars.util.Binary.intToHexString(displayBaseAddressArray[i]) + descriptions[i];
|
||||
}
|
||||
defaultBaseAddressIndex = 2; // default to 0x10010000 (static data)
|
||||
baseAddress = displayBaseAddressArray[defaultBaseAddressIndex];
|
||||
}
|
||||
|
||||
// update based on combo box selection (currently not editable but that may change).
|
||||
private void updateBaseAddress()
|
||||
{
|
||||
baseAddress = displayBaseAddresses[displayBaseAddressSelector.getSelectedIndex()];
|
||||
/* If you want to extend this app to allow user to edit combo box, you can always
|
||||
parse the getSelectedItem() value, because the pre-defined items are all formatted
|
||||
such that the first 10 characters contain the integer's hex value. And if the
|
||||
value is user-entered, the numeric part cannot exceed 10 characters for a 32-bit
|
||||
address anyway. So if the value is > 10 characters long, slice off the first
|
||||
10 and apply Integer.parseInt() to it to get custom base address.
|
||||
*/
|
||||
}
|
||||
|
||||
// Returns Dimension object with current width and height of display area as determined
|
||||
// by current settings of respective combo boxes.
|
||||
private Dimension getDisplayAreaDimension()
|
||||
{
|
||||
return new Dimension(displayAreaWidthInPixels, displayAreaHeightInPixels);
|
||||
}
|
||||
|
||||
// reset all counters in the Grid.
|
||||
private void resetCounts()
|
||||
{
|
||||
theGrid.reset();
|
||||
}
|
||||
|
||||
// Will return int equivalent of specified combo box's current selection.
|
||||
// The selection must be a String that parses to an int.
|
||||
private int getIntComboBoxSelection(JComboBox comboBox)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Integer.parseInt((String) comboBox.getSelectedItem());
|
||||
}
|
||||
catch (NumberFormatException nfe)
|
||||
{
|
||||
// Can occur only if initialization list contains badly formatted numbers. This
|
||||
// is a developer's error, not a user error, and better be caught before release.
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Use this for consistent results.
|
||||
private JPanel getPanelWithBorderLayout()
|
||||
{
|
||||
return new JPanel(new BorderLayout(2, 2));
|
||||
}
|
||||
|
||||
// Method to determine grid dimensions based on current control settings.
|
||||
// Each grid element corresponds to one visualization unit.
|
||||
private Grid createNewGrid()
|
||||
{
|
||||
int rows = displayAreaHeightInPixels / unitPixelHeight;
|
||||
int columns = displayAreaWidthInPixels / unitPixelWidth;
|
||||
return new Grid(rows, columns);
|
||||
}
|
||||
|
||||
// Given memory address, update color for the corresponding grid element.
|
||||
private void updateColorForAddress(MemoryAccessNotice notice)
|
||||
{
|
||||
int address = notice.getAddress();
|
||||
int value = notice.getValue();
|
||||
int offset = (address - baseAddress) / Memory.WORD_LENGTH_BYTES;
|
||||
try
|
||||
{
|
||||
theGrid.setElement(offset / theGrid.getColumns(), offset % theGrid.getColumns(), value);
|
||||
}
|
||||
catch (IndexOutOfBoundsException e)
|
||||
{
|
||||
// If address is out of range for display, do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Specialized inner classes for modeling and animation.
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Class that represents the panel for visualizing and animating memory reference
|
||||
// patterns.
|
||||
private class GraphicsPanel extends JPanel
|
||||
{
|
||||
|
||||
// override default paint method to assure display updated correctly every time
|
||||
// the panel is repainted.
|
||||
public void paint(Graphics g)
|
||||
{
|
||||
paintGrid(g, theGrid);
|
||||
}
|
||||
|
||||
// Paint the color codes.
|
||||
private void paintGrid(Graphics g, Grid grid)
|
||||
{
|
||||
int upperLeftX = 0, upperLeftY = 0;
|
||||
for (int i = 0; i < grid.getRows(); i++)
|
||||
{
|
||||
for (int j = 0; j < grid.getColumns(); j++)
|
||||
{
|
||||
g.setColor(grid.getElementFast(i, j));
|
||||
g.fillRect(upperLeftX, upperLeftY, unitPixelWidth, unitPixelHeight);
|
||||
upperLeftX += unitPixelWidth; // faster than multiplying
|
||||
}
|
||||
// get ready for next row...
|
||||
upperLeftX = 0;
|
||||
upperLeftY += unitPixelHeight; // faster than multiplying
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Represents grid of colors
|
||||
private class Grid
|
||||
{
|
||||
|
||||
Color[][] grid;
|
||||
|
||||
int rows, columns;
|
||||
|
||||
private Grid(int rows, int columns)
|
||||
{
|
||||
grid = new Color[rows][columns];
|
||||
this.rows = rows;
|
||||
this.columns = columns;
|
||||
reset();
|
||||
}
|
||||
|
||||
private int getRows()
|
||||
{
|
||||
return rows;
|
||||
}
|
||||
|
||||
private int getColumns()
|
||||
{
|
||||
return columns;
|
||||
}
|
||||
|
||||
// Returns value in given grid element; null if row or column is out of range.
|
||||
private Color getElement(int row, int column)
|
||||
{
|
||||
return (row >= 0 && row <= rows && column >= 0 && column <= columns) ? grid[row][column] : null;
|
||||
}
|
||||
|
||||
// Returns value in given grid element without doing any row/column index checking.
|
||||
// Is faster than getElement but will throw array index out of bounds exception if
|
||||
// parameter values are outside the bounds of the grid.
|
||||
private Color getElementFast(int row, int column)
|
||||
{
|
||||
return grid[row][column];
|
||||
}
|
||||
|
||||
// Set the grid element.
|
||||
private void setElement(int row, int column, int color)
|
||||
{
|
||||
grid[row][column] = new Color(color);
|
||||
}
|
||||
|
||||
// Set the grid element.
|
||||
private void setElement(int row, int column, Color color)
|
||||
{
|
||||
grid[row][column] = color;
|
||||
}
|
||||
|
||||
// Just set all grid elements to black.
|
||||
private void reset()
|
||||
{
|
||||
for (int i = 0; i < rows; i++)
|
||||
{
|
||||
for (int j = 0; j < columns; j++)
|
||||
{
|
||||
grid[i][j] = Color.BLACK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,465 @@
|
||||
package mars.tools
|
||||
|
||||
import mars.mips.hardware.AccessNotice
|
||||
import mars.mips.hardware.Memory
|
||||
import mars.mips.hardware.MemoryAccessNotice
|
||||
import mars.util.Binary
|
||||
import java.awt.*
|
||||
import java.util.*
|
||||
import javax.swing.*
|
||||
import javax.swing.border.EmptyBorder
|
||||
|
||||
/*
|
||||
Copyright (c) 2010-2011, Pete Sanderson and Kenneth Vollmar
|
||||
|
||||
Developed by Pete Sanderson (psanderson@otterbein.edu)
|
||||
and Kenneth Vollmar (kenvollmar@missouristate.edu)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject
|
||||
to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
(MIT license, http://www.opensource.org/licenses/mit-license.html)
|
||||
*/
|
||||
/**
|
||||
* Bitmapp display simulator. It can be run either as a stand-alone Java application having access to the mars package,
|
||||
* or through MARS as an item in its Tools menu. It makes maximum use of methods inherited from its abstract superclass
|
||||
* AbstractMarsToolAndApplication. Pete Sanderson, verison 1.0, 23 December 2010.
|
||||
*/
|
||||
class BitmapDisplay : AbstractMarsToolAndApplication
|
||||
{
|
||||
// Major GUI components
|
||||
private lateinit var uiUnitWidthSelector: JComboBox<Int>
|
||||
private lateinit var uiUnitHeightSelector: JComboBox<Int>
|
||||
private lateinit var uiWidthSelector: JComboBox<Int>
|
||||
private lateinit var uiHeightSelector: JComboBox<Int>
|
||||
private lateinit var uiBaseAddressSelector: JComboBox<String>
|
||||
private lateinit var canvas: JPanel
|
||||
private lateinit var results: JPanel
|
||||
|
||||
// Some GUI settings
|
||||
private val emptyBorder = EmptyBorder(4, 4, 4, 4)
|
||||
private val backgroundColor = Color.WHITE
|
||||
|
||||
// Values for display canvas. Note their initialization uses the identifiers just above.
|
||||
private val unitWidth get() = uiUnitWidthSelector.getInt()
|
||||
private val unitHeight get() = uiUnitHeightSelector.getInt()
|
||||
private val displayWidth get() = uiWidthSelector.getInt()
|
||||
private val displayHeight get() = uiHeightSelector.getInt()
|
||||
private val displayDimension get() = Dimension(displayWidth, displayHeight)
|
||||
|
||||
private val baseAddresses = intArrayOf(Memory.dataSegmentBaseAddress, Memory.globalPointer, Memory.dataBaseAddress,
|
||||
Memory.heapBaseAddress, Memory.memoryMapBaseAddress)
|
||||
|
||||
private val baseAddress get() = baseAddresses[uiBaseAddressSelector.selectedIndex]
|
||||
|
||||
private lateinit var grid: Grid
|
||||
|
||||
/**
|
||||
* Simple constructor, likely used to run a stand-alone bitmap display tool.
|
||||
*
|
||||
* @param title String containing title for title bar
|
||||
* @param heading String containing text for heading shown in upper part of window.
|
||||
*/
|
||||
constructor(title: String, heading: String) : super(title, heading)
|
||||
|
||||
constructor() : super("Azalea's Modified Bitmap Display", heading)
|
||||
|
||||
override fun getName() = "Bitmap Display"
|
||||
|
||||
/**
|
||||
* Override the inherited method, which registers us as an Observer over the static data segment (starting address
|
||||
* 0x10010000) only. This version will register us as observer over the the memory range as selected by the base
|
||||
* address combo box and capacity of the visualization display (number of visualization elements times the number of
|
||||
* memory words each one represents). It does so by calling the inherited 2-parameter overload of this method. If
|
||||
* you use the inherited GUI buttons, this method is invoked when you click "Connect" button on MarsTool or the
|
||||
* "Assemble and Run" button on a Mars-based app.
|
||||
*/
|
||||
override fun addAsObserver()
|
||||
{
|
||||
var highAddress: Int = baseAddress + grid.rows * grid.cols * Memory.WORD_LENGTH_BYTES
|
||||
// Special case: baseAddress<0 means we're in kernel memory (0x80000000 and up) and most likely
|
||||
// in memory map address space (0xffff0000 and up). In this case, we need to make sure the high address
|
||||
// does not drop off the high end of 32 bit address space. Highest allowable word address is 0xfffffffc,
|
||||
// which is interpreted in Java int as -4.
|
||||
if (baseAddress < 0 && highAddress > -4)
|
||||
{
|
||||
highAddress = -4
|
||||
}
|
||||
addAsObserver(baseAddress, highAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that constructs the main display area. It is organized vertically into two major components: the display
|
||||
* configuration which an be modified using combo boxes, and the visualization display which is updated as the
|
||||
* attached MIPS program executes.
|
||||
*
|
||||
* @return the GUI component containing these two areas
|
||||
*/
|
||||
override fun buildMainDisplayArea(): JComponent
|
||||
{
|
||||
results = JPanel()
|
||||
results.add(buildOrganizationArea())
|
||||
results.add(buildVisualizationArea())
|
||||
return results
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Rest of the protected methods. These override do-nothing methods inherited from
|
||||
// the abstract superclass.
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Update display when connected MIPS program accesses (data) memory.
|
||||
*
|
||||
* @param memory the attached memory
|
||||
* @param accessNotice information provided by memory in MemoryAccessNotice object
|
||||
*/
|
||||
override fun processMIPSUpdate(memory: Observable, accessNotice: AccessNotice)
|
||||
{
|
||||
if (accessNotice.accessType == AccessNotice.WRITE)
|
||||
{
|
||||
updateColorForAddress(accessNotice as MemoryAccessNotice)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize all JComboBox choice structures not already initialized at declaration. Overrides inherited method
|
||||
* that does nothing.
|
||||
*/
|
||||
override fun initializePreGUI()
|
||||
{
|
||||
grid = Grid(0, 0)
|
||||
}
|
||||
|
||||
/**
|
||||
* The only post-GUI initialization is to create the initial Grid object based on the default settings of the
|
||||
* various combo boxes. Overrides inherited method that does nothing.
|
||||
*/
|
||||
override fun initializePostGUI()
|
||||
{
|
||||
grid = createNewGrid()
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to reset counters and display when the Reset button selected. Overrides inherited method that does
|
||||
* nothing.
|
||||
*/
|
||||
override fun reset()
|
||||
{
|
||||
resetCounts()
|
||||
updateDisplay()
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates display immediately after each update (AccessNotice) is processed, after display configuration changes as
|
||||
* needed, and after each execution step when Mars is running in timed mode. Overrides inherited method that does
|
||||
* nothing.
|
||||
*/
|
||||
override fun updateDisplay() = canvas.repaint()
|
||||
|
||||
/**
|
||||
* Overrides default method, to provide a Help button for this tool/app.
|
||||
*/
|
||||
override fun getHelpComponent(): JComponent
|
||||
{
|
||||
val helpContent = """
|
||||
Use this program to simulate a basic bitmap display where
|
||||
each memory word in a specified address space corresponds to
|
||||
one display pixel in row-major order starting at the upper left
|
||||
corner of the display. This tool may be run either from the
|
||||
MARS Tools menu or as a stand-alone application.
|
||||
|
||||
You can easily learn to use this small program by playing with
|
||||
it! Each rectangular unit on the display represents one memory
|
||||
word in a contiguous address space starting with the specified
|
||||
base address. The value stored in that word will be interpreted
|
||||
as a 24-bit RGB color value with the red component in bits 16-23,
|
||||
the green component in bits 8-15, and the blue component in bits 0-7.
|
||||
Each time a memory word within the display address space is written
|
||||
by the MIPS program, its position in the display will be rendered
|
||||
in the color that its value represents.
|
||||
|
||||
Version 1.0 is very basic and was constructed from the Memory
|
||||
Reference Visualization tool's code. Feel free to improve it and
|
||||
send me your code for consideration in the next MARS release.
|
||||
|
||||
Contact Pete Sanderson at psanderson@otterbein.edu with
|
||||
questions or comments.
|
||||
|
||||
""".trimIndent()
|
||||
val help = JButton("Help")
|
||||
help.addActionListener { JOptionPane.showMessageDialog(theWindow, helpContent) }
|
||||
return help
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private methods defined to support the above.
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// UI components and layout for left half of GUI, where settings are specified.
|
||||
private fun buildOrganizationArea(): JComponent
|
||||
{
|
||||
val organization = JPanel(GridLayout(8, 1))
|
||||
|
||||
uiUnitWidthSelector = JComboBox(arrayOf(1, 2, 4, 8, 16, 32)).apply {
|
||||
isEditable = false
|
||||
background = backgroundColor
|
||||
selectedIndex = 2
|
||||
toolTipText = "Width in pixels of rectangle representing memory word"
|
||||
addActionListener {
|
||||
grid = createNewGrid()
|
||||
updateDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
uiUnitHeightSelector = JComboBox(arrayOf(1, 2, 4, 8, 16, 32)).apply {
|
||||
isEditable = false
|
||||
background = backgroundColor
|
||||
selectedIndex = 2
|
||||
toolTipText = "Height in pixels of rectangle representing memory word"
|
||||
addActionListener {
|
||||
grid = createNewGrid()
|
||||
updateDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
uiWidthSelector = JComboBox(arrayOf(64, 128, 256, 512, 1024)).apply {
|
||||
isEditable = false
|
||||
background = backgroundColor
|
||||
selectedIndex = 3
|
||||
toolTipText = "Total width in pixels of display area"
|
||||
addActionListener {
|
||||
canvas.preferredSize = displayDimension
|
||||
canvas.size = displayDimension
|
||||
grid = createNewGrid()
|
||||
updateDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
uiHeightSelector = JComboBox(arrayOf(64, 128, 256, 512, 1024)).apply {
|
||||
isEditable = false
|
||||
background = backgroundColor
|
||||
selectedIndex = 2
|
||||
toolTipText = "Total height in pixels of display area"
|
||||
addActionListener {
|
||||
canvas.preferredSize = displayDimension
|
||||
canvas.size = displayDimension
|
||||
grid = createNewGrid()
|
||||
updateDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
val descriptions = arrayOf("global data", "\$gp", "static data", "heap", "memory map")
|
||||
|
||||
val displayBaseAddressChoices = baseAddresses
|
||||
.mapIndexed { i, it -> "${Binary.intToHexString(it)} (${descriptions[i]})" }.toTypedArray()
|
||||
|
||||
uiBaseAddressSelector = JComboBox(displayBaseAddressChoices).apply {
|
||||
isEditable = false
|
||||
background = backgroundColor
|
||||
selectedIndex = 1
|
||||
toolTipText = "Base address for display area (upper left corner)"
|
||||
addActionListener {
|
||||
// If display base address is changed while connected to MIPS (this can only occur
|
||||
// when being used as a MarsTool), we have to delete ourselves as an observer and re-register.
|
||||
if (connectButton != null && connectButton.isConnected)
|
||||
{
|
||||
deleteAsObserver()
|
||||
addAsObserver()
|
||||
}
|
||||
grid = createNewGrid()
|
||||
updateDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
// ALL COMPONENTS FOR "ORGANIZATION" SECTION
|
||||
val unitWidthInPixelsRow = panelWithBorderLayout
|
||||
unitWidthInPixelsRow.border = emptyBorder
|
||||
unitWidthInPixelsRow.add(JLabel("Unit Width in Pixels "), BorderLayout.WEST)
|
||||
unitWidthInPixelsRow.add(uiUnitWidthSelector, BorderLayout.EAST)
|
||||
val unitHeightInPixelsRow = panelWithBorderLayout
|
||||
unitHeightInPixelsRow.border = emptyBorder
|
||||
unitHeightInPixelsRow.add(JLabel("Unit Height in Pixels "), BorderLayout.WEST)
|
||||
unitHeightInPixelsRow.add(uiUnitHeightSelector, BorderLayout.EAST)
|
||||
val widthInPixelsRow = panelWithBorderLayout
|
||||
widthInPixelsRow.border = emptyBorder
|
||||
widthInPixelsRow.add(JLabel("Display Width in Pixels "), BorderLayout.WEST)
|
||||
widthInPixelsRow.add(uiWidthSelector, BorderLayout.EAST)
|
||||
val heightInPixelsRow = panelWithBorderLayout
|
||||
heightInPixelsRow.border = emptyBorder
|
||||
heightInPixelsRow.add(JLabel("Display Height in Pixels "), BorderLayout.WEST)
|
||||
heightInPixelsRow.add(uiHeightSelector, BorderLayout.EAST)
|
||||
val baseAddressRow = panelWithBorderLayout
|
||||
baseAddressRow.border = emptyBorder
|
||||
baseAddressRow.add(JLabel("Base address for display "), BorderLayout.WEST)
|
||||
baseAddressRow.add(uiBaseAddressSelector, BorderLayout.EAST)
|
||||
|
||||
// Lay 'em out in the grid...
|
||||
organization.add(unitWidthInPixelsRow)
|
||||
organization.add(unitHeightInPixelsRow)
|
||||
organization.add(widthInPixelsRow)
|
||||
organization.add(heightInPixelsRow)
|
||||
organization.add(baseAddressRow)
|
||||
return organization
|
||||
}
|
||||
|
||||
// UI components and layout for right half of GUI, the visualization display area.
|
||||
private fun buildVisualizationArea(): JComponent
|
||||
{
|
||||
canvas = GraphicsPanel()
|
||||
canvas.preferredSize = displayDimension
|
||||
canvas.toolTipText = "Bitmap display area"
|
||||
return canvas
|
||||
}
|
||||
|
||||
// reset all counters in the Grid.
|
||||
private fun resetCounts() = grid.reset()
|
||||
|
||||
private fun <T> JComboBox<T>.getInt() = selectedItem!!.toString().toInt()
|
||||
|
||||
// Use this for consistent results.
|
||||
private val panelWithBorderLayout: JPanel
|
||||
get() = JPanel(BorderLayout(2, 2))
|
||||
|
||||
// Method to determine grid dimensions based on current control settings.
|
||||
// Each grid element corresponds to one visualization unit.
|
||||
private fun createNewGrid(): Grid
|
||||
{
|
||||
val rows = displayHeight / unitHeight
|
||||
val columns = displayWidth / unitWidth
|
||||
return Grid(rows, columns)
|
||||
}
|
||||
|
||||
// Given memory address, update color for the corresponding grid element.
|
||||
private fun updateColorForAddress(notice: MemoryAccessNotice)
|
||||
{
|
||||
val address = notice.address
|
||||
val value = notice.value
|
||||
val offset = (address - baseAddress) / Memory.WORD_LENGTH_BYTES
|
||||
try
|
||||
{
|
||||
grid.setElement(offset / grid.cols, offset % grid.cols, value)
|
||||
} catch (e: IndexOutOfBoundsException)
|
||||
{
|
||||
// If address is out of range for display, do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Specialized inner classes for modeling and animation.
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Class that represents the panel for visualizing and animating memory reference
|
||||
// patterns.
|
||||
private inner class GraphicsPanel : JPanel()
|
||||
{
|
||||
// override default paint method to assure display updated correctly every time
|
||||
// the panel is repainted.
|
||||
override fun paint(g: Graphics) = paintGrid(g, grid)
|
||||
|
||||
// Paint the color codes.
|
||||
private fun paintGrid(g: Graphics, grid: Grid)
|
||||
{
|
||||
var upperLeftX = 0
|
||||
var upperLeftY = 0
|
||||
for (i in 0 until grid.rows)
|
||||
{
|
||||
for (j in 0 until grid.cols)
|
||||
{
|
||||
g.color = grid.getElementFast(i, j)
|
||||
g.fillRect(upperLeftX, upperLeftY, unitWidth, unitHeight)
|
||||
upperLeftX += unitWidth // faster than multiplying
|
||||
}
|
||||
// get ready for next row...
|
||||
upperLeftX = 0
|
||||
upperLeftY += unitHeight // faster than multiplying
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Represents grid of colors
|
||||
private class Grid(rows: Int, columns: Int)
|
||||
{
|
||||
var grid: Array<Array<Color?>>
|
||||
var rows: Int
|
||||
var cols: Int
|
||||
|
||||
init
|
||||
{
|
||||
grid = Array(rows) { arrayOfNulls(columns) }
|
||||
this.rows = rows
|
||||
this.cols = columns
|
||||
reset()
|
||||
}
|
||||
|
||||
// Returns value in given grid element; null if row or column is out of range.
|
||||
private fun getElement(row: Int, column: Int): Color?
|
||||
{
|
||||
return if (row in 0..rows && column >= 0 && column <= cols) grid[row][column] else null
|
||||
}
|
||||
|
||||
// Returns value in given grid element without doing any row/column index checking.
|
||||
// Is faster than getElement but will throw array index out of bounds exception if
|
||||
// parameter values are outside the bounds of the grid.
|
||||
fun getElementFast(row: Int, column: Int): Color?
|
||||
{
|
||||
return grid[row][column]
|
||||
}
|
||||
|
||||
// Set the grid element.
|
||||
fun setElement(row: Int, column: Int, color: Int)
|
||||
{
|
||||
grid[row][column] = Color(color)
|
||||
}
|
||||
|
||||
// Set the grid element.
|
||||
private fun setElement(row: Int, column: Int, color: Color)
|
||||
{
|
||||
grid[row][column] = color
|
||||
}
|
||||
|
||||
// Just set all grid elements to black.
|
||||
fun reset()
|
||||
{
|
||||
for (i in 0 until rows)
|
||||
{
|
||||
for (j in 0 until cols)
|
||||
{
|
||||
grid[i][j] = Color.BLACK
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object
|
||||
{
|
||||
private const val version = "Version 1.0"
|
||||
private const val heading = "Bitmap Display"
|
||||
|
||||
/**
|
||||
* Main provided for pure stand-alone use. Recommended stand-alone use is to write a driver program that
|
||||
* instantiates a Bitmap object then invokes its go() method. "stand-alone" means it is not invoked from the MARS
|
||||
* Tools menu. "Pure" means there is no driver program to invoke the application.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>)
|
||||
{
|
||||
BitmapDisplay("Bitmap Display stand-alone, " + version, heading).go()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user