//-----------------------------------------------------------------------------
// マップが開かれているか
//-----------------------------------------------------------------------------
BOOL CFmfMap::IsOpen() const
{
return m_pLayerAddr != NULL;
}
NULLでなければレイヤーデータへのポインタ(m_pLayerAddr)を返すということか?
constの位置がちょっと不思議な気がする。
よく分からん。パス。
//-----------------------------------------------------------------------------
// マップメモリを開放
//-----------------------------------------------------------------------------
void CFmfMap::Close(void)
{
if (m_pLayerAddr != NULL)
{
delete [] m_pLayerAddr;
m_pLayerAddr = NULL;
}
}
new演算子を使って確保したメモリを解放する演算子。
どうやらnewとセットで使うのが決まりらしい。
なんでそのあとにNULLを入れてるのかとか
深く考えないことにする。
//-----------------------------------------------------------------------------
// 指定レイヤの先頭アドレスを得る
// 引数: レイヤ番号
// 戻り値: 正常終了 = レイヤデータのアドレス
// エラー = NULL
// 各レイヤデータは連続したメモリ領域に配置されてるので
// 指定レイヤデータのアドレスを計算で求める。
//-----------------------------------------------------------------------------
void* CFmfMap::GetLayerAddr(BYTE byLayerIndex) const
{
// メモリチェック、範囲チェック
if ((m_pLayerAddr == NULL) || (byLayerIndex >= m_fmfHeader.byLayerCount))
return NULL;
BYTE bySize = m_fmfHeader.byBitCount / 8;
return m_pLayerAddr + m_fmfHeader.dwWidth * m_fmfHeader.dwHeight * bySize * byLayerIndex;
}
byLayerIndexは、この後出てくるのですがレイヤーの番号です。
m_fmfHeader.byLayerCountはレイヤーの数。
レイヤーデータがきちんと読まれてない、もしくは読み込もうとするレイヤー番号が実際のレイヤー数より大きい場合はエラー。
で、その下。m_fmfHeader.byBitCountはレイヤデータのビットカウントらしい。
ビットカウント…よくわからんが、platinumで新規作成するとき、8ビットと16ビットを選択できる。たぶんあれのことだと思う。
bySizeは8ビットなら1、16ビットなら2になる。
8ビットで作ったデータでは、1つのマップチップ情報を保存するのに1バイト、16ビットなら2バイト必要ってことだろう。
レイヤーデータは連続したメモリ領域に配置されてると見出しに書かれている。
たぶんこんな感じだ。
<レイヤー0>
123
456
789
<レイヤー1>
a b c
d e f
g h i
という風な配置のマップデータがあったとして、メモリ領域では
123456789abcdefghi
という風に配置してるんだと思う。
ここでの計算は、(byLayerIndex)番のレイヤー情報を読むにはどこから読み始めたらいいの~?ってのを計算しているようだ。
その式が最後の一行。言い換えると、
レイヤー情報の先頭の位置 + マップの横幅 * マップの縦幅 * ビット数 * レイヤー番号
ビット数ってのがややこしいけど、上の例でレイヤー1の情報の先頭の位置を知りたければ、「a」の情報が入っている場所が分かれば良い。
ぱっと見では10番目。
だけどメモリ上では、「1」の情報を保存するのに8ビット使われている(8ビットで作った場合)。
つまり「a」の情報が入っている場所は10番目ではなく、10*8=80番目ということになる。
ビットでそのまま計算すればいいのに、なぜわざわざバイトに直すのかと思うけれど、
コンピュータは情報の記憶や処理、伝達をバイト単位で行うことが多い、ってことらしい。たぶんそれでだ。
//-----------------------------------------------------------------------------
// レイヤ番号と座標を指定して直接データを貰う
// 引数:
// byLayerIndex = レイヤ番号
// dwX = X座標(0~m_fmfHeader.dwWidth - 1)
// dwY = Y座標(0~m_fmfHeader.dwHeight - 1)
// 戻り値:
// 正常終了 = 座標の値
// エラー = -1
//-----------------------------------------------------------------------------
int CFmfMap::GetValue(BYTE byLayerIndex, DWORD dwX, DWORD dwY) const
{
int nIndex = -1;
// 範囲チェック
if (byLayerIndex >= m_fmfHeader.byLayerCount ||
dwX >= m_fmfHeader.dwWidth ||
dwY >= m_fmfHeader.dwHeight)
return nIndex;
if (m_fmfHeader.byBitCount == 8)
{
// 8bit layer
BYTE* pLayer = (BYTE*)GetLayerAddr(byLayerIndex);
nIndex = *(pLayer + dwY * m_fmfHeader.dwWidth + dwX);
}
else
{
// 16bit layer
WORD* pLayer = (WORD*)GetLayerAddr(byLayerIndex);
nIndex = *(pLayer + dwY * m_fmfHeader.dwWidth + dwX);
}
return nIndex;
}
さっきの関数でほしいレイヤーの先頭のアドレスは分かったので、
今度ははそのレイヤー上の、座標(dwX、dwY)のマップのデータを取り出すための関数。
もうエラー処理はいいかな…飛ばします。
8ビットの場合から見てみる。
まず、pLayerにレイヤーの先頭のデータが書かれているアドレスを入れます。
で、ほしい座標のデータはそこから数えて何番目~?ってのを計算してます。
m_fmfHeader.dwWidthはマップの横幅です。
さっきも言ったとおり、マップ情報はずらーっと一列に並んでいるので、
n行目のデータを見るにはマップの横幅×n個分データを進める必要があるってことですね。
16ビットも式が同じで、処理同じじゃ~んって思ったら、データ型がWORDになってる。
WORDとは16ビット符号なし整数の型らしい。
う~ん、いろいろ決まりごとがあるんだろう。
//-----------------------------------------------------------------------------
// レイヤ番号と座標を指定してデータをセット
//-----------------------------------------------------------------------------
void CFmfMap::SetValue(BYTE byLayerIndex, DWORD dwX, DWORD dwY, int nValue)
{
// 範囲チェック
if (byLayerIndex >= m_fmfHeader.byLayerCount ||
dwX >= m_fmfHeader.dwWidth ||
dwY >= m_fmfHeader.dwHeight)
return;
if (m_fmfHeader.byBitCount == 8)
{
// 8bit layer
BYTE* pLayer = (BYTE*)GetLayerAddr(byLayerIndex);
*(pLayer + dwY * m_fmfHeader.dwWidth + dwX) = (BYTE)nValue;
}
else
{
// 16bit layer
WORD* pLayer = (WORD*)GetLayerAddr(byLayerIndex);
*(pLayer + dwY * m_fmfHeader.dwWidth + dwX) = (WORD)nValue;
}
}
さっきとまったく同じ処理をしてnValueに代入している気がするんだけど・・・
データを貰うのとセットするのって何が違うんだ・・・
読み進めたらわかるかな。とりあえずパス。
//-----------------------------------------------------------------------------
// マップの横幅を得る
//-----------------------------------------------------------------------------
DWORD CFmfMap::GetMapWidth(void) const
{
return m_fmfHeader.dwWidth;
}
//-----------------------------------------------------------------------------
// マップの高さを得る
//-----------------------------------------------------------------------------
DWORD CFmfMap::GetMapHeight(void) const
{
return m_fmfHeader.dwHeight;
}
//-----------------------------------------------------------------------------
// チップの横幅を得る
//-----------------------------------------------------------------------------
BYTE CFmfMap::GetChipWidth(void) const
{
return m_fmfHeader.byChipWidth;
}
//-----------------------------------------------------------------------------
// チップの高さを得る
//-----------------------------------------------------------------------------
BYTE CFmfMap::GetChipHeight(void) const
{
return m_fmfHeader.byChipHeight;
}
//-----------------------------------------------------------------------------
// レイヤー数を得る
//-----------------------------------------------------------------------------
BYTE CFmfMap::GetLayerCount(void) const
{
return m_fmfHeader.byLayerCount;
}
//-----------------------------------------------------------------------------
// レイヤーデータのビットカウントを得る
//-----------------------------------------------------------------------------
BYTE CFmfMap::GetLayerBitCount(void) const
{
return m_fmfHeader.byBitCount;
}
なんでいちいち関数にするのか。代入でいいんじゃないのと思ってしまうのはきっと素人考え。
あと順序もよくわからん。こいつら最初に書けばよさそうなのに…そこは好みの問題なのか?
って、そんなことを言ってる間にcppファイルは終わってしまった。
あれ??SetValue関数何に使うの???
なるほど分からん。
よし、次からマップ描画のためのコード書きに挑戦だ♪