123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436 |
- {
- $Id$
- This file is part of the Free Pascal run time library.
- Copyright (c) 1998-2000 by the Free Pascal development team
- This include implements video mode management.
- 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.
- **********************************************************************}
- {-----------------------------------------------------------------------}
- { Internal routines }
- {-----------------------------------------------------------------------}
- procedure addmode(mode: TModeInfo);
- {********************************************************}
- { Procedure AddMode() }
- {--------------------------------------------------------}
- { This routine adds <mode> to the list of recognized }
- { modes. Duplicates are allowed. }
- {********************************************************}
- var
- list: PModeInfo;
- newlst : PModeInfo;
- begin
- if not assigned(ModeList) then
- begin
- new(ModeList);
- move(mode, ModeList^, sizeof(Mode));
- end
- else
- begin
- list := ModeList;
- { go to the end of the list }
- while assigned(list^.next) do
- list:=list^.next;
- new(NewLst);
- list^.next := NewLst;
- move(mode, NewLst^, sizeof(Mode));
- end;
- end;
- procedure initmode(var mode: TModeInfo);
- {********************************************************}
- { Procedure InitMode() }
- {--------------------------------------------------------}
- { This routine initialized the mode to default values. }
- {********************************************************}
- begin
- FillChar(mode,sizeof(Mode),#0);
- end;
- function searchmode(ReqDriver : smallint; var reqmode: smallint): PModeInfo;
- {********************************************************}
- { Procedure SearchMode() }
- {--------------------------------------------------------}
- { This routine searches the list of recognized modes, }
- { and tries to find the <reqmode> in the <reqdriver> }
- { return nil if not found, otherwise returns the found }
- { structure. }
- { note: if reqmode = -32768, the first mode available }
- { for reqdriver is returned (JM) }
- {********************************************************}
- var
- list, lastModeInfo: PModeInfo;
- begin
- {$ifdef logging}
- LogLn('Searching for driver '+strf(reqdriver)+' and mode '+strf(reqmode));
- {$endif logging}
- searchmode := nil;
- list := ModeList;
- If assigned(list) then
- lastModeInfo := list;
- { go to the end of the list }
- while assigned(list) do
- begin
- {$ifdef logging}
- Log('Found driver '+strf(list^.DriverNumber)+
- ' and mode $'+hexstr(list^.ModeNumber,4)+'... ');
- {$endif logging}
- if ((list^.DriverNumber = ReqDriver) and
- ((list^.ModeNumber = ReqMode) or
- { search for lowest mode }
- (reqMode = -32768))) or
- { search for highest mode }
- ((reqMode = -32767) and
- (lastModeInfo^.driverNumber = reqDriver) and
- ((list^.driverNumber <> lastModeInfo^.driverNumber) or
- not(assigned(list^.next)))) then
- begin
- {$ifdef logging}
- LogLn('Accepted!');
- {$endif logging}
- searchmode := list;
- If reqMode = -32768 then
- reqMode := list^.modeNumber
- else if reqMode = -32767 then
- begin
- reqMode := lastModeInfo^.modeNumber;
- searchMode := lastModeInfo;
- end;
- exit;
- end;
- {$ifdef logging}
- LogLn('Rejected.');
- {$endif logging}
- lastModeInfo := list;
- list:=list^.next;
- end;
- end;
- {-----------------------------------------------------------------------}
- { External routines }
- {-----------------------------------------------------------------------}
- function GetModeName(ModeNumber: smallint): string;
- {********************************************************}
- { Function GetModeName() }
- {--------------------------------------------------------}
- { Checks the known video list, and returns ModeName }
- { string. On error returns an empty string. }
- {********************************************************}
- var
- mode: PModeInfo;
- begin
- mode:=nil;
- GetModeName:='';
- { only search in the current driver modes ... }
- mode:=SearchMode(IntCurrentDriver,ModeNumber);
- if assigned(mode) then
- GetModeName:=Mode^.ModeName
- else
- _GraphResult := grInvalidMode;
- end;
- function GetGraphMode: smallint;
- begin
- GetGraphMode := IntCurrentMode;
- end;
- function GetMaxMode: word;
- { I know , i know, this routine is very slow, and it would }
- { be much easier to sort the linked list of possible modes }
- { instead of doing this, but I'm lazy!! And anyways, the }
- { speed of the routine here is not that important.... }
- var
- i: word;
- mode: PModeInfo;
- begin
- mode:=nil;
- i:=0;
- repeat
- inc(i);
- { mode 0 always exists... }
- { start search at 1.. }
- mode:=SearchMode(IntCurrentDriver,i);
- until not assigned(mode);
- GetMaxMode:=i;
- end;
- procedure GetModeRange(GraphDriver: smallint; var LoMode,
- HiMode: smallint);
- var
- mode : PModeInfo;
- begin
- {$ifdef logging}
- LogLn('GetModeRange : Enter ('+strf(GraphDriver)+')');
- {$endif}
- HiMode:=-1;
- mode := nil;
- { First search if the graphics driver is supported .. }
- { since mode zero is always supported.. if that driver }
- { is supported it should return something... }
- { not true, e.g. VESA doesn't have a mode 0. Changed so}
- { -32768 means "return lowest mode in second parameter }
- { also, under VESA some modes may not be supported }
- { (e.g. $108 here) while some with a higher number can }
- { be supported ($112 and onward), so I also added that }
- { -32767 means "return highest mode in second parameter}
- { This whole system should be overhauled though to work}
- { without such hacks (JM) }
- loMode := -32768;
- mode := SearchMode(GraphDriver, loMode);
- { driver not supported...}
- if not assigned(mode) then
- begin
- loMode := -1;
- exit;
- end;
- {$ifdef logging}
- LogLn('GetModeRange : Mode 0 found');
- {$endif}
- { now it exists... find highest available mode... }
- hiMode := -32767;
- mode:=SearchMode(GraphDriver,hiMode);
- end;
- procedure SetGraphMode(mode: smallint);
- var
- modeinfo: PModeInfo;
- begin
- { check if the mode exists... }
- modeinfo := searchmode(IntcurrentDriver,mode);
- if not assigned(modeinfo) then
- begin
- {$ifdef logging}
- LogLn('Mode setting failed in setgraphmode pos 1');
- {$endif logging}
- _GraphResult := grInvalidMode;
- exit;
- end;
- { reset all hooks...}
- DefaultHooks;
- { arccall not reset - tested against VGA BGI driver }
- { Setup all hooks if none, keep old defaults...}
- { required hooks - returns error if no hooks to these }
- { routines. }
- if assigned(modeinfo^.DirectPutPixel) then
- DirectPutPixel := modeinfo^.DirectPutPixel
- else
- begin
- {$ifdef logging}
- LogLn('Mode setting failed in setgraphmode pos 2');
- {$endif logging}
- _Graphresult := grInvalidMode;
- exit;
- end;
- if assigned(modeinfo^.PutPixel) then
- PutPixel := modeinfo^.PutPixel
- else
- begin
- {$ifdef logging}
- LogLn('Mode setting failed in setgraphmode pos 3');
- {$endif logging}
- _Graphresult := grInvalidMode;
- exit;
- end;
- if assigned(modeinfo^.GetPixel) then
- GetPixel := modeinfo^.GetPixel
- else
- begin
- {$ifdef logging}
- LogLn('Mode setting failed in setgraphmode pos 4');
- {$endif logging}
- _Graphresult := grInvalidMode;
- exit;
- end;
- if assigned(modeinfo^.SetRGBPalette) then
- SetRGBPalette := modeinfo^.SetRGBPalette
- else
- begin
- {$ifdef logging}
- LogLn('Mode setting failed in setgraphmode pos 5');
- {$endif logging}
- _Graphresult := grInvalidMode;
- exit;
- end;
- if assigned(modeinfo^.GetRGBPalette) then
- GetRGBPalette := modeinfo^.GetRGBPalette
- else
- begin
- {$ifdef logging}
- LogLn('Mode setting failed in setgraphmode pos 6');
- {$endif logging}
- _Graphresult := grInvalidMode;
- exit;
- end;
- { optional hooks. }
- if assigned(modeinfo^.ClearViewPort) then
- ClearViewPort := modeinfo^.ClearViewPort;
- if assigned(modeinfo^.PutImage) then
- PutImage := modeinfo^.PutImage;
- if assigned(modeinfo^.GetImage) then
- GetImage := modeinfo^.GetImage;
- if assigned(modeinfo^.ImageSize) then
- ImageSize := modeinfo^.ImageSize;
- if assigned(modeinfo^.GetScanLine) then
- GetScanLine := modeinfo^.GetScanLine;
- if assigned(modeinfo^.Line) then
- Line := modeinfo^.Line;
- if assigned(modeinfo^.InternalEllipse) then
- InternalEllipse := modeinfo^.InternalEllipse;
- if assigned(modeinfo^.PatternLine) then
- PatternLine := modeinfo^.PatternLine;
- if assigned(modeinfo^.HLine) then
- Hline := modeinfo^.Hline;
- if assigned(modeinfo^.Vline) then
- VLine := modeinfo^.VLine;
- if assigned(modeInfo^.SetVisualPage) then
- SetVisualPage := modeInfo^.SetVisualPage;
- if assigned(modeInfo^.SetActivePage) then
- SetActivePage := modeInfo^.SetActivePage;
- IntCurrentMode := modeinfo^.ModeNumber;
- IntCurrentDriver := modeinfo^.DriverNumber;
- XAspect := modeinfo^.XAspect;
- YAspect := modeinfo^.YAspect;
- MaxX := modeinfo^.MaxX;
- MaxY := modeinfo^.MaxY;
- HardwarePages := modeInfo^.HardwarePages;
- MaxColor := modeinfo^.MaxColor;
- PaletteSize := modeinfo^.PaletteSize;
- { is this a direct color mode? }
- DirectColor := modeinfo^.DirectColor;
- { now actually initialize the video mode...}
- { check first if the routine exists }
- if not assigned(modeinfo^.InitMode) then
- begin
- {$ifdef logging}
- LogLn('Mode setting failed in setgraphmode pos 7');
- {$endif logging}
- _GraphResult := grInvalidMode;
- exit;
- end;
- modeinfo^.InitMode;
- if _GraphResult <> grOk then exit;
- isgraphmode := true;
- { It is very important that this call be made }
- { AFTER the other variables have been setup. }
- { Since it calls some routines which rely on }
- { those variables. }
- SetActivePage(0);
- SetVisualPage(0);
- GraphDefaults;
- SetViewPort(0,0,MaxX,MaxY,TRUE);
- end;
- procedure RestoreCrtMode;
- {********************************************************}
- { Procedure RestoreCRTMode() }
- {--------------------------------------------------------}
- { Returns to the video mode which was set before the }
- { InitGraph. Hardware state is set to the old values. }
- {--------------------------------------------------------}
- { NOTE: - }
- { - }
- {********************************************************}
- begin
- isgraphmode := false;
- RestoreVideoState;
- end;
- {
- $Log$
- Revision 1.18 2000-01-07 16:32:26 daniel
- * copyright 2000 added
- Revision 1.17 2000/01/02 19:02:39 jonas
- * removed/commented out (inited but) unused vars and unused types
- Revision 1.16 1999/12/21 17:42:18 jonas
- * changed vesa.inc do it doesn't try to use linear modes anymore (doesn't work
- yet!!)
- * fixed mode detection so the low modenumber of a driver doesn't have to be zero
- anymore (so VESA autodetection now works)
- Revision 1.15 1999/12/20 11:22:36 peter
- * integer -> smallint to overcome -S2 switch needed for ggi version
- Revision 1.14 1999/12/04 21:20:04 michael
- + Additional logging
- Revision 1.13 1999/11/28 16:13:55 jonas
- * corrected misplacement of call to initvars in initgraph
- + some extra debugging commands (for -dlogging) in the mode functions
- Revision 1.12 1999/09/28 13:56:31 jonas
- * reordered some local variables (first 4 byte vars, then 2 byte vars
- etc)
- * font data is now disposed in exitproc, exitproc is now called
- GraphExitProc (was CleanModes) and resides in graph.pp instead of in
- modes.inc
- Revision 1.11 1999/09/26 13:31:07 jonas
- * changed name of modeinfo variable to vesamodeinfo and fixed
- associated errors (fillchar(modeinfo,sizeof(tmodeinfo),#0) instead
- of sizeof(TVesamodeinfo) etc)
- * changed several sizeof(type) to sizeof(varname) to avoid similar
- errors in the future
- Revision 1.10 1999/09/24 22:52:39 jonas
- * optimized patternline a bit (always use hline when possible)
- * isgraphmode stuff cleanup
- * vesainfo.modelist now gets disposed in cleanmode instead of in
- closegraph (required moving of some declarations from vesa.inc to
- new vesah.inc)
- * queryadapter gets no longer called from initgraph (is called from
- initialization of graph unit)
- * bugfix for notput in 32k and 64k vesa modes
- * a div replaced by / in fillpoly
- Revision 1.9 1999/09/22 13:13:36 jonas
- * renamed text.inc -> gtext.inc to avoid conflict with system unit
- * fixed textwidth
- * isgraphmode now gets properly updated, so mode restoring works
- again
- Revision 1.8 1999/09/18 22:21:11 jonas
- + hlinevesa256 and vlinevesa256
- + support for not/xor/or/andput in vesamodes with 32k/64k colors
- * lots of changes to avoid warnings under FPC
- Revision 1.7 1999/07/12 13:27:14 jonas
- + added Log and Id tags
- * added first FPC support, only VGA works to some extend for now
- * use -dasmgraph to use assembler routines, otherwise Pascal
- equivalents are used
- * use -dsupportVESA to support VESA (crashes under FPC for now)
- * only dispose vesainfo at closegrph if a vesa card was detected
- * changed int32 to longint (int32 is not declared under FPC)
- * changed the declaration of almost every procedure in graph.inc to
- "far;" becquse otherwise you can't assign them to procvars under TP
- real mode (but unexplainable "data segnment too large" errors prevent
- it from working under real mode anyway)
- }
|