⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mainmenuwnd.c

📁 俄罗斯方块的整套源代码
💻 C
字号:
#include "MainMenuWnd.h" 

#include "russdmd.h"
#include "russdmd_res.h"
#include "commondef.h"

static void MainMenuWnd_Update	(MainMenuWnd* pthis);
boolean		MainMenuWnd_Compute (MainMenuWnd* pthis);
void		MainMenuWnd_Draw	(MainMenuWnd* pthis);
uint8		MainMenuWnd_QueryTextLineNum	(MainMenuWnd* pthis, const AECHAR * pcText, int nChars);

#define ARROW_ALIGN		(10)
#define STRING_BUFFER_SIZE	(128 * 2)

boolean MainMenuWnd_New(MainMenuWnd* pthis, RussDmdApp* pMe)
{
	pthis->pMe = pMe;
	pthis->m_state = eMenuState_SPLASH;
	pthis->m_menuIndex = eMenuIndex_START;
	pthis->m_imgSplash = NULL;
	pthis->m_nSplashSkipCounter = 10;

	return TRUE;
}

boolean MainMenuWnd_HandleEvent(MainMenuWnd* pthis, AEEEvent eCode, uint16 wParam, uint32 dwParam)
{
	switch(eCode)
	{
		case EVT_APP_SUSPEND:
			ISHELL_CancelTimer(pthis->pMe->a.m_pIShell, (PFNNOTIFY)MainMenuWnd_Update, pthis);
			return TRUE;

		case EVT_APP_RESUME:
			MainMenuWnd_Update(pthis);
			return TRUE;

		default:
			return FALSE;
	}
}

boolean MainMenuWnd_Open(MainMenuWnd* pthis)
{
	switch(pthis->m_state)
	{
	case eMenuState_MENU:
		IDISPLAY_SetColor(pthis->pMe->a.m_pIDisplay, CLR_USER_TEXT, RGB_WHITE);
		pthis->m_nArrowAlign = ARROW_ALIGN;
		pthis->m_pszMenu = (AECHAR*)MALLOC(STRING_BUFFER_SIZE);
		ZEROAT(pthis->m_pszMenu);
		ISHELL_LoadResString(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IDS_MENU, 
							pthis->m_pszMenu, STRING_BUFFER_SIZE);
		pthis->m_nMaxLine = MainMenuWnd_QueryTextLineNum(pthis, pthis->m_pszMenu, -1);
		pthis->m_nStartLine = 0;
		CleanDeleteImage(pthis->m_imgSplash);
		pthis->m_imgSplash = ISHELL_LoadResImage(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IMG_MENUBG);
		IIMAGE_GetInfo(pthis->m_imgSplash, &pthis->m_pi);
		break;

	case eMenuState_SPLASH:
		CleanDeleteImage(pthis->m_imgSplash);
		pthis->m_imgSplash = ISHELL_LoadResImage(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IMG_SPLASH);
		IIMAGE_GetInfo(pthis->m_imgSplash, &pthis->m_pi);
		break;

	case eMenuState_FILEERROR:
		IDISPLAY_SetColor(pthis->pMe->a.m_pIDisplay, CLR_USER_TEXT, RGB_BLACK);
		IDISPLAY_FillRect(pthis->pMe->a.m_pIDisplay, NULL, RGB_BLACK);
		pthis->m_pszMenu = (AECHAR*)MALLOC(STRING_BUFFER_SIZE);
		ISHELL_LoadResString(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IDS_FILEERROR, pthis->m_pszMenu, STRING_BUFFER_SIZE);
		break;

	case eMenuState_DEMOERROR:
		IDISPLAY_SetColor(pthis->pMe->a.m_pIDisplay, CLR_USER_TEXT, RGB_BLACK);
		IDISPLAY_FillRect(pthis->pMe->a.m_pIDisplay, NULL, RGB_BLACK);
		pthis->m_pszMenu = (AECHAR*)MALLOC(STRING_BUFFER_SIZE);
		ISHELL_LoadResString(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IDS_DEMOERROR, pthis->m_pszMenu, STRING_BUFFER_SIZE);
		break;
	}
 	MainMenuWnd_Update(pthis);
	return TRUE;
}


