//
/* ----------------------------------------------------------------------------------------------
ethernet.java イーサネット ver. 1.10 (JDK 1.02)
ueyama@infonet.co.jp 2000.10.05
---------------------------------------------------------------------------------------------- */
import java.applet.Applet;
import java.awt.*;
import java.lang.Math;
import java.util.*;
public class ethernet extends Applet implements Runnable
{
int Dq=14;
int Dx[]=new int[16]; // X座標値
int Dy[]=new int[16]; // Y座標値
int Snd[]={-1,-1,-1,-1,-1,-1,-1}; // 送信コンピュータ
int Rcv[]={-1,-1,-1,-1,-1,-1,-1}; // 受信コンピュータ
int Tq=0; // 通信数
int Ms=-1,Mr=-1;
boolean Busy=false; // true: ネットワーク使用中
boolean Run=true; // false: 停止
boolean Col=false; // true: 衝突発生モード
int Cd=0; // >0: 衝突検出
boolean Used[]=new boolean[11];
int W0,W1;
int Bgc;
int Wait=64;
Thread th=null;
Graphics gr;
Image Gif;
Random Rnd=new Random();
public void start()
{
if(th==null)
{
th=new Thread(this);
th.start();
}
}
public void init()
{
String bg=getParameter("BgColor");
Bgc=Integer.valueOf(bg,16).intValue();
setBackground(new Color(Bgc));
gr=getGraphics();
MediaTracker mt=new MediaTracker(this);
Gif=getImage(getCodeBase(),"ethernet.gif");
mt.addImage(Gif, 0);
try
{
mt.waitForID(0);
}
catch(InterruptedException e){};
}
public boolean inside(int x, int a, int b)
{
return (x<=Math.max(a,b) && x>=Math.min(a,b)) ? true:false;
}
public void dsp_g(int x, int y, int n, int c) // 画像の表示
{
int w=0,h=0, ox=0,oy=0;
Graphics gx=gr.create();
switch(n)
{
case 0: w= 11; h= 11; ox=248; oy=11; break; // 宛先 ヘッダ
case 1: w= 11; h= 11; ox=248; oy= 0; break; // 送り主 ヘッダ
case 2: w= 11; h= 11; ox=369; oy= 0; break; // データ
case 3: w= 11; h= 11; ox=369; oy=11; break; // データ消去
case 4: w= 61; h= 60; ox= 0; oy= 0; break; // コンピュータ
case 5: w= 17; h= 21; ox= 61; oy= 0; break; // コンピュータ名 白
case 6: w= 17; h= 21; ox= 61; oy=21; break; // コンピュータ名 青
case 7: w= 17; h= 21; ox= 61; oy=42; break; // コンピュータ名 赤
case 8: w= 26; h= 23; ox=352; oy=45; break; // "<<" ボタン
case 9: w= 26; h= 23; ox=326; oy=22; break; // ">>" ボタン
case 10: w= 26; h= 23; ox=248; oy=45; break; // "||" ボタン
case 11: w= 26; h= 23; ox=300; oy=45; break; // "|>" ボタン
case 12: w= 26; h= 23; ox=248; oy=22; break; // "×" ボタン
case 13: w= 33; h= 33; ox= 0; oy=68; break; // タイマー
}
if(n<4 && y>165) h=176-y;
if(n<4 && y<99) {h=y-88; y=99; oy+=(11-h);}
gx.clipRect(x,y,w,h);
gx.drawImage(Gif,x-(ox+w*c),y-oy,this);
gx.dispose();
}
public void dsp_c(int c) // ネットワークケーブルの表示
{
int i;
switch(c)
{
case 0: gr.setColor(new Color(102,102,102)); break;
case 1: gr.setColor(new Color(153,102,102)); break;
case 2: gr.setColor(new Color(204, 51, 51)); break;
}
gr.fillRect(0,132,501,11);
for(i=0;i<5;i++) gr.fillRect(i*88+69, 99, 11, 33);
for(i=0;i<6;i++) gr.fillRect(i*88+25,143, 11, 33);
}
public void paint(Graphics g)
{
int i;
for(i=0;i<11;i++)
{
dsp_g(i*44, (i%2==0)?176:39,4,0); // コンピュータの表示
dsp_g(i*44+22,(i%2==0)?185:48,5,i); // 画面の表示
}
for(i=0;i<6;i++) if(Snd[i]>=0) dsp_g(Snd[i]*44+22,(Snd[i]%2==0)?185:48,6,Snd[i]);
for(i=0;i<6;i++) if(Rcv[i]>=0) dsp_g(Rcv[i]*44+22,(Rcv[i]%2==0)?185:48,7,Rcv[i]);
i=0;
if(Busy) i=2;
if(Col) i=1;
dsp_c((Busy)?1:0); // ネットワークケーブルの表示
dsp_g(192,287,8,0); // "<<" ボタンの表示
dsp_g(222,287,(Run)? 10:11,0); // "||" or "|>" ボタンの表示
dsp_g(252,287,12,i); // "×" ボタンの表示
dsp_g(282,287,9,(Wait>16)? 0:2); // ">>" ボタンの表示
}
public boolean dsp_p() // パケットの表示
{
int i,j=0,k=0,x=0,y=0, d=9;
k=(Rcv[0]0)
{
dsp_c((Cd%2==0)?2:1);
Cd--;
if(Cd==0) dsp_c((Dy[0]==99 || Dy[0]==176)?0:1);
}
if(!Busy)
{
k=Rnd.nextInt()%128;
if(k==0 && W0==0 && W1==0)
{
for(i=0;i<11;i++) Used[i]=false;
j=Math.abs(Rnd.nextInt())%11;
while(j==(k=Math.abs(Rnd.nextInt())%11));
Used[j]=true; Used[k]=true;
data_set(k,j);
if(Col)
{
while(Used[(j=Math.abs(Rnd.nextInt())%11)]);
Used[j]=true;
while(Used[(k=Math.abs(Rnd.nextInt())%11)]);
data_set(k,j);
W0=Math.abs(Rnd.nextInt())%128+32;
W1=Math.abs(Rnd.nextInt())%64+32;
Cd=8;
}
}
}
if(Col && W0>0)
{
W0--;
if(W0%21==0) dsp_g(Snd[0]*44+14,(Snd[0]%2==0)?242:0,13,(W0+20)/21); // タイマーの表示
if(W1>0 && (W0+W1)%21==0) dsp_g(Snd[1]*44+14,(Snd[1]%2==0)?242:0,13,(W0+W1+20)/21);
if(W0==0) dsp_c(1);
}
else if(dsp_p()) // 通信の終了
{
stop_c();
if(Tq>0)
{
data_pos(Snd[0]);
dsp_g(Rcv[0]*44+22,(Rcv[0]%2==0)?185:48,7,Rcv[0]); // 端末赤色表示
dsp_g(Snd[0]*44+22,(Snd[0]%2==0)?185:48,6,Snd[0]); // 端末青色表示
}
if(W0==0 && W1>0)
{
W0=W1; W1=0;
}
if(W0==0 && W1==0)
{
Col=false;
dsp_g(252, 287, 12, 0);
}
}
}
try
{
th.sleep((Run)?Wait:128);
}
catch (InterruptedException e){}
}
}
public void stop_c() // 通信終了処理
{
int i;
for(i=0;i<11;i++) dsp_g(i*44+22,(i%2==0)?185:48,5,i); // 画面の白色表示
gr.setColor(new Color(Bgc));
gr.fillRect(Snd[0]*44+14,(Snd[0]%2==0)?242:0,33,33); // タイマーの消去
for(i=0;i<6;i++) {Snd[i]=Snd[i+1]; Rcv[i]=Rcv[i+1];}
Snd[6]=-1; Rcv[6]=-1; Ms=-1; Mr=-1;
dsp_c(0);
Busy=false;
dsp_g(252,287,12,(Col)?1:0); // "×" ボタンの表示
Tq--;
}
public boolean mouseDown(Event e, int mx, int my)
{
int i,j, n=mx/88;
boolean c=false;
if(inside(my,39,99) && (mx-44)%88<61) // 端末をクリック
{
n=(mx-44)/88*2+1;
c=true;
}
if(inside(my,176,237) && mx%88<61) // 端末をクリック
{
n=mx/88*2;
c=true;
}
if(c)
{
if(Ms<0)
{
if(Mr<0)
{
Ms=n;
dsp_g(n*44+22, (n%2==0)?185:48, 6, n); // 端末青色表示
}
}
else if(Mr<0)
{
if(Ms>=0)
{
Mr=n;
if(Busy)
{
Cd=8; Col=true;
W1=Math.abs(Rnd.nextInt())%32+32;
dsp_g(252, 287, 12, 1);
}
data_set(Ms, Mr);
}
}
}
if(inside(my,287,310))
{
if(inside(mx,192,218)) // "<<" ボタン
{
Wait*=2;
dsp_g(192, 287, 8, 1);
dsp_g(282, 287, 9, 0);
}
if(inside(mx,222,248)) // "||" or "|>" ボタン
{
Run=!Run;
dsp_g(222, 287, (Run)? 11:10, 1);
}
if(inside(mx,252,278) && !Busy) // "×" ボタン
{
Col=!Col;
dsp_g(252, 287, 12, (Col)?1:0);
if(!Col) W0=W1=0;
}
if(inside(mx,282,308) && Wait>16) // ">>" ボタン
{
Wait/=2;
dsp_g(282, 287, 9, 1);
}
}
return true;
}
public boolean mouseUp(Event e, int mx, int my)
{
if(inside(my,287,310))
{
if(inside(mx,192,218)) dsp_g(192, 287, 8, 0); // "<<" ボタン
if(inside(mx,222,248)) dsp_g(222, 287, (Run)? 10:11, 0); // "||" or "|>" ボタン
if(inside(mx,282,308)) dsp_g(282, 287, 9, (Wait>16)? 0:2); // ">>" ボタン
}
return true;
}
public void stop()
{
if(th!=null)
{
th.stop();
th=null;
}
}
}
// 戻る