Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Where are the fonts stored ?
#1
I developed a very awkward text module for the TC-Lib. It works fine, but I'm sure the definition of the letters (i.e. their bitmaps) must be stored somewhere in the RAM.

Remember the TC-Lib works in true-colour modes, so that a lot of standard features do not work : it seems impossible to just poke an Ascii code, each pixel must be plotted. Moreover, I need a pixel text position on the screen : the row and column stuff do not work...

Can anybody tell me where and how the font is stored in the machine?

Here's the prog (adapted for the SCREEN 12 mode):

=============================================
DECLARE SUB PrintStd (x%, y%, Text$)

DIM SHARED Font%(91, 16)

Data.Font:
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,24,60,60,60,24,24,24,0,24,24,0,0,0,0
DATA 0,102,102,102,36,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,54,54,127,54,54,54,127,54,54,0,0,0,0
DATA 24,24,62,99,67,3,62,96,96,97,99,62,24,24,0,0
DATA 0,0,0,0,67,99,48,24,12,6,99,97,0,0,0,0
DATA 0,0,28,54,54,28,110,59,51,51,51,110,0,0,0,0
DATA 0,12,12,12,6,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,48,24,12,12,12,12,12,12,24,48,0,0,0,0
DATA 0,0,12,24,48,48,48,48,48,48,24,12,0,0,0,0
DATA 0,0,0,0,0,102,60,255,60,102,0,0,0,0,0,0
DATA 0,0,0,0,0,24,24,126,24,24,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,24,24,24,12,0,0,0
DATA 0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,24,24,0,0,0,0
DATA 0,0,0,0,64,96,48,24,12,6,3,1,0,0,0,0
DATA 0,0,28,54,99,99,107,107,99,99,54,28,0,0,0,0
DATA 0,0,24,28,30,24,24,24,24,24,24,126,0,0,0,0
DATA 0,0,62,99,96,48,24,12,6,3,99,127,0,0,0,0
DATA 0,0,62,99,96,96,60,96,96,96,99,62,0,0,0,0
DATA 0,0,48,56,60,54,51,127,48,48,48,120,0,0,0,0
DATA 0,0,127,3,3,3,63,96,96,96,99,62,0,0,0,0
DATA 0,0,28,6,3,3,63,99,99,99,99,62,0,0,0,0
DATA 0,0,127,99,96,96,48,24,12,12,12,12,0,0,0,0
DATA 0,0,62,99,99,99,62,99,99,99,99,62,0,0,0,0
DATA 0,0,62,99,99,99,126,96,96,96,48,30,0,0,0,0
DATA 0,0,0,0,24,24,0,0,0,24,24,0,0,0,0,0
DATA 0,0,0,0,24,24,0,0,0,24,24,12,0,0,0,0
DATA 0,0,0,96,48,24,12,6,12,24,48,96,0,0,0,0
DATA 0,0,0,0,0,126,0,0,126,0,0,0,0,0,0,0
DATA 0,0,0,6,12,24,48,96,48,24,12,6,0,0,0,0
DATA 0,0,62,99,99,48,24,24,24,0,24,24,0,0,0,0
DATA 0,0,0,62,99,99,123,123,123,59,3,62,0,0,0,0
DATA 0,0,8,28,54,99,99,127,99,99,99,99,0,0,0,0
DATA 0,0,63,102,102,102,62,102,102,102,102,63,0,0,0,0
DATA 0,0,60,102,67,3,3,3,3,67,102,60,0,0,0,0
DATA 0,0,31,54,102,102,102,102,102,102,54,31,0,0,0,0
DATA 0,0,127,102,70,22,30,22,6,70,102,127,0,0,0,0
DATA 0,0,127,102,70,22,30,22,6,6,6,15,0,0,0,0
DATA 0,0,60,102,67,3,3,123,99,99,102,92,0,0,0,0
DATA 0,0,99,99,99,99,127,99,99,99,99,99,0,0,0,0
DATA 0,0,60,24,24,24,24,24,24,24,24,60,0,0,0,0
DATA 0,0,120,48,48,48,48,48,51,51,51,30,0,0,0,0
DATA 0,0,103,102,102,54,30,30,54,102,102,103,0,0,0,0
DATA 0,0,15,6,6,6,6,6,6,70,102,127,0,0,0,0
DATA 0,0,99,119,127,127,107,99,99,99,99,99,0,0,0,0
DATA 0,0,99,103,111,127,123,115,99,99,99,99,0,0,0,0
DATA 0,0,62,99,99,99,99,99,99,99,99,62,0,0,0,0
DATA 0,0,63,102,102,102,62,6,6,6,6,15,0,0,0,0
DATA 0,0,62,99,99,99,99,99,99,107,123,62,48,112,0,0
DATA 0,0,63,102,102,102,62,54,102,102,102,103,0,0,0,0
DATA 0,0,62,99,99,6,28,48,96,99,99,62,0,0,0,0
DATA 0,0,126,126,90,24,24,24,24,24,24,60,0,0,0,0
DATA 0,0,99,99,99,99,99,99,99,99,99,62,0,0,0,0
DATA 0,0,99,99,99,99,99,99,99,54,28,8,0,0,0,0
DATA 0,0,99,99,99,99,107,107,107,127,119,54,0,0,0,0
DATA 0,0,99,99,54,62,28,28,62,54,99,99,0,0,0,0
DATA 0,0,102,102,102,102,60,24,24,24,24,60,0,0,0,0
DATA 0,0,127,99,97,48,24,12,6,67,99,127,0,0,0,0
DATA 0,0,60,12,12,12,12,12,12,12,12,60,0,0,0,0
DATA 0,0,0,1,3,7,14,28,56,112,96,64,0,0,0,0
DATA 0,0,60,48,48,48,48,48,48,48,48,60,0,0,0,0
DATA 8,28,54,99,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0
DATA 0,12,24,48,0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,30,48,62,51,51,51,110,0,0,0,0
DATA 0,0,7,6,6,30,54,102,102,102,102,62,0,0,0,0
DATA 0,0,0,0,0,62,99,3,3,3,99,62,0,0,0,0
DATA 0,0,56,48,48,60,54,51,51,51,51,110,0,0,0,0
DATA 0,0,0,0,0,62,99,127,3,3,99,62,0,0,0,0
DATA 0,0,56,108,76,12,30,12,12,12,12,30,0,0,0,0
DATA 0,0,0,0,0,110,51,51,51,51,51,62,48,51,30,0
DATA 0,0,7,6,6,54,110,102,102,102,102,103,0,0,0,0
DATA 0,0,24,24,0,28,24,24,24,24,24,60,0,0,0,0
DATA 0,0,96,96,0,112,96,96,96,96,96,96,102,102,60,0
DATA 0,0,7,6,6,102,54,30,30,54,102,103,0,0,0,0
DATA 0,0,28,24,24,24,24,24,24,24,24,60,0,0,0,0
DATA 0,0,0,0,0,55,127,107,107,107,107,99,0,0,0,0
DATA 0,0,0,0,0,59,102,102,102,102,102,102,0,0,0,0
DATA 0,0,0,0,0,62,99,99,99,99,99,62,0,0,0,0
DATA 0,0,0,0,0,59,102,102,102,102,102,62,6,6,15,0
DATA 0,0,0,0,0,110,51,51,51,51,51,62,48,48,120,0
DATA 0,0,0,0,0,59,110,102,6,6,6,15,0,0,0,0
DATA 0,0,0,0,0,62,99,6,28,48,99,62,0,0,0,0
DATA 0,0,8,12,12,63,12,12,12,12,108,56,0,0,0,0
DATA 0,0,0,0,0,51,51,51,51,51,51,110,0,0,0,0
DATA 0,0,0,0,0,99,99,99,99,99,54,28,0,0,0,0
DATA 0,0,0,0,0,99,99,107,107,107,127,54,0,0,0,0
DATA 0,0,0,0,0,99,54,28,28,28,54,99,0,0,0,0
DATA 0,0,0,0,0,99,99,99,99,99,99,126,96,48,31,0
DATA 0,0,0,0,0,127,51,24,12,6,99,127,0,0,0,0

