改造の館 掲示板のログ
( 1662 件中 501 - 600 件目を表示中 )

1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10

No.1321
たぶん終わりです
みろす(2010-01-17 01:40:28)

TATSU様、皆様、こんばんは。

これでたぶん、ほぼ全部だと思います。
私のメモ書きには、何も残っていませんです。

もちろん、TATSUさんや皆さんからご指摘がありましたら、即座に直していきますが、
長文のお付き合い、本当にありがとうございました。




No.1320
変数とWHILE文(2)
みろす(2010-01-17 01:26:37)


--------------------------------------------------------------------
【例題3】
アイテム番号10番のアイテムを持っているかどうかを調べたい。
所持アイテムの先頭アドレスは00072FFCで、
アイテム番号は4バイト領域の先頭に格納されている。
所持アイテム数は、1@0007340Dで参照できる。
--------------------------------------------------------------------
※PSのPE2より

まず、繰り返しを抜ける条件を決定します。
全ての所持アイテムの中から、アイテム番号10番のアイテムを探すわけ
ですから、
・所持しているアイテム番号が10番だった
・所持アイテム数だけ調べ終わった
この2つの条件のどちらかを満たせば、繰り返しを抜けることにします。

次に、使用する変数を決めます。
・所持アイテムの格納アドレス
・調べ終わったアイテム数
この2つがあれば取り敢えず良さそうですので、
格納アドレスを「%8」、アイテム数を「%9」にすることにします。

すると、コードは、
---------------------------------------
【例3】
'アドレス用に4バイト固定
SIZE %8 4
'所持アイテムの先頭アドレス
%8 = 00072FFC
'未調査アイテム数を所持アイテム数で初期化
%9 = @0007340D

'所持アイテム数だけ繰り返す
WHILE

'もしアイテム番号が10番だったら抜ける
IF @%8 == D:10
BREAK
ENDIF

'未調査アイテム数を1減らす
%9 = %9 - 1

'未調査アイテム数が0になったら抜ける
IF %9 == 0
BREAK
ENDIF

'次の所持アイテムのアドレスは+4(4バイト計算しておく)
%8 = %8 + 4

ENDWHILE
---------------------------------------
となります。

この場合、繰り返しから抜けた時に、「%9」が「0」だったら、探していた
アイテムは持っていなかったことになります。
持っていたときは、「%8」にそのアイテムの格納アドレスが残っていますので、
後の処理に使うことが出来ます。


最後は、福引をします。
--------------------------------------------------------------------
【例題4】
キャラがレベルアップしたら、福引を3回行って、賞品としてアイテムを
GETできるようにする。
当選は1等賞から4等賞まで、ハズレは残念賞とする。
当選確率と賞品はそれぞれ、
1等賞: 5%:マエダSP1箱
2等賞:10%:エアバースト1箱
3等賞:20%:R.スラッグ1箱
4等賞:40%:スパルタン1箱
残念賞:25%:リンゲル液
とし、所持アイテムが一杯だった時は福引を終了する。

00072FFC:所持アイテムの先頭アドレス
1@0007340D:所持アイテム数
1@0007340A:キャラレベル(架空の設定)

アイテムコードと単位個数
A7:25個:マエダSP1箱
AA: 4個:エアバースト1箱
AE:10個:R.スラッグ1箱
A2:50個:スパルタン1箱
3D: 1個:リンゲル液
--------------------------------------------------------------------
※PSのPE2をベースにした、架空のゲーム設定です。

まず、レベルアップごとに福引を3回だけ行うため、空きメモリに
福引をしたレベルを記録しておくことにします。
1@0007340B:福引をしたレベル

福引の抽選をするには乱数が必要ですが、MECCには
「RANDOM文」と「RAND」といううってつけの命令があります。
例えば、
---------------------------------------
【例4a】
RANDOM D:1 D:100
%0 = RAND
---------------------------------------
とすると、「%0」には1〜100までの間の乱数値が入ります。

そこで、当選確率から、
・100本の中に何本当たりがあるのか
・RANDが何番を引いたら何等賞になるのか
を決めますと、
・1等賞: 5%: 5本: 1番〜5番
・2等賞:10%:10本: 6番〜15番
・3等賞:20%:20本:16番〜35番
・4等賞:40%:40本:36番〜75番
・残念賞:25%:25本:残り全部
となります。

賞品のアイテムをGETするためには、アイテムの空きエリアを探す必要が
あります。
探すためには繰り返しをしますから、抜ける条件を決めておきます。
・空きエリアを見つけた
・最後まで探索した
これで問題ないと思います。

最後まで探索したら、さっさとコードを抜けるようにします。
後は、その空きエリアにアイテムをセットして、これらの処理をまとめて、
全部で3回行えば福引の完成です。

使用する変数は、
・%0:抽選番号
・%7:福引回数
・%8:空きアイテムエリアのアドレス
・%9:未調査アイテム数
とします。

では、コードです。
---------------------------------------
【例4】
'もしレベルが福引したレベル以下だったら終了
IF @0007340A <= @0007340B
EXIT
ENDIF

'アドレス用に4バイト固定
SIZE %8 4

'抽選番号の準備
RANDOM D:1 D:100
'福引回数をセット
%7 = 3

'所持アイテムの先頭アドレスの1つ前に初期化
%8 = 00072FFC - 4
'未調査アイテム数を所持アイテム数+1で初期化
%9 = @0007340D + 1

'福引回数だけ繰り返す
WHILE

'所持アイテム数だけ繰り返す
WHILE
'未調査アイテム数を1減らす
%9 = %9 - 1
'未調査アイテム数が0になったら終了
'(所持アイテムに空きがない)
IF %9 == 0
EXIT
ENDIF

'次の所持アイテムのアドレスは+4(4バイト計算しておく)
%8 = %8 + 4
'もしアイテム番号がなかったら抜ける
'(所持アイテムに空きがある)
IF @%8 == 0
BREAK
ENDIF
ENDWHILE

'抽選する
%0 = RAND
'繰り返しはしない
WHILE
'1等賞
IF %0 >= D:1
IF %0 <= D:5
'空きアイテムエリアに賞品をセットして抜ける
@%8 = 001900A7
BREAK
ENDIF
ENDIF

'2等賞
IF %0 >= D:6
IF %0 <= D:15
'空きアイテムエリアに賞品をセットして抜ける
@%8 = 000400AA
BREAK
ENDIF
ENDIF

'3等賞
IF %0 >= D:16
IF %0 <= D:35
'空きアイテムエリアに賞品をセットして抜ける
@%8 = 000A00AE
BREAK
ENDIF
ENDIF

'4等賞
IF %0 >= D:36
IF %0 <= D:75
'空きアイテムエリアに賞品をセットして抜ける
@%8 = 003200A2
BREAK
ENDIF
ENDIF

'残念賞
'空きアイテムエリアに賞品をセットして抜ける
@%8 = 0001003D
BREAK
ENDWHILE

'レベルアップの福引をしたことにする
0007340B @0007340A

'福引回数を1回減らす
%7 = %7 - 1
'福引回数が無くなれば終了
IF %7 == 0
EXIT
ENDIF

ENDWHILE
---------------------------------------


以上「WHILE文」のいろんな使い方を並べてみました。
最後の例題4は少々やり過ぎではありますが、実際に似たようなものを使用
していまして、中々熱くなれます。

アイテムやステータスなどの処理に関しては、いろいろと判断を加える場合、
「WHILE文」をうまく使えば、今まで簡単には出来なかった事が出来るように
なります。




No.1319
変数とWHILE文(1)
みろす(2010-01-17 01:25:49)


サイトに説明はありますが、おさらいの意味で、
まずは「WHILE文」の基本的な形から並べます。

「WHILE文」というのは、繰り返し処理をするための構文で、
「ENDWHILE文」までの間にある処理を、繰り返し処理します。
例えば、
---------------------------------------
WHILE
・・・(処理)・・・
ENDWHILE
---------------------------------------
と書きますと、永遠に(処理)をし続けます。

これでは困るので、繰り返しを止めるための命令「BREAK文」があります。
「BREAK文」は、その後に出てくる「ENDWHILE」の次の行まで、途中の行を
実行せずに飛ばします。
例えば、
---------------------------------------
WHILE
・・・(処理A)・・・
BREAK
・・・(処理B)・・・
ENDWHILE
---------------------------------------
と書きますと、(処理A)を実行した後、(処理B)を実行せずに抜けます。
この場合、繰り返しは行われません。

「WHILE文」を入れ子にした場合、
---------------------------------------
WHILE
・・・(処理)・・・
WHILE
・・・(処理)・・・
BREAK 2
ENDWHILE
・・・(処理)・・・
ENDWHILE
---------------------------------------
このような「BREAK文」で一気に抜けることもできます。
この場合も、繰り返しは行われません。

ところで、本当は繰り返し処理をしたい訳ですから、
「抜けるための条件」=「!繰り返すための条件」が必ず必要になります。
抜けるための条件を満たした時に抜けるためには、
---------------------------------------
WHILE
・・・(処理)・・・
IF 抜けるための条件
BREAK
ENDIF
・・・(処理)・・・
ENDWHILE
---------------------------------------
のように、どこかに「IF文」を書いて、その中に「BREAK文」を書きます。
そうすれば、それを満たすまでの間、処理を繰り返すことができます。


では、具体的な例で見ていきます。

--------------------------------------------------------------------
【例題1】
ふくろに持っているアイテムだけを、全て99個にしたい。
アイテムはアドレス7E3F0B〜7E4009のエリアに、
個数が1バイト数値で入っている。
--------------------------------------------------------------------
※SFCのドラクエ6のコードから拝借しました(ありがとうございます)

まず、繰り返しを抜ける条件を決定します。
これは、アドレス固定タイプのアイテムテーブルですから、最後のアイテム
のアドレスの確認が済めば、繰り返しの終了で良いと思います。
使う変数は、アイテムのアドレスとして「%8」を使用することにします。

コードは以下のようになります。
---------------------------------------
【例1】
'アドレス用に3バイト固定
SIZE %8 3
'先頭のアイテムのアドレス
%8 = 7E3F0B

'ふくろのアイテム全てに対して繰り返す
WHILE

'もしアイテムを1個以上所持していたら
IF @%8 > 0
'アイテム個数を99個にする
@%8 = D:99
ENDIF

'もし最後のアイテムアドレスになっていたら抜ける
IF %8 == 7E4009
BREAK
ENDIF

'次のアイテムアドレスは+1(3バイト計算)
%8 = %8 + 1

ENDWHILE
---------------------------------------


--------------------------------------------------------------------
【例題2】
全員のHP・MPを50、ステータスを20、それぞれ上昇させたい。
先頭キャラのベースアドレスは7E1600。
HP・MPは、7E1609〜7E1610の間に2バイト数値で入っている。
ステータスは、7E161A〜7E161Dの間に1バイト数値で入っている。
他のキャラはそれぞれアドレスを+25hで、キャラの人数は全部で16人。
HP・MPの最大値は999で、ステータスの最大値は235。
--------------------------------------------------------------------
※SFCのFF6のコードから拝借しました(ありがとうございます)

まず、繰り返しを抜ける条件を決定します。
人数の指定があるので、16人分作業したら、抜けるので良いと思います。
使う変数は、キャラのベースアドレス用に「%6」、HPMPのアドレス用に「%7」、
ステータスのアドレス用に「%8」、人数用に「%9」とします。

コードは以下のようになります。
---------------------------------------
【例2】
'アドレス用に3バイト固定
SIZE %6 3
SIZE %7 3
SIZE %8 3

'先頭キャラのベースアドレス
%6 = 7E1600
'残り人数をセット
%9 = 16

'人数分繰り返す
WHILE

'HP・MPの先頭アドレスを計算
%7 = %6 + 09
'ステータスの先頭アドレスを計算
%8 = %6 + 1A

'HP・MPを加算
@%7 = VALUE_2 + D:50; MAX=D:999;
%7 = %7 + 2
@%7 = VALUE_2 + D:50; MAX=D:999;
%7 = %7 + 2
@%7 = VALUE_2 + D:50; MAX=D:999;
%7 = %7 + 2
@%7 = VALUE_2 + D:50; MAX=D:999;

'ステータスを加算
@%8 = VALUE_1 + D:20; MAX=D:235;
%8 = %8 + 1
@%8 = VALUE_1 + D:20; MAX=D:235;
%8 = %8 + 1
@%8 = VALUE_1 + D:20; MAX=D:235;
%8 = %8 + 1
@%8 = VALUE_1 + D:20; MAX=D:235;

'残り人数を1人減らす
%9 = %9 - 1

'残り人数が0人になったら抜ける
IF %9 == D:16
BREAK
ENDIF

'次のキャラのアドレスは+25h(3バイト計算)
%6 = %6 + 25

ENDWHILE
---------------------------------------
結構長くなりました。
繰り返しを入れ子にするかどうか、微妙な状況です。

ただ、例題としてはこれで良いのですが、現実問題として見ると、
こういう単純繰り返しの場合は、もっと良い方法があります。
---------------------------------------
【例2’】
'HP・MPに50を加算
7E1609 VALUE_2 + D:50; COUNT=10; ADDRUP=25; MAX=D:999;
7E160B VALUE_2 + D:50; COUNT=10; ADDRUP=25; MAX=D:999;
7E160D VALUE_2 + D:50; COUNT=10; ADDRUP=25; MAX=D:999;
7E160F VALUE_2 + D:50; COUNT=10; ADDRUP=25; MAX=D:999;

'ステータスに20を加算
7E161A VALUE_1 + D:20; COUNT=10; ADDRUP=25; MAX=D:235;
7E161B VALUE_1 + D:20; COUNT=10; ADDRUP=25; MAX=D:235;
7E161C VALUE_1 + D:20; COUNT=10; ADDRUP=25; MAX=D:235;
7E161D VALUE_1 + D:20; COUNT=10; ADDRUP=25; MAX=D:235;
---------------------------------------
しかし、これで済んでしまうのも、MECCならではですね。。。




No.1318
変数とSIZE文(2)【2010/01/16追記修正】
みろす(2010-01-16 22:25:53)

〓〓〓〓〓〓〓〓
§掘ダ瀋衒法
〓〓〓〓〓〓〓〓

変数を使うには、まず値を設定することが必要です。

--------------------------------------------------------------------
【例1】%0 = 0
--------------------------------------------------------------------
これは、ローカル変数「%0」に「0」という値を設定しています。

--------------------------------------------------------------------
【例2】%0 = @00074888 + 80; MAX=FF;
--------------------------------------------------------------------
これは、ローカル変数「%0」に、その時の@00074888の値に80を加算したもの
を設定していますが、「MAX=FF」オプションがついていますので、計算結果が
「FF」を超える時は全て値が「FF」になります。

--------------------------------------------------------------------
【例3】%0 = 00074888
--------------------------------------------------------------------
これは、ローカル変数「%0」に「00074888」という値を設定しています。
ちなみに、こう書いても「%0」のバイト数が4バイトになる訳ではありません。


以上のような行の形を、一般的には「代入式」と呼び、右辺の計算式の計算結果を
左辺の変数に代入・格納・設定します。

右辺には計算式と「MAX=」「MIN=」オプションが書けますので、今までに出た
ほとんどの書式が使用できますが、「メモリ書込み」ではありませんので、
メモリ書込み関係のオプションや「VALUE系」は使用できません。


〓〓〓〓〓〓〓〓
§検ネ用方法
〓〓〓〓〓〓〓〓

変数の利用方法は、置きたい数値の変わりに、その変数名を書くだけです。

--------------------------------------------------------------------
【例4】000XXXXX %0
--------------------------------------------------------------------
その時の「%0」の値を、000XXXXXに書き込みます。
処理バイト数は、「%0」が数値項ですので、その値のバイト数に応じて、自動
的に変わります。

--------------------------------------------------------------------
【例5】000XXXXX %0 + 000001
--------------------------------------------------------------------
その時の「%0」の値に「000001」を加算して、000XXXXXに書き込みます。
処理バイト数は、「%0」の値のバイト数と、「000001」の3バイトの、大きい
方のバイト数になります。

--------------------------------------------------------------------
【例6】%0 = @00074888 + %0; MAX=%0;
--------------------------------------------------------------------
意味はともかく、こんな形も書けます。

オプションだろうが何だろうが、基本的に、数値の書ける所であれば、
どこにでも変数を書く事ができます。

<2010/01/16追記>
〜〜〜〜〜〜〜〜
--------------------------------------------------------------------
【例7】WAIT %0
--------------------------------------------------------------------
仮に「%0」に「1000」を設定している時に、こう書くと、
「WAIT 1000」
と同じ意味になります。

※「WAIT文」に使用する場合には「注意」が必要です。

「WAIT文」のパラメータは「10進数」として解釈される仕様のようですので、
パラメータに書く「変数」には「BCD値」を入れておく必要があるようです。

「BCD値」とは、16進数の桁数で10進数を表現した値のことで、例えば、
本来なら16進数の「1000」は10進数で「4096」のことですが、
BCD値の「1000」は文字通り10進数の「1000」の意味になります。
(16進数のふりをした10進数だとも言える)

そのため、
「%0 = 1000」と書くと「WAIT %0」は「WAIT 1000」となり問題ありませんし、
「%0 = D:4096」と書いても「WAIT %0」は「WAIT 1000」となり問題ありませんが、
「%0 = D:1000」と書くと「WAIT %0」は「エラー」になります。

また、計算結果を変数に入れて利用する場合は、特に注意が必要で、
例えば「%0 = 1000」「WAIT %0」でコードを動かしていた場合、
WAIT時間を半分にしようと思って「%0 = %0 / 2」としても、
「WAIT %0」は「WAIT 800」になりますので、意図通りのWAIT値にはなりません。

そこで計算値でWAIT値をコントロールするような用途では、以下のような、
BIN→BCD変換処理を通してから「WAIT文」に使用する必要があります。
---------------------------------------
【例7a】
'BIN(%0)→BCD(%9)→WAIT %9
'待ち時間(%0)をWAIT文パラメータ(%9)に変換する
'(ただし9999msecまで)
%1 = %0; MAX=D:9999;
%4 = %1 / D:1000
%1 = %1 - %4 * D:1000
%3 = %1 / D:100
%1 = %1 - %3 * D:100
%2 = %1 / D:10
%1 = %1 - %2 * D:10
%9 = 0000 + %4 < C | %3 < 8 | %2 < 4 | %1
WAIT %9
---------------------------------------
こうしておけば、「%0」は普通に計算で使用できますので、
計算結果でWAIT値をコントロールすることができます。
〜〜〜〜〜〜〜〜

