Amiga: special CRT unit (named vidcrt) based on video unit

git-svn-id: trunk@45197 -
This commit is contained in:
marcus 2020-04-30 19:28:45 +00:00
parent c6b0195c5f
commit 95ced4a7f5
3 changed files with 457 additions and 0 deletions
.gitattributes
packages/rtl-console
fpmake.pp
src/amicommon

1
.gitattributes vendored
View File

@ -8681,6 +8681,7 @@ packages/rtl-console/fpmake.pp svneol=native#text/plain
packages/rtl-console/src/amicommon/crt.pp svneol=native#text/plain
packages/rtl-console/src/amicommon/keyboard.pp svneol=native#text/plain
packages/rtl-console/src/amicommon/mouse.pp svneol=native#text/plain
packages/rtl-console/src/amicommon/vidcrt.pp svneol=native#text/pascal
packages/rtl-console/src/amicommon/video.pp svneol=native#text/plain
packages/rtl-console/src/amicommon/videodata.inc svneol=native#text/plain
packages/rtl-console/src/emx/crt.pp svneol=native#text/plain

View File

@ -110,6 +110,16 @@ begin
AddUnit ('keyboard',[win16]);
end;
T:=P.Targets.AddUnit('vidcrt.pp', AllAmigaLikeOSes);
with T.Dependencies do
begin
AddInclude('crth.inc');
AddInclude('crt.inc');
AddUnit ('video', AllAmigaLikeOSes);
AddUnit ('keyboard', AllAmigaLikeOSes);
AddUnit ('mouse', AllAmigaLikeOSes);
end;
T:=P.Targets.AddUnit('vesamode.pp',[go32v2,msdos]);
with T.Dependencies do
begin

View File

