mirror of
https://github.com/0ldsk00l/nestopia.git
synced 2025-04-02 10:31:51 -04:00
245 lines
6.6 KiB
C++
245 lines
6.6 KiB
C++
////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Nestopia - NES/Famicom emulator written in C++
|
|
//
|
|
// Copyright (C) 2003-2008 Martin Freij
|
|
//
|
|
// This file is part of Nestopia.
|
|
//
|
|
// Nestopia is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation; either version 2 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Nestopia is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Nestopia; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "resource/resource.h"
|
|
#include "NstWindowParam.hpp"
|
|
#include "NstManager.hpp"
|
|
#include "NstManagerInput.hpp"
|
|
|
|
namespace Nestopia
|
|
{
|
|
namespace Managers
|
|
{
|
|
Input::Cursor::Cursor(Window::Custom& w,const Screening& i,const Screening& o)
|
|
:
|
|
hCursor ( Resource::Cursor::GetArrow() ),
|
|
hCurrent ( Resource::Cursor::GetArrow() ),
|
|
deadline ( NO_DEADLINE ),
|
|
window ( w ),
|
|
wheel ( WHEEL_MAX ),
|
|
getInputRect ( i ),
|
|
getOutputRect ( o ),
|
|
gun ( IDC_CURSOR_GUN ),
|
|
primaryButtonId ( ::GetSystemMetrics( SM_SWAPBUTTON ) ? VK_RBUTTON : VK_LBUTTON ),
|
|
secondaryButtonId ( primaryButtonId == VK_LBUTTON ? VK_RBUTTON : VK_LBUTTON )
|
|
{
|
|
static const Window::MsgHandler::Entry<Input::Cursor> messages[] =
|
|
{
|
|
{ WM_SETCURSOR, &Cursor::OnSetCursor },
|
|
{ WM_MOUSEMOVE, &Cursor::OnNop },
|
|
{ WM_LBUTTONDOWN, &Cursor::OnNop },
|
|
{ WM_RBUTTONDOWN, &Cursor::OnRButtonDownNop },
|
|
{ WM_LBUTTONUP, &Cursor::OnNop },
|
|
{ WM_RBUTTONUP, &Cursor::OnNop },
|
|
{ WM_MOUSEWHEEL, &Cursor::OnWheel }
|
|
};
|
|
|
|
window.Messages().Add( this, messages );
|
|
}
|
|
|
|
Input::Cursor::~Cursor()
|
|
{
|
|
window.Messages().Remove( this );
|
|
}
|
|
|
|
void Input::Cursor::Acquire(Emulator& emulator)
|
|
{
|
|
bool autoHide = false;
|
|
bool usesRButton = false;
|
|
|
|
if
|
|
(
|
|
Nes::Input(emulator).IsControllerConnected( Nes::Input::ZAPPER ) ||
|
|
Nes::Input(emulator).IsControllerConnected( Nes::Input::BANDAIHYPERSHOT )
|
|
)
|
|
{
|
|
hCursor = gun;
|
|
usesRButton = true;
|
|
}
|
|
else if (Nes::Input(emulator).IsControllerConnected( Nes::Input::POWERGLOVE ))
|
|
{
|
|
hCursor = NULL;
|
|
usesRButton = true;
|
|
}
|
|
else if
|
|
(
|
|
Nes::Input(emulator).IsControllerConnected( Nes::Input::PADDLE ) ||
|
|
Nes::Input(emulator).IsControllerConnected( Nes::Input::HORITRACK ) ||
|
|
Nes::Input(emulator).IsControllerConnected( Nes::Input::PACHINKO ) ||
|
|
Nes::Input(emulator).IsControllerConnected( Nes::Input::OEKAKIDSTABLET ) ||
|
|
Nes::Input(emulator).IsControllerConnected( Nes::Input::MOUSE )
|
|
)
|
|
{
|
|
hCursor = NULL;
|
|
}
|
|
else
|
|
{
|
|
hCursor = Resource::Cursor::GetArrow();
|
|
autoHide = true;
|
|
}
|
|
|
|
Window::MsgHandler& router = window.Messages();
|
|
|
|
router[ WM_MOUSEMOVE ].Set( this, autoHide ? &Cursor::OnMouseMove : &Cursor::OnNop );
|
|
router[ WM_LBUTTONDOWN ].Set( this, autoHide ? &Cursor::OnLButtonDown : &Cursor::OnNop );
|
|
router[ WM_LBUTTONUP ].Set( this, autoHide ? &Cursor::OnButtonUp : &Cursor::OnNop );
|
|
router[ WM_RBUTTONDOWN ].Set( this, autoHide ? &Cursor::OnRButtonDown : usesRButton ? &Cursor::OnNop : &Cursor::OnRButtonDownNop );
|
|
router[ WM_RBUTTONUP ].Set( this, autoHide ? &Cursor::OnButtonUp : &Cursor::OnNop );
|
|
|
|
hCurrent = hCursor;
|
|
deadline = autoHide ? ::GetTickCount() + TIME_OUT : NO_DEADLINE;
|
|
}
|
|
|
|
void Input::Cursor::Unacquire()
|
|
{
|
|
deadline = NO_DEADLINE;
|
|
hCurrent = hCursor = Resource::Cursor::GetArrow();
|
|
|
|
Window::MsgHandler& router = window.Messages();
|
|
|
|
router[ WM_MOUSEMOVE ].Set( this, &Cursor::OnNop );
|
|
router[ WM_LBUTTONDOWN ].Set( this, &Cursor::OnNop );
|
|
router[ WM_LBUTTONUP ].Set( this, &Cursor::OnNop );
|
|
router[ WM_RBUTTONDOWN ].Set( this, &Cursor::OnRButtonDownNop );
|
|
router[ WM_RBUTTONUP ].Set( this, &Cursor::OnNop );
|
|
}
|
|
|
|
void Input::Cursor::AutoHide()
|
|
{
|
|
deadline = NO_DEADLINE;
|
|
|
|
if (window.Active())
|
|
{
|
|
Window::Point pos;
|
|
::GetCursorPos( &pos );
|
|
|
|
if (Window::Rect(window.PictureCoordinates()).ScreenTransform(window).Inside( pos ))
|
|
::SetCursor( hCurrent=NULL );
|
|
}
|
|
}
|
|
|
|
#ifdef NST_MSVC_OPTIMIZE
|
|
#pragma optimize("t", on)
|
|
#endif
|
|
|
|
bool Input::Cursor::Poll(uint& x,uint& y,uint& lbutton,uint* const rbutton) const
|
|
{
|
|
POINT mouse;
|
|
::GetCursorPos( &mouse );
|
|
|
|
Window::Rect output;
|
|
getOutputRect( output );
|
|
|
|
if (output.Inside( mouse ))
|
|
{
|
|
Window::Rect input;
|
|
getInputRect( input );
|
|
|
|
x = input.left + (mouse.x - output.left) * (uint(input.Width())-1) / output.Width();
|
|
y = input.top + (mouse.y - output.top) * (uint(input.Height())-1) / output.Height();
|
|
|
|
if (window.Active())
|
|
{
|
|
lbutton = ::GetAsyncKeyState( primaryButtonId ) & 0x8000U;
|
|
|
|
if (rbutton)
|
|
*rbutton = ::GetAsyncKeyState( secondaryButtonId ) & 0x8000U;
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
lbutton = 0;
|
|
|
|
if (rbutton)
|
|
*rbutton = 0;
|
|
|
|
return false;
|
|
}
|
|
|
|
ibool Input::Cursor::OnNop(Window::Param&)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
ibool Input::Cursor::OnSetCursor(Window::Param& param)
|
|
{
|
|
if (LOWORD(param.lParam) == HTCLIENT)
|
|
{
|
|
param.lResult = true;
|
|
::SetCursor( hCurrent );
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
ibool Input::Cursor::OnMouseMove(Window::Param&)
|
|
{
|
|
hCurrent = hCursor;
|
|
deadline = ::GetTickCount() + TIME_OUT;
|
|
return true;
|
|
}
|
|
|
|
ibool Input::Cursor::OnLButtonDown(Window::Param&)
|
|
{
|
|
deadline = NO_DEADLINE;
|
|
::SetCursor( hCurrent=hCursor );
|
|
return true;
|
|
}
|
|
|
|
ibool Input::Cursor::OnRButtonDown(Window::Param&)
|
|
{
|
|
deadline = NO_DEADLINE;
|
|
::SetCursor( hCurrent=hCursor );
|
|
window.SendCommand( IDM_VIEW_MENU );
|
|
return true;
|
|
}
|
|
|
|
ibool Input::Cursor::OnRButtonDownNop(Window::Param&)
|
|
{
|
|
window.SendCommand( IDM_VIEW_MENU );
|
|
return true;
|
|
}
|
|
|
|
ibool Input::Cursor::OnButtonUp(Window::Param&)
|
|
{
|
|
::SetCursor( hCurrent=hCursor );
|
|
deadline = ::GetTickCount() + TIME_OUT;
|
|
return true;
|
|
}
|
|
|
|
ibool Input::Cursor::OnWheel(Window::Param& param)
|
|
{
|
|
wheel += GET_WHEEL_DELTA_WPARAM(param.wParam);
|
|
wheel = NST_CLAMP(wheel,WHEEL_MIN,WHEEL_MAX);
|
|
|
|
return true;
|
|
}
|
|
|
|
#ifdef NST_MSVC_OPTIMIZE
|
|
#pragma optimize("", on)
|
|
#endif
|
|
}
|
|
}
|