2021/02/04(木) [n年前の日記]
#2 [love2d] love2dでWindows用のスクリーンセーバを作成してみる
love2d を使って、Windows用のスクリーンセーバを作成してみる。環境は、Windows10 x64 20H2 + love2d 11.3。
◎ Windows用スクリーンセーバについてのおさらい。 :
Windows用のスクリーンセーバは、拡張子が .scr になっているけれど、実態は exeファイル。
以下のコマンドラインオプションを渡して実行した際に、それぞれ処理が変わるように作っておけばスクリーンセーバとして使える、らしい。
また、スクリーンセーバのファイル名は、8文字以下(拡張子を除く)にしておかないといけない、という話もどこかで見かけた。それって Windows 9x 時代の話じゃないのか、今も適用されるのか、という疑問も湧くけど、一応合わせておいたほうが無難だろうなと…。
以下、参考ページ。
_スクリーンセーバー
_Borland C++ 5.5 フリーでスクリーンセーバを作る
以下のコマンドラインオプションを渡して実行した際に、それぞれ処理が変わるように作っておけばスクリーンセーバとして使える、らしい。
- /s : フルスクリーン表示。スクリーンセーバとして動いている時はこの状態。
- /c : 設定ダイアログを表示する。
- /p xxxx : プレビューモード。スクリーンセーバの種類を選択する際に表示されている小さい窓部分を返す。xxxx はウインドウハンドルらしい。
- /a : パスワード設定。
また、スクリーンセーバのファイル名は、8文字以下(拡張子を除く)にしておかないといけない、という話もどこかで見かけた。それって Windows 9x 時代の話じゃないのか、今も適用されるのか、という疑問も湧くけど、一応合わせておいたほうが無難だろうなと…。
以下、参考ページ。
_スクリーンセーバー
_Borland C++ 5.5 フリーでスクリーンセーバを作る
◎ love2dスクリプトを書く。 :
とりえず、フルスクリーンで表示して、丸が画面の中で跳ね回るだけのlove2dスクリプトを書いてみた。
lovescr1 というフォルダを作って、中に conf.lua と main.lua を置く。
_conf.lua
_main.lua
動作確認。
フルスクリーン表示で、丸が動いた。
何かキーを押したり、マウスを勢いよく動かすと終了する。
lovescr1 というフォルダを作って、中に conf.lua と main.lua を置く。
_conf.lua
function love.conf(t) t.window.title = "Windows Screensaver with love2" t.window.vsync = true t.window.width = 1280 t.window.height = 720 t.window.fullscreen = true -- t.window.fullscreentype = "exclusive" end
- t.window.fullscreen = true を書いて、フルスクリーン表示を指定している。
_main.lua
-- Windows screensaver with love2d function love.load() love.graphics.setDefaultFilter("nearest", "nearest") -- get screen size wdw_w, wdw_h = love.graphics.getDimensions() -- Check command line options ssmode = "" for k, v in pairs(arg) do lv = string.lower(v) if lv == "/s" then ssmode = "fullscreen" elseif lv == "/c" then ssmode = "config" elseif lv == "/p" then ssmode = "preview" elseif lv == "/a" then ssmode = "passwordlock" end end if ssmode == "" then ssmode = "none" end if ssmode == "config" then love.event.quit() end if ssmode == "preview" then love.event.quit() end if ssmode == "passwordlock" then love.event.quit() end if ssmode == "none" then love.event.quit() end -- hide mouse cursor love.mouse.setVisible(false) min_dt = 1 / 60 next_time = love.timer.getTime() dx = wdw_w / 2 dy = dx / 3 x = wdw_w / 2 y = wdw_h / 2 r = wdw_w / 100 end function love.update(dt) next_time = next_time + min_dt if dt > 0.75 then return end -- move ball x = x + dx * dt y = y + dy * dt if (x - r) < 0 or (x + r) > wdw_w then dx = dx * -1 end if (y - r) < 0 or (y + r) > wdw_h then dy = dy * -1 end end function love.draw() -- clear screen love.graphics.setCanvas() love.graphics.clear(0, 0, 0, 1.0) -- draw ball love.graphics.setColor(0.1, 0.3, 1.0, 1.0) love.graphics.circle("fill", x, y, r) -- draw FPS love.graphics.setColor(0.5, 0.5, 0.5, 1.0) love.graphics.print("FPS: "..tostring(love.timer.getFPS()), 10, 10) if love.system.getOS() == "Windows" then -- wait local cur_time = love.timer.getTime() if next_time <= cur_time then next_time = cur_time else love.timer.sleep(next_time - cur_time) end end end function love.keypressed(key, isrepeat) -- Pressed any key to exit love.mouse.setVisible(true) love.event.quit() end function love.mousemoved( x, y, dx, dy, istouch ) -- Moved the mouse cursor a lot to exit if dx * dx + dy * dy >= 16 * 16 then love.mouse.setVisible(true) love.event.quit() end end
- コマンドラインオプションを取得して、/s の時だけ動作させる。
- /c、/p、/a、及び、コマンドラインオプション無しの場合は、いきなり終了させている。
- 何かキー入力があったら終了させる。love.keypressed(key, isrepeat) で検出。
- マウスカーソルが16ドット以上動いたら終了させる。love.mousemoved( x, y, dx, dy, istouch ) で検出。
動作確認。
love lovescr1 /s
フルスクリーン表示で、丸が動いた。
何かキーを押したり、マウスを勢いよく動かすと終了する。
◎ scr化する。 :
.loveファイルを作成。conf.lua と main.lua を、lovescr1.zip に圧縮して、.zip を .love にリネーム。
.loveファイルをexe化(scr化)する。
.loveファイルをexe化(scr化)する。
copy /b love.exe+lovescr1.love lovescr1.scrlovescr1.scr が出来上がった。
◎ 所定の場所にコピー。 :
出来上がった lovescr1.scr を、所定の場所にコピーしてみる。
今回の環境は、64bit版の Windows10。また、今回利用した love2d は 32bit版だったので、C:\Windows\SysWOW64\ に lovescr1.scr を置いてみた。
本来、lovescr1.scr と一緒に、love2d を動かすための以下のDLL群も C:\Windows\SysWOW64\ 以下にコピーしないといけないのだけど…。
こんなに大量の .dll を、C:\Windows\SysWOW64\ 以下にコピーするのはちょっとヤバイ気がするわけで。
なので、環境変数 PATH に、love2d のインストール場所を追加しておいて、.dll のコピーはしないことにする。love2d を利用する exe が実行されて、.dll が必要になったら、PATH の中から探して呼び出してくれるだろう…。たぶん。
- 32bit版 Windows の場合、C:\Windows\System32\
- 64bit版 Windows、かつ、スクリーンセーバが32bit版プログラムの場合、C:\Windows\SysWOW64\
- 64bit版 Windows、かつ、スクリーンセーバが64bit版プログラムの場合、C:\Windows\System32\
今回の環境は、64bit版の Windows10。また、今回利用した love2d は 32bit版だったので、C:\Windows\SysWOW64\ に lovescr1.scr を置いてみた。
本来、lovescr1.scr と一緒に、love2d を動かすための以下のDLL群も C:\Windows\SysWOW64\ 以下にコピーしないといけないのだけど…。
game.ico love.dll love.ico lua51.dll mpg123.dll msvcp120.dll msvcr120.dll OpenAL32.dll SDL2.dll
こんなに大量の .dll を、C:\Windows\SysWOW64\ 以下にコピーするのはちょっとヤバイ気がするわけで。
なので、環境変数 PATH に、love2d のインストール場所を追加しておいて、.dll のコピーはしないことにする。love2d を利用する exe が実行されて、.dll が必要になったら、PATH の中から探して呼び出してくれるだろう…。たぶん。
◎ 動作確認。 :
Windows10 のスクリーンセーバ設定を呼び出してみる。デスクトップ画面を右クリック → 個人用設定 → ロック画面 → スクリーンセーバー設定。
lovescr1 が選べるようになっている。
スクリーンセーバが実行されるまでの時間を1分に設定して、本当に呼びされるのか眺めてみたけれど、一応実行してくれた、ように見えている。
lovescr1 が選べるようになっている。
- プレビュー画面には、何も出てこない。/p xxxx を与えて実行した時は、即座に終了するようにしているので。
- 設定ボタンを押しても、何も出てこない。/c を与えて実行した時も、即座に終了するようにしているので。
- プレビューボタンを押すと(/s を与えて実行されると)、フルスクリーンで表示される。
スクリーンセーバが実行されるまでの時間を1分に設定して、本当に呼びされるのか眺めてみたけれど、一応実行してくれた、ように見えている。
◎ 試してみた感想。 :
何かの拍子にプロセスが残り続けたりしないか、等々が気になるし、プレビュー表示も設定画面も出せないあたりがちょっともやもやするけれど。でもまあ、一応、love2d を使って Windows用のスクリーンセーバを作れなくもないっぽい雰囲気ではあるな、と…。
ただ、動作に必要なDLL群をどこに置くか、という問題は残るなと。今回は love2d をインストールしてある環境だから動いているけれど、どの環境でも動作する形にして配布するのは結構難しそう。
ただ、動作に必要なDLL群をどこに置くか、という問題は残るなと。今回は love2d をインストールしてある環境だから動いているけれど、どの環境でも動作する形にして配布するのは結構難しそう。
[ ツッコむ ]
以上です。