/*/<C> pfwwdx.c //////////////////////////////[PastelFantasyWW DX]///
                      パステルファンタジーDeluxe
                           for WonderWitch
                            Version 1.00
                  《インプリメンテーションファイル》
                     Copyright(C) K.Shimizu 2001
///////////////////////////////////////////////////////////////////*/

/*外部ヘッダのインクルード//---------------------------------------*/
#include "pfwwdx.h"

/*変数宣言//-------------------------------------------------------*/
int		g_nStage;									/* ステージ数 */
char	g_acStage[MAX_STAGE][PF_WIDTH][PF_HEIGHT];	/* ステージデータ */
char	g_acField[PF_WIDTH][PF_HEIGHT];				/* フィールドの状態 */
char	g_acCheck[PF_WIDTH][PF_HEIGHT];				/* チェック状態 */
int		g_nCurStage;	/* 現在のステージ番号 */
int		g_nChar;		/* 残っているキャラクタ数 */
int		g_nStep;		/* ステップ数カウンタ */
DWORD	g_dwStartTime;	/* ステージをスタートした時間 */
char	g_szBuf[32];	/* 汎用文字列バッファ */
SoundIL	soundIL;		/* SoundILのインタフェース */
BOOL	g_bSoundIL;		/* SoundILを使用するか */
BOOL	g_bPlay;		/* BGM・効果音を再生するか */
BOOL	g_bColor;		/* 16色カラー機能を使用するか */

/*実装//-----------------------------------------------------------*/

/*/<FUNC> main ///////////////////////////////[PastelFantasyWW DX]/*/
/* メイン関数 */
int main()
{
	BOOL	bExit = FALSE;

	Init();
	while(TRUE){
		while(TRUE){
			if(!ProcTitle()){
				bExit = TRUE;
				break;
			}
			if(SelectFile(g_szBuf)){
				LoadDataFile(g_szBuf);
				break;
			}
		}
		if(bExit)
			break;

		BgmPlay(PF_RES_BGM2, PLAY_LOOP);
		while(TRUE){
			if(!ProcStage())
				break;
		}
		bgm_stop();
	}
	if(g_bSoundIL){
		sound_close();
		sounddrv_release();
	}
	wwc_set_color_mode(COLOR_MODE_GRAYSCALE);
	return 0;
}

/*/<FUNC> Init ///////////////////////////////[PastelFantasyWW DX]/*/
/* 初期化処理 */
void Init()
{
	/* 16色カラー機能設定 */
	g_bColor = (wwc_get_hardarch() == HARDARCH_WSC)		/* WSCの判別 */
				&& !(key_press_check() & KEY_Y1);
	if(g_bColor)
		wwc_set_color_mode(COLOR_MODE_16PACKED);	/* 16色パックトモードに設定 */

	/* 画面初期化 */
	screen_fill_char(SCREEN1, 0, 0, SCREEN_CHAR_WIDTH, SCREEN_CHAR_HEIGHT, 0);
	screen_fill_char(SCREEN2, 0, 0, SCREEN_CHAR_WIDTH, SCREEN_CHAR_HEIGHT, 0);
	screen_set_scroll(SCREEN1, 0, 0);
	screen_set_scroll(SCREEN2, 0, 0);
	display_control(DCM_SCR1 | DCM_SCR2 | DCM_SPR);
	lcd_set_segments(LCDSEG_HORIZONTAL);

	/* キーリピート設定 */
	key_set_repeat(4, 20);

	/* リソース検索 */
	ResFindResource();

	/* フォント設定 */
	InitFont();

	/* サウンド初期化 */
	if(open_sound_il(&soundIL) == E_FS_SUCCESS){
		g_bSoundIL = g_bPlay = TRUE;
		sounddrv_init();
		sound_open();
		se_play(ResGetRes(PF_RES_SE), -1);
	} else
		g_bSoundIL = g_bPlay = FALSE;
}

