Added level select scene and more

I've added a new level select scene after picking your set, and I've
updated the engine to store the result of each puzzle separately. The
level select is paged (can't fit all 50 on one screen), so needed to add
a new "previous button" graphic.

Added confirmation prompts, so I can prompt before quitting, and for a
new menu option to clear your scores if you want to reset your progress.

Progress is still not persisted when you exit, as I haven't figured out
how to do that yet.

I've also rearranged the title screen a bit.
This commit is contained in:
Jon Thysell 2021-11-30 18:38:36 -08:00
parent 206284b71d
commit 3542861603
21 changed files with 422 additions and 38 deletions

BIN
assets/prev.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 B

View File

@ -13,7 +13,8 @@
#define BCharPictResID (ACharPictResID + 1)
#define SlashCharPictResID (BCharPictResID + 1)
#define StarPictBaseResID (SlashCharPictResID + 1)
#define NextButtonPictResID (StarPictBaseResID + StarPictCount)
#define PrevButtonPictResID (StarPictBaseResID + StarPictCount)
#define NextButtonPictResID (PrevButtonPictResID + 1)
#define RetryButtonPictResID (NextButtonPictResID + 1)
#define SoundOffPictResID (RetryButtonPictResID + 1)
#define SoundOnPictResID (SoundOffPictResID + 1)
@ -89,6 +90,13 @@ void Bitmaps_Init(Bitmaps *pBitmaps)
ShowError("\pSlash char PICT resource missing!", true);
}
// Load prev button
pBitmaps->PrevButtonPict = Bitmaps_GetPict(baseResID, PrevButtonPictResID);
if (pBitmaps->PrevButtonPict == nil)
{
ShowError("\pPrev button PICT resource missing!", true);
}
// Load next button
pBitmaps->NextButtonPict = Bitmaps_GetPict(baseResID, NextButtonPictResID);
if (pBitmaps->NextButtonPict == nil)

View File

@ -17,6 +17,7 @@ typedef struct sBitmaps
PicHandle BCharPict;
PicHandle SlashCharPict;
PicHandle StarPicts[StarPictCount];
PicHandle PrevButtonPict;
PicHandle NextButtonPict;
PicHandle RetryButtonPict;
PicHandle SoundOffPict;

View File

@ -23,7 +23,7 @@ void GameEndScene_Init(GameWindow *pGameWindow)
CenterRect(&r, &(pGameWindow->GameEndScene.SetRect));
// Setup score
Bitmaps_GetNumberRect(&(pGameWindow->Bitmaps), pGameWindow->Engine.Score, ScoreTextScale, &(pGameWindow->GameEndScene.ScoreRect));
Bitmaps_GetNumberRect(&(pGameWindow->Bitmaps), GameEngine_GetTotalScore(&(pGameWindow->Engine)), 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);
@ -51,7 +51,7 @@ void GameEndScene_Draw(const GameWindow *pGameWindow, bool fullRefresh)
// Draw score
MoveTo(pGameWindow->GameEndScene.ScoreRect.left, pGameWindow->GameEndScene.ScoreRect.top);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), pGameWindow->Engine.Score, ScoreTextScale);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), GameEngine_GetTotalScore(&(pGameWindow->Engine)), ScoreTextScale);
Bitmaps_DrawSlashChar(&(pGameWindow->Bitmaps), ScoreTextScale);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), PerfectScore, ScoreTextScale);
}

View File

