mirror of https://github.com/jonthysell/MacLO.git
393 lines
10 KiB
C
393 lines
10 KiB
C
// Copyright (c) Jon Thysell <http://jonthysell.com>
|
|
// Licensed under the MIT License.
|
|
|
|
/**
|
|
* @file Bitmaps.c
|
|
*
|
|
* This file provides implementations for Bitmaps.h.
|
|
*/
|
|
|
|
#include <OSUtils.h>
|
|
|
|
#include "Bitmaps.h"
|
|
|
|
/** The first PICT resource ID. */
|
|
#define BasePictResID BaseResID
|
|
|
|
/** Index of the title PICT resource ID. */
|
|
#define TitlePictResID 0
|
|
|
|
/** Starting index of the number character PICT resource IDs. */
|
|
#define NumCharPictBaseResID (TitlePictResID + 1)
|
|
|
|
/** Index of the A character PICT resource ID. */
|
|
#define ACharPictResID (NumCharPictBaseResID + NumCharPictCount)
|
|
|
|
/** Index of the B character PICT resource ID. */
|
|
#define BCharPictResID (ACharPictResID + 1)
|
|
|
|
/** Index of the / character PICT resource ID. */
|
|
#define SlashCharPictResID (BCharPictResID + 1)
|
|
|
|
/** Starting index of the star PICT resource IDs. */
|
|
#define StarPictBaseResID (SlashCharPictResID + 1)
|
|
|
|
/** Index of the previous button PICT resource ID. */
|
|
#define PrevButtonPictResID (StarPictBaseResID + StarPictCount)
|
|
|
|
/** Index of the next button PICT resource ID. */
|
|
#define NextButtonPictResID (PrevButtonPictResID + 1)
|
|
|
|
/** Index of the retry button PICT resource ID. */
|
|
#define RetryButtonPictResID (NextButtonPictResID + 1)
|
|
|
|
/** Index of the sound off PICT resource ID. */
|
|
#define SoundOffPictResID (RetryButtonPictResID + 1)
|
|
|
|
/** Index of the sound on PICT resource ID. */
|
|
#define SoundOnPictResID (SoundOffPictResID + 1)
|
|
|
|
/** Index of the light off PICT resource ID. */
|
|
#define LightOffPictResID (SoundOnPictResID + 1)
|
|
|
|
/** Index of the light on PICT resource ID. */
|
|
#define LightOnPictResID (LightOffPictResID + 1)
|
|
|
|
/** The total number of PICT resources. */
|
|
#define TotalPictCount (LightOnPictResID + 1)
|
|
|
|
/** Amount of padding to place between star PICTs. */
|
|
#define StarRectPadding 2
|
|
|
|
/** Mapping of months to the day of the year of their first day. */
|
|
const int16_t MonthOffset[] = {
|
|
0, // Jan
|
|
31, // Feb
|
|
60, // Mar
|
|
91, // Apr
|
|
121, // May
|
|
152, // Jun
|
|
182, // Jul
|
|
213, // Aug
|
|
244, // Sep
|
|
274, // Oct
|
|
305, // Nov
|
|
335, // Dec
|
|
};
|
|
|
|
/**
|
|
* Gets the override base resource ID.
|
|
* @return The base resource ID.
|
|
*/
|
|
int16_t Bitmaps_GetOverrideBaseResID();
|
|
|
|
/**
|
|
* Gets the PICT specified by the base resource ID and given offset.
|
|
* @param baseResID The base resource ID.
|
|
* @param offset The offset.
|
|
* @return The PICT resource.
|
|
*/
|
|
PicHandle Bitmaps_GetPict(const int16_t baseResID, const int16_t offset);
|
|
|
|
void Bitmaps_Init(Bitmaps *pBitmaps)
|
|
{
|
|
int16_t i, baseResID;
|
|
|
|
baseResID = Bitmaps_GetOverrideBaseResID();
|
|
|
|
// Load title
|
|
pBitmaps->TitlePict = Bitmaps_GetPict(baseResID, TitlePictResID);
|
|
if (pBitmaps->TitlePict == nil)
|
|
{
|
|
ShowError("\pTitle PICT resource missing!", true);
|
|
}
|
|
|
|
// Load number chars
|
|
for (i = 0; i < NumCharPictCount; i++)
|
|
{
|
|
pBitmaps->NumCharPicts[i] = Bitmaps_GetPict(baseResID, NumCharPictBaseResID + i);
|
|
if (pBitmaps->NumCharPicts[i] == nil)
|
|
{
|
|
ShowError("\pNumber char PICT resource missing!", true);
|
|
}
|
|
}
|
|
|
|
// Load "A" char
|
|
pBitmaps->ACharPict = Bitmaps_GetPict(baseResID, ACharPictResID);
|
|
if (pBitmaps->ACharPict == nil)
|
|
{
|
|
ShowError("\pA char PICT resource missing!", true);
|
|
}
|
|
|
|
// Load "B" char
|
|
pBitmaps->BCharPict = Bitmaps_GetPict(baseResID, BCharPictResID);
|
|
if (pBitmaps->BCharPict == nil)
|
|
{
|
|
ShowError("\pB char PICT resource missing!", true);
|
|
}
|
|
|
|
// Load "/" char
|
|
pBitmaps->SlashCharPict = Bitmaps_GetPict(baseResID, SlashCharPictResID);
|
|
if (pBitmaps->SlashCharPict == nil)
|
|
{
|
|
ShowError("\pSlash char PICT resource missing!", true);
|
|
}
|
|
|
|
// Load half-stars
|
|
for (i = 0; i < StarPictCount; i++)
|
|
{
|
|
pBitmaps->StarPicts[i] = Bitmaps_GetPict(baseResID, StarPictBaseResID + i);
|
|
if (pBitmaps->StarPicts[i] == nil)
|
|
{
|
|
ShowError("\pStar PICT resource missing!", true);
|
|
}
|
|
}
|
|
|
|
// Load slash char
|
|
pBitmaps->SlashCharPict = Bitmaps_GetPict(baseResID, SlashCharPictResID);
|
|
if (pBitmaps->SlashCharPict == nil)
|
|
{
|
|
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)
|
|
{
|
|
ShowError("\pNext button PICT resource missing!", true);
|
|
}
|
|
|
|
// Load retry button
|
|
pBitmaps->RetryButtonPict = Bitmaps_GetPict(baseResID, RetryButtonPictResID);
|
|
if (pBitmaps->RetryButtonPict == nil)
|
|
{
|
|
ShowError("\pRetry button PICT resource missing!", true);
|
|
}
|
|
|
|
// Load sound off
|
|
pBitmaps->SoundOffPict = Bitmaps_GetPict(baseResID, SoundOffPictResID);
|
|
if (pBitmaps->SoundOffPict == nil)
|
|
{
|
|
ShowError("\pSound off PICT resource missing!", true);
|
|
}
|
|
|
|
// Load sound on
|
|
pBitmaps->SoundOnPict = Bitmaps_GetPict(baseResID, SoundOnPictResID);
|
|
if (pBitmaps->SoundOnPict == nil)
|
|
{
|
|
ShowError("\pSound on PICT resource missing!", true);
|
|
}
|
|
|
|
// Load light off
|
|
pBitmaps->LightOffPict = Bitmaps_GetPict(baseResID, LightOffPictResID);
|
|
if (pBitmaps->LightOffPict == nil)
|
|
{
|
|
ShowError("\pLight off PICT resource missing!", true);
|
|
}
|
|
|
|
// Load light on
|
|
pBitmaps->LightOnPict = Bitmaps_GetPict(baseResID, LightOnPictResID);
|
|
if (pBitmaps->LightOnPict == nil)
|
|
{
|
|
ShowError("\pLight on PICT resource missing!", true);
|
|
}
|
|
}
|
|
|
|
int16_t Bitmaps_GetOverrideBaseResID()
|
|
{
|
|
uint32_t seconds;
|
|
DateTimeRec dateTime;
|
|
int16_t dayOfYear;
|
|
|
|
GetDateTime(&seconds);
|
|
Secs2Date(seconds, &dateTime);
|
|
|
|
// Calculate "day number" (1 - 366, always assume leap year)
|
|
dayOfYear = MonthOffset[dateTime.month - 1];
|
|
dayOfYear += dateTime.day;
|
|
|
|
return BasePictResID + (dayOfYear * TotalPictCount);
|
|
}
|
|
|
|
PicHandle Bitmaps_GetPict(const int16_t baseResID, const int16_t offset)
|
|
{
|
|
PicHandle pic;
|
|
pic = (PicHandle)Get1Resource('PICT', baseResID + offset);
|
|
|
|
if (pic == nil)
|
|
{
|
|
// No override pic, get default
|
|
pic = (PicHandle)Get1Resource('PICT', BasePictResID + offset);
|
|
}
|
|
|
|
return pic;
|
|
}
|
|
|
|
void Bitmaps_GetNumberRect(const Bitmaps *pBitmaps, const uint32_t number, const uint8_t scale, Rect *pDestRect)
|
|
{
|
|
bool started;
|
|
uint32_t k, digit, remainder;
|
|
Rect digitRect;
|
|
|
|
pDestRect->top = 0;
|
|
pDestRect->left = 0;
|
|
pDestRect->bottom = 0;
|
|
pDestRect->right = 0;
|
|
|
|
if (number == 0)
|
|
{
|
|
GetScaledPicFrame(pBitmaps->NumCharPicts[0], scale, &digitRect);
|
|
ConcatenateRect(pDestRect, &digitRect, pDestRect);
|
|
return;
|
|
}
|
|
|
|
started = false;
|
|
remainder = number;
|
|
|
|
for (k = 1000000000UL; k > 0; k = k / 10)
|
|
{
|
|
digit = remainder / k;
|
|
remainder = remainder % k;
|
|
|
|
if (started || (digit > 0 && digit < 10))
|
|
{
|
|
GetScaledPicFrame(pBitmaps->NumCharPicts[digit], scale, &digitRect);
|
|
ConcatenateRect(pDestRect, &digitRect, pDestRect);
|
|
started = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Bitmaps_DrawNumber(const Bitmaps *pBitmaps, const uint32_t number, const uint8_t scale)
|
|
{
|
|
bool started;
|
|
uint32_t k, digit, remainder;
|
|
|
|
if (number == 0)
|
|
{
|
|
DrawScaledPic(pBitmaps->NumCharPicts[0], scale);
|
|
return;
|
|
}
|
|
|
|
started = false;
|
|
remainder = number;
|
|
|
|
for (k = 1000000000UL; k > 0; k = k / 10)
|
|
{
|
|
digit = remainder / k;
|
|
remainder = remainder % k;
|
|
|
|
if (started || (digit > 0 && digit < 10))
|
|
{
|
|
DrawScaledPic(pBitmaps->NumCharPicts[digit], scale);
|
|
started = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Bitmaps_DrawAChar(const Bitmaps *pBitmaps, const uint8_t scale)
|
|
{
|
|
DrawScaledPic(pBitmaps->ACharPict, scale);
|
|
}
|
|
|
|
void Bitmaps_DrawBChar(const Bitmaps *pBitmaps, const uint8_t scale)
|
|
{
|
|
DrawScaledPic(pBitmaps->BCharPict, scale);
|
|
}
|
|
|
|
void Bitmaps_DrawSlashChar(const Bitmaps *pBitmaps, const uint8_t scale)
|
|
{
|
|
DrawScaledPic(pBitmaps->SlashCharPict, scale);
|
|
}
|
|
|
|
void Bitmaps_GetHalfStarsRect(const Bitmaps *pBitmaps, const uint8_t maxStars, const uint8_t scale, Rect *pDestRect)
|
|
{
|
|
uint8_t stars;
|
|
Rect starRect, paddingRect;
|
|
|
|
pDestRect->top = 0;
|
|
pDestRect->left = 0;
|
|
pDestRect->bottom = 0;
|
|
pDestRect->right = 0;
|
|
|
|
if (maxStars == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
GetScaledPicFrame(pBitmaps->StarPicts[0], scale, &starRect);
|
|
paddingRect = starRect;
|
|
paddingRect.right = paddingRect.left + (StarRectPadding * scale);
|
|
|
|
ConcatenateRect(pDestRect, &starRect, pDestRect);
|
|
|
|
for (stars = 1; stars < maxStars; stars++)
|
|
{
|
|
ConcatenateRect(pDestRect, &paddingRect, pDestRect);
|
|
ConcatenateRect(pDestRect, &starRect, pDestRect);
|
|
}
|
|
}
|
|
|
|
void Bitmaps_DrawHalfStars(const Bitmaps *pBitmaps, const uint8_t halfStars, const uint8_t maxStars, const uint8_t scale)
|
|
{
|
|
Point penPosition;
|
|
uint8_t i, progress, drawn;
|
|
|
|
progress = halfStars;
|
|
drawn = 0;
|
|
|
|
for (i = StarPictCount - 1; i > 0; i--)
|
|
{
|
|
while (drawn < maxStars && progress >= i)
|
|
{
|
|
DrawScaledPic(pBitmaps->StarPicts[i], scale);
|
|
GetPen(&penPosition);
|
|
MoveTo(penPosition.h + (StarRectPadding * scale), penPosition.v);
|
|
progress -= i;
|
|
drawn++;
|
|
}
|
|
}
|
|
|
|
for (; drawn < maxStars; drawn++)
|
|
{
|
|
DrawScaledPic(pBitmaps->StarPicts[0], scale);
|
|
GetPen(&penPosition);
|
|
MoveTo(penPosition.h + (StarRectPadding * scale), penPosition.v);
|
|
}
|
|
}
|
|
|
|
void Bitmaps_GetSoundRect(const Bitmaps *pBitmaps, const uint8_t scale, Rect *pDestRect)
|
|
{
|
|
Rect r;
|
|
|
|
GetScaledPicFrame(pBitmaps->SoundOffPict, scale, pDestRect);
|
|
GetScaledPicFrame(pBitmaps->SoundOnPict, scale, &r);
|
|
ConcatenateRect(pDestRect, &r, pDestRect);
|
|
}
|
|
|
|
void Bitmaps_DrawSound(const Bitmaps *pBitmaps, const bool enabled, const uint8_t scale)
|
|
{
|
|
Point penPosition;
|
|
Rect r;
|
|
|
|
DrawScaledPic(pBitmaps->SoundOffPict, scale);
|
|
if (enabled)
|
|
{
|
|
DrawScaledPic(pBitmaps->SoundOnPict, scale);
|
|
}
|
|
else
|
|
{
|
|
GetScaledPicFrame(pBitmaps->SoundOnPict, scale, &r);
|
|
GetPen(&penPosition);
|
|
OffsetRect(&r, penPosition.h, penPosition.v);
|
|
FillRect(&r, black);
|
|
}
|
|
}
|