Create a gist now

Instantly share code, notes, and snippets.

@vain0 /tiny_binary_editor.hsp Secret
Last active Aug 29, 2015

[TOY] 超簡易バイナリエディタ
/*
データを16進数表記の文字列に変換してテキストエディタに表示。それを直接書き換える。
この方針だと機能を追加するためにEditControlのWindowMessageを処理する必要があるのでHSPに向いていない。
次の記事を見て思い立って書いた。
link: 「http://hsp.tv/play/pforum.php?mode=all&num=67848 バイナリエディタの製作 - HSPTV!掲示板」
とりあえずあった方がよさそうな機能:
* ファイルの読み込み、および保存の実装。(これは自明なので読者への演習問題とする。)
* 変更を検出する。終了したりロードするときに確認し、保存を促す。
* 1バイトごとに(2文字ごとに)空白を入れる。16バイトごとに改行する。上端や下端に、00 01 02 03...0F みたいなルーラを表示する。
* 選択した範囲を(指定エンコードの)文字列として表示するとかそういうの。
* 検索や置換。
mesbox を使わない実装としては、画面をセル分割して、画面上の文字を直接触れるようにするのがいいと思う。
つまり「行単位のスクリーンテキストエディタ」(<https://gist.github.com/vain0/99a87a80bee2661f5eaa>)の2次元版。
* 各セルを1バイトとして、16進数の文字で表示。
* セルをクリックするとその上に input が重ねて表示される。それを変更して別のところをクリックすると、input が消えて、入力した内容が当該セルに対応する byte に上書きされる。
* 画面を垂直スクロールする機能。それと画面を左右で分けて、右側に文字列表記を置くのがいいと思う。(私がバイナリエディタをStirlingしか使ったことがないので、その影響を受けている。)
あまり関係ないけどバイナリエディタの例 (input を画面上に並べる): http://hsp.tv/play/pforum.php?mode=pastwch&num=25818
*/
#packopt name "simple_binary_editor"
#enum ERROR_NONE = 0
#enum ERROR_INVALID_CHAR
sdim buf
//screen
title "binary editor"
font msgothic, 12
mesbox buf, ginfo_winx, ginfo_winy - 24,, 1024
objid_edit_box = stat
button gosub "保存", *SaveFile
objid_save_button = stat
gosub *LoadFile
stop
*LoadFile
//変更点があれば保存
//gosub *SaveFile
//データをファイルから読み込む
//dialog, bload
load_data = "hello world"
data_size = 64
//データを16進表記にする
sdim buf, data_size * 2 + 1
buf_len = 0 // bufの末尾を表す変数
repeat data_size
byte = peek(load_data, cnt)
poke buf, buf_len, strf("%02X", byte)
buf_len += strsize
loop
objprm objid_edit_box, buf
return
*SaveFile
//bufの文字列をバイナリデータに戻す
err_code = ERROR_NONE
buf_len = strlen(buf)
sdim save_data, buf_len / 2
repeat buf_len / 2
byte_hex = strmid(buf, cnt * 2, 2)
repeat 2
c = peek(byte_hex, cnt)
//16進数じゃなかったらエラー
if ( (('0' <= c && c <= '9') || ('A' <= c && c <= 'F')) == 0 ) {
err_code = ERROR_INVALID_CHAR
break
}
loop
if ( err_code ) { break }
byte = int("$" + byte_hex) // 16進数の2文字→1バイト
poke save_data, cnt, byte
loop
if ( err_code ) {
dialog "error: " + err_code
return
}
//ファイルに保存
//dialog, bsave
logmes save_data
return
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment