/* * This file is a part of the Jop-UI * Copyright (C) 2009, Stefan Resch (e0425306@student.tuwien.ac.at) * Stefan Rottensteiner (e0425058@student.tuwien.ac.at) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.jopdesign.jopui; import java.util.Enumeration; import java.util.Vector; import com.jopdesign.jopui.core.Graphics; import com.jopdesign.jopui.core.Image; import com.jopdesign.jopui.core.Theme; import com.jopdesign.jopui.event.KeyboardEvent; import com.jopdesign.jopui.event.MouseEvent; import com.jopdesign.jopui.helper.KeyBoard; import com.jopdesign.sys.Native; import com.jopdesign.sys.Const; /** * Start point for JopUi <p> * initializes and starts all JopUi applications */ public final class JopUi { private static int mouseX; private static int mouseY; private static int button_left = 0; private static int button_right = 0; private static int button_middle = 0; private static KeyBoard keyboard = new KeyBoard(); private static Vector apps = new Vector(); /** * Start address of video memory <p> * Constant has the value 0x78500 */ public static final int MEM_START = 0x78500; /** * Width of the screen in pixel <p> * Constant has the value 320 */ public static final int WIDTH = 320; /** * Height of the screen in pixel <p> * Constant has the value 240 */ public static final int HEIGHT = 240; private static Image fb = Image.createImage(WIDTH,HEIGHT); /** * Returns the framebuffer, where all images will be drwan to * @return framebuffer image */ public static Image getFrameBuffer() { return fb; } /** * Adds an application to the execution list * @param app JopUiApplication */ public static void register(JopUiApplication app) { apps.addElement(app); } /** * Run the applications */ public static void run() { Enumeration e; JopUiApplication app; KeyboardEvent keyboardEvent = null; MouseEvent mouseEvent = null; fb.setColorKey(Theme.colorKey); Graphics g = fb.getGraphics(); Graphics.enable(Graphics.COLOR_KEY); int oldMouseX = 0; int oldMouseY = 0; mouseX = fb.getWidth()>>1; mouseY = fb.getHeight()>>1; boolean redraw; e = apps.elements(); while(e.hasMoreElements()) { app = (JopUiApplication) e.nextElement(); if(app.init() == false); // TODO Error Message and remove app from list // as soon as there is a scheduling algorithm } g.setColor(Theme.colorBackground); g.fillRect(0, 0, WIDTH, HEIGHT); e = apps.elements(); // initial draw while(e.hasMoreElements()) { app = (JopUiApplication) e.nextElement(); app.paint(g); } while(true) { keyboardEvent = readKeyboard(); mouseEvent = readMouse(); redraw = false; e = apps.elements(); while(e.hasMoreElements()) { app = (JopUiApplication) e.nextElement(); if(keyboardEvent != null) redraw |= app.distribute(keyboardEvent); if(mouseEvent != null) redraw |= app.distribute(mouseEvent); } if(redraw) { g.setColor(Theme.colorBackground); g.fillRect(0, 0, WIDTH, HEIGHT); e = apps.elements(); while(e.hasMoreElements()) { ((JopUiApplication) e.nextElement()).paint(g); } } if((oldMouseX != mouseX) || (oldMouseY != mouseY)) redraw = true; if(redraw) { int [] data = fb.getData(); int [] pdata = new int[3*7]; int adr; int absolute_adr; int adroffset; for(int i = 0; i < 3; i++) { // copy destination area for mouse for(int j = 0; j < 7; j++) { adr = (mouseX>>2) + i + (mouseY + j) * (WIDTH>>2); if(adr < data.length) pdata[i + j*3] = data[adr]; } } for(int i = 0; i < 7; i++) { // draw mouse for(int j = 0; j < 7; j++) { int col = -1; if(i == 0) { col = Theme.mouseColorLight; } else if (i == j) { col = Theme.mouseColorLight; } else if (i < j) { col = Theme.mouseColorDark; } if(col != -1) { adr = (mouseX & 0x03) + i + j*12; absolute_adr = (adr>>2); adroffset = 8*(adr & 0x03); pdata[absolute_adr] &= ~(0xFF << adroffset); pdata[absolute_adr] |= col << adroffset; } } } int mx = -((mouseX-1)>>2); int my = -mouseY-1; for(int i=0; i<(data.length-1); ++i) { // TODO remeber to change this value when changing Image class mx++; if((i % (WIDTH>>2)) == 0) { mx = -(mouseX>>2); my++; } // either draw from mouse field or whole if(mx >= 0 && mx <= 2 && my >= 0 && my <= 6) { Native.wr(pdata[mx + my*3],MEM_START + i); } else { Native.wr(data[i],MEM_START + i); } } } oldMouseX = mouseX; oldMouseY = mouseY; // TODO other tasks? } } private static KeyboardEvent readKeyboard() { int ctrl = keyboard.getCtrlReg(); KeyboardEvent kbev = null; if((ctrl & KeyBoard.MSK_ASCII_RDY) != 0 || (ctrl & KeyBoard.MSK_SCC_RDY) != 0) { if((ctrl & KeyBoard.MSK_KEY_REL) != 0) { kbev = new KeyboardEvent(KeyboardEvent.KEY_RELEASED,(char)keyboard.getAscii(),keyboard.getScanCode()); System.out.print("event -> kb_up : "); System.out.println((char)keyboard.getAscii()); System.out.print(" == 0x"); System.out.println(Integer.toHexString(kbev.getScanCode())); } else { kbev = new KeyboardEvent(KeyboardEvent.KEY_PRESSED,(char)keyboard.getAscii(),keyboard.getScanCode()); System.out.print("event -> kb_down : "); System.out.print((char)keyboard.getAscii()); System.out.print(" == 0x"); System.out.println(Integer.toHexString(kbev.getScanCode())); } } return kbev; } private static MouseEvent readMouse() { // set mouseX mouseY // generate event MouseEvent me = null; int flags = Native.rd(Const.MOUSE_FLAG); if((flags & Const.MSK_DTA_RDY)!= 0) { mouseX += Native.rd(Const.MOUSE_X_INC); mouseY -= Native.rd(Const.MOUSE_Y_INC); } if(mouseX < 0) mouseX = 0; if(mouseX >= WIDTH) mouseX = WIDTH - 1; if(mouseY < 0) mouseY = 0; if(mouseY >= HEIGHT) mouseY = HEIGHT - 1; if((flags & Const.MSK_BTN_LEFT)!= button_left) { button_left = (flags & Const.MSK_BTN_LEFT); if(button_left == 0) { me = new MouseEvent(mouseX, mouseY, MouseEvent.MOUSE_UP, MouseEvent.LEFT_BUTTON); System.out.println("event -> mouse up : left"); } else { me = new MouseEvent(mouseX, mouseY, MouseEvent.MOUSE_DOWN, MouseEvent.LEFT_BUTTON); System.out.println("event -> mouse down : left"); } } if((flags & Const.MSK_BTN_MIDDLE)!= button_middle && me == null) { button_middle = (flags & Const.MSK_BTN_MIDDLE); if(button_middle == 0) { me = new MouseEvent(mouseX, mouseY, MouseEvent.MOUSE_UP, MouseEvent.MIDDLE_BUTTON); System.out.println("event -> mouse up : middle"); } else { me = new MouseEvent(mouseX, mouseY, MouseEvent.MOUSE_DOWN, MouseEvent.MIDDLE_BUTTON); System.out.println("event -> mouse down : middle"); } } if((flags & Const.MSK_BTN_RIGHT)!= button_right && me == null) { button_right = (flags & Const.MSK_BTN_RIGHT); if(button_right == 0) { me = new MouseEvent(mouseX, mouseY, MouseEvent.MOUSE_UP, MouseEvent.RIGHT_BUTTON); System.out.println("event -> mouse up : right"); } else { me = new MouseEvent(mouseX, mouseY, MouseEvent.MOUSE_DOWN, MouseEvent.RIGHT_BUTTON); System.out.println("event -> mouse down : right"); } } return me; } }