📄 mainmenuwnd.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 + -