2006-02-25 20:50:29 +00:00
/*
AppleWin : An Apple //e emulator for Windows
Copyright ( C ) 1994 - 1996 , Michael O ' Brien
Copyright ( C ) 1999 - 2001 , Oliver Schmidt
Copyright ( C ) 2002 - 2005 , Tom Charlesworth
2014-09-08 21:25:29 +00:00
Copyright ( C ) 2006 - 2014 , Tom Charlesworth , Michael Pohoreski
2006-02-25 20:50:29 +00:00
AppleWin is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
AppleWin is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with AppleWin ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
/* Description: main
*
* Author : Various
*/
# include "StdAfx.h"
2014-08-13 20:30:35 +00:00
2018-02-24 15:12:40 +00:00
# include "Applewin.h"
2014-08-13 20:30:35 +00:00
# include "CPU.h"
# include "Debug.h"
# include "Disk.h"
2010-01-03 18:43:08 +00:00
# include "DiskImage.h"
2014-08-13 20:30:35 +00:00
# include "Frame.h"
2010-01-03 18:43:08 +00:00
# include "Harddisk.h"
2014-09-14 20:23:54 +00:00
# include "Joystick.h"
2019-03-03 14:32:19 +00:00
# include "Keyboard.h"
2018-10-26 18:23:30 +00:00
# include "LanguageCard.h"
2014-08-13 20:30:35 +00:00
# include "Log.h"
# include "Memory.h"
# include "Mockingboard.h"
2007-08-06 21:38:35 +00:00
# include "MouseInterface.h"
2014-08-13 20:30:35 +00:00
# include "ParallelPrinter.h"
# include "Registry.h"
# include "Riff.h"
# include "SaveState.h"
# include "SerialComms.h"
# include "SoundCore.h"
# include "Speaker.h"
2010-02-14 21:11:26 +00:00
# ifdef USE_SPEECH_API
# include "Speech.h"
# endif
2014-08-13 20:30:35 +00:00
# include "Video.h"
2019-04-06 16:31:26 +00:00
# include "RGBMonitor.h"
2014-12-31 22:13:36 +00:00
# include "NTSC.h"
2014-08-13 20:30:35 +00:00
2018-02-24 15:12:40 +00:00
# include "Configuration/About.h"
# include "Configuration/PropertySheet.h"
# include "Tfe/Tfe.h"
2006-02-25 20:50:29 +00:00
2019-08-09 03:50:29 +00:00
# define VERSIONSTRING_SIZE 16
2016-03-21 23:48:02 +00:00
static UINT16 g_AppleWinVersion [ 4 ] = { 0 } ;
2019-01-09 21:29:36 +00:00
static UINT16 g_OldAppleWinVersion [ 4 ] = { 0 } ;
2019-08-09 03:50:29 +00:00
TCHAR VERSIONSTRING [ VERSIONSTRING_SIZE ] = " xx.yy.zz.ww " ;
2006-02-25 20:50:29 +00:00
2018-02-24 15:12:40 +00:00
const TCHAR * g_pAppTitle = NULL ;
2006-06-27 02:34:46 +00:00
2012-09-16 21:53:07 +00:00
eApple2Type g_Apple2Type = A2TYPE_APPLE2EENHANCED ;
2006-06-12 22:06:50 +00:00
2006-02-25 20:50:29 +00:00
bool g_bFullSpeed = false ;
2006-07-02 09:56:50 +00:00
2008-06-20 23:47:25 +00:00
//=================================================
2006-07-02 09:56:50 +00:00
// Win32
HINSTANCE g_hInstance = ( HINSTANCE ) 0 ;
2006-06-12 22:06:50 +00:00
AppMode_e g_nAppMode = MODE_LOGO ;
2013-04-26 21:55:45 +00:00
static bool g_bLoadedSaveState = false ;
2006-06-12 22:06:50 +00:00
2011-02-15 17:22:33 +00:00
TCHAR g_sProgramDir [ MAX_PATH ] = TEXT ( " " ) ; // Directory of where AppleWin executable resides
TCHAR g_sDebugDir [ MAX_PATH ] = TEXT ( " " ) ; // TODO: Not currently used
TCHAR g_sScreenShotDir [ MAX_PATH ] = TEXT ( " " ) ; // TODO: Not currently used
2017-08-24 23:33:03 +00:00
bool g_bCapturePrintScreenKey = true ;
2018-06-16 09:24:05 +00:00
static bool g_bHookSystemKey = true ;
2018-07-29 21:34:09 +00:00
static bool g_bHookAltTab = false ;
static bool g_bHookAltGrControl = false ;
2018-06-16 09:24:05 +00:00
2011-02-15 17:22:33 +00:00
TCHAR g_sCurrentDir [ MAX_PATH ] = TEXT ( " " ) ; // Also Starting Dir. Debugger uses this when load/save
2016-09-10 21:58:26 +00:00
bool g_bRestart = false ;
2016-07-23 21:53:29 +00:00
bool g_bRestartFullScreen = false ;
2006-02-25 20:50:29 +00:00
DWORD g_dwSpeed = SPEED_NORMAL ; // Affected by Config dialog's speed slider bar
2019-06-28 20:34:34 +00:00
double g_fCurrentCLK6502 = CLK_6502_NTSC ; // Affected by Config dialog's speed slider bar
2006-02-25 20:50:29 +00:00
static double g_fMHz = 1.0 ; // Affected by Config dialog's speed slider bar
int g_nCpuCyclesFeedback = 0 ;
2006-03-12 09:05:39 +00:00
DWORD g_dwCyclesThisFrame = 0 ;
2013-03-23 14:14:48 +00:00
bool g_bDisableDirectInput = false ;
2006-02-25 20:50:29 +00:00
bool g_bDisableDirectSound = false ;
2009-10-07 21:38:42 +00:00
bool g_bDisableDirectSoundMockingboard = false ;
2014-09-08 21:25:29 +00:00
int g_nMemoryClearType = MIP_FF_FF_00_00 ; // Note: -1 = random MIP in Memory.cpp MemReset()
2006-02-25 20:50:29 +00:00
2012-05-06 22:14:03 +00:00
IPropertySheet & sg_PropertySheet = * new CPropertySheet ;
2007-08-06 21:38:35 +00:00
CSuperSerialCard sg_SSC ;
CMouseInterface sg_Mouse ;
2019-04-14 16:01:49 +00:00
Disk2InterfaceCard sg_Disk2Card ;
2007-08-06 21:38:35 +00:00
2018-10-26 18:23:30 +00:00
SS_CARDTYPE g_Slot0 = CT_LanguageCard ; // Just for Apple II or II+ or similar clones
SS_CARDTYPE g_Slot4 = CT_Empty ;
SS_CARDTYPE g_Slot5 = CT_Empty ;
SS_CARDTYPE g_SlotAux = CT_Extended80Col ; // For Apple //e and above
2009-01-06 22:02:31 +00:00
2008-02-22 21:28:35 +00:00
HANDLE g_hCustomRomF8 = INVALID_HANDLE_VALUE ; // Cmd-line specified custom ROM at $F800..$FFFF
static bool g_bCustomRomF8Failed = false ; // Set if custom ROM file failed
2007-05-28 11:16:42 +00:00
2010-02-14 21:11:26 +00:00
static bool g_bEnableSpeech = false ;
2010-11-24 22:39:20 +00:00
# ifdef USE_SPEECH_API
2010-02-14 21:11:26 +00:00
CSpeech g_Speech ;
2010-11-24 22:39:20 +00:00
# endif
2010-02-14 21:11:26 +00:00
2006-02-25 20:50:29 +00:00
//===========================================================================
2016-09-06 20:38:00 +00:00
static DWORD dwLogKeyReadTickStart ;
static bool bLogKeyReadDone = false ;
void LogFileTimeUntilFirstKeyReadReset ( void )
{
if ( ! g_fh )
return ;
dwLogKeyReadTickStart = GetTickCount ( ) ;
bLogKeyReadDone = false ;
}
// Log the time from emulation restart/reboot until the first key read: BIT $C000
2018-10-02 21:08:54 +00:00
// . AZTEC.DSK (DOS 3.3) does prior LDY $C000 reads, but the BIT $C000 is at the "Press any key" message
// . Phasor1.dsk / ProDOS 1.1.1: PC=E797: B1 50: LDA ($50),Y / "Select an Option:" message
2019-07-05 22:01:19 +00:00
// . Rescue Raiders v1.3,v1.5: PC=895: LDA $C000 / boot to intro
2016-09-06 20:38:00 +00:00
void LogFileTimeUntilFirstKeyRead ( void )
{
if ( ! g_fh | | bLogKeyReadDone )
return ;
2018-10-02 21:08:54 +00:00
if ( ( mem [ regs . pc - 3 ] ! = 0x2C ) // AZTEC: bit $c000
& & ! ( ( regs . pc - 2 ) = = 0xE797 & & mem [ regs . pc - 2 ] = = 0xB1 & & mem [ regs . pc - 1 ] = = 0x50 ) // Phasor1: lda ($50),y
2019-07-05 22:01:19 +00:00
& & ! ( ( regs . pc - 3 ) = = 0x0895 & & mem [ regs . pc - 3 ] = = 0xAD ) // Rescue Raiders v1.3,v1.5: lda $c000
2018-10-02 21:08:54 +00:00
)
2016-09-06 20:38:00 +00:00
return ;
DWORD dwTime = GetTickCount ( ) - dwLogKeyReadTickStart ;
LogFileOutput ( " Time from emulation reboot until first $C000 access: %d msec \n " , dwTime ) ;
bLogKeyReadDone = true ;
}
//---------------------------------------------------------------------------
2016-03-21 23:48:02 +00:00
eApple2Type GetApple2Type ( void )
{
return g_Apple2Type ;
}
void SetApple2Type ( eApple2Type type )
{
g_Apple2Type = type ;
SetMainCpuDefault ( type ) ;
}
2019-01-09 21:29:36 +00:00
const UINT16 * GetOldAppleWinVersion ( void )
2016-03-21 23:48:02 +00:00
{
2019-01-09 21:29:36 +00:00
return g_OldAppleWinVersion ;
2016-03-21 23:48:02 +00:00
}
2013-04-26 21:55:45 +00:00
bool GetLoadedSaveStateFlag ( void )
{
return g_bLoadedSaveState ;
}
void SetLoadedSaveStateFlag ( const bool bFlag )
{
g_bLoadedSaveState = bFlag ;
}
2018-07-29 21:34:09 +00:00
bool GetHookAltGrControl ( void )
{
return g_bHookAltGrControl ;
}
2013-04-26 21:55:45 +00:00
static void ResetToLogoMode ( void )
{
g_nAppMode = MODE_LOGO ;
SetLoadedSaveStateFlag ( false ) ;
}
//---------------------------------------------------------------------------
2009-06-20 13:43:12 +00:00
static bool g_bPriorityNormal = true ;
// Make APPLEWIN process higher priority
2013-03-28 22:28:42 +00:00
void SetPriorityAboveNormal ( void )
2009-06-20 13:43:12 +00:00
{
if ( ! g_bPriorityNormal )
return ;
if ( SetPriorityClass ( GetCurrentProcess ( ) , ABOVE_NORMAL_PRIORITY_CLASS ) )
{
SetThreadPriority ( GetCurrentThread ( ) , THREAD_PRIORITY_ABOVE_NORMAL ) ;
g_bPriorityNormal = false ;
}
}
// Make APPLEWIN process normal priority
2013-03-28 22:28:42 +00:00
void SetPriorityNormal ( void )
2009-06-20 13:43:12 +00:00
{
if ( g_bPriorityNormal )
return ;
if ( SetPriorityClass ( GetCurrentProcess ( ) , NORMAL_PRIORITY_CLASS ) )
{
SetThreadPriority ( GetCurrentThread ( ) , THREAD_PRIORITY_NORMAL ) ;
g_bPriorityNormal = true ;
}
}
//---------------------------------------------------------------------------
2017-02-25 22:32:46 +00:00
static UINT g_uModeStepping_Cycles = 0 ;
2017-02-26 13:45:06 +00:00
static bool g_uModeStepping_LastGetKey_ScrollLock = false ;
2017-02-25 22:32:46 +00:00
static void ContinueExecution ( void )
2006-02-25 20:50:29 +00:00
{
2017-02-25 22:32:46 +00:00
_ASSERT ( g_nAppMode = = MODE_RUNNING | | g_nAppMode = = MODE_STEPPING ) ;
2006-02-25 20:50:29 +00:00
const double fUsecPerSec = 1.e6 ;
# if 1
const UINT nExecutionPeriodUsec = 1000 ; // 1.0ms
// const UINT nExecutionPeriodUsec = 100; // 0.1ms
const double fExecutionPeriodClks = g_fCurrentCLK6502 * ( ( double ) nExecutionPeriodUsec / fUsecPerSec ) ;
# else
const double fExecutionPeriodClks = 1800.0 ;
const UINT nExecutionPeriodUsec = ( UINT ) ( fUsecPerSec * ( fExecutionPeriodClks / g_fCurrentCLK6502 ) ) ;
# endif
//
2017-02-26 13:45:06 +00:00
bool bScrollLock_FullSpeed = false ;
if ( sg_PropertySheet . GetScrollLockToggle ( ) )
{
bScrollLock_FullSpeed = g_bScrollLock_FullSpeed ;
}
else
{
if ( g_nAppMode = = MODE_RUNNING )
{
bScrollLock_FullSpeed = GetKeyState ( VK_SCROLL ) < 0 ;
}
else if ( ! IsDebugSteppingAtFullSpeed ( ) ) // Implicitly: MODE_STEPPING
{
// NB. For MODE_STEPPING: GetKeyState() is slow, so only call periodically
// . 0x3FFF is roughly the number of cycles in a video frame, which seems a reasonable rate to call GetKeyState()
if ( ( g_uModeStepping_Cycles & 0x3FFF ) = = 0 )
g_uModeStepping_LastGetKey_ScrollLock = GetKeyState ( VK_SCROLL ) < 0 ;
bScrollLock_FullSpeed = g_uModeStepping_LastGetKey_ScrollLock ;
}
}
2007-08-06 21:38:35 +00:00
2016-05-17 21:03:45 +00:00
const bool bWasFullSpeed = g_bFullSpeed ;
2017-02-25 22:32:46 +00:00
g_bFullSpeed = ( g_dwSpeed = = SPEED_MAX ) | |
2007-08-06 21:38:35 +00:00
bScrollLock_FullSpeed | |
2019-04-14 16:01:49 +00:00
( sg_Disk2Card . IsConditionForFullSpeed ( ) & & ! Spkr_IsActive ( ) & & ! MB_IsActive ( ) ) | |
2017-02-25 22:32:46 +00:00
IsDebugSteppingAtFullSpeed ( ) ;
2006-02-25 20:50:29 +00:00
2013-03-28 22:28:42 +00:00
if ( g_bFullSpeed )
2006-02-25 20:50:29 +00:00
{
2016-09-22 21:34:16 +00:00
if ( ! bWasFullSpeed )
VideoRedrawScreenDuringFullSpeed ( 0 , true ) ; // Init for full-speed mode
2006-02-25 20:50:29 +00:00
// Don't call Spkr_Mute() - will get speaker clicks
MB_Mute ( ) ;
SysClk_StopTimer ( ) ;
2010-11-24 22:39:20 +00:00
# ifdef USE_SPEECH_API
2010-02-14 21:11:26 +00:00
g_Speech . Reset ( ) ; // TODO: Put this on a timer (in emulated cycles)... otherwise CATALOG cuts out
2010-11-24 22:39:20 +00:00
# endif
2006-02-25 20:50:29 +00:00
g_nCpuCyclesFeedback = 0 ; // For the case when this is a big -ve number
2009-06-20 13:43:12 +00:00
// Switch to normal priority so that APPLEWIN process doesn't hog machine!
//. EG: No disk in Drive-1, and boot Apple: Windows will start to crawl!
SetPriorityNormal ( ) ;
2006-02-25 20:50:29 +00:00
}
else
{
2016-05-17 21:03:45 +00:00
if ( bWasFullSpeed )
VideoRedrawScreenAfterFullSpeed ( g_dwCyclesThisFrame ) ;
2006-02-25 20:50:29 +00:00
// Don't call Spkr_Demute()
MB_Demute ( ) ;
SysClk_StartTimerUsec ( nExecutionPeriodUsec ) ;
2009-06-20 13:43:12 +00:00
// Switch to higher priority, eg. for audio (BUG #015394)
SetPriorityAboveNormal ( ) ;
2006-02-25 20:50:29 +00:00
}
//
2017-02-26 13:45:06 +00:00
int nCyclesWithFeedback = ( int ) fExecutionPeriodClks + g_nCpuCyclesFeedback ;
const UINT uCyclesToExecuteWithFeedback = ( nCyclesWithFeedback > = 0 ) ? nCyclesWithFeedback
: 0 ;
2006-02-25 20:50:29 +00:00
2017-02-26 13:45:06 +00:00
const DWORD uCyclesToExecute = ( g_nAppMode = = MODE_RUNNING ) ? uCyclesToExecuteWithFeedback
/* MODE_STEPPING */ : 0 ;
2017-02-25 22:32:46 +00:00
const bool bVideoUpdate = ! g_bFullSpeed ;
2017-02-26 13:45:06 +00:00
const DWORD uActualCyclesExecuted = CpuExecute ( uCyclesToExecute , bVideoUpdate ) ;
2014-09-14 20:23:54 +00:00
g_dwCyclesThisFrame + = uActualCyclesExecuted ;
2006-02-25 20:50:29 +00:00
2019-04-14 16:01:49 +00:00
sg_Disk2Card . UpdateDriveState ( uActualCyclesExecuted ) ;
2014-09-14 20:23:54 +00:00
JoyUpdateButtonLatch ( nExecutionPeriodUsec ) ; // Button latch time is independent of CPU clock frequency
PrintUpdate ( uActualCyclesExecuted ) ;
2006-02-25 20:50:29 +00:00
//
2017-02-25 22:32:46 +00:00
DWORD uSpkrActualCyclesExecuted = uActualCyclesExecuted ;
bool bModeStepping_WaitTimer = false ;
if ( g_nAppMode = = MODE_STEPPING & & ! IsDebugSteppingAtFullSpeed ( ) )
{
g_uModeStepping_Cycles + = uActualCyclesExecuted ;
2017-02-26 13:45:06 +00:00
if ( g_uModeStepping_Cycles > = uCyclesToExecuteWithFeedback )
2017-02-25 22:32:46 +00:00
{
uSpkrActualCyclesExecuted = g_uModeStepping_Cycles ;
2017-02-26 13:45:06 +00:00
g_uModeStepping_Cycles - = uCyclesToExecuteWithFeedback ;
2017-02-25 22:32:46 +00:00
bModeStepping_WaitTimer = true ;
}
}
// For MODE_STEPPING: do this speaker update periodically
// - Otherwise kills performance due to sound-buffer lock/unlock for every 6502 opcode!
if ( g_nAppMode = = MODE_RUNNING | | bModeStepping_WaitTimer )
SpkrUpdate ( uSpkrActualCyclesExecuted ) ;
//
2019-06-28 20:34:34 +00:00
const UINT dwClksPerFrame = NTSC_GetCyclesPerFrame ( ) ;
2013-03-28 22:28:42 +00:00
if ( g_dwCyclesThisFrame > = dwClksPerFrame )
2006-02-25 20:50:29 +00:00
{
2006-03-12 09:05:39 +00:00
g_dwCyclesThisFrame - = dwClksPerFrame ;
2015-01-01 19:48:59 +00:00
2016-07-23 21:53:29 +00:00
if ( g_bFullSpeed )
VideoRedrawScreenDuringFullSpeed ( g_dwCyclesThisFrame ) ;
2016-09-18 14:56:22 +00:00
else
2016-11-06 14:33:14 +00:00
VideoRefreshScreen ( ) ; // Just copy the output of our Apple framebuffer to the system Back Buffer
2016-07-23 21:53:29 +00:00
2007-08-06 21:38:35 +00:00
MB_EndOfVideoFrame ( ) ;
2006-02-25 20:50:29 +00:00
}
2017-02-25 22:32:46 +00:00
if ( ( g_nAppMode = = MODE_RUNNING & & ! g_bFullSpeed ) | | bModeStepping_WaitTimer )
2006-02-25 20:50:29 +00:00
{
SysClk_WaitTimer ( ) ;
}
}
2017-02-26 13:45:06 +00:00
void SingleStep ( bool bReinit )
2017-02-25 22:32:46 +00:00
{
2017-02-26 13:45:06 +00:00
if ( bReinit )
{
g_uModeStepping_Cycles = 0 ;
g_uModeStepping_LastGetKey_ScrollLock = false ;
}
2017-02-25 22:32:46 +00:00
ContinueExecution ( ) ;
}
2006-02-25 20:50:29 +00:00
//===========================================================================
2019-06-28 20:34:34 +00:00
double Get6502BaseClock ( void )
{
return ( GetVideoRefreshRate ( ) = = VR_50HZ ) ? CLK_6502_PAL : CLK_6502_NTSC ;
}
2013-03-28 22:28:42 +00:00
void SetCurrentCLK6502 ( void )
2006-02-25 20:50:29 +00:00
{
static DWORD dwPrevSpeed = ( DWORD ) - 1 ;
2019-06-28 20:34:34 +00:00
static VideoRefreshRate_e prevVideoRefreshRate = VR_NONE ;
2006-02-25 20:50:29 +00:00
2019-06-28 20:34:34 +00:00
if ( dwPrevSpeed = = g_dwSpeed & & GetVideoRefreshRate ( ) = = prevVideoRefreshRate )
2006-02-25 20:50:29 +00:00
return ;
dwPrevSpeed = g_dwSpeed ;
2019-06-28 20:34:34 +00:00
prevVideoRefreshRate = GetVideoRefreshRate ( ) ;
2006-02-25 20:50:29 +00:00
// SPEED_MIN = 0 = 0.50 MHz
// SPEED_NORMAL = 10 = 1.00 MHz
// 20 = 2.00 MHz
// SPEED_MAX-1 = 39 = 3.90 MHz
// SPEED_MAX = 40 = ???? MHz (run full-speed, /g_fCurrentCLK6502/ is ignored)
if ( g_dwSpeed < SPEED_NORMAL )
g_fMHz = 0.5 + ( double ) g_dwSpeed * 0.05 ;
else
g_fMHz = ( double ) g_dwSpeed / 10.0 ;
2019-06-28 20:34:34 +00:00
g_fCurrentCLK6502 = Get6502BaseClock ( ) * g_fMHz ;
2006-02-25 20:50:29 +00:00
//
// Now re-init modules that are dependent on /g_fCurrentCLK6502/
//
SpkrReinitialize ( ) ;
MB_Reinitialize ( ) ;
}
//===========================================================================
2013-03-28 22:28:42 +00:00
void EnterMessageLoop ( void )
2006-06-12 22:06:50 +00:00
{
MSG message ;
2007-03-27 20:46:14 +00:00
PeekMessage ( & message , NULL , 0 , 0 , PM_NOREMOVE ) ;
2006-07-05 21:23:13 +00:00
while ( message . message ! = WM_QUIT )
{
2007-03-27 20:46:14 +00:00
if ( PeekMessage ( & message , NULL , 0 , 0 , PM_REMOVE ) )
2006-06-12 22:06:50 +00:00
{
2007-03-27 20:46:14 +00:00
TranslateMessage ( & message ) ;
DispatchMessage ( & message ) ;
while ( ( g_nAppMode = = MODE_RUNNING ) | | ( g_nAppMode = = MODE_STEPPING ) )
2006-06-12 22:06:50 +00:00
{
2007-03-27 20:46:14 +00:00
if ( PeekMessage ( & message , 0 , 0 , 0 , PM_REMOVE ) )
{
if ( message . message = = WM_QUIT )
return ;
TranslateMessage ( & message ) ;
DispatchMessage ( & message ) ;
}
else if ( g_nAppMode = = MODE_STEPPING )
{
DebugContinueStepping ( ) ;
}
else
{
ContinueExecution ( ) ;
if ( g_nAppMode ! = MODE_DEBUG )
{
if ( g_bFullSpeed )
ContinueExecution ( ) ;
}
}
2006-06-12 22:06:50 +00:00
}
}
2007-03-27 20:46:14 +00:00
else
2007-03-23 22:26:35 +00:00
{
2007-03-27 20:46:14 +00:00
if ( g_nAppMode = = MODE_DEBUG )
DebuggerUpdate ( ) ;
2017-04-22 19:42:42 +00:00
else if ( g_nAppMode = = MODE_PAUSED )
Sleep ( 1 ) ; // Stop process hogging CPU - 1ms, as need to fade-out speaker sound buffer
else if ( g_nAppMode = = MODE_LOGO )
2018-06-30 17:21:28 +00:00
Sleep ( 1 ) ; // Stop process hogging CPU (NB. don't delay for too long otherwise key input can be slow in other apps - GH#569)
2007-03-23 22:26:35 +00:00
}
2006-07-05 21:23:13 +00:00
}
}
2006-06-12 22:06:50 +00:00
2006-02-25 20:50:29 +00:00
//===========================================================================
2013-03-28 22:28:42 +00:00
void GetProgramDirectory ( void )
{
GetModuleFileName ( ( HINSTANCE ) 0 , g_sProgramDir , MAX_PATH ) ;
g_sProgramDir [ MAX_PATH - 1 ] = 0 ;
int loop = _tcslen ( g_sProgramDir ) ;
while ( loop - - )
{
if ( ( g_sProgramDir [ loop ] = = TEXT ( ' \\ ' ) ) | | ( g_sProgramDir [ loop ] = = TEXT ( ' : ' ) ) )
{
g_sProgramDir [ loop + 1 ] = 0 ;
break ;
}
}
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2013-12-31 22:40:10 +00:00
// Backwards compatibility with AppleWin <1.24.0
2017-07-03 20:48:21 +00:00
static void LoadConfigOldJoystick_v1 ( const UINT uJoyNum )
2013-12-31 22:40:10 +00:00
{
DWORD dwOldJoyType ;
2017-07-03 20:48:21 +00:00
if ( ! REGLOAD ( TEXT ( uJoyNum = = 0 ? REGVALUE_OLD_JOYSTICK0_EMU_TYPE1 : REGVALUE_OLD_JOYSTICK1_EMU_TYPE1 ) , & dwOldJoyType ) )
2013-12-31 22:40:10 +00:00
return ; // EG. Old AppleWin never installed
UINT uNewJoyType ;
switch ( dwOldJoyType )
{
case 0 : // Disabled
default :
uNewJoyType = J0C_DISABLED ;
break ;
case 1 : // PC Joystick
uNewJoyType = J0C_JOYSTICK1 ;
break ;
case 2 : // Keyboard (standard)
uNewJoyType = J0C_KEYBD_NUMPAD ;
sg_PropertySheet . SetJoystickCenteringControl ( JOYSTICK_MODE_FLOATING ) ;
break ;
case 3 : // Keyboard (centering)
uNewJoyType = J0C_KEYBD_NUMPAD ;
sg_PropertySheet . SetJoystickCenteringControl ( JOYSTICK_MODE_CENTERING ) ;
break ;
case 4 : // Mouse
uNewJoyType = J0C_MOUSE ;
break ;
}
2016-03-21 23:48:02 +00:00
JoySetJoyType ( uJoyNum , uNewJoyType ) ;
}
2008-06-20 23:47:25 +00:00
//Reads configuration from the registry entries
2013-03-28 22:28:42 +00:00
void LoadConfiguration ( void )
2007-05-28 11:16:42 +00:00
{
2019-08-09 03:50:29 +00:00
DWORD dwComputerType = 0 ;
2016-03-21 23:48:02 +00:00
eApple2Type apple2Type = A2TYPE_APPLE2EENHANCED ;
2007-05-28 11:16:42 +00:00
2012-03-20 23:17:06 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_APPLE2_TYPE ) , & dwComputerType ) )
{
2017-05-08 21:32:01 +00:00
const DWORD dwLoadedComputerType = dwComputerType ;
if ( ( dwComputerType > = A2TYPE_MAX ) | |
( dwComputerType > = A2TYPE_UNDEFINED & & dwComputerType < A2TYPE_CLONE ) | |
( dwComputerType > = A2TYPE_CLONE_A2_MAX & & dwComputerType < A2TYPE_CLONE_A2E ) )
2012-09-16 21:53:07 +00:00
dwComputerType = A2TYPE_APPLE2EENHANCED ;
2008-06-20 23:47:25 +00:00
2016-04-12 22:21:05 +00:00
// Remap the bad Pravets models (before AppleWin v1.26)
if ( dwComputerType = = A2TYPE_BAD_PRAVETS82 ) dwComputerType = A2TYPE_PRAVETS82 ;
if ( dwComputerType = = A2TYPE_BAD_PRAVETS8M ) dwComputerType = A2TYPE_PRAVETS8M ;
2017-05-08 21:32:01 +00:00
// Remap the bad Pravets models (at AppleWin v1.26) - GH#415
if ( dwComputerType = = A2TYPE_CLONE ) dwComputerType = A2TYPE_PRAVETS82 ;
if ( dwLoadedComputerType ! = dwComputerType )
{
char sText [ 100 ] ;
_snprintf ( sText , sizeof ( sText ) - 1 , " Unsupported Apple2Type(%d). Changing to %d " , dwLoadedComputerType , dwComputerType ) ;
2018-01-26 11:03:44 +00:00
LogFileOutput ( " %s \n " , sText ) ;
2017-05-08 21:32:01 +00:00
MessageBox (
GetDesktopWindow ( ) , // NB. g_hFrameWindow is not yet valid
sText ,
" Load Configuration " ,
MB_ICONSTOP | MB_SETFOREGROUND ) ;
2018-01-26 11:03:44 +00:00
sg_PropertySheet . ConfigSaveApple2Type ( ( eApple2Type ) dwComputerType ) ;
2017-05-08 21:32:01 +00:00
}
2016-03-21 23:48:02 +00:00
apple2Type = ( eApple2Type ) dwComputerType ;
2012-03-20 23:17:06 +00:00
}
2019-08-09 03:50:29 +00:00
else if ( REGLOAD ( TEXT ( REGVALUE_OLD_APPLE2_TYPE ) , & dwComputerType ) ) // Support older AppleWin registry entries
2012-03-20 23:17:06 +00:00
{
switch ( dwComputerType )
2008-06-20 23:47:25 +00:00
{
2012-03-20 23:17:06 +00:00
// NB. No A2TYPE_APPLE2E (this is correct)
2016-03-21 23:48:02 +00:00
case 0 : apple2Type = A2TYPE_APPLE2 ; break ;
case 1 : apple2Type = A2TYPE_APPLE2PLUS ; break ;
case 2 : apple2Type = A2TYPE_APPLE2EENHANCED ; break ;
2019-08-09 03:50:29 +00:00
default : apple2Type = A2TYPE_APPLE2EENHANCED ; break ;
2008-06-20 23:47:25 +00:00
}
}
2007-05-28 11:16:42 +00:00
2016-03-21 23:48:02 +00:00
SetApple2Type ( apple2Type ) ;
//
2019-08-09 03:50:29 +00:00
DWORD dwMainCpuType ;
REGLOAD_DEFAULT ( TEXT ( REGVALUE_CPU_TYPE ) , & dwMainCpuType , CPU_65C02 ) ;
if ( dwMainCpuType ! = CPU_6502 & & dwMainCpuType ! = CPU_65C02 )
dwMainCpuType = CPU_65C02 ;
SetMainCpu ( ( eCpuType ) dwMainCpuType ) ;
2016-03-21 23:48:02 +00:00
//
DWORD dwJoyType ;
if ( REGLOAD ( TEXT ( REGVALUE_JOYSTICK0_EMU_TYPE ) , & dwJoyType ) )
JoySetJoyType ( JN_JOYSTICK0 , dwJoyType ) ;
2017-07-03 20:48:21 +00:00
else if ( REGLOAD ( TEXT ( REGVALUE_OLD_JOYSTICK0_EMU_TYPE2 ) , & dwJoyType ) ) // GH#434
JoySetJoyType ( JN_JOYSTICK0 , dwJoyType ) ;
2016-03-21 23:48:02 +00:00
else
2017-07-03 20:48:21 +00:00
LoadConfigOldJoystick_v1 ( JN_JOYSTICK0 ) ;
2016-03-21 23:48:02 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_JOYSTICK1_EMU_TYPE ) , & dwJoyType ) )
JoySetJoyType ( JN_JOYSTICK1 , dwJoyType ) ;
2017-07-03 20:48:21 +00:00
else if ( REGLOAD ( TEXT ( REGVALUE_OLD_JOYSTICK1_EMU_TYPE2 ) , & dwJoyType ) ) // GH#434
JoySetJoyType ( JN_JOYSTICK1 , dwJoyType ) ;
2016-03-21 23:48:02 +00:00
else
2017-07-03 20:48:21 +00:00
LoadConfigOldJoystick_v1 ( JN_JOYSTICK1 ) ;
2008-04-11 21:54:06 +00:00
2016-09-07 21:20:15 +00:00
DWORD dwSoundType ;
2019-08-09 03:50:29 +00:00
REGLOAD_DEFAULT ( TEXT ( " Sound Emulation " ) , & dwSoundType , REG_SOUNDTYPE_NONE ) ;
2016-09-07 21:20:15 +00:00
switch ( dwSoundType )
{
case REG_SOUNDTYPE_NONE :
case REG_SOUNDTYPE_DIRECT : // Not supported from 1.26
case REG_SOUNDTYPE_SMART : // Not supported from 1.26
default :
soundtype = SOUND_NONE ;
break ;
case REG_SOUNDTYPE_WAVE :
soundtype = SOUND_WAVE ;
break ;
}
2007-05-28 11:16:42 +00:00
2019-08-09 03:50:29 +00:00
TCHAR serialPortName [ CSuperSerialCard : : SIZEOF_SERIALCHOICE_ITEM ] ;
if ( RegLoadString (
TEXT ( REG_CONFIG ) ,
2013-03-28 22:28:42 +00:00
TEXT ( REGVALUE_SERIAL_PORT_NAME ) ,
TRUE ,
2019-08-09 03:50:29 +00:00
serialPortName ,
CSuperSerialCard : : SIZEOF_SERIALCHOICE_ITEM ) )
2013-03-28 22:28:42 +00:00
{
2019-08-09 03:50:29 +00:00
sg_SSC . SetSerialPortName ( serialPortName ) ;
2013-03-28 22:28:42 +00:00
}
2007-05-28 11:16:42 +00:00
2019-08-09 03:50:29 +00:00
REGLOAD_DEFAULT ( TEXT ( REGVALUE_EMULATION_SPEED ) , & g_dwSpeed , SPEED_NORMAL ) ;
2019-06-28 20:34:34 +00:00
Config_Load_Video ( ) ;
SetCurrentCLK6502 ( ) ; // Pre: g_dwSpeed && Config_Load_Video()->SetVideoRefreshRate()
2018-02-25 15:09:25 +00:00
DWORD dwEnhanceDisk ;
2019-08-09 03:50:29 +00:00
REGLOAD_DEFAULT ( TEXT ( REGVALUE_ENHANCE_DISK_SPEED ) , & dwEnhanceDisk , 1 ) ;
2019-04-14 16:01:49 +00:00
sg_Disk2Card . SetEnhanceDisk ( dwEnhanceDisk ? true : false ) ;
2009-02-14 04:05:15 +00:00
2019-08-09 03:50:29 +00:00
DWORD dwTfeEnabled ;
REGLOAD_DEFAULT ( TEXT ( " Uthernet Active " ) , & dwTfeEnabled , 0 ) ;
tfe_enabled = dwTfeEnabled ? 1 : 0 ;
2006-02-25 20:50:29 +00:00
2013-03-28 22:28:42 +00:00
//
2006-02-25 20:50:29 +00:00
2019-08-09 03:50:29 +00:00
DWORD dwTmp = 0 ;
2006-02-25 20:50:29 +00:00
2017-10-02 21:22:26 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_FS_SHOW_SUBUNIT_STATUS ) , & dwTmp ) )
SetFullScreenShowSubunitStatus ( dwTmp ? true : false ) ;
2013-03-28 22:28:42 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_THE_FREEZES_F8_ROM ) , & dwTmp ) )
sg_PropertySheet . SetTheFreezesF8Rom ( dwTmp ) ;
2007-08-06 21:38:35 +00:00
2013-03-28 22:28:42 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_SPKR_VOLUME ) , & dwTmp ) )
SpkrSetVolume ( dwTmp , sg_PropertySheet . GetVolumeMax ( ) ) ;
2006-02-25 20:50:29 +00:00
2013-03-28 22:28:42 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_MB_VOLUME ) , & dwTmp ) )
MB_SetVolume ( dwTmp , sg_PropertySheet . GetVolumeMax ( ) ) ;
2006-02-25 20:50:29 +00:00
2013-03-28 22:28:42 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_SAVE_STATE_ON_EXIT ) , & dwTmp ) )
g_bSaveStateOnExit = dwTmp ? true : false ;
2006-02-25 20:50:29 +00:00
2009-01-09 21:59:22 +00:00
2013-03-28 22:28:42 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_DUMP_TO_PRINTER ) , & dwTmp ) )
g_bDumpToPrinter = dwTmp ? true : false ;
2009-01-09 21:59:22 +00:00
2013-03-28 22:28:42 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_CONVERT_ENCODING ) , & dwTmp ) )
g_bConvertEncoding = dwTmp ? true : false ;
2009-01-09 21:59:22 +00:00
2013-03-28 22:28:42 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_FILTER_UNPRINTABLE ) , & dwTmp ) )
g_bFilterUnprintable = dwTmp ? true : false ;
2009-01-09 21:59:22 +00:00
2013-03-28 22:28:42 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_PRINTER_APPEND ) , & dwTmp ) )
g_bPrinterAppend = dwTmp ? true : false ;
2009-01-09 21:59:22 +00:00
2013-03-28 22:28:42 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_HDD_ENABLED ) , & dwTmp ) )
HD_SetEnabled ( dwTmp ? true : false ) ;
2006-02-25 20:50:29 +00:00
2013-03-28 22:28:42 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_PDL_XTRIM ) , & dwTmp ) )
JoySetTrim ( ( short ) dwTmp , true ) ;
if ( REGLOAD ( TEXT ( REGVALUE_PDL_YTRIM ) , & dwTmp ) )
JoySetTrim ( ( short ) dwTmp , false ) ;
2006-02-25 20:50:29 +00:00
2013-03-28 22:28:42 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_SCROLLLOCK_TOGGLE ) , & dwTmp ) )
sg_PropertySheet . SetScrollLockToggle ( dwTmp ) ;
2007-08-06 21:38:35 +00:00
2013-12-06 21:10:41 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_CURSOR_CONTROL ) , & dwTmp ) )
2013-12-31 22:40:10 +00:00
sg_PropertySheet . SetJoystickCursorControl ( dwTmp ) ;
2013-12-06 21:10:41 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_AUTOFIRE ) , & dwTmp ) )
sg_PropertySheet . SetAutofire ( dwTmp ) ;
2013-12-31 22:40:10 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_CENTERING_CONTROL ) , & dwTmp ) )
sg_PropertySheet . SetJoystickCenteringControl ( dwTmp ) ;
2013-12-06 21:10:41 +00:00
2013-03-28 22:28:42 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_MOUSE_CROSSHAIR ) , & dwTmp ) )
sg_PropertySheet . SetMouseShowCrosshair ( dwTmp ) ;
if ( REGLOAD ( TEXT ( REGVALUE_MOUSE_RESTRICT_TO_WINDOW ) , & dwTmp ) )
sg_PropertySheet . SetMouseRestrictToWindow ( dwTmp ) ;
2008-08-19 21:36:31 +00:00
2012-03-20 23:17:06 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_SLOT4 ) , & dwTmp ) )
g_Slot4 = ( SS_CARDTYPE ) dwTmp ;
if ( REGLOAD ( TEXT ( REGVALUE_SLOT5 ) , & dwTmp ) )
g_Slot5 = ( SS_CARDTYPE ) dwTmp ;
2012-01-22 13:46:36 +00:00
2012-01-23 22:40:36 +00:00
//
2006-02-25 20:50:29 +00:00
2019-08-09 03:50:29 +00:00
TCHAR szFilename [ MAX_PATH ] ;
2009-01-09 21:59:22 +00:00
2019-08-09 03:50:29 +00:00
RegLoadString ( TEXT ( REG_PREFS ) , TEXT ( REGVALUE_PREF_HDV_START_DIR ) , 1 , szFilename , MAX_PATH , TEXT ( " " ) ) ;
if ( szFilename [ 0 ] = = ' \0 ' )
2016-03-21 23:48:02 +00:00
GetCurrentDirectory ( sizeof ( szFilename ) , szFilename ) ;
SetCurrentImageDir ( szFilename ) ;
HD_LoadLastDiskImage ( HARDDISK_1 ) ;
HD_LoadLastDiskImage ( HARDDISK_2 ) ;
//
2009-01-06 22:02:31 +00:00
// Current/Starting Dir is the "root" of where the user keeps his disk images
2019-08-09 03:50:29 +00:00
RegLoadString ( TEXT ( REG_PREFS ) , TEXT ( REGVALUE_PREF_START_DIR ) , 1 , szFilename , MAX_PATH , TEXT ( " " ) ) ;
if ( szFilename [ 0 ] = = ' \0 ' )
2013-12-29 22:09:41 +00:00
GetCurrentDirectory ( sizeof ( szFilename ) , szFilename ) ;
SetCurrentImageDir ( szFilename ) ;
2009-01-06 22:02:31 +00:00
2019-04-14 16:01:49 +00:00
sg_Disk2Card . LoadLastDiskImage ( DRIVE_1 ) ;
sg_Disk2Card . LoadLastDiskImage ( DRIVE_2 ) ;
2009-01-06 22:02:31 +00:00
2013-12-29 22:09:41 +00:00
//
2019-08-09 03:50:29 +00:00
RegLoadString ( TEXT ( REG_CONFIG ) , TEXT ( REGVALUE_SAVESTATE_FILENAME ) , 1 , szFilename , MAX_PATH , TEXT ( " " ) ) ;
2013-12-29 22:09:41 +00:00
Snapshot_SetFilename ( szFilename ) ; // If not in Registry than default will be used (ie. g_sCurrentDir + default filename)
2019-08-09 03:50:29 +00:00
RegLoadString ( TEXT ( REG_CONFIG ) , TEXT ( REGVALUE_PRINTER_FILENAME ) , 1 , szFilename , MAX_PATH , TEXT ( " " ) ) ;
2013-12-29 22:09:41 +00:00
Printer_SetFilename ( szFilename ) ; // If not in Registry than default will be used
2019-08-09 03:50:29 +00:00
REGLOAD_DEFAULT ( TEXT ( REGVALUE_PRINTER_IDLE_LIMIT ) , & dwTmp , 10 ) ;
2009-01-09 21:59:22 +00:00
Printer_SetIdleLimit ( dwTmp ) ;
2019-08-09 03:50:29 +00:00
RegLoadString ( TEXT ( REG_CONFIG ) , TEXT ( " Uthernet Interface " ) , 1 , szFilename , MAX_PATH , TEXT ( " " ) ) ;
update_tfe_interface ( szFilename , NULL ) ;
2012-12-29 14:53:52 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_WINDOW_SCALE ) , & dwTmp ) )
SetViewportScale ( dwTmp ) ;
2014-07-26 21:51:23 +00:00
2014-07-27 21:31:00 +00:00
if ( REGLOAD ( TEXT ( REGVALUE_CONFIRM_REBOOT ) , & dwTmp ) )
g_bConfirmReboot = dwTmp ;
2009-01-06 22:02:31 +00:00
}
2006-02-25 20:50:29 +00:00
2009-01-06 22:02:31 +00:00
//===========================================================================
2008-06-21 11:48:15 +00:00
2015-01-11 00:56:47 +00:00
bool SetCurrentImageDir ( const char * pszImageDir )
2009-01-06 22:02:31 +00:00
{
2013-12-29 22:09:41 +00:00
strcpy ( g_sCurrentDir , pszImageDir ) ;
2014-09-02 15:48:46 +00:00
int nLen = strlen ( g_sCurrentDir ) ;
2016-03-21 23:48:02 +00:00
if ( ( nLen > 0 ) & & ( g_sCurrentDir [ nLen - 1 ] ! = ' \\ ' ) )
2014-09-02 15:48:46 +00:00
{
2014-09-04 00:14:06 +00:00
g_sCurrentDir [ nLen + 0 ] = ' \\ ' ;
g_sCurrentDir [ nLen + 1 ] = 0 ;
2014-09-02 15:48:46 +00:00
}
2015-01-11 00:56:47 +00:00
if ( SetCurrentDirectory ( g_sCurrentDir ) )
return true ;
return false ;
2008-06-21 11:48:15 +00:00
}
2010-01-03 18:43:08 +00:00
//===========================================================================
2009-02-14 04:05:15 +00:00
// TODO: Added dialog option of which file extensions to registry
2013-03-28 22:28:42 +00:00
static bool g_bRegisterFileTypes = true ;
2009-02-14 04:05:15 +00:00
2013-03-28 22:28:42 +00:00
void RegisterExtensions ( void )
2006-05-02 21:56:28 +00:00
{
TCHAR szCommandTmp [ MAX_PATH ] ;
GetModuleFileName ( ( HMODULE ) 0 , szCommandTmp , MAX_PATH ) ;
TCHAR command [ MAX_PATH ] ;
wsprintf ( command , " \" %s \" " , szCommandTmp ) ; // Wrap path & filename in quotes & null terminate
TCHAR icon [ MAX_PATH ] ;
wsprintf ( icon , TEXT ( " %s,1 " ) , ( LPCTSTR ) command ) ;
_tcscat ( command , TEXT ( " \" %1 \" " ) ) ; // Append "%1"
2009-02-14 04:05:15 +00:00
// _tcscat(command,TEXT("-d1 %1\"")); // Append "%1"
// sprintf(command, "\"%s\" \"-d1 %%1\"", szCommandTmp); // Wrap path & filename in quotes & null terminate
2006-05-02 21:56:28 +00:00
2019-07-28 16:13:39 +00:00
// NB. Registry access to HKLM typically results in ErrorCode 5(ACCESS DENIED), as UAC requires elevated permissions (Run as administrator).
// . HKEY_CLASSES_ROOT\CLSID is a merged view of HKLM\SOFTWARE\Classes and HKCU\SOFTWARE\Classes
2010-01-03 18:43:08 +00:00
// NB. Reflect extensions in DELREG.INF
2018-02-24 15:24:37 +00:00
// RegSetValue(HKEY_CLASSES_ROOT,".bin",REG_SZ,"DiskImage",0); // Removed as .bin is too generic
2010-01-03 18:43:08 +00:00
2019-07-28 16:13:39 +00:00
const char * pValueName = " .bin " ;
LSTATUS res = RegDeleteValue ( HKEY_CLASSES_ROOT , pValueName ) ;
if ( res ! = NOERROR & & res ! = ERROR_FILE_NOT_FOUND ) LogFileOutput ( " RegDeleteValue(%s) failed (0x%08X) \n " , pValueName , res ) ;
pValueName = " .do " ;
res = RegSetValue ( HKEY_CLASSES_ROOT , pValueName , REG_SZ , " DiskImage " , 0 ) ;
if ( res ! = NOERROR ) LogFileOutput ( " RegSetValue(%s) failed (0x%08X) \n " , pValueName , res ) ;
pValueName = " .dsk " ;
res = RegSetValue ( HKEY_CLASSES_ROOT , pValueName , REG_SZ , " DiskImage " , 0 ) ;
if ( res ! = NOERROR ) LogFileOutput ( " RegSetValue(%s) failed (0x%08X) \n " , pValueName , res ) ;
pValueName = " .nib " ;
res = RegSetValue ( HKEY_CLASSES_ROOT , pValueName , REG_SZ , " DiskImage " , 0 ) ;
if ( res ! = NOERROR ) LogFileOutput ( " RegSetValue(%s) failed (0x%08X) \n " , pValueName , res ) ;
pValueName = " .po " ;
res = RegSetValue ( HKEY_CLASSES_ROOT , pValueName , REG_SZ , " DiskImage " , 0 ) ;
if ( res ! = NOERROR ) LogFileOutput ( " RegSetValue(%s) failed (0x%08X) \n " , pValueName , res ) ;
pValueName = " .woz " ;
res = RegSetValue ( HKEY_CLASSES_ROOT , pValueName , REG_SZ , " DiskImage " , 0 ) ;
if ( res ! = NOERROR ) LogFileOutput ( " RegSetValue(%s) failed (0x%08X) \n " , pValueName , res ) ;
2018-02-24 15:24:37 +00:00
// RegSetValue(HKEY_CLASSES_ROOT,".2mg",REG_SZ,"DiskImage",0); // Don't grab this, as not all .2mg images are supported (so defer to CiderPress)
// RegSetValue(HKEY_CLASSES_ROOT,".2img",REG_SZ,"DiskImage",0); // Don't grab this, as not all .2mg images are supported (so defer to CiderPress)
2019-07-28 16:13:39 +00:00
// RegSetValue(HKEY_CLASSES_ROOT,".aws.yaml",REG_SZ,"DiskImage",0); // NB. Can't grab this extension (even though it returns 0!) with embedded period (and .yaml is too generic) - GH#548
2018-02-24 15:24:37 +00:00
// RegSetValue(HKEY_CLASSES_ROOT,".hdv",REG_SZ,"DiskImage",0); // TO DO
2006-05-02 21:56:28 +00:00
2019-07-28 16:13:39 +00:00
pValueName = " DiskImage " ;
res = RegSetValue ( HKEY_CLASSES_ROOT ,
pValueName ,
2018-02-24 15:24:37 +00:00
REG_SZ , " Disk Image " , 0 ) ;
2019-07-28 16:13:39 +00:00
if ( res ! = NOERROR ) LogFileOutput ( " RegSetValue(%s) failed (0x%08X) \n " , pValueName , res ) ;
2006-05-02 21:56:28 +00:00
2019-07-28 16:13:39 +00:00
pValueName = " DiskImage \\ DefaultIcon " ;
res = RegSetValue ( HKEY_CLASSES_ROOT ,
pValueName ,
2018-02-24 15:24:37 +00:00
REG_SZ , icon , 0 ) ;
2019-07-28 16:13:39 +00:00
if ( res ! = NOERROR ) LogFileOutput ( " RegSetValue(%s) failed (0x%08X) \n " , pValueName , res ) ;
2006-05-02 21:56:28 +00:00
2009-02-14 04:05:15 +00:00
// This key can interfere....
// HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExt\.dsk
2019-07-28 16:13:39 +00:00
pValueName = " DiskImage \\ shell \\ open \\ command " ;
res = RegSetValue ( HKEY_CLASSES_ROOT ,
pValueName ,
2006-05-02 21:56:28 +00:00
REG_SZ , command , _tcslen ( command ) + 1 ) ;
2019-07-28 16:13:39 +00:00
if ( res ! = NOERROR ) LogFileOutput ( " RegSetValue(%s) failed (0x%08X) \n " , pValueName , res ) ;
2006-05-02 21:56:28 +00:00
2019-07-28 16:13:39 +00:00
pValueName = " DiskImage \\ shell \\ open \\ ddeexec " ;
res = RegSetValue ( HKEY_CLASSES_ROOT ,
pValueName ,
2006-05-02 21:56:28 +00:00
REG_SZ , " %1 " , 3 ) ;
2019-07-28 16:13:39 +00:00
if ( res ! = NOERROR ) LogFileOutput ( " RegSetValue(%s) failed (0x%08X) \n " , pValueName , res ) ;
2006-05-02 21:56:28 +00:00
2019-07-28 16:13:39 +00:00
pValueName = " DiskImage \\ shell \\ open \\ ddeexec \\ application " ;
res = RegSetValue ( HKEY_CLASSES_ROOT ,
pValueName ,
2009-02-14 04:05:15 +00:00
REG_SZ , " applewin " , _tcslen ( " applewin " ) + 1 ) ;
// REG_SZ,szCommandTmp,_tcslen(szCommandTmp)+1);
2019-07-28 16:13:39 +00:00
if ( res ! = NOERROR ) LogFileOutput ( " RegSetValue(%s) failed (0x%08X) \n " , pValueName , res ) ;
2006-05-02 21:56:28 +00:00
2019-07-28 16:13:39 +00:00
pValueName = " DiskImage \\ shell \\ open \\ ddeexec \\ topic " ;
res = RegSetValue ( HKEY_CLASSES_ROOT ,
pValueName ,
2009-02-14 04:05:15 +00:00
REG_SZ , " system " , _tcslen ( " system " ) + 1 ) ;
2019-07-28 16:13:39 +00:00
if ( res ! = NOERROR ) LogFileOutput ( " RegSetValue(%s) failed (0x%08X) \n " , pValueName , res ) ;
2006-02-25 20:50:29 +00:00
}
2008-07-14 16:02:44 +00:00
//===========================================================================
2018-04-02 11:38:05 +00:00
// NB. On a restart, it's OK to call RegisterHotKey() again since the old g_hFrameWindow has been destroyed
2018-05-28 16:27:38 +00:00
static void RegisterHotKeys ( void )
2009-01-06 22:02:31 +00:00
{
2018-02-27 21:07:16 +00:00
BOOL bStatus [ 3 ] = { 0 , 0 , 0 } ;
bStatus [ 0 ] = RegisterHotKey (
2014-08-25 15:35:43 +00:00
g_hFrameWindow , // HWND hWnd
VK_SNAPSHOT_560 , // int id (user/custom id)
0 , // UINT fsModifiers
VK_SNAPSHOT // UINT vk = PrintScreen
2009-01-06 22:02:31 +00:00
) ;
2018-02-27 21:07:16 +00:00
bStatus [ 1 ] = RegisterHotKey (
2014-08-25 15:35:43 +00:00
g_hFrameWindow , // HWND hWnd
2009-01-06 22:02:31 +00:00
VK_SNAPSHOT_280 , // int id (user/custom id)
2014-08-25 15:35:43 +00:00
MOD_SHIFT , // UINT fsModifiers
VK_SNAPSHOT // UINT vk = PrintScreen
) ;
2018-02-27 21:07:16 +00:00
bStatus [ 2 ] = RegisterHotKey (
2014-08-25 15:35:43 +00:00
g_hFrameWindow , // HWND hWnd
VK_SNAPSHOT_TEXT , // int id (user/custom id)
MOD_CONTROL , // UINT fsModifiers
VK_SNAPSHOT // UINT vk = PrintScreen
2009-01-06 22:02:31 +00:00
) ;
2018-02-28 21:22:40 +00:00
if ( ( ! bStatus [ 0 ] | | ! bStatus [ 1 ] | | ! bStatus [ 2 ] ) )
2009-01-06 22:02:31 +00:00
{
2018-02-27 21:07:16 +00:00
std : : string msg ( " Unable to register for PrintScreen key(s): \n " ) ;
if ( ! bStatus [ 0 ] )
msg + = " \n . PrintScreen " ;
if ( ! bStatus [ 1 ] )
msg + = " \n . Shift+PrintScreen " ;
if ( ! bStatus [ 2 ] )
msg + = " \n . Ctrl+PrintScreen " ;
2018-02-28 21:22:40 +00:00
if ( g_bShowPrintScreenWarningDialog )
MessageBox ( g_hFrameWindow , msg . c_str ( ) , " Warning " , MB_ICONASTERISK | MB_OK ) ;
2018-02-27 21:07:16 +00:00
msg + = " \n " ;
LogFileOutput ( msg . c_str ( ) ) ;
2009-01-06 22:02:31 +00:00
}
}
2018-05-28 16:27:38 +00:00
//---------------------------------------------------------------------------
static HINSTANCE g_hinstDLL = 0 ;
static HHOOK g_hhook = 0 ;
2018-07-15 20:00:01 +00:00
static HANDLE g_hHookThread = NULL ;
static DWORD g_HookThreadId = 0 ;
2018-05-28 16:27:38 +00:00
// Pre: g_hFrameWindow must be valid
2018-07-15 20:00:01 +00:00
static bool HookFilterForKeyboard ( )
2018-05-28 16:27:38 +00:00
{
g_hinstDLL = LoadLibrary ( TEXT ( " HookFilter.dll " ) ) ;
_ASSERT ( g_hFrameWindow ) ;
2018-07-29 21:34:09 +00:00
typedef void ( * RegisterHWNDProc ) ( HWND , bool , bool ) ;
2018-05-28 16:27:38 +00:00
RegisterHWNDProc RegisterHWND = ( RegisterHWNDProc ) GetProcAddress ( g_hinstDLL , " RegisterHWND " ) ;
if ( RegisterHWND )
2018-07-29 21:34:09 +00:00
RegisterHWND ( g_hFrameWindow , g_bHookAltTab , g_bHookAltGrControl ) ;
2018-05-28 16:27:38 +00:00
HOOKPROC hkprcLowLevelKeyboardProc = ( HOOKPROC ) GetProcAddress ( g_hinstDLL , " LowLevelKeyboardProc " ) ;
g_hhook = SetWindowsHookEx (
WH_KEYBOARD_LL ,
hkprcLowLevelKeyboardProc ,
g_hinstDLL ,
0 ) ;
2018-06-16 09:24:05 +00:00
if ( g_hhook ! = 0 & & g_hFrameWindow ! = 0 )
return true ;
2018-05-28 16:27:38 +00:00
2018-06-16 09:24:05 +00:00
std : : string msg ( " Failed to install hook filter for system keys " ) ;
2018-05-28 16:27:38 +00:00
2018-06-16 09:24:05 +00:00
DWORD dwErr = GetLastError ( ) ;
MessageBox ( GetDesktopWindow ( ) , msg . c_str ( ) , " Warning " , MB_ICONASTERISK | MB_OK ) ;
msg + = " \n " ;
LogFileOutput ( msg . c_str ( ) ) ;
return false ;
2018-05-28 16:27:38 +00:00
}
2018-07-15 20:00:01 +00:00
static void UnhookFilterForKeyboard ( )
2018-05-28 16:27:38 +00:00
{
UnhookWindowsHookEx ( g_hhook ) ;
FreeLibrary ( g_hinstDLL ) ;
}
2018-07-15 20:00:01 +00:00
static DWORD WINAPI HookThread ( LPVOID lpParameter )
{
if ( ! HookFilterForKeyboard ( ) )
return - 1 ;
MSG msg ;
while ( GetMessage ( & msg , NULL , 0 , 0 ) > 0 )
{
if ( msg . message = = WM_QUIT )
break ;
TranslateMessage ( & msg ) ;
DispatchMessage ( & msg ) ;
}
UnhookFilterForKeyboard ( ) ;
return 0 ;
}
static bool InitHookThread ( )
{
g_hHookThread = CreateThread ( NULL , // lpThreadAttributes
0 , // dwStackSize
( LPTHREAD_START_ROUTINE ) HookThread ,
0 , // lpParameter
0 , // dwCreationFlags : 0 = Run immediately
& g_HookThreadId ) ; // lpThreadId
if ( g_hHookThread = = NULL )
return false ;
return true ;
}
static void UninitHookThread ( )
{
if ( g_hHookThread )
{
if ( ! PostThreadMessage ( g_HookThreadId , WM_QUIT , 0 , 0 ) )
{
_ASSERT ( 0 ) ;
return ;
}
do
{
DWORD dwExitCode ;
if ( GetExitCodeThread ( g_hHookThread , & dwExitCode ) )
{
if ( dwExitCode = = STILL_ACTIVE )
Sleep ( 10 ) ;
else
break ;
}
}
while ( 1 ) ;
CloseHandle ( g_hHookThread ) ;
g_hHookThread = NULL ;
g_HookThreadId = 0 ;
}
}
2009-01-06 22:02:31 +00:00
//===========================================================================
2008-02-22 21:28:35 +00:00
LPSTR GetCurrArg ( LPSTR lpCmdLine )
{
if ( * lpCmdLine = = ' \" ' )
lpCmdLine + + ;
return lpCmdLine ;
}
2006-02-25 20:50:29 +00:00
LPSTR GetNextArg ( LPSTR lpCmdLine )
{
int bInQuotes = 0 ;
while ( * lpCmdLine )
{
if ( * lpCmdLine = = ' \" ' )
{
bInQuotes ^ = 1 ;
if ( ! bInQuotes )
{
* lpCmdLine + + = 0x00 ; // Assume end-quote is end of this arg
continue ;
}
}
if ( ( * lpCmdLine = = ' ' ) & & ! bInQuotes )
{
* lpCmdLine + + = 0x00 ;
break ;
}
lpCmdLine + + ;
}
return lpCmdLine ;
}
//---------------------------------------------------------------------------
2018-04-02 11:38:05 +00:00
static std : : string GetFullPath ( LPCSTR szFileName )
2006-02-25 20:50:29 +00:00
{
2014-08-14 19:29:01 +00:00
std : : string strPathName ;
2010-01-17 18:43:06 +00:00
if ( szFileName [ 0 ] = = ' \\ ' | | szFileName [ 1 ] = = ' : ' )
{
// Abs pathname
strPathName = szFileName ;
}
else
{
// Rel pathname
char szCWD [ _MAX_PATH ] = { 0 } ;
if ( ! GetCurrentDirectory ( sizeof ( szCWD ) , szCWD ) )
2018-04-02 11:38:05 +00:00
return " " ;
2010-01-17 18:43:06 +00:00
strPathName = szCWD ;
strPathName . append ( " \\ " ) ;
strPathName . append ( szFileName ) ;
}
2018-04-02 11:38:05 +00:00
return strPathName ;
}
static bool DoDiskInsert ( const int nDrive , LPCSTR szFileName )
{
std : : string strPathName = GetFullPath ( szFileName ) ;
if ( strPathName . empty ( ) ) return false ;
2019-04-14 16:01:49 +00:00
ImageError_e Error = sg_Disk2Card . InsertDisk ( nDrive , strPathName . c_str ( ) , IMAGE_USE_FILES_WRITE_PROTECT_STATUS , IMAGE_DONT_CREATE ) ;
2010-01-17 18:43:06 +00:00
return Error = = eIMAGE_ERROR_NONE ;
2006-02-25 20:50:29 +00:00
}
2018-04-02 11:38:05 +00:00
static bool DoHardDiskInsert ( const int nDrive , LPCSTR szFileName )
{
std : : string strPathName = GetFullPath ( szFileName ) ;
if ( strPathName . empty ( ) ) return false ;
BOOL bRes = HD_Insert ( nDrive , strPathName . c_str ( ) ) ;
return bRes ? true : false ;
}
static void InsertFloppyDisks ( LPSTR szImageName_drive [ NUM_DRIVES ] , bool & bBoot )
{
if ( ! szImageName_drive [ DRIVE_1 ] & & ! szImageName_drive [ DRIVE_2 ] )
return ;
bool bRes = true ;
if ( szImageName_drive [ DRIVE_1 ] )
{
bRes = DoDiskInsert ( DRIVE_1 , szImageName_drive [ DRIVE_1 ] ) ;
LogFileOutput ( " Init: DoDiskInsert(D1), res=%d \n " , bRes ) ;
FrameRefreshStatus ( DRAW_LEDS | DRAW_BUTTON_DRIVES ) ; // floppy activity LEDs and floppy buttons
bBoot = true ;
}
if ( szImageName_drive [ DRIVE_2 ] )
{
bRes | = DoDiskInsert ( DRIVE_2 , szImageName_drive [ DRIVE_2 ] ) ;
LogFileOutput ( " Init: DoDiskInsert(D2), res=%d \n " , bRes ) ;
}
if ( ! bRes )
MessageBox ( g_hFrameWindow , " Failed to insert floppy disk(s) - see log file " , " Warning " , MB_ICONASTERISK | MB_OK ) ;
}
static void InsertHardDisks ( LPSTR szImageName_harddisk [ NUM_HARDDISKS ] , bool & bBoot )
{
if ( ! szImageName_harddisk [ HARDDISK_1 ] & & ! szImageName_harddisk [ HARDDISK_2 ] )
return ;
// Enable the Harddisk controller card
HD_SetEnabled ( true ) ;
DWORD dwTmp ;
if ( REGLOAD ( TEXT ( REGVALUE_HDD_ENABLED ) , & dwTmp ) )
{
if ( ! dwTmp )
REGSAVE ( TEXT ( REGVALUE_HDD_ENABLED ) , 1 ) ; // Config: HDD Enabled
}
//
bool bRes = true ;
if ( szImageName_harddisk [ HARDDISK_1 ] )
{
bRes = DoHardDiskInsert ( HARDDISK_1 , szImageName_harddisk [ HARDDISK_1 ] ) ;
LogFileOutput ( " Init: DoHardDiskInsert(HDD1), res=%d \n " , bRes ) ;
FrameRefreshStatus ( DRAW_LEDS ) ; // harddisk activity LED
bBoot = true ;
}
if ( szImageName_harddisk [ HARDDISK_2 ] )
{
bRes | = DoHardDiskInsert ( HARDDISK_2 , szImageName_harddisk [ HARDDISK_2 ] ) ;
LogFileOutput ( " Init: DoHardDiskInsert(HDD2), res=%d \n " , bRes ) ;
}
if ( ! bRes )
MessageBox ( g_hFrameWindow , " Failed to insert harddisk(s) - see log file " , " Warning " , MB_ICONASTERISK | MB_OK ) ;
}
2019-01-09 21:29:36 +00:00
static bool CheckOldAppleWinVersion ( void )
{
2019-08-09 03:50:29 +00:00
TCHAR szOldAppleWinVersion [ VERSIONSTRING_SIZE + 1 ] ;
RegLoadString ( TEXT ( REG_CONFIG ) , TEXT ( REGVALUE_VERSION ) , 1 , szOldAppleWinVersion , VERSIONSTRING_SIZE , TEXT ( " " ) ) ;
2019-01-09 21:29:36 +00:00
const bool bShowAboutDlg = strcmp ( szOldAppleWinVersion , VERSIONSTRING ) ! = 0 ;
// version: xx.yy.zz.ww
char * p0 = szOldAppleWinVersion ;
2019-08-09 03:50:29 +00:00
int len = strlen ( szOldAppleWinVersion ) ;
szOldAppleWinVersion [ len ] = ' . ' ; // append a null terminator
szOldAppleWinVersion [ len + 1 ] = ' \0 ' ;
2019-01-09 21:29:36 +00:00
for ( UINT i = 0 ; i < 4 ; i + + )
{
char * p1 = strstr ( p0 , " . " ) ;
if ( ! p1 )
break ;
* p1 = 0 ;
g_OldAppleWinVersion [ i ] = atoi ( p0 ) ;
p0 = p1 + 1 ;
}
return bShowAboutDlg ;
}
2006-02-25 20:50:29 +00:00
//---------------------------------------------------------------------------
2013-03-28 22:28:42 +00:00
int APIENTRY WinMain ( HINSTANCE passinstance , HINSTANCE , LPSTR lpCmdLine , int )
2006-02-25 20:50:29 +00:00
{
2016-03-21 23:48:02 +00:00
bool bShutdown = false ;
2006-02-25 20:50:29 +00:00
bool bSetFullScreen = false ;
bool bBoot = false ;
2017-09-29 19:33:30 +00:00
bool bChangedDisplayResolution = false ;
2018-11-04 15:07:46 +00:00
bool bSlot0LanguageCard = false ;
2018-04-05 20:33:36 +00:00
bool bSlot7Empty = false ;
2017-09-29 19:33:30 +00:00
UINT bestWidth = 0 , bestHeight = 0 ;
2018-04-02 11:38:05 +00:00
LPSTR szImageName_drive [ NUM_DRIVES ] = { NULL , NULL } ;
LPSTR szImageName_harddisk [ NUM_HARDDISKS ] = { NULL , NULL } ;
2016-03-21 23:48:02 +00:00
LPSTR szSnapshotName = NULL ;
2013-03-28 22:28:42 +00:00
const std : : string strCmdLine ( lpCmdLine ) ; // Keep a copy for log ouput
2018-10-26 18:23:30 +00:00
UINT uRamWorksExPages = 0 ;
UINT uSaturnBanks = 0 ;
2019-02-24 15:59:35 +00:00
int newVideoType = - 1 ;
2019-02-24 22:00:14 +00:00
int newVideoStyleEnableMask = 0 ;
int newVideoStyleDisableMask = 0 ;
2019-06-28 20:34:34 +00:00
VideoRefreshRate_e newVideoRefreshRate = VR_NONE ;
2019-03-17 15:01:51 +00:00
LPSTR szScreenshotFilename = NULL ;
2006-02-25 20:50:29 +00:00
2013-03-28 22:28:42 +00:00
while ( * lpCmdLine )
2006-02-25 20:50:29 +00:00
{
LPSTR lpNextArg = GetNextArg ( lpCmdLine ) ;
2013-03-28 22:28:42 +00:00
if ( ( ( strcmp ( lpCmdLine , " -l " ) = = 0 ) | | ( strcmp ( lpCmdLine , " -log " ) = = 0 ) ) & & ( g_fh = = NULL ) )
{
2018-07-15 14:38:37 +00:00
LogInit ( ) ;
2013-03-28 22:28:42 +00:00
}
else if ( strcmp ( lpCmdLine , " -noreg " ) = = 0 )
2009-02-14 04:05:15 +00:00
{
g_bRegisterFileTypes = false ;
}
2013-03-28 22:28:42 +00:00
else if ( strcmp ( lpCmdLine , " -d1 " ) = = 0 )
2006-02-25 20:50:29 +00:00
{
2008-02-22 21:28:35 +00:00
lpCmdLine = GetCurrArg ( lpNextArg ) ;
lpNextArg = GetNextArg ( lpNextArg ) ;
2018-04-02 11:38:05 +00:00
szImageName_drive [ DRIVE_1 ] = lpCmdLine ;
2006-02-25 20:50:29 +00:00
}
2013-03-28 22:28:42 +00:00
else if ( strcmp ( lpCmdLine , " -d2 " ) = = 0 )
2006-02-25 20:50:29 +00:00
{
2008-02-22 21:28:35 +00:00
lpCmdLine = GetCurrArg ( lpNextArg ) ;
lpNextArg = GetNextArg ( lpNextArg ) ;
2018-04-02 11:38:05 +00:00
szImageName_drive [ DRIVE_2 ] = lpCmdLine ;
}
else if ( strcmp ( lpCmdLine , " -h1 " ) = = 0 )
{
lpCmdLine = GetCurrArg ( lpNextArg ) ;
lpNextArg = GetNextArg ( lpNextArg ) ;
szImageName_harddisk [ HARDDISK_1 ] = lpCmdLine ;
}
else if ( strcmp ( lpCmdLine , " -h2 " ) = = 0 )
{
lpCmdLine = GetCurrArg ( lpNextArg ) ;
lpNextArg = GetNextArg ( lpNextArg ) ;
szImageName_harddisk [ HARDDISK_2 ] = lpCmdLine ;
2006-02-25 20:50:29 +00:00
}
2018-04-05 20:33:36 +00:00
else if ( strcmp ( lpCmdLine , " -s7 " ) = = 0 )
{
lpCmdLine = GetCurrArg ( lpNextArg ) ;
lpNextArg = GetNextArg ( lpNextArg ) ;
if ( strcmp ( lpCmdLine , " empty " ) = = 0 )
bSlot7Empty = true ;
}
2016-03-21 23:48:02 +00:00
else if ( strcmp ( lpCmdLine , " -load-state " ) = = 0 )
{
lpCmdLine = GetCurrArg ( lpNextArg ) ;
lpNextArg = GetNextArg ( lpNextArg ) ;
szSnapshotName = lpCmdLine ;
}
2013-03-28 22:28:42 +00:00
else if ( strcmp ( lpCmdLine , " -f " ) = = 0 )
2006-02-25 20:50:29 +00:00
{
bSetFullScreen = true ;
}
2017-09-29 19:33:30 +00:00
# define CMD_FS_HEIGHT "-fs-height="
else if ( strncmp ( lpCmdLine , CMD_FS_HEIGHT , sizeof ( CMD_FS_HEIGHT ) - 1 ) = = 0 )
{
bSetFullScreen = true ; // Implied
LPSTR lpTmp = lpCmdLine + sizeof ( CMD_FS_HEIGHT ) - 1 ;
bool bRes = false ;
if ( strcmp ( lpTmp , " best " ) = = 0 )
{
bRes = GetBestDisplayResolutionForFullScreen ( bestWidth , bestHeight ) ;
}
else
{
UINT userSpecifiedHeight = atoi ( lpTmp ) ;
if ( userSpecifiedHeight )
bRes = GetBestDisplayResolutionForFullScreen ( bestWidth , bestHeight , userSpecifiedHeight ) ;
else
LogFileOutput ( " Invalid cmd-line parameter for -fs-height=x switch \n " ) ;
}
if ( bRes )
LogFileOutput ( " Best resolution for -fs-height=x switch: Width=%d, Height=%d \n " , bestWidth , bestHeight ) ;
else
LogFileOutput ( " Failed to set parameter for -fs-height=x switch \n " ) ;
}
2013-03-28 22:28:42 +00:00
else if ( strcmp ( lpCmdLine , " -no-di " ) = = 0 )
2013-03-23 14:14:48 +00:00
{
g_bDisableDirectInput = true ;
}
2013-03-28 22:28:42 +00:00
else if ( strcmp ( lpCmdLine , " -m " ) = = 0 )
2006-02-25 20:50:29 +00:00
{
g_bDisableDirectSound = true ;
}
2013-03-28 22:28:42 +00:00
else if ( strcmp ( lpCmdLine , " -no-mb " ) = = 0 )
2009-10-07 21:38:42 +00:00
{
g_bDisableDirectSoundMockingboard = true ;
}
2014-07-18 03:18:59 +00:00
else if ( strcmp ( lpCmdLine , " -memclear " ) = = 0 )
{
lpCmdLine = GetCurrArg ( lpNextArg ) ;
lpNextArg = GetNextArg ( lpNextArg ) ;
g_nMemoryClearType = atoi ( lpCmdLine ) ;
if ( g_nMemoryClearType < 0 )
g_nMemoryClearType = 0 ;
else
if ( g_nMemoryClearType > = NUM_MIP )
g_nMemoryClearType = NUM_MIP - 1 ;
}
2006-02-25 20:50:29 +00:00
# ifdef RAMWORKS
2013-03-28 22:28:42 +00:00
else if ( strcmp ( lpCmdLine , " -r " ) = = 0 ) // RamWorks size [1..127]
2006-02-25 20:50:29 +00:00
{
2008-02-22 21:28:35 +00:00
lpCmdLine = GetCurrArg ( lpNextArg ) ;
lpNextArg = GetNextArg ( lpNextArg ) ;
2018-10-26 18:23:30 +00:00
uRamWorksExPages = atoi ( lpCmdLine ) ;
if ( uRamWorksExPages > kMaxExMemoryBanks )
uRamWorksExPages = kMaxExMemoryBanks ;
2017-04-27 21:59:41 +00:00
else
2018-10-26 18:23:30 +00:00
if ( uRamWorksExPages < 1 )
uRamWorksExPages = 1 ;
2006-02-25 20:50:29 +00:00
}
2017-04-27 21:50:15 +00:00
# endif
2018-10-27 17:48:47 +00:00
else if ( strcmp ( lpCmdLine , " -s0 " ) = = 0 )
2017-04-27 21:50:15 +00:00
{
lpCmdLine = GetCurrArg ( lpNextArg ) ;
lpNextArg = GetNextArg ( lpNextArg ) ;
2018-10-27 17:48:47 +00:00
if ( strcmp ( lpCmdLine , " saturn " ) = = 0 | | strcmp ( lpCmdLine , " saturn128 " ) = = 0 )
2018-10-26 18:23:30 +00:00
uSaturnBanks = Saturn128K : : kMaxSaturnBanks ;
2018-10-27 17:48:47 +00:00
else if ( strcmp ( lpCmdLine , " saturn64 " ) = = 0 )
uSaturnBanks = Saturn128K : : kMaxSaturnBanks / 2 ;
2018-11-04 15:07:46 +00:00
else if ( strcmp ( lpCmdLine , " languagecard " ) = = 0 | | strcmp ( lpCmdLine , " lc " ) = = 0 )
bSlot0LanguageCard = true ;
2017-04-27 21:51:34 +00:00
}
2013-03-28 22:28:42 +00:00
else if ( strcmp ( lpCmdLine , " -f8rom " ) = = 0 ) // Use custom 2K ROM at [$F800..$FFFF]
2008-02-22 21:28:35 +00:00
{
lpCmdLine = GetCurrArg ( lpNextArg ) ;
lpNextArg = GetNextArg ( lpNextArg ) ;
2018-11-06 19:12:10 +00:00
if ( g_hCustomRomF8 ! = INVALID_HANDLE_VALUE ) // Stop resource leak if -f8rom is specified twice!
CloseHandle ( g_hCustomRomF8 ) ;
2008-02-22 21:28:35 +00:00
g_hCustomRomF8 = CreateFile ( lpCmdLine , GENERIC_READ , 0 , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_READONLY , NULL ) ;
if ( ( g_hCustomRomF8 = = INVALID_HANDLE_VALUE ) | | ( GetFileSize ( g_hCustomRomF8 , NULL ) ! = 0x800 ) )
g_bCustomRomF8Failed = true ;
}
2018-11-19 22:15:04 +00:00
else if ( strcmp ( lpCmdLine , " -videorom " ) = = 0 ) // Use 2K (for II/II+). Use 4K,8K or 16K video ROM (for Enhanced //e)
2018-11-17 16:29:17 +00:00
{
lpCmdLine = GetCurrArg ( lpNextArg ) ;
lpNextArg = GetNextArg ( lpNextArg ) ;
if ( ! ReadVideoRomFile ( lpCmdLine ) )
{
2018-12-08 13:29:48 +00:00
std : : string msg = " Failed to load video rom (not found or not exactly 2/4/8/16KiB) \n " ;
2018-11-17 16:29:17 +00:00
LogFileOutput ( " %s " , msg . c_str ( ) ) ;
MessageBox ( g_hFrameWindow , msg . c_str ( ) , TEXT ( " AppleWin Error " ) , MB_OK ) ;
}
else
{
SetVideoRomRockerSwitch ( true ) ; // Use PAL char set
}
}
2013-03-28 22:28:42 +00:00
else if ( strcmp ( lpCmdLine , " -printscreen " ) = = 0 ) // Turn on display of the last filename print screen was saved to
2009-01-06 22:02:31 +00:00
{
g_bDisplayPrintScreenFileName = true ;
}
2017-08-24 23:40:21 +00:00
else if ( strcmp ( lpCmdLine , " -no-printscreen-key " ) = = 0 ) // Don't try to capture PrintScreen key GH#469
2017-08-24 23:33:03 +00:00
{
g_bCapturePrintScreenKey = false ;
}
2013-12-23 03:20:54 +00:00
else if ( strcmp ( lpCmdLine , " -no-printscreen-dlg " ) = = 0 ) // Turn off the PrintScreen warning message dialog (if PrintScreen key can't be grabbed)
{
g_bShowPrintScreenWarningDialog = false ;
}
2018-06-16 09:24:05 +00:00
else if ( strcmp ( lpCmdLine , " -no-hook-system-key " ) = = 0 ) // Don't hook the System keys (eg. Left-ALT+ESC/SPACE/TAB) GH#556
{
g_bHookSystemKey = false ;
}
2018-07-29 21:34:09 +00:00
else if ( strcmp ( lpCmdLine , " -hook-alt-tab " ) = = 0 ) // GH#556
{
g_bHookAltTab = true ;
}
else if ( strcmp ( lpCmdLine , " -hook-altgr-control " ) = = 0 ) // GH#556
{
g_bHookAltGrControl = true ;
}
2019-03-03 14:32:19 +00:00
else if ( strcmp ( lpCmdLine , " -altgr-sends-wmchar " ) = = 0 ) // GH#625
{
KeybSetAltGrSendsWM_CHAR ( true ) ;
}
2018-11-10 15:55:20 +00:00
else if ( strcmp ( lpCmdLine , " -no-hook-alt " ) = = 0 ) // GH#583
{
JoySetHookAltKeys ( false ) ;
}
2013-03-28 22:28:42 +00:00
else if ( strcmp ( lpCmdLine , " -spkr-inc " ) = = 0 )
2009-10-07 21:38:42 +00:00
{
lpCmdLine = GetCurrArg ( lpNextArg ) ;
lpNextArg = GetNextArg ( lpNextArg ) ;
const int nErrorInc = atoi ( lpCmdLine ) ;
SoundCore_SetErrorInc ( nErrorInc ) ;
}
2013-03-28 22:28:42 +00:00
else if ( strcmp ( lpCmdLine , " -spkr-max " ) = = 0 )
2009-10-07 21:38:42 +00:00
{
lpCmdLine = GetCurrArg ( lpNextArg ) ;
lpNextArg = GetNextArg ( lpNextArg ) ;
const int nErrorMax = atoi ( lpCmdLine ) ;
SoundCore_SetErrorMax ( nErrorMax ) ;
}
2013-03-28 22:28:42 +00:00
else if ( strcmp ( lpCmdLine , " -use-real-printer " ) = = 0 ) // Enable control in Advanced config to allow dumping to a real printer
2009-01-17 15:10:00 +00:00
{
g_bEnableDumpToRealPrinter = true ;
}
2013-03-28 22:28:42 +00:00
else if ( strcmp ( lpCmdLine , " -speech " ) = = 0 )
2010-02-14 21:11:26 +00:00
{
g_bEnableSpeech = true ;
}
2013-03-28 22:28:42 +00:00
else if ( strcmp ( lpCmdLine , " -multimon " ) = = 0 )
2011-02-20 18:59:53 +00:00
{
g_bMultiMon = true ;
}
2018-04-22 13:37:59 +00:00
else if ( ( strcmp ( lpCmdLine , " -dcd " ) = = 0 ) | | ( strcmp ( lpCmdLine , " -modem " ) = = 0 ) ) // GH#386
2017-03-19 21:44:20 +00:00
{
2017-03-23 21:36:26 +00:00
sg_SSC . SupportDCD ( true ) ;
2017-03-19 21:44:20 +00:00
}
2018-06-10 17:14:34 +00:00
else if ( strcmp ( lpCmdLine , " -alt-enter=toggle-full-screen " ) = = 0 ) // GH#556
{
SetAltEnterToggleFullScreen ( true ) ;
}
else if ( strcmp ( lpCmdLine , " -alt-enter=open-apple-enter " ) = = 0 ) // GH#556
{
SetAltEnterToggleFullScreen ( false ) ;
}
2019-02-24 15:59:35 +00:00
else if ( strcmp ( lpCmdLine , " -video-mode=rgb-monitor " ) = = 0 ) // GH#616
{
newVideoType = VT_COLOR_MONITOR_RGB ;
}
else if ( strcmp ( lpCmdLine , " -video-style=vertical-blend " ) = = 0 ) // GH#616
{
2019-02-24 22:00:14 +00:00
newVideoStyleEnableMask = VS_COLOR_VERTICAL_BLEND ;
}
else if ( strcmp ( lpCmdLine , " -video-style=no-vertical-blend " ) = = 0 ) // GH#616
{
newVideoStyleDisableMask = VS_COLOR_VERTICAL_BLEND ;
2019-02-24 15:59:35 +00:00
}
2019-04-06 16:31:26 +00:00
else if ( strcmp ( lpCmdLine , " -rgb-card-invert-bit7 " ) = = 0 ) // GH#633
{
RGB_SetInvertBit7 ( true ) ;
}
2019-03-17 15:01:51 +00:00
else if ( strcmp ( lpCmdLine , " -screenshot-and-exit " ) = = 0 ) // GH#616: For testing - Use in combination with -load-state
{
szScreenshotFilename = GetCurrArg ( lpNextArg ) ;
lpNextArg = GetNextArg ( lpNextArg ) ;
}
2019-06-28 20:34:34 +00:00
else if ( _stricmp ( lpCmdLine , " -50hz " ) = = 0 ) // (case-insensitive)
{
newVideoRefreshRate = VR_50HZ ;
}
else if ( _stricmp ( lpCmdLine , " -60hz " ) = = 0 ) // (case-insensitive)
{
newVideoRefreshRate = VR_60HZ ;
}
2013-03-28 22:28:42 +00:00
else // unsupported
{
LogFileOutput ( " Unsupported arg: %s \n " , lpCmdLine ) ;
}
2006-02-25 20:50:29 +00:00
lpCmdLine = lpNextArg ;
}
2013-03-28 22:28:42 +00:00
LogFileOutput ( " CmdLine: %s \n " , strCmdLine . c_str ( ) ) ;
2006-02-25 20:50:29 +00:00
#if 0
# ifdef RIFF_SPKR
RiffInitWriteFile ( " Spkr.wav " , SPKR_SAMPLE_RATE , 1 ) ;
# endif
# ifdef RIFF_MB
RiffInitWriteFile ( " Mockingboard.wav " , 44100 , 2 ) ;
# endif
# endif
//-----
char szPath [ _MAX_PATH ] ;
2013-03-28 22:28:42 +00:00
if ( 0 = = GetModuleFileName ( NULL , szPath , sizeof ( szPath ) ) )
2006-02-25 20:50:29 +00:00
{
strcpy ( szPath , __argv [ 0 ] ) ;
}
// Extract application version and store in a global variable
DWORD dwHandle , dwVerInfoSize ;
dwVerInfoSize = GetFileVersionInfoSize ( szPath , & dwHandle ) ;
2013-03-28 22:28:42 +00:00
if ( dwVerInfoSize > 0 )
2006-02-25 20:50:29 +00:00
{
char * pVerInfoBlock = new char [ dwVerInfoSize ] ;
2013-03-28 22:28:42 +00:00
if ( GetFileVersionInfo ( szPath , NULL , dwVerInfoSize , pVerInfoBlock ) )
2006-02-25 20:50:29 +00:00
{
VS_FIXEDFILEINFO * pFixedFileInfo ;
UINT pFixedFileInfoLen ;
VerQueryValue ( pVerInfoBlock , TEXT ( " \\ " ) , ( LPVOID * ) & pFixedFileInfo , ( PUINT ) & pFixedFileInfoLen ) ;
// Construct version string from fixed file info block
2016-03-21 23:48:02 +00:00
unsigned long major = g_AppleWinVersion [ 0 ] = pFixedFileInfo - > dwFileVersionMS > > 16 ;
unsigned long minor = g_AppleWinVersion [ 1 ] = pFixedFileInfo - > dwFileVersionMS & 0xffff ;
unsigned long fix = g_AppleWinVersion [ 2 ] = pFixedFileInfo - > dwFileVersionLS > > 16 ;
unsigned long fix_minor = g_AppleWinVersion [ 3 ] = pFixedFileInfo - > dwFileVersionLS & 0xffff ;
2019-08-09 03:50:29 +00:00
StringCbPrintf ( VERSIONSTRING , VERSIONSTRING_SIZE , " %d.%d.%d.%d " , major , minor , fix , fix_minor ) ;
2013-08-08 21:13:31 +00:00
}
2018-08-12 11:48:08 +00:00
delete [ ] pVerInfoBlock ;
2006-02-25 20:50:29 +00:00
}
2013-03-18 23:17:18 +00:00
LogFileOutput ( " AppleWin version: %s \n " , VERSIONSTRING ) ;
2006-02-25 20:50:29 +00:00
//-----
2008-02-22 21:28:35 +00:00
// Initialize COM - so we can use CoCreateInstance
2008-05-17 23:20:33 +00:00
// . NB. DSInit() & DIMouse::DirectInputInit are done when g_hFrameWindow is created (WM_CREATE)
2013-03-18 23:17:18 +00:00
HRESULT hr = CoInitializeEx ( NULL , COINIT_APARTMENTTHREADED ) ;
LogFileOutput ( " Init: CoInitializeEx(), hr=0x%08X \n " , hr ) ;
2010-12-30 20:10:48 +00:00
2013-03-18 23:17:18 +00:00
const bool bSysClkOK = SysClk_InitTimer ( ) ;
LogFileOutput ( " Init: SysClk_InitTimer(), res=%d \n " , bSysClkOK ? 1 : 0 ) ;
2010-02-14 21:11:26 +00:00
# ifdef USE_SPEECH_API
if ( g_bEnableSpeech )
{
2013-03-18 23:17:18 +00:00
const bool bSpeechOK = g_Speech . Init ( ) ;
LogFileOutput ( " Init: SysClk_InitTimer(), res=%d \n " , bSpeechOK ? 1 : 0 ) ;
2010-02-14 21:11:26 +00:00
}
# endif
2006-02-25 20:50:29 +00:00
// DO ONE-TIME INITIALIZATION
2006-07-02 09:56:50 +00:00
g_hInstance = passinstance ;
2006-02-25 20:50:29 +00:00
GdiSetBatchLimit ( 512 ) ;
2013-03-18 23:17:18 +00:00
LogFileOutput ( " Init: GdiSetBatchLimit() \n " ) ;
2006-02-25 20:50:29 +00:00
GetProgramDirectory ( ) ;
2013-03-18 23:17:18 +00:00
LogFileOutput ( " Init: GetProgramDirectory() \n " ) ;
2013-03-28 22:28:42 +00:00
if ( g_bRegisterFileTypes )
2009-02-14 04:05:15 +00:00
{
RegisterExtensions ( ) ;
2013-03-18 23:17:18 +00:00
LogFileOutput ( " Init: RegisterExtensions() \n " ) ;
2009-02-14 04:05:15 +00:00
}
2013-03-18 23:17:18 +00:00
2006-02-25 20:50:29 +00:00
FrameRegisterClass ( ) ;
2013-03-18 23:17:18 +00:00
LogFileOutput ( " Init: FrameRegisterClass() \n " ) ;
2006-02-25 20:50:29 +00:00
ImageInitialize ( ) ;
2013-03-18 23:17:18 +00:00
LogFileOutput ( " Init: ImageInitialize() \n " ) ;
2006-02-25 20:50:29 +00:00
//
2009-05-09 14:37:08 +00:00
2006-02-25 20:50:29 +00:00
do
{
// DO INITIALIZATION THAT MUST BE REPEATED FOR A RESTART
2016-09-10 21:58:26 +00:00
g_bRestart = false ;
2013-04-26 21:55:45 +00:00
ResetToLogoMode ( ) ;
2013-03-18 23:17:18 +00:00
2019-01-09 21:29:36 +00:00
// NB. g_OldAppleWinVersion needed by LoadConfiguration() -> Config_Load_Video()
const bool bShowAboutDlg = CheckOldAppleWinVersion ( ) ; // Post: g_OldAppleWinVersion
2006-02-25 20:50:29 +00:00
LoadConfiguration ( ) ;
2013-03-28 22:28:42 +00:00
LogFileOutput ( " Main: LoadConfiguration() \n " ) ;
2013-03-18 23:17:18 +00:00
2019-02-24 15:59:35 +00:00
if ( newVideoType > = 0 )
2019-06-28 20:34:34 +00:00
{
2019-02-24 15:59:35 +00:00
SetVideoType ( ( VideoType_e ) newVideoType ) ;
2019-06-28 20:34:34 +00:00
newVideoType = - 1 ; // Don't reapply after a restart
}
2019-02-24 22:00:14 +00:00
SetVideoStyle ( ( VideoStyle_e ) ( ( GetVideoStyle ( ) | newVideoStyleEnableMask ) & ~ newVideoStyleDisableMask ) ) ;
2019-02-24 15:59:35 +00:00
2019-06-28 20:34:34 +00:00
if ( newVideoRefreshRate ! = VR_NONE )
{
SetVideoRefreshRate ( newVideoRefreshRate ) ;
newVideoRefreshRate = VR_NONE ; // Don't reapply after a restart
SetCurrentCLK6502 ( ) ;
}
2018-10-26 18:23:30 +00:00
// Apply the memory expansion switches after loading the Apple II machine type
# ifdef RAMWORKS
if ( uRamWorksExPages )
{
SetRamWorksMemorySize ( uRamWorksExPages ) ;
SetExpansionMemType ( CT_RamWorksIII ) ;
uRamWorksExPages = 0 ; // Don't reapply after a restart
}
# endif
if ( uSaturnBanks )
{
SetSaturnMemorySize ( uSaturnBanks ) ; // Set number of banks before constructing Saturn card
SetExpansionMemType ( CT_Saturn128K ) ;
uSaturnBanks = 0 ; // Don't reapply after a restart
}
2018-11-04 15:07:46 +00:00
if ( bSlot0LanguageCard )
{
SetExpansionMemType ( CT_LanguageCard ) ;
bSlot0LanguageCard = false ; // Don't reapply after a restart
}
2006-02-25 20:50:29 +00:00
DebugInitialize ( ) ;
2013-03-28 22:28:42 +00:00
LogFileOutput ( " Main: DebugInitialize() \n " ) ;
2013-03-18 23:17:18 +00:00
2006-02-25 20:50:29 +00:00
JoyInitialize ( ) ;
2013-03-28 22:28:42 +00:00
LogFileOutput ( " Main: JoyInitialize() \n " ) ;
2013-03-18 23:17:18 +00:00
2009-02-16 19:18:34 +00:00
VideoInitialize ( ) ; // g_pFramebufferinfo been created now
2013-03-28 22:28:42 +00:00
LogFileOutput ( " Main: VideoInitialize() \n " ) ;
2013-03-18 23:17:18 +00:00
2013-03-28 22:28:42 +00:00
LogFileOutput ( " Main: FrameCreateWindow() - pre \n " ) ;
2013-08-08 21:13:31 +00:00
FrameCreateWindow ( ) ; // g_hFrameWindow is now valid
2013-03-28 22:28:42 +00:00
LogFileOutput ( " Main: FrameCreateWindow() - post \n " ) ;
2013-03-18 23:17:18 +00:00
2018-04-02 11:38:05 +00:00
// Pre: may need g_hFrameWindow for MessageBox errors
// Post: may enable HDD, required for MemInitialize()->MemInitializeIO()
{
InsertFloppyDisks ( szImageName_drive , bBoot ) ;
szImageName_drive [ DRIVE_1 ] = szImageName_drive [ DRIVE_2 ] = NULL ; // Don't insert on a restart
InsertHardDisks ( szImageName_harddisk , bBoot ) ;
szImageName_harddisk [ HARDDISK_1 ] = szImageName_harddisk [ HARDDISK_2 ] = NULL ; // Don't insert on a restart
2018-04-05 20:33:36 +00:00
if ( bSlot7Empty )
HD_SetEnabled ( false ) ;
2018-04-02 11:38:05 +00:00
}
MemInitialize ( ) ;
LogFileOutput ( " Main: MemInitialize() \n " ) ;
2019-01-09 21:29:36 +00:00
// Show About dialog after creating main window (need g_hFrameWindow)
2013-08-08 21:13:31 +00:00
if ( bShowAboutDlg )
{
if ( ! AboutDlg ( ) )
2016-03-21 23:48:02 +00:00
bShutdown = true ; // Close everything down
2013-08-08 21:13:31 +00:00
else
RegSaveString ( TEXT ( REG_CONFIG ) , TEXT ( REGVALUE_VERSION ) , 1 , VERSIONSTRING ) ; // Only save version after user accepts license
}
2017-08-24 23:33:03 +00:00
if ( g_bCapturePrintScreenKey )
2018-05-28 16:27:38 +00:00
{
RegisterHotKeys ( ) ; // needs valid g_hFrameWindow
LogFileOutput ( " Main: RegisterHotKeys() \n " ) ;
}
2018-06-16 09:24:05 +00:00
if ( g_bHookSystemKey )
{
2018-07-15 20:00:01 +00:00
if ( InitHookThread ( ) ) // needs valid g_hFrameWindow (for message pump)
2018-06-16 09:24:05 +00:00
LogFileOutput ( " Main: HookFilterForKeyboard() \n " ) ;
}
2008-07-14 16:02:44 +00:00
2008-02-22 21:28:35 +00:00
// Need to test if it's safe to call ResetMachineState(). In the meantime, just call DiskReset():
2019-07-05 22:01:19 +00:00
sg_Disk2Card . Reset ( true ) ; // Switch from a booting A][+ to a non-autostart A][, so need to turn off floppy motor
2013-03-28 22:28:42 +00:00
LogFileOutput ( " Main: DiskReset() \n " ) ;
2017-12-03 21:05:05 +00:00
HD_Reset ( ) ; // GH#515
LogFileOutput ( " Main: HDDReset() \n " ) ;
2007-03-26 21:27:29 +00:00
if ( ! bSysClkOK )
{
MessageBox ( g_hFrameWindow , " DirectX failed to create SystemClock instance " , TEXT ( " AppleWin Error " ) , MB_OK ) ;
2016-03-21 23:48:02 +00:00
bShutdown = true ;
2007-03-26 21:27:29 +00:00
}
2008-02-22 21:28:35 +00:00
if ( g_bCustomRomF8Failed )
{
2018-12-08 13:29:48 +00:00
std : : string msg = " Failed to load custom F8 rom (not found or not exactly 2KiB) \n " ;
2018-11-17 16:29:17 +00:00
LogFileOutput ( " %s " , msg . c_str ( ) ) ;
MessageBox ( g_hFrameWindow , msg . c_str ( ) , TEXT ( " AppleWin Error " ) , MB_OK ) ;
2016-03-21 23:48:02 +00:00
bShutdown = true ;
2008-02-22 21:28:35 +00:00
}
2007-03-26 21:27:29 +00:00
tfe_init ( ) ;
2013-03-28 22:28:42 +00:00
LogFileOutput ( " Main: tfe_init() \n " ) ;
2016-03-21 23:48:02 +00:00
if ( szSnapshotName )
2006-02-25 20:50:29 +00:00
{
2016-04-20 21:46:12 +00:00
std : : string strPathname ( szSnapshotName ) ;
int nIdx = strPathname . find_last_of ( ' \\ ' ) ;
if ( nIdx > = 0 & & nIdx + 1 < ( int ) strPathname . length ( ) )
{
std : : string strPath = strPathname . substr ( 0 , nIdx + 1 ) ;
SetCurrentImageDir ( strPath . c_str ( ) ) ;
}
2016-03-21 23:48:02 +00:00
// Override value just loaded from Registry by LoadConfiguration()
// . NB. Registry value is not updated with this cmd-line value
Snapshot_SetFilename ( szSnapshotName ) ;
Snapshot_LoadState ( ) ;
bBoot = true ;
# if _DEBUG && 0 // Debug/test: Save a duplicate of the save-state file in tmp folder
std : : string saveName = std : : string ( " tmp \\ " ) + std : : string ( szSnapshotName ) ;
Snapshot_SetFilename ( saveName ) ;
g_bSaveStateOnExit = true ;
bShutdown = true ;
# endif
szSnapshotName = NULL ;
}
else
{
Snapshot_Startup ( ) ; // Do this after everything has been init'ed
LogFileOutput ( " Main: Snapshot_Startup() \n " ) ;
2006-02-25 20:50:29 +00:00
}
2019-03-17 15:01:51 +00:00
if ( szScreenshotFilename )
{
Video_RedrawAndTakeScreenShot ( szScreenshotFilename ) ;
bShutdown = true ;
}
2016-03-21 23:48:02 +00:00
if ( bShutdown )
{
PostMessage ( g_hFrameWindow , WM_DESTROY , 0 , 0 ) ; // Close everything down
// NB. If shutting down, then don't post any other messages (GH#286)
}
else
2006-02-25 20:50:29 +00:00
{
2016-03-21 23:48:02 +00:00
if ( bSetFullScreen )
{
2017-09-29 19:33:30 +00:00
if ( bestWidth & & bestHeight )
{
DEVMODE devMode ;
memset ( & devMode , 0 , sizeof ( devMode ) ) ;
devMode . dmSize = sizeof ( devMode ) ;
devMode . dmPelsWidth = bestWidth ;
devMode . dmPelsHeight = bestHeight ;
devMode . dmFields = DM_PELSWIDTH | DM_PELSHEIGHT ;
DWORD dwFlags = 0 ;
LONG res = ChangeDisplaySettings ( & devMode , dwFlags ) ;
if ( res = = 0 )
bChangedDisplayResolution = true ;
}
2016-03-21 23:48:02 +00:00
PostMessage ( g_hFrameWindow , WM_USER_FULLSCREEN , 0 , 0 ) ;
bSetFullScreen = false ;
}
if ( bBoot )
{
PostMessage ( g_hFrameWindow , WM_USER_BOOT , 0 , 0 ) ;
bBoot = false ;
}
2006-02-25 20:50:29 +00:00
}
// ENTER THE MAIN MESSAGE LOOP
2013-03-28 22:28:42 +00:00
LogFileOutput ( " Main: EnterMessageLoop() \n " ) ;
2006-02-25 20:50:29 +00:00
EnterMessageLoop ( ) ;
2013-03-28 22:28:42 +00:00
LogFileOutput ( " Main: LeaveMessageLoop() \n " ) ;
2007-08-06 21:38:35 +00:00
2016-09-10 21:58:26 +00:00
if ( g_bRestart )
2016-07-23 21:53:29 +00:00
{
bSetFullScreen = g_bRestartFullScreen ;
g_bRestartFullScreen = false ;
}
2006-02-25 20:50:29 +00:00
MB_Reset ( ) ;
2013-03-28 22:28:42 +00:00
LogFileOutput ( " Main: MB_Reset() \n " ) ;
2013-03-18 23:17:18 +00:00
2013-03-28 22:28:42 +00:00
sg_Mouse . Uninitialize ( ) ; // Maybe restarting due to switching slot-4 card from MouseCard to Mockingboard
2017-12-03 21:05:05 +00:00
sg_Mouse . Reset ( ) ; // Deassert any pending IRQs - GH#514
2013-03-28 22:28:42 +00:00
LogFileOutput ( " Main: sg_Mouse.Uninitialize() \n " ) ;
2017-08-10 21:10:59 +00:00
DSUninit ( ) ;
LogFileOutput ( " Main: DSUninit() \n " ) ;
2018-05-28 16:27:38 +00:00
2018-06-16 09:24:05 +00:00
if ( g_bHookSystemKey )
{
2018-07-15 20:00:01 +00:00
UninitHookThread ( ) ;
2018-06-16 09:24:05 +00:00
LogFileOutput ( " Main: UnhookFilterForKeyboard() \n " ) ;
}
2006-02-25 20:50:29 +00:00
}
2016-09-10 21:58:26 +00:00
while ( g_bRestart ) ;
2013-03-28 22:28:42 +00:00
2017-09-29 19:33:30 +00:00
if ( bChangedDisplayResolution )
ChangeDisplaySettings ( NULL , 0 ) ; // restore default
2006-02-25 20:50:29 +00:00
// Release COM
SysClk_UninitTimer ( ) ;
2013-03-18 23:17:18 +00:00
LogFileOutput ( " Exit: SysClk_UninitTimer() \n " ) ;
2006-02-25 20:50:29 +00:00
CoUninitialize ( ) ;
2013-03-18 23:17:18 +00:00
LogFileOutput ( " Exit: CoUninitialize() \n " ) ;
2013-03-28 22:28:42 +00:00
2006-03-24 06:34:37 +00:00
tfe_shutdown ( ) ;
2013-03-18 23:17:18 +00:00
LogFileOutput ( " Exit: tfe_shutdown() \n " ) ;
2013-03-28 22:28:42 +00:00
2018-07-15 14:38:37 +00:00
LogDone ( ) ;
2006-02-25 20:50:29 +00:00
RiffFinishWriteFile ( ) ;
2008-02-22 21:28:35 +00:00
if ( g_hCustomRomF8 ! = INVALID_HANDLE_VALUE )
CloseHandle ( g_hCustomRomF8 ) ;
2006-02-25 20:50:29 +00:00
return 0 ;
}