#11 Article 1187 Posted at 1988/03/04 02:45:14 by のりPー (MAP629) [INF.NL3]

Subject: NL3フォーマット解説(プログラミング用)

***  NLOADER3の  データーフォーマット  ***

  自分の機械にNLOADER3を移植してみようと思う方には参考にな
ると思います。これを読んでマイナー機種の人もあきらめずに,みなさん
の素晴らしい絵を見るよう,努力してみて下さい。
  このファイル制作にあたり,このFORMATの作者NOZOMUさん
の了解や助言など一切受けてませんが,おゆるし下さい。
なお,NOZOMUさんのX68K用BASICのNLOADER3を参
考にアルゴリズムを調べさせていただきました。

**NL3の概念**
  御覧の通り無手順通信によりカラー画像をやりとりしようというもので
す。画面を160*100分割し,その1ドット毎の色番号を送受信し,
640*200ドット8色フルカラー以上の機種に対しデーター的に互換
を持たせてもいます。それ以下の機種にでも多少の条件をつけながら,む
りに展開することも可能と思われます。基本的にはアニメを主とするもの
のため,その類を送受信するにはかなりすぐれていると思います。
  640*200の画面を160*100に分割すると,1ピクセルは4
*2ドットで表現されます。その8ビットのうちRGBについて何ビット
を発光するかにより色が決定します。R,G,Bはそれぞれ,0~8の9
段階の濃度を持つことができ,その組合わせにより最大9^3=729色
が表現できるのです。1ピクセルを1バイトで表現させる為,データーの
効率などを考えた結果1枚の絵について64色使用可能ということなにっ
ています。(全色使うとデーター量は2倍弱となりますので。)

**圧縮**
  データーを1ピクセルを1バイトで表現すると約16Kバイトのデータ
ーになります。そこで,基本的には1:1で取り込み,同じ色番号が並ん
だ部分に対しては,「色番号+そのバイト数」という2バイトに置きかえ
ることにより,簡単な圧縮を行なっています。手描きの絵は同じ色でベタ
塗りすることが多く,こういった絵に対しては,かなりの圧縮効率を示し
ます。

**データー構成**
  データーは2つの部分に分かれます。
  1つは,頭から128バイトで,色番号0~63に対する実際の色が格
納されています。1色は2バイトでR,G,B各プレーンの混入濃度0~
8が2バイトの中に納められています。R,G,B:0~8として,
データーは,「D=R*81+G*9+B」により,なりたちます。
ただし,このデーターは後に示す通信用データーにコンバートされます。
  もう1つは,画像のデーターとなります。128バイトの色データーの
すぐ次のからが,それに当たります。画像のストック順序ですが,160
*100にて,(0,0)より,上から下に走査します。1ライン終わる
と1つ右の列に移ります。(X,Y)で考えるとX方向ループの中にY方
向ループがあるようになっています。結果的に1本の長い16000個の
点として,扱かいます。
  データーの始りと終りには何の印もないので,目で見てどこから始まる
のか確認してデーターだけ抽出します。
  データーはASCIIコード256バイトのうち以下のコードを使用し
ています。

  $20~$7E,$A0~$DF,$FE~$FF

これ以外のコード

  $00~$1F,$7F,$80~$AF,$E0~$FD

は,使用しません。コントロールコードは,含まれている場合削除します
。(CR,LF,etc.)
$7Fは,以前は使用していたのですが,$7FをDELコードとみなし
,ダウンロード不可能な機種がある為,V1.1より使用を禁止し,以後
このままのバージョンが継続されています。
実際にUPLOADされているデーターは300番以後のものは全部V1
.1です。

**サンプルリスト(無気味な言語)**
main()
  {
  int  R[63],G[63],B[63]  各色番号に対応した色をテーブルにします

  open("I",#1,"DATA")

  for I=0 to 63
    D=read()+read()*128
    R=int(D/81)
    G=int(D-R*81)/9)
    B=D-D*81-G*9
  next

  X=0
  while X<160
    Y=0
      C=READ()
      if (C and $40) then  {
                           C=C and not($40)
                           L=READ()+2
                           }
                     else  L=1
      for I=1 to L
        TILE(X,Y,C)
        Y=Y+1 if Y=100 then Y=0 X=X+1
      next
  wend
  close(#1)
  }

READ();      (*** V1.0 ***)
  D=0
  while D<$20
    D=input$(1,#1)
  wend
  D=D-$20
  if D>=$80 then D=D-$20
  return(D)

READ();      (*** V1.1 ***)
  D=0
  while D<$20
    D=INPUT$(1,#1)
  wend
  D=D-$20
  if D>=$7f then D=D-$21
  if D>=$bf then D=D-$20
  return(D)

TILE(X,Y,C);
  160*100の(X,Y)座標に対しドットを書くルーチンです。
  各プレーンには,R[C],G[C],B[C]  の数のドットが打たれます。
  例えば,R[C]が7ならば,そこの座標のRプレーンには全ビットの
  7/8個のドットを書きます。この場合640*200の機種では7個
  で,640*400の機種では14個となります。
  return


  640*200を例にドットパターンの一例を示します。
数さえあっていれば,一応表示はされます。
僕は次のパターンを使用しています。

濃度      0    1    2    3    4    5    6    7    8
データー 00  80  82  86  A6  B6  BE  FE  FF

むりやりBASICで作るとすれば,次のようなものも考えられないこと
はありません。速度は保証しかねます。

*TILE(X,Y,C)
FOR RGB=0 TO 2
FOR XX=0 TO 3
FOR YY=0 TO 1
PSET(X*4+XX,Y*2+YY),-( 2^RGB)*(2^(7-(XX+YY*4)) AND BIT[-R[C]*(RGB=
0)-G[C]*(RGB=1)-B[C]*(RGB=2)] )
NEXT
NEXT
NEXT
RETURN

ただし″BIT[0]~BIT[8]″には,それぞれ対応ビットデータ
ーが入いっているとします。
TILEって関数だけはマシン語で作るのが最も楽そうです。
それだけである程度の速度さえ維持できると思います。

では,これを参考にマイナー機種の方も展開ルーチンを作成して(もらっ
て)一刻も早くNL3の素晴らしさを体験しましょう。

このファイルに間違いがありましたら,MAILにてお報せ下さい。
速急に対応したいと思います。ただし,アクセスが3日に1回程度なので
,どのくらい対応できるか分かりませんが。

            やっぱり酒井法子はいいなあの,  MAP629  のりPー

(アニメより,アイドルがぁぁ    ぃぃ...)

それでも,先日ただ券にて,TAKAKO(くん)と一緒に「めぞん一刻
完結編」を見にいったのだが,非常におしりが痛かった。
姫乃樹リカもいいなあ,でも麻田華子はちとパス。

私はいったい誰でしょう。