Graphics mode
Graphics mode
hi every body...
i want to know how can i write a char in graphics mode with
simple assembly IRQ please be carefull writing a char not put a pixel
becasue i tried to write a char with assembly 0x10 int
and function 0x0e,i wrote the char but it gave me black background
on my blue one
i want to know how can i write a char in graphics mode with
simple assembly IRQ please be carefull writing a char not put a pixel
becasue i tried to write a char with assembly 0x10 int
and function 0x0e,i wrote the char but it gave me black background
on my blue one
Re:Graphics mode
Hi,
If you're not using a standard VGA mode (for e.g. you've used VBE to set an SVGA mode) then you should write your own routines to draw characters - IIRC the VBE standard says that support for any of the BIOS character output routines is optional (so character output might work in some modes on some video cards, but not on all video cards).
I'd recommend writing your own routines to draw characters anyway - the BIOS functions are too slow.
Cheers,
Brendan
If you're using a standard VGA mode (e.g. mode 0x12 or 0x13) you might be able to use the write character and attribute at cursor or the write character at cursor BIOS functions (instead of the teletype output function).ajanh wrote:i want to know how can i write a char in graphics mode with
simple assembly IRQ please be carefull writing a char not put a pixel
becasue i tried to write a char with assembly 0x10 int
and function 0x0e,i wrote the char but it gave me black background
on my blue one
If you're not using a standard VGA mode (for e.g. you've used VBE to set an SVGA mode) then you should write your own routines to draw characters - IIRC the VBE standard says that support for any of the BIOS character output routines is optional (so character output might work in some modes on some video cards, but not on all video cards).
I'd recommend writing your own routines to draw characters anyway - the BIOS functions are too slow.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re:Graphics mode
plus with your own routine it should be very easy to add new fonts and change them
it shouldn't be too hard to do
all you have to do is make a font
the font format should be bitmaps of each character so every bit represents 1 pixel and if it is set then you draw the foreground color if its not then draw background
then just use plot(curx*8+x_draw,cury*8+y_draw) assuming you are using 8x8 characters(like most text modes) you just have a while loop and every time x_draw gets to 8(which you advance each pixel) you advance y_draw and set x_draw to 0
then when both y_draw and x_draw is 8 you advance curx BY ONE and if its a new line then you advance cury BY ONE
and voila
it shouldn't be too hard to do
all you have to do is make a font
the font format should be bitmaps of each character so every bit represents 1 pixel and if it is set then you draw the foreground color if its not then draw background
then just use plot(curx*8+x_draw,cury*8+y_draw) assuming you are using 8x8 characters(like most text modes) you just have a while loop and every time x_draw gets to 8(which you advance each pixel) you advance y_draw and set x_draw to 0
then when both y_draw and x_draw is 8 you advance curx BY ONE and if its a new line then you advance cury BY ONE
and voila
Re:Graphics mode
Hi,
For drawing characters there's different ways to do it, with different performance. The first thing I'd do is use a double buffer (draw the characters into RAM, and then when everything is ready copy from RAM into display memory). To speed this up I like to keep track of which lines have been changed and then only copy changed lines from RAM into display memory.
For 256 colour modes I'd consider getting rid of the inner loop of the character drawing code completely by using a lookup table and some bit fiddling. For example:
For the "normal" method, you end up with 64 conditional branches (one per bit) that the CPU can't predict correctly. Mis-predicted branches make peformance suck, and writing one byte/pixel at a time doesn't help much either.
Cheers,
Brendan
It's much easier to use the BIOS's fonts (which are in the same format). For example:Jordan3 wrote:all you have to do is make a font
the font format should be bitmaps of each character so every bit represents 1 pixel and if it is set then you draw the foreground color if its not then draw background
Code: Select all
mov bh,3 ;Get address for first half of BIOS 8 * 8 character font
mov ax,0x1130
int 0x10 ;es:bp = address of BIOS 8 * 8 characters (first half)
clr eax ;Make sure high 16 bits of [ieax] are clear
movzx ebx,bp ;ebx = real mode offset (with high 16 bits cleared)
mov ax,es ;eax = real mode segment (with high 16 bits cleared)
shl eax,4 ;eax = real mode segment base address
add eax,ebx ;eax = 32 bit address of font data
mov [fontAddress8x8_firstHalf],eax ;Set the 32 bit font address
For 256 colour modes I'd consider getting rid of the inner loop of the character drawing code completely by using a lookup table and some bit fiddling. For example:
Code: Select all
bitMaskTable:
db 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF ;0x00
db 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00 ;0x01
db 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xFF ;0x02
db 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00 ;0x03
db 0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xFF,0xFF ;0x04
<- more ->
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ;0xFF
;Input
; edx = foreground colour packed into each byte
; esi = address of font data for character
;
;Output
; edi = address for next character
drawCharacter:
push edi
clr ecx ;ecx = number of first character row
.nextRow:
movzx eax,[esi+ecx] ;eax = bit pattern for this row
mov ebx,[bitMaskTable+eax*8 ] ;ebx = bit mask for first dword
mov eax,[bitMaskTable+eax*8+4] ;eax = bit mask for second dword
and [edi],ebx ;Clear bits in first dword
and [edi+4],eax ;Clear bits in second dword
not ebx ;ebx = inverted bit mask for first dword
not eax ;eax = inverted bit mask for second dword
and ebx,edx ;ebx = foreground colour data for first dword
and eax,edx ;eax = foreground colour data for second dword
or [edi],edx ;Set first dword foreground bits to colour
or [edi+4],esi ;Set second dword foreground bits to colour
inc ecx ;ecx = number of next character row
add edi,[number_of_bytes_per_screen_line] ;edi = address of next line
cmp ecx,8 ;Have all character rows been done?
jb .nextRow ; no, keep going
pop edi
add edi,8
ret
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re:Graphics mode
You can take a look at some code i wrote, call "CdPod", it for vesa 640x480 32bpp, but by changing it abit it will work for any graphic mode.
http://www.dex4u.com/images/cdpod.zip
http://www.dex4u.com/images/cdpod.zip
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Graphics mode
Don't take it bad, i know this code was build to fit on a single sector, and you made extraodinary work in that field, but yet, i'm not that convince that "changing it abit will work" for any other purpose.Dex4u wrote: You can take a look at some code i wrote, call "CdPod", it for vesa 640x480 32bpp, but by changing it abit it will work for any graphic mode.
http://www.dex4u.com/images/cdpod.zip
For instance, a typical "drawtext" function will receive an array of ASCII char with e.g. "Hello World" and retrieve the appropriate font bits for 'H' and render the 'H', then for 'e', then for 'l', etc.
Your code instead, has "Play:" and "Stop:" directly encoded as a bitmap element (if i understand the code correctly), which means -- in some way -- that they are somehow like 32-pixels-wide single characters ...
Seeing something like
Code: Select all
;***********************************
; Draws the Pod.
;***********************************
mov edi,236*4+640*4*125
add edi,edx
Pod:
xor ecx,ecx
mov ebx,245
button2:
mov cl,14
mov al,0x2d
letsloop1:
stosd
add eax,15
loop letsloop1
mov cl,130
rep stosd
mov cl,14
letsloop2:
stosd
sub eax,15
loop letsloop2
add edi,640*4-158*4
dec ebx
jnz button2
I'm not sure the above code would even helped me to write a "fillrect (x1,y1,x2,y2, color) -- but it's certainly very compact and efficient, i won't deny it.
i was about to point you towards the FAQ but i realise we still have to write that part. If anyone is willing to take it, it's yours
Re:Graphics mode
Maybe your right Pype.Clicker, but i thought it may give a idea that you test for a bit, if its a 1 you put pixel, if a 0 you move pointer by one pixel (or put a differant colored pixel in), The other above code was not there when i put the link, on seeing it, i tryed to deleting the post, but it did not seem to work.
Re:Graphics mode
Well aside from "Graphics" mode being pretty vague, Dex4u gave me a pretty well explained here
It explains things like just plotting pixels on the screen but I don't think you should be thinking at fonts at this level yet. I think you should implement the lower level functions first and efficiently then try to port an existing solution like Freetype or just implement your own.
Hope I helped some.
It explains things like just plotting pixels on the screen but I don't think you should be thinking at fonts at this level yet. I think you should implement the lower level functions first and efficiently then try to port an existing solution like Freetype or just implement your own.
Hope I helped some.
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Graphics mode
updated the FAQ with basic informations about plotting pixels, drawing rectangles and characters ...Pype.Clicker wrote: i was about to point you towards the FAQ but i realise we still have to write that part. If anyone is willing to take it, it's yours
Re:Graphics mode
I've written a (self-contained) sample that illustrates some basic stuff (especially font writing):
http://www.mega-tokyo.com/forum/index.php?board=1;action=display;threadid=9169
At the moment my code has 64 conditional branches per character (to determine a new line). Which is actually not too smart. That can actually be done a lot smarter without any jumps (with or without lookup tables)
http://www.mega-tokyo.com/forum/index.php?board=1;action=display;threadid=9169
At the moment my code has 64 conditional branches per character (to determine a new line). Which is actually not too smart. That can actually be done a lot smarter without any jumps (with or without lookup tables)
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Graphics mode
i remember some project of mine where fonts were actually code, consisting of "stosb" bytes for pixels to be drawn, "inc di" for pixels to be skipped and "add di,dx" for end of lines. That made fonts sensibly larger than bitmaps, but faster to render (at least on that good old pentium). With today architectures, i think i would rather orient towards RLE encoding if i had to do a bitmap font renderer.
At least, i'd make sure it can take "antialiasing pixels" into account right from the start (which a bitmap may have more trouble to handle).
At least, i'd make sure it can take "antialiasing pixels" into account right from the start (which a bitmap may have more trouble to handle).
Re:Graphics mode
Agreed, I wouldn't use 1 bit fonts like my example does now. However, it is a nice "system" to use during boot and perhaps exception handling.
If you want to do serious graphics in your OS a proper font (probably scalable as well) will be important. And of coures in that case your characters will (should) have different widths.
If you want to do serious graphics in your OS a proper font (probably scalable as well) will be important. And of coures in that case your characters will (should) have different widths.
Re:Graphics mode
We all want great looking antialiasing and scalable fonts in our OS, but coding them so they look right and work is not easy.
I do not see many hobby OS with them implemented, even MenuetOS does not have them.
I do not see many hobby OS with them implemented, even MenuetOS does not have them.
Re:Graphics mode
If you are going to do graphics then it's weird people don't add at least proper bitmapped fonts (those are freely available). It should be easy to implement in C(++) [performance might be not so good though], especially if you've setup the basics as I've demonstrated with my code.
But it isn't as easy as plain old textmode, that's for sure.
But it isn't as easy as plain old textmode, that's for sure.
Re:Graphics mode
You miss understood what i was saying, "bitmapped" are easy to code and common.
But "scalable" are harder to code right and not so common in hobby OS:A bitmapped font (the simpler of the two) is like a BMP image. It's stored as a matrix (or grid) of pixel values, and is displayed exactly as it's written -- no interpretation is involved. It's a perfect copy, but as a result, it can't be resized without a significant loss of quality.
A scalable font, on the other hand, is stored in the same manner as a vectored graphic. Rather than being mapped pixel by pixel, a scalable font's "stylistic information" is saved in its data file. This information includes the angles of each character's curves, and how they're proportioned. Because no actual picture exists, it's up to the program that reads in the font to construct it for display. This adds some processing overhead, but the end result is well worth it. Scalable fonts can be resized without losing any quality, and often have smooth (or antialiased) edges.