@ -0,0 +1,446 @@
unit vidcrt;
interface
uses
Classes, Video, sysutils,
mouse,
Types, Math, keyboard;
{$include crth.inc}
implementation
var
FGPen: Byte = 7;
BGPen: Byte = 0;
WinRect: TRect;
LastKeys: array[0..1] of Char;
LastKeysIdx: Integer = -1;
function PosToArray(px, py: Integer): Integer; inline;
begin
PosToArray := px + py * ScreenWidth;
end;
procedure SetChar(p: Integer; c: Char); overload;
begin
if (p >= 0) and (p < VideoBufSize) then
VideoBuf^[p] := (BGPen shl 12) or (FGPen shl 8) or Byte(c);
end;
procedure SetChar(x,y: Integer; c: Char); overload;
begin
SetChar(PosToArray(x,y), c);
end;
procedure ProcessKeyEvent(NKey: TKeyEvent);
var
c1: Char;
begin
c1 := GetKeyEventChar(NKey);
if c1 = #0 then
begin
LastKeys[1] := #0;
LastKeys[0] := Char((NKey shr 8) and $FF);
LastKeysIdx := 1;
case LastKeys[0] of
#28: begin LastKeys[0] := #13; LastKeysIdx := 0; end; // Enter
#01: begin LastKeys[0] := #27; LastKeysIdx := 0; end; // ESC
end;
end
else
begin
LastKeys[0] := c1;
LastKeysIdx := 0;
end;
end;
function KeyPressed: Boolean;
var
NKey: TKeyEvent;
begin
KeyPressed := False;
// Try to get a key if not already pressed one
if LastKeysIdx < 0 then
begin
NKey := PollKeyEvent;
if NKey <> 0 then
begin
ProcessKeyEvent(NKey);
end;
end;
// if last key is set, return that we have something
KeyPressed := LastKeysIdx <> 0;
end;
function ReadKey: Char;
var
NKey: TKeyEvent;
begin
ReadKey := #0;
if LastKeysIdx < 0 then
begin
repeat
NKey := GetKeyEvent;
if NKey <> 0 then
begin
ProcessKeyEvent(NKey);
end;
until NKey <> 0;
end;
if LastKeysIdx >= 0 then
begin
ReadKey := LastKeys[LastKeysIdx];
Dec(LastKeysIdx);
end;
end;
procedure TextMode (Mode: word);
begin
end;
procedure Window(X1,Y1,X2,Y2: Byte);
begin
x1 := EnsureRange(x1,1,256);
y1 := EnsureRange(y1,1,256);
x2 := EnsureRange(x2,x1,256);
y2 := EnsureRange(y2,y1,256);
WinRect := Rect(x1, y1, x2, y2);
WindMinX := WinRect.Left - 1;
WindMaxX := WinRect.Right - 1;
WindMinY := WinRect.Top - 1;
WindMaxY := WinRect.Bottom - 1;
WindMin := WindMinX or (WindMinY shl 8);
WindMax := WindMaxX or (WindMaxY shl 8);
GoToXY(1,1);
end;
procedure GotoXY(X,Y: tcrtcoord);
begin
SetCursorPos(x - 1, y - 1);
end;
function WhereX: tcrtcoord;
begin
WhereX := CursorX + 1;
end;
function WhereY: tcrtcoord;
begin
WhereY := CursorY + 1;
end;
procedure ClrScr;
var
y: Integer;
begin
for y := WinRect.Top to WinRect.Bottom do
begin
FillWord(VideoBuf^[PosToArray(WinRect.Left - 1, y - 1)], WinRect.Width + 1, (BGPen shl 12) or (FGPen shl 8));
end;
CursorX := 0;
CursorY := 0;
UpdateScreen(False);
end;
procedure ClrEol;
begin
FillWord(VideoBuf^[PosToArray(WinRect.Left + CursorX - 1, WinRect.Top + CursorY - 1)], WinRect.Width - CursorX, (BGPen shl 12) or (FGPen shl 8));
UpdateScreen(False);
end;
procedure InsLine;
var
AFrom, ATo, i: Integer;
begin
for i := WinRect.Bottom downto WinRect.Top + CursorY + 1 do
begin
AFrom := PosToArray(WinRect.Left - 1, i - 2);
ATo := PosToArray(WinRect.Left - 1, i - 1);
Move(VideoBuf^[AFrom], VideoBuf^[ATo], (WinRect.Width + 1) * SizeOf(Word));
end;
FillWord(VideoBuf^[PosToArray(WinRect.Left - 1, WinRect.Top + CursorY - 1)], WinRect.Width, (BGPen shl 12) or (FGPen shl 8));
UpdateScreen(False);
end;
procedure DelLine;
var
AFrom, ATo, i: Integer;
begin
for i := WinRect.Top + CursorY + 1 to WinRect.Bottom do
begin
AFrom := PosToArray(WinRect.Left - 1, i - 1);
ATo := PosToArray(WinRect.Left - 1, i - 2);
Move(VideoBuf^[AFrom], VideoBuf^[ATo], (WinRect.Width + 1) * SizeOf(Word));
end;
FillWord(VideoBuf^[PosToArray(WinRect.Left - 1, WinRect.Bottom - 1)], WinRect.Width, (BGPen shl 12) or (FGPen shl 8));
UpdateScreen(False);
end;
procedure TextColor(Color: Byte);
begin
if InRange(Color, 0, 15) then
FGPen := Color;
end;
procedure TextBackground(Color: Byte);
begin
if InRange(Color, 0, 7) then
BGPen := Color;
end;
procedure LowVideo;
begin
end;
procedure HighVideo;
begin
end;
procedure NormVideo;
begin
end;
procedure Delay(MS: Word);
begin
Sleep(ms);
end;
procedure Sound(Hz: Word);
begin
end;
procedure NoSound;
begin
end;
procedure cursoron;
begin
SetCursorType(crUnderline);
end;
procedure cursoroff;
begin
SetCursorType(crHidden);
end;
procedure cursorbig;
begin
SetCursorType(crBlock);
end;
procedure NextLine;
var
i, AFrom, ATo: Integer;
begin
Inc(CursorY);
if CursorY > WinRect.Height then
begin
for i := WinRect.Top to WinRect.Bottom - 1 do
begin
AFrom := PosToArray(WinRect.Left - 1, i);
ATo := PosToArray(WinRect.Left - 1, i - 1);
Move(VideoBuf^[AFrom], VideoBuf^[ATo], (WinRect.Width + 1) * SizeOf(Word));
end;
CursorY := WinRect.Height;
FillWord(VideoBuf^[PosToArray(WinRect.Left - 1, WinRect.Top - 1 + CursorY)], WinRect.Width + 1, (BGPen shl 12) or (FGPen shl 8));
end;
end;
procedure WriteChar(c: Char);
var
NX,NY: Integer;
begin
// ignore #13, we only use #10
case c of
#13: begin
//
end;
#10: begin
CursorX := 0;
NextLine;
end;
#7: begin
Beep;
Exit;
end;
#8: begin
if CursorX > 0 then
CursorX := CursorX - 1
end;
else
begin
// all other Chars
NX := (WinRect.Left - 1) + CursorX; // is zero based ... so both - 1
NY := (WinRect.Top - 1) + CursorY;
SetChar(NX, NY, c);
if CursorX >= WinRect.Width then
begin
CursorX := 0;
NextLine;
end
else
Inc(CursorX);
end;
end;
end;
procedure CrtWrite(Var F: TextRec);
var
i: Smallint;
begin
for i := 0 to f.BufPos - 1 do
WriteChar(F.Buffer[i]);
UpdateScreen(False);
F.BufPos := 0;
end;
Procedure CrtRead(Var F: TextRec);
var
ch : Char;
procedure BackSpace;
begin
if (f.bufpos>0) and (f.bufpos=f.bufend) then
begin
WriteChar(#8);
WriteChar(' ');
WriteChar(#8);
dec(f.bufpos);
dec(f.bufend);
end;
end;
Begin
f.bufpos:=0;
f.bufend:=0;
repeat
if f.bufpos > f.bufend then
f.bufend := f.bufpos;
ch := readkey;
case ch of
#0: begin
readkey;
Exit;
end;
^S,
#8: BackSpace;
^Y,
#27: begin
while f.bufpos < f.bufend do
begin
WriteChar(f.bufptr^[f.bufpos]);
Inc(f.bufpos);
end;
while f.bufend>0 do
BackSpace;
end;
#13: begin
WriteChar(#13);
WriteChar(#10);
f.bufptr^[f.bufend] := #13;
f.bufptr^[f.bufend + 1] := #10;
Inc(f.bufend, 2);
break;
end;
#26:
if CheckEOF then
begin
f.bufptr^[f.bufend] := #26;
Inc(f.bufend);
break;
end;
else
begin
if f.bufpos < f.bufsize - 2 then
begin
f.buffer[f.bufpos] := ch;
Inc(f.bufpos);
WriteChar(ch);
end;
end;
end;
UpdateScreen(False);
until False;
f.bufpos := 0;
End;
function CrtReturn (var F: TextRec): integer;
begin
CrtReturn:=0;
end;
procedure CrtClose(var F: TextRec);
begin
F.Mode:=fmClosed;
end;
procedure CrtOpen(var F: TextRec);
begin
if F.Mode = fmOutput then
begin
TextRec(F).InOutFunc := @CrtWrite;
TextRec(F).FlushFunc := @CrtWrite;
end
else
begin
F.Mode:=fmInput;
TextRec(F).InOutFunc:=@CrtRead;
TextRec(F).FlushFunc:=@CrtReturn;
end;
TextRec(F).CloseFunc := @CrtClose;
end;
procedure AssignCrt(var F: Text);
begin
Assign(F,'');
TextRec(F).OpenFunc:=@CrtOpen;
end;
procedure InitCRT;
begin
//
AssignCrt(Output);
Rewrite(Output);
TextRec(Output).Handle := StdOutputHandle;
//
AssignCrt(Input);
Reset(Input);
TextRec(Input).Handle := StdInputHandle;
end;
procedure FreeCRT;
begin
end;
initialization
InitVideo;
{$ifdef HASAMIGA}
SetWindowTitle(ExtractFileName(ParamStr(0)), 'CRT Window');
{$endif}
Window(1,1, ScreenWidth, ScreenHeight);
SetCursorType(crUnderLine);
//
InitMouse;
InitCRT;
//
InitKeyboard;
finalization
DoneKeyboard;
DoneMouse;
//
FreeCRT;
DoneVideo;
end.