1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
|
Program FontDemo;
{ FontDemo.pas, by Marco van de Voort (C) 2000-2001
Compiler: 1.0.5 or 1.1 after 20-01-2001
Target : FreeBSD 4.x+ with 16x8 font. 3.x untested (syscons driver)
Demonstrate font modification with the console driver "syscons".
This program doesn't work under X or over telnet.
The purpose of the program is to demonstrate the procedures that change the
font. The demonstration assume a 80x25 console. Framebuffer devices or 80x50
displays (80x50 use 8x8 fonts) require a trivial modification.
The example of mirroring is absurd, but is very visible, so good for
demonstration. The real use is to load the font, change a few characters
(linedrawing, (C) characters, force existance of umlaute or tremas for the
duration of the application.
Note that if you switch to a different vty while the font is mirrored, that
vty is also mirrored.
Root can restore the font via a network device with:
vidcontrol -f 8x16 "fontname in /usr/share/syscons/fonts" < /dev/ttyv1
The program saves the font, and will terminate and restore the font when
SIGUSR2 is received, unless -n is specified.
killall -USR2 fontdemo
}
Uses Console,{$ifdef ver1_0}Linux{$else}Baseunix{$endif},GetOpts;
{$ifdef ver1_0}
function fpnanosleep;
begin
nanosleep;
end;
{$endif}
procedure MirrorFont8(var Data;Count:longint); assembler;
{Mirrors on a bit level "Count" bytes in typeless variable "Data"}
asm
mov data,%esi
movl Count,%edx
.LLoop1: movb (%esi),%bl
movl $8,%ecx
.LLoop2: shr $1,%bl
rcl $1,%al
loop .LLoop2
movb %al,(%esi)
incl %esi
decl %edx
jne .LLoop1
end['EAX','EBX','ECX','EDX','ESI'];
procedure GoLeft(var Data;Count:longint;shcnt:longint); assembler;
{Mirrors on a bit level "Count" bytes in typeless variable "Data"}
asm
mov data,%esi
mov data,%edi
mov shcnt,%ecx
movl Count,%edx
xorl %eax,%eax
.LLoop1: lodsb
shl %cl,%eax
stosb
incl %esi
incl %edi
decl %edx
jne .LLoop1
end['EAX','EBX','ECX','EDX','ESI'];
procedure GoRight(var Data;Count:longint;shcnt:longint); assembler;
{Mirrors on a bit level "Count" bytes in typeless variable "Data"}
asm
mov data,%esi
mov data,%edi
mov shcnt,%ecx
movl Count,%edx
xor %eax,%eax
.LLoop1: lodsb
shr %cl,%eax
stosb
incl %esi
incl %edi
decl %edx
jne .LLoop1
end['EAX','EBX','ECX','EDX','ESI'];
procedure DoAlt(var Data;Count:longint;shcnt:longint;alt:integer); assembler;
{Mirrors on a bit level "Count" bytes in typeless variable "Data"}
asm
mov alt,%ecx
mov data,%esi
mov data,%edi
add %ecx,%esi
add %ecx,%edi
mov shcnt,%ecx
movl Count,%edx
xorl %eax,%eax
.LLoop1: lodsb
mov %edx,%ebx
and $1,%ebx
test %ebx,%ebx
je .Lgoleftalt1
shl %cl,%eax
jmp .Lgoleftalt2
.Lgoleftalt1:
shr %cl,%eax
.Lgoleftalt2:
stosb
incl %esi
incl %edi
decl %edx
jne .LLoop1
end['EAX','EBX','ECX','EDX','ESI'];
procedure stripbits (var Data;Count:longint); assembler;
{ "Compresses" a byte. 76543210 -> x764310x where x=0 (but 0 was already
used to indicate bit number :-)
Needed for a rotating effect. (Character rotating round vertical axis)
Does this for "Count" bytes in "Data".
}
asm
mov data,%esi
movl Count,%edx
.LLoop1: movb (%esi),%cl
and $219,%ecx
mov %ecx,%eax
mov %ecx,%ebx
and $24,%eax
and $3,%bl
shr $1,%al
or %bl,%al
shl $1,%al
mov %ecx,%ebx
and $192,%bl
shl $1,%al
or %bl,%al
shr $1,%al
movb %al,(%esi)
incl %esi
decl %edx
jne .LLoop1
end['EAX','EBX','ECX','EDX','ESI'];
procedure silloute (var Data;Count:longint); assembler;
{Iterates through "Count" bytes of "Data" and sets a byte to $48 if it is
not zero. If you would rotate a character round vertical axis through 90
degrees, this is about how it looks like}
asm
mov data,%esi
movl Count,%edx
.LLoop1: movb (%esi),%al
mov $48,%ecx
test %al,%al
je .Lfurther
mov %cl,%al
.Lfurther:
movb %al,(%esi)
incl %esi
decl %edx
jne .LLoop1
end['EAX','EBX','ECX','EDX','ESI'];
var Originalfont : Fnt16; {Font on startup, to be saved for restore}
StopIt : BOOLEAN; {Becomes TRUE when SIGUSR2 is received}
RestoreOnExit : Boolean; {Should font be restored on exit?}
procedure OkThatsEnough(sig:longint);cdecl;
begin
StopIt:=TRUE;
end;
procedure dorotate;
{ The animation order of the 5 distinctive states, -> 8 changes is one
rotation}
Type RotStatesType = array[0..7] of longint;
const RotStates : RotStatesType=(0,1,4,3,2,3,4,1);
{5 states:
- 0 is mirrored,
- 1 mirrored "compressed"
- 2 is normal,
- 3 normal "compressed",
- 4 "silloutte"}
var fnts : array[0..4] of fnt16;
I : Longint;
iin,oout: timespec;
begin
iin.tv_nsec:=250000000;
iin.tv_sec:=0;
fnts[2]:=OriginalFont;
fnts[0]:=fnts[2]; // Keep a copy.
MirrorFont8(fnts[0],sizeof(fnt16)); // Mirror every byte at bitlevel
fnts[1]:=fnts[0];
stripbits(fnts[1],sizeof(fnt16));
fnts[3]:=fnts[2];
stripbits(fnts[3],sizeof(fnt16));
fnts[4]:=fnts[2];
silloute(fnts[4],sizeof(fnt16));
i:=4;
Repeat
PIO_FONT8x16(0,fnts[RotStates[I and 7]]); // Activate the mirrored set
fpnanosleep(@iin,@oout);
inc(i);
until StopIt;
end;
procedure upanddown(Mini:BOOLEAN);
var
fnts : array[1..4] OF fnt16;
inn,outn : Timespec;
i : longint;
Mask : Longint;
begin
fnts[2]:=OriginalFont;
inn.tv_nsec:=50000000;
inn.tv_sec:=0;
fnts[4]:=fnts[2]; {Make three copies}
fnts[1]:=fnts[2];
fnts[3]:=fnts[2];
{Move one of them one byte up in memory. Font is one bit lower}
move (fnts[1],fnts[1].fnt8x16[1],SIZEOF(Fnt16)-1);
{Move another of them one byte down in memory. Font is one bit higher}
IF Mini THEN
Begin
Mask:=1;
move (fnts[2].fnt8x16[1],fnts[2],SIZEOF(Fnt16)-1);
end
else
begin
move (fnts[3].fnt8x16[1],fnts[3],SIZEOF(Fnt16)-1);
Mask:=3;
end;
Repeat
fpnanosleep(@inn,@outn);
pIO_FONT8x16(0,fnts[1 + (I and Mask)]);
inc(I);
until StopIt;
end;
procedure LeftAndRight;
var
fnts : array[1..4] OF fnt16;
inn,outn : Timespec;
i : longint;
Mask : Longint;
begin
fnts[2]:=OriginalFont;
inn.tv_nsec:=50000000;
inn.tv_sec:=0;
fnts[4]:=fnts[2]; {Make three copies}
fnts[1]:=fnts[2];
fnts[3]:=fnts[2];
{Move one of them one byte up in memory. Font is one bit lower}
Goright(Fnts[1],SIZEOF(FNT16),2);
GoLeft( Fnts[3],SIZEOF(FNT16),2);
Repeat
fpnanosleep(@inn,@outn);
pIO_FONT8x16(0,fnts[1 + (I and 3)]);
inc(I);
until StopIt;
end;
procedure doalternate;
var
fnts : array[0..5] OF fnt16;
inn,outn : Timespec;
i : longint;
Mask : Longint;
begin
fnts[2]:=OriginalFont;
inn.tv_nsec:=500000000;
inn.tv_sec:=0;
fnts[4]:=fnts[2]; {Make three copies}
fnts[1]:=fnts[2];
fnts[3]:=fnts[2];
{Move one of them one byte up in memory. Font is one bit lower}
doalt(fnts[1],SIZEOF(FNT16) div 2,2,1);
doalt(fnts[3],SIZEOF(FNT16) div 2,2,0);
Repeat
fpnanosleep(@inn,@outn);
writeln(1 + (I and 3));
pIO_FONT8x16(0,fnts[1 + (I and 3)]);
inc(I);
until StopIt;
end;
procedure JustMirror;
var fnt : Fnt16;
begin
fnt:=OriginalFont;
MirrorFont8(fnt,sizeof(fnt16));
pIO_FONT8x16(0,fnt);
IF RestoreOnExit THEN
Repeat
until StopIt;
end;
var DoThis : Longint;
c : Char;
begin
DoThis:=0;
RestoreOnExit := TRUE;
if PhysicalConsole(0) then // a vty?
begin
REPEAT
c:=GetOpt('n012345'); // Commandline processing
IF c IN ['0'..'5'] Then
DoThis:= ORD(c)-48;
IF c='n' THEN
RestoreOnExit:=FALSE;
UNTIL C=EndOfOptions;
StopIt:=false; // Turns true on signal USR2
GIO_FONT8x16(0,OriginalFont); // Get font from videocard.
fpSignal(SIGUSR2,@OkThatsEnough); // Install handler for sigusr2.
CASE DoThis OF // Call the font routines
0 : DoRotate;
1 : UpAndDown(TRUE);
2 : JustMirror;
3 : UpAndDown(FALSE);
4 : LeftAndRight;
5 : doAlternate;
END;
IF RestoreOnExit THEN // clean up if required.
PIO_FONT8x16(0,OriginalFont);
end;
end.
|