--------------------------------------------------------------------
【例8】COPY %0 000735E0 %1
--------------------------------------------------------------------
仮に「%0」に「00074888」、「%1」に「10」を設定している時に、こう書くと、
「COPY 00074888 000735E0 10」
と同じ意味になります。

--------------------------------------------------------------------
【例9】RANDOM %0 %1
--------------------------------------------------------------------
仮に「%0」に「1」、「%1」に「100」を設定している時に、こう書くと、
「RANDOM 1 100
と同じ意味になります。

--------------------------------------------------------------------
【例10a】000XXXXX @%0
【例10b】000XXXXX 2@%0; COUNT=%1;
--------------------------------------------------------------------
仮に「%0」に「00074888」、「%1」に「10」を設定している時に、こう書くと、
「000XXXXX @00074888」
「000XXXXX 2@00074888; COUNT=10;」
と同じ意味になります。

※「%0 @000XXXXX」という書き方はできません→次の例をご参照ください

--------------------------------------------------------------------
【例11】@%0 = @000XXXXX + 1; SIZE=2;
--------------------------------------------------------------------
この形だけは特殊で「メモリ書込み式」と言えます。

仮に「%0」に「00074888」を設定している時に、こう書くと、
「00074888 @000XXXXX + 1; SIZE=2;」
という「メモリ書込み文」と同じ意味になります。

この形は「メモリ書込み」処理そのものですので、
「SIZE=」「COUNT=」「ADDRUP=」など、全てのオプションが使えます。

※ちなみに「2@%0 = 〜」という書き方は出来ません


以上まとめますと、
---------------------------------------
【変数の使える場所】
 ○数値の書けるところ
 ○メモリ読出し命令のアドレス値
 ○メモリ書込み式の左辺
 △WAIT文のパラメータ
---------------------------------------
【変数の使えない場所】
 ×メモリ書込み文のアドレス部
---------------------------------------



No.1317
バイト数(1)【2010/01/16追記修正】
みろす(2010-01-16 14:17:23)

まず大前提として、メモリに読み書きする場合、必ずバイト数を何バイトに
するのかを決めないと処理できません。
PARコードでも、必ず書き込みバイト数が決められています。
MECCコードでも、この処理するバイト数が一番重要な事項になっています。

--------------------------------------------------------------------
MECCコードの動作は、1行ごとに、

A:処理バイト数の決定(全ての項のバイト数の最大に合わせる)

R:読み出し

C:計算

W:書き込み

の基本4サイクルで動いていると思われます。(便宜的に名前をつけています)
そして、Aで決まった処理バイト数が、後のR・C・W全ての処理に
対して制限を加えます。
※意図的に処理バイト数を明示した場合を除く
--------------------------------------------------------------------

ポイントは、Cの計算処理にも、Aの処理バイト数が影響していることです。
当初は、このAの処理の存在が、見え隠れしていたために悩みました。
(計算に関しては次回します)

ですが、3.110以降1本筋の通った仕様になっていますので、ここさえ押さえ
てしまえば、MECCコードが非常に理解しやすくなっていると思います。


例えば、
--------------------------------------------------------------------
【例1】00XXXX @00YYYY - 01
--------------------------------------------------------------------
この行で、MECCの動作を脳内トレースしてみると、

<A処理>
@00YYYY:可変項(他項のバイト数に合わせるが、可変項のみの場合は1バイト)
01:1バイトの16進数
→処理バイト数を「1」に決定(全ての項のバイト数の最大に合わせる)

<R処理>
@00YYYY:00YYYYから「1」バイトの数値を読み出す

<C処理>
@00YYYY - 01:「1」バイト数値同士で計算して結果を出す

<W処理>
00XXXX:求めた結果を00XXXXに「1」バイトで書き込む

という具合です。
もう1つ似た例で、
--------------------------------------------------------------------
【例2】00XXXX @00YYYY - 0001
--------------------------------------------------------------------
の場合ですと、

<A処理>
@00YYYY:可変項(他項のバイト数に合わせるが、可変項のみの場合は1バイト)
0001:2バイトの16進数
→処理バイト数を「2」に決定(全ての項のバイト数の最大に合わせる)

<R処理>
@00YYYY:00YYYYから「2」バイトの数値を読み出す

<C処理>
@00YYYY - 0001:「2」バイト数値同士で計算して結果を出す

<W処理>
00XXXX:求めた結果を00XXXXに「2」バイトで書き込む

となります。
この例2で、00YYYYが1バイトデータのメモリだった場合は、
--------------------------------------------------------------------
【例3】00XXXX 1@00YYYY - 0001
--------------------------------------------------------------------
と書きます。

<A処理>
1@00YYYY:1バイト読出し
0001:2バイトの16進数
→処理バイト数を「2」に決定(全ての項のバイト数の最大に合わせる)

<R処理>
1@00YYYY:00YYYYから「1」バイトの数値を読み出して「2」バイト数値にする。
・処理バイト数は「2」ですが、直接指定した「1」バイト指定が優先します。
・読み出した1バイトデータを、処理バイト数の「2」バイトに合わせます。

<C処理>
1@00YYYY - 0001:「2」バイト数値同士で計算して結果を出す

<W処理>
00XXXX:求めた結果を00XXXXに「2」バイトで書き込む

となります。
ここで「@00YYYY系」の書式をまとめますと、
---------------------------------------
@00YYYY:可変バイト数読出し
1@00YYYY:1バイト読出し
2@00YYYY:2バイト読出し
3@00YYYY:3バイト読出し
4@00YYYY:4バイト読出し
---------------------------------------
です。

逆に、例1で、00XXXXが2バイトデータのメモリだった場合は、
--------------------------------------------------------------------
【例4】00XXXX @00YYYY - 01; SIZE=2;
--------------------------------------------------------------------
と「Size=」オプションを付けて、書き込みバイト数を2バイトに変更します。

<A処理>
@00YYYY:可変項(他項のバイト数に合わせるが、可変項のみの場合は1バイト)
01:1バイトの16進数
→処理バイト数を「1」に決定(全ての項のバイト数の最大に合わせる)

<R処理>
@00YYYY:00YYYYから「1」バイトの数値を読み出す

<C処理>
@00YYYY - 01:「1」バイト数値同士で計算して結果を出す

<W処理>
00XXXX:求めた結果を00XXXXに「2」バイトで書き込む
・処理バイト数は「2」ですが、Size=指定があるとそのバイト数で書き込まれます。

「SIZE=系」の書式をまとめますと、
---------------------------------------
SIZE=1:1バイト書込み
SIZE=2:2バイト書込み
SIZE=3:3バイト書込み
SIZE=4:4バイト書込み
---------------------------------------
となります。

例4は、例3と同じように見えますが、例3では計算が2バイトになるため、
状況によっては書き込まれる数値が変わってきます。
(計算に関しては次回します)



No.1316
IF文とフラグ(2)【2010/01/16追記修正】
みろす(2010-01-16 14:05:02)


条件Aと条件Bがあったとします。
---------------------------------------
【命題】
AとBが共に成立した時だけ
コードを走らせたい
---------------------------------------
こんなケースがあったとします。
(例えば、戦闘中にR3ボタンを押した時、とか)
こういう時は、IF文を並べます。
--------------------------------------------------------------------
【例4a】
IF Aが成立
IF Bが成立
・・・(処理)・・・
ENDIF
ENDIF
--------------------------------------------------------------------
特に難しいところは無いと思います。

今度は、
---------------------------------------
【命題】
AとBのどちらかが成立した時に
コードを走らせたい
---------------------------------------
とします。
普通に書くと、
--------------------------------------------------------------------
【例5a】
IF Aが成立
・・・(処理)・・・
ENDIF
IF Bが成立
・・・(処理)・・・
ENDIF
--------------------------------------------------------------------
こうなりますが、同じ処理を2回書かないといけないのが不満です。
なので、各条件を反対条件にしてみます。

AとBのどちらかが成立=(AとBが共に不成立)ではない、
という意味になりますから、
--------------------------------------------------------------------
【例5b】
C=0
IF Aが不成立
IF Bが不成立
C=1
ENDIF
ENDIF

IF C == 0
・・・(処理)・・・
ENDIF
--------------------------------------------------------------------
うーん・・・確かに処理は1回で済みましたが、何か無駄に長いです。
余計な条件Cまで出てきますし。。。

そこで比較条件そのものを、論理演算に変換してみましょう。

# 以降の説明の中で、例えば、
# A=@00XXXX
# B=@00YYYY
# C=@00ZZZZ
# とすればコードらしくなりますが、ABCの方が読みやすいと思いますので、
# 以降も、ABC記述で統一します。

条件A・Bともゼロイチフラグにして、1で成立、0で不成立とします。
すると、AとBのどちらかが成立というのは、
「A|B!=0」と置き換えれますから、
--------------------------------------------------------------------
【例5c】
IF (A|B) != 0
・・・(処理)・・・
ENDIF
--------------------------------------------------------------------
と、シンプルに書くことができます。

実は、例4aも、この論理演算を使えば、もっとシンプルに書けました。
--------------------------------------------------------------------
【例4b】
IF (A&B) != 0
・・・(処理)・・・
ENDIF
--------------------------------------------------------------------
こうなります。
前回、いろいろとしつこいくらいにフラグの話を書いた所以です。

次はもう少し複雑な条件を見てみましょう。
---------------------------------------
【命題】
所持金を1万以上持っている時は、条件Aが1の時
所持金が1万未満の時は、条件Bが1の時
以上の時に、コードを走らせたい
---------------------------------------
こんな条件になると、全てフラグを使わないと、行が多く複雑になって大変です。
そこで、AとBは既にゼロイチフラグになっていますから、新たに、
「条件C=所持金を1万以上持っている」
というゼロイチフラグを作ってしまいます。
(前回のお話の中で作り方は書いています)

それらを用いれば、
命題の1行目は「C&A」と書けますし、2行目は「!C&B」と書けます。
「!C」とはCの反対の意味、すなわち「C^01」と書けますから、
これら2行を「|」で繋いで、
--------------------------------------------------------------------
【例5】
IF (C^01 & B | C & A) != 0
・・・(処理)・・・
ENDIF
--------------------------------------------------------------------
と書いて出来上がり・・・
と言いたいところだったのですが、実はこの場合は少々拙いのがわかりました。
「&」と「|」の優先順位が同じなので、このままだと、左から順に計算していって、
「C^01 & B | C」と「A」を「&」演算することになってしまいます。
「C&A」を先に演算して欲しい・・・

そこで対策として、演算の一部を四則演算に置き換えることを考えてみました。
ゼロイチフラグにさえしていれば、
・論理和=加算(和)
・論理積=積算(積)
という形で、論理演算を四則演算に置き換えができる場合があります。
--------------------------------------------------------------------
【例5’】
IF (C^01 & B | C * A) != 0
・・・(処理)・・・
ENDIF
--------------------------------------------------------------------
この形であれば、「C*A」の優先順位が高いので先に計算され、
その計算結果もゼロイチフラグになりますから、
後は、左から順に計算されて万事解決です。

<2010/01/16追記>
〜〜〜〜〜〜〜〜
なのですが・・・
実はもっと良い方法あるのです。
優先順位を上げたい演算「C&A」を、()で括ってしまう方法で、
TATSUさんからご指摘を受けました。
--------------------------------------------------------------------
【例5''】
IF (C^01 & B | (C & A)) != 0
・・・(処理)・・・
ENDIF
--------------------------------------------------------------------
こうすれば「C&A」を一番最初に演算してくれるようになりますので、
これで優先順位の問題は完全に解決ですね。
〜〜〜〜〜〜〜〜



No.1315
Re:改造コードと投稿コードについて
管理人TATSU(2010-01-16 13:43:40)

モナドマンダラ様

TATSUです。
ご連絡いただきありがとうございます。

先日投稿コードの整理をしていた際に、
誤ってタイトル一覧から消してしまったようです。申し訳ありません。

投稿コードのPSの欄に戻しておきましたのでご確認をお願いいたします。
ご迷惑をおかけして申し訳ありませんでした。

また何かありましたらご連絡をお願いいたします。

以上です。


No.1314
Ootake Ver 2.27
ちこ(2010-01-16 11:44:35)

Ootake Ver 2.27がリリースされていました。
MECCの設定値は2.26と同じのようです。

管理人TATSUさんのお時間のある時に、ご確認をよろしく
お願いいたします。


No.1312
改造コードと投稿コードについて
モナドマンダラ(2010-01-16 10:58:20)

どうもモナドマンダラです。
さて今年初めての質問です。

僕が投稿したPSのドラゴンクエスト7の改造コードが見当たらなくなっています。
新たにコードサーチしたので投稿しようと前の投稿コードの欄を見ましたところ投稿コードのPSの欄に、ありませんでした。
僕は管理人TATSU様が改造コードの欄に移しているのかなと思い改造コードの欄を見ましたところ、ありませんでした。
ほかの改造コードは、ちゃんと投稿コード欄にありました。
僕が投稿した改造コードが消えているので気になったので書き込みさせていただきました。

管理人TATSU様大変恐縮とは思いますが確認をお願いします。

本当に、ご迷惑かけて、すいません。
−以上です−


No.1311
Re:IF文とフラグ(1)
みろす(2010-01-16 10:07:05)

TATSU様、いつも大変お世話になっております。
情報ありがとうございます。

>()内で計算された値が必ず4バイトになってしまうという現象です。

ほんとですね。。。
気がつきませんでした。

>あと、説明していなかったかもしれませんが、
>実は()は一般的な数式と同じような使い方ができます。

はい。これも気がつきませんでした。
ちょっと試してみましたが、IF文の()内計算式だけの仕様ですね?
これは便利です。
条件判定の優先順位で悩む必要がなくなります。
早速修正しなくては。

こうして、いろいろと書いてみるものですねぇ。。。
嬉しい事が舞い降りてきます^^



No.1310
Re:IF文とフラグ(1)
管理人TATSU(2010-01-16 09:30:50)

みろす様

TATSUです。
MECCコードの説明ありがとうございます。

今回のif文を読んでこちらで確認していて、()を使った場合の不具合を見つけました。
()内で計算された値が必ず4バイトになってしまうという現象です。

例えば以下のようなコードの場合、
if (50+5) == @7E0000
アドレス7E0000の値が55であれば処理を実行しますが、
上記のコードだとアドレス7E0000から4バイトで読み込まれてしまいます。

これについては次回のバージョンアップ時に修正しておきます。
不具合の発見につながって助かりました。


あと、説明していなかったかもしれませんが、
実は()は一般的な数式と同じような使い方ができます。
具体的には以下のようなコードを記述可能です。
if ((50+5)*100+55) == @7E0000
上記のif文だと、7E0000から2バイト読み出し、値が5555だとコードが実行されます。
()により計算の優先順位を変更することが可能ですので、
何かの機会に使ってみてください。


以上です。


No.1309
変数とSIZE文(3)
みろす(2010-01-16 05:49:57)


〓〓〓〓〓〓〓〓
§后ケ用例
〓〓〓〓〓〓〓〓

以上のように、基本的な利用の仕方は見てきましたが、変数ならではの利用
方法を考えてみます。

ゲームには、よくデータテーブルが存在します。

例えば、アイテム一覧とか、金額テーブルであるとか、キャラのステータス
テーブルであるとか、ゲームによってその種類は様々です。
よく改造コードで「以降は+08ずつ」とかありますが、あれもテーブルです。

テーブルのインデックスも、アイテム番号だったり、キャラ番号だったり、
そのテーブルの目的に応じて様々です。

仮に改造コードの中で、そのテーブル値を参照したいとします。
引っ張ってくるデータは、そのテーブルの先頭アドレスに、インデックス値
×増分値を加えたアドレスにあります。

となると、コードの中でその格納アドレスを計算しないといけません。

---------------------------------------
【例題】
アイテム番号1の値段がアドレス「0010D9C4」
に2バイトで格納されていて、以降+08バイト
毎に格納されている時、カーソルで指定した
アイテムの値段を取得したい。
アイテム番号は1バイトで、カーソルで指定
しているアイテム番号を「@0010EAC8」で取得
できるのはサーチ済み
---------------------------------------

データテーブルの先頭アドレスが「10D9C4」ですが、そのアイテム番号が1番
ですので、まず、アイテム番号0番のアドレスを求めます。
それを先頭アドレスとすれば、取得したい値段の格納されたアドレスは、

「格納アドレス=0番のアドレス+アイテム番号×8」

で計算できますから、その格納アドレスから2バイトデータを読み出せば良い
ことになります。

以上の内容をそのままコードにすると、
--------------------------------------------------------------------
【例12】
%0 = 0010D9C4 - 8
%1 = %0 + @0010EAC8 * 8
%2 = 2@%1
--------------------------------------------------------------------
となりますが、これではうまく動きません。

2行目の「%0」は数値項ですので、実際の値は「10D9BC」の3バイトになっ
ていますから、@0010EAC8が3バイト読出しをしてしまいます。

修正したコードは以下の通りです。
--------------------------------------------------------------------
【例12a】
%0 = 0010D9C4 - 8
%1 = %0 + 1@0010EAC8 * 8
%2 = 2@%1
--------------------------------------------------------------------
これで無事に、指定したアイテムの値段を取得できました。

アイテム番号が1バイトですので、2行目の処理バイト数は3バイトのままで
大丈夫そうですが、今後別のアドレスに流用した時のことを考えて、4バイト
にしておいても良いかもしれません。

その場合は、
--------------------------------------------------------------------
【例12b】
%0 = 0010D9C4 - 8
%1 = %0 + 1@0010EAC8 * 00000008
%2 = 2@%1
--------------------------------------------------------------------
と書きます。

ところで・・・

もし、こういう桁合わせが何回も出てきて、その時の使用変数が、
例えば「%0」で決まっているのであれば、
--------------------------------------------------------------------
【例13】SIZE %0 4
--------------------------------------------------------------------
という「SIZE文」を、最初に書いておくと、「%0」の処理バイト数が常に
4バイトになって、例12bのように書く必要はなくなります。

ただ、有効である間は全ての行に影響を与えますので、
--------------------------------------------------------------------
【例13a】
SIZE %0 4
00XXXX @00YYYY + %0
--------------------------------------------------------------------
のように書くと、処理バイト数が4バイトになってしまうため、
@00YYYYは4バイト読出しを行います。

この変数に対する「SIZE文」の有効範囲は、変数の有効範囲と同じで、
例13や例13aの場合は、その項目のみで有効となります。

