Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

lafore_robert_objectoriented_programming_in_c

.pdf
Скачиваний:
51
Добавлен:
27.03.2023
Размер:
8.94 Mб
Скачать

Console Graphics Lite

idea was to create the minimum routines that would do the job. You can examine the source files at the end of this appendix if you’re curious.

Microsoft Compilers

The Microsoft compilers no longer include their own console graphics routines as they did several years ago. However, Windows itself provides a set of routines for simple console graphics operations, such as positioning the cursor and changing the text color. For the Microsoft compilers, the Console Graphics Lite functions access these built-in Windows console functions. (Thanks to André LaMothe for suggesting this solution. His excellent game book is listed in Appendix H, “Bibliography.”)

To use the console graphics functions you should use a project of type “Win32 Console Application,” as described in Appendix C.

The Windows console functions won’t work unless you initialize the console graphics system, so calling the init_graphics() function is essential if you’re using the Microsoft compiler.

Borland Compilers

Borland C++ still has built-in graphics functions, both for console-mode graphics and for pixel graphics. If you use the BORLACON.CPP file, the Console Graphics Lite functions are translated into Borland console functions, which they closely resemble.

You might wonder why you can’t use the Borland compiler to access the console functions built into Windows. The problem is that to create a console-mode program in Borland C++, you must use either an EasyWin or a DOS target, both of which are 16-bit systems. The Windows console functions are 32-bit functions, and so can’t be used in Borland’s console mode.

When you use Borland C++, the iostream approach to I/O (cout <<) doesn’t produce different colors. Thus some of the example programs, like HORSE.CPP, use console-mode functions such as cputs() and putch(), found in the CONIO.H file.

Source Code Listings

Here are the listings for the four files used in Console Graphics Lite: MSOFTCON.H and MSOFTCON.CPP for Microsoft, and BORLACON.H and BORLACON.CPP for C++Builder. Normally there won’t be any reason for you to worry about the internals of these files. They are shown here for reference.

885

E

GRAPHICS C

L ONSOLE

ITE

Appendix E

886

Listing for MSOFTCON.H

//msoftcon.h

//declarations for Lafore’s console graphics functions //uses Window’s console functions

#ifndef

_INC_WCONSOLE

//don’t

let this file be included

#define

_INC_WCONSOLE

//twice

in

the

same source file

#include <windows.h>

//for Windows console functions

#include

<conio.h>

//for kbhit(),

getche()

#include

<math.h>

//for sin,

cos

 

enum fstyle { SOLID_FILL, X_FILL,

O_FILL,

 

LIGHT_FILL, MEDIUM_FILL, DARK_FILL

};

enum color {

 

 

 

cBLACK=0,

cDARK_BLUE=1,

cDARK_GREEN=2,

cDARK_CYAN=3,

cDARK_RED=4,

cDARK_MAGENTA=5,

cBROWN=6,

cLIGHT_GRAY=7,

cDARK_GRAY=8,

cBLUE=9,

cGREEN=10,

cCYAN=11,

cRED=12,

cMAGENTA=13,

cYELLOW=14,

cWHITE=15 };

//--------------------------------------------------------------

 

 

 

void init_graphics();

void set_color(color fg, color bg = cBLACK); void set_cursor_pos(int x, int y);

void clear_screen();

void wait(int milliseconds); void clear_line();

void draw_rectangle(int left, int top, int right, int bottom); void draw_circle(int x, int y, int rad);

void draw_line(int x1, int y1, int x2, int y2); void draw_pyramid(int x1, int y1, int height); void set_fill_style(fstyle);

#endif /* _INC_WCONSOLE */

Listing for MSOFTCON.CPP

//msoftcon.cpp

//provides routines to access Windows console functions

//compiler needs to be able to find this file

//in MCV++, /Tools/Options/Directories/Include/type path name

#include “msoftcon.h”

 

 

HANDLE hConsole;

//console handle

 

char fill_char;

//character used

for fill

//--------------------------------------------------------------

 

 

Console Graphics Lite

void

init_graphics()

 

