មេរៀនទី១២: ក្រាភិច GRAPHIC

មេរៀនទី១២: ក្រាភិច GRAPHIC
C C++
I.  សញ្ញាណទូទៅនៃ  GRAPHIC :
ការសំដែងទិន្នន័យមកលើ  SCREEN  ក្នុងTurbo  C  មានរបបពីរ  គឺ  ៖Text  ModeនឹងGraph Mode ។ Graph  Mode  មិនមែនជាខ្នាតគំរូរបស់គ្រប់ភាសា និង ម៉ាស៊ីនកុំព្យូទ័រទេ។ ព្រោះការគូសក្រាហ្វិចលើ Screen, អាស្រ័យ ដោយ ប្រភេទកុំព្យូទ័រនីមួយៗ, អាស្រ័យដោយប្រភេទ Screen នីមួយៗ ,,,,,។ ដើម្បីគូសរូប, ផាត់ពណ៍រូបភាព,,,,នៅលើកុំព្យូទ័រ,យើងត្រូវប្ដូរចរន្ដអគ្គសនីបញ្ជា Screen ពីText ModeទៅGraph Mode។

កុំព្យូទ័រ, IBM – PC/XT /AT សព្វថ្ងៃមានច្រើនប្រភេទខុសគ្នាដូចខាងក្រោម ៖
–  CGA : Color Graphic Adater : ចរន្ដអគ្គិសនីបញ្ជា Screen Color
+ (640 * 200) (មានអាប់ស៊ីស 640 Pixel, មានអរដោនេ 200Pixel ) មានពីរពណ៍
+ (320*200) មានបួនពណ៍ ។
–  MGDA : Monochrome Graphic Display Adapter ឬ Hercule :
ចរន្ដអគ្គិសនីបញ្ជា Screenស-ខេμៅ (monochrome),

+ 720 * 348 (មានអាប់ស៊ីស 720Pixel,មានអរដោនេ 348Pixel )
−    EGA : Enhanced Graphic Adapter : ចរន្ដអគ្គិសនីបញ្ជា Screen Color
+ 640 * 350 និងអាចជ្រើសរើសបាន ១៦ពណ៍ ។
–  VGA : Video Graphic Array : 640 * 480
Super VGA : 1024 * 768 : អាចជ្រើសរើសបានដល់ ២៥៦ ពណ៍។

II.  បណ្ដា  FILE របស់ Graphic : ពេលប្រើ Graphic ជាមួយ Turbo C នៅលើ Disk យើងត្រូវ Copy បណ្ដា File សំខាន់ៗ របស់ Graphic ដូចខាងក្រោម ៖

*.TPU
*.
BGI
*.CHR

នឹងនៅដើមកមμវិធី យើងត្រូវ Proto Type ដើម្បីប្រើ GRAPH.TPU ដូចខាងក្រោម ៖

# include<graphics.h>
+  បណ្ដា  File  *.BGI  (BGI  :  Borland  Graphic  Interface  )  គឺជាបណ្ដា  File
ផ្ទុកបណ្ដាឃ្លាបញ្ជា Screen ផ្សេងគ្នាដូចជា ៖

CGA.BGI ; EGAVGA.BGI ; HERC.BGI ;
+  បណ្ដា  File  *.CHR  ជាបណ្ដា  File  ផ្ទុកបណ្ដាឃ្លាបញ្ជាសំរាប់គូសប្រភេទអក្សរក្នុង Graphic។

ដូចជាបណ្ដា File ខាងក្រោមនេះ ៖

GOTH.CHR  (អក្សរ Gothic) LITT.CHR (Small Font) SANS.CHR (អក្សរ Sons Serif) TRIP.CHR (អក្សរធំជាង៣ដង ,Triplex)

ដើម្បីងាយយល់របៀបប្រើក្រាហ្វិច, យើងពិនិត្យ  ឧទាហរណ៍គូស បន្នាត់ពីមុំកែងខាងលើផ្នែក ខាងឆ្វេងចុះមក មុំកែង ខាងក្រោម  ផ្នែកខាងស្ដាំ ៖

