static void dbg_memspy_init() { // initial state of the analyzed memory bmp_printf(FONT_MED, 10,10, "memspy init @ f:%x ... (l:+%x) ... t:%x", mem_spy_start, mem_spy_len, mem_spy_start + mem_spy_len * 4); SleepTask(1000); //debug_log("memspy init @ from:%x ... (len:%x) ... to:%x", mem_spy_start, mem_spy_len, mem_spy_start + mem_spy_len * 4); //mem_spy_len is number of int32's if (!dbg_memmirror) dbg_memmirror = AllocateMemory(mem_spy_len*4 + 100); // local copy of mem area analyzed if (!dbg_memmirror) return; if (!dbg_memchanges) dbg_memchanges = AllocateMemory(mem_spy_len*4 + 100); // local copy of mem area analyzed if (!dbg_memchanges) return; //if (!dbg_memlogged) dbg_memlogged = AllocateMemory(mem_spy_len*4 + 100); // is this change logged //if (!dbg_memlogged) return; int i; int crc = 0; for (i = 0; i < mem_spy_len; i++) { unsigned int addr = dbg_memspy_get_addr(i); dbg_memmirror[i] = MEMX(addr); dbg_memchanges[i] = 0; //dbg_memlogged[i] = 0; crc += dbg_memmirror[i]; } bmp_printf(FONT_MED, 10,10, "memspy OK: %x", crc); //debug_log("memspy OK: %x", crc); _tic(); SleepTask(1000); }
static int yuv422_show(char* filename) { uint32_t size; if( FIO_GetFileSize( filename, &size ) != 0 ) return 0; uint32_t * buf = fio_malloc(size); if (!buf) return 0; struct vram_info * vram = get_yuv422_vram(); if (!vram->vram) goto err; clrscr(); bmp_printf(FONT_MED, 600, 460, "%d", size); int w,h; // auto-generated code from 422-jpg.py if (size == 1120 * 746 * 2) { w = 1120; h = 746; } else if (size == 1872 * 1080 * 2) { w = 1872; h = 1080; } else if (size == 1024 * 680 * 2) { w = 1024; h = 680; } else if (size == 1560 * 884 * 2) { w = 1560; h = 884; } else if (size == 944 * 632 * 2) { w = 944; h = 632; } else if (size == 928 * 616 * 2) { w = 928; h = 616; } else if (size == 1576 * 1048 * 2) { w = 1576; h = 1048; } else if (size == 1576 * 632 * 2) { w = 1576; h = 632; } else if (size == 720 * 480 * 2) { w = 720; h = 480; } else if (size == 1056 * 704 * 2) { w = 1056; h = 704; } else if (size == 1720 * 974 * 2) { w = 1720; h = 974; } else if (size == 1280 * 580 * 2) { w = 1280; h = 580; } else if (size == 640 * 480 * 2) { w = 640; h = 480; } else if (size == 1024 * 680 * 2) { w = 1024; h = 680; } else if (size == 1056 * 756 * 2) { w = 1056; h = 756; } else if (size == 1728 * 972 * 2) { w = 1728; h = 972; } else if (size == 1680 * 945 * 2) { w = 1680; h = 945; } else if (size == 1280 * 560 * 2) { w = 1280; h = 560; } else if (size == 1152 * 768 * 2) { w = 1152; h = 768; } else if (size == 1904 * 1274 * 2) { w = 1904; h = 1274; } else if (size == 1620 * 1080 * 2) { w = 1620; h = 1080; } else if (size == 1280 * 720 * 2) { w = 1280; h = 720; } else if (size == 1808 * 1206 * 2) { w = 1808; h = 1206; } // 6D Movie else if (size == 1816 * 1210 * 2) { w = 1816; h = 1210; } // 6D Photo else if (size == 1104 * 736 * 2) { w = 1104; h = 736; } // 6D Zoom else if (size == 1680 * 952 * 2) { w = 1680; h = 952; } // 600D else if (size == 1728 * 972 * 2) { w = 1728; h = 972; } // 600D Crop else if (size == 960 * 639 * 2) { w = 960; h = 639; } // 650D LV STDBY else if (size == 1729 * 1151 * 2) { w = 1728; h = 1151; } // 650D 1080p/480p recording else if (size == 1280 * 689 * 2) { w = 1280; h = 689; } // 650D 720p recording else goto err; bmp_printf(FONT_MED, 600, 460, " %dx%d ", w, h); size_t rc = read_file( filename, buf, size ); if( rc != size ) goto err; yuv_resize(buf, w, h, (uint32_t*)vram->vram, vram->width, vram->height); fio_free(buf); return 1; err: fio_free(buf); return 0; }
unsigned int lv_rec_vsync_cbr(unsigned int ctx) { lv_rec_data_t *data = lv_rec_state; int err = 0; if(!data) { return 0; } if(data->abort) { data->finished = 1; lv_rec_state = NULL; return 0; } if(!data->running) { data->running = 1; ConnectWriteEDmac(data->dmaChannel, data->dmaSourceConn); err = PackMem_SetEDmacForMemorySuite(data->dmaChannel, data->chunkData.memSuite, data->dmaFlags); PackMem_StartEDmac(data->dmaChannel, 0); if(err) { bmp_printf( FONT(FONT_MED, COLOR_WHITE, COLOR_BLACK), 30, 20 * (18), "Failed: PackMem_SetEDmacForMemorySuite"); } } else { lv_rec_state->capturedFrames++; if(data->capturedFrames >= data->maxFrames || (data->capturedFrames - data->savedFrames) >= data->maxFramesBufferable) { PackMem_PopEDmacForMemorySuite(data->dmaChannel); PackMem_PopEDmacForMemorySuite(data->dmaCopyChannel); data->finished = 1; lv_rec_state = NULL; return 0; } } if(data->options.rawMode) { #define RAW_LV_EDMAC 0xC0F26208 /* copy from RAW buffer */ ConnectReadEDmac(data->dmaCopyChannel, data->dmaCopyConn); err = PackMem_SetEDmacForMemorySuite(data->dmaCopyChannel, data->memCopySuite, data->dmaFlags); PackMem_StartEDmac(data->dmaCopyChannel, 2); if(err) { bmp_printf( FONT(FONT_MED, COLOR_WHITE, COLOR_BLACK), 30, 20 * (18), "Failed: PackMem_SetEDmacForMemorySuite"); } } return 0; }
void draw_help_not_installed_page() { bmp_fill(COLOR_BLACK, 0, 0, 720, 480); bfnt_puts("Help files not found", 10, 20, COLOR_WHITE, COLOR_BLACK); bmp_printf(FONT_MED, 10, 150, "Magic Lantern help files could not be found. "); bmp_printf(FONT_MED, 10, 200, "Make sure all ML files are installed to your card. "); bmp_printf(FONT_MED, 10, 250, "See http://wiki.magiclantern.fm/install for instructions. "); }
unsigned int second_timer(unsigned int ctx) { static int counter = 0; bmp_printf( FONT(FONT_MED, COLOR_WHITE, COLOR_BLACK), 30, 20, "seconds: %d", counter++); return 0; }
void qemu_hello() { bmp_printf(FONT_LARGE, 50, 50, "Hello from QEMU!"); for (int i = 1; i < 14; i++) { bfnt_draw_char(-i, i * 50, 100, COLOR_BLUE, COLOR_WHITE); bmp_printf(FONT(FONT_MED, COLOR_BLUE, COLOR_WHITE), i * 50, 140, "%d", i); } qprintf("\nHello at QEMU console!\n\n"); call("dispcheck"); call("shutdown"); while(1); // that's all, folks! }
static void find_response_curve_ex(const char* fname, int iso, int dgain, int htp) { bmp_printf(FONT_MED, 0, 100, "ISO %d\nDGain %d\n%s", iso, dgain, htp ? "HTP" : ""); set_htp(htp); msleep(100); lens_set_iso(iso); set_display_gain_equiv(dgain); find_response_curve(fname); set_display_gain_equiv(0); set_htp(0); }
void display_overlay(uint8_t *vram_address) { char buffer[LP_MAX_WORD]; if (FLAG_GUI_MODE == GUIMODE_OLC && AE_IS_CREATIVE(DPData.ae)) { if (FLAG_DISPLAY_ON) { int current_cmode = get_current_cmode(); if (status.msm_active) bmp_printf(vram_address, FONT(FONT_SMALL, COLOR_BLACK, COLOR_GRAY), 35, 96, "[***]"); else if (status.cmode_active && current_cmode != CMODE_NONE) bmp_printf(vram_address, FONT(FONT_SMALL, COLOR_BLACK, COLOR_GRAY), 16, 96, "%s", cmodes_config.names[current_cmode]); if (status.fexp && DPData.tv_val != TV_VAL_BULB) bmp_printf(vram_address, FONT(FONT_SMALL, COLOR_BLACK, COLOR_GRAY), 138, 32, "#"); if (settings.autoiso_enable && (DPData.ae != AE_MODE_M || DPData.tv_val != TV_VAL_BULB)) bmp_printf(vram_address, FONT(FONT_SMALL, COLOR_BLACK, COLOR_GRAY), 237, 14, "%s", AUTOISO_AUTO); if (DPData.wb == WB_MODE_COLORTEMP) bmp_printf(vram_address, FONT(FONT_SMALL, COLOR_BLACK, COLOR_GRAY), 50, 138, "%d", DPData.color_temp); if (DPData.ae_bkt) { ec_print(buffer, DPData.ae_bkt); bmp_printf(vram_address, FONT(FONT_SMALL, COLOR_BLACK, COLOR_GRAY), 224, 96, "%s", buffer); } #ifdef RELEASE bmp_printf(vram_address, FONT(FONT_SMALL, COLOR_BLACK, COLOR_BLUE), 148, 0, LP_WORD(L_P_400PLUS)); #else bmp_printf(vram_address, FONT(FONT_SMALL, COLOR_BLACK, COLOR_RED ), 20, 0, LP_WORD(L_A_WARNING)); #endif if (*display_message) { if(timestamp() < message_timeout) bmp_printf(vram_address, FONT(FONT_SMALL, COLOR_WHITE, COLOR_BLACK), 16, 228, display_message); else *display_message = '\0'; } } } }
static void shutter_lock_print( void * priv, int x, int y, int selected ) { bmp_printf( selected ? MENU_FONT_SEL : MENU_FONT, x, y, "Shutter Lock : %s", shutter_lock ? "ON" : "OFF" ); }
void draw_beta_warning() { bmp_fill(COLOR_BLACK, 0, 0, 720, 480); bfnt_puts("Magic Lantern", 242, 53, COLOR_WHITE, COLOR_BLACK); bmp_printf(FONT_MED, 50, 150, "This is a development snapshot for testing purposes."); bmp_printf(FONT_MED, 50, 200, " Please report all bugs at www.magiclantern.fm. "); bmp_printf(FONT_MED, 50, 250, " Be careful using it for production work. "); bmp_printf(FONT_MED, 50, 300, " Enjoy! "); big_bmp_printf(FONT_MED, 10, 410, "Magic Lantern version : %s\n" "Mercurial changeset : %s\n" "Built on %s by %s.", build_version, build_id, build_date, build_user); }
static void vram_print( void * priv, int x, int y, int selected ) { unsigned menu_font = selected ? FONT(FONT_LARGE, COLOR_WHITE, COLOR_BLACK) : MENU_FONT; bmp_printf( menu_font, x, y, "%s = %d", vram_param_names[(int)priv], MEM(vram_params[(int)priv]) ); menu_draw_icon(x,y,MNI_NONE,0); }
int get_prop_picstyle_from_index(int index) { switch(index) { case 1: return 0x87; // auto case 2: return 0x81; case 3: return 0x82; case 4: return 0x83; case 5: return 0x84; case 6: return 0x85; case 7: return 0x86; case 8: return 0x21; case 9: return 0x22; case 10: return 0x23; } bmp_printf(FONT_LARGE, 0, 0, "unk picstyle index: %x", index); return 0; }
int get_prop_picstyle_index(int pic_style) { switch(pic_style) { case 0x87: return 1; // auto case 0x81: return 2; // std case 0x82: return 3; // portrait case 0x83: return 4; // landscape case 0x84: return 5; // neutral case 0x85: return 6; // faithful case 0x86: return 7; // mono case 0x21: return 8; // user 1 case 0x22: return 9; // user 2 case 0x23: return 10; // user 3 } bmp_printf(FONT_LARGE, 0, 0, "unk picstyle: %x", pic_style); return 0; }
void menu_help_show_page(int page) { menu_help_active = 1; #ifndef CONFIG_RELEASE_BUILD if (page == 1) { draw_beta_warning(); return; } // display this instead of the main About page #endif if (page == 0) { draw_404_page(); return; } // help page not found if (page == -1) { draw_help_not_installed_page(); return; } // help page not found char path[100]; struct bmp_file_t * doc = (void*) -1; #ifdef CONFIG_HELP_CACHE char rpath[30]; snprintf(rpath, sizeof(rpath), CARD_DRIVE "ML/doc/page-%03d.vrm", page); if (load_vram(rpath)==-1) #endif { snprintf(path, sizeof(path), CARD_DRIVE "ML/doc/page-%03d.bmh", page); doc = bmp_load(path, 1); if (!doc) { snprintf(path, sizeof(path), CARD_DRIVE "ML/doc/page-%03d.bmp", page); doc = bmp_load(path, 1); } if (doc) { bmp_draw_scaled_ex(doc, 0, 0, 720, 480, 0); #ifdef CONFIG_HELP_CACHE extern int _bmp_draw_should_stop; if (!_bmp_draw_should_stop) save_vram(rpath); #endif FreeMemory(doc); } else { clrscr(); bmp_printf(FONT_MED, 0, 0, "Could not load help page %s.", path); } } }
void console_puts(const char* str) // don't DebugMsg from here! { #define NEW_CHAR(c) CONSOLE_BUFFER(console_buffer_index++) = (c) #ifdef CONFIG_QEMU qprintf("%s", str); #endif #ifdef CONSOLE_DEBUG bmp_printf(FONT_MED, 0, 0, "%s ", str); if (console_log_file) my_fprintf( console_log_file, "%s", str ); #endif const char* c = str; while (*c) { if (*c == '\n') { if (mod(console_buffer_index, CONSOLE_W) == 0) NEW_CHAR(' '); while (mod(console_buffer_index, CONSOLE_W) != 0) NEW_CHAR(' '); } else if (*c == '\t') { NEW_CHAR(' '); while (mod(mod(console_buffer_index, CONSOLE_W), 4) != 0) NEW_CHAR(' '); } else if (*c == 8) { console_buffer_index = mod(console_buffer_index - 1, BUFSIZE); console_buffer[console_buffer_index] = ' '; } else NEW_CHAR(*c); c++; } console_buffer_index = mod(console_buffer_index, BUFSIZE); }
void draw_404_page() { bmp_fill(COLOR_BLACK, 0, 0, 720, 480); bfnt_puts("404 Undocumented Feature", 10, 20, COLOR_WHITE, COLOR_BLACK); bmp_printf(FONT_MED, 10, 100, "This feature is probably not yet documented."); bmp_printf(FONT_MED, 10, 120, "After all, we are programmers, not tech writers."); bmp_printf(FONT_MED, 10, 180, "But... you can simply try it and see what it does."); bmp_printf(FONT_MED, 10, 240, "Then, write a short paragraph to describe it,"); bmp_printf(FONT_MED, 10, 260, "and we will include it in the user guide."); bmp_printf(FONT_MED, 10, 320, "Thanks!"); }
void display_shooting_info() // called from debug task { if (lv) return; #ifdef FEATURE_FLEXINFO // from flexinfo.c info_print_screen(); #endif // the following is stuff not yet ported to flexinfo #ifdef FEATURE_LCD_SENSOR_REMOTE display_lcd_remote_icon(555, 460); #endif // hack for Rebel cameras to display intermediate ISOs iso_refresh_display(); display_trap_focus_info(); #ifdef STROBO_READY_AND_WE_CAN_USE_IT int col_field = bmp_getpixel(20,10); if (flash_info.mode==STROBO_FLASH_MODE_MANUAL) { uint32_t fntl = FONT(FONT_LARGE, COLOR_YELLOW, col_field); fnt = FONT(FONT_SMALL, COLOR_CYAN, col_field); bmp_printf(fnt, 488, 188, "A"); bmp_printf(fntl, 498, 185, "%3d", 1 << flash_info.group_a_output); bmp_printf(fnt, 556, 188, "B"); bmp_printf(fntl, 564, 185, "%3d", 1 << flash_info.group_b_output ); bmp_printf(fnt, 624, 188, "C"); bmp_printf(fntl, 632, 185, "%3d", 1 << flash_info.group_c_output); bmp_fill(col_bg,486,212,212,6); } #endif }
static struct config *config_parse_line(const char *line) { int name_len = 0; int value_len = 0; static struct config _cfg; struct config * cfg = &_cfg; // Trim any leading whitespace int i = 0; while( line[i] && isspace( line[i] ) ) i++; // Copy the name to the name buffer while( line[i] && !isspace( line[i] ) && line[i] != '=' && name_len < MAX_NAME_LEN ) cfg->name[ name_len++ ] = line[i++]; if( name_len == MAX_NAME_LEN ) goto parse_error; // And nul terminate it cfg->name[ name_len ] = '\0'; // Skip any white space and = signs while( line[i] && isspace( line[i] ) ) i++; if( line[i++] != '=' ) goto parse_error; while( line[i] && isspace( line[i] ) ) i++; // Copy the value to the value buffer while( line[i] && value_len < MAX_VALUE_LEN ) cfg->value[ value_len++ ] = line[ i++ ]; // Back up to trim any white space while( value_len > 0 && isspace( cfg->value[ value_len-1 ] ) ) value_len--; // And nul terminate it cfg->value[ value_len ] = '\0'; DebugMsg( DM_MAGIC, 3, "%s: '%s' => '%s'", __func__, cfg->name, cfg->value ); return cfg; parse_error: DebugMsg( DM_MAGIC, 3, "%s: PARSE ERROR: len=%d,%d string='%s'", __func__, name_len, value_len, line ); bmp_printf(FONT_LARGE, 10, 150, "CONFIG PARSE ERROR"); bmp_printf(FONT_MED, 10, 200, "%s: PARSE ERROR:\nlen=%d,%d\nstring='%s'", __func__, name_len, value_len, line ); msleep(2000); //~ FreeMemory( cfg ); call("dumpf"); //~ malloc_error: return 0; }
static void dbg_memspy_update() { //int printed_elapsed=0; static int init_done = 0; if (!init_done) dbg_memspy_init(); init_done = 1; if (!dbg_memmirror) return; if (!dbg_memchanges) return; //if (!dbg_memlogged) return; int elapsed_time = _toc(); bmp_printf(FONT_MED, 50, 200, "[%d] ", elapsed_time); int i; int k=0; for (i = 0; i < mem_spy_len; i++) { int fnt = FONT_SMALL; unsigned int addr = dbg_memspy_get_addr(i); int oldval = dbg_memmirror[i]; int newval = MEMX(addr); if (oldval != newval) { dbg_memmirror[i] = newval; if (dbg_memchanges[i] < 1000000) dbg_memchanges[i]++; //dbg_memlogged[i]=0; fnt = FONT(FONT_SMALL,5, COLOR_BG); if (elapsed_time < mem_spy_start_time) dbg_memchanges[i] = 1000000; // so it will be ignored } if (mem_spy_bool && newval != 0 && newval != 1 && newval != -1) continue; if (mem_spy_value_lo && newval < mem_spy_value_lo) continue; if (mem_spy_value_hi && newval > mem_spy_value_hi) continue; if (mem_spy_count_lo && dbg_memchanges[i] < mem_spy_count_lo) continue; if (mem_spy_count_hi && dbg_memchanges[i] > mem_spy_count_hi) continue; int freq = dbg_memchanges[i] / elapsed_time; if (mem_spy_freq_lo && freq < mem_spy_freq_lo) continue; if (mem_spy_freq_hi && freq > mem_spy_freq_hi) continue; //if (dbg_memlogged[i]) return; //if (!printed_elapsed) { // debug_log("memspy: elapsed: %d sec ", elapsed_time); // printed_elapsed = 1; //} //debug_log("%8x:%2d:%8x", addr, dbg_memchanges[i], newval); //dbg_memlogged[i] = 1; //SleepTask(10); int x = 10 + 8 * 22 * (k % 2); int y = 10 + 12 * (k / 2); bmp_printf(fnt, x, y, "[%8x:%2d:%8x]", addr, dbg_memchanges[i], newval); k = (k + 1) % 120; } //printed_elapsed=0; //SleepTask(10); //for (i = 0; i < 10; i++) { // int x = 10 + 8 * 13 * (k % 3); // int y = 10 + 12 * (k / 3); // bmp_printf(FONT_SMALL, x, y, " "); // k = (k + 1) % 120; //} }
static int dng_show(char* filename) { uint32_t size; if( FIO_GetFileSize( filename, &size ) != 0 ) return 0; FILE* f = FIO_OpenFile(filename, O_RDONLY | O_SYNC); void* buf = 0; /* should be big enough for the header */ int header_maxsize = 65536; int* header = fio_malloc(header_maxsize); if (!header) return 0; int rc = FIO_ReadFile(f, header, header_maxsize); if( rc != header_maxsize ) goto err; if (header[0] != 0x002A4949 && header[1] != 0x00000008) { bmp_printf(FONT_MED, 0, 0, "Not a CHDK DNG"); goto err; } raw_info.width = 0; raw_info.height = 0; int strip_offset = 0; int off = 8; for (int ifd = 0; off; ifd++) off = tif_parse_ifd(ifd, (void*)header, off, &strip_offset); fio_free(header); header = 0; if (!strip_offset) goto err; if (!raw_info.width) goto err; if (!raw_info.height) goto err; int raw_size = raw_info.width * raw_info.height * 14/8; buf = fio_malloc(raw_size); if (!buf) goto err; FIO_SeekSkipFile(f, strip_offset, SEEK_SET); rc = FIO_ReadFile(f, buf, raw_size); if (rc != raw_size) goto err; FIO_CloseFile(f); f = 0; info_led_on(); /* fixme: this step is really slow */ reverse_bytes_order(buf, raw_size); info_led_off(); raw_info.buffer = buf; raw_set_geometry(raw_info.width, raw_info.height, raw_info.active_area.x1, raw_info.width - raw_info.active_area.x2, raw_info.active_area.y1, raw_info.height - raw_info.active_area.y2); raw_force_aspect_ratio_1to1(); vram_clear_lv(); raw_preview_fast_ex((void*)-1, (void*)-1, -1, -1, RAW_PREVIEW_COLOR_HALFRES); fio_free(buf); buf = 0; raw_set_dirty(); bmp_printf(FONT_MED, 600, 460, " %dx%d ", raw_info.jpeg.width, raw_info.jpeg.height); return 1; err: if (f) FIO_CloseFile(f); if (header) fio_free(header); if (buf) fio_free(buf); raw_set_dirty(); return 0; }
static void update_graph() { exposure last_expo; bool draw_label = 0; //bg rect bmp_fill(GRAPH_BG, 1, GRAPH_YOFF - GRAPH_MAX_PX - GRAPH_PADD, 720 - 2, GRAPH_MAX_PX + GRAPH_TEXT_PADD + GRAPH_PADD + font_med.height ); // current BV if(last_bv != INT_MIN){ int x = GRAPH_XOFF + (BV_MAX - last_bv) * GRAPH_XSIZE; draw_line(x - 1, GRAPH_YOFF - GRAPH_MAX_PX, x - 1, GRAPH_YOFF, IS_SEL(browse) ? COLOR_WHITE : COLOR_CYAN); draw_line(x + 1, GRAPH_YOFF - GRAPH_MAX_PX, x + 1, GRAPH_YOFF, IS_SEL(browse) ? COLOR_WHITE : COLOR_CYAN); } graph_draw: last_expo = (exposure){-1, -1, -1, -1}; for(int bv = BV_MAX; bv >= BV_MIN; bv -= (draw_label) ? 20 : GRAPH_STEP) { int x = GRAPH_XOFF + (BV_MAX - bv) * GRAPH_XSIZE; exposure expo = get_exposure(bv, 1); int ec_val = expo.ec; expo.ec = (GRAPH_MAX / 2) + expo.ec; if(!draw_label) { int x_last = x - GRAPH_XSIZE * GRAPH_STEP; // bg lines if(!(bv % 10))draw_line(x, GRAPH_YOFF - GRAPH_MAX_PX, x, GRAPH_YOFF, COLOR_BLACK); // sv curve GRAPH_DRAW_CURVE(sv, COLOR_LIGHT_BLUE); // av curve GRAPH_DRAW_CURVE(av, COLOR_GREEN2); // ec curve GRAPH_DRAW_CURVE(ec, (last_expo.ec - (GRAPH_MAX / 2) == 0 && ec_val == 0) ? COLOR_BLACK : COLOR_ORANGE); // tv curve GRAPH_DRAW_CURVE(tv, COLOR_RED); } else { // bv value { char bv_str[3]; snprintf(bv_str, sizeof(bv_str), "%d", ABS(bv / 10)); int center = strlen(bv_str) * font_med.width / 2; if(bv < 0) center += font_med.width; bmp_printf(GRAPH_FONT, x + 3 - center, GRAPH_YOFF + GRAPH_TEXT_PADD, "%d", bv / 10); } //do not print on the right edge of graph if(BV_MAX + bv <= 40) continue; // sv value if(expo.sv != last_expo.sv) { bmp_printf(GRAPH_FONT, x, GRAPH_Y_TEXT(expo.sv), "%d", raw2iso(SV2RAW(expo.sv))); } // av value if(expo.av != last_expo.av) { int ap = AV2STR(expo.av); bmp_printf(GRAPH_FONT, x, GRAPH_Y_TEXT(expo.av), "%d.%d", ap / 10, ap % 10); } // ec value if(expo.ec != last_expo.ec && ec_val) { bmp_printf(GRAPH_FONT, x, GRAPH_Y_TEXT(expo.ec), "%s%d.%d", FMT_FIXEDPOINT1S(ec_val)); } // tv value if(expo.tv != last_expo.tv) { bmp_printf(GRAPH_FONT, x, GRAPH_Y_TEXT(expo.tv), "%s", lens_format_shutter(TV2RAW(expo.tv))); } } last_expo = expo; } if(!draw_label) { draw_label = 1; goto graph_draw; } }
static void console_draw(int tiny) { int cbpos0 = mod((console_buffer_index / CONSOLE_W) * CONSOLE_W + CONSOLE_W, BUFSIZE); /* display last two lines that actually contain something (don't display the cursor-only line) */ if (tiny && console_buffer_index % CONSOLE_W == 0) cbpos0 -= CONSOLE_W; int skipped_lines = 0; int chopped_columns = 0; /* skip empty lines at the top */ for (int i = 0; i < CONSOLE_H; i++) { int cbpos = cbpos0 + i * CONSOLE_W; int empty = 1; for (int j = 0; j < CONSOLE_W; j++) if (CONSOLE_BUFFER(cbpos + j) != ' ') { empty = 0; break; } if (empty) skipped_lines++; else break; } if (skipped_lines == CONSOLE_H) // nothing to show return; if (tiny) skipped_lines = CONSOLE_H - 3; /* chop empty columns from the right */ for (int j = CONSOLE_W-1; j > 0; j--) { int empty = 1; for (int i = skipped_lines; i < CONSOLE_H; i++) if (CONSOLE_BUFFER(cbpos0 + i*CONSOLE_W + j) != ' ') { empty = 0; break; } if (empty) chopped_columns++; else break; } chopped_columns = MIN(chopped_columns, CONSOLE_W - (console_buffer_index % CONSOLE_W)); if (skipped_lines < 5) skipped_lines = 0; if (chopped_columns < 5) chopped_columns = 0; /* can we use large fonts? */ int can_use_large_font = (skipped_lines > 7 && chopped_columns > 25 && !tiny); /* top-left corner of "full" console (without lines/columns skipped) */ unsigned x0 = 720/2 - fontspec_font(CONSOLE_FONT)->width * CONSOLE_W/2; unsigned y0 = 480/2 - fontspec_font(CONSOLE_FONT)->height * CONSOLE_H/2; /* correct y to account for skipped lines */ int yc = y0; if (tiny) { yc = gui_menu_shown() || MENU_MODE ? 415 : y0; } else { yc = y0 + fontspec_font(CONSOLE_FONT)->height * skipped_lines; } if (can_use_large_font) yc -= (fontspec_font(FONT_LARGE)->height - fontspec_font(CONSOLE_FONT)->height) * (CONSOLE_H - skipped_lines); int fnt = FONT(can_use_large_font ? FONT_LARGE : CONSOLE_FONT,COLOR_WHITE, (lv || PLAY_OR_QR_MODE) ? COLOR_BG_DARK : COLOR_ALMOST_BLACK); int xa = (x0 & ~3) - 1; int ya = (yc-1); int w = fontspec_font(fnt)->width * (CONSOLE_W - chopped_columns) + 2; int h = fontspec_font(fnt)->height * (CONSOLE_H - skipped_lines) + 2; /* did the console shrink? if so, redraw Canon GUI around it */ static int prev_w = 0; static int prev_h = 0; if (w < prev_w || h < prev_h) { canon_gui_enable_front_buffer(1); // force a redraw prev_w = w; prev_h = h; //return; // better luck next time :) } else if (!tiny) /* fixme: prevent Canon code from drawing over the console (ugly) */ canon_gui_disable_front_buffer(); prev_w = w; prev_h = h; bmp_draw_rect(60, xa, ya, w, h); bmp_draw_rect(COLOR_BLACK, xa-1, ya-1, w+2, h+2); /* display each line */ int found_cursor = 0; for (int i = skipped_lines; i < CONSOLE_H; i++) { char buf[CONSOLE_W+1]; int cbpos = cbpos0 + i * CONSOLE_W; for (int j = 0; j < CONSOLE_W; j++) { // last character should be on last line => this ensures proper scrolling if (mod(cbpos+j, BUFSIZE) == mod(console_buffer_index, BUFSIZE)) // end of data { if (!found_cursor) { buf[j] = '_'; found_cursor = 1; continue; } } buf[j] = found_cursor ? ' ' : CONSOLE_BUFFER(cbpos+j); } buf[CONSOLE_W - chopped_columns] = 0; int y = yc + fontspec_font(fnt)->height * (i - skipped_lines); bmp_printf(fnt, x0, y, buf); } }
void console_show_status() { int fnt = FONT(CONSOLE_FONT,60, COLOR_BLACK); bmp_printf(fnt, 0, 480 - font_med.height, console_status_text); if (console_visible) bmp_printf(fnt, 720 - font_med.width * strlen(console_help_text), 480 - font_med.height, console_help_text); }
void lv_rec_start() { int yPos = 3; lv_rec_data_t data; lv_rec_save_data_t save_data; /* set all values to zero */ memset(&data, 0x00, sizeof(lv_rec_data_t)); memset(&save_data, 0x00, sizeof(lv_rec_save_data_t)); /* menu options */ data.options.frameSkip = lv_rec_frame_skip; data.options.rawMode = lv_rec_raw_mode; data.options.singleFile = lv_rec_single_file; data.options.linesToSkip = lv_rec_line_skip; /* this causes the function to hang!? */ if(data.options.rawMode) { //~ bmp_printf( FONT(FONT_MED, COLOR_WHITE, COLOR_BLACK), 30, 20 * yPos++, "Make sure you ran call('lv_save_raw')"); call("lv_save_raw", 1); msleep(200); raw_update_params(); } /* get maximum available memory */ bmp_printf( FONT(FONT_MED, COLOR_WHITE, COLOR_BLACK), 30, 20 * yPos++, "Allocating memory"); data.chunkData.memSuite = shoot_malloc_suite(0); if(!data.chunkData.memSuite) { bmp_printf( FONT(FONT_MED, COLOR_WHITE, COLOR_BLACK), 30, 20 * yPos++, "Failed to allocate memory"); return; } unsigned int allocatedMemory = lv_rec_get_memsize(data.chunkData.memSuite); bmp_printf( FONT(FONT_MED, COLOR_WHITE, COLOR_BLACK), 30, 20 * yPos++, "Allocated %d MiB", allocatedMemory/1024/1024); save_data.options = data.options; save_data.chunkData = data.chunkData; /* ensure the selected profile is applied, dont rely on menu painting to do this for us */ lv_rec_update_preset(&save_data); /* file sequence number */ int start_number = 0; /* set file pre/suffixes */ if(data.options.singleFile) { strcpy(save_data.filePrefix, "M"); } else { strcpy(save_data.filePrefix, "I"); } if(data.options.rawMode) { strcpy(save_data.fileSuffix, "RAW"); } else { strcpy(save_data.fileSuffix, "YUV"); } /* get first available file name */ for (start_number = 0 ; start_number < 1000; start_number++) { snprintf(save_data.fileName, sizeof(save_data.fileName), "%s%s%07d.%s", MODULE_CARD_DRIVE, save_data.filePrefix, start_number, save_data.fileSuffix); uint32_t size; if( FIO_GetFileSize( save_data.fileName, &size ) != 0 ) break; if (size == 0) break; } if(data.options.rawMode) { /* copy 8 bytes per transfer */ data.dmaFlags = 0x20001000; /* set block size for EDMAC and update cropping */ save_data.frameSize = (save_data.frameSizeReal + 4095) & (~4095); /* the data at bottom are trash remains caused by EDMAC block size, drop it */ save_data.bottomDrop = save_data.frameSize - save_data.frameSizeReal; /* mem copy connection */ data.dmaCopyChannel = 0x19; data.dmaCopyConn = 0x06; data.dmaSourceConn = 0x06; data.dmaFlags = 0; /* create a memory suite that consists of lv_save_raw raw buffer */ data.memCopySuite = CreateMemorySuite((void*)shamem_read(RAW_LV_EDMAC), save_data.frameSize, 0); PackMem_RegisterEDmacCompleteCBRForMemorySuite(data.dmaCopyChannel, &complete_cbr, 0); PackMem_RegisterEDmacPopCBRForMemorySuite(data.dmaCopyChannel, &pop_cbr, 0); } else { /* copy 2 byte per transfer */ data.dmaFlags = 0x20000000; /* read from YUV connection */ data.dmaSourceConn = 0x1B; /* no special treatment, save the exact size */ save_data.frameSize = save_data.frameSizeReal; save_data.bottomDrop = 0; } /* who wants to save more? */ data.maxFrames = 200000; data.dmaChannel = 0x11; data.maxFramesBufferable = allocatedMemory / save_data.frameSize; data.frameSize = save_data.frameSize; /* EDMAC callbacks */ PackMem_RegisterEDmacCompleteCBRForMemorySuite(data.dmaChannel, &complete_cbr, 1); PackMem_RegisterEDmacPopCBRForMemorySuite(data.dmaChannel, &pop_cbr, 1); /* this enables recording */ lv_rec_state = &data; bmp_printf( FONT(FONT_MED, COLOR_WHITE, COLOR_BLACK), 30, 20 * yPos++, "Ready, waiting for first frame"); int wait_loops = 0; int t0 = get_ms_clock_value(); while(!data.finished || (lv_rec_ring_mode && (data.capturedFrames > data.savedFrames))) { if(lv_rec_ring_mode) { if(data.capturedFrames > data.savedFrames) { if(data.options.singleFile) { if(!save_data.handle) { snprintf(save_data.fileName, sizeof(save_data.fileName), "%s%s%07d.%s", MODULE_CARD_DRIVE, save_data.filePrefix, start_number, save_data.fileSuffix); bmp_printf( FONT(FONT_MED, COLOR_WHITE, COLOR_BLACK), 30, 20 * (yPos+1), "Saving to '%s'", save_data.fileName); save_data.handle = FIO_CreateFileEx(save_data.fileName); save_data.handleWritten = 0; } if(save_data.handle) { /* save or skip, depending on skip counter */ save_data.handleWritten += lv_rec_save_frame(save_data.handle, &save_data, (data.savedFrames % data.options.frameSkip) != 0); } else { yPos++; bmp_printf( FONT(FONT_MED, COLOR_WHITE, COLOR_BLACK), 30, 20 * yPos++, "Failed to save file"); break; } /* when reaching 2GiB, create another file */ if(save_data.handleWritten > ((2UL * 1024UL) - 10UL) * 1024UL * 1024UL) { yPos++; bmp_printf( FONT(FONT_MED, COLOR_WHITE, COLOR_BLACK), 30, 20 * yPos++, "Creating next file"); FIO_CloseFile(save_data.handle); save_data.handle = NULL; lv_rec_update_suffix(&save_data); save_data.fileSeqNum++; } data.savedFrames++; } else { if((data.savedFrames % data.options.frameSkip) == 0) { snprintf(save_data.fileName, sizeof(save_data.fileName), "%s%s%07d.%s", MODULE_CARD_DRIVE, save_data.filePrefix, start_number + (data.savedFrames / data.options.frameSkip), save_data.fileSuffix); bmp_printf( FONT(FONT_MED, COLOR_WHITE, COLOR_BLACK), 30, 20 * (yPos+1), "Saving '%s'", save_data.fileName); save_data.handle = FIO_CreateFileEx(save_data.fileName); save_data.handleWritten = 0; if(save_data.handle) { save_data.handleWritten += lv_rec_save_frame(save_data.handle, &save_data, 0); save_data.frameCount = 1; lv_rec_save_footer(save_data.handle, &save_data); FIO_CloseFile(save_data.handle); save_data.handle = NULL; } else { yPos++; bmp_printf( FONT(FONT_MED, COLOR_WHITE, COLOR_BLACK), 30, 20 * yPos++, "Failed to save file"); break; } } else { /* do not save data, just skip buffers */ lv_rec_save_frame(save_data.handle, &save_data, 1); } data.savedFrames++; } /* reset timeout counter */ wait_loops = 0; } else { msleep(10); if(wait_loops++ > 25) { yPos++; bmp_printf( FONT(FONT_MED, COLOR_WHITE, COLOR_BLACK), 30, 20 * yPos++, "No more data, aborting."); lv_rec_state = NULL; PackMem_PopEDmacForMemorySuite(data.dmaChannel); data.finished = 1; } } } else { msleep(200); } int t1 = get_ms_clock_value(); int speed = (save_data.handleWritten / 1024) * 10 / (t1 - t0) * 1000 / 1024; // MB/s x10 bmp_printf( FONT(FONT_MED, COLOR_WHITE, COLOR_BLACK), 30, 20 * yPos, "%s, %d buffered, %d saved, %d.%d MB/s ", (data.finished?"Finished":(data.running?"Recording":"Wait.....")), data.capturedFrames - data.savedFrames, data.savedFrames / data.options.frameSkip, speed/10, speed%10 ); } yPos++; if(lv_rec_ring_mode) { if(data.options.singleFile) { save_data.frameCount = data.capturedFrames; lv_rec_save_footer(save_data.handle, &save_data); FIO_CloseFile(save_data.handle); } } else { bmp_printf( FONT(FONT_MED, COLOR_WHITE, COLOR_BLACK), 30, 20 * ++yPos, "Saving"); if(data.options.singleFile) { /* save one single file */ bmp_printf( FONT(FONT_MED, COLOR_WHITE, COLOR_BLACK), 30, 20 * ++yPos, "Saved: 0x%08X", exmem_save_buffer(data.chunkData.memSuite, "DATA.BIN")); } } bmp_printf( FONT(FONT_MED, COLOR_WHITE, COLOR_BLACK), 30, 20 * ++yPos, "Recording finished"); shoot_free_suite(data.chunkData.memSuite); /* the dummy suite that points to lv_save_raw buffer */ if(data.memCopySuite) { DeleteMemorySuite(data.memCopySuite); } }
void green_screen_step() { /**************************************************** * .. if Canon menu is ACTIVE - return immediately * ****************************************************/ if (!lv) { last_green_screen_state = 0; return; } /******************************** * Masses of auto variables. * ********************************/ // unsigned int Xs,Xe; // X_POSITION of Cropmark_start/_end //~ Xs = g_cropmark_x_start; // First Pix drawn on (and a multiple of 4) //~ Xe = g_cropmark_x_end; // First Pix not drawn on (multiple of 4) // unsigned int Vram_pixels = Xe - Xs; unsigned int vpix, lum1, lum2; // results from previous loop, used for display static int total_luma = 0; static int highest_luma = 0; static int lowest_luma = 256; static int total_pixels = 0; // results for current loop, being updated (will be used at next loop) unsigned int total_luma_tmp = 0; unsigned int highest_luma_tmp = 0; unsigned int lowest_luma_tmp = 256; unsigned int total_pixels_tmp = 0; /**************************************************************** * Set address pointers up to first line in Vram * ****************************************************************/ uint32_t* lv = (uint32_t *) get_yuv422_vram()->vram; if (!lv) return; uint8_t* bm = bmp_vram(); // uint16_t* bm16 = (uint16_t *) bmp_vram(); uint8_t* bm_mirror = (uint8_t *) get_bvram_mirror(); unsigned int average_luma = total_luma / total_pixels; unsigned int high_delta = highest_luma - average_luma; // used to work out colour scale unsigned int low_delta = average_luma - lowest_luma; // colour scale for darker pixels /****************************************************************** * Go through Crop area. Note highest and lowest luma, average * ******************************************************************/ int high_delta_factor = 1024 / high_delta; // replace division with multiplication int low_delta_factor = 1024 / low_delta; for(int y = os.y0 + os.off_169; y < os.y_max - os.off_169; y += 2 ) { uint32_t * const v_row = (uint32_t*)( lv + BM2LV_R(y) ); // 2 pixels uint16_t * const b_row = (uint16_t*)( bm + BM_R(y) ); // 2 pixels uint16_t * const m_row = (uint16_t*)( bm_mirror + BM_R(y) ); // 2 pixels uint8_t* lvp; // that's a moving pointer through lv vram uint16_t* bp; // through bmp vram uint16_t* mp; // through mirror for (int x = os.x0; x < os.x_max; x += 2) { lvp = (uint8_t *) (v_row + BM2LV_X(x)/2); lvp++; bp = b_row + x/2; mp = m_row + x/2; /******************************************** * Get 4 bytes of vram (ie two vram Pixels) * ********************************************/ // vpix = [LSB=pix on left] u y1 v y2 [MSB=pix on right] vpix = lv[BM2LV(x,y)/4]; total_pixels_tmp += 2; lum1 = ( vpix & 0x0000FF00 ) >> 8; // y1 lum2 = ( vpix & 0xFF000000 ) >> 24; // y2 /************************* * Update total luma * *************************/ total_luma_tmp += lum1 + lum2; /************************* * new Maximum ? * *************************/ if (lum1 > highest_luma_tmp) highest_luma_tmp = lum1; if (lum2 > highest_luma_tmp) highest_luma_tmp = lum2; /************************* * new Miniumum ? * *************************/ if (lum1 < lowest_luma_tmp) lowest_luma_tmp = lum1; if (lum2 < lowest_luma_tmp) lowest_luma_tmp = lum2; /********************************************************* * Initialise writeback colour of overlay to 0 for LUM1 * *********************************************************/ unsigned int lum = (lum1 + lum2) / 2; unsigned int col = 0; /************************************** * LUM1 Higher than average luma * **************************************/ if (lum > average_luma) { col = ((lum-average_luma)*12) * high_delta_factor / 1024; if (col > 12) col=12; col = 128 + (col+2) * 8; } else if (lum < average_luma) { /************************************** * LUM1 Lower than average luma * **************************************/ col = ((average_luma-lum)*12) * low_delta_factor / 1024; if (col > 12) col=12; col = 128 - (col+2) * 8; } if (col) col = ((col * 41) >> 8) + 38; unsigned int c = col | (col << 8); #define BP (*bp) #define MP (*mp) #define BN (*(bp + BMPPITCH/2)) #define MN (*(mp + BMPPITCH/2)) if (BP != 0 && BP != MP) { continue; } if (BN != 0 && BN != MN) { continue; } if ((MP & 0x80808080) || (MN & 0x80808080)) continue; MP = BP = c; MN = BN = c; #undef BP #undef MP #undef BN #undef MN } } // end of (y loop) /********************************** * commit statistics for next loop * **********************************/ total_luma = total_luma_tmp; highest_luma = highest_luma_tmp; lowest_luma = lowest_luma_tmp; total_pixels = total_pixels_tmp; /********************************** * Display average, min and max * **********************************/ bmp_printf( FONT(FONT_MED, COLOR_WHITE, COLOR_BLACK), os.x0 + os.x_ex/2 - font_med.width*7, os.y_max - os.off_169 - 47, "Average = %03d",average_luma); bmp_printf( FONT(FONT_MED,COLOR_CYAN, COLOR_BLACK), os.x0, os.y_max - os.off_169 - 47, "MIN = %03d",lowest_luma); bmp_printf( FONT(FONT_MED,COLOR_YELLOW, COLOR_BLACK), os.x_max - font_med.width*9, os.y_max - os.off_169 - 47, "%03d = MAX",highest_luma); bmp_printf( FONT(FONT_MED,COLOR_WHITE, COLOR_BLACK), os.x0 + os.x_ex/2 - font_med.width*7, os.y_max - os.off_169 - 27, "Accuracy=%03d%%",((255-(highest_luma-lowest_luma))*99 )/255 ); bmp_printf( FONT(FONT_MED,COLOR_CYAN, COLOR_BLACK), os.x0, os.y_max - os.off_169 - 27, "delta %03d", COERCE(average_luma - lowest_luma, 0, 255)); bmp_printf( FONT(FONT_MED, COLOR_YELLOW, COLOR_BLACK), os.x_max - font_med.width*9, os.y_max - os.off_169 - 27, "%03d delta", COERCE(highest_luma - average_luma, 0, 255)); msleep(10); // don't kill the battery :) } /* end of green_screen_step() */
void display_lens_hyperfocal() { unsigned menu_font = MENU_FONT; unsigned font = FONT(FONT_MED, FONT_FG(menu_font), FONT_BG(menu_font)); unsigned height = fontspec_height( font ); int x = 10; int y = 315; y += 10; y += height; if (!lens_info.name[0]) { y += height; bmp_printf( font, x, y, "Lens: manual (without chip)." ); return; } bmp_printf( font, x, y, "Lens: %s, %dmm f/%d.%d", lens_info.name, lens_info.focal_len, lens_info.aperture / 10, lens_info.aperture % 10 ); if (!lv || !lens_info.focus_dist) { y += height; bmp_printf( font, x, y, "Hyperfocal: %s", lens_info.hyperfocal ? lens_format_dist( lens_info.hyperfocal ) : "unknown, go to LiveView to get focal length" ); y += height; bmp_printf( font, x, y, "Your lens did not report focus distance" ); return; } y += height; bmp_printf( font, x, y, "Focus dist: %s", lens_info.focus_dist == 0xFFFF ? " Infty" : lens_format_dist( lens_info.focus_dist * 10 ) ); y += height; bmp_printf( font, x, y, "Hyperfocal: %s", lens_format_dist( lens_info.hyperfocal ) ); x += 300; y -= height; bmp_printf( font, x, y, "DOF Near: %s", lens_format_dist( lens_info.dof_near ) ); y += height; bmp_printf( font, x, y, "DOF Far: %s", lens_info.dof_far >= 1000*1000 ? " Infty" : lens_format_dist( lens_info.dof_far ) ); }
static MENU_UPDATE_FUNC(mrc_dump_update_all) { if (!info->can_custom_draw) return; info->custom_drawing = CUSTOM_DRAW_THIS_MENU; bmp_fill(COLOR_BLACK, 0, 0, 720, 480); int skip = (mrc_dump_page - 1) * (450 / font_large.height); int k = 0; int y = 0; int printed = 0; for(int pos = 0; pos < COUNT(cp_regs); pos++) { char *str = cp_regs[pos].desc; if(!str) { break; } k++; if (k <= skip) { continue; } mrc_cp = cp_regs[pos].cp; mrc_crn = cp_regs[pos].crn; mrc_op1 = cp_regs[pos].op1; mrc_crm = cp_regs[pos].crm; mrc_op2 = cp_regs[pos].op2; mrc_dump_process(); printed = 1; if(k%2) { bmp_fill(COLOR_GRAY(10), 0, y, 720, font_large.height); } int yasm = y + font_small.height; bmp_printf( SHADOW_FONT(FONT_SMALL), 10, y, "%s", str ); bmp_printf( SHADOW_FONT(FONT_MED), 10, yasm, "MRC p%d, %d, Rd, c%d, c%d, %d", mrc_cp, mrc_op1, mrc_crn, mrc_crm, mrc_op2 ); bmp_printf( SHADOW_FONT(FONT(FONT_LARGE, COLOR_YELLOW, COLOR_BLACK)), 720 - 8*font_large.width, y, "%8x", mrc_value ); y += font_large.height; if (y > 440) { bmp_printf(FONT(FONT_MED, COLOR_CYAN, COLOR_BLACK), 710 - 7*font_med.width, y, "more..."); break; } } if (!printed) { mrc_dump_page = 1; } }