// Class starwarsscroller
//
// (C) Søren Holstebroe 2 oct. 1997
//
//[Adding some functionalities Philippe Guilbert 02-04-2000]
import java.util.*;
import java.awt.*;
import java.io.*;
import java.awt.image.*;
import java.applet.*;
import java.net.URL;
import java.net.MalformedURLException;
public class starwarsscroller extends Applet implements Runnable
{
//
// Defaults
//
private final int DELAY = 10; // delay between frames in ms
private final int FONTSIZE = 20;
private final String FONTNAME = "SansSerif";
private final double SCROLLSPEED = 0.5;
private final int DECIMAL = 16; // bits used for integer decimal
private final int MAXLINES = 256;
private final int LINESPACE = 0;
private final int ZOOM = 100;
private final int DIST = 200;
private final double ANGLE = 1.3;
private final String DEFAULTURL = "http://www.rhk.dk/users/seap/starwars.txt";
private final Color BGCOLOR = Color.black;
private final Color FONTCOLOR = Color.yellow;
private final int LOOPSPACE = 0;
Color fontColor,bgColor;
Image textimg,img;
Graphics textg; // textbuffer
Thread killme = null;
MemoryImageSource source;
boolean loop; // default : text will be displayed only once
boolean started; // to interrupt the thread without the crashing "stop()" method
int[] pixels; // display pixels
int width,height; // display dimensions
int[] textpixels; // source pixels
int textwidth,textheight; // source dimensions
String urlname; // name of url of text to scroll
String fontname; // name of font to scroll
int fontsize; // size of above font
int linespace; // space in pixels between lines of text to be scrolled
int maxlines; // maximum number of lines to be scrolled
int loopSpace; // maximum space in pixels between two loops
int delay;
double scroll_offset, scroll_speed, scroll_begin;
double cos_vx,sin_vx,vx;
double theEnd; // maximum height of the text... untill it is not visible any more
double dist,zoom;
public void init()
{
setBackground(BGCOLOR);
int i;
URL url;
String s;
width = getSize().width; // width of viewport reserved by browser
height = getSize().height; // height of viewport reserved by browser
//
// Load parameters
//
urlname = getParameter("url");
if (urlname == null) {
urlname = DEFAULTURL;
}
fontname = getParameter("fontname");
if (fontname == null)
fontname = FONTNAME;
s = getParameter("fontsize");
if (s != null)
fontsize = parseNum(s,FONTSIZE);
else
fontsize = FONTSIZE;
s = getParameter("linespace");
if (s != null)
linespace = parseNum(s,LINESPACE);
else
linespace = LINESPACE;
s = getParameter("maxlines");
if (s != null)
maxlines = parseNum(s,MAXLINES);
else
maxlines = MAXLINES;
s = getParameter("zoom");
if (s != null)
zoom = (double) parseNum(s,ZOOM);
else
zoom = ZOOM;
s = getParameter("angle");
if (s == null)
vx = ANGLE;
else
vx = Double.valueOf(s).doubleValue();
cos_vx = Math.cos(vx);
sin_vx = Math.sin(vx);
s = getParameter("scrollspeed");
if (s == null)
scroll_speed = SCROLLSPEED;
else
scroll_speed = Double.valueOf(s).doubleValue();
s = getParameter("delay");
if (s != null)
delay = parseNum(s,DELAY);
else
delay = DELAY;
s = getParameter("fontcolor");
if ((s == null) || (s.equals("")))
fontColor = FONTCOLOR;
else
fontColor = defineColor(s,"font");
System.err.println("fontcolor : >"+s+"< \r");
System.err.println("fontcolor :"+fontColor.toString());
s = getParameter("bgcolor");
if ((s == null)||(s.equals("")))
bgColor = BGCOLOR;
else
bgColor = defineColor(s,"bg");
s = getParameter("loop");
if ((s != null)&&(s.toLowerCase().equals("yes")))
loop = true;
else
loop = false;
s = getParameter("loopspace");
if (s != null)
loopSpace = parseNum(s,LOOPSPACE);
else
loopSpace = LOOPSPACE;
Font font = new Font(fontname,Font.BOLD,fontsize);
try
{
url = new URL(getCodeBase(),urlname);
} catch (MalformedURLException e1)
{
System.out.println("Malformed URL ERROR using default");
try
{
url = new URL(DEFAULTURL);
} catch (MalformedURLException e2)
{
System.out.println("ERROR! Could not init default url");
return;
}
}
textimg = url2image(url,font);
System.out.println("W = "+textimg.getWidth(this)+" H = "+textimg.getHeight(this));
// INIT TEXTIMAGE
textwidth = textimg.getWidth(this);
textheight = textimg.getHeight(this);
textpixels = getPixels(textimg); // convert Image to integer array (pixels)
textimg = createImage(new
MemoryImageSource(textwidth, textheight, textpixels, 0, textwidth));
// Load parameter "dist"
s = getParameter("dist");
if (s == null)
{
dist = DIST;
// Calculate DIST
// We want to adjust DIST in such way, that width of the text fits the width of the screen
//
//
// temp = dist / (cos_vx * zoom + (height-height/4) * sin_vx);
// 0 = (-textwidth/2)/(cos_vx * temp)+width/2;
// -(width/2)*(cos_vx * temp)=(-textwidth/2)
// temp = (textwidth/2)/((width/2) * cos_vx)
// dist = (cos_vx * zoom + (height-height/4) * sin_vx)*(textwidth/2)/((width/2) * cos_vx)
dist = (cos_vx * zoom + (height-height/4) * sin_vx) *
(textwidth/2)/((width/2) * cos_vx);
// System.out.println("DIST = "+dist);
}
else
dist = (double) Integer.parseInt(s);
// Calculate scroll_offset
/*
The following equation tells with what scroll_offset
the text is _just_ out of sight below the screen.
temp = dist / (cos_vx * zoom + (height-height/4) * sin_vx);
0 = scroll_offset + ((height-height/4) * temp)
*/
scroll_offset = -(height-height/4.0) *
(dist / (cos_vx * zoom + (height-height/4.0) * sin_vx));
scroll_begin = scroll_offset;
theEnd = (double) (scroll_begin+textheight*2+loopSpace);
// INIT DISPLAYIMAGE
pixels = new int[width*height];
for (i=0;i textwidth)
textwidth = tmp;
}
textheight = (fontM.getHeight()+linespace)*line;
// INIT TEXTIMAGE
textimg = createImage(textwidth,textheight);
textg = textimg.getGraphics();
textg.setColor(bgColor);
textg.fillRect(0,0,textwidth,textheight);
textg.setColor(fontColor);
textg.setFont(font);
for (i=0;i=textheight)
continue;
maxY0 = (int)(((height-1)-height/4) * temp);
minY0 = (int)((yStart-height/4) * temp);
colorMask = 0xff000000 + 0x00010100*
(int)(((y-height/4) * temp-minY0)*255/(maxY0-minY0));
// init x0
x0 = (int)((1<= 0 && x0 < textwidth && y0 >= 0 && y0 < textheight)
pixels[sOffset++] = textpixels[tOffset+(x0>>DECIMAL)]&colorMask;
// else
// pixels[x+y*width] = 0xffff00ff; // Test: farv blå hvis vi er uden for grænsen
x0 += dx0;
}
}
scroll_offset += scroll_speed;
if (scroll_offset>=theEnd) //testing if loop=true and looping
{
if (loop)
scroll_offset = scroll_begin;
else
stop();
}
}
public void start()
{
if(killme == null)
{
killme = new Thread(this);
killme.start();
}
}
public void stop()
{
if (killme != null && killme.isAlive())
killme = null;
}
public void run()
{
while (true) {
repaint();
try {Thread.sleep(delay);} catch (InterruptedException e){}
}
}
public void paint(Graphics g)
{
next_scrollimage();
source.newPixels(0, 0, width, height);
g.drawImage(img,0,0,this);
}
public void update(Graphics g)
{
paint(g);
}
private int parseNum(String st, int constant)
{
if (st.equals(""))
return constant;
try
{
int num = Integer.parseInt(st);
return num;
} catch (NumberFormatException nbe)
{
return constant;
}
}
private Color defineColor(String s, String type)
{
StringTokenizer stk = new StringTokenizer(s,",");
int counter = 0;
int value[] = new int[3];
String temp = null;
while (stk.hasMoreTokens()) {
temp = stk.nextToken();
try {
value[counter]=Integer.parseInt(temp);
++counter;
} catch (NumberFormatException nbe) {
System.err.println("Error in defining the colors...");
if (type.equals("font"))
return FONTCOLOR;
if (type.equals("bg"))
return BGCOLOR;
}
}
return new Color(value[0],value[1],value[2]);
}
}