{

 

 

 

COORD console_size =

{80, 25};

//open i/o channel to console screen

hConsole = CreateFile(“CONOUT$”, GENERIC_WRITE | GENERIC_READ,

 

 

FILE_SHARE_READ | FILE_SHARE_WRITE,

 

 

0L, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0L);

//set to 80x25 screen size

SetConsoleScreenBufferSize(hConsole, console_size);

//set text to white on black

SetConsoleTextAttribute( hConsole, (WORD)((0 << 4) | 15) );

fill_char = ‘\xDB’;

//default fill is solid block

clear_screen();

 

 

}

 

 

 

//--------------------------------------------------------------

 

 

 

void

set_color(color foreground, color background)

{

 

 

 

SetConsoleTextAttribute( hConsole,

 

 

 

(WORD)((background << 4) | foreground) );

}

//end setcolor()

 

/* 0

Black

8

Dark gray

1

Dark blue

9

Blue

2

Dark green

10

Green

3

Dark cyan

11

Cyan

4

Dark red

12

Red

5

Dark magenta

13

Magenta

6

Brown

14

Yellow

7

Light gray

15

White

*/

 

 

 

//--------------------------------------------------------------

 

 

 

void

set_cursor_pos(int

x, int y)

{

 

 

 

COORD cursor_pos;

//origin in upper

left corner

cursor_pos.X

=

x

- 1;

//Windows starts at (0, 0)

cursor_pos.Y

=

y

- 1;

//we start at (1,

1)

SetConsoleCursorPosition(hConsole, cursor_pos);

}

//--------------------------------------------------------------

void clear_screen()

{

set_cursor_pos(1, 25); for(int j=0; j<25; j++)

putch(‘\n’); set_cursor_pos(1, 1);

}

887

E

GRAPHICS C

L ONSOLE

ITE

888

Appendix E

 

//--------------------------------------------------------------

 

 

 

 

 

void wait(int milliseconds)

 

 

 

{

 

 

 

 

 

Sleep(milliseconds);

 

 

 

}

 

 

 

 

 

//--------------------------------------------------------------

 

 

 

 

 

void clear_line()

 

 

//clear to end of line

{

 

 

 

//80 spaces

 

//.....

1234567890123456789012345678901234567890

//.....

0........

1.........

2

.........3.........

4

cputs(“

 

 

 

 

“);

cputs(“

 

 

 

 

“);

}

 

 

 

 

 

//--------------------------------------------------------------

 

 

 

 

 

void draw_rectangle(int left, int top, int right, int bottom)

{

char temp[80];

int width = right - left + 1;

for(int j=0; j<width; j++)

//string of squares

temp[j] = fill_char;

 

temp[j] = 0;

//null

for(int y=top; y<=bottom; y++)

//stack of strings

{

 

set_cursor_pos(left, y);

 

cputs(temp);

 

}

 

}

 

//--------------------------------------------------------------

 

void draw_circle(int xC, int yC, int radius)

{

double theta, increment, xF, pi=3.14159; int x, xN, yN;

increment = 0.8 / static_cast<double>(radius);

for(theta=0; theta<=pi/2; theta+=increment) //quarter circle

{

xF = radius * cos(theta);

xN = static_cast<int>(xF * 2 / 1); //pixels not square

yN = static_cast<int>(radius * sin(theta) + 0.5);

 

x = xC-xN;

 

 

while(x <= xC+xN)

//fill two horizontal lines

{

//one for each half circle

set_cursor_pos(x,

yC-yN); putch(fill_char);

//top

set_cursor_pos(x++, yC+yN); putch(fill_char);

//bottom

}

 

 

Console Graphics Lite

}//end for

}

//--------------------------------------------------------------

void draw_line(int x1, int y1, int x2, int y2)

{

int w, z, t, w1, w2, z1, z2;

double xDelta=x1-x2, yDelta=y1-y2, slope; bool isMoreHoriz;

if( fabs(xDelta) > fabs(yDelta) ) //more horizontal

{

 

 

isMoreHoriz = true;

 

 

slope = yDelta / xDelta;

 

 

w1=x1; z1=y1; w2=x2, z2=y2;

//w=x, z=y

}

 

 

else

//more vertical

{

 

 

isMoreHoriz = false;

 

 

slope = xDelta / yDelta;

 

 

w1=y1; z1=x1; w2=y2, z2=x2;

//w=y, z=x

}

 

 

if(w1 > w2)

//if backwards w

{

 

 

t=w1; w1=w2; w2=t;

//

swap (w1,z1)

t=z1; z1=z2; z2=t;

//

with (w2,z2)

}

 

 

for(w=w1; w<=w2; w++)

 

 

{

 

 

z = static_cast<int>(z1 + slope * (w-w1));

if( !(w==80 && z==25) )

//avoid scroll at 80,25

{

 

 

if(isMoreHoriz)

 

 

set_cursor_pos(w, z); else

set_cursor_pos(z, w); putch(fill_char);

}

}

}

