#15188 - Dreamer - Sun Jan 18, 2004 6:57 pm
I'm left a bit stumped about a problem I seem to be having. I'm not quite used to structs compared to classes, so that may be something of a factor. I have a Sprite struct for loading sprite data and storing it in a global array, a SpriteObject struct for creating specific instances of sprites and keeping track of their location and animation, and a Piece struct that stores an array of SpriteObjects (I'm working on Tetris).
I've recently been working on setting tiles dynamically onto the background, and noticed that for some reason, after I create my first Pieces, it will not show the tile I dynamically displayed. I was testing lines and think it is somehow related to the SpriteObject struct, or how the pieces are made.
Is there something about initializing a Struct or something like that which can cause problems? Appreciate any insight.
Here is the source for any interested, starting at line 88 of Main.c is the trouble.
#15191 - sajiimori - Sun Jan 18, 2004 8:15 pm
Code: |
SpriteObject Make ( u8 spriteindex, int x, int y )
{
SpriteObject obj;
...
return obj;
}
|
Am I picking up a pattern here?
#15192 - Dreamer - Sun Jan 18, 2004 8:21 pm
You've got to be kidding me... Ok, well I tried
Code: |
//object.h
void CreateObject ( SpriteObject * obj, u8 spriteindex, int x, int y )
//main.c
SpriteObject O;
CreateObject ( &O, 2, 8, 8 );
|
And got the same result. Geez why do I feel like I've never written C code before... Ugh. And why do I feel like I'm missing something in writing constructors for structs.
#15195 - sajiimori - Sun Jan 18, 2004 9:05 pm
Well, I'm not going to look around for other bugs right now, but I'm noticing other things about your program as a whole.
Some header files have data and function definitions in them, which is a bad idea. (random.h creates lots of stuff, graphics.h creates a variable, background.h creates 3 functions, timers.h creates 1 function)
Some C files have 'extern' declarations in them, which seems redundant and error-prone. Put declarations in header files -- that's what they're for.
Why does SpriteObject contain an entire Sprite struct, instead of a reference to one of the entries in SpriteInfo[]?
Why does Piece contain an array of whole SpriteObject structs, instead of an array of references to entries in Objects[]?
All that redundant data costs you big time. Most obviously, it eats up lots of RAM. In addition, it costs CPU time and increases code complexity due to the extra work required to keep the various structures synchronized. Lastly, it makes the program much harder to debug (as you have discovered the hard way).
(Note that I am not listing a "fix" here, so don't come back and say "I did all those things and it still doesn't work.")
#15196 - Dreamer - Sun Jan 18, 2004 9:26 pm
Background.h creates 3 functions (instead of being in Background.cpp) because of a problem I seem to have where Main doesn't recognize any of its methods. Most of the messiness and poor style is because I'm not really trying to be efficient, just trying to slowly learn the engine, and then work on refactoring. Maybe if I fix things, I'll figure out this struct sucker. Thanks for the help.
#15197 - sajiimori - Sun Jan 18, 2004 9:57 pm
Quote: |
Background.h creates 3 functions (instead of being in Background.cpp) because of a problem I seem to have where Main doesn't recognize any of its methods.
|
Maybe you could post a version that has this problem. The solution is likely to be simple. If you don't start making your life easier by solving your existing problems, it's just going to get worse and worse, until it's so hard to add features that you're at a deadlock.
Quote: |
Most of the messiness and poor style is because I'm not really trying to be efficient, just trying to slowly learn the engine, and then work on refactoring.
|
It's ok to start with an inefficient prototype in the interests of keeping things simple at first, but I don't think that logic applies here because some aspects of your program are making things significantly *less* simple.
Compared to doing the simple thing (sharing structures), having to synchronize multiple copies of sprite data is not just less efficient -- it's much more complicated.
#15200 - Dreamer - Sun Jan 18, 2004 10:24 pm
Same link: http://jhunix.hcf.jhu.edu/~prt2/Test/DreamTris.zip
I've tried whatever I could think of to get it working, and I'm rather lost. Background.cpp compiles and links with Main, and I don't quite understand why it won't recognize methods. I got that code from Pern Project Day 4 Tutorial.
Last edited by Dreamer on Mon Jan 19, 2004 12:52 am; edited 2 times in total
#15204 - poslundc - Mon Jan 19, 2004 12:44 am
I took a look at your code and it really is a mess to figure out.
My best advice to you is to start simpler and write a program that tries to do just what you are doing with sprites. Code and debug it, and it will be much easier for us to help you with it if you need it. Then incorporate that into the program you are writing now.
It might seem like taking a step backwards (in fact it is), but it's something the rest of us do all the time to help keep our code tidy, modular, and most importantly, working.
You will also have better luck getting help if you figure out where the general problem is, and post a code snippet here for us to look at (using code tags). Giving us a link to a zip file to your entire project kind of sends the message "it's broke, fix it". I know you only did so because you don't know where the problem is originating from, but then that goes back to what I said earlier about taking a step back and writing a simpler program.
Good luck,
Dan.
#15205 - Dreamer - Mon Jan 19, 2004 12:55 am
I refactored the living hell out of the code, given the suggestions, so it is looking a lot neater and tidier. Everything seems to work fine, except now I need to figure out why it says "Multiple Definitions of BricksXData and BricksXPalette" despite my attempts at #ifndef. But I think I'm getting it.
I greatly appreciate the help and advice, and no, I definitely didn't mean for it to come across like "Fix my code, compile, and return with hot coffee". I'd actually rather know why my code isn't working than to have the solution done, just so I learn something. I also didn't mean to come across as a novice coder, although it appears that it indeed has been quite a long time since I really did code last.
At this point I'd hate to take the step back (having done that twice on earlier learning ventures) since it only seems to be this one error left, but I'll get that sucker working. It has to do with the includes in various files. It can't hide from me forever!
#15207 - Dreamer - Mon Jan 19, 2004 2:31 am
Ok problem has been fixed (not exactly solved). I don't seem to be understanding how linking handles things, because a reference to data arrays generated from a .pcx file in one header was giving a dozen 'multiple definition' errors. So I just moved all code relevant to those data pieces into Main, which is somewhat ugly, but it works now, and I have gotten the dynamic tile setting to function.
Appreciate all the help, advice, and time spent to help this young soul. Thanks for putting up with me.
#15210 - tepples - Mon Jan 19, 2004 3:16 am
Dreamer wrote: |
except now I need to figure out why it says "Multiple Definitions of BricksXData and BricksXPalette" despite my attempts at #ifndef. |
The declarations (with extern) should appear in a header file. On the other hand, the definitions (without extern) should appear in one and only one source code file.
Quote: |
I'd actually rather know why my code isn't working than to have the solution done |
In general, in the world of Usenet and web boards that discuss C programming, you'll get better results by minimizing your test case, that is, producing the smallest possible test case that demonstrates a misbehavior that you do not understand.
Quote: |
I also didn't mean to come across as a novice coder |
Even experienced coders on 32-bit PC-like platforms, such as BSD, VMS, Linux, Mac OS, and Windows, can become confused when placed in an environment with no file system and no API layer around the hardware. That's why libraries such as HAMlib, AGBTTY, and GBFS exist, to provide rough equivalents to familiar interfaces.
Quote: |
I don't seem to be understanding how linking handles things, because a reference to data arrays generated from a .pcx file in one header was giving a dozen 'multiple definition' errors. |
Here's what you do:- Never #include a .c file from another .c file.
- Avoid converting binary files such as .pcx files to .c; convert them to .s (assembly) instead.
- If you still have trouble understanding how to statically link binary files into your program, use an appended data programming library such as my GBFS.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#15211 - poslundc - Mon Jan 19, 2004 3:21 am
Dreamer wrote: |
Ok problem has been fixed (not exactly solved). I don't seem to be understanding how linking handles things, because a reference to data arrays generated from a .pcx file in one header was giving a dozen 'multiple definition' errors. |
This is a result of you putting the data into a header file, instead of a proper data file (either C or ASM).
See my comments in this thread for an explanation.
Edit: Once again, tepples beats me to the punch...
Dan.
#15212 - sajiimori - Mon Jan 19, 2004 3:29 am
Seems like you haven't removed all the data/function definitions from your .h files. See: random.h timers.h graphics.h
#15213 - Dreamer - Mon Jan 19, 2004 4:00 am
I removed all of them... except for the ones that came from converting images using the pcx2gba and pcx2sprite programs. I realize that they were defining variables in a header, but I wasn't quite sure how to handle it, since I'd have to keep cutting and pasting the converted arrays into some file. Tried using it as a .c file instead of an .h file. I don't quite have experience with .s or ASM so I'm somewhat avoiding anything to do with it at the moment, instead using those conversion programs.
#15219 - sajiimori - Mon Jan 19, 2004 5:44 am
Quote: |
I realize that they were defining variables in a header, but I wasn't quite sure how to handle it, since I'd have to keep cutting and pasting the converted arrays into some file.
|
For example?
#15221 - Dreamer - Mon Jan 19, 2004 6:10 am
When I take some image mapped to tiles, or one of my sprite images, like BricksX.pcx, then convert it to a .h file, I have the data array and palette BricksXData[] and BricksXPalette there. Now, if I moved that to my variable definition file, and then re-did the image and reconverted it, I'd have to move that again. Or every time I convert any more images or maps, I'd have to move them to a file, and it seems somewhat... unnecessary when I can just use the header files generated for me where they are.
#15222 - sajiimori - Mon Jan 19, 2004 6:21 am
Can't you tell your utilities to output to a different filename?
Edit: better yet, use tepples' filesystem.
#15223 - Dreamer - Mon Jan 19, 2004 7:23 am
Hmm, thanks for the heads-up. I downloaded it, and I'll take a look at it when I get the chance and see what's the dilly-yo, as they say on the mean streets. Now, however, I must hit the sack, as they say on the more pleasant streets.
#15249 - tepples - Tue Jan 20, 2004 12:31 am
Here's one solution to work with image converters that like to spit out .h files: Have one .c file that #include's all the .h files, and then compile and link this .c file into your program. In your makefile, make this .c file depend on all those .h files. Or if the image converters (like my older ones) like to write to stdout, try >> to append to a file.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.