碎碎念

陪她去流浪 新建

我靠,Shaders好好玩儿!

没有评论 页首

去电影院看了一部3️⃣个小时的电影《奥德赛》到凌晨、去木屋烧烤吃了一顿好吃的烧烤、去网吧玩了两个小时差不多快十年没玩过的电脑版英雄联盟(大概十几把吧,胜率:0%,实在没手感🥵),太无聊了,然后打开了WebGL教程学写Shaders(着色器)到破晓。🤡

不得不感叹网吧的电脑真流畅啊,包间里面的电脑据说有240帧,那光标真的是巨丝滑,回到家再看外接了4K显示器的Macbook Pro,像是上世纪的产物一般🤷。

没有评论 页首

虽然不算是明确的响应式布局,但是起码不是订死了窗口大小了。

排版有点抖动,但是我还不知道真实原因。猜测:

  1. 内部尺寸计算使用的是整数除法;
  2. 垂直同步问题。
没有评论 页首

给桌面端加入了Apple的Metal GPU后端,现在桌面端渲染一帧只需要不到200us秒(也就是FPS=5000?),相比于纯CPU的2ms还是挺震惊的。

没有评论 页首

让Codex写了个同步碎碎念到推特的按钮,现在应该不会因为打开推特就刷两个小时然后忘记要干什么了……

这是一个测试。

没有评论 页首

本来以为墨水屏局部刷新脏矩形的计算对GUI框架来说很麻烦…

给我给整不会了…🤡🤡🤡

...

其实你的渲染架构已经比较接近墨水屏需要的模式了。

建议把渲染拆成两层:

Layout
    ↓
Paint 到内存 Buffer
    ↓
Diff
    ↓
Dirty Rect
    ↓
EPD Update

也就是说:

GUI 仍然画完整 Buffer。

最后:

Old Buffer

New Buffer

↓

比较

↓

找出变化区域

↓

通知 EPD

这样你的 GUI 不需要知道是不是墨水屏。

LCD Backend:

Memcpy framebuffer

EPD Backend:

Diff

↓

Update(Rect1)

↓

Update(Rect2)

如果以后支持真正的 E-Ink 驱动,只需要替换最后一层 Backend 即可。

所以只要遍历所有像素点,找出 [min(x),min(y),max(x),max(y)] 构成的矩形,拷贝过去即可完成刷新。

最大的问题就是CPU快不快了。

没有评论 页首

狗屁通给我讲的复杂文本排版居然和我想的一样

文本排版需要自动换行,所以最好在一个地方处理。但是我不确定这样是否“标准”,于是在我刚开始修改了一点点实现的时候我就问了狗屁通,这一通回答下,我感觉自信满满。

但是凭心而论,这个排版方式其实更应该适用于所有的内联排版(比如图文混排),而不仅仅是文本。然后,图片其实也就是个“不会wrap的text”仅此而已。所以后面如果要增加图文混排,只会更简单?

另外,排版这个过程应该由<text>的父元素来执行(即便<text>内还有其它元素),因为:对于来换行的父元素来说,<text是没法知道父元素的总体大小的。

我的文本节点是 <text>,它里面可以有 <b>、<i>、<code> 等子元素,而且子元素可以嵌套。由于文本在渲染、排版的时候是可以自动换行的,我应该如何表示这层关系、并且方便渲染?

我看了你的代码,我觉得现在最大的瓶颈不是 <b> 怎么表示,而是你的 Text 节点承担了两种职责:

  1. DOM 节点(树)
  2. 排版对象(Layout)

浏览器实际上把这两者分开了。


浏览器大概是这样

DOM:

1
2
3
4
5
6
7
text
├── "Hello "
├── b
│   ├── "World "
│   └── i
│       └── "!!!"
└── " Bye"

对应:

1
2
3
4
5
6
7
8
<text>
    Hello
    <b>
        World
        <i>!!!</i>
    </b>
    Bye
</text>

但是 Layout 并不会递归画这个树。

而是先展开。


第一步:生成 TextRun

浏览器会得到类似:

1
2
3
4
type TextRun struct {
    Text  string
    Style Styles
}

例如:

1
2
3
4
5
6
[
    {Text:"Hello ", Style:normal},
    {Text:"World ", Style:bold},
    {Text:"!!!",    Style:bold+italic},
    {Text:" Bye",   Style:normal},
]

注意:

已经没有 DOM。

只有:

1
2
3
4
5
字符串

+

最终样式

第二步:Layout

Layout 输入:

1
[]TextRun

例如:

1
Hello World !!! Bye

然后:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Segment()

↓

Line1

↓

Line2

↓

...

这里可以跨 Run。

例如:

1
2
3
4
5
6
7
8
Run1

Hello

Run2

World

宽度:

1
Hello Wo

第一行:

1
Hello Wo

第二行:

1
rld

甚至:

1
Hel

也是合法的。

所以:

换行单位不是 Run,而是 Glyph。


第三步:生成 Line

例如:

1
2
3
type TextLine struct {
    Runs []TextRunFragment
}

其中:

1
2
3
4
5
type TextRunFragment struct {
    Run   *TextRun
    Start int
    End   int
}

例如:

1
Hello World!!!

可能得到:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
Line1

Hello Wo

↓

[
 normal(Hello ),
 bold(Wo),
]

Line2

rld!!!

↓

[
 bold(rld),
 bold+italic(!!!),
]

Draw

Draw 就非常简单:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
for _, line := range lines {

    x := 0

    for _, run := range line.Runs {

        face := fontManager.Face(run.Style)

        DrawString(run.Text)

        x += run.Width
    }
}

对你的代码

我会把:

1
2
3
4
5
6
7
type Text struct {
    BaseBox

    Data string

    face FontFace
}

改掉。

Data 不应该存在。

应该:

1
2
3
4
5
type Text struct {
    BaseBox

    Lines []TextLine
}

真正的数据来自:

1
Children

例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Text

↓

Children

↓

TextNode

Bold

Italic

然后新增一种:

1
2
3
4
5
6
type TextData struct {

    BaseBox

    Data string
}

注意:

