202 lines
5.6 KiB
C
202 lines
5.6 KiB
C
#include "global.h"
|
|
#include "main.h"
|
|
#include "menu.h"
|
|
#include "bg.h"
|
|
#include "window.h"
|
|
#include "text.h"
|
|
#include "string_util.h"
|
|
#include "international_string_util.h"
|
|
#include "script_menu.h"
|
|
#include "field_message_box.h"
|
|
#include "graphics.h"
|
|
#include "script.h"
|
|
#include "field_name_box.h"
|
|
#include "event_data.h"
|
|
#include "match_call.h"
|
|
#include "malloc.h"
|
|
#include "constants/speaker_names.h"
|
|
#include "data/speaker_names.h"
|
|
|
|
static EWRAM_INIT u8 sNameboxWindowId = WINDOW_NONE;
|
|
EWRAM_DATA const u8 *gSpeakerName = NULL;
|
|
|
|
static const u32 sNameBoxDefaultGfx[] = INCBIN_U32("graphics/text_window/name_box.4bpp");
|
|
static const u32 sNameBoxPokenavGfx[] = INCBIN_U32("graphics/pokenav/name_box.4bpp");
|
|
|
|
static void WindowFunc_DrawNamebox(u32, u32, u32, u32, u32, u32, u32);
|
|
static void WindowFunc_ClearNamebox(u8, u8, u8, u8, u8, u8);
|
|
|
|
void TrySpawnNamebox(u32 tileNum)
|
|
{
|
|
u8 *strbuf = AllocZeroed(32 * sizeof(u8));
|
|
if ((OW_FLAG_SUPPRESS_NAME_BOX != 0 && FlagGet(OW_FLAG_SUPPRESS_NAME_BOX)) || gSpeakerName == NULL || !strbuf)
|
|
{
|
|
// Re-check again in case anything but !strbuf is TRUE.
|
|
if (strbuf)
|
|
Free(strbuf);
|
|
|
|
DestroyNamebox();
|
|
return;
|
|
}
|
|
|
|
StringExpandPlaceholders(strbuf, gSpeakerName);
|
|
|
|
u32 fontId = FONT_SMALL;
|
|
u32 winWidth = OW_NAME_BOX_DEFAULT_WIDTH;
|
|
|
|
if (OW_NAME_BOX_USE_DYNAMIC_WIDTH)
|
|
{
|
|
winWidth = ConvertPixelWidthToTileWidth(GetStringWidth(fontId, strbuf, -1));
|
|
if (winWidth > OW_NAME_BOX_DEFAULT_WIDTH)
|
|
winWidth = OW_NAME_BOX_DEFAULT_WIDTH;
|
|
}
|
|
|
|
if (sNameboxWindowId != WINDOW_NONE)
|
|
{
|
|
DestroyNamebox();
|
|
RedrawDialogueFrame();
|
|
}
|
|
|
|
bool32 matchCall = IsMatchCallTaskActive();
|
|
|
|
struct WindowTemplate template =
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 2,
|
|
.tilemapTop = 13,
|
|
.width = winWidth,
|
|
.height = OW_NAME_BOX_DEFAULT_HEIGHT,
|
|
.paletteNum = matchCall ? 14 : DLG_WINDOW_PALETTE_NUM,
|
|
.baseBlock = tileNum,
|
|
};
|
|
|
|
sNameboxWindowId = AddWindow(&template);
|
|
FillNamebox();
|
|
|
|
u8 colors[3] = {TEXT_COLOR_TRANSPARENT, OW_NAME_BOX_FOREGROUND_COLOR, OW_NAME_BOX_SHADOW_COLOR};
|
|
u8 bakColors[3];
|
|
int strX = GetStringCenterAlignXOffset(fontId, strbuf, (winWidth * 8));
|
|
if (matchCall)
|
|
{
|
|
colors[1] = 1;
|
|
colors[2] = 0;
|
|
}
|
|
|
|
SaveTextColors(&bakColors[0], &bakColors[1], &bakColors[2]);
|
|
AddTextPrinterParameterized3(sNameboxWindowId, fontId, strX, 0, colors, 0, strbuf);
|
|
RestoreTextColors(&bakColors[0], &bakColors[1], &bakColors[2]);
|
|
PutWindowTilemap(sNameboxWindowId);
|
|
Free(strbuf);
|
|
}
|
|
|
|
u32 GetNameboxWindowId(void)
|
|
{
|
|
return sNameboxWindowId;
|
|
}
|
|
|
|
void ResetNameboxData(void)
|
|
{
|
|
sNameboxWindowId = WINDOW_NONE;
|
|
gSpeakerName = NULL;
|
|
}
|
|
|
|
void DestroyNamebox(void)
|
|
{
|
|
if (sNameboxWindowId == WINDOW_NONE)
|
|
return;
|
|
|
|
ClearNamebox(sNameboxWindowId, TRUE);
|
|
ClearWindowTilemap(sNameboxWindowId);
|
|
RemoveWindow(sNameboxWindowId);
|
|
sNameboxWindowId = WINDOW_NONE;
|
|
gSpeakerName = NULL;
|
|
}
|
|
|
|
u32 GetNameboxWidth(void)
|
|
{
|
|
return gWindows[sNameboxWindowId].window.width;
|
|
}
|
|
|
|
static const u32 *GetNameboxGraphics(void)
|
|
{
|
|
if (IsMatchCallTaskActive())
|
|
return sNameBoxPokenavGfx;
|
|
else
|
|
return sNameBoxDefaultGfx;
|
|
}
|
|
|
|
void FillNamebox(void)
|
|
{
|
|
u32 winSize = GetNameboxWidth();
|
|
const u32 *gfx = GetNameboxGraphics();
|
|
|
|
for (u32 i = 0; i < winSize; i++)
|
|
{
|
|
#define TILE(x) (8 * x)
|
|
CopyToWindowPixelBuffer(sNameboxWindowId, &gfx[TILE(1)], TILE_SIZE_4BPP, i);
|
|
CopyToWindowPixelBuffer(sNameboxWindowId, &gfx[TILE(4)], TILE_SIZE_4BPP, i + winSize);
|
|
#undef TILE
|
|
}
|
|
}
|
|
|
|
void DrawNamebox(u32 windowId, u32 tileNum, bool32 copyToVram)
|
|
{
|
|
// manual instead of using CallWindowFunction for extra tileNum param
|
|
struct WindowTemplate *w = &gWindows[windowId].window;
|
|
u32 size = TILE_OFFSET_4BPP(NAME_BOX_BASE_TILES_TOTAL);
|
|
|
|
LoadBgTiles(GetWindowAttribute(sNameboxWindowId, WINDOW_BG), GetNameboxGraphics(), size, tileNum);
|
|
WindowFunc_DrawNamebox(w->bg, w->tilemapLeft, w->tilemapTop, w->width, w->height, w->paletteNum, tileNum);
|
|
PutWindowTilemap(windowId);
|
|
if (copyToVram == TRUE)
|
|
CopyWindowToVram(windowId, COPYWIN_FULL);
|
|
}
|
|
|
|
void ClearNamebox(u32 windowId, bool32 copyToVram)
|
|
{
|
|
CallWindowFunction(windowId, WindowFunc_ClearNamebox);
|
|
ClearWindowTilemap(windowId);
|
|
if (copyToVram == TRUE)
|
|
CopyWindowToVram(windowId, COPYWIN_FULL);
|
|
}
|
|
|
|
static void WindowFunc_DrawNamebox(u32 bg, u32 L, u32 T, u32 w, u32 h, u32 p, u32 tileNum)
|
|
{
|
|
// left-most
|
|
FillBgTilemapBufferRect(bg, tileNum, L - 1, T, 1, 1, p);
|
|
FillBgTilemapBufferRect(bg, tileNum + 3, L - 1, T + 1, 1, 1, p);
|
|
|
|
// right-most
|
|
FillBgTilemapBufferRect(bg, tileNum + 2, L + w, T, 1, 1, p);
|
|
FillBgTilemapBufferRect(bg, tileNum + 5, L + w, T + 1, 1, 1, p);
|
|
}
|
|
|
|
static void WindowFunc_ClearNamebox(u8 bg, u8 L, u8 T, u8 w, u8 h, u8 p)
|
|
{
|
|
FillBgTilemapBufferRect(bg, 0, L - 1, T, w + 2, h, 0); // palette doesn't matter
|
|
}
|
|
|
|
void SetSpeaker(struct ScriptContext *ctx)
|
|
{
|
|
u32 arg = ScriptReadWord(ctx);
|
|
const u8 *speaker = NULL;
|
|
|
|
if (arg < SP_NAME_COUNT)
|
|
speaker = gSpeakerNamesTable[arg];
|
|
else if (arg >= ROM_START && arg < ROM_END)
|
|
speaker = (const u8 *)arg;
|
|
|
|
gSpeakerName = speaker;
|
|
}
|
|
|
|
// useful for other context e.g. match call
|
|
void TrySpawnAndShowNamebox(const u8 *speaker, u32 tileNum)
|
|
{
|
|
gSpeakerName = speaker;
|
|
TrySpawnNamebox(tileNum);
|
|
if (sNameboxWindowId != WINDOW_NONE)
|
|
DrawNamebox(sNameboxWindowId, tileNum - NAME_BOX_BASE_TILES_TOTAL, TRUE);
|
|
else // either NULL or SP_NAME_NONE
|
|
RedrawDialogueFrame();
|
|
}
|