[Back to SCREEN SWAG index] [Back to Main SWAG index] [Original]
{
> I just let dos write something on the screen, I'm in the normal
> videomode, say that writes 100 lines to the screen. How can I read
> whatever that program wrote if the lines have scrolled of the screen ???
> I need to have the output in an array ... with the colors ... there might
> even be an animation in the output (ansi) ... I know how to put a normal
> 25x80 in an array or a 50x80 ... but how do you work with something
> that's 100 lines long ... I want to be able to scroll back after the
> display ...
You can use an Array to do it - or, you can program your graphic-card. :-)
Perhaps this little prog will give you a clue:
}
program BreakOut;
uses CRT, DOS;
const
UP = 0; { Verschieberichtung fuer Bildschirm. }
DOWN = 1;
ST_X = 10; { Steine nebeneinander. }
ST_Y = 5; { Steine uebereinander. }
type
screen_params = record
zeichen : char;
attribut : byte;
end;
Video_params = record
mode, page : byte;
start_scanline : byte;
end_scanline : byte;
row, column : byte;
end;
stone_params = record
spalte : byte;
zeile : byte;
end;
bouncer_params = record { bouncer == schlaeger }
spalte : shortint;
zeile : shortint;
dir : shortint;
speed : longint;
count : longint;
end;
ball_params = record
spalte : real;
zeile : real;
speed : longint;
count : longint;
dir_x : real;
dir_y : real;
next_x : real;
next_y : real;
last_x : real;
last_y : real;
flag : byte;
end;
screen_type = array [1..2000] of screen_params;
var
regs : Registers;
Video : Video_params;
bouncer : bouncer_params;
ball : ball_params;
stone : array [1..ST_X,1..ST_Y] of stone_params;
screen : ^screen_type; { Zeiger auf aktuelle Seite. }
screen0 : pointer; { Zeiger auf Seite 0. }
screen1 : pointer; { Zeiger auf Seite 1. }
screen2 : pointer; { Zeiger auf Seite 2. }
procedure GetCurrentVideoMode;
{
Procedure to get and store the current video mode settings.
}
begin
regs.ah := $0F;
intr($10, regs);
Video.mode := regs.al;
Video.page := regs.bh;
end;
procedure GetCurrentCursorSettings;
{
Procedure to get and store the current cursor settings.
}
begin
regs.ah := 3;
regs.bh := Video.page;
intr($10, regs);
Video.start_scanline := regs.ch;
Video.end_scanline := regs.cl;
Video.row := regs.dh;
Video.column := regs.dl;
end;
procedure SetVideoMode(mode : byte);
{
Procedure to set a specific video mode.
mode = new video mode.
}
begin
regs.ah := 0;
regs.al := mode;
intr($10, regs);
end;
procedure HideCursor;
{
Procedure to make the cursor invisible on the screen.
}
begin
regs.ah := 1;
regs.al := Video.mode;
regs.cx := $FFFF;
intr($10, regs);
end;
procedure RestoreCursor;
{
Procedure to restore the old cursor.
}
begin
regs.ah := 1;
regs.al := Video.mode;
regs.ch := Video.start_scanline;
regs.cl := Video.end_scanline;
intr($10, regs);
end;
procedure ClearScreen;
var
i : integer;
begin
for i := 1 to 2000 do
begin
screen^[i].zeichen := #32;
screen^[i].attribut := 7;
end;
end;
procedure DrawBorder;
var
i : integer;
begin
for i := 1 to 80 do
screen^[i].attribut := $30;
for i := 81 to 1920 do { 1920 = 2000 - 80 }
begin
screen^[i].attribut := $30;
i := i + 79;
screen^[i].attribut := $30;
end;
end;
procedure InitializeStones;
var
i, j : byte;
x, y : byte; { x = Spalte; y = Zeile }
begin
y := 4;
for i := 1 to ST_Y do { Zeilen }
begin
x := 7;
for j := 1 to ST_X do { Spalten }
begin
stone[j, i].spalte := x;
stone[j, i].zeile := y;
x := x + 7;
end;
y := y + 2;
end;
end;
procedure DrawStones;
var
pos : integer;
i, j, k : byte;
begin
for i := 1 to ST_Y do { Zeilen }
begin
for j := 1 to ST_X do { Spalten }
begin
pos := stone[j, i].zeile * 80 + stone[j, i].spalte;
for k := 0 to 4 do
screen^[(pos + k)].attribut := $60;
end;
end;
end;
procedure DrawBouncer;
var
i : integer;
pos : integer;
begin
pos := bouncer.zeile * 80 + bouncer.spalte - 1;
screen^[pos].attribut := 7;
for i := 1 to 8 do
screen^[(pos + i)].attribut := $70;
screen^[(pos + 9)].attribut := 7;
end;
procedure DrawBall;
var
pos : integer;
begin
pos := integer(trunc(ball.last_y) * 80 + trunc(ball.last_x));
screen^[pos].zeichen := #32;
screen^[pos].attribut := 7;
pos := integer(trunc(ball.zeile) * 80 + trunc(ball.spalte));
screen^[pos].zeichen := 'o';
screen^[pos].attribut := 5;
ball.last_x := ball.spalte;
ball.last_y := ball.zeile;
ball.next_x := ball.spalte + ball.dir_x;
ball.next_y := ball.zeile + ball.dir_y;
end;
procedure MovePicture(scr : pointer; direction : byte);
var
dir : integer;
count : word;
zaehler : word;
begin
zaehler := ofs(screen^) shr 1;
port[$03D4] := $0C;
port[$03D5] := hi(zaehler);
port[$03D4] := $0D;
port[$03D5] := lo(zaehler);
if (direction = UP) then
dir := 80
else
dir := (-80);
count := 0;
repeat
inc(count);
zaehler := zaehler + dir;
port[$03D4] := $0C;
port[$03D5] := hi(zaehler);
port[$03D4] := $0D;
port[$03D5] := lo(zaehler);
delay(20);
until (count = 25);
screen := scr;
end;
function MoveBouncer : byte;
var
c : char;
begin
bouncer.count := bouncer.count - 1;
if (bouncer.count = 0) then
begin
bouncer.count := bouncer.speed;
if (keypressed) then
begin
c := readkey;
case c of
#0 : begin
c := readkey;
case c of
#75 : bouncer.dir := (-1);
#77 : bouncer.dir := 1;
end;
end;
#27 : begin
MoveBouncer := 1;
exit;
end;
#32 : bouncer.dir := 0;
end;
end;
bouncer.spalte := bouncer.spalte + bouncer.dir;
if (bouncer.spalte < 2) then
begin
bouncer.spalte := 2;
bouncer.dir := 0;
end;
if (bouncer.spalte = 73) then
begin
bouncer.spalte := 72;
bouncer.dir := 0;
end;
if (bouncer.dir <> 0) then
DrawBouncer;
end;
MoveBouncer := 0;
end;
procedure MoveBall;
var
pos : integer;
begin
ball.count := ball.count - 1;
if (ball.count = 0) then
begin
ball.count := ball.speed;
{ Linken und rechten Rand abfragen. }
if ((trunc(ball.next_x) < 2) or (trunc(ball.next_x) > 79)) then
begin
ball.dir_x := ball.dir_x * (-1.0);
ball.next_x := ball.spalte + ball.dir_x;
end;
{ Oberen Rand abfragen. }
if (trunc(ball.next_y) < 1) then
begin
ball.dir_y := ball.dir_y * (-1.0);
ball.next_y := ball.zeile + ball.dir_y;
end;
{ Unteren Rand abfragen. }
if (trunc(ball.next_y) > 23) then
begin
pos := integer((trunc(ball.zeile) + 1) * 80 + trunc(ball.spalte));
if (screen^[pos].attribut = $70) then
begin
ball.dir_y := ball.dir_y * (-1.0);
ball.next_y := ball.zeile + ball.dir_y;
end
else
begin
ball.flag := 2;
exit;
end;
end;
ball.spalte := ball.next_x;
ball.zeile := ball.next_y;
DrawBall;
end;
end;
procedure Play;
var
erg : byte;
begin
while (TRUE) do
begin
erg := MoveBouncer;
if (erg = 1) then
exit;
MoveBall;
if (ball.flag = 2) then
exit;
end;
end;
begin
GetCurrentVideoMode;
GetCurrentCursorSettings;
if (Video.mode <> 3) then
SetVideoMode(3);
HideCursor;
screen0 := ptr($B800, 0000); { Bildschirmseite 0. }
screen1 := ptr($B800, 4000); { Bildschirmseite 1. }
screen2 := ptr($B800, 8000); { Bildschirmseite 2. }
screen := screen0;
ClearScreen;
screen := screen2;
ClearScreen;
screen := screen1;
ClearScreen;
DrawBorder;
InitializeStones;
DrawStones;
bouncer.spalte := 35;
bouncer.zeile := 24;
bouncer.dir := 0;
bouncer.speed := 3000;
bouncer.count := bouncer.speed;
DrawBouncer;
ball.spalte := 40.0;
ball.zeile := 20.0;
ball.speed := 8000;
ball.count := ball.speed;
ball.dir_x := 1.0;
ball.dir_y := (-1.0);
ball.last_x := 39.0;
ball.last_y := 21.0;
ball.flag := 0;
DrawBall;
screen := screen0;
repeat
MovePicture(screen1, UP);
MovePicture(screen2, UP);
MovePicture(screen1, DOWN);
MovePicture(screen0, DOWN);
until (keypressed);
MovePicture(screen1, UP);
Play;
RestoreCursor;
port[$03D4] := $0C;
port[$03D5] := 0;
port[$03D4] := $0D;
port[$03D5] := 0;
if (Video.mode <> 3) then
SetVideoMode(Video.mode)
else
clrscr;
textattr := LIGHTGRAY;
writeln;
writeln('Thank you for playing BreakOut!');
writeln;
writeln('Do have a nice day...');
writeln; writeln;
end.
[Back to SCREEN SWAG index] [Back to Main SWAG index] [Original]