📄 game.cpp
字号:
boolean CGame::KeyReleaseEvent(uint16 wParam)
{
switch(wParam)
{
case AVK_SELECT:
m_kSELECT = false;
return TRUE;
case AVK_LEFT:
m_kLEFT = false;
return TRUE;
case AVK_RIGHT:
m_kRIGHT = false;
return TRUE;
case AVK_UP:
m_kUP = false;
return TRUE;
case AVK_DOWN:
m_kDOWN = false;
return TRUE;
case AVK_1:
return TRUE;
case AVK_2:
m_k2 = false;
return TRUE;
case AVK_3:
return TRUE;
case AVK_4:
m_k4 = false;
return TRUE;
case AVK_5:
return TRUE;
case AVK_6:
m_k6 = false;
return TRUE;
case AVK_7:
return TRUE;
case AVK_8:
m_k8 = false;
return TRUE;
case AVK_9:
return TRUE;
case AVK_STAR:
return TRUE;
case AVK_0:
return TRUE;
case AVK_POUND:
return TRUE;
case AVK_CLR:
m_kCLEAR = false;
return TRUE;
}
return TRUE;
}
// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
void CGame::NextFrame(CGame* pGame)
{
IDISPLAY_Backlight(pGame->m_applet.m_pIDisplay, TRUE);
// ----------------------------------------------------------------------------------
pGame->RenderFrame();
// ----------------------------------------------------------------------------------
ISHELL_SetTimer(pGame->m_applet.m_pIShell, 33, (PFNNOTIFY)NextFrame, (void *)pGame);
}
// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
void CGame::RenderFrame()
{
// -----------------------------------------------------------------------------------------
// clear everything
// -----------------------------------------------------------------------------------------
#if 1
glClearColorx(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
#else
glClear(GL_DEPTH_BUFFER_BIT);
#endif
switch(m_jGameStatus)
{
case STATUS_START:
{
RenderStart();
break;
}
case STATUS_LOADING:
{
if (!LoadResources()) ISHELL_CloseApplet(m_applet.m_pIShell, 0);
m_dwFrame = 0;
m_jGameStatus = STATUS_MENU;
break;
}
case STATUS_MENU:
{
m_dwFrame = 0;
m_jGameStatus = STATUS_HELP;
break;
}
case STATUS_HELP:
{
RenderHelp();
break;
}
case STATUS_PLAYING:
{
RenderPlaying();
break;
}
}
// -----------------------------------------------------------------------------------------
//
// swap buffers and update screen
m_pEngine->SwapBuffers();
IDISPLAY_Update(m_applet.m_pIDisplay);
//
// -----------------------------------------------------------------------------------------
}
// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
void CGame::RenderStart()
{
if (m_dwFrame == 0)
{
if (m_kCLEAR || m_kSELECT) return;
// load 8x13 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ font sprite
m_pSpr8x13 = new CSprite(m_pEngine);
m_pSpr8x13->LoadFromVfs("game.dat", "font_8x13.bmp");
int16 jFrm8x13[58*6];
int yy, pp=0, f8x13offx=0;
for (yy=0; yy<58; yy++)
{
jFrm8x13[pp++] = f8x13offx;
jFrm8x13[pp++] = 0;
jFrm8x13[pp++] = 0;
jFrm8x13[pp++] = 0;
jFrm8x13[pp++] = 8;
jFrm8x13[pp++] = 13;
f8x13offx += 8;
}
m_pSpr8x13->Config(58, jFrm8x13);
}
if (m_dwFrame)
{
m_pSpr8x13->DrawText32To90((m_pEngine->ScreenWidth()-88)>>1, (m_pEngine->ScreenHeight()-13)>>1, "- LOADING -");
m_jGameStatus = STATUS_LOADING;
}
m_dwFrame++;
}
// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
void CGame::RenderHelp()
{
if (m_dwFrame == 0)
{
if (m_kCLEAR || m_kSELECT) return;
m_pScene->AddItem(m_pScene->Root(), m_pHelp);
m_pHelp->TranslateTo(0, 0, 0);
m_pHelp->UpdateDirection();
m_pCam->TranslateTo(0,0,ITOX(35));
m_pCam->RotateTo(0,0,0);
m_pCam->UpdateDirection();
}
else
{
if (m_kCLEAR)
{
ISHELL_CloseApplet(m_applet.m_pIShell, 0);
return;
}
if (m_kSELECT || m_kUP || m_kDOWN || m_kLEFT || m_kRIGHT)
{
m_dwFrame = 0;
m_dwAddSecs = 0;
m_pScene->RemoveItem(m_pHelp);
m_pScene->AddItem(m_pScene->Root(), m_pEarth);
m_pScene->AddItem(m_pScene->Root(), m_pSun);
m_pScene->AddItem(m_pScene->Root(), m_pMoon);
m_jGameStatus = STATUS_PLAYING;
}
m_pHelp->TranslateTo(0, 9 * FPsin[(m_dwFrame)%359], 0);
m_pScene->Render(m_pScene->Root(), m_pCam);
}
m_dwFrame++;
}
// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
void CGame::RenderPlaying()
{
if (m_kCLEAR)
{
m_dwFrame = 0;
m_pScene->RemoveItem(m_pEarth);
m_pScene->RemoveItem(m_pSun);
m_pScene->RemoveItem(m_pMoon);
m_jGameStatus = STATUS_MENU;
return;
}
#if MESH_SUN
// simple rotate sun
m_pSun->AddRotation(ITOX(3),ITOX(4),ITOX(1));
#else
// make sun face the camera
// ### dont be lazy... do it the right way...
m_pSun->RotateTo(-m_pCam->Rotation()[0], m_pCam->Rotation()[1]+ITOX(180), m_pCam->Rotation()[2]);
#endif
// -----------------------------------------------------------------------------------------
// update local and utc times
// -----------------------------------------------------------------------------------------
TimeUpdate();
// -----------------------------------------------------------------------------------------
// update earth orbit around sun
// -----------------------------------------------------------------------------------------
EarthUpdate();
// -----------------------------------------------------------------------------------------
// do a step of sunlight raytracing
// -----------------------------------------------------------------------------------------
RayTrace();
// -----------------------------------------------------------------------------------------
// update cam position and orientation
// -----------------------------------------------------------------------------------------
#define ORBITING_CAMERA 1
#if ORBITING_CAMERA
if (m_kLEFT) m_iCamLongitude += ITOX(3);
if (m_kRIGHT) m_iCamLongitude -= ITOX(3);
if (m_iCamLongitude > ITOX(180)) m_iCamLongitude -= ITOX(360);
if (m_iCamLongitude < -180) m_iCamLongitude += ITOX(360);
if (m_kUP) m_iCamLatitude += ITOX(2);
if (m_kDOWN) m_iCamLatitude -= ITOX(2);
#define LAT_LIMIT ITOX(75)
if (m_iCamLatitude >= LAT_LIMIT) m_iCamLatitude = LAT_LIMIT;
if (m_iCamLatitude < -LAT_LIMIT) m_iCamLatitude = -LAT_LIMIT;
if (m_k2)
if (m_iCamDistance > ITOX(25)) m_iCamDistance -= ITOX(3);
if (m_k8)
if (m_iCamDistance < ITOX(250)) m_iCamDistance += ITOX(3);
// keep within FP sin/cos table ranges (0..359)
int iAngLon = m_iCamLongitude;
int iAngLat = m_iCamLatitude;
if (iAngLon < 0) iAngLon += ITOX(360);
if (iAngLon >= ITOX(360)) iAngLon -= ITOX(360);
if (iAngLat < 0) iAngLat += ITOX(360);
if (iAngLat >= ITOX(360)) iAngLat -= ITOX(360);
// longitude
matrix_t mRotLat, mRotLon, mRotFinal;
vec3_t vTmpOrbitPos = { 0, 0, m_iCamDistance };
mRotLat = RXMatrix(iAngLat);
mRotLon = RYMatrix(iAngLon);
mRotFinal = MatrixMultiply(mRotLat, mRotLon);
MatrixMultiplyVector(mRotFinal, vTmpOrbitPos, m_pCam->Position());
// decide what the cam is chasing
switch (m_jChase)
{
case CHASE_EARTH:
{
// chasing earth
VectorAdd(m_pCam->Position(), m_pEarth->Position(), m_pCam->Position());
break;
}
case CHASE_SUN:
{
// chasing sun
VectorAdd(m_pCam->Position(), m_pSun->Position(), m_pCam->Position());
break;
}
case CHASE_MOON:
{
// chasing moon
VectorAdd(m_pCam->Position(), m_pMoon->Position(), m_pCam->Position());
break;
}
}
// -----------------------------------------------------------------------------------------
// calculate camera orientation to face earth
// -----------------------------------------------------------------------------------------
m_pCam->RotateTo(iAngLat, -iAngLon, 0);
m_pCam->UpdateDirection();
#else
// -----------------------------------------------------------------------------------------
// just walk around
// -----------------------------------------------------------------------------------------
if (m_kLEFT) m_pCam->AddRotation(0, ITOX(3), 0);
if (m_kRIGHT) m_pCam->AddRotation(0, ITOX(-3), 0);
m_pCam->UpdateDirection();
if (m_kUP) m_pCam->AddTranslation(m_pCam->m_Direction[0], -m_pCam->m_Direction[1], -m_pCam->m_Direction[2]);
if (m_kDOWN) m_pCam->AddTranslation(-m_pCam->m_Direction[0], m_pCam->m_Direction[1], m_pCam->m_Direction[2]);
#endif
// -----------------------------------------------------------------------------------------
// render simplistic demo scene
// -----------------------------------------------------------------------------------------
m_pScene->Render(m_pScene->Root(), m_pCam);
//
// show local time
//
char szText[7];
SPRINTF(szText, "%02u:%02u - %02u/%02u", m_LocalDate.wHour, m_LocalDate.wMinute, m_LocalDate.wDay, m_LocalDate.wMonth);
// 13 chars 8 pixels wide = 104 pixels
m_pSpr8x13->DrawText32To90((m_pEngine->ScreenWidth() - 104)>>1, m_pEngine->ScreenHeight() - 13, szText);
}
// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
void CGame::EarthUpdate(void)
{
// -------------------------------------------------------------------------------------------
// fEarthOrbit
// The earth orbit rotation around the sun (in radians).
// This will put the world approximately where it should be on its orbit,
// given the day number plus time of the current year.
//
// In WorldMap:
// 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -