openMSXで、V9990に画像を出力してみる

V9990のエミュレーションが組み込まれたMSXエミュレーター

オープンソースMSXエミュレーターopenMSXには、各種拡張カートリッジのエミュレーターが予め用意されている。その中の、V9990搭載グラフィックカード、GFX9000のエクステンションを有効にすることで、V9990対応ソフトを動かすことができる。

 msx-sdcc@Wikiに簡単な解説とサンプルコードがあったので、ありがたくパク…参考にさせてもらうことにする。


www28.atwiki.jpwww28.atwiki.jp


512x424ドット、32768色モードを使いたい

 ただ、これそのままやっても面白くないので、画面モードを512x424のインターレースモードで高解像度の画像表示に挑戦してみた。なにしろ256x212ではいまどきかなり凸凹して見えてしまうので…

 で、実際画面モードを希望のものにするにはどうしたらいいかとなると、上記サイトの情報だけでは全く足りないので。
MSX Banzai! - The MSX Worshipping Shrine - V9990 Programmers Manual

をチェック。うーん、MSX2 テクニカルハンドブックを思い出す詳しい説明だ。ただ問題は英語だということなのだけど…



 どうやら、V9990の場合は、インターレースモードで2プレーンに分けて描画する必要はなく、普通の縦424ピクセルの画像としてVRAMに上から書き込んでいけばうまいことインターレース表示してくれるらしいので、そのようにする。

 以前の記事で書いた、z88dkを使用し、以下のようなコードを書く。
juangotoh.hatenablog.com

#include <stdio.h>

unsigned char inp(unsigned char addr);
void outp(unsigned char addr, unsigned char data);
void V9990Reg(unsigned char reg, unsigned char data);
void V9990Memadr(unsigned long addr,unsigned char rw);

unsigned char inp(unsigned char addr)
{
    #asm
    
    ld hl,2
    add hl,sp   ;skip return address
    ld c,(hl)   ; c=addr (LSB)
    in a,(c)
    ld h,0
    ld l,a      ; hl = return parameter

    #endasm
}

void outp(unsigned char addr, unsigned char data)
{
    #asm

    ld hl,2
    add hl,sp
    ld a,(hl)   ;a=data
    inc hl
    inc hl
    ld c,(hl)   ;c=addr
    out (c),a

    #endasm

}

void V9990Reg(unsigned char reg, unsigned char data){
	outp(0x64,reg);
	outp(0x63,data);
}

void V9990Memadr(unsigned long addr,unsigned char rw){
	unsigned char hi,mi,lo;

	lo=addr & 0xff;
	mi=(addr >> 8) & 0x3f;
	hi=(addr >> 14) & 0x7;


	if (rw) {
		/* R#3 VRAM READ ADDRESS REGISTER */
		outp(0x64,0x3);
	}else{
		/* R#0 VRAM WRITE ADDRESS REGISTER */
		outp(0x64,0x0);
	}

	/* SET ADDRESS */
	outp(0x63,lo);
	outp(0x63,mi);
	outp(0x63,hi);

}

void main(void){
	long i;
    unsigned char col[3];
    FILE *fp;
    int c;
    int cIndex=0;


	
    // R#6 SCREEN MODE 512x424 16bit/pixel
    V9990Reg(0x6,0x97);

    // R#7 ENABLE INTERLACE
	V9990Reg(0x7,0x85);

	// R#8 ENABLE SCREEN
	V9990Reg(0x8,0x82);

	// SET VRAM ADDRESS(r=0,w=1) 
	V9990Memadr(0x0,1);
    if ((fp = fopen("A004.RAW", "rb")) == NULL ) {
		//puts("file not found\n");
		return 1;
	}
    fseek(fp,0,SEEK_SET);
    while((c=fgetc(fp)) !=EOF){
        unsigned char d1,d2,tmp;
        if (feof(fp)) break;
        col[cIndex]=c;
        cIndex++;
        if (cIndex >2){
            // col[0]=R col[1]=G col[2]=B
            cIndex =0;
            d2 = (col[1] >>1) & 0x7c;
            tmp=col[0] >>6;
            d2 |= tmp;
            d1 = ((col[0] <<2) & 0xE0) | (col[2] >>3);
            
            outp(0x60,d1);
            outp(0x60,d2);
            
        }

    }
    fclose(fp);

}

