K1Guitar/UI/UI_SongMode.c

555 lines
21 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "includes.h"
extern uint8_t CurrentMode;
static uint8_t transpose[5] = {0xF0, 0x51, 0x05, 0x0A, 0xF7};
static uint8_t Speed[6] = {0xF0, 0x51, 0x03, 0x00, 0x00, 0xF7};
void Draw_Tab_Mode_Menu(const LEBEL_UI *UI, GUI_SWITCH *Group)
{
/* 0819:TAB 字号 11;0902:紧凑圆角条,选中常亮蓝,文字垂直居中 */
const uint16_t tab_w = UI0902_TAB_W;
const uint16_t tab_h = UI0902_TAB_H;
const uint8_t tab_r = UI0902_RADIUS_TAB;
const uint8_t tab_font = UI0902_FONT_LABEL;
const uint16_t start_x = UI0902_MARGIN_X;
const uint16_t start_y = UI->y;
const uint16_t gap = UI0902_TAB_GAP;
const uint16_t text_y = start_y + (tab_h - tab_font) / 2;
const uint16_t inset = 3;
uint16_t color_sel_bg = COLOR_GRAD_MID;
uint16_t color_unsel_bg = UI0902_ROW_BG;
uint16_t color_text = UI->Text_fc;
uint16_t x1 = start_x;
uint16_t x2 = start_x + tab_w + gap;
if(Group->Current == 1)
{
LCD_FillRoundRect(x1, start_y, tab_w, tab_h, tab_r, color_unsel_bg);
LCD_FillRoundRect(x2, start_y, tab_w, tab_h, tab_r, color_sel_bg);
LCD_ShowChinese_AutoAlign(
x1 + inset, x1 + tab_w - inset, text_y,
(const uint8_t*)"\xBD\xDA\xD7\xE0\xC0\xE0\xD0\xCD",
LCD_ALIGN_CENTER, color_text, color_unsel_bg, 0, tab_font);
LCD_ShowChinese_AutoAlign(
x2 + inset, x2 + tab_w - inset, text_y,
(const uint8_t *)"\xB1\xBE\xB5\xD8\xC7\xFA\xC4\xBF",
LCD_ALIGN_CENTER, color_text, color_sel_bg, 0, tab_font);
}
else
{
LCD_FillRoundRect(x1, start_y, tab_w, tab_h, tab_r, color_sel_bg);
LCD_FillRoundRect(x2, start_y, tab_w, tab_h, tab_r, color_unsel_bg);
LCD_ShowChinese_AutoAlign(
x1 + inset, x1 + tab_w - inset, text_y,
(const uint8_t*)"\xBD\xDA\xD7\xE0\xC0\xE0\xD0\xCD",
LCD_ALIGN_CENTER, color_text, color_sel_bg, 0, tab_font);
LCD_ShowChinese_AutoAlign(
x2 + inset, x2 + tab_w - inset, text_y,
(const uint8_t *)"\xB1\xBE\xB5\xD8\xC7\xFA\xC4\xBF",
LCD_ALIGN_CENTER, color_text, color_unsel_bg, 0, tab_font);
}
}
void Show_home_UI(void)
{
UI_ClearFocus();
LCD_FillByColor(0,0,240,320,UI0902_BG_COLOR);
label_top();
label_Tranzpose_ui(&UI_Label[GUI_TRANSPOSE], &mGuiData[GUI_TRANSPOSE]);
label_Speed_ui(&UI_Label[GUI_SPEED], &mGuiData[GUI_SPEED]);
label_ModeSelece_ui(&UI_Label[GUI_MODE_PARAM],&mGuiData[GUI_MODE_PARAM]);
label_TimbreSelece_ui(&UI_Label[GUI_TIMBRE_SELECT], &mGuiData[GUI_TIMBRE_SELECT]);
label_PlaySection_ui(&UI_Label[GUI_PLAY_SECTION], &mGuiData[GUI_PLAY_SECTION]);
label_Tab_Select_ui(&UI_Label[GUI_PLAY_SECTION], &mGuiData[GUI_TAB_INDEX]);
//LCD_WR_REG(0x29); // Display ON:恢复扫描,整页<E695B4>?间呈<E997B4>?
//LCD_BLK_Set();
}
/* 三模式主页互切:只重绘变化区,避免整屏清导致闪烁 */
void Show_home_UI_Diff(void)
{
const LEBEL_UI *mode = &UI_Label[GUI_MODE_PARAM];
UI_ClearFocus();
/* 清 TAB/标题条,避免万能↔普通/专业互切留下残影 */
LCD_FillByColor(mode->x, mode->y,
(uint16_t)(mode->x + mode->w),
(uint16_t)(mode->y + UI0902_TAB_H + 4),
UI0902_BG_COLOR);
label_ModeSelece_ui(mode, &mGuiData[GUI_MODE_PARAM]);
label_Tab_Select_ui(&UI_Label[GUI_PLAY_SECTION], &mGuiData[GUI_TAB_INDEX]);
}
int8_t delta = 0;
void Touch_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex,uint8_t value)
{
uint8_t last_value;
NvmParam_Type * nvm = drv_nvm_param_ptr();
if(FLAG == 1 || FLAG == -1)
{
switch(ID)
{
case GUI_TRANSPOSE:
{
last_value = mGuiData[ID].Current;
GUI_Item_AjustLoopValue(&mGuiData[ID], FLAG);
if (!UI_SetFocus(GUI_TRANSPOSE))
Refresh_Transpose(&UI_Label[ID], &mGuiData[ID]);
// label_Tranzpose_ui(&UI_Label[GUI_TRANSPOSE], &mGuiData[GUI_TRANSPOSE]);
if(nvm->param.Transpose != mGuiData[ID].Current)
{
nvm->param.Transpose = mGuiData[ID].Current;
}
transpose[3] = mGuiData[ID].Current;
USART4_SendData(transpose,sizeof(transpose));
int8_t new_trans = mGuiData[GUI_TRANSPOSE].Current;
delta = new_trans - last_value;
USE_MIDI.Midi_1 += delta;
USE_MIDI.Midi_2 += delta;
USE_MIDI.Midi_3 += delta;
USE_MIDI.Midi_4 += delta;
USE_MIDI.Midi_5 += delta;
USE_MIDI.Midi_6 += delta;
if(StartFlag)
{
switch(mGuiData[GUI_TAB_INDEX].Current)
{
case 0: /* 万能:和弦走向转调触发 */
{
uint8_t midi = 0x3c;
midi += mGuiData[GUI_TRANSPOSE].Current;
AutoBandTop1_Note_On(midi,0x3c);
}
break;
case 1: /* 专业 */
case 2: /* 普通 */
/* 音师:快转调只换和弦音,伴奏不重头 */
Accomp_UpdatePlayingChord();
break;
}
}
}
break;
case GUI_SPEED:
{
last_value = mGuiData[ID].Current;
GUI_Item_AjustValue(&mGuiData[ID], FLAG);
if (!UI_SetFocus(GUI_SPEED))
Refresh_Transpose(&UI_Label[ID], &mGuiData[ID]);
Speed[3] = mGuiData[ID].Current / 128;
Speed[4] = mGuiData[ID].Current % 128;
USART4_SendData(Speed,sizeof(Speed));
if(nvm->param.BPM != mGuiData[ID].Current)
{
nvm->param.BPM = mGuiData[ID].Current;
}
AutoBandTop1_ChangeBPM(mGuiData[ID].Current); // AutoBand 模块未加入工程
}
break;
case GUI_MODE_PARAM:
{
GUI_SWITCH *pCurData =NULL;
uint8_t tab = (uint8_t)mGuiData[GUI_TAB_INDEX].Current;
if (tab == 0)
pCurData = &ParamGuiData[ALL_MODE_PARAM];
else if (mGuiData[GUI_AUTOBAND_SW].Current)
pCurData = &ParamGuiData[EXPRESS_MODE_PARAM];
else
pCurData = &ParamGuiData[SONG_MODE_PARAM];
last_value = pCurData->Current;
GUI_Item_AjustLoopValue(pCurData, FLAG);
if (!UI_SetFocus(GUI_MODE_PARAM))
show_Param(&UI_Label[GUI_MODE_PARAM], pCurData);
/* 切歌/切走向:先停当前伴奏并静音,避免旧曲尾音残留 */
if (last_value != pCurData->Current)
Stop_AutoBand();
UI_ApplyToneAddress();
int ret = 0;
if (tab == 0)
ret = App_Auto_LoadPresetFromFlash(ParamGuiData[ALL_MODE_PARAM].Current);
else if (mGuiData[GUI_AUTOBAND_SW].Current)
ret = App_Auto_LoadPresetFromFlash(ParamGuiData[EXPRESS_MODE_PARAM].Current);
else
ret = App_Auto_LoadPresetFromFlash(ParamGuiData[SONG_MODE_PARAM].Current);
if (ret != 0)
LOG_E("tone", "load preset failed tab=%d sw=%d ret=%d addr=0x%08X",
tab, mGuiData[GUI_AUTOBAND_SW].Current, ret, (unsigned)ADDRESS);
else
LOG_I("tone", "load preset ok tab=%d sw=%d name=%s addr=0x%08X",
tab, mGuiData[GUI_AUTOBAND_SW].Current,
AutoBandTop1_GetPresetName() ? AutoBandTop1_GetPresetName() : "?",
(unsigned)ADDRESS);
if (tab == 0)
nvm->param.Param3 = ParamGuiData[ALL_MODE_PARAM].Current;
else if (mGuiData[GUI_AUTOBAND_SW].Current)
nvm->param.Param2 = ParamGuiData[EXPRESS_MODE_PARAM].Current;
else
nvm->param.Param1 = ParamGuiData[SONG_MODE_PARAM].Current;
/* 联动 App:本地切换节奏风格后上报(格式同 03 04 读回复;万能 tab 为和弦走向不上报) */
if (tab != 0)
{
uint8_t style_src = (uint8_t)mGuiData[GUI_AUTOBAND_SW].Current;
uint16_t style_id = style_src ? ParamGuiData[EXPRESS_MODE_PARAM].Current
: ParamGuiData[SONG_MODE_PARAM].Current;
uint8_t StyleNotify[9] = {0xF0,0x60,0x03,0x04,0x00,0x00,0x00,0x00,0xF7};
StyleNotify[5] = style_src;
StyleNotify[6] = (uint8_t)(style_id / 128);
StyleNotify[7] = (uint8_t)(style_id % 128);
USART4_SendData(StyleNotify,sizeof(StyleNotify));
}
}
break;
case GUI_TIMBRE_SELECT:
last_value = mGuiData[ID].Current;
GUI_Item_AjustLoopValue(&mGuiData[ID], FLAG);
UI_SetFocus(GUI_TIMBRE_SELECT);
Refresh_StringTimbre(last_value, &UI_Label[ID], &mGuiData[ID]);
uint8_t ReturnTimbre[8] = {0xF0,0x60,0x03,0x05,0x00,0x00,0x00,0xF7};
ReturnTimbre[6] = mGuiData[GUI_TIMBRE_SELECT].Current;
USART4_SendData(ReturnTimbre,sizeof(ReturnTimbre));
if(nvm->param.Timbre != mGuiData[ID].Current)
{
nvm->param.Timbre = mGuiData[ID].Current;
}
break;
}
}
if(ID == GUI_AUTOBAND_SW)
{
/* 万能无节奏/本地 TAB,忽略该触控 */
if (mGuiData[GUI_TAB_INDEX].Current == 0)
return;
if (mGuiData[ID].Current == value)
return;
mGuiData[ID].Current = value;
StartFlag = 0;
AutoBandTop1_Stop();
UI_ReloadTonePreset();
if (!UI_SetFocus(GUI_MODE_PARAM))
label_ModeSelece_ui(&UI_Label[GUI_MODE_PARAM],&mGuiData[GUI_MODE_PARAM]);
/* 联动 App:节奏类型/本地曲目切换后上报当前风格 */
{
uint16_t style_id = value ? ParamGuiData[EXPRESS_MODE_PARAM].Current
: ParamGuiData[SONG_MODE_PARAM].Current;
uint8_t StyleNotify[9] = {0xF0,0x60,0x03,0x04,0x00,0x00,0x00,0x00,0xF7};
StyleNotify[5] = (uint8_t)value;
StyleNotify[6] = (uint8_t)(style_id / 128);
StyleNotify[7] = (uint8_t)(style_id % 128);
USART4_SendData(StyleNotify,sizeof(StyleNotify));
}
return;
}
else if(ID==GUI_PLAY_SECTION)
{
/* 万能模式第4键:改为尾奏播放(与独立尾奏键同路径),不走 main4 */
if (mGuiData[GUI_TAB_INDEX].Current == 0 && value == 3)
{
last_value = mGuiData[ID].Current;
mGuiData[ID].Current = value;
AutoBand_StartOutro();
if (!UI_SetFocus(GUI_PLAY_SECTION))
Refresh_SectionSelect(last_value, &UI_Label[ID], &mGuiData[ID]);
return;
}
if(mGuiData[ID].Current != value)
{
mGuiData[ID].Current = value;
AutoBandTop1_SetRunVar(mGuiData[ID].Current);
}else
{
/* 触摸起奏前补发主音量,保证实际音量与图标一致 */
MasterVolume_Reapply();
AutoBandTop1_FillinWithIndex(value);
AutoBandTop1_Start();
}
if (!UI_SetFocus(GUI_PLAY_SECTION))
Refresh_SectionSelect(last_value, &UI_Label[ID], &mGuiData[ID]);
return;
}
else if(ID == GUI_NAV_BAR)
{
UI_NavBar_Action(value);
return;
}
else if(ID==GUI_TAB_INDEX)
{
if(mGuiData[ID].Current != value)
{
mGuiData[ID].Current = value;
app_tm1629_all_on(LED_COLOR_G);
switch(mGuiData[ID].Current)
{
case 0: /* 万能 → 3.bin / 本地→2.bin */
if(mGuiData[GUI_TAB_LAST_INDEX].Current == mGuiData[ID].Current)
break;
StartFlag = 0;
KEY_ID_1629 = 0; /* 清专业等残留指板键,拨片按当前调走走向 */
PressFlag = 0;
AutoBandTop1_Stop();
UI_ReloadTonePreset(); /* 切换模式必须换库,避免专业仍播万能数据 */
break;
case 1: /* 专业 → 1.bin / 本地→2.bin */
if(mGuiData[GUI_TAB_LAST_INDEX].Current == mGuiData[ID].Current)
break;
StartFlag = 0;
AutoBandTop1_Stop();
UI_ReloadTonePreset();
break;
case 2: /* 普通 → 1.bin */
if(mGuiData[GUI_TAB_LAST_INDEX].Current == mGuiData[ID].Current)
break;
StartFlag = 0;
AutoBandTop1_Stop();
UI_ReloadTonePreset();
break;
}
Refresh_TabSelect_ui(&UI_Label[ID], &mGuiData[ID]);
}
return;
}
else if(ID==GUI_BL_SW)
{
mGuiData[ID].Current = !mGuiData[ID].Current;
Show_BL_Icon(mGuiData[GUI_BL_SW].Current);
return;
}
}
void UI_SongMode_Init(void)
{
CurrentMode = 0;
//mGuiData[GUI_AUTOBAND_SW].Current = 0;
mGuiData[GUI_TAB_INDEX].Current = 0;
mGuiData[GUI_TAB_LAST_INDEX].Current = mGuiData[GUI_TAB_INDEX].Current;
UI_ReloadTonePreset(); /* TAB=万能 后再加载 3.bin */
/* 已在主页互切用差分;从 Idle/设置进入仍整页 */
if (CurrUIProcress == UI_SongMode_Process)
Show_home_UI_Diff();
else
Show_home_UI();
pCurrentTouch_Area = Touch_Areas;
}
void UI_SongMode_Process(DisplayTaskMessage_Type msg)
{
NvmParam_Type * nvm = drv_nvm_param_ptr();
switch(msg.MessageType)
{
case MSG_ID_TOUCH:
{
uint8_t hit = 0U;
for(uint8_t k=0; k<TOUCH_AREA_NUM; k++)
{
if( msg.HiByte >= pCurrentTouch_Area[k].x_min && msg.HiByte <= pCurrentTouch_Area[k].x_max &&
msg.LoByte >= pCurrentTouch_Area[k].y_min && msg.LoByte <= pCurrentTouch_Area[k].y_max )
{
hit = 1U;
LOG_I("UI", "song hit area=%u id=%u val=%u x=%u y=%u",
(unsigned)k, (unsigned)pCurrentTouch_Area[k].ID,
(unsigned)pCurrentTouch_Area[k].Value,
(unsigned)msg.HiByte, (unsigned)msg.LoByte);
Touch_Action(pCurrentTouch_Area[k].Flag,pCurrentTouch_Area[k].ID,k,pCurrentTouch_Area[k].Value);
ResetAutoPowerCount();
break;
}
}
if (!hit) {
LOG_I("UI", "song miss x=%u y=%u",
(unsigned)msg.HiByte, (unsigned)msg.LoByte);
}
}
break;
case MSG_ID_BATTERY_VALUE:
Draw_Status_Battery_Icon(percentage);
break;
case MSG_ID_EC_VOL:
/* 主音量已在 MainTask 下发;此处只刷新条 */
Draw_Volume_Bar(UI0902_VOL_X, UI0902_VOL_Y, msg.HiByte, 1, WHITE, GRAY);
break;
case MSG_ID_TAP_SPEED:
//last_value = mGuiData[GUI_SPEED].Current;
mGuiData[GUI_SPEED].Current = msg.ID;
if (!UI_SetFocus(GUI_SPEED))
Refresh_Transpose(&UI_Label[GUI_SPEED], &mGuiData[GUI_SPEED]);
AutoBandTop1_ChangeBPM(mGuiData[GUI_SPEED].Current);
if(nvm->param.BPM != mGuiData[GUI_SPEED].Current)
{
nvm->param.BPM = mGuiData[GUI_SPEED].Current;
}
Speed[3] = mGuiData[GUI_SPEED].Current / 128;
Speed[4] = mGuiData[GUI_SPEED].Current % 128;
USART4_SendData(Speed,sizeof(Speed));
//
// ResetAutoPowerCount();
break;
case MSG_ID_TOUCH_LONG_REPEAT:
{
/* 长按顶栏(y<28)返回三键模式选择页 */
if (msg.LoByte < 28)
{
UI_ReturnToModeSelect();
break;
}
for(uint8_t k=0; k<TOUCH_AREA_NUM; k++)
{
if( msg.HiByte >= pCurrentTouch_Area[k].x_min && msg.HiByte <= pCurrentTouch_Area[k].x_max &&
msg.LoByte >= pCurrentTouch_Area[k].y_min && msg.LoByte <= pCurrentTouch_Area[k].y_max )
{
if(pCurrentTouch_Area[k].ID == GUI_SPEED)
{
int flag = pCurrentTouch_Area[k].Flag;
uint8_t last = mGuiData[GUI_SPEED].Current;
if(flag == 1)
{
if(mGuiData[GUI_SPEED].Current < 260)
{
mGuiData[GUI_SPEED].Current += 10;
if(mGuiData[GUI_SPEED].Current > 260)
mGuiData[GUI_SPEED].Current = 260;
}
else
{
break;
}
}
else if(flag == -1)
{
if(mGuiData[GUI_SPEED].Current > 40)
{
mGuiData[GUI_SPEED].Current -= 10;
if(mGuiData[GUI_SPEED].Current < 40)
mGuiData[GUI_SPEED].Current = 40;
}else
{
break;
}
}
// <20>?有数值真正改变,才执行全套刷新、串口、伴奏更<E5A58F>?
if(last != mGuiData[GUI_SPEED].Current)
{
Refresh_Transpose(&UI_Label[GUI_SPEED], &mGuiData[GUI_SPEED]);
if(nvm->param.BPM != mGuiData[GUI_SPEED].Current)
{
nvm->param.BPM = mGuiData[GUI_SPEED].Current;
}
uint8_t Speed[6] = {0xF0, 0x51, 0x03, 0x00, 0x00, 0xF7};
Speed[3] = mGuiData[GUI_SPEED].Current / 128;
Speed[4] = mGuiData[GUI_SPEED].Current % 128;
USART4_SendData(Speed,sizeof(Speed));
AutoBandTop1_ChangeBPM(mGuiData[GUI_SPEED].Current);
}
// 超时计数无<E695B0>?<3F>变不变都可以重<E4BBA5>?,看你需<E4BDA0>?
//ResetAutoPowerCount();
}
break;
}
}
}
break;
case MSG_ID_BP_TRANSPOSE:
{
uint8_t lastvalue = mGuiData[GUI_TRANSPOSE].Current;
if(mGuiData[GUI_TRANSPOSE].Current != msg.ID)
{
mGuiData[GUI_TRANSPOSE].Current = msg.ID;
if (!UI_SetFocus(GUI_TRANSPOSE))
Refresh_Transpose(&UI_Label[GUI_TRANSPOSE], &mGuiData[GUI_TRANSPOSE]);
}
if(nvm->param.Transpose != mGuiData[GUI_TRANSPOSE].Current)
{
nvm->param.Transpose = mGuiData[GUI_TRANSPOSE].Current;
}
transpose[3] = mGuiData[GUI_TRANSPOSE].Current;
USART4_SendData(transpose,5);
int8_t new_trans = mGuiData[GUI_TRANSPOSE].Current;
delta = new_trans - lastvalue; /* 使用正确<E6ADA3>???? lastvalue */
USE_MIDI.Midi_1 += delta;
USE_MIDI.Midi_2 += delta;
USE_MIDI.Midi_3 += delta;
USE_MIDI.Midi_4 += delta;
USE_MIDI.Midi_5 += delta;
USE_MIDI.Midi_6 += delta;
if(/*KEY_ID_1629 != 0 && */StartFlag && KEY_ID_1629 != 22 && KEY_ID_1629 != 23)
{
/* 音师:快转调只换和弦音,伴奏不重头 */
Accomp_UpdatePlayingChord();
}
ResetAutoPowerCount();
}
break;
case MSG_ID_BLE_UI_REFRESH:
/* BLE 写指令的 LCD 刷新:状态已在 BLE 任务更新,此处仅在 UI 任务上下文绘制。
本消息经 MainTask→UITask 转发到 CurrUIProcress,只在曲目页才会被处理,
其它页面天然忽略,无需页面判断 */
switch (msg.ID)
{
case GUI_TIMBRE_SELECT:
UI_SetFocus(GUI_TIMBRE_SELECT);
Refresh_StringTimbre(0, &UI_Label[GUI_TIMBRE_SELECT], &mGuiData[GUI_TIMBRE_SELECT]);
break;
case GUI_MODE_PARAM:
if (!UI_SetFocus(GUI_MODE_PARAM))
label_ModeSelece_ui(&UI_Label[GUI_MODE_PARAM], &mGuiData[GUI_MODE_PARAM]);
break;
case GUI_SPEED:
Refresh_Transpose(&UI_Label[GUI_SPEED], &mGuiData[GUI_SPEED]);
break;
case GUI_TRANSPOSE:
Refresh_Transpose(&UI_Label[GUI_TRANSPOSE], &mGuiData[GUI_TRANSPOSE]);
break;
default:
break;
}
break;
case MSG_ID_BLE_STYLE_SET:
/* 停伴奏+换库已在 TaskUIThread 全局处理;此处仅刷新节奏风格卡片 */
if (!UI_SetFocus(GUI_MODE_PARAM))
label_ModeSelece_ui(&UI_Label[GUI_MODE_PARAM], &mGuiData[GUI_MODE_PARAM]);
break;
case MSG_ID_CHARG:
Show_Battery_Icon(msg.ID);
break;
}
//drv_nvm_save_to_flash();
}