@ -16,24 +16,73 @@ void GameEngine_LoadLevel(GameEngine *pGameEngine, const int8_t level, const boo
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_Init(GameEngine *pGameEngine)
{
int8_t level;
for (level = 0; level < LevelCount; level++)
{
// TODO: Load actual scores
pGameEngine->ScoresA[level] = 1;
pGameEngine->ScoresB[level] = 0;
}
pGameEngine->Level = -1;
pGameEngine->SetB = false;
pGameEngine->PreviousLights = 0;
pGameEngine->Lights = 0;
pGameEngine->Par = 0;
pGameEngine->Moves = 0;
}
void GameEngine_NewGame(GameEngine *pGameEngine, const bool setB)
{
pGameEngine->Score = 0;
GameEngine_LoadLevel(pGameEngine, 0, setB);
pGameEngine->SetB = setB;
GameEngine_StartLevel(pGameEngine, 0);
}
void GameEngine_ResetGame(GameEngine *pGameEngine)
{
int8_t level;
for (level = 0; level < LevelCount; level++)
{
pGameEngine->ScoresA[level] = 0;
pGameEngine->ScoresB[level] = 0;
}
}
void GameEngine_StartLevel(GameEngine *pGameEngine, const uint8_t level)
{
GameEngine_LoadLevel(pGameEngine, level, pGameEngine->SetB);
}
void GameEngine_CompleteLevel(GameEngine *pGameEngine)
{
if (GameEngine_IsCompleted(pGameEngine))
{
if (pGameEngine->SetB)
{
pGameEngine->ScoresB[pGameEngine->Level] = max(GameEngine_GetHalfStars(pGameEngine), pGameEngine->ScoresB[pGameEngine->Level]);
}
else
{
pGameEngine->ScoresA[pGameEngine->Level] = max(GameEngine_GetHalfStars(pGameEngine), pGameEngine->ScoresA[pGameEngine->Level]);
}
}
}
void GameEngine_NextLevel(GameEngine *pGameEngine)
{
if (GameEngine_IsCompleted(pGameEngine))
{
pGameEngine->Score += GameEngine_GetHalfStars(pGameEngine);
GameEngine_LoadLevel(pGameEngine, pGameEngine->Level + 1, pGameEngine->SetB);
GameEngine_StartLevel(pGameEngine, pGameEngine->Level + 1);
}
}
void GameEngine_ResetLevel(GameEngine *pGameEngine)
{
GameEngine_LoadLevel(pGameEngine, pGameEngine->Level, pGameEngine->SetB);
GameEngine_StartLevel(pGameEngine, pGameEngine->Level);
}
void GameEngine_LoadLevel(GameEngine *pGameEngine, const int8_t level, const bool setB)
@ -56,6 +105,11 @@ bool GameEngine_GetLight(const GameEngine *pGameEngine, const int8_t x, const in
return false;
}
bool GameEngine_IsEnabled(const GameEngine *pGameEngine, const int8_t level)
{
return level == 0 || (level < LevelCount && GameEngine_GetScore(pGameEngine, level - 1) > 0);
}
bool GameEngine_IsCompleted(const GameEngine *pGameEngine)
{
return pGameEngine->Lights == 0;
@ -71,6 +125,25 @@ uint8_t GameEngine_GetHalfStars(const GameEngine *pGameEngine)
return GameEngine_CalculateHalfStars(pGameEngine->Par, pGameEngine->Moves);
}
uint8_t GameEngine_GetScore(const GameEngine *pGameEngine, const int8_t level)
{
return pGameEngine->SetB ? pGameEngine->ScoresB[level] : pGameEngine->ScoresA[level];
}
uint16_t GameEngine_GetTotalScore(const GameEngine *pGameEngine)
{
uint8_t level;
uint16_t score;
score = 0;
for (level = 0; level < LevelCount; level++)
{
score += GameEngine_GetScore(pGameEngine, level);
}
return score;
}
uint8_t GameEngine_CalculateHalfStars(const uint16_t par, const uint16_t moves)
{
uint8_t halfStarsLost = moves <= par ? 0 : max(0, (1 + moves - par) / 2);

View File

@ -16,7 +16,8 @@ extern const uint16_t PerfectScore;
typedef struct GameEngine
{
uint16_t Score;
uint8_t ScoresA[LevelCount];
uint8_t ScoresB[LevelCount];
int8_t Level;
bool SetB;
uint32_t Lights;
@ -25,8 +26,16 @@ typedef struct GameEngine
uint16_t Moves;
} GameEngine;
void GameEngine_Init(GameEngine *pGameEngine);
void GameEngine_NewGame(GameEngine *pGameEngine, const bool setB);
void GameEngine_ResetGame(GameEngine *pGameEngine);
void GameEngine_StartLevel(GameEngine *pGameEngine, const uint8_t level);
void GameEngine_CompleteLevel(GameEngine *pGameEngine);
void GameEngine_NextLevel(GameEngine *pGameEngine);
void GameEngine_ResetLevel(GameEngine *pGameEngine);
@ -35,10 +44,16 @@ bool GameEngine_GetLight(const GameEngine *pGameEngine, const int8_t x, const in
bool GameEngine_IsCompleted(const GameEngine *pGameEngine);
bool GameEngine_IsEnabled(const GameEngine *pGameEngine, const int8_t level);
bool GameEngine_IsGameOver(const GameEngine *pGameEngine);
uint8_t GameEngine_GetHalfStars(const GameEngine *pGameEngine);
uint8_t GameEngine_GetScore(const GameEngine *pGameEngine, const int8_t level);
uint16_t GameEngine_GetTotalScore(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);

View File

@ -3,6 +3,7 @@
#include "GameWindow.h"
#include "TitleScene.h"
#include "LevelSelectScene.h"
#include "PlayScene.h"
#include "LevelEndScene.h"
#include "GameEndScene.h"
@ -21,15 +22,18 @@ void GameWindow_Init(GameWindow *pGameWindow)
ShowError("\pGameWindow WIND resource missing!", true);
}
// Initialize window buffer
WindowBuffer_Init(&(pGameWindow->WindowBuffer), pGameWindow->Window);
// Initialize game engine
GameEngine_Init(&(pGameWindow->Engine));
// Load PICT resources
Bitmaps_Init(&(pGameWindow->Bitmaps));
// Load snd resources
Sounds_Init(&(pGameWindow->Sounds));
// Initialize window buffer
WindowBuffer_Init(&(pGameWindow->WindowBuffer), pGameWindow->Window);
// Setup graphics before first draw
SetPort(pGameWindow->Window);
FillRect(&(pGameWindow->Window->portRect), WindowPattern);
@ -58,6 +62,9 @@ void GameWindow_Draw(const GameWindow *pGameWindow, bool fullRefresh)
case Title:
TitleScene_Draw(pGameWindow, fullRefresh);
break;
case LevelSelect:
LevelSelectScene_Draw(pGameWindow, fullRefresh);
break;
case Play:
PlayScene_Draw(pGameWindow, fullRefresh);
break;
@ -81,6 +88,9 @@ void GameWindow_Click(GameWindow *pGameWindow, const Point *pPosition)
case Title:
TitleScene_Click(pGameWindow, pPosition);
break;
case LevelSelect:
LevelSelectScene_Click(pGameWindow, pPosition);
break;
case Play:
PlayScene_Click(pGameWindow, pPosition);
break;
@ -100,6 +110,9 @@ void GameWindow_SetScene(GameWindow *pGameWindow, const SceneId sceneId)
case Title:
TitleScene_Init(pGameWindow);
break;
case LevelSelect:
LevelSelectScene_Init(pGameWindow);
break;
case Play:
PlayScene_Init(pGameWindow);
break;
@ -119,3 +132,12 @@ void GameWindow_Show(const GameWindow *pGameWindow)
{
ShowWindow(pGameWindow->Window);
}
void GameWindow_ClearScores(GameWindow *pGameWindow)
{
if (ShowConfirm("\pClear all scores?"))
{
GameEngine_ResetGame(&(pGameWindow->Engine));
GameWindow_SetScene(pGameWindow, Title);
}
}

View File

@ -15,16 +15,17 @@
typedef struct sGameWindow
{
WindowPtr Window;
WindowBuffer WindowBuffer;
GameEngine Engine;
Bitmaps Bitmaps;
Sounds Sounds;
SceneId CurrentSceneId;
TitleScene TitleScene;
PlayScene PlayScene;
LevelEndScene LevelEndScene;
GameEndScene GameEndScene;
WindowPtr Window;
WindowBuffer WindowBuffer;
GameEngine Engine;
Bitmaps Bitmaps;
Sounds Sounds;
SceneId CurrentSceneId;
TitleScene TitleScene;
LevelSelectScene LevelSelectScene;
PlayScene PlayScene;
LevelEndScene LevelEndScene;
GameEndScene GameEndScene;
} GameWindow;
void GameWindow_Init(GameWindow *pGameWindow);
@ -34,4 +35,6 @@ void GameWindow_Click(GameWindow *pGameWindow, const Point *pPosition);
void GameWindow_SetScene(GameWindow *pGameWindow, const SceneId sceneId);
void GameWindow_Show(const GameWindow *pGameWindow);
void GameWindow_ClearScores(GameWindow *pGameWindow);
#endif

View File

@ -28,7 +28,7 @@ void LevelEndScene_Init(GameWindow *pGameWindow)
CenterRect(&r, &(pGameWindow->LevelEndScene.HalfStarsRect));
// Setup score
Bitmaps_GetNumberRect(&(pGameWindow->Bitmaps), pGameWindow->Engine.Score, ScoreTextScale, &(pGameWindow->LevelEndScene.ScoreRect));
Bitmaps_GetNumberRect(&(pGameWindow->Bitmaps), GameEngine_GetTotalScore(&(pGameWindow->Engine)), 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);
@ -70,7 +70,7 @@ void LevelEndScene_Draw(const GameWindow *pGameWindow, bool fullRefresh)
// Draw score
MoveTo(pGameWindow->LevelEndScene.ScoreRect.left, pGameWindow->LevelEndScene.ScoreRect.top);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), pGameWindow->Engine.Score, ScoreTextScale);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), GameEngine_GetTotalScore(&(pGameWindow->Engine)), ScoreTextScale);
Bitmaps_DrawSlashChar(&(pGameWindow->Bitmaps), ScoreTextScale);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), PerfectScore, ScoreTextScale);

