mieki256's diary



2018/11/01(木) [n年前の日記]

#1 [nitijyou] 某所に行ってきた

複合機のスキャナがどのPCからも利用できないという相談があったので自転車で。09:40-12:00,13:00-13:20まで作業。

#2 [pc] 親父さん用PCがまた不調

先日、親父さん用PC内部の掃除をしたけれど、今日も Windows10 x64 が何かの拍子に固まったとのことで。何が原因なのだろう…。

Memtest86+ を走らせてみたけど、一周はする…。さっぱり分からん…。

_AMD A8-Series A8-3850 - AD3850WNZ43GX / AD3850WNGXBOX

AMD A8-3850の場合、温度の上限は 72.7度か…。

2018/11/02(金) [n年前の日記]

#1 [tic80] Raspberry Pi Zero W 上で TIC-80 をビルドしようとしたけれど

Raspberry Pi Zero W + Raspbian stretch 上で TIC-80 が動くかどうかが気になったので、TIC-80 をビルドしようとしたのだけれど、なかなかちょっと厳しい感じに。

_Build instructions - nesbox/TIC-80 Wiki に、Raspberry Pi でビルドする例が書いてあったのだけど…。試してみたら、Github から git clone してきたソース群の中に build.sh は無くて。

_Compilation on Raspberry Pi B+ fails on LTO - Issue #389 - nesbox/TIC-80 に従って、make linux と打てばビルドできるのかなと思ったけれど、Makefile なんて無いよと言われ。 _#tic80 moved to use CMake here are updated build instructions によると、cmake に移行したということなのかな…。

_nesbox/TIC-80: TIC-80 is a fantasy computer for making, playing and sharing tiny games. を参考に、cmake . と打ってみたら、cmake 3.9 以上が必要だと言われてしまった。Raspbian stretch 上で、sudo apt install cmake でインストールできるのは、cmake 3.7.2。つまり cmake のバージョンが古いので、このままでは Raspbian 上で TIC-80 をビルドできない模様。

cmake は、以下の操作でビルドできるのだろうか…。

_OSDevLab: How to install latest Cmake for Raspberry Pi

_Download | CMake から、cmake-3.12.3.tar.gz をDLして、ビルドを試みた。
wget https://cmake.org/files/v3.12/cmake-3.12.3.tar.gz
tar zxvf cmake-3.12.3.tar.gz
cd cmake-3.12.3
sudo ./bootstrap
sudo make
コンパイルが始まったけど、Raspberry Pi Zero W 上では、かなりの時間がかかるようで…。5〜6時間ぐらい処理させてるけど、終わりが見えない。

TIC-80 の過去バージョンを眺めたら、どうやら 0.70.6 までは make を使ってたらしい。github上の最新版ではなく、0.70.6 をDLしてビルドすればよかったのかな…。

#2 [pc] 親父さん用PCの調子がまだおかしい

朝方、2回ほどPCが固まったと、親父さんからの報告が。

安定動作しないのでは話にならないので、BIOSから設定を弄って、CPUクロックとメモリクロックを落として様子を見てみることにした。CPU AMD A8-3850 は、2.9GHz → 2.5GHz に。メモリクロックは、1600 → 1333 に。内蔵GPUのクロックも、600MHz → 500MHz に。

Windows起動後、HWiNFO で温度センサの値を眺めてみたけど、CPU温度は以前より10度近く下がった感じ。ただ、M/B上の FCH なるものが98度ぐらいになってる点が気になってきた。FCHって何だ。ググってみたけど、もしかして Fusion controller hubs のことか。つまりチップセットが高温になってるということかな。

もしかして、チップセットについてるヒートシンクが冷却に貢献できてないのだろうか。熱伝導シートが黒焦げ状態なのかな…。ヒートシンクを外して、掃除して、熱伝導グリスを塗り直すべき、なのだろうか…。

2018/11/03() [n年前の日記]

#1 [tic80] Raspberry Pi Zero W上でTIC-80を動かしてみたけれど

Raspberry Pi Zero W + Raspbian stretch 上で、TIC-80 を動かそうと試みたり。

今現在 github にある TIC-80 の版は、ビルドするのに cmake 3.9 以上が必要だけど、Raspberry Pi Zero W 上で cmake をビルドするのに時間がかかり過ぎるので…。make を使ってビルドする、TIC-80 0.70.6 をダウンロードしてビルドすることにした。

ビルド手順のメモ。 :

以下を参考にして作業。

_Build instructions - nesbox/TIC-80 Wiki
_Compilation on Raspberry Pi B+ fails on LTO - Issue #389 - nesbox/TIC-80
_Installation de TIC-80 - Framboise Pi

端末を開いて、以下を打ち込んでいった。

sudo apt-get update
sudo apt-get dist-upgrade
sudo apt-get install git build-essential libgtk-3-dev libsdl2-dev zlib1g-dev
sudo apt-get install libgif-dev
sudo apt-get install liblua5.3-dev

git clone --recursive --branch v0.70.6 https://github.com/nesbox/TIC-80
cd TIC-80
./build.sh

git に、「--branch v0.70.6」を指定することで、v0.70.6 とタグがつけられてる版を github からダウンロードできる。

./build.sh を実行すると、「どの版を作りたいのだ?」と尋ねてきたので、2番の linux を選択。

数時間ビルドして、途中でエラーが出てきた。以下を参考にして、Makefile を修正。

_Installation de TIC-80 - Framboise Pi

vi Makefile
 LINUX_LIBS= \
        -L/opt/vc/lib \
        $(GTK_LIBS) \
 LINUX_LINKER_FLAGS= \
        -lbcm_host \
        -llua \
  • LINUX_LIBS に、-L/opt/vc/lib \ を挿入。
  • LINUX_LINKER_FLAGS に、-lbcm_host \ を挿入。
再度、./build.sh を実行。ビルドが終わると、「どの版を作りたいのだ?」と尋ねてくるので、9 を入力して exit。

bin/ 以下に、tic80 という実行ファイルができているので、パスの通っているところにコピー。自分の場合は、~/bin/ にパスを通してあるので、
cp bin/tic80 ~/bin
だったかな…。

動作確認。 :

Raspberry Pi Zero W + Raspbian stretch、かつ、GL Driver を無効にしてある状態で、端末から tic80 を実行してみた。

初期化処理っぽいオレンジ色の線が画面に出てくるまで、数分かかった…。しかも、入力待ちの画面になってくれない…。

おそらくだけど、TIC-80 は、画面描画が60FPSで更新できることを前提にして起動時の処理を書いていて…。しかしこの場合、画面更新が1〜2秒で1回更新、みたいな速度だから、ひたすら待たされるのではないか。

仕方ないのでウインドウを閉じた。

GL Driver を有効にして試してみる。Raspberry Pi Zero W 上での、GL Driver の有効化は、昔試した。

_mieki256's diary - Raspberry Pi Zero WでOpenGLが使えそうかテスト

この状態なら、tic80 を実行しても、すぐに入力待ち画面になった。しかし、起動音が、何か妙な聞こえ方…。更に、run と打って Hello World 相当を動かしてみたけれど、カーソルキーでスプライトを動かすと明らかに処理落ちしてる雰囲気。

どうやら、Raspberry Pi Zero W + Raspbian stretch 上において、TIC-80 は処理が重過ぎてまともに使えないっぽいなと。これが love2d なら、Raspberry Pi Zero W上でも、そこそこの速度で動くのだけどな…。

CPUコアを4つ積んでる Raspberry Pi3 あたりで動かすとどうなるのかは、ちょっと気になるところ。

#2 [pc] 鼓型ケースに入ってるPCのメンテナンス中

親父さん用PCが、ここ数日不調なので、代替機が必要になるかもしれないなと。弟が帰省した際に持ってきてくれた、 _鼓型ケース に入ったPCがあるので、コレを使えるようにしておいたほうがいいかもしれないな、ということで電源を入れてメンテナンス作業を開始。

中に入ってる Windows10 x64 のビルドバージョンが古かったので、現行版にアップグレード。数時間待たされた。

アップグレード後、無線LANドライバをアンインストール・再インストール。使ってる無線LAN子機は、 _ELECOM WDC-300SU2SWH

親父さんが使いそうなアプリを今のうちにインストールしておく。まずは親父さん用のアカウントを追加。その後、Google Chrome、LibreOffice、Thunderbird、縮小専用。、IrfanView、GIMP 2.10.6…思いついたものからインストール。

後は、デジカメ関係や、プリンタ・複合機のドライバをインストールしないと…。メールデータの引っ越し、ブックマークのエクスポートとインポート、ホームページビルダーの引っ越し…。そのあたりは、親父さんの作業場所にPCを持っていってからじゃないとできないな…。

2018/11/04() [n年前の日記]

#1 [pc] HDMIについて調べていたり

親父さん用PCが不調なので代替機もしくは代替M/Bについて検討していたのだけど、親父さんが使ってるディスプレイ、DELL UP2516D (25インチ液晶, 2560 x 1440)の入力端子が、DisplayPort と HDMI しかないことを思い出して、構成について悩み始めてしまったり。

今現在は、PC側がM/B背面のDisplayPort、ディスプレイ側がminiDisplayPort、で接続してるから、WQHD (= 2560x1440) で表示できているけれど。代替として検討してるM/Bには、DisplayPortが無い ―― DVI、HDMI、D-SUB しかないわけで。となると、HDMI で WQHD は表示できるのだろうか。

ググったところ、HDMIでもバージョンによっては、2560x1440 @ 60FPSで表示できなくもないらしい。ただ、手持ちのM/B が…。
_ASRock > M3A785GMH/128M
_ASRock > AM1B-ITX

すると、AM1B-ITX + ちゃんとしたHDMIケーブルを使えば、2560x1440 が表示できる可能性はあるのかな…。

と思ったが、ディスプレイ側がHDMI接続した際に1920x1080より上の解像度を出せるかどうかが疑問。DELLのサイトからマニュアルpdfをDLして眺めてみたけど、そのあたりの仕様が書いてない。液晶ディスプレイによっては、HDMI接続時は最大1920x1080までの製品も多々あるそうで。

_パソコンとモニターの接続方法で解像度は変わる

上記ページで紹介されてる DELL U2711b の場合、HDMI接続時はフルHD (= 1920x1080)までの対応だったりするようだし…。もしや、DELL UP2516D もそんな感じだったりしないか。

他にも、デュアルリンクDVI - HDMI変換アダプタを使ったら、2560x1440が表示できた事例もあるようで。ただ、市販の DVI - HDMI変換アダプタやケーブルは、シングルリンクDVIのみ対応と書いてある製品がほとんどで…。どの製品ならフルHDより上を出せるのか…。

いっそ DisplayPort端子を持ってるビデオカードを増設するのはどうか、と思ってググってみたけど。例えば DisplayPort付きの GeForce GT 1030 搭載ビデオカードは 1万円以上するのだな…。

DisplayPort に拘らず、HDMI接続で2560x1440を出せるビデオカードなら、GeForce GT 710等が5,000円台からあるけれど。しかし、HDMI接続ではディスプレイ側がイケるのかどうかが不安だったりもするわけで…。

面倒臭いな…。いっそ、1920x1080で表示することを前提にしてしまおうか。いや、でも、せっかく 2560x1440 を表示できるディスプレイがあるのに…。フルHDで使うのも、もったいない…。

#2 [windows] 親父さん用PCから他のPCの共有フォルダにアクセスできず

親父さん用PC (Windows10 x64 バージョン 1803 (Windows 10 April 2018 Update) ) 内のファイルを、他のPCの共有フォルダにバックアップしようとして、「\\hoge\共有フォルダ名\」を打ち込んだら、SMB関係のエラーメッセージが表示されて。

安全でないためファイル共有には接続できません。
この共有には最新でない SMB1 プロトコルが必要です。
そのプロトコルは安全でないため、システムが攻撃にさらされる可能性があります。
このシステムには SMB2 以降を使用する必要があります。

とりあえずでどうにかしたいなら、「SMB 1.0/CIFS ファイル共有のサポート」を有効にすれば、ひとまずは解決するらしい…。

_Windows 10のパソコンからアクセスすると「指定されたネットワーク名は利用できません。」または「安全ではないため、ファイル共有に接続できません。」と表示される|Q&A | IODATA アイ・オー・データ機器
_NASへの接続時に「SMB1プロトコルが必要です」エラーが出る場合の対処方法 | TeraDas
_Windows 10 バージョン 1709 と Windows Server バージョン 1709 以降のバージョンの既定では SMBv1 はインストールされません
_Microsoft、Windows 10の次期大型アップデートでSMBv1を無効化する計画 | スラド セキュリティ

本来は、サーバ側で SMB2 を使うようにすべき、かもしれないのだけど。古いOSを使う時もあるので、そっちに合わせるしか…。

2018/11/05(月) [n年前の日記]

#1 [nitijyou] 某所に行ってきた

Windows10機の電源を入れても起動せずにビープ音が鳴りっぱなし、という連絡を受けて、某所まで。13:40〜15:30まで作業。

Windows10機のメンテナンス。 :

Windows10機のM/Bは、 _GIGABYTE GA-EP45-UD3R 。マニュアルを眺めると、短いビープ音が鳴り続ける場合は電源関係の不具合らしい。

電源を交換して動作の検証をするために、部屋の中に転がってるサブPCから、ATX電源、 _サイズ 鎌力 弐 KMRK-550A(II) を調達して持っていった。

現場で、たしかにビープ音が鳴り続けてることを確認。電源交換後は、フツーに Windows10 が起動した。となると、やはり電源の故障だろうか。

今回持っていった鎌力弐と、某所で今まで使われていた Antec TP-750 を交換するということに。TP-750 は持って帰ってきた。

ノートPCのメンテナンス。 :

前回お邪魔した際に、ノートPC(VAIO)からLAN内の複合機が利用できないことが発覚して、解決策がないか調べていたのだけど。現場で再確認したところ…。
  • サブネットマスクは 255.255.255.0 だったので合ってる。
  • Windowsファイアウォールを一時的に無効にしても症状は変わらず。
となると、ひょっとして無線LANルータの隔離機能設定が絡んでないか、と思えてきたわけで。

ルータの管理画面に入れれば設定状況が分かるのだけど諸般の事情でソレはできず。LANを再構築した業者さんに確認してもらってほしい、という話に。

#2 [pc] サブPCの電源を交換

サブPC(Core2Duo E8400機)に積んでいたATX電源、 _サイズ 鎌力 弐 KMRK-550A(II) を某所に持っていってしまったので、代わりに、某所から持ち帰ってきた、不調なはずのATX電源 Antec TP-750 を積んでみることに。

ひとまず、TP-750 の蓋を開いて、エアダスターで掃除して、また蓋を閉めて、サブPCに入れてみた。

動いてるな…。どうなってるんだ…。Memtest86+ もエラーを出さずに4周ほど走ってしまった。

某所のPCは Core 2 Quad Q9550 で、こちらは Core2Duo E8400 だから…。こちらのほうがまだ電力をビミョーに要求されないので弱った電源でも動いてしまうのだろうか。それともケース内の排熱の問題で、あちらは「電源に異常有り」と言い出しやすい状況になってるのだろうか。原因が分からん…。

2018/11/06(火) [n年前の日記]

#1 [pc] LibreOffice Writerでテキストボックスの中にリストを入れたいのだけど

LibreOffice Writer 6.1.2.1 x64 上で、テキストボックス(テキスト枠?)を作成して、その中でリスト(箇条書き)を使いたいのだけど…。どうすれば可能なのか…。

ググってみたら、どうやらそんなことはできないらしい。機能として持ってないそうで。

_How do I add a numbered list inside of a text box? [closed] - Ask LibreOffice

しかし、代わりにフレームを使えるという話も見かけた。

_[Solved] Can't use bullets or numbering in Text Box (View topic) - Apache OpenOffice Community Forum
_Bullet List in Text Box (View topic) - Apache OpenOffice Community Forum

試しにフレームを挿入してみたところ、たしかにリストが使えた。コレを使ってどうにかするしかないか…。

ちなみに、LibreOffice Writer ではなく、LibreOffice Draw なら、テキストボックスの中でリストが使える。…どちらもテキストボックスと呼びつつ、それぞれ別の実装・別の機能なのだろうか。

#2 [pc] 本当にパソコンが必要なのだろうか

親父さんの友人が新しいPCを購入したらしく、親父さん経由でPC関係の質問を受けたのだけど。なんでもその御仁、PCはネットに繋げてないし、そのPCでやることと言えば、デジカメ写真の取り込み・管理・整理・色調補正等の簡易なレタッチぐらい、なのだそうで。

その話を聞いて、なんだかちょっと考え込んでしまった。この場合、本当にPCは必要なのだろうか?

まあ、たしかに、今現在のこの状況では、写真の取り込みだの管理だのができる機器と言えばPCぐらいしか存在しないので、PCを導入する流れは当たり前かもしれないけれど。しかし、行いたい作業範囲はある程度決まってるのに、やれWindowsへのログインがどうとか、パスワード変更の操作方法の把握とか、そのあたりの知識の習得は本当に必要なのだろうか。その人しか使わないPCなのに、アカウントという概念は必要なのかな。みたいな。 *1

昔、日本にはワープロ専用機というものが存在していて、印刷用の文書を作るだけならPCなど買わなくても、ワープロ専用機を導入するだけで目的を十分果たせていた、そんな時期もあるわけで。

あるいは、世の中にはゲーム専用機というものが存在していて、ゲームをプレイするだけならPCなど買わなくても、ゲーム専用機を買えば目的を果たせたりもするわけで。

それを考えると、デジカメで撮影した写真をアレコレできる専用機、という商品ジャンルだって本当はアリだったりしないか…。年配で、視力が弱っているから大きな画面に大きな文字じゃないと読めなくて、PC操作なんてよく分からないような方々でも、サクサク使える何かがあれば…。

どの日本メーカも、PCの販売は伸び悩んで、関連事業部を中国企業に売却しちゃったわけだけど。ユーザにとってもメーカにとっても、見た目も中身も複雑怪奇なPCという商品をわざわざ用意して、しかも他社製品との差別化がなかなか出来ずに、結局は全てを手放す展開になったのは、なんだかアレな気もしてくるなと。本当は、ユーザがやりたいことをバラバラに分解して、一つ一つの需要に特化した機器を打ち出したほうが、生き残る道もあったのではないか…。例えば、次々に産まれてくる各種Webサービスは、Web利用者のやりたいことをバラバラに分解して、それぞれの需要に特化したサービスとして提示しているわけで。それと同じことをハードウェアの分野でもできた可能性はないか。「なんでもできますよ」ではなく、「コレしかできませんけど圧倒的に簡単です。他の製品ジャンルには負けませんよ」的な製品…。

もっとも、そういった製品を作る場合も、結局中身はPC相当になるよなと。例えば今時の据え置きゲーム機だって中身はPCそのものだったりするわけで。

妄想。 :

Linuxのディストリを作るっぽいノリで、専用機モドキを用意できたりしないかな…。ハードウェアはPCだし、OSも既存OSだけど、起動して真っ先に立ち上がるのが、ジャンルに特化した専用デスクトップ+専用アプリ、みたいな…。

ファミコンにカセットを差し込む感覚で使えるPC、とか。HDDやSSDは入ってなくて、USBポートにUSBメモリや外付けSSDを差し込むことで起動する構成なら似た感じになるのだろうか。

そこまでやる必要は無いか。昔あった、 _98ランチ みたいなものを用意すればいいだけか。…昔は邪魔者扱いされてた98ランチだけど、もしかして状況によっては、ああいうアプローチはアリだったのだろうか。まあ、Windows8のスタート画面でもあるのだけど。「この作業しかしません」的にやることが決まってる場合はアリのような気もする。

*1: Windows10上で自動ログインを有効にすればいいのだろうけど、誰か詳しい人がその設定をした後で、よく分かってないユーザ当人が何か起きた際に対処できるかというと疑問が…。

この記事へのツッコミ

Re: 本当にパソコンが必要なのだろうか by セイ    2018/11/29 09:57
差が社、いろんな用途に適した製品ってのはあるにはあるけど、
これができない、あれやるにはオプションが必要ってなって、結果PCが必要ってなるんだよねぇ。
まぁ、写真の整理tってことに絞るなら、バッファローのおもいでばこ一択かと思う。
レタッチ機能はないけど、オンラインサービスで割といけるのあるから、タブレットにデータさえ移せばなんとかなるんじゃないかな。
Re: 本当にパソコンが必要なのだろうか by 名無しさん    2018/12/01 00:09
んー「ネットに繋がらなくてデジカメの取り込みと簡単なレタッチ機能しかない」という機械の適正価格はどれくらいなんですかね。
個人的にそういう機械があったとして、定価が1980円くらいなら買ってもいいかなとは思いますが、数万円となると誰も見向きもしないでしょう。
2016年初めにキングジムから「ポータブック」なる小型ノートPCが発売されました。
当時の格安タブレット並みのスペックに折りたたみ式のキーボードがついたもので9万円という価格で発売したものの全く売れず、
ほんの数ヶ月で1/3以下に値崩れして叩き売られてました。
小型低スペックとはいえ液晶もキーボードも付いてるフル機能のWindowsノートPCが2万円台でも魅力を感じないこのご時世に
ネットすら繋がらない専用機が商品として魅力を感じるには、超低価格路線か、使い勝手が超優れているくらい内部を作り込むか、
最低どちらかは満たす必要があるように思います。

2018/11/07(水) [n年前の日記]

#1 [python] pygameについて調べ直したり

pygame は今現在どうなってるのかと思ってググったら、どうやら SDL2 を使った pygame 2 とやらが開発中らしいと知り。

_pygame 2 status - 5 Nov, 2018

なんだか嬉しいニュースだなと。Python で2Dゲーム制作というと、手軽だけど描画が遅い pygame が使われてしまう事例が多くて、この状況はどうなんだともやもやしていたものだけど。ハードウェアによる描画がデフォルトらしい SDL2 が使われるなら、そのあたりの状況が改善しそう。

それにしても、これは以前始まったけど途中で止まってしまったプロジェクトの再開なのか、それとも新規に始まったプロジェクトなのか、どっちなんだろう…。

pygame の後継ライブラリの流れについては…たしか以前、簡単にメモしてた気がする…。うむ…メモしてあった。

_mieki256's diary - pysdl2をほんの少しだけ試用

余談。 :

pygame も、デフォルトはソフトウェア描画だから遅いけど、ハードウェア描画を可能にする機能・設定もあるようで。

ただ、当時のIntel製GPU ―― CPUではなくチップセットにGPUが内蔵されてた時代のドライバがクソで、ハードウェア描画の設定にすると画面が描画されない不具合が多発して。

ノートPCの類は内蔵GPUが当たり前だから、PC市場のシェアを考えてもIntel製GPUを無視するわけにもいかないし、そのあたりの処理は SDL 1.x にお任せしてるから pygame側で何かしら対策するのも難しい…。

そんな理由で、「pygameを使うなら、かつ、色んな環境で確実に動かしたいなら、ソフトウェア描画以外はオススメしませんよ」という流れになったわけで。

描画に pygame を使わず、OpenGLを制御できるモジュール(PyOpenGL等)を使って高速に描画する、という構成もあるのだけど。それだとソースがゴチャゴチャしちゃうし、OpenGL に関しては、Intel製GPUのみならず、AMD/ATI製GPUのドライバも輪をかけてクソで…。

故に、手軽に使えるけど遅い、というのが pygame の評価だったけれど、そのあたりが改善されそうなので、pygame 2 に期待せずには居られないのです。

#2 [python] 手元のPCに入ってるPythonのモジュールをアップデート

ふとなんとなく、手元の環境、Windows10 x64 + Python 2.7.12 上でインストールしていたモジュールについて、アップデート作業をしてみたり。

まずは Pthon 2.7.12 を 2.7.15 にアップグレード。公式サイトから python-2.7.15.msi をダウンロードして実行。Python 2.7.12 が入ってるフォルダに上書きインストール。

本当に上書きでいいのだろうか。一旦アンインストールしてからインストールしたほうが良くないか。しかしその場合、別途インストールしていた各モジュールはどうなるのだろう。なんだか怖いので毎回上書きしちゃってるけど…コレっていいのかなあ…。

DOS窓を開いて python のバージョンを確認。
> python --version
Python 2.7.15

モジュールをアップデート。まずは更新可能なモジュールの一覧を表示。
pip list --o

一つずつアップデート。
pip install -U hoge

依存関係がよろしくないモジュールがいくつかあったような気がするけれど…問題が出てから対処しよう…。

pycairo、pygobject はアップデートできなかった。ビルドするための環境が必要らしい。prompt-toolkit も、ドキュメントには 1.x と 2.x で仕様が違うと書いてあったので、アップデートしなかった。

pygletのサウンド関係が変わってた。 :

pyglet を 1.3.2 にアップデートしたら、昔書いたスクリプトが動かなくなった。どうやらサウンド関係の仕様が変わってしまったらしい。

自分、以前はどのバージョンを使っていたのだったか…。

_mieki256's diary - pygletを1.3.0rc1にしてみたら遅くなった

どうやら 1.2.4 か 1.3.0rc1 を使っていたと思われる。

さておき、変更点をメモ。pyglet はデフォルト状態だと wavファイルしか鳴らせないので、avbin なるものを導入 *1 して、mp3 や ogg も再生できるようにしてからスクリプトを書いたのだけど。その avbin 関係が少し変わってるように見えた。
  • avbin のバージョンを調べる、pyglet.media.avbin.get_version() が見当たらない。
  • avbin が使えるかどうかを調べる pyglet.media.have_avbin を pyglet.media.have_avbin() の形で呼ばないと True , False を返してくれない。ただ、コレは以前のスクリプトで記述ミスをしていた可能性もありそう。

それと、ループ再生の仕方が変わってた。

以前は以下のような感じで呼んでたけど。
    self.sndplayer = pyglet.media.ManagedSoundPlayer()
    self.sndplayer.queue(self.bgm_src)
    self.sndplayer.eos_action = self.sndplayer.EOS_LOOP  # ループ再生を設定
    self.sndplayer.play()  # 再生開始
pyglet 1.3.2 は以下のように書いたらループ再生してくれた。
    self.loop_music = pyglet.media.SourceGroup(self.bgm_src.audio_format, None)
    self.sndplayer = pyglet.media.Player()
    self.loop_music.queue(self.bgm_src)
    self.loop_music.loop = True               # ループ再生を設定
    self.sndplayer.queue(self.loop_music)
    self.sndplayer.play()  # 再生開始

pyglet.media.ManagedSoundPlayer は無くなって、「pyglet.media.Player を使え」という仕様になったようで。

_pyglet.media - pyglet v1.2.4

また、EOS_LOOP は無くなって、「SourceGroup.loop を使え」という仕様になった模様。

_Player Class - pyglet v1.2.4
_python - Haven't changed my code but it stopped working: `object has no attribute 'EOS_LOOP'` - Stack Overflow

ゲーム関係のライブラリやツールって、バージョンによって仕様がコロコロ変わるところがあるからなんだかアレだなと。Unity もそうだったし…。まあ、ゲームが完成したらそこでプロジェクト終了、みたいな昔風のノリがちょっと残っているのだろう…。

*1: Windowsの場合、avbin.dll をスクリプトと同じ場所に置く。

2018/11/08(木) [n年前の日記]

#1 [python] Python 3.7.1をインストールしておいた

Windows10 x64 上で、Python 3.7.1 をインストールしておいた。とメモ。

Python 2.6、2.7、3.5 をインストールしておいた環境だけど、3.7.1 をインストールしたので、今後 3.5 は使わないだろうからアンインストールしておいた。現在は 2.6、2.7、3.7 が入ってる状態。まあ、基本的には 2.7 しか使ってないし…。

pip で各種モジュールもインストール。Pillow、pygame、pyglet 等。

2018/11/09(金) [n年前の日記]

#1 [python] pygameとGLUTを同時に使おうとしてハマった

Windows10 x64 + Python 2.7.15 上で、pyagame 1.9.4 + PyOpenGL 3.1.3b2 + PyOpenGL-accelerate 3.1.3b2 の動作確認をしているのだけど。 _昔書いたスクリプト が動かなくて…。gl や glu を使って描画する部分は動くのだけど、glut を使って teapot 等を描画してるところがエラーを出してしまう。おかしいな…。昔は動いていたんだけどなあ…。

ふと思いついた。バージョンがアレなのでは。

PyOpenGL、PyOpenGL-accelerate をアンインストールして。
pip uninstall PyOpenGL
pip uninstall PyOpenGL-accelerate

PyOpenGL 3.1.0、PyOpenGL-accelerate 3.1.0 をインストール。
pip install PyOpenGL
pip install PyOpenGL-accelerate

この状態なら、昔のスクリプトも動いた。そういうオチか…。

ソース。 :

こんな感じのソースで動作確認をした。とメモ。

_teapot_on_pygame.py
"""
draw glut teapot on pygame

* Windows10 x64 + Python 2.7.15
* pygame 1.9.4 + PyOpenGL 3.1.0 + PyOpenGL-accelerate 3.1.0
"""

import pygame
from pygame.locals import *

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *

SCRW, SCRH = 640, 480


class PyGame:
    def __init__(self):
        self._running = True
        self._screen = None

    def initialize(self, w, h):
        self.scrw = w
        self.scrh = h

        glutInit()
        glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH)

        pygame.init()

        # OPENGL向けに初期化
        self._screen = pygame.display.set_mode(
            (w, h), pygame.OPENGL | pygame.DOUBLEBUF)

        if not self._screen:
            return

        glClearColor(0.0, 0.0, 0.0, 1.0)
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluPerspective(45.0, float(w) / float(h), 0.1, 100.0)
        # gluOrtho2D(0, w, h, 0)
        glEnable(GL_DEPTH_TEST)  # enable shading

        self.clock = pygame.time.Clock()

        self.xrot, self.yrot = (0.0, 0.0)
        self.xpos, self.ypos, self.zpos = (0.0, 0.0, -5.0)

        return True

    def onKeyDown(self, event):
        print(event.key, event.mod, event.unicode)
        if event.key == pygame.K_ESCAPE or event.unicode == u'q':
            self._running = False

    def onKeyUp(self, event):
        print(event.key, event.mod)

    def update(self):
        spd = 0.05
        pressed_keys = pygame.key.get_pressed()
        if pressed_keys[pygame.K_UP]:
            self.zpos -= spd
        if pressed_keys[pygame.K_DOWN]:
            self.zpos += spd
        if pressed_keys[pygame.K_LEFT]:
            self.xpos -= spd
        if pressed_keys[pygame.K_RIGHT]:
            self.xpos += spd

        self.xrot += 0.25
        self.yrot += 1.0

    def draw(self):
        """ draw object """

        # Clear OpenGL Buffer
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

        # set camera
        # gluLookAt(0.0, 1.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)

        glTranslatef(self.xpos, self.ypos, self.zpos)
        glRotatef(self.xrot, 1.0, 0.0, 0.0)
        glRotatef(self.yrot, 0.0, 1.0, 0.0)
        glScale(1.0, 1.0, 1.0)

        # draw teapot
        glColor3f(1.0, 0.0, 0.0)  # color red
        glutWireTeapot(1.0)   # wireframe
        # glutSolidTeapot(1.0)  # solid

        # OpenGL drawing
        glFlush()

        # flip pygame double buffer
        pygame.display.flip()

    def execute(self, w, h):
        if not self.initialize(w, h):
            return

        # main loop
        while self._running:
            # self.clock.tick(60)
            self.clock.tick_busy_loop(60)

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self._running = False
                elif event.type == pygame.KEYDOWN:
                    self.onKeyDown(event)
                elif event.type == pygame.KEYUP:
                    self.onKeyUp(event)

            self.update()
            self.draw()

            cap = '%5.2f FPS' % (self.clock.get_fps())
            pygame.display.set_caption(cap)


if __name__ == "__main__":
    game = PyGame()
    game.execute(SCRW, SCRH)
    pygame.quit()

以下のような結果に。

teapot_on_pygame_ss01.gif

#2 [prog] Visual Studio Codeでファイル内のタイムスタンプを書き換えたい

今現在、emacs系のエディタ(xyzzy, NTEmacs)を使っている際は、ファイルの最初のほうにタイムスタンプを書いておいて、保存と同時にタイムスタンプを自動で更新するようにしているのだけど。

_[Home] Time Stamp
_xyzzyはすごいぜ
_auto-time-stamp.l

例えば、ファイルの最初のほうに、以下のような記述をしておくと…。
#!/usr/bin/perl -w
# -*- mode: perl; Encoding: sjis; coding: sjis -*-
# Last updated: <>
#

保存した際、以下のように書き換わる、みたいな。
#!/usr/bin/perl -w
# -*- mode: perl; Encoding: sjis; coding: sjis -*-
# Last updated: <2018/11/09 19:27:04 +0900>
#

これを、Visual Studio Code でやりたいわけですよ。

それらしい拡張に遭遇。 :

検索してみたら、似たような処理をしてくれる拡張は存在しているようで。

_Auto Time Stamp - Visual Studio Marketplace

ただ、タイムスタンプのフォーマットが、今までemacs系エディタ上で設定していたソレとは違っていて…。

一応、拡張の設定で、タイムスタンプの前後の文字列を正規表現で指定できるのだけど、色々記述を変えて試してみても動いてくれない。何故。

デフォルト設定のまま、デフォルトのタイムスタンプ文字列をファイルの最初のあたりに書き加えてみると動くので、拡張が動いてないというわけではなさそうだけど…。

フィルタを書いた。 :

考えてみたら、sort や uniq のようなフィルタの形で、タイムスタンプを書き換えてくれるフィルタがあれば、多少は違うかなと。幸い、Visual Studio Code の拡張には、外部フィルタを利用可能にしてくれるものがあるようで。

_Filter Text - Visual Studio Marketplace

選択範囲を作って、Ctrl + K, Ctrl + F を押すと、入力欄が開くので、フィルタ名を打ち込んでやれば、選択範囲に対して処理をしてくれる。

後はフィルタがあれば…。試しにフィルタを Perl で書いてみた。

_timestamp.pl
# replace time stamp filter

use strict;
use warnings;

my $patstart = "Last updated: <";
my $patend = ">";
my $chklines = 8;

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$year += 1900;
$mon += 1;

my $cnt = 0;
while(<>) {
    chomp $_;
    if ($cnt <= $chklines && $_ =~ /(.+)$patstart.*$patend$/) {
        my $tmstr = sprintf("%04d/%02d/%02d %02d:%02d:%02d +0900", $year, $mon, $mday, $hour, $min, $sec);
        print "$1$patstart$tmstr$patend\n";
    } else {
        print "$_\n";
    }
    $cnt++;
}

動作確認用に、以下のテキストファイルを書いて…。

_test.txt
#!/usr/bin/perl -w
# -*- mode: perl; Encoding: sjis; coding: sjis -*-
# Last updated: <>
# Last updated: <>
# Last updated: <>
# Last updated: <>
# Last updated: <>
# Last updated: <>
# Last updated: <>
# Last updated: <>
# Last updated: <>
# Last updated: <>
# Last updated: <>
#

変換できるか実験。
> cat test.txt | perl timestamp.pl
#!/usr/bin/perl -w
# -*- mode: perl; Encoding: sjis; coding: sjis -*-
# Last updated: <2018/11/09 20:33:27 +0900>
# Last updated: <2018/11/09 20:33:27 +0900>
# Last updated: <2018/11/09 20:33:27 +0900>
# Last updated: <2018/11/09 20:33:27 +0900>
# Last updated: <2018/11/09 20:33:27 +0900>
# Last updated: <2018/11/09 20:33:27 +0900>
# Last updated: <2018/11/09 20:33:27 +0900>
# Last updated: <>
# Last updated: <>
# Last updated: <>
# Last updated: <>
#
書き換わった。

ちなみに自分の環境は Windows10 だけど cat.exe も入れてある。デフォルト状態なら、type test.txt で同じことができるのかな。たぶん。

更に、自分の環境では ActivePerl を使っているので、plファイルをbatファイルに変換してみる。
pl2bat timestamp.pl
_timestamp.bat が出来上がった。

これをパスの通ったところに置いておいて…。Visual Studio Code 上で、タイムスタンプのある行を選択して、Ctrl + K, Ctrl + F → timestamp を入力。該当行が書き換わってくれた。

自動で書き換えてくれるわけではないから不便だけど、それでも手打ちで修正するよりはまだマシだろう…。

余談。 :

Atomエディタも、ファイルを保存する際に自動でタイムスタンプを書き換えてくれる拡張が存在していて。コレなら、設定次第で、emacs系エディタと同じフォーマットが使える。とメモ。

_atom-timestamp

ただ、Atomエディタ自体が、鬼のように重いわけで…。起動に数分かかるし、時々強制終了するし…。なので、Visual Studio Code を使えるなら、そちらのほうが嬉しいよなと…。

#3 [nitijyou] 市の保健センターまで行ってきた

市の保健センターまで行って、大腸がん検診の検体を提出。雨だったので、親父さんの運転する車で連れて行ってもらった。助かった。

昔は、保健センターの駐車場を無料で利用できていた記憶があるのだけど。今は有料になってしまったそうで。保健センターに用事が合って、かつ、30分までの利用なら、受付の方に言えば無料駐車券を貰えるらしい。

