textfx2.pp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. {*
  2. * TextFX2 Copyright (c) 1998 Jari Komppa aka Sol/Trauma
  3. * <mailto:[email protected]>
  4. *
  5. * Textmode low-level functions
  6. *
  7. * This sourcefile is kinda long-ish, and should be split into several
  8. * sources, but I have wanted to keep it in one file since everything
  9. * here is kinda small and.. well, I wanted to keep it as a single .obj
  10. * file.
  11. *
  12. * If you make improvements, send me a copy!
  13. * If you use this for something, let me know!
  14. *}
  15. {$MODE objfpc}
  16. Unit textfx2;
  17. Interface
  18. Const
  19. {*
  20. * Charsets in 'lightness' order. First byte = num of chars
  21. *
  22. * Please note that these don't work with the current calcpal
  23. * strategy :)
  24. *
  25. *}
  26. charset_b8ibm : Array[0..254] Of Byte = { all imbscii characters }
  27. ( 254, 32, 96, 39, 250, 95, 126, 46, 94, 34, 249, 248, 44, 58, 45,
  28. 196, 59, 253, 167, 61, 166, 252, 47, 28, 217, 192, 169, 205, 246, 7,
  29. 170, 27, 190, 43, 212, 62, 60, 124, 26, 226, 193, 40, 243, 242, 240,
  30. 63, 41, 37, 139, 191, 55, 91, 207, 218, 200, 176, 9, 105, 241, 92,
  31. 141, 33, 125, 238, 102, 161, 231, 123, 211, 202, 247, 108, 99, 168,
  32. 188, 73, 93, 67, 29, 175, 174, 106, 114, 189, 140, 24, 76, 116, 194,
  33. 208, 49, 115, 50, 70, 228, 13, 84, 80, 156, 51, 120, 122, 179, 173,
  34. 184, 53, 89, 155, 244, 213, 90, 25, 135, 223, 57, 42, 83, 118, 128,
  35. 101, 245, 127, 171, 74, 19, 159, 4, 1, 180, 110, 137, 230, 195, 209,
  36. 18, 97, 111, 117, 86, 229, 31, 138, 69, 144, 22, 148, 130, 16, 132,
  37. 181, 129, 36, 157, 198, 136, 12, 214, 71, 239, 133, 160, 162, 149,
  38. 163, 151, 52, 54, 98, 107, 251, 104, 224, 197, 183, 154, 235, 164,
  39. 112, 131, 85, 147, 121, 236, 150, 232, 134, 153, 11, 210, 225, 79,
  40. 172, 145, 227, 152, 100, 23, 21, 88, 17, 48, 119, 75, 68, 113, 30, 72,
  41. 15, 233, 56, 103, 65, 142, 234, 5, 82, 109, 216, 201, 254, 66, 38,
  42. 158, 143, 237, 203, 187, 77, 221, 146, 14, 78, 35, 81, 64, 20, 177,
  43. 87, 6, 165, 3, 204, 186, 222, 199, 206, 185, 182, 215, 220, 2, 178,
  44. 10, 8, 219);
  45. charset_b7asc : Array[0..94] Of Byte = { 7b ascii (chars 32 - 126) }
  46. ( 94, 32, 96, 39, 95, 126, 46, 94, 34, 44, 58, 45, 59, 61, 47, 43, 62,
  47. 60, 40, 63, 41, 37, 55, 91, 105, 92, 33, 125, 102, 123, 108, 99, 73,
  48. 93, 67, 106, 114, 76, 116, 49, 115, 50, 70, 84, 80, 51, 120, 122, 53,
  49. 89, 90, 57, 42, 83, 118, 101, 74, 110, 97, 111, 117, 86, 69, 36, 71,
  50. 52, 54, 98, 107, 104, 112, 85, 121, 79, 100, 88, 48, 119, 75, 68, 113,
  51. 72, 56, 103, 65, 82, 109, 66, 38, 77, 78, 35, 81, 64, 87);
  52. charset_b7sml : Array[0..14] Of Byte = { " crsxzvenaouwm" dark->light. }
  53. ( 14, 32, 99, 114, 115, 120, 122, 118, 101, 110, 97, 111, 117, 119,
  54. 109 );
  55. charset_b8gry : Array[0..5] Of Byte = { 8b ibm grayscale characters }
  56. ( 5, 32, 176, 177, 178, 219 );
  57. charset_b7nws : Array[0..6] Of Byte = { 7b grayscale 'newschool' askee chars}
  58. ( 6, 32{' '}, 46{'.'}, 111{'o'}, 109{'m'}, 87{'W'}, 77{'M'} );
  59. use_charset : Pbyte = @charset_b7asc;
  60. { Character set to use. Can be changed run-time. }
  61. colmap : PSmallInt = Nil;
  62. Procedure set80x43; { Sets up 80x43, no blink, no cursor. }
  63. Procedure set80x50; { Sets up 80x50, no blink, no cursor. }
  64. Procedure set80x25; { Resets 80x25, blink, cursor. }
  65. Procedure border(color : Byte); { _ONLY_ for debugging! }
  66. Procedure vrc; { Although all should be timer-synced instead.. }
  67. {*
  68. * calc_ functions are pretty *S*L*O*W* so use them to precalculate
  69. * color tables and then use those tables instead.
  70. *}
  71. Function calcpal_colorbase(red, green, blue : Real) : Word;
  72. Function calcpal_lightbase(red, green, blue : Real) : Word;
  73. Function calcpal_lightbase_g(red, green, blue : Real) : Word;
  74. {Function (*calcpal)(float red, float green, float blue) : Word;}
  75. Const calcpal : Function(red, green, blue : Real) : Word = @calcpal_colorbase;
  76. {* Finds the closest color/char combo for any 0:63,0:63,0:63 value.
  77. *
  78. * calcpal_colorbase is the 'old' calcpal, only "a bit" optimized.
  79. * calcpal is now function pointer so calcpal function can be changed
  80. * run-time. Use the functions directly if you need speed (and
  81. * compile with -oe256 or something to force inlining)
  82. *}
  83. Function calc_gscale(light : Real) : Word;
  84. Function calc_gscale2(light : Real) : Word;
  85. {* Finds the closes gscale color/char combo for 0..1 range
  86. * gscale2 uses colors 8,7,15, normal just uses 7.
  87. *}
  88. Procedure build_colormap(dots : Integer);
  89. {* Used to calculate colormap for dump_nnx() -functions.
  90. * if dots=0, will output nothing.
  91. * 1, will cprintf .:s as process.
  92. * 2, will cprintf rolling wheel as process.
  93. *}
  94. Procedure dispose_colormap;
  95. Procedure dump_80x(y0, y1 : Integer; buffer : PInteger);
  96. {* Dumps 80-pixel wide 0bgr-truecolor buffer from y0 to y1.
  97. * (For fullscreen dump in 80x43 use dump_80x(0,43,buf);
  98. *}
  99. Procedure dump_160x(y0, y1 : Integer; buffer : PInteger);
  100. {* Dumps 160-pixel wide 0bgr-truecolor buffer from y0 to y1
  101. * with 4-to-1 pixel averaging.
  102. *}
  103. Procedure dump_320x(y0, y1 : Integer; buffer : PInteger);
  104. {* Dumps 160-pixel wide 0bgr-truecolor buffer from y0 to y1
  105. * with 16-to-1 pixel averaging. (this is tad bit slow :)
  106. *}
  107. Implementation
  108. Uses
  109. go32;
  110. { $define __USE_178NOT176}
  111. { uncomment to use 75% char instead of 25% char }
  112. {$DEFINE __USE_REALIBMPAL}
  113. { comment out to use 'clean' truecolor palette for calculations }
  114. Const
  115. COLORMAP_DEPTH = 4;
  116. {* Normally, build 1<<4, ie. 16x16x16 colormap.
  117. * If you require bigger map, increase the value.
  118. * (5 will mean 32x32x32 etc).
  119. * 8 is max for dump_80x and _320x, 6 is max for _160x.
  120. * If you make your own routines, well, nothing is too much :)
  121. *}
  122. { Don't touch the rest of the defines. }
  123. COLMAPDIM = 1 Shl COLORMAP_DEPTH;
  124. TRUCOLBITS = 8 - COLORMAP_DEPTH;
  125. {$IFDEF __USE_REALIBMPAL}
  126. palette : Array[0..16*3-1] Of Byte = ( {IBM basic palette, 16c}
  127. 0, 0, 0, 0, 0,42, 0,42, 0, 0,42,42, 42, 0, 0, 42, 0,42, 42,21, 0, 42,42,42,
  128. 21,21,21, 21,21,63, 21,63,21, 21,63,63, 63,21,21, 63,21,63, 63,63,21, 63,63,63);
  129. {$ELSE}
  130. palette : Array[0..16*3-1] Of Byte = ( { 'clean' RGB palette }
  131. 0, 0, 0, 0, 0,32, 0,32, 0, 0,32,32, 32, 0, 0, 32, 0,32, 32,32, 0, 32,32,32,
  132. 32,32,32, 0, 0,63, 0,63, 0, 0,63,63, 63, 0, 0, 63, 0,63, 63,63, 0, 63,63,63);
  133. {$ENDIF}
  134. Procedure set80x43; { Sets up 80x43, no blink, no cursor. }
  135. Var
  136. regs : TRealRegs;
  137. Begin
  138. regs.ax := $1201; { Set 350 scanlines }
  139. regs.bl := $30;
  140. realintr($10, regs);
  141. regs.ax := $3; { Set text mode }
  142. realintr($10, regs);
  143. regs.ax := $1112; { Set font }
  144. regs.bx := 0;
  145. realintr($10, regs);
  146. regs.bh := 0; { Kill cursor - doesn't seem to work.. }
  147. regs.ah := 3;
  148. realintr($10, regs);
  149. regs.cx := $2000;
  150. regs.ah := 1;
  151. realintr($10, regs);
  152. regs.ax := $1003; { Kill blink }
  153. regs.bl := 0;
  154. realintr($10, regs);
  155. regs.ax := $0200; { Position cursor to 51,80 - better way to kill. }
  156. regs.bx := $0033;
  157. regs.dx := $004f;
  158. realintr($10, regs);
  159. End;
  160. Procedure set80x50; { Sets up 80x50, no blink, no cursor. }
  161. Var
  162. regs : TRealRegs;
  163. Begin
  164. regs.ax := $1202; { Set 400 scanlines }
  165. regs.bl := $30;
  166. realintr($10, regs);
  167. regs.ax := $3; { Set text mode }
  168. realintr($10, regs);
  169. regs.ax := $1112; { Set font }
  170. regs.bx := 0;
  171. realintr($10, regs);
  172. regs.bh := 0; { Kill cursor - doesn't seem to work.. }
  173. regs.ah := 3;
  174. realintr($10, regs);
  175. regs.cx := $2000;
  176. regs.ah := 1;
  177. realintr($10, regs);
  178. regs.ax := $1003; { Kill blink }
  179. regs.bl := 0;
  180. realintr($10, regs);
  181. regs.ax := $0200; { Position cursor to 51,80 - better way to kill. }
  182. regs.bx := $0033;
  183. regs.dx := $004f;
  184. realintr($10, regs);
  185. End;
  186. Procedure set80x25; { Resets 80x25, blink, cursor. }
  187. Var
  188. regs : TRealRegs;
  189. Begin
  190. regs.ax := $1202; { Set 400 scanlines }
  191. regs.bl := $30;
  192. realintr($10, regs);
  193. regs.ax := $3; { Set text mode }
  194. realintr($10, regs);
  195. regs.ax := $1114; { Set font }
  196. regs.bx := 0;
  197. realintr($10, regs);
  198. regs.bh := 0; { Ressurrect cursor }
  199. regs.ah := 3;
  200. realintr($10, regs);
  201. regs.cx := regs.cx And $dfff;
  202. regs.ah := 1;
  203. realintr($10, regs);
  204. regs.ax := $1003; { Enable blink }
  205. regs.bl := 1;
  206. realintr($10, regs);
  207. End;
  208. Procedure border(color : Byte); { _ONLY_ for debugging! }
  209. Begin
  210. inportb($3da);
  211. outportb($3c0, 17+32);
  212. outportb($3c0, color);
  213. End;
  214. Procedure vrc; { Although all should be timer-synced instead.. }
  215. Begin
  216. While (inportb($3da) And 8) = 0 Do ;
  217. While (inportb($3da) And 8) <> 0 Do ;
  218. End;
  219. {#define COLMAP(r,g,b) *(colmap+((r)<<(COLORMAP_DEPTH*2))+((g)<<COLORMAP_DEPTH)+(b))}
  220. Function COLMAP_(r, g, b : Integer) : Integer;{ Inline;}
  221. Begin
  222. COLMAP_ := (colmap + ((r Shl (COLORMAP_DEPTH*2)) + (g Shl COLORMAP_DEPTH) + b))^;
  223. End;
  224. Procedure COLMAPSet(r, g, b, v : Integer);{ Inline;}
  225. Begin
  226. (colmap + ((r Shl (COLORMAP_DEPTH*2)) + (g Shl COLORMAP_DEPTH) + b))^ := v;
  227. End;
  228. Function calcpal_colorbase(red, green, blue : Real) : Word;
  229. Var
  230. a, b, c, d, ch, co : Integer;
  231. lastdist, dist : Double;
  232. Begin
  233. red := red * 1.2;
  234. green := green * 1.2;
  235. blue := blue * 1.2;
  236. lastdist := 1e242;
  237. d := 0;
  238. For c := 0 To 15 Do
  239. Begin
  240. dist := sqr(palette[d + 0] - red) +
  241. sqr(palette[d + 1] - green) +
  242. sqr(palette[d + 2] - blue);
  243. If dist < lastdist Then
  244. Begin
  245. lastdist := dist;
  246. co := c;
  247. ch := 219; { 100% block in IBMSCII }
  248. End;
  249. Inc(d, 3);
  250. End;
  251. c := co;
  252. d := c*3;
  253. a := 0;
  254. For b := 0 To 15 Do
  255. Begin
  256. dist := sqr(((palette[a+0]+palette[d+0]) / 2.0) - red) +
  257. sqr(((palette[a+1]+palette[d+1]) / 2.0) - green) +
  258. sqr(((palette[a+2]+palette[d+2]) / 2.0) - blue);
  259. If dist < lastdist Then
  260. Begin
  261. lastdist := dist;
  262. co := b + (c Shl 4);
  263. ch := 177; { 50% block in IBMSCII }
  264. End;
  265. {$IFDEF __USE_178NOT176}
  266. dist := sqr((palette[a+0]*0.75+palette[d+0]*0.25) - red) +
  267. sqr((palette[a+1]*0.75+palette[d+1]*0.25) - green) +
  268. sqr((palette[a+2]*0.75+palette[d+2]*0.25) - blue);
  269. If dist < lastdist Then
  270. Begin
  271. lastdist := dist;
  272. co := b + (c Shl 4);
  273. ch := 178; { 75% block in IBMSCII }
  274. End;
  275. dist := sqr((palette[a+0]*0.25+palette[d+0]*0.75) - red) +
  276. sqr((palette[a+1]*0.25+palette[d+1]*0.75) - green) +
  277. sqr((palette[a+2]*0.25+palette[d+2]*0.75) - blue);
  278. If dist < lastdist Then
  279. Begin
  280. lastdist := dist;
  281. co := c + (b Shl 4);
  282. ch := 178; { 75% block in IBMSCII }
  283. End;
  284. {$ELSE}
  285. dist := sqr((palette[a+0]*0.25+palette[d+0]*0.75) - red) +
  286. sqr((palette[a+1]*0.25+palette[d+1]*0.75) - green) +
  287. sqr((palette[a+2]*0.25+palette[d+2]*0.75) - blue);
  288. If dist < lastdist Then
  289. Begin
  290. lastdist := dist;
  291. co := b + (c Shl 4);
  292. ch := 176; { 25% block in IBMSCII }
  293. End;
  294. dist := sqr((palette[a+0]*0.75+palette[d+0]*0.25) - red) +
  295. sqr((palette[a+1]*0.75+palette[d+1]*0.25) - green) +
  296. sqr((palette[a+2]*0.75+palette[d+2]*0.25) - blue);
  297. If dist < lastdist Then
  298. Begin
  299. lastdist := dist;
  300. co := c + (b Shl 4);
  301. ch := 176; { 25% block in IBMSCII }
  302. End;
  303. {$ENDIF}
  304. Inc(a, 3);
  305. End;
  306. calcpal_colorbase := (co Shl 8) + ch;
  307. End;
  308. {*
  309. * Unlike _colorbase, _lightbase and _gscale calculations are
  310. * based on some trivial assumptions, such as that the character
  311. * tables have linear grayscale ramps and stuff like that.
  312. *
  313. * ie: they are *not* accurate!
  314. *
  315. * The tables were generated by calculating the dot distance from
  316. * center of character, ((xdistmax-xdist)^2)+((ydistmax-ydist)^2),
  317. * and sorting by this value. (HOW are you supposed to calculate
  318. * random pattern lightness value anyway?! =)
  319. *
  320. * Bright and dark color values are just thrown in without any
  321. * math background. (How could there be some? At this point you
  322. * should realize we have thrown all accurancy out the window).
  323. *
  324. * So. They work - kinda. They don't work correctly, but there
  325. * you go.
  326. *
  327. * color ramp= (dark color) [0 .. 1] + (light color) [0.3 .. 1]
  328. *
  329. * (didn't bother to rip AAlib :)
  330. *}
  331. Function calcpal_lightbase(red, green, blue : Real) : Word;
  332. Var
  333. light, col, a, a3 : Integer;
  334. lastdist, dist : Real;
  335. Begin
  336. lastdist := 1e24;
  337. a3 := 3;
  338. For a := 1 To 15 Do
  339. Begin
  340. dist := Sqr(palette[a * 3 + 0] - red) +
  341. Sqr(palette[a * 3 + 1] - green) +
  342. Sqr(palette[a * 3 + 2] - blue);
  343. If dist < lastdist Then
  344. Begin
  345. lastdist := dist;
  346. col := a;
  347. End;
  348. Inc(a3, 3);
  349. End;
  350. light := Trunc(((0.2990 * red + 0.5870 * green + 0.1140 * blue) / 63) * 64);
  351. If light < 32 Then
  352. light := Trunc(((0.2990 * red + 0.5870 * green + 0.1140 * blue) / 63) * 1.5 * use_charset^)
  353. Else
  354. light := Trunc(((0.2990 * red + 0.5870 * green + 0.1140 * blue) / 63) * use_charset^);
  355. calcpal_lightbase := (col Shl 8) + (use_charset + light + 1)^;
  356. End;
  357. Function calcpal_lightbase_g(red, green, blue : Real) : Word;
  358. Var
  359. light : Integer;
  360. Begin
  361. light := Trunc(((0.2990 * red + 0.5870 * green + 0.1140 * blue) / 63) * use_charset^);
  362. calcpal_lightbase_g := (7 Shl 8) + (use_charset + light + 1)^;
  363. End;
  364. Function calc_gscale(light : Real) : Word;
  365. Begin
  366. calc_gscale := (7 Shl 8) + (use_charset + Trunc(light * (use_charset^ + 1)))^;
  367. End;
  368. Function calc_gscale2(light : Real) : Word;
  369. Begin
  370. If light < 0.3 Then
  371. calc_gscale2 := (8 Shl 8) + (use_charset + Trunc(light * 3 * (use_charset^ + 1)))^
  372. Else
  373. If light < 0.6 Then
  374. calc_gscale2 := (7 Shl 8) + (use_charset + Trunc((light + 0.3) * (use_charset^ + 1)))^
  375. Else
  376. calc_gscale2 := (15 Shl 8) + (use_charset + Trunc(light * (use_charset^ + 1)))^;
  377. End;
  378. Procedure build_colormap(dots : Integer);
  379. Const
  380. wheel : Array[0..3] Of Char = ('-', '\', '|', '/');
  381. Var
  382. r, g, b : Integer;
  383. f : Double;
  384. Begin
  385. If dots = 2 Then
  386. Write(' ');
  387. If colmap <> Nil Then
  388. FreeMem(colmap);
  389. f := 64.0 / COLMAPDIM;
  390. colmap := GetMem(SizeOf(SmallInt) * COLMAPDIM * COLMAPDIM * COLMAPDIM);
  391. For r := 0 To COLMAPDIM - 1 Do
  392. Begin
  393. For g := 0 To COLMAPDIM - 1 Do
  394. For b := 0 To COLMAPDIM - 1 Do
  395. COLMAPSet(r, g, b, calcpal(r * f, g * f, b * f));
  396. If dots = 1 Then
  397. Write('.');
  398. If dots = 2 Then
  399. Write({#127}#8, wheel[r And 3]);
  400. End;
  401. End;
  402. Procedure dispose_colormap;
  403. Begin
  404. If colmap <> Nil Then
  405. FreeMem(colmap);
  406. colmap := Nil;
  407. End;
  408. Procedure dump_80x(y0, y1 : Integer; buffer : PInteger);
  409. Var
  410. x, y, yd : Integer;
  411. scr : DWord;
  412. buf : PByte;
  413. Begin
  414. buf := PByte(buffer);
  415. scr := $b8000 + (y0 * 160);
  416. yd := y1 - y0;
  417. For y := 0 To yd - 1 Do
  418. For x := 0 To 79 Do
  419. Begin
  420. MemW[scr] := COLMAP_((buf + 0)^ Shr TRUCOLBITS,
  421. (buf + 1)^ Shr TRUCOLBITS,
  422. (buf + 2)^ Shr TRUCOLBITS);
  423. Inc(scr, 2);
  424. Inc(buf, 4);
  425. End;
  426. End;
  427. Procedure dump_160x(y0, y1 : Integer; buffer : PInteger);
  428. Var
  429. x, y, yd : Integer;
  430. i : DWord;
  431. scr : DWord;
  432. buf : PByte;
  433. Begin
  434. buf := @i;
  435. scr := $b8000 + (y0 * 160);
  436. yd := y1 - y0;
  437. For y := 0 To yd - 1 Do
  438. Begin
  439. For x := 0 To 79 Do
  440. Begin
  441. i := ((buffer+0)^ And $fcfcfcfc)+
  442. ((buffer+1)^ And $fcfcfcfc)+
  443. ((buffer+160)^ And $fcfcfcfc)+
  444. ((buffer+161)^ And $fcfcfcfc);
  445. i := i Shr 2;
  446. i := i And $fcfcfcfc;
  447. MemW[scr] := COLMAP_((buf + 0)^ Shr TRUCOLBITS,
  448. (buf + 1)^ Shr TRUCOLBITS,
  449. (buf + 2)^ Shr TRUCOLBITS);
  450. Inc(scr, 2);
  451. Inc(buffer, 2);
  452. End;
  453. Inc(buffer, 160);
  454. End;
  455. End;
  456. Procedure dump_320x(y0, y1 : Integer; buffer : PInteger);
  457. Var
  458. x, y, yd, r, g, b, xx, yy : Integer;
  459. buf : PByte;
  460. scr : DWord;
  461. Begin
  462. buf := PByte(buffer);
  463. scr := $b8000 + (y0 * 160);
  464. yd := y1 - y0;
  465. For y := 0 To yd - 1 Do
  466. Begin
  467. For x := 0 To 79 Do
  468. Begin
  469. r := 0; g := 0; b:= 0;
  470. xx := 0;
  471. While xx < 4 * 4 Do
  472. Begin
  473. yy := 0;
  474. While yy < 4 * 4 * 320 Do
  475. Begin
  476. Inc(r, (buf + xx + yy + 0)^);
  477. Inc(g, (buf + xx + yy + 1)^);
  478. Inc(b, (buf + xx + yy + 2)^);
  479. Inc(yy, 320 * 4);
  480. End;
  481. Inc(xx, 4);
  482. End;
  483. MemW[scr] := COLMAP_(r Shr (TRUCOLBITS + 4),
  484. g Shr (TRUCOLBITS + 4),
  485. b Shr (TRUCOLBITS + 4));
  486. Inc(scr, 2);
  487. Inc(buf, 4 * 4);
  488. End;
  489. Inc(buf, 80 * 4 * 4 * 3);
  490. End;
  491. End;
  492. End.