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

new topic     » topic index » view message » categorize

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  .

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu