Removed unnecessary drawing for massive performance boost

This commit is contained in:
Jon Thysell 2021-11-23 10:34:18 -08:00
parent 95dba45a0e
commit 2d5d39874a
6 changed files with 73 additions and 27 deletions

View File

@ -13,6 +13,7 @@ const uint8_t MinHalfStars = 1;
const uint16_t PerfectScore = 300; // LevelCount * MaxHalfStars
void GameEngine_LoadLevel(GameEngine *pGameEngine, const int8_t level, const bool setB);
uint8_t GameEngine_CalculateHalfStars(const uint16_t par, const uint16_t moves);
void GameEngine_ToggleSingleLight(GameEngine *pGameEngine, const int8_t x, const int8_t y);
void GameEngine_NewGame(GameEngine *pGameEngine, const bool setB)
@ -39,6 +40,7 @@ void GameEngine_LoadLevel(GameEngine *pGameEngine, const int8_t level, const boo
{
pGameEngine->Level = level;
pGameEngine->SetB = setB;
pGameEngine->PreviousLights = pGameEngine->Lights;
pGameEngine->Lights = Levels_GetLightsForLevel(pGameEngine->Level, setB);
pGameEngine->Par = Levels_GetParForLevel(pGameEngine->Level);
pGameEngine->Moves = 0;
@ -66,7 +68,12 @@ bool GameEngine_IsGameOver(const GameEngine *pGameEngine)
uint8_t GameEngine_GetHalfStars(const GameEngine *pGameEngine)
{
uint8_t halfStarsLost = pGameEngine->Moves <= pGameEngine->Par ? 0 : max(0, (1 + pGameEngine->Moves - pGameEngine->Par) / 2);
return GameEngine_CalculateHalfStars(pGameEngine->Par, pGameEngine->Moves);
}
uint8_t GameEngine_CalculateHalfStars(const uint16_t par, const uint16_t moves)
{
uint8_t halfStarsLost = moves <= par ? 0 : max(0, (1 + moves - par) / 2);
return max(MinHalfStars, MaxHalfStars - halfStarsLost);
}
@ -75,6 +82,8 @@ void GameEngine_ToggleLights(GameEngine *pGameEngine, const int8_t x, const int8
int8_t targetX = max(0, min(x, PuzzleSize - 1));
int8_t targetY = max(0, min(y, PuzzleSize - 1));
pGameEngine->PreviousLights = pGameEngine->Lights;
GameEngine_ToggleSingleLight(pGameEngine, targetX, targetY);
GameEngine_ToggleSingleLight(pGameEngine, targetX + 1, targetY);
GameEngine_ToggleSingleLight(pGameEngine, targetX, targetY + 1);
@ -91,3 +100,19 @@ void GameEngine_ToggleSingleLight(GameEngine *pGameEngine, const int8_t x, const
bitToggle(pGameEngine->Lights, y * PuzzleSize + x);
}
}
bool GameEngine_LightChanged(const GameEngine *pGameEngine, const int8_t x, const int8_t y)
{
if (x >= 0 && x < PuzzleSize && y >= 0 && y < PuzzleSize)
{
return bitRead(pGameEngine->Lights, y * PuzzleSize + x) != bitRead(pGameEngine->PreviousLights, y * PuzzleSize + x);
}
return false;
}
bool GameEngine_HalfStarsChanged(const GameEngine *pGameEngine)
{
return pGameEngine->Moves == 0 ||
GameEngine_CalculateHalfStars(pGameEngine->Par, pGameEngine->Moves - 1) != GameEngine_GetHalfStars(pGameEngine);
}

View File

@ -20,6 +20,7 @@ typedef struct GameEngine
int8_t Level;
bool SetB;
uint32_t Lights;
uint32_t PreviousLights;
uint16_t Par;
uint16_t Moves;
} GameEngine;
@ -40,4 +41,8 @@ uint8_t GameEngine_GetHalfStars(const GameEngine *pGameEngine);
void GameEngine_ToggleLights(GameEngine *pGameEngine, const int8_t x, const int8_t y);
bool GameEngine_LightChanged(const GameEngine *pGameEngine, const int8_t x, const int8_t y);
bool GameEngine_HalfStarsChanged(const GameEngine *pGameEngine);
#endif

View File

@ -110,8 +110,9 @@ void GameWindow_SetScene(GameWindow *pGameWindow, const SceneId sceneId)
GameEndScene_Init(pGameWindow);
break;
}
pGameWindow->CurrentSceneId = sceneId;
GameWindow_Draw(pGameWindow, true);
GameWindow_Draw(pGameWindow, true); // Always force a full refresh when changing scenes
}
void GameWindow_Show(const GameWindow *pGameWindow)