これをMSXDOS用にコンパイルし、できたコマンドと同じディレクトリに"A004.RAW"という画像ファイルを置く。
 これはあらかじめPhotoshopで512x424ピクセルにした、RGB各8bit、つまり24bitカラーのRAW画像だ。RAW画像というのは、ひたすらピクセルデータが左上から右下まで隙間なく並んだ、全く圧縮されておらず、一切メタデータを含まない画像で、普通こんなものを使う用途はあまりない。なにしろ画像ファイルに縦横のドット数とかRGBの並び順とかの、表示に必要な情報が一切含まれていない。ただ、予め必要な情報を自分が持っているなら、プログラムから読み出すのに一番簡単なフォーマットである。
V9990の16bitカラーモードは、1ピクセルに2バイト使用し、RGB各5bitとなっており、その並びは
0GGGGGRR RRRBBBBB
となっている。リトルエンディアンで格納されるので、RRRBBBBBの方を先に書き込む必要がある。もとのRAW画像は、
RRRRRRRR GGGGGGGG BBBBBBBB
の順で並んでいるので、3バイト読み込んでは、下位3ビットをクリアし、左右にずらした上で合成し、2バイトにまとめなないといけないのでちょっとだけめんどい。

結果

 実行してみると、まあ呆れるほど遅い。そりゃ1バイトずつ愚直に読み込んでは表示してるんだから遅いわなあ。結果が以下の画像。
f:id:juangotoh:20170716180720j:plain

あー、縦方向の解像度全く出てない。もちろん1/60秒ごとにチラチラ切り替わる画面をスクリーンショットでうまく取り込めないという問題はあるのだけど、これ実際見てるとわかるのだけど、openMSXのインターレースモードって、エミュレーターの画面上で全く同じ位置に奇数ラインと偶数ラインが描かれてて、それを切り換え表示してる感じなんだよね。本来テレビのインターレースモードは、走査線の奇数偶数で上下にずれて隙間を埋めてるから、それで解像度上がるのだけど、同じ位置で混ざって表示されるんじゃインターレース使う意味がない。実機とエミュレーターの違いが出てしまった感じかあ。

 まあとにかく、32,768色、横512ドットモードの画面のサンプルということで。

余談

 V9990、640x400とか、640x480とかの画面モードがあるのだけど、これらのモードだと最大16色しか出ないんだよね。時代的にMS-DOSで動くPC-9801シリーズのアプリが移植できればOK的なモードだったのかなあ。

Kiwi:68008+V9990+SID音源×2という「あの頃ほしかった系」コンピューター

f:id:juangotoh:20170709105210j:plain

www.ist-schlau.de

 

 以前たまたま見つけたドイツのサイトだが、自作コンピューターの説明と販売を行っている。販売ページを見ると、基板と部品のセットで€333.33。ただし追加部品がいくつか必要になる。基板には表面実装LSIのみ実装済みで、他のものはすべて自分ではんだ付けする必要があり、まあそれなりに覚悟がいるキットだ。このコンピューター、なんとも「あー、昔こういう仕様のパソコンがあったらよかったなあ」的なスペックなのである。

 

CPUが68008

 モトローラの16ビットCPU、68000の8ビットバス版。これはできたら8ビットバスバージョンじゃなく、完全な68000であってほしいところだけど、自作となるとこの辺が妥当なところか。とにかくm68kアーキテクチャである。フラットな4MBメモリマップが使える。ホビーパソコンとしてこれはうれしい。

 

VDPがV9990

 あの、MSX3用に開発されたV9990 VDPである。開発の遅れから、実際には採用されず。これが使われたパソコンは存在しない。なのでカーナビとかパチンコ用に使われたらしい。VGA解像度で家庭用テレビに出力でき、32768色発色。MSX2+やturboRのV9958より格段に高速。

 

