mieki256's diary



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

#1 [hsp] hsp3dishでスクリーンセーバを作れそうか試したけど無理っぽい

Windows10 x64 22H2 + HSP 3.7beta7 で、hsp3dish を使ってスクリーンセーバを作れそうなのか試していた。

結論を先に書くと、無理っぽい。

無理な理由 :

HSP には多数のサンプルが同梱されていて、sample\ssaver\arusave.hsp がスクリーンセーバ作成のサンプルになってる。そのサンプルでは、スクリーンセーバのフルスクリーン表示モード時に、以下の処理が書かれてる。
  • HSP製プログラム実行時にデフォルトで作られる表示ウインドウ(ウインドウID0)には、一切手を付けない。
  • ウインドウID2の表示ウインドウをフルスクリーン表示で新規に作成して、そちらに描画をしていく。
HSPの標準命令のみを使ってプログラムを作れば、複数の表示ウインドウを作ることも可能だから、そういうことができるわけだけど…。

しかし、hsp3dish を使う場合は、以下の制限がある。
  • 表示ウインドウは1つしか持てない。複数の表示ウインドウは作れない。
  • プログラム実行時に作られるウインドウID0の表示ウインドウだけが、描画可能なウインドウになる。

それを踏まえた上で。

hsp3dish を使ってスクリーンセーバを作るなら…。ウインドウID2の表示ウインドウを新規作成せずに、既に存在するウインドウID0をフルスクリーン表示にして、そこに描画していけばスクリーンセーバを作れるのではないかな、などと甘いことを考えていたのだけど…。

実際にやってみたら、そうは問屋が卸さなかった。見た目だけはそれらしくなったけど、マウスを動かしたりキーボードを叩いても終了してくれないプログラムになってしまった。これではスクリーンセーバにならないわけで…。

どういう仕組みになっているのか分からないけれど、HSPでスクリーンセーバを作る際、フルスクリーンモード時では、手付かずのウインドウID0と、ガンガン描画をしていくウインドウID2、この2つの表示ウインドウが存在してる状態じゃないといけないようだなと…。

では、hsp3dish ではなく、HGIMG4 ならどうだろう。HGIMG4 なら複数の表示ウインドウを作れたりしないか? 調べてみたけれど、サンプルを眺める限り、表示ウインドウを1つしか持てないのは hsp3dish と同じらしい。HGIMG4 は hsp3dish を拡張して作られたプラグインなので、hsp3dish と同じ制限を引き継ぐ模様。

ならば HGIMG3 ではどうかとサンプルを眺めてみたら、screen命令でもう1つの表示ウインドウを確保しているサンプルが見つかった。ひょっとすると HGIMG3 を使えばスクリーンセーバが作れるのでは、と期待しているところ。実験してみないと…。

ソース :

スクリーンセーバにはならなかったけれど、デモプログラムとしては動かせるので、一応ソースを置いておく。

_h3dshscr.hsp
    ; screensaver sample for hsp3dish.
    ; fork arusave.hsp
    ;
    ; This program does not work.
    ;
    ; hsp3dish を使ってスクリーンセーバが作れるか実験したが、失敗に終わった。
    ;
    ; Windows10 x64 22H2 + HSP 3.7 beta7
    ;
    ; 2023/11/04 by mieki256
    
    #include "hsp3dish.as"
    #include "d3m.hsp"
    
    ; 以下の行のコメントアウトを外すとスクリーンセーバとして実行ファイルを作成する
    ; #define SCREENSAVER_ENABLE
    
    #define TITLE_STR   "Screensaver sample for hsp3dish"
    #define VER_STR     "0.0.1"
    
    #packopt name "h3dshscr"
    
#ifdef SCREENSAVER_ENABLE
    #packopt type 2
#else
    #packopt type 0
