Added sound menu item and other optimizations

* Added sound menu which keeps in sync with pressing sound button
* Changed navigation behavior between scenes to go straight to next
  level if it hasn't been beaten, otherwise return to level select
  so the player can view their progress in the set
* More drawing optimizations
This commit is contained in:
Jon Thysell 2021-12-16 12:57:00 -08:00
parent cdf67289a9
commit e4cb9a7af8
15 changed files with 220 additions and 92 deletions

View File

@ -46,23 +46,29 @@ void GameEndScene_Init(GameWindow *pGameWindow)
void GameEndScene_Draw(const GameWindow *pGameWindow, bool fullRefresh) void GameEndScene_Draw(const GameWindow *pGameWindow, bool fullRefresh)
{ {
// Draw set // Draw set
MoveTo(pGameWindow->GameEndScene.SetRect.left, pGameWindow->GameEndScene.SetRect.top); if (fullRefresh)
DrawScaledPic(pGameWindow->Bitmaps.StarPicts[StarPictCount - 1], SetTextScale);
if (pGameWindow->Engine.SetB)
{ {
Bitmaps_DrawBChar(&(pGameWindow->Bitmaps), SetTextScale); MoveTo(pGameWindow->GameEndScene.SetRect.left, pGameWindow->GameEndScene.SetRect.top);
DrawScaledPic(pGameWindow->Bitmaps.StarPicts[StarPictCount - 1], SetTextScale);
if (pGameWindow->Engine.SetB)
{
Bitmaps_DrawBChar(&(pGameWindow->Bitmaps), SetTextScale);
}
else
{
Bitmaps_DrawAChar(&(pGameWindow->Bitmaps), SetTextScale);
}
DrawScaledPic(pGameWindow->Bitmaps.StarPicts[StarPictCount - 1], SetTextScale);
} }
else
{
Bitmaps_DrawAChar(&(pGameWindow->Bitmaps), SetTextScale);
}
DrawScaledPic(pGameWindow->Bitmaps.StarPicts[StarPictCount - 1], SetTextScale);
// Draw score // Draw score
MoveTo(pGameWindow->GameEndScene.ScoreRect.left, pGameWindow->GameEndScene.ScoreRect.top); if (fullRefresh)
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), GameEngine_GetTotalScore(&(pGameWindow->Engine)), ScoreTextScale); {
Bitmaps_DrawSlashChar(&(pGameWindow->Bitmaps), ScoreTextScale); MoveTo(pGameWindow->GameEndScene.ScoreRect.left, pGameWindow->GameEndScene.ScoreRect.top);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), PerfectScore, ScoreTextScale); Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), GameEngine_GetTotalScore(&(pGameWindow->Engine)), ScoreTextScale);
Bitmaps_DrawSlashChar(&(pGameWindow->Bitmaps), ScoreTextScale);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), PerfectScore, ScoreTextScale);
}
} }
void GameEndScene_Click(GameWindow *pGameWindow, const Point *pPosition) void GameEndScene_Click(GameWindow *pGameWindow, const Point *pPosition)

View File

