123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428 |
- {
- This file is part of the Free Pascal run time library.
- Copyright (c) 2006 by Karoly Balogh
- member of the Free Pascal development team
- Video unit for Amiga and MorphOS
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- unit Video;
- interface
- uses
- intuition;
- {$i videoh.inc}
- var
- videoWindow : pWindow;
- implementation
- uses
- // dos
- exec,graphics;
- {$i video.inc}
- {$i videodata.inc}
- const
- LastCursorType: word = crUnderline;
- OrigScreen: PVideoBuf = nil;
- OrigScreenSize: cardinal = 0;
- var
- videoColorMap : pColorMap;
- videoPens : array[0..15] of longint;
- oldCursorX, oldCursorY: longint;
- visibleCursor: boolean;
- oldvisibleCursor: boolean;
- procedure SysInitVideo;
- var counter: longint;
- begin
- writeln('sysinitvideo');
- InitGraphicsLibrary;
- InitIntuitionLibrary;
- {
- ScreenColor:=true;
- GetConsoleScreenBufferInfo(TextRec(Output).Handle, OrigConsoleInfo);
- GetConsoleCursorInfo(TextRec(Output).Handle, OrigConsoleCursorInfo);
- 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, [
- WA_Left,50,
- WA_Top,50,
- WA_InnerWidth,80*8,
- WA_InnerHeight,25*16,
- // WA_IDCMP,IDCMP_MOUSEBUTTONS Or IDCMP_RAWKEYS,
- WA_IDCMP,IDCMP_VANILLAKEY Or IDCMP_RAWKEY,
- 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)
- ]);
- ScreenWidth := 80;
- ScreenHeight := 25;
- videoColorMap := pScreen(videoWindow^.WScreen)^.ViewPort.ColorMap;
- for counter:=0 to 15 do begin
- videoPens[counter]:=ObtainPen(videoColorMap,-1,
- vgacolors[counter,0] shl 24,vgacolors[counter,1] shl 24,vgacolors[counter,2] shl 24,
- PEN_EXCLUSIVE);
- // writeln(videoPens[counter]);
- // XXX: do checks for -1 colors (KB)
- end;
- CursorX:=0;
- CursorY:=0;
- oldCursorX:=0;
- oldCursorY:=0;
- visibleCursor:=true;
- oldvisibleCursor:=true;
- end;
- procedure SysDoneVideo;
- var counter: longint;
- begin
- if videoWindow<>nil then CloseWindow(videoWindow);
- 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;
- function SysVideoModeSelector (const VideoMode: TVideoMode): boolean;
- {
- 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;
- begin
- {
- I:=SysVideoModeCount-1;
- SysSetVideoMode:=False;
- While (I>=0) and Not SysSetVideoMode do
- If (Mode.col=SysVMD[i].col) and
- (Mode.Row=SysVMD[i].Row) and
- (Mode.Color=SysVMD[i].Color) then
- SysSetVideoMode:=True
- else
- Dec(I);
- If SysSetVideoMode then
- begin
- if SysVideoModeSelector(Mode) then
- begin
- ScreenWidth:=SysVMD[I].Col;
- ScreenHeight:=SysVMD[I].Row;
- ScreenColor:=SysVMD[I].Color;
- end else SysSetVideoMode := false;
- 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;
- begin
- UpdateScreen(true);
- end;
- procedure DrawChar(x,y: longint; bitmap: pBitmap; drawCursor: boolean);
- var tmpCharData: word;
- tmpChar : byte;
- tmpRow : byte;
- tmpFGColor : byte;
- tmpBGColor : byte;
- var
- counterX, counterY:longint;
- sX,sY: longint;
- begin
- tmpCharData:=VideoBuf^[y*ScreenWidth+x];
- tmpChar :=tmpCharData and $0ff;
- tmpFGColor :=(tmpCharData shr 8) and %00001111;
- tmpBGColor :=(tmpCharData shr 12) and %00000111;
-
- // write('"',char(tmpChar),'" ',tmpChar);
- sX:=x*8;
- sY:=y*16;
- SetAPen(videoWindow^.RPort,videoPens[tmpBGColor]);
- RectFill(videoWindow^.RPort, sX, sY, sX + 7, sY + 15);
- SetAPen(videoWindow^.Rport,videoPens[tmpFGColor]);
- for counterY:=0 to 15 do begin
- tmpRow:=vgafont[tmpChar,counterY];
- if (tmpRow>0) then begin
- for counterX:=0 to 7 do begin
- if ((tmpRow and (1 shl counterX)) > 0) then
- WritePixel(videoWindow^.RPort,sX+counterX,sY+counterY);
- end;
- end;
- end;
- if drawCursor then begin
- 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);
- end;
- end;
- procedure SysUpdateScreen(force: boolean);
- var
- BufCounter : Longint;
- smallforce : boolean;
- counter, counterX, counterY: longint;
- var
- tmpBitmap : tBitmap;
- begin
- if force then
- smallforce:=true
- else begin
- counter:=0;
- while not smallforce and (counter<(VideoBufSize div 4)-1) do begin
- if PDWord(VideoBuf)[counter]<>PDWord(OldVideoBuf)[counter] then smallforce:=true;
- counter+=1;
- end;
- end;
- BufCounter:=0;
- if smallforce then begin
- for counterY:=0 to ScreenHeight-1 do begin
- for counterX:=0 to ScreenWidth-1 do begin
- if VideoBuf^[BufCounter]<>OldVideoBuf^[BufCounter] then
- DrawChar(counterX,counterY,@tmpBitmap,false);
- Inc(BufCounter);
- end;
- end;
- move(VideoBuf^,OldVideoBuf^,VideoBufSize);
- end;
- if (oldvisibleCursor<>visibleCursor) or (CursorX<>oldCursorX) or (CursorY<>oldCursorY) then begin
- writeln('kurzor:',cursorx,' ',cursory);
- DrawChar(oldCursorY,oldCursorX,@tmpBitmap,false);
- DrawChar(CursorY,CursorX,@tmpBitmap,visibleCursor);
- oldCursorX:=CursorX;
- oldCursorY:=CursorY;
- oldVisibleCursor:=visibleCursor;
- end;
- end;
- procedure SysSetCursorPos(NewCursorX, NewCursorY: Word);
- begin
- CursorX:=NewCursorY;
- CursorY:=NewCursorX;
- SysUpdateScreen(false);
- end;
- function SysGetCapabilities: Word;
- begin
- SysGetCapabilities:=cpColor or cpChangeCursor;
- end;
- function SysGetCursorType: Word;
- begin
- if not visibleCursor then SysGetCursorType:=crHidden
- 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;
- procedure SysSetCursorType(NewType: Word);
- begin
- if newType=crHidden then visibleCursor:=false
- else visibleCursor:=true;
- SysUpdateScreen(false);
- {
- GetConsoleCursorInfo(TextRec(Output).Handle,ConsoleCursorInfo);
- if newType=crHidden then
- ConsoleCursorInfo.bvisible:=false
- else
- begin
- ConsoleCursorInfo.bvisible:=true;
- case NewType of
- crUnderline:
- ConsoleCursorInfo.dwSize:=10;
- crHalfBlock:
- ConsoleCursorInfo.dwSize:=50;
- crBlock:
- ConsoleCursorInfo.dwSize:=99;
- end
- end;
- SetConsoleCursorInfo(TextRec(Output).Handle,ConsoleCursorInfo);
- }
- end;
- const
- SysVideoDriver : TVideoDriver = (
- InitDriver : @SysInitVideo;
- DoneDriver : @SysDoneVideo;
- UpdateScreen : @SysUpdateScreen;
- ClearScreen : @SysClearScreen;
- SetVideoMode : @SysSetVideoMode;
- GetVideoModeCount : @SysGetVideoModeCount;
- GetVideoModeData : @SysGetVideoModeData;
- SetCursorPos : @SysSetCursorPos;
- GetCursorType : @SysGetCursorType;
- SetCursorType : @SysSetCursorType;
- GetCapabilities : @SysGetCapabilities
- );
- initialization
- SetVideoDriver(SysVideoDriver);
- end.
|