[fpc-pascal] Segmentation Error using VideoBuf
mokashe.ram
mokashe.ram at gmail.com
Wed Jul 2 14:32:28 CEST 2014
Hi Tomas,
I have done all my work with Free pascal but only one error
which still i am not able to fix is MEM as i tried all the options which you
suggest me (heartly thanks for that) but still i am not Getting exect
solution for it.....Please see below fully compilable source in free pascal
2.6.4 using 'Video' unit on windows 7 and help me please...
UNIT TestMem;
{$O+,F+}
INTERFACE
TYPE
location_pointer = ^location;
location = RECORD
next : location_pointer;
code : WORD;
END;
window_pointer = ^window_object;
window_object = OBJECT
x, y,
x_offset,
y_offset : BYTE;
first_location : location_pointer;
window_has_been_saved : BOOLEAN;
CONSTRUCTOR initialise(top_left_x,
top_left_y,
width,
height : BYTE);
PROCEDURE save;
PROCEDURE appear; VIRTUAL;
DESTRUCTOR destroy_window;
END;
screen_window_pointer = ^screen_window;
screen_window = OBJECT(window_object)
replacement_window : window_pointer;
border_fore_colour,
border_back_colour,
window_fore_colour,
window_back_colour,
window_style : BYTE;
CONSTRUCTOR initialise(top_left_x,
top_left_y,
width,
height,
style,
border_foreground,
border_background,
window_foreground,
window_background : BYTE);
PROCEDURE appear; VIRTUAL;
PROCEDURE appear_at(top_left_x,
top_left_y : BYTE); VIRTUAL;
PROCEDURE disappear; VIRTUAL;
DESTRUCTOR destroy_window;
END;
PROCEDURE draw_window_outline(top_left_x,
top_left_y,
width,
height,
style,
fore,
back : BYTE);
PROCEDURE blank_window(top_left_x,
top_left_y,
width,
height,
colour : BYTE);
PROCEDURE draw_window(top_left_x,
top_left_y,
width,
height,
style,
border_fore,
border_back,
window_fore,
window_back : BYTE);
PROCEDURE clear_last_boxed_message;
PROCEDURE halt_with_message(line_1,
line_2,
line_3,
line_4 : STRING);
PROCEDURE siren(sound_length : BYTE;
delay_length : BYTE);
PROCEDURE write_box_message (str1, str2, str3 : string; exit_required :
BOOLEAN);
PROCEDURE write_boxed_message(line_1,
line_2,
line_3,
line_4,
line_5 : STRING);
FUNCTION upcase_string(st : STRING): STRING;
VAR
write_message_to_screen : BOOLEAN;
halt_with_message_string : STRING;
IMPLEMENTATION
USES
CRT,
video,
mouse;
TYPE
border_code = ARRAY [0..4] OF BYTE;
CONST
top_left_corner : border_code = (32, 218, 201, 214, 213);
top_right_corner : border_code = (32, 191, 187, 183, 184);
bottom_left_corner : border_code = (32, 192, 200, 211, 212);
bottom_right_corner : border_code = (32, 217, 188, 189, 190);
horizontal : border_code = (32, 196, 205, 196, 205);
vertical : border_code = (32, 179, 186, 186, 179);
VAR
error_message : screen_window;
PROCEDURE set_range_of( VAR input : BYTE;
most,
least : BYTE);
BEGIN
IF input>most THEN
input:=most
ELSE IF input<least THEN
input:=least;
END;
CONSTRUCTOR window_object.initialise(top_left_x,
top_left_y,
width,
height : BYTE);
BEGIN
x:=top_left_x;
y:=top_left_y;
x_offset:=width;
y_offset:=height;
set_range_of( x, 80, 1);
set_range_of( y, 25, 1);
set_range_of( x_offset, 81-top_left_x, 1);
set_range_of( y_offset, 26-top_left_y, 1);
first_location:=NIL;
window_has_been_saved:=FALSE;
END;
PROCEDURE window_object.save;
VAR
width_offset,
height_offset : BYTE;
current_location : location_pointer;
P:Integer;
BEGIN
IF NOT window_has_been_saved THEN
BEGIN
NEW(first_location);
first_location^.next:=NIL;
END;
current_location:=first_location;
FOR height_offset:=y TO (y+y_offset-1) DO
BEGIN
FOR width_offset:=x TO (x+x_offset-1) DO
BEGIN
// current_location^.code:=MEMW[$B800:(width_offset-1)*2
// +(height_offset-1)*160];
P:= ((width_offset-1)+(height_offset-1)* ScreenWidth);
current_location^.code:=word(@VideoBuf^[P]);
IF (current_location^.next=NIL) THEN
BEGIN
NEW(current_location^.next);
current_location^.next^.next:=NIL;
END;
current_location:=current_location^.next;
END;
UpdateScreen(false);
END;
window_has_been_saved:=TRUE;
END;
PROCEDURE window_object.appear;
VAR
width_offset,
height_offset : BYTE;
current_location : location_pointer;
BEGIN
current_location:=first_location;
FOR height_offset:=y TO (y+y_offset-1) DO
BEGIN
FOR width_offset:=x TO (x+x_offset-1) DO
BEGIN
// MEMW[$B800:(width_offset-1)*2
// +(height_offset-1)*160]:=current_location^.code;
VideoBuf^[(width_offset-1)
+(height_offset-1)*
ScreenWidth]:=Ord(current_location^.code);
current_location:=current_location^.next;
END;
END;
current_location^.next:=NIL;
UpdateScreen(false);
END;
DESTRUCTOR window_object.destroy_window;
VAR
current_location : location_pointer;
BEGIN
IF window_has_been_saved AND (first_location<> NIL) THEN
BEGIN
current_location:=first_location^.next;
WHILE current_location<>NIL DO
BEGIN
DISPOSE(first_location);
first_location:=current_location;
current_location:=first_location^.next;
END;
DISPOSE(first_location);
END;
window_has_been_saved:= FALSE;
END;
CONSTRUCTOR screen_window.initialise(top_left_x,
top_left_y,
width,
height,
style,
border_foreground,
border_background,
window_foreground,
window_background : BYTE);
BEGIN
window_object.initialise(top_left_x,
top_left_y,
width,
height);
NEW(replacement_window,initialise(top_left_x,
top_left_y,
width,
height));
window_style:=style;
border_fore_colour:=border_foreground;
border_back_colour:=border_background;
window_fore_colour:=window_foreground;
window_back_colour:=window_background;
set_range_of( window_style, 4, 0);
set_range_of( border_fore_colour, 15, 0);
set_range_of( border_back_colour, 7, 0);
set_range_of( window_fore_colour, 15, 0);
set_range_of( window_back_colour, 7, 0);
END;
PROCEDURE screen_window.appear;
BEGIN
replacement_window^.save;
IF NOT window_has_been_saved THEN
draw_window(x,
y,
x_offset,
y_offset,
window_style,
border_fore_colour,
border_back_colour,
window_fore_colour,
window_back_colour)
ELSE window_object.appear;
END;
PROCEDURE screen_window.disappear;
BEGIN
save;
replacement_window^.appear;
END;
PROCEDURE screen_window.appear_at(top_left_x,
top_left_y : BYTE);
BEGIN
x:=top_left_x;
y:=top_left_y;
set_range_of( x, 79, 1);
set_range_of( y, 24, 1);
replacement_window^.x:=x;
replacement_window^.y:=y;
appear;
END;
DESTRUCTOR screen_window.destroy_window;
BEGIN
IF replacement_window<> NIL THEN
DISPOSE(replacement_window,destroy_window);
window_object.destroy_window;
END;
PROCEDURE draw_window_outline(top_left_x,
top_left_y,
width,
height,
style,
fore,
back : BYTE);
VAR
x,y : BYTE;
offset : INTEGER;
{*
BEGIN
IF (style<>255) AND (width>2) AND (height>2) THEN
BEGIN
offset:=(top_left_x-1)*2
+(top_left_y-1)*160;
MEM[$B800:offset]:=top_left_corner[style];
MEM[$B800:offset+1]:=back*16+fore;
FOR x:=1 TO (width-2) DO
BEGIN
MEM[$B800:offset+x*2]:=horizontal[style];
MEM[$B800:offset+x*2+1]:=back*16+fore;
END;
MEM[$B800:offset+(width-1)*2]:=top_right_corner[style];
MEM[$B800:offset+(width-1)*2+1]:=back*16+fore;
FOR y:=1 TO (height-2) DO
BEGIN
MEM[$B800:offset+y*160]:=vertical[style];
MEM[$B800:offset+y*160+1]:=back*16+fore;
MEM[$B800:offset+(width-1)*2+y*160]:=vertical[style];
MEM[$B800:offset+(width-1)*2+y*160+1]:=back*16+fore;
END;
offset:=(top_left_x-1)*2
+(top_left_y+height-2)*160;
MEM[$B800:offset]:=bottom_left_corner[style];
MEM[$B800:offset+1]:=back*16+fore;
FOR x:=1 TO (width-2) DO
BEGIN
MEM[$B800:offset+x*2]:=horizontal[style];
MEM[$B800:offset+x*2+1]:=back*16+fore;
END;
MEMW[$B800:offset+(width-1)*2]:=bottom_right_corner[style];
MEM[$B800:offset+(width-1)*2+1]:=back*16+fore;
END;
END;
*}
BEGIN
IF (style<>255) AND (width>2) AND (height>2) THEN
BEGIN
offset:=(top_left_x-1)+(top_left_y-1)* ScreenWidth;
VideoBuf^[offset]:=top_left_corner[style];
VideoBuf^[offset+1]:=back*16+fore;
FOR x:=1 TO (width-2) DO
BEGIN
VideoBuf^[offset+x]:=horizontal[style];
VideoBuf^[offset+x]:=back*16+fore;
END;
VideoBuf^[offset+(width-1)]:=top_right_corner[style];
VideoBuf^[offset+(width-1)]:=back*16+fore;
FOR y:=1 TO (height-2) DO
BEGIN
VideoBuf^[offset+y* ScreenWidth]:=vertical[style];
VideoBuf^[offset+y*0+1]:=back*16+fore;
VideoBuf^[offset+(width-1)+y*ScreenWidth]:=vertical[style];
VideoBuf^[offset+(width-1)+y*ScreenWidth+1]:=back*16+fore;
END;
offset:=(top_left_x-1)
+(top_left_y+height-2)*160;
VideoBuf^[offset]:=bottom_left_corner[style];
VideoBuf^[offset+1]:=back*16+fore;
FOR x:=1 TO (width-2) DO
BEGIN
VideoBuf^[offset+x]:=horizontal[style];
VideoBuf^[offset+x]:=back*16+fore;
END;
VideoBuf^[offset+(width-1)]:=bottom_right_corner[style];
VideoBuf^[offset+(width-1)]:=back*16+fore;
END;
UpdateScreen(false);
END;
PROCEDURE blank_window(top_left_x,
top_left_y,
width,
height,
colour : BYTE);
VAR
x_offset,
y_offset : BYTE;
code : WORD;
BEGIN
FOR y_offset:=top_left_y TO (top_left_y+height) DO
BEGIN
FOR x_offset:=top_left_x TO (top_left_x+width) DO
BEGIN
{* MEM[$B800:(x_offset-1)*2
+(y_offset-1)*160]:=32;
MEM[$B800:(x_offset-1)*2
+(y_offset-1)*160+1]:=colour*16; *}
// VideoBuf^[(x_offset-1)+(y_offset-1)*160]:=32;
// VideoBuf^[(x_offset-1)+(y_offset-1)*160]:=colour*16 ;
VideoBuf^[(x_offset-1)+(y_offset-1)*ScreenWidth] :=32 + $16 shl
8;
END;
END;
UpdateScreen(false);
END;
PROCEDURE draw_window(top_left_x,
top_left_y,
width,
height,
style,
border_fore,
border_back,
window_fore,
window_back : BYTE);
BEGIN
draw_window_outline(top_left_x,
top_left_y,
width,
height,
style,
border_fore,
border_back);
blank_window(top_left_x+1,
top_left_y+1,
width-3,
height-3,
window_back);
END;
PROCEDURE siren(sound_length : BYTE;
delay_length : BYTE);
VAR
count : INTEGER;
BEGIN
FOR count := 10 DOWNTO 1 DO
BEGIN
sound(sound_length*count);
delay(delay_length);
nosound;
delay(sound_length);
END;
END;{PROCEDURE siren}
PROCEDURE truncate_message(VAR message_string : STRING);
VAR
counter : INTEGER;
temp_string : STRING;
BEGIN
temp_string := '';
FOR counter := 1 to 69 DO
temp_string := temp_string + message_string[counter];
message_string := temp_string;
END;
PROCEDURE write_boxed_message(line_1,
line_2,
line_3,
line_4,
line_5 : STRING);
VAR
message : ARRAY [1..5] OF STRING;
message_window_height : INTEGER;
message_window_width : INTEGER;
message_window_x : INTEGER;
message_window_y : INTEGER;
PROCEDURE work_out_box_dimensions;
VAR
z,
t,
message_length : BYTE;
BEGIN
message[1]:=line_1;
message[2]:=line_2;
message[3]:=line_3;
message[4]:=line_4;
message[5]:=line_5;
message_window_height:=5;
message_window_width:=0;
FOR z:=1 TO 5 DO
BEGIN
message_length:=LENGTH(message[z]);
IF message_length>69 THEN
BEGIN
truncate_message(message[z]);
message_length := 69;
END;
IF (message_length>message_window_width) THEN
message_window_width:=message_length;
IF (message_length=0) AND (z>1) AND (LENGTH(message[z-1])>0) THEN
message_window_height:=(z-1);
IF (message_window_height<5) AND (message_length>0) THEN
message_window_height:=z;
END;
message_window_height:=message_window_height+2;
message_window_width:=message_window_width+4;
message_window_x:=TRUNC((84-message_window_width)/2);
message_window_y:=TRUNC((24-message_window_height)/2);
END;
PROCEDURE write_message_in_box(box : screen_window);
VAR
z : INTEGER;
BEGIN
WITH box DO
BEGIN
textbackground(window_back_colour);
textcolor(window_fore_colour);
FOR z:=1 TO (message_window_height-2) DO
BEGIN
GOTOXY(message_window_x
+TRUNC((message_window_width-LENGTH(message[z]))/2),
message_window_y+z);
WRITE(message[z]);
END;
END
END;
BEGIN
IF error_message.window_has_been_saved THEN
clear_last_boxed_message;
work_out_box_dimensions;
error_message.initialise(message_window_x,
message_window_y,
message_window_width,
message_window_height,
2,
yellow,
red,
yellow,
red);
IF mouse_enabled THEN
hide_mouse;
error_message.replacement_window^.save;
error_message.appear;
write_message_in_box(error_message);
gotoxy(80,25);
error_message.save;
END;
PROCEDURE halt_with_message(line_1,
line_2,
line_3,
line_4 : STRING);
VAR
dummy : CHAR;
line_5 : STRING;
BEGIN
line_5:='Contact Your Product Support Representative';
IF write_message_to_screen THEN
BEGIN
write_boxed_message(line_1,
line_2,
line_3,
line_4,
line_5);
siren(50,35);
dummy := readkey;
error_message.disappear;
error_message.destroy_window;
END
ELSE
halt_with_message_string := line_1+' '+line_2+' '+line_3+'
'+line_4;
halt;
END;
PROCEDURE clear_last_boxed_message;
BEGIN
IF (error_message.window_has_been_saved) THEN
BEGIN
error_message.replacement_window^.appear;
error_message.destroy_window;
END;
IF mouse_enabled THEN
show_mouse;
END;
PROCEDURE write_box_message (str1, str2, str3 : string; exit_required :
BOOLEAN);
var
border : integer;
ch1 : char;
longest : string;
begin
longest := str1;
if length(str2) > length(longest) then
longest := str2;
if length(str3) > length(longest) then
longest := str3;
clrscr;
border := TRUNC((80 - length(longest)) / 2) - 3;
textbackground(1);
window (border,5,80-border,11);
clrscr;
textcolor(11);
writeln;
writeln(' ', str1);
writeln(' ', str2);
writeln(' ', str3);
writeln;
if exit_required then
begin
textcolor(13);
writeln(' Press any key to exit');
ch1 := ReadKey;
textbackground(0);
textcolor(7);
window (1,1,80,25);
clrscr;
halt;
end;
end;
FUNCTION upcase_string(st : STRING): STRING;
VAR
z : INTEGER;
BEGIN
FOR z:=1 TO LENGTH(st) DO
st[z]:=UpCase(st[z]);
upcase_string:=st;
END;
BEGIN
InitVideo;
error_message.initialise( 1, 1, 1, 1,
2,
yellow,
red,
yellow,
red);
write_message_to_screen := TRUE;
halt_with_message_string := '';
DoneVideo;
END.
--
View this message in context: http://free-pascal-general.1045716.n5.nabble.com/Segmentation-Error-using-VideoBuf-tp5719293p5719692.html
Sent from the Free Pascal - General mailing list archive at Nabble.com.
More information about the fpc-pascal
mailing list