RESTORE Data.Font
FOR k% = 0 TO 90
FOR p% = 0 TO 15
READ Font%(k%, p%)
NEXT p%
NEXT k%


SCREEN 12

PrintStd 53, 72, "Standard QB font", 2

' Attente d'une touche
DO WHILE INKEY$ = ""
LOOP

' Retour au mode texte et fin du programme
SCREEN 0
WIDTH 80, 25
CLS
SYSTEM

SUB PrintStd (x%, y%, Text$)
Red%=255 : Green%=255 : Blue%=255
FOR i% = 1 TO LEN(Text$)
Letter% = ASC(MID$(Text$, i%, 1)) - 32
IF Letter% < 0 OR Letter% > 91 THEN Letter% = 0
FOR j% = 0 TO 15
p% = Font%(Letter%, j%)
FOR k% = 0 TO 7
IF p% AND &H1 THEN Pset24 x% + 8 * (i% - 1) + k%, y% + j%)
p% = p% \ 2
NEXT k%
NEXT j%
NEXT i%
END SUB
hink Global, Make Symp' All ! ®
[Image: Banner.gif]
Reply
#2
Here's the regular 8*8 font used in DOS:
Code:
DECLARE SUB nPrint (Xpos%, Ypos%, Text$, col%)
SCREEN 13

