Added key repeat support to MediaViewer and PDFViewer

This commit is contained in:
Leon Styhre 2023-08-15 19:52:53 +02:00
parent c4d2cc5598
commit 4918c16a98
6 changed files with 260 additions and 80 deletions

View file

@ -12,11 +12,23 @@
#include "components/VideoFFmpegComponent.h"
#include "views/ViewController.h"
#define KEY_REPEAT_START_DELAY 600
#define KEY_REPEAT_SPEED 250
MediaViewer::MediaViewer()
: mRenderer {Renderer::getInstance()}
, mGame {nullptr}
, mHasVideo {false}
, mHasImages {false}
, mDisplayingImage {false}
, mHasManual {false}
, mShowMediaTypes {false}
, mFrameHeight {0.0f}
, mCurrentImageIndex {0}
, mScreenshotIndex {0}
, mTitleScreenIndex {0}
, mKeyRepeatDir {0}
, mKeyRepeatTimer {0}
, mHelpInfoPosition {HelpInfoPosition::TOP}
{
Window::getInstance()->setMediaViewer(this);
@ -29,6 +41,8 @@ bool MediaViewer::startMediaViewer(FileData* game)
mCurrentImageIndex = 0;
mScreenshotIndex = -1;
mTitleScreenIndex = -1;
mKeyRepeatDir = 0;
mKeyRepeatTimer = 0;
ViewController::getInstance()->pauseViewVideos();
@ -106,8 +120,64 @@ void MediaViewer::launchPDFViewer()
}
}
void MediaViewer::input(InputConfig* config, Input input)
{
if (config->isMappedLike("down", input) && input.value != 0) {
mKeyRepeatDir = 0;
return;
}
else if (config->isMappedLike("up", input) && input.value != 0) {
mKeyRepeatDir = 0;
launchPDFViewer();
return;
}
else if (config->isMappedLike("left", input)) {
if (input.value) {
mKeyRepeatDir = -1;
mKeyRepeatTimer = -(KEY_REPEAT_START_DELAY - KEY_REPEAT_SPEED);
showPrevious();
}
else {
mKeyRepeatDir = 0;
}
}
else if (config->isMappedLike("right", input)) {
if (input.value) {
mKeyRepeatDir = 1;
mKeyRepeatTimer = -(KEY_REPEAT_START_DELAY - KEY_REPEAT_SPEED);
showNext();
}
else {
mKeyRepeatDir = 0;
}
}
else if (config->isMappedLike("lefttrigger", input) && input.value != 0) {
mKeyRepeatDir = 0;
showFirst();
}
else if (config->isMappedLike("righttrigger", input) && input.value != 0) {
mKeyRepeatDir = 0;
showLast();
}
else if (input.value != 0) {
// Any other input stops the media viewer.
Window::getInstance()->stopMediaViewer();
}
}
void MediaViewer::update(int deltaTime)
{
if (mKeyRepeatDir != 0) {
mKeyRepeatTimer += deltaTime;
while (mKeyRepeatTimer >= KEY_REPEAT_SPEED) {
mKeyRepeatTimer -= KEY_REPEAT_SPEED;
if (mKeyRepeatDir == 1)
showNext();
else
showPrevious();
}
}
if (mVideo)
mVideo->update(deltaTime);
}

View file

