1. Trammell Hudson
  2. Magic Lantern

Commits

g3gg0  committed 82886ad

7D: add flexible info screen routines to easily configure info screen and even load configs dynamically
7D: switch back to no-PIC code as (char *) arrays seem to cause trouble (to be analyzed)
all: add stubs needed for flexible info screen (not enabled yet)

  • Participants
  • Parent commits 04cefe3
  • Branches unified

Comments (0)

Files changed (10)

File platform/5D2.212/misc.c

View file
 {
 	return battery_level;
 }
+int GetBatteryPerformance()
+{
+    return 0;
+}
+int GetBatteryHist()
+{
+    return 0;
+}
 int GetBatteryTimeRemaining()
 {
 	return battery_seconds_same_level_ok * battery_level;

File platform/5D3.113/misc.c

View file
 {
     return bat_info.level;
 }
+int GetBatteryPerformance()
+{
+    return bat_info.performance;
+}
+int GetBatteryHist()
+{
+    return bat_info.act_hist;
+}
 int GetBatteryTimeRemaining()
 {
 	return battery_seconds_same_level_ok * bat_info.level;

File platform/60D.111/misc.c

View file
 {
 	return battery_level;
 }
+int GetBatteryPerformance()
+{
+    return 0;
+}
+int GetBatteryHist()
+{
+    return 0;
+}
 int GetBatteryTimeRemaining()
 {
 	return battery_seconds_same_level_ok * battery_level;

File platform/6D.112/misc.c

View file
 {
     return bat_info.level;
 }
+int GetBatteryPerformance()
+{
+    return bat_info.performance;
+}
+int GetBatteryHist()
+{
+    return bat_info.act_hist;
+}
 int GetBatteryTimeRemaining()
 {
     return battery_seconds_same_level_ok * bat_info.level;

File platform/7D.203/Makefile

View file
 ML_VERSION=unified1 
 
 # compile position independent (experimental)
-CONFIG_PIC=y
+CONFIG_PIC=n
 
 #used in CFLAGS
 PLATFORM_INC=.
 	boot-hack.o \
 	stubs.o \
 	version.o \
+	flexinfo.o \
 	ml_rpc.o \
 	bmp.o \
 	font-dyn.o \

File platform/7D.203/consts.h

View file
 
 // for the yellow ISO range [a-b]
 #define ISO_RANGE_POS_X 455
-#define ISO_RANGE_POS_Y 92
+#define ISO_RANGE_POS_Y 90
 
 #define WB_KELVIN_POS_X 393
 #define WB_KELVIN_POS_Y 276

File platform/7D.203/misc.c

View file
 {
     return bat_info.level;
 }
+int GetBatteryPerformance()
+{
+    return bat_info.performance;
+}
+int GetBatteryHist()
+{
+    return bat_info.act_hist;
+}
 int GetBatteryTimeRemaining()
 {
     return battery_seconds_same_level_ok * bat_info.level;

File src/flexinfo.c

View file
+
+#include <dryos.h>
+#include <property.h>
+#include <menu.h>
+#include <bmp.h>
+#include <config.h>
+#include <consts.h>
+#include <lens.h>
+#include <version.h>
+#include <flexinfo.h>
+
+#define BUF_SIZE 128
+
+/* 
+   this is the definition of the info screen elements.
+   it can either be made switchable for photo and LV setting or put in an array.
+   the config can get loaded from an user-save and -editable ini file.
+   -> ToDo: for now there is only 7D photo screen, add others too
+            do we put raw X/Y positions here or keep them im consts.h?
+ */
+info_elem_t info_config[64] =
+{
+    { .config = { { INFO_TYPE_CONFIG } } },
+
+#if defined(CONFIG_7D)
+    /* print ISO range */
+    { .string = { { INFO_TYPE_STRING, { ISO_RANGE_POS_X, ISO_RANGE_POS_Y, 2 }}, INFO_STRING_ISO_MINMAX, COLOR_YELLOW, INFO_COL_FIELD, INFO_FONT_MEDIUM } },
+    
+    /* entry 2, referenced as anchor */
+    { .string = { { INFO_TYPE_STRING, { WBS_POS_X, WBS_POS_Y, 2 }}, INFO_STRING_WBS_BA, COLOR_YELLOW, INFO_COL_FIELD, INFO_FONT_LARGE } },
+    { .string = { { INFO_TYPE_STRING, { 0, 0, 2, INFO_ANCHOR_RIGHT | INFO_ANCHOR_TOP, 2 }}, INFO_STRING_WBS_GM, COLOR_YELLOW, INFO_COL_FIELD, INFO_FONT_LARGE } },
+    
+    /* entry 4, referenced as anchor */
+    { .battery_icon = { { INFO_TYPE_BATTERY_ICON, { DISPLAY_BATTERY_POS_X, DISPLAY_BATTERY_POS_Y, 2 }}, DISPLAY_BATTERY_LEVEL_2, DISPLAY_BATTERY_LEVEL_1 } },
+    { .battery_perf = { { INFO_TYPE_BATTERY_PERF, { -14, 0, 3, INFO_ANCHOR_LEFT | INFO_ANCHOR_TOP, 4 }}, 0, 12, 12 } },
+    { .string = { { INFO_TYPE_STRING, { 0, 2, 2, INFO_ANCHOR_HCENTER | INFO_ANCHOR_BOTTOM, 4, INFO_ANCHOR_HCENTER | INFO_ANCHOR_TOP }}, INFO_STRING_BATTERY_PCT, COLOR_YELLOW, INFO_COL_FIELD, INFO_FONT_LARGE } },
+    { .string = { { INFO_TYPE_STRING, { 0, 0, 2, INFO_ANCHOR_RIGHT | INFO_ANCHOR_TOP, 4 }}, INFO_STRING_BATTERY_ID, COLOR_YELLOW, INFO_COL_FIELD, INFO_FONT_LARGE } },
+#endif
+
+    { .type = INFO_TYPE_END },
+};
+
+uint32_t info_get_string(char *buffer, uint32_t maxsize, uint32_t string_type)
+{
+    strcpy(buffer, "");
+
+    switch(string_type)
+    {
+        case INFO_STRING_ISO:
+        {
+            snprintf(buffer, maxsize, "(ISO)");
+            break;
+        }
+        case INFO_STRING_ISO_MIN:
+        {
+            if (lens_info.raw_iso != 0)
+            {
+                return 1;
+            }
+            snprintf(buffer, maxsize, "MIN:%d",raw2iso(auto_iso_range >> 8));
+            break;
+        }
+        case INFO_STRING_ISO_MAX:
+        {
+            if (lens_info.raw_iso != 0)
+            {
+                return 1;
+            }
+            snprintf(buffer, maxsize, "MAX:%d",raw2iso(auto_iso_range & 0xFF));
+            break;
+        }
+        case INFO_STRING_ISO_MINMAX:
+        {
+            if (lens_info.raw_iso != 0)
+            {
+                return 1;
+            }
+            snprintf(buffer, maxsize, "[%d-%d]", MAX((get_htp() ? 200 : 100), raw2iso(auto_iso_range >> 8)), raw2iso(auto_iso_range & 0xFF));
+            break;
+        }
+        case INFO_STRING_KELVIN:
+        {
+            if (lens_info.wb_mode != WB_KELVIN)
+            {
+                return 1;
+            }
+            snprintf(buffer, maxsize, "%5d", lens_info.kelvin);
+            break;
+        }
+        case INFO_STRING_WBS_BA:
+        {
+            int ba = lens_info.wbs_ba;
+            if (ba == 0)
+            {
+                return 1;
+            }
+            snprintf(buffer, maxsize, "%s%d", ba > 0 ? "A" : "B", ABS(ba));
+            break;
+        }
+        case INFO_STRING_WBS_GM:
+        {
+            int gm = lens_info.wbs_gm;
+            if (gm == 0)
+            {
+                return 1;
+            }
+            snprintf(buffer, maxsize, "%s%d", gm > 0 ? "G" : "M", ABS(gm));
+            break;
+        }
+        case INFO_STRING_DATE_DDMMYYYY:
+        {
+            struct tm now;
+            LoadCalendarFromRTC(&now);
+            snprintf(buffer, maxsize, "%2d.%2d.%4d", now.tm_mday,(now.tm_mon+1),(now.tm_year+1900));
+            break;
+        }
+        case INFO_STRING_DATE_YYYYMMDD:
+        {
+            struct tm now;
+            LoadCalendarFromRTC(&now);
+            snprintf(buffer, maxsize, "%2d.%2d.%4d", (now.tm_mon+1),now.tm_mday,(now.tm_year+1900));
+            break;
+        }
+        case INFO_STRING_DATE_MM:
+        {
+            struct tm now;
+            LoadCalendarFromRTC(&now);
+            snprintf(buffer, maxsize, "%2d", (now.tm_mon+1));
+            break;
+        }
+        case INFO_STRING_DATE_DD:
+        {
+            struct tm now;
+            LoadCalendarFromRTC(&now);
+            snprintf(buffer, maxsize, "%2d", now.tm_mday);
+            break;
+        }
+        case INFO_STRING_DATE_YY:
+        {
+            struct tm now;
+            LoadCalendarFromRTC(&now);
+            snprintf(buffer, maxsize, "%2d", now.tm_year % 100);
+            break;
+        }
+        case INFO_STRING_DATE_YYYY:
+        {
+            struct tm now;
+            LoadCalendarFromRTC(&now);
+            snprintf(buffer, maxsize, "%4d", (now.tm_year+1900));
+            break;
+        }
+        case INFO_STRING_TIME:
+        {
+            struct tm now;
+            LoadCalendarFromRTC(&now);
+            snprintf(buffer, maxsize, "%02d:%02d", now.tm_hour, now.tm_min);
+            break;
+        }
+        case INFO_STRING_TIME_HH12:
+        {
+            struct tm now;
+            LoadCalendarFromRTC(&now);
+            snprintf(buffer, maxsize, "%02d", now.tm_hour % 13);
+            break;
+        }
+        case INFO_STRING_TIME_HH24:
+        {
+            struct tm now;
+            LoadCalendarFromRTC(&now);
+            snprintf(buffer, maxsize, "%02d", now.tm_hour);
+            break;
+        }
+        case INFO_STRING_TIME_MM:
+        {
+            struct tm now;
+            LoadCalendarFromRTC(&now);
+            snprintf(buffer, maxsize, "%02d", now.tm_min);
+            break;
+        }
+        case INFO_STRING_TIME_SS:
+        {
+            struct tm now;
+            LoadCalendarFromRTC(&now);
+            snprintf(buffer, maxsize, "%02d", now.tm_sec);
+            break;
+        }
+        case INFO_STRING_TIME_AMPM:
+        {
+            struct tm now;
+            LoadCalendarFromRTC(&now);
+            snprintf(buffer, maxsize, "%s", (now.tm_hour > 12) ? "PM" : "AM");
+            break;
+        }
+        case INFO_STRING_ARTIST:
+        {
+            snprintf(buffer, maxsize, "%s", artist_name);
+            break;
+        }
+        case INFO_STRING_COPYRIGHT:
+        {
+            snprintf(buffer, maxsize, "%s", copyright_info);
+            break;
+        }
+        case INFO_STRING_LENS:
+        {
+            snprintf(buffer, maxsize, "%s", lens_info.name);
+            break;
+        }
+        case INFO_STRING_BUILD:
+        {
+            snprintf(buffer, maxsize, "%s", build_version);
+            break;
+        }
+        case INFO_STRING_BATTERY_PCT:
+        {
+            snprintf(buffer, maxsize, "%d%%%%", GetBatteryLevel());
+            break;
+        }
+        case INFO_STRING_BATTERY_ID:
+        {
+            if (GetBatteryHist() == 0)
+            {
+                return 1;
+            }
+            snprintf(buffer, maxsize, "%d", GetBatteryHist());
+            break;
+        }
+        case INFO_STRING_CARD_LABEL_A:
+        case INFO_STRING_CARD_LABEL_B:
+        case INFO_STRING_CARD_SPACE_A:
+        case INFO_STRING_CARD_SPACE_B:
+        case INFO_STRING_CARD_FILES_A:
+        case INFO_STRING_CARD_FILES_B:
+        case INFO_STRING_CARD_MAKER_A:
+        case INFO_STRING_CARD_MAKER_B:
+        case INFO_STRING_CARD_MODEL_A:
+        case INFO_STRING_CARD_MODEL_B:
+            snprintf(buffer, maxsize, "(card info)");
+            break;
+        /* error */
+        default:
+            return 1;
+    }
+
+    return 0;
+}
+
+uint32_t info_measure_string(char *string, uint32_t font_type, int32_t *width, int32_t *height)
+{
+    switch(font_type)
+    {
+        case INFO_FONT_SMALL:
+        case INFO_FONT_MEDIUM:
+        case INFO_FONT_LARGE:
+            *width = fontspec_font(WBS_FONT)->width * strlen(string);
+            *height = fontspec_font(WBS_FONT)->height;
+            break;
+        case INFO_FONT_CANON:
+            *width = bfnt_puts(string, 1000, 1000, COLOR_CYAN, 0);
+            *height = 0;
+            break;
+        /* error */
+        default:
+            return 1;
+    }
+
+    return 0;
+}
+
+uint32_t info_get_absolute(info_elem_t *config, info_elem_t *element)
+{
+    /* in case of absolute positioning, this is the absolute pos else it is the offset from the anchor */
+    element->hdr.pos.abs_x = element->hdr.pos.x;
+    element->hdr.pos.abs_y = element->hdr.pos.y;
+
+    /* if the element is relatively positioned to some other element, we have to look it up */
+
+    /* determine position from referenced element identified by 'anchor' and update pos_x, pos_y (they contain the offset) */
+    info_elem_t *anchor = &(config[element->hdr.pos.anchor]);
+
+    switch(element->hdr.pos.anchor_flags & INFO_ANCHOR_H_MASK)
+    {
+        case INFO_ANCHOR_LEFT:
+            element->hdr.pos.abs_x += anchor->hdr.pos.x;
+            break;
+        case INFO_ANCHOR_HCENTER:
+            element->hdr.pos.abs_x += anchor->hdr.pos.x + anchor->hdr.pos.w / 2;
+            break;
+        case INFO_ANCHOR_RIGHT:
+            element->hdr.pos.abs_x += anchor->hdr.pos.x + anchor->hdr.pos.w;
+            break;
+    }
+
+    switch(element->hdr.pos.anchor_flags & INFO_ANCHOR_V_MASK)
+    {
+        case INFO_ANCHOR_TOP:
+            element->hdr.pos.abs_y += anchor->hdr.pos.y;
+            break;
+        case INFO_ANCHOR_VCENTER:
+            element->hdr.pos.abs_y += anchor->hdr.pos.y + anchor->hdr.pos.h / 2;
+            break;
+        case INFO_ANCHOR_BOTTOM:
+            element->hdr.pos.abs_y += anchor->hdr.pos.y + anchor->hdr.pos.h;
+            break;
+    }
+
+    switch(element->hdr.pos.anchor_flags_self & INFO_ANCHOR_H_MASK)
+    {
+        case INFO_ANCHOR_LEFT:
+            element->hdr.pos.abs_x += 0;
+            break;
+        case INFO_ANCHOR_HCENTER:
+            element->hdr.pos.abs_x += -element->hdr.pos.w / 2;
+            break;
+        case INFO_ANCHOR_RIGHT:
+            element->hdr.pos.abs_x += -element->hdr.pos.w;
+            break;
+    }
+
+    switch(element->hdr.pos.anchor_flags_self & INFO_ANCHOR_V_MASK)
+    {
+        case INFO_ANCHOR_TOP:
+            element->hdr.pos.abs_y += 0;
+            break;
+        case INFO_ANCHOR_VCENTER:
+            element->hdr.pos.abs_y += -element->hdr.pos.h / 2;
+            break;
+        case INFO_ANCHOR_BOTTOM:
+            element->hdr.pos.abs_y += -element->hdr.pos.h;
+            break;
+    }
+    
+    return 0;
+}
+
+    
+uint32_t info_print_string(info_elem_t *config, info_elem_string_t *element, uint32_t run_type)
+{
+    char str[BUF_SIZE];
+
+    if(info_get_string(str, BUF_SIZE, element->string_type))
+    {
+        element->hdr.pos.shown = 0;
+        return 1;
+    }
+    
+    /* get absolute position of this element */
+    info_get_absolute(config, (info_elem_t *)element);
+    int pos_x = element->hdr.pos.abs_x;
+    int pos_y = element->hdr.pos.abs_y;
+
+    /* update the width/height */
+    info_measure_string(str, element->font_type, &element->hdr.pos.w, &element->hdr.pos.h);
+
+    /* ToDo: make defineable */
+    int col_bg = bmp_getpixel(10,1);
+    int col_field = bmp_getpixel(615,375);
+    uint32_t fgcolor = element->fgcolor;
+    uint32_t bgcolor = element->bgcolor;
+    uint32_t fnt;
+
+    /* look up special colors. ToDo: optimize */
+    if(bgcolor == INFO_COL_BG)
+    {
+        bgcolor = col_bg;
+    }
+    if(bgcolor == INFO_COL_FIELD)
+    {
+        bgcolor = col_field;
+    }
+    if(fgcolor == INFO_COL_BG)
+    {
+        fgcolor = col_bg;
+    }
+    if(fgcolor == INFO_COL_FIELD)
+    {
+        fgcolor = col_field;
+    }
+
+    /* print string if this was not just a pre-pass run */
+    if(run_type == INFO_PRINT)
+    {
+        switch(element->font_type)
+        {
+            case INFO_FONT_SMALL:
+                fnt = FONT(FONT_SMALL, fgcolor, bgcolor);
+                bmp_printf(fnt, pos_x, pos_y, str);
+                break;
+            case INFO_FONT_MEDIUM:
+                fnt = FONT(FONT_MED, fgcolor, bgcolor);
+                bmp_printf(fnt, pos_x, pos_y, str);
+                break;
+            case INFO_FONT_LARGE:
+                fnt = FONT(FONT_LARGE, fgcolor, bgcolor);
+                bmp_printf(fnt, pos_x, pos_y, str);
+                break;
+            case INFO_FONT_CANON:
+                bfnt_puts(str, pos_x, pos_y, fgcolor, bgcolor);
+                break;
+            /* error */
+            default:
+                return 1;
+        }
+    }
+
+    return 0;
+}
+
+uint32_t info_print_fill(info_elem_t *config, info_elem_fill_t *element, uint32_t run_type)
+{
+    bmp_fill(element->color, element->hdr.pos.x, element->hdr.pos.y, element->hdr.pos.w, element->hdr.pos.h);
+    return 0;
+}
+
+uint32_t info_print_icon(info_elem_t *config, info_elem_icon_t *element, uint32_t run_type)
+{
+    return 0;
+}
+
+uint32_t info_print_battery_perf(info_elem_t *config, info_elem_battery_perf_t *element, uint32_t run_type)
+{
+    /* get absolute position of this element */
+    info_get_absolute(config, (info_elem_t *)element);
+
+    int pos_x = element->hdr.pos.abs_x;
+    int pos_y = element->hdr.pos.abs_y;
+    int width = element->width;
+    int height = element->height;    
+
+    if(element->horizontal)
+    {
+        element->hdr.pos.w = 3 * width + 8;
+        element->hdr.pos.h = height;
+    }
+    else
+    {
+        element->hdr.pos.w = width;
+        element->hdr.pos.h = 3 * height + 8;
+    }
+    
+    if(run_type == INFO_PRINT)
+    {
+        if(element->horizontal)
+        {
+            bmp_fill((GetBatteryPerformance()<1 ? COLOR_GRAY50 : COLOR_GREEN2),pos_x,pos_y,width,height);
+            bmp_fill((GetBatteryPerformance()<2 ? COLOR_GRAY50 : COLOR_GREEN2),pos_x+4+width,pos_y,width,height);
+            bmp_fill((GetBatteryPerformance()<3 ? COLOR_GRAY50 : COLOR_GREEN2),pos_x+8+2*width,pos_y,width,height);
+        }
+        else
+        {
+            bmp_fill((GetBatteryPerformance()<1 ? COLOR_GRAY50 : COLOR_GREEN2),pos_x,pos_y,width,height);
+            bmp_fill((GetBatteryPerformance()<2 ? COLOR_GRAY50 : COLOR_GREEN2),pos_x,pos_y+4+height,width,height);
+            bmp_fill((GetBatteryPerformance()<3 ? COLOR_GRAY50 : COLOR_GREEN2),pos_x,pos_y+8+2*height,width,height);
+        }
+    }
+    return 0;
+}
+
+uint32_t info_print_battery_icon(info_elem_t *config, info_elem_battery_icon_t *element, uint32_t run_type)
+{
+    int batlev = GetBatteryLevel();
+    int col_field = bmp_getpixel(615,455);
+    
+    /* get absolute position of this element */
+    info_get_absolute(config, (info_elem_t *)element);
+    int pos_x = element->hdr.pos.abs_x;
+    int pos_y = element->hdr.pos.abs_y;
+
+    element->hdr.pos.w = 96;
+    element->hdr.pos.h = 32;
+    
+    if(run_type == INFO_PRINT)
+    {
+        uint batcol = 0;
+        uint batfil = 0;
+        bmp_fill(col_field,pos_x-4,pos_y+14,96,32); // clear the Canon battery icon
+        
+        if (batlev <= (int)element->pct_red)
+        {
+            batcol = COLOR_RED;
+        }
+        else
+        {
+            batcol = COLOR_WHITE;
+        }
+        
+        bmp_fill(batcol,pos_x+10,pos_y,72,32); // draw the new battery icon
+        bmp_fill(batcol,pos_x,pos_y+8,12,16);
+        bmp_fill(col_field,pos_x+14,pos_y+4,64,24);
+        
+        if (batlev <= (int)element->pct_red)
+        {
+            batcol = COLOR_RED;
+        }
+        else if (batlev <= (int)element->pct_yellow)
+        {
+            batcol = COLOR_YELLOW;
+        }
+        else
+        {
+            batcol = COLOR_GREEN2;
+        }
+        
+        batfil = batlev*56/100;
+        bmp_fill(batcol,pos_x+18+56-batfil,pos_y+8,batfil,16);
+    }
+    return 0;
+}
+
+
+uint32_t info_get_next_z(info_elem_t *config, uint32_t current)
+{
+    uint32_t pos = 0;
+    uint32_t next = INFO_Z_END;
+
+    while(config[pos].type != INFO_TYPE_END)
+    {
+        uint32_t z = config[pos].hdr.pos.z;
+        
+        if(z >= current && z < next )
+        {
+            next = z;
+        }
+        pos++;
+    }
+
+    return next;
+}
+
+uint32_t info_print_element(info_elem_t *config, info_elem_t *element, uint32_t run_type)
+{
+    switch(element->type)
+    {
+        case INFO_TYPE_STRING:
+            return info_print_string(config, (info_elem_string_t *)element, run_type);
+        case INFO_TYPE_BATTERY_ICON:
+            return info_print_battery_icon(config, (info_elem_battery_icon_t *)element, run_type);
+        case INFO_TYPE_BATTERY_PERF:
+            return info_print_battery_perf(config, (info_elem_battery_perf_t *)element, run_type);
+        case INFO_TYPE_FILL:
+            return info_print_fill(config, (info_elem_fill_t *)element, run_type);
+        case INFO_TYPE_ICON:
+            return info_print_icon(config, (info_elem_icon_t *)element, run_type);
+    }
+    
+    return 1;
+}
+
+uint32_t info_print_config(info_elem_t *config)
+{
+    uint32_t pos = 0;
+    int32_t z = 0;
+
+    while(config[pos].type != INFO_TYPE_END)
+    {
+        /* by default nothing is shown, so reset all shown flags */
+        config[pos].hdr.pos.shown = 0;
+        
+        /* but let check if the element should get shown. this updates above flag and ensures that lower layers are only drawn if the referenced is shown */
+        info_print_element(config, &(config[pos]), INFO_PRERUN);
+        
+        pos++;
+    }
+
+    z = info_get_next_z(config, 0);
+    while(z != INFO_Z_END)
+    {
+        pos = 0;
+        while(config[pos].type != INFO_TYPE_END)
+        {
+            if(z == config[pos].hdr.pos.z)
+            {
+                info_print_element(config, &(config[pos]), INFO_PRINT);
+                
+                if(config[0].config.show_boundaries || config[0].config.selected_item == pos || config[0].config.anchor_target == pos)
+                {
+                    int color = COLOR_RED;
+                    
+                    if(config[0].config.selected_item == pos)
+                    {
+                        color = COLOR_GREEN1;
+                    }
+                    else if(config[0].config.anchor_target == pos)
+                    {
+                        color = COLOR_BLUE;
+                    }
+                    draw_line(config[pos].hdr.pos.abs_x, config[pos].hdr.pos.abs_y, config[pos].hdr.pos.abs_x + config[pos].hdr.pos.w, config[pos].hdr.pos.abs_y, color);
+                    draw_line(config[pos].hdr.pos.abs_x, config[pos].hdr.pos.abs_y, config[pos].hdr.pos.abs_x, config[pos].hdr.pos.abs_y + config[pos].hdr.pos.h, color);
+                    draw_line(config[pos].hdr.pos.abs_x + config[pos].hdr.pos.w, config[pos].hdr.pos.abs_y + config[pos].hdr.pos.h, config[pos].hdr.pos.abs_x, config[pos].hdr.pos.abs_y + config[pos].hdr.pos.h, color);
+                    draw_line(config[pos].hdr.pos.abs_x + config[pos].hdr.pos.w, config[pos].hdr.pos.abs_y + config[pos].hdr.pos.h, config[pos].hdr.pos.abs_x + config[pos].hdr.pos.w, config[pos].hdr.pos.abs_y, color);
+                    draw_line(config[pos].hdr.pos.abs_x, config[pos].hdr.pos.abs_y, config[pos].hdr.pos.abs_x + config[pos].hdr.pos.w, config[pos].hdr.pos.abs_y + config[pos].hdr.pos.h, color);
+                    draw_line(config[pos].hdr.pos.abs_x + config[pos].hdr.pos.w, config[pos].hdr.pos.abs_y, config[pos].hdr.pos.abs_x, config[pos].hdr.pos.abs_y + config[pos].hdr.pos.h, color);
+                }
+            }
+            pos++;
+        }
+        /* find the next highest layers */
+        z = info_get_next_z(config, z + 1);
+    } 
+    return 0;
+}
+
+
+uint32_t info_print_screen()
+{
+    return info_print_config(info_config);
+}
+
+void info_menu_item_select(void* priv, int delta)
+{
+    uint32_t count = 0;
+    info_elem_t *config = (info_elem_t *)priv;
+
+    while(config[count].type != INFO_TYPE_END)
+    {
+        count++;
+    }
+    
+    if((delta < 0 && config[0].config.selected_item > 0) || (delta > 0 && config[0].config.selected_item < count))
+    {
+        config[0].config.selected_item += delta;
+    }
+}
+
+void info_menu_item_display(void *priv, int x, int y, int selected)
+{
+    info_elem_t *config = (info_elem_t *)priv;
+    
+    if(config[0].config.selected_item)
+    {
+        bmp_printf(selected ? MENU_FONT_SEL : MENU_FONT, x, y, "Select item: #%d", config[0].config.selected_item);
+        if(selected)
+        {
+            info_print_config(config);
+        }
+    }
+    else
+    {
+        bmp_printf(selected ? MENU_FONT_SEL : MENU_FONT, x, y, "Select item: (none)");
+    }
+}
+
+void info_menu_item_posx_select(void* priv, int delta)
+{
+    info_elem_t *config = (info_elem_t *)priv;
+    info_elem_t *item = (info_elem_t *) &config[config[0].config.selected_item];
+    
+    if((delta < 0 && item->hdr.pos.x > -50) || (delta > 0 && item->hdr.pos.x < 720))
+    {
+        item->hdr.pos.x += delta;
+    }
+}
+
+void info_menu_item_posy_select(void* priv, int delta)
+{
+    info_elem_t *config = (info_elem_t *)priv;
+    info_elem_t *item = (info_elem_t *) &config[config[0].config.selected_item];
+    
+    if((delta < 0 && item->hdr.pos.y > -50) || (delta > 0 && item->hdr.pos.y < 480))
+    {
+        item->hdr.pos.y += delta;
+    }
+}
+
+void info_menu_item_posz_select(void* priv, int delta)
+{
+    info_elem_t *config = (info_elem_t *)priv;
+    info_elem_t *item = (info_elem_t *) &config[config[0].config.selected_item];
+    
+    if((delta < 0 && item->hdr.pos.z > 0) || (delta > 0 && item->hdr.pos.z < 32))
+    {
+        item->hdr.pos.z += delta;
+    }
+}
+
+void info_menu_item_posx_display(void *priv, int x, int y, int selected)
+{
+    info_elem_t *config = (info_elem_t *)priv;
+    
+    if(config[0].config.selected_item)
+    {
+        bmp_printf(selected ? MENU_FONT_SEL : MENU_FONT, x, y, "X-Position: #%d", config[config[0].config.selected_item].hdr.pos.x);
+        if(selected)
+        {
+            info_print_config(config);
+        }
+    }
+    else
+    {
+        bmp_printf(selected ? MENU_FONT_SEL : MENU_FONT, x, y, "X-Position: (none)");
+    }
+}
+
+void info_menu_item_posy_display(void *priv, int x, int y, int selected)
+{
+    info_elem_t *config = (info_elem_t *)priv;
+    
+    if(config[0].config.selected_item)
+    {
+        bmp_printf(selected ? MENU_FONT_SEL : MENU_FONT, x, y, "Y-Position: #%d", config[config[0].config.selected_item].hdr.pos.y);
+        if(selected)
+        {
+            info_print_config(config);
+        }
+    }
+    else
+    {
+        bmp_printf(selected ? MENU_FONT_SEL : MENU_FONT, x, y, "Y-Position: (none)");
+    }
+}
+
+void info_menu_item_posz_display(void *priv, int x, int y, int selected)
+{
+    info_elem_t *config = (info_elem_t *)priv;
+    
+    if(config[0].config.selected_item)
+    {
+        bmp_printf(selected ? MENU_FONT_SEL : MENU_FONT, x, y, "Z-Position: #%d", config[config[0].config.selected_item].hdr.pos.z);
+        if(selected)
+        {
+            info_print_config(config);
+        }
+    }
+    else
+    {
+        bmp_printf(selected ? MENU_FONT_SEL : MENU_FONT, x, y, "Z-Position: (none)");
+    }
+}
+
+
+
+
+void info_menu_item_anchor_select(void* priv, int delta)
+{
+    info_elem_t *config = (info_elem_t *)priv;
+    info_elem_t *item = (info_elem_t *) &config[config[0].config.selected_item];
+
+    if((delta < 0 && item->hdr.pos.anchor_flags > 0) || (delta > 0 && item->hdr.pos.anchor_flags < 15))
+    {
+        item->hdr.pos.anchor_flags += delta;
+    }
+}
+
+void info_menu_item_anchor_display(void *priv, int x, int y, int selected)
+{
+    info_elem_t *config = (info_elem_t *)priv;
+    const char *text[] = {
+        "Absolute",
+        "Left", "H-Center", "Right",
+        "Top",
+        "Top-Left", "Top-Center", "Top-Right", 
+        "V-Center",
+        "Left-Center", "Center", "Right-Center",
+        "Bottom",
+        "Bottom-Left", "Bottom-Center", "Bottom-Right"};
+
+    if(config[0].config.selected_item)
+    {
+        bmp_printf(selected ? MENU_FONT_SEL : MENU_FONT, x, y, "Anchored: %s", text[config[config[0].config.selected_item].hdr.pos.anchor_flags]);
+        if(selected)
+        {
+            info_print_config(config);
+        }
+    }
+    else
+    {
+        bmp_printf(selected ? MENU_FONT_SEL : MENU_FONT, x, y, "Anchored: (none)");
+    }
+}
+
+void info_menu_item_anchor_item_select(void* priv, int delta)
+{
+    uint32_t count = 0;
+    info_elem_t *config = (info_elem_t *)priv;
+    info_elem_t *item = (info_elem_t *) &config[config[0].config.selected_item];
+
+    while(config[count].type != INFO_TYPE_END)
+    {
+        count++;
+    }
+    
+    if((delta < 0 && item->hdr.pos.anchor > 0) || (delta > 0 && item->hdr.pos.anchor < count))
+    {
+        item->hdr.pos.anchor += delta;
+    }
+}
+
+void info_menu_item_anchor_item_display(void *priv, int x, int y, int selected)
+{
+    info_elem_t *config = (info_elem_t *)priv;
+    info_elem_t *item = (info_elem_t *) &config[config[0].config.selected_item];
+    
+    if(config[0].config.selected_item)
+    {
+        bmp_printf(selected ? MENU_FONT_SEL : MENU_FONT, x, y, "Anchor item: #%d", item->hdr.pos.anchor);
+        if(selected)
+        {
+            info_print_config(config);
+        }
+    }
+    else
+    {
+        bmp_printf(selected ? MENU_FONT_SEL : MENU_FONT, x, y, "Anchor item: (none)");
+    }
+}
+
+
+void info_menu_item_anchor_self_select(void* priv, int delta)
+{
+    info_elem_t *config = (info_elem_t *)priv;
+    info_elem_t *item = (info_elem_t *) &config[config[0].config.selected_item];
+
+    if((delta < 0 && item->hdr.pos.anchor_flags_self > 0) || (delta > 0 && item->hdr.pos.anchor_flags_self < 15))
+    {
+        item->hdr.pos.anchor_flags_self += delta;
+    }
+}
+
+void info_menu_item_anchor_self_display(void *priv, int x, int y, int selected)
+{
+    info_elem_t *config = (info_elem_t *)priv;
+    const char *text[] = {
+        "Absolute",
+        "Left", "H-Center", "Right",
+        "Top",
+        "Top-Left", "Top-Center", "Top-Right", 
+        "V-Center",
+        "Left-Center", "Center", "Right-Center",
+        "Bottom",
+        "Bottom-Left", "Bottom-Center", "Bottom-Right" };
+
+    if(config[0].config.selected_item)
+    {
+        bmp_printf(selected ? MENU_FONT_SEL : MENU_FONT, x, y, "Own anchor: %s", text[config[config[0].config.selected_item].hdr.pos.anchor_flags_self]);
+        if(selected)
+        {
+            info_print_config(config);
+        }
+    }
+    else
+    {
+        bmp_printf(selected ? MENU_FONT_SEL : MENU_FONT, x, y, "Own anchor: (none)");
+    }
+}
+
+static struct menu_entry info_menus[] = {
+    {
+        .name = "FlexInfo Settings",
+        .select = menu_open_submenu,
+        .submenu_width = 700,
+        .children =  (struct menu_entry[]) {
+            {
+                .name = "Show boundaries",
+                .priv = &(info_config[0].config.show_boundaries),
+                .max = 1,
+                .help = "Enable boundary display for all elements.",
+            },
+            {
+                .name = "Select item",
+                .priv = info_config,
+                .min = 0,
+                .max = 64,
+                .select = info_menu_item_select,
+                .display = info_menu_item_display,
+                .help = "Select a specific element for editing.",
+            },
+            {
+                .name = "Pos X",
+                .priv = info_config,
+                .min = 0,
+                .max = 720,
+                .select = info_menu_item_posx_select,
+                .display = info_menu_item_posx_display,
+                .help = "Move item in its X position.",
+            },
+            {
+                .name = "Pos Y",
+                .priv = info_config,
+                .min = 0,
+                .max = 480,
+                .select = info_menu_item_posy_select,
+                .display = info_menu_item_posy_display,
+                .help = "Move item in its Y position.",
+            },
+            {
+                .name = "Pos Z",
+                .priv = info_config,
+                .min = 0,
+                .max = 32,
+                .select = info_menu_item_posz_select,
+                .display = info_menu_item_posz_display,
+                .help = "Move item in its Z position.",
+            },
+            {
+                .name = "Anchor type",
+                .priv = info_config,
+                .min = 0,
+                .max = 9,
+                .select = info_menu_item_anchor_select,
+                .display = info_menu_item_anchor_display,
+                .help = "Select anchor tyoe",
+            },
+            {
+                .name = "Anchor item",
+                .priv = info_config,
+                .select = info_menu_item_anchor_item_select,
+                .display = info_menu_item_anchor_item_display,
+                .help = "Select Anchor item.",
+            },
+            {
+                .name = "Anchor on self",
+                .priv = info_config,
+                .min = 0,
+                .max = 9,
+                .select = info_menu_item_anchor_self_select,
+                .display = info_menu_item_anchor_self_display,
+                .help = "Select anchor tyoe",
+            },
+            MENU_EOL,
+        }
+    }
+};
+
+static void info_init()
+{
+    menu_add( "Prefs", info_menus, COUNT(info_menus) );
+}
+
+static void info_edit_task()
+{
+    TASK_LOOP
+    {
+        if (info_config[0].config.selected_item || info_config[0].config.show_boundaries)
+        {
+            info_print_config(info_config);
+            msleep(50);
+        }
+        else
+        {
+            msleep(500);
+        }
+    }
+}
+TASK_CREATE( "info_edit_task", info_edit_task, 0, 0x16, 0x1000 );
+INIT_FUNC("info.init", info_init);
+

File src/flexinfo.h

View file
+
+
+/* these are binary coded (combineable) flags to either set ABSOLUTE or like (LEFT|CENTER)
+   examples:
+
+    INFO_ANCHOR_ABSOLUTE: the element has absolute coordinates but only is printed when the anchor element is shown    
+    (INFO_ANCHOR_LEFT | INFO_ANCHOR_BOTTOM): element is printed x/y pixels from the anchor elements lower left corner
+ */
+#define INFO_ANCHOR_ABSOLUTE 0
+#define INFO_ANCHOR_LEFT     (1<<0)
+#define INFO_ANCHOR_HCENTER  (2<<0)
+#define INFO_ANCHOR_RIGHT    (3<<0)
+#define INFO_ANCHOR_TOP      (1<<2)
+#define INFO_ANCHOR_VCENTER  (2<<2)
+#define INFO_ANCHOR_BOTTOM   (3<<2)
+
+#define INFO_ANCHOR_H_MASK   (3<<0)
+#define INFO_ANCHOR_V_MASK   (3<<2)
+
+#define INFO_Z_END 0x7FFFFFFF
+#define INFO_ANCHOR_NONE 0
+
+#define INFO_PRINT  0
+#define INFO_PRERUN 1
+
+typedef struct
+{
+    int32_t x;
+    int32_t y;
+    int32_t z;
+    uint32_t anchor_flags;
+    uint32_t anchor;
+    uint32_t anchor_flags_self;
+    int32_t abs_x;
+    int32_t abs_y;
+    int32_t w;
+    int32_t h;
+    uint32_t shown;
+} info_elem_pos_t;
+
+
+#define INFO_TYPE_CONFIG 0
+#define INFO_TYPE_END    1
+#define INFO_TYPE_STRING 2
+#define INFO_TYPE_FILL   3
+#define INFO_TYPE_ICON   4
+
+#define INFO_TYPE_BATTERY_ICON   5
+#define INFO_TYPE_BATTERY_PERF   6
+
+typedef struct
+{
+    uint32_t type;
+    info_elem_pos_t pos;
+} info_elem_header_t;
+
+/* known strings to display */
+#define INFO_STRING_ISO             1
+#define INFO_STRING_ISO_MIN         2
+#define INFO_STRING_ISO_MAX         3
+#define INFO_STRING_ISO_MINMAX      4
+#define INFO_STRING_KELVIN          5
+#define INFO_STRING_WBS_BA          6
+#define INFO_STRING_WBS_GM          7
+#define INFO_STRING_DATE_DDMMYYYY   8
+#define INFO_STRING_DATE_YYYYMMDD   9
+#define INFO_STRING_DATE_MM         10
+#define INFO_STRING_DATE_DD         11
+#define INFO_STRING_DATE_YY         12
+#define INFO_STRING_DATE_YYYY       13
+#define INFO_STRING_TIME            14
+#define INFO_STRING_TIME_HH12       15
+#define INFO_STRING_TIME_HH24       16
+#define INFO_STRING_TIME_MM         17
+#define INFO_STRING_TIME_SS         18
+#define INFO_STRING_TIME_AMPM       19
+#define INFO_STRING_ARTIST          20
+#define INFO_STRING_COPYRIGHT       21
+#define INFO_STRING_LENS            22
+#define INFO_STRING_BUILD           23
+#define INFO_STRING_CARD_LABEL_A    24
+#define INFO_STRING_CARD_LABEL_B    25
+#define INFO_STRING_CARD_SPACE_A    26
+#define INFO_STRING_CARD_SPACE_B    27
+#define INFO_STRING_CARD_FILES_A    28
+#define INFO_STRING_CARD_FILES_B    29
+#define INFO_STRING_CARD_MAKER_A    30
+#define INFO_STRING_CARD_MAKER_B    31
+#define INFO_STRING_CARD_MODEL_A    32
+#define INFO_STRING_CARD_MODEL_B    33
+#define INFO_STRING_BATTERY_PCT     34
+#define INFO_STRING_BATTERY_ID      35
+
+#define INFO_FONT_SMALL  0
+#define INFO_FONT_MEDIUM 1
+#define INFO_FONT_LARGE  2
+#define INFO_FONT_CANON  3
+
+#define INFO_COL_BG    0xFFFFFFFE
+#define INFO_COL_FIELD 0xFFFFFFFD
+
+
+typedef struct
+{
+    info_elem_header_t hdr;
+    uint32_t string_type;
+    uint32_t fgcolor;
+    uint32_t bgcolor;
+    uint32_t font_type;
+} info_elem_string_t;
+
+typedef struct
+{
+    info_elem_header_t hdr;
+    uint32_t string_type;
+    uint32_t color;
+} info_elem_fill_t;
+
+typedef struct
+{
+    info_elem_header_t hdr;
+    uint32_t show_boundaries;
+    uint32_t selected_item;
+    uint32_t anchor_target;
+} info_elem_config_t;
+
+typedef struct
+{
+    info_elem_header_t hdr;
+    uint32_t pct_red;
+    uint32_t pct_yellow;
+} info_elem_battery_icon_t;
+
+typedef struct
+{
+    info_elem_header_t hdr;
+    uint32_t horizontal;
+    uint32_t width;
+    uint32_t height;
+} info_elem_battery_perf_t;
+
+typedef struct
+{
+    info_elem_header_t hdr;
+    uint32_t string_type;
+    uint32_t fgcolor;
+    uint32_t bgcolor;
+    uint8_t filename;
+    uint8_t *icon_data;
+} info_elem_icon_t;
+
+typedef union
+{
+    uint32_t type;
+    info_elem_header_t hdr;
+    info_elem_config_t config;
+    info_elem_string_t string;
+    info_elem_battery_icon_t battery_icon;
+    info_elem_battery_perf_t battery_perf;
+    info_elem_fill_t fill;
+    info_elem_icon_t icon;
+} info_elem_t;
+
+
+

File src/ph_info_disp.c

View file
 void display_shooting_info() // called from debug task
 {
 	if (lv) return;
-    
     uint32_t fnt;
 	int bg;
     int col_bg = bmp_getpixel(10,1);
     int col_field = bmp_getpixel(615,375);
     
+#if defined(CONFIG_7D)    
+    info_print_screen(); 
+    iso_refresh_display();
+
+    bg = bmp_getpixel(HDR_STATUS_POS_X, HDR_STATUS_POS_Y);
+    fnt = FONT(FONT_MED, COLOR_FG_NONLV, bg);
+    hdr_display_status(fnt);
+
+    bg = bmp_getpixel(MLU_STATUS_POS_X, MLU_STATUS_POS_Y);
+    bmp_printf(FONT(FONT_MED, COLOR_YELLOW, bg), MLU_STATUS_POS_X, MLU_STATUS_POS_Y, get_mlu() ? "MLU" : "   ");
+
+    display_trap_focus_info();   
+    return;
+#endif
+
+    
 #if defined(CONFIG_7D)
     /* clearing some zones, revise and make generic or remove */
     if (lens_info.raw_iso == 0)