Added touchscreen calibration from NVRAM (thanks @wolfvak)

This commit is contained in:
d0k3 2019-04-26 02:01:08 +02:00
parent 36c03e578c
commit 54caa3588e
4 changed files with 71 additions and 23 deletions

View File

@ -1,15 +1,34 @@
#include "touchcal.h" #include "touchcal.h"
#include "ui.h" #include "ui.h"
#include "hid.h" #include "hid.h"
#include "crc16.h"
#include "spiflash.h"
bool ShowCalibrationDialog(void) static const HID_CalibrationData default_calib = {
.screen_x = 0,
.screen_y = 0,
.ts_raw = 0
// ^ wrong: in my console it's 0x780086
// but this is very much console dependent
// so it's better to go with a sane default
};
static bool SetCalibrationDefaults(void)
{
// Hardcoding this isn't ideal but it's better than
// leaving the system without any state to work with
return HID_SetCalibrationData(&default_calib, 1, SCREEN_WIDTH_BOT, SCREEN_HEIGHT);
}
bool ShowTouchCalibrationDialog(void)
{ {
static const u32 dot_positions[][2] = { static const u32 dot_positions[][2] = {
{16, 16}, {16, 16},
{320 - 16, 240 - 16}, {SCREEN_WIDTH_BOT - 16, SCREEN_HEIGHT - 16},
{16, 240 - 16}, {16, SCREEN_HEIGHT - 16},
{320 - 16, 16}, {SCREEN_WIDTH_BOT - 16, 16},
}; };
HID_CalibrationData calibrations[countof(dot_positions)]; HID_CalibrationData calibrations[countof(dot_positions)];
@ -23,6 +42,9 @@ bool ShowCalibrationDialog(void)
DrawStringCenter(BOT_SCREEN, COLOR_STD_FONT, COLOR_STD_BG, DrawStringCenter(BOT_SCREEN, COLOR_STD_FONT, COLOR_STD_BG,
"Touch the red crosshairs to\ncalibrate your touchscreen.\n \nUse the stylus for best\nresults!"); "Touch the red crosshairs to\ncalibrate your touchscreen.\n \nUse the stylus for best\nresults!");
// set calibration defaults
SetCalibrationDefaults();
// actual calibration // actual calibration
for (u32 current_dot = 0; current_dot < countof(dot_positions); current_dot++) { for (u32 current_dot = 0; current_dot < countof(dot_positions); current_dot++) {
// draw four crosshairs // draw four crosshairs
@ -48,7 +70,7 @@ bool ShowCalibrationDialog(void)
} }
} }
return HID_SetCalibrationData(calibrations, countof(dot_positions), 320, 240); return HID_SetCalibrationData(calibrations, countof(dot_positions), SCREEN_WIDTH_BOT, SCREEN_HEIGHT);
} }
void ShowTouchPlayground(void) void ShowTouchPlayground(void)
@ -65,12 +87,49 @@ void ShowTouchPlayground(void)
while (pressed & BUTTON_TOUCH) { while (pressed & BUTTON_TOUCH) {
u16 tx, ty; u16 tx, ty;
HID_ReadTouchState(&tx, &ty); HID_ReadTouchState(&tx, &ty);
if (tx < 320 && ty < 240) if (tx < SCREEN_WIDTH_BOT && ty < SCREEN_HEIGHT)
DrawPixel(BOT_SCREEN, tx, ty, COLOR_BRIGHTYELLOW); DrawPixel(BOT_SCREEN, tx, ty, COLOR_BRIGHTYELLOW);
DrawStringF(BOT_SCREEN, 16, 16, COLOR_STD_FONT, COLOR_STD_BG, DrawStringF(BOT_SCREEN, 16, 16, COLOR_STD_FONT, COLOR_STD_BG,
"Current touchscreen coordinates: %3.3d, %3.3d", tx, ty); "Current touchscreen coordinates: %3.3d, %3.3d", tx, ty);
pressed = HID_ReadState(); pressed = HID_ReadState();
} }
} }
}
bool CalibrateTouchFromFlash(void) {
HID_CalibrationData data[2];
// set calibration defaults
SetCalibrationDefaults();
// check SPIflash status
if (!spiflash_get_status())
return false;
// check NVRAM console ID
u32 console_id = 0;
spiflash_read(0x001C, 4, (u8*)&console_id);
if (((console_id >> 8) & 0xFF) != 0x57)
return false; // not a 3DS
// read and check DS fw user settings
// see: https://problemkaputt.de/gbatek.htm#dsfirmwareusersettings
u32 fw_usercfg_buf[0x100 / 0x4];
u8* fw_usercfg = (u8*) fw_usercfg_buf;
spiflash_read(0x1FE00, 0x100, fw_usercfg);
if (getle16(fw_usercfg + 0x72) != crc16_quick(fw_usercfg, 0x70)) {
ShowPrompt(false, "ugh");
return false;
}
// get touchscreen calibration data from user settings
u8 *ts_data = fw_usercfg + 0x58;
for (int i = 0; i < 2; i++) {
int base = i * 6;
data[i].ts_raw = ts_data[base + 1] << 24 | ts_data[base + 0] << 16 | ts_data[base + 3] << 8 | ts_data[base + 2];
data[i].screen_x = (((int)ts_data[base + 4]) * SCREEN_WIDTH_BOT) / 256;
data[i].screen_y = (((int)ts_data[base + 5]) * SCREEN_HEIGHT) / 192;
}
return HID_SetCalibrationData(data, 2, SCREEN_WIDTH_BOT, SCREEN_HEIGHT);
} }

View File

@ -2,5 +2,6 @@
#include "common.h" #include "common.h"
bool ShowCalibrationDialog(void); bool ShowTouchCalibrationDialog(void);
void ShowTouchPlayground(void); void ShowTouchPlayground(void);
bool CalibrateTouchFromFlash(void);

View File

@ -2049,6 +2049,7 @@ u32 GodMode(int entrypoint) {
AutoEmuNandBase(true); AutoEmuNandBase(true);
InitNandCrypto(entrypoint != ENTRY_B9S); InitNandCrypto(entrypoint != ENTRY_B9S);
InitExtFS(); InitExtFS();
CalibrateTouchFromFlash(); // !!! this may need some further checking
// custom font handling // custom font handling
if (CheckSupportFile("font.pbm")) { if (CheckSupportFile("font.pbm")) {
@ -2537,7 +2538,7 @@ u32 GodMode(int entrypoint) {
break; break;
} }
} else if (user_select == calib) { } else if (user_select == calib) {
ShowPrompt(false, "Touchscreen calibration %s!", (ShowCalibrationDialog()) ? "success" : "failed"); ShowPrompt(false, "Touchscreen calibration %s!", (ShowTouchCalibrationDialog()) ? "success" : "failed");
} else if (user_select == playground) { } else if (user_select == playground) {
ShowTouchPlayground(); ShowTouchPlayground();
} else if (user_select == payloads) { } else if (user_select == payloads) {
@ -2599,6 +2600,7 @@ u32 ScriptRunner(int entrypoint) {
AutoEmuNandBase(true); AutoEmuNandBase(true);
InitNandCrypto(entrypoint != ENTRY_B9S); InitNandCrypto(entrypoint != ENTRY_B9S);
InitExtFS(); InitExtFS();
CalibrateTouchFromFlash(); // !!! this may need some further checking
while (CheckButton(BOOTPAUSE_KEY)); // don't continue while these keys are held while (CheckButton(BOOTPAUSE_KEY)); // don't continue while these keys are held
while (timer_msec( timer ) < 500); // show splash for at least 0.5 sec while (timer_msec( timer ) < 500); // show splash for at least 0.5 sec

View File

@ -1,22 +1,12 @@
#include "godmode.h" #include "godmode.h"
#include "power.h" #include "power.h"
#include "timer.h"
#include "pxi.h" #include "pxi.h"
#include "i2c.h"
#include "arm.h" #include "arm.h"
#include "shmem.h" #include "shmem.h"
#include "hid.h" #include "hid.h"
static const HID_CalibrationData default_calib = {
.screen_x = 0,
.screen_y = 0,
.ts_raw = 0
// ^ wrong: in my console it's 0x780086
// but this is very much console dependent
// so it's better to go with a sane default
};
void main(int argc, char** argv, int entrypoint) void main(int argc, char** argv, int entrypoint)
{ {
@ -33,10 +23,6 @@ void main(int argc, char** argv, int entrypoint)
// stored in the thread ID register in the ARM9 // stored in the thread ID register in the ARM9
ARM_InitSHMEM(); ARM_InitSHMEM();
// Hardcoding this isn't ideal but it's better than
// leaving the system without any state to work with
HID_SetCalibrationData(&default_calib, 1, 320, 240);
#ifdef SCRIPT_RUNNER #ifdef SCRIPT_RUNNER
// Run the script runner // Run the script runner
if (ScriptRunner(entrypoint) == GODMODE_EXIT_REBOOT) if (ScriptRunner(entrypoint) == GODMODE_EXIT_REBOOT)