HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2013
0201
ひでぶ[HGIMG3] texmes命令に1024バイト以上の文字列を渡した場合の挙動について7解決


ひでぶ

リンク

2013/2/1(Fri) 19:27:44|NO.52129

E3Dがあんな事になってしまいましたので、新たにHGIMG3の習得に乗り出したのですが
表題の通り、texmes命令によるテキストの表示で難儀しております。

どうも凡そ1024バイト以上の内容を持つ文字列を渡すとエラーになってしまう様で、
(致命的エラーで強制終了する事もあれば、実行自体はされるものの表示されないという事もあるようです)
これが命令の仕様なのか、それとも私の環境の問題なのか、あるいは渡し方次第でどうにかなるものなのか、
…といった事柄について、どなたかお知恵を拝借したく思います。

無論、極めて単純な解決策としては
「もっと細かい単位に分割して渡す」というのが即座に思い付く所なのですが、
これではどうにも不恰好でして…



この記事に返信する


暇人

リンク

2013/2/1(Fri) 21:55:58|NO.52131

自分の環境だと1k超える文字列表示させても特にエラーは出ない



ひでぶ

リンク

2013/2/1(Fri) 22:58:48|NO.52134

>暇人さん

有難うございます。
…が、非常に申し訳ない事に、私自身が正しく症状を把握できていなかった様で
前回の投稿の内容ではエラー発生条件が不十分でした。重ねてお詫び致します。

思っていたよりもややこしい症状だったので、
最低限の構成でサンプルスクリプトを用意しました。

--------

#include "hgimg3.as" hgini texmake 640,480,0 : textbuff = stat text="" ;全角表示 ;/* repeat 511 ;ここを512以上にすると、致命的エラーで強制終了 text+"あ" loop ;*/ ;半角表示 /* repeat 1023 ;ここを1024以上にすると、実行および表示はされるが text+"a" ;1024バイト以降の文字データは無視される。 loop ;*/ hgdraw color 222,222,222 : font "MS ゴシック",20,0 texmes text,textbuff,0,0 gmode 2,640,480 : pos 320,240 : hgrotate textbuff,0,0, 0.0,640,480 hgsync 0
--------

実行環境は7sp1x64、HSPのバージョンは3.31、HGIMG3は3.31付属の物です。

そちらでテストして頂いたのが半角文字だった場合、確かにエラーは出ませんので
もし、更なるお暇があるようでしたら
お手数ですがこのサンプルで全角文字もテストして頂けると助かります。

記述不足による二度手間などと、実に許されざる有様で
真に申し訳ありません。



暇人

リンク

2013/2/1(Fri) 23:18:36|NO.52135

HSP3.32で試してたけどエラーは出ない
1k超えると文字が処理されてない現象は起きた

texmesは一行ずつ使う方が良いのかも・・・
元々毎フレーム大量に文字列書き込ませるような使い方は重くて出来ないし・・・



いなえ

リンク

2013/2/1(Fri) 23:47:16|NO.52137

同条件でエラー確認しました。
texmes用のバッファが1KBしかないのは間違いないようですね。
それも1023バイト目までしか表示されないので、
1024バイト目の文字は強制的にnull文字に置き換わるのではないでしょうか。

1023-1024バイト目に日本語を配置するとフリーズすることから、
1024バイト目がnull文字に置き換わることで規格に存在しない文字が生じ、
それをHGIMG3が処理できない、ということが原因なのかもしれません。
内部的なものは開発者にしか分からないのであくまで推測です。

よって、一回のtexmesに与える文字列は1023バイト以下にするのがよさそうです。
細かい単位に分割して渡すのが面倒なら、
それを自動で行ってくれる命令なりマクロなり書いてみてはいかがでしょう。



ひでぶ

リンク

2013/2/2(Sat) 01:26:45|NO.52138

>暇人さん

再び有難うございます。

>1k超えると文字が処理されてない現象は起きた

うぅむ…そうなると、これは現状では仕様という事になりそうですね。
画面のテキスト表示を、1枚のテキスト用テクスチャと1回のtexmes命令で完了できれば
コードの可読性という観点からも好ましいものになると考えていたのですが、
諦めて分割処理する事になりそうです。

>texmesは一行ずつ使う方が良いのかも・・・
>元々毎フレーム大量に文字列書き込ませるような使い方は重くて出来ないし・・・

HGIMG3のリファレンスにも
態々「毎フレーム呼ぶ必要は無い(≒呼ぶな)」と書いてあるくらいですので、
恐らく、もっとこまごまとしたテキスト表示を想定した命令なんでしょうね。
テキスト更新フラグを管理しつつ、こまごまやっていきたいと思います。



>いなえさん

これはどうも。
そちらのHGIMG3講座には、正に現在進行形で大層お世話になっております。
有難うございます。

分割処理を忌避する理由としては、見た目や面倒さの問題もあるのですが
それら以上に「texmes命令自体の重さ」が大きな問題になっておりまして…
(この命令、何故か、実質的な処理量を持たない筈の空文字列を渡しても
 他の命令とは比較にならないレベルの負荷が発生するようです)

その問題を回避する為に、
テキスト更新フラグで管理してメインループへの露出を最小限にすると同時に
呼び出し回数自体も最小限にしたい、というのが今回の取り組みの始点でした。

最初は、暇人さんが仰る様に1行づつtexmes命令を呼び出していたのですが
この時はテキスト更新フラグが立つ毎にCorei5のマシンがカクつくという信じ難い有様で…
現在も、変動の多い数値部分へのオリジナルフォント機能の適用なども検討しつつ
何とかしてテキスト表示を軽量化できないかと試行錯誤している次第です。



