summaryrefslogtreecommitdiff
path: root/meme/gui.c
diff options
context:
space:
mode:
authorWerner Almesberger <werner@almesberger.net>2014-09-15 18:42:14 (GMT)
committerWerner Almesberger <werner@almesberger.net>2014-09-15 18:42:14 (GMT)
commit6edfd775045fe64620f523c2cf23fa64a4045eb2 (patch)
treee476909efa2ced57f1581c38eff10e575474b410 /meme/gui.c
parent43d5bbb2ce7f6c4e0f2aa250821496ce0c1388be (diff)
downloadmisc-6edfd775045fe64620f523c2cf23fa64a4045eb2.zip
misc-6edfd775045fe64620f523c2cf23fa64a4045eb2.tar.gz
misc-6edfd775045fe64620f523c2cf23fa64a4045eb2.tar.bz2
meme/gui.c: add contrast enhancement mode (hold down C and turn wheel)
Diffstat (limited to 'meme/gui.c')
-rw-r--r--meme/gui.c109
1 files changed, 100 insertions, 9 deletions
diff --git a/meme/gui.c b/meme/gui.c
index 6f78c63..6142a68 100644
--- a/meme/gui.c
+++ b/meme/gui.c
@@ -40,6 +40,7 @@
#define PROFILE_RGBA 0x2020ffff
#define MARK_A_RGBA 0x00ff00ff
#define MARK_B_RGBA 0x3030ffff
+#define CONTRAST_RGBA 0xffe080ff
#define DEPTH_RANGE 0xc0
#define DEPTH_OFFSET 0x30
@@ -149,23 +150,93 @@ static int coord_yz(int x, int y, Sint16 *res_x, Sint16 *res_y)
/* ----- Depth gradient ---------------------------------------------------- */
-static Uint32 *z_grad;
+static Uint32 *default_z_grad, *zoom_z_grad;
+static const Uint32 *z_grad;
-static void setup_z_grad(void)
+static void init_z_grad(void)
{
int i;
int div;
uint8_t col;
- if (z_grad)
- return;
- z_grad = calloc(3*(z_max-z_min)+1, sizeof(Uint32));
+ default_z_grad = calloc(3*(z_max-z_min)+1, sizeof(Uint32));
div = 3*(z_max-z_min);
for (i = 0; i <= 3*(z_max-z_min); i++) {
col = i*DEPTH_RANGE/div + DEPTH_OFFSET;
- z_grad[i] = col * 0x1010100 + 0xff;
+ default_z_grad[i] = col * 0x1010100 + 0xff;
+ }
+ z_grad = default_z_grad;
+}
+
+
+static void calc_z_grad(int center, unsigned c_zoom)
+{
+ unsigned i;
+ int col;
+ uint8_t mid = DEPTH_RANGE >> 1;
+
+ if (!zoom_z_grad)
+ zoom_z_grad = calloc(3*(z_max-z_min)+1, sizeof(Uint32));
+ for (i = 0; i <= 3*(z_max-z_min); i++) {
+ col = ((int) i-center*3)/(1 << c_zoom)+mid;
+ if (col < 0 || col >= DEPTH_RANGE)
+ zoom_z_grad[i] = CONTRAST_RGBA;
+ else
+ zoom_z_grad[i] = (col+DEPTH_OFFSET) * 0x1010100 + 0xff;
}
+ z_grad = zoom_z_grad;
+}
+
+
+static void reset_z_grad(void)
+{
+ z_grad = default_z_grad;
+}
+
+
+/* ----- Contrast adjustment ----------------------------------------------- */
+
+
+static bool contrast_mode = 0;
+static int contrast_center;
+static unsigned contrast_zoom = 1;
+
+
+static void contrast_change(bool lower)
+{
+ if (cursor)
+ contrast_center = cursor->z - z_min;
+ if (lower) {
+ /* limit zoom to 1/12 of the Z range */
+ if (1 << contrast_zoom > (z_max-z_min)/4)
+ return;
+ contrast_zoom++;
+ } else {
+ if (contrast_zoom == 1)
+ return;
+ contrast_zoom--;
+ }
+ calc_z_grad(contrast_center, contrast_zoom);
+}
+
+
+static void begin_contrast(void)
+{
+ contrast_mode = 1;
+ if (cursor)
+ contrast_center = cursor->z - z_min;
+ contrast_zoom = 1;
+ while (DEPTH_RANGE << contrast_zoom < 3*(z_max-z_min))
+ contrast_zoom++;
+ calc_z_grad(contrast_center, contrast_zoom);
+}
+
+
+static void end_contrast(void)
+{
+ contrast_mode = 0;
+ reset_z_grad();
}
@@ -179,7 +250,6 @@ static void surface_draw(SDL_Surface *s)
int a, b, c;
int z_off = z_min*3;
- setup_z_grad();
for (f = facets; f; f = f->next) {
a = coord(f->v[0]->x, f->v[0]->y, &xa, &ya);
if (a < 0)
@@ -682,14 +752,22 @@ static void button_event(SDL_MouseButtonEvent *button)
x_orig = x;
y_orig = y;
break;
- case 4:
+ case 4: /* wheel forward */
+ if (contrast_mode) {
+ contrast_change(0);
+ break;
+ }
if (zoom == 1)
break;
zoom--;
x_orig = (x_orig+x)/2;
y_orig = (y_orig+y)/2;
break;
- case 5:
+ case 5: /* wheel backward */
+ if (contrast_mode) {
+ contrast_change(1);
+ break;
+ }
if (1 << (zoom+1) > x_max-x_min && 1 << (zoom+1) > y_max-y_min)
return;
zoom++;
@@ -892,6 +970,9 @@ static bool event_loop(SDL_Surface **surf)
return 0;
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
+ case SDLK_c:
+ begin_contrast();
+ return 0;
case SDLK_g:
show_grid = !show_grid;
return 0;
@@ -912,6 +993,15 @@ static bool event_loop(SDL_Surface **surf)
return 0;
}
break;
+ case SDL_KEYUP:
+ switch (event.key.keysym.sym) {
+ case SDLK_c:
+ end_contrast();
+ return 0;
+ default:
+ break;
+ }
+ break;
case SDL_QUIT:
return 1;
}
@@ -942,6 +1032,7 @@ void gui(void)
SDL_EnableUNICODE(1);
extrema();
+ init_z_grad();
auto_scale();
while (1) {