Graphics Bitmaps Drawing alphabetic characters and multicolor patterns

advertisement
Graphics Bitmaps
Drawing alphabetic characters
and multicolor patterns
Finding the ROM fonts
• Standard BIOS service locates ROM fonts
• Designed to execute in 8086 real-mode
• Normal service-call protocol is followed:
– Parameters are placed in CPU registers
– Software interrupt instruction is executed
– ROM-BIOS code performs desired service
– Parameters may be returned in registers
Example
# AT&T assembly language syntax
mov
$0x11, %ah # char. gen. services
mov
$0x30, %al # get font information
mov
$2, %bh
# 8x14 font address
int
$0x10
# request BIOS service
# the font address is returned in ES:BP
# (and count of scanlines should be in CX)
Interface for Linux
•
•
•
•
•
•
•
No C++ syntax to access CPU registers
Software interrupt is privileged operation
Must call kernel to obtain BIOS services
How to do it isn’t very clearly documented
SVGALIB Project: includes ‘LRMI’ wrapper
An acronym for Linux Real-Mode Interface
Idea: make it easy to invoke BIOS calls
How LRMI is used
•
•
•
•
C program needs: #include “lrmi.h”
Needs to do initialization: LRMI_init();
Declares: struct LRMI_regs reg = {0};
Code-example:
reg.eax = 0x1130;
reg.ebx = 0x0200;
LRMI_int( 0x10, &reg );
int
font_address = reg.ebp + 16*reg.es;
Link with ‘lrmi.o’ object-module
• Need to precompile ‘lrmi.c’ source-text:
gcc –c lrmi.c
• For C++ you need overriding prototypes:
extern “C” int LRMI_init( void ); # etc.
#include “lrmi.h”
# this comes after
• To compile and link your C++ program:
g++ drawtext.cpp lrmi.o -o drawtext
Acknowledgement
• The author of ‘LRMI’ is Josh Vanderhoof
• His code is part of the SVGALIB package
• Full package can be downloaded from:
http://www.svgalib.org
• Downloaded as a compressed ‘.tar’ file:
Example: svgalib-1.4.3.tar.gz
• Use the ‘tar’ command to ‘expand’ it:
tar -xvzf svgalib-1.4.3.tar.gz
Copying 8x14 ROM font
•
•
•
•
Need to memory-map the ROM region
‘mmap()’ requires map to be 4K-aligned
Size of mapped region: 0x1000 (256*16)
Need to allocate a local array in RAM:
static unsigned char glyph[256][16];
for (c = 0; c < 256; c++)
for (r =0; r < 14; r++)
glyph[ c ][ r ] = *font_addr++;
Drawing a character (in mode 19)
•
•
•
•
•
•
•
Must memory-map the VRAM window
Physical base-address is 0x000A0000
Size of VRAM window is 64K: (64<<10)
Use the ascii-code as a glyph-table index
Specify the character’s ‘foreground color’
Use x,y coordinates for character location
So your function prototype could be:
void draw_char( int ascii, int color );
Implementing ‘draw_char()’
int
hres = 320, vres = 200;
unsigned char *dstn = 0x000A0000;
dstn += ( y * hres + x ); # where to start drawing
for (r = 0; r < 14; r++)
# 14-rows high
{
for (w = 0; w < 8; w++)
# 8-pixels wide
if ( glyph[ ascii ][ r ] & (0x80>>w) )
dstn[ w ] = fgcolor;
dstn += hres;
# drop to next screen row
}
Some comparisons
•
•
•
•
•
•
text mode
‘character generator’ imposes a fixed grid
All characters from a common glyph-table
Character backgrounds always solid color
graphics mode
You can freely mix numerous font styles
You can place characters at any positions
You can draw against backgound patterns
Using bitmap ‘patterns’
• You can create interesting backgrounds
• Fill screen regions with a copied pattern
0xFF
0x80
0x80
0x80
0xFF
0x08
0x08
0x08
foreground
color
background
color
Algorithm for ‘tiling’ (mode 19)
unsigned char pat[ 8 ];
# 8x8 2-color bitmap
unsigned char *vram = 0x000A0000, color;
for (int y = 0; y < vres; v++)
for (int x = 0; x < hres; x++)
{
int
r = y % 8, k = x % 8;
color = ( pat[ r ] & (0x80>>k) ) ? fg : bg;
vram[ y*hres + x ] = color;
}
Automating pattern-creation
• Try these standard runtime functions;
#include <stdlib.h>
int rand( void );
void srand( unsigned int seed );
• Can make new 8x8 patterns like this:
for (k = 0; k < 8; k++) pat[ k ] = rand();
fgcolor = rand(); bgcolor = rand();
Esthetics
• Use a ‘brighter’ color in the foreground
• Use a ‘darker’ color in the background
• To implement this discipline we need to
know how the ‘color-table’ is arranged
• In mode 19 there are 256 default colors
• Among these are 24 color-groups:
– 3 intensity-levels plus 3 saturation-levels
The ‘default’ colors (mode 19)
•
•
•
•
•
•
•
Range for the 72 brightest colors: 32–103
Range for the 72 midlevel colors: 104-175
Range for the 72 darkest colors: 176-247
Colors 0-15 are the standard EGA colors
Colors 16-31 are sixteen grayscale colors
Colors 248-255 are solid black (default)
(But all of these are fully ‘programmable’)
Choosing a random color-pair
• foreground color (from the ‘bright’ range):
fgcolor = ( ( rand() & 0xFF ) % 72 ) + 32;
• Background color (from the ‘dark’ range):
bgcolor = ( ( rand() & 0xFF ) % 72 ) + 104;
Using patterns with more colors
•
•
•
•
Same concepts can be extended
But need a larger pattern-bitmap
Example: use 2 bits-per-pixel (4 colors)
An 8x8 pattern that using 4 colors:
unsigned short
pat2bpp[ 8 ];
unsigned char
palette4[ 4 ];
for (r = 0; r < 8; r++) pat2bpp[ r ] = rand();
for (c = 0; c < 4; c++) palette4[ c ] = rand();
Tiling with a 4-color bitmap
for (y = 0; y < hres; y++)
{
unsigned short
bits = pat2bpp[ y % 8 ];
for (x = 0; x < hres; x++)
{
int
i = ( bits >> ( x % 8 )&3;
int
color = palette4[ i ];
vram[ y*hres + x ] = color;
}
}
Automating an ‘art show’
• Can use a standard C runtime function:
#include <stdlib.h>
void sleep( int seconds );
• User views your screen for fixed duration:
while ( !done )
{
draw_next_scene(); sleep(1);
}
Download