From 40f77dc03e897b4251324b9213e15001ad1bc0dc Mon Sep 17 00:00:00 2001 From: stephena Date: Tue, 6 Jul 2004 22:51:58 +0000 Subject: [PATCH] Yet more StellaX code cleanup. The 'Browse for ROM directory' button now works, so you can change ROM directories while within StellaX. Added a 'Reload' button to the main dialog, so that when you change the ROM dir, you can immediately reload the directory (instead of having to quit and restart the app). Added quotes around romnames; previously, names with spaces would cause problems. Removed old 'beta-testers' and 'thanks to' info from the Help dialog, since it's over 4 years old and none of those people helped me :) Still TODO is parse stella.pro info (so you can see romname, ms5sum, rarity, manufacturer, and notes from the GUI), add a gamelist cache mode (so the stella.pro and roms don't have to be accessed each time you start the emulator, only when the romdir has changed), and add more options to the config dialog. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@296 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- stella/src/win32/StellaX/BrowseForFolder.cxx | 202 ++++++------------- stella/src/win32/StellaX/BrowseForFolder.hxx | 198 +++++------------- stella/src/win32/StellaX/ConfigPage.cxx | 7 +- stella/src/win32/StellaX/MainDlg.cxx | 197 ++++++++++-------- stella/src/win32/StellaX/MainDlg.hxx | 22 +- stella/src/win32/StellaX/StellaX.aps | Bin 44484 -> 39668 bytes stella/src/win32/StellaX/StellaX.rc | 70 ++----- stella/src/win32/StellaX/StellaX.vcproj | 3 + stella/src/win32/StellaX/StellaXMain.cxx | 15 +- stella/src/win32/StellaX/resource.h | 26 +-- stella/src/win32/Stella_Emulator.ncb | Bin 510976 -> 510976 bytes stella/src/win32/Stella_Emulator.suo | Bin 11776 -> 11776 bytes 12 files changed, 270 insertions(+), 470 deletions(-) diff --git a/stella/src/win32/StellaX/BrowseForFolder.cxx b/stella/src/win32/StellaX/BrowseForFolder.cxx index 1f6c5c3c8..625ee008f 100644 --- a/stella/src/win32/StellaX/BrowseForFolder.cxx +++ b/stella/src/win32/StellaX/BrowseForFolder.cxx @@ -1,185 +1,117 @@ -////////////////////////////////////////////////////////////////////// -// -// ShellBrowser.cpp: implementation of the CShellBrowser class. -// +//============================================================================ +// +// 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) 1998 Scott D. Killen +// Copyright (c) 2004 by Stephen Anthony +// +// See the file "license" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +// +// $Id: BrowseForFolder.cxx,v 1.3 2004-07-06 22:51:58 stephena Exp $ +//============================================================================ #include "pch.hxx" #include "BrowseForFolder.hxx" -////////////////////////////////////////////////////////////////////// -// -// Construction/Destruction -// CBrowseForFolder::CBrowseForFolder( const HWND hParent, const LPITEMIDLIST pidl, LPCTSTR strTitle) { - m_hwnd = NULL; + myHwnd = NULL; - myBrowseInfo.pidlRoot = pidl; + myBrowseInfo.pidlRoot = pidl; myBrowseInfo.hwndOwner = NULL; - myBrowseInfo.pszDisplayName = mySelected; - myBrowseInfo.lpszTitle = "Open ROM Folder "; + myBrowseInfo.pszDisplayName = mySelected; + myBrowseInfo.lpszTitle = strTitle; myBrowseInfo.ulFlags = BIF_RETURNONLYFSDIRS|BIF_RETURNFSANCESTORS; - myBrowseInfo.lParam = reinterpret_cast( this ); - -// myBrowseInfo.lpfn = BrowseCallbackProc; + myBrowseInfo.lParam = reinterpret_cast( this ); + myBrowseInfo.lpfn = BrowseCallbackProc; } CBrowseForFolder::~CBrowseForFolder() { } -////////////////////////////////////////////////////////////////////// -// -// Implementation -// - -void CBrowseForFolder::SetOwner(const HWND hwndOwner) +LPCTSTR CBrowseForFolder::GetSelectedFolder() const { - if (m_hwnd != NULL) - return; - - myBrowseInfo.hwndOwner = hwndOwner; -} - -void CBrowseForFolder::SetRoot(const LPITEMIDLIST pidl) -{ - if (m_hwnd != NULL) - return; - - myBrowseInfo.pidlRoot = pidl; -} - -LPCTSTR CBrowseForFolder::GetTitle() const -{ - return myBrowseInfo.lpszTitle; -} - -bool CBrowseForFolder::SetTitle( - LPCTSTR strTitle - ) -{ - if (m_hwnd != NULL) - return false; - - if ( strTitle == NULL ) - { - return false; - } - - if ( ! m_pchTitle.Set( strTitle ) ) - { - return false; - } - - myBrowseInfo.lpszTitle = m_pchTitle.Get(); - - return true; -} - -void CBrowseForFolder::SetFlags(const UINT ulFlags) -{ - if (m_hwnd != NULL) - return; - - myBrowseInfo.ulFlags = ulFlags; -} - -LPCTSTR CBrowseForFolder::GetSelectedFolder( - void - ) const -{ - return mySelected; + return mySelected; } bool CBrowseForFolder::SelectFolder() { - bool bRet = false; + bool bRet = false; - LPITEMIDLIST pidl; - if ((pidl = ::SHBrowseForFolder(&myBrowseInfo)) != NULL) - { - myPath.Set( _T("") ); - if (SUCCEEDED(::SHGetPathFromIDList(pidl, mySelected))) - { - bRet = true; - myPath.Set( mySelected ); - } + LPITEMIDLIST pidl; + if ((pidl = SHBrowseForFolder(&myBrowseInfo)) != NULL) + { + myPath.Set( _T("") ); + if (SUCCEEDED(SHGetPathFromIDList(pidl, mySelected))) + { + bRet = true; + myPath.Set( mySelected ); + } - LPMALLOC pMalloc; - //Retrieve a pointer to the shell's IMalloc interface - if (SUCCEEDED(SHGetMalloc(&pMalloc))) - { - // free the PIDL that SHBrowseForFolder returned to us. - pMalloc->Free(pidl); - // release the shell's IMalloc interface - (void)pMalloc->Release(); - } - } - m_hwnd = NULL; - - return bRet; -} - -void CBrowseForFolder::OnInit() const -{ + LPMALLOC pMalloc; + //Retrieve a pointer to the shell's IMalloc interface + if (SUCCEEDED(SHGetMalloc(&pMalloc))) + { + // free the PIDL that SHBrowseForFolder returned to us. + pMalloc->Free(pidl); + // release the shell's IMalloc interface + (void)pMalloc->Release(); + } + } + myHwnd = NULL; + return bRet; } void CBrowseForFolder::OnSelChanged(const LPITEMIDLIST pidl) const { - (void)pidl; + (void)pidl; } void CBrowseForFolder::EnableOK(const bool bEnable) const { - if (m_hwnd == NULL) - return; + if (myHwnd == NULL) + return; - // (void)SendMessage(m_hwnd, BFFM_ENABLEOK, static_cast(bEnable), NULL); - (void)SendMessage( m_hwnd, BFFM_ENABLEOK, NULL, static_cast(bEnable) ); + // (void)SendMessage(myHwnd, BFFM_ENABLEOK, static_cast(bEnable), NULL); + (void)SendMessage( myHwnd, BFFM_ENABLEOK, NULL, static_cast(bEnable) ); } void CBrowseForFolder::SetSelection(const LPITEMIDLIST pidl) const { - if (m_hwnd == NULL) - return; + if (myHwnd == NULL) + return; - (void)SendMessage(m_hwnd, BFFM_SETSELECTION, FALSE, reinterpret_cast(pidl)); + (void)SendMessage(myHwnd, BFFM_SETSELECTION, FALSE, reinterpret_cast(pidl)); } -void CBrowseForFolder::SetSelection( - LPCTSTR strPath - ) const +void CBrowseForFolder::SetSelection(LPCTSTR strPath) const { - if (m_hwnd == NULL) - return; + if (myHwnd == NULL) + return; - (void)SendMessage(m_hwnd, BFFM_SETSELECTION, TRUE, reinterpret_cast(strPath)); -} - -void CBrowseForFolder::SetStatusText( - LPCTSTR strText - ) const -{ - if (m_hwnd == NULL) - return; - - (void)SendMessage(m_hwnd, BFFM_SETSTATUSTEXT, NULL, reinterpret_cast(strText)); + (void)SendMessage(myHwnd, BFFM_SETSELECTION, TRUE, reinterpret_cast(strPath)); } int __stdcall CBrowseForFolder::BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) { - CBrowseForFolder* pbff = reinterpret_cast( lpData ); - pbff->m_hwnd = hwnd; - if (uMsg == BFFM_INITIALIZED) - pbff->OnInit(); - else if (uMsg == BFFM_SELCHANGED) - pbff->OnSelChanged( reinterpret_cast( lParam )); - - return 0; -} + CBrowseForFolder* pbff = reinterpret_cast( lpData ); + pbff->myHwnd = hwnd; + if (uMsg == BFFM_SELCHANGED) + pbff->OnSelChanged( reinterpret_cast( lParam )); + + return 0; +} diff --git a/stella/src/win32/StellaX/BrowseForFolder.hxx b/stella/src/win32/StellaX/BrowseForFolder.hxx index 44d1aa0f9..08186587a 100644 --- a/stella/src/win32/StellaX/BrowseForFolder.hxx +++ b/stella/src/win32/StellaX/BrowseForFolder.hxx @@ -1,162 +1,76 @@ -////////////////////////////////////////////////////////////////////// -// -// ShellBrowser.h: interface for the CShellBrowser class. -// -// Copyright 1998 Scott D. Killen -// -////////////////////////////////////////////////////////////////////// +//============================================================================ +// +// 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) 1998 Scott D. Killen +// Copyright (c) 2004 by Stephen Anthony +// +// See the file "license" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +// +// $Id: BrowseForFolder.hxx,v 1.3 2004-07-06 22:51:58 stephena Exp $ +//============================================================================ #ifndef __BROWSE_FOR_FOLDER_ #define __BROWSE_FOR_FOLDER_ #include -///////////////////////////////////////////////////////////////////// -// -// CShellBrowser -// class CBrowseForFolder { -public: - CBrowseForFolder(const HWND hParent = NULL, - const LPITEMIDLIST pidl = NULL, - LPCTSTR strTitle = NULL ); + public: + CBrowseForFolder(const HWND hParent = NULL, + const LPITEMIDLIST pidl = NULL, + LPCTSTR strTitle = NULL ); - virtual ~CBrowseForFolder(); + virtual ~CBrowseForFolder(); - // - // Set the handle of the owner window for the dialog box. - // - void SetOwner(const HWND hwndOwner); + public: + // Call GetSelectedFolder to retrieve the folder selected by the user. + LPCTSTR GetSelectedFolder() const; - // - // Set the root of the heirarchy that will be browsed. Get pidl from - // SHGetSpecialFolderLocation. This can be set to NULL to use the Virtual Folder - // that represents the Windows Desktop. - // - void SetRoot(const LPITEMIDLIST pidl); + // Call SelectFolder to display the dialog and get a selection from the user. Use + // GetSelectedFolder and GetImage to get the results of the dialog. + bool SelectFolder(); - // - // Access a string that is displayed above the tree view control in the dialog box. - // This string can be used to specify instructions to the user. strTitle is a - // CString containing the text to be displayed. nTitle is the index of a string - // resource to be loaded. The return value is false if the resource could not be - // loaded. - // - LPCTSTR GetTitle() const; - bool SetTitle(LPCTSTR strTitle); + protected: + // OnSelChanged is called whenever the user selects a different directory. pidl is + // the LPITEMIDLIST of the new selection. Use SHGetPathFromIDList to retrieve the + // path of the selection. + virtual void OnSelChanged(const LPITEMIDLIST pidl) const; - // - // ulFlags = Value specifying the types of folders to be listed in the dialog box - // as well as other options. This member can include zero or more of the following - // values: - // - // BIF_BROWSEFORCOMPUTER Only returns computers. If the user selects - // anything other than a computer, the OK button - // is grayed. - // - // BIF_BROWSEFORPRINTER Only returns printers. If the user selects - // anything other than a printer, the OK button - // is grayed. - // - // BIF_DONTGOBELOWDOMAIN Does not include network folders below the - // domain level in the tree view control. - // - // BIF_RETURNFSANCESTORS Only returns file system ancestors. If the user - // selects anything other than a file system - // ancestor, the OK button is grayed. - // - // BIF_RETURNONLYFSDIRS Only returns file system directories. If the - // user selects folders that are not part of the - // file system, the OK button is grayed. - // - // BIF_STATUSTEXT Includes a status area in the dialog box. The - // callback function can set the status text by - // sending messages to the dialog box. - // - UINT GetFlags() const; - void SetFlags(const UINT ulFlags); + // Call EnableOK to enable the OK button on the active dialog. If bEnable is true + // then the button is enabled, otherwise it is disabled. + // NOTE -- This function should only be called within overrides of OnInit and + // OnSelChanged. + void EnableOK(const bool bEnable) const; - // - // Call GetSelectedFolder to retrieve the folder selected by the user. - // - LPCTSTR GetSelectedFolder() const; + // Call SetSelection to set the selection in the active dialog. pidl is the + // LPITEMIDLIST + // of the path to be selected. strPath is a CString containing the path to be + // selected. + // NOTE -- This function should only be called within overrides of OnInit and + // OnSelChanged. + void SetSelection(const LPITEMIDLIST pidl) const; + void SetSelection(LPCTSTR strPath) const; - // - // Function to retreive the image associated with the selected folder. The image is - // specified as an index to the system image list. - // - int GetImage() const; + private: + static int __stdcall BrowseCallbackProc(HWND hwnd, + UINT uMsg, + LPARAM lParam, + LPARAM lpData); - // - // Call SelectFolder to display the dialog and get a selection from the user. Use - // GetSelectedFolder and GetImage to get the results of the dialog. - // - bool SelectFolder(); - -protected: - // - // OnInit is called before the dialog is displayed on the screen. - // - virtual void OnInit() const; - - // - // OnSelChanged is called whenever the user selects a different directory. pidl is - // the LPITEMIDLIST of the new selection. Use SHGetPathFromIDList to retrieve the - // path of the selection. - // - virtual void OnSelChanged(const LPITEMIDLIST pidl) const; - - // - // Call EnableOK to enable the OK button on the active dialog. If bEnable is true - // then the button is enabled, otherwise it is disabled. - // NOTE -- This function should only be called within overrides of OnInit and - // OnSelChanged. - // - void EnableOK(const bool bEnable) const; - - // - // Call SetSelection to set the selection in the active dialog. pidl is the - // LPITEMIDLIST - // of the path to be selected. strPath is a CString containing the path to be - // selected. - // NOTE -- This function should only be called within overrides of OnInit and - // OnSelChanged. - // - void SetSelection(const LPITEMIDLIST pidl) const; - void SetSelection(LPCTSTR strPath) const; - - // - // Call SetStatusText to set the text in the Status area in the active dialog. - // strText is the text to be displayed. - // NOTE -- This function should only be called within overrides of OnInit and - // OnSelChanged. - // - void SetStatusText(LPCTSTR strText) const; - -private: - static int __stdcall BrowseCallbackProc(HWND hwnd, - UINT uMsg, - LPARAM lParam, - LPARAM lpData); - - CSimpleString m_pchTitle; - - BROWSEINFO myBrowseInfo; - char mySelected[MAX_PATH]; - CSimpleString myPath; - HWND m_hwnd; + BROWSEINFO myBrowseInfo; + char mySelected[MAX_PATH]; + CSimpleString myPath; + HWND myHwnd; }; -inline UINT CBrowseForFolder::GetFlags() const -{ - return myBrowseInfo.ulFlags; -} - -inline int CBrowseForFolder::GetImage() const -{ - return myBrowseInfo.iImage; -} - #endif diff --git a/stella/src/win32/StellaX/ConfigPage.cxx b/stella/src/win32/StellaX/ConfigPage.cxx index 088819dce..0b229c07b 100644 --- a/stella/src/win32/StellaX/ConfigPage.cxx +++ b/stella/src/win32/StellaX/ConfigPage.cxx @@ -14,7 +14,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: ConfigPage.cxx,v 1.2 2004-07-04 20:16:03 stephena Exp $ +// $Id: ConfigPage.cxx,v 1.3 2004-07-06 22:51:58 stephena Exp $ //============================================================================ #include "pch.hxx" @@ -154,10 +154,9 @@ BOOL CConfigPage::OnCommand( WORD wNotifyCode, WORD wID, HWND hwndCtl ) if ( wID == IDC_BROWSE ) { - CBrowseForFolder bff( m_hwnd ); + CBrowseForFolder bff( m_hwnd, NULL, "Open ROM Folder " ); if ( bff.SelectFolder() ) -; -// ::SetDlgItemText( m_hwnd, IDC_ROMPATH, bff.GetSelectedFolder() ); + SetDlgItemText( m_hwnd, IDC_ROMPATH, bff.GetSelectedFolder() ); } return FALSE; diff --git a/stella/src/win32/StellaX/MainDlg.cxx b/stella/src/win32/StellaX/MainDlg.cxx index 514d60ed7..7ebf3356b 100644 --- a/stella/src/win32/StellaX/MainDlg.cxx +++ b/stella/src/win32/StellaX/MainDlg.cxx @@ -14,7 +14,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: MainDlg.cxx,v 1.2 2004-07-04 20:16:03 stephena Exp $ +// $Id: MainDlg.cxx,v 1.3 2004-07-06 22:51:58 stephena Exp $ //============================================================================ #include "pch.hxx" @@ -29,8 +29,6 @@ #define BKGND_BITMAP_TOP 64 #define BKGND_BITMAP_BOTTOM 355 -// NOTE: LVS_OWNERDATA doesn't support LVM_SORTITEMS! - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - inline LPARAM ListView_GetItemData( HWND hwndList, int iItem ) { @@ -54,12 +52,12 @@ CMainDlg::CMainDlg( CGlobalData& rGlobalData, HINSTANCE hInstance ) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CMainDlg::ClearList( void ) { - int nCount = ListView_GetItemCount( m_hwndList ); + int nCount = ListView_GetItemCount( myHwndList ); for (int i = 0; i < nCount; ++i) - delete (CListData*)ListView_GetItemData( m_hwndList, i ); + delete (CListData*)ListView_GetItemData( myHwndList, i ); - ListView_DeleteAllItems( m_hwndList ); + ListView_DeleteAllItems( myHwndList ); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -82,7 +80,7 @@ CMainDlg::StaticDialogFunc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { case WM_INITDIALOG: pDlg = reinterpret_cast( lParam ); - pDlg->m_hwnd = hDlg; + pDlg->myHwnd = hDlg; (void)::SetWindowLong( hDlg, DWL_USER, reinterpret_cast( pDlg ) ); break; @@ -152,7 +150,7 @@ CMainDlg::DialogFunc( UINT uMsg, WPARAM wParam, LPARAM lParam ) // When the fActive parameter is FALSE, an application should return // TRUE to indicate that the system should proceed with the default // processing - SetWindowLong( m_hwnd, DWL_MSGRESULT, TRUE ); + SetWindowLong( myHwnd, DWL_MSGRESULT, TRUE ); return TRUE; case WM_NCLBUTTONDOWN: @@ -161,7 +159,7 @@ CMainDlg::DialogFunc( UINT uMsg, WPARAM wParam, LPARAM lParam ) case WM_SYSCOMMAND: // Allow Alt-F4 to close the window if ( wParam == SC_CLOSE ) - ::EndDialog( m_hwnd, IDCANCEL ); + ::EndDialog( myHwnd, IDCANCEL ); break; } @@ -198,26 +196,27 @@ BOOL CMainDlg::OnInitDialog( void ) // Do subclassing m_CoolCaption.OnInitDialog( hwnd ); - m_header.SubclassDlgItem( hwnd, IDC_ROMLIST ); - m_btn3d.SubclassDlgItem( hwnd, IDC_TITLE ); - m_btnPlay.SubclassDlgItem( hwnd, IDC_PLAY ); - m_btnHelp.SubclassDlgItem( hwnd, IDC_ABOUT ); - m_btnConfig.SubclassDlgItem( hwnd, IDC_CONFIG ); - m_btnExit.SubclassDlgItem( hwnd, IDC_EXIT ); + myHeader.SubclassDlgItem( hwnd, IDC_ROMLIST ); + myAppTitle.SubclassDlgItem( hwnd, IDC_TITLE ); + myPlayButton.SubclassDlgItem( hwnd, IDC_PLAY ); + myReloadButton.SubclassDlgItem( hwnd, IDC_RELOAD ); + myHelpButton.SubclassDlgItem( hwnd, IDC_ABOUT ); + myConfigButton.SubclassDlgItem( hwnd, IDC_CONFIG ); + myExitButton.SubclassDlgItem( hwnd, IDC_EXIT ); const int nMaxString = 256; TCHAR psz[nMaxString + 1]; // Initialize the list view - m_hwndList = ::GetDlgItem( hwnd, IDC_ROMLIST ); - ASSERT( m_hwndList ); + myHwndList = ::GetDlgItem( hwnd, IDC_ROMLIST ); + ASSERT( myHwndList ); // LVS_EX_ONECLICKACTIVATE was causing a/vs in kernel32 - ::SendMessage( m_hwndList, LVM_SETEXTENDEDLISTVIEWSTYLE, + ::SendMessage( myHwndList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT ); RECT rc; - ::GetClientRect( m_hwndList, &rc ); + ::GetClientRect( myHwndList, &rc ); LONG lTotalWidth = rc.right-rc.left - GetSystemMetrics(SM_CXVSCROLL); int cx = lTotalWidth / CListData::GetColumnCount(); @@ -232,39 +231,11 @@ BOOL CMainDlg::OnInitDialog( void ) lvc.fmt = LVCFMT_LEFT; lvc.cx = cx; lvc.pszText = psz; - ListView_InsertColumn( m_hwndList, i, &lvc ); + ListView_InsertColumn( myHwndList, i, &lvc ); } - DWORD dwError = PopulateRomList(); - if ( dwError != ERROR_SUCCESS ) - { - MessageBoxFromWinError( dwError, _T("PopulateRomList") ); - return FALSE; - } - - // if items added, select first item and enable play button - int nCount = ListView_GetItemCount( m_hwndList ); - if (nCount != 0) - { - m_header.SetSortCol( 0, TRUE ); - ListView_SortItems( m_hwndList, ListViewCompareFunc, (LPARAM)this ); - ListView_SetItemState( m_hwndList, 0, LVIS_SELECTED | LVIS_FOCUSED, - LVIS_SELECTED | LVIS_FOCUSED ); - } - else - { - ::EnableWindow(::GetDlgItem( hwnd, IDC_PLAY), FALSE ); - } - - // Show status text - TCHAR pszStatus[256 + 1]; - LoadString(m_hInstance, IDS_STATUSTEXT, pszStatus, 256); - wsprintf( psz, pszStatus, nCount ); - SetDlgItemText( hwnd, IDC_ROMCOUNT, psz ); - - // Show rom path - SetDlgItemText( hwnd, IDC_ROMPATH, - myGlobalData.settings().getString("romdir").c_str() ); + // Update the ROM game list + UpdateRomList(); // Set default button ::SendMessage( hwnd, DM_SETDEFID, IDC_PLAY, 0 ); @@ -287,7 +258,7 @@ BOOL CMainDlg::OnCommand( int id, HWND hwndCtl, UINT codeNotify ) switch (id) { case IDC_PLAY: - nItem = (int)::SendMessage( m_hwndList, LVM_GETNEXTITEM, + nItem = (int)::SendMessage( myHwndList, LVM_GETNEXTITEM, (WPARAM)-1, MAKELPARAM( LVNI_SELECTED, 0 ) ); ASSERT( nItem != -1 ); if ( nItem == -1 ) @@ -296,7 +267,7 @@ BOOL CMainDlg::OnCommand( int id, HWND hwndCtl, UINT codeNotify ) return TRUE; } - pListData = (CListData*)ListView_GetItemData( m_hwndList, nItem ); + pListData = (CListData*)ListView_GetItemData( myHwndList, nItem ); TCHAR pszPathName[ MAX_PATH + 1 ]; lstrcpy( pszPathName, myGlobalData.settings().getString("romdir").c_str() ); @@ -306,7 +277,7 @@ BOOL CMainDlg::OnCommand( int id, HWND hwndCtl, UINT codeNotify ) (void)m_stella.PlayROM( pszPathName, myGlobalData ); // Set focus back to the rom list - ::SetFocus( m_hwndList ); + ::SetFocus( myHwndList ); return TRUE; break; // case IDC_PLAY @@ -341,6 +312,14 @@ BOOL CMainDlg::OnCommand( int id, HWND hwndCtl, UINT codeNotify ) return TRUE; break; // case IDC_ABOUT } + + case IDC_RELOAD: + { + UpdateRomList(); + + return TRUE; + break; // case IDC_RELOAD + } } return FALSE; @@ -455,13 +434,57 @@ HBRUSH CMainDlg::OnCtlColorStatic( HDC hdcStatic, HWND hwndStatic ) return (HBRUSH)GetStockObject(NULL_BRUSH); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CMainDlg::UpdateRomList( void ) +{ + HWND hwndText; + RECT rc; + + DWORD dwError = PopulateRomList(); + if ( dwError != ERROR_SUCCESS ) + MessageBoxFromWinError( dwError, _T("PopulateRomList") ); + + // if items added, select first item and enable play button + int nCount = ListView_GetItemCount( myHwndList ); + if (nCount != 0) + { + myHeader.SetSortCol( 0, TRUE ); + ListView_SortItems( myHwndList, ListViewCompareFunc, (LPARAM)this ); + ListView_SetItemState( myHwndList, 0, LVIS_SELECTED | LVIS_FOCUSED, + LVIS_SELECTED | LVIS_FOCUSED ); + } + else + { + ::EnableWindow(::GetDlgItem( *this, IDC_PLAY), FALSE ); + } + + // Show status text + TCHAR psz[256 + 1]; + TCHAR pszStatus[256 + 1]; + LoadString(m_hInstance, IDS_STATUSTEXT, pszStatus, 256); + wsprintf( psz, pszStatus, nCount ); + hwndText = GetDlgItem( *this, IDC_ROMCOUNT ); + GetWindowRect(hwndText, &rc); + ScreenToClient( *this, (LPPOINT)&rc ); + ScreenToClient( *this, ((LPPOINT)&rc)+1 ); + SetWindowText( hwndText, psz ); + InvalidateRect( *this, &rc, TRUE ); + + // Show rom path + hwndText = GetDlgItem( *this, IDC_ROMPATH ); + GetWindowRect(hwndText, &rc); + ScreenToClient( *this, (LPPOINT)&rc ); + ScreenToClient( *this, ((LPPOINT)&rc)+1 ); + SetWindowText( hwndText, myGlobalData.settings().getString("romdir").c_str() ); + InvalidateRect( *this, &rc, TRUE ); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DWORD CMainDlg::PopulateRomList( void ) { DWORD dwRet; ClearList(); - // REVIEW: Support .zip files? TCHAR pszPath[ MAX_PATH ]; lstrcpy( pszPath, myGlobalData.settings().getString("romdir").c_str() ); @@ -470,7 +493,7 @@ DWORD CMainDlg::PopulateRomList( void ) WIN32_FIND_DATA ffd; HANDLE hFind = FindFirstFile( pszPath, &ffd ); - ListView_SetItemCount( m_hwndList, 100 ); + ListView_SetItemCount( myHwndList, 100 ); int iItem = 0; BOOL fDone = (hFind == INVALID_HANDLE_VALUE); @@ -494,15 +517,15 @@ DWORD CMainDlg::PopulateRomList( void ) lvi.iSubItem = 0; lvi.pszText = LPSTR_TEXTCALLBACK; lvi.lParam = (LPARAM)pListData; - int nItem = ListView_InsertItem( m_hwndList, &lvi ); + int nItem = ListView_InsertItem( myHwndList, &lvi ); ASSERT( nItem != -1 ); - ListView_SetItemText( m_hwndList, nItem, + ListView_SetItemText( myHwndList, nItem, CListData::FILENAME_COLUMN, LPSTR_TEXTCALLBACK ); - ListView_SetItemText(m_hwndList, nItem, + ListView_SetItemText(myHwndList, nItem, CListData::MANUFACTURER_COLUMN, LPSTR_TEXTCALLBACK); - ListView_SetItemText( m_hwndList, nItem, + ListView_SetItemText( myHwndList, nItem, CListData::RARITY_COLUMN, LPSTR_TEXTCALLBACK ); // go to the next rom file @@ -616,55 +639,51 @@ DWORD CMainDlg::ReadRomData(CListData* pListData) const return ERROR_SUCCESS; } -void CMainDlg::OnColumnClick( - LPNMLISTVIEW pnmv - ) +void CMainDlg::OnColumnClick( LPNMLISTVIEW pnmv ) { HCURSOR hcur = ::SetCursor(::LoadCursor(NULL, IDC_WAIT)); - m_header.SetSortCol(pnmv->iSubItem, TRUE); + myHeader.SetSortCol(pnmv->iSubItem, TRUE); ListView_SortItems(pnmv->hdr.hwndFrom, ListViewCompareFunc, (LPARAM)this); // ensure the selected item is visible - int nItem = ListView_GetNextItem( m_hwndList, -1, LVNI_SELECTED ); + int nItem = ListView_GetNextItem( myHwndList, -1, LVNI_SELECTED ); if (nItem != -1) { - ListView_EnsureVisible( m_hwndList, nItem, TRUE ); + ListView_EnsureVisible( myHwndList, nItem, TRUE ); } ::SetCursor(hcur); } -void CMainDlg::OnItemChanged( - LPNMLISTVIEW pnmv - ) +void CMainDlg::OnItemChanged( LPNMLISTVIEW pnmv ) { - HWND hwnd = *this; + HWND hwnd = *this; - HWND hwndNote = ::GetDlgItem( hwnd, IDC_ROMNOTE ); + HWND hwndNote = ::GetDlgItem( hwnd, IDC_ROMNOTE ); - RECT rc; - ::GetWindowRect(hwndNote, &rc); - ::ScreenToClient( hwnd, (LPPOINT)&rc ); - ::ScreenToClient( hwnd, ((LPPOINT)&rc)+1 ); + RECT rc; + GetWindowRect(hwndNote, &rc); + ScreenToClient( hwnd, (LPPOINT)&rc ); + ScreenToClient( hwnd, ((LPPOINT)&rc)+1 ); - int iItem = ListView_GetNextItem(pnmv->hdr.hwndFrom, -1, LVNI_SELECTED); - if (iItem == -1) - { - ::SetWindowText( hwndNote, _T("") ); - ::EnableWindow( ::GetDlgItem( hwnd, IDC_PLAY ), FALSE ); - ::InvalidateRect( hwnd, &rc, TRUE ); - return; - } + int iItem = ListView_GetNextItem(pnmv->hdr.hwndFrom, -1, LVNI_SELECTED); + if (iItem == -1) + { + SetWindowText( hwndNote, _T("") ); + EnableWindow( ::GetDlgItem( hwnd, IDC_PLAY ), FALSE ); + InvalidateRect( hwnd, &rc, TRUE ); + return; + } - CListData* pListData = (CListData*)ListView_GetItemData( - pnmv->hdr.hwndFrom, - pnmv->iItem ); + CListData* pListData = (CListData*)ListView_GetItemData( + pnmv->hdr.hwndFrom, + pnmv->iItem ); - ::SetWindowText( hwndNote, pListData->GetNote() ); - ::InvalidateRect( hwnd, &rc, TRUE ); - ::EnableWindow( ::GetDlgItem( hwnd, IDC_PLAY ), TRUE ); + SetWindowText( hwndNote, pListData->GetNote() ); + InvalidateRect( hwnd, &rc, TRUE ); + EnableWindow( ::GetDlgItem( hwnd, IDC_PLAY ), TRUE ); } // --------------------------------------------------------------------------- @@ -700,7 +719,7 @@ int CALLBACK CMainDlg::ListViewCompareFunc( // while other column metadata requires a call to ReadRomData // - int nSortCol = pThis->m_header.GetSortCol(); + int nSortCol = pThis->myHeader.GetSortCol(); CListData* pItem1 = reinterpret_cast( lParam1 ); if ( ! pItem1->IsPopulated() && nSortCol != 0 ) diff --git a/stella/src/win32/StellaX/MainDlg.hxx b/stella/src/win32/StellaX/MainDlg.hxx index 5b9718bb5..00aa9fe6f 100644 --- a/stella/src/win32/StellaX/MainDlg.hxx +++ b/stella/src/win32/StellaX/MainDlg.hxx @@ -180,20 +180,21 @@ public: operator HWND( void ) const { - return m_hwnd; + return myHwnd; } private: - HWND m_hwnd; + HWND myHwnd; - CCoolCaption m_CoolCaption; - CTextButton3d m_btn3d; - CHeaderCtrl m_header; - CRoundButton m_btnPlay; - CRoundButton m_btnHelp; - CRoundButton m_btnConfig; - CRoundButton m_btnExit; + CCoolCaption m_CoolCaption; + CTextButton3d myAppTitle; + CHeaderCtrl myHeader; + CRoundButton myPlayButton; + CRoundButton myHelpButton; + CRoundButton myReloadButton; + CRoundButton myConfigButton; + CRoundButton myExitButton; // // Message handlers @@ -235,13 +236,14 @@ private: // internal data DWORD PopulateRomList(); + void UpdateRomList(); DWORD ReadRomData( CListData* ) const; HINSTANCE m_hInstance; // stuff in list - HWND m_hwndList; + HWND myHwndList; void ClearList(); HFONT m_hfontRomNote; diff --git a/stella/src/win32/StellaX/StellaX.aps b/stella/src/win32/StellaX/StellaX.aps index 228307c0ef93e76bd70e1c329645fba70663e699..7c80c61ae06cc0e3cc1b87e984bfceae1344c2e2 100644 GIT binary patch delta 1648 zcmZ9MU2GIp6oAhicDMBZZ-1xl>~`C(ZGmNHcH8dO(lG7L!Zy1*%j_&af-V?{n5eBu z6MsU0n5dDcv7GRe7$_hy(yocR@yQ1?0ThGagAXRW5Kx1p)E9m5g?gs9AbK~m_sn|IAdK@S$zy;8E;mO^0d#(#b+e%@~@R++h@RxpZz5 zD3J)%a?QA!GxfZdBNl_Y6}GLEQqvhNNiYue9HvxL&1i<98=wpgK*I_pvz(gMhz&s_ zXIV8@OsV5$(a`o=#&Kxk3T_yWKr?^Wi>98+YFXXb0ZKdyEgT!Fkv1(7gH}!orfL=o zrncQAngHiRs%0`ND2WKT@aa_^=Ei21OYi_5c6q{HZlo3pj~0^{0w1S&^)VU;5pdQm zwzgTy@sc`5iGdu6$k2{=ZS5l+oNHOyloF+3MJ06X^s;>n{2b&n>JH0d00Owt z?i}vq*wC|?bYa+StF*Wf?;FwcUB> ziATQks=1jylcUi4h~;$CawW&0kF#+-mr8H4&;ayvlvk6<<$&@Ktl_Aj7jsF=C=P2m z*{WxXbj*YjuxlPb2=&olhFI?3L_j+)(gx+cqJaiQi1;a9+~YE!}j;HtV9zTMEv zq9`|Xps(JA0zDfW9fBN3R`0~Q`XE*7@+Dd>UoWFK{Hs1#O{?aEYR8SQHpUoWx$#|g z6%$Q&A8IGTmAT;HG*SKC%)%ghc}$h;G3>i(wuS)czCS; z6)1(Ab^BRE<)XWvk>R4}w%aPz$M+2w{p@(dJAxg)!HVf?XDo>?i+=i_5qGllcwg*d zhq1Zs#HuOi#rZZBrBE;HtMs*B6og?L-jl+t5q#+lLGe`&^1u^k=r zZlSvcrFlj8u7yZAl%(xgpv0Dzn&`3W59lUU6Xj!=q`U_gCDCz>#Bv*6nU{o<0sM`o z-X3(6#{_Q(C(4o#=)*->bWrbs{rz}^NVy+hkBW{7BGbq4`?BcRO5&|!c#p(gByK;B RN6v|kGbH|W9Oph2{{c|bk$wOG delta 6301 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 diff --git a/stella/src/win32/StellaX/StellaX.rc b/stella/src/win32/StellaX/StellaX.rc index b3b78f467..828bc592d 100644 --- a/stella/src/win32/StellaX/StellaX.rc +++ b/stella/src/win32/StellaX/StellaX.rc @@ -76,7 +76,7 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "Comments", "This version of StellaX is released under the GPL." - VALUE "CompanyName", "Stephen Anthony (stephena@users.sourceforge.net)" + VALUE "CompanyName", "Stephen Anthony (sa666_666@hotmail.com)" VALUE "FileDescription", "StellaX" VALUE "FileVersion", "1, 4, 0, 0" VALUE "InternalName", "StellaX" @@ -113,15 +113,15 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_AUTOARRANGE | WS_BORDER | WS_TABSTOP,7,57,395,143,WS_EX_STATICEDGE CONTROL "&Play",IDC_PLAY,"Button",BS_OWNERDRAW | WS_TABSTOP,7, - 226,200,16 + 226,149,16 CONTROL "&Options",IDC_CONFIG,"Button",BS_OWNERDRAW | WS_TABSTOP, 230,226,54,16 CONTROL "&Help",IDC_ABOUT,"Button",BS_OWNERDRAW | WS_TABSTOP,289, 226,54,16 CONTROL "E&xit",IDC_EXIT,"Button",BS_OWNERDRAW | WS_TABSTOP,348, 226,54,16 - CTEXT "Written by Jeff Miller (miller@zipcon.net)\nStella core by Bradford W. Mott (bwmott@acm.org)", - IDC_STATIC,175,13,227,19,SS_NOPREFIX + CTEXT "Written by Jeff Miller (miller@zipcon.net)\nUpdated by Stephen Anthony (sa666_666@hotmail.com)\nStella core by Bradford W. Mott (bwmott@acm.org)", + IDC_STATIC,175,7,227,28,SS_NOPREFIX RTEXT "",IDC_ROMCOUNT,322,45,80,8,SS_NOPREFIX CONTROL "",-1,"Static",SS_ETCHEDHORZ,0,39,411,1 CONTROL "",-1,"Static",SS_ETCHEDHORZ,0,218,411,1 @@ -132,37 +132,30 @@ BEGIN CONTROL "",IDC_ROMNOTE,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | WS_GROUP,93,205,309,8 LTEXT "Game notes (if available):",-1,7,205,98,8 + CONTROL "&Reload",IDC_RELOAD,"Button",BS_OWNERDRAW | WS_TABSTOP, + 172,226,54,16 END -IDD_ABOUT_PAGE DIALOGEX 0, 0, 298, 136 +IDD_ABOUT_PAGE DIALOGEX 0, 0, 299, 86 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Information" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN LTEXT "You must own legal copies of all ROM images you are using. The Stella team can't tell you where to find ROM images so DON'T ASK. All requests will either be deleted or sent to the appropriate authorities. StellaX is GPL software.", - -1,7,7,283,30,SS_NOPREFIX + -1,7,7,284,30,SS_NOPREFIX LTEXT "If you have a question or a problem, please try one of these contacts:", - -1,7,44,283,8,SS_NOPREFIX + -1,7,44,284,8,SS_NOPREFIX LTEXT "Steve Anthony:",-1,7,58,53,8,SS_NOPREFIX LTEXT "sa666_666@hotmail.com",IDC_EMAIL_MAINTAINER,73,58,122,8, SS_NOPREFIX | SS_NOTIFY LTEXT "http://minbar.org",IDC_WEB_MAINTAINER,202,58,72,8, SS_NOPREFIX | SS_NOTIFY - LTEXT "Stella dev team:",-1,7,70,52,8,SS_NOPREFIX + LTEXT "Stella dev team:",-1,7,70,60,8,SS_NOPREFIX LTEXT "stella-main@lists.sourceforge.net",IDC_EMAIL_STELLA,73, 70,122,8,SS_NOPREFIX | SS_NOTIFY LTEXT "http://stella.sf.net",IDC_WEB_STELLA,202,70,68,8, SS_NOPREFIX | SS_NOTIFY - LTEXT "God, Suzi and Noah",-1,60,94,69,8,SS_NOPREFIX - LTEXT "Bradford Mott, Mike Balfour and Roger Onslow.",-1,60, - 107,204,8,SS_NOPREFIX - CONTROL "",-1,"Static",SS_ETCHEDHORZ,7,86,283,1 - LTEXT "Beta Tester:",-1,7,120,44,8,SS_NOPREFIX - LTEXT "John Hardy IV",IDC_WWW_MAME,60,120,46,8,SS_NOPREFIX | - SS_NOTIFY - CONTROL "",-1,"Static",SS_ETCHEDHORZ,7,37,283,1 - LTEXT "Thanks To:",-1,7,107,38,8 - LTEXT "Dedicated To:",-1,7,94,46,8 + CONTROL "",-1,"Static",SS_ETCHEDHORZ,7,37,284,1 END IDD_CONFIG_PAGE DIALOGEX 0, 0, 306, 199 @@ -212,9 +205,9 @@ BEGIN IDD_ABOUT_PAGE, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 290 + RIGHTMARGIN, 291 TOPMARGIN, 7 - BOTTOMMARGIN, 128 + BOTTOMMARGIN, 78 END IDD_CONFIG_PAGE, DIALOG @@ -253,60 +246,23 @@ STRINGTABLE BEGIN IDS_STATUSTEXT "%d files found" IDS_STELLA "StellaX" - IDS_NODIRECTINPUT "DirectInput could not be initialized. Be sure you have DirectX 5.0 or later installed." - IDS_CANTSTARTCONSOLE "Error starting console. You may have chosen an invalid ROM file." - IDS_COINIT_FAILED "Unable to initialize COM subsystem" - IDS_ASS_FAILED "Unable to initialize audio subsystem" - IDS_PAS_FAILED "Unable to create audio stream" - IDS_DD_INIT_FAILED "Unable to initialize DirectDraw object" - IDS_DD_ENUMMODES_FAILED "Unable to enumerate display modes" - IDS_NO_VID_MODE "No compatible video modes were found" - IDS_DI_INIT_FAILED "Unable to initialize DirectInput object" END STRINGTABLE BEGIN IDS_ALREADYRUNNING "StellaX is already running!" - IDS_BADARGUMENT "Unknown argument given on command line" END STRINGTABLE BEGIN - IDS_DDSDM_FAILED "Unable to set video mode. Your video adapter might be incompatible with stella." - IDS_DSCSBFAILED "IDirectSound::CreateSoundBuffer failed" - IDS_DSSCLFAILED "IDirectSound::SetCooperativeLevel failed" - IDS_FILEFILTER "Stella Files (*.bin)|*.bin|All Files (*.*)|*.*||" IDS_FILENAME "Filename" IDS_MANUFACTURER "Manufacturer" - IDS_MIKE """I've heard some folks discussing the possibility of writing an 2600 emulator in a high level language - forget it, not possible."" -- Mike Livesay on rec.games.video.classic" IDS_NAME "Name" - IDS_NODIRECTDRAW "DirectDraw does not appear to be installed on this system!" IDS_RARITY "Rarity" END STRINGTABLE BEGIN - IDS_CW_FAILED "CreateWindow failed" -END - -STRINGTABLE -BEGIN - IDS_DDSCL_FAILED "IDirectDraw::SetCooperativeLevel failed" -END - -STRINGTABLE -BEGIN - IDS_DDCS_FAILED "IDirectDraw::CreateSurface failed" -END - -STRINGTABLE -BEGIN - IDS_DDCP_FAILED "IDirectDraw::CreatePalette failed" -END - -STRINGTABLE -BEGIN - IDS_ROM_LOAD_FAILED "Unable to load ROM image\n\nCurrent Directory: %s\nPath: %s\nError code: %d - %s" IDS_NO_ITEM_SELECTED "Before pressing play you must first select a game from the list!" END diff --git a/stella/src/win32/StellaX/StellaX.vcproj b/stella/src/win32/StellaX/StellaX.vcproj index 734e03b02..58e76a808 100644 --- a/stella/src/win32/StellaX/StellaX.vcproj +++ b/stella/src/win32/StellaX/StellaX.vcproj @@ -244,5 +244,8 @@ + diff --git a/stella/src/win32/StellaX/StellaXMain.cxx b/stella/src/win32/StellaX/StellaXMain.cxx index 231199a80..04b63b486 100644 --- a/stella/src/win32/StellaX/StellaXMain.cxx +++ b/stella/src/win32/StellaX/StellaXMain.cxx @@ -14,24 +14,20 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: StellaXMain.cxx,v 1.2 2004-07-04 20:16:03 stephena Exp $ +// $Id: StellaXMain.cxx,v 1.3 2004-07-06 22:51:58 stephena Exp $ //============================================================================ #include #include -#include #include #include #include -#include "resource.h" #include "GlobalData.hxx" #include "Settings.hxx" #include "pch.hxx" #include "StellaXMain.hxx" -// CStellaXMain -// equivalent to main() in the DOS version of stella CStellaXMain::CStellaXMain() { @@ -44,19 +40,20 @@ CStellaXMain::~CStellaXMain() void CStellaXMain::PlayROM( LPCTSTR filename, CGlobalData& globaldata ) { string rom = filename; + ostringstream buf; // Make sure the specfied ROM exists if(!globaldata.settings().fileExists(filename)) { - ostringstream out; - out << "\"" << rom << "\" doesn't exist"; + buf << "\"" << rom << "\" doesn't exist"; - MessageBox( NULL, out.str().c_str(), "Unknown ROM", MB_ICONEXCLAMATION|MB_OK); + MessageBox( NULL, buf.str().c_str(), "Unknown ROM", MB_ICONEXCLAMATION|MB_OK); return; } // Assume that the ROM file does exist, attempt to run external Stella // Since all settings are saved to the stella.ini file, we don't need // to pass any arguments here ... - ShellExecute(NULL, "open", "stella.exe", rom.c_str(), NULL, 0); + buf << "\"" << rom << "\""; + ShellExecute(NULL, "open", "stella.exe", buf.str().c_str(), NULL, 0); } diff --git a/stella/src/win32/StellaX/resource.h b/stella/src/win32/StellaX/resource.h index 1155374b7..9d6371f95 100644 --- a/stella/src/win32/StellaX/resource.h +++ b/stella/src/win32/StellaX/resource.h @@ -9,44 +9,21 @@ #define IDD_ABOUT_PAGE 106 #define IDD_CONFIG_PAGE 108 #define IDS_ALREADYRUNNING 200 -#define IDS_BADARGUMENT 201 -#define IDS_BADFRAMERATE 202 -#define IDS_BADPADDLEMODE 203 #define IDS_CANTOPEN 204 #define IDS_CW_FAILED 208 -#define IDS_DDCP_FAILED 224 -#define IDS_DDCS_FAILED 240 -#define IDS_DDSCL_FAILED 256 -#define IDS_DDSDM_FAILED 272 -#define IDS_DSCSBFAILED 273 -#define IDS_DSSCLFAILED 274 #define IDS_FATALERROR 275 -#define IDS_FILEFILTER 276 #define IDS_FILENAME 277 #define IDS_MANUFACTURER 278 -#define IDS_MIKE 279 #define IDS_NAME 280 -#define IDS_NODIRECTDRAW 281 -#define IDS_NOGOODVIDEOMODE 282 #define IDS_OUTOFMEMORY 283 #define IDS_RARITY 284 -#define IDS_RC_FAILED 288 #define IDS_STATUSTEXT 289 #define IDS_STELLA 290 #define IDS_UNKNOWNERROR 291 #define IDS_DEBUGBUILD 292 -#define IDS_NODIRECTINPUT 293 -#define IDS_FATALSOUNDERROR 294 -#define IDS_CANTSTARTCONSOLE 295 #define IDS_COINIT_FAILED 296 #define IDS_ASS_FAILED 297 #define IDS_PAS_FAILED 298 -#define IDS_DD_FAILED 299 -#define IDS_DD_INIT_FAILED 300 -#define IDS_DD_ENUMMODES_FAILED 301 -#define IDS_NO_VID_MODE 302 -#define IDS_DI_INIT_FAILED 303 -#define IDS_ROM_LOAD_FAILED 304 #define IDS_NO_ITEM_SELECTED 305 #define IDC_ABOUT 1001 #define IDC_EMAIL_MAINTAINER 1002 @@ -63,6 +40,7 @@ #define IDC_ROMPATH 1013 #define IDC_ROMNOTE 1014 #define IDC_CONFIG 1015 +#define IDC_CONFIG2 1016 #define IDC_PADDLE 1017 #define IDC_SOUND 1018 #define IDC_VOLUME 1019 @@ -70,8 +48,8 @@ #define IDC_ASPECT 1021 #define IDC_BROWSE 1022 #define IDC_EDIT2 1027 +#define IDC_RELOAD 1028 #define IDC_INSTRUCTIONS 2000 -#define IDC_ADOBE 2001 #define ID_FILE_EXIT 32771 // Next default values for new objects diff --git a/stella/src/win32/Stella_Emulator.ncb b/stella/src/win32/Stella_Emulator.ncb index c775d32c37347688e2342b5a548398b89bbaa174..d96d08cf17b5271750bc31814183ad57d7149483 100644 GIT binary patch delta 27268 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 dnFr8@PTSa@kPPL5 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 delta 25067 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 Vjv~!YvSgLX3`KskI#$^x{RCr!y>tKo delta 683 zcmaJ;QA-q26h8MlGmhiz?3yi31Z@xIx+JlRL7<@KMjC|^X^BpShJw(OJ4D#a!WO9b zBIge*^w`VN{R5J|)Juf@fqp?R`w&69eRtZGdC4<;GvEEry>q^EZY8XQ^*L$w6H!w= zkU8nqsx#mJteuE1NaXX5@x}GQOrV9}Z^j^3Y=d8$fo&wkqm;qF%s?#hyfq~r^B&$$ z__I|VUBtE(po#Mu%Wbazw+bEtPl0E^bD(+nu=>%Sl_?>y(z|rTl_O`-w%TGWG@QWI z+3tj>qTa7EMY^fpgv^l_a4B8n2EHfhqSc4wvB^8>d#>Bw*C}LPfDrLa&t0C*_&04y z@jM{zPSm~HWZe_sJ$e9$aq))k&~3V9l0gEQGBD0R3Ipao()*gJqs&_)wwi&|sl!or zfoIdBs*!y!FRpq>J)(#<=p~*ttWMPj|5BH$t2>Evs&RSAw*EO$3xlD!@_&DlN`ixd z`@AaoNq1C4!Oggf9M}+8zk6ow2EF3x{Pk=(VK<~QZPN=1xsqS! zPx-5P3Dd0>is^Cb*qzvNYLi=zUU$YfqV4%S=Fh?6Z*^RFCvAN