📄 menu.cpp
字号:
m_fDestRingAngle2 = fRingAngles2[0];
m_fRingMoveDist2 = (DFLOAT)fabs(m_fDestRingAngle2 - m_fRingAngle2);
m_fDestRingAngle3 = fRingAngles3[0];
m_fRingMoveDist3 = (DFLOAT)fabs(m_fDestRingAngle3 - m_fRingAngle3);
// play the ring rotation sound
m_pClientDE->PlaySoundLocal("sounds/interface/MenuOpen1.wav", NULL, SOUNDPRIORITY_MISC_HIGH);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CMenu::Animate()
//
// PURPOSE: Animates the menu background onto the screen
//
// ----------------------------------------------------------------------- //
DBOOL CMenu::Animate(HSURFACE hScreen)
{
if (!m_pClientDE) return DFALSE;
if (!m_bSlideMenu) return DFALSE;
// get the screen's surface and it's dimensions
// HSURFACE hScreen = m_pClientDE->GetScreenSurface();
DDWORD nScreenWidth = 0;
DDWORD nScreenHeight = 0;
m_pClientDE->GetSurfaceDims (hScreen, &nScreenWidth, &nScreenHeight);
float nDelay = 0.30f;
float nCurrentTime = m_pClientDE->GetTime() - m_nAnimStartTime;
if (nCurrentTime > nDelay) nCurrentTime = nDelay;
float nRatio = nCurrentTime / nDelay;
DFloatPt ptFinal;
ptFinal.x = 266;
HDECOLOR hTrans = m_pClientDE->SetupColor1 ( 0, 0, 0, DFALSE);
m_pClientDE->DrawSurfaceToSurfaceTransparent (hScreen, m_hBackR, NULL, 532 - (int)(ptFinal.x * nRatio), 0, hTrans);
m_pClientDE->DrawSurfaceToSurfaceTransparent (hScreen, m_hBackL, NULL, (int)(ptFinal.x * nRatio) - 266, 0, hTrans);
m_pClientDE->DrawSurfaceToSurfaceTransparent (hScreen, m_hRing1, NULL, (int)(ptFinal.x * nRatio) - 266 + RING_1_X, RING_1_Y, hTrans);
m_pClientDE->DrawSurfaceToSurfaceTransparent (hScreen, m_hRing2, NULL, (int)(ptFinal.x * nRatio) - 266 + RING_2_X, RING_2_Y, hTrans);
m_pClientDE->DrawSurfaceToSurfaceTransparent (hScreen, m_hRing3, NULL, (int)(ptFinal.x * nRatio) - 266 + RING_3_X, RING_3_Y, hTrans);
if (nCurrentTime == nDelay)
{
m_bSlideMenu = DFALSE;
return DFALSE;
}
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CMenu::StartAnimRings()
//
// PURPOSE: Starts the rings rotating to their destination positions()
//
// ----------------------------------------------------------------------- //
void CMenu::StartAnimRings(DBOOL bFast, DFLOAT fRingAngle1, DFLOAT fRingAngle2, DFLOAT fRingAngle3)
{
if (!m_pClientDE) return;
// get the start time for the animation
m_bRotateRings = DTRUE;
// randomize a little
if (GetRandom(0, 1) && fRingAngle1)
fRingAngle1 = (fRingAngle1 < 0) ? fRingAngle1 + PIx2 : fRingAngle1 - PIx2;
if (GetRandom(0, 1) && fRingAngle2)
fRingAngle2 = (fRingAngle2 < 0) ? fRingAngle2 + PIx2 : fRingAngle2 - PIx2;
if (GetRandom(0, 1) && fRingAngle3)
fRingAngle3 = (fRingAngle3 < 0) ? fRingAngle3 + PIx2 : fRingAngle3 - PIx2;
m_fDestRingAngle1 = fRingAngle1;
m_fRingMoveDist1 = (DFLOAT)fabs(m_fDestRingAngle1 - m_fRingAngle1);
m_fDestRingAngle2 = fRingAngle2;
m_fRingMoveDist2 = (DFLOAT)fabs(m_fDestRingAngle2 - m_fRingAngle2);
m_fDestRingAngle3 = fRingAngle3;
m_fRingMoveDist3 = (DFLOAT)fabs(m_fDestRingAngle3 - m_fRingAngle3);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CMenu::AnimateRings()
//
// PURPOSE: Rotates the rings to their correct location
//
// ----------------------------------------------------------------------- //
DBOOL CMenu::AnimateRings()
{
DBOOL bRetVal = DFALSE;
if (!m_pClientDE) return DFALSE;
if (!m_bRotateRings) return DFALSE;
if (m_fRingAngle1 > m_fDestRingAngle1)
{
DFLOAT fSpeed = GetMoveSpeed(m_fDestRingAngle1, m_fRingAngle1, m_fRingMoveDist1);
m_pClientDE->PlaySoundLocal("sounds/interface/MenuChange2.wav", NULL, SOUNDPRIORITY_MISC_HIGH);
m_fRingAngle1 -= fSpeed;
if (m_fRingAngle1 < m_fDestRingAngle1) m_fRingAngle1 = m_fDestRingAngle1;
bRetVal = DTRUE;
}
else if (m_fRingAngle1 < m_fDestRingAngle1)
{
DFLOAT fSpeed = GetMoveSpeed(m_fDestRingAngle1, m_fRingAngle1, m_fRingMoveDist1);
m_pClientDE->PlaySoundLocal("sounds/interface/MenuChange2.wav", NULL, SOUNDPRIORITY_MISC_HIGH);
m_fRingAngle1 += fSpeed;
if (m_fRingAngle1 > m_fDestRingAngle1) m_fRingAngle1 = m_fDestRingAngle1;
bRetVal = DTRUE;
}
if (m_fRingAngle2 > m_fDestRingAngle2)
{
DFLOAT fSpeed = GetMoveSpeed(m_fDestRingAngle2, m_fRingAngle2, m_fRingMoveDist2);
m_pClientDE->PlaySoundLocal("sounds/interface/MenuChange3.wav", NULL, SOUNDPRIORITY_MISC_HIGH);
m_fRingAngle2 -= fSpeed;
if (m_fRingAngle2 < m_fDestRingAngle2) m_fRingAngle2 = m_fDestRingAngle2;
bRetVal = DTRUE;
}
else if (m_fRingAngle2 < m_fDestRingAngle2)
{
DFLOAT fSpeed = GetMoveSpeed(m_fDestRingAngle2, m_fRingAngle2, m_fRingMoveDist2);
m_pClientDE->PlaySoundLocal("sounds/interface/MenuChange3.wav", NULL, SOUNDPRIORITY_MISC_HIGH);
m_fRingAngle2 += fSpeed;
if (m_fRingAngle2 > m_fDestRingAngle2) m_fRingAngle2 = m_fDestRingAngle2;
bRetVal = DTRUE;
}
if (m_fRingAngle3 > m_fDestRingAngle3)
{
DFLOAT fSpeed = GetMoveSpeed(m_fDestRingAngle3, m_fRingAngle3, m_fRingMoveDist3);
m_pClientDE->PlaySoundLocal("sounds/interface/MenuChange1.wav", NULL, SOUNDPRIORITY_MISC_HIGH);
m_fRingAngle3 -= fSpeed;
if (m_fRingAngle3 < m_fDestRingAngle3) m_fRingAngle3 = m_fDestRingAngle3;
bRetVal = DTRUE;
}
else if (m_fRingAngle3 < m_fDestRingAngle3)
{
DFLOAT fSpeed = GetMoveSpeed(m_fDestRingAngle3, m_fRingAngle3, m_fRingMoveDist3);
m_pClientDE->PlaySoundLocal("sounds/interface/MenuChange1.wav", NULL, SOUNDPRIORITY_MISC_HIGH);
m_fRingAngle3 += fSpeed;
if (m_fRingAngle3 > m_fDestRingAngle3) m_fRingAngle3 = m_fDestRingAngle3;
bRetVal = DTRUE;
}
if (!bRetVal)
{
m_bRotateRings = DFALSE;
return DFALSE;
}
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CMenu::Draw()
//
// PURPOSE: Draws the menu to the screen
//
// ----------------------------------------------------------------------- //
void CMenu::Draw()
{
if (!m_pClientDE) return;
char scale = 1;
HSURFACE hScreen = m_pClientDE->GetScreenSurface();
// get the screen's surface and it's dimensions
DDWORD nScreenWidth = 0;
DDWORD nScreenHeight = 0;
m_pClientDE->GetSurfaceDims (m_hMenuScreen, &nScreenWidth, &nScreenHeight);
if (Animate(m_hMenuScreen))
{
return;
}
else
{
// if the dims are 640x480, no stretching is needed
HDECOLOR hTrans;
int nRingMenu = m_pCurrentItem->pTop->nRing;
// if(m_bOptionsOn) { DrawOptions(m_hMenuScreen); return; }
if (!nRingMenu && !AnimateRings())
{
switch(m_pCurrentItem->pTop->nID)
{
case IDS_NEWGAME_EASY:
scale = 0;
DrawNewGameMenu(hScreen);
break;
case ID_SAVEGAME:
scale = 0;
DrawSaveGameMenu(hScreen);
break;
case ID_LOADGAME:
scale = 0;
DrawLoadGameMenu(hScreen);
break;
case ID_BASEWORLD:
scale = 0;
DrawWorldMenu(hScreen);
break;
case ID_BASEOPTION:
scale = 0;
DrawOptions(hScreen);
break;
case ID_BASEHELP:
scale = 0;
DrawHelp(hScreen);
break;
case ID_BASEMULTISETUP:
scale = 0;
DrawMultiSetup(hScreen);
break;
}
}
else if (nRingMenu >= 0 && nRingMenu <= 3)
{
int x;
int y;
// Ring menu, draw the menu items
hTrans = m_pClientDE->SetupColor1 (0.0f, 0.0f, 0.0f, DFALSE);
m_pClientDE->DrawSurfaceToSurface (m_hMenuScreen, m_hBackL, NULL, 0, 0);
m_pClientDE->DrawSurfaceToSurface (m_hMenuScreen, m_hBackR, NULL, 266, 0);
m_pClientDE->DrawSurfaceToSurfaceTransparent (m_hMenuScreen, m_hTitle, NULL, 407, 10, hTrans);
m_pClientDE->TransformSurfaceToSurfaceTransparent (m_hMenuScreen, m_hRing1, NULL, RING_1_X, RING_1_Y, m_fRingAngle1, 1.0f, 1.0f, hTrans);
m_pClientDE->TransformSurfaceToSurfaceTransparent (m_hMenuScreen, m_hRing2, NULL, RING_2_X, RING_2_Y, m_fRingAngle2, 1.0f, 1.0f, hTrans);
m_pClientDE->TransformSurfaceToSurfaceTransparent (m_hMenuScreen, m_hRing3, NULL, RING_3_X, RING_3_Y, m_fRingAngle3, 1.0f, 1.0f, hTrans);
if (!AnimateRings() && nRingMenu != 0)
{
// Hilite the menu title
HSURFACE hMenuTitle = NULL;
switch (nRingMenu)
{
case 1: hMenuTitle = m_hMenuTitle1; break;
case 2: hMenuTitle = m_hMenuTitle2; break;
case 3: hMenuTitle = m_hMenuTitle3; break;
}
x = (int) ptMenuTitlePos[nRingMenu-1].x;
y = (int) ptMenuTitlePos[nRingMenu-1].y;
m_pClientDE->DrawSurfaceToSurfaceTransparent (m_hMenuScreen, hMenuTitle, NULL, x, y, hTrans);
MENUITEM* pItem = m_pCurrentItem->pTop->pPrev;
do
{
// if this is the current selection, draw it as selected
x = (int) ptRingPos[pItem->nRingPos].x;
y = (int) ptRingPos[pItem->nRingPos].y;
if (m_pCurrentItem == pItem)
{
m_pClientDE->DrawSurfaceToSurfaceTransparent (m_hMenuScreen, pItem->hSurfaceHi, NULL, x, y, hTrans);
}
else
{
m_pClientDE->DrawSurfaceToSurfaceTransparent (m_hMenuScreen, pItem->hSurface, NULL, x, y, hTrans);
}
pItem = pItem->pPrev;
} while (pItem != m_pCurrentItem->pTop->pPrev);
}
}
}
if(scale)
{
DDWORD nWidth = 0;
DDWORD nHeight = 0;
m_pClientDE->GetSurfaceDims (hScreen, &nWidth, &nHeight);
DRect rcDst;
rcDst.left = rcDst.top = 0;
rcDst.right = nWidth;
rcDst.bottom = nHeight;
m_pClientDE->GetSurfaceDims (m_hMenuScreen, &nWidth, &nHeight);
DRect rcSrc;
rcSrc.left = rcSrc.top = 0;
rcSrc.right = nWidth;
rcSrc.bottom = nHeight;
m_pClientDE->ScaleSurfaceToSurface (hScreen, m_hMenuScreen, &rcDst, &rcSrc);
}
// Display the version string
if (m_hstrVersion)
{
HDECOLOR white = m_pClientDE->SetupColor1(0.5f, 0.5f, 0.5f, DFALSE);
m_pMenuCursor->SetDest(hScreen);
m_pClientDE->GetSurfaceDims (hScreen, &nScreenWidth, &nScreenHeight);
m_pMenuCursor->SetJustify(CF_JUSTIFY_RIGHT);
int nSpacing = m_pMenuCursor->GetHeight();
m_pMenuCursor->SetLoc((short)nScreenWidth, (short)nScreenHeight - nSpacing);
m_pMenuCursor->DrawSolid(m_pClientDE->GetStringData(m_hstrVersion), white);
}
}
//***************************************************************************
//***** Function: DrawWorldMenu(HSURFACE hScreen)
//***** Details: Draws the custom world selection screen
//***************************************************************************
void CMenu::DrawWorldMenu(HSURFACE hScreen)
{
// MENUITEM *pItem = m_pCurrentItem->pTop->pPrev;
MENUITEM *pItem = m_pCurrentItem->pTop;
HDECOLOR transColor = m_pClientDE->SetupColor1(1.0f, 0.0f, 1.0f, DFALSE);
HDECOLOR white = m_pClientDE->SetupColor1(1.0f, 1.0f, 1.0f, DFALSE);
HDECOLOR red = m_pClientDE->SetupColor2 (0.596f, 0.031f, 0.094f, DFALSE);
HDECOLOR black = m_pClientDE->SetupColor1 (0.0f, 0.0f, 0.0f, DFALSE);
DDWORD nWidth = 0, nHeight = 0;
m_pClientDE->GetSurfaceDims(hScreen, &nWidth, &nHeight);
DFLOAT xRatio = (DFLOAT)nWidth / 640.0f;
DFLOAT yRatio = (DFLOAT)nHeight / 480.0f;
int nSpacing = m_pMenuCursor->GetHeight();
int nCount = 0;
// int y = (int)((MENU_TOP + MENU_HEIGHT - FONT_HEIGHT) * yRatio);
int y = (int)(MENU_TOP * yRatio);
int x = (int)(MENU_LEFT * xRatio);
// Text menu, draw the text items
m_pClientDE->ScaleSurfaceToSurface (hScreen, m_hDimBack, NULL, NULL);
// m_pClientDE->DrawSurfaceToSurface(hScreen, m_hDimBack, NULL, 0, 0);
m_pClientDE->DrawSurfaceToSurfaceTransparent(hScreen, m_hCustomTitle, NULL, (int)(MENU_TITLE_X * xRatio), (int)(MENU_TITLE_Y * yRatio), transColor);
m_pMenuCursor->SetDest(hScreen);
m_pMenuCursor->SetJustify(CF_JUSTIFY_LEFT);
do
{
m_pMenuCursor->SetLoc(x, y);
m_pMenuCursor->DrawSolid(m_pClientDE->GetStringData(pItem->hString), 3, 3, black);
if(m_pCurrentItem == pItem)
m_pMenuCursor->DrawSolid(m_pClientDE->GetStringData(pItem->hString), red);
else
m_pMenuCursor->DrawSolid(m_pClientDE->GetStringData(pItem->hString), white);
y += nSpacing;
if (y > (int)((MENU_TOP + MENU_HEIGHT - FONT_HEIGHT) * yRatio))
{
y = (int)(MENU_TOP * yRatio);
x += 200;
}
pItem = pItem->pNext;
} while (pItem != m_pCurrentItem->pTop);
}
//***************************************************************************
//***** Function: DrawNewGameMenu(HSURFACE hScreen)
//***** Details: Draws the new game difficulty level screen
//***************************************************************************
void CMenu::DrawNewGameMenu(HSURFACE hScreen)
{
MENUITEM *pItem = m_pCurrentItem->pTop->pPrev;
HDECOLOR transColor = m_pClientDE->SetupColor1(1.0f, 0.0f, 1.0f, DFALSE);
HDECOLOR white = m_pClientDE->SetupColor1(1.0f, 1.0f, 1.0f, DFALSE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -