package lejos.nxt; /** * Text and graphics output to the LCD display. * * @author Andre Nijholt and BB bitBlt and other mods Andy Shaw */ public class LCD { public static final int SCREEN_WIDTH = 100; public static final int SCREEN_HEIGHT = 64; public static final int DISPLAY_WIDTH = 100; public static final int DISPLAY_DEPTH = 8; // 8 * 8 bits = 64 pixels public static final int NOOF_CHARS = 128; public static final int FONT_WIDTH = 5; public static final int FONT_HEIGHT = 8; public static final int CELL_WIDTH = FONT_WIDTH + 1; public static final int CELL_HEIGHT = FONT_HEIGHT; public static final int DISPLAY_CHAR_WIDTH = DISPLAY_WIDTH / CELL_WIDTH; public static final int DISPLAY_CHAR_DEPTH = DISPLAY_DEPTH; private static byte[] font = getSystemFont(); private static byte [] displayBuf = getDisplay(); /** * Common raster operations for use with bitBlt */ public static final int ROP_CLEAR = 0x00000000; public static final int ROP_AND = 0xff000000; public static final int ROP_ANDREVERSE = 0xff00ff00; public static final int ROP_COPY = 0x0000ff00; public static final int ROP_ANDINVERTED = 0xffff0000; public static final int ROP_NOOP = 0x00ff0000; public static final int ROP_XOR = 0x00ffff00; public static final int ROP_OR = 0xffffff00; public static final int ROP_NOR = 0xffffffff; public static final int ROP_EQUIV = 0x00ffffff; public static final int ROP_INVERT = 0x00ff00ff; public static final int ROP_ORREVERSE = 0xffff00ff; public static final int ROP_COPYINVERTED= 0x0000ffff; public static final int ROP_ORINVERTED = 0xff00ffff; public static final int ROP_NAND = 0xff0000ff; public static final int ROP_SET = 0x000000ff; /** * Standard two input BitBlt function with the LCD display as the * destination. Supports standard raster ops and * overlapping images. Images are held in native leJOS/Lego format. * @param src byte array containing the source image * @param sw Width of the source image * @param sh Height of the source image * @param sx X position to start the copy from * @param sy Y Position to start the copy from * @param dx X destination * @param dy Y destination * @param w width of the area to copy * @param h height of the area to copy * @param rop raster operation. */ public static void bitBlt(byte [] src, int sw, int sh, int sx, int sy, int dx, int dy, int w, int h, int rop) { bitBlt(src, sw, sh, sx, sy, displayBuf, SCREEN_WIDTH, SCREEN_HEIGHT, dx, dy, w, h, rop); } /** * Special case bitBlt with no input image. Can be used to clear areas * draw rectangles etc. * @param dx X destination * @param dy Y destination * @param w width of the area to copy * @param h height of the area to copy * @param rop raster operation. */ public static void bitBlt(int dx, int dy, int w, int h, int rop) { bitBlt(displayBuf, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, displayBuf, SCREEN_WIDTH, SCREEN_HEIGHT, dx, dy, w, h, rop); } /** * Method to set a pixel to screen. * @param rgbColor the pixel color (0 = white, 1 = black) * @param x the x coordinate * @param y the y coordinate */ public static void setPixel(int rgbColor, int x, int y) { if (x < 0 || x >= SCREEN_WIDTH || y < 0 || y >= SCREEN_HEIGHT) return; // Test-Modify for speed int bit = (y & 0x7); int index = (y/8)*DISPLAY_WIDTH + x; displayBuf[index] = (byte)((displayBuf[index] & ~(1 << bit)) | (rgbColor << bit)); } /** * Method to get a pixel from the screen. * @param x the x coordinate * @param y the y coordinate * @return the pixel color (0 = white, 1 = black) */ public static int getPixel(int x, int y) { if (x < 0 || x >= SCREEN_WIDTH || y < 0 || y >= SCREEN_HEIGHT) return 0; int bit = (y & 0x7); int index = (y/8)*DISPLAY_WIDTH + x; return ((displayBuf[index] >> bit) & 1); } /** * Output a string to the display. Allow any location. Allow the string to * be inverted. * @param str String to display * @param x X location (pixels) * @param y Y location (pixels) * @param invert set to true to displayed the string inverted */ public static void drawString(String str, int x, int y, boolean invert) { char [] strData = str.toCharArray(); if (invert) { for (int i = 0; (i < strData.length); i++) { drawChar(strData[i], x + i*CELL_WIDTH, y, true); } } else { for (int i = 0; (i < strData.length); i++) { drawChar(strData[i], x + i*CELL_WIDTH, y, ROP_COPY); } } } /** * Draw a single char to an arbitary location on the screen. * @param c Character to display * @param x X location (pixels) * @param y Y location (pixels) * @param invert Set to true to invert the display */ public static void drawChar(char c, int x, int y, boolean invert) { bitBlt(font, FONT_WIDTH*128, FONT_HEIGHT, FONT_WIDTH*c, 0, x, y, FONT_WIDTH, FONT_HEIGHT, (invert ? ROP_COPYINVERTED : ROP_COPY)); if (invert) bitBlt(x+FONT_WIDTH, y, 1, FONT_HEIGHT, ROP_SET); } /** * Output a string to the display. Allow any location. Allow use of raster * operations. * @param str String to display * @param x X location (pixels) * @param y Y location (pixels) * @param rop Raster operation */ public static void drawString(String str, int x, int y, int rop) { char [] strData = str.toCharArray(); for (int i = 0; (i < strData.length); i++) { drawChar(strData[i], x + i*CELL_WIDTH, y, rop); } } /** * Draw a single char to an arbitary location on the screen. * @param c Character to display * @param x X location (pixels) * @param y Y location (pixels) * @param rop Raster operation for how to combine with existing content */ public static void drawChar(char c, int x, int y, int rop) { bitBlt(font, FONT_WIDTH*128, FONT_HEIGHT, FONT_WIDTH*c, 0, x, y, FONT_WIDTH, FONT_HEIGHT, rop); } /** * Draw pixels a byte at a time. Should probably no longer be used. * @param b * @param x * @param y * @param invert */ public static void drawPixels(byte b, int x, int y, boolean invert) { int index = (y/8)*DISPLAY_WIDTH + x; displayBuf[index] |= ((invert ? (b ^ 0xFF) : b)); } public static void clearDisplay() { clear(); } public static void setDisplay() { } /** * Display a string on the LCD at specified x,y co-ordinate. */ public static native void drawString(String str, int x, int y); /** * Display an int on the LCD at specified x,y co-ordinate. */ public static native void drawInt(int i, int x, int y); /** * Display an in on the LCD at x,y with leading spaces to occupy at least the number * of characters specified by the places parameter. */ public static native void drawInt(int i, int places, int x, int y); /** * Update the display. */ public static native void refresh(); /** * Clear the display. */ public static native void clear(); /** * Write graphics from a Java buffer to the display. */ public static native void setDisplay(int[] buff); /** * Provide access to the LCD display frame buffer. Allows both the firmware * and Java to make changes. * @return byte array that is the frame buffer. */ public static native byte [] getDisplay(); /** * Provide access to the LCD system font. Allows both the firmware * and Java to share the same font bitmaps. * @return byte array that is the frame buffer. */ public static native byte [] getSystemFont(); /** * Turn on/off the automatic refresh of the LCD display. At system startup * auto refresh is on. * @param mode 1 to enable 0 to disable */ public static native void setAutoRefresh(int mode); /** * Standard two input BitBlt function. Supports standard raster ops and * overlapping images. Images are held in native leJOS/Lego format. * @param src byte array containing the source image * @param sw Width of the source image * @param sh Height of the source image * @param sx X position to start the copy from * @param sy Y Position to start the copy from * @param dst byte array containing the destination image * @param dw Width of the destination image * @param dh Height of the destination image * @param dx X destination * @param dy Y destination * @param w width of the area to copy * @param h height of the area to copy * @param rop raster operation. */ public native static void bitBlt(byte [] src, int sw, int sh, int sx, int sy, byte dst[], int dw, int dh, int dx, int dy, int w, int h, int rop); /** * Scrolls the screen up one text line * */ public static void scroll() { LCD.bitBlt(displayBuf, SCREEN_WIDTH, SCREEN_HEIGHT, 0, CELL_HEIGHT, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT - CELL_HEIGHT, ROP_COPY); LCD.bitBlt(0, SCREEN_HEIGHT - CELL_HEIGHT, SCREEN_WIDTH, CELL_HEIGHT, ROP_CLEAR); } }