Root/ubb-vga/tstimg.c

1/*
2 * tstimg.c - Generate a test image
3 *
4 * Written 2011 by Werner Almesberger
5 * Copyright 2011 Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13/*
14 * WARNING: this program does very nasty things to the Ben and it doesn't
15 * like company. In particular, it resents:
16 *
17 * - the MMC driver - disable it with
18 * echo jz4740-mmc.0 >/sys/bus/platform/drivers/jz4740-mmc/unbind
19 * - the AT86RF230/1 kernel driver - use a kernel that doesn't have it
20 * - anything that accesses the screen - kill GUI, X server, etc.
21 * - the screen blanker - either disable it or make sure the screen stays
22 * dark, e.g., with
23 * echo 1 >/sys/devices/platform/jz4740-fb/graphics/fb0/blank
24 * - probably a fair number of other daemons and things as well - best to
25 * kill them all.
26 */
27
28
29#include <stdint.h>
30#include <stdio.h>
31#include <string.h>
32#include <math.h>
33
34#include "ubb-vga.h"
35
36
37/* ----- Pixel operations -------------------------------------------------- */
38
39
40#define WHITE 0xf
41
42
43static void pixel(void **f, int xres, int x, int y, uint8_t c)
44{
45    uint8_t *p;
46
47    p = f[y]+(x >> 1);
48    if (x & 1)
49        *p = (*p & 0xf0) | c;
50    else
51        *p = (*p & 0x0f) | (c << 4);
52}
53
54
55/* ----- Color bars -------------------------------------------------------- */
56
57
58#define CBAR_X0 0.1
59#define CBAR_X1 0.9
60#define CBAR_Y0 0.55
61#define CBAR_Y1 0.75
62
63
64static void color_bars(void **f, int xres, int yres, ...)
65{
66    int i, x, y;
67    uint8_t c;
68
69    for (i = 0; i < xres*(CBAR_X1-CBAR_X0); i++) {
70        x = i+xres*CBAR_X0;
71        c = 1+15*i/(xres*(CBAR_X1-CBAR_X0));
72        for (y = yres*CBAR_Y0; y < yres*CBAR_Y1; y++)
73            pixel(f, xres, x, y, c);
74    }
75}
76
77
78/* ----- Grid -------------------------------------------------------------- */
79
80
81#define GRID 50
82
83
84static void grill(void **f, int ares, int bres, int swap)
85{
86    int n, o;
87    int i, a, b;
88
89    n = (ares-1)/GRID+1;
90    o = ((ares-1) % GRID)/2;
91    if (!(n & 1)) {
92        n--;
93        o += GRID/2;
94    }
95    for (i = 0; i != n; i++) {
96        a = o+i*GRID;
97        for (b = 0; b != bres-1; b++)
98            if (swap)
99                pixel(f, bres, b, a, WHITE);
100            else
101                pixel(f, ares, a, b, WHITE);
102    }
103
104    if (o <= GRID/2) {
105        o += GRID/2;
106        n--;
107    } else {
108        o -= GRID/2;
109        n++;
110    }
111    for (i = 0; i != n; i++) {
112        a = o+i*GRID;
113        for (b = -GRID/4; b != GRID/4; b++)
114            if (swap)
115                pixel(f, bres, bres/2+b, a, WHITE);
116            else
117                pixel(f, ares, a, bres/2+b, WHITE);
118    }
119}
120
121
122static void grid(void **f, int xres, int yres)
123{
124    grill(f, xres, yres, 0);
125    grill(f, yres, xres, 1);
126}
127
128
129/* ----- Diagonal lines meeting at the sides ------------------------------- */
130
131
132static void sides(void **f, int xres, int yres)
133{
134    int i;
135
136    for (i = 0; i != yres/2; i++) {
137        pixel(f, xres, i, yres/2-i, WHITE);
138        pixel(f, xres, i, yres/2+i, WHITE);
139        pixel(f, xres, xres-i-1, yres/2-i, WHITE);
140        pixel(f, xres, xres-i-1, yres/2+i, WHITE);
141    }
142    for (i = 0; i != xres/2; i++) {
143        pixel(f, xres, xres/2-i, i, WHITE);
144        pixel(f, xres, xres/2+i, i, WHITE);
145        pixel(f, xres, xres/2-i, yres-i-1, WHITE);
146        pixel(f, xres, xres/2+i, yres-i-1, WHITE);
147    }
148}
149
150
151/* ----- Text -------------------------------------------------------------- */
152
153
154static void dot(void **f, int xres, int x, int y, int color, int side)
155{
156    int xi, yi;
157
158    for (xi = -side; xi != side+1; xi++)
159        for (yi = -side; yi != side+1; yi++)
160            pixel(f, xres, x+xi, y+yi, color);
161}
162
163
164static void line45(void **f, int xres, int x, int y, int dx, int dy, int n,
165     uint8_t color, int side)
166{
167    while (n--) {
168        dot(f, xres, x, y, color, side);
169        x += dx;
170        y += dy;
171    }
172    dot(f, xres, x, y, color, side);
173}
174
175
176static void arc(void **f, int xres, int x, int y, int n, int q,
177    uint8_t color, int side)
178{
179    int dx, dy;
180
181    for (dx = 0; dx != n+1; dx++) {
182        dy = sqrt(n*n-dx*dx);
183        if (q & 1)
184            dot(f, xres, x+dx, y-dy, color, side);
185        if (q & 2)
186            dot(f, xres, x+dx, y+dy, color, side);
187        if (q & 4)
188            dot(f, xres, x-dx, y+dy, color, side);
189        if (q & 8)
190            dot(f, xres, x-dx, y-dy, color, side);
191    }
192}
193
194
195static void printc(void **f, int xres, int x, int y, char c, int n,
196    uint8_t color, int side)
197{
198    switch (c) {
199    case '0':
200        arc(f, xres, x+n, y+n, n, 9, color, side);
201        line45(f, xres, x, y+n, 0, 1, 2*n, color, side);
202        line45(f, xres, x+2*n, y+n, 0, 1, 2*n, color, side);
203        arc(f, xres, x+n, y+3*n, n, 6, color, side);
204        line45(f, xres, x, y+3*n, 1, -1, 2*n, color, side);
205        break;
206    case '1':
207        line45(f, xres, x, y+n, 1, -1, n, color, side);
208        line45(f, xres, x+n, y, 0, 1, 4*n, color, side);
209        break;
210    case '2':
211        arc(f, xres, x+n, y+n, n, 9, color, side);
212        line45(f, xres, x+2*n, y+n, 0, 1, n, color, side);
213        line45(f, xres, x, y+4*n, 1, -1, 2*n, color, side);
214        line45(f, xres, x, y+4*n, 1, 0, 2*n, color, side);
215        break;
216    case '3':
217        arc(f, xres, x+n, y+n, n, 3, color, side);
218        arc(f, xres, x+n, y+3*n, n, 3, color, side);
219        line45(f, xres, x, y, 1, 0, n, color, side);
220        line45(f, xres, x, y+2*n, 1, 0, n, color, side);
221        line45(f, xres, x, y+4*n, 1, 0, n, color, side);
222        break;
223    case '4':
224        line45(f, xres, x, y, 0, 1, 2*n, color, side);
225        line45(f, xres, x, y+2*n, 1, 0, 2*n, color, side);
226        line45(f, xres, x+2*n, y, 0, 1, 4*n, color, side);
227        break;
228    case '5':
229        line45(f, xres, x, y, 1, 0, 2*n, color, side);
230        line45(f, xres, x, y, 0, 1, 2*n, color, side);
231        line45(f, xres, x, y+2*n, 1, 0, n, color, side);
232        arc(f, xres, x+n, y+3*n, n, 7, color, side);
233        break;
234    case '6':
235        arc(f, xres, x+n, y+n, n, 9, color, side);
236        line45(f, xres, x, y+n, 0, 1, 2*n, color, side);
237        arc(f, xres, x+n, y+3*n, n, 15, color, side);
238        break;
239    case '7':
240        line45(f, xres, x, y, 1, 0, 2*n, color, side);
241        line45(f, xres, x+2*n, y, 0, 1, 2*n, color, side);
242        line45(f, xres, x, y+4*n, 1, -1, 2*n, color, side);
243        break;
244    case '8':
245        arc(f, xres, x+n, y+n, n, 15, color, side);
246        arc(f, xres, x+n, y+3*n, n, 15, color, side);
247        break;
248    case '9':
249        arc(f, xres, x+n, y+n, n, 15, color, side);
250        line45(f, xres, x+2*n, y+n, 0, 1, 2*n, color, side);
251        arc(f, xres, x+n, y+3*n, n, 6, color, side);
252        break;
253    case 'x':
254        line45(f, xres, x, y+n, 1, 1, 2*n, color, side);
255        line45(f, xres, x, y+3*n, 1, -1, 2*n, color, side);
256        break;
257    case 'A':
258        line45(f, xres, x, y+n, 1, -1, n, color, side);
259        line45(f, xres, x, y+n, 0, 1, 3*n, color, side);
260        line45(f, xres, x+n, y, 1, 1, n, color, side);
261        line45(f, xres, x+2*n, y+n, 0, 1, 3*n, color, side);
262        line45(f, xres, x, y+2*n, 1, 0, 2*n, color, side);
263        break;
264    case 'B':
265        arc(f, xres, x+n, y+n, n, 3, color, side);
266        arc(f, xres, x+n, y+3*n, n, 3, color, side);
267        line45(f, xres, x, y, 1, 0, n, color, side);
268        line45(f, xres, x, y+2*n, 1, 0, n, color, side);
269        line45(f, xres, x, y+4*n, 1, 0, n, color, side);
270        line45(f, xres, x, y, 0, 1, 4*n, color, side);
271        break;
272    case 'C':
273        arc(f, xres, x+n, y+n, n, 9, color, side);
274        line45(f, xres, x, y+n, 0, 1, 2*n, color, side);
275        arc(f, xres, x+n, y+3*n, n, 6, color, side);
276        break;
277    case 'D':
278        arc(f, xres, x+n, y+n, n, 1, color, side);
279        line45(f, xres, x, y, 0, 1, 4*n, color, side);
280        line45(f, xres, x+2*n, y+n, 0, 1, 3*n, color, side);
281        line45(f, xres, x, y, 1, 0, n, color, side);
282        line45(f, xres, x, y+4*n, 1, 0, n, color, side);
283        arc(f, xres, x+n, y+3*n, n, 2, color, side);
284        break;
285    case 'E':
286        line45(f, xres, x, y, 0, 1, 4*n, color, side);
287        line45(f, xres, x, y, 1, 0, 2*n, color, side);
288        line45(f, xres, x, y+2*n, 1, 0, 2*n, color, side);
289        line45(f, xres, x, y+4*n, 1, 0, 2*n, color, side);
290        break;
291    case 'F':
292        line45(f, xres, x, y, 0, 1, 4*n, color, side);
293        line45(f, xres, x, y, 1, 0, 2*n, color, side);
294        line45(f, xres, x, y+2*n, 1, 0, 2*n, color, side);
295        break;
296    case 'G':
297        arc(f, xres, x+n, y+n, n, 9, color, side);
298        line45(f, xres, x, y+n, 0, 1, 2*n, color, side);
299        arc(f, xres, x+n, y+3*n, n, 6, color, side);
300        line45(f, xres, x+n, y+2*n, 1, 0, n, color, side);
301        line45(f, xres, x+2*n, y+2*n, 0, 1, n, color, side);
302        break;
303    case 'H':
304        line45(f, xres, x, y, 0, 1, 4*n, color, side);
305        line45(f, xres, x+2*n, y, 0, 1, 4*n, color, side);
306        line45(f, xres, x, y+2*n, 1, 0, 2*n, color, side);
307        break;
308    case 'I':
309        line45(f, xres, x+n, y, 0, 1, 4*n, color, side);
310        line45(f, xres, x, y, 1, 0, 2*n, color, side);
311        line45(f, xres, x, y+4*n, 1, 0, 2*n, color, side);
312        break;
313    case 'J':
314        line45(f, xres, x+2*n, y, 0, 1, 3*n, color, side);
315        arc(f, xres, x+n, y+3*n, n, 6, color, side);
316        break;
317    case 'K':
318        line45(f, xres, x, y, 0, 1, 4*n, color, side);
319        line45(f, xres, x, y+2*n, 1, -1, 2*n, color, side);
320        line45(f, xres, x, y+2*n, 1, 1, 2*n, color, side);
321        break;
322    case 'L':
323        line45(f, xres, x, y, 0, 1, 4*n, color, side);
324        line45(f, xres, x, y+4*n, 1, 0, 2*n, color, side);
325        break;
326    case 'M':
327        line45(f, xres, x, y, 0, 1, 4*n, color, side);
328        line45(f, xres, x+2*n, y, 0, 1, 4*n, color, side);
329        line45(f, xres, x, y, 1, 1, n, color, side);
330        line45(f, xres, x+n, y+n, 1, -1, n, color, side);
331        line45(f, xres, x+n, y+1*n, 0, 1, n, color, side);
332        break;
333    case 'N':
334        line45(f, xres, x, y, 0, 1, 4*n, color, side);
335        line45(f, xres, x+2*n, y, 0, 1, 4*n, color, side);
336        line45(f, xres, x, y, 1, 1, n, color, side);
337        line45(f, xres, x+n, y+n, 0, 1, 2*n, color, side);
338        line45(f, xres, x+n, y+3*n, 1, 1, n, color, side);
339        break;
340    case 'O':
341        arc(f, xres, x+n, y+n, n, 9, color, side);
342        line45(f, xres, x, y+n, 0, 1, 2*n, color, side);
343        line45(f, xres, x+2*n, y+n, 0, 1, 2*n, color, side);
344        arc(f, xres, x+n, y+3*n, n, 6, color, side);
345        break;
346    case 'P':
347        line45(f, xres, x, y, 0, 1, 4*n, color, side);
348        line45(f, xres, x, y, 1, 0, n, color, side);
349        line45(f, xres, x, y+2*n, 1, 0, n, color, side);
350        arc(f, xres, x+n, y+n, n, 3, color, side);
351        break;
352    case 'Q':
353        arc(f, xres, x+n, y+n, n, 9, color, side);
354        line45(f, xres, x, y+n, 0, 1, 2*n, color, side);
355        line45(f, xres, x+2*n, y+n, 0, 1, 2*n, color, side);
356        arc(f, xres, x+n, y+3*n, n, 6, color, side);
357        line45(f, xres, x+n, y+3*n, 1, 1, n, color, side);
358        break;
359    case 'R':
360        line45(f, xres, x, y, 0, 1, 4*n, color, side);
361        line45(f, xres, x, y, 1, 0, n, color, side);
362        line45(f, xres, x, y+2*n, 1, 0, n, color, side);
363        arc(f, xres, x+n, y+n, n, 3, color, side);
364        line45(f, xres, x, y+2*n, 1, 1, 2*n, color, side);
365        break;
366    case 'S':
367        arc(f, xres, x+n, y+n, n, 9, color, side);
368        line45(f, xres, x, y+n, 1, 1, 2*n, color, side);
369        arc(f, xres, x+n, y+3*n, n, 6, color, side);
370        break;
371    case 'T':
372        line45(f, xres, x+n, y, 0, 1, 4*n, color, side);
373        line45(f, xres, x, y, 1, 0, 2*n, color, side);
374        break;
375    case 'U':
376        line45(f, xres, x, y, 0, 1, 3*n, color, side);
377        line45(f, xres, x+2*n, y, 0, 1, 3*n, color, side);
378        arc(f, xres, x+n, y+3*n, n, 6, color, side);
379        break;
380    case 'V':
381        line45(f, xres, x, y, 0, 1, 3*n, color, side);
382        line45(f, xres, x+2*n, y, 0, 1, 3*n, color, side);
383        line45(f, xres, x+n, y+4*n, 1, -1, n, color, side);
384        line45(f, xres, x+n, y+4*n, -1, -1, n, color, side);
385        break;
386    case 'W':
387        line45(f, xres, x, y, 0, 1, 4*n, color, side);
388        line45(f, xres, x+2*n, y, 0, 1, 4*n, color, side);
389        line45(f, xres, x, y+4*n, 1, -1, n, color, side);
390        line45(f, xres, x+n, y+3*n, 1, 1, n, color, side);
391        line45(f, xres, x+n, y+2*n, 0, 1, n, color, side);
392        break;
393    case 'X':
394        line45(f, xres, x, y+n, 1, 1, 2*n, color, side);
395        line45(f, xres, x, y+3*n, 1, -1, 2*n, color, side);
396        line45(f, xres, x, y, 0, 1, n, color, side);
397        line45(f, xres, x+2*n, y, 0, 1, n, color, side);
398        line45(f, xres, x, y+3*n, 0, 1, n, color, side);
399        line45(f, xres, x+2*n, y+3*n, 0, 1, n, color, side);
400        break;
401    case 'Y':
402        line45(f, xres, x, y, 0, 1, n, color, side);
403        line45(f, xres, x+2*n, y, 0, 1, n, color, side);
404        line45(f, xres, x, y+n, 1, 1, n, color, side);
405        line45(f, xres, x+2*n, y+n, -1, 1, n, color, side);
406        line45(f, xres, x+n, y+2*n, 0, 1, 2*n, color, side);
407        break;
408    case 'Z':
409        line45(f, xres, x, y, 1, 0, 2*n, color, side);
410        line45(f, xres, x, y+4*n, 1, 0, 2*n, color, side);
411        line45(f, xres, x+2*n, y, 0, 1, n, color, side);
412        line45(f, xres, x, y+3*n, 0, 1, n, color, side);
413        line45(f, xres, x, y+3*n, 1, -1, 2*n, color, side);
414        break;
415    case '-':
416        line45(f, xres, x, y+2*n, 1, 0, 2*n, color, side);
417        break;
418    case '=':
419        line45(f, xres, x, y+1*n, 1, 0, 2*n, color, side);
420        line45(f, xres, x, y+3*n, 1, 0, 2*n, color, side);
421        break;
422    case '+':
423        line45(f, xres, x, y+2*n, 1, 0, 2*n, color, side);
424        line45(f, xres, x+n, y+n, 0, 1, 2*n, color, side);
425        break;
426    case ' ':
427        break;
428    case '.':
429        line45(f, xres, x+n, y+3*n, 0, 1, n, color, side);
430        break;
431    default:
432        arc(f, xres, x+n, y+n, n, 9, color, side);
433        line45(f, xres, x+n, y+2*n, 1, -1, n, color, side);
434        line45(f, xres, x+n, y+3*n, 0, 1, n, color, side);
435        break;
436    }
437}
438
439
440static void text(void **f, int xres, int x, int y, const char *s, int n,
441    uint8_t color, int side)
442{
443    while (*s) {
444        printc(f, xres, x, y, *s, n, color, side);
445        x += 3*n;
446        s++;
447    }
448}
449
450
451
452static void ctext(void **f, int xres, int x, int y, const char *s, int n,
453    uint8_t color, int side)
454{
455    text(f, xres, x+n*(1-3*(int) strlen(s))/2, y-2*n, s, n, color, side);
456}
457
458
459/* ----- Generate the test image ------------------------------------------- */
460
461
462void tstimg(void **f, int xres, int yres)
463{
464    char buf[40];
465    double line_freq_hz;
466    int y, n;
467
468    grid(f, xres, yres);
469    sides(f, xres, yres);
470    color_bars(f, xres, yres);
471
472    sprintf(buf, "UBB-VGA %dx%d", xres, yres);
473    ctext(f, xres, xres/2, yres/2-GRID*0.75, buf, 10, WHITE, 3);
474    ctext(f, xres, xres/2, yres*(CBAR_Y0+CBAR_Y1)/2, buf, 2, 0, 0);
475
476    y = yres/8;
477    n = 5;
478    if (yres < 768)
479        y = yres/16;
480    if (yres < 600)
481        n = 4;
482
483    sprintf(buf, "PIXEL %5.2f MHZ", 336.0/(mode->clkdiv+1));
484    text(f, xres, xres/8, y, buf, n, WHITE, 1);
485    y += 6*n;
486
487    line_freq_hz = 112000000.0/(mode->line_cycles);
488    sprintf(buf, "LINE %5.2f KHZ", line_freq_hz/1000);
489    text(f, xres, xres/8, y, buf, n, WHITE, 1);
490    y += 6*n;
491
492    sprintf(buf, "FRAME %5.2f HZ",
493        line_freq_hz/(mode->vsync_lines+ mode->vfront_lines+mode->yres+
494        mode->vback_lines));
495    text(f, xres, xres/8, y, buf, n, WHITE, 1);
496    y += 6*n;
497
498    sprintf(buf, "VERT %d+%d+%d+%d LINES",
499        mode->vsync_lines, mode->vfront_lines, mode->yres,
500        mode->vback_lines);
501    text(f, xres, xres/8, y, buf, n, WHITE, 1);
502    y += 6*n;
503
504    sprintf(buf, "HOR %4.2f+...+%4.2f = %5.2f US",
505        CYCLES(mode->hsync_cycles), CYCLES(mode->hback_cycles),
506        CYCLES(mode->line_cycles));
507    text(f, xres, xres/8, y, buf, n, WHITE, 1);
508}
509

Archive Download this file

Branches:
master



interactive