我如何参加IOCCC-'19(并输了)。第2部分:“ NOR模拟器”

这是关于我如何参加IOCCC'19系列文章的第二部分







  1. 我如何参加IOCCC-'19(并输了)。第1部分:“井字游戏”
  2. 我如何参加IOCCC-'19(并输了)。第2部分:“ NOR模拟器”


希望本文对反编译器或混淆器后解析别人的代码或其他代码有帮助。



如果您仍然不知道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的昵称躲藏起来。



All Articles