home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / MCGA#07.ZIP / LESSON07.TXT < prev    next >
Encoding:
Text File  |  1992-06-09  |  8.4 KB  |  181 lines

  1.                            MCGA Graphics Tutorial
  2.                                  Lesson #7
  3.                                 by Jim Cook
  4.  
  5. Howdy!  This is going to be semi-cool.  Although, I have mentioned that
  6. MCGA #7 was going to address page flipping, I lied!  Many of you are
  7. probably trying to display PCX images that were not created with the
  8. default palette, so this issue will address everything you ever wanted
  9. to know about palettes.  We aren't going to mess around with those
  10. sweet, neat BIOS routines either!  Why not?  'Cause they're slooow!
  11.  
  12. But first! a couple additions to the source I have already posted.  The
  13. DisplayPCX routine seems to work fine for PCX images with an even width,
  14. but (and you knew there was a but) when the PCX is saved with an odd
  15. numbered width, it seems the PCX format calls for an extra byte to be
  16. added for padding.  I use Deluxe Paint II enhanced for all of my
  17. artwork, and it adds the pad byte.  I cannot assume that it will do this
  18. for everyone.  To fix the currrent routine add the indicated line:
  19.  
  20.         Procedure DisplayPCX (X,Y:Integer;Buf:Pointer);
  21.         ...
  22.           NumRows   := Header^.YMax - Header^.YMin + 1;
  23.           BytesWide := Header^.XMax - Header^.XMin + 1;
  24.   >>>>>>  If Odd (BytesWide) then Inc (BytesWide);      <<<<<<
  25.  
  26.           For I := 1 to NumRows do begin
  27.         ...
  28.  
  29. I think that this should fix most problems, but let me know if it
  30. doesn't.  Just one more thing.  Those of you familiar with assembly will
  31. notice that my assembly routines contain rep movsw or some other
  32. repetitive move, store, or read command.  You also know that these
  33. repetitive commands can work in forwards or reverse.  Well, we want them
  34. to go forwards and I forgot the itty bitty command to do this.  Add
  35.  
  36.         cld
  37.  
  38. to the following routines:
  39.  
  40.         Procedure ClearScreen (Color:Byte);
  41.         Procedure HorzLine (X1,X2,Y1:Integer;Color:Byte);
  42.         Procedure ExtractLineASM (BytesWide:Integer;Var Source,Dest:Pointer);
  43.         Procedure GetImageAsm (X1,Y1,X2,Y2:Integer;P:Pointer); assembler;
  44.         Procedure PutImageAsm (X1,Y1:Integer;P:Pointer); assembler;
  45.  
  46. Just put the cld command on a line by itself in each routine before a
  47. rep command is encountered.  By the way, don't put it in a loop!
  48.  
  49. OK, enough dwelling on the past.  Let's put it in high gear and learn
  50. this palette stuff.
  51.  
  52. The MCGA palette consists of 256 colors.  Those 256 colors (numbered 0
  53. through 255) can be chosen from a total palette of 262,144 colors.  How
  54. did they come up with this number?  To understand this concept we have
  55. to change the way we think about color.  Think of color in terms of
  56. Textmode.  We have numbers to represent colors.  For example 0 is Black,
  57. and 15 is white.  It's similar in MCGA modes, in that, if you had a picture
  58. that was made up of color #15, it would probably be a screen full of white.
  59. Suppose we wanted to make it a screen full of Black?  We could fill the
  60. entire screen with color #0, OR we could change the color of #15.  I can
  61. hear the buzzing now.  All color #15 means is, color #15 points to a
  62. lookup table (PEL) where three bytes are waiting to designate the percentage
  63. of red, green and blue that make up that color.  Take a look at the
  64. sketch below.  If you looked at the address in memory where the
  65. information is stored for color #209 it would look like this:
  66.  
  67.                                  │    8h   │
  68.                                  ├─────────┤
  69.                              Red │    8h   │ < Color #209
  70.                                  ├─────────┤
  71.                            Green │   16h   │
  72.                                  ├─────────┤
  73.                             Blue │   10h   │
  74.                                  ├─────────┤
  75.                                  │    8h   │
  76.  
  77. What the PEL tells us, is color #209 is made up of 8% red, 22% green,
  78. and 16% blue.  A 50% gray is represented as $32,$32,$32. You will notice
  79. that the largest percentage number (63) can be represented in 6 bits
  80. (111111b).  You may sometimes see this type of palette written as 6-6-6.
  81. I said that the maximum number of colors we can choose our screen colors
  82. from is 262,144.  This comes about by considering all of the possible color
  83. combinations of red, green and blue yielding 64 x 64 x 64 = 262,144!
  84.  
  85. If this is getting confusing, drop me a note and I will spend some more
  86. time on this.  It really is critical to understanding smooth fades.
  87.  
  88. You may think that updating a color #'s RGB value is as easy as putting
  89. new values into the PEL area of memory.  This is true, but with one
  90. catch.  The PEL resides on your graphics card.  We cannot update it
  91. simply by poking a new byte into memory.  Instead, we communicate to the
  92. VGA card via latches or IO ports.  Welcome to the wonderful, wacky world
  93. of the VGA.
  94.  
  95. To set a RGB sequence we concern ourselves with two ports.  Let's say we
  96. want to change color #209 to the RGB values of (20h,40h,60h).  First we
  97. send the number of the color we want to alter out port #03C8:
  98.  
  99.         Port [$03C8] := 209
  100.  
  101. Next, we send the RGB values we want to change to out through port #03C9:
  102.  
  103.         Port [$03C9] := $20;
  104.         Port [$03C9] := $40;
  105.         Port [$03C9] := $60;
  106.  
  107. After we update each red, green, and blue value, port $3C8 advances to
  108. the next color number and we could do that one right away.  I can't
  109. begin to tell you how much faster this is than using the BIOS routines
  110. to do the same thing.  It was pretty painless also.
  111.  
  112. There is one thing to consider.  While our palette is 6-6-6, the PCX
  113. format saves its palette as 8-8-8.  This means that White, for example,
  114. is stored as ($FF,$FF,$FF), while we need it as ($63,$63,$63).  This is
  115. very simple to fix.  Simply read in the palette, and as each byte comes
  116. in shift it two places to the right.
  117.  
  118. So much for writing a palette register.  Reading the RGB values for a
  119. color register is just as simple.  the only difference is the first port
  120. we call is $3C7:
  121.  
  122.         Port [$03C7] := 209
  123.         Red   := Port [$03C9];
  124.         Green := Port [$03C9];
  125.         Blue  := Port [$03C9];
  126.  
  127. The rest of the routine stays the same.
  128.  
  129. Have you ever seen a professionaly written computer game fade to black,
  130. just like on the TV when a commercial comes on.  I call this a
  131. commercial fade.  What you do is gradually take all of the palette's RGB
  132. values slowly to a RGB value of (0,0,0).  The trick is to take each
  133. color to Black at equal percentages.  For example, if you have the color
  134. white ($63,$63,$63) and you want to make it approach black (0,0,0) and
  135. you want to do this over 10 steps, you get the following gradient:
  136.  
  137.  
  138.   Before Fade: 100%   $63,$63,$63          Step 4:  40%   $28,$28,$28
  139.        Step 1:  90%   $5A,$5A,$5A          Step 3:  30%   $1E,$1E,$1E
  140.        Step 2:  80%   $50,$50,$50          Step 2:  20%   $14,$14,$14
  141.        Step 3:  70%   $46,$46,$46          Step 1:  10%   $0A,$0A,$0A
  142.        Step 4:  60%   $3C,$3C,$3C      Final Step:  00%   $00,$00,$00
  143.        Step 5:  50%   $32,$32,$32
  144.  
  145. That represents a subtle change in white to black.  You can apply the
  146. same percentages to any color combination.  Due to lack of space, I do
  147. not want to get into the math associated with making this a general
  148. purpose routine, but please take the time to look closely at the
  149. SetupFade and FadePalette routines in the accompanying source message.
  150.  
  151. Did he say "accompanying?"  Yes, I am having a difficult time keeping
  152. these tutorials short.  I do not believe in just posting code and having
  153. it scavenged.  I think the purpose of this echo is to provoke thought
  154. and encourage education.  Please take the time to peruse the code
  155. thoroughly and ask questions if you do not understand.
  156.  
  157. The accompanying code contains a new unit called PALETTE.  I though it
  158. better to separate the palette source from the rest of the code.  With
  159. very minor tweaking the palette unit can be used in all video modes,
  160. including Super VGA!  Once again, I have written the routine in Pascal
  161. for readability (as well as y'all with < TP 6.0).  You may see reference
  162. to WritePalette in future programs.  I'm going to remove the Pascal
  163. routines and stick with assembler for speeeed.  Those of you that cannot
  164. due to compiler restrictions, please nix the assembler routines and
  165. rename the WritePalettePas procedure to WritePalette.  Hope that makes
  166. sense.
  167.  
  168. P.S.:  I included a bonus procedure I call OREO.  It makes a color
  169. picture into a black and white.  A major threat to Ted Turner's
  170. colorization process!......NOT!
  171.  
  172. jim
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181.