summaryrefslogtreecommitdiff
path: root/engine.c
diff options
context:
space:
mode:
authorerdgeist <erdgeist@bauklotz.fritz.box>2017-04-08 14:21:36 +0200
committererdgeist <erdgeist@bauklotz.fritz.box>2017-04-08 14:21:36 +0200
commitf2683a4b707cd714b7f540ebf6482563df83d51e (patch)
treede4941add99f0eb1642aa57c6af180b4ee70119a /engine.c
parent78d309a97b782bd6ab2716fa7595bb3f409479e3 (diff)
Near complete rewrite.
Diffstat (limited to 'engine.c')
-rw-r--r--engine.c172
1 files changed, 104 insertions, 68 deletions
diff --git a/engine.c b/engine.c
index 0d92b50..43892fb 100644
--- a/engine.c
+++ b/engine.c
@@ -2,6 +2,7 @@
2#include <stdlib.h> 2#include <stdlib.h>
3 3
4#include "config.h" 4#include "config.h"
5#include "geometry.h"
5#include "engine.h" 6#include "engine.h"
6#include "main.h" 7#include "main.h"
7#include "midi.h" 8#include "midi.h"
@@ -13,91 +14,131 @@ static int g_selected_string = -1;
13 14
14static LPoint g_render_points[1024]; 15static LPoint g_render_points[1024];
15static int g_render_point_count; 16static int g_render_point_count;
16static const int g_harfe_width = 1024; 17static ConfigSelect g_selected_config;
17static const int g_harfe_height = 768; 18static void highlight_line(int value, int y, int max_x, uint32_t color);
18static int g_factor = 1<<16;
19 19
20static inline int scale(int coord) { 20#define scale(X) display_scale_harfe_to_screen(X)
21 return (int)(((((int64_t)coord) << 32) / g_factor ) >> 16);
22}
23 21
24void 22void
25engine_redraw() 23engine_redraw()
26{ 24{
27 int i; 25 char text[32];
26 char *config_hints[] = { "No", "Harfe", "File", "Edit" };
27 int i, MAX_X, MAX_Y, FONT_HEIGHT;
28 int height = g_max_y - g_min_y;
28 29
29 display_redraw(); 30 display_redraw();
30 display_clear(); 31 display_clear();
31 display_text(g_harfe_connected ? "online" : "offline", 4, 4, 0xffffffff); 32 display_getdimensions(&MAX_X, &MAX_Y, &FONT_HEIGHT);
32 33
33 for (i = 0; i < g_string_count; ++i) { 34 snprintf( text, sizeof(text), g_harfe_connected ? "online (%s)" : "offline (%s)", config_hints[(int)g_config_source]);
34 LLine *l = &g_string_conf[i].line; 35 display_text(text, 8, MAX_Y - 4, g_harfe_connected ? 0x00ff3fff : 0xff003fff );
35 uint32_t color = i == g_selected_string ? 0xff00ffff : 0x00ffffffff;
36 36
37 display_line_color(scale(l->x0), scale(l->y0), scale(l->x1), scale(l->y1), color); 37 if (height) {
38 display_circle(scale(l->x0), scale(l->y0), 4); 38 int b = g_midi_three_octave_split_inverse;
39 display_circle(scale(l->x1), scale(l->y1), 4); 39 int tos1 = g_midi_three_octave_split_1, tos2 = g_midi_three_octave_split_2;
40 display_text( b ? "+1" : "-1", 4, scale(g_min_y + tos1 * height / 200) + FONT_HEIGHT / 2, 0x007f7f7fff);
41 display_text( " 0", 4, scale(g_min_y + (tos1 + tos2) * height / 200) + FONT_HEIGHT / 2, 0x007f7f7fff);
42 display_text( b ? "-1" : "+1", 4, scale(g_min_y + (tos2 / 2 + 50 ) * height / 100) + FONT_HEIGHT / 2, 0x007f7f7fff);
40 43
41 if (g_string_conf[i].playing) 44 display_line_color(0, scale(g_min_y), MAX_X, scale(g_min_y), 0xff00ffff);
42 display_text(config_midi_note_to_string(g_string_conf[i].note+12*g_string_conf[i].octave), scale(l->x1) - 20, g_height - 40, color ); 45 display_line_color(0, scale(g_max_y), MAX_X, scale(g_max_y), 0xff00ffff);
43 else 46
44 display_text(config_midi_note_to_string(g_string_conf[i].note), scale(l->x1) - 20, g_height - 40, color ); 47 display_line_color(0, scale(g_min_y + g_midi_two_octave_split * height / 100), MAX_X, scale(g_min_y + g_midi_two_octave_split * height / 100), 0xffff00ff);
48
49 display_line_color(0, scale(g_min_y + tos1 * height / 100), MAX_X, scale(g_min_y + tos1 * height / 100), 0x00ff00ff);
50 display_line_color(0, scale(g_min_y + tos2 * height / 100), MAX_X, scale(g_min_y + tos2 * height / 100), 0x00ff00ff);
51
52
53 switch (g_selected_config) {
54 case sel_min_y: highlight_line(g_min_y, g_min_y, MAX_X, 0xff00ffff); break;
55 case sel_max_y: highlight_line(g_max_y, g_max_y, MAX_X, 0xff00ffff); break;
56 case sel_2_oct: highlight_line(g_midi_two_octave_split, g_min_y + g_midi_two_octave_split * height / 100, MAX_X, 0xffff00ff); break;
57 case sel_3_oct_top: highlight_line(tos2, g_min_y + tos2 * height / 100, MAX_X, 0x00ff00ff); break;
58 case sel_3_oct_bottom: highlight_line(tos1, g_min_y + tos1 * height / 100, MAX_X, 0x00ff00ff); break;
59 case sel_none: break;
60 }
61
62 for (i = 0; i < g_string_count; ++i) {
63 LLine *l = &g_string_conf[i].line;
64 uint32_t color = ( ( i == g_selected_string ) ? 0xff00ffff : 0x00ffffffff );
65 uint32_t text_color = ( ( i == g_selected_string ) ? 0xff00ffff : 0x007f7f7fff );
66
67 int center_y = g_min_y+height/2;
68 int x2 = l->p1.x;
69
70 if (l->p1.x!=l->p0.x) {
71 double m = (double)(l->p1.y-l->p0.y) / (double)(l->p1.x-l->p0.x);
72 double _x2 = ((double)center_y) - (double)l->p0.y + m * (double)l->p0.x;
73 x2 = (int)(_x2/m);
74 }
75
76 if (g_string_conf[i].playing)
77 display_text(config_midi_note_to_string(g_string_conf[i].note+12*g_string_conf[i].octave), scale(x2-20), scale(center_y) + FONT_HEIGHT, text_color );
78 else
79 display_text(config_midi_note_to_string(g_string_conf[i].note), scale(x2-20), scale(center_y) + FONT_HEIGHT, text_color );
80
81 display_line_color(scale(l->p0.x), scale(l->p0.y), scale(l->p1.x), scale(l->p1.y), color);
82 display_circle(scale(l->p0.x), scale(l->p0.y), 4);
83 display_circle(scale(l->p1.x), scale(l->p1.y), 4);
84
85 }
45 } 86 }
46 g_selected_string = -1; 87 g_selected_string = -1;
47 88
48 for (i = 0; i < g_render_point_count; ++i) 89 for (i = 0; i < g_render_point_count; ++i)
49 display_circle_color(scale(g_render_points[i].x), scale(g_render_points[i].y), 4, 0xff0000ff); 90 display_circle_color(scale(g_render_points[i].x), scale(g_render_points[i].y), 4, 0xff0000ff);
50 g_render_point_count = 0; 91 g_render_point_count = 0;
92}
51 93
52 display_line_color(0, scale(g_min_y), g_width, scale(g_min_y), 0xff00ffff); 94static void
53 display_line_color(0, scale(g_max_y), g_width, scale(g_max_y), 0xff00ffff); 95highlight_line(int value, int y, int max_x, uint32_t color) {
54 96 char text[32];
55 if (g_min_y != g_max_y) { 97 display_line_color(0, scale(y-10), 10, scale(y), color);
56 int height = scale(g_max_y - g_min_y); 98 display_line_color(0, scale(y+10), 10, scale(y), color);
57 99 display_line_color(max_x, scale(y-10), max_x-10, scale(y), color);
58 display_line_color(0, scale(g_max_y) - g_midi_two_octave_split * height / 256, g_width, scale(g_max_y) - g_midi_two_octave_split * height / 256, 0xffff00ff); 100 display_line_color(max_x, scale(y+10), max_x-10, scale(y), color);
59 101
60 display_line_color(0, scale(g_max_y) - g_midi_three_octave_split_1 * height / 256, g_width, scale(g_max_y) - g_midi_three_octave_split_1 * height / 256, 0x00ff00ff); 102 display_rect_color(max_x/2-40, scale(y+20), 80, 40, 0xffffffff);
61 display_line_color(0, scale(g_max_y) - g_midi_three_octave_split_2 * height / 256, g_width, scale(g_max_y) - g_midi_three_octave_split_2 * height / 256, 0x00ff00ff); 103 display_text(text, max_x/2-20, scale(y+20), 0);
62 }
63} 104}
64 105
65#endif
66
67void 106void
68engine_init() { 107engine_select_config(ConfigSelect sel) {
69#ifndef NO_DISPLAY 108 g_selected_config = sel;
70 g_factor = (g_harfe_width << 16) / g_width;
71 if ((g_harfe_height << 16) / g_height < g_factor)
72 g_factor = (g_harfe_height << 16) / g_height;
73#endif
74} 109}
75 110
76static int 111ConfigSelect
77dist_pp(int x0, int y0, int x1, int y1) 112engine_change_selected(int off)
78{ 113{
79 return (y0 - y1) * (y0 - y1) + (x0 - x1) * (x0 - x1); 114 switch(g_selected_config) {
115 case sel_3_oct_top:
116 g_midi_three_octave_split_2 += off;
117 if (g_midi_three_octave_split_2<0) g_midi_three_octave_split_2 = 0;
118 if (g_midi_three_octave_split_2>100) g_midi_three_octave_split_2 = 100;
119 break;
120 case sel_3_oct_bottom:
121 g_midi_three_octave_split_1 += off;
122 if (g_midi_three_octave_split_1<0) g_midi_three_octave_split_1 = 0;
123 if (g_midi_three_octave_split_1>100) g_midi_three_octave_split_1 = 100;
124 break;
125 case sel_2_oct:
126 g_midi_two_octave_split += off;
127 if (g_midi_two_octave_split<0) g_midi_two_octave_split = 0;
128 if (g_midi_two_octave_split>100) g_midi_two_octave_split = 100;
129 break;
130 default:
131 break;
132 }
133 return g_selected_config;
80} 134}
81 135
82// dist is a fixed point with precission of 8 bits 136#endif
83// offs is where on the line segment xy0-xy1 the point's normale hits,
84// range 0..65536 (but can extend, if normale hits line outside line segment)
85static int
86dist_lp(int x0, int y0, int x1, int y1, int xp, int yp, int *offs)
87{
88 int64_t r = (y1 - y0) * (y1 - y0) + (x1 - x0) * (x1 - x0);
89 int64_t q1 = (xp - x0) * (y1 - y0) - (yp - y0) * (x1 - x0);
90 int64_t q2 = (x1 - x0) * (xp - x0) + (y1 - y0) * (yp - y0);
91 137
92 *offs = (int)((q2 << 16) / r); 138void
93 return (int)( q1 * q1 * ((y0 - y1) * (y0 - y1) + (x1 - x0) * (x1 - x0)) * 256 / (r * r)); 139engine_init() {
94} 140}
95 141
96static int
97dist_pl(LPoint * p, LLine * l, int *offs)
98{
99 return dist_lp(l->x0, l->y0, l->x1, l->y1, p->x, p->y, offs);
100}
101 142
102void 143void
103engine_handle_point(LPoint * p, uint32_t monotime) 144engine_handle_point(LPoint * p, uint32_t monotime)
@@ -108,9 +149,6 @@ engine_handle_point(LPoint * p, uint32_t monotime)
108 int y_viewfield, pitch_factor = 12; 149 int y_viewfield, pitch_factor = 12;
109 int dv, dt, speed, new_pitch; 150 int dv, dt, speed, new_pitch;
110 151
111 // XXX should not be inverted here
112 p->x = 1024 - p->x;
113
114#ifndef NO_DISPLAY 152#ifndef NO_DISPLAY
115 /* Pass to "render thread" */ 153 /* Pass to "render thread" */
116 g_render_points[g_render_point_count] = *p; 154 g_render_points[g_render_point_count] = *p;
@@ -120,27 +158,25 @@ engine_handle_point(LPoint * p, uint32_t monotime)
120 /* See which line is closest */ 158 /* See which line is closest */
121 for (i = 0; i < g_string_count; ++i) { 159 for (i = 0; i < g_string_count; ++i) {
122 int dist = dist_pl(p, &g_string_conf[i].line, &offs); 160 int dist = dist_pl(p, &g_string_conf[i].line, &offs);
123 if ((dist < 256 * 10 * 10 ) && (dist < dist_max)) { 161
162 /* Avoid miss-fires, check if offset is in range -5% - +105% */
163 if ((dist < 512 * 10 * 10 ) && (dist < dist_max) && (offs<68812) && (offs>-3276)) {
124 dist_max = dist; 164 dist_max = dist;
125 saite = i; 165 saite = i;
126 } 166 }
127 } 167 }
128 168
129 /* Avoid miss-fires, check if offset is in range -5% - +105% */
130 if (offs>68812 || offs<-3276)
131 return;
132
133 if (saite == -1) 169 if (saite == -1)
134 return; 170 return;
135 171
136 s = g_string_conf + saite; 172 s = g_string_conf + saite;
137 g_selected_string = saite; 173 g_selected_string = saite;
138 174
139 y_viewfield = 256 * (g_max_y - p->y) / (g_max_y - g_min_y); 175 y_viewfield = (100 * (p->y - g_min_y)) / (g_max_y - g_min_y);
140 if (y_viewfield < 0) 176 if (y_viewfield < 0)
141 y_viewfield = 0; 177 y_viewfield = 0;
142 if (y_viewfield >= 256) 178 if (y_viewfield >= 100)
143 y_viewfield = 255; 179 y_viewfield = 100;
144 180
145 // Determine octave, if configured 181 // Determine octave, if configured
146 switch (s->mode) { 182 switch (s->mode) {
@@ -183,7 +219,7 @@ engine_handle_point(LPoint * p, uint32_t monotime)
183 dv = abs(s->start_off - offs); 219 dv = abs(s->start_off - offs);
184 dt = monotime - s->first_time_seen; 220 dt = monotime - s->first_time_seen;
185 if (!dt) ++dt; 221 if (!dt) ++dt;
186 speed = 1000 * dv / dt; // in offs_prec per second 222 speed = 1000 * dv / dt; // in offs_prec per second
187 } 223 }
188 s->last_off = offs; 224 s->last_off = offs;
189 break; 225 break;
@@ -193,7 +229,7 @@ engine_handle_point(LPoint * p, uint32_t monotime)
193 if (s->modifier == pitch_bend_up) 229 if (s->modifier == pitch_bend_up)
194 new_pitch = (pitch_factor * (s->start_off - offs)) >> 16; 230 new_pitch = (pitch_factor * (s->start_off - offs)) >> 16;
195 else if (s->modifier == pitch_bend_down) 231 else if (s->modifier == pitch_bend_down)
196 new_pitch = (pitch_factor * (s->start_off - offs)) >> 16; 232 new_pitch = (pitch_factor * (offs - s->start_off)) >> 16;
197 else 233 else
198 break; 234 break;
199 // avoid reporting same pitch bend over and over 235 // avoid reporting same pitch bend over and over