/*/<FUNC> InitFont ///////////////////////////[PastelFantasyWW DX]/*/
/* フォント設定 */
void InitFont()
{
	int	i;

	if(g_bColor){		/* 16色カラーの場合 */
		wwc_clear_font();
		wwc_font_set_colordata(PF_FONT_FRAME, 8, ResGetImgBits(PF_RES_FRAME16));
		wwc_font_set_colordata(PF_FONT_CHAR, 108, ResGetImgBits(PF_RES_MAIN16));
		for(i=0; i<16; i++){
			wwc_palette_set_color(PF_PAL_SCREEN, i, ResGet16ColorPalette(PF_RES_MAIN16)[i]);
			wwc_palette_set_color(PF_PAL_CURSOR, i, ResGet16ColorPalette(PF_RES_MAIN16)[i]);
		}
	} else {			/* 4色グレースケールの場合 */
		WORD	wColor = 0;

		font_set_colordata(PF_FONT_FRAME, 8, ResGetImgBits(PF_RES_FRAME4G));
		font_set_colordata(PF_FONT_CHAR, 108, ResGetImgBits(PF_RES_MAIN4G));
		for(i=3; i>=0; i--)
			wColor = (wColor << 4) | (ResGetColorPalette(PF_RES_MAIN4G)[i] >> 5);
		palette_set_color(PF_PAL_SCREEN, wColor);
		palette_set_color(PF_PAL_CURSOR, wColor);
	}
}

/*/<FUNC> SelectFile /////////////////////////[PastelFantasyWW DX]/*/
/* ファイルを選択 */
BOOL SelectFile(char *pszFileName)
{
	char		acIndex[ROM0FS_NUM_ENTRIES];
	int			i, nCount = 0, nFile = 0, nTop = 0, nSel = 0;
	struct stat	Stat;
	BOOL		bSel = TRUE, bRefresh = TRUE;

	DrawWndFrame(SCREEN1, 0, 0, 27, 17, TRUE);
	screen_fill_char(SCREEN1, 3, 0, 1, 1, PF_FONT_FRAME + 6);
	screen_fill_char(SCREEN1, 17, 0, 1, 1, PF_FONT_FRAME + 6);
	screen_fill_char(SCREEN1, 17, 17, 1, 1, PF_FONT_FRAME + 6);
	screen_fill_char(SCREEN1, 24, 17, 1, 1, PF_FONT_FRAME + 6);
	DrawStringFrom(SCREEN1, 4, 0, "ファイルを選択してください", PF_FONT_STRING);
	DrawStringFrom(SCREEN1, 18, 17, "PFWWDX", PF_FONT_STRING + 13);

	memset(acIndex, -1, sizeof(acIndex));

	while(TRUE){
		if(getent("/rom0/", nCount, &Stat) != E_FS_SUCCESS)
			break;
		if(Stat.count == -1)
			break;
		if(strcmp(strrchr(Stat.name, '.'), PF_FILE_EXT) == 0)
			acIndex[nFile++] = nCount;
		nCount++;
	}
	nFile--;

	if(nFile == -1){
		DrawWndFrame(SCREEN1, 6, 7, 21, 9, TRUE);
		DrawStringFrom(SCREEN1, 7, 8, "データファイルがありません。", PF_FONT_STRING + 20);
		key_wait();
		return FALSE;
	}

	for(i=0; i<5; i++)
		screen_fill_char(SCREEN1, 1, 2 + i * 3, 26, 2, PF_FONT_TILE);

	while(bSel){
		for(i=0; i<6; i++)
			screen_fill_char(SCREEN1, 1, 1 + i * 3, 26, 1, PF_FONT_TILE + 2);
		for(i=0; i<5; i++){
			screen_fill_char(SCREEN1, 1, i * 3 + 2, 1, 2, PF_FONT_TILE);
			screen_fill_char(SCREEN1, 26, i * 3 + 2, 1, 2, PF_FONT_TILE);
		}
		DrawWndFrame(SCREEN1, 1,  1 + nSel * 3, 26,  4 + nSel * 3, FALSE);

		if(bRefresh){
			for(i=0; i<=4; i++){
				if(i > nFile)
					break;
				screen_fill_char(SCREEN1, 2, i * 3 + 2, 24, 2, PF_FONT_TILE);
				getent("/rom0/", acIndex[i + nTop], &Stat);
				strcpy(g_szBuf, Stat.info);
				DrawStringFrom(SCREEN1, 2, 2 + i * 3, g_szBuf, PF_FONT_STRING + 20 + i * 45);
				strcpy(g_szBuf, Stat.name);
				DrawStringFrom(SCREEN1, 2, 3 + i * 3, g_szBuf, PF_FONT_STRING + 44 + i * 45);
				sprintf(g_szBuf, "%dKB", (Stat.len + 500) / 1000);
				DrawStringFrom(SCREEN1, 21, 3 + i * 3, g_szBuf, PF_FONT_STRING + 60 + i * 45);
			}
			bRefresh = FALSE;
		}

		switch(key_wait()){
		case KEY_UP1:
			if(--nSel < 0){
				nSel = 0;
				bRefresh = TRUE;
				if(--nTop < 0)
					nTop = 0;
			}
			break;
		case KEY_DOWN1:
			nSel++;
			if(nSel > nFile){
				nSel = nFile;
			} else if(nSel > 4){
				nSel = 4;
				bRefresh = TRUE;
				if(++nTop > nFile - 4)
					nTop = nFile - 4;
			}
			break;
		case KEY_A:
			bSel = FALSE;
			break;
		case KEY_B:
		case KEY_START:
			return FALSE;
		}
	}
	getent("/rom0/", acIndex[nSel + nTop], &Stat);
	strcpy(pszFileName, "/rom0/");
	strcat(pszFileName, Stat.name);
	return TRUE;
}

/*/<FUNC> LoadDataFile ///////////////////////[PastelFantasyWW DX]/*/
/* データファイル読み込み */
BOOL LoadDataFile(char *pszFileName)
{
	FILE far	*fp;
	static char	szBuf[256];
	char		c;
	int			i, j, k;

	DrawWndFrame(SCREEN1, 6, 7, 21, 9, TRUE);
	DrawStringFrom(SCREEN1, 7, 8, "Now Loading...", PF_FONT_STRING + 250);

	fp = fopen(pszFileName, "r");
	if(!fp)
		return FALSE;

	if(!GetLine(szBuf, fp))
		return FALSE;
	g_nStage = atoi(szBuf);
	if(g_nStage == 0)
		return FALSE;
	g_nCurStage = 0;

	for(k=0; k<g_nStage; k++){
		for(j=0; j<PF_HEIGHT; j++){
			if(!GetLine(szBuf, fp))
				return FALSE;
			for(i=0; i<PF_WIDTH; i++){
				c = szBuf[i];
				if(!c || c < '0' || c > '9')
					return FALSE;
				g_acStage[k][i][j] = c - '0';
			}
		}
	}
	return TRUE;
}

/*/<FUNC> GetLine ////////////////////////////[PastelFantasyWW DX]/*/
/* データファイルから１行取得 */
BOOL GetLine(char *pszBuf, FILE far *fp)
{
	while(TRUE){
		if(!fgets(pszBuf, 256, fp))
			return FALSE;
		if(*pszBuf != '#' && *pszBuf != 0x0d && *pszBuf != 0x0a)
			return TRUE;
	}
}

