/* * @(#)Jasper.java 1.1 27/04/97 Adam Davidson & Andrew Pollard */ import java.awt.*; import java.applet.*; import java.net.*; import java.io.*; /** *

The Jasper class wraps up * the Spectrum class into an Applet which emulates a ZX Spectrum in a Web Page.

* *

* * * *

* *

This applet can be supplied the following parameters: *

* *

The snapshot parameter can specify a file in one of two popuplar formats, * .z80 * or .sna. * The type is determined at runtime by checking the length of the snapshot * file, if it is 49,179 then it is assumed to be of type .sna else it is assumed to * be of type .z80.

* *

The rom parameter can be used to specify a different ROM to load * other than the standard sinclair ROM. This file must be 16,384 bytes in length. * The default value is spectrum.rom.

* *

The borderWidth parameter specifies the width in pixels of the border * which surrounds the main screen. The default value is 20.

* *

The refreshRate parameter specifies how often the screen should be * updated in terms of Z80 interrupts. The default value is 1.

* *

The sleepHack parameter is needed to introduce a delay into the main * Z80 execute loop. In some browsers, the thread which updates the screen and * delivers keyboard/mouse events to the applet can be blocked out by the Spectrum * thread since it never gives up its timeslice. By default the value for this * is 0 which means that the main execute loop runs at full speed. * *

The showStats parameter enables or disables the progress bar at the * foot of the screen. The values that can be supplied are Yes and No. * The default value is Yes.

* *

Since the release of version 1.0 Jasper has won various awards:

* *
* * Rated Top 1% WebApplet by JARS * * Gamelan * * Duke Award *
* *

Jasper is best viewed with:
*

* * Download Explorer

*
* *

Thanks to Adam Doppelt * for his AMDProgressBar class.

* * Version: 1.1 27 Apr 1997
* Authors: Adam Davidson & Andrew Pollard
* * @see Spectrum * @see Z80 */ public class Jasper extends Applet implements Runnable { Spectrum spectrum = null; Thread thread = null; /** Version and author information. */ public String getAppletInfo() { return "Jasper V1.1 by Adam Davidson and Andrew Pollard"; } /** Applet parameters and their descriptions. */ public String[][] getParameterInfo() { String [][] info = { { "snapshot", "filename", "name of SNA or Z80 snapshot to load" }, { "rom", "filename", "filename of ROM (default=spectrum.rom)" }, { "borderWidth", "integer", "width of spectrum border (default=20)" }, { "refreshRate", "integer", "refresh screen every 'X' interrupts (default=1)" }, { "sleepHack", "integer", "sleep per interrupt in ms, for old VMs (default=0)" }, { "showStats", "Yes/No", "show progress bar (default=Yes)" }, }; return info; } /** Initailize the applet. */ public void init() { setLayout( null ); } /** Start the applet creating a new thread which invokes run(). */ public void start() { if ( thread == null ) { thread = new Thread( this, "Jasper" ); thread.start(); } } /** Stop the applet. */ public void stop() { if ( thread != null ) { thread.stop(); thread = null; } } /** Parse available applet parameters. * @exception Exception Problem loading ROM or snaphot. */ public void readParameters() throws Exception { String rom = getParameter( "rom" ); if ( rom == null ) { rom = "spectrum.rom"; } spectrum.setBorderWidth( getIntParameter( "borderWidth", spectrum.borderWidth*spectrum.pixelScale, 0, 100 ) ); spectrum.refreshRate = getIntParameter( "refreshRate", spectrum.refreshRate, 1, 100 ); spectrum.sleepHack = getIntParameter( "sleepHack", spectrum.sleepHack, 0, 100 ); resize( preferredSize() ); // once borderWidth is set up String showStats = getParameter( "showStats" ); if ( showStats != null ) { if ( showStats.equals( "Yes" ) ) { spectrum.showStats = true; } else if ( showStats.equals( "No" ) ) { spectrum.showStats = false; } } URL baseURL = getDocumentBase(); spectrum.urlField.setText( baseURL.toString() ); URL romURL = new URL( baseURL, rom ); spectrum.loadROM( romURL.toString(), romURL.openStream() ); String snapshot = getParameter( "snapshot" ); snapshot = ((snapshot == null) ? getParameter( "sna" ) : snapshot); snapshot = ((snapshot == null) ? getParameter( "z80" ) : snapshot); if ( snapshot != null ) { URL url = new URL( baseURL, snapshot ); URLConnection snap = url.openConnection(); InputStream input = snap.getInputStream(); spectrum.loadSnapshot( url.toString(), input, snap.getContentLength() ); input.close(); } else { spectrum.reset(); spectrum.refreshWholeScreen(); } } /** Read applet parameters and start the Spectrum. */ public void run() { showStatus( getAppletInfo() ); if ( spectrum == null ) { try { spectrum = new Spectrum( this ); readParameters(); } catch ( Exception e ) { showStatus( "Caught IO Error: " + e.toString() ); } } if ( spectrum != null ) { spectrum.execute(); } } /** Handle integer parameters in a range with defaults. */ public int getIntParameter( String name, int ifUndef, int min, int max ) { String param = getParameter( name ); if ( param == null ) { return ifUndef; } try { int n = Integer.parseInt( param ); if ( n < min ) return min; if ( n > max ) return max; return n; } catch ( Exception e ) { return ifUndef; } } /** Refresh handling. */ public void update( Graphics g ) { paint( g ); } /** Paint sets a flag on the spectrum to tell it to redraw the screen on the next Z80 interrupt. */ public void paint( Graphics g ) { if ( spectrum != null ) { spectrum.repaint(); } } /** Event handling. */ public boolean handleEvent( Event e ) { if ( spectrum != null ) { return spectrum.handleEvent( e ); } return super.handleEvent( e ); } /** Applet size. */ public Dimension minimumSize() { int scale = spectrum.pixelScale; int border = (spectrum == null) ? 20 : spectrum.borderWidth; return new Dimension( spectrum.nPixelsWide * scale + border*2, spectrum.nPixelsHigh * scale + border*2 ); } /** Returns Jasper.minimumSize(). */ public Dimension preferredSize() { return minimumSize(); } }