@ -25,6 +25,7 @@ public:
void stopMediaViewer() override;
void launchPDFViewer() override;
void input(InputConfig* config, Input input) override;
void update(int deltaTime) override;
void render(const glm::mat4& parentTrans) override;
std::vector<HelpPrompt> getHelpPrompts() override;
@ -42,10 +43,10 @@ private:
void playVideo();
void showNext() override;
void showPrevious() override;
void showFirst() override;
void showLast() override;
void showNext();
void showPrevious();
void showFirst();
void showLast();
Renderer* mRenderer;
FileData* mGame;
@ -61,6 +62,9 @@ private:
int mScreenshotIndex;
int mTitleScreenIndex;
int mKeyRepeatDir;
int mKeyRepeatTimer;
struct ImageInfo {
std::string mediaType;
bool linearInterpolation;

View file

@ -22,10 +22,25 @@
#define DEBUG_PDF_CONVERSION false
#define KEY_REPEAT_START_DELAY 600
#define KEY_REPEAT_START_DELAY_ZOOMED 500
#define KEY_REPEAT_SPEED 250
#define KEY_REPEAT_SPEED_ZOOMED 150
PDFViewer::PDFViewer()
: mRenderer {Renderer::getInstance()}
, mGame {nullptr}
, mFrameHeight {0.0f}
, mScaleFactor {1.0f}
, mCurrentPage {0}
, mPageCount {0}
, mZoom {1.0f}
, mPanAmount {0.0f}
, mPanOffset {0.0f, 0.0f, 0.0f}
, mKeyRepeatLeftRight {0}
, mKeyRepeatUpDown {0}
, mKeyRepeatZoom {0}
, mKeyRepeatTimer {0}
, mHelpInfoPosition {HelpInfoPosition::TOP}
{
Window::getInstance()->setPDFViewer(this);
@ -76,6 +91,10 @@ bool PDFViewer::startPDFViewer(FileData* game)
mZoom = 1.0f;
mPanAmount = 0.0f;
mPanOffset = {0.0f, 0.0f, 0.0f};
mKeyRepeatLeftRight = 0;
mKeyRepeatUpDown = 0;
mKeyRepeatZoom = 0;
mKeyRepeatTimer = 0;
// Increase the rasterization resolution when running at lower screen resolutions to make
// the texture look ok when zoomed in.
@ -491,6 +510,146 @@ void PDFViewer::convertPage(int pageNum)
#endif
}
void PDFViewer::input(InputConfig* config, Input input)
{
if (config->isMappedLike("up", input)) {
if (input.value) {
mKeyRepeatUpDown = -1;
mKeyRepeatLeftRight = 0;
mKeyRepeatZoom = 0;
mKeyRepeatTimer =
-((mZoom > 1.0f ? KEY_REPEAT_START_DELAY_ZOOMED : KEY_REPEAT_START_DELAY) -
KEY_REPEAT_SPEED);
navigateUp();
}
else {
mKeyRepeatUpDown = 0;
}
}
else if (config->isMappedLike("down", input)) {
if (input.value) {
mKeyRepeatUpDown = 1;
mKeyRepeatLeftRight = 0;
mKeyRepeatZoom = 0;
mKeyRepeatTimer =
-((mZoom > 1.0f ? KEY_REPEAT_START_DELAY_ZOOMED : KEY_REPEAT_START_DELAY) -
KEY_REPEAT_SPEED);
navigateDown();
}
else {
mKeyRepeatUpDown = 0;
}
return;
}
else if (config->isMappedLike("left", input)) {
if (input.value) {
mKeyRepeatLeftRight = -1;
mKeyRepeatUpDown = 0;
mKeyRepeatZoom = 0;
mKeyRepeatTimer =
-((mZoom > 1.0f ? KEY_REPEAT_START_DELAY_ZOOMED : KEY_REPEAT_START_DELAY) -
KEY_REPEAT_SPEED);
navigateLeft();
}
else {
mKeyRepeatLeftRight = 0;
}
}
else if (config->isMappedLike("right", input)) {
if (input.value) {
mKeyRepeatLeftRight = 1;
mKeyRepeatUpDown = 0;
mKeyRepeatZoom = 0;
mKeyRepeatTimer =
-((mZoom > 1.0f ? KEY_REPEAT_START_DELAY_ZOOMED : KEY_REPEAT_START_DELAY) -
KEY_REPEAT_SPEED);
navigateRight();
}
else {
mKeyRepeatLeftRight = 0;
}
}
else if (config->isMappedLike("leftshoulder", input)) {
if (input.value) {
mKeyRepeatZoom = -1;
mKeyRepeatLeftRight = 0;
mKeyRepeatUpDown = 0;
mKeyRepeatTimer = -(KEY_REPEAT_START_DELAY_ZOOMED - KEY_REPEAT_SPEED_ZOOMED);
navigateLeftShoulder();
}
else {
mKeyRepeatZoom = 0;
}
}
else if (config->isMappedLike("rightshoulder", input)) {
if (input.value) {
mKeyRepeatZoom = 1;
mKeyRepeatLeftRight = 0;
mKeyRepeatUpDown = 0;
mKeyRepeatTimer = -(KEY_REPEAT_START_DELAY_ZOOMED - KEY_REPEAT_SPEED_ZOOMED);
navigateRightShoulder();
}
else {
mKeyRepeatZoom = 0;
}
}
else if (config->isMappedLike("lefttrigger", input) && input.value != 0) {
mKeyRepeatLeftRight = 0;
mKeyRepeatUpDown = 0;
mKeyRepeatZoom = 0;
navigateLeftTrigger();
}
else if (config->isMappedLike("righttrigger", input) && input.value != 0) {
mKeyRepeatLeftRight = 0;
mKeyRepeatUpDown = 0;
mKeyRepeatZoom = 0;
navigateRightTrigger();
}
else if (input.value != 0) {
// Any other input stops the PDF viewer.
Window::getInstance()->stopPDFViewer();
}
}
void PDFViewer::update(int deltaTime)
{
if (mKeyRepeatLeftRight != 0) {
mKeyRepeatTimer += deltaTime;
// Limit the accumulated backlog of keypresses if the computer can't keep up.
if (mKeyRepeatTimer > KEY_REPEAT_SPEED * 2)
mKeyRepeatTimer = KEY_REPEAT_SPEED * 2;
while (mKeyRepeatTimer >= (mZoom > 1.0f ? KEY_REPEAT_SPEED_ZOOMED : KEY_REPEAT_SPEED)) {
mKeyRepeatTimer -= (mZoom > 1.0f ? KEY_REPEAT_SPEED_ZOOMED : KEY_REPEAT_SPEED);
if (mKeyRepeatLeftRight == 1)
navigateRight();
else
navigateLeft();
}
}
if (mKeyRepeatUpDown != 0) {
mKeyRepeatTimer += deltaTime;
if (mKeyRepeatTimer > KEY_REPEAT_SPEED * 2)
mKeyRepeatTimer = KEY_REPEAT_SPEED * 2;
while (mKeyRepeatTimer >= (mZoom > 1.0f ? KEY_REPEAT_SPEED_ZOOMED : KEY_REPEAT_SPEED)) {
mKeyRepeatTimer -= (mZoom > 1.0f ? KEY_REPEAT_SPEED_ZOOMED : KEY_REPEAT_SPEED);
if (mKeyRepeatUpDown == 1)
navigateDown();
else
navigateUp();
}
}
if (mKeyRepeatZoom != 0) {
mKeyRepeatTimer += deltaTime;
while (mKeyRepeatTimer >= KEY_REPEAT_SPEED_ZOOMED) {
mKeyRepeatTimer -= KEY_REPEAT_SPEED_ZOOMED;
if (mKeyRepeatZoom == 1)
navigateRightShoulder();
else
navigateLeftShoulder();
}
}
}
void PDFViewer::render(const glm::mat4& /*parentTrans*/)
{
glm::mat4 trans {Renderer::getIdentity()};

View file

@ -27,6 +27,8 @@ public:
bool getDocumentInfo();
void convertPage(int pageNum);
void input(InputConfig* config, Input input) override;
void update(int deltaTime) override;
void render(const glm::mat4& parentTrans) override;
std::vector<HelpPrompt> getHelpPrompts() override;
@ -40,16 +42,15 @@ private:
void showNextPage();
void showPreviousPage();
void navigateUp() override;
void navigateDown() override;
void navigateLeft() override;
void navigateRight() override;
void navigateUp();
void navigateDown();
void navigateLeft();
void navigateRight();
void navigateLeftShoulder() override;
void navigateRightShoulder() override;
void navigateLeftTrigger() override;
void navigateRightTrigger() override;
void navigateLeftShoulder();
void navigateRightShoulder();
void navigateLeftTrigger();
void navigateRightTrigger();
struct PageEntry {
float width;
@ -69,6 +70,11 @@ private:
float mPanAmount;
glm::vec3 mPanOffset;
int mKeyRepeatLeftRight;
int mKeyRepeatUpDown;
int mKeyRepeatZoom;
int mKeyRepeatTimer;
std::string mESConvertPath;
std::string mManualPath;

View file

@ -221,62 +221,12 @@ void Window::input(InputConfig* config, Input input)
}
if (mMediaViewer && mRenderMediaViewer) {
if (config->isMappedLike("down", input) && input.value != 0) {
return;
}
else if (config->isMappedLike("up", input) && input.value != 0) {
mMediaViewer->launchPDFViewer();
return;
}
else if (config->isMappedLike("left", input) && input.value != 0) {
mMediaViewer->showPrevious();
}
else if (config->isMappedLike("right", input) && input.value != 0) {
mMediaViewer->showNext();
}
else if (config->isMappedLike("lefttrigger", input) && input.value != 0) {
mMediaViewer->showFirst();
}
else if (config->isMappedLike("righttrigger", input) && input.value != 0) {
mMediaViewer->showLast();
}
else if (input.value != 0) {
// Any other input stops the media viewer.
stopMediaViewer();
}
mMediaViewer->input(config, input);
return;
}
if (mPDFViewer && mRenderPDFViewer) {
if (config->isMappedLike("up", input) && input.value != 0) {
mPDFViewer->navigateUp();
}
else if (config->isMappedLike("down", input) && input.value != 0) {
mPDFViewer->navigateDown();
return;
}
else if (config->isMappedLike("left", input) && input.value != 0) {
mPDFViewer->navigateLeft();
}
else if (config->isMappedLike("right", input) && input.value != 0) {
mPDFViewer->navigateRight();
}
else if (config->isMappedLike("leftshoulder", input) && input.value != 0) {
mPDFViewer->navigateLeftShoulder();
}
else if (config->isMappedLike("rightshoulder", input) && input.value != 0) {
mPDFViewer->navigateRightShoulder();
}
else if (config->isMappedLike("lefttrigger", input) && input.value != 0) {
mPDFViewer->navigateLeftTrigger();
}
else if (config->isMappedLike("righttrigger", input) && input.value != 0) {
mPDFViewer->navigateRightTrigger();
}
else if (input.value != 0) {
// Any other input stops the PDF viewer.
stopPDFViewer();
}
mPDFViewer->input(config, input);
return;
}
@ -477,6 +427,9 @@ void Window::update(int deltaTime)
if (mMediaViewer && mRenderMediaViewer)
mMediaViewer->update(deltaTime);
if (mPDFViewer && mRenderPDFViewer)
mPDFViewer->update(deltaTime);
if (mLaunchScreen && mRenderLaunchScreen)
mLaunchScreen->update(deltaTime);

View file

@ -58,11 +58,7 @@ public:
virtual void stopMediaViewer() = 0;
virtual void launchPDFViewer() = 0;
virtual void showNext() = 0;
virtual void showPrevious() = 0;
virtual void showFirst() = 0;
virtual void showLast() = 0;
virtual void input(InputConfig* config, Input input) = 0;
virtual void update(int deltaTime) = 0;
virtual void render(const glm::mat4& parentTrans) = 0;
virtual std::vector<HelpPrompt> getHelpPrompts() = 0;
@ -75,16 +71,8 @@ public:
virtual void stopPDFViewer() = 0;
virtual void launchMediaViewer() = 0;
virtual void navigateUp() = 0;
virtual void navigateDown() = 0;
virtual void navigateLeft() = 0;
virtual void navigateRight() = 0;
virtual void navigateLeftShoulder() = 0;
virtual void navigateRightShoulder() = 0;
virtual void navigateLeftTrigger() = 0;
virtual void navigateRightTrigger() = 0;
virtual void input(InputConfig* config, Input input) = 0;
virtual void update(int deltaTime) = 0;
virtual void render(const glm::mat4& parentTrans) = 0;
virtual std::vector<HelpPrompt> getHelpPrompts() = 0;
};