Implements support for Alt-Enter fullscreen switching, DX9 only! DX10 is still broken, will stay that way until some clever person figures out how to make it work. I've make some comment guidelines in source (see MTGS.cpp).

... also, it's possible DX10 fullscreen will work if bound to, say, Shift-F9 (ie, something beside alt-enter, which DX10 decides to wrangle full unrelenting control of, without our explicit consent, and needs some 20 lines of random COM chaos to disable).

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2282 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-12-01 15:33:56 +00:00
parent 62384ea56a
commit 97d52323d1
8 changed files with 103 additions and 41 deletions

View File

@ -204,6 +204,26 @@ void SysMtgsThread::OpenPlugin()
throw Exception::PluginOpenError( PluginId_GS );
}
// This is the preferred place to implement DXGI fullscreen overrides, using LoadLibrary.
// But I hate COM, I don't know to make this work, and I don't have DX10, so I give up
// and enjoy my working DX9 alt-enter instead. Someone else can fix this mess. --air
// Also: Prolly needs some DX10 header includes? Which ones? Too many, I gave up.
#if 0 // defined(__WXMSW__) && defined(_MSC_VER)
wxDynamicLibrary dynlib( L"dxgi.dll" );
SomeFuncTypeIDunno isThisEvenTheRightFunctionNameIDunno = dynlib.GetSymbol("CreateDXGIFactory");
if( isThisEvenTheRightFunctionNameIDunno )
{
// Is this how LoadLibrary for COM works? I dunno. I dont care.
IDXGIFactory* pFactory;
hr = isThisEvenTheRightFunctionNameIDunno(__uuidof(IDXGIFactory), (void**)(&pFactory) );
pFactory->MakeWindowAssociation((HWND)&pDsp, DXGI_MWA_NO_WINDOW_CHANGES);
pFactory->Release();
}
#endif
m_PluginOpened = true;
m_sem_OpenDone.Post();

View File

@ -414,6 +414,9 @@ public:
void SysExecute( CDVD_SourceType cdvdsrc, const wxString& elf_override=wxEmptyString );
void SysReset();
GSFrame& GetGSFrame() const;
GSFrame* GetGSFramePtr() const { return m_gsFrame; }
MainEmuFrame& GetMainFrame() const;
MainEmuFrame* GetMainFramePtr() const { return m_MainFrame; }
bool HasMainFrame() const { return m_MainFrame != NULL; }
@ -574,6 +577,9 @@ DECLARE_APP(Pcsx2App)
#define sMainFrame \
if( MainEmuFrame* __frame_ = GetMainFramePtr() ) (*__frame_)
#define sGSFrame \
if( GSFrame* __gsframe_ = wxGetApp().GetGSFramePtr() ) (*__gsframe_)
// Use this within the scope of a wxWindow (wxDialog or wxFrame). If the window has a valid menu
// bar, the command will run, otherwise it will be silently ignored. :)
#define sMenuBar \

View File

@ -187,8 +187,13 @@ void AppCoreThread::StateCheckInThread()
{
case WXK_SHIFT: m_kevt.m_shiftDown = isDown; return;
case WXK_CONTROL: m_kevt.m_controlDown = isDown; return;
case WXK_ALT: // ALT/MENU are usually the same key? I'm confused.
case WXK_MENU: m_kevt.m_altDown = isDown; return;
}
if( vkey != WXK_ALT )
Console.Warning( "It's not Alt!" );
m_kevt.m_keyCode = vkey;
wxGetApp().PostPadKey( m_kevt );

View File

