HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2021
1231
MSX68000数値配列と文字列の同時SAVE方法は?3解決


MSX68000

リンク

2021/12/31(Fri) 00:43:08|NO.94830

 以前質問などをした自作中のゲーム、2年たつがまだ自然消滅したりせず、ちゃんと
作り続けていますw

 でそうしたそれなりに大きな作品なので、データ保存を必要とするゲームであり、

A.文字変数によるプレイヤーの名前(日本語と英語の表示切替も作っており、
  日本語は全角4字か8字、英語は半角8字か16字)

B.数値型配列によるプレイヤーの能力値(添字が4なら早さとか、8ならHPとか)

C.数値型配列によるマップデータ(固定マップでなく、DQ9の宝の地図みたいに
  ランダムでマップが作られ、保存データを消すまで有効なので、いちいち保存)

 に大別されます。でHSPではどんなセーブ機能があるか質問したら、また微妙?な
機能だと回答があって、それぞのSAVE機能に合わせた保存方法として、

1.notesave(文字列保存)
 1と逆で数値型変数を、str関数とval関数で文字型にコンバートし、数字ばかり
並んだ文字列で保存。ただし桁あふれしない事と(上記変数のBは殆どが0-255で
一部は0-65535、Cは0-3)、改行文字も取得できないみたいなので、固定長にして
LOAD時に取得位置を厳格化する。

2.bsave(配列変数保存)
 BとCはほぼそのまま入るが、Aはそのままでは無理。文字コードが取得できれば
数値型に出来るが、HSPでは文字コードが取得出来ないそうなので、"ABC"や「あいう
えお」などよく使う文字を長大文字列に格納し、instr関数やstrmid関数の何番目に
来るかという疑似文字コードを使い数値型にコンバートという方法を考えたが、
ファミコンの様に英数字・ひらがな・カタカナ程度で精いっぱいであり、漢字は無理?

3.bmppsave(グラフィック保存)
 数値をcolor命令とpget命令によるRGB(0-255,0-255,0-255)にコンバートし
bmpで保存…というのも考えたが(プチコンでもこんなテクニックが早くから編み
出されていましたね)、同じ数値保存なら2のほうが簡単で容量も小さいか(^^;

4.Aはnoteseva・BとCはbsaveでそれぞれ別々に保存
 ただしゲームデータをコピペする時、微妙に面倒。

 を考えました。どの方法がいいでしょう?あるいはほかにいい方法ありますか?



この記事に返信する


zrs90(5さい)

リンク

2021/12/31(Fri) 09:50:35|NO.94831

ここまで、詳細に書かれている方に、意見するレベルでは
全くない、その上、スマホ投稿しか出来ないので。
(※saveデータの暗号化とかは、考慮してません。)

save をHDLで検索すると、他にも色々
save に使える命令が出てきます。

サイズは、ともかく、高速化等を検討されているなら
下記のHP、hsp3のマニュアルを見ると良いかと。

http://mclab.uunyan.com/lab/hspneta/neta020.htm
(※この方のHPは、他にも、有益な情報がありますので
ついでに、色々見て置くと良いです。)

HSP3文字列のひみつ(中上級者向け)


...ご存知とは、思いますが、こんな手もあります。

1.セーブデータを、メモリ上にロード

2.ゲーム中は、peek / poke 系の命令を使って
 必要に応じて、メモリ上で読み出し/書き込み
 (※取り扱いは、気をつけて下さい。
 後、2バイト文字を使っていると、処理が面倒ですが...)

3.セーブデータを作成する。



沢渡

リンク

2021/12/31(Fri) 12:10:10|NO.94832

>HSPでは文字コードが取得出来ないそうなので
そんなことはありません。
文字列変数はpeekでバイト単位で位置を指定して文字コードを取得できますし、
memcpyで文字コードの並びを丸ごとコピーしたり、
bsaveで保存したりすることも可能です。
>日本語は全角4字か8字、英語は半角8字か16字
Shift_JISでは「半角文字は1バイト、全角文字は2バイト」と決まっているので、
大きい方を採用するのなら、文字列のデータは最大で16バイトということになります。
(これはShift_JISの場合なので、hsp3utfを使うのならまた話は違ってくる)

以下、名前と能力値とマップデータをbsaveで一つのファイルに保存する例を示します。

//名前と能力値とマップデータを一つのファイルに保存する例。 //今回、能力値は0〜65535、マップは0〜3と決まっているので、 //もっとファイル容量を削減できそうだが、簡略化のためとりあえず //文字列と配列をそのまま保存してみる。 name="1234あいうえお" //名前。最大16バイト。 dim state,16 //能力値。仮に16種類とする dim map,100,100 //マップデータ。仮に100×100とする。 //テスト用に、stateとmapにデタラメなデータを書き込む。 randomize repeat 16 : state(cnt)=rnd(256) : loop repeat 100 cnt0=cnt repeat 100 map(cnt,cnt0)=rnd(4) loop loop //セーブ用のバッファを確保 //整数配列は1要素4バイトなので、能力値は16×4で64バイト、 //マップは100×100×4で40000バイト。 //16(名前)+64(能力値)+40000(マップ)で40080バイトを確保する。 sdim save_dat,40080 //セーブ用バッファにデータをコピー memcpy save_dat,name,strlen(name),0,0 memcpy save_dat,state,64,16,0 memcpy save_dat,map,40000,80,0 bsave "test.dat",save_dat,40080

以下はセーブしたデータをbloadで読み込む例です。

sdim save_dat,40080 bload "test.dat",save_dat,40080 sdim name,17 //名前 //↑最大バイト数16に終端ヌルの分を足した17バイトを確保。sdimは最低でも //64バイト確保するので64未満の値を指定してもあまり意味はないが、一応 dim state,16 //能力値 dim map,100,100 //マップデータ //セーブデータを読み込んだバッファからデータをコピー memcpy name,save_dat,16,0,0 memcpy state,save_dat,64,0,16 memcpy map,save_dat,40000,0,80 mes name //名前を表示してみる repeat 16 : mes state(cnt) : loop //能力値を表示してみる //マップについてはデバッグウィンドウで確認してみてください



MSX68000

リンク

2021/12/31(Fri) 14:45:00|NO.94833

zrs90さん、沢渡さん

 ありがとうございます。ご多分に漏れず正月は仕事が無くて暇なので、
仕事初めまでに、そっちをもっと突っ込んで調べてみます。



ONION software Copyright 1997-2023(c) All rights reserved.