From c7958c23bce4a8f1f235273c01a592ab30816c2b Mon Sep 17 00:00:00 2001 From: Jon Thysell Date: Mon, 8 Nov 2021 14:47:31 -0800 Subject: [PATCH] Imported more image assets, updated scenes --- img/next.gif | Bin 0 -> 86 bytes img/retry.gif | Bin 0 -> 82 bytes img/sound0.gif | Bin 0 -> 62 bytes img/sound1.gif | Bin 0 -> 64 bytes img/star0.gif | Bin 0 -> 71 bytes img/star1.gif | Bin 0 -> 74 bytes img/star2.gif | Bin 0 -> 68 bytes src/Bitmaps.c | 113 +++++++++++++++++++++++++++++++++++------- src/Bitmaps.h | 13 ++++- src/GameEndScene.c | 58 ++++++++++++++++------ src/GameWindow.c | 31 +++++------- src/GameWindow.h | 1 - src/LevelEndScene.c | 89 +++++++++++++++++++++++++-------- src/MacCommon.c | 96 +++++++++++++++++++++-------------- src/MacCommon.h | 3 ++ src/MacLO.pi.bin | Bin 15872 -> 15872 bytes src/MacLO.pi.rsrc.bin | Bin 10752 -> 12032 bytes src/PlayScene.c | 81 +++++++++++++++++++++++------- src/Scenes.h | 12 ++++- src/TitleScene.c | 7 +-- 20 files changed, 365 insertions(+), 139 deletions(-) create mode 100644 img/next.gif create mode 100644 img/retry.gif create mode 100644 img/sound0.gif create mode 100644 img/sound1.gif create mode 100644 img/star0.gif create mode 100644 img/star1.gif create mode 100644 img/star2.gif diff --git a/img/next.gif b/img/next.gif new file mode 100644 index 0000000000000000000000000000000000000000..bb8ff1485dc73212c15d7c0bf1a28a70e505af85 GIT binary patch literal 86 zcmZ?wbhEHb6kysyZrK=#-@P?#Slo e#x4)PC+dsltZI}#7BnyGpk&JmZ@cczcYa-A I5n-?f0IgIN!~g&Q literal 0 HcmV?d00001 diff --git a/img/star0.gif b/img/star0.gif new file mode 100644 index 0000000000000000000000000000000000000000..f4d04d0521e3d0602c9e0a2500392bfe9c42b70f GIT binary patch literal 71 zcmZ?wbh9u|6krfwXkcUjg8%>j>wsvG2m_N^3%}rr9XD@PUko@grL5|1R_y|IxhXGF WrgkKyRUR#zamX!5RSd)EHC% literal 0 HcmV?d00001 diff --git a/img/star1.gif b/img/star1.gif new file mode 100644 index 0000000000000000000000000000000000000000..8f5413145eb42597cdae93cfa88de91ab9056563 GIT binary patch literal 74 zcmZ?wbh9u|6krfwXkcUjg8%>j>wsvG2m_O53%}rr6*q51f7I~0yEje$yypXD)r6as ZKGWLfzHqv=?cA2sj>wsvG2m_OH3%}rr6}N6hfAl%At}gTU{!#_Cx|x+# Tnpr&|)(7XfUdk60Wv~VSrh*pe literal 0 HcmV?d00001 diff --git a/src/Bitmaps.c b/src/Bitmaps.c index c1f8256..68b099e 100644 --- a/src/Bitmaps.c +++ b/src/Bitmaps.c @@ -5,11 +5,14 @@ #define TitlePictResID BaseResID #define NumCharPictBaseResID (TitlePictResID + 1) -#define ACharPictResID (NumCharPictBaseResID + NumChars) +#define ACharPictResID (NumCharPictBaseResID + NumCharPictCount) #define BCharPictResID (ACharPictResID + 1) #define SlashCharPictResID (BCharPictResID + 1) +#define StarPictBaseResID (SlashCharPictResID + 1) +#define NextButtonPictResID (StarPictBaseResID + StarPictCount) +#define RetryButtonPictResID (NextButtonPictResID + 1) -void Bitmaps_DrawScaledPic(const PicHandle pic, const uint8_t scale); +#define StarRectPadding 2 void Bitmaps_Init(Bitmaps *pBitmaps) { @@ -23,7 +26,7 @@ void Bitmaps_Init(Bitmaps *pBitmaps) } // Load number chars - for (i = 0; i < NumChars; i++) + for (i = 0; i < NumCharPictCount; i++) { pBitmaps->NumCharPicts[i] = GetPicture(NumCharPictBaseResID + i); if (pBitmaps->NumCharPicts[i] == nil) @@ -52,20 +55,37 @@ void Bitmaps_Init(Bitmaps *pBitmaps) { ShowError("\pSlash char PICT resource missing!", true); } -} - -void Bitmaps_DrawScaledPic(const PicHandle pic, const uint8_t scale) -{ - Point penPosition; - Rect destRect; - GetPen(&penPosition); - GetScaledPicFrame(pic, scale, &destRect); + // Load half-stars + for (i = 0; i < StarPictCount; i++) + { + pBitmaps->StarPicts[i] = GetPicture(StarPictBaseResID + i); + if (pBitmaps->StarPicts[i] == nil) + { + ShowError("\pStar PICT resource missing!", true); + } + } - OffsetRect(&destRect, penPosition.h, penPosition.v); + // Load next button + pBitmaps->SlashCharPict = GetPicture(SlashCharPictResID); + if (pBitmaps->SlashCharPict == nil) + { + ShowError("\pSlash char PICT resource missing!", true); + } - DrawPicture(pic, &destRect); - MoveTo(destRect.right, destRect.top); + // Load next button + pBitmaps->NextButtonPict = GetPicture(NextButtonPictResID); + if (pBitmaps->NextButtonPict == nil) + { + ShowError("\pNext button PICT resource missing!", true); + } + + // Load retry button + pBitmaps->RetryButtonPict = GetPicture(RetryButtonPictResID); + if (pBitmaps->RetryButtonPict == nil) + { + ShowError("\pRetry button PICT resource missing!", true); + } } void Bitmaps_GetNumberRect(const Bitmaps *pBitmaps, const uint32_t number, const uint8_t scale, Rect *pDestRect) @@ -110,7 +130,7 @@ void Bitmaps_DrawNumber(const Bitmaps *pBitmaps, const uint32_t number, const ui if (number == 0) { - Bitmaps_DrawScaledPic(pBitmaps->NumCharPicts[0], scale); + DrawScaledPic(pBitmaps->NumCharPicts[0], scale); return; } @@ -124,7 +144,7 @@ void Bitmaps_DrawNumber(const Bitmaps *pBitmaps, const uint32_t number, const ui if (started || (digit > 0 && digit < 10)) { - Bitmaps_DrawScaledPic(pBitmaps->NumCharPicts[digit], scale); + DrawScaledPic(pBitmaps->NumCharPicts[digit], scale); started = true; } } @@ -132,15 +152,70 @@ void Bitmaps_DrawNumber(const Bitmaps *pBitmaps, const uint32_t number, const ui void Bitmaps_DrawAChar(const Bitmaps *pBitmaps, const uint8_t scale) { - Bitmaps_DrawScaledPic(pBitmaps->ACharPict, scale); + DrawScaledPic(pBitmaps->ACharPict, scale); } void Bitmaps_DrawBChar(const Bitmaps *pBitmaps, const uint8_t scale) { - Bitmaps_DrawScaledPic(pBitmaps->BCharPict, scale); + DrawScaledPic(pBitmaps->BCharPict, scale); } void Bitmaps_DrawSlashChar(const Bitmaps *pBitmaps, const uint8_t scale) { - Bitmaps_DrawScaledPic(pBitmaps->SlashCharPict, scale); + DrawScaledPic(pBitmaps->SlashCharPict, scale); +} + +void Bitmaps_GetHalfStarsRect(const Bitmaps *pBitmaps, const uint8_t halfStars, const uint8_t maxStars, const uint8_t scale, Rect *pDestRect) +{ + uint8_t stars; + Rect starRect, paddingRect; + + pDestRect->top = 0; + pDestRect->left = 0; + pDestRect->bottom = 0; + pDestRect->right = 0; + + if (maxStars == 0) + { + return; + } + + GetScaledPicFrame(pBitmaps->StarPicts[0], scale, &starRect); + paddingRect = starRect; + paddingRect.right = paddingRect.left + (StarRectPadding * scale); + + ConcatenateRect(pDestRect, &starRect, pDestRect); + + for (stars = 1; stars < maxStars; stars++) + { + ConcatenateRect(pDestRect, &paddingRect, pDestRect); + ConcatenateRect(pDestRect, &starRect, pDestRect); + } +} + +void Bitmaps_DrawHalfStars(const Bitmaps *pBitmaps, const uint8_t halfStars, const uint8_t maxStars, const uint8_t scale) +{ + Point penPosition; + uint8_t i, progress, drawn; + + progress = halfStars; + drawn = 0; + + for (i = StarPictCount - 1; i > 0; i--) + { + while (drawn < maxStars && progress >= i) + { + DrawScaledPic(pBitmaps->StarPicts[i], scale); + GetPen(&penPosition); + MoveTo(penPosition.h + (StarRectPadding * scale), penPosition.v); + progress -= i; + drawn++; + } + } + + for (; drawn < maxStars; drawn++) + { + DrawScaledPic(pBitmaps->StarPicts[0], scale); + MoveTo(penPosition.h + (StarRectPadding * scale), penPosition.v); + } } diff --git a/src/Bitmaps.h b/src/Bitmaps.h index bb8e0e5..408a27f 100644 --- a/src/Bitmaps.h +++ b/src/Bitmaps.h @@ -6,15 +6,21 @@ #include "MacCommon.h" -#define NumChars 10 +#define NumCharPictCount 10 +#define StarPictCount 3 typedef struct sBitmaps { PicHandle TitlePict; - PicHandle NumCharPicts[NumChars]; + PicHandle NumCharPicts[NumCharPictCount]; PicHandle ACharPict; PicHandle BCharPict; PicHandle SlashCharPict; + PicHandle StarPicts[StarPictCount]; + PicHandle NextButtonPict; + PicHandle RetryButtonPict; + PicHandle SoundOffPict; + PicHandle SoundOnPict; } Bitmaps; void Bitmaps_Init(Bitmaps *pBitmaps); @@ -26,4 +32,7 @@ void Bitmaps_DrawAChar(const Bitmaps *pBitmaps, const uint8_t scale); void Bitmaps_DrawBChar(const Bitmaps *pBitmaps, const uint8_t scale); void Bitmaps_DrawSlashChar(const Bitmaps *pBitmaps, const uint8_t scale); +void Bitmaps_GetHalfStarsRect(const Bitmaps *pBitmaps, const uint8_t halfStars, const uint8_t maxStars, const uint8_t scale, Rect *pDestRect); +void Bitmaps_DrawHalfStars(const Bitmaps *pBitmaps, const uint8_t halfStars, const uint8_t maxStars, const uint8_t scale); + #endif diff --git a/src/GameEndScene.c b/src/GameEndScene.c index d596cab..02ca7d6 100644 --- a/src/GameEndScene.c +++ b/src/GameEndScene.c @@ -3,32 +3,60 @@ #include "GameEndScene.h" +#define SetTextScale 6 +#define ScoreTextScale 3 + void GameEndScene_Init(GameWindow *pGameWindow) { + Rect r; + + const Rect *pContentRect = &(pGameWindow->Window->portRect); + + // Setup set + GetScaledPicFrame(pGameWindow->Bitmaps.StarPicts[StarPictCount - 1], SetTextScale, &r); + GetScaledPicFrame(pGameWindow->Engine.SetB ? pGameWindow->Bitmaps.BCharPict : pGameWindow->Bitmaps.ACharPict, SetTextScale, &(pGameWindow->GameEndScene.SetRect)); + ConcatenateRect(&r, &(pGameWindow->GameEndScene.SetRect), &(pGameWindow->GameEndScene.SetRect)); + ConcatenateRect(&(pGameWindow->GameEndScene.SetRect), &r, &(pGameWindow->GameEndScene.SetRect)); + + GetBoxRect(pContentRect, Top, &r); + GetBoxRect(&r, Bottom, &r); + CenterRect(&r, &(pGameWindow->GameEndScene.SetRect)); + + // Setup score + Bitmaps_GetNumberRect(&(pGameWindow->Bitmaps), pGameWindow->Engine.Score, ScoreTextScale, &(pGameWindow->GameEndScene.ScoreRect)); + GetScaledPicFrame(pGameWindow->Bitmaps.SlashCharPict, ScoreTextScale, &r); + ConcatenateRect(&(pGameWindow->GameEndScene.ScoreRect), &r, &(pGameWindow->GameEndScene.ScoreRect)); + Bitmaps_GetNumberRect(&(pGameWindow->Bitmaps), PerfectScore, ScoreTextScale, &r); + ConcatenateRect(&(pGameWindow->GameEndScene.ScoreRect), &r, &(pGameWindow->GameEndScene.ScoreRect)); + + GetBoxRect(pContentRect, Bottom, &r); + GetBoxRect(&r, Top, &r); + CenterRect(&r, &(pGameWindow->GameEndScene.ScoreRect)); } void GameEndScene_Draw(const GameWindow *pGameWindow, bool fullRefresh) { - Str255 scoreStr; - - // TODO: Proper level end - if (fullRefresh) + // Draw set + MoveTo(pGameWindow->GameEndScene.SetRect.left, pGameWindow->GameEndScene.SetRect.top); + DrawScaledPic(pGameWindow->Bitmaps.StarPicts[StarPictCount - 1], SetTextScale); + if (pGameWindow->Engine.SetB) { + Bitmaps_DrawBChar(&(pGameWindow->Bitmaps), SetTextScale); } + else + { + Bitmaps_DrawAChar(&(pGameWindow->Bitmaps), SetTextScale); + } + DrawScaledPic(pGameWindow->Bitmaps.StarPicts[StarPictCount - 1], SetTextScale); - MoveTo(100, 100); - DrawString("\pGame complete! Click to continue."); - - MoveTo(100, 125); - DrawString("\pScore: "); - NumToString((int32_t)(pGameWindow->Engine.Score), &scoreStr); - DrawString(scoreStr); - DrawString("\p/300"); + // Draw score + MoveTo(pGameWindow->GameEndScene.ScoreRect.left, pGameWindow->GameEndScene.ScoreRect.top); + Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), pGameWindow->Engine.Score, ScoreTextScale); + Bitmaps_DrawSlashChar(&(pGameWindow->Bitmaps), ScoreTextScale); + Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), PerfectScore, ScoreTextScale); } void GameEndScene_Click(GameWindow *pGameWindow, const Point *pPosition) { - // TODO: Proper click handling - - GameWindow_SetScene(pGameWindow, Title); + // Do nothing } diff --git a/src/GameWindow.c b/src/GameWindow.c index 98d7380..235306f 100644 --- a/src/GameWindow.c +++ b/src/GameWindow.c @@ -77,25 +77,20 @@ void GameWindow_Click(GameWindow *pGameWindow, const Point *pPosition) void GameWindow_SetScene(GameWindow *pGameWindow, const SceneId sceneId) { - GameWindow_Draw(pGameWindow, false); - if (!(pGameWindow->SceneIsInitialized[sceneId])) + switch (sceneId) { - switch (sceneId) - { - case Title: - TitleScene_Init(pGameWindow); - break; - case Play: - PlayScene_Init(pGameWindow); - break; - case LevelEnd: - LevelEndScene_Init(pGameWindow); - break; - case GameEnd: - GameEndScene_Init(pGameWindow); - break; - } - pGameWindow->SceneIsInitialized[sceneId] = true; + case Title: + TitleScene_Init(pGameWindow); + break; + case Play: + PlayScene_Init(pGameWindow); + break; + case LevelEnd: + LevelEndScene_Init(pGameWindow); + break; + case GameEnd: + GameEndScene_Init(pGameWindow); + break; } pGameWindow->CurrentSceneId = sceneId; GameWindow_Draw(pGameWindow, true); diff --git a/src/GameWindow.h b/src/GameWindow.h index 7e9ef54..44c0286 100644 --- a/src/GameWindow.h +++ b/src/GameWindow.h @@ -17,7 +17,6 @@ typedef struct sGameWindow GameEngine Engine; Bitmaps Bitmaps; SceneId CurrentSceneId; - bool SceneIsInitialized[NumScenes]; TitleScene TitleScene; PlayScene PlayScene; LevelEndScene LevelEndScene; diff --git a/src/LevelEndScene.c b/src/LevelEndScene.c index 16f90c7..c788b06 100644 --- a/src/LevelEndScene.c +++ b/src/LevelEndScene.c @@ -3,47 +3,94 @@ #include "LevelEndScene.h" +#define LevelTextScale 4 +#define HalfStarScale 3 +#define ScoreTextScale 1 + void LevelEndScene_Init(GameWindow *pGameWindow) { + Rect r; + + const Rect *pContentRect = &(pGameWindow->Window->portRect); + + // Setup level + GetScaledPicFrame(pGameWindow->Engine.SetB ? pGameWindow->Bitmaps.BCharPict : pGameWindow->Bitmaps.ACharPict, LevelTextScale, &(pGameWindow->LevelEndScene.LevelRect)); + Bitmaps_GetNumberRect(&(pGameWindow->Bitmaps), 1 + pGameWindow->Engine.Level, LevelTextScale, &r); + ConcatenateRect(&(pGameWindow->LevelEndScene.LevelRect), &r, &(pGameWindow->LevelEndScene.LevelRect)); + + GetBoxRect(pContentRect, Top, &r); + CenterRect(&r, &(pGameWindow->LevelEndScene.LevelRect)); + + // Setup half-stars + Bitmaps_GetHalfStarsRect(&(pGameWindow->Bitmaps), GameEngine_GetHalfStars(&(pGameWindow->Engine)), MaxStars, HalfStarScale, &(pGameWindow->LevelEndScene.HalfStarsRect)); + + GetBoxRect(pContentRect, Center, &r); + CenterRect(&r, &(pGameWindow->LevelEndScene.HalfStarsRect)); + + // Setup score + Bitmaps_GetNumberRect(&(pGameWindow->Bitmaps), pGameWindow->Engine.Score, ScoreTextScale, &(pGameWindow->LevelEndScene.ScoreRect)); + GetScaledPicFrame(pGameWindow->Bitmaps.SlashCharPict, ScoreTextScale, &r); + ConcatenateRect(&(pGameWindow->LevelEndScene.ScoreRect), &r, &(pGameWindow->LevelEndScene.ScoreRect)); + Bitmaps_GetNumberRect(&(pGameWindow->Bitmaps), PerfectScore, ScoreTextScale, &r); + ConcatenateRect(&(pGameWindow->LevelEndScene.ScoreRect), &r, &(pGameWindow->LevelEndScene.ScoreRect)); + + GetBoxRect(pContentRect, Bottom, &r); + CenterRect(&r, &(pGameWindow->LevelEndScene.ScoreRect)); + + // Setup retry button + GetPictureRect(pGameWindow->Bitmaps.RetryButtonPict, &(pGameWindow->LevelEndScene.RetryButtonRect)); + + GetBoxRect(pContentRect, BottomLeft, &r); + CenterRect(&r, &(pGameWindow->LevelEndScene.RetryButtonRect)); + + // Setup next button + GetPictureRect(pGameWindow->Bitmaps.NextButtonPict, &(pGameWindow->LevelEndScene.NextButtonRect)); + + GetBoxRect(pContentRect, BottomRight, &r); + CenterRect(&r, &(pGameWindow->LevelEndScene.NextButtonRect)); } void LevelEndScene_Draw(const GameWindow *pGameWindow, bool fullRefresh) { - Str255 halfStarsStr; - - // TODO: Proper level end - if (fullRefresh) + // Draw level + MoveTo(pGameWindow->LevelEndScene.LevelRect.left, pGameWindow->LevelEndScene.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); - MoveTo(100, 100); - DrawString("\pLevel complete! Click to continue."); + // Draw half-stars + MoveTo(pGameWindow->LevelEndScene.HalfStarsRect.left, pGameWindow->LevelEndScene.HalfStarsRect.top); + Bitmaps_DrawHalfStars(&(pGameWindow->Bitmaps), GameEngine_GetHalfStars(&(pGameWindow->Engine)), MaxStars, HalfStarScale); - MoveTo(100, 125); - DrawString("\pReceived "); - NumToString((int32_t)GameEngine_GetHalfStars(&(pGameWindow->Engine)), &halfStarsStr); - DrawString(halfStarsStr); - DrawString("\p/6 half-stars."); + // Draw score + MoveTo(pGameWindow->LevelEndScene.ScoreRect.left, pGameWindow->LevelEndScene.ScoreRect.top); + Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), pGameWindow->Engine.Score, ScoreTextScale); + Bitmaps_DrawSlashChar(&(pGameWindow->Bitmaps), ScoreTextScale); + Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), PerfectScore, ScoreTextScale); - MoveTo(100, 200); - DrawString("\pRetry level."); + // Draw retry button + DrawPicture(pGameWindow->Bitmaps.RetryButtonPict, &(pGameWindow->LevelEndScene.RetryButtonRect)); - MoveTo(350, 200); - DrawString("\pNext level."); + // Draw next button + DrawPicture(pGameWindow->Bitmaps.NextButtonPict, &(pGameWindow->LevelEndScene.NextButtonRect)); } void LevelEndScene_Click(GameWindow *pGameWindow, const Point *pPosition) { - // TODO: Proper click handling - - if (pPosition->h < ((pGameWindow->Window->portRect.right - pGameWindow->Window->portRect.left) / 2)) + if (PtInRect(*pPosition, &(pGameWindow->LevelEndScene.RetryButtonRect))) { GameEngine_ResetLevel(&(pGameWindow->Engine)); + GameWindow_SetScene(pGameWindow, Play); } - else + else if (PtInRect(*pPosition, &(pGameWindow->LevelEndScene.NextButtonRect))) { GameEngine_NextLevel(&(pGameWindow->Engine)); + GameWindow_SetScene(pGameWindow, GameEngine_IsGameOver(&(pGameWindow->Engine)) ? GameEnd : Play); } - - GameWindow_SetScene(pGameWindow, GameEngine_IsGameOver(&(pGameWindow->Engine)) ? GameEnd : Play); } diff --git a/src/MacCommon.c b/src/MacCommon.c index c0f7c95..bb1e189 100644 --- a/src/MacCommon.c +++ b/src/MacCommon.c @@ -47,6 +47,7 @@ void ConcatenateRect(const Rect *pLeftRect, const Rect *pRightRect, Rect *pDestR void GetBoxRect(const Rect *pOuterRect, const BoxAlignment boxAlignment, Rect *pBoxRect) { int32_t boxWidth, boxHeight; + Rect resultRect; boxWidth = (pOuterRect->right - pOuterRect->left) / 3; boxHeight = (pOuterRect->bottom - pOuterRect->top) / 3; @@ -54,66 +55,87 @@ void GetBoxRect(const Rect *pOuterRect, const BoxAlignment boxAlignment, Rect *p switch (boxAlignment) { case Top: - pBoxRect->top = pOuterRect->top; - pBoxRect->left = pOuterRect->left + boxWidth; - pBoxRect->bottom = pOuterRect->top + boxHeight; - pBoxRect->right = pOuterRect->right - boxWidth; + resultRect.top = pOuterRect->top; + resultRect.left = pOuterRect->left + boxWidth; + resultRect.bottom = pOuterRect->top + boxHeight; + resultRect.right = pOuterRect->right - boxWidth; break; case TopLeft: - pBoxRect->top = pOuterRect->top; - pBoxRect->left = pOuterRect->left; - pBoxRect->bottom = pOuterRect->top + boxHeight; - pBoxRect->right = pOuterRect->left + boxWidth; + resultRect.top = pOuterRect->top; + resultRect.left = pOuterRect->left; + resultRect.bottom = pOuterRect->top + boxHeight; + resultRect.right = pOuterRect->left + boxWidth; break; case Left: - pBoxRect->top = pOuterRect->top + boxHeight; - pBoxRect->left = pOuterRect->left; - pBoxRect->bottom = pOuterRect->bottom - boxHeight; - pBoxRect->right = pOuterRect->left + boxWidth; + resultRect.top = pOuterRect->top + boxHeight; + resultRect.left = pOuterRect->left; + resultRect.bottom = pOuterRect->bottom - boxHeight; + resultRect.right = pOuterRect->left + boxWidth; break; case BottomLeft: - pBoxRect->top = pOuterRect->bottom - boxHeight; - pBoxRect->left = pOuterRect->left; - pBoxRect->bottom = pOuterRect->bottom; - pBoxRect->right = pOuterRect->left + boxWidth; + resultRect.top = pOuterRect->bottom - boxHeight; + resultRect.left = pOuterRect->left; + resultRect.bottom = pOuterRect->bottom; + resultRect.right = pOuterRect->left + boxWidth; break; case Bottom: - pBoxRect->top = pOuterRect->bottom - boxHeight; - pBoxRect->left = pOuterRect->left + boxWidth; - pBoxRect->bottom = pOuterRect->bottom; - pBoxRect->right = pOuterRect->right - boxWidth; + resultRect.top = pOuterRect->bottom - boxHeight; + resultRect.left = pOuterRect->left + boxWidth; + resultRect.bottom = pOuterRect->bottom; + resultRect.right = pOuterRect->right - boxWidth; break; case BottomRight: - pBoxRect->top = pOuterRect->bottom - boxHeight; - pBoxRect->left = pOuterRect->right - boxWidth; - pBoxRect->bottom = pOuterRect->bottom; - pBoxRect->right = pOuterRect->right; + resultRect.top = pOuterRect->bottom - boxHeight; + resultRect.left = pOuterRect->right - boxWidth; + resultRect.bottom = pOuterRect->bottom; + resultRect.right = pOuterRect->right; break; case Right: - pBoxRect->top = pOuterRect->top + boxHeight; - pBoxRect->left = pOuterRect->right - boxWidth; - pBoxRect->bottom = pOuterRect->bottom - boxHeight; - pBoxRect->right = pOuterRect->right; + resultRect.top = pOuterRect->top + boxHeight; + resultRect.left = pOuterRect->right - boxWidth; + resultRect.bottom = pOuterRect->bottom - boxHeight; + resultRect.right = pOuterRect->right; break; case TopRight: - pBoxRect->top = pOuterRect->top; - pBoxRect->left = pOuterRect->right - boxWidth; - pBoxRect->bottom = pOuterRect->top + boxHeight; - pBoxRect->right = pOuterRect->right; + resultRect.top = pOuterRect->top; + resultRect.left = pOuterRect->right - boxWidth; + resultRect.bottom = pOuterRect->top + boxHeight; + resultRect.right = pOuterRect->right; break; case Center: - pBoxRect->top = pOuterRect->top + boxHeight; - pBoxRect->left = pOuterRect->left + boxWidth; - pBoxRect->bottom = pOuterRect->bottom - boxHeight; - pBoxRect->right = pOuterRect->right - boxWidth; + resultRect.top = pOuterRect->top + boxHeight; + resultRect.left = pOuterRect->left + boxWidth; + resultRect.bottom = pOuterRect->bottom - boxHeight; + resultRect.right = pOuterRect->right - boxWidth; break; } + + *pBoxRect = resultRect; +} + +void GetPictureRect(const PicHandle picHandle, Rect *pDestRect) +{ + *pDestRect = (**(picHandle)).picFrame; } void GetScaledPicFrame(const PicHandle picHandle, const uint8_t scale, Rect *pDestRect) { - *pDestRect = (**(picHandle)).picFrame; + GetPictureRect(picHandle, pDestRect); pDestRect->right = pDestRect->left + ((pDestRect->right - pDestRect->left) * max(scale, 1)); pDestRect->bottom = pDestRect->top + ((pDestRect->bottom - pDestRect->top) * max(scale, 1)); } + +void DrawScaledPic(const PicHandle pic, const uint8_t scale) +{ + Point penPosition; + Rect destRect; + + GetPen(&penPosition); + GetScaledPicFrame(pic, scale, &destRect); + + OffsetRect(&destRect, penPosition.h, penPosition.v); + + DrawPicture(pic, &destRect); + MoveTo(destRect.right, destRect.top); +} diff --git a/src/MacCommon.h b/src/MacCommon.h index 58c5a4c..a87be46 100644 --- a/src/MacCommon.h +++ b/src/MacCommon.h @@ -39,6 +39,9 @@ void ConcatenateRect(const Rect *pLeftRect, const Rect *pRightRect, Rect *pDestR void GetBoxRect(const Rect *pOuterRect, const BoxAlignment boxAlignment, Rect *pBoxRect); +void GetPictureRect(const PicHandle picHandle, Rect *pDestRect); + void GetScaledPicFrame(const PicHandle picHandle, const uint8_t scale, Rect *pDestRect); +void DrawScaledPic(const PicHandle pic, const uint8_t scale); #endif diff --git a/src/MacLO.pi.bin b/src/MacLO.pi.bin index bdb822f2d03eca0181ad3f06a6ddf1778a3d04b4..829953be2b62052cbea772c0c5ca8e8c40fd41e4 100644 GIT binary patch delta 2991 zcmeHJT}&KR6rS0;l(w4z3WWj-IEADx8(4mtGy#F6i61=!cfL7u?m6fC?zwv>F_D;<>aV73S9c)&>f&Hpy}f&S+YaaP>p+axDXa%*vBvpoDkyUVa(PK zb25*Iz>a;9`YgMjlShL}G^SgbhAB(u^Z1~z^|q7ai!vp3o+3NjXC!%698cX_fRH20Wc zn|q?7WVkeDg=uMFhp-%vvJxbS8Ik+2yq^onaS7}3azhymfuKQ3_iC~y8&+1uF}(C3 zjaJHDC=yF%*sPlKgRB!HQ=?xTUn7uTRAgBk9l#@cX_A!}C>iR9q2zrMD7`kTy}gm3 zWU|U#we<=F`SxaWRI*6!lI~~bKQYsZ1-O?Y>oZew);_af{(ni$pG|E;%oKfFfGB^@ zoXqd|N2TClkJ-Vit)A2OP3()J$g?AHo)6#=3CALtod6xHPd7J^A({SYbu6r_C$o{p z5>$r$TJ5@(D0Ob~gR9r2Uj8j@4f4W{TE>x9FLh)Fxx={0^|A%h!Hl`okA6y9gA|p! zUAca>F7>;`v^B^wTbW{u4myy!7)T{b2#wU6n;}{y@s&2)XOdS+KSt`6gOI<9JW=Me z)#NVrPNnD z!3-I!FM`$XAkWp``oCk1zlr~7$C6{d2?f4an%Mn(@Q8KNPBN2>`4zW?62j&;QUJ@+ z5q}(xFCqIh*~oEcJIC`5pthXDZUB#A{;~Dbk_#ENt*rowx6SJ) zdrCLH+}1~vhQe^_^LD&tnst)8uHu3ZZ!Q&=koK-wB{^3~Q7bDHRqzE$&H+;$JH3Ee z6QjF;YfRjH4ZcnPG;!;eEc`y;C9{amHv!9L k5uH;gdGagE{x-y4w(K(~Ia^}pDtHYgXXvZsTKAs60C*Dmwg3PC delta 2875 zcmeH}Uu;uV9LImBr(O4l(XA_^V{;uK8_cZRFd?`M$^!|}NMy!{QcZlg5A$J(Ch7o} z-Ae>DWQm)HL`+DONOa8z4r_dHY+MsHhOoH=|Lnh|1%o8UJrI~%dyn7K+wo`J13u`B zcKP*w&+mTD@BGg1-k#r#4x^*{(KU?j{cL-3`pD0_rz6*P_Y|*o9y;{OrJl|f_HobX zdLH>LeD>xCPWMTxgP&YD6+Pj4i;0%any7I5((%y8}37r1uqI@hiTVSBiCt1F#IHPz4oI;cz9MH{G^4$|w;d+*ZE z!n?@qgW5#xbU+6bR#KNx>f_#Xja=XK(kCQfm#LR}U;?Ief+Exn>wzhKh5G0nST{`R zt2BV|0LB9t4`4h9JqUgf{2+Wo&_jqfgm^=wC+Iu|=P|g5>qT6L0SrSAr*(ox5MTtp z5d;`PfKe-dv6&u}q|@;ixH6f#Jcu@t#NF(NJ(h_NI%j}CAn0vZ6fD^MqZW{Pq`CJ~cHl9UEOlw5h=nkhsn`xCfIZs|<1-rLV3@$kE=%fuhvV0K;wg;`le+e)^uznhZqt*Xn8?h$RPs89ob#)zzSt_QgHhFLoEh%zY_FIVG#&Plc+Lc^AQfuvx|G&lQ*YSR;?f_Cgd0gcl*C7tLjCIuZP1uW@JpXW){g@{xiGSGLW!#@4ZJ9ss4v;voXo&)sU#2owB zM<7H+t3aPt{pBu`dWwA>?!s| zkJi^RM{XQaTxh6u6n&?h`Hj1n3#$@EKik}zCn}pguBS`B_LA7#{JtKZoKp>$D5si- zC(+iFcGmLn6ecLmZ@`ajDjkG>@&{YHK7_u3e>&iA4D#^!F}pU6TcC5%P^FI=w}Uxt z^Epl)9@A{yWWaAKtrImJ#)SQu8*k&rIm$^VLC{lBIY_7idW;O^&shikc}C|#_uEM{ lbs^3(b`nk9(6NmF7!OZq8UJx4vBO@=^(Gj0LR{Fkm*-8xh5(hdl_DWZPK( z+azuef`}eGNWoBSbMRs|AnHMA4?U=~&7vYj3Qa*tG@Fg@P1=@g(6DHj%jg4t(NKqTvvM??hx6Ll#iQMbY`fKEF|;k za4KYm%w!>*U(7CM)A_l+clTa>#FHOF1p5&7Fp!@L{IjzG8YnWgQL3su79(jSb7>_7 zCYVY=%j;P^tL3%6)c=UZXZUgsg^B|TrwO{Ki<+Pbsqngai9?+Ix9zWWv9a~v^Mbal zMzn{dd@R)nbwSe`w0muKi;cGc&+`_G&1ScIy}_VquBp#I#(@>)R7nzr3S%kyiVut} zx)`2}-1lAf8I8GTOG{y0%=o^qy(^o7i~>`85m?pK^Z1$qN{!NmE=% z9F!qK+}w@&#}FlUH6TwwjPaC^=mfY!+%kZA4OC+HKI9GTTAAbF4~wRH>(szA(?GjW10?aHzAhu!*(yk$mN@u?2($7l3G;EkjKDy Ucjb(77-o<)eEWindow->portRect); // Setup Playfield pGameWindow->PlayScene.PlayfieldRect.top = PlayfieldMargin; - pGameWindow->PlayScene.PlayfieldRect.bottom = pGameWindow->Window->portRect.bottom - PlayfieldMargin; + pGameWindow->PlayScene.PlayfieldRect.bottom = pContentRect->bottom - PlayfieldMargin; pGameWindow->PlayScene.PlayfieldRect.left = pGameWindow->PlayScene.PlayfieldRect.top; pGameWindow->PlayScene.PlayfieldRect.right = pGameWindow->PlayScene.PlayfieldRect.bottom; // Setup HUD pGameWindow->PlayScene.HUDRect.top = HUDMargin; - pGameWindow->PlayScene.HUDRect.bottom = pGameWindow->Window->portRect.bottom - HUDMargin; + pGameWindow->PlayScene.HUDRect.bottom = pContentRect->bottom - HUDMargin; pGameWindow->PlayScene.HUDRect.left = pGameWindow->PlayScene.PlayfieldRect.right + HUDMargin; - pGameWindow->PlayScene.HUDRect.right = pGameWindow->Window->portRect.right - HUDMargin; + pGameWindow->PlayScene.HUDRect.right = pContentRect->right - HUDMargin; - // Setup Level - GetScaledPicFrame(pGameWindow->Engine.SetB ? pGameWindow->Bitmaps.BCharPict : pGameWindow->Bitmaps.ACharPict, LevelTextScale, &r1); - Bitmaps_GetNumberRect(&(pGameWindow->Bitmaps), 1 + pGameWindow->Engine.Level, LevelTextScale, &r2); - ConcatenateRect(&r1, &r2, &(pGameWindow->PlayScene.LevelRect)); + // Setup level + GetScaledPicFrame(pGameWindow->Engine.SetB ? pGameWindow->Bitmaps.BCharPict : pGameWindow->Bitmaps.ACharPict, LevelTextScale, &(pGameWindow->PlayScene.LevelRect)); + Bitmaps_GetNumberRect(&(pGameWindow->Bitmaps), 1 + pGameWindow->Engine.Level, LevelTextScale, &r); + ConcatenateRect(&(pGameWindow->PlayScene.LevelRect), &r, &(pGameWindow->PlayScene.LevelRect)); + + GetBoxRect(&(pGameWindow->PlayScene.HUDRect), Top, &r); + CenterRect(&r, &(pGameWindow->PlayScene.LevelRect)); + + // Setup half-stars + Bitmaps_GetHalfStarsRect(&(pGameWindow->Bitmaps), GameEngine_GetHalfStars(&(pGameWindow->Engine)), MaxStars, HalfStarScale, &(pGameWindow->PlayScene.HalfStarsRect)); - GetBoxRect(&(pGameWindow->PlayScene.HUDRect), Top, &r1); - GetBoxRect(&r1, Bottom, &r2); - CenterRect(&r2, &(pGameWindow->PlayScene.LevelRect)); + GetBoxRect(&(pGameWindow->PlayScene.HUDRect), Center, &r); + CenterRect(&r, &(pGameWindow->PlayScene.HalfStarsRect)); + + // Setup score + Bitmaps_GetNumberRect(&(pGameWindow->Bitmaps), pGameWindow->Engine.Score, ScoreTextScale, &(pGameWindow->PlayScene.ScoreRect)); + GetScaledPicFrame(pGameWindow->Bitmaps.SlashCharPict, ScoreTextScale, &r); + ConcatenateRect(&(pGameWindow->PlayScene.ScoreRect), &r, &(pGameWindow->PlayScene.ScoreRect)); + Bitmaps_GetNumberRect(&(pGameWindow->Bitmaps), PerfectScore, ScoreTextScale, &r); + ConcatenateRect(&(pGameWindow->PlayScene.ScoreRect), &r, &(pGameWindow->PlayScene.ScoreRect)); + + GetBoxRect(&(pGameWindow->PlayScene.HUDRect), Bottom, &r); + CenterRect(&r, &(pGameWindow->PlayScene.ScoreRect)); + + // Setup retry button + GetPictureRect(pGameWindow->Bitmaps.RetryButtonPict, &(pGameWindow->PlayScene.RetryButtonRect)); + + GetBoxRect(&(pGameWindow->PlayScene.HUDRect), BottomLeft, &r); + CenterRect(&r, &(pGameWindow->PlayScene.RetryButtonRect)); } void PlayScene_SetLightRect(const GameWindow *pGameWindow, Rect *pRect, const int8_t c, const int8_t r) @@ -59,8 +84,10 @@ void PlayScene_Draw(const GameWindow *pGameWindow, bool fullRefresh) if (fullRefresh) { // Fill backgrounds - FillRoundRect(&(pGameWindow->PlayScene.PlayfieldRect), PlayfieldCornerSize, PlayfieldCornerSize, PlayfieldPattern); - //FillRoundRect(&(pGameWindow->PlayScene.HUDRect), HUDCornerSize, HUDCornerSize, HUDPattern); + ForeColor(whiteColor); + FrameRoundRect(&(pGameWindow->PlayScene.PlayfieldRect), PlayfieldCornerSize, PlayfieldCornerSize); + FrameRoundRect(&(pGameWindow->PlayScene.HUDRect), HUDCornerSize, HUDCornerSize); + ForeColor(blackColor); } // Draw Playfield @@ -80,14 +107,14 @@ void PlayScene_Draw(const GameWindow *pGameWindow, bool fullRefresh) else { // Draw OFF light - FillRoundRect(&lightRect, LightCornerSize, LightCornerSize, black); + FillRoundRect(&lightRect, LightCornerSize, LightCornerSize, dkGray); } } } // Draw HUD - // Draw Level + // Draw level MoveTo(pGameWindow->PlayScene.LevelRect.left, pGameWindow->PlayScene.LevelRect.top); if (pGameWindow->Engine.SetB) { @@ -99,7 +126,18 @@ void PlayScene_Draw(const GameWindow *pGameWindow, bool fullRefresh) } Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), 1 + pGameWindow->Engine.Level, LevelTextScale); - // Draw Stars + // Draw half-stars + 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); + + // Draw retry button + DrawPicture(pGameWindow->Bitmaps.RetryButtonPict, &(pGameWindow->PlayScene.RetryButtonRect)); } void PlayScene_Click(GameWindow *pGameWindow, const Point *pPosition) @@ -128,11 +166,18 @@ void PlayScene_Click(GameWindow *pGameWindow, const Point *pPosition) if (GameEngine_IsCompleted(&(pGameWindow->Engine))) { // Level was completed in the last click + GameWindow_Draw(pGameWindow, false); GameWindow_SetScene(pGameWindow, LevelEnd); } } else if (PtInRect(*pPosition, &(pGameWindow->PlayScene.HUDRect))) { // Click within HUD + + if (PtInRect(*pPosition, &(pGameWindow->PlayScene.RetryButtonRect))) + { + GameEngine_ResetLevel(&(pGameWindow->Engine)); + GameWindow_Draw(pGameWindow, false); + } } } diff --git a/src/Scenes.h b/src/Scenes.h index 9d05482..f712b83 100644 --- a/src/Scenes.h +++ b/src/Scenes.h @@ -26,16 +26,24 @@ typedef struct sPlayScene Rect PlayfieldRect; Rect HUDRect; Rect LevelRect; + Rect HalfStarsRect; + Rect ScoreRect; + Rect RetryButtonRect; } PlayScene; typedef struct sLevelEndScene { - Rect temp; + Rect LevelRect; + Rect HalfStarsRect; + Rect ScoreRect; + Rect RetryButtonRect; + Rect NextButtonRect; } LevelEndScene; typedef struct sGameEndScene { - Rect temp; + Rect SetRect; + Rect ScoreRect; } GameEndScene; #endif diff --git a/src/TitleScene.c b/src/TitleScene.c index 8437d2b..1b3a283 100644 --- a/src/TitleScene.c +++ b/src/TitleScene.c @@ -13,7 +13,7 @@ void TitleScene_Init(GameWindow *pGameWindow) const Rect *pContentRect = &(pGameWindow->Window->portRect); // Setup rects - GetScaledPicFrame(pGameWindow->Bitmaps.TitlePict, 1, &(pGameWindow->TitleScene.TitleRect)); + GetPictureRect(pGameWindow->Bitmaps.TitlePict, &(pGameWindow->TitleScene.TitleRect)); CenterRect(pContentRect, &(pGameWindow->TitleScene.TitleRect)); GetBoxRect(pContentRect, BottomLeft, &r); @@ -27,11 +27,6 @@ void TitleScene_Init(GameWindow *pGameWindow) void TitleScene_Draw(const GameWindow *pGameWindow, bool fullRefresh) { - // TODO: Proper title - if (fullRefresh) - { - } - // Draw Title DrawPicture(pGameWindow->Bitmaps.TitlePict, &(pGameWindow->TitleScene.TitleRect));