Binary file not shown.

Binary file not shown.

View File

@ -98,17 +98,20 @@ void PlayScene_Draw(const GameWindow *pGameWindow, bool fullRefresh)
{
for (c = 0; c < PuzzleSize; c++)
{
PlayScene_SetLightRect(pGameWindow, &lightRect, c, r);
if (GameEngine_GetLight(&(pGameWindow->Engine), c, r))
if (fullRefresh || GameEngine_LightChanged(&(pGameWindow->Engine), c, r))
{
// Draw ON light
DrawPicture(pGameWindow->Bitmaps.LightOnPict, &lightRect);
}
else
{
// Draw OFF light
DrawPicture(pGameWindow->Bitmaps.LightOffPict, &lightRect);
PlayScene_SetLightRect(pGameWindow, &lightRect, c, r);
if (GameEngine_GetLight(&(pGameWindow->Engine), c, r))
{
// Draw ON light
DrawPicture(pGameWindow->Bitmaps.LightOnPict, &lightRect);
}
else
{
// Draw OFF light
DrawPicture(pGameWindow->Bitmaps.LightOffPict, &lightRect);
}
}
}
}
@ -116,29 +119,41 @@ void PlayScene_Draw(const GameWindow *pGameWindow, bool fullRefresh)
// Draw HUD
// Draw level
MoveTo(pGameWindow->PlayScene.LevelRect.left, pGameWindow->PlayScene.LevelRect.top);
if (pGameWindow->Engine.SetB)
if (fullRefresh)
{
Bitmaps_DrawBChar(&(pGameWindow->Bitmaps), LevelTextScale);
MoveTo(pGameWindow->PlayScene.LevelRect.left, pGameWindow->PlayScene.LevelRect.top);
if (pGameWindow->Engine.SetB)
{
Bitmaps_DrawBChar(&(pGameWindow->Bitmaps), LevelTextScale);
}
else
{
Bitmaps_DrawAChar(&(pGameWindow->Bitmaps), LevelTextScale);
}
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), 1 + pGameWindow->Engine.Level, LevelTextScale);
}
else
{
Bitmaps_DrawAChar(&(pGameWindow->Bitmaps), LevelTextScale);
}
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), 1 + pGameWindow->Engine.Level, LevelTextScale);
// Draw half-stars
MoveTo(pGameWindow->PlayScene.HalfStarsRect.left, pGameWindow->PlayScene.HalfStarsRect.top);
Bitmaps_DrawHalfStars(&(pGameWindow->Bitmaps), GameEngine_GetHalfStars(&(pGameWindow->Engine)), MaxStars, HalfStarScale);
if (fullRefresh || GameEngine_HalfStarsChanged(&(pGameWindow->Engine)))
{
MoveTo(pGameWindow->PlayScene.HalfStarsRect.left, pGameWindow->PlayScene.HalfStarsRect.top);
Bitmaps_DrawHalfStars(&(pGameWindow->Bitmaps), GameEngine_GetHalfStars(&(pGameWindow->Engine)), MaxStars, HalfStarScale);
}
// Draw score
MoveTo(pGameWindow->PlayScene.ScoreRect.left, pGameWindow->PlayScene.ScoreRect.top);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), pGameWindow->Engine.Score, ScoreTextScale);
Bitmaps_DrawSlashChar(&(pGameWindow->Bitmaps), ScoreTextScale);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), PerfectScore, ScoreTextScale);
if (fullRefresh)
{
MoveTo(pGameWindow->PlayScene.ScoreRect.left, pGameWindow->PlayScene.ScoreRect.top);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), pGameWindow->Engine.Score, ScoreTextScale);
Bitmaps_DrawSlashChar(&(pGameWindow->Bitmaps), ScoreTextScale);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), PerfectScore, ScoreTextScale);
}
// Draw retry button
DrawPicture(pGameWindow->Bitmaps.RetryButtonPict, &(pGameWindow->PlayScene.RetryButtonRect));
if (fullRefresh)
{
DrawPicture(pGameWindow->Bitmaps.RetryButtonPict, &(pGameWindow->PlayScene.RetryButtonRect));
}
// Draw sound button
MoveTo(pGameWindow->PlayScene.SoundButtonRect.left, pGameWindow->PlayScene.SoundButtonRect.top);