Well, this is weird...
I am intercepting the display refresh using the traditional method (cache hacks are scheduled for next version):
TransferScreen = my_TransferScreen;
And my_TransferScreen is just this piece of code:
int my_TransferScreen(int r0, int r1, int r2, int r3, int a, int b, int c, int d) {
display_overlay((uint8_t*)(r3 + 0x78));
return TransferNormalScreen(r0, r1, r2, r3, a, b, c, d);
}
Now, the fun part is at display_overlay:
void display_overlay(uint8_t *vram_address) {
char buffer[LP_MAX_WORD];
if (FLAG_GUI_MODE == GUIMODE_OLC && AE_IS_CREATIVE(DPData.ae)) {
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';
}
}
}
With that code, bad things happen: I cannot take more than a couple dozen photographs before the camera locks. If I just comment out the first line (where TransferScreen is intercepted), then everything seems to work nicely; so far so good, problem seems to be here.
I suspected we could be writing to the display in a bad moment, so I added some code, at the end of display_overlay, but inside the "if (FLAG_GUI_MODE == GUIMODE_OLC && AE_IS_CREATIVE(DPData.ae))" condition, to check whether the display was off, and make the camera emit a beep in that case (notice that the display is checked after writing to it, we are always writing to the display).
Well, guess what? Yes, I hear the accusing beep now and then, but one hundred photographs later the camera hasn't failed once. So, adding some innocent code inside display_overlay seems to fix the issue, but I haven't the slightest idea of why...