@ -96,7 +96,7 @@ void Pcsx2App::PostPadKey( wxKeyEvent& evt )
}
else
{
evt.SetId( m_gsFrame->GetId() );
evt.SetId( m_gsFrame->GetViewport()->GetId() );
m_gsFrame->AddPendingEvent( evt );
}
}
@ -391,6 +391,12 @@ MainEmuFrame& Pcsx2App::GetMainFrame() const
return *m_MainFrame;
}
GSFrame& Pcsx2App::GetGSFrame() const
{
pxAssert( m_gsFrame != NULL );
return *m_gsFrame;
}
void AppApplySettings( const AppConfig* oldconf )
{
AllowFromMainThreadOnly();
@ -467,7 +473,7 @@ void Pcsx2App::OpenGsFrame()
m_gsFrame = new GSFrame( m_MainFrame, L"PCSX2" );
m_gsFrame->SetFocus();
pDsp = (uptr)m_gsFrame->GetWindow()->GetHandle();
pDsp = (uptr)m_gsFrame->GetViewport()->GetHandle();
m_gsFrame->Show();
// The "in the main window" quickie hack...

View File

@ -20,7 +20,7 @@
#include "wx/utils.h"
void GSFrame::InitDefaultAccelerators()
void GSPanel::InitDefaultAccelerators()
{
typedef KeyAcceleratorCode AAC;
@ -37,9 +37,11 @@ void GSFrame::InitDefaultAccelerators()
m_Accels.Map( AAC( WXK_F8 ), "Sys_TakeSnapshot" );
m_Accels.Map( AAC( WXK_F9 ), "Sys_RenderswitchToggle" );
m_Accels.Map( AAC( WXK_F10 ), "Sys_LoggingToggle" );
//m_Accels.Map( AAC( WXK_F10 ), "Sys_LoggingToggle" );
m_Accels.Map( AAC( WXK_F11 ), "Sys_FreezeGS" );
m_Accels.Map( AAC( WXK_F12 ), "Sys_RecordingToggle" );
m_Accels.Map( AAC( WXK_RETURN ).Alt(), "FullscreenToggle" );
}
GSPanel::GSPanel( wxWindow* parent )
@ -53,6 +55,8 @@ GSPanel::GSPanel( wxWindow* parent )
if ( !wxWindow::Create(parent, wxID_ANY) )
throw Exception::RuntimeError( "GSPanel constructor esplode!!" );
InitDefaultAccelerators();
if( g_Conf->GSWindow.AlwaysHideMouse )
{
SetCursor( wxCursor(wxCURSOR_BLANK) );
@ -61,6 +65,7 @@ GSPanel::GSPanel( wxWindow* parent )
Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler (GSPanel::OnCloseWindow) );
Connect( wxEVT_SIZE, wxSizeEventHandler (GSPanel::OnResize) );
Connect( wxEVT_KEY_DOWN, wxKeyEventHandler (GSPanel::OnKeyDown) );
Connect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(GSPanel::OnShowMouse) );
Connect(wxEVT_MIDDLE_UP, wxMouseEventHandler(GSPanel::OnShowMouse) );
@ -143,6 +148,30 @@ void GSPanel::OnHideMouseTimeout( wxTimerEvent& evt )
m_CursorShown = false;
}
void GSPanel::OnKeyDown( wxKeyEvent& evt )
{
// HACK: Legacy PAD plugins expect PCSX2 to ignore keyboard messages on the GS Window while
// the PAD plugin is open, so ignore here (PCSX2 will direct messages routed from PAD directly
// to the APP level message handler, which in turn routes them right back here -- yes it's
// silly, but oh well).
if( (PADopen != NULL) && CoreThread.IsOpen() ) return;
const GlobalCommandDescriptor* cmd = NULL;
m_Accels.TryGetValue( KeyAcceleratorCode( evt ).val32, cmd );
if( cmd == NULL )
{
evt.Skip(); // Let the global APP handle it if it wants
return;
}
if( cmd != NULL )
{
DbgCon.WriteLn( "(gsFrame) Invoking command: %s", cmd->Id );
cmd->Invoke();
}
}
void __evt_fastcall GSPanel::OnSettingsApplied( void* obj, int& evt )
{
@ -162,8 +191,6 @@ GSFrame::GSFrame(wxWindow* parent, const wxString& title)
{
SetIcons( wxGetApp().GetIconBundle() );
InitDefaultAccelerators();
SetClientSize( g_Conf->GSWindow.WindowSize );
m_gspanel = new GSPanel( this );
@ -171,7 +198,6 @@ GSFrame::GSFrame(wxWindow* parent, const wxString& title)
//Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler (GSFrame::OnCloseWindow) );
Connect( wxEVT_MOVE, wxMoveEventHandler (GSFrame::OnMove) );
Connect( wxEVT_SIZE, wxSizeEventHandler (GSFrame::OnResize) );
Connect( wxEVT_KEY_DOWN, wxKeyEventHandler (GSFrame::OnKeyDown) );
}
GSFrame::~GSFrame() throw()
@ -179,7 +205,7 @@ GSFrame::~GSFrame() throw()
CoreThread.Suspend(); // Just in case...!
}
wxWindow* GSFrame::GetWindow()
wxWindow* GSFrame::GetViewport()
{
return m_gspanel;
}
@ -206,27 +232,3 @@ void GSFrame::OnResize( wxSizeEvent& evt )
// if we skip, the panel is auto-sized to fit our window anyway, which we do not want!
//evt.Skip();
}
void GSFrame::OnKeyDown( wxKeyEvent& evt )
{
// HACK: Legacy PAD plugins expect PCSX2 to ignore keyboard messages on the GS Window while
// the PAD plugin is open, so ignore here (PCSX2 will direct messages routed from PAD directly
// to the APP level message handler, which in turn routes them right back here -- yes it's
// silly, but oh well).
if( (PADopen != NULL) && CoreThread.IsOpen() ) return;
const GlobalCommandDescriptor* cmd = NULL;
m_Accels.TryGetValue( KeyAcceleratorCode( evt ).val32, cmd );
if( cmd == NULL )
{
evt.Skip(); // Let the global APP handle it if it wants
return;
}
if( cmd != NULL )
{
DbgCon.WriteLn( "(gsFrame) Invoking command: %s", cmd->Id );
cmd->Invoke();
}
}

