gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

C/C++ > Intro prob

#5262 - maciel310 - Thu Apr 24, 2003 1:15 am

Hi, I have a little problem making an intro for a game I am in the process of making. I have a some pictures that I made and I have it so when they press the A button it switches between them, but when I tested it, it would keep on going back to the first screen after changing the first time, so it would loop the same image instead of going on. How can I fix this? Ill post the code so you can see what I am doing wrong

Quote:

#include "headers.h"

u16* theVideoBuffer = (u16*)VideoBuffer;
u16* theScreenPalette = (u16*)BGPaletteMem;

#define RGB(r,g,b) (r+(g<<5)+(b<<10)) //Macro to build a color from its parts

int main()
{
SetMode(MODE_4|BG2_ENABLE);

if(!(*KEYS & KEY_A)) //A
{
//Copy the palette
u16 i;
for ( i = 0; i < 256; i++ )
theScreenPalette[ i ] = APalette[ i ];

//Cast a 16 bit pointer to our data so we can read/write 16 bits at a time easily
u16* tempData = (u16*)A;

//Write the data
//Note we're using 120 instead of 240 because we're writing 16 bits
//(2 colors) at a time
u16 x, y;
for ( x = 0; x < 120; x++ )
for ( y = 0; y < 160; y++ )
theVideoBuffer[ y * 120 + x ] = tempData[ y * 120 + x ];


if(!(*KEYS & KEY_A)) //B
{
//Copy the palette
u16 i;
for ( i = 0; i < 256; i++ )
theScreenPalette[ i ] = BPalette[ i ];

//Cast a 16 bit pointer to our data so we can read/write 16 bits at a time easily
u16* tempData = (u16*)B;

//Write the data
//Note we're using 120 instead of 240 because we're writing 16 bits
//(2 colors) at a time
u16 x, y;
for ( x = 0; x < 120; x++ )
for ( y = 0; y < 160; y++ )
theVideoBuffer[ y * 120 + x ] = tempData[ y * 120 + x ];


if(!(*KEYS & KEY_A)) //C
{
//Copy the palette
u16 i;
for ( i = 0; i < 256; i++ )
theScreenPalette[ i ] = CPalette[ i ];

//Cast a 16 bit pointer to our data so we can read/write 16 bits at a time easily
u16* tempData = (u16*)C;

//Write the data
//Note we're using 120 instead of 240 because we're writing 16 bits
//(2 colors) at a time
u16 x, y;
for ( x = 0; x < 120; x++ )
for ( y = 0; y < 160; y++ )
theVideoBuffer[ y * 120 + x ] = tempData[ y * 120 + x ];

}
}
}


return 0;
}


Thanx for any help

#5265 - johnny_north - Thu Apr 24, 2003 3:11 am

In PC development, if you run off the end of main() with a return 0, your program exits to the operating system. Easy enough. On the GBA however, if you don't do something to capture the execution before this happens, the programm will begin to execute again at the first line of main(). So ineffect you will continue to "loop" through main() indefinitely. Just before returning 0 in main(), add the following line:

while(1){}

The reason you're only seeing the first screen is because your first button press will trigger all of the rest of your button tests. What you need to is capture the button presses after the first button press. This makes sure that the second screen is not displayed until the player first releases the A button. If you don't add this capture code, you'll blast by the other graphics. See what I mean:

#include "headers.h"

u16* theVideoBuffer = (u16*)VideoBuffer;
u16* theScreenPalette = (u16*)BGPaletteMem;

#define RGB(r,g,b) (r+(g<<5)+(b<<10)) //Macro to build a color from its parts

