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