[comp.sys.cbm] C-Power bug ???

aig@i.cc.purdue.edu (Doug Crabill) (12/08/86)

	I am writing a game in C-Power (please hold all applause until the end
of the article) and have run into a bit of a problem.  I can't be sure if it is
a problem with the way I have the code set up or if it is a problem with
C-Power.  I figured I would post what I have in hopes that some kind soul out 
there could spot a problem.  I know there are other ways to write this bit of 
code, but I really want to know why it doesn't work as it is.


--------------------------------This is it-------------------------------------
/*
   This program checks joyport 1 and updates a sprite on the screen according
   to the direction of the joystick.  Real simple right?
*/

#include <stdio.h>
main()
{
	struct tank {
		char *x;	/* x coordinate		*/
		char *y;	/* y coordinate		*/
		float a;	/* doesn't matter here  */
		char *sp;	/* sprite image pointer */
	};
	char *joy1;	/* joyport location */
	char j; 	/* temporary copy of *joy1 */
	char *enable;	/* sprite enable location  */
	struct tank *pl1;	/* the sprite used in this program */
	pl1->x = 53248;  *pl1->x = 30;
	pl1->y = 53249;  *pl1->y = 100;
	pl1->a = 0.0;
	pl1->sp = 2040;  *pl1->sp = 192;  /* set the sprite pointer */
	joy1 = 56320; 	/* set joyport location */
	enable = 53269; /* set sprite enable location */
	*enable = 1;	/* enable sprite 1 */

	/* set up an infinite game loop */
	for (;;) {
		/* 
		   what happens here is that the sprite will not move unless
		   the joystick is pushed up (the first case) and when this
		   happens, ALL of the ifs below are executed, so the sprite
		   goes up, down, left, right (sounds like aerobics eh?)
		   I've printed out j as I go and it is as it should be.
		*/

		j = 15 - (*joy & 15);
		if ((j&1 == 1) && ((*pl1->y) > 50)) (*pl1->y)--;  /* up    */
		if ((j&2 == 2) && ((*pl1->y) < 226)) (*pl1->y)++; /* down  */
		if ((j&4 == 4) && ((*pl1->x) > 24)) (*pl1->x)--;  /* left  */
		if ((j&8 == 8) && ((*pl1->x) < 250)) (*pl1->x)++; /* right */
	}
}

aig@i.cc.purdue.edu (Doug Crabill) (12/08/86)

	I found my own error when I looked over the program last night.  It
seems I forgot that binary operations have low precedence and should be
parenthesied! <blush>.


						Doug Crabill
						aig@i

ark@alice.UUCP (12/08/86)

In article <1688@i.cc.purdue.edu>, aig@i.cc.purdue.edu.UUCP writes:
> 
> 	I am writing a game in C-Power (please hold all applause until the end
> of the article) and have run into a bit of a problem.

The example given includes the following code:

> 		if ((j&1 == 1) && ((*pl1->y) > 50)) (*pl1->y)--;  /* up    */
> 		if ((j&2 == 2) && ((*pl1->y) < 226)) (*pl1->y)++; /* down  */
> 		if ((j&4 == 4) && ((*pl1->x) > 24)) (*pl1->x)--;  /* left  */
> 		if ((j&8 == 8) && ((*pl1->x) < 250)) (*pl1->x)++; /* right */

The trouble with this code is that the expression

		j&1 == 1

doesn't do what you think, because == binds more tightly than &.
Thus, this is equivalent to

		j&(1 == 1)

which, unfortunately, has the same effect for the wrong reason.
The trouble is that we have actually written

		j&1

because 1==1 evaluates to 1, so when we write

		j&2 == 2

we have actually written EXACTLY THE SAME THING.  No wonder
the results are confusing!  Might I suggest a rewrite:

	if ((j&1) && *pl1->y > 50) --*pl1->y;  /* up    */
	if ((j&2) && *pl1->y < 226) ++*pl1->y; /* down  */
	if ((j&4) && *pl1->x > 24) --*pl1->x;  /* left  */
	if ((j&8) && *pl1->x < 250) ++*pl1->x; /* right */

rayz@csustan.UUCP (R. L. Zarling) (12/08/86)

In article <1688@i.cc.purdue.edu> aig@i.cc.purdue.edu (Doug Crabill) writes:
>
>	I am writing a game in C-Power (please hold all applause until the end
>of the article) and have run into a bit of a problem.
> ...
>	joy1 = 56320; 	/* set joyport location */
> ...
>		j = 15 - (*joy & 15);

Just guessing, but I noticed you have not set any bank number (i.e. memory
configuration).  Your references *pointer could be hitting either bank0 ram,
bank1 ram, i/o devices, etc.  My guess is that C-Power, by default, hits some
kind of RAM; thus, your reference to *joy is not reading an i/o device at all.
Using the supplied peek() and poke() gives you the option of specifying a
bank number to control this.  By the way, there was some discussion that
either peek() or poke(), as supplied, may be buggy.  In any case, there is
a revised version on the C-Power bbs.

mcewan@uiucdcsb.UUCP (12/09/86)

There's another, potentially much more troublesome, error that no one seems
to have noticed:

	struct tank *pl1;	/* the sprite used in this program */
	pl1->x = 53248;  *pl1->x = 30;

Pointer pl1 isn't initialized; you need to do a malloc. The results of the
above code will be totally unpredictable. It could overwrite the running
code and cause a crash in some other routine. It may not cause any problem
at all. Since it depends on what junk is sitting in memory when the program
is run, you could get different results when you run the program different
times.

		Scott McEwan
		{ihnp4,pur-ee}!uiucdcs!mcewan

"Sheep abusers really get my goat."