From cdf67289a951aa3f6e4c87862f259f36fc59e8e1 Mon Sep 17 00:00:00 2001 From: Jon Thysell Date: Sun, 12 Dec 2021 15:45:28 -0800 Subject: [PATCH] Added saving of progress to the application's 'SAVE' resource --- src/GameEngine.c | 3 +- src/GameSave.c | 80 ++++++++++++++++++++++++++++++++++++++++++ src/GameSave.h | 41 ++++++++++++++++++++++ src/GameWindow.c | 7 ++++ src/GameWindow.h | 2 ++ src/Levels.h | 3 ++ src/MacCommon.c | 25 +++++++++++++ src/MacCommon.h | 10 ++++++ src/MacLO.c | 1 + src/MacLO.pi.bin | Bin 16128 -> 20224 bytes src/MacLO.pi.rsrc.bin | Bin 35968 -> 36096 bytes src/PlayScene.c | 1 + src/Sounds.c | 4 +-- src/WindowBuffer.h | 2 +- 14 files changed, 174 insertions(+), 5 deletions(-) create mode 100644 src/GameSave.c create mode 100644 src/GameSave.h diff --git a/src/GameEngine.c b/src/GameEngine.c index dcf26ae..67a69c3 100644 --- a/src/GameEngine.c +++ b/src/GameEngine.c @@ -48,8 +48,7 @@ void GameEngine_Init(GameEngine *pGameEngine) for (level = 0; level < LevelCount; level++) { - // TODO: Load actual scores - pGameEngine->ScoresA[level] = 1; + pGameEngine->ScoresA[level] = 0; pGameEngine->ScoresB[level] = 0; } diff --git a/src/GameSave.c b/src/GameSave.c new file mode 100644 index 0000000..58ff5ba --- /dev/null +++ b/src/GameSave.c @@ -0,0 +1,80 @@ +// Copyright (c) Jon Thysell +// Licensed under the MIT License. + +/** + * @file GameSave.c + * + * This file provides implementations for GameSave.h. + */ + +#include "GameSave.h" +#include "MacCommon.h" + +/** The save resource type. */ +#define SaveResType 'SAVE' + +/** The save resource ID. */ +#define SaveResID 128 + +/** The save resource ID. */ +#define SaveResSize (sizeof(uint8_t) * SetCount * LevelCount) + +void GameSave_Init(GameSave *pGameSave) +{ + pGameSave->Save = GetOrAddResource(SaveResType, SaveResID, SaveResSize, EmptyString); + if (pGameSave->Save == nil) + { + ShowError("\pGame's SAVE resource couldn't be created!", true); + } +} + +void GameSave_LoadData(const GameSave *pSaveGame, GameEngine *pGameEngine) +{ + int8_t level, scoreA, scoreB; + bool resetA, resetB; + + HLock(pSaveGame->Save); + + resetA = false; + resetB = false; + + for (level = 0; level < LevelCount; level++) + { + scoreA = min(MaxHalfStars, (*pSaveGame->Save)[level]); + resetA = resetA || (scoreA < MinHalfStars); + pGameEngine->ScoresA[level] = resetA ? 0 : scoreA; + + scoreB = min(MaxHalfStars, (*pSaveGame->Save)[LevelCount + level]); + resetB = resetB || (scoreB < MinHalfStars); + pGameEngine->ScoresB[level] = resetB ? 0 : scoreB; + } + + HUnlock(pSaveGame->Save); +} + +void GameSave_SaveData(GameSave *pSaveGame, const GameEngine *pGameEngine) +{ + int8_t level; + bool dataChanged; + + HLock(pSaveGame->Save); + + dataChanged = false; + for (level = 0; level < LevelCount; level++) + { + dataChanged = dataChanged + || ((*pSaveGame->Save)[level] != pGameEngine->ScoresA[level]) + || ((*pSaveGame->Save)[LevelCount + level] != pGameEngine->ScoresB[level]); + + (*pSaveGame->Save)[level] = pGameEngine->ScoresA[level]; + (*pSaveGame->Save)[LevelCount + level] = pGameEngine->ScoresB[level]; + } + + HUnlock(pSaveGame->Save); + + if (dataChanged) + { + ChangedResource(pSaveGame->Save); + WriteResource(pSaveGame->Save); + } +} diff --git a/src/GameSave.h b/src/GameSave.h new file mode 100644 index 0000000..02c7c41 --- /dev/null +++ b/src/GameSave.h @@ -0,0 +1,41 @@ +// Copyright (c) Jon Thysell +// Licensed under the MIT License. + +/** + * @file GameSave.h + * + * This file provides a GameSave type which manages saving scores to disk. + */ + +#ifndef GAMESAVE_H +#define GAMESAVE_H + +#include "GameEngine.h" + +/** Struct containing handle to the save resource. */ +typedef struct sGameSave +{ + Handle Save; +} GameSave; + +/** + * Initializes the GameSave. + * @param pGameSave The GameSave. + */ +void GameSave_Init(GameSave *pSaveGame); + +/** + * Loads data from the GameSave into the GameEngine. + * @param pGameSave The GameSave. + * @param pGameEngine The GameEngine. + */ +void GameSave_LoadData(const GameSave *pSaveGame, GameEngine *pGameEngine); + +/** + * Saves data from the GameEngine into the GameSave. + * @param pGameSave The GameSave. + * @param pGameEngine The GameEngine. + */ +void GameSave_SaveData(GameSave *pSaveGame, const GameEngine *pGameEngine); + +#endif diff --git a/src/GameWindow.c b/src/GameWindow.c index 2b76bb7..3a89e94 100644 --- a/src/GameWindow.c +++ b/src/GameWindow.c @@ -34,6 +34,9 @@ void GameWindow_Init(GameWindow *pGameWindow) // Initialize game engine GameEngine_Init(&(pGameWindow->Engine)); + // Initialize game save + GameSave_Init(&(pGameWindow->GameSave)); + // Load PICT resources Bitmaps_Init(&(pGameWindow->Bitmaps)); @@ -44,6 +47,9 @@ void GameWindow_Init(GameWindow *pGameWindow) SetPort(pGameWindow->Window); FillRect(&(pGameWindow->Window->portRect), WindowPattern); + // Load data from saved game + GameSave_LoadData(&(pGameWindow->GameSave), &(pGameWindow->Engine)); + GameWindow_SetScene(pGameWindow, Title); } @@ -144,6 +150,7 @@ void GameWindow_ClearScores(GameWindow *pGameWindow) if (ShowConfirm("\pAre you sure you want to clear all scores?")) { GameEngine_ResetGame(&(pGameWindow->Engine)); + GameSave_SaveData(&(pGameWindow->GameSave), &(pGameWindow->Engine)); GameWindow_SetScene(pGameWindow, Title); } } diff --git a/src/GameWindow.h b/src/GameWindow.h index b0e616c..14d6376 100644 --- a/src/GameWindow.h +++ b/src/GameWindow.h @@ -17,6 +17,7 @@ #include "MacCommon.h" #include "WindowBuffer.h" #include "GameEngine.h" +#include "GameSave.h" #include "Bitmaps.h" #include "Sounds.h" #include "Scenes.h" @@ -30,6 +31,7 @@ typedef struct sGameWindow WindowPtr Window; WindowBuffer WindowBuffer; GameEngine Engine; + GameSave GameSave; Bitmaps Bitmaps; Sounds Sounds; SceneId CurrentSceneId; diff --git a/src/Levels.h b/src/Levels.h index 3c12f2f..75bae74 100644 --- a/src/Levels.h +++ b/src/Levels.h @@ -18,6 +18,9 @@ /** The number of levels in each set. */ #define LevelCount 50 +/** The number of sets. */ +#define SetCount 2 + /** * Gets the lights for a given set and level number. * @param level The level number. diff --git a/src/MacCommon.c b/src/MacCommon.c index 76fd6ea..ecf50fa 100644 --- a/src/MacCommon.c +++ b/src/MacCommon.c @@ -164,3 +164,28 @@ void DrawScaledPic(const PicHandle pic, const uint8_t scale) DrawPicture(pic, &destRect); MoveTo(destRect.right, destRect.top); } + +Handle GetOrAddResource(ResType resType, uint16_t resID, Size byteCount, Str255 resName) +{ + Handle result; + + result = GetResource(resType, resID); + + if (result != nil && GetHandleSize(result) != byteCount) + { + // Resource was the wrong size, delete it + RmveResource(result); + ReleaseResource(result); + result = nil; + } + + if (result == nil) + { + // Resource didn't exist, create it + result = NewHandleClear(byteCount); + HNoPurge(result); + AddResource(result, resType, resID, resName); + } + + return result; +} diff --git a/src/MacCommon.h b/src/MacCommon.h index 8d5751a..d178750 100644 --- a/src/MacCommon.h +++ b/src/MacCommon.h @@ -122,4 +122,14 @@ void GetScaledPicFrame(const PicHandle picHandle, const uint8_t scale, Rect *pDe */ void DrawScaledPic(const PicHandle pic, const uint8_t scale); +/** + * Gets the specified resource or creates it if it doesn't exist. + * @param resType The resource type. + * @param resID The resource ID. + * @param byteCount The size of the resource if it needs to be created. + * @param resName The resource name if it needs to be created. + * @return Handle to the resource. + */ +Handle GetOrAddResource(ResType resType, uint16_t resID, Size byteCount, Str255 resName); + #endif diff --git a/src/MacLO.c b/src/MacLO.c index ea9e324..e5dc074 100644 --- a/src/MacLO.c +++ b/src/MacLO.c @@ -313,5 +313,6 @@ void MacLO_Quit() if (ShowConfirm("\pAre you sure you want to quit MacLO?")) { gExitApp = true; + GameSave_SaveData(&(gGameWindow.GameSave), &(gGameWindow.Engine)); } } diff --git a/src/MacLO.pi.bin b/src/MacLO.pi.bin index c5f410fd42af22302a175042d4aca74e31ed089a..4463d0ee863ba84357476a45833a6a3ac7341682 100644 GIT binary patch literal 20224 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 literal 16128 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 F4goPBs3rga diff --git a/src/PlayScene.c b/src/PlayScene.c index f376278..f268760 100644 --- a/src/PlayScene.c +++ b/src/PlayScene.c @@ -218,6 +218,7 @@ void PlayScene_Click(GameWindow *pGameWindow, const Point *pPosition) // Level was completed in the last click GameEngine_CompleteLevel(&(pGameWindow->Engine)); GameWindow_Draw(pGameWindow, false); + GameSave_SaveData(&(pGameWindow->GameSave), &(pGameWindow->Engine)); GameWindow_SetScene(pGameWindow, LevelEnd); Sounds_PlayDoneSnd(&(pGameWindow->Sounds)); } diff --git a/src/Sounds.c b/src/Sounds.c index ec6ea9f..de6fa40 100644 --- a/src/Sounds.c +++ b/src/Sounds.c @@ -10,10 +10,10 @@ #include "Sounds.h" /** The first snd resource ID. */ -#define SndBaseResId 8192 +#define SndBaseResID 8192 /** The click snd resource ID. */ -#define ClickSndResID SndBaseResId +#define ClickSndResID SndBaseResID /** The retry snd resource ID. */ #define RetrySndResID (ClickSndResID + 1) diff --git a/src/WindowBuffer.h b/src/WindowBuffer.h index a94ff5a..9530d29 100644 --- a/src/WindowBuffer.h +++ b/src/WindowBuffer.h @@ -38,4 +38,4 @@ void WindowBuffer_StartDraw(const WindowBuffer *pWindowBuffer); */ void WindowBuffer_EndDraw(const WindowBuffer *pWindowBuffer); -#endif \ No newline at end of file +#endif