従って、
--------------------------------------------------------------------
【例14】SIZE $0 2
--------------------------------------------------------------------
のようにグローバル変数を指定した場合は、これ以降、最後の項目の実行が
終わるまで有効です。

もう1つ、
--------------------------------------------------------------------
【例15】SIZE ADDR 1
--------------------------------------------------------------------
こう書いた場合は、処理サイズが可変項のアドレス読出し命令のサイズを、
1バイトに固定します。

「@00XXXX」や「@%0」や「VALUE」などが、「1@00XXXX」や「1@%0」や「VALUE_1」
などと同じになります。

例えば、
--------------------------------------------------------------------
【例15a】
SIZE ADDR 1
SIZE %0 4
00XXXX @00YYYY + %0
--------------------------------------------------------------------
と書いた場合、3行目の処理バイト数は、大きい項に合わされますから4バイト
になりますが、@00YYYYは1バイト読出しを行います。

「SIZE文」は、このように計算式に作用しますので、「IF文」の場合は、
()内に書いた読出し命令だけが影響を受けます。

例えば、
--------------------------------------------------------------------
【例15b】
SIZE ADDR 4
IF @00XXXX == 0
--------------------------------------------------------------------
と書いた場合、「IF文」の左項は1バイトしか読出しませんが、
--------------------------------------------------------------------
【例15c】
SIZE ADDR 4
IF (@00XXXX) == 0
--------------------------------------------------------------------
と書いた場合は、「IF文」の左項は4バイトを読み出します。

このアドレスに対する「SIZE文」の有効範囲は、その項目のみです。


以上のいずれの場合も、「SIZE文」で指定した固定バイト数を、途中で解除
したい場合は、「SIZE文」の固定バイト数に「0」を指定します。

ここで「SIZE文系」をまとめておきます。
--------------------------------------------------------------
  −−−−  メモリ読出し  ローカル変数  グローバル変数
  固定解除  SIZE ADDR 0   SIZE %0 0    SIZE $0 0
1バイト固定  SIZE ADDR 1   SIZE %0 1    SIZE $0 1
2バイト固定  SIZE ADDR 2   SIZE %0 2    SIZE $0 2
3バイト固定  SIZE ADDR 3   SIZE %0 3    SIZE $0 3
4バイト固定  SIZE ADDR 4   SIZE %0 4    SIZE $0 4
  有効範囲  その項目    その項目    最後の項目まで

※変数番号は代表で0番を指定していますが、全て指定可能です
--------------------------------------------------------------


さて、変数の応用例では、もう1つ大切な使われ方があります。
それは「WHILE文」との組み合わせです。
これについては、次回に書こうと思います。




No.1308
変数とSIZE文(2)
みろす(2010-01-16 05:49:25)


〓〓〓〓〓〓〓〓
§掘ダ瀋衒法
〓〓〓〓〓〓〓〓

変数を使うには、まず値を設定することが必要です。

--------------------------------------------------------------------
【例1】%0 = 0
--------------------------------------------------------------------
これは、ローカル変数「%0」に「0」という値を設定しています。

--------------------------------------------------------------------
【例2】%0 = @00074888 + 80; MAX=FF;
--------------------------------------------------------------------
これは、ローカル変数「%0」に、その時の@00074888の値に80を加算したもの
を設定していますが、「MAX=FF」オプションがついていますので、計算結果が
「FF」を超える時は全て値が「FF」になります。

--------------------------------------------------------------------
【例3】%0 = 00074888
--------------------------------------------------------------------
これは、ローカル変数「%0」に「00074888」という値を設定しています。
ちなみに、こう書いても「%0」のバイト数が4バイトになる訳ではありません。


以上のような行の形を、一般的には「代入式」と呼び、右辺の計算式の計算結果を
左辺の変数に代入・格納・設定します。

右辺には計算式と「MAX=」「MIN=」オプションが書けますので、今までに出た
ほとんどの書式が使用できますが、「メモリ書込み」ではありませんので、
メモリ書込み関係のオプションや「VALUE系」は使用できません。


〓〓〓〓〓〓〓〓
§検ネ用方法
〓〓〓〓〓〓〓〓

変数の利用方法は、置きたい数値の変わりに、その変数名を書くだけです。

--------------------------------------------------------------------
【例4】000XXXXX %0
--------------------------------------------------------------------
その時の「%0」の値を、000XXXXXに書き込みます。
処理バイト数は、「%0」が数値項ですので、その値のバイト数に応じて、自動
的に変わります。

--------------------------------------------------------------------
【例5】000XXXXX %0 + 000001
--------------------------------------------------------------------
その時の「%0」の値に「000001」を加算して、000XXXXXに書き込みます。
処理バイト数は、「%0」の値のバイト数と、「000001」の3バイトの、大きい
方のバイト数になります。

--------------------------------------------------------------------
【例6】%0 = @00074888 + %0; MAX=%0;
--------------------------------------------------------------------
意味はともかく、こんな形も書けます。

オプションだろうが何だろうが、基本的に、数値の書ける所であれば、
どこにでも変数を書く事ができます。

※「WAIT文」には使用できません(無理やり使うことはできますが・・・)

--------------------------------------------------------------------
【例7】COPY %0 000735E0 %1
--------------------------------------------------------------------
仮に「%0」に「00074888」、「%1」に「10」を設定している時に、こう書くと、
「COPY 00074888 000735E0 10」
と同じ意味になります。

--------------------------------------------------------------------
【例8】RANDOM %0 %1
--------------------------------------------------------------------
仮に「%0」に「1」、「%1」に「100」を設定している時に、こう書くと、
「RANDOM 1 100
と同じ意味になります。

--------------------------------------------------------------------
【例9】000XXXXX @%0
--------------------------------------------------------------------
仮に「%0」に「00074888」を設定している時に、こう書くと、
「000XXXXX @00074888」
と同じ意味になります。

※「%0 @000XXXXX」という書き方はできません→【例11】をご参照ください

--------------------------------------------------------------------
【例10】000XXXXX 2@%0; COUNT=%1;
--------------------------------------------------------------------
仮に「%0」に「00074888」、「%1」に「10」を設定している時に、こう書くと、
「000XXXXX 2@00074888; COUNT=10;」
と同じ意味になります。

--------------------------------------------------------------------
【例11】@%0 = @000XXXXX + 1; SIZE=2;
--------------------------------------------------------------------
この形だけは特殊で「メモリ書込み式」と言えます。

仮に「%0」に「00074888」を設定している時に、こう書くと、
「00074888 @000XXXXX + 1; SIZE=2;」
という「メモリ書込み文」と同じ意味になります。

この形は「メモリ書込み」処理そのものですので、
「SIZE=」「COUNT=」「ADDRUP=」など、全てのオプションが使えます。

※ちなみに「2@%0 = 〜」という書き方は出来ません


以上まとめますと、
---------------------------------------
【変数の使える場所】
 ○数値の書けるところ
 ○メモリ読出し命令のアドレス値
 ○メモリ書込み式の左辺
---------------------------------------
【変数の使えない場所】
 ×メモリ書込み文のアドレス部
 △WAIT文のパラメータ
---------------------------------------




No.1307
変数とSIZE文(1)
みろす(2010-01-16 05:48:17)


変数は、うまく使えば、コードの機能と実行速度を上げる事ができますが、
慣れない方には、取っ付きにくい印象がどうしてもあると思います。
でもでもですね、メモリへのアクセスの方がよっぽど難しいんですよ。


〓〓〓〓〓〓〓〓
§機ゼ鑪
〓〓〓〓〓〓〓〓

MECCの変数には、グローバル変数とローカル変数の2種類があります。
---------------------------------------
【グローバル変数】$0〜$9までの10個
【ローカル変数】 %0〜%9までの10個
---------------------------------------
「グローバル」「ローカル」というのは、変数の有効範囲の違いからそう
呼んでいるだけで、変数そのものの働きに違いはありません。

--------------------------------------------------------------------
メモリアクセス→項目1の実行→項目2の実行→・・・→最後の項目の実行
--------------------------------------------------------------------
というMECCの処理サイクルに対して、最後の項目の実行が終わるまでずっと
有効なのが「グローバル変数」で、項目1なら項目1、項目2なら項目2、
というふうに、その項目の中だけで有効なのが「ローカル変数」です。
従って、ローカル変数は、項目の数だけ、同じ名前だけど別の変数が存在します。

注意点としては、値を何も入れずにいきなり使用すると、動作が変になる恐れが
あることですが、普通はそんなことはしないと思います。
また、次の周回以降も有効にしておきたいデータは、変数ではなく、どこか空き
メモリを使うしかありません。

変数の大切な特徴としては、処理バイト数に関しては「10進数」と同じ扱いで、
「数値項」だということです。
従って、後で説明するサイズ固定文を使用しない限り、変数の処理バイト数は、
設定している数値のバイト数で決まってしまいます。


〓〓〓〓〓〓〓〓
§供セ箸錣貶
〓〓〓〓〓〓〓〓

では、どんな時に使うか、です。

例えば、前回、
$3 = @00071D55 | @00071D40 | @00072192; Max=1;
という行がありました。
こういう、計算処理した値を、そのコード内で使いたい時、変数に設定しておくと、
以降の行が見やすくなる場合があります。

また、同じアドレスが何度もコード内で出てくる時、変数に設定しておくことで、
見た目をシンプルにすることができます。
見た目がシンプルになるのは重要で、間違いが発生しにくいというメリットもあ
ります。

他には、何種類かコードがある時で、共通の計算結果が必要な時は、先頭の
項目でグローバル変数に設定しておけば、各項目で共通して使用できます。
(何度も計算する必要がないので速くなる)
もし、後でその計算式を変えたくなった場合でも、その1箇所だけを変更すれば
良いので、メンテナンス性が上がります。




No.1306
コード実行(2)
みろす(2010-01-15 14:51:32)


ということで、話を戻します。
今回は、HP・MPとも、1秒ごとに1ポイント回復するようにしましょう。
自動的にコードを適用させますので、コード実行は常時実行タイプにします。

では、コードの構造設計です。
--------------------------------------------------------------------
【構造1】
フラグの準備をする
IF キャラを操作していたら
:HPとMPを1ポイント回復させる
:ただし回復はそれぞれ最大値まで
:1秒WAITを入れる
ENDIF
--------------------------------------------------------------------
構造的には簡単なので、これで大丈夫のはずです。

それでは実際に書いてみます。
--------------------------------------------------------------------
【コード1】
'方向操作をしているフラグ
$0 = @000722F5 & F0; Max=1;
'特殊画面になっているフラグ
$3 = @00071D55 | @00071D40 | @00072192; Max=1;

'もし、特殊画面以外で方向操作をしていたら
IF ($3 ^ 01 & $0) != 0

'HP最大値を取得
%0 = 2@0007488A
'MP最大値を取得
%1 = 2@0007488E

'HP現在値を1ポイント回復(HP最大値まで)
00074888 VALUE_2 + 1; MAX=%0;
'MP現在値を1ポイント回復(MP最大値まで)
0007488C VALUE_2 + 1; MAX=%1;

'1秒間次の実行を待つ
WAIT 1000

ENDIF
--------------------------------------------------------------------
以上です。
掲示板なので、行頭のスペースなど、インデントは入れていません。
こんな処理を簡単に書けてしまうのが、MECCの素晴らしいところですね。

# ここでは、変数を4つ使っています。
# グローバル変数「$0」「$3」と、ローカル変数「%0」「%1」です。
# 変数についての詳細は次回に書こうと思いますが、
# 変数と言うものに馴染みのない方は、例えばコードの中に、
#---------------------------------------
# <変数名A> = <計算式A>
#---------------------------------------
# という行を書いておけば、
# <変数名A>には、<計算式A>の<計算結果A>が設定されますので、
# 以降のコードの中で、仮に、
#---------------------------------------
# MAX=<変数名A>
#---------------------------------------
# というコードがあった場合は、
# そのまま、
#---------------------------------------
# MAX=<計算結果A>
#---------------------------------------
# のように置き換えられる、というふうに解釈をお願いします。

ところで、実はTATSUさんから、EXIT命令を入れた方が速いケースがある、
というお話が以前ありました。
このコードのように、全体をIF文で囲っているような場合、条件にそぐわない
ケースで最後まで実行するのは処理時間の無駄だというお話で、言われてみま
すと確かに無駄です。
特に、私のように負荷の重たい環境で使用している場合は、尚更です。

そこで、条件にそぐわない場合は、EXIT命令でさっさとコードから抜けてしま
うようにしてみます。
--------------------------------------------------------------------
【例2】EXIT
--------------------------------------------------------------------
この命令があると、以降の行の実行をせずに、その項目から抜け出します。

--------------------------------------------------------------------
【構造2】
フラグの準備をする
IF キャラを操作していなかったら終了
EXIT
ENDIF

HPとMPを1ポイント回復させる
ただし回復はそれぞれ最大値まで
1秒WAITを入れる
--------------------------------------------------------------------
構造的にはこんな感じですね。

--------------------------------------------------------------------
【コード2】
'方向操作をしているフラグ
$0 = @000722F5 & F0; Max=1;
'特殊画面になっているフラグ
$3 = @00071D55 | @00071D40 | @00072192; Max=1;

'もし、特殊画面だったり、方向操作をしていなかったりしたら終了
IF ($0 ^ 01 | $3) != 0
EXIT
ENDIF

'HP最大値を取得
%0 = 2@0007488A
'MP最大値を取得
%1 = 2@0007488E

'HP現在値を1ポイント回復(HP最大値まで)
00074888 VALUE_2 + 1; MAX=%0;
'MP現在値を1ポイント回復(MP最大値まで)
0007488C VALUE_2 + 1; MAX=%1;

'1秒間次の実行を待つ
WAIT 1000
--------------------------------------------------------------------
コードもこんな感じ、ある意味すっきりしました。
途中「($0 ^ 01 | $3) != 0」は「($3 ^ 01 & $0) == 0」と書いても同じです。


さて次は、いよいよ変数のお話をしようと思います。
今までも、ちょこちょこっと変数を使用してきましたが、変数を使う事でしか
できないコードもありますので、丁寧に書いてみたいと思います。




No.1305
コード実行(1)
みろす(2010-01-15 14:49:37)


今回は、これまでに書いてきた内容を使って、簡単なコードを作ってみます。
その中で、MECCにおけるコード実行について、書いてみようと思います。

これから作るコードの対象ゲームはPE2で、内容はドラクエよろしく、
---------------------------------------
【内容】
キャラを操作していれば、
徐々にHPとMPが回復していく
---------------------------------------
とします。

まず、どんなデータが必要なのかを考えます。
キャラを操作しているとは、

・方向キーかアナログスティックを入力していること
・メニュー画面でないこと
・マップ画面でないこと
・PE選択中でないこと
・イベント中でないこと

つまり、
「あらゆる特殊画面でない時に、方向操作をしていたら」
ということになります。
そこで、これら特殊画面のフラグと、方向操作のフラグを探しださないと
いけませんですね。
また「徐々に」は後で考えるとして、HPとMPを回復させるわけですから、

・HPの現在値と最大値
・MPの現在値と最大値

も必要です。
という事で、サーチの開始です。

---------------------------------------
方向キーかアナログスティックを入力していること
---------------------------------------
@71E9A:生方向キー(上位4ビット負論理)
@71E9E:生左アナログスティック(80センター・1バイト×2軸)
@72344:左アナログスティック(0000センター・2バイト×2軸)
@722F5:方向キー+左アナログスティック合成(上位4ビット正論理)
@721E9:さらにゲームが止まる画面では内容が保持される

方向操作関係は探しやすいです。
いろんなデータがありましたが、@722F5を使うことにします。
--------------------------------------------------------------------
$0 = @000722F5 & F0; Max=1;
--------------------------------------------------------------------
データは、上位4ビットの正論理で入っていましたので、
グローバル変数「$0」に、ゼロイチフラグの形で入れておきます。

---------------------------------------
メニュー画面でないこと
マップ画面でないこと
PE選択中でないこと
イベント中でないこと
---------------------------------------
@72192:マップ画面・PE選択中・メニュー画面
@71C56:イベント進行・マップ画面・メニュー画面
@71D40:イベント進行・マップ画面・メニュー画面
@71D55:イベント発生数(画面が切り替わったりムービーが動いたり)
@71D5A:メニュー画面

これらのフラグも、実際にモードに入れたり外したりしながら探せば、
割合簡単に見つかりました。
これらの中から、全てを網羅できる組み合わせとして、
@72192と@71D40と@71D55を使うことにします。
--------------------------------------------------------------------
$3 = @00071D55 | @00071D40 | @00072192; Max=1;
--------------------------------------------------------------------
取り敢えず、特殊画面になっていることを示すフラグとして、
グローバル変数「$3」に、ゼロイチフラグの形で入れておきます。

---------------------------------------
HPの現在値と最大値
MPの現在値と最大値
---------------------------------------
@74888:HP現在(2byte)
@7488A:HP最大(2byte)
@7488C:MP現在(2byte)
@7488E:MP最大(2byte)

こういう定量データも割合見つけやすいですね。
これらは直接使うことにします。


一通りのサーチが終わったので、目的の動作をどう実現するかを考えます。
「徐々に」というからには、1秒に1ポイントとか、2秒に1ポイントとか、
そんな感じで回復していくのが、それらしい感じです。

ちょうど、MECCにはそういうのに使える便利な命令がありました。
--------------------------------------------------------------------
【例1】WAIT 1000
--------------------------------------------------------------------
こうすれば1秒間、コード実行を止めてくれます。
と言ってしまうと語弊がありますね。。。


良い機会ですので、TATSUさんにもお伺いしながら、試してみながら、いろいろ
わかってきた、MECCのコード実行の方法を書いてみます。
細かいところは、TATSUさんのフォローを期待するとしまして・・・

TATSUさんに伺ったお話と、MECC右下に表示される数値から、
---------------------------------------
メモリアクセス

項目1の全ての行を実行

項目2の全ての行を実行

・・・

メモリ更新間隔時間だけ待つ

始めに戻る
---------------------------------------
実際には、こんな感じになっているのではないかと思われます。

ここで、項目1に「WAIT命令」があったとします。
TATSUさんにお伺いすると、「WAIT命令」があると、その項目の実行を一旦抜けて、
次の項目の実行に移る、という事でしたので、項目2に実行が移ります。
項目2の実行が終わると、またその次の項目、という具合に進み、一周してきた時、
指定時間が経過していなければ、また項目1は飛ばして、項目2に実行が移る、
そんなご説明だったと思います。