现在:

1
Text

不再保存:

1
Data

而是:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Text

↓

TextData

↓

Bold

↓

Italic

这样:

1
2
3
4
5
6
<text>
    Hello
    <b>
        World
    </b>
</text>

就是:

1
2
3
4
5
6
7
Text

├──TextData("Hello")

└──Bold

    └──TextData("World")

Calc()

Calc 时:

第一步:

DFS。

把树:

1
2
3
4
5
6
7
8
9
Text

↓

Bold

↓

Italic

展开:

1
[]TextRun

每个 Run 带:

1
最终 Styles

例如:

1
2
3
4
5
Bold

↓

Style.FontBold=true

Italic:

1
2
3
FontBold=true

FontItalic=true

全部继承好了。


然后:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
Runs

↓

Layout

↓

Lines

↓

保存到

Text.Lines

Draw:

完全不用递归。

直接:

1
2
3
4
5
for line

    for run

        Draw

我为什么推荐这种结构

因为以后你肯定还会支持:

1
2
3
4
5
<b>
<i>
<code>
<span>
<color>

甚至:

1
<a>

如果每一种都在 Draw 里面递归:

1
2
3
4
5
6
7
8
9
Draw()

↓

Draw()

↓

Draw()

最后:

1
2
3
4
5
6
7
8
9
自动换行

跨节点

选中

复制

光标

都会变得非常痛苦。

而浏览器几十年来一直都是:

DOM → TextRun → Line → Glyph → Draw

DOM 只是输入。

真正负责排版的是一组已经扁平化的 TextRun。


结合你现在的代码,我建议把 Text 从“叶子节点”改成“文本容器”,新增一个真正的文本叶子节点(例如你已经有的 _TextData,把它完善即可)。 然后在 Text.Calc() 中递归遍历子树,继承样式并生成 []TextRun,再进行换行和排版。这一步完成后,Draw() 就完全不需要关心 DOM 树了,只负责按排版结果绘制。这种结构和浏览器、Qt、Flutter 的文本引擎都非常接近,而且以后加 <i>、<code>、<span>、超链接等都不用推翻整个设计。

2026-08-04 12:29:30

我实现好了,感觉非常优雅:fbiw/box.go at main · movsb/fbiw。

4条评论 页首

最近的代码提交时间居然异常正经

1
2
3
$ git log --pretty=format:'%h %ad %s' \
          --date=format:'%m-%d %H:%M' \
          --graph
  • e08a80c 07-31 19:13 增加字体后备功能(防止崩溃)
  • fce9533 07-31 18:43 支持后代选择器
  • 2cb5538 07-31 15:42 默认不应有背景色
  • 7f3bd6e 07-31 15:23 修复继承顺序错误
  • 9f8c466 07-31 13:34 常规元素也可以作为Spacer占据剩余空间
  • 152cb61 07-31 12:03 字体继承 & 字体管家
  • 74bd881 07-31 00:15 修复CSS样式层叠/继承未生效问题
  • 77dc0ed 07-30 20:45 修复背景透明问题
  • 450f78c 07-30 18:03 缓存直接能用的图片格式(性能提高了80倍!)
  • c696ca8 07-30 14:51 第一版CSS样式功能测试成功
  • 0702f94 07-30 08:41 修复inline的高度计算错误
  • 4dfa220 07-29 18:41 支持垂直居中
  • 3d2c6a9 07-29 18:29 修复排版
  • 80bb0d4 07-29 17:51 支持水平居中
  • e3b31cb 07-29 16:47 宽度可以用百分数
  • 7e4225c 07-29 16:11 重写排版引擎(取消block和inline的混合排版)
  • 5ab9e65 07-29 09:56 增加背景图片功能 & 修复透明背景变黑色问题
  • 4573629 07-29 08:26 tidy
  • 1b416ff 07-28 23:49 映射电脑按键为控制器按键
  • b3936ca 07-28 23:41 按“菜单”+“开始”可以退出程序
  • 2e7fb82 07-28 23:06 统一事件驱动循环框架 & 集成按键处理
  • 9d5a29a 07-28 17:22 简单脏判断(但是并没有停止刷新)
  • ecbee77 07-28 16:25 在主界面展示帧渲染时长
  • 3265a8c 07-28 15:57 缓存图片加载
  • 54309f4 07-28 15:45 用 FillRect 方法重新实现画边框、画背景
  • 2382375 07-28 12:28 修复崩溃
  • aad3fb3 07-28 12:25 修复块级元素排版崩溃
  • f68940c 07-28 12:16 提取公共基础方法 & 支持内联排列
  • c1622d5 07-28 09:48 简单居中对话框 & 图片显示控件
  • 1c1c988 07-27 23:06 绘制多行文本
  • 305f8e0 07-27 19:55 换成HTML测试
  • 8bae5cc 07-27 18:06 内边距(Padding)
  • 4e0bedf 07-27 17:48 initial commit
没有评论 页首

小切片容量居然能带来这么大的性能优化

以下是手写图像合成时AlphaBlend过程代码片段:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
for x := range width {
	// 参考:image/draw/draw.go
	// “Small cap improves performance”
	// 从每帧2.6ms降到1.7ms。
	s := src[x*4 : x*4+4]
	d := dst[x*4 : x*4+4]
	a := s[3]
	switch {
	case a == 255:
		// copy(d, s[:4])
		*(*uint32)(unsafe.Pointer(&d[0])) = *(*uint32)(unsafe.Pointer(&s[0]))
	case a != 0:
		i := 255 - a
		d[0] = uint8((int(s[0])*int(a) + int(d[0])*int(i)) / 255)
		d[1] = uint8((int(s[1])*int(a) + int(d[1])*int(i)) / 255)
		d[2] = uint8((int(s[2])*int(a) + int(d[2])*int(i)) / 255)
		d[3] = 255
	}
}

参考了标准库的写法:https://github.com/golang/go/blob/9d8bad3bbd88ed75a6ea4a20fa633ede9d1bb0d9/src/image/draw/draw.go#L460

没有评论 页首

RAR居然有Linux版本!

