electronic_level.c
#include "dryos.h"
#include "bmp.h"
#include "tasks.h"
#include "debug.h"
#include "menu.h"
#include "property.h"
#include "config.h"
#include "gui.h"
#include "lens.h"
#include "version.h"
#include "edmac.h"
#include "asm.h"
#include "lvinfo.h"
#ifdef CONFIG_ELECTRONIC_LEVEL
/* Canon stub */
extern void GUI_SetRollingPitchingLevelStatus(int request);
struct rolling_pitching
{
uint8_t status;
uint8_t cameraposture;
uint8_t roll_sensor1;
uint8_t roll_sensor2;
uint8_t pitch_sensor1;
uint8_t pitch_sensor2;
};
static struct rolling_pitching level_data;
PROP_HANDLER(PROP_ROLLING_PITCHING_LEVEL)
{
memcpy(&level_data, buf, 6);
}
static void draw_electronic_level(int angle, int prev_angle, int force_redraw)
{
if (!force_redraw && angle == prev_angle) return;
int x0 = os.x0 + os.x_ex/2;
int y0 = os.y0 + os.y_ex/2;
int r = 200;
int prev_dx = (prev_angle % 1800 >= 450 && prev_angle % 1800 < 1350);
int prev_dy = 1 - prev_dx;
int dx = (angle % 1800 >= 450 && angle % 1800 < 1350);
int dy = 1 - dx;
draw_angled_line(x0, y0, r, prev_angle, 0);
draw_angled_line(x0 + prev_dx, y0 + prev_dy, r, prev_angle, 0);
draw_angled_line(x0, y0, r, angle, (angle % 900) ? COLOR_BLACK : COLOR_GREEN1);
draw_angled_line(x0 + dx, y0 + dy, r, angle, (angle % 900) ? COLOR_WHITE : COLOR_GREEN2);
}
void disable_electronic_level()
{
if (level_data.status == 2)
{
GUI_SetRollingPitchingLevelStatus(1);
msleep(100);
}
}
void show_electronic_level()
{
static int prev_angle10 = 0;
int force_redraw = 0;
if (level_data.status != 2)
{
GUI_SetRollingPitchingLevelStatus(0);
msleep(100);
force_redraw = 1;
}
static int k = 0;
k++;
if (k % 10 == 0) force_redraw = 1;
int angle100 = level_data.roll_sensor1 * 256 + level_data.roll_sensor2;
int angle10 = angle100/10;
draw_electronic_level(angle10, prev_angle10, force_redraw);
draw_electronic_level(angle10 + 1800, prev_angle10 + 1800, force_redraw);
prev_angle10 = angle10;
}
#define FMT_FIXEDPOINT1E(x) (x) < 0 ? "-" : (x) > 0 ? "+" : "=", ABS(x)/10, ABS(x)%10
static LVINFO_UPDATE_FUNC(electronic_level_update)
{
LVINFO_BUFFER(8);
if(level_data.status == 2)
{
int angle10 = (level_data.roll_sensor1 * 256 + level_data.roll_sensor2) / 10;
if (angle10 > 1800) angle10 -= 3600;
snprintf(buffer, sizeof(buffer), "%s%d.%d" SYM_DEGREE, FMT_FIXEDPOINT1E(angle10));
item->color_fg = angle10 == 0 || ABS(angle10) == 900 || ABS(angle10) == 1800 ? COLOR_GREEN1 : COLOR_WHITE;
}
}
static struct lvinfo_item info_items[] = {
{
.name = "Electronic level",
.which_bar = LV_TOP_BAR_ONLY,
.update = electronic_level_update,
.preferred_position = -100,
.priority = 1,
},
};
static void electronic_level_init()
{
lvinfo_add_items(info_items, COUNT(info_items));
}
INIT_FUNC("electronic_level_info", electronic_level_init);
#endif