Replace some of the onscreen touch buttons with a new better impl that doesn't rely on InputState.

This commit is contained in:
Henrik Rydgard 2013-07-20 12:06:06 +02:00
parent 18d0d72b45
commit 325f5dfc21
8 changed files with 207 additions and 52 deletions

View File

@ -143,6 +143,7 @@ void EmuScreen::dialogFinished(const Screen *dialog, DialogResult result) {
delete msg; delete msg;
} }
} }
RecreateViews();
} }
void EmuScreen::sendMessage(const char *message, const char *value) { void EmuScreen::sendMessage(const char *message, const char *value) {
@ -200,7 +201,7 @@ inline float clamp1(float x) {
} }
void EmuScreen::touch(const TouchInput &touch) { void EmuScreen::touch(const TouchInput &touch) {
root_->Touch(touch);
} }
void EmuScreen::onVKeyDown(int virtualKeyCode) { void EmuScreen::onVKeyDown(int virtualKeyCode) {
@ -368,7 +369,13 @@ static const struct { int from, to; } legacy_touch_mapping[12] = {
{PAD_BUTTON_LEFT, CTRL_LEFT}, {PAD_BUTTON_LEFT, CTRL_LEFT},
}; };
void EmuScreen::CreateViews() {
root_ = CreatePadLayout();
}
void EmuScreen::update(InputState &input) { void EmuScreen::update(InputState &input) {
UIScreen::update(input);
// Simply forcibily update to the current screen size every frame. Doesn't cost much. // Simply forcibily update to the current screen size every frame. Doesn't cost much.
PSP_CoreParameter().outputWidth = dp_xres; PSP_CoreParameter().outputWidth = dp_xres;
PSP_CoreParameter().outputHeight = dp_yres; PSP_CoreParameter().outputHeight = dp_yres;
@ -510,8 +517,15 @@ void EmuScreen::render() {
ui_draw2d.Begin(UIShader_Get(), DBMODE_NORMAL); ui_draw2d.Begin(UIShader_Get(), DBMODE_NORMAL);
float touchOpacity = g_Config.iTouchButtonOpacity / 100.0f; float touchOpacity = g_Config.iTouchButtonOpacity / 100.0f;
if (g_Config.bShowTouchControls) if (g_Config.bShowTouchControls) {
// Parts of UIScreen that make sense here.
UI::LayoutViewHierarchy(*screenManager()->getUIContext(), root_);
root_->Draw(*screenManager()->getUIContext());
//screenManager()->getUIContext()->Flush();
// UIScreen::render();
DrawGamepad(ui_draw2d, touchOpacity); DrawGamepad(ui_draw2d, touchOpacity);
}
DrawWatermark(); DrawWatermark();

View File

@ -21,9 +21,10 @@
#include <list> #include <list>
#include "ui/screen.h" #include "ui/screen.h"
#include "ui/ui_screen.h"
#include "Common/KeyMap.h" #include "Common/KeyMap.h"
class EmuScreen : public Screen class EmuScreen : public UIScreen
{ {
public: public:
EmuScreen(const std::string &filename); EmuScreen(const std::string &filename);
@ -39,6 +40,9 @@ public:
virtual void key(const KeyInput &key); virtual void key(const KeyInput &key);
virtual void axis(const AxisInput &axis); virtual void axis(const AxisInput &axis);
protected:
virtual void CreateViews();
private: private:
void bootGame(const std::string &filename); void bootGame(const std::string &filename);

View File

@ -200,7 +200,6 @@ void GameSettingsScreen::CreateViews() {
ViewGroup *audioSettings = new LinearLayout(ORIENT_VERTICAL); ViewGroup *audioSettings = new LinearLayout(ORIENT_VERTICAL);
audioSettingsScroll->Add(audioSettings); audioSettingsScroll->Add(audioSettings);
tabHolder->AddTab("Audio", audioSettingsScroll); tabHolder->AddTab("Audio", audioSettingsScroll);
audioSettings->Add(new Choice(a->T("Download Atrac3+ plugin")))->OnClick.Handle(this, &GameSettingsScreen::OnDownloadPlugin);
audioSettings->Add(new PopupSliderChoice(&g_Config.iSEVolume, 0, 8, a->T("FX volume"), screenManager())); audioSettings->Add(new PopupSliderChoice(&g_Config.iSEVolume, 0, 8, a->T("FX volume"), screenManager()));
audioSettings->Add(new PopupSliderChoice(&g_Config.iBGMVolume, 0, 8, a->T("BGM volume"), screenManager())); audioSettings->Add(new PopupSliderChoice(&g_Config.iBGMVolume, 0, 8, a->T("BGM volume"), screenManager()));
audioSettings->Add(new CheckBox(&g_Config.bEnableSound, a->T("Enable Sound"))); audioSettings->Add(new CheckBox(&g_Config.bEnableSound, a->T("Enable Sound")));
@ -223,11 +222,6 @@ void GameSettingsScreen::CreateViews() {
systemSettings->Add(new CheckBox(&g_Config.bFastMemory, s->T("Fast Memory", "Fast Memory (unstable)"))); systemSettings->Add(new CheckBox(&g_Config.bFastMemory, s->T("Fast Memory", "Fast Memory (unstable)")));
} }
UI::EventReturn GameSettingsScreen::OnDownloadPlugin(UI::EventParams &e) {
screenManager()->push(new PluginScreen());
return UI::EVENT_DONE;
}
void DrawBackground(float alpha); void DrawBackground(float alpha);
void GameSettingsScreen::DrawBackground(UIContext &dc) { void GameSettingsScreen::DrawBackground(UIContext &dc) {
@ -296,9 +290,11 @@ void DeveloperToolsScreen::CreateViews() {
I18NCategory *g = GetI18NCategory("General"); I18NCategory *g = GetI18NCategory("General");
I18NCategory *d = GetI18NCategory("Developer"); I18NCategory *d = GetI18NCategory("Developer");
I18NCategory *a = GetI18NCategory("Audio");
LinearLayout *list = root_->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); LinearLayout *list = root_->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0f)));
list->Add(new ItemHeader(g->T("General"))); list->Add(new ItemHeader(g->T("General")));
list->Add(new Choice(a->T("Download Atrac3+ plugin")))->OnClick.Handle(this, &DeveloperToolsScreen::OnDownloadPlugin);
list->Add(new Choice(d->T("Run CPU Tests")))->OnClick.Handle(this, &DeveloperToolsScreen::OnRunCPUTests); list->Add(new Choice(d->T("Run CPU Tests")))->OnClick.Handle(this, &DeveloperToolsScreen::OnRunCPUTests);
list->Add(new Choice(g->T("Back")))->OnClick.Handle(this, &DeveloperToolsScreen::OnBack); list->Add(new Choice(g->T("Back")))->OnClick.Handle(this, &DeveloperToolsScreen::OnBack);
@ -313,3 +309,8 @@ UI::EventReturn DeveloperToolsScreen::OnRunCPUTests(UI::EventParams &e) {
RunTests(); RunTests();
return UI::EVENT_DONE; return UI::EVENT_DONE;
} }
UI::EventReturn DeveloperToolsScreen::OnDownloadPlugin(UI::EventParams &e) {
screenManager()->push(new PluginScreen());
return UI::EVENT_DONE;
}

View File

@ -31,8 +31,6 @@ protected:
virtual void DrawBackground(UIContext &dc); virtual void DrawBackground(UIContext &dc);
private: private:
UI::EventReturn OnDownloadPlugin(UI::EventParams &e);
std::string gamePath_, gameID_; std::string gamePath_, gameID_;
// As we load metadata in the background, we need to be able to update these after the fact. // As we load metadata in the background, we need to be able to update these after the fact.
@ -74,4 +72,5 @@ protected:
private: private:
UI::EventReturn OnBack(UI::EventParams &e); UI::EventReturn OnBack(UI::EventParams &e);
UI::EventReturn OnRunCPUTests(UI::EventParams &e); UI::EventReturn OnRunCPUTests(UI::EventParams &e);
UI::EventReturn OnDownloadPlugin(UI::EventParams &e);
}; };

View File

@ -18,8 +18,10 @@
#include "GamepadEmu.h" #include "GamepadEmu.h"
#include "base/colorutil.h" #include "base/colorutil.h"
#include "ui/virtual_input.h" #include "ui/virtual_input.h"
#include "ui/ui_context.h"
#include "Core/Config.h" #include "Core/Config.h"
#include "ui_atlas.h" #include "ui_atlas.h"
#include "Core/HLE/sceCtrl.h"
#if defined(__SYMBIAN32__) || defined(IOS) || defined(MEEGO_EDITION_HARMATTAN) #if defined(__SYMBIAN32__) || defined(IOS) || defined(MEEGO_EDITION_HARMATTAN)
#define USE_PAUSE_BUTTON 1 #define USE_PAUSE_BUTTON 1
@ -27,16 +29,91 @@
#define USE_PAUSE_BUTTON 0 #define USE_PAUSE_BUTTON 0
#endif #endif
TouchButton buttonX(&ui_atlas, I_ROUND, I_CROSS, PAD_BUTTON_A); void MultiTouchButton::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
TouchButton buttonO(&ui_atlas, I_ROUND, I_CIRCLE, PAD_BUTTON_B); const AtlasImage &image = dc.Draw()->GetAtlas()->images[bgImg_];
TouchButton buttonSq(&ui_atlas, I_ROUND, I_SQUARE, PAD_BUTTON_X); w = image.w * scale_;
TouchButton buttonTri(&ui_atlas, I_ROUND, I_TRIANGLE, PAD_BUTTON_Y); h = image.h * scale_;
TouchButton buttonSelect(&ui_atlas, I_RECT, I_SELECT, PAD_BUTTON_SELECT); }
TouchButton buttonStart(&ui_atlas, I_RECT, I_START, PAD_BUTTON_START);
TouchButton buttonLShoulder(&ui_atlas, I_SHOULDER, I_L, PAD_BUTTON_LBUMPER); void MultiTouchButton::Touch(const TouchInput &input) {
TouchButton buttonRShoulder(&ui_atlas, I_SHOULDER, I_R, PAD_BUTTON_RBUMPER, 0, true); if ((input.flags & TOUCH_DOWN) && bounds_.Contains(input.x, input.y)) {
pointerDownMask_ |= 1 << input.id;
}
if (input.flags & TOUCH_MOVE) {
if (bounds_.Contains(input.x, input.y))
pointerDownMask_ |= 1 << input.id;
else
pointerDownMask_ &= ~(1 << input.id);
}
if (input.flags & TOUCH_UP) {
pointerDownMask_ &= ~(1 << input.id);
}
}
void MultiTouchButton::Draw(UIContext &dc) {
float opacity = g_Config.iTouchButtonOpacity / 100.0f;
float scale = scale_;
if (IsDown()) {
scale *= 2.0f;
opacity = 100.0f;
}
uint32_t colorBg = colorAlpha(0xc0b080, opacity);
uint32_t color = colorAlpha(0xFFFFFF, opacity);
dc.Draw()->DrawImageRotated(bgImg_, bounds_.centerX(), bounds_.centerY(), scale, 0.0f, colorBg, flipImageH_);
dc.Draw()->DrawImageRotated(img_, bounds_.centerX(), bounds_.centerY(), scale, 0.0f, color, flipImageH_);
}
void PSPButton::Touch(const TouchInput &input) {
bool lastDown = pointerDownMask_ != 0;
MultiTouchButton::Touch(input);
bool down = pointerDownMask_ != 0;
if (down && !lastDown) {
__CtrlButtonDown(pspButtonBit_);
} else if (lastDown && !down) {
__CtrlButtonUp(pspButtonBit_);
}
}
bool PSPButton::IsDown() {
return __CtrlPeekButtons() & pspButtonBit_;
}
UI::ViewGroup *CreatePadLayout() {
using namespace UI;
AnchorLayout *root = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT));
// TODO: See if we can make some kind of global scaling for views instead of this hackery.
float scale = g_Config.fButtonScale;
// const int button_spacing = 50 * controlScale;
const int button_spacing = 50 * scale;
const int arrow_spacing = 40 * scale;
const int circleX = 40 * scale;
const int circleY = 120 * scale;
const int startX = 170 * scale;
const int leftX = 40 * scale;
const int bottomStride = 120 * scale;
root->Add(new PSPButton(CTRL_CIRCLE, I_ROUND, I_CIRCLE, scale, new AnchorLayoutParams(NONE, NONE, circleX, circleY, true)));
root->Add(new PSPButton(CTRL_CROSS, I_ROUND, I_CROSS, scale, new AnchorLayoutParams(NONE, NONE, circleX + button_spacing, circleY - button_spacing, true)));
root->Add(new PSPButton(CTRL_TRIANGLE, I_ROUND, I_TRIANGLE, scale, new AnchorLayoutParams(NONE, NONE, circleX + button_spacing, circleY + button_spacing, true)));
root->Add(new PSPButton(CTRL_SQUARE, I_ROUND, I_SQUARE, scale, new AnchorLayoutParams(NONE, NONE, circleX + button_spacing * 2, circleY, true)));
root->Add(new PSPButton(CTRL_START, I_RECT, I_START, scale, new AnchorLayoutParams(NONE, NONE, startX, 30, true)));
root->Add(new PSPButton(CTRL_SELECT, I_RECT, I_SELECT, scale, new AnchorLayoutParams(NONE, NONE, startX + bottomStride, 30, true)));
root->Add(new PSPButton(CTRL_LTRIGGER, I_RECT, I_L, scale, new AnchorLayoutParams(10, 10, NONE, NONE, false)));
root->Add(new PSPButton(CTRL_RTRIGGER, I_RECT, I_R, scale, new AnchorLayoutParams(NONE, 10, 10, NONE, false)))->FlipImageH(true);
return root;
}
TouchButton buttonTurbo(&ui_atlas, I_RECT, I_ARROW, PAD_BUTTON_UNTHROTTLE, 180); TouchButton buttonTurbo(&ui_atlas, I_RECT, I_ARROW, PAD_BUTTON_UNTHROTTLE, 180);
//TouchButton buttonVPS(&ui_atlas, I_RECT, I_ARROW, PAD_BUTTON_LEFT_THUMB, 180);
TouchCrossPad crossPad(&ui_atlas, I_DIR, I_ARROW); TouchCrossPad crossPad(&ui_atlas, I_DIR, I_ARROW);
#if USE_PAUSE_BUTTON #if USE_PAUSE_BUTTON
TouchButton buttonPause(&ui_atlas, I_RECT, I_ARROW, PAD_BUTTON_BACK, 90); TouchButton buttonPause(&ui_atlas, I_RECT, I_ARROW, PAD_BUTTON_BACK, 90);
@ -66,22 +143,12 @@ void LayoutGamepad(int w, int h)
const int halfW = w / 2; const int halfW = w / 2;
buttonO.setPos(circleX, circleY, controlScale);
buttonX.setPos(circleX - button_spacing, circleY + button_spacing, controlScale);
buttonTri.setPos(circleX - button_spacing, circleY - button_spacing, controlScale);
buttonSq.setPos(circleX - button_spacing * 2, circleY, controlScale);
crossPad.setPos(leftX + arrow_spacing, leftY, 40, controlScale); crossPad.setPos(leftX + arrow_spacing, leftY, 40, controlScale);
//if (g_Config.iFpsLimit) //if (g_Config.iFpsLimit)
// buttonVPS.setPos(halfW - button_spacing * 2, h - 20 * controlScale, controlScale); // buttonVPS.setPos(halfW - button_spacing * 2, h - 20 * controlScale, controlScale);
//else //else
buttonTurbo.setPos(halfW - button_spacing * 2, h - 20 * controlScale, controlScale); buttonTurbo.setPos(halfW - button_spacing * 2, h - 20 * controlScale, controlScale);
buttonSelect.setPos(halfW , h - 20 * controlScale, controlScale);
buttonStart.setPos(halfW + button_spacing * 2 , h - 20 * controlScale, controlScale);
buttonLShoulder.setPos(button_spacing + 10 * controlScale, 30 * controlScale, controlScale);
buttonRShoulder.setPos(w - button_spacing - 10 * controlScale, 30 * controlScale, controlScale);
#if USE_PAUSE_BUTTON #if USE_PAUSE_BUTTON
buttonPause.setPos(halfW, 15 * controlScale, controlScale); buttonPause.setPos(halfW, 15 * controlScale, controlScale);
@ -93,18 +160,8 @@ void LayoutGamepad(int w, int h)
void UpdateGamepad(InputState &input_state) { void UpdateGamepad(InputState &input_state) {
LayoutGamepad(dp_xres, dp_yres); LayoutGamepad(dp_xres, dp_yres);
buttonO.update(input_state);
buttonX.update(input_state);
buttonTri.update(input_state);
buttonSq.update(input_state);
crossPad.update(input_state); crossPad.update(input_state);
buttonSelect.update(input_state);
buttonStart.update(input_state);
buttonLShoulder.update(input_state);
buttonRShoulder.update(input_state);
//if (g_Config.iFpsLimit) //if (g_Config.iFpsLimit)
// buttonVPS.update(input_state); // buttonVPS.update(input_state);
//else //else
@ -122,18 +179,8 @@ void DrawGamepad(DrawBuffer &db, float opacity) {
uint32_t color = colorAlpha(0xc0b080, opacity); uint32_t color = colorAlpha(0xc0b080, opacity);
uint32_t colorOverlay = colorAlpha(0xFFFFFF, opacity); uint32_t colorOverlay = colorAlpha(0xFFFFFF, opacity);
buttonO.draw(db, color, colorOverlay);
buttonX.draw(db, color, colorOverlay);
buttonTri.draw(db, color, colorOverlay);
buttonSq.draw(db, color, colorOverlay);
crossPad.draw(db, color, colorOverlay); crossPad.draw(db, color, colorOverlay);
buttonSelect.draw(db, color, colorOverlay);
buttonStart.draw(db, color, colorOverlay);
buttonLShoulder.draw(db, color, colorOverlay);
buttonRShoulder.draw(db, color, colorOverlay);
//if (g_Config.iFpsLimit) //if (g_Config.iFpsLimit)
// buttonVPS.draw(db, color, colorOverlay); // buttonVPS.draw(db, color, colorOverlay);
//else //else

View File

@ -20,6 +20,96 @@
#include "input/input_state.h" #include "input/input_state.h"
#include "gfx_es2/draw_buffer.h" #include "gfx_es2/draw_buffer.h"
#include "ui/view.h"
#include "ui/viewgroup.h"
class MultiTouchButton : public UI::View {
public:
MultiTouchButton(int bgImg, int img, float scale, UI::LayoutParams *layoutParams)
: UI::View(layoutParams), pointerDownMask_(0), bgImg_(bgImg), img_(img), scale_(scale), flipImageH_(false) {
}
virtual void Key(const KeyInput &input) {}
virtual void Update(const InputState &input) {}
virtual void Touch(const TouchInput &input);
virtual void Draw(UIContext &dc);
virtual void GetContentDimensions(const UIContext &dc, float &w, float &h) const;
virtual bool IsDown() { return pointerDownMask_ != NULL; }
void FlipImageH(bool flip) { flipImageH_ = flip; }
protected:
uint32_t pointerDownMask_;
private:
int bgImg_;
int img_;
float scale_;
bool flipImageH_;
};
class PSPButton : public MultiTouchButton {
public:
PSPButton(int pspButtonBit, int bgImg, int img, float scale, UI::LayoutParams *layoutParams)
: MultiTouchButton(bgImg, img, scale, layoutParams), pspButtonBit_(pspButtonBit) {
}
virtual void Touch(const TouchInput &input);
virtual bool IsDown();
private:
int pspButtonBit_;
};
class PSPCross : public UI::View {
public:
PSPCross(int arrowIndex, int overlayIndex, float scale, UI::LayoutParams *layoutParams);
virtual void Touch(const TouchInput &input);
virtual void Draw(UIContext &dc);
virtual void GetContentDimensions(const UIContext &dc, float &w, float &h) const;
void set(float radius, float scale = 1.0f) {
radius_ = radius;
scale_ = scale;
}
private:
float radius_;
float scale_;
int arrowIndex_;
int overlayIndex_;
int down_;
};
class PSPStick : public UI::View {
public:
virtual void Touch(const TouchInput &input);
virtual void Draw(UIContext &dc);
virtual void GetContentDimensions(const UIContext &dc, float &w, float &h) const;
private:
int bgImageIndex_;
int stickImageIndex_;
int stick_;
int stick_size_;
float stick_x_;
float stick_y_;
float scale_;
bool dragging_[MAX_POINTERS];
bool lastPointerDown_[MAX_POINTERS];
// maintained for drawing only
float stick_delta_x_;
float stick_delta_y_;
};
void LayoutGamepad(int w, int h); void LayoutGamepad(int w, int h);
void UpdateGamepad(InputState &input_state); void UpdateGamepad(InputState &input_state);
void DrawGamepad(DrawBuffer &db, float opacity); void DrawGamepad(DrawBuffer &db, float opacity);
UI::ViewGroup *CreatePadLayout();

View File

@ -613,7 +613,7 @@ void NativeShutdown() {
// boot up correctly with "dirty" global variables currently, so we hack around that // boot up correctly with "dirty" global variables currently, so we hack around that
// by simply exiting. // by simply exiting.
#ifdef ANDROID #ifdef ANDROID
ELOG("NativeShutdown called"); ILOG("NativeShutdown called");
exit(0); exit(0);
#endif #endif
} }

2
native

@ -1 +1 @@
Subproject commit 13b8277bd3229fe2ea56b082fc34de773be42257 Subproject commit b059027359d69dec21fc5b392378fd00a1d45043