#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(くん)と一緒に「めぞん一刻
完結編」を見にいったのだが,非常におしりが痛かった。
姫乃樹リカもいいなあ,でも麻田華子はちとパス。
私はいったい誰でしょう。