//--------------------------------------------------------------

void draw_pyramid(int x1, int y1, int height)

{

int x, y;

for(y=y1; y<y1+height; y++)

{

889

E

GRAPHICS C

L ONSOLE

ITE

890

Appendix E

 

int incr = y - y1;

 

 

for(x=x1-incr; x<=x1+incr; x++)

 

{

 

 

 

set_cursor_pos(x, y);

 

putch(fill_char);

 

}

 

 

 

}

 

 

 

}

 

 

 

//--------------------------------------------------------------

 

 

 

void set_fill_style(fstyle fs)

 

{

 

 

 

switch(fs)

 

 

{

 

 

 

case

SOLID_FILL:

fill_char = ‘\xDB’; break;

case

DARK_FILL:

fill_char = ‘\xB0’; break;

case

MEDIUM_FILL:

fill_char = ‘\xB1’; break;

case

LIGHT_FILL:

fill_char = ‘\xB2’;

break;

case

X_FILL:

fill_char = ‘X’;

break;

case

O_FILL:

fill_char = ‘O’;

break;

}

 

 

 

}

 

 

 

//--------------------------------------------------------------

 

 

 

Listing for BORLACON.H

//borlacon.h

//declarations for Console Graphics Lite functions //uses Borland’s console functions

#ifndef _INC_WCONSOLE //don’t let this file be included #define _INC_WCONSOLE //twice in the same source file

#include <windows.h>

//for Sleep()

#include

<conio.h>

//for

kbhit(), getche()

#include

<math.h>

//for

sin, cos

enum fstyle { SOLID_FILL, X_FILL, O_FILL,

 

LIGHT_FILL, MEDIUM_FILL, DARK_FILL

};

enum color {

 

 

 

cBLACK=0,

cDARK_BLUE=1,

cDARK_GREEN=2,

cDARK_CYAN=3,

cDARK_RED=4,

cDARK_MAGENTA=5,

cBROWN=6,

cLIGHT_GRAY=7,

cDARK_GRAY=8,

cBLUE=9,

cGREEN=10,

cCYAN=11,

cRED=12,

cMAGENTA=13,

cYELLOW=14,

cWHITE=15 };

//--------------------------------------------------------------

 

 

 

void init_graphics();

void set_color(color fg, color bg = cBLACK); void set_cursor_pos(int x, int y);

Console Graphics Lite

void clear_screen();

void wait(int milliseconds); void clear_line();

void draw_rectangle(int left, int top, int right, int bottom); void draw_circle(int x, int y, int rad);

void draw_line(int x1, int y1, int x2, int y2); void draw_pyramid(int x1, int y1, int height); void set_fill_style(fstyle);

#endif // _INC_WCONSOLE

Listing for BORLACON.CPP

//borlacon.cpp

//provides drawing routines for Borland console functions #include “borlaCon.h”

char

fill_char;

//character used for fill

//--------------------------------------------------------------

 

 

void

init_graphics()

 

{

 

 

textcolor(WHITE);

//text to white on black

textbackground(BLACK);

 

fill_char = ‘\xDB’;

// default fill is solid block

clrscr();

 

}

 

 

//--------------------------------------------------------------

 

 

void

set_color(color foreground, color background)

{

 

 

textcolor( static_cast<int>(foreground) );

textbackground( static_cast<int>(background) );

}

 

 

//--------------------------------------------------------------

 

 

void

set_cursor_pos(int x, int y)

{

 

 

gotoxy(x, y);

 

}

 

 

//--------------------------------------------------------------

 

 

void

clear_screen()

 

{

 

 

clrscr();

 

}

 

 

//--------------------------------------------------------------

 

 

void

wait(int milliseconds)

 

