tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルデータ書き込みについて
記事No5975
投稿日: 2007/07/31(Tue) 23:50
投稿者area88
こんにちは、area88です。

データをセーブする際、例えば&H1B4から7ビット分だけ書き込む方法あるでしょうか?
7ビットだと、1101101の数列ですが、これをある特定のアドレスから上書きし、他の
データはそのままというふうです。
もちろん、いろんなケースもあり、&H654から25ビット分、その後に9ビット分を書き込み
というように、さまざまです。
よろしくおねがいいたします。<(_ _)>

[ツリー表示へ]
タイトルRe: データ書き込みについて
記事No5976
投稿日: 2007/08/01(Wed) 00:01
投稿者よねKEN
> データをセーブする際、例えば&H1B4から7ビット分だけ書き込む方法あるでしょうか?
> 7ビットだと、1101101の数列ですが、これをある特定のアドレスから上書きし、他の
> データはそのままというふうです。
> もちろん、いろんなケースもあり、&H654から25ビット分、その後に9ビット分を書き込み

ビット演算子Andでマスクすればよいかと。

[ツリー表示へ]
タイトルRe^2: データ書き込みについて
記事No5977
投稿日: 2007/08/01(Wed) 01:10
投稿者area88
こんにちは、area88です。

>ビット演算子Andでマスクすればよいかと。

私の持っている解説書では、あまりビット演算子が詳しく書かれていなく、
できれば、もうちょっと詳しく教えていただきたいと思います。

私の行っているプログラミングは、以下のような感じです。

ボタン1(開く)をクリックすると、

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

OpenFileDialog1.InitialDirectory = My.Computer.FileSystem.SpecialDirectories.MyDocuments
            
OpenFileDialog1.FileName = CurFileName

OpenFileDialog1.Filter = "セーブデータ(*.bin)|*.bin"

If OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
   CurFileName = OpenFileDialog1.FileName

   LoadFile() '後述のプロシージャ
   Me_Data() '後述のプロシージャ

End If

End Sub
------------------------------------------------------------------------------

ボタン1をクリックすると、ダイアログボックスからセーブテータが読み込まれます。
で、プロシージャLoadFile() 、Me_Data()の処理が行われる。

Private Sub LoadFile()

        '入力ストリームを作成する
        Dim ifs As FileStream = New FileStream(CurFileName, FileMode.Open)

        'ファイルの長さ(バイト単位)
        Dim filelen As Long = ifs.Length

        '配列を作成する
        ByteData = New Byte(filelen) {}

        'バイナリリーダーを作成する
        Dim br As BinaryReader = New BinaryReader(ifs)
        Dim count As Integer = 0
        Do While (True)
            Try
                ByteData(count) = br.ReadByte()
            Catch ex As EndOfStreamException
                Exit Do
            End Try
            count += 1
        Loop
        ifs.Close()
        FileLength = count

End Sub
-------------------------------------------------------------------------------

Private Sub Me_Data()

'バイトデータ抽出
  Dim a As String

'16進数を2進数に変換し、ビット位置から、サイズまでのデータを抽出
  Dim x As String

'総資金、総資源
  a = BitConverter.ToString(ByteData, &H656, 6).Replace("-", "")
  x = Convert.ToString(Convert.ToInt64(a, 16), 2).PadLeft(48, "0")
  TextBox1.Text = Convert.ToInt32(x.Substring(0, 24), 2) '総資金
  TextBox2.Text = Convert.ToInt32(x.Substring(24, 24), 2) '総資源

End Sub
-------------------------------------------------------------------------------

例えば、ここで総資金100000、総資源80000と読み込まれたとして、
テキストボックスの数値を、総資金200000、総資源100000に書き換え、
ボタン2(上書き保存)をクリックすると、上書き保存されるというふうにしたいのです。
その際、&H656から総資金として24ビット分、その後総資源として24ビット分のデータを書き込みたいのですが、And演算子をどう活用したらよいのか、???です。(T_T)

申し訳ありませんが、And演算子を使った少し具体的なコードを教えていただけませんか?
よろしくお願いいたします。<(_ _)>
また、バイナリデータの読み込み方は(LoadFile())、見つけたのですが、書き込み方がよくわかっていません。
できれば、上書き保存による、バイナリデータの書き込みコードも含めて教えていただければ幸いです。

[ツリー表示へ]
タイトルRe^3: データ書き込みについて
記事No5984
投稿日: 2007/08/01(Wed) 13:17
投稿者よねKEN
> その際、&H656から総資金として24ビット分、その後総資源として24ビット分の
> データを書き込みたいのですが、And演算子をどう活用したらよいのか、???です。(T_T)

当初の質問を見てAnd演算子を使えばよさそうな話かな?と思ったので、

>ビット演算子Andでマスクすればよいかと。

と回答したんですが、別の方法もありますね。
(もちろんAnd演算子を使ってもできます。ただし、シフト演算子も使います)

変数ByteDataに元々のデータがありますね。
そして、&H656バイト目から3バイト(24ビット) + 3バイト(24ビット)を置き換えた上で、
このバイト配列で元ファイルを上書きしてやればよいということになるかと思います。

まずは総資金、総資源からそれぞれ3つのバイトデータに分割する必要がありますが、
以下のようにすることでも分割できますね。(総資金200000の場合)

(1) 200000(10進数) → "030D40"(16進数の文字列。前ゼロ埋め)
(2) 2文字ずつ区切って、"03"、"0D"、"40"を数値化

