mirror of
https://github.com/AppleWin/AppleWin.git
synced 2024-12-21 17:31:23 +00:00
Video & FrameBase: better split (PR #908)
* Video / FrameBase: move arch specific code to FrameBase. * Video::Initialize & SetFrameBuffer. Ensure initialization and SetBuffer can only happen in the right order. * Video: move virtual functions to FrameBase. With these changes all the virtual functions are in FrameBase and Video gets closer to be (only) the Apple ][ Video device. * Move a few more functions from Video to FrameBase (snapshot related) Now, the inclusion is one way with Video *not* including FrameBase. * FrameBase::VideoRefreshScreen move Video related code to Video. And only leave management to FrameBase.
This commit is contained in:
parent
0139878dd7
commit
159cde7d64
@ -1001,14 +1001,6 @@
|
||||
RelativePath=".\source\Windows\WinFrame.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\source\Windows\WinVideo.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\source\Windows\WinVideo.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Configuration"
|
||||
|
@ -122,7 +122,6 @@
|
||||
<ClInclude Include="source\Windows\DirectInput.h" />
|
||||
<ClInclude Include="source\Windows\Win32Frame.h" />
|
||||
<ClInclude Include="source\Windows\WinFrame.h" />
|
||||
<ClInclude Include="source\Windows\WinVideo.h" />
|
||||
<ClInclude Include="source\YamlHelper.h" />
|
||||
<ClInclude Include="source\z80emu.h" />
|
||||
<ClInclude Include="source\Z80VICE\daa.h" />
|
||||
@ -243,7 +242,6 @@
|
||||
<ClCompile Include="source\Windows\DirectInput.cpp" />
|
||||
<ClCompile Include="source\Windows\Win32Frame.cpp" />
|
||||
<ClCompile Include="source\Windows\WinFrame.cpp" />
|
||||
<ClCompile Include="source\Windows\WinVideo.cpp" />
|
||||
<ClCompile Include="source\YamlHelper.cpp" />
|
||||
<ClCompile Include="source\z80emu.cpp" />
|
||||
<ClCompile Include="source\Z80VICE\daa.cpp">
|
||||
|
@ -199,9 +199,6 @@
|
||||
<ClCompile Include="source\Windows\DirectInput.cpp">
|
||||
<Filter>Source Files\Windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="source\Windows\WinVideo.cpp">
|
||||
<Filter>Source Files\Windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="source\Windows\WinFrame.cpp">
|
||||
<Filter>Source Files\Windows</Filter>
|
||||
</ClCompile>
|
||||
@ -504,9 +501,6 @@
|
||||
<ClInclude Include="source\Windows\DirectInput.h">
|
||||
<Filter>Source Files\Windows</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="source\Windows\WinVideo.h">
|
||||
<Filter>Source Files\Windows</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="source\Windows\WinFrame.h">
|
||||
<Filter>Source Files\Windows</Filter>
|
||||
</ClInclude>
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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."),
|
||||
|
128
source/Video.cpp
128
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);
|
||||
}
|
||||
|
@ -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[];
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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:
|
||||
|
@ -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; 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 WinVideo::DDUninit(void)
|
||||
{
|
||||
SAFE_RELEASE(g_lpDD);
|
||||
}
|
||||
|
||||
#undef SAFE_RELEASE
|
||||
|
||||
//===========================================================================
|
@ -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;
|
||||
};
|
Loading…
Reference in New Issue
Block a user