https://bitbucket.org/hudson/magic-lantern
Raw File
Tip revision: aa78bfa234aa950f9a171902d52b598b46fc4fba authored by alex@thinkpad on 21 June 2018, 06:19:07 UTC
Close branch mlv-snd-merge (see PR #578)
Tip revision: aa78bfa
cartridge.c
/** 
 * Cartridge hooks (used for HDR video).
 * 
 * If you use this file, don't use fps.c (use fps-engio.c instead).
 * 
 * Credits goto g3gg0
 **/

#include "math.h"
#include "dryos.h"
#include "bmp.h"
#include "property.h"
#include "menu.h"
#include "lens.h"
#include "config.h"

#ifdef CONFIG_600D
#define CARTIRIDGE_CALL_TABLE 0x8AAC
#endif
#ifdef CONFIG_60D
#define CARTIRIDGE_CALL_TABLE 0x26490
#endif
#ifdef CONFIG_1100D
#define CARTIRIDGE_CALL_TABLE 0x8B24
#endif

#define HOOK_TABLE_FUNCTION(table,position,new,old) \
    old = (void*)((unsigned int*)table)[position];\
    ((unsigned int*)table)[position] = (unsigned int)new;\

#define UNHOOK_TABLE_FUNCTION(table,position,old) \
    ((unsigned int*)table)[position] = (unsigned int)old;\

#define IS_TABLE_FUNCTION_HOOKED(table,position,new) \
    (((unsigned int*)table)[position] == (unsigned int)new) \

#define REDIRECT_BUFFER(address,buffer) \
    memcpy(buffer, (unsigned char*)(*((unsigned int *)(address))), sizeof(buffer));\
    *((unsigned int *)(address)) = (unsigned int)buffer;\

static char cartridge_table[0xF4];
static void (*cartridge_AfStopPathReal)(void *this) = NULL;

static void cartridge_AfStopPath(void *this)
{
    /* change ISO for HDR movie (will only work if HDR is enabled) */
    hdr_step();

    /* call hooked function */
    cartridge_AfStopPathReal(this);
}

// Q: what happes if this is called when Canon firmware flips the resolution?
static void update_cartridge_table()
{
    extern int hdrv_enabled;
    if (hdrv_enabled)
    {
        // cartridge call table is sometimes overriden by Canon firmware
        // so this function polls the status periodically (and updates it if needed)
        if (!is_cartridge_table_overridden())
        {
            /* first clone the cartridge call table */
            REDIRECT_BUFFER(CARTIRIDGE_CALL_TABLE, cartridge_table);

            /* now hook the function Af_StopPath in cloned cartridge_table */
            HOOK_TABLE_FUNCTION(cartridge_table, 0x39, cartridge_AfStopPath, cartridge_AfStopPathReal);
            //~ beep();
            
            lens_display_set_dirty();
       }
    }
    else
    {
        if (is_cartridge_table_overridden() && cartridge_AfStopPathReal)
        {
            UNHOOK_TABLE_FUNCTION(cartridge_table, 0x39, cartridge_AfStopPathReal);
            cartridge_AfStopPathReal = NULL;
            //~ beep();

            lens_display_set_dirty();
        }
    }
}

int is_cartridge_table_overridden()
{
    return MEM(CARTIRIDGE_CALL_TABLE) == (int)cartridge_table &&
        IS_TABLE_FUNCTION_HOOKED(cartridge_table, 0x39, cartridge_AfStopPath);
}


static void cartridge_task()
{
    TASK_LOOP
    {
        if (lv)
        {
            update_cartridge_table();
        }
        msleep(200);
    }
}

TASK_CREATE("cartridge_task", cartridge_task, 0, 0x1d, 0x1000 );
back to top