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


HSPTV!掲示板


未解決 解決 停止 削除要請

2017
0119
memohsp3dishでsetreq SYSREQ_CLSMODE,0 を使うとバグる?2解決


memo

リンク

2017/1/19(Thu) 23:39:20|NO.77988

はじめまして。
簡単なメモ帳を作ってみたところパソコン上では正常に動きますが
エミュレーターや実機で動作させるとおかしくなります。

#include "hsp3dish.as"

setreq SYSREQ_CLSMODE,0

screen 0,600,800,0

redraw 0
color 255,255,255
boxf
redraw 1


color 0,0,0

*draw

redraw 0

stick pnt,256
if pnt=256 : line px,py,mousex,mousey

px=mousex
py=mousey

redraw 1

await 1
goto *draw



実機では起動すると画面が白黒に点滅しています。
次に画面を触って文字などを書こうとすると
画面が8分割くらいになってバグります。
でもその分割されたウィンドウ内では文字が書けます。
HSPのバージョンはhsp35b4aです。

過去ログをCLSMODEで検索したところCLSMODE,1 にすると画面分割バグが直ったとの
書き込みがありましたがCLSMODE,1 にすると画面がクリアされてしまうので
メモ帳に書いた文字が消えてしまって何も書けなくなってしまいます。

なんとかなりませんでしょうか?
よろしくお願いいたします。

画面分割バグの画像はこちらにあります。

http://blogs.yahoo.co.jp/blood_ex2008/41836662.html



この記事に返信する


Drip

リンク

2017/1/20(Fri) 09:45:40|NO.77989

Dripです。

memoさん、こんにちは。
早速ですが、今回ご提示されたスクリプトにはちょっと問題があるように見えます。
まずSYSREQ_CLSMODEを0に指定しますと、背景のクリアが行われなくなります。
これは例えばゲームなどで、自分で背景マップなどを描画する場合を考えてみてください。
自分で背景を描画しているのにHSP側でも背景をクリアしてしまうと二度手間(無駄な処理)に
なってしまうため、それをしないようにするオプションとしてSYSREQ_CLSMODEが提供されています。

memoさんのスクリプトを拝見いたしますと、redraw 0の後、どこにも背景を描画する処理がありません。
そうしますと、redraw 0のあと画素の転送が行われなかったピクセルについては
「どうなるかわかりません」というのが正しい動作となります。
HSPDishでは標準のHSPのように画像データをメモリ上に後から作成したり、
前の描画状態を後から利用することができない点に注意しなければなりません。
従いまして今回ご報告された現象は仕様かと思われます。SYSREQ_CLSMODE 0を利用する際は
redraw 0のあと、全画素に対して自分で責任を持って描画する必要があります。

スクリプトの内容からして落書き帳のようなものを作ろうとされていらっしゃる気がしますが、
HSPDishでそれをやろうとした場合はかなり面倒なことになります。
RPGゲームのタイルマップのように画素を自分で管理して描画するか、
全ストロークを記録して描画するなどのアイデアを使って解決しなければなりません。

…解決になるかわかりませんが、以下に「そのうち消えること」をメリットとして主張する
私なりのメモ帳のサンプルを書いてみました。何かの参考になれば幸いです。

//★ 消えるメモ帳  このアイデアやスクリプトはご自由にお使いください^^; #include "hsp3dish.as" #define mem 200 //記録する最大ストローク数(200はちょっと少ないかも。一応速度重視で。) dim dm,mem //線モード(0:なし 1:ペン 2:消し 3:終端) dim dx,mem //ストローク座標X dim dy,mem //ストローク座標Y cp=0 //現在のストロークID max=0 //最大ストロークID(memでカンスト) kesi=0 //消しペンモードフラグ oldx=-1:oldy=0 //前に描いた座標 //UIをセットアップ objsize 107,32 pos 0,0:button gosub "鉛筆",*penmode pos 107,0:button gosub "消しペン",*kesimode pos 214,0:button gosub "全消し",*alldel title "記録は"+mem+"ストロークまでです。" //メインループ repeat //★描画の内部処理 stick ky,256 if ky&256:{ if kesi:{ //消しペンモードなら if oldx!mousex | oldy!mousey:{ //前の座標と違っていればデータ入力 oldx=mousex:oldy=mousey //前の座標を今の座標で更新 dm(cp)=2:dx(cp)=oldx:dy(cp)=oldy //今の座標に「消し」データの2を入れる cp=(cp+1)\mem //cpを次のIDに送る max++:if max>mem:max=mem //データの最大量を増やす } }else{ //鉛筆モードなら if oldx!mousex | oldy!mousey:{ //前の座標と違っていればデータ入力 oldx=mousex:oldy=mousey //前の座標を今の座標で更新 dm(cp)=1:dx(cp)=oldx:dy(cp)=oldy //今の座標に「ペン」データの1を入れる cp=(cp+1)\mem //cpを次のIDに送る dm(cp)=3:dx(cp)=oldx:dy(cp)=oldy //次のデータに「終端」データの3を入れ、座標を今の座標にしておく。 max++:if max>mem:max=mem //データの最大量を増やす } } }else{ //入力がないとき if dm(cp)=3:{ //今のデータが「終端」データなら次の描画データになるとダメなので cp=(cp+1)\mem:max++:if max>mem:max=mem //cpを次のIDに送っておく } } //★ここから描画開始 redraw 0 mul=4 //インクがかすれていく強さ(大きいほどキリッと消え、小さいほどもやっと消える。※255*mulがmemを下回ると薄いインクになる。) startInk=255-(mem-max)*mul //開始インク濃度 repeat max id=(cp-max+mem+cnt)\mem //処理するIDは古いIDから ink=startInk-cnt*mul:if ink<0:ink=0 //インク濃度を求める if dm(id)=1:color ink,ink,ink:repeat 2:line dx(id)+cnt,dy(id),dx((id+1)\mem)+cnt,dy((id+1)\mem):loop //鉛筆(横長にしてカリグラフィペン風に) if dm(id)=2:color 255,255,255:circle dx(id)-15,dy(id)-15,dx(id)+15,dy(id)+15 //消しゴムはただの丸 loop //メモ帳の装飾を(横線)。これをペンより先に書くと消しゴムがおかしな表示になるので装飾を後からしています。 color 0,128,255:gmode 3,ginfo_winx-20,1,48 repeat ginfo_winy/20-5,4 grect ginfo_winx/2,cnt*20 loop redraw 1 await 30 loop *penmode //鉛筆モードにする oldx=-1:oldy=0 kesi=0 return *kesimode //消しゴムモードにする oldx=-1:oldy=0 kesi=1 return *alldel //全消しする oldx=-1:oldy=0 cp=0 max=0 return



memo

リンク

2017/1/20(Fri) 11:09:39|NO.77990

Dripさん
お返事ありがとうございます。
とても丁寧に解説していただき、原因がよくわかりました。
サンプルも家に帰って使わせていただきます。
ありがとうございました。



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