/*/<FUNC> ProcTitle //////////////////////////[PastelFantasyWW DX]/*/
/* タイトル処理 */
BOOL ProcTitle()
{
	int 	i, j, nSel = 0;
	WORD	wCount = 0;
	BOOL	bSel = TRUE;

	for(j=0; j<SCREEN_CHAR_HEIGHT; j++)
		for(i=0; i<SCREEN_CHAR_WIDTH; i++)
			screen_fill_char(SCREEN2, i, j, 1, 1, PF_FONT_TILE + (i + j) % 2);

	screen_fill_char(SCREEN1, 0, 0, SCREEN_CHAR_WIDTH, SCREEN_CHAR_HEIGHT, PF_FONT_TILE);
	for(i=0; i<=15; i++){
		DrawWndFrame(SCREEN1, 5, 1, 5 + i, 1 + i, TRUE);
		sys_wait(1);
	}
	DrawWndFrame(SCREEN1, 5, 1, 22, 16, TRUE);

	for(j=0; j<4; j++)
		for(i=0; i<8; i++)
			DrawCharAtRawPos(SCREEN1, i * 2 + 6, j * 2 + 2, (i + j * 12) % 5 + 1);

	for(j=0; j<4; j++)
		for(i=0; i<12; i++)
			screen_fill_char(SCREEN1, i + 8, j + 4, 1, 1, PF_FONT_TITLE + i + j * 12);

	DrawWndFrame(SCREEN1, 7, 10, 20, 13, TRUE);
	DrawString(SCREEN1, 9, 11, "GAME START", TRUE);
	DrawString(SCREEN1, 9, 12, "   EXIT   ", FALSE);
	DrawString(SCREEN1, 6, 15, "\x1cK.Shimizu 2001", FALSE);

	i = (PF_PAL_CURSOR - 8) << CFSFT_PALETTE;
	sprite_set_char_location(0, PF_FONT_CURSOR | CFM_SPR_UPPER | i, 64, 88);
	sprite_set_char_location(1, PF_FONT_CURSOR | CFM_SPR_UPPER | CFM_FLIP_H | i, 152, 88);
	sprite_set_char_location(2, PF_FONT_STAR | CFM_SPR_UPPER | i, 64, 88);
	sprite_set_char_location(3, PF_FONT_STAR | CFM_SPR_UPPER | i, 152, 88);
	sprite_set_range(0, 4);

	screen2_set_window(40, 8, 143, 127);
	display_control(DCM_SCR1 | DCM_SCR2 | DCM_SCR2_WIN_OUTSIDE | DCM_SPR);

	if(!bgm_check())
		BgmPlay(PF_RES_BGM1, PLAY_LOOP);

	while(bSel){
		switch(key_hit_check_with_repeat()){
		case KEY_UP1:
		case KEY_DOWN1:
			nSel = 1 - nSel;	/* 0 <-> 1 切り替え */
			break;
		case KEY_A:
			bSel = FALSE;
			if(nSel == 1)
				return FALSE;
			break;
		case KEY_B:
		case KEY_START:
			return FALSE;
		}
		i = 88 + nSel * 8;
		sprite_set_location(0, 64, i);
		sprite_set_location(1, 152, i);
		sprite_set_location(2, 64 + (wCount % 40) * 2, i);
		sprite_set_location(3, 152 - (wCount % 40) * 2, i);

		i = (wCount % 32) / 2;
		screen_set_scroll(SCREEN2, i, i);
		wCount--;
		if(wCount < 0)
			wCount = (WORD)-1;
		sys_wait(2);
	}
	sprite_set_range(0, 0);
	screen_set_scroll(SCREEN2, 0, 0);
	display_control(DCM_SCR1 | DCM_SPR);
}

/*/<FUNC> LoadStage //////////////////////////[PastelFantasyWW DX]/*/
/* ステージデータ読み込み */
void LoadStage(int nStage)
{
	int	i, j;

	g_nCurStage = (char)nStage;
	g_nStep = 0;
	g_nChar = 0;
	for(j=0; j<PF_HEIGHT; j++){
		for(i=0; i<PF_WIDTH; i++){
			g_acField[i][j] = g_acStage[g_nCurStage][i][j];
			if(g_acField[i][j] > 0)
				g_nChar++;
			g_acCheck[i][j] = FALSE;
		}
	}
}

