2023/11/06(月) [n年前の日記]
#1 [hsp] HGIMG3を使ってスクリーンセーバを作成してみた
Windows10 x64 22H2 + HSP 3.7 beta7 + HGIMG3 を使って、スクリーンセーバが作れそうか実験中。
一応、ここまでの経緯について再度メモ。
そんなわけで、HGIMG3 を使ってもスクリーンセーバを作れた、ような気がする。たぶん。github にサンプルを ―― 「宇宙飛行」スクリーンセーバと似た感じの見た目になってるスクリーンセーバをアップロードしてみた。
_mieki256/ssstarshsp: Screensaver like ssstars.scr created by HGIMG3.
余談。かなり昔にHSPで作ったスクリーンセーバは、プレビュー画面を終了する度に、Windowsイベントビューアにエラーを残してしまう状態になってしまったので、今回はそういう不具合が発生してないか気にしながら動作確認しているのだけど、今のところWindowsイベントビューアに変な記録は残っていない。スクリーンセーバとしては正常に動作している状態なのではないかなと。たぶん。そうであってほしい…。
一応、ここまでの経緯について再度メモ。
- HSPを使ってスクリーンセーバを作ったものの、HSPの標準機能による描画処理は遅かった。
- DirectX や OpenGL を利用する描画プラグインを使って、速く描画できないものかと調べ始めた。
- HSPでスクリーンセーバを作る際は、ID=2の表示ウインドウを新規作成して、ウインドウID=0とID=2の2つが存在する状態にしないといけない。
- hsp3dish と HGIMG4 は、複数の表示ウインドウを持てないので、スクリーンセーバを作れなかった。
- HGIMG3なら複数の表示ウインドウを持てるように見えたので、スクリーンセーバを作れそうかどうか試していた。
そんなわけで、HGIMG3 を使ってもスクリーンセーバを作れた、ような気がする。たぶん。github にサンプルを ―― 「宇宙飛行」スクリーンセーバと似た感じの見た目になってるスクリーンセーバをアップロードしてみた。
_mieki256/ssstarshsp: Screensaver like ssstars.scr created by HGIMG3.
余談。かなり昔にHSPで作ったスクリーンセーバは、プレビュー画面を終了する度に、Windowsイベントビューアにエラーを残してしまう状態になってしまったので、今回はそういう不具合が発生してないか気にしながら動作確認しているのだけど、今のところWindowsイベントビューアに変な記録は残っていない。スクリーンセーバとしては正常に動作している状態なのではないかなと。たぶん。そうであってほしい…。
◎ 別サンプル :
せっかくだから、ソースをもっとシンプルにしたサンプルも載せてみる。1つのボールが画面の中を跳ね回るだけの、いつもの処理にしてみた。
_sshgimg3.hsp
使用画像は以下。
_ball.png
_font.png
_preview.png
動かすと以下のような感じになる。この手のソレでよく見かける処理。
_sshgimg3.hsp
; screensaver sample for HGIMG3. fork arusave.hsp
;
; HSP + HGIMG3を使ってスクリーンセーバを作れるか実験
;
; Windows10 x64 22H2 + HSP 3.7 beta7, 2023/11/06 by mieki256
#include "hgimg3.as"
#include "d3m.hsp"
; 以下の行をコメントアウトすればexeになる
;#define SCREENSAVER_ENABLE
#define TITLESTR "Screensaver for HGIMG3"
#define VERSTR "0.0.1"
#packopt name "sshgimg3"
#ifdef SCREENSAVER_ENABLE
#packopt type 2 ; generate ".scr"
#else
#packopt type 0 ; generate ".exe"
#endif
#packopt xsize 640 ; 設定画面横幅
#packopt ysize 320 ; 設定画面縦幅
#define TEXFILE "ball.png"
#define PREVIEWFILE "preview.png"
#define FONTFILE "font.png"
#pack TEXFILE
#pack PREVIEWFILE
#pack FONTFILE
#define KB_ESC $000080
#define NWDW_ID 2
; paramater
framerate = 60
fps_disp_enable = 1
; ----------------------------------------
; コマンドラインオプションを解析
s = dir_cmdline ; コマンドラインオプション文字列を取得
i = instr(s, 0, "/") ; "/" の出現位置を検索
if i == -1 {
; オプション無し
#ifdef SCREENSAVER_ENABLE
goto *config_mode
#else
goto *fullscreen_mode
#endif
; goto *preview_mode
}
a = strmid(s, i, 2) ; 2文字だけ取り出し
if a == "/p" or a == "/P" : goto *preview_mode ; プレビュー
if a == "/s" or a == "/S" : goto *fullscreen_mode ; フルスクリーン
if a == "/c" or a == "/C" : goto *config_mode ; コンフィグ
; コマンドラインがどれでもない時はエラー表示
dialog "Unknown switch [" + s + "]"
end
*config_mode
; 設定画面モード
goto *display_config_dialog_only
*preview_mode
; プレビュー画面モード
goto *display_preview
; ----------------------------------------
*fullscreen_mode
; フルスクリーン描画処理
; デスクトップサイズを取得
dispw = ginfo_dispx
disph = ginfo_dispy
; ウインドウID=2で枠無しウインドウを新規作成
; これができないとHSPでスクリーンセーバを作れない
; bgscr WindowID, width, height, mode, x, y, width, height
bgscr NWDW_ID, dispw, disph, 0, 0, 0, dispw, disph
; HGIMG3初期化
hgini
; ビットマップフォントを設定。フォント画像を読み込み
setfont 20, 20, 18, 1 ; 20x20 font
texload FONTFILE
; 画像を読み込み
texload2 TEXFILE
texid = stat ; get texture ID
texw = 128
texh = 128
gsel NWDW_ID, 1
clscolor $000000 ; set clear color
; clsblur 24 ; set blur. 0 - 255
randomize
; ワーク初期化
x = dispw / 2
y = disph / 2
dy = double(disph) / double(framerate)
dx = dy
time_start = d3timer() ; get time
endfg = 0
; ----------------------------------------
*mainloop
while endfg == 0
tm = d3timer() - time_start
fps = d3getfps() ; get FPS
#ifndef SCREENSAVER_ENABLE
; ESC key to exit
stick key, 0
if key & KB_ESC : endfg = 1
#endif
; move ball
x += dx
y += dy
wh = texw / 2
hh = texh / 2
if (x - wh) < 0 or (x + wh) > dispw : dx *= -1
if (y - hh) < 0 or (y + hh) > disph : dy *= -1
; ----------------------------------------
; draw start
hgdraw
; clear screen
; color 64, 128, 192
; boxf
; draw ball
src_w = texw
src_h = texh
dst_w = texw
dst_h = texh
rot = 0.0
gmode gmode_rgb0, texw, texh
pos x, y
hgrotate texid, src_w, src_h, rot, dst_w, dst_h
; draw text
if fps_disp_enable {
gmode gmode_rgb0
fprt strf("[%dx%d] %d/%dFPS", dispw, disph, fps, framerate), 10, 10
}
; draw end. screen refersh. wait
t = (1000 / framerate) - 1
if t <= 0 : t = 1
hgsync t
wend ; end main loop
*jobend:
end
; ----------------------------------------
; プレビュー画面表示
; 「スクリーンセーバの変更」ウインドウ内で表示されるプレビュー処理。
; HSPのWindow ID0がプレビュー画面に合わせて小さくなっているので、
; ginfo_winx, ginfo_winy で画面サイズを取得後、その中に描画する。
;
; 経験上、単に画像を表示してstopしたほうが不具合が起きにくい。
; ここでアニメーションさせると、プログラム終了時に、
; Windowsイベントビューアにエラーが残る状態になったりする。
;
; ここではHGIMG3の描画機能を使わず、
; HSP標準の描画機能を使ってレイアウトしている。
*display_preview
; get preview window size
wdw_w = ginfo_winx
wdw_h = ginfo_winy
; load image
imgid = 3
w = 152
h = 112
buffer imgid, w, h ; reserve image buffer
picload PREVIEWFILE ; load image file
iw = ginfo_winx ; get image size
ih = ginfo_winy
; draw
gsel 0
redraw 0 ; draw start
cls 4
; 画像をウインドウ全体に引き延ばして描画
gmode gmode_gdi, iw, ih
gzoom wdw_w, wdw_h, imgid, 0, 0, iw, ih, 1
redraw 1 ; draw end. Refresh
stop
; ----------------------------------------
; 設定画面を描画
; 本来は動作パラメータを設定できるウインドウになるはず。
; 今回は、プログラム名、バージョン、終了のためのOKボタンを表示しかしない。
;
; ここではHGIMG3の描画機能を使わず、
; HSP標準の描画機能を使ってレイアウトしている。
*display_config_dialog_only
screen 0, 640, 320, 0 ; Reset window ID=0
title TITLESTR + " " + VERSTR ; set window title
gsel 0, 1 ; select window
cls ; clear window
font "Tahoma", 18, 1 ; set font kind, font size, bold
redraw 0 ; draw start
gmode gmode_rgb0
color 0, 0, 0
pos 20, 20
mes "Config - " + TITLESTR
pos 20, 50
mes "Version : " + VERSTR
pos 520, 260
button "OK", *config_end
redraw 1 ; draw end. refresh
await 15
stop
*config_end
end
使用画像は以下。
_ball.png
_font.png
_preview.png
動かすと以下のような感じになる。この手のソレでよく見かける処理。
[ ツッコむ ]
以上です。