SUB nPrint (Xpos%, Ypos%, Text$, col%)
X% = Xpos%
Y% = Ypos%
  FOR I% = 0 TO LEN(Text$) - 1
    X% = X% + 8
    Offset% = 8 * ASC(MID$(Text$, I% + 1, 1)) + 14
    FOR J% = 0 TO 7
      DEF SEG = &HFFA6
      Bit% = PEEK(Offset% + J%)
      IF Bit% AND 1 THEN PSET (X%, Y% + J%), col% + J%
      IF Bit% AND 2 THEN PSET (X% - 1, Y% + J%), col% + J%
      IF Bit% AND 4 THEN PSET (X% - 2, Y% + J%), col% + J%
      IF Bit% AND 8 THEN PSET (X% - 3, Y% + J%), col% + J%
      IF Bit% AND 16 THEN PSET (X% - 4, Y% + J%), col% + J%
      IF Bit% AND 32 THEN PSET (X% - 5, Y% + J%), col% + J%
      IF Bit% AND 64 THEN PSET (X% - 6, Y% + J%), col% + J%
      IF Bit% AND 128 THEN PSET (X% - 7, Y% + J%), col% + J%
    NEXT J%
  NEXT I%

END SUB
am an asshole. Get used to it.
Reply
#3
I think that's what I was looking for...

Still, my prog was fun to build, and I think I will keep it in order to have different fonts : for example, it can be used to "digitalize" fonts from an MS-Word screenshot.
hink Global, Make Symp' All ! ®
[Image: Banner.gif]
Reply
#4
Your prog works fine, Ninkazu ! What I need now is the same logics but with the default QB font, which is 8x16.

8x8 is at address HFFA6, do you know where the 8x16 is ?
hink Global, Make Symp' All ! ®
[Image: Banner.gif]
Reply
#5
the location given by the interrupt vector for "interrupt" 43. That interrupt really isn't an interrupt at all. It's just a table. You can get the address of the font table by (after changing to the video mode you want to use) using interrupt 21h / function 35h, with 43h in AL. After calling int 21, the memory segment of the font table is in ES and the offset is in BX. Here's a program I wrote a while back, if that helps.