# include<graphics.h>
# include<conio.h>

main()
{ int gd=DETECT, gm ,errorcode ; initgraph(&gd,&gm,”C:\\TC\\BGI”); errorcode =graphresult () ; if(errorcode != grOk())
{  printf(“ Graphics error : %s \n “,grapherrormsg(errorcode));
printf(“ Press any key to halt : “);  getch();
exit(1);
}
moveto(0,0) ;       (* នាំ Cursor Graph ទៅចំនុចមុំកែងខាងលើ,ផ្នែកខាងឆ្វេង *)
lineto(getmaxx(),getmaxy() ) ;     (* គូសបន្ទាត់ *)
getch();
closegraph();
}
Statement initgraph មានទំរង់ Declaration ដូចខាងក្រោម ៖

initgraph( &graphdriver , &graphmode , driverpath ) ;

គឺជា Statement បង្កើត (Greate Graphics) ក្រាហ្វិច ក្នុងនោះ ៖

+ graphdriver ផ្ទុកតំលៃកំណត់ប្រភេទ Screen :

0  DETECT  3  EGA           6  IBM8514  9    VGA
1  CGA           4  EGA 64     7  HercMono 10  PC3270
2  MCGA       5  RGAMono 8  ATT 400
+graphmode  ផ្ទុកតំលៃកំណត់ Mode  ក្រាហ្វិច ។
+driverpath ប្រាប់អោយ Turbo C ស្គាល់ Directory ដែលផ្ទុកបណ្ដា File បញ្ជាក្រាហ្វិច ។ តារាងខាងក្រោមនេះបង្ហាញឈោះរបស់បណ្ដាតំលៃរបស់ GraphDriver,graphMode :

graphdriver graphmode
CGA CGAc0,1,2,3,4 320 * 200 CGA
CGAHi 640 * 200 CGA
MCGA MCGA0,,1,,2,,3 320 * 200
MCGAMed 320 * 200
MCGAHi 640 * 480
EGA EGALo 640 * 200  Ù CGA
EGAHi 640 * 350
EGA64 EGA64 Lo 640 * 200 Ù CGA
EGA64 Li 640 * 350
EGAMono EGAMono Hi 640 * 350
VGA VGA Lo 640 * 200
VGA Med 640 * 350
VGA Hi 640 * 480
HercMono HercMonoHi 720 * 348
ATT400 ATT400 C0,1,2,3 320 * 200
ATT 400 Med 640 * 400
ATT 400 Hi 640 * 400
PC3270 PC 3270 Hi 720 * 350
IBM8514 IBM8514 Lo 640 * 480 ,, 256COLOR
IBM8514 Hi 1024 * 768 ,, 256COLOR

Statement initgraph មាន Variable 2 គឺ : &gd, &gm ។មុននេះ បើសិនជា graphdriver ត្រូវបានកំនត់ ដោយតំលៃ DETECT នោះ initgraph នឹងកំនត់យក graphdriver និង graphmode  ដែលល្អ បំផុត  (មើលក្នុង តារាង ខាង លើ)។ លទ្ធផលនឹងផ្ដល់អោយ  &gd,  &gm សមមូលនឹង graph diver, graphmode ។ ក្នុងករណី Screen មាន Mode ច្រើនប្រភេទខុសគ្នា, យើងអាច ជ្រើសរើស gaphdrver, GraphMode សមរម្យ ដោយមិន ប្រើ របៀបកំនត់តំលៃអោយ Gd = DETECT;តែយើងកំណត់ តំលៃ សមរម្យអោយ gd និង gm មុនពេលហៅ initgraph ។

Ex :   gd = EGA ;    gm = EGAHi ;

initgraph(&Gd,&Gm, “ C:\\ TC\\BGI” ) ;