虽然官方写的是Trial(免费试用),但是命令行帮助文档又写是Freeware(免费软件),这就让我很难懂。

另外,7-zip的命令行版本竟然不支持解压RAR,我明明记得以前是可以的(我专门为此下载过p7zip很多次)。

没有评论 页首

西部数据的硬盘真垃圾,感觉没有必要再测下去了

从大学拥有笔记本开始,用西部数据的硬盘比较多。但是基本上都是没过太久硬盘内部就开始作响,读取速度极慢。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
root@nuc:~ → badblocks -sv /dev/sdf
Checking blocks 0 to 3906984959
Checking for bad blocks (read-only test): 219343792one, 54:30 elapsed. (0/0/0 errors)
219343793
219343794one, 54:31 elapsed. (2/0/0 errors)
219343795
219343796
219343797
219343798
219343799
219343800
219343801
219343802one, 54:33 elapsed. (10/0/0 errors)
219343803
219343804
219343805
219343806
219343807
581342744one, 4:40:18 elapsed. (16/0/0 errors)
581342745
581342746
581342747
581758516one, 4:40:34 elapsed. (20/0/0 errors)
581758517
581758518
581758519one, 4:40:35 elapsed. (23/0/0 errors)
1041350828ne, 9:28:51 elapsed. (24/0/0 errors)
1041350829
1041350830ne, 9:28:52 elapsed. (26/0/0 errors)
1041350831
1189825252ne, 11:02:30 elapsed. (28/0/0 errors)
1189825253
1189825254
1189825255
1228382868ne, 11:26:54 elapsed. (32/0/0 errors)
1228382869
1228382870
1228382871
1379033540ne, 13:03:23 elapsed. (36/0/0 errors)
1379033541ne, 13:03:24 elapsed. (37/0/0 errors)
1379033542
1379033543
1379033544
1379033545
1379033546
1379033547ne, 13:03:25 elapsed. (43/0/0 errors)
1515611824ne, 14:31:23 elapsed. (44/0/0 errors)
1515611825
1515611826
1515611827ne, 14:31:24 elapsed. (47/0/0 errors)
 42.79% done, 16:11:53 elapsed. (48/0/0 errors)
^C2.92% done, 16:15:09 elapsed. (48/0/0 errors))

Interrupted at block 1676792265

但是如果让AI分析一下smart信息,却又显示……很好。我认为:这基本等同于说这盘没有自恢复/重映射/磨损均衡1。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
root@nuc:~ → smartctl -a /dev/sdf
smartctl 7.5 2025-04-30 r5714 [x86_64-linux-6.18.22-0-lts] (local build)
Copyright (C) 2002-25, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Family:     Western Digital Elements / My Passport (USB, AF)
Device Model:     WDC WD40NMZW-11GX6S2
Serial Number:    WD-WX51D29RDNYH
LU WWN Device Id: 5 0014ee 2111915d5
Firmware Version: 01.01A01
User Capacity:    4,000,787,030,016 bytes [4.00 TB]
Sector Sizes:     512 bytes logical, 4096 bytes physical
Rotation Rate:    5400 rpm
Form Factor:      2.5 inches
TRIM Command:     Available, deterministic
Device is:        In smartctl database 7.5/5706
ATA Version is:   ACS-3 (minor revision not indicated)
SATA Version is:  SATA 3.1, 6.0 Gb/s (current: 6.0 Gb/s)
Local Time is:    Thu Jul 16 18:20:58 2026 CST
SMART support is: Available - device has SMART capability.
SMART support is: Enabled

=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED

General SMART Values:
Offline data collection status:  (0x00)	Offline data collection activity
					was never started.
					Auto Offline Data Collection: Disabled.
Self-test execution status:      ( 121)	The previous self-test completed having
					the read element of the test failed.
Total time to complete Offline
data collection: 		(21300) seconds.
Offline data collection
capabilities: 			 (0x1b) SMART execute Offline immediate.
					Auto Offline data collection on/off support.
					Suspend Offline collection upon new
					command.
					Offline surface scan supported.
					Self-test supported.
					No Conveyance Self-test supported.
					No Selective Self-test supported.
SMART capabilities:            (0x0003)	Saves SMART data before entering
					power-saving mode.
					Supports SMART auto save timer.
Error logging capability:        (0x01)	Error logging supported.
					General Purpose Logging supported.
Short self-test routine
recommended polling time: 	 (   2) minutes.
Extended self-test routine
recommended polling time: 	 ( 673) minutes.
SCT capabilities: 	       (0x30b5)	SCT Status supported.
					SCT Feature Control supported.
					SCT Data Table supported.

SMART Attributes Data Structure revision number: 16
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x002f   200   174   051    Pre-fail  Always       -       15
  3 Spin_Up_Time            0x0027   253   253   021    Pre-fail  Always       -       3716
  4 Start_Stop_Count        0x0032   099   099   000    Old_age   Always       -       1366
  5 Reallocated_Sector_Ct   0x0033   200   200   140    Pre-fail  Always       -       0
  7 Seek_Error_Rate         0x002e   100   253   000    Old_age   Always       -       0
  9 Power_On_Hours          0x0032   031   031   000    Old_age   Always       -       50889
 10 Spin_Retry_Count        0x0032   100   100   000    Old_age   Always       -       0
 11 Calibration_Retry_Count 0x0032   100   100   000    Old_age   Always       -       0
 12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       626
192 Power-Off_Retract_Count 0x0032   200   200   000    Old_age   Always       -       591
193 Load_Cycle_Count        0x0032   196   196   000    Old_age   Always       -       14992
194 Temperature_Celsius     0x0022   101   082   000    Old_age   Always       -       51
196 Reallocated_Event_Count 0x0032   200   200   000    Old_age   Always       -       0
197 Current_Pending_Sector  0x0032   200   200   000    Old_age   Always       -       10
198 Offline_Uncorrectable   0x0030   100   253   000    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x0032   200   200   000    Old_age   Always       -       0
200 Multi_Zone_Error_Rate   0x0008   100   253   000    Old_age   Offline      -       0