View File

@ -153,6 +153,14 @@ namespace Implementations
Console.Warning("hardware registers dumped EE:%x, IOP:%x\n", cpuRegs.pc, psxRegs.pc);
#endif
}
static bool isFullscreen = false;
void FullscreenToggle()
{
isFullscreen = !isFullscreen;
sGSFrame.ShowFullScreen( isFullscreen );
}
}
// --------------------------------------------------------------------------------------
@ -242,6 +250,11 @@ static const GlobalCommandDescriptor CommandDeclarations[] =
NULL,
},
{ "FullscreenToggle",
Implementations::FullscreenToggle,
NULL,
NULL,
},
// Command Declarations terminator:
// (must always be last in list!!)
@ -305,6 +318,10 @@ void Pcsx2App::InitDefaultGlobalAccelerators()
GlobalAccels.Map( AAC( WXK_TAB ), "Framelimiter_TurboToggle" );
GlobalAccels.Map( AAC( WXK_TAB ).Shift(), "Framelimiter_MasterToggle" );
// Hack! The following bindings are temporary hacks which are needed because of issues
// with PAD plugin interfacing (the local window-based accelerators in GSPanel are
// currently ignored).
GlobalAccels.Map( AAC( WXK_ESCAPE ), "Sys_Suspend");
GlobalAccels.Map( AAC( WXK_F8 ), "Sys_TakeSnapshot");
GlobalAccels.Map( AAC( WXK_F9 ), "Sys_RenderswitchToggle");
@ -312,4 +329,6 @@ void Pcsx2App::InitDefaultGlobalAccelerators()
GlobalAccels.Map( AAC( WXK_F10 ), "Sys_LoggingToggle");
GlobalAccels.Map( AAC( WXK_F11 ), "Sys_FreezeGS");
GlobalAccels.Map( AAC( WXK_F12 ), "Sys_RecordingToggle");
GlobalAccels.Map( AAC( WXK_RETURN ).Alt(), "FullscreenToggle" );
}

View File

@ -27,6 +27,7 @@
class GSPanel : public wxWindow
{
protected:
AcceleratorDictionary m_Accels;
EventListenerBinding<int> m_Listener_SettingsApplied;
wxTimer m_HideMouseTimer;
bool m_CursorShown;
@ -41,10 +42,13 @@ public:
protected:
static void __evt_fastcall OnSettingsApplied( void* obj, int& evt );
void InitDefaultAccelerators();
void OnCloseWindow( wxCloseEvent& evt );
void OnResize(wxSizeEvent& event);
void OnShowMouse( wxMouseEvent& evt );
void OnHideMouseTimeout( wxTimerEvent& evt );
void OnKeyDown( wxKeyEvent& evt );
};
// --------------------------------------------------------------------------------------
@ -53,21 +57,17 @@ protected:
class GSFrame : public wxFrame
{
protected:
AcceleratorDictionary m_Accels;
GSPanel* m_gspanel;
public:
GSFrame(wxWindow* parent, const wxString& title);
virtual ~GSFrame() throw();
wxWindow* GetWindow();
wxWindow* GetViewport();
protected:
void InitDefaultAccelerators();
void OnMove( wxMoveEvent& evt );
void OnResize( wxSizeEvent& evt );
void OnKeyDown( wxKeyEvent& evt );
};
struct PluginMenuAddition

View File

@ -131,12 +131,16 @@ void pxLogTextCtrl::ConcludeIssue( int lines )
// makes logging very slow, so we only send the message for status changes, so that the
// log aligns itself nicely when we pause emulation or when errors occur.
m_win32_StupidRefreshTricks += lines;
m_win32_StupidRefreshTricks %= m_win32_LinesPerPage;
if( m_win32_StupidRefreshTricks > m_win32_LinesPerScroll )
//m_win32_StupidRefreshTricks += lines;
//if( m_win32_StupidRefreshTricks > m_win32_LinesPerScroll )
{
wxTextPos showpos = XYToPosition( 1, GetNumberOfLines()-m_win32_LinesPerScroll );
if( showpos > 0 )
ShowPosition( showpos );
m_win32_StupidRefreshTricks = 0;
::SendMessage((HWND)GetHWND(), WM_VSCROLL, SB_BOTTOM, (LPARAM)NULL);
//::SendMessage((HWND)GetHWND(), WM_VSCROLL, SB_BOTTOM, (LPARAM)NULL);
}
#endif
}