トピック
しんいち stgf1080

SBGEDのUNDO

さて、がまんできずにSBGED(スマイルツールのお絵かき)の改良に手を付けようとしてるのですが、まずは謎のUNDO、と思ってソース見ると何じゃこりゃ~な感じ。 お絵かきツールでUNDOというと、私が思い付くのはバカ正直に変更前の画像をメモリの許す限り何枚も覚えとく、という方法だったのですが、SBGEDでは処理内容(PSETなのかLINEなのか、変更前後の色、その時の座標など)を覚えといて、UNDOしたらその処理を変更前の色でやり直してるだけに見えるんだけど、そんなんでちゃんとUNDOできるのか?ってこと。できないよねぇ?。だから謎UNDOになっちゃってるんだと思うんだけど。 う~ん、こりゃぁもう叫んでもいいよね? おたんこナスゥ~!!! #かわいい感じの罵倒語をチョイスするのが #大人のやり方 直すか... 上手いUNDO方法あれば教えて下さいませ。
3そうだね
プレイ済み
返信[1]
親投稿
たぶんちゃんとした概念とかクラス分けとかあったりすると思うけど(mementoパターンとかcommandパターンとか)、smile basicだと構造体もクラスも使えないので、配列をスタック代わりに使っている感じです。 あるコマンド(ここからここへ線を引け)を実行したときに、そのコマンドを実行する前と同じようになる打ち消し(変更差分)のコマンド(ここからここへの線のうち、色はもともとそこにあった色)が undo処理になるので、作りとしてはそうなってる感じです。 何度もコマンド実行してundoで戻り続けても、コマンドごとに1つ前の打ち消しundoが実行されるので、ちゃんと最初まで戻れるって感じです。 変更前の画面メモリ全部持つのも方法ですが、1つの点を打ったのに1画面全部持っていたらメモリがたりなくなっちゃうので、最小限の打ち消し情報を持っている設計のような感じです。
1そうだね
プレイ済み
返信[2]
親投稿
同じお絵かきツール系だと、スーさんのエディタは空メモリから確保できるだけ画面全部のundo/redoバッファを持っていた感じだけど、15枚くらいまでしか持ってなかった記憶です。 打ち消しコマンドの変更差分をスタックに詰んでいく方法は、ちゃんと設計しないとどこで間違いが起きてるかデバッグが大変というのもあるので、機能追加がかなり大変というのもあったりもです。 (ついこの間お仕事でundo/redoをclassが無い環境で作ったときはデバッグで苦労した思い出)
0そうだね
プレイ済み
返信[3]
親投稿
しんいち stgf1080
UNDO用の画像まるっと全部覚えておくよりは、ちゃんと前に戻れるコマンドだけを覚えておく方が賢い方法なのは分かるんだけど、その「ちゃんと前に戻れるコマンド」ってのを実現するのが、難しいんでしょうね。 ドット打つとか線引くくらいなら、単純に変更前の色で同じことやり直せば元に戻りそうだけど、塗りつぶしはそれやっちゃダメだよね。 例えば、白で円描いて円の中心で白塗りつぶしした時に、円繋がってなくて画面全部白くなっちゃったからUNDO、ってした時に、今のSBGEDは単に変更前の色で塗りつぶすだけだから円も全て消されちゃう(T_T) そこ気付かないかなぁ。コーディングで気付かなくても使えば直ぐ分かりそうなもんだけどなぁ。使ってないんだろうなぁ(仕様だったりして^^;)。 「ちゃんと前に戻れるコマンド」でのUNDO考えて見ようかな。 #画像まるっと覚えるUNDOにヒヨる可能性大^^;
0そうだね
プレイ済み
返信[4]
親投稿
それだと塗りつぶしのundoコマンドが間違ってる感じかも。 たぶんGPAINTだけだと思うから、自作GPAINT+影響範囲しらべる(塗りつぶし場所全部覚える)を実装する必要あると思うけど、 あまりにも変更点多くて大変な条件なら影響範囲分の前画像覚えた方が早そうかも。 SBGEDとかsys/系の場合は改造してもらう前提もありそうだし、動くけど特定の場合はちょっとおかしいかも、ってのが残ってそうな感じしそうです。 結局は変更差分さえあればどのバージョンにでも戻せるっていうバージョン管理システム(gitとかsvnとかcvsとかrcsとか)と同じ理屈なので、差分ちゃんと求めるのをどうするかって感じですね。
1そうだね
プレイ済み
返信[5]
親投稿
しんいち stgf1080
近頃は、SBGED変なままなのはもう確信犯で、直したくなるように仕向けてそれでSmileBASIC覚えてね、っていう意図があるのかも、というふうに考える程になってきました^^; 差分(CVS懐かしい)管理良さそうですね。画像版diff,patch関数群みたいなのを用意できれば、汎用性もあって幸せになりそう。速度面が心配だけど、メモリ効率とのバランス考えなきゃだな。 ちょっとがんばる気になってきました(^o^) #新しいスマイルツール開発中の噂が #気になるところだけど。
0そうだね
プレイ済み
返信[6]
親投稿
すう SU-KUN
お絵かきソフトのPicsを作る時や、そのアップデートの時に、自前のPAINTや、部分アンドゥも考えたりしましたけど、プチコンの場合「1ドットずつ自前で処理する」と言うのがとてつもなく重いんですよね… コンパイラとかアセンブラとかの、ネイティブに動くものなら、多くの場合で「処理する情報量」が「処理速度」にほぼ等しくなると思いますけど、プチコンは、一度のコマンド呼び出しのオーバーヘッドが大きいので、それをいかに減らすかの方が大事だと思ってます。 よって、アンドゥも変に部分処理しようとする場合、うまくやらないと、すごく低速になっちゃいます。逆にメモリはたくさんある(特にBIG)ので、まるごとGSAVEで保存してGLOADってしてしまった方が楽だし、とても早いんですよね^^;
1そうだね
プレイ済み
返信[7]
親投稿
しんいち stgf1080
お絵かきソフトだと、どうせ解像度違うので3号互換性とか気にせず割り切ってBIG専用として作れるのがちょっと気楽。 なので確かにメモリ効率もそんなに気にしなくても良いかもしれませんね。速度もARYOP遠慮せず使えればあんまり遅くならなそうだし。 具体的なUNDO方法はこれから詰めようと思ってますが、さっき試しに変更前、変更後の画像比較して変更部分だけをUNDOバッファに格納する方式のつもりでコード追加してみたんだけど、見事にエラー^^; まずは動くUNDO実現しないとだけど、解析面倒くさいんだよなぁ。あのソースコード。 #本当にそれでSmileBASIC覚えて、ってんなら #SmileBoomのスパルタ加減が厳しいッス^^;
0そうだね
プレイ済み
返信[8]
親投稿
しんいち stgf1080
心配してたよりもあっさりと、一応動くようにはできました(^o^) たんじぇさんの仰る通り、GPAINTのUNDOだけが変だったみたい。 ただ、画面全体(1024×1024)のUNDO/REDOに3秒くらいかかっちゃう。それと何やらゴミが(REDOボタンと色パレットのカーソルらしい^^;)。まぁゴミは簡単に直せそうだけど、3秒かぁ。 私的には謎UNDO直るならそれくらいって思っちゃうけど、でも速いほうがいいよなぁ。 画像まるごと方式も考えてみようかな。最初にUNDO回数決め打ちでバッファ確保しといた方が楽そうだし(っていうか差分方式で空きメモリチェックしてOut of memory対策する方法をまだ思い付いてない^^;)。 ここんとこ絵描いてばかりでプログラミング久々だから楽しくなってきた。 #ん、プレイ日記っぽくなっちゃったな。
0そうだね
プレイ済み
返信[9]
親投稿
しんいち stgf1080
#ここで進捗挙げてていいんだろうか? #ま、いっか。 まだ画像まるごとUNDOにしてないので遅いままなのですが、ゴミ問題は解決しました(ただのおっちょこちょいだった。そして気まぐれにグラデーションを倍にしてみたり)。 UNDO方式何にするにせよ、空きメモリと確保できるUNDOバッファの関係を、きちんとお勉強しとく必要がありそうだな。 前に画像何枚も配列に突っ込んだ時は、まだFREEMEMの値に余裕ありそうだったけどOut of memoryになったことがあったような気がするので、多分プチコンのクセがあるんだろうなぁ。
0そうだね
プレイ済み
返信[10]
親投稿
画像病が速度とか配列アクセス速度とかフリーメモリが全体の空きじゃない(配列用とか文字列用途かいろいろ上限あるイメージ)とか、プチコンは結構癖あるっぽいので、たぶんGSAVE/GLOADで一括読み込みしたほうがよさそうかもです。 みなつさんが前に 512x512未満 GLOADが60fpsでも動作するって試してた感じなので、そのくらい GRP一括アクセス系は早いイメージです。
1そうだね
プレイ済み
返信[11]
親投稿
しんいち stgf1080
プチコンのメモリの扱いについて、真面目に向き合おうと思って色々試してたら、気持ち悪い現象に遭遇してしまいました(*_*) 画面は1024×1024の画像何枚取っとけるか試してたもので、20枚までになってますが、本当は28枚まで取っとけるはずなんですぅ。 というのは、最初のうちプログラム書きながら色々試してて28枚ってのを確認して、一旦プチコン終了してから再起動後、同じプログラム実行したら減っちゃったんです(T_T) 勘違いじゃないはずなんです。この減った状態から、別スロットにプログラムコピペしてちょっと変えたり変更内容セーブ無視してNEWしたり色々した後試したら28枚に戻ったのを確認してるんです。 正確な再現方法これから突き止めようと思ってますが、お手すきの方いらっしゃいましたら試して頂けると幸いです。 公開キー:JCNW334 #UNDO方式どころじゃなくなった。
0そうだね
プレイ済み
返信[12]
親投稿
だにえる haru2016nen
ああ、その現象。 僕はBIG持ってませんけど 3号で起こりますよ。 残りメモリの7~9割を仕様するような プログラム組んでると特に。 なんか残りメモリは 限界まで使えるとかじゃないっぽいです。
0そうだね
未プレイ
返信[13]
親投稿
しんいち stgf1080
本当に同様の現象なのでしょうか? 全く同じプログラム、同じ空きメモリの状況で、実行するタイミング(ここは詳細調査中)により、使える配列の大きさが変わっちゃう?3号でも? だとしたら、FREEMEMからUNDO回数決めるとかどうすりゃ良いんだろう?困ったなぁ(>_<)
0そうだね
プレイ済み
返信[14]
親投稿
しんいち stgf1080
執念のデバッグ(大袈裟か^^;)で、配列の大きさ増える現象を再現させました。 まずこのプログラム(MAX_UNDO)をスマイルツールに登録。スロット0にもロードしといてスロット0を実行。この時はまだ20枚でOut of memoryになると思うんだけど、CLEARしてからそのままDirectモードでOut of memoryになったときより大きい配列(但しDirectモードではOut of memoryにならない程度の^^;)を宣言。CLEARした後、今度はスマイルツールのMAX_UNDOを実行(これがミソなのか)。すると20枚より増えてるはず(画面すぐ消えちゃうけど)。CLEAR後、スロット0のMAX_UNDOを実行しても同じだけ増えてるはずです。 これをじわじわ繰り返した結果が画面。FREEMEM限界まで使うと30枚(別に限界ギリギリまで使いたいってことじゃないんだけどね)。
0そうだね
プレイ済み
返信[15]
親投稿
しんいち stgf1080
結局UNDOバッファ20枚(G0/G1/SP/BG 4ページあるから4分割して1ページ5枚。結構少ないな)決め打ちで作ってるとこなんだけど、画像まるごと方式でも意外と面倒で苦戦中。 しかし20枚で大丈夫なのかなぁ。FREEMEM最大だとしても使える配列の大きさハッキリしないから、これより少なくなることもあるのかなぁ。プチコン起動直後で使える配列小さくなるなんて、気持ち悪いバグだな(-_-;) 因みに3号でも似たことちょっと試したけど、再現できませんでした。3号の方が安定してるみたいだから、もっと色々複雑な条件じゃないと発生しないのかも知れませんね。
0そうだね
プレイ済み
返信[16]
親投稿
だにえる haru2016nen
そういえば 文字列操作を繰り返し時も メモリがなくなることあったなぁ。 でもその時はCLEARしても 回復しなくて、プチコン再起動しないと いけなくなったやつだから、>蒸発<かな。
0そうだね
未プレイ
返信[17]
親投稿
だにえる haru2016nen
一応、 GRPって2と3 もあるのご存知です??
0そうだね
未プレイ
返信[18]
親投稿
だにえる haru2016nen
メモリ関係のエラーといえば、あとは *PRGINS等の文字追加時に 引数の文字列が一定文字数を越える と実行されていない (エラーは表示されない)。 *DATA文1行に連なるデータの個数が 4096個を越えるとエラー。 (文字列は""で囲まれた分が1つのデータ としてカウントされる)
0そうだね
未プレイ
返信[19]
親投稿
しんいち stgf1080
は~い、知ってます(^o^) SBGEDでは編集できるGRPが0,1,4,5になってるので、それ用の4分割でした。GRP2と3は上画面、下画面のグリッドやら何やらSBGED自体のデザインに使われてるみたいです。 文字列操作での話は私もどこかで見かけたような気がしますが、CLEARできないのは厄介ですね。
0そうだね
プレイ済み
返信[20]
親投稿
PAINTする前に変更比較用にいったん画面覚えて、塗りつぶした後に変更前と全pixel比較して、変更された個数によって配列に覚えるのか、高さx幅やだけを覚えるのかすればundo bufferはGRPページ全部覚えなくてもいけそうだけど、VRAMアクセス遅いのでどのくらい時間かかるかは気になるところです。 プチコンの動的配列系(文字列含む)って、どうもメモリ連続の配列じゃないっぽかったり、配列要素変更する場合(文字列の変更も)に新しくメモリ確保して前の配列は解放されなかったり解放タイミングいつか分からなかったりっていう今時の言語を微妙にした感じの動きをしている感じ。
1そうだね
プレイ済み
返信[21]
親投稿
しんいち stgf1080
まさに塗りつぶし前後の変更ピクセルだけバッファに覚えとく方法で試したのが、3秒くらいでした(全ピクセルが変更された場合)。VRAMアクセスの遅さというよりは、変更ピクセルだけを抜き出すループで時間がかかってしまう感じでした。 ARYOPとか駆使して変更ピクセルだけの配列ごそっと作れないか考えたけど、良い方法思い付かなかった。 このためにファイルロードとかで見かけるクルクルアニメ用意したりとかしてたんだけど、Out of memoryの対策とか面倒くさくなっちゃって、結局画像まるごとUNDO回数固定方式で作っちゃいました。 需要あるか分からんし、それに間もなく新しいスマイルツールも出てきそうなところですが、せっかく作ったんで後で公開しときます。 SBGEDにはかなり手を焼かされたけど、色々勉強になったし、まぁ楽しかったかな。ありがとうSBGED。そしてさようなら(って^^;)。
0そうだね
プレイ済み