Mail Archives: djgpp/2002/01/11/01:03:11
"Zenko B. Klapko Jr." <zen1 AT comcast DOT net> wrote in
news:5cp%7.332292$ez DOT 47656452 AT news1 DOT rdc1 DOT nj DOT home DOT com:
> For a week or two I've been trying to get a line to rotate like a
> propeller. I'm using the allegro and math libraries and I"m wondering
> what i'm doing wrong. I felt this would be a proper place for it since
> the programmers here are well educated and show concern for the people
> who post. And I've asked 3 math teachers (2 of which program) for help
> but to no avail. I've even tinkered with the equaitons and created
> really amazing cylinders and other circular based patterns, but I
> really would like a rotating line. Heres the Code and thanks for any
> time spent! -Zen PS. if you have a simpler example that will do.
I don't use allegro. In addition, I am a bit too lazy to try to figure out
what the code below is doing.
However, you should use constants M_PI, M_PI_2, and M_PI_4 defined in
math.h for radian computations rather than your own approximations. Also,
it doesn't look like you are erasing the lines after a short wait (which
is what is needed to give the movement effect).
I put together a quick'n'dirty program which hopefully does something like
what you want. doPropeller is where the relevant work gets done. The rest
is there because I do not have allegro. It probably has a whole bunch of
bugs.
compile it using
gcc -Wall -O proplr.c -o proplr.exe
then run it using
proplr 3, 14, 125
the first parameter is the speed of animation (smaller = faster).
/* === BEGIN: proplr.c === */
#include <dpmi.h>
#include <go32.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/farptr.h>
#include <math.h>
#include <time.h>
#include <pc.h>
/* TODO: I really don't know the list of VGA modes */
typedef unsigned char COLOR;
typedef int VIDEOMODE;
typedef struct
{
int x;
int y;
} POINT;
/* There does not seem to be a sign function in the standard library */
static int sign(int n)
{
static int ret = 0;
if (n != 0) ret = ( (n > 0) ? 1 : -1 );
return ret;
}
VIDEOMODE setVideoMode(VIDEOMODE mode)
{
__dpmi_regs r;
memset(&r, 0, sizeof(r));
r.h.al = mode & 0xff;
return __dpmi_int(0x10, &r) == 0 ? mode : -1;
}
VIDEOMODE getVideoMode(void)
{
__dpmi_regs r;
memset(&r, 0, sizeof(r));
r.h.ah = 0x0f;
__dpmi_int(0x10, &r);
return r.h.al;
}
void pp13(POINT *p, COLOR c)
{
_farpokeb(_dos_ds, 0xa0000 + 320*(p->y) + p->x, c);
return;
}
/* use this version in loops where you are plotting a number
* of pixels in succession. see info libc alpha far*
*/
void nspp13(POINT *p, COLOR c)
{
_farnspokeb(0xa0000 + 320*(p->y) + p->x, c);
return;
}
unsigned char gp13(POINT *p)
{
return _farpeekb(_dos_ds, 0xa0000 + 320*(p->y) + p->x);
}
unsigned char nsgp13(POINT *p)
{
return _farnspeekb(0xa0000 + 320*(p->y) + p->x);
}
void drawVerticalLine(POINT *p, int dy, COLOR c)
{
unsigned short old_sel = _fargetsel();
_farsetsel(_dos_ds);
{
POINT r = { p->x, p->y };
int i, sdy = sign(dy);
for(i = 0; i != dy; i += sdy)
{
r.y = p->y + i;
nspp13(&r, c);
}
}
_farsetsel(old_sel);
return;
}
void drawHorizontalLine(POINT *p, int dx, COLOR c) {
unsigned short old_sel = _fargetsel();
_farsetsel(_dos_ds);
{
POINT r = { p->x, p->y };
int i, sdx = sign(dx);
for( i = 0; i != dx; i += sdx)
{
r.x = p->x + i;
nspp13(&r, c);
}
}
_farsetsel(old_sel);
return;
}
void drawLine(POINT *p1, POINT *p2, COLOR c) {
int dx = p2->x - p1->x;
int dy = p2->y - p1->y;
/* handle vertical line */
if (dx == 0)
{
drawVerticalLine(p1, dy, c);
return;
}
/* handle horizontal line */
if (dy == 0)
{
drawHorizontalLine(p1, dx, c);
return;
}
/* bad bad line drawing algorithm */
{
unsigned short old_sel = _fargetsel();
double m = ((double) dy)/dx;
_farsetsel(_dos_ds);
if (fabs(m) <= 1)
{
POINT r;
int i, sdx = sign(dx);
for (i = 0; i != dx; i += sdx)
{
r.x = p1->x + i;
r.y = (int) (p1->y + m*i);
nspp13(&r, c);
}
}
else
{
POINT r;
int i, sdy = sign(dy);
m = ((double) dx/dy);
for (i = 0; i != dy; i += sdy)
{
r.x = (int)(p1->x + m*i);
r.y = p1->y + i;
nspp13(&r, c);
}
}
_farsetsel(old_sel);
}
return;
}
void drawBox(POINT *b, POINT *e, COLOR c)
{
drawVerticalLine(b, e->y - b->y, c);
drawVerticalLine(e, b->y - e->y, c);
drawHorizontalLine(b, e->x - b->x, c);
drawHorizontalLine(e, b->x - e->x, c);
return;
}
void drawFilledBox(POINT *b, POINT *e, COLOR c)
{
int dx = e->x - b->x;
int dy = e->y - b->y;
if (abs(dx) > abs(dy))
{
POINT p = { b->x, b->y };
int i, sdy = sign(dy);
for (i=0; i != dy; i += sdy)
{
p.y = b->y + i;
drawHorizontalLine(&p, dx, c);
}
}
else
{
POINT p = { b->x, b->y };
int i, sdx = sign(dx);
for (i=0; i != dx; i += sdx)
{
p.x = b->x + i;
drawVerticalLine(&p, dy, c);
}
}
return;
}
void setBackgroundColor(COLOR c)
{
POINT b = { 0, 0 };
POINT e = { 320, 200};
drawFilledBox(&b, &e, c);
return;
}
void doPropeller(int speed, COLOR fg, COLOR bg)
{
#define NUM_POINTS 48
static POINT begin[NUM_POINTS];
static POINT end[NUM_POINTS];
static const int LENGTH = 80;
static const int X_CENTER = 160;
static const int Y_CENTER = 100;
static char INIT_DONE = 0;
if (!INIT_DONE)
{
int i;
const double STEP_ANGLE = M_PI/NUM_POINTS;
begin[0].x = X_CENTER + LENGTH;
begin[0].y = Y_CENTER;
end[0].x = X_CENTER - LENGTH;
end[0].y = Y_CENTER;
for (i=1; i<NUM_POINTS; ++i)
{
begin[i].x = X_CENTER + (int)
(LENGTH*cos(i*STEP_ANGLE));
begin[i].y = Y_CENTER + (int)
(LENGTH*sin(i*STEP_ANGLE));
end[i].x = X_CENTER - (int)
(LENGTH*cos(i*STEP_ANGLE));
end[i].y = Y_CENTER - (int)
(LENGTH*sin(i*STEP_ANGLE));
}
INIT_DONE=1;
}
while (!kbhit())
{
int i;
unsigned long rawticks;
for (i=0; i<NUM_POINTS; ++i)
{
if (kbhit()) break;
drawLine(&begin[i], &end[i], fg);
rawticks = rawclock() + speed;
while(rawclock() < rawticks)
__dpmi_yield();
drawLine(&begin[i], &end[i], bg);
}
}
return;
}
/* test */
int main(int argc, char *argv[]) {
int speed = 3;
COLOR fg = 15;
COLOR bg = 0;
int old_mode;
if (argv[1]) speed = atoi(argv[1]);
if (argv[2]) fg = atoi(argv[2]);
if (argv[3]) bg = atoi(argv[3]);
{
old_mode = getVideoMode();
fprintf(stderr, "Current mode: %2.2x\n", old_mode);
if ( 0x13 != setVideoMode(0x13) )
{
setVideoMode(old_mode);
fprintf(stderr, "Could not set graphics mode:
%2.2x\n", 0x13);
exit(1);
}
}
setBackgroundColor(bg);
doPropeller(speed, fg, bg);
setVideoMode(old_mode);
return 0;
}
/* === END: proplr.c === */
--
--------------------------------
A. Sinan Unur
http://www.unur.com/
- Raw text -