mirror of
https://github.com/AppleWin/AppleWin.git
synced 2024-10-01 19:56:21 +00:00
Merge pull request #230 from AppleWin/main_loop_refactor
Main loop refactor -- code cleanup looks good !
This commit is contained in:
commit
3e22d07951
@ -35,6 +35,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "DiskImage.h"
|
#include "DiskImage.h"
|
||||||
#include "Frame.h"
|
#include "Frame.h"
|
||||||
#include "Harddisk.h"
|
#include "Harddisk.h"
|
||||||
|
#include "Joystick.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
#include "Mockingboard.h"
|
#include "Mockingboard.h"
|
||||||
@ -61,10 +62,6 @@ TCHAR *g_pAppTitle = TITLE_APPLE_2E_ENHANCED;
|
|||||||
|
|
||||||
eApple2Type g_Apple2Type = A2TYPE_APPLE2EENHANCED;
|
eApple2Type g_Apple2Type = A2TYPE_APPLE2EENHANCED;
|
||||||
|
|
||||||
DWORD cumulativecycles = 0; // Wraps after ~1hr 9mins
|
|
||||||
DWORD cyclenum = 0; // Used by SpkrToggle() for non-wave sound
|
|
||||||
DWORD emulmsec = 0;
|
|
||||||
static DWORD emulmsec_frac = 0;
|
|
||||||
bool g_bFullSpeed = false;
|
bool g_bFullSpeed = false;
|
||||||
|
|
||||||
//Pravets 8A/C variables
|
//Pravets 8A/C variables
|
||||||
@ -78,7 +75,6 @@ HINSTANCE g_hInstance = (HINSTANCE)0;
|
|||||||
AppMode_e g_nAppMode = MODE_LOGO;
|
AppMode_e g_nAppMode = MODE_LOGO;
|
||||||
static bool g_bLoadedSaveState = false;
|
static bool g_bLoadedSaveState = false;
|
||||||
|
|
||||||
static int lastmode = MODE_LOGO;
|
|
||||||
TCHAR g_sProgramDir[MAX_PATH] = TEXT(""); // Directory of where AppleWin executable resides
|
TCHAR g_sProgramDir[MAX_PATH] = TEXT(""); // Directory of where AppleWin executable resides
|
||||||
TCHAR g_sDebugDir [MAX_PATH] = TEXT(""); // TODO: Not currently used
|
TCHAR g_sDebugDir [MAX_PATH] = TEXT(""); // TODO: Not currently used
|
||||||
TCHAR g_sScreenShotDir[MAX_PATH] = TEXT(""); // TODO: Not currently used
|
TCHAR g_sScreenShotDir[MAX_PATH] = TEXT(""); // TODO: Not currently used
|
||||||
@ -117,17 +113,6 @@ CSpeech g_Speech;
|
|||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
#define DBG_CALC_FREQ 0
|
|
||||||
#if DBG_CALC_FREQ
|
|
||||||
const UINT MAX_CNT = 256;
|
|
||||||
double g_fDbg[MAX_CNT];
|
|
||||||
UINT g_nIdx = 0;
|
|
||||||
double g_fMeanPeriod,g_fMeanFreq;
|
|
||||||
ULONGLONG g_nPerfFreq = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool GetLoadedSaveStateFlag(void)
|
bool GetLoadedSaveStateFlag(void)
|
||||||
{
|
{
|
||||||
return g_bLoadedSaveState;
|
return g_bLoadedSaveState;
|
||||||
@ -229,86 +214,28 @@ void ContinueExecution(void)
|
|||||||
if (nCyclesToExecute < 0)
|
if (nCyclesToExecute < 0)
|
||||||
nCyclesToExecute = 0;
|
nCyclesToExecute = 0;
|
||||||
|
|
||||||
DWORD dwExecutedCycles = CpuExecute(nCyclesToExecute);
|
const DWORD uActualCyclesExecuted = CpuExecute(nCyclesToExecute);
|
||||||
g_dwCyclesThisFrame += dwExecutedCycles;
|
g_dwCyclesThisFrame += uActualCyclesExecuted;
|
||||||
|
|
||||||
//
|
DiskUpdatePosition(uActualCyclesExecuted);
|
||||||
|
JoyUpdateButtonLatch(nExecutionPeriodUsec); // Button latch time is independent of CPU clock frequency
|
||||||
|
|
||||||
cyclenum = dwExecutedCycles;
|
SpkrUpdate(uActualCyclesExecuted);
|
||||||
|
sg_SSC.CommUpdate(uActualCyclesExecuted);
|
||||||
DiskUpdatePosition(dwExecutedCycles);
|
PrintUpdate(uActualCyclesExecuted);
|
||||||
JoyUpdatePosition();
|
|
||||||
|
|
||||||
SpkrUpdate(cyclenum);
|
|
||||||
sg_SSC.CommUpdate(cyclenum);
|
|
||||||
PrintUpdate(cyclenum);
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
const DWORD CLKS_PER_MS = (DWORD)g_fCurrentCLK6502 / 1000;
|
|
||||||
|
|
||||||
emulmsec_frac += dwExecutedCycles;
|
|
||||||
if (emulmsec_frac > CLKS_PER_MS)
|
|
||||||
{
|
|
||||||
emulmsec += emulmsec_frac / CLKS_PER_MS;
|
|
||||||
emulmsec_frac %= CLKS_PER_MS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// DETERMINE WHETHER THE SCREEN WAS UPDATED THIS CLOCKTICK
|
|
||||||
static BOOL anyupdates = 0;
|
|
||||||
VideoCheckPage(0); // force=0
|
|
||||||
anyupdates |= VideoHasRefreshed(); // Only called from here. Returns & clears 'hasrefreshed' flag
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
if (g_dwCyclesThisFrame >= dwClksPerFrame)
|
if (g_dwCyclesThisFrame >= dwClksPerFrame)
|
||||||
{
|
{
|
||||||
g_dwCyclesThisFrame -= dwClksPerFrame;
|
g_dwCyclesThisFrame -= dwClksPerFrame;
|
||||||
VideoUpdateFlash();
|
VideoEndOfVideoFrame();
|
||||||
|
|
||||||
static BOOL lastupdates[2] = {0,0};
|
|
||||||
if (!anyupdates && !lastupdates[0] && !lastupdates[1] && VideoApparentlyDirty())
|
|
||||||
{
|
|
||||||
VideoCheckPage(1); // force=1
|
|
||||||
static DWORD lasttime = 0;
|
|
||||||
DWORD currtime = GetTickCount();
|
|
||||||
if ((!g_bFullSpeed) ||
|
|
||||||
(currtime-lasttime >= (DWORD)(g_bGraphicsMode ? 100 : 25)))
|
|
||||||
{
|
|
||||||
VideoRefreshScreen();
|
|
||||||
lasttime = currtime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lastupdates[1] = lastupdates[0];
|
|
||||||
lastupdates[0] = anyupdates;
|
|
||||||
anyupdates = 0;
|
|
||||||
|
|
||||||
MB_EndOfVideoFrame();
|
MB_EndOfVideoFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
if (!g_bFullSpeed)
|
if (!g_bFullSpeed)
|
||||||
{
|
{
|
||||||
SysClk_WaitTimer();
|
SysClk_WaitTimer();
|
||||||
|
|
||||||
#if DBG_CALC_FREQ
|
|
||||||
if (g_nPerfFreq)
|
|
||||||
{
|
|
||||||
QueryPerformanceCounter((LARGE_INTEGER*)&nTime1);
|
|
||||||
LONGLONG nTimeDiff = nTime1 - nTime0;
|
|
||||||
double fTime = (double)nTimeDiff / (double)(LONGLONG)g_nPerfFreq;
|
|
||||||
|
|
||||||
g_fDbg[g_nIdx] = fTime;
|
|
||||||
g_nIdx = (g_nIdx+1) & (MAX_CNT-1);
|
|
||||||
g_fMeanPeriod = 0.0;
|
|
||||||
for(UINT n=0; n<MAX_CNT; n++)
|
|
||||||
g_fMeanPeriod += g_fDbg[n];
|
|
||||||
g_fMeanPeriod /= (double)MAX_CNT;
|
|
||||||
g_fMeanFreq = 1.0 / g_fMeanPeriod;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -985,11 +912,6 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
|||||||
|
|
||||||
LogFileOutput("AppleWin version: %s\n", VERSIONSTRING);
|
LogFileOutput("AppleWin version: %s\n", VERSIONSTRING);
|
||||||
|
|
||||||
#if DBG_CALC_FREQ
|
|
||||||
QueryPerformanceFrequency((LARGE_INTEGER*)&g_nPerfFreq);
|
|
||||||
if(g_fh) fprintf(g_fh, "Performance frequency = %d\n",g_nPerfFreq);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//-----
|
//-----
|
||||||
|
|
||||||
// Initialize COM - so we can use CoCreateInstance
|
// Initialize COM - so we can use CoCreateInstance
|
||||||
|
@ -13,9 +13,6 @@ extern TCHAR *g_pAppTitle;
|
|||||||
|
|
||||||
extern eApple2Type g_Apple2Type;
|
extern eApple2Type g_Apple2Type;
|
||||||
|
|
||||||
extern DWORD cumulativecycles;
|
|
||||||
extern DWORD cyclenum;
|
|
||||||
extern DWORD emulmsec;
|
|
||||||
extern bool g_bFullSpeed;
|
extern bool g_bFullSpeed;
|
||||||
|
|
||||||
//Pravets 8A/C only variables
|
//Pravets 8A/C only variables
|
||||||
|
@ -176,16 +176,18 @@ void RequestDebugger()
|
|||||||
*
|
*
|
||||||
***/
|
***/
|
||||||
|
|
||||||
unsigned __int64 g_nCycleIrqStart;
|
#ifdef _DEBUG
|
||||||
unsigned __int64 g_nCycleIrqEnd;
|
static unsigned __int64 g_nCycleIrqStart;
|
||||||
UINT g_nCycleIrqTime;
|
static unsigned __int64 g_nCycleIrqEnd;
|
||||||
|
static UINT g_nCycleIrqTime;
|
||||||
|
|
||||||
UINT g_nIdx = 0;
|
static UINT g_nIdx = 0;
|
||||||
const UINT BUFFER_SIZE = 4096; // 80 secs
|
static const UINT BUFFER_SIZE = 4096; // 80 secs
|
||||||
UINT g_nBuffer[BUFFER_SIZE];
|
static UINT g_nBuffer[BUFFER_SIZE];
|
||||||
UINT g_nMean = 0;
|
static UINT g_nMean = 0;
|
||||||
UINT g_nMin = 0xFFFFFFFF;
|
static UINT g_nMin = 0xFFFFFFFF;
|
||||||
UINT g_nMax = 0;
|
static UINT g_nMax = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
static __forceinline void DoIrqProfiling(DWORD uCycles)
|
static __forceinline void DoIrqProfiling(DWORD uCycles)
|
||||||
{
|
{
|
||||||
@ -352,7 +354,9 @@ static __forceinline void NMI(ULONG& uExecutedCycles, UINT& uExtraCycles, BOOL&
|
|||||||
{
|
{
|
||||||
// NMI signals are only serviced once
|
// NMI signals are only serviced once
|
||||||
g_bNmiFlank = FALSE;
|
g_bNmiFlank = FALSE;
|
||||||
|
#ifdef _DEBUG
|
||||||
g_nCycleIrqStart = g_nCumulativeCycles + uExecutedCycles;
|
g_nCycleIrqStart = g_nCumulativeCycles + uExecutedCycles;
|
||||||
|
#endif
|
||||||
PUSH(regs.pc >> 8)
|
PUSH(regs.pc >> 8)
|
||||||
PUSH(regs.pc & 0xFF)
|
PUSH(regs.pc & 0xFF)
|
||||||
EF_TO_AF
|
EF_TO_AF
|
||||||
@ -369,7 +373,9 @@ static __forceinline void IRQ(ULONG& uExecutedCycles, UINT& uExtraCycles, BOOL&
|
|||||||
if(g_bmIRQ && !(regs.ps & AF_INTERRUPT))
|
if(g_bmIRQ && !(regs.ps & AF_INTERRUPT))
|
||||||
{
|
{
|
||||||
// IRQ signals are deasserted when a specific r/w operation is done on device
|
// IRQ signals are deasserted when a specific r/w operation is done on device
|
||||||
|
#ifdef _DEBUG
|
||||||
g_nCycleIrqStart = g_nCumulativeCycles + uExecutedCycles;
|
g_nCycleIrqStart = g_nCumulativeCycles + uExecutedCycles;
|
||||||
|
#endif
|
||||||
PUSH(regs.pc >> 8)
|
PUSH(regs.pc >> 8)
|
||||||
PUSH(regs.pc & 0xFF)
|
PUSH(regs.pc & 0xFF)
|
||||||
EF_TO_AF
|
EF_TO_AF
|
||||||
@ -465,6 +471,29 @@ ULONG CpuGetCyclesThisVideoFrame(const ULONG nExecutedCycles)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static DWORD g_dwEmulationTime_ms = 0;
|
||||||
|
|
||||||
|
static void UpdateEmulationTime(const DWORD dwExecutedCycles)
|
||||||
|
{
|
||||||
|
static DWORD dwEmulationTimeFrac_clks = 0;
|
||||||
|
|
||||||
|
const DWORD CLKS_PER_MS = (DWORD)g_fCurrentCLK6502 / 1000;
|
||||||
|
|
||||||
|
dwEmulationTimeFrac_clks += dwExecutedCycles;
|
||||||
|
if (dwEmulationTimeFrac_clks > CLKS_PER_MS)
|
||||||
|
{
|
||||||
|
g_dwEmulationTime_ms += dwEmulationTimeFrac_clks / CLKS_PER_MS;
|
||||||
|
dwEmulationTimeFrac_clks %= CLKS_PER_MS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD CpuGetEmulationTime_ms(void)
|
||||||
|
{
|
||||||
|
return g_dwEmulationTime_ms;
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
DWORD CpuExecute(const DWORD uCycles)
|
DWORD CpuExecute(const DWORD uCycles)
|
||||||
@ -479,6 +508,7 @@ DWORD CpuExecute(const DWORD uCycles)
|
|||||||
const DWORD uExecutedCycles = InternalCpuExecute(uCycles);
|
const DWORD uExecutedCycles = InternalCpuExecute(uCycles);
|
||||||
|
|
||||||
MB_UpdateCycles(uExecutedCycles); // Update 6522s (NB. Do this before updating g_nCumulativeCycles below)
|
MB_UpdateCycles(uExecutedCycles); // Update 6522s (NB. Do this before updating g_nCumulativeCycles below)
|
||||||
|
UpdateEmulationTime(uExecutedCycles);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
|
@ -31,3 +31,5 @@ DWORD CpuSetSnapshot(SS_CPU6502* pSS);
|
|||||||
|
|
||||||
BYTE CpuRead(USHORT addr, ULONG uExecutedCycles);
|
BYTE CpuRead(USHORT addr, ULONG uExecutedCycles);
|
||||||
void CpuWrite(USHORT addr, BYTE a, ULONG uExecutedCycles);
|
void CpuWrite(USHORT addr, BYTE a, ULONG uExecutedCycles);
|
||||||
|
|
||||||
|
DWORD CpuGetEmulationTime_ms(void);
|
||||||
|
@ -4711,9 +4711,9 @@ size_t Util_GetTextScreen ( char* &pText_ )
|
|||||||
g_nTextScreen = 0;
|
g_nTextScreen = 0;
|
||||||
memset( pBeg, 0, sizeof( g_aTextScreen ) );
|
memset( pBeg, 0, sizeof( g_aTextScreen ) );
|
||||||
|
|
||||||
int bBank2 = g_bVideoDisplayPage2;
|
unsigned int uBank2 = VideoGetSWPAGE2() ? 1 : 0;
|
||||||
LPBYTE g_pTextBank1 = MemGetAuxPtr (0x400 << (int)bBank2);
|
LPBYTE g_pTextBank1 = MemGetAuxPtr (0x400 << uBank2);
|
||||||
LPBYTE g_pTextBank0 = MemGetMainPtr(0x400 << (int)bBank2);
|
LPBYTE g_pTextBank0 = MemGetMainPtr(0x400 << uBank2);
|
||||||
|
|
||||||
for( int y = 0; y < 24; y++ )
|
for( int y = 0; y < 24; y++ )
|
||||||
{
|
{
|
||||||
@ -4724,7 +4724,7 @@ size_t Util_GetTextScreen ( char* &pText_ )
|
|||||||
{
|
{
|
||||||
char c; // TODO: FormatCharTxtCtrl() ?
|
char c; // TODO: FormatCharTxtCtrl() ?
|
||||||
|
|
||||||
if ( g_bVideoMode & VF_80COL )
|
if ( VideoGetSW80COL() )
|
||||||
{ // AUX
|
{ // AUX
|
||||||
c = g_pTextBank1[ nAddressStart ] & 0x7F;
|
c = g_pTextBank1[ nAddressStart ] & 0x7F;
|
||||||
c = RemapChar(c);
|
c = RemapChar(c);
|
||||||
@ -4792,7 +4792,7 @@ int CmdTextSave (int nArgs)
|
|||||||
_tcscpy( g_sMemoryLoadSaveFileName, g_aArgs[ 1 ].sArg );
|
_tcscpy( g_sMemoryLoadSaveFileName, g_aArgs[ 1 ].sArg );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( g_bVideoMode & VF_80COL )
|
if( VideoGetSW80COL() )
|
||||||
sprintf( g_sMemoryLoadSaveFileName, "AppleWin_Text80.txt" );
|
sprintf( g_sMemoryLoadSaveFileName, "AppleWin_Text80.txt" );
|
||||||
else
|
else
|
||||||
sprintf( g_sMemoryLoadSaveFileName, "AppleWin_Text40.txt" );
|
sprintf( g_sMemoryLoadSaveFileName, "AppleWin_Text40.txt" );
|
||||||
@ -5997,11 +5997,11 @@ Update_t _ViewOutput( ViewVideoPage_t iPage, VideoUpdateFuncPtr_t pfUpdate );
|
|||||||
|
|
||||||
Update_t _ViewOutput( ViewVideoPage_t iPage, VideoUpdateFuncPtr_t pfUpdate )
|
Update_t _ViewOutput( ViewVideoPage_t iPage, VideoUpdateFuncPtr_t pfUpdate )
|
||||||
{
|
{
|
||||||
g_VideoForceFullRedraw = true;
|
VideoSetForceFullRedraw();
|
||||||
_Video_Dirty();
|
_Video_Dirty();
|
||||||
switch( iPage )
|
switch( iPage )
|
||||||
{
|
{
|
||||||
case VIEW_PAGE_X: _Video_SetupBanks( g_bVideoDisplayPage2 ); break; // Page Current
|
case VIEW_PAGE_X: _Video_SetupBanks( VideoGetSWPAGE2() ); break; // Page Current
|
||||||
case VIEW_PAGE_1: _Video_SetupBanks( false ); break; // Page 1
|
case VIEW_PAGE_1: _Video_SetupBanks( false ); break; // Page 1
|
||||||
case VIEW_PAGE_2: _Video_SetupBanks( true ); break; // Page 2 !
|
case VIEW_PAGE_2: _Video_SetupBanks( true ); break; // Page 2 !
|
||||||
default:
|
default:
|
||||||
|
@ -2735,38 +2735,38 @@ void DrawSoftSwitches( int iSoftSwitch )
|
|||||||
// GR / TEXT
|
// GR / TEXT
|
||||||
// GRAPH/TEXT
|
// GRAPH/TEXT
|
||||||
// TEXT ON/OFF
|
// TEXT ON/OFF
|
||||||
sprintf( sText, !(g_bVideoMode & VF_TEXT) ? "GR / ----" : "-- / TEXT" );
|
sprintf( sText, !VideoGetSWTEXT() ? "GR / ----" : "-- / TEXT" );
|
||||||
PrintTextCursorY( sText, rect );
|
PrintTextCursorY( sText, rect );
|
||||||
|
|
||||||
// $C052 / $C053 = MIXEDOFF/MIXEDON = SW.MIXCLR/SW.MIXSET
|
// $C052 / $C053 = MIXEDOFF/MIXEDON = SW.MIXCLR/SW.MIXSET
|
||||||
// FULL/MIXED
|
// FULL/MIXED
|
||||||
// MIX OFF/ON
|
// MIX OFF/ON
|
||||||
sprintf( sText, !(g_bVideoMode & VF_MIXED) ? "FULL/-----" : "----/MIXED" );
|
sprintf( sText, !VideoGetSWMIXED() ? "FULL/-----" : "----/MIXED" );
|
||||||
PrintTextCursorY( sText, rect );
|
PrintTextCursorY( sText, rect );
|
||||||
|
|
||||||
// $C054 / $C055 = PAGE1/PAGE2 = PAGE2OFF/PAGE2ON = SW.LOWSCR/SW.HISCR
|
// $C054 / $C055 = PAGE1/PAGE2 = PAGE2OFF/PAGE2ON = SW.LOWSCR/SW.HISCR
|
||||||
// PAGE 1 / 2
|
// PAGE 1 / 2
|
||||||
sprintf( sText, !(g_bVideoMode & VF_PAGE2) ? "PAGE 1 / -" : "PAGE - / 2" );
|
sprintf( sText, !VideoGetSWPAGE2() ? "PAGE 1 / -" : "PAGE - / 2" );
|
||||||
PrintTextCursorY( sText, rect );
|
PrintTextCursorY( sText, rect );
|
||||||
|
|
||||||
// $C056 / $C057 LORES/HIRES = HIRESOFF/HIRESON = SW.LORES/SW.HIRES
|
// $C056 / $C057 LORES/HIRES = HIRESOFF/HIRESON = SW.LORES/SW.HIRES
|
||||||
// LO / HIRES
|
// LO / HIRES
|
||||||
// LO / -----
|
// LO / -----
|
||||||
// -- / HIRES
|
// -- / HIRES
|
||||||
sprintf( sText, !(g_bVideoMode & VF_HIRES) ? "LO /-- RES" : "---/HI RES" );
|
sprintf( sText, !VideoGetSWHIRES() ? "LO /-- RES" : "---/HI RES" );
|
||||||
PrintTextCursorY( sText, rect );
|
PrintTextCursorY( sText, rect );
|
||||||
|
|
||||||
PrintTextCursorY( "", rect );
|
PrintTextCursorY( "", rect );
|
||||||
|
|
||||||
// Extended soft switches
|
// Extended soft switches
|
||||||
sprintf( sText, !(g_bVideoMode & VF_80COL) ? "40 / -- COL" : "-- / 80 COL" );
|
sprintf( sText, !VideoGetSW80COL() ? "40 / -- COL" : "-- / 80 COL" );
|
||||||
PrintTextCursorY( sText, rect );
|
PrintTextCursorY( sText, rect );
|
||||||
|
|
||||||
sprintf(sText, (g_nAltCharSetOffset == 0) ? "ASCII/-----" : "-----/MOUSE" );
|
sprintf(sText, VideoGetSWAltCharSet() ? "ASCII/-----" : "-----/MOUSE" );
|
||||||
PrintTextCursorY( sText, rect );
|
PrintTextCursorY( sText, rect );
|
||||||
|
|
||||||
// 280/560 HGR
|
// 280/560 HGR
|
||||||
sprintf(sText, !(g_bVideoMode & VF_DHIRES) ? "HGR / ----" : "--- / DHGR" );
|
sprintf(sText, !VideoGetSWDHIRES() ? "HGR / ----" : "--- / DHGR" );
|
||||||
PrintTextCursorY( sText, rect );
|
PrintTextCursorY( sText, rect );
|
||||||
#else //SOFTSWITCH_OLD
|
#else //SOFTSWITCH_OLD
|
||||||
// See: VideoSetMode()
|
// See: VideoSetMode()
|
||||||
@ -2778,25 +2778,25 @@ void DrawSoftSwitches( int iSoftSwitch )
|
|||||||
bool bSet;
|
bool bSet;
|
||||||
|
|
||||||
// $C050 / $C051 = TEXTOFF/TEXTON = SW.TXTCLR/SW.TXTSET
|
// $C050 / $C051 = TEXTOFF/TEXTON = SW.TXTCLR/SW.TXTSET
|
||||||
bSet = !(g_bVideoMode & VF_TEXT);
|
bSet = !VideoGetSWTEXT();
|
||||||
_DrawSoftSwitch( rect, 0xC050, bSet, NULL, "GR.", "TEXT" );
|
_DrawSoftSwitch( rect, 0xC050, bSet, NULL, "GR.", "TEXT" );
|
||||||
|
|
||||||
// $C052 / $C053 = MIXEDOFF/MIXEDON = SW.MIXCLR/SW.MIXSET
|
// $C052 / $C053 = MIXEDOFF/MIXEDON = SW.MIXCLR/SW.MIXSET
|
||||||
// FULL/MIXED
|
// FULL/MIXED
|
||||||
// MIX OFF/ON
|
// MIX OFF/ON
|
||||||
bSet = !(g_bVideoMode & VF_MIXED);
|
bSet = !VideoGetSWMIXED();
|
||||||
_DrawSoftSwitch( rect, 0xC052, bSet, NULL, "FULL", "MIX" );
|
_DrawSoftSwitch( rect, 0xC052, bSet, NULL, "FULL", "MIX" );
|
||||||
|
|
||||||
// $C054 / $C055 = PAGE1/PAGE2 = PAGE2OFF/PAGE2ON = SW.LOWSCR/SW.HISCR
|
// $C054 / $C055 = PAGE1/PAGE2 = PAGE2OFF/PAGE2ON = SW.LOWSCR/SW.HISCR
|
||||||
// PAGE 1 / 2
|
// PAGE 1 / 2
|
||||||
bSet = !(g_bVideoMode & VF_PAGE2);
|
bSet = !VideoGetSWPAGE2();
|
||||||
_DrawSoftSwitch( rect, 0xC054, bSet, "PAGE ", "1", "2" );
|
_DrawSoftSwitch( rect, 0xC054, bSet, "PAGE ", "1", "2" );
|
||||||
|
|
||||||
// $C056 / $C057 LORES/HIRES = HIRESOFF/HIRESON = SW.LORES/SW.HIRES
|
// $C056 / $C057 LORES/HIRES = HIRESOFF/HIRESON = SW.LORES/SW.HIRES
|
||||||
// LO / HIRES
|
// LO / HIRES
|
||||||
// LO / -----
|
// LO / -----
|
||||||
// -- / HIRES
|
// -- / HIRES
|
||||||
bSet = !(g_bVideoMode & VF_HIRES);
|
bSet = !VideoGetSWHIRES();
|
||||||
_DrawSoftSwitch( rect, 0xC056, bSet, NULL, "LO", "HI", "RES" );
|
_DrawSoftSwitch( rect, 0xC056, bSet, NULL, "LO", "HI", "RES" );
|
||||||
|
|
||||||
DebuggerSetColorBG( DebuggerGetColor( BG_INFO ));
|
DebuggerSetColorBG( DebuggerGetColor( BG_INFO ));
|
||||||
@ -2805,20 +2805,20 @@ void DrawSoftSwitches( int iSoftSwitch )
|
|||||||
|
|
||||||
// 280/560 HGR
|
// 280/560 HGR
|
||||||
// C05E = ON, C05F = OFF
|
// C05E = ON, C05F = OFF
|
||||||
bSet = (g_bVideoMode & VF_DHIRES) ? true : false;
|
bSet = VideoGetSWDHIRES();
|
||||||
_DrawSoftSwitch( rect, 0xC05E, bSet, NULL, "DHGR", "HGR" );
|
_DrawSoftSwitch( rect, 0xC05E, bSet, NULL, "DHGR", "HGR" );
|
||||||
|
|
||||||
// Extended soft switches
|
// Extended soft switches
|
||||||
// C00C = off, C00D = on
|
// C00C = off, C00D = on
|
||||||
bSet = !(g_bVideoMode & VF_80COL);
|
bSet = !VideoGetSW80COL();
|
||||||
_DrawSoftSwitch( rect, 0xC00C, bSet, "Col", "40", "80" );
|
_DrawSoftSwitch( rect, 0xC00C, bSet, "Col", "40", "80" );
|
||||||
|
|
||||||
// C00E = off, C00F = on
|
// C00E = off, C00F = on
|
||||||
bSet = (g_nAltCharSetOffset == 0);
|
bSet = VideoGetSWAltCharSet();
|
||||||
_DrawSoftSwitch( rect, 0xC00E, bSet, NULL, "ASC", "MOUS" ); // ASCII/MouseText
|
_DrawSoftSwitch( rect, 0xC00E, bSet, NULL, "ASC", "MOUS" ); // ASCII/MouseText
|
||||||
|
|
||||||
// C000 = 80STOREOFF, C001 = 80STOREON
|
// C000 = 80STOREOFF, C001 = 80STOREON
|
||||||
bSet = !(g_bVideoMode & VF_MASK2);
|
bSet = !VideoGetSW80STORE();
|
||||||
_DrawSoftSwitch( rect, 0xC000, bSet, "80Sto", "0", "1" );
|
_DrawSoftSwitch( rect, 0xC000, bSet, "80Sto", "0", "1" );
|
||||||
#endif // SOFTSWITCH_OLD
|
#endif // SOFTSWITCH_OLD
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
|
|
||||||
#include "Configuration\PropertySheet.h"
|
#include "Configuration\PropertySheet.h"
|
||||||
|
|
||||||
#define BUTTONTIME 5000 // TODO: Describe this magic number
|
#define BUTTONTIME 5000 // This is the latch (debounce) time in usecs for the joystick buttons
|
||||||
|
|
||||||
enum {DEVICE_NONE=0, DEVICE_JOYSTICK, DEVICE_KEYBOARD, DEVICE_MOUSE};
|
enum {DEVICE_NONE=0, DEVICE_JOYSTICK, DEVICE_KEYBOARD, DEVICE_MOUSE};
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ static POINT keyvalue[9] = {{PDL_MIN,PDL_MAX}, {PDL_CENTRAL,PDL_MAX}, {PDL
|
|||||||
{PDL_MIN,PDL_CENTRAL},{PDL_CENTRAL,PDL_CENTRAL},{PDL_MAX,PDL_CENTRAL},
|
{PDL_MIN,PDL_CENTRAL},{PDL_CENTRAL,PDL_CENTRAL},{PDL_MAX,PDL_CENTRAL},
|
||||||
{PDL_MIN,PDL_MIN}, {PDL_CENTRAL,PDL_MIN}, {PDL_MAX,PDL_MIN}};
|
{PDL_MIN,PDL_MIN}, {PDL_CENTRAL,PDL_MIN}, {PDL_MAX,PDL_MIN}};
|
||||||
|
|
||||||
static DWORD buttonlatch[3] = {0,0,0};
|
static int buttonlatch[3] = {0,0,0};
|
||||||
static BOOL joybutton[3] = {0,0,0};
|
static BOOL joybutton[3] = {0,0,0};
|
||||||
|
|
||||||
static int joyshrx[2] = {8,8};
|
static int joyshrx[2] = {8,8};
|
||||||
@ -703,11 +703,19 @@ void JoySetPosition(int xvalue, int xrange, int yvalue, int yrange)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
void JoyUpdatePosition()
|
|
||||||
|
// Update the latch (debounce) time for each button
|
||||||
|
void JoyUpdateButtonLatch(const UINT nExecutionPeriodUsec)
|
||||||
{
|
{
|
||||||
if (buttonlatch[0]) --buttonlatch[0];
|
for (UINT i=0; i<3; i++)
|
||||||
if (buttonlatch[1]) --buttonlatch[1];
|
{
|
||||||
if (buttonlatch[2]) --buttonlatch[2];
|
if (buttonlatch[i])
|
||||||
|
{
|
||||||
|
buttonlatch[i] -= nExecutionPeriodUsec;
|
||||||
|
if (buttonlatch[i] < 0)
|
||||||
|
buttonlatch[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -15,7 +15,7 @@ void JoyReset();
|
|||||||
void JoySetButton(eBUTTON,eBUTTONSTATE);
|
void JoySetButton(eBUTTON,eBUTTONSTATE);
|
||||||
BOOL JoySetEmulationType(HWND,DWORD,int, const bool bMousecardActive);
|
BOOL JoySetEmulationType(HWND,DWORD,int, const bool bMousecardActive);
|
||||||
void JoySetPosition(int,int,int,int);
|
void JoySetPosition(int,int,int,int);
|
||||||
void JoyUpdatePosition();
|
void JoyUpdateButtonLatch(const UINT nExecutionPeriodUsec);
|
||||||
BOOL JoyUsingMouse();
|
BOOL JoyUsingMouse();
|
||||||
BOOL JoyUsingKeyboard();
|
BOOL JoyUsingKeyboard();
|
||||||
BOOL JoyUsingKeyboardCursors();
|
BOOL JoyUsingKeyboardCursors();
|
||||||
|
@ -88,7 +88,7 @@ MEMORY MANAGEMENT SOFT SWITCHES
|
|||||||
$C005 W RAMWRTON Write enable aux memory from $0200-$BFFF
|
$C005 W RAMWRTON Write enable aux memory from $0200-$BFFF
|
||||||
$C006 W INTCXROMOFF Enable slot ROM from $C100-$CFFF
|
$C006 W INTCXROMOFF Enable slot ROM from $C100-$CFFF
|
||||||
$C007 W INTCXROMON Enable main ROM from $C100-$CFFF
|
$C007 W INTCXROMON Enable main ROM from $C100-$CFFF
|
||||||
$C008 W ALZTPOFF Enable main memory from $0000-$01FF & avl BSR
|
$C008 W ALTZPOFF Enable main memory from $0000-$01FF & avl BSR
|
||||||
$C009 W ALTZPON Enable aux memory from $0000-$01FF & avl BSR
|
$C009 W ALTZPON Enable aux memory from $0000-$01FF & avl BSR
|
||||||
$C00A W SLOTC3ROMOFF Enable main ROM from $C300-$C3FF
|
$C00A W SLOTC3ROMOFF Enable main ROM from $C300-$C3FF
|
||||||
$C00B W SLOTC3ROMON Enable slot ROM from $C300-$C3FF
|
$C00B W SLOTC3ROMON Enable slot ROM from $C300-$C3FF
|
||||||
@ -1074,13 +1074,6 @@ void MemDestroy ()
|
|||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
bool MemGet80Store()
|
|
||||||
{
|
|
||||||
return SW_80STORE != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
bool MemCheckSLOTCXROM()
|
bool MemCheckSLOTCXROM()
|
||||||
{
|
{
|
||||||
return SW_SLOTCXROM ? true : false;
|
return SW_SLOTCXROM ? true : false;
|
||||||
|
@ -38,7 +38,6 @@ extern UINT g_uMaxExPages; // user requested ram pages (from cmd line)
|
|||||||
void RegisterIoHandler(UINT uSlot, iofunction IOReadC0, iofunction IOWriteC0, iofunction IOReadCx, iofunction IOWriteCx, LPVOID lpSlotParameter, BYTE* pExpansionRom);
|
void RegisterIoHandler(UINT uSlot, iofunction IOReadC0, iofunction IOWriteC0, iofunction IOReadCx, iofunction IOWriteCx, LPVOID lpSlotParameter, BYTE* pExpansionRom);
|
||||||
|
|
||||||
void MemDestroy ();
|
void MemDestroy ();
|
||||||
bool MemGet80Store();
|
|
||||||
bool MemCheckSLOTCXROM();
|
bool MemCheckSLOTCXROM();
|
||||||
LPBYTE MemGetAuxPtr(const WORD);
|
LPBYTE MemGetAuxPtr(const WORD);
|
||||||
LPBYTE MemGetMainPtr(const WORD);
|
LPBYTE MemGetMainPtr(const WORD);
|
||||||
|
@ -479,7 +479,9 @@ BYTE __stdcall SpkrToggle (WORD, WORD, BYTE, BYTE, ULONG nCyclesLeft)
|
|||||||
if (lastcyclenum)
|
if (lastcyclenum)
|
||||||
{
|
{
|
||||||
toggles++;
|
toggles++;
|
||||||
DWORD delta = cyclenum-lastcyclenum;
|
//DWORD delta = cyclenum-lastcyclenum; // [TC: 14/09/2014] Looks broken, since 'cyclenum' is cycles executed in previous call to CpuExecute()
|
||||||
|
CpuCalcCycles(nCyclesLeft);
|
||||||
|
DWORD delta = (DWORD)g_nCumulativeCycles - lastcyclenum;
|
||||||
|
|
||||||
// DETERMINE WHETHER WE ARE PLAYING A SOUND EFFECT
|
// DETERMINE WHETHER WE ARE PLAYING A SOUND EFFECT
|
||||||
if (directio &&
|
if (directio &&
|
||||||
@ -493,7 +495,8 @@ BYTE __stdcall SpkrToggle (WORD, WORD, BYTE, BYTE, ULONG nCyclesLeft)
|
|||||||
lastdelta[0] = delta;
|
lastdelta[0] = delta;
|
||||||
totaldelta += delta;
|
totaldelta += delta;
|
||||||
}
|
}
|
||||||
lastcyclenum = cyclenum;
|
//lastcyclenum = cyclenum;
|
||||||
|
lastcyclenum = (DWORD)g_nCumulativeCycles;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -610,7 +613,7 @@ void SpkrUpdate_Timer()
|
|||||||
nSamplesUsed = Spkr_SubmitWaveBuffer_FullSpeed(g_pSpeakerBuffer, g_nBufferIdx);
|
nSamplesUsed = Spkr_SubmitWaveBuffer_FullSpeed(g_pSpeakerBuffer, g_nBufferIdx);
|
||||||
|
|
||||||
_ASSERT(nSamplesUsed <= g_nBufferIdx);
|
_ASSERT(nSamplesUsed <= g_nBufferIdx);
|
||||||
memmove(g_pSpeakerBuffer, &g_pSpeakerBuffer[nSamplesUsed], g_nBufferIdx-nSamplesUsed); // FIXME-TC: _Size * 2
|
memmove(g_pSpeakerBuffer, &g_pSpeakerBuffer[nSamplesUsed], g_nBufferIdx-nSamplesUsed); // FIXME-TC: _Size * 2 (GH#213?)
|
||||||
g_nBufferIdx -= nSamplesUsed;
|
g_nBufferIdx -= nSamplesUsed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
247
source/Video.cpp
247
source/Video.cpp
@ -197,13 +197,24 @@ const BYTE DoubleHiresPalIndex[16] = {
|
|||||||
const int SRCOFFS_DHIRES = (SRCOFFS_HIRES + 512); // 1168
|
const int SRCOFFS_DHIRES = (SRCOFFS_HIRES + 512); // 1168
|
||||||
const int SRCOFFS_TOTAL = (SRCOFFS_DHIRES + 2560); // 3278
|
const int SRCOFFS_TOTAL = (SRCOFFS_DHIRES + 2560); // 3278
|
||||||
|
|
||||||
#define SW_80COL (g_bVideoMode & VF_80COL)
|
enum VideoFlag_e
|
||||||
#define SW_DHIRES (g_bVideoMode & VF_DHIRES)
|
{
|
||||||
#define SW_HIRES (g_bVideoMode & VF_HIRES)
|
VF_80COL = 0x00000001,
|
||||||
#define SW_MASK2 (g_bVideoMode & VF_MASK2)
|
VF_DHIRES = 0x00000002,
|
||||||
#define SW_MIXED (g_bVideoMode & VF_MIXED)
|
VF_HIRES = 0x00000004,
|
||||||
#define SW_PAGE2 (g_bVideoMode & VF_PAGE2)
|
VF_80STORE= 0x00000008,
|
||||||
#define SW_TEXT (g_bVideoMode & VF_TEXT)
|
VF_MIXED = 0x00000010,
|
||||||
|
VF_PAGE2 = 0x00000020,
|
||||||
|
VF_TEXT = 0x00000040
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SW_80COL (g_uVideoMode & VF_80COL)
|
||||||
|
#define SW_DHIRES (g_uVideoMode & VF_DHIRES)
|
||||||
|
#define SW_HIRES (g_uVideoMode & VF_HIRES)
|
||||||
|
#define SW_80STORE (g_uVideoMode & VF_80STORE)
|
||||||
|
#define SW_MIXED (g_uVideoMode & VF_MIXED)
|
||||||
|
#define SW_PAGE2 (g_uVideoMode & VF_PAGE2)
|
||||||
|
#define SW_TEXT (g_uVideoMode & VF_TEXT)
|
||||||
|
|
||||||
#define SETSOURCEPIXEL(x,y,c) g_aSourceStartofLine[(y)][(x)] = (c)
|
#define SETSOURCEPIXEL(x,y,c) g_aSourceStartofLine[(y)][(x)] = (c)
|
||||||
|
|
||||||
@ -261,24 +272,20 @@ static BYTE colormixbuffer[6];
|
|||||||
static WORD colormixmap[6][6][6];
|
static WORD colormixmap[6][6][6];
|
||||||
//
|
//
|
||||||
|
|
||||||
int g_nAltCharSetOffset = 0; // alternate character set
|
static int g_nAltCharSetOffset = 0; // alternate character set
|
||||||
|
|
||||||
bool g_bVideoDisplayPage2 = 0;
|
static /*bool*/ UINT g_VideoForceFullRedraw = 1;
|
||||||
/*bool*/ UINT g_VideoForceFullRedraw = 1;
|
|
||||||
|
|
||||||
static LPBYTE framebufferaddr = (LPBYTE)0;
|
static LPBYTE framebufferaddr = (LPBYTE)0;
|
||||||
static LONG g_nFrameBufferPitch = 0;
|
static LONG g_nFrameBufferPitch = 0;
|
||||||
BOOL g_bGraphicsMode = 0;
|
|
||||||
static BOOL hasrefreshed = 0;
|
|
||||||
static DWORD lastpageflip = 0;
|
|
||||||
COLORREF monochrome = RGB(0xC0,0xC0,0xC0);
|
COLORREF monochrome = RGB(0xC0,0xC0,0xC0);
|
||||||
static BOOL rebuiltsource = 0;
|
static BOOL rebuiltsource = 0;
|
||||||
static LPBYTE vidlastmem = NULL;
|
static LPBYTE vidlastmem = NULL;
|
||||||
|
|
||||||
int g_bVideoMode = VF_TEXT;
|
static UINT g_uVideoMode = VF_TEXT;
|
||||||
|
|
||||||
DWORD g_eVideoType = VT_COLOR_TVEMU;
|
DWORD g_eVideoType = VT_COLOR_TVEMU;
|
||||||
DWORD g_uHalfScanLines = true; // drop 50% scan lines for a more authentic look
|
DWORD g_uHalfScanLines = 1; // drop 50% scan lines for a more authentic look
|
||||||
|
|
||||||
|
|
||||||
static bool g_bTextFlashState = false;
|
static bool g_bTextFlashState = false;
|
||||||
@ -1924,8 +1931,8 @@ BOOL VideoApparentlyDirty ()
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
DWORD address = (SW_HIRES && !SW_TEXT)
|
DWORD address = (SW_HIRES && !SW_TEXT)
|
||||||
? (0x20 << (int)g_bVideoDisplayPage2)
|
? (0x20 << (SW_PAGE2 ? 1 : 0))
|
||||||
: (0x04 << (int)g_bVideoDisplayPage2);
|
: (0x04 << (SW_PAGE2 ? 1 : 0));
|
||||||
DWORD length = (SW_HIRES && !SW_TEXT) ? 0x20 : 0x4;
|
DWORD length = (SW_HIRES && !SW_TEXT) ? 0x20 : 0x4;
|
||||||
while (length--)
|
while (length--)
|
||||||
if (*(memdirty+(address++)) & 2)
|
if (*(memdirty+(address++)) & 2)
|
||||||
@ -1933,12 +1940,12 @@ BOOL VideoApparentlyDirty ()
|
|||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
bool bCharFlashing = false;
|
|
||||||
|
|
||||||
// Scan visible text page for any flashing chars
|
// Scan visible text page for any flashing chars
|
||||||
if((SW_TEXT || SW_MIXED) && (g_nAltCharSetOffset == 0))
|
if((SW_TEXT || SW_MIXED) && (g_nAltCharSetOffset == 0))
|
||||||
{
|
{
|
||||||
BYTE* pnMemText = MemGetMainPtr(0x400 << (int)g_bVideoDisplayPage2);
|
BYTE* pTextBank0 = MemGetMainPtr(0x400 << (SW_PAGE2 ? 1 : 0));
|
||||||
|
BYTE* pTextBank1 = MemGetAuxPtr (0x400 << (SW_PAGE2 ? 1 : 0));
|
||||||
|
const bool b80Col = SW_80COL;
|
||||||
|
|
||||||
// Scan 8 long-lines of 120 chars (at 128 char offsets):
|
// Scan 8 long-lines of 120 chars (at 128 char offsets):
|
||||||
// . Skip 8-char holes in TEXT
|
// . Skip 8-char holes in TEXT
|
||||||
@ -1946,19 +1953,20 @@ BOOL VideoApparentlyDirty ()
|
|||||||
{
|
{
|
||||||
for(UINT x=0; x<40*3; x++)
|
for(UINT x=0; x<40*3; x++)
|
||||||
{
|
{
|
||||||
BYTE ch = pnMemText[y*128+x];
|
BYTE ch = pTextBank0[y*128+x];
|
||||||
if((ch >= 0x40) && (ch <= 0x7F))
|
if((ch >= 0x40) && (ch <= 0x7F))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (b80Col)
|
||||||
{
|
{
|
||||||
bCharFlashing = true;
|
ch = pTextBank1[y*128+x];
|
||||||
break;
|
if((ch >= 0x40) && (ch <= 0x7F))
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bCharFlashing)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1981,7 +1989,7 @@ void VideoBenchmark () {
|
|||||||
// GOING ON, CHANGING HALF OF THE BYTES IN THE VIDEO BUFFER EACH FRAME TO
|
// GOING ON, CHANGING HALF OF THE BYTES IN THE VIDEO BUFFER EACH FRAME TO
|
||||||
// SIMULATE THE ACTIVITY OF AN AVERAGE GAME
|
// SIMULATE THE ACTIVITY OF AN AVERAGE GAME
|
||||||
DWORD totaltextfps = 0;
|
DWORD totaltextfps = 0;
|
||||||
g_bVideoMode = VF_TEXT;
|
g_uVideoMode = VF_TEXT;
|
||||||
FillMemory(mem+0x400,0x400,0x14);
|
FillMemory(mem+0x400,0x400,0x14);
|
||||||
VideoRedrawScreen();
|
VideoRedrawScreen();
|
||||||
DWORD milliseconds = GetTickCount();
|
DWORD milliseconds = GetTickCount();
|
||||||
@ -2003,7 +2011,7 @@ void VideoBenchmark () {
|
|||||||
// GOING ON, CHANGING HALF OF THE BYTES IN THE VIDEO BUFFER EACH FRAME TO
|
// GOING ON, CHANGING HALF OF THE BYTES IN THE VIDEO BUFFER EACH FRAME TO
|
||||||
// SIMULATE THE ACTIVITY OF AN AVERAGE GAME
|
// SIMULATE THE ACTIVITY OF AN AVERAGE GAME
|
||||||
DWORD totalhiresfps = 0;
|
DWORD totalhiresfps = 0;
|
||||||
g_bVideoMode = VF_HIRES;
|
g_uVideoMode = VF_HIRES;
|
||||||
FillMemory(mem+0x2000,0x2000,0x14);
|
FillMemory(mem+0x2000,0x2000,0x14);
|
||||||
VideoRedrawScreen();
|
VideoRedrawScreen();
|
||||||
milliseconds = GetTickCount();
|
milliseconds = GetTickCount();
|
||||||
@ -2099,7 +2107,7 @@ void VideoBenchmark () {
|
|||||||
DWORD executedcycles = CpuExecute(103);
|
DWORD executedcycles = CpuExecute(103);
|
||||||
cycles -= executedcycles;
|
cycles -= executedcycles;
|
||||||
DiskUpdatePosition(executedcycles);
|
DiskUpdatePosition(executedcycles);
|
||||||
JoyUpdatePosition();
|
JoyUpdateButtonLatch(executedcycles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cycle & 1)
|
if (cycle & 1)
|
||||||
@ -2154,25 +2162,6 @@ BYTE VideoCheckMode (WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles)
|
|||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
// Check if we should call VideoRefreshScreen() based on unexpected page
|
|
||||||
// - Only called from 2 places in main ContinueExecution() loop
|
|
||||||
void VideoCheckPage(BOOL force)
|
|
||||||
{
|
|
||||||
const bool bUnexpectedPage = (g_bVideoDisplayPage2 != (SW_PAGE2 != 0));
|
|
||||||
//_ASSERT(!bUnexpectedPage); // [TC] Q: When does this happen? A: EG. When page-flipping && Scroll-Lock is pressed
|
|
||||||
|
|
||||||
if (bUnexpectedPage && // Unexpected page &&
|
|
||||||
(force || (emulmsec-lastpageflip > 500))) // force || >500ms since last flip
|
|
||||||
{
|
|
||||||
g_bVideoDisplayPage2 = (SW_PAGE2 != 0);
|
|
||||||
VideoRefreshScreen();
|
|
||||||
hasrefreshed = 1;
|
|
||||||
lastpageflip = emulmsec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Drol expects = 80
|
// Drol expects = 80
|
||||||
68DE A5 02 LDX #02
|
68DE A5 02 LDX #02
|
||||||
@ -2384,13 +2373,6 @@ void VideoDisplayLogo ()
|
|||||||
DeleteObject(font);
|
DeleteObject(font);
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
BOOL VideoHasRefreshed () {
|
|
||||||
BOOL result = hasrefreshed;
|
|
||||||
hasrefreshed = 0;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
void VideoRealizePalette(HDC dc)
|
void VideoRealizePalette(HDC dc)
|
||||||
{
|
{
|
||||||
@ -2483,8 +2465,9 @@ static void DebugRefresh(char uDebugFlag)
|
|||||||
{
|
{
|
||||||
static DWORD uLastRefreshTime = 0;
|
static DWORD uLastRefreshTime = 0;
|
||||||
|
|
||||||
const DWORD uTimeBetweenRefreshes = uLastRefreshTime ? emulmsec - uLastRefreshTime : 0;
|
const DWORD dwEmuTime_ms = CpuGetEmulationTime_ms();
|
||||||
uLastRefreshTime = emulmsec;
|
const DWORD uTimeBetweenRefreshes = uLastRefreshTime ? dwEmuTime_ms - uLastRefreshTime : 0;
|
||||||
|
uLastRefreshTime = dwEmuTime_ms;
|
||||||
|
|
||||||
if (!uTimeBetweenRefreshes)
|
if (!uTimeBetweenRefreshes)
|
||||||
return; // 1st time in func
|
return; // 1st time in func
|
||||||
@ -2505,7 +2488,7 @@ VideoUpdateFuncPtr_t VideoRefreshScreen ()
|
|||||||
// IN THE FRAME BUFFER. MARK CELLS IN WHICH REDRAWING HAS TAKEN PLACE AS
|
// IN THE FRAME BUFFER. MARK CELLS IN WHICH REDRAWING HAS TAKEN PLACE AS
|
||||||
// DIRTY.
|
// DIRTY.
|
||||||
_Video_Dirty();
|
_Video_Dirty();
|
||||||
_Video_SetupBanks( g_bVideoDisplayPage2 );
|
_Video_SetupBanks( SW_PAGE2 != 0 );
|
||||||
|
|
||||||
VideoUpdateFuncPtr_t pfUpdate = SW_TEXT
|
VideoUpdateFuncPtr_t pfUpdate = SW_TEXT
|
||||||
? SW_80COL
|
? SW_80COL
|
||||||
@ -2694,15 +2677,8 @@ void VideoReinitialize ()
|
|||||||
void VideoResetState ()
|
void VideoResetState ()
|
||||||
{
|
{
|
||||||
g_nAltCharSetOffset = 0;
|
g_nAltCharSetOffset = 0;
|
||||||
g_bVideoDisplayPage2 = 0;
|
g_uVideoMode = VF_TEXT;
|
||||||
g_bVideoMode = VF_TEXT;
|
|
||||||
g_VideoForceFullRedraw = 1;
|
g_VideoForceFullRedraw = 1;
|
||||||
|
|
||||||
#if 0 // Debug HGR2 without having to exec 6502 code
|
|
||||||
g_bVideoDisplayPage2 = 1;
|
|
||||||
g_bVideoMode = VF_TEXT | VF_HIRES;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2711,53 +2687,46 @@ BYTE VideoSetMode (WORD, WORD address, BYTE write, BYTE, ULONG uExecutedCycles)
|
|||||||
{
|
{
|
||||||
address &= 0xFF;
|
address &= 0xFF;
|
||||||
DWORD oldpage2 = SW_PAGE2;
|
DWORD oldpage2 = SW_PAGE2;
|
||||||
int oldvalue = g_nAltCharSetOffset+(int)(g_bVideoMode & ~(VF_MASK2 | VF_PAGE2));
|
int oldvalue = g_nAltCharSetOffset+(int)(g_uVideoMode & ~(VF_80STORE | VF_PAGE2));
|
||||||
switch (address) {
|
|
||||||
case 0x00: g_bVideoMode &= ~VF_MASK2; break;
|
switch (address)
|
||||||
case 0x01: g_bVideoMode |= VF_MASK2; break;
|
{
|
||||||
case 0x0C: if (!IS_APPLE2) g_bVideoMode &= ~VF_80COL; break;
|
case 0x00: g_uVideoMode &= ~VF_80STORE; break;
|
||||||
case 0x0D: if (!IS_APPLE2) g_bVideoMode |= VF_80COL; break;
|
case 0x01: g_uVideoMode |= VF_80STORE; break;
|
||||||
|
case 0x0C: if (!IS_APPLE2) g_uVideoMode &= ~VF_80COL; break;
|
||||||
|
case 0x0D: if (!IS_APPLE2) g_uVideoMode |= VF_80COL; break;
|
||||||
case 0x0E: if (!IS_APPLE2) g_nAltCharSetOffset = 0; break; // Alternate char set off
|
case 0x0E: if (!IS_APPLE2) g_nAltCharSetOffset = 0; break; // Alternate char set off
|
||||||
case 0x0F: if (!IS_APPLE2) g_nAltCharSetOffset = 256; break; // Alternate char set on
|
case 0x0F: if (!IS_APPLE2) g_nAltCharSetOffset = 256; break; // Alternate char set on
|
||||||
case 0x50: g_bVideoMode &= ~VF_TEXT; break;
|
case 0x50: g_uVideoMode &= ~VF_TEXT; break;
|
||||||
case 0x51: g_bVideoMode |= VF_TEXT; break;
|
case 0x51: g_uVideoMode |= VF_TEXT; break;
|
||||||
case 0x52: g_bVideoMode &= ~VF_MIXED; break;
|
case 0x52: g_uVideoMode &= ~VF_MIXED; break;
|
||||||
case 0x53: g_bVideoMode |= VF_MIXED; break;
|
case 0x53: g_uVideoMode |= VF_MIXED; break;
|
||||||
case 0x54: g_bVideoMode &= ~VF_PAGE2; break;
|
case 0x54: g_uVideoMode &= ~VF_PAGE2; break;
|
||||||
case 0x55: g_bVideoMode |= VF_PAGE2; break;
|
case 0x55: g_uVideoMode |= VF_PAGE2; break;
|
||||||
case 0x56: g_bVideoMode &= ~VF_HIRES; break;
|
case 0x56: g_uVideoMode &= ~VF_HIRES; break;
|
||||||
case 0x57: g_bVideoMode |= VF_HIRES; break;
|
case 0x57: g_uVideoMode |= VF_HIRES; break;
|
||||||
case 0x5E: if (!IS_APPLE2) g_bVideoMode |= VF_DHIRES; break;
|
case 0x5E: if (!IS_APPLE2) g_uVideoMode |= VF_DHIRES; break;
|
||||||
case 0x5F: if (!IS_APPLE2) g_bVideoMode &= ~VF_DHIRES; break;
|
case 0x5F: if (!IS_APPLE2) g_uVideoMode &= ~VF_DHIRES; break;
|
||||||
}
|
}
|
||||||
if (SW_MASK2)
|
|
||||||
g_bVideoMode &= ~VF_PAGE2;
|
if (SW_80STORE)
|
||||||
if (oldvalue != g_nAltCharSetOffset+(int)(g_bVideoMode & ~(VF_MASK2 | VF_PAGE2))) {
|
g_uVideoMode &= ~VF_PAGE2;
|
||||||
g_bGraphicsMode = !SW_TEXT;
|
|
||||||
g_VideoForceFullRedraw = 1;
|
if (oldvalue != g_nAltCharSetOffset+(int)(g_uVideoMode & ~(VF_80STORE | VF_PAGE2)))
|
||||||
}
|
{
|
||||||
if (g_bFullSpeed && oldpage2 && !SW_PAGE2) {
|
g_VideoForceFullRedraw = 1;
|
||||||
static DWORD lasttime = 0;
|
|
||||||
DWORD currtime = GetTickCount();
|
|
||||||
if (currtime-lasttime >= 20)
|
|
||||||
lasttime = currtime;
|
|
||||||
else
|
|
||||||
oldpage2 = SW_PAGE2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldpage2 != SW_PAGE2)
|
if (oldpage2 != SW_PAGE2)
|
||||||
{
|
{
|
||||||
g_bVideoDisplayPage2 = (SW_PAGE2 != 0);
|
|
||||||
if (!g_VideoForceFullRedraw)
|
if (!g_VideoForceFullRedraw)
|
||||||
{
|
{
|
||||||
#if 1
|
#if 1
|
||||||
VideoRefreshScreen();
|
VideoRefreshScreen();
|
||||||
hasrefreshed = 1;
|
|
||||||
#else
|
#else
|
||||||
g_VideoForceFullRedraw = 1; // GH#129,GH204: Defer the redraw until the main ContinueExecution() loop (TODO: What effect does this have on other games?)
|
g_VideoForceFullRedraw = 1; // GH#129,GH204: Defer the redraw until the main ContinueExecution() loop (TODO: What effect does this have on other games?)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
lastpageflip = emulmsec;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return MemReadFloatingBus(uExecutedCycles);
|
return MemReadFloatingBus(uExecutedCycles);
|
||||||
@ -2766,7 +2735,7 @@ BYTE VideoSetMode (WORD, WORD address, BYTE write, BYTE, ULONG uExecutedCycles)
|
|||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
// Called at 60Hz (every 16.666ms)
|
// Called at 60Hz (every 16.666ms)
|
||||||
void VideoUpdateFlash()
|
static void VideoUpdateFlash()
|
||||||
{
|
{
|
||||||
static UINT nTextFlashCnt = 0;
|
static UINT nTextFlashCnt = 0;
|
||||||
|
|
||||||
@ -2788,17 +2757,81 @@ void VideoUpdateFlash()
|
|||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
bool VideoGetSW80COL()
|
// Called from main-loop every 17030 cycles (ie. 60Hz when CPU = 1MHz)
|
||||||
|
void VideoEndOfVideoFrame(void)
|
||||||
|
{
|
||||||
|
VideoUpdateFlash(); // TODO: Flash rate should be constant (regardless of CPU speed)
|
||||||
|
|
||||||
|
if (!VideoApparentlyDirty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Apple II is not page flipping...
|
||||||
|
|
||||||
|
static DWORD dwLastTime = 0;
|
||||||
|
DWORD dwCurrTime = GetTickCount();
|
||||||
|
if (!g_bFullSpeed ||
|
||||||
|
(dwCurrTime-dwLastTime >= 100)) // FullSpeed: update every 100ms
|
||||||
|
{
|
||||||
|
VideoRefreshScreen();
|
||||||
|
dwLastTime = dwCurrTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
bool VideoGetSW80COL(void)
|
||||||
{
|
{
|
||||||
return SW_80COL ? true : false;
|
return SW_80COL ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VideoGetSWDHIRES(void)
|
||||||
|
{
|
||||||
|
return SW_DHIRES ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VideoGetSWHIRES(void)
|
||||||
|
{
|
||||||
|
return SW_HIRES ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VideoGetSW80STORE(void)
|
||||||
|
{
|
||||||
|
return SW_80STORE ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VideoGetSWMIXED(void)
|
||||||
|
{
|
||||||
|
return SW_MIXED ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VideoGetSWPAGE2(void)
|
||||||
|
{
|
||||||
|
return SW_PAGE2 ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VideoGetSWTEXT(void)
|
||||||
|
{
|
||||||
|
return SW_TEXT ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VideoGetSWAltCharSet(void)
|
||||||
|
{
|
||||||
|
return g_nAltCharSetOffset == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void VideoSetForceFullRedraw(void)
|
||||||
|
{
|
||||||
|
g_VideoForceFullRedraw = 1;
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
DWORD VideoGetSnapshot(SS_IO_Video* pSS)
|
DWORD VideoGetSnapshot(SS_IO_Video* pSS)
|
||||||
{
|
{
|
||||||
pSS->bAltCharSet = !(g_nAltCharSetOffset == 0);
|
pSS->bAltCharSet = !(g_nAltCharSetOffset == 0);
|
||||||
pSS->dwVidMode = g_bVideoMode;
|
pSS->dwVidMode = g_uVideoMode;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2807,13 +2840,7 @@ DWORD VideoGetSnapshot(SS_IO_Video* pSS)
|
|||||||
DWORD VideoSetSnapshot(SS_IO_Video* pSS)
|
DWORD VideoSetSnapshot(SS_IO_Video* pSS)
|
||||||
{
|
{
|
||||||
g_nAltCharSetOffset = !pSS->bAltCharSet ? 0 : 256;
|
g_nAltCharSetOffset = !pSS->bAltCharSet ? 0 : 256;
|
||||||
g_bVideoMode = pSS->dwVidMode;
|
g_uVideoMode = pSS->dwVidMode;
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
g_bGraphicsMode = !SW_TEXT;
|
|
||||||
g_bVideoDisplayPage2 = (SW_PAGE2 != 0);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2831,8 +2858,8 @@ WORD VideoGetScannerAddress(bool* pbVblBar_OUT, const DWORD uExecutedCycles)
|
|||||||
// machine state switches
|
// machine state switches
|
||||||
//
|
//
|
||||||
int nHires = (SW_HIRES && !SW_TEXT) ? 1 : 0;
|
int nHires = (SW_HIRES && !SW_TEXT) ? 1 : 0;
|
||||||
int nPage2 = (SW_PAGE2) ? 1 : 0;
|
int nPage2 = SW_PAGE2 ? 1 : 0;
|
||||||
int n80Store = (MemGet80Store()) ? 1 : 0;
|
int n80Store = SW_80STORE ? 1 : 0;
|
||||||
|
|
||||||
// calculate video parameters according to display standard
|
// calculate video parameters according to display standard
|
||||||
//
|
//
|
||||||
|
@ -19,17 +19,6 @@
|
|||||||
extern TCHAR g_aVideoChoices[];
|
extern TCHAR g_aVideoChoices[];
|
||||||
extern char *g_apVideoModeDesc[ NUM_VIDEO_MODES ];
|
extern char *g_apVideoModeDesc[ NUM_VIDEO_MODES ];
|
||||||
|
|
||||||
enum VideoFlag_e
|
|
||||||
{
|
|
||||||
VF_80COL = 0x00000001,
|
|
||||||
VF_DHIRES = 0x00000002,
|
|
||||||
VF_HIRES = 0x00000004,
|
|
||||||
VF_MASK2 = 0x00000008,
|
|
||||||
VF_MIXED = 0x00000010,
|
|
||||||
VF_PAGE2 = 0x00000020,
|
|
||||||
VF_TEXT = 0x00000040
|
|
||||||
};
|
|
||||||
|
|
||||||
enum AppleFont_e
|
enum AppleFont_e
|
||||||
{
|
{
|
||||||
// 40-Column mode is 1x Zoom (default)
|
// 40-Column mode is 1x Zoom (default)
|
||||||
@ -57,15 +46,11 @@ enum AppleFont_e
|
|||||||
|
|
||||||
extern HBITMAP g_hLogoBitmap;
|
extern HBITMAP g_hLogoBitmap;
|
||||||
|
|
||||||
extern BOOL g_bGraphicsMode;
|
|
||||||
extern COLORREF monochrome; // saved
|
extern COLORREF monochrome; // saved
|
||||||
extern DWORD g_eVideoType; // saved
|
extern DWORD g_eVideoType; // saved
|
||||||
extern DWORD g_uHalfScanLines; // saved
|
extern DWORD g_uHalfScanLines; // saved
|
||||||
extern LPBYTE g_pFramebufferbits;
|
extern LPBYTE g_pFramebufferbits;
|
||||||
|
|
||||||
extern int g_nAltCharSetOffset;
|
|
||||||
extern int g_bVideoMode; // g_bVideoMode
|
|
||||||
|
|
||||||
typedef bool (*VideoUpdateFuncPtr_t)(int,int,int,int,int);
|
typedef bool (*VideoUpdateFuncPtr_t)(int,int,int,int,int);
|
||||||
|
|
||||||
// Prototypes _______________________________________________________
|
// Prototypes _______________________________________________________
|
||||||
@ -74,12 +59,10 @@ void CreateColorMixMap();
|
|||||||
|
|
||||||
BOOL VideoApparentlyDirty ();
|
BOOL VideoApparentlyDirty ();
|
||||||
void VideoBenchmark ();
|
void VideoBenchmark ();
|
||||||
void VideoCheckPage (BOOL);
|
|
||||||
void VideoChooseColor ();
|
void VideoChooseColor ();
|
||||||
void VideoDestroy ();
|
void VideoDestroy ();
|
||||||
void VideoDrawLogoBitmap(HDC hDstDC, int xoff, int yoff, int srcw, int srch, int scale);
|
void VideoDrawLogoBitmap(HDC hDstDC, int xoff, int yoff, int srcw, int srch, int scale);
|
||||||
void VideoDisplayLogo ();
|
void VideoDisplayLogo ();
|
||||||
BOOL VideoHasRefreshed ();
|
|
||||||
void VideoInitialize ();
|
void VideoInitialize ();
|
||||||
void VideoRealizePalette (HDC);
|
void VideoRealizePalette (HDC);
|
||||||
VideoUpdateFuncPtr_t VideoRedrawScreen (UINT);
|
VideoUpdateFuncPtr_t VideoRedrawScreen (UINT);
|
||||||
@ -89,15 +72,22 @@ void VideoReinitialize ();
|
|||||||
void VideoResetState ();
|
void VideoResetState ();
|
||||||
WORD VideoGetScannerAddress(bool* pbVblBar_OUT, const DWORD uExecutedCycles);
|
WORD VideoGetScannerAddress(bool* pbVblBar_OUT, const DWORD uExecutedCycles);
|
||||||
bool VideoGetVbl(DWORD uExecutedCycles);
|
bool VideoGetVbl(DWORD uExecutedCycles);
|
||||||
void VideoUpdateFlash();
|
void VideoEndOfVideoFrame(void);
|
||||||
bool VideoGetSW80COL();
|
|
||||||
|
bool VideoGetSW80COL(void);
|
||||||
|
bool VideoGetSWDHIRES(void);
|
||||||
|
bool VideoGetSWHIRES(void);
|
||||||
|
bool VideoGetSW80STORE(void);
|
||||||
|
bool VideoGetSWMIXED(void);
|
||||||
|
bool VideoGetSWPAGE2(void);
|
||||||
|
bool VideoGetSWTEXT(void);
|
||||||
|
bool VideoGetSWAltCharSet(void);
|
||||||
|
|
||||||
|
void VideoSetForceFullRedraw(void);
|
||||||
|
|
||||||
DWORD VideoGetSnapshot(SS_IO_Video* pSS);
|
DWORD VideoGetSnapshot(SS_IO_Video* pSS);
|
||||||
DWORD VideoSetSnapshot(SS_IO_Video* pSS);
|
DWORD VideoSetSnapshot(SS_IO_Video* pSS);
|
||||||
|
|
||||||
|
|
||||||
extern bool g_bVideoDisplayPage2;
|
|
||||||
extern /*bool*/ UINT g_VideoForceFullRedraw;
|
|
||||||
|
|
||||||
void _Video_Dirty();
|
void _Video_Dirty();
|
||||||
void _Video_RedrawScreen( VideoUpdateFuncPtr_t update, bool bMixed = false );
|
void _Video_RedrawScreen( VideoUpdateFuncPtr_t update, bool bMixed = false );
|
||||||
void _Video_SetupBanks( bool bBank2 );
|
void _Video_SetupBanks( bool bBank2 );
|
||||||
|
Loading…
Reference in New Issue
Block a user