--
Andとシフトを使う方法
200000を3つのバイトデータに分割するのは以下のようにしてできます。
1〜3行目はそれぞれ1〜3バイト目の値を算出する方法です。

(200000 And &HFF0000) >> 16
(200000 And &H00FF00) >> 8  
(200000 And &H0000FF)

And演算子については以下からヘルプを確認してください。
http://msdn2.microsoft.com/ja-jp/library/2h9cz2eb(VS.80).aspx

>>演算子についても同様に以下からヘルプを確認してください。
http://msdn2.microsoft.com/ja-jp/library/2d9yb87a(VS.80).aspx

[ツリー表示へ]
タイトルRe^4: データ書き込みについて
記事No5989
投稿日: 2007/08/01(Wed) 22:38
投稿者area88
こんにちは、area88です。
よねKENさん、レスありがとうございます。
もう少し、私の頭の悪さにお付き合い下さい。

前スレの24ビットのように、ちょうど3バイトに分けられる時は、
私も16進数に変換し、データを取り出していましたが、
以下のような処理もあり、どうしても2進数で取り出す必要がでてきました。

a2 = BitConverter.ToString(ByteData, &H677, 4).Replace("-", "")
x2 = Convert.ToString(Convert.ToInt32(a2, 16), 2).PadLeft(32, "0")
TextBox48.Text = Convert.ToInt32(x2.Substring(0, 7), 2) '基礎グラフ
TextBox47.Text = Convert.ToInt32(x2.Substring(7, 7), 2) 'MSグラフ
TextBox46.Text = Convert.ToInt32(x2.Substring(14, 7), 2) 'MAグラフ
TextBox45.Text = Convert.ToInt32(x2.Substring(21, 7), 2) '敵性グラフ

2進数に変換し、7ビット分取り出し、それを10進数に変換したものを、
テキストボックスに表示させます。
例えば、セーブデータ(バイナリデータ)の基礎グラフ2進数で「1000100」だと、
10進数で「68」ですね。
この「68」がテキストボックスに表示されます。
このテキストボックスで「68」を「80」に変更すると、
2進数で「1010000」になります。
で、セーブすると&H677から7ビット分、つまり「1000100」→「1010000」に置き換えたい。

私のしょぼい考えでは、10進数「80」を2進数「1010000」に変換し、
7ビット分一気に、セーブデータに上書き保存すればよいのかと。

次にMSグラフは変更なしだが、MAグラフは他の数値に変更した。
このようにして、変更したビット分を、上書き保存していきたいのです。

そこで、And演算子やシフトを用いたとき、特定のアドレス(ビット位置?)に
2進数で置き換えられるのか?という疑問がでてきました。

さらに、上記のような処理は1000ぐらいあります。(@_@;)
例えば、&H123から、初めは3ビット、続けて5ビット、9ビット、1ビットと
取り出す連続するビット数もバラバラの時もあります。
この場合、9ビット部分が変更されたら、そのビット分を上書きするみたいな。
もしくは、連続したビットなら、変更がないビットも含めて、
この場合、3ビット、5ビット、9ビット、1ビットとして、
一括して上書きしてしまうとか、、、。

取り出すのは、なんとかなったのですが、書き込むのができなくて、ジタバタしております。

すいません、やっかいな質問で。

[ツリー表示へ]
タイトルRe^5: データ書き込みについて
記事No5993
投稿日: 2007/08/02(Thu) 10:57
投稿者よねKEN
考え方を書きます。書き戻す処理のためにはOR演算子も使用します。

1バイト(=8ビット)の10進数126(2進数で01111110)から
上位5ビットを書き換える場合を例に取ります。

(1) 上位5ビットを取り出す

     01111110 ← 126
AND  11111000 ← 上位5ビットが1のマスクを用意する(10進数で248、16進数でF8)
--------------
     01111000 ・・・(a)

下位3ビットは不要なので、(a)を3ビット右にシフトすると
     00001111 ・・・(b)
となります(10進数で15、16進数でF)
これで上位5ビットを取り出せました。

(2) この15という数値を20(16進数で14、2進数で10100)に書き換えるとします。
   (この値20を(c)とする)

(3) 上位5ビットを書き戻す

まずは、元の数値126から下位3ビットのみ取り出します。
(取り出した結果を(d)とする)

     01111110 ← 126
AND  00000111 ← 上位5ビットが0のマスクを用意する(10進数の7、16進数の7)
--------------
     00000110 ・・・(d)

この(d)の値の上位5ビットを(c)の値で置き換えるために、
(c)の値を3ビット左にシフトします。結果は、
    10100000 ・・・(e)
となります(10進数で160、16進数でA0)。
(d)と(e)とをORで合成することで書き換え完了となります。

     00000110 ←(d)
OR   10100000 ←(e)
--------------
     10100110 ←10進数で166、16進数でA6

この答えを検証すると
     10100 110
     ~~~~~ ~~~
上位5ビットは書き換えた数値20になっており、
下位3ビットは元の値から引き継いだビット並びです。

[ツリー表示へ]
タイトルRe^6: データ書き込みについて
記事No6003
投稿日: 2007/08/02(Thu) 21:34
投稿者area88
こんにちは、area88です。

なーるほど考え方、よくわかりました。\(◎o◎)/!
けど、結構、複雑というか、ややこしいというか、簡単に処理できそうではありませんね。
とにかく、単純なデータ並びの処理からチャレンジしてみます。

よねKENさん、お忙しいところありがとうございました。<(_ _)>

[ツリー表示へ]