import browser.*;
import awt.*;
import java.lang.*;
import net.*;
class FrogPond extends Applet {
/* This is the version running on the Frog Pond Benchmark page */
float now [][]; /* arrays for calculating raster values */
float old [][];
float neww [][];
float laplacian[][];
float sum [][];
int numButtons=10;
int selectedButton;
int drawStatus=0;
int newheight=200; /* display size */
int newwidth=200;
final int height=50; /* calculation matrix size */
final int width=50;
float velocity;
float viscosity;
int pclip; /*the clip percentage: any value in the
calculation matrix that is at or above this
percentile or at or below 100-this
percentile will be assigned the maximum
or minimum value, respectively*/
int status;
int click;
boolean rmode=true; /* is random mode on? */
boolean painted=false; /* is pond finished painting? */
boolean up=false; /* has user just clicked on the applet? */
boolean newFrog=false; /* will the frog be moving this frame? */
boolean firstFrog=true;
boolean firstClick=true;
int curX;
int curY;
int nextX;
int nextY;
int frogX;
int frogY;
int fpd=1; /* frames of calculation per pond update */
int fnum=0;
boolean clicked=false;
Image frogImg;
ImageMaker imgmkr;
RButton[] buttons=new RButton[numButtons];
long startTime;
long pauseTime;
long pauseStartTime;
long paintTime;
long paintStartTime;
BarGraph graph;
float fPerS=0.0;
public void init() {
int i;
int j;
now=new float[width][height];
neww=new float[width][height];
old=new float[width][height];
laplacian=new float[width][height];
sum=new float[width][height];
resize(550,480);
fnum=0;
pauseTime=0;
rmode=true;
velocity=.20;
viscosity=.15;
pclip=100;
click=0;
status=1;
curX=-1;
curY=-1;
frogImg=getImage("images/frog.gif");
for(i=0;i<width; i++) {
for(j=0;j<height;j++) {
now[i][j]=0;
old[i][j]=0;
neww[i][j]=0;
}
}
imgmkr=new ImageMaker(width,height,newwidth,newheight,neww,
pclip);
imgmkr.makeImage();
makeButtons();
makeGraph();
nextX=(int)(width*Math.random());
nextY=(int)(height*Math.random());
startTime=System.currentTimeMillis();
}
public void paint (Graphics g) {
g.drawImage(imgmkr.img, 0, 0);
for(int i=0;i<numButtons;i++) buttons[i].drawUp(g);
updateStats(g);
graph.drawLabels(g);
painted=true;
}
/* The update method is used so the applet display will be updated
* throughout the execution of the applet, not just at its termination
*/
public void update (Graphics g) {
switch(drawStatus) {
case 0: updatePond(g);painted=true;
newFrog=false; break;
case 1: painted=true;
buttons[selectedButton].drawDown(g);
painted=true; break;
case 2: buttons[selectedButton].drawUp(g);
painted=true; break;
case 3: updateStats(g);painted=true; break;
case 4: updateGraph(g);break;
}
painted=true;
}
public final void updatePond(Graphics g){
paintStartTime=System.currentTimeMillis();
imgmkr=new ImageMaker(width,height,newwidth, newheight,neww,pclip);
imgmkr.oldras=neww; /* create the image */
imgmkr.pclip=pclip;
imgmkr.makeImage();
if(newFrog){ //find new frog location
int fx=(int)(frogX*width/newwidth);
int fy=(int)(frogY*height/newheight);
if(neww[fx][fy]<=0)g.setForeground(Color.blue);
if(neww[fx][fy]>0)g.setForeground(Color.white);
g.fillRect(frogX,frogY,37,28);
g.setForeground(Color.black);
if(firstFrog){pclip=99; firstFrog=false;}
}
g.drawImage(imgmkr.img,0,0);
frogX=(int)(nextX*newwidth /width -19);
frogY=(int)(nextY*newheight/height-14);
/* if frog overlaps edge of pond, reposition him so he
doesn't */
if(frogX>newwidth -37)frogX=newwidth -37;
if(frogY>newheight-28)frogY=newheight-28;
if(frogX<0)frogX=0;
if(frogY<0)frogY=0;
if(curX!=-1)g.drawImage(frogImg,frogX,frogY);
g.clearRect(405,270,150,115);
int len=405+g.drawStringWidth("Frames/sec: ",405,290);
long msecs=System.currentTimeMillis()-startTime-pauseTime;
fPerS=(float)(1000*fnum)/msecs;
g.drawStringWidth(Float.toString(fPerS), len,290);
len= 405+g.drawStringWidth("Frame #: ", 405,315);
g.drawStringWidth(Integer.toString(fnum), len,315);
}
public final void updateStats(Graphics g){
int totalLen;
g.clearRect(0,400,550,40);
totalLen=g.drawStringWidth("XSize: ", 0, 410);
totalLen+=g.drawStringWidth(Integer.toString(newwidth),
totalLen,410);
totalLen+=g.drawStringWidth(" YSize: " ,
totalLen,410);
totalLen+=g.drawStringWidth(Integer.toString(newheight),
totalLen,410);
totalLen+=g.drawStringWidth(" Status: ",totalLen,410);
switch(status){
case 1:totalLen+= g.drawStringWidth("running", totalLen,410);break;
case 2: totalLen+=g.drawStringWidth("finished",
totalLen,410);break;
case 3:totalLen+= g.drawStringWidth("paused",
totalLen,410);break;
}
totalLen+=g.drawStringWidth(" Random: " ,totalLen, 410);
if(rmode) totalLen+=g.drawStringWidth("on", totalLen, 410);
else totalLen+=g.drawStringWidth("off", totalLen, 410);
totalLen+=g.drawStringWidth(" Frame Skip: ", totalLen, 410);
totalLen+=g.drawStringWidth(Integer.toString(fpd-1),
totalLen, 410);
totalLen+=g.drawStringWidth(" Clip %: ", totalLen, 410);
totalLen+=g.drawStringWidth(Float.toString(pclip),
totalLen,410);
painted=true;
}
public final void updateGraph(Graphics g){
graph.draw(g,fPerS);
}
public final void makeButtons(){
buttons[0]=new RButton(405,0 ,30,20,"pause" ,Color.orange,
null,Color.black,null,true);
buttons[1]=new RButton(405,55 ,30,20,"stop" ,Color.red,
null,Color.black,null,true);
buttons[2]=new RButton(405,110,30,20,"clip +1%",Color.cyan,
null,Color.black,null,true);
buttons[3]=new RButton(465,55 ,30,20,"random" ,Color.red,
null,Color.black,null,true);
buttons[4]=new RButton(465,0 ,30,20,"reset" ,Color.orange,
null,Color.black,null,true);
buttons[5]=new RButton(465,110,30,20,"clip -1%",Color.cyan,
null,Color.black,null,true);
buttons[6]=new RButton(405,165,30,20,"fskip+" ,Color.green,
null,Color.black,null,true);
buttons[7]=new RButton(465,165,30,20,"fskip-" ,Color.green,
null,Color.black,null,true);
buttons[8]=new RButton(405,210,30,20,"enlarge" ,Color.magenta,
null,Color.black,null,true);
buttons[9]=new RButton(465,210,30,20,"reduce" ,Color.magenta,
null,Color.black,null,true);
}
public final void makeGraph(){
String labels[]=new String[3];
labels[0]="Macintosh";
labels[1]="Sun Solaris";
labels[2]="Cray";
graph=new BarGraph(30,440,450,20,0.0,2.0,3,labels);
}
public void mouseUp(int x, int y){
int temp=drawStatus;
if(x<newheight && y<newwidth){ /* user has clicked on pond*/
if(!clicked)firstClick=true;
clicked=true; click=1; rmode=false; newFrog=true;
curX=nextX;
curY=nextY;
nextX=(int)(x*width /newwidth);
nextY=(int)(y*height/newheight);
} else { /* see if user has hit a button */
for(int i=0;i<numButtons;i++){
if(buttons[i].selected(x,y)) selectedButton=i;
up=true;
}
}
}
public final void handleMouseUp() {
up=false;
drawStatus=1; /* draw button down */
repaint();
drawStatus=2; /* draw button up */
repaint();
doButtonEvent();
}
public final void doButtonEvent() {
drawStatus=3;
switch(selectedButton) {
case 0: if(status==3){status=1;break;}status=3; break;
case 1: status=2; break;
case 2: if(pclip<100)pclip+=1; break;
case 3: rmode= !rmode; break;
case 4: init(); break;
case 5: if(pclip>6) pclip-=1; break;
case 6: if(fpd<39) fpd++; break;
case 7: if(fpd>1 ) fpd-; break;
case 8: if(newheight<390){ newheight+=10;
newwidth+=10;} break;
case 9: if(newheight>10){ newheight-=10;
newwidth-=10;} break;
}
repaint();
}
public final void calcValues() {
int i,j;
for(i=0;i<width ;i++){
for(j=0;j<height;j++){
sum[i][j]=now[i][j]-viscosity * old[i][j];
}
}
for(i=1;i<width-1 ;i++){
for(j=1;j<height-1;j++){
laplacian[i][j]= sum[i-1][j]-2*sum[i][j ] +
sum[i+1][j]+ sum[i][j-1] -
2*sum[i ][j]+ sum[i][j+1];
}
}
for(i=1;i<width-1 ;i++){
for(j=1;j<height-1;j++){
neww[i][j]=-old[i][j]+2*now[i][j]+velocity*
laplacian[i][j];
}
}
}
public final void resetArrays(){
int i,j;
for(i=0;i<width;i++){
for(j=0;j<height;j++){
old[i][j]=now[i][j];
}
}
for(i=0;i<width;i++){
for(j=0;j<height;j++){
now[i][j]=neww[i][j];
}
}
for(i=0;i<width;i++){
for(j=0;j<height;j++){
neww[i][j]=0;
}
}
}
public final void randomToss(){
curX=nextX;
curY=nextY;
nextX=(int)(width*Math.random());
nextY=(int)(height*Math.random());
now[curX][curY]+=1; /* frog has jumped, start wave */
newFrog=true;
}
public void start (){
int p=0;
while(status==1||status==3){
if(status==3)while(status==3){
checkMouse();
if(p==0)pauseStartTime=
System.currentTimeMillis();
p=1;
}
if(p==1)pauseTime=(System.currentTimeMillis()
-pauseStartTime);
p=0;
checkMouse();
if(click==1){
now[curX][curY]+=1; // drop stone where
click=0; // user clicked
}
if((rmode)&&(fnum)%10==0)randomToss();
calcValues();// calculate new values
fnum++;
if(firstClick){
drawStatus=3;
repaint(); //so display will say
firstClick=false; //random is off
}
if((fnum%10)==0){
drawStatus=4;
repaint();
}
drawStatus=0;
if((fnum%fpd)==0){
painted=false;
repaint();
while(!painted){} /*make sure its finished */
}
resetArrays();
}
stop(); /*so Hotjava doesn't crash*/
}
final public void checkMouse(){
if(up)handleMouseUp();
}
}