@ -7,8 +7,8 @@
* This file provides implementations for GameEngine.h. * This file provides implementations for GameEngine.h.
*/ */
#include "Common.h"
#include "GameEngine.h" #include "GameEngine.h"
#include "Common.h"
const int8_t PuzzleSize = 5; const int8_t PuzzleSize = 5;
@ -62,22 +62,8 @@ void GameEngine_Init(GameEngine *pGameEngine)
void GameEngine_NewGame(GameEngine *pGameEngine, const bool setB) void GameEngine_NewGame(GameEngine *pGameEngine, const bool setB)
{ {
int8_t level, startLevel;
pGameEngine->SetB = setB; pGameEngine->SetB = setB;
GameEngine_StartLevel(pGameEngine, 0);
startLevel = 0;
for (level = 0; level < LevelCount; level++)
{
// Find the first uncompleted level
if (GameEngine_GetScore(pGameEngine, level) == 0)
{
startLevel = level;
break;
}
}
GameEngine_StartLevel(pGameEngine, startLevel);
} }
void GameEngine_ResetGame(GameEngine *pGameEngine) void GameEngine_ResetGame(GameEngine *pGameEngine)
@ -115,7 +101,7 @@ void GameEngine_NextLevel(GameEngine *pGameEngine)
{ {
if (GameEngine_IsCompleted(pGameEngine)) if (GameEngine_IsCompleted(pGameEngine))
{ {
GameEngine_StartLevel(pGameEngine, pGameEngine->Level + 1); GameEngine_StartLevel(pGameEngine, (pGameEngine->Level + 1) % LevelCount);
} }
} }
@ -146,7 +132,7 @@ bool GameEngine_GetLight(const GameEngine *pGameEngine, const int8_t x, const in
bool GameEngine_IsEnabled(const GameEngine *pGameEngine, const int8_t level) bool GameEngine_IsEnabled(const GameEngine *pGameEngine, const int8_t level)
{ {
return level == 0 || (level < LevelCount && GameEngine_GetScore(pGameEngine, level - 1) > 0); return level == 0 || (level < LevelCount && GameEngine_HasPlayedLevel(pGameEngine, level - 1));
} }
bool GameEngine_IsCompleted(const GameEngine *pGameEngine) bool GameEngine_IsCompleted(const GameEngine *pGameEngine)
@ -154,9 +140,14 @@ bool GameEngine_IsCompleted(const GameEngine *pGameEngine)
return pGameEngine->Lights == 0; return pGameEngine->Lights == 0;
} }
bool GameEngine_IsGameOver(const GameEngine *pGameEngine) bool GameEngine_IsLastLevel(const GameEngine *pGameEngine)
{ {
return pGameEngine->Level >= LevelCount; return pGameEngine->Level == LevelCount - 1;
}
bool GameEngine_HasPlayedLevel(const GameEngine *pGameEngine, const int8_t level)
{
return GameEngine_GetScore(pGameEngine, level) > 0;
} }
uint8_t GameEngine_GetHalfStars(const GameEngine *pGameEngine) uint8_t GameEngine_GetHalfStars(const GameEngine *pGameEngine)

View File

