2023/10/28(土) [n年前の日記]
#1 [hsp] hsp3dishについて勉強中
HSP は色々な描画プラグインが同梱されているけれど、その中の hsp3dish が気になったので試用してみることにした。OpenGL か DirectX を使って描画するらしいので、高速に描画できるのではないかと期待。
環境は Windows10 x64 22H2 + HSP 3.7 beta7。
環境は Windows10 x64 22H2 + HSP 3.7 beta7。
◎ Hello Wrold :
まずは Hello World。
_01_hello_hsp3dish.hsp
以下のような感じになった。
_01_hello_hsp3dish.hsp
; hsp3dish hello world #include "hsp3dish.as" ; use hsp3dish #packopt name "01_hello_hsp3dish" #packopt type 0 #define KB_ESC $00080 ; set font font "Tahoma", 32, font_bold *mainloop stick k, 0 ; check keyboard if k & KB_ESC : goto *job_end ; ESC key to exit redraw 0 ; draw start color 0, 100, 200 boxf ; clear screen ; draw text color 255, 255, 255 pos 10, 10 mes "Hello World" redraw 1 ; draw end. screen refresh. await (1000 / 60) ; wait 1/60 sec ;await 12 goto *mainloop *job_end end
以下のような感じになった。
- hsp3dish を使う時は、最初のほうに #include "hsp3dish.as" を書く。
- HSPの標準機能では複数の表示ウインドウを持つことが可能だけど、hsp3dish の利用時は、実際に表示できるウインドウとしてウインドウID 0 の1枚のみを持つ。らしい。
- 描画を開始する前に redraw 0 を呼び、描画が終わったら redraw 1 を呼ぶ。そうすることでウインドウに描画内容が反映される。
◎ 画像を描画 :
画像を描画してみる。せっかくだから、ファンタジーコンソール TIC-80 起動時の初期サンプルと同様に、カーソルキーで画像を移動できるようにしてみた。
_02_hello_hsp3dish_with_image.hsp
使用画像は以下。
_chara.png
以下のような感じになった。
この時点で、ちょっと気づいたことがある。
問題その1。文字を描画するとゴミが出る。上記のスクリーンショットでは、「-」の右下に変なドットが出ている。
問題その2。画像の周囲に1ドットのゴミが出る。必ずいつでも出るわけではなく、拡大描画をした際に、拡大率によっては出たり出なかったりするらしい。
もしかすると、どちらの問題も、隣のドットまで拾ってきて描画しちゃってるのかもしれない。
_celputの拡大縮小回転表示 - HSP Dishでスマホのゲームを制作、販売してニート脱出を試みる
_hsp3dishのcelputで、表示倍率マイナス指定時に1ドットずれる - HSPTV!掲示板
_celputの動作について - HSPTV!掲示板
_hsp3dishにおけるgfilter 1での拡大時の輪郭のノイズ - HSPTV!掲示板
回避策としては…。あらかじめ画像側で、描画したい領域の周辺を1〜2ドットほど透明にしておく、とか。ただ、タイルBGのようにギッシリ詰まってる系の画像では、そういうことはできないよな…。
_02_hello_hsp3dish_with_image.hsp
; hsp3dish hello world. display image. #include "hsp3dish.as" ; use hsp3dish #packopt name "02_hello_hsp3dish_with_image" #packopt type 0 ; generate ".exe" #pack "chara.png" #define KB_ESC $00080 #define KB_LEFT $00001 #define KB_UP $00002 #define KB_RIGHT $00004 #define KB_DOWN $00008 #define KB_CURSOR (KB_LEFT | KB_UP | KB_RIGHT | KB_DOWN) title "Hello world - hsp3dish" ; set window title ; set window size ; hsp3dish は表示ウインドウとしてウインドウID 0しか使えない点に注意 screen 0, 800, 600, 0 ; load image #define IMGID 3 celload "chara.png", IMGID celdiv IMGID, 16, 16, 8, 8 ; 16x16ドットで分割して管理。基準点は(8,8)に ; set font kind font "Tahoma", 24, 1 ; get window size wdwx = ginfo_winx wdwy = ginfo_winy x = wdwx / 2 y = wdwy / 2 i = 0 count = 0 ; ---------------------------------------- *mainloop stick k, KB_CURSOR ; check keyboard if k & KB_ESC : goto *job_end ; ESC key to exit ; cursor key to move spd = 4 if k & KB_LEFT : x -= spd if k & KB_RIGHT : x += spd if k & KB_UP : y -= spd if k & KB_DOWN : y += spd redraw 0 ; draw start ; clear screen color 0, 100, 200 boxf gfilter FILTER_NONE ; gfilter FILTER_LINEAR ; gfilter FILTER_LINEAR2 ; draw image gmode gmode_rgb0, IMGW, IMGH pos x, y idx = (count / 15) & 1 scale = 6.0 angle = 0.0 celput IMGID, idx, scale, scale, angle ; draw text color 255, 255, 255 pos 10, 10 mes "Hello World - hsp3dish, Push cursor key" redraw 1 ; draw end. screen refresh. await (1000 / 60) ; wait 1/60 sec ;await 12 count++ goto *mainloop *job_end end
使用画像は以下。
_chara.png
以下のような感じになった。
- screen命令でウインドウサイズを変更できる。この機能については、HSP 3.6 から対応、とドキュメントに書いてあった。以前のバージョンでは別ファイルでウインドウサイズを指定して、そのサイズに固定しておかないといけなかったらしい。
- screen命令等、ウインドウの初期化をする命令を呼ぶと、それまで読み込んでいた画像等は消滅するらしい。ウインドウの初期化が終わってから画像を読み込むこと。
- 画像を読み込む命令として picload 等も使えるらしいけど、今回は celload を使ってみた。celload, celdiv, celput を使うと、読み込んだ画像を指定サイズで分割して、n番目の領域を拡大縮小回転しながら描画することができる。
- celput は、等倍表示の時は gcopy、等倍表示ではない時は grotate 相当の描画をする命令なのだとか。
この時点で、ちょっと気づいたことがある。
問題その1。文字を描画するとゴミが出る。上記のスクリーンショットでは、「-」の右下に変なドットが出ている。
問題その2。画像の周囲に1ドットのゴミが出る。必ずいつでも出るわけではなく、拡大描画をした際に、拡大率によっては出たり出なかったりするらしい。
もしかすると、どちらの問題も、隣のドットまで拾ってきて描画しちゃってるのかもしれない。
_celputの拡大縮小回転表示 - HSP Dishでスマホのゲームを制作、販売してニート脱出を試みる
_hsp3dishのcelputで、表示倍率マイナス指定時に1ドットずれる - HSPTV!掲示板
_celputの動作について - HSPTV!掲示板
_hsp3dishにおけるgfilter 1での拡大時の輪郭のノイズ - HSPTV!掲示板
回避策としては…。あらかじめ画像側で、描画したい領域の周辺を1〜2ドットほど透明にしておく、とか。ただ、タイルBGのようにギッシリ詰まってる系の画像では、そういうことはできないよな…。
◎ 拡大縮小描画をしてみる :
せっかく celput で描画したので、拡大縮小描画を試してみる。
_celput_zoom.hsp
使用画像は以下。
_texa.png
せっかくだから、hsp3dish + celput と、HSP標準機能の celput で結果を比較してみたところ、ちょっと興味深い結果になった。動画でキャプチャしてみたけれど、前半が hsp3dish + celput、後半(01:00-)が HSP標準の celput。HSP 3.7 beta7 で動作確認。
hsp3dish + celput は、比較的滑らかに拡大表示されている。しかし、HSP標準の celput は、途中からプルプルと震え始めて、最後のあたりはもうガックンガックン状態…。
HSP標準の celput は、等倍表示は gcopy、等倍表示ではない場合は grotate を使っているという話なので、celput ではなく grotate を使ってもおそらくこんな感じの結果になるのだろうなと予想。
先日作成したスクリーンセーバで、見た目がプルプルしてしまう点について自分の書いた部分がバグってるのではないかと疑ったけど、grotate や gsquare を使うとそうなってしまうのは仕方ない、ということなのだろう…。たぶん。
_celput_zoom.hsp
; hsp3dish + celput で拡大縮小描画を試す ; ; Windows10 x64 22H2 + HSP 3.7beta7 ; 次の行をコメントアウトすれば hsp3dish を使わずに描画 #define HSP3DISH_ENABLE #ifdef HSP3DISH_ENABLE #include "hsp3dish.as" #endif #packopt name "celput_zoom" #packopt type 0 #packopt xsize 1024 #packopt ysize 768 #define TEX_FILE "texa.png" #pack TEX_FILE #define KB_ESC $000080 ; init window ID 0 screen 0, 1024, 768, 0 title "cellput zoom test - hsp3dish" wdw_w = ginfo_winx wdw_h = ginfo_winy ; load image imgid = 3 celload TEX_FILE, imgid ; 512x512 で画像を分割。基準点は(256, 512) celdiv imgid, 512, 512, 256, 512 ; 描画先を指定。ウインドウID=0 を指定 gsel 0, 1 #ifdef HSP3DISH_ENABLE ; redraw 0 を呼んだ時の画面クリア設定 ; 0 or 1, 色指定($000000 - $ffffff) setcls CLSMODE_SOLID, $4080c0 #endif scale = 0.1 idx = 0 *mainloop ; ESC key to exit stick key, 0 if key & KB_ESC : goto *jobend redraw 0 ; draw start gmode gmode_rgb0 ; αチャンネル有効、半透明無効でコピーを指定 #ifndef HSP3DISH_ENABLE ; clear screen color 64, 128, 192 boxf #endif x = int(double(wdw_w) * 0.25) y = int(double(wdw_h) * 0.90) ; draw image by crlput pos x, y celput imgid, idx, scale, scale, 0.0 ; draw text color 255, 255, 255 pos 10, 10 mes "scale = " + scale redraw 1 ; draw end. screen refersh scale += 0.01 if scale >= 8.0 { scale = 0.1 idx = (idx + 1) \ 4 } await (1000 / 60) goto *mainloop *jobend: end
使用画像は以下。
_texa.png
せっかくだから、hsp3dish + celput と、HSP標準機能の celput で結果を比較してみたところ、ちょっと興味深い結果になった。動画でキャプチャしてみたけれど、前半が hsp3dish + celput、後半(01:00-)が HSP標準の celput。HSP 3.7 beta7 で動作確認。
hsp3dish + celput は、比較的滑らかに拡大表示されている。しかし、HSP標準の celput は、途中からプルプルと震え始めて、最後のあたりはもうガックンガックン状態…。
HSP標準の celput は、等倍表示は gcopy、等倍表示ではない場合は grotate を使っているという話なので、celput ではなく grotate を使ってもおそらくこんな感じの結果になるのだろうなと予想。
先日作成したスクリーンセーバで、見た目がプルプルしてしまう点について自分の書いた部分がバグってるのではないかと疑ったけど、grotate や gsquare を使うとそうなってしまうのは仕方ない、ということなのだろう…。たぶん。
◎ hsp3dishでフルスクリーン表示をしてみたい :
hsp3dishでフルスクリーン表示をしてみたい。HSP 3.6 からはウインドウサイズをソース(スクリプト?)内から変更できるようになったとのことなので、そのあたりを試してみる。
HSP標準機能を使いつつ、フルスクリーン表示をするには、以下の考え方で実現できるらしい。
_fullscreen_hsp3dish.hsp
使用画像は以下。
_texa2.png
実行したら以下のような感じになった。縮小してるので見辛いけど、雰囲気だけは伝わるかと。
一応、フルスクリーン表示ができているように見える。しかもこれだけの面積を描画しているのに60FPS出てる。素晴らしい。
ただ、「bgscrは使うべきじゃない」というやり取りも見かけてしまって…。
_HSP3dishでWindows用のフルスクリーンゲームを作るには? - HSPTV!掲示板
何を言わんとしているのか、よく分からない…。非互換? どういうこと?
「Linux や Android で bgscr を使ったスクリプトは違う動作になるかもしれないから色んな環境で動かすことを考えたら使わないほうが良い」という話なのだろうか? でも、それはつまり、逆に考えれば、「Windows上で動かすことだけを念頭に置いているなら使っても良い」ということ…? ただ、件のやり取りは、WindowsAPI を叩きまくってフルスクリーン表示を実現できるかどうか、という話のようで…。そもそも最初から「Windows上でやれるのか?」というお題だから、Linux や Android のことは考えなくてもいいのでは…。
上記のソレは2016年頃のやり取りだから、今はまた状況が違っているのだろうか?
doclib\history.txt を確認したところ、以下の記述があった。
2016年から4年後にこういった機能が盛り込まれたわけだから、現状の HSP 3.6 や HSP 3.7beta では bgscr でフルスクリーン表示できるよ、と捉えてしまってもいいのだろうか。実際動いてるようにも見えるし…。
HSP標準機能を使いつつ、フルスクリーン表示をするには、以下の考え方で実現できるらしい。
- デスクトップのサイズを取得して、
- bgscr で枠無しウインドウを指定、かつ、デスクトップサイズと同じにして、(0, 0) の位置に表示。
_fullscreen_hsp3dish.hsp
; hsp3dish + fullscreen test ; ; Windows10 x64 22H2 + HSP 3.7beta7 #include "hsp3dish.as" #include "d3m.hsp" #packopt name "fullscreen_hsp3dish" #packopt type 0 #define TEX_FILE "texa2.png" #pack TEX_FILE #define KB_ESC $000080 #define FRAMERATE 60 ; get desktop size dispx = ginfo_dispx dispy = ginfo_dispy ; initialize window without frame bgscr 0, dispx, dispy, 0 ; load image imgid = 3 celload TEX_FILE, imgid ; split image, set orign. celdiv imgid, 512, 512, 256, 256 ; Set the buffer to draw from. Windows ID 0 gsel 0, 1 ; Set screen clear color to be performed when redraw 0 is called. ; 0 or 1, color ($000000 - $ffffff) setcls CLSMODE_SOLID, $4080c0 font "Tahoma", 24, 1 angle = 0.0 time_start = d3timer() *mainloop ; ESC key to exit stick key, 0 if key & KB_ESC : goto *jobend tm = d3timer() - time_start fps = d3getfps() angle += 0.5 redraw 0 ; draw start ; clear screen ; color 64, 128, 192 ; boxf objmax = 64 repeat objmax r = double(dispy) * 0.5 a = angle + (270.0 / double(objmax)) * double(cnt) x = int(r * cos(deg2rad(a))) + (dispx / 2) y = int(r * sin(deg2rad(a))) + (dispy / 2) d = double(cnt) / double(objmax) ; draw image by crlput gmode gmode_rgb0 ; alpha channel enabled. Semi transparency disabled. pos x, y scale = 8.0 - (7.5 * d) idx = (cnt \ 4) rot = deg2rad(angle * 2.0 + 360.0 * d) celput imgid, idx, scale, scale, rot loop color 255, 255, 255 pos 10, 10 mes strf("[%dx%d] %d/%dFPS", dispx, dispy, fps, FRAMERATE) redraw 1 ; draw end. screen refersh await (1000 / FRAMERATE) ; await 12 goto *mainloop *jobend: end
使用画像は以下。
_texa2.png
実行したら以下のような感じになった。縮小してるので見辛いけど、雰囲気だけは伝わるかと。
一応、フルスクリーン表示ができているように見える。しかもこれだけの面積を描画しているのに60FPS出てる。素晴らしい。
ただ、「bgscrは使うべきじゃない」というやり取りも見かけてしまって…。
_HSP3dishでWindows用のフルスクリーンゲームを作るには? - HSPTV!掲示板
bgscrはwindows版と非互換なのであまり使わない方がいいと思います。
何を言わんとしているのか、よく分からない…。非互換? どういうこと?
「Linux や Android で bgscr を使ったスクリプトは違う動作になるかもしれないから色んな環境で動かすことを考えたら使わないほうが良い」という話なのだろうか? でも、それはつまり、逆に考えれば、「Windows上で動かすことだけを念頭に置いているなら使っても良い」ということ…? ただ、件のやり取りは、WindowsAPI を叩きまくってフルスクリーン表示を実現できるかどうか、という話のようで…。そもそも最初から「Windows上でやれるのか?」というお題だから、Linux や Android のことは考えなくてもいいのでは…。
上記のソレは2016年頃のやり取りだから、今はまた状況が違っているのだろうか?
doclib\history.txt を確認したところ、以下の記述があった。
2020/07/09 3.6 beta3
...
[HSP3Dish][Linux] bgscr,screen命令による表示サイズ変更、及びフルスクリーン化に対応
...
2020/01/14 3.6 beta2
...
[HSP3Dish][Windows] bgscr,screen命令による表示サイズ変更、及びフルスクリーン化に対応
...
2016年から4年後にこういった機能が盛り込まれたわけだから、現状の HSP 3.6 や HSP 3.7beta では bgscr でフルスクリーン表示できるよ、と捉えてしまってもいいのだろうか。実際動いてるようにも見えるし…。
[ ツッコむ ]
以上、1 日分です。