Skip to content

Commit bf8398a

Browse files
authored
DS Classic Menu: Draw calendar and top-bar datetime using monospaced characters (#2534)
* quickmenu: Draw monospaced fonts * quickmenu: Slight refactoring of date.cpp
1 parent b3f8b60 commit bf8398a

File tree

8 files changed

+70
-55
lines changed

8 files changed

+70
-55
lines changed

quickmenu/arm9/source/date.cpp

100644100755
Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
#include "common/tonccpy.h"
77
#include "language.h"
88

9-
tm iTimeParts;
10-
119
Datetime::Datetime(time_t rawTime)
1210
:_time(rawTime)
1311
{
@@ -46,34 +44,16 @@ int Datetime::getMonthDays() const {
4644

4745
if (month <= 7)
4846
return 30+(month%2);
49-
50-
return 31-(month%2);
47+
else
48+
return 31-(month%2);
5149
}
5250

5351
/**
5452
* Get weekday from this date
5553
* @return 0 for Sunday ... 6 for Saturday
5654
*/
5755
int Datetime::getWeekDay() const {
58-
int year = _formattedTime.tm_year+1900;
59-
int month = _formattedTime.tm_mon+1;
60-
int day = _formattedTime.tm_mday;
61-
62-
if (month < 3)
63-
{
64-
month+=12;
65-
year--;
66-
}
67-
68-
int centuryYear = year % 100;
69-
int zeroCentury = year / 100;
70-
71-
// Use Zeller's Congruence algorithm
72-
int _p1 = 13*(month+1)/5;
73-
int _p2 = centuryYear/4;
74-
int _p3 = zeroCentury/4;
75-
int _weekDay = (day + _p1 + centuryYear + _p2 + _p3 + 5 * zeroCentury) % 7;
76-
return (_weekDay+6)%7; // convert "sat..fri" to "sun..sat"
56+
return _formattedTime.tm_wday;
7757
}
7858

7959
/**

quickmenu/arm9/source/graphics/FontGraphic.cpp

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ FontGraphic::FontGraphic(const std::vector<std::string> &paths, const bool set_u
180180
questionMark = getCharIndex(0xFFFD);
181181
if (questionMark == 0)
182182
questionMark = getCharIndex('?');
183+
184+
// I feel like using hashtag's width for monospace is generally fine for most fonts.
185+
setFixedWidthChar('#');
183186
}
184187
}
185188

@@ -235,18 +238,26 @@ std::u16string FontGraphic::utf8to16(std::string_view text) {
235238
return out;
236239
}
237240

238-
int FontGraphic::calcWidth(std::u16string_view text) {
239-
uint x = 0;
241+
void FontGraphic::setFixedWidthChar(char character) {
242+
// Use this character's total width as the base for fixed-width calculations
243+
fontFixedWidth = fontWidths[(getCharIndex(character) * 3) + 2];
244+
}
240245

241-
for (auto it = text.begin(); it != text.end(); ++it) {
242-
u16 index = getCharIndex(arabicForm(*it, it > text.begin() ? *(it - 1) : 0, it < text.end() - 1 ? *(it + 1) : 0));
243-
x += fontWidths[(index * 3) + 2];
246+
int FontGraphic::calcWidth(std::u16string_view text, bool monospaced) {
247+
if (!monospaced) {
248+
uint x = 0;
249+
for (auto it = text.begin(); it != text.end(); ++it) {
250+
u16 index = getCharIndex(arabicForm(*it, it > text.begin() ? *(it - 1) : 0, it < text.end() - 1 ? *(it + 1) : 0));
251+
x += fontWidths[(index * 3) + 2];
252+
}
253+
254+
return x;
255+
} else {
256+
return text.length() * fontFixedWidth;
244257
}
245-
246-
return x;
247258
}
248259

249-
ITCM_CODE void FontGraphic::print(int x, int y, bool top, std::u16string_view text, Alignment align, FontPalette palette, bool rtl) {
260+
ITCM_CODE void FontGraphic::print(int x, int y, bool top, std::u16string_view text, Alignment align, FontPalette palette, bool rtl, bool monospaced) {
250261
// If RTL isn't forced, check for RTL text
251262
if (!rtl) {
252263
for (const auto c : text) {
@@ -265,23 +276,23 @@ ITCM_CODE void FontGraphic::print(int x, int y, bool top, std::u16string_view te
265276
} case Alignment::center: {
266277
size_t newline = text.find('\n');
267278
while (newline != text.npos) {
268-
print(x, y, top, text.substr(0, newline), align, palette, rtl);
279+
print(x, y, top, text.substr(0, newline), align, palette, rtl, monospaced);
269280
text = text.substr(newline + 1);
270281
newline = text.find('\n');
271282
y += tileHeight;
272283
}
273284

274-
x = ((256 - calcWidth(text)) / 2) + x;
285+
x = ((256 - calcWidth(text, monospaced)) / 2) + x;
275286
break;
276287
} case Alignment::right: {
277288
size_t newline = text.find('\n');
278289
while (newline != text.npos) {
279-
print(x - calcWidth(text.substr(0, newline)), y, top, text.substr(0, newline), Alignment::left, palette, rtl);
290+
print(x - calcWidth(text.substr(0, newline), monospaced), y, top, text.substr(0, newline), Alignment::left, palette, rtl, monospaced);
280291
text = text.substr(newline + 1);
281292
newline = text.find('\n');
282293
y += tileHeight;
283294
}
284-
x = x - calcWidth(text);
295+
x = x - calcWidth(text, monospaced);
285296
break;
286297
}
287298
}
@@ -461,6 +472,6 @@ ITCM_CODE void FontGraphic::print(int x, int y, bool top, std::u16string_view te
461472
}
462473
}
463474

464-
x += fontWidths[(index * 3) + 2];
475+
x += (monospaced) ? fontFixedWidth : fontWidths[(index * 3) + 2];
465476
}
466477
}

quickmenu/arm9/source/graphics/FontGraphic.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class FontGraphic {
4646
u8 *fontTiles = nullptr;
4747
u8 *fontWidths = nullptr;
4848
u16 *fontMap = nullptr;
49+
u8 fontFixedWidth = 8;
4950

5051
u16 getCharIndex(char16_t c);
5152

@@ -59,11 +60,14 @@ class FontGraphic {
5960
~FontGraphic(void);
6061

6162
u8 height(void) { return tileHeight; }
63+
u8 fixedWidth(void) { return fontFixedWidth; }
6264

63-
int calcWidth(std::string_view text) { return calcWidth(utf8to16(text)); }
64-
int calcWidth(std::u16string_view text);
65+
void setFixedWidthChar(char character);
6566

66-
void print(int x, int y, bool top, int value, Alignment align, FontPalette palette, bool rtl = false) { print(x, y, top, std::to_string(value), align, palette, rtl); }
67-
void print(int x, int y, bool top, std::string_view text, Alignment align, FontPalette palette, bool rtl = false) { print(x, y, top, utf8to16(text), align, palette, rtl); }
68-
void print(int x, int y, bool top, std::u16string_view text, Alignment align, FontPalette palette, bool rtl = false);
67+
int calcWidth(std::string_view text, bool monospaced = false) { return calcWidth(utf8to16(text), monospaced); }
68+
int calcWidth(std::u16string_view text, bool monospaced = false);
69+
70+
void print(int x, int y, bool top, int value, Alignment align, FontPalette palette, bool rtl = false, bool monospaced = false) { print(x, y, top, std::to_string(value), align, palette, rtl, monospaced); }
71+
void print(int x, int y, bool top, std::string_view text, Alignment align, FontPalette palette, bool rtl = false, bool monospaced = false) { print(x, y, top, utf8to16(text), align, palette, rtl, monospaced); }
72+
void print(int x, int y, bool top, std::u16string_view text, Alignment align, FontPalette palette, bool rtl = false, bool monospaced = false);
6973
};
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include "TextEntry.h"
22

3-
TextEntry::TextEntry(bool large, int x, int y, std::string_view message, Alignment align, FontPalette palette)
4-
: large(large), x(x), y(y), message(FontGraphic::utf8to16(message)), align(align), palette(palette) {};
3+
TextEntry::TextEntry(bool large, bool monospaced, int x, int y, std::string_view message, Alignment align, FontPalette palette)
4+
: large(large), monospaced(monospaced), x(x), y(y), message(FontGraphic::utf8to16(message)), align(align), palette(palette) {};
55

6-
TextEntry::TextEntry(bool large, int x, int y, std::u16string_view message, Alignment align, FontPalette palette)
7-
: large(large), x(x), y(y), message(message), align(align), palette(palette) {};
6+
TextEntry::TextEntry(bool large, bool monospaced, int x, int y, std::u16string_view message, Alignment align, FontPalette palette)
7+
: large(large), monospaced(monospaced), x(x), y(y), message(message), align(align), palette(palette) {};

quickmenu/arm9/source/graphics/TextEntry.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55
class TextEntry {
66
public:
77
bool large;
8+
bool monospaced;
89
int x, y;
910
std::u16string message;
1011
Alignment align;
1112
FontPalette palette;
1213

13-
TextEntry(bool large, int x, int y, std::string_view message, Alignment align, FontPalette palette);
14-
TextEntry(bool large, int x, int y, std::u16string_view message, Alignment align, FontPalette palette);
14+
TextEntry(bool large, bool monospaced, int x, int y, std::string_view message, Alignment align, FontPalette palette);
15+
TextEntry(bool large, bool monospaced, int x, int y, std::u16string_view message, Alignment align, FontPalette palette);
1516
};

quickmenu/arm9/source/graphics/fontHandler.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ void fontInit() {
6767
palette[3] = 0x94A5;
6868
}
6969
tinyFont = new FontGraphic({"nitro:/graphics/font/tiny.nftr"}, false);
70+
tinyFont->setFixedWidthChar('A'); // tiny font has tiny fixed-width
7071

7172
if (colorTable) {
7273
for (uint i = 1; i < sizeof(palette)/sizeof(u16); i++) {
@@ -99,7 +100,7 @@ void updateText(bool top) {
99100
for (auto it = text.begin(); it != text.end(); ++it) {
100101
FontGraphic *font = getFont(it->large);
101102
if (font)
102-
font->print(it->x, it->y, top, it->message, it->align, it->palette);
103+
font->print(it->x, it->y, top, it->message, it->align, it->palette, false, it->monospaced);
103104
}
104105
text.clear();
105106

@@ -132,17 +133,31 @@ void clearText() {
132133
}
133134

134135
void printSmall(bool top, int x, int y, std::string_view message, Alignment align, FontPalette palette) {
135-
getTextQueue(top).emplace_back(false, x, y, message, align, palette);
136+
getTextQueue(top).emplace_back(false, false, x, y, message, align, palette);
136137
}
137138
void printSmall(bool top, int x, int y, std::u16string_view message, Alignment align, FontPalette palette) {
138-
getTextQueue(top).emplace_back(false, x, y, message, align, palette);
139+
getTextQueue(top).emplace_back(false, false, x, y, message, align, palette);
140+
}
141+
142+
void printSmallMonospaced(bool top, int x, int y, std::string_view message, Alignment align, FontPalette palette) {
143+
getTextQueue(top).emplace_back(false, true, x, y, message, align, palette);
144+
}
145+
void printSmallMonospaced(bool top, int x, int y, std::u16string_view message, Alignment align, FontPalette palette) {
146+
getTextQueue(top).emplace_back(false, true, x, y, message, align, palette);
139147
}
140148

141149
void printTiny(bool top, int x, int y, std::string_view message, Alignment align, FontPalette palette) {
142-
getTextQueue(top).emplace_back(true, x, y, message, align, palette);
150+
getTextQueue(top).emplace_back(true, false, x, y, message, align, palette);
143151
}
144152
void printTiny(bool top, int x, int y, std::u16string_view message, Alignment align, FontPalette palette) {
145-
getTextQueue(top).emplace_back(true, x, y, message, align, palette);
153+
getTextQueue(top).emplace_back(true, false, x, y, message, align, palette);
154+
}
155+
156+
void printTinyMonospaced(bool top, int x, int y, std::string_view message, Alignment align, FontPalette palette) {
157+
getTextQueue(top).emplace_back(true, true, x, y, message, align, palette);
158+
}
159+
void printTinyMonospaced(bool top, int x, int y, std::u16string_view message, Alignment align, FontPalette palette) {
160+
getTextQueue(top).emplace_back(true, true, x, y, message, align, palette);
146161
}
147162

148163
int calcSmallFontWidth(std::string_view text) {

quickmenu/arm9/source/graphics/fontHandler.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,12 @@ void clearText();
1111

1212
void printSmall(bool top, int x, int y, std::string_view message, Alignment align = Alignment::left, FontPalette palette = FontPalette::regular);
1313
void printSmall(bool top, int x, int y, std::u16string_view message, Alignment align = Alignment::left, FontPalette palette = FontPalette::regular);
14+
void printSmallMonospaced(bool top, int x, int y, std::string_view message, Alignment align = Alignment::left, FontPalette palette = FontPalette::regular);
15+
void printSmallMonospaced(bool top, int x, int y, std::u16string_view message, Alignment align = Alignment::left, FontPalette palette = FontPalette::regular);
1416
void printTiny(bool top, int x, int y, std::string_view message, Alignment align = Alignment::left, FontPalette palette = FontPalette::regular);
1517
void printTiny(bool top, int x, int y, std::u16string_view message, Alignment align = Alignment::left, FontPalette palette = FontPalette::regular);
18+
void printTinyMonospaced(bool top, int x, int y, std::string_view message, Alignment align = Alignment::left, FontPalette palette = FontPalette::regular);
19+
void printTinyMonospaced(bool top, int x, int y, std::u16string_view message, Alignment align = Alignment::left, FontPalette palette = FontPalette::regular);
1620

1721
int calcSmallFontWidth(std::string_view text);
1822
int calcSmallFontWidth(std::u16string_view text);

quickmenu/arm9/source/graphics/graphics.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,7 @@ static void markerDraw(int x, int y) {
874874
}
875875

876876
static void calendarTextDraw(const Datetime& now) {
877-
printSmall(true, 56, calendarYPos+3, getDateYear(), Alignment::center);
877+
printSmallMonospaced(true, 56, calendarYPos+3, getDateYear(), Alignment::center);
878878

879879
Datetime firstDay(now.getYear(), now.getMonth(), 1);
880880
int startWeekday = firstDay.getWeekDay();
@@ -1259,8 +1259,8 @@ void drawDateTime(bool date, bool showTimeColon) {
12591259
std::string text = date ? getDate() : retTime();
12601260
if (!date && !showTimeColon) text[2] = ' ';
12611261

1262-
const int posX = date ? 205 : 171;
1263-
printTiny(true, posX, 3, text, Alignment::right, FontPalette::topBar);
1262+
const int posX = date ? 204 : 172;
1263+
printTinyMonospaced(true, posX, 3, text, Alignment::right, FontPalette::topBar);
12641264
updateTopTextArea(posX - 27, 3, 27, tinyFontHeight(), bmpImageBuffer);
12651265
}
12661266

0 commit comments

Comments
 (0)