音源がSID×2

 コモドール64で使用されたSID音源を二個搭載。欧米のチップチューンでいまだ人気の音源チップである。まあC64が流行らなかった日本から見ると、ヤマハFM音源チップとかの方がうれしいけど。

各種インターフェース

 RS232C、パラレルポート、PS/2キーボード及びマウス端子、ATARI方式のジョイスティックポート、IDE/ATA ハードディスク&フロッピーインターフェースを装備。EPROMにIDEからのブートローダを格納している。グラフィックを扱えるBASICも用意しているようだ。

 

雑感

 MSX好きにとっては、V9990搭載というのがすごい魅力的だ。RAM 4MBは現代のパソコンから考えると少ないが、Macintosh Plusの最大メモリが4MBだったことを考えると十分である。適切な開発環境を整えることができれば結構使えると思う。ちなみにVRAM512KBはメインメモリとは別に確保されている。

 €333.33という価格は、おそらくApple Iの$666.66を意識していると思われる。ギャラリーページを見ると、この作者、スティーブ・ウォズニアックに会いに行ってるようだ。

 基板と部品のセットには、メモリとSIDチップが含まれておらず、これは別売りになっているが、SIDに関してはSIDのICパッケージサイズのボードにマイコンチップを乗せたエミュレーションボードであるNano SwinSIDがラインナップされている。C64の音源であるSIDは部品単体で入手が難しいこともあってこういう代替品が作られているようだ。

 

デモ動画

www.youtube.com

有名なAmigaのデモを移植したもの。

 

www.youtube.com

2Dアクションゲーム。

パソコンにおける80系 VS 68系の時代

