Compare commits

..

2 Commits

Author SHA1 Message Date
yuquanjun 23c2dee80f Release 0.2.2: package ALL extflash only and bump firmware version.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-07 09:29:01 +08:00
yuquanjun 0a0bd9b3ea Fix system-settings icon dark fill on focus blue rows.
Treat baked #242B3A as transparent when drawing icons, and limit #IV octave drop to keys 10-12.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-07 09:28:35 +08:00
5 changed files with 41 additions and 34 deletions

View File

@ -101,7 +101,7 @@ int16_t MIC_VOL_MAP[11]= {-9000,-7000,-5000,-3000,-1000,1000,3000,5000,7000,9000
uint8_t TOUCH_AREA_NUM = (sizeof(Touch_Areas)/sizeof(Touch_AreaTypeDef)); uint8_t TOUCH_AREA_NUM = (sizeof(Touch_Areas)/sizeof(Touch_AreaTypeDef));
const uint8_t Version[3] = {0,2,1}; /* major.minor.patch — 0.2.1: keep mixer/master vol across power cycle */ const uint8_t Version[3] = {0,2,2}; /* major.minor.patch — 0.2.2: BT persist, settings icon focus, auto-off UI */
uint8_t Led = 8; uint8_t Led = 8;
bool PressFlag = 0; bool PressFlag = 0;
@ -1240,8 +1240,10 @@ uint8_t GetChordNotesByType(uint8_t MIDI_Index,uint8_t type,uint8_t *buff)
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
buff[i] += mGuiData[GUI_TRANSPOSE].Current; buff[i] += mGuiData[GUI_TRANSPOSE].Current;
/* 音师:所有调的 #四级 — 整组和弦低八度,音域压在一个八度内 */ /* 音师:仅所有调的 #四级(键 10~12 + 升)— 整组低八度,音域压在一个八度内
if (chord_type_index_map[MIDI_Index].PitchOffset == 2) * = #IV IV */
if (MIDI_Index >= 10 && MIDI_Index <= 12 &&
chord_type_index_map[MIDI_Index].PitchOffset == 2)
{ {
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{ {

View File

@ -1166,7 +1166,7 @@ void Draw_System_Item_List(const LEBEL_UI *UI, GUI_SWITCH *Group)
} }
break; break;
case GUI_BLUETOOTH_SW: case GUI_BLUETOOTH_SW:
/* 蓝牙符:外置 Flash 当前在 RESTORE 槽(13x21)SET_BLUETOOTH 槽曾误打包调音台 */ /* 素材:系统设置图标-11白蓝牙符Flash 槽名 RESTORE尺寸 13x21 */
LCD_WR_PIC_FROM_FLASH_Trans(UI->x + 12, LCD_WR_PIC_FROM_FLASH_Trans(UI->x + 12,
(uint16_t)(UI->y + (UI->h - UI0902_ICON_SYS_RESTORE_H) / 2), (uint16_t)(UI->y + (UI->h - UI0902_ICON_SYS_RESTORE_H) / 2),
UI0902_ICON_SYS_RESTORE_W, UI0902_ICON_SYS_RESTORE_H, UI0902_ICON_SYS_RESTORE_W, UI0902_ICON_SYS_RESTORE_H,
@ -1183,7 +1183,7 @@ void Draw_System_Item_List(const LEBEL_UI *UI, GUI_SWITCH *Group)
drv_nvm_save_to_flash(); drv_nvm_save_to_flash();
break; break;
case GUI_AUTOCLOSE: case GUI_AUTOCLOSE:
/* 0902-07电源图标档位按手册 15/30/45/60/不自动 */ /* 素材:系统设置图标-12电源符 / ABOUT 槽 18x21 */
LCD_WR_PIC_FROM_FLASH_Trans(UI->x+12, UI->y + (UI->h - 21) / 2, 18, 21, UI0902_ICON_SYS_ABOUT_ADDR); LCD_WR_PIC_FROM_FLASH_Trans(UI->x+12, UI->y + (UI->h - 21) / 2, 18, 21, UI0902_ICON_SYS_ABOUT_ADDR);
ApplyAutoCloseIndex(Group->Current); ApplyAutoCloseIndex(Group->Current);
UI_DrawTriLeft(val_x1, chev_cy); UI_DrawTriLeft(val_x1, chev_cy);

View File

@ -168,7 +168,23 @@ void LCD_WR_PIC(uint16_t x, uint16_t y, uint16_t length, uint16_t width, const u
} }
} }
/* 跳过近黑色像素(图标导出底色常为 0x0000/0x0001/0x0022非纯 BLACK */ /* 跳过近黑色像素(图标导出底色常为 0x0000/0x0001/0x0022非纯 BLACK
* #242B3A(0x2147) PNG
* */
static uint8_t LCD_PicColorIsTransparent(uint16_t c)
{
uint8_t r5 = (uint8_t)((c >> 11) & 0x1F);
uint8_t g6 = (uint8_t)((c >> 5) & 0x3F);
uint8_t b5 = (uint8_t)(c & 0x1F);
if (r5 <= 1 && g6 <= 2 && b5 <= 2)
return 1;
/* UI0902_ROW_BG 0x2147 ≈ R5=4 G6=10 B5=7含打包抗锯齿邻色 */
if (r5 >= 2 && r5 <= 6 && g6 >= 7 && g6 <= 14 && b5 >= 4 && b5 <= 11)
return 1;
return 0;
}
void LCD_WR_PIC_Trans(uint16_t x, uint16_t y, uint16_t length, uint16_t width, void LCD_WR_PIC_Trans(uint16_t x, uint16_t y, uint16_t length, uint16_t width,
const uint8_t data[], uint16_t key_color) const uint8_t data[], uint16_t key_color)
{ {
@ -184,12 +200,8 @@ void LCD_WR_PIC_Trans(uint16_t x, uint16_t y, uint16_t length, uint16_t width,
uint8_t hi = data[i * 2]; uint8_t hi = data[i * 2];
uint8_t lo = data[i * 2 + 1]; uint8_t lo = data[i * 2 + 1];
uint16_t c = (uint16_t)((hi << 8) | lo); uint16_t c = (uint16_t)((hi << 8) | lo);
uint8_t r5 = (uint8_t)((c >> 11) & 0x1F);
uint8_t g6 = (uint8_t)((c >> 5) & 0x3F);
uint8_t b5 = (uint8_t)(c & 0x1F);
/* 近黑视为透明,避免图标黑底方块 */ if (LCD_PicColorIsTransparent(c))
if (r5 <= 1 && g6 <= 2 && b5 <= 2)
continue; continue;
LCD_DrawPoint((uint16_t)(x + (i % length)), LCD_DrawPoint((uint16_t)(x + (i % length)),
@ -254,7 +266,7 @@ void LCD_WR_PIC_ClipX(uint16_t x, uint16_t y, uint16_t full_w, uint16_t h,
} }
} }
/* 从 W25Q128 按行读取并透明显示(跳过近黑像素),复用 pic_batch_buf无大块静态 RAM */ /* 从 W25Q128 按行读取并透明显示(跳过近黑 / 行底色像素),复用 pic_batch_buf无大块静态 RAM */
void LCD_WR_PIC_FROM_FLASH_Trans(uint16_t x, uint16_t y, uint16_t length, uint16_t width, uint32_t flash_addr) void LCD_WR_PIC_FROM_FLASH_Trans(uint16_t x, uint16_t y, uint16_t length, uint16_t width, uint32_t flash_addr)
{ {
uint16_t row, col; uint16_t row, col;
@ -267,10 +279,7 @@ void LCD_WR_PIC_FROM_FLASH_Trans(uint16_t x, uint16_t y, uint16_t length, uint16
for (col = 0; col < length; col++) for (col = 0; col < length; col++)
{ {
uint16_t c = (uint16_t)((pic_batch_buf[col * 2U] << 8) | pic_batch_buf[col * 2U + 1U]); uint16_t c = (uint16_t)((pic_batch_buf[col * 2U] << 8) | pic_batch_buf[col * 2U + 1U]);
uint8_t r5 = (uint8_t)((c >> 11) & 0x1F); if (LCD_PicColorIsTransparent(c))
uint8_t g6 = (uint8_t)((c >> 5) & 0x3F);
uint8_t b5 = (uint8_t)(c & 0x1F);
if (r5 <= 1 && g6 <= 2 && b5 <= 2)
continue; continue;
LCD_DrawPoint((uint16_t)(x + col), (uint16_t)(y + row), c); LCD_DrawPoint((uint16_t)(x + col), (uint16_t)(y + row), c);
} }

View File

@ -42,9 +42,13 @@ def rgba_to_rgb565(im):
for y in range(h): for y in range(h):
for x in range(w): for x in range(w):
r, g, b, a = px[x, y] r, g, b, a = px[x, y]
# 低透明 / 近黑 / 列表行底 #242B3A → 透明(焦点蓝底上避免黑块)
if a < 40 or (r < 12 and g < 12 and b < 12): if a < 40 or (r < 12 and g < 12 and b < 12):
out[i] = 0 out[i] = 0
out[i + 1] = 0 out[i + 1] = 0
elif abs(r - ROW_BG[0]) <= 18 and abs(g - ROW_BG[1]) <= 18 and abs(b - ROW_BG[2]) <= 18:
out[i] = 0
out[i + 1] = 0
else: else:
r = (r * a) // 255 r = (r * a) // 255
g = (g * a) // 255 g = (g * a) // 255

View File

@ -25,7 +25,7 @@ MAP_TXT = REPO / "Doc" / "音色文件" / "0903" / "FLASH_MAP.txt"
IAP_DIR = REPO / "升级" / "MCU主控升级" IAP_DIR = REPO / "升级" / "MCU主控升级"
OUT_ROOT = REPO / "tools" / "out" OUT_ROOT = REPO / "tools" / "out"
FW_VER = "0.2.1" FW_VER = "0.2.2"
TONE_RES_VER = "0903" TONE_RES_VER = "0903"
UI0902_RES_BASE = 0x00100000 UI0902_RES_BASE = 0x00100000
@ -87,18 +87,12 @@ def main() -> None:
combined = build_combined_extflash(tone_data, ui_data) combined = build_combined_extflash(tone_data, ui_data)
mcu_name = f"YNGJ-GT1-M_MCU_v{FW_VER}_{stamp}.bin" mcu_name = f"YNGJ-GT1-M_MCU_v{FW_VER}_{stamp}.bin"
tone_name = f"extflash_toneRes_v{TONE_RES_VER}_{stamp}.res"
ui_name = f"extflash_ui0902_{stamp}.res"
comb_name = f"extflash_ALL_tone0903_ui0902_{stamp}.res" comb_name = f"extflash_ALL_tone0903_ui0902_{stamp}.res"
mcu_dst = pkg / mcu_name mcu_dst = pkg / mcu_name
tone_dst = pkg / tone_name
ui_dst = pkg / ui_name
comb_dst = pkg / comb_name comb_dst = pkg / comb_name
shutil.copy2(EXE_BIN, mcu_dst) shutil.copy2(EXE_BIN, mcu_dst)
tone_dst.write_bytes(tone_data)
ui_dst.write_bytes(ui_data)
comb_dst.write_bytes(combined) comb_dst.write_bytes(combined)
shutil.copy2(iap, pkg / "SoundWalkerIAP.exe") shutil.copy2(iap, pkg / "SoundWalkerIAP.exe")
shutil.copy2(guide, pkg / "升级步骤.docx") shutil.copy2(guide, pkg / "升级步骤.docx")
@ -106,9 +100,10 @@ def main() -> None:
shutil.copy2(MAP_TXT, pkg / "FLASH_MAP.txt") shutil.copy2(MAP_TXT, pkg / "FLASH_MAP.txt")
shutil.copy2(mcu_dst, OUT_ROOT / mcu_name) shutil.copy2(mcu_dst, OUT_ROOT / mcu_name)
shutil.copy2(tone_dst, OUT_ROOT / "extflash_tone_0903.res")
shutil.copy2(ui_dst, OUT_ROOT / "extflash_ui0902.res")
shutil.copy2(comb_dst, OUT_ROOT / "extflash_ALL_tone0903_ui0902.res") shutil.copy2(comb_dst, OUT_ROOT / "extflash_ALL_tone0903_ui0902.res")
# Keep build intermediates under tools/out for local rebuilds; not shipped in package.
(OUT_ROOT / "extflash_tone_0903.res").write_bytes(tone_data)
(OUT_ROOT / "extflash_ui0902.res").write_bytes(ui_data)
readme = pkg / "README.txt" readme = pkg / "README.txt"
readme.write_text( readme.write_text(
@ -120,29 +115,26 @@ def main() -> None:
f"Git subject {subject}", f"Git subject {subject}",
f"FW version {FW_VER}", f"FW version {FW_VER}",
"", "",
"==== 同事整机升级请优先刷这两项 ====", "==== 整机升级请刷这两项 ====",
f" 1) {mcu_name} -> MCU APP", f" 1) {mcu_name} -> MCU APP",
f" 2) {comb_name} -> 外部 Flash 从 0x0 起整包", f" 2) {comb_name} -> 外部 Flash 从 0x0 起整包",
" (= 音色区 + 填充 + UI0902 图片区)", " (= 音色区 + 填充 + UI0902 图片区)",
"", "",
"建议步骤:",
" - 先整片擦除外部 Flash再刷上述 ALL .res @ 0x00000000",
" - 勿只刷音色区否则模式选择页会花屏UI 图在 0x100000",
"",
"外部 Flash 分区:", "外部 Flash 分区:",
" 0x00000000 音色/充电图 (toneRes)", " 0x00000000 音色/充电图 (toneRes)",
" logo pad + Charg@0xCB70 + 1.bin@0x1B8F0 + 2.bin + 3.bin", " logo pad + Charg@0xCB70 + 1.bin@0x1B8F0 + 2.bin + 3.bin",
" 0x00100000 UI0902 图片 (模式选择大图、全屏开机 Logo、设置/调音台素材等)", " 0x00100000 UI0902 图片 (模式选择大图、全屏开机 Logo、设置/调音台素材等)",
"", "",
"分文件(仅在工具支持指定偏移时使用):", f" {comb_name} size={comb_dst.stat().st_size} @ 0x00000000",
f" {tone_name} size={tone_dst.stat().st_size} @ 0x00000000",
f" sha256={sha256(tone_dst)}",
f" {ui_name} size={ui_dst.stat().st_size} @ 0x00100000",
f" sha256={sha256(ui_dst)}",
f" {comb_name} size={comb_dst.stat().st_size} @ 0x00000000 (推荐)",
f" sha256={sha256(comb_dst)}", f" sha256={sha256(comb_dst)}",
"", "",
f"MCU: {mcu_name} size={mcu_dst.stat().st_size} sha256={sha256(mcu_dst)}", f"MCU: {mcu_name} size={mcu_dst.stat().st_size} sha256={sha256(mcu_dst)}",
"", "",
"说明:", "说明:",
" - 只刷音色 .res、不刷 UI0902 时,模式选择页会花屏(读图地址在 0x100000",
" - 本机开发板若早已刷过 UI0902只更新音色+MCU 仍可能正常;同事空片/整片擦除会中招。",
" - 开机全屏 Logo、关机充电全屏画面在 UI0902不在音色包里的 logo.bin/Charg.bin 占位。", " - 开机全屏 Logo、关机充电全屏画面在 UI0902不在音色包里的 logo.bin/Charg.bin 占位。",
" - AutoBand 0x9EB5F 本版未重排。", " - AutoBand 0x9EB5F 本版未重排。",
"", "",