mirror of
https://github.com/pret/pokeruby.git
synced 2026-10-04 08:21:13 -04:00
2ec8ae4bec
cleaning up. Rename DEBUG_TRANSLATE to DEBUG_FIX now that we have actual English Debug ROMs. Add Sapphire German "first edition" debug support, now that we have a hash for it. Fix an obvious nonmatching.
4394 lines
120 KiB
C
4394 lines
120 KiB
C
#include "global.h"
|
|
#include "text.h"
|
|
#include "battle.h"
|
|
#include "main.h"
|
|
#include "palette.h"
|
|
#include "constants/songs.h"
|
|
#include "sound.h"
|
|
#include "string_util.h"
|
|
#include "start_menu.h"
|
|
|
|
enum
|
|
{
|
|
WIN_STATE_END,
|
|
WIN_STATE_BEGIN,
|
|
WIN_STATE_NORMAL,
|
|
WIN_STATE_CHAR_DELAY,
|
|
WIN_STATE_PAUSE,
|
|
WIN_STATE_WAIT_BUTTON,
|
|
WIN_STATE_NEWLINE,
|
|
WIN_STATE_PLACEHOLDER,
|
|
WIN_STATE_WAIT_CLEAR,
|
|
WIN_STATE_WAIT_SCROLL,
|
|
WIN_STATE_WAIT_SOUND,
|
|
};
|
|
|
|
enum
|
|
{
|
|
TEXT_MODE_UNKNOWN0,
|
|
TEXT_MODE_MONOSPACE,
|
|
TEXT_MODE_UNKNOWN2, // variable width?
|
|
};
|
|
|
|
enum
|
|
{
|
|
WAIT_TYPE_NORMAL, // allows the player to interrupt the text delay with A or B
|
|
WAIT_TYPE_BATTLE, // disables interrupting the text delay if in a link battle
|
|
WAIT_TYPE_AUTOSCROLL, // disables interrupting the text delay
|
|
WAIT_TYPE_CONTEST, // disables interrupting the text delay if in a link contest
|
|
};
|
|
|
|
struct Font
|
|
{
|
|
u32 type;
|
|
u8 *glyphs;
|
|
u16 glyphSize;
|
|
u16 lowerTileOffset;
|
|
};
|
|
|
|
struct GlyphBuffer
|
|
{
|
|
// 0-7 left tile
|
|
// 8-15 right tile (if it exists)
|
|
u32 pixelRows[16];
|
|
|
|
// pixel row filled with BG color
|
|
u32 background;
|
|
|
|
// table of color indices (not a palette)
|
|
u32 colors[16];
|
|
};
|
|
|
|
struct GlyphTileInfo
|
|
{
|
|
u8 textMode;
|
|
u8 startPixel;
|
|
u8 width;
|
|
u8 *src;
|
|
u32 *dest;
|
|
u32 *colors;
|
|
};
|
|
|
|
struct ShiftAmount
|
|
{
|
|
u32 left;
|
|
u32 right;
|
|
};
|
|
|
|
static u16 InitVariableWidthFontTileData(struct Window *, u16);
|
|
static u16 LoadFixedWidthFont(struct Window *, u16);
|
|
static u16 LoadFixedWidthFont_Font1Latin(struct Window *, u16);
|
|
static u16 LoadFixedWidthFont_Font4Latin(struct Window *, u16);
|
|
static u16 LoadFixedWidthFont_Braille(struct Window *, u16);
|
|
static void MultistepLoadFont_LoadGlyph(struct Window *, u16, u8);
|
|
static u8 sub_8002FA0(struct Window *, const u8 *);
|
|
static u8 PrintNextChar(struct Window *);
|
|
static u8 HandleExtCtrlCode(struct Window *);
|
|
static u8 UpdateWindowText(struct Window *);
|
|
static u8 DrawGlyph_TextMode0(struct Window *, u32);
|
|
static void DrawGlyph_TextMode2(struct Window *, u32);
|
|
static void LoadFixedWidthGlyph(struct Window *, u32, u8 *);
|
|
static void WriteGlyphTilemap(struct Window *, u16, u16);
|
|
static void GetGlyphTilePointers(u8, u8, u16, u8 **, u8 **);
|
|
static u16 *GetCursorTilemapPointer(struct Window *);
|
|
static void ApplyColors_UnshadowedFont(const u8 *, u32 *, u8, u8);
|
|
static void ApplyColors_ShadowedFont(const void *, void *, u8, u8, u8);
|
|
static void SetCursorX(struct Window *, u8);
|
|
static void AddToCursorX(struct Window *, u8);
|
|
static void AddToCursorY(struct Window *, u8);
|
|
static void ClipLeft(struct Window *);
|
|
static void ClipRight(struct Window *);
|
|
static void SetWindowDefaultColors(struct Window *);
|
|
static void SetWindowBackgroundColor(struct Window *, u8);
|
|
static void SetWindowShadowColor(struct Window *, u8);
|
|
static void SetWindowForegroundColor(struct Window *, u8);
|
|
static u8 GetTextDelay(struct Window *);
|
|
static bool8 PlayerCanInterruptDelay(struct Window *);
|
|
static void ScrollWindowTextLines(struct Window *);
|
|
static void ScrollWindowTextLines_TextMode0(struct Window *);
|
|
static void DoScroll_TextMode0(struct Window *, u16);
|
|
static void ScrollWindowTextLines_TextModeMonospace(struct Window *);
|
|
static void DoScroll_TextModeMonospace(struct Window *, u16);
|
|
static void ScrollWindowTextLines_TextMode2(struct Window *);
|
|
static void DoScroll_TextMode2(struct Window *, u8);
|
|
void Text_ClearWindow(struct Window *);
|
|
static void ClearWindowTextLines_TextMode0_TextMode1(struct Window *, u8);
|
|
static void ClearWindowTextLines_TextMode2(struct Window *, u8);
|
|
static void TryEraseDownArrow(struct Window *);
|
|
static u16 GetBlankTileNum(struct Window *);
|
|
static u8 WaitWithDownArrow(struct Window *);
|
|
static void DrawInitialDownArrow(struct Window *);
|
|
static void UpdateDownArrowAnimation(struct Window *);
|
|
static u16 GetCursorTileNum(struct Window *, u32, u32);
|
|
static s32 DrawGlyphTiles(struct Window *, u32, u32);
|
|
static void UpdateTilemap(struct Window *, u32);
|
|
static u8 GetGlyphWidth(struct Window *, u32);
|
|
static s32 DrawGlyphTile_ShadowedFont(struct GlyphTileInfo *);
|
|
|
|
static void PrintGlyph_TextMode0(struct Window *, u32);
|
|
static void PrintGlyph_TextMode1(struct Window *, u32);
|
|
static void PrintGlyph_TextMode2(struct Window *, u32);
|
|
|
|
static void WriteGlyphTilemap_Font0_Font3(struct Window *, u32);
|
|
static void WriteGlyphTilemap_Font1_Font4(struct Window *, u32);
|
|
static void WriteGlyphTilemap_Font2_Font5(struct Window *, u32);
|
|
static void WriteGlyphTilemap_Font1_Font4(struct Window *, u32);
|
|
static void WriteGlyphTilemap_Font2_Font5(struct Window *, u32);
|
|
static void WriteGlyphTilemap_Font6(struct Window *, u32);
|
|
|
|
static u8 ExtCtrlCode_Nop(struct Window *);
|
|
static u8 ExtCtrlCode_ForegroundColor(struct Window *);
|
|
static u8 ExtCtrlCode_BackgroundColor(struct Window *);
|
|
static u8 ExtCtrlCode_ShadowColor(struct Window *);
|
|
static u8 ExtCtrlCode_AllColors(struct Window *);
|
|
static u8 ExtCtrlCode_Palette(struct Window *);
|
|
static u8 ExtCtrlCode_Font(struct Window *);
|
|
static u8 ExtCtrlCode_DefaultFont(struct Window *);
|
|
static u8 ExtCtrlCode_Pause(struct Window *);
|
|
static u8 ExtCtrlCode_WaitButton(struct Window *);
|
|
static u8 ExtCtrlCode_WaitSound(struct Window *);
|
|
static u8 ExtCtrlCode_PlayBGM(struct Window *);
|
|
static u8 ExtCtrlCode_Escape(struct Window *);
|
|
static u8 ExtCtrlCode_Nop2(struct Window *);
|
|
static u8 ExtCtrlCode_SetCursorY(struct Window *);
|
|
static u8 ExtCtrlCode_ClearWindowTextLines(struct Window *);
|
|
static u8 ExtCtrlCode_PlaySE(struct Window *);
|
|
static u8 ExtCtrlCode_Skip(struct Window *);
|
|
static u8 ExtCtrlCode_SetCursorX(struct Window *);
|
|
static u8 ExtCtrlCode_SkipTo(struct Window *);
|
|
static u8 ExtCtrlCode_Spacing(struct Window *);
|
|
static u8 ExtCtrlCode_Japanese(struct Window *);
|
|
static u8 ExtCtrlCode_Latin(struct Window *);
|
|
|
|
static void ShiftGlyphTile_UnshadowedFont_Width0(struct GlyphBuffer *, u8 *, u32 *, u8);
|
|
static void ShiftGlyphTile_UnshadowedFont_Width1(struct GlyphBuffer *, u8 *, u32 *, u8);
|
|
static void ShiftGlyphTile_UnshadowedFont_Width2(struct GlyphBuffer *, u8 *, u32 *, u8);
|
|
static void ShiftGlyphTile_UnshadowedFont_Width3(struct GlyphBuffer *, u8 *, u32 *, u8);
|
|
static void ShiftGlyphTile_UnshadowedFont_Width4(struct GlyphBuffer *, u8 *, u32 *, u8);
|
|
static void ShiftGlyphTile_UnshadowedFont_Width5(struct GlyphBuffer *, u8 *, u32 *, u8);
|
|
static void ShiftGlyphTile_UnshadowedFont_Width6(struct GlyphBuffer *, u8 *, u32 *, u8);
|
|
static void ShiftGlyphTile_UnshadowedFont_Width7(struct GlyphBuffer *, u8 *, u32 *, u8);
|
|
static void ShiftGlyphTile_UnshadowedFont_Width8(struct GlyphBuffer *, u8 *, u32 *, u8);
|
|
|
|
static void ShiftGlyphTile_ShadowedFont_Width0(struct GlyphBuffer *, u32 *, u32 *, u8);
|
|
static void ShiftGlyphTile_ShadowedFont_Width1(struct GlyphBuffer *, u32 *, u32 *, u8);
|
|
static void ShiftGlyphTile_ShadowedFont_Width2(struct GlyphBuffer *, u32 *, u32 *, u8);
|
|
static void ShiftGlyphTile_ShadowedFont_Width3(struct GlyphBuffer *, u32 *, u32 *, u8);
|
|
static void ShiftGlyphTile_ShadowedFont_Width4(struct GlyphBuffer *, u32 *, u32 *, u8);
|
|
static void ShiftGlyphTile_ShadowedFont_Width5(struct GlyphBuffer *, u32 *, u32 *, u8);
|
|
static void ShiftGlyphTile_ShadowedFont_Width6(struct GlyphBuffer *, u32 *, u32 *, u8);
|
|
static void ShiftGlyphTile_ShadowedFont_Width7(struct GlyphBuffer *, u32 *, u32 *, u8);
|
|
static void ShiftGlyphTile_ShadowedFont_Width8(struct GlyphBuffer *, u32 *, u32 *, u8);
|
|
|
|
static struct Window *sMultistepLoadFont_Window;
|
|
static u16 sMultistepLoadFont_StartOffset;
|
|
static u16 sMultistepLoadFont_Index;
|
|
static struct Window sTempWindow;
|
|
static u8 sWaitType;
|
|
static u8 sLineLength;
|
|
static struct GlyphBuffer sGlyphBuffer;
|
|
|
|
EWRAM_DATA u16 gBGTilemapBuffers[4][0x400] = {0};
|
|
|
|
EWRAM_DATA u8 gStringVar1[0x100] = {0};
|
|
EWRAM_DATA u8 gStringVar2[0x100] = {0};
|
|
EWRAM_DATA u8 gStringVar3[0x100] = {0};
|
|
EWRAM_DATA u8 gStringVar4[0x100] = {0};
|
|
|
|
extern u16 gBattleTypeFlags;
|
|
extern u8 gIsLinkContest;
|
|
extern u8 gTileBuffer[];
|
|
|
|
vu16 *const gBGControlRegs[] =
|
|
{
|
|
®_BG0CNT,
|
|
®_BG1CNT,
|
|
®_BG2CNT,
|
|
®_BG3CNT,
|
|
};
|
|
|
|
vu16 *const gBGHOffsetRegs[] =
|
|
{
|
|
®_BG0HOFS,
|
|
®_BG1HOFS,
|
|
®_BG2HOFS,
|
|
®_BG3HOFS,
|
|
};
|
|
|
|
vu16 *const gBGVOffsetRegs[] =
|
|
{
|
|
®_BG0VOFS,
|
|
®_BG1VOFS,
|
|
®_BG2VOFS,
|
|
®_BG3VOFS,
|
|
};
|
|
|
|
const u16 gUnknown_081E29D8[] = { 0x100, 0x200, 0x400, 0x800 };
|
|
const u16 gUnknown_081E29E0[] = { 0x100, 0x200, 0x400, 0x800 };
|
|
const u16 gUnknown_081E29E8[] = { 1, 2, 4, 8 };
|
|
|
|
static const u8 sFont0LatinGlyphs[] = INCBIN_U8("graphics/fonts/font0_lat.1bpp");
|
|
static const u8 sFont1LatinGlyphs[] = INCBIN_U8("graphics/fonts/font1_lat.1bpp");
|
|
static const u8 sFont0JapaneseGlyphs[] = INCBIN_U8("graphics/fonts/font0_jpn.1bpp");
|
|
static const u8 sFont1JapaneseGlyphs[] = INCBIN_U8("graphics/fonts/font1_jpn.1bpp");
|
|
static const u8 sBrailleGlyphs[] = INCBIN_U8("graphics/fonts/font6_braille.1bpp");
|
|
static const u32 sDownArrowTiles[] = INCBIN_U32("graphics/fonts/down_arrow.4bpp");
|
|
|
|
// clang-format off
|
|
#include "data/text/type1_map.h"
|
|
#include "data/text/type3_map.h"
|
|
#include "data/text/font1_widths.h"
|
|
#include "data/text/font4_widths.h"
|
|
#include "data/text/font0_widths.h"
|
|
#include "data/text/font3_widths.h"
|
|
// clang-format on
|
|
|
|
const u16 gUnknownPalette_81E6692[] = INCBIN_U16("graphics/fonts/unknown_81E6692.gbapal");
|
|
const u16 gFontDefaultPalette[] = INCBIN_U16("graphics/fonts/default.gbapal");
|
|
|
|
const u8 sBlankTile[8] = { 0, 0, 0, 0, 0, 0, 0, 0, };
|
|
|
|
static const u32 sGlyphMasks[9][8][3] =
|
|
{
|
|
{
|
|
{ 0xFFFFFFFF,0xFFFFFFFF,0x00000000, },
|
|
{ 0xFFFFFFFF,0xFFFFFFFF,0x00000000, },
|
|
{ 0xFFFFFFFF,0xFFFFFFFF,0x00000000, },
|
|
{ 0xFFFFFFFF,0xFFFFFFFF,0x00000000, },
|
|
{ 0xFFFFFFFF,0xFFFFFFFF,0x00000000, },
|
|
{ 0xFFFFFFFF,0xFFFFFFFF,0x00000000, },
|
|
{ 0xFFFFFFFF,0xFFFFFFFF,0x00000000, },
|
|
{ 0xFFFFFFFF,0xFFFFFFFF,0x00000000, },
|
|
},
|
|
{
|
|
{ 0x00000000,0xFFFFFFFF,0xFFFFFFF0, },
|
|
{ 0x0000000F,0xFFFFFFFF,0xFFFFFF00, },
|
|
{ 0x000000FF,0xFFFFFFFF,0xFFFFF000, },
|
|
{ 0x00000FFF,0xFFFFFFFF,0xFFFF0000, },
|
|
{ 0x0000FFFF,0xFFFFFFFF,0xFFF00000, },
|
|
{ 0x000FFFFF,0xFFFFFFFF,0xFF000000, },
|
|
{ 0x00FFFFFF,0xFFFFFFFF,0xF0000000, },
|
|
{ 0x0FFFFFFF,0xFFFFFFFF,0x00000000, },
|
|
},
|
|
{
|
|
{ 0x00000000,0xFFFFFFFF,0xFFFFFF00, },
|
|
{ 0x0000000F,0xFFFFFFFF,0xFFFFF000, },
|
|
{ 0x000000FF,0xFFFFFFFF,0xFFFF0000, },
|
|
{ 0x00000FFF,0xFFFFFFFF,0xFFF00000, },
|
|
{ 0x0000FFFF,0xFFFFFFFF,0xFF000000, },
|
|
{ 0x000FFFFF,0xFFFFFFFF,0xF0000000, },
|
|
{ 0x00FFFFFF,0xFFFFFFFF,0x00000000, },
|
|
{ 0x0FFFFFFF,0xFFFFFFF0,0x00000000, },
|
|
},
|
|
{
|
|
{ 0x00000000,0xFFFFFFFF,0xFFFFF000, },
|
|
{ 0x0000000F,0xFFFFFFFF,0xFFFF0000, },
|
|
{ 0x000000FF,0xFFFFFFFF,0xFFF00000, },
|
|
{ 0x00000FFF,0xFFFFFFFF,0xFF000000, },
|
|
{ 0x0000FFFF,0xFFFFFFFF,0xF0000000, },
|
|
{ 0x000FFFFF,0xFFFFFFFF,0x00000000, },
|
|
{ 0x00FFFFFF,0xFFFFFFF0,0x00000000, },
|
|
{ 0x0FFFFFFF,0xFFFFFF00,0x00000000, },
|
|
},
|
|
{
|
|
{ 0x00000000,0xFFFFFFFF,0xFFFF0000, },
|
|
{ 0x0000000F,0xFFFFFFFF,0xFFF00000, },
|
|
{ 0x000000FF,0xFFFFFFFF,0xFF000000, },
|
|
{ 0x00000FFF,0xFFFFFFFF,0xF0000000, },
|
|
{ 0x0000FFFF,0xFFFFFFFF,0x00000000, },
|
|
{ 0x000FFFFF,0xFFFFFFF0,0x00000000, },
|
|
{ 0x00FFFFFF,0xFFFFFF00,0x00000000, },
|
|
{ 0x0FFFFFFF,0xFFFFF000,0x00000000, },
|
|
},
|
|
{
|
|
{ 0x00000000,0xFFFFFFFF,0xFFF00000, },
|
|
{ 0x0000000F,0xFFFFFFFF,0xFF000000, },
|
|
{ 0x000000FF,0xFFFFFFFF,0xF0000000, },
|
|
{ 0x00000FFF,0xFFFFFFFF,0x00000000, },
|
|
{ 0x0000FFFF,0xFFFFFFF0,0x00000000, },
|
|
{ 0x000FFFFF,0xFFFFFF00,0x00000000, },
|
|
{ 0x00FFFFFF,0xFFFFF000,0x00000000, },
|
|
{ 0x0FFFFFFF,0xFFFF0000,0x00000000, },
|
|
},
|
|
{
|
|
{ 0x00000000,0xFFFFFFFF,0xFF000000, },
|
|
{ 0x0000000F,0xFFFFFFFF,0xF0000000, },
|
|
{ 0x000000FF,0xFFFFFFFF,0x00000000, },
|
|
{ 0x00000FFF,0xFFFFFFF0,0x00000000, },
|
|
{ 0x0000FFFF,0xFFFFFF00,0x00000000, },
|
|
{ 0x000FFFFF,0xFFFFF000,0x00000000, },
|
|
{ 0x00FFFFFF,0xFFFF0000,0x00000000, },
|
|
{ 0x0FFFFFFF,0xFFF00000,0x00000000, },
|
|
},
|
|
{
|
|
{ 0x00000000,0xFFFFFFFF,0xF0000000, },
|
|
{ 0x0000000F,0xFFFFFFFF,0x00000000, },
|
|
{ 0x000000FF,0xFFFFFFF0,0x00000000, },
|
|
{ 0x00000FFF,0xFFFFFF00,0x00000000, },
|
|
{ 0x0000FFFF,0xFFFFF000,0x00000000, },
|
|
{ 0x000FFFFF,0xFFFF0000,0x00000000, },
|
|
{ 0x00FFFFFF,0xFFF00000,0x00000000, },
|
|
{ 0x0FFFFFFF,0xFF000000,0x00000000, },
|
|
},
|
|
{
|
|
{ 0x00000000,0xFFFFFFFF,0x00000000, },
|
|
{ 0x0000000F,0xFFFFFFF0,0x00000000, },
|
|
{ 0x000000FF,0xFFFFFF00,0x00000000, },
|
|
{ 0x00000FFF,0xFFFFF000,0x00000000, },
|
|
{ 0x0000FFFF,0xFFFF0000,0x00000000, },
|
|
{ 0x000FFFFF,0xFFF00000,0x00000000, },
|
|
{ 0x00FFFFFF,0xFF000000,0x00000000, },
|
|
{ 0x0FFFFFFF,0xF0000000,0x00000000, },
|
|
},
|
|
};
|
|
|
|
static const struct ShiftAmount sGlyphShiftAmounts[8] =
|
|
{
|
|
{ 0, 32 },
|
|
{ 4, 28 },
|
|
{ 8, 24 },
|
|
{ 12, 20 },
|
|
{ 16, 16 },
|
|
{ 20, 12 },
|
|
{ 24, 8 },
|
|
{ 28, 4 },
|
|
};
|
|
|
|
typedef void (*PrintGlyphFunc)(struct Window *, u32);
|
|
|
|
static const PrintGlyphFunc sPrintGlyphFuncs[] =
|
|
{
|
|
PrintGlyph_TextMode0,
|
|
PrintGlyph_TextMode1,
|
|
PrintGlyph_TextMode2,
|
|
};
|
|
|
|
typedef void (*WriteGlyphTilemapFunc)(struct Window *, u32);
|
|
|
|
static const WriteGlyphTilemapFunc sWriteGlyphTilemapFuncs[] =
|
|
{
|
|
WriteGlyphTilemap_Font0_Font3,
|
|
WriteGlyphTilemap_Font1_Font4,
|
|
WriteGlyphTilemap_Font2_Font5,
|
|
WriteGlyphTilemap_Font0_Font3,
|
|
WriteGlyphTilemap_Font1_Font4,
|
|
WriteGlyphTilemap_Font2_Font5,
|
|
WriteGlyphTilemap_Font6,
|
|
};
|
|
|
|
static const struct Window sDefaultWindow = { .language = GAME_LANGUAGE };
|
|
|
|
typedef u8 (*ExtCtrlCodeFunc)(struct Window *);
|
|
|
|
static const ExtCtrlCodeFunc sExtCtrlCodeFuncs[] =
|
|
{
|
|
ExtCtrlCode_Nop,
|
|
ExtCtrlCode_ForegroundColor,
|
|
ExtCtrlCode_BackgroundColor,
|
|
ExtCtrlCode_ShadowColor,
|
|
ExtCtrlCode_AllColors,
|
|
ExtCtrlCode_Palette,
|
|
ExtCtrlCode_Font,
|
|
ExtCtrlCode_DefaultFont,
|
|
ExtCtrlCode_Pause,
|
|
ExtCtrlCode_WaitButton,
|
|
ExtCtrlCode_WaitSound,
|
|
ExtCtrlCode_PlayBGM,
|
|
ExtCtrlCode_Escape,
|
|
ExtCtrlCode_Nop2,
|
|
ExtCtrlCode_SetCursorY,
|
|
ExtCtrlCode_ClearWindowTextLines,
|
|
ExtCtrlCode_PlaySE,
|
|
ExtCtrlCode_Skip,
|
|
ExtCtrlCode_SetCursorX,
|
|
ExtCtrlCode_SkipTo,
|
|
ExtCtrlCode_Spacing,
|
|
ExtCtrlCode_Japanese,
|
|
ExtCtrlCode_Latin,
|
|
};
|
|
|
|
extern const u32 gFont3LatinGlyphs[];
|
|
extern const u32 gFont4LatinGlyphs[];
|
|
extern const u32 gFont3JapaneseGlyphs[];
|
|
extern const u32 gFont4JapaneseGlyphs[];
|
|
|
|
// Getting rid of the u8 recasting will make the ROM no longer match due to
|
|
// a const being required to pass the elements directly to the rodata structs.
|
|
static const struct Font sFonts[] =
|
|
{
|
|
// Japanese fonts
|
|
{ 0, (u8 *)sFont0JapaneseGlyphs, 16, 8 },
|
|
{ 1, (u8 *)sFont1JapaneseGlyphs, 8, 0 },
|
|
{ 2, (u8 *)sFont1JapaneseGlyphs, 8, 0 },
|
|
{ 4, (u8 *)gFont3JapaneseGlyphs, 64, 512 },
|
|
{ 1, (u8 *)gFont4JapaneseGlyphs, 32, 0 },
|
|
{ 2, (u8 *)gFont4JapaneseGlyphs, 32, 0 },
|
|
{ 3, (u8 *)sBrailleGlyphs, 8, 0 },
|
|
// Latin
|
|
{ 0, (u8 *)sFont0LatinGlyphs, 16, 8 },
|
|
{ 1, (u8 *)sFont1LatinGlyphs, 8, 0 },
|
|
{ 2, (u8 *)sFont1LatinGlyphs, 8, 0 },
|
|
{ 0, (u8 *)gFont3LatinGlyphs, 64, 32 },
|
|
{ 1, (u8 *)gFont4LatinGlyphs, 32, 0 },
|
|
{ 2, (u8 *)gFont4LatinGlyphs, 32, 0 },
|
|
{ 3, (u8 *)sBrailleGlyphs, 8, 0 },
|
|
};
|
|
|
|
static const u8 sTextSpeedDelays[] = { 6, 3, 1 }; // slow, mid, fast
|
|
|
|
static const u8 sExtCtrlCodeLengths[] =
|
|
{
|
|
1,
|
|
2,
|
|
2,
|
|
2,
|
|
4,
|
|
2,
|
|
2,
|
|
1,
|
|
2,
|
|
1,
|
|
1,
|
|
3,
|
|
2,
|
|
2,
|
|
2,
|
|
1,
|
|
3,
|
|
2,
|
|
2,
|
|
2,
|
|
2,
|
|
1,
|
|
1,
|
|
};
|
|
|
|
typedef void (*ShiftGlyphTileUnshadowedFunc)(struct GlyphBuffer *, u8 *, u32 *, u8);
|
|
|
|
static const ShiftGlyphTileUnshadowedFunc sShiftGlyphTileUnshadowedFuncs[] =
|
|
{
|
|
ShiftGlyphTile_UnshadowedFont_Width0,
|
|
ShiftGlyphTile_UnshadowedFont_Width1,
|
|
ShiftGlyphTile_UnshadowedFont_Width2,
|
|
ShiftGlyphTile_UnshadowedFont_Width3,
|
|
ShiftGlyphTile_UnshadowedFont_Width4,
|
|
ShiftGlyphTile_UnshadowedFont_Width5,
|
|
ShiftGlyphTile_UnshadowedFont_Width6,
|
|
ShiftGlyphTile_UnshadowedFont_Width7,
|
|
ShiftGlyphTile_UnshadowedFont_Width8,
|
|
};
|
|
|
|
typedef void (*ShiftGlyphTileShadowedFunc)(struct GlyphBuffer *, u32 *, u32 *, u8);
|
|
|
|
static const ShiftGlyphTileShadowedFunc sShiftGlyphTileShadowedFuncs[] =
|
|
{
|
|
ShiftGlyphTile_ShadowedFont_Width0,
|
|
ShiftGlyphTile_ShadowedFont_Width1,
|
|
ShiftGlyphTile_ShadowedFont_Width2,
|
|
ShiftGlyphTile_ShadowedFont_Width3,
|
|
ShiftGlyphTile_ShadowedFont_Width4,
|
|
ShiftGlyphTile_ShadowedFont_Width5,
|
|
ShiftGlyphTile_ShadowedFont_Width6,
|
|
ShiftGlyphTile_ShadowedFont_Width7,
|
|
ShiftGlyphTile_ShadowedFont_Width8,
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6C3C =
|
|
{
|
|
0, // BG number
|
|
2, // BG character base block
|
|
31, // BG screen base block
|
|
0, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
0, // font
|
|
0, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(31), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6C58 =
|
|
{
|
|
0, // BG number
|
|
0, // BG character base block
|
|
24, // BG screen base block
|
|
0, // BG priority
|
|
0, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
0, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
26, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(24), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6C74 =
|
|
{
|
|
0, // BG number
|
|
0, // BG character base block
|
|
0, // BG screen base block
|
|
0, // BG priority
|
|
0, // palette number
|
|
1, // foreground color
|
|
0, // background color
|
|
3, // shadow color
|
|
4, // font
|
|
0, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
OBJ_VRAM0, // tile data
|
|
NULL, // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6C90 =
|
|
{
|
|
0, // BG number
|
|
1, // BG character base block
|
|
30, // BG screen base block
|
|
2, // BG priority
|
|
31, // palette number
|
|
15, // foreground color
|
|
0, // background color
|
|
1, // shadow color
|
|
4, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(1), // tile data
|
|
BG_SCREEN_ADDR(30), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6CAC =
|
|
{
|
|
0, // BG number
|
|
0, // BG character base block
|
|
0, // BG screen base block
|
|
0, // BG priority
|
|
0, // palette number
|
|
15, // foreground color
|
|
0, // background color
|
|
1, // shadow color
|
|
4, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
8, // width
|
|
60, // height
|
|
gTileBuffer, // tile data
|
|
NULL, // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6CC8 =
|
|
{
|
|
2, // BG number
|
|
2, // BG character base block
|
|
15, // BG screen base block
|
|
0, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(15), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gMenuTextWindowTemplate =
|
|
{
|
|
0, // BG number
|
|
2, // BG character base block
|
|
31, // BG screen base block
|
|
0, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(31), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6D00 =
|
|
{
|
|
0, // BG number
|
|
0, // BG character base block
|
|
31, // BG screen base block
|
|
0, // BG priority
|
|
15, // palette number
|
|
2, // foreground color
|
|
15, // background color
|
|
3, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(31), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6D1C =
|
|
{
|
|
1, // BG number
|
|
0, // BG character base block
|
|
31, // BG screen base block
|
|
1, // BG priority
|
|
15, // palette number
|
|
2, // foreground color
|
|
15, // background color
|
|
3, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(31), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6D38 =
|
|
{
|
|
0, // BG number
|
|
0, // BG character base block
|
|
0, // BG screen base block
|
|
0, // BG priority
|
|
0, // palette number
|
|
15, // foreground color
|
|
0, // background color
|
|
14, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
8, // width
|
|
64, // height
|
|
gTileBuffer, // tile data
|
|
NULL, // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6D54 =
|
|
{
|
|
3, // BG number
|
|
3, // BG character base block
|
|
15, // BG screen base block
|
|
3, // BG priority
|
|
2, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(3), // tile data
|
|
BG_SCREEN_ADDR(15), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6D70 =
|
|
{
|
|
3, // BG number
|
|
3, // BG character base block
|
|
15, // BG screen base block
|
|
3, // BG priority
|
|
3, // palette number
|
|
1, // foreground color
|
|
3, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(3), // tile data
|
|
BG_SCREEN_ADDR(15), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6D8C =
|
|
{
|
|
1, // BG number
|
|
0, // BG character base block
|
|
14, // BG screen base block
|
|
1, // BG priority
|
|
0, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(14), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6DA8 =
|
|
{
|
|
0, // BG number
|
|
0, // BG character base block
|
|
12, // BG screen base block
|
|
0, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(11), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_TrainerCard_Back_Values =
|
|
{
|
|
0, // BG number
|
|
2, // BG character base block
|
|
30, // BG screen base block
|
|
0, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
0, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(30), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_TrainerCard_Back_Labels =
|
|
{
|
|
0, // BG number
|
|
2, // BG character base block
|
|
30, // BG screen base block
|
|
0, // BG priority
|
|
14, // palette number
|
|
1, // foreground color
|
|
0, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(30), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6DFC =
|
|
{
|
|
0, // BG number
|
|
2, // BG character base block
|
|
31, // BG screen base block
|
|
0, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
0, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(31), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6E18 =
|
|
{
|
|
0, // BG number
|
|
2, // BG character base block
|
|
31, // BG screen base block
|
|
1, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
0, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(31), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6E34 =
|
|
{
|
|
1, // BG number
|
|
0, // BG character base block
|
|
31, // BG screen base block
|
|
1, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
0, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(31), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6E50 =
|
|
{
|
|
0, // BG number
|
|
2, // BG character base block
|
|
28, // BG screen base block
|
|
0, // BG priority
|
|
13, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(28), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6E6C =
|
|
{
|
|
0, // BG number
|
|
2, // BG character base block
|
|
30, // BG screen base block
|
|
0, // BG priority
|
|
13, // palette number
|
|
15, // foreground color
|
|
0, // background color
|
|
10, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(30), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6E88 =
|
|
{
|
|
0, // BG number
|
|
0, // BG character base block
|
|
31, // BG screen base block
|
|
0, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(31), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6EA4 =
|
|
{
|
|
1, // BG number
|
|
0, // BG character base block
|
|
28, // BG screen base block
|
|
1, // BG priority
|
|
1, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
8, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(28), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6EC0 =
|
|
{
|
|
2, // BG number
|
|
2, // BG character base block
|
|
29, // BG screen base block
|
|
2, // BG priority
|
|
1, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
8, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(29), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6EDC =
|
|
{
|
|
1, // BG number
|
|
0, // BG character base block
|
|
28, // BG screen base block
|
|
1, // BG priority
|
|
2, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
8, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(28), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6EF8 =
|
|
{
|
|
2, // BG number
|
|
2, // BG character base block
|
|
29, // BG screen base block
|
|
2, // BG priority
|
|
2, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
8, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(29), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6F14 =
|
|
{
|
|
1, // BG number
|
|
0, // BG character base block
|
|
28, // BG screen base block
|
|
1, // BG priority
|
|
3, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
8, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(28), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6F30 =
|
|
{
|
|
2, // BG number
|
|
2, // BG character base block
|
|
29, // BG screen base block
|
|
2, // BG priority
|
|
3, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
8, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(29), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6F4C =
|
|
{
|
|
3, // BG number
|
|
0, // BG character base block
|
|
30, // BG screen base block
|
|
3, // BG priority
|
|
0, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(30), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6F68 =
|
|
{
|
|
0, // BG number
|
|
2, // BG character base block
|
|
13, // BG screen base block
|
|
0, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(13), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6F84 =
|
|
{
|
|
0, // BG number
|
|
2, // BG character base block
|
|
31, // BG screen base block
|
|
0, // BG priority
|
|
15, // palette number
|
|
15, // foreground color
|
|
0, // background color
|
|
1, // shadow color
|
|
3, // font
|
|
0, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(31), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6FA0 =
|
|
{
|
|
1, // BG number
|
|
0, // BG character base block
|
|
24, // BG screen base block
|
|
3, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
0, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
0, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(24), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6FBC =
|
|
{
|
|
0, // BG number
|
|
0, // BG character base block
|
|
30, // BG screen base block
|
|
0, // BG priority
|
|
15, // palette number
|
|
15, // foreground color
|
|
0, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
0, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(30), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6FD8 =
|
|
{
|
|
0, // BG number
|
|
0, // BG character base block
|
|
24, // BG screen base block
|
|
0, // BG priority
|
|
15, // palette number
|
|
15, // foreground color
|
|
0, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
0, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(24), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E6FF4 =
|
|
{
|
|
0, // BG number
|
|
0, // BG character base block
|
|
24, // BG screen base block
|
|
0, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
0, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
0, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(24), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E7010 =
|
|
{
|
|
0, // BG number
|
|
0, // BG character base block
|
|
30, // BG screen base block
|
|
0, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
0, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
0, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(30), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E702C =
|
|
{
|
|
3, // BG number
|
|
2, // BG character base block
|
|
15, // BG screen base block
|
|
0, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(15), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E7048 =
|
|
{
|
|
2, // BG number
|
|
2, // BG character base block
|
|
14, // BG screen base block
|
|
2, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
0, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
16, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
16, // width
|
|
32, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(14), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E7064 =
|
|
{
|
|
2, // BG number
|
|
2, // BG character base block
|
|
14, // BG screen base block
|
|
2, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
0, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(14), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E7080 =
|
|
{
|
|
3, // BG number
|
|
0, // BG character base block
|
|
30, // BG screen base block
|
|
3, // BG priority
|
|
11, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
5, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(30), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E709C =
|
|
{
|
|
0, // BG number
|
|
0, // BG character base block
|
|
31, // BG screen base block
|
|
1, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(31), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E70B8 =
|
|
{
|
|
2, // BG number
|
|
0, // BG character base block
|
|
30, // BG screen base block
|
|
2, // BG priority
|
|
11, // palette number
|
|
1, // foreground color
|
|
0, // background color
|
|
5, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(30), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E70D4 =
|
|
{
|
|
3, // BG number
|
|
0, // BG character base block
|
|
30, // BG screen base block
|
|
3, // BG priority
|
|
11, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
5, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(30), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E70F0 =
|
|
{
|
|
0, // BG number
|
|
0, // BG character base block
|
|
0, // BG screen base block
|
|
0, // BG priority
|
|
0, // palette number
|
|
15, // foreground color
|
|
1, // background color
|
|
14, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
32, // width
|
|
32, // height
|
|
gTileBuffer, // tile data
|
|
NULL, // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E710C =
|
|
{
|
|
0, // BG number
|
|
0, // BG character base block
|
|
31, // BG screen base block
|
|
1, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
0, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(31), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E7128 =
|
|
{
|
|
0, // BG number
|
|
2, // BG character base block
|
|
31, // BG screen base block
|
|
0, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(31), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E7144 =
|
|
{
|
|
0, // BG number
|
|
2, // BG character base block
|
|
31, // BG screen base block
|
|
0, // BG priority
|
|
13, // palette number
|
|
1, // foreground color
|
|
0, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(31), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E7160 =
|
|
{
|
|
1, // BG number
|
|
1, // BG character base block
|
|
10, // BG screen base block
|
|
1, // BG priority
|
|
14, // palette number
|
|
1, // foreground color
|
|
0, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
0, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(1), // tile data
|
|
BG_SCREEN_ADDR(10), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E717C =
|
|
{
|
|
0, // BG number
|
|
3, // BG character base block
|
|
31, // BG screen base block
|
|
0, // BG priority
|
|
15, // palette number
|
|
15, // foreground color
|
|
0, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
0, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(3), // tile data
|
|
BG_SCREEN_ADDR(31), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E7198 =
|
|
{
|
|
0, // BG number
|
|
2, // BG character base block
|
|
15, // BG screen base block
|
|
0, // BG priority
|
|
15, // palette number
|
|
15, // foreground color
|
|
0, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(15), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E71B4 =
|
|
{
|
|
0, // BG number
|
|
2, // BG character base block
|
|
15, // BG screen base block
|
|
0, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(15), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E71D0 =
|
|
{
|
|
1, // BG number
|
|
1, // BG character base block
|
|
28, // BG screen base block
|
|
0, // BG priority
|
|
5, // palette number
|
|
13, // foreground color
|
|
14, // background color
|
|
15, // shadow color
|
|
3, // font
|
|
0, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(1), // tile data
|
|
BG_SCREEN_ADDR(28), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E71EC =
|
|
{
|
|
2, // BG number
|
|
1, // BG character base block
|
|
30, // BG screen base block
|
|
0, // BG priority
|
|
5, // palette number
|
|
13, // foreground color
|
|
14, // background color
|
|
15, // shadow color
|
|
3, // font
|
|
0, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(1), // tile data
|
|
BG_SCREEN_ADDR(30), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E7208 =
|
|
{
|
|
0, // BG number
|
|
2, // BG character base block
|
|
28, // BG screen base block
|
|
0, // BG priority
|
|
8, // palette number
|
|
1, // foreground color
|
|
0, // background color
|
|
2, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(28), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E7224 =
|
|
{
|
|
0, // BG number
|
|
0, // BG character base block
|
|
31, // BG screen base block
|
|
0, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(0), // tile data
|
|
BG_SCREEN_ADDR(31), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gMoveTutorMenuFramesWindowTemplate =
|
|
{
|
|
1, // BG number
|
|
2, // BG character base block
|
|
30, // BG screen base block
|
|
0, // BG priority
|
|
15, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
BG_CHAR_ADDR(2), // tile data
|
|
BG_SCREEN_ADDR(30), // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E725C =
|
|
{
|
|
0, // BG number
|
|
0, // BG character base block
|
|
0, // BG screen base block
|
|
0, // BG priority
|
|
0, // palette number
|
|
15, // foreground color
|
|
0, // background color
|
|
14, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
30, // width
|
|
20, // height
|
|
OBJ_VRAM0, // tile data
|
|
NULL, // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E7278 =
|
|
{
|
|
0, // BG number
|
|
0, // BG character base block
|
|
0, // BG screen base block
|
|
0, // BG priority
|
|
0, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
3, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
16, // width
|
|
32, // height
|
|
gTileBuffer, // tile data
|
|
NULL, // tilemap
|
|
};
|
|
|
|
const struct WindowTemplate gWindowTemplate_81E7294 =
|
|
{
|
|
0, // BG number
|
|
0, // BG character base block
|
|
0, // BG screen base block
|
|
0, // BG priority
|
|
0, // palette number
|
|
1, // foreground color
|
|
15, // background color
|
|
8, // shadow color
|
|
4, // font
|
|
2, // text mode
|
|
0, // spacing
|
|
0, // tilemap left coordinate
|
|
0, // tilemap top coordinate
|
|
16, // width
|
|
32, // height
|
|
gTileBuffer, // tile data
|
|
NULL, // tilemap
|
|
};
|
|
|
|
static void UpdateBGRegs(const struct WindowTemplate *winTemplate)
|
|
{
|
|
u8 bgNum = winTemplate->bgNum;
|
|
*gBGHOffsetRegs[bgNum] = 0;
|
|
*gBGVOffsetRegs[bgNum] = 0;
|
|
*gBGControlRegs[bgNum] = winTemplate->priority | (winTemplate->screenBaseBlock << 8) | (winTemplate->charBaseBlock << 2);
|
|
}
|
|
|
|
static void ClearBGMem(const struct WindowTemplate *winTemplate)
|
|
{
|
|
CpuFastFill(0, winTemplate->tileData, 32);
|
|
|
|
if (winTemplate->tilemap)
|
|
CpuFastFill(0, winTemplate->tilemap, 0x800);
|
|
}
|
|
|
|
void LoadFontDefaultPalette(const struct WindowTemplate *winTemplate)
|
|
{
|
|
LoadPalette(gFontDefaultPalette, 16 * winTemplate->paletteNum, 32);
|
|
}
|
|
|
|
void Text_LoadWindowTemplate(const struct WindowTemplate *winTemplate)
|
|
{
|
|
UpdateBGRegs(winTemplate);
|
|
ClearBGMem(winTemplate);
|
|
LoadFontDefaultPalette(winTemplate);
|
|
}
|
|
|
|
u16 InitWindowTileData(struct Window *win, u16 startOffset)
|
|
{
|
|
u16 retVal;
|
|
|
|
win->tileDataStartOffset = startOffset;
|
|
retVal = 0;
|
|
|
|
switch (win->template->textMode)
|
|
{
|
|
case TEXT_MODE_UNKNOWN2:
|
|
retVal = InitVariableWidthFontTileData(win, startOffset);
|
|
break;
|
|
case TEXT_MODE_MONOSPACE:
|
|
switch (win->template->fontNum)
|
|
{
|
|
case 0:
|
|
case 3:
|
|
retVal = LoadFixedWidthFont(win, startOffset);
|
|
break;
|
|
case 1:
|
|
case 2:
|
|
retVal = LoadFixedWidthFont_Font1Latin(win, startOffset);
|
|
break;
|
|
case 4:
|
|
case 5:
|
|
retVal = LoadFixedWidthFont_Font4Latin(win, startOffset);
|
|
break;
|
|
case 6:
|
|
retVal = LoadFixedWidthFont_Braille(win, startOffset);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
static u16 InitVariableWidthFontTileData(struct Window *win, u16 startOffset)
|
|
{
|
|
u8 *buffer;
|
|
|
|
win->tileDataStartOffset = startOffset;
|
|
win->tileDataOffset = 2;
|
|
buffer = win->tileData + 32 * win->tileDataStartOffset;
|
|
CpuFastFill(0, buffer, 32);
|
|
ApplyColors_UnshadowedFont(sBlankTile, (u32 *)(buffer + 32), win->template->foregroundColor, win->template->backgroundColor);
|
|
return win->tileDataStartOffset + win->tileDataOffset + win->width * win->height;
|
|
}
|
|
|
|
static u16 LoadFixedWidthFont(struct Window *win, u16 startOffset)
|
|
{
|
|
s32 glyph;
|
|
u8 *buffer = win->tileData + 32 * startOffset;
|
|
for (glyph = 0; glyph < 256; glyph++)
|
|
{
|
|
LoadFixedWidthGlyph(win, glyph, buffer);
|
|
buffer += 64;
|
|
}
|
|
return 2 * glyph;
|
|
}
|
|
|
|
static u16 LoadFixedWidthFont_Font1Latin(struct Window *win, u16 startOffset)
|
|
{
|
|
s32 i;
|
|
u8 *buffer = win->tileData + 32 * startOffset;
|
|
for (i = 0; i < 256; i++)
|
|
{
|
|
ApplyColors_UnshadowedFont(&sFont1LatinGlyphs[8 * i], (u32 *)buffer, win->foregroundColor, win->backgroundColor);
|
|
buffer += 32;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
static u16 LoadFixedWidthFont_Font4Latin(struct Window *win, u16 startOffset)
|
|
{
|
|
s32 i;
|
|
u8 *buffer = win->tileData + 32 * startOffset;
|
|
for (i = 0; i < 256; i++)
|
|
{
|
|
ApplyColors_ShadowedFont(&gFont4LatinGlyphs[8 * i], buffer, win->foregroundColor, win->shadowColor, win->backgroundColor);
|
|
buffer += 32;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
static u16 LoadFixedWidthFont_Braille(struct Window *win, u16 startOffset)
|
|
{
|
|
s32 i;
|
|
u8 *buffer = win->tileData + 32 * startOffset;
|
|
for (i = 0; i < 256; i++)
|
|
{
|
|
ApplyColors_UnshadowedFont(&sBrailleGlyphs[8 * i], (u32 *)buffer, win->foregroundColor, win->backgroundColor);
|
|
buffer += 32;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
u32 MultistepInitWindowTileData(struct Window *win, u16 startOffset)
|
|
{
|
|
u32 retVal;
|
|
sMultistepLoadFont_Window = win;
|
|
sMultistepLoadFont_Index = 0;
|
|
sMultistepLoadFont_StartOffset = startOffset;
|
|
win->tileDataStartOffset = startOffset;
|
|
retVal = 0;
|
|
|
|
switch (win->template->textMode)
|
|
{
|
|
case TEXT_MODE_UNKNOWN2:
|
|
retVal = InitVariableWidthFontTileData(win, startOffset);
|
|
break;
|
|
case TEXT_MODE_MONOSPACE:
|
|
retVal = 256;
|
|
if (win->template->fontNum == 0
|
|
|| win->template->fontNum == 3)
|
|
retVal *= 2;
|
|
break;
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
bool32 MultistepLoadFont(void)
|
|
{
|
|
bool32 retVal = TRUE;
|
|
|
|
if (sMultistepLoadFont_Window->template->textMode == TEXT_MODE_MONOSPACE)
|
|
{
|
|
s32 i;
|
|
|
|
for (i = sMultistepLoadFont_Index; i < sMultistepLoadFont_Index + 16; i++)
|
|
MultistepLoadFont_LoadGlyph(sMultistepLoadFont_Window, sMultistepLoadFont_StartOffset, i);
|
|
|
|
sMultistepLoadFont_Index += 16;
|
|
|
|
if (sMultistepLoadFont_Index < 256)
|
|
retVal = FALSE;
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
static void MultistepLoadFont_LoadGlyph(struct Window *win, u16 startOffset, u8 glyph)
|
|
{
|
|
u8 *buffer;
|
|
|
|
switch (win->template->fontNum)
|
|
{
|
|
case 0:
|
|
case 3:
|
|
buffer = win->tileData + 32 * startOffset + 64 * glyph;
|
|
LoadFixedWidthGlyph(win, glyph, buffer);
|
|
break;
|
|
case 1:
|
|
case 2:
|
|
buffer = win->tileData + 32 * (glyph + startOffset);
|
|
ApplyColors_UnshadowedFont(
|
|
&sFont1LatinGlyphs[8 * glyph],
|
|
(u32 *)buffer,
|
|
win->foregroundColor,
|
|
win->backgroundColor);
|
|
break;
|
|
case 4:
|
|
case 5:
|
|
buffer = win->tileData + 32 * (glyph + startOffset);
|
|
ApplyColors_ShadowedFont(
|
|
&gFont4LatinGlyphs[8 * glyph],
|
|
buffer,
|
|
win->foregroundColor,
|
|
win->shadowColor,
|
|
win->backgroundColor);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void EmptyFunc(void)
|
|
{
|
|
}
|
|
|
|
void Text_InitWindowWithTemplate(struct Window *win, const struct WindowTemplate *winTemplate)
|
|
{
|
|
*win = sDefaultWindow;
|
|
win->template = (struct WindowTemplate *)winTemplate;
|
|
win->textMode = winTemplate->textMode;
|
|
win->spacing = winTemplate->spacing;
|
|
win->fontNum = winTemplate->fontNum;
|
|
win->paletteNum = winTemplate->paletteNum;
|
|
win->tilemapLeft = winTemplate->tilemapLeft;
|
|
win->tilemapTop = winTemplate->tilemapTop;
|
|
win->width = winTemplate->width;
|
|
win->height = winTemplate->height;
|
|
win->tileData = winTemplate->tileData;
|
|
win->tilemap = winTemplate->tilemap;
|
|
SetWindowDefaultColors(win);
|
|
SetWindowBackgroundColor(win, winTemplate->backgroundColor);
|
|
SetWindowShadowColor(win, winTemplate->shadowColor);
|
|
SetWindowForegroundColor(win, winTemplate->foregroundColor);
|
|
}
|
|
|
|
void Text_InitWindow(struct Window *win, const u8 *text, u16 tileDataStartOffset, u8 left, u8 top)
|
|
{
|
|
const struct WindowTemplate *winTemplate = win->template;
|
|
win->textMode = winTemplate->textMode;
|
|
win->fontNum = winTemplate->fontNum;
|
|
win->language = GAME_LANGUAGE;
|
|
win->paletteNum = winTemplate->paletteNum;
|
|
win->win_field_B = 0;
|
|
win->win_field_C = 0;
|
|
win->delayCounter = 0;
|
|
win->spacing = winTemplate->spacing;
|
|
win->win_field_F = 0;
|
|
win->tilemapLeft = winTemplate->tilemapLeft;
|
|
win->tilemapTop = winTemplate->tilemapTop;
|
|
win->width = winTemplate->width;
|
|
win->height = winTemplate->height;
|
|
win->text = text;
|
|
win->textIndex = 0;
|
|
win->tileDataStartOffset = tileDataStartOffset;
|
|
win->tileDataOffset = 0;
|
|
win->left = 8 * left;
|
|
win->cursorX = 0;
|
|
win->top = 8 * top;
|
|
win->cursorY = 0;
|
|
win->state = WIN_STATE_BEGIN;
|
|
win->downArrowCounter = 0;
|
|
win->tileData = winTemplate->tileData;
|
|
win->tilemap = winTemplate->tilemap;
|
|
SetWindowDefaultColors(win);
|
|
SetWindowBackgroundColor(win, winTemplate->backgroundColor);
|
|
SetWindowShadowColor(win, winTemplate->shadowColor);
|
|
SetWindowForegroundColor(win, winTemplate->foregroundColor);
|
|
}
|
|
|
|
void Text_InitWindow8002E4C(struct Window *win, const u8 *text, u16 tileDataStartOffset, u8 left, u16 top, u32 a6)
|
|
{
|
|
u8 val;
|
|
|
|
Text_InitWindow(win, text, tileDataStartOffset, 0, 0);
|
|
win->left = left;
|
|
win->top = top;
|
|
val = 0;
|
|
if (a6)
|
|
val = 255;
|
|
win->win_field_F = val;
|
|
if (win->win_field_F)
|
|
ClipLeft(win);
|
|
}
|
|
|
|
void Text_SetWindowText(struct Window *win, const u8 *text)
|
|
{
|
|
win->state = WIN_STATE_NORMAL;
|
|
win->text = text;
|
|
win->textIndex = 0;
|
|
win->downArrowCounter = 0;
|
|
win->win_field_B = -1;
|
|
win->win_field_C = 0;
|
|
win->delayCounter = 0;
|
|
}
|
|
|
|
void Text_InitWindow8002EB0(struct Window *win, const u8 *text, u16 tileDataStartOffset, u8 left, u8 top)
|
|
{
|
|
gMain.watchedKeysMask = A_BUTTON | B_BUTTON;
|
|
gMain.watchedKeysPressed = 0;
|
|
sWaitType = WAIT_TYPE_NORMAL;
|
|
sLineLength = 26;
|
|
Text_InitWindow(win, text, tileDataStartOffset, left, top);
|
|
win->win_field_B = -1;
|
|
if (win->textMode == TEXT_MODE_UNKNOWN0)
|
|
{
|
|
u16 val = GetCursorTileNum(win, 0, 0);
|
|
u8 *buffer = win->tileData + 32 * val;
|
|
ApplyColors_UnshadowedFont(sBlankTile, (u32 *)buffer, win->backgroundColor, win->backgroundColor);
|
|
ApplyColors_UnshadowedFont(&sFont1LatinGlyphs[8 * 0x6E], (u32 *)(buffer + 32), win->foregroundColor, win->backgroundColor);
|
|
win->tileDataOffset = 2;
|
|
}
|
|
}
|
|
|
|
u8 Text_PrintWindow8002F44(struct Window *win)
|
|
{
|
|
while (win->state != WIN_STATE_END)
|
|
{
|
|
if (win->state == WIN_STATE_NEWLINE)
|
|
{
|
|
AddToCursorY(win, 16);
|
|
win->cursorX = 0;
|
|
if (win->win_field_F)
|
|
ClipLeft(win);
|
|
win->state = WIN_STATE_NORMAL;
|
|
}
|
|
else if (win->state == WIN_STATE_PLACEHOLDER)
|
|
{
|
|
sub_8002FA0(win, GetExpandedPlaceholder(win->text[win->textIndex++]));
|
|
}
|
|
|
|
PrintNextChar(win);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static u8 sub_8002FA0(struct Window *win, const u8 *text)
|
|
{
|
|
u8 retVal;
|
|
u8 savedLanguage = win->language;
|
|
const u8 *savedText = win->text;
|
|
|
|
u16 savedTextIndex = win->textIndex;
|
|
win->text = text;
|
|
win->textIndex = 0;
|
|
win->state = WIN_STATE_NORMAL;
|
|
retVal = Text_PrintWindow8002F44(win);
|
|
win->text = savedText;
|
|
win->textIndex = savedTextIndex;
|
|
win->state = WIN_STATE_NORMAL;
|
|
win->language = savedLanguage;
|
|
return retVal;
|
|
}
|
|
|
|
static u8 PrintNextChar(struct Window *win)
|
|
{
|
|
u32 c = win->text[win->textIndex++];
|
|
|
|
// Handle special control characters
|
|
switch (c)
|
|
{
|
|
case EOS:
|
|
ClipRight(win);
|
|
win->state = WIN_STATE_END;
|
|
return 0;
|
|
case PLACEHOLDER_BEGIN:
|
|
win->state = WIN_STATE_PLACEHOLDER;
|
|
return 2;
|
|
case CHAR_NEWLINE:
|
|
ClipRight(win);
|
|
win->state = WIN_STATE_NEWLINE;
|
|
return 2;
|
|
case CHAR_PROMPT_CLEAR:
|
|
DrawInitialDownArrow(win);
|
|
win->state = WIN_STATE_WAIT_CLEAR;
|
|
return 2;
|
|
case CHAR_PROMPT_SCROLL:
|
|
DrawInitialDownArrow(win);
|
|
win->state = WIN_STATE_WAIT_SCROLL;
|
|
return 2;
|
|
case EXT_CTRL_CODE_BEGIN:
|
|
return HandleExtCtrlCode(win);
|
|
}
|
|
|
|
// TODO: see if this is in rev1+
|
|
#if (DEBUG && ENGLISH && REVISION == 0)
|
|
// Code related to the Murakawa task.
|
|
if ((gUnknown_Debug_03004BD0) && (!gUnknown_Debug_Murakawa2))
|
|
c = win->textMode + CHAR_0;
|
|
#endif
|
|
sPrintGlyphFuncs[win->textMode](win, c);
|
|
return 1;
|
|
}
|
|
|
|
// Extended 0xFC control functions
|
|
|
|
static u8 HandleExtCtrlCode(struct Window *win)
|
|
{
|
|
return sExtCtrlCodeFuncs[win->text[win->textIndex++]](win);
|
|
}
|
|
|
|
static u8 ExtCtrlCode_Nop(struct Window *win)
|
|
{
|
|
return 2;
|
|
}
|
|
|
|
static u8 ExtCtrlCode_ForegroundColor(struct Window *win)
|
|
{
|
|
SetWindowForegroundColor(win, win->text[win->textIndex++]);
|
|
return 2;
|
|
}
|
|
|
|
static u8 ExtCtrlCode_BackgroundColor(struct Window *win)
|
|
{
|
|
SetWindowBackgroundColor(win, win->text[win->textIndex++]);
|
|
return 2;
|
|
}
|
|
|
|
static u8 ExtCtrlCode_ShadowColor(struct Window *win)
|
|
{
|
|
SetWindowShadowColor(win, win->text[win->textIndex++]);
|
|
return 2;
|
|
}
|
|
|
|
static u8 ExtCtrlCode_AllColors(struct Window *win)
|
|
{
|
|
SetWindowForegroundColor(win, win->text[win->textIndex++]);
|
|
SetWindowBackgroundColor(win, win->text[win->textIndex++]);
|
|
SetWindowShadowColor(win, win->text[win->textIndex++]);
|
|
return 2;
|
|
}
|
|
|
|
static u8 ExtCtrlCode_Palette(struct Window *win)
|
|
{
|
|
win->paletteNum = win->text[win->textIndex++];
|
|
return 2;
|
|
}
|
|
|
|
static u8 ExtCtrlCode_Font(struct Window *win)
|
|
{
|
|
win->fontNum = win->text[win->textIndex++];
|
|
return 2;
|
|
}
|
|
|
|
static u8 ExtCtrlCode_DefaultFont(struct Window *win)
|
|
{
|
|
win->fontNum = win->template->fontNum;
|
|
return 2;
|
|
}
|
|
|
|
static u8 ExtCtrlCode_Pause(struct Window *win)
|
|
{
|
|
ClipRight(win);
|
|
win->state = WIN_STATE_PAUSE;
|
|
win->delayCounter = win->text[win->textIndex++];
|
|
return 2;
|
|
}
|
|
|
|
static u8 ExtCtrlCode_WaitButton(struct Window *win)
|
|
{
|
|
ClipRight(win);
|
|
win->state = WIN_STATE_WAIT_BUTTON;
|
|
return 2;
|
|
}
|
|
|
|
static u8 ExtCtrlCode_WaitSound(struct Window *win)
|
|
{
|
|
ClipRight(win);
|
|
win->state = WIN_STATE_WAIT_SOUND;
|
|
return 2;
|
|
}
|
|
|
|
static u8 ExtCtrlCode_PlayBGM(struct Window *win)
|
|
{
|
|
u16 loByte = win->text[win->textIndex++];
|
|
u16 hiByte = win->text[win->textIndex++] << 8;
|
|
PlayBGM(loByte | hiByte);
|
|
return 2;
|
|
}
|
|
|
|
static u8 ExtCtrlCode_Escape(struct Window *win)
|
|
{
|
|
sPrintGlyphFuncs[win->textMode](win, win->text[win->textIndex++]);
|
|
return 1;
|
|
}
|
|
|
|
u8 ExtCtrlCode_Nop2(struct Window *win)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
static u8 ExtCtrlCode_SetCursorY(struct Window *win)
|
|
{
|
|
ClipRight(win);
|
|
AddToCursorY(win, 8 * win->text[win->textIndex++]);
|
|
return 1;
|
|
}
|
|
|
|
static u8 ExtCtrlCode_ClearWindowTextLines(struct Window *win)
|
|
{
|
|
Text_ClearWindow(win);
|
|
return 2;
|
|
}
|
|
|
|
static u8 ExtCtrlCode_PlaySE(struct Window *win)
|
|
{
|
|
u16 loByte = win->text[win->textIndex++];
|
|
u16 hiByte = win->text[win->textIndex++] << 8;
|
|
PlaySE(loByte | hiByte);
|
|
return 2;
|
|
}
|
|
|
|
static void DrawSpace(struct Window *win)
|
|
{
|
|
if (win->textMode == TEXT_MODE_MONOSPACE || (win->left + win->cursorX) & 7 || win->spacing <= 7)
|
|
{
|
|
sPrintGlyphFuncs[win->textMode](win, 0);
|
|
}
|
|
else
|
|
{
|
|
u32 val = sGlyphBuffer.background;
|
|
u16 index = GetCursorTileNum(win, 0, 0);
|
|
u32 *buffer = (u32 *)(win->tileData + 32 * index);
|
|
buffer[0] = val;
|
|
buffer[1] = val;
|
|
buffer[2] = val;
|
|
buffer[3] = val;
|
|
buffer[4] = val;
|
|
buffer[5] = val;
|
|
buffer[6] = val;
|
|
buffer[7] = val;
|
|
index = GetCursorTileNum(win, 0, 1);
|
|
buffer = (u32 *)(win->tileData + 32 * index);
|
|
buffer[0] = val;
|
|
buffer[1] = val;
|
|
buffer[2] = val;
|
|
buffer[3] = val;
|
|
buffer[4] = val;
|
|
buffer[5] = val;
|
|
buffer[6] = val;
|
|
buffer[7] = val;
|
|
UpdateTilemap(win, 1);
|
|
AddToCursorX(win, 8);
|
|
}
|
|
}
|
|
|
|
static void sub_8003344(struct Window *win, u8 newX)
|
|
{
|
|
u8 savedSpacing = win->spacing;
|
|
|
|
if (newX - win->cursorX <= 8)
|
|
win->spacing = newX - win->cursorX;
|
|
else
|
|
win->spacing = 8 - ((win->left + win->cursorX) & 7);
|
|
|
|
while (win->cursorX < newX)
|
|
{
|
|
s32 spacing;
|
|
DrawSpace(win);
|
|
spacing = newX - win->cursorX;
|
|
if (spacing >= 8)
|
|
spacing = 8;
|
|
win->spacing = spacing;
|
|
}
|
|
|
|
win->spacing = savedSpacing;
|
|
}
|
|
|
|
static u8 ExtCtrlCode_Skip(struct Window *win)
|
|
{
|
|
sub_8003344(win, win->cursorX + win->text[win->textIndex++]);
|
|
return 1;
|
|
}
|
|
|
|
static u8 ExtCtrlCode_SetCursorX(struct Window *win)
|
|
{
|
|
ClipRight(win);
|
|
SetCursorX(win, win->text[win->textIndex++]);
|
|
return 1;
|
|
}
|
|
|
|
static u8 ExtCtrlCode_SkipTo(struct Window *win)
|
|
{
|
|
sub_8003344(win, win->text[win->textIndex++]);
|
|
return 1;
|
|
}
|
|
|
|
static u8 ExtCtrlCode_Spacing(struct Window *win)
|
|
{
|
|
win->spacing = win->text[win->textIndex++];
|
|
return 2;
|
|
}
|
|
|
|
static u8 ExtCtrlCode_Japanese(struct Window *win)
|
|
{
|
|
win->language = LANGUAGE_JAPANESE;
|
|
return 2;
|
|
}
|
|
|
|
static u8 ExtCtrlCode_Latin(struct Window *win)
|
|
{
|
|
win->language = GAME_LANGUAGE;
|
|
return 2;
|
|
}
|
|
|
|
// Prints the window text without expanding any placeholders
|
|
u8 Text_PrintWindowSimple(struct Window *win)
|
|
{
|
|
u8 retVal = 1;
|
|
while (win->state != WIN_STATE_END)
|
|
{
|
|
if (win->state == WIN_STATE_NEWLINE)
|
|
{
|
|
AddToCursorY(win, 16);
|
|
win->cursorX = 0;
|
|
if (win->win_field_F)
|
|
ClipLeft(win);
|
|
win->state = WIN_STATE_NORMAL;
|
|
}
|
|
if (PrintNextChar(win) == 1)
|
|
{
|
|
retVal = 0;
|
|
break;
|
|
}
|
|
}
|
|
return retVal;
|
|
}
|
|
|
|
u8 Text_InitWindowAndPrintText(struct Window *win, const u8 *text, u16 tileDataStartOffset, u8 left, u8 top)
|
|
{
|
|
Text_InitWindow(win, text, tileDataStartOffset, left, top);
|
|
return Text_PrintWindow8002F44(win);
|
|
}
|
|
|
|
u8 sub_8003490(struct Window *win, u8 c, u16 tileDataStartOffset, u8 left, u8 top)
|
|
{
|
|
u8 retVal;
|
|
u8 text[2];
|
|
text[0] = c;
|
|
text[1] = EOS;
|
|
Text_InitWindow(win, text, tileDataStartOffset, left, top);
|
|
retVal = PrintNextChar(win);
|
|
ClipRight(win);
|
|
return retVal;
|
|
}
|
|
|
|
void sub_80034D4(u8 *tileData, const u8 *text)
|
|
{
|
|
Text_InitWindow8004E3C(&gWindowTemplate_81E6C74, tileData, text);
|
|
}
|
|
|
|
u8 sub_80034EC(u8 *str)
|
|
{
|
|
return Text_GetStringWidthFromWindowTemplate((struct WindowTemplate *)&gWindowTemplate_81E6C74, str);
|
|
}
|
|
|
|
u8 *sub_8003504(u8 *dest, s32 value, u8 alignAmount, u8 alignType)
|
|
{
|
|
sTempWindow.template = (struct WindowTemplate *)&gWindowTemplate_81E6C74;
|
|
Text_InitWindow(&sTempWindow, 0, 0, 0, 0);
|
|
return AlignInt2(&sTempWindow, dest, value, alignAmount, alignType);
|
|
}
|
|
|
|
u8 *sub_8003558(u8 *dest, const u8 *src, u8 alignAmount, u8 alignType)
|
|
{
|
|
sTempWindow.template = (struct WindowTemplate *)&gWindowTemplate_81E6C74;
|
|
Text_InitWindow(&sTempWindow, src, 0, 0, 0);
|
|
return AlignString(&sTempWindow, dest, src, alignAmount, alignType);
|
|
}
|
|
|
|
// Updates the window text
|
|
// The text delay can be accelerated by holding the A button
|
|
u8 Text_UpdateWindow(struct Window *win)
|
|
{
|
|
sWaitType = WAIT_TYPE_NORMAL;
|
|
return UpdateWindowText(win);
|
|
}
|
|
|
|
// Returns TRUE when all of the text has been printed.
|
|
static u8 UpdateWindowText(struct Window *win)
|
|
{
|
|
switch (win->state)
|
|
{
|
|
case WIN_STATE_WAIT_BUTTON:
|
|
if (PlayerCanInterruptDelay(win))
|
|
{
|
|
if (gMain.newKeys & (A_BUTTON | B_BUTTON))
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
win->delayCounter--;
|
|
if (win->delayCounter)
|
|
return FALSE;
|
|
}
|
|
win->state = WIN_STATE_NORMAL;
|
|
return FALSE;
|
|
case WIN_STATE_CHAR_DELAY:
|
|
// Allow the player to speed up text by holding a button
|
|
if (PlayerCanInterruptDelay(win)
|
|
&& (gMain.heldKeys & (A_BUTTON | B_BUTTON))
|
|
&& gMain.watchedKeysPressed == TRUE)
|
|
{
|
|
win->delayCounter = 0;
|
|
win->state = WIN_STATE_NORMAL;
|
|
break;
|
|
}
|
|
// fall through
|
|
case WIN_STATE_PAUSE:
|
|
// Wait for timer to expire, then continue printing
|
|
if (win->delayCounter)
|
|
{
|
|
win->delayCounter--;
|
|
if (win->delayCounter)
|
|
return FALSE;
|
|
}
|
|
win->state = WIN_STATE_NORMAL;
|
|
break;
|
|
case WIN_STATE_WAIT_CLEAR:
|
|
// Erase the text once a button is pressed
|
|
if (WaitWithDownArrow(win))
|
|
{
|
|
Text_ClearWindow(win);
|
|
win->state = WIN_STATE_NORMAL;
|
|
asm("");
|
|
}
|
|
return FALSE;
|
|
case WIN_STATE_WAIT_SCROLL:
|
|
// Scroll the text once a button is pressed
|
|
if (WaitWithDownArrow(win))
|
|
{
|
|
ScrollWindowTextLines(win);
|
|
win->state = WIN_STATE_NORMAL;
|
|
asm("");
|
|
}
|
|
return FALSE;
|
|
case WIN_STATE_PLACEHOLDER:
|
|
win->textIndex++;
|
|
win->state = WIN_STATE_NORMAL;
|
|
break;
|
|
case WIN_STATE_NEWLINE:
|
|
ScrollWindowTextLines(win);
|
|
win->state = WIN_STATE_NORMAL;
|
|
asm("");
|
|
return FALSE;
|
|
case WIN_STATE_BEGIN:
|
|
Text_ClearWindow(win);
|
|
break;
|
|
case WIN_STATE_WAIT_SOUND:
|
|
if (IsSEPlaying())
|
|
return FALSE;
|
|
win->state = WIN_STATE_NORMAL;
|
|
break;
|
|
case WIN_STATE_END:
|
|
return TRUE; // done printing text
|
|
case WIN_STATE_NORMAL:
|
|
break;
|
|
default:
|
|
win->state = WIN_STATE_END;
|
|
return TRUE;
|
|
}
|
|
|
|
PrintNextChar(win);
|
|
|
|
switch (win->state)
|
|
{
|
|
case WIN_STATE_END:
|
|
return TRUE; // done printing text
|
|
case WIN_STATE_WAIT_BUTTON:
|
|
case WIN_STATE_WAIT_CLEAR:
|
|
case WIN_STATE_WAIT_SCROLL:
|
|
if (PlayerCanInterruptDelay(win))
|
|
return 0;
|
|
win->delayCounter = 60;
|
|
break;
|
|
case WIN_STATE_PAUSE:
|
|
case WIN_STATE_NEWLINE:
|
|
case WIN_STATE_WAIT_SOUND:
|
|
break;
|
|
default:
|
|
win->state = WIN_STATE_CHAR_DELAY;
|
|
win->delayCounter = GetTextDelay(win);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if defined(ENGLISH)
|
|
#define SUB_800374C_LINE_LENGTH 26
|
|
#elif defined(GERMAN)
|
|
#define SUB_800374C_LINE_LENGTH 27
|
|
#endif
|
|
|
|
u8 Text_UpdateWindowInBattle(struct Window *win)
|
|
{
|
|
u8 retVal;
|
|
|
|
sWaitType = WAIT_TYPE_BATTLE;
|
|
sLineLength = SUB_800374C_LINE_LENGTH;
|
|
retVal = UpdateWindowText(win);
|
|
sLineLength = 26;
|
|
sWaitType = WAIT_TYPE_NORMAL;
|
|
return retVal;
|
|
}
|
|
|
|
u8 Text_UpdateWindowAutoscroll(struct Window *win)
|
|
{
|
|
u8 retVal;
|
|
|
|
sWaitType = WAIT_TYPE_AUTOSCROLL;
|
|
sLineLength = 26;
|
|
retVal = UpdateWindowText(win);
|
|
sWaitType = WAIT_TYPE_NORMAL;
|
|
return retVal;
|
|
}
|
|
|
|
u8 Text_UpdateWindowInContest(struct Window *win)
|
|
{
|
|
u8 retVal;
|
|
|
|
sWaitType = WAIT_TYPE_CONTEST;
|
|
sLineLength = 17;
|
|
retVal = UpdateWindowText(win);
|
|
sLineLength = 26;
|
|
return retVal;
|
|
}
|
|
|
|
u32 Text_UpdateWindowOverrideLineLength(struct Window *win, u8 lineLength)
|
|
{
|
|
u8 retVal;
|
|
|
|
sWaitType = WAIT_TYPE_NORMAL;
|
|
sLineLength = lineLength;
|
|
retVal = UpdateWindowText(win);
|
|
sLineLength = 26;
|
|
return retVal;
|
|
}
|
|
|
|
static void PrintGlyph_TextMode0(struct Window *win, u32 glyph)
|
|
{
|
|
AddToCursorX(win, DrawGlyph_TextMode0(win, glyph));
|
|
if (win->win_field_B)
|
|
ClipRight(win);
|
|
}
|
|
|
|
static u8 DrawGlyph_TextMode0(struct Window *win, u32 glyph)
|
|
{
|
|
u8 pixelsWidth = GetGlyphWidth(win, glyph);
|
|
u32 tilesWidth = DrawGlyphTiles(win, glyph, pixelsWidth);
|
|
UpdateTilemap(win, tilesWidth);
|
|
return pixelsWidth;
|
|
}
|
|
|
|
static void PrintGlyph_TextMode1(struct Window *win, u32 glyph)
|
|
{
|
|
sWriteGlyphTilemapFuncs[win->fontNum](win, glyph);
|
|
win->cursorX += 8;
|
|
}
|
|
|
|
static void WriteGlyphTilemap_Font0_Font3(struct Window *win, u32 glyph)
|
|
{
|
|
s16 val = win->tileDataStartOffset + 2 * glyph;
|
|
WriteGlyphTilemap(win, val, val + 1);
|
|
}
|
|
|
|
static void WriteGlyphTilemap_Font1_Font4(struct Window *win, u32 glyph)
|
|
{
|
|
u32 val = glyph * 2;
|
|
WriteGlyphTilemap(
|
|
win,
|
|
win->tileDataStartOffset + sFontType1Map[val],
|
|
win->tileDataStartOffset + sFontType1Map[val + 1]);
|
|
}
|
|
|
|
static void WriteGlyphTilemap_Font2_Font5(struct Window *win, u32 glyph)
|
|
{
|
|
WriteGlyphTilemap(
|
|
win,
|
|
win->tileDataStartOffset + 212,
|
|
win->tileDataStartOffset + glyph);
|
|
}
|
|
|
|
static void WriteGlyphTilemap_Font6(struct Window *win, u32 glyph)
|
|
{
|
|
u32 val = glyph * 2;
|
|
WriteGlyphTilemap(
|
|
win,
|
|
win->tileDataStartOffset + sFontType3Map[val],
|
|
win->tileDataStartOffset + sFontType3Map[val + 1]);
|
|
}
|
|
|
|
static void PrintGlyph_TextMode2(struct Window *win, u32 glyph)
|
|
{
|
|
u8 width = GetGlyphWidth(win, glyph);
|
|
DrawGlyph_TextMode2(win, glyph);
|
|
AddToCursorX(win, width);
|
|
if (win->win_field_B)
|
|
ClipRight(win);
|
|
}
|
|
|
|
static void DrawGlyph_TextMode2(struct Window *win, u32 glyph)
|
|
{
|
|
u8 pixelsWidth = GetGlyphWidth(win, glyph);
|
|
u32 tilesWidth = DrawGlyphTiles(win, glyph, pixelsWidth);
|
|
UpdateTilemap(win, tilesWidth);
|
|
}
|
|
|
|
static void LoadFixedWidthGlyph(struct Window *win, u32 glyph, u8 *dest)
|
|
{
|
|
u8 *upperTile;
|
|
u8 *lowerTile;
|
|
|
|
GetGlyphTilePointers(win->fontNum, win->language, glyph, &upperTile, &lowerTile);
|
|
|
|
switch (win->fontNum)
|
|
{
|
|
case 0:
|
|
case 1:
|
|
case 2:
|
|
case 6:
|
|
ApplyColors_UnshadowedFont(upperTile, (u32 *)dest, win->foregroundColor, win->backgroundColor);
|
|
ApplyColors_UnshadowedFont(lowerTile, (u32 *)(dest + 32), win->foregroundColor, win->backgroundColor);
|
|
break;
|
|
case 3:
|
|
case 4:
|
|
case 5:
|
|
ApplyColors_ShadowedFont(upperTile, dest, win->foregroundColor, win->shadowColor, win->backgroundColor);
|
|
ApplyColors_ShadowedFont(lowerTile, dest + 32, win->foregroundColor, win->shadowColor, win->backgroundColor);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void WriteGlyphTilemap(struct Window *win, u16 upperTileNum, u16 lowerTileNum)
|
|
{
|
|
u16 *buffer = GetCursorTilemapPointer(win);
|
|
if (buffer)
|
|
{
|
|
u16 palette = (win->paletteNum << 12);
|
|
buffer[0] = upperTileNum | palette;
|
|
buffer[32] = lowerTileNum | palette;
|
|
}
|
|
}
|
|
|
|
static void GetGlyphTilePointers(u8 fontNum, u8 language, u16 glyph, u8 **upperTilePtr, u8 **lowerTilePtr)
|
|
{
|
|
u16 index;
|
|
const struct Font *font;
|
|
|
|
if (language == LANGUAGE_JAPANESE)
|
|
language = 0;
|
|
else
|
|
language = 7;
|
|
|
|
font = &sFonts[language + fontNum];
|
|
|
|
switch (font->type)
|
|
{
|
|
case 0:
|
|
*upperTilePtr = font->glyphs + glyph * font->glyphSize;
|
|
*lowerTilePtr = *upperTilePtr + font->lowerTileOffset;
|
|
break;
|
|
case 1:
|
|
index = 2 * glyph;
|
|
*upperTilePtr = font->glyphs + sFontType1Map[index] * font->glyphSize;
|
|
*lowerTilePtr = font->glyphs + sFontType1Map[index + 1] * font->glyphSize;
|
|
break;
|
|
case 2:
|
|
*upperTilePtr = font->glyphs + 212 * font->glyphSize;
|
|
*lowerTilePtr = font->glyphs + glyph * font->glyphSize;
|
|
break;
|
|
case 3:
|
|
index = 2 * glyph;
|
|
*upperTilePtr = font->glyphs + sFontType3Map[index] * font->glyphSize;
|
|
*lowerTilePtr = font->glyphs + sFontType3Map[index + 1] * font->glyphSize;
|
|
break;
|
|
case 4:
|
|
*upperTilePtr = font->glyphs
|
|
+ (glyph & 0xFFF0) * font->glyphSize
|
|
+ (((glyph &= 0xF) * font->glyphSize) >> 1);
|
|
*lowerTilePtr = *upperTilePtr + font->lowerTileOffset;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static u16 *GetCursorTilemapPointer(struct Window *win)
|
|
{
|
|
u16 *ptr = NULL;
|
|
if (win->tilemap)
|
|
{
|
|
u8 x = ((win->left + win->cursorX) >> 3) + win->tilemapLeft;
|
|
u8 y = ((win->top + win->cursorY) >> 3) + win->tilemapTop;
|
|
ptr = &win->tilemap[(y * 32) + x];
|
|
}
|
|
return ptr;
|
|
}
|
|
|
|
static void ApplyColors_UnshadowedFont(const u8 *src, u32 *dest, u8 foreground, u8 background)
|
|
{
|
|
u32 a[2];
|
|
s32 i;
|
|
const u8 *srcRows = src;
|
|
|
|
a[0] = background;
|
|
a[1] = foreground;
|
|
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
u32 destRow = a[srcRows[i] & 1]
|
|
| (a[(srcRows[i] >> 1) & 1] << 4)
|
|
| (a[(srcRows[i] >> 2) & 1] << 8)
|
|
| (a[(srcRows[i] >> 3) & 1] << 12)
|
|
| (a[(srcRows[i] >> 4) & 1] << 16)
|
|
| (a[(srcRows[i] >> 5) & 1] << 20)
|
|
| (a[(srcRows[i] >> 6) & 1] << 24)
|
|
| (a[(srcRows[i] >> 7) ] << 28);
|
|
dest[i] = destRow;
|
|
}
|
|
}
|
|
|
|
static void ApplyColors_ShadowedFont(const void *src, void *dest, u8 foreground, u8 shadow, u8 background)
|
|
{
|
|
u32 a[0x10];
|
|
s32 i;
|
|
const u32 *curSrc;
|
|
u32 *curDest;
|
|
u32 colorMask;
|
|
|
|
a[0x1] = 0x1;
|
|
a[0x2] = 0x2;
|
|
a[0x3] = 0x3;
|
|
a[0x4] = 0x4;
|
|
a[0x5] = 0x5;
|
|
a[0x6] = 0x6;
|
|
a[0x7] = 0x7;
|
|
a[0x8] = 0x8;
|
|
a[0x9] = 0x9;
|
|
a[0xA] = 0xA;
|
|
a[0xB] = 0xB;
|
|
a[0xC] = 0xC;
|
|
a[0xD] = 0xD;
|
|
a[0x0] = background;
|
|
a[0xE] = shadow;
|
|
a[0xF] = foreground;
|
|
|
|
colorMask = 0xF;
|
|
|
|
curSrc = src;
|
|
curDest = dest;
|
|
|
|
for (i = 7; i >= 0; i--)
|
|
{
|
|
u32 row = *curSrc++;
|
|
u32 recoloredRow = a[row & colorMask]
|
|
| (a[(row >> 4) & colorMask] << 4)
|
|
| (a[(row >> 8) & colorMask] << 8)
|
|
| (a[(row >> 12) & colorMask] << 12)
|
|
| (a[(row >> 16) & colorMask] << 16)
|
|
| (a[(row >> 20) & colorMask] << 20)
|
|
| (a[(row >> 24) & colorMask] << 24)
|
|
| (a[(row >> 28) ] << 28);
|
|
*curDest++ = recoloredRow;
|
|
}
|
|
}
|
|
|
|
static void SetCursorX(struct Window *win, u8 x)
|
|
{
|
|
if (win->textMode == TEXT_MODE_UNKNOWN0 && ((win->left + win->cursorX) & 7))
|
|
win->tileDataOffset += 2;
|
|
win->cursorX = x;
|
|
}
|
|
|
|
static void AddToCursorX(struct Window *win, u8 deltaX)
|
|
{
|
|
if (win->textMode == TEXT_MODE_UNKNOWN0)
|
|
{
|
|
u8 x = win->cursorX;
|
|
win->cursorX += deltaX;
|
|
if (((win->left + win->cursorX) & 0xF8) != ((win->left + x) & 0xF8))
|
|
win->tileDataOffset += 2;
|
|
}
|
|
else
|
|
{
|
|
win->cursorX += deltaX;
|
|
}
|
|
}
|
|
|
|
static void AddToCursorY(struct Window *win, u8 deltaY)
|
|
{
|
|
if (win->textMode == TEXT_MODE_UNKNOWN0 && ((win->left + win->cursorX) & 7))
|
|
win->tileDataOffset += 2;
|
|
win->cursorY += deltaY;
|
|
}
|
|
|
|
static void EraseAtCursor(struct Window *win)
|
|
{
|
|
switch (win->textMode)
|
|
{
|
|
case TEXT_MODE_UNKNOWN0:
|
|
case TEXT_MODE_UNKNOWN2:
|
|
DrawGlyphTiles(win, 0, 8);
|
|
break;
|
|
case TEXT_MODE_MONOSPACE:
|
|
sWriteGlyphTilemapFuncs[win->fontNum](win, 0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void ClipLeft(struct Window *win)
|
|
{
|
|
u32 pixel = win->left & 7;
|
|
|
|
if (win->textMode != TEXT_MODE_MONOSPACE && pixel)
|
|
{
|
|
const u32 *masks = sGlyphMasks[8][pixel];
|
|
u32 outsideMask = masks[0];
|
|
u32 insideMask = ~outsideMask;
|
|
u32 outside = sGlyphBuffer.background & outsideMask;
|
|
u16 tileNum = GetCursorTileNum(win, 0, 0);
|
|
u32 *buffer = (u32 *)(win->tileData + 32 * tileNum);
|
|
buffer[0] = (buffer[0] & insideMask) | outside;
|
|
buffer[1] = (buffer[1] & insideMask) | outside;
|
|
buffer[2] = (buffer[2] & insideMask) | outside;
|
|
buffer[3] = (buffer[3] & insideMask) | outside;
|
|
buffer[4] = (buffer[4] & insideMask) | outside;
|
|
buffer[5] = (buffer[5] & insideMask) | outside;
|
|
buffer[6] = (buffer[6] & insideMask) | outside;
|
|
buffer[7] = (buffer[7] & insideMask) | outside;
|
|
tileNum = GetCursorTileNum(win, 0, 1);
|
|
buffer = (u32 *)(win->tileData + 32 * tileNum);
|
|
buffer[0] = (buffer[0] & insideMask) | outside;
|
|
buffer[1] = (buffer[1] & insideMask) | outside;
|
|
buffer[2] = (buffer[2] & insideMask) | outside;
|
|
buffer[3] = (buffer[3] & insideMask) | outside;
|
|
buffer[4] = (buffer[4] & insideMask) | outside;
|
|
buffer[5] = (buffer[5] & insideMask) | outside;
|
|
buffer[6] = (buffer[6] & insideMask) | outside;
|
|
buffer[7] = (buffer[7] & insideMask) | outside;
|
|
}
|
|
}
|
|
|
|
static void ClipRight(struct Window *win)
|
|
{
|
|
register u8 cursorX asm("r0") = win->cursorX;
|
|
u8 left = win->left;
|
|
u32 pixelX = (cursorX + left) & 7;
|
|
|
|
if (win->textMode != TEXT_MODE_MONOSPACE && pixelX != 0)
|
|
{
|
|
const u32 *masks = sGlyphMasks[8 - pixelX][pixelX];
|
|
u32 insideMask = masks[0];
|
|
u32 outside = (sGlyphBuffer.background & ~insideMask);
|
|
u16 tileNum;
|
|
u32 *tileData;
|
|
|
|
tileNum = GetCursorTileNum(win, 0, 0);
|
|
tileData = (u32 *)(win->tileData + 32 * tileNum);
|
|
|
|
tileData[0] = (tileData[0] & insideMask) | outside;
|
|
tileData[1] = (tileData[1] & insideMask) | outside;
|
|
tileData[2] = (tileData[2] & insideMask) | outside;
|
|
tileData[3] = (tileData[3] & insideMask) | outside;
|
|
tileData[4] = (tileData[4] & insideMask) | outside;
|
|
tileData[5] = (tileData[5] & insideMask) | outside;
|
|
tileData[6] = (tileData[6] & insideMask) | outside;
|
|
tileData[7] = (tileData[7] & insideMask) | outside;
|
|
|
|
tileNum = GetCursorTileNum(win, 0, 1);
|
|
tileData = (u32 *)(win->tileData + 32 * tileNum);
|
|
|
|
tileData[0] = (tileData[0] & insideMask) | outside;
|
|
tileData[1] = (tileData[1] & insideMask) | outside;
|
|
tileData[2] = (tileData[2] & insideMask) | outside;
|
|
tileData[3] = (tileData[3] & insideMask) | outside;
|
|
tileData[4] = (tileData[4] & insideMask) | outside;
|
|
tileData[5] = (tileData[5] & insideMask) | outside;
|
|
tileData[6] = (tileData[6] & insideMask) | outside;
|
|
tileData[7] = (tileData[7] & insideMask) | outside;
|
|
|
|
UpdateTilemap(win, 1);
|
|
}
|
|
}
|
|
|
|
static void SetWindowDefaultColors(struct Window *win)
|
|
{
|
|
u32 i;
|
|
|
|
win->backgroundColor = 0;
|
|
win->shadowColor = 14;
|
|
win->foregroundColor = 15;
|
|
|
|
for (i = 0; i < 16; i++)
|
|
sGlyphBuffer.colors[i] = i;
|
|
}
|
|
|
|
static void SetWindowBackgroundColor(struct Window *win, u8 color)
|
|
{
|
|
u32 val1;
|
|
u32 val2;
|
|
u32 val3;
|
|
win->backgroundColor = color;
|
|
sGlyphBuffer.colors[0] = color;
|
|
val1 = color | (color << 4);
|
|
val2 = val1 | (val1 << 8);
|
|
val3 = val2 | (val2 << 16);
|
|
sGlyphBuffer.background = val3;
|
|
}
|
|
|
|
static void SetWindowShadowColor(struct Window *win, u8 color)
|
|
{
|
|
win->shadowColor = color;
|
|
sGlyphBuffer.colors[14] = color;
|
|
}
|
|
|
|
static void SetWindowForegroundColor(struct Window *win, u8 color)
|
|
{
|
|
win->foregroundColor = color;
|
|
sGlyphBuffer.colors[15] = color;
|
|
}
|
|
|
|
static u8 GetTextDelay(struct Window *win)
|
|
{
|
|
if (!PlayerCanInterruptDelay(win))
|
|
return 3;
|
|
|
|
return sTextSpeedDelays[gSaveBlock2.optionsTextSpeed];
|
|
}
|
|
|
|
static bool8 PlayerCanInterruptDelay(struct Window *win)
|
|
{
|
|
bool8 retVal = TRUE;
|
|
|
|
switch (sWaitType)
|
|
{
|
|
case WAIT_TYPE_AUTOSCROLL:
|
|
retVal = FALSE;
|
|
break;
|
|
case WAIT_TYPE_CONTEST:
|
|
retVal = gIsLinkContest ? FALSE : TRUE;
|
|
break;
|
|
case WAIT_TYPE_BATTLE:
|
|
retVal = (gBattleTypeFlags & BATTLE_TYPE_LINK) ? FALSE : TRUE;
|
|
break;
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
static void ScrollWindowTextLines(struct Window *win)
|
|
{
|
|
switch (win->textMode)
|
|
{
|
|
case TEXT_MODE_UNKNOWN0:
|
|
ScrollWindowTextLines_TextMode0(win);
|
|
break;
|
|
case TEXT_MODE_MONOSPACE:
|
|
ScrollWindowTextLines_TextModeMonospace(win);
|
|
break;
|
|
case TEXT_MODE_UNKNOWN2:
|
|
ScrollWindowTextLines_TextMode2(win);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void ScrollWindowTextLines_TextMode0(struct Window *win)
|
|
{
|
|
if (win->cursorY == 0)
|
|
{
|
|
// Advance to the next line
|
|
win->tileDataOffset = 2 * sLineLength + 2;
|
|
win->cursorX = 0;
|
|
win->cursorY += 16;
|
|
}
|
|
else
|
|
{
|
|
if (win->win_field_C & 2)
|
|
win->tileDataOffset = 2 * sLineLength + 2;
|
|
else
|
|
win->tileDataOffset = 2;
|
|
win->win_field_C ^= 2;
|
|
win->cursorX = 0;
|
|
DoScroll_TextMode0(win, sLineLength);
|
|
}
|
|
}
|
|
|
|
static void DoScroll_TextMode0(struct Window *win, u16 lineLength)
|
|
{
|
|
u16 *buffer = win->tilemap;
|
|
u32 val1 = 32 * (win->top >> 3);
|
|
u32 val2 = (win->left >> 3);
|
|
u16 fill;
|
|
buffer += val1 + val2;
|
|
fill = (win->paletteNum << 12) | GetBlankTileNum(win);
|
|
|
|
// Move the bottom line up
|
|
CpuCopy16(buffer + 64, buffer, lineLength * 2);
|
|
CpuCopy16(buffer + 96, buffer + 32, lineLength * 2);
|
|
|
|
// Clear the bottom line
|
|
CpuFill16(fill, buffer + 64, lineLength * 2);
|
|
CpuFill16(fill, buffer + 96, lineLength * 2);
|
|
}
|
|
|
|
static void ScrollWindowTextLines_TextModeMonospace(struct Window *win)
|
|
{
|
|
if (win->cursorY == 0)
|
|
{
|
|
// Advance to the next line
|
|
win->cursorX = 0;
|
|
win->cursorY += 16;
|
|
}
|
|
else
|
|
{
|
|
win->win_field_C ^= 2;
|
|
win->cursorX = 0;
|
|
DoScroll_TextModeMonospace(win, sLineLength);
|
|
}
|
|
}
|
|
|
|
static void DoScroll_TextModeMonospace(struct Window *win, u16 lineLength)
|
|
{
|
|
u16 *buffer = GetCursorTilemapPointer(win);
|
|
u16 *dest = buffer - 32;
|
|
u16 fill = (win->paletteNum << 12) | GetBlankTileNum(win);
|
|
|
|
// Move the bottom line up
|
|
CpuCopy16(buffer + 32, dest, lineLength * 2);
|
|
CpuCopy16(buffer + 64, buffer, lineLength * 2);
|
|
|
|
// Clear the bottom line
|
|
CpuFill16(fill, buffer + 32, lineLength * 2);
|
|
CpuFill16(fill, buffer + 64, lineLength * 2);
|
|
}
|
|
|
|
static void ScrollWindowTextLines_TextMode2(struct Window *win)
|
|
{
|
|
if (win->cursorY == 0)
|
|
{
|
|
// Advance to the next line
|
|
win->cursorX = 0;
|
|
win->cursorY += 16;
|
|
}
|
|
else
|
|
{
|
|
win->win_field_C ^= 2;
|
|
win->cursorX = 0;
|
|
DoScroll_TextMode2(win, sLineLength);
|
|
}
|
|
}
|
|
|
|
static void DoScroll_TextMode2(struct Window *win, u8 lineLength)
|
|
{
|
|
u8 i;
|
|
u8 *buf1 = win->tileData + 32 * GetCursorTileNum(win, 0, -2);
|
|
u8 *buf2 = win->tileData + 32 * GetCursorTileNum(win, 0, 0);
|
|
u8 *buf4;
|
|
u16 *buf3;
|
|
u16 a[4];
|
|
|
|
CpuFastCopy(buf2, buf1, 32 * lineLength);
|
|
CpuFastFill(sGlyphBuffer.background, buf2, 32 * lineLength);
|
|
buf4 = buf2 + 32 * win->width;
|
|
CpuFastCopy(buf4, buf1 + 32 * win->width, 32 * lineLength);
|
|
CpuFastFill(sGlyphBuffer.background, buf4, 32 * lineLength);
|
|
|
|
buf3 = GetCursorTilemapPointer(win) - 64;
|
|
|
|
a[0] = (win->tileDataStartOffset + win->tileDataOffset
|
|
+ ((win->top >> 3) * win->width)
|
|
+ (win->left >> 3))
|
|
| (win->paletteNum << 12);
|
|
a[1] = a[0] + win->width;
|
|
a[2] = a[1] + win->width;
|
|
a[3] = a[2] + win->width;
|
|
|
|
for (i = 0; i < lineLength; i++)
|
|
{
|
|
buf3[0] = a[0]++;
|
|
buf3[32] = a[1]++;
|
|
buf3[64] = a[2]++;
|
|
buf3[96] = a[3]++;
|
|
buf3++;
|
|
}
|
|
}
|
|
|
|
void Text_ClearWindow(struct Window *win)
|
|
{
|
|
switch (win->textMode)
|
|
{
|
|
case TEXT_MODE_UNKNOWN0:
|
|
ClearWindowTextLines_TextMode0_TextMode1(win, sLineLength);
|
|
win->tileDataOffset = 2;
|
|
break;
|
|
case TEXT_MODE_MONOSPACE:
|
|
ClearWindowTextLines_TextMode0_TextMode1(win, sLineLength);
|
|
break;
|
|
case TEXT_MODE_UNKNOWN2:
|
|
ClearWindowTextLines_TextMode2(win, sLineLength);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void ClearWindowTextLines_TextMode0_TextMode1(struct Window *win, u8 lineLength)
|
|
{
|
|
u8 x, y;
|
|
u16 *buffer;
|
|
u16 fill;
|
|
|
|
win->cursorX = 0;
|
|
win->cursorY = 0;
|
|
win->win_field_C = 0;
|
|
|
|
buffer = GetCursorTilemapPointer(win);
|
|
fill = GetBlankTileNum(win) | (win->paletteNum << 12);
|
|
|
|
for (y = 0; y < 4; y++)
|
|
{
|
|
for (x = 0; x < lineLength; x++)
|
|
buffer[x] = fill;
|
|
buffer += 32;
|
|
}
|
|
}
|
|
|
|
static void ClearWindowTextLines_TextMode2(struct Window *win, u8 lineLength)
|
|
{
|
|
u8 *buffer;
|
|
|
|
win->cursorX = 0;
|
|
win->cursorY = 0;
|
|
win->win_field_C = 0;
|
|
|
|
buffer = win->tileData + 32 * GetCursorTileNum(win, 0, 0);
|
|
CpuFastFill(sGlyphBuffer.background, buffer, 32 * lineLength);
|
|
buffer += 32 * win->width;
|
|
CpuFastFill(sGlyphBuffer.background, buffer, 32 * lineLength);
|
|
buffer += 32 * win->width;
|
|
CpuFastFill(sGlyphBuffer.background, buffer, 32 * lineLength);
|
|
buffer += 32 * win->width;
|
|
CpuFastFill(sGlyphBuffer.background, buffer, 32 * lineLength);
|
|
}
|
|
|
|
static void DrawDownArrow(struct Window *win)
|
|
{
|
|
if (PlayerCanInterruptDelay(win))
|
|
{
|
|
const u32 *downArrowTiles = &sDownArrowTiles[((win->downArrowCounter & 0x0F00) >> 8) * 16];
|
|
|
|
switch (win->textMode)
|
|
{
|
|
case TEXT_MODE_MONOSPACE:
|
|
{
|
|
u8 *buffer;
|
|
u16 tileNum = win->tileDataStartOffset + 254;
|
|
if (win->fontNum == 0 || win->fontNum == 3)
|
|
tileNum *= 2;
|
|
buffer = win->tileData + 32 * tileNum;
|
|
ApplyColors_ShadowedFont(downArrowTiles, buffer, win->foregroundColor, win->shadowColor, win->backgroundColor);
|
|
ApplyColors_ShadowedFont(downArrowTiles + 8, buffer + 32, win->foregroundColor, win->shadowColor, win->backgroundColor);
|
|
WriteGlyphTilemap(win, tileNum, tileNum + 1);
|
|
break;
|
|
}
|
|
case TEXT_MODE_UNKNOWN0:
|
|
case TEXT_MODE_UNKNOWN2:
|
|
{
|
|
struct GlyphTileInfo glyphTileInfo;
|
|
glyphTileInfo.textMode = win->textMode;
|
|
glyphTileInfo.startPixel = (win->left + win->cursorX) & 7;
|
|
if (glyphTileInfo.startPixel != 0)
|
|
{
|
|
u8 *upperTile;
|
|
u8 *lowerTile;
|
|
GetGlyphTilePointers(win->fontNum, win->language, 0, &upperTile, &lowerTile);
|
|
glyphTileInfo.width = 8 - glyphTileInfo.startPixel;
|
|
glyphTileInfo.src = upperTile;
|
|
glyphTileInfo.dest = (u32 *)(win->tileData + 32 * GetCursorTileNum(win, 1, 0));
|
|
glyphTileInfo.colors = sGlyphBuffer.colors;
|
|
DrawGlyphTile_ShadowedFont(&glyphTileInfo);
|
|
glyphTileInfo.src = lowerTile;
|
|
glyphTileInfo.dest = (u32 *)(win->tileData + 32 * GetCursorTileNum(win, 1, 1));
|
|
DrawGlyphTile_ShadowedFont(&glyphTileInfo);
|
|
}
|
|
glyphTileInfo.width = 8;
|
|
glyphTileInfo.src = (u8 *)downArrowTiles;
|
|
glyphTileInfo.dest = (u32 *)(win->tileData + 32 * GetCursorTileNum(win, 0, 0));
|
|
glyphTileInfo.colors = sGlyphBuffer.colors;
|
|
DrawGlyphTile_ShadowedFont(&glyphTileInfo);
|
|
glyphTileInfo.src += 32;
|
|
glyphTileInfo.dest = (u32 *)(win->tileData + 32 * GetCursorTileNum(win, 0, 1));
|
|
DrawGlyphTile_ShadowedFont(&glyphTileInfo);
|
|
if (glyphTileInfo.startPixel != 0)
|
|
UpdateTilemap(win, 2);
|
|
else
|
|
UpdateTilemap(win, 1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static u8 WaitWithDownArrow(struct Window *win)
|
|
{
|
|
u8 retVal = TRUE;
|
|
|
|
if (!PlayerCanInterruptDelay(win))
|
|
{
|
|
win->delayCounter--;
|
|
if (!win->delayCounter)
|
|
{
|
|
TryEraseDownArrow(win);
|
|
}
|
|
else
|
|
{
|
|
UpdateDownArrowAnimation(win);
|
|
retVal = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (gMain.newKeys & (A_BUTTON | B_BUTTON))
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
TryEraseDownArrow(win);
|
|
}
|
|
else
|
|
{
|
|
UpdateDownArrowAnimation(win);
|
|
retVal = FALSE;
|
|
}
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
static void DrawInitialDownArrow(struct Window *win)
|
|
{
|
|
win->downArrowCounter = 0;
|
|
DrawDownArrow(win);
|
|
}
|
|
|
|
static void UpdateDownArrowAnimation(struct Window *win)
|
|
{
|
|
u16 downArrowPos = (win->downArrowCounter & 0x0F00) >> 8;
|
|
u16 wait = win->downArrowCounter & 0x000F;
|
|
u16 newVal;
|
|
|
|
wait++;
|
|
|
|
if (wait == 6)
|
|
{
|
|
wait = 0;
|
|
downArrowPos++;
|
|
if (downArrowPos > 3)
|
|
downArrowPos = 0;
|
|
win->downArrowCounter = downArrowPos << 8;
|
|
DrawDownArrow(win);
|
|
}
|
|
|
|
newVal = downArrowPos << 8;
|
|
newVal |= wait;
|
|
|
|
win->downArrowCounter = newVal;
|
|
}
|
|
|
|
static void TryEraseDownArrow(struct Window *win)
|
|
{
|
|
win->downArrowCounter = 0;
|
|
if (PlayerCanInterruptDelay(win) == TRUE)
|
|
EraseAtCursor(win);
|
|
}
|
|
|
|
// unused
|
|
u16 Text_GetWindowTilemapEntry(struct Window *win, u8 x, u8 y)
|
|
{
|
|
u16 *tilemap = win->tilemap;
|
|
return tilemap[32 * y + x];
|
|
}
|
|
|
|
// unused
|
|
void Text_FillWindowBorder(struct Window *win, u16 tilemapEntry, u8 left, u8 top, u8 right, u8 bottom)
|
|
{
|
|
u8 i;
|
|
u16 *buffer = &win->tilemap[top * 32];
|
|
|
|
// Fill top border
|
|
for (i = left; i <= right; i++)
|
|
buffer[i] = tilemapEntry;
|
|
|
|
for (i = top + 1; i < bottom - 1; i++)
|
|
{
|
|
buffer += 32;
|
|
// left border
|
|
buffer[left] = tilemapEntry;
|
|
// right border
|
|
buffer[right] = tilemapEntry;
|
|
}
|
|
|
|
// Fill bottom border
|
|
if (top != bottom)
|
|
{
|
|
buffer += 32;
|
|
for (i = left; i <= right; i++)
|
|
buffer[i] = tilemapEntry;
|
|
}
|
|
}
|
|
|
|
// unused
|
|
void DrawWindowRect_DefaultPalette(struct Window *win, u16 tileNum, u8 left, u8 top, u8 right, u8 bottom)
|
|
{
|
|
Text_FillWindowBorder(win, (win->paletteNum << 12) | tileNum, left, top, right, bottom);
|
|
}
|
|
|
|
// Fills the whole window area with tilemapEntry
|
|
void Text_FillWindowRect(struct Window *win, u16 tilemapEntry, u8 left, u8 top, u8 right, u8 bottom)
|
|
{
|
|
u16 *buffer = &win->tilemap[top * 32];
|
|
while (top++ <= bottom)
|
|
{
|
|
u8 x;
|
|
for (x = left; x <= right; x++)
|
|
buffer[x] = tilemapEntry;
|
|
buffer += 32;
|
|
}
|
|
}
|
|
|
|
void Text_FillWindowRectDefPalette(struct Window *win, u16 tileNum, u8 left, u8 top, u8 right, u8 bottom)
|
|
{
|
|
Text_FillWindowRect(win, (win->paletteNum << 12) | tileNum, left, top, right, bottom);
|
|
}
|
|
|
|
void Text_EraseWindowRect(struct Window *win, u8 left, u8 top, u8 right, u8 bottom)
|
|
{
|
|
Text_FillWindowRectDefPalette(win, 0, left, top, right, bottom);
|
|
}
|
|
|
|
void Text_BlankWindowRect(struct Window *win, u8 left, u8 top, u8 right, u8 bottom)
|
|
{
|
|
u16 tileNum = GetBlankTileNum(win);
|
|
Text_FillWindowRectDefPalette(win, tileNum, left, top, right, bottom);
|
|
}
|
|
|
|
static u16 GetBlankTileNum(struct Window *win)
|
|
{
|
|
u16 retVal = win->tileDataStartOffset;
|
|
|
|
switch (win->textMode)
|
|
{
|
|
case TEXT_MODE_UNKNOWN0:
|
|
break;
|
|
case TEXT_MODE_UNKNOWN2:
|
|
retVal++;
|
|
break;
|
|
case TEXT_MODE_MONOSPACE:
|
|
switch (win->fontNum)
|
|
{
|
|
case 1:
|
|
case 2:
|
|
case 4:
|
|
case 5:
|
|
retVal += 212;
|
|
case 0:
|
|
case 3:
|
|
case 6:
|
|
break;
|
|
default:
|
|
retVal = 0;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
static s32 Window_MoveCursor(struct Window *win, u8 x, u8 y)
|
|
{
|
|
win->cursorX = x;
|
|
win->cursorY = y & 0xF8;
|
|
}
|
|
|
|
static u8 GetGlyphWidth(struct Window *win, u32 glyph)
|
|
{
|
|
u8 width = 8;
|
|
|
|
#ifdef BUGFIX_GLYPHWIDTH
|
|
if (win->language != LANGUAGE_JAPANESE)
|
|
#else
|
|
if (win->language == LANGUAGE_ENGLISH)
|
|
#endif
|
|
{
|
|
width = win->spacing;
|
|
if (!win->spacing)
|
|
{
|
|
switch (win->fontNum)
|
|
{
|
|
case 3:
|
|
width = sFont3Widths[glyph];
|
|
break;
|
|
case 4:
|
|
case 5:
|
|
width = sFont4Widths[sFontType1Map[2 * glyph + 1]];
|
|
break;
|
|
case 0:
|
|
width = sFont0Widths[glyph];
|
|
break;
|
|
case 1:
|
|
case 2:
|
|
width = sFont1Widths[sFontType1Map[2 * glyph + 1]];
|
|
break;
|
|
case 6:
|
|
width = 8;
|
|
break;
|
|
default:
|
|
width = 8;
|
|
}
|
|
}
|
|
}
|
|
|
|
return width;
|
|
}
|
|
|
|
u8 GetExtCtrlCodeLength(u8 code)
|
|
{
|
|
u8 length = 0;
|
|
if (code <= 0x16)
|
|
length = sExtCtrlCodeLengths[code];
|
|
return length;
|
|
}
|
|
|
|
u8 *AlignInt1(struct Window *win, u8 *dest, s32 value, u8 alignAmount, u8 alignType)
|
|
{
|
|
u8 temp[16];
|
|
u8 width;
|
|
switch (alignType)
|
|
{
|
|
case 0:
|
|
ConvertIntToDecimalString(temp, value);
|
|
dest = StringCopy(dest, temp);
|
|
dest[0] = EXT_CTRL_CODE_BEGIN;
|
|
dest[1] = 19;
|
|
dest[2] = alignAmount;
|
|
dest += 3;
|
|
*dest = 0xFF;
|
|
break;
|
|
case 1:
|
|
ConvertIntToDecimalString(temp, value);
|
|
width = GetStringWidth(win, temp);
|
|
if (alignAmount > width)
|
|
{
|
|
dest[0] = EXT_CTRL_CODE_BEGIN;
|
|
dest[1] = 19;
|
|
dest[2] = alignAmount - width;
|
|
dest += 3;
|
|
}
|
|
dest = StringCopy(dest, temp);
|
|
break;
|
|
case 2:
|
|
ConvertIntToDecimalString(temp, value);
|
|
width = GetStringWidth(win, temp);
|
|
if (alignAmount > width)
|
|
{
|
|
dest[0] = EXT_CTRL_CODE_BEGIN;
|
|
dest[1] = 19;
|
|
dest[2] = (alignAmount - width) / 2;
|
|
dest += 3;
|
|
}
|
|
dest = StringCopy(dest, temp);
|
|
if (alignAmount > width)
|
|
{
|
|
dest[0] = EXT_CTRL_CODE_BEGIN;
|
|
dest[1] = 19;
|
|
dest[2] = alignAmount;
|
|
dest += 3;
|
|
*dest = 0xFF;
|
|
}
|
|
break;
|
|
}
|
|
return dest;
|
|
}
|
|
|
|
u8 *AlignInt2(struct Window *win, u8 *dest, s32 value, u8 alignAmount, u8 alignType)
|
|
{
|
|
u8 temp[16];
|
|
u8 width;
|
|
switch (alignType)
|
|
{
|
|
case 0:
|
|
ConvertIntToDecimalString(temp, value);
|
|
width = GetStringWidth(win, temp);
|
|
dest = StringCopy(dest, temp);
|
|
dest[0] = EXT_CTRL_CODE_BEGIN;
|
|
dest[1] = 17;
|
|
dest[2] = alignAmount - width;
|
|
dest += 3;
|
|
*dest = 0xFF;
|
|
break;
|
|
case 1:
|
|
ConvertIntToDecimalString(temp, value);
|
|
width = GetStringWidth(win, temp);
|
|
if (alignAmount > width)
|
|
{
|
|
dest[0] = EXT_CTRL_CODE_BEGIN;
|
|
dest[1] = 17;
|
|
dest[2] = alignAmount - width;
|
|
dest += 3;
|
|
}
|
|
dest = StringCopy(dest, temp);
|
|
break;
|
|
case 2:
|
|
ConvertIntToDecimalString(temp, value);
|
|
width = GetStringWidth(win, temp);
|
|
if (alignAmount > width)
|
|
{
|
|
dest[0] = EXT_CTRL_CODE_BEGIN;
|
|
dest[1] = 17;
|
|
dest[2] = (alignAmount - width) / 2;
|
|
dest += 3;
|
|
}
|
|
dest = StringCopy(dest, temp);
|
|
if (alignAmount > width)
|
|
{
|
|
dest[0] = EXT_CTRL_CODE_BEGIN;
|
|
dest[1] = 17;
|
|
dest[2] = (alignAmount - width) / 2;
|
|
dest += 3;
|
|
*dest = 0xFF;
|
|
}
|
|
break;
|
|
}
|
|
return dest;
|
|
}
|
|
|
|
u8 *AlignString(struct Window *win, u8 *dest, const u8 *src, u8 alignAmount, u8 alignType)
|
|
{
|
|
u8 width;
|
|
switch (alignType)
|
|
{
|
|
case 0:
|
|
dest = StringCopy(dest, src);
|
|
dest[0] = EXT_CTRL_CODE_BEGIN;
|
|
dest[1] = 19;
|
|
dest[2] = alignAmount;
|
|
dest += 3;
|
|
*dest = 0xFF;
|
|
break;
|
|
case 1:
|
|
width = GetStringWidth(win, src);
|
|
if (alignAmount > width)
|
|
{
|
|
dest[0] = EXT_CTRL_CODE_BEGIN;
|
|
dest[1] = 19;
|
|
dest[2] = alignAmount - width;
|
|
dest += 3;
|
|
}
|
|
dest = StringCopy(dest, src);
|
|
break;
|
|
case 2:
|
|
width = GetStringWidth(win, src);
|
|
if (alignAmount > width)
|
|
{
|
|
dest[0] = EXT_CTRL_CODE_BEGIN;
|
|
dest[1] = 19;
|
|
dest[2] = (alignAmount - width) / 2;
|
|
dest += 3;
|
|
}
|
|
dest = StringCopy(dest, src);
|
|
if (alignAmount > width)
|
|
{
|
|
dest[0] = EXT_CTRL_CODE_BEGIN;
|
|
dest[1] = 19;
|
|
dest[2] = alignAmount;
|
|
dest += 3;
|
|
*dest = 0xFF;
|
|
}
|
|
break;
|
|
}
|
|
return dest;
|
|
}
|
|
|
|
u8 GetStringWidth(struct Window *win, const u8 *s)
|
|
{
|
|
u8 width = 0;
|
|
u8 savedFontNum = win->fontNum;
|
|
u8 savedLanguage = win->language;
|
|
u8 savedSpacing = win->spacing;
|
|
s32 i = 0;
|
|
|
|
while (s[i] != EOS)
|
|
{
|
|
u8 c = s[i];
|
|
switch (c)
|
|
{
|
|
case PLACEHOLDER_BEGIN:
|
|
{
|
|
u8 temp;
|
|
i++;
|
|
temp = win->language;
|
|
width += GetStringWidth(win, GetExpandedPlaceholder(s[i]));
|
|
win->language = temp;
|
|
i++;
|
|
break;
|
|
}
|
|
case EXT_CTRL_CODE_BEGIN:
|
|
i++;
|
|
switch (s[i])
|
|
{
|
|
case 6:
|
|
win->fontNum = s[i + 1];
|
|
break;
|
|
case 7:
|
|
win->fontNum = win->template->fontNum;
|
|
break;
|
|
case 0x11:
|
|
width += s[i + 1];
|
|
break;
|
|
case 0x12:
|
|
case 0x13:
|
|
if (width < s[i + 1])
|
|
width = s[i + 1];
|
|
break;
|
|
case 0x14:
|
|
win->spacing = s[i + 1];
|
|
break;
|
|
case 0x15:
|
|
win->language = LANGUAGE_JAPANESE;
|
|
break;
|
|
case 0x16:
|
|
win->language = GAME_LANGUAGE;
|
|
break;
|
|
}
|
|
|
|
i += GetExtCtrlCodeLength(s[i]);
|
|
break;
|
|
default:
|
|
i++;
|
|
width += GetGlyphWidth(win, c);
|
|
}
|
|
}
|
|
|
|
win->spacing = savedSpacing;
|
|
win->language = savedLanguage;
|
|
win->fontNum = savedFontNum;
|
|
|
|
return width;
|
|
}
|
|
|
|
u8 Text_InitWindow8004D04(struct Window *win, const u8 *text, u16 tileDataStartOffset, u8 left, u16 top, u32 a6)
|
|
{
|
|
Text_InitWindow8002E4C(win, text, tileDataStartOffset, left, top, a6);
|
|
return Text_PrintWindow8002F44(win);
|
|
}
|
|
|
|
u8 Text_InitWindow_RightAligned(struct Window *win, const u8 *text, u16 tileDataStartOffset, u8 right, u8 top)
|
|
{
|
|
u8 width = GetStringWidth(win, text);
|
|
Text_InitWindow(win, text, tileDataStartOffset, right - ((u32)(width + 7) >> 3), top);
|
|
EraseAtCursor(win);
|
|
width &= 7;
|
|
if (width)
|
|
width = 8 - width;
|
|
Window_MoveCursor(win, width, 0);
|
|
return Text_PrintWindow8002F44(win);
|
|
}
|
|
|
|
u8 Text_InitWindow_Centered(struct Window *win, const u8 *text, u16 tileDataStartOffset, u8 left, u8 top, u16 width)
|
|
{
|
|
width = (u8)(width / 2 - GetStringWidth(win, text) / 2);
|
|
left += (u8)width / 8;
|
|
Text_InitWindow(win, text, tileDataStartOffset, left, top);
|
|
EraseAtCursor(win);
|
|
width &= 7;
|
|
Window_MoveCursor(win, width, 0);
|
|
return Text_PrintWindow8002F44(win);
|
|
}
|
|
|
|
u8 Text_GetWindowPaletteNum(struct Window *win)
|
|
{
|
|
return win->paletteNum;
|
|
}
|
|
|
|
void Text_GetTextColors(struct Window *win, u8 *foreground, u8 *background, u8 *shadow)
|
|
{
|
|
*foreground = win->foregroundColor;
|
|
*background = win->backgroundColor;
|
|
*shadow = win->shadowColor;
|
|
}
|
|
|
|
void Text_InitWindow8004E3C(const struct WindowTemplate *winTemplate, u8 *tileData, const u8 *text)
|
|
{
|
|
sTempWindow.template = winTemplate;
|
|
Text_InitWindow(&sTempWindow, text, 0, 0, 0);
|
|
sTempWindow.tileData = tileData;
|
|
Text_PrintWindow8002F44(&sTempWindow);
|
|
}
|
|
|
|
u8 Text_GetStringWidthFromWindowTemplate(const struct WindowTemplate *winTemplate, const u8 *s)
|
|
{
|
|
sTempWindow.template = winTemplate;
|
|
Text_InitWindow(&sTempWindow, s, 0, 0, 0);
|
|
return GetStringWidth(&sTempWindow, s);
|
|
}
|
|
|
|
void ConvertInternationalString(u8 *s, u8 language)
|
|
{
|
|
if (language == LANGUAGE_JAPANESE)
|
|
{
|
|
u8 i;
|
|
|
|
Text_StripExtCtrlCodes(s);
|
|
i = StringLength(s);
|
|
s[i++] = EXT_CTRL_CODE_BEGIN;
|
|
s[i++] = 22;
|
|
s[i++] = EOS;
|
|
|
|
i--;
|
|
|
|
while (i != (u8)-1)
|
|
{
|
|
s[i + 2] = s[i];
|
|
i--;
|
|
}
|
|
|
|
s[0] = EXT_CTRL_CODE_BEGIN;
|
|
s[1] = 21;
|
|
}
|
|
}
|
|
|
|
void Text_StripExtCtrlCodes(u8 *str)
|
|
{
|
|
u16 srcIndex = 0;
|
|
u16 destIndex = 0;
|
|
while (str[srcIndex] != EOS)
|
|
{
|
|
if (str[srcIndex] == EXT_CTRL_CODE_BEGIN)
|
|
{
|
|
srcIndex++;
|
|
srcIndex += GetExtCtrlCodeLength(str[srcIndex]);
|
|
}
|
|
else
|
|
{
|
|
str[destIndex++] = str[srcIndex++];
|
|
}
|
|
}
|
|
str[destIndex] = EOS;
|
|
}
|
|
|
|
static const u8 *SkipExtCtrlCode(const u8 *s)
|
|
{
|
|
while (*s == EXT_CTRL_CODE_BEGIN)
|
|
{
|
|
s++;
|
|
s += GetExtCtrlCodeLength(*s);
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
s32 StringCompareWithoutExtCtrlCodes(const u8 *str1, const u8 *str2)
|
|
{
|
|
s32 retVal = 0;
|
|
|
|
while (1)
|
|
{
|
|
str1 = SkipExtCtrlCode(str1);
|
|
str2 = SkipExtCtrlCode(str2);
|
|
|
|
if (*str1 > *str2)
|
|
break;
|
|
|
|
if (*str1 < *str2)
|
|
{
|
|
retVal = -1;
|
|
if (*str2 == 0xFF)
|
|
retVal = 1;
|
|
}
|
|
|
|
if (*str1 == 0xFF)
|
|
return retVal;
|
|
|
|
str1++;
|
|
str2++;
|
|
}
|
|
|
|
retVal = 1;
|
|
|
|
if (*str1 == 0xFF)
|
|
retVal = -1;
|
|
|
|
return retVal;
|
|
}
|
|
|
|
u8 sub_8004FD0(struct Window *win, u8 *dest, const u8 *src, u16 tileDataStartOffset, u8 left, u16 top, u8 width, u32 a8)
|
|
{
|
|
u8 newlineCount = 0;
|
|
u8 extCtrlCodeLength;
|
|
u8 *start;
|
|
u32 endsWithoutNewline;
|
|
|
|
if (dest == NULL)
|
|
dest = gStringVar4;
|
|
|
|
start = dest;
|
|
endsWithoutNewline = FALSE;
|
|
|
|
while (*src != 0xFF)
|
|
{
|
|
switch (*src)
|
|
{
|
|
default:
|
|
*dest = *src;
|
|
dest++;
|
|
src++;
|
|
endsWithoutNewline = TRUE;
|
|
break;
|
|
case 0xFC:
|
|
extCtrlCodeLength = GetExtCtrlCodeLength(src[1]) + 1;
|
|
memcpy(dest, src, extCtrlCodeLength);
|
|
dest += extCtrlCodeLength;
|
|
src += extCtrlCodeLength;
|
|
break;
|
|
case 0xFE:
|
|
dest[0] = 0xFC;
|
|
dest[1] = 19;
|
|
dest[2] = width;
|
|
dest[3] = 0xFE;
|
|
dest += 4;
|
|
src++;
|
|
newlineCount++;
|
|
endsWithoutNewline = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
dest[0] = 0xFC;
|
|
dest[1] = 19;
|
|
dest[2] = width;
|
|
dest[3] = 0xFF;
|
|
|
|
if (endsWithoutNewline)
|
|
newlineCount++;
|
|
|
|
Text_InitWindow8002E4C(win, start, tileDataStartOffset, left, top, a8);
|
|
Text_PrintWindow8002F44(win);
|
|
|
|
return newlineCount;
|
|
}
|
|
|
|
static s32 DrawGlyphTile_UnshadowedFont(struct GlyphTileInfo *glyphTileInfo)
|
|
{
|
|
struct GlyphBuffer *glyphBuffer = &sGlyphBuffer;
|
|
u32 colors[2];
|
|
u32 *buffer = glyphTileInfo->dest;
|
|
const u32 *masks = sGlyphMasks[glyphTileInfo->width][glyphTileInfo->startPixel];
|
|
u32 mask1 = masks[0] | masks[2];
|
|
|
|
glyphBuffer->pixelRows[0] = buffer[0] & mask1;
|
|
glyphBuffer->pixelRows[1] = buffer[1] & mask1;
|
|
glyphBuffer->pixelRows[2] = buffer[2] & mask1;
|
|
glyphBuffer->pixelRows[3] = buffer[3] & mask1;
|
|
glyphBuffer->pixelRows[4] = buffer[4] & mask1;
|
|
glyphBuffer->pixelRows[5] = buffer[5] & mask1;
|
|
glyphBuffer->pixelRows[6] = buffer[6] & mask1;
|
|
glyphBuffer->pixelRows[7] = buffer[7] & mask1;
|
|
|
|
if (glyphTileInfo->startPixel + glyphTileInfo->width > 8)
|
|
{
|
|
u32 mask2 = masks[1];
|
|
if (glyphTileInfo->textMode == TEXT_MODE_UNKNOWN2)
|
|
{
|
|
glyphBuffer->pixelRows[8] = buffer[8] & mask2;
|
|
glyphBuffer->pixelRows[9] = buffer[9] & mask2;
|
|
glyphBuffer->pixelRows[10] = buffer[10] & mask2;
|
|
glyphBuffer->pixelRows[11] = buffer[11] & mask2;
|
|
glyphBuffer->pixelRows[12] = buffer[12] & mask2;
|
|
glyphBuffer->pixelRows[13] = buffer[13] & mask2;
|
|
glyphBuffer->pixelRows[14] = buffer[14] & mask2;
|
|
glyphBuffer->pixelRows[15] = buffer[15] & mask2;
|
|
}
|
|
else
|
|
{
|
|
glyphBuffer->pixelRows[8] = buffer[16] & mask2;
|
|
glyphBuffer->pixelRows[9] = buffer[17] & mask2;
|
|
glyphBuffer->pixelRows[10] = buffer[18] & mask2;
|
|
glyphBuffer->pixelRows[11] = buffer[19] & mask2;
|
|
glyphBuffer->pixelRows[12] = buffer[20] & mask2;
|
|
glyphBuffer->pixelRows[13] = buffer[21] & mask2;
|
|
glyphBuffer->pixelRows[14] = buffer[22] & mask2;
|
|
glyphBuffer->pixelRows[15] = buffer[23] & mask2;
|
|
}
|
|
}
|
|
|
|
colors[0] = glyphTileInfo->colors[0];
|
|
colors[1] = glyphTileInfo->colors[15];
|
|
|
|
sShiftGlyphTileUnshadowedFuncs[glyphTileInfo->width](glyphBuffer, glyphTileInfo->src, colors, glyphTileInfo->startPixel);
|
|
|
|
buffer[0] = glyphBuffer->pixelRows[0];
|
|
buffer[1] = glyphBuffer->pixelRows[1];
|
|
buffer[2] = glyphBuffer->pixelRows[2];
|
|
buffer[3] = glyphBuffer->pixelRows[3];
|
|
buffer[4] = glyphBuffer->pixelRows[4];
|
|
buffer[5] = glyphBuffer->pixelRows[5];
|
|
buffer[6] = glyphBuffer->pixelRows[6];
|
|
buffer[7] = glyphBuffer->pixelRows[7];
|
|
|
|
if (glyphTileInfo->startPixel + glyphTileInfo->width > 8)
|
|
{
|
|
if (glyphTileInfo->textMode != TEXT_MODE_UNKNOWN2)
|
|
buffer += 8;
|
|
buffer[8] = glyphBuffer->pixelRows[8];
|
|
buffer[9] = glyphBuffer->pixelRows[9];
|
|
buffer[10] = glyphBuffer->pixelRows[10];
|
|
buffer[11] = glyphBuffer->pixelRows[11];
|
|
buffer[12] = glyphBuffer->pixelRows[12];
|
|
buffer[13] = glyphBuffer->pixelRows[13];
|
|
buffer[14] = glyphBuffer->pixelRows[14];
|
|
buffer[15] = glyphBuffer->pixelRows[15];
|
|
}
|
|
|
|
return (glyphTileInfo->startPixel + glyphTileInfo->width) / 8;
|
|
}
|
|
|
|
static void ShiftGlyphTile_UnshadowedFont_Width0(struct GlyphBuffer *glyphBuffer, u8 *src, u32 *a3, u8 startPixel)
|
|
{
|
|
}
|
|
|
|
static void ShiftGlyphTile_UnshadowedFont_Width1(struct GlyphBuffer *glyphBuffer, u8 *src, u32 *colors, u8 startPixel)
|
|
{
|
|
const struct ShiftAmount *shiftAmount = &sGlyphShiftAmounts[startPixel];
|
|
u8 i;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
u32 val = colors[src[i] >> 7];
|
|
u32 *dest = &glyphBuffer->pixelRows[i];
|
|
dest[0] |= val << shiftAmount->left;
|
|
dest[8] |= val >> shiftAmount->right;
|
|
}
|
|
}
|
|
|
|
static void ShiftGlyphTile_UnshadowedFont_Width2(struct GlyphBuffer *glyphBuffer, u8 *src, u32 *colors, u8 startPixel)
|
|
{
|
|
const struct ShiftAmount *shiftAmount = &sGlyphShiftAmounts[startPixel];
|
|
u8 i;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
u32 val = (colors[(src[i] >> 7) & 1] << 0)
|
|
| (colors[(src[i] >> 6) & 1] << 4);
|
|
u32 *dest = &glyphBuffer->pixelRows[i];
|
|
dest[0] |= val << shiftAmount->left;
|
|
dest[8] |= val >> shiftAmount->right;
|
|
}
|
|
}
|
|
|
|
static void ShiftGlyphTile_UnshadowedFont_Width3(struct GlyphBuffer *glyphBuffer, u8 *src, u32 *colors, u8 startPixel)
|
|
{
|
|
const struct ShiftAmount *shiftAmount = &sGlyphShiftAmounts[startPixel];
|
|
u8 i;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
// XXX: why 4?
|
|
u32 val = (colors[(src[i] >> 7) & 1] << 0)
|
|
| (colors[(src[i] >> 6) & 1] << 4)
|
|
| (colors[(src[i] >> 5) & 1] << 8)
|
|
| (colors[(src[i] >> 4) & 1] << 12);
|
|
u32 *dest = &glyphBuffer->pixelRows[i];
|
|
dest[0] |= val << shiftAmount->left;
|
|
dest[8] |= val >> shiftAmount->right;
|
|
}
|
|
}
|
|
|
|
static void ShiftGlyphTile_UnshadowedFont_Width4(struct GlyphBuffer *glyphBuffer, u8 *src, u32 *colors, u8 startPixel)
|
|
{
|
|
const struct ShiftAmount *shiftAmount = &sGlyphShiftAmounts[startPixel];
|
|
u8 i;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
u32 val = (colors[(src[i] >> 7) & 1] << 0)
|
|
| (colors[(src[i] >> 6) & 1] << 4)
|
|
| (colors[(src[i] >> 5) & 1] << 8)
|
|
| (colors[(src[i] >> 4) & 1] << 12);
|
|
u32 *dest = &glyphBuffer->pixelRows[i];
|
|
dest[0] |= val << shiftAmount->left;
|
|
dest[8] |= val >> shiftAmount->right;
|
|
}
|
|
}
|
|
|
|
static void ShiftGlyphTile_UnshadowedFont_Width5(struct GlyphBuffer *glyphBuffer, u8 *src, u32 *colors, u8 startPixel)
|
|
{
|
|
const struct ShiftAmount *shiftAmount = &sGlyphShiftAmounts[startPixel];
|
|
u8 i;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
u32 val = (colors[(src[i] >> 7) & 1] << 0)
|
|
| (colors[(src[i] >> 6) & 1] << 4)
|
|
| (colors[(src[i] >> 5) & 1] << 8)
|
|
| (colors[(src[i] >> 4) & 1] << 12)
|
|
| (colors[(src[i] >> 3) & 1] << 16);
|
|
u32 *dest = &glyphBuffer->pixelRows[i];
|
|
dest[0] |= val << shiftAmount->left;
|
|
dest[8] |= val >> shiftAmount->right;
|
|
}
|
|
}
|
|
|
|
static void ShiftGlyphTile_UnshadowedFont_Width6(struct GlyphBuffer *glyphBuffer, u8 *src, u32 *colors, u8 startPixel)
|
|
{
|
|
const struct ShiftAmount *shiftAmount = &sGlyphShiftAmounts[startPixel];
|
|
u8 i;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
u32 val = (colors[(src[i] >> 7) & 1] << 0)
|
|
| (colors[(src[i] >> 6) & 1] << 4)
|
|
| (colors[(src[i] >> 5) & 1] << 8)
|
|
| (colors[(src[i] >> 4) & 1] << 12)
|
|
| (colors[(src[i] >> 3) & 1] << 16)
|
|
| (colors[(src[i] >> 2) & 1] << 20);
|
|
u32 *dest = &glyphBuffer->pixelRows[i];
|
|
dest[0] |= val << shiftAmount->left;
|
|
dest[8] |= val >> shiftAmount->right;
|
|
}
|
|
}
|
|
|
|
static void ShiftGlyphTile_UnshadowedFont_Width7(struct GlyphBuffer *glyphBuffer, u8 *src, u32 *colors, u8 startPixel)
|
|
{
|
|
const struct ShiftAmount *shiftAmount = &sGlyphShiftAmounts[startPixel];
|
|
u8 i;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
u32 val = (colors[(src[i] >> 7) & 1] << 0)
|
|
| (colors[(src[i] >> 6) & 1] << 4)
|
|
| (colors[(src[i] >> 5) & 1] << 8)
|
|
| (colors[(src[i] >> 4) & 1] << 12)
|
|
| (colors[(src[i] >> 3) & 1] << 16)
|
|
| (colors[(src[i] >> 2) & 1] << 20)
|
|
| (colors[(src[i] >> 1) & 1] << 24);
|
|
u32 *dest = &glyphBuffer->pixelRows[i];
|
|
dest[0] |= val << shiftAmount->left;
|
|
dest[8] |= val >> shiftAmount->right;
|
|
}
|
|
}
|
|
|
|
static void ShiftGlyphTile_UnshadowedFont_Width8(struct GlyphBuffer *glyphBuffer, u8 *src, u32 *colors, u8 startPixel)
|
|
{
|
|
const struct ShiftAmount *shiftAmount = &sGlyphShiftAmounts[startPixel];
|
|
u8 i;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
u32 val = (colors[(src[i] >> 7) & 1] << 0)
|
|
| (colors[(src[i] >> 6) & 1] << 4)
|
|
| (colors[(src[i] >> 5) & 1] << 8)
|
|
| (colors[(src[i] >> 4) & 1] << 12)
|
|
| (colors[(src[i] >> 3) & 1] << 16)
|
|
| (colors[(src[i] >> 2) & 1] << 20)
|
|
| (colors[(src[i] >> 1) & 1] << 24)
|
|
| (colors[(src[i] >> 0) & 1] << 28);
|
|
u32 *dest = &glyphBuffer->pixelRows[i];
|
|
dest[0] |= val << shiftAmount->left;
|
|
dest[8] |= val >> shiftAmount->right;
|
|
}
|
|
}
|
|
|
|
static s32 DrawGlyphTile_ShadowedFont(struct GlyphTileInfo *glyphTileInfo)
|
|
{
|
|
struct GlyphBuffer *glyphBuffer = &sGlyphBuffer;
|
|
u32 *buffer = glyphTileInfo->dest;
|
|
const u32 *masks = sGlyphMasks[glyphTileInfo->width][glyphTileInfo->startPixel];
|
|
u32 mask1 = masks[0] | masks[2];
|
|
|
|
glyphBuffer->pixelRows[0] = buffer[0] & mask1;
|
|
glyphBuffer->pixelRows[1] = buffer[1] & mask1;
|
|
glyphBuffer->pixelRows[2] = buffer[2] & mask1;
|
|
glyphBuffer->pixelRows[3] = buffer[3] & mask1;
|
|
glyphBuffer->pixelRows[4] = buffer[4] & mask1;
|
|
glyphBuffer->pixelRows[5] = buffer[5] & mask1;
|
|
glyphBuffer->pixelRows[6] = buffer[6] & mask1;
|
|
glyphBuffer->pixelRows[7] = buffer[7] & mask1;
|
|
|
|
if (glyphTileInfo->startPixel + glyphTileInfo->width > 8)
|
|
{
|
|
u32 mask2 = masks[1];
|
|
if (glyphTileInfo->textMode == TEXT_MODE_UNKNOWN2)
|
|
{
|
|
glyphBuffer->pixelRows[8] = buffer[8] & mask2;
|
|
glyphBuffer->pixelRows[9] = buffer[9] & mask2;
|
|
glyphBuffer->pixelRows[10] = buffer[10] & mask2;
|
|
glyphBuffer->pixelRows[11] = buffer[11] & mask2;
|
|
glyphBuffer->pixelRows[12] = buffer[12] & mask2;
|
|
glyphBuffer->pixelRows[13] = buffer[13] & mask2;
|
|
glyphBuffer->pixelRows[14] = buffer[14] & mask2;
|
|
glyphBuffer->pixelRows[15] = buffer[15] & mask2;
|
|
}
|
|
else
|
|
{
|
|
glyphBuffer->pixelRows[8] = buffer[16] & mask2;
|
|
glyphBuffer->pixelRows[9] = buffer[17] & mask2;
|
|
glyphBuffer->pixelRows[10] = buffer[18] & mask2;
|
|
glyphBuffer->pixelRows[11] = buffer[19] & mask2;
|
|
glyphBuffer->pixelRows[12] = buffer[20] & mask2;
|
|
glyphBuffer->pixelRows[13] = buffer[21] & mask2;
|
|
glyphBuffer->pixelRows[14] = buffer[22] & mask2;
|
|
glyphBuffer->pixelRows[15] = buffer[23] & mask2;
|
|
}
|
|
}
|
|
|
|
sShiftGlyphTileShadowedFuncs[glyphTileInfo->width](glyphBuffer, (u32 *)glyphTileInfo->src, glyphTileInfo->colors, glyphTileInfo->startPixel);
|
|
|
|
buffer[0] = glyphBuffer->pixelRows[0];
|
|
buffer[1] = glyphBuffer->pixelRows[1];
|
|
buffer[2] = glyphBuffer->pixelRows[2];
|
|
buffer[3] = glyphBuffer->pixelRows[3];
|
|
buffer[4] = glyphBuffer->pixelRows[4];
|
|
buffer[5] = glyphBuffer->pixelRows[5];
|
|
buffer[6] = glyphBuffer->pixelRows[6];
|
|
buffer[7] = glyphBuffer->pixelRows[7];
|
|
|
|
if (glyphTileInfo->startPixel + glyphTileInfo->width > 8)
|
|
{
|
|
if (glyphTileInfo->textMode != TEXT_MODE_UNKNOWN2)
|
|
buffer += 8;
|
|
buffer[8] = glyphBuffer->pixelRows[8];
|
|
buffer[9] = glyphBuffer->pixelRows[9];
|
|
buffer[10] = glyphBuffer->pixelRows[10];
|
|
buffer[11] = glyphBuffer->pixelRows[11];
|
|
buffer[12] = glyphBuffer->pixelRows[12];
|
|
buffer[13] = glyphBuffer->pixelRows[13];
|
|
buffer[14] = glyphBuffer->pixelRows[14];
|
|
buffer[15] = glyphBuffer->pixelRows[15];
|
|
}
|
|
|
|
return (glyphTileInfo->startPixel + glyphTileInfo->width) / 8;
|
|
}
|
|
|
|
static void ShiftGlyphTile_ShadowedFont_Width0(struct GlyphBuffer *glyphBuffer, u32 *src, u32 *colors, u8 startPixel)
|
|
{
|
|
}
|
|
|
|
static void ShiftGlyphTile_ShadowedFont_Width1(struct GlyphBuffer *glyphBuffer, u32 *src, u32 *colors, u8 startPixel)
|
|
{
|
|
const struct ShiftAmount *shiftAmount = &sGlyphShiftAmounts[startPixel];
|
|
u8 i;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
u32 val = colors[src[i] & 0xF];
|
|
u32 *dest = &glyphBuffer->pixelRows[i];
|
|
dest[0] |= val << shiftAmount->left;
|
|
dest[8] |= val >> shiftAmount->right;
|
|
}
|
|
}
|
|
|
|
static void ShiftGlyphTile_ShadowedFont_Width2(struct GlyphBuffer *glyphBuffer, u32 *src, u32 *colors, u8 startPixel)
|
|
{
|
|
const struct ShiftAmount *shiftAmount = &sGlyphShiftAmounts[startPixel];
|
|
u8 i;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
u32 val = (colors[(src[i] >> 0) & 0xF] << 0)
|
|
| (colors[(src[i] >> 4) & 0xF] << 4);
|
|
u32 *dest = &glyphBuffer->pixelRows[i];
|
|
dest[0] |= val << shiftAmount->left;
|
|
dest[8] |= val >> shiftAmount->right;
|
|
}
|
|
}
|
|
|
|
static void ShiftGlyphTile_ShadowedFont_Width3(struct GlyphBuffer *glyphBuffer, u32 *src, u32 *colors, u8 startPixel)
|
|
{
|
|
const struct ShiftAmount *shiftAmount = &sGlyphShiftAmounts[startPixel];
|
|
u8 i;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
u32 val = (colors[(src[i] >> 0) & 0xF] << 0)
|
|
| (colors[(src[i] >> 4) & 0xF] << 4)
|
|
| (colors[(src[i] >> 8) & 0xF] << 8);
|
|
u32 *dest = &glyphBuffer->pixelRows[i];
|
|
dest[0] |= val << shiftAmount->left;
|
|
dest[8] |= val >> shiftAmount->right;
|
|
}
|
|
}
|
|
|
|
static void ShiftGlyphTile_ShadowedFont_Width4(struct GlyphBuffer *glyphBuffer, u32 *src, u32 *colors, u8 startPixel)
|
|
{
|
|
const struct ShiftAmount *shiftAmount = &sGlyphShiftAmounts[startPixel];
|
|
u8 i;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
u32 val = (colors[(src[i] >> 0) & 0xF] << 0)
|
|
| (colors[(src[i] >> 4) & 0xF] << 4)
|
|
| (colors[(src[i] >> 8) & 0xF] << 8)
|
|
| (colors[(src[i] >> 12) & 0xF] << 12);
|
|
u32 *dest = &glyphBuffer->pixelRows[i];
|
|
dest[0] |= val << shiftAmount->left;
|
|
dest[8] |= val >> shiftAmount->right;
|
|
}
|
|
}
|
|
|
|
#define SHIFT_GLYPH_WIDTH5_STEP(i) \
|
|
val = (colors[(src[i] >> 0) & 0xF] << 0) \
|
|
| (colors[(src[i] >> 4) & 0xF] << 4) \
|
|
| (colors[(src[i] >> 8) & 0xF] << 8) \
|
|
| (colors[(src[i] >> 12) & 0xF] << 12) \
|
|
| (colors[(src[i] >> 16) & 0xF] << 16); \
|
|
glyphBuffer->pixelRows[i] |= val << shiftAmount->left; \
|
|
glyphBuffer->pixelRows[i + 8] |= val >> shiftAmount->right; \
|
|
|
|
static void ShiftGlyphTile_ShadowedFont_Width5(struct GlyphBuffer *glyphBuffer, u32 *src, u32 *colors, u8 startPixel)
|
|
{
|
|
const struct ShiftAmount *shiftAmount = &sGlyphShiftAmounts[startPixel];
|
|
u32 val;
|
|
SHIFT_GLYPH_WIDTH5_STEP(0)
|
|
SHIFT_GLYPH_WIDTH5_STEP(1)
|
|
SHIFT_GLYPH_WIDTH5_STEP(2)
|
|
SHIFT_GLYPH_WIDTH5_STEP(3)
|
|
SHIFT_GLYPH_WIDTH5_STEP(4)
|
|
SHIFT_GLYPH_WIDTH5_STEP(5)
|
|
SHIFT_GLYPH_WIDTH5_STEP(6)
|
|
SHIFT_GLYPH_WIDTH5_STEP(7)
|
|
}
|
|
|
|
#define SHIFT_GLYPH_WIDTH6_STEP(i) \
|
|
val = (colors[(src[i] >> 0) & 0xF] << 0) \
|
|
| (colors[(src[i] >> 4) & 0xF] << 4) \
|
|
| (colors[(src[i] >> 8) & 0xF] << 8) \
|
|
| (colors[(src[i] >> 12) & 0xF] << 12) \
|
|
| (colors[(src[i] >> 16) & 0xF] << 16) \
|
|
| (colors[(src[i] >> 20) & 0xF] << 20); \
|
|
glyphBuffer->pixelRows[i] |= val << shiftAmount->left; \
|
|
glyphBuffer->pixelRows[i + 8] |= val >> shiftAmount->right; \
|
|
|
|
static void ShiftGlyphTile_ShadowedFont_Width6(struct GlyphBuffer *glyphBuffer, u32 *src, u32 *colors, u8 startPixel)
|
|
{
|
|
const struct ShiftAmount *shiftAmount = &sGlyphShiftAmounts[startPixel];
|
|
u32 val;
|
|
SHIFT_GLYPH_WIDTH6_STEP(0)
|
|
SHIFT_GLYPH_WIDTH6_STEP(1)
|
|
SHIFT_GLYPH_WIDTH6_STEP(2)
|
|
SHIFT_GLYPH_WIDTH6_STEP(3)
|
|
SHIFT_GLYPH_WIDTH6_STEP(4)
|
|
SHIFT_GLYPH_WIDTH6_STEP(5)
|
|
SHIFT_GLYPH_WIDTH6_STEP(6)
|
|
SHIFT_GLYPH_WIDTH6_STEP(7)
|
|
}
|
|
|
|
#define SHIFT_GLYPH_WIDTH7_STEP(i) \
|
|
val = (colors[(src[i] >> 0) & 0xF] << 0) \
|
|
| (colors[(src[i] >> 4) & 0xF] << 4) \
|
|
| (colors[(src[i] >> 8) & 0xF] << 8) \
|
|
| (colors[(src[i] >> 12) & 0xF] << 12) \
|
|
| (colors[(src[i] >> 16) & 0xF] << 16) \
|
|
| (colors[(src[i] >> 20) & 0xF] << 20) \
|
|
| (colors[(src[i] >> 24) & 0xF] << 24); \
|
|
glyphBuffer->pixelRows[i] |= val << shiftAmount->left; \
|
|
glyphBuffer->pixelRows[i + 8] |= val >> shiftAmount->right; \
|
|
|
|
static void ShiftGlyphTile_ShadowedFont_Width7(struct GlyphBuffer *glyphBuffer, u32 *src, u32 *colors, u8 startPixel)
|
|
{
|
|
const struct ShiftAmount *shiftAmount = &sGlyphShiftAmounts[startPixel];
|
|
u32 val;
|
|
SHIFT_GLYPH_WIDTH7_STEP(0)
|
|
SHIFT_GLYPH_WIDTH7_STEP(1)
|
|
SHIFT_GLYPH_WIDTH7_STEP(2)
|
|
SHIFT_GLYPH_WIDTH7_STEP(3)
|
|
SHIFT_GLYPH_WIDTH7_STEP(4)
|
|
SHIFT_GLYPH_WIDTH7_STEP(5)
|
|
SHIFT_GLYPH_WIDTH7_STEP(6)
|
|
SHIFT_GLYPH_WIDTH7_STEP(7)
|
|
}
|
|
|
|
#define SHIFT_GLYPH_WIDTH8_STEP(i) \
|
|
val = (colors[(src[i] >> 0) & 0xF] << 0) \
|
|
| (colors[(src[i] >> 4) & 0xF] << 4) \
|
|
| (colors[(src[i] >> 8) & 0xF] << 8) \
|
|
| (colors[(src[i] >> 12) & 0xF] << 12) \
|
|
| (colors[(src[i] >> 16) & 0xF] << 16) \
|
|
| (colors[(src[i] >> 20) & 0xF] << 20) \
|
|
| (colors[(src[i] >> 24) & 0xF] << 24) \
|
|
| (colors[(src[i] >> 28) ] << 28); \
|
|
glyphBuffer->pixelRows[i] |= val << shiftAmount->left; \
|
|
glyphBuffer->pixelRows[i + 8] |= val >> shiftAmount->right; \
|
|
|
|
static void ShiftGlyphTile_ShadowedFont_Width8(struct GlyphBuffer *glyphBuffer, u32 *src, u32 *colors, u8 startPixel)
|
|
{
|
|
const struct ShiftAmount *shiftAmount = &sGlyphShiftAmounts[startPixel];
|
|
u32 val;
|
|
SHIFT_GLYPH_WIDTH8_STEP(0)
|
|
SHIFT_GLYPH_WIDTH8_STEP(1)
|
|
SHIFT_GLYPH_WIDTH8_STEP(2)
|
|
SHIFT_GLYPH_WIDTH8_STEP(3)
|
|
SHIFT_GLYPH_WIDTH8_STEP(4)
|
|
SHIFT_GLYPH_WIDTH8_STEP(5)
|
|
SHIFT_GLYPH_WIDTH8_STEP(6)
|
|
SHIFT_GLYPH_WIDTH8_STEP(7)
|
|
}
|
|
|
|
static s32 DrawGlyphTiles(struct Window *win, u32 glyph, u32 glyphWidth)
|
|
{
|
|
struct GlyphTileInfo glyphTileInfo;
|
|
u8 *upperTile;
|
|
u8 *lowerTile;
|
|
s32 retVal = 0;
|
|
|
|
GetGlyphTilePointers(win->fontNum, win->language, glyph, &upperTile, &lowerTile);
|
|
glyphTileInfo.textMode = win->textMode;
|
|
glyphTileInfo.startPixel = (win->left + win->cursorX) & 7;
|
|
glyphTileInfo.width = glyphWidth;
|
|
glyphTileInfo.src = upperTile;
|
|
glyphTileInfo.dest = (u32 *)(win->tileData + 32 * GetCursorTileNum(win, 0, 0));
|
|
glyphTileInfo.colors = sGlyphBuffer.colors;
|
|
|
|
switch (win->fontNum)
|
|
{
|
|
case 0:
|
|
case 1:
|
|
case 2:
|
|
case 6:
|
|
DrawGlyphTile_UnshadowedFont(&glyphTileInfo);
|
|
glyphTileInfo.src = lowerTile;
|
|
glyphTileInfo.dest = (u32 *)(win->tileData + 32 * GetCursorTileNum(win, 0, 1));
|
|
retVal = DrawGlyphTile_UnshadowedFont(&glyphTileInfo);
|
|
break;
|
|
case 3:
|
|
case 4:
|
|
case 5:
|
|
DrawGlyphTile_ShadowedFont(&glyphTileInfo);
|
|
glyphTileInfo.src = lowerTile;
|
|
glyphTileInfo.dest = (u32 *)(win->tileData + 32 * GetCursorTileNum(win, 0, 1));
|
|
retVal = DrawGlyphTile_ShadowedFont(&glyphTileInfo);
|
|
break;
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
static void UpdateTilemap(struct Window *win, u32 tilesWidth)
|
|
{
|
|
u16 *tilemap = GetCursorTilemapPointer(win);
|
|
if (tilesWidth && tilemap)
|
|
{
|
|
u16 paletteNum = (win->paletteNum << 12);
|
|
u16 upperLeftTileNum = GetCursorTileNum(win, 0, 0);
|
|
u16 lowerLeftTileNum = GetCursorTileNum(win, 0, 1);
|
|
tilemap[0] = upperLeftTileNum | paletteNum;
|
|
tilemap[32] = lowerLeftTileNum | paletteNum;
|
|
if (tilesWidth == 2)
|
|
{
|
|
u16 upperRightTileNum = GetCursorTileNum(win, 1, 0);
|
|
u16 lowerRightTileNum = GetCursorTileNum(win, 1, 1);
|
|
tilemap[1] = upperRightTileNum | paletteNum;
|
|
tilemap[33] = lowerRightTileNum | paletteNum;
|
|
}
|
|
}
|
|
}
|
|
|
|
static u16 GetCursorTileNum(struct Window *win, u32 xOffset, u32 yOffset)
|
|
{
|
|
u16 index;
|
|
|
|
if (win->textMode == TEXT_MODE_UNKNOWN2)
|
|
index = win->tileDataStartOffset
|
|
+ win->tileDataOffset
|
|
+ (((win->top + win->cursorY) >> 3) + yOffset) * win->width
|
|
+ (((win->left + win->cursorX) >> 3) + xOffset);
|
|
else
|
|
index = win->tileDataStartOffset + win->tileDataOffset + 2 * xOffset + yOffset;
|
|
|
|
return index;
|
|
}
|