mieki256's diary



2023/11/27(月) [n年前の日記]

#1 [hsp] HGIMG3のhgrotateやhgrectのバグについて調べてた

プログラミング環境 HSP には、DirectXを利用して描画できる HGIMG3 プラグインが同梱されているのだけど。この HGIMG3 で直接描画(ダイレクト描画)ができる hgrotate や hgrect という命令について、奇数サイズを指定して描画しようとしても偶数サイズになってしまうというバグがあると今頃になって知った。 *1

_hgimg3のhgrotate命令で奇数サイズのコピーが出来ません - HSPTV!掲示板

本当にそうなるのか、Windows10 x64 22H2 + HSP 3.7 beta 7 で動作確認してみた。

結果 :

hgrotate で、16x16 の画像を、14x16, 15x16, 16x16, 17x16, ... 21x16 と描画してみたところ、以下のようになった。

hgrotate_bug2_ss.png


8倍に拡大。

hgrotate_bug2_ss_all_x8.png

たしかに、奇数サイズを指定しても、偶数サイズになってしまっている…。


hgrect はどうなるだろう。これも、14x16, 15x16, 16x16, 17x16, ... 21x16 のサイズで描画してみた。

hgrect_bug_ss01.png

hgrect_bug_ss01_x8.png

こちらも、奇数サイズを指定しているのに偶数サイズになってしまっている…。

これは参った…。hgrotate さえあれば、やりたい描画処理はおおよそできるだろうと安易に思っていたけれど、こんなバグがあるのでは…。

つまるところ、HGIMG3を使って拡大縮小描画をすると、画像の外枠と言うか、輪郭に関しては、ウインドウ解像度の約1/4の解像度でしか描画できませんよ、という状態になるのだな…。 *2

HGIMG3 は開発終了ということになっているので、このバグは修正されない可能性が高いのだろうな…。困る…。hsp3dish や HGIMG4 でスクリーンセーバを作れるなら HGIMG3 を使う必要も無さそうなのだけど、今のところ高速描画するスクリーンセーバを HSP で作りたいとなると HGIMG3 を使うしかないわけで…。まあ、「高速描画できる代わりに解像度は1/4相当」と割り切っちゃうのもアリかもしれんけど…。

ソース :

hgrotate の検証に使ったソースは以下。

_10_hgrotate_bug2.hsp
    ; hgimg3 hgrotate bug
    ; hgrotateで奇数サイズを指定しても偶数サイズにされてしまうバグの動作確認
    ; 16x16ドットの画像を、14x16, 15x16, 16x16, ... 21x16 で描画してみた
    ; たしかに、奇数サイズは偶数サイズになってしまった
    ; 2023/11/27, use HSP 3.7 beta 7
    
    #include "hgimg3.as"
    
    #packopt name   "10_hgrotate_bug2"  ; file name
    #packopt type   0   ; generate ".exe"
    
    #define TEXFILE     "tex.png"
    #pack   TEXFILE
    
    #define KB_ESC      $00080
    
    screen 0, 512, 288, 0       ; initialize screen
    wdw_w = ginfo_winx          ; get window size
    wdw_h = ginfo_winy
    hgini                       ; initialize hgimg3
    
    ; load texture
    ; * texload : alpha channel not support
    ; * texload2 : alpha channel support
    texload2 TEXFILE
    texid = stat            ; get texture ID
    
    clscolor $4080c0        ; set clear color
    
*mainloop
    stick k, 0                      ; check keyboard
    if k & KB_ESC : goto *job_end   ; ESC key to exit
    
    hgdraw          ; draw start
    
    repeat 8
        ; draw image
        
        ; set src size 16x16
        gmode gmode_rgb0, 16, 16
        
        ; set position
        x = wdw_w / 2
        y = 80 + (16 + 4) * cnt
        pos x, y
        
        src_x = 0
        src_y = 0
        rot = 0.0
        dst_w = 14 + cnt
        dst_h = 16
        hgrotate texid, src_x, src_y, rot, dst_w, dst_h   ; draw texture
    loop
    
    hgsync 15       ; draw end and wait
    goto *mainloop

*job_end
    hgbye       ; release HGIMG3 plugin
    end

使用画像は以下。

_tex.png


hgrectの検証に使ったソースは以下。

_12_hgrect_bug.hsp
    ; hgimg3 hgrect bug
    ; 2023/11/27
    ; hgrectで奇数サイズを指定しても偶数サイズにされてしまうバグについて動作確認
    ; 14x16, 15x16, 16x16, ... 21x16 で描画してみる。
    
    #include "hgimg3.as"
    
    #packopt name   "12_hgrect_bug"  ; file name
    #packopt type   0   ; generate ".exe"
    
    #define KB_ESC      $00080
    
    screen 0, 512, 288, 0       ; initialize screen
    wdw_w = ginfo_winx          ; get window size
    wdw_h = ginfo_winy
    hgini                       ; initialize hgimg3
    
    clscolor $4080c0        ; set clear color
    
