Coverage Report - uk.co.javagear.JavaGearApplet
 
Classes in this File Line Coverage Branch Coverage Complexity
JavaGearApplet
0% 
0% 
4.3
 
 1  
 /*
 2  
  * JavaGearApplet.java
 3  
  *
 4  
  *  This file is part of JavaGear.
 5  
  *
 6  
  * JavaGear is free software; you can redistribute it and/or modify
 7  
  * it under the terms of the GNU General Public License as published by
 8  
  * the Free Software Foundation; either version 2 of the License, or
 9  
  * (at your option) any later version.
 10  
  *
 11  
  * JavaGear is distributed in the hope that it will be useful,
 12  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14  
  * GNU General Public License for more details.
 15  
  *
 16  
  * You should have received a copy of the GNU General Public License
 17  
  * along with JavaGear; if not, write to the Free Software
 18  
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 19  
 */
 20  
 
 21  
 package uk.co.javagear;
 22  
 
 23  
 import java.awt.Dimension;
 24  
 import java.awt.Graphics;
 25  
 import java.awt.Image;
 26  
 import java.awt.List;
 27  
 import java.awt.MediaTracker;
 28  
 import java.awt.Toolkit;
 29  
 import java.awt.event.ActionEvent;
 30  
 import java.awt.event.ActionListener;
 31  
 import java.io.BufferedReader;
 32  
 import java.io.IOException;
 33  
 import java.io.InputStreamReader;
 34  
 import java.net.MalformedURLException;
 35  
 import java.net.URL;
 36  
 import javax.swing.AbstractAction;
 37  
 import javax.swing.Action;
 38  
 import javax.swing.ImageIcon;
 39  
 import javax.swing.JApplet;
 40  
 import javax.swing.JButton;
 41  
 import javax.swing.JFrame;
 42  
 import javax.swing.JPanel;
 43  
 import javax.swing.JToolBar;
 44  
 import org.apache.log4j.Logger;
 45  
 
 46  
 
 47  
 /**
 48  
  * JavaGear Applet user interface.
 49  
  *
 50  
  * @author Copyright (C) 2002 Chris White
 51  
  * @version 16th March 2002
 52  
  * @see "JavaGear Final Project Report"
 53  
  */
 54  0
 public final class JavaGearApplet extends JApplet implements ActionListener {
 55  
     
 56  
     /**
 57  
      * Memory and Paging Emulation.
 58  
      */
 59  
     private Memory mem;
 60  
     
 61  
     /**
 62  
      * SN76596 Emulation.
 63  
      */
 64  
     private SN76496 sn76496;
 65  
     
 66  
     /**
 67  
      * Port Emulation.
 68  
      */
 69  
     private Ports port;
 70  
     
 71  
     /**
 72  
      * Z80 CPU Emulation.
 73  
      */
 74  
     private Z80 z80cpu;
 75  
     
 76  
     /**
 77  
      * Controller Emulation.
 78  
      */
 79  
     private Controllers controllers;
 80  
     
 81  
     /**
 82  
      * Main Emulation Loop.
 83  
      */
 84  0
     private EmulateLoop emulateLoop = null;
 85  
     
 86  
     /**
 87  
      * VDP Emulation.
 88  
      */
 89  
     private Vdp vdp;
 90  
     
 91  
     /**
 92  
      * Java Screen Display.
 93  
      */
 94  
     private Screen screenpanel;
 95  
     
 96  
     /**
 97  
      * Keyboard configuration Frame.
 98  
      */
 99  
     private KeyFrame keyFrame;
 100  
     
 101  
     /**
 102  
      * Pointer to ToolBar.
 103  
      */
 104  
     private JToolBar bar;
 105  
     
 106  
     /**
 107  
      * Pointer to General Parameters.
 108  
      */
 109  
     private Setup setup;
 110  
     
 111  
     /**
 112  
      * Directory containing ROM images.
 113  
      */
 114  0
     private String romDirectory = "./roms/";
 115  
     
 116  
     /**
 117  
      * File containing ROM information.
 118  
      */
 119  0
     private String romIndex = "index.txt";
 120  
     
 121  
     /**
 122  
      * Store the filenames stored in the index file.
 123  
      */
 124  
     private String[] filenames;
 125  
     
 126  
     /**
 127  
      * Store NTSC / PAL Settings for file.
 128  
      */
 129  
     private boolean[] tvType;
 130  
     
 131  
     /**
 132  
      * File Descriptions.
 133  
      */
 134  0
     private List fileList = new List(8, false);
 135  
     
 136  
     /**
 137  
      * Custom ROM Loader Dialog Box.
 138  
      */
 139  0
     private JFrame openFrame = new JFrame("Open");
 140  
     
 141  
     /**
 142  
      * OK button.
 143  
      */
 144  0
     private JButton okButton = new JButton("OK");
 145  
     
 146  
     /**
 147  
      * Cancel button.
 148  
      */
 149  0
     private JButton cancelButton = new JButton("Cancel");
 150  
     
 151  
     /**
 152  
      * Has a Cartridge Been Loaded.
 153  
      */
 154  0
     private boolean cartLoaded = false;
 155  
     
 156  
     /**
 157  
      * Game Gear image.
 158  
      */
 159  
     private Image gameGear;
 160  
     
 161  
     /**
 162  
      * Splash screen image.
 163  
      */
 164  
     private Image splash;
 165  
     
 166  
     /**
 167  
      * Initializes de applet.
 168  
      */
 169  
     public void init() {
 170  
         // Load Images
 171  0
         URL imageURL = JavaGearApplet.class.getResource("/images/cart.gif");
 172  0
         final Image cart = Toolkit.getDefaultToolkit().getImage(imageURL);
 173  0
         imageURL = JavaGearApplet.class.getResource("/images/sound.gif");
 174  0
         final Image soundOn = Toolkit.getDefaultToolkit().getImage(imageURL);
 175  0
         imageURL = JavaGearApplet.class.getResource("/images/soundoff.gif");
 176  0
         final Image soundOff = Toolkit.getDefaultToolkit().getImage(imageURL);
 177  0
         imageURL = JavaGearApplet.class.getResource("/images/controller.gif");
 178  0
         final Image control = Toolkit.getDefaultToolkit().getImage(imageURL);
 179  0
         imageURL = JavaGearApplet.class.getResource("/images/fs0.gif");
 180  0
         final Image fs0 = Toolkit.getDefaultToolkit().getImage(imageURL);
 181  0
         imageURL = JavaGearApplet.class.getResource("/images/fs1.gif");
 182  0
         final Image fs1 = Toolkit.getDefaultToolkit().getImage(imageURL);
 183  0
         imageURL = JavaGearApplet.class.getResource("/images/fs2.gif");
 184  0
         final Image fs2 = Toolkit.getDefaultToolkit().getImage(imageURL);
 185  0
         imageURL = JavaGearApplet.class.getResource("/images/gamegear.jpg");
 186  0
         gameGear = Toolkit.getDefaultToolkit().getImage(imageURL);
 187  0
         imageURL = JavaGearApplet.class.getResource("/images/splash.jpg");
 188  0
         splash = Toolkit.getDefaultToolkit().getImage(imageURL);
 189  
         
 190  
         // Wait for images to load
 191  0
         MediaTracker tracker = new MediaTracker(this);
 192  0
         tracker.addImage(cart, 0);
 193  0
         tracker.addImage(gameGear, 1);
 194  0
         tracker.addImage(soundOn, 2);
 195  0
         tracker.addImage(soundOff, 3);
 196  0
         tracker.addImage(control, 4);
 197  0
         tracker.addImage(fs0, 5);
 198  0
         tracker.addImage(fs1, 6);
 199  0
         tracker.addImage(fs2, 7);
 200  0
         tracker.addImage(splash, 8);
 201  
         try {
 202  0
             tracker.waitForAll();
 203  0
         } catch (InterruptedException ie) {
 204  0
             Logger.getLogger(this.getClass()).error("Interrupted while waiting for images to load"
 205  
                     , ie);
 206  0
         }
 207  
         
 208  
         // Create pointer to general options
 209  0
         setup = new Setup();
 210  
         
 211  
         // Initialise Objects
 212  0
         controllers = new Controllers(setup);
 213  0
         InterruptLine irq = new InterruptLine();
 214  0
         mem = new Memory(setup);
 215  0
         vdp = new Vdp(setup, irq);
 216  0
         screenpanel = new Screen(setup, vdp);
 217  0
         sn76496 = new SN76496(111860.78125, 11025);
 218  0
         port = new Ports(vdp, controllers, sn76496);
 219  0
         z80cpu = new Z80(mem, port, irq);
 220  0
         emulateLoop = new EmulateLoop(z80cpu, mem, vdp, sn76496, screenpanel, setup);
 221  
         
 222  
         // Create ToolBar
 223  0
         bar = new JToolBar();
 224  
         
 225  0
         Action openCartAction = new AbstractAction("Open Cartridge", new ImageIcon(cart)) {
 226  
             public void actionPerformed(ActionEvent event) {
 227  0
                 if (cartLoaded) {
 228  0
                     emulateLoop.suspendThread();
 229  
                 }
 230  0
                 openFrame.setVisible(true);
 231  0
             }
 232  
         };
 233  0
         Action soundAction = new AbstractAction("Toggle Sound", new ImageIcon(soundOn)) {
 234  
             public void actionPerformed(ActionEvent event) {
 235  0
                 sn76496.setEnabled();
 236  0
                 if (sn76496.isEnabled()) {
 237  
                     // Change Icon
 238  0
                     putValue(Action.SMALL_ICON, new ImageIcon(soundOn));
 239  
                 } else {
 240  0
                     putValue(Action.SMALL_ICON, new ImageIcon(soundOff));
 241  
                 }
 242  0
                 requestFocus();
 243  0
             }
 244  
         };
 245  0
         Action controlAction = new AbstractAction("Controller Config", new ImageIcon(control)) {
 246  
             public void actionPerformed(ActionEvent event) {
 247  0
                 if (keyFrame == null) {
 248  0
                     keyFrame = new KeyFrame(controllers);
 249  
                 }
 250  0
                 keyFrame.setVisible(true);
 251  0
             }
 252  
         };
 253  
         
 254  0
         Action frameSkipAction = new AbstractAction("FrameSkip", new ImageIcon(fs0)) {
 255  
             public void actionPerformed(ActionEvent event) {
 256  0
                 int frameskip = Throttle.fskip;
 257  
                 
 258  0
                 if (++frameskip > 2) {
 259  0
                     frameskip = 0;
 260  
                 }
 261  0
                 Throttle.setFrameSkip(frameskip);
 262  
                 
 263  
                 // Cycle Icons
 264  0
                 if (frameskip == 0) {
 265  0
                     putValue(Action.SMALL_ICON, new ImageIcon(fs0));
 266  0
                 } else if (frameskip == 1) {
 267  0
                     putValue(Action.SMALL_ICON, new ImageIcon(fs1));
 268  0
                 } else if (frameskip == 2) {
 269  0
                     putValue(Action.SMALL_ICON, new ImageIcon(fs2));
 270  
                 }
 271  
                 
 272  0
                 requestFocus();
 273  0
             }
 274  
         };
 275  
         
 276  
         // Add the Actions to the ToolBar
 277  0
         bar.add(openCartAction);
 278  0
         bar.add(controlAction);
 279  0
         bar.add(soundAction);
 280  0
         bar.add(frameSkipAction);
 281  
         // So the toolbar doesn't take our left/right keys!
 282  0
         bar.setActionMap(null);
 283  
         // Disable toolbar dragging
 284  0
         bar.setFloatable(false);
 285  
         // Add ToolBar To Top Of Frame
 286  0
         getContentPane().add(bar, "North");
 287  
         
 288  
         // Set Emulation Defaults
 289  0
         port.setEurope(true); // Default to a domestic system
 290  0
         setup.setSystem(Setup.System.SMS); // Default to SMS mode
 291  
         
 292  
         // Load ROM List
 293  0
         readIndexFile();
 294  
         
 295  
         // Add Keyboard Support
 296  0
         addKeyListener(controllers);
 297  
         
 298  
         // Add Display Window
 299  0
         getContentPane().add(screenpanel);
 300  
         
 301  
         // Receive Keystrokes Immediately
 302  0
         requestFocus();
 303  0
     }
 304  
     
 305  
     
 306  
     /**
 307  
      * Invoked when a button from the ROM Selector is clicked.
 308  
      *
 309  
      * @param evt a non-null instance of <code>ActionEvent</code>.
 310  
      */
 311  
     public void actionPerformed(ActionEvent evt) {
 312  
         // Load ROM from List
 313  0
         if (evt.getSource() == okButton) {
 314  0
             if (fileList.getSelectedIndex() != -1) {
 315  
                 try {
 316  0
                     String path = romDirectory + filenames[fileList.getSelectedIndex()];
 317  
                     
 318  
                     // Set PAL/NTSC
 319  0
                     if (tvType[fileList.getSelectedIndex()]) {
 320  0
                         emulateLoop.setNTSC();
 321  
                     } else {
 322  0
                         emulateLoop.setPAL();
 323  
                     }
 324  
                     
 325  0
                     openFrame.setVisible(false);
 326  0
                     openCart(new URL(getCodeBase(), path));
 327  0
                 } catch (MalformedURLException mue) {
 328  0
                     Logger.getLogger(this.getClass()).error("Unable to open cart.", mue);
 329  0
                 }
 330  
             }
 331  0
             requestFocus();
 332  0
         } else if (evt.getSource() == cancelButton) {
 333  0
             openFrame.setVisible(false);
 334  0
             if (cartLoaded) {
 335  0
                 screenpanel.disposeGraphics();
 336  0
                 emulateLoop.resumeThread();
 337  
             }
 338  0
             requestFocus();
 339  
         }
 340  0
     }
 341  
     
 342  
     /**
 343  
      * Paint splash screen and Game Gear image.
 344  
      *
 345  
      * @param g The graphics context to use for painting.
 346  
      */
 347  
     public void paint(Graphics g) {
 348  0
         super.paint(g);
 349  
         
 350  0
         if (cartLoaded) {
 351  0
             if (setup.getSystem() == Setup.System.GG) {
 352  0
                 screenpanel.getGraphics().drawImage(gameGear, 0, 0, this);
 353  
             }
 354  
         } else {
 355  0
             Dimension d = screenpanel.getSize();
 356  0
             screenpanel.getGraphics().drawImage(splash, 0, 0, d.width, d.height, this);
 357  
         }
 358  0
     }
 359  
     
 360  
     /**
 361  
      * Read Index File From Server.
 362  
      * The Index File Contains The List of ROMs
 363  
      */
 364  
     public void readIndexFile() {
 365  0
         InputStreamReader is = null;
 366  0
         URL url = null;
 367  0
         int linecount = 0; // stores number of lines in files
 368  
         
 369  
         try {
 370  0
             url = new URL(getCodeBase(), romDirectory + romIndex);
 371  0
             is = new InputStreamReader(url.openStream());
 372  0
         } catch (MalformedURLException mue) {
 373  0
             System.out.println("The URL for the ROM list is not valid: "
 374  
                     + romDirectory + romIndex);
 375  0
             Logger.getLogger(this.getClass()).error("The URL for the ROM list is not valid.", mue);
 376  0
             return;
 377  0
         } catch (IOException ioe) {
 378  0
             System.out.println("Unable to open URL: " + url);
 379  0
             Logger.getLogger(this.getClass()).error("Unable to open URL: " + url, ioe);
 380  0
             return;
 381  0
         }
 382  
         
 383  0
         BufferedReader bis = new BufferedReader(is);
 384  
         
 385  
         // Count lines in file
 386  
         try {
 387  0
             while (bis.readLine() != null) {
 388  0
                 linecount++;
 389  
             }
 390  
             // reset to start of stream
 391  0
             bis = new BufferedReader(new InputStreamReader(url.openStream()));
 392  0
         } catch (IOException ioe) {
 393  0
             System.out.println("Error reading from: " + url);
 394  0
             Logger.getLogger(this.getClass()).error("Error reading from: " + url, ioe);
 395  0
             return;
 396  0
         }
 397  
         
 398  
         // Create an array of the correct size
 399  0
         filenames = new String[linecount];
 400  0
         tvType = new boolean[linecount];
 401  0
         linecount = 0; // Reset number of lines
 402  
         String s;
 403  
         
 404  
         try {
 405  0
             while ((s = bis.readLine()) != null) {
 406  
                 // Split string at ':'
 407  0
                 for (int x = 0; x < s.length(); x++) {
 408  0
                     if (s.charAt(x) == ':') {
 409  0
                         int filenameStart = x + 1;
 410  
                         
 411  
                         // Not over bounds
 412  0
                         if ((x + 2) < s.length()) {
 413  
                             // Check for PAL
 414  0
                             if ((s.charAt(x + 1) == 'p') && (s.charAt(x + 2) == ':')) {
 415  0
                                 filenameStart += 2;
 416  0
                                 tvType[linecount] = false;
 417  
                             } else {
 418  0
                                 tvType[linecount] = true;
 419  
                             }
 420  
                         }
 421  
                         
 422  
                         // Add file description to Combo list at the index specified by linecount
 423  0
                         fileList.add(s.substring(0, x), linecount);
 424  
                         // Add filename to the array
 425  0
                         filenames[linecount++] = s.substring(filenameStart);
 426  0
                         break;
 427  
                     }
 428  
                 }
 429  
             } // end while
 430  0
         } catch (IOException ioe) {
 431  0
             System.out.println("Error reading from: " + romIndex);
 432  0
             Logger.getLogger(this.getClass()).error("Error reading from: " + romIndex, ioe);
 433  0
             return;
 434  0
         }
 435  
         
 436  0
         JPanel p2 = new JPanel();
 437  0
         p2.add(okButton);
 438  0
         p2.add(cancelButton);
 439  0
         okButton.addActionListener(this);
 440  0
         cancelButton.addActionListener(this);
 441  0
         openFrame.getContentPane().add(fileList, "North");
 442  0
         openFrame.getContentPane().add(p2, "South");
 443  0
         openFrame.setResizable(false);
 444  0
         openFrame.pack();
 445  0
     }
 446  
     
 447  
     /**
 448  
      * Open cartridge and start emulation.
 449  
      *
 450  
      * @param filename <code>URL</code> of cartridge image.
 451  
      */
 452  
     public void openCart(URL filename) {
 453  0
         mem.reset();
 454  
         try {
 455  0
             mem.readCart(filename);
 456  0
             cartLoaded = true;
 457  0
             emulateLoop.stopThread();
 458  0
             if (setup.getSystem() == Setup.System.GG) {
 459  0
                 emulateLoop.setNTSC();
 460  
             }
 461  0
             z80cpu.reset();
 462  0
             vdp.reset();
 463  0
             emulateLoop.startThread();
 464  0
         } catch (IOException ioe) {
 465  0
             Logger.getLogger(this.getClass()).error("Error opening ROM file: " + filename, ioe);
 466  0
         } catch (IllegalArgumentException iae) {
 467  0
             Logger.getLogger(this.getClass()).error("Error opening ROM file: " + filename, iae);
 468  
         } finally {
 469  0
             repaint(); // repaint this window
 470  0
         }
 471  0
     }
 472  
     
 473  
     /**
 474  
      * Stop applet.
 475  
      */
 476  
     public void stop() {
 477  
         //emulateLoop.stopThread();
 478  0
     }
 479  
     
 480  
 }