f:id:juangotoh:20170705181958j:plain

 1974年に、Intelの8080とモトローラの6800という8ビットCPUが登場した。8080が、電卓用4ビットCPU 、4004から8008を経て進化したのに対し、6800はミニコンアーキテクチャ(DEC PDP-11をモデルにしたといわれている)を縮小して設計されたらしい。つまり8080は電卓が進化したCPU。6800はミニコンが退化したCPUといえる。Intel 8080とその後継アーキテクチャを80系、モトローラ6800とその後継アーキテクチャを68系と呼び、これらが戦いを繰り広げた時代があった。

 特徴として、8080はレジスタが多めで、数値をいくつも代入してちゃっちゃと計算するのに向いていた。それに対し6800は直行性の高い命令で、一貫性の高いプログラムを作成するのに向いていた。誤解を恐れずいうなら、8080はとにかく実用性重視。6800は理念重視といえるのではないだろうか。高度な電卓VS簡易化されたコンピューターだったのだ。この場合、すでにミニコンや大型コンピューターを使っていた技術者からは、よく似たアーキテクチャの6800は評判が高かったはずだが、インテルはいちはやく評価ボードやCPUを安価に配布し、初期の段階でわりとシェアを取ってしまう。マイコンの歴史に残るAltair8800など、当時インテルが市販していたCPU単体の価格と変わらない値段で筐体とマザーボード込みのコンピューターセットを販売できた。これはIntelがこういう企業に対し、極めて格安でCPUを卸していたからに他ならない。

 ここで、80 VS 68の第一ラウンドは80の勝利に終わるのだが、ここで成功したのはIntelではなかった。IntelからスピンアウトしたZilogが、Z80という、8080互換で、さらに便利な命令や裏レジスタを完備たCPUを発売。横から商売をかっさらっていく。
 日本では、日立Basic Masterが6800を採用。シャープ MZ-80と、NEC PC-8001Z80を採用していた。その後、モトローラは6800を大幅に改良した6809を発売する。6809は究極の8ビットCPUと呼ばれ、日立のほか、富士通が採用して一定の支持を得る。しかしこれは6800との互換性がなかったし、登場時期も遅すぎた。「究極の8ビット」というのは、要するに「8ビット時代の最後を飾る」という意味になってしまう。

 なお、日本でパソコンへの採用例はほぼないのだが、米国では6502がかなりのシェアを得た。これはモトローラからスピンアウトしたモステクノロジーが開発したCPUで、6800をさらに簡易化したような製品だ。プログラムカウンタ以外のレジスタがすべて8ビットであり、命令数も少ないが、その分高速で動作した。つまりプログラムはより複雑になる。のちのRISCにちょっと似ている。モステクノロジーはこのCPUをすげえ安く市販した。8080が3万円位した時代に2000円位で売り出したらしい。これに注目したのがスティーブ・ウォズニアックで、彼が作ったのがApple I。後継のApple IIも6502を使っていたので、アメリカを席巻したパソコンが6502を採用したということになる。コモドール社もPET-2001でこの6502を採用し、のちのコモドール64でも使われた。英国でもエイコーン社がBBC Microに6502を採用。世界的に安価なパソコンは6502という流れがあった。なぜか日本ではパソコンにおける採用例がない。これは日本で初期にパソコンを製造したのが半導体メーカーばかりで、これらがモトローラインテルザイログと提携して自社で互換チップを製造していたこともあるのだろう。初期の日本のパソコンは基本自社製のCPUを搭載していたはず。製造ライセンスを買った後の製造原価で考えるならどれも大差なく、ならば高機能なZ80や6809となったのではないか。
 それに対して米国などでパソコン市場を立ち上げたのは、自社に半導体工場なんか持たない新興企業だった。大量に外部から購入する部品として、安価な6502は魅力的だったと思われる。
 6502を68系に含めるのなら、案外日本以外ではいい勝負をしていたかもしれない。日本においては、ファミコンが6502に機能を追加したカスタムCPUを採用し、その後PCエンジンスーパーファミコン(16ビット化された65816のカスタム)などに採用された。セガのSC-1000などがZ80を採用していたのに勝ったので、ゲーム機市場では80系の負けといえたかも。


 16ビットでは、Intelが8086、モトローラが68000を出した。8086はこれまた8080を大きく拡張したアーキテクチャで、機械語に互換性はなかったものの、再アセンブルすれば今までのプログラムがそのまま動くようにできていた。そういう設計のため、16ビットCPUとしてはメモリが64kB単位で区切られたり、非常にせせこましくなっていた。それに対して68000は、リニアな16MBメモリマップを実現し、たくさん装備された汎用レジスタは32ビットで自由自在に使えるなど、どう考えても68000の勝ちだろってな仕上がりだった。しかし、6800や6809との互換性とかは特に考えられていなかった。この時代、IBM-PCが8086の8ビットバス版の8088を採用し、AppleのLisa、Macintosh。アタリのST。コモドールのAmigaが68000を採用した。後者はどれもビットマップディスプレイを効率的に扱う必要上、68000の方が率直にOSやアプリケーションを書くことができる利点があった。しかし、IBM-PCやその互換機が主流となり、ここでも68系は敗退する。
なお、8ビットパソコン市場でIntelのパイを奪ったザイログは、16ビットのZ8000が思ったより速くならず、エラーも出たりして16ビットパソコン市場ではさっぱり採用例がなかった。アーケードゲームとかでいくつか採用されたようだけど。

アタリやコモドールがドロップアウトして、唯一の68系陣営となったアップルは、IBMPowerPCを採用し、これにモトローラを巻き込む。PowerPCの時代を68系と言っていいのかどうか、全然アーキテクチャ違うし難しいところだけど、最終的にモトローラのCPU採用をやめたIntel Mac登場の2006年を持って、1974年から続いたパソコン市場の80系 VS 68系の戦いは幕を閉じたと考えていいのだろう。

Win2Dを使って2Dゲームを作る場合のメモ的な何か

 別にゲーム作る予定があるわけではないのだけど、ちょっと興味を持ったので調べてみた。Win2Dには、SpriteBatchという、昔のゲーム機やホビーパソコンで使われた「スプライト」に似た機能がある。まあこれ自体はDirect3DやDirect2Dに以前からあって、XNAなどでも便利に使われてたものだけど、UWPアプリ用のDirect2DライブラリであるWin2Dの発表時には含まれておらず、あとからサポートされた。なので、SpriteBatch関連のAPIは、Windows10 November update以降でしか使えないとなっている。

 Win2Dが描画を行うコントロールは、主にCanvasControlと、CanvasAnimatedControlだ。後者は前者にアニメーションのための機能を付けえくわえたものと考えていい。具体的には、一定間隔(デフォルトでは1/60秒間隔)で画面の更新が強制的に行われるようになっており、そのためのイベントハンドラが使える。ここにキャラクターの移動などの処理を描けば、無理なくアクションやシューティングゲームのためのゲームループが作成できるわけだ。というわけで、とりあえずXAML

xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"

と書いてから、Gridの下に

<canvas:CanvasAnimatedControl x:Name ="canvas" Margin="10" Update="canvas_Update" Draw="CanvasControl_Draw" CreateResources="OnCreateResources"  ClearColor="Black"/>

などのように書いて、CanvasAnimatedControlを作成する。CreateResourcesはリソース作成時に呼ばれるので、スプライト用の画像データを読み込むなどするために登録したほうがいい。Updateは1/60秒ごとに呼び出されるアップデートイベントで、これが呼ばれた直後にDrawメソッドも呼び出されるので、Invaridate()とか呼んで無理やり描画イベントを起こす必要もない。

 CanvasのDrawメソッドが呼び出されるとき、引数に

Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedDrawEventArgs args

が入るので、

CanvasSpriteBatch  batch = args.DrawingSession.CreateSpriteBatch();

としてSpriteBatchを作成する。これがなにかというと、Canvasに乗ったレイヤーのようなものだ。スプライトと言っても、ビットマップのキャラクターを登録したら、あとは座標を指定するだけで動き回ってくれるようなものではなく、毎回更新のたびに全スプライトをこのSpriteBatchの上に書き込む必要がある。CanvasSpriteBatchクラスのDrawメソッドを使うのだが、これはあらかじめ用意したキャラクター単一のビットマップ、もしくは歩きパターンなどを複数並べた大きなビットマップ(SpriteSheet)の任意の矩形領域からSpriteBatchに転送することになる。単一ビットマップを使う場合は、CanvasBitmap.Draw()メソッド、SpriteSheetを使う場合はCanvasBitmap.DrawFromSpriteSheet()メソッドを使う。どちらも用途に応じて多くのオーバーロード関数が用意されている。「Draw」となってるから、この時点で画面に表示されそうな気がするが、これはあくまでオフスクリーンで画面を作っている段階で、実際のCanvasへの描画は

batch.Dispose();

で行われる。「え?」と思うでしょ。実際ドキュメントには
Finalizes the sprite batch and submits it to the CanvasDrawingSession.
と書いてあるのでこの理解で正しいはず。まあ、シューティングゲームとかで考えても、敵が数十機出たり、弾幕とで数百個のビットマップをSpriteBatchに書き込むことになる場合もあるのだろうけど、おそらくそのへんうまいことやってくれてあんまし遅くならないんじゃないかな。なんせDirectX系だし(甘いか?)

 それにしてもWin2D、日本語での解説がなかなか見つからないうえに、本家のドキュメントもあまりにシンプルでいろいろ試してみないとわからない。引数の説明がほぼなかったり、まあDirect2Dのドキュメントの該当部分読めってことなんだろうけど…


 とりあえず黒背景で自機を動かしてショットを打つところまでは作ってみた。SEやBGMはネットで拾ってきたフリー素材。

 なお、自機の画像は背景透過のアルファ付きPNGで用意した。2コマしかないが、一応これがSpriteSheetということになる。
f:id:juangotoh:20170619065431p:plain

Win2DでUWPアプリに日本語縦書き

MicrosoftがGititHubで公開しているWin2Dというライブラリ、Direct2DをUWPのCanvasで簡単に使えるようにしたものらしい。ちょっと試してみた。

' 空白ページのアイテム テンプレートについては、http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 を参照してください
Imports Windows.UI
Imports Microsoft.Graphics.Canvas.UI.Xaml
Imports Microsoft.Graphics.Canvas.Text