という事は、WAIT中に、他の項目で同じメモリを書き換えてしまう、という事が
起こりえるのではないかと思われます。
ので、項目の処理の途中に「WAIT命令」を入れる場合は、辻褄がおかしくならな
いよう、命令順序には少し気を配るようにしています。

逆に、わざと「WAIT 1」という命令を入れて、他の項目を先に実行させ、次の周で
WAITから復帰した時にその結果を利用する、という使い方もあるのではないかと、
密かに考えていまして、いつか実践してみたい腹案の1つです。。。
(全然密かじゃないですけど(笑))




No.1303
IF文とフラグ(3)
みろす(2010-01-15 02:19:18)


最後は、実際にあった私の失敗例から・・・
---------------------------------------
【命題】
初日なら25個まで、
2日目以降なら50個まで、
アイテム個数を増やす改造ができる
---------------------------------------
まず、コード実行に必要な条件を考えますと、
条件A:2日目かどうか
条件B:アイテム個数が25個未満(25個だと改造しない)
条件C:アイテム個数が50個未満(50個だと改造しない)
ですから、ゲームのメモリからこれらのフラグを探します。

すると、2日目になると必ず、@00073540のbit2の値が1になることが
わかりました。
他のビットの値は、そこに至るまでのゲーム状態で変化するようですので、
ビットフラグとして処理することにします。
---------------------------------------
$5 = @00073540 > 2 & 01
---------------------------------------
前に書きましたように、このビットフラグをゼロイチフラグに変換処理して、
グローバル変数「$5」に入れておきます。
変数については今は詳しく書きませんが、コードの中で「$5」が出てきたら、
上の計算式の「結果値」と置き換えられる、という動作になります。
これで、条件Aが片付きました。

次に、条件Bと条件Cを探しますがありません。
と言いますか、25個と50個というのは、私が勝手に作った数値ですので、
あるわけがありませんですね。
そこで、アイテム個数のデータを探すことにします。

すると、@0007340Dの1バイトに、現在のアイテム個数の値が入っていることが
わかりましたので、取り敢えず、
---------------------------------------
$7 = @0007340D
---------------------------------------
グローバル変数「$7」に入れておきます。

条件Bは25個未満であること、
条件Cは50個未満であることですので、
---------------------------------------
%0 = D:25 - $7; MIN=0; MAX=1;
%1 = D:50 - $7; MIN=0; MAX=1;
---------------------------------------
と、ローカル変数「%0」「%1」に入れておきます。

これらを組み合わせて、命題を置き換えますと、
1行目は「$5 ^ 01 & %0」、2行目は「$5 & %1」、
と書く事ができます。

そこで、例5’でやったように、
--------------------------------------------------------------------
【例6】
IF ($5 ^ 01 & %0 | $5 * %1) != 0
・・・(処理)・・・
ENDIF
--------------------------------------------------------------------
と書いて、無事に出来上がりです。

なのですが、実はこの条件、もっとシンプルに書くことが出来ます。
後日気がつきました。

---------------------------------------
【命題(再掲)】
初日なら25個まで、
2日目以降なら50個まで、
アイテム個数を増やす改造ができる
---------------------------------------
これは言い換えれば、
---------------------------------------
【命題(変形)】
アイテム個数が25個未満なら改造できる
2日目以降なら50個未満で改造できる
---------------------------------------
という事と同じことです。

従って素直に、「$5」のゼロイチフラグを利用して比較個数を変化させて、
--------------------------------------------------------------------
【例6’】
IF $7 < (D:25 + $5 * D:25)
・・・(処理)・・・
ENDIF
--------------------------------------------------------------------
と書けばよかったのでした。。。

---------------------------------------
【教訓】
命題をできるだけシンプルにしてから考えよ
---------------------------------------


これで、たぶんMECCコード仕様の半分くらいまで、お話が済んだと思います。
次は、ここまでお話した内容で実際にコードを書いてみながら、
MECCのコード実行についても書いてみたいと思います。




No.1302
IF文とフラグ(2)
みろす(2010-01-15 02:17:15)


条件Aと条件Bがあったとします。
---------------------------------------
【命題】
AとBが共に成立した時だけ
コードを走らせたい
---------------------------------------
こんなケースがあったとします。
(例えば、戦闘中にR3ボタンを押した時、とか)
こういう時は、IF文を並べます。
--------------------------------------------------------------------
【例4a】
IF Aが成立
IF Bが成立
・・・(処理)・・・
ENDIF
ENDIF
--------------------------------------------------------------------
特に難しいところは無いと思います。

今度は、
---------------------------------------
【命題】
AとBのどちらかが成立した時に
コードを走らせたい
---------------------------------------
とします。
普通に書くと、
--------------------------------------------------------------------
【例5a】
IF Aが成立
・・・(処理)・・・
ENDIF
IF Bが成立
・・・(処理)・・・
ENDIF
--------------------------------------------------------------------
こうなりますが、同じ処理を2回書かないといけないのが不満です。
なので、各条件を反対条件にしてみます。

AとBのどちらかが成立=(AとBが共に不成立)ではない、
という意味になりますから、
--------------------------------------------------------------------
【例5b】
C=0
IF Aが不成立
IF Bが不成立
C=1
ENDIF
ENDIF

IF C == 0
・・・(処理)・・・
ENDIF
--------------------------------------------------------------------
うーん・・・確かに処理は1回で済みましたが、何か無駄に長いです。
余計な条件Cまで出てきますし。。。

そこで比較条件そのものを、論理演算に変換してみましょう。

# 以降の説明の中で、例えば、
# A=@00XXXX
# B=@00YYYY
# C=@00ZZZZ
# とすればコードらしくなりますが、ABCの方が読みやすいと思いますので、
# 以降も、ABC記述で統一します。

条件A・Bともゼロイチフラグにして、1で成立、0で不成立とします。
すると、AとBのどちらかが成立というのは、
「A|B!=0」と置き換えれますから、
--------------------------------------------------------------------
【例5c】
IF (A|B) != 0
・・・(処理)・・・
ENDIF
--------------------------------------------------------------------
と、シンプルに書くことができます。

実は、例4aも、この論理演算を使えば、もっとシンプルに書けました。
--------------------------------------------------------------------
【例4b】
IF (A&B) != 0
・・・(処理)・・・
ENDIF
--------------------------------------------------------------------
こうなります。
前回、いろいろとしつこいくらいにフラグの話を書いた所以です。

次はもう少し複雑な条件を見てみましょう。
---------------------------------------
【命題】
所持金を1万以上持っている時は、条件Aが1の時
所持金が1万未満の時は、条件Bが1の時
以上の時に、コードを走らせたい
---------------------------------------
こんな条件になると、全てフラグを使わないと、行が多く複雑になって大変です。
そこで、AとBは既にゼロイチフラグになっていますから、新たに、
「条件C=所持金を1万以上持っている」
というゼロイチフラグを作ってしまいます。
(前回のお話の中で作り方は書いています)

それらを用いれば、
命題の1行目は「C&A」と書けますし、2行目は「!C&B」と書けます。
「!C」とはCの反対の意味、すなわち「C^01」と書けますから、
これら2行を「|」で繋いで、
--------------------------------------------------------------------
【例5】
IF (C^01 & B | C & A) != 0
・・・(処理)・・・
ENDIF
--------------------------------------------------------------------
と書いて出来上がり・・・
と言いたいところだったのですが、実はこの場合は少々拙いのがわかりました。
「&」と「|」の優先順位が同じなので、このままだと、左から順に計算していって、
「C^01 & B | C」と「A」を「&」演算することになってしまいます。
「C&A」を先に演算して欲しい・・・

そこで対策として、演算の一部を四則演算に置き換えることを考えます。
ゼロイチフラグにさえしていれば、
・論理和=加算(和)
・論理積=積算(積)
という形で、論理演算を四則演算に置き換えができる場合があります。
--------------------------------------------------------------------
【例5’】
IF (C^01 & B | C * A) != 0
・・・(処理)・・・
ENDIF
--------------------------------------------------------------------
この形であれば、「C*A」の優先順位が高いので先に計算され、
その計算結果もゼロイチフラグになりますから、
後は、左から順に計算されて万事解決です。




No.1301
IF文とフラグ(1)
みろす(2010-01-15 02:16:19)


MECCのIF文は、単純比較しかできない仕様になっています。
そのため、機能的に使うには少しコツが必要です。

サイトにも説明がありますが、まずは、基本的な比較の形から。

--------------------------------------------------------------------
【例1】IF @00XXXX >= 0
--------------------------------------------------------------------
普通にこう書いた場合、@00XXXXから1バイトの数値を読み出して、それが
0以上なら成立します。
@00XXXXが2バイトのデータだと、これでは困りますので、
--------------------------------------------------------------------
【例1a】IF @00XXXX >= 0000
--------------------------------------------------------------------
こう書きます。
「0000」が2バイトだと、@00XXXXも2バイトの数値を読み出してくれます。

次は、もっと大きい数値との比較です。
--------------------------------------------------------------------
【例2】IF @00XXXX >= D:10000
--------------------------------------------------------------------
こう書くと、D:10000が2バイトの数値であるため、@00XXXXから2バイトの
数値を読み出して、1万以上であれば成立します。
ところが、@00XXXXが所持金など4バイトのデータだと、これでは比較できません。
--------------------------------------------------------------------
【例2a】IF @00XXXX >= 00002710
--------------------------------------------------------------------
こう書けば、「00002710」が4バイトですので、@00XXXXから4バイトの
数値を読み出して、「00002710」以上であれば成立します。
でも、ぱっと見た目、1万であることがわからないのが不満です。
なので、
--------------------------------------------------------------------
【例2b】
%0 = 4@00XXXX
IF %0 >= D:10000
--------------------------------------------------------------------
変数を利用して、こう書く方法もありますが、
変数のお話は後日するとして・・・

実は、最近「さりげなく」追加されたIF文の仕様で、
---------------------------------------
IF文の両項には、()内に計算式が書ける
---------------------------------------
というのがあります。
計算式が書けるということは、前回まで書いてきたお話がほとんど適用できます。
(当然、オプションやVALUEなどはだめ)

そこで、
--------------------------------------------------------------------
【例2c】IF (4@00XXXX) >= D:10000
--------------------------------------------------------------------
4バイト読出し命令を使って、こう書くことが出来ました。
これが一番スマートでしょうか。
注意点としては、計算式を書く場合は、必ず()内に書く、ということだけです。

次は、メモリ同士の比較です。
--------------------------------------------------------------------
【例3】IF @00XXXX >= @00YYYY
--------------------------------------------------------------------
こう書くと、@00XXXXと@00YYYY、それぞれ1バイトの数値を読み出して、
@00XXXXの値が@00YYYYの値以上であれば成立します。
ところが、HPの現在値と最大値を比較しようとしても、データが2バイトだと
この形では比較できません。
--------------------------------------------------------------------
【例3a】IF @00XXX1 == @00YYY1
【例3b】IF @00XXX0 >= @00YYY0
--------------------------------------------------------------------
これは、例3aで上位バイトを比較し、等しければ、例3bで下位バイトを
比較している、という意味です。
実際にやってみましたが、これでは余りにも面倒です。
そこで、
--------------------------------------------------------------------
【例3c】
%0 = 2@00XXX0
%1 = 2@00YYY0
IF %0 >= %1
--------------------------------------------------------------------
やはり変数を利用して、こう書く方法もありますが・・・
--------------------------------------------------------------------
【例3d】IF (2@00XXXX) >= (2@00YYYY)
--------------------------------------------------------------------
こう書けば、すんなりと2バイト数値として比較してくれます。
IF文の()内計算式はとてもありがたい仕様ですね。

ということで、IF文の比較の形としては以上で全部です。
比較符号については省略します。

ここからは、過去いろいろと試行錯誤してみた内容から、
条件を組み合わせたい時どうしたら良いのかを、考えてみようと思います。




No.1300
Re:バイト数(2)
みろす(2010-01-14 16:56:47)

TATSU様、いつも大変お世話になっております。

補足ありがとうございます。
そうでした。。。単項の場合を忘れていました。
こうして補足してくださると助かります。

貯金はこれで終わりですので、これからはペースが落ちると思いますが、
なるべく切れないように書いていきますので、
どうぞ気長によろしくお願いいたします。




No.1299
演算子とフラグ(2)
みろす(2010-01-14 16:47:30)


さて、ビットフラグの取り出し方や書き込み方のお話をしましたが、MECCでの
利用方法を考えますと、バイトフラグはバイトフラグでも、ゼロイチフラグ
にしておくと便利だなぁ、というケースがあります。
理由は、ゼロイチフラグ同士を掛け算しても、結果はゼロイチフラグのままだし、
定量データと掛け算しても、定量データが大きくなったりはしないからです。

次の例は、そのゼロイチフラグの形に変換する方法です。

--------------------------------------------------------------------
【例3】00YYYY @00XXXX > 5 & 01
--------------------------------------------------------------------
「>」はシフト演算子と呼ばれるもので、指定した回数だけ右にビットシフトします。
この例の場合は、5回右にシフトしています。

例えば今、値が「80」だったとします。
まず、「値 > 1」を実行しますと「40」になります。
さらに「値 > 1」を実行しますと「20」になります。
さらに「値 > 1」を実行しますと「10」になります。
さらに「値 > 1」を実行しますと「08」になります。
さらに「値 > 1」を実行しますと「04」になります。
ここまでで5回です。
結果の数値は、元の数(128)を2の5乗=32で割った値となります。

例3に戻りますと、
@00XXXX=80のとき、「@00XXXX > 5」は「04」になりますので「04 & 01」を実行する
ことになり、結果、00YYYYは「00」となります。
@00XXXX=40のとき、「@00XXXX > 5」は「02」になりますので「02 & 01」を実行する
ことになり、結果、00YYYYは「00」となります。
@00XXXX=20のとき、「@00XXXX > 5」は「01」になりますので「01 & 01」を実行する
ことになり、結果、00YYYYは「01」となります。
@00XXXX=10のとき、「@00XXXX > 5」は「00」になりますので「00 & 01」を実行する
ことになり、結果、00YYYYは「00」となります。

@00XXXX=63のとき、「@00XXXX > 5」は「03」になりますので「03 & 01」を実行する
ことになり、結果、00YYYYは「01」となります。

つまり、元の@00XXXXの20のビットが1の時だけ、00YYYYの値が「01」となり、
ゼロイチフラグに変換できたことになります。

ところで・・・
--------------------------------------------------------------------
【例3a】00YYYY @00XXXX & 20; MAX=1;
--------------------------------------------------------------------
上のが一般的な正攻法なら、これはMECCでしかできない裏技です。
ご覧の通り、欲しいビットフラグを「&」演算で取り出して、「MAX=1」で
無理やり「01」か「00」にしています。
シフト量を考える必要もありません。

例えば、所持金が@0007487Cに4バイトで入っている時、
所持金があるかどうかのゼロイチフラグは、
--------------------------------------------------------------------
【例3b】00YYYY 4@0007487C; MAX=1; SIZE=1;
--------------------------------------------------------------------
所持金が1万以上あるかどうかのゼロイチフラグは、
--------------------------------------------------------------------
【例3c】00YYYY 4@0007487C - D:9999; MIN=0; MAX=1; SIZE=1;
--------------------------------------------------------------------
で簡単に作れてしまいます。『MECCよ恐るべし』


話戻りまして、今度は逆に、ゼロイチフラグを書き戻す方法です。
ただし、あまりこういうケースは無いと思いますので、
ご参考程度で構わないと思います。

--------------------------------------------------------------------
【例4a】00XXXX @00YYYY < 5 | VALUE
【例4b】00XXXX @00YYYY < 5 ^ 01 < 5 ^ FF & VALUE
--------------------------------------------------------------------
複雑な式で恐縮です。
計算式の練習として書いてみました。
@00YYYYに、ゼロイチフラグが入っているとします。

「<」も同じくシフト演算子と呼ばれるもので、指定した回数だけ左にビットシフトします。
この例の場合は、5回左にシフトしています。

例えば今、値が「01」だったとします。
まず、「値 < 1」を実行しますと「02」になります。
さらに「値 < 1」を実行しますと「04」になります。
さらに「値 < 1」を実行しますと「08」になります。
さらに「値 < 1」を実行しますと「10」になります。
さらに「値 < 1」を実行しますと「20」になります。
ここまでで5回です。
結果の数値は、元の数(1)を2の5乗=32を掛けた値となります。

ちなみに今、値が「00」だったとすると、
「値 < 5」を実行したとしても「00」で変わりません。

これらの数値に、例4bで出てくる計算「 ^ 01 < 5 ^ FF」を実行すると、
優先順位の高いシフト演算「01 < 5」は「20」なので、
「20」の時なら、「20 ^ 20 ^ FF」は「00 ^ FF」となって「FF」となりますし、
「00」の時なら、「00 ^ 20 ^ FF」は「20 ^ FF」となって「DF」となります。

これらを踏まえて例4a例4bの話に戻ります。

例4aでは、
VALUEが「15」の時、@00YYYYが「00」だと、「00 | 15」を実行することになり、
結果、00XXXXは「15」となります。
VALUEが「15」の時、@00YYYYが「01」だと、「20 | 15」を実行することになり、
結果、00XXXXは「35」となります。
つまり、ゼロイチフラグが1のとき、元のビットフラグをセットしています。

例4bでは、
VALUEが「35」の時、@00YYYYが「00」だと、「DF & 35」を実行することになり、
結果、00XXXXは「15」となります。
VALUEが「35」の時、@00YYYYが「01」だと、「FF & 35」を実行することになり、
結果、00XXXXは「35」となります。
つまり、ゼロイチフラグが0のとき、元のビットフラグをクリアしています。

この例4aと例4bは、常に2行セットで実行しても問題ありません。

もちろん、ここまでしなくても、
後で登場するIF文で、値を判断しながらフラグを書き換えても良いですし、
一旦普通のバイトフラグに変換して、元のビットフラグに書き戻しても良いです。


ここまで、演算子の話から、フラグの操作を一通り並べましたが、
MECCでフラグを利用するための方法をまとめます
---------------------------------------
【バイトフラグ】
そのまま読み書きすればよい

【ビットフラグ読出し】
&演算でバイトフラグに変換する

【ビットフラグ書込み】
|演算でビットフラグをセットする
&演算でビットフラグをクリアする
^演算でビットフラグを反転させる

【ビットフラグをゼロイチフラグに変換】
>演算でビットフラグをシフトする
&演算でゼロイチフラグに変換する

【ゼロイチフラグでビットフラグをセット】
<演算でゼロイチフラグをシフトする
|演算でビットフラグをセットする

