diff --git a/gflib/text.c b/gflib/text.c index a9c3c98ed..ad26da0b6 100644 --- a/gflib/text.c +++ b/gflib/text.c @@ -42,8 +42,38 @@ static u32 GetGlyphWidth_SmallNarrower(u16, bool32); static u32 GetGlyphWidth_ShortNarrow(u16, bool32); static void SpriteCB_TextCursor(struct Sprite *sprite); +static EWRAM_DATA struct TextPrinter sTempTextPrinter = {0}; +static EWRAM_DATA struct TextPrinter sTextPrinters[NUM_TEXT_PRINTERS] = {0}; + +static u16 sFontHalfRowLookupTable[0x51]; +static u16 sLastTextBgColor; +static u16 sLastTextFgColor; +static u16 sLastTextShadowColor; + +const struct FontInfo *gFonts; +struct GlyphInfo gGlyphInfo; TextFlags gTextFlags; +static const u8 sFontHalfRowOffsets[] = +{ + 0x00, 0x01, 0x02, 0x00, 0x03, 0x04, 0x05, 0x03, 0x06, 0x07, 0x08, 0x06, 0x00, 0x01, 0x02, 0x00, + 0x09, 0x0A, 0x0B, 0x09, 0x0C, 0x0D, 0x0E, 0x0C, 0x0F, 0x10, 0x11, 0x0F, 0x09, 0x0A, 0x0B, 0x09, + 0x12, 0x13, 0x14, 0x12, 0x15, 0x16, 0x17, 0x15, 0x18, 0x19, 0x1A, 0x18, 0x12, 0x13, 0x14, 0x12, + 0x00, 0x01, 0x02, 0x00, 0x03, 0x04, 0x05, 0x03, 0x06, 0x07, 0x08, 0x06, 0x00, 0x01, 0x02, 0x00, + 0x1B, 0x1C, 0x1D, 0x1B, 0x1E, 0x1F, 0x20, 0x1E, 0x21, 0x22, 0x23, 0x21, 0x1B, 0x1C, 0x1D, 0x1B, + 0x24, 0x25, 0x26, 0x24, 0x27, 0x28, 0x29, 0x27, 0x2A, 0x2B, 0x2C, 0x2A, 0x24, 0x25, 0x26, 0x24, + 0x2D, 0x2E, 0x2F, 0x2D, 0x30, 0x31, 0x32, 0x30, 0x33, 0x34, 0x35, 0x33, 0x2D, 0x2E, 0x2F, 0x2D, + 0x1B, 0x1C, 0x1D, 0x1B, 0x1E, 0x1F, 0x20, 0x1E, 0x21, 0x22, 0x23, 0x21, 0x1B, 0x1C, 0x1D, 0x1B, + 0x36, 0x37, 0x38, 0x36, 0x39, 0x3A, 0x3B, 0x39, 0x3C, 0x3D, 0x3E, 0x3C, 0x36, 0x37, 0x38, 0x36, + 0x3F, 0x40, 0x41, 0x3F, 0x42, 0x43, 0x44, 0x42, 0x45, 0x46, 0x47, 0x45, 0x3F, 0x40, 0x41, 0x3F, + 0x48, 0x49, 0x4A, 0x48, 0x4B, 0x4C, 0x4D, 0x4B, 0x4E, 0x4F, 0x50, 0x4E, 0x48, 0x49, 0x4A, 0x48, + 0x36, 0x37, 0x38, 0x36, 0x39, 0x3A, 0x3B, 0x39, 0x3C, 0x3D, 0x3E, 0x3C, 0x36, 0x37, 0x38, 0x36, + 0x00, 0x01, 0x02, 0x00, 0x03, 0x04, 0x05, 0x03, 0x06, 0x07, 0x08, 0x06, 0x00, 0x01, 0x02, 0x00, + 0x09, 0x0A, 0x0B, 0x09, 0x0C, 0x0D, 0x0E, 0x0C, 0x0F, 0x10, 0x11, 0x0F, 0x09, 0x0A, 0x0B, 0x09, + 0x12, 0x13, 0x14, 0x12, 0x15, 0x16, 0x17, 0x15, 0x18, 0x19, 0x1A, 0x18, 0x12, 0x13, 0x14, 0x12, + 0x00, 0x01, 0x02, 0x00, 0x03, 0x04, 0x05, 0x03, 0x06, 0x07, 0x08, 0x06, 0x00, 0x01, 0x02, 0x00 +}; + static const u8 sDownArrowTiles[] = INCBIN_U8("graphics/fonts/down_arrow.4bpp"); static const u8 sDarkDownArrowTiles[] = INCBIN_U8("graphics/fonts/down_arrow_RS.4bpp"); static const u8 sTinyArrowTiles[] = INCBIN_U8("graphics/fonts/down_arrow_2.4bpp"); @@ -588,6 +618,277 @@ ALIGNED(4) const u8 gFontShortNarrowLatinGlyphWidths[] = { static const u16 sFontBoldJapaneseGlyphs[] = INCBIN_U16("graphics/fonts/japanese_bold.fwjpnfont"); +void SetFontsPointer(const struct FontInfo *fonts) +{ + gFonts = fonts; +} + +void DeactivateAllTextPrinters (void) +{ + int printer; + for (printer = 0; printer < NUM_TEXT_PRINTERS; ++printer) + sTextPrinters[printer].active = 0; +} + +u16 AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 *str, u8 x, u8 y, u8 speed, void (*callback)(struct TextPrinterTemplate *, u16)) +{ + struct TextPrinterTemplate printerTemplate; + + printerTemplate.currentChar = str; + printerTemplate.windowId = windowId; + printerTemplate.fontId = fontId; + printerTemplate.x = x; + printerTemplate.y = y; + printerTemplate.currentX = x; + printerTemplate.currentY = y; + printerTemplate.letterSpacing = gFonts[fontId].letterSpacing; + printerTemplate.lineSpacing = gFonts[fontId].lineSpacing; + printerTemplate.unk = gFonts[fontId].unk; + printerTemplate.fgColor = gFonts[fontId].fgColor; + printerTemplate.bgColor = gFonts[fontId].bgColor; + printerTemplate.shadowColor = gFonts[fontId].shadowColor; + return AddTextPrinter(&printerTemplate, speed, callback); +} + +bool16 AddTextPrinter(struct TextPrinterTemplate *textSubPrinter, u8 speed, void (*callback)(struct TextPrinterTemplate *, u16)) +{ + int i; + u16 j; + + if (!gFonts) + return FALSE; + + sTempTextPrinter.active = TRUE; + sTempTextPrinter.state = RENDER_STATE_HANDLE_CHAR; + sTempTextPrinter.textSpeed = speed; + sTempTextPrinter.delayCounter = 0; + sTempTextPrinter.scrollDistance = 0; + + for (i = 0; i < (int)ARRAY_COUNT(sTempTextPrinter.subUnion.fields); ++i) + sTempTextPrinter.subUnion.fields[i] = 0; + + sTempTextPrinter.printerTemplate = *textSubPrinter; + sTempTextPrinter.callback = callback; + sTempTextPrinter.minLetterSpacing = 0; + sTempTextPrinter.japanese = 0; + + GenerateFontHalfRowLookupTable(textSubPrinter->fgColor, textSubPrinter->bgColor, textSubPrinter->shadowColor); + if (speed != TEXT_SKIP_DRAW && speed != 0) + { + --sTempTextPrinter.textSpeed; + sTextPrinters[textSubPrinter->windowId] = sTempTextPrinter; + } + else + { + sTempTextPrinter.textSpeed = 0; + + // Render all text (up to limit) at once + for (j = 0; j < 0x400; ++j) + { + if (RenderFont(&sTempTextPrinter) == RENDER_FINISH) + break; + } + + // All the text is rendered to the window but don't draw it yet. + if (speed != TEXT_SKIP_DRAW) + CopyWindowToVram(sTempTextPrinter.printerTemplate.windowId, COPYWIN_GFX); + sTextPrinters[textSubPrinter->windowId].active = FALSE; + } + return TRUE; +} + +void RunTextPrinters(void) +{ + int i; + + for (i = 0; i < NUM_TEXT_PRINTERS; ++i) + { + if (sTextPrinters[i].active) + { + u16 renderCmd = RenderFont(&sTextPrinters[i]); + switch (renderCmd) + { + case RENDER_PRINT: + CopyWindowToVram(sTextPrinters[i].printerTemplate.windowId, COPYWIN_GFX); + case RENDER_UPDATE: + if (sTextPrinters[i].callback != NULL) + sTextPrinters[i].callback(&sTextPrinters[i].printerTemplate, renderCmd); + break; + case RENDER_FINISH: + sTextPrinters[i].active = FALSE; + break; + } + } + } +} + +void GenerateFontHalfRowLookupTable(u8 fgColor, u8 bgColor, u8 shadowColor) +{ + int lutIndex; + int i, j, k, l; + const u32 colors[] = {bgColor, fgColor, shadowColor}; + + sLastTextBgColor = bgColor; + sLastTextFgColor = fgColor; + sLastTextShadowColor = shadowColor; + + lutIndex = 0; + + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) + for (k = 0; k < 3; k++) + for (l = 0; l < 3; l++) + sFontHalfRowLookupTable[lutIndex++] = (colors[l] << 12) | (colors[k] << 8) | (colors[j] << 4) | colors[i]; +} + +bool16 IsTextPrinterActive(u8 id) +{ + return sTextPrinters[id].active; +} + +u32 RenderFont(struct TextPrinter *textPrinter) +{ + u32 ret; + while (TRUE) + { + ret = gFonts[textPrinter->printerTemplate.fontId].fontFunction(textPrinter); + if (ret != 2) + return ret; + } +} + +void SaveTextColors(u8 *fgColor, u8 *bgColor, u8 *shadowColor) +{ + *bgColor = sLastTextBgColor; + *fgColor = sLastTextFgColor; + *shadowColor = sLastTextShadowColor; +} + +void RestoreTextColors(u8 *fgColor, u8 *bgColor, u8 *shadowColor) +{ + GenerateFontHalfRowLookupTable(*fgColor, *bgColor, *shadowColor); +} + +void DecompressGlyphTile(const u16 *src, u16 *dest) +{ + int i; + + for (i = 0; i < 16; i++) + { + int offsetIndex = (i << 31) != 0 ? (u8)*src++ : (*src >> 8); + dest[i] = sFontHalfRowLookupTable[sFontHalfRowOffsets[offsetIndex]]; + } +} + + +u8 GetLastTextColor(u8 colorType) +{ + switch (colorType) + { + case 0: + return sLastTextFgColor; + case 2: + return sLastTextBgColor; + case 1: + return sLastTextShadowColor; + default: + return 0; + } +} + +#define GLYPH_COPY(widthOffset, heightOffset, width, height, tilesDest, left, top, sizeX) \ +{ \ + int xAdd, xpos, yAdd, ypos, toOrr, bits; \ + u8 * src, * dst; \ + u32 _8pixbuf; \ + \ + src = gGlyphInfo.pixels + (heightOffset / 8 * 0x40) + (widthOffset / 8 * 0x20); \ + for (yAdd = 0, ypos = top + heightOffset; yAdd < height; yAdd++, ypos++) \ + { \ + _8pixbuf = *(u32 *)src; \ + for (xAdd = 0, xpos = left + widthOffset; xAdd < width; xAdd++, xpos++) \ + { \ + dst = (u8 *)((tilesDest) + ((xpos >> 1) & 3) + ((xpos >> 3) << 5) + (((ypos >> 3) * (sizeX)) << 5) + ((u32)(ypos << 29) >> 27)); \ + toOrr = (_8pixbuf >> (xAdd * 4)) & 0xF; \ + if (toOrr != 0) \ + { \ + bits = (xpos & 1) * 4; \ + *dst = (toOrr << bits) | (*dst & (0xF0 >> bits)); \ + } \ + } \ + src += 4; \ + } \ +} + +void CopyGlyphToWindow(struct TextPrinter *textPrinter) +{ + int glyphWidth, glyphHeight; + u8 sizeType; + + if (gWindows[textPrinter->printerTemplate.windowId].window.width * 8 - textPrinter->printerTemplate.currentX < gGlyphInfo.width) + glyphWidth = gWindows[textPrinter->printerTemplate.windowId].window.width * 8 - textPrinter->printerTemplate.currentX; + else + glyphWidth = gGlyphInfo.width; + if (gWindows[textPrinter->printerTemplate.windowId].window.height * 8 - textPrinter->printerTemplate.currentY < gGlyphInfo.height) + glyphHeight = gWindows[textPrinter->printerTemplate.windowId].window.height * 8 - textPrinter->printerTemplate.currentY; + else + glyphHeight = gGlyphInfo.height; + + sizeType = 0; + if (glyphWidth > 8) + sizeType |= 1; + if (glyphHeight > 8) + sizeType |= 2; + + switch (sizeType) + { + case 0: // ≤ 8x8 + GLYPH_COPY(0, 0, glyphWidth, glyphHeight, gWindows[textPrinter->printerTemplate.windowId].tileData, textPrinter->printerTemplate.currentX, textPrinter->printerTemplate.currentY, ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8 + ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8) & 7)) >> 3)); + return; + case 1: // ≤ 16x8 + GLYPH_COPY(0, 0, 8, glyphHeight, gWindows[textPrinter->printerTemplate.windowId].tileData, textPrinter->printerTemplate.currentX, textPrinter->printerTemplate.currentY, ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8 + ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8) & 7)) >> 3)); + GLYPH_COPY(8, 0, glyphWidth - 8, glyphHeight, gWindows[textPrinter->printerTemplate.windowId].tileData, textPrinter->printerTemplate.currentX, textPrinter->printerTemplate.currentY, ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8 + ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8) & 7)) >> 3)); + return; + case 2: // ≤ 8x16 + GLYPH_COPY(0, 0, glyphWidth, 8, gWindows[textPrinter->printerTemplate.windowId].tileData, textPrinter->printerTemplate.currentX, textPrinter->printerTemplate.currentY, ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8 + ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8) & 7)) >> 3)); + GLYPH_COPY(0, 8, glyphWidth, glyphHeight - 8, gWindows[textPrinter->printerTemplate.windowId].tileData, textPrinter->printerTemplate.currentX, textPrinter->printerTemplate.currentY, ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8 + ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8) & 7)) >> 3)); + return; + case 3: // ≤ 16x16 + GLYPH_COPY(0, 0, 8, 8, gWindows[textPrinter->printerTemplate.windowId].tileData, textPrinter->printerTemplate.currentX, textPrinter->printerTemplate.currentY, ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8 + ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8) & 7)) >> 3)); + GLYPH_COPY(8, 0, glyphWidth - 8, 8, gWindows[textPrinter->printerTemplate.windowId].tileData, textPrinter->printerTemplate.currentX, textPrinter->printerTemplate.currentY, ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8 + ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8) & 7)) >> 3)); + GLYPH_COPY(0, 8, 8, glyphHeight - 8, gWindows[textPrinter->printerTemplate.windowId].tileData, textPrinter->printerTemplate.currentX, textPrinter->printerTemplate.currentY, ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8 + ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8) & 7)) >> 3)); + GLYPH_COPY(8, 8, glyphWidth - 8, glyphHeight - 8, gWindows[textPrinter->printerTemplate.windowId].tileData, textPrinter->printerTemplate.currentX, textPrinter->printerTemplate.currentY, ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8 + ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8) & 7)) >> 3)); + return; + } +} + +void ClearTextSpan(struct TextPrinter *textPrinter, u32 width) +{ + struct Window *window; + struct Bitmap pixels_data; + struct GlyphInfo *glyph; + u8 *glyphHeight; + + if (sLastTextBgColor != TEXT_COLOR_TRANSPARENT) + { + window = &gWindows[textPrinter->printerTemplate.windowId]; + pixels_data.pixels = window->tileData; + pixels_data.width = window->window.width << 3; + pixels_data.height = window->window.height << 3; + + glyph = &gGlyphInfo; + glyphHeight = &glyph->height; + + FillBitmapRect4Bit( + &pixels_data, + textPrinter->printerTemplate.currentX, + textPrinter->printerTemplate.currentY, + width, + *glyphHeight, + sLastTextBgColor); + } +} + u16 FontFunc_Small(struct TextPrinter *textPrinter) { struct TextPrinterSubStruct *subStruct = &textPrinter->subUnion.sub; diff --git a/src/text_printer.c b/src/text_printer.c deleted file mode 100644 index 034f07721..000000000 --- a/src/text_printer.c +++ /dev/null @@ -1,305 +0,0 @@ -#include "global.h" -#include "blit.h" -#include "window.h" -#include "text.h" - -static EWRAM_DATA struct TextPrinter sTempTextPrinter = {0}; -static EWRAM_DATA struct TextPrinter sTextPrinters[NUM_TEXT_PRINTERS] = {0}; - -static u16 sFontHalfRowLookupTable[0x51]; -static u16 sLastTextBgColor; -static u16 sLastTextFgColor; -static u16 sLastTextShadowColor; - -const struct FontInfo *gFonts; -struct GlyphInfo gGlyphInfo; - -static const u8 sFontHalfRowOffsets[] = -{ - 0x00, 0x01, 0x02, 0x00, 0x03, 0x04, 0x05, 0x03, 0x06, 0x07, 0x08, 0x06, 0x00, 0x01, 0x02, 0x00, - 0x09, 0x0A, 0x0B, 0x09, 0x0C, 0x0D, 0x0E, 0x0C, 0x0F, 0x10, 0x11, 0x0F, 0x09, 0x0A, 0x0B, 0x09, - 0x12, 0x13, 0x14, 0x12, 0x15, 0x16, 0x17, 0x15, 0x18, 0x19, 0x1A, 0x18, 0x12, 0x13, 0x14, 0x12, - 0x00, 0x01, 0x02, 0x00, 0x03, 0x04, 0x05, 0x03, 0x06, 0x07, 0x08, 0x06, 0x00, 0x01, 0x02, 0x00, - 0x1B, 0x1C, 0x1D, 0x1B, 0x1E, 0x1F, 0x20, 0x1E, 0x21, 0x22, 0x23, 0x21, 0x1B, 0x1C, 0x1D, 0x1B, - 0x24, 0x25, 0x26, 0x24, 0x27, 0x28, 0x29, 0x27, 0x2A, 0x2B, 0x2C, 0x2A, 0x24, 0x25, 0x26, 0x24, - 0x2D, 0x2E, 0x2F, 0x2D, 0x30, 0x31, 0x32, 0x30, 0x33, 0x34, 0x35, 0x33, 0x2D, 0x2E, 0x2F, 0x2D, - 0x1B, 0x1C, 0x1D, 0x1B, 0x1E, 0x1F, 0x20, 0x1E, 0x21, 0x22, 0x23, 0x21, 0x1B, 0x1C, 0x1D, 0x1B, - 0x36, 0x37, 0x38, 0x36, 0x39, 0x3A, 0x3B, 0x39, 0x3C, 0x3D, 0x3E, 0x3C, 0x36, 0x37, 0x38, 0x36, - 0x3F, 0x40, 0x41, 0x3F, 0x42, 0x43, 0x44, 0x42, 0x45, 0x46, 0x47, 0x45, 0x3F, 0x40, 0x41, 0x3F, - 0x48, 0x49, 0x4A, 0x48, 0x4B, 0x4C, 0x4D, 0x4B, 0x4E, 0x4F, 0x50, 0x4E, 0x48, 0x49, 0x4A, 0x48, - 0x36, 0x37, 0x38, 0x36, 0x39, 0x3A, 0x3B, 0x39, 0x3C, 0x3D, 0x3E, 0x3C, 0x36, 0x37, 0x38, 0x36, - 0x00, 0x01, 0x02, 0x00, 0x03, 0x04, 0x05, 0x03, 0x06, 0x07, 0x08, 0x06, 0x00, 0x01, 0x02, 0x00, - 0x09, 0x0A, 0x0B, 0x09, 0x0C, 0x0D, 0x0E, 0x0C, 0x0F, 0x10, 0x11, 0x0F, 0x09, 0x0A, 0x0B, 0x09, - 0x12, 0x13, 0x14, 0x12, 0x15, 0x16, 0x17, 0x15, 0x18, 0x19, 0x1A, 0x18, 0x12, 0x13, 0x14, 0x12, - 0x00, 0x01, 0x02, 0x00, 0x03, 0x04, 0x05, 0x03, 0x06, 0x07, 0x08, 0x06, 0x00, 0x01, 0x02, 0x00 -}; - -void SetFontsPointer(const struct FontInfo *fonts) -{ - gFonts = fonts; -} - -void DeactivateAllTextPrinters (void) -{ - int printer; - for (printer = 0; printer < NUM_TEXT_PRINTERS; ++printer) - sTextPrinters[printer].active = 0; -} - -u16 AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 *str, u8 x, u8 y, u8 speed, void (*callback)(struct TextPrinterTemplate *, u16)) -{ - struct TextPrinterTemplate printerTemplate; - - printerTemplate.currentChar = str; - printerTemplate.windowId = windowId; - printerTemplate.fontId = fontId; - printerTemplate.x = x; - printerTemplate.y = y; - printerTemplate.currentX = x; - printerTemplate.currentY = y; - printerTemplate.letterSpacing = gFonts[fontId].letterSpacing; - printerTemplate.lineSpacing = gFonts[fontId].lineSpacing; - printerTemplate.unk = gFonts[fontId].unk; - printerTemplate.fgColor = gFonts[fontId].fgColor; - printerTemplate.bgColor = gFonts[fontId].bgColor; - printerTemplate.shadowColor = gFonts[fontId].shadowColor; - return AddTextPrinter(&printerTemplate, speed, callback); -} - -bool16 AddTextPrinter(struct TextPrinterTemplate *textSubPrinter, u8 speed, void (*callback)(struct TextPrinterTemplate *, u16)) -{ - int i; - u16 j; - - if (!gFonts) - return FALSE; - - sTempTextPrinter.active = TRUE; - sTempTextPrinter.state = RENDER_STATE_HANDLE_CHAR; - sTempTextPrinter.textSpeed = speed; - sTempTextPrinter.delayCounter = 0; - sTempTextPrinter.scrollDistance = 0; - - for (i = 0; i < (int)ARRAY_COUNT(sTempTextPrinter.subUnion.fields); ++i) - sTempTextPrinter.subUnion.fields[i] = 0; - - sTempTextPrinter.printerTemplate = *textSubPrinter; - sTempTextPrinter.callback = callback; - sTempTextPrinter.minLetterSpacing = 0; - sTempTextPrinter.japanese = 0; - - GenerateFontHalfRowLookupTable(textSubPrinter->fgColor, textSubPrinter->bgColor, textSubPrinter->shadowColor); - if (speed != TEXT_SKIP_DRAW && speed != 0) - { - --sTempTextPrinter.textSpeed; - sTextPrinters[textSubPrinter->windowId] = sTempTextPrinter; - } - else - { - sTempTextPrinter.textSpeed = 0; - - // Render all text (up to limit) at once - for (j = 0; j < 0x400; ++j) - { - if (RenderFont(&sTempTextPrinter) == RENDER_FINISH) - break; - } - - // All the text is rendered to the window but don't draw it yet. - if (speed != TEXT_SKIP_DRAW) - CopyWindowToVram(sTempTextPrinter.printerTemplate.windowId, COPYWIN_GFX); - sTextPrinters[textSubPrinter->windowId].active = FALSE; - } - return TRUE; -} - -void RunTextPrinters(void) -{ - int i; - - for (i = 0; i < NUM_TEXT_PRINTERS; ++i) - { - if (sTextPrinters[i].active) - { - u16 renderCmd = RenderFont(&sTextPrinters[i]); - switch (renderCmd) - { - case RENDER_PRINT: - CopyWindowToVram(sTextPrinters[i].printerTemplate.windowId, COPYWIN_GFX); - case RENDER_UPDATE: - if (sTextPrinters[i].callback != NULL) - sTextPrinters[i].callback(&sTextPrinters[i].printerTemplate, renderCmd); - break; - case RENDER_FINISH: - sTextPrinters[i].active = FALSE; - break; - } - } - } -} - -bool16 IsTextPrinterActive(u8 id) -{ - return sTextPrinters[id].active; -} - -u32 RenderFont(struct TextPrinter *textPrinter) -{ - u32 ret; - while (TRUE) - { - ret = gFonts[textPrinter->printerTemplate.fontId].fontFunction(textPrinter); - if (ret != 2) - return ret; - } -} - -void GenerateFontHalfRowLookupTable(u8 fgColor, u8 bgColor, u8 shadowColor) -{ - int lutIndex; - int i, j, k, l; - const u32 colors[] = {bgColor, fgColor, shadowColor}; - - sLastTextBgColor = bgColor; - sLastTextFgColor = fgColor; - sLastTextShadowColor = shadowColor; - - lutIndex = 0; - - for (i = 0; i < 3; i++) - for (j = 0; j < 3; j++) - for (k = 0; k < 3; k++) - for (l = 0; l < 3; l++) - sFontHalfRowLookupTable[lutIndex++] = (colors[l] << 12) | (colors[k] << 8) | (colors[j] << 4) | colors[i]; -} - -void SaveTextColors(u8 *fgColor, u8 *bgColor, u8 *shadowColor) -{ - *bgColor = sLastTextBgColor; - *fgColor = sLastTextFgColor; - *shadowColor = sLastTextShadowColor; -} - -void RestoreTextColors(u8 *fgColor, u8 *bgColor, u8 *shadowColor) -{ - GenerateFontHalfRowLookupTable(*fgColor, *bgColor, *shadowColor); -} - -void DecompressGlyphTile(const u16 *src, u16 *dest) -{ - int i; - - for (i = 0; i < 16; i++) - { - int offsetIndex = (i << 31) != 0 ? (u8)*src++ : (*src >> 8); - dest[i] = sFontHalfRowLookupTable[sFontHalfRowOffsets[offsetIndex]]; - } -} - -u8 GetLastTextColor(u8 colorType) -{ - switch (colorType) - { - case 0: - return sLastTextFgColor; - case 2: - return sLastTextBgColor; - case 1: - return sLastTextShadowColor; - default: - return 0; - } -} - -#define GLYPH_COPY(widthOffset, heightOffset, width, height, tilesDest, left, top, sizeX) \ -{ \ - int xAdd, xpos, yAdd, ypos, toOrr, bits; \ - u8 * src, * dst; \ - u32 _8pixbuf; \ - \ - src = gGlyphInfo.pixels + (heightOffset / 8 * 0x40) + (widthOffset / 8 * 0x20); \ - for (yAdd = 0, ypos = top + heightOffset; yAdd < height; yAdd++, ypos++) \ - { \ - _8pixbuf = *(u32 *)src; \ - for (xAdd = 0, xpos = left + widthOffset; xAdd < width; xAdd++, xpos++) \ - { \ - dst = (u8 *)((tilesDest) + ((xpos >> 1) & 3) + ((xpos >> 3) << 5) + (((ypos >> 3) * (sizeX)) << 5) + ((u32)(ypos << 29) >> 27)); \ - toOrr = (_8pixbuf >> (xAdd * 4)) & 0xF; \ - if (toOrr != 0) \ - { \ - bits = (xpos & 1) * 4; \ - *dst = (toOrr << bits) | (*dst & (0xF0 >> bits)); \ - } \ - } \ - src += 4; \ - } \ -} - -void CopyGlyphToWindow(struct TextPrinter *textPrinter) -{ - int glyphWidth, glyphHeight; - u8 sizeType; - - if (gWindows[textPrinter->printerTemplate.windowId].window.width * 8 - textPrinter->printerTemplate.currentX < gGlyphInfo.width) - glyphWidth = gWindows[textPrinter->printerTemplate.windowId].window.width * 8 - textPrinter->printerTemplate.currentX; - else - glyphWidth = gGlyphInfo.width; - if (gWindows[textPrinter->printerTemplate.windowId].window.height * 8 - textPrinter->printerTemplate.currentY < gGlyphInfo.height) - glyphHeight = gWindows[textPrinter->printerTemplate.windowId].window.height * 8 - textPrinter->printerTemplate.currentY; - else - glyphHeight = gGlyphInfo.height; - - sizeType = 0; - if (glyphWidth > 8) - sizeType |= 1; - if (glyphHeight > 8) - sizeType |= 2; - - switch (sizeType) - { - case 0: // ≤ 8x8 - GLYPH_COPY(0, 0, glyphWidth, glyphHeight, gWindows[textPrinter->printerTemplate.windowId].tileData, textPrinter->printerTemplate.currentX, textPrinter->printerTemplate.currentY, ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8 + ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8) & 7)) >> 3)); - return; - case 1: // ≤ 16x8 - GLYPH_COPY(0, 0, 8, glyphHeight, gWindows[textPrinter->printerTemplate.windowId].tileData, textPrinter->printerTemplate.currentX, textPrinter->printerTemplate.currentY, ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8 + ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8) & 7)) >> 3)); - GLYPH_COPY(8, 0, glyphWidth - 8, glyphHeight, gWindows[textPrinter->printerTemplate.windowId].tileData, textPrinter->printerTemplate.currentX, textPrinter->printerTemplate.currentY, ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8 + ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8) & 7)) >> 3)); - return; - case 2: // ≤ 8x16 - GLYPH_COPY(0, 0, glyphWidth, 8, gWindows[textPrinter->printerTemplate.windowId].tileData, textPrinter->printerTemplate.currentX, textPrinter->printerTemplate.currentY, ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8 + ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8) & 7)) >> 3)); - GLYPH_COPY(0, 8, glyphWidth, glyphHeight - 8, gWindows[textPrinter->printerTemplate.windowId].tileData, textPrinter->printerTemplate.currentX, textPrinter->printerTemplate.currentY, ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8 + ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8) & 7)) >> 3)); - return; - case 3: // ≤ 16x16 - GLYPH_COPY(0, 0, 8, 8, gWindows[textPrinter->printerTemplate.windowId].tileData, textPrinter->printerTemplate.currentX, textPrinter->printerTemplate.currentY, ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8 + ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8) & 7)) >> 3)); - GLYPH_COPY(8, 0, glyphWidth - 8, 8, gWindows[textPrinter->printerTemplate.windowId].tileData, textPrinter->printerTemplate.currentX, textPrinter->printerTemplate.currentY, ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8 + ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8) & 7)) >> 3)); - GLYPH_COPY(0, 8, 8, glyphHeight - 8, gWindows[textPrinter->printerTemplate.windowId].tileData, textPrinter->printerTemplate.currentX, textPrinter->printerTemplate.currentY, ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8 + ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8) & 7)) >> 3)); - GLYPH_COPY(8, 8, glyphWidth - 8, glyphHeight - 8, gWindows[textPrinter->printerTemplate.windowId].tileData, textPrinter->printerTemplate.currentX, textPrinter->printerTemplate.currentY, ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8 + ((gWindows[textPrinter->printerTemplate.windowId].window.width * 8) & 7)) >> 3)); - return; - } -} - -void ClearTextSpan(struct TextPrinter *textPrinter, u32 width) -{ - struct Window *window; - struct Bitmap pixels_data; - struct GlyphInfo *glyph; - u8 *glyphHeight; - - if (sLastTextBgColor != TEXT_COLOR_TRANSPARENT) - { - window = &gWindows[textPrinter->printerTemplate.windowId]; - pixels_data.pixels = window->tileData; - pixels_data.width = window->window.width << 3; - pixels_data.height = window->window.height << 3; - - glyph = &gGlyphInfo; - glyphHeight = &glyph->height; - - FillBitmapRect4Bit( - &pixels_data, - textPrinter->printerTemplate.currentX, - textPrinter->printerTemplate.currentY, - width, - *glyphHeight, - sLastTextBgColor); - } -}