ビットマップ使えば、事足りるんじゃないかと思い、
DIBセクションを用意して、ビットマップを読み込むようにしてみた。
他にもビットマップは、工夫さえすれば、色々使えるのではないだろうか。
以下、マップチップ(タイル)とキャラとマップ上のオブジェクトを別々の同じサイズのビットマップで
作ったとして、それぞれ読み込むソースコード。
無料でブログを利用させてもらうので、誰かの何かの役に立つようなソースコード上げて
いけたらいいなと思う。
int CMapManager::LoadMapFile(LPCWSTR pwstr_map , LPCWSTR pwstr_chara , LPCWSTR pwstr_obj)
{
// テスト用マップの用意
// DIBセクションの用意
DWORD rgb;
BYTE *p = NULL;
int i = 0;
CDIBSection * pdib;
pdib = new CDIBSection;
pdib->CreateFromFileW(pwstr_map);
m_map_width_chip = pdib->GetWidth();
m_map_height_chip = pdib->GetHeight();
m_map_width_absolute = m_map_width_chip * m_mapchip_width;
m_map_height_absolute = m_map_height_chip * m_mapchip_height;
MapMemAlloc(m_map_width_chip , m_map_height_chip);
for(int y=0;y < m_map_height_chip;y++){
for(int x=0;x < m_map_width_chip;x++)
{
p = pdib->GetPixel(x,y);
rgb = p[0]|((0xffffff&p[1])<<8)|((0xffffff&p[2])<<16);
m_pMapChip[x][y].m_init_flg = 1;
m_pMapChip[x][y].__m_width = m_mapchip_width;
m_pMapChip[x][y].__m_height = m_mapchip_height;
m_pMapChip[x][y].m_type = 1;
m_pMapChip[x][y].m_code = rgb;
m_pMapChip[x][y].setRotation(0.0f);
m_pMapChip[x][y].setScalling(1.0f,1.0f);
}
}
m_mapcopy_width = m_mapscreen_width / m_mapchip_width;
m_mapcopy_height = m_mapscreen_height / m_mapchip_height;
delete pdib;
pdib = new CDIBSection;
if(!pdib->CreateFromFileW(pwstr_chara))goto SKIP_CHARA;
for(int y=0;y < m_map_height_chip;y++){
for(int x=0;x < m_map_width_chip;x++)
{
p = pdib->GetPixel(x,y);
rgb = p[0]|((0xffffff&p[1])<<8)|((0xffffff&p[2])<<16);
switch(rgb)
{
case 0x00ff0000:
m_pMapChara[i].m_type = 1;
m_pMapChara[i].set_mappos(x , y);
i++;
break;
case 0x0000ff00:
m_pMapChara[i].m_type = 2;
m_pMapChara[i].set_mappos(x , y);
i++;
break;
}
}
}
SKIP_CHARA:
delete pdib;
pdib = new CDIBSection;
if(!pdib->CreateFromFileW(pwstr_obj))goto SKIP_OBJ;
for(int y=0;y < m_map_height_chip;y++){
for(int x=0;x < m_map_width_chip;x++)
{
p = pdib->GetPixel(x,y);
rgb = p[0]|((0xffffff&p[1])<<8)|((0xffffff&p[2])<<16);
switch(rgb)
{
case 0x00ff0000:
m_pMapObj[i].m_type = 1;
m_pMapObj[i].set_mappos(x , y);
i++;
break;
case 0x0000ff00:
m_pMapObj[i].m_type = 2;
m_pMapObj[i].set_mappos(x , y);
i++;
break;
}
}
}
SKIP_OBJ:
delete pdib;
return 0;
}
定数が定義されていない(コメントアウトしてあるtarcs_code.hで定義した)
から、それだけ修正すれば使えるはず。
.H
#pragma once
#include <windows.h>
//#include "tarcs_code.h"
class CDIBSection;
class CDIBSection
{
public:
INT m__Code;
BYTE * m_lpPixel;
INT m_BitsPerPixel;
HBITMAP m_hBitmap;
HFONT m_hFont;
HDC m_hMemDC;
COLORREF m_transparentcolor;
DIBSECTION m_Dibsection;
BITMAPINFO m_Bmi;
// 空のDIBセクションを作る
CDIBSection(HWND hWnd , int w , int h)
{
HDC hdc;
// DIBの情報を設定する
BITMAPINFO bmi;
bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth=w;
bmi.bmiHeader.biHeight=h;
bmi.bmiHeader.biPlanes=1;
bmi.bmiHeader.biBitCount=24;
bmi.bmiHeader.biCompression=BI_RGB;
// DIBSection作成
hdc=GetDC(hWnd);
m_hBitmap=CreateDIBSection(hdc,&bmi,DIB_RGB_COLORS,(void**)&m_lpPixel,NULL,0);
if(m_hBitmap == NULL) {
m__Code = -2;
} else {
GetObject(
m_hBitmap, // グラフィックオブジェクトのハンドル
sizeof(DIBSECTION), // オブジェクト情報を格納するバッファのサイズ
&m_Dibsection // オブジェクト情報を格納するバッファ
);
m_hMemDC=CreateCompatibleDC(hdc);
SelectObject(m_hMemDC,m_hBitmap);
ReleaseDC(hWnd,hdc);
}
m__Code = 0;
}
// ファイルを読み込んで初期化
CDIBSection(HWND hWnd , LPCSTR lpszName)
{
HDC hdc;
if(CreateFromFile(lpszName)==FALSE)exit(0);
hdc = GetDC(hWnd);
m_hMemDC=CreateCompatibleDC(hdc);
SelectObject(m_hMemDC,m_hBitmap);
ReleaseDC(hWnd,hdc);
m__Code = 0;
}
CDIBSection()
{
}
~CDIBSection() {
this->Release();
}
VOID Release() {
if(m_hBitmap) {
DeleteObject(m_hBitmap);
m_hBitmap = NULL;
}
if(m_hMemDC) {
DeleteDC(m_hMemDC);
}
}
DIBSECTION GetDIBSection(){return m_Dibsection;}
BOOL CreateFromFile(LPCSTR lpszName);
BOOL CreateFromFileW(LPCWSTR lpszName);
int GetErrorCode() {return m__Code;}
COLORREF GetTransparentColor() {return m_transparentcolor;}
VOID SetTransparentColor(COLORREF color) {m_transparentcolor = color;}
LONG & GetWidth() {return m_Dibsection.dsBm.bmWidth;}
LONG & GetHeight() {return m_Dibsection.dsBm.bmHeight;}
WORD & GetBitsPerPixel() {return m_Dibsection.dsBm.bmBitsPixel;}
BYTE * GetPixel(int x , int y);
VOID Copy(CDIBSection &srcdib , int srcx , int srcy , int cw , int ch , int destx , int desty );
VOID Blt(HDC hdcDest) {BitBlt(hdcDest,0,0 ,m_Dibsection.dsBmih.biWidth,m_Dibsection.dsBmih.biHeight,m_hMemDC,0,0,SRCCOPY);}
int ScreenCapture(int width ,int height);
BOOL SaveW(LPCWSTR lpFileName);
void Write32(HANDLE fh,const DWORD *lpPixel,int w,int h)
{
int extra;
if(w*3%4) extra=4-w*3%4;
else extra=0;
DWORD dwWriteSize;
int zero=0;
for(int y=0;y<h;y++){
for(int x=0;x<w;x++)
WriteFile(fh,lpPixel+x+y*w,3,&dwWriteSize,NULL);
if(extra) WriteFile(fh,&zero,extra,&dwWriteSize,NULL);
} //一行分のバイト数を4の倍数に補正
}
void SetFont(LPCTSTR lpszFace , int Height , int Width , COLORREF crColor)
{
SetBkMode(
m_hMemDC, // デバイスコンテキストのハンドル
TRANSPARENT // 背景モード
);
SetTextColor(
m_hMemDC, // デバイスコンテキストのハンドル
crColor// テキストの色
);
m_hFont = CreateFont(
Height, // フォントの高さ
Width, // 平均文字幅
0, // 文字送り方向の角度
0, // ベースラインの角度
0, // フォントの太さ
FALSE, // 斜体にするかどうか
FALSE, // 下線を付けるかどうか
FALSE, // 取り消し線を付けるかどうか
DEFAULT_CHARSET, // 文字セットの識別子
OUT_DEFAULT_PRECIS, // 出力精度
CLIP_DEFAULT_PRECIS, // クリッピング精度
ANTIALIASED_QUALITY, // 出力品質
FIXED_PITCH|FF_MODERN, // ピッチとファミリ
lpszFace // フォント名
);
SelectObject(m_hMemDC , (HGDIOBJ)m_hFont);
}
int DrawText(int x, int y , LPCTSTR lpString , int len){
RECT rct;
rct.left = x;
rct.top = y;
rct.right = 0;
rct.bottom = 0;
::DrawText(
m_hMemDC, // デバイスコンテキストのハンドル
lpString, // 描画するテキスト
len, // テキストの長さ
&rct, // テキストを描画する長方形領域
DT_NOCLIP // テキスト描画オプション
);
return 0;
}
};
#include "dibsection.h"
BOOL CDIBSection :: CreateFromFile(LPCSTR lpszName)
{
this->Release();
m_hBitmap = (HBITMAP)LoadImageA(
NULL , // インスタンスのハンドル
lpszName, // イメージの名前または識別子
IMAGE_BITMAP, // イメージのタイプ
0, // 希望する幅
0, // 希望する高さ
LR_DEFAULTCOLOR | LR_CREATEDIBSECTION // ロードのオプション
| LR_DEFAULTSIZE | LR_LOADFROMFILE
);
if(m_hBitmap == NULL) {
m__Code = (INT)APP_ERR_FILE_NOT_FOUND;; // ファイルが見つからない
return FALSE;
}
if(GetObject(
m_hBitmap, // グラフィックオブジェクトのハンドル
sizeof(DIBSECTION), // オブジェクト情報を格納するバッファのサイズ
&m_Dibsection // オブジェクト情報を格納するバッファ
) == 0 ) {
m__Code = (INT)APP_ERR_INITIALIZE_ERR; // その他のエラー
return FALSE;
}
m_lpPixel = (BYTE *)m_Dibsection.dsBm.bmBits;
return TRUE;
}
BOOL CDIBSection :: CreateFromFileW(LPCWSTR lpszName)
{
this->Release();
m_hBitmap = (HBITMAP)LoadImageW(
NULL , // インスタンスのハンドル
lpszName, // イメージの名前または識別子
IMAGE_BITMAP, // イメージのタイプ
0, // 希望する幅
0, // 希望する高さ
LR_DEFAULTCOLOR | LR_CREATEDIBSECTION // ロードのオプション
| LR_DEFAULTSIZE | LR_LOADFROMFILE
);
if(m_hBitmap == NULL)
{
m__Code = (INT)APP_ERR_FILE_NOT_FOUND; // ファイルが見つからない
return FALSE;
}
if(GetObject(
m_hBitmap, // グラフィックオブジェクトのハンドル
sizeof(DIBSECTION), // オブジェクト情報を格納するバッファのサイズ
&m_Dibsection // オブジェクト情報を格納するバッファ
) == 0 )
{
m__Code = (INT)APP_ERR_INITIALIZE_ERR; // その他のエラー
return FALSE;
}
m_lpPixel = (BYTE *)m_Dibsection.dsBm.bmBits;
HDC hdc = GetDC(NULL);
m_hMemDC = CreateCompatibleDC(hdc);
SelectObject(m_hMemDC,m_hBitmap);
ReleaseDC(NULL,hdc);
return TRUE;
}
BYTE * CDIBSection :: GetPixel(int x , int y)
{
BYTE * p = m_lpPixel;
switch(m_Dibsection.dsBm.bmBitsPixel)
{
case 24:
p += (m_Dibsection.dsBm.bmWidth * 3) * ((m_Dibsection.dsBm.bmHeight - 1 - y)) + (x * 3);
break;
case 32:
p += (m_Dibsection.dsBm.bmWidth * 4) * ((m_Dibsection.dsBm.bmHeight - 1 - y)) + (x * 4);
break;
default:
break;
}
return p;
}
VOID CDIBSection :: Copy(CDIBSection &srcdib , int srcx , int srcy , int cw , int ch , int destx , int desty) {
BYTE * psrc , * pdest;
int x,y;
COLORREF transparentcolor = srcdib.GetTransparentColor();
switch(this->m_Dibsection.dsBm.bmBitsPixel)
{
case 24:
for(y=0;y < ch;++y) {
if(((desty + y) >= this->GetHeight()) || ((srcy + y) >= srcdib.GetHeight()))break;
psrc = srcdib.GetPixel(srcx , srcy + y);
pdest = this->GetPixel(destx , desty + y);
for(x=0;x < cw;++x) {
if(((destx + x) >= this->GetWidth()) || ((srcx + x) >= srcdib.GetWidth()))break;
if(
((0xff&transparentcolor ) == psrc[2]) &&
((0xff&(transparentcolor>>8)) == psrc[1]) &&
((0xff&(transparentcolor>>16)) == psrc[0])
) {} else {
pdest[2] = psrc[2];
pdest[1] = psrc[1];
pdest[0] = psrc[0];
}
psrc += 3;
pdest += 3;
}
}
break;
case 32:
for(y=0;y < ch;++y) {
if(((desty + y) >= this->GetHeight()) || ((srcy + y) >= srcdib.GetHeight()))break;
psrc = srcdib.GetPixel(srcx , srcy + y);
pdest = this->GetPixel(destx , desty + y);
for(x=0;x < cw;++x) {
if(((destx + x) >= this->GetWidth()) || ((srcx + x) >= srcdib.GetWidth()))break;
if(
((0xff&transparentcolor ) == psrc[2]) &&
((0xff&(transparentcolor>>8)) == psrc[1]) &&
((0xff&(transparentcolor>>16)) == psrc[0])
) {} else {
pdest[2] = psrc[2];
pdest[1] = psrc[1];
pdest[0] = psrc[0];
}
psrc += 4;
pdest += 4;
}
}
break;
default:
this->m__Code = -5;
break;
}
}
int CDIBSection::ScreenCapture(int width ,int height)
{
HDC hdc=GetDC(NULL);
BitBlt(m_hMemDC,0,0,width,height,hdc,0,0,SRCCOPY);
ReleaseDC(NULL,hdc);
return 1;
}
BOOL CDIBSection::SaveW(LPCWSTR lpFileName)
{
BITMAPINFOHEADER bmpInfoH;
CopyMemory(&bmpInfoH,&m_Dibsection.dsBmih,sizeof(BITMAPINFOHEADER));
int bitCount=bmpInfoH.biBitCount;
if(bitCount!=32 && bitCount!=24 && bitCount!=8)
{
return FALSE;
}
int w=bmpInfoH.biWidth , h=bmpInfoH.biHeight;
DWORD nColorTable=bmpInfoH.biClrUsed;
if(bitCount==8 && nColorTable==0) nColorTable=256;
int len;
if(w*(bitCount/8)%4) len=w*(bitCount/8)+(4-w*(bitCount/8)%4);
else len=w*(bitCount/8);
BITMAPFILEHEADER bmpfh;
bmpfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+len*h;
bmpfh.bfType = ('M'<<8)+'B';
bmpfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
if(bitCount==8)
{
bmpfh.bfSize+=nColorTable*4;
bmpfh.bfOffBits+=nColorTable*4;
}
HANDLE fh=CreateFileW(lpFileName,GENERIC_WRITE,0,NULL,
CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
if(fh==INVALID_HANDLE_VALUE)
{
MessageBoxW(NULL,L"同名のファイルが既に存在しています",lpFileName,MB_OK);
return FALSE;
}
DWORD dwWriteSize;
WriteFile(fh,&bmpfh,sizeof(BITMAPFILEHEADER),&dwWriteSize,NULL);
WriteFile(fh,&bmpInfoH,sizeof(BITMAPINFOHEADER),&dwWriteSize,NULL);
if(bitCount == 8)
WriteFile(fh,m_Bmi.bmiColors,nColorTable*4,&dwWriteSize,NULL);
if(bitCount == 32) Write32(fh,(LPDWORD)m_lpPixel , w , h );
else WriteFile(fh,m_lpPixel , len * h , &dwWriteSize , NULL);
CloseHandle(fh);
return TRUE;
}