1
0
mirror of git://projects.qi-hardware.com/ben-blinkenlights.git synced 2024-11-04 23:29:23 +02:00
ben-blinkenlights/ubb-vga/tstimg.c
Werner Almesberger 19f43a77c9 ubb-vga2: added test image generator (option -t)
- tstimg.c: test image generator
- Makefile (OBJS): added tstimg.o
- Makefile (LDFLAGS): tstimg.c needs libm
- ubb-vga2.c (session, main): pass image generator as a function pointer
- ubb-vga2.c (main): new option -t to select the test image generator
2011-04-27 23:31:39 -03:00

336 lines
8.2 KiB
C

/*
* tstimg.c - Generate a test image
*
* Written 2011 by Werner Almesberger
* Copyright 2011 Werner Almesberger
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
/*
* WARNING: this program does very nasty things to the Ben and it doesn't
* like company. In particular, it resents:
*
* - the MMC driver - disable it with
* echo jz4740-mmc.0 >/sys/bus/platform/drivers/jz4740-mmc/unbind
* - the AT86RF230/1 kernel driver - use a kernel that doesn't have it
* - anything that accesses the screen - kill GUI, X server, etc.
* - the screen blanker - either disable it or make sure the screen stays
* dark, e.g., with
* echo 1 >/sys/devices/platform/jz4740-fb/graphics/fb0/blank
* - probably a fair number of other daemons and things as well - best to
* kill them all.
*/
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "ubb-vga.h"
/* ----- Pixel operations -------------------------------------------------- */
#define WHITE 0xf
static void pixel(void *f, int xres, int x, int y, uint8_t c)
{
uint8_t *p;
p = f+((y*xres+x) >> 1);
if (x & 1)
*p = (*p & 0xf0) | c;
else
*p = (*p & 0x0f) | (c << 4);
}
/* ----- Color bars -------------------------------------------------------- */
#define CBAR_X0 0.1
#define CBAR_X1 0.9
#define CBAR_Y0 0.55
#define CBAR_Y1 0.75
static void color_bars(void *f, int xres, int yres, ...)
{
int i, x, y;
uint8_t c;
for (i = 0; i < xres*(CBAR_X1-CBAR_X0); i++) {
x = i+xres*CBAR_X0;
c = 1+15*i/(xres*(CBAR_X1-CBAR_X0));
for (y = yres*CBAR_Y0; y < yres*CBAR_Y1; y++)
pixel(f, xres, x, y, c);
}
}
/* ----- Grid -------------------------------------------------------------- */
#define GRID 50
static void grill(void *f, int ares, int bres, int swap)
{
int n, o;
int i, a, b;
n = ares/GRID+1;
o = (ares % GRID)/2;
if (!(n & 1)) {
n--;
o += GRID/2;
}
for (i = 0; i != n; i++) {
a = o+i*GRID;
for (b = 0; b != bres; b++)
if (swap)
pixel(f, bres, b, a, WHITE);
else
pixel(f, ares, a, b, WHITE);
}
if (o <= GRID/2) {
o += GRID/2;
n--;
} else {
o -= GRID/2;
n++;
}
for (i = 0; i != n; i++) {
a = o+i*GRID;
for (b = -GRID/4; b != GRID/4; b++)
if (swap)
pixel(f, bres, bres/2+b, a, WHITE);
else
pixel(f, ares, a, bres/2+b, WHITE);
}
}
static void grid(void *f, int xres, int yres)
{
grill(f, xres, yres, 0);
grill(f, yres, xres, 1);
}
/* ----- Diagonal lines meeting at the sides ------------------------------- */
static void sides(void *f, int xres, int yres)
{
int i;
for (i = 0; i != yres/2; i++) {
pixel(f, xres, i, yres/2-i, WHITE);
pixel(f, xres, i, yres/2+i, WHITE);
pixel(f, xres, xres-i-1, yres/2-i, WHITE);
pixel(f, xres, xres-i-1, yres/2+i, WHITE);
}
for (i = 0; i != xres/2; i++) {
pixel(f, xres, xres/2-i, i, WHITE);
pixel(f, xres, xres/2+i, i, WHITE);
pixel(f, xres, xres/2-i, yres-i-1, WHITE);
pixel(f, xres, xres/2+i, yres-i-1, WHITE);
}
}
/* ----- Text -------------------------------------------------------------- */
static void dot(void *f, int xres, int x, int y, int color, int side)
{
int xi, yi;
for (xi = -side; xi != side+1; xi++)
for (yi = -side; yi != side+1; yi++)
pixel(f, xres, x+xi, y+yi, color);
}
static void line45(void *f, int xres, int x, int y, int dx, int dy, int n,
uint8_t color, int side)
{
while (n--) {
dot(f, xres, x, y, color, side);
x += dx;
y += dy;
}
dot(f, xres, x, y, color, side);
}
static void arc(void *f, int xres, int x, int y, int n, int q,
uint8_t color, int side)
{
int dx, dy;
for (dx = 0; dx != n+1; dx++) {
dy = sqrt(n*n-dx*dx);
if (q & 1)
dot(f, xres, x+dx, y-dy, color, side);
if (q & 2)
dot(f, xres, x+dx, y+dy, color, side);
if (q & 4)
dot(f, xres, x-dx, y+dy, color, side);
if (q & 8)
dot(f, xres, x-dx, y-dy, color, side);
}
}
static void printc(void *f, int xres, int x, int y, char c, int n,
uint8_t color, int side)
{
switch (c) {
case '0':
arc(f, xres, x+n, y+n, n, 9, color, side);
line45(f, xres, x, y+n, 0, 1, 2*n, color, side);
line45(f, xres, x+2*n, y+n, 0, 1, 2*n, color, side);
arc(f, xres, x+n, y+3*n, n, 6, color, side);
break;
case '1':
line45(f, xres, x+n, y, 0, 1, 4*n, color, side);
break;
case '2':
arc(f, xres, x+n, y+n, n, 9, color, side);
line45(f, xres, x+2*n, y+n, 0, 1, n, color, side);
line45(f, xres, x, y+4*n, 1, -1, 2*n, color, side);
line45(f, xres, x, y+4*n, 1, 0, 2*n, color, side);
break;
case '3':
arc(f, xres, x+n, y+n, n, 3, color, side);
arc(f, xres, x+n, y+3*n, n, 3, color, side);
line45(f, xres, x, y, 1, 0, n, color, side);
line45(f, xres, x, y+2*n, 1, 0, n, color, side);
line45(f, xres, x, y+4*n, 1, 0, n, color, side);
break;
case '4':
line45(f, xres, x, y, 0, 1, 2*n, color, side);
line45(f, xres, x, y+2*n, 1, 0, 2*n, color, side);
line45(f, xres, x+2*n, y, 0, 1, 4*n, color, side);
break;
case '5':
line45(f, xres, x, y, 1, 0, 2*n, color, side);
line45(f, xres, x, y, 0, 1, 2*n, color, side);
line45(f, xres, x, y+2*n, 1, 0, n, color, side);
arc(f, xres, x+n, y+3*n, n, 7, color, side);
break;
case '6':
arc(f, xres, x+n, y+n, n, 9, color, side);
line45(f, xres, x, y+n, 0, 1, 2*n, color, side);
arc(f, xres, x+n, y+3*n, n, 15, color, side);
break;
case '7':
line45(f, xres, x, y, 1, 0, 2*n, color, side);
line45(f, xres, x+2*n, y, 0, 1, 2*n, color, side);
line45(f, xres, x, y+4*n, 1, -1, 2*n, color, side);
break;
case '8':
arc(f, xres, x+n, y+n, n, 15, color, side);
arc(f, xres, x+n, y+3*n, n, 15, color, side);
break;
case '9':
arc(f, xres, x+n, y+n, n, 15, color, side);
line45(f, xres, x+2*n, y+n, 0, 1, 2*n, color, side);
arc(f, xres, x+n, y+3*n, n, 6, color, side);
break;
case 'x':
line45(f, xres, x, y+n, 1, 1, 2*n, color, side);
line45(f, xres, x, y+3*n, 1, -1, 2*n, color, side);
break;
case 'A':
line45(f, xres, x, y+n, 1, -1, n, color, side);
line45(f, xres, x, y+n, 0, 1, 3*n, color, side);
line45(f, xres, x+n, y, 1, 1, n, color, side);
line45(f, xres, x+2*n, y+n, 0, 1, 3*n, color, side);
line45(f, xres, x, y+2*n, 1, 0, 2*n, color, side);
break;
case 'B':
arc(f, xres, x+n, y+n, n, 3, color, side);
arc(f, xres, x+n, y+3*n, n, 3, color, side);
line45(f, xres, x, y, 1, 0, n, color, side);
line45(f, xres, x, y+2*n, 1, 0, n, color, side);
line45(f, xres, x, y+4*n, 1, 0, n, color, side);
line45(f, xres, x, y, 0, 1, 4*n, color, side);
break;
case 'G':
arc(f, xres, x+n, y+n, n, 9, color, side);
line45(f, xres, x, y+n, 0, 1, 2*n, color, side);
arc(f, xres, x+n, y+3*n, n, 6, color, side);
line45(f, xres, x+n, y+2*n, 1, 0, n, color, side);
line45(f, xres, x+2*n, y+2*n, 0, 1, n, color, side);
break;
case 'U':
line45(f, xres, x, y, 0, 1, 3*n, color, side);
line45(f, xres, x+2*n, y, 0, 1, 3*n, color, side);
arc(f, xres, x+n, y+3*n, n, 6, color, side);
break;
case 'V':
line45(f, xres, x, y, 0, 1, 3*n, color, side);
line45(f, xres, x+2*n, y, 0, 1, 3*n, color, side);
line45(f, xres, x+n, y+4*n, 1, -1, n, color, side);
line45(f, xres, x+n, y+4*n, -1, -1, n, color, side);
break;
case '-':
line45(f, xres, x, y+2*n, 1, 0, 2*n, color, side);
break;
case ' ':
break;
default:
arc(f, xres, x+n, y+n, n, 9, color, side);
line45(f, xres, x+n, y+2*n, 1, -1, n, color, side);
line45(f, xres, x+n, y+3*n, 0, 1, n, color, side);
break;
}
}
static void text(void *f, int xres, int x, int y, const char *s, int n,
uint8_t color, int side)
{
while (*s) {
printc(f, xres, x, y, *s, n, color, side);
x += 3*n;
s++;
}
}
static void ctext(void *f, int xres, int x, int y, const char *s, int n,
uint8_t color, int side)
{
text(f, xres, x+n*(1-3*(int) strlen(s))/2, y-2*n, s, n, color, side);
}
/* ----- Generate the test image ------------------------------------------- */
void tstimg(void *f, int xres, int yres)
{
char buf[20];
memset(f, 0, xres*yres/2);
grid(f, xres, yres);
sides(f, xres, yres);
color_bars(f, xres, yres);
sprintf(buf, "UBB-VGA %dx%d", xres, yres);
ctext(f, xres, xres/2, yres/2-GRID*0.75, buf, 10, WHITE, 3);
ctext(f, xres, xres/2, yres*(CBAR_Y0+CBAR_Y1)/2, buf, 2, 0, 0);
}