void MainMenuWnd_Close(MainMenuWnd* pthis)
{
	pthis->m_state = eMenuState_MENU;
	ISHELL_CancelTimer(pthis->pMe->a.m_pIShell, (PFNNOTIFY)MainMenuWnd_Update, pthis);
	CleanDeleteImage(pthis->m_imgSplash);
	FREEIF(pthis->m_pszMenu);
}

void MainMenuWnd_Free(MainMenuWnd* pthis)
{
	MainMenuWnd_Close(pthis);
}

static void MainMenuWnd_Update(MainMenuWnd* pthis)
{	
	ISHELL_SetTimer(pthis->pMe->a.m_pIShell, MAIN_LOOP_TIME, (PFNNOTIFY)MainMenuWnd_Update, pthis);

	if (MainMenuWnd_Compute(pthis))
		MainMenuWnd_Draw(pthis);
	pthis->pMe->keyFlag = kKeypad_NULL;	// 这里有个潜在问题,即绘制过程中的按键都会被清除
}

boolean MainMenuWnd_Compute(MainMenuWnd* pthis)
{
	switch(pthis->m_state)
	{
	case eMenuState_SPLASH:
		if (pthis->m_nSplashSkipCounter > 0)
		{
			pthis->m_nSplashSkipCounter--;
		}
		else
		{
			// 跳出闪屏
			IDISPLAY_SetColor(pthis->pMe->a.m_pIDisplay, CLR_USER_TEXT, RGB_WHITE);
			pthis->m_state = eMenuState_MENU;
			CleanDeleteImage(pthis->m_imgSplash);
			pthis->m_imgSplash = ISHELL_LoadResImage(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IMG_MENUBG);
			IIMAGE_GetInfo(pthis->m_imgSplash, &pthis->m_pi);
			pthis->m_pszMenu = (AECHAR*)MALLOC(STRING_BUFFER_SIZE);
			ZEROAT(pthis->m_pszMenu);
			ISHELL_LoadResString(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IDS_MENU,
								pthis->m_pszMenu, STRING_BUFFER_SIZE);
			pthis->m_nMaxLine = MainMenuWnd_QueryTextLineNum(pthis, pthis->m_pszMenu, -1);
			pthis->m_nStartLine = 0;
		}
		break;

	case eMenuState_MENU:
		// 菜单箭头位置
		pthis->m_nArrowAlign = (pthis->m_nArrowAlign + 1) % ARROW_ALIGN;

		// 按键处理
		if (pthis->pMe->keyFlag & kKeypad_Left)
		{
			pthis->m_menuIndex = (pthis->m_menuIndex + eMenuIndex_NUM - 1) % eMenuIndex_NUM;
		}
		else if (pthis->pMe->keyFlag & kKeypad_Right)
		{
			pthis->m_menuIndex = (pthis->m_menuIndex + 1) % eMenuIndex_NUM;
		}
		else if (pthis->pMe->keyFlag & kKeypad_Clr)
		{
			ISHELL_CloseApplet(pthis->pMe->a.m_pIShell, FALSE);
		}
		else if (pthis->pMe->keyFlag & kKeypad_Select)
		{
			switch(pthis->m_menuIndex)
			{
			case eMenuIndex_START:
				IDISPLAY_SetColor(pthis->pMe->a.m_pIDisplay, CLR_USER_TEXT, RGB_WHITE);
				RussDmdApp_SetActiveWnd(pthis->pMe, IDW_GAME);
				break;

#ifdef ENABLE_MUSIC
			case eMenuIndex_OPTION:
				// 切换音乐开关
				pthis->pMe->game.m_bMusicOn = !pthis->pMe->game.m_bMusicOn;
				break;
#endif

			case eMenuIndex_RECORD:
				IDISPLAY_SetColor(pthis->pMe->a.m_pIDisplay, CLR_USER_TEXT, RGB_BLACK);
				RussDmdApp_SetActiveWnd(pthis->pMe, IDW_SCORELIST);
				break;

			case eMenuIndex_HELP:
				IDISPLAY_SetColor(pthis->pMe->a.m_pIDisplay, CLR_USER_TEXT, RGB_BLACK);
				CleanDeleteImage(pthis->m_imgSplash);
				pthis->m_imgSplash = ISHELL_LoadResImage(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IMG_OPTIONBG);
				IIMAGE_GetInfo(pthis->m_imgSplash, &pthis->m_pi);
				ISHELL_LoadResString(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IDS_HELP,
								pthis->m_pszMenu, STRING_BUFFER_SIZE);
				pthis->m_nMaxLine = MainMenuWnd_QueryTextLineNum(pthis, pthis->m_pszMenu, -1);
				pthis->m_nStartLine = 0;
				pthis->m_state = eMenuState_HELP;
				break;

			case eMenuIndex_ABOUT:
				IDISPLAY_SetColor(pthis->pMe->a.m_pIDisplay, CLR_USER_TEXT, RGB_BLACK);
				CleanDeleteImage(pthis->m_imgSplash);
				pthis->m_imgSplash = ISHELL_LoadResImage(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IMG_OPTIONBG);
				IIMAGE_GetInfo(pthis->m_imgSplash, &pthis->m_pi);
				ISHELL_LoadResString(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IDS_ABOUT,
								pthis->m_pszMenu, STRING_BUFFER_SIZE);
				pthis->m_nMaxLine = MainMenuWnd_QueryTextLineNum(pthis, pthis->m_pszMenu, -1);
				pthis->m_nStartLine = 0;
				pthis->m_state = eMenuState_ABOUT;
				break;
#ifdef ENABLE_RECOMAND
			case eMenuIndex_SMS:
				IDISPLAY_SetColor(pthis->pMe->a.m_pIDisplay, CLR_USER_TEXT, RGB_BLACK);
				CleanDeleteImage(pthis->m_imgSplash);
				pthis->m_imgSplash = ISHELL_LoadResImage(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IMG_OPTIONBG);
				IIMAGE_GetInfo(pthis->m_imgSplash, &pthis->m_pi);
				RussDmdApp_SetActiveWnd(pthis->pMe, IDW_SMS);
				break;
#endif
			}
			return FALSE;
		}
		break;

	case eMenuState_ABOUT:
	case eMenuState_HELP:
		if (pthis->pMe->keyFlag & kKeypad_Clr)
		{
			IDISPLAY_SetColor(pthis->pMe->a.m_pIDisplay, CLR_USER_TEXT, RGB_WHITE);
			CleanDeleteImage(pthis->m_imgSplash);
			pthis->m_imgSplash = ISHELL_LoadResImage(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IMG_MENUBG);
			IIMAGE_GetInfo(pthis->m_imgSplash, &pthis->m_pi);
			ISHELL_LoadResString(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IDS_MENU, 
								pthis->m_pszMenu, STRING_BUFFER_SIZE);
			pthis->m_nMaxLine = MainMenuWnd_QueryTextLineNum(pthis, pthis->m_pszMenu, -1);
			pthis->m_nStartLine = 0;
			pthis->m_state = eMenuState_MENU;
		}
		else if (pthis->pMe->keyFlag & kKeypad_Up)
		{
			if (pthis->m_nStartLine > 0)
				pthis->m_nStartLine--;
		}
		else if (pthis->pMe->keyFlag & kKeypad_Down)
		{
			if (pthis->m_nStartLine < pthis->m_nMaxLine - 1)
				pthis->m_nStartLine++;
		}
		break;

	case eMenuState_FILEERROR:
	case eMenuState_DEMOERROR:
		if (pthis->pMe->keyFlag & kKeypad_Select)
		{
			ISHELL_CloseApplet(pthis->pMe->a.m_pIShell, FALSE);
		}
		break;
	}
	return TRUE;
}