graphgesult គឺជា Function របស់ Tur bo C ,វាអោយយើងដឹង ពី ស្ថានភាពរបស់ Graphic ។

Function មានតំលៃដូច ក្នុងតារាងខាងក្រោនេះ ៖

ឈេμាះ

តំលៃ

RbePT kMhus

grOk()

0

OK, គμានកំហុស
grNoInitGraph()

-1

មិនទាន់ដំណើរការបាន
grNotDetected()

-2

អត់មានផ្នែក HardWareGraph
grFileNotFound()

-3

អត់រកឃើញបណ្ដា File បញ្ជា

Graph

III. បណ្ដាStatement ប្រើជាមួយGraph :
a, moveto(x,y) ;

គឹជា  Statement  បញ្ជូនទីតាំង  CP(Current-Position)  ទៅចំនុច ដែលមានកូអរដោនេ X,Y។ Cursor ក្នុង Screen graph កំណត់ ដោយ កូអរដោនេ វាអត់មានចំនុចភ្លឺលោតភ្លឹបភ្លេតៗដូចក្នុង ScreenText ទេ ។
C C++អនុគមន៍ getx(), gety() ផ្ដល់នូវកូអរដោនេនៃ Cursor-Graph.

b,lineto (x,y); គឺជា Statement គូសបន្ទាត់ត្រង់ពីទីតាំង Cursor-Graph បច្ចុប្បន្នទៅចំនុចដែលមានកូអរដោនេ (X,Y)  បន្ទាប់ពី គូសរួច Cursor-Graph ស្ថិតនៅទីតាំងថμីដែលមានកូអរដោនេ (X,Y)

Function getmaxx(),getmaxy(),ប្រើដើម្បីគណនាចំនួនចំនុច អតិបរមាតាមអក័្ស អាប់ស៊ីសនិងអ័ក្ស អរដោនេ ។ មានន័យ ថា, ជាកូអរដោនេចំនុចនៃ មុំកែងខាង ក្រោម ផ្នែកខាងស្ដាំ។

Ex ចំពោះ EGA Screen,  នោះ getmaxx = 639, getmaxy = 349 ។
+ដើម្បីរក្សា Screen-Graph ក្នុងការពិនិត្យមើលលទ្ធផលយើងប្រើ Statement getch() ។
+ដើម្បីបញ្ជប់ Graph Mode យើងប្រើ Statement closesgraph() ;

 IV. Function  គូសចំនុច   ៖

Function  គូសចំនុចមានលក្ខណៈជាមូលដ្ឋាន, ព្រោះចំនុចបង្កើតបាន ជារូបភាពផ្សេងៗទ្យេត ។

putpixel(int x, int y ,int  color) ;

គូសចំនុចភ្លឺត្រង់ទីតាំងដែលមានកូអរដោនេ (X,Y) មានពណ៍ជា Color ។

getpixel( int x, int y ) ;

ជា Function បង្ហាញប្រាប់ពណ៍បច្ចុប្បន្នត្រង់ចំនុច (X,Y) ។

V. Function គូសបន្ទាត់ត្រង់  ៖

line(int  x1, int  y1, int  x2, int  y2 ) ;

ជា Function គូសបន្ទាត់ត្រង់ពីចំនុចដែលមានកូអរដោនេ (X1,Y1) ទៅចំនុច (X2,Y2)។ វាមិនអាស្រ័យទៅនឹង ទីតាំងនៃ CP ( Current-Position) ។ ក្រោយពីគូសរួច CPនឹងស្ថិតនៅត្រង់ចំនុច (X2,Y2) , ពេលនោះ LineTo(X,Y) នឹង គូសបន្ទាត់ពីទីតាំង CP ទៅចំនុច (X,Y) ។

linerel( int dx, int dy ) ;

ជា Function គូសអង្កត់ត្រង់ពីទីតាំង CP ទៅចំនុចថμីដែលមានកូអរដោនេ (X + dx, Y + dy)។