206
src/LevelSelectScene.c Normal file
View File

@ -0,0 +1,206 @@
// Copyright (c) Jon Thysell <http://jonthysell.com>
// Licensed under the MIT License.
#include "LevelSelectScene.h"
#define SetTextScale 3
#define ScoreTextScale 1
#define LevelMargin 10
#define LevelWidth 80
#define LevelHeight 60
#define LevelRowCount 2
#define LevelColumnCount 5
#define LevelsPerPage (LevelRowCount * LevelColumnCount)
#define LevelTextScale 1
void LevelSelectScene_Init(GameWindow *pGameWindow)
{
Rect r;
const Rect *pContentRect = &(pGameWindow->Window->portRect);
pGameWindow->LevelSelectScene.PageNumber = pGameWindow->Engine.Level / LevelsPerPage;
// Setup set
GetScaledPicFrame(pGameWindow->Engine.SetB ? pGameWindow->Bitmaps.BCharPict : pGameWindow->Bitmaps.ACharPict, SetTextScale, &(pGameWindow->LevelSelectScene.SetRect));
GetBoxRect(pContentRect, Top, &r);
//GetBoxRect(&r, Top, &r);
CenterRect(&r, &(pGameWindow->LevelSelectScene.SetRect));
// Setup score
Bitmaps_GetNumberRect(&(pGameWindow->Bitmaps), GameEngine_GetTotalScore(&(pGameWindow->Engine)), ScoreTextScale, &(pGameWindow->LevelSelectScene.ScoreRect));
GetScaledPicFrame(pGameWindow->Bitmaps.SlashCharPict, ScoreTextScale, &r);
ConcatenateRect(&(pGameWindow->LevelSelectScene.ScoreRect), &r, &(pGameWindow->LevelSelectScene.ScoreRect));
Bitmaps_GetNumberRect(&(pGameWindow->Bitmaps), PerfectScore, ScoreTextScale, &r);
ConcatenateRect(&(pGameWindow->LevelSelectScene.ScoreRect), &r, &(pGameWindow->LevelSelectScene.ScoreRect));
GetBoxRect(pContentRect, Bottom, &r);
//GetBoxRect(&r, Bottom, &r);
CenterRect(&r, &(pGameWindow->LevelSelectScene.ScoreRect));
// Setup previous button
GetPictureRect(pGameWindow->Bitmaps.NextButtonPict, &(pGameWindow->LevelSelectScene.PrevButtonRect));
GetBoxRect(pContentRect, BottomLeft, &r);
//GetBoxRect(&r, Bottom, &r);
CenterRect(&r, &(pGameWindow->LevelSelectScene.PrevButtonRect));
// Setup next button
GetPictureRect(pGameWindow->Bitmaps.NextButtonPict, &(pGameWindow->LevelSelectScene.NextButtonRect));
GetBoxRect(pContentRect, BottomRight, &r);
//GetBoxRect(&r, Bottom, &r);
CenterRect(&r, &(pGameWindow->LevelSelectScene.NextButtonRect));
// Setup LevelGrid
pGameWindow->LevelSelectScene.LevelGridRect.top = 0;
pGameWindow->LevelSelectScene.LevelGridRect.bottom = (LevelRowCount * (LevelHeight + LevelMargin)) - LevelMargin;
pGameWindow->LevelSelectScene.LevelGridRect.left = 0;
pGameWindow->LevelSelectScene.LevelGridRect.right = (LevelColumnCount * (LevelWidth + LevelMargin)) - LevelMargin;
CenterRect(pContentRect, &(pGameWindow->LevelSelectScene.LevelGridRect));
}
void LevelSelectScene_SetLevelRect(const GameWindow *pGameWindow, Rect *pRect, const int8_t i)
{
int8_t c, r;
c = i % LevelColumnCount;
r = i / LevelColumnCount;
pRect->top = pGameWindow->LevelSelectScene.LevelGridRect.top + (r * (LevelHeight + LevelMargin));
pRect->bottom = pRect->top + LevelHeight;
pRect->left = pGameWindow->LevelSelectScene.LevelGridRect.left + (c * (LevelWidth + LevelMargin));
pRect->right = pRect->left + LevelWidth;
}
void LevelSelectScene_Draw(const GameWindow *pGameWindow, bool fullRefresh)
{
int8_t i, level;
Rect levelRect, levelTextRect, levelHalfStarsRect, r;
// Draw set
if (fullRefresh)
{
MoveTo(pGameWindow->LevelSelectScene.SetRect.left, pGameWindow->LevelSelectScene.SetRect.top);
if (pGameWindow->Engine.SetB)
{
Bitmaps_DrawBChar(&(pGameWindow->Bitmaps), SetTextScale);
}
else
{
Bitmaps_DrawAChar(&(pGameWindow->Bitmaps), SetTextScale);
}
}
// Draw score
if (fullRefresh)
{
MoveTo(pGameWindow->LevelSelectScene.ScoreRect.left, pGameWindow->LevelSelectScene.ScoreRect.top);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), GameEngine_GetTotalScore(&(pGameWindow->Engine)), ScoreTextScale);
Bitmaps_DrawSlashChar(&(pGameWindow->Bitmaps), ScoreTextScale);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), PerfectScore, ScoreTextScale);
}
// Draw prev button
if (fullRefresh)
{
DrawPicture(pGameWindow->Bitmaps.PrevButtonPict, &(pGameWindow->LevelSelectScene.PrevButtonRect));
}
// Draw next button
if ((pGameWindow->LevelSelectScene.PageNumber + 1) * LevelsPerPage < LevelCount)
{
DrawPicture(pGameWindow->Bitmaps.NextButtonPict, &(pGameWindow->LevelSelectScene.NextButtonRect));
}
else
{
FillRect(&(pGameWindow->LevelSelectScene.NextButtonRect), WindowPattern);
}
// Draw levels
for (i = 0; i < LevelsPerPage; i++)
{
level = i + (LevelsPerPage * pGameWindow->LevelSelectScene.PageNumber);
LevelSelectScene_SetLevelRect(pGameWindow, &levelRect, i);
if (!fullRefresh)
{
FillRect(&levelRect, WindowPattern);
}
if (level < LevelCount)
{
// Draw level number
Bitmaps_GetNumberRect(&(pGameWindow->Bitmaps), 1 + level, LevelTextScale, &levelTextRect);
GetBoxRect(&levelRect, Top, &r);
GetBoxRect(&r, Bottom, &r);
CenterRect(&r, &levelTextRect);
MoveTo(levelTextRect.left, levelTextRect.top);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), 1 + level, LevelTextScale);
if (GameEngine_IsEnabled(&(pGameWindow->Engine), level))
{
// Draw half-stars
Bitmaps_GetHalfStarsRect(&(pGameWindow->Bitmaps), GameEngine_GetScore(&(pGameWindow->Engine), level), MaxStars, LevelTextScale, &levelHalfStarsRect);
GetBoxRect(&levelRect, Bottom, &r);
GetBoxRect(&r, Top, &r);
CenterRect(&r, &levelHalfStarsRect);
MoveTo(levelHalfStarsRect.left, levelHalfStarsRect.top);
Bitmaps_DrawHalfStars(&(pGameWindow->Bitmaps), GameEngine_GetScore(&(pGameWindow->Engine), level), MaxStars, LevelTextScale);
}
}
}
}
void LevelSelectScene_Click(GameWindow *pGameWindow, const Point *pPosition)
{
int8_t i, level;
Rect levelRect;
if (PtInRect(*pPosition, &(pGameWindow->LevelSelectScene.LevelGridRect)))
{
// Click within LevelGrid
for (i = 0; i < LevelsPerPage; i++)
{
level = i + (LevelsPerPage * pGameWindow->LevelSelectScene.PageNumber);
if (GameEngine_IsEnabled(&(pGameWindow->Engine), level))
{
LevelSelectScene_SetLevelRect(pGameWindow, &levelRect, i);
if (PtInRect(*pPosition, &levelRect))
{
GameEngine_StartLevel(&(pGameWindow->Engine), level);
GameWindow_SetScene(pGameWindow, Play);
break;
}
}
}
}
else if (PtInRect(*pPosition, &(pGameWindow->LevelSelectScene.PrevButtonRect)))
{
if (pGameWindow->LevelSelectScene.PageNumber > 0)
{
pGameWindow->LevelSelectScene.PageNumber--;
GameWindow_Draw(pGameWindow, false);
}
else
{
GameWindow_SetScene(pGameWindow, Title);
}
}
else if (PtInRect(*pPosition, &(pGameWindow->LevelSelectScene.NextButtonRect)))
{
if ((pGameWindow->LevelSelectScene.PageNumber + 1) * LevelsPerPage < LevelCount)
{
pGameWindow->LevelSelectScene.PageNumber++;
GameWindow_Draw(pGameWindow, false);
}
}
}