親父さんは待ってる間、近所の馴染みの写真屋さんに寄って写真談義をしていたようで。そこで聞いた話によると、市役所等も含め、市の中心部にある駐車場のほとんどは、基本的には有料になってしまったのだとか。そういう時代になったのだな…。

帰宅途中にケーズデンキに寄ってもらって、Panasonic製のスイッチ付きタップを購入。型番は確認してないけど、おそらく、 _WHS2001WP じゃないかな…。茶の間の炬燵用として使う予定。

全然関係ないけど、ケーズデンキの店頭でスイッチ付きタップを探しても、パナソニック製の件の製品しか置いてなかった。昔は色んな製品が置いてあった記憶があるけど。ケーズデンキに一体何があったのか。それとも、この手の製品ジャンルで何か事故でも発生して、ジャンルそのものが…。

2018/11/10() [n年前の日記]

#1 [prog][ruby][python] Perl/Ruby/Pythonスクリプトをbatファイルにしたい

Windows10上で、Perlスクリプト、もしくはRubyスクリプトを、 _バッチファイル(batファイル) にしたいなと。

前提条件。 :

前提条件として、あらかじめWindows10に、Perl や Ruby がインストールされていることとする。

「Perl (Ruby) がインストールされているなら、batファイルなんて作らなくても、いきなりDOS窓上で hoge.pl (hoge.rb) を実行すればいいんじゃないの?」と思われるかもしれないけれど。

自分の環境では、Perl や Ruby は複数のバージョンが入っているので、.pl、.rb に一体どのバージョンが関連付けされているのか、恥ずかしながら把握できてないという…。環境変数PATHを探していって一番最初に見つかった perl.exe、ruby.exe が現在使おうとしてるソレ、というルールにして使っているので、バージョンが不明な perl.exe、ruby.exe を、いきなり呼び出されるとちょっと困る時があるわけで。

それと、今現在はどうなのか分からないけれど、Windowsには、拡張子の関連付けに基づいてPerlやRubyを起動した場合、リダイレクトやパイプが効かなくなるというバグ(仕様?)があったらしいので、batファイルにしておいたほうが確実だったりするわけで。

_「batファイルにrubyを埋め込む方法」が必要なわけ - Rubyの魔神 - はてな?Rubyグループ

Perlの場合。 :

Windows上でPerlを使う場合、 _ActivePerl をインストールして使う場面が多い(多かった)と思うのだけど。ActivePerlなら、pl2bat という、.pl を .bat に変換してくれるツールが入ってる(入っていた)。

pl2bat hoge.pl
これで、hoge.bat が作られる。

例えば、以下のようなスクリプトを書いた場合。
#!/usr/bin/perl -w
# -*- mode: perl; Encoding: sjis; coding: sjis -*-

use strict;
use warnings;

print "Hello. I am Perl";

pl2bat hoge.pl で変換すると、以下のようなbatファイルが出来上がる。
@rem = '--*-Perl-*--
@echo off
if "%OS%" == "Windows_NT" goto WinNT
perl -x -S "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9
goto endofperl
:WinNT
perl -x -S %0 %*
if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto endofperl
if %errorlevel% == 9009 echo You do not have Perl in your PATH.
if errorlevel 1 goto script_failed_so_exit_with_non_zero_val 2>nul
goto endofperl
@rem ';
#!/usr/bin/perl -w
#line 15
# -*- mode: perl; Encoding: sjis; coding: sjis -*-

use strict;
use warnings;

print "Hello. I am Perl";

__END__
:endofperl