ក្រោយពីគូសរួច , CP ស្ថិតនៅចំនុចថ្នី (X+dx,Y+dy)។

 VI. Function គូសរង្វង់   ៖

circle(int x, int y , int R ) ;

ជា Function គូសរង្វង់ដែលមានផ្ចិតត្រង់ចំនុន (X,Y), មានកាំ R ។

pieslice( int x, int y , int start, int end ,int R ) ;

ជា Function គូសផ្ទែនៃរង្វង់ ។

ellipse(int x, int y , int start , int end ,int dx , int dy) ;

ជា Function គូស Ellipse ។

 VII.  សំដែងអត្ដបទលើ  SCREEN GRAPH-MODE :

ក្នុង graphmode, Statement  printf() នឹង cprintf()  មិនស្របនឹង ScreenGraph

ទេព្រោះវាប្រើខ្នាតកូអរដោនេ ជាចំនួន character ។

យើងមាន Function ពីរសំរាប់សំដែងអត្ដបទលើ ScreenGraph :

–     outtext (char  *st) ;

សំដែងអត្ដន័យរបស់ St ត្រង់ចំនុច CP (Current Position) នៅលើ ScreenGraph ។

–     outtextxy ( int x,  int  y , char  *st ) ;សំដែងអត្ដន័យរបស់ St ត្រង់ចំនុច (X,Y) នៅលើ ScreenGraph  ។ ដូច្នេះ outtextxy

សមមូលនឹង Command ពីខាងក្រោម ៖

+ moveto (x,y) ;

+ outtext (*st) ;

–     settextstyle (font, direction, charsize) ;

កំណត់ប្រភេទអក្សរជាមួយ ៖

+ប្រភេទ Font អក្សរ ៖

– DefaultFont = 0 ;

-TriplexFont = 1 ;

– SmallFont = 2 ;

– SansSerifFont = 3 ;

– GothicFont = 4;

+Direction : HorizDir = 0 ; VertDir = 1 ;

+ CharSize :

CharSize ទទួលតំលៃពី ១ ដល់ ១០, ជាមេគុណដើម្បីពង្រីកតួអក្សរ ។

–     restorecrtmode() ;

Function នេះប្រើសំរាប់ត្រលប់ទៅ TextMode បណ្ដោះអសន្ន ។

–     setgraphmode() ;

Function នេះប្រើសំរាប់ត្រលប់ទៅ GrapgMode វិញ ។

–     closegraph() ;

Function នេះប្រើសំរាប់បិទ GrapgMode ហើយត្រលប់ទៅ TextMode វិញ ។

 VIII.  Procedure គូសចតុកោណកែង  ៖

–     rectangle(int x1, int  y1, int  x2, int  y2 ) ;

គូសចតុកោណកែងដែលមាន (X1,Y1)  ជាកូអរដោនេនៃចំនុច មុំកែង ខាងលើផ្នែកខាងឆ្វេង, និង

(X2,Y2) ជា កូអរដោនេនៃចំនុចមុំកែងខាងក្រោមផ្នែកខាងស្ដាំ ។

–     bar(int  x1, int y1, int  x2, int  y2 ) ;

គូសចតុកោណកែងតែមានផាត់ពណ៍នៅផ្ទៃខាងក្នុង ។

bar() ខុសពី rectangle() ត្រង់ rectangle() គ្រាន់តែគូស ជ្រុង របស់ចតុកោណកែងប៉ុណ្ណោះវាអត់ផាត់ពណ៍ ខាង ក្នុងទេ ។-     drawpoly( int   NumPoints  ,int    PolyPoints) ;

ជា Function គូសពហុកោណ, ត្រីកោណ ……។

-polypoints : ជាប៉ារ៉ាមែត្រអត់ប្រភេទ, វាផ្ទុកកូអរដោនេ នៃ បណ្ដាកំពូលរបស់ពហុកោណ ។