/*/<FUNC> ProcStage //////////////////////////[PastelFantasyWW DX]/*/
/* ステージ中の処理 */
BOOL ProcStage()
{
	int	i, j, nKey;
	int	x = 0, y = 0;

	for(i=0; i<=8; i++){
		DrawWndFrame(SCREEN1, 8 - i, 8 - i, 19 + i, 9 + i, TRUE);
		sys_wait(2);
	}
	for(j=0; j<16; j++)
		for(i=0; i<2; i++)
			screen_fill_char(SCREEN1, i + 25, j + 1, 1, 1, PF_FONT_TILE + (i + j) % 2);

	LoadStage(g_nCurStage);
	DrawField();

	i = (PF_PAL_CURSOR - 8) << CFSFT_PALETTE;
	screen_fill_attr(SCREEN2, 0, 0, SCREEN_CHAR_WIDTH, SCREEN_CHAR_HEIGHT, 0 | i, 0);
	sprite_set_char_location(0, PF_FONT_CURSOR | i, 0, 12);
	sprite_set_char_location(1, PF_FONT_CURSOR | CFM_FLIP_H | i, 24, 12);
	sprite_set_char_location(2, PF_FONT_CURSOR + 1 | i, 12, 0);
	sprite_set_char_location(3, PF_FONT_CURSOR + 1 | CFM_FLIP_V | i, 12, 24);
	sprite_set_range(0, 4);

	sprintf(g_szBuf, "STAGE %d", g_nCurStage + 1);
	DrawString(SCREEN1, 4, 17, g_szBuf, TRUE);
	screen_fill_char(SCREEN1, 3, 17, 1, 1, PF_FONT_FRAME + 6);
	screen_fill_char(SCREEN1, 4 + strlen(g_szBuf), 17, 1, 1, PF_FONT_FRAME + 6);

	sprintf(g_szBuf, "%d Steps", g_nStep);
	DrawString(SCREEN1, 17, 17, g_szBuf, FALSE);
	screen_fill_char(SCREEN1, 16, 17, 1, 1, PF_FONT_FRAME + 6);
	screen_fill_char(SCREEN1, 17 + strlen(g_szBuf), 17, 1, 1, PF_FONT_FRAME + 6);

	display_control(DCM_SCR1 | DCM_SCR2 | DCM_SPR);

	g_dwStartTime = sys_get_tick_count();

	while(TRUE){
		nKey = key_hit_check_with_repeat();

		if(nKey){
			if(nKey & KEY_LEFT1)			/* X4 */
				if(--x < 0)
					x = PF_WIDTH - 1;
			if(nKey & KEY_DOWN1)			/* X3 */
				if(++y > PF_HEIGHT - 1)
					y = 0;
			if(nKey & KEY_RIGHT1)			/* X2 */
				if(++x > PF_WIDTH - 1)
					x = 0;
			if(nKey & KEY_UP1)				/* X1 */
				if(--y < 0)
					y = PF_HEIGHT - 1;
			if(nKey & KEY_LEFT2){			/* Y4 */
				SePlayN(PF_SE_PIPO);
				if(--g_nCurStage < 0)
					g_nCurStage = g_nStage - 1;
				return TRUE;
			}
			if(nKey & KEY_DOWN2)			/* Y3 */
				return TRUE;
			if(nKey & KEY_RIGHT2){			/* Y2 */
				SePlayN(PF_SE_PIPO);
				if(++g_nCurStage > g_nStage - 1)
					g_nCurStage = 0;
				return TRUE;
			}
			if(nKey & KEY_A)				/* A */
				if(g_acField[x][y] > 0){
					SePlayN(PF_SE_PU);
					g_acCheck[x][y]  = !g_acCheck[x][y];
					DrawChar(SCREEN1, x, y, g_acField[x][y]);
					CheckChar(SCREEN2, x, y, g_acCheck[x][y]);
				}
			if(nKey & KEY_B)				/* B */
				ClearChar();
			if(nKey & KEY_START)			/* START */
				return FALSE;

			if(g_nChar == 0){			/* すべて消したら */
				StageClear();
				return TRUE;
			}

			sprite_set_location(0, x * 16,      y * 16 + 12);
			sprite_set_location(1, x * 16 + 24, y * 16 + 12);
			sprite_set_location(2, x * 16 + 12, y * 16);
			sprite_set_location(3, x * 16 + 12, y * 16 + 24);
		}
	}
}