13
src/LevelSelectScene.h Normal file
View File

@ -0,0 +1,13 @@
// Copyright (c) Jon Thysell <http://jonthysell.com>
// Licensed under the MIT License.
#ifndef LEVELSELECTSCENE_H
#define LEVELSELECTSCENE_H
#include "GameWindow.h"
void LevelSelectScene_Init(GameWindow *pGameWindow);
void LevelSelectScene_Draw(const GameWindow *pGameWindow, bool fullRefresh);
void LevelSelectScene_Click(GameWindow *pGameWindow, const Point *pPosition);
#endif

View File

@ -4,8 +4,6 @@
#include "Common.h"
#include "Levels.h"
const int8_t LevelCount = 50;
const uint32_t Levels_LightsA[] = {
0x0005400UL, 0x15A82B5UL, 0x0ADEF6AUL, 0x1B88360UL, 0x1BC5EEFUL, 0x0EAD400UL, 0x0F8C62FUL, 0x0AAA880UL, 0x07D3BEAUL,
0x00039CEUL, 0x0EAD6B5UL, 0x0A76D5FUL, 0x022AA88UL, 0x0210800UL, 0x0010040UL, 0x1F08421UL, 0x1F71000UL, 0x0455544UL,

View File

@ -7,7 +7,7 @@
#include "stdint.h"
#include "stdbool.h"
extern const int8_t LevelCount;
#define LevelCount 50
uint32_t Levels_GetLightsForLevel(const int8_t level, const bool setB);

View File

@ -3,6 +3,11 @@
#include "MacCommon.h"
#define ErrorAlertResID BaseResID
#define ConfirmAlertResID (ErrorAlertResID + 1)
#define YesResult 2
const int16_t MonthOffset[] = {
0, // Jan
31, // Feb
@ -29,6 +34,16 @@ void ShowError(Str255 message, bool isFatal)
}
}
bool ShowConfirm(Str255 message)
{
uint16_t result;
ParamText(message, EmptyString, EmptyString, EmptyString);
result = CautionAlert(ConfirmAlertResID, NilFilterProc);
return result == YesResult;
}
void CenterRect(const Rect *pOuterRect, Rect *pInnerRect)
{
CenterRectH(pOuterRect, pInnerRect);

View File

@ -12,8 +12,6 @@
#define EmptyString "\p"
#define NilFilterProc nil
#define ErrorAlertResID BaseResID
extern const int16_t MonthOffset[];
typedef enum eBoxAlignment
@ -33,6 +31,8 @@ pascal OSErr SetDialogDefaultItem(DialogPtr theDialog, int16_t newItem) = { 0x30
void ShowError(Str255 message, bool isFatal);
bool ShowConfirm(Str255 message);
void CenterRect(const Rect *pOuterRect, Rect *pInnerRect);
void CenterRectH(const Rect *pOuterRect, Rect *pInnerRect);
void CenterRectV(const Rect *pOuterRect, Rect *pInnerRect);

View File

@ -8,8 +8,9 @@
#define AboutMenuItemID 1
#define GameMenuResID BaseResID+1
#define NewMenuItemID 1
#define QuitMenuItemID 3
#define TitleMenuItemID 1
#define ClearMenuItemID 2
#define QuitMenuItemID 4
#define AboutDialogResID BaseResID
#define AboutDialogOKID 1
@ -29,6 +30,8 @@ void MacLO_LaunchAppleMenuItem(const int16_t item);
void MacLO_HandleGameMenuChoice(const int16_t item);
void MacLO_Quit();
void MacLO_ToolBoxInit()
{
MaxApplZone();
@ -233,11 +236,22 @@ void MacLO_HandleGameMenuChoice(const int16_t item)
{
switch (item)
{
case NewMenuItemID:
case TitleMenuItemID:
GameWindow_SetScene(&gGameWindow, Title);
break;
case ClearMenuItemID:
GameWindow_ClearScores(&gGameWindow);
break;
case QuitMenuItemID:
gExitApp = true;
MacLO_Quit();
break;
}
}
void MacLO_Quit()
{
if (ShowConfirm("\pQuit MacLO?"))
{
gExitApp = true;
}
}

Binary file not shown.

Binary file not shown.

View File

@ -16,6 +16,8 @@
#define HalfStarScale 2
#define ScoreTextScale 1
void PlayScene_SetLightRect(const GameWindow *pGameWindow, Rect *pRect, const int8_t c, const int8_t r);
void PlayScene_Init(GameWindow *pGameWindow)
{
Rect r;
@ -49,7 +51,7 @@ void PlayScene_Init(GameWindow *pGameWindow)
CenterRect(&r, &(pGameWindow->PlayScene.HalfStarsRect));
// Setup score
Bitmaps_GetNumberRect(&(pGameWindow->Bitmaps), pGameWindow->Engine.Score, ScoreTextScale, &(pGameWindow->PlayScene.ScoreRect));
Bitmaps_GetNumberRect(&(pGameWindow->Bitmaps), GameEngine_GetTotalScore(&(pGameWindow->Engine)), 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);
@ -144,7 +146,7 @@ void PlayScene_Draw(const GameWindow *pGameWindow, bool fullRefresh)
if (fullRefresh)
{
MoveTo(pGameWindow->PlayScene.ScoreRect.left, pGameWindow->PlayScene.ScoreRect.top);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), pGameWindow->Engine.Score, ScoreTextScale);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), GameEngine_GetTotalScore(&(pGameWindow->Engine)), ScoreTextScale);
Bitmaps_DrawSlashChar(&(pGameWindow->Bitmaps), ScoreTextScale);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), PerfectScore, ScoreTextScale);
}
@ -187,6 +189,7 @@ void PlayScene_Click(GameWindow *pGameWindow, const Point *pPosition)
if (GameEngine_IsCompleted(&(pGameWindow->Engine)))
{
// Level was completed in the last click
GameEngine_CompleteLevel(&(pGameWindow->Engine));
GameWindow_Draw(pGameWindow, false);
GameWindow_SetScene(pGameWindow, LevelEnd);
Sounds_PlayDoneSnd(&(pGameWindow->Sounds));

View File

@ -9,6 +9,7 @@
typedef enum eSceneId
{
Title,
LevelSelect,
Play,
LevelEnd,
GameEnd
@ -22,6 +23,16 @@ typedef struct sTitleScene
Rect SoundButtonRect;
} TitleScene;
typedef struct sLevelSelectScene
{
int8_t PageNumber;
Rect SetRect;
Rect ScoreRect;
Rect PrevButtonRect;
Rect NextButtonRect;
Rect LevelGridRect;
} LevelSelectScene;
typedef struct sPlayScene
{
Rect PlayfieldRect;

View File

@ -14,7 +14,9 @@ void TitleScene_Init(GameWindow *pGameWindow)
// Setup Title
GetPictureRect(pGameWindow->Bitmaps.TitlePict, &(pGameWindow->TitleScene.TitleRect));
CenterRect(pContentRect, &(pGameWindow->TitleScene.TitleRect));
GetBoxRect(pContentRect, Center, &r);
GetBoxRect(&r, Top, &r);
CenterRect(&r, &(pGameWindow->TitleScene.TitleRect));
// Setup Set A
GetScaledPicFrame(pGameWindow->Bitmaps.ACharPict, TitleTextScale, &(pGameWindow->TitleScene.SetARect));
@ -55,12 +57,12 @@ void TitleScene_Click(GameWindow *pGameWindow, const Point *pPosition)
if (PtInRect(*pPosition, &(pGameWindow->TitleScene.SetARect)))
{
GameEngine_NewGame(&(pGameWindow->Engine), false);
GameWindow_SetScene(pGameWindow, Play);
GameWindow_SetScene(pGameWindow, LevelSelect);
}
else if (PtInRect(*pPosition, &(pGameWindow->TitleScene.SetBRect)))
{
GameEngine_NewGame(&(pGameWindow->Engine), true);
GameWindow_SetScene(pGameWindow, Play);
GameWindow_SetScene(pGameWindow, LevelSelect);
}
else if (PtInRect(*pPosition, &(pGameWindow->TitleScene.SoundButtonRect)))
{