-numpoints : បង្ហាញចំនួនកូអរដោនេក្នុង PolyPoints ( ជាចំនួន​កំពូលរបស់ពហុកោណ ) ។ កូអរដោនេមួយមាន តំលៃពីរជាប្រភេទ int។ តំលៃមួយជាអាប់ស៊ីស X, និងតំលៃមួយទ្យេតជាអរដោនេ Y។

ចំណាំ ៖  ដើម្បីគូសពហុកោណដែលមាន N ជ្រុង, យើងត្រូវផ្ដល់ N+1 កូអរដោនេទៅ DrawPoly ។

Example :

# include<graphics.h>

# include<stdlib.h>

#include<conio.h>

main()

{  int gd=DETECT, gm, errorcode;

int poly={20,240,620,20,590,460,320,240,20,240} ;

initgraph(&gd,&gm.”C:\\TC\\BGI”);

errorcode = graphresult();

if (errorcode != grOk())

{ printf(“Graphics error : %s\n”,grapherrormsg(errorcode));

printf(“ Press any key to halt “);

getch();

exit(1);

} drawpoly(5,poly); getch(); closegraph(); return 0;

}

IX.  កំណត់ពណ៍រូបភាព  ៖

* setfillstyle ( int Pattern, int  Color) ;

ក្នុងនោះ Pattern ជាចំនួនគត់ពី ០ ដល់ ១២ ដែលមានឈេμាះ និងតំលៃដែលបានកំណត់និយមយ័មហើយ ៖

EmptyFill       = 0 ;       { ពណ៍ខ្នៅ } SolidFill   = 1 ;     { ពណ៍ក្រម៉ៅប្រផេះ }

LineFill          = 2 ;       { – – -}

LtSlashFill    = 3 ;       { / / / }

SlashFill        = 4 ;       {/ / / ដែលមានបន្ទាត់តូច } BkSlashFill = 5 ;     {\ \ \ ដែលមានបន្ទាតក្រាស់់}

LtBkSlashFill = 6 ;      {\ \ \ }

HatchFill  = 7 ;   {Light Hatch Fill} XHatchFill   = 8 ;     {Heavy cross hatch Fill} InterLeaveFill  = 9 ;      {Interleaving line Fill} WideDotFill  = 10 ;   {widely spaced dot Fill}

CloseDotFill = 11 ;    {Closely Spaced dot Fill} UserFill = 12 ;  {ផាត់តាមពណ៍របស់ User បង្កើត}

Example :

# include<graphics.h>

# include<conio.h>

# include<stdlib.h>

main()

{int gd=0, gm maxx,maxy ;

char pattern[8]={0x00, 0x70, 0x20, 0x27, 0x25, 0x27,0x04,0x04} ;

initgraph(&gd, &gm, “C:\\TC\\BGI”); maxx=getmaxx(); maxy=getmaxy(); setcolor(getmaxcolor()); setfillpattern(pattern, getmaxcolor()); bar(0, 0, maxx, maxy);

getch(); getfillpattern(pattern); pattern[4] -= 1 ; pattern[5] -= 3 ; pattern[6] +=3 ; pattern[7] -= 4 ;

setfillpattern(pattern,getmaxcolor());

bar(0, 0, max, maxy );

getch ();

closegraph();

}

 * floodfill(int X, int Y, int Border) ;

យើងប្រើ function នេះដើម្បីផាត់ពណ៍អោយចតុកោណ, ត្រីកោណ, ពហុកោណ……….,ចំនុច (X,Y) ត្រូវស្ថិត នៅក្នុងផ្ទៃុ នៃ ចតុកោណ។ ពណ៍ដែលផាត់នោះត្រូវបានបង្កើតឡើងដោយ setfillstyle ឬ setfillpattern ។ Border (មានតំលៃពី ០ ដល់ ១៥) ជាពណ៍របស់ជ្រុង ។

បើចំនុច  (X,Y)  ស្ថិតនៅក្នុងផ្ទៃចតុកោណ,  នោះផ្នែកខាងក្នុង ចតុកោណ  ត្រូវបានផាត់ពណ៍  តែបើចំណុច

(X,Y) នៅក្រៅ ចតុកោណវិញនោះគឺផ្នែកខាងក្រៅចតុកោណត្រូវបានផាត់ពណ៍ ។

 * fillpoly(  NumPoints ,  PolyPoints) ;

គូសពហុកោណហើយមានផាត់ពណ៍ផ្នែកខាងក្នុង ។

+ PolyPoints : ជាប៉ារ៉ាមែត្រគ្នានប្រភេទវា ផ្ទុកកូអរដោនេបណ្ដាកំពូលរបស់ពហុកោណ ។

+NumPoints: ប្រាប់ចំនួនកូអរដោនេក្នុង PolyPoints។ (គឺជាចំនួន កំពូលរបស់ពហុកោណ) ។ កូអរដោនេ  មួយ  មាន  តំលៃពីរ  (word  :  តំលៃX  និង  តំលៃY)  ។  FillPoly ផាត់ពណ៍ពហុកោណដោយប្រើ ពណ៍ដែលបង្កើតដោយ SetFillStyle ឬ SetFillPattern ។ ចំនែកជ្រុងរបស់ពហុកោណ, ត្រូវបានគូសជាមួយ ប្រភេទ បន្ទាត់ និង ពណ៍ ដែលបង្កើតឡើងដោយ SetLineStyle ។

 X.  ViewPort : Viewport  ជាតំបន់ចតុកោណកែងមួយនោលើ  Screen  ដែលយើងអាចអនុវត្ដបណ្ដា  Procedure

របស់ Graphic នៅក្នុង នោះ ហាក់បីដូចជា Screen តូចមួយ ។

setviewport (int X1,int Y1,int X2,int Y2, Clip) ;

ជា  Function  កំណត់  ViewPort  មួយនៅលើ  Screen  ជាមួយ  (X1,Y1,X2,Y2) ជាកូអរដោនេរបស់ ViewPort ។ ក្រោយ ពីហៅ esetviewport , កូអរដោនេ (0,0) នៃបណ្ដា Statement គូសនឹង ក្លាយជាមុំកែង ខាងលើ ផ្នែកខាងឆ្វេងរបស់ ViewPort  គឺ (X1,Y1) ។

ប៉ារ៉ាមែត្រ  Clip    អាចមានតំលៃ  True  =    clipon  : អនុញ្ញាតិ អោយមើលឃើញបណ្ដាបន្នាត់ដែលគូសចេញក្រៅ                                            ViewPort  ,   ចំណែក    clipoff នឹងមិនអាចមើលឃើញ បន្នាត់ដែល គូសចេញក្រៅ ViewPort ។

C C++

យើងអាចផ្លាស់ប្ដូរ ViewPort នៅគ្រប់កន្លៃងក្នុងកមμវិធី ដើម្បី បានកូអរដោនេគូស និង តំបន់គូសសមស្រប។

ឧទាហរណ៍គូសក្រាហ្វិចរបស់សមីការដែលមានមុំ កូអរដោនេនៅ កណ្ដាល SCREEN :

setviewport (getmaxx() / 2, getmaxy() / 2, getmaxx(), getmaxy(), 1

) ;

 XI.  បណ្ដាអនុគមន៍ផ្សេងទៀត  ៖

*setlinestyle(int LineStyle,int Pattern,int Thickness);

ជា Function សំរាប់កំនត់រាងអោយបន្ទាត់

* bar3d (int x1, int y1 ,int x2 ,int y2, int depth, top );

ជា Function សំរាប់គូសចតុកោណប៉ោងក្នុងលំហរ ។

XII.  កាត់រូប,   បិទរូប  និង  បង្កើតរូបភាពដែលមានចលនា  ៖

រក្សាទុករូបភាព  ៖

