mirror of
https://github.com/jonthysell/MacLO.git
synced 2025-02-06 16:30:04 +00:00
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:
parent
206284b71d
commit
3542861603
BIN
assets/prev.gif
Normal file
BIN
assets/prev.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 85 B |
@ -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)
|
||||
|
@ -17,6 +17,7 @@ typedef struct sBitmaps
|
||||
PicHandle BCharPict;
|
||||
PicHandle SlashCharPict;
|
||||
PicHandle StarPicts[StarPictCount];
|
||||
PicHandle PrevButtonPict;
|
||||
PicHandle NextButtonPict;
|
||||
PicHandle RetryButtonPict;
|
||||
PicHandle SoundOffPict;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
206
src/LevelSelectScene.c
Normal 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
13
src/LevelSelectScene.h
Normal 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
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
22
src/MacLO.c
22
src/MacLO.c
@ -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;
|
||||
}
|
||||
}
|
||||
|
BIN
src/MacLO.pi.bin
BIN
src/MacLO.pi.bin
Binary file not shown.
Binary file not shown.
@ -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));
|
||||
|
11
src/Scenes.h
11
src/Scenes.h
@ -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;
|
||||
|
@ -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)))
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user