@ -110,11 +110,19 @@ bool GameEngine_IsCompleted(const GameEngine *pGameEngine);
bool GameEngine_IsEnabled(const GameEngine *pGameEngine, const int8_t level); bool GameEngine_IsEnabled(const GameEngine *pGameEngine, const int8_t level);
/** /**
* Gets whether or not the last level has just been completed. * Gets whether the current level is the last of a set.
* @param pGameEngine The GameEngine. * @param pGameEngine The GameEngine.
* @return Whether or not the game is over. * @return Whether the current level is the last of a set.
*/ */
bool GameEngine_IsGameOver(const GameEngine *pGameEngine); bool GameEngine_IsLastLevel(const GameEngine *pGameEngine);
/**
* Gets whether the given level has been completed before.
* @param pGameEngine The GameEngine.
* @param level The level.
* @return Whether the given level has been completed before.
*/
bool GameEngine_HasPlayedLevel(const GameEngine *pGameEngine, const int8_t level);
/** /**
* Gets the number of half-stars the user stands to earn given the current * Gets the number of half-stars the user stands to earn given the current

View File

@ -8,6 +8,7 @@
*/ */
#include "GameWindow.h" #include "GameWindow.h"
#include "MacLO.h"
#include "TitleScene.h" #include "TitleScene.h"
#include "LevelSelectScene.h" #include "LevelSelectScene.h"
#include "PlayScene.h" #include "PlayScene.h"
@ -145,6 +146,13 @@ void GameWindow_Show(const GameWindow *pGameWindow)
ShowWindow(pGameWindow->Window); ShowWindow(pGameWindow->Window);
} }
void GameWindow_ToggleSound(GameWindow *pGameWindow)
{
pGameWindow->Sounds.Enabled = !pGameWindow->Sounds.Enabled;
MacLO_UpdateMenus();
GameWindow_Draw(pGameWindow, false);
}
void GameWindow_ClearScores(GameWindow *pGameWindow) void GameWindow_ClearScores(GameWindow *pGameWindow)
{ {
if (ShowConfirm("\pAre you sure you want to clear all scores?")) if (ShowConfirm("\pAre you sure you want to clear all scores?"))

View File

@ -75,6 +75,12 @@ void GameWindow_SetScene(GameWindow *pGameWindow, const SceneId sceneId);
*/ */
void GameWindow_Show(const GameWindow *pGameWindow); void GameWindow_Show(const GameWindow *pGameWindow);
/**
* Toggles whether sound is enabled/disabled for the GameWindow.
* @param pGameWindow The GameWindow.
*/
void GameWindow_ToggleSound(GameWindow *pGameWindow);
/** /**
* Resets the level scores of the GameWindow. * Resets the level scores of the GameWindow.
* @param pGameWindow The GameWindow. * @param pGameWindow The GameWindow.

View File

@ -64,54 +64,83 @@ void LevelEndScene_Init(GameWindow *pGameWindow)
void LevelEndScene_Draw(const GameWindow *pGameWindow, bool fullRefresh) void LevelEndScene_Draw(const GameWindow *pGameWindow, bool fullRefresh)
{ {
// Draw level // Draw level
MoveTo(pGameWindow->LevelEndScene.LevelRect.left, pGameWindow->LevelEndScene.LevelRect.top); if (fullRefresh)
if (pGameWindow->Engine.SetB)
{ {
Bitmaps_DrawBChar(&(pGameWindow->Bitmaps), LevelTextScale); MoveTo(pGameWindow->LevelEndScene.LevelRect.left, pGameWindow->LevelEndScene.LevelRect.top);
if (pGameWindow->Engine.SetB)
{
Bitmaps_DrawBChar(&(pGameWindow->Bitmaps), LevelTextScale);
}
else
{
Bitmaps_DrawAChar(&(pGameWindow->Bitmaps), LevelTextScale);
}
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), 1 + pGameWindow->Engine.Level, LevelTextScale);
} }
else
{
Bitmaps_DrawAChar(&(pGameWindow->Bitmaps), LevelTextScale);
}
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), 1 + pGameWindow->Engine.Level, LevelTextScale);
// Draw half-stars // Draw half-stars
MoveTo(pGameWindow->LevelEndScene.HalfStarsRect.left, pGameWindow->LevelEndScene.HalfStarsRect.top); if (fullRefresh)
Bitmaps_DrawHalfStars(&(pGameWindow->Bitmaps), GameEngine_GetHalfStars(&(pGameWindow->Engine)), MaxStars, HalfStarScale); {
MoveTo(pGameWindow->LevelEndScene.HalfStarsRect.left, pGameWindow->LevelEndScene.HalfStarsRect.top);
Bitmaps_DrawHalfStars(&(pGameWindow->Bitmaps), GameEngine_GetHalfStars(&(pGameWindow->Engine)), MaxStars, HalfStarScale);
}
// Draw score // Draw score
MoveTo(pGameWindow->LevelEndScene.ScoreRect.left, pGameWindow->LevelEndScene.ScoreRect.top); if (fullRefresh)
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), GameEngine_GetTotalScore(&(pGameWindow->Engine)), ScoreTextScale); {
Bitmaps_DrawSlashChar(&(pGameWindow->Bitmaps), ScoreTextScale); MoveTo(pGameWindow->LevelEndScene.ScoreRect.left, pGameWindow->LevelEndScene.ScoreRect.top);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), PerfectScore, ScoreTextScale); Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), GameEngine_GetTotalScore(&(pGameWindow->Engine)), ScoreTextScale);
Bitmaps_DrawSlashChar(&(pGameWindow->Bitmaps), ScoreTextScale);
Bitmaps_DrawNumber(&(pGameWindow->Bitmaps), PerfectScore, ScoreTextScale);
}
// Draw retry button // Draw retry button
DrawPicture(pGameWindow->Bitmaps.RetryButtonPict, &(pGameWindow->LevelEndScene.RetryButtonRect)); if (fullRefresh)
{
DrawPicture(pGameWindow->Bitmaps.RetryButtonPict, &(pGameWindow->LevelEndScene.RetryButtonRect));
}
// Draw next button // Draw next button
DrawPicture(pGameWindow->Bitmaps.NextButtonPict, &(pGameWindow->LevelEndScene.NextButtonRect)); if (fullRefresh)
{
DrawPicture(pGameWindow->Bitmaps.NextButtonPict, &(pGameWindow->LevelEndScene.NextButtonRect));
}
} }
void LevelEndScene_Click(GameWindow *pGameWindow, const Point *pPosition) void LevelEndScene_Click(GameWindow *pGameWindow, const Point *pPosition)
{ {
if (PtInRect(*pPosition, &(pGameWindow->LevelEndScene.RetryButtonRect))) if (PtInRect(*pPosition, &(pGameWindow->LevelEndScene.RetryButtonRect)))
{ {
// Clicked on retry button
GameEngine_ResetLevel(&(pGameWindow->Engine)); GameEngine_ResetLevel(&(pGameWindow->Engine));
GameWindow_SetScene(pGameWindow, Play); GameWindow_SetScene(pGameWindow, Play);
Sounds_PlayRetrySnd(&(pGameWindow->Sounds)); Sounds_PlayRetrySnd(&(pGameWindow->Sounds));
} }
else if (PtInRect(*pPosition, &(pGameWindow->LevelEndScene.NextButtonRect))) else if (PtInRect(*pPosition, &(pGameWindow->LevelEndScene.NextButtonRect)))
{ {
GameEngine_NextLevel(&(pGameWindow->Engine)); // Clicked on next button
if (GameEngine_IsLastLevel(&(pGameWindow->Engine)))
if (GameEngine_IsGameOver(&(pGameWindow->Engine)))
{ {
// Finished the last level, go to game end scene
GameWindow_SetScene(pGameWindow, GameEnd); GameWindow_SetScene(pGameWindow, GameEnd);
Sounds_PlayDoneSnd(&(pGameWindow->Sounds)); Sounds_PlayDoneSnd(&(pGameWindow->Sounds));
} }
else else
{ {
GameWindow_SetScene(pGameWindow, Play); if (GameEngine_HasPlayedLevel(&(pGameWindow->Engine), pGameWindow->Engine.Level + 1))
{
// Next level has been played before, assume they're
// replaying old levels and return to level select scene
GameWindow_SetScene(pGameWindow, LevelSelect);
}
else
{
// First time for next level, load and go to play scene
GameEngine_NextLevel(&(pGameWindow->Engine));
GameWindow_SetScene(pGameWindow, Play);
Sounds_PlayRetrySnd(&(pGameWindow->Sounds));
}
} }
} }
} }

View File

@ -202,8 +202,10 @@ void LevelSelectScene_Click(GameWindow *pGameWindow, const Point *pPosition)
if (PtInRect(*pPosition, &levelRect)) if (PtInRect(*pPosition, &levelRect))
{ {
// Clicked on level button
GameEngine_StartLevel(&(pGameWindow->Engine), level); GameEngine_StartLevel(&(pGameWindow->Engine), level);
GameWindow_SetScene(pGameWindow, Play); GameWindow_SetScene(pGameWindow, Play);
Sounds_PlayRetrySnd(&(pGameWindow->Sounds));
break; break;
} }
} }
@ -211,6 +213,7 @@ void LevelSelectScene_Click(GameWindow *pGameWindow, const Point *pPosition)
} }
else if (PtInRect(*pPosition, &(pGameWindow->LevelSelectScene.PrevButtonRect))) else if (PtInRect(*pPosition, &(pGameWindow->LevelSelectScene.PrevButtonRect)))
{ {
// Clicked on previous button, go to previous page or title scene
if (pGameWindow->LevelSelectScene.PageNumber > 0) if (pGameWindow->LevelSelectScene.PageNumber > 0)
{ {
pGameWindow->LevelSelectScene.PageNumber--; pGameWindow->LevelSelectScene.PageNumber--;
@ -223,6 +226,7 @@ void LevelSelectScene_Click(GameWindow *pGameWindow, const Point *pPosition)
} }
else if (PtInRect(*pPosition, &(pGameWindow->LevelSelectScene.NextButtonRect))) else if (PtInRect(*pPosition, &(pGameWindow->LevelSelectScene.NextButtonRect)))
{ {
// Clicked on next button, go to next page if possible
if ((pGameWindow->LevelSelectScene.PageNumber + 1) * LevelsPerPage < LevelCount) if ((pGameWindow->LevelSelectScene.PageNumber + 1) * LevelsPerPage < LevelCount)
{ {
pGameWindow->LevelSelectScene.PageNumber++; pGameWindow->LevelSelectScene.PageNumber++;

View File

@ -7,7 +7,6 @@
* This file provides implementations for Levels.h. * This file provides implementations for Levels.h.
*/ */
#include "Common.h"
#include "Levels.h" #include "Levels.h"
/** The levels from Set A, stored in 32-bit integers. */ /** The levels from Set A, stored in 32-bit integers. */

View File

@ -7,32 +7,35 @@
* This file provides implementations for MacLO.h. * This file provides implementations for MacLO.h.
*/ */
#include "GameWindow.h"
#include "MacLO.h" #include "MacLO.h"
#include "GameWindow.h"
/** Resource ID for the apple menu. */ /** Resource ID for the apple menu. */
#define AppleMenuResID BaseResID #define AppleMenuResID BaseResID
/** Resource ID for the about menu item. */ /** ID for the about menu item. */
#define AboutMenuItemID 1 #define AboutMenuItemID 1
/** Resource ID for the game menu. */ /** Resource ID for the game menu. */
#define GameMenuResID BaseResID+1 #define GameMenuResID BaseResID+1
/** Resource ID for the title menu id. */ /** ID for the title menu item. */
#define TitleMenuItemID 1 #define GoToTitleMenuItemID 1
/** Resource ID for the clear menu id. */ /** ID for the sound item. */
#define ClearMenuItemID 2 #define SoundMenuItemID 2
/** Resource ID for the quit menu id. */ /** ID for the clear menu item. */
#define QuitMenuItemID 4 #define ClearMenuItemID 4
/** ID for the quit menu item. */
#define QuitMenuItemID 6
/** Resource ID for the about dialog. */ /** Resource ID for the about dialog. */
#define AboutDialogResID BaseResID #define AboutDialogResID BaseResID
/** Resource ID for the about dialog's ok button. */ /** Resource ID for the about dialog's ok button. */
#define AboutDialogOKID 1 #define AboutDialogOKID 1
/** GameWindow global instance. */ /** GameWindow global instance. */
GameWindow gGameWindow; GameWindow gGameWindow;
@ -109,21 +112,39 @@ void MacLO_ToolBoxInit()
void MacLO_AppInit() void MacLO_AppInit()
{ {
Handle menuBar; Handle menuBar;
MenuHandle appleMenu; MenuHandle appleMenu, gameMenu;
// Add the menu bar // Add the menu bar
menuBar = GetNewMBar(BaseResID); menuBar = GetNewMBar(BaseResID);
if (menuBar == nil)
{
ShowError("\pMacLO MBAR resource missing!", true);
}
SetMenuBar(menuBar); SetMenuBar(menuBar);
// Populate the apple menu // Populate the apple menu
appleMenu = GetMHandle(AppleMenuResID); appleMenu = GetMHandle(AppleMenuResID);
if (appleMenu == nil)
{
ShowError("\pApple MENU resource missing!", true);
}
AddResMenu(appleMenu, 'DRVR'); AddResMenu(appleMenu, 'DRVR');
DrawMenuBar(); gameMenu = GetMHandle(GameMenuResID);
if (gameMenu == nil)
{
ShowError("\pGame MENU resource missing!", true);
}
// Setup the game window // Setup the game window
GameWindow_Init(&gGameWindow); GameWindow_Init(&gGameWindow);
MacLO_UpdateMenus();
GameWindow_Show(&gGameWindow); GameWindow_Show(&gGameWindow);
// Update menus now that the game window is ready
MacLO_UpdateMenus();
} }
void MacLO_MainLoop() void MacLO_MainLoop()
@ -152,7 +173,17 @@ void MacLO_MainLoop()
cmdChar = event.message & charCodeMask; cmdChar = event.message & charCodeMask;
if ((event.modifiers & cmdKey) != 0) if ((event.modifiers & cmdKey) != 0)
{ {
MacLO_HandleMenuChoice(MenuKey(cmdChar)); if (cmdChar == 'Q' || cmdChar == 'q')
{
// Always handle quit properly, don't rely
// on the quit menu existing or working properly
MacLO_Quit();
}
else
{
// Try to invoke menu
MacLO_HandleMenuChoice(MenuKey(cmdChar));
}
} }
break; break;
} }
@ -160,6 +191,15 @@ void MacLO_MainLoop()
} }
} }
void MacLO_UpdateMenus()
{
MenuHandle gameMenu = GetMHandle(GameMenuResID);
CheckItem(gameMenu, SoundMenuItemID, gGameWindow.Sounds.Enabled);
DrawMenuBar();
}
void MacLO_HandleUpdate(const EventRecord *pEvent) void MacLO_HandleUpdate(const EventRecord *pEvent)
{ {
WindowPtr window; WindowPtr window;
@ -244,10 +284,6 @@ void MacLO_HandleMenuChoice(const int32_t menuChoice)
void MacLO_HandleAppleMenuChoice(const int16_t item) void MacLO_HandleAppleMenuChoice(const int16_t item)
{ {
MenuHandle appleMenu;
Str255 accName;
int16_t accNumber;
switch (item) switch (item)
{ {
case AboutMenuItemID: case AboutMenuItemID:
@ -296,9 +332,12 @@ void MacLO_HandleGameMenuChoice(const int16_t item)
{ {
switch (item) switch (item)
{ {
case TitleMenuItemID: case GoToTitleMenuItemID:
GameWindow_SetScene(&gGameWindow, Title); GameWindow_SetScene(&gGameWindow, Title);
break; break;
case SoundMenuItemID:
GameWindow_ToggleSound(&gGameWindow);
break;
case ClearMenuItemID: case ClearMenuItemID:
GameWindow_ClearScores(&gGameWindow); GameWindow_ClearScores(&gGameWindow);
break; break;

View File

@ -25,4 +25,9 @@ void MacLO_AppInit();
*/ */
void MacLO_MainLoop(); void MacLO_MainLoop();
/**
* Update menus of the application.
*/
void MacLO_UpdateMenus();
#endif #endif

Binary file not shown.

Binary file not shown.

View File

@ -205,6 +205,7 @@ void PlayScene_Click(GameWindow *pGameWindow, const Point *pPosition)
if (PtInRect(*pPosition, &lightRect)) if (PtInRect(*pPosition, &lightRect))
{ {
// Toggle clicked-on light
GameEngine_ToggleLights(&(pGameWindow->Engine), c, r); GameEngine_ToggleLights(&(pGameWindow->Engine), c, r);
GameWindow_Draw(pGameWindow, false); GameWindow_Draw(pGameWindow, false);
Sounds_PlayClickSnd(&(pGameWindow->Sounds)); Sounds_PlayClickSnd(&(pGameWindow->Sounds));
@ -229,14 +230,15 @@ void PlayScene_Click(GameWindow *pGameWindow, const Point *pPosition)
if (PtInRect(*pPosition, &(pGameWindow->PlayScene.RetryButtonRect))) if (PtInRect(*pPosition, &(pGameWindow->PlayScene.RetryButtonRect)))
{ {
// Click on retry button, reset level
GameEngine_ResetLevel(&(pGameWindow->Engine)); GameEngine_ResetLevel(&(pGameWindow->Engine));
GameWindow_Draw(pGameWindow, false); GameWindow_Draw(pGameWindow, false);
Sounds_PlayRetrySnd(&(pGameWindow->Sounds)); Sounds_PlayRetrySnd(&(pGameWindow->Sounds));
} }
else if (PtInRect(*pPosition, &(pGameWindow->PlayScene.SoundButtonRect))) else if (PtInRect(*pPosition, &(pGameWindow->PlayScene.SoundButtonRect)))
{ {
pGameWindow->Sounds.Enabled = !pGameWindow->Sounds.Enabled; // Click on sound button
GameWindow_Draw(pGameWindow, false); GameWindow_ToggleSound(pGameWindow);
} }
} }
} }

View File

@ -13,13 +13,13 @@
#define SndBaseResID 8192 #define SndBaseResID 8192
/** The click snd resource ID. */ /** The click snd resource ID. */
#define ClickSndResID SndBaseResID #define ClickSndResID SndBaseResID
/** The retry snd resource ID. */ /** The retry snd resource ID. */
#define RetrySndResID (ClickSndResID + 1) #define RetrySndResID (ClickSndResID + 1)
/** The done snd resource ID. */ /** The done snd resource ID. */
#define DoneSndResID (RetrySndResID + 1) #define DoneSndResID (RetrySndResID + 1)
/** Whether or not sound is enabled by default. */ /** Whether or not sound is enabled by default. */
#define DefaultEnabled true #define DefaultEnabled true

View File

@ -44,15 +44,24 @@ void TitleScene_Init(GameWindow *pGameWindow)
void TitleScene_Draw(const GameWindow *pGameWindow, bool fullRefresh) void TitleScene_Draw(const GameWindow *pGameWindow, bool fullRefresh)
{ {
// Draw Title // Draw Title
DrawPicture(pGameWindow->Bitmaps.TitlePict, &(pGameWindow->TitleScene.TitleRect)); if (fullRefresh)
{
DrawPicture(pGameWindow->Bitmaps.TitlePict, &(pGameWindow->TitleScene.TitleRect));
}
// Draw Set A // Draw Set A
MoveTo(pGameWindow->TitleScene.SetARect.left, pGameWindow->TitleScene.SetARect.top); if (fullRefresh)
Bitmaps_DrawAChar(&(pGameWindow->Bitmaps), TitleTextScale); {
MoveTo(pGameWindow->TitleScene.SetARect.left, pGameWindow->TitleScene.SetARect.top);
Bitmaps_DrawAChar(&(pGameWindow->Bitmaps), TitleTextScale);
}
// Draw Set B // Draw Set B
MoveTo(pGameWindow->TitleScene.SetBRect.left, pGameWindow->TitleScene.SetBRect.top); if (fullRefresh)
Bitmaps_DrawBChar(&(pGameWindow->Bitmaps), TitleTextScale); {
MoveTo(pGameWindow->TitleScene.SetBRect.left, pGameWindow->TitleScene.SetBRect.top);
Bitmaps_DrawBChar(&(pGameWindow->Bitmaps), TitleTextScale);
}
// Draw sound button // Draw sound button
MoveTo(pGameWindow->TitleScene.SoundButtonRect.left, pGameWindow->TitleScene.SoundButtonRect.top); MoveTo(pGameWindow->TitleScene.SoundButtonRect.left, pGameWindow->TitleScene.SoundButtonRect.top);
@ -63,17 +72,39 @@ void TitleScene_Click(GameWindow *pGameWindow, const Point *pPosition)
{ {
if (PtInRect(*pPosition, &(pGameWindow->TitleScene.SetARect))) if (PtInRect(*pPosition, &(pGameWindow->TitleScene.SetARect)))
{ {
// Click on Set A button
GameEngine_NewGame(&(pGameWindow->Engine), false); GameEngine_NewGame(&(pGameWindow->Engine), false);
GameWindow_SetScene(pGameWindow, LevelSelect); if (GameEngine_HasPlayedLevel(&(pGameWindow->Engine), 0))
{
// Not first time, go to level select
GameWindow_SetScene(pGameWindow, LevelSelect);
}
else
{
// First time, go straight to play scene
GameWindow_SetScene(pGameWindow, Play);
Sounds_PlayRetrySnd(&(pGameWindow->Sounds));
}
} }
else if (PtInRect(*pPosition, &(pGameWindow->TitleScene.SetBRect))) else if (PtInRect(*pPosition, &(pGameWindow->TitleScene.SetBRect)))
{ {
// Click on Set B button
GameEngine_NewGame(&(pGameWindow->Engine), true); GameEngine_NewGame(&(pGameWindow->Engine), true);
GameWindow_SetScene(pGameWindow, LevelSelect); if (GameEngine_HasPlayedLevel(&(pGameWindow->Engine), 0))
{
// Not first time, go to level select
GameWindow_SetScene(pGameWindow, LevelSelect);
}
else
{
// First time, go straight to play scene
GameWindow_SetScene(pGameWindow, Play);
Sounds_PlayRetrySnd(&(pGameWindow->Sounds));
}
} }
else if (PtInRect(*pPosition, &(pGameWindow->TitleScene.SoundButtonRect))) else if (PtInRect(*pPosition, &(pGameWindow->TitleScene.SoundButtonRect)))
{ {
pGameWindow->Sounds.Enabled = !pGameWindow->Sounds.Enabled; // Click on sound button
GameWindow_Draw(pGameWindow, false); GameWindow_ToggleSound(pGameWindow);
} }
} }