Previous: Oh no, not another Learning Experience!
Next: Finally some example code!
Z88dk and C gotchas - episode 1
Posted by Chief Experimenter in Code, Journal, Problems at 9:38 pm on November 27, 2006.
Still working on experimental stuff (partly to get the hang of Z88dk, and partly to scrape the rust off my underutilized C-coding “skillz” before doing anything important), I got stung by a nasty little gotcha.
I created a source file, 2player.c, which is expanding on the first bit of z88dk/Spritepack 3 code I wrote, to have two graphics on screen, both player controllable.
Every build attempt met with this error:
1 errors occurred during assembly
Errors in source file 2player.c:
File '/tmp/tmpXXTIgPHd.opt', at line 10, Illegal identifier
make: *** [2player] Error 1
Ouch. Where’s the error? Line 10 is in the middle of my descriptive comment section! This is meaningless!! Eventually I stripped out just about everything to the point where it couldn’t possibly NOT compile and…still the same error! WTF?
Then it occurred to me: somewhere in the build process, perhaps the filename is being used as an identifier. And perhaps identifiers starting with a number are illegal. A quick rollback to the proper code I’d written first time around (Vim 7 undo rocks!), rename to twoplayer.c and the bugger builds first time.
Attempting to run the thing resulted in a spectacular crash, but at least it built! Now for some trial and error debugging (my kingdom for a z88dk equivalent to gdb). I look at the pointer stuff first and find that it doesn’t like the following code:
player[p]->sprite = sp1_CreateSpr(sp1_SprId2Type(SP1_ID_MASK2_LB) | SP1_TYPE_2BYTE, 3, 0, 0);
sp1_AddColSpr(player[p]->sprite, sp1_SprId2Type(SP1_ID_MASK2), 48, 0);
sp1_AddColSpr(player[p]->sprite, sp1_SprId2Type(SP1_ID_MASK2_RB), 0, 0);
sp1_MoveSprAbs(player[p]->sprite, &drawarea, man + 16, 10, 14, 0, 4);
player[p]->frameoffset = (uchar *) 0; /* no frame offset */
/* make sure player[p] isn't in motion */
player[p]->dx = player[p]->dy = 0;
}
Changing it to this code (with the appropriate pointer-to-player-struct declared at the top of main()) gets over that speed bump, by pointing a pointer at the array element and then using the pointer instead of the subscripted reference. It’s not clear why the first fails and the second appears to work. I probably need to go read K&R again…
pl = &player[p];
pl->sprite = sp1_CreateSpr(sp1_SprId2Type(SP1_ID_MASK2_LB) | SP1_TYPE_2BYTE, 3, 0, p);
sp1_AddColSpr(pl->sprite, sp1_SprId2Type(SP1_ID_MASK2), 48, p);
sp1_AddColSpr(pl->sprite, sp1_SprId2Type(SP1_ID_MASK2_RB), 0, p);
sp1_MoveSprAbs(pl->sprite, &drawarea, man + 16, 10, 14, 0, 4);
pl->frameoffset = (uchar *) 0; /* no frame offset */
/* make sure pl isn't in motion */
pl->dx = pl->dy = 0;
}
Referencing the players array via a temporary pointer like this, the program builds and runs exactly as designed.
Comments
Leave a comment
Spam is filtered, and in the unlikely event it survives will be removed. Comments with hyperlinks will be held for moderation. Spammers really stink, don't they?
Posted by Stefano at 8:56 am on March 9, 2008.
Z88DK still has many limits, but is a good compromise in, my opinion.
The first issue you met is just because you begun your file name with a number, and it is not allowed.