{

 

 

Sleep(milliseconds);

}

//--------------------------------------------------------------

891

E

GRAPHICS C

L ONSOLE

ITE

892

Appendix E

 

void clear_line()

 

 

// clear to end of line

{

 

 

 

// 80 spaces

 

//

.....1234567890123456789012345678901234567890

//.....

0........

1.........

2

.........3.........

4

cputs(“

 

 

 

“);

cputs(“

 

 

 

“);

}

//end clreol()

 

 

 

//--------------------------------------------------------------

 

 

 

 

 

void draw_rectangle(int left, int top, int right, int bottom)

{

int j;

char temp[80];

int width = right - left + 1;

for(j=0; j<width; j++)

//string of squares

temp[j] = fill_char;

 

temp[j] = 0;

//null

for(int y=top; y<=bottom; y++)

//stack of strings

{

 

set_cursor_pos(left, y);

 

cputs(temp);

 

}

 

} //end rectangle

 

//--------------------------------------------------------------

 

void draw_circle(int xC, int yC, int radius)

{

double theta, increment, xF, pi=3.14159; int x, xN, yN;

increment = 0.8 / static_cast<double>(radius);

for(theta=0; theta<=pi/2; theta+=increment) //quarter circle

{

 

 

 

xF

= radius * cos(theta);

 

xN

= static_cast<int>(xF * 2 / 1); // pixels not square

yN

= static_cast<int>(radius * sin(theta) + 0.5);

 

x = xC-xN;

 

 

while(x <= xC+xN)

//fill two horizontal lines

 

{

//one for each half circle

 

set_cursor_pos(x,

yC-yN); putch(fill_char);

//top

 

set_cursor_pos(x++, yC+yN); putch(fill_char);

//bottom

 

}

 

 

}

//end for

 

 

} //end circle() //--------------------------------------------------------------

void draw_line(int x1, int y1, int x2, int y2)

{

int w, z, t, w1, w2, z1, z2;

double xDelta=x1-x2, yDelta=y1-y2, slope; bool isMoreHoriz;

if( fabs(xDelta) > fabs(yDelta) ) //more horizontal

{

 

 

isMoreHoriz = true;

 

 

slope = yDelta / xDelta;

 

 

w1=x1; z1=y1; w2=x2, z2=y2;

//w=x, z=y

}

 

 

else

//more vertical

{

 

 

isMoreHoriz = false;

 

 

slope = xDelta / yDelta;

 

 

w1=y1; z1=x1; w2=y2, z2=x2;

//w=y, z=x

}

 

 

if(w1 > w2)

//if backwards w

{

 

 

t=w1; w1=w2; w2=t;

//

swap (w1,z1)

t=z1; z1=z2; z2=t;

//

with (w2,z2)

}

 

 

for(w=w1; w<=w2; w++)

 

 

{

 

 

z = static_cast<int>(z1 + slope * (w-w1));

if( !(w==80 && z==25) )

//avoid scroll at 80,25

{

 

 

if(isMoreHoriz)

 

 

set_cursor_pos(w, z);

 

 

else

 

 

set_cursor_pos(z, w);

 

 

putch(fill_char);

 

 

}

}

Console Graphics Lite

893

E

GRAPHICS C

L ONSOLE

ITE

}

//--------------------------------------------------------------

void draw_pyramid(int x1, int y1, int height)

{

int x, y;

for(y=y1; y<y1+height; y++)

{

int incr = y - y1; for(x=x1-incr; x<=x1+incr; x++)

{

894

Appendix E

 

set_cursor_pos(x, y);

 

putch(fill_char);

 

}

 

 

}

 

 

}

 

 

//--------------------------------------------------------------

 

 

void set_fill_style(fstyle fs)

 

{

 

 

switch(fs)

 

 

{

 

 

case SOLID_FILL:

fill_char = ‘\xDB’; break;

case DARK_FILL:

fill_char = ‘\xB0’; break;

case MEDIUM_FILL:

fill_char = ‘\xB1’; break;

case LIGHT_FILL:

fill_char = ‘\xB2’;

break;

case X_FILL:

fill_char = ‘X’;

break;

case O_FILL:

fill_char = ‘O’;

break;

}

 

 

}

 

 

//--------------------------------------------------------------