+ Huge video unit rework for Amiga/MorphOS

* removed tons of Win32 unit leftovers, and other cleanups
  * cursor handling fixes, additions (like changing cursor shapes)
  * added initial support for sysmsgs

git-svn-id: trunk@11982 -
This commit is contained in:
Károly Balogh 2008-10-27 09:30:46 +00:00
parent 42871abdeb
commit 423aca9d63

View File

@ -22,9 +22,16 @@ uses
{$i videoh.inc} {$i videoh.inc}
{ Amiga specific calls, to help interaction between Keyboard, Mouse and
Video units, and Free Vision }
procedure GotCloseWindow;
function HasCloseWindow: boolean;
var var
videoWindow : pWindow; videoWindow : pWindow;
implementation implementation
uses uses
@ -45,57 +52,36 @@ var
videoPens : array[0..15] of longint; videoPens : array[0..15] of longint;
oldCursorX, oldCursorY: longint; oldCursorX, oldCursorY: longint;
visibleCursor: boolean; cursorType: word;
oldvisibleCursor: boolean; oldcursorType: word;
gotCloseWindowMsg: boolean;
procedure SysInitVideo; procedure SysInitVideo;
var counter: longint; var counter: longint;
begin begin
// writeln('sysinitvideo');
InitGraphicsLibrary; InitGraphicsLibrary;
InitIntuitionLibrary; InitIntuitionLibrary;
{
ScreenColor:=true; // fill videobuf and oldvideobuf with different bytes, to allow proper first draw
GetConsoleScreenBufferInfo(TextRec(Output).Handle, OrigConsoleInfo); FillDword(VideoBuf^,VideoBufSize Div 4,$1234D3AD);
GetConsoleCursorInfo(TextRec(Output).Handle, OrigConsoleCursorInfo); FillDword(OldVideoBuf^,VideoBufSize Div 4,$4321BEEF);
OrigCP := GetConsoleCP;
ConsoleInfo:=OrigConsoleInfo;
ConsoleCursorInfo:=OrigConsoleCursorInfo;
{
About the ConsoleCursorInfo record: There are 3 possible
structures in it that can be regarded as the 'screen':
- dwsize : contains the cols & row in current screen buffer.
- srwindow : Coordinates (relative to buffer) of upper left
& lower right corners of visible console.
- dmMaximumWindowSize : Maximal size of Screen buffer.
The first implementation of video used srWindow. After some
bug-reports, this was switched to dwMaximumWindowSize.
}
with ConsoleInfo.dwMaximumWindowSize do
begin
ScreenWidth:=X;
ScreenHeight:=Y;
end;
{ TDrawBuffer only has FVMaxWidth elements
larger values lead to crashes }
if ScreenWidth> FVMaxWidth then
ScreenWidth:=FVMaxWidth;
CursorX:=ConsoleInfo.dwCursorPosition.x;
CursorY:=ConsoleInfo.dwCursorPosition.y;
if not ConsoleCursorInfo.bvisible then
CursorLines:=0
else
CursorLines:=ConsoleCursorInfo.dwSize;
}
videoWindow:=OpenWindowTags(Nil, [ videoWindow:=OpenWindowTags(Nil, [
WA_Left,50, WA_Left,50,
WA_Top,50, WA_Top,50,
WA_InnerWidth,80*8, WA_InnerWidth,80*8,
WA_InnerHeight,25*16, WA_InnerHeight,25*16,
WA_MaxWidth,32768,
WA_MaxHeight,32768,
// WA_IDCMP,IDCMP_MOUSEBUTTONS Or IDCMP_RAWKEYS, // WA_IDCMP,IDCMP_MOUSEBUTTONS Or IDCMP_RAWKEYS,
WA_IDCMP,IDCMP_VANILLAKEY Or IDCMP_RAWKEY, WA_IDCMP,IDCMP_VANILLAKEY Or IDCMP_RAWKEY Or
IDCMP_CLOSEWINDOW,
WA_Title,DWord(PChar('Free Pascal Video Output')), WA_Title,DWord(PChar('Free Pascal Video Output')),
WA_Flags,(WFLG_GIMMEZEROZERO Or WFLG_SMART_REFRESH Or WFLG_NOCAREREFRESH Or WFLG_ACTIVATE Or WFLG_DRAGBAR Or WFLG_DEPTHGADGET) WA_Flags,(WFLG_GIMMEZEROZERO Or WFLG_SMART_REFRESH Or WFLG_NOCAREREFRESH Or
WFLG_ACTIVATE Or WFLG_DRAGBAR Or WFLG_DEPTHGADGET Or
// WFLG_SIZEGADGET Or WFLG_SIZEBBOTTOM Or
WFLG_CLOSEGADGET)
]); ]);
ScreenWidth := 80; ScreenWidth := 80;
@ -115,8 +101,10 @@ begin
CursorY:=0; CursorY:=0;
oldCursorX:=0; oldCursorX:=0;
oldCursorY:=0; oldCursorY:=0;
visibleCursor:=true; cursorType:=crHidden;
oldvisibleCursor:=true; oldcursorType:=crHidden;
gotCloseWindowMsg:=false;
end; end;
@ -125,101 +113,18 @@ var counter: longint;
begin begin
if videoWindow<>nil then CloseWindow(videoWindow); if videoWindow<>nil then CloseWindow(videoWindow);
for counter:=0 to 15 do ReleasePen(videoColorMap,videoPens[counter]); for counter:=0 to 15 do ReleasePen(videoColorMap,videoPens[counter]);
{
SetConsoleScreenBufferSize (TextRec (Output).Handle, OrigConsoleInfo.dwSize);
SetConsoleWindowInfo (cardinal (TextRec (Output).Handle), true, OrigConsoleInfo.srWindow);
SetConsoleCursorInfo(TextRec(Output).Handle, OrigConsoleCursorInfo);
SetConsoleCP(OrigCP);
}
end; end;
function SysVideoModeSelector (const VideoMode: TVideoMode): boolean; function SysSetVideoMode (Const Mode : TVideoMode) : Boolean;
{ var
var MI: Console_Screen_Buffer_Info;
C: Coord;
SR: Small_Rect;
}
begin
{
if not (GetConsoleScreenBufferInfo (TextRec (Output).Handle, MI)) then
SysVideoModeSelector := false
else
begin
with MI do
begin
C.X := VideoMode.Col;
C.Y := VideoMode.Row;
end;
with SR do
begin
Top := 0;
Left := 0;
{ First, we need to make sure we reach the minimum window size
to always fit in the new buffer after changing buffer size. }
Right := MI.srWindow.Right - MI.srWindow.Left;
if VideoMode.Col <= Right then
Right := Pred (VideoMode.Col);
Bottom := MI.srWindow.Bottom - MI.srWindow.Top;
if VideoMode.Row <= Bottom then
Bottom := Pred (VideoMode.Row);
end;
if SetConsoleWindowInfo (cardinal (TextRec (Output).Handle), true, SR) then
if SetConsoleScreenBufferSize (TextRec (Output).Handle, C) then
begin
with SR do
begin
{ Now, we can resize the window to the final size. }
Right := Pred (VideoMode.Col);
Bottom := Pred (VideoMode.Row);
end;
if SetConsoleWindowInfo (cardinal (TextRec (Output).Handle), true, SR) then
begin
SysVideoModeSelector := true;
SetCursorType (LastCursorType);
ClearScreen;
end
else
begin
SysVideoModeSelector := false;
SetConsoleScreenBufferSize (TextRec (Output).Handle, MI.dwSize);
SetConsoleWindowInfo (cardinal (TextRec (Output).Handle), true, MI.srWindow);
SetCursorType (LastCursorType);
end
end
else
begin
SysVideoModeSelector := false;
SetConsoleWindowInfo (cardinal (TextRec (Output).Handle), true, MI.srWindow);
SetCursorType (LastCursorType);
end
else
SysVideoModeSelector := false;
end;
}
end;
Const
SysVideoModeCount = 6;
SysVMD : Array[0..SysVideoModeCount-1] of TVideoMode = (
(Col: 40; Row: 25; Color: True),
(Col: 80; Row: 25; Color: True),
(Col: 80; Row: 30; Color: True),
(Col: 80; Row: 43; Color: True),
(Col: 80; Row: 50; Color: True),
(Col: 80; Row: 25; Color: True) // Reserved for TargetEntry
);
Function SysSetVideoMode (Const Mode : TVideoMode) : Boolean;
Var
I : Integer; I : Integer;
begin begin
{
I:=SysVideoModeCount-1; I:=SysVideoModeCount-1;
SysSetVideoMode:=False; SysSetVideoMode:=False;
While (I>=0) and Not SysSetVideoMode do While (I>=0) and Not SysSetVideoMode do
@ -238,21 +143,9 @@ begin
ScreenColor:=SysVMD[I].Color; ScreenColor:=SysVMD[I].Color;
end else SysSetVideoMode := false; end else SysSetVideoMode := false;
end; end;
}
end; end;
Function SysGetVideoModeData (Index : Word; Var Data : TVideoMode) : boolean;
begin
SysGetVideoModeData:=(Index<=high(SysVMD));
If SysGetVideoModeData then
Data:=SysVMD[Index];
end;
Function SysGetVideoModeCount : Word;
begin
SysGetVideoModeCount:=SysVideoModeCount;
end;
procedure SysClearScreen; procedure SysClearScreen;
begin begin
@ -260,7 +153,7 @@ begin
end; end;
procedure DrawChar(x,y: longint; bitmap: pBitmap; drawCursor: boolean); procedure DrawChar(x,y: longint; crType: word);
var tmpCharData: word; var tmpCharData: word;
tmpChar : byte; tmpChar : byte;
tmpFGColor : byte; tmpFGColor : byte;
@ -277,11 +170,18 @@ begin
sX:=x*8; sX:=x*8;
sY:=y*16; sY:=y*16;
SetAPen(videoWindow^.Rport,videoPens[tmpFGColor]); if crType <> crBlock then begin
SetBPen(videoWindow^.RPort,videoPens[tmpBGColor]); SetABPenDrMd(videoWindow^.RPort,videoPens[tmpFGColor],videoPens[tmpBGColor],JAM2);
end else begin
{ in case of block cursor, swap fg/bg colors
and BltTemplate() below will take care of everything }
SetABPenDrMd(videoWindow^.RPort,videoPens[tmpBGColor],videoPens[tmpFGColor],JAM2);
end;
BltTemplate(@vgafont[tmpChar,0],0,1,videoWindow^.RPort,sX,sY,8,16); BltTemplate(@vgafont[tmpChar,0],0,1,videoWindow^.RPort,sX,sY,8,16);
if drawCursor then begin if crType = crUnderLine then begin
{ draw two lines at the bottom of the char, in case of underline cursor }
gfxMove(videoWindow^.RPort,sX,sY+14); Draw(videoWindow^.RPort,sX+7,sY+14); gfxMove(videoWindow^.RPort,sX,sY+14); Draw(videoWindow^.RPort,sX+7,sY+14);
gfxMove(videoWindow^.RPort,sX,sY+15); Draw(videoWindow^.RPort,sX+7,sY+15); gfxMove(videoWindow^.RPort,sX,sY+15); Draw(videoWindow^.RPort,sX+7,sY+15);
end; end;
@ -292,11 +192,12 @@ procedure SysUpdateScreen(force: boolean);
var var
BufCounter : Longint; BufCounter : Longint;
smallforce : boolean; smallforce : boolean;
cursormoved : boolean;
counter, counterX, counterY: longint; counter, counterX, counterY: longint;
var
tmpBitmap : tBitmap;
begin begin
smallforce:=false;
cursormoved:=false;
if force then if force then
smallforce:=true smallforce:=true
else begin else begin
@ -312,21 +213,23 @@ begin
for counterY:=0 to ScreenHeight-1 do begin for counterY:=0 to ScreenHeight-1 do begin
for counterX:=0 to ScreenWidth-1 do begin for counterX:=0 to ScreenWidth-1 do begin
if VideoBuf^[BufCounter]<>OldVideoBuf^[BufCounter] then if VideoBuf^[BufCounter]<>OldVideoBuf^[BufCounter] then
DrawChar(counterX,counterY,@tmpBitmap,false); DrawChar(counterX,counterY,crHidden);
Inc(BufCounter); Inc(BufCounter);
end; end;
end; end;
move(VideoBuf^,OldVideoBuf^,VideoBufSize); move(VideoBuf^,OldVideoBuf^,VideoBufSize);
end; end;
if (oldvisibleCursor<>visibleCursor) or (CursorX<>oldCursorX) or (CursorY<>oldCursorY) then begin if (cursorType<>oldcursorType) or
writeln('kurzor:',cursorx,' ',cursory); (CursorX<>oldCursorX) or (CursorY<>oldCursorY) or
DrawChar(oldCursorY,oldCursorX,@tmpBitmap,false); smallforce then begin
DrawChar(CursorY,CursorX,@tmpBitmap,visibleCursor); DrawChar(oldCursorY,oldCursorX,crHidden);
DrawChar(CursorY,CursorX,cursorType);
oldCursorX:=CursorX; oldCursorX:=CursorX;
oldCursorY:=CursorY; oldCursorY:=CursorY;
oldVisibleCursor:=visibleCursor; oldcursorType:=cursorType;
end; end;
end; end;
@ -344,53 +247,32 @@ end;
function SysGetCursorType: Word; function SysGetCursorType: Word;
begin begin
if not visibleCursor then SysGetCursorType:=crHidden SysGetCursorType:=cursorType;
else SysGetCursorType:=crUnderline;
{
GetConsoleCursorInfo(TextRec(Output).Handle,ConsoleCursorInfo);
if not ConsoleCursorInfo.bvisible then
SysGetCursorType:=crHidden
else
case ConsoleCursorInfo.dwSize of
1..30:
SysGetCursorType:=crUnderline;
31..70:
SysGetCursorType:=crHalfBlock;
71..100:
SysGetCursorType:=crBlock;
end;
}
end; end;
procedure SysSetCursorType(NewType: Word); procedure SysSetCursorType(NewType: Word);
begin begin
if newType=crHidden then visibleCursor:=false cursorType:=newType;
else visibleCursor:=true; { FIXME: halfBlock cursors are not supported for now
by the rendering code }
if cursorType = crHalfBlock then cursorType:=crBlock;
SysUpdateScreen(false); SysUpdateScreen(false);
{ end;
GetConsoleCursorInfo(TextRec(Output).Handle,ConsoleCursorInfo);
if newType=crHidden then
ConsoleCursorInfo.bvisible:=false // Amiga specific calls
else procedure GotCloseWindow;
begin begin
ConsoleCursorInfo.bvisible:=true; gotCloseWindowMsg:=true;
case NewType of
crUnderline:
ConsoleCursorInfo.dwSize:=10;
crHalfBlock:
ConsoleCursorInfo.dwSize:=50;
crBlock:
ConsoleCursorInfo.dwSize:=99;
end
end;
SetConsoleCursorInfo(TextRec(Output).Handle,ConsoleCursorInfo);
}
end; end;
function HasCloseWindow: boolean;
begin
HasCloseWindow:=gotCloseWindowMsg;
gotCloseWindowMsg:=false;
end;
const const
@ -400,13 +282,12 @@ const
UpdateScreen : @SysUpdateScreen; UpdateScreen : @SysUpdateScreen;
ClearScreen : @SysClearScreen; ClearScreen : @SysClearScreen;
SetVideoMode : @SysSetVideoMode; SetVideoMode : @SysSetVideoMode;
GetVideoModeCount : @SysGetVideoModeCount; GetVideoModeCount : nil;
GetVideoModeData : @SysGetVideoModeData; GetVideoModeData : nil;
SetCursorPos : @SysSetCursorPos; SetCursorPos : @SysSetCursorPos;
GetCursorType : @SysGetCursorType; GetCursorType : @SysGetCursorType;
SetCursorType : @SysSetCursorType; SetCursorType : @SysSetCursorType;
GetCapabilities : @SysGetCapabilities GetCapabilities : @SysGetCapabilities
); );