Hi...I'm Zozel...I am trying to make a program and to use the cleardevice() function to clear screen...but I'm not satisfied of this function...calling it, it flashes the screen...it "blinks" my whole screen.....how could I avoid this flash?...please help!...I appreciate any answer ...:)
Duoas 1,025 Postaholic Featured Poster
Using the old BGI functions you are pretty much out of luck... Sorry.
Are you using an old Turbo C compiler or are you using the WinBGIm package?
Zozel 0 Newbie Poster
Yes...I'm using the old C++ ...Borland C++ 3.1 FOR DOS....but I believe it's possible...for example how did the one that made Mario succeded to do this...I don't see any flashing out there...and it's made in Turbo PASCAL....but if I have no chance with cleardevice() could anyone give me another way to clear the screen - without that flashing of course....THANKS in advance....:)
Duoas 1,025 Postaholic Featured Poster
It has nothing to do with the function. It is flashing because the DOS emulator is lagging when your code updates the screen.
Now that my brain is working, though, if you are trying to do animations stay away from cleardevice().
There are two little functions to set the active page and the displayed page (I don't remember their names right now... but you can look them up).
The trick is this:
1. set the active page to whichever page is currently hidden
2. clear, draw, etc... whatever you need to do to create the next frame of animation
3. set the visible page to the active page
4. rinse and repeat
Hope this helps.
Zozel 0 Newbie Poster
#include<conio.h>
#include<graphics.h>
#include<dos.h>
int x,y;void call();
void scene(){
setbkcolor(LIGHTBLUE);
setfillstyle(1,LIGHTGREEN);
bar(0,getmaxy()/2+95,getmaxx(),getmaxy());
setcolor(RED);
for(int i=1;i<16;i++) circle(x,y,i);
call();
}
void call(){
char c;
c=getch();
while(!kbhit()){
if (kbhit())
c=getch();
}
if (c==97){
x+=15;
delay(10);
cleardevice();//this flashes the screen
scene();
}
}
void main(){
int gd,gm;
x=15;y=getmaxy()/2+319;
gd=DETECT;
initgraph(&gd,&gm,"D:\\BORLANDC\\BGI");
scene();
getch();
closegraph();
}
Could you show me how could I avoid the flashing by reproducing this code with the functions that you reffered to?....Please...Thx in advance!:)
Prabakar 77 Posting Whiz
I don't have a turbo c compiler at home, though I am forced to use it in college.
Is it the case with you too? If not, the 32 bit world offers better ways to do everything.
I had a glance of your code & I want to say something
1) Formate your code
2) Use Code Tags
3)
while(!kbhit()){
if (kbhit())
c=getch();
}
When you want to wait indefinitely, just c= getch() will be enough.
4) calling scene() in call() & call() in scene() Does the program end? That may be the reason for the flashing.
Hope it helps:)
Lastly, Could you please state the problem.
EDIT:
There is something more that I want to say.
Console output did not work for me in graphics mode. perhaps console input too does not work & it may also be a reason for the flashing(not sure) I shall test it in college tomorrow.
Zozel 0 Newbie Poster
No...I asked for future projects for me...I have to do something in the DOS interface...
It's something special...I know in windows interface it would be very very easy to make some graphics...I worked in C#,C++,Java,Visual Basic & Others...I just need to work under DOS...Thanks in advance!!
Prabakar 77 Posting Whiz
Well, I ain't know this for sure, but please do try to replace getch() with scanf() or getchar()
Zozel 0 Newbie Poster
OK...to convince yourself that these functions have nothing to do with the flashing copy the code and eliminate them...you'll see that it still blinks...it is about the cleardevice() or clearviewport() functions....and it doesn't work with setactivepage() and setvisualpage() functions...it's a bit complicated...i really need this...please think again and answer if anyone has any idea...Thx!...:)
Duoas 1,025 Postaholic Featured Poster
It has been a long time since I played with BGI graphics, and I did it in Turbo Pascal. If you want I'll whip something up to demonstrate page flipping... This is a standard technique, often called "double buffering".
Zozel 0 Newbie Poster
OK...Thanks a lot...so how could you give me a hand?....are a kind of tutor or something?...do you have a site or a contact?....my Yahoo! Messenger Adress is corneliuzuzu ...if you'd want to you could give an Add...thanks!
Zozel 0 Newbie Poster
I have to sleep now...what a day....
Zozel 0 Newbie Poster
About "double buffering"...I read on the internet that it can't be done in Borland C++ 3.1 for DOS....and I want to ask you too...is it possible to do it on the DOS platform in Borland C ?...
I really need to make it in this prog...I intend to take some of my projects to school and run them on the DOS Borland C++...thanks!!...
Duoas 1,025 Postaholic Featured Poster
I don't know where you read that, but they're wrong. Multiple display pages is a hardware feature, so you can use it no matter what programming language you use.
Give me a little bit to provide your example..
Prabakar 77 Posting Whiz
I run your program in college & all I had was a ball which run from one end to another end with blue background & green basement:). No flashing occurred:-O Perhaps your program may not be your problem.;)
And I realize that getch() causes no problem.
Just for my curiosity, what are you doing?:?:
And then, I would suggest a class for the ball & the background, but without knowing what you are doing I am not sure if it is a good suggestion.
Duoas 1,025 Postaholic Featured Poster
OK, I told you I'd get you an example. I don't want to spend a lot of time finding the libraries to do it and coding one, but I do have an old program I wrote many many moons ago, when I was still new to programming. It is in Turbo Pascal, but you can translate the important parts to Turbo C++ easily enough. Just a couple notes for you:
-
uses Graph;
corresponds to#include <graphics.h>
Individual Borland graphics routines are named similarly (I think TC puts them all in lowercase though). -
foo^
is the same as*foo
-
ReadKey
corresponds togetch
-
{
and}
correspond to/*
and*/
-
Mark
andRelease
are old Borland heap control procedures. I don't think TC has corresponding procedures... better for you tofree()
the image data manually. - The arrow keys move the background around. ESC quits.
- The procedures of interest to you are: InitiateGraphics, FlipPages, ClearPage, and the main code block.
- It is fairly heavily commented in my newbie style.
Ok, so here it is. (I use 80 column limits, but DaniWeb is shorter, so what you see following looks messy. Just click the "Toggle Plain Text" button to cut and paste something more readable.)
program GPImage;
uses Crt,Graph;
var
GraphDriver, GraphMode : integer; { hardware refrences }
WX1,WY1, WX2,WY2, MX2,MY2 : integer;{ window x1,y1, x2,y2, center of scr }
CurrentPage : integer; { active, hidden graphics page }
IMAGE_SIZE : integer; { size of foreground image }
MASK_IMAGE, DETAIL_IMAGE : pointer; { foreground image }
BKisizes : integer; { size of background images }
BKimages : array[1..6,1..6] of pointer; { background images }
BKindexX, BKindexY : integer; { background window index }
ch : char; { user controls screen scrolling }
Stop : boolean; { stop execution if true }
Xincr, Yincr : integer; { controls direction BK is scrolled }
HeapPtr : pointer; { state of heap upon entry and set upon exit }
{
INITIALIZATIONS
}
procedure InitiateGraphics;
var GrErrorCode : integer;
begin
InitGraph(GraphDriver, GraphMode, ''); { enter graphics mode }
GrErrorCode := GraphResult;
if GrErrorCode <> grOK then begin { check to make sure }
Writeln('Graphics Error : ' { graphics correctly }
+GraphErrorMsg(GrErrorCode)); { initiated }
Halt(1); end;
MX2 := GetMaxX div 2; MY2 := GetMaxY div 2; { center of true screen }
WX1 := MX2 -300+1; WY1 := MY2 -150+1; { make screen 600x300 }
WX2 := MX2 +300; WY2 := MY2 +150; { pixels large }
SetLineStyle(UserBitln,$AAAA,NormWidth); { draw a boarder around }
SetVisualPage(0);
SetActivePage(0); { page 0 }
Rectangle(WX1-1,WY1-1, WX2+1, WY2+1); { the "background window" }
SetTextJustify(CenterText,CenterText); { set how text is mapped }
SetTextStyle(DefaultFont,HorizDir,2); { to the screen }
OutTextXY(MX2,MY2,'Please wait...'); { keep user }
SetActivePage(1); { page 1 }
Rectangle(WX1-1,WY1-1, WX2+2, WY2+1); { the "background window" }
SetViewPort(WX1,WY1, WX2,WY2, ClipOn); { set the window }
CurrentPage := 1;
MX2 := 300; MY2 := 150; { center of "window" }
SetLineStyle(Solidln,0,NormWidth); { restore line style }
end; { proc. InitiateGraphics }
{
OPERATIONS
}
procedure FlipPages; { show one page of graphics }
begin { while drawing another }
if CurrentPage = 0 then begin { (allows smooth animation) }
CurrentPage := 1;
SetVisualPage(0);
SetActivePage(1); end else begin
CurrentPage := 0;
SetVisualPage(1);
SetActivePage(0); end;
end; { proc. FlipPages }
procedure ClearPage; { erase current graphics page }
begin
SetFillStyle(SolidFill,0);
Bar(0,0, 639,347);
end; { proc. ClearPage }
procedure DrawBK; { draw background in new position }
var xscr, xcntr, yscr, ycntr : integer;
begin
ycntr := 1; { yloop }
yscr := BKindexY;
repeat
xcntr := 1; { xloop }
xscr := BKindexX;
repeat
if (xscr = 1) and
(yscr = 1) then
PutImage( (xcntr-1)*100, { calculate x coordinate }
(ycntr-1)* 50, { calculate y coordinate }
BKimages[xscr][yscr]^, { address correct image }
NotPut ) else { show corner of BK array }
PutImage( (xcntr-1)*100, { calculate x coordinate }
(ycntr-1)* 50, { calculate y coordinate }
BKimages[xscr][yscr]^, { address correct image }
NormalPut ); { overwrite previous screen }
if xscr = 6 then
xscr := 1 else
Inc(xscr,1);
Inc(xcntr);
until (xcntr > 6); { xloop end }
if yscr = 6 then
yscr := 1 else
Inc(yscr,1);
Inc(ycntr,1);
until (ycntr > 6); { yloop end }
end; { proc. DrawBK }
{
IMAGES
}
procedure DrawForeGroundImage( x, y : integer;
c1, c2 : word;
MaskOn : boolean);
begin
if MaskOn then { draw MASK or DETAIL image }
SetLineStyle(Solidln,0,ThickWidth) else
SetLineStyle(Solidln,0,NormWidth);
SetColor(c1); { draw the image }
Line(x-50,y-00, x+40,y-20); Line(x+40,y-20, x+60,y+00); { ( moveto & }
Line(x+60,y+00, x-50,y-00); Line(x-50,y-00, x+80,y+05); { lineto }
Line(x+80,y+05, x+61,y+00); Line(x+61,y+00, x+41,y-20); { draw thin }
Line(x+41,y-20, x+51,y-30); Line(x+51,y-30, x+50,y-30); { lines ) }
Line(x+50,y-30, x+40,y-20); Line(x+40,y-20, x+50,y-30);
Line(x+50,y-30, x+45,y-30); Line(x+45,y-30, x+23,y-16);
Line(x+23,y-16, x+35,y-04); Line(x+35,y-04, x+34,y-04);
Line(x+34,y-04, x+22,y-16); Line(x+22,y-16, x+34,y-04);
Line(x+34,y-04, x-30,y-04); Line(x-51,y-00, x+40,y+10);
Line(x+40,y+10, x+53,y+04);
SetFillStyle(SolidFill,c2); SetColor(c2); { color image }
FloodFill(x+40,y-10,c1); FloodFill(x+30,y+05,c1);
Circle(x+20,y-08,4); FloodFill(x+20,y-08,c2);
if MaskOn then
begin { fill completely for MASK }
FloodFill(x+42,y+02,c1); FloodFill(x+40,y-23,c1);
Line(x+40,y-23, x+20,y-15);
end else begin { else draw smiley face }
SetColor(Black); Arc(x+20,y-07, 180,360, 2);
PutPixel(x+18,y-09,Black); PutPixel(x+22,y-09,Black);
end;
IMAGE_SIZE := ImageSize(x+100,y+20, x-70,y-40);
if MaskOn then
begin
GetMem(MASK_IMAGE,IMAGE_SIZE); { allocate mem for MASK pic }
GetImage(x+100,y+20, x-70,y-40, MASK_IMAGE^); { and save it }
end else begin
GetMem(DETAIL_IMAGE,IMAGE_SIZE); { allocate mem for DETAIL pic }
PutImage(x-70,y-40, MASK_IMAGE^, XORput); { get "negative" }
GetImage(x+100,y+20, x-70,y-40, DETAIL_IMAGE^); { and save it }
end;
end; { proc. DrawForeGroundImage }
procedure DrawBackGroundImage( x, y : integer;
c1, c2, c3 : word );
const
BKpic : array[1..14] of PointType = { BK image information }
( (x: 60; y: 70), (x: 130; y: 50), (x: 120; y: 70),
(x: 110; y: 60), (x: 80; y: 80), (x: 95; y: 75),
(x: 140; y: 120), (x: 50; y: 130), (x: 80; y: 100),
(x: 110; y: 150), (x: 110; y: 90), (x: 80; y: 100),
(x: 150; y: 100), (x: 60; y: 70) );
var
p : array[1..2,1..2] of pointer;
ycntr, switch : integer;
begin
SetColor(c1); { background color }
Rectangle(x-100,y-50, x+101,y+51);
SetFillStyle(SolidFill,c2);
FloodFill(x,y,c1);
SetColor(c3); { set outline color }
SetFillStyle(InterLeaveFill,c2); { set inside color }
FillPoly(SizeOf(BKpic) div SizeOf(PointType), BKpic); { draw BK image }
SetColor(c1);
SetTextStyle(TriplexFont,HorizDir,4); { add to BK image }
OutTextXY(30,95,'BK');
SetFillStyle(CloseDotFill, c1); { upper-left corner }
Circle(x-100,y-50,10); FloodFill(x-99,y-49,c1);
SetFillStyle(InterLeaveFill,c1); { upper-right corner }
Circle(x+101,y-50,10); FloodFill(x+99,y-49,c1);
SetFillStyle(XHatchFill, c1); { lower-left corner }
Circle(x-100,y+51,10); FloodFill(x-99,y+49,c1);
SetFillStyle(SolidFill, c1); { lower-right corner }
Circle(x+101,y+51,10); FloodFill(x+99,y+49,c1);
BKisizes := ImageSize(0,0,100,50); { allocate memory for BK }
GetMem(p[1][1],BKisizes); GetMem(p[2][1],BKisizes);
GetMem(p[1][2],BKisizes); GetMem(p[2][2],BKisizes);
GetImage(x-99,y-49,x,y , p[1][1]^); { save images to memory }
GetImage(x+1,y-49,x+100,y , p[2][1]^);
GetImage(x-99,y+1,x,y+50, p[1][2]^);
GetImage(x+1,y+1,x+100,y+50, p[2][2]^);
switch := 1;
for ycntr := 1 to 6 do begin { set up BK image array for }
BKimages[1][ycntr] := p[1][switch]; { each section of the BK }
BKimages[2][ycntr] := p[2][switch];
BKimages[3][ycntr] := p[1][switch];
BKimages[4][ycntr] := p[2][switch];
BKimages[5][ycntr] := p[1][switch];
BKimages[6][ycntr] := p[2][switch];
if switch = 1 then
switch := 2 else
switch := 1; end;
BKindexX := 1; { initialize BK window index }
BKindexY := 1;
BKindexX := 5; { initialize last BK index }
BKindexX := 1; { y not used }
end; { proc. DrawBackGroundImage }
{
MAIN
}
begin
Mark(HeapPtr); { save state of heap }
GraphDriver := {HercMono; } { EGA; } VGA;
GraphMode := {HercMonoHi;} { EGAhi; } VGAmed;
InitiateGraphics; { enter graphics mode }
if GraphDriver = HercMono then begin
DrawForeGroundImage(100,100, 1,1, true);
DrawForeGroundImage(100,200, 1,1, false); end else begin
DrawForeGroundImage(100,100, White,White, true);
DrawForeGroundImage(300,200, Red, Green,false); end;
ClearPage; { avoid getting FG image in BK image }
if GraphDriver = HercMono then
DrawBackGroundImage(100,100, 1, 0, 1) else
DrawBackGroundImage(100,100, Yellow,Blue,LightGray);
SetFillStyle(SolidFill,1); { draw and show first screen }
DrawBK;
PutImage(230,120, MASK_IMAGE^, ORput);
PutImage(230,120, DETAIL_IMAGE^, XORput);
FlipPages;
Stop := false;
repeat
ch := ReadKey;
if ch = #0 then
begin
ch := ReadKey; { if numeric keypad pressed then move BK }
case ch of
{ 7 } #71 : begin Xincr := 1; Yincr := 1; end;
{ 8 } #72 : begin Xincr := 0; Yincr := 1; end;
{ 9 } #73 : begin Xincr := -1; Yincr := 1; end;
{ 4 } #75 : begin Xincr := 1; Yincr := 0; end;
{ 6 } #77 : begin Xincr := -1; Yincr := 0; end;
{ 1 } #79 : begin Xincr := 1; Yincr := -1; end;
{ 2 } #80 : begin Xincr := 0; Yincr := -1; end;
{ 3 } #81 : begin Xincr := -1; Yincr := -1; end;
end; { case }
Inc(BKindexX,Xincr); { increment X }
if BKindexX = 7 then BKindexX := 1;
if BKindexX = 0 then BKindexX := 6;
Inc(BKindexY,Yincr); { increment Y }
if BKindexY = 7 then BKindexY := 1;
if BKindexY = 0 then BKindexY := 6;
DrawBK; { draw the new BK }
PutImage(230,120, MASK_IMAGE^, ORput); { draw the FG image }
PutImage(230,120, DETAIL_IMAGE^, XORput);
FlipPages; { show work }
end else
if (ch = #27) or { if <ESC> or }
(ch = #13) then { <CR> pressed then }
Stop := true; { terminate program }
until Stop;
CloseGraph; { return to AlphaNumeric mode }
Release(HeapPtr); { clean up }
end. { terminate normally }
Hope this helps.
Zozel 0 Newbie Poster
Thx...really useful...if you still have any more, PUT the codes that you can and you want...any code would be wellcomed and could help me...anyway...Thx again!!:)
Zozel 0 Newbie Poster
So...sorry that the answer comes a bit too late but guess what: CASE SOLVED...I finally did what I wanted...Many thx to DUOAS...hope I could help you like you helped me now...THX AGAIN!!!
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.