#define Uses_TEvent
#define Uses_TScreen
#define Uses_THardwareInfo
#include <tvision/tv.h>
#if !defined( __FLAT__ ) && !defined( __DOS_H )
#include <dos.h>
#endif // __DOS_H
ushort _NEAR TScreen::startupMode = 0xFFFF;
ushort _NEAR TScreen::startupCursor = 0;
ushort _NEAR TScreen::screenMode = 0;
ushort _NEAR TScreen::screenWidth = 0;
ushort _NEAR TScreen::screenHeight = 0;
Boolean _NEAR TScreen::hiResScreen = False;
Boolean _NEAR TScreen::checkSnow = True;
TScreenCell * _NEAR TScreen::screenBuffer;
ushort _NEAR TScreen::cursorLines = 0;
Boolean _NEAR TScreen::clearOnSuspend = True;
ushort TDisplay::getCursorType()
noexcept
{
#if defined( __FLAT__ )
return
THardwareInfo::getCaretSize();
#else
uchar start, end, base = 8;
ushort result;
_AH = 3;
_BH = 0;
videoInt();
start = _CH;
end = _CL;
if
( _CX == 0x2000 )
return
0;
if
( isEGAorVGA() )
{
_AX = 0x1130;
_BL = 0;
videoInt();
base = _CL;
}
start = (ushort) start * 100 / base;
end = (ushort) end * 100 / base;
result = (start << 8) + end;
return
result;
#endif
}
#if !defined( __FLAT__ )
int
TDisplay::isEGAorVGA(
void
)
{
_BL=0x10;
_AH=0x12;
videoInt();
return
_BL != 0x10;
}
#endif
void
TDisplay::setCursorType( ushort ct )
noexcept
{
#if defined( __FLAT__ )
THardwareInfo::setCaretSize( ct & 0xFF );
#else
uchar start, end, base = 8;
if
( ct == 0 )
_CX = 0x2000;
else
{
start = ct >> 8;
end = ct & 0xFF;
if
( isEGAorVGA() )
{
_AX = 0x1130;
_BL = 0;
videoInt();
base = _CL;
}
start = ((ushort) start * base + 50) / 100;
end = ((ushort) end * base + 50) / 100;
_CH = start;
_CL = end;
}
_AH = 1;
videoInt();
#endif
}
void
TDisplay::clearScreen( uchar w, uchar h )
noexcept
{
#if defined( __FLAT__ )
THardwareInfo::clearScreen( w, h );
#else
_BH = 0x07;
_CX = 0;
_DL = w;
_DH = h - 1;
_AX = 0x0600;
videoInt();
#endif
}
#pragma warn -asc
#if !defined( __FLAT__ )
void
TDisplay::videoInt()
{
I PUSH BP
I PUSH ES
I
INT
10h
I POP ES
I POP BP
}
#endif
#pragma warn .asc
ushort TDisplay::getRows()
noexcept
{
#if defined( __FLAT__ )
return
THardwareInfo::getScreenRows();
#else
_AX = 0x1130;
_BH = 0;
_DL = 0;
videoInt();
if
( _DL == 0 )
_DL = 24;
return
_DL + 1;
#endif
}
ushort TDisplay::getCols()
noexcept
{
#if defined( __FLAT__ )
return
THardwareInfo::getScreenCols();
#else
_AH = 0x0F;
videoInt();
return
_AH;
#endif
}
ushort TDisplay::getCrtMode()
noexcept
{
#if defined( __FLAT__ )
return
THardwareInfo::getScreenMode();
#else
_AH = 0x0F;
videoInt();
ushort mode = _AL;
if
( getRows() > 25 )
mode |= smFont8x8;
return
mode;
#endif
}
#pragma argsused
void
TDisplay::setCrtMode( ushort mode )
noexcept
{
#if defined( __FLAT__ )
THardwareInfo::setScreenMode( mode );
#else
ushort eflag = THardwareInfo::getBiosEquipmentFlag() & 0xFFCF;
eflag |= (mode == smMono) ? 0x30 : 0x20;
THardwareInfo::setBiosEquipmentFlag( eflag );
THardwareInfo::setBiosVideoInfo( THardwareInfo::getBiosVideoInfo() & 0x00FE );
_AH = 0;
_AL = mode;
videoInt();
if
( (mode & smFont8x8) != 0 )
{
_AX = 0x1112;
_BL = 0;
videoInt();
if
( getRows() > 25 )
{
THardwareInfo::setBiosVideoInfo( THardwareInfo::getBiosVideoInfo() | 1 );
_AH = 1;
_CX = 0x0607;
videoInt();
_AH = 0x12;
_BL = 0x20;
videoInt();
}
}
#endif
}
TScreen::TScreen()
noexcept
{
#if defined(__FLAT__)
THardwareInfo::setUpConsole();
#endif
startupMode = getCrtMode();
startupCursor = getCursorType();
#if defined(__FLAT__)
screenBuffer = THardwareInfo::allocateScreenBuffer();
#endif
setCrtData();
}
void
TScreen::resume()
noexcept
{
#if defined(__FLAT__)
THardwareInfo::setUpConsole();
#endif
startupMode = getCrtMode();
startupCursor = getCursorType();
if
(screenMode != startupMode)
setCrtMode( screenMode );
setCrtData();
}
TScreen::~TScreen()
{
suspend();
#if defined( __FLAT__ )
THardwareInfo::freeScreenBuffer( screenBuffer );
#endif
}
void
TScreen::suspend()
noexcept
{
if
( startupMode != screenMode )
setCrtMode( startupMode );
if
(clearOnSuspend)
clearScreen();
setCursorType( startupCursor );
#if defined(__FLAT__)
THardwareInfo::restoreConsole();
#endif
}
#pragma argsused
ushort TScreen::fixCrtMode( ushort mode )
noexcept
{
#ifdef __BORLANDC__
#if defined( __FLAT__ )
if
( THardwareInfo::getPlatform() != THardwareInfo::plDPMI32 )
{
mode = (mode & smFont8x8) ? smCO80 | smFont8x8 : smCO80;
return
mode;
}
#endif
if
( (mode & 0xFF) == smMono )
return
smMono;
if
( (mode & 0xFF) != smCO80 && (mode & 0xFF) != smBW80 )
mode = (mode & 0xFF00) | smCO80;
#endif
return
mode;
}
void
TScreen::setCrtData()
noexcept
{
screenMode = getCrtMode();
screenWidth = getCols();
screenHeight = getRows();
hiResScreen = Boolean(screenHeight > 25);
#if !defined(__FLAT__)
if
( screenMode == smMono )
{
screenBuffer = THardwareInfo::getMonoAddr();
checkSnow = False;
}
else
{
screenBuffer = THardwareInfo::getColorAddr();
if
( isEGAorVGA() )
checkSnow = False;
}
#endif
cursorLines = getCursorType();
setCursorType( 0 );
}
void
TScreen::clearScreen()
noexcept
{
TDisplay::clearScreen( screenWidth, screenHeight );
}
void
TScreen::flushScreen()
noexcept
{
#ifdef __FLAT__
THardwareInfo::flushScreen();
#endif
}
void
TScreen::setVideoMode( ushort mode )
noexcept
{
if
( mode != smUpdate )
setCrtMode( fixCrtMode( mode ) );
#ifdef __FLAT__
else
{
THardwareInfo::freeScreenBuffer( screenBuffer );
screenBuffer = THardwareInfo::allocateScreenBuffer();
}
#endif
setCrtData();
if
(TMouse::present())
TMouse::setRange( getCols()-1, getRows()-1 );
}