Пример #1
0
    void run()
    {
        Vector screenSize(80, 48);
        int frames = 13125000 * 14 / (11 * 76 * 262);
        int maxRadius = 20;

        // Center of screen
        Vector2<double> c = Vector2Cast<double>(screenSize) / 2;

        // Positions of screen top-left relative to centre of each picture
        Array<Vector> p1s(frames);
        Array<Vector> p2s(frames);
        int minX = 0, maxX = 0;
        for (int t = 0; t < frames; ++t) {
            double f = static_cast<double>(t) / frames;
            double r = maxRadius; // *(1 - cos(f * tau)) / 2;
            Rotor2<double> z1(f * 6);
            Rotor2<double> z2(f * 7);
            Vector2<double> a1(r*cos(f*tau * 6), r*sin(f*tau * 7));
            Vector2<double> a2(r*cos(f*tau * 5), r*sin(f*tau * 4));

            // Positions of picture centres relative to screen top-left
            Vector p1 = -Vector2Cast<int>(c + a1);
            Vector p2 = -Vector2Cast<int>(c + a2);
            p1s[t] = p1;
            p2s[t] = p2;

            minX = min(min(minX, p1.x), p2.x);
            maxX = max(max(maxX, p1.x + screenSize.x), p2.x + screenSize.x);
        }
        int stride = (3 + maxX - minX) & ~3;

        // Offset in picture from start of screen to end
        int ss = (screenSize.y - 1)*stride + screenSize.x;

        Array<int> o1s(frames);
        Array<int> o2s(frames);
        int minO = 0, maxO = 0;
        for (int t = 0; t < frames; ++t) {
            Vector p1 = p1s[t];
            Vector p2 = p2s[t];

            // Offsets of screen top-left into pictures relative to pictures
            // center.
            int o1 = p1.y*stride + p1.x;
            int o2 = p2.y*stride + p2.x;

            int o1e = o1 + ss;
            int o2e = o2 + ss;

            // Picture bounds
            minO = min(min(minO, o1), o2);
            maxO = max(max(maxO, o1e), o2e);

            o1s[t] = o1;
            o2s[t] = o2;
        }
        minO &= -2;
        maxO = (maxO + 1) & -2;

        FileStream output = File("tables.asm").openWrite();
/*        output.write("cpu 8086\n"
            "segment _DATA public class = DATA\n"
            "\n"
            "global _picture, _motion\n"
            "\n"
            "\n"); */

        int d = ((-minO) / stride + 1)*stride + stride/2;

        int bytes = (maxO + 1 - minO) / 2;

        int xs = (minO + d) % stride;
        int ys = (minO - xs) / stride;
        console.write("First position: (" + decimal(xs) + ", " + decimal(ys) +
            ")\n");
        xs = (maxO + d) % stride;
        ys = (maxO - xs) / stride;
        console.write("Last position: (" + decimal(xs) + ", " + decimal(ys) +
            ")\n");
        console.write("Picture size: " + decimal(bytes) + "\n");
        console.write("Motion size: " + decimal(4 * frames) + "\n");

        output.write("frames equ " + decimal(frames) + "\n");
        output.write("stride equ " + decimal(stride/2) + "\n");
        output.write("p equ picture\n");
        output.write(
            "p2 equ pictureEnd+(pictureEnd-picture)+(headerEnd-header)\n\n");

        output.write("motion:");
        for (int t = 0; t < frames; ++t) {
            int o1 = o1s[t] - minO;
            int o2 = o2s[t] - minO;

            int sp = o1 / 2;
            if ((o1 & 1) != 0)
                sp += bytes;
            int bp = o2 / 2;
            if ((o2 & 1) != 0)
                bp += bytes;

            if (t % 3 == 0)
                output.write("\n  dw ");
            else
                output.write(", ");
            output.write("p+" + hex(sp, 4) + ", p+" + hex(bp, 4));
        }

        int lastX = 20;
        output.write("\n\n");

        int p2 = (maxO + 1 - minO) / 2;
        p2 += p2 - 1;

        output.write("transition:");
        Array<bool> cleared(20 * 13);
        for (int p = 0; p < 20 * 13; ++p)
            cleared[p] = false;
        int pp = 0;
        for (int t = 0; t < 1000000; ++t) {
            int r = 999 - t / 1000;
            int theta = t % 1000;
            Vector2<double> z =
                Vector2<double>(r/20.0, 0)*Rotor2<double>(theta / 1000.0);
            Vector p = Vector2Cast<int>(z + Vector2<double>(10, 6));
            if (p.x >= 0 && p.x < 20 && p.y >= 0 && p.y < 12) {
                int aa = p.y * 20 + p.x;
                if (cleared[aa])
                    continue;
                int a = p.y * 206 * 4 + p.x * 10;
                if (pp % 3 == 0)
                    output.write("\n  dw ");
                else
                    output.write(", ");
                ++pp;
                output.write("p2+" + hex(a, 4) + ", ");
                if (p.y == 12)
                    output.write("p2+" + hex(a, 4));
                else
                    output.write("p2+" + hex(a + 206*2, 4));
                cleared[aa] = true;
            }
        }
        console.write("pp = " + decimal(pp) + " \n");
        output.write("\n\npicture:");
        for (int o = minO; o < maxO + 1; o += 2) {
            int x = (o + d) % stride;
            int y = (o + d - x) / stride - d/stride;

            if (lastX == 20) {
                output.write("\n  db ");
                lastX = 0;
            }
            else
                output.write(", ");
            for (; lastX < x % 20; lastX += 2)
                output.write("      ");

            Vector p(x - stride / 2, y);
            int cL = colour(p);
            int cR = colour(p + Vector(1, 0));
            int b = cL | (cR << 4);
            output.write(String(hex(b, 2)));
            lastX += 2;
        }
        output.write("\n");
        output.write("pictureEnd:\n");
    }