何をやっているのかというと…。Perl は -x をつけて起動することで、読み込んだファイルに対して _shebang が出てくるまで読み飛ばす、ということができる。これにより、
  • batファイルの前半で、「perl -x -S batファイル名」を呼び出して、
  • 呼び出されたPerlは、渡されたbatファイルの後半(「#!/usr/bin/perl -w」以降の行)に書かれたPerlスクリプト部分だけを実行。
ということをしている。

_付録2
_perlrun - Perl インタプリタの起動方法 - perldoc.jp
-x directory

メールのような大きな無関係のASCII テキストのかたまりの中に プログラムが埋め込まれている事を Perl につたえます。
最初の #! で始まり、"perl" という文字列を含む行までの、 先行するゴミは捨てられます。
その行にある意味を持つスイッチは適用されます。
directory が指定されると、Perl はプログラムの実行前に、 そのディレクトリに移ります。
-x スイッチは先行するゴミの処分を制御するだけです。
プログラムの後に無視すべきゴミがある場合には、 __END__ でプログラムを終了する必要があります
(その、後に続く ゴミの一部または全部は、必要に応じて DATA ファイルハンドルを通して、 そのプログラムで処理する事ができます)。

perlrun - Perl インタプリタの起動方法 - perldoc.jp より


ついでに説明しておくと…。
  • perl に渡している -S は、環境変数PATH からスクリプトファイルを探す指定。
  • batファイル中で %0 と書くと、その部分は、実行ファイル名で置き換えられる。
  • %* と書くと、batファイルに与えられた引数全てで置き換えられる。
  • if "%OS%" == "Windows_NT" goto WinNT で、Windows NT系のOSなら :WinNT に飛び、そうでなければ次の行へと進む。
  • goto endofperl で、:endofperl に飛ぶ。
  • batファイル中で存在しないコマンドを実行しようとした場合、%errorlevel% に 9009 が入るので、エラー発生時の処理が書ける。
  • Perlスクリプトが正常終了すると errorlevel には 0 が入る。0以外ならスクリプト実行中に何かエラーが発生したということ。(エラーが発生した際に 1 等を返すようにスクリプトを記述しておくのがお約束。)

_Windowsのバッチファイルの基本的な使い方 (2/4):Tech TIPS - @IT
_Windowsバッチファイル引数 CapmNetwork
_Windowsコマンドでファイル名だけ/パスだけ取得する - 帰りは気楽な歌で

全然関係ないけど、今現在の ActivePerl って64bit版しかなくて、32bit版は入手できなくなってたのだな…。というか、今時 Windows上でPerlを使いたい場合、何を使うのが主流なのだろう。 _Strawberry Perl かな。

Rubyの場合。 :

Ruby の場合も、Perlと同様に -x オプションが用意されているので、似たようなことができる。

_Rubyスクリプトであり、バッチファイルでもあるファイルの作り方 - Route 477(2007-11-27)
_「batファイルにrubyを埋め込む方法」が必要なわけ - Rubyの魔神 - はてな?Rubyグループ

例えば、次のようなRubyスクリプトを書いたとして。
#!ruby -Ks
# -*- mode: ruby; coding: sjis -*-

puts "Hello. I am Ruby."

ファイルの最初と最後に何行か追加するだけで、batファイルとして実行できるようになる。
@echo off
ruby -x "%~f0" %*
goto endofruby

#!ruby -Ks
# -*- mode: ruby; coding: sjis -*-

puts "Hello. I am Ruby."
__END__
:endofruby

> ruby rb2bat_test.rb
Hello. I am Ruby.

> rb2bat_test.bat
Hello. I am Ruby.

Ruby に渡している "%~f0" は、実行ファイル自身を完全修飾パス名に展開したもの。例えば以下のようなbatファイルを作成して実行してみれば動作確認ができる。
echo "%~f0"

D:\temp> cat test.bat
echo "%~f0"

D:\temp> test.bat

D:\temp> echo "D:\temp\test.bat"
"D:\temp\test.bat"
ドライブ名から始まる、ファイルの完全なパスに置き換わってることが分かるかな、と。

Pythonの場合。 :

ついでに、Pythonでも似たようなことができるのかどうかを調べてみたり。Pythonの起動オプションに -x があったので、もしかして、と。

_1. コマンドラインと環境 - Python 3.7.1 ドキュメント
-x

Unix 以外の形式の #!cmd を使うために、ソースの最初の行をスキップします。これは、DOS専用のハックのみを目的としています。

1. コマンドラインと環境 - Python 3.7.1 ドキュメント より


試してみたけど、Pythonの -x オプションは、Perl や Ruby のソレとは違う動作をするので、似たようなノリでbatファイルにすることはできなかった。どうやら、本当にソースの最初の行だけをスキップするように見える…。Perl や Ruby のように、shebang が出てくるまでゴミ(?)を読み飛ばすわけではないようで。

ただ、py2bat でググったら、以下のやり取りに遭遇。2000年頃のやり取りらしい。

_py2bat (was: How do I make a Python .bat executable file?)

記述されていたスクリプトを少し手直しして試してみた。

_py2bat.py

例えば以下のようなスクリプトを書いて。

_hello.py
#!python
# -*- mode: python; Encoding: utf-8; coding: utf-8 -*-

print("Hello. I am python.")

py2bat.py で変換してみる。
python py2bat.py hello.py

hello.bat が作成された。中身は以下のような感じに。

_hello.bat
@echo off
rem="""
if "%OS%" == "Windows_NT" goto WinNT
python -x "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9
goto endofpython
:WinNT
python -x "%0" %*
if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto endofpython
if %errorlevel% == 9009 echo ERROR: You do not have Python in your PATH.
goto endofpython
rem """

# python script starts here
#!python
# -*- mode: python; Encoding: utf-8; coding: utf-8 -*-

print("Hello. I am python.")

# end of python script
rem="""
:endofpython
rem """

batファイルとして見た場合、Perl や Ruby と同様に、goto を使ってPythonスクリプト部分には処理が行かないように避けているのが分かる。

Pythonから、このファイルをスクリプトファイルとして見た場合は…。
  • -x オプションをつけて呼んでいるから、1行目の @echo off は無視される。
  • batファイルとして使われる部分は、Python から見て、remという変数に文字列を代入する形にしているので、Pythonスクリプトの動作には絡んでこない。(rem=""" 〜 rem """ までは、Pythonにとっては文字列の代入になる。)

なかなかトリッキーだなと…。一応動くけど…。
> python hello.py
Hello. I am python.

> cat hello.py
#!python
# -*- mode: python; Encoding: utf-8; coding: utf-8 -*-

print("Hello. I am python.")

> python py2bat.py hello.py
generating hello.bat

> hello.bat
Hello. I am python.

Pythonの場合その2。 :

前述のやり取りを追っていったら、もっと簡単なやり方も紹介されていた。

_py2bat (was: How do I make a Python .bat executable file?)

「Pythonスクリプトの一行目に以下を追加するだけでイケるんじゃね」と言っている。
@python -x %~f0 %* & goto :EOF

batファイルにとっては意味のある行だけど、Pythonから見ると -x オプションをつけて呼んでいるから、1行目は無視されてPythonの動作には無関係な行になる。

また、batファイルは暗黙的に、ファイルの最後に「:eof」というラベルがあるものとして扱われるので、goto :EOF でファイルの最後まで飛ぶ、という指定になるらしい。

_Windowsのバッチファイルの基本的な使い方 (4/4):Tech TIPS - @IT
また暗黙のラベルとして、バッチファイルの最後には「:eof」というラベルがあるものと想定されており(EOFはファイル終了、End Of Fileの略)、「goto :eof」とするとバッチファイルが終了する(「goto eof」ではなく「goto :eof」にしないとエラーになる。「help goto」参照)。

Windowsのバッチファイルの基本的な使い方 (4/4):Tech TIPS - @IT より


更に、batファイル内で「&」を使うと、左のコマンドを実行後に右のコマンドを実行、という指定になるようで。コレを使えば複数の指定を一行で書ける。

_「&」 - DOS コマンド一覧 - Programming Field
<command1> を実行した後、その結果に関わらず <command2> を実行します。
ただし、<command1> がExitなどでプロンプト(セッション)を終了させた場合は実行されません。
「&」を使用した場合、Errorlevel(または環境変数ERRORLEVEL)の値は <command2> の実行結果(& で複数つないだ場合はその最後のコマンド)による値となります。

「&」 - DOS コマンド一覧 - Programming Field より


つまり、前述のPythonスクリプトは、以下のように書けばbatファイルにできる。
@python -x "%~f0" %* & goto :EOF
#!python
# -*- mode: python; Encoding: utf-8; coding: utf-8 -*-

print("Hello. I am python.")
随分と簡単になった。

ただし、Windows95/98では動かない等の注意点もあるらしい。でもまあ、今時、NT系ではないWindowsを使っている場面は少ないだろう…。

#2 [windows] 拡張子の関連付けを調べたり

「自分が使ってるWindowsが、どの拡張子にどのプログラムを関連付けしてるのか、自分で把握できてない」というのはやっぱりちょっと恥ずかしいなと思ったので調べる方法をググってみたり。たしか記憶では… assoc なるコマンドが関係していた…ような気がする…。

_コマンドプロンプト assoc - [ファイルと拡張子の関連を表示・設定する]

やはりそうだったらしい。assoc で調べられる。

とりあえずDOS窓で、.pl、.rb、.py について確認してみたりして。
> assoc .pl
.pl=APerl

> assoc .rb
.rb=Ruby200

> assoc .py
拡張子 .py のファイルの関連付けが見つかりません
えっ。.py は何も関連付けしてなかったのか…。 *1

APerl とか Ruby200 って何だろう。おそらく、アプリケーションの種類を示す何かだろう…。それぞれどんなアプリケーションが割り当てられているかは、ftype で調べることができる模様。

_コマンドプロンプト ftype - [拡張子に関連付けられているアプリケーションを設定する]

DOS窓で打ち込んで調べてみる。
C:\home> ftype APerl
APerl="C:\Perls\aperl589build827\bin\perl.exe" "%1" %*

C:\home> ftype Ruby200
Ruby200="C:\Ruby\Ruby200\bin\ruby.exe" "%1" %*
APerl は ActivePerl に関連付けしてあった模様。Ruby200は…コレ、Ruby 2.0.0 に関連付けしてあるのか…。古過ぎる…。まあ、ActivePerl もバージョンが古いまま使ってるのでアレなんだけど。

ところが、自分の環境において、DOS窓上で直接 .rb を実行してみると、違うバージョンのRubyが使われるようで。

以下のようなスクリプトを書いて実行してみると…。
#!ruby -Ks

puts RUBY_VERSION
> showver.rb
2.4.3

> ruby --version
ruby 2.2.6p396 (2016-11-15 revision 56800) [i386-mingw32]

> ruby showver.rb
2.2.6
assoc や ftype で確認した際には、.rb に Ruby 2.0.0 が関連付けされてるように見えたけど、.rb を直接実行してみると Ruby 2.4.3 が使われてしまう。何故。

どうやら、エクスプローラ上でダブルクリックした時の関連付けでは、Ruby 2.4.3 になっているから、っぽいなと。 *2 自分の環境では、エクスプローラ上で、.rb、.rbw は、Ruby 2.4.3 に関連付けされていて、assoc や ftype で調べたソレとは違う関連付けになっている。更に、.py、.pyw は、pythonw.exe に関連付けされてるように見えたけど、ダブルクリックして見ると IDLE が起動するという…。何故。

どうやら Windowsは、関連付けに関して、3〜4種類の設定があるようで。

_ASCII.jp:最新のWindowsにおけるファイルの関連づけを分析する (2/2)|Windows Info
_Windowsの関連付けを決めるレジストリの優先順位とassoc ftypeが効かない問題について - イム日記
_レジストリの直接編集によるファイルの拡張子と関連づけ - Glamenv-Septzen.net

ややこしいな…。関連付けにも優先順位があるらしい…。

自分の環境の場合、.rb については、 になっていた。上記レジストリの内容が assoc で確認できる内容よりも優先されるので、DOS窓上で .rb を直接実行すると、Ruby 2.0.0 ではなく Ruby 2.4.3 が呼び出されるのだろう。

更に、環境変数PATHには、Ruby 2.2.6 のインストールフォルダが登録されているので、ruby.exe を実行した際は 2.2.6 が使われる。だから、hoge.rb を直接実行した場合と、ruby hoge.rb で実行した場合で、異なるバージョンのRubyが使われるわけで。ややこしい。

とまあ、このように面倒臭いので、「ruby hoge.rb」「python hoge.py」の形で呼ぶことにしよう、.rb や .py を直接実行するのはやめておこう、とルールを決めて使っていたりするのでした…。
*1: おそらくPythonのインストール時、色んなバージョンをインストールすることが前提だったから、「関連付けする?」のチェックボックスを外した状態でインストールしたのだろう。
*2: Windows10 バージョン 1803 の場合、スタートボタン → 設定 → アプリ → 既定のアプリ → ファイルの種類ごとに既定のアプリを選ぶ、で関連付けを確認できる…のかと思ったけれどコレもちょっと不十分らしい。

#3 [ruby] Ruby2.4、2.5をWindows上にインストール

したとメモ。環境は Windows10 x64。インストールした版は、以下の2つ。
_RubyInstaller for Windows

どの時期から導入されたのか分からないけど、今現在の RubyInstaller は、DevKit 付きの版と付いてない版の2つが配布されているっぽい。以前は MSYS2 のインストールが必要だった記憶があるのだけど、これで導入が随分簡単になった、ような気がする。もっとも、DevKit と呼んでるけど実際は MSYS2 が入るようだけど。

今回は DevKit付き版をインストール。インストールしたフォルダの中を覗いてみると、msys32 というフォルダがあって、中に MSYS2 関係のファイルがごっそり入ってた。Rubyインストールフォルダ全体で、950MB前後。Ruby2.3以前と比べたらファイルサイズは大きいけど、別途MSYS2をインストールした場合より小さくなっている、ような気がするけどちょっと自信無し。自分の環境は C:\msys32 も入ってるので、そっちのファイルも流用してたら総容量はちょっと分からなくなるよなと…。

拡張ライブラリがビルドできるか確認してみたいのだけど…。以前試した Nokogiri は、mingw32版用のバイナリが配布されるようになったらしくて、gem install nokogiri をしてもビルドの処理は走らなかった。ありがたや。

それはさておき、何を入れてみればビルド処理が走るのか…。

2018/11/11() [n年前の日記]

#1 [anime] 砂嵐ノイズとベリノイズ

プリキュアを見ていたら、 _ベリノイズ(ドロップノイズ) だか _ブロックノイズ だか _グリッチアート だか、そういう感じの映像が演出として使われていて、なんだか感心してしまったり。幼児向けアニメでもこういう見せ方をする時代になったか…。いや、逆か。むしろ子供向け・幼児向けだからこそ、今現在、実際に見かける映像ノイズを出さないといかんのか。

そういえば、先日までNHKで放送されてた進撃の巨人3期でも、ベリノイズ・ブロックノイズを使ってたな…。一瞬アンテナがおかしくなった・放送信号が途切れたのかと驚いた直後に演出と気付いて、これまた感心してしまったわけで。

映像ノイズはリトマス試験紙、かもしれない。 :

考えてみれば、昭和世代にとって映像ノイズと言えば砂嵐ノイズだけど、デジタル放送に移行してしまった現在において、そんなノイズはもうこの世に存在しないのだよな…。

つまり、アニメ演出家さんが、現代もしくは未来設定の作品内で砂嵐ノイズを平気で出してきたら、その方は知識をアップデートできてないし、自分の周囲の光景の変化もさっぱり観察していない、ちょっとアレな演出家さんであると ―― そんなリトマス試験紙になりそうだなと思えてきたりもして。

もちろん、例えば昭和を舞台にした作品内で、劇中のTV画面の中でデジタル系の映像ノイズを出してしまったらそれもそれでおかしいわけで。そういうミスは、若い演出家さんがうっかりやってしまいそう。「えっ? 映像ノイズってこういうのでしょ? 一体何がおかしいんですか?」などとキョトンとしたりして。

さらに遡って、TVが普及してなかった時代を想像すると、当時は砂嵐ノイズも存在しないわけで。その頃の映像ノイズと言えば、フィルムの同期(?)が取れてないとか、糸くずが画面に映るとか、縦線が入りっぱなしになるとか、そんな感じだろう…。そのあたりも、子供の頃からTVを見て育った世代の作り手がうっかりやりそうなミス、だったりして。

と思ったけれど、さすがに映像作家を志す人達がそういうミスをしちゃう場面なんて見かけないわな。色々な過去の作品を眺めていれば、その当時の映像ノイズはどういうものか、フツーに把握できるし。

もし、そういううっかりミスをやってしまう演出家が居たら、その人は既存の映像作品をほとんど見ていない、とんでもなく不勉強な人なのだと発覚してしまう…。

映像ノイズを使った表現って、ちょっと油断できないところがありそうだな、と。

未来の映像ノイズ。 :

将来、デジタル的な映像圧縮技術が更に進歩していくと、CD等と同様に、データが壊れてることが分かりづらくなるエラー訂正技術がそれなりに盛り込まれて、ベリノイズ、ドロップノイズ、ブロックノイズなんてまず見かけない状態になるのかもしれない。壊れた部分を、周囲の正常な画素を利用して、あるいは前後のフレームを利用して、とてもイイ感じに補間してしまう、とか。

となると、見た目では、壊れた部分だけかすかに解像度が下がってるとか、不自然なぼかしが入ってるように見えるとか、フレーム補間を頑張り過ぎてモーフィングっぽい不自然な動きになる瞬間がある、てな感じの映像ノイズになるのだろうか。もはやノイズと呼べるのか疑問だけど…。ひょっとすると、未来世界を舞台にしたアニメの中では、そんな映像だって使えるかもしれないなと。

もっとも、未来世界を舞台にしたアニメの中でも、素直にブロックノイズを出したほうが視聴者には分かりやすいのかな。大半の視聴者は、未来世界で使われている映像圧縮技術について想像を巡らせたりしないし。現代の視聴者に、映像データが壊れてる状況を伝えたいなら、現代の壊れ方をそのまま見せたほうが伝わりそうな気がする。だけどSFモノが好きな視聴者からは、「未来世界でもmpeg圧縮かよ。SF考証サボり過ぎ」とツッコまれたりして…。

未来は未来でも、例えばスチームパンクっぽい世界では、映像ノイズはどうなるのだろう。その場合、やはりフィルムのソレになるのかな。あるいは…。どういうノイズなら、それっぽく感じられるのだろうか。そもそも、スチームパンクな世界で使われている映像記録媒体が想像できないな…。何を使って記録してたらスチームパンクっぽいのか…。

2018/11/12(月) [n年前の日記]

#1 [tic80] TIC-80で音楽を止める方法が分からず

無料で使える Fantasy Console (架空のゲーム機)、 _TIC-80 上で、ゲームに見えそうな何かを書こうとしているのだけど。音楽(music)の止め方が分からない…。再生の仕方は分かるのだけど…。停止はどうやるんだ…?

_music - nesbox/TIC-80 Wiki

2018/11/13追記。 :

以下の作例を眺めてみたら、musicの停止の仕方が分かった。引数無しで music() を呼び出せば停止するのだな。

_Play ATARI BASS DEMO in TIC-80

というか、 _music - nesbox/TIC-80 Wiki にも書いてあった。
It starts playing the track created in the Music Editor.

Call without arguments to stop the music.

music ・ nesbox/TIC-80 Wiki より


つまりこういうことか…。
music(0)  -- play music (tack 0)

music(0,0)  -- play music (tack 0, frame 0)

music()  -- stop music

ただ、試しに music(0,0,0,true) と打ったら、最初の一音が鳴らなくて。何故。まあ、music(track番号) で鳴るから、いいか…。

2018/11/13(火) [n年前の日記]

#1 [tic80] TIC-80でゲームっぽい何かを書いてみた

_TIC-80 を触り始めたことだし、せっかくだからゲームっぽい何かを書いてみようかなと。

しかし何を書こうか…。と悩んだところで、ふと、昔の _「るびま(Rubyist Magazine)」 で公開されていた、Ruby/SDL のサンプルゲームっぽいものを書いてみたらどうだろうと思いついたわけで。上から林檎 or 爆弾が落ちてくるので、プレイヤーキャラを操作して林檎だけキャッチする、というゲーム内容。

_Ruby/SDLで始めるゲームプログラミング【前編】
_Ruby/SDL で始めるゲームプログラミング【後編】

てなわけで、TIC-80上でも書いてみました。環境は、Windows10 x64 + TIC-80 0.70.6。

newtototone_ss2.gif

ブラウザ上で動かせます。以下をクリックすれば動くかなと。(音が出ます。)

_newtototone.tic.html

画像やソースを見たいときは、ブラウザ上で動かしてる状態でESCキーを押すとメニューが出てくるので、「CLOSE GAME」を選んでZキー(Aボタン)。その後、F1 〜 F5キーを叩けば、ソースや画像が見れるはず。

余談だけど。ローカルのTIC-80で動かした場合と、ブラウザ上で動かした場合で、疑似乱数の出方が違うようだなと…。ローカルで動くLuaと、ブラウザ上で動くJavaScriptは、疑似乱数の処理がそれぞれ違うのかもしれない…。

一応 .tic(TIC-80のファイル形式)も、 zip にして置いときます。

_newtototone_20181113.zip

ソース。 :

一応ソースも貼り付けておくのです。

-- title:  NEWTOTOTONE
-- author: mieki256
-- desc:   It's a game to catch an apple.
-- script: lua

scrw,scrh=240,136

Player={}
Player.new=function()
 local obj={
  alive=true,flip=0,
  x=scrw/2,y=scrh-32+8
 }
 setmetatable(obj,{__index=Player})
 return obj
end

Player.init=function(self)
 self.alive=true
 self.x=scrw/2
 self.y=scrh-32+8
 self.flip=0
end

Player.update=function(self)
 if not self.alive then return end
 local spd=2
 if btn(2) then
  self.x=self.x-spd
  self.flip=0
 end
 if btn(3) then
  self.x=self.x+spd
  self.flip=1
 end
 if self.x <= 8 then self.x=8 end
 if self.x >= scrw-8 then
  self.x=scrw-8
 end
end

Player.draw=function(self)
 local id
 if self.alive then
  id=1+t%60//30*2
 else
  id=9
  self.flip=t%20//10
 end
 local x,y=self.x-8,self.y-8
 spr(id,x,y,14,1,self.flip,0,2,2)
end

Item={}
Item.new=function(_x,_y,_kind)
 local obj={
  alive=true,
  x=_x,y=_y,dx=0,dy=0,
  hit=false,kind=_kind,
  sprid=5
 }
 if _kind==1 then obj.sprid=7 end
 setmetatable(obj,{__index=Item})
 return obj
end

Item.update=function(self)
 self.x=self.x+self.dx
 self.y=self.y+self.dy
 self.dy=self.dy+0.3*9.8/60.0
 if self.y >= scrh then
  self.y=-16
  self.dy=0
  self.alive=false
 end
 if self.hit then
  if self.kind==0 then
   score=score+10
   bornInfo(self.x,self.y,10)
  end
  self.alive=false
 end
end

Item.draw=function(self)
 if self.alive then
  spr(self.sprid,self.x-8,self.y-8,
      14,1,0,0,2,2)
 end
end

Info={}
Info.new=function(_x,_y,_str)
 local obj={
  alive=true,
  x=_x,y=_y,str=_str,timer=0
 }
 setmetatable(obj,{__index=Info})
 return obj
end

Info.update=function(self)
 self.y=self.y-0.5
 self.timer=self.timer+1
 if self.timer>30 then
  self.alive=false
 end
end

Info.draw=function(self)
 print(self.str,self.x+1,self.y+1,0)
 print(self.str,self.x,self.y,15)
end

function bornInfo(_x,_y,_score)
 local info=Info.new(_x,_y-16,"+".._score)
 table.insert(infos,info)
end

function hitcheck(p,objs)
 for i,spr in ipairs(objs) do
  local dx,dy,dist
  dx=math.abs(spr.x-p.x)
  dy=math.abs(spr.y-p.y)
  if spr.kind==0 then
   if dx<=8 and dy<=8 then
    spr.hit=true
    sfx(1, "C-5")
   end
  elseif spr.kind==1 then
   if (dx*dx+dy*dy)<(8*8) then
    spr.hit=true
    p.alive=false
   end
  end
 end
end

function updateSprites(objs)
 for i,spr in ipairs(objs) do
  spr:update()
 end
end

function removeSprites(objs)
 local elen=#objs
 for i=elen,1,-1 do
  if not objs[i].alive then
   table.remove(objs,i)
  end
 end
end

function drawSprites(objs)
 for i,spr in ipairs(objs) do
  spr:draw()
 end
end

function printCt(_s,_y,_scale)
 local w=print(_s,0,-6)
 local x=(scrw-(w*_scale))//2
 local a=_scale
 print(_s,x+a,_y+a,0,false,_scale)
 print(_s,x,_y,15,false,_scale)
end

score=0
hiscore=0
gmstep=0
t=0
brate=100

player=Player.new()
items={}
infos={}

PALADDR=0x3FC0+14*3
R1,G1,B1=0x59,0x7D,0xCE
R2,G2,B2=0x6D,0xC2,0xCA

function SCN(row)
 -- sky gradient
 local d,hh,h
 hh=scrh-8*4
 h=hh*0.75
 if row<h then d=0
 elseif row>hh then d=1
 else d=(row-h)/(hh-h) end
 poke(PALADDR,R1+(R2-R1)*d)
 poke(PALADDR+1,G1+(G2-G1)*d)
 poke(PALADDR+2,B1+(B2-B1)*d)
end

function TIC()
 if gmstep==0 then
  -- title
  if btnp(0) then
   gmstep=1
   score=0
   brate=100
   music(0)
   math.randomseed(0)
  end
 elseif gmstep==1 then
  -- game main
  hitcheck(player,items)
  player:update()

  -- born item
  if t%60==0 then
   brate=brate-1
   if brate<=1 then brate=100 end
  end
  if t%8==0 then
   local ex,b,k,item
   ex=math.random(8,scrw-8)
   b=math.max(20,brate)
   k=(math.random(100)>b) and 1 or 0
   item=Item.new(ex,-16,k)
   table.insert(items,item)
  end
 
  updateSprites(items)
  updateSprites(infos)
  
  removeSprites(items)
  removeSprites(infos)
  
  if score>hiscore then
   hiscore=score
  end
  
  if not player.alive then
   gmstep=2
   t=0
   sfx(2,"C-5")
   music()  -- music stop
  end
 elseif gmstep==2 then
  -- game over
  if t>=60+30 then
   player:init()
   gmstep=0
   items={}
   infos={}
  end
 end

 -- draw 
 cls(14)
 map(0,0,30,17,0,0,14)
 player:draw()
 drawSprites(items)
 drawSprites(infos)
 print("SCORE: "..score,4,2)
 print("HI-SCORE: "..hiscore,120,2)
 
 if gmstep==0 then
  printCt("NEWTOTOTONE",52,2)
  printCt("MOVE: LEFT,RIGHT KEY",84,1)
  printCt("PUSH UP KEY TO START",94,1)
 elseif gmstep==2 then
  printCt("GAME OVER",54,2)
 end
 
 t=t+1
end

  • 〜.new が、クラスのインスタンス発生+初期化処理
  • 〜.update が更新処理(1秒間に60回呼ばれる)
  • 〜.draw が描画処理
と思って眺めれば、やってることがなんとなく分かるはず。

ちなみに、Lua はまだ全然勉強中なので、本来ならクラスの継承を使うべきところで使ってなかったり。精進します。

宿題。 :

これだけではゲームとして全然面白くないよなと…。プレイしていて、なんだか修行僧になった気分…。

さて、どうすれば、ちょっとは面白くなるのだろうか…。

例えばだけど…。
  • 時間制限をつけて、1分以内に何点稼げるかで競う感じにするとか。
  • 地面の上に蛇でも出すとか。プレイヤーキャラはジャンプで避けるとか。あるいは弾を撃って蛇を倒すとか。
  • フィーバータイムをつけるとか。何かを取ると一定時間、全てが林檎に変化したり。
  • ステージを設けるとか。ある程度取るとステージクリア。
  • 長くプレイしてると背景が変わってくるとか。徐々に夕焼けになったり、夜空になったり。

何にせよ、この段階では「変化」「ご褒美」が無いよなと…。ゲームにおいて「ご褒美」は大事。皆、何かしらの「ご褒美」が欲しくてプレイするわけだから…。

#2 [tic80] TIC-80で画面キャプチャ

TIC-80を動かしていて、動作画面をキャプチャしたいと思った際、F9キーを押すとGIFアニメとしてキャプチャできると知ったのでメモ。

F9キーを叩くと、画面の右上のほうに、記録中のアイコンが表示される。

tic80_gifanime_cap_mark_ss.gif

一定時間キャプチャするとファイル保存ダイアログが開いて、GIFアニメとして保存できる。

キャプチャ時間は、config を弄ることで変更できるっぽい。入力待ち画面で config[Enter] と打つと設定ファイルがロードされて、F1キーを押してエディタを開くと設定ファイルを開くことができる。

以下が、関係してる記述だろうか。(TIC-80 0.70.6 の場合。)
GIF_LENGTH=20 -- in seconds
GIF_SCALE=2

出力されたGIFアニメの各フレームには、2/100secのwait値が入ってた。60FPSなら1フレーム約16.67msになるので、GIFアニメに指定できるwait値としては妥当な気がする。

ただ、出力ファイルサイズが異様に大きい。そのままだと、10MBぐらいのGIFアニメになってしまった。 _EZGIF.COM を利用させてもらって、不要なフレームの削除、及び、最適化をしたら、810KBぐらいになった。

ちなみに、実行画面を _OBS Studio を使ってデスクトップ画面ごとキャプチャして、切り出して mp4 にしてみたところ、約900KBぐらいになった。mp4 なら音声まで入ってることを考えると、GIFアニメ以外にも mp4 にしてblog等に貼る選択肢もアリなのかもしれないなと。

#3 [prog] 「Hello world」の次の課題の候補が欲しい気もする

思考メモ。

プログラミングの世界には、「Hello world」というお題があって。

「コンソール上(あるいはウインドウ内)に、『Hello World』と表示してみよう!」というお題なのだけど。自分が知らない言語やライブラリを使う際には、まずは「Hello world」をやってみる、というのがよくある流れ、だったりするわけで。

非プログラマーさんからは、「えっ? たったそれだけの課題なの?」と思われるかもしれないけれど。コレ、意外と大事な課題で。

「Hello world」をするためには、開発環境の構築・導入が必要で。コンパイルをする言語なら、コンパイラだの何だのをインストールしなきゃいけない。つまり、「Hello world」と表示できた段階で、「これで開発環境の構築は終わったよ」「さあ、後は各自、目的のプログラムを書くだけだよ」という状態になる。「Hello world」すらできないようでは、その先のプログラミングもへったくれもないのです。

しかし…。「Hello world」が終わった段階で、「さあ、環境構築はできたぞ。…さて、ここから一体何を書こうかなあ。どうしよう」と悩んじゃうときも…あるよなと。

「そんな馬鹿な。何かを作りたくて環境構築したんでしょ? その何かを書き始めればいいじゃん」と思われるかもしれないけれど。意外とそういう流れじゃない時もあって…。「お? なんだかコレ面白そうだな。少し触ってみるか」なんて動機で、自分にとっては未知の言語・ライブラリを試してみる、てな時もあるわけですよ。

そういうときに、ちょっと困っちゃう。次の段階に進みたいけど、適切なお題が思いつかないのだよなあ。みたいな。

そういったことを考えると、 _「るびま(Rubyist Magazine)」 で紹介されてた、Ruby/SDLのサンプルゲームの仕様 ―― 上から落ちてくる何かをひたすら拾うというゲーム内容は、ゲームプログラミングのお題としては結構イイ感じかもしれない、と。

_Ruby/SDLで始めるゲームプログラミング【前編】
_Ruby/SDL で始めるゲームプログラミング【後編】

このサンプル相当を作れば…。 このあたりの基本的な実現方法が一通り分かるわけで。これはなかなか良いお題かもと思えてきたり。

他にも、ヨサゲなお題はないものだろうか…。

自分の場合はゲームプログラミングについて考えちゃうけど、例えばWebサービス作成版の、「Hello world」の次のお題、とかあっても良さそうだよな…。

電子工作なら、Lチカ(LEDをチカチカさせるアレ)の次のお題、とか。

もっとも、見るからに面白そうと感じられたり、あるいは発展させるとこうなりそう的な想像ができるお題じゃないと、モチベーションが出てこないか…。

昔見かけたお題。 :

某社の新人研修時に出されたお題も、基本を学ぶ分にはなんだか良さそうだな、と思い出したりして。
  • 横スクロールシューティングゲームを作れ。
  • 自機はカーソルキーで上下左右に動く。
  • 自機は弾を撃てる。
  • 雑魚敵は画面内に複数出てくる。
  • 雑魚敵は自機の弾で消せる。
  • 雑魚敵を4種類実装しろ。
  • 雑魚敵Aは、画面右から出現。sinカーブで飛んでくる。
  • 雑魚敵Bは、画面右から出現。自機を追いかける。
  • 雑魚敵Cは、画面左から出現。放物線を描いて画面左に帰っていく。
  • 雑魚敵Dは、(仕様失念)
こんな感じの課題…だった気がする。大昔のことだからちょっと記憶が怪しいけれど。たしか、PC-9801上でスプライト相当を描画できるライブラリと、自機、弾、雑魚敵のドット絵データを渡されて、この課題を2週間でクリアせよ、みたいな。 *1

この課題をやると、何が身につくのだろう…。
  • 画面内に複数のオブジェクトを出して動かす仕組み、の基本を学べる。
  • 速度と加速度の使い方を学ぶ。
  • 角度から速度を求めて使うやり方を知る。(三角関数の復習。)
そんな感じなのかな…。

もっとも、今時はそのあたりフレームワーク云々で用意されてそうな気もする。今時の環境に合ったお題となると、どういった内容になるのだろう。

*1: まあ、研修を受けていたほとんどの人は数日で課題をクリアして、残り時間は各々が好き勝手な仕様を追加して遊んでたけど…。

2018/11/14(水) [n年前の日記]

#1 [tic80] TIC-80でシューティングゲームっぽいものを書いてみようかなと

せっかくだからTIC-80上で横スクロールシューティングっぽいものを書いてみようかなと。環境は、Windows10 x64 + TIC-80 0.70.6。

自機の移動。 :

まずは、自機の移動処理。カーソルキーでスプライトを動かすあたりを書いてみる。ついでに、後々のことも考えて、Playerクラスを作って分離してみる。

stgsample1_ss1_opt.gif

-- title:  stg sample 1
-- author: mieki256
-- desc:   short description
-- script: lua

scrw,scrh=240,136

-- ----------------------------------------
-- Player class
Player={}
Player.new=function()
 local o={
  alive=true,
  x=scrw/2,
  y=scrh/2,
  sprid=5
 }
 setmetatable(o,{__index=Player})
 return o
end

Player.update=function(self)
 local spd=2.0
 local dx,dy=0,0
 if btn(0) then dy=-spd end
 if btn(1) then dy=spd end
 if btn(2) then dx=-spd end
 if btn(3) then dx=spd end
 if dx~=0 and dy~=0 then
  local d=math.cos(math.rad(45))
  dx=dx*d
  dy=dy*d
 end
 self.x=self.x+dx
 self.y=self.y+dy
 self.x=math.min(math.max(self.x,8),scrw-8)
 self.y=math.min(math.max(self.y,8),scrh-8)
end

Player.draw=function(self)
 local x,y=self.x-8,self.y-8
 spr(self.sprid,x,y,14,1,0,0,2,2)
end

-- init

score=0
t=0
player=Player.new()

-- main loop

function TIC()
 player:update()

 cls(0)
 player:draw()
 print("SCORE: "..score,2,2)
 t=t+1
end

TIC-80上で new と打てば Hello world相当がロードされた状態になるので、F1キーを押してエディタを表示してソースを眺めれば、カーソルキーの入力や、スプライト描画のやり方はすぐわかるのだけど…。

8方向に動かす際には、斜め移動の距離について、ちょっと注意しないといけない。詳しくは以下を参考に…。

_アナログ入力の斜め補正
_第5回 キー入力によってキャラクタを8方向へ動かす | TAKABO SOFT
_斜めに移動させる | ゲームプログラミング入門〜bituse〜

とりあえず今回は、斜め移動の時だけ、math.cos(math.rad(45)) を掛けた値を自機の移動量にしてみたり。
 if dx~=0 and dy~=0 then
  local d=math.cos(math.rad(45))
  dx=dx*d
  dy=dy*d
 end

ちなみに以下の行は、画面外に自機が出ていかないようにしている。
 self.x=math.min(math.max(self.x,8),scrw-8)
 self.y=math.min(math.max(self.y,8),scrh-8)
math.min(v1, v2) は最小値、math.max(v1, v2) は最大値を取得できる。 _Lua言語のライブラリ関数 の、 _math.min_math.max が参考になる、かなと。

弾を撃つ。 :

自機から弾を撃ってみる。弾を担当する Bulletクラスを作って、一定時間毎に発生させる。

stgsample2_ss1_opt.gif

-- title:  stg sample 2
-- author: mieki256
-- desc:   short description
-- script: lua

scrw,scrh=240,136

-- ---------------------------------------
-- Player class

Player={}
Player.new=function()
 local o={
  alive=true,
  x=scrw/2,
  y=scrh/2,
  sprid=5
 }
 setmetatable(o,{__index=Player})
 return o
end

Player.update=function(self)
 local spd=2.0
 local dx,dy=0,0
 if btn(0) then dy=-spd end
 if btn(1) then dy=spd end
 if btn(2) then dx=-spd end
 if btn(3) then dx=spd end
 if dx~=0 and dy~=0 then
  local d=math.cos(math.rad(45))
  dx=dx*d
  dy=dy*d
 end
 self.x=self.x+dx
 self.y=self.y+dy
 self.x=math.min(math.max(self.x,8),scrw-8)
 self.y=math.min(math.max(self.y,8),scrh-8)
 
 -- shot
 if t%6==0 then
  local x,y=self.x,self.y
  spd=6
  table.insert(bullets,Bullet.new(x,y,spd,0))
  table.insert(bullets,Bullet.new(x,y,spd,12))
  table.insert(bullets,Bullet.new(x,y,spd,-12))
  table.insert(bullets,Bullet.new(x,y,spd,180))
 end
end

Player.draw=function(self)
 local x,y=self.x-8,self.y-8
 spr(self.sprid,x,y,14,1,0,0,2,2)
end

-- ---------------------------------------
-- Bullet class

Bullet={}
Bullet.new=function(_x,_y,_spd,_ang)
 local o={
  alive=true,
  x=_x,y=_y,spd=_spd,ang=_ang,
  sprid=7
 }
 local ra=math.rad(_ang)
 o.dx=_spd*math.cos(ra)
 o.dy=_spd*math.sin(ra)
 setmetatable(o,{__index=Bullet})
 return o
end

Bullet.update=function(self)
 self.x=self.x+self.dx
 self.y=self.y+self.dy
 if self.x<-16 or self.x>scrw+16 or
    self.y<-16 or self.y>scrh+16 then
  self.alive=false
 end
end

Bullet.draw=function(self)
 local x,y=self.x-4,self.y-4
 spr(self.sprid,x,y,0,1,0,0,1,1)
end

-- ----------------------------------------

function objsUpdate(objs)
 for i,o in ipairs(objs) do
  o:update()
 end
end

function objsDraw(objs)
 for i,o in ipairs(objs) do
  o:draw()
 end
end

function objsRemove(objs)
 local l=#objs
 for i=l,1,-1 do
  if not objs[i].alive then
   table.remove(objs,i)
  end
 end
end

-- init

score=0
t=0
player=Player.new()
bullets={}

-- main loop

function TIC()
 player:update()
 objsUpdate(bullets)
 objsRemove(bullets)

 cls(0)
 objsDraw(bullets)
 player:draw()
 print("SCORE: "..score,2,2)
 print("bullets: "..#bullets,120,2)
 t=t+1
end

Bulletクラスの他にも、複数のオブジェクトを処理する関数、objsUpdate()、objsDraw()、objsRemove() を書いた。また、プレイヤーの更新処理(update())の中で、一定時間毎に弾を発生させる処理を追加した。

弾は、初期座標、速度、角度(方向)を与えて発生させている。弾は、その方向にまっすぐ進んで、画面外に出たら自分の存在フラグ(?)を false にする。後で、objsRemove() が、存在フラグが false になってるインスタンスを探して削除してくれる。

雑魚敵を出す。 :

雑魚敵を出してみる。Zakoクラスを作って、これまた一定時間毎に出してみる。とりあえず、弾と同様に、まっすぐ進むだけの処理を書いておいた。

stgsample3_ss1_opt.gif

-- title:  stg sample 3
-- author: mieki256
-- desc:   short description
-- script: lua

scrw,scrh=240,136

-- --------------------
-- Player class

Player={}
Player.new=function()
 local o={
  alive=true,
  x=scrw/2,
  y=scrh/2,
  sprid=5
 }
 setmetatable(o,{__index=Player})
 return o
end

Player.update=function(self)
 local spd=2.0
 local dx,dy=0,0
 if btn(0) then dy=-spd end
 if btn(1) then dy=spd end
 if btn(2) then dx=-spd end
 if btn(3) then dx=spd end
 if dx~=0 and dy~=0 then
  local d=math.cos(math.rad(45))
  dx=dx*d
  dy=dy*d
 end
 self.x=self.x+dx
 self.y=self.y+dy
 self.x=math.min(math.max(self.x,8),scrw-8)
 self.y=math.min(math.max(self.y,8),scrh-8)
 
 -- shot
 if t%6==0 then
  local o
  local x,y=self.x,self.y
  spd=6
  table.insert(bullets,Bullet.new(x,y,spd,0))
  -- table.insert(bullets,Bullet.new(x,y,spd,12))
  -- table.insert(bullets,Bullet.new(x,y,spd,-12))
  -- table.insert(bullets,Bullet.new(x,y,spd,180))
 end
end

Player.draw=function(self)
 local x,y=self.x-8,self.y-8
 spr(self.sprid,x,y,14,1,0,0,2,2)
end

-- --------------------
-- Bullet class

Bullet={}
Bullet.new=function(_x,_y,_spd,_ang)
 local o={
  alive=true,
  x=_x,y=_y,spd=_spd,ang=_ang,
  sprid=7
 }
 local ra=math.rad(_ang)
 o.dx=_spd*math.cos(ra)
 o.dy=_spd*math.sin(ra)
 setmetatable(o,{__index=Bullet})
 return o
end

Bullet.update=function(self)
 self.x=self.x+self.dx
 self.y=self.y+self.dy
 if self.x<-16 or self.x>scrw+16 or
    self.y<-16 or self.y>scrh+16 then
  self.alive=false
 end
end

Bullet.draw=function(self)
 local x,y=self.x-4,self.y-4
 spr(self.sprid,x,y,0,1,0,0,1,1)
end

-- --------------------
-- Zako enemy class

Zako={}
Zako.new=function(_x,_y,_spd,_ang)
 local o={
  alive=true,x=_x,y=_y,
  spd=_spd,ang=_ang,
  sprid=1,t=0
 }
 local ra=math.rad(_ang)
 o.dx=_spd*math.cos(ra)
 o.dy=_spd*math.sin(ra)
 setmetatable(o,{__index=Zako})
 return o
end

Zako.update=function(self)
 self.x=self.x+self.dx
 self.y=self.y+self.dy
 self.t=self.t+1
 if self.x<-32 or self.x>scrw+32 or
    self.y<-32 or self.y>scrh+32 then
  self.alive=false
 end
end

Zako.draw=function(self)
 local x,y=self.x-8,self.y-8
 spr(self.sprid,x,y,14,1,0,0,2,2)
end

-- --------------------

function objsUpdate(objs)
 for i,o in ipairs(objs) do
  o:update()
 end
end

function objsDraw(objs)
 for i,o in ipairs(objs) do
  o:draw()
 end
end

function objsRemove(objs)
 local l=#objs
 for i=l,1,-1 do
  if not objs[i].alive then
   table.remove(objs,i)
  end
 end
end

function bornEnemys()
 if t%50==0 then
  for i=1,3 do
   local o,spd,ang,x,y
   spd=1.5
   x=scrw+16
   y=math.random(8,scrh-8)
   ang=180+25*((y-(scrh/2))/(scrh/2))
   o=Zako.new(x,y,spd,ang)
   table.insert(enemys,o)
  end
 end
end

-- init

score=0
t=0
player=Player.new()
bullets={}
enemys={}

-- main loop

function TIC()
 bornEnemys()
 player:update()
 objsUpdate(bullets)
 objsUpdate(enemys)
 objsRemove(bullets)
 objsRemove(enemys)

 cls(0)
 objsDraw(enemys)
 objsDraw(bullets)
 player:draw()
 print("SCORE: "..score,2,2)
 print("enemys: "..#enemys,120,2)
 t=t+1
end

さて、弾を撃って、雑魚敵も出せたから、アタリ判定を入れたくなるなと…。

とりあえず、今日はここまで。ブラウザ上で動く版は以下。

_stgsample3.tic.html

2018/11/15(木) [n年前の日記]

#1 [windows][cg_tools] 高速にGIFアニメを再生できるビューアはないのだろうか

TIC-80の動作画面をGIFアニメとしてキャプチャしても、正常に再生・描画できるビューアが見当たらなくて、ちょっと困ったり。1フレームあたり、2/100秒のwaitが入ってるはずだけど…。

Windows10 x64上で、 _IrfanView 4.51_nomacs 3.10_XnView 2.46_MassiGra 0.45 を使って表示してみたけれど、どうにも再生速度が遅い。Webブラウザ(Waterfox 56.2.5, Google Chrome 70.0.3538.102, Internet Explorer 11)上ではそれらしい速度で再生されるのだけど。

GIFアニメ専用を謳う、 _GIF Viewer_7GIF 1.2.2 を使って再生確認してみたけれど、やはり遅い。

色々試してみたけれど、 _Honeyview 5.31 と、Windows10 に標準で入ってる「フォト」の2つだけが、Webブラウザと同等の速度で再生できた。

GIFアニメが誕生してから結構な年数が経ってるはずだけど、まさかローカルで動くビューアの類ですら、ここまで不十分な対応状況だったとは…。

もっとも、GIFアニメは、「ブラウザ上でそれらしく表示できれば後はどうでもいいじゃん」てな扱いを受けている画像フォーマット、ということでもあるのだろうな…。Web上でしか使われていない気もするし。

#2 [zatta] 天井には広大なスクリーンが眠っている

気になる製品ニュースを見かけた。

_セガトイズ、子どもをスムーズに寝かし付けられる「動く絵本プロジェクター」 - 家電 Watch

個人的に、プロジェクターの類がちょっと気になったりする時期がチラホラあったりするのだけど。自分の部屋は散らかってるので、大きなスクリーンを設置・展開する場所も無いし、これじゃ導入できないよなあ、と毎回諦めていたりするわけで。

しかし、前述の製品ニュースを目にして、その手があったかと…。天井って、全然使ってないよなあ…。日本の各御家庭において、天井には広大なスクリーンが眠っている…のかもしれない。

気になってググってみたけど、上に向かって投影可能な製品って意外と少ないのだろうか…。排熱の問題もあるだろうから、製品によっては「そんな使い方は想定してません。壊れます」と設計者から言われそう。下手したら寝落ちしてるうちに製品が燃え出して火事になったりして。

_the360.life - 壁が、天井が、スクリーンになる! 寝室で映画を観るための新アイデア
_天井にも投影可能な『DBPOWER ミニプロジェクター』がコスパ抜群!!
_プロジェクタで天井に映像を投影!寝ながら映画を見るならこのモデル!

2018/11/16(金) [n年前の日記]

#1 [tic80] TIC-80でシューティングゲームっぽいものを書いてみる。その2

先日、TIC-80上で動く横スクロールシューティングっぽいモノを書き始めたけれど、アタリ判定もつけてみた。

stgsample5_ss1_opt.gif

ブラウザ上で動かしたいなら以下。

_stgsample5.tic.html

操作方法。

ソース。 :

ソースは以下。長くなり始めたので Gist にアップロードしてみた。

_TIC-80 shoot 'em up sample

スプライト画像は以下。

sprites.gif

_sprites.gif

ソースも画像も、CC0 / Public Domain ってことで。

ちなみに。
  • export sprites で、スプライト画像のエクスポート。
  • import sprites で、スプライト画像のインポート。
以下が参考になった。ありがたや。

_TIC-80 初心者講座: マップ・スプライト画像を画像ソフトで描いて取り込もう - Qiita

ソースの簡単な解説。 :

アタリ判定は、hitcheck()、hitcheckCirc() で処理をしている。
function hitcheckCirc(e,b)
 if not next(b.collision) then
  return false
 end
 local x,y,r
 x=e.collision[1]-b.collision[1]
 y=e.collision[2]-b.collision[2]
 r=e.collision[3]+b.collision[3]
 if x*x+y*y <=r*r then return true end
 return false
end

function hitcheck()
 -- enemys vs bullet
 for i,e in ipairs(enemys) do
  if e.alive and next(e.collision) then
   for j,b in ipairs(bullets) do
    if b.alive and hitcheckCirc(e,b) then
     e:hit(b)
     b:shot(e)
     break
    end
   end
  end
 end

 if player.alive==false or
    not next(player.collision) then
  return
 end

 -- enemys vs player
 -- ...

 -- enemy bullets vs player
 -- ...
end

判定の仕方は色々あるけど、今回は、点と点の距離で判定。
 if x*x+y*y<=r*r then return true end
 return false
敵と弾、敵と自機、等、x座標とy座標の差が得られれば、 _三平方の定理 で距離は求められる。式に平方根が入ってくるけど、今回は正確な距離を求めたいわけじゃなく、任意の距離より近いか遠いかを知りたいだけなので、判定に使う距離を二乗して比較に使えば平方根を求めなくて済む。

アタリ判定用のデータは、 _DXRuby Sprite#collision= を参考に、{x,y,r} を各クラスで持つことにした。

ちなみに、Lua で、テーブルが空かどうかを判定する際は next(テーブル名) が使えるらしい。

_Lua ちょっとしたコードチューニング - Qiita

#2 [tic80] TIC-80用のソースコードを外部エディタで編集したい

TIC-80は、エディタ、スプライトエディタ(ドットエディタ)、マップエディタ、サウンドエディタ、ミュージックエディタ ―― 全部入っているので、気軽に触り始めることができて便利なのだけど。しかし、エディタが貧弱なので、せめてソースコードを外部エディタで編集出来たらな、と思う時があって。

まあ、お金を出してPro版を買えば、外部エディタで編集することもできるらしいのだけど。そこらへん、無料版でも、ちょっとはどうにかならんか…。

と思ってググっていたら、「ソースコードの一行目に dofile("game.lua") と書けば game.lua を読み込んで使えるよ」という話を見かけて。

_Add the ability to export/import the game code so it can be edited externally - Issue #85 - nesbox/TIC-80
_TIC-80さんのツイート: "TIC tip: if you place your game.lua file near TIC exe, add dofile('game.lua') to the code you can edit game in your favorite editor

なるほど…。その機能を使えば、.lua ファイルを外部エディタで編集できそうだなと。

注意点としては…。 そのあたりは気を付けないといかんらしい。

更に、以下によると「dofile() は非推奨」と書いてあるので、いつまでこの機能が使えるのかは不明。

_Time Tripper: TIC-80の新バージョン(0.50.0)がリリースされました。

試してみた。 :

とりあえず試してみた。環境は Windows10 x64 + TIC-80 0.70.6。

任意のディレクトリを作って、以下のようなファイル構成にして。
.
|-- tic80.exe
|-- stgsample5.lua
`-- stgsample5.tic

DOS窓を開いて、そのディレクトリをカレントディレクトリにして。(cd C:\hoge\fuga)

コマンドラインオプションをつけて、TIC-80を起動。
tic80 .
「.」をつけて起動すると、いつもと違って、カレントディレクトリをストレージ場所にした状態で起動できるらしい。ちなみに、folder と打てばストレージ扱いの場所がエクスプローラで開かれるので、反映されてるかどうかも確認できる。

_Home - nesbox/TIC-80 Wiki
tic80 .                        will use current directory as storage
tic80 ../path/to/cart.tic      will use ../path/to/ as storage and load cart.tic
tic80 -code game.lua           load and run the code without startup animation
tic80 -code-watch game.lua     same as -code but also reload it when TIC is focused
tic80 game.tic -code game.lua  load cartridge, inject the code and run without startup animation

load stgsample5 で、カートリッジ(.tic)をロード。

F1キーを押してエディタに入って、ソースコードを全部消して(Ctrl+Aで全選択、Deleteで消去)、1行目に、dofile("stgsample5.lua") とだけ書いておく。

この状態で Ctrl+R を叩いて実行してみたら、.lua に書かれた内容で動いてくれた。

外部エディタで .lua を修正して、TIC-80上で ESCキー → run をしたら、修正内容が反映された動作になった。

つまり、無料版の TIC-80 0.70.6 でも、外部エディタを使って .lua を編集することが一応可能な状態にできるっぽいなと。

#3 [prog] Luaにcontinueが無いのがツライ

Lua というプログラミング言語には、ループを制御する continue文が無い。

_break文とcontinue文
_continue文 - Wikipedia
_Tips/continue - Lua Memo
_Luaには『continue』は存在しない | とど。

地味にツライ。ループ内の記述が結構グチャグチャになる…。

Lua でもどうにかして continue を使えないかという質問に対して、こういうやり方はどうかと提案してる事例を見かけた。

_loops - Why does Lua have no "continue" statement? - Stack Overflow

どれもなんだかしっくりこない…。

一般的には、continue を呼び出す条件判定に not をつけて、if文で処理を囲むというのが定番だろうけど。Lua 5.2 から goto文が追加されたので、continue というラベルを作ってどうにかする方法が提示されていた。
for i=1,10 do
  if i % 2 == 0 then goto continue end
  print(i)
  ::continue::
end
手元の環境、Windows10 x64 + Lua 5.3.4 で試してみたけど、たしかに動いた。

そういえば、love2d は Lua 5.1相当(LuaJIT)を内蔵してたはずなので、この記述はできないだろうな…。

_Lua 5.1.2 is goto statement possible? - LoVE
_Why isn't Love 0.8.0 on Lua 5.2? - LoVE
_Lua 5.2 released, is there a plan to use it? - LoVE

いや、どうかな。 _LuaJIT Change History を眺めると、LuaJIT 2.0.0-beta11 - 2012-10-16 の時点で Lua 5.2 の goto/labels を追加した、と書いてある。

Windows10 x64 + love2d 11.1 では、LuaJIT 2.0.5 が内蔵されてるっぽいので…。もしかすると goto も使えるのかな…。そのうち試してみよう…。

2018/11/17() [n年前の日記]

#1 [prog] Luaでクラスの継承を書く方法を調べていたり

Luaでクラス相当の継承をするにはどのように記述すればいいのか分からなかったので勉強中。

ググってみたら、色々な書き方があるらしくて、何がなんだか。その中でも以下を参考にして、手元で動作確認。環境は Windows10 x64 + Lua 5.3。

_お気楽 Lua プログラミング超入門
_Luaにおけるオブジェクト指向的記述の検討 - ぱろっと・すたじお

こんな感じだろうか…。
-- スーパークラス

SuperClass = {}
SuperClass.new = function()
 local obj = {}
 obj.a = "SuperClass"
 return setmetatable(obj,{__index = SuperClass})
end

SuperClass.hello = function(self)
 print("I am ".. self.a)
end

SuperClass.thx = function(self)
 print("THX")
end

-- サブクラス

SubClass = {}
setmetatable(SubClass, {__index = SuperClass})
SubClass.new = function()
 local obj = SuperClass.new()
 obj.superclass_hello = obj.hello
 obj.b = "SubClass"
 return setmetatable(obj, {__index = SubClass})
end

SubClass.hello = function(self)
 self:superclass_hello()
 print("I am " .. self.b)
end

-- 確認

a = SuperClass.new()
print(a)
a:hello()
a:thx()
print()

b = SubClass.new()
print(b)
b:hello()
b:thx()


実行すると以下のような感じに。
> lua class_inheritance.lua
table: 007e9d30
I am SuperClass
THX

table: 007e9b50
I am SuperClass
I am SubClass
THX
サブクラスから、スーパークラスが持っているメソッドを呼び出せている。

スーパークラスのメソッドを明示的に呼ぶ方法が分からない。Ruby でいうところの super みたいなソレ。前述の記事内で、一旦別名で記憶しておいて使う方法が提示されていたけれど、他にも方法があるのだろうか…。

2018/11/18() [n年前の日記]

#1 [prog][lua] Lua用のエディタとしてGeanyを導入してみたり

TIC-80用のLuaスクリプトソースを外部エディタで書こうとしているのだけど、普段使ってる xyzzy ではちとしっくりこないところがあって。インデントが妙なことになったりとか。

他にヨサゲなエディタは無いのかなとググってみたら、Geany を推してるページを見かけた。Geanyか…。Raspbian (Raspberry Pi の標準的なOS)あたりでも、たしか標準でインストールされているのだよな…。

_Geany : Home Page

Windows版もあるらしいので、試しに Windows10上で導入してみたのだけど。ちと問題が。

現行版の 1.33 をインストールしたら、文字入力をすると何故か半角カタカナになってしまう。この不具合は、GIMP や Inkscape でも見たな…。GTK+ の不具合だよな…。たしか 64bit版では不具合が出なくて、32bit版のGTK+で発生していた気がする。

解決策を紹介してるページに遭遇。ありがたや。

_Geany 1.31のWindowsにおける文字入力か表示の不具合 - 借りてきた猫のように静か

やはりGTK+の不具合らしい。解決策としては、 が有効、らしい。上書きインストールする際に、GTK+ランタイムは選択しない状態でインストールすることで、古い GTK+ が残ってくれる模様。手元の環境で試してみたけれど、文字がちゃんと入力できる状態になった。

Geany のプラグイン集もインストール。

_Plugins for Geany [downloads]

_Geany 1.25 is out! Overview plugin is now included in Geany-Plugins! - Py淡 によると、minimapを表示できる Overview plugin も入ってるらしい。

2018/11/19(月) [n年前の日記]

#1 [pc] メインPC上でデフラグ

最近、Windows10上で、HDDへのアクセスが遅くなってきたような気がしたので、デフラグをかけてみようかと。

試しに UltraDefrag 7.1.1 で、「迅速に最適化する」を選んでみたけれど…。全然迅速じゃない…。240GBのパーティションに対して、10時間ぐらいかかったような…。

処理内容としては、パーティションを5〜6の領域に分けて順々に処理していくようで。
  1. 処理領域の頭から、パーティションの最後にセクタを移動。
  2. 処理領域にある程度の空き領域が出来たら、処理領域の後ろの領域からセクタを持ってきて詰めていく。
  3. 次の領域を対象にして、1〜2を行う。
よくわからないのが、各領域内の全セクタを移動するわけではなく、あちこちに何かをずらりと残した状態で移動する点。どういう基準で、移動するのか、残すのかを決めているのだろう…。

パーティション内全体に、セクタだかファイルだかが、満遍なく配置されてしまうのも気になるところ。空き領域をまとめてくれるわけではないのか…。

#2 [movie] 「ボディ・スナッチャー/恐怖の街」を視聴

メインPCがデフラグ中で使えなかったので、HDDレコーダに録画したままだった映画を今頃視聴。1956年制作のモノクロ映像作品。

いつ放送されたんだっけ…。2017/03/16、と記録されてるな…。たしか、「タイトルからして某ゲームの元ネタだろうか? 一応勉強のつもりで見ておいたほうがいいのかな」的に録画してた気がする。

映像が白黒だったりするぐらいに古い作品なので、さすがに今見ると、ホラー映画というよりギャグ映画だなと…。ただ、基本設定は秀逸で、漫画やアニメでもたまに見かけるソレのような気がしたり。

体験や記憶をアレしてるのに感情が無い、てな台詞のあたりは首を捻ったりもして。そのへんアレできたら感情も自然と芽生えるのではないのか。もしかして、あちらの人達は、感情とは人間という生物だけが獲得できる神聖なものなのだ、てな認識でもあるのだろうか。それとも単に脚本が雑なだけだろうか。

視聴後にググってみて知ったのだけど、古典的名作として扱われていて、何度もリメイクされていたのだな…。知らなかった。

_ボディ・スナッチャー/恐怖の街 - Wikipedia
_映画『ボディ・スナッチャー/恐怖の街』感想とイラスト【ネタバレ有】はじまりはドン・シーゲル | 映画を観たからイラスト描いた
_B級の古典『ボディ・スナッチャー/恐怖の街』やったねドン・シーゲル!/ネタバレなし・感想・あらすじ・解説: レビュー・アン・ローズ

上記ページによると、今回視聴したオリジナル版は…。 そのあたりのエピソードが気になった。たしかに当時、赤狩りをする側は、個々の感情なんて持ち合わせていないように見えていた可能性もありそうな。友人知人との関係性より国の方針を優先して行動、みたいな話だろうし。あるいは逆に、「こっちに来れば楽だよ」「レベルが上がるよ」と勧誘するあたり、赤狩りされる側の言動を連想させる描写だった可能性もあるのだろうか。

ちなみに、リメイク作品は、ちゃんと怖い作品になっているっぽい。

_【ネタバレ】映画「SF/ボディ・スナッチャー」 ネタ・ヴァレー/ウェブリブログ

#3 [tv] 実写ドラマ「学校へ行けなかった私が「あの花」「ここさけ」を書くまで」を視聴

録画したままだったけど、ようやく視聴。NHK BSプレミアムで放送された実写ドラマ、なのかな。2018/09/01に放送したらしい。

_脚本・岡田麿里,主演・前田敦子『学校へ行けなかった私が「あの花」「ここさけ」を書くまで』 | 特集ドラマシリーズ | NHKドラマ

視聴開始数分後に、見るのをやめようかな…と思ってしまったぐらいに、ちと演出がオーバー過ぎてアレだった印象。正直、この内容で、この見せ方は、個人的にキツイなと…。「アニメを見るような映像音痴・味覚音痴連中はこういう極端な見せ方がどうせ好きなんだろ?」とでも演出家に思われてしまったのか。それとも、脚本内に出てくる各台詞が、現実にはちょっとありえない、不自然なわざとらしい言い回しばかりで、「脚本通りに映像化するとしたらこういうデフォルメをするしか…」と悩んだ末にこうなったのか…。どういう思考でこの演出方針になったのか、少し気になる作り、だったような気もしたり。

後半、ゲームの専門学校に入ったあたりや、脚本家としてデビューしてからのエピソードは、フツーに面白かった気がする。そこらへんを膨らませて別作品にできそう。もっとも、学生時代の鬱々としたソレを描写してるからこそ、後半の右肩上がりが面白く感じられたのかもしれない。

脚本は誰だろう、と思いながら眺めてたけど、原作者自ら脚本を担当してたのか…。なんとなく思ったけれど、別の脚本家さんのフィルタを一旦通して客観的な描写や構成に変化させたほうが、映像作品として単体で成立しやすくなるのでは、という気もしたり。本編内の、登校拒否に対する周囲の受け止め方、てなあたりと絡みそうだけど、当人が面白いと感じる部分と周囲が面白いと感じる部分は違ったりするものだし。とはいえ、原作者自ら脚本も担当、と打ち出すほうが企画の売りになりそうでもあるなと…。せっかくそこに有名な脚本家が居るのだから使わない手はないだろうし。原作者も、他人に改悪されるぐらいなら自分でやるわい、と思いそうだし…。

さておき。個人的に、自分の好き嫌いは別にして、この原作者の作家性 ―― 時折チラリと出現する妙な生々しさを伴う描写は、「単なる絵」を見せ続けながらも最終的に見世物のレベルにまで持っていかなければならないアニメ業界にとって結構貴重なのでは、と思ってたりするので、今後もますます活躍してほしいものだなと…。いわゆるアンチが多いようではあるけれど、アニメは所詮嗜好品。誰かが嫌った分、別の誰かのお気に入りになってたりするもので。誰も文句を言わないけれど、誰にも刺さらない作品より、好き嫌いがハッキリ分かれて大騒ぎになる作品のほうがまだマシだろう…ぐらいの気持ちでガンガン書いてほしいものだなと…。 *1
*1: 叩く人は、必ず大声でキツイ言い方をするけれど、褒める人は、優しくさりげない言い方になるので、うっかりすると「叩かれてばかり」と感じてしまいそうだけど、実際はそんな状況ではなかったりする…てな場面も結構ありそうだなと思ったりもして。

2018/11/20(火) [n年前の日記]

#1 [tic80] TIC-80でシューティングゲームっぽいものを書いている最中

TIC-80上で横スクロールシューティングっぽいものを書いているところ。

雑魚敵の種類を増やしたものの、発生処理を時間と疑似乱数を元に行っていて、追加していくのがシンドイなと。この際、敵発生テーブルを書いて処理することにしてみたり。というか、書き直してみて思ったけれど、最初からテーブルにしておけばよかった…。どう考えてもテーブルを読んで発生させていくほうが処理も調整も楽…。

この手のテーブル作成用に使えそうなツールが欲しくなってきたりもして。一般的には何を使うのだろう…。マップエディタだったりするのかな…。例えば _Tiled なら、タイルベースとは別にスプライト相当のオブジェクトを配置することもできるので、以前はソレを使って敵発生テーブルを書いた…ような気がする。ただ、他にもヨサゲなツールがどこかにあったりしそうだなと。

そもそも、今時は、レトロ仕様のシューティングゲームを作れる専用ツールが存在しそう。調べてないけどあるんじゃないか。たぶん。

2018/11/21(水) [n年前の日記]

#1 [tic80] TIC-80で曲を作りたくて試行錯誤中

TIC-80上で横スクロールシューティングっぽいものを書いているけれど、せっかくだからBGMを流したいなと。

しかし、曲データが…。シューティングゲームっぽいBGMって、どういう感じだろう…。某ゲームのソレしか思い浮かんでこない…。

更に、TIC-80のような、トラッカー(?)タイプの作曲ツールはほとんど使ったことがないので苦戦中。

_ModPlug Tracker - Wikipedia
_トラッカー:Trackerとは | 偏ったDTM用語辞典 - DTM / MIDI 用語の意味・解説 | g200kg Music & Software

MIDIデータを変換して TIC-80 に持ってくるツール等は無いのかなとググってみたけどそういうものは無いっぽい。せめてノートオン情報だけでもテキスト形式っぽく出力できたら作業効率が違ってくるかも、と思って Python 等でMIDIデータ(SMFファイル)を処理する事例を眺めてみたけど…。トラッカータイプのツールに慣れてしまったほうが早そうだな…。

2018/11/22(木) [n年前の日記]

#1 [tic80] 波形メモリ音源について調べていたり

TIC-80 のサウンドは、音量16段階(4bit)、32個の点を並べて波形にする、波形メモリ音源っぽい仕様になっているのだけど、イイ感じの波形が作れなくて悩んでしまって波形メモリ音源について調べ始めたり。

32個の点で一つの波形と言うと、某社のSCC音源に近いのかなと思ったけれど、ググってみたらSCC音源は音量について256段階(8bit)の解像度を持ってるようだからちょっと違うなと。TIC-80のソレはどちらかというと、ゲームボーイの波形メモリ音源チャンネルに近いのかもしれないなと…。

_波形メモリ音源 - Wikipedia

ゲームボーイの音源に近いのであれば、と、関連ツールをググっているところ。

_Gameboy Programing - FM Synthesis -
_Wavetable calculator
_補助ツール - MCK Wiki*

#2 [web] wonderflってサービス終了してたのか

以下の記事に遭遇して、試しに触ってみたいなと思ったのだけど…。

_ActionScript で波形メモリ音源向け波形編集ツール - Simple Inspiration

Actionscriptを使った試作品をアップロードできるサービス、wonderfl が終了していて、該当プログラムが404。実行できなかった…。

_wonderfl build flash online | 面白法人カヤック

件のサービスは、かなり多くの様々な実験プログラムがアップロードされていた印象があったのだけど、全部消滅か…。Web上のFLASHが殺されたことで、こんなところにも影響が…。もったいない。あまりにもったいない。せめてソースの閲覧だけでもできないものか…。と言っても今後何の利益も出さないものに営利企業が便宜を図るはずもなく。こういうことがあるからリチャード・ストールマンが以下略。

infoseek isweb、Nifty @homepage、Yahoo GeoCities の終了時も思ったけれど、どこかの企業のWebサービスに自作の何かしらを預けるのは極めて危ないのだなと再認識。おそらく将来的には pixiv や github もヤバいのだろうな…。

2018/11/23(金) [n年前の日記]

#1 [tic80] TIC-80でシューティングゲームっぽいものを書いてみた

_TIC-80 上で、横スクロールシューティングっぽいものを書いていたのだけど、それっぽくなってきた気がするので、このあたりで作業終了ということにしようかなと。

こんな感じになった。

stgsample6_ss1_opti.gif

stgsample6_ss2_opti.gif

ブラウザ上でプレイするなら以下。

_stgsample6.tic.html
_Play WCQ NO.6 - WORST CHEAP QUALITY SHOOT 'EM UP EXAPMLE NO.6 - in TIC-80
(※ 2018/12/01追記。TIC-80の公式サイトにもアップロードしてみた。)

cart(.tic)もzipにして置いときます。

_stgsample6.tic.zip

スプライト画像は以下。

_sprites.gif

どれも CC0 / Public Domain ってことで。

ボスを倒すと最初に戻るだけなので、クリア画面等の仕様は期待しないでほしいなと…。一応、ステージクリアすると、撃ち返し弾が増えるようにはしたけれど…。

とりあえず、TIC-80 を使うとこういうのが作れるみたいですよ、てな参考事例になればと。エディタだけは途中から日和って _Geany を使ってしまったけれど、ドット絵も TIC-80上で全部打ったし、効果音もBGMも TIC-80上だけで作業したので、TIC-80 のみを導入しても、ほとんどの作業は完結しそうな印象。

ソース。 :

ソースが長くなってしまったので、gist にアップロードしてみたり。

_TIC-80 shoot 'em up example No.6

一応ここにも置いておくか…。

_stgsample6.lua

#2 [tic80] TIC-80の波形メモリ音源について試行錯誤中

TIC-80のサウンド機能は、いわゆる波形メモリ音源タイプとして実装されているのだけれど。

この、波形メモリ音源、一見すると波形を描いていけばいいだけだから簡単そうに思えてくるけれど、実際にやってみるとイイ感じの音がさっぱり鳴らないというアレな感じの音源タイプで。

もうちょっとどうにかならんのか、と思えてきたので、試しに、sin値等で一周期分の波形データを作って、ソレを波形メモリに書き込んで鳴らすプログラムを書いてみたり。

wavetest_ss1.png

ブラウザでプレイするなら以下。

_wavetest.tic.html
cart(.tic)は以下。

_wavetest.tic.zip

ソース。 :

ソースは以下。無駄に長いけど、makeWave() の中だけ弄れば波形が変わるので…。長さ32個の配列さえ作れば、中の各値を音量16段階(4bit)に切り詰めて波形メモリに書き込んでくれる。

_wavetest.lua
-- title:  wavetest
-- author: mieki256
-- desc:   short description
-- script: lua

waveid=4

WAVADR=0x0ffe4

function makeWave()
 dt={}
 for i=0,31 do
  local v=0
  -- multiplier, speed, shift
  v=v+getSin(i, 1.0, 1.0, 0)
  v=v+getSin(i, 1.5, 0.5, 0)
  v=v+getSin(i, 1.5, 2.0, 0)
  v=v+getSin(i, 0.5, 3.0, 90)
  --[[
  v=v+getSin(i, 0.5, 3.0, 0)
  v=v+getSin(i, 0.25, 4.0, 0)
  --]]
  table.insert(dt,v)
 end
 return dt
end

function getSin(i,m,spd,sft)
 return m*math.sin(math.rad(spd*i*360/32+sft))
end

function writeWave(id,dt)
 -- adjust
 if id<0 or id>15 then return end
 if #dt>32 then return end
 local vmax,vmin
 vmax=0
 vmin=0
 for i=1,#dt do
  if dt[i]>vmax then vmax=dt[i] end
  if dt[i]<vmin then vmin=dt[i] end
 end
 local range=vmax-vmin
 for i=1,#dt do
  dt[i]=math.floor(15*(dt[i]-vmin)/range)
 end

 -- write wave 
 local addr=WAVADR+id*16
 for i=1,#dt,2 do
  local v=0
  v = v | ((dt[i+1] & 0x0f)<<4)
  v = v | (dt[i] & 0x0f)
  poke(addr+((i-1)//2),v)
 end
end

function drawGuide(bx,by,w,h)
 local x0,y0,x1,y1
 local c=3
 x0,x1=bx,bx+w*32-2
 y0=by+h*8-1
 line(x0,y0,x1,y0,c)
 y0=by+h*4-1
 line(x0,y0,x1,y0,c)
 y0=by+h*12-1
 line(x0,y0,x1,y0,c)
 x0=bx+w*16-1
 y0,y1=by,by+h*16-2
 line(x0,y0,x0,y1,c)
 x0=bx+w*8-1
 line(x0,y0,x0,y1,c)
 x0=bx+w*24-1
 line(x0,y0,x0,y1,c)
end

function drawWave(id)
 -- read wave
 local addr=WAVADR+id*16
 local dt={}
 for i=0,15 do
  local v=peek(addr+i)
  local v1=v&0x0f
  local v2=(v>>4)&0x0f
  table.insert(dt,v1)
  table.insert(dt,v2)
 end

 -- draw wave
 local bx,by=24,12
 local w,h=6,6
 local x,y
 for ix=0,31 do
  x = ix * w + bx
  for iy=0,15 do
   y = iy * h + by
   rect(x,y,w,h,0)
   rect(x,y,w-1,h-1,1)
  end
  y=(15-dt[ix+1])*h+by
  rect(x,y,w-1,h-1,6)
 end
 drawGuide(bx,by,w,h)
end

dt=makeWave()
writeWave(waveid,dt)
t=0

function TIC()

 if keyp(14) then sfx(0,"A-4",30,0) end
 if keyp(25) then sfx(1,"A-4",30,0) end
 if btnp(5) then
  -- write to cart
  sync(1<<3,0,true)
 end

 cls(0)
 drawWave(waveid)
 print("WAVE ID: "..waveid, 2,120)
 print("Play: N or Y / Write: X", 2,128)
 t=t+1
end

少し解説。 :

TIC-80上で波形データがどこに記録されているかは、以下のページで説明されてる。

_RAM - nesbox/TIC-80 Wiki

| 0FFE4 | WAVEFORMS | 256 | 16 waveforms, each 32 x 4bit values
というのがソレ。
  • 0x0FFE4番地から、256byteほど確保してあって、16種類の波形が記録されてる。
  • 1つの波形につき、4bitの音量が32個並んでる。つまり、16byteで一つの波形になる。
このアドレス領域に、poke(アドレス,値) を使って 16byte を書き込んでやれば、波形メモリ1つ分の内容を書き換えられる。

_poke - nesbox/TIC-80 Wiki

書き込む1byteのうち、下位4bitが0番目の音量、上位4bitが1番目の音量、となっている模様。
bytes : 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, ...

wave memory : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, ...

せっかく波形メモリを書き換えても、プログラムを終了してしまうと、波形メモリの内容はデフォルト値でリセットされてしまう。できれば cart.tic に保存・記録しておきたい。そんな時は、sync() を使う。

_sync - nesbox/TIC-80 Wiki

とりあえず、sync(1<<3, 0, true) を呼び出せば、現在のSFXデータ(効果音データ)を、cart.tic に記憶させられる。と言っても、その段階ではファイルとして保存されてない気配がするので、更に Ctrl+S を叩いてファイルとして上書き保存したほうがいいのかもしれず。

課題。 :

一々ソースを書き換えて波形を変えていくのは面倒なので、実行画面上でパラメータを弄ればその場で変化するようにしたいのだけど。しかし、どういった波形ソース、及び、パラメータを用意しておけばいいのかで悩んだり。

sin波をいくつか合成するだけでではそんなに変化が出ないだろうし…。矩形波、三角波、ノコギリ波も加算できるようにしたほうがいいのかな…。

#3 [pc] ロジクール M705が壊れたっぽい

親父さん用PCに繋いでいた無線マウス、ロジクール M705 の調子が悪いと親父さんから相談が。D&Dが上手くできないとかなんとか。

随分昔に買ったマウスだし、親父さんも随分長く使っていたので、スイッチがヘタレてチャタリングが起きてるのではないか、新品マウスを買ったほうがいいかも、という話の流れに。

その後、親父さんは、ケーズデンキでELECOM製の無線マウスを買ってきたそうで、今のところ問題は起きてないっぽい。

一応、M705 を回収して、自分のメインPC上でもチャタリングが起きるかどうかを検証。以下のソフトの中に入ってる「おまけ.exe」が、マウスクリックの回数を表示してくれるらしい。コレを使えば、テストというか検査ができるのではないか…。

_連打くんの詳細情報 : Vector ソフトを探す!

試したところ、稀に、左ボタンを押して1回、離して1回、と入力されてることが確認できた。やはりチャタリングは起きてるっぽいなと。

更に、振ると中でカラカラと音がすることに気づいた。親父さんの話では、床に落としてしまったことがあるそうで。物理的(?)にも何かが壊れてるっぽいな…。

分解して修理できないかと思ったものの、使われてるネジが六角穴の例のネジで。コレに対応する工具は持ってない…。どうしてフツーのネジにしてくれないのだ…。

まあ、自分にとっては、電池は圧倒的に長持ちするけどすぐにスリープに入ってストレスが溜まるマウスだったし、小指のあたりにセンサがあるからカーソル移動すら妙な感覚だったし、後継製品が出ているぐらいに古い製品でもあるし、スイッチ交換となれば半田付けが必須だけどそういうのはもう面倒臭いしで。ちょっともったいない気もするけど、この際捨てることにした。

2018/11/24() [n年前の日記]

#1 [ubuntu][linux] SPTKを触っているところ

TIC-80の波形メモリ音源をもっと使いこなせないものかとヒントを探してググってるうちに、SPTK (Speech Signal Processing Toolkit)という、波形データを処理するツール群の存在を知り、試しに触ってみようかと。なんでも、波形データの中身をテキスト形式でダンプしたり、ピッチを検出したりすることができるらしい。

_SPTKの使い方 (1) インストール・波形描画・音声再生 - 人工知能に関する断創録
_Speech Signal Processing Toolkit (SPTK)
_SPTKというものを使ってみた - matobaの雑記

Ubuntu 18.04 LTS上でインストール。 :

とりあえず、VMware Player + Ubuntu 18.04 LTS 上でインストールしてみた。

Ubuntuの場合、sptk というパッケージが用意されていたので、導入は簡単だった。
$ sudo apt install sptk
$ sptk impulse -h

impulse - generate impulse sequence

...

SPTK: version 3.9
CVS Info: $Id: impulse.c,v 1.24 2015/12/14 01:14:16 uratec Exp $
現状では SPTK 3.9 がインストールされる模様。

巷の解説記事では、直接 impulse -h と打ち込んで動作確認している事例がほとんどだけど。Ubuntu の sptk パッケージは、sptkの後ろに実行したいコマンド名を追加して実行する状態で配布されているらしい。これは勝手な想像だけど、コマンド数が多いので、他のツール名と重複することを避けるためにそうしているのかな、と。

まあ、/usr/lib/sptk/bin/ 以下に各コマンドが入ってるっぽいので、面倒な時は PATH に設定してしまうのもありかもしれない。
export PATH=$PATH:/usr/lib/sptk/bin

xgrが動かない。 :

SPTK に同梱されている、波形をグラフ表示するツール、xgr が動かなかった。
$ gwave +s data.short | xgr
X Error of failed request:  BadName (named color or font does not exist)
  Major opcode of failed request:  45 (X_OpenFont)
  Serial number of failed request:  312
  Current serial number in output stream:  318
Broken pipe
Broken pipe
Broken pipe
Broken pipe
Broken pipe
Broken pipe
このツールだけは X Window を使うので、他の環境でも動かなかった事例がちょこちょこあるらしい。

エラーメッセージでググったら、どうもフォントが足りてない時に出るエラーっぽい…。

結論を先に書くと、以下を再インストールしたら動くようになった。
sudo apt --reinstall install xfonts-base xfonts-100dpi xfonts-75dpi xfonts-cyrillic

おそらく、何かしらのフォントをインストールしていく途中で、何かが壊れてしまっていた、と言うことだろうか…。

xgrを動かすために試行錯誤した際の記録。 :

以下のパッケージをインストールしてみたけれど、状況は改善しなかった。
sudo apt install xfonts-75dpi xfonts-100dpi
sudo apt install xfonts-75dpi-transcoded xfonts-100dpi-transcoded
sudo apt install x11-xfs-utils
sudo apt install xfonts-unifont
sudo apt install gsfonts-x11

xgr のソースファイル群を眺めてみたら、gcdata.h の中で以下の記述があった。ここで記述されているフォントの種類が必要になるのだろう…。
/*
* Fonts name
*/
#define FSymbol 9
static char *f_name[] = {
   "-adobe-courier-medium-r-normal-*-*-100-*-*-m-*-iso8859-1",
   "-adobe-courier-medium-r-normal-*-*-120-*-*-m-*-iso8859-1",
   "-adobe-courier-medium-r-normal-*-*-140-*-*-m-*-iso8859-1",
   "-adobe-courier-medium-r-normal-*-*-160-*-*-m-*-iso8859-1",
   "-adobe-courier-bold-r-normal-*-*-100-*-*-m-*-iso8859-1",
   "-adobe-courier-bold-r-normal-*-*-120-*-*-m-*-iso8859-1",
   "-adobe-courier-bold-r-normal-*-*-140-*-*-m-*-iso8859-1",
   "-adobe-courier-bold-r-normal-*-*-160-*-*-m-*-iso8859-1",
   "-adobe-symbol-medium-r-normal-*-*-80-*-*-p-*-adobe-fontspecific",
   "-adobe-symbol-medium-r-normal-*-*-100-*-*-p-*-adobe-fontspecific",
   "-adobe-symbol-medium-r-normal-*-*-120-*-*-p-*-adobe-fontspecific",
   "-adobe-symbol-medium-r-normal-*-*-140-*-*-p-*-adobe-fontspecific",
   "-adobe-symbol-medium-r-normal-*-*-160-*-*-p-*-adobe-fontspecific"
};

xfontsel & と打って、前述のフォント種類が選べるか確認してみたが、adobe なんたらというフォントは入ってないように見える。

xfonts とついてるパッケージを片っ端から入れてみたところ、xfontsel で、adobe なんたらというフォントは選べるようになった。が、相変わらず sptk の xgr はエラーを出す。再度 xfontsel で確認してみると、adobeなんたらについては、ptSz は 120 以外無いし、spc も m が無い。必要なフォント種類を満たしていなかった。

ダメ元で、xfonts-base その他を再インストールしてみたところ、xfontsel 上でも目的のフォント種類が選べるようになったし、xgr も動いてくれた…。

以下、関係ありそうなページ。

_UbuntuでPackageの再インストール | technote
_11.04 - How to install xorg-x11-fonts - Ask Ubuntu
_Ubuntu設定-3- - kshimo69のブログ

#2 [nitijyou] 日記をアップロード

気づいたら2018/10/30を最後に日記をアップロードしてなかったので、まとめてアップロードしておいた。とメモ。

2018/11/25() [n年前の日記]

#1 [windows] SPTKがWindows上で使えるか確認

SPTK (Speech Signal Processing Toolkit) が Windows10上でも使えそうかどうかを確認してみたくなったので、そのあたり試してみたり。

SPTK は、Windows用バイナリが配布されてないので、ソースをビルドしないといけない。とりあえず、手元の Windows10 には MSYS2 がインストールされているので、その上でビルドしてみようかと。

Cortana に msys2 と打ち込んで、「MSYS2 MinGW 32-bit(32bit)」を起動。

ホームフォルダ以下に build/sptk/ を作って、中に SPTK-3.11.tar.gz をコピー。
cd ~/build/sptk
tar zxvf SPTK-3.11.tar.gz
cd SPTK-3.11
./configure
make
make install

$ which impulse
/mingw32/bin/impulse

$ impulse -h
ひとまず、SPTK 3.11 をビルド、かつ、インストールできたらしい。

動作させるために X Window が必要になる xgr については、ビルドされなかった。当然インストールもされてない。また、今回のソレだと、「MSYS2 MinGW 32-bit(32bit)」上でしか使えない点にも少し注意。

ちなみに、「MSYS2 MSYS (32bit)」を起動して同じ作業をしてみたところ、MSYS上でも使えるようになった。

Windows版gnuplotもインストール。 :

gnuplotがあると波形の類を表示することも容易と知って、試しにインストールしてみたり。

_gnuplot homepage
_gnuplot - Browse /gnuplot at SourceForge.net
_Windows PCへのgnuplotのインストール (2016年8月)

今回は、gp525-win64-mingw.exe をDLしてインストールしてみた。以下を参考に、SPTK の rawデータをテキスト出力したものを渡してみたら、たしかに波形っぽいものが表示された。

_SPTKの使い方 (1) インストール・波形描画・音声再生 - 人工知能に関する断創録
dmp +s data.short > data.txt
wgnuplot
gnuplot > plot "data.txt" w l

#2 [windows] ホームページビルダーのページ保存が遅い

親父さんから、ホームページビルダー20でページ保存をしようとすると4分ぐらい待たされる、という相談が。SSDを積んでいる WIndows10機で、その状況は異常なのではないか…。

SSDが壊れているのかと思ったけれど、エクスプローラその他でファイルのコピーや移動をする分にはそんな遅さはないわけで。ホームページビルダーだけが遅い…。

設定で、「再編集用データを生成する」のチェックを外せば少しは改善するという話を見かけたので試してみたけど、効果無し…。

_[ホームページビルダー]再編集用フォルダ : 初心者のためのOffice講座-SupportingBlog1
_ホームページビルダー16、ファイル保存が遅い原因 - エクセル将棋館Tips

以前、Windows7上でホームページビルダーを使おうとした際に、特定サービスを有効にしていると不正終了する不具合に遭遇したことがあったけど。

_mieki256's diary - Windows7上でホームページビルダー11に不具合が

それと似た感じで、ネットワーク上の何かにアクセスしようとして反応が遅くなってる可能性は…。しかし、ググってみてもそれらしい情報が無い…。

ちなみに、昨今の Windows10 はホームグループ機能が無くなったそうで、そのせいか HomeGroup Provider というサービス名も見当たらなかった。

2018/11/26(月) [n年前の日記]

#1 [windows] ホームページビルダー20でページ保存が遅い問題をどうにかしたいのだけど

親父さん用PC上で、ホームページビルダー20のページ保存が数分かかる問題をどうにかしたくて、ググったり、何か試したりをしているところ。環境は Windows10 Home x64 1803 (April 2018 Update)。

デスクトップ上のアイコンが絡んでる場合もあるらしい。 :

デスクトップ上に「God Mode」のショートカットがあるとホームページビルダーの動作がおかしくなる、ので、該当ショートカットを別の場所に移動すると改善された、という事例があることを知った。

_ホームページビルダー トラブル発生から解決まで - CQ DE JF3PLF

何なの…その黒魔術…。どういう作りになっているんだ、ホームページビルダー。

そういえば、親父さん用PCのデスクトップには、コントロールパネルへのショートカットその他があったな…。と思い出して、似た感じのアレコレを削除したり表示OFFにしてみたり。

しかし、効果無し。コレじゃないようだな…。

ちなみに、Windows10では、一部のデスクトップアイコンの表示設定は「個人用設定」から辿ってできる。

_Windows10 - デスクトップ・アイコンの設定(表示/非表示) - PC設定のカルマ

画面の何もないところで右クリック → 個人用設定 → テーマ → デスクトップアイコンの設定。

プリンタの設定を変更。 :

ホームページビルダーについての話ではないけれど、ジャストシステム製のアプリは、ファイル関係のダイアログを開く際にプリンタ一覧情報を見に行くので、そのあたりの設定を変えると状況が変わる場合もある、と知った。

_[051541]操作中に画面が止まったり、エラーメッセージが表示されたりする

まあ、ホームページビルダーは、元々IBMが売ってて、ソースネクストが引き取って、最後はジャストシステムが引き取ったアプリだから、そのへん関係無い可能性が高そうだけど…。

とりあえず、「通常使うプリンタ」だけでも、Microsoft XPS Document Writer に変更して試してみたり。

しかし、効果無し。

常駐ソフトを終了してから試した。 :

親父さん用PC上で常駐している各ソフトを終了させてから試してみた。WinShot、Canon製デジカメのファイル転送用ツール、DELL製ディスプレイの管理ツール等、タスクトレイに居るヤツで、Windowsの動作に絡んでこないであろう連中は、一通り終了。

しかし、効果無し。

特定バージョンの EaseUS Todo Backup が、バックグラウンドで悪さをしていた事例もあるらしい。

_Windows10 関連、操作やアプリが固まる原因と対策

そこまではチェックしてなかった。後で確認してみないと。

メディア機器を削除。 :

ネットワークフォルダを開くと、メディア機器というカテゴリ内に色々な機器が表示されるけど。以前導入したけど結局弟が持って帰ったNASやら、他所から預かってメンテナンスをしたノートPC等、既に存在していない機器が多々残ってたので、そのあたりも「デバイスの削除」を選んで消してみた。

しかし、効果無し。

残るはアプリの再インストールだけど。 :

他に思いつくのは、ホームページビルダーのアンインストール・再インストールだけど。サイト管理情報を登録し直すことになる、という話をしたら、親父さんが、「そんな面倒臭いことは嫌だ」と言い出して。

サイト管理情報を、別途バックアップしておいて書き戻すこともできるのだけど…。 *1 調子が悪い現状の各情報をバックアップして書き戻しても、また症状が再現する可能性もあるし…。いやまあ、その場合、サイト管理情報が悪さをしていたのだ、ということが分かって意味はあるのだけど。ただ、アプリの再インストールをしても症状が変わらない可能性もあるわけで。

「そんな面倒臭いことをするぐらいなら、保存に数分かかる状況を我慢する」「どうせ今だって保存ボタンを押したらそこから数分は別のことをやって時間を潰しているし」と親父さんが言い始めたので、アプリの再インストールは試さない方向で。

自分が使ってるPC・アプリなら、解決策が本当に無いのかもっと試すところだけど。使ってる当人が乗り気じゃないようだし…。放置してても改善する見込みなんて一切無いのだけれど、今回はここまでだな…。

これがまた、Windows Update のせいで症状が発生、てな可能性も否定できないし…。

_2018年11月のWindows UpdateでOutlookにエラーが出る - treedown's Report
_11月のパッチで64bit版「Outlook 2010」が起動不能に 〜Microsoftが修正プログラムを公開 - 窓の杜

その場合も、Microsoft なり、ジャストシステムなりに報告しなきゃ改善する見込みもないけれど、自分が使ってるわけでもないから更に検証するわけにも…。

*1: 最近のホームページビルダーには、 _安心バックアップ・移行ツール というツールが付属しているので、ソレを使えば必要な情報のバックアップができる。はず。使ったことないから自信無いけど。

#2 [windows] Microsoft Expression Web 4 を試用

ホームページビルダーの代替にならないかと思って、Microsoft Expression Web 4 を試用してみたり。開発終了と同時に無償配布することになったHTML編集ソフト。

_Microsoft Expression Web - Wikipedia
_無料のウェブ作成ソフトMicrosoft Expression Web 4 [ホームページ作成] All About
_Microsoft Expression Web 4 (Free Version) のダウンロードとインストールの方法
_Download Microsoft Expression Web 4 (Free Version) from Official Microsoft Download Center

少し触ってみた程度だけど、大昔に Microsoft が配布していた、IEに特化したHTMLを出力する編集ソフト(Microsoft FrontPage系?)と違って、随分と素直なHTMLを出力してくれるソフトだなと…。

ただ、HTMLタグとスタイルシートの知識が無いと装飾もままならない雰囲気で。ホームページビルダーの代替にはならない印象も受けた。少なくとも、ウチの親父さんのレベルでは使えないだろうなと。HTMLソースを眺めたりしない人だし…。

blogやCMS等の普及で、こういったジャンルのソフトは、ほぼ絶滅してしまったし…。なかなか厳しいなと。

2018/11/27(火) [n年前の日記]

#1 [tic80] TIC-80の波形メモリをアレコレして試しているところ

TIC-80の波形メモリに対して、sin値を書き込んで波形を作るソレを試しているところ。とりあえず、マウス座標を取得して、sin値に掛ける値を変更する仕様を追加していたり。

マウス座標は、mouse() で得られる。x,y座標と、マウスボタンを押しているか否か、が取得できる模様。

_mouse - nesbox/TIC-80 Wiki
_Handling Mouse Touch Events - nesbox/TIC-80 Wiki

mx, my, md = mouse()

マウスボタンの種類も取得できるようだなと。
mx, my, ml, mm, mr = mouse()
上記の場合、ml, mm, mr に、左ボタン、中ボタン(ホイールクリック)、右ボタンが押されてるかどうかが true / false で入ってくる。

#2 [windows] ホームページビルダーの動作が遅い問題のその後

親父さん用PC上で起きていた、ホームページビルダーからページ保存すると数分待たされる症状が気になっていたけれど。

ふと、新規ページを作成して保存してみれば何か分かるかもと、ようやく思いついた。新規ページを保存する際も遅いなら何かがおかしいし、新規ページがすぐに保存できるなら、今まで開いて保存していたページの分量が ―― リンク数その他が多過ぎて遅くなってる可能性があるなと。ていうか、最初にそのあたりを確認すべきだった…。

試してみたけど、新規ページの保存時は一瞬で保存できた。そういうオチか…。つまり、今まで開いて試していたページの分量が、ホームページビルダーにとっては多過ぎる、ということだろうなと…。パッと見、それほどヘビーな感じのページには見えなかったのだけどな…。

とりあえず、新規ページならサクッと保存できる様子を親父さんにも見せて、保存時間を短くしたいならページの軽量化を試みる手がある、と伝えたり。

それにしても、あの程度のページ内容でもこんなに時間がかかるのか…。ホームページビルダー、遅いな…。

2018/11/28(水) [n年前の日記]

#1 [tic80] TIC-80の波形メモリをまだアレコレして試していたり

TIC-80の波形メモリにそれっぽい波形を書き込むツールっぽいものを作成中。

sin波、矩形波、ノコギリ波、三角波のどれかを、10個ぐらい位相を変えて加算して、波形を作れるようにはなった。スライダーを弄っていると、なんとなく人の声の「あー」に聞こえなくもない音が出たりして、ちょっとだけ夢が広がりんぐ。

しかし、見た目で奇麗な波形にならないあたり、ちょっと気になる…。出来た波形は、マウスで描いた場合と違って、上下や左右が非対称で…。実数から4bitの整数に変換する際に、プラス値とマイナス値の切り捨て方を雑に書いてるせいだろうか。別々に処理しないとダメかな…。でもまあ、気に入らなければ、後から手作業で波形を修正すればいいだけの話か…。

全体の音量を変化させたり、クリッピングしないように各値を自動調整する処理も一応追加。それぞれの波の量をチマチマ調整すれば同じ結果が得られるはずだけど、そういう操作も面倒だし。

TIC-80のSFXエディタとクリソツな波形表示画面にしているせいで、スライダー相当を表示する面積が少なくて、マウスで1ドット単位の操作を要求する点も気になる。もうちょっとスライダーを大きくして、ざっくりとした操作にしたい…。波形表示部分を小さくしてしまおうか…。どうしたもんか…。

ピッチを微妙に変えた音を同時に鳴らすことで、音にうねりが出るという、 _デチューン(Detune) なる技があると知り、似たようなことが波形生成の段階でできないかと試してみたものの、全く効果が得られず。考えてみたら、ずっとその音を流し続けることで波がずれていってうねりが出るのだから、たかだか1周期分の波形に、事前に変化を盛り込んでおくことはできないのだな…。

アレコレ検索しているうちに、FM音源の仕組みについても興味が湧いてきた。コレを盛り込めないか…。

もっとも、FM音源は時間の経過と共に波形が変化していくあたりが肝らしいので、これまた1周期分の波形の中にそういった変化を盛り込むなんて無理っぽい予感。それに、FM音源で生成した波形は奇麗に1周期分が取れない気もするので、波形を繋いで鳴らした際にノイズが出そうだなと。

#2 [anime] ガンダムってスゴイ

TVをつけてたら、中国がゲノム編集をした赤ん坊を云々、というニュースを見かけて。瞬間的に、「ああ、ガンダムSEEDの…」と思ってしまったのだけど。

改めて、ガンダムって凄いなと…。アレを見てると、その手の科学知識の概要が、楽しみながら頭の中に入っちゃって、こういう話が出てきたときにも「ああ、アレかあ」と理解できちゃう。

もちろん、ガンダムシリーズ内の各設定は、現実世界で語られているアレコレを取り込んで作ってるわけだから、ガンダムシリーズがオリジナルというわけではないのだけれど。それらの知識を子供達にも分かる形で提示して、世間に広く認知してもらうという点では、非常に優秀というか、ある種の社会貢献をしているとも言えるよなと…。

スペースコロニーもそうだし、ゲノム編集もそうだし、軌道エレベーターもそうだし…。ガンダムシリーズは科学教育番組としてもスゴイ。ような気がするのでした。まあ、ガンダムに限らず、SFアニメならそういう面があるわけですけど。

異世界転生ハーレムアニメばかり作ってたら、こういった効能は期待できないわけで。

2018/11/29(木) [n年前の日記]

#1 [pc][windows] 特定文字を使ったファイル名のリストアップや置換作業をしていたり

親父さんが、親父さんのWebサイトのディレクトリ構成を変更していたのだけど。Webサーバ上にアップロードするとよろしくないファイル名が ―― ホームページビルダーのファイル転送ツールが「このファイル名には問題があるよ」と言ってくるファイル名が大量に見つかってしまったので、そういったファイル名の検索や置換をする作業を手伝ったり。環境は Windows10 Home x64。

ファイルの検索。 :

ダメな文字を使っているファイル名の検索は、Rubyスクリプトを書いて行った。カレントフォルダ以下のファイル名を再帰的に取得して、条件に合わないファイル名のパスを出力する。
Dir.glob('**/*') do |item|
  unless item =~ /^[0-9a-zA-Z\/\._\-]+$/
    puts item
  end
end
たったこれだけ。Rubyって便利。

親父さん用PCに Ruby はインストールされていないので、前述のスクリプトを ocra で exe化して持っていって使った。これで、どのフォルダの中に、ダメなファイル名があるのか目途がついた。

リンクの修正とファイル名の変更。 :

html内のリンク文字列の置換は、 _Devas を使用。

ファイル名の置換は、 _Flexible Renamer を使用。

一つ一つを手作業で修正せずに済んだ。ありがたや。

エクスプローラで開いてるフォルダでDOS窓を開きたい。 :

エクスプローラのアドレス欄(ロケーションバー)に、「cmd」と打って実行すると、現在開いてるフォルダをカレントフォルダにしてDOS窓が開けると知った。

_【Tips】Windows 10で選択したフォルダからコマンドプロンプトを開く方法 | ソフトアンテナブログ
_Windows 10でコマンドプロンプトを素早く起動する方法:Tech TIPS - @IT

こんな仕様があったのか…。今まで、Win + R → cmd → エクスプローラのアドレス欄で右クリック → テキストとしてコピー → DOS窓上で右クリックして 貼り付け、とかやってた…。

2018/11/30(金) [n年前の日記]

#1 [tic80] TIC-80の波形メモリ音源の波形を生成するツールを書いてみた

TIC-80の波形メモリ音源に対して、波形を生成して書き込むツールを書いてみたり。Windows10 x64 + TIC-80 0.70.6 で動作確認した。

使い方がよく分からん気もするので、操作してる様子を動画でキャプチャしてみたり。こんな感じ。



cart(.tic)は以下。zip圧縮して置いておきますので、使ってみたい方は御自由に。CC0 / Public Domain ってことで。

_wavetest2_20181130.zip

ブラウザ上で動作させるなら以下。

_wavetest2.tic.html
_Play WAVETEST2 in TIC-80
(※ 2018/12/01追記。TIC-80の公式サイト(Playコーナー)にもアップロードしてみた。)

ただ、ブラウザ上では処理が重く、手元の環境(Windows10 + Waterfox 56.2.5)ではノイズがやたらと入るようで…。それでもひとまず、触ってみれば雰囲気だけは伝わるかなと…。

ソースは以下。

_wavetest2.lua

操作方法。 :

一応操作方法をメモ。

基本的にはマウスクリックで動作する。
  • WAVE ID <n> : 現在アクセスしてる波形メモリのID。0〜15まで選べるが、0〜3はデフォルトで波形が入っているので変更できないようにしてある。
  • READ : 波形メモリの読み出し再生モード。
  • MAKE : 波形生成モード。
  • PLAY : 1秒間隔で音が鳴り続ける。
  • STOP : 音を停止。
  • Sync : 現在の波形メモリ状態を、cart に記録。
  • MAXI : SFXエディタと同じサイズで波形を表示。
  • OCT : オクターブの指定。
  • AJST : 音量自動調整。
  • RSET : 周波数設定のリセット。
  • スライダー : 音量や位相の指定値。
  • 波形アイコン : sin波(正弦波)、矩形波、ノコギリ波、三角波の切り替え。

下のほうに2つのスライダー群があるけれど、左が周波数の音量指定。基準となる周波数(440Hz)の1倍、2倍、3倍…10倍、と並んでいる。

右のスライダー群は、位相(角度)の指定。-180度 〜 +180度を指定できる。

一番左のスライダーは、全体の音量。

スライダーの上で左ボタンクリック or ドラッグすると値を変更できる。中ボタンクリック(ホイールクリック)で、値をリセット。

他のcartへの流用方法。 :

この wavetest2.tic で作成したSFX(効果音)の波形メモリを、自分が作成中の cart に流用したい場合は、load コマンドが使える模様。
load wavetest2.tic sfx
最後に「sfx」を指定して load しているので、wavetest2.tic のSFX領域データだけが、現在開いてる cart の SFX領域データに読み込まれる。ソースコードやスプライト画像の領域は上書きされない。はず。たぶん。

#2 [lua][tic80] Lua用軽量IDE ZeroBrane Studio を少し試用

TIC-80用のプログラムを、今まで _Geany を使って書いていたけれど。他にヨサゲなエディタはないかとググってたら、Lua用の軽量IDEとして ZeroBrane Studio なるものがあると知り。興味が湧いたので少し試用してみたり。ちなみに、Windows10 x64上で試したけれど、Mac や Linux でも使える、と謳っている模様。

_ZeroBrane Studio - Lua IDE/editor/debugger for Windows, Mac OSX, and Linux
_【Lua】軽量の Lua IDE「ZeroBrane Studio」紹介 - コガネブログ
_これ一つでLuaの開発がはじめられる・ZeroBrane Studio MOONGIFT

ちょっとだけ触ってみた印象では、改行した時のインデントを自動で挿入してくれたり、if 〜 then 〜 else 〜 end を打った時にインデントを調整してくれたりするあたりがイイ感じ。また、関数一覧を表示する機能もヨサゲ。

ちなみに、日本語文字列のインライン入力はできない模様。

デフォルトのキー割り当て一覧は以下。

_Editor Keyboard Shortcuts - ZeroBrane Studio

設定をカスタマイズ。 :

設定は、Edit → Preferences → Setting: User を選ぶと開かれる、user.lua に追加していけばいいらしい。たぶん。

今回は以下のような設定を追加してみた。
-- font setting
editor.fontname = "Consolas"
-- editor.fontname = "MigMix 1M"
editor.fontsize = 13

-- indent setting
-- editor.tabwidth = 2  -- default
editor.tabwidth = 1
上記の例では、フォント種類、フォントサイズ、及び、インデント幅を設定している。記述してから ZeroBrane Studio を再起動したら設定が反映された。

設定内容については、以下が参考になる。

_Editor Preferences - ZeroBrane Studio

ショートカットキーも追加してみた。
-- add shortcut key
editor.keymap[#editor.keymap+1] = {('E'):byte(), wxstc.wxSTC_SCMOD_CTRL, wxstc.wxSTC_CMD_LINEEND}
editor.keymap[#editor.keymap+1] = {('K'):byte(), wxstc.wxSTC_SCMOD_ALT, wxstc.wxSTC_CMD_DELLINERIGHT}
editor.keymap[#editor.keymap+1] = {wxstc.wxSTC_KEY_UP, wxstc.wxSTC_SCMOD_ALT, wxstc.wxSTC_CMD_MOVESELECTEDLINESUP}
editor.keymap[#editor.keymap+1] = {wxstc.wxSTC_KEY_DOWN, wxstc.wxSTC_SCMOD_ALT, wxstc.wxSTC_CMD_MOVESELECTEDLINESDOWN}
この例では、以下のショートカットキーを追加している。
  • Ctrl + E : 行末まで移動
  • ALt + K : 行末まで削除
  • Alt + Up : 行を上に移動
  • Alt + Down : 行を下に移動

このIDEは、 _Scintilla を利用しているようで、ショートカットキーの設定などは、Scintilla の設定その他が参考になる模様。

_Editor Preferences - ZeroBrane Studio
_KeyBindings - Scintilla Documentation
_KeyboardCommands - Scintilla Documentation
_[ZeroBrane Studio] Copy/move line keyboard shortcuts - zerobrane - FreeLists
_[ZeroBrane Studio] Re: Copy/move line keyboard shortcuts - zerobrane - FreeLists

「editor.keymap[#editor.keymap+1] = { 〜 }」と書くことで、editor.keymap というテーブルの最後に設定を追加しているのだろう…。

ショートカットキーの設定は、
{ キー種類, 修飾キー, コマンド }
という形で並べていくのかなと。修飾キーの種類には、以下があるらしい。
  • wxstc.wxSTC_SCMOD_CTRL
  • wxstc.wxSTC_SCMOD_SHIFT
  • wxstc.wxSTC_SCMOD_META
  • wxstc.wxSTC_SCMOD_ALT
2つ以上の修飾キーを指定したい場合は、
wxstc.wxSTC_SCMOD_CTRL + wxstc.wxSTC_SCMOD_ALT
といった形で書くのかな。たぶん。試してないけど。

コマンドの種類については、 _Scintillaのソレ を眺めて処理内容を想像しつつ試しに書いて動かしてみるしかないかな…。wxstc.wxSTC_CMD_コマンド名、と書くっぽい。

カラーテーマの変更。 :

カラーテーマというか配色を変更したいなと思ってググってみたら、以下が参考になった。

_Changing color theme in ZeroBrane Studio

ZeroBrane Studio のインストール場所に、cfg/scheme-picker.lua というファイルがあるので、ZeroBrane Studio で開いてみる。コメント部分に、色々なテーマ名が並んでいるので、それぞれをマウスでクリックしてみると色が変わるので…。これだな、と思ったテーマ名で、user.lua に以下のような感じで記述。
styles = loadfile('cfg/tomorrow.lua')('Monokai')
stylesoutshell = styles -- apply the same scheme to Output/Console windows
styles.auxwindow = styles.text -- apply text colors to auxiliary windows
styles.calltip = styles.text -- apply text colors to tooltips
この場合は、Monokai を選んでる。

Notepad++ 風にしたい場合は、
styles = loadfile('cfg/tomorrow.lua')('NotepadPlusPlus')
と書く模様。

プラグインの追加。 :

以下から入手できるらしい。

_pkulchenko/ZeroBranePackage: Packages for ZeroBrane Studio (https://studio.zerobrane.com)

インストールの仕方は以下。
  • ZeroBrane Studio インストール場所の下にある packages フォルダの中に .lua を入れる。
  • もしくは、~/.zbstudio/packages/ フォルダを作ってその中に .lua を入れる。

以上、30 日分です。

過去ログ表示

Prev - 2018/11 -
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project