mirror of
https://github.com/spicyjpeg/573in1.git
synced 2025-02-02 12:37:19 +01:00
Change back button combo, update readme, misc. cleanups
This commit is contained in:
parent
3e84285837
commit
fa7beb023e
@ -73,11 +73,13 @@ target_compile_definitions(
|
|||||||
cart_tool PRIVATE
|
cart_tool PRIVATE
|
||||||
VERSION="${PROJECT_VERSION}"
|
VERSION="${PROJECT_VERSION}"
|
||||||
$<IF:$<CONFIG:Debug>,
|
$<IF:$<CONFIG:Debug>,
|
||||||
|
ENABLE_CART_MENU=1
|
||||||
ENABLE_DUMMY_DRIVER=1
|
ENABLE_DUMMY_DRIVER=1
|
||||||
ENABLE_I2C_LOGGING=1
|
ENABLE_I2C_LOGGING=1
|
||||||
ENABLE_PS1_CONTROLLER=1
|
ENABLE_PS1_CONTROLLER=1
|
||||||
,
|
,
|
||||||
#ENABLE_ARGV=1
|
#ENABLE_ARGV=1
|
||||||
|
ENABLE_CART_MENU=1
|
||||||
ENABLE_PS1_CONTROLLER=1
|
ENABLE_PS1_CONTROLLER=1
|
||||||
>
|
>
|
||||||
)
|
)
|
||||||
|
@ -1,10 +1,22 @@
|
|||||||
Konami System 573 security cartridge tool
|
Konami System 573 security cartridge tool
|
||||||
|
|
||||||
|
# Credits
|
||||||
|
|
||||||
|
Lead developer: spicyjpeg
|
||||||
|
Cartridge database: smf
|
||||||
|
Testing: Naoki Saito
|
||||||
|
|
||||||
|
# Disclaimer
|
||||||
|
|
||||||
|
This tool is experimental and provided with no warranty whatsoever. It is not
|
||||||
|
guaranteed to work and improper usage can PERMANENTLY BRICK your System 573
|
||||||
|
security cartridges. Use this tool at your own risk.
|
||||||
|
|
||||||
|
# License
|
||||||
|
|
||||||
(C) 2022-2023 spicyjpeg
|
(C) 2022-2023 spicyjpeg
|
||||||
|
|
||||||
WARNING: This tool is experimental and provided with no warranty whatsoever. It
|
TODO: add a license
|
||||||
is not guaranteed to work and improper usage can PERMANENTLY BRICK your System
|
|
||||||
573 security cartridges. Use this tool at your own risk.
|
|
||||||
|
|
||||||
# Third-party licenses
|
# Third-party licenses
|
||||||
|
|
||||||
@ -101,11 +113,9 @@ the Software without restriction, including without limitation the rights to
|
|||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
subject to the following conditions:
|
subject to the following conditions:
|
||||||
|
- The above copyright notice and this permission notice shall be included in
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
all copies or substantial portions of the Software.
|
||||||
|
- The Software is provided "as is", without warranty of any kind, express or
|
||||||
* The Software is provided "as is", without warranty of any kind, express or
|
|
||||||
implied, including but not limited to the warranties of merchantability,
|
implied, including but not limited to the warranties of merchantability,
|
||||||
fitness for a particular purpose and noninfringement. In no event shall the
|
fitness for a particular purpose and noninfringement. In no event shall the
|
||||||
authors or copyright holders be liable for any claim, damages or other
|
authors or copyright holders be liable for any claim, damages or other
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
"App": {
|
"App": {
|
||||||
"cartDetectWorker": {
|
"cartDetectWorker": {
|
||||||
"readDigitalIO": "Retrieving digital I/O board ID...",
|
"readDigitalIO": "Retrieving digital I/O board ID...",
|
||||||
"identifyCart": "Identifying security cartridge...",
|
|
||||||
"readCart": "Reading security cartridge...",
|
"readCart": "Reading security cartridge...",
|
||||||
"identifyGame": "Attempting to identify game..."
|
"identifyGame": "Attempting to identify game..."
|
||||||
},
|
},
|
||||||
@ -50,7 +49,8 @@
|
|||||||
"atapiEjectWorker": {
|
"atapiEjectWorker": {
|
||||||
"eject": "Sending eject command...",
|
"eject": "Sending eject command...",
|
||||||
"success": "The drive's tray has been opened.\n\nYou may safely remove or replace the disc and close the tray. All data has been loaded into RAM and the tool will keep running until the 573 is turned off.",
|
"success": "The drive's tray has been opened.\n\nYou may safely remove or replace the disc and close the tray. All data has been loaded into RAM and the tool will keep running until the 573 is turned off.",
|
||||||
"error": "Failed to open the drive's tray. Your drive might be incompatible with the ATAPI driver used by this tool.\n\nPress the Test button to view debug logs."
|
"atapiError": "The drive currently configured as primary on the IDE bus is not an ATAPI CD-ROM drive and does not support ejecting.\n\nPress the Test button to view debug logs.",
|
||||||
|
"ejectError": "Failed to open the drive's tray. Your drive might be incompatible with the ATAPI driver used by this tool.\n\nPress the Test button to view debug logs."
|
||||||
},
|
},
|
||||||
"rebootWorker": {
|
"rebootWorker": {
|
||||||
"reboot": "Rebooting system..."
|
"reboot": "Rebooting system..."
|
||||||
@ -71,7 +71,7 @@
|
|||||||
|
|
||||||
"CartActionsScreen": {
|
"CartActionsScreen": {
|
||||||
"title": "{CART_ICON} Cartridge options",
|
"title": "{CART_ICON} Cartridge options",
|
||||||
"itemPrompt": "{RIGHT_ARROW} Press {START_BUTTON} to select, hold {LEFT_BUTTON} + {RIGHT_BUTTON} to go back",
|
"itemPrompt": "{RIGHT_ARROW} Press {START_BUTTON} to select, hold {LEFT_BUTTON}{RIGHT_BUTTON} + {START_BUTTON} to go back",
|
||||||
|
|
||||||
"qrDump": {
|
"qrDump": {
|
||||||
"name": "Dump cartridge as QR code",
|
"name": "Dump cartridge as QR code",
|
||||||
@ -157,9 +157,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"prompt": {
|
"prompt": {
|
||||||
"locked": "Press {START_BUTTON} to unlock the cartridge, hold {LEFT_BUTTON} + {RIGHT_BUTTON} to go back.",
|
"locked": "Press {START_BUTTON} to unlock, hold {LEFT_BUTTON}{RIGHT_BUTTON} + {START_BUTTON} to go back.",
|
||||||
"unlocked": "Press {START_BUTTON} to continue, hold {LEFT_BUTTON} + {RIGHT_BUTTON} to go back.",
|
"unlocked": "Press {START_BUTTON} to continue, hold {LEFT_BUTTON}{RIGHT_BUTTON} + {START_BUTTON} to go back.",
|
||||||
"error": "Hold {LEFT_BUTTON} + {RIGHT_BUTTON} to go back."
|
"error": "Hold {LEFT_BUTTON}{RIGHT_BUTTON} + {START_BUTTON} to go back."
|
||||||
},
|
},
|
||||||
|
|
||||||
"x76f041": {
|
"x76f041": {
|
||||||
@ -245,7 +245,7 @@
|
|||||||
"ReflashGameScreen": {
|
"ReflashGameScreen": {
|
||||||
"title": "{CART_ICON} Select game to convert cartridge to",
|
"title": "{CART_ICON} Select game to convert cartridge to",
|
||||||
"prompt": "Make sure you select the correct region. Note that cartridges can only be converted for use with games that accept the same cartridge type.",
|
"prompt": "Make sure you select the correct region. Note that cartridges can only be converted for use with games that accept the same cartridge type.",
|
||||||
"itemPrompt": "{RIGHT_ARROW} Press {START_BUTTON} to select, hold {LEFT_BUTTON} + {RIGHT_BUTTON} to go back"
|
"itemPrompt": "{RIGHT_ARROW} Press {START_BUTTON} to select, hold {LEFT_BUTTON}{RIGHT_BUTTON} + {START_BUTTON} to go back"
|
||||||
},
|
},
|
||||||
|
|
||||||
"SystemIDEntryScreen": {
|
"SystemIDEntryScreen": {
|
||||||
@ -263,7 +263,7 @@
|
|||||||
"UnlockKeyScreen": {
|
"UnlockKeyScreen": {
|
||||||
"title": "{CART_ICON} Select unlocking key",
|
"title": "{CART_ICON} Select unlocking key",
|
||||||
"prompt": "If the cartridge has been converted before, select the game it was last converted to. If it is currently blank, select 00-00-00-00-00-00-00-00.",
|
"prompt": "If the cartridge has been converted before, select the game it was last converted to. If it is currently blank, select 00-00-00-00-00-00-00-00.",
|
||||||
"itemPrompt": "{RIGHT_ARROW} Press {START_BUTTON} to select, hold {LEFT_BUTTON} + {RIGHT_BUTTON} to go back",
|
"itemPrompt": "{RIGHT_ARROW} Press {START_BUTTON} to select, hold {LEFT_BUTTON}{RIGHT_BUTTON} + {START_BUTTON} to go back",
|
||||||
|
|
||||||
"autoUnlock": "Use key from identified game (recommended)",
|
"autoUnlock": "Use key from identified game (recommended)",
|
||||||
"useCustomKey": "Enter key manually...",
|
"useCustomKey": "Enter key manually...",
|
||||||
|
@ -1,16 +1,27 @@
|
|||||||
|
|
||||||
Konami System 573 security cartridge reset tool
|
Konami System 573 security cartridge tool
|
||||||
===============================================
|
=========================================
|
||||||
|
|
||||||
Version ${PROJECT_VERSION}
|
Release ${PROJECT_VERSION}
|
||||||
|
|
||||||
Use this disc by simply putting it into your 573; make sure DIP switch 4 (the
|
# Usage
|
||||||
rightmost one) is off. Remember to insert the cartridge you want to reset or
|
|
||||||
dump prior to turning on the system.
|
Use this disc by simply inserting it into your System 573 and rebooting. Ensure
|
||||||
|
DIP switch 4 (the rightmost one) is off in order to force the 573 to boot from
|
||||||
|
the CD-ROM drive rather than the internal flash memory. Remember to insert the
|
||||||
|
cartridge you want to reset, reflash or dump prior to turning on the system.
|
||||||
|
|
||||||
|
# Credits
|
||||||
|
|
||||||
|
Lead developer: spicyjpeg
|
||||||
|
Cartridge database: smf
|
||||||
|
Testing: Naoki Saito
|
||||||
|
|
||||||
|
# Disclaimer
|
||||||
|
|
||||||
|
This tool is experimental and provided with no warranty whatsoever. It is not
|
||||||
|
guaranteed to work and improper usage can PERMANENTLY BRICK your System 573
|
||||||
|
security cartridges. Use this tool at your own risk.
|
||||||
|
|
||||||
More information and source code are available at:
|
More information and source code are available at:
|
||||||
${PROJECT_HOMEPAGE_URL}
|
${PROJECT_HOMEPAGE_URL}
|
||||||
|
|
||||||
WARNING: This tool is experimental and provided with no warranty whatsoever. It
|
|
||||||
is not guaranteed to work and improper usage can PERMANENTLY BRICK your System
|
|
||||||
573 security cartridges. Use this tool at your own risk.
|
|
||||||
|
@ -71,7 +71,7 @@ static const char *const _CARTDB_PATHS[cart::NUM_CHIP_TYPES]{
|
|||||||
|
|
||||||
bool App::_cartDetectWorker(void) {
|
bool App::_cartDetectWorker(void) {
|
||||||
_workerStatus.setNextScreen(_cartInfoScreen);
|
_workerStatus.setNextScreen(_cartInfoScreen);
|
||||||
_workerStatus.update(0, 4, WSTR("App.cartDetectWorker.identifyCart"));
|
_workerStatus.update(0, 3, WSTR("App.cartDetectWorker.readCart"));
|
||||||
_unloadCartData();
|
_unloadCartData();
|
||||||
|
|
||||||
#ifdef ENABLE_DUMMY_DRIVER
|
#ifdef ENABLE_DUMMY_DRIVER
|
||||||
@ -81,6 +81,7 @@ bool App::_cartDetectWorker(void) {
|
|||||||
if (cart::dummyDriverDump.chipType) {
|
if (cart::dummyDriverDump.chipType) {
|
||||||
LOG("using dummy cart driver");
|
LOG("using dummy cart driver");
|
||||||
_driver = new cart::DummyDriver(_dump);
|
_driver = new cart::DummyDriver(_dump);
|
||||||
|
_driver->readSystemID();
|
||||||
} else {
|
} else {
|
||||||
_driver = cart::newCartDriver(_dump);
|
_driver = cart::newCartDriver(_dump);
|
||||||
}
|
}
|
||||||
@ -91,7 +92,6 @@ bool App::_cartDetectWorker(void) {
|
|||||||
if (_dump.chipType) {
|
if (_dump.chipType) {
|
||||||
LOG("cart dump @ 0x%08x", &_dump);
|
LOG("cart dump @ 0x%08x", &_dump);
|
||||||
LOG("cart driver @ 0x%08x", _driver);
|
LOG("cart driver @ 0x%08x", _driver);
|
||||||
_workerStatus.update(1, 4, WSTR("App.cartDetectWorker.readCart"));
|
|
||||||
|
|
||||||
auto error = _driver->readCartID();
|
auto error = _driver->readCartID();
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ bool App::_cartDetectWorker(void) {
|
|||||||
_parser = cart::newCartParser(_dump);
|
_parser = cart::newCartParser(_dump);
|
||||||
|
|
||||||
LOG("cart parser @ 0x%08x", _parser);
|
LOG("cart parser @ 0x%08x", _parser);
|
||||||
_workerStatus.update(2, 4, WSTR("App.cartDetectWorker.identifyGame"));
|
_workerStatus.update(1, 3, WSTR("App.cartDetectWorker.identifyGame"));
|
||||||
|
|
||||||
if (!_db.ptr) {
|
if (!_db.ptr) {
|
||||||
if (!_resourceProvider->loadData(
|
if (!_resourceProvider->loadData(
|
||||||
@ -137,9 +137,13 @@ bool App::_cartDetectWorker(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_cartInitDone:
|
_cartInitDone:
|
||||||
_workerStatus.update(3, 4, WSTR("App.cartDetectWorker.readDigitalIO"));
|
_workerStatus.update(2, 3, WSTR("App.cartDetectWorker.readDigitalIO"));
|
||||||
|
|
||||||
|
#ifdef ENABLE_DUMMY_DRIVER
|
||||||
|
if (io::isDigitalIOPresent() && !(_dump.flags & cart::DUMP_SYSTEM_ID_OK)) {
|
||||||
|
#else
|
||||||
if (io::isDigitalIOPresent()) {
|
if (io::isDigitalIOPresent()) {
|
||||||
|
#endif
|
||||||
util::Data bitstream;
|
util::Data bitstream;
|
||||||
bool ready;
|
bool ready;
|
||||||
|
|
||||||
@ -158,14 +162,12 @@ _cartInitDone:
|
|||||||
|
|
||||||
delayMicroseconds(5000); // Probably not necessary
|
delayMicroseconds(5000); // Probably not necessary
|
||||||
io::initKonamiBitstream();
|
io::initKonamiBitstream();
|
||||||
}
|
|
||||||
|
|
||||||
// This must be outside of the if block above to make sure the system ID
|
|
||||||
// gets read with the dummy driver.
|
|
||||||
auto error = _driver->readSystemID();
|
auto error = _driver->readSystemID();
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
LOG("XID error [%s]", util::getErrorString(error));
|
LOG("XID error [%s]", util::getErrorString(error));
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -330,8 +332,6 @@ bool App::_cartReflashWorker(void) {
|
|||||||
_parser->flush();
|
_parser->flush();
|
||||||
|
|
||||||
auto error = _driver->setDataKey(_selectedEntry->dataKey);
|
auto error = _driver->setDataKey(_selectedEntry->dataKey);
|
||||||
delayMicroseconds(1000000); // TODO: does this fix ZS01 bricking?
|
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
LOG("key error [%s]", util::getErrorString(error));
|
LOG("key error [%s]", util::getErrorString(error));
|
||||||
else
|
else
|
||||||
@ -356,8 +356,6 @@ bool App::_cartEraseWorker(void) {
|
|||||||
_workerStatus.update(0, 1, WSTR("App.cartEraseWorker.erase"));
|
_workerStatus.update(0, 1, WSTR("App.cartEraseWorker.erase"));
|
||||||
|
|
||||||
auto error = _driver->erase();
|
auto error = _driver->erase();
|
||||||
delayMicroseconds(1000000); // TODO: does this fix ZS01 bricking?
|
|
||||||
|
|
||||||
_cartDetectWorker();
|
_cartDetectWorker();
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
@ -533,6 +531,17 @@ _writeError:
|
|||||||
bool App::_atapiEjectWorker(void) {
|
bool App::_atapiEjectWorker(void) {
|
||||||
_workerStatus.update(0, 1, WSTR("App.atapiEjectWorker.eject"));
|
_workerStatus.update(0, 1, WSTR("App.atapiEjectWorker.eject"));
|
||||||
|
|
||||||
|
if (!(ide::devices[0].flags & ide::DEVICE_ATAPI)) {
|
||||||
|
LOG("primary drive is not ATAPI");
|
||||||
|
|
||||||
|
_messageScreen.setMessage(
|
||||||
|
MESSAGE_ERROR, _mainMenuScreen,
|
||||||
|
WSTR("App.atapiEjectWorker.atapiError")
|
||||||
|
);
|
||||||
|
_workerStatus.setNextScreen(_messageScreen);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ide::Packet packet;
|
ide::Packet packet;
|
||||||
packet.setStartStopUnit(ide::START_STOP_MODE_OPEN_TRAY);
|
packet.setStartStopUnit(ide::START_STOP_MODE_OPEN_TRAY);
|
||||||
|
|
||||||
@ -542,7 +551,8 @@ bool App::_atapiEjectWorker(void) {
|
|||||||
LOG("eject error [%s]", util::getErrorString(error));
|
LOG("eject error [%s]", util::getErrorString(error));
|
||||||
|
|
||||||
_messageScreen.setMessage(
|
_messageScreen.setMessage(
|
||||||
MESSAGE_ERROR, _mainMenuScreen, WSTR("App.atapiEjectWorker.error")
|
MESSAGE_ERROR, _mainMenuScreen,
|
||||||
|
WSTR("App.atapiEjectWorker.ejectError")
|
||||||
);
|
);
|
||||||
_workerStatus.setNextScreen(_messageScreen);
|
_workerStatus.setNextScreen(_messageScreen);
|
||||||
return false;
|
return false;
|
||||||
|
@ -179,10 +179,12 @@ void CartActionsScreen::update(ui::Context &ctx) {
|
|||||||
|
|
||||||
ListScreen::update(ctx);
|
ListScreen::update(ctx);
|
||||||
|
|
||||||
if (ctx.buttons.pressed(ui::BTN_START))
|
if (ctx.buttons.pressed(ui::BTN_START)) {
|
||||||
(this->*action.target)(ctx);
|
if (ctx.buttons.held(ui::BTN_LEFT) || ctx.buttons.held(ui::BTN_RIGHT))
|
||||||
if (ctx.buttons.bothPressed(ui::BTN_LEFT, ui::BTN_RIGHT))
|
|
||||||
ctx.show(APP->_cartInfoScreen, true, true);
|
ctx.show(APP->_cartInfoScreen, true, true);
|
||||||
|
else
|
||||||
|
(this->*action.target)(ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr int _QR_CODE_SCALE = 2;
|
static constexpr int _QR_CODE_SCALE = 2;
|
||||||
@ -200,10 +202,7 @@ void QRCodeScreen::show(ui::Context &ctx, bool goBack) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void QRCodeScreen::update(ui::Context &ctx) {
|
void QRCodeScreen::update(ui::Context &ctx) {
|
||||||
if (
|
if (ctx.buttons.pressed(ui::BTN_START))
|
||||||
ctx.buttons.pressed(ui::BTN_START) ||
|
|
||||||
ctx.buttons.bothPressed(ui::BTN_LEFT, ui::BTN_RIGHT)
|
|
||||||
)
|
|
||||||
ctx.show(APP->_cartActionsScreen, true, true);
|
ctx.show(APP->_cartActionsScreen, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,10 +229,7 @@ void HexdumpScreen::show(ui::Context &ctx, bool goBack) {
|
|||||||
void HexdumpScreen::update(ui::Context &ctx) {
|
void HexdumpScreen::update(ui::Context &ctx) {
|
||||||
TextScreen::update(ctx);
|
TextScreen::update(ctx);
|
||||||
|
|
||||||
if (
|
if (ctx.buttons.pressed(ui::BTN_START))
|
||||||
ctx.buttons.pressed(ui::BTN_START) ||
|
|
||||||
ctx.buttons.bothPressed(ui::BTN_LEFT, ui::BTN_RIGHT)
|
|
||||||
)
|
|
||||||
ctx.show(APP->_cartActionsScreen, true, true);
|
ctx.show(APP->_cartActionsScreen, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,6 +254,9 @@ void ReflashGameScreen::update(ui::Context &ctx) {
|
|||||||
ListScreen::update(ctx);
|
ListScreen::update(ctx);
|
||||||
|
|
||||||
if (ctx.buttons.pressed(ui::BTN_START)) {
|
if (ctx.buttons.pressed(ui::BTN_START)) {
|
||||||
|
if (ctx.buttons.held(ui::BTN_LEFT) || ctx.buttons.held(ui::BTN_RIGHT)) {
|
||||||
|
ctx.show(APP->_cartActionsScreen, true, true);
|
||||||
|
} else {
|
||||||
APP->_confirmScreen.setMessage(
|
APP->_confirmScreen.setMessage(
|
||||||
*this,
|
*this,
|
||||||
[](ui::Context &ctx) {
|
[](ui::Context &ctx) {
|
||||||
@ -269,8 +268,7 @@ void ReflashGameScreen::update(ui::Context &ctx) {
|
|||||||
|
|
||||||
APP->_selectedEntry = APP->_db.get(_activeItem);
|
APP->_selectedEntry = APP->_db.get(_activeItem);
|
||||||
ctx.show(APP->_confirmScreen, false, true);
|
ctx.show(APP->_confirmScreen, false, true);
|
||||||
} else if (ctx.buttons.bothPressed(ui::BTN_LEFT, ui::BTN_RIGHT)) {
|
}
|
||||||
ctx.show(APP->_cartActionsScreen, true, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,14 +207,16 @@ void CartInfoScreen::show(ui::Context &ctx, bool goBack) {
|
|||||||
void CartInfoScreen::update(ui::Context &ctx) {
|
void CartInfoScreen::update(ui::Context &ctx) {
|
||||||
TextScreen::update(ctx);
|
TextScreen::update(ctx);
|
||||||
|
|
||||||
if (APP->_dump.chipType && ctx.buttons.pressed(ui::BTN_START)) {
|
if (ctx.buttons.pressed(ui::BTN_START)) {
|
||||||
|
if (ctx.buttons.held(ui::BTN_LEFT) || ctx.buttons.held(ui::BTN_RIGHT)) {
|
||||||
|
ctx.show(APP->_mainMenuScreen, true, true);
|
||||||
|
} else if (APP->_dump.chipType) {
|
||||||
if (APP->_dump.flags & cart::DUMP_PRIVATE_DATA_OK)
|
if (APP->_dump.flags & cart::DUMP_PRIVATE_DATA_OK)
|
||||||
ctx.show(APP->_cartActionsScreen, false, true);
|
ctx.show(APP->_cartActionsScreen, false, true);
|
||||||
else
|
else
|
||||||
ctx.show(APP->_unlockKeyScreen, false, true);
|
ctx.show(APP->_unlockKeyScreen, false, true);
|
||||||
}
|
}
|
||||||
if (ctx.buttons.bothPressed(ui::BTN_LEFT, ui::BTN_RIGHT))
|
}
|
||||||
ctx.show(APP->_mainMenuScreen, true, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SpecialEntryIndex {
|
enum SpecialEntryIndex {
|
||||||
@ -313,6 +315,9 @@ void UnlockKeyScreen::update(ui::Context &ctx) {
|
|||||||
ListScreen::update(ctx);
|
ListScreen::update(ctx);
|
||||||
|
|
||||||
if (ctx.buttons.pressed(ui::BTN_START)) {
|
if (ctx.buttons.pressed(ui::BTN_START)) {
|
||||||
|
if (ctx.buttons.held(ui::BTN_LEFT) || ctx.buttons.held(ui::BTN_RIGHT)) {
|
||||||
|
ctx.show(APP->_cartInfoScreen, true, true);
|
||||||
|
} else {
|
||||||
int index = _activeItem + _getSpecialEntryOffset(ctx);
|
int index = _activeItem + _getSpecialEntryOffset(ctx);
|
||||||
|
|
||||||
APP->_confirmScreen.setMessage(
|
APP->_confirmScreen.setMessage(
|
||||||
@ -341,8 +346,6 @@ void UnlockKeyScreen::update(ui::Context &ctx) {
|
|||||||
ctx.show(APP->_confirmScreen, false, true);
|
ctx.show(APP->_confirmScreen, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ctx.buttons.bothPressed(ui::BTN_LEFT, ui::BTN_RIGHT)) {
|
|
||||||
ctx.show(APP->_cartInfoScreen, true, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,14 +81,20 @@ public:
|
|||||||
void (MainMenuScreen::*target)(ui::Context &ctx);
|
void (MainMenuScreen::*target)(ui::Context &ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef ENABLE_CART_MENU
|
||||||
static constexpr int _NUM_MENU_ENTRIES = 5;
|
static constexpr int _NUM_MENU_ENTRIES = 5;
|
||||||
|
#else
|
||||||
|
static constexpr int _NUM_MENU_ENTRIES = 4;
|
||||||
|
#endif
|
||||||
|
|
||||||
static const MenuEntry _MENU_ENTRIES[_NUM_MENU_ENTRIES]{
|
static const MenuEntry _MENU_ENTRIES[_NUM_MENU_ENTRIES]{
|
||||||
{
|
{
|
||||||
|
#ifdef ENABLE_CART_MENU
|
||||||
.name = "MainMenuScreen.cartInfo.name"_h,
|
.name = "MainMenuScreen.cartInfo.name"_h,
|
||||||
.prompt = "MainMenuScreen.cartInfo.prompt"_h,
|
.prompt = "MainMenuScreen.cartInfo.prompt"_h,
|
||||||
.target = &MainMenuScreen::cartInfo
|
.target = &MainMenuScreen::cartInfo
|
||||||
}, {
|
}, {
|
||||||
|
#endif
|
||||||
.name = "MainMenuScreen.dump.name"_h,
|
.name = "MainMenuScreen.dump.name"_h,
|
||||||
.prompt = "MainMenuScreen.dump.prompt"_h,
|
.prompt = "MainMenuScreen.dump.prompt"_h,
|
||||||
.target = &MainMenuScreen::dump
|
.target = &MainMenuScreen::dump
|
||||||
@ -194,11 +200,14 @@ void AboutScreen::show(ui::Context &ctx, bool goBack) {
|
|||||||
auto ptr = reinterpret_cast<char *>(_text.ptr);
|
auto ptr = reinterpret_cast<char *>(_text.ptr);
|
||||||
_body = ptr;
|
_body = ptr;
|
||||||
|
|
||||||
// Replace single newlines with spaces to reflow the text. The last
|
// Replace single newlines with spaces to reflow the text, unless the line
|
||||||
// character is also cut off and replaced with a null terminator.
|
// preceding the newline ends with a space. The last character is also cut
|
||||||
|
// off and replaced with a null terminator.
|
||||||
for (size_t i = _text.length - 1; i; i--, ptr++) {
|
for (size_t i = _text.length - 1; i; i--, ptr++) {
|
||||||
if (*ptr != '\n')
|
if (*ptr != '\n')
|
||||||
continue;
|
continue;
|
||||||
|
if (__builtin_isspace(ptr[-1]))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (ptr[1] == '\n')
|
if (ptr[1] == '\n')
|
||||||
i--, ptr++;
|
i--, ptr++;
|
||||||
@ -221,9 +230,6 @@ void AboutScreen::hide(ui::Context &ctx, bool goBack) {
|
|||||||
void AboutScreen::update(ui::Context &ctx) {
|
void AboutScreen::update(ui::Context &ctx) {
|
||||||
TextScreen::update(ctx);
|
TextScreen::update(ctx);
|
||||||
|
|
||||||
if (
|
if (ctx.buttons.pressed(ui::BTN_START))
|
||||||
ctx.buttons.pressed(ui::BTN_START) ||
|
|
||||||
ctx.buttons.bothPressed(ui::BTN_LEFT, ui::BTN_RIGHT)
|
|
||||||
)
|
|
||||||
ctx.show(APP->_mainMenuScreen, true, true);
|
ctx.show(APP->_mainMenuScreen, true, true);
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,11 @@ void Identifier::updateDSCRC(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Identifier::validateDSCRC(void) const {
|
bool Identifier::validateDSCRC(void) const {
|
||||||
|
if (!data[0] || (data[0] == 0xff)) {
|
||||||
|
LOG("invalid 1-wire prefix 0x%02x", data[0]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t value = util::dsCRC8(data, 7);
|
uint8_t value = util::dsCRC8(data, 7);
|
||||||
|
|
||||||
if (value != data[7]) {
|
if (value != data[7]) {
|
||||||
|
@ -28,7 +28,7 @@ void Font::draw(
|
|||||||
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '\t':
|
case '\t':
|
||||||
x += metrics.tabWidth - 1;
|
x += metrics.tabWidth;
|
||||||
x -= x % metrics.tabWidth;
|
x -= x % metrics.tabWidth;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ void Font::getStringBounds(
|
|||||||
if (breakOnSpace)
|
if (breakOnSpace)
|
||||||
goto _break;
|
goto _break;
|
||||||
|
|
||||||
x += metrics.tabWidth - 1;
|
x += metrics.tabWidth;
|
||||||
x -= x % metrics.tabWidth;
|
x -= x % metrics.tabWidth;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -214,7 +214,7 @@ int Font::getStringWidth(const char *str, bool breakOnSpace) const {
|
|||||||
if (breakOnSpace)
|
if (breakOnSpace)
|
||||||
goto _break;
|
goto _break;
|
||||||
|
|
||||||
width += metrics.tabWidth - 1;
|
width += metrics.tabWidth;
|
||||||
width -= width % metrics.tabWidth;
|
width -= width % metrics.tabWidth;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ public:
|
|||||||
inline uint32_t getCharacterSize(uint8_t ch) const {
|
inline uint32_t getCharacterSize(uint8_t ch) const {
|
||||||
uint32_t sizes = characterSizes[ch];
|
uint32_t sizes = characterSizes[ch];
|
||||||
if (!sizes)
|
if (!sizes)
|
||||||
return characterSizes[FONT_INVALID_CHAR];
|
return characterSizes[int(FONT_INVALID_CHAR)];
|
||||||
|
|
||||||
return sizes;
|
return sizes;
|
||||||
}
|
}
|
||||||
|
@ -125,15 +125,6 @@ void ButtonState::update(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ButtonState::bothPressed(Button buttonA, Button buttonB) {
|
|
||||||
if (pressed(buttonA) && held(buttonB))
|
|
||||||
return true;
|
|
||||||
if (held(buttonA) && pressed(buttonB))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UI context */
|
/* UI context */
|
||||||
|
|
||||||
Context::Context(gpu::Context &gpuCtx, void *screenData)
|
Context::Context(gpu::Context &gpuCtx, void *screenData)
|
||||||
|
@ -128,7 +128,6 @@ public:
|
|||||||
|
|
||||||
ButtonState(void);
|
ButtonState(void);
|
||||||
void update(void);
|
void update(void);
|
||||||
bool bothPressed(Button buttonA, Button buttonB);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* UI context */
|
/* UI context */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user