/*/<FUNC> ClearChar //////////////////////////[PastelFantasyWW DX]/*/
/* キャラクタをクリアする処理 */
void ClearChar()
{
	char	cChange[PF_WIDTH][PF_HEIGHT];	/* 作業用 */
	BOOL	bClear;							/* 消えたか */
	int		nClear = 0;						/* 消えた数 */
	int		i, j;

	for(j=0; j<PF_HEIGHT; j++)
		for(i=0; i<PF_WIDTH; i++){
			cChange[i][j] = FALSE;
			if(g_acCheck[i][j]){
				bClear = FALSE;
				if(i > 0 && g_acField[i][j] == g_acField[i - 1][j])
					bClear = TRUE;
				if(i < PF_WIDTH - 1 && g_acField[i][j] == g_acField[i + 1][j])
					bClear = TRUE;
				if(j > 0 && g_acField[i][j] == g_acField[i][j - 1])
					bClear = TRUE;
				if(j < PF_HEIGHT - 1 && g_acField[i][j] == g_acField[i][j + 1])
					bClear = TRUE;
				if(bClear){
					cChange[i][j] = TRUE;
					nClear++;
					g_nChar--;
				}
			}
		}
	for(j=0; j<8; j++)
		for(i=0; i<12; i++)
			if(g_acCheck[i][j]){
				g_acCheck[i][j] = FALSE;
				if(cChange[i][j])
					g_acField[i][j] = 0;
				DrawChar(SCREEN1, i, j, g_acField[i][j]);
				CheckChar(SCREEN2, i, j, g_acCheck[i][j]);
			}
	FallChar();
	if(nClear){
		SePlayN(PF_SE_PUPE);
		sprintf(g_szBuf, "%d", ++g_nStep);
		DrawString(SCREEN1, 17, 17, g_szBuf, FALSE);
	}
}

/*/<FUNC> FallChar ///////////////////////////[PastelFantasyWW DX]/*/
/* キャラクタの落下処理 */
void FallChar()
{
	int	nSpace = 0;	/* 空白の数 */
	int	i, j, k;

	for(i=0; i<PF_WIDTH; i++){
		for(j=PF_HEIGHT-1; j>0; j--){
			if(g_acField[i][j] == 0){
				nSpace = 0;
				for(k=j; k>0; k--)
				if(g_acField[i][k] == 0)
					nSpace++;
				else
					break;
				for(k=j; k>0; k--){
					if(k - nSpace >= 0)
						g_acField[i][k] = g_acField[i][k - nSpace];
					else
						g_acField[i][k] = 0;
					DrawChar(SCREEN1, i, k, g_acField[i][k]);
					CheckChar(SCREEN2, i, k, g_acCheck[i][k]);
				}
				g_acField[i][0] = 0;
				DrawChar(SCREEN1, i, 0, g_acField[i][0]);
				CheckChar(SCREEN2, i, 0, g_acCheck[i][0]);
			}
		}
	}
}

/*/<FUNC> StageClear /////////////////////////[PastelFantasyWW DX]/*/
/* ステージクリア処理 */
void StageClear()
{
	DWORD	dwPastSec = (sys_get_tick_count() - g_dwStartTime) / 75;
	int		i;

	sprite_set_range(0, 0);
	for(i=0; i<=3; i++){
		DrawWndFrame(SCREEN1, 10 - i, 6 - i, 17 + i, 7 + i, TRUE);
		sys_wait(2);
	}
	for(i=0; i<10; i++)
		screen_fill_char(SCREEN1, i + 9, 5, 1, 1, PF_FONT_CLEAR + i);
	for(i=0; i<10; i++)
		screen_fill_char(SCREEN1, i + 9, 6, 1, 1, PF_FONT_CLEAR + i + 12);

	for(i=0; i<=1; i++){
		DrawWndFrame(SCREEN1, 7 - i, 12 - i, 20 + i, 13 + i, TRUE);
		sys_wait(2);
	}
	DrawString(SCREEN1, 10, 8, "TIME:", FALSE);
	sprintf(g_szBuf, "%d'%d\"", (int)dwPastSec / 60, (int)dwPastSec % 60);
	DrawString(SCREEN1, 12, 9, g_szBuf, FALSE);
	DrawString(SCREEN1, 8, 12, "A:NEXT STAGE", FALSE);
	DrawString(SCREEN1, 8, 13, "B:TRY AGAIN", FALSE);

	SePlayN(PF_SE_STAGECLEAR);

	while(TRUE){
		switch(key_wait()){
		case KEY_A:
			if(++g_nCurStage > g_nStage - 1)
				g_nCurStage = 0;
			return;
		case KEY_B:
			return;
		}
	}
}

