mirror of
https://github.com/spicyjpeg/573in1.git
synced 2025-03-01 07:20:42 +01:00
Add splash screen and FAQ/troubleshooting page
This commit is contained in:
parent
e9b389a82f
commit
57139b87b5
16
README.md
16
README.md
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img alt="573in1 logo" src="doc/assets/logo.png" width="512" height="336" />
|
<img alt="573in1 logo" src="doc/assets/logo.png" width="512" />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
573in1 is a full-featured homebrew maintenance and troubleshooting tool, game
|
573in1 is a full-featured homebrew maintenance and troubleshooting tool, game
|
||||||
@ -43,17 +43,17 @@ instructions. **Reading the documentation before proceeding is highly**
|
|||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img alt="Main menu" src="doc/assets/mainMenu.png" width="320" height="240" />
|
<img alt="Main menu" src="doc/assets/mainMenu.png" width="320" />
|
||||||
<img alt="Cartridge information screen" src="doc/assets/cartInfo.png"
|
<img alt="Cartridge information screen" src="doc/assets/cartInfo.png"
|
||||||
width="320" height="240" />
|
width="320" />
|
||||||
<img alt="Cartridge system ID editor" src="doc/assets/editSystemID.png"
|
<img alt="Cartridge system ID editor" src="doc/assets/editSystemID.png"
|
||||||
width="320" height="240" />
|
width="320" />
|
||||||
<img alt="Storage device information screen" src="doc/assets/storageInfo.png"
|
<img alt="Storage device information screen" src="doc/assets/storageInfo.png"
|
||||||
width="320" height="240" />
|
width="320" />
|
||||||
<img alt="IDE drive file picker" src="doc/assets/ideDrivePicker.png"
|
<img alt="IDE drive file picker" src="doc/assets/ideDrivePicker.png"
|
||||||
width="320" height="240" />
|
width="320" />
|
||||||
<img alt="Monitor test pattern" src="doc/assets/monitorTestPattern.png"
|
<img alt="Monitor test pattern" src="doc/assets/monitorTestPattern.png"
|
||||||
width="320" height="240" />
|
width="320" />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## Project status
|
## Project status
|
||||||
@ -78,6 +78,8 @@ to lowest priority:
|
|||||||
flash or a PCMCIA card, allowing the 573 BIOS to boot them automatically even
|
flash or a PCMCIA card, allowing the 573 BIOS to boot them automatically even
|
||||||
with no CD-ROM drive present.
|
with no CD-ROM drive present.
|
||||||
- Cleaning up the codebase, which currently contains *many* bad practices.
|
- Cleaning up the codebase, which currently contains *many* bad practices.
|
||||||
|
- Adding support for JVS bus scanning and using JVS I/O boards in place of the
|
||||||
|
JAMMA button inputs.
|
||||||
- Adding UTF-8 support to the font and text rendering code. This is a rather low
|
- Adding UTF-8 support to the font and text rendering code. This is a rather low
|
||||||
priority feature, but it would allow 573in1 to be translated to other
|
priority feature, but it would allow 573in1 to be translated to other
|
||||||
languages.
|
languages.
|
||||||
|
BIN
doc/assets/buttonMapping.png
Normal file
BIN
doc/assets/buttonMapping.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
67
doc/faq.md
Normal file
67
doc/faq.md
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
|
||||||
|
# FAQ and troubleshooting
|
||||||
|
|
||||||
|
## Running 573in1
|
||||||
|
|
||||||
|
### I cannot get past the BIOS "hardware error" screen and into the main menu
|
||||||
|
|
||||||
|
- Make sure the disc image has been burned correctly (and not by e.g. dragging
|
||||||
|
the image file onto the disc). The disc should appear as `573IN1_xxxxx` and
|
||||||
|
contain a bunch of files named `README.TXT`, `PSX.EXE` and so on.
|
||||||
|
- Try using a different disc and/or another CD-ROM drive. A list of drives known
|
||||||
|
to be compatible with the stock System 573 BIOS can be found
|
||||||
|
[here](https://psx-spx.consoledev.net/konamisystem573/#known-working-replacement-drives).
|
||||||
|
- Ensure the BIOS is not reporting an actual hardware error with the 573. A
|
||||||
|
CD-ROM error will result in `CDR BAD` being displayed, while other errors will
|
||||||
|
be reported under the PCB location of the chip that failed (e.g. `18E BAD` for
|
||||||
|
a JVS MCU error). A list of BIOS errors can be found
|
||||||
|
[here](https://psx-spx.consoledev.net/konamisystem573/#boot-sequence).
|
||||||
|
|
||||||
|
### I get an error about a missing file or the CD-ROM being incorrect
|
||||||
|
|
||||||
|
- You have booted into the game currently installed on the 573's internal flash
|
||||||
|
rather than from the disc. Turn off DIP switch 4 (the rightmost one) and power
|
||||||
|
cycle the 573.
|
||||||
|
|
||||||
|
## Security cartridges
|
||||||
|
|
||||||
|
### My cartridge does not get recognized
|
||||||
|
|
||||||
|
- Make sure the cartridge's contacts are clean and the security cartridge
|
||||||
|
connector on the 573 has no bent pins and is not worn out, corroded or
|
||||||
|
otherwise damaged.
|
||||||
|
|
||||||
|
## IDE devices
|
||||||
|
|
||||||
|
### My IDE cable does not fit into the 573
|
||||||
|
|
||||||
|
- The 573 motherboard has pin 20 populated on the IDE connector, but most cables
|
||||||
|
use it as a keying pin (as per later versions of the IDE specification) and
|
||||||
|
thus have it blocked off. You may either try to find another cable or drill a
|
||||||
|
small hole in the cable's connector.
|
||||||
|
- You can also cut or desolder pin 20 on the 573, however this is not
|
||||||
|
recommended.
|
||||||
|
|
||||||
|
### My IDE drive, CF card or adapter does not show up
|
||||||
|
|
||||||
|
- Try using a different drive or adapter. Some CF cards, SD card adapters and
|
||||||
|
IDE-to-SATA converters are known to be problematic.
|
||||||
|
|
||||||
|
### My IDE drive, CF card or adapter shows up but is unreadable
|
||||||
|
|
||||||
|
- Ensure the drive supports LBA addressing. All CF cards, SD card adapters and
|
||||||
|
the vast majority of hard drives do, however older hard drives (typically ones
|
||||||
|
with a capacity lower than 8 GB or manufactured before the mid 1990s) may only
|
||||||
|
support CHS addressing.
|
||||||
|
- Ensure the drive is formatted with a single FAT12, FAT16, FAT32 or exFAT
|
||||||
|
partition. Other filesystems such as NTFS or ext4 are not supported.
|
||||||
|
|
||||||
|
## Miscellaneous
|
||||||
|
|
||||||
|
### How do I obtain more information about an error that happened?
|
||||||
|
|
||||||
|
- You may press the test button on your 573 or cabinet at any time to toggle the
|
||||||
|
log window, which will contain detailed information about errors.
|
||||||
|
- If an IDE hard drive is connected you can also take screenshots by holding
|
||||||
|
down the test button. Screenshots are saved to the `573in1` directory in the
|
||||||
|
root of the filesystem.
|
@ -8,7 +8,7 @@
|
|||||||
- TODO: ~~[Installing games and working with flash memory devices](flash.md)~~
|
- TODO: ~~[Installing games and working with flash memory devices](flash.md)~~
|
||||||
- TODO: ~~[Connecting an IDE hard drive](hdd.md)~~
|
- TODO: ~~[Connecting an IDE hard drive](hdd.md)~~
|
||||||
- TODO: ~~[Installing 573in1 as a BIOS ROM](bios.md)~~
|
- TODO: ~~[Installing 573in1 as a BIOS ROM](bios.md)~~
|
||||||
- TODO: ~~[FAQ and troubleshooting](faq.md)~~
|
- [FAQ and troubleshooting](faq.md)
|
||||||
|
|
||||||
## Development resources
|
## Development resources
|
||||||
|
|
||||||
|
@ -326,11 +326,6 @@ void Context::drawGradientRectD(
|
|||||||
cmd[7] = gp0_xy(x + width, y + height);
|
cmd[7] = gp0_xy(x + width, y + height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Context::drawBackdrop(Color color, BlendMode blendMode) {
|
|
||||||
setBlendMode(blendMode, true);
|
|
||||||
drawRect(0, 0, width, height, color, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Image class */
|
/* Image class */
|
||||||
|
|
||||||
void Image::initFromVRAMRect(
|
void Image::initFromVRAMRect(
|
||||||
|
@ -143,6 +143,14 @@ public:
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void drawBackdrop(Color color) {
|
||||||
|
drawRect(0, 0, width, height, color);
|
||||||
|
}
|
||||||
|
inline void drawBackdrop(Color color, BlendMode blendMode) {
|
||||||
|
setBlendMode(blendMode, true);
|
||||||
|
drawRect(0, 0, width, height, color, true);
|
||||||
|
}
|
||||||
|
|
||||||
void setResolution(
|
void setResolution(
|
||||||
VideoMode mode, int width, int height, bool forceInterlace = false,
|
VideoMode mode, int width, int height, bool forceInterlace = false,
|
||||||
bool sideBySide = false
|
bool sideBySide = false
|
||||||
@ -169,7 +177,6 @@ public:
|
|||||||
int x, int y, int width, int height, Color top, Color middle,
|
int x, int y, int width, int height, Color top, Color middle,
|
||||||
Color bottom, bool blend = false
|
Color bottom, bool blend = false
|
||||||
);
|
);
|
||||||
void drawBackdrop(Color color, BlendMode blendMode);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Image class */
|
/* Image class */
|
||||||
|
@ -180,6 +180,8 @@ void FileIOManager::closeResourceFile(void) {
|
|||||||
|
|
||||||
static constexpr size_t _WORKER_STACK_SIZE = 0x20000;
|
static constexpr size_t _WORKER_STACK_SIZE = 0x20000;
|
||||||
|
|
||||||
|
static constexpr int _SPLASH_SCREEN_TIMEOUT = 5;
|
||||||
|
|
||||||
App::App(ui::Context &ctx)
|
App::App(ui::Context &ctx)
|
||||||
#ifdef ENABLE_LOG_BUFFER
|
#ifdef ENABLE_LOG_BUFFER
|
||||||
: _logOverlay(_logBuffer),
|
: _logOverlay(_logBuffer),
|
||||||
@ -238,6 +240,7 @@ void App::_loadResources(void) {
|
|||||||
res.loadTIM(_background.tile, "assets/textures/background.tim");
|
res.loadTIM(_background.tile, "assets/textures/background.tim");
|
||||||
res.loadTIM(_ctx.font.image, "assets/textures/font.tim");
|
res.loadTIM(_ctx.font.image, "assets/textures/font.tim");
|
||||||
res.loadStruct(_ctx.font.metrics, "assets/textures/font.metrics");
|
res.loadStruct(_ctx.font.metrics, "assets/textures/font.metrics");
|
||||||
|
res.loadTIM(_splashOverlay.image, "assets/textures/splash.tim");
|
||||||
res.loadStruct(_ctx.colors, "assets/app.palette");
|
res.loadStruct(_ctx.colors, "assets/app.palette");
|
||||||
res.loadData(_stringTable, "assets/app.strings");
|
res.loadData(_stringTable, "assets/app.strings");
|
||||||
|
|
||||||
@ -303,6 +306,36 @@ bool App::_takeScreenshot(void) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void App::_updateOverlays(void) {
|
||||||
|
// Date and time overlay
|
||||||
|
static char dateString[24];
|
||||||
|
util::Date date;
|
||||||
|
|
||||||
|
io::getRTCTime(date);
|
||||||
|
date.toString(dateString);
|
||||||
|
|
||||||
|
_textOverlay.leftText = dateString;
|
||||||
|
|
||||||
|
// Splash screen overlay
|
||||||
|
int timeout = _ctx.gpuCtx.refreshRate * _SPLASH_SCREEN_TIMEOUT;
|
||||||
|
|
||||||
|
if ((_workerStatus.status == WORKER_DONE) || (_ctx.time > timeout))
|
||||||
|
_splashOverlay.hide(_ctx);
|
||||||
|
|
||||||
|
// Log overlay
|
||||||
|
if (
|
||||||
|
_ctx.buttons.released(ui::BTN_DEBUG) &&
|
||||||
|
!_ctx.buttons.longReleased(ui::BTN_DEBUG)
|
||||||
|
)
|
||||||
|
_logOverlay.toggle(_ctx);
|
||||||
|
|
||||||
|
// Screenshot overlay
|
||||||
|
if (_ctx.buttons.longPressed(ui::BTN_DEBUG)) {
|
||||||
|
if (_takeScreenshot())
|
||||||
|
_screenshotOverlay.animate(_ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void App::_runWorker(
|
void App::_runWorker(
|
||||||
bool (App::*func)(void), ui::Screen &next, bool goBack, bool playSound
|
bool (App::*func)(void), ui::Screen &next, bool goBack, bool playSound
|
||||||
) {
|
) {
|
||||||
@ -361,40 +394,27 @@ void App::_interruptHandler(void) {
|
|||||||
_fileIO.loadResourceFile(nullptr);
|
_fileIO.loadResourceFile(nullptr);
|
||||||
_loadResources();
|
_loadResources();
|
||||||
|
|
||||||
char dateString[24];
|
_textOverlay.rightText = "v" VERSION_STRING;
|
||||||
|
|
||||||
_textOverlay.leftText = dateString;
|
|
||||||
_textOverlay.rightText = "v" VERSION_STRING;
|
|
||||||
_screenshotOverlay.callback = [](ui::Context &ctx) -> bool {
|
|
||||||
return APP->_takeScreenshot();
|
|
||||||
};
|
|
||||||
|
|
||||||
_ctx.backgrounds[0] = &_background;
|
_ctx.backgrounds[0] = &_background;
|
||||||
_ctx.backgrounds[1] = &_textOverlay;
|
_ctx.backgrounds[1] = &_textOverlay;
|
||||||
|
_ctx.overlays[0] = &_splashOverlay;
|
||||||
#ifdef ENABLE_LOG_BUFFER
|
#ifdef ENABLE_LOG_BUFFER
|
||||||
_ctx.overlays[0] = &_logOverlay;
|
_ctx.overlays[1] = &_logOverlay;
|
||||||
#endif
|
#endif
|
||||||
_ctx.overlays[1] = &_screenshotOverlay;
|
_ctx.overlays[2] = &_screenshotOverlay;
|
||||||
|
|
||||||
#ifdef ENABLE_AUTOBOOT
|
|
||||||
_runWorker(&App::_ideInitWorker, _warningScreen);
|
_runWorker(&App::_ideInitWorker, _warningScreen);
|
||||||
#else
|
|
||||||
// If autoboot is disabled, show the warning screen before initializing the
|
|
||||||
// drives in order to give them enough time to spin up.
|
|
||||||
_runWorker(nullptr, _warningScreen);
|
|
||||||
#endif
|
|
||||||
_setupInterrupts();
|
_setupInterrupts();
|
||||||
|
|
||||||
|
_splashOverlay.show(_ctx);
|
||||||
_ctx.sounds[ui::SOUND_STARTUP].play();
|
_ctx.sounds[ui::SOUND_STARTUP].play();
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
util::Date date;
|
|
||||||
|
|
||||||
io::getRTCTime(date);
|
|
||||||
date.toString(dateString);
|
|
||||||
|
|
||||||
_ctx.update();
|
_ctx.update();
|
||||||
_ctx.draw();
|
_updateOverlays();
|
||||||
|
|
||||||
|
_ctx.draw();
|
||||||
switchThreadImmediate(&_workerThread);
|
switchThreadImmediate(&_workerThread);
|
||||||
_ctx.gpuCtx.flip();
|
_ctx.gpuCtx.flip();
|
||||||
}
|
}
|
||||||
|
@ -180,12 +180,13 @@ private:
|
|||||||
ResolutionScreen _resolutionScreen;
|
ResolutionScreen _resolutionScreen;
|
||||||
AboutScreen _aboutScreen;
|
AboutScreen _aboutScreen;
|
||||||
|
|
||||||
|
ui::TiledBackground _background;
|
||||||
|
ui::TextOverlay _textOverlay;
|
||||||
|
ui::SplashOverlay _splashOverlay;
|
||||||
#ifdef ENABLE_LOG_BUFFER
|
#ifdef ENABLE_LOG_BUFFER
|
||||||
util::LogBuffer _logBuffer;
|
util::LogBuffer _logBuffer;
|
||||||
ui::LogOverlay _logOverlay;
|
ui::LogOverlay _logOverlay;
|
||||||
#endif
|
#endif
|
||||||
ui::TiledBackground _background;
|
|
||||||
ui::TextOverlay _textOverlay;
|
|
||||||
ui::ScreenshotOverlay _screenshotOverlay;
|
ui::ScreenshotOverlay _screenshotOverlay;
|
||||||
|
|
||||||
ui::Context &_ctx;
|
ui::Context &_ctx;
|
||||||
@ -214,6 +215,7 @@ private:
|
|||||||
char *output, size_t length, const char *path, int maxIndex = 9999
|
char *output, size_t length, const char *path, int maxIndex = 9999
|
||||||
);
|
);
|
||||||
bool _takeScreenshot(void);
|
bool _takeScreenshot(void);
|
||||||
|
void _updateOverlays(void);
|
||||||
void _runWorker(
|
void _runWorker(
|
||||||
bool (App::*func)(void), ui::Screen &next, bool goBack = false,
|
bool (App::*func)(void), ui::Screen &next, bool goBack = false,
|
||||||
bool playSound = false
|
bool playSound = false
|
||||||
|
@ -239,6 +239,7 @@ void QRCodeScreen::show(ui::Context &ctx, bool goBack) {
|
|||||||
_title = STR("QRCodeScreen.title");
|
_title = STR("QRCodeScreen.title");
|
||||||
_prompt = STR("QRCodeScreen.prompt");
|
_prompt = STR("QRCodeScreen.prompt");
|
||||||
|
|
||||||
|
_image = &_code;
|
||||||
_imageScale = _QR_CODE_SCALE;
|
_imageScale = _QR_CODE_SCALE;
|
||||||
_imagePadding = _QR_CODE_SCALE * _QR_CODE_PADDING;
|
_imagePadding = _QR_CODE_SCALE * _QR_CODE_PADDING;
|
||||||
_backdropColor = 0xffffff;
|
_backdropColor = 0xffffff;
|
||||||
|
@ -45,6 +45,9 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class QRCodeScreen : public ui::ImageScreen {
|
class QRCodeScreen : public ui::ImageScreen {
|
||||||
|
private:
|
||||||
|
gpu::Image _code;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool valid;
|
bool valid;
|
||||||
|
|
||||||
@ -52,14 +55,14 @@ public:
|
|||||||
: valid(false) {}
|
: valid(false) {}
|
||||||
|
|
||||||
inline bool generateCode(const char *textInput) {
|
inline bool generateCode(const char *textInput) {
|
||||||
if (!gpu::generateQRCode(_image, 960, 256, textInput))
|
if (!gpu::generateQRCode(_code, 960, 256, textInput))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
valid = true;
|
valid = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
inline bool generateCode(const uint8_t *binaryInput, size_t length) {
|
inline bool generateCode(const uint8_t *binaryInput, size_t length) {
|
||||||
if (!gpu::generateQRCode(_image, 960, 256, binaryInput, length))
|
if (!gpu::generateQRCode(_code, 960, 256, binaryInput, length))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
valid = true;
|
valid = true;
|
||||||
|
@ -303,9 +303,7 @@ void TestPatternScreen::_drawTextOverlay(
|
|||||||
|
|
||||||
void TestPatternScreen::draw(ui::Context &ctx, bool active) const {
|
void TestPatternScreen::draw(ui::Context &ctx, bool active) const {
|
||||||
_newLayer(ctx, 0, 0, ctx.gpuCtx.width, ctx.gpuCtx.height);
|
_newLayer(ctx, 0, 0, ctx.gpuCtx.width, ctx.gpuCtx.height);
|
||||||
ctx.gpuCtx.drawRect(
|
ctx.gpuCtx.drawBackdrop(_BACKGROUND_COLOR);
|
||||||
0, 0, ctx.gpuCtx.width, ctx.gpuCtx.height, _BACKGROUND_COLOR
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestPatternScreen::update(ui::Context &ctx) {
|
void TestPatternScreen::update(ui::Context &ctx) {
|
||||||
|
@ -234,11 +234,6 @@ void Context::draw(void) {
|
|||||||
void Context::update(void) {
|
void Context::update(void) {
|
||||||
buttons.update();
|
buttons.update();
|
||||||
|
|
||||||
for (auto layer : overlays) {
|
|
||||||
if (layer)
|
|
||||||
layer->update(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto screen = getCurrentScreen();
|
auto screen = getCurrentScreen();
|
||||||
|
|
||||||
if (screen)
|
if (screen)
|
||||||
@ -294,22 +289,56 @@ void TextOverlay::draw(Context &ctx, bool active) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogOverlay::LogOverlay(util::LogBuffer &buffer)
|
void SplashOverlay::draw(Context &ctx, bool active) const {
|
||||||
: _buffer(buffer) {
|
int brightness = _fadeAnim.getValue(ctx.time);
|
||||||
_slideAnim.setValue(0);
|
|
||||||
|
if (!brightness)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Backdrop
|
||||||
|
_newLayer(ctx, 0, 0, ctx.gpuCtx.width, ctx.gpuCtx.height);
|
||||||
|
ctx.gpuCtx.drawBackdrop(
|
||||||
|
gp0_rgb(brightness, brightness, brightness), GP0_BLEND_SUBTRACT
|
||||||
|
);
|
||||||
|
|
||||||
|
if (brightness < 0xff)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Image
|
||||||
|
int x = (ctx.gpuCtx.width - image.width) / 2;
|
||||||
|
int y = (ctx.gpuCtx.height - image.height) / 2;
|
||||||
|
|
||||||
|
image.draw(ctx.gpuCtx, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SplashOverlay::show(Context &ctx) {
|
||||||
|
if (!_fadeAnim.getTargetValue())
|
||||||
|
#if 0
|
||||||
|
_fadeAnim.setValue(ctx.time, 0, 0xff, SPEED_SLOWEST);
|
||||||
|
#else
|
||||||
|
_fadeAnim.setValue(0xff);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void SplashOverlay::hide(Context &ctx) {
|
||||||
|
if (_fadeAnim.getTargetValue())
|
||||||
|
_fadeAnim.setValue(ctx.time, 0xff, 0, SPEED_SLOWEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogOverlay::draw(Context &ctx, bool active) const {
|
void LogOverlay::draw(Context &ctx, bool active) const {
|
||||||
int offset = _slideAnim.getValue(ctx.time);
|
int offset = _slideAnim.getValue(ctx.time);
|
||||||
|
|
||||||
if (!offset)
|
if (!offset)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Backdrop
|
||||||
_newLayer(
|
_newLayer(
|
||||||
ctx, 0, offset - ctx.gpuCtx.height, ctx.gpuCtx.width,
|
ctx, 0, offset - ctx.gpuCtx.height, ctx.gpuCtx.width,
|
||||||
ctx.gpuCtx.height
|
ctx.gpuCtx.height
|
||||||
);
|
);
|
||||||
ctx.gpuCtx.drawBackdrop(ctx.colors[COLOR_BACKDROP], GP0_BLEND_SUBTRACT);
|
ctx.gpuCtx.drawBackdrop(ctx.colors[COLOR_BACKDROP], GP0_BLEND_SUBTRACT);
|
||||||
|
|
||||||
|
// Text
|
||||||
int screenHeight = ctx.gpuCtx.height - SCREEN_MIN_MARGIN_Y * 2;
|
int screenHeight = ctx.gpuCtx.height - SCREEN_MIN_MARGIN_Y * 2;
|
||||||
int linesShown = screenHeight / ctx.font.metrics.lineHeight;
|
int linesShown = screenHeight / ctx.font.metrics.lineHeight;
|
||||||
|
|
||||||
@ -330,15 +359,11 @@ void LogOverlay::draw(Context &ctx, bool active) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogOverlay::update(Context &ctx) {
|
void LogOverlay::toggle(Context &ctx) {
|
||||||
if (
|
bool shown = !_slideAnim.getTargetValue();
|
||||||
ctx.buttons.released(BTN_DEBUG) && !ctx.buttons.longReleased(BTN_DEBUG)
|
|
||||||
) {
|
|
||||||
bool shown = !_slideAnim.getTargetValue();
|
|
||||||
|
|
||||||
_slideAnim.setValue(ctx.time, shown ? ctx.gpuCtx.height : 0, SPEED_SLOW);
|
_slideAnim.setValue(ctx.time, shown ? ctx.gpuCtx.height : 0, SPEED_SLOW);
|
||||||
ctx.sounds[shown ? SOUND_ENTER : SOUND_EXIT].play();
|
ctx.sounds[shown ? SOUND_ENTER : SOUND_EXIT].play();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenshotOverlay::draw(Context &ctx, bool active) const {
|
void ScreenshotOverlay::draw(Context &ctx, bool active) const {
|
||||||
@ -353,13 +378,9 @@ void ScreenshotOverlay::draw(Context &ctx, bool active) const {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenshotOverlay::update(Context &ctx) {
|
void ScreenshotOverlay::animate(Context &ctx) {
|
||||||
if (ctx.buttons.longPressed(BTN_DEBUG)) {
|
_flashAnim.setValue(ctx.time, 0xff, 0, SPEED_SLOW);
|
||||||
if (callback(ctx)) {
|
ctx.sounds[ui::SOUND_SCREENSHOT].play();
|
||||||
_flashAnim.setValue(ctx.time, 0xff, 0, SPEED_SLOW);
|
|
||||||
ctx.sounds[ui::SOUND_SCREENSHOT].play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Base screen classes */
|
/* Base screen classes */
|
||||||
@ -381,15 +402,17 @@ void AnimatedScreen::hide(Context &ctx, bool goBack) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BackdropScreen::show(Context &ctx, bool goBack) {
|
void BackdropScreen::show(Context &ctx, bool goBack) {
|
||||||
_backdropAnim.setValue(ctx.time, 0, 0x50, SPEED_FAST);
|
if (!_fadeAnim.getTargetValue())
|
||||||
|
_fadeAnim.setValue(ctx.time, 0, 0x50, SPEED_FAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackdropScreen::hide(Context &ctx, bool goBack) {
|
void BackdropScreen::hide(Context &ctx, bool goBack) {
|
||||||
_backdropAnim.setValue(ctx.time, 0x50, 0, SPEED_FAST);
|
if (_fadeAnim.getTargetValue())
|
||||||
|
_fadeAnim.setValue(ctx.time, 0x50, 0, SPEED_FAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackdropScreen::draw(Context &ctx, bool active) const {
|
void BackdropScreen::draw(Context &ctx, bool active) const {
|
||||||
int brightness = _backdropAnim.getValue(ctx.time);
|
int brightness = _fadeAnim.getValue(ctx.time);
|
||||||
|
|
||||||
if (!brightness)
|
if (!brightness)
|
||||||
return;
|
return;
|
||||||
|
@ -64,7 +64,8 @@ enum Sound {
|
|||||||
enum AnimationSpeed {
|
enum AnimationSpeed {
|
||||||
SPEED_FASTEST = 10,
|
SPEED_FASTEST = 10,
|
||||||
SPEED_FAST = 15,
|
SPEED_FAST = 15,
|
||||||
SPEED_SLOW = 20
|
SPEED_SLOW = 20,
|
||||||
|
SPEED_SLOWEST = 30
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr int SCREEN_MARGIN_X = 16;
|
static constexpr int SCREEN_MARGIN_X = 16;
|
||||||
@ -214,7 +215,6 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void draw(Context &ctx, bool active = true) const {}
|
virtual void draw(Context &ctx, bool active = true) const {}
|
||||||
virtual void update(Context &ctx) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TiledBackground : public Layer {
|
class TiledBackground : public Layer {
|
||||||
@ -234,15 +234,29 @@ public:
|
|||||||
void draw(Context &ctx, bool active = true) const;
|
void draw(Context &ctx, bool active = true) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SplashOverlay : public Layer {
|
||||||
|
private:
|
||||||
|
util::Tween<int, util::QuadOutEasing> _fadeAnim;
|
||||||
|
|
||||||
|
public:
|
||||||
|
gpu::Image image;
|
||||||
|
|
||||||
|
void draw(Context &ctx, bool active = true) const;
|
||||||
|
void show(Context &ctx);
|
||||||
|
void hide(Context &ctx);
|
||||||
|
};
|
||||||
|
|
||||||
class LogOverlay : public Layer {
|
class LogOverlay : public Layer {
|
||||||
private:
|
private:
|
||||||
util::LogBuffer &_buffer;
|
util::LogBuffer &_buffer;
|
||||||
util::Tween<int, util::QuadOutEasing> _slideAnim;
|
util::Tween<int, util::QuadOutEasing> _slideAnim;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LogOverlay(util::LogBuffer &buffer);
|
inline LogOverlay(util::LogBuffer &buffer)
|
||||||
|
: _buffer(buffer) {}
|
||||||
|
|
||||||
void draw(Context &ctx, bool active = true) const;
|
void draw(Context &ctx, bool active = true) const;
|
||||||
void update(Context &ctx);
|
void toggle(Context &ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ScreenshotOverlay : public Layer {
|
class ScreenshotOverlay : public Layer {
|
||||||
@ -250,13 +264,8 @@ private:
|
|||||||
util::Tween<int, util::QuadOutEasing> _flashAnim;
|
util::Tween<int, util::QuadOutEasing> _flashAnim;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool (*callback)(ui::Context &ctx);
|
|
||||||
|
|
||||||
inline ScreenshotOverlay(void)
|
|
||||||
: callback(nullptr) {}
|
|
||||||
|
|
||||||
void draw(Context &ctx, bool active = true) const;
|
void draw(Context &ctx, bool active = true) const;
|
||||||
void update(Context &ctx);
|
void animate(Context &ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Base screen classes */
|
/* Base screen classes */
|
||||||
@ -286,7 +295,7 @@ public:
|
|||||||
|
|
||||||
class BackdropScreen : public Screen {
|
class BackdropScreen : public Screen {
|
||||||
private:
|
private:
|
||||||
util::Tween<int, util::LinearEasing> _backdropAnim;
|
util::Tween<int, util::LinearEasing> _fadeAnim;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void show(Context &ctx, bool goBack = false);
|
virtual void show(Context &ctx, bool goBack = false);
|
||||||
|
@ -24,13 +24,6 @@ namespace ui {
|
|||||||
|
|
||||||
/* Common screens */
|
/* Common screens */
|
||||||
|
|
||||||
void PlaceholderScreen::draw(Context &ctx, bool active) const {
|
|
||||||
_newLayer(ctx, 0, 0, ctx.gpuCtx.width, ctx.gpuCtx.height);
|
|
||||||
ctx.gpuCtx.drawRect(
|
|
||||||
0, 0, ctx.gpuCtx.width, ctx.gpuCtx.height, ctx.colors[COLOR_WINDOW2]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
TextScreen::TextScreen(void)
|
TextScreen::TextScreen(void)
|
||||||
: _title(nullptr), _body(nullptr), _prompt(nullptr) {}
|
: _title(nullptr), _body(nullptr), _prompt(nullptr) {}
|
||||||
|
|
||||||
@ -128,16 +121,17 @@ void TextScreen::update(Context &ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ImageScreen::ImageScreen(void)
|
ImageScreen::ImageScreen(void)
|
||||||
: _imageScale(1), _imagePadding(0), _title(nullptr), _prompt(nullptr) {}
|
: _image(nullptr), _imageScale(1), _imagePadding(0), _title(nullptr),
|
||||||
|
_prompt(nullptr) {}
|
||||||
|
|
||||||
void ImageScreen::draw(Context &ctx, bool active) const {
|
void ImageScreen::draw(Context &ctx, bool active) const {
|
||||||
_newLayer(ctx, 0, 0, ctx.gpuCtx.width, ctx.gpuCtx.height);
|
_newLayer(ctx, 0, 0, ctx.gpuCtx.width, ctx.gpuCtx.height);
|
||||||
|
|
||||||
if (_image.width && _image.height) {
|
if (_image) {
|
||||||
int x = ctx.gpuCtx.width / 2;
|
int x = ctx.gpuCtx.width / 2;
|
||||||
int y = ctx.gpuCtx.height / 2;
|
int y = ctx.gpuCtx.height / 2;
|
||||||
int width = _image.width * _imageScale / 2;
|
int width = _image->width * _imageScale / 2;
|
||||||
int height = _image.height * _imageScale / 2;
|
int height = _image->height * _imageScale / 2;
|
||||||
|
|
||||||
if (_prompt)
|
if (_prompt)
|
||||||
y -= (SCREEN_PROMPT_HEIGHT - ctx.font.metrics.lineHeight) / 2;
|
y -= (SCREEN_PROMPT_HEIGHT - ctx.font.metrics.lineHeight) / 2;
|
||||||
@ -153,9 +147,12 @@ void ImageScreen::draw(Context &ctx, bool active) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Image
|
// Image
|
||||||
_image.drawScaled(
|
if (_imageScale > 1)
|
||||||
ctx.gpuCtx, x - width - 1, y - height - 1, width * 2, height * 2
|
_image->drawScaled(
|
||||||
);
|
ctx.gpuCtx, x - width - 1, y - height - 1, width * 2, height * 2
|
||||||
|
);
|
||||||
|
else
|
||||||
|
_image->draw(ctx.gpuCtx, x - width, y - height);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Text
|
// Text
|
||||||
|
@ -25,11 +25,6 @@ namespace ui {
|
|||||||
|
|
||||||
/* Common screens */
|
/* Common screens */
|
||||||
|
|
||||||
class PlaceholderScreen : public AnimatedScreen {
|
|
||||||
public:
|
|
||||||
void draw(Context &ctx, bool active) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TextScreen : public AnimatedScreen {
|
class TextScreen : public AnimatedScreen {
|
||||||
private:
|
private:
|
||||||
util::Tween<int, util::QuadOutEasing> _scrollAnim;
|
util::Tween<int, util::QuadOutEasing> _scrollAnim;
|
||||||
@ -54,7 +49,7 @@ public:
|
|||||||
|
|
||||||
class ImageScreen : public AnimatedScreen {
|
class ImageScreen : public AnimatedScreen {
|
||||||
protected:
|
protected:
|
||||||
gpu::Image _image;
|
gpu::Image *_image;
|
||||||
int _imageScale, _imagePadding;
|
int _imageScale, _imagePadding;
|
||||||
gpu::Color _backdropColor;
|
gpu::Color _backdropColor;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user