123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346 |
- {
- $Id$
- System independent low-level video interface for win32
- Copyright (c) 1999 by Florian Klaempfl
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- This library 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. See the GNU
- Library General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- }
- uses
- windows,dos;
- var
- OldVideoBuf : PVideoBuf;
- ConsoleInfo : TConsoleScreenBufferInfo;
- ConsoleCursorInfo : TConsoleCursorInfo;
- MaxVideoBufSize : DWord;
- procedure InitVideo;
- begin
- ScreenColor:=true;
- GetConsoleScreenBufferInfo(TextRec(Output).Handle, ConsoleInfo);
- GetConsoleCursorInfo(TextRec(Output).Handle, ConsoleCursorInfo);
- with ConsoleInfo.srWindow do
- begin
- ScreenWidth:=right-left+1;
- ScreenHeight:=bottom-top+1;
- end;
- { srWindow is sometimes bigger then dwMaximumWindowSize
- this led to wrong ScreenWidth and ScreenHeight values PM }
- { damned: its also sometimes less !! PM }
- with ConsoleInfo.dwMaximumWindowSize do
- begin
- {if ScreenWidth>X then}
- ScreenWidth:=X;
- {if ScreenHeight>Y then}
- ScreenHeight:=Y;
- end;
- CursorX:=ConsoleInfo.dwCursorPosition.x;
- CursorY:=ConsoleInfo.dwCursorPosition.y;
- if not ConsoleCursorInfo.bvisible then
- CursorLines:=0
- else
- CursorLines:=ConsoleCursorInfo.dwSize;
- { allocate back buffer }
- MaxVideoBufSize:= ScreenWidth * ScreenHeight * 2;
- VideoBufSize:=ScreenWidth*ScreenHeight*2;
- GetMem(VideoBuf,MaxVideoBufSize);
- GetMem(OldVideoBuf,MaxVideoBufSize);
- {ClearScreen; not needed PM }
- end;
- procedure DoneVideo;
- begin
- { ClearScreen; also not needed PM }
- SetCursorType(crUnderLine);
- { SetCursorPos(0,0); also not needed PM }
- FreeMem(VideoBuf,MaxVideoBufSize);
- FreeMem(OldVideoBuf,MaxVideoBufSize);
- VideoBufSize:=0;
- end;
- function GetCapabilities: Word;
- begin
- GetCapabilities:=cpColor or cpChangeCursor;
- end;
- procedure SetCursorPos(NewCursorX, NewCursorY: Word);
- var
- pos : COORD;
- begin
- pos.x:=NewCursorX;
- pos.y:=NewCursorY;
- SetConsoleCursorPosition(TextRec(Output).Handle,pos);
- CursorX:=pos.x;
- CursorY:=pos.y;
- end;
- function GetCursorType: Word;
- begin
- GetConsoleCursorInfo(TextRec(Output).Handle,ConsoleCursorInfo);
- if not ConsoleCursorInfo.bvisible then
- GetCursorType:=crHidden
- else
- case ConsoleCursorInfo.dwSize of
- 1..30:
- GetCursorType:=crUnderline;
- 31..70:
- GetCursorType:=crHalfBlock;
- 71..100:
- GetCursorType:=crBlock;
- end;
- end;
- procedure SetCursorType(NewType: Word);
- begin
- 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;
- function DefaultVideoModeSelector(const VideoMode: TVideoMode; Params: Longint): Boolean;
- begin
- end;
- procedure ClearScreen;
- begin
- FillWord(VideoBuf^,VideoBufSize div 2,$0720);
- UpdateScreen(true);
- end;
- {$IFDEF FPC}
- function WriteConsoleOutput(hConsoleOutput:HANDLE; lpBuffer:pointer; dwBufferSize:COORD; dwBufferCoord:COORD;
- var lpWriteRegion:SMALL_RECT):WINBOOL; external 'kernel32' name 'WriteConsoleOutputA';
- {$ENDIF}
- procedure UpdateScreen(Force: Boolean);
- type TmpRec = Array[0..(1024*32) - 1] of TCharInfo;
- type WordRec = record
- One, Two: Byte;
- end; { wordrec }
- var
- BufSize,
- BufCoord : COORD;
- WriteRegion : SMALL_RECT;
- LineBuf : ^TmpRec;
- BufCounter : Longint;
- LineCounter,
- ColCounter : Longint;
- smallforce : boolean;
- {
- begin
- if LockUpdateScreen<>0 then
- exit;
- if not force then
- begin
- asm
- movl VideoBuf,%esi
- movl OldVideoBuf,%edi
- movl VideoBufSize,%ecx
- shrl $2,%ecx
- repe
- cmpsl
- orl %ecx,%ecx
- jz .Lno_update
- movb $1,force
- .Lno_update:
- end;
- end;
- if Force then
- begin
- BufSize.X := ScreenWidth;
- BufSize.Y := ScreenHeight;
- BufCoord.X := 0;
- BufCoord.Y := 0;
- with WriteRegion do
- begin
- Top :=0;
- Left :=0;
- Bottom := ScreenHeight-1;
- Right := ScreenWidth-1;
- end;
- New(LineBuf);
- BufCounter := 0;
- for LineCounter := 1 to ScreenHeight do
- begin
- for ColCounter := 1 to ScreenWidth do
- begin
- LineBuf^[BufCounter].UniCodeChar := WordRec(VideoBuf^[BufCounter]).One;
- LineBuf^[BufCounter].Attributes := WordRec(VideoBuf^[BufCounter]).Two;
- Inc(BufCounter);
- end; { for }
- end; { for }
- WriteConsoleOutput(TextRec(Output).Handle, LineBuf, BufSize, BufCoord, WriteRegion);
- Dispose(LineBuf);
- move(VideoBuf^,OldVideoBuf^,VideoBufSize);
- end;
- end;
- }
- var
- x1,y1,x2,y2 : longint;
- begin
- if LockUpdateScreen<>0 then
- exit;
- if force then
- smallforce:=true
- else
- begin
- asm
- movl VideoBuf,%esi
- movl OldVideoBuf,%edi
- movl VideoBufSize,%ecx
- shrl $2,%ecx
- repe
- cmpsl
- orl %ecx,%ecx
- jz .Lno_update
- movb $1,smallforce
- .Lno_update:
- end;
- end;
- if SmallForce then
- begin
- BufSize.X := ScreenWidth;
- BufSize.Y := ScreenHeight;
- BufCoord.X := 0;
- BufCoord.Y := 0;
- with WriteRegion do
- begin
- Top :=0;
- Left :=0;
- Bottom := ScreenHeight-1;
- Right := ScreenWidth-1;
- end;
- New(LineBuf);
- BufCounter := 0;
- x1:=ScreenWidth+1;
- x2:=-1;
- y1:=ScreenHeight+1;
- y2:=-1;
- for LineCounter := 1 to ScreenHeight do
- begin
- for ColCounter := 1 to ScreenWidth do
- begin
- if (WordRec(VideoBuf^[BufCounter]).One<>WordRec(OldVideoBuf^[BufCounter]).One) or
- (WordRec(VideoBuf^[BufCounter]).Two<>WordRec(OldVideoBuf^[BufCounter]).Two) then
- begin
- if ColCounter<x1 then
- x1:=ColCounter;
- if ColCounter>x2 then
- x2:=ColCounter;
- if LineCounter<y1 then
- y1:=LineCounter;
- if LineCounter>y2 then
- y2:=LineCounter;
- end;
- LineBuf^[BufCounter].UniCodeChar := WordRec(VideoBuf^[BufCounter]).One;
- { If (WordRec(VideoBuf^[BufCounter]).Two and $80)<>0 then
- LineBuf^[BufCounter].Attributes := $100+WordRec(VideoBuf^[BufCounter]).Two
- else }
- LineBuf^[BufCounter].Attributes := WordRec(VideoBuf^[BufCounter]).Two;
- Inc(BufCounter);
- end; { for }
- end; { for }
- BufSize.X := ScreenWidth;
- BufSize.Y := ScreenHeight;
- with WriteRegion do
- begin
- if force then
- begin
- Top := 0;
- Left :=0;
- Bottom := ScreenHeight-1;
- Right := ScreenWidth-1;
- BufCoord.X := 0;
- BufCoord.Y := 0;
- end
- else
- begin
- Top := y1-1;
- Left :=x1-1;
- Bottom := y2-1;
- Right := x2-1;
- BufCoord.X := x1-1;
- BufCoord.Y := y1-1;
- end;
- end;
- {
- writeln('X1: ',x1);
- writeln('Y1: ',y1);
- writeln('X2: ',x2);
- writeln('Y2: ',y2);
- }
- WriteConsoleOutput(TextRec(Output).Handle, LineBuf, BufSize, BufCoord, WriteRegion);
- Dispose(LineBuf);
- move(VideoBuf^,OldVideoBuf^,VideoBufSize);
- end;
- end;
- procedure RegisterVideoModes;
- begin
- { don't know what to do for win32 (FK) }
- RegisterVideoMode(80, 25, True, @DefaultVideoModeSelector, $00000003);
- end;
- {
- $Log$
- Revision 1.2 2000-07-13 11:32:27 michael
- + removed logs
-
- }
|