【ゼロイチフラグでビットフラグをクリア】
<演算でゼロイチフラグをシフトする
^演算で目的のビットを反転する(少々複雑)
&演算でビットフラグをクリアする

【あらゆるデータをゼロイチフラグに変換(MECC限定)】
&演算; MIN=0; MAX=1; SIZE=1;
で、ゼロイチフラグに変換する
必要なものだけを並べればよい
---------------------------------------

次回は、MECCのIF文の話をしていこうと思います。



No.1298
演算子とフラグ(1)
みろす(2010-01-14 16:44:09)


2つの数値をどう演算するのか示す記号の事を、数学的には二項演算子と呼ばれ、
MECCの計算で使える二項演算子には、四則演算子とシフト演算子と論理演算子があります。
---------------------------------------
四則演算子: * / + -
シフト演算子: < >
論理演算子: & | ^
---------------------------------------
ソフト演算子は、IF文で使われる大小関係を示す比較符号と同じ記号ですが、
こちらは計算式の中で使われます。

サイトに説明があるように、演算子には優先順位があって、優先順位の高い演算から
順番に行われます。
そして、優先順位が同じ演算は、左から右へ順番に行われます。
決して同時ではありません。
これ、当たり前のようで、意外に大事なルールです。

--------------------------------------------------------------------
【例1】00ZZZZ FF + 01 - 01 * 05; MAX=FF;
--------------------------------------------------------------------
これを実行すると、まず「01 * 05」が実行されて「05」となります。
そして「FF + 01 - 05」が実行されるわけですが、「FF + 01」が先に実行されます。
そのため、ここで「MAX=FF」が効いて「00」ではなく「FF」になります。
最後に、「FF - 05」が実行されて、結果は「FA」となります。

もしこれが意図とは違っていて、正しい計算結果を出したかったのであれば、
--------------------------------------------------------------------
【例1’】00ZZZZ FF - 01 * 05 + 01; MAX=FF;
--------------------------------------------------------------------
こう書くべきでした。
これなら、結果は「FB」となります。


四則演算は、一般的にもよく使われますので問題はないと思いますが、シフト演算と
論理演算に関しては、もしかしたら馴染みの薄い方もいらっしゃるかもしれませんので、
どういった時に使われるのか、ここからはそれについてお話したいと思います。


ゲームデータの中には、ゲームの状態を示すフラグと呼ばれるデータがあります。
たぶん必ずあります。
それに対して、HPとか所持金とかは定量データと呼ばれたりします。

フラグデータとは、今その状態なのかどうかを、0か0でないか、で表現したもので、
多いのは、バイトフラグとビットフラグです。
特に、1か0で表現されたバイトフラグを、1のときのデータが「01」になることから、
ローカル呼称ですが、ゼロイチフラグと呼んだりしています。

例えば、今、戦闘に入っているとします。
そうしたら大抵、今戦闘中かどうかを示す、こうしたフラグデータが、ゲームのメモリの
どこかに存在しています。

もし、00XXXXの1バイトのデータが、戦闘中のときだけ「01」になるとしたら、
この00XXXXは戦闘中を示すフラグデータで「バイトフラグ」です。(ゼロイチフラグ)
もし、00YYYYの1バイトのデータが、戦闘中の時は「20」とか「63」とかになっていて、
それ以外のときは、「00」とか「43」とかになっているとしたら、このbit5の「20」が、
戦闘中を示すフラグデータで「ビットフラグ」です。
(実際にはもっと様々な条件で検索・サーチします)

バイトフラグなら普通に1バイト読出しをして、コードの中で使用できますが、
ビットフラグだと、そのビット以外の状態が様々に変化するため、そのままでは
使用できません。
目的のビット以外の値を変えてしまうと、不具合が発生する場合が多いためです。

そこで、論理演算が必要となります。

--------------------------------------------------------------------
【例2】00ZZZZ @00YYYY & 20
--------------------------------------------------------------------
仮に今、@00YYYYが「13」だったとします。
「@00YYYY & 20」で論理演算をすると、00ZZZZは「00」になります。
仮に今、@00YYYYが「3F」だったとします。
「@00YYYY & 20」で論理演算をすると、00ZZZZは「20」になります。

つまり「20」という数値で指定したビットの状態だけを抜き出しているわけで、
ビットフラグをバイトフラグに変換したことになります。
これが基本形です。

前置きの例で行くと、この演算の後、@00ZZZZが0なら戦闘中でない、
@00ZZZZが0以外なら戦闘中である、と判断できます。

フラグは様々なケースで使用されますから、フラグを強制的にセットすることで、
ゲームの動作状態を強制的に変えることができる場合もあります。
そのためには、そのビットフラグだけを、セットしたりクリアしたりしないと
いけません。
先日ちこさんが書かれたアイテム所持コードも、このフラグの操作でした

--------------------------------------------------------------------
【例2a】00YYYY VALUE | 20
【例2b】00YYYY VALUE & DF
--------------------------------------------------------------------
仮に今、VALUEが「43」になっているとします。
例2aを実行すると、00YYYYは「63」となります。
仮に今、VALUEが「63」になっているとします。
例2bを実行すると、00YYYYは「43」となり、元に戻ります。

もしかしたら、加減算と同じように思われるかもしれませんが、加減算と根本的に
違うのは、結果が蓄積しないことです。

同じ例で、仮に今、VALUEが「43」になっているとします。
例2aを実行すると、00YYYYは「63」となりますが、
さらに例2aを実行しても、00YYYYは「63」のままです。

やはり同じ例で、仮に今、VALUEが「63」になっているとします。
例2bを実行すると、00YYYYは「43」となりますが、
さらに例2bを実行しても、00YYYYは「43」のままです。

ここで「20」と「DF」の2つの数値は、フラグ操作の結果が逆になっています。
こうした数値のことを、補数の関係があると言い、例えば、2つの数値を
加算すると「FF」になるのが特徴です。
(厳密に言うとこの場合は、16進数におけるFの補数、2進数における1の補数)
---------------------------------------
【AとBが補数の関係にあるときの特徴】
A + B = FF
A | B = FF
A & B = 00
A ^ B = FF
---------------------------------------

最後の演算子「^」は排他的論理和という名前で呼ばれる演算子で、専門的に説明
すると難しくなるのですが、ゲーム改造では1つの効果だけを覚えておけば、
非常に役に立ちます。

--------------------------------------------------------------------
【例2c】00YYYY VALUE ^ 20
--------------------------------------------------------------------
仮に今、VALUEが「43」になっているとします。
例2cを実行すると、00YYYYは「63」となります。
もう一度、例2cを実行すると、00YYYYは「43」となり、元に戻ります。

つまり「20」という数値で指定したビットの状態だけを反転しているわけです。
MECCコードでフラグの操作をする場合には、特に重要な操作になります。



No.1297
Re:PCSX2における不具合
SS(2010-01-14 15:05:29)

>先日MECCをバージョンアップし、ベースアドレス検索の設定を簡単にできるようにしました。
>ベースアドレス検索をするかどうかを設定ファイルに記録し、
>検索で見つけられたらそのままアドレス設定をするように変更しました。
>ご確認をお願いいたします。
ベースアドレス検索ボタンをクリックしただけで済み、アドレス設定のボタンをクリックする手間が省けました。
希望通りにしていただきありがとうございました。


No.1296
Re:MECC&SSF ver 0.11 Alpha R2
ちこ(2010-01-13 22:08:38)

>SSFをちょっと詳しく調べてみましたが、
>結構高いスペックが要求されるのですね。
>今は手元にノートPCしかないので、このPCではできないかもしれません。
>自宅のPCであれば大丈夫だと思いますので今しばらくお待ちください。

了解しました。

ちなみに、NAME OVERさん投稿の制服伝説プリティファイターXの
コードの、PARコードの先頭を0に変換してMECCに入力した所、
正常に動作しました。

とはいえ、やっぱり、管理人TATSUさんに確認していただかないと
不安なので、よろしくお願いします。


No.1295
Re:MECC&SSF ver 0.11 Alpha R2
管理人TATSU(2010-01-13 21:21:47)

ちこ様

TATSUです。

SSFをちょっと詳しく調べてみましたが、
結構高いスペックが要求されるのですね。
今は手元にノートPCしかないので、このPCではできないかもしれません。
自宅のPCであれば大丈夫だと思いますので今しばらくお待ちください。

以上です。


No.1294
Re:バイト数(2)
管理人TATSU(2010-01-13 20:53:41)

みろす様

TATSUです。

詳しい説明をしていただきありがとうございます。
当初は仕様がはっきりしない部分が多く、
みろす様から指摘していただいたことで仕様が固まっていきました。
サイトの説明だけでは不十分なところが多いので、
ここまで具体的に書いていただけると助かります。
せっかくなので、最終的にはサイトのほうにも記載させていただきたいと思います。

今回のバイト数に関して一点だけ補足させていただきます。
みろす様はご存知のこととは思いますが。。。
コードを解析する際に、まず初めに処理するバイト数を決める、
という処理は間違いではありません。
が、最初の段階でバイト数を決められない場合があります。
それは、バイトサイズが可変である@XXXXXXのみの場合です。
みろす様の説明にもあるとおり、これは他の項に合わせてバイトサイズが変わります。
しかし、他にサイズが決まっている項が無い場合は、
1バイトとして処理をするようにしています。
2バイト以上で処理をしたい場合には2@XXXXXXや3@XXXXXXなどを使ってください。

また何か気づいたこと等ありましたら補足させていただきます。

以上です。


No.1293
計算(2)
みろす(2010-01-13 18:13:15)

※続きです・・・


閑話休題・・・
〜〜〜〜〜〜
このような「MAX=」「MIN=」は、1行で最大と最小を制限できるメリットを
生かして、いろいろと便利に使えます。

所持金やHPなど、ゲーム内に限界のある数値を計算して書き込むときには、
「MAX=」指定していれば安心です。
--------------------------------------------------------------------
【例8】000XXXXX VALUE_2 + D:50; MAX=D:999;
--------------------------------------------------------------------

計算してHPを減らしたりする時など、絶対0にはしたくない時などには、
「MIN=」指定が便利です。
--------------------------------------------------------------------
【例9】000XXXXX VALUE_2 - D:100; MIN=1;
--------------------------------------------------------------------

変わった使い方として、持っていないアイテムだけを全て1個所持にしたい時などは、
アドレス固定タイプのアイテム表であれば、
--------------------------------------------------------------------
【例10】000XXXXX VALUE; MIN=1; COUNT=100; ADDRUP=2;
--------------------------------------------------------------------
とかで一発です。
メモリの値が0のところだけ、そこを1に書き換えます。

さらに変わった使い方として、
--------------------------------------------------------------------
【例11】000XXXXX VALUE - 1 + 1; MAX=FF;
--------------------------------------------------------------------
VALUE=01のとき、「01 - 1 + 1」=01となります。
VALUE=02のとき、「02 - 1 + 1」=02となります。
VALUE=FFのとき、「FF - 1 + 1」=FFとなります。
いずれも元の値は変化しませんし、「MAX=」オプションの影響も受けません。

唯一、VALUE=00のときだけ動作が違って、処理バイト数は1バイトなので、
「VALUE - 1」=「00 - 1」=FFとなり、「VALUE - 1 + 1」=「FF + 1」は、
「MAX=FF」指定があるため、00には戻らず、FFになります。
これは、値が0の時は特別に無限に動かしたい、という時に使いました。
〜〜〜〜〜〜


計算の話に戻って、次の行はあるゲームのキャラのHPの操作ですが、
--------------------------------------------------------------------
【例12】00074888 @00072E76 + @000735E0
--------------------------------------------------------------------
足し算の結果がFFを超えてしまうると、処理バイト数が1バイトであるため、
逆にHPが下がってしまいます。
でも「MAX=FF」を指定して頭打ちにはさせたくない。。。

この例のように、計算項の00072E76と000735E0は1バイトだけど、加算して
FFを超えたら2バイトで書込みたい、という時もあります。
そのためには、計算の処理バイト数を2バイトにしたいのですが、うまく補正
できる適当な項がありません。

そんな時は、
--------------------------------------------------------------------
【例12’】00074888 1@00072E76 + 1@000735E0 + 0000
--------------------------------------------------------------------
と書くことで、処理バイト数を2バイトにすることが出来ます。
処理バイト数が1バイトでは無くなったので、読出し命令を「@〜」ではなく、
「1@〜」という1バイト読出しの命令に変えています。

この「+ 0000」というのは、処理バイト数を上げるためだけに書いた補正項で、
強制的に処理バイト数を上げたい時に使えます。
4バイトにしたい時は「+ 00000000」を書くという感じです。

似たような例で、
--------------------------------------------------------------------
【例13】00072E77 VALUE * D:69 / D:100
--------------------------------------------------------------------
これは、00072E77の1バイト値を69%に減らそうとしています。
でもこのままでは、処理バイト数が1バイトであるため、「VALUE * D:69」
が既に正しく計算できません。

例えば、VALUEの値が4の時は、00072E77に2を書き込みたいのですが、
VALUE * D:69 = 04 * 45 = 0114 = 14(1バイトに丸められる)
VALUE * D:69 / D:100 = 14 / 64 = 00
となって、00が書き込まれてしまいます。

この場合は、処理バイト数を2バイトにして、書込みバイト数を1バイトにする、
という書き方が正解になります。
--------------------------------------------------------------------
【例13a】00072E77 VALUE_1 * D:69 / D:100 + 0000; SIZE=1;
【例13b】00072E77 VALUE_1 * 0045 / D:100; SIZE=1;
【例13c】00072E77 VALUE_1 * D:69 / 0064; SIZE=1;
【例13d】00072E77 VALUE_1 * 0045 / 0064; SIZE=1;
--------------------------------------------------------------------
このどれでも同じ結果になります。
処理バイト数を2バイトにしましたので、1バイト読出しのために「VALUE」
ではなく「VALUE_1」を使っています。

ちなみに、計算に必要なバイト数の目安は、数値的な裏づけが無い場合、
---------------------------------------
【加算】大きい方のバイト数+1
【乗算】2項のバイト数の和
---------------------------------------
です。


以上、計算の基本形から、今まで失敗して印象に残っている事項を中心に
並べてみましたが、とにかくポイントは、
---------------------------------------
何バイトで読み出して
何バイトで計算して
何バイトで書き込むのか
---------------------------------------
だと思います。

次は、計算に使われる「演算子」の話から「IF文」の話になると思います。



No.1292
計算(1)
みろす(2010-01-13 18:11:30)


計算は、MECCコードの大部分を占めています。
処理バイト数を常に意識していれば、そう難しくはないのがわかってきましたが、
うっかりミスしやすい要素でもあります。。。

例えば、
--------------------------------------------------------------------
【例1】00072E76 VALUE + 5
--------------------------------------------------------------------
これは、あるゲーム内の補正値を上昇させるコードですが、
VALUE=64のとき、00072E76=69、となります。
VALUE=C8のとき、00072E76=CD、となります。

では、VALUE=FFのとき、いくらになるかというと、
FF+5=104で、00072E76=04となります。
理由は、この行の処理バイト数が1バイトになっているからです。

本当は0104の2バイトを書きたかった・・・ならばと、
--------------------------------------------------------------------
【例2】00072E76 VALUE + 5; SIZE=2;
--------------------------------------------------------------------
こう書いたとします。
これで、VALUE=FFのときどうなるかというと、
00072E77=00、00072E76=04、となります。
「SIZE=2」オプションの効果で、2バイト書かれてはいますが、0104にはなりません。

この場合は、
--------------------------------------------------------------------
【例2a】00072E76 VALUE_2 + 5
【例2b】00072E76 VALUE + 0005
--------------------------------------------------------------------
このように書くのが正解となります。
「VALUE_2」や「0005」を明示的に使う事で、処理バイト数を2バイトに
引き上げます。

今度は同じ【例1】で、
「書込みは1バイトで良いんだけど、補正値足したらガクンと数値が下がっちゃって・・・」
というケースです。
FF+5=104で、00072E76=04となる訳ですから、確かにFF→04へ下がっちゃってます。

この場合は「MAX=」オプションを使います。
--------------------------------------------------------------------
【例3】00072E76 VALUE + 5; MAX=FF;
--------------------------------------------------------------------
こうしておけば、VALUEの値がいくら大きくなっても、加算値を5より大きくしても、
書き込まれる値は「MAX=FF」で指定したFFで頭打ちとなります。

では反対のケースで、
--------------------------------------------------------------------
【例4】00072E76 VALUE - 5
--------------------------------------------------------------------
VALUE=64のとき、00072E76=5F、となります。
VALUE=C8のとき、00072E76=C3、となります。

この場合は例えば、VALUE=00などのときが問題で、
結果は、00072E76=FBの1バイトとなります。
処理バイト数が1バイトなので、00の下はFFとなるからです。

ちなみに、上と同じような例を一通りあげると、
--------------------------------------------------------------------
【例5】00072E76 VALUE - 5; SIZE=2;
【例5a】00072E76 VALUE_2 - 5
【例5b】00072E76 VALUE - 0005
--------------------------------------------------------------------
例5なら、処理バイト数が1バイトなので、00072E77=00、00072E76=FBとなります。
例5a例5bなら、処理バイト数が2バイトなので、0000の下はFFFFとなりますから、
00072E77=FF、00072E76=FBとなります。

でも普通のゲーム値で、00より減らしてFFとか、0000より減らしてFFFFとか、
減らしていきなり最高値にするようなケースはあまりないと思います。

それを避けるためには「MIN=」オプションを使います。
--------------------------------------------------------------------
【例6】00072E76 VALUE - 5; MIN=0;
--------------------------------------------------------------------
こうしておけば、VALUEの値がいくらであろうと、書き込まれる値は、
「MIN=0」で指定した0で底打ちとなります。

ここで私の失敗例から、
--------------------------------------------------------------------
【例7】00072E76 VALUE + 5; MIN=7F7F;
--------------------------------------------------------------------
これ私は、MINで指定した「7F7F」以上の値が書かれると思っていましたが、
違っていました。

この行の処理バイト数は、あくまでも1バイトです。
だから「VALUE + 5」の結果数値は「00〜FF」の間にあります。
「00〜FF」は「7F7F」より小さいので、一旦結果数値は「7F7F」
に引き上げられますが、処理バイト数は1バイトなので、結局、
結果数値は「7F」に丸められ、00072E76=7Fとなります。

TATSUさんからこのような意味のご説明を受けて、なるほどと思った次第です。
---------------------------------------
「MAX=」「MIN=」は、数値には作用するが、
処理バイト数には作用しない
---------------------------------------

