1. VGA (mode 18) Questions
- Posted by "Cuny, David" <ATB.DCUNY at HW1.CAHWNET.GOV> Mar 17, 1997
- 1269 views
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
- Posted by mike burrell <Mike.Burrell at EARTH.GAIANET.NET> Mar 17, 1997
- 1119 views
> 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
- Posted by "Cuny, David" <ATB.DCUNY at HW1.CAHWNET.GOV> Mar 18, 1997
- 1177 views
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