mieki256's diary



2023/10/28() [n年前の日記]

#1 [hsp] hsp3dishについて勉強中

HSP は色々な描画プラグインが同梱されているけれど、その中の hsp3dish が気になったので試用してみることにした。OpenGL か DirectX を使って描画するらしいので、高速に描画できるのではないかと期待。

環境は Windows10 x64 22H2 + HSP 3.7 beta7。

Hello Wrold :

まずは Hello World。

_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

以下のような感じになった。

01_hello_hsp3dish_ss.png


  • hsp3dish を使う時は、最初のほうに #include "hsp3dish.as" を書く。
  • HSPの標準機能では複数の表示ウインドウを持つことが可能だけど、hsp3dish の利用時は、実際に表示できるウインドウとしてウインドウID 0 の1枚のみを持つ。らしい。
  • 描画を開始する前に redraw 0 を呼び、描画が終わったら redraw 1 を呼ぶ。そうすることでウインドウに描画内容が反映される。

画像を描画 :

画像を描画してみる。せっかくだから、ファンタジーコンソール TIC-80 起動時の初期サンプルと同様に、カーソルキーで画像を移動できるようにしてみた。

_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


以下のような感じになった。

02_hello_hsp3dish_with_image_ss.gif


  • 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
    ; 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標準機能を使いつつ、フルスクリーン表示をするには、以下の考え方で実現できるらしい。
  1. デスクトップのサイズを取得して、
  2. bgscr で枠無しウインドウを指定、かつ、デスクトップサイズと同じにして、(0, 0) の位置に表示。
この方法を、hsp3dish でも使えるのかどうか…?

_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版と非互換なのであまり使わない方がいいと思います。

HSP3dishでWindows用のフルスクリーンゲームを作るには? - HSPTV!掲示板 より


何を言わんとしているのか、よく分からない…。非互換? どういうこと?

「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 日分です。

過去ログ表示

Prev - 2023/10 - Next
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 31

カテゴリで表示

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


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

Powered by hns-2.19.6, HyperNikkiSystem Project