video.pp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Florian Klaempfl
  4. member of the Free Pascal development team
  5. Video unit for Win32
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit Video;
  13. interface
  14. {$i videoh.inc}
  15. const
  16. useunicodefunctions : boolean = false;
  17. implementation
  18. uses
  19. windows,dos;
  20. {$i video.inc}
  21. type
  22. tunicodecharmappingflag = (umf_noinfo,umf_leadbyte,umf_undefined,
  23. umf_unused);
  24. punicodecharmapping = ^tunicodecharmapping;
  25. tunicodecharmapping = record
  26. unicode : word;
  27. flag : tunicodecharmappingflag;
  28. reserved : byte;
  29. end;
  30. const
  31. mapcp850 : array[0..255] of tunicodecharmapping = (
  32. (unicode : 0; flag : umf_noinfo; reserved : 0),
  33. (unicode : 1; flag : umf_noinfo; reserved : 0),
  34. (unicode : 2; flag : umf_noinfo; reserved : 0),
  35. (unicode : 3; flag : umf_noinfo; reserved : 0),
  36. (unicode : 4; flag : umf_noinfo; reserved : 0),
  37. (unicode : 5; flag : umf_noinfo; reserved : 0),
  38. (unicode : 6; flag : umf_noinfo; reserved : 0),
  39. (unicode : 7; flag : umf_noinfo; reserved : 0),
  40. (unicode : 8; flag : umf_noinfo; reserved : 0),
  41. (unicode : 9; flag : umf_noinfo; reserved : 0),
  42. (unicode : 10; flag : umf_noinfo; reserved : 0),
  43. (unicode : 11; flag : umf_noinfo; reserved : 0),
  44. (unicode : 12; flag : umf_noinfo; reserved : 0),
  45. (unicode : 13; flag : umf_noinfo; reserved : 0),
  46. (unicode : 14; flag : umf_noinfo; reserved : 0),
  47. (unicode : 15; flag : umf_noinfo; reserved : 0),
  48. (unicode : 16; flag : umf_noinfo; reserved : 0),
  49. (unicode : 17; flag : umf_noinfo; reserved : 0),
  50. (unicode : 18; flag : umf_noinfo; reserved : 0),
  51. (unicode : 19; flag : umf_noinfo; reserved : 0),
  52. (unicode : 20; flag : umf_noinfo; reserved : 0),
  53. (unicode : 21; flag : umf_noinfo; reserved : 0),
  54. (unicode : 22; flag : umf_noinfo; reserved : 0),
  55. (unicode : 23; flag : umf_noinfo; reserved : 0),
  56. (unicode : 24; flag : umf_noinfo; reserved : 0),
  57. (unicode : 25; flag : umf_noinfo; reserved : 0),
  58. (unicode : 26; flag : umf_noinfo; reserved : 0),
  59. (unicode : 27; flag : umf_noinfo; reserved : 0),
  60. (unicode : 28; flag : umf_noinfo; reserved : 0),
  61. (unicode : 29; flag : umf_noinfo; reserved : 0),
  62. (unicode : 30; flag : umf_noinfo; reserved : 0),
  63. (unicode : 31; flag : umf_noinfo; reserved : 0),
  64. (unicode : 32; flag : umf_noinfo; reserved : 0),
  65. (unicode : 33; flag : umf_noinfo; reserved : 0),
  66. (unicode : 34; flag : umf_noinfo; reserved : 0),
  67. (unicode : 35; flag : umf_noinfo; reserved : 0),
  68. (unicode : 36; flag : umf_noinfo; reserved : 0),
  69. (unicode : 37; flag : umf_noinfo; reserved : 0),
  70. (unicode : 38; flag : umf_noinfo; reserved : 0),
  71. (unicode : 39; flag : umf_noinfo; reserved : 0),
  72. (unicode : 40; flag : umf_noinfo; reserved : 0),
  73. (unicode : 41; flag : umf_noinfo; reserved : 0),
  74. (unicode : 42; flag : umf_noinfo; reserved : 0),
  75. (unicode : 43; flag : umf_noinfo; reserved : 0),
  76. (unicode : 44; flag : umf_noinfo; reserved : 0),
  77. (unicode : 45; flag : umf_noinfo; reserved : 0),
  78. (unicode : 46; flag : umf_noinfo; reserved : 0),
  79. (unicode : 47; flag : umf_noinfo; reserved : 0),
  80. (unicode : 48; flag : umf_noinfo; reserved : 0),
  81. (unicode : 49; flag : umf_noinfo; reserved : 0),
  82. (unicode : 50; flag : umf_noinfo; reserved : 0),
  83. (unicode : 51; flag : umf_noinfo; reserved : 0),
  84. (unicode : 52; flag : umf_noinfo; reserved : 0),
  85. (unicode : 53; flag : umf_noinfo; reserved : 0),
  86. (unicode : 54; flag : umf_noinfo; reserved : 0),
  87. (unicode : 55; flag : umf_noinfo; reserved : 0),
  88. (unicode : 56; flag : umf_noinfo; reserved : 0),
  89. (unicode : 57; flag : umf_noinfo; reserved : 0),
  90. (unicode : 58; flag : umf_noinfo; reserved : 0),
  91. (unicode : 59; flag : umf_noinfo; reserved : 0),
  92. (unicode : 60; flag : umf_noinfo; reserved : 0),
  93. (unicode : 61; flag : umf_noinfo; reserved : 0),
  94. (unicode : 62; flag : umf_noinfo; reserved : 0),
  95. (unicode : 63; flag : umf_noinfo; reserved : 0),
  96. (unicode : 64; flag : umf_noinfo; reserved : 0),
  97. (unicode : 65; flag : umf_noinfo; reserved : 0),
  98. (unicode : 66; flag : umf_noinfo; reserved : 0),
  99. (unicode : 67; flag : umf_noinfo; reserved : 0),
  100. (unicode : 68; flag : umf_noinfo; reserved : 0),
  101. (unicode : 69; flag : umf_noinfo; reserved : 0),
  102. (unicode : 70; flag : umf_noinfo; reserved : 0),
  103. (unicode : 71; flag : umf_noinfo; reserved : 0),
  104. (unicode : 72; flag : umf_noinfo; reserved : 0),
  105. (unicode : 73; flag : umf_noinfo; reserved : 0),
  106. (unicode : 74; flag : umf_noinfo; reserved : 0),
  107. (unicode : 75; flag : umf_noinfo; reserved : 0),
  108. (unicode : 76; flag : umf_noinfo; reserved : 0),
  109. (unicode : 77; flag : umf_noinfo; reserved : 0),
  110. (unicode : 78; flag : umf_noinfo; reserved : 0),
  111. (unicode : 79; flag : umf_noinfo; reserved : 0),
  112. (unicode : 80; flag : umf_noinfo; reserved : 0),
  113. (unicode : 81; flag : umf_noinfo; reserved : 0),
  114. (unicode : 82; flag : umf_noinfo; reserved : 0),
  115. (unicode : 83; flag : umf_noinfo; reserved : 0),
  116. (unicode : 84; flag : umf_noinfo; reserved : 0),
  117. (unicode : 85; flag : umf_noinfo; reserved : 0),
  118. (unicode : 86; flag : umf_noinfo; reserved : 0),
  119. (unicode : 87; flag : umf_noinfo; reserved : 0),
  120. (unicode : 88; flag : umf_noinfo; reserved : 0),
  121. (unicode : 89; flag : umf_noinfo; reserved : 0),
  122. (unicode : 90; flag : umf_noinfo; reserved : 0),
  123. (unicode : 91; flag : umf_noinfo; reserved : 0),
  124. (unicode : 92; flag : umf_noinfo; reserved : 0),
  125. (unicode : 93; flag : umf_noinfo; reserved : 0),
  126. (unicode : 94; flag : umf_noinfo; reserved : 0),
  127. (unicode : 95; flag : umf_noinfo; reserved : 0),
  128. (unicode : 96; flag : umf_noinfo; reserved : 0),
  129. (unicode : 97; flag : umf_noinfo; reserved : 0),
  130. (unicode : 98; flag : umf_noinfo; reserved : 0),
  131. (unicode : 99; flag : umf_noinfo; reserved : 0),
  132. (unicode : 100; flag : umf_noinfo; reserved : 0),
  133. (unicode : 101; flag : umf_noinfo; reserved : 0),
  134. (unicode : 102; flag : umf_noinfo; reserved : 0),
  135. (unicode : 103; flag : umf_noinfo; reserved : 0),
  136. (unicode : 104; flag : umf_noinfo; reserved : 0),
  137. (unicode : 105; flag : umf_noinfo; reserved : 0),
  138. (unicode : 106; flag : umf_noinfo; reserved : 0),
  139. (unicode : 107; flag : umf_noinfo; reserved : 0),
  140. (unicode : 108; flag : umf_noinfo; reserved : 0),
  141. (unicode : 109; flag : umf_noinfo; reserved : 0),
  142. (unicode : 110; flag : umf_noinfo; reserved : 0),
  143. (unicode : 111; flag : umf_noinfo; reserved : 0),
  144. (unicode : 112; flag : umf_noinfo; reserved : 0),
  145. (unicode : 113; flag : umf_noinfo; reserved : 0),
  146. (unicode : 114; flag : umf_noinfo; reserved : 0),
  147. (unicode : 115; flag : umf_noinfo; reserved : 0),
  148. (unicode : 116; flag : umf_noinfo; reserved : 0),
  149. (unicode : 117; flag : umf_noinfo; reserved : 0),
  150. (unicode : 118; flag : umf_noinfo; reserved : 0),
  151. (unicode : 119; flag : umf_noinfo; reserved : 0),
  152. (unicode : 120; flag : umf_noinfo; reserved : 0),
  153. (unicode : 121; flag : umf_noinfo; reserved : 0),
  154. (unicode : 122; flag : umf_noinfo; reserved : 0),
  155. (unicode : 123; flag : umf_noinfo; reserved : 0),
  156. (unicode : 124; flag : umf_noinfo; reserved : 0),
  157. (unicode : 125; flag : umf_noinfo; reserved : 0),
  158. (unicode : 126; flag : umf_noinfo; reserved : 0),
  159. (unicode : 127; flag : umf_noinfo; reserved : 0),
  160. (unicode : 199; flag : umf_noinfo; reserved : 0),
  161. (unicode : 252; flag : umf_noinfo; reserved : 0),
  162. (unicode : 233; flag : umf_noinfo; reserved : 0),
  163. (unicode : 226; flag : umf_noinfo; reserved : 0),
  164. (unicode : 228; flag : umf_noinfo; reserved : 0),
  165. (unicode : 224; flag : umf_noinfo; reserved : 0),
  166. (unicode : 229; flag : umf_noinfo; reserved : 0),
  167. (unicode : 231; flag : umf_noinfo; reserved : 0),
  168. (unicode : 234; flag : umf_noinfo; reserved : 0),
  169. (unicode : 235; flag : umf_noinfo; reserved : 0),
  170. (unicode : 232; flag : umf_noinfo; reserved : 0),
  171. (unicode : 239; flag : umf_noinfo; reserved : 0),
  172. (unicode : 238; flag : umf_noinfo; reserved : 0),
  173. (unicode : 236; flag : umf_noinfo; reserved : 0),
  174. (unicode : 196; flag : umf_noinfo; reserved : 0),
  175. (unicode : 197; flag : umf_noinfo; reserved : 0),
  176. (unicode : 201; flag : umf_noinfo; reserved : 0),
  177. (unicode : 230; flag : umf_noinfo; reserved : 0),
  178. (unicode : 198; flag : umf_noinfo; reserved : 0),
  179. (unicode : 244; flag : umf_noinfo; reserved : 0),
  180. (unicode : 246; flag : umf_noinfo; reserved : 0),
  181. (unicode : 242; flag : umf_noinfo; reserved : 0),
  182. (unicode : 251; flag : umf_noinfo; reserved : 0),
  183. (unicode : 249; flag : umf_noinfo; reserved : 0),
  184. (unicode : 255; flag : umf_noinfo; reserved : 0),
  185. (unicode : 214; flag : umf_noinfo; reserved : 0),
  186. (unicode : 220; flag : umf_noinfo; reserved : 0),
  187. (unicode : 248; flag : umf_noinfo; reserved : 0),
  188. (unicode : 163; flag : umf_noinfo; reserved : 0),
  189. (unicode : 216; flag : umf_noinfo; reserved : 0),
  190. (unicode : 215; flag : umf_noinfo; reserved : 0),
  191. (unicode : 402; flag : umf_noinfo; reserved : 0),
  192. (unicode : 225; flag : umf_noinfo; reserved : 0),
  193. (unicode : 237; flag : umf_noinfo; reserved : 0),
  194. (unicode : 243; flag : umf_noinfo; reserved : 0),
  195. (unicode : 250; flag : umf_noinfo; reserved : 0),
  196. (unicode : 241; flag : umf_noinfo; reserved : 0),
  197. (unicode : 209; flag : umf_noinfo; reserved : 0),
  198. (unicode : 170; flag : umf_noinfo; reserved : 0),
  199. (unicode : 186; flag : umf_noinfo; reserved : 0),
  200. (unicode : 191; flag : umf_noinfo; reserved : 0),
  201. (unicode : 174; flag : umf_noinfo; reserved : 0),
  202. (unicode : 172; flag : umf_noinfo; reserved : 0),
  203. (unicode : 189; flag : umf_noinfo; reserved : 0),
  204. (unicode : 188; flag : umf_noinfo; reserved : 0),
  205. (unicode : 161; flag : umf_noinfo; reserved : 0),
  206. (unicode : 171; flag : umf_noinfo; reserved : 0),
  207. (unicode : 187; flag : umf_noinfo; reserved : 0),
  208. (unicode : 9617; flag : umf_noinfo; reserved : 0),
  209. (unicode : 9618; flag : umf_noinfo; reserved : 0),
  210. (unicode : 9619; flag : umf_noinfo; reserved : 0),
  211. (unicode : 9474; flag : umf_noinfo; reserved : 0),
  212. (unicode : 9508; flag : umf_noinfo; reserved : 0),
  213. (unicode : 193; flag : umf_noinfo; reserved : 0),
  214. (unicode : 194; flag : umf_noinfo; reserved : 0),
  215. (unicode : 192; flag : umf_noinfo; reserved : 0),
  216. (unicode : 169; flag : umf_noinfo; reserved : 0),
  217. (unicode : 9571; flag : umf_noinfo; reserved : 0),
  218. (unicode : 9553; flag : umf_noinfo; reserved : 0),
  219. (unicode : 9559; flag : umf_noinfo; reserved : 0),
  220. (unicode : 9565; flag : umf_noinfo; reserved : 0),
  221. (unicode : 162; flag : umf_noinfo; reserved : 0),
  222. (unicode : 165; flag : umf_noinfo; reserved : 0),
  223. (unicode : 9488; flag : umf_noinfo; reserved : 0),
  224. (unicode : 9492; flag : umf_noinfo; reserved : 0),
  225. (unicode : 9524; flag : umf_noinfo; reserved : 0),
  226. (unicode : 9516; flag : umf_noinfo; reserved : 0),
  227. (unicode : 9500; flag : umf_noinfo; reserved : 0),
  228. (unicode : 9472; flag : umf_noinfo; reserved : 0),
  229. (unicode : 9532; flag : umf_noinfo; reserved : 0),
  230. (unicode : 227; flag : umf_noinfo; reserved : 0),
  231. (unicode : 195; flag : umf_noinfo; reserved : 0),
  232. (unicode : 9562; flag : umf_noinfo; reserved : 0),
  233. (unicode : 9556; flag : umf_noinfo; reserved : 0),
  234. (unicode : 9577; flag : umf_noinfo; reserved : 0),
  235. (unicode : 9574; flag : umf_noinfo; reserved : 0),
  236. (unicode : 9568; flag : umf_noinfo; reserved : 0),
  237. (unicode : 9552; flag : umf_noinfo; reserved : 0),
  238. (unicode : 9580; flag : umf_noinfo; reserved : 0),
  239. (unicode : 164; flag : umf_noinfo; reserved : 0),
  240. (unicode : 240; flag : umf_noinfo; reserved : 0),
  241. (unicode : 208; flag : umf_noinfo; reserved : 0),
  242. (unicode : 202; flag : umf_noinfo; reserved : 0),
  243. (unicode : 203; flag : umf_noinfo; reserved : 0),
  244. (unicode : 200; flag : umf_noinfo; reserved : 0),
  245. (unicode : 305; flag : umf_noinfo; reserved : 0),
  246. (unicode : 205; flag : umf_noinfo; reserved : 0),
  247. (unicode : 206; flag : umf_noinfo; reserved : 0),
  248. (unicode : 207; flag : umf_noinfo; reserved : 0),
  249. (unicode : 9496; flag : umf_noinfo; reserved : 0),
  250. (unicode : 9484; flag : umf_noinfo; reserved : 0),
  251. (unicode : 9608; flag : umf_noinfo; reserved : 0),
  252. (unicode : 9604; flag : umf_noinfo; reserved : 0),
  253. (unicode : 166; flag : umf_noinfo; reserved : 0),
  254. (unicode : 204; flag : umf_noinfo; reserved : 0),
  255. (unicode : 9600; flag : umf_noinfo; reserved : 0),
  256. (unicode : 211; flag : umf_noinfo; reserved : 0),
  257. (unicode : 223; flag : umf_noinfo; reserved : 0),
  258. (unicode : 212; flag : umf_noinfo; reserved : 0),
  259. (unicode : 210; flag : umf_noinfo; reserved : 0),
  260. (unicode : 245; flag : umf_noinfo; reserved : 0),
  261. (unicode : 213; flag : umf_noinfo; reserved : 0),
  262. (unicode : 181; flag : umf_noinfo; reserved : 0),
  263. (unicode : 254; flag : umf_noinfo; reserved : 0),
  264. (unicode : 222; flag : umf_noinfo; reserved : 0),
  265. (unicode : 218; flag : umf_noinfo; reserved : 0),
  266. (unicode : 219; flag : umf_noinfo; reserved : 0),
  267. (unicode : 217; flag : umf_noinfo; reserved : 0),
  268. (unicode : 253; flag : umf_noinfo; reserved : 0),
  269. (unicode : 221; flag : umf_noinfo; reserved : 0),
  270. (unicode : 175; flag : umf_noinfo; reserved : 0),
  271. (unicode : 180; flag : umf_noinfo; reserved : 0),
  272. (unicode : 173; flag : umf_noinfo; reserved : 0),
  273. (unicode : 177; flag : umf_noinfo; reserved : 0),
  274. (unicode : 8215; flag : umf_noinfo; reserved : 0),
  275. (unicode : 190; flag : umf_noinfo; reserved : 0),
  276. (unicode : 182; flag : umf_noinfo; reserved : 0),
  277. (unicode : 167; flag : umf_noinfo; reserved : 0),
  278. (unicode : 247; flag : umf_noinfo; reserved : 0),
  279. (unicode : 184; flag : umf_noinfo; reserved : 0),
  280. (unicode : 176; flag : umf_noinfo; reserved : 0),
  281. (unicode : 168; flag : umf_noinfo; reserved : 0),
  282. (unicode : 183; flag : umf_noinfo; reserved : 0),
  283. (unicode : 185; flag : umf_noinfo; reserved : 0),
  284. (unicode : 179; flag : umf_noinfo; reserved : 0),
  285. (unicode : 178; flag : umf_noinfo; reserved : 0),
  286. (unicode : 9632; flag : umf_noinfo; reserved : 0),
  287. (unicode : 160; flag : umf_noinfo; reserved : 0)
  288. );
  289. const
  290. LastCursorType: word = crUnderline;
  291. OrigScreen: PVideoBuf = nil;
  292. OrigScreenSize: cardinal = 0;
  293. var ConsoleInfo : TConsoleScreenBufferInfo;
  294. ConsoleCursorInfo : TConsoleCursorInfo;
  295. OrigCP: cardinal;
  296. OrigConsoleCursorInfo : TConsoleCursorInfo;
  297. OrigConsoleInfo : TConsoleScreenBufferInfo;
  298. procedure SysInitVideo;
  299. begin
  300. ScreenColor:=true;
  301. GetConsoleScreenBufferInfo(TextRec(Output).Handle, OrigConsoleInfo);
  302. GetConsoleCursorInfo(TextRec(Output).Handle, OrigConsoleCursorInfo);
  303. OrigCP := GetConsoleCP;
  304. ConsoleInfo:=OrigConsoleInfo;
  305. ConsoleCursorInfo:=OrigConsoleCursorInfo;
  306. {
  307. About the ConsoleCursorInfo record: There are 3 possible
  308. structures in it that can be regarded as the 'screen':
  309. - dwsize : contains the cols & row in current screen buffer.
  310. - srwindow : Coordinates (relative to buffer) of upper left
  311. & lower right corners of visible console.
  312. - dmMaximumWindowSize : Maximal size of Screen buffer.
  313. The first implementation of video used srWindow. After some
  314. bug-reports, this was switched to dwMaximumWindowSize.
  315. }
  316. with ConsoleInfo.dwMaximumWindowSize do
  317. begin
  318. ScreenWidth:=X;
  319. ScreenHeight:=Y;
  320. end;
  321. { TDrawBuffer only has FVMaxWidth elements
  322. larger values lead to crashes }
  323. if ScreenWidth> FVMaxWidth then
  324. ScreenWidth:=FVMaxWidth;
  325. CursorX:=ConsoleInfo.dwCursorPosition.x;
  326. CursorY:=ConsoleInfo.dwCursorPosition.y;
  327. if not ConsoleCursorInfo.bvisible then
  328. CursorLines:=0
  329. else
  330. CursorLines:=ConsoleCursorInfo.dwSize;
  331. end;
  332. procedure SysDoneVideo;
  333. begin
  334. SetConsoleScreenBufferSize (TextRec (Output).Handle, OrigConsoleInfo.dwSize);
  335. SetConsoleWindowInfo (cardinal (TextRec (Output).Handle), true, OrigConsoleInfo.srWindow);
  336. SetConsoleCursorInfo(TextRec(Output).Handle, OrigConsoleCursorInfo);
  337. SetConsoleCP(OrigCP);
  338. end;
  339. function SysGetCapabilities: Word;
  340. begin
  341. SysGetCapabilities:=cpColor or cpChangeCursor;
  342. end;
  343. procedure SysSetCursorPos(NewCursorX, NewCursorY: Word);
  344. var
  345. pos : COORD;
  346. begin
  347. pos.x:=NewCursorX;
  348. pos.y:=NewCursorY;
  349. SetConsoleCursorPosition(TextRec(Output).Handle,pos);
  350. CursorX:=pos.x;
  351. CursorY:=pos.y;
  352. end;
  353. function SysGetCursorType: Word;
  354. begin
  355. GetConsoleCursorInfo(TextRec(Output).Handle,ConsoleCursorInfo);
  356. if not ConsoleCursorInfo.bvisible then
  357. SysGetCursorType:=crHidden
  358. else
  359. case ConsoleCursorInfo.dwSize of
  360. 1..30:
  361. SysGetCursorType:=crUnderline;
  362. 31..70:
  363. SysGetCursorType:=crHalfBlock;
  364. 71..100:
  365. SysGetCursorType:=crBlock;
  366. end;
  367. end;
  368. procedure SysSetCursorType(NewType: Word);
  369. begin
  370. GetConsoleCursorInfo(TextRec(Output).Handle,ConsoleCursorInfo);
  371. if newType=crHidden then
  372. ConsoleCursorInfo.bvisible:=false
  373. else
  374. begin
  375. ConsoleCursorInfo.bvisible:=true;
  376. case NewType of
  377. crUnderline:
  378. ConsoleCursorInfo.dwSize:=10;
  379. crHalfBlock:
  380. ConsoleCursorInfo.dwSize:=50;
  381. crBlock:
  382. ConsoleCursorInfo.dwSize:=99;
  383. end
  384. end;
  385. SetConsoleCursorInfo(TextRec(Output).Handle,ConsoleCursorInfo);
  386. end;
  387. function SysVideoModeSelector (const VideoMode: TVideoMode): boolean;
  388. var MI: Console_Screen_Buffer_Info;
  389. C: Coord;
  390. SR: Small_Rect;
  391. begin
  392. if not (GetConsoleScreenBufferInfo (TextRec (Output).Handle, MI)) then
  393. SysVideoModeSelector := false
  394. else
  395. begin
  396. with MI do
  397. begin
  398. C.X := VideoMode.Col;
  399. C.Y := VideoMode.Row;
  400. end;
  401. with SR do
  402. begin
  403. Top := 0;
  404. Left := 0;
  405. { First, we need to make sure we reach the minimum window size
  406. to always fit in the new buffer after changing buffer size. }
  407. Right := MI.srWindow.Right - MI.srWindow.Left;
  408. if VideoMode.Col <= Right then
  409. Right := Pred (VideoMode.Col);
  410. Bottom := MI.srWindow.Bottom - MI.srWindow.Top;
  411. if VideoMode.Row <= Bottom then
  412. Bottom := Pred (VideoMode.Row);
  413. end;
  414. if SetConsoleWindowInfo (cardinal (TextRec (Output).Handle), true, SR) then
  415. if SetConsoleScreenBufferSize (TextRec (Output).Handle, C) then
  416. begin
  417. with SR do
  418. begin
  419. { Now, we can resize the window to the final size. }
  420. Right := Pred (VideoMode.Col);
  421. Bottom := Pred (VideoMode.Row);
  422. end;
  423. if SetConsoleWindowInfo (cardinal (TextRec (Output).Handle), true, SR) then
  424. begin
  425. SysVideoModeSelector := true;
  426. SetCursorType (LastCursorType);
  427. ClearScreen;
  428. end
  429. else
  430. begin
  431. SysVideoModeSelector := false;
  432. SetConsoleScreenBufferSize (TextRec (Output).Handle, MI.dwSize);
  433. SetConsoleWindowInfo (cardinal (TextRec (Output).Handle), true, MI.srWindow);
  434. SetCursorType (LastCursorType);
  435. end
  436. end
  437. else
  438. begin
  439. SysVideoModeSelector := false;
  440. SetConsoleWindowInfo (cardinal (TextRec (Output).Handle), true, MI.srWindow);
  441. SetCursorType (LastCursorType);
  442. end
  443. else
  444. SysVideoModeSelector := false;
  445. end;
  446. end;
  447. Const
  448. SysVideoModeCount = 6;
  449. SysVMD : Array[0..SysVideoModeCount-1] of TVideoMode = (
  450. (Col: 40; Row: 25; Color: True),
  451. (Col: 80; Row: 25; Color: True),
  452. (Col: 80; Row: 30; Color: True),
  453. (Col: 80; Row: 43; Color: True),
  454. (Col: 80; Row: 50; Color: True),
  455. (Col: 80; Row: 25; Color: True) // Reserved for TargetEntry
  456. );
  457. Function SysSetVideoMode (Const Mode : TVideoMode) : Boolean;
  458. Var
  459. I : Integer;
  460. begin
  461. I:=SysVideoModeCount-1;
  462. SysSetVideoMode:=False;
  463. While (I>=0) and Not SysSetVideoMode do
  464. If (Mode.col=SysVMD[i].col) and
  465. (Mode.Row=SysVMD[i].Row) and
  466. (Mode.Color=SysVMD[i].Color) then
  467. SysSetVideoMode:=True
  468. else
  469. Dec(I);
  470. If SysSetVideoMode then
  471. begin
  472. if SysVideoModeSelector(Mode) then
  473. begin
  474. ScreenWidth:=SysVMD[I].Col;
  475. ScreenHeight:=SysVMD[I].Row;
  476. ScreenColor:=SysVMD[I].Color;
  477. end else SysSetVideoMode := false;
  478. end;
  479. end;
  480. Function SysGetVideoModeData (Index : Word; Var Data : TVideoMode) : boolean;
  481. begin
  482. SysGetVideoModeData:=(Index<=high(SysVMD));
  483. If SysGetVideoModeData then
  484. Data:=SysVMD[Index];
  485. end;
  486. Function SysGetVideoModeCount : Word;
  487. begin
  488. SysGetVideoModeCount:=SysVideoModeCount;
  489. end;
  490. procedure SysClearScreen;
  491. begin
  492. UpdateScreen(true);
  493. end;
  494. procedure SysUpdateScreen(Force: Boolean);
  495. type WordRec = record
  496. One, Two: Byte;
  497. end; { wordrec }
  498. var
  499. BufSize,
  500. BufCoord : COORD;
  501. WriteRegion : SMALL_RECT;
  502. LineBuf : Array[0..(1024*32) - 1] of TCharInfo;
  503. BufCounter : Longint;
  504. LineCounter,
  505. ColCounter : Longint;
  506. smallforce : boolean;
  507. x1,y1,x2,y2 : longint;
  508. p1,p2,p3 : PCardinal;
  509. j : integer;
  510. begin
  511. if force then
  512. smallforce:=true
  513. else
  514. begin
  515. {$ifdef cpui386}
  516. asm
  517. pushl %esi
  518. pushl %edi
  519. movl VideoBuf,%esi
  520. movl OldVideoBuf,%edi
  521. movl VideoBufSize,%ecx
  522. shrl $2,%ecx
  523. repe
  524. cmpsl
  525. setne smallforce
  526. popl %edi
  527. popl %esi
  528. end;
  529. {$else}
  530. {$ifdef cpux86_64}
  531. asm
  532. pushq %rsi
  533. pushq %rdi
  534. xorq %rcx,%rcx
  535. movq VideoBuf,%rsi
  536. movq OldVideoBuf,%edi
  537. movl VideoBufSize,%ecx
  538. shrq $2,%rcx
  539. repe
  540. cmpsl
  541. setne smallforce
  542. popq %rdi
  543. popq %rsi
  544. end;
  545. {$else}
  546. {$INFO No optimized version for this CPU, reverting to a pascal version}
  547. j:=Videobufsize shr 2;
  548. smallforce:=false;
  549. p1:=pcardinal(VideoBuf);
  550. p2:=pcardinal(OldVideoBuf);
  551. p3:=@pcardinal(videobuf)[j];
  552. while (p1<p3) and (p1^=p2^) do
  553. begin
  554. inc(p1); inc(p2);
  555. end;
  556. smallforce:=p1<>p3;
  557. {$ENDIF}
  558. {$endif}
  559. end;
  560. if SmallForce then
  561. begin
  562. BufSize.X := ScreenWidth;
  563. BufSize.Y := ScreenHeight;
  564. BufCoord.X := 0;
  565. BufCoord.Y := 0;
  566. with WriteRegion do
  567. begin
  568. Top :=0;
  569. Left :=0;
  570. Bottom := ScreenHeight-1;
  571. Right := ScreenWidth-1;
  572. end;
  573. BufCounter := 0;
  574. x1:=ScreenWidth+1;
  575. x2:=-1;
  576. y1:=ScreenHeight+1;
  577. y2:=-1;
  578. for LineCounter := 1 to ScreenHeight do
  579. begin
  580. for ColCounter := 1 to ScreenWidth do
  581. begin
  582. if (WordRec(VideoBuf^[BufCounter]).One<>WordRec(OldVideoBuf^[BufCounter]).One) or
  583. (WordRec(VideoBuf^[BufCounter]).Two<>WordRec(OldVideoBuf^[BufCounter]).Two) then
  584. begin
  585. if ColCounter<x1 then
  586. x1:=ColCounter;
  587. if ColCounter>x2 then
  588. x2:=ColCounter;
  589. if LineCounter<y1 then
  590. y1:=LineCounter;
  591. if LineCounter>y2 then
  592. y2:=LineCounter;
  593. end;
  594. if useunicodefunctions then
  595. LineBuf[BufCounter].UniCodeChar := Widechar(mapcp850[WordRec(VideoBuf^[BufCounter]).One].unicode)
  596. else
  597. LineBuf[BufCounter].UniCodeChar := Widechar(WordRec(VideoBuf^[BufCounter]).One);
  598. { If (WordRec(VideoBuf^[BufCounter]).Two and $80)<>0 then
  599. LineBuf^[BufCounter].Attributes := $100+WordRec(VideoBuf^[BufCounter]).Two
  600. else }
  601. LineBuf[BufCounter].Attributes := WordRec(VideoBuf^[BufCounter]).Two;
  602. Inc(BufCounter);
  603. end; { for }
  604. end; { for }
  605. BufSize.X := ScreenWidth;
  606. BufSize.Y := ScreenHeight;
  607. with WriteRegion do
  608. begin
  609. if force then
  610. begin
  611. Top := 0;
  612. Left :=0;
  613. Bottom := ScreenHeight-1;
  614. Right := ScreenWidth-1;
  615. BufCoord.X := 0;
  616. BufCoord.Y := 0;
  617. end
  618. else
  619. begin
  620. Top := y1-1;
  621. Left :=x1-1;
  622. Bottom := y2-1;
  623. Right := x2-1;
  624. BufCoord.X := x1-1;
  625. BufCoord.Y := y1-1;
  626. end;
  627. end;
  628. {
  629. writeln('X1: ',x1);
  630. writeln('Y1: ',y1);
  631. writeln('X2: ',x2);
  632. writeln('Y2: ',y2);
  633. }
  634. if useunicodefunctions then
  635. WriteConsoleOutputW(TextRec(Output).Handle, @LineBuf, BufSize, BufCoord, WriteRegion)
  636. else
  637. WriteConsoleOutput(TextRec(Output).Handle, @LineBuf, BufSize, BufCoord, WriteRegion);
  638. move(VideoBuf^,OldVideoBuf^,VideoBufSize);
  639. end;
  640. end;
  641. Const
  642. SysVideoDriver : TVideoDriver = (
  643. InitDriver : @SysInitVideo;
  644. DoneDriver : @SysDoneVideo;
  645. UpdateScreen : @SysUpdateScreen;
  646. ClearScreen : @SysClearScreen;
  647. SetVideoMode : @SysSetVideoMode;
  648. GetVideoModeCount : @SysGetVideoModeCount;
  649. GetVideoModeData : @SysGetVideoModeData;
  650. SetCursorPos : @SysSetCursorPos;
  651. GetCursorType : @SysGetCursorType;
  652. SetCursorType : @SysSetCursorType;
  653. GetCapabilities : @SysGetCapabilities
  654. );
  655. procedure TargetEntry;
  656. var
  657. C: Coord;
  658. SR: Small_Rect;
  659. VioMode: TConsoleScreenBufferInfo;
  660. begin
  661. GetConsoleScreenBufferInfo (TextRec (Output).Handle, VioMode);
  662. { Register the curent video mode in reserved slot in System Modes}
  663. with VioMode do
  664. begin
  665. {Assume we have at least 16 colours available in "colour" modes}
  666. SysVMD[SysVideoModeCount-1].Col:=dwMaximumWindowSize.X;
  667. SysVMD[SysVideoModeCount-1].Row:=dwMaximumWindowSize.Y;
  668. SysVMD[SysVideoModeCount-1].Color:=true;
  669. OrigScreenSize := max(dwMaximumWindowSize.X,dwSize.X) * max(dwMaximumWindowSize.Y,dwSize.Y) * SizeOf (Char_Info);
  670. end;
  671. GetMem (OrigScreen, OrigScreenSize);
  672. with C do
  673. begin
  674. X := 0;
  675. Y := 0;
  676. end;
  677. with SR do
  678. begin
  679. Top := 0;
  680. Left := 0;
  681. Right := Pred (VioMode.dwSize.X);
  682. Bottom := Pred (VioMode.dwSize.Y);
  683. end;
  684. if not (ReadConsoleOutput (TextRec (Output).Handle, OrigScreen, VioMode.dwSize, C, SR)) then
  685. begin
  686. FreeMem (OrigScreen, OrigScreenSize);
  687. OrigScreen := nil;
  688. OrigScreenSize := 0;
  689. end;
  690. end;
  691. initialization
  692. SetVideoDriver(SysVideoDriver);
  693. TargetEntry;
  694. end.