*mainloop
    stick k, 0                      ; check keyboard
    if k & KB_ESC : goto *job_end   ; ESC key to exit
    
    hgdraw          ; draw start
    
    repeat 8
        gmode 0
        color 1, 1, 1
        
        ; draw rectangle
        x = wdw_w / 2
        y = 80 + (16 + 1) * cnt
        rot = 0.0
        dst_w = 14 + cnt
        dst_h = 16
        hgrect x, y, rot, dst_w, dst_h
    loop
    
    hgsync 15       ; draw end and wait
    goto *mainloop

*job_end
    hgbye       ; release HGIMG3 plugin
    end

dxgrotateを使ってみる :

前述の掲示板でのやり取りの中で、奇数サイズを指定しても正しく反映して描画できる、dx8_grot.as (dxgrotate) という追加ライブラリが紹介されている。

_hgimg3のhgrotate命令で奇数サイズのコピーが出来ません - HSPTV!掲示板 (NO.88437 を参照のこと)

コレを使えば正しく描画されるのかどうか確認してみた。

hgrotate_bugfix2_ss.png

hgrotate_bugfix2_ss_x8.png


たしかに、奇数サイズも正しく反映されているように見えた。素晴らしい。

ただ、若干動作が怪しいところもあって…。横方向のサイズのみを変化させているのに、縦方向の描画内容までずれてしまう時がある。上記のスクリーンショットで言えば、25x16 を指定して描画した際に、描画結果がおかしくなっている。

また、d3dx9_39.dll を要求するあたりも少し厳しいかもしれない。OSによってはDirectXランタイムのインストールが別途必要になりそうなので…。

検証に使ったソースと画像は以下。dx8_grot.as は、掲示板で紹介されていたものを、ほぼそのまま利用。(*main 以下は除外してある。) ありがたや。

_11_hgrotate_bugfix2.hsp
_dx8_grot.as
_tex.png

hglineはどうだろう :

画像を描画する hgrotate、矩形を描画する hgrect は奇数サイズが反映されないのは分かったけれど、線を描画する hgline はどうだろう。気になったので確認してみた。

hgline_bug_ss.png


ドットエディタ EDGE2 で該当部分(左上部分)を拡大表示。

hgline_bug_ss_xn.png


さすがに hgline は奇数サイズも描画できるっぽい…。良かった。

いや。ちょっと待て。コレもしかして描画位置がずれてないか…? (0,0)-(0,0), (0,2)-(1,2), (0,4)-(2,4), ... と描いてるはずだけど、始点座標は描画されていないように見える…。

検証に使ったソースは以下。

_13_hgline_bug.hsp
    ; hgimg3 hgline bug sample
    ; hglineで奇数サイズを指定した場合も偶数サイズにされるかどうか動作確認
    ; 2023/11/27, use HSP 3.7 beta 7
    
    #include "hgimg3.as"
    
    #packopt name   "13_hgline_bug"  ; file name
    #packopt type   0   ; generate ".exe"
    
    #define KB_ESC      $00080
    
    screen 0, 512, 288, 0       ; initialize screen
    wdw_w = ginfo_winx          ; get window size
    wdw_h = ginfo_winy
    hgini                       ; initialize hgimg3
    
    clscolor $4080c0        ; set clear color
    
*mainloop
    stick k, 0                      ; check keyboard
    if k & KB_ESC : goto *job_end   ; ESC key to exit
    
    hgdraw          ; draw start
    
    gmode 0
    color 128, 128, 128
    hgrect 8, 8, 0.0, 16, 16
    
    repeat 8
        gmode 0
        color 1, 1, 1
        
        ; draw rectangle
        x = 0
        y = 0 + (2 * cnt)
        w = cnt
        hgline x + w, y, x, y
    loop
    
    hgsync 15       ; draw end and wait
    goto *mainloop

*job_end
    hgbye       ; release HGIMG3 plugin
    end


標準機能の line を使うとどうなるだろう。試してみた。

normalline_ss.png

normalline_ss_xn.png

_13_normaline.hsp

こちらは逆に、終点座標が描画されない模様。

line にしろ、hgline にしろ、始点座標か終点座標のどちらかは描画されないのだろう…。

*1: バグなのか仕様なのか分らんけど、ドキュメントに制限事項として書いてないあたり、フツーにバグじゃないかな…。
*2: 横が2ドット単位だから、横解像度は半分になるし、縦も2ドット単位なら、縦解像度も半分になる。縦横合わせれば、1/4の解像度。もっとも、表示位置については1ドット単位でずらせるだろうから、単純にそのまま1/4の解像度になるわけでもない。

以上です。

過去ログ表示

Prev - 2023/11 - 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

カテゴリで表示

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


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

Powered by hns-2.19.6, HyperNikkiSystem Project