SMART Error Log Version: 1
No Errors Logged

SMART Self-test log structure revision number 1
Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
# 1  Extended offline    Completed: read failure       90%     50873         438687584
# 2  Extended offline    Aborted by host               90%     16613         -
# 3  Short offline       Completed without error       00%     16613         -

Selective Self-tests/Logging not supported

The above only provides legacy SMART information - try 'smartctl -x' for more
2026-07-16 19:42:12

我隐约觉得可以拯救一下:用badblocks来个全盘读写测试(可能需要几天时间),然后只把好的扇区划分出新的盘,坏的就不管了。然后把它作为BT下载盘,物尽其用。

2026-07-17 03:02:46
1
2
3
4
root@nuc:~ → badblocks -wsv /dev/sdf                                                                                                                                                              
Checking for bad blocks in read-write mode
From block 0 to 3906984959
Testing with pattern 0xaa:   1.53% done, 8:02:51 elapsed. (0/0/0 errors)

按照这个进度,完成此4T大小的机械硬盘的读写测试需要大概520个小时。🫪


  1. 这应该属于闪存介质层面的概念。这里借用来说明主控芯片的重分配功能是垃圾。 ^

没有评论 页首

语法分析:“copy the link to this tweet”

“copy the link to this tweet” 按照语法分析,“to”是哪部分?修饰link还是copy…to语法?

这是一个很好的语法分析题。

在 "Copy the link to this tweet." 中,to this tweet 是修饰 link 的,而不是 copy 的补足语。

整个结构可以分析为:

  • Copy —— 动词(祈使句)
  • the link to this tweet —— 宾语(名词短语)
    • the link —— 名词
    • to this tweet —— 介词短语,作后置定语,修饰 link

也就是:

the link [to this tweet]

「指向这条推文的链接」

相当于:

  • the key to the door(门的钥匙)
  • the answer to the question(问题的答案)
  • the solution to the problem(问题的解决方案)
  • the road to Beijing(通往北京的路)

这里 to 表示「通向、指向、关于」。


为什么不是 "copy ... to ..."?

英语确实有 copy A to B 这种结构,例如:

  • Copy the file to your desktop.
  • Copy this text to the clipboard.
  • Copy the photo to another folder.

这里的 to + 地点 是表示复制到哪里去,属于动词 copy 的补足语。

例如:

Copy the file to your desktop.

分析:

  • Copy(动词)
  • the file(宾语)
  • to your desktop(地点状语,表示复制到哪里)

为什么这里不能这样理解?

如果把它理解成:

Copy

the link

to this tweet

意思就会变成:

把链接复制到这条推文里。

但实际上:

  • 一条推文不是一个可以粘贴内容的目标位置;
  • 在 X(Twitter)的界面中,Copy link to this tweet 是一个固定菜单项,它表示:

    复制这条推文的链接。

所以这里 to this tweet 必须和 link 连在一起。


可以画成语法树

Copy
└── the link
    └── to this tweet

而不是

Copy
├── the link
└── to this tweet

一个验证方法

把名词换掉就很容易看出来:

  • Copy the URL to this page.
  • Copy the link to this video.
  • Copy the path to this folder.

这里:

  • the URL to this page(这个页面的 URL)
  • the link to this video(这个视频的链接)
  • the path to this folder(这个文件夹的路径)

其中 to ... 都是修饰前面的名词,而不是表示复制的目标。

因此,"Copy the link to this tweet." 中的 to this tweet 是 link 的后置定语,整个名词短语 the link to this tweet 作 copy 的宾语,而不是 copy ... to ... 的句型。

那如何翻译“把链接复制到这条推文里。”?

如果要表达 “把链接复制到这条推文里。”,英语就会采用 copy A to B 的结构,其中 to 属于动词 copy。

例如:

Copy the link to this tweet.

单独看这句话其实有歧义:

  1. Copy [the link to this tweet].(复制这条推文的链接)✅ 在 X/Twitter 的界面中就是这个意思。
  2. Copy [the link] [to this tweet].(把链接复制到这条推文里。)语法上也可以分析,但语义不太自然,因为推文本身不是一个可作为目标位置的容器。

因此,英语母语者通常会把第二种意思说得更明确。

常见表达有:

  • Paste the link into this tweet.(把链接粘贴到这条推文里。)⭐⭐⭐⭐⭐ 最自然
  • Copy the link into this tweet.(把链接复制到这条推文里。)虽然能理解,但 copy into 不如 paste into 常见。
  • Copy the link and paste it into this tweet.(复制链接,然后把它粘贴到这条推文里。)最明确。
  • Paste the link into the tweet you're composing.(把链接粘贴到你正在编辑的这条推文中。)如果指的是正在写的新推文。

为什么不用 to?

对于表示目标位置时:

  • copy ... to ... 更常用于文件、目录、设备等,例如:
    • Copy the file to your desktop.
    • Copy the image to another folder.

而对于文本编辑框、邮件、聊天窗口、推文等可以输入文字的地方,英语更习惯用:

  • paste ... into ...
  • insert ... into ...

例如:

  • Paste the URL into the email.
  • Paste the code into the editor.
  • Paste the link into the tweet.

所以,如果真的想表达中文的“把链接复制到这条推文里”,最地道的英语通常不是 Copy the link to this tweet,而是:

Paste the link into this tweet.

因为英语里 copy 强调“复制到剪贴板”,paste 才强调“放到目标位置”。

为什么“推文本身不是一个可作为目标位置的容器”?

这是一个涉及**英语语义习惯(selectional preference,搭配偏好)**的问题,而不是严格的语法规则。

从语法上说,Copy the link to this tweet. 完全可以分析成:

copy + the link + to this tweet

没有任何语法错误。

真正的问题是语义。


为什么说 "tweet" 不像一个目标位置?

英语里的 copy A to B,其中 B 往往是一个存放对象的地方(destination)。

例如:

  • Copy the file to your desktop.
  • Copy the photo to the SD card.
  • Copy the folder to the USB drive.
  • Copy the text to the clipboard.

这些目的地都有一个共同特点:

它们是存储对象的地方。


Tweet 更像什么?

一条已经发布的 tweet,英语母语者通常把它理解为:

一个已经存在的内容(a piece of content)

而不是

一个可以放东西进去的容器(a container)。

所以:

Copy the link to this tweet.

更容易被理解为:

the link to this tweet

(这条推文的链接)

因为 link to X 是一个极其固定的搭配:

  • link to this page
  • link to this article
  • link to the video
  • link to your profile

看到 link to,大脑几乎会立刻把它作为一个整体来解析。


如果是在编辑推文呢?

情况就不同了。

例如:

  • Paste the link into the tweet.
  • Paste the link into your reply.
  • Paste the URL into the comment.
  • Paste the code into the editor.

这里用的是 into。

为什么?

因为:

  • editor(编辑器)
  • comment box(评论框)
  • text field(文本框)
  • compose window(编辑窗口)

这些都是真正意义上的输入区域。

如果说的是:

the tweet you're writing

也可以:

Paste the link into the tweet you're writing.

这里的 tweet 实际上是借代为正在编辑的文本内容,因此 into 很自然。


为什么不用 to?

英语里:

  • copy ... to ... 更强调复制到某个存储位置(文件系统、设备、剪贴板等)。
  • paste ... into ... 更强调把内容插入某个文本或文档内部。

例如:

  • Copy the file to Downloads.
  • Paste the text into the document.

因此,如果目标是一条推文(尤其是正在编辑的推文),英语通常会说:

Paste the link into the tweet.

而不是:

Copy the link to the tweet.


所以,我之前说“推文本身不是一个可作为目标位置的容器”,更准确地说应该是:

在英语的惯用表达中,一条 tweet 通常不会和 copy ... to ... 搭配来表示复制的目标;如果是往推文内容中放文字,更自然的搭配是 paste ... into ...。

这是一种搭配习惯,而不是语法上的禁止。事实上,如果上下文明确是在编辑一条推文,听者仍然有可能理解你的意思,只是会觉得 paste ... into ... 更符合英语的自然表达。

https://chatgpt.com/share/6a578b02-cc74-83e8-8449-1c6ca029ce12

没有评论 页首

到底是谁在用Jellyfin这么卡的播放器啊?

上一次尝试使用Jellyfin1至少应该是在五年前。这两天又尝试了一下,体验了几分钟,再次放弃。

走WebDAV/Samba共享硬解直接播放的播放器可能完全不需要耗费CPU,但是用Jellyfin在网页上播放直接快要跑满了我的12核小主机,风扇直接起飞。我感觉我是吃饱了撑的,真的。

而且,明明内网网速极快,但是在网页上Seek却需要卡好几秒。这跟在线平台看有啥区别?没有……

我一个非前端都知道在URL中使用/#/home这种东西已经是非常落后的技术了,怎么还有人在用啊?

非常希望IINA出一个手机版!


更新一条:

X 上的 蓝点网:“软件资讯 开源媒体服务器项目 Jellyfin 创始团队接连离开,项目后续治理和路线变得灰暗,暂时也没有继任安排。 近期 Jellyfin 两名联合创始人和一名长期核心成员接连宣布离开,离开的原因五花八门,有个人原因,也有项目开发和社区原因。 离任后没有接任计划,这让 Jellyfin https://t.co/3wxUrFEKGn” / X


  1. 谨防有人不知道:Jellyfin简单说是一个把自己的电影文件整理成家庭影院似的播放器。 ^

2条评论 页首

笔记本从腿上掉下来给砸了

心疼、肉痛!去了天才吧,她不建议我修,说需要换整个外壳,¥5000🤡。然后她又现场给我看了以旧换新:残值¥5000,补差价¥20000可以上M5同配置🤡。

你🉑拉倒吧,听你的我就是大冤种。

没有评论 页首

我感觉OpenSSL哪天会再次爆发类似“心脏流血”的事故……

刚看OpenWRT版本25.12.5的更新记录1,对OpenSSL的更新有点儿吓人……

OpenSSL: update to 3.5.7, fixing multiple security vulnerabilities (CVE-2026-7383, CVE-2026-9076, CVE-2026-34180, CVE-2026-34181, CVE-2026-34182, CVE-2026-34183, CVE-2026-42764, CVE-2026-42766, CVE-2026-42767, CVE-2026-42768, CVE-2026-42769, CVE-2026-42770, CVE-2026-45445, CVE-2026-45446, CVE-2026-45447).

虽然没看具体是什么问题,但是感觉OpenSSL这堆屎山迟早会再次掀起像几年前的“心脏流血”事件一样的重大互联网安全事故。

没有评论 页首

去医院正经洗了个牙,费用震惊我妈

年纪大了,牙周不太好,所以去了一次医院做个正经的牙周治疗,但我感觉就是个稍微专业点的洗牙?相比于机构的50块钱的洗牙并没有太大区别?

噢对了,这仅是单次的,上周还做了一次。所以到目前为止,一共花了¥2000. 😭

3条评论 页首

人生第一次美甲体验💅

感觉手被紫外线烤得特别烧,不知道每个月不停换美甲、出门又戴防晒的是怎么想的。

实况
实况

怎么样,好看吗?[doge][doge][doge]

2条评论 页首

终于给车找了个正经的停车位

在深圳的路边停车,我发现有个非常奇怪的现象:

  • 别人可以停,我一停就被贴。路边到处都是别人的车,也没有罚单。
  • 好不容易找到个路边划线停车但是不收费的车位,刚停一周就被涂黑了,不敢再停。
  • 小区内车位非常少,电瓶车非常乱停,收费20一天,一个月要600。没有月卡可办,就是抢钱。

终于找到了一个能找到的最便宜的车位:300/月,在公园内。

悬着的心终于放下来了……

没有评论 页首

把服务器必要组件全部打包进了一个Docker容器中

最开始的时候服务器只有nginx一个必要组件;后来把http2tcp装进去了,为的是能让ssh走https连接,尽量防止服务器被屏蔽;再后来又加上了http2socks,它能基于1条http2tcp连接mux出多条tcp连接,作为SOCKS协议使用;再再后来还加上了类似hysteria这种第三方组件。所以,维护成本就变得更高了;二进制文件分散、配置文件分散,特别是有多台服务器的时候,每台都需要重新弄一遍,很是麻烦。

拖了很久,今晚才抽空把它们全部装进了一个名为“serverd”的容器中。里面同时包含了服务器证书、各种配置文件,所以这个容器是个私有容器。靠在本地build后save到文件然后load到服务器。

感觉极大地降低了心智负担。

没有评论 页首

第一次这么明显地感受到618的先涨价再打折

以前还没那么明显,老实说。因为加了商家的群,偶尔有人会交流经验,然后我就会经常留意到最新的价格。

我去年买的时候是170左右,后面因为内存原因一波涨到250,持续了很久。这几天为了迎接618,直接拉爆了。只能说,平台跟商家没一个好东西。

没有评论 页首

手机电池电量掉到99%了

时间刚好是半年零半个月。难受,焦虑😐。

不知道是不是最近打游戏导致的…

我决定卸载游戏。

3条评论 页首

法语原版音乐剧《唐璜》

怎么说呢,感觉是最近看过的最朴素、无感的一部剧了。

虽然说名字是音乐剧,但是就我而言,我感觉音乐一点都不好听。全程是那种打击乐➕跺脚表演,没有起伏,没有递进。听了不到半小时我就已经坐不住了,后面干脆迷迷糊糊开始睡觉了。

再说剧情,真实的表演我其实没太看懂,章节之间比较割裂。看了门票/海报上的介绍才知道这是一个出轨剧,我去……

噢,还有一点。我发现我不喜欢法语。口齿好像非常不清晰,舌头👅在打架🫯式地绕圈子,以至于让不懂法语的人有一种听起来完全没有抑扬顿挫的感觉,所以又给整个剧更徒增了乏味。

2026-05-20 10:34:23

必须再重听一遍《摇滚红与黑 | 法语音乐剧》涤荡一下我的心灵。

5条评论 页首

就这么简单地成为“超凡大师”了?

笑死我了,这游戏是不是已经没有太多人玩了?

超凡大师?信不信马上超鬼给你看,不说假话。


最强王者🤴

没有评论 页首

《给阿嬷的情书》,真好看!

很感人、很催泪。


到底怎么读,打一架吧要不?

没有评论 页首

伦敦西区原版音乐剧《玛蒂尔达》

我拍的:

谢幕:

实况

剧照:

没有评论 页首

所以binwalk是个什么工具啊,为什么需要安装这么多附加包,太吓人了……

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
$ sudo apt install binwalk
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  7zip adwaita-icon-theme arj at-spi2-common at-spi2-core binutils binutils-common
  binutils-x86-64-linux-gnu blt bzip2 cpp cpp-13 cpp-13-x86-64-linux-gnu cpp-x86-64-linux-gnu
  cramfsswap dconf-gsettings-backend dconf-service fontconfig fonts-lyx g++ g++-13
  g++-13-x86-64-linux-gnu g++-x86-64-linux-gnu gcc gcc-13 gcc-13-base gcc-13-x86-64-linux-gnu
  gcc-14-base gcc-x86-64-linux-gnu gsettings-desktop-schemas gtk-update-icon-cache
  hicolor-icon-theme humanity-icon-theme isympy-common isympy3 javascript-common libafflib0t64
  libasan8 libatk-bridge2.0-0t64 libatk1.0-0t64 libatomic1 libatspi2.0-0t64 libavahi-client3
  libavahi-common-data libavahi-common3 libb2-1 libbfio1 libbinutils libblas3 libbz2-1.0
  libcairo-gobject2 libcairo2 libcc1-0 libcolord2 libctf-nobfd0 libctf0 libcups2t64
  libdate-manip-perl libdatrie1 libdconf1 libdouble-conversion3 libdrm-amdgpu1 libdrm-common
  libdrm-intel1 libdrm2 libegl-dev libegl-mesa0 libegl1 libepoxy0 libewf2 libgbm1
  libgcc-13-dev libgcc-s1 libgdk-pixbuf-2.0-0 libgdk-pixbuf2.0-bin libgdk-pixbuf2.0-common
  libgfortran5 libgl-dev libgl1 libgl1-mesa-dev libgl1-mesa-dri libgles-dev libgles1 libgles2
  libglu1-mesa libglu1-mesa-dev libglut-dev libglut3.12 libglvnd-core-dev libglvnd-dev
  libglvnd0 libglx-dev libglx-mesa0 libglx0 libgomp1 libgprofng0 libgraphite2-3 libgtk-3-0t64
  libgtk-3-bin libgtk-3-common libharfbuzz0b libhwasan0 libice-dev libice6 libimagequant0
  libiniparser1 libinput-bin libinput10 libisl23 libitm1 libjs-jquery libjs-jquery-ui
  liblapack3 liblbfgsb0 liblcms2-2 libllvm20 liblsan0 libmd4c0 libmpc3 libmtdev1t64
  libopengl-dev libopengl0 libopenjp2-7 libpango-1.0-0 libpangocairo-1.0-0 libpangoft2-1.0-0
  libpciaccess0 libpcre2-16-0 libpcre2-8-0 libpixman-1-0 libproxy1v5 libpthread-stubs0-dev
  libqhull-r8.0 libqt5core5t64 libqt5dbus5t64 libqt5designer5 libqt5gui5t64 libqt5help5
  libqt5network5t64 libqt5opengl5t64 libqt5printsupport5t64 libqt5qml5 libqt5qmlmodels5
  libqt5quick5 libqt5sql5-sqlite libqt5sql5t64 libqt5svg5 libqt5test5t64 libqt5waylandclient5
  libqt5waylandcompositor5 libqt5widgets5t64 libqt5xml5t64 libqt6core6t64 libqt6dbus6t64
  libqt6gui6t64 libqt6network6t64 libqt6opengl6t64 libqt6openglwidgets6t64
  libqt6printsupport6t64 libqt6qml6 libqt6qmlmodels6 libqt6quick6 libqt6sql6-sqlite
  libqt6sql6t64 libqt6test6t64 libqt6waylandclient6 libqt6waylandcompositor6
  libqt6waylandeglclienthwintegration6 libqt6waylandeglcompositorhwintegration6
  libqt6widgets6t64 libqt6wlshellintegration6 libqt6xml6t64 libquadmath0 libraqm0 librsvg2-2
  librsvg2-common libsframe1 libsm-dev libsm6 libstdc++-13-dev libstdc++6 libthai-data
  libthai0 libtk8.6 libts0t64 libtsan2 libtsk19t64 libubsan1 libvhdi1 libvmdk1 libvulkan1
  libwacom-common libwacom9 libwayland-client0 libwayland-cursor0 libwayland-egl1
  libwayland-server0 libwebpdemux2 libwebpmux3 libx11-dev libx11-xcb1 libxau-dev libxcb-dri3-0
  libxcb-glx0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-present0 libxcb-randr0
  libxcb-render-util0 libxcb-render0 libxcb-shape0 libxcb-shm0 libxcb-sync1 libxcb-util1
  libxcb-xfixes0 libxcb-xinerama0 libxcb-xinput0 libxcb-xkb1 libxcb1-dev libxcomposite1
  libxcursor1 libxdamage1 libxdmcp-dev libxext-dev libxfixes3 libxft2 libxi6 libxinerama1
  libxkbcommon-x11-0 libxrandr2 libxrender1 libxshmfence1 libxss1 libxt-dev libxt6t64 libxtst6
  libxxf86vm1 mesa-libgallium mesa-vulkan-drivers mtd-utils ncompress p7zip pyqt5-dev-tools
  pyqt6-dev-tools python-matplotlib-data python3-appdirs python3-binwalk python3-brotli
  python3-bs4 python3-contourpy python3-cssselect python3-cycler python3-dateutil
  python3-decorator python3-fonttools python3-fs python3-html5lib python3-kiwisolver
  python3-lxml python3-lz4 python3-matplotlib python3-mpmath python3-numpy python3-olefile
  python3-opengl python3-packaging python3-pil python3-pil.imagetk python3-pyqt5
  python3-pyqt5.qtopengl python3-pyqt5.sip python3-pyqt6 python3-pyqt6.sip python3-pyqtgraph
  python3-scipy python3-soupsieve python3-sympy python3-tk python3-ufolib2
  python3-unicodedata2 python3-webencodings python3-zombie-imp qt5-gtk-platformtheme
  qt6-base-dev-tools qt6-gtk-platformtheme qt6-qpa-plugins qt6-translations-l10n qt6-wayland
  qtbase5-dev-tools qtchooser qttranslations5-l10n qtwayland5 session-migration sleuthkit
  tk8.6-blt2.5 ubuntu-mono unicode-data x11-common x11proto-dev xorg-sgml-doctools xtrans-dev
