#44016 - Issac - Sun May 29, 2005 12:12 pm
I made a little test to catch up a little coding...
but somehow, when I try it out, I just get a black screen (white at first)
can someone tell me what i've done wrong??
Code: |
#include <gba.h>
int main()
{
unsigned char x,y,z,q;
z=0;
q=0;
SetMode(MODE_3 | BG2_ENABLE);
for(x = 0; x < SCREEN_WIDTH; x++){
for(y = 0; y < SCREEN_HEIGHT; y++){
if(z<31 && q==0){
z++;
VideoBuffer [x+ y * SCREEN_WIDTH] = RGB16(z,0,0);
}
else{
q++;z=0;
}
if(z<31 && q==1){
z++;
VideoBuffer [x+ y * SCREEN_WIDTH] = RGB16(0,z,0);
}
else{
q++;z=0;
}
if(z<31 && q==2){
z++;
VideoBuffer [x+ y * SCREEN_WIDTH] = RGB16(0,0,z);
}
else{
q++;z=0;
}
if(q==3){
VideoBuffer [x+ y * SCREEN_WIDTH] = RGB16(31,31,31);
}
}}
while(1){}
} |
_________________
yeah, well, maybe... or? anyways.... eh... what was i talking about??
#44032 - poslundc - Sun May 29, 2005 6:02 pm
Fundamental debugging question you should ask yourself first: does it work when you take all the ifs/elses out and just try to paint the entire screen a single colour?
Dan.
#44046 - Issac - Sun May 29, 2005 7:50 pm
why, yes it does.
i dont see why it shouldn't work :S
EDIT:
Code: |
unsigned char x,y,z;
z=31;
SetMode(MODE_3 | BG2_ENABLE);
for(x = 0; x < SCREEN_WIDTH; x++)
for(y = 0; y < SCREEN_HEIGHT; y++)
VideoBuffer [x+ y * SCREEN_WIDTH] = RGB16(z,0,0);
|
this code work, so I dont see why the other one wouldn't.....
first thing i thought about was having a variable as a "colorthing" ( the z )
_________________
yeah, well, maybe... or? anyways.... eh... what was i talking about??
#44054 - poslundc - Sun May 29, 2005 8:56 pm
OK, I'm having a real hard time reading your code; I don't know if it's just because of a problem between the way the tabs are formatted in your editor versus how they appear in the browser, but it's really messy and difficult to tell where the program flow is headed at any stage.
As best as I can make out, it should be working for a column on the left-hand edge of the screen of 32 pixels. After that, you start bumping up the value of q every cycle and resetting z to 0 every cycle, so the rest of the screen will be black.
Dan.
#44056 - Issac - Sun May 29, 2005 9:18 pm
what it does is:
different values of red for the first 31 pixels, then 31 pixels green, then 31 pixels blue... then the rest White....
maybe this will simplyfie it a little:
Code: |
if(z<31 && q==0)
{
z++;
VideoBuffer [x+ y * SCREEN_WIDTH] = RGB16(z,0,0);
}
else
{
q++;
z=0;
}
|
This piece check if the value of z is less than 31, and if q is 0 (as it is at first), and then make different shades of red. until z is 31, then reset z and make q 1.
Code: |
if(z<31 && q==1)
{
z++;
VideoBuffer [x+ y * SCREEN_WIDTH] = RGB16(0,z,0);
}
else
{
q++;z=0;
}
|
this piece check if z is less than 31, and if q is 1, then it fill different shades of green,
and then the same with blue.
and after that, it just check if q is 3, which it would be at this point, and fills the rest with white.....
made any sence?
EDIT: OOH, i think i know why now!
got to test it right away now,
Since some of the if's isn't true, the else's will execute, and screw everything up right away... Maybe that was what you meant :)
Edit 2: Nope, still doesn't work.. and I now simplified it more...
Code: |
for(x = 0; x < SCREEN_WIDTH; x++){
for(y = 0; y < SCREEN_HEIGHT; y++){
for(z = 0; z < 31; z++){
VideoBuffer [x+ y * SCREEN_WIDTH] = RGB16(z,z,z);
}
VideoBuffer [x+ y * SCREEN_WIDTH] = RGB16(15,12,0);
}
}
|
Shouldn't this make it lighter and lighter grey (up to allmost white, then the rest brown? Now it just get brown :S
_________________
yeah, well, maybe... or? anyways.... eh... what was i talking about??
Last edited by Issac on Sun May 29, 2005 9:38 pm; edited 1 time in total
#44057 - poslundc - Sun May 29, 2005 9:32 pm
Issac wrote: |
Since some of the if's isn't true, the else's will execute, and screw everything up right away... Maybe that was what you meant :) |
*taps nose*
This is why a good debugging strategy is always to pare your code down to the simplest piece of code that does what it's supposed to, then gradually rebuild chunks on until you can see where it's going wrong. You will be surprised how often it isn't some mysterious aspect of the hardware's behaviour, but in fact an error in your underlying algorithm.
Dan.
#44059 - Issac - Sun May 29, 2005 9:41 pm
yeah, but now i've tried some other things too, still without a success.. :S
(code in the above post edit2)
and i also tried >>>else{ if(z==31 && q==0){ z=0;q++;} }<<<
but that didn't work either..
_________________
yeah, well, maybe... or? anyways.... eh... what was i talking about??
#44071 - poslundc - Sun May 29, 2005 10:58 pm
Your problem is that you are using weird counters and conditional structures so that the state of the current pixel is dependent on the states of the previous pixels. So if you make a mistake early on - which you probably are - that mistake gets propagated to everything else.
Instead of using q and z, see if you can find a way to algorithmically determine what colour a pixel should be, given any values of x and y. In other words, if I give you x = 12 and y = 80 you should be able to write a function that tells me what colour that pixel is, without knowing what happened in previous loop cycles.
Then your code just becomes the following:
Code: |
u16 GetColour(int x, int y)
{
...
return c;
}
void main(void)
{
...
for (y = 0; y < SCREEN_HEIGHT; y++)
{
for (x = 0; x < SCREEN_WIDTH; x++)
{
VideoBuffer[y * SCREEN_WIDTH + x] = GetColour(x, y);
}
}
} |
Dan.
#44079 - strager - Mon May 30, 2005 1:32 am
Issac wrote: |
Edit 2: Nope, still doesn't work.. and I now simplified it more...
Code: |
for(x = 0; x < SCREEN_WIDTH; x++){
for(y = 0; y < SCREEN_HEIGHT; y++){
for(z = 0; z < 31; z++){
VideoBuffer [x+ y * SCREEN_WIDTH] = RGB16(z,z,z);
}
VideoBuffer [x+ y * SCREEN_WIDTH] = RGB16(15,12,0);
}
}
|
Shouldn't this make it lighter and lighter grey (up to allmost white, then the rest brown? Now it just get brown :S |
Oh, that is SOOOOOOOOOOOOOOOOOOOOO funny!!! It's a hard-to-find mistake, and it makes you look like the dumbest person in the world...
Let's take it step-by-step, shall we?
Code: |
?L = ? loop
xL: x = 0
yL: y = 0
zL: z = 0
plot(x, y, z, z, z) // x=y=z=0
zL: z = 1
plot(x, y, z, z, z) // x=y=0; z=1
zL: z = 2
plot(x, y, z, z, z) // x=y=0; z=2
zL: z = 3
plot(x, y, z, z, z) // x=y=0; z=3
...
plot(x, y, 15, 12, 0) // x=y=0
yL: y = 1
zL: z = 0
plot(x, y, z, z, z) // x=z=0; y=1
zL: z = 1
plot(x, y, z, z, z) // x=0; y=z=1
zL: z = 2
plot(x, y, z, z, z) // x=0; y=1; z=2
zL: z = 3
plot(x, y, z, z, z) // x=0; y=1; z=3
...
plot(x, y, 15, 12, 0) // x=0; y=1
...
...
|
If you didn't see it, the inner loop plots the color to the SAME PIXEL 32 times, then that SAME PIXEL is plotted again.
Correct code:
Code: |
z = 0;
for(x = 0; x < SCREEN_WIDTH; x++)
{
for(y = 0; y < SCREEN_HEIGHT; y++)
{
if(z < 32) /* Oh, and I replaced 31 with 32 for a fuller shade. */
{
VideoBuffer[x + (y * SCREEN_WIDTH)] = RGB16(z, z, z);
z++;
}
else
{
VideoBuffer[x + (y * SCREEN_WIDTH)] = RGB16(15, 12, 0);
};
};
};
|
That should do it.
#44094 - Issac - Mon May 30, 2005 6:06 am
Code: |
for(x = 0; x < SCREEN_WIDTH; x++)
{
for(y = 0; y < SCREEN_HEIGHT; y++)
{
if(z<32 && q==0)
{
VideoBuffer [x+ y * SCREEN_WIDTH] = RGB16(z,0,0);
z++;
}
else
{
if(z==32 && q==0)
{
q++;z=0;
}
}
//and continuing for 2 more rounds, then fill with 15,12,0
}}
|
Okay, but then i dont see why this won't work :S
its quite the same as the example you made, though it has more steps..
edit: Whoa!
Now i feel really stupid!
that code works, just not in Visual Boy Advance... the screen it just black.
but if i look at the mapviewer, i see the shades and all.. :)
got to try this on hardware now to see if that works :P
_________________
yeah, well, maybe... or? anyways.... eh... what was i talking about??
#44097 - sajiimori - Mon May 30, 2005 7:53 am
Must you indent so obscenely?
#44100 - Issac - Mon May 30, 2005 10:09 am
what do you mean with that?
and a little update: It doesn't work on hardware either :?
this is really buggin me .....
_________________
yeah, well, maybe... or? anyways.... eh... what was i talking about??
#44101 - Cearn - Mon May 30, 2005 10:15 am
Indented for clarity
Quote: |
Code: |
int main()
{
unsigned char x,y,z,q;
z=0;
q=0;
REG_DISPCNT = 0x0403;
for(x = 0; x < 240; x++)
{
for(y = 0; y < 160; y++)
{
if(z<31 && q==0) // first pass: start true -> z++
{ // second: q==2, false -> q=3, z=0
z++;
VideoBuffer [x+ y * 240] = RGB16(31,0,0);
}
else
{
q++;z=0;
}
if(z<31 && q==1) // first: q==0, false -> q=1, z=0
{ // second: q==3, false -> q=4, z=0
z++;
VideoBuffer [x+ y * 240] = RGB16(0,31,0);
}
else
{
q++;z=0;
}
if(z<31 && q==2) // first: q==1, false -> q=2, z=0
{ // second: q==4, false -> q=5, z=0
z++;
VideoBuffer [x+ y * 240] = RGB16(0,0,31);
}
else
{
q++;z=0;
}
if(q==3) // first q==2, false
{ // second: q==5, false
VideoBuffer [x+ y * 240] = RGB16(31,31,31);
}
// etc
}
}
while(1){}
}
|
|
The whole thing is basically 4 if-else blocks; the first one will work, z is incremented and q isn't. The second if-else is false since q!=1, so we go to the else of it, increment q and reset z. Etc, etc until q wraps around because it's a char (if you intented this that's fair, but if not USE INT, NOT CHAR!
I'd suggest scrapping this and starting over. I'm still not exactly sure what you were hoping to get, but if it's something along the line of four different gradients on the screen, think about using four different loops, one for each color. This will eliminate all the switching in the inner loop, so should be faster as well. Again, depending on what you're after, you might be able to get away with one row of intensive plotting, and then simply copying that a few times.
#44113 - strager - Mon May 30, 2005 2:45 pm
Here:
Code: |
void main(void)
{
int q, z;
...
for(y = 0; y < SCREENHEIGHT; y++)
{
for(x = 0; x < SCREENWIDTH; x++)
{
if(q <= 10)
{
VideoBuffer[x + (y * SCREENHEIGHT)] = z << q;
z++;
if(z >= 32)
{
z = 0;
q += 5;
};
};
};
};
};
|
A couple of reasons why your screen may be black:
- You did not enable the background in DISPCNT
- You enabled a window in DISPCNT, but not enabled in WININ or WINOUT
- You have another layer above the one you want
- MAYBE (stressed) you have the force-blank bit enabled in DISPCNT
- Something else ?
#44126 - poslundc - Mon May 30, 2005 4:43 pm
sajiimori wrote: |
Must you indent so obscenely? |
Isaac wrote: |
What do you mean with that? |
What sajimori means is that it's practically impossible to read your code because of the bizarre and inconsistent spacings you use at the beginning of lines.
Please do the following:
- Use an editor designed for programming when writing your code. ConTEXT is free, but any such program you happen to have will do fine.
- Put any curly-braces on their own line, like you did in the previous post.
- Let the editor handle the spacing for you. Please.
Next, go back up and read the post I made that included some sample code and a GetColour() function. Do it the way I tell you to there, and your problems will go away.
Dan.