void MainMenuWnd_Draw(MainMenuWnd* pthis)
{
	switch(pthis->m_state)
	{
	case eMenuState_SPLASH:
		IDISPLAY_ClearScreen(pthis->pMe->a.m_pIDisplay);
		IIMAGE_Draw(pthis->m_imgSplash, (pthis->pMe->screenWidth - pthis->m_pi.cx) >> 1, (pthis->pMe->screenHeight - pthis->m_pi.cy) >> 1);
		break;

	case eMenuState_MENU:
		IDISPLAY_FillRect(pthis->pMe->a.m_pIDisplay, NULL, RGB_BLACK);
		IIMAGE_Draw(pthis->m_imgSplash, (pthis->pMe->screenWidth - pthis->m_pi.cx) >> 1, 0);

		// 画左右提示箭头
		IDISPLAY_DrawText(pthis->pMe->a.m_pIDisplay, AEE_FONT_NORMAL, 
						pthis->m_pszMenu, 1, 20 - pthis->m_nArrowAlign, 0/*pthis->pMe->screenHeight - 20*/, 
						NULL, IDF_TEXT_TRANSPARENT | IDF_ALIGN_BOTTOM);
		IDISPLAY_DrawText(pthis->pMe->a.m_pIDisplay, AEE_FONT_NORMAL, 
						pthis->m_pszMenu + 1, 1, 
						pthis->pMe->screenWidth - FONT_HEIGHT / 2 - (20 - pthis->m_nArrowAlign), 0/*pthis->pMe->screenHeight - 20*/,
						NULL, IDF_TEXT_TRANSPARENT | IDF_ALIGN_BOTTOM);
#ifdef ENABLE_MUSIC
		if (pthis->m_menuIndex < eMenuIndex_OPTION)
		{
			IDISPLAY_DrawText(pthis->pMe->a.m_pIDisplay, AEE_FONT_NORMAL, 
				pthis->m_pszMenu + 2 + pthis->m_menuIndex * 2, 2, 
				0, 0/*pthis->pMe->screenHeight - 20*/, NULL, IDF_TEXT_TRANSPARENT | IDF_ALIGN_CENTER | IDF_ALIGN_BOTTOM);
		}
		else if (pthis->m_menuIndex > eMenuIndex_OPTION)
		{
			IDISPLAY_DrawText(pthis->pMe->a.m_pIDisplay, AEE_FONT_NORMAL, 
				pthis->m_pszMenu + 2 + (pthis->m_menuIndex - 1) * 2, 2, 
				0, 0/*pthis->pMe->screenHeight - 20*/, NULL, IDF_TEXT_TRANSPARENT | IDF_ALIGN_CENTER | IDF_ALIGN_BOTTOM);
		}
		else
		{
			//pthis->m_menuIndex == eMenuIndex_OPTION
			IDISPLAY_DrawText(pthis->pMe->a.m_pIDisplay, AEE_FONT_NORMAL, 
				pthis->m_pszMenu + 12 + (pthis->pMe->game.m_bMusicOn ? 0 : 3), 3, 
				0, 0/*pthis->pMe->screenHeight - 20*/, NULL, IDF_TEXT_TRANSPARENT | IDF_ALIGN_CENTER | IDF_ALIGN_BOTTOM);
		}
#else
		IDISPLAY_DrawText(pthis->pMe->a.m_pIDisplay, AEE_FONT_NORMAL, 
						pthis->m_pszMenu + 2 + pthis->m_menuIndex * 2, 2, 
						0, 0/*pthis->pMe->screenHeight - 20*/, NULL, IDF_TEXT_TRANSPARENT | IDF_ALIGN_CENTER | IDF_ALIGN_BOTTOM);
#endif
		break;

	case eMenuState_ABOUT:
	case eMenuState_HELP:
		IIMAGE_Draw(pthis->m_imgSplash, 0, 0);
	case eMenuState_FILEERROR:
	case eMenuState_DEMOERROR:
		{
			int nChars;				// 总字数
			int nPrinted = 0;		// 已经显示完的字符数
			int nToPrint = 0;		// 本次可以显示的字符数
			int y = 5;
			uint8 nStartLine = pthis->m_nStartLine;
			AECHAR szText[MAX_STRING_SIZE];

			IDISPLAY_SetColor(pthis->pMe->a.m_pIDisplay, CLR_USER_TEXT, RGB_WHITE);
			if (pthis->m_state == eMenuState_DEMOERROR || pthis->m_state == eMenuState_FILEERROR)
				IDISPLAY_FillRect(pthis->pMe->a.m_pIDisplay, NULL, RGB_BLACK);
			
			nChars = WSTRLEN(pthis->m_pszMenu);
			if (nStartLine < 0)
				nStartLine = 0;
			

			while (nPrinted < nChars)
			{
				MEMSET(szText, 0, sizeof(AECHAR) * MAX_STRING_SIZE);
				// 计算本行可以显示多少个字符
				do
				{
					// 判断换行符"\"
					if (pthis->m_pszMenu[nPrinted + nToPrint] == 0x005c)
					{
						nToPrint++;
						break;
					}
					szText[nToPrint] = pthis->m_pszMenu[nPrinted + nToPrint];
					if (IDISPLAY_MeasureText(pthis->pMe->a.m_pIDisplay, AEE_FONT_NORMAL, szText) < pthis->pMe->screenWidth - 5)
					{
						nToPrint++;
					}
					else
					{
						szText[--nToPrint] = 0;
						break;
					}
				} while(nToPrint < nChars - nPrinted);

				// 到达开始显示的行数后才开始显示
				if (nStartLine > 0)
					nStartLine--;
				else
				{
					IDISPLAY_DrawText(pthis->pMe->a.m_pIDisplay, AEE_FONT_NORMAL, szText, -1, 0, y, NULL, IDF_ALIGN_CENTER | IDF_TEXT_TRANSPARENT); 
					y += pthis->pMe->score.m_nStepH + 1;	// 行间距1pixel
				}

				if (y + pthis->pMe->score.m_nStepH > pthis->pMe->screenHeight - 3)
					break;

				nPrinted += nToPrint;
				nToPrint = 0;
			}
		}
		break;
	}

	IDISPLAY_Update(pthis->pMe->a.m_pIDisplay);
}