/*/<FUNC> DrawChar ///////////////////////////[PastelFantasyWW DX]/*/
/* キャラクタをキャラクタ座標指定で表示 */
void DrawChar(int nScreen, int nX, int nY, int nChar)
{
	DrawCharAtRawPos(nScreen, nX * 2 + 1, nY * 2 + 1, nChar);
}

/*/<FUNC> DrawCharAtRawPos ///////////////////[PastelFantasyWW DX]/*/
/* キャラクタを絶対座標指定で表示 */
void DrawCharAtRawPos(int nScreen, int nX, int nY, int nChar)
{
	nChar = (nChar) * 2 + PF_FONT_CHAR;
	screen_fill_char(nScreen, nX,     nY,     1, 1, nChar++);
	screen_fill_char(nScreen, nX + 1, nY,     1, 1, nChar++);
	nChar += 10;
	screen_fill_char(nScreen, nX,     nY + 1, 1, 1, nChar++);
	screen_fill_char(nScreen, nX + 1, nY + 1, 1, 1, nChar);
}

/*/<FUNC> CheckChar //////////////////////////[PastelFantasyWW DX]/*/
/* キャラクタにチェックを入れる */
void CheckChar(int nScreen, int nX, int nY, BOOL bCheck)
{
	int	nPal, nChar = PF_FONT_CHECK;

	nPal = PF_PAL_CURSOR << CFSFT_PALETTE;
	nX = nX * 2 + 1;
	nY = nY * 2 + 1;
	if(!bCheck){
		screen_fill_attr(nScreen, nX, nY, 2, 2, 0 | nPal, 0);
	} else {
		screen_fill_attr(nScreen, nX,     nY,     1, 1, nChar++ | nPal, 0);
		screen_fill_attr(nScreen, nX + 1, nY,     1, 1, nChar++ | nPal, 0);
		screen_fill_attr(nScreen, nX,     nY + 1, 1, 1, nChar++ | nPal, 0);
		screen_fill_attr(nScreen, nX + 1, nY + 1, 1, 1, nChar   | nPal, 0);
	}
}

/*/<FUNC> DrawField //////////////////////////[PastelFantasyWW DX]/*/
/* フィールド全体を表示 */
void DrawField()
{
	int	i, j;

	for(j=0; j<PF_HEIGHT; j++){
		for(i=0; i<PF_WIDTH; i++){
			DrawChar(SCREEN1, i, j, g_acField[i][j]);
			CheckChar(SCREEN2, i, j, g_acCheck[i][j]);
		}
	}
}

/*/<FUNC> DrawWndFrame ///////////////////////[PastelFantasyWW DX]/*/
/* ウィンドウ枠を表示 */
void DrawWndFrame(int nScreen, int nX1, int nY1, int nX2, int nY2, BOOL bClear)
{
	int	i;

	screen_fill_char(nScreen, nX1, nY1, 1, 1, PF_FONT_FRAME);
	screen_fill_char(nScreen, nX2, nY1, 1, 1, PF_FONT_FRAME + 1);
	screen_fill_char(nScreen, nX1, nY2, 1, 1, PF_FONT_FRAME + 2);
	screen_fill_char(nScreen, nX2, nY2, 1, 1, PF_FONT_FRAME + 3);

	for(i=nX1+1; i<nX2; i++)
		screen_fill_char(nScreen, i, nY1, 1, 1, PF_FONT_FRAME + 4);
	for(i=nX1+1; i<nX2; i++)
		screen_fill_char(nScreen, i, nY2, 1, 1, PF_FONT_FRAME + 4);
	for(i=nY1+1; i<nY2; i++)
		screen_fill_char(nScreen, nX1, i, 1, 1, PF_FONT_FRAME + 5);
	for(i=nY1+1; i<nY2; i++)
		screen_fill_char(nScreen, nX2, i, 1, 1, PF_FONT_FRAME + 5);
	if(bClear && nX2 - nX1 - 1 > 0 && nY2 - nY1 - 1 > 0)
		screen_fill_char(nScreen, nX1 + 1, nY1 + 1, nX2 - nX1 - 1, nY2 - nY1 - 1, PF_FONT_TILE);
}

