[GBA教程]黑幕文字的实现

[GBA教程]黑幕文字的实现

在src\scrcmd.c文件末尾添加ScrCmd_blacktext和ScrCmd_closeblacktext函数。

bool8 ScrCmd_blacktext(struct ScriptContext *ctx)
{
    u8 x = ScriptReadByte(ctx);
    u8 y = ScriptReadByte(ctx);
    const u8 *msg = (const u8 *)ScriptReadWord(ctx);
    
    FlagSet(FLAG_SHOW_BLACK_TEXT);
    ChangeBgX(0, x << 8, BG_COORD_SET);
    ChangeBgY(0, y << 8, BG_COORD_SET);
    ShowFieldMessage(msg);
    return FALSE;
}

bool8 ScrCmd_closeblacktext(struct ScriptContext *ctx)
{
    LoadMessageBoxAndBorderGfx();
    ChangeBgX(0, 0, BG_COORD_SET);
    ChangeBgY(0, 0, BG_COORD_SET);
    FlagClear(FLAG_SHOW_BLACK_TEXT);
    return FALSE;
}

修改src\field_message_box.c,添加对FLAG_SHOW_BLACK_TEXT标志的处理逻辑。

头部添加引用

#include "event_data.h"
#include "palette.h"
#include "bg.h"
#include "gpu_regs.h"
#include "constants/rgb.h"

添加白色消息框调色板并修改Task_DrawFieldMessage函数来处理FLAG_SHOW_BLACK_TEXT标志。

static const u16 gWhiteMsgBoxPalette[] =
{
    RGB_BLACK,
    RGB_BLACK,
    RGB(26, 26, 25),
    RGB(12, 12, 12),
    RGB(28, 01, 01),
    RGB_BLACK,
    RGB_BLACK,
    RGB_BLACK,
    RGB_BLACK,
    RGB_BLACK,
    RGB_BLACK,
    RGB_BLACK,
    RGB_BLACK,
    RGB_BLACK,
    RGB_BLACK,
    RGB_BLACK,
};


static const u16 gTransMsgBoxPalette[] =
{
    RGB_BLACK,
    RGB(31,  31, 31),
    RGB(111 / 8,  134 / 8, 146 / 8),
};

static void DrawDialogueFrameNoBoard(u8 windowId, bool8 copyToVram)
{
    LoadPalette(gTransMsgBoxPalette, BG_PLTT_ID(15) + 1, 2 * 3);

    SetGpuRegBits(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_EFFECT_DARKEN);
    SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON);
    ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_WIN1_ON);

    SetGpuReg(REG_OFFSET_BLDY, 5);
    SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_ALL);
    SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WINOBJ_ALL);

    FillWindowPixelBuffer(windowId, PIXEL_FILL(0));
    PutWindowTilemap(windowId);
    if (copyToVram == TRUE)
        CopyWindowToVram(windowId, COPYWIN_FULL);
}

在scrcmd.c文件中添加bg.h头文件的包含

#include "bg.h"

修改Task_DrawFieldMessage函数,使其能够处理FLAG_SHOW_BLACK_TEXT标志。

static void Task_DrawFieldMessage(u8 taskId)
{
    struct Task *task = &gTasks[taskId];

    switch (task->tState)
    {
        case 0:
            if (gMsgIsSignPost)
                LoadSignPostWindowFrameGfx();
            else
                LoadMessageBoxAndBorderGfx();
            task->tState++;
            break;
        case 1:
//新增代码
            if (FlagGet(FLAG_SHOW_BLACK_TEXT))
            {
                LoadPalette(gWhiteMsgBoxPalette, BG_PLTT_ID(15), sizeof(gWhiteMsgBoxPalette));
                DrawDialogueFrameNoBoard(0, TRUE);
            }
            else
            {
                DrawDialogueFrame(0, TRUE);
            }
//新增代码
            task->tState++;
            break;
        case 2:
            UpdateDialoguePortraits();   
            if (RunTextPrintersAndIsPrinter0Active() != TRUE)
            {
                sFieldMessageBoxMode = FIELD_MESSAGE_BOX_HIDDEN;
                DestroyTask(taskId);
            }
    }
}

修改HideFieldMessageBox函数,以确保在消息框隐藏时恢复正常的显示设置。

void HideFieldMessageBox(void)
{
    DestroyTask_DrawFieldMessage();
    ClearDialogWindowAndFrame(0, TRUE);
    CleanupDialoguePortraitSystem();  
    //新增代码
    // 恢复正常的显示设置
    ClearGpuRegBits(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_EFFECT_DARKEN);
    ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON);
    SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_WIN1_ON);
    //新增代码
    sFieldMessageBoxMode = FIELD_MESSAGE_BOX_HIDDEN;
}

在项目中定义 FLAG_SHOW_BLACK_TEXT 标志(include\constants\flags.h)

找一个没用过的flag

#define FLAG_SHOW_BLACK_TEXT    0x4E // 已用 Flag

 

在script_cmd_table.inc文件中添加blacktext和closeblacktext命令的条目,以便脚本汇编器能够识别这些命令。

script_cmd_table_entry SCR_OP_BLACKTEXT                     ScrCmd_blacktext,                   requests_effects=1  @ 0xe6
	script_cmd_table_entry SCR_OP_CLOSEBLACKTEXT                ScrCmd_closeblacktext,              requests_effects=1  @ 0xe7

在event.inc文件的末尾添加blacktext和closeblacktext命令的宏定义,以便脚本汇编器能够正确识别和处理这些命令。

// Black text macro
.macro blacktext x:req, y:req, text:req
    .byte SCR_OP_BLACKTEXT
    .byte \x
    .byte \y
    .4byte \text
    waitmessage
    waitbuttonpress
    closemessage
    delay 16
.endm

// Close black text macro
.macro closeblacktext
    .byte SCR_OP_CLOSEBLACKTEXT
.endm

 

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容