/*
 * motor - balls will attempt to catch up with the user's mouse
 *
 */

#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <rtos.h>
#include "mouse.h"

#define MAXBALLS 10

#define MAXX 80
#define MAXY 25

typedef struct {
    BYTE color;
    WORD x, y;
} ball_str;

ball_str balls[ MAXBALLS ];
int idealx = 0, idealy = 0;

void put_on_screen( int x, int y, WORD ch, WORD opt_attr )
{
    static WORD far *screen = 0xb8000000;
    WORD ofs;
    ofs = y * 80 + x;
    screen[ ofs ] = (WORD)ch | ((WORD)opt_attr)<<8;
}


void ball( DWORD num )
{
    ball_str *b;
    int tempx, tempy;

    b = &balls[ num ];
    b->color = (num % 7) + 9;
    b->x = MAXX / 2;
    b->y = MAXY / 2;

    do {
        /* get new locaton */
        tempx = b->x;
        if ( tempx < idealx ) tempx++;
        else if ( tempx > idealx ) tempx--;

        tempy = b->y;
        if ( tempy < idealy ) tempy++;
        else if ( tempy > idealy ) tempy--;

        /* erase old and accept new */
        if ( (b->y != tempy ) || (b->x != tempx )) {
            put_on_screen( b->x, b->y, ' ', 0 );
            b->x = tempx;
            b->y = tempy;
        }

        /* draw the ball */
        put_on_screen( b->x, b->y, 9, b->color );
        rt_sleep( 30 * num );
    } while ( 1 );
}

void mouse_thread( DWORD dummy )
{
    int x, y, buttons;

    do {
        mouse_posn( &x, &y, &buttons );
        idealx = x / 8;
        idealy = y / 8;
        rt_sleep( 10 );
    } while ( 1 );
}
main(int argc, char **argv )
{
    int temp, max;
    DWORD dummy;
    char buf[128];

    rt_init( 100 );

    max = 10;
    rt_timerfreq( 100 );

    if ( mouse_init() == 0 )
        rt_halt( "you need a mouse attached and the mouse driver loaded\r\n");


    mouse_show( 1 );
    clrscr();
    cputs("move your mouse and the balls will follow it at varying speeds\r\n");
    rt_newthread( &mouse_thread, 0, 1024, 0, "the mouse");

    for ( temp = 0 ; temp < max; ++temp )
        rt_newthread( &ball, temp, 1024, 0, "a ball");

    while ( 1 ) {
        if ( kbhit() ) break;
        rt_sleep( 1000 );
    }
    /* clean up */
    mouse_show( 0 );
}

 