int main()
{
SetMode(MODE_4|BG2_ENABLE);

if(!(*KEYS & KEY_A)) //A
{
//Copy the palette
u16 i;
for ( i = 0; i < 256; i++ )
theScreenPalette[ i ] = APalette[ i ];

//Cast a 16 bit pointer to our data so we can read/write 16 bits at a time easily
u16* tempData = (u16*)A;

//Write the data
//Note we're using 120 instead of 240 because we're writing 16 bits
//(2 colors) at a time
u16 x, y;
for ( x = 0; x < 120; x++ )
for ( y = 0; y < 160; y++ )
theVideoBuffer[ y * 120 + x ] = tempData[ y * 120 + x ];

while(*KEYS & KEY_A){} //wait until the player releases the A button
if(!(*KEYS & KEY_A)) //B
{
//Copy the palette
u16 i;
for ( i = 0; i < 256; i++ )
theScreenPalette[ i ] = BPalette[ i ];

//Cast a 16 bit pointer to our data so we can read/write 16 bits at a time easily
u16* tempData = (u16*)B;

//Write the data
//Note we're using 120 instead of 240 because we're writing 16 bits
//(2 colors) at a time
u16 x, y;
for ( x = 0; x < 120; x++ )
for ( y = 0; y < 160; y++ )
theVideoBuffer[ y * 120 + x ] = tempData[ y * 120 + x ];

while(*KEYS & KEY_A){} //wait until the player releases the A button
if(!(*KEYS & KEY_A)) //C
{
//Copy the palette
u16 i;
for ( i = 0; i < 256; i++ )
theScreenPalette[ i ] = CPalette[ i ];

//Cast a 16 bit pointer to our data so we can read/write 16 bits at a time easily
u16* tempData = (u16*)C;

//Write the data
//Note we're using 120 instead of 240 because we're writing 16 bits
//(2 colors) at a time
u16 x, y;
for ( x = 0; x < 120; x++ )
for ( y = 0; y < 160; y++ )
theVideoBuffer[ y * 120 + x ] = tempData[ y * 120 + x ];

}
}
}

while(1){}
return 0;
}

#5268 - maciel310 - Thu Apr 24, 2003 5:54 am

Thank you for helping me out there. Checking to see when the button was release worked perfectly, but when I tried adding the line before return 0, my emulator just flashed really fast but wouldnt do anything, I think it was because the thing you do first is you have to push the button so it only gives a split second to allow you to press the button, so right now I dont think I want to have that in, but I will put that into the final thing. Thank you again for your help

#5276 - Maverick - Thu Apr 24, 2003 1:20 pm

Here is your problem, you are doing:

Check for A then while A is being held, check for A, then while this A is being held, check for A.

When it gets A for the first time and you release it, the first check is then invalid so it continues to the end and seeing as there is no while(1); it will start all over again with the first check.

change it to this:

Code:

#include "headers.h"

u16* theVideoBuffer = (u16*)VideoBuffer;
u16* theScreenPalette = (u16*)BGPaletteMem;

#define RGB(r,g,b) (r+(g<<5)+(b<<10)) //Macro to build a color from its parts

int main()
{
SetMode(MODE_4|BG2_ENABLE);

while(*KEYS & KEY_A)
{
//Copy the palette
u16 i;
for ( i = 0; i < 256; i++ )
theScreenPalette[ i ] = APalette[ i ];

//Cast a 16 bit pointer to our data so we can read/write 16 bits at a time easily
u16* tempData = (u16*)A;

//Write the data
//Note we're using 120 instead of 240 because we're writing 16 bits
//(2 colors) at a time
u16 x, y;
for ( x = 0; x < 120; x++ )
for ( y = 0; y < 160; y++ )
theVideoBuffer[ y * 120 + x ] = tempData[ y * 120 + x ];
}

while(*KEYS & KEY_A)
{
//Copy the palette
u16 i;
for ( i = 0; i < 256; i++ )
theScreenPalette[ i ] = BPalette[ i ];

//Cast a 16 bit pointer to our data so we can read/write 16 bits at a time easily
u16* tempData = (u16*)B;

//Write the data
//Note we're using 120 instead of 240 because we're writing 16 bits
//(2 colors) at a time
u16 x, y;
for ( x = 0; x < 120; x++ )
for ( y = 0; y < 160; y++ )
theVideoBuffer[ y * 120 + x ] = tempData[ y * 120 + x ];
}

while(*KEYS & KEY_A)
{
//Copy the palette
u16 i;
for ( i = 0; i < 256; i++ )
theScreenPalette[ i ] = CPalette[ i ];

//Cast a 16 bit pointer to our data so we can read/write 16 bits at a time easily
u16* tempData = (u16*)C;

//Write the data
//Note we're using 120 instead of 240 because we're writing 16 bits
//(2 colors) at a time
u16 x, y;
for ( x = 0; x < 120; x++ )
for ( y = 0; y < 160; y++ )
theVideoBuffer[ y * 120 + x ] = tempData[ y * 120 + x ];
}

while(1);
}