|
-
review my code for plotting a horizontal line
Hello all,
I am trying to find the longest horizontal line on a screen. I have written the following code(using Alex Russell's Dos Game Programming in C for Beginners ) and making changes so as to work with Windows XP.
I have added the getLine() method which is supposed to give me longest horizontal line starting address (*linep) and its length(line_length), as well as the initial coordiantes(lx, ly). The program compiles, but when run locks my system. I am using Turbo C++ 3.0 compiler. Can you suggest any ways to change the code, so that it works correctly.
Here is the complete code (with some irrelevant methods, which you can ignore):
=================================================
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#include <dos.h>
#define ESC 27
#define INPUT_STATUS_0 0x3da
unsigned char far *screen; // pointer to the vga video memory
unsigned char far *off_screen; // pointer to our off screen buffer
int screen_width, screen_height;
unsigned int screen_size;
int lx, ly, line_length;
unsigned char far *linep;//pointer to the start of a line
void enter_mode13h(void)
{
_AX = 0x0013;
geninterrupt (0x10);
}
void leave_mode13h(void)
{
_AX = 0x0003;
geninterrupt (0x10);
}
int init_video_mode(void)
{
off_screen=farmalloc(64000u);
if ( off_screen )
{
screen=MK_FP(0xa000, 0);
screen_width=320;
screen_height=200;
screen_size=64000u;
enter_mode13h();
_fmemset(off_screen, 0, screen_size);
return 0;
}
else
{
// no mem! Return error code!
leave_mode13h();
printf("Out of mem!\n");
return 1;
}
}
// copy the off screen buffer to video memory
void update_buffer(void)
{
// wait for vertical re-trace
while ( inportb(INPUT_STATUS_0) & 8 )
;
while ( !(inportb(INPUT_STATUS_0) & 8) )
;
// copy everything to video memory
_fmemcpy(screen, off_screen, screen_size);
}
void draw_pixel(int x, int y, int colour)
{
*(off_screen + y*screen_width + x)=colour;
}
int get_pixel(int x, int y)
{
return *(off_screen + y*screen_width + x);
}
void getLine(int colour){
int x, y, helplen;
line_length = 0;
helplen=0;
for(y=0; y < screen_size-1; y++){
for(x=0; x < screen_size-1; x++){
if(colour == *(screen + y*screen_width + x))
{
helplen++;
}
else
{
if(helplen > line_length)
{
if(!(helplen==0))
{
linep = screen + y*screen_width + x;//start address of the longest line
lx=x;
ly=y;
}
line_length = helplen;
helplen = 0;
}
}
}
}
}
void horz_line(int x, int y, int len, int colour)
{
unsigned char far *p;
p=off_screen + y*screen_width +x; // make p point to the start of the line
_fmemset(p, colour, len); // fill in the line
}
void vert_line(int x, int y, int len, int colour)
{
unsigned char far *p;
p=off_screen + y*screen_width +x; // make p point to the start of the line
while ( len--) // repeat for entire line length
{
*p=colour; // set one pixel
p+=screen_width; // move down one row
}
}
/*
Bresenham's line algorithm.
*/
void line(int x0, int y0, int x1, int y1, int colour)
{
int inc1, inc2, i;
int cnt, y_adj, dy, dx, x_adj;
unsigned char far *p;
if ( x0 == x1 )
{
// vertical line
if ( y0 > y1 )
{
i=y0;
y0=y1;
y1=i;
}
p=off_screen + y0*screen_width + x0;
i=y1 - y0 + 1;
while ( i-- )
{
*p=colour;
p+=screen_width;
}
}
else
{
if ( y0 == y1 )
{
// horizontal line
if ( x0 > x1 )
{
i=x0;
x0=x1;
x1=i;
}
p=off_screen + y0*screen_width + x0;
i=x1 - x0 + 1;
_fmemset(p, colour, i);
}
else
{
// general line --------------------------------------
dy=y1 - y0; // dy is increment
dx=x1 - x0; // dx is line length
// is it a shallow, or steep line?
if ( abs(dy) < abs(dx) )
{
// lo slope
// we always want to draw from left to right
if ( x0 > x1 )
{
// swap x's, and y's
i=x0;
x0=x1;
x1=i;
i=y0;
y0=y1;
y1=i;
}
dy=y1 - y0; // dy is used to calulate the increments
dx=x1 - x0; // dx is line length
if ( dy < 0 )
{
// going up the screen
dy=-dy;
y_adj=-screen_width;
}
else
y_adj=screen_width; // and down
// calulate the increments
inc1=dy<<1;
inc2=(dy - dx)<<1;
cnt=(dy<<1) - dx;
// set p to start pixel
p=off_screen + y0*screen_width + x0;
dx++;
while ( dx-- ) // for the length of the line
{
*p++=colour; // set one pixel, move right one pixel
if ( cnt >= 0 ) // is it time to adjust y?
{
cnt+=inc2;
p+=y_adj;
}
else
cnt+=inc1;
}
}
else
{
// hi slope - like lo slope turned on its side
// always draw top to bottom
if ( y0 > y1 )
{
// swap x's, and y's
i=x0;
x0=x1;
x1=i;
i=y0;
y0=y1;
y1=i;
}
dy=y1 - y0; // dy is line length
dx=x1 - x0; // dx is used to calculate incr's
if ( dx < 0)
{
dx=-dx;
x_adj=-1; // moving left
}
else
x_adj=1; // moving right
inc1=dx<<1;
inc2=(dx - dy)<<1;
cnt=(dx<<1) - dy;
// set p to first pixel position
p=off_screen + y0*screen_width + x0;
dy++;
while ( dy-- ) // for height of line
{
*p=colour; // set one pixel
p+=screen_width; // move down one pixel
if ( cnt >= 0 ) // is it time to move x?
{
cnt+=inc2;
p+=x_adj;
}
else
cnt+=inc1;
}
}
}
}
}
int get_key(void)
{
int a;
a=getch();
if ( a == ESC )
{
farfree(off_screen);
leave_mode13h();
exit(1);
}
return a;
}
void main(void)
{
int x,y, width, height;
int i, x1, y1;
printf("Test code\n");
get_key();
init_video_mode();
// draw horz line
_fmemset(off_screen, 0, screen_size); // blank the screen
for ( i=0; i < 50; i++ )
{
x=random(screen_width - 20) + 10;
y=random(screen_height - 20) + 10;
width=random(screen_width);
if ( width + x >= screen_width )
width=screen_width - x - 1;
horz_line(x,y, width, 80);
}
update_buffer();
get_key();
//getLine(80);
printf("Longest horizonal line is:\n");
printf("length: %d\n",line_length);
printf("start address: %d\n",linep);
printf("coordinates: x - %d, y - %d\n",lx, ly);
get_key();
// draw vert lines
_fmemset(off_screen, 0, screen_size); // blank the screen
for ( i=0; i < 50; i++ )
{
x=random(screen_width - 20) + 10;
y=random(screen_height - 20) + 10;
height=random(screen_height);
if ( height + y >= screen_height )
height=screen_height - y - 1;
vert_line(x,y, width, 80);
}
update_buffer();
get_key();
// draw random lines
_fmemset(off_screen, 0, screen_size); // blank the screen
for ( i=0; i < 5; i++ )
{
x=random(screen_width - 20) + 10;
y=random(screen_height - 20) + 10;
height=random(screen_height);
if ( height + y >= screen_height )
height=screen_height - y - 1;
width=random(screen_width);
if ( width + x >= screen_width )
width=screen_width - x - 1;
x1=x + width - 1;
y1=y + height - 1;
line(x, y, x1, y1, 80);
}
update_buffer();
get_key();
leave_mode13h();
farfree(off_screen);
}
==================================
Thanks a lot,
Amrita
Similar Threads
-
By Chaitanya Marvici in forum ASP.NET
Replies: 6
Last Post: 07-21-2003, 09:15 AM
-
Replies: 246
Last Post: 10-26-2002, 12:30 AM
-
By Al Guten in forum .NET
Replies: 0
Last Post: 04-11-2002, 06:48 PM
-
By michael s in forum XML
Replies: 0
Last Post: 04-03-2001, 04:32 PM
-
By Robert G in forum .NET
Replies: 84
Last Post: 02-08-2001, 02:38 PM
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
Forum Rules
|
Top DevX Stories
Easy Web Services with SQL Server 2005 HTTP Endpoints
JavaOne 2005: Java Platform Roadmap Focuses on Ease of Development, Sun Focuses on the "Free" in F.O.S.S.
Wed Yourself to UML with the Power of Associations
Microsoft to Add AJAX Capabilities to ASP.NET
IBM's Cloudscape Versus MySQL
|
Bookmarks