Commit eda90151 authored by stephena's avatar stephena
Browse files

Removed the old Windows frontend code. Most of it has serious bit-rot

anyway, and some of it has been in an uncompilable state for almost
4 years!

All future Windows development will be on the StellaX GUI, and even
that may eventually disappear if the same functionality is integrated
into Stella itself.

So, for any Windows developers reading this, all Win32 development
occurs in the src/win32 directory.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@303 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
parent 1859b80f
// AboutDlg.cpp : implementation file
//
#include "pch.hxx"
#include "Cyberstella.h"
#include "AboutDlg.h"
#include ".\aboutdlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// AboutDlg dialog
AboutDlg::AboutDlg(CWnd* pParent /*=NULL*/)
: CDialog(AboutDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(AboutDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void AboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(AboutDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(AboutDlg, CDialog)
// {{AFX_MSG_MAP(AboutDlg)
ON_BN_CLICKED(IDC_CONTINUE, OnContinue)
// }} AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// AboutDlg message handlers
void AboutDlg::OnContinue()
{
EndDialog(1);
}
BOOL AboutDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_hlMail_JSM.SubclassDlgItem(IDC_EMAIL_MAINTAINER, this);
m_hlMail_JSM.SetURL( _T("mailto:stephena@users.sourceforge.net?Subject=Cyberstella") );
m_hlWWW_JSM.SubclassDlgItem(IDC_WEB_MAINTAINER, this);
m_hlWWW_JSM.SetURL( _T("http://www.cs.mun.ca/~stephena") );
m_hlMail_Stella.SubclassDlgItem(IDC_EMAIL_STELLA, this);
m_hlMail_Stella.SetURL( _T("mailto:stella-main@lists.sourceforge.net") );
m_hlWWW_Stella.SubclassDlgItem(IDC_WEB_STELLA, this);
m_hlWWW_Stella.SetURL( _T("http://stella.sourceforge.net") );
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
#if !defined(AFX_ABOUTDLG_H__1E4CE741_3D76_11D6_ACFC_0048546D2F04__INCLUDED_)
#define AFX_ABOUTDLG_H__1E4CE741_3D76_11D6_ACFC_0048546D2F04__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// AboutDlg.h : header file
//
#include "HyperLink.h"
/////////////////////////////////////////////////////////////////////////////
// AboutDlg dialog
class AboutDlg : public CDialog
{
// Construction
public:
AboutDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(AboutDlg)
enum { IDD = IDD_ABOUTBOX };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(AboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(AboutDlg)
afx_msg void OnContinue();
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
CHyperLink m_hlMail_JSM;
CHyperLink m_hlWWW_JSM;
CHyperLink m_hlMail_Stella;
CHyperLink m_hlWWW_Stella;
CHyperLink m_hlWWW_Mame;
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_ABOUTDLG_H__1E4CE741_3D76_11D6_ACFC_0048546D2F04__INCLUDED_)
//
// StellaX
// Jeff Miller 05/01/2000
//
#define DIRECTSOUND_VERSION 0x700
#include "pch.hxx"
#include "AudioStream.hxx"
#include "Timer.hxx"
#include "SoundWin32.hxx"
//
// see "Streaming Wave Files with DirectSound" (Mark McCulley)
// http://msdn.microsoft.com/library/techart/msdn_streams3.htm
//
// Modified for infinite streaming by Jeff Miller 25-Apr-2000
//
// The following constants are the defaults for our streaming buffer operation.
// default buffer length in msec
const UINT AudioStream::DefBufferLength = 250;
// default buffer service interval in msec
const UINT AudioStream::DefBufferServiceInterval = 50;
AudioStreamServices::AudioStreamServices(
void
) :
m_pds( NULL ),
m_hwnd( NULL )
{
TRACE ("AudioStreamServices::AudioStreamServices");
}
AudioStreamServices::~AudioStreamServices(
void
)
{
TRACE ( "AudioStreamServices::~AudioStreamServices" );
if ( m_pds )
{
m_pds->Release();
m_pds = NULL;
}
}
BOOL AudioStreamServices::Initialize(
HWND hwnd
)
{
TRACE( "AudioStreamServices::Initialize" );
ASSERT( hwnd != NULL );
HRESULT hr;
BOOL fRtn = TRUE;
if ( m_pds != NULL )
{
return TRUE;
}
if ( hwnd == NULL )
{
// Error, invalid hwnd
TRACE ( "ERROR: Invalid hwnd, unable to initialize services" );
return FALSE;
}
m_hwnd = hwnd;
// Create DirectSound object
hr = ::CoCreateInstance( CLSID_DirectSound,
NULL,
CLSCTX_SERVER,
IID_IDirectSound,
(void**)&m_pds );
if ( FAILED(hr) )
{
TRACE( "CCI IDirectSound failed" );
return FALSE;
}
hr = m_pds->Initialize( NULL );
if ( FAILED(hr) )
{
TRACE( "IDS::Initialize failed" );
m_pds->Release();
m_pds = NULL;
return FALSE;
}
// Set cooperative level for DirectSound. Normal means our
// sounds will be silenced when our window loses input focus.
if ( m_pds->SetCooperativeLevel( m_hwnd, DSSCL_NORMAL ) == DS_OK )
{
// Any additional initialization goes here
}
else
{
// Error
TRACE ("ERROR: Unable to set cooperative level\n\r");
m_pds->Release();
m_pds = NULL;
fRtn = FALSE;
}
return fRtn;
}
//
// AudioStream class implementation
//
////////////////////////////////////////////////////////////
AudioStream::AudioStream(
void
)
{
TRACE( "AudioStream::AudioStream" );
// Initialize data members
m_pass = NULL;
m_pwavefile = NULL;
m_pdsb = NULL;
m_ptimer = NULL;
m_fPlaying = m_fCued = FALSE;
m_lInService = FALSE;
m_dwWriteCursor = 0;
m_nBufLength = DefBufferLength;
m_cbBufSize = 0;
m_nBufService = DefBufferServiceInterval;
m_nTimeStarted = 0;
m_nTimeElapsed = 0;
m_pbTempData = NULL;
}
AudioStream::~AudioStream(
void
)
{
TRACE( "AudioStream::~AudioStream" );
Destroy();
}
BOOL AudioStream::Create(
AudioStreamServices* pass
)
{
BOOL fRtn = TRUE; // assume TRUE
ASSERT( pass );
TRACE( "AudioStream::Create" );
// pass points to AudioStreamServices object
m_pass = pass;
if ( m_pass )
{
// Create a new WaveFile object
if ( m_pwavefile = new WaveFile )
{
// Open given file
if ( m_pwavefile->Open( ) )
{
// Calculate sound buffer size in bytes
// Buffer size is average data rate times length of buffer
// No need for buffer to be larger than wave data though
m_cbBufSize = (m_pwavefile->GetAvgDataRate () * m_nBufLength) / 1000;
m_pbTempData = new BYTE[ m_cbBufSize ];
if ( m_pbTempData == NULL )
{
delete m_pwavefile;
return FALSE;
}
TRACE1( "average data rate = %d", m_pwavefile->GetAvgDataRate () );
TRACE1( "m_cbBufSize = %d", m_cbBufSize );
// Create sound buffer
HRESULT hr;
memset (&m_dsbd, 0, sizeof (DSBUFFERDESC));
m_dsbd.dwSize = sizeof (DSBUFFERDESC);
m_dsbd.dwBufferBytes = m_cbBufSize;
m_dsbd.lpwfxFormat = m_pwavefile->GetWaveFormatEx();
hr = m_pass->GetPDS()->CreateSoundBuffer( &m_dsbd, &m_pdsb, NULL );
if (hr == DS_OK)
{
// Cue for playback
Cue();
}
else
{
// Error, unable to create DirectSound buffer
TRACE ("Error, unable to create DirectSound buffer\n\r");
if (hr == DSERR_BADFORMAT)
{
TRACE (" Bad format (probably ADPCM)\n\r");
}
fRtn = FALSE;
}
}
else
{
// Error opening file
delete m_pwavefile;
m_pwavefile = NULL;
fRtn = FALSE;
}
}
else
{
// Error, unable to create WaveFile object
fRtn = FALSE;
}
}
else
{
// Error, passed invalid parms
fRtn = FALSE;
}
return fRtn;
}
// Destroy
BOOL AudioStream::Destroy(
void
)
{
BOOL fRtn = TRUE;
TRACE ("AudioStream::Destroy");
// Stop playback
Stop();
// Release DirectSound buffer
if (m_pdsb)
{
m_pdsb->Release();
m_pdsb = NULL;
}
// Delete WaveFile object
delete m_pwavefile;
m_pwavefile = NULL;
delete[] m_pbTempData;
m_pbTempData = NULL;
return fRtn;
}
// WriteWaveData
//
// Writes wave data to sound buffer. This is a helper method used by Create and
// ServiceBuffer; it's not exposed to users of the AudioStream class.
BOOL AudioStream::WriteWaveData(
DWORD cbWriteBytes
)
{
HRESULT hr;
LPVOID pvAudioPtr1 = NULL;
DWORD cbAudioBytes1 = 0;
LPVOID pvAudioPtr2 = NULL;
DWORD cbAudioBytes2 = 0;
BOOL fRtn = TRUE;
// Lock the sound buffer
hr = m_pdsb->Lock( m_dwWriteCursor,
cbWriteBytes,
&pvAudioPtr1, &cbAudioBytes1,
&pvAudioPtr2, &cbAudioBytes2,
0 );
if ( hr == DS_OK )
{
// Write data to sound buffer. Because the sound buffer is circular, we may have to
// do two write operations if locked portion of buffer wraps around to start of buffer.
ASSERT ( pvAudioPtr1 != NULL );
m_pwavefile->Read( m_pbTempData, cbWriteBytes );
memcpy( pvAudioPtr1, m_pbTempData, cbAudioBytes1 );
memcpy( pvAudioPtr2, m_pbTempData + cbAudioBytes1, cbAudioBytes2 );
// Update our buffer offset and unlock sound buffer
m_dwWriteCursor = ( m_dwWriteCursor + cbAudioBytes1 + cbAudioBytes2 ) % m_cbBufSize;
m_pdsb->Unlock( pvAudioPtr1, cbAudioBytes1,
pvAudioPtr2, cbAudioBytes2 );
}
else
{
// Error locking sound buffer
TRACE("Error, unable to lock sound buffer" );
fRtn = FALSE;
}
return fRtn;
}
// GetMaxWriteSize
//
// Helper function to calculate max size of sound buffer write operation, i.e. how much
// free space there is in buffer.
DWORD AudioStream::GetMaxWriteSize(
void
)
{
DWORD dwCurrentPlayCursor;
DWORD dwCurrentWriteCursor;
DWORD dwMaxSize;
// Get current play position
if ( m_pdsb->GetCurrentPosition( &dwCurrentPlayCursor,
&dwCurrentWriteCursor) == DS_OK)
{
if ( m_dwWriteCursor <= dwCurrentPlayCursor )
{
// Our write position trails play cursor
dwMaxSize = dwCurrentPlayCursor - m_dwWriteCursor;
}
else // (m_dwWriteCursor > dwCurrentPlayCursor)
{
// Play cursor has wrapped
dwMaxSize = m_cbBufSize - m_dwWriteCursor + dwCurrentPlayCursor;
}
}
else
{
// GetCurrentPosition call failed
ASSERT (0);
dwMaxSize = 0;
}
return dwMaxSize;
}
// ServiceBuffer
//
// Routine to service buffer requests initiated by periodic timer.
//
// Returns TRUE if buffer serviced normally; otherwise returns FALSE.
BOOL AudioStream::ServiceBuffer(
void
)
{
BOOL fRtn = TRUE;
// Check for reentrance
if ( ::InterlockedExchange( &m_lInService, TRUE ) == FALSE )
{
// Not reentered, proceed normally
// Maintain elapsed time count
m_nTimeElapsed = timeGetTime () - m_nTimeStarted;
// All of sound not played yet, send more data to buffer
DWORD dwFreeSpace = GetMaxWriteSize ();
// Determine free space in sound buffer
if (dwFreeSpace)
{
// Enough wave data remains to fill free space in buffer
// Fill free space in buffer with wave data
if ( WriteWaveData( dwFreeSpace ) == FALSE )
{
// Error writing wave data
fRtn = FALSE;
ASSERT (0);
TRACE ("WriteWaveData failed\n\r");
}
}
else
{
// No free space in buffer for some reason
fRtn = FALSE;
}
// Reset reentrancy semaphore
::InterlockedExchange( &m_lInService, FALSE );
}
else
{
// Service routine reentered. Do nothing, just return
fRtn = FALSE;
}
return fRtn;
}
void AudioStream::Cue(
void
)
{
TRACE ( "AudioStream::Cue" );
if ( !m_fCued )
{
// Reset buffer ptr
m_dwWriteCursor = 0;
// Reset file ptr, etc
m_pwavefile->Cue();
// Reset DirectSound buffer
m_pdsb->SetCurrentPosition( 0 );
// Fill buffer with wave data
WriteWaveData( m_cbBufSize );
m_fCued = TRUE;
}
}
void AudioStream::Play(
void
)
{
if ( m_pdsb )
{
// If playing, stop
if (m_fPlaying)
{
Stop();
}
// Cue for playback if necessary