You've already forked pico-loader
mirror of
https://github.com/LNH-team/pico-loader.git
synced 2026-01-09 16:28:35 -08:00
Initial commit
This commit is contained in:
48
arm9/source/errorDisplay/ErrorDisplay.cpp
Normal file
48
arm9/source/errorDisplay/ErrorDisplay.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "common.h"
|
||||
#include <libtwl/mem/memVram.h>
|
||||
#include <libtwl/gfx/gfx.h>
|
||||
#include <libtwl/gfx/gfxStatus.h>
|
||||
#include <libtwl/gfx/gfxPalette.h>
|
||||
#include <libtwl/gfx/gfxBackground.h>
|
||||
#include "nitroFont2.h"
|
||||
#include "font_nft2.h"
|
||||
#include "ErrorDisplay.h"
|
||||
|
||||
void ErrorDisplay::PrintError(const char* errorString)
|
||||
{
|
||||
mem_setVramEMapping(MEM_VRAM_E_MAIN_BG_00000);
|
||||
auto textBuffer = (u8*)0x02100000;
|
||||
memset(textBuffer, 0, 256 * 192);
|
||||
nft2_unpack((nft2_header_t*)font_nft2);
|
||||
nft2_string_render_params_t renderParams =
|
||||
{
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 256,
|
||||
height: 192
|
||||
};
|
||||
nft2_renderString((const nft2_header_t*)font_nft2, errorString, textBuffer, 256, &renderParams);
|
||||
memcpy((void*)GFX_BG_MAIN, textBuffer, 256 * 192);
|
||||
while (gfx_getVCount() != 191);
|
||||
while (gfx_getVCount() == 191);
|
||||
// 4 bit grayscale palette
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
int gray = i * 2 + (i == 0 ? 0 : 1);
|
||||
GFX_PLTT_BG_MAIN[i] = gray | (gray << 5) | (gray << 10);
|
||||
}
|
||||
REG_BG3PA = 256;
|
||||
REG_BG3PB = 0;
|
||||
REG_BG3PC = 0;
|
||||
REG_BG3PD = 256;
|
||||
REG_BG3X = 0;
|
||||
REG_BG3Y = 0;
|
||||
REG_BG3CNT = (1 << 7) | (1 << 14);
|
||||
REG_BLDCNT = 0;
|
||||
REG_DISPCNT = 3 | (1 << 11) | (1 << 16);
|
||||
REG_MASTER_BRIGHT = 0;
|
||||
GFX_PLTT_BG_SUB[0] = 0;
|
||||
REG_MASTER_BRIGHT_SUB = 0x8010;
|
||||
REG_DISPCNT_SUB = 0x10000;
|
||||
while (true);
|
||||
}
|
||||
11
arm9/source/errorDisplay/ErrorDisplay.h
Normal file
11
arm9/source/errorDisplay/ErrorDisplay.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
/// @brief Class for displaying a critical error message.
|
||||
class ErrorDisplay
|
||||
{
|
||||
public:
|
||||
/// @brief Displays the given \p errorString and loops.
|
||||
/// @note This function does not return.
|
||||
/// @param errorString The error string to display.
|
||||
void PrintError(const char* errorString);
|
||||
};
|
||||
104
arm9/source/errorDisplay/nitroFont2.cpp
Normal file
104
arm9/source/errorDisplay/nitroFont2.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
#include "common.h"
|
||||
#include "nitroFont2.h"
|
||||
|
||||
bool nft2_unpack(nft2_header_t* font)
|
||||
{
|
||||
if (font->signature != NFT2_SIGNATURE)
|
||||
return false;
|
||||
|
||||
font->glyphInfoPtr = (const nft2_glyph_t*)((u32)font + (u32)font->glyphInfoPtr);
|
||||
font->charMapPtr = (const nft2_char_map_entry_t*)((u32)font + (u32)font->charMapPtr);
|
||||
font->glyphDataPtr = (const u8*)((u32)font + (u32)font->glyphDataPtr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int nft2_findGlyphIdxForCharacter(const nft2_header_t* font, u16 character)
|
||||
{
|
||||
const nft2_char_map_entry_t* charMapEntry = font->charMapPtr;
|
||||
while (charMapEntry->count > 0)
|
||||
{
|
||||
if (charMapEntry->startChar <= character && character < charMapEntry->startChar + charMapEntry->count)
|
||||
return charMapEntry->glyphs[character - charMapEntry->startChar];
|
||||
|
||||
charMapEntry = (const nft2_char_map_entry_t*)((u32)charMapEntry + 4 + 2 * charMapEntry->count);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void renderGlyph(const nft2_header_t* font, const nft2_glyph_t* glyph,
|
||||
int xPos, int yPos, int width, int height, u8* dst, u32 stride)
|
||||
{
|
||||
int yOffset = glyph->spacingTop;
|
||||
u32 xStart = xPos < 0 ? -xPos : 0;
|
||||
u32 yStart = yPos + yOffset < 0 ? -(yPos + yOffset) : 0;
|
||||
|
||||
int xEnd = glyph->glyphWidth;
|
||||
if (xPos + xEnd > width)
|
||||
{
|
||||
// by returning we only render complete glyphs
|
||||
return;
|
||||
// old code for rendering partial glyphs
|
||||
// xEnd = width - xPos;
|
||||
}
|
||||
|
||||
int yEnd = glyph->glyphHeight;
|
||||
if (yPos + yOffset + yEnd > height)
|
||||
yEnd = height - (yPos + yOffset); // allow partial glyphs in the vertical direction
|
||||
|
||||
const u8* glyphData = &font->glyphDataPtr[glyph->dataOffset];
|
||||
glyphData += yStart * ((glyph->glyphWidth + 1) >> 1);
|
||||
for (int y = yStart; y < yEnd; y++)
|
||||
{
|
||||
for (int x = xStart; x < xEnd; x++)
|
||||
{
|
||||
u32 data = glyphData[x >> 1];
|
||||
if ((x & 1) == 0)
|
||||
data &= 0xF;
|
||||
else
|
||||
data >>= 4;
|
||||
|
||||
if (data == 0)
|
||||
continue;
|
||||
|
||||
u32 finalX = x + xPos;
|
||||
u32 finalY = y + yPos + yOffset;
|
||||
|
||||
dst[finalY * stride + finalX] = data;
|
||||
}
|
||||
glyphData += (glyph->glyphWidth + 1) >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
ITCM_CODE void nft2_renderString(const nft2_header_t* font, const char* string, u8* dst, u32 stride,
|
||||
nft2_string_render_params_t* renderParams)
|
||||
{
|
||||
int xPos = renderParams->x;
|
||||
int yPos = renderParams->y;
|
||||
u32 textWidth = 0;
|
||||
while (true)
|
||||
{
|
||||
char c = *string++;
|
||||
if (c == 0)
|
||||
break;
|
||||
if (c == '\n')
|
||||
{
|
||||
xPos = renderParams->x;
|
||||
yPos += font->ascend + font->descend + 1;
|
||||
if (yPos >= (int)renderParams->height)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
int glyphIdx = nft2_findGlyphIdxForCharacter(font, c);
|
||||
const nft2_glyph_t* glyph = &font->glyphInfoPtr[glyphIdx];
|
||||
xPos += glyph->spacingLeft;
|
||||
renderGlyph(font, glyph, xPos, yPos, renderParams->width, renderParams->height, dst, stride);
|
||||
xPos += glyph->glyphWidth;
|
||||
if (xPos > (int)textWidth)
|
||||
textWidth = xPos;
|
||||
xPos += glyph->spacingRight;
|
||||
}
|
||||
renderParams->textWidth = textWidth;
|
||||
}
|
||||
62
arm9/source/errorDisplay/nitroFont2.h
Normal file
62
arm9/source/errorDisplay/nitroFont2.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#define NFT2_SIGNATURE 0x3254464E
|
||||
|
||||
struct nft2_glyph_t
|
||||
{
|
||||
u32 dataOffset : 24;
|
||||
u32 glyphWidth : 8;
|
||||
s8 spacingLeft;
|
||||
s8 spacingRight;
|
||||
u8 glyphHeight;
|
||||
s8 spacingTop;
|
||||
};
|
||||
|
||||
struct nft2_char_map_entry_t
|
||||
{
|
||||
u16 count;
|
||||
u16 startChar;
|
||||
u16 glyphs[1];
|
||||
};
|
||||
|
||||
struct nft2_header_t
|
||||
{
|
||||
u32 signature;
|
||||
const nft2_glyph_t* glyphInfoPtr;
|
||||
const nft2_char_map_entry_t* charMapPtr;
|
||||
const u8* glyphDataPtr;
|
||||
u8 ascend;
|
||||
u8 descend;
|
||||
u16 glyphCount;
|
||||
};
|
||||
|
||||
struct nft2_string_render_params_t
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
u32 width;
|
||||
u32 height;
|
||||
u32 textWidth;
|
||||
};
|
||||
|
||||
/// @brief Prepares the ntf2 data of the given \p font for runtime use.
|
||||
/// Call this method once after loading a font file.
|
||||
/// @param font The font to prepare.
|
||||
/// @return True if preparing was successful, or false otherwise.
|
||||
bool nft2_unpack(nft2_header_t* font);
|
||||
|
||||
/// @brief Finds the glyph index in the given \p font that corresponds to the given \p character.
|
||||
/// @param font The font the find the glyph index in.
|
||||
/// @param character The character to find the glyph index for.
|
||||
/// @return The glyph index if found, or 0 otherwise.
|
||||
int nft2_findGlyphIdxForCharacter(const nft2_header_t* font, u16 character);
|
||||
|
||||
/// @brief Renders the given \p string with the given \p font to the \p dst buffer
|
||||
/// with the given \p stride and \p renderParams.
|
||||
/// @param font The font to use.
|
||||
/// @param string The string to render.
|
||||
/// @param dst The destination buffer.
|
||||
/// @param stride The stride of the destination buffer.
|
||||
/// @param renderParams The render params.
|
||||
void nft2_renderString(const nft2_header_t* font, const char* string, u8* dst,
|
||||
u32 stride, nft2_string_render_params_t* renderParams);
|
||||
Reference in New Issue
Block a user