diff --git a/AppleWinExpress2008.vcproj b/AppleWinExpress2008.vcproj
index 5ea3a7ca..bd3930cc 100644
--- a/AppleWinExpress2008.vcproj
+++ b/AppleWinExpress2008.vcproj
@@ -1001,14 +1001,6 @@
RelativePath=".\source\Windows\WinFrame.h"
>
-
-
-
-
-
@@ -243,7 +242,6 @@
-
diff --git a/AppleWinExpress2019.vcxproj.filters b/AppleWinExpress2019.vcxproj.filters
index 8a06c6c0..ccb2cd1a 100644
--- a/AppleWinExpress2019.vcxproj.filters
+++ b/AppleWinExpress2019.vcxproj.filters
@@ -199,9 +199,6 @@
Source Files\Windows
-
- Source Files\Windows
-
Source Files\Windows
@@ -504,9 +501,6 @@
Source Files\Windows
-
- Source Files\Windows
-
Source Files\Windows
diff --git a/source/CmdLine.cpp b/source/CmdLine.cpp
index 29dea833..348232ee 100644
--- a/source/CmdLine.cpp
+++ b/source/CmdLine.cpp
@@ -319,7 +319,7 @@ bool ProcessCmdLine(LPSTR lpCmdLine)
}
else if (strcmp(lpCmdLine, "-printscreen") == 0) // Turn on display of the last filename print screen was saved to
{
- GetVideo().SetDisplayPrintScreenFileName(true);
+ GetFrame().SetDisplayPrintScreenFileName(true);
}
else if (strcmp(lpCmdLine, "-no-printscreen-key") == 0) // Don't try to capture PrintScreen key GH#469
{
@@ -327,7 +327,7 @@ bool ProcessCmdLine(LPSTR lpCmdLine)
}
else if (strcmp(lpCmdLine, "-no-printscreen-dlg") == 0) // Turn off the PrintScreen warning message dialog (if PrintScreen key can't be grabbed)
{
- GetVideo().SetShowPrintScreenWarningDialog(false);
+ GetFrame().SetShowPrintScreenWarningDialog(false);
}
else if (strcmp(lpCmdLine, "-no-hook-system-key") == 0) // Don't hook the System keys (eg. Left-ALT+ESC/SPACE/TAB) GH#556
{
diff --git a/source/Configuration/PageConfig.cpp b/source/Configuration/PageConfig.cpp
index 8ff37e1b..b5026ab6 100644
--- a/source/Configuration/PageConfig.cpp
+++ b/source/Configuration/PageConfig.cpp
@@ -30,7 +30,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "../Windows/WinFrame.h"
#include "../Registry.h"
#include "../SerialComms.h"
-#include "../Windows/WinVideo.h"
#include "../resource/resource.h"
CPageConfig* CPageConfig::ms_this = 0; // reinit'd in ctor
@@ -116,7 +115,7 @@ INT_PTR CPageConfig::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPA
break;
case IDC_MONOCOLOR:
- GetVideo().ChooseMonochromeColor();
+ GetFrame().ChooseMonochromeColor();
break;
case IDC_CHECK_CONFIRM_REBOOT:
@@ -318,7 +317,7 @@ void CPageConfig::DlgOK(HWND hWnd)
GetVideo().VideoReinitialize();
if ((g_nAppMode != MODE_LOGO) && (g_nAppMode != MODE_DEBUG))
{
- GetVideo().VideoRedrawScreen();
+ GetFrame().VideoRedrawScreen();
}
}
diff --git a/source/Debugger/Debug.cpp b/source/Debugger/Debug.cpp
index e27d9172..b9159a2e 100644
--- a/source/Debugger/Debug.cpp
+++ b/source/Debugger/Debug.cpp
@@ -44,7 +44,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "../Memory.h"
#include "../NTSC.h"
#include "../SoundCore.h" // SoundCore_SetFade()
-#include "../Windows/WinVideo.h"
#include "../Windows/WinFrame.h"
// #define DEBUG_COMMAND_HELP 1
@@ -754,7 +753,7 @@ Update_t CmdBenchmarkStop (int nArgs)
DebugEnd();
GetFrame().FrameRefreshStatus(DRAW_TITLE);
- GetVideo().VideoRedrawScreen();
+ GetFrame().VideoRedrawScreen();
DWORD currtime = GetTickCount();
while ((extbench = GetTickCount()) != currtime)
; // intentional busy-waiting
@@ -6896,7 +6895,7 @@ Update_t _ViewOutput( ViewVideoPage_t iPage, int bVideoModeFlags )
}
DebugVideoMode::Instance().Set(bVideoModeFlags);
- GetVideo().VideoRefreshScreen( bVideoModeFlags, true );
+ GetFrame().VideoRefreshScreen( bVideoModeFlags, true );
return UPDATE_NOTHING; // intentional
}
@@ -7447,7 +7446,7 @@ Update_t CmdWindowViewData (int nArgs)
//===========================================================================
Update_t CmdWindowViewOutput (int nArgs)
{
- GetVideo().VideoRedrawScreen();
+ GetFrame().VideoRedrawScreen();
DebugVideoMode::Instance().Set( GetVideo().GetVideoMode() );
@@ -9583,7 +9582,7 @@ void DebugDisplay( BOOL bInitDisasm/*=FALSE*/ )
{
uint32_t mode = 0;
DebugVideoMode::Instance().Get(&mode);
- GetVideo().VideoRefreshScreen(mode, true);
+ GetFrame().VideoRefreshScreen(mode, true);
return;
}
diff --git a/source/Disk.cpp b/source/Disk.cpp
index 250e8e27..ee9a7e89 100644
--- a/source/Disk.cpp
+++ b/source/Disk.cpp
@@ -351,7 +351,7 @@ void Disk2InterfaceCard::EjectDisk(const int drive)
Snapshot_UpdatePath();
SaveLastDiskImage(drive);
- GetVideo().Video_ResetScreenshotCounter("");
+ GetFrame().Video_ResetScreenshotCounter("");
}
void Disk2InterfaceCard::UnplugDrive(const int drive)
@@ -709,14 +709,14 @@ ImageError_e Disk2InterfaceCard::InsertDisk(const int drive, LPCTSTR pszImageFil
GetImageTitle(pszImageFilename, pFloppy->m_imagename, pFloppy->m_fullname);
Snapshot_UpdatePath();
- GetVideo().Video_ResetScreenshotCounter(pFloppy->m_imagename);
+ GetFrame().Video_ResetScreenshotCounter(pFloppy->m_imagename);
if (g_nAppMode == MODE_LOGO)
InitFirmware(GetCxRomPeripheral());
}
else
{
- GetVideo().Video_ResetScreenshotCounter("");
+ GetFrame().Video_ResetScreenshotCounter("");
}
SaveLastDiskImage(drive);
diff --git a/source/FrameBase.cpp b/source/FrameBase.cpp
index 1c4722be..ea41ea20 100644
--- a/source/FrameBase.cpp
+++ b/source/FrameBase.cpp
@@ -1,6 +1,9 @@
#include "StdAfx.h"
#include "FrameBase.h"
+#include "Interface.h"
+#include "Core.h"
+#include "NTSC.h"
FrameBase::FrameBase()
{
@@ -9,9 +12,135 @@ FrameBase::FrameBase()
g_bMultiMon = 0; // OFF = load window position & clamp initial frame to screen, ON = use window position as is
g_bFreshReset = false;
g_hInstance = (HINSTANCE)0;
+ g_bDisplayPrintScreenFileName = false;
+ g_bShowPrintScreenWarningDialog = true;
}
FrameBase::~FrameBase()
{
}
+
+void FrameBase::VideoRefreshScreen(uint32_t uRedrawWholeScreenVideoMode, bool bRedrawWholeScreen)
+{
+ // regenerate video buffer if needed
+ GetVideo().VideoRefreshBuffer(uRedrawWholeScreenVideoMode, bRedrawWholeScreen);
+
+ // actually draw it on screen
+ VideoPresentScreen();
+}
+
+void FrameBase::VideoRedrawScreen(void)
+{
+ // NB. Can't rely on g_uVideoMode being non-zero (ie. so it can double up as a flag) since 'GR,PAGE1,non-mixed' mode == 0x00.
+ VideoRefreshScreen(GetVideo().GetVideoMode(), true);
+}
+
+//===========================================================================
+void FrameBase::VideoRedrawScreenDuringFullSpeed(DWORD dwCyclesThisFrame, bool bInit /*=false*/)
+{
+ if (bInit)
+ {
+ // Just entered full-speed mode
+ dwFullSpeedStartTime = GetTickCount();
+ return;
+ }
+
+ DWORD dwFullSpeedDuration = GetTickCount() - dwFullSpeedStartTime;
+ if (dwFullSpeedDuration <= 16) // Only update after every realtime ~17ms of *continuous* full-speed
+ return;
+
+ dwFullSpeedStartTime += dwFullSpeedDuration;
+
+ VideoRedrawScreenAfterFullSpeed(dwCyclesThisFrame);
+}
+
+void FrameBase::VideoRedrawScreenAfterFullSpeed(DWORD dwCyclesThisFrame)
+{
+ NTSC_VideoClockResync(dwCyclesThisFrame);
+ VideoRedrawScreen(); // Better (no flicker) than using: NTSC_VideoReinitialize() or VideoReinitialize()
+}
+
+void FrameBase::Video_RedrawAndTakeScreenShot(const char* pScreenshotFilename)
+{
+ _ASSERT(pScreenshotFilename);
+ if (!pScreenshotFilename)
+ return;
+
+ VideoRedrawScreen();
+ Video_SaveScreenShot(Video::SCREENSHOT_560x384, pScreenshotFilename);
+}
+
+void FrameBase::Video_TakeScreenShot(const Video::VideoScreenShot_e ScreenShotType)
+{
+ TCHAR sScreenShotFileName[MAX_PATH];
+
+ // find last screenshot filename so we don't overwrite the existing user ones
+ bool bExists = true;
+ while (bExists)
+ {
+ if (g_nLastScreenShot > nMaxScreenShot) // Holy Crap! User has maxed the number of screenshots!?
+ {
+ TCHAR msg[512];
+ StringCbPrintf(msg, 512, "You have more then %d screenshot filenames! They will no longer be saved.\n\nEither move some of your screenshots or increase the maximum in video.cpp\n", nMaxScreenShot);
+ MessageBox(GetFrame().g_hFrameWindow, msg, "Warning", MB_OK);
+ g_nLastScreenShot = 0;
+ return;
+ }
+
+ Util_MakeScreenShotFileName(sScreenShotFileName, MAX_PATH);
+ bExists = Util_TestScreenShotFileName(sScreenShotFileName);
+ if (!bExists)
+ {
+ break;
+ }
+ g_nLastScreenShot++;
+ }
+
+ Video_SaveScreenShot(ScreenShotType, sScreenShotFileName);
+ g_nLastScreenShot++;
+}
+
+//===========================================================================
+
+void FrameBase::Video_SaveScreenShot(const Video::VideoScreenShot_e ScreenShotType, const TCHAR* pScreenShotFileName)
+{
+ FILE* pFile = fopen(pScreenShotFileName, "wb");
+ if (pFile)
+ {
+ GetVideo().Video_MakeScreenShot(pFile, ScreenShotType);
+ fclose(pFile);
+ }
+
+ if (g_bDisplayPrintScreenFileName)
+ {
+ MessageBox(GetFrame().g_hFrameWindow, pScreenShotFileName, "Screen Captured", MB_OK);
+ }
+}
+
+void FrameBase::Util_MakeScreenShotFileName(TCHAR* pFinalFileName_, DWORD chars)
+{
+ const std::string sPrefixScreenShotFileName = "AppleWin_ScreenShot";
+ // TODO: g_sScreenshotDir
+ const std::string pPrefixFileName = !g_pLastDiskImageName.empty() ? g_pLastDiskImageName : sPrefixScreenShotFileName;
+ StringCbPrintf(pFinalFileName_, chars, TEXT("%s_%09d.bmp"), pPrefixFileName.c_str(), g_nLastScreenShot);
+}
+
+// Returns TRUE if file exists, else FALSE
+bool FrameBase::Util_TestScreenShotFileName(const TCHAR* pFileName)
+{
+ bool bFileExists = false;
+ FILE* pFile = fopen(pFileName, "rt");
+ if (pFile)
+ {
+ fclose(pFile);
+ bFileExists = true;
+ }
+ return bFileExists;
+}
+
+void FrameBase::Video_ResetScreenshotCounter(const std::string& pImageName)
+{
+ g_nLastScreenShot = 0;
+ g_pLastDiskImageName = pImageName;
+}
diff --git a/source/FrameBase.h b/source/FrameBase.h
index 8f123642..315999e4 100644
--- a/source/FrameBase.h
+++ b/source/FrameBase.h
@@ -1,5 +1,7 @@
#pragma once
+#include "Video.h"
+
class FrameBase
{
public:
@@ -13,6 +15,9 @@ public:
BOOL g_bMultiMon;
bool g_bFreshReset;
+ virtual void Initialize(void) = 0;
+ virtual void Destroy(void) = 0;
+
virtual void FrameDrawDiskLEDS(HDC hdc) = 0;
virtual void FrameDrawDiskStatus(HDC hdc) = 0;
virtual void FrameRefreshStatus(int, bool bUpdateDiskStatus = true) = 0;
@@ -25,4 +30,36 @@ public:
virtual void SetAltEnterToggleFullScreen(bool mode) = 0;
virtual void SetLoadedSaveStateFlag(const bool bFlag) = 0;
+
+ virtual void VideoPresentScreen(void) = 0;
+ virtual void ChooseMonochromeColor(void) = 0;
+ virtual void Benchmark(void) = 0;
+ virtual void DisplayLogo(void) = 0;
+
+ void VideoRefreshScreen(uint32_t uRedrawWholeScreenVideoMode, bool bRedrawWholeScreen);
+ void VideoRedrawScreen(void);
+ void VideoRedrawScreenDuringFullSpeed(DWORD dwCyclesThisFrame, bool bInit = false);
+ void VideoRedrawScreenAfterFullSpeed(DWORD dwCyclesThisFrame);
+ void Video_RedrawAndTakeScreenShot(const char* pScreenshotFilename);
+
+ void Video_TakeScreenShot(const Video::VideoScreenShot_e ScreenShotType);
+ void Video_SaveScreenShot(const Video::VideoScreenShot_e ScreenShotType, const TCHAR* pScreenShotFileName);
+ void SetDisplayPrintScreenFileName(bool state) { g_bDisplayPrintScreenFileName = state; }
+ void Video_ResetScreenshotCounter(const std::string& pDiskImageFileName);
+
+ bool GetShowPrintScreenWarningDialog(void) { return g_bShowPrintScreenWarningDialog; }
+ void SetShowPrintScreenWarningDialog(bool state) { g_bShowPrintScreenWarningDialog = state; }
+
+private:
+ void Util_MakeScreenShotFileName(TCHAR* pFinalFileName_, DWORD chars);
+ bool Util_TestScreenShotFileName(const TCHAR* pFileName);
+
+ bool g_bShowPrintScreenWarningDialog;
+
+ DWORD dwFullSpeedStartTime;
+ bool g_bDisplayPrintScreenFileName;
+
+ int g_nLastScreenShot;
+ std::string g_pLastDiskImageName;
+ static const int nMaxScreenShot = 999999999;
};
diff --git a/source/Keyboard.cpp b/source/Keyboard.cpp
index e6eb34b6..6d43aa8a 100644
--- a/source/Keyboard.cpp
+++ b/source/Keyboard.cpp
@@ -36,7 +36,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "Pravets.h"
#include "Tape.h"
#include "YamlHelper.h"
-#include "Windows/WinVideo.h" // Needed by TK3000 //e, to refresh the frame at each |Mode| change
#include "Log.h"
static BYTE asciicode[2][10] = {
@@ -303,7 +302,7 @@ void KeybQueueKeypress (WPARAM key, Keystroke_e bASCII)
{
g_bTK3KModeKey = (GetKeyState(VK_SCROLL) & 1) ? true : false; // Sync with the Scroll Lock status
GetFrame().FrameRefreshStatus(DRAW_LEDS); // TODO: Implement |Mode| LED in the UI; make it appear only when in TK3000 mode
- GetVideo().VideoRedrawScreen(); // TODO: Still need to implement page mode switching and 'whatnot'
+ GetFrame().VideoRedrawScreen(); // TODO: Still need to implement page mode switching and 'whatnot'
}
return;
}
diff --git a/source/NTSC.cpp b/source/NTSC.cpp
index e4c7c55e..45bafa9f 100644
--- a/source/NTSC.cpp
+++ b/source/NTSC.cpp
@@ -101,10 +101,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define VIDEO_SCANNER_Y_MIXED 160 // num scanlins for mixed graphics + text
#define VIDEO_SCANNER_Y_DISPLAY 192 // max displayable scanlines
- static bgra_t *g_pVideoAddress = 0;
+ // these are initialized in NTSC_VideoInit
+ static bgra_t* g_pVideoAddress = 0;
static bgra_t *g_pScanLines[VIDEO_SCANNER_Y_DISPLAY*2]; // To maintain the 280x192 aspect ratio for 560px width, we double every scan line -> 560x384
-
- static const UINT g_kFrameBufferWidth = GetVideo().GetFrameBufferWidth();
+ static UINT g_kFrameBufferWidth;
static unsigned short (*g_pHorzClockOffset)[VIDEO_SCANNER_MAX_HORZ] = 0;
@@ -2090,6 +2090,8 @@ void NTSC_Destroy(void)
// After a VM restart, this will point to an old FrameBuffer
// - if it's now unmapped then this can cause a crash in NTSC_SetVideoMode()!
g_pVideoAddress = 0;
+ g_kFrameBufferWidth = 0;
+ memset(g_pScanLines, 0, sizeof(g_pScanLines));
}
void NTSC_VideoInit( uint8_t* pFramebuffer ) // wsVideoInit
@@ -2100,6 +2102,8 @@ void NTSC_VideoInit( uint8_t* pFramebuffer ) // wsVideoInit
initChromaPhaseTables();
updateMonochromeTables( 0xFF, 0xFF, 0xFF );
+ g_kFrameBufferWidth = GetVideo().GetFrameBufferWidth();
+
for (int y = 0; y < (VIDEO_SCANNER_Y_DISPLAY*2); y++)
{
uint32_t offset = sizeof(bgra_t) * GetVideo().GetFrameBufferWidth()
diff --git a/source/Speaker.cpp b/source/Speaker.cpp
index 7db89dbd..ef68e96e 100644
--- a/source/Speaker.cpp
+++ b/source/Speaker.cpp
@@ -97,7 +97,7 @@ static void Spkr_DSUninit();
static void DisplayBenchmarkResults ()
{
DWORD totaltime = GetTickCount()-extbench;
- GetVideo().VideoRedrawScreen();
+ GetFrame().VideoRedrawScreen();
TCHAR buffer[64];
wsprintf(buffer,
TEXT("This benchmark took %u.%02u seconds."),
diff --git a/source/Video.cpp b/source/Video.cpp
index 18dcc16f..7b47c426 100644
--- a/source/Video.cpp
+++ b/source/Video.cpp
@@ -31,7 +31,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "Video.h"
#include "Core.h"
#include "CPU.h"
-#include "Interface.h"
#include "Log.h"
#include "Memory.h"
#include "Registry.h"
@@ -437,65 +436,6 @@ bool Video::VideoGetVblBar(const DWORD uExecutedCycles)
//===========================================================================
-void Video::Video_ResetScreenshotCounter(const std::string& pImageName)
-{
- g_nLastScreenShot = 0;
- g_pLastDiskImageName = pImageName;
-}
-
-void Video::Util_MakeScreenShotFileName(TCHAR *pFinalFileName_, DWORD chars)
-{
- const std::string sPrefixScreenShotFileName = "AppleWin_ScreenShot";
- // TODO: g_sScreenshotDir
- const std::string pPrefixFileName = !g_pLastDiskImageName.empty() ? g_pLastDiskImageName : sPrefixScreenShotFileName;
- StringCbPrintf( pFinalFileName_, chars, TEXT("%s_%09d.bmp"), pPrefixFileName.c_str(), g_nLastScreenShot );
-}
-
-// Returns TRUE if file exists, else FALSE
-bool Video::Util_TestScreenShotFileName(const TCHAR *pFileName)
-{
- bool bFileExists = false;
- FILE *pFile = fopen( pFileName, "rt" );
- if (pFile)
- {
- fclose( pFile );
- bFileExists = true;
- }
- return bFileExists;
-}
-
-//===========================================================================
-
-void Video::Video_TakeScreenShot(const VideoScreenShot_e ScreenShotType)
-{
- TCHAR sScreenShotFileName[ MAX_PATH ];
-
- // find last screenshot filename so we don't overwrite the existing user ones
- bool bExists = true;
- while( bExists )
- {
- if (g_nLastScreenShot > nMaxScreenShot) // Holy Crap! User has maxed the number of screenshots!?
- {
- TCHAR msg[512];
- StringCbPrintf( msg, 512, "You have more then %d screenshot filenames! They will no longer be saved.\n\nEither move some of your screenshots or increase the maximum in video.cpp\n", nMaxScreenShot );
- MessageBox( GetFrame().g_hFrameWindow, msg, "Warning", MB_OK );
- g_nLastScreenShot = 0;
- return;
- }
-
- Util_MakeScreenShotFileName(sScreenShotFileName, MAX_PATH);
- bExists = Util_TestScreenShotFileName(sScreenShotFileName);
- if( !bExists )
- {
- break;
- }
- g_nLastScreenShot++;
- }
-
- Video_SaveScreenShot(ScreenShotType, sScreenShotFileName);
- g_nLastScreenShot++;
-}
-
void Video::Video_SetBitmapHeader(WinBmpHeader_t *pBmp, int nWidth, int nHeight, int nBitsPerPixel)
{
pBmp->nCookie[ 0 ] = 'B'; // 0x42
@@ -603,23 +543,6 @@ void Video::Video_MakeScreenShot(FILE *pFile, const VideoScreenShot_e ScreenShot
//===========================================================================
-void Video::Video_SaveScreenShot(const VideoScreenShot_e ScreenShotType, const TCHAR *pScreenShotFileName)
-{
- FILE *pFile = fopen( pScreenShotFileName, "wb" );
- if( pFile )
- {
- Video_MakeScreenShot( pFile, ScreenShotType );
- fclose( pFile );
- }
-
- if( g_bDisplayPrintScreenFileName )
- {
- MessageBox( GetFrame().g_hFrameWindow, pScreenShotFileName, "Screen Captured", MB_OK );
- }
-}
-
-//===========================================================================
-
bool Video::ReadVideoRomFile(const char* pRomFile)
{
g_videoRomSize = 0;
@@ -831,41 +754,32 @@ const char* Video::VideoGetAppWindowTitle(void)
return apVideoMonitorModeDesc[ GetVideoRefreshRate() == VR_60HZ ? 0 : 1 ]; // NTSC or PAL
}
-void Video::VideoRedrawScreenDuringFullSpeed(DWORD dwCyclesThisFrame, bool bInit /*=false*/)
+
+void Video::Initialize(uint8_t* frameBuffer)
{
- if (bInit)
- {
- // Just entered full-speed mode
- dwFullSpeedStartTime = GetTickCount();
- return;
- }
+ SetFrameBuffer(frameBuffer);
- DWORD dwFullSpeedDuration = GetTickCount() - dwFullSpeedStartTime;
- if (dwFullSpeedDuration <= 16) // Only update after every realtime ~17ms of *continuous* full-speed
- return;
+ // RESET THE VIDEO MODE SWITCHES AND THE CHARACTER SET OFFSET
+ VideoResetState();
- dwFullSpeedStartTime += dwFullSpeedDuration;
+ // DRAW THE SOURCE IMAGE INTO THE SOURCE BIT BUFFER
+ memset(GetFrameBuffer(), 0, GetFrameBufferWidth() * GetFrameBufferHeight() * sizeof(bgra_t));
- VideoRedrawScreenAfterFullSpeed(dwCyclesThisFrame);
+ // CREATE THE OFFSET TABLE FOR EACH SCAN LINE IN THE FRAME BUFFER
+ NTSC_VideoInit(GetFrameBuffer());
+
+#if 0
+ DDInit(); // For WaitForVerticalBlank()
+#endif
}
-void Video::VideoRedrawScreenAfterFullSpeed(DWORD dwCyclesThisFrame)
+void Video::Destroy(void)
{
- NTSC_VideoClockResync(dwCyclesThisFrame);
- VideoRedrawScreen(); // Better (no flicker) than using: NTSC_VideoReinitialize() or VideoReinitialize()
+ SetFrameBuffer(NULL);
+ NTSC_Destroy();
}
-void Video::Video_RedrawAndTakeScreenShot(const char* pScreenshotFilename)
-{
- _ASSERT(pScreenshotFilename);
- if (!pScreenshotFilename)
- return;
-
- VideoRedrawScreen();
- Video_SaveScreenShot(SCREENSHOT_560x384, pScreenshotFilename);
-}
-
-void Video::VideoRefreshScreen(uint32_t uRedrawWholeScreenVideoMode, bool bRedrawWholeScreen)
+void Video::VideoRefreshBuffer(uint32_t uRedrawWholeScreenVideoMode, bool bRedrawWholeScreen)
{
if (bRedrawWholeScreen || g_nAppMode == MODE_PAUSED)
{
@@ -881,12 +795,4 @@ void Video::VideoRefreshScreen(uint32_t uRedrawWholeScreenVideoMode, bool bRedra
if (g_nAppMode == MODE_DEBUG || g_nAppMode == MODE_PAUSED)
NTSC_VideoRedrawWholeScreen();
}
-
- VideoPresentScreen();
-}
-
-void Video::VideoRedrawScreen(void)
-{
- // NB. Can't rely on g_uVideoMode being non-zero (ie. so it can double up as a flag) since 'GR,PAGE1,non-mixed' mode == 0x00.
- VideoRefreshScreen(GetVideoMode(), true);
}
diff --git a/source/Video.h b/source/Video.h
index 51b1fa4c..72bef838 100644
--- a/source/Video.h
+++ b/source/Video.h
@@ -191,38 +191,14 @@ public:
g_eVideoStyle = VS_HALF_SCANLINES;
g_bVideoScannerNTSC = true;
g_nMonochromeRGB = RGB(0xC0,0xC0,0xC0);
- g_bDisplayPrintScreenFileName = false;
- g_bShowPrintScreenWarningDialog = true;
- g_nLastScreenShot = 0;
g_videoRomSize = 0;
g_videoRomRockerSwitch = false;
}
- virtual ~Video(void)
- {
- }
-
- virtual void Initialize(void)
- {
- }
-
- virtual void Destroy(void)
- {
- }
-
- virtual void VideoPresentScreen(void) = 0;
- virtual void ChooseMonochromeColor(void) = 0;
- virtual void Benchmark(void) = 0;
- virtual void DisplayLogo(void) = 0;
-
- void VideoRefreshScreen(uint32_t uRedrawWholeScreenVideoMode, bool bRedrawWholeScreen);
- void VideoRedrawScreenDuringFullSpeed(DWORD dwCyclesThisFrame, bool bInit = false);
- void VideoRedrawScreenAfterFullSpeed(DWORD dwCyclesThisFrame);
- void Video_RedrawAndTakeScreenShot(const char* pScreenshotFilename);
- void VideoRedrawScreen(void);
+ void Initialize(uint8_t* frameBuffer); // Do not call directly. Call FrameBase::Initialize()
+ void Destroy(void); // Call FrameBase::Destroy()
uint8_t* GetFrameBuffer(void) { return g_pFramebufferbits; }
- void SetFrameBuffer(uint8_t* frameBuffer) { g_pFramebufferbits = frameBuffer; }
// size of the video buffer stored in g_pFramebufferbits
UINT GetFrameBufferBorderlessWidth(void);
@@ -237,6 +213,7 @@ public:
void VideoReinitialize(bool bInitVideoScannerAddress = true);
void VideoResetState(void);
+ void VideoRefreshBuffer(uint32_t uRedrawWholeScreenVideoMode, bool bRedrawWholeScreen);
enum VideoScanner_e {VS_FullAddr, VS_PartialAddrV, VS_PartialAddrH};
WORD VideoGetScannerAddress(DWORD nCycles, VideoScanner_e videoScannerAddr = VS_FullAddr);
@@ -255,19 +232,14 @@ public:
void VideoSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
void VideoLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT version);
- void Video_ResetScreenshotCounter(const std::string & pDiskImageFileName);
enum VideoScreenShot_e
{
SCREENSHOT_560x384 = 0,
SCREENSHOT_280x192
};
- void Video_TakeScreenShot(VideoScreenShot_e ScreenShotType);
void Video_SetBitmapHeader(WinBmpHeader_t *pBmp, int nWidth, int nHeight, int nBitsPerPixel);
- void Video_SaveScreenShot(const VideoScreenShot_e ScreenShotType, const TCHAR* pScreenShotFileName);
- void SetDisplayPrintScreenFileName(bool state) { g_bDisplayPrintScreenFileName = state; }
- bool GetShowPrintScreenWarningDialog(void) { return g_bShowPrintScreenWarningDialog; }
- void SetShowPrintScreenWarningDialog(bool state) { g_bShowPrintScreenWarningDialog = state; }
+ void Video_MakeScreenShot(FILE* pFile, const VideoScreenShot_e ScreenShotType);
BYTE VideoSetMode(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG uExecutedCycles);
@@ -303,10 +275,8 @@ protected:
uint8_t *g_pFramebufferbits;
private:
- void Util_MakeScreenShotFileName(TCHAR *pFinalFileName_, DWORD chars);
- bool Util_TestScreenShotFileName(const TCHAR *pFileName);
- void Video_MakeScreenShot(FILE *pFile, const VideoScreenShot_e ScreenShotType);
+ void SetFrameBuffer(uint8_t* frameBuffer) { g_pFramebufferbits = frameBuffer; }
std::string VideoGetSnapshotStructName(void);
int g_nAltCharSetOffset;
@@ -318,13 +288,6 @@ private:
WinBmpHeader_t g_tBmpHeader;
- bool g_bDisplayPrintScreenFileName;
- bool g_bShowPrintScreenWarningDialog;
-
- int g_nLastScreenShot;
- static const int nMaxScreenShot = 999999999;
- std::string g_pLastDiskImageName;
-
static const int kVDisplayableScanLines = 192; // max displayable scanlines
static const UINT kVideoRomSize8K = kVideoRomSize4K*2;
@@ -334,8 +297,6 @@ private:
UINT g_videoRomSize;
bool g_videoRomRockerSwitch;
- DWORD dwFullSpeedStartTime;
-
static const char g_aVideoChoices[];
static const char m_szModeDesc0[];
diff --git a/source/Windows/AppleWin.cpp b/source/Windows/AppleWin.cpp
index 70cd5efb..f20a6d6e 100644
--- a/source/Windows/AppleWin.cpp
+++ b/source/Windows/AppleWin.cpp
@@ -46,7 +46,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#ifdef USE_SPEECH_API
#include "Speech.h"
#endif
-#include "Windows/WinVideo.h"
#include "Windows/Win32Frame.h"
#include "Windows/WinFrame.h"
#include "RGBMonitor.h"
@@ -172,7 +171,7 @@ static void ContinueExecution(void)
if (g_bFullSpeed)
{
if (!bWasFullSpeed)
- GetVideo().VideoRedrawScreenDuringFullSpeed(0, true); // Init for full-speed mode
+ GetFrame().VideoRedrawScreenDuringFullSpeed(0, true); // Init for full-speed mode
// Don't call Spkr_Mute() - will get speaker clicks
MB_Mute();
@@ -190,7 +189,7 @@ static void ContinueExecution(void)
else
{
if (bWasFullSpeed)
- GetVideo().VideoRedrawScreenAfterFullSpeed(g_dwCyclesThisFrame);
+ GetFrame().VideoRedrawScreenAfterFullSpeed(g_dwCyclesThisFrame);
// Don't call Spkr_Demute()
MB_Demute();
@@ -251,9 +250,9 @@ static void ContinueExecution(void)
g_dwCyclesThisFrame -= dwClksPerFrame;
if (g_bFullSpeed)
- GetVideo().VideoRedrawScreenDuringFullSpeed(g_dwCyclesThisFrame);
+ GetFrame().VideoRedrawScreenDuringFullSpeed(g_dwCyclesThisFrame);
else
- GetVideo().VideoPresentScreen(); // Just copy the output of our Apple framebuffer to the system Back Buffer
+ GetFrame().VideoPresentScreen(); // Just copy the output of our Apple framebuffer to the system Back Buffer
}
#ifdef LOG_PERF_TIMINGS
@@ -482,7 +481,7 @@ static void RegisterHotKeys(void)
if (!bStatus[2])
msg += "\n. Ctrl+PrintScreen";
- if (GetVideo().GetShowPrintScreenWarningDialog())
+ if (GetFrame().GetShowPrintScreenWarningDialog())
SHMessageBoxCheck( GetFrame().g_hFrameWindow, msg.c_str(), "Warning", MB_ICONASTERISK | MB_OK, MB_OK, "AppleWin-75097740-8e59-444c-bc94-2d4915132599" );
msg += "\n";
@@ -840,7 +839,7 @@ static void RepeatInitialization(void)
JoyInitialize();
LogFileOutput("Main: JoyInitialize()\n");
- GetVideo().Initialize(); // g_pFramebufferinfo been created now & COM init'ed
+ GetFrame().Initialize(); // g_pFramebufferinfo been created now & COM init'ed
LogFileOutput("Main: VideoInitialize()\n");
LogFileOutput("Main: FrameCreateWindow() - pre\n");
@@ -975,7 +974,7 @@ static void RepeatInitialization(void)
if (g_cmdLine.szScreenshotFilename)
{
- GetVideo().Video_RedrawAndTakeScreenShot(g_cmdLine.szScreenshotFilename);
+ GetFrame().Video_RedrawAndTakeScreenShot(g_cmdLine.szScreenshotFilename);
g_cmdLine.bShutdown = true;
}
@@ -1058,6 +1057,6 @@ FrameBase& GetFrame(void)
Video& GetVideo(void)
{
- static WinVideo video;
+ static Video video;
return video;
}
diff --git a/source/Windows/Win32Frame.cpp b/source/Windows/Win32Frame.cpp
index 0545b7af..bb7a8893 100644
--- a/source/Windows/Win32Frame.cpp
+++ b/source/Windows/Win32Frame.cpp
@@ -1,6 +1,501 @@
#include "StdAfx.h"
#include "Windows/Win32Frame.h"
+#include "Windows/WinFrame.h"
+#include "Interface.h"
+#include "Core.h"
+#include "CPU.h"
+#include "Joystick.h"
+#include "Log.h"
+#include "Memory.h"
+#include "CardManager.h"
+#include "../resource/resource.h"
// Win32Frame methods are implemented in AppleWin, WinFrame and WinVideo.
// in time they should be brought together and more freestanding functions added to Win32Frame.
+
+Win32Frame::Win32Frame()
+{
+ g_pFramebufferinfo = NULL;
+ num_draw_devices = 0;
+ g_lpDD = NULL;
+ g_hLogoBitmap = (HBITMAP)0;
+ g_hDeviceBitmap = (HBITMAP)0;
+ g_hDeviceDC = (HDC)0;
+}
+
+void Win32Frame::videoCreateDIBSection(Video & video)
+{
+ // CREATE THE DEVICE CONTEXT
+ HWND window = GetDesktopWindow();
+ HDC dc = GetDC(window);
+ if (g_hDeviceDC)
+ {
+ DeleteDC(g_hDeviceDC);
+ }
+ g_hDeviceDC = CreateCompatibleDC(dc);
+
+ // CREATE THE FRAME BUFFER DIB SECTION
+ if (g_hDeviceBitmap)
+ DeleteObject(g_hDeviceBitmap);
+
+ uint8_t* pFramebufferbits;
+
+ g_hDeviceBitmap = CreateDIBSection(
+ dc,
+ g_pFramebufferinfo,
+ DIB_RGB_COLORS,
+ (LPVOID*)&pFramebufferbits, 0, 0
+ );
+ SelectObject(g_hDeviceDC, g_hDeviceBitmap);
+ video.Initialize(pFramebufferbits);
+}
+
+void Win32Frame::Initialize(void)
+{
+ // LOAD THE LOGO
+ g_hLogoBitmap = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_APPLEWIN));
+
+ // CREATE A BITMAPINFO STRUCTURE FOR THE FRAME BUFFER
+ g_pFramebufferinfo = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
+
+ Video & video = GetVideo();
+
+ memset(g_pFramebufferinfo, 0, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
+ g_pFramebufferinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ g_pFramebufferinfo->bmiHeader.biWidth = video.GetFrameBufferWidth();
+ g_pFramebufferinfo->bmiHeader.biHeight = video.GetFrameBufferHeight();
+ g_pFramebufferinfo->bmiHeader.biPlanes = 1;
+ g_pFramebufferinfo->bmiHeader.biBitCount = 32;
+ g_pFramebufferinfo->bmiHeader.biCompression = BI_RGB;
+ g_pFramebufferinfo->bmiHeader.biClrUsed = 0;
+
+ videoCreateDIBSection(video);
+
+#if 0
+ DDInit(); // For WaitForVerticalBlank()
+#endif
+}
+
+void Win32Frame::Destroy(void)
+{
+ // DESTROY BUFFERS
+ delete[] g_pFramebufferinfo;
+ g_pFramebufferinfo = NULL;
+
+ // DESTROY FRAME BUFFER
+ DeleteDC(g_hDeviceDC);
+ g_hDeviceDC = (HDC)0;
+
+ DeleteObject(g_hDeviceBitmap); // this invalidates the Video's FrameBuffer pointer
+ GetVideo().Destroy(); // this resets the Video's FrameBuffer pointer
+ g_hDeviceBitmap = (HBITMAP)0;
+
+ // DESTROY LOGO
+ if (g_hLogoBitmap) {
+ DeleteObject(g_hLogoBitmap);
+ g_hLogoBitmap = (HBITMAP)0;
+ }
+
+ DDUninit();
+}
+
+//===========================================================================
+void Win32Frame::Benchmark(void)
+{
+ _ASSERT(g_nAppMode == MODE_BENCHMARK);
+ Sleep(500);
+ Video& video = GetVideo();
+
+ // PREPARE TWO DIFFERENT FRAME BUFFERS, EACH OF WHICH HAVE HALF OF THE
+ // BYTES SET TO 0x14 AND THE OTHER HALF SET TO 0xAA
+ int loop;
+ LPDWORD mem32 = (LPDWORD)mem;
+ for (loop = 4096; loop < 6144; loop++)
+ *(mem32 + loop) = ((loop & 1) ^ ((loop & 0x40) >> 6)) ? 0x14141414
+ : 0xAAAAAAAA;
+ for (loop = 6144; loop < 8192; loop++)
+ *(mem32 + loop) = ((loop & 1) ^ ((loop & 0x40) >> 6)) ? 0xAAAAAAAA
+ : 0x14141414;
+
+ // SEE HOW MANY TEXT FRAMES PER SECOND WE CAN PRODUCE WITH NOTHING ELSE
+ // GOING ON, CHANGING HALF OF THE BYTES IN THE VIDEO BUFFER EACH FRAME TO
+ // SIMULATE THE ACTIVITY OF AN AVERAGE GAME
+ DWORD totaltextfps = 0;
+
+ video.SetVideoMode(VF_TEXT);
+ memset(mem + 0x400, 0x14, 0x400);
+ VideoRedrawScreen();
+ DWORD milliseconds = GetTickCount();
+ while (GetTickCount() == milliseconds);
+ milliseconds = GetTickCount();
+ DWORD cycle = 0;
+ do {
+ if (cycle & 1)
+ memset(mem + 0x400, 0x14, 0x400);
+ else
+ memcpy(mem + 0x400, mem + ((cycle & 2) ? 0x4000 : 0x6000), 0x400);
+ VideoPresentScreen();
+ if (cycle++ >= 3)
+ cycle = 0;
+ totaltextfps++;
+ } while (GetTickCount() - milliseconds < 1000);
+
+ // SEE HOW MANY HIRES FRAMES PER SECOND WE CAN PRODUCE WITH NOTHING ELSE
+ // GOING ON, CHANGING HALF OF THE BYTES IN THE VIDEO BUFFER EACH FRAME TO
+ // SIMULATE THE ACTIVITY OF AN AVERAGE GAME
+ DWORD totalhiresfps = 0;
+ video.SetVideoMode(VF_HIRES);
+ memset(mem + 0x2000, 0x14, 0x2000);
+ VideoRedrawScreen();
+ milliseconds = GetTickCount();
+ while (GetTickCount() == milliseconds);
+ milliseconds = GetTickCount();
+ cycle = 0;
+ do {
+ if (cycle & 1)
+ memset(mem + 0x2000, 0x14, 0x2000);
+ else
+ memcpy(mem + 0x2000, mem + ((cycle & 2) ? 0x4000 : 0x6000), 0x2000);
+ VideoPresentScreen();
+ if (cycle++ >= 3)
+ cycle = 0;
+ totalhiresfps++;
+ } while (GetTickCount() - milliseconds < 1000);
+
+ // DETERMINE HOW MANY 65C02 CLOCK CYCLES WE CAN EMULATE PER SECOND WITH
+ // NOTHING ELSE GOING ON
+ DWORD totalmhz10[2] = { 0,0 }; // bVideoUpdate & !bVideoUpdate
+ for (UINT i = 0; i < 2; i++)
+ {
+ CpuSetupBenchmark();
+ milliseconds = GetTickCount();
+ while (GetTickCount() == milliseconds);
+ milliseconds = GetTickCount();
+ do {
+ CpuExecute(100000, i == 0 ? true : false);
+ totalmhz10[i]++;
+ } while (GetTickCount() - milliseconds < 1000);
+ }
+
+ // IF THE PROGRAM COUNTER IS NOT IN THE EXPECTED RANGE AT THE END OF THE
+ // CPU BENCHMARK, REPORT AN ERROR AND OPTIONALLY TRACK IT DOWN
+ if ((regs.pc < 0x300) || (regs.pc > 0x400))
+ if (MessageBox(g_hFrameWindow,
+ TEXT("The emulator has detected a problem while running ")
+ TEXT("the CPU benchmark. Would you like to gather more ")
+ TEXT("information?"),
+ TEXT("Benchmarks"),
+ MB_ICONQUESTION | MB_YESNO | MB_SETFOREGROUND) == IDYES) {
+ BOOL error = 0;
+ WORD lastpc = 0x300;
+ int loop = 0;
+ while ((loop < 10000) && !error) {
+ CpuSetupBenchmark();
+ CpuExecute(loop, true);
+ if ((regs.pc < 0x300) || (regs.pc > 0x400))
+ error = 1;
+ else {
+ lastpc = regs.pc;
+ ++loop;
+ }
+ }
+ if (error) {
+ TCHAR outstr[256];
+ wsprintf(outstr,
+ TEXT("The emulator experienced an error %u clock cycles ")
+ TEXT("into the CPU benchmark. Prior to the error, the ")
+ TEXT("program counter was at $%04X. After the error, it ")
+ TEXT("had jumped to $%04X."),
+ (unsigned)loop,
+ (unsigned)lastpc,
+ (unsigned)regs.pc);
+ MessageBox(g_hFrameWindow,
+ outstr,
+ TEXT("Benchmarks"),
+ MB_ICONINFORMATION | MB_SETFOREGROUND);
+ }
+ else
+ MessageBox(g_hFrameWindow,
+ TEXT("The emulator was unable to locate the exact ")
+ TEXT("point of the error. This probably means that ")
+ TEXT("the problem is external to the emulator, ")
+ TEXT("happening asynchronously, such as a problem in ")
+ TEXT("a timer interrupt handler."),
+ TEXT("Benchmarks"),
+ MB_ICONINFORMATION | MB_SETFOREGROUND);
+ }
+
+ // DO A REALISTIC TEST OF HOW MANY FRAMES PER SECOND WE CAN PRODUCE
+ // WITH FULL EMULATION OF THE CPU, JOYSTICK, AND DISK HAPPENING AT
+ // THE SAME TIME
+ DWORD realisticfps = 0;
+ memset(mem + 0x2000, 0xAA, 0x2000);
+ VideoRedrawScreen();
+ milliseconds = GetTickCount();
+ while (GetTickCount() == milliseconds);
+ milliseconds = GetTickCount();
+ cycle = 0;
+ do {
+ if (realisticfps < 10) {
+ int cycles = 100000;
+ while (cycles > 0) {
+ DWORD executedcycles = CpuExecute(103, true);
+ cycles -= executedcycles;
+ GetCardMgr().GetDisk2CardMgr().UpdateDriveState(executedcycles);
+ JoyUpdateButtonLatch(executedcycles);
+ }
+ }
+ if (cycle & 1)
+ memset(mem + 0x2000, 0xAA, 0x2000);
+ else
+ memcpy(mem + 0x2000, mem + ((cycle & 2) ? 0x4000 : 0x6000), 0x2000);
+ VideoRedrawScreen();
+ if (cycle++ >= 3)
+ cycle = 0;
+ realisticfps++;
+ } while (GetTickCount() - milliseconds < 1000);
+
+ // DISPLAY THE RESULTS
+ DisplayLogo();
+ TCHAR outstr[256];
+ wsprintf(outstr,
+ TEXT("Pure Video FPS:\t%u hires, %u text\n")
+ TEXT("Pure CPU MHz:\t%u.%u%s (video update)\n")
+ TEXT("Pure CPU MHz:\t%u.%u%s (full-speed)\n\n")
+ TEXT("EXPECTED AVERAGE VIDEO GAME\n")
+ TEXT("PERFORMANCE: %u FPS"),
+ (unsigned)totalhiresfps,
+ (unsigned)totaltextfps,
+ (unsigned)(totalmhz10[0] / 10), (unsigned)(totalmhz10[0] % 10), (LPCTSTR)(IS_APPLE2 ? TEXT(" (6502)") : TEXT("")),
+ (unsigned)(totalmhz10[1] / 10), (unsigned)(totalmhz10[1] % 10), (LPCTSTR)(IS_APPLE2 ? TEXT(" (6502)") : TEXT("")),
+ (unsigned)realisticfps);
+ MessageBox(g_hFrameWindow,
+ outstr,
+ TEXT("Benchmarks"),
+ MB_ICONINFORMATION | MB_SETFOREGROUND);
+}
+
+//===========================================================================
+
+// This is called from PageConfig
+void Win32Frame::ChooseMonochromeColor(void)
+{
+ Video& video = GetVideo();
+ CHOOSECOLOR cc;
+ memset(&cc, 0, sizeof(CHOOSECOLOR));
+ cc.lStructSize = sizeof(CHOOSECOLOR);
+ cc.hwndOwner = g_hFrameWindow;
+ cc.rgbResult = video.GetMonochromeRGB();
+ cc.lpCustColors = customcolors + 1;
+ cc.Flags = CC_RGBINIT | CC_SOLIDCOLOR;
+ if (ChooseColor(&cc))
+ {
+ video.SetMonochromeRGB(cc.rgbResult);
+ video.VideoReinitialize();
+ if ((g_nAppMode != MODE_LOGO) && (g_nAppMode != MODE_DEBUG))
+ {
+ VideoRedrawScreen();
+ }
+ video.Config_Save_Video();
+ }
+}
+
+//===========================================================================
+
+void Win32Frame::VideoDrawLogoBitmap(HDC hDstDC, int xoff, int yoff, int srcw, int srch, int scale)
+{
+ HDC hSrcDC = CreateCompatibleDC(hDstDC);
+ SelectObject(hSrcDC, g_hLogoBitmap);
+ StretchBlt(
+ hDstDC, // hdcDest
+ xoff, yoff, // nXDest, nYDest
+ scale * srcw, scale * srch, // nWidth, nHeight
+ hSrcDC, // hdcSrc
+ 0, 0, // nXSrc, nYSrc
+ srcw, srch,
+ SRCCOPY // dwRop
+ );
+
+ DeleteObject(hSrcDC);
+}
+
+//===========================================================================
+
+void Win32Frame::DisplayLogo(void)
+{
+ Video& video = GetVideo();
+ int nLogoX = 0, nLogoY = 0;
+ int scale = GetViewportScale();
+
+ HDC hFrameDC = FrameGetDC();
+
+ // DRAW THE LOGO
+ SelectObject(hFrameDC, GetStockObject(NULL_PEN));
+
+ if (g_hLogoBitmap)
+ {
+ BITMAP bm;
+ if (GetObject(g_hLogoBitmap, sizeof(bm), &bm))
+ {
+ nLogoX = (g_nViewportCX - scale * bm.bmWidth) / 2;
+ nLogoY = (g_nViewportCY - scale * bm.bmHeight) / 2;
+
+ if (IsFullScreen())
+ {
+ nLogoX += GetFullScreenOffsetX();
+ nLogoY += GetFullScreenOffsetY();
+ }
+
+ VideoDrawLogoBitmap(hFrameDC, nLogoX, nLogoY, bm.bmWidth, bm.bmHeight, scale);
+ }
+ }
+
+ // DRAW THE VERSION NUMBER
+ TCHAR sFontName[] = TEXT("Arial");
+ HFONT font = CreateFont(-20, 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET,
+ OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
+ VARIABLE_PITCH | 4 | FF_SWISS,
+ sFontName);
+ SelectObject(hFrameDC, font);
+ SetTextAlign(hFrameDC, TA_RIGHT | TA_TOP);
+ SetBkMode(hFrameDC, TRANSPARENT);
+
+ TCHAR szVersion[64];
+ StringCbPrintf(szVersion, 64, "Version %s", VERSIONSTRING);
+ int xoff = GetFullScreenOffsetX(), yoff = GetFullScreenOffsetY();
+
+#define DRAWVERSION(x,y,c) \
+ SetTextColor(hFrameDC,c); \
+ TextOut(hFrameDC, \
+ scale*540+x+xoff,scale*358+y+yoff, \
+ szVersion, \
+ strlen(szVersion));
+
+ if (GetDeviceCaps(hFrameDC, PLANES) * GetDeviceCaps(hFrameDC, BITSPIXEL) <= 4) {
+ DRAWVERSION(2, 2, RGB(0x00, 0x00, 0x00));
+ DRAWVERSION(1, 1, RGB(0x00, 0x00, 0x00));
+ DRAWVERSION(0, 0, RGB(0xFF, 0x00, 0xFF));
+ }
+ else {
+ DRAWVERSION(1, 1, PALETTERGB(0x30, 0x30, 0x70));
+ DRAWVERSION(-1, -1, PALETTERGB(0xC0, 0x70, 0xE0));
+ DRAWVERSION(0, 0, PALETTERGB(0x70, 0x30, 0xE0));
+ }
+
+#if _DEBUG
+ StringCbPrintf(szVersion, 64, "DEBUG");
+ DRAWVERSION(2, -358 * scale, RGB(0x00, 0x00, 0x00));
+ DRAWVERSION(1, -357 * scale, RGB(0x00, 0x00, 0x00));
+ DRAWVERSION(0, -356 * scale, RGB(0xFF, 0x00, 0xFF));
+#endif
+
+#undef DRAWVERSION
+
+ DeleteObject(font);
+}
+
+//===========================================================================
+
+void Win32Frame::VideoPresentScreen(void)
+{
+ HDC hFrameDC = FrameGetDC();
+
+ if (hFrameDC)
+ {
+ Video& video = GetVideo();
+ int xSrc = video.GetFrameBufferBorderWidth();
+ int ySrc = video.GetFrameBufferBorderHeight();
+
+ int xdest = IsFullScreen() ? GetFullScreenOffsetX() : 0;
+ int ydest = IsFullScreen() ? GetFullScreenOffsetY() : 0;
+ int wdest = g_nViewportCX;
+ int hdest = g_nViewportCY;
+
+ SetStretchBltMode(hFrameDC, COLORONCOLOR);
+ StretchBlt(
+ hFrameDC,
+ xdest, ydest,
+ wdest, hdest,
+ g_hDeviceDC,
+ xSrc, ySrc,
+ video.GetFrameBufferBorderlessWidth(), video.GetFrameBufferBorderlessHeight(),
+ SRCCOPY);
+ }
+
+#ifdef NO_DIRECT_X
+#else
+ //if (g_lpDD) g_lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL);
+#endif // NO_DIRECT_X
+
+ GdiFlush();
+}
+
+//===========================================================================
+
+BOOL CALLBACK Win32Frame::DDEnumProc(LPGUID lpGUID, LPCTSTR lpszDesc, LPCTSTR lpszDrvName, LPVOID lpContext)
+{
+ Win32Frame* obj = (Win32Frame*)lpContext;
+
+ int i = obj->num_draw_devices;
+ if (i == MAX_DRAW_DEVICES)
+ return TRUE;
+ if (lpGUID != NULL)
+ memcpy(&(obj->draw_device_guid[i]), lpGUID, sizeof(GUID));
+ obj->draw_devices[i] = _strdup(lpszDesc);
+
+ if (g_fh) fprintf(g_fh, "%d: %s - %s\n", i, lpszDesc, lpszDrvName);
+
+ (obj->num_draw_devices)++;
+ return TRUE;
+}
+
+bool Win32Frame::DDInit(void)
+{
+#ifdef NO_DIRECT_X
+
+ return false;
+
+#else
+ HRESULT hr = DirectDrawEnumerate((LPDDENUMCALLBACK)DDEnumProc, this);
+ if (FAILED(hr))
+ {
+ LogFileOutput("DSEnumerate failed (%08X)\n", hr);
+ return false;
+ }
+
+ LogFileOutput("Number of draw devices = %d\n", num_draw_devices);
+
+ bool bCreatedOK = false;
+ for (int x = 0; x < num_draw_devices; x++)
+ {
+ hr = DirectDrawCreate(&draw_device_guid[x], &g_lpDD, NULL);
+ if (SUCCEEDED(hr))
+ {
+ LogFileOutput("DSCreate succeeded for draw device #%d\n", x);
+ bCreatedOK = true;
+ break;
+ }
+
+ LogFileOutput("DSCreate failed for draw device #%d (%08X)\n", x, hr);
+ }
+
+ if (!bCreatedOK)
+ {
+ LogFileOutput("DSCreate failed for all draw devices\n");
+ return false;
+ }
+
+ return true;
+#endif // NO_DIRECT_X
+}
+
+// From SoundCore.h
+#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
+
+void Win32Frame::DDUninit(void)
+{
+ SAFE_RELEASE(g_lpDD);
+}
+
+#undef SAFE_RELEASE
diff --git a/source/Windows/Win32Frame.h b/source/Windows/Win32Frame.h
index c7002aa8..e095474b 100644
--- a/source/Windows/Win32Frame.h
+++ b/source/Windows/Win32Frame.h
@@ -2,9 +2,13 @@
#include "FrameBase.h"
+class Video;
+
class Win32Frame : public FrameBase
{
public:
+ Win32Frame();
+
virtual void FrameDrawDiskLEDS(HDC hdc);
virtual void FrameDrawDiskStatus(HDC hdc);
virtual void FrameRefreshStatus(int, bool bUpdateDiskStatus = true);
@@ -17,4 +21,29 @@ public:
virtual void SetAltEnterToggleFullScreen(bool mode);
virtual void SetLoadedSaveStateFlag(const bool bFlag);
+
+ virtual void Initialize(void);
+ virtual void Destroy(void);
+ virtual void VideoPresentScreen(void);
+ virtual void ChooseMonochromeColor(void);
+ virtual void Benchmark(void);
+ virtual void DisplayLogo(void);
+private:
+ void videoCreateDIBSection(Video& video);
+ void VideoDrawLogoBitmap(HDC hDstDC, int xoff, int yoff, int srcw, int srch, int scale);
+ static BOOL CALLBACK DDEnumProc(LPGUID lpGUID, LPCTSTR lpszDesc, LPCTSTR lpszDrvName, LPVOID lpContext);
+ bool DDInit(void);
+ void DDUninit(void);
+
+ COLORREF customcolors[256]; // MONOCHROME is last custom color
+ HBITMAP g_hLogoBitmap;
+ HBITMAP g_hDeviceBitmap;
+ HDC g_hDeviceDC;
+ LPBITMAPINFO g_pFramebufferinfo;
+
+ static const UINT MAX_DRAW_DEVICES = 10;
+ char* draw_devices[MAX_DRAW_DEVICES];
+ GUID draw_device_guid[MAX_DRAW_DEVICES];
+ int num_draw_devices;
+ LPDIRECTDRAW g_lpDD;
};
diff --git a/source/Windows/WinFrame.cpp b/source/Windows/WinFrame.cpp
index 98c0a1c6..bb613f55 100644
--- a/source/Windows/WinFrame.cpp
+++ b/source/Windows/WinFrame.cpp
@@ -46,7 +46,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "SoundCore.h"
#include "Speaker.h"
#include "Utilities.h"
-#include "Windows/WinVideo.h"
#include "../resource/resource.h"
#include "Configuration/PropertySheet.h"
#include "Debugger/Debug.h"
@@ -585,11 +584,11 @@ static void DrawFrameWindow (bool bPaintingWindow/*=false*/)
// DRAW THE CONTENTS OF THE EMULATED SCREEN
if (g_nAppMode == MODE_LOGO)
- GetVideo().DisplayLogo();
+ GetFrame().DisplayLogo();
else if (g_nAppMode == MODE_DEBUG)
DebugDisplay();
else
- GetVideo().VideoRedrawScreen();
+ GetFrame().VideoRedrawScreen();
if (bPaintingWindow)
EndPaint(GetFrame().g_hFrameWindow,&ps);
@@ -1064,7 +1063,7 @@ LRESULT CALLBACK FrameWndProc (
CpuDestroy();
MemDestroy();
SpkrDestroy();
- GetVideo().Destroy();
+ GetFrame().Destroy();
MB_Destroy();
DeleteGdiObjects();
DIMouse::DirectInputUninit(window); // NB. do before window is destroyed
@@ -1186,12 +1185,12 @@ LRESULT CALLBACK FrameWndProc (
// lparam = modifiers: shift, ctrl, alt, win
if (wparam == VK_SNAPSHOT_560)
{
- GetVideo().Video_TakeScreenShot( Video::SCREENSHOT_560x384 );
+ GetFrame().Video_TakeScreenShot( Video::SCREENSHOT_560x384 );
}
else
if (wparam == VK_SNAPSHOT_280) // ( lparam & MOD_SHIFT )
{
- GetVideo().Video_TakeScreenShot( Video::SCREENSHOT_280x192 );
+ GetFrame().Video_TakeScreenShot( Video::SCREENSHOT_280x192 );
}
else
if (wparam == VK_SNAPSHOT_TEXT) // ( lparam & MOD_CONTROL )
@@ -1254,13 +1253,13 @@ LRESULT CALLBACK FrameWndProc (
{
UINT debugVideoMode;
if ( DebugGetVideoMode(&debugVideoMode) )
- GetVideo().VideoRefreshScreen(debugVideoMode, true);
+ GetFrame().VideoRefreshScreen(debugVideoMode, true);
else
- GetVideo().VideoPresentScreen();
+ GetFrame().VideoPresentScreen();
}
else
{
- GetVideo().VideoPresentScreen();
+ GetFrame().VideoPresentScreen();
}
}
@@ -1322,7 +1321,7 @@ LRESULT CALLBACK FrameWndProc (
}
DrawStatusArea((HDC)0,DRAW_TITLE);
if ((g_nAppMode != MODE_LOGO) && (g_nAppMode != MODE_DEBUG))
- GetVideo().VideoRedrawScreen();
+ GetFrame().VideoRedrawScreen();
}
else if ((wparam == VK_SCROLL) && GetPropertySheet().GetScrollLockToggle())
{
@@ -1809,7 +1808,7 @@ LRESULT CALLBACK FrameWndProc (
DrawStatusArea((HDC)0,DRAW_TITLE);
HCURSOR oldcursor = SetCursor(LoadCursor(0,IDC_WAIT));
g_nAppMode = MODE_BENCHMARK;
- GetVideo().Benchmark();
+ GetFrame().Benchmark();
g_nAppMode = MODE_LOGO;
ResetMachineState();
SetCursor(oldcursor);
@@ -2005,7 +2004,7 @@ static void ProcessButtonClick(int button, bool bFromButtonUI /*=false*/)
}
DrawStatusArea((HDC)0,DRAW_TITLE);
- GetVideo().VideoRedrawScreen();
+ GetFrame().VideoRedrawScreen();
break;
case BTN_DRIVE1:
diff --git a/source/Windows/WinVideo.cpp b/source/Windows/WinVideo.cpp
deleted file mode 100644
index 2d919068..00000000
--- a/source/Windows/WinVideo.cpp
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
-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
-Copyright (C) 2006-2010, Tom Charlesworth, Michael Pohoreski, Nick Westgate
-
-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: Emulation of video modes
- *
- * Author: Various
- */
-
-#include "StdAfx.h"
-
-#include "Windows/WinVideo.h"
-#include "Windows/WinFrame.h"
-#include "Windows/AppleWin.h"
-#include "Interface.h"
-#include "Core.h"
-#include "CPU.h"
-#include "Joystick.h"
-#include "Log.h"
-#include "Memory.h"
-#include "CardManager.h"
-#include "NTSC.h"
-
-#include "../resource/resource.h"
-
-void WinVideo::videoCreateDIBSection(void)
-{
- // CREATE THE DEVICE CONTEXT
- HWND window = GetDesktopWindow();
- HDC dc = GetDC(window);
- if (g_hDeviceDC)
- {
- DeleteDC(g_hDeviceDC);
- }
- g_hDeviceDC = CreateCompatibleDC(dc);
-
- // CREATE THE FRAME BUFFER DIB SECTION
- if (g_hDeviceBitmap)
- DeleteObject(g_hDeviceBitmap);
-
- g_hDeviceBitmap = CreateDIBSection(
- dc,
- g_pFramebufferinfo,
- DIB_RGB_COLORS,
- (LPVOID*)&g_pFramebufferbits, 0, 0
- );
- SelectObject(g_hDeviceDC, g_hDeviceBitmap);
-
- // DRAW THE SOURCE IMAGE INTO THE SOURCE BIT BUFFER
- memset(GetFrameBuffer(), 0, GetFrameBufferWidth() * GetFrameBufferHeight() * sizeof(bgra_t));
-
- // CREATE THE OFFSET TABLE FOR EACH SCAN LINE IN THE FRAME BUFFER
- NTSC_VideoInit(GetFrameBuffer());
-}
-
-void WinVideo::Initialize(void)
-{
- Video::Initialize();
-
- // RESET THE VIDEO MODE SWITCHES AND THE CHARACTER SET OFFSET
- VideoResetState();
-
- // LOAD THE LOGO
- g_hLogoBitmap = LoadBitmap(GetFrame().g_hInstance, MAKEINTRESOURCE(IDB_APPLEWIN));
-
- // CREATE A BITMAPINFO STRUCTURE FOR THE FRAME BUFFER
- g_pFramebufferinfo = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
-
- memset(g_pFramebufferinfo, 0, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
- g_pFramebufferinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- g_pFramebufferinfo->bmiHeader.biWidth = GetFrameBufferWidth();
- g_pFramebufferinfo->bmiHeader.biHeight = GetFrameBufferHeight();
- g_pFramebufferinfo->bmiHeader.biPlanes = 1;
- g_pFramebufferinfo->bmiHeader.biBitCount = 32;
- g_pFramebufferinfo->bmiHeader.biCompression = BI_RGB;
- g_pFramebufferinfo->bmiHeader.biClrUsed = 0;
-
- videoCreateDIBSection();
-
-#if 0
- DDInit(); // For WaitForVerticalBlank()
-#endif
-}
-
-void WinVideo::Destroy(void)
-{
- // DESTROY BUFFERS
- delete [] g_pFramebufferinfo;
- g_pFramebufferinfo = NULL;
-
- // DESTROY FRAME BUFFER
- DeleteDC(g_hDeviceDC);
- DeleteObject(g_hDeviceBitmap);
- g_hDeviceDC = (HDC)0;
- g_hDeviceBitmap = (HBITMAP)0;
- SetFrameBuffer(NULL);
-
- // DESTROY LOGO
- if (g_hLogoBitmap) {
- DeleteObject(g_hLogoBitmap);
- g_hLogoBitmap = (HBITMAP)0;
- }
-
- NTSC_Destroy();
-
- DDUninit();
-
- Video::Destroy();
-}
-
-//===========================================================================
-void WinVideo::Benchmark(void)
-{
- _ASSERT(g_nAppMode == MODE_BENCHMARK);
- Sleep(500);
-
- // PREPARE TWO DIFFERENT FRAME BUFFERS, EACH OF WHICH HAVE HALF OF THE
- // BYTES SET TO 0x14 AND THE OTHER HALF SET TO 0xAA
- int loop;
- LPDWORD mem32 = (LPDWORD)mem;
- for (loop = 4096; loop < 6144; loop++)
- *(mem32+loop) = ((loop & 1) ^ ((loop & 0x40) >> 6)) ? 0x14141414
- : 0xAAAAAAAA;
- for (loop = 6144; loop < 8192; loop++)
- *(mem32+loop) = ((loop & 1) ^ ((loop & 0x40) >> 6)) ? 0xAAAAAAAA
- : 0x14141414;
-
- // SEE HOW MANY TEXT FRAMES PER SECOND WE CAN PRODUCE WITH NOTHING ELSE
- // GOING ON, CHANGING HALF OF THE BYTES IN THE VIDEO BUFFER EACH FRAME TO
- // SIMULATE THE ACTIVITY OF AN AVERAGE GAME
- DWORD totaltextfps = 0;
-
- SetVideoMode(VF_TEXT);
- memset(mem+0x400,0x14,0x400);
- VideoRedrawScreen();
- DWORD milliseconds = GetTickCount();
- while (GetTickCount() == milliseconds) ;
- milliseconds = GetTickCount();
- DWORD cycle = 0;
- do {
- if (cycle & 1)
- memset(mem+0x400,0x14,0x400);
- else
- memcpy(mem+0x400,mem+((cycle & 2) ? 0x4000 : 0x6000),0x400);
- VideoPresentScreen();
- if (cycle++ >= 3)
- cycle = 0;
- totaltextfps++;
- } while (GetTickCount() - milliseconds < 1000);
-
- // SEE HOW MANY HIRES FRAMES PER SECOND WE CAN PRODUCE WITH NOTHING ELSE
- // GOING ON, CHANGING HALF OF THE BYTES IN THE VIDEO BUFFER EACH FRAME TO
- // SIMULATE THE ACTIVITY OF AN AVERAGE GAME
- DWORD totalhiresfps = 0;
- SetVideoMode(VF_HIRES);
- memset(mem+0x2000,0x14,0x2000);
- VideoRedrawScreen();
- milliseconds = GetTickCount();
- while (GetTickCount() == milliseconds) ;
- milliseconds = GetTickCount();
- cycle = 0;
- do {
- if (cycle & 1)
- memset(mem+0x2000,0x14,0x2000);
- else
- memcpy(mem+0x2000,mem+((cycle & 2) ? 0x4000 : 0x6000),0x2000);
- VideoPresentScreen();
- if (cycle++ >= 3)
- cycle = 0;
- totalhiresfps++;
- } while (GetTickCount() - milliseconds < 1000);
-
- // DETERMINE HOW MANY 65C02 CLOCK CYCLES WE CAN EMULATE PER SECOND WITH
- // NOTHING ELSE GOING ON
- DWORD totalmhz10[2] = {0,0}; // bVideoUpdate & !bVideoUpdate
- for (UINT i=0; i<2; i++)
- {
- CpuSetupBenchmark();
- milliseconds = GetTickCount();
- while (GetTickCount() == milliseconds) ;
- milliseconds = GetTickCount();
- do {
- CpuExecute(100000, i==0 ? true : false);
- totalmhz10[i]++;
- } while (GetTickCount() - milliseconds < 1000);
- }
-
- // IF THE PROGRAM COUNTER IS NOT IN THE EXPECTED RANGE AT THE END OF THE
- // CPU BENCHMARK, REPORT AN ERROR AND OPTIONALLY TRACK IT DOWN
- if ((regs.pc < 0x300) || (regs.pc > 0x400))
- if (MessageBox(GetFrame().g_hFrameWindow,
- TEXT("The emulator has detected a problem while running ")
- TEXT("the CPU benchmark. Would you like to gather more ")
- TEXT("information?"),
- TEXT("Benchmarks"),
- MB_ICONQUESTION | MB_YESNO | MB_SETFOREGROUND) == IDYES) {
- BOOL error = 0;
- WORD lastpc = 0x300;
- int loop = 0;
- while ((loop < 10000) && !error) {
- CpuSetupBenchmark();
- CpuExecute(loop, true);
- if ((regs.pc < 0x300) || (regs.pc > 0x400))
- error = 1;
- else {
- lastpc = regs.pc;
- ++loop;
- }
- }
- if (error) {
- TCHAR outstr[256];
- wsprintf(outstr,
- TEXT("The emulator experienced an error %u clock cycles ")
- TEXT("into the CPU benchmark. Prior to the error, the ")
- TEXT("program counter was at $%04X. After the error, it ")
- TEXT("had jumped to $%04X."),
- (unsigned)loop,
- (unsigned)lastpc,
- (unsigned)regs.pc);
- MessageBox(GetFrame().g_hFrameWindow,
- outstr,
- TEXT("Benchmarks"),
- MB_ICONINFORMATION | MB_SETFOREGROUND);
- }
- else
- MessageBox(GetFrame().g_hFrameWindow,
- TEXT("The emulator was unable to locate the exact ")
- TEXT("point of the error. This probably means that ")
- TEXT("the problem is external to the emulator, ")
- TEXT("happening asynchronously, such as a problem in ")
- TEXT("a timer interrupt handler."),
- TEXT("Benchmarks"),
- MB_ICONINFORMATION | MB_SETFOREGROUND);
- }
-
- // DO A REALISTIC TEST OF HOW MANY FRAMES PER SECOND WE CAN PRODUCE
- // WITH FULL EMULATION OF THE CPU, JOYSTICK, AND DISK HAPPENING AT
- // THE SAME TIME
- DWORD realisticfps = 0;
- memset(mem+0x2000,0xAA,0x2000);
- VideoRedrawScreen();
- milliseconds = GetTickCount();
- while (GetTickCount() == milliseconds) ;
- milliseconds = GetTickCount();
- cycle = 0;
- do {
- if (realisticfps < 10) {
- int cycles = 100000;
- while (cycles > 0) {
- DWORD executedcycles = CpuExecute(103, true);
- cycles -= executedcycles;
- GetCardMgr().GetDisk2CardMgr().UpdateDriveState(executedcycles);
- JoyUpdateButtonLatch(executedcycles);
- }
- }
- if (cycle & 1)
- memset(mem+0x2000,0xAA,0x2000);
- else
- memcpy(mem+0x2000,mem+((cycle & 2) ? 0x4000 : 0x6000),0x2000);
- VideoRedrawScreen();
- if (cycle++ >= 3)
- cycle = 0;
- realisticfps++;
- } while (GetTickCount() - milliseconds < 1000);
-
- // DISPLAY THE RESULTS
- DisplayLogo();
- TCHAR outstr[256];
- wsprintf(outstr,
- TEXT("Pure Video FPS:\t%u hires, %u text\n")
- TEXT("Pure CPU MHz:\t%u.%u%s (video update)\n")
- TEXT("Pure CPU MHz:\t%u.%u%s (full-speed)\n\n")
- TEXT("EXPECTED AVERAGE VIDEO GAME\n")
- TEXT("PERFORMANCE: %u FPS"),
- (unsigned)totalhiresfps,
- (unsigned)totaltextfps,
- (unsigned)(totalmhz10[0] / 10), (unsigned)(totalmhz10[0] % 10), (LPCTSTR)(IS_APPLE2 ? TEXT(" (6502)") : TEXT("")),
- (unsigned)(totalmhz10[1] / 10), (unsigned)(totalmhz10[1] % 10), (LPCTSTR)(IS_APPLE2 ? TEXT(" (6502)") : TEXT("")),
- (unsigned)realisticfps);
- MessageBox(GetFrame().g_hFrameWindow,
- outstr,
- TEXT("Benchmarks"),
- MB_ICONINFORMATION | MB_SETFOREGROUND);
-}
-
-//===========================================================================
-
-// This is called from PageConfig
-void WinVideo::ChooseMonochromeColor(void)
-{
- CHOOSECOLOR cc;
- memset(&cc, 0, sizeof(CHOOSECOLOR));
- cc.lStructSize = sizeof(CHOOSECOLOR);
- cc.hwndOwner = GetFrame().g_hFrameWindow;
- cc.rgbResult = GetMonochromeRGB();
- cc.lpCustColors = customcolors + 1;
- cc.Flags = CC_RGBINIT | CC_SOLIDCOLOR;
- if (ChooseColor(&cc))
- {
- SetMonochromeRGB(cc.rgbResult);
- VideoReinitialize();
- if ((g_nAppMode != MODE_LOGO) && (g_nAppMode != MODE_DEBUG))
- {
- VideoRedrawScreen();
- }
- Config_Save_Video();
- }
-}
-
-//===========================================================================
-
-void WinVideo::VideoDrawLogoBitmap(HDC hDstDC, int xoff, int yoff, int srcw, int srch, int scale)
-{
- HDC hSrcDC = CreateCompatibleDC( hDstDC );
- SelectObject( hSrcDC, g_hLogoBitmap );
- StretchBlt(
- hDstDC, // hdcDest
- xoff, yoff, // nXDest, nYDest
- scale * srcw, scale * srch, // nWidth, nHeight
- hSrcDC, // hdcSrc
- 0, 0, // nXSrc, nYSrc
- srcw, srch,
- SRCCOPY // dwRop
- );
-
- DeleteObject( hSrcDC );
-}
-
-//===========================================================================
-
-void WinVideo::DisplayLogo(void)
-{
- int nLogoX = 0, nLogoY = 0;
- int scale = GetViewportScale();
-
- HDC hFrameDC = FrameGetDC();
-
- // DRAW THE LOGO
- SelectObject(hFrameDC, GetStockObject(NULL_PEN));
-
- if (g_hLogoBitmap)
- {
- BITMAP bm;
- if (GetObject(g_hLogoBitmap, sizeof(bm), &bm))
- {
- nLogoX = (g_nViewportCX - scale*bm.bmWidth )/2;
- nLogoY = (g_nViewportCY - scale*bm.bmHeight)/2;
-
- if( IsFullScreen() )
- {
- nLogoX += GetFullScreenOffsetX();
- nLogoY += GetFullScreenOffsetY();
- }
-
- VideoDrawLogoBitmap( hFrameDC, nLogoX, nLogoY, bm.bmWidth, bm.bmHeight, scale );
- }
- }
-
- // DRAW THE VERSION NUMBER
- TCHAR sFontName[] = TEXT("Arial");
- HFONT font = CreateFont(-20,0,0,0,FW_NORMAL,0,0,0,ANSI_CHARSET,
- OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
- VARIABLE_PITCH | 4 | FF_SWISS,
- sFontName );
- SelectObject(hFrameDC,font);
- SetTextAlign(hFrameDC,TA_RIGHT | TA_TOP);
- SetBkMode(hFrameDC,TRANSPARENT);
-
- TCHAR szVersion[ 64 ];
- StringCbPrintf(szVersion, 64, "Version %s", VERSIONSTRING);
- int xoff = GetFullScreenOffsetX(), yoff = GetFullScreenOffsetY();
-
-#define DRAWVERSION(x,y,c) \
- SetTextColor(hFrameDC,c); \
- TextOut(hFrameDC, \
- scale*540+x+xoff,scale*358+y+yoff, \
- szVersion, \
- strlen(szVersion));
-
- if (GetDeviceCaps(hFrameDC,PLANES) * GetDeviceCaps(hFrameDC,BITSPIXEL) <= 4) {
- DRAWVERSION( 2, 2,RGB(0x00,0x00,0x00));
- DRAWVERSION( 1, 1,RGB(0x00,0x00,0x00));
- DRAWVERSION( 0, 0,RGB(0xFF,0x00,0xFF));
- } else {
- DRAWVERSION( 1, 1,PALETTERGB(0x30,0x30,0x70));
- DRAWVERSION(-1,-1,PALETTERGB(0xC0,0x70,0xE0));
- DRAWVERSION( 0, 0,PALETTERGB(0x70,0x30,0xE0));
- }
-
-#if _DEBUG
- StringCbPrintf(szVersion, 64, "DEBUG");
- DRAWVERSION( 2, -358*scale,RGB(0x00,0x00,0x00));
- DRAWVERSION( 1, -357*scale,RGB(0x00,0x00,0x00));
- DRAWVERSION( 0, -356*scale,RGB(0xFF,0x00,0xFF));
-#endif
-
-#undef DRAWVERSION
-
- DeleteObject(font);
-}
-
-//===========================================================================
-
-void WinVideo::VideoPresentScreen(void)
-{
- HDC hFrameDC = FrameGetDC();
-
- if (hFrameDC)
- {
- int xSrc = GetFrameBufferBorderWidth();
- int ySrc = GetFrameBufferBorderHeight();
-
- int xdest = IsFullScreen() ? GetFullScreenOffsetX() : 0;
- int ydest = IsFullScreen() ? GetFullScreenOffsetY() : 0;
- int wdest = g_nViewportCX;
- int hdest = g_nViewportCY;
-
- SetStretchBltMode(hFrameDC, COLORONCOLOR);
- StretchBlt(
- hFrameDC,
- xdest, ydest,
- wdest, hdest,
- g_hDeviceDC,
- xSrc, ySrc,
- GetFrameBufferBorderlessWidth(), GetFrameBufferBorderlessHeight(),
- SRCCOPY);
- }
-
-#ifdef NO_DIRECT_X
-#else
- //if (g_lpDD) g_lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL);
-#endif // NO_DIRECT_X
-
- GdiFlush();
-}
-
-//===========================================================================
-
-BOOL CALLBACK WinVideo::DDEnumProc(LPGUID lpGUID, LPCTSTR lpszDesc, LPCTSTR lpszDrvName, LPVOID lpContext)
-{
- WinVideo* obj = (WinVideo*)lpContext;
-
- int i = obj->num_draw_devices;
- if (i == MAX_DRAW_DEVICES)
- return TRUE;
- if (lpGUID != NULL)
- memcpy(&(obj->draw_device_guid[i]), lpGUID, sizeof (GUID));
- obj->draw_devices[i] = _strdup(lpszDesc);
-
- if (g_fh) fprintf(g_fh, "%d: %s - %s\n",i,lpszDesc,lpszDrvName);
-
- (obj->num_draw_devices)++;
- return TRUE;
-}
-
-bool WinVideo::DDInit(void)
-{
-#ifdef NO_DIRECT_X
-
- return false;
-
-#else
- HRESULT hr = DirectDrawEnumerate((LPDDENUMCALLBACK)DDEnumProc, this);
- if (FAILED(hr))
- {
- LogFileOutput("DSEnumerate failed (%08X)\n", hr);
- return false;
- }
-
- LogFileOutput("Number of draw devices = %d\n", num_draw_devices);
-
- bool bCreatedOK = false;
- for (int x=0; xRelease(); (p)=NULL; } }
-
-void WinVideo::DDUninit(void)
-{
- SAFE_RELEASE(g_lpDD);
-}
-
-#undef SAFE_RELEASE
-
-//===========================================================================
diff --git a/source/Windows/WinVideo.h b/source/Windows/WinVideo.h
deleted file mode 100644
index e1761aa8..00000000
--- a/source/Windows/WinVideo.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#pragma once
-
-#include "Video.h"
-
-class WinVideo : public Video
-{
-public:
- WinVideo()
- {
- g_pFramebufferinfo = NULL;
- num_draw_devices = 0;
- g_lpDD = NULL;
- }
-
- virtual ~WinVideo()
- {
- }
-
- virtual void Initialize(void);
- virtual void Destroy(void);
-
- virtual void VideoPresentScreen(void);
- virtual void ChooseMonochromeColor(void);
- virtual void Benchmark(void);
- virtual void DisplayLogo(void);
-
-private:
- void videoCreateDIBSection(void);
- void VideoDrawLogoBitmap(HDC hDstDC, int xoff, int yoff, int srcw, int srch, int scale);
- static BOOL CALLBACK DDEnumProc(LPGUID lpGUID, LPCTSTR lpszDesc, LPCTSTR lpszDrvName, LPVOID lpContext);
- bool DDInit(void);
- void DDUninit(void);
-
- COLORREF customcolors[256]; // MONOCHROME is last custom color
- HBITMAP g_hLogoBitmap;
- HBITMAP g_hDeviceBitmap;
- HDC g_hDeviceDC;
- LPBITMAPINFO g_pFramebufferinfo;
-
- static const UINT MAX_DRAW_DEVICES = 10;
- char *draw_devices[MAX_DRAW_DEVICES];
- GUID draw_device_guid[MAX_DRAW_DEVICES];
- int num_draw_devices;
- LPDIRECTDRAW g_lpDD;
-};