mirror of https://github.com/jonthysell/MacLO.git
Refactored scenes into separate files, added game end, added title logo
This commit is contained in:
parent
866dadb28d
commit
66794a2241
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) Jon Thysell <http://jonthysell.com>
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "GameEndScene.h"
|
||||
|
||||
void GameEndScene_Init(GameWindow *pGameWindow)
|
||||
{
|
||||
}
|
||||
|
||||
void GameEndScene_Draw(const GameWindow *pGameWindow, bool fullRefresh)
|
||||
{
|
||||
Str255 scoreStr;
|
||||
|
||||
SetPort(pGameWindow->Window);
|
||||
|
||||
// TODO: Proper level end
|
||||
if (fullRefresh)
|
||||
{
|
||||
}
|
||||
|
||||
MoveTo(100, 100);
|
||||
DrawString("\pGame complete! Click to continue.");
|
||||
|
||||
MoveTo(100, 125);
|
||||
DrawString("\pScore: ");
|
||||
NumToString((long)(pGameWindow->Engine.Score), &scoreStr);
|
||||
DrawString(scoreStr);
|
||||
DrawString("\p/300");
|
||||
}
|
||||
|
||||
void GameEndScene_Click(GameWindow *pGameWindow, const Point *pPosition)
|
||||
{
|
||||
// TODO: Proper click handling
|
||||
|
||||
GameWindow_SetScene(pGameWindow, Title);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (c) Jon Thysell <http://jonthysell.com>
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#ifndef GAMEENDSCENE_H
|
||||
#define GAMEENDSCENE_H
|
||||
|
||||
#include "GameWindow.h"
|
||||
|
||||
void GameEndScene_Init(GameWindow *pGameWindow);
|
||||
void GameEndScene_Draw(const GameWindow *pGameWindow, bool fullRefresh);
|
||||
void GameEndScene_Click(GameWindow *pGameWindow, const Point *pPosition);
|
||||
|
||||
#endif
|
|
@ -37,7 +37,7 @@ void GameEngine_ResetLevel(GameEngine *pGameEngine)
|
|||
|
||||
void GameEngine_LoadLevel(GameEngine *pGameEngine, const int8_t level, const bool setB)
|
||||
{
|
||||
pGameEngine->Level = Levels_BoundLevel(level);
|
||||
pGameEngine->Level = level;
|
||||
pGameEngine->SetB = setB;
|
||||
pGameEngine->Lights = Levels_GetLightsForLevel(pGameEngine->Level, setB);
|
||||
pGameEngine->Par = Levels_GetParForLevel(pGameEngine->Level);
|
||||
|
@ -59,6 +59,11 @@ bool GameEngine_IsCompleted(const GameEngine *pGameEngine)
|
|||
return pGameEngine->Lights == 0;
|
||||
}
|
||||
|
||||
bool GameEngine_IsGameOver(const GameEngine *pGameEngine)
|
||||
{
|
||||
return pGameEngine->Level >= LevelCount;
|
||||
}
|
||||
|
||||
uint8_t GameEngine_GetHalfStars(const GameEngine *pGameEngine)
|
||||
{
|
||||
uint8_t halfStarsLost = pGameEngine->Moves <= pGameEngine->Par ? 0 : max(0, (1 + pGameEngine->Moves - pGameEngine->Par) / 2);
|
||||
|
|
|
@ -34,6 +34,8 @@ bool GameEngine_GetLight(const GameEngine *pGameEngine, const int8_t x, const in
|
|||
|
||||
bool GameEngine_IsCompleted(const GameEngine *pGameEngine);
|
||||
|
||||
bool GameEngine_IsGameOver(const GameEngine *pGameEngine);
|
||||
|
||||
uint8_t GameEngine_GetHalfStars(const GameEngine *pGameEngine);
|
||||
|
||||
void GameEngine_ToggleLights(GameEngine *pGameEngine, const int8_t x, const int8_t y);
|
||||
|
|
294
src/GameWindow.c
294
src/GameWindow.c
|
@ -2,16 +2,10 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
#include "GameWindow.h"
|
||||
|
||||
void GameWindow_SetLightRect(const GameWindow *pGameWindow, Rect *pRect, const int8_t c, const int8_t r);
|
||||
|
||||
void GameWindow_DrawTitleMode(const GameWindow *pGameWindow, bool fullRefresh);
|
||||
void GameWindow_DrawPlayMode(const GameWindow *pGameWindow, bool fullRefresh);
|
||||
void GameWindow_DrawLevelCompleteMode(const GameWindow *pGameWindow, bool fullRefresh);
|
||||
|
||||
void GameWindow_ClickTitleMode(GameWindow *pGameWindow, const Point *pPosition);
|
||||
void GameWindow_ClickPlayMode(GameWindow *pGameWindow, const Point *pPosition);
|
||||
void GameWindow_ClickLevelCompleteMode(GameWindow *pGameWindow, const Point *pPosition);
|
||||
#include "TitleScene.h"
|
||||
#include "PlayScene.h"
|
||||
#include "LevelEndScene.h"
|
||||
#include "GameEndScene.h"
|
||||
|
||||
void GameWindow_Init(GameWindow *pGameWindow)
|
||||
{
|
||||
|
@ -24,24 +18,10 @@ void GameWindow_Init(GameWindow *pGameWindow)
|
|||
|
||||
if (pGameWindow->Window == nil)
|
||||
{
|
||||
ShowError("\pGameWindow resource WIND BaseResID missing!", true);
|
||||
ShowError("\pGameWindow WIND resource missing!", true);
|
||||
}
|
||||
|
||||
pGameWindow->GameMode = Title;
|
||||
|
||||
// Setup rects
|
||||
pGameWindow->PlayfieldRect.top = PlayfieldMargin;
|
||||
pGameWindow->PlayfieldRect.bottom = pGameWindow->Window->portRect.bottom - PlayfieldMargin;
|
||||
pGameWindow->PlayfieldRect.left = pGameWindow->PlayfieldRect.top;
|
||||
pGameWindow->PlayfieldRect.right = pGameWindow->PlayfieldRect.bottom;
|
||||
|
||||
pGameWindow->HUDRect.top = HUDMargin;
|
||||
pGameWindow->HUDRect.bottom = pGameWindow->Window->portRect.bottom - HUDMargin;
|
||||
pGameWindow->HUDRect.left = pGameWindow->PlayfieldRect.right + HUDMargin;
|
||||
pGameWindow->HUDRect.right = pGameWindow->Window->portRect.right - HUDMargin;
|
||||
|
||||
// Load first level
|
||||
GameEngine_LoadLevel(&(pGameWindow->Engine), 0, false);
|
||||
GameWindow_SetScene(pGameWindow, Title);
|
||||
}
|
||||
|
||||
void GameWindow_Draw(const GameWindow *pGameWindow, bool fullRefresh)
|
||||
|
@ -56,245 +36,69 @@ void GameWindow_Draw(const GameWindow *pGameWindow, bool fullRefresh)
|
|||
FillRect(pContentRect, WindowPattern);
|
||||
}
|
||||
|
||||
switch (pGameWindow->GameMode)
|
||||
switch (pGameWindow->CurrentSceneId)
|
||||
{
|
||||
case Title:
|
||||
GameWindow_DrawTitleMode(pGameWindow, fullRefresh);
|
||||
TitleScene_Draw(pGameWindow, fullRefresh);
|
||||
break;
|
||||
case Play:
|
||||
GameWindow_DrawPlayMode(pGameWindow, fullRefresh);
|
||||
PlayScene_Draw(pGameWindow, fullRefresh);
|
||||
break;
|
||||
case LevelComplete:
|
||||
GameWindow_DrawLevelCompleteMode(pGameWindow, fullRefresh);
|
||||
case LevelEnd:
|
||||
LevelEndScene_Draw(pGameWindow, fullRefresh);
|
||||
break;
|
||||
case GameEnd:
|
||||
GameEndScene_Draw(pGameWindow, fullRefresh);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GameWindow_SetLightRect(const GameWindow *pGameWindow, Rect *pRect, const int8_t c, const int8_t r)
|
||||
void GameWindow_Click(GameWindow *pGameWindow, const Point *pPosition)
|
||||
{
|
||||
pRect->top = pGameWindow->PlayfieldRect.top + PlayfieldPadding + LightMargin + (r * (LightMargin + LightSize));
|
||||
pRect->bottom = pRect->top + LightSize;
|
||||
pRect->left = pGameWindow->PlayfieldRect.left + PlayfieldPadding + LightMargin + (c * (LightMargin + LightSize));
|
||||
pRect->right = pRect->left + LightSize;
|
||||
switch (pGameWindow->CurrentSceneId)
|
||||
{
|
||||
case Title:
|
||||
TitleScene_Click(pGameWindow, pPosition);
|
||||
break;
|
||||
case Play:
|
||||
PlayScene_Click(pGameWindow, pPosition);
|
||||
break;
|
||||
case LevelEnd:
|
||||
LevelEndScene_Click(pGameWindow, pPosition);
|
||||
break;
|
||||
case GameEnd:
|
||||
GameEndScene_Click(pGameWindow, pPosition);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GameWindow_DrawTitleMode(const GameWindow *pGameWindow, bool fullRefresh)
|
||||
void GameWindow_SetScene(GameWindow *pGameWindow, const SceneId sceneId)
|
||||
{
|
||||
SetPort(pGameWindow->Window);
|
||||
|
||||
// TODO: Proper title
|
||||
if (fullRefresh)
|
||||
GameWindow_Draw(pGameWindow, false);
|
||||
if (!(pGameWindow->SceneIsInitialized[sceneId]))
|
||||
{
|
||||
}
|
||||
|
||||
ForeColor(blackColor);
|
||||
TextFace(bold + outline);
|
||||
|
||||
MoveTo(100, 100);
|
||||
DrawString("\pMacLO! Click to continue.");
|
||||
|
||||
MoveTo(25, 200);
|
||||
DrawString("\pSet A.");
|
||||
|
||||
MoveTo(250, 200);
|
||||
DrawString("\pSet B.");
|
||||
}
|
||||
|
||||
void GameWindow_DrawPlayMode(const GameWindow *pGameWindow, bool fullRefresh)
|
||||
{
|
||||
int8_t r, c;
|
||||
Rect lightRect;
|
||||
Str255 levelStr, parStr, movesStr, halfStarsStr, scoreStr;
|
||||
|
||||
SetPort(pGameWindow->Window);
|
||||
|
||||
if (fullRefresh)
|
||||
{
|
||||
// Fill backgrounds
|
||||
FillRoundRect(&(pGameWindow->PlayfieldRect), PlayfieldCornerSize, PlayfieldCornerSize, PlayfieldPattern);
|
||||
FillRoundRect(&(pGameWindow->HUDRect), HUDCornerSize, HUDCornerSize, HUDPattern);
|
||||
}
|
||||
|
||||
// Draw Playfield
|
||||
|
||||
// Draw lights
|
||||
for (r = 0; r < PuzzleSize; r++)
|
||||
{
|
||||
for (c = 0; c < PuzzleSize; c++)
|
||||
switch (sceneId)
|
||||
{
|
||||
GameWindow_SetLightRect(pGameWindow, &lightRect, c, r);
|
||||
|
||||
if (GameEngine_GetLight(&(pGameWindow->Engine), c, r))
|
||||
{
|
||||
// Draw ON light
|
||||
FillRoundRect(&lightRect, LightCornerSize, LightCornerSize, white);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw OFF light
|
||||
FillRoundRect(&lightRect, LightCornerSize, LightCornerSize, black);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
// Draw HUD
|
||||
|
||||
ForeColor(blackColor);
|
||||
TextFace(bold + outline);
|
||||
|
||||
// Draw Level
|
||||
MoveTo(pGameWindow->HUDRect.left + 10, pGameWindow->HUDRect.top + 20);
|
||||
DrawString("\pLevel: ");
|
||||
NumToString(1L + pGameWindow->Engine.Level, &levelStr);
|
||||
DrawString(levelStr);
|
||||
DrawString("\p/50");
|
||||
|
||||
// Draw Par
|
||||
MoveTo(pGameWindow->HUDRect.left + 10, pGameWindow->HUDRect.top + 40);
|
||||
DrawString("\pPar: ");
|
||||
NumToString((long)(pGameWindow->Engine.Par), &parStr);
|
||||
DrawString(parStr);
|
||||
|
||||
// Draw Moves
|
||||
MoveTo(pGameWindow->HUDRect.left + 10, pGameWindow->HUDRect.top + 60);
|
||||
DrawString("\pMoves: ");
|
||||
NumToString((long)(pGameWindow->Engine.Moves), &movesStr);
|
||||
DrawString(movesStr);
|
||||
DrawString("\p/");
|
||||
DrawString(parStr);
|
||||
|
||||
// Draw Stars
|
||||
MoveTo(pGameWindow->HUDRect.left + 10, pGameWindow->HUDRect.top + 80);
|
||||
DrawString("\pStars: ");
|
||||
NumToString((long)GameEngine_GetHalfStars(&(pGameWindow->Engine)), &halfStarsStr);
|
||||
DrawString(halfStarsStr);
|
||||
DrawString("\p/6");
|
||||
|
||||
// Draw Score
|
||||
MoveTo(pGameWindow->HUDRect.left + 10, pGameWindow->HUDRect.top + 100);
|
||||
DrawString("\pScore: ");
|
||||
NumToString((long)(pGameWindow->Engine.Score), &scoreStr);
|
||||
DrawString(scoreStr);
|
||||
DrawString("\p/300");
|
||||
}
|
||||
|
||||
void GameWindow_DrawLevelCompleteMode(const GameWindow *pGameWindow, bool fullRefresh)
|
||||
{
|
||||
Str255 halfStarsStr;
|
||||
|
||||
SetPort(pGameWindow->Window);
|
||||
|
||||
// TODO: Proper level complete
|
||||
if (fullRefresh)
|
||||
{
|
||||
}
|
||||
|
||||
MoveTo(50, 100);
|
||||
DrawString("\pLevel complete! Click to continue.");
|
||||
|
||||
MoveTo(50, 125);
|
||||
DrawString("\pReceived ");
|
||||
NumToString((long)GameEngine_GetHalfStars(&(pGameWindow->Engine)), &halfStarsStr);
|
||||
DrawString(halfStarsStr);
|
||||
DrawString("\p/6 half-stars.");
|
||||
|
||||
MoveTo(25, 200);
|
||||
DrawString("\pRetry level.");
|
||||
|
||||
MoveTo(250, 200);
|
||||
DrawString("\pNext level.");
|
||||
pGameWindow->CurrentSceneId = sceneId;
|
||||
GameWindow_Draw(pGameWindow, true);
|
||||
}
|
||||
|
||||
void GameWindow_Show(const GameWindow *pGameWindow)
|
||||
{
|
||||
ShowWindow(pGameWindow->Window);
|
||||
}
|
||||
|
||||
void GameWindow_Click(GameWindow *pGameWindow, const Point *pPosition)
|
||||
{
|
||||
switch (pGameWindow->GameMode)
|
||||
{
|
||||
case Title:
|
||||
GameWindow_ClickTitleMode(pGameWindow, pPosition);
|
||||
break;
|
||||
case Play:
|
||||
GameWindow_ClickPlayMode(pGameWindow, pPosition);
|
||||
break;
|
||||
case LevelComplete:
|
||||
GameWindow_ClickLevelCompleteMode(pGameWindow, pPosition);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GameWindow_ClickTitleMode(GameWindow *pGameWindow, const Point *pPosition)
|
||||
{
|
||||
bool setB;
|
||||
|
||||
// TODO: Proper click handling
|
||||
|
||||
if (pPosition->h < ((pGameWindow->Window->portRect.right - pGameWindow->Window->portRect.left) / 2))
|
||||
{
|
||||
setB = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
setB = true;
|
||||
}
|
||||
|
||||
GameEngine_NewGame(&(pGameWindow->Engine), setB);
|
||||
pGameWindow->GameMode = Play;
|
||||
GameWindow_Draw(pGameWindow, true);
|
||||
}
|
||||
|
||||
void GameWindow_ClickPlayMode(GameWindow *pGameWindow, const Point *pPosition)
|
||||
{
|
||||
int8_t r, c;
|
||||
Rect lightRect;
|
||||
|
||||
if (PtInRect(*pPosition, &(pGameWindow->PlayfieldRect)))
|
||||
{
|
||||
// Click within Playfield
|
||||
for (r = 0; r < PuzzleSize; r++)
|
||||
{
|
||||
for (c = 0; c < PuzzleSize; c++)
|
||||
{
|
||||
GameWindow_SetLightRect(pGameWindow, &lightRect, c, r);
|
||||
|
||||
if (PtInRect(*pPosition, &lightRect))
|
||||
{
|
||||
GameEngine_ToggleLights(&(pGameWindow->Engine), c, r);
|
||||
GameWindow_Draw(pGameWindow, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GameEngine_IsCompleted(&(pGameWindow->Engine)))
|
||||
{
|
||||
// Level was completed in the last click
|
||||
pGameWindow->GameMode = LevelComplete;
|
||||
GameWindow_Draw(pGameWindow, true);
|
||||
}
|
||||
}
|
||||
else if (PtInRect(*pPosition, &(pGameWindow->HUDRect)))
|
||||
{
|
||||
// Click within HUD
|
||||
}
|
||||
}
|
||||
|
||||
void GameWindow_ClickLevelCompleteMode(GameWindow *pGameWindow, const Point *pPosition)
|
||||
{
|
||||
// TODO: Proper click handling
|
||||
|
||||
if (pPosition->h < ((pGameWindow->Window->portRect.right - pGameWindow->Window->portRect.left) / 2))
|
||||
{
|
||||
GameEngine_ResetLevel(&(pGameWindow->Engine));
|
||||
}
|
||||
else
|
||||
{
|
||||
GameEngine_NextLevel(&(pGameWindow->Engine));
|
||||
}
|
||||
|
||||
pGameWindow->GameMode = Play;
|
||||
GameWindow_Draw(pGameWindow, true);
|
||||
}
|
||||
|
|
|
@ -6,43 +6,25 @@
|
|||
|
||||
#include "MacCommon.h"
|
||||
#include "GameEngine.h"
|
||||
#include "Scenes.h"
|
||||
|
||||
#define WindowPattern black
|
||||
|
||||
#define PlayfieldMargin 4
|
||||
#define PlayfieldPadding 2
|
||||
#define PlayfieldCornerSize 12
|
||||
#define LightMargin 6
|
||||
#define LightSize 50
|
||||
#define LightCornerSize 8
|
||||
#define PlayfieldPattern ltGray
|
||||
|
||||
#define HUDMargin PlayfieldMargin
|
||||
#define HUDCornerSize PlayfieldCornerSize
|
||||
#define HUDPattern PlayfieldPattern
|
||||
|
||||
typedef enum GameMode
|
||||
{
|
||||
Title,
|
||||
Play,
|
||||
LevelComplete,
|
||||
GameComplete
|
||||
} GameMode;
|
||||
#define WindowPattern black
|
||||
|
||||
typedef struct GameWindow
|
||||
{
|
||||
WindowPtr Window;
|
||||
GameEngine Engine;
|
||||
GameMode GameMode;
|
||||
Rect PlayfieldRect;
|
||||
Rect HUDRect;
|
||||
SceneId CurrentSceneId;
|
||||
bool SceneIsInitialized[NumScenes];
|
||||
TitleScene TitleScene;
|
||||
PlayScene PlayScene;
|
||||
} GameWindow;
|
||||
|
||||
void GameWindow_Init(GameWindow *pGameWindow);
|
||||
|
||||
void GameWindow_Draw(const GameWindow *pGameWindow, bool fullRefresh);
|
||||
void GameWindow_Show(const GameWindow *pGameWindow);
|
||||
|
||||
void GameWindow_Click(GameWindow *pGameWindow, const Point *pPosition);
|
||||
|
||||
void GameWindow_SetScene(GameWindow *pGameWindow, const SceneId sceneId);
|
||||
void GameWindow_Show(const GameWindow *pGameWindow);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
// Copyright (c) Jon Thysell <http://jonthysell.com>
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "LevelEndScene.h"
|
||||
|
||||
void LevelEndScene_Init(GameWindow *pGameWindow)
|
||||
{
|
||||
}
|
||||
|
||||
void LevelEndScene_Draw(const GameWindow *pGameWindow, bool fullRefresh)
|
||||
{
|
||||
Str255 halfStarsStr;
|
||||
|
||||
SetPort(pGameWindow->Window);
|
||||
|
||||
// TODO: Proper level end
|
||||
if (fullRefresh)
|
||||
{
|
||||
}
|
||||
|
||||
MoveTo(100, 100);
|
||||
DrawString("\pLevel complete! Click to continue.");
|
||||
|
||||
MoveTo(100, 125);
|
||||
DrawString("\pReceived ");
|
||||
NumToString((long)GameEngine_GetHalfStars(&(pGameWindow->Engine)), &halfStarsStr);
|
||||
DrawString(halfStarsStr);
|
||||
DrawString("\p/6 half-stars.");
|
||||
|
||||
MoveTo(100, 200);
|
||||
DrawString("\pRetry level.");
|
||||
|
||||
MoveTo(350, 200);
|
||||
DrawString("\pNext level.");
|
||||
}
|
||||
|
||||
void LevelEndScene_Click(GameWindow *pGameWindow, const Point *pPosition)
|
||||
{
|
||||
// TODO: Proper click handling
|
||||
|
||||
if (pPosition->h < ((pGameWindow->Window->portRect.right - pGameWindow->Window->portRect.left) / 2))
|
||||
{
|
||||
GameEngine_ResetLevel(&(pGameWindow->Engine));
|
||||
}
|
||||
else
|
||||
{
|
||||
GameEngine_NextLevel(&(pGameWindow->Engine));
|
||||
}
|
||||
|
||||
GameWindow_SetScene(pGameWindow, GameEngine_IsGameOver(&(pGameWindow->Engine)) ? GameEnd : Play);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (c) Jon Thysell <http://jonthysell.com>
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#ifndef LEVELENDSCENE_H
|
||||
#define LEVELENDSCENE_H
|
||||
|
||||
#include "GameWindow.h"
|
||||
|
||||
void LevelEndScene_Init(GameWindow *pGameWindow);
|
||||
void LevelEndScene_Draw(const GameWindow *pGameWindow, bool fullRefresh);
|
||||
void LevelEndScene_Click(GameWindow *pGameWindow, const Point *pPosition);
|
||||
|
||||
#endif
|
21
src/Levels.c
21
src/Levels.c
|
@ -24,19 +24,22 @@ const uint32_t Levels_LightsB[] = {
|
|||
0x1151151UL, 0x1F27C9FUL, 0x1F711DFUL, 0x04AFEA4UL, 0x1FFFFFFUL,
|
||||
};
|
||||
|
||||
int8_t Levels_BoundLevel(const int8_t level)
|
||||
{
|
||||
return max(level, 0) % LevelCount;
|
||||
}
|
||||
|
||||
uint32_t Levels_GetLightsForLevel(const int8_t level, const bool setB)
|
||||
{
|
||||
int8_t bLevel = Levels_BoundLevel(level);
|
||||
return setB ? Levels_LightsB[bLevel] : Levels_LightsA[bLevel];
|
||||
if (level >= 0 && level < LevelCount)
|
||||
{
|
||||
return setB ? Levels_LightsB[level] : Levels_LightsA[level];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t Levels_GetParForLevel(const int8_t level)
|
||||
{
|
||||
return 6 + (Levels_BoundLevel(level) / 5);
|
||||
if (level >= 0 && level < LevelCount)
|
||||
{
|
||||
return 6 + (level / 5);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
|
||||
extern const int8_t LevelCount;
|
||||
|
||||
int8_t Levels_BoundLevel(const int8_t level);
|
||||
|
||||
uint32_t Levels_GetLightsForLevel(const int8_t level, const bool setB);
|
||||
|
||||
uint16_t Levels_GetParForLevel(const int8_t level);
|
||||
|
|
|
@ -13,3 +13,21 @@ void ShowError(Str255 message, Boolean isFatal)
|
|||
ExitToShell();
|
||||
}
|
||||
}
|
||||
|
||||
void CenterRect(const Rect *pOuterRect, Rect *pInnerRect)
|
||||
{
|
||||
CenterRectH(pOuterRect, pInnerRect);
|
||||
CenterRectV(pOuterRect, pInnerRect);
|
||||
}
|
||||
|
||||
void CenterRectH(const Rect *pOuterRect, Rect *pInnerRect)
|
||||
{
|
||||
OffsetRect(pInnerRect, pOuterRect->left - pInnerRect->left, 0);
|
||||
OffsetRect(pInnerRect, (pOuterRect->right - pInnerRect->right) / 2, 0);
|
||||
}
|
||||
|
||||
void CenterRectV(const Rect *pOuterRect, Rect *pInnerRect)
|
||||
{
|
||||
OffsetRect(pInnerRect, 0, pOuterRect->top - pInnerRect->top);
|
||||
OffsetRect(pInnerRect, 0, (pOuterRect->bottom - pInnerRect->bottom) / 2);
|
||||
}
|
|
@ -16,4 +16,8 @@ pascal OSErr SetDialogDefaultItem(DialogPtr theDialog, short newItem) = { 0x303C
|
|||
|
||||
void ShowError(Str255 message, Boolean isFatal);
|
||||
|
||||
void CenterRect(const Rect *pOuterRect, Rect *pInnerRect);
|
||||
void CenterRectH(const Rect *pOuterRect, Rect *pInnerRect);
|
||||
void CenterRectV(const Rect *pOuterRect, Rect *pInnerRect);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
#define AboutMenuItemID 1
|
||||
|
||||
#define GameMenuResID BaseResID+1
|
||||
#define QuitMenuItemID 1
|
||||
#define NewMenuItemID 1
|
||||
#define QuitMenuItemID 3
|
||||
|
||||
#define AboutDialogResID BaseResID
|
||||
#define AboutDialogOKID 1
|
||||
|
@ -228,6 +229,9 @@ void MacLO_HandleGameMenuChoice(const short item)
|
|||
{
|
||||
switch (item)
|
||||
{
|
||||
case NewMenuItemID:
|
||||
GameWindow_SetScene(&gGameWindow, Title);
|
||||
break;
|
||||
case QuitMenuItemID:
|
||||
gExitApp = true;
|
||||
break;
|
||||
|
|
BIN
src/MacLO.pi.bin
BIN
src/MacLO.pi.bin
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,151 @@
|
|||
// Copyright (c) Jon Thysell <http://jonthysell.com>
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "PlayScene.h"
|
||||
|
||||
#define PlayfieldMargin 4
|
||||
#define PlayfieldPadding 2
|
||||
#define PlayfieldCornerSize 12
|
||||
#define LightMargin 6
|
||||
#define LightSize 50
|
||||
#define LightCornerSize 8
|
||||
#define PlayfieldPattern ltGray
|
||||
|
||||
#define HUDMargin PlayfieldMargin
|
||||
#define HUDCornerSize PlayfieldCornerSize
|
||||
#define HUDPattern PlayfieldPattern
|
||||
|
||||
void PlayScene_Init(GameWindow *pGameWindow)
|
||||
{
|
||||
// Setup rects
|
||||
pGameWindow->PlayScene.PlayfieldRect.top = PlayfieldMargin;
|
||||
pGameWindow->PlayScene.PlayfieldRect.bottom = pGameWindow->Window->portRect.bottom - PlayfieldMargin;
|
||||
pGameWindow->PlayScene.PlayfieldRect.left = pGameWindow->PlayScene.PlayfieldRect.top;
|
||||
pGameWindow->PlayScene.PlayfieldRect.right = pGameWindow->PlayScene.PlayfieldRect.bottom;
|
||||
|
||||
pGameWindow->PlayScene.HUDRect.top = HUDMargin;
|
||||
pGameWindow->PlayScene.HUDRect.bottom = pGameWindow->Window->portRect.bottom - HUDMargin;
|
||||
pGameWindow->PlayScene.HUDRect.left = pGameWindow->PlayScene.PlayfieldRect.right + HUDMargin;
|
||||
pGameWindow->PlayScene.HUDRect.right = pGameWindow->Window->portRect.right - HUDMargin;
|
||||
}
|
||||
|
||||
void PlayScene_SetLightRect(const GameWindow *pGameWindow, Rect *pRect, const int8_t c, const int8_t r)
|
||||
{
|
||||
pRect->top = pGameWindow->PlayScene.PlayfieldRect.top + PlayfieldPadding + LightMargin + (r * (LightMargin + LightSize));
|
||||
pRect->bottom = pRect->top + LightSize;
|
||||
pRect->left = pGameWindow->PlayScene.PlayfieldRect.left + PlayfieldPadding + LightMargin + (c * (LightMargin + LightSize));
|
||||
pRect->right = pRect->left + LightSize;
|
||||
}
|
||||
|
||||
void PlayScene_Draw(const GameWindow *pGameWindow, bool fullRefresh)
|
||||
{
|
||||
int8_t r, c;
|
||||
Rect lightRect;
|
||||
Str255 levelStr, parStr, movesStr, halfStarsStr, scoreStr;
|
||||
|
||||
SetPort(pGameWindow->Window);
|
||||
|
||||
if (fullRefresh)
|
||||
{
|
||||
// Fill backgrounds
|
||||
FillRoundRect(&(pGameWindow->PlayScene.PlayfieldRect), PlayfieldCornerSize, PlayfieldCornerSize, PlayfieldPattern);
|
||||
FillRoundRect(&(pGameWindow->PlayScene.HUDRect), HUDCornerSize, HUDCornerSize, HUDPattern);
|
||||
}
|
||||
|
||||
// Draw Playfield
|
||||
|
||||
// Draw lights
|
||||
for (r = 0; r < PuzzleSize; r++)
|
||||
{
|
||||
for (c = 0; c < PuzzleSize; c++)
|
||||
{
|
||||
PlayScene_SetLightRect(pGameWindow, &lightRect, c, r);
|
||||
|
||||
if (GameEngine_GetLight(&(pGameWindow->Engine), c, r))
|
||||
{
|
||||
// Draw ON light
|
||||
FillRoundRect(&lightRect, LightCornerSize, LightCornerSize, white);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw OFF light
|
||||
FillRoundRect(&lightRect, LightCornerSize, LightCornerSize, black);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw HUD
|
||||
|
||||
ForeColor(blackColor);
|
||||
TextFace(bold + outline);
|
||||
|
||||
// Draw Level
|
||||
MoveTo(pGameWindow->PlayScene.HUDRect.left + 10, pGameWindow->PlayScene.HUDRect.top + 20);
|
||||
DrawString("\pLevel: ");
|
||||
NumToString(1L + pGameWindow->Engine.Level, &levelStr);
|
||||
DrawString(levelStr);
|
||||
DrawString("\p/50");
|
||||
|
||||
// Draw Par
|
||||
MoveTo(pGameWindow->PlayScene.HUDRect.left + 10, pGameWindow->PlayScene.HUDRect.top + 40);
|
||||
DrawString("\pPar: ");
|
||||
NumToString((long)(pGameWindow->Engine.Par), &parStr);
|
||||
DrawString(parStr);
|
||||
|
||||
// Draw Moves
|
||||
MoveTo(pGameWindow->PlayScene.HUDRect.left + 10, pGameWindow->PlayScene.HUDRect.top + 60);
|
||||
DrawString("\pMoves: ");
|
||||
NumToString((long)(pGameWindow->Engine.Moves), &movesStr);
|
||||
DrawString(movesStr);
|
||||
DrawString("\p/");
|
||||
DrawString(parStr);
|
||||
|
||||
// Draw Stars
|
||||
MoveTo(pGameWindow->PlayScene.HUDRect.left + 10, pGameWindow->PlayScene.HUDRect.top + 80);
|
||||
DrawString("\pStars: ");
|
||||
NumToString((long)GameEngine_GetHalfStars(&(pGameWindow->Engine)), &halfStarsStr);
|
||||
DrawString(halfStarsStr);
|
||||
DrawString("\p/6");
|
||||
|
||||
// Draw Score
|
||||
MoveTo(pGameWindow->PlayScene.HUDRect.left + 10, pGameWindow->PlayScene.HUDRect.top + 100);
|
||||
DrawString("\pScore: ");
|
||||
NumToString((long)(pGameWindow->Engine.Score), &scoreStr);
|
||||
DrawString(scoreStr);
|
||||
DrawString("\p/300");
|
||||
}
|
||||
|
||||
void PlayScene_Click(GameWindow *pGameWindow, const Point *pPosition)
|
||||
{
|
||||
int8_t r, c;
|
||||
Rect lightRect;
|
||||
|
||||
if (PtInRect(*pPosition, &(pGameWindow->PlayScene.PlayfieldRect)))
|
||||
{
|
||||
// Click within Playfield
|
||||
for (r = 0; r < PuzzleSize; r++)
|
||||
{
|
||||
for (c = 0; c < PuzzleSize; c++)
|
||||
{
|
||||
PlayScene_SetLightRect(pGameWindow, &lightRect, c, r);
|
||||
|
||||
if (PtInRect(*pPosition, &lightRect))
|
||||
{
|
||||
GameEngine_ToggleLights(&(pGameWindow->Engine), c, r);
|
||||
GameWindow_Draw(pGameWindow, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GameEngine_IsCompleted(&(pGameWindow->Engine)))
|
||||
{
|
||||
// Level was completed in the last click
|
||||
GameWindow_SetScene(pGameWindow, LevelEnd);
|
||||
}
|
||||
}
|
||||
else if (PtInRect(*pPosition, &(pGameWindow->PlayScene.HUDRect)))
|
||||
{
|
||||
// Click within HUD
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (c) Jon Thysell <http://jonthysell.com>
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#ifndef PLAYSCENE_H
|
||||
#define PLAYSCENE_H
|
||||
|
||||
#include "GameWindow.h"
|
||||
|
||||
void PlayScene_Init(GameWindow *pGameWindow);
|
||||
void PlayScene_Draw(const GameWindow *pGameWindow, bool fullRefresh);
|
||||
void PlayScene_Click(GameWindow *pGameWindow, const Point *pPosition);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright (c) Jon Thysell <http://jonthysell.com>
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#ifndef SCENES_H
|
||||
#define SCENES_H
|
||||
|
||||
#define NumScenes 4
|
||||
|
||||
typedef enum SceneId
|
||||
{
|
||||
Title,
|
||||
Play,
|
||||
LevelEnd,
|
||||
GameEnd
|
||||
} SceneId;
|
||||
|
||||
typedef struct TitleScene
|
||||
{
|
||||
PicHandle TitlePict;
|
||||
Rect TitleRect;
|
||||
} TitleScene;
|
||||
|
||||
typedef struct PlayScene
|
||||
{
|
||||
Rect PlayfieldRect;
|
||||
Rect HUDRect;
|
||||
} PlayScene;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,64 @@
|
|||
// Copyright (c) Jon Thysell <http://jonthysell.com>
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "TitleScene.h"
|
||||
|
||||
#define TitlePictResID BaseResID
|
||||
|
||||
void TitleScene_Init(GameWindow *pGameWindow)
|
||||
{
|
||||
const Rect *pContentRect = &(pGameWindow->Window->portRect);
|
||||
|
||||
pGameWindow->TitleScene.TitlePict = GetPicture(TitlePictResID);
|
||||
|
||||
if (pGameWindow->TitleScene.TitlePict == nil)
|
||||
{
|
||||
ShowError("\pTitle PICT resource missing!", true);
|
||||
}
|
||||
|
||||
// Setup rects
|
||||
pGameWindow->TitleScene.TitleRect = (**(pGameWindow->TitleScene.TitlePict)).picFrame;
|
||||
CenterRect(pContentRect, &(pGameWindow->TitleScene.TitleRect));
|
||||
}
|
||||
|
||||
void TitleScene_Draw(const GameWindow *pGameWindow, bool fullRefresh)
|
||||
{
|
||||
SetPort(pGameWindow->Window);
|
||||
|
||||
// TODO: Proper title
|
||||
if (fullRefresh)
|
||||
{
|
||||
}
|
||||
|
||||
// Draw Title PICT
|
||||
DrawPicture(pGameWindow->TitleScene.TitlePict, &(pGameWindow->TitleScene.TitleRect));
|
||||
|
||||
ForeColor(blackColor);
|
||||
TextFace(bold + outline);
|
||||
|
||||
MoveTo(100, pGameWindow->TitleScene.TitleRect.bottom + 30);
|
||||
DrawString("\pSet A");
|
||||
|
||||
MoveTo(350, pGameWindow->TitleScene.TitleRect.bottom + 30);
|
||||
DrawString("\pSet B");
|
||||
}
|
||||
|
||||
void TitleScene_Click(GameWindow *pGameWindow, const Point *pPosition)
|
||||
{
|
||||
bool setB;
|
||||
|
||||
// TODO: Proper click handling
|
||||
|
||||
if (pPosition->h < ((pGameWindow->Window->portRect.right - pGameWindow->Window->portRect.left) / 2))
|
||||
{
|
||||
setB = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
setB = true;
|
||||
}
|
||||
|
||||
GameEngine_NewGame(&(pGameWindow->Engine), setB);
|
||||
|
||||
GameWindow_SetScene(pGameWindow, Play);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (c) Jon Thysell <http://jonthysell.com>
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#ifndef TITLESCENE_H
|
||||
#define TITLESCENE_H
|
||||
|
||||
#include "GameWindow.h"
|
||||
|
||||
void TitleScene_Init(GameWindow *pGameWindow);
|
||||
void TitleScene_Draw(const GameWindow *pGameWindow, bool fullRefresh);
|
||||
void TitleScene_Click(GameWindow *pGameWindow, const Point *pPosition);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue