希望本文对反编译器或混淆器后解析别人的代码或其他代码有帮助。
如果您仍然不知道IOCCC是什么,或者想熟悉混淆代码的简单版本,那么我建议您参考第一部分。
对于其他所有人,祝您阅读愉快。
所有资源都放置在github上,您可以从那里下载它们并尝试对其进行编译。
初始数据
由于可以在链接中找到文本形式的源代码,因此我将显示代码的图形外观:
传统上,如果代码格式非标准或看起来像某种图像,则会给出“加分”。好吧,让我们假设这没问题。
但是该程序做什么?
它初始化X服务器图形堆栈,扫描提供的配置文件,根据该文件绘制电气图并开始仿真,仅使用NOR(非或)元素交替改变4个输入引脚上的极性。渲染是使用旧的LCD屏幕着色器完成的。
该程序带有几个配置文件,即:
DIP8-4packnot.txt-CMOS 4041 /四通道逆变器的近似模拟
(将图像压缩2倍以适应体面的限制。有趣的是,该程序重3.5 KB,生成一系列图像,最大压缩量为10.5 + MB)
DIP8-triplexor.txt-具有组合输入和三通道/具有组合输入的三通道XOR门的CMOS 4030的近似模拟
DIP8-fulladder.txt-CMOS 4008的近似模拟,但为两位/加法器为2位,带有进位输出
解析代码
这次最困难的任务是适应所提交作品的大小限制。不仅文件大小受到限制,而且条件“令牌”的数量也受到限制-操作符号,语言关键字和括号对。为了“利用”程序中的大小分析器检查器的这一功能,需要声明大量的定义,这些定义将代码块引导至单个C关键字:
首先,让我们看一下Makefile,以了解代码的汇编方式:
#!/usr/bin/env make
PROJECT=prog
CC= gcc
SRC=prog.c
CWARN=-Wall -Wextra -Wno-char-subscripts
CSTD= -std=c99
# Syscalls table
# DS - syscall nanosleep
# DO - syscall open
# DR - syscall read
# DC - syscall close
# X11 structures offsets
# dS - offset of screens in Display
# dR - offset of root in Screen
# dD - offset of root_depth in Screen
# dV - offset of root_visual in Screen
# dG - offset of default_gc in Screen
BITS := $(shell uname -p)
ifeq ($(BITS), x86_64)
ARCH= -m64
CDEFINE= -DDS=35 -DDO=2 -DDR=0 -DDC=3 -DdS=232 -DdR=16 -DdD=56 -DdV=64 -DdG=72
else
ARCH= -m32
CDEFINE= -DDS=162 -DDO=5 -DDR=3 -DDC=6 -DdS=140 -DdR=8 -DdD=36 -DdV=40 -DdG=44
endif
OPT= -g
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${CDEFINE} ${OPT}
LDFLAGS= -ldl
RM= rm
all: ${PROJECT}
${PROJECT}:
${CC} ${CFLAGS} ${SRC} -o $@ ${LDFLAGS}
clean:
${RM} -f ${PROJECT}
如您所见,这项工作与上一个工作一样,积极地使用系统调用来避免难看的“ #include”破坏图片的图案。让我们记住这一事实,并为预处理器和linter准备一行:
在预处理器之后
gcc -DDS=35 -DDO=2 -DDR=0 -DDC=3 -DdS=232 -DdR=16 -DdD=56 -DdV=64 -DdG=72 prog.c -ldl -E | indent -kr -brf > /tmp/fmt.c
int _x[] = { 15117427, 8413248, 5878632, 13027014, 1 };
extern void *dlsym(void *, char *);
int x_[616][1220];
extern long syscall(long, ...);
extern void *dlopen(char *, int);
char m[19][20], _n[] =
"pu~D--2os" "<<<<<<<<" "<<<DSlyrXuolp}e" "<<<<<<<<"
"D_ny}hyOuqlpyKurxsk<D_ny" "}hyUq}{y" "<<<<<<<<" "DLihUq}{y" "<<<<<<<<"
"<<<DQ}lKurxsk" "<<<<<<<<" "<<DZpiot<";
long w, N[2] = { 0, 1 << 29 };
int rn = 2166136261, _[8][40][64] = { 0 };
long R[2];
void *M, *d, *T;
void b(int t, int x, int y, int c, int l) {
if ((x >= 19 || y >= 19 || x < 0 || y < 0) || (m[y][x] == l)
|| (m[y][x] != c))
return;
m[y][x] = l;
b(t, x - 1, y, c, l);
b(t, x + 1, y, c, l);
b(t, x, y - 1, c, l);
b(t, x, y + 1, c, l);
}
void e(int t, int x, int y, int c, int l) {
if ((x >= 64 || y >= 40 || x < 0 || y < 0) || (_[t][y][x] == l)
|| (_[t][y][x] != c))
return;
_[t][y][x] = l;
e(t, x - 1, y, c, l);
e(t, x + 1, y, c, l);
e(t, x, y - 1, c, l);
e(t, x, y + 1, c, l);
}
void k(int t, int x, int y, int c, int l) {
while (c--) {
_[t][y][x++] = l;
_[t][y++][x++] = l;
}
}
void r(int t, int x, int y, int c, int l) {
while (c--) {
_[t][y][x--] = l;
_[t][y++][x--] = l;
}
}
void u(int t, int x, int y, int c, int l) {
while (c--)
_[t][y++][x] = l;
}
char *z[8] = {
(char[]) {4},
(char[]) {6, 1 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16, 0, 0,
21 + 0 * 3 - 0, 16, 1, 63, 21 + 0 * 3 - 0, 16, 2,
63 * 0, 21 - 0, 4, 2, 31 + 0, 36 - 0, 4, 0 + 1,
32 - 1, 5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1, 63,
21 + 1 * 3 - 0, 16, 2, 63 * 1, 21 - 0, 4, 2, 31 + 1,
36 - 0, 4, 6, 1 * 4 + 0, 3, 31, 8 - 0, 6, 1 * 4 + 2,
3, 33, 38 - 0, 6, 1 * 4 + 3, 3, 30, 38 - 0, 4},
(char[]) {5, 1},
(char[]) {6, 0 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16,
0, 0, 21 + 0 * 3 - 0, 16, 1, 63,
21 + 0 * 3 - 0, 16, 2, 63 * 0, 21 - 0,
4, 2, 31 + 0, 36 - 0, 4, 0 + 1, 32 - 1,
5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1,
63, 21 + 1 * 3 - 0, 16, 2, 63 * 1,
21 - 0, 4, 2, 31 + 1, 36 - 0, 4, 6,
0 * 4 + 0, 3, 31, 8 - 0, 6, 0 * 4 + 2,
3, 33, 38 - 0, 6, 0 * 4 + 3, 3, 30,
38 - 0,
4},
(char[]) {4}, (char[]) {4},
(char[]) {6, 2 * 4 + 1, 0 + 0, 32 - 0, 5 - 3, 16, 0, 0,
21 + 0 * 3 - 3, 16, 1, 63, 21 + 0 * 3 - 3, 16, 2, 63 * 0,
21 - 3, 4, 2, 31 + 0, 36 - 3, 4, 0 + 1, 32 - 1, 5 - 3,
16, 0, 0, 21 + 1 * 3 - 3, 16, 1, 63, 21 + 1 * 3 - 3, 16,
2, 63 * 1, 21 - 3, 4, 2, 31 + 1, 36 - 3, 4, 6, 2 * 4 + 0,
3, 31, 8 - 3, 6, 2 * 4 + 2, 3, 33, 38 - 3, 6, 2 * 4 + 3,
3, 30, 38 - 3, 4},
(char[]) {6, 13, 0, 32, 9 + 0, 12 - 0,
0, 8 + 0 + 0, 21, 12 - 0, 1,
31, 9 + 0, 12 - 0, 1,
55 - 0 - 0, 21, 12 - 0, 0,
32, 9 + 3, 12 - 3, 0,
8 + 3 + 3, 21, 12 - 3, 1,
31, 9 + 3, 12 - 3, 1,
55 - 3 - 3, 21, 12 - 3, 6,
14 + 0, 2, 31 + 0, 13, 4,
1 - 0, 31 + 0, 16, 7, 3,
30 + 3 * 0, 14, 6,
12 + 0 * 4, 3, 32 - 0,
11 + 0 * 8, 6, 14 + 1, 2,
31 + 1, 13, 4, 1 - 1,
31 + 1, 16, 7, 3,
30 + 3 * 1, 14, 6,
12 + 1 * 4, 3, 32 - 1,
11 + 1 * 8,
4}
};
void d_(int t, int p, int q) {
for (int y = 0; y < 40; y++)
for (int x = 0; x < 64; x++)
if (_[t]
[y][x])
x_[y + q * 16 + p * 16][x + 580 + p * 32 - q *
32] = _[t][y][x];
}
int main(int a, char *s[]) {
int h = 127;
while (h--) {
_n[h] ^= 28;
_n[h] -= (_n[h] == 32 ? 32 : 0);
}
T = dlopen(_n, 2);
d = ((void *(*)()) dlsym(T, _n + (1 * 20))) (0);
w = ((long (*)()) dlsym(T, _n + (2 * 20))) (d,
(*(long *)
((char
*) (*(long *) ((char *)
d +
232)) +
16))
, 0, 0, 1220, 616, 1, 0,
0);
M = ((void *(*)()) dlsym(T, _n + (3 * 20))) (d,
(*(long *)
((char
*) (*(long *) ((char *)
d +
232)) +
64)),
(*(long *)
((char
*) (*(long *) ((char *)
d +
232)) +
56)), 2, 0, (char *) x_,
1220, 616, 32, 0);
for (int i = 0; i < 8; i++) {
char *p = z[i];
int c = 0;
while (*p != 4) {
switch (*p) {
case 0:
k(i, p[1], p[2], p[3], c);
p += 4;
break;
case 1:
r(i, p[1], p[2], p[3], c);
p += 4;
break;
case 2:
u(i, p[1], p[2], p[3], c);
p += 4;
break;
case 3:
e(i, p[1]
, p[2], 0, c);
p += 3;
break;
case 5:
p = z[p[1]];
break;
case 6:
c = _x[p[1] / 4] - 1643277 * (p[1] % 4);
p += 2;
break;
}
}
}
while (a++) {
int f = syscall(2, s[1], 0);
syscall(0, f, m, 380);
syscall(3, f);
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
if ((x % 14 == 2) && (y % 4 == 3))
m[y][x] = 46;
b(0, 2, 3, m[3][2], a & 1 ? 43 : 45);
b(0, 2, 7, m[7][2], a & 2 ? 43 : 45);
b(0, 2, 11, m[11][2], a & 4 ? 43 : 45);
b(0, 2, 15, m[15][2], a & 8 ? 43 : 45);
for (int i = 0; i < 20; i++)
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
if (m[y][x] == 62)
b(0, x + 1, y, m[y][x + 1],
!(m[y - 1][x] == 43 ? 1 : 0
|| m[y + 1][x] == 43 ? 1 : 0) ? 43 : 45);
for (int y = 0; y < 616; y++)
for (int x = 0; x < 1220; x++)
x_[y][x] = 0;
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
d_(((m[y][x] >> 4) & 1) << 2 | (m[y][x] & 3), x, y);
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
if ((x % 14 == 2) && (y % 4 == 3))
d_(7, x, y);
for (int y = 0; y < 616; y++)
for (int x = 0; x < 1220; x++) {
x_[y][x] &= 14737632 | (31 << ((x % 3) << 3));
x_[y][x] += 986895 & (rn *= 16777619);
} ((long (*)()) dlsym(T, _n + (4 * 20))) (d, w,
(*(long *)
((char
*) (*(long
*) ((char *)
d +
232)) +
72)), M, 0, 0, 0,
0, 1220, 616);
((long (*)()) dlsym(T, _n + (5 * 20))) (d, w);
((long (*)()) dlsym(T, _n + (6 * 20))) (d);
syscall(35, &N, &R);
} return 0;
}
好吧,我们至少满足了比赛的条件之一,预处理器之后的代码没有变得更加清晰。
让我们从一目了然开始,尝试重建事件链。
dlsym \ dlopen
显然,为了使用X服务器的功能并创建一个窗口,然后在其中绘制内容,代码必须转到XLib库。该代码包含dlopen / dlsym函数,这些函数允许您动态加载库,但是在输入时会遇到一些棘手的问题:
char _n[] =
"pu~D--2os" "<<<<<<<<" "<<<DSlyrXuolp}e" "<<<<<<<<"
"D_ny}hyOuqlpyKurxsk<D_ny" "}hyUq}{y" "<<<<<<<<" "DLihUq}{y" "<<<<<<<<"
"<<<DQ}lKurxsk" "<<<<<<<<" "<<DZpiot<";
...
T = dlopen(_n, 2);
让我们退后一步,检查以下代码:
int h = 127;
while (h--) {
_n[h] ^= 28;
_n[h] -= (_n[h] == 32 ? 32 : 0);
}
显然,它以某种方式转换了原始数组,使我们能够获得可读的行。让我们分别执行它:
https : //onlinegdb.com/SJNM9Og7v:
libX11.so
XOpenDisplay
XCreateSimpleWindow
XCreateImage
XPutImage
XMapWindow
XFlush
为了在一行中调用格式如此不同的函数,代码利用了以下事实:在C语言标准中(void)表示没有参数,而()表示任意数量的参数。剩下的只是将产生的void *强制转换为相应的((long(*)())类型和类型:
w = ((long (*)()) dlsym(T, _n + (2 * 20))) (d, (*(long *)((char *) (*(long *)((char *) d + 232)) + 16))
知道了这些转换的含义后,我们现在可以用以下行替换dlsym的这种不寻常用法:
替换行后:
int _x[] = { 15117427, 8413248, 5878632, 13027014, 1 };
extern void *dlsym(void *, char *);
int x_[616][1220];
extern long syscall(long, ...);
extern void *dlopen(char *, int);
char m[19][20];
long w, N[2] = { 0, 1 << 29 };
int rn = 2166136261, _[8][40][64] = { 0 };
long R[2];
void *M, *d, *T;
void b(int t, int x, int y, int c, int l) {
if ((x >= 19 || y >= 19 || x < 0 || y < 0) || (m[y][x] == l)
|| (m[y][x] != c))
return;
m[y][x] = l;
b(t, x - 1, y, c, l);
b(t, x + 1, y, c, l);
b(t, x, y - 1, c, l);
b(t, x, y + 1, c, l);
}
void e(int t, int x, int y, int c, int l) {
if ((x >= 64 || y >= 40 || x < 0 || y < 0) || (_[t][y][x] == l)
|| (_[t][y][x] != c))
return;
_[t][y][x] = l;
e(t, x - 1, y, c, l);
e(t, x + 1, y, c, l);
e(t, x, y - 1, c, l);
e(t, x, y + 1, c, l);
}
void k(int t, int x, int y, int c, int l) {
while (c--) {
_[t][y][x++] = l;
_[t][y++][x++] = l;
}
}
void r(int t, int x, int y, int c, int l) {
while (c--) {
_[t][y][x--] = l;
_[t][y++][x--] = l;
}
}
void u(int t, int x, int y, int c, int l) {
while (c--)
_[t][y++][x] = l;
}
char *z[8] = {
(char[]) {4},
(char[]) {6, 1 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16, 0, 0,
21 + 0 * 3 - 0, 16, 1, 63, 21 + 0 * 3 - 0, 16, 2,
63 * 0, 21 - 0, 4, 2, 31 + 0, 36 - 0, 4, 0 + 1,
32 - 1, 5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1, 63,
21 + 1 * 3 - 0, 16, 2, 63 * 1, 21 - 0, 4, 2, 31 + 1,
36 - 0, 4, 6, 1 * 4 + 0, 3, 31, 8 - 0, 6, 1 * 4 + 2,
3, 33, 38 - 0, 6, 1 * 4 + 3, 3, 30, 38 - 0, 4},
(char[]) {5, 1},
(char[]) {6, 0 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16,
0, 0, 21 + 0 * 3 - 0, 16, 1, 63,
21 + 0 * 3 - 0, 16, 2, 63 * 0, 21 - 0,
4, 2, 31 + 0, 36 - 0, 4, 0 + 1, 32 - 1,
5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1,
63, 21 + 1 * 3 - 0, 16, 2, 63 * 1,
21 - 0, 4, 2, 31 + 1, 36 - 0, 4, 6,
0 * 4 + 0, 3, 31, 8 - 0, 6, 0 * 4 + 2,
3, 33, 38 - 0, 6, 0 * 4 + 3, 3, 30,
38 - 0,
4},
(char[]) {4}, (char[]) {4},
(char[]) {6, 2 * 4 + 1, 0 + 0, 32 - 0, 5 - 3, 16, 0, 0,
21 + 0 * 3 - 3, 16, 1, 63, 21 + 0 * 3 - 3, 16, 2, 63 * 0,
21 - 3, 4, 2, 31 + 0, 36 - 3, 4, 0 + 1, 32 - 1, 5 - 3,
16, 0, 0, 21 + 1 * 3 - 3, 16, 1, 63, 21 + 1 * 3 - 3, 16,
2, 63 * 1, 21 - 3, 4, 2, 31 + 1, 36 - 3, 4, 6, 2 * 4 + 0,
3, 31, 8 - 3, 6, 2 * 4 + 2, 3, 33, 38 - 3, 6, 2 * 4 + 3,
3, 30, 38 - 3, 4},
(char[]) {6, 13, 0, 32, 9 + 0, 12 - 0,
0, 8 + 0 + 0, 21, 12 - 0, 1,
31, 9 + 0, 12 - 0, 1,
55 - 0 - 0, 21, 12 - 0, 0,
32, 9 + 3, 12 - 3, 0,
8 + 3 + 3, 21, 12 - 3, 1,
31, 9 + 3, 12 - 3, 1,
55 - 3 - 3, 21, 12 - 3, 6,
14 + 0, 2, 31 + 0, 13, 4,
1 - 0, 31 + 0, 16, 7, 3,
30 + 3 * 0, 14, 6,
12 + 0 * 4, 3, 32 - 0,
11 + 0 * 8, 6, 14 + 1, 2,
31 + 1, 13, 4, 1 - 1,
31 + 1, 16, 7, 3,
30 + 3 * 1, 14, 6,
12 + 1 * 4, 3, 32 - 1,
11 + 1 * 8,
4}
};
void d_(int t, int p, int q) {
for (int y = 0; y < 40; y++)
for (int x = 0; x < 64; x++)
if (_[t]
[y][x])
x_[y + q * 16 + p * 16][x + 580 + p * 32 - q *
32] = _[t][y][x];
}
int main(int a, char *s[]) {
T = dlopen("libX11.so", 2);
d = ((void *(*)()) dlsym(T, "XOpenDisplay") (0);
w = ((long (*)()) dlsym(T, "XCreateSimpleWindow")) (d,
(*(long *)
((char
*) (*(long *) ((char *)
d +
232)) +
16))
, 0, 0, 1220, 616, 1, 0,
0);
M = ((void *(*)()) dlsym(T, "XCreateImage")) (d,
(*(long *)
((char
*) (*(long *) ((char *)
d +
232)) +
64)),
(*(long *)
((char
*) (*(long *) ((char *)
d +
232)) +
56)), 2, 0, (char *) x_,
1220, 616, 32, 0);
for (int i = 0; i < 8; i++) {
char *p = z[i];
int c = 0;
while (*p != 4) {
switch (*p) {
case 0:
k(i, p[1], p[2], p[3], c);
p += 4;
break;
case 1:
r(i, p[1], p[2], p[3], c);
p += 4;
break;
case 2:
u(i, p[1], p[2], p[3], c);
p += 4;
break;
case 3:
e(i, p[1]
, p[2], 0, c);
p += 3;
break;
case 5:
p = z[p[1]];
break;
case 6:
c = _x[p[1] / 4] - 1643277 * (p[1] % 4);
p += 2;
break;
}
}
}
while (a++) {
int f = syscall(2, s[1], 0);
syscall(0, f, m, 380);
syscall(3, f);
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
if ((x % 14 == 2) && (y % 4 == 3))
m[y][x] = 46;
b(0, 2, 3, m[3][2], a & 1 ? 43 : 45);
b(0, 2, 7, m[7][2], a & 2 ? 43 : 45);
b(0, 2, 11, m[11][2], a & 4 ? 43 : 45);
b(0, 2, 15, m[15][2], a & 8 ? 43 : 45);
for (int i = 0; i < 20; i++)
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
if (m[y][x] == 62)
b(0, x + 1, y, m[y][x + 1],
!(m[y - 1][x] == 43 ? 1 : 0
|| m[y + 1][x] == 43 ? 1 : 0) ? 43 : 45);
for (int y = 0; y < 616; y++)
for (int x = 0; x < 1220; x++)
x_[y][x] = 0;
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
d_(((m[y][x] >> 4) & 1) << 2 | (m[y][x] & 3), x, y);
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
if ((x % 14 == 2) && (y % 4 == 3))
d_(7, x, y);
for (int y = 0; y < 616; y++)
for (int x = 0; x < 1220; x++) {
x_[y][x] &= 14737632 | (31 << ((x % 3) << 3));
x_[y][x] += 986895 & (rn *= 16777619);
} ((long (*)()) dlsym(T, "XPutImage")) (d, w,
(*(long *)
((char
*) (*(long
*) ((char *)
d +
232)) +
72)), M, 0, 0, 0,
0, 1220, 616);
((long (*)()) dlsym(T, "XMapWindow")) (d, w);
((long (*)()) dlsym(T, "XFlush")) (d);
syscall(35, &N, &R);
} return 0;
}
然后到本机函数:
用``native''函数替换后:
#include <X11/Xlib.h>
int _x[] = { 15117427, 8413248, 5878632, 13027014, 1 };
int x_[616][1220];
extern long syscall(long, ...);
char m[19][20];
long w, N[2] = { 0, 1 << 29 };
int rn = 2166136261, _[8][40][64] = { 0 };
long R[2];
void *M, *d, *T;
void b(int t, int x, int y, int c, int l) {
if ((x >= 19 || y >= 19 || x < 0 || y < 0) || (m[y][x] == l)
|| (m[y][x] != c))
return;
m[y][x] = l;
b(t, x - 1, y, c, l);
b(t, x + 1, y, c, l);
b(t, x, y - 1, c, l);
b(t, x, y + 1, c, l);
}
void e(int t, int x, int y, int c, int l) {
if ((x >= 64 || y >= 40 || x < 0 || y < 0) || (_[t][y][x] == l)
|| (_[t][y][x] != c))
return;
_[t][y][x] = l;
e(t, x - 1, y, c, l);
e(t, x + 1, y, c, l);
e(t, x, y - 1, c, l);
e(t, x, y + 1, c, l);
}
void k(int t, int x, int y, int c, int l) {
while (c--) {
_[t][y][x++] = l;
_[t][y++][x++] = l;
}
}
void r(int t, int x, int y, int c, int l) {
while (c--) {
_[t][y][x--] = l;
_[t][y++][x--] = l;
}
}
void u(int t, int x, int y, int c, int l) {
while (c--)
_[t][y++][x] = l;
}
char *z[8] = {
(char[]) {4},
(char[]) {6, 1 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16, 0, 0,
21 + 0 * 3 - 0, 16, 1, 63, 21 + 0 * 3 - 0, 16, 2,
63 * 0, 21 - 0, 4, 2, 31 + 0, 36 - 0, 4, 0 + 1,
32 - 1, 5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1, 63,
21 + 1 * 3 - 0, 16, 2, 63 * 1, 21 - 0, 4, 2, 31 + 1,
36 - 0, 4, 6, 1 * 4 + 0, 3, 31, 8 - 0, 6, 1 * 4 + 2,
3, 33, 38 - 0, 6, 1 * 4 + 3, 3, 30, 38 - 0, 4},
(char[]) {5, 1},
(char[]) {6, 0 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16,
0, 0, 21 + 0 * 3 - 0, 16, 1, 63,
21 + 0 * 3 - 0, 16, 2, 63 * 0, 21 - 0,
4, 2, 31 + 0, 36 - 0, 4, 0 + 1, 32 - 1,
5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1,
63, 21 + 1 * 3 - 0, 16, 2, 63 * 1,
21 - 0, 4, 2, 31 + 1, 36 - 0, 4, 6,
0 * 4 + 0, 3, 31, 8 - 0, 6, 0 * 4 + 2,
3, 33, 38 - 0, 6, 0 * 4 + 3, 3, 30,
38 - 0,
4},
(char[]) {4}, (char[]) {4},
(char[]) {6, 2 * 4 + 1, 0 + 0, 32 - 0, 5 - 3, 16, 0, 0,
21 + 0 * 3 - 3, 16, 1, 63, 21 + 0 * 3 - 3, 16, 2, 63 * 0,
21 - 3, 4, 2, 31 + 0, 36 - 3, 4, 0 + 1, 32 - 1, 5 - 3,
16, 0, 0, 21 + 1 * 3 - 3, 16, 1, 63, 21 + 1 * 3 - 3, 16,
2, 63 * 1, 21 - 3, 4, 2, 31 + 1, 36 - 3, 4, 6, 2 * 4 + 0,
3, 31, 8 - 3, 6, 2 * 4 + 2, 3, 33, 38 - 3, 6, 2 * 4 + 3,
3, 30, 38 - 3, 4},
(char[]) {6, 13, 0, 32, 9 + 0, 12 - 0,
0, 8 + 0 + 0, 21, 12 - 0, 1,
31, 9 + 0, 12 - 0, 1,
55 - 0 - 0, 21, 12 - 0, 0,
32, 9 + 3, 12 - 3, 0,
8 + 3 + 3, 21, 12 - 3, 1,
31, 9 + 3, 12 - 3, 1,
55 - 3 - 3, 21, 12 - 3, 6,
14 + 0, 2, 31 + 0, 13, 4,
1 - 0, 31 + 0, 16, 7, 3,
30 + 3 * 0, 14, 6,
12 + 0 * 4, 3, 32 - 0,
11 + 0 * 8, 6, 14 + 1, 2,
31 + 1, 13, 4, 1 - 1,
31 + 1, 16, 7, 3,
30 + 3 * 1, 14, 6,
12 + 1 * 4, 3, 32 - 1,
11 + 1 * 8,
4}
};
void d_(int t, int p, int q) {
for (int y = 0; y < 40; y++)
for (int x = 0; x < 64; x++)
if (_[t]
[y][x])
x_[y + q * 16 + p * 16][x + 580 + p * 32 - q *
32] = _[t][y][x];
}
int main(int a, char *s[]) {
d = XOpenDisplay(0);
w = XCreateSimpleWindow(d, (*(long *) ((char *) (*(long *) ((char *)d + 232)) + 16)), 0, 0, 1220, 616, 1, 0, 0);
M = XCreateImage(d, (*(long *)((char *) (*(long *) ((char *)d + 232)) + 64)), (*(long *)((char *) (*(long *) ((char *)d + 232)) + 56)), 2, 0, (char *) x_, 1220, 616, 32, 0);
for (int i = 0; i < 8; i++) {
char *p = z[i];
int c = 0;
while (*p != 4) {
switch (*p) {
case 0:
k(i, p[1], p[2], p[3], c);
p += 4;
break;
case 1:
r(i, p[1], p[2], p[3], c);
p += 4;
break;
case 2:
u(i, p[1], p[2], p[3], c);
p += 4;
break;
case 3:
e(i, p[1]
, p[2], 0, c);
p += 3;
break;
case 5:
p = z[p[1]];
break;
case 6:
c = _x[p[1] / 4] - 1643277 * (p[1] % 4);
p += 2;
break;
}
}
}
while (a++) {
int f = syscall(2, s[1], 0);
syscall(0, f, m, 380);
syscall(3, f);
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
if ((x % 14 == 2) && (y % 4 == 3))
m[y][x] = 46;
b(0, 2, 3, m[3][2], a & 1 ? 43 : 45);
b(0, 2, 7, m[7][2], a & 2 ? 43 : 45);
b(0, 2, 11, m[11][2], a & 4 ? 43 : 45);
b(0, 2, 15, m[15][2], a & 8 ? 43 : 45);
for (int i = 0; i < 20; i++)
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
if (m[y][x] == 62)
b(0, x + 1, y, m[y][x + 1],
!(m[y - 1][x] == 43 ? 1 : 0
|| m[y + 1][x] == 43 ? 1 : 0) ? 43 : 45);
for (int y = 0; y < 616; y++)
for (int x = 0; x < 1220; x++)
x_[y][x] = 0;
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
d_(((m[y][x] >> 4) & 1) << 2 | (m[y][x] & 3), x, y);
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
if ((x % 14 == 2) && (y % 4 == 3))
d_(7, x, y);
for (int y = 0; y < 616; y++)
for (int x = 0; x < 1220; x++) {
x_[y][x] &= 14737632 | (31 << ((x % 3) << 3));
x_[y][x] += 986895 & (rn *= 16777619);
}
XPutImage(d, w, (*(long *)((char *) (*(long *) ((char *)d + 232)) + 72)), M, 0, 0, 0, 0, 1220, 616);
XMapWindow(d, w);
XFlush(d);
syscall(35, &N, &R);
}
return 0;
}
系统调用
让我们以与第一部分相同的方式替换系统调用:
不带系统调用的代码:
#include <X11/Xlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int _x[] = { 15117427, 8413248, 5878632, 13027014, 1 };
int x_[616][1220];
char m[19][20];
long w;
int rn = 2166136261, _[8][40][64] = { 0 };
void *M, *d, *T;
void b(int t, int x, int y, int c, int l) {
if ((x >= 19 || y >= 19 || x < 0 || y < 0) || (m[y][x] == l)
|| (m[y][x] != c))
return;
m[y][x] = l;
b(t, x - 1, y, c, l);
b(t, x + 1, y, c, l);
b(t, x, y - 1, c, l);
b(t, x, y + 1, c, l);
}
void e(int t, int x, int y, int c, int l) {
if ((x >= 64 || y >= 40 || x < 0 || y < 0) || (_[t][y][x] == l)
|| (_[t][y][x] != c))
return;
_[t][y][x] = l;
e(t, x - 1, y, c, l);
e(t, x + 1, y, c, l);
e(t, x, y - 1, c, l);
e(t, x, y + 1, c, l);
}
void k(int t, int x, int y, int c, int l) {
while (c--) {
_[t][y][x++] = l;
_[t][y++][x++] = l;
}
}
void r(int t, int x, int y, int c, int l) {
while (c--) {
_[t][y][x--] = l;
_[t][y++][x--] = l;
}
}
void u(int t, int x, int y, int c, int l) {
while (c--)
_[t][y++][x] = l;
}
char *z[8] = {
(char[]) {4},
(char[]) {6, 1 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16, 0, 0,
21 + 0 * 3 - 0, 16, 1, 63, 21 + 0 * 3 - 0, 16, 2,
63 * 0, 21 - 0, 4, 2, 31 + 0, 36 - 0, 4, 0 + 1,
32 - 1, 5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1, 63,
21 + 1 * 3 - 0, 16, 2, 63 * 1, 21 - 0, 4, 2, 31 + 1,
36 - 0, 4, 6, 1 * 4 + 0, 3, 31, 8 - 0, 6, 1 * 4 + 2,
3, 33, 38 - 0, 6, 1 * 4 + 3, 3, 30, 38 - 0, 4},
(char[]) {5, 1},
(char[]) {6, 0 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16,
0, 0, 21 + 0 * 3 - 0, 16, 1, 63,
21 + 0 * 3 - 0, 16, 2, 63 * 0, 21 - 0,
4, 2, 31 + 0, 36 - 0, 4, 0 + 1, 32 - 1,
5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1,
63, 21 + 1 * 3 - 0, 16, 2, 63 * 1,
21 - 0, 4, 2, 31 + 1, 36 - 0, 4, 6,
0 * 4 + 0, 3, 31, 8 - 0, 6, 0 * 4 + 2,
3, 33, 38 - 0, 6, 0 * 4 + 3, 3, 30,
38 - 0,
4},
(char[]) {4}, (char[]) {4},
(char[]) {6, 2 * 4 + 1, 0 + 0, 32 - 0, 5 - 3, 16, 0, 0,
21 + 0 * 3 - 3, 16, 1, 63, 21 + 0 * 3 - 3, 16, 2, 63 * 0,
21 - 3, 4, 2, 31 + 0, 36 - 3, 4, 0 + 1, 32 - 1, 5 - 3,
16, 0, 0, 21 + 1 * 3 - 3, 16, 1, 63, 21 + 1 * 3 - 3, 16,
2, 63 * 1, 21 - 3, 4, 2, 31 + 1, 36 - 3, 4, 6, 2 * 4 + 0,
3, 31, 8 - 3, 6, 2 * 4 + 2, 3, 33, 38 - 3, 6, 2 * 4 + 3,
3, 30, 38 - 3, 4},
(char[]) {6, 13, 0, 32, 9 + 0, 12 - 0,
0, 8 + 0 + 0, 21, 12 - 0, 1,
31, 9 + 0, 12 - 0, 1,
55 - 0 - 0, 21, 12 - 0, 0,
32, 9 + 3, 12 - 3, 0,
8 + 3 + 3, 21, 12 - 3, 1,
31, 9 + 3, 12 - 3, 1,
55 - 3 - 3, 21, 12 - 3, 6,
14 + 0, 2, 31 + 0, 13, 4,
1 - 0, 31 + 0, 16, 7, 3,
30 + 3 * 0, 14, 6,
12 + 0 * 4, 3, 32 - 0,
11 + 0 * 8, 6, 14 + 1, 2,
31 + 1, 13, 4, 1 - 1,
31 + 1, 16, 7, 3,
30 + 3 * 1, 14, 6,
12 + 1 * 4, 3, 32 - 1,
11 + 1 * 8,
4}
};
void d_(int t, int p, int q) {
for (int y = 0; y < 40; y++)
for (int x = 0; x < 64; x++)
if (_[t]
[y][x])
x_[y + q * 16 + p * 16][x + 580 + p * 32 - q *
32] = _[t][y][x];
}
int main(int a, char *s[]) {
d = XOpenDisplay(0);
w = XCreateSimpleWindow(d, (*(long *) ((char *) (*(long *) ((char *)d + 232)) + 16)), 0, 0, 1220, 616, 1, 0, 0);
M = XCreateImage(d, (*(long *)((char *) (*(long *) ((char *)d + 232)) + 64)), (*(long *)((char *) (*(long *) ((char *)d + 232)) + 56)), 2, 0, (char *) x_, 1220, 616, 32, 0);
for (int i = 0; i < 8; i++) {
char *p = z[i];
int c = 0;
while (*p != 4) {
switch (*p) {
case 0:
k(i, p[1], p[2], p[3], c);
p += 4;
break;
case 1:
r(i, p[1], p[2], p[3], c);
p += 4;
break;
case 2:
u(i, p[1], p[2], p[3], c);
p += 4;
break;
case 3:
e(i, p[1]
, p[2], 0, c);
p += 3;
break;
case 5:
p = z[p[1]];
break;
case 6:
c = _x[p[1] / 4] - 1643277 * (p[1] % 4);
p += 2;
break;
}
}
}
while (a++) {
int f = open(s[1], 0);
read(f, m, 380);
close(f);
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
if ((x % 14 == 2) && (y % 4 == 3))
m[y][x] = 46;
b(0, 2, 3, m[3][2], a & 1 ? 43 : 45);
b(0, 2, 7, m[7][2], a & 2 ? 43 : 45);
b(0, 2, 11, m[11][2], a & 4 ? 43 : 45);
b(0, 2, 15, m[15][2], a & 8 ? 43 : 45);
for (int i = 0; i < 20; i++)
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
if (m[y][x] == 62)
b(0, x + 1, y, m[y][x + 1],
!(m[y - 1][x] == 43 ? 1 : 0
|| m[y + 1][x] == 43 ? 1 : 0) ? 43 : 45);
for (int y = 0; y < 616; y++)
for (int x = 0; x < 1220; x++)
x_[y][x] = 0;
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
d_(((m[y][x] >> 4) & 1) << 2 | (m[y][x] & 3), x, y);
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
if ((x % 14 == 2) && (y % 4 == 3))
d_(7, x, y);
for (int y = 0; y < 616; y++)
for (int x = 0; x < 1220; x++) {
x_[y][x] &= 14737632 | (31 << ((x % 3) << 3));
x_[y][x] += 986895 & (rn *= 16777619);
}
XPutImage(d, w, (*(long *)((char *) (*(long *) ((char *)d + 232)) + 72)), M, 0, 0, 0, 0, 1220, 616);
XMapWindow(d, w);
XFlush(d);
sleep(1);
}
return 0;
}
XCreateSimpleWindow和偏移量
让我们尝试分解以下结构:
w = XCreateSimpleWindow(d, (*(long *) ((char *) (*(long *) ((char *)d + 232)) + 16)), 0, 0, 1220, 616, 1, 0, 0);
一堆类型转换,乍一看只需要使读者
感到困惑,但是这里的每个转换都有其自己的用途,即:d是指向Xlib上下文中Display结构的指针。它有一个名为screens的数组字段,为了获得指向该数组第一个元素的指针,我们必须从Display指针开始计算一定数量的字节(x64-232)。由于Display不是char *,因此如果直接读取,我们将以sizeof(long *)个字节进行计算。因此,我们将d强制转换为char *并移动232个字节:
((char *)d + 232)
我们获得了内存中第一个Screens元素的位置。让我们将其转换为完整的指针并取消引用:
(*(long *) ((char *)d + 232))
现在,在Screens结构内部,我们需要获得一个指向根窗口Root的指针。为此,让我们从Screens移开16个字节,并取消引用构造:
(*(long *) ((char *) (*(long *) ((char *)d + 232)) + 16))
Xlib程序员实际上每天都在使用此构造,因为它的常用等效项是
RootWindow(Display, DefaultScreen(Display))
同样,我们将在其他位置替换相应的偏移量,以便获得更熟悉的宏(同时我们将纠正缩进边距):
替换偏移量后的代码:
#include <X11/Xlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int _x[] = { 15117427, 8413248, 5878632, 13027014, 1 };
int x_[616][1220];
char m[19][20];
int rn = 2166136261, _[8][40][64] = { 0 };
void *T;
Display * display;
Window window;
XImage * image;
void b(int t, int x, int y, int c, int l) {
if ((x >= 19 || y >= 19 || x < 0 || y < 0) || (m[y][x] == l)
|| (m[y][x] != c))
return;
m[y][x] = l;
b(t, x - 1, y, c, l);
b(t, x + 1, y, c, l);
b(t, x, y - 1, c, l);
b(t, x, y + 1, c, l);
}
void e(int t, int x, int y, int c, int l) {
if ((x >= 64 || y >= 40 || x < 0 || y < 0) || (_[t][y][x] == l)
|| (_[t][y][x] != c))
return;
_[t][y][x] = l;
e(t, x - 1, y, c, l);
e(t, x + 1, y, c, l);
e(t, x, y - 1, c, l);
e(t, x, y + 1, c, l);
}
void k(int t, int x, int y, int c, int l) {
while (c--) {
_[t][y][x++] = l;
_[t][y++][x++] = l;
}
}
void r(int t, int x, int y, int c, int l) {
while (c--) {
_[t][y][x--] = l;
_[t][y++][x--] = l;
}
}
void u(int t, int x, int y, int c, int l) {
while (c--)
_[t][y++][x] = l;
}
char *z[8] = {
(char[]) {4},
(char[]) {6, 1 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16, 0, 0,
21 + 0 * 3 - 0, 16, 1, 63, 21 + 0 * 3 - 0, 16, 2,
63 * 0, 21 - 0, 4, 2, 31 + 0, 36 - 0, 4, 0 + 1,
32 - 1, 5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1, 63,
21 + 1 * 3 - 0, 16, 2, 63 * 1, 21 - 0, 4, 2, 31 + 1,
36 - 0, 4, 6, 1 * 4 + 0, 3, 31, 8 - 0, 6, 1 * 4 + 2,
3, 33, 38 - 0, 6, 1 * 4 + 3, 3, 30, 38 - 0, 4},
(char[]) {5, 1},
(char[]) {6, 0 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16,
0, 0, 21 + 0 * 3 - 0, 16, 1, 63,
21 + 0 * 3 - 0, 16, 2, 63 * 0, 21 - 0,
4, 2, 31 + 0, 36 - 0, 4, 0 + 1, 32 - 1,
5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1,
63, 21 + 1 * 3 - 0, 16, 2, 63 * 1,
21 - 0, 4, 2, 31 + 1, 36 - 0, 4, 6,
0 * 4 + 0, 3, 31, 8 - 0, 6, 0 * 4 + 2,
3, 33, 38 - 0, 6, 0 * 4 + 3, 3, 30,
38 - 0,
4},
(char[]) {4},
(char[]) {4},
(char[]) {6, 2 * 4 + 1, 0 + 0, 32 - 0, 5 - 3, 16, 0, 0,
21 + 0 * 3 - 3, 16, 1, 63, 21 + 0 * 3 - 3, 16, 2, 63 * 0,
21 - 3, 4, 2, 31 + 0, 36 - 3, 4, 0 + 1, 32 - 1, 5 - 3,
16, 0, 0, 21 + 1 * 3 - 3, 16, 1, 63, 21 + 1 * 3 - 3, 16,
2, 63 * 1, 21 - 3, 4, 2, 31 + 1, 36 - 3, 4, 6, 2 * 4 + 0,
3, 31, 8 - 3, 6, 2 * 4 + 2, 3, 33, 38 - 3, 6, 2 * 4 + 3,
3, 30, 38 - 3, 4},
(char[]) {6, 13, 0, 32, 9 + 0, 12 - 0,
0, 8 + 0 + 0, 21, 12 - 0, 1,
31, 9 + 0, 12 - 0, 1,
55 - 0 - 0, 21, 12 - 0, 0,
32, 9 + 3, 12 - 3, 0,
8 + 3 + 3, 21, 12 - 3, 1,
31, 9 + 3, 12 - 3, 1,
55 - 3 - 3, 21, 12 - 3, 6,
14 + 0, 2, 31 + 0, 13, 4,
1 - 0, 31 + 0, 16, 7, 3,
30 + 3 * 0, 14, 6,
12 + 0 * 4, 3, 32 - 0,
11 + 0 * 8, 6, 14 + 1, 2,
31 + 1, 13, 4, 1 - 1,
31 + 1, 16, 7, 3,
30 + 3 * 1, 14, 6,
12 + 1 * 4, 3, 32 - 1,
11 + 1 * 8,
4}
};
void d_(int t, int p, int q) {
for (int y = 0; y < 40; y++)
for (int x = 0; x < 64; x++)
if (_[t][y][x])
x_[y + q * 16 + p * 16][x + 580 + p * 32 - q * 32] = _[t][y][x];
}
int main(int a, char *s[]) {
display = XOpenDisplay(0);
window = XCreateSimpleWindow(display,
RootWindow(display, DefaultScreen(display)),
0, 0, 1220, 616, 1, 0, 0);
image = XCreateImage(display,
DefaultVisual(display, DefaultScreen(display)),
DefaultDepth(display, DefaultScreen(display)),
2, 0, (char *) x_, 1220, 616, 32, 0);
for (int i = 0; i < 8; i++) {
char *p = z[i];
int c = 0;
while (*p != 4) {
switch (*p) {
case 0:
k(i, p[1], p[2], p[3], c);
p += 4;
break;
case 1:
r(i, p[1], p[2], p[3], c);
p += 4;
break;
case 2:
u(i, p[1], p[2], p[3], c);
p += 4;
break;
case 3:
e(i, p[1]
, p[2], 0, c);
p += 3;
break;
case 5:
p = z[p[1]];
break;
case 6:
c = _x[p[1] / 4] - 1643277 * (p[1] % 4);
p += 2;
break;
}
}
}
while (a++) {
int f = open(s[1], 0);
read(f, m, 380);
close(f);
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
if ((x % 14 == 2) && (y % 4 == 3))
m[y][x] = 46;
b(0, 2, 3, m[3][2], a & 1 ? 43 : 45);
b(0, 2, 7, m[7][2], a & 2 ? 43 : 45);
b(0, 2, 11, m[11][2], a & 4 ? 43 : 45);
b(0, 2, 15, m[15][2], a & 8 ? 43 : 45);
for (int i = 0; i < 20; i++)
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
if (m[y][x] == 62)
b(0, x + 1, y, m[y][x + 1],
!(m[y - 1][x] == 43 ? 1 : 0
|| m[y + 1][x] == 43 ? 1 : 0) ? 43 : 45);
for (int y = 0; y < 616; y++)
for (int x = 0; x < 1220; x++)
x_[y][x] = 0;
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
d_(((m[y][x] >> 4) & 1) << 2 | (m[y][x] & 3), x, y);
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
if ((x % 14 == 2) && (y % 4 == 3))
d_(7, x, y);
for (int y = 0; y < 616; y++)
for (int x = 0; x < 1220; x++) {
x_[y][x] &= 14737632 | (31 << ((x % 3) << 3));
x_[y][x] += 986895 & (rn *= 16777619);
}
XPutImage(display, window,
DefaultGC(display, DefaultScreen(display)),
image, 0, 0, 0, 0, 1220, 616);
XMapWindow(display, window);
XFlush(display);
sleep(1);
}
return 0;
}
影像数据
请注意,XCreateImage需要一个指向将存储像素数据的存储区的指针。对于我们的函数调用,这是“ x_”变量。将其重命名为pixdata并找到所有使用它的地方:
void d_(int t, int p, int q) {
for (int y = 0; y < 40; y++)
for (int x = 0; x < 64; x++)
if (_[t][y][x])
pixdata[y + q * 16 + p * 16][x + 580 + p * 32 - q * 32] = _[t][y][x]; // , -
}
image = XCreateImage(display,
DefaultVisual(display, DefaultScreen(display)),
DefaultDepth(display, DefaultScreen(display)),
2, 0, (char *) pixdata, 1220, 616, 32, 0); //
for (int y = 0; y < 616; y++)
for (int x = 0; x < 1220; x++)
pixdata[y][x] = 0; // "" ,
for (int y = 0; y < 616; y++)
for (int x = 0; x < 1220; x++) { // - , .
pixdata[y][x] &= 14737632 | (31 << ((x % 3) << 3));
pixdata[y][x] += 986895 & (rn *= 16777619);
}
让我们将pixdata [..] = 0块隔离到一个单独的函数中,然后尝试弄清楚第一次出现的情况:
for (int y = 0; y < 40; y++)
for (int x = 0; x < 64; x++)
if (_[t][y][x])
pixdata[y + q * 16 + p * 16][x + 580 + p * 32 - q * 32] = _[t][y][x];
如果仔细查看在编程操作过程中生成的最终图像,您会很容易注意到40和64是构成电路的单独“块”的尺寸。
因此,此函数在主图像的画布上绘制单独的“平铺”,并通过对“ _”数组的索引进行判断,“ t”变量负责图像索引,而p和q-负责x和y坐标。还要将“ _”重命名为纹理:
目前的代码:
#include <X11/Xlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/* */
/*! \brief */
#define IMAGE_WIDTH *1220)
/*! \brief */
#define IMAGE_HEIGHT (616)
/*! \brief */
#define TEXTURE_COUNT (8)
/*! \brief */
#define TEXTURE_WIDTH (64)
/*! \brief */
#define TEXTURE_HEIGHT (40)
/*! \brief .
* int */
int pixdata[IMAGE_HEIGHT][IMAGE_WIDTH];
int textures[TEXTURE_COUNT][TEXTURE_HEIGHT][TEXTURE_WIDTH] = { 0 };
/*! \brief Xlib */
Display * display;
/*! \brief Xlib */
Window window;
/*! \brief */
XImage * image;
/* \brief , */
static void _image_reset(void) {
for (int y = 0; y < IMAGE_HEIGHT; y++)
for (int x = 0; x < IMAGE_WIDTH; x++)
pixdata[y][x] = 0;
}
/*! \brief
* \param[in] t
* \param[in] x X
* \param[in] y Y */
void _texture_draw(int t, int x, int y) {
for (int ty = 0; ty < TEXTURE_HEIGHT; ty++)
for (int tx = 0; tx < TEXTURE_WIDTH; tx++)
if (textures[t][ty][tx])
pixdata[ty + y * 16 + x * 16]
[tx + 580 + x * 32 - y * 32] = textures[t][ty][tx];
}
/* */
int _x[] = { 15117427, 8413248, 5878632, 13027014, 1 };
char m[19][20];
int rn = 2166136261;
void *T;
void b(int t, int x, int y, int c, int l) {
if ((x >= 19 || y >= 19 || x < 0 || y < 0) || (m[y][x] == l)
|| (m[y][x] != c))
return;
m[y][x] = l;
b(t, x - 1, y, c, l);
b(t, x + 1, y, c, l);
b(t, x, y - 1, c, l);
b(t, x, y + 1, c, l);
}
void e(int t, int x, int y, int c, int l) {
if ((x >= TEXTURE_WIDTH || y >= TEXTURE_HEIGHT ||
x < 0 || y < 0) ||
(textures[t][y][x] == l) ||
(textures[t][y][x] != c))
return;
textures[t][y][x] = l;
e(t, x - 1, y, c, l);
e(t, x + 1, y, c, l);
e(t, x, y - 1, c, l);
e(t, x, y + 1, c, l);
}
void k(int t, int x, int y, int c, int l) {
while (c--) {
textures[t][y][x++] = l;
textures[t][y++][x++] = l;
}
}
void r(int t, int x, int y, int c, int l) {
while (c--) {
textures[t][y][x--] = l;
textures[t][y++][x--] = l;
}
}
void u(int t, int x, int y, int c, int l) {
while (c--)
textures[t][y++][x] = l;
}
char *z[8] = {
(char[]) {4},
(char[]) {6, 1 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16, 0, 0,
21 + 0 * 3 - 0, 16, 1, 63, 21 + 0 * 3 - 0, 16, 2,
63 * 0, 21 - 0, 4, 2, 31 + 0, 36 - 0, 4, 0 + 1,
32 - 1, 5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1, 63,
21 + 1 * 3 - 0, 16, 2, 63 * 1, 21 - 0, 4, 2, 31 + 1,
36 - 0, 4, 6, 1 * 4 + 0, 3, 31, 8 - 0, 6, 1 * 4 + 2,
3, 33, 38 - 0, 6, 1 * 4 + 3, 3, 30, 38 - 0, 4},
(char[]) {5, 1},
(char[]) {6, 0 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16,
0, 0, 21 + 0 * 3 - 0, 16, 1, 63,
21 + 0 * 3 - 0, 16, 2, 63 * 0, 21 - 0,
4, 2, 31 + 0, 36 - 0, 4, 0 + 1, 32 - 1,
5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1,
63, 21 + 1 * 3 - 0, 16, 2, 63 * 1,
21 - 0, 4, 2, 31 + 1, 36 - 0, 4, 6,
0 * 4 + 0, 3, 31, 8 - 0, 6, 0 * 4 + 2,
3, 33, 38 - 0, 6, 0 * 4 + 3, 3, 30,
38 - 0,
4},
(char[]) {4},
(char[]) {4},
(char[]) {6, 2 * 4 + 1, 0 + 0, 32 - 0, 5 - 3, 16, 0, 0,
21 + 0 * 3 - 3, 16, 1, 63, 21 + 0 * 3 - 3, 16, 2, 63 * 0,
21 - 3, 4, 2, 31 + 0, 36 - 3, 4, 0 + 1, 32 - 1, 5 - 3,
16, 0, 0, 21 + 1 * 3 - 3, 16, 1, 63, 21 + 1 * 3 - 3, 16,
2, 63 * 1, 21 - 3, 4, 2, 31 + 1, 36 - 3, 4, 6, 2 * 4 + 0,
3, 31, 8 - 3, 6, 2 * 4 + 2, 3, 33, 38 - 3, 6, 2 * 4 + 3,
3, 30, 38 - 3, 4},
(char[]) {6, 13, 0, 32, 9 + 0, 12 - 0,
0, 8 + 0 + 0, 21, 12 - 0, 1,
31, 9 + 0, 12 - 0, 1,
55 - 0 - 0, 21, 12 - 0, 0,
32, 9 + 3, 12 - 3, 0,
8 + 3 + 3, 21, 12 - 3, 1,
31, 9 + 3, 12 - 3, 1,
55 - 3 - 3, 21, 12 - 3, 6,
14 + 0, 2, 31 + 0, 13, 4,
1 - 0, 31 + 0, 16, 7, 3,
30 + 3 * 0, 14, 6,
12 + 0 * 4, 3, 32 - 0,
11 + 0 * 8, 6, 14 + 1, 2,
31 + 1, 13, 4, 1 - 1,
31 + 1, 16, 7, 3,
30 + 3 * 1, 14, 6,
12 + 1 * 4, 3, 32 - 1,
11 + 1 * 8,
4}
};
int main(int a, char *s[]) {
display = XOpenDisplay(0);
window = XCreateSimpleWindow(display,
RootWindow(display, DefaultScreen(display)),
0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, 1, 0, 0);
image = XCreateImage(display,
DefaultVisual(display, DefaultScreen(display)),
DefaultDepth(display, DefaultScreen(display)),
2, 0, (char *) pixdata, IMAGE_WIDTH, IMAGE_HEIGHT, 32, 0);
for (int i = 0; i < 8; i++) {
char *p = z[i];
int c = 0;
while (*p != 4) {
switch (*p) {
case 0:
k(i, p[1], p[2], p[3], c);
p += 4;
break;
case 1:
r(i, p[1], p[2], p[3], c);
p += 4;
break;
case 2:
u(i, p[1], p[2], p[3], c);
p += 4;
break;
case 3:
e(i, p[1]
, p[2], 0, c);
p += 3;
break;
case 5:
p = z[p[1]];
break;
case 6:
c = _x[p[1] / 4] - 1643277 * (p[1] % 4);
p += 2;
break;
}
}
}
while (a++) {
int f = open(s[1], 0);
read(f, m, 380);
close(f);
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
if ((x % 14 == 2) && (y % 4 == 3))
m[y][x] = 46;
b(0, 2, 3, m[3][2], a & 1 ? 43 : 45);
b(0, 2, 7, m[7][2], a & 2 ? 43 : 45);
b(0, 2, 11, m[11][2], a & 4 ? 43 : 45);
b(0, 2, 15, m[15][2], a & 8 ? 43 : 45);
for (int i = 0; i < 20; i++)
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
if (m[y][x] == 62)
b(0, x + 1, y, m[y][x + 1],
!(m[y - 1][x] == 43 ? 1 : 0
|| m[y + 1][x] == 43 ? 1 : 0) ? 43 : 45);
_image_reset();
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
_texture_draw(((m[y][x] >> 4) & 1) << 2 | (m[y][x] & 3), x, y);
for (int y = 0; y < 19; y++)
for (int x = 0; x < 19; x++)
if ((x % 14 == 2) && (y % 4 == 3))
_texture_draw(7, x, y);
for (int y = 0; y < IMAGE_HEIGHT; y++)
for (int x = 0; x < IMAGE_WIDTH; x++) {
pixdata[y][x] &= 14737632 | (31 << ((x % 3) << 3));
pixdata[y][x] += 986895 & (rn *= 16777619);
}
XPutImage(display, window,
DefaultGC(display, DefaultScreen(display)),
image, 0, 0, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
XMapWindow(display, window);
XFlush(display);
sleep(1);
}
return 0;
}
阅读地图
让我们将open..close行分开到一个单独的函数中,将所选文件的内容读入变量m(我们将其重命名为mapdata)。
为什么在每个周期都对文件计数?在代码和令牌方面更短。该代码的“夯实”过程大约需要4天才能适应规则的限制。如果您仅读取一次文件,则将需要额外的存储空间和memcpy函数的某些类似形式。
专用功能_map_read
#include <X11/Xlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/* */
/*! \brief */
#define IMAGE_WIDTH (1220)
/*! \brief */
#define IMAGE_HEIGHT (616)
/*! \brief */
#define IMAGE_SHIFTX (580)
/*! \brief */
#define TEXTURE_COUNT (8)
/*! \brief */
#define TEXTURE_WIDTH (64)
/*! \brief */
#define TEXTURE_HEIGHT (40)
/*! \brief */
#define TEXTURE_TOP_WIDTH (64)
/*! \brief */
#define TEXTURE_TOP_HEIGHT (32)
/*! \brief */
#define MAP_WIDTH (19)
/*! \brief */
#define MAP_HEIGHT (19)
/*! \brief -. '\n' */
#define MAP_FILEDATA ((MAP_WIDTH + 1) * MAP_HEIGHT)
/*! \brief .
* int */
int pixdata[IMAGE_HEIGHT][IMAGE_WIDTH];
/*! \brief , */
int textures[TEXTURE_COUNT][TEXTURE_HEIGHT][TEXTURE_WIDTH] = { 0 };
/*! \brief .
* '\n' */
char mapdata[MAP_HEIGHT][MAP_WIDTH + 1];
/*! \brief Xlib */
Display * display;
/*! \brief Xlib */
Window window;
/*! \brief */
XImage * image;
/* \brief , */
static void _image_reset(void) {
for (int y = 0; y < IMAGE_HEIGHT; y++)
for (int x = 0; x < IMAGE_WIDTH; x++)
pixdata[y][x] = 0;
}
/*! \brief
* \param[in] t
* \param[in] x X
* \param[in] y Y */
static void _texture_draw(int t, int x, int y) {
for (int ty = 0; ty < TEXTURE_HEIGHT; ty++)
for (int tx = 0; tx < TEXTURE_WIDTH; tx++)
if (textures[t][ty][tx])
pixdata[ty +
y * (TEXTURE_TOP_HEIGHT / 2) +
x * (TEXTURE_TOP_HEIGHT / 2)]
[tx +
IMAGE_SHIFTX +
x * (TEXTURE_TOP_WIDTH / 2) -
y * TEXTURE_TOP_HEIGHT] = textures[t][ty][tx];
}
/*! \brief -
* \param[in] filename - */
static void _map_read(const char * filename) {
int f = open(filename, 0);
read(f, mapdata, MAP_FILEDATA);
close(f);
}
/* */
int _x[] = { 15117427, 8413248, 5878632, 13027014, 1 };
int rn = 2166136261;
void *T;
void b(int t, int x, int y, int c, int l) {
if ((x >= MAP_WIDTH || y >= MAP_HEIGHT ||
x < 0 || y < 0) || (mapdata[y][x] == l)
|| (mapdata[y][x] != c))
return;
mapdata[y][x] = l;
b(t, x - 1, y, c, l);
b(t, x + 1, y, c, l);
b(t, x, y - 1, c, l);
b(t, x, y + 1, c, l);
}
void e(int t, int x, int y, int c, int l) {
if ((x >= TEXTURE_WIDTH || y >= TEXTURE_HEIGHT ||
x < 0 || y < 0) ||
(textures[t][y][x] == l) ||
(textures[t][y][x] != c))
return;
textures[t][y][x] = l;
e(t, x - 1, y, c, l);
e(t, x + 1, y, c, l);
e(t, x, y - 1, c, l);
e(t, x, y + 1, c, l);
}
void k(int t, int x, int y, int c, int l) {
while (c--) {
textures[t][y][x++] = l;
textures[t][y++][x++] = l;
}
}
void r(int t, int x, int y, int c, int l) {
while (c--) {
textures[t][y][x--] = l;
textures[t][y++][x--] = l;
}
}
void u(int t, int x, int y, int c, int l) {
while (c--)
textures[t][y++][x] = l;
}
char *z[8] = {
(char[]) {4},
(char[]) {6, 1 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16, 0, 0,
21 + 0 * 3 - 0, 16, 1, 63, 21 + 0 * 3 - 0, 16, 2,
63 * 0, 21 - 0, 4, 2, 31 + 0, 36 - 0, 4, 0 + 1,
32 - 1, 5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1, 63,
21 + 1 * 3 - 0, 16, 2, 63 * 1, 21 - 0, 4, 2, 31 + 1,
36 - 0, 4, 6, 1 * 4 + 0, 3, 31, 8 - 0, 6, 1 * 4 + 2,
3, 33, 38 - 0, 6, 1 * 4 + 3, 3, 30, 38 - 0, 4},
(char[]) {5, 1},
(char[]) {6, 0 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16,
0, 0, 21 + 0 * 3 - 0, 16, 1, 63,
21 + 0 * 3 - 0, 16, 2, 63 * 0, 21 - 0,
4, 2, 31 + 0, 36 - 0, 4, 0 + 1, 32 - 1,
5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1,
63, 21 + 1 * 3 - 0, 16, 2, 63 * 1,
21 - 0, 4, 2, 31 + 1, 36 - 0, 4, 6,
0 * 4 + 0, 3, 31, 8 - 0, 6, 0 * 4 + 2,
3, 33, 38 - 0, 6, 0 * 4 + 3, 3, 30,
38 - 0,
4},
(char[]) {4},
(char[]) {4},
(char[]) {6, 2 * 4 + 1, 0 + 0, 32 - 0, 5 - 3, 16, 0, 0,
21 + 0 * 3 - 3, 16, 1, 63, 21 + 0 * 3 - 3, 16, 2, 63 * 0,
21 - 3, 4, 2, 31 + 0, 36 - 3, 4, 0 + 1, 32 - 1, 5 - 3,
16, 0, 0, 21 + 1 * 3 - 3, 16, 1, 63, 21 + 1 * 3 - 3, 16,
2, 63 * 1, 21 - 3, 4, 2, 31 + 1, 36 - 3, 4, 6, 2 * 4 + 0,
3, 31, 8 - 3, 6, 2 * 4 + 2, 3, 33, 38 - 3, 6, 2 * 4 + 3,
3, 30, 38 - 3, 4},
(char[]) {6, 13, 0, 32, 9 + 0, 12 - 0,
0, 8 + 0 + 0, 21, 12 - 0, 1,
31, 9 + 0, 12 - 0, 1,
55 - 0 - 0, 21, 12 - 0, 0,
32, 9 + 3, 12 - 3, 0,
8 + 3 + 3, 21, 12 - 3, 1,
31, 9 + 3, 12 - 3, 1,
55 - 3 - 3, 21, 12 - 3, 6,
14 + 0, 2, 31 + 0, 13, 4,
1 - 0, 31 + 0, 16, 7, 3,
30 + 3 * 0, 14, 6,
12 + 0 * 4, 3, 32 - 0,
11 + 0 * 8, 6, 14 + 1, 2,
31 + 1, 13, 4, 1 - 1,
31 + 1, 16, 7, 3,
30 + 3 * 1, 14, 6,
12 + 1 * 4, 3, 32 - 1,
11 + 1 * 8,
4}
};
int main(int a, char *s[]) {
display = XOpenDisplay(0);
window = XCreateSimpleWindow(display,
RootWindow(display, DefaultScreen(display)),
0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, 1, 0, 0);
image = XCreateImage(display,
DefaultVisual(display, DefaultScreen(display)),
DefaultDepth(display, DefaultScreen(display)),
2, 0, (char *) pixdata, IMAGE_WIDTH, IMAGE_HEIGHT, 32, 0);
for (int i = 0; i < 8; i++) {
char *p = z[i];
int c = 0;
while (*p != 4) {
switch (*p) {
case 0:
k(i, p[1], p[2], p[3], c);
p += 4;
break;
case 1:
r(i, p[1], p[2], p[3], c);
p += 4;
break;
case 2:
u(i, p[1], p[2], p[3], c);
p += 4;
break;
case 3:
e(i, p[1]
, p[2], 0, c);
p += 3;
break;
case 5:
p = z[p[1]];
break;
case 6:
c = _x[p[1] / 4] - 1643277 * (p[1] % 4);
p += 2;
break;
}
}
}
while (a++) {
_map_read(s[1]);
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if ((x % 14 == 2) && (y % 4 == 3))
mapdata[y][x] = 46;
b(0, 2, 3, mapdata[3][2], a & 1 ? 43 : 45);
b(0, 2, 7, mapdata[7][2], a & 2 ? 43 : 45);
b(0, 2, 11, mapdata[11][2], a & 4 ? 43 : 45);
b(0, 2, 15, mapdata[15][2], a & 8 ? 43 : 45);
for (int i = 0; i < 20; i++)
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if (mapdata[y][x] == 62)
b(0, x + 1, y, mapdata[y][x + 1],
!(mapdata[y - 1][x] == 43 ? 1 : 0
|| mapdata[y + 1][x] == 43 ? 1 : 0) ? 43 : 45);
_image_reset();
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
_texture_draw(((m[y][x] >> 4) & 1) << 2 | (mapdata[y][x] & 3), x, y);
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if ((x % 14 == 2) && (y % 4 == 3))
_texture_draw(7, x, y);
for (int y = 0; y < IMAGE_HEIGHT; y++)
for (int x = 0; x < IMAGE_WIDTH; x++) {
pixdata[y][x] &= 14737632 | (31 << ((x % 3) << 3));
pixdata[y][x] += 986895 & (rn *= 16777619);
}
XPutImage(display, window,
DefaultGC(display, DefaultScreen(display)),
image, 0, 0, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
XMapWindow(display, window);
XFlush(display);
sleep(1);
}
return 0;
}
由于我们已经触及了mapdata变量,因此我们要注意它所更改的行和函数-这是我们暂时将不涉及的“ b”函数和“主要”位置,并注意“完整”配置文件的内容,我们将重构:
在mapdata上重构后
#include <X11/Xlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/* */
/*! \brief */
#define IMAGE_WIDTH (1220)
/*! \brief */
#define IMAGE_HEIGHT (616)
/*! \brief */
#define IMAGE_SHIFTX (580)
/*! \brief */
#define TEXTURE_COUNT (8)
/*! \brief */
#define TEXTURE_WIDTH (64)
/*! \brief */
#define TEXTURE_HEIGHT (40)
/*! \brief */
#define TEXTURE_TOP_WIDTH (64)
/*! \brief */
#define TEXTURE_TOP_HEIGHT (32)
/*! \brief */
#define MAP_WIDTH (19)
/*! \brief */
#define MAP_HEIGHT (19)
/*! \brief -. '\n' */
#define MAP_FILEDATA ((MAP_WIDTH + 1) * MAP_HEIGHT)
/*! \brief NOR- */
#define MAP_ITERATIONS (20)
/*! \brief - */
enum map_characters {
MAPCHAR_WIRE = '.', /**< (ASCII = 46) */
MAPCHAR_PLUS = '+', /**< ( ) (ASCII = 43) */
MAPCHAR_MINUS = '-', /**< ( ) (ASCII = 45) */
MAPCHAR_NOR = '>', /**< NOR- (ASCII = 62) */
}
/*! \brief .
* int */
int pixdata[IMAGE_HEIGHT][IMAGE_WIDTH];
/*! \brief , */
int textures[TEXTURE_COUNT][TEXTURE_HEIGHT][TEXTURE_WIDTH] = { 0 };
/*! \brief .
* '\n' */
char mapdata[MAP_HEIGHT][MAP_WIDTH + 1];
/*! \brief Xlib */
Display * display;
/*! \brief Xlib */
Window window;
/*! \brief */
XImage * image;
/* \brief , */
static void _image_reset(void) {
for (int y = 0; y < IMAGE_HEIGHT; y++)
for (int x = 0; x < IMAGE_WIDTH; x++)
pixdata[y][x] = 0;
}
/*! \brief
* \param[in] t
* \param[in] x X
* \param[in] y Y */
static void _texture_draw(int t, int x, int y) {
for (int ty = 0; ty < TEXTURE_HEIGHT; ty++)
for (int tx = 0; tx < TEXTURE_WIDTH; tx++)
if (textures[t][ty][tx])
pixdata[ty +
y * (TEXTURE_TOP_HEIGHT / 2) +
x * (TEXTURE_TOP_HEIGHT / 2)]
[tx +
IMAGE_SHIFTX +
x * (TEXTURE_TOP_WIDTH / 2) -
y * TEXTURE_TOP_HEIGHT] = textures[t][ty][tx];
}
/*! \brief -
* \param[in] filename - */
static void _map_read(const char * filename) {
int f = open(filename, 0);
read(f, mapdata, MAP_FILEDATA);
close(f);
}
/*! \brief -
* */
static void _map_wire_inputs(void) {
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if ((x % 14 == 2) && (y % 4 == 3))
mapdata[y][x] = MAPCHAR_WIRE;
}
/*! \brief
* .
* \param[in] counter */
static void _map_wire_counter(int counter) {
b(0, 2, 3, mapdata[3][2], counter & 1 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
b(0, 2, 7, mapdata[7][2], counter & 2 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
b(0, 2, 11, mapdata[11][2], counter & 4 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
b(0, 2, 15, mapdata[15][2], counter & 8 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
}
/*! \brief () NOR- */
static void _map_process_gates(void) {
for (int i = 0; i < MAP_ITERATIONS; i++)
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if (mapdata[y][x] == MAPCHAR_NOR)
b(0, x + 1, y, mapdata[y][x + 1],
!(mapdata[y - 1][x] == MAPCHAR_PLUS ? 1 : 0
|| mapdata[y + 1][x] == MAPCHAR_PLUS ? 1 : 0) ?
MAPCHAR_PLUS : MAPCHAR_MINUS);
}
/* */
int _x[] = { 15117427, 8413248, 5878632, 13027014, 1 };
int rn = 2166136261;
void *T;
void b(int t, int x, int y, int c, int l) {
if ((x >= MAP_WIDTH || y >= MAP_HEIGHT ||
x < 0 || y < 0) || (mapdata[y][x] == l)
|| (mapdata[y][x] != c))
return;
mapdata[y][x] = l;
b(t, x - 1, y, c, l);
b(t, x + 1, y, c, l);
b(t, x, y - 1, c, l);
b(t, x, y + 1, c, l);
}
void e(int t, int x, int y, int c, int l) {
if ((x >= TEXTURE_WIDTH || y >= TEXTURE_HEIGHT ||
x < 0 || y < 0) ||
(textures[t][y][x] == l) ||
(textures[t][y][x] != c))
return;
textures[t][y][x] = l;
e(t, x - 1, y, c, l);
e(t, x + 1, y, c, l);
e(t, x, y - 1, c, l);
e(t, x, y + 1, c, l);
}
void k(int t, int x, int y, int c, int l) {
while (c--) {
textures[t][y][x++] = l;
textures[t][y++][x++] = l;
}
}
void r(int t, int x, int y, int c, int l) {
while (c--) {
textures[t][y][x--] = l;
textures[t][y++][x--] = l;
}
}
void u(int t, int x, int y, int c, int l) {
while (c--)
textures[t][y++][x] = l;
}
char *z[8] = {
(char[]) {4},
(char[]) {6, 1 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16, 0, 0,
21 + 0 * 3 - 0, 16, 1, 63, 21 + 0 * 3 - 0, 16, 2,
63 * 0, 21 - 0, 4, 2, 31 + 0, 36 - 0, 4, 0 + 1,
32 - 1, 5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1, 63,
21 + 1 * 3 - 0, 16, 2, 63 * 1, 21 - 0, 4, 2, 31 + 1,
36 - 0, 4, 6, 1 * 4 + 0, 3, 31, 8 - 0, 6, 1 * 4 + 2,
3, 33, 38 - 0, 6, 1 * 4 + 3, 3, 30, 38 - 0, 4},
(char[]) {5, 1},
(char[]) {6, 0 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16,
0, 0, 21 + 0 * 3 - 0, 16, 1, 63,
21 + 0 * 3 - 0, 16, 2, 63 * 0, 21 - 0,
4, 2, 31 + 0, 36 - 0, 4, 0 + 1, 32 - 1,
5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1,
63, 21 + 1 * 3 - 0, 16, 2, 63 * 1,
21 - 0, 4, 2, 31 + 1, 36 - 0, 4, 6,
0 * 4 + 0, 3, 31, 8 - 0, 6, 0 * 4 + 2,
3, 33, 38 - 0, 6, 0 * 4 + 3, 3, 30,
38 - 0,
4},
(char[]) {4},
(char[]) {4},
(char[]) {6, 2 * 4 + 1, 0 + 0, 32 - 0, 5 - 3, 16, 0, 0,
21 + 0 * 3 - 3, 16, 1, 63, 21 + 0 * 3 - 3, 16, 2, 63 * 0,
21 - 3, 4, 2, 31 + 0, 36 - 3, 4, 0 + 1, 32 - 1, 5 - 3,
16, 0, 0, 21 + 1 * 3 - 3, 16, 1, 63, 21 + 1 * 3 - 3, 16,
2, 63 * 1, 21 - 3, 4, 2, 31 + 1, 36 - 3, 4, 6, 2 * 4 + 0,
3, 31, 8 - 3, 6, 2 * 4 + 2, 3, 33, 38 - 3, 6, 2 * 4 + 3,
3, 30, 38 - 3, 4},
(char[]) {6, 13, 0, 32, 9 + 0, 12 - 0,
0, 8 + 0 + 0, 21, 12 - 0, 1,
31, 9 + 0, 12 - 0, 1,
55 - 0 - 0, 21, 12 - 0, 0,
32, 9 + 3, 12 - 3, 0,
8 + 3 + 3, 21, 12 - 3, 1,
31, 9 + 3, 12 - 3, 1,
55 - 3 - 3, 21, 12 - 3, 6,
14 + 0, 2, 31 + 0, 13, 4,
1 - 0, 31 + 0, 16, 7, 3,
30 + 3 * 0, 14, 6,
12 + 0 * 4, 3, 32 - 0,
11 + 0 * 8, 6, 14 + 1, 2,
31 + 1, 13, 4, 1 - 1,
31 + 1, 16, 7, 3,
30 + 3 * 1, 14, 6,
12 + 1 * 4, 3, 32 - 1,
11 + 1 * 8,
4}
};
int main(int a, char *s[]) {
display = XOpenDisplay(0);
window = XCreateSimpleWindow(display,
RootWindow(display, DefaultScreen(display)),
0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, 1, 0, 0);
image = XCreateImage(display,
DefaultVisual(display, DefaultScreen(display)),
DefaultDepth(display, DefaultScreen(display)),
2, 0, (char *) pixdata, IMAGE_WIDTH, IMAGE_HEIGHT, 32, 0);
for (int i = 0; i < 8; i++) {
char *p = z[i];
int c = 0;
while (*p != 4) {
switch (*p) {
case 0:
k(i, p[1], p[2], p[3], c);
p += 4;
break;
case 1:
r(i, p[1], p[2], p[3], c);
p += 4;
break;
case 2:
u(i, p[1], p[2], p[3], c);
p += 4;
break;
case 3:
e(i, p[1]
, p[2], 0, c);
p += 3;
break;
case 5:
p = z[p[1]];
break;
case 6:
c = _x[p[1] / 4] - 1643277 * (p[1] % 4);
p += 2;
break;
}
}
}
while (a++) {
_map_read(s[1]);
_map_wire_inputs();
_map_wire_counter(a);
_map_process_gates();
_image_reset();
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
_texture_draw(((mapdata[y][x] >> 4) & 1) << 2 | (mapdata[y][x] & 3), x, y);
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if ((x % 14 == 2) && (y % 4 == 3))
_texture_draw(7, x, y);
for (int y = 0; y < IMAGE_HEIGHT; y++)
for (int x = 0; x < IMAGE_WIDTH; x++) {
pixdata[y][x] &= 14737632 | (31 << ((x % 3) << 3));
pixdata[y][x] += 986895 & (rn *= 16777619);
}
XPutImage(display, window,
DefaultGC(display, DefaultScreen(display)),
image, 0, 0, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
XMapWindow(display, window);
XFlush(display);
sleep(1);
}
return 0;
}
为了完成对“ mapdata”的工作处理,您需要再回答两个问题-什么是函数“ b”:
void b(int t, int x, int y, int c, int l) {
if ((x >= MAP_WIDTH || y >= MAP_HEIGHT ||
x < 0 || y < 0) || (mapdata[y][x] == l)
|| (mapdata[y][x] != c))
return;
mapdata[y][x] = l;
b(t, x - 1, y, c, l);
b(t, x + 1, y, c, l);
b(t, x, y - 1, c, l);
b(t, x, y + 1, c, l);
}
块中发生了什么:
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
_texture_draw(((mapdata[y][x] >> 4) & 1) << 2 | (mapdata[y][x] & 3), x, y);
功能“ b”
如果仔细观察函数“ b”,您会发现它非常类似于Flood_fill算法的实现,这与它的理论目的相吻合-它以所需的状态“淹没”“导线”,使电流波前传播到导线的末端。让我们重命名它并将其放在“生产就绪”块中。
洪水填充
#include <X11/Xlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/* */
/*! \brief */
#define IMAGE_WIDTH (1220)
/*! \brief */
#define IMAGE_HEIGHT (616)
/*! \brief */
#define IMAGE_SHIFTX (580)
/*! \brief */
#define TEXTURE_COUNT (8)
/*! \brief */
#define TEXTURE_WIDTH (64)
/*! \brief */
#define TEXTURE_HEIGHT (40)
/*! \brief */
#define TEXTURE_TOP_WIDTH (64)
/*! \brief */
#define TEXTURE_TOP_HEIGHT (32)
/*! \brief */
#define MAP_WIDTH (19)
/*! \brief */
#define MAP_HEIGHT (19)
/*! \brief -. '\n' */
#define MAP_FILEDATA ((MAP_WIDTH + 1) * MAP_HEIGHT)
/*! \brief NOR- */
#define MAP_ITERATIONS (20)
/*! \brief - */
enum map_characters {
MAPCHAR_WIRE = '.', /**< (ASCII = 46) */
MAPCHAR_PLUS = '+', /**< ( ) (ASCII = 43) */
MAPCHAR_MINUS = '-', /**< ( ) (ASCII = 45) */
MAPCHAR_NOR = '>', /**< NOR- (ASCII = 62) */
};
/*! \brief .
* int */
int pixdata[IMAGE_HEIGHT][IMAGE_WIDTH];
/*! \brief , */
int textures[TEXTURE_COUNT][TEXTURE_HEIGHT][TEXTURE_WIDTH] = { 0 };
/*! \brief .
* '\n' */
char mapdata[MAP_HEIGHT][MAP_WIDTH + 1];
/*! \brief Xlib */
Display * display;
/*! \brief Xlib */
Window window;
/*! \brief */
XImage * image;
/* \brief , */
static void _image_reset(void) {
for (int y = 0; y < IMAGE_HEIGHT; y++)
for (int x = 0; x < IMAGE_WIDTH; x++)
pixdata[y][x] = 0;
}
/*! \brief
* \param[in] t
* \param[in] x X
* \param[in] y Y */
static void _texture_draw(int t, int x, int y) {
for (int ty = 0; ty < TEXTURE_HEIGHT; ty++)
for (int tx = 0; tx < TEXTURE_WIDTH; tx++)
if (textures[t][ty][tx])
pixdata[ty +
y * (TEXTURE_TOP_HEIGHT / 2) +
x * (TEXTURE_TOP_HEIGHT / 2)]
[tx +
IMAGE_SHIFTX +
x * (TEXTURE_TOP_WIDTH / 2) -
y * TEXTURE_TOP_HEIGHT] = textures[t][ty][tx];
}
/*! \brief -
* \param[in] filename - */
static void _map_read(const char * filename) {
int f = open(filename, 0);
read(f, mapdata, MAP_FILEDATA);
close(f);
}
/*! \brief -
* */
static void _map_wire_inputs(void) {
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if ((x % 14 == 2) && (y % 4 == 3))
mapdata[y][x] = MAPCHAR_WIRE;
}
/*! \brief
* \param[in] t ,
* \param[in] x X-
* \param[in] y Y-
* \param[in] c
* \param[in] l */
static void _map_fill(int t, int x, int y, int c, int l) {
if ((x >= MAP_WIDTH || y >= MAP_HEIGHT ||
x < 0 || y < 0) || (mapdata[y][x] == l)
|| (mapdata[y][x] != c))
return;
mapdata[y][x] = l;
_map_fill(t, x - 1, y, c, l);
_map_fill(t, x + 1, y, c, l);
_map_fill(t, x, y - 1, c, l);
_map_fill(t, x, y + 1, c, l);
}
/*! \brief
* .
* \param[in] counter */
static void _map_wire_counter(int counter) {
_map_fill(0, 2, 3, mapdata[3][2], counter & 1 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
_map_fill(0, 2, 7, mapdata[7][2], counter & 2 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
_map_fill(0, 2, 11, mapdata[11][2], counter & 4 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
_map_fill(0, 2, 15, mapdata[15][2], counter & 8 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
}
/*! \brief () NOR- */
static void _map_process_gates(void) {
for (int i = 0; i < MAP_ITERATIONS; i++)
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if (mapdata[y][x] == MAPCHAR_NOR)
_map_fill(0, x + 1, y, mapdata[y][x + 1],
!(mapdata[y - 1][x] == MAPCHAR_PLUS ? 1 : 0
|| mapdata[y + 1][x] == MAPCHAR_PLUS ? 1 : 0) ?
MAPCHAR_PLUS : MAPCHAR_MINUS);
}
/* */
int _x[] = { 15117427, 8413248, 5878632, 13027014, 1 };
int rn = 2166136261;
void *T;
void e(int t, int x, int y, int c, int l) {
if ((x >= TEXTURE_WIDTH || y >= TEXTURE_HEIGHT ||
x < 0 || y < 0) ||
(textures[t][y][x] == l) ||
(textures[t][y][x] != c))
return;
textures[t][y][x] = l;
e(t, x - 1, y, c, l);
e(t, x + 1, y, c, l);
e(t, x, y - 1, c, l);
e(t, x, y + 1, c, l);
}
void k(int t, int x, int y, int c, int l) {
while (c--) {
textures[t][y][x++] = l;
textures[t][y++][x++] = l;
}
}
void r(int t, int x, int y, int c, int l) {
while (c--) {
textures[t][y][x--] = l;
textures[t][y++][x--] = l;
}
}
void u(int t, int x, int y, int c, int l) {
while (c--)
textures[t][y++][x] = l;
}
char *z[8] = {
(char[]) {4},
(char[]) {6, 1 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16, 0, 0,
21 + 0 * 3 - 0, 16, 1, 63, 21 + 0 * 3 - 0, 16, 2,
63 * 0, 21 - 0, 4, 2, 31 + 0, 36 - 0, 4, 0 + 1,
32 - 1, 5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1, 63,
21 + 1 * 3 - 0, 16, 2, 63 * 1, 21 - 0, 4, 2, 31 + 1,
36 - 0, 4, 6, 1 * 4 + 0, 3, 31, 8 - 0, 6, 1 * 4 + 2,
3, 33, 38 - 0, 6, 1 * 4 + 3, 3, 30, 38 - 0, 4},
(char[]) {5, 1},
(char[]) {6, 0 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16,
0, 0, 21 + 0 * 3 - 0, 16, 1, 63,
21 + 0 * 3 - 0, 16, 2, 63 * 0, 21 - 0,
4, 2, 31 + 0, 36 - 0, 4, 0 + 1, 32 - 1,
5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1,
63, 21 + 1 * 3 - 0, 16, 2, 63 * 1,
21 - 0, 4, 2, 31 + 1, 36 - 0, 4, 6,
0 * 4 + 0, 3, 31, 8 - 0, 6, 0 * 4 + 2,
3, 33, 38 - 0, 6, 0 * 4 + 3, 3, 30,
38 - 0,
4},
(char[]) {4},
(char[]) {4},
(char[]) {6, 2 * 4 + 1, 0 + 0, 32 - 0, 5 - 3, 16, 0, 0,
21 + 0 * 3 - 3, 16, 1, 63, 21 + 0 * 3 - 3, 16, 2, 63 * 0,
21 - 3, 4, 2, 31 + 0, 36 - 3, 4, 0 + 1, 32 - 1, 5 - 3,
16, 0, 0, 21 + 1 * 3 - 3, 16, 1, 63, 21 + 1 * 3 - 3, 16,
2, 63 * 1, 21 - 3, 4, 2, 31 + 1, 36 - 3, 4, 6, 2 * 4 + 0,
3, 31, 8 - 3, 6, 2 * 4 + 2, 3, 33, 38 - 3, 6, 2 * 4 + 3,
3, 30, 38 - 3, 4},
(char[]) {6, 13, 0, 32, 9 + 0, 12 - 0,
0, 8 + 0 + 0, 21, 12 - 0, 1,
31, 9 + 0, 12 - 0, 1,
55 - 0 - 0, 21, 12 - 0, 0,
32, 9 + 3, 12 - 3, 0,
8 + 3 + 3, 21, 12 - 3, 1,
31, 9 + 3, 12 - 3, 1,
55 - 3 - 3, 21, 12 - 3, 6,
14 + 0, 2, 31 + 0, 13, 4,
1 - 0, 31 + 0, 16, 7, 3,
30 + 3 * 0, 14, 6,
12 + 0 * 4, 3, 32 - 0,
11 + 0 * 8, 6, 14 + 1, 2,
31 + 1, 13, 4, 1 - 1,
31 + 1, 16, 7, 3,
30 + 3 * 1, 14, 6,
12 + 1 * 4, 3, 32 - 1,
11 + 1 * 8,
4}
};
int main(int a, char *s[]) {
display = XOpenDisplay(0);
window = XCreateSimpleWindow(display,
RootWindow(display, DefaultScreen(display)),
0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, 1, 0, 0);
image = XCreateImage(display,
DefaultVisual(display, DefaultScreen(display)),
DefaultDepth(display, DefaultScreen(display)),
2, 0, (char *) pixdata, IMAGE_WIDTH, IMAGE_HEIGHT, 32, 0);
for (int i = 0; i < 8; i++) {
char *p = z[i];
int c = 0;
while (*p != 4) {
switch (*p) {
case 0:
k(i, p[1], p[2], p[3], c);
p += 4;
break;
case 1:
r(i, p[1], p[2], p[3], c);
p += 4;
break;
case 2:
u(i, p[1], p[2], p[3], c);
p += 4;
break;
case 3:
e(i, p[1]
, p[2], 0, c);
p += 3;
break;
case 5:
p = z[p[1]];
break;
case 6:
c = _x[p[1] / 4] - 1643277 * (p[1] % 4);
p += 2;
break;
}
}
}
while (a++) {
_map_read(s[1]);
_map_wire_inputs();
_map_wire_counter(a);
_map_process_gates();
_image_reset();
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
_texture_draw(((mapdata[y][x] >> 4) & 1) << 2 | (mapdata[y][x] & 3), x, y);
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if ((x % 14 == 2) && (y % 4 == 3))
_texture_draw(7, x, y);
for (int y = 0; y < IMAGE_HEIGHT; y++)
for (int x = 0; x < IMAGE_WIDTH; x++) {
pixdata[y][x] &= 14737632 | (31 << ((x % 3) << 3));
pixdata[y][x] += 986895 & (rn *= 16777619);
}
XPutImage(display, window,
DefaultGC(display, DefaultScreen(display)),
image, 0, 0, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
XMapWindow(display, window);
XFlush(display);
sleep(1);
}
return 0;
}
怪块
现在,仍然需要解析该行中发生的事情:
_texture_draw(((mapdata[y][x] >> 4) & 1) << 2 | (mapdata[y][x] & 3), x, y);
由于我们已经建立了一个完整的状态表,可以在mapdata内部,因此我们可以获得第一个参数的所有输出值:
枚举 | 整型 | 结果 |
---|---|---|
MAPCHAR_WIRE | 46 | 2 |
MAPCHAR_PLUS | 43 | 3 |
MAPCHAR_MINUS | 45 | 1个 |
MAPCHAR_NOR | 62 | 6 |
MAPCHAR_EMPTY | 32 | 0 |
是的,也就是说,作为此转换的结果,我们在纹理数组中获得了纹理索引。
花了几个小时来思考从一组可读且可关联理解的符号到纹理索引的生成机制。我写出了可能表示导线和NOR元素的符号,然后绘制了它们的二进制值,然后圈出了唯一区域。除了当前选项之外,还有另一个选项具有更复杂的计算,但是它更长,因此不符合令牌限制。
太好了,它使我们能够隔离另一个函数并为每个纹理声明一个枚举:
另一个重构:
#include <X11/Xlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/* */
/*! \brief */
#define IMAGE_WIDTH (1220)
/*! \brief */
#define IMAGE_HEIGHT (616)
/*! \brief */
#define IMAGE_SHIFTX (580)
/*! \brief */
#define TEXTURE_COUNT (8)
/*! \brief */
#define TEXTURE_WIDTH (64)
/*! \brief */
#define TEXTURE_HEIGHT (40)
/*! \brief */
#define TEXTURE_TOP_WIDTH (64)
/*! \brief */
#define TEXTURE_TOP_HEIGHT (32)
/*! \brief */
#define MAP_WIDTH (19)
/*! \brief */
#define MAP_HEIGHT (19)
/*! \brief -. '\n' */
#define MAP_FILEDATA ((MAP_WIDTH + 1) * MAP_HEIGHT)
/*! \brief NOR- */
#define MAP_ITERATIONS (20)
/*! \brief - */
enum map_characters {
MAPCHAR_WIRE = '.', /**< (ASCII = 46) */
MAPCHAR_PLUS = '+', /**< ( ) (ASCII = 43) */
MAPCHAR_MINUS = '-', /**< ( ) (ASCII = 45) */
MAPCHAR_NOR = '>', /**< NOR- (ASCII = 62) */
MAPCHAR_EMPTY = ' ', /**< (ASCII = 32) */
};
/*! \brief */
enum textures_indexes {
TEXINDEX_EMPTY = (0), /**< */
TEXINDEX_MINUS = (1), /**< " " */
TEXINDEX_WIRE = (2), /**< */
TEXINDEX_PLUS = (3), /**< "" */
/**/
TEXINDEX_NOR = (6) /**< NOR- */
};
/*! \brief */
enum program_arguments {
ARG_PROGRAM, /**< */
ARG_BLUEPRINT /**< - */
};
/*! \brief .
* int */
int pixdata[IMAGE_HEIGHT][IMAGE_WIDTH];
/*! \brief , */
int textures[TEXTURE_COUNT][TEXTURE_HEIGHT][TEXTURE_WIDTH] = { 0 };
/*! \brief .
* '\n' */
char mapdata[MAP_HEIGHT][MAP_WIDTH + 1];
/*! \brief Xlib */
Display * display;
/*! \brief Xlib */
Window window;
/*! \brief */
XImage * image;
/* \brief , */
static void _image_reset(void) {
for (int y = 0; y < IMAGE_HEIGHT; y++)
for (int x = 0; x < IMAGE_WIDTH; x++)
pixdata[y][x] = 0;
}
/*! \brief
* \param[in] elem
* \return */
static int _map2texture(char elem) {
return ((elem >> 4) & 1) << 2 | (elem & 3);
}
/*! \brief */
static void _image_compile(void) {
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
_texture_draw(_map2texture(mapdata[y][x]), x, y);
}
/*! \brief */
static void _image_draw(void) {
XPutImage(display, window,
DefaultGC(display, DefaultScreen(display)),
image, 0, 0, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
XMapWindow(display, window);
XFlush(display);
}
/*! \brief
* \param[in] t
* \param[in] x X
* \param[in] y Y */
static void _texture_draw(int t, int x, int y) {
for (int ty = 0; ty < TEXTURE_HEIGHT; ty++)
for (int tx = 0; tx < TEXTURE_WIDTH; tx++)
if (textures[t][ty][tx])
pixdata[ty +
y * (TEXTURE_TOP_HEIGHT / 2) +
x * (TEXTURE_TOP_HEIGHT / 2)]
[tx +
IMAGE_SHIFTX +
x * (TEXTURE_TOP_WIDTH / 2) -
y * TEXTURE_TOP_HEIGHT] = textures[t][ty][tx];
}
/*! \brief -
* \param[in] filename - */
static void _map_read(const char * filename) {
int f = open(filename, 0);
read(f, mapdata, MAP_FILEDATA);
close(f);
}
/*! \brief -
* */
static void _map_wire_inputs(void) {
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if ((x % 14 == 2) && (y % 4 == 3))
mapdata[y][x] = MAPCHAR_WIRE;
}
/*! \brief
* \param[in] t ,
* \param[in] x X-
* \param[in] y Y-
* \param[in] c
* \param[in] l */
static void _map_fill(int t, int x, int y, int c, int l) {
if ((x >= MAP_WIDTH || y >= MAP_HEIGHT ||
x < 0 || y < 0) || (mapdata[y][x] == l)
|| (mapdata[y][x] != c))
return;
mapdata[y][x] = l;
_map_fill(t, x - 1, y, c, l);
_map_fill(t, x + 1, y, c, l);
_map_fill(t, x, y - 1, c, l);
_map_fill(t, x, y + 1, c, l);
}
/*! \brief
* .
* \param[in] counter */
static void _map_wire_counter(int counter) {
_map_fill(0, 2, 3, mapdata[3][2], counter & 1 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
_map_fill(0, 2, 7, mapdata[7][2], counter & 2 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
_map_fill(0, 2, 11, mapdata[11][2], counter & 4 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
_map_fill(0, 2, 15, mapdata[15][2], counter & 8 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
}
/*! \brief () NOR- */
static void _map_process_gates(void) {
for (int i = 0; i < MAP_ITERATIONS; i++)
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if (mapdata[y][x] == MAPCHAR_NOR)
_map_fill(0, x + 1, y, mapdata[y][x + 1],
!(mapdata[y - 1][x] == MAPCHAR_PLUS ? 1 : 0
|| mapdata[y + 1][x] == MAPCHAR_PLUS ? 1 : 0) ?
MAPCHAR_PLUS : MAPCHAR_MINUS);
}
/* */
int _x[] = { 15117427, 8413248, 5878632, 13027014, 1 };
int rn = 2166136261;
void *T;
void e(int t, int x, int y, int c, int l) {
if ((x >= TEXTURE_WIDTH || y >= TEXTURE_HEIGHT ||
x < 0 || y < 0) ||
(textures[t][y][x] == l) ||
(textures[t][y][x] != c))
return;
textures[t][y][x] = l;
e(t, x - 1, y, c, l);
e(t, x + 1, y, c, l);
e(t, x, y - 1, c, l);
e(t, x, y + 1, c, l);
}
void k(int t, int x, int y, int c, int l) {
while (c--) {
textures[t][y][x++] = l;
textures[t][y++][x++] = l;
}
}
void r(int t, int x, int y, int c, int l) {
while (c--) {
textures[t][y][x--] = l;
textures[t][y++][x--] = l;
}
}
void u(int t, int x, int y, int c, int l) {
while (c--)
textures[t][y++][x] = l;
}
char *z[8] = {
(char[]) {4},
(char[]) {6, 1 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16, 0, 0,
21 + 0 * 3 - 0, 16, 1, 63, 21 + 0 * 3 - 0, 16, 2,
63 * 0, 21 - 0, 4, 2, 31 + 0, 36 - 0, 4, 0 + 1,
32 - 1, 5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1, 63,
21 + 1 * 3 - 0, 16, 2, 63 * 1, 21 - 0, 4, 2, 31 + 1,
36 - 0, 4, 6, 1 * 4 + 0, 3, 31, 8 - 0, 6, 1 * 4 + 2,
3, 33, 38 - 0, 6, 1 * 4 + 3, 3, 30, 38 - 0, 4},
(char[]) {5, 1},
(char[]) {6, 0 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16,
0, 0, 21 + 0 * 3 - 0, 16, 1, 63,
21 + 0 * 3 - 0, 16, 2, 63 * 0, 21 - 0,
4, 2, 31 + 0, 36 - 0, 4, 0 + 1, 32 - 1,
5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1,
63, 21 + 1 * 3 - 0, 16, 2, 63 * 1,
21 - 0, 4, 2, 31 + 1, 36 - 0, 4, 6,
0 * 4 + 0, 3, 31, 8 - 0, 6, 0 * 4 + 2,
3, 33, 38 - 0, 6, 0 * 4 + 3, 3, 30,
38 - 0,
4},
(char[]) {4},
(char[]) {4},
(char[]) {6, 2 * 4 + 1, 0 + 0, 32 - 0, 5 - 3, 16, 0, 0,
21 + 0 * 3 - 3, 16, 1, 63, 21 + 0 * 3 - 3, 16, 2, 63 * 0,
21 - 3, 4, 2, 31 + 0, 36 - 3, 4, 0 + 1, 32 - 1, 5 - 3,
16, 0, 0, 21 + 1 * 3 - 3, 16, 1, 63, 21 + 1 * 3 - 3, 16,
2, 63 * 1, 21 - 3, 4, 2, 31 + 1, 36 - 3, 4, 6, 2 * 4 + 0,
3, 31, 8 - 3, 6, 2 * 4 + 2, 3, 33, 38 - 3, 6, 2 * 4 + 3,
3, 30, 38 - 3, 4},
(char[]) {6, 13, 0, 32, 9 + 0, 12 - 0,
0, 8 + 0 + 0, 21, 12 - 0, 1,
31, 9 + 0, 12 - 0, 1,
55 - 0 - 0, 21, 12 - 0, 0,
32, 9 + 3, 12 - 3, 0,
8 + 3 + 3, 21, 12 - 3, 1,
31, 9 + 3, 12 - 3, 1,
55 - 3 - 3, 21, 12 - 3, 6,
14 + 0, 2, 31 + 0, 13, 4,
1 - 0, 31 + 0, 16, 7, 3,
30 + 3 * 0, 14, 6,
12 + 0 * 4, 3, 32 - 0,
11 + 0 * 8, 6, 14 + 1, 2,
31 + 1, 13, 4, 1 - 1,
31 + 1, 16, 7, 3,
30 + 3 * 1, 14, 6,
12 + 1 * 4, 3, 32 - 1,
11 + 1 * 8,
4}
};
int main(int argc, char * args[]) {
display = XOpenDisplay(0);
window = XCreateSimpleWindow(display,
RootWindow(display, DefaultScreen(display)),
0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, 1, 0, 0);
image = XCreateImage(display,
DefaultVisual(display, DefaultScreen(display)),
DefaultDepth(display, DefaultScreen(display)),
2, 0, (char *) pixdata, IMAGE_WIDTH, IMAGE_HEIGHT, 32, 0);
for (int i = 0; i < 8; i++) {
char *p = z[i];
int c = 0;
while (*p != 4) {
switch (*p) {
case 0:
k(i, p[1], p[2], p[3], c);
p += 4;
break;
case 1:
r(i, p[1], p[2], p[3], c);
p += 4;
break;
case 2:
u(i, p[1], p[2], p[3], c);
p += 4;
break;
case 3:
e(i, p[1]
, p[2], 0, c);
p += 3;
break;
case 5:
p = z[p[1]];
break;
case 6:
c = _x[p[1] / 4] - 1643277 * (p[1] % 4);
p += 2;
break;
}
}
}
unsigned int counter = 0;
while (counter++) {
_map_read(args[ARG_BLUEPRINT]);
_map_wire_inputs();
_map_wire_counter(counter);
_map_process_gates();
_image_reset();
_image_compile();
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if ((x % 14 == 2) && (y % 4 == 3))
_texture_draw(7, x, y);
for (int y = 0; y < IMAGE_HEIGHT; y++)
for (int x = 0; x < IMAGE_WIDTH; x++) {
pixdata[y][x] &= 14737632 | (31 << ((x % 3) << 3));
pixdata[y][x] += 986895 & (rn *= 16777619);
}
_image_draw();
sleep(1);
}
return 0;
}
质地#7
如果仔细观察“ z”数组,您会发现它包含8个数据块,作为纹理数量的常数。就像在我们的枚举中一样,它甚至在位置4和5处都有两个空格,很可能是纹理数据。但是,它包含8张图像,而我们只能“打开” 7张图像。但是,如果我们足够小心,我们会注意到有一段代码专门绘制了第7个纹理:
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if ((x % 14 == 2) && (y % 4 == 3))
_texture_draw(7, x, y);
通过该位置,您已经可以猜出它是什么,但是注释掉以下几行并运行该应用程序:
之前:
之后:
现在我们可以确定这是板上孔的纹理,可以通过在单独的函数中将其渲染来将其添加到枚举列表中:
组装所有纹理:
#include <X11/Xlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/* */
/*! \brief */
#define IMAGE_WIDTH (1220)
/*! \brief */
#define IMAGE_HEIGHT (616)
/*! \brief */
#define IMAGE_SHIFTX (580)
/*! \brief */
#define TEXTURE_COUNT (8)
/*! \brief */
#define TEXTURE_WIDTH (64)
/*! \brief */
#define TEXTURE_HEIGHT (40)
/*! \brief */
#define TEXTURE_TOP_WIDTH (64)
/*! \brief */
#define TEXTURE_TOP_HEIGHT (32)
/*! \brief */
#define MAP_WIDTH (19)
/*! \brief */
#define MAP_HEIGHT (19)
/*! \brief -. '\n' */
#define MAP_FILEDATA ((MAP_WIDTH + 1) * MAP_HEIGHT)
/*! \brief NOR- */
#define MAP_ITERATIONS (20)
/*! \brief - */
enum map_characters {
MAPCHAR_WIRE = '.', /**< (ASCII = 46) */
MAPCHAR_PLUS = '+', /**< ( ) (ASCII = 43) */
MAPCHAR_MINUS = '-', /**< ( ) (ASCII = 45) */
MAPCHAR_NOR = '>', /**< NOR- (ASCII = 62) */
MAPCHAR_EMPTY = ' ', /**< (ASCII = 32) */
};
/*! \brief */
enum textures_indexes {
TEXINDEX_EMPTY = (0), /**< */
TEXINDEX_MINUS = (1), /**< " " */
TEXINDEX_WIRE = (2), /**< */
TEXINDEX_PLUS = (3), /**< "" */
/**/
TEXINDEX_NOR = (6), /**< NOR- */
TEXINDEX_HOLE = (7) /**< */
};
/*! \brief */
enum program_arguments {
ARG_PROGRAM, /**< */
ARG_BLUEPRINT /**< - */
};
/*! \brief .
* int */
int pixdata[IMAGE_HEIGHT][IMAGE_WIDTH];
/*! \brief , */
int textures[TEXTURE_COUNT][TEXTURE_HEIGHT][TEXTURE_WIDTH] = { 0 };
/*! \brief .
* '\n' */
char mapdata[MAP_HEIGHT][MAP_WIDTH + 1];
/*! \brief Xlib */
Display * display;
/*! \brief Xlib */
Window window;
/*! \brief */
XImage * image;
static void _texture_draw(int t, int x, int y);
/*! \brief */
static void _image_create(void) {
display = XOpenDisplay(0);
window = XCreateSimpleWindow(display,
RootWindow(display, DefaultScreen(display)),
0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, 1, 0, 0);
image = XCreateImage(display,
DefaultVisual(display, DefaultScreen(display)),
DefaultDepth(display, DefaultScreen(display)),
2, 0, (char *) pixdata, IMAGE_WIDTH, IMAGE_HEIGHT, 32, 0);
}
/* \brief , */
static void _image_reset(void) {
for (int y = 0; y < IMAGE_HEIGHT; y++)
for (int x = 0; x < IMAGE_WIDTH; x++)
pixdata[y][x] = 0;
}
/*! \brief
* \param[in] elem
* \return */
static int _map2texture(char elem) {
return ((elem >> 4) & 1) << 2 | (elem & 3);
}
/*! \brief */
static void _image_compile(void) {
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
_texture_draw(_map2texture(mapdata[y][x]), x, y);
}
/*! \brief */
static void _image_draw(void) {
XPutImage(display, window,
DefaultGC(display, DefaultScreen(display)),
image, 0, 0, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
XMapWindow(display, window);
XFlush(display);
}
/*! \brief */
static void _image_drill(void) {
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if ((x % 14 == 2) && (y % 4 == 3))
_texture_draw(TEXINDEX_HOLE, x, y);
}
/*! \brief
* \param[in] t
* \param[in] x X
* \param[in] y Y */
static void _texture_draw(int t, int x, int y) {
for (int ty = 0; ty < TEXTURE_HEIGHT; ty++)
for (int tx = 0; tx < TEXTURE_WIDTH; tx++)
if (textures[t][ty][tx])
pixdata[ty +
y * (TEXTURE_TOP_HEIGHT / 2) +
x * (TEXTURE_TOP_HEIGHT / 2)]
[tx +
IMAGE_SHIFTX +
x * (TEXTURE_TOP_WIDTH / 2) -
y * TEXTURE_TOP_HEIGHT] = textures[t][ty][tx];
}
/*! \brief -
* \param[in] filename - */
static void _map_read(const char * filename) {
int f = open(filename, 0);
read(f, mapdata, MAP_FILEDATA);
close(f);
}
/*! \brief -
* */
static void _map_wire_inputs(void) {
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if ((x % 14 == 2) && (y % 4 == 3))
mapdata[y][x] = MAPCHAR_WIRE;
}
/*! \brief
* \param[in] t ,
* \param[in] x X-
* \param[in] y Y-
* \param[in] c
* \param[in] l */
static void _map_fill(int t, int x, int y, int c, int l) {
if ((x >= MAP_WIDTH || y >= MAP_HEIGHT ||
x < 0 || y < 0) || (mapdata[y][x] == l)
|| (mapdata[y][x] != c))
return;
mapdata[y][x] = l;
_map_fill(t, x - 1, y, c, l);
_map_fill(t, x + 1, y, c, l);
_map_fill(t, x, y - 1, c, l);
_map_fill(t, x, y + 1, c, l);
}
/*! \brief
* .
* \param[in] counter */
static void _map_wire_counter(int counter) {
_map_fill(0, 2, 3, mapdata[3][2], counter & 1 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
_map_fill(0, 2, 7, mapdata[7][2], counter & 2 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
_map_fill(0, 2, 11, mapdata[11][2], counter & 4 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
_map_fill(0, 2, 15, mapdata[15][2], counter & 8 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
}
/*! \brief () NOR- */
static void _map_process_gates(void) {
for (int i = 0; i < MAP_ITERATIONS; i++)
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if (mapdata[y][x] == MAPCHAR_NOR)
_map_fill(0, x + 1, y, mapdata[y][x + 1],
!(mapdata[y - 1][x] == MAPCHAR_PLUS ? 1 : 0
|| mapdata[y + 1][x] == MAPCHAR_PLUS ? 1 : 0) ?
MAPCHAR_PLUS : MAPCHAR_MINUS);
}
/* */
int _x[] = { 15117427, 8413248, 5878632, 13027014, 1 };
int rn = 2166136261;
void *T;
void e(int t, int x, int y, int c, int l) {
if ((x >= TEXTURE_WIDTH || y >= TEXTURE_HEIGHT ||
x < 0 || y < 0) ||
(textures[t][y][x] == l) ||
(textures[t][y][x] != c))
return;
textures[t][y][x] = l;
e(t, x - 1, y, c, l);
e(t, x + 1, y, c, l);
e(t, x, y - 1, c, l);
e(t, x, y + 1, c, l);
}
void k(int t, int x, int y, int c, int l) {
while (c--) {
textures[t][y][x++] = l;
textures[t][y++][x++] = l;
}
}
void r(int t, int x, int y, int c, int l) {
while (c--) {
textures[t][y][x--] = l;
textures[t][y++][x--] = l;
}
}
void u(int t, int x, int y, int c, int l) {
while (c--)
textures[t][y++][x] = l;
}
char *z[8] = {
(char[]) {4},
(char[]) {6, 1 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16, 0, 0,
21 + 0 * 3 - 0, 16, 1, 63, 21 + 0 * 3 - 0, 16, 2,
63 * 0, 21 - 0, 4, 2, 31 + 0, 36 - 0, 4, 0 + 1,
32 - 1, 5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1, 63,
21 + 1 * 3 - 0, 16, 2, 63 * 1, 21 - 0, 4, 2, 31 + 1,
36 - 0, 4, 6, 1 * 4 + 0, 3, 31, 8 - 0, 6, 1 * 4 + 2,
3, 33, 38 - 0, 6, 1 * 4 + 3, 3, 30, 38 - 0, 4},
(char[]) {5, 1},
(char[]) {6, 0 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16,
0, 0, 21 + 0 * 3 - 0, 16, 1, 63,
21 + 0 * 3 - 0, 16, 2, 63 * 0, 21 - 0,
4, 2, 31 + 0, 36 - 0, 4, 0 + 1, 32 - 1,
5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1,
63, 21 + 1 * 3 - 0, 16, 2, 63 * 1,
21 - 0, 4, 2, 31 + 1, 36 - 0, 4, 6,
0 * 4 + 0, 3, 31, 8 - 0, 6, 0 * 4 + 2,
3, 33, 38 - 0, 6, 0 * 4 + 3, 3, 30,
38 - 0,
4},
(char[]) {4},
(char[]) {4},
(char[]) {6, 2 * 4 + 1, 0 + 0, 32 - 0, 5 - 3, 16, 0, 0,
21 + 0 * 3 - 3, 16, 1, 63, 21 + 0 * 3 - 3, 16, 2, 63 * 0,
21 - 3, 4, 2, 31 + 0, 36 - 3, 4, 0 + 1, 32 - 1, 5 - 3,
16, 0, 0, 21 + 1 * 3 - 3, 16, 1, 63, 21 + 1 * 3 - 3, 16,
2, 63 * 1, 21 - 3, 4, 2, 31 + 1, 36 - 3, 4, 6, 2 * 4 + 0,
3, 31, 8 - 3, 6, 2 * 4 + 2, 3, 33, 38 - 3, 6, 2 * 4 + 3,
3, 30, 38 - 3, 4},
(char[]) {6, 13, 0, 32, 9 + 0, 12 - 0,
0, 8 + 0 + 0, 21, 12 - 0, 1,
31, 9 + 0, 12 - 0, 1,
55 - 0 - 0, 21, 12 - 0, 0,
32, 9 + 3, 12 - 3, 0,
8 + 3 + 3, 21, 12 - 3, 1,
31, 9 + 3, 12 - 3, 1,
55 - 3 - 3, 21, 12 - 3, 6,
14 + 0, 2, 31 + 0, 13, 4,
1 - 0, 31 + 0, 16, 7, 3,
30 + 3 * 0, 14, 6,
12 + 0 * 4, 3, 32 - 0,
11 + 0 * 8, 6, 14 + 1, 2,
31 + 1, 13, 4, 1 - 1,
31 + 1, 16, 7, 3,
30 + 3 * 1, 14, 6,
12 + 1 * 4, 3, 32 - 1,
11 + 1 * 8,
4}
};
int main(int argc, char * args[]) {
_image_create();
for (int i = 0; i < 8; i++) {
char *p = z[i];
int c = 0;
while (*p != 4) {
switch (*p) {
case 0:
k(i, p[1], p[2], p[3], c);
p += 4;
break;
case 1:
r(i, p[1], p[2], p[3], c);
p += 4;
break;
case 2:
u(i, p[1], p[2], p[3], c);
p += 4;
break;
case 3:
e(i, p[1]
, p[2], 0, c);
p += 3;
break;
case 5:
p = z[p[1]];
break;
case 6:
c = _x[p[1] / 4] - 1643277 * (p[1] % 4);
p += 2;
break;
}
}
}
unsigned int counter = 1;
while (counter++) {
_map_read(args[ARG_BLUEPRINT]);
_map_wire_inputs();
_map_wire_counter(counter);
_map_process_gates();
_image_reset();
_image_compile();
_image_drill();
for (int y = 0; y < IMAGE_HEIGHT; y++)
for (int x = 0; x < IMAGE_WIDTH; x++) {
pixdata[y][x] &= 14737632 | (31 << ((x % 3) << 3));
pixdata[y][x] += 986895 & (rn *= 16777619);
}
_image_draw();
sleep(1);
}
return 0;
}
着色器
上一篇文章中的猫向着色器承诺。他们在这里。负责处理它们的代码在哪里?
_image_reset(); //
_image_compile(); //
_image_drill(); //
for (int y = 0; y < IMAGE_HEIGHT; y++)
for (int x = 0; x < IMAGE_WIDTH; x++) {
pixdata[y][x] &= 14737632 | (31 << ((x % 3) << 3));
pixdata[y][x] += 986895 & (rn *= 16777619);
}
_image_draw(); //
通过消除方法,我们了解到屏幕噪声和LCD监视器的效果可分为这两行。它们如何工作?
让我们从最后一个开始:
pixdata[y][x] += 986895 & (rn *= 16777619);
向每个像素添加值986895(在十六进制版本中看起来像0x0f0f0f),该值先前是通过位与运算与rn乘以16777619相乘的结果相结合的。如果rn是随机数生成器,则会产生颗粒状的“噪声”在屏幕上每个通道有16个渐变。并且由于出现了噪声,因此rn是随机数生成器。但是,如何实现呢?
int rn = 2166136261;
在程序的最开始,使用数字2166136261初始化rn变量。在每次迭代中,像素都乘以16777619。这无非是伪随机数生成器。但是,由于我们不需要最终结果,因此使用了没有XOR步骤的FNV哈希算法,而不是经过深入研究的线性生成器。
前一行的工作方式还有待观察:
pixdata[y][x] &= 14737632 | (31 << ((x % 3) << 3));
让我们将数字14737632转换为十六进制格式,因为我们正在处理一个字节的光通道:0xe0e0e0。现在,使x等于0到3,我们执行相应的计算:
0xe0e0e0 | (31 << ((0 % 3) << 3)) = e0e0ff
0xe0e0e0 | (31 << ((1 % 3) << 3)) = e0ffe0
0xe0e0e0 | (31 << ((2 % 3) << 3)) = ffe0e0
如果现在使用“&”操作将这些蒙版应用于像素的颜色,我们将分别获得静音的R和G通道,R和B通道,G通道和B通道,其效果类似于LCD监视器:
让我们将它们分成单独的函数:
#include <X11/Xlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/* */
/*! \brief */
#define IMAGE_WIDTH (1220)
/*! \brief */
#define IMAGE_HEIGHT (616)
/*! \brief */
#define IMAGE_SHIFTX (580)
/*! \brief */
#define TEXTURE_COUNT (8)
/*! \brief */
#define TEXTURE_WIDTH (64)
/*! \brief */
#define TEXTURE_HEIGHT (40)
/*! \brief */
#define TEXTURE_TOP_WIDTH (64)
/*! \brief */
#define TEXTURE_TOP_HEIGHT (32)
/*! \brief */
#define MAP_WIDTH (19)
/*! \brief */
#define MAP_HEIGHT (19)
/*! \brief -. '\n' */
#define MAP_FILEDATA ((MAP_WIDTH + 1) * MAP_HEIGHT)
/*! \brief NOR- */
#define MAP_ITERATIONS (20)
/*! \brief - */
enum map_characters {
MAPCHAR_WIRE = '.', /**< (ASCII = 46) */
MAPCHAR_PLUS = '+', /**< ( ) (ASCII = 43) */
MAPCHAR_MINUS = '-', /**< ( ) (ASCII = 45) */
MAPCHAR_NOR = '>', /**< NOR- (ASCII = 62) */
MAPCHAR_EMPTY = ' ', /**< (ASCII = 32) */
};
/*! \brief */
enum textures_indexes {
TEXINDEX_EMPTY = (0), /**< */
TEXINDEX_MINUS = (1), /**< " " */
TEXINDEX_WIRE = (2), /**< */
TEXINDEX_PLUS = (3), /**< "" */
/**/
TEXINDEX_NOR = (6), /**< NOR- */
TEXINDEX_HOLE = (7) /**< */
};
/*! \brief */
enum program_arguments {
ARG_PROGRAM, /**< */
ARG_BLUEPRINT /**< - */
};
/*! \brief .
* int */
int pixdata[IMAGE_HEIGHT][IMAGE_WIDTH];
/*! \brief , */
int textures[TEXTURE_COUNT][TEXTURE_HEIGHT][TEXTURE_WIDTH] = { 0 };
/*! \brief .
* '\n' */
char mapdata[MAP_HEIGHT][MAP_WIDTH + 1];
/*! \brief */
int random = 2166136261;
/*! \brief Xlib */
Display * display;
/*! \brief Xlib */
Window window;
/*! \brief */
XImage * image;
static void _texture_draw(int t, int x, int y);
/*! \brief */
static void _image_create(void) {
display = XOpenDisplay(0);
window = XCreateSimpleWindow(display,
RootWindow(display, DefaultScreen(display)),
0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, 1, 0, 0);
image = XCreateImage(display,
DefaultVisual(display, DefaultScreen(display)),
DefaultDepth(display, DefaultScreen(display)),
2, 0, (char *) pixdata, IMAGE_WIDTH, IMAGE_HEIGHT, 32, 0);
}
/* \brief , */
static void _image_reset(void) {
for (int y = 0; y < IMAGE_HEIGHT; y++)
for (int x = 0; x < IMAGE_WIDTH; x++)
pixdata[y][x] = 0;
}
/*! \brief
* \param[in] elem
* \return */
static int _map2texture(char elem) {
return ((elem >> 4) & 1) << 2 | (elem & 3);
}
/*! \brief */
static void _image_compile(void) {
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
_texture_draw(_map2texture(mapdata[y][x]), x, y);
}
/*! \brief */
static void _image_draw(void) {
XPutImage(display, window,
DefaultGC(display, DefaultScreen(display)),
image, 0, 0, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
XMapWindow(display, window);
XFlush(display);
}
/*! \brief */
static void _image_drill(void) {
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if ((x % 14 == 2) && (y % 4 == 3))
_texture_draw(TEXINDEX_HOLE, x, y);
}
/*! \brief LCD-
* \param[in] x X-
* \param[in] y Y- */
static void _shader_lcd(int x, int y) {
pixdata[y][x] &= 0xe0e0e0 | (31 << ((x % 3) << 3));
}
/*! \brief
* \param[in] x X-
* \param[in] y Y- */
static void _shader_noise(int x, int y) {
pixdata[y][x] += 0x0f0f0f & (random *= 16777619);
}
/*! \brief */
static void _image_postprocess(void) {
for (int y = 0; y < IMAGE_HEIGHT; y++)
for (int x = 0; x < IMAGE_WIDTH; x++) {
_shader_lcd(x, y);
_shader_noise(x, y);
}
}
/*! \brief
* \param[in] t
* \param[in] x X
* \param[in] y Y */
static void _texture_draw(int t, int x, int y) {
for (int ty = 0; ty < TEXTURE_HEIGHT; ty++)
for (int tx = 0; tx < TEXTURE_WIDTH; tx++)
if (textures[t][ty][tx])
pixdata[ty +
y * (TEXTURE_TOP_HEIGHT / 2) +
x * (TEXTURE_TOP_HEIGHT / 2)]
[tx +
IMAGE_SHIFTX +
x * (TEXTURE_TOP_WIDTH / 2) -
y * TEXTURE_TOP_HEIGHT] = textures[t][ty][tx];
}
/*! \brief -
* \param[in] filename - */
static void _map_read(const char * filename) {
int f = open(filename, 0);
read(f, mapdata, MAP_FILEDATA);
close(f);
}
/*! \brief -
* */
static void _map_wire_inputs(void) {
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if ((x % 14 == 2) && (y % 4 == 3))
mapdata[y][x] = MAPCHAR_WIRE;
}
/*! \brief
* \param[in] t ,
* \param[in] x X-
* \param[in] y Y-
* \param[in] c
* \param[in] l */
static void _map_fill(int t, int x, int y, int c, int l) {
if ((x >= MAP_WIDTH || y >= MAP_HEIGHT ||
x < 0 || y < 0) || (mapdata[y][x] == l)
|| (mapdata[y][x] != c))
return;
mapdata[y][x] = l;
_map_fill(t, x - 1, y, c, l);
_map_fill(t, x + 1, y, c, l);
_map_fill(t, x, y - 1, c, l);
_map_fill(t, x, y + 1, c, l);
}
/*! \brief
* .
* \param[in] counter */
static void _map_wire_counter(int counter) {
_map_fill(0, 2, 3, mapdata[3][2], counter & 1 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
_map_fill(0, 2, 7, mapdata[7][2], counter & 2 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
_map_fill(0, 2, 11, mapdata[11][2], counter & 4 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
_map_fill(0, 2, 15, mapdata[15][2], counter & 8 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
}
/*! \brief () NOR- */
static void _map_process_gates(void) {
for (int i = 0; i < MAP_ITERATIONS; i++)
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if (mapdata[y][x] == MAPCHAR_NOR)
_map_fill(0, x + 1, y, mapdata[y][x + 1],
!(mapdata[y - 1][x] == MAPCHAR_PLUS ? 1 : 0
|| mapdata[y + 1][x] == MAPCHAR_PLUS ? 1 : 0) ?
MAPCHAR_PLUS : MAPCHAR_MINUS);
}
/* */
int _x[] = { 15117427, 8413248, 5878632, 13027014, 1 };
void e(int t, int x, int y, int c, int l) {
if ((x >= TEXTURE_WIDTH || y >= TEXTURE_HEIGHT ||
x < 0 || y < 0) ||
(textures[t][y][x] == l) ||
(textures[t][y][x] != c))
return;
textures[t][y][x] = l;
e(t, x - 1, y, c, l);
e(t, x + 1, y, c, l);
e(t, x, y - 1, c, l);
e(t, x, y + 1, c, l);
}
void k(int t, int x, int y, int c, int l) {
while (c--) {
textures[t][y][x++] = l;
textures[t][y++][x++] = l;
}
}
void r(int t, int x, int y, int c, int l) {
while (c--) {
textures[t][y][x--] = l;
textures[t][y++][x--] = l;
}
}
void u(int t, int x, int y, int c, int l) {
while (c--)
textures[t][y++][x] = l;
}
char *z[8] = {
(char[]) {4},
(char[]) {6, 1 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16, 0, 0,
21 + 0 * 3 - 0, 16, 1, 63, 21 + 0 * 3 - 0, 16, 2,
63 * 0, 21 - 0, 4, 2, 31 + 0, 36 - 0, 4, 0 + 1,
32 - 1, 5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1, 63,
21 + 1 * 3 - 0, 16, 2, 63 * 1, 21 - 0, 4, 2, 31 + 1,
36 - 0, 4, 6, 1 * 4 + 0, 3, 31, 8 - 0, 6, 1 * 4 + 2,
3, 33, 38 - 0, 6, 1 * 4 + 3, 3, 30, 38 - 0, 4},
(char[]) {5, 1},
(char[]) {6, 0 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16,
0, 0, 21 + 0 * 3 - 0, 16, 1, 63,
21 + 0 * 3 - 0, 16, 2, 63 * 0, 21 - 0,
4, 2, 31 + 0, 36 - 0, 4, 0 + 1, 32 - 1,
5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1,
63, 21 + 1 * 3 - 0, 16, 2, 63 * 1,
21 - 0, 4, 2, 31 + 1, 36 - 0, 4, 6,
0 * 4 + 0, 3, 31, 8 - 0, 6, 0 * 4 + 2,
3, 33, 38 - 0, 6, 0 * 4 + 3, 3, 30,
38 - 0,
4},
(char[]) {4},
(char[]) {4},
(char[]) {6, 2 * 4 + 1, 0 + 0, 32 - 0, 5 - 3, 16, 0, 0,
21 + 0 * 3 - 3, 16, 1, 63, 21 + 0 * 3 - 3, 16, 2, 63 * 0,
21 - 3, 4, 2, 31 + 0, 36 - 3, 4, 0 + 1, 32 - 1, 5 - 3,
16, 0, 0, 21 + 1 * 3 - 3, 16, 1, 63, 21 + 1 * 3 - 3, 16,
2, 63 * 1, 21 - 3, 4, 2, 31 + 1, 36 - 3, 4, 6, 2 * 4 + 0,
3, 31, 8 - 3, 6, 2 * 4 + 2, 3, 33, 38 - 3, 6, 2 * 4 + 3,
3, 30, 38 - 3, 4},
(char[]) {6, 13, 0, 32, 9 + 0, 12 - 0,
0, 8 + 0 + 0, 21, 12 - 0, 1,
31, 9 + 0, 12 - 0, 1,
55 - 0 - 0, 21, 12 - 0, 0,
32, 9 + 3, 12 - 3, 0,
8 + 3 + 3, 21, 12 - 3, 1,
31, 9 + 3, 12 - 3, 1,
55 - 3 - 3, 21, 12 - 3, 6,
14 + 0, 2, 31 + 0, 13, 4,
1 - 0, 31 + 0, 16, 7, 3,
30 + 3 * 0, 14, 6,
12 + 0 * 4, 3, 32 - 0,
11 + 0 * 8, 6, 14 + 1, 2,
31 + 1, 13, 4, 1 - 1,
31 + 1, 16, 7, 3,
30 + 3 * 1, 14, 6,
12 + 1 * 4, 3, 32 - 1,
11 + 1 * 8,
4}
};
int main(int argc, char * args[]) {
_image_create();
for (int i = 0; i < 8; i++) {
char *p = z[i];
int c = 0;
while (*p != 4) {
switch (*p) {
case 0:
k(i, p[1], p[2], p[3], c);
p += 4;
break;
case 1:
r(i, p[1], p[2], p[3], c);
p += 4;
break;
case 2:
u(i, p[1], p[2], p[3], c);
p += 4;
break;
case 3:
e(i, p[1]
, p[2], 0, c);
p += 3;
break;
case 5:
p = z[p[1]];
break;
case 6:
c = _x[p[1] / 4] - 1643277 * (p[1] % 4);
p += 2;
break;
}
}
}
unsigned int counter = 1;
while (counter++) {
_map_read(args[ARG_BLUEPRINT]);
_map_wire_inputs();
_map_wire_counter(counter);
_map_process_gates();
_image_reset();
_image_compile();
_image_drill();
_image_postprocess();
_image_draw();
sleep(1);
}
return 0;
}
“ E”,“ k”,“ r”,“ u”
我们还有4个尚未调查或重命名的函数-它们是“ e”,“ k”,“ r”和“ u”。让我们尝试检查它们,而不寻找从何处调用它们:
void e(int t, int x, int y, int c, int l) {
if ((x >= TEXTURE_WIDTH || y >= TEXTURE_HEIGHT ||
x < 0 || y < 0) ||
(textures[t][y][x] == l) ||
(textures[t][y][x] != c))
return;
textures[t][y][x] = l;
e(t, x - 1, y, c, l);
e(t, x + 1, y, c, l);
e(t, x, y - 1, c, l);
e(t, x, y + 1, c, l);
}
显然,此函数的外观和工作方式类似于Flood_fill,仅适用于textures数组,将其重命名为_texture_fill。
void k(int t, int x, int y, int c, int l) {
while (c--) {
textures[t][y][x++] = l;
textures[t][y++][x++] = l;
}
}
void r(int t, int x, int y, int c, int l) {
while (c--) {
textures[t][y][x--] = l;
textures[t][y++][x--] = l;
}
}
每个给定单位c的函数“ k”和“ r”绘制两个像素,其值分别为l,向右或向左移动两个像素,向下移动一个像素-这意味着它们是绘制等距线SW和SE的函数。让我们将它们重命名为_texture_linesw和_texture_linese。
此时,您已经可以猜到最后一个函数“ u”在垂直向下绘制一条线:
void u(int t, int x, int y, int c, int l) {
while (c--)
textures[t][y++][x] = l;
}
让我们将其重命名为_texture_linedown。
所有单个功能均已重构:
#include <X11/Xlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/* */
/*! \brief */
#define IMAGE_WIDTH (1220)
/*! \brief */
#define IMAGE_HEIGHT (616)
/*! \brief */
#define IMAGE_SHIFTX (580)
/*! \brief */
#define TEXTURE_COUNT (8)
/*! \brief */
#define TEXTURE_WIDTH (64)
/*! \brief */
#define TEXTURE_HEIGHT (40)
/*! \brief */
#define TEXTURE_TOP_WIDTH (64)
/*! \brief */
#define TEXTURE_TOP_HEIGHT (32)
/*! \brief */
#define MAP_WIDTH (19)
/*! \brief */
#define MAP_HEIGHT (19)
/*! \brief -. '\n' */
#define MAP_FILEDATA ((MAP_WIDTH + 1) * MAP_HEIGHT)
/*! \brief NOR- */
#define MAP_ITERATIONS (20)
/*! \brief - */
enum map_characters {
MAPCHAR_WIRE = '.', /**< (ASCII = 46) */
MAPCHAR_PLUS = '+', /**< ( ) (ASCII = 43) */
MAPCHAR_MINUS = '-', /**< ( ) (ASCII = 45) */
MAPCHAR_NOR = '>', /**< NOR- (ASCII = 62) */
MAPCHAR_EMPTY = ' ', /**< (ASCII = 32) */
};
/*! \brief */
enum textures_indexes {
TEXINDEX_EMPTY = (0), /**< */
TEXINDEX_MINUS = (1), /**< " " */
TEXINDEX_WIRE = (2), /**< */
TEXINDEX_PLUS = (3), /**< "" */
/**/
TEXINDEX_NOR = (6), /**< NOR- */
TEXINDEX_HOLE = (7) /**< */
};
/*! \brief */
enum program_arguments {
ARG_PROGRAM, /**< */
ARG_BLUEPRINT /**< - */
};
/*! \brief .
* int */
int pixdata[IMAGE_HEIGHT][IMAGE_WIDTH];
/*! \brief , */
int textures[TEXTURE_COUNT][TEXTURE_HEIGHT][TEXTURE_WIDTH] = { 0 };
/*! \brief .
* '\n' */
char mapdata[MAP_HEIGHT][MAP_WIDTH + 1];
/*! \brief */
int random = 2166136261;
/*! \brief Xlib */
Display * display;
/*! \brief Xlib */
Window window;
/*! \brief */
XImage * image;
static void _texture_draw(int t, int x, int y);
/*! \brief */
static void _image_create(void) {
display = XOpenDisplay(0);
window = XCreateSimpleWindow(display,
RootWindow(display, DefaultScreen(display)),
0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, 1, 0, 0);
image = XCreateImage(display,
DefaultVisual(display, DefaultScreen(display)),
DefaultDepth(display, DefaultScreen(display)),
2, 0, (char *) pixdata, IMAGE_WIDTH, IMAGE_HEIGHT, 32, 0);
}
/* \brief , */
static void _image_reset(void) {
for (int y = 0; y < IMAGE_HEIGHT; y++)
for (int x = 0; x < IMAGE_WIDTH; x++)
pixdata[y][x] = 0;
}
/*! \brief
* \param[in] elem
* \return */
static int _map2texture(char elem) {
return ((elem >> 4) & 1) << 2 | (elem & 3);
}
/*! \brief */
static void _image_compile(void) {
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
_texture_draw(_map2texture(mapdata[y][x]), x, y);
}
/*! \brief */
static void _image_draw(void) {
XPutImage(display, window,
DefaultGC(display, DefaultScreen(display)),
image, 0, 0, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
XMapWindow(display, window);
XFlush(display);
}
/*! \brief */
static void _image_drill(void) {
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if ((x % 14 == 2) && (y % 4 == 3))
_texture_draw(TEXINDEX_HOLE, x, y);
}
/*! \brief LCD-
* \param[in] x X-
* \param[in] y Y- */
static void _shader_lcd(int x, int y) {
pixdata[y][x] &= 0xe0e0e0 | (31 << ((x % 3) << 3));
}
/*! \brief
* \param[in] x X-
* \param[in] y Y- */
static void _shader_noise(int x, int y) {
pixdata[y][x] += 0x0f0f0f & (random *= 16777619);
}
/*! \brief */
static void _image_postprocess(void) {
for (int y = 0; y < IMAGE_HEIGHT; y++)
for (int x = 0; x < IMAGE_WIDTH; x++) {
_shader_lcd(x, y);
_shader_noise(x, y);
}
}
/*! \brief
* \param[in] t
* \param[in] x X
* \param[in] y Y */
static void _texture_draw(int t, int x, int y) {
for (int ty = 0; ty < TEXTURE_HEIGHT; ty++)
for (int tx = 0; tx < TEXTURE_WIDTH; tx++)
if (textures[t][ty][tx])
pixdata[ty +
y * (TEXTURE_TOP_HEIGHT / 2) +
x * (TEXTURE_TOP_HEIGHT / 2)]
[tx +
IMAGE_SHIFTX +
x * (TEXTURE_TOP_WIDTH / 2) -
y * TEXTURE_TOP_HEIGHT] = textures[t][ty][tx];
}
/*! \brief
* \param[in] t
* \param[in] x X-
* \param[in] y Y-
* \param[in] source
* \param[in] target */
static void _texture_fill(int t, int x, int y, int source, int target) {
if ((x >= TEXTURE_WIDTH || y >= TEXTURE_HEIGHT ||
x < 0 || y < 0) ||
(textures[t][y][x] == target) ||
(textures[t][y][x] != source))
return;
textures[t][y][x] = target;
_texture_fill(t, x - 1, y, source, target);
_texture_fill(t, x + 1, y, source, target);
_texture_fill(t, x, y - 1, source, target);
_texture_fill(t, x, y + 1, source, target);
}
/*! \brief SE
* \param[in] t
* \param[in] x X-
* \param[in] y Y-
* \param[in] c
* \param[in] color */
static void _texture_linese(int t, int x, int y, int c, int color) {
while (c--) {
textures[t][y][x++] = color;
textures[t][y++][x++] = color;
}
}
/*! \brief SW
* \param[in] t
* \param[in] x X-
* \param[in] y Y-
* \param[in] c
* \param[in] color */
static void _texture_linesw(int t, int x, int y, int c, int color) {
while (c--) {
textures[t][y][x--] = color;
textures[t][y++][x--] = color;
}
}
/*! \brief
* \param[in] t
* \param[in] x X-
* \param[in] y Y-
* \param[in] c
* \param[in] color */
static void _texture_linedown(int t, int x, int y, int c, int color) {
while (c--)
textures[t][y++][x] = color;
}
/*! \brief -
* \param[in] filename - */
static void _map_read(const char * filename) {
int f = open(filename, 0);
read(f, mapdata, MAP_FILEDATA);
close(f);
}
/*! \brief -
* */
static void _map_wire_inputs(void) {
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if ((x % 14 == 2) && (y % 4 == 3))
mapdata[y][x] = MAPCHAR_WIRE;
}
/*! \brief
* \param[in] t ,
* \param[in] x X-
* \param[in] y Y-
* \param[in] c
* \param[in] l */
static void _map_fill(int t, int x, int y, int c, int l) {
if ((x >= MAP_WIDTH || y >= MAP_HEIGHT ||
x < 0 || y < 0) || (mapdata[y][x] == l)
|| (mapdata[y][x] != c))
return;
mapdata[y][x] = l;
_map_fill(t, x - 1, y, c, l);
_map_fill(t, x + 1, y, c, l);
_map_fill(t, x, y - 1, c, l);
_map_fill(t, x, y + 1, c, l);
}
/*! \brief
* .
* \param[in] counter */
static void _map_wire_counter(int counter) {
_map_fill(0, 2, 3, mapdata[3][2], counter & 1 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
_map_fill(0, 2, 7, mapdata[7][2], counter & 2 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
_map_fill(0, 2, 11, mapdata[11][2], counter & 4 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
_map_fill(0, 2, 15, mapdata[15][2], counter & 8 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
}
/*! \brief () NOR- */
static void _map_process_gates(void) {
for (int i = 0; i < MAP_ITERATIONS; i++)
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if (mapdata[y][x] == MAPCHAR_NOR)
_map_fill(0, x + 1, y, mapdata[y][x + 1],
!(mapdata[y - 1][x] == MAPCHAR_PLUS ? 1 : 0
|| mapdata[y + 1][x] == MAPCHAR_PLUS ? 1 : 0) ?
MAPCHAR_PLUS : MAPCHAR_MINUS);
}
/* */
int _x[] = { 15117427, 8413248, 5878632, 13027014, 1 };
char *z[8] = {
(char[]) {4},
(char[]) {6, 1 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16, 0, 0,
21 + 0 * 3 - 0, 16, 1, 63, 21 + 0 * 3 - 0, 16, 2,
63 * 0, 21 - 0, 4, 2, 31 + 0, 36 - 0, 4, 0 + 1,
32 - 1, 5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1, 63,
21 + 1 * 3 - 0, 16, 2, 63 * 1, 21 - 0, 4, 2, 31 + 1,
36 - 0, 4, 6, 1 * 4 + 0, 3, 31, 8 - 0, 6, 1 * 4 + 2,
3, 33, 38 - 0, 6, 1 * 4 + 3, 3, 30, 38 - 0, 4},
(char[]) {5, 1},
(char[]) {6, 0 * 4 + 1, 0 + 0, 32 - 0, 5 - 0, 16,
0, 0, 21 + 0 * 3 - 0, 16, 1, 63,
21 + 0 * 3 - 0, 16, 2, 63 * 0, 21 - 0,
4, 2, 31 + 0, 36 - 0, 4, 0 + 1, 32 - 1,
5 - 0, 16, 0, 0, 21 + 1 * 3 - 0, 16, 1,
63, 21 + 1 * 3 - 0, 16, 2, 63 * 1,
21 - 0, 4, 2, 31 + 1, 36 - 0, 4, 6,
0 * 4 + 0, 3, 31, 8 - 0, 6, 0 * 4 + 2,
3, 33, 38 - 0, 6, 0 * 4 + 3, 3, 30,
38 - 0,
4},
(char[]) {4},
(char[]) {4},
(char[]) {6, 2 * 4 + 1, 0 + 0, 32 - 0, 5 - 3, 16, 0, 0,
21 + 0 * 3 - 3, 16, 1, 63, 21 + 0 * 3 - 3, 16, 2, 63 * 0,
21 - 3, 4, 2, 31 + 0, 36 - 3, 4, 0 + 1, 32 - 1, 5 - 3,
16, 0, 0, 21 + 1 * 3 - 3, 16, 1, 63, 21 + 1 * 3 - 3, 16,
2, 63 * 1, 21 - 3, 4, 2, 31 + 1, 36 - 3, 4, 6, 2 * 4 + 0,
3, 31, 8 - 3, 6, 2 * 4 + 2, 3, 33, 38 - 3, 6, 2 * 4 + 3,
3, 30, 38 - 3, 4},
(char[]) {6, 13, 0, 32, 9 + 0, 12 - 0,
0, 8 + 0 + 0, 21, 12 - 0, 1,
31, 9 + 0, 12 - 0, 1,
55 - 0 - 0, 21, 12 - 0, 0,
32, 9 + 3, 12 - 3, 0,
8 + 3 + 3, 21, 12 - 3, 1,
31, 9 + 3, 12 - 3, 1,
55 - 3 - 3, 21, 12 - 3, 6,
14 + 0, 2, 31 + 0, 13, 4,
1 - 0, 31 + 0, 16, 7, 3,
30 + 3 * 0, 14, 6,
12 + 0 * 4, 3, 32 - 0,
11 + 0 * 8, 6, 14 + 1, 2,
31 + 1, 13, 4, 1 - 1,
31 + 1, 16, 7, 3,
30 + 3 * 1, 14, 6,
12 + 1 * 4, 3, 32 - 1,
11 + 1 * 8,
4}
};
int main(int argc, char * args[]) {
_image_create();
for (int i = 0; i < 8; i++) {
char *p = z[i];
int c = 0;
while (*p != 4) {
switch (*p) {
case 0:
_texture_linese(i, p[1], p[2], p[3], c);
p += 4;
break;
case 1:
_texture_linesw(i, p[1], p[2], p[3], c);
p += 4;
break;
case 2:
_texture_linedown(i, p[1], p[2], p[3], c);
p += 4;
break;
case 3:
_texture_fill(i, p[1], p[2], 0, c);
p += 3;
break;
case 5:
p = z[p[1]];
break;
case 6:
c = _x[p[1] / 4] - 1643277 * (p[1] % 4);
p += 2;
break;
}
}
}
unsigned int counter = 1;
while (counter++) {
_map_read(args[ARG_BLUEPRINT]);
_map_wire_inputs();
_map_wire_counter(counter);
_map_process_gates();
_image_reset();
_image_compile();
_image_drill();
_image_postprocess();
_image_draw();
sleep(1);
}
return 0;
}
矢量图形
仅剩最后一步-弄清楚在最后的切换情况下会发生什么,以备后用:
for (int i = 0; i < 8; i++) {
char *p = z[i];
int c = 0;
while (*p != 4) {
switch (*p) {
case 0:
_texture_linese(i, p[1], p[2], p[3], c);
p += 4;
break;
case 1:
_texture_linesw(i, p[1], p[2], p[3], c);
p += 4;
break;
case 2:
_texture_linedown(i, p[1], p[2], p[3], c);
p += 4;
break;
case 3:
_texture_fill(i, p[1], p[2], 0, c);
p += 3;
break;
case 5:
p = z[p[1]];
break;
case 6:
c = _x[p[1] / 4] - 1643277 * (p[1] % 4);
p += 2;
break;
}
}
}
现在,这些函数有了新的,易于理解的名称,我们可以说这段代码块解释了数组“ z”中的数据,并根据其中包含的指令进行了解释(例如,0、5、5、8、2-“在南-向东,从[5,5]的短边开始,长8个像素,颜色编号2“)绘制了整个纹理集。
一切似乎都很清楚,但是没有注意到程序中颜色的单一指示。
c = _x[p[1] / 4] - 1643277 * (p[1] % 4);
是的,所以_x数组是一个调色板,但是格式非常奇怪,是“压缩”的。
int _x[] = { 15117427, 8413248, 5878632, 13027014, 1 };
由于我们尚不知道调色板中使用了多少种颜色(设置颜色时,索引至少可以被4整除),因此我们重新格式化数据表以进行绘制,并按类别对数字进行分组,用常量替换指令签名:
重构向量指令表
#include <X11/Xlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/* */
/*! \brief */
#define IMAGE_WIDTH (1220)
/*! \brief */
#define IMAGE_HEIGHT (616)
/*! \brief */
#define IMAGE_SHIFTX (580)
/*! \brief */
#define TEXTURE_COUNT (8)
/*! \brief */
#define TEXTURE_WIDTH (64)
/*! \brief */
#define TEXTURE_HEIGHT (40)
/*! \brief */
#define TEXTURE_TOP_WIDTH (64)
/*! \brief */
#define TEXTURE_TOP_HEIGHT (32)
/*! \brief */
#define MAP_WIDTH (19)
/*! \brief */
#define MAP_HEIGHT (19)
/*! \brief -. '\n' */
#define MAP_FILEDATA ((MAP_WIDTH + 1) * MAP_HEIGHT)
/*! \brief NOR- */
#define MAP_ITERATIONS (20)
/*! \brief - */
enum map_characters {
MAPCHAR_WIRE = '.', /**< (ASCII = 46) */
MAPCHAR_PLUS = '+', /**< ( ) (ASCII = 43) */
MAPCHAR_MINUS = '-', /**< ( ) (ASCII = 45) */
MAPCHAR_NOR = '>', /**< NOR- (ASCII = 62) */
MAPCHAR_EMPTY = ' ', /**< (ASCII = 32) */
};
/*! \brief */
enum textures_indexes {
TEXINDEX_EMPTY = (0), /**< */
TEXINDEX_MINUS = (1), /**< " " */
TEXINDEX_WIRE = (2), /**< */
TEXINDEX_PLUS = (3), /**< "" */
/**/
TEXINDEX_NOR = (6), /**< NOR- */
TEXINDEX_HOLE = (7) /**< */
};
/*! \brief */
enum textures_instructions {
TEXVEC_LINESE = (0), /**< SE */
TEXVEC_LINESW = (1), /**< SW */
TEXVEC_LINEDW = (2), /**< */
TEXVEC_FILL = (3), /**< */
TEXVEC_EXIT = (4), /**< */
TEXVEC_REPEAT = (5), /**< */
TEXVEC_COLOR = (6) /**< */
};
/*! \brief */
enum program_arguments {
ARG_PROGRAM, /**< */
ARG_BLUEPRINT /**< - */
};
/*! \brief .
* int */
int pixdata[IMAGE_HEIGHT][IMAGE_WIDTH];
/*! \brief , */
int textures[TEXTURE_COUNT][TEXTURE_HEIGHT][TEXTURE_WIDTH] = { 0 };
/*! \brief .
* '\n' */
char mapdata[MAP_HEIGHT][MAP_WIDTH + 1];
/*! \brief */
int random = 2166136261;
/*! \brief Xlib */
Display * display;
/*! \brief Xlib */
Window window;
/*! \brief */
XImage * image;
/*! \brief */
static const char * vecdata[TEXTURE_COUNT] = {
/* TEXINDEX_EMPTY */
(char[]) { TEXVEC_EXIT },
/* TEXINDEX_MINUS */
(char[]) { TEXVEC_COLOR, 5, TEXVEC_LINESE, 32, 5, 16,
TEXVEC_LINESE, 0, 21, 16, TEXVEC_LINESW, 63, 21, 16,
TEXVEC_LINEDW, 0, 21, 4, TEXVEC_LINEDW, 31, 36, 4,
TEXVEC_LINESW, 31, 5, 16, TEXVEC_LINESE, 0, 24, 16,
TEXVEC_LINESW, 63, 24, 16, TEXVEC_LINEDW, 63, 21, 4,
TEXVEC_LINEDW, 32, 36, 4, TEXVEC_COLOR, 4,
TEXVEC_FILL, 31, 8, TEXVEC_COLOR, 6,
TEXVEC_FILL, 33, 38, TEXVEC_COLOR, 7,
TEXVEC_FILL, 30, 38, TEXVEC_EXIT },
/* TEXINDEX_WIRE */
(char[]) { TEXVEC_REPEAT, 1 },
/* TEXINDEX_PLUS */
(char[]) { TEXVEC_COLOR, 1, TEXVEC_LINESE, 32, 5, 16,
TEXVEC_LINESE, 0, 21, 16, TEXVEC_LINESW, 63, 21, 16,
TEXVEC_LINEDW, 63, 21, 4, TEXVEC_LINEDW, 31, 36, 4,
TEXVEC_LINESW, 31, 5, 16, TEXVEC_LINESE, 0, 24, 16,
TEXVEC_LINESW, 63, 24, 16, TEXVEC_LINEDW, 63, 21, 4,
TEXVEC_LINEDW, 32, 36, 4, TEXVEC_COLOR, 0,
TEXVEC_FILL, 31, 8, TEXVEC_COLOR, 2,
TEXVEC_FILL, 33, 38, TEXVEC_COLOR, 3,
TEXVEC_FILL, 30, 38, TEXVEC_EXIT },
/* */
(char[]) { TEXVEC_EXIT },
/* */
(char[]) { TEXVEC_EXIT },
/* TEXINDEX_NOR */
(char[]) { TEXVEC_COLOR, 9, TEXVEC_LINESE, 32, 2, 16,
TEXVEC_LINESE, 0, 18, 16, TEXVEC_LINESW, 63, 18, 16,
TEXVEC_LINEDW, 0, 18, 4, TEXVEC_LINEDW, 31, 33, 4,
TEXVEC_LINESW, 31, 2, 16, TEXVEC_LINESE, 0, 21, 16,
TEXVEC_LINESW, 63, 21, 16, TEXVEC_LINEDW, 63, 18, 4,
TEXVEC_LINEDW, 32, 33, 4, TEXVEC_COLOR, 8,
TEXVEC_FILL, 31, 5, TEXVEC_COLOR, 10,
TEXVEC_FILL, 33, 35, TEXVEC_COLOR, 11,
TEXVEC_FILL, 30, 35, TEXVEC_EXIT },
/* TEXINDEX_HOLE */
(char[]) { TEXVEC_COLOR, 13, TEXVEC_LINESE, 32, 9, 12,
TEXVEC_LINESE, 8, 21, 12, TEXVEC_LINESW, 31, 9, 12,
TEXVEC_LINESW, 55, 21, 12, TEXVEC_LINESE, 32, 12, 9,
TEXVEC_LINESE, 14, 21, 9, TEXVEC_LINESW, 31, 12, 9,
TEXVEC_LINESW, 49, 21, 9, TEXVEC_COLOR, 14,
TEXVEC_LINEDW, 31, 13, 4, TEXVEC_LINESW, 31, 16, 7,
TEXVEC_FILL, 30, 14, TEXVEC_COLOR, 12,
TEXVEC_FILL, 32, 11, TEXVEC_COLOR, 15,
TEXVEC_LINEDW, 32, 13, 4, TEXVEC_LINESE, 32, 16, 7,
TEXVEC_FILL, 33, 14, TEXVEC_COLOR, 16,
TEXVEC_FILL, 31, 19, TEXVEC_EXIT }
};
static void _texture_draw(int t, int x, int y);
/*! \brief */
static void _image_create(void) {
display = XOpenDisplay(0);
window = XCreateSimpleWindow(display,
RootWindow(display, DefaultScreen(display)),
0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, 1, 0, 0);
image = XCreateImage(display,
DefaultVisual(display, DefaultScreen(display)),
DefaultDepth(display, DefaultScreen(display)),
2, 0, (char *) pixdata, IMAGE_WIDTH, IMAGE_HEIGHT, 32, 0);
}
/* \brief , */
static void _image_reset(void) {
for (int y = 0; y < IMAGE_HEIGHT; y++)
for (int x = 0; x < IMAGE_WIDTH; x++)
pixdata[y][x] = 0;
}
/*! \brief
* \param[in] elem
* \return */
static int _map2texture(char elem) {
return ((elem >> 4) & 1) << 2 | (elem & 3);
}
/*! \brief */
static void _image_compile(void) {
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
_texture_draw(_map2texture(mapdata[y][x]), x, y);
}
/*! \brief */
static void _image_draw(void) {
XPutImage(display, window,
DefaultGC(display, DefaultScreen(display)),
image, 0, 0, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
XMapWindow(display, window);
XFlush(display);
}
/*! \brief */
static void _image_drill(void) {
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if ((x % 14 == 2) && (y % 4 == 3))
_texture_draw(TEXINDEX_HOLE, x, y);
}
/*! \brief LCD-
* \param[in] x X-
* \param[in] y Y- */
static void _shader_lcd(int x, int y) {
pixdata[y][x] &= 0xe0e0e0 | (31 << ((x % 3) << 3));
}
/*! \brief
* \param[in] x X-
* \param[in] y Y- */
static void _shader_noise(int x, int y) {
pixdata[y][x] += 0x0f0f0f & (random *= 16777619);
}
/*! \brief */
static void _image_postprocess(void) {
for (int y = 0; y < IMAGE_HEIGHT; y++)
for (int x = 0; x < IMAGE_WIDTH; x++) {
_shader_lcd(x, y);
_shader_noise(x, y);
}
}
/*! \brief
* \param[in] t
* \param[in] x X
* \param[in] y Y */
static void _texture_draw(int t, int x, int y) {
for (int ty = 0; ty < TEXTURE_HEIGHT; ty++)
for (int tx = 0; tx < TEXTURE_WIDTH; tx++)
if (textures[t][ty][tx])
pixdata[ty +
y * (TEXTURE_TOP_HEIGHT / 2) +
x * (TEXTURE_TOP_HEIGHT / 2)]
[tx +
IMAGE_SHIFTX +
x * (TEXTURE_TOP_WIDTH / 2) -
y * TEXTURE_TOP_HEIGHT] = textures[t][ty][tx];
}
/*! \brief
* \param[in] t
* \param[in] x X-
* \param[in] y Y-
* \param[in] source
* \param[in] target */
static void _texture_fill(int t, int x, int y, int source, int target) {
if ((x >= TEXTURE_WIDTH || y >= TEXTURE_HEIGHT ||
x < 0 || y < 0) ||
(textures[t][y][x] == target) ||
(textures[t][y][x] != source))
return;
textures[t][y][x] = target;
_texture_fill(t, x - 1, y, source, target);
_texture_fill(t, x + 1, y, source, target);
_texture_fill(t, x, y - 1, source, target);
_texture_fill(t, x, y + 1, source, target);
}
/*! \brief SE
* \param[in] t
* \param[in] x X-
* \param[in] y Y-
* \param[in] c
* \param[in] color */
static void _texture_linese(int t, int x, int y, int c, int color) {
while (c--) {
textures[t][y][x++] = color;
textures[t][y++][x++] = color;
}
}
/*! \brief SW
* \param[in] t
* \param[in] x X-
* \param[in] y Y-
* \param[in] c
* \param[in] color */
static void _texture_linesw(int t, int x, int y, int c, int color) {
while (c--) {
textures[t][y][x--] = color;
textures[t][y++][x--] = color;
}
}
/*! \brief
* \param[in] t
* \param[in] x X-
* \param[in] y Y-
* \param[in] c
* \param[in] color */
static void _texture_linedown(int t, int x, int y, int c, int color) {
while (c--)
textures[t][y++][x] = color;
}
/*! \brief -
* \param[in] filename - */
static void _map_read(const char * filename) {
int f = open(filename, 0);
read(f, mapdata, MAP_FILEDATA);
close(f);
}
/*! \brief -
* */
static void _map_wire_inputs(void) {
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if ((x % 14 == 2) && (y % 4 == 3))
mapdata[y][x] = MAPCHAR_WIRE;
}
/*! \brief
* \param[in] t ,
* \param[in] x X-
* \param[in] y Y-
* \param[in] c
* \param[in] l */
static void _map_fill(int t, int x, int y, int c, int l) {
if ((x >= MAP_WIDTH || y >= MAP_HEIGHT ||
x < 0 || y < 0) || (mapdata[y][x] == l)
|| (mapdata[y][x] != c))
return;
mapdata[y][x] = l;
_map_fill(t, x - 1, y, c, l);
_map_fill(t, x + 1, y, c, l);
_map_fill(t, x, y - 1, c, l);
_map_fill(t, x, y + 1, c, l);
}
/*! \brief
* .
* \param[in] counter */
static void _map_wire_counter(int counter) {
_map_fill(0, 2, 3, mapdata[3][2], counter & 1 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
_map_fill(0, 2, 7, mapdata[7][2], counter & 2 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
_map_fill(0, 2, 11, mapdata[11][2], counter & 4 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
_map_fill(0, 2, 15, mapdata[15][2], counter & 8 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
}
/*! \brief () NOR- */
static void _map_process_gates(void) {
for (int i = 0; i < MAP_ITERATIONS; i++)
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if (mapdata[y][x] == MAPCHAR_NOR)
_map_fill(0, x + 1, y, mapdata[y][x + 1],
!(mapdata[y - 1][x] == MAPCHAR_PLUS ? 1 : 0
|| mapdata[y + 1][x] == MAPCHAR_PLUS ? 1 : 0) ?
MAPCHAR_PLUS : MAPCHAR_MINUS);
}
/* */
int _x[] = { 15117427, 8413248, 5878632, 13027014, 1 };
int main(int argc, char * args[]) {
_image_create();
for (int tex = 0; tex < TEXTURE_COUNT; tex++) {
char * ptr = vecdata[tex];
int c = 0;
while (*ptr != TEXVEC_EXIT) {
switch (*ptr) {
case TEXVEC_LINESE:
_texture_linese(tex, ptr[1], ptr[2], ptr[3], c);
ptr += 4;
break;
case TEXVEC_LINESW:
_texture_linesw(tex, ptr[1], ptr[2], ptr[3], c);
ptr += 4;
break;
case TEXVEC_LINEDW:
_texture_linedown(tex, ptr[1], ptr[2], ptr[3], c);
ptr += 4;
break;
case TEXVEC_FILL:
_texture_fill(tex, ptr[1], ptr[2], 0, c);
ptr += 3;
break;
case TEXVEC_REPEAT:
ptr = vecdata[ptr[1]];
break;
case TEXVEC_COLOR:
c = _x[ptr[1] / 4] - 1643277 * (ptr[1] % 4);
ptr += 2;
break;
}
}
}
unsigned int counter = 1;
while (counter++) {
_map_read(args[ARG_BLUEPRINT]);
_map_wire_inputs();
_map_wire_counter(counter);
_map_process_gates();
_image_reset();
_image_compile();
_image_drill();
_image_postprocess();
_image_draw();
sleep(1);
}
return 0;
}
“ TEXVEC_COLOR”指令之后的最大数目为16。让我们编写最简单的代码来获取整个表格:
现在,掌握了已解密的调色板之后,我们就可以替换其使用功能,并为常量表中的颜色编写解密,同时突出显示创建纹理的功能:
重构后的完整代码:
#include <X11/Xlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/* */
/*! \brief */
#define IMAGE_WIDTH (1220)
/*! \brief */
#define IMAGE_HEIGHT (616)
/*! \brief */
#define IMAGE_SHIFTX (580)
/*! \brief */
#define TEXTURE_COUNT (8)
/*! \brief */
#define TEXTURE_WIDTH (64)
/*! \brief */
#define TEXTURE_HEIGHT (40)
/*! \brief */
#define TEXTURE_TOP_WIDTH (64)
/*! \brief */
#define TEXTURE_TOP_HEIGHT (32)
/*! \brief */
#define MAP_WIDTH (19)
/*! \brief */
#define MAP_HEIGHT (19)
/*! \brief -. '\n' */
#define MAP_FILEDATA ((MAP_WIDTH + 1) * MAP_HEIGHT)
/*! \brief NOR- */
#define MAP_ITERATIONS (20)
/*! \brief - */
enum map_characters {
MAPCHAR_WIRE = '.', /**< (ASCII = 46) */
MAPCHAR_PLUS = '+', /**< ( ) (ASCII = 43) */
MAPCHAR_MINUS = '-', /**< ( ) (ASCII = 45) */
MAPCHAR_NOR = '>', /**< NOR- (ASCII = 62) */
MAPCHAR_EMPTY = ' ', /**< (ASCII = 32) */
};
/*! \brief */
enum textures_indexes {
TEXINDEX_EMPTY = (0), /**< */
TEXINDEX_MINUS = (1), /**< " " */
TEXINDEX_WIRE = (2), /**< */
TEXINDEX_PLUS = (3), /**< "" */
/**/
TEXINDEX_NOR = (6), /**< NOR- */
TEXINDEX_HOLE = (7) /**< */
};
/*! \brief */
enum textures_instructions {
TEXVEC_LINESE = (0), /**< SE */
TEXVEC_LINESW = (1), /**< SW */
TEXVEC_LINEDW = (2), /**< */
TEXVEC_FILL = (3), /**< */
TEXVEC_EXIT = (4), /**< */
TEXVEC_REPEAT = (5), /**< */
TEXVEC_COLOR = (6) /**< */
};
/*! \brief */
enum program_arguments {
ARG_PROGRAM, /**< */
ARG_BLUEPRINT /**< - */
};
/*! \brief .
* int */
int pixdata[IMAGE_HEIGHT][IMAGE_WIDTH];
/*! \brief , */
int textures[TEXTURE_COUNT][TEXTURE_HEIGHT][TEXTURE_WIDTH] = { 0 };
/*! \brief .
* '\n' */
char mapdata[MAP_HEIGHT][MAP_WIDTH + 1];
/*! \brief */
int random = 2166136261;
/*! \brief Xlib */
Display * display;
/*! \brief Xlib */
Window window;
/*! \brief */
XImage * image;
/*! \brief
* \note {001} "" {000} */
static const int texturepalette[] = {
/* ▁▁▂▂▃▃▄▄▅▅▆▆▇▇██ */
/* - */ 0xe6ac73, 0xcd9966, 0xb48659, 0x9b734c,
/* - */ 0x806040, 0x674d33, 0x4e3a26, 0x352719,
/* */ 0x59b368, 0x40a05b, 0x278d4e, 0x0e7a41,
/* */ 0xc6c6c6, 0xadb3b9, 0x94a0ac, 0x7b8d9f,
/* */ 0x000001
};
/*! \brief */
static const char * vecdata[TEXTURE_COUNT] = {
/* TEXINDEX_EMPTY */
(char[]) { TEXVEC_EXIT },
/* TEXINDEX_MINUS */
(char[]) { TEXVEC_COLOR, 5, TEXVEC_LINESE, 32, 5, 16,
TEXVEC_LINESE, 0, 21, 16, TEXVEC_LINESW, 63, 21, 16,
TEXVEC_LINEDW, 0, 21, 4, TEXVEC_LINEDW, 31, 36, 4,
TEXVEC_LINESW, 31, 5, 16, TEXVEC_LINESE, 0, 24, 16,
TEXVEC_LINESW, 63, 24, 16, TEXVEC_LINEDW, 63, 21, 4,
TEXVEC_LINEDW, 32, 36, 4, TEXVEC_COLOR, 4,
TEXVEC_FILL, 31, 8, TEXVEC_COLOR, 6,
TEXVEC_FILL, 33, 38, TEXVEC_COLOR, 7,
TEXVEC_FILL, 30, 38, TEXVEC_EXIT },
/* TEXINDEX_WIRE */
(char[]) { TEXVEC_REPEAT, 1 },
/* TEXINDEX_PLUS */
(char[]) { TEXVEC_COLOR, 1, TEXVEC_LINESE, 32, 5, 16,
TEXVEC_LINESE, 0, 21, 16, TEXVEC_LINESW, 63, 21, 16,
TEXVEC_LINEDW, 63, 21, 4, TEXVEC_LINEDW, 31, 36, 4,
TEXVEC_LINESW, 31, 5, 16, TEXVEC_LINESE, 0, 24, 16,
TEXVEC_LINESW, 63, 24, 16, TEXVEC_LINEDW, 63, 21, 4,
TEXVEC_LINEDW, 32, 36, 4, TEXVEC_COLOR, 0,
TEXVEC_FILL, 31, 8, TEXVEC_COLOR, 2,
TEXVEC_FILL, 33, 38, TEXVEC_COLOR, 3,
TEXVEC_FILL, 30, 38, TEXVEC_EXIT },
/* */
(char[]) { TEXVEC_EXIT },
/* */
(char[]) { TEXVEC_EXIT },
/* TEXINDEX_NOR */
(char[]) { TEXVEC_COLOR, 9, TEXVEC_LINESE, 32, 2, 16,
TEXVEC_LINESE, 0, 18, 16, TEXVEC_LINESW, 63, 18, 16,
TEXVEC_LINEDW, 0, 18, 4, TEXVEC_LINEDW, 31, 33, 4,
TEXVEC_LINESW, 31, 2, 16, TEXVEC_LINESE, 0, 21, 16,
TEXVEC_LINESW, 63, 21, 16, TEXVEC_LINEDW, 63, 18, 4,
TEXVEC_LINEDW, 32, 33, 4, TEXVEC_COLOR, 8,
TEXVEC_FILL, 31, 5, TEXVEC_COLOR, 10,
TEXVEC_FILL, 33, 35, TEXVEC_COLOR, 11,
TEXVEC_FILL, 30, 35, TEXVEC_EXIT },
/* TEXINDEX_HOLE */
(char[]) { TEXVEC_COLOR, 13, TEXVEC_LINESE, 32, 9, 12,
TEXVEC_LINESE, 8, 21, 12, TEXVEC_LINESW, 31, 9, 12,
TEXVEC_LINESW, 55, 21, 12, TEXVEC_LINESE, 32, 12, 9,
TEXVEC_LINESE, 14, 21, 9, TEXVEC_LINESW, 31, 12, 9,
TEXVEC_LINESW, 49, 21, 9, TEXVEC_COLOR, 14,
TEXVEC_LINEDW, 31, 13, 4, TEXVEC_LINESW, 31, 16, 7,
TEXVEC_FILL, 30, 14, TEXVEC_COLOR, 12,
TEXVEC_FILL, 32, 11, TEXVEC_COLOR, 15,
TEXVEC_LINEDW, 32, 13, 4, TEXVEC_LINESE, 32, 16, 7,
TEXVEC_FILL, 33, 14, TEXVEC_COLOR, 16,
TEXVEC_FILL, 31, 19, TEXVEC_EXIT }
};
static void _texture_draw(int t, int x, int y);
/*! \brief */
static void _image_create(void) {
display = XOpenDisplay(0);
window = XCreateSimpleWindow(display,
RootWindow(display, DefaultScreen(display)),
0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, 1, 0, 0);
image = XCreateImage(display,
DefaultVisual(display, DefaultScreen(display)),
DefaultDepth(display, DefaultScreen(display)),
2, 0, (char *) pixdata, IMAGE_WIDTH, IMAGE_HEIGHT, 32, 0);
}
/* \brief , */
static void _image_reset(void) {
for (int y = 0; y < IMAGE_HEIGHT; y++)
for (int x = 0; x < IMAGE_WIDTH; x++)
pixdata[y][x] = 0;
}
/*! \brief
* \param[in] elem
* \return */
static int _map2texture(char elem) {
return ((elem >> 4) & 1) << 2 | (elem & 3);
}
/*! \brief */
static void _image_compile(void) {
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
_texture_draw(_map2texture(mapdata[y][x]), x, y);
}
/*! \brief */
static void _image_draw(void) {
XPutImage(display, window,
DefaultGC(display, DefaultScreen(display)),
image, 0, 0, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
XMapWindow(display, window);
XFlush(display);
}
/*! \brief */
static void _image_drill(void) {
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if ((x % 14 == 2) && (y % 4 == 3))
_texture_draw(TEXINDEX_HOLE, x, y);
}
/*! \brief LCD-
* \param[in] x X-
* \param[in] y Y- */
static void _shader_lcd(int x, int y) {
pixdata[y][x] &= 0xe0e0e0 | (31 << ((x % 3) << 3));
}
/*! \brief
* \param[in] x X-
* \param[in] y Y- */
static void _shader_noise(int x, int y) {
pixdata[y][x] += 0x0f0f0f & (random *= 16777619);
}
/*! \brief */
static void _image_postprocess(void) {
for (int y = 0; y < IMAGE_HEIGHT; y++)
for (int x = 0; x < IMAGE_WIDTH; x++) {
_shader_lcd(x, y);
_shader_noise(x, y);
}
}
/*! \brief
* \param[in] t
* \param[in] x X
* \param[in] y Y */
static void _texture_draw(int t, int x, int y) {
for (int ty = 0; ty < TEXTURE_HEIGHT; ty++)
for (int tx = 0; tx < TEXTURE_WIDTH; tx++)
if (textures[t][ty][tx])
pixdata[ty +
y * (TEXTURE_TOP_HEIGHT / 2) +
x * (TEXTURE_TOP_HEIGHT / 2)]
[tx +
IMAGE_SHIFTX +
x * (TEXTURE_TOP_WIDTH / 2) -
y * TEXTURE_TOP_HEIGHT] = textures[t][ty][tx];
}
/*! \brief
* \param[in] t
* \param[in] x X-
* \param[in] y Y-
* \param[in] source
* \param[in] target */
static void _texture_fill(int t, int x, int y, int source, int target) {
if ((x >= TEXTURE_WIDTH || y >= TEXTURE_HEIGHT ||
x < 0 || y < 0) ||
(textures[t][y][x] == target) ||
(textures[t][y][x] != source))
return;
textures[t][y][x] = target;
_texture_fill(t, x - 1, y, source, target);
_texture_fill(t, x + 1, y, source, target);
_texture_fill(t, x, y - 1, source, target);
_texture_fill(t, x, y + 1, source, target);
}
/*! \brief SE
* \param[in] t
* \param[in] x X-
* \param[in] y Y-
* \param[in] c
* \param[in] color */
static void _texture_linese(int t, int x, int y, int c, int color) {
while (c--) {
textures[t][y][x++] = color;
textures[t][y++][x++] = color;
}
}
/*! \brief SW
* \param[in] t
* \param[in] x X-
* \param[in] y Y-
* \param[in] c
* \param[in] color */
static void _texture_linesw(int t, int x, int y, int c, int color) {
while (c--) {
textures[t][y][x--] = color;
textures[t][y++][x--] = color;
}
}
/*! \brief
* \param[in] t
* \param[in] x X-
* \param[in] y Y-
* \param[in] c
* \param[in] color */
static void _texture_linedown(int t, int x, int y, int c, int color) {
while (c--)
textures[t][y++][x] = color;
}
/*! \brief , */
static void _textures_create(void) {
for (int tex = 0; tex < TEXTURE_COUNT; tex++) {
const char * ptr = vecdata[tex];
int c = 0;
while (*ptr != TEXVEC_EXIT) {
switch (*ptr) {
case TEXVEC_LINESE:
_texture_linese(tex, ptr[1], ptr[2], ptr[3], c);
ptr += 4;
break;
case TEXVEC_LINESW:
_texture_linesw(tex, ptr[1], ptr[2], ptr[3], c);
ptr += 4;
break;
case TEXVEC_LINEDW:
_texture_linedown(tex, ptr[1], ptr[2], ptr[3], c);
ptr += 4;
break;
case TEXVEC_FILL:
_texture_fill(tex, ptr[1], ptr[2], 0, c);
ptr += 3;
break;
case TEXVEC_REPEAT:
ptr = vecdata[ptr[1]];
break;
case TEXVEC_COLOR:
c = texturepalette[ptr[1]];
ptr += 2;
break;
}
}
}
}
/*! \brief -
* \param[in] filename - */
static void _map_read(const char * filename) {
int f = open(filename, 0);
read(f, mapdata, MAP_FILEDATA);
close(f);
}
/*! \brief -
* */
static void _map_wire_inputs(void) {
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if ((x % 14 == 2) && (y % 4 == 3))
mapdata[y][x] = MAPCHAR_WIRE;
}
/*! \brief
* \param[in] t ,
* \param[in] x X-
* \param[in] y Y-
* \param[in] c
* \param[in] l */
static void _map_fill(int t, int x, int y, int c, int l) {
if ((x >= MAP_WIDTH || y >= MAP_HEIGHT ||
x < 0 || y < 0) || (mapdata[y][x] == l)
|| (mapdata[y][x] != c))
return;
mapdata[y][x] = l;
_map_fill(t, x - 1, y, c, l);
_map_fill(t, x + 1, y, c, l);
_map_fill(t, x, y - 1, c, l);
_map_fill(t, x, y + 1, c, l);
}
/*! \brief
* .
* \param[in] counter */
static void _map_wire_counter(int counter) {
_map_fill(0, 2, 3, mapdata[3][2], counter & 1 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
_map_fill(0, 2, 7, mapdata[7][2], counter & 2 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
_map_fill(0, 2, 11, mapdata[11][2], counter & 4 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
_map_fill(0, 2, 15, mapdata[15][2], counter & 8 ? MAPCHAR_PLUS : MAPCHAR_MINUS);
}
/*! \brief () NOR- */
static void _map_process_gates(void) {
for (int i = 0; i < MAP_ITERATIONS; i++)
for (int y = 0; y < MAP_HEIGHT; y++)
for (int x = 0; x < MAP_WIDTH; x++)
if (mapdata[y][x] == MAPCHAR_NOR)
_map_fill(0, x + 1, y, mapdata[y][x + 1],
!(mapdata[y - 1][x] == MAPCHAR_PLUS ? 1 : 0
|| mapdata[y + 1][x] == MAPCHAR_PLUS ? 1 : 0) ?
MAPCHAR_PLUS : MAPCHAR_MINUS);
}
int main(int argc, char * args[]) {
_image_create();
_textures_create();
unsigned int counter = 1;
while (counter++) {
_map_read(args[ARG_BLUEPRINT]);
_map_wire_inputs();
_map_wire_counter(counter);
_map_process_gates();
_image_reset();
_image_compile();
_image_drill();
_image_postprocess();
_image_draw();
sleep(1);
}
return 0;
}
结语
就这样。尽管我没有获得任何奖项,但那是一个非常奇怪的经历(硬盘驱动器在开始接受工作的两天前就死了)。从语言的角度来看,编写代码时存在一些错误,该错误应尽可能地不可读,同时绝对有效。但是,不能说这并不有趣。当一个计算令牌的实用程序说代码通过超出限制超过2000个令牌而违反了规则,而您又不知道如何缩短令牌时,这就是一个挑战。当文件大小超出限制,并且您想添加某种图形效果时,这是一个挑战。容纳如此多的功能非常困难,而且读取实用程序的输出更甜蜜,经过数百次更正后,最终表明可以卸载该代码。我建议读者参加比赛,即使只是为了加入并测试您的力量。
是的,它没有提供任何奖项或奖品,但是您会知道您以国际奥委会委身的zhestokyshveller的昵称躲藏起来。