mirror of
https://github.com/jonthysell/MacLO.git
synced 2024-06-26 08:29:27 +00:00
* 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
237 lines
8.4 KiB
C
237 lines
8.4 KiB
C
// Copyright (c) Jon Thysell <http://jonthysell.com>
|
|
// Licensed under the MIT License.
|
|
|
|
/**
|
|
* @file LevelSelectScene.c
|
|
*
|
|
* This file provides implementations for LevelSelectScene.h.
|
|
*/
|
|
|
|
#include "LevelSelectScene.h"
|
|
|
|
/** Scale factor for the A/B set text. */
|
|
#define SetTextScale 3
|
|
|
|
/** Scale factor for the score text. */
|
|
#define ScoreTextScale 1
|
|
|
|
/** Margin for each level selection. */
|
|
#define LevelMargin 10
|
|
|
|
/** Width for each level selection. */
|
|
#define LevelWidth 80
|
|
|
|
/** Height for each level selection. */
|
|
#define LevelHeight 60
|
|
|
|
/** The number of rows of levels to show. */
|
|
#define LevelRowCount 2
|
|
|
|
/** The number of columns of levels to show. */
|
|
#define LevelColumnCount 5
|
|
|
|
/** The total number of levels to show per page. */
|
|
#define LevelsPerPage (LevelRowCount * LevelColumnCount)
|
|
|
|
/** Scale factor for the level text. */
|
|
#define LevelTextScale 1
|
|
|
|
/**
|
|
* Gets the Rect of the level selection at the given index.
|
|
* @param pGameWindow The GameWindow.
|
|
* @param pRect. The Rect of the level selection.
|
|
* @param i The index of the level onscreen.
|
|
*/
|
|
void LevelSelectScene_SetLevelRect(const GameWindow *pGameWindow, Rect *pRect, const int8_t i);
|
|
|
|
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);
|
|
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);
|
|
CenterRect(&r, &(pGameWindow->LevelSelectScene.ScoreRect));
|
|
|
|
// Setup previous button
|
|
GetPictureRect(pGameWindow->Bitmaps.NextButtonPict, &(pGameWindow->LevelSelectScene.PrevButtonRect));
|
|
|
|
GetBoxRect(pContentRect, BottomLeft, &r);
|
|
CenterRect(&r, &(pGameWindow->LevelSelectScene.PrevButtonRect));
|
|
|
|
// Setup next button
|
|
GetPictureRect(pGameWindow->Bitmaps.NextButtonPict, &(pGameWindow->LevelSelectScene.NextButtonRect));
|
|
|
|
GetBoxRect(pContentRect, BottomRight, &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), 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))
|
|
{
|
|
// Clicked on level button
|
|
GameEngine_StartLevel(&(pGameWindow->Engine), level);
|
|
GameWindow_SetScene(pGameWindow, Play);
|
|
Sounds_PlayRetrySnd(&(pGameWindow->Sounds));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (PtInRect(*pPosition, &(pGameWindow->LevelSelectScene.PrevButtonRect)))
|
|
{
|
|
// Clicked on previous button, go to previous page or title scene
|
|
if (pGameWindow->LevelSelectScene.PageNumber > 0)
|
|
{
|
|
pGameWindow->LevelSelectScene.PageNumber--;
|
|
GameWindow_Draw(pGameWindow, false);
|
|
}
|
|
else
|
|
{
|
|
GameWindow_SetScene(pGameWindow, Title);
|
|
}
|
|
}
|
|
else if (PtInRect(*pPosition, &(pGameWindow->LevelSelectScene.NextButtonRect)))
|
|
{
|
|
// Clicked on next button, go to next page if possible
|
|
if ((pGameWindow->LevelSelectScene.PageNumber + 1) * LevelsPerPage < LevelCount)
|
|
{
|
|
pGameWindow->LevelSelectScene.PageNumber++;
|
|
GameWindow_Draw(pGameWindow, false);
|
|
}
|
|
}
|
|
}
|