#endif
    
    #packopt xsize  640     ; 設定画面横幅
    #packopt ysize  360     ; 設定画面縦幅

    #define TEX_FILE        "star.png"
    #define PREVIEWFILE     "preview.png"
    #pack TEX_FILE
    #pack PREVIEWFILE
    
    #define KB_ESC      $000080
    #define FRAMERATE   60
    
    fps_display_enable = 1
    
    ; ----------------------------------------
    ; parse command line option
    
    s = dir_cmdline         ; get command line option
    i = instr(s, 0, "/")    ; "/" の出現位置を検索
   
    if i = -1 {
        ; not option
#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
    ; 設定画面
    
    screen 0, 640, 360, 0
    gsel 0
    cls
    
    tt = "Config - " + TITLE_STR + " " + VER_STR
    title tt
    font "Tahoma", 24, 1
    
    redraw 0
    color 0, 0, 0
    
    pos 20, 20
    mes "Config - " + TITLE_STR
    
    pos 20, 50
    mes "Version : " + VER_STR
    
    pos 520, 300
    button "OK", *ssend
    
    redraw 1
    stop
    
*ssend
    end

*preview_mode
    ; プレビュー画面
    ; スクリーンセーバー選択時の、小さな画面内でのプレビューの処理。
    ; HSPのWindow ID0がプレビュー画面に合わせて小さくなっているので、
    ; ginfo_winx, ginfo_winy で画面サイズを取得後、その中に描画する。
    ; 経験上、単に画像を表示してstopしたほうが不具合が起きにくい。
    wdw_w = ginfo_winx
    wdw_h = ginfo_winy
    
    ; load preview image
    imgid = 3
    w = 152
    h = 112
    buffer imgid, w, h
    picload PREVIEWFILE
    iw = ginfo_winx
    ih = ginfo_winy
    
    ; draw
    gsel 0
    redraw 0
    cls 4
    gmode gmode_gdi, iw, ih
    gzoom wdw_w, wdw_h, imgid, 0, 0, iw, ih, 1
    redraw 1
    
    stop

; ----------------------------------------
*fullscreen_mode
    ; フルスクリーン描画処理
    
    ; get desktop size
    dispw = ginfo_dispx
    disph = ginfo_dispy
    
    ; initialize window without frame
    ; bgscr WindowID, width, height, mode, x, y
    bgscr 0, dispw, disph, 0, 0, 0, dispw, disph
    
    ; 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
    setcls CLSMODE_SOLID, $000000
    
    font "Tahoma", 24, 1
    
    randomize
    
    star_size = 0.75
    dist = 150.0        ; screen distabce
    area_z = 5000
    zmax = double(area_z) + dist
    
    ; rnd() only accepts 1 to 32768.
    ; adjust the value to stay within that range.
    area_m = 4.0
    area_w = int((double(dispw) * zmax) / dist / area_m)
    area_h = int((double(disph) * zmax) / dist / area_m)
    
    objmax = 512
    
    ; initialize stars work
    ddim posx, objmax       ; position x
    ddim posy, objmax       ; position y
    ddim posz, objmax       ; position z
    dim px, objmax          ; display position x
    dim py, objmax          ; display position y
    ddim scalev, objmax     ; scale
    dim alpha, obj_max      ; alpha value
    dim patidx, obj_max     ; pattern index
    repeat objmax
        gosub *get_newpos_xy
        posx(cnt) = nx
        posy(cnt) = ny
        patidx(cnt) = idx
        posz(cnt) = double(rnd(area_z)) + dist
        px(cnt) = 0
        py(cnt) = 0
        scale(cnt) = 0.0
        alpha(cnt) = 0
    loop
    
    time_start = d3timer()
    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 stars
        spd = 40.0
        repeat objmax
            posz(cnt) -= spd
            if posz(cnt) < (dist / 2.0) {
                posz(cnt) += zmax
                gosub *get_newpos_xy
                posx(cnt) = nx
                posy(cnt) = ny
                patidx(cnt) = idx
            }
            
            ; get display x, y position
            px(cnt) = int(posx(cnt) * dist / posz(cnt)) + (dispw / 2)
            py(cnt) = int(posy(cnt) * dist / posz(cnt)) + (disph / 2)
            scalev(cnt) = star_size * dist / posz(cnt)
            
            size = int(512.0 * scalev(cnt))
            x0 = px(cnt) - (size / 2)
            y0 = py(cnt) - (size / 2)
            x1 = px(cnt) + (size / 2)
            y1 = py(cnt) + (size / 2)
            if x1 < 0 or x0 > dispw or y1 < 0 or y0 > disph {
                ; out of display area. position reset
                posz(cnt) += zmax
                gosub *get_newpos_xy
                posx(cnt) = nx
                posy(cnt) = ny
                patidx(cnt) = idx
                px(cnt) = int(posx(cnt) * dist / posz(cnt)) + (dispw / 2)
                py(cnt) = int(posy(cnt) * dist / posz(cnt)) + (disph / 2)
                scalev(cnt) = star_size * dist / posz(cnt)
            }
            
            ; get alpha value
            az = double(area_z) * 0.7
            if posz(cnt) < az {
                alpha(cnt) = 255
            } else {
                ; fade in
                z = posz(cnt)
                if z > zmax : z = zmax
                v0 = z - az
                v1 = zmax - az
                alpha(cnt) = int(255.0 - (255.0 * v0 / v1))
            }
        loop
        
        ; ----------------------------------------
        ; draw start
        redraw 0
        
        ; clear screen
        ; color 64, 128, 192
        ; boxf
        
        ; draw stars
        repeat objmax
            rot = 0.0
            idx = 0
            
            ; draw image by celput
            gmode gmode_add, 512, 512, alpha(cnt)
            pos px(cnt), py(cnt)
            rot = 0.0
            idx = patidx(cnt)
            celput imgid, idx, scalev(cnt), scalev(cnt), rot
        loop

        ; draw text
        if fps_display_enable {
            gmode gmode_rgb0
            color 255, 255, 255
            pos 10, 10
            mes strf("[%dx%d] %d/%dFPS", dispw, disph, fps, FRAMERATE)
        }
        
        ; draw end. screen refersh
        redraw 1
        
        await (1000 / FRAMERATE)
        ; await 12
    wend
    
*jobend:
    end
    
*get_newpos_xy
    nx = double(rnd(area_w) - (area_w / 2)) * area_m
    ny = double(rnd(area_h) - (area_h / 2)) * area_m
    idx = rnd(4)
    return

使用画像は以下。

_preview.png
_star.png


実行画面は以下。静止画ではさっぱり伝わらないけれど、星が奥から飛んでくるアレ。昔のWindowsに入ってた「宇宙飛行」スクリーンセーバみたいなソレ。

h3dshscr_ss.png

#2 [anime][neta] 主人公がジョブチェンジするロボットアニメはどうだろう

妄想メモ。

BS11で放送されている「ガンダムSEED」を眺めていたら、コーディネーター(遺伝子操作で作られためっちゃ頭のいい人間)の主人公がガンダムのOSを調整したことで、コーディネーターだけではなくナチュラル(遺伝子操作されてない頭の悪い人間)もそこそこ操縦できるガンダムが出来ちゃいました、というシーンが出てきた。

そのシーンを見ていて、なんとなく妄想。ひょっとしたら、あの主人公、途中でパイロットなんか辞めさせて、その後はずっとMSのOSの改良に専念させたら、軍全体の戦力が著しく増強されたのではないか、そのほうが効率良く使えたのではないかなと思えてきた。いやまあ、フィクション作品に効率がどうとか言い出してもアレなんだけど。ただ、ハードウェアは変えてないのに、ソフトウェアを変えただけで戦力増強というのは、それはそれで夢がある展開のような気もする。…ところが、その夢のOS、実はとんでもないものが仕込まれていて…って方向で話を転がしたら 「パトレイバー」になっちゃうか。

さておき。上記のような展開になるとしたら、作品としては「パイロット編」と「開発者編」で構成されることになるだろうなと…。主人公のジョブチェンジで構成されるガンダムシリーズ、もしくはロボットアニメって新規性があったりしないだろうか。

そういえば、韓国ドラマ「チャングム」も、前半は「料理人編」、後半は「医者編」で構成されてたっけ。いや、考えてみたら、NHKの朝ドラでもそういう構成はたまにある気もする。途中から、当初目指していた職業とは別の方向に行くヒロインという設定は、それなりにあったような…。であれば、ロボットアニメの類でソレをやってもおかしくはないよな…。

などと妄想していたのだけど。考えてみたら「ガンダムAGE」が結構近いのかもしれないと思えてきた。アレは世代が変わって主人公も変わるという構成だけど、初代のフリット爺さん(?)にだけ注目すると、「パイロット編」「司令官編」「老兵編」に分けられそうでもあるなと…。

あるいは、「グレンラガン」もそうかもしれない。「最前線の一兵士編」と「指導者編」になってた気もする。

ということで、主人公のジョブチェンジで各編に分かれる構成というのは、探せば結構あるのかもしれないと思えてきた。新規性は特にないなと…。

でもまあ、「主人公がジョブチェンジすることで各章が分かれる構成を考えてみましょう。さて、主人公は一体どんな職種/ポジションを経由していくでしょう?」というお題もアリかも。スポーツアニメなら「選手編」「監督編」。アイドルアニメなら「アイドル編」「事務所社長編」。色々思いつきそう。「全編通して主人公は同じ職業でなくてもよい」という点を頭の片隅に置いておくだけも何か違ってきそうな気もする…。

妄想メモです。オチはないです。

以上、1 日分です。

過去ログ表示

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