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 const uint16_t PerfectScore = 300; // LevelCount * MaxHalfStars
void GameEngine_LoadLevel(GameEngine *pGameEngine, const int8_t level, const bool setB); 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_ToggleSingleLight(GameEngine *pGameEngine, const int8_t x, const int8_t y);
void GameEngine_NewGame(GameEngine *pGameEngine, const bool setB) 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->Level = level;
pGameEngine->SetB = setB; pGameEngine->SetB = setB;
pGameEngine->PreviousLights = pGameEngine->Lights;
pGameEngine->Lights = Levels_GetLightsForLevel(pGameEngine->Level, setB); pGameEngine->Lights = Levels_GetLightsForLevel(pGameEngine->Level, setB);
pGameEngine->Par = Levels_GetParForLevel(pGameEngine->Level); pGameEngine->Par = Levels_GetParForLevel(pGameEngine->Level);
pGameEngine->Moves = 0; pGameEngine->Moves = 0;
@ -66,7 +68,12 @@ bool GameEngine_IsGameOver(const GameEngine *pGameEngine)
uint8_t GameEngine_GetHalfStars(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); 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 targetX = max(0, min(x, PuzzleSize - 1));
int8_t targetY = max(0, min(y, PuzzleSize - 1)); int8_t targetY = max(0, min(y, PuzzleSize - 1));
pGameEngine->PreviousLights = pGameEngine->Lights;
GameEngine_ToggleSingleLight(pGameEngine, targetX, targetY); GameEngine_ToggleSingleLight(pGameEngine, targetX, targetY);
GameEngine_ToggleSingleLight(pGameEngine, targetX + 1, targetY); GameEngine_ToggleSingleLight(pGameEngine, targetX + 1, targetY);
GameEngine_ToggleSingleLight(pGameEngine, targetX, targetY + 1); 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); 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; int8_t Level;
bool SetB; bool SetB;
uint32_t Lights; uint32_t Lights;
uint32_t PreviousLights;
uint16_t Par; uint16_t Par;
uint16_t Moves; uint16_t Moves;
} GameEngine; } 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); 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 #endif

View File

@ -110,8 +110,9 @@ void GameWindow_SetScene(GameWindow *pGameWindow, const SceneId sceneId)
GameEndScene_Init(pGameWindow); GameEndScene_Init(pGameWindow);
break; break;
} }
pGameWindow->CurrentSceneId = sceneId; 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) 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++) for (c = 0; c < PuzzleSize; c++)
{ {
PlayScene_SetLightRect(pGameWindow, &lightRect, c, r); if (fullRefresh || GameEngine_LightChanged(&(pGameWindow->Engine), c, r))
if (GameEngine_GetLight(&(pGameWindow->Engine), c, r))
{ {
// Draw ON light PlayScene_SetLightRect(pGameWindow, &lightRect, c, r);
DrawPicture(pGameWindow->Bitmaps.LightOnPict, &lightRect);
} if (GameEngine_GetLight(&(pGameWindow->Engine), c, r))
else {
{ // Draw ON light
// Draw OFF light DrawPicture(pGameWindow->Bitmaps.LightOnPict, &lightRect);
DrawPicture(pGameWindow->Bitmaps.LightOffPict, &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 HUD
// Draw level // Draw level
MoveTo(pGameWindow->PlayScene.LevelRect.left, pGameWindow->PlayScene.LevelRect.top); if (fullRefresh)
if (pGameWindow->Engine.SetB)
{ {
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 // Draw half-stars
MoveTo(pGameWindow->PlayScene.HalfStarsRect.left, pGameWindow->PlayScene.HalfStarsRect.top); if (fullRefresh || GameEngine_HalfStarsChanged(&(pGameWindow->Engine)))
Bitmaps_DrawHalfStars(&(pGameWindow->Bitmaps), GameEngine_GetHalfStars(&(pGameWindow->Engine)), MaxStars, HalfStarScale); {
MoveTo(pGameWindow->PlayScene.HalfStarsRect.left, pGameWindow->PlayScene.HalfStarsRect.top);
Bitmaps_DrawHalfStars(&(pGameWindow->Bitmaps), GameEngine_GetHalfStars(&(pGameWindow->Engine)), MaxStars, HalfStarScale);
}
// Draw score // Draw score
MoveTo(pGameWindow->PlayScene.ScoreRect.left, pGameWindow->PlayScene.ScoreRect.top); if (fullRefresh)
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), pGameWindow->Engine.Score, ScoreTextScale); {
Bitmaps_DrawSlashChar(&(pGameWindow->Bitmaps), ScoreTextScale); MoveTo(pGameWindow->PlayScene.ScoreRect.left, pGameWindow->PlayScene.ScoreRect.top);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), PerfectScore, ScoreTextScale); Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), pGameWindow->Engine.Score, ScoreTextScale);
Bitmaps_DrawSlashChar(&(pGameWindow->Bitmaps), ScoreTextScale);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), PerfectScore, ScoreTextScale);
}
// Draw retry button // Draw retry button
DrawPicture(pGameWindow->Bitmaps.RetryButtonPict, &(pGameWindow->PlayScene.RetryButtonRect)); if (fullRefresh)
{
DrawPicture(pGameWindow->Bitmaps.RetryButtonPict, &(pGameWindow->PlayScene.RetryButtonRect));
}
// Draw sound button // Draw sound button
MoveTo(pGameWindow->PlayScene.SoundButtonRect.left, pGameWindow->PlayScene.SoundButtonRect.top); MoveTo(pGameWindow->PlayScene.SoundButtonRect.left, pGameWindow->PlayScene.SoundButtonRect.top);