mirror of
https://github.com/spicyjpeg/573in1.git
synced 2025-02-02 12:37:19 +01:00
Add screen resolution switcher, minor cleanups
This commit is contained in:
parent
36b09d5865
commit
d5c1f0065b
@ -79,6 +79,7 @@ target_compile_definitions(
|
|||||||
ENABLE_CART_MENU=1
|
ENABLE_CART_MENU=1
|
||||||
#ENABLE_X76F100_DRIVER=1
|
#ENABLE_X76F100_DRIVER=1
|
||||||
ENABLE_DUMMY_DRIVER=1
|
ENABLE_DUMMY_DRIVER=1
|
||||||
|
ENABLE_LOGGING=1
|
||||||
ENABLE_I2C_LOGGING=1
|
ENABLE_I2C_LOGGING=1
|
||||||
,
|
,
|
||||||
#ENABLE_ARGV=1
|
#ENABLE_ARGV=1
|
||||||
@ -86,6 +87,7 @@ target_compile_definitions(
|
|||||||
ENABLE_CART_MENU=1
|
ENABLE_CART_MENU=1
|
||||||
#ENABLE_X76F100_DRIVER=1
|
#ENABLE_X76F100_DRIVER=1
|
||||||
#ENABLE_DUMMY_DRIVER=1
|
#ENABLE_DUMMY_DRIVER=1
|
||||||
|
ENABLE_LOGGING=1
|
||||||
#ENABLE_I2C_LOGGING=1
|
#ENABLE_I2C_LOGGING=1
|
||||||
>
|
>
|
||||||
)
|
)
|
||||||
|
@ -221,6 +221,10 @@
|
|||||||
"name": "Restore flash, PCMCIA cards or RTC from dump",
|
"name": "Restore flash, PCMCIA cards or RTC from dump",
|
||||||
"prompt": "Restore the contents of the internal ROMs or any PCMCIA cards from the IDE hard drive or CF card connected as secondary drive (if any)."
|
"prompt": "Restore the contents of the internal ROMs or any PCMCIA cards from the IDE hard drive or CF card connected as secondary drive (if any)."
|
||||||
},
|
},
|
||||||
|
"setResolution": {
|
||||||
|
"name": "Change screen resolution",
|
||||||
|
"prompt": "Switch to a different screen resolution and aspect ratio."
|
||||||
|
},
|
||||||
"about": {
|
"about": {
|
||||||
"name": "About this tool",
|
"name": "About this tool",
|
||||||
"prompt": "View information about this tool, including open source licenses."
|
"prompt": "View information about this tool, including open source licenses."
|
||||||
@ -255,6 +259,22 @@
|
|||||||
"itemPrompt": "{RIGHT_ARROW} Press {START_BUTTON} to select, hold {LEFT_BUTTON}{RIGHT_BUTTON} + {START_BUTTON} to go back"
|
"itemPrompt": "{RIGHT_ARROW} Press {START_BUTTON} to select, hold {LEFT_BUTTON}{RIGHT_BUTTON} + {START_BUTTON} to go back"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"ResolutionScreen": {
|
||||||
|
"title": "{CART_ICON} Change screen resolution",
|
||||||
|
"prompt": "Select a resolution appropriate for your monitor or upscaler setup. Note that interlaced modes may be subject to flickering.",
|
||||||
|
"itemPrompt": "{RIGHT_ARROW} Press {START_BUTTON} to select, hold {LEFT_BUTTON}{RIGHT_BUTTON} + {START_BUTTON} to go back",
|
||||||
|
|
||||||
|
"320x240p": "320x240 (4:3), progressive",
|
||||||
|
"320x240i": "320x240 (4:3), interlaced (line doubled)",
|
||||||
|
"368x240p": "368x240 (~16:10), progressive",
|
||||||
|
"368x240i": "368x240 (~16:10), interlaced (line doubled)",
|
||||||
|
"512x240p": "512x240 (~20:9), progressive",
|
||||||
|
"512x240i": "512x240 (~20:9), interlaced (line doubled)",
|
||||||
|
"640x240p": "640x240 (24:9), progressive",
|
||||||
|
"640x240i": "640x240 (24:9), interlaced (line doubled)",
|
||||||
|
"640x480i": "640x480 (4:3), interlaced"
|
||||||
|
},
|
||||||
|
|
||||||
"SystemIDEntryScreen": {
|
"SystemIDEntryScreen": {
|
||||||
"title": "Edit system identifier",
|
"title": "Edit system identifier",
|
||||||
"body": "Enter the new digital I/O board's identifier. To obtain the ID of another board, run this tool on its respective system.\n\nUse {LEFT_BUTTON}{RIGHT_BUTTON} to move between digits, hold {START_BUTTON} and use {LEFT_BUTTON}{RIGHT_BUTTON} to edit the highlighted digit.",
|
"body": "Enter the new digital I/O board's identifier. To obtain the ID of another board, run this tool on its respective system.\n\nUse {LEFT_BUTTON}{RIGHT_BUTTON} to move between digits, hold {START_BUTTON} and use {LEFT_BUTTON}{RIGHT_BUTTON} to edit the highlighted digit.",
|
||||||
|
@ -156,7 +156,7 @@ void App::_interruptHandler(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::run(void) {
|
[[noreturn]] void App::run(void) {
|
||||||
LOG("starting app @ 0x%08x", this);
|
LOG("starting app @ 0x%08x", this);
|
||||||
|
|
||||||
_ctx.screenData = this;
|
_ctx.screenData = this;
|
||||||
@ -165,8 +165,10 @@ void App::run(void) {
|
|||||||
_loadResources();
|
_loadResources();
|
||||||
|
|
||||||
_backgroundLayer.text = "v" VERSION_STRING;
|
_backgroundLayer.text = "v" VERSION_STRING;
|
||||||
_ctx.setBackgroundLayer(_backgroundLayer);
|
_ctx.background = &_backgroundLayer;
|
||||||
_ctx.setOverlayLayer(_overlayLayer);
|
#ifdef ENABLE_LOGGING
|
||||||
|
_ctx.overlay = &_overlayLayer;
|
||||||
|
#endif
|
||||||
_ctx.show(_workerStatusScreen);
|
_ctx.show(_workerStatusScreen);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "app/main.hpp"
|
#include "app/main.hpp"
|
||||||
#include "app/misc.hpp"
|
#include "app/misc.hpp"
|
||||||
#include "app/cartunlock.hpp"
|
#include "app/cartunlock.hpp"
|
||||||
|
#include "ps1/system.h"
|
||||||
#include "cart.hpp"
|
#include "cart.hpp"
|
||||||
#include "cartdata.hpp"
|
#include "cartdata.hpp"
|
||||||
#include "cartio.hpp"
|
#include "cartio.hpp"
|
||||||
@ -56,6 +57,7 @@ class App {
|
|||||||
friend class WarningScreen;
|
friend class WarningScreen;
|
||||||
friend class ButtonMappingScreen;
|
friend class ButtonMappingScreen;
|
||||||
friend class MainMenuScreen;
|
friend class MainMenuScreen;
|
||||||
|
friend class ResolutionScreen;
|
||||||
friend class AboutScreen;
|
friend class AboutScreen;
|
||||||
friend class CartInfoScreen;
|
friend class CartInfoScreen;
|
||||||
friend class UnlockKeyScreen;
|
friend class UnlockKeyScreen;
|
||||||
@ -73,6 +75,7 @@ private:
|
|||||||
WarningScreen _warningScreen;
|
WarningScreen _warningScreen;
|
||||||
ButtonMappingScreen _buttonMappingScreen;
|
ButtonMappingScreen _buttonMappingScreen;
|
||||||
MainMenuScreen _mainMenuScreen;
|
MainMenuScreen _mainMenuScreen;
|
||||||
|
ResolutionScreen _resolutionScreen;
|
||||||
AboutScreen _aboutScreen;
|
AboutScreen _aboutScreen;
|
||||||
CartInfoScreen _cartInfoScreen;
|
CartInfoScreen _cartInfoScreen;
|
||||||
UnlockKeyScreen _unlockKeyScreen;
|
UnlockKeyScreen _unlockKeyScreen;
|
||||||
@ -132,7 +135,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
~App(void);
|
~App(void);
|
||||||
void run(void);
|
[[noreturn]] void run(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define APP (reinterpret_cast<App *>(ctx.screenData))
|
#define APP (reinterpret_cast<App *>(ctx.screenData))
|
||||||
|
@ -402,9 +402,7 @@ enum DumpBank {
|
|||||||
BANK_NONE_16BIT = -2
|
BANK_NONE_16BIT = -2
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr int _NUM_DUMP_REGIONS = 5;
|
static const DumpRegion _DUMP_REGIONS[]{
|
||||||
|
|
||||||
static const DumpRegion _DUMP_REGIONS[_NUM_DUMP_REGIONS]{
|
|
||||||
{
|
{
|
||||||
.prompt = "App.romDumpWorker.dumpBIOS"_h,
|
.prompt = "App.romDumpWorker.dumpBIOS"_h,
|
||||||
.path = EXTERNAL_DATA_DIR "/dump%d/bios.bin",
|
.path = EXTERNAL_DATA_DIR "/dump%d/bios.bin",
|
||||||
@ -468,7 +466,7 @@ bool App::_romDumpWorker(void) {
|
|||||||
if (!_fileProvider.createDirectory(dirPath))
|
if (!_fileProvider.createDirectory(dirPath))
|
||||||
goto _initError;
|
goto _initError;
|
||||||
|
|
||||||
for (int i = 0; i < _NUM_DUMP_REGIONS; i++) {
|
for (int i = 0; i < util::countOf(_DUMP_REGIONS); i++) {
|
||||||
auto ®ion = _DUMP_REGIONS[i];
|
auto ®ion = _DUMP_REGIONS[i];
|
||||||
|
|
||||||
// Skip PCMCIA slots if a card is not inserted.
|
// Skip PCMCIA slots if a card is not inserted.
|
||||||
|
@ -13,10 +13,9 @@ public:
|
|||||||
void (CartActionsScreen::*target)(ui::Context &ctx);
|
void (CartActionsScreen::*target)(ui::Context &ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr int _NUM_SYSTEM_ID_ACTIONS = 8;
|
static constexpr int _NUM_SYSTEM_ID_ACTIONS = 3;
|
||||||
static constexpr int _NUM_NO_SYSTEM_ID_ACTIONS = 5;
|
|
||||||
|
|
||||||
static const Action _ACTIONS[_NUM_SYSTEM_ID_ACTIONS]{
|
static const Action _ACTIONS[]{
|
||||||
{
|
{
|
||||||
.name = "CartActionsScreen.qrDump.name"_h,
|
.name = "CartActionsScreen.qrDump.name"_h,
|
||||||
.prompt = "CartActionsScreen.qrDump.prompt"_h,
|
.prompt = "CartActionsScreen.qrDump.prompt"_h,
|
||||||
@ -163,11 +162,11 @@ void CartActionsScreen::show(ui::Context &ctx, bool goBack) {
|
|||||||
_prompt = STRH(_ACTIONS[0].prompt);
|
_prompt = STRH(_ACTIONS[0].prompt);
|
||||||
_itemPrompt = STR("CartActionsScreen.itemPrompt");
|
_itemPrompt = STR("CartActionsScreen.itemPrompt");
|
||||||
|
|
||||||
_listLength = _NUM_NO_SYSTEM_ID_ACTIONS;
|
_listLength = util::countOf(_ACTIONS) - _NUM_SYSTEM_ID_ACTIONS;
|
||||||
|
|
||||||
if (APP->_parser) {
|
if (APP->_parser) {
|
||||||
if (APP->_parser->flags & cart::DATA_HAS_SYSTEM_ID)
|
if (APP->_parser->flags & cart::DATA_HAS_SYSTEM_ID)
|
||||||
_listLength = _NUM_SYSTEM_ID_ACTIONS;
|
_listLength = util::countOf(_ACTIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
ListScreen::show(ctx, goBack);
|
ListScreen::show(ctx, goBack);
|
||||||
|
106
src/app/main.cpp
106
src/app/main.cpp
@ -1,12 +1,13 @@
|
|||||||
|
|
||||||
#include "app/app.hpp"
|
#include "app/app.hpp"
|
||||||
#include "app/main.hpp"
|
#include "app/main.hpp"
|
||||||
|
#include "ps1/gpucmd.h"
|
||||||
#include "uibase.hpp"
|
#include "uibase.hpp"
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
|
|
||||||
/* Main menu screens */
|
/* Main menu screens */
|
||||||
|
|
||||||
static constexpr int WARNING_COOLDOWN = 15;
|
static constexpr int WARNING_COOLDOWN = 10;
|
||||||
|
|
||||||
void WarningScreen::show(ui::Context &ctx, bool goBack) {
|
void WarningScreen::show(ui::Context &ctx, bool goBack) {
|
||||||
_title = STR("WarningScreen.title");
|
_title = STR("WarningScreen.title");
|
||||||
@ -81,13 +82,7 @@ public:
|
|||||||
void (MainMenuScreen::*target)(ui::Context &ctx);
|
void (MainMenuScreen::*target)(ui::Context &ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef ENABLE_CART_MENU
|
static const MenuEntry _MENU_ENTRIES[]{
|
||||||
static constexpr int _NUM_MENU_ENTRIES = 5;
|
|
||||||
#else
|
|
||||||
static constexpr int _NUM_MENU_ENTRIES = 4;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const MenuEntry _MENU_ENTRIES[_NUM_MENU_ENTRIES]{
|
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_CART_MENU
|
#ifdef ENABLE_CART_MENU
|
||||||
.name = "MainMenuScreen.cartInfo.name"_h,
|
.name = "MainMenuScreen.cartInfo.name"_h,
|
||||||
@ -109,6 +104,10 @@ static const MenuEntry _MENU_ENTRIES[_NUM_MENU_ENTRIES]{
|
|||||||
.target = &MainMenuScreen::systemInfo
|
.target = &MainMenuScreen::systemInfo
|
||||||
}, {
|
}, {
|
||||||
#endif
|
#endif
|
||||||
|
.name = "MainMenuScreen.setResolution.name"_h,
|
||||||
|
.prompt = "MainMenuScreen.setResolution.prompt"_h,
|
||||||
|
.target = &MainMenuScreen::setResolution
|
||||||
|
}, {
|
||||||
.name = "MainMenuScreen.about.name"_h,
|
.name = "MainMenuScreen.about.name"_h,
|
||||||
.prompt = "MainMenuScreen.about.prompt"_h,
|
.prompt = "MainMenuScreen.about.prompt"_h,
|
||||||
.target = &MainMenuScreen::about
|
.target = &MainMenuScreen::about
|
||||||
@ -157,6 +156,10 @@ void MainMenuScreen::systemInfo(ui::Context &ctx) {
|
|||||||
//ctx.show(APP->systemInfoScreen, false, true);
|
//ctx.show(APP->systemInfoScreen, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainMenuScreen::setResolution(ui::Context &ctx) {
|
||||||
|
ctx.show(APP->_resolutionScreen, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
void MainMenuScreen::about(ui::Context &ctx) {
|
void MainMenuScreen::about(ui::Context &ctx) {
|
||||||
ctx.show(APP->_aboutScreen, false, true);
|
ctx.show(APP->_aboutScreen, false, true);
|
||||||
}
|
}
|
||||||
@ -176,7 +179,7 @@ void MainMenuScreen::show(ui::Context &ctx, bool goBack) {
|
|||||||
_prompt = STRH(_MENU_ENTRIES[0].prompt);
|
_prompt = STRH(_MENU_ENTRIES[0].prompt);
|
||||||
_itemPrompt = STR("MainMenuScreen.itemPrompt");
|
_itemPrompt = STR("MainMenuScreen.itemPrompt");
|
||||||
|
|
||||||
_listLength = _NUM_MENU_ENTRIES;
|
_listLength = util::countOf(_MENU_ENTRIES);
|
||||||
|
|
||||||
ListScreen::show(ctx, goBack);
|
ListScreen::show(ctx, goBack);
|
||||||
}
|
}
|
||||||
@ -191,6 +194,91 @@ void MainMenuScreen::update(ui::Context &ctx) {
|
|||||||
(this->*action.target)(ctx);
|
(this->*action.target)(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Resolution {
|
||||||
|
public:
|
||||||
|
util::Hash name;
|
||||||
|
int width, height;
|
||||||
|
bool forceInterlace;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const Resolution _RESOLUTIONS[]{
|
||||||
|
{
|
||||||
|
.name = "ResolutionScreen.320x240p"_h,
|
||||||
|
.width = 320,
|
||||||
|
.height = 240,
|
||||||
|
.forceInterlace = false
|
||||||
|
}, {
|
||||||
|
.name = "ResolutionScreen.320x240i"_h,
|
||||||
|
.width = 320,
|
||||||
|
.height = 240,
|
||||||
|
.forceInterlace = true
|
||||||
|
}, {
|
||||||
|
.name = "ResolutionScreen.368x240p"_h,
|
||||||
|
.width = 368,
|
||||||
|
.height = 240,
|
||||||
|
.forceInterlace = false
|
||||||
|
}, {
|
||||||
|
.name = "ResolutionScreen.368x240i"_h,
|
||||||
|
.width = 368,
|
||||||
|
.height = 240,
|
||||||
|
.forceInterlace = true
|
||||||
|
}, {
|
||||||
|
.name = "ResolutionScreen.512x240p"_h,
|
||||||
|
.width = 512,
|
||||||
|
.height = 240,
|
||||||
|
.forceInterlace = false
|
||||||
|
}, {
|
||||||
|
.name = "ResolutionScreen.512x240i"_h,
|
||||||
|
.width = 512,
|
||||||
|
.height = 240,
|
||||||
|
.forceInterlace = true
|
||||||
|
}, {
|
||||||
|
.name = "ResolutionScreen.640x240p"_h,
|
||||||
|
.width = 640,
|
||||||
|
.height = 240,
|
||||||
|
.forceInterlace = false
|
||||||
|
}, {
|
||||||
|
.name = "ResolutionScreen.640x240i"_h,
|
||||||
|
.width = 640,
|
||||||
|
.height = 240,
|
||||||
|
.forceInterlace = true
|
||||||
|
}, {
|
||||||
|
.name = "ResolutionScreen.640x480i"_h,
|
||||||
|
.width = 640,
|
||||||
|
.height = 480,
|
||||||
|
.forceInterlace = true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *ResolutionScreen::_getItemName(ui::Context &ctx, int index) const {
|
||||||
|
return STRH(_RESOLUTIONS[index].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResolutionScreen::show(ui::Context &ctx, bool goBack) {
|
||||||
|
_title = STR("ResolutionScreen.title");
|
||||||
|
_prompt = STR("ResolutionScreen.prompt");
|
||||||
|
_itemPrompt = STR("ResolutionScreen.itemPrompt");
|
||||||
|
|
||||||
|
_listLength = util::countOf(_RESOLUTIONS);
|
||||||
|
|
||||||
|
ListScreen::show(ctx, goBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResolutionScreen::update(ui::Context &ctx) {
|
||||||
|
auto &res = _RESOLUTIONS[_activeItem];
|
||||||
|
|
||||||
|
ListScreen::update(ctx);
|
||||||
|
|
||||||
|
if (ctx.buttons.pressed(ui::BTN_START)) {
|
||||||
|
if (!ctx.buttons.held(ui::BTN_LEFT) && !ctx.buttons.held(ui::BTN_RIGHT))
|
||||||
|
ctx.gpuCtx.setResolution(
|
||||||
|
GP1_MODE_NTSC, res.width, res.height, res.forceInterlace
|
||||||
|
);
|
||||||
|
|
||||||
|
ctx.show(APP->_mainMenuScreen, true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AboutScreen::show(ui::Context &ctx, bool goBack) {
|
void AboutScreen::show(ui::Context &ctx, bool goBack) {
|
||||||
_title = STR("AboutScreen.title");
|
_title = STR("AboutScreen.title");
|
||||||
_prompt = STR("AboutScreen.prompt");
|
_prompt = STR("AboutScreen.prompt");
|
||||||
|
@ -35,6 +35,7 @@ public:
|
|||||||
void dump(ui::Context &ctx);
|
void dump(ui::Context &ctx);
|
||||||
void restore(ui::Context &ctx);
|
void restore(ui::Context &ctx);
|
||||||
void systemInfo(ui::Context &ctx);
|
void systemInfo(ui::Context &ctx);
|
||||||
|
void setResolution(ui::Context &ctx);
|
||||||
void about(ui::Context &ctx);
|
void about(ui::Context &ctx);
|
||||||
void ejectCD(ui::Context &ctx);
|
void ejectCD(ui::Context &ctx);
|
||||||
void reboot(ui::Context &ctx);
|
void reboot(ui::Context &ctx);
|
||||||
@ -43,6 +44,15 @@ public:
|
|||||||
void update(ui::Context &ctx);
|
void update(ui::Context &ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ResolutionScreen : public ui::ListScreen {
|
||||||
|
protected:
|
||||||
|
const char *_getItemName(ui::Context &ctx, int index) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void show(ui::Context &ctx, bool goBack = false);
|
||||||
|
void update(ui::Context &ctx);
|
||||||
|
};
|
||||||
|
|
||||||
class AboutScreen : public ui::TextScreen {
|
class AboutScreen : public ui::TextScreen {
|
||||||
private:
|
private:
|
||||||
util::Data _text;
|
util::Data _text;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "vendor/miniz.h"
|
#include "vendor/miniz.h"
|
||||||
#include "cart.hpp"
|
#include "cart.hpp"
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
|
#include "utilerror.hpp"
|
||||||
|
|
||||||
namespace cart {
|
namespace cart {
|
||||||
|
|
||||||
@ -247,7 +248,7 @@ size_t Dump::toQRString(char *output) const {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (error != MZ_OK) {
|
if (error != MZ_OK) {
|
||||||
LOG("compression error, code=%d", error);
|
LOG("%s, ptr=0x%08x", util::getErrorString(error), this);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
LOG(
|
LOG(
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "cart.hpp"
|
#include "cart.hpp"
|
||||||
#include "cartdata.hpp"
|
#include "cartdata.hpp"
|
||||||
|
#include "util.hpp"
|
||||||
|
|
||||||
namespace cart {
|
namespace cart {
|
||||||
|
|
||||||
@ -211,9 +212,7 @@ public:
|
|||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr int _NUM_KNOWN_FORMATS = 11;
|
static const KnownFormat _KNOWN_FORMATS[]{
|
||||||
|
|
||||||
static const KnownFormat _KNOWN_FORMATS[_NUM_KNOWN_FORMATS]{
|
|
||||||
{
|
{
|
||||||
// Used by GCB48 (and possibly other games?)
|
// Used by GCB48 (and possibly other games?)
|
||||||
.name = "region only",
|
.name = "region only",
|
||||||
@ -337,7 +336,7 @@ Parser *newCartParser(Dump &dump, FormatType formatType, uint8_t flags) {
|
|||||||
|
|
||||||
Parser *newCartParser(Dump &dump) {
|
Parser *newCartParser(Dump &dump) {
|
||||||
// Try all formats from the most complex one to the simplest.
|
// Try all formats from the most complex one to the simplest.
|
||||||
for (int i = _NUM_KNOWN_FORMATS - 1; i >= 0; i--) {
|
for (int i = util::countOf(_KNOWN_FORMATS) - 1; i >= 0; i--) {
|
||||||
auto &format = _KNOWN_FORMATS[i];
|
auto &format = _KNOWN_FORMATS[i];
|
||||||
Parser *parser = newCartParser(dump, format.format, format.flags);
|
Parser *parser = newCartParser(dump, format.format, format.flags);
|
||||||
|
|
||||||
|
27
src/gpu.cpp
27
src/gpu.cpp
@ -56,11 +56,13 @@ size_t upload(const RectWH &rect, const void *data, bool wait) {
|
|||||||
|
|
||||||
/* Rendering context */
|
/* Rendering context */
|
||||||
|
|
||||||
void Context::_applyResolution(VideoMode mode, int shiftX, int shiftY) const {
|
void Context::_applyResolution(
|
||||||
|
VideoMode mode, bool forceInterlace, int shiftX, int shiftY
|
||||||
|
) const {
|
||||||
GP1HorizontalRes hres;
|
GP1HorizontalRes hres;
|
||||||
GP1VerticalRes vres;
|
GP1VerticalRes vres;
|
||||||
|
|
||||||
int span, is480;
|
int span, vdiv;
|
||||||
|
|
||||||
if (width < 320) {
|
if (width < 320) {
|
||||||
hres = GP1_HRES_256;
|
hres = GP1_HRES_256;
|
||||||
@ -80,17 +82,19 @@ void Context::_applyResolution(VideoMode mode, int shiftX, int shiftY) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (height <= 256) {
|
if (height <= 256) {
|
||||||
vres = GP1_VRES_256;
|
vres = GP1_VRES_256;
|
||||||
is480 = false;
|
vdiv = 1;
|
||||||
} else {
|
} else {
|
||||||
vres = GP1_VRES_512;
|
vres = GP1_VRES_512;
|
||||||
is480 = true;
|
vdiv = 2;
|
||||||
|
|
||||||
|
forceInterlace = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int x = shiftX + 0x760, offsetX = span / 2;
|
int x = shiftX + 0x760, offsetX = span >> 1;
|
||||||
int y = shiftY + (mode ? 0xa3 : 0x88), offsetY = height / (2 << is480);
|
int y = shiftY + (mode ? 0xa3 : 0x88), offsetY = height >> vdiv;
|
||||||
|
|
||||||
GPU_GP1 = gp1_fbMode(hres, vres, mode, is480, GP1_COLOR_16BPP);
|
GPU_GP1 = gp1_fbMode(hres, vres, mode, forceInterlace, GP1_COLOR_16BPP);
|
||||||
GPU_GP1 = gp1_fbRangeH(x - offsetX, x + offsetX);
|
GPU_GP1 = gp1_fbRangeH(x - offsetX, x + offsetX);
|
||||||
GPU_GP1 = gp1_fbRangeV(y - offsetY, y + offsetY);
|
GPU_GP1 = gp1_fbRangeV(y - offsetY, y + offsetY);
|
||||||
}
|
}
|
||||||
@ -114,7 +118,8 @@ void Context::flip(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Context::setResolution(
|
void Context::setResolution(
|
||||||
VideoMode mode, int _width, int _height, bool sideBySide
|
VideoMode mode, int _width, int _height, bool forceInterlace,
|
||||||
|
bool sideBySide
|
||||||
) {
|
) {
|
||||||
auto enable = disableInterrupts();
|
auto enable = disableInterrupts();
|
||||||
|
|
||||||
@ -143,7 +148,7 @@ void Context::setResolution(
|
|||||||
_currentListPtr = _buffers[0].displayList;
|
_currentListPtr = _buffers[0].displayList;
|
||||||
_currentBuffer = 0;
|
_currentBuffer = 0;
|
||||||
|
|
||||||
_applyResolution(mode);
|
_applyResolution(mode, forceInterlace);
|
||||||
if (enable)
|
if (enable)
|
||||||
enableInterrupts();
|
enableInterrupts();
|
||||||
}
|
}
|
||||||
|
13
src/gpu.hpp
13
src/gpu.hpp
@ -79,15 +79,19 @@ private:
|
|||||||
return _buffers[_currentBuffer ^ 1];
|
return _buffers[_currentBuffer ^ 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
void _applyResolution(VideoMode mode, int shiftX = 0, int shiftY = 0) const;
|
void _applyResolution(
|
||||||
|
VideoMode mode, bool forceInterlace = false, int shiftX = 0,
|
||||||
|
int shiftY = 0
|
||||||
|
) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int width, height, refreshRate;
|
int width, height, refreshRate;
|
||||||
|
|
||||||
inline Context(
|
inline Context(
|
||||||
VideoMode mode, int width, int height, bool sideBySide = false
|
VideoMode mode, int width, int height, bool forceInterlace = false,
|
||||||
|
bool sideBySide = false
|
||||||
) : _lastTexpage(0) {
|
) : _lastTexpage(0) {
|
||||||
setResolution(mode, width, height, sideBySide);
|
setResolution(mode, width, height, forceInterlace, sideBySide);
|
||||||
}
|
}
|
||||||
inline void newLayer(int x, int y) {
|
inline void newLayer(int x, int y) {
|
||||||
newLayer(x, y, width, height);
|
newLayer(x, y, width, height);
|
||||||
@ -115,7 +119,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setResolution(
|
void setResolution(
|
||||||
VideoMode mode, int width, int height, bool sideBySide = false
|
VideoMode mode, int width, int height, bool forceInterlace = false,
|
||||||
|
bool sideBySide = false
|
||||||
);
|
);
|
||||||
void flip(void);
|
void flip(void);
|
||||||
|
|
||||||
|
27
src/main.cpp
27
src/main.cpp
@ -18,12 +18,14 @@ extern "C" const size_t _resourcesSize;
|
|||||||
class Settings {
|
class Settings {
|
||||||
public:
|
public:
|
||||||
int width, height;
|
int width, height;
|
||||||
|
bool forceInterlace;
|
||||||
int baudRate;
|
int baudRate;
|
||||||
const void *resPtr;
|
const void *resPtr;
|
||||||
size_t resLength;
|
size_t resLength;
|
||||||
|
|
||||||
inline Settings(void)
|
inline Settings(void)
|
||||||
: width(320), height(240), baudRate(0), resPtr(nullptr), resLength(0) {}
|
: width(320), height(240), forceInterlace(false), baudRate(0),
|
||||||
|
resPtr(nullptr), resLength(0) {}
|
||||||
|
|
||||||
bool parse(const char *arg);
|
bool parse(const char *arg);
|
||||||
};
|
};
|
||||||
@ -53,6 +55,10 @@ bool Settings::parse(const char *arg) {
|
|||||||
height = int(strtol(&arg[14], nullptr, 0));
|
height = int(strtol(&arg[14], nullptr, 0));
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case "screen.interlace"_h:
|
||||||
|
forceInterlace = bool(strtol(&arg[17], nullptr, 0));
|
||||||
|
return true;
|
||||||
|
|
||||||
// Allow the default assets to be overridden by passing a pointer to an
|
// Allow the default assets to be overridden by passing a pointer to an
|
||||||
// in-memory ZIP file as a command-line argument.
|
// in-memory ZIP file as a command-line argument.
|
||||||
case "resources.ptr"_h:
|
case "resources.ptr"_h:
|
||||||
@ -99,26 +105,31 @@ int main(int argc, const char **argv) {
|
|||||||
// Load the resource archive, first from memory if a pointer was given and
|
// Load the resource archive, first from memory if a pointer was given and
|
||||||
// then from the HDD. If both attempts fail, fall back to the archive
|
// then from the HDD. If both attempts fail, fall back to the archive
|
||||||
// embedded into the executable.
|
// embedded into the executable.
|
||||||
file::ZIPProvider resourceProvider;
|
auto resourceProvider = new file::ZIPProvider;
|
||||||
|
|
||||||
if (settings.resPtr && settings.resLength) {
|
if (settings.resPtr && settings.resLength) {
|
||||||
if (resourceProvider.init(settings.resPtr, settings.resLength))
|
if (resourceProvider->init(settings.resPtr, settings.resLength))
|
||||||
goto _resourceInitDone;
|
goto _resourceInitDone;
|
||||||
}
|
}
|
||||||
|
|
||||||
resourceProvider.init(_resources, _resourcesSize);
|
resourceProvider->init(_resources, _resourcesSize);
|
||||||
|
|
||||||
_resourceInitDone:
|
_resourceInitDone:
|
||||||
io::clearWatchdog();
|
io::clearWatchdog();
|
||||||
|
|
||||||
gpu::Context gpuCtx(GP1_MODE_NTSC, settings.width, settings.height);
|
auto gpuCtx = new gpu::Context(
|
||||||
ui::Context uiCtx(gpuCtx);
|
GP1_MODE_NTSC, settings.width, settings.height, settings.forceInterlace
|
||||||
App app(uiCtx, resourceProvider);
|
);
|
||||||
|
auto uiCtx = new ui::Context(*gpuCtx);
|
||||||
|
auto app = new App(*uiCtx, *resourceProvider);
|
||||||
|
|
||||||
gpu::enableDisplay(true);
|
gpu::enableDisplay(true);
|
||||||
spu::setVolume(0x3fff);
|
spu::setVolume(0x3fff);
|
||||||
io::setMiscOutput(io::MISC_SPU_ENABLE, true);
|
io::setMiscOutput(io::MISC_SPU_ENABLE, true);
|
||||||
|
app->run();
|
||||||
|
|
||||||
app.run();
|
delete app;
|
||||||
|
delete uiCtx;
|
||||||
|
delete gpuCtx;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "ps1/registers.h"
|
#include "ps1/registers.h"
|
||||||
|
#include "ps1/system.h"
|
||||||
#include "spu.hpp"
|
#include "spu.hpp"
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ void ButtonState::update(void) {
|
|||||||
/* UI context */
|
/* UI context */
|
||||||
|
|
||||||
Context::Context(gpu::Context &gpuCtx, void *screenData)
|
Context::Context(gpu::Context &gpuCtx, void *screenData)
|
||||||
: _background(nullptr), _overlay(nullptr), _currentScreen(0), gpuCtx(gpuCtx),
|
: _currentScreen(0), gpuCtx(gpuCtx), background(nullptr), overlay(nullptr),
|
||||||
time(0), screenData(screenData) {
|
time(0), screenData(screenData) {
|
||||||
_screens[0] = nullptr;
|
_screens[0] = nullptr;
|
||||||
_screens[1] = nullptr;
|
_screens[1] = nullptr;
|
||||||
@ -151,21 +151,21 @@ void Context::draw(void) {
|
|||||||
auto oldScreen = _screens[_currentScreen ^ 1];
|
auto oldScreen = _screens[_currentScreen ^ 1];
|
||||||
auto newScreen = _screens[_currentScreen];
|
auto newScreen = _screens[_currentScreen];
|
||||||
|
|
||||||
if (_background)
|
if (background)
|
||||||
_background->draw(*this);
|
background->draw(*this);
|
||||||
if (oldScreen)
|
if (oldScreen)
|
||||||
oldScreen->draw(*this, false);
|
oldScreen->draw(*this, false);
|
||||||
if (newScreen)
|
if (newScreen)
|
||||||
newScreen->draw(*this, true);
|
newScreen->draw(*this, true);
|
||||||
if (_overlay)
|
if (overlay)
|
||||||
_overlay->draw(*this);
|
overlay->draw(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Context::update(void) {
|
void Context::update(void) {
|
||||||
buttons.update();
|
buttons.update();
|
||||||
|
|
||||||
if (_overlay)
|
if (overlay)
|
||||||
_overlay->update(*this);
|
overlay->update(*this);
|
||||||
if (_screens[_currentScreen])
|
if (_screens[_currentScreen])
|
||||||
_screens[_currentScreen]->update(*this);
|
_screens[_currentScreen]->update(*this);
|
||||||
}
|
}
|
||||||
|
@ -138,11 +138,11 @@ class Screen;
|
|||||||
class Context {
|
class Context {
|
||||||
private:
|
private:
|
||||||
Screen *_screens[2];
|
Screen *_screens[2];
|
||||||
Layer *_background, *_overlay;
|
|
||||||
int _currentScreen;
|
int _currentScreen;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
gpu::Context &gpuCtx;
|
gpu::Context &gpuCtx;
|
||||||
|
Layer *background, *overlay;
|
||||||
|
|
||||||
gpu::Font font;
|
gpu::Font font;
|
||||||
gpu::Color colors[NUM_UI_COLORS];
|
gpu::Color colors[NUM_UI_COLORS];
|
||||||
@ -157,12 +157,6 @@ public:
|
|||||||
//buttons.update();
|
//buttons.update();
|
||||||
time++;
|
time++;
|
||||||
}
|
}
|
||||||
inline void setBackgroundLayer(Layer &layer) {
|
|
||||||
_background = &layer;
|
|
||||||
}
|
|
||||||
inline void setOverlayLayer(Layer &layer) {
|
|
||||||
_overlay = &layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
Context(gpu::Context &gpuCtx, void *screenData = nullptr);
|
Context(gpu::Context &gpuCtx, void *screenData = nullptr);
|
||||||
void show(Screen &screen, bool goBack = false, bool playSound = false);
|
void show(Screen &screen, bool goBack = false, bool playSound = false);
|
||||||
|
14
src/util.hpp
14
src/util.hpp
@ -5,7 +5,6 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "ps1/system.h"
|
|
||||||
|
|
||||||
namespace util {
|
namespace util {
|
||||||
|
|
||||||
@ -47,6 +46,10 @@ template<typename T, typename X> static inline void assertAligned(X *ptr) {
|
|||||||
assert(!(reinterpret_cast<uintptr_t>(ptr) % alignof(T)));
|
assert(!(reinterpret_cast<uintptr_t>(ptr) % alignof(T)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T> static constexpr inline size_t countOf(T &array) {
|
||||||
|
return sizeof(array) / sizeof(array[0]);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T, typename X> static constexpr inline T forcedCast(X item) {
|
template<typename T, typename X> static constexpr inline T forcedCast(X item) {
|
||||||
return reinterpret_cast<T>(reinterpret_cast<void *>(item));
|
return reinterpret_cast<T>(reinterpret_cast<void *>(item));
|
||||||
}
|
}
|
||||||
@ -91,14 +94,14 @@ public:
|
|||||||
if (ptr)
|
if (ptr)
|
||||||
free(ptr);
|
free(ptr);
|
||||||
|
|
||||||
ptr = malloc(_length);
|
ptr = new uint8_t[length];
|
||||||
length = _length;
|
length = _length;
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
inline void destroy(void) {
|
inline void destroy(void) {
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
free(ptr);
|
delete[] as<uint8_t>();
|
||||||
ptr = nullptr;
|
ptr = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,9 +268,12 @@ extern const char *const MINIZ_ZIP_ERROR_NAMES[];
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//#define LOG(...) util::logger.log(__VA_ARGS__)
|
#ifdef ENABLE_LOGGING
|
||||||
#define LOG(fmt, ...) \
|
#define LOG(fmt, ...) \
|
||||||
util::logger.log("%s(%d): " fmt, __func__, __LINE__ __VA_OPT__(,) __VA_ARGS__)
|
util::logger.log("%s(%d): " fmt, __func__, __LINE__ __VA_OPT__(,) __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define LOG(fmt, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
static constexpr inline util::Hash operator""_h(
|
static constexpr inline util::Hash operator""_h(
|
||||||
const char *const literal, size_t length
|
const char *const literal, size_t length
|
||||||
|
Loading…
x
Reference in New Issue
Block a user