HSPでセーブデータを書きかえる2
●その1.スクリプト編

スクリプトの解説

では、セーブデータを書きかえるスクリプト、savew.asを説明します。
このスクリプトの構造は非常に単純です。

(1)ファイルを読み込む
(2)初期設定
(3)画面を作る
(4)値を書きこんでファイルに書き出す

という4ブロックに分かれています。

(1)ファイルを読み込む

screen 0,400,400,0

alloc buf,200000
skiperr 1
bload "G2sys.sav",buf
if err=12:mes "G2sys.savがあるフォルダに、\nこのプログラムをコピーし、\nそこで実行して下さい。":wait 1000:end
skiperr 0


最初にalloc命令で変数の領域を確保します。
書きこむファイルのサイズは多めに設定しておきます。

次にbload命令で、変数にセーブファイルを読みこみます。
その前に、skiperr命令でエラーを止めています。
これでファイルが読みこめなくて、エラーになった場合でもスクリプトが止まらず、
次の行でエラーメッセージを出すことが出来ます。
システム変数errにはエラー番号が入っています。
エラー12は、”ファイルが存在しない”というエラーです。

(2)初期設定

font "MS ゴシック",16,0
pos 25,20
;書きこむアドレスの定義 .0 クリア CGコンプリート.1アドレスから .2アドレスまで
dim wt,3,8
wt.0.0=$3b1c,$1e88,$1ec0 ;船山望美
wt.0.1=$3b20,$1ec8,$1f00 ;奥田玲佳
wt.0.2=$3b24,$1f08,$1f2c ;白石阿夜
wt.0.3=$3b28,$1f48,$1f7c ;岩崎奈穂子
wt.0.4=$3b2c,$1f88,$1fc0 ;島田慎子
wt.0.5=$3b30,$1fc8,$1ff4 ;仙奥寺かほり
wt.0.6=$3b34,$2008,$2020 ;高橋友里恵
wt.0.7=$3b18,$2048,$2068 ;cgmode/other
;値フラグ
dim wf,20

配列にアドレスデータいれます。
たとえば”船山望美”では、wt.0.0から4バイトがクリア情報のアドレスになります。
また、その中の各CGの情報はwt.1.0からwt.2.0のアドレスになります。
2番目の数字の0がキャラクター番号になります。
昔のBASICと配列の添え字を付ける順番が逆になっていますので、注意してください。

また、画面上のチェック用にwfを定義しておきます。

(3)画面を作る

*gamen
cls 1
pos 20,60:mes "船山望美"
pos 20,90:mes "奥田玲佳"
pos 20,120:mes "白石阿夜"
pos 20,150:mes "岩崎奈穂子"
pos 20,180:mes "島田慎子"
pos 20,210:mes "仙奥寺かほり"
pos 20,240:mes "高橋友里恵"
pos 20,300:mes "OTHER"
sysfont font "MS ゴシック",16,0
objsize 250,20
pos 20,20:chkbox "CGモード/BGMモード出現",wf.7
objsize 80,20 ;オブジェクトサイズを指定
objmode 2 ;オブジェクトにfont命令で指定したフォントを使う
pos 140,60:chkbox "クリア",wf.0
pos 140,90:chkbox "クリア",wf.1
pos 140,120:chkbox "クリア",wf.2
pos 140,150:chkbox "クリア",wf.3
pos 140,180:chkbox "クリア",wf.4
pos 140,210:chkbox "クリア",wf.5
pos 140,240:chkbox "クリア",wf.6
objsize 140,20
pos 240,60:chkbox "CGコンプリート",wf.8
pos 240,90:chkbox "CGコンプリート",wf.9
pos 240,120:chkbox "CGコンプリート",wf.10
pos 240,150:chkbox "CGコンプリート",wf.11
pos 240,180:chkbox "CGコンプリート",wf.12
pos 240,210:chkbox "CGコンプリート",wf.13
pos 240,240:chkbox "CGコンプリート",wf.14
pos 240,300:chkbox "CGコンプリート",wf.15
objsize 80,25
pos 140,340:button "書きこみ",*kakikomi_all
objsize 140,25
pos 240,340:button "プログラム終了", *prog_end
stop
*prog_end
end

画面を作っていきます。
「pos 140,60:chkbox "クリア",wf.0 」
とすることで、配列wf.0の内容に応じて画面上のチェックボックスが表示されます。
表示前に「wf.0=1」などとしておけば、最初からチェックしている状態になります。
objsaize命令で表示されるオブジェクト(部品)のサイズを決めて、
pos命令で表示位置を決めています。
指定のアドレスに1度書きこむタイプのクリア情報などはwf.0からwf.7が、
アドレスからアドレスへの書きこみはwf.8からwf.15が割り当てられています。

(4)値を書きこんでファイルに書き出す

*kakikomi_all
;クリア処理
repeat 8
 if wf.cnt=1:ad=wt.0.cnt:gosub kakikomi1
loop
repeat 8
cc=cnt+8
if wf.cc=0:continue ;処理しない
wrct=(wt.2.cnt-wt.1.cnt) >> 2
wrct++
adtop=wt.1.cnt
 repeat wrct
  ad=adtop+(cnt*4):gosub *kakikomi1
  wait 1
 loop
loop
size=15164
bsave "G2sys.sav",buf,size
cls
pos 100,150
mes "書き換えは終りました。"
wait 100
goto *gamen end
*kakikomi1
poke buf,ad,1
poke buf,ad+1,0
poke buf,ad+2,0
poke buf,ad+3,0
return

「書きこみ」ボタンを押すと、書きこみをはじめます。
最初に1度だけ書きこめばいいタイプのデータを書きこみます。
サブルーチン「*kakikomi1」を呼んでいますが、
そこでは変数bufに、変数adの場所から4バイトに”01 00 00 00”を
書きこんでいます。
次の2重のrepeat-loopではアドレス-アドレスの書きこみをしています。
引き算で長さを出した後、4バイト単位なので4で割っています。
その時「wrct=(wt.2.cnt-wt.1.cnt) >> 2 」 というように「>>(ビットシフト)」で
変数を2ビット分シフトすることで4分の1にしています。
シフトは、2進数の状態で右に動かす命令です。
たとえば、値が10だった場合、2進数では

1010 コレを右に1回シフトすると
 101 と一番下の0が消えてしまいます。

値は5になり、2で割ったのと同じ事になります。
あまりは消えてしまいます。
フラグを見て、1の場合はループ回数分書きこみをしています。
フラグが0の場合はcontinue命令でループの先頭に戻ります。

書き換えが終了すると、bssave命令で保存します。

以上でG2sys.savの書き換えが終りました。


その2. EXEファイル作成編へ移動
HSPでセーブデータを書きかえる2へ戻る