'
' This program demonstrates how to change the font in a QB graphics
' video mode. (It changes a character of your choosing to a box.)
'
'$INCLUDE: 'QB.BI'
DIM CHAR(1 TO 1024) AS LONG, SM AS INTEGER, OS AS INTEGER, I AS INTEGER
DIM BYTE AS INTEGER, VS AS INTEGER, INREGS AS REGTYPEX, OUTREGS AS REGTYPEX
DIM MODE AS INTEGER, NBYTES AS INTEGER, SMORG AS INTEGER, OSORG AS INTEGER
DIM SMORG1 AS INTEGER, OSORG1 AS INTEGER
'
' Get location in memory of where font data is to go.
'
SM = VARSEG(CHAR(1)): OS = VARPTR(CHAR(1))
'
' Get video mode to use.
'
MODE = 0
WHILE MODE < 1 OR (MODE > 2 AND MODE < 7) OR MODE > 13
INPUT "WHAT QB GRAPHICS MODE DO YOU WANT"; MODE
WEND
SCREEN MODE
'
' Get character size.
'
DEF SEG = 0
VS = PEEK(&H485)
'
' If this routine doesn't work for you, print out the value of VS just
' obtained. If it's 14, uncomment the following line of code and see if
' that helps. (Some video boards require it.)
'
'IF VS = 14 THEN VS = 16
'
' Find out where font data is.
'
INREGS.AX = &H3543
CALL INTERRUPTX(&H21, INREGS, OUTREGS)
'
' Save IVT data.
'
SMORG = OUTREGS.ES: OSORG = OUTREGS.BX
'
' Read font data from video area and write it to array.
'
NBYTES = VS * 256
IF MODE < 7 THEN NBYTES = NBYTES / 2
FOR I = 0 TO NBYTES - 1
DEF SEG = OUTREGS.ES
BYTE = PEEK(I + OUTREGS.BX)
DEF SEG = SM
POKE I + OS, BYTE
NEXT I
'
' If MODE < 7, font data for ascii values > 127 are located elsewhere.
'
IF MODE < 7 THEN
INREGS.AX = &H351F
CALL INTERRUPTX(&H21, INREGS, OUTREGS)
SMORG1 = OUTREGS.ES: OSORG1 = OUTREGS.BX
FOR I = NBYTES TO 2 * NBYTES - 1
DEF SEG = OUTREGS.ES
BYTE = PEEK(I - NBYTES + OUTREGS.BX)
DEF SEG = SM
POKE I + OS, BYTE
NEXT I
END IF
'
' Ask for what character is to be changed to box and get its ascii
' value.
'
LINE INPUT "WHAT CHARACTER DO YOU WANT TO CHANGE TO BOX?"; UCHAR$
ASCII = ASC(UCHAR$)
'
' Change UCHAR$ font to box. Note that (255 decimal = 11111111 binary
' and 129 decimal = 10000001 binary.)
'
OS = ASCII * VS + OS
'
' Write top byte.
'
POKE OS, 255
OS = OS + 1
'
' Write side bytes.
'
FOR I = 1 TO VS - 2
POKE OS, 129
OS = OS + 1
NEXT I
'
' Write bottom byte.
'
POKE OS, 255
DEF SEG
'
' Clear screen and write original character.
'
CLS
PRINT UCHAR$
'
' Change interrupt vector to memory location of array.
'
INREGS.DX = VARPTR(CHAR(1))
IF MODE > 6 THEN
INREGS.AX = &H2543
ELSE
INREGS.AX = &H251F
INREGS.DX = INREGS.DX + NBYTES
END IF
INREGS.DS = SM
CALL INTERRUPTX(&H21, INREGS, OUTREGS)
'
' Display UCHAR$ again and see how it's changed.
'
PRINT UCHAR$
'
' Pause program.
'
WHILE INKEY$ = "": WEND
'
' Restore original interrupt vectors.
'
INREGS.AX = &H2543
INREGS.DS = SMORG
INREGS.DX = OSORG
CALL INTERRUPTX(&H21, INREGS, OUTREGS)
IF MODE < 7 THEN
INREGS.AX = &H251F
INREGS.DS = SMORG1
INREGS.DX = OSORG1
CALL INTERRUPTX(&H21, INREGS, OUTREGS)
END IF
END
ravelling Curmudgeon
(geocities sites require copying and pasting URLs.)
I liked spam better when it was something that came in a can.
Windows should be defenestrated.
Reply
#6
Ninkazu's method of setting the segment to a constant does not work in every computer. At least it does'nt work in mine under W2000.
It's safer to use int 10h to ask DOS for the address of fonts.

Code:
'$include:'qb.bi'
regs.ax = &H1130
regs.bx = font * 256  '3 for 8X8 font and 6 for 8X16 font
                                  '2 for 14x8 font (this one may not exist)
CALL INTERRUPTX(&H10, regs, regs)
Fontseg = regs.es
fontoffset& = regs.bp

then
DEFSEG= fontseg
and add fontoffset& to Ninkazu's Offset% expression
the rest of the code should work the same...
Antoni
Reply
#7
Now I understand why it's at the same time easy and difficult... Easy when you've done it, and tough when you need to work on the details of a subject...

Thanks folks !

PS : Antoni, hearing about your trouble with W2000, I hope my progs will work on the new machine I will get Friday ! It will use XP...

And I will also load a Mandrake 9.1, just for the fun...

BTW, does anybody have a genuine DOS 5.0 ? I would really appreciate getting back to my favorite OS, but DOS is almost impossible to download from the web
hink Global, Make Symp' All ! ®
[Image: Banner.gif]
Reply
#8
I have 6.22

Want it? :*)
y smiley is 24 bit.
[Image: anya2.jpg]

Genso's Junkyard:
http://rel.betterwebber.com/
Reply
#9
If you can make a zip and mail it to me... I know there is something called Freedos, but my point is to test progs with a plain MS-Dos config.

Thanks by advance!
hink Global, Make Symp' All ! ®
[Image: Banner.gif]
Reply
#10
Jark:

The common gossip is XP is even worse for DOS programs than W2000, so be prepared
Antoni
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)