Пример #2
0
int
malloc_vsnprintf(char *str, size_t size, const char *format, va_list ap)
{
	int ret;
	size_t i;
	const char *f;

#define	APPEND_C(c) do {						\
	if (i < size)							\
		str[i] = (c);						\
	i++;								\
} while (0)
#define	APPEND_S(s, slen) do {						\
	if (i < size) {							\
		size_t cpylen = (slen <= size - i) ? slen : size - i;	\
		memcpy(&str[i], s, cpylen);				\
	}								\
	i += slen;							\
} while (0)
#define	APPEND_PADDED_S(s, slen, width, left_justify) do {		\
	/* Left padding. */						\
	size_t pad_len = (width == -1) ? 0 : ((slen < (size_t)width) ?	\
	    (size_t)width - slen : 0);					\
	if (left_justify == false && pad_len != 0) {			\
		size_t j;						\
		for (j = 0; j < pad_len; j++)				\
			APPEND_C(' ');					\
	}								\
	/* Value. */							\
	APPEND_S(s, slen);						\
	/* Right padding. */						\
	if (left_justify && pad_len != 0) {				\
		size_t j;						\
		for (j = 0; j < pad_len; j++)				\
			APPEND_C(' ');					\
	}								\
} while (0)
#define GET_ARG_NUMERIC(val, len) do {					\
	switch (len) {							\
	case '?':							\
		val = va_arg(ap, int);					\
		break;							\
	case '?' | 0x80:						\
		val = va_arg(ap, unsigned int);				\
		break;							\
	case 'l':							\
		val = va_arg(ap, long);					\
		break;							\
	case 'l' | 0x80:						\
		val = va_arg(ap, unsigned long);			\
		break;							\
	case 'q':							\
		val = va_arg(ap, long long);				\
		break;							\
	case 'q' | 0x80:						\
		val = va_arg(ap, unsigned long long);			\
		break;							\
	case 'j':							\
		val = va_arg(ap, intmax_t);				\
		break;							\
	case 't':							\
		val = va_arg(ap, ptrdiff_t);				\
		break;							\
	case 'z':							\
		val = va_arg(ap, ssize_t);				\
		break;							\
	case 'z' | 0x80:						\
		val = va_arg(ap, size_t);				\
		break;							\
	case 'p': /* Synthetic; used for %p. */				\
		val = va_arg(ap, uintptr_t);				\
		break;							\
	default: not_reached();						\
	}								\
} while (0)

	i = 0;
	f = format;
	while (true) {
		switch (*f) {
		case '\0': goto label_out;
		case '%': {
			bool alt_form = false;
			bool zero_pad = false;
			bool left_justify = false;
			bool plus_space = false;
			bool plus_plus = false;
			int prec = -1;
			int width = -1;
			unsigned char len = '?';

			f++;
			if (*f == '%') {
				/* %% */
				APPEND_C(*f);
				break;
			}
			/* Flags. */
			while (true) {
				switch (*f) {
				case '#':
					assert(alt_form == false);
					alt_form = true;
					break;
				case '0':
					assert(zero_pad == false);
					zero_pad = true;
					break;
				case '-':
					assert(left_justify == false);
					left_justify = true;
					break;
				case ' ':
					assert(plus_space == false);
					plus_space = true;
					break;
				case '+':
					assert(plus_plus == false);
					plus_plus = true;
					break;
				default: goto label_width;
				}
				f++;
			}
			/* Width. */
			label_width:
			switch (*f) {
			case '*':
				width = va_arg(ap, int);
				f++;
				break;
			case '0': case '1': case '2': case '3': case '4':
			case '5': case '6': case '7': case '8': case '9': {
				uintmax_t uwidth;
				set_errno(0);
				uwidth = malloc_strtoumax(f, (char **)&f, 10);
				assert(uwidth != UINTMAX_MAX || get_errno() !=
				    ERANGE);
				width = (int)uwidth;
				if (*f == '.') {
					f++;
					goto label_precision;
				} else
					goto label_length;
				break;
			} case '.':
				f++;
				goto label_precision;
			default: goto label_length;
			}
			/* Precision. */
			label_precision:
			switch (*f) {
			case '*':
				prec = va_arg(ap, int);
				f++;
				break;
			case '0': case '1': case '2': case '3': case '4':
			case '5': case '6': case '7': case '8': case '9': {
				uintmax_t uprec;
				set_errno(0);
				uprec = malloc_strtoumax(f, (char **)&f, 10);
				assert(uprec != UINTMAX_MAX || get_errno() !=
				    ERANGE);
				prec = (int)uprec;
				break;
			}
			default: break;
			}
			/* Length. */
			label_length:
			switch (*f) {
			case 'l':
				f++;
				if (*f == 'l') {
					len = 'q';
					f++;
				} else
					len = 'l';
				break;
			case 'j':
				len = 'j';
				f++;
				break;
			case 't':
				len = 't';
				f++;
				break;
			case 'z':
				len = 'z';
				f++;
				break;
			default: break;
			}
			/* Conversion specifier. */
			switch (*f) {
				char *s;
				size_t slen;
			case 'd': case 'i': {
				intmax_t val JEMALLOC_CC_SILENCE_INIT(0);
				char buf[D2S_BUFSIZE];

				GET_ARG_NUMERIC(val, len);
				s = d2s(val, (plus_plus ? '+' : (plus_space ?
				    ' ' : '-')), buf, &slen);
				APPEND_PADDED_S(s, slen, width, left_justify);
				f++;
				break;
			} case 'o': {
				uintmax_t val JEMALLOC_CC_SILENCE_INIT(0);
				char buf[O2S_BUFSIZE];

				GET_ARG_NUMERIC(val, len | 0x80);
				s = o2s(val, alt_form, buf, &slen);
				APPEND_PADDED_S(s, slen, width, left_justify);
				f++;
				break;
			} case 'u': {
				uintmax_t val JEMALLOC_CC_SILENCE_INIT(0);
				char buf[U2S_BUFSIZE];

				GET_ARG_NUMERIC(val, len | 0x80);
				s = u2s(val, 10, false, buf, &slen);
				APPEND_PADDED_S(s, slen, width, left_justify);
				f++;
				break;
			} case 'x': case 'X': {
				uintmax_t val JEMALLOC_CC_SILENCE_INIT(0);
				char buf[X2S_BUFSIZE];

				GET_ARG_NUMERIC(val, len | 0x80);
				s = x2s(val, alt_form, *f == 'X', buf, &slen);
				APPEND_PADDED_S(s, slen, width, left_justify);
				f++;
				break;
			} case 'c': {
				unsigned char val;
				char buf[2];

				assert(len == '?' || len == 'l');
				assert_not_implemented(len != 'l');
				val = va_arg(ap, int);
				buf[0] = val;
				buf[1] = '\0';
				APPEND_PADDED_S(buf, 1, width, left_justify);
				f++;
				break;
			} case 's':
				assert(len == '?' || len == 'l');
				assert_not_implemented(len != 'l');
				s = va_arg(ap, char *);
				slen = (prec == -1) ? strlen(s) : prec;
				APPEND_PADDED_S(s, slen, width, left_justify);
				f++;
				break;
			case 'p': {
				uintmax_t val;
				char buf[X2S_BUFSIZE];

				GET_ARG_NUMERIC(val, 'p');
				s = x2s(val, true, false, buf, &slen);
				APPEND_PADDED_S(s, slen, width, left_justify);
				f++;
				break;
			}
			default: not_implemented();
			}
			break;
		} default: {
			APPEND_C(*f);
			f++;
			break;
		}}
	}
	label_out:
	if (i < size)
		str[i] = '\0';
	else
		str[size - 1] = '\0';
	ret = i;

#undef APPEND_C
#undef APPEND_S
#undef APPEND_PADDED_S
#undef GET_ARG_NUMERIC
	return (ret);
}