#45155 - Lideln - Wed Jun 08, 2005 3:22 am
Hi all !
I'm new to GBA programming, and I don't understand some very weird behaviors related to sprites and backgrounds happening on my Double Dragon - like game.
First, the background
I'm using tile-based mode 0. I display :
- a background on BG0 (street and buildings) with priority 3 (like the sprites) size : 256*256
- a status background (lives, ennemies' lives, etc) with priority 2
In that case, everything works FINE.
But I would like to change the BG0 size to 512*256 in order to allow me to create a level bigger than 256 pixels :p
And... tadaaaaa ! Beurk ! I do not understand what's happening : everyhting (only in BG0) is messed up, tiles are not at their "normal" position, its awful. And its even worst when I try to change the screen and char BaseBlock of the BG0.
I tried almost everything, it just doesn't work.
Does someone have an idea about what's happening ? If you need my code to answer, I'll post it.
Second, the sprites
Another thing very weird is something like if the sprite palette had been corrupted (when looking in the palette viewer of VBA, some colors have been replaced by other).
When do this happen : In fact, till today I had been #include-ing the "sprite.c" files directly in my main.h, because I saw it somewhere, and .c are what pcx2sprite spits out. All my code was in a single file (almost) and so I decided to split it into many files (without modifying the code itself).
I then had a problem : "spriteData multiple defined in game.o, first defined in main.o", but in main.h I only #include the game.h.
So I decided to create a sprite.h file, to #include it, and to add the sprite.c to the project.
At this moment, this weird palette corruption happened. The solution I found is to delete sprite.c from the project (not compiled directly in the makefile) and to #include it directly in the game.c
It worked, but I wanted to do the same way for other sprite files, and then it became more awful than the first time (with bad animation index, missing tiles, etc)
Does anyone have ever heard about that ?
I'm sorry to bother you with my newbie's questions, and I would be very grateful for help (especially for the background problem, since I would like to create a REAL level ^^ (and I have never found a real, simple, not asm-based tutorial about that))
Thanks again,
Regards,
Lideln[/b]
#45159 - tepples - Wed Jun 08, 2005 4:01 am
Lideln wrote: |
I'm new to GBA programming, and I don't understand some very weird behaviors related to sprites and backgrounds happening on my Double Dragon - like game. |
Double Dragon Warrior, or Final Fight VII? ;-)
Quote: |
First, the background
I'm using tile-based mode 0. I display :
- a background on BG0 (street and buildings) with priority 3 (like the sprites) size : 256*256
- a status background (lives, ennemies' lives, etc) with priority 2
In that case, everything works FINE.
But I would like to change the BG0 size to 512*256 in order to allow me to create a level bigger than 256 pixels :p
And... tadaaaaa ! Beurk ! I do not understand what's happening : everyhting (only in BG0) is messed up, tiles are not at their "normal" position, its awful. And its even worst when I try to change the screen and char BaseBlock of the BG0.
I tried almost everything, it just doesn't work. |
A 512x256 pixel map is organized in memory as two 256x256 maps side by side. But actually, you can make a level bigger than 256 pixels with a 256x256 map by redrawing only those tiles that are about to become visible. At any given scroll position, there's a 16-pixel-wide strip of the map that is not displayed; if you continue to draw new map data into that strip, you can keep drawing map data until the batteries run out.
Quote: |
I then had a problem : "spriteData multiple defined in game.o, first defined in main.o", but in main.h I only #include the game.h.
So I decided to create a sprite.h file, to #include it, and to add the sprite.c to the project.
At this moment, this weird palette corruption happened. The solution I found is to delete sprite.c from the project (not compiled directly in the makefile) and to #include it directly in the game.c
It worked, but I wanted to do the same way for other sprite files, and then it became more awful than the first time (with bad animation index, missing tiles, etc) |
Are you making sure to give each file a unique name? Don't use "sprite" as a file name unless it depicts a Secret of Mana fairy or a can of lemon-lime flavored carbonated soda.
Quote: |
I'm sorry to bother you with my newbie's questions, and I would be very grateful for help (especially for the background problem, since I would like to create a REAL level ^^ (and I have never found a real, simple, not asm-based tutorial about that)) |
Open the tile viewer in VisualBoyAdvance for Windows, set it on auto-refresh, and look at the background on any GB, GBC, or GBA scrolling game.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#45198 - Lideln - Wed Jun 08, 2005 3:19 pm
Hi Tepples,
First of all thanks for your answer. I'll try to figure out how to make the "fill the strip" work since I did not find any good tutorial about this (for example, do I have to fill the tiles memory as well, or just the data memory ?) I won't deny that if you know about a good tutorial on what you said (using a 256*256 BG) it would be of great help for me.
(maybe you could write some lines of code about that, since I think that, for you, it must not be very hard to write ? of course, I do not want to bother you, and if you have better things to do, or else, I'll try by myself)
For the sprites being corrupted, I still don't know what's happening... The sprites are called a different name each, and before splitting my code into different files everything was ok... weird...
Not knowing what to do, I decided to put my code in a single (almost) file again... It's very ugly, but its the only way it works atm.
Thanks again, and if you know about a good scrolling tutorial speaking about what you told me, I would be greatly interested.
Have a nice day,
Lideln
#45273 - Lideln - Thu Jun 09, 2005 3:44 am
Hi !
It's me, again...
I juste can't figure out what the hell is happening in my code. Could someone help me please ?
Here is what the problem is (about the sprites) :
Let's say I have a main.c and main.h.
In the main.h, I write :
[code]
#include "ptiga.h"
#include "ptiga.c"
// #include "jelly.h"
// #include "jelly.c"
[/quote]
Note that I had to comment the second sprite include.
In that case, everything is ok, my hero is displayed correctly.
However, if I write :
[code]
#include "ptiga.h"
#include "ptiga.c"
#include "jelly.h"
#include "jelly.c"
[/quote]
For example if I need to display other sprites than my hero.......
In that case everything goes wront, even not using the second sprite, juste including it !!!
What's happening ? My hero sprite is then displayed randomly, wrong tiles are displayed, sometimes nothing is displayed, sometimes just some weird pixels, sometimes a good face of my hero...
Please, does someone know what is happening with my code ?
I just don't have the courage to write my code again from the beginning to see where it crashes, it would take too much time.
Thanks by advance for your help.
Regards.
#45288 - ScottLininger - Thu Jun 09, 2005 6:32 am
Lideln,
Could you post an opening snippet from your C and H files? My guess is that you're missing something very simple.
One thing that's possible is that you're not putting the sprite data into the right memory area, and you're running out of RAM.
For example, are you using the "const" keyword in your graphic data declaration? This is needed to tell the compiler to store your graphics in cartridge ROM. If you don't declare them as const, they're getting stuffed into RAM at runtime.
Code: |
const u16 jellyData[] = {
0x0000, 0x0000, 0x058B, 0x0000, 0x0000, 0xAC8B, 0x7979, 0x0079, 0x7979, 0x7979,
...
|
We don't need to see everything... but a bit of code would be a good start.
:)
-Scott
#45361 - Lideln - Thu Jun 09, 2005 11:29 pm
Hi Scott
Thank you for your answer.
Yes, there is the "const" since it is created by pcx2sprite, but the fact is that finally I decided to check every line of my code (since my last post yesterday).
I found at last where the error was, but I found it thanks to luck. (after about 6-8hours reading my code and making tests)
When I create a sprite handler, a structure that knows the x, y, and z coord of my sprites for example, I created a [128] array, and that is what was wrong. I don't know why, because when I put [NUMBALLS] (from a Harbour Tutorial), it works !
This is quite annoying because Harbour created a 128 array, not a NUMBALLS one.
I thinks it's because I do not initialize every sprite, do you think so ?
I just initialize the sprites I am using, so if I copy the data from sprites I am not using (thus they are not initialized, are they ?), I copy some weird values, isn't it ?
Here are some lines of code using sprites and sprites handlers (I am unfortunately not a guru coder, so my code is not secret ^^) :
Here is the sprites.h
Code: |
// ------------------------
// sprites.h
// ------------------------
typedef struct tagSprite
{
unsigned short attribute0;
unsigned short attribute1;
unsigned short attribute2;
unsigned short attribute3;
}Sprite,*pSprite;
typedef struct tagSpriteHandler
{
int alive;
int x, y, z;
int dirx, diry;
int width, height;
int hflip, vflip;
int size;
int shape;
int colormode;
int trans;
}SpriteHandler;
extern Sprite sprites[128];
extern SpriteHandler mysprites[NUMBALLS];
|
Here is the sprites.c :
Code: |
#include "sprites.h"
SpriteHandler mysprites[NUMBALLS];
Sprite sprites[128];
void HideSprites()
{
int n;
for (n = 0; n < NUMBALLS; ++n)
{
sprites[n].attribute0 = 160;
sprites[n].attribute1 = 240;
}
}
void MoveSprite(int num)
{
sprites[num].attribute1 &= 0xFE00;
sprites[num].attribute1 |= mysprites[num].x | mysprites[num].hflip | mysprites[num].vflip;// & 0x01FF);
sprites[num].attribute0 &= 0xFF00;
sprites[num].attribute0 |= mysprites[num].y;// & 0x00FF);
}
void UpdateSpriteMemory(void)
{
unsigned short* temp;
temp = (unsigned short*)sprites;
DMACopy((void*)temp, (void*)SpriteMem, NUMBALLS * sizeof(Sprite) / 4, DMA_32NOW);
}
void InitSprite(int num, int x, int y, int z, int sizeX, int sizeY, int color, int tileIndex)
{
unsigned int sprite_size = 0;
unsigned int sprite_shape = 0;
// some uninteresting code......
}
|
Here is where I initialize the sprites (at the moment only 2 different sprites, heheee it's the beginning :D). Here the code is exclusively (almost) from me, so there may be erros :D
Code: |
void UpdateJelly(int index)
{
u16 *data;
u16 *dest;
int max = jelly_WIDTH * jelly_HEIGHT / 2;
int begin = ptiga_WIDTH * ptiga_HEIGHT / 2;
data = &jellyData[(max * index)];
dest = &SpriteData[begin];
DMACopy((void*)data, (void*)dest, max, DMA_16NOW);
}
void UpdatePtiga(int index)
{
u16 *data;
int max = ptiga_WIDTH * ptiga_HEIGHT / 2;
data = &ptigaData[(max * index)];
DMACopy((void*)data, (void*)SpriteData, max, DMA_16NOW);
sprites[0].attribute0 = mysprites[0].shape | mysprites[0].colormode | mysprites[0].y;
sprites[0].attribute1 = mysprites[0].size;
sprites[0].attribute1 |= mysprites[0].x | mysprites[0].hflip | mysprites[0].vflip;
}
// ----------------------------------
// In the main(void) function :
// ----------------------------------
InitSprite(0, (240 - ptiga_WIDTH) / 2, 160 - 16 - ptiga_HEIGHT, 16, ptiga_WIDTH, ptiga_HEIGHT, COLOR_256, 0);
for (n = 1; n < NUMBALLS; ++n)
{
InitSprite(n, rand() % 230, rand() % 150, 0, jelly_WIDTH, jelly_HEIGHT, COLOR_256, 32);
}
|
Now, if I change the :
Code: |
// sprites.h
extern SpriteHandler mysprites[NUMBALLS];
// sprites.c
SpriteHandler mysprites[NUMBALLS];
|
into :
Code: |
// sprites.h
extern SpriteHandler mysprites[128]; // the max amount of sprites
// sprites.c
SpriteHandler mysprites[128]; // the max amount of sprites
|
Then my game freezes.... Nice, isn't it ? :D
(I also got some weird results like sprites displaying only one frame each two frames, and each its turn : ptiga first, then jelly, then ptiga... and with some of the frames distorted, I mean weird things... erf)
I should try with different values of NUMBALLS (atm it's 10), but if you see where the problem comes from, I'm listening :D
Thanks for your help, this is very nice of you !
Another thing : I still experience problems when trying to display a 512*256 background, the result is very awful. If you know where I can find a tutorial about how to display such a background (and especially how to perform a scrolling -- not only with the MapWrap bit, but a real level like mario) I would be very interested ! I am in mode 0.
Thanks again a lot, :)
Lideln
#45388 - Shade - Fri Jun 10, 2005 3:40 am
Hi, I've stopped following the Harbour book and started using TONC as a guide; I strongly recommend you do so as well. It's been quite useful so far (specially the background chapter).
http://user.chem.tue.nl/jakvijn/tonc/
Cheers and good luck
_________________
"Whenever you find you're on the side of the majority, it's time to pause and reflect." -- Mark Twain
#45390 - Lideln - Fri Jun 10, 2005 3:56 am
Hi Shade !
It seems to be very interesting, I think its just what I was in need for.
Thank you for your tip, have a nice day !
Lideln
(France)
#45398 - Lideln - Fri Jun 10, 2005 8:17 am
Nice, thanks again for the site, now I understood why I was wrong (i thought the way to fill the BG was th same as a picture, but its not)
Thanks !
Lideln
#45441 - Shade - Fri Jun 10, 2005 6:35 pm
Lideln wrote: |
Nice, thanks again for the site, now I understood why I was wrong (i thought the way to fill the BG was th same as a picture, but its not) |
You're welcome. TONC already helped me a lot. Enjoy!
Cheers
_________________
"Whenever you find you're on the side of the majority, it's time to pause and reflect." -- Mark Twain