暇人

リンク

2013/2/3(Sun) 20:39:57|NO.52151

>最初は、暇人さんが仰る様に1行づつtexmes命令を呼び出していたのですが
>この時はテキスト更新フラグが立つ毎にCorei5のマシンがカクつくという信じ難い有様で…
1フレーム1行にしても?
自分の環境だと1ms程度

#include "hgimg3.as" screen 0,640,480,0 cls 4 hgini addxfile m_xmodel,dir_exe+"\\sample\\hgimg3\\font_a.x" ; モデルを読み込む regobj xobj, m_xmodel ; オブジェクトの登録 setefx xobj, $80 setuv 0,0,64,64 addplate m_plate,1,3,3 texload dir_exe+"\\sample\\hgimg3\\efx.bmp" newevent ev1 ; 新しいイベントIDを取得 event_setefx ev1, $2ff,0,0 ; 色加算モードに設定 event_setdir ev1, -0.5,-1.0,-0.5, 0.5,-1.2,0.5 event_prmon ev1,PRMSET_MODE,OBJ_MOVE|OBJ_XFRONT event_adddir ev1, 0, 0.1, 0 event_wait ev1,10 event_efx ev1, 16, $200, 0, 0 event_adddir ev1, 0, 0.1, 0 event_wait ev1,16 event_delobj ev1 newevent ev2 ; 新しいイベントIDを取得 event_setwork ev2, 0, -5, 0 event_regobj ev2, m_plate, ev1 event_regobj ev2, m_plate, ev1 event_wait ev2,1 event_jump ev2,0 setevent xobj, ev2 font "MS ゴシック",24 color 255,255,255 ; テクスチャの準備 ; texmake 256,32 timtexid = stat//処理時間 ms 表示用 texcls timtexid,0 texmes "処理時間 ms",timtexid,16,5 texmake 64,32 timdatatexid = stat//tim_c 表示用(毎フレーム書き換え) texmake 640,240 mest = stat //メッセージ用テクスチャ1 texcls mest,0 texmake 640,240 mest(1) = stat //メッセージ用テクスチャ2 texcls mest(1),0 txt="" repeat 10 repeat 26 txt+strf("%c",130)+strf("%c",160+rnd(50)) loop txt+"\n" loop split txt,"\n",txt_split texlinemax=stat rgb=rnd(50)*3+100,rnd(50)*3+100,rnd(50)*3+100 clscolor $40 *main if texline=texlinemax {//メッセージが完成してる if k&256 {//左クリック texcls mest(texno),0 texline=0 click_rl=1 rgb=rnd(50)*3+100,rnd(50)*3+100,rnd(50)*3+100 } if k&512 {//右クリック click_rl=2 texno^1//メッセージ用テクスチャ2枚を切り替え texcls mest(texno),0 texline=0 alpha=256 rgb=rnd(50)*3+100,rnd(50)*3+100,rnd(50)*3+100 } }else{//メッセージが完成してない color rgb,rgb(1),rgb(2) repeat 1,texline//一行分だけtexmes texmes txt_split(cnt),mest(texno),0,cnt*24 loop texline++ } texcls timdatatexid,0 color 255,limit(255-tim_c*16,0,255),limit(255-tim_c*16,0,255) texmes strf("%3d",tim_c),timdatatexid,0,5 addang xobj,0,0.05,0 hgdraw ; 描画処理 gmode 2,256,32 pos 256/2,50 hgrotate timtexid,0,0 gmode 2,64,32 pos 256/2+20,50 hgrotate timdatatexid,0,0 if click_rl=2 {//右クリック if texline=texlinemax { //メッセージが完成した gmode 2,640,240 pos 320+8,480-240/2-10 hgrotate mest(texno),0,0 }else{//メッセージが完成するまでにフェードアウト alpha-=(256/texlinemax) gmode 4,640,240,limit(alpha,0,256) pos 320+8,480-240/2-10 hgrotate mest(texno^1),0,0 } }else{//左クリック gmode 2,640,240 pos 320+8,480-240/2-10 hgrotate mest(texno),0,0 } hggettime tim_b,0 tim_c=tim_b-tim_a hgsync 16 ; 時間待ち hggettime tim_a,0 stick k,127 if k&128 : goto *owari ; [ESC]で終了 goto *main *owari end
常に書き換えされる処理時間の数値部分のテクスチャは小さく確保
左クリックで1フレーム1行描画してずらして追加してく表示
右クリックは裏でメッセージを完成させてから一回で表示(完成するまでに前のメッセージをフェードアウト)

裏でメッセージを完成さえるのを先読みでやっとけば
ある程度クリックからラグ無しで表示もできると思う



ひでぶ

リンク

2013/2/6(Wed) 01:12:04|NO.52196

>暇人さん
>1フレーム1行にしても?

おお、まさか「1行づつ使う」というのが、こういった形を意味していたとは…
すみません。極めて単純な方向に勘違いしておりました。
(単純にtexmes命令を細かく分けて記述するだけで、処理自体は更新フラグ検出時に一括)

いなえさんの仰る「細かい単位に分割して渡す」というのも、こういった趣旨だったのでしょうか…
折角頂いた助言の真意を理解できていなかったとは、何ともお恥ずかしい限りです。

更に、添付のサンプルも意図明快で非常に解り易く
しかも、95行目前後を少し変更するだけで瞬間負荷と処理フレーム数を自由に調節できる拡張性まであり
発想その他の点で、非常に学ぶ所の多い内容でした。
本当に有難うございました。



ONION software Copyright 1997-2023(c) All rights reserved.