uint8 MainMenuWnd_QueryTextLineNum(MainMenuWnd* pthis, const AECHAR * pcText, int nChars)
{
	int iLineNum = 0;
	int nPrinted = 0;		// 已经显示完的字符数
	int nToPrint = 0;		// 本次可以显示的字符数
	AECHAR szText[MAX_STRING_SIZE];

	if (nChars < 0)
		nChars = WSTRLEN(pcText);
	

	while (nPrinted < nChars)
	{
		MEMSET(szText, 0, sizeof(AECHAR) * MAX_STRING_SIZE);
		// 计算本行可以显示多少个字符
		do
		{
			// 判断换行符"\"
			if (pcText[nPrinted + nToPrint] == 0x005c)
			{
				nToPrint++;
				break;
			}
			szText[nToPrint] = pcText[nPrinted + nToPrint];
			if (IDISPLAY_MeasureText(pthis->pMe->a.m_pIDisplay, AEE_FONT_NORMAL, szText) < pthis->pMe->screenWidth - 5)
			{
				nToPrint++;
			}
			else
			{
				szText[--nToPrint] = 0;
				break;
			}
		} while(nToPrint < nChars - nPrinted);

		nPrinted += nToPrint;
		nToPrint = 0;
		iLineNum++;
	}

	return iLineNum;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -