mirror of
https://github.com/spicyjpeg/573in1.git
synced 2025-01-22 19:52:05 +01:00
Make message screen generic, add error enum strings
This commit is contained in:
parent
3fc447da4d
commit
ced62de54e
@ -28,8 +28,9 @@
|
||||
"error": "An error occurred while writing to the cartridge's EEPROM.\n\nPress the Test button to view debug logs."
|
||||
},
|
||||
"cartDumpWorker": {
|
||||
"save": "Saving cartridge dump...",
|
||||
"error": "An error occurred while saving the dump to the hard drive. Turn off the system and make sure the drive is connected to the IDE bus properly, set as secondary and formatted with a single FAT16, FAT32 or exFAT partition.\n\nPress the Test button to view debug logs."
|
||||
"save": "Saving cartridge dump...",
|
||||
"success": "A dump of the cartridge and all its identifiers has been saved as %s in the root of the drive. The dump can be decoded and viewed using the decodeDump.py script provided with this tool.",
|
||||
"error": "An error occurred while saving the dump to the hard drive. Turn off the system and make sure the drive is connected to the IDE bus properly, set as secondary and formatted with a single FAT16, FAT32 or exFAT partition.\n\nPress the Test button to view debug logs."
|
||||
},
|
||||
"qrCodeWorker": {
|
||||
"compress": "Compressing cartridge dump...",
|
||||
@ -42,6 +43,7 @@
|
||||
"dumpFlash": "Dumping internal flash...",
|
||||
"dumpPCMCIA1": "Dumping PCMCIA card in slot 1...",
|
||||
"dumpPCMCIA2": "Dumping PCMCIA card in slot 2...",
|
||||
"success": "All dumps have been saved to the %s directory in the root of the drive.",
|
||||
"initError": "An error occurred while creating the dump directory. Turn off the system and make sure the drive is connected to the IDE bus properly, set as secondary and formatted with a single FAT16, FAT32 or exFAT partition.\n\nPress the Test button to view debug logs.",
|
||||
"dumpError": "An error occurred while writing dumps to the hard drive. Ensure the drive has at least 32 MB of free space (256 MB if both PCMCIA cards are inserted) and the filesystem is not damaged.\n\nPress the Test button to view debug logs."
|
||||
},
|
||||
@ -178,11 +180,6 @@
|
||||
"yes": "Yes, continue"
|
||||
},
|
||||
|
||||
"ErrorScreen": {
|
||||
"title": "Error",
|
||||
"ok": "Continue"
|
||||
},
|
||||
|
||||
"HexdumpScreen": {
|
||||
"title": "{CART_ICON} Cartridge dump",
|
||||
"prompt": "Use {LEFT_BUTTON}{RIGHT_BUTTON} to scroll. Press {START_BUTTON} to go back."
|
||||
@ -222,6 +219,15 @@
|
||||
}
|
||||
},
|
||||
|
||||
"MessageScreen": {
|
||||
"title": {
|
||||
"success": "Success",
|
||||
"error": "Error"
|
||||
},
|
||||
|
||||
"ok": "Continue"
|
||||
},
|
||||
|
||||
"QRCodeScreen": {
|
||||
"title": "{CART_ICON} Cartridge dump",
|
||||
"prompt": "Scan this code and paste the resulting string into the decodeDump.py script provided alongside this tool to obtain a dump of the cartridge. Press {START_BUTTON} to go back."
|
||||
@ -242,7 +248,7 @@
|
||||
|
||||
"SystemInfoScreen": {
|
||||
"title": "System information",
|
||||
"prompt": "Press {START_BUTTON} to go back."
|
||||
"prompt": "Use {LEFT_BUTTON}{RIGHT_BUTTON} to scroll. Press {START_BUTTON} to go back."
|
||||
},
|
||||
|
||||
"UnlockKeyScreen": {
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "io.hpp"
|
||||
#include "uibase.hpp"
|
||||
#include "util.hpp"
|
||||
#include "utilerror.hpp"
|
||||
|
||||
/* App class */
|
||||
|
||||
@ -24,7 +25,10 @@ void App::_unloadCartData(void) {
|
||||
_parser = nullptr;
|
||||
}
|
||||
|
||||
_dump.chipType = cart::NONE;
|
||||
_dump.chipType = cart::NONE;
|
||||
_dump._reserved[0] = 0;
|
||||
_dump._reserved[1] = 0;
|
||||
|
||||
_dump.clearIdentifiers();
|
||||
_dump.clearData();
|
||||
|
||||
@ -90,12 +94,12 @@ bool App::_cartDetectWorker(void) {
|
||||
auto error = _driver->readCartID();
|
||||
|
||||
if (error)
|
||||
LOG("cart ID error, code=%d", error);
|
||||
LOG("SID error [%s]", util::getErrorString(error));
|
||||
|
||||
error = _driver->readPublicData();
|
||||
|
||||
if (error)
|
||||
LOG("public data error, code=%d", error);
|
||||
LOG("read error [%s]", util::getErrorString(error));
|
||||
else
|
||||
_parser = cart::newCartParser(_dump);
|
||||
|
||||
@ -159,7 +163,7 @@ _cartInitDone:
|
||||
auto error = _driver->readSystemID();
|
||||
|
||||
if (error)
|
||||
LOG("system ID error, code=%d", error);
|
||||
LOG("XID error [%s]", util::getErrorString(error));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -171,12 +175,12 @@ bool App::_cartUnlockWorker(void) {
|
||||
auto error = _driver->readPrivateData();
|
||||
|
||||
if (error) {
|
||||
LOG("private data error, code=%d", error);
|
||||
LOG("read error [%s]", util::getErrorString(error));
|
||||
|
||||
/*_errorScreen.setMessage(
|
||||
_cartInfoScreen, WSTR("App.cartUnlockWorker.error")
|
||||
/*_messageScreen.setMessage(
|
||||
MESSAGE_ERROR, _cartInfoScreen, WSTR("App.cartUnlockWorker.error")
|
||||
);*/
|
||||
_workerStatus.setNextScreen(_errorScreen);
|
||||
_workerStatus.setNextScreen(_messageScreen);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -243,14 +247,18 @@ bool App::_cartDumpWorker(void) {
|
||||
LOG("saving %s, length=%d", path, length);
|
||||
|
||||
if (_fileProvider->saveData(&_dump, length, path) != length) {
|
||||
_errorScreen.setMessage(
|
||||
_cartInfoScreen, WSTR("App.cartDumpWorker.error")
|
||||
_messageScreen.setMessage(
|
||||
MESSAGE_ERROR, _cartInfoScreen, WSTR("App.cartDumpWorker.error")
|
||||
);
|
||||
_workerStatus.setNextScreen(_errorScreen);
|
||||
_workerStatus.setNextScreen(_messageScreen);
|
||||
return false;
|
||||
}
|
||||
|
||||
_workerStatus.setNextScreen(_cartActionsScreen);
|
||||
_messageScreen.setMessage(
|
||||
MESSAGE_SUCCESS, _cartInfoScreen, WSTR("App.cartDumpWorker.success"),
|
||||
path
|
||||
);
|
||||
_workerStatus.setNextScreen(_messageScreen);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -266,12 +274,12 @@ bool App::_cartWriteWorker(void) {
|
||||
_cartDetectWorker();
|
||||
|
||||
if (error) {
|
||||
LOG("write error, code=%d", error);
|
||||
LOG("write error [%s]", util::getErrorString(error));
|
||||
|
||||
_errorScreen.setMessage(
|
||||
_cartInfoScreen, WSTR("App.cartWriteWorker.error")
|
||||
_messageScreen.setMessage(
|
||||
MESSAGE_ERROR, _cartInfoScreen, WSTR("App.cartWriteWorker.error")
|
||||
);
|
||||
_workerStatus.setNextScreen(_errorScreen);
|
||||
_workerStatus.setNextScreen(_messageScreen);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -323,19 +331,19 @@ bool App::_cartReflashWorker(void) {
|
||||
delayMicroseconds(1000000); // TODO: does this fix ZS01 bricking?
|
||||
|
||||
if (error)
|
||||
LOG("failed to set data key");
|
||||
LOG("key error [%s]", util::getErrorString(error));
|
||||
else
|
||||
error = _driver->writeData();
|
||||
|
||||
_cartDetectWorker();
|
||||
|
||||
if (error) {
|
||||
LOG("write error, code=%d", error);
|
||||
LOG("write error [%s]", util::getErrorString(error));
|
||||
|
||||
_errorScreen.setMessage(
|
||||
_cartInfoScreen, WSTR("App.cartReflashWorker.error")
|
||||
_messageScreen.setMessage(
|
||||
MESSAGE_ERROR, _cartInfoScreen, WSTR("App.cartReflashWorker.error")
|
||||
);
|
||||
_workerStatus.setNextScreen(_errorScreen);
|
||||
_workerStatus.setNextScreen(_messageScreen);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -351,12 +359,12 @@ bool App::_cartEraseWorker(void) {
|
||||
_cartDetectWorker();
|
||||
|
||||
if (error) {
|
||||
LOG("erase error, code=%d", error);
|
||||
LOG("erase error [%s]", util::getErrorString(error));
|
||||
|
||||
_errorScreen.setMessage(
|
||||
_cartInfoScreen, WSTR("App.cartEraseWorker.error")
|
||||
_messageScreen.setMessage(
|
||||
MESSAGE_ERROR, _cartInfoScreen, WSTR("App.cartEraseWorker.error")
|
||||
);
|
||||
_workerStatus.setNextScreen(_errorScreen);
|
||||
_workerStatus.setNextScreen(_messageScreen);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -423,20 +431,20 @@ bool App::_romDumpWorker(void) {
|
||||
|
||||
// Store all dumps in a directory named "dump_N".
|
||||
int index = 0;
|
||||
char path[32];
|
||||
char directoryPath[32], filePath[32];
|
||||
|
||||
do {
|
||||
index++;
|
||||
snprintf(path, sizeof(path), "dump_%d", index);
|
||||
} while (_fileProvider->fileExists(path));
|
||||
snprintf(directoryPath, sizeof(directoryPath), "dump_%d", index);
|
||||
} while (_fileProvider->fileExists(directoryPath));
|
||||
|
||||
LOG("saving dumps to %s", path);
|
||||
LOG("saving dumps to %s", directoryPath);
|
||||
|
||||
if (!_fileProvider->createDirectory(path)) {
|
||||
_errorScreen.setMessage(
|
||||
_mainMenuScreen, WSTR("App.romDumpWorker.initError")
|
||||
if (!_fileProvider->createDirectory(directoryPath)) {
|
||||
_messageScreen.setMessage(
|
||||
MESSAGE_ERROR, _mainMenuScreen, WSTR("App.romDumpWorker.initError")
|
||||
);
|
||||
_workerStatus.setNextScreen(_errorScreen);
|
||||
_workerStatus.setNextScreen(_messageScreen);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -449,10 +457,10 @@ bool App::_romDumpWorker(void) {
|
||||
if (region.inputs && !(inputs & region.inputs))
|
||||
continue;
|
||||
|
||||
snprintf(path, sizeof(path), region.path, index);
|
||||
snprintf(filePath, sizeof(filePath), region.path, index);
|
||||
|
||||
auto _file = _fileProvider->openFile(
|
||||
path, file::WRITE | file::ALLOW_CREATE
|
||||
filePath, file::WRITE | file::ALLOW_CREATE
|
||||
);
|
||||
|
||||
if (!_file)
|
||||
@ -501,17 +509,21 @@ bool App::_romDumpWorker(void) {
|
||||
}
|
||||
|
||||
_file->close();
|
||||
LOG("%s saved", path);
|
||||
LOG("%s saved", filePath);
|
||||
}
|
||||
|
||||
_workerStatus.setNextScreen(_mainMenuScreen);
|
||||
_messageScreen.setMessage(
|
||||
MESSAGE_SUCCESS, _mainMenuScreen, WSTR("App.romDumpWorker.success"),
|
||||
directoryPath
|
||||
);
|
||||
_workerStatus.setNextScreen(_messageScreen);
|
||||
return true;
|
||||
|
||||
_writeError:
|
||||
_errorScreen.setMessage(
|
||||
_mainMenuScreen, WSTR("App.romDumpWorker.dumpError")
|
||||
_messageScreen.setMessage(
|
||||
MESSAGE_ERROR, _mainMenuScreen, WSTR("App.romDumpWorker.dumpError")
|
||||
);
|
||||
_workerStatus.setNextScreen(_errorScreen);
|
||||
_workerStatus.setNextScreen(_messageScreen);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ static constexpr size_t WORKER_STACK_SIZE = 0x20000;
|
||||
|
||||
class App {
|
||||
friend class WorkerStatusScreen;
|
||||
friend class ErrorScreen;
|
||||
friend class MessageScreen;
|
||||
friend class ConfirmScreen;
|
||||
friend class WarningScreen;
|
||||
friend class ButtonMappingScreen;
|
||||
@ -105,7 +105,7 @@ class App {
|
||||
|
||||
private:
|
||||
WorkerStatusScreen _workerStatusScreen;
|
||||
ErrorScreen _errorScreen;
|
||||
MessageScreen _messageScreen;
|
||||
ConfirmScreen _confirmScreen;
|
||||
WarningScreen _warningScreen;
|
||||
ButtonMappingScreen _buttonMappingScreen;
|
||||
|
@ -103,11 +103,11 @@ void CartActionsScreen::resetSystemID(ui::Context &ctx) {
|
||||
|
||||
ctx.show(APP->_confirmScreen, false, true);
|
||||
} else {
|
||||
APP->_errorScreen.setMessage(
|
||||
*this, STR("CartActionsScreen.resetSystemID.error")
|
||||
APP->_messageScreen.setMessage(
|
||||
MESSAGE_ERROR, *this, STR("CartActionsScreen.resetSystemID.error")
|
||||
);
|
||||
|
||||
ctx.show(APP->_errorScreen, false, true);
|
||||
ctx.show(APP->_messageScreen, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,11 +129,11 @@ void CartActionsScreen::matchSystemID(ui::Context &ctx) {
|
||||
|
||||
ctx.show(APP->_confirmScreen, false, true);
|
||||
} else {
|
||||
APP->_errorScreen.setMessage(
|
||||
*this, STR("CartActionsScreen.matchSystemID.error")
|
||||
APP->_messageScreen.setMessage(
|
||||
MESSAGE_ERROR, *this, STR("CartActionsScreen.matchSystemID.error")
|
||||
);
|
||||
|
||||
ctx.show(APP->_errorScreen, false, true);
|
||||
ctx.show(APP->_messageScreen, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,8 +149,9 @@ void CartActionsScreen::editSystemID(ui::Context &ctx) {
|
||||
STR("CartActionsScreen.editSystemID.confirm")
|
||||
);
|
||||
|
||||
APP->_errorScreen.setMessage(
|
||||
APP->_systemIDEntryScreen, STR("CartActionsScreen.editSystemID.error")
|
||||
APP->_messageScreen.setMessage(
|
||||
MESSAGE_ERROR, APP->_systemIDEntryScreen,
|
||||
STR("CartActionsScreen.editSystemID.error")
|
||||
);
|
||||
|
||||
ctx.show(APP->_systemIDEntryScreen, false, true);
|
||||
@ -201,7 +202,11 @@ void QRCodeScreen::show(ui::Context &ctx, bool goBack) {
|
||||
}
|
||||
|
||||
void QRCodeScreen::update(ui::Context &ctx) {
|
||||
if (ctx.buttons.pressed(ui::BTN_START))
|
||||
if (
|
||||
ctx.buttons.pressed(ui::BTN_START) ||
|
||||
(ctx.buttons.held(ui::BTN_LEFT) && ctx.buttons.pressed(ui::BTN_RIGHT)) ||
|
||||
(ctx.buttons.pressed(ui::BTN_LEFT) && ctx.buttons.held(ui::BTN_RIGHT))
|
||||
)
|
||||
ctx.show(APP->_cartActionsScreen, true, true);
|
||||
}
|
||||
|
||||
@ -228,7 +233,11 @@ void HexdumpScreen::show(ui::Context &ctx, bool goBack) {
|
||||
void HexdumpScreen::update(ui::Context &ctx) {
|
||||
TextScreen::update(ctx);
|
||||
|
||||
if (ctx.buttons.pressed(ui::BTN_START))
|
||||
if (
|
||||
ctx.buttons.pressed(ui::BTN_START) ||
|
||||
(ctx.buttons.held(ui::BTN_LEFT) && ctx.buttons.pressed(ui::BTN_RIGHT)) ||
|
||||
(ctx.buttons.pressed(ui::BTN_LEFT) && ctx.buttons.held(ui::BTN_RIGHT))
|
||||
)
|
||||
ctx.show(APP->_cartActionsScreen, true, true);
|
||||
}
|
||||
|
||||
@ -299,7 +308,7 @@ void SystemIDEntryScreen::update(ui::Context &ctx) {
|
||||
if (util::dsCRC8(_buffer, 7) == _buffer[7])
|
||||
ctx.show(APP->_confirmScreen, false, true);
|
||||
else
|
||||
ctx.show(APP->_errorScreen, false, true);
|
||||
ctx.show(APP->_messageScreen, false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -327,8 +327,8 @@ void UnlockKeyScreen::update(ui::Context &ctx) {
|
||||
STRH(_CART_TYPES[APP->_dump.chipType].warning)
|
||||
);
|
||||
|
||||
APP->_errorScreen.setMessage(
|
||||
APP->_cartInfoScreen,
|
||||
APP->_messageScreen.setMessage(
|
||||
MESSAGE_ERROR, APP->_cartInfoScreen,
|
||||
STRH(_CART_TYPES[APP->_dump.chipType].error)
|
||||
);
|
||||
|
||||
@ -384,8 +384,8 @@ void KeyEntryScreen::update(ui::Context &ctx) {
|
||||
STRH(_CART_TYPES[APP->_dump.chipType].warning)
|
||||
);
|
||||
|
||||
APP->_errorScreen.setMessage(
|
||||
APP->_cartInfoScreen,
|
||||
APP->_messageScreen.setMessage(
|
||||
MESSAGE_ERROR, APP->_cartInfoScreen,
|
||||
STRH(_CART_TYPES[APP->_dump.chipType].error)
|
||||
);
|
||||
|
||||
|
@ -18,13 +18,13 @@ void WarningScreen::show(ui::Context &ctx, bool goBack) {
|
||||
|
||||
_cooldownTimer = ctx.time + ctx.gpuCtx.refreshRate * WARNING_COOLDOWN;
|
||||
|
||||
MessageScreen::show(ctx, goBack);
|
||||
MessageBoxScreen::show(ctx, goBack);
|
||||
|
||||
ctx.buttons.buttonMap = ui::MAP_SINGLE_BUTTON;
|
||||
}
|
||||
|
||||
void WarningScreen::update(ui::Context &ctx) {
|
||||
MessageScreen::update(ctx);
|
||||
MessageBoxScreen::update(ctx);
|
||||
|
||||
int time = _cooldownTimer - ctx.time;
|
||||
_locked = (time > 0);
|
||||
@ -98,6 +98,10 @@ static const MenuEntry _MENU_ENTRIES[_NUM_MENU_ENTRIES]{
|
||||
.prompt = "MainMenuScreen.restore.prompt"_h,
|
||||
.target = &MainMenuScreen::restore
|
||||
}, {
|
||||
.name = "MainMenuScreen.systemInfo.name"_h,
|
||||
.prompt = "MainMenuScreen.systemInfo.prompt"_h,
|
||||
.target = &MainMenuScreen::systemInfo
|
||||
}, {
|
||||
#endif
|
||||
.name = "MainMenuScreen.about.name"_h,
|
||||
.prompt = "MainMenuScreen.about.prompt"_h,
|
||||
@ -139,6 +143,10 @@ void MainMenuScreen::restore(ui::Context &ctx) {
|
||||
//ctx.show(APP->_restoreMenuScreen, false, true);
|
||||
}
|
||||
|
||||
void MainMenuScreen::systemInfo(ui::Context &ctx) {
|
||||
//ctx.show(APP->systemInfoScreen, false, true);
|
||||
}
|
||||
|
||||
void MainMenuScreen::about(ui::Context &ctx) {
|
||||
ctx.show(APP->_aboutScreen, false, true);
|
||||
}
|
||||
@ -204,6 +212,10 @@ void AboutScreen::hide(ui::Context &ctx, bool goBack) {
|
||||
void AboutScreen::update(ui::Context &ctx) {
|
||||
TextScreen::update(ctx);
|
||||
|
||||
if (ctx.buttons.pressed(ui::BTN_START))
|
||||
if (
|
||||
ctx.buttons.pressed(ui::BTN_START) ||
|
||||
(ctx.buttons.held(ui::BTN_LEFT) && ctx.buttons.pressed(ui::BTN_RIGHT)) ||
|
||||
(ctx.buttons.pressed(ui::BTN_LEFT) && ctx.buttons.held(ui::BTN_RIGHT))
|
||||
)
|
||||
ctx.show(APP->_mainMenuScreen, true, true);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
/* Main menu screens */
|
||||
|
||||
class WarningScreen : public ui::MessageScreen {
|
||||
class WarningScreen : public ui::MessageBoxScreen {
|
||||
private:
|
||||
int _cooldownTimer;
|
||||
char _buttonText[16];
|
||||
@ -34,6 +34,7 @@ public:
|
||||
void cartInfo(ui::Context &ctx);
|
||||
void dump(ui::Context &ctx);
|
||||
void restore(ui::Context &ctx);
|
||||
void systemInfo(ui::Context &ctx);
|
||||
void about(ui::Context &ctx);
|
||||
void reboot(ui::Context &ctx);
|
||||
|
||||
|
@ -30,7 +30,15 @@ void WorkerStatusScreen::update(ui::Context &ctx) {
|
||||
_body = worker.message;
|
||||
}
|
||||
|
||||
void ErrorScreen::setMessage(ui::Screen &prev, const char *format, ...) {
|
||||
static const util::Hash _MESSAGE_TITLES[]{
|
||||
"MessageScreen.title.success"_h,
|
||||
"MessageScreen.title.error"_h
|
||||
};
|
||||
|
||||
void MessageScreen::setMessage(
|
||||
MessageType type, ui::Screen &prev, const char *format, ...
|
||||
) {
|
||||
_type = type;
|
||||
_prevScreen = &prev;
|
||||
|
||||
va_list ap;
|
||||
@ -40,19 +48,19 @@ void ErrorScreen::setMessage(ui::Screen &prev, const char *format, ...) {
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void ErrorScreen::show(ui::Context &ctx, bool goBack) {
|
||||
_title = STR("ErrorScreen.title");
|
||||
void MessageScreen::show(ui::Context &ctx, bool goBack) {
|
||||
_title = STRH(_MESSAGE_TITLES[_type]);
|
||||
_body = _bodyText;
|
||||
_buttons[0] = STR("ErrorScreen.ok");
|
||||
_buttons[0] = STR("MessageScreen.ok");
|
||||
|
||||
_numButtons = 1;
|
||||
_locked = _prevScreen ? false : true;
|
||||
|
||||
MessageScreen::show(ctx, goBack);
|
||||
MessageBoxScreen::show(ctx, goBack);
|
||||
}
|
||||
|
||||
void ErrorScreen::update(ui::Context &ctx) {
|
||||
MessageScreen::update(ctx);
|
||||
void MessageScreen::update(ui::Context &ctx) {
|
||||
MessageBoxScreen::update(ctx);
|
||||
|
||||
if (ctx.buttons.pressed(ui::BTN_START))
|
||||
ctx.show(*_prevScreen, true, true);
|
||||
@ -80,12 +88,12 @@ void ConfirmScreen::show(ui::Context &ctx, bool goBack) {
|
||||
|
||||
_numButtons = 2;
|
||||
|
||||
MessageScreen::show(ctx, goBack);
|
||||
MessageBoxScreen::show(ctx, goBack);
|
||||
ctx.sounds[ui::SOUND_ERROR].play();
|
||||
}
|
||||
|
||||
void ConfirmScreen::update(ui::Context &ctx) {
|
||||
MessageScreen::update(ctx);
|
||||
MessageBoxScreen::update(ctx);
|
||||
|
||||
if (ctx.buttons.pressed(ui::BTN_START)) {
|
||||
if (_activeButton)
|
||||
|
@ -12,19 +12,27 @@ public:
|
||||
void update(ui::Context &ctx);
|
||||
};
|
||||
|
||||
class ErrorScreen : public ui::MessageScreen {
|
||||
enum MessageType {
|
||||
MESSAGE_SUCCESS = 0,
|
||||
MESSAGE_ERROR = 1
|
||||
};
|
||||
|
||||
class MessageScreen : public ui::MessageBoxScreen {
|
||||
private:
|
||||
char _bodyText[512];
|
||||
ui::Screen *_prevScreen;
|
||||
MessageType _type;
|
||||
char _bodyText[512];
|
||||
ui::Screen *_prevScreen;
|
||||
|
||||
public:
|
||||
void setMessage(ui::Screen &prev, const char *format, ...);
|
||||
void setMessage(
|
||||
MessageType type, ui::Screen &prev, const char *format, ...
|
||||
);
|
||||
|
||||
void show(ui::Context &ctx, bool goBack = false);
|
||||
void update(ui::Context &ctx);
|
||||
};
|
||||
|
||||
class ConfirmScreen : public ui::MessageScreen {
|
||||
class ConfirmScreen : public ui::MessageBoxScreen {
|
||||
private:
|
||||
char _bodyText[512];
|
||||
ui::Screen *_prevScreen;
|
||||
|
@ -2,6 +2,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "cart.hpp"
|
||||
#include "util.hpp"
|
||||
#include "zs01.hpp"
|
||||
|
||||
|
47
src/file.cpp
47
src/file.cpp
@ -7,6 +7,7 @@
|
||||
#include "vendor/ff.h"
|
||||
#include "vendor/miniz.h"
|
||||
#include "file.hpp"
|
||||
#include "utilerror.hpp"
|
||||
|
||||
namespace file {
|
||||
|
||||
@ -16,7 +17,7 @@ size_t HostFile::read(void *output, size_t length) {
|
||||
int actualLength = pcdrvRead(_fd, output, length);
|
||||
|
||||
if (actualLength < 0) {
|
||||
LOG("PCDRV error, code=%d", actualLength);
|
||||
LOG("PCDRV error, code=%d, file=0x%08x", actualLength, this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -27,7 +28,7 @@ size_t HostFile::write(const void *input, size_t length) {
|
||||
int actualLength = pcdrvWrite(_fd, input, length);
|
||||
|
||||
if (actualLength < 0) {
|
||||
LOG("PCDRV error, code=%d", actualLength);
|
||||
LOG("PCDRV error, code=%d, file=0x%08x", actualLength, this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -38,7 +39,7 @@ uint64_t HostFile::seek(uint64_t offset) {
|
||||
int actualOffset = pcdrvSeek(_fd, int(offset), PCDRV_SEEK_SET);
|
||||
|
||||
if (actualOffset < 0) {
|
||||
LOG("PCDRV error, code=%d", actualOffset);
|
||||
LOG("PCDRV error, code=%d, file=0x%08x", actualOffset, this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -49,7 +50,7 @@ uint64_t HostFile::tell(void) const {
|
||||
int actualOffset = pcdrvSeek(_fd, 0, PCDRV_SEEK_CUR);
|
||||
|
||||
if (actualOffset < 0) {
|
||||
LOG("PCDRV error, code=%d", actualOffset);
|
||||
LOG("PCDRV error, code=%d, file=0x%08x", actualOffset, this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -65,7 +66,7 @@ size_t FATFile::read(void *output, size_t length) {
|
||||
auto error = f_read(&_fd, output, length, &actualLength);
|
||||
|
||||
if (error) {
|
||||
LOG("FAT error, code=%d", error);
|
||||
LOG("%s, file=0x%08x", util::getErrorString(error), this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -77,7 +78,7 @@ size_t FATFile::write(const void *input, size_t length) {
|
||||
auto error = f_write(&_fd, input, length, &actualLength);
|
||||
|
||||
if (error) {
|
||||
LOG("FAT error, code=%d", error);
|
||||
LOG("%s, file=0x%08x", util::getErrorString(error), this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -88,7 +89,7 @@ uint64_t FATFile::seek(uint64_t offset) {
|
||||
auto error = f_lseek(&_fd, offset);
|
||||
|
||||
if (error) {
|
||||
LOG("FAT error, code=%d", error);
|
||||
LOG("%s, file=0x%08x", util::getErrorString(error), this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -261,7 +262,7 @@ bool FATProvider::init(const char *drive) {
|
||||
auto error = f_mount(&_fs, drive, 1);
|
||||
|
||||
if (error) {
|
||||
LOG("FAT mount error, drive=%s, code=%d", drive, error);
|
||||
LOG("%s, drive=%s", util::getErrorString(error), drive);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -276,7 +277,7 @@ void FATProvider::close(void) {
|
||||
auto error = f_unmount(_drive);
|
||||
|
||||
if (error)
|
||||
LOG("FAT unmount error, drive=%s, code=%d", _drive, error);
|
||||
LOG("%s, drive=%s", util::getErrorString(error), _drive);
|
||||
else
|
||||
LOG("FAT unmount ok, drive=%s", _drive);
|
||||
}
|
||||
@ -289,7 +290,7 @@ bool FATProvider::createDirectory(const char *path) {
|
||||
auto error = f_mkdir(path);
|
||||
|
||||
if (error) {
|
||||
LOG("FAT error, code=%d", error);
|
||||
LOG("%s, drive=%s", util::getErrorString(error), _drive);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -301,7 +302,7 @@ File *FATProvider::openFile(const char *path, uint32_t flags) {
|
||||
auto error = f_open(&(file->_fd), path, uint8_t(flags));
|
||||
|
||||
if (error) {
|
||||
LOG("FAT error, code=%d", error);
|
||||
LOG("%s, drive=%s", util::getErrorString(error), _drive);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -331,11 +332,13 @@ bool ZIPProvider::init(File *file) {
|
||||
};
|
||||
|
||||
if (!mz_zip_reader_init(&_zip, file->length, _ZIP_FLAGS)) {
|
||||
LOG("host zip init error, code=%d", mz_zip_get_last_error(&_zip));
|
||||
auto error = mz_zip_get_last_error(&_zip);
|
||||
|
||||
LOG("%s, file=0x%08x", util::getErrorString(error), file);
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG("file=0x%08x, length=0x%x", file, file->length);
|
||||
LOG("ZIP init ok, file=0x%08x", file);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -344,11 +347,13 @@ bool ZIPProvider::init(const void *zipData, size_t length) {
|
||||
_file = nullptr;
|
||||
|
||||
if (!mz_zip_reader_init_mem(&_zip, zipData, length, _ZIP_FLAGS)) {
|
||||
LOG("ZIP error, code=%d", mz_zip_get_last_error(&_zip));
|
||||
auto error = mz_zip_get_last_error(&_zip);
|
||||
|
||||
LOG("%s, ptr=0x%08x", util::getErrorString(error), zipData);
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG("ptr=0x%08x, length=0x%x", zipData, length);
|
||||
LOG("ZIP init ok, ptr=0x%08x", zipData);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -369,15 +374,23 @@ size_t ZIPProvider::loadData(util::Data &output, const char *path) {
|
||||
&_zip, path, &(output.length), 0
|
||||
);
|
||||
|
||||
if (!output.ptr)
|
||||
if (!output.ptr) {
|
||||
auto error = mz_zip_get_last_error(&_zip);
|
||||
|
||||
LOG("%s, zip=0x%08x", util::getErrorString(error), this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return output.length;
|
||||
}
|
||||
|
||||
size_t ZIPProvider::loadData(void *output, size_t length, const char *path) {
|
||||
if (!mz_zip_reader_extract_file_to_mem(&_zip, path, output, length, 0))
|
||||
if (!mz_zip_reader_extract_file_to_mem(&_zip, path, output, length, 0)) {
|
||||
auto error = mz_zip_get_last_error(&_zip);
|
||||
|
||||
LOG("%s, zip=0x%08x", util::getErrorString(error), this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// FIXME: this may not reflect the file's actual length
|
||||
return length;
|
||||
|
@ -31,6 +31,7 @@ int main(int argc, const char **argv) {
|
||||
gpu::init();
|
||||
spu::init();
|
||||
io::init();
|
||||
util::initZipCRC32();
|
||||
|
||||
int width = 320, height = 240;
|
||||
|
||||
|
@ -32,12 +32,13 @@
|
||||
#define F_GPU_PAL 53203425
|
||||
|
||||
typedef enum {
|
||||
DEV0_BASE = 0xbf000000,
|
||||
EXP1_BASE = 0xbf000000,
|
||||
IO_BASE = 0xbf800000,
|
||||
EXP2_BASE = 0xbf802000,
|
||||
EXP3_BASE = 0xbfa00000,
|
||||
DEV2_BASE = 0xbfc00000
|
||||
DEV0_BASE = 0xbf000000,
|
||||
EXP1_BASE = 0xbf000000,
|
||||
CACHE_BASE = 0xbf800000,
|
||||
IO_BASE = 0xbf801000,
|
||||
EXP2_BASE = 0xbf802000,
|
||||
EXP3_BASE = 0xbfa00000,
|
||||
DEV2_BASE = 0xbfc00000
|
||||
} BaseAddress;
|
||||
|
||||
/* Bus interface */
|
||||
@ -60,15 +61,15 @@ typedef enum {
|
||||
BIU_CTRL_WAIT = 1 << 31
|
||||
} BIUControlFlag;
|
||||
|
||||
#define BIU_DEV0_ADDR _MMIO32(IO_BASE | 0x1000) // PIO/573
|
||||
#define BIU_EXP2_ADDR _MMIO32(IO_BASE | 0x1004) // PIO/debug
|
||||
#define BIU_DEV0_CTRL _MMIO32(IO_BASE | 0x1008) // PIO/573
|
||||
#define BIU_EXP3_CTRL _MMIO32(IO_BASE | 0x100c) // PIO/debug
|
||||
#define BIU_DEV2_CTRL _MMIO32(IO_BASE | 0x1010) // BIOS ROM
|
||||
#define BIU_DEV4_CTRL _MMIO32(IO_BASE | 0x1014) // SPU
|
||||
#define BIU_DEV5_CTRL _MMIO32(IO_BASE | 0x1018) // CD-ROM
|
||||
#define BIU_EXP2_CTRL _MMIO32(IO_BASE | 0x101c) // PIO/debug
|
||||
#define BIU_COM_DELAY _MMIO32(IO_BASE | 0x1020)
|
||||
#define BIU_DEV0_ADDR _MMIO32(IO_BASE | 0x000) // PIO/573
|
||||
#define BIU_EXP2_ADDR _MMIO32(IO_BASE | 0x004) // PIO/debug
|
||||
#define BIU_DEV0_CTRL _MMIO32(IO_BASE | 0x008) // PIO/573
|
||||
#define BIU_EXP3_CTRL _MMIO32(IO_BASE | 0x00c) // PIO/debug
|
||||
#define BIU_DEV2_CTRL _MMIO32(IO_BASE | 0x010) // BIOS ROM
|
||||
#define BIU_DEV4_CTRL _MMIO32(IO_BASE | 0x014) // SPU
|
||||
#define BIU_DEV5_CTRL _MMIO32(IO_BASE | 0x018) // CD-ROM
|
||||
#define BIU_EXP2_CTRL _MMIO32(IO_BASE | 0x01c) // PIO/debug
|
||||
#define BIU_COM_DELAY _MMIO32(IO_BASE | 0x020)
|
||||
|
||||
/* Serial interfaces */
|
||||
|
||||
@ -123,11 +124,11 @@ typedef enum {
|
||||
|
||||
// SIO_DATA is a 32-bit register, but some emulators do not implement it
|
||||
// correctly and break if it's read more than 8 bits at a time.
|
||||
#define SIO_DATA(N) _MMIO8 ((IO_BASE | 0x1040) + (16 * (N)))
|
||||
#define SIO_STAT(N) _MMIO16((IO_BASE | 0x1044) + (16 * (N)))
|
||||
#define SIO_MODE(N) _MMIO16((IO_BASE | 0x1048) + (16 * (N)))
|
||||
#define SIO_CTRL(N) _MMIO16((IO_BASE | 0x104a) + (16 * (N)))
|
||||
#define SIO_BAUD(N) _MMIO16((IO_BASE | 0x104e) + (16 * (N)))
|
||||
#define SIO_DATA(N) _MMIO8 ((IO_BASE | 0x040) + (16 * (N)))
|
||||
#define SIO_STAT(N) _MMIO16((IO_BASE | 0x044) + (16 * (N)))
|
||||
#define SIO_MODE(N) _MMIO16((IO_BASE | 0x048) + (16 * (N)))
|
||||
#define SIO_CTRL(N) _MMIO16((IO_BASE | 0x04a) + (16 * (N)))
|
||||
#define SIO_BAUD(N) _MMIO16((IO_BASE | 0x04e) + (16 * (N)))
|
||||
|
||||
/* DRAM controller */
|
||||
|
||||
@ -142,7 +143,7 @@ typedef enum {
|
||||
DRAM_CTRL_SIZE_2MB = 1 << 11 // 2MB chips (8MB with MUL4)
|
||||
} DRAMControlFlag;
|
||||
|
||||
#define DRAM_CTRL _MMIO32(IO_BASE | 0x1060)
|
||||
#define DRAM_CTRL _MMIO32(IO_BASE | 0x060)
|
||||
|
||||
/* IRQ controller */
|
||||
|
||||
@ -161,8 +162,8 @@ typedef enum {
|
||||
IRQ_PIO = 10
|
||||
} IRQChannel;
|
||||
|
||||
#define IRQ_STAT _MMIO16(IO_BASE | 0x1070)
|
||||
#define IRQ_MASK _MMIO16(IO_BASE | 0x1074)
|
||||
#define IRQ_STAT _MMIO16(IO_BASE | 0x070)
|
||||
#define IRQ_MASK _MMIO16(IO_BASE | 0x074)
|
||||
|
||||
/* DMA */
|
||||
|
||||
@ -212,12 +213,12 @@ typedef enum {
|
||||
#define DMA_DICR_CH_ENABLE(dma) (1 << ((dma) + 16))
|
||||
#define DMA_DICR_CH_STAT(dma) (1 << ((dma) + 24))
|
||||
|
||||
#define DMA_MADR(N) _MMIO32((IO_BASE | 0x1080) + (16 * (N)))
|
||||
#define DMA_BCR(N) _MMIO32((IO_BASE | 0x1084) + (16 * (N)))
|
||||
#define DMA_CHCR(N) _MMIO32((IO_BASE | 0x1088) + (16 * (N)))
|
||||
#define DMA_MADR(N) _MMIO32((IO_BASE | 0x080) + (16 * (N)))
|
||||
#define DMA_BCR(N) _MMIO32((IO_BASE | 0x084) + (16 * (N)))
|
||||
#define DMA_CHCR(N) _MMIO32((IO_BASE | 0x088) + (16 * (N)))
|
||||
|
||||
#define DMA_DPCR _MMIO32(IO_BASE | 0x10f0)
|
||||
#define DMA_DICR _MMIO32(IO_BASE | 0x10f4)
|
||||
#define DMA_DPCR _MMIO32(IO_BASE | 0x0f0)
|
||||
#define DMA_DICR _MMIO32(IO_BASE | 0x0f4)
|
||||
|
||||
/* Timers */
|
||||
|
||||
@ -240,9 +241,9 @@ typedef enum {
|
||||
TIMER_CTRL_OVERFLOWED = 1 << 12
|
||||
} TimerControlFlag;
|
||||
|
||||
#define TIMER_VALUE(N) _MMIO32((IO_BASE | 0x1100) + (16 * (N)))
|
||||
#define TIMER_CTRL(N) _MMIO32((IO_BASE | 0x1104) + (16 * (N)))
|
||||
#define TIMER_RELOAD(N) _MMIO32((IO_BASE | 0x1108) + (16 * (N)))
|
||||
#define TIMER_VALUE(N) _MMIO32((IO_BASE | 0x100) + (16 * (N)))
|
||||
#define TIMER_CTRL(N) _MMIO32((IO_BASE | 0x104) + (16 * (N)))
|
||||
#define TIMER_RELOAD(N) _MMIO32((IO_BASE | 0x108) + (16 * (N)))
|
||||
|
||||
/* CD-ROM drive */
|
||||
|
||||
@ -299,12 +300,12 @@ typedef enum {
|
||||
CDROM_MODE_SPEED_2X = 1 << 7
|
||||
} CDROMModeFlag;
|
||||
|
||||
#define CDROM_STAT _MMIO8(IO_BASE | 0x1800)
|
||||
#define CDROM_CMD _MMIO8(IO_BASE | 0x1801)
|
||||
#define CDROM_DATA _MMIO8(IO_BASE | 0x1802)
|
||||
#define CDROM_IRQ _MMIO8(IO_BASE | 0x1803)
|
||||
#define CDROM_STAT _MMIO8(IO_BASE | 0x800)
|
||||
#define CDROM_CMD _MMIO8(IO_BASE | 0x801)
|
||||
#define CDROM_DATA _MMIO8(IO_BASE | 0x802)
|
||||
#define CDROM_IRQ _MMIO8(IO_BASE | 0x803)
|
||||
|
||||
#define CDROM_REG(N) _MMIO8((IO_BASE | 0x1800) + (N))
|
||||
#define CDROM_REG(N) _MMIO8((IO_BASE | 0x800) + (N))
|
||||
|
||||
/* GPU */
|
||||
|
||||
@ -321,8 +322,8 @@ typedef enum {
|
||||
GP1_STAT_FIELD_ODD = 1 << 31
|
||||
} GP1StatusFlag;
|
||||
|
||||
#define GPU_GP0 _MMIO32(IO_BASE | 0x1810)
|
||||
#define GPU_GP1 _MMIO32(IO_BASE | 0x1814)
|
||||
#define GPU_GP0 _MMIO32(IO_BASE | 0x810)
|
||||
#define GPU_GP1 _MMIO32(IO_BASE | 0x814)
|
||||
|
||||
/* MDEC */
|
||||
|
||||
@ -347,8 +348,8 @@ typedef enum {
|
||||
MDEC_CTRL_RESET = 1 << 31
|
||||
} MDECControlFlag;
|
||||
|
||||
#define MDEC0 _MMIO32(IO_BASE | 0x1820)
|
||||
#define MDEC1 _MMIO32(IO_BASE | 0x1824)
|
||||
#define MDEC0 _MMIO32(IO_BASE | 0x820)
|
||||
#define MDEC1 _MMIO32(IO_BASE | 0x824)
|
||||
|
||||
/* SPU */
|
||||
|
||||
@ -386,47 +387,47 @@ typedef enum {
|
||||
SPU_CTRL_ENABLE = 1 << 15
|
||||
} SPUControlFlag;
|
||||
|
||||
#define SPU_CH_VOL_L(N) _MMIO16((IO_BASE | 0x1c00) + (16 * (N)))
|
||||
#define SPU_CH_VOL_R(N) _MMIO16((IO_BASE | 0x1c02) + (16 * (N)))
|
||||
#define SPU_CH_FREQ(N) _MMIO16((IO_BASE | 0x1c04) + (16 * (N)))
|
||||
#define SPU_CH_ADDR(N) _MMIO16((IO_BASE | 0x1c06) + (16 * (N)))
|
||||
#define SPU_CH_ADSR1(N) _MMIO16((IO_BASE | 0x1c08) + (16 * (N)))
|
||||
#define SPU_CH_ADSR2(N) _MMIO16((IO_BASE | 0x1c0a) + (16 * (N)))
|
||||
#define SPU_CH_LOOP(N) _MMIO16((IO_BASE | 0x1c0e) + (16 * (N)))
|
||||
#define SPU_CH_VOL_L(N) _MMIO16((IO_BASE | 0xc00) + (16 * (N)))
|
||||
#define SPU_CH_VOL_R(N) _MMIO16((IO_BASE | 0xc02) + (16 * (N)))
|
||||
#define SPU_CH_FREQ(N) _MMIO16((IO_BASE | 0xc04) + (16 * (N)))
|
||||
#define SPU_CH_ADDR(N) _MMIO16((IO_BASE | 0xc06) + (16 * (N)))
|
||||
#define SPU_CH_ADSR1(N) _MMIO16((IO_BASE | 0xc08) + (16 * (N)))
|
||||
#define SPU_CH_ADSR2(N) _MMIO16((IO_BASE | 0xc0a) + (16 * (N)))
|
||||
#define SPU_CH_LOOP(N) _MMIO16((IO_BASE | 0xc0e) + (16 * (N)))
|
||||
|
||||
#define SPU_MASTER_VOL_L _MMIO16(IO_BASE | 0x1d80)
|
||||
#define SPU_MASTER_VOL_R _MMIO16(IO_BASE | 0x1d82)
|
||||
#define SPU_REVERB_VOL_L _MMIO16(IO_BASE | 0x1d84)
|
||||
#define SPU_REVERB_VOL_R _MMIO16(IO_BASE | 0x1d86)
|
||||
#define SPU_FLAG_ON1 _MMIO16(IO_BASE | 0x1d88)
|
||||
#define SPU_FLAG_ON2 _MMIO16(IO_BASE | 0x1d8a)
|
||||
#define SPU_FLAG_OFF1 _MMIO16(IO_BASE | 0x1d8c)
|
||||
#define SPU_FLAG_OFF2 _MMIO16(IO_BASE | 0x1d8e)
|
||||
#define SPU_FLAG_FM1 _MMIO16(IO_BASE | 0x1d90)
|
||||
#define SPU_FLAG_FM2 _MMIO16(IO_BASE | 0x1d92)
|
||||
#define SPU_FLAG_NOISE1 _MMIO16(IO_BASE | 0x1d94)
|
||||
#define SPU_FLAG_NOISE2 _MMIO16(IO_BASE | 0x1d96)
|
||||
#define SPU_FLAG_REVERB1 _MMIO16(IO_BASE | 0x1d98)
|
||||
#define SPU_FLAG_REVERB2 _MMIO16(IO_BASE | 0x1d9a)
|
||||
#define SPU_FLAG_STATUS1 _MMIO16(IO_BASE | 0x1d9c)
|
||||
#define SPU_FLAG_STATUS2 _MMIO16(IO_BASE | 0x1d9e)
|
||||
#define SPU_MASTER_VOL_L _MMIO16(IO_BASE | 0xd80)
|
||||
#define SPU_MASTER_VOL_R _MMIO16(IO_BASE | 0xd82)
|
||||
#define SPU_REVERB_VOL_L _MMIO16(IO_BASE | 0xd84)
|
||||
#define SPU_REVERB_VOL_R _MMIO16(IO_BASE | 0xd86)
|
||||
#define SPU_FLAG_ON1 _MMIO16(IO_BASE | 0xd88)
|
||||
#define SPU_FLAG_ON2 _MMIO16(IO_BASE | 0xd8a)
|
||||
#define SPU_FLAG_OFF1 _MMIO16(IO_BASE | 0xd8c)
|
||||
#define SPU_FLAG_OFF2 _MMIO16(IO_BASE | 0xd8e)
|
||||
#define SPU_FLAG_FM1 _MMIO16(IO_BASE | 0xd90)
|
||||
#define SPU_FLAG_FM2 _MMIO16(IO_BASE | 0xd92)
|
||||
#define SPU_FLAG_NOISE1 _MMIO16(IO_BASE | 0xd94)
|
||||
#define SPU_FLAG_NOISE2 _MMIO16(IO_BASE | 0xd96)
|
||||
#define SPU_FLAG_REVERB1 _MMIO16(IO_BASE | 0xd98)
|
||||
#define SPU_FLAG_REVERB2 _MMIO16(IO_BASE | 0xd9a)
|
||||
#define SPU_FLAG_STATUS1 _MMIO16(IO_BASE | 0xd9c)
|
||||
#define SPU_FLAG_STATUS2 _MMIO16(IO_BASE | 0xd9e)
|
||||
|
||||
#define SPU_REVERB_ADDR _MMIO16(IO_BASE | 0x1da2)
|
||||
#define SPU_IRQ_ADDR _MMIO16(IO_BASE | 0x1da4)
|
||||
#define SPU_ADDR _MMIO16(IO_BASE | 0x1da6)
|
||||
#define SPU_DATA _MMIO16(IO_BASE | 0x1da8)
|
||||
#define SPU_CTRL _MMIO16(IO_BASE | 0x1daa)
|
||||
#define SPU_DMA_CTRL _MMIO16(IO_BASE | 0x1dac)
|
||||
#define SPU_STAT _MMIO16(IO_BASE | 0x1dae)
|
||||
#define SPU_REVERB_ADDR _MMIO16(IO_BASE | 0xda2)
|
||||
#define SPU_IRQ_ADDR _MMIO16(IO_BASE | 0xda4)
|
||||
#define SPU_ADDR _MMIO16(IO_BASE | 0xda6)
|
||||
#define SPU_DATA _MMIO16(IO_BASE | 0xda8)
|
||||
#define SPU_CTRL _MMIO16(IO_BASE | 0xdaa)
|
||||
#define SPU_DMA_CTRL _MMIO16(IO_BASE | 0xdac)
|
||||
#define SPU_STAT _MMIO16(IO_BASE | 0xdae)
|
||||
|
||||
#define SPU_CDDA_VOL_L _MMIO16(IO_BASE | 0x1db0)
|
||||
#define SPU_CDDA_VOL_R _MMIO16(IO_BASE | 0x1db2)
|
||||
#define SPU_EXT_VOL_L _MMIO16(IO_BASE | 0x1db4)
|
||||
#define SPU_EXT_VOL_R _MMIO16(IO_BASE | 0x1db6)
|
||||
#define SPU_VOL_STAT_L _MMIO16(IO_BASE | 0x1db8)
|
||||
#define SPU_VOL_STAT_R _MMIO16(IO_BASE | 0x1dba)
|
||||
#define SPU_CDDA_VOL_L _MMIO16(IO_BASE | 0xdb0)
|
||||
#define SPU_CDDA_VOL_R _MMIO16(IO_BASE | 0xdb2)
|
||||
#define SPU_EXT_VOL_L _MMIO16(IO_BASE | 0xdb4)
|
||||
#define SPU_EXT_VOL_R _MMIO16(IO_BASE | 0xdb6)
|
||||
#define SPU_VOL_STAT_L _MMIO16(IO_BASE | 0xdb8)
|
||||
#define SPU_VOL_STAT_R _MMIO16(IO_BASE | 0xdba)
|
||||
|
||||
#define SPU_REVERB_BASE _ADDR16(IO_BASE | 0x1dc0)
|
||||
#define SPU_REVERB_BASE _ADDR16(IO_BASE | 0xdc0)
|
||||
|
||||
/* System 573 base hardware */
|
||||
|
||||
|
@ -144,8 +144,8 @@ bool Sound::initFromVAGHeader(const VAGHeader *header, uint32_t ramOffset) {
|
||||
return false;
|
||||
|
||||
offset = ramOffset / 8;
|
||||
sampleRate = (util::swapEndian(header->sampleRate) << 12) / 44100;
|
||||
length = util::swapEndian(header->length);
|
||||
sampleRate = (__builtin_bswap32(header->sampleRate) << 12) / 44100;
|
||||
length = __builtin_bswap32(header->length);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -17,18 +17,18 @@ void PlaceholderScreen::draw(Context &ctx, bool active) const {
|
||||
);
|
||||
}
|
||||
|
||||
MessageScreen::MessageScreen(void)
|
||||
MessageBoxScreen::MessageBoxScreen(void)
|
||||
: ModalScreen(MODAL_WIDTH, MODAL_HEIGHT_FULL), _numButtons(0),
|
||||
_buttonIndexOffset(0), _locked(false) {}
|
||||
|
||||
void MessageScreen::show(Context &ctx, bool goBack) {
|
||||
void MessageBoxScreen::show(Context &ctx, bool goBack) {
|
||||
ModalScreen::show(ctx, goBack);
|
||||
|
||||
_activeButton = 0;
|
||||
_buttonAnim.setValue(_getButtonWidth());
|
||||
}
|
||||
|
||||
void MessageScreen::draw(Context &ctx, bool active) const {
|
||||
void MessageBoxScreen::draw(Context &ctx, bool active) const {
|
||||
ModalScreen::draw(ctx, active);
|
||||
|
||||
if (!active || !_numButtons)
|
||||
@ -77,7 +77,7 @@ void MessageScreen::draw(Context &ctx, bool active) const {
|
||||
}
|
||||
}
|
||||
|
||||
void MessageScreen::update(Context &ctx) {
|
||||
void MessageBoxScreen::update(Context &ctx) {
|
||||
if (_locked)
|
||||
return;
|
||||
|
||||
@ -117,7 +117,7 @@ HexEntryScreen::HexEntryScreen(void)
|
||||
: _bufferLength(0) {}
|
||||
|
||||
void HexEntryScreen::show(Context &ctx, bool goBack) {
|
||||
MessageScreen::show(ctx, goBack);
|
||||
MessageBoxScreen::show(ctx, goBack);
|
||||
|
||||
_buttonIndexOffset = _bufferLength * 2;
|
||||
__builtin_memset(_buffer, 0, _bufferLength);
|
||||
@ -127,7 +127,7 @@ void HexEntryScreen::show(Context &ctx, bool goBack) {
|
||||
}
|
||||
|
||||
void HexEntryScreen::draw(Context &ctx, bool active) const {
|
||||
MessageScreen::draw(ctx, active);
|
||||
MessageBoxScreen::draw(ctx, active);
|
||||
|
||||
if (!active)
|
||||
return;
|
||||
@ -214,7 +214,7 @@ void HexEntryScreen::update(Context &ctx) {
|
||||
} else {
|
||||
int oldActive = _activeButton;
|
||||
|
||||
MessageScreen::update(ctx);
|
||||
MessageBoxScreen::update(ctx);
|
||||
|
||||
// Update the cursor's position if necessary.
|
||||
if (oldActive != _activeButton) {
|
||||
|
@ -15,7 +15,7 @@ public:
|
||||
void draw(Context &ctx, bool active) const;
|
||||
};
|
||||
|
||||
class MessageScreen : public ModalScreen {
|
||||
class MessageBoxScreen : public ModalScreen {
|
||||
private:
|
||||
util::Tween<int, util::QuadOutEasing> _buttonAnim;
|
||||
|
||||
@ -30,13 +30,13 @@ protected:
|
||||
const char *_buttons[3];
|
||||
|
||||
public:
|
||||
MessageScreen(void);
|
||||
MessageBoxScreen(void);
|
||||
virtual void show(Context &ctx, bool goBack = false);
|
||||
virtual void draw(Context &ctx, bool active = true) const;
|
||||
virtual void update(Context &ctx);
|
||||
};
|
||||
|
||||
class HexEntryScreen : public MessageScreen {
|
||||
class HexEntryScreen : public MessageBoxScreen {
|
||||
private:
|
||||
int _charIndex;
|
||||
|
||||
|
141
src/util.cpp
141
src/util.cpp
@ -66,8 +66,9 @@ void Logger::log(const char *format, ...) {
|
||||
|
||||
/* CRC calculation */
|
||||
|
||||
static constexpr uint16_t _CRC8_POLY = 0x8c;
|
||||
static constexpr uint8_t _CRC8_POLY = 0x8c;
|
||||
static constexpr uint16_t _CRC16_POLY = 0x1021;
|
||||
static constexpr uint32_t _CRC32_POLY = 0xedb88320;
|
||||
|
||||
uint8_t dsCRC8(const uint8_t *data, size_t length) {
|
||||
uint8_t crc = 0;
|
||||
@ -98,7 +99,7 @@ uint16_t zsCRC16(const uint8_t *data, size_t length) {
|
||||
uint16_t temp = crc;
|
||||
|
||||
crc <<= 1;
|
||||
if (temp & 0x8000)
|
||||
if (temp & (1 << 15))
|
||||
crc ^= _CRC16_POLY;
|
||||
}
|
||||
}
|
||||
@ -106,6 +107,42 @@ uint16_t zsCRC16(const uint8_t *data, size_t length) {
|
||||
return (crc ^ 0xffff) & 0xffff;
|
||||
}
|
||||
|
||||
uint32_t zipCRC32(const uint8_t *data, size_t length, uint32_t crc) {
|
||||
// This CRC32 implementation uses a lookup table cached in the scratchpad
|
||||
// area in order to improve performance.
|
||||
auto table = reinterpret_cast<const uint32_t *>(CACHE_BASE);
|
||||
crc = ~crc;
|
||||
|
||||
for (; length; length--) {
|
||||
crc >>= 8;
|
||||
crc ^= table[(crc ^ *(data++)) & 0xff];
|
||||
}
|
||||
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
void initZipCRC32(void) {
|
||||
auto table = reinterpret_cast<uint32_t *>(CACHE_BASE);
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
uint32_t crc = i;
|
||||
|
||||
for (int bit = 8; bit; bit--) {
|
||||
uint32_t temp = crc;
|
||||
|
||||
crc >>= 1;
|
||||
if (temp & 1)
|
||||
crc ^= _CRC32_POLY;
|
||||
}
|
||||
|
||||
*(table++) = crc;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" uint32_t mz_crc32(uint32_t crc, const uint8_t *data, size_t length) {
|
||||
return zipCRC32(data, length, crc);
|
||||
}
|
||||
|
||||
/* String manipulation */
|
||||
|
||||
static const char _HEX_CHARSET[]{ "0123456789ABCDEF" };
|
||||
@ -132,7 +169,8 @@ size_t hexToString(char *output, const uint8_t *input, size_t length, char sep)
|
||||
}
|
||||
|
||||
size_t serialNumberToString(char *output, const uint8_t *input) {
|
||||
uint32_t value = input[0] | (input[1] << 8) | (input[2] << 16) | (input[3] << 24);
|
||||
uint32_t value =
|
||||
input[0] | (input[1] << 8) | (input[2] << 16) | (input[3] << 24);
|
||||
|
||||
return sprintf(output, "%04d-%04d", (value / 10000) % 10000, value % 10000);
|
||||
}
|
||||
@ -143,7 +181,8 @@ static const char _TRACE_ID_CHECKSUM_CHARSET[]{ "0X987654321" };
|
||||
|
||||
size_t traceIDToString(char *output, const uint8_t *input) {
|
||||
uint16_t high = (input[0] << 8) | input[1];
|
||||
uint32_t low = (input[2] << 24) | (input[3] << 16) | (input[4] << 8) | input[5];
|
||||
uint32_t low =
|
||||
(input[2] << 24) | (input[3] << 16) | (input[4] << 8) | input[5];
|
||||
|
||||
size_t length = sprintf(&output[1], "%02d-%04d", high % 100, low % 10000);
|
||||
|
||||
@ -182,4 +221,98 @@ size_t encodeBase41(char *output, const uint8_t *input, size_t length) {
|
||||
return outLength;
|
||||
}
|
||||
|
||||
/* Error strings */
|
||||
|
||||
const char *const CART_DRIVER_ERROR_NAMES[]{
|
||||
"NO_ERROR", // = 0
|
||||
"UNSUPPORTED_OP",
|
||||
"DS2401_NO_RESP",
|
||||
"DS2401_ID_ERROR",
|
||||
"X76_NACK",
|
||||
"X76_POLL_FAIL",
|
||||
"X76_VERIFY_FAIL",
|
||||
"ZS01_NACK",
|
||||
"ZS01_ERROR",
|
||||
"ZS01_CRC_MISMATCH"
|
||||
};
|
||||
|
||||
const char *const IDE_DEVICE_ERROR_NAMES[]{
|
||||
"NO_ERROR", // = 0
|
||||
"UNSUPPORTED_OP",
|
||||
"STATUS_TIMEOUT",
|
||||
"DRIVE_ERROR",
|
||||
"INCOMPLETE_DATA",
|
||||
"CHECKSUM_MISMATCH"
|
||||
};
|
||||
|
||||
const char *const FATFS_ERROR_NAMES[]{
|
||||
"OK", // = 0
|
||||
"DISK_ERR",
|
||||
"INT_ERR",
|
||||
"NOT_READY",
|
||||
"NO_FILE",
|
||||
"NO_PATH",
|
||||
"INVALID_NAME",
|
||||
"DENIED",
|
||||
"EXIST",
|
||||
"INVALID_OBJECT",
|
||||
"WRITE_PROTECTED",
|
||||
"INVALID_DRIVE",
|
||||
"NOT_ENABLED",
|
||||
"NO_FILESYSTEM",
|
||||
"MKFS_ABORTED",
|
||||
"TIMEOUT",
|
||||
"LOCKED",
|
||||
"NOT_ENOUGH_CORE",
|
||||
"TOO_MANY_OPEN_FILES",
|
||||
"INVALID_PARAMETER"
|
||||
};
|
||||
|
||||
const char *const MINIZ_ERROR_NAMES[]{
|
||||
"VERSION_ERROR",
|
||||
"BUF_ERROR",
|
||||
"MEM_ERROR",
|
||||
"DATA_ERROR",
|
||||
"STREAM_ERROR",
|
||||
"ERRNO",
|
||||
"OK", // = 0
|
||||
"STREAM_END",
|
||||
"NEED_DICT"
|
||||
};
|
||||
|
||||
const char *const MINIZ_ZIP_ERROR_NAMES[]{
|
||||
"NO_ERROR", // = 0
|
||||
"UNDEFINED_ERROR",
|
||||
"TOO_MANY_FILES",
|
||||
"FILE_TOO_LARGE",
|
||||
"UNSUPPORTED_METHOD",
|
||||
"UNSUPPORTED_ENCRYPTION",
|
||||
"UNSUPPORTED_FEATURE",
|
||||
"FAILED_FINDING_CENTRAL_DIR",
|
||||
"NOT_AN_ARCHIVE",
|
||||
"INVALID_HEADER_OR_CORRUPTED",
|
||||
"UNSUPPORTED_MULTIDISK",
|
||||
"DECOMPRESSION_FAILED",
|
||||
"COMPRESSION_FAILED",
|
||||
"UNEXPECTED_DECOMPRESSED_SIZE",
|
||||
"CRC_CHECK_FAILED",
|
||||
"UNSUPPORTED_CDIR_SIZE",
|
||||
"ALLOC_FAILED",
|
||||
"FILE_OPEN_FAILED",
|
||||
"FILE_CREATE_FAILED",
|
||||
"FILE_WRITE_FAILED",
|
||||
"FILE_READ_FAILED",
|
||||
"FILE_CLOSE_FAILED",
|
||||
"FILE_SEEK_FAILED",
|
||||
"FILE_STAT_FAILED",
|
||||
"INVALID_PARAMETER",
|
||||
"INVALID_FILENAME",
|
||||
"BUF_TOO_SMALL",
|
||||
"INTERNAL_ERROR",
|
||||
"FILE_NOT_FOUND",
|
||||
"ARCHIVE_TOO_LARGE",
|
||||
"VALIDATION_FAILED",
|
||||
"WRITE_CALLBACK_FAILED"
|
||||
};
|
||||
|
||||
}
|
||||
|
23
src/util.hpp
23
src/util.hpp
@ -43,19 +43,6 @@ template<typename T> static inline T roundUpToMultiple(T value, T length) {
|
||||
return diff ? (value - diff + length) : value;
|
||||
}
|
||||
|
||||
static inline uint16_t swapEndian(uint16_t value) {
|
||||
value = ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline uint32_t swapEndian(uint32_t value) {
|
||||
value = ((value & 0x0000ffff) << 16) | ((value & 0xffff0000) >> 16);
|
||||
value = ((value & 0x00ff00ff) << 8) | ((value & 0xff00ff00) >> 8);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
template<typename T, typename X> static inline void assertAligned(X *ptr) {
|
||||
assert(!(reinterpret_cast<uintptr_t>(ptr) % alignof(T)));
|
||||
}
|
||||
@ -260,12 +247,22 @@ extern Logger logger;
|
||||
|
||||
uint8_t dsCRC8(const uint8_t *data, size_t length);
|
||||
uint16_t zsCRC16(const uint8_t *data, size_t length);
|
||||
uint32_t zipCRC32(const uint8_t *data, size_t length, uint32_t crc = 0);
|
||||
void initZipCRC32(void);
|
||||
|
||||
size_t hexToString(char *output, const uint8_t *input, size_t length, char sep = 0);
|
||||
size_t serialNumberToString(char *output, const uint8_t *input);
|
||||
size_t traceIDToString(char *output, const uint8_t *input);
|
||||
size_t encodeBase41(char *output, const uint8_t *input, size_t length);
|
||||
|
||||
/* Error strings */
|
||||
|
||||
extern const char *const CART_DRIVER_ERROR_NAMES[];
|
||||
extern const char *const IDE_DEVICE_ERROR_NAMES[];
|
||||
extern const char *const FATFS_ERROR_NAMES[];
|
||||
extern const char *const MINIZ_ERROR_NAMES[];
|
||||
extern const char *const MINIZ_ZIP_ERROR_NAMES[];
|
||||
|
||||
}
|
||||
|
||||
//#define LOG(...) util::logger.log(__VA_ARGS__)
|
||||
|
32
src/utilerror.hpp
Normal file
32
src/utilerror.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cartio.hpp"
|
||||
#include "ide.hpp"
|
||||
#include "util.hpp"
|
||||
#include "vendor/ff.h"
|
||||
#include "vendor/miniz.h"
|
||||
|
||||
namespace util {
|
||||
|
||||
static inline const char *getErrorString(cart::DriverError error) {
|
||||
return CART_DRIVER_ERROR_NAMES[error];
|
||||
}
|
||||
|
||||
static inline const char *getErrorString(ide::DeviceError error) {
|
||||
return IDE_DEVICE_ERROR_NAMES[error];
|
||||
}
|
||||
|
||||
static inline const char *getErrorString(FRESULT error) {
|
||||
return FATFS_ERROR_NAMES[error];
|
||||
}
|
||||
|
||||
static inline const char *getErrorString(int error) {
|
||||
return MINIZ_ERROR_NAMES[error - MZ_VERSION_ERROR];
|
||||
}
|
||||
|
||||
static inline const char *getErrorString(mz_zip_error error) {
|
||||
return MINIZ_ZIP_ERROR_NAMES[error];
|
||||
}
|
||||
|
||||
}
|
2
src/vendor/vendorconfig.h
vendored
2
src/vendor/vendorconfig.h
vendored
@ -46,6 +46,8 @@
|
||||
#define MINIZ_NO_ARCHIVE_WRITING_APIS
|
||||
#define MINIZ_NO_STDIO
|
||||
#define MINIZ_NO_TIME
|
||||
#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES
|
||||
#define USE_EXTERNAL_MZCRC
|
||||
|
||||
/* printf configuration */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user