22
33#include " common/tonccpy.h"
44
5- u8 *FontGraphic::lastUsedLoc = (u8 *)0x08000000 ;
6-
75u8 FontGraphic::textBuf[256 * 192 ];
86
97std::map<char16_t , std::array<char16_t , 3 >> FontGraphic::arabicPresentationForms = {
@@ -90,19 +88,15 @@ char16_t FontGraphic::arabicForm(char16_t current, char16_t prev, char16_t next)
9088 return current;
9189}
9290
93- FontGraphic::FontGraphic (const std::vector<std::string> &paths, bool useExpansionPak) : useExpansionPak(useExpansionPak) {
94- FILE *file = nullptr ;
91+ FontGraphic::FontGraphic (const std::vector<std::string> &paths, const bool set_useTileCache) {
9592 for (const auto &path : paths) {
9693 file = fopen (path.c_str (), " rb" );
9794 if (file)
9895 break ;
9996 }
10097
98+ useTileCache = set_useTileCache;
10199 if (file) {
102- if (useExpansionPak && *(u16 *)(0x020000C0 ) == 0 && lastUsedLoc == (u8 *)0x08000000 ) {
103- lastUsedLoc += 0x01000000 ;
104- }
105-
106100 // Get file size
107101 fseek (file, 0 , SEEK_END);
108102 u32 fileSize = ftell (file);
@@ -121,14 +115,8 @@ FontGraphic::FontGraphic(const std::vector<std::string> &paths, bool useExpansio
121115 // Load character glyphs
122116 tileAmount = (chunkSize - 0x10 ) / tileSize;
123117 fseek (file, 4 , SEEK_CUR);
124- if (useExpansionPak) {
125- fontTiles = lastUsedLoc;
126- lastUsedLoc += tileSize * tileAmount;
127-
128- u8 *buf = new u8 [tileSize * tileAmount];
129- fread (buf, tileSize, tileAmount, file);
130- tonccpy (fontTiles, buf, tileSize * tileAmount);
131- delete[] buf;
118+ if (useTileCache) {
119+ fontTiles = new u8 [tileSize * (tileAmount>tileCacheCount ? tileCacheCount : tileAmount)];
132120 } else {
133121 fontTiles = new u8 [tileSize * tileAmount];
134122 fread (fontTiles, tileSize, tileAmount, file);
@@ -141,32 +129,17 @@ FontGraphic::FontGraphic(const std::vector<std::string> &paths, bool useExpansio
141129 fseek (file, locHDWC-4 , SEEK_SET);
142130 fread (&chunkSize, 4 , 1 , file);
143131 fseek (file, 8 , SEEK_CUR);
144- if (useExpansionPak) {
145- fontWidths = lastUsedLoc;
146- lastUsedLoc += 3 * tileAmount;
147-
148- u8 *buf = new u8 [3 * tileAmount];
149- fread (buf, 3 , tileAmount, file);
150- tonccpy (fontWidths, buf, 3 * tileAmount);
151- delete[] buf;
152- } else {
153- fontWidths = new u8 [3 * tileAmount];
154- fread (fontWidths, 3 , tileAmount, file);
155- }
132+ fontWidths = new u8 [3 * tileAmount];
133+ fread (fontWidths, 3 , tileAmount, file);
156134
157135 // Load character maps
158- if (useExpansionPak) {
159- fontMap = (u16 *)lastUsedLoc;
160- lastUsedLoc += tileAmount * sizeof (u16 );
161- } else {
162- fontMap = new u16 [tileAmount];
163- }
136+ fontMap = new u16 [tileAmount];
164137
165138 fseek (file, 0x28 , SEEK_SET);
166139 u32 locPAMC, mapType;
167140 fread (&locPAMC, 4 , 1 , file);
168141
169- while (locPAMC < fileSize) {
142+ while (locPAMC && locPAMC < fileSize) {
170143 u16 firstChar, lastChar;
171144 fseek (file, locPAMC, SEEK_SET);
172145 fread (&firstChar, 2 , 1 , file);
@@ -202,22 +175,20 @@ FontGraphic::FontGraphic(const std::vector<std::string> &paths, bool useExpansio
202175 }
203176 }
204177 }
205- fclose (file);
206178 questionMark = getCharIndex (0xFFFD );
207179 if (questionMark == 0 )
208180 questionMark = getCharIndex (' ?' );
209181 }
210182}
211183
212184FontGraphic::~FontGraphic (void ) {
213- if (!useExpansionPak) {
214- if (fontTiles)
215- delete[] fontTiles;
216- if (fontWidths)
217- delete[] fontWidths;
218- if (fontMap)
219- delete[] fontMap;
220- }
185+ fclose (file);
186+ if (fontTiles)
187+ delete[] fontTiles;
188+ if (fontWidths)
189+ delete[] fontWidths;
190+ if (fontMap)
191+ delete[] fontMap;
221192}
222193
223194u16 FontGraphic::getCharIndex (char16_t c) {
@@ -430,14 +401,60 @@ ITCM_CODE void FontGraphic::print(int x, int y, bool top, std::u16string_view te
430401 index = getCharIndex (*it);
431402 }
432403
433- // Don't draw off screen chars
434- if (x >= 0 && x + fontWidths[(index * 3 ) + 2 ] < 256 && y >= 0 && y + tileHeight < 192 ) {
435- u8 *dst = textBuf + x + fontWidths[(index * 3 )];
436- for (int i = 0 ; i < tileHeight; i++) {
437- for (int j = 0 ; j < tileWidth; j++) {
438- u8 px = fontTiles[(index * tileSize) + (i * tileWidth + j) / 4 ] >> ((3 - ((i * tileWidth + j) % 4 )) * 2 ) & 3 ;
439- if (px)
440- dst[(y + i) * 256 + j] = px + 0xF8 ;
404+ if (useTileCache) {
405+ bool found = false ;
406+ bool overwrite = true ;
407+ u8 cachePos = 0 ;
408+ for (u8 i = 0 ; i < tileCacheCount; i++) {
409+ if (!cacheAllocated[i]) {
410+ indexCache[i] = index;
411+ cachePos = i;
412+ cacheAllocated[i] = true ;
413+ overwrite = false ;
414+ break ;
415+ } else if (indexCache[i] == index) {
416+ cachePos = i;
417+ found = true ;
418+ overwrite = false ;
419+ break ;
420+ }
421+ }
422+
423+ if (overwrite) {
424+ nextCachePos++;
425+ if (nextCachePos == tileCacheCount) {
426+ nextCachePos = 0 ;
427+ }
428+ cachePos = nextCachePos;
429+ indexCache[cachePos] = index;
430+ }
431+
432+ if (!found && file) {
433+ fseek (file, 0x40 +(index * tileSize), SEEK_SET);
434+ fread (fontTiles+(cachePos * tileSize), tileSize, 1 , file);
435+ }
436+
437+ // Don't draw off screen chars
438+ if (x >= 0 && x + fontWidths[(index * 3 ) + 2 ] < 256 && y >= 0 && y + tileHeight < 192 ) {
439+ u8 *dst = textBuf + x + fontWidths[(index * 3 )];
440+ for (int i = 0 ; i < tileHeight; i++) {
441+ for (int j = 0 ; j < tileWidth; j++) {
442+ u8 px = fontTiles[(cachePos * tileSize) + (i * tileWidth + j) / 4 ] >> ((3 - ((i * tileWidth + j) % 4 )) * 2 ) & 3 ;
443+ if (px)
444+ dst[(y + i) * 256 + j] = px + 0xF8 ;
445+ }
446+ }
447+ }
448+ } else {
449+ // Don't draw off screen chars
450+ if (x >= 0 && x + fontWidths[(index * 3 ) + 2 ] < 256 && y >= 0 && y + tileHeight < 192 ) {
451+ u8 *dst = textBuf + x + fontWidths[(index * 3 )];
452+ for (int i = 0 ; i < tileHeight; i++) {
453+ for (int j = 0 ; j < tileWidth; j++) {
454+ u8 px = fontTiles[(index * tileSize) + (i * tileWidth + j) / 4 ] >> ((3 - ((i * tileWidth + j) % 4 )) * 2 ) & 3 ;
455+ if (px)
456+ dst[(y + i) * 256 + j] = px + 0xF8 ;
457+ }
441458 }
442459 }
443460 }
0 commit comments