私の意図で書くなら、例えば、
--------------------------------------------------------------------
【例7’】00072E76 VALUE + 0005; MIN=7F7F;
--------------------------------------------------------------------
とするべきでした。





No.1291
バイト数(2)
みろす(2010-01-13 04:10:16)

※行が長過ぎたので分けました。

バイト数、最後は「VALUE系」です。例えば、
--------------------------------------------------------------------
【例5】00XXXX @00XXXX - 01
【例6】00XXXX 2@00XXXX - 01
--------------------------------------------------------------------
このように、書き込むアドレスと読み出すアドレスが一緒の場合、
--------------------------------------------------------------------
【例5’】00XXXX VALUE - 01
【例6’】00XXXX VALUE_2 - 01
--------------------------------------------------------------------
と、読出し側のアドレスを省略して書くことができます。

VALUE系には、「VALUE」「VALUE_1」「VALUE_2」「VALUE_3」「VALUE_4」の、
5種類の書き方がありますが、それぞれ、
---------------------------------------
VALUE = @00XXXX:可変バイト数読み出し(MECC3.121以降)
VALUE_1=1@00XXXX:1バイト読み出し
VALUE_2=2@00XXXX:2バイト読み出し
VALUE_3=3@00XXXX:3バイト読み出し
VALUE_4=4@00XXXX:4バイト読み出し
---------------------------------------
のように対応しています。
いずれも、読出し命令を簡略記述するための書き方であって、書込みバイト数
を決定する命令ではありません。

これに関しては、サイトにも記述がありますが、例えば、
--------------------------------------------------------------------
【例3’】00XXXX VALUE_1 - 0001
--------------------------------------------------------------------
と書いた場合、

<A処理>
VALUE_1:1バイト読出し
0001:2バイトの16進数
→処理バイト数を「2」に決定(全ての項のバイト数の最大に合わせる)

<R処理>
VALUE_1:00XXXXから「1」バイトの数値を読み出して「2」バイト数値にする。
・処理バイト数は「2」ですが、直接指定した「1」バイト指定が優先します。

<C処理>
VALUE_1 - 0001:「2」バイト数値同士で計算して結果を出す

<W処理>
00XXXX:求めた結果を00XXXXに「2」バイトで書き込む

というように、1バイトを読み出したアドレスに2バイトで書き込みます。
1バイトで書き戻したい時には「SIZE=1」オプションを付けます。


以上、基本形の整理で終わってしまいましたが、おそらく大きく間違っては
いないと思います。

※バイト数に関係する「SIZE文」の話は飛ばします。
※これに関しては、IF文の話と変数の話の頃にします。

もし間違いがありましたら、TATSUさん、どうぞよろしくお願いいたします。
また不明瞭な点がありましたら、皆様もこの機会にぜひどうぞ。


次はこれらを踏まえた上で、計算とMAX・MINオプションに関して整理しながら、
もう少し具体的な話になると思います。




No.1290
バイト数(1)
みろす(2010-01-13 04:08:46)


まず大前提として、メモリに読み書きする場合、必ずバイト数を何バイトに
するのかを決めないと処理できません。
PARコードでも、必ず書き込みバイト数が決められています。
MECCコードでも、この処理するバイト数が一番重要な事項になっています。

--------------------------------------------------------------------
MECCコードの動作は、1行ごとに、

A:処理バイト数の決定(全ての項のバイト数の最大に合わせる)

R:読み出し

C:計算

W:書き込み

の基本4サイクルで動いていると思われます。(便宜的に名前をつけています)
そして、Aで決まった処理バイト数が、後のR・C・W全ての処理に
対して制限を加えます。
※意図的に処理バイト数を明示した場合を除く
--------------------------------------------------------------------

ポイントは、Cの計算処理にも、Aの処理バイト数が影響していることです。
当初は、このAの処理の存在が、見え隠れしていたために悩みました。
(計算に関しては次回します)

ですが、3.110以降1本筋の通った仕様になっていますので、ここさえ押さえ
てしまえば、MECCコードが非常に理解しやすくなっていると思います。


例えば、
--------------------------------------------------------------------
【例1】00XXXX @00YYYY - 01
--------------------------------------------------------------------
この行で、MECCの動作を脳内トレースしてみると、

<A処理>
@00YYYY:可変項(他項のバイト数に合わせる)
01:1バイトの16進数
→処理バイト数を「1」に決定(全ての項のバイト数の最大に合わせる)

<R処理>
@00YYYY:00YYYYから「1」バイトの数値を読み出す

<C処理>
@00YYYY - 01:「1」バイト数値同士で計算して結果を出す

<W処理>
00XXXX:求めた結果を00XXXXに「1」バイトで書き込む

という具合です。
もう1つ似た例で、
--------------------------------------------------------------------
【例2】00XXXX @00YYYY - 0001
--------------------------------------------------------------------
の場合ですと、

<A処理>
@00YYYY:可変項(他項のバイト数に合わせる)
0001:2バイトの16進数
→処理バイト数を「2」に決定(全ての項のバイト数の最大に合わせる)

<R処理>
@00YYYY:00YYYYから「2」バイトの数値を読み出す

<C処理>
@00YYYY - 0001:「2」バイト数値同士で計算して結果を出す

<W処理>
00XXXX:求めた結果を00XXXXに「2」バイトで書き込む

となります。
この例2で、00YYYYが1バイトデータのメモリだった場合は、
--------------------------------------------------------------------
【例3】00XXXX 1@00YYYY - 0001
--------------------------------------------------------------------
と書きます。

<A処理>
1@00YYYY:1バイト読出し
0001:2バイトの16進数
→処理バイト数を「2」に決定(全ての項のバイト数の最大に合わせる)

<R処理>
1@00YYYY:00YYYYから「1」バイトの数値を読み出して「2」バイト数値にする。
・処理バイト数は「2」ですが、直接指定した「1」バイト指定が優先します。
・読み出した1バイトデータを、処理バイト数の「2」バイトに合わせます。

<C処理>
1@00YYYY - 0001:「2」バイト数値同士で計算して結果を出す

<W処理>
00XXXX:求めた結果を00XXXXに「2」バイトで書き込む

となります。
ここで「@00YYYY系」の書式をまとめますと、
---------------------------------------
@00YYYY:可変バイト数読出し
1@00YYYY:1バイト読出し
2@00YYYY:2バイト読出し
3@00YYYY:3バイト読出し
4@00YYYY:4バイト読出し
---------------------------------------
です。

逆に、例1で、00XXXXが2バイトデータのメモリだった場合は、
--------------------------------------------------------------------
【例4】00XXXX @00YYYY - 01; SIZE=2;
--------------------------------------------------------------------
と「Size=」オプションを付けて、書き込みバイト数を2バイトに変更します。

<A処理>
@00YYYY:可変項(他項のバイト数に合わせる)
01:1バイトの16進数
→処理バイト数を「1」に決定(全ての項のバイト数の最大に合わせる)

<R処理>
@00YYYY:00YYYYから「1」バイトの数値を読み出す

<C処理>
@00YYYY - 01:「1」バイト数値同士で計算して結果を出す

<W処理>
00XXXX:求めた結果を00XXXXに「2」バイトで書き込む
・処理バイト数は「2」ですが、Size=指定があるとそのバイト数で書き込まれます。

「SIZE=系」の書式をまとめますと、
---------------------------------------
SIZE=1:1バイト書込み
SIZE=2:2バイト書込み
SIZE=3:3バイト書込み
SIZE=4:4バイト書込み
---------------------------------------
となります。

例4は、例3と同じように見えますが、例3では計算が2バイトになるため、
状況によっては書き込まれる数値が変わってきます。
(計算に関しては次回します)




No.1289
MECCコードのまとめ
みろす(2010-01-13 04:03:00)

皆様、こんばんは。

MECCは、数値を変更するだけに留まらず、解析に便利な機能を
多く持ち、さらには、ゲームの処理にまで手を添えられる、私
にとっては最高の改造支援ソフトです。

昨年来、結構な行数のMECCコードを書いてきましたが、途中、
TATSUさんとも、いろいろやり取りさせて貰いました。
(ありがとうございました)

MECCも3.110以降、コードの仕様や動作が安定してきたと思いますので、サイト
にも説明がありますが、今まで悩んだり苦労したりした点を中心に、再認識の
意味も込めまして、忘れないうちにまとめておきたいと思います。
(何回かに分けます)




No.1288
Re:PCSX2における不具合
管理人TATSU(2010-01-12 21:01:32)

SS様

TATSUです。

先日MECCをバージョンアップし、ベースアドレス検索の設定を簡単にできるようにしました。
ベースアドレス検索をするかどうかを設定ファイルに記録し、
検索で見つけられたらそのままアドレス設定をするように変更しました。
ご確認をお願いいたします。

以上です。


No.1287
Re:MECC&SSF ver 0.11 Alpha R2
ちこ(2010-01-11 21:05:27)

>本日MECCをバージョンアップして、以下の対処を入れました。
>・仮想メモリ構築で表示アドレスを設定
>・アイコンなしでもランチャから起動できる
>
>仮想メモリのほうに関しては、以下のように設定してください。
>==============================
>開始アドレス:$200000
>仮想メモリ
>$00F49BA0,$100000
>$04D69BA0,$100000,$6000000
>==============================
>メモリサイズの後ろに,で区切って表示アドレスを指定できます。
>これを省略すると今までと同じようになります。
>また、メモリの検索結果のアドレスが正しく表示されるように修正しておきました。
>コードも表示アドレスに合わせて使えるようになっているので、
>ご確認をお願いいたします。

今、確認してみました。
検索が凄く早くなっていて快適です。
また、検索結果に002XXXXXと060XXXXXの両方のアドレスが
表示されました。
本当にありがとうございます。


>SSFがWindows7では正常に動作しないようなので、
>すぐには確認できないためSSFの設定には対応できていません。
>確認できしだい対応しますので、しばらくお待ちください。

新式のOSでエミュが動かなくなるというのは、時々ありますね。
やはりSSFのバージョンアップを待つしかないでしょうか。
自分の時はDirectXが最新のではなくて動かなかったことが
あるのですが、管理人TATSUさんならそういう事もないでしょうし・・・

ちなみに自分のOSはXPです。
CPU交換と合わせてWin7の導入も検討していたのですが、もうちょっと
様子を見た方が良さそうですね。


No.1286
Re:読み取り違反の件
みろす(2010-01-11 17:43:24)

TATSU様、いつも大変お世話になっております。

>本日MECCをバージョンアップし、エラーの対処を行いました。

お疲れ様でございました。
また数々のご対処ありがとうございました。

>ご迷惑をおかけして申し訳ありませんでした。

いいえ、とんでもないです。
私のテンションがちょくちょくおかしいですけど、
迷惑だなんて全然そんなことないですから、
どうぞお気になさらないでくださいましね。



No.1285
Re:読み取り違反の件
管理人TATSU(2010-01-11 15:03:37)

みろす様

TATSUです。

本日MECCをバージョンアップし、エラーの対処を行いました。
ご迷惑をおかけして申し訳ありませんでした。

また何かありましたらご連絡いただけると助かります。

以上です。


No.1284
Re:エディタ検索の件
管理人TATSU(2010-01-11 15:02:12)

みろす様

TATSUです。

本日MECCをバージョンアップし、文字列検索を修正しました。
現在の開発環境に変えてから、Unicodeで検索されるようになっていました。
今までどおりのSJISと、新たにUnicodeで検索できるように変更しましたので、
ご確認をよろしくお願いいたします。

以上です。


No.1283
Re:アドレス監視の固定について
管理人TATSU(2010-01-11 15:00:26)

みろす様

TATSUです。

本日MECCをバージョンアップし、アドレス監視の入力に関して修正しました。
ご確認をよろしくお願いいたします。

簡単ですが以上です。


No.1282
Re:MECC&SSF ver 0.11 Alpha R2
管理人TATSU(2010-01-11 14:59:27)

ちこ様

TATSUです。

本日MECCをバージョンアップして、以下の対処を入れました。
・仮想メモリ構築で表示アドレスを設定
・アイコンなしでもランチャから起動できる

仮想メモリのほうに関しては、以下のように設定してください。
==============================
開始アドレス:$200000
仮想メモリ
$00F49BA0,$100000
$04D69BA0,$100000,$6000000
==============================
メモリサイズの後ろに,で区切って表示アドレスを指定できます。
これを省略すると今までと同じようになります。
また、メモリの検索結果のアドレスが正しく表示されるように修正しておきました。
コードも表示アドレスに合わせて使えるようになっているので、
ご確認をお願いいたします。

SSFがWindows7では正常に動作しないようなので、
すぐには確認できないためSSFの設定には対応できていません。
確認できしだい対応しますので、しばらくお待ちください。

以上です。


No.1281
MECCの小ネタ
みろす(2010-01-11 01:00:47)

皆様こんにちは。
思いっきり環境依存かもしれませんが、小ネタをいくつか。


【MECCの動作が異常に重い】

うちのPC君は、PentiumM170でメモリは1GBです。
そのためか、エミュがCPUを100%使っています。
MECCを操作した後、エミュでゲームを始めると、MECCの右下の数字が
1700とか1900とかで止まってしまい、コードが動きません。
そのまま1分程度待ってさえいれば、MECCが起きて動き始めるのですが、
こんな時は、エミュのタイトルバーをマウスでドラッグして、グリグリ
動かしてやると、何故かすぐにMECCが動き始めます。


【横スクロールバー】

うちのOS君はXPProSP3で、1024の横幅で使用しています。
そのためか、コード画面のコード一覧に必ず横スクロールバーが出ます。
これはMECCに限らず、SRCなどの固定幅のソフトでは皆同じ症状で、
ソフトではなく、うちのフォントと解像度の関係のせいだと思われます。
MECCの場合は、毎回列幅を調整してやれば良いのですが、他はそうもいかず・・・
そこで、甚だ環境依存ではありますが、画面のプロパティからデザインの
詳細設定を選び、スクロールバーを16→13等小さな数値に変更。
これで一度スクロールさせてやると、横幅にゆとりができて、以降横スク
ロールバーが出なくなります。


【数値のわからないものを検索】

絞込みは、入力数値で検索した後でないとできないと思っていたので、
数値のわからないものを検索したい時には、いつも困っていました。
ところが、
 1.ゲームを止めた状態で「等しい」を選んで「検索開始」
 2.検索結果には何も出ませんが・・・(これで駄目だと思い込んでいた)
 3.気にせずそのまま「絞込み検索」
すると、これで全ての候補が検索結果に出ますので、後は普通に絞り込ん
でいくことができます。
わかってみれば、出来ないと思っていたのは私の勝手な思い込みでした。。。(恥ずかし)




No.1280
Re:読み取り違反の件
みろす(2010-01-10 19:43:49)

TATSU様、いつも大変お世話になっております。

>調べてみたところ原因が判明しました。
>空白のみの行があるとエラーが出続けるようになっていました。

おおお!さすがはTATSUさん、原因がわかるとすっきりしますね!
ということは、私の書いた報告のコードもやっぱり少し違っていました。。。
申し訳ございません。

でも良かったです^^
ありがとうございました。



No.1279
Re:読み取り違反の件
管理人TATSU(2010-01-10 13:55:11)

みろす様

TATSUです。

>モジュールのアドレスから何かわかるかも、とは微かに思ったのですが、
>やはり再現しませんでしたか。。。
その手がありましたね。。。
ありがとうございます。

調べてみたところ原因が判明しました。
空白のみの行があるとエラーが出続けるようになっていました。
申し訳ありません。

次回バージョンアップ時に修正します。

以上です。


No.1278
Re:ff5の
管理人TATSU(2010-01-10 12:01:38)

髭切様

TATSUです。

補足の欄にも書いていますが、
アイテムのせいとんを行うとアイテムが全て99個になります。
ご確認をお願いいたします。

以上です。


No.1277
ff5の
髭切(2010-01-10 03:20:53)

プログラムコードで全アイテム99個のコードはどのタイミングで使うと効果が出るのでしょうか


No.1276
Re:エディタ検索の件
みろす(2010-01-08 23:57:00)

TATSU様、いつも大変お世話になっております。

もっと早く気づいていれば良かったのですが、
申し訳ございません。
どうぞよろしくお願いいたします。



No.1275
Re:エディタ検索の件
管理人TATSU(2010-01-08 23:12:59)

みろす様

TATSUです。
ご連絡頂きありがとうございます。

開発環境をWindows7に移したので、
もしかしたらそれが影響しているのかもしれません。
ちょっとこちらで調べてみて対処します。

以上です。


No.1274
Re:PCSX2における不具合
管理人TATSU(2010-01-08 22:59:55)

SS様

TATSUです。

とりあえず解決したようで安心しました。
ベースアドレス検索は次回バージョンアップ時に、
簡単に設定できるように対応したいと思います。

以上です。


No.1273
Re:Ootake Ver 2.26
管理人TATSU(2010-01-08 22:55:27)

ちこ様

TATSUです。
情報いただきありがとうございます。

こちらで確認してから対応させていただきます。

以上です。


No.1272
Re:エディタ検索の件
みろす(2010-01-08 15:41:28)

>ちょうど、UTF-16リトルの1バイト目のみを検索している感じです。(2バイト目はFF)

すみません、1バイト目・・・というのは、便宜上、
リトルのアドレスの小さい方を言っています。。。



No.1271
エディタ検索の件
みろす(2010-01-08 15:35:59)

TATSU様、いつも大変お世話になっております。

以前、シフトJISの文字列検索ができるようにしてくださったと思うのですが、
何故か今、それが出来なくなっているようです。
「mm」を検索して「4D 4D」、「SP」を検索して「33 30」等、
ちょうど、UTF-16リトルの1バイト目のみを検索している感じです。(2バイト目はFF)

度々で恐縮なのですが、一度ご確認をお願いできませんでしょうか。
どうぞよろしくお願いいたします。



No.1270
Re:読み取り違反の件
みろす(2010-01-08 14:43:29)

TATSU様、いつも大変お世話になっております。

>こちらでも再現しないですね。。。

モジュールのアドレスから何かわかるかも、とは微かに思ったのですが、
やはり再現しませんでしたか。。。

>また発生したときにご報告をいただけると助かります。

了解いたしました^^
お忙しいところありがとうございました。



No.1269
Re:アドレス監視の固定について
みろす(2010-01-08 14:34:53)

TATSU様、いつも大変お世話になっております。

>次回バージョンアップ時に修正いたします。

お忙しいところありがとうございます。
どうぞよろしくお願いいたします。



No.1268
Re:PCSX2における不具合
SS(2010-01-08 01:58:06)