ដើម្បីរក្សាទុករូបភាពណាមួយ, យើងត្រូវប្រើ Block Memory     មួយដែល មានរាងជា ចតុកោណកែងពទ្ធ៍ជុំវិញ រូបភាពនោះ ។ ក្រោយ មកយើងរក្សាផ្ទៃក្រលាចតុកោណកែងនោះ។ដើម្បីគណនាទំហំ Block Memory រាង ចតុកោណ កែងផ្ទុករូបភាពនោះ, យើងប្រើ Function មានស្រាប់ គឺ ៖

+ imagesize(int X1, int  Y1,int  X2 , int  Y2 ) ;

ដើម្បីរ្យេបចំ Memory រក្សាទុករូបភាព,យើងប្រើ Function នេះបង្កើត Dynamic Variable

មិនកំនត់ ប្រភេទ ។

+ getimage(int  X1,int Y1,int  X2, int  Y2 , *PBitMap) ;

ជា Procedure ដើម្បី Copy បណ្ដាចំនុចនៃរូបភាពនៅលើ   Screen ដែលស្ថិតក្នុងចតុកោណ (X1,Y1,X2,Y2) ចូលទៅ ក្នុង Memory ដែលត្រូវ PBitMap ជាអ្នក Index, ដោយប្រើ Procedure GetMem ខាងលើ ។

+ putimage(int X, int Y , *PBitMap , int  CopyMode) ; រំដោះរូបភាពដែលយើងបាន Copy ដោយ GetImage, មកលើ Screen ត្រង់ចំនុច (X,Y)។ ក្នុងនោះ CopyMode ជាប្រភេទ Copy រូបភាពមកលើ Screen :

Copy = 0

XORPut = 1

ORPut = 2

ANDPut = 3

NOTPut = 4

* ដើម្បីបង្កើតរូបភាពមានចលនា ក្នុង GraphMode :

– គូសរូប, Copy រូបនោះចូលទៅក្នុង DynamicVariable :

– បង្កើត (Delay) ។

– លុបរូបនោះ, រំដោះរូបភាពឡើងវិញដោយប្រើ putimage();

–  គូសរូបភាពនៅទីតាំងថ្នី ។

# include<graphics.h>

# include<conio.h>

# include<stdlib.h>

# include<alloc.h>

# include<stdio.h>

void save_screen(void far *buf[4]); void restore_screen(void far *buf[4]); int maxx, maxy ;

int main(void)

{ int gd=DETECT, gm ,errorcode ;

void far *ptr[4];

initgraph(&gd,&gm,”c:\\tc\\bgi”); erorcode = graphresult(); if(errorcode != grOk())

{printf(“ Graphics error : %s\n”,grapherrormsg(errorcode));

printf(“Press any key to halt:“);

getch();

exit(1);

}

maxx=getmaxx(); maxy=getmaxy(); rectangle(0,0,maxx,maxy); line(0,0,maxx,maxy); line(0,maxy,maxx,0); save_screen(ptr);

getch(); cleardevice(); restore_screen(); getch(); closegraph(); return 0;

}

void save_screen(void far *buf[4])

{ unsigned side;

int ystart = 0 ,yend , yincr , block ;

yincr = (maxy+1)/4;

yend = yincr;

size = imagesize(0,ystart,maxx,yend);

for(block=0; block<=3;block++)

{

if ((buf[block]=farmalloc(size))== NULL)

{closegraph();

printf(“Error ! not enough heap space in save_screen()”);

exit(1);

}

getimage(0,ystart,maxx,yend,buf[block]);

ystart = yend + 1;

yend += yincr +1;

}

}

void restore_screen(void far *buf[4])

{

int ystart = 0 , yend, yincr , block;

yincr = (maxy+1)/4;

yend = yincr;

for (block=0;block<=3;block++)

{

putimag(0,ystart,buf[block],COPY_PUT);

farfree(buf[block]);

ystart = yend + 1;

yend +=yincr + 1;

}

}