Support vertical blending for 'RGB (Color Monitor)' for hires (#616) (PR #624)

Support the old AppleWin 1.25 vertical blending for hires:
- extended Config dialog to include 'Vertical Blend' checkbox
- Persist 'Video Styles' to Registry
- new cmd line options to select this style & also select 'RGB (Color Monitor)'
- code refactor to support enum VideoStyle_e (and replaced g_uHalfScanLines with a bit in g_eVideoStyles)

Bumped version to 1.28.2.0.
This commit is contained in:
TomCh 2019-02-24 15:59:35 +00:00 committed by GitHub
parent be81458284
commit 082b22d753
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 308 additions and 120 deletions

View File

@ -89,16 +89,17 @@ CAPTION "Configuration"
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
LTEXT "&Model:",IDC_STATIC,5,7,40,8
COMBOBOX IDC_COMPUTER,45,5,95,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "Confirm reboot",IDC_CHECK_CONFIRM_REBOOT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,148,8,62,10
COMBOBOX IDC_COMPUTER,45,5,90,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "Confirm reboot",IDC_CHECK_CONFIRM_REBOOT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,142,8,62,10
GROUPBOX "Video",IDC_STATIC,5,22,200,56
LTEXT "Mo&de:",IDC_STATIC,12,33,33,8
COMBOBOX IDC_VIDEOTYPE,45,30,95,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_VIDEOTYPE,45,30,90,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Monochrome &Color...",IDC_MONOCOLOR,12,46,80,14
CONTROL "50% Scan lines",IDC_CHECK_HALF_SCAN_LINES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,103,48,62,10
CONTROL "50% Scan lines",IDC_CHECK_HALF_SCAN_LINES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,142,33,62,10
CONTROL "Vertical blend",IDC_CHECK_VERTICAL_BLEND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,142,48,62,10
CONTROL "Full-Screen: Show drive/keyboard status",IDC_CHECK_FS_SHOW_SUBUNIT_STATUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,64,140,10
LTEXT "&Serial Port:",IDC_STATIC,5,89,40,8
COMBOBOX IDC_SERIALPORT,45,87,95,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_SERIALPORT,45,87,90,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "&Ethernet Settings...",IDC_ETHERNET,4,105,80,14
GROUPBOX "Emulation Speed Control",IDC_STATIC,5,130,200,85
CONTROL "Use &Authentic Machine Speed",IDC_AUTHENTIC_SPEED,

View File

@ -115,6 +115,7 @@
#define IDC_COMBO_DISK1 1080
#define IDC_COMBO_DISK2 1081
#define IDC_CHECK_FS_SHOW_SUBUNIT_STATUS 1082
#define IDC_CHECK_VERTICAL_BLEND 1083
#define IDM_EXIT 40001
#define IDM_HELP 40002
#define IDM_ABOUT 40003

View File

@ -1,4 +1,4 @@
#define APPLEWIN_VERSION 1,28,1,0
#define APPLEWIN_VERSION 1,28,2,0
#define xstr(a) str(a)
#define str(a) #a

View File

@ -1175,6 +1175,8 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
const std::string strCmdLine(lpCmdLine); // Keep a copy for log ouput
UINT uRamWorksExPages = 0;
UINT uSaturnBanks = 0;
int newVideoType = -1;
int newVideoStyle = -1;
while (*lpCmdLine)
{
@ -1395,6 +1397,14 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
{
SetAltEnterToggleFullScreen(false);
}
else if (strcmp(lpCmdLine, "-video-mode=rgb-monitor") == 0) // GH#616
{
newVideoType = VT_COLOR_MONITOR_RGB;
}
else if (strcmp(lpCmdLine, "-video-style=vertical-blend") == 0) // GH#616
{
newVideoStyle = VS_COLOR_VERTICAL_BLEND;
}
else // unsupported
{
LogFileOutput("Unsupported arg: %s\n", lpCmdLine);
@ -1507,6 +1517,11 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
LoadConfiguration();
LogFileOutput("Main: LoadConfiguration()\n");
if (newVideoType >= 0)
SetVideoType( (VideoType_e)newVideoType );
if (newVideoStyle >= 0)
SetVideoStyle( (VideoStyle_e)newVideoStyle );
// Apply the memory expansion switches after loading the Apple II machine type
#ifdef RAMWORKS
if (uRamWorksExPages)

View File

@ -104,7 +104,8 @@ enum AppMode_e
#define REGVALUE_PRINTER_APPEND "Append to printer file"
#define REGVALUE_PRINTER_IDLE_LIMIT "Printer idle limit"
#define REGVALUE_VIDEO_MODE "Video Emulation"
#define REGVALUE_VIDEO_HALF_SCAN_LINES "Half Scan Lines"
#define REGVALUE_VIDEO_STYLE "Video Style" // GH#616: Added at 1.28.2
#define REGVALUE_VIDEO_HALF_SCAN_LINES "Half Scan Lines" // GH#616: Deprecated from 1.28.2
#define REGVALUE_VIDEO_MONO_COLOR "Monochrome Color"
#define REGVALUE_SERIAL_PORT_NAME "Serial Port Name"
#define REGVALUE_ENHANCE_DISK_SPEED "Enhance Disk Speed"

View File

@ -119,6 +119,7 @@ BOOL CPageConfig::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM
case IDC_CHECK_CONFIRM_REBOOT:
case IDC_CHECK_HALF_SCAN_LINES:
case IDC_CHECK_VERTICAL_BLEND:
case IDC_CHECK_FS_SHOW_SUBUNIT_STATUS:
// Checked in DlgOK()
break;
@ -142,6 +143,14 @@ BOOL CPageConfig::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM
}
break;
case IDC_VIDEOTYPE:
if(HIWORD(wparam) == CBN_SELCHANGE)
{
const VideoType_e newVideoType = (VideoType_e) SendDlgItemMessage(hWnd, IDC_VIDEOTYPE, CB_GETCURSEL, 0, 0);
EnableWindow(GetDlgItem(hWnd, IDC_CHECK_VERTICAL_BLEND), (newVideoType == VT_COLOR_MONITOR_RGB) ? TRUE : FALSE);
}
break;
#if 0
case IDC_RECALIBRATE:
RegSaveValue(TEXT(""),TEXT("RunningOnOS"),0,0);
@ -186,10 +195,13 @@ BOOL CPageConfig::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM
CheckDlgButton(hWnd, IDC_CHECK_CONFIRM_REBOOT, g_bConfirmReboot ? BST_CHECKED : BST_UNCHECKED );
m_PropertySheetHelper.FillComboBox(hWnd,IDC_VIDEOTYPE,g_aVideoChoices,g_eVideoType);
CheckDlgButton(hWnd, IDC_CHECK_HALF_SCAN_LINES, g_uHalfScanLines ? BST_CHECKED : BST_UNCHECKED);
m_PropertySheetHelper.FillComboBox(hWnd,IDC_VIDEOTYPE, g_aVideoChoices, GetVideoType());
CheckDlgButton(hWnd, IDC_CHECK_HALF_SCAN_LINES, IsVideoStyle(VS_HALF_SCANLINES) ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hWnd, IDC_CHECK_FS_SHOW_SUBUNIT_STATUS, GetFullScreenShowSubunitStatus() ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hWnd, IDC_CHECK_VERTICAL_BLEND, IsVideoStyle(VS_COLOR_VERTICAL_BLEND) ? BST_CHECKED : BST_UNCHECKED);
EnableWindow(GetDlgItem(hWnd, IDC_CHECK_VERTICAL_BLEND), (GetVideoType() == VT_COLOR_MONITOR_RGB) ? TRUE : FALSE);
m_PropertySheetHelper.FillComboBox(hWnd,IDC_SERIALPORT, sg_SSC.GetSerialPortChoices(), sg_SSC.GetSerialPort());
EnableWindow(GetDlgItem(hWnd, IDC_SERIALPORT), !sg_SSC.IsActive() ? TRUE : FALSE);
@ -245,17 +257,32 @@ void CPageConfig::DlgOK(HWND hWnd)
{
bool bVideoReinit = false;
const DWORD uNewVideoType = (DWORD) SendDlgItemMessage(hWnd, IDC_VIDEOTYPE, CB_GETCURSEL, 0, 0);
if (g_eVideoType != uNewVideoType)
const VideoType_e newVideoType = (VideoType_e) SendDlgItemMessage(hWnd, IDC_VIDEOTYPE, CB_GETCURSEL, 0, 0);
if (GetVideoType() != newVideoType)
{
g_eVideoType = uNewVideoType;
SetVideoType(newVideoType);
bVideoReinit = true;
}
const DWORD uNewHalfScanLines = IsDlgButtonChecked(hWnd, IDC_CHECK_HALF_SCAN_LINES) ? 1 : 0;
if (g_uHalfScanLines != uNewHalfScanLines)
const bool newHalfScanLines = IsDlgButtonChecked(hWnd, IDC_CHECK_HALF_SCAN_LINES) != 0;
const bool currentHalfScanLines = IsVideoStyle(VS_HALF_SCANLINES);
if (currentHalfScanLines != newHalfScanLines)
{
g_uHalfScanLines = uNewHalfScanLines;
if (newHalfScanLines)
SetVideoStyle( (VideoStyle_e) (GetVideoStyle() | VS_HALF_SCANLINES) );
else
SetVideoStyle( (VideoStyle_e) (GetVideoStyle() & ~VS_HALF_SCANLINES) );
bVideoReinit = true;
}
const bool newVerticalBlend = IsDlgButtonChecked(hWnd, IDC_CHECK_VERTICAL_BLEND) != 0;
const bool currentVerticalBlend = IsVideoStyle(VS_COLOR_VERTICAL_BLEND);
if (currentVerticalBlend != newVerticalBlend)
{
if (newVerticalBlend)
SetVideoStyle( (VideoStyle_e) (GetVideoStyle() | VS_COLOR_VERTICAL_BLEND) );
else
SetVideoStyle( (VideoStyle_e) (GetVideoStyle() & ~VS_COLOR_VERTICAL_BLEND) );
bVideoReinit = true;
}

View File

@ -275,7 +275,7 @@ static void GetAppleWindowTitle()
// TODO: g_bDisplayVideoModeInTitle
_tcscat( g_pAppleWindowTitle, " - " );
if( g_uHalfScanLines )
if( IsVideoStyle(VS_HALF_SCANLINES) )
{
_tcscat( g_pAppleWindowTitle," 50% " );
}
@ -1289,7 +1289,7 @@ LRESULT CALLBACK FrameWndProc (
}
else if ( KeybGetCtrlStatus() && KeybGetShiftStatus() ) // CTRL+SHIFT+F9
{
g_uHalfScanLines = !g_uHalfScanLines;
SetVideoStyle( (VideoStyle_e) (GetVideoStyle() ^ VS_HALF_SCANLINES) );
}
// TODO: Clean up code:FrameRefreshStatus(DRAW_TITLE) DrawStatusArea((HDC)0,DRAW_TITLE)

View File

@ -1940,7 +1940,7 @@ void NTSC_SetVideoMode( uint32_t uVideoModeFlags )
//===========================================================================
void NTSC_SetVideoStyle() // (int v, int s)
{
int half = g_uHalfScanLines;
int half = IsVideoStyle(VS_HALF_SCANLINES);
uint8_t r, g, b;
switch ( g_eVideoType )

View File

@ -39,6 +39,7 @@ enum Color_Palette_Index_e
, HGR_GREEN // HCOLOR=1 GREEN , 2400: 02 00 2A 55
, HGR_VIOLET // HCOLOR=2 VIOLET , 2800: 01 00 55 2A
#endif
// TV emu
, HGR_GREY1
, HGR_GREY2
@ -206,88 +207,6 @@ static void V_CreateLookup_DoubleHires ()
//===========================================================================
#if 0
static void V_CreateLookup_Hires()
{
// int iMonochrome = GetMonochromeIndex();
// BYTE colorval[6] = {MAGENTA,BLUE,GREEN,ORANGE,BLACK,WHITE};
// BYTE colorval[6] = {HGR_MAGENTA,HGR_BLUE,HGR_GREEN,HGR_RED,HGR_BLACK,HGR_WHITE};
for (int iColumn = 0; iColumn < 16; iColumn++)
{
int coloffs = iColumn << 5;
for (unsigned iByte = 0; iByte < 256; iByte++)
{
int aPixels[11];
aPixels[ 0] = iColumn & 4;
aPixels[ 1] = iColumn & 8;
aPixels[ 9] = iColumn & 1;
aPixels[10] = iColumn & 2;
int nBitMask = 1;
int iPixel;
for (iPixel = 2; iPixel < 9; iPixel++) {
aPixels[iPixel] = ((iByte & nBitMask) != 0);
nBitMask <<= 1;
}
int hibit = ((iByte & 0x80) != 0);
int x = 0;
int y = iByte << 1;
while (x < 28)
{
int adj = (x >= 14) << 1;
int odd = (x >= 14);
for (iPixel = 2; iPixel < 9; iPixel++)
{
int color = CM_Black;
if (aPixels[iPixel])
{
if (aPixels[iPixel-1] || aPixels[iPixel+1])
color = CM_White;
else
color = ((odd ^ (iPixel&1)) << 1) | hibit;
}
else if (aPixels[iPixel-1] && aPixels[iPixel+1])
{
// Activate fringe reduction on white HGR text - drawback: loss of color mix patterns in HGR video mode.
// VT_COLOR_MONITOR_RGB = Fill in colors in between white pixels
// VT_COLOR_TVEMU = Fill in colors in between white pixels (Post Processing will mix/merge colors)
// VT_COLOR_TEXT_OPTIMIZED --> !(aPixels[iPixel-2] && aPixels[iPixel+2]) = Don't fill in colors in between white
if ((g_eVideoType == VT_COLOR_TVEMU) || !(aPixels[iPixel-2] && aPixels[iPixel+2]) )
color = ((odd ^ !(iPixel&1)) << 1) | hibit; // No white HGR text optimization
}
//if (g_eVideoType == VT_MONO_AUTHENTIC) {
// int nMonoColor = (color != CM_Black) ? iMonochrome : BLACK;
// SETSOURCEPIXEL(SRCOFFS_HIRES+coloffs+x+adj ,y , nMonoColor); // buggy
// SETSOURCEPIXEL(SRCOFFS_HIRES+coloffs+x+adj+1,y , nMonoColor); // buggy
// SETSOURCEPIXEL(SRCOFFS_HIRES+coloffs+x+adj ,y+1,BLACK); // BL
// SETSOURCEPIXEL(SRCOFFS_HIRES+coloffs+x+adj+1,y+1,BLACK); // BR
//} else
{
// Colors - Top/Bottom Left/Right
// cTL cTR
// cBL cBR
SETSOURCEPIXEL(SRCOFFS_HIRES+coloffs+x+adj ,y ,HiresToPalIndex[color]); // cTL
SETSOURCEPIXEL(SRCOFFS_HIRES+coloffs+x+adj+1,y ,HiresToPalIndex[color]); // cTR
SETSOURCEPIXEL(SRCOFFS_HIRES+coloffs+x+adj ,y+1,HiresToPalIndex[color]); // cBL
SETSOURCEPIXEL(SRCOFFS_HIRES+coloffs+x+adj+1,y+1,HiresToPalIndex[color]); // cBR
}
x += 2;
}
}
}
}
}
#endif
//===========================================================================
void V_CreateLookup_Lores()
{
for (int color = 0; color < 16; color++)
@ -484,6 +403,174 @@ Legend:
//===========================================================================
// For AppleWin 1.25 "tv emulation" HGR Video Mode
const UINT FRAMEBUFFER_W = 560;
const UINT FRAMEBUFFER_H = 384;
const UINT HGR_MATRIX_YOFFSET = 2;
static BYTE hgrpixelmatrix[FRAMEBUFFER_W/2][FRAMEBUFFER_H/2 + 2 * HGR_MATRIX_YOFFSET]; // 2 extra scan lines on bottom?
static BYTE colormixbuffer[6]; // 6 hires colours
static WORD colormixmap[6][6][6]; // top x middle x bottom
BYTE MixColors(BYTE c1, BYTE c2)
{
#define COMBINATION(c1,c2,ref1,ref2) (((c1)==(ref1)&&(c2)==(ref2)) || ((c1)==(ref2)&&(c2)==(ref1)))
if (c1 == c2)
return c1;
if (COMBINATION(c1,c2,HGR_BLUE,HGR_ORANGE))
return HGR_GREY1;
else if (COMBINATION(c1,c2,HGR_GREEN,HGR_VIOLET))
return HGR_GREY2;
else if (COMBINATION(c1,c2,HGR_ORANGE,HGR_GREEN))
return HGR_YELLOW;
else if (COMBINATION(c1,c2,HGR_BLUE,HGR_GREEN))
return HGR_AQUA;
else if (COMBINATION(c1,c2,HGR_BLUE,HGR_VIOLET))
return HGR_PURPLE;
else if (COMBINATION(c1,c2,HGR_ORANGE,HGR_VIOLET))
return HGR_PINK;
else
return WHITE; // visible failure indicator
#undef COMBINATION
}
static void CreateColorMixMap(void)
{
const int FROM_NEIGHBOUR = 0x00;
const int MIX_THRESHOLD = HGR_BLUE; // (skip) bottom 2 HGR colors
for (int t=0; t<6; t++) // Color_Palette_Index_e::HGR_BLACK(0) ... Color_Palette_Index_e::HGR_VIOLET(5)
{
for (int m=0; m<6; m++)
{
for (int b=0; b<6; b++)
{
BYTE cTop = t;
BYTE cMid = m;
BYTE cBot = b;
WORD mixTop, mixBot;
if (cMid < MIX_THRESHOLD)
{
mixTop = mixBot = cMid;
}
else
{
if (cTop < MIX_THRESHOLD)
mixTop = FROM_NEIGHBOUR;
else
mixTop = MixColors(cMid,cTop);
if (cBot < MIX_THRESHOLD)
mixBot = FROM_NEIGHBOUR;
else
mixBot = MixColors(cMid,cBot);
if (mixTop == FROM_NEIGHBOUR && mixBot != FROM_NEIGHBOUR)
mixTop = mixBot;
else if (mixBot == FROM_NEIGHBOUR && mixTop != FROM_NEIGHBOUR)
mixBot = mixTop;
else if (mixBot == FROM_NEIGHBOUR && mixTop == FROM_NEIGHBOUR)
mixBot = mixTop = cMid;
}
colormixmap[t][m][b] = (mixTop << 8) | mixBot;
}
}
}
}
static void MixColorsVertical(int matx, int maty)
{
int bot1idx, bot2idx;
if (VideoGetSWMIXED() && maty > 159)
{
if (maty < 161)
{
bot1idx = hgrpixelmatrix[matx][maty+1] & 0x0F;
bot2idx = 0;
}
else
{
bot1idx = bot2idx = 0;
}
}
else
{
bot1idx = hgrpixelmatrix[matx][maty+1] & 0x0F;
bot2idx = hgrpixelmatrix[matx][maty+2] & 0x0F;
}
WORD twoHalfPixel = colormixmap[hgrpixelmatrix[matx][maty-2] & 0x0F]
[hgrpixelmatrix[matx][maty-1] & 0x0F]
[hgrpixelmatrix[matx][maty ] & 0x0F];
colormixbuffer[0] = (twoHalfPixel & 0xFF00) >> 8;
colormixbuffer[1] = (twoHalfPixel & 0x00FF);
twoHalfPixel = colormixmap[hgrpixelmatrix[matx][maty-1] & 0x0F]
[hgrpixelmatrix[matx][maty ] & 0x0F]
[bot1idx];
colormixbuffer[2] = (twoHalfPixel & 0xFF00) >> 8;
colormixbuffer[3] = (twoHalfPixel & 0x00FF);
twoHalfPixel = colormixmap[hgrpixelmatrix[matx][maty ] & 0x0F]
[bot1idx]
[bot2idx];
colormixbuffer[4] = (twoHalfPixel & 0xFF00) >> 8;
colormixbuffer[5] = (twoHalfPixel & 0x00FF);
}
// NB. This operates at the 7M pixel level: 2 identical 14M pixels are written per inner loop (so no support for half-dot-shift, eg. Archon's title)
static void CopyMixedSource(int x, int y, int sourcex, int sourcey, bgra_t *pVideoAddress)
{
const BYTE* const currsourceptr = g_aSourceStartofLine[sourcey]+sourcex;
UINT32* const currdestptr = (UINT32*) pVideoAddress;
const int matx = x;
const int maty = HGR_MATRIX_YOFFSET + y;
const int hgrlinesabove = (y > 0) ? 1 : 0;
const int hgrlinesbelow = VideoGetSWMIXED() ? ((y < 159)? 1:0) : ((y < 191)? 1:0);
const int istart = 2 - (hgrlinesabove*2);
const int iend = 3 + (hgrlinesbelow*2);
// transfer 7 pixels (i.e. the visible part of an apple hgr-byte) from row to pixelmatrix
for (int count = 0, bufxoffset = 0; count < 7; count++, bufxoffset += 2)
{
hgrpixelmatrix[matx+count][maty] = *(currsourceptr+bufxoffset);
// color mixing between adjacent scanlines at current x position
MixColorsVertical(matx+count, maty);
// transfer up to 6 mixed (half-)pixels of current column to framebuffer
UINT32* currptr = currdestptr+bufxoffset;
if (hgrlinesabove)
currptr += GetFrameBufferWidth() * 2;
for (int i = istart; i <= iend; currptr -= GetFrameBufferWidth(), i++)
{
if (IsVideoStyle(VS_HALF_SCANLINES) && (i & 1))
{
// 50% Half Scan Line clears every odd scanline (and SHIFT+PrintScreen saves only the even rows)
*currptr = *(currptr+1) = 0;
}
else
{
_ASSERT( colormixbuffer[i] < (sizeof(PalIndex2RGB)/sizeof(PalIndex2RGB[0])) );
const RGBQUAD& rRGB = PalIndex2RGB[ colormixbuffer[i] ];
const UINT32 rgb = (((UINT32)rRGB.rgbRed)<<16) | (((UINT32)rRGB.rgbGreen)<<8) | ((UINT32)rRGB.rgbBlue);
*currptr = *(currptr+1) = rgb;
}
}
}
}
//===========================================================================
// Pre: nSrcAdjustment: for 160-color images, src is +1 compared to dst
static void CopySource(int w, int h, int sx, int sy, bgra_t *pVideoAddress, const int nSrcAdjustment = 0)
{
@ -498,7 +585,7 @@ static void CopySource(int w, int h, int sx, int sy, bgra_t *pVideoAddress, cons
{
--nBytes;
if (g_uHalfScanLines && !(h & 1))
if (IsVideoStyle(VS_HALF_SCANLINES) && !(h & 1))
{
// 50% Half Scan Line clears every odd scanline (and SHIFT+PrintScreen saves only the even rows)
*(pDst+nBytes) = 0;
@ -527,16 +614,15 @@ void UpdateHiResCell (int x, int y, uint16_t addr, bgra_t *pVideoAddress)
BYTE byteval3 = (x < 39) ? *(pMain+1) : 0;
#define COLOFFS (((byteval1 & 0x60) << 2) | ((byteval3 & 0x03) << 5))
#if 0
if (g_eVideoType == VT_COLOR_TVEMU)
if (IsVideoStyle(VS_COLOR_VERTICAL_BLEND))
{
CopyMixedSource(
xpixel >> 1, (ypixel+(yoffset >> 9)) >> 1,
SRCOFFS_HIRES+COLOFFS+((x & 1) << 4), (((int)byteval2) << 1)
x*7, y,
SRCOFFS_HIRES+COLOFFS+((x & 1) << 4), (((int)byteval2) << 1),
pVideoAddress
);
}
else
#endif
{
CopySource(14,2, SRCOFFS_HIRES+COLOFFS+((x & 1) << 4), (((int)byteval2) << 1), pVideoAddress);
}
@ -700,13 +786,10 @@ static void V_CreateDIBSections(void)
ZeroMemory(g_pSourcePixels, SRCOFFS_TOTAL*MAX_SOURCE_Y); // 32 bytes/pixel * 16 colors = 512 bytes/row
V_CreateLookup_Lores();
// if ( g_eVideoType == VT_COLOR_TVEMU )
// V_CreateLookup_Hires();
// else
V_CreateLookup_HiResHalfPixel_Authentic(VT_COLOR_MONITOR_RGB);
V_CreateLookup_HiResHalfPixel_Authentic(VT_COLOR_MONITOR_RGB);
V_CreateLookup_DoubleHires();
CreateColorMixMap();
}
void VideoInitializeOriginal(baseColors_t pBaseNtscColors)

View File

@ -89,7 +89,7 @@ COLORREF g_nMonochromeRGB = RGB(0xC0,0xC0,0xC0);
uint32_t g_uVideoMode = VF_TEXT; // Current Video Mode (this is the last set one as it may change mid-scan line!)
DWORD g_eVideoType = VT_DEFAULT;
DWORD g_uHalfScanLines = 1; // drop 50% scan lines for a more authentic look
static VideoStyle_e g_eVideoStyle = VS_HALF_SCANLINES;
static const bool g_bVideoScannerNTSC = true; // NTSC video scanning (or PAL)
@ -1211,11 +1211,28 @@ enum VideoType127_e
void Config_Load_Video()
{
REGLOAD(TEXT(REGVALUE_VIDEO_MODE ),&g_eVideoType);
REGLOAD(TEXT(REGVALUE_VIDEO_HALF_SCAN_LINES),&g_uHalfScanLines);
REGLOAD(TEXT(REGVALUE_VIDEO_MONO_COLOR ),&g_nMonochromeRGB);
REGLOAD(TEXT(REGVALUE_VIDEO_MODE) ,&g_eVideoType);
REGLOAD(TEXT(REGVALUE_VIDEO_STYLE) ,(DWORD*)&g_eVideoStyle);
REGLOAD(TEXT(REGVALUE_VIDEO_MONO_COLOR),&g_nMonochromeRGB);
//
const UINT16* pOldVersion = GetOldAppleWinVersion();
if (pOldVersion[0] == 1 && pOldVersion[1] <= 28 && pOldVersion[2] <= 1)
{
DWORD halfScanLines = 0;
REGLOAD(TEXT(REGVALUE_VIDEO_HALF_SCAN_LINES),&halfScanLines);
if (halfScanLines)
g_eVideoStyle = (VideoStyle_e) ((DWORD)g_eVideoStyle | VS_HALF_SCANLINES);
else
g_eVideoStyle = (VideoStyle_e) ((DWORD)g_eVideoStyle & ~VS_HALF_SCANLINES);
REGSAVE(TEXT(REGVALUE_VIDEO_STYLE), g_eVideoStyle);
}
//
if (pOldVersion[0] == 1 && pOldVersion[1] <= 27 && pOldVersion[2] <= 13)
{
switch (g_eVideoType)
@ -1229,6 +1246,8 @@ void Config_Load_Video()
case VT127_MONO_WHITE: g_eVideoType = VT_MONO_WHITE; break;
default: g_eVideoType = VT_DEFAULT; break;
}
REGSAVE(TEXT(REGVALUE_VIDEO_MODE), g_eVideoType);
}
if (g_eVideoType >= NUM_VIDEO_MODES)
@ -1237,9 +1256,37 @@ void Config_Load_Video()
void Config_Save_Video()
{
REGSAVE(TEXT(REGVALUE_VIDEO_MODE ),g_eVideoType);
REGSAVE(TEXT(REGVALUE_VIDEO_HALF_SCAN_LINES),g_uHalfScanLines);
REGSAVE(TEXT(REGVALUE_VIDEO_MONO_COLOR ),g_nMonochromeRGB);
REGSAVE(TEXT(REGVALUE_VIDEO_MODE) ,g_eVideoType);
REGSAVE(TEXT(REGVALUE_VIDEO_STYLE) ,g_eVideoStyle);
REGSAVE(TEXT(REGVALUE_VIDEO_MONO_COLOR),g_nMonochromeRGB);
}
//===========================================================================
VideoType_e GetVideoType(void)
{
return (VideoType_e) g_eVideoType;
}
// TODO: Can only do this at start-up (mid-emulation requires a more heavy-weight video reinit)
void SetVideoType(VideoType_e newVideoType)
{
g_eVideoType = newVideoType;
}
VideoStyle_e GetVideoStyle(void)
{
return g_eVideoStyle;
}
void SetVideoStyle(VideoStyle_e newVideoStyle)
{
g_eVideoStyle = newVideoStyle;
}
bool IsVideoStyle(VideoStyle_e mask)
{
return (g_eVideoStyle & mask) != 0;
}
//===========================================================================

View File

@ -21,6 +21,14 @@
extern TCHAR g_aVideoChoices[];
extern char *g_apVideoModeDesc[ NUM_VIDEO_MODES ];
enum VideoStyle_e
{
VS_NONE=0,
VS_HALF_SCANLINES=1, // drop 50% scan lines for a more authentic look
VS_COLOR_VERTICAL_BLEND=2, // Color "TV Emu" rendering from AppleWin 1.25 (GH#616)
// VS_TEXT_OPTIMIZED=4,
};
enum VideoFlag_e
{
VF_80COL = 0x00000001,
@ -156,7 +164,6 @@ struct WinBmpHeader4_t
extern COLORREF g_nMonochromeRGB; // saved to Registry
extern uint32_t g_uVideoMode;
extern DWORD g_eVideoType; // saved to Registry
extern DWORD g_uHalfScanLines; // saved to Registry
extern uint8_t *g_pFramebufferbits;
// Prototypes _______________________________________________________
@ -212,3 +219,9 @@ bool IsVideoRom4K(void);
void Config_Load_Video(void);
void Config_Save_Video(void);
VideoType_e GetVideoType(void);
void SetVideoType(VideoType_e newVideoType);
VideoStyle_e GetVideoStyle(void);
void SetVideoStyle(VideoStyle_e newVideoStyle);
bool IsVideoStyle(VideoStyle_e mask);