Suggested packages:
  7zip-standalone 7zip-rar binutils-doc gprofng-gui blt-demo bzip2-doc cpp-doc gcc-13-locales
  cpp-13-doc g++-multilib g++-13-multilib gcc-13-doc gcc-multilib make autoconf automake
  libtool flex bison gdb gcc-doc gcc-13-multilib gdb-x86-64-linux-gnu apache2 | lighttpd
  | httpd colord cups-common gvfs libice-doc libjs-jquery-ui-docs liblcms2-utils
  qgnomeplatform-qt5 qt5-image-formats-plugins qt5-qmltooling-plugins qt6-qmltooling-plugins
  librsvg2-bin libsm-doc libstdc++-13-doc tk8.6 libwacom-bin libx11-doc libxcb-doc libxext-doc
  libxt-doc python-cycler-doc python3-genshi python-lxml-doc cm-super-minimal dvipng ffmpeg
  fonts-staypuft ghostscript gir1.2-gtk-3.0 inkscape ipython3 python3-cairocffi
  python3-gi-cairo python3-gobject python3-sip python3-tornado texlive-extra-utils
  texlive-latex-extra python-mpmath-doc python3-gmpy2 gfortran python3-dev python3-pytest
  libgle3 python-pil-doc python-pyqtgraph-doc python-scipy-doc texlive-fonts-extra
  python-sympy-doc tix python3-tk-dbg cmake autopsy mac-robber
The following NEW packages will be installed:
  7zip adwaita-icon-theme arj at-spi2-common at-spi2-core binutils binutils-common
  binutils-x86-64-linux-gnu binwalk blt bzip2 cpp cpp-13 cpp-13-x86-64-linux-gnu
  cpp-x86-64-linux-gnu cramfsswap dconf-gsettings-backend dconf-service fontconfig fonts-lyx
  g++ g++-13 g++-13-x86-64-linux-gnu g++-x86-64-linux-gnu gcc gcc-13 gcc-13-base
  gcc-13-x86-64-linux-gnu gcc-x86-64-linux-gnu gsettings-desktop-schemas gtk-update-icon-cache
  hicolor-icon-theme humanity-icon-theme isympy-common isympy3 javascript-common libafflib0t64
  libasan8 libatk-bridge2.0-0t64 libatk1.0-0t64 libatomic1 libatspi2.0-0t64 libavahi-client3
  libavahi-common-data libavahi-common3 libb2-1 libbfio1 libbinutils libblas3
  libcairo-gobject2 libcairo2 libcc1-0 libcolord2 libctf-nobfd0 libctf0 libcups2t64
  libdate-manip-perl libdatrie1 libdconf1 libdouble-conversion3 libdrm-amdgpu1 libdrm-intel1
  libegl-dev libegl-mesa0 libegl1 libepoxy0 libewf2 libgbm1 libgcc-13-dev libgdk-pixbuf-2.0-0
  libgdk-pixbuf2.0-bin libgdk-pixbuf2.0-common libgfortran5 libgl-dev libgl1 libgl1-mesa-dev
  libgl1-mesa-dri libgles-dev libgles1 libgles2 libglu1-mesa libglu1-mesa-dev libglut-dev
  libglut3.12 libglvnd-core-dev libglvnd-dev libglvnd0 libglx-dev libglx-mesa0 libglx0
  libgomp1 libgprofng0 libgraphite2-3 libgtk-3-0t64 libgtk-3-bin libgtk-3-common libharfbuzz0b
  libhwasan0 libice-dev libice6 libimagequant0 libiniparser1 libinput-bin libinput10 libisl23
  libitm1 libjs-jquery libjs-jquery-ui liblapack3 liblbfgsb0 liblcms2-2 libllvm20 liblsan0
  libmd4c0 libmpc3 libmtdev1t64 libopengl-dev libopengl0 libopenjp2-7 libpango-1.0-0
  libpangocairo-1.0-0 libpangoft2-1.0-0 libpciaccess0 libpcre2-16-0 libpixman-1-0 libproxy1v5
  libpthread-stubs0-dev libqhull-r8.0 libqt5core5t64 libqt5dbus5t64 libqt5designer5
  libqt5gui5t64 libqt5help5 libqt5network5t64 libqt5opengl5t64 libqt5printsupport5t64
  libqt5qml5 libqt5qmlmodels5 libqt5quick5 libqt5sql5-sqlite libqt5sql5t64 libqt5svg5
  libqt5test5t64 libqt5waylandclient5 libqt5waylandcompositor5 libqt5widgets5t64 libqt5xml5t64
  libqt6core6t64 libqt6dbus6t64 libqt6gui6t64 libqt6network6t64 libqt6opengl6t64
  libqt6openglwidgets6t64 libqt6printsupport6t64 libqt6qml6 libqt6qmlmodels6 libqt6quick6
  libqt6sql6-sqlite libqt6sql6t64 libqt6test6t64 libqt6waylandclient6 libqt6waylandcompositor6
  libqt6waylandeglclienthwintegration6 libqt6waylandeglcompositorhwintegration6
  libqt6widgets6t64 libqt6wlshellintegration6 libqt6xml6t64 libquadmath0 libraqm0 librsvg2-2
  librsvg2-common libsframe1 libsm-dev libsm6 libstdc++-13-dev libthai-data libthai0 libtk8.6
  libts0t64 libtsan2 libtsk19t64 libubsan1 libvhdi1 libvmdk1 libvulkan1 libwacom-common
  libwacom9 libwayland-client0 libwayland-cursor0 libwayland-egl1 libwayland-server0
  libwebpdemux2 libwebpmux3 libx11-dev libx11-xcb1 libxau-dev libxcb-dri3-0 libxcb-glx0
  libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-present0 libxcb-randr0
  libxcb-render-util0 libxcb-render0 libxcb-shape0 libxcb-shm0 libxcb-sync1 libxcb-util1
  libxcb-xfixes0 libxcb-xinerama0 libxcb-xinput0 libxcb-xkb1 libxcb1-dev libxcomposite1
  libxcursor1 libxdamage1 libxdmcp-dev libxext-dev libxfixes3 libxft2 libxi6 libxinerama1
  libxkbcommon-x11-0 libxrandr2 libxrender1 libxshmfence1 libxss1 libxt-dev libxt6t64 libxtst6
  libxxf86vm1 mesa-libgallium mesa-vulkan-drivers mtd-utils ncompress p7zip pyqt5-dev-tools
  pyqt6-dev-tools python-matplotlib-data python3-appdirs python3-binwalk python3-brotli
  python3-bs4 python3-contourpy python3-cssselect python3-cycler python3-dateutil
  python3-decorator python3-fonttools python3-fs python3-html5lib python3-kiwisolver
  python3-lxml python3-lz4 python3-matplotlib python3-mpmath python3-numpy python3-olefile
  python3-opengl python3-packaging python3-pil python3-pil.imagetk python3-pyqt5
  python3-pyqt5.qtopengl python3-pyqt5.sip python3-pyqt6 python3-pyqt6.sip python3-pyqtgraph
  python3-scipy python3-soupsieve python3-sympy python3-tk python3-ufolib2
  python3-unicodedata2 python3-webencodings python3-zombie-imp qt5-gtk-platformtheme
  qt6-base-dev-tools qt6-gtk-platformtheme qt6-qpa-plugins qt6-translations-l10n qt6-wayland
  qtbase5-dev-tools qtchooser qttranslations5-l10n qtwayland5 session-migration sleuthkit
  tk8.6-blt2.5 ubuntu-mono unicode-data x11-common x11proto-dev xorg-sgml-doctools xtrans-dev
The following packages will be upgraded:
  gcc-14-base libbz2-1.0 libdrm-common libdrm2 libgcc-s1 libpcre2-8-0 libstdc++6
7 upgraded, 296 newly installed, 0 to remove and 328 not upgraded.
Need to get 248 MB of archives.
After this operation, 1,053 MB of additional disk space will be used.
Do you want to continue? [Y/n]

我想念 AlpineLinux APK。

2026-05-03 21:33:44

AlpineLinux 上没有 binwalk 这个包 🤡。

2条评论 页首

对象说便宜买了个得力的温湿度计……

结果没几天就掉地上摔了个狗吃屎,这质量……

老实说,我已经很多很多年没有见过这种“牛屎”型封装的芯片了,成本节省到了极致。

2条评论 页首

日子也是好起来了,居然吃上大龙虾了

这应该是第二次吃吧,第一次是2024年在埃及的赫尔格达。

这龙虾还真好看,身体竟然是彩色的。

没有评论 页首

强如苹果词典中的牛津词典对“Attack”在乐理中的含义也没有比较准确的释义,难怪八年前我看着全英文的百科一头雾水。

“Envelope”是另外一个当时完全不知道如何理解的词。

不然的话,音乐的模拟怎么也不应该缺席。不会只写了个开头就八年没再动过了。当然,现在更不会有时间去研究了。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package main

/*
 $4000~$4013, $4015, $4017

 5个通道:两个脉冲波、一个三角波、一个噪声、一个DPCM
*/

type APU struct {
}

type Triangle struct {
	enabled     bool
	counterLoad byte
	timer       uint16
}

项目地址:movsb/taones。

没有评论 页首