mirror of
git://projects.qi-hardware.com/ben-blinkenlights.git
synced 2024-11-16 19:15:55 +02:00
ubb-la/gui.c: experimental GUI code (WIP)
This commit is contained in:
parent
b7688f3abe
commit
94e099eebc
179
ubb-la/gui.c
Normal file
179
ubb-la/gui.c
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* gui.c - Graphical output for ubb-la
|
||||
*
|
||||
* Written 2013 by Werner Almesberger
|
||||
* Copyright 2013 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.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "SDL.h"
|
||||
#include "SDL_gfxPrimitives.h"
|
||||
|
||||
#include "gui.h"
|
||||
|
||||
|
||||
#define XRES 320 /* canvas width */
|
||||
#define YRES 240 /* canvas height */
|
||||
|
||||
#define LEVEL_RGBA 0xffff00ff
|
||||
#define BOUNCE_RGBA 0xff8080ff
|
||||
|
||||
#define CH_XOFF 30
|
||||
#define CH_YOFF 30
|
||||
#define CH_SKIP 16
|
||||
#define CH_HEIGHT 8
|
||||
|
||||
#define MAX_ZOOM 8
|
||||
|
||||
|
||||
static SDL_Surface *surf;
|
||||
|
||||
|
||||
void gui_init(void)
|
||||
{
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||
fprintf(stderr, "SDL_init: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
atexit(SDL_Quit);
|
||||
|
||||
surf = SDL_SetVideoMode(XRES, YRES, 0, SDL_SWSURFACE);
|
||||
if (!surf) {
|
||||
fprintf(stderr, "SDL_SetVideoMode: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void clear(void)
|
||||
{
|
||||
SDL_LockSurface(surf);
|
||||
SDL_FillRect(surf, NULL, SDL_MapRGB(surf->format, 0, 0, 0));
|
||||
}
|
||||
|
||||
|
||||
static inline int ch_y(int ch, int v)
|
||||
{
|
||||
return CH_YOFF+CH_SKIP*ch+(v ? 0 : CH_HEIGHT);
|
||||
}
|
||||
|
||||
|
||||
static void bounce(int x, int ch)
|
||||
{
|
||||
vlineColor(surf, x, ch_y(ch, 0), ch_y(ch, 1), BOUNCE_RGBA);
|
||||
}
|
||||
|
||||
|
||||
static void change(int x, int ch)
|
||||
{
|
||||
vlineColor(surf, x, ch_y(ch, 0), ch_y(ch, 1), LEVEL_RGBA);
|
||||
}
|
||||
|
||||
|
||||
static void level(int x, int ch, int v)
|
||||
{
|
||||
pixelColor(surf, x, ch_y(ch, v), LEVEL_RGBA);
|
||||
}
|
||||
|
||||
|
||||
static void show_buffer(const uint8_t *buf, int skip, int nibbles,
|
||||
int x0, int x1)
|
||||
{
|
||||
double f = (nibbles-skip)/(x1-x0+1.0);
|
||||
int x;
|
||||
int i = skip-1, n, j;
|
||||
int changes[4], last[4] = { -1, -1, -1, -1}, next[4];
|
||||
uint8_t v, bit;
|
||||
|
||||
for (x = x0; x != x1+1; x++) {
|
||||
n = (x-x0)*f+skip;
|
||||
if (i == n) {
|
||||
for (j = 0; j != 4; j++)
|
||||
level(x, j, last[j]);
|
||||
continue;
|
||||
}
|
||||
for (j = 0; j != 4; j++) {
|
||||
next[j] = last[j];
|
||||
changes[j] = 0;
|
||||
}
|
||||
while (i != n) {
|
||||
i++;
|
||||
v = (buf[i >> 1] >> 4*(~i & 1)) & 0xf;
|
||||
for (j = 0; j != 4; j++) {
|
||||
bit = (v >> j) & 1;
|
||||
if (bit != next[j]) {
|
||||
changes[j]++;
|
||||
next[j] = bit;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (j = 0; j != 4; j++) {
|
||||
if (changes[j] > 1)
|
||||
bounce(x, j);
|
||||
else if (!changes[j] || last[j] == -1)
|
||||
level(x, j, next[j]);
|
||||
else
|
||||
change(x, j);
|
||||
last[j] = next[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void update(void)
|
||||
{
|
||||
SDL_UnlockSurface(surf);
|
||||
SDL_UpdateRect(surf, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
void gui(const uint8_t *buf, int skip, int nibbles)
|
||||
{
|
||||
SDL_Event event;
|
||||
int zoom = 0;
|
||||
int m, w;
|
||||
|
||||
while (1) {
|
||||
m = (nibbles-skip) >> 1;
|
||||
w = (nibbles-skip) >> zoom;
|
||||
clear();
|
||||
show_buffer(buf, m-(w >> 1), m+(w >> 1), CH_XOFF, XRES-1);
|
||||
update();
|
||||
|
||||
do {
|
||||
SDL_WaitEvent(&event);
|
||||
switch (event.type) {
|
||||
case SDL_KEYDOWN:
|
||||
switch (event.key.keysym.sym) {
|
||||
case SDLK_UP:
|
||||
if (zoom < MAX_ZOOM)
|
||||
zoom++;
|
||||
break;
|
||||
case SDLK_DOWN:
|
||||
if (zoom)
|
||||
zoom--;
|
||||
break;
|
||||
case SDLK_RETURN:
|
||||
case SDLK_q:
|
||||
return;
|
||||
default:
|
||||
printf("%x\n", event.key.keysym.sym);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case SDL_QUIT:
|
||||
return;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
while (0);
|
||||
}
|
||||
}
|
23
ubb-la/gui.h
Normal file
23
ubb-la/gui.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* gui.h - Graphical output for ubb-la
|
||||
*
|
||||
* Written 2013 by Werner Almesberger
|
||||
* Copyright 2013 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GUI_H
|
||||
#define GUI_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
void gui_init(void);
|
||||
void gui(const uint8_t *buf, int skip, int nibbles);
|
||||
|
||||
#endif /* !GUI_H */
|
Loading…
Reference in New Issue
Block a user