mirror of https://github.com/stella-emu/stella.git
First of all, I forgot to include the MainWin32 class before, so it
really didn't compile :) And now for the changes. 1) I've updated the DirectInput class to DirectInput 8, and moved to an event-based system, somewhat similar to SDL. Only the keyboard is supported for now, but adding joystick and mouse should be quite easy. 2) I've (almost completely) moved the FrameBuffer stuff out of MainWin32 and into FrameBufferWin32, where it actually belongs. Next, I'll work on more code cleanups, and then I'll attempt to switch to the experimental DirectDraw code (so we have windowed *and* fullscreen modes dynamically). All things considered, its coming together faster than I thought ... git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@205 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
9d2e1cfcc0
commit
24968d9976
|
@ -13,12 +13,14 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: EventHandler.cxx,v 1.18 2003-11-06 22:22:32 stephena Exp $
|
||||
// $Id: EventHandler.cxx,v 1.19 2003-11-13 00:25:07 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
#include "pch.hxx"
|
||||
|
||||
#include "Console.hxx"
|
||||
#include "Event.hxx"
|
||||
#include "EventHandler.hxx"
|
||||
|
@ -155,7 +157,7 @@ void EventHandler::sendEvent(Event::Type event, Int32 state)
|
|||
else if(event == Event::Quit)
|
||||
{
|
||||
myQuitStatus = !myQuitStatus;
|
||||
myConsole->settings().saveConfig();
|
||||
// myConsole->settings().saveConfig();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ LPCTSTR g_ctszDebugLog = _T("stella.log");
|
|||
BOOL CCyberstellaApp::InitInstance()
|
||||
{
|
||||
// Delete previous Debug Log
|
||||
(void)::DeleteFile(g_ctszDebugLog);
|
||||
(void)::DeleteFile(g_ctszDebugLog);
|
||||
|
||||
// Avoid Second instance
|
||||
CreateMutex(NULL,TRUE,_T("StellaXMutex"));
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="dxguid.lib ddraw.lib dsound.lib"
|
||||
AdditionalDependencies="dxguid.lib ddraw.lib dsound.lib dinput8.lib"
|
||||
OutputFile=".\Debug/Cyberstella.exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
|
|
|
@ -118,9 +118,9 @@ BOOL CCyberstellaView::PreCreateWindow(CREATESTRUCT& cs)
|
|||
|
||||
void CCyberstellaView::OnInitialUpdate()
|
||||
{
|
||||
CFormView::OnInitialUpdate();
|
||||
GetParentFrame()->RecalcLayout();
|
||||
ResizeParentToFit();
|
||||
CFormView::OnInitialUpdate();
|
||||
GetParentFrame()->RecalcLayout();
|
||||
ResizeParentToFit();
|
||||
|
||||
// Init ListControl, parse stella.pro
|
||||
PostMessage(MSG_VIEW_INITIALIZE);
|
||||
|
@ -318,65 +318,3 @@ void CCyberstellaView::playRom(LONG gameID)
|
|||
// Set focus back to the rom list
|
||||
m_List.SetFocus();
|
||||
}
|
||||
|
||||
#if 0 // MainWin32
|
||||
try
|
||||
{
|
||||
// If this throws an exception, then it's probably a bad cartridge
|
||||
pConsole = new Console( pImage, dwActualSize, pszFileName, *pSettings,
|
||||
*thePropertiesSet, 31400 );
|
||||
if ( pConsole == NULL )
|
||||
goto exit;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
// FIXME ::MessageBox(GetModuleHandle(NULL),
|
||||
// NULL, IDS_CANTSTARTCONSOLE);
|
||||
|
||||
goto exit;
|
||||
}
|
||||
|
||||
#ifdef USE_FS
|
||||
pwnd = new CDirectXFullScreen( m_pGlobalData, pConsole, pSound );
|
||||
#else
|
||||
pwnd = new CDirectXWindow( m_pGlobalData, pConsole, pSound );
|
||||
#endif
|
||||
if( pwnd == NULL )
|
||||
goto exit;
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
#ifdef USE_FS
|
||||
if (m_pGlobalData->bAutoSelectVideoMode)
|
||||
{
|
||||
hr = pwnd->Initialize( );
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Initialize with 640 x 480
|
||||
//
|
||||
|
||||
hr = pwnd->Initialize( FORCED_VIDEO_CX, FORCED_VIDEO_CY );
|
||||
}
|
||||
#else
|
||||
hr = pwnd->Initialize(*this, m_List.getCurrentName());
|
||||
#endif
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
TRACE( "CWindow::Initialize failed, err = %X", hr );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if(!m_pGlobalData->bNoSound)
|
||||
{
|
||||
SoundWin32* pSoundWin32 = static_cast<SoundWin32*>( pSound );
|
||||
|
||||
hr = pSoundWin32->Initialize(*pwnd);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
TRACE( "Sndwin32 Initialize failed, err = %X", hr );
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -13,174 +13,141 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: DirectInput.cxx,v 1.2 2003-11-11 18:55:39 stephena Exp $
|
||||
// $Id: DirectInput.cxx,v 1.3 2003-11-13 00:25:07 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#define DIRECTINPUT_VERSION 0x700
|
||||
|
||||
#include "pch.hxx"
|
||||
#include "resource.h"
|
||||
|
||||
#include "DirectInput.hxx"
|
||||
|
||||
|
||||
//
|
||||
// DirectInput
|
||||
//
|
||||
|
||||
DirectInput::DirectInput(HWND hwnd, DWORD dwDevType, int nButtonCount)
|
||||
: m_hwnd( hwnd )
|
||||
, m_piDID(NULL)
|
||||
, m_piDI(NULL)
|
||||
, m_dwDevType(dwDevType)
|
||||
, m_nButtonCount(nButtonCount)
|
||||
, m_pButtons(NULL)
|
||||
, m_lX(0)
|
||||
, m_lY(0)
|
||||
, m_fInitialized( FALSE )
|
||||
DirectInput::DirectInput()
|
||||
: myHWND(NULL),
|
||||
mylpdi(NULL),
|
||||
myKeyboard(NULL),
|
||||
myMouse(NULL),
|
||||
myLeftJoystick(NULL),
|
||||
myRightJoystick(NULL)
|
||||
{
|
||||
TRACE("DirectInput::DirectInput");
|
||||
}
|
||||
|
||||
DirectInput::~DirectInput(
|
||||
)
|
||||
DirectInput::~DirectInput()
|
||||
{
|
||||
TRACE("DirectInput::~DirectInput");
|
||||
|
||||
Cleanup();
|
||||
cleanup();
|
||||
}
|
||||
|
||||
HRESULT DirectInput::Initialize(
|
||||
void
|
||||
)
|
||||
bool DirectInput::initialize(HWND hwnd)
|
||||
{
|
||||
TRACE("DirectInput::Initialize");
|
||||
// FIXME - this should move to the constructor
|
||||
if(FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION,
|
||||
IID_IDirectInput8, (void**)&mylpdi, NULL)))
|
||||
return false;
|
||||
|
||||
HINSTANCE hInstance = (HINSTANCE)::GetWindowLong( m_hwnd, GWL_HINSTANCE );
|
||||
// initialize the keyboard
|
||||
if(FAILED(mylpdi->CreateDevice(GUID_SysKeyboard, &myKeyboard, NULL)))
|
||||
return false;
|
||||
if(FAILED(myKeyboard->SetDataFormat(&c_dfDIKeyboard)))
|
||||
return false;
|
||||
if(FAILED(myKeyboard->SetCooperativeLevel(hwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)))
|
||||
return false;
|
||||
|
||||
if ( m_fInitialized )
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
DIPROPDWORD dipdw;
|
||||
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
|
||||
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
||||
dipdw.diph.dwObj = 0;
|
||||
dipdw.diph.dwHow = DIPH_DEVICE;
|
||||
dipdw.dwData = 256;
|
||||
if(FAILED(myKeyboard->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)))
|
||||
return false;
|
||||
|
||||
if ( m_hwnd == NULL )
|
||||
{
|
||||
// This is for CDisabledJoystick
|
||||
if(FAILED(myKeyboard->Acquire()))
|
||||
return false;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
// Make sure to reset the event buffer
|
||||
myEventBufferPos = 0;
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
UINT uMsg = 0; // if ( FAILED(hr) )
|
||||
|
||||
hr = ::CoCreateInstance( CLSID_DirectInput,
|
||||
NULL,
|
||||
CLSCTX_SERVER,
|
||||
IID_IDirectInput,
|
||||
(void**)&m_piDI );
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
TRACE( "WARNING: CCI on DirectInput failed, error=%X", hr );
|
||||
|
||||
//
|
||||
// Note -- I don't fail here so that machines with NT4 (which doesn't
|
||||
// have DirectX 5.0) don't fail
|
||||
//
|
||||
// For this to work, Update() must begin with
|
||||
// if (GetDevice() == NULL) { return E_FAIL; }
|
||||
//
|
||||
|
||||
// uMsg = IDS_NODIRECTINPUT;
|
||||
hr = S_FALSE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize it
|
||||
//
|
||||
|
||||
hr = m_piDI->Initialize( hInstance, DIRECTINPUT_VERSION );
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
TRACE("IDI::Initialize failed");
|
||||
uMsg = IDS_DI_INIT_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
//
|
||||
// enumerate to find proper device
|
||||
// The callback will set m_piDID
|
||||
//
|
||||
|
||||
TRACE("\tCalling EnumDevices");
|
||||
|
||||
hr = m_piDI->EnumDevices( m_dwDevType,
|
||||
EnumDevicesProc,
|
||||
this,
|
||||
DIEDFL_ATTACHEDONLY );
|
||||
if ( m_piDID )
|
||||
{
|
||||
TRACE("\tGot a device!");
|
||||
|
||||
(void)m_piDID->SetCooperativeLevel( m_hwnd,
|
||||
DISCL_NONEXCLUSIVE
|
||||
| DISCL_FOREGROUND);
|
||||
|
||||
hr = GetDevice()->Acquire();
|
||||
if ( hr == DIERR_OTHERAPPHASPRIO )
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
m_pButtons = new BYTE[GetButtonCount()];
|
||||
if ( m_pButtons == NULL )
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
m_fInitialized = TRUE;
|
||||
|
||||
cleanup:
|
||||
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
Cleanup();
|
||||
|
||||
if ( uMsg != 0 )
|
||||
{
|
||||
MessageBox( hInstance, m_hwnd, uMsg );
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
return true;
|
||||
}
|
||||
|
||||
void DirectInput::Cleanup(
|
||||
void
|
||||
)
|
||||
void DirectInput::update()
|
||||
{
|
||||
TRACE("DirectInput::Cleanup");
|
||||
HRESULT hr;
|
||||
|
||||
delete[] m_pButtons;
|
||||
if(myKeyboard != NULL)
|
||||
{
|
||||
DIDEVICEOBJECTDATA keyEvents[256];
|
||||
DWORD numKeyEvents = 256;
|
||||
|
||||
if (m_piDID)
|
||||
{
|
||||
m_piDID->Unacquire();
|
||||
m_piDID->Release();
|
||||
m_piDID = NULL;
|
||||
}
|
||||
hr = myKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA),
|
||||
keyEvents, &numKeyEvents, 0 );
|
||||
|
||||
if (m_piDI)
|
||||
{
|
||||
m_piDI->Release();
|
||||
m_piDI = NULL;
|
||||
}
|
||||
if(hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED)
|
||||
{
|
||||
hr = myKeyboard->Acquire();
|
||||
if(hr == DIERR_OTHERAPPHASPRIO)
|
||||
return;
|
||||
|
||||
m_fInitialized = FALSE;
|
||||
hr = myKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA),
|
||||
keyEvents, &numKeyEvents, 0 );
|
||||
}
|
||||
|
||||
// add these new key events to the event buffer
|
||||
for(unsigned int i = 0; i < numKeyEvents; i++ )
|
||||
{
|
||||
uInt32 j = myEventBufferPos;
|
||||
if(j < 100)
|
||||
{
|
||||
myEventBuffer[j].type = (keyEvents[i].dwData & 0x80) ? KEY_DOWN : KEY_UP;
|
||||
myEventBuffer[j].key.key = keyEvents[i].dwOfs;
|
||||
myEventBuffer[j].key.state = (myEventBuffer[j].type == KEY_DOWN) ? 1 : 0;
|
||||
myEventBufferPos++;
|
||||
}
|
||||
else // if we run out of room, then ignore new events
|
||||
{
|
||||
myEventBufferPos = 100;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// else check mouse
|
||||
}
|
||||
|
||||
bool DirectInput::pollEvent(DI_Event* event)
|
||||
{
|
||||
// Pump the event buffer and return if a new event is found
|
||||
if(myEventBufferPos > 0)
|
||||
{
|
||||
*event = myEventBuffer[--myEventBufferPos];
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void DirectInput::cleanup()
|
||||
{
|
||||
if(myMouse)
|
||||
{
|
||||
myMouse->Unacquire();
|
||||
myMouse->Release();
|
||||
myMouse = NULL;
|
||||
}
|
||||
|
||||
if(myKeyboard)
|
||||
{
|
||||
myKeyboard->Unacquire();
|
||||
myKeyboard->Release();
|
||||
myKeyboard = NULL;
|
||||
}
|
||||
|
||||
if(mylpdi)
|
||||
{
|
||||
mylpdi->Release();
|
||||
mylpdi = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
BOOL CALLBACK DirectInput::EnumDevicesProc
|
||||
(
|
||||
const DIDEVICEINSTANCE* lpddi,
|
||||
|
@ -271,46 +238,6 @@ BOOL DirectInput::IsButtonPressed
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
DirectKeyboard::DirectKeyboard(
|
||||
HWND hwnd
|
||||
) : \
|
||||
DirectInput( hwnd, DIDEVTYPE_KEYBOARD, 256 )
|
||||
{
|
||||
TRACE( "DirectKeyboard::DirectKeyboard" );
|
||||
}
|
||||
|
||||
HRESULT DirectKeyboard::Update(
|
||||
void
|
||||
)
|
||||
{
|
||||
if ( GetDevice() == NULL )
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
GetDevice()->Poll();
|
||||
|
||||
hr = GetDevice()->GetDeviceState( GetButtonCount(), m_pButtons );
|
||||
if ( hr == DIERR_INPUTLOST ||
|
||||
hr == DIERR_NOTACQUIRED )
|
||||
{
|
||||
hr = GetDevice()->Acquire();
|
||||
if ( hr == DIERR_OTHERAPPHASPRIO )
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
TRACE( "Acquire = %X", hr );
|
||||
|
||||
GetDevice()->Poll();
|
||||
hr = GetDevice()->GetDeviceState( GetButtonCount(), m_pButtons );
|
||||
}
|
||||
|
||||
ASSERT(hr == S_OK && "Keyboard GetDeviceState failed");
|
||||
return hr;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
@ -546,3 +473,70 @@ HRESULT DirectMouse::Update(
|
|||
|
||||
return hr;
|
||||
}
|
||||
*/
|
||||
|
||||
///////////////////////////////////////
|
||||
// The following was part of initialize
|
||||
///////////////////////////////////////
|
||||
/*
|
||||
// initialize the mouse
|
||||
if (FAILED(lpdi->CreateDevice(GUID_SysMouse, &m_mouse, NULL)))
|
||||
return false;
|
||||
if (FAILED(m_mouse->SetCooperativeLevel(hWnd, DISCL_BACKGROUND |
|
||||
DISCL_NONEXCLUSIVE)))
|
||||
return false;
|
||||
if (FAILED(m_mouse->SetDataFormat(&c_dfDIMouse)))
|
||||
return false;
|
||||
if (FAILED(m_mouse->Acquire()))
|
||||
return false;
|
||||
*/
|
||||
/*
|
||||
//
|
||||
// enumerate to find proper device
|
||||
// The callback will set m_piDID
|
||||
//
|
||||
|
||||
TRACE("\tCalling EnumDevices");
|
||||
|
||||
hr = m_piDI->EnumDevices( m_dwDevType,
|
||||
EnumDevicesProc,
|
||||
this,
|
||||
DIEDFL_ATTACHEDONLY );
|
||||
if ( m_piDID )
|
||||
{
|
||||
TRACE("\tGot a device!");
|
||||
|
||||
(void)m_piDID->SetCooperativeLevel( m_hwnd,
|
||||
DISCL_NONEXCLUSIVE
|
||||
| DISCL_FOREGROUND);
|
||||
|
||||
hr = GetDevice()->Acquire();
|
||||
if ( hr == DIERR_OTHERAPPHASPRIO )
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
m_pButtons = new BYTE[GetButtonCount()];
|
||||
if ( m_pButtons == NULL )
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
m_fInitialized = TRUE;
|
||||
|
||||
cleanup:
|
||||
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
Cleanup();
|
||||
|
||||
if ( uMsg != 0 )
|
||||
{
|
||||
MessageBox( hInstance, m_hwnd, uMsg );
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
*/
|
||||
|
|
|
@ -13,162 +13,60 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: DirectInput.hxx,v 1.3 2003-11-11 18:55:39 stephena Exp $
|
||||
// $Id: DirectInput.hxx,v 1.4 2003-11-13 00:25:07 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef DIRECT_INPUT_HXX
|
||||
#define DIRECT_INPUT_HXX
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "dinput.h"
|
||||
|
||||
class DirectInput
|
||||
{
|
||||
public:
|
||||
DirectInput( HWND hwnd, DWORD dwDevType, int nButtonCount );
|
||||
virtual ~DirectInput( );
|
||||
DirectInput();
|
||||
~DirectInput();
|
||||
|
||||
public:
|
||||
virtual HRESULT Initialize( void );
|
||||
enum type_tt { KEY_DOWN, KEY_UP };
|
||||
|
||||
virtual HRESULT Update( void ) = 0;
|
||||
struct KeyboardEvent
|
||||
{
|
||||
uInt32 key;
|
||||
uInt8 state;
|
||||
};
|
||||
|
||||
void GetPos( LONG* pX, LONG* pY ) const;
|
||||
struct DI_Event
|
||||
{
|
||||
type_tt type;
|
||||
union
|
||||
{
|
||||
KeyboardEvent key;
|
||||
};
|
||||
};
|
||||
|
||||
virtual BOOL IsButtonPressed( int nButton ) const;
|
||||
virtual int GetButtonCount( void ) const;
|
||||
bool initialize(HWND hwnd);
|
||||
|
||||
// I need IDID2 for the Poll method
|
||||
void update();
|
||||
|
||||
IDirectInputDevice2* GetDevice( void ) const;
|
||||
bool pollEvent(DI_Event* event);
|
||||
|
||||
protected:
|
||||
private:
|
||||
DI_Event myEventBuffer[100];
|
||||
uInt32 myEventBufferPos;
|
||||
|
||||
LONG m_lX;
|
||||
LONG m_lY;
|
||||
BYTE* m_pButtons;
|
||||
void cleanup();
|
||||
|
||||
private:
|
||||
static BOOL CALLBACK EnumDevicesProc(const DIDEVICEINSTANCE* lpddi, LPVOID pvRef );
|
||||
|
||||
void Cleanup();
|
||||
|
||||
static BOOL CALLBACK EnumDevicesProc( const DIDEVICEINSTANCE* lpddi,
|
||||
LPVOID pvRef );
|
||||
|
||||
IDirectInput* m_piDI;
|
||||
|
||||
HWND m_hwnd;
|
||||
IDirectInputDevice2* m_piDID;
|
||||
DWORD m_dwDevType;
|
||||
|
||||
const int m_nButtonCount;
|
||||
|
||||
BOOL m_fInitialized;
|
||||
|
||||
DirectInput( const DirectInput& ); // no implementation
|
||||
void operator=( const DirectInput& ); // no implementation
|
||||
|
||||
};
|
||||
|
||||
inline int DirectInput::GetButtonCount(
|
||||
void
|
||||
) const
|
||||
{
|
||||
return m_nButtonCount;
|
||||
}
|
||||
|
||||
|
||||
inline IDirectInputDevice2* DirectInput::GetDevice(
|
||||
void
|
||||
) const
|
||||
{
|
||||
// 060499: Dont assert here, as it's okay if a device isn't available
|
||||
// (client must check for NULL return)
|
||||
return m_piDID;
|
||||
}
|
||||
|
||||
inline void DirectInput::GetPos(
|
||||
LONG* pX,
|
||||
LONG* pY
|
||||
) const
|
||||
{
|
||||
if (pX != NULL)
|
||||
{
|
||||
*pX = m_lX;
|
||||
}
|
||||
|
||||
if (pY != NULL)
|
||||
{
|
||||
*pY = m_lY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class DirectMouse : public DirectInput
|
||||
{
|
||||
public:
|
||||
|
||||
DirectMouse( HWND hwnd );
|
||||
|
||||
HRESULT Update( void );
|
||||
|
||||
private:
|
||||
|
||||
DirectMouse( const DirectMouse& ); // no implementation
|
||||
void operator=( const DirectMouse& ); // no implementation
|
||||
|
||||
};
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class DirectJoystick : public DirectInput
|
||||
{
|
||||
public:
|
||||
|
||||
DirectJoystick( HWND hwnd );
|
||||
|
||||
HRESULT Initialize( void );
|
||||
HRESULT Update( void );
|
||||
|
||||
private:
|
||||
|
||||
DirectJoystick( const DirectJoystick& ); // no implementation
|
||||
void operator=( const DirectJoystick& ); // no implementation
|
||||
|
||||
};
|
||||
|
||||
class CDisabledJoystick : public DirectInput
|
||||
{
|
||||
public:
|
||||
|
||||
CDisabledJoystick( HWND hwnd );
|
||||
|
||||
HRESULT Update( void );
|
||||
|
||||
private:
|
||||
|
||||
CDisabledJoystick( const CDisabledJoystick& ); // no implementation
|
||||
void operator=( const CDisabledJoystick& ); // no implementation
|
||||
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class DirectKeyboard : public DirectInput
|
||||
{
|
||||
public:
|
||||
|
||||
DirectKeyboard( HWND hwnd );
|
||||
|
||||
HRESULT Update( void );
|
||||
|
||||
private:
|
||||
|
||||
DirectKeyboard( const DirectKeyboard& ); // no implementation
|
||||
void operator=( const DirectKeyboard& ); // no implementation
|
||||
HWND myHWND;
|
||||
|
||||
LPDIRECTINPUT8 mylpdi;
|
||||
LPDIRECTINPUTDEVICE8 myKeyboard;
|
||||
LPDIRECTINPUTDEVICE8 myMouse;
|
||||
LPDIRECTINPUTDEVICE8 myLeftJoystick;
|
||||
LPDIRECTINPUTDEVICE8 myRightJoystick;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: FrameBufferWin32.hxx,v 1.1 2003-11-11 18:55:39 stephena Exp $
|
||||
// $Id: FrameBufferWin32.hxx,v 1.2 2003-11-13 00:25:07 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef FRAMEBUFFER_WIN32_HXX
|
||||
|
@ -25,7 +25,12 @@
|
|||
class Console;
|
||||
class MediaSource;
|
||||
|
||||
/**
|
||||
This class implements a DirectX software framebuffer.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: FrameBufferWin32.hxx,v 1.2 2003-11-13 00:25:07 stephena Exp $
|
||||
*/
|
||||
class FrameBufferWin32 : public FrameBuffer
|
||||
{
|
||||
public:
|
||||
|
@ -39,6 +44,9 @@ class FrameBufferWin32 : public FrameBuffer
|
|||
*/
|
||||
virtual ~FrameBufferWin32();
|
||||
|
||||
HWND hwnd() const { return myHWND; }
|
||||
bool windowActive() { return m_fActiveWindow; }
|
||||
|
||||
/**
|
||||
This routine should be called once the console is created to setup
|
||||
the video system for us to use. Return false if any operation fails,
|
||||
|
@ -92,12 +100,12 @@ class FrameBufferWin32 : public FrameBuffer
|
|||
virtual void postFrameUpdate();
|
||||
|
||||
/**
|
||||
This routine is called when the emulation has been paused.
|
||||
This routine is called when the emulation has received
|
||||
a pause event.
|
||||
|
||||
@param status Toggle pause based on status
|
||||
@param status The received pause status
|
||||
*/
|
||||
virtual void pause(bool status);
|
||||
|
||||
virtual void pauseEvent(bool status);
|
||||
/**
|
||||
Toggles between fullscreen and window mode. Grabmouse and hidecursor
|
||||
activated when in fullscreen mode.
|
||||
|
@ -114,72 +122,49 @@ class FrameBufferWin32 : public FrameBuffer
|
|||
*/
|
||||
void resize(int mode);
|
||||
|
||||
/**
|
||||
Shows or hides the cursor based on the given boolean value.
|
||||
*/
|
||||
void showCursor(bool show);
|
||||
|
||||
/**
|
||||
Grabs or ungrabs the mouse based on the given boolean value.
|
||||
*/
|
||||
void grabMouse(bool grab);
|
||||
|
||||
/**
|
||||
Answers if the display is currently in fullscreen mode.
|
||||
*/
|
||||
bool fullScreen() { return isFullscreen; }
|
||||
|
||||
/**
|
||||
Answers the current zoom level of the SDL
|
||||
Answers the current zoom level of the window
|
||||
*/
|
||||
uInt32 zoomLevel() { return theZoomLevel; }
|
||||
|
||||
/**
|
||||
This routine is called whenever the screen needs to be recreated.
|
||||
It updates the global screen variable.
|
||||
*/
|
||||
bool createScreen();
|
||||
|
||||
/**
|
||||
Calculate the maximum window size that the current screen can hold.
|
||||
Only works in X11 for now. If not running under X11, always return 4.
|
||||
*/
|
||||
uInt32 maxWindowSizeForScreen();
|
||||
|
||||
/**
|
||||
Set up the palette for a screen of any depth > 8.
|
||||
Scales the palette by 'shade'.
|
||||
*/
|
||||
void setupPalette(float shade);
|
||||
|
||||
private:
|
||||
// The SDL video buffer
|
||||
// SDL_Surface* myScreen;
|
||||
static LRESULT CALLBACK StaticWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
BOOL WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
static HRESULT WINAPI EnumModesCallback(LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext);
|
||||
|
||||
void cleanup();
|
||||
|
||||
HWND myHWND;
|
||||
bool m_fActiveWindow;
|
||||
|
||||
RECT m_rectScreen;
|
||||
POINT m_ptBlitOffset;
|
||||
|
||||
// Stella objects
|
||||
SIZE mySizeGame;
|
||||
BYTE myPalette[256];
|
||||
|
||||
//
|
||||
// DirectX
|
||||
//
|
||||
IDirectDraw* m_piDD;
|
||||
IDirectDrawSurface* m_piDDSPrimary;
|
||||
IDirectDrawSurface* m_piDDSBack;
|
||||
IDirectDrawPalette* m_piDDPalette;
|
||||
|
||||
static LPCTSTR pszClassName;
|
||||
|
||||
// Used in the dirty update of the SDL surface
|
||||
// RectList* myRectList;
|
||||
|
||||
// SDL initialization flags
|
||||
// uInt32 mySDLFlags;
|
||||
|
||||
// SDL palette
|
||||
// Uint32 palette[256];
|
||||
|
||||
// Used to get window-manager specifics
|
||||
// SDL_SysWMinfo myWMInfo;
|
||||
|
||||
// Indicates the current zoom level of the SDL screen
|
||||
// Indicates the current zoom level of the window
|
||||
uInt32 theZoomLevel;
|
||||
|
||||
// Indicates the maximum zoom of the SDL screen
|
||||
// Indicates the maximum zoom of the window
|
||||
uInt32 theMaxZoomLevel;
|
||||
|
||||
// Indicates if the mouse should be grabbed
|
||||
bool theGrabMouseIndicator;
|
||||
|
||||
// Indicates if the mouse cursor should be hidden
|
||||
bool theHideCursorIndicator;
|
||||
|
||||
// Indicates whether the game is currently in fullscreen
|
||||
bool isFullscreen;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,427 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2002 by Bradford W. Mott
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: MainWin32.cxx,v 1.1 2003-11-13 00:25:07 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#define STRICT
|
||||
|
||||
#include "pch.hxx"
|
||||
#include "resource.h"
|
||||
#include "DirectInput.hxx"
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "Console.hxx"
|
||||
#include "EventHandler.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
#include "FrameBufferWin32.hxx"
|
||||
#include "Settings.hxx"
|
||||
#include "SettingsWin32.hxx"
|
||||
#include "Sound.hxx"
|
||||
#include "SoundWin32.hxx"
|
||||
#include "StellaEvent.hxx"
|
||||
#include "MainWin32.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
MainWin32::MainWin32(const uInt8* image, uInt32 size, const char* filename,
|
||||
Settings& settings, PropertiesSet& properties)
|
||||
: theSettings(settings),
|
||||
thePropertiesSet(properties),
|
||||
myIsInitialized(false),
|
||||
theDisplay(NULL),
|
||||
theSound(NULL),
|
||||
theInput(NULL)
|
||||
{
|
||||
// Setup the DirectX window
|
||||
theDisplay = new FrameBufferWin32();
|
||||
if(!theDisplay)
|
||||
{
|
||||
cleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a sound object for playing audio
|
||||
// string driver = theSettings.getString("sound");
|
||||
// if(driver != "0")
|
||||
// theSound = new SoundWin32();
|
||||
// else
|
||||
theSound = new Sound();
|
||||
/*
|
||||
if(!theSound)
|
||||
{
|
||||
cleanup();
|
||||
return;
|
||||
}
|
||||
*/
|
||||
// theSound->setSoundVolume(theSettings.getInt("volume"));
|
||||
|
||||
// Create the 2600 game console
|
||||
theConsole = new Console(image, size, filename, theSettings, thePropertiesSet,
|
||||
*theDisplay, *theSound);
|
||||
|
||||
// We can now initialize the sound and directinput classes with
|
||||
// the handle to the current window.
|
||||
// This must be done after the console is created, since at this
|
||||
// point we know that the FrameBuffer has been fully initialized
|
||||
|
||||
// Initialize DirectInput
|
||||
theInput = new DirectInput();
|
||||
if(!theInput)
|
||||
{
|
||||
cleanup();
|
||||
return;
|
||||
}
|
||||
theInput->initialize(theDisplay->hwnd());
|
||||
|
||||
myIsInitialized = true;
|
||||
}
|
||||
|
||||
MainWin32::~MainWin32()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
||||
void MainWin32::cleanup()
|
||||
{
|
||||
ShowCursor(TRUE);
|
||||
|
||||
if(theDisplay)
|
||||
delete theDisplay;
|
||||
|
||||
if(theSound)
|
||||
delete theSound;
|
||||
|
||||
if(theInput)
|
||||
delete theInput;
|
||||
|
||||
if(theConsole)
|
||||
delete theConsole;
|
||||
|
||||
myIsInitialized = false;
|
||||
}
|
||||
|
||||
DWORD MainWin32::run()
|
||||
{
|
||||
if(!myIsInitialized)
|
||||
return 0;
|
||||
|
||||
// Get the initial tick count
|
||||
UINT uFrameCount = 0;
|
||||
|
||||
unsigned __int64 uiStartRun;
|
||||
QueryPerformanceCounter( (LARGE_INTEGER*)&uiStartRun );
|
||||
|
||||
// Find out how many ticks occur per second
|
||||
unsigned __int64 uiCountsPerSecond;
|
||||
QueryPerformanceFrequency( (LARGE_INTEGER*)&uiCountsPerSecond );
|
||||
|
||||
const unsigned __int64 uiCountsPerFrame =
|
||||
( uiCountsPerSecond / 60);// FIXME m_rGlobalData->desiredFrameRate);
|
||||
|
||||
unsigned __int64 uiFrameStart;
|
||||
unsigned __int64 uiFrameCurrent;
|
||||
|
||||
// Main message loop
|
||||
MSG msg;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if( ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
|
||||
{
|
||||
if( msg.message == WM_QUIT )
|
||||
{
|
||||
// theConsole->eventHandler().sendEvent(Event::Quit, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
::TranslateMessage( &msg );
|
||||
::DispatchMessage( &msg );
|
||||
}
|
||||
else if (theDisplay->windowActive())
|
||||
{
|
||||
// idle time -- do stella updates
|
||||
++uFrameCount;
|
||||
|
||||
::QueryPerformanceCounter( (LARGE_INTEGER*)&uiFrameStart );
|
||||
|
||||
UpdateEvents();
|
||||
theDisplay->update();
|
||||
theSound->updateSound(*theDisplay->mediaSource());
|
||||
|
||||
// waste time to to meet desired frame rate
|
||||
for(;;)
|
||||
{
|
||||
QueryPerformanceCounter( (LARGE_INTEGER*)&uiFrameCurrent );
|
||||
if((uiFrameCurrent - uiFrameStart) >= uiCountsPerFrame)
|
||||
break;
|
||||
//FIXME else
|
||||
// WaitMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Main message loop done
|
||||
/*
|
||||
if ( m_rGlobalData->bShowFPS)
|
||||
{
|
||||
// get number of scanlines in last frame
|
||||
|
||||
uInt32 uScanLines = rMediaSource.scanlines();
|
||||
|
||||
// Get the final tick count
|
||||
|
||||
unsigned __int64 uiEndRun;
|
||||
::QueryPerformanceCounter( (LARGE_INTEGER*)&uiEndRun );
|
||||
|
||||
// Get number of ticks
|
||||
|
||||
DWORD secs = (DWORD)( ( uiEndRun - uiStartRun ) / uiCountsPerSecond );
|
||||
|
||||
DWORD fps = (secs == 0) ? 0 : (uFrameCount / secs);
|
||||
|
||||
TCHAR pszBuf[1024];
|
||||
wsprintf( pszBuf, _T("Frames drawn: %ld\nFPS: %ld\nScanlines in last frame: %ld\n"),
|
||||
uFrameCount,
|
||||
fps,
|
||||
uScanLines );
|
||||
MessageBox( NULL, pszBuf, _T("Statistics"), MB_OK );
|
||||
}*/
|
||||
|
||||
return msg.wParam;
|
||||
}
|
||||
|
||||
void MainWin32::UpdateEvents()
|
||||
{
|
||||
// Update the input devices, and gather all pending events
|
||||
theInput->update();
|
||||
|
||||
const int nSize = _countof(keyList);
|
||||
DirectInput::DI_Event event;
|
||||
while(theInput->pollEvent(&event))
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case DirectInput::KEY_DOWN:
|
||||
case DirectInput::KEY_UP:
|
||||
uInt32 key = event.key.key;
|
||||
uInt8 state = event.key.state;
|
||||
|
||||
for(uInt32 i = 0; i < sizeof(keyList) / sizeof(Switches); ++i)
|
||||
{
|
||||
if(keyList[i].nVirtKey == key)
|
||||
theConsole->eventHandler().sendKeyEvent(keyList[i].keyCode, state);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// I do this because an event may appear multiple times in the map
|
||||
// and I don't want to undo a set i may have done earlier in the loop
|
||||
//
|
||||
|
||||
|
||||
// long rgKeyEventState[ nSize ];
|
||||
// ZeroMemory( rgKeyEventState, nSize * sizeof(StellaEvent::KeyCode) );
|
||||
|
||||
// Update keyboard
|
||||
/*
|
||||
if(m_pDirectKeyboard->Update() == S_OK)
|
||||
{
|
||||
for(int i = 0; i < nSize; ++i)
|
||||
{
|
||||
int state = (m_pDirectKeyboard->IsButtonPressed(keyList[i].nVirtKey)) ? 1 : 0;
|
||||
theConsole->eventHandler().sendKeyEvent(keyList[i].keyCode, state);
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
//
|
||||
// Update joystick
|
||||
//
|
||||
|
||||
FIXME - add multiple joysticks
|
||||
if (m_pDirectJoystick->Update() == S_OK)
|
||||
{
|
||||
rgEventState[Event::JoystickZeroFire] |=
|
||||
m_pDirectJoystick->IsButtonPressed(0);
|
||||
|
||||
LONG x;
|
||||
LONG y;
|
||||
m_pDirectJoystick->GetPos( &x, &y );
|
||||
|
||||
if (x < 0)
|
||||
{
|
||||
rgEventState[Event::JoystickZeroLeft] = 1;
|
||||
}
|
||||
else if (x > 0)
|
||||
{
|
||||
rgEventState[Event::JoystickZeroRight] = 1;
|
||||
}
|
||||
if (y < 0)
|
||||
{
|
||||
rgEventState[Event::JoystickZeroUp] = 1;
|
||||
}
|
||||
else if (y > 0)
|
||||
{
|
||||
rgEventState[Event::JoystickZeroDown] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Update mouse
|
||||
//
|
||||
|
||||
if (m_pDirectMouse->Update() == S_OK)
|
||||
{
|
||||
// NOTE: Mouse::GetPos returns a value from 0..999
|
||||
|
||||
LONG x;
|
||||
m_pDirectMouse->GetPos( &x, NULL );
|
||||
|
||||
// Mouse resistance is measured between 0...1000000
|
||||
|
||||
// rgEventState[ m_rGlobalData->PaddleResistanceEvent() ] = (999-x)*1000;
|
||||
|
||||
// rgEventState[ m_rGlobalData->PaddleFireEvent() ] |= m_pDirectMouse->IsButtonPressed(0);
|
||||
}
|
||||
|
||||
//
|
||||
// Write new event state
|
||||
//
|
||||
|
||||
// for (i = 0; i < nEventCount; ++i)
|
||||
// {
|
||||
// m_rEvent.set( (Event::Type)i, rgEventState[i] );
|
||||
// }
|
||||
*/
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
MainWin32::Switches MainWin32::keyList[StellaEvent::LastKCODE] = {
|
||||
{ DIK_F1, StellaEvent::KCODE_F1 },
|
||||
{ DIK_F2, StellaEvent::KCODE_F2 },
|
||||
{ DIK_F3, StellaEvent::KCODE_F3 },
|
||||
{ DIK_F4, StellaEvent::KCODE_F4 },
|
||||
{ DIK_F5, StellaEvent::KCODE_F5 },
|
||||
{ DIK_F6, StellaEvent::KCODE_F6 },
|
||||
{ DIK_F7, StellaEvent::KCODE_F7 },
|
||||
{ DIK_F8, StellaEvent::KCODE_F8 },
|
||||
{ DIK_F9, StellaEvent::KCODE_F9 },
|
||||
{ DIK_F10, StellaEvent::KCODE_F10 },
|
||||
{ DIK_F11, StellaEvent::KCODE_F11 },
|
||||
{ DIK_F12, StellaEvent::KCODE_F12 },
|
||||
{ DIK_F13, StellaEvent::KCODE_F13 },
|
||||
{ DIK_F14, StellaEvent::KCODE_F14 },
|
||||
{ DIK_F15, StellaEvent::KCODE_F15 },
|
||||
|
||||
{ DIK_UP, StellaEvent::KCODE_UP },
|
||||
{ DIK_DOWN, StellaEvent::KCODE_DOWN },
|
||||
{ DIK_LEFT, StellaEvent::KCODE_LEFT },
|
||||
{ DIK_RIGHT, StellaEvent::KCODE_RIGHT },
|
||||
{ DIK_SPACE, StellaEvent::KCODE_SPACE },
|
||||
{ DIK_LCONTROL, StellaEvent::KCODE_LCTRL },
|
||||
{ DIK_RCONTROL, StellaEvent::KCODE_RCTRL },
|
||||
{ DIK_LMENU, StellaEvent::KCODE_LALT },
|
||||
{ DIK_RMENU, StellaEvent::KCODE_RALT },
|
||||
{ DIK_LWIN, StellaEvent::KCODE_LWIN },
|
||||
{ DIK_RWIN, StellaEvent::KCODE_RWIN },
|
||||
{ DIK_APPS, StellaEvent::KCODE_MENU },
|
||||
|
||||
{ DIK_A, StellaEvent::KCODE_a },
|
||||
{ DIK_B, StellaEvent::KCODE_b },
|
||||
{ DIK_C, StellaEvent::KCODE_c },
|
||||
{ DIK_D, StellaEvent::KCODE_d },
|
||||
{ DIK_E, StellaEvent::KCODE_e },
|
||||
{ DIK_F, StellaEvent::KCODE_f },
|
||||
{ DIK_G, StellaEvent::KCODE_g },
|
||||
{ DIK_H, StellaEvent::KCODE_h },
|
||||
{ DIK_I, StellaEvent::KCODE_i },
|
||||
{ DIK_J, StellaEvent::KCODE_j },
|
||||
{ DIK_K, StellaEvent::KCODE_k },
|
||||
{ DIK_L, StellaEvent::KCODE_l },
|
||||
{ DIK_M, StellaEvent::KCODE_m },
|
||||
{ DIK_N, StellaEvent::KCODE_n },
|
||||
{ DIK_O, StellaEvent::KCODE_o },
|
||||
{ DIK_P, StellaEvent::KCODE_p },
|
||||
{ DIK_Q, StellaEvent::KCODE_q },
|
||||
{ DIK_R, StellaEvent::KCODE_r },
|
||||
{ DIK_S, StellaEvent::KCODE_s },
|
||||
{ DIK_T, StellaEvent::KCODE_t },
|
||||
{ DIK_U, StellaEvent::KCODE_u },
|
||||
{ DIK_V, StellaEvent::KCODE_v },
|
||||
{ DIK_W, StellaEvent::KCODE_w },
|
||||
{ DIK_X, StellaEvent::KCODE_x },
|
||||
{ DIK_Y, StellaEvent::KCODE_y },
|
||||
{ DIK_Z, StellaEvent::KCODE_z },
|
||||
|
||||
{ DIK_0, StellaEvent::KCODE_0 },
|
||||
{ DIK_1, StellaEvent::KCODE_1 },
|
||||
{ DIK_2, StellaEvent::KCODE_2 },
|
||||
{ DIK_3, StellaEvent::KCODE_3 },
|
||||
{ DIK_4, StellaEvent::KCODE_4 },
|
||||
{ DIK_5, StellaEvent::KCODE_5 },
|
||||
{ DIK_6, StellaEvent::KCODE_6 },
|
||||
{ DIK_7, StellaEvent::KCODE_7 },
|
||||
{ DIK_8, StellaEvent::KCODE_8 },
|
||||
{ DIK_9, StellaEvent::KCODE_9 },
|
||||
|
||||
{ DIK_NUMPAD0, StellaEvent::KCODE_KP0 },
|
||||
{ DIK_NUMPAD1, StellaEvent::KCODE_KP1 },
|
||||
{ DIK_NUMPAD2, StellaEvent::KCODE_KP2 },
|
||||
{ DIK_NUMPAD3, StellaEvent::KCODE_KP3 },
|
||||
{ DIK_NUMPAD4, StellaEvent::KCODE_KP4 },
|
||||
{ DIK_NUMPAD5, StellaEvent::KCODE_KP5 },
|
||||
{ DIK_NUMPAD6, StellaEvent::KCODE_KP6 },
|
||||
{ DIK_NUMPAD7, StellaEvent::KCODE_KP7 },
|
||||
{ DIK_NUMPAD8, StellaEvent::KCODE_KP8 },
|
||||
{ DIK_NUMPAD9, StellaEvent::KCODE_KP9 },
|
||||
{ DIK_DECIMAL, StellaEvent::KCODE_KP_PERIOD },
|
||||
{ DIK_DIVIDE, StellaEvent::KCODE_KP_DIVIDE },
|
||||
{ DIK_MULTIPLY, StellaEvent::KCODE_KP_MULTIPLY },
|
||||
{ DIK_SUBTRACT, StellaEvent::KCODE_KP_MINUS },
|
||||
{ DIK_ADD, StellaEvent::KCODE_KP_PLUS },
|
||||
{ DIK_NUMPADENTER, StellaEvent::KCODE_KP_ENTER },
|
||||
// { SDLK_KP_EQUALS, StellaEvent::KCODE_KP_EQUALS },
|
||||
|
||||
{ DIK_BACK, StellaEvent::KCODE_BACKSPACE },
|
||||
{ DIK_TAB, StellaEvent::KCODE_TAB },
|
||||
// { SDLK_CLEAR, StellaEvent::KCODE_CLEAR },
|
||||
{ DIK_RETURN, StellaEvent::KCODE_RETURN },
|
||||
{ DIK_ESCAPE, StellaEvent::KCODE_ESCAPE },
|
||||
{ DIK_COMMA, StellaEvent::KCODE_COMMA },
|
||||
{ DIK_MINUS, StellaEvent::KCODE_MINUS },
|
||||
{ DIK_PERIOD, StellaEvent::KCODE_PERIOD },
|
||||
{ DIK_SLASH, StellaEvent::KCODE_SLASH },
|
||||
{ DIK_BACKSLASH, StellaEvent::KCODE_BACKSLASH },
|
||||
{ DIK_SEMICOLON, StellaEvent::KCODE_SEMICOLON },
|
||||
{ DIK_EQUALS, StellaEvent::KCODE_EQUALS },
|
||||
{ DIK_APOSTROPHE, StellaEvent::KCODE_QUOTE },
|
||||
{ DIK_GRAVE, StellaEvent::KCODE_BACKQUOTE },
|
||||
{ DIK_LBRACKET, StellaEvent::KCODE_LEFTBRACKET },
|
||||
{ DIK_RBRACKET, StellaEvent::KCODE_RIGHTBRACKET },
|
||||
|
||||
{ DIK_SYSRQ, StellaEvent::KCODE_PRTSCREEN },
|
||||
{ DIK_SCROLL, StellaEvent::KCODE_SCRLOCK },
|
||||
{ DIK_PAUSE, StellaEvent::KCODE_PAUSE },
|
||||
{ DIK_INSERT, StellaEvent::KCODE_INSERT },
|
||||
{ DIK_HOME, StellaEvent::KCODE_HOME },
|
||||
{ DIK_PRIOR, StellaEvent::KCODE_PAGEUP },
|
||||
{ DIK_DELETE, StellaEvent::KCODE_DELETE },
|
||||
{ DIK_END, StellaEvent::KCODE_END },
|
||||
{ DIK_NEXT, StellaEvent::KCODE_PAGEDOWN }
|
||||
};
|
|
@ -0,0 +1,211 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2002 by Bradford W. Mott
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: MainWin32.hxx,v 1.1 2003-11-13 00:25:07 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef MAIN_WIN32_HXX
|
||||
#define MAIN_WIN32_HXX
|
||||
|
||||
class Console;
|
||||
class FrameBufferWin32;
|
||||
class MediaSource;
|
||||
class PropertiesSet;
|
||||
class Sound;
|
||||
class Settings;
|
||||
class DirectInput;
|
||||
|
||||
#include "GlobalData.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
#include "Event.hxx"
|
||||
#include "StellaEvent.hxx"
|
||||
|
||||
/**
|
||||
This class implements a main-like method where all per-game
|
||||
instantiation is done. Event gathering is also done here.
|
||||
|
||||
This class is meant to be quite similar to the mainDOS or mainSDL
|
||||
classes so that all platforms have a main-like method as described
|
||||
in the Porting.txt document
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: MainWin32.hxx,v 1.1 2003-11-13 00:25:07 stephena Exp $
|
||||
*/
|
||||
class MainWin32
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Create a new instance of the emulation core for the specified
|
||||
rom image.
|
||||
|
||||
@param image The ROM image of the game to emulate
|
||||
@param size The size of the ROM image
|
||||
@param filename The name of the file that contained the ROM image
|
||||
@param settings The settings object to use
|
||||
@param properties The game profiles object to use
|
||||
*/
|
||||
MainWin32(const uInt8* image, uInt32 size, const char* filename,
|
||||
Settings& settings, PropertiesSet& properties);
|
||||
/**
|
||||
Destructor
|
||||
*/
|
||||
virtual ~MainWin32();
|
||||
|
||||
// Start the main emulation loop
|
||||
DWORD run();
|
||||
|
||||
private:
|
||||
void UpdateEvents();
|
||||
|
||||
private:
|
||||
// Pointer to the console object
|
||||
Console* theConsole;
|
||||
|
||||
// Reference to the settings object
|
||||
Settings& theSettings;
|
||||
|
||||
// Reference to the properties set object
|
||||
PropertiesSet& thePropertiesSet;
|
||||
|
||||
// Pointer to the display object
|
||||
FrameBufferWin32* theDisplay;
|
||||
|
||||
// Pointer to the sound object
|
||||
Sound* theSound;
|
||||
|
||||
// Pointer to the input object
|
||||
DirectInput* theInput;
|
||||
|
||||
struct Switches
|
||||
{
|
||||
uInt32 nVirtKey;
|
||||
StellaEvent::KeyCode keyCode;
|
||||
};
|
||||
static Switches keyList[StellaEvent::LastKCODE];
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// These will move into a separate Framebuffer class soon
|
||||
//
|
||||
/////////////////////////////////////////////////////////
|
||||
#if 0
|
||||
public:
|
||||
HWND hwnd() const { return myHWND; }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// The following methods are derived from FrameBuffer.hxx
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
This routine should be called once the console is created to setup
|
||||
the video system for us to use. Return false if any operation fails,
|
||||
otherwise return true.
|
||||
*/
|
||||
bool init();
|
||||
|
||||
/**
|
||||
This routine should be called anytime the MediaSource needs to be redrawn
|
||||
to the screen.
|
||||
*/
|
||||
void drawMediaSource();
|
||||
|
||||
/**
|
||||
This routine should be called to draw a rectangular box with sides
|
||||
at the specified coordinates.
|
||||
|
||||
@param x The x coordinate
|
||||
@param y The y coordinate
|
||||
@param w The width of the box
|
||||
@param h The height of the box
|
||||
*/
|
||||
void drawBoundedBox(uInt32 x, uInt32 y, uInt32 w, uInt32 h);
|
||||
|
||||
/**
|
||||
This routine should be called to draw text at the specified coordinates.
|
||||
|
||||
@param x The x coordinate
|
||||
@param y The y coordinate
|
||||
@param message The message text
|
||||
*/
|
||||
void drawText(uInt32 x, uInt32 y, const string& message);
|
||||
|
||||
/**
|
||||
This routine should be called to draw character 'c' at the specified coordinates.
|
||||
|
||||
@param x The x coordinate
|
||||
@param y The y coordinate
|
||||
@param c The character to draw
|
||||
*/
|
||||
void drawChar(uInt32 x, uInt32 y, uInt32 c);
|
||||
|
||||
/**
|
||||
This routine is called before any drawing is done (per-frame).
|
||||
*/
|
||||
void preFrameUpdate();
|
||||
|
||||
/**
|
||||
This routine is called after any drawing is done (per-frame).
|
||||
*/
|
||||
void postFrameUpdate();
|
||||
|
||||
/**
|
||||
This routine is called when the emulation has received
|
||||
a pause event.
|
||||
|
||||
@param status The received pause status
|
||||
*/
|
||||
virtual void pauseEvent(bool status);
|
||||
#endif
|
||||
//////////////////////////////////////////////////
|
||||
// Some of this will stay here, some will go to
|
||||
// the FrameBufferWin32 class
|
||||
//////////////////////////////////////////////////
|
||||
private:
|
||||
const CGlobalData* m_rGlobalData;
|
||||
|
||||
bool myIsInitialized;
|
||||
|
||||
void cleanup();
|
||||
#if 0
|
||||
static LRESULT CALLBACK StaticWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
|
||||
BOOL WndProc( UINT uMsg, WPARAM wParam, LPARAM lParam );
|
||||
|
||||
static HRESULT WINAPI EnumModesCallback( LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext);
|
||||
|
||||
void cleanup();
|
||||
|
||||
HWND myHWND;
|
||||
bool m_fActiveWindow;
|
||||
|
||||
RECT m_rectScreen;
|
||||
POINT m_ptBlitOffset;
|
||||
|
||||
// Stella objects
|
||||
SIZE mySizeGame;
|
||||
BYTE myPalette[256];
|
||||
|
||||
//
|
||||
// DirectX
|
||||
//
|
||||
IDirectDraw* m_piDD;
|
||||
IDirectDrawSurface* m_piDDSPrimary;
|
||||
IDirectDrawSurface* m_piDDSBack;
|
||||
IDirectDrawPalette* m_piDDPalette;
|
||||
|
||||
static LPCTSTR pszClassName;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue