#26815 - LOst? - Sun Sep 26, 2004 7:47 pm
I want a type struct like this:
Code: |
typedef struct
{
size = ?;
const int array [size]
} name;
|
And I don't want to use new or malloc because I want the array to be set at compilation, and not during execution.
I hope I'm not too confusing. I need a mappings struct with an array with each sprite represented. I want to have a managable ammount of sprites for each mappings that will be hardcoded, and I only want to have one struct. Not hard coded structs for each mappings.
EDIT:
Or maybe I should just use structs for all mappings without the typedef? Is this working?
Code: |
struct HeroCharacter
{
size = 12;
const sprites array [size]
};
|
#26816 - Lord Graga - Sun Sep 26, 2004 7:59 pm
When you set size at compilation and define all RAM ereas, you do NOT malloc.
Here's an example of something that does not take malloc:
Code: |
#include "someheadershere.h"
const int array[1324];
int main() {
SetUpPrintSystem();
PrintNumberToScreen(sizeof(array));
} |
This will print the size of the array in bytes (1234*4, I believe).
#26817 - sajiimori - Sun Sep 26, 2004 8:01 pm
That's one sort of problem that templates were meant to fix in C++, but it's not so bad in C as long as you're using a compiler that supports flexible arrays (which GCC has for a while). Code: |
typedef struct
{
int size;
int array[];
} S;
const S s =
{
3,
{ 100, 200, 300 }
}; |
You still have to ensure that 'size' matches the length of the array, so if you have to manage a lot of data then write a code generator and let your computer do the tedious work. Perl helps here.
#26821 - LOst? - Sun Sep 26, 2004 9:57 pm
sajiimori wrote: |
That's one sort of problem that templates were meant to fix in C++, but it's not so bad in C as long as you're using a compiler that supports flexible arrays (which GCC has for a while). Code: | typedef struct
{
int size;
int array[];
} S;
const S s =
{
3,
{ 100, 200, 300 }
}; | You still have to ensure that 'size' matches the length of the array, so if you have to manage a lot of data then write a code generator and let your computer do the tedious work. Perl helps here. |
Thank you very much! I can see how you are using const. That's something I really wanted to know. Const in C++ is so confusing.
#26824 - LOst? - Sun Sep 26, 2004 10:16 pm
Okay, I'm stuck. Do you have any suggestion on making this working?
Code: |
typedef struct
{
s16 sx;
s8 sy;
u16 CharStart;
s8 PalNumPlus;
u16 Shape;
u16 Size;
} Fragment;
typedef struct
{
int size;
Fragment fragments [];
} Mappings;
const Mappings test [2] =
{
2,
{ {-8, -8, 512, 0, SQUARE, SIZE_16}, {-8, -8, 252, 0, SQUARE, SIZE_16} }
};
|
I have no idea how to initialize the Fragment structure inside the array {} :(
#26825 - Lord Graga - Sun Sep 26, 2004 10:23 pm
Code: |
const Mappings test [2] =
{
2,
{ {{-8, -8, 512, 0, SQUARE, SIZE_16}, {-8, -8, 252, 0, SQUARE, SIZE_16}} }
};
|
I have no idea how to initialize the Fragment structure inside the array {} :(
There you go. An extra { } should do it. Beware that if you plan to copy the struct that you made to the OAM, then errors will definetly occur :)
#26826 - sajiimori - Sun Sep 26, 2004 10:26 pm
I wouldn't expect Graga's code to work, either. The reason neither version should work is that you declared an array of Mappings, which you can't really do since Mapping is of undefined size. It could be 4 bytes or 4000, depending on the size of the 'fragments' array.
You can make single Mapping structs, or you can make arrays of Mapping pointers.
#26828 - LOst? - Sun Sep 26, 2004 10:33 pm
sajiimori wrote: |
I wouldn't expect Graga's code to work, either. The reason neither version should work is that you declared an array of Mappings, which you can't really do since Mapping is of undefined size. It could be 4 bytes or 4000, depending on the size of the 'fragments' array.
You can make single Mapping structs, or you can make arrays of Mapping pointers. |
I have no idea how to do this. I want the best and fastest way to do sprite mappings. It doesn't need to be the same format as the OAM memory.
#26829 - sajiimori - Sun Sep 26, 2004 11:30 pm
Sorry, I don't understand the problem well enough to offer a solution. If by "fastest" you mean in terms of CPU usage, I wouldn't worry about it until you are actually running out of CPU. Do it whichever way is simplest.
#26832 - LOst? - Mon Sep 27, 2004 12:23 am
sajiimori wrote: |
Sorry, I don't understand the problem well enough to offer a solution. If by "fastest" you mean in terms of CPU usage, I wouldn't worry about it until you are actually running out of CPU. Do it whichever way is simplest. |
Okay. No not really fast in terms of CPU usage... More of a fast way to handle the data.
I mean managing sprite frames (using multiple sprites per frame) in a data format represented by a struct.
I have a sprite list that is copied every vblank. I will use a function called ShowObject(); to translate the mappings into sprites and load them into that list. I have everything set except for the mappings format. If it was Motorola 68k assembler I would do it like this:
Code: |
MappingsStart:
dc.w Frame1-MappingsStart
dc.w Frame2.MappingsStart
Frame1:
dc.b $05 ; 5 sprites for this frame
dc.w $FFE0 ; X offset of sprite 1
....
dc.w $FFE0 ; X offset of sprite 2
....
dc.w $FFE0 ; X offset of sprite 3
....
dc.w $FFE0 ; X offset of sprite 4
....
dc.w $FFE0 ; X offset of sprite 5
....
Frame2:
dc.b $01 ; One sprite for this frame
dc.w $FFE0 ; X offset of sprite 1
....
|
A simple list where every frame has its unique number of sprites with their X, Y, PALLINE, CHARACTER data declared.
#26833 - sajiimori - Mon Sep 27, 2004 1:58 am
It looks like "MappingsStart" is an array of pointers to "Mappings" structures, which are each created seperately.
Code: |
Mappings Frame1 =
{
5, // 5 sprites for this frame
{ ... },
...
};
Mappings Frame2 =
{
...
};
Mappings* MappingsStart[] =
{
&Frame1,
&Frame2,
...
};
|
#26834 - MumblyJoe - Mon Sep 27, 2004 2:29 am
Just throwing my C++ hat into the ring:
Code: |
template<unsigned int SIZE>
class Mappings
{
public:
class Fragment
{
public:
s16 sx;
s8 sy;
u16 CharStart;
s8 PalNumPlus;
u16 Shape;
u16 Size;
};
Fragment fragments [SIZE];
};
const Mappings<2> test =
{
{ {-8, -8, 512, 0, 5, 3}, {-8, -8, 252, 0, 3, 5} }
}; |
Tested on borland 5.5.1, not gcc yet.
_________________
www.hungrydeveloper.com
Version 2.0 now up - guaranteed at least 100% more pleasing!
#26836 - sajiimori - Mon Sep 27, 2004 2:38 am
Ok, now make an array of those, or pointers to them, in such a way that the fragments of each array element can be iterated over.
#26837 - Lord Graga - Mon Sep 27, 2004 7:43 am
If C++ gives you problems, you can probably just use C and then make a header?
#26840 - sajiimori - Mon Sep 27, 2004 8:02 am
What problems?
#26849 - LOst? - Mon Sep 27, 2004 1:46 pm
MumblyJoe wrote: |
Just throwing my C++ hat into the ring:
Code: | template<unsigned int SIZE>
class Mappings
{
public:
class Fragment
{
public:
s16 sx;
s8 sy;
u16 CharStart;
s8 PalNumPlus;
u16 Shape;
u16 Size;
};
Fragment fragments [SIZE];
};
const Mappings<2> test =
{
{ {-8, -8, 512, 0, 5, 3}, {-8, -8, 252, 0, 3, 5} }
}; |
Tested on borland 5.5.1, not gcc yet. |
I'm really interested in learning templates someday. This might be the start of it. And if it doesn't work, I will go by sajiimori list of pointers.
EDIT: MumblyJoe's code compiles without errors. This is going to be interesting. Hopefully this works...
EDIT: How do I get the stuff out from "test"?
Would it be like this?
Code: |
test.fragments [0].Shape
|
Also this class misses the info on how many fragments there are. How do I implent it into the class Mappings?
#26852 - poslundc - Mon Sep 27, 2004 2:25 pm
LOst? wrote: |
I'm really interested in learning templates someday. |
http://cplusplus.com/doc/tutorial/tut5-1.html
Dan.
#26854 - jma - Mon Sep 27, 2004 3:38 pm
It probably doesn't matter to the original poster, but just to add completeness to the template idea: every different instance of the template will generate more code for that template. In essence, a templated class is just one massive macro that will generate code. So, using your Mappings class:
Code: |
Mappings<128> sprite_list_1;
Mappings<200> sprite_list_2; |
This will create 2 different copies of the Mappings code. Just letting the original poster know if space is precious to him. Usually, templates aren't much of a big deal because they template types (like an array of ints, or an array of doubles) -- not too many different ones floating around. But when you start templating with integers and such, you can generate lots of extra code.
If you only need a single instance of it, (like <128> in this case perhaps?) then there is no real need to use a template. I consider this especially true since you are declaring them globally at compile time. Just use a #define'd constant. Likewise, there is no reason that you can't use C, either:
Code: |
typedef struct tagFragment {
s16 sx;
s8 sy;
u16 CharStart;
s8 PalNumPlus;
u16 Shape;
u16 Size;
} Fragment;
typedef struct tagMappings {
unsigned int nFragments;
Fragment *pFragments;
} Mappings;
/* declare your constant list of them */
const Fragment some_fragments[] = {
{-8, -8, 512, 0, 5, 3},
{-8, -8, 252, 0, 3, 5},
/* TODO: fill in the rest */
};
/* delcare the mapping to them */
const Mappings a_mapping = {
sizeof(some_fragments) / sizeof(Fragment),
some_fragments,
}; |
Nothing against C++ and templates -- they can be very useful. Just giving the original poster more information and options to choose from.
Jeff
_________________
massung@gmail.com
http://www.retrobyte.org
#26857 - LOst? - Mon Sep 27, 2004 8:31 pm
For the first time in my life I see C/C++ missing something.
Pointers to class templates of different sizes.
Predeclaration of a array of structures with more arrays with different data types in it.
With a lot off errors for these kind of datas, I'm forced to use 4 structures each, with different types, so making a simple sprite frame I need to have 4 different types of structures seperate from each other.
This is what I call OOP!
EDIT:
And guess what? It still isn't working!
You guys seem to forget one thing when you post your examples: Number of mappings (frames)! I need each mapping to have a variable with number of fragments, but I also need the mappings to hold a variable with number of frames.
Mappings = (a group of frames)
Frame = (a group of fragments)
Fragment = a hardware sprite.
-------------------------------------------------
EDIT:
I have taken out the mappings structure, and I go with this now:
Code: |
typedef struct
{
s16 sx;
s8 sy;
u16 CharStart;
s8 PalNumPlus;
u16 Shape;
u16 Size;
} Fragment;
#define NumFragments(n) sizeof (n) / sizeof (Fragment)
|
And when creating two frames, I go like this:
Code: |
const Fragment frame1 [] =
{
{-8, -8, 512, 0, SQUARE, SIZE_16},
{-8, -8, 252, 0, SQUARE, SIZE_16}
};
const Fragment frame2 [] =
{
{-8, -8, 512, 0, SQUARE, SIZE_16},
{-8, -8, 512, 0, SQUARE, SIZE_16},
{-8, -8, 252, 0, SQUARE, SIZE_16}
};
const Fragment* test [] =
{
frame1,
frame2
};
|
Then I guess I can get the number of fragments by doing this (hopefully):
Code: |
int number = NumFragments (test [0]); // Using macro for getting the amount of arrays
|
But I'm kinda stuck now. The biggest issue right now is to keep track of the data through pointers to arrays of unknown sizes that points to (is it?) the fragments wich i can use that macro to get the number of.
God this code would give so much Access Violation exceptions if it was a Win32 application I assume.
#26866 - jma - Mon Sep 27, 2004 10:57 pm
LOst? wrote: |
I need each mapping to have a variable with number of fragments |
How do you not have that with the example code I provided above?
Quote: |
Mappings = (a group of frames)
Frame = (a group of fragments)
Fragment = a hardware sprite.
...
And when creating two frames, I go like this:
Code: |
const Fragment frame1 [] =
{
{-8, -8, 512, 0, SQUARE, SIZE_16},
{-8, -8, 252, 0, SQUARE, SIZE_16}
};
const Fragment frame2 [] =
{
{-8, -8, 512, 0, SQUARE, SIZE_16},
{-8, -8, 512, 0, SQUARE, SIZE_16},
{-8, -8, 252, 0, SQUARE, SIZE_16}
};
const Fragment* test [] =
{
frame1,
frame2
};
|
Then I guess I can get the number of fragments by doing this (hopefully):
Code: |
int number = NumFragments (test [0]); // Using macro for getting the amount of arrays
|
|
I think you are sorely confused in your "objectifying" of the problem. Given your example code, test[0] should contain (in some way) the number of fragments (hardware sprites) in the frame. But you state at the beginning of your post that the number of fragments should be stored in the mapping. Which do you want? If a frame is no more than an array of fragments it can't contain the size (unless you make it a struct or class that can hold more data).
Quote: |
but I also need the mappings to hold a variable with number of frames. |
Again, you are objectifying poorly. You are saying one thing and coding something entirely different. You should have an entirely separate structure here just for frames:
Code: |
struct Mapping {
int n_frames;
Frame *frames;
};
struct Frame {
int n_fragments;
Fragment *fragments;
};
struct Fragment {
/* sprite stuff */
};
// Now put it all together:
const Fragment some_fragments[] = {
/* todo */
};
const Frame some_frames[] = {
{ sizeof(some_fragments) / sizeof(Fragment), some_fragments },
/* todo: more */
};
const Mapping some_mappings[] = {
{ sizeof(some_frames) / sizeof(Frames), some_frames },
/* todo: more */
}; |
You are trying to skip the middle step of "Frame" and expect the array to just "know" how many elements it has. Sorry, no-go in C.
Jeff
_________________
massung@gmail.com
http://www.retrobyte.org
#26867 - LOst? - Mon Sep 27, 2004 11:07 pm
jma wrote: |
LOst? wrote: | I need each mapping to have a variable with number of fragments |
How do you not have that with the example code I provided above?
I think you are sorely confused in your "objectifying" of the problem. |
Well, it's an outcome of my bad English. I'm sorry for that. I'm also sorry for getting upset. I hoped I would have found a way to make this mappings system work today.
You are correct, and I used some of you code. I never aimed this problem to be caused by you. I got mad at all the errors I got from GCC while trying to get this to work. Mostly the error that says you can't convert const Mappings* into Mappings*.
I really don't need the number of frames, but my wish was to hold the number so that I can't by accident read data outside of the array.
#26871 - sajiimori - Tue Sep 28, 2004 1:04 am
Well, you've heard plenty of reasonable solutions by now, and you can pick the one you like best. C and C++ lack a lot of things I like, but the features you are complaining about are too vague to implement.
You want a pointer to a templatized object with an unspecified argument? You may as well ask for pointers to classes you haven't finished writing yet. The compiler couldn't know how to treat such an "object". Use dynamic allocation or flexible arrays.
You want arrays of values that are all different sizes? Then what does a[i] compile to if a is such an array? Use arrays of pointers.