1. VGA (mode 18) Questions
I've been rewriting the GUI toolkit to work in move 18 (VGA graphics). I've
gotten most of it up and running, but I suspect that there are much better
ways to do this.
There may be errors in the examples, since I've tried to cut out the
extraneous details from an already long posting. In practice, the *do* work.
QUESTION #1
-----------
I finally figured out a way to write colored text on colored backgrounds in
mode 18, but if anyone's got a better suggestion, could someone let me know?
I ended up doing an interrupt, and ORing the text to the screen. The first
write puts the text down in the background color. This gives a mask of black
letters against the background (color OR color = 0 = BLACK). Then I write
the string out again, and the result is the text in the color I want (color
OR color = color).
-- CODE BEGINS HERE
---------------------------------------------------------
global procedure graphic_text( integer row, integer col,
integer fColor, integer bColor, sequence char )
object lowMem
sequence inReg, outReg
lowMem = allocate_low( length( char ) ) -- get memory
poke( lowMem, char ) -- move string
-- first, OR the text with the background to
-- make it black
inReg = repeat( 0, 10 ) -- initialize register list
inReg[REG_AX] = #1300 -- tty string write
inReg[REG_BX] = bColor -- video page/color
inReg[REG_CX] = length( char ) -- number of characters to print
inReg[REG_DX] = (row-1)*#100+(col-1) -- position of cursor
inReg[REG_ES] = floor(lowMem / cTall) -- segment of low_mem
inReg[REG_BP] = remainder(lowMem, cTall) -- offset of low_mem
outReg = dos_interrupt( #10, inReg ) -- bios call
-- next, logical OR it with the black mask for the
-- correct color
inReg[REG_BX] = fColor -- video page/color
outReg = dos_interrupt( #10, inReg ) -- bios call
free_low( lowMem ) -- free the memory
end procedure
-- END OF CODE -----------------------------------------------------------
Is there a better way to do this? It's actually pretty fast, but if there's
a "proper" way to do this, I'd like to know.
QUESTION #2
-----------
I need to display text of one color against a background of another. There
are multiple different background colors on the screen at the same time.
Unlike text mode, I can't just change the background color, since it only
alters the pallatte of color 0 (BLACK). This is counter-productive for my
purposes.
To get around this, I paint a background in the appropriate color, and then
write to it using the prior procedure. A call to the procedure looks like:
position( 12, 13 ) -- position the cursor
put_graphic_colors( {BLACK, WHITE}, "Hello, World!" )
Here's the procedure:
-- CODE BEGINS HERE
---------------------------------------------------------
global procedure put_graphic_colors( sequence colors,
integer row, integer col,
sequence text )
-- emulate put_colors for graphics colors display
integer row1, col1, row2, col2
-- check for zero length
if length( text ) = 0 then
return
end if
-- convert to graphics coordinates
row1 = (row-1)*16
col1 = (col-1)*8
row2 = row1 + 16
col2 = col1 + ( length( text ) * 8 )
-- paint background color
polygon( colors[2], 1,
{{col1,row1},{col1,row2},{col2,row2},{col2,row1}} )
-- text
graphic_text( row, col, colors[1], colors[2], text )
-- position cursor
if col+length( text ) <= SCREEN_WIDE
position( row, col+length(text) )
end if
end procedure
-- END OF CODE -----------------------------------------------------------
This works fine, but seems terribly inefficient, especially when displaying
a screen full of text (as the editor does). Is there a way that I can simply
write a string to the VGA screen with a given foreground and background
attribute?
QUESTION #3
-----------
When the GUI paints a window, it stores the background of that window so it
can restore the screen when it closes the window.
In text mode, the routine is fast enough that I could save the whole screen
and not have any negative effect (timewise) on the program. However, this is
*not* true when working with bitmaps. They are terribly *slow*.
I suspect that this is because the bitmap is converted to a Euphoria object,
and back again when it is written to the screen.
I was wondering if there were any blitting routines available in the BIOS
that would do a video move to and from memory for me, bypassing the Euphoria
representation altogether. That way, I could just allocate memory, and blit
the bitmap to and from memory.
Is this feasible? Or is the idea doomed because Euphoria only allows low
memory to be allocated, which is far to scarce to use for this purpose?
Thanks in advance.
-- David Cuny
2. Re: VGA (mode 18) Questions
> QUESTION #1
> -----------
> I finally figured out a way to write colored text on colored backgrounds in
> mode 18, but if anyone's got a better suggestion, could someone let me know?
> I ended up doing an interrupt, and ORing the text to the screen. The first
> write puts the text down in the background color. This gives a mask of black
> letters against the background (color OR color = 0 = BLACK). Then I write
> the string out again, and the result is the text in the color I want (color
> OR color = color).
i believe you can write text directly to video memory via:
procedure text_write(integer bk_colour, integer fore_colour,
integer char,integer pos)
-- pos is (screen_width * y + x) * 2
-- this is assuming 0,0 is the top left corner, not 1,1
poke(#A8000 + pos,{char, 16 * bk_colour + fore_colour})
end procedure
obviously you can simplify this
. . o o O O Mike Burrell O O o o . .
. o O http://www.geocities.com/SoHo/9036 O o .
. o o O mikpos at gaianet.net O o o .
3. Re: VGA (mode 18) Questions
Thanks for the code, Mike. But I can't seem to get it to work in graphic
mode 18. It works fine if I set it to mode 1 and used #B8000, the start of
color VGA memory.
-- CODE STARTS HERE
include graphics.e
procedure text_write(integer bk_colour, integer fore_colour,
integer char,integer pos)
-- pos is (screen_width * y + x) * 2
-- this is assuming 0,0 is the top left corner, not 1,1
poke(#A8000 + pos,{char, 16 * bk_colour + fore_colour})
end procedure
integer result
result = graphics_mode( 18 )
text_write( RED, GREEN, 'A', 0 )
-- CODE ENDS HERE
btw, There is one error (at least) in my example code I posted. Where I had
written:
inReg[REG_BX] = bColor -- video page/color
and
inReg[REG_BX] = fColor -- video page/color
I should have put:
inReg[REG_BX] = #F0 + bColor -- video page/color
and
inReg[REG_BX] = #F0 + fColor -- video page/color
One of those high bits (I forget which, so I set them all) tells the BIOS to
OR the pixels. Sorry.
Thanks.
-- David Cuny