TATSU様

>現在PS2のエミュが使えないので現象を確認することができないのですが、
>エラー等の現象は頻繁に発生するのでしょうか?
>
>デフォルトの設定だと、メモリのアクセス保護を定期的に変更するので、
>もしかしたらそれが影響を与えている可能性があります。

2CHでMECCをFF12で使って問題なく動いていると報告がありました。
もしかしてVISUAL STUDIO 2010 BETA を一時インストールしていたので
それが原因ではないかと思い、WindowsXPを入れなおしてみたら今のところ
よさそうです。
メモリのアクセス保護を定期的に変更していることでC++の不具合が表面化
したのかもしれません。TATSU様のほうでの確認は不要です。
また別な問題があれば報告いたします。
ベースアドレス検索が必要なときにもう少し簡単にできればよろしくお願いします。



No.1267
Ootake Ver 2.26
ちこ(2010-01-08 00:36:23)

OotakeのVer 2.26が出てました。
以下の設定値でたぶん大丈夫でしょう。

ベースアドレス
@$0247C858
メモリサイズ
$2000
開始アドレス
0

お時間のある時で構いませんので、念の為、管理人TATSUさんの
ご確認をお願いします。



No.1266
Re:PCSX2における不具合
管理人TATSU(2010-01-07 21:32:39)

SS様

TATSUです。
MECCをご利用頂きありがとうございます。

不具合のご報告ありがとうございます。
現在PS2のエミュが使えないので現象を確認することができないのですが、
エラー等の現象は頻繁に発生するのでしょうか?

デフォルトの設定だと、メモリのアクセス保護を定期的に変更するので、
もしかしたらそれが影響を与えている可能性があります。
ツール->設定->全般->メモリ保護解除間隔の値を0にして、
一度試してみていただいてもよろしいでしょうか?

それでも現象が変わらないようであればこちらでも確認してみますので、
申し訳ありませんがしばらくお待ちください。

以上です。


No.1265
Re:読み取り違反の件
管理人TATSU(2010-01-07 21:19:56)

みろす様

TATSUです。
ご報告ありがとうございます。

こちらでも再現しないですね。。。
何か条件があるのかもしれませんが、現状では分かりません。
コードに原因があるのかもしれませんし、
コードを新たに追加するときにエラーが出る原因があるのかもしれません。

また発生したときにご報告をいただけると助かります。

以上です。


No.1264
Re:アドレス監視の固定について
管理人TATSU(2010-01-07 21:04:08)

みろす様

TATSUです。
ご報告頂きありがとうございます。

こちらでも確認できました。
10進数と16進数の入力が逆になっているようです。
申し訳ありません。

次回バージョンアップ時に修正いたします。

以上です。


No.1263
PCSX2における不具合
SS(2010-01-07 19:20:20)

暮れにMECCを導入してPCSX2で使ってみたのですが不具合が発生しました。
ファイナルファンタジーX、ファイナルファンタジーX-2インターナショナル、
ファイナルファンタジー12でゲーム中にRUNTIMEエラーで落ちたり、
セーブしようとすると真っ暗になって音だけになりました。
PCSX2だけあるいはCEPを使っているときにはこのようなことは一度も
ありませんし、PCSX2の古いバージョンでも同じでした。
あと、PCSX2は起動ごとに、リージョンアドレスやサイズがころころ変わるので
ベースアドレス検索を毎回やる必要があるのですが、ベースアドレス検索
にチェックをいれ、ボタンを2回クリックする必要があるので、2回目以降
もう少し簡単にならないかと思うのですがいかがでしょうか。
CEPを使えば問題ないのですが、他のチートツールにはない豊富な機能が
気に入っていますので、かなり先になってもよいのでよろしく
お願いします。
最後にベースアドレス検索で使った設定を参考までに報告。
PCSX2 0.9.7.2410\pcsx2-r2410.exe||$2001000|0|01 80 1A 3C|0|$1000|$1100


No.1262
読み取り違反の件
みろす(2010-01-07 18:40:52)

TATSU様、いつも大変お世話になっております。

表題の件、一度発生して強制終了させた後は、二度と再現していませんが、
取り合えず、状況は以下の通りです。

【発生したエラー内容】
モジュールmecc.exe 0051803C
アドレス00000000に対する読み取り違反

このダイアログが、いくら消しても連続して出るため、MECCを強制終了させました。(CTRL+ALT+DEL)

【やっていた作業内容】
1.ePSXeとゲームは起動しましたが、プレイ終了後、EMUの動作は停止させていました。
2.10項目の無効コードの後に、2項目新規追加して、CODE文の後にそれぞれ、以下のコードを入れました。(項目は有効状態)

<コード1>
Size Addr 4
Size $0 4
735E4 00000000
735E0 12345678

<コード2>
If (@735E0) == 78
735E4 FF
EndIf
$0 = 8888
735E8 $0

3.「コード適用」を押した瞬間、上記のエラーが出ました。

ただ、保存する前にエラーが発生してしまったため、こんなコードだった筈ですが、
微妙に違うかもしれません。
念のため、バージョンは3.110、ツールメニューの設定時間は、上から10/0/1000/1で、
OSは窓XPProSP3、動かしていたソフトは、EMUとMECCとDAEMON(バーチャルCDP)です。

もし何かわかれば・・・で構いませんので、どうぞよろしくお願いいたします。



No.1261
アドレス監視の固定について
みろす(2010-01-06 23:52:22)

TATSU様、いつも大変お世話になっております。

表題の件なのですが、
基数を16にすると、A-Fの文字が入らないようです。
基数を10にすれば、A-Fが入力できて表示は変わりますが、メモリの内容は変わりません。

うまく書けないのですが、アドレス監視の固定時の入力と表示は、16進と10進が逆のような感じで、メモリへの処理は基数と合っている感じです。

お時間のおありの時で構いませんので、何かの折にでも、一度ご確認をお願いできませんでしょうか。
どうぞよろしくお願いいたします。



No.1260
Re:MECC&SSF ver 0.11 Alpha R2
ちこ(2010-01-06 22:22:50)

>現状ではアイコンが取得できない場合は起動ができないようになっています。
>次回バージョンアップ時に修正しておきます。

恐れ入ります。
色々とご面倒をおかけしますが、よろしくお願いします。


>アイコンさえ取得できれば起動できるので以下のソフトでアイコンを設定してみてください。
>http://www.vector.co.jp/soft/dl/win95/amuse/se372418.html

丁度、何かアイコンを変更できるツールは無いかと探していた所でした。
ありがとうございます。助かりました。


>お手数をおかけして申し訳ありません。

いえ、こちらこそ色々とすみません。
それにしても、アイコンを変更するツールがあるなら、現状では
MECCのランチャーのシステム変更も必要ないかも・・・

ちなみに、変更用のアイコン素材はこちらから頂きました。

ゲーム機アイコン
http://www.ix.sakura.ne.jp/~yoshi/icon/game/index.htm


No.1259
Re:MECC&SSF ver 0.11 Alpha R2
管理人TATSU(2010-01-06 19:27:18)

ちこ様

TATSUです。

現状ではアイコンが取得できない場合は起動ができないようになっています。
次回バージョンアップ時に修正しておきます。

アイコンさえ取得できれば起動できるので以下のソフトでアイコンを設定してみてください。
http://www.vector.co.jp/soft/dl/win95/amuse/se372418.html

お手数をおかけして申し訳ありません。

以上です。


No.1258
Re:MECC&SSF ver 0.11 Alpha R2
ちこ(2010-01-06 16:45:14)

>こちらでも確認してみます。
>仮想メモリ構築設定を使って検索は確認していなかったので、
>検索結果の値がおかしくなっているのかもしれません。

委細、了解いたしました。
お時間のある時によろしくお願いします。

ところで、これはMECCとは関係の無い話なんですが、SSFをMECCの
ランチャーに登録しても、そこから起動できません。
もしかしたらSSFにアイコンが設定されていない事と関係が
あるのかもしれませんが、何か良い方法はありませんか?


No.1257
Re:MECC&SSF ver 0.11 Alpha R2
管理人TATSU(2010-01-05 20:46:43)

ちこ様

TATSUです。
確認ありがとうございます。

>ただ、検索結果に 003XXXXXというアドレスが出て来ました。
>おそらくアドレス060XXXXXなのだろうと思いますが、後日、お時間の
>ある時にでも修整していただければ幸いです。
こちらでも確認してみます。
仮想メモリ構築設定を使って検索は確認していなかったので、
検索結果の値がおかしくなっているのかもしれません。

以上です。


No.1256
Re:MECC&SSF ver 0.11 Alpha R2
ちこ(2010-01-05 18:33:29)

お忙しい所どうもありがとうございます。


>ちなみに、下記のような設定をするとそのままのアドレスで使えます。
>開始アドレス:$200000
>仮想メモリ
>$00F49BA0,$100000
>0,$5D00000
>$04D69BA0,$100000
>
>が、これだと検索に時間がかかるのと、メモリエディタが使いにくいですね。
>コードを使うだけであれば問題ないかもしれませんが。。。

この設定で使ってみたのですが、コードは問題無く使えましたし、
確かに検索も通常よりも遥かに時間がかかりますが、使えない
レベルではなかったです。
むしろ、自分の使用機のCPUがCeleron440という事を考えれば、
検索スピードとしては申し分無いのではないかと思います。

ただ、検索結果に 003XXXXXというアドレスが出て来ました。
おそらくアドレス060XXXXXなのだろうと思いますが、後日、お時間の
ある時にでも修整していただければ幸いです。


>それぞれのメモリ設定で開始アドレスを変更できるような機能を検討してみます。

そうしていただけると助かります。
確かに合計200000hだと一瞬で検索結果が出ますから。


>私事ですがちょっとの間自宅のPCが使えないので、
>SSFの対応と、MECCの機能追加/変更等が行えません。
>せっかく情報を提供していただいて申し訳ありませんが、
>MECCでの正式対応はしばらくお待ちください。

もちろん、管理人TATSUさんのご都合の良い時で構いませんので、
よろしくお願いします。
せっかくのお正月休みなのに、色々とすみませんでした。


No.1255
Re:MECC&SSF ver 0.11 Alpha R2
管理人TATSU(2010-01-04 20:26:31)

ちこ様

TATSUです。

>$00F49BA0,$100000
>$04D69BA0,$100000
仮想メモリ構築の設定は上記であっています。
セガサターンはRAMが二つあって結構特殊な構造になっているのですね。

上記の設定で二つのRAMを書き換えできますが、
これだとそのままのアドレスが使えないのでちょっと不便ですね。
ちなみに、下記のような設定をするとそのままのアドレスで使えます。
開始アドレス:$200000
仮想メモリ
$00F49BA0,$100000
0,$5D00000
$04D69BA0,$100000

が、これだと検索に時間がかかるのと、メモリエディタが使いにくいですね。
コードを使うだけであれば問題ないかもしれませんが。。。
それぞれのメモリ設定で開始アドレスを変更できるような機能を検討してみます。

私事ですがちょっとの間自宅のPCが使えないので、
SSFの対応と、MECCの機能追加/変更等が行えません。
せっかく情報を提供していただいて申し訳ありませんが、
MECCでの正式対応はしばらくお待ちください。

以上です。


No.1254
Re:ドラクエ6のモンスターの職変更について
サル(2010-01-03 23:16:55)

>サル様
>
>TATSUです。
>
>キャラクターの順番は確か仲間になった順番になっていたと思います。
>
>例えば、主人公・ハッサンが仲間になっている状態で、
>次にスライムナイトが仲間になったとすると、
>スライムナイトのコードはハッサンのコードに+2Ahしたアドレスになります。
>主人公・ハッサン・ミレーユが仲間になっている状態で仲間になったのならば、
>ミレーユのコードに+2Ahしたアドレスになります。
>
>以上です。
 
お早い返信ありがとうございました。
 



No.1253
Re:MECC&SSF ver 0.11 Alpha R2
ちこ(2010-01-03 23:07:12)

>cep base address
>(02) 00F49BA0
>(60) 04D69BA0

上記の設定値なんですが・・・

$00F49BA0,$100000
$04D69BA0,$100000

仮想メモリ構築設定で、このようにすればいいんですよね?
やってみると簡単ですね。凄い便利です。


No.1252
Re:ドラクエ6のモンスターの職変更について
管理人TATSU(2010-01-03 22:55:05)

サル様

TATSUです。

キャラクターの順番は確か仲間になった順番になっていたと思います。

例えば、主人公・ハッサンが仲間になっている状態で、
次にスライムナイトが仲間になったとすると、
スライムナイトのコードはハッサンのコードに+2Ahしたアドレスになります。
主人公・ハッサン・ミレーユが仲間になっている状態で仲間になったのならば、
ミレーユのコードに+2Ahしたアドレスになります。

以上です。


No.1251
Re:MECC&Regen 0.972の設定
管理人TATSU(2010-01-03 22:51:54)

ちこ様

TATSUです。
ご確認いただきありがとうございます。

表記をリトルエンディアンに変えておきました。

簡単ですが以上です。


No.1250
MECC&SSF ver 0.11 Alpha R2
ちこ(2010-01-03 22:30:28)

セガサターンエミュがまだ未対応という事で色々調べてみた所、
RAM領域が二つに分かれていて、自分ではちょっと設定が難しそう
なので、とりあえずわかった事だけご報告します。

これは、SSFのAboutをクリックすると表示されるものです。
−−−−−−−−
cep base address
(02) 00F49BA0
(60) 04D69BA0
−−−−−−−−
二つのメモリのアドレスを示しているようです。

二つのメモリを同時に書き換えたい場合、cepでは二つ同時に
起動するしかなかったようですが、離れたRAM領域をくっつけて
一つに見做す事ができる現在のMECCならば対応可能ですよね?

詳しい事は以下の掲示板に書かれております。
参考にどうぞ。
http://www.unkar.org/read/game14.2ch.net/gameurawaza/1200863784

すでに対応作業中でしたらすみません。


No.1249
ドラクエ6のモンスターの職変更について
サル(2010-01-03 19:49:48)

主人公やハッサン等のキャラクターについては各キャラごとに+2Ahすればいいのと分かっているのですが
 
モンスターの職をコードで変更しようとすると、いくつになるかが解りません
ちなみに、スライムナイトを最初に仲間にしました。


No.1248
Re:MECC&Turbo Engine 16 v0.31bの設定
ちこ(2010-01-03 19:40:31)

>こちらの環境でも確認できましたので、
>本日MECCをバージョンアップし、TurboEngineのアドレス設定を含めました。

お疲れ様でした。
また何かありました時はよろしくお願いします。


No.1247
Re:MECC&Regen 0.972の設定
ちこ(2010-01-03 19:37:54)

>こちらの環境でも確認できましたので、
>本日MECCをバージョンアップし、Regenのアドレス設定を含めました。

お疲れ様でした。
一つだけ修整をお願いしたいのですが、MECCの紹介ページのエミュの
設定一覧表で、

Gens v2.14 @$402C0B $10000 $FF0000 リトル
Regen v0.97 @$401200 $10000 $FF0000 ビッグ

と、なっておりますが、RegenもGensと同じような
リトル(?)エンディアンになっていました。
細かい事で申し訳ないですが、よろしくお願いいたします。


No.1246
Re:GBエミュ2種とNESエミュのベースアドレス
管理人TATSU(2010-01-03 16:59:41)

峰様
ちこ様

TATSUです。

本日MECCをバージョンアップし、NNNesteRのアドレス設定を修正しました。
サイトのほうへ書いていますが、仮想メモリ機能を使って以下のように設定します。
#開始アドレスは0です
============================
@$52AAF4,$800
0,$5800
@$528AC4,$2000
============================
1行目は0000h-07FFhのRAM領域を設定しています。
2行目は0800h-5FFFhを無効な領域としています。
実際のこのメモリ領域は、ROMやIOのための領域になっています。
改造コードの観点から言えば必要ではないと思いましたので、
この領域は無視するような設定にしました。
3行目は6000h-7FFFhのSRAM領域を設定しています。

上記の設定を行うことで、NNNesteRのコードのうち、
00000h-007FFhのコードと10000h-11FFFhのコードに対応できます。
00000h-007FFhのコードはそのままのアドレスを入力すれば問題ありません。
10000h-11FFFhのコードについては、
10000hを引いて6000hを足したアドレスを設定すれば適用できます。

ちなみに2行目を「0,$F800」とすることで、
NNNesteRの10000h-11FFFhのコードをそのまま適用できるようになります。


20000h-のコードについては対応できていません。
既に調べたように、このアドレスのコードは拡張メモリ領域を書き換えるコードです。
この領域は各ゲーム独自のメモリ領域となっており、
このメモリ領域が存在しないゲームも存在します。
MECCで一つ一つのゲームに対応させる設定を行えば可能ではありますが、
ゲームごとにアドレス設定を変えて設定しなおすのは面倒ですし、
この領域を書き換えるコードが少ないことから、
今回の設定では対応しないこととしました。


以上、ご確認をよろしくお願いいたします。


No.1245
Re:MECC&Regen 0.972の設定
管理人TATSU(2010-01-03 16:42:57)

ちこ様

TATSUです。
情報を提供していただきありがとうございます。

こちらの環境でも確認できましたので、
本日MECCをバージョンアップし、Regenのアドレス設定を含めました。

簡単ですが以上です。


No.1244
Re:MECC&Turbo Engine 16 v0.31bの設定
管理人TATSU(2010-01-03 16:42:35)

ちこ様

TATSUです。
情報を提供していただきありがとうございます。

こちらの環境でも確認できましたので、
本日MECCをバージョンアップし、TurboEngineのアドレス設定を含めました。

簡単ですが以上です。


No.1243
Re:論理和「|」について
ちこ(2010-01-03 15:04:21)

>0AC0 VALUE|04
>
>のような書き方もできるようにしてくださいました。
>同じアドレスを2回書かなくて良いので助かります。

そういう書き方もあるのですか。
確かに間違えないで済むし、便利そうですね。


>という事で、
>勝手に書いて失礼かもしれませんが、

いえいえ、とんでもない。
本当は紙媒体の「MECCの使い方入門」が欲しいくらいなので助かります。


>今年もどうぞよろしくお願いいたします。

こちらこそよろしくお願いします。


No.1242
Re:論理和「|」について
みろす(2010-01-03 12:56:01)

ちこさん、初めまして。
新年明けましておめでとうございます。

>0AC0 @CAC0|04

既に解決されたようですが、
私もこれよくやります。。。

で、最近、TATSUさんが仕様を追加してくださいまして、