''' <summary>
''' それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。
''' </summary>
Public NotInheritable Class MainPage
    Inherits Page
    Sub CanvasControl_Draw(sender As CanvasControl, args As CanvasDrawEventArgs)
        Dim textFormat = New CanvasTextFormat()
        Dim s As String = "こんにちは、" + vbCrLf + "私は後藤寿庵です。" + vbCrLf + "This is a pen."
        textFormat.FontSize = 24
        textFormat.Direction = CanvasTextDirection.TopToBottomThenRightToLeft   '縦書きを指定
        textFormat.VerticalGlyphOrientation = CanvasVerticalGlyphOrientation.Stacked '英字グリフを正立に
        args.DrawingSession.DrawText(s, 100, 100, Colors.Black, textFormat)
        textFormat.VerticalGlyphOrientation = CanvasVerticalGlyphOrientation.Default '英字グリフをデフォルトに
        args.DrawingSession.DrawText(s, 250, 100, Colors.Black, textFormat)
        textFormat.Direction = CanvasTextDirection.LeftToRightThenTopToBottom   '横書きを指定
        args.DrawingSession.DrawText(s, 270, 100, Colors.Black, textFormat)
    End Sub
End Class

なぜVBなのかといえば、慣れてるから。まあこの程度のコードならそのままC#に置き換えるのも難しくないだろう。
短いので説明の必要もないと思うが、何をやってるかといえば、CanvasTextFormatという、テキストの属性とかを定義するオブジェクトを作り、そこに行方向(CanvasTextDirection)とか、縦書き時のグリフの向き(CanvasVerticalGlyphOrientation これは漢字などのグリフではどちらでも変わらず、英数字の表示に影響する)を設定し、適当な座標にDrawingSession.DrawText()で描画しているだけ。フォントファミリーやサイズ、ウェイトなんかもCanvasTextFormatのプロパティとして簡単に設定できる。
結果:
f:id:juangotoh:20170613190819p:plain
確かに簡単だ。まあ、縦中横とかルビとかを実現しようと思ったらこれじゃ駄目なので、DrawText()じゃなくてDrawTextLayout()を使い、InlineObjectを定義するとかなんとかする必要は出てくると思うけど。

Direct2Dについての記事なのに、地味なテキストを表示するだけって…

アニメ「正解するカド」の、CGと手描きと歴史

f:id:juangotoh:20170608185050p:plain

 「正解するカド」では、主要キャラクターは3DCGだが、登場頻度の低いキャラは手描き作画である。これ、頑張ってコスト計算してるんだろうなあ。人物の3Dモデルを制作するのはそれなりに手間と時間がかかるが、できてしまえばモデルの配置とモーション付けは手描きより早くできてコストを抑えられるだろう。これは同じモデルを使用する時間が長いほど安くなるはずだ。それに対し手描きの場合登場するたびにすべての動きを描かなければいけないので、コストがかかる。だたし、モデリングにかかる費用と時間を考えると、登場頻度の低い人物に関しては手描きのほうが安上がりになるだろう。

 

 1990年代末あたりから、アニメにCGが使用され始めたが、当初は宇宙船のような、ディティールが多く、基本的に変形せず、方向転換や移動というシンプルで描くのは大変だけどCGなら如実に楽で効果的になる部分に限られていた。人間のモーション付けみたいな作業がそれなりにこなれてきたあとも、しばらくは手描きでは大変な、巨大ロボットなどを中心に使われていた。2007年の「デュエル・マスターズ ゼロ」などで、人物もCGになったが、トゥーンレンダリングがまだ不気味で、顎を上げたシーンなどで違和感が強かった。このへんは幼児向けのシンプルなキャラクターであることもCG化に向いていたのだろう。

 2000年代には、劇場作品などでフルCG作品がいくつも登場するが、この頃はおそらくTVに比べて予算をかけられる劇場映画だからこそフルCGができたのだろう。まだCGはカネがかかったわけだ。

 

 2010年代に入ると、TVでフルCG作品がそれなりに多くなってくる。「シドニアの騎士」あたりになると、CGキャラの不気味さもだいぶ緩和されてくる。ポリゴン・ピクチュアズや、サンジゲンといった、2Dアニメの中のCGパートを制作していた会社が作品元請けとなって制作されるので、その過程でためたノウハウが活かされているのだろう。

 

 「正解するカド」は東映アニメーション初のフルCGによるTVシリーズと言われている。最初に書いたように一部のキャラクターは手描きなので、完全なフルCGではないが、ほとんどCGではある。手描きアニメの老舗である東映アニメーションが、ここでCGアニメに本格的に取り組み始めたわけで、将来日本製アニメの中心がCGになる分岐点となるのかもしれない。東映アニメーションよ、どうか正解されたし。

19世紀物理学のエーテルとは

 19世紀、ニュートン力学が物体の運動を過不足なく記述し、電磁気学マクスウェル方程式が過不足なく記述していた。物理学は「もうすぐ完成する学問」と思われていたのだ。この時代、光が波動であるというのは常識で、波動であるなら波を伝える媒質が存在するはずであると思われていた。水面に石を落とせば円形に波が広がるし、音は空気中を伝わる波動である。光もそれを伝える物質があるだろうと、当然思われ、それはエーテルと呼ばれていた。

 

 一般的に、波動を伝える媒質の性質は、波の周波数や伝搬速度が大きいなら、高密度で固体に近い性質を持たなければいけない。当時すでに光の速度の検証は行われており、秒速30万kmという、すごい速さで空間を伝わることがあきらかだった。そうすると、光を伝えるエーテルは鋼鉄より硬い物質でなければいけなかった。また、光が宇宙、空気中、水中、ガラスも関係なく伝わることから、あらゆる物質の中に「染み込む」非常に細かくどこにでもある物質でなければいけなかった。考えてほしい。宇宙のどこにも染み込んで存在し、鉄より硬い物質である。そんなものがあったら、惑星の公転運動もなにんもかも阻害されて停止してしまうだろう。なので、エーテルは光速に近い速度でだけ非常に硬くなるが、ゆっくり動く物質にとっては真空と同じくらい抵抗がないと定義される。かなり無理のある設定である。だが、当時は当然それが存在すると思われていたのだ。

 

 エーテルは宇宙に静止状態で存在し、その中を恒星や惑星が移動すると考えられた。したがって、エーテルに向かっていくときと、エーテルから遠ざかるときで、光の速度が変わるはずと思われた、地球が公転していることは知られていたので、その進む方向と、それと90度ずれた方向で光の速度を測れば、エーテルに対する地球の速度が測定できる。これをやったのがマイケルソンとモーリーで、結果はどの方向にも光速度は一定だった。方向にかかわらず光速度が一定というのは、異様な話である。新幹線が時速300kmで走ってるとき、駅で立ってる人が測っても、線路に並走してスポーツカーで時速200kmで走ってる人が測ってもどっちも時速300kmだというようなものだ。これをなんとかしようと頑張ったのがローレンツで、彼は高速移動すると距離が縮むとしたのだが、最終的にはアインシュタインが「いや、時間が縮むんだよ」と反則技を繰り出した。光の波を伝える媒質は、エーテルではなく「電磁場」という新しい概念になり、光を伝搬する媒質で、鋼鉄より硬いエーテルというものが不要になったのだ。  

 

 アインシュタイン特殊相対性理論によって、エーテルは追放されたのだが、20世紀初頭のSFではまだ生きていた。あらゆる物質に染み込んで光を伝えるエーテル。ならば、エーテルに染み込むさらに細かく高硬度の物質があればどうなるか。超光速の情報や超光速移動をつかさどる「サブエーテル」である。物理学会で「サブエーテル」という概念が話題に上ったことはないと思う。これはSFがSFならではのセンスオブワンダーを生み出した運動であった。サブエーテルを含めたエーテル宇宙論は、レンズマンなど、20世紀前半のSFで使われ、スペースオペラの衰退とともに忘れられていったが、1980年代末、スタジオガイナックスの「トップをねらえ」で復権する。あれはエーテル風に宇宙船が流される様を描いた超エーテル宇宙論の世界である。