/*/<FUNC> DrawString /////////////////////////[PastelFantasyWW DX]/*/
/* 文字列を表示 */
void DrawString(int nScreen, int nX, int nY, char *pszStr, BOOL bReset)
{
	static int	nCount = 0;

	if(bReset)
		nCount = 0;
	DrawStringFrom(nScreen, nX, nY, pszStr, PF_FONT_STRING + nCount);
	nCount += strlen(pszStr);
}

/*/<FUNC> DrawStringFrom /////////////////////[PastelFantasyWW DX]/*/
/* フォント番号を指定して文字列を表示 */
void DrawStringFrom(int nScreen, int nX, int nY, char *pszStr, int nFont)
{
	WORD		wCode;
	BYTE		byChar;

	while(TRUE){
		byChar = *pszStr++;
		if(!byChar)
			break;
		if(IsSjis1st(byChar))
			wCode = (byChar << 8) + *pszStr++;
		else
			wCode = (WORD)byChar;

		if(g_bColor)		/* 16色カラーの場合 */
			SetTextFont16Packed(wCode, nFont);
		else				/* 4色グレースケールの場合 */
			SetTextFontColor(wCode, nFont);

		screen_fill_char(nScreen, nX, nY, 1, 1, nFont);
		nFont++;
		nX++;
	}
}

/*/<FUNC> Set16PackedTextFont ////////////////[PastelFantasyWW DX]/*/
/* 文字を 16色パックトフォントで設定 */
void SetTextFont16Packed(WORD wCode, int nFont)
{
	static BYTE		abyMonoFont[8];
	static DWORD	adw16ColorFont[8];
	int				i, j;

	text_get_fontdata(wCode, abyMonoFont);
	memset(adw16ColorFont, 0, 32);		/* 32バイト分ゼロクリア */

	for(j=0; j<8; j++){
		for(i=0; i<4; i++){
			adw16ColorFont[j] = (adw16ColorFont[j] << 4)
				| ((abyMonoFont[j] & (1 << (i * 2 + 1))) ? 1 : 5);
			adw16ColorFont[j] = (adw16ColorFont[j] << 4)
				| ((abyMonoFont[j] & (1 << i * 2)) ? 1 : 5);
		}
	}
	wwc_font_set_colordata(nFont, 1, adw16ColorFont);
}

/*/<FUNC> SetTextFontColor ///////////////////[PastelFantasyWW DX]/*/
/* 文字を 4色グレースケールフォントで設定 */
void SetTextFontColor(WORD wCode, int nFont)
{
	static BYTE	abyMonoFont[8];

	text_get_fontdata(wCode, abyMonoFont);
	font_set_monodata(nFont, 1, abyMonoFont);
}

/*/<FUNC> IsSjis1st //////////////////////////[PastelFantasyWW DX]/*/
/* ShiftJISの 1バイト目か調べる */
BOOL IsSjis1st(BYTE byByte)
{
	return (0x81 <= byByte && byByte <= 0x9f)
			|| (0xe0 <= byByte && byByte <= 0xfc);
}

/*/<FUNC> BgmPlay ////////////////////////////[PastelFantasyWW DX]/*/
/* BGMを再生 */
void BgmPlay(int nRes, WORD wMode)
{
	if(g_bPlay)
		bgm_play(ResGetRes(nRes), wMode);
}

/*/<FUNC> SePlayN ////////////////////////////[PastelFantasyWW DX]/*/
/* 効果音を再生 */
void SePlayN(int n)
{
	if(g_bPlay)
		se_play_n(n);
}

/*/<FUNC> atoi ///////////////////////////////[PastelFantasyWW DX]/*/
/* 文字列を整数に変換 */
int atoi(char *pszStr)
{
	int		nRet = 0;
	char	c;

	while(TRUE){
		c = *pszStr++;
		if(!c || c < '0' || c > '9')
			break;
		nRet = nRet * 10 + (c - '0');
	}
	return nRet;
}

/*/[EOF] pfwwdx.c /////////////////////////////////////////////////*/