0AC0 VALUE|04

のような書き方もできるようにしてくださいました。
同じアドレスを2回書かなくて良いので助かります。
またこれを使うと、COUNTループ内でも、その途中アドレスのデータを
使って計算することができます。

という事で、
勝手に書いて失礼かもしれませんが、
そもそもMECCを使い始めた切っ掛けが、ちこさんだったりしますので、
大変感謝しております。

今年もどうぞよろしくお願いいたします。



No.1241
Re:論理和「|」について
ちこ(2010-01-03 10:40:24)

>>0AC0 @CAC0|04
>コードの式はあっています。
>ただ、@CAC0となっているので、@0AC0とすればいけると思います。

お恥ずかしい。
どうりで取った覚えの無いアイテムまで増えてる訳ですね。
ありがとうございました。

#全く気付かなかった・・・自分で自分が情けない。


No.1240
Re:論理和「|」について
管理人TATSU(2010-01-03 10:23:36)

ちこ様

TATSUです。

>0AC0 @CAC0|04
コードの式はあっています。
ただ、@CAC0となっているので、@0AC0とすればいけると思います。

以上、ご確認をお願いいたします。


No.1239
論理和「|」について
ちこ(2010-01-03 10:07:35)

PC-Engine SUPER CD-ROM2のY's&兇鯆瓦戮討い董

所持アイテム 3
0AC0 XX
入手したい装備品の数値の
合計をXXに設定してください。
+00h 無し
+01h マスク オブ アイズ
+02h ミラー
+04h ウイング
+08h ヒールポーション
+10h EVIL RING
+20h HEAL RING
+40h TIMER RING
+80h RING MAIL

という内容の数値が格納されているアドレスを見つけたので、早速、
このアドレスを利用して、+04hのウイングを常に所持している
状態に固定するコードを考えてみました。

ウイング以外のアイテムに影響が出ないよう、論理和を利用し、

0AC0 @CAC0|04

と、このようにしてみたのですが、コードを有効にした後に
ミラーというアイテムを購入しても表示されないのです。

コードの式や記述はこれで合ってますか?


No.1237
Re:GBエミュ2種とNESエミュのベースアドレス
峰(2010-01-03 09:32:33)

>色々調べてみたところ、D000h-DFFFhはバンク切り替えというのを行っていて、
>同じアドレスで読み書きをしても実際には違う場所が読み書きされているようです。
>バンクは7つ用意されていて、実際には7000hバイトの領域が読み書きされています。
>
>また、GBのPARコードの先頭1バイトが何を示しているのか分からなかったのですが、
>上述したバンクを指定しているようだということが分かりました。
>C000h-CFFFhはバンク切り替えしないので、
>気にすることなくそのアドレスを読み書きすればいいわけですが、
>PARのコードでは先頭に01がついています。
>そしてD000h-DFFFhのメモリを書き換えるコードでは、
>先頭が9Xとなっていて、Xがバンクをあらわしているようです。
>例えば先頭が93のコードであれば、
>バンク3のD000h-DFFFhのメモリを書き換えることになります。

なるほど。
自分はGBコードの先頭の1バイトは、PARの対応バージョンの違いを示しているのかと思っていました。
昔、ゲームラボかなんかの雑誌に
「9Xで始まるGBコードはPAR2以降専用」と書いてあったような気がします(ちょっと記憶が曖昧ですが・・・)。
もしそれが正しければ──

・PAR1にはバンク切り替えの機能に対応していない
・もしくはそもそもD000h-DFFFの領域を書き換える機能がない

──のどちらかになるのかな?と思ったのですが、

>ちなみに、上記で書いたことは全てGBカラーが対象となっています。
>カラーでない普通のGBではD000h-DFFFhのバンク切り替えはないので、
>C000h-DFFFhの2000hバイトを設定すればよいです。

以上の部分を読んで合点がいきました。
おそらくPAR1はバンク切り替え機能に対応しておらず、飽くまでGBCを除いたGB用ですが、GBCであってもバンク切り替えの絡まないアドレスであれば問題なくコードが使えるということなのかもしれません。

>また、GBのRAM領域はA000h-BFFFhもあるという情報をいただきましたが、
>GBのPARコードを調べてみるとこの領域のメモリを書き換えるコードは見つかりませんでした。
>もしかしたらこの領域のメモリを書き換えるコードもあるのかもしれませんが、
>この領域はゲームによって取り扱いが変わるようなので、
>現状はこの領域を無視しています。
>もし、どうしてもこの領域もMECCで扱いたいということがあれば、
>対応方法を考えてみますのでご連絡ください。

そうでしたか。
先に自分が挙げたエストポリス伝記はバンク機能の切り替えを行っているだけで、
A000h-BFFFhを使用しているわけではなかったということですね。
可能性は低いかもしれませんが、この先もしA000h-BFFFhの領域を使っているようなゲームがあったとしたら、
改めてその時ご報告させて頂きます。

>VisualBoyAdvanceでは、これまでのやり取りした内容から、
>1000hバイト単位でメモリを管理しているということが分かっていますので、
>別々のメモリ領域をつなげる必要があります。
>そこで、今回のバージョンアップでこのようなばらばらのメモリ領域を
>一つにまとめてあたかも連続したメモリ領域にする機能を追加しました。
>少々設定が分かりにくいかもしれませんが、
>VisualBoyAdvanceのアドレス設定は初期設定ファイルに含めていますので、
>そちらを使ってご確認ください。

こちらについても大変ご苦労さまでした。
自分の力など微々たるものですが、これからもMECCの機能充実の一助となれば幸いです。


No.1235
Re:GBエミュ2種とNESエミュのベースアドレス
峰(2010-01-03 07:41:14)

遅れましたが、明けましておめでとうございます。

>TATSUさん
> { 0000H- 0800H : MainMemory }
> { 6000H- FFFFH : ROM(書き込みは危険カもしれないので今のところ不可) }
> { 10000H-1FFFFH : SRAM }
> { 20000H-2FFFFH : Mapper拡張メモリ }
>
>つまり、10000h〜のアドレスを指定した場合はSRAMの領域を書き換え、
>20000h〜のアドレスを指定した場合は拡張メモリ領域を書き換えるようです。
>
>そして、NNNesteRではRAMの管理を以下のようにしているようです。
>0000h-07FFh:メインメモリ
>0800h-27FFh:SRAM
>2800h-:拡張メモリ?(未確認です)
>
>そのため、10000h〜のアドレスの場合は10000hを引いて800hを足せばうまくいきます。
>20000h〜のアドレスの場合は20000hを引いて2800hを足せばうまくいく?(未確認)
>
>ちなみに、本来のSRAMのアドレスは6000h-7FFFhであり、
>NNNesteRのメモリビューで確認すると、
>10000h〜のコードを入力するとこの領域が書き換わっていました。

詳細な調査、大変ご苦労様です。
特に20000h〜のアドレスの場合の20000hを引いて2800hを足せばうまくいくかどうかについては
ただいま実家へ帰省中ですが自宅へ戻り次第試させていただきます。


>ちこさん
多少の間違いはやむを得ぬものですので、どうぞお気になさらずに


No.1234
MECC&Regen 0.972の設定
ちこ(2010-01-02 23:18:00)

MECCにおけるRegen 0.972の設定は、以下の数値で成功する
可能性があります。

ベースアドレス
@$00401200
メモリサイズ
$10000
開始アドレス
$FF0000


念の為、その他のベースアドレス候補も以下に記します。

@$004021AA
@$004032F2
@$00409B11
@$00409C86
@$00409D04
@$00409D7C
@$00409F74
@$0040A1BE
@$0040A5CD
@$0040A95D
@$0040BB31
@$0040BE34
@$0040C0AF
@$0040C375
@$004FE23D
@$004FE5C3
@$004FE5E2

こちらもお時間のある時にお試しください。

尚、Regenという名前から嫌な予感はしていましたが、メモリの
配列がGensと全く一緒でした。
こちらも今は、正式対応を見送るべきと考えます。


No.1233
MECC&Turbo Engine 16 v0.31bの設定
ちこ(2010-01-02 22:25:43)

MECCにおける、Turbo Engine 16 v0.31bの設定は、以下の数値で
成功する可能性があります。

ベースアドレス
@$0040F6FA
メモリサイズ
$2000
開始アドレス
0


念の為、他のベースアドレス候補も以下に記しておきます。

@$0040F856
@$0040F9A2
@$004167AA
@$00416881
@$00416A01
@$00416ADF
@$00416CF3
@$00416DFE

お時間のある時にご確認ください。


No.1232
管理人TATSUさんへ
ちこ(2010-01-02 12:24:20)

>MECCでは本来の6000h-7FFFhのアドレス指定でコードを入力するようにしたいので、
>FCのメモリ全体に対応したアドレス設定を調べますので、
>それまでしばらくお待ちください。

了解しました。
管理人TATSUさんの解析結果を楽しみに待ってます。
それにしても気付けばMECCも多機能になりましたね。
凄い。


No.1231
峰さんへ
ちこ(2010-01-02 12:17:14)

>もしかしたら、20000hを引いて、1000hを足せばいいのかな?

峰さんすみません。全然違ってました。
詳しくは管理人TATSUさんの解説をお読みくださいませ。

それにしても、なんとややこしい・・・


No.1229
Re:GBエミュ2種とNESエミュのベースアドレス
管理人TATSU(2010-01-02 12:05:51)

ちこ様
峰様

TATSUです。

NNNesterJのサイトの解説ページに書いてましたね。。。
以下転載です。
{ 0000H- 0800H : MainMemory }
{ 6000H- FFFFH : ROM(書き込みは危険カもしれないので今のところ不可) }
{ 10000H-1FFFFH : SRAM }
{ 20000H-2FFFFH : Mapper拡張メモリ }

つまり、10000h〜のアドレスを指定した場合はSRAMの領域を書き換え、
20000h〜のアドレスを指定した場合は拡張メモリ領域を書き換えるようです。

そして、NNNesteRではRAMの管理を以下のようにしているようです。
0000h-07FFh:メインメモリ
0800h-27FFh:SRAM
2800h-:拡張メモリ?(未確認です)

そのため、10000h〜のアドレスの場合は10000hを引いて800hを足せばうまくいきます。
20000h〜のアドレスの場合は20000hを引いて2800hを足せばうまくいく?(未確認)

ちなみに、本来のSRAMのアドレスは6000h-7FFFhであり、
NNNesteRのメモリビューで確認すると、
10000h〜のコードを入力するとこの領域が書き換わっていました。

MECCでは本来の6000h-7FFFhのアドレス指定でコードを入力するようにしたいので、
FCのメモリ全体に対応したアドレス設定を調べますので、
それまでしばらくお待ちください。

以上です。


No.1228
Re:MECC&Ootake 2.25の設定値
ちこ(2010-01-02 12:05:40)

>前回のバージョンアップで入れようと思っていて忘れてました。。。
>本日、別件の修正に合わせてご連絡いただいたアドレス設定を含めました。
>ありがとうございました。

いえいえ、こちらこそありがとうございます。
新年早々お疲れ様でした。

今、アーケードカード対応のゲームでコードを調べているのですが、
どうやら通常とは違うRAM領域が設定されているようです。
もっとも、アーケードカード自体が拡張RAMカードみたいなものなので、
当然と言えば当然かもしれませんが・・・
また、Magic Engineで同ゲームのコードをサーチしても、ヒット
しませんでした。

取り急ぎご報告いたします。


No.1227
Re:MECC&Ootake 2.25の設定値
管理人TATSU(2010-01-02 10:48:50)

ちこ様

TATSUです。

前回のバージョンアップで入れようと思っていて忘れてました。。。
本日、別件の修正に合わせてご連絡いただいたアドレス設定を含めました。
ありがとうございました。

以上です。


No.1226
Re:MECC3.090のオプションについて
ちこ(2010-01-01 23:07:48)

>次回以降はバージョンを記載するようにします。
>また、ファイルについてもバージョンをつけた名前にするようにします。

ありがとうございます。
自分はそそっかしいので、そうしていただけると本当に助かります。


No.1225
Re:MECC&Ootake 2.25の設定値
ちこ(2010-01-01 23:06:12)

>こちらでも確認してMECCで対応させていただきます。
>それにしても更新が頻繁に行われると大変ですね。。。

お疲れ様です。
何かとお忙しい中、大変でしょうが、よろしくお願いいたします。


No.1224
Re:GBエミュ2種とNESエミュのベースアドレス
管理人TATSU(2010-01-01 21:36:32)

峰様
みろす様

TATSUです。

本日MECCをバージョンアップしGBエミュレータに対応しました。


色々調べてみたところ、D000h-DFFFhはバンク切り替えというのを行っていて、
同じアドレスで読み書きをしても実際には違う場所が読み書きされているようです。
バンクは7つ用意されていて、実際には7000hバイトの領域が読み書きされています。

また、GBのPARコードの先頭1バイトが何を示しているのか分からなかったのですが、
上述したバンクを指定しているようだということが分かりました。
C000h-CFFFhはバンク切り替えしないので、
気にすることなくそのアドレスを読み書きすればいいわけですが、
PARのコードでは先頭に01がついています。
そしてD000h-DFFFhのメモリを書き換えるコードでは、
先頭が9Xとなっていて、Xがバンクをあらわしているようです。
例えば先頭が93のコードであれば、
バンク3のD000h-DFFFhのメモリを書き換えることになります。

で、このようなメモリ構造にMECCでは以下のように対応しました。
MECCのメモリエディタではサイズを0C000h-13FFFhの合計8000hバイトとし、
0C000h-0CFFFhはGBのC000h-CFFFhに割り当て、
0D000h-13FFFhはGBのD000h-DFFFh(バンク1-7)に割り当てることで、
GBのC000h-DFFFhのメモリにアクセスする構造としています。
MECCのGBPARコードでは、コードの先頭1バイトからバンクを割り出し、
該当するメモリを書き換えることでPARコードに対応しています。

このような対応をしているため、MECCのメモリエディタ上では、
10000hというGBではありえないアドレスにアクセスすることになりますが、
上記のようにD000h-DFFFhの異なるバンクにアクセスしていることを意識しておいてください。


また、GBのRAM領域はA000h-BFFFhもあるという情報をいただきましたが、
GBのPARコードを調べてみるとこの領域のメモリを書き換えるコードは見つかりませんでした。
もしかしたらこの領域のメモリを書き換えるコードもあるのかもしれませんが、
この領域はゲームによって取り扱いが変わるようなので、
現状はこの領域を無視しています。
もし、どうしてもこの領域もMECCで扱いたいということがあれば、
対応方法を考えてみますのでご連絡ください。


ちなみに、上記で書いたことは全てGBカラーが対象となっています。
カラーでない普通のGBではD000h-DFFFhのバンク切り替えはないので、
C000h-DFFFhの2000hバイトを設定すればよいです。

VisualBoyAdvanceでは、これまでのやり取りした内容から、
1000hバイト単位でメモリを管理しているということが分かっていますので、
別々のメモリ領域をつなげる必要があります。
そこで、今回のバージョンアップでこのようなばらばらのメモリ領域を
一つにまとめてあたかも連続したメモリ領域にする機能を追加しました。
少々設定が分かりにくいかもしれませんが、
VisualBoyAdvanceのアドレス設定は初期設定ファイルに含めていますので、
そちらを使ってご確認ください。


長々と書き、分かりにくい箇所もあるかもしれませんが、
何かありましたら遠慮なくご連絡ください。

以上です。


No.1223
Re:続:管理人TATSU様へ
管理人TATSU(2010-01-01 14:33:13)

モナドマンダラ様
すえ様

TATSUです。
あけましておめでとうございます。今年もよろしくお願いいたします。

これからも皆様にとって有益なサイトになるようがんばっていきます。
また、何かありましたら遠慮なくご連絡ください。

以上です。


No.1222
Re:MECC&Ootake 2.25の設定値
管理人TATSU(2010-01-01 14:29:42)

ちこ様

TATSUです。
設定情報をご連絡いただきありがとうございます。

こちらでも確認してMECCで対応させていただきます。

それにしても更新が頻繁に行われると大変ですね。。。

簡単ですが以上です。


No.1221
Re:MECC3.090のオプションについて
管理人TATSU(2010-01-01 14:27:31)

ちこ様

TATSUです。

更新履歴は一行なので確かにバージョンアップされたことが人目で分かりにくいですね。
次回以降はバージョンを記載するようにします。

また、ファイルについてもバージョンをつけた名前にするようにします。

ご指摘いただきありがとうございました。

以上です。


No.1220
続:管理人TATSU様へ
すえ(2010-01-01 12:38:39)

新年明けましておめでとうございます。今年もよろしくお願いします。

思えば1年前は自分がコードを投稿する側になるとは夢にも思ってませんでした。
このサイトのおかげで少しだけ階段を上れたような気がします。

今年がみなさんにとって良い年になりますように。




No.1219
Re:アーケイドエミュレータについて
モナドマンダラ(2010-01-01 12:34:43)

>モナドマンダラさん今晩は、MAMEは何種類かありますが、国産のMAME(通称豆電)もありますので、豆電から入った方が分かりやすいかも知れませんね。くにおくんが対応してるかは分かりませんが・・・起動、設定、チート等、基本的には同じですし、豆電の方が動作も軽いですよ!
>ホームページ探しにくいのであれば、本屋のパソコンコーナーには、エミュレータ関連の雑誌もたくさん出てますので、その辺を見てもいいかと。
>この間、立ち読みした本は付録CDにMAME本体とかインストール起動の仕方など入ってますよ〜的な事が書いてましたので、手っ取り早いんじゃないでしょうか?


どうもモナドマンダラです。
返信遅くなってスイマセン。
まずは、新年明けましておめでとうございます。
今年も宜しくお願いします。

今日見ましたらチョコ様より返信がありましたことを知りました。
明日にも本屋に行って買って見ながらやって行きたいと思います。
本当に詳しく有難う御座いました。
短いですが・・・
−以上です−


No.1218
管理人TATSU様へ
モナドマンダラ(2010-01-01 12:13:39)

どうもモナドマンダラです。
新年明けましておめでとうございます。今年も宜しくお願いします。

昨年はいろいろと大変お世話になりました。
今年も質問ばかりだと思いますので、そのときは宜しくお願いします。
短いですが・・・
            −以上です−


No.1217
MECC&Ootake 2.25の設定値
ちこ(2009-12-31 21:14:36)

今見たらまたバージョンアップされていました。

ベースアドレス
@$0247C7C4
メモリサイズ
$2